Files
skills/.agents/adr/0002-ship-as-a-claude-code-plugin.md
Matt PocockandClaude Opus 4.8 42a5b70fca feat: ship the skill set as a native Claude Code plugin
Add a Claude Code plugin marketplace so the promoted skills can be
installed as a managed, read-only bundle (subscribe rather than fork),
alongside the existing skills.sh installer.

- Enrich .claude-plugin/plugin.json with marketplace metadata (version,
  description, author, license, keywords); keep the curated promoted-only
  skills array.
- Add .claude-plugin/marketplace.json making the repo its own
  single-plugin marketplace (mattpocock-skills@mattpocock).
- README: document /plugin install alongside skills.sh, and the
  subscribe-vs-fork tradeoff.
- CLAUDE.md: extend the promoted-set invariant to cover marketplace.json
  and plugin.json/package.json version sync.
- ADR 0002: record why Claude ships now and a native Codex plugin is
  deferred (Codex skills field is single-path + drops symlinks, which
  can't express a curated subset of a bucketed repo without a restructure).

Verified: 'claude plugin validate . --strict' passes, and marketplace
add -> install resolves all 21 promoted skills at v1.2.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 10:14:22 +01:00

3.8 KiB

Ship the skill set as a native Claude Code plugin; defer a native Codex plugin

These skills have always been installable via skills.sh (npx skills add mattpocock/skills), which copies editable skill files into a user's project across Claude Code, Codex, and other Agent-Skills-standard harnesses. A recurring request is a plug-and-play distribution: subscribe to the set as a read-only, always-current bundle you don't edit, rather than a fork you own. That is exactly what native plugin systems provide.

We ship a native Claude Code plugin and, for now, defer a native Codex plugin. The split is forced by how each ecosystem's plugin manifest selects skills, against this repo's bucketed layout.

The constraint: bucketed skills vs. single-path selection

Skills live in bucket folders under skills/engineering/ and productivity/ are promoted (shipped); misc/, personal/, in-progress/, and deprecated/ are not. A plugin must expose only the promoted set, which spans two of those bucket folders.

  • Claude Code.claude-plugin/plugin.json accepts skills as an array of explicit skill-directory paths. We list the promoted skills one by one, exclude everything else with zero ambiguity, and add .claude-plugin/marketplace.json so the repo is its own single-plugin marketplace. Verified end to end: claude plugin validate . --strict passes, and marketplace addinstall resolves all promoted skills.

  • Codex.codex-plugin/plugin.json accepts skills only as a single path string (arrays are rejected with missing or invalid plugin.json), and Codex discovers SKILL.md files recursively under it. There is no way to name two bucket folders, or to curate a subset, from one path. Two escape hatches were tested and rejected:

    • Pointing at ./skills/ would also ship deprecated/, in-progress/, personal/, and misc/ — retired, draft, and personal skills we deliberately don't promote.
    • A curated flat directory of symlinks into the buckets does not survive install: Codex copies the plugin tree into its cache and drops symlinks, so the skills arrive empty.

The only robust ways to give Codex a single promoted-only path are (a) restructure so skills/ contains only promoted skills (moving the non-promoted buckets out — a large blast radius across CLAUDE.md, scripts/link-skills.sh, the bucket READMEs, and the local dev workflow that relies on in-progress/ and personal/), or (b) commit duplicate copies of promoted skills into a flat directory (a sync burden and a second source of truth). Both are structural decisions, not something to bundle into shipping the Claude plugin. This is very likely the original, half-remembered reason a plugin wasn't shipped earlier: the manifest formats didn't cleanly express a curated subset of a bucketed repo.

Decision

  • Ship the Claude Code plugin now (.claude-plugin/plugin.json + .claude-plugin/marketplace.json), curated to the promoted set, as the headline v1.2 deliverable.
  • Keep skills.sh as the universal installer — it already serves Codex and other harnesses today, so no Codex user is left without an install path.
  • Defer the native Codex plugin until we decide between restructuring skills/ to promoted-only vs. committing a generated flat copy. Revisit when Codex either supports a skills array / include-list or preserves symlinks on install.

Invariants this creates

  • Every promoted skill has an entry in .claude-plugin/plugin.json's skills array (this already stood as a CLAUDE.md rule; it now also gates the plugin's contents).
  • .claude-plugin/plugin.json's version tracks package.json's version — bump both together on release. Claude uses the plugin version to decide when installed users see an update.