Capability: distribution
Shipping the-loop as an installable plugin for Claude Code and Cursor from a single repository — no bespoke marketplace publishing.
What it is
The packaging that makes the-loop installable in both harnesses: two thin plugin manifests over one shared set of skills, commands and templates. The templates and the config schemas are internal to the plugin — read from it when authoring artifacts or validating a config, never copied into the projects the-loop is run on.
Current behaviour
- the-loop SHALL be installable in Claude Code directly from GitHub (
/plugin marketplace add MadaraUchiha-314/the-loop+/plugin install the-loop@the-loop) via.claude-plugin/plugin.json+marketplace.json. - the-loop SHALL be installable in Cursor (≥ 2.5) from the same repo via
.cursor-plugin/plugin.json+marketplace.json, or by cloning under~/.cursor/plugins/local/. - The Claude Code plugin SHALL also be installable non-interactively from a terminal with
the-loop install claude [--scope user|project](and moved forward withthe-loop upgrade), which drivesclaude's own plugin CLI where it has one and otherwise falls back to the settings keys above. The Cursor plugin SHALL keep its documented in-editor routes until issue-157 establishes a terminal one — the CLI reportscursoras an unknown component rather than half-supporting it (owner decision on PR #153). See cli and decision-057; the in-session/pluginand/add-pluginroutes remain exactly as documented. - Both plugins SHALL reuse the SAME
skills/(Agent Skills standard) andcommands/; nothing is forked per harness. - Plugin and marketplace manifest
versionfields SHALL carry the released version:cz bumprewrites them in lockstep on every release (see release-publishing, decision-028). - WHERE Claude Code uses the SessionStart hook (
hooks/hooks.json) the Cursor package SHALL use the always-applied rulerules/the-loop.mdcinstead.hooks/hooks.jsonSHALL also declare the Stop gate (the-loop-gate.py) and, since issue-370, thePostToolUserecorder (the-loop-link-pr.py, which runssessions link-prfor a pull request the session just created); Cursor has a hook surface for the first and none for the second, so there the skill's prose rule is what records a pull request. - Work-item and process templates SHALL be internal to the plugin, shipped under
skills/the-loop/templates/(manifest.templatesDir) and read from${CLAUDE_PLUGIN_ROOT}when an artifact is authored./the-loop:initSHALL NOT copy them into a project; a project carries only its own generated artifacts. - WHEN
/the-loop:upgrade-the-loopruns on a project that an older version scaffolded a.the-loop/templates/folder into THEN it SHALL remove that folder (permanifest.deprecated), confirming first only if the user has added their own files under it. - Config schemas SHALL be internal to the plugin too (issue-220, decision-080), shipped under
${CLAUDE_PLUGIN_ROOT}/.the-loop/and declared once asmanifest.schemasDir— the same shapetemplatesDirhas./the-loop:initSHALL NOT createharness-config.schema.json,collaborators.schema.jsonorcli-config.schema.jsonin a project, and the opt-in.the-loop/cli-config.yamlSHALL be scaffolded alone. - WHEN init or upgrade validates a config, or drives the
x-onboardingwalkthrough, THEN it SHALL read the schema frommanifest.schemasDiron disk — the absence of a project-local copy SHALL NOT weaken, skip, or move that validation onto the network. - WHEN
/the-loop:upgrade-the-loopruns on a project holding a schema copy an older version left behind THEN it SHALL delete it and report it under removed (deprecated); WHERE that copy differs from the plugin's shipped schema the difference SHALL be surfaced first, and WHERE the file cannot be established as a the-loop copy it SHALL be left in place and reported under needs-user. Deletion is name-driven frommanifest.deprecated; a path resolving outside the project's.the-loop/SHALL be refused. - Every config the-loop scaffolds SHALL open, on its first line, with a
# yaml-language-server: $schema=<published url>modeline, so an operator's editor validates the file with no local schema. It is a comment: the loop SHALL never read it, and SHALL never fetch a schema over the network. - WHEN
/the-loop:initscaffolds.the-loop/harness-config.yamlTHEN it SHALL establish the config with the user via a guided onboarding driven by the schema'sx-onboardinggroups: related keys clubbed and decided together, each group explained, enum keys presented with ALL possibilities, free-form keys with schemaexamples, and sensible defaults resolved as existing answer → detected signal → schema default (see the skill'sreference/onboarding.md). - WHERE
--defaultsis passed init SHALL apply sensible defaults without interaction and report the remaining gaps under needs-user; WHEN init re-runs it SHALL raise only gaps, never re-asking established answers. - WHEN
/the-loop:upgrade-the-loopfinds a removed schema key that still carries live operational settings (not just a stale default) THEN it SHALL migrate the data, not merely flag and drop it — e.g. a pre-decision-032.the-loop/harness-config.yamlstill carryingwebhooks/polling/observability.eventLogSHALL have that block extracted,eventLog-renamed, and written to a CLI config (asking the same yes/no location question/initasks), both resulting files validated, and the migration reported as its own line — never silently dropped. - WHEN a release adds a config key whose default changes runtime behaviour THEN upgrade SHALL surface it under needs-user rather than adding it silently — the add-with-defaults rule covers opt-in keys, not behaviour flips. The first instance is
routing.control.requireStartCommand(issue-106): its default demotes the auto-execute label to necessary but not sufficient, so upgrade asks whether to keep the previous behaviour (false) or adopt the gate (true). Related state moves are offered, never performed silently: an older state layout (.the-loop/poll-state.json, then<state.root>/sessions/) may be tidied away, but the daemon keeps READING what is there until each work item has been written forward, because an empty ledger would re-forward every watched thread (issue-106, issue-128). - A CLI config that lives in the operator's home directory is outside upgrade's reach (it reconciles project files). Upgrade SHALL say so and print what to paste, and the runtime SHALL stay correct for an un-migrated config — every key added this way is optional and falls back to the same defaults.
Design
docs/specs/issue-12/design.md · architecture § distribution
History
| Work item | What changed | Links |
|---|---|---|
| issue-220 | Config schemas made internal to the plugin (manifest.schemasDir); init stops copying up to 118 KB of them into each project, upgrade deletes the copies already there, and scaffolded configs carry a # yaml-language-server: $schema= modeline instead | spec, decision-080, issue |
| issue-152 | The Claude Code plugin became installable and upgradable from the CLI (the-loop install / upgrade), at user or project scope, without opening a session — the terminal-side counterpart to the marketplace routes. Cursor stays in-editor-only, split out as issue-157 | spec, decision-057, cli, issue |
| issue-106 | A key whose default changes behaviour (routing.control.requireStartCommand) is reported as needs-user, not silently added; the state/control blocks are added with defaults and the poll-state move is offered, not forced | spec, decision-040, issue |
| issue-63 | /upgrade migrates (not just flags) removed schema keys with live data — the webhooks/polling/observability.eventLog → CLI config extraction | spec, decision-032 |
| issue-46 | Plugin/marketplace manifest versions bumped by the release engine (were frozen at 0.1.0) | spec, decision-028 |
| issue-49 | Guided, schema-driven config onboarding in /init (x-onboarding groups, ask levels, --defaults mode, examples on gap-prone keys) | spec, decision-024 |
| issue-36 | Templates made internal to the plugin (skills/the-loop/templates/); init no longer copies them into projects, and upgrade cleans up the deprecated .the-loop/templates/ folder | spec |
| issue-12 | Added Cursor packaging (.cursor-plugin/, rules/the-loop.mdc) reusing the same skills/commands | spec, decision-015 |
| issue-1 | Shipped the Claude Code plugin + marketplace manifests (v0) | spec, decision-001 |