Adds a new skill for creating, managing, and adopting plugins across Claude Code and GitHub Copilot CLI marketplaces. Includes three Bash scripts (inventory, gen_manifests, validate), three reference docs (cross-compat, claude-code, copilot-cli), a test harness with 18 passing tests, and an eval.yaml. Also adds the `marketplace` category to CATEGORIES.md and commits the plugin marketplace architecture research doc that informed the skill design. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.5 KiB
Cross-Tool Compatibility Reference
Claude Code and GitHub Copilot CLI share the plugin concept but diverge in specific, breaking ways. Skills are the portable core. Manifests and agents are where they split.
Make Claude Code the source of truth — it is the stricter, more fully specified format. Treat "loads in Copilot CLI" as a tested checklist item per plugin, not an assumption.
Divergence table
| Concern | Claude Code | GitHub Copilot CLI | Portable choice |
|---|---|---|---|
| Marketplace manifest path | .claude-plugin/marketplace.json (required) |
.github/plugin/marketplace.json (primary); also reads .claude-plugin/ |
Put it in .claude-plugin/ — both read it. Optionally mirror to .github/plugin/. |
| Plugin manifest path | .claude-plugin/plugin.json (required; only plugin.json goes in this dir) |
plugin.json at plugin root |
Ship in both locations until verified — see ⚠️ below |
| Skills | skills/<name>/SKILL.md |
skills/<name>/SKILL.md |
✅ Identical |
| Agents | agents/<name>.md |
agents/<name>.agent.md (frontmatter incl. tools:) |
Diverges — keep portable logic in skills; ship per-tool agent files only when needed |
| Hooks | hooks/hooks.json |
hooks.json at plugin root |
Diverges; declare paths in manifest to be safe |
| MCP servers | .mcp.json at plugin root |
.mcp.json at plugin root |
✅ Same |
Relative source |
must start with ./ |
./x and x both valid |
Always use ./ — valid for both |
| Validate command | claude plugin validate . (or /plugin validate .) |
none documented | Run Claude validator + manual JSON checks for Copilot |
| Install marketplace | claude plugin marketplace add owner/repo |
copilot plugin marketplace add owner/repo |
Same shape |
| Install plugin | claude plugin install <name>@<marketplace-name> |
install by plugin name; @marketplace suffix unconfirmed |
⚠️ Verify Copilot install string before documenting |
| Local install (dev) | claude --plugin-dir ./plugin |
copilot plugin install ./plugin |
Tool-specific |
| Component paths in plugin.json | Claude defaults to standard dirs; path overrides via marketplace entry only | "skills": "skills/", "agents": "agents/", etc. in plugin.json |
Generate per-tool manifests rather than one shared file |
⚠️ UNVERIFIED — test before committing to a layout. Copilot docs confirm it reads the marketplace manifest from
.claude-plugin/. They do NOT confirm the same fallback for a plugin'splugin.json. Copilot docs showplugin.jsonat plugin root; Claude requires it in.claude-plugin/. Until verified: shipplugin.jsonin BOTHplugin-name/plugin.jsonandplugin-name/.claude-plugin/plugin.json(identical content), then drop whichever proves redundant.
@<marketplace-name> resolution
claude plugin install startup-cto@my-ai-marketplace requires the marketplace manifest's
top-level name field to be exactly my-ai-marketplace. It is not the GitHub repo name.
Keep them aligned to avoid confusion, but they are separate fields.
Canonical cross-compatible repo layout
repo-root/
├── .claude-plugin/
│ └── marketplace.json # both tools read here
├── .github/plugin/
│ └── marketplace.json # OPTIONAL: Copilot canonical path (mirror)
├── plugins/
│ └── startup-cto/
│ ├── plugin.json # Copilot root manifest ┐ ship both until
│ ├── .claude-plugin/ # │ the note above is
│ │ └── plugin.json # Claude manifest ┘ verified
│ ├── skills/
│ │ ├── fundraising/SKILL.md
│ │ └── hiring/SKILL.md
│ ├── agents/
│ │ ├── startup-cto.md # Claude
│ │ └── startup-cto.agent.md # Copilot (only if shipping native agents)
│ ├── hooks/hooks.json # Claude
│ ├── hooks.json # Copilot (if hooks used)
│ └── README.md
└── README.md
Open questions to resolve before generating layouts
-
Does Copilot CLI load a plugin whose
plugin.jsonlives only in.claude-plugin/? Install a test plugin both ways. The answer decides whether to ship one manifest or two. -
What is Copilot's exact install-from-marketplace command? Run
copilot plugin install --help. Theupdate/uninstallcommands take a bare plugin name — the@marketplaceform may not apply.