apm becomes the only supported install path. The flat mirror at each plugin root existed solely so Claude Code's native `claude plugin install` could convention-scan plugin content (ADR-0017). With no native consumers, it cost ~20,000 tracked lines plus ~2,100 lines of sync tooling and ~88s of every push to guard content apm never reads — and its only automated gate, `claude plugin validate --strict`, passes on a plugin with zero content, so it could not detect the defect ADR-0017 was created to fix. Removes the mirror (213 files), the six per-plugin manifest pairs, sync-plugin-content.sh, its 1,289-line test, the orphaned marketplace-plugins.sh, and the check-plugin-content-sync and validate-plugins pre-push hooks. The root `marketplace:` block and .claude-plugin/ catalogue stay: apm's own marketplace consumers read that same file, so `<name>@holocron` short names keep working. tests/run-bats.sh now excludes .claude/skills/. apm installs from .apm/, which carries the tests/ dirs the mirror stripped, so deployed .bats files would otherwise be discovered and double-run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
bin
A place for things to be binned
Install
Claude Code:
claude plugin marketplace add <owner>/<repo>
claude plugin install bin@<marketplace-name>
GitHub Copilot CLI:
copilot plugin marketplace add <owner>/<repo>
copilot plugin install bin
Local (development):
# Claude Code
claude --plugin-dir ./plugins/bin
# GitHub Copilot CLI
copilot plugin install ./plugins/bin
Contents
| Component | Path | Description |
|---|---|---|
| Skills | .apm/skills/ → skills/ |
Slash commands available after install |
| MCP servers | .mcp.json |
The obsidian server (npx @bitbonsai/mcpvault@0.15.0 docs/), hand-authored at the plugin root |
.apm/ is the authoring source; skills/ is the generated mirror plugin hosts scan (ADR-0017). This plugin ships no agents. It is the only plugin here with a non-empty .mcp.json, which is why its compiled manifests are the only ones carrying an mcpServers block.
The two compiled manifests get that block by different routes. .claude-plugin/plugin.json gets it from apm itself: build_plugin_manifest's Claude branch calls collect_mcp_servers, which reads .mcp.json, sanitizes it, and inlines the resulting server objects. .github/plugin/plugin.json gets nothing from apm — the Copilot branch drops the field — so scripts/sync-plugin-content.sh's reinject_mcp_servers() puts it back, as the string ".mcp.json" rather than the resolved objects. Copilot's manifest schema types the field as "string or object — MCP server config path or inline definitions", and a path reference cannot carry a credential into a committed manifest. See ADR-0017's mcpServers amendment.
Author
Defame1297