Skip to content

refactor(plugin): collapse three host bundles into one shared plugin/ tree - #250

Merged
ScriptedAlchemy merged 1 commit into
masterfrom
feat/plugin-single-bundle
Jul 3, 2026
Merged

refactor(plugin): collapse three host bundles into one shared plugin/ tree#250
ScriptedAlchemy merged 1 commit into
masterfrom
feat/plugin-single-bundle

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Stacked on #249 (base: feat/adoption-contract-injection). Merge last in the plugin stack.

What

Replaces the three duplicated host bundles (claude-plugin/, codex-plugin/, cursor-plugin/) — kept in lockstep by copy + parity tests — with a single plugin/ tree and per-host manifest dirs, the superpowers-style single-source/multi-manifest model.

The overriding invariant: deployed trees do not change

Captured golden sha256 manifests of all three hosts' deployed trees from the pre-refactor binary, then re-installed each host post-refactor: all three deploy byte-for-byte identically (paths + content hashes). This refactor changes only where files live in the repo and how they're embedded — not a single byte of what any host actually installs.

Layout

  • plugin/skills/ — the 17 byte-identical canonical skills + 13 canonical-form workflow skills
  • plugin/overlays/cursor/skills/ — the 13 Cursor disable-model-invocation dispatcher skills (kept as a Cursor overlay; the dispatcher→.cursor/commands/ migration is a deliberate follow-on)
  • plugin/{commands,rules,agents}/ + plugin/overlays/cursor/agents/ (Cursor-form agents differ from Claude-form)
  • plugin/hooks/hooks-{claude,cursor,codex}.json, plugin/.{claude,cursor,codex}-plugin/ manifests (contents unchanged so deployed manifests stay identical), plugin/.mcp.json + plugin/mcp-cursor.json, per-host READMEs
  • src/agents/plugin_bundle.rsPluginFile { relative (deploy path), contents }; CANONICAL_PLUGIN_FILES{CLAUDE,CURSOR,CODEX}_MANIFEST_FILES via {host}_files(). The deploy relative differs from the repo source path where needed (e.g. cursor deploys hooks/hooks.json from plugin/hooks/hooks-cursor.json) — that indirection is what keeps deployed trees byte-identical.
  • The three installers now consume plugin_bundle::{host}_files(); the three *_EMBEDDED_PLUGIN_FILES tables are gone. steering.rs repointed.

Tests

  • Deleted the now-moot cross-copy parity machinery (plugin_bundle_sync_test, codex *_match_the_cursor_source_for_parity / ships_exactly_the_model_invocable, claude byte-identity-to-codex) — with one source copy there's nothing to sync.
  • Rewrote the three *_embedded_file_list_covers_the_whole_source_bundle as composed-view checks; retargeted the manifest/config/skill-contract/skill-lint/coverage/update-plugin tests to the plugin/ tree (staging composed per-host deploy layouts in temp dirs where source≠deploy).
  • fmt/clippy/build clean; full suite green (lib 773, agent_suite 413, mcp 307, +others). Per-host install smoke-test proves deployed trees unchanged.

Deferred (follow-on pass, task #11 remainder)

Recursive-walk embedding for skill support-files; cursor dispatcher→.cursor/commands/; memory-skill merge + message_search lane split; unified shared_skill_contract_test.

🤖 Generated with Claude Code

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@changeset-bot

changeset-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b42021d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Merge the byte-duplicated claude-plugin/, codex-plugin/, and cursor-plugin/
trees into a single shared plugin/ tree with per-host manifest overlays,
and route all three installers through a new composed embed registry
(src/agents/plugin_bundle.rs). Each host still deploys a byte-for-byte
identical tree to before — verified by installing every host from the new
layout and diffing sha256 hashes against the pre-refactor deploy.

Layout (plugin/):
- skills/                 17 shared model-invocable skills + 13 canonical
                          (claude/codex form) tracedecay-* workflow dispatchers
- overlays/cursor/skills/ 13 Cursor dispatcher slugs (disable-model-invocation
                          form) — deployed by Cursor in place of the canonical
                          dispatchers at the same skills/ deploy path
- overlays/cursor/agents/ Cursor-form subagents
- agents/                 Claude-form subagents
- commands/               13 Claude slash commands
- rules/                  2 Cursor .mdc rules
- hooks/hooks-<host>.json per-host hook wiring (each deploys as hooks/hooks.json)
- .{claude,cursor,codex}-plugin/  host manifests (unchanged deploy contents)
- .mcp.json               shared Claude/Codex MCP config (byte-identical)
- mcp-cursor.json         Cursor MCP config (deploys as mcp.json)
- README-<host>.md        per-host README (deploys as README.md)

src/agents/plugin_bundle.rs owns CANONICAL_PLUGIN_FILES plus the per-host
manifest slices and composes each installer's deploy set as
CANONICAL ∪ <HOST>_MANIFEST. Each PluginFile.relative is the deploy path
(unchanged from the legacy bundles); contents are include_str!'d from the
shared plugin/ source, whose path may differ (e.g. Cursor's hooks/hooks.json
is sourced from plugin/hooks/hooks-cursor.json).

cursor.rs/codex.rs/claude.rs drop their per-host EMBEDDED_PLUGIN_FILES tables
and consume plugin_bundle::{cursor,codex,claude}_files(); deploy/render/
migrate/doctor logic is unchanged. steering.rs bootstrap include repoints to
plugin/skills/using-tracedecay/SKILL.md.

Track plugin/.mcp.json past .gitignore; add /plugin/** to the Cargo publish
include list (replacing the cursor/codex bundle globs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ScriptedAlchemy
ScriptedAlchemy force-pushed the feat/plugin-single-bundle branch from bdde218 to b42021d Compare July 3, 2026 19:25
@ScriptedAlchemy
ScriptedAlchemy changed the base branch from feat/adoption-contract-injection to master July 3, 2026 19:43
@ScriptedAlchemy
ScriptedAlchemy merged commit 67cace7 into master Jul 3, 2026
16 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the feat/plugin-single-bundle branch July 4, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant