Why: ADR-0022 made `metadata.version` mandatory in SKILL.md frontmatter, but three documents still instructed the opposite — that `version:`, `source:`, `references:` and `when:` belong in a separate META.md. That recommendation was never implemented: META.md exists exactly once in this repo, inside a vendored third-party research example, and all 39 skills now contradict it. A stale instruction that outranks nothing is worse than no instruction, because an author following it undoes the ADR. Implementation notes: - Two LESSONS.md entries deleted outright — their entire payload was the rejected fix. Two kept and rewritten: the copy-fill entry loses only its META-TEMPLATE clause, and the `model:` entry keeps the provider-extension fact and the invocation-time boundary rule, which stand on their own. - One factual error corrected in passing: the `extracted` slug entry claimed provenance is recorded in META.md. It lives in `references/sources.md` keyed by `source_keys:`, verified against validate-provenance.sh. - Both docs/notes files gain `metadata.version` in their required-field lists. Deleting the stale paragraph while leaving those lists silent would have re-created the gap. - `bin/write-docs` carried `metadata.version: "1.0"` — the only non-semver value in the corpus, and the result of relocating its old top-level `version:` without normalising it. Now `1.0.0`. ADR-0022 records the relocation it previously omitted, which issue #127 had asked it to decide. Impact: patch bumps for the four plugins whose `.apm/` content changed — bin, git, gitea, kyberforge. core and lint are untouched and stay put. Root apm.yml's `executables.allow` key and marketplace package versions move in lockstep; the marketplace release version is unchanged. Refs: #127 ADR: 0022 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EeH8SCbcrCAQrtymkNuhKP
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