Repository navigation
Track Claude Code plugin contract parity beyond the current adapter #187
Description
Summary
Documentation-coverage follow-up for the Claude Code plugin surface observed on 2026-09-01. This is a host-specific child of #100 and the #107 plan; it turns the current Claude adapter's implicit omissions into an explicit checklist.
Current implemented baseline: skills/SKILL.md emission, command hook wrappers for the canonical route families, MCP, marketplace stub, and LSP are in packages/agent-bundle/src/adapters/claude.ts and adapters/capabilities/claude-2.1.250.json. Skill lowering stays on #108, semantic event-family work stays on #97, schema/validator adoption stays on #133, and end-user installation stays on #181/#101.
Documented contract to account for
Sources (read 2026-09-01):
- https://code.claude.com/docs/en/plugins
- https://code.claude.com/docs/en/plugins-reference
- https://code.claude.com/docs/en/plugin-marketplaces
- https://code.claude.com/docs/en/plugin-dependencies
- https://code.claude.com/docs/en/skills
- https://code.claude.com/docs/en/hooks
Every item below must end as implemented with pinned evidence, delegated to the linked lane, or explicitly unavailable/prohibited in the capability table with a reason.
Plugin components and manifest
- Commands (
commands/) including flat Markdown discovery and custom paths — flat.mdemission landed earlier; custom-path replace/add rules pinned as capability evidence with native proof in feat(claude): emit manifest metadata fields and pin component path rules (#187) #293 (slice 2) - Agents (
agents/) withname,description,model,effort,maxTurns,tools,disallowedTools,skills,memory,background, andisolation: worktree— feat(claude): record agents-component parity evidence under G5 gate #346 (slice 4; recordedunavailableunder the Compile capability-aware host component bundles #100 stage-2 G5 gate per docs(capabilities): record the #100 stage 2 agents-component deferral in pinned capability notes #220/meta-framework: execution plan and sequencing #107 revision 3: 15 dated capability rows cover the component, every documented frontmatter field, and the security contract; native proof records Claude Code 2.1.257 strict validation accepts all documented fields; re-admitting agents emission needs its own evidence-backed increment) - Enforce the plugin-agent security contract: reject/omit
hooks,mcpServers, andpermissionModefor plugin-shipped agents — feat(claude): record agents-component parity evidence under G5 gate #346 (slice 4; recorded as capability evidence under the same G5 deferral: the docs state all three are ignored for plugin-shipped agents, and native proof records strict validation accepts evenpermissionMode: bypassPermissionswithout warning, so the loader-side ignore contract has no validator enforcement; compiler-side rejection lands with the gated agents emission increment) - Workflows (
workflows/and manifest path field) — feat(claude): emit plugin workflows and output styles (#187) #300 (slice 2; canonicalworkflows/directory emission via the hardened shared payload-directory normalizer with realpath containment; the optional manifest path field is deliberately not emitted since the adapter only uses the default location, and workflow file contents stay opaque because the reference defines no file schema) - Output styles (
output-styles//outputStyles) — feat(claude): emit plugin workflows and output styles (#187) #300 (slice 2; tightened to.mdfiles per the output-styles doc; frontmatter is not validated — native proof records Claude Code 2.1.257 strict validation accepts an output style with no frontmatter; default-location emission only, nooutputStylesmanifest field) - Experimental themes and monitors, including
whenand host-availability constraints — feat(claude): emit experimental themes and monitors (#187) #302 (slice 2; pinned monitors/theme schemas,whenlimited toalways/on-skill-invoke:<skill>with a skill-existence tightening,${user_config.*}rejected in monitor commands, host-availability warnings emitted; native proof records 2.1.257 strict validation does not inspect either default-location document's contents, so the pinned schemas and compiler diagnostics are the only content guard) -
bin/PATH executables and the organization-distribution prohibition on top-levelbin/— feat(claude): emit plugin bin/ executables (#187 slice 1) #282 (slice 1) - Root
settings.jsondefaults (agent,subagentStatusLine) and precedence over manifest settings — feat(claude): emit plugin-root settings.json defaults (#187 slice 1) #284 (slice 1) - Complete metadata/component path fields (
displayName, metadata,defaultEnabled, custom path replace/add rules) — feat(claude): emit manifest metadata fields and pin component path rules (#187) #293 (slice 2) -
userConfig, including supported types, validation fields, sensitive storage, source precedence, and shell-substitution prohibitions — feat(claude): emit userConfig manifest options (#187 slice 1) #287 (slice 1; substitution enforcement inside hook/MCP planning recorded as evidence, deferred to the hooks-fidelity slice) -
channelsdeclarations bound to plugin MCP servers — feat(claude): emit channel declarations bound to plugin MCP servers (#187) #294 (slice 2; native proof records the CLI does not cross-check the server binding, so the compiler diagnostic is the only guard) - Plugin dependencies: same/cross-marketplace resolution, semver ranges, auto-install/enable, conflicts, prune, and command/headersHelper exceptions — feat(claude): emit plugin dependencies (#187 slice 1) #290 (slice 1; declaration validation + manifest emission + pinned evidence; marketplace-side allowCrossMarketplaceDependenciesOn emission landed in feat(claude): complete marketplace manifest contract (#187) #310, slice 3)
Package/cache/data lifecycle
- Eligible Node dependency install contract: root
package.jsonplus Bun/npm lockfile, frozen install,--ignore-scripts, 60-second limit, deterministic lockfile precedence — feat(claude): validate substitution tokens and record lifecycle contract #347 (slice 5; recordedunavailablewith the full documented contract pinned in the capability row — lockfile-to-command map, precedence order, 60-second timeout; native proof records strict validation accepts package metadata without running any install) - Explicitly reject/defer automatic Yarn/pnpm installs and document the
${CLAUDE_PLUGIN_DATA}alternative — feat(claude): validate substitution tokens and record lifecycle contract #347 (slice 5; recordedunavailable: the host skipsyarn.lock/pnpm-lock.yamlbecause resolution-time hooks can bypass--ignore-scripts, and the documented${CLAUDE_PLUGIN_DATA}hook-install alternative is pinned in the evidence) - Cache copy/link semantics, version resolution, orphan grace/sweep, symlink containment, and path-escape rejection — feat(claude): validate substitution tokens and record lifecycle contract #347 (slice 5; recorded
unavailableas host install-time behavior with the full documented lifecycle pinned; native proof records strict validation does not catch a path-escaping symlink, so containment is an install-copy check) -
${CLAUDE_PLUGIN_ROOT},${CLAUDE_PLUGIN_DATA}, and${CLAUDE_PROJECT_DIR}substitution by component/field — feat(claude): validate substitution tokens and record lifecycle contract #347 (slice 5; recordeddegradedwith the closed documented field table pinned and enforced: token-bearing MCP stdiocwdand undocumented LSP fields now fail withclaude.substitution.token.unsupported, and the previously emitted never-substitutedcwd: "${CLAUDE_PLUGIN_ROOT}"is omitted; Skill content and target-native hook documents remain opaque payloads) - Persistent-data deletion on last uninstall and
--keep-data— feat(claude): validate substitution tokens and record lifecycle contract #347 (slice 5; recordedunavailablewith dated evidence: last-scope deletion, the interactive prompt, CLI default deletion, and--keep-dataare host uninstall behavior)
Marketplace/distribution/policy
- Full
marketplace.jsontop-level and plugin-entry fields, includingstrict, renames, relevance, headers, andheadersHelper— feat(claude): complete marketplace manifest contract (#187) #310 (slice 3; authoredclaude.marketplaceoverlay with closed schema re-pinned in PROVENANCE; tightening:headers/headersHelperare rejected as inapplicable on non-archive sources rather than emitted, since the native CLI's strict validation fails them there — the archive-source path landed with feat(claude): support marketplace source matrix #314) - Source matrix: relative, github, git URL, git-subdir, npm, archive, and command (copy/link) with pin/integrity rules — feat(claude): support marketplace source matrix #314 (slice 3; all seven documented source forms with plan-time pin/integrity validation — 40-hex commit SHAs,
sha256:digests, HTTPS-only archives, documented command modes — and native strict-validation proofs including negative proofs for short SHA, HTTP archive URL, and unknown command mode) -
@skills-dirplugins and their project trust/MCP/LSP/monitor restrictions — feat(claude): pin distribution policy capability evidence (#187) #308 (slice 3; recordedunavailablewith dated evidence: Agent Bundle emits plugin directories but does not register host-owned@skills-diridentities or satisfy the trust/MCP-approval/LSP/monitor gates, which are runtime host behavior) - Install scopes, reload behavior, trust gates, synced plugins, and managed scope — feat(claude): pin distribution policy capability evidence (#187) #308 (slice 3; recorded
unavailablewith dated evidence: these are host-owned install-time/runtime behaviors outside compile-time artifact emission) - Managed restrictions:
strictKnownMarketplaces,blockedMarketplaces,disableSideloadFlags,disableCommandPluginSources,allowManagedHooksOnly, and plugin suggestions — feat(claude): pin distribution policy capability evidence (#187) #308 (slice 3; recordedunavailablewith dated evidence: managed-settings enforcement is administrator/host-owned) - CLI lifecycle coverage (
init/new, install/uninstall/prune/enable/disable/update/list/details/tag, marketplace add/list/remove/update) — feat(claude): pin distribution policy capability evidence (#187) #308 (slice 3; recorded as capability rows with dated evidence, plus native proofs exercisingclaude plugin/claude plugin marketplacelifecycle commands against the real binary in an isolated config directory)
Acceptance
- The capability table names every documented component/lifecycle area above as supported, degraded, unavailable, or prohibited with dated evidence.
- The compiler never silently drops a documented component requested by an author.
- Supported fields validate against pinned schemas and real-host fixtures; unsupported fields fail with a precise diagnostic and recovery.
- Compile semantic Agent event routes into native host hooks #97, Compile target-aware Skills with host frontmatter and interpolation #108, Adopt pinned schemas and ecosystem validators for generated plugin conformance (build-time + doctor) #133, Feature: emit ready-to-install host packs (and/or an 'agent-bundle install <host>' command) so projects don't hand-maintain install scripts #181, and Add safe managed lifecycle for generated host bundles #101 are linked from the resulting capability evidence instead of duplicating their work.
Activity
ScriptedAlchemy commentedon Sep 1, 2026
Additional hook/MCP contract checklist from the same 2026-09-01 reference pass:
command,http,mcp_tool,prompt, and experimentalagent; current generated schema/wrappers support command only.if,argsexec form,timeout,statusMessage, skill-onlyonce,async,asyncRewake, and shell selection.mcp__plugin_<plugin>_<server>__<tool>andmcp_tool.serverusesplugin:<plugin>:<server>; bare server keys are not equivalent.Canonical event-family selection remains on #97; this checklist is native Claude hook-document fidelity.
ScriptedAlchemy commentedon Sep 1, 2026
#193 records and proves the
validate, strict-warning,--plugin-dir, and JSON list developer-tool surfaces against Claude Code 2.1.251 while keeping the capability pin at 2.1.250. Theplugin detailscomponent inventory remains tracked here; the PR does not reimplement Claude'scount_tokens/character-fallback costing.ScriptedAlchemy commentedon Sep 2, 2026
Decision (2026-09-01): systematic parity pass adopted — every stable documented surface gets implemented, host by host, Claude (#187) first. Recorded gate deferrals (e.g. G5 agents via #220) stand unless explicitly lifted. Slice 1 of #187 is in flight.
ScriptedAlchemy commentedon Sep 2, 2026
Systematic host-parity pass started (Claude first). This lane owns Slice 1 of the checklist above; the mandate is to land every stable documented surface not gate-deferred, host by host, as separate reviewable PRs with dated evidence.
Slice 1 (this lane, in flight)
Four highest-value unimplemented manifest/config surfaces, one PR each, branch prefix
feat/187-s1-:bin/PATH executables — config surface lowered to emittedbin/copy entries preserving the executable bit, with the documented claude.ai organization-distribution prohibition recorded in the capability evidence.settings.jsondefaults — the two supported keys (agent,subagentStatusLine), closed schema, plus the documented precedence note (settings.json over manifestsettings) and theallowManagedHooksOnlynon-exemption evidence.userConfig— typed enable-time options (string|number|boolean|directory|file), requiredtitle/description,sensitivesecure-storage semantics, per-type constraint validation (multiple,min/max,default), source-precedence and shell-substitution prohibitions documented with citations.dependencies— string and{name, version, marketplace}entries, semver-range validation, cross-marketplaceallowCrossMarketplaceDependenciesOngate, and the documentedcommand/headersHelperauto-install exceptions recorded.Each PR: honest capability rows with dated doc citations (pin stays 2.1.250; local proof runs against the installed Claude Code 2.1.257), closed pinned schemas + PROVENANCE updates, artifact-validator coverage, host-level proof where
claude plugin validate --strict/--plugin-dir plugin list --jsoncan verify, and packaging boundary tests. Standing gates per PR: scoped tests + typecheck + lint locally before merge, with changesets.Agents stay deferred: the
agents/component and the plugin-agent security contract rows remain under the #100 stage-2 / G5 deferral recorded in #220; they are excluded from every slice until that gate lifts.Remaining-slice plan
whenand host-availability constraints), complete metadata/component-path fields (displayName,metadata,defaultEnabled, custom-path replace/add rules),channelsbound to plugin MCP servers.http/mcp_tool/prompt/experimentalagent;if, exec-formargs,timeout,statusMessage,once,async/asyncRewake, shell selection; per-event I/O, exit-code, and blocking rules; matcher modes incl. FileChanged watch lists; plugin-scoped MCP matcher/server naming and connected-server timing. Canonical event-family selection stays on Compile semantic Agent event routes into native host hooks #97.${CLAUDE_PLUGIN_DATA}alternative, cache copy/link + orphan sweep + symlink containment + path-escape rules, token substitution matrix, persistent-data deletion/--keep-data; fullmarketplace.jsonfields, source matrix,@skills-dirrestrictions, scopes/reload/trust/synced/managed, managed restrictions, CLI lifecycle coverage. Per the acceptance criteria, host-owned lifecycle behaviors land as capability-evidence rows rather than reimplemented surfaces.Delivered items will be checked off here as each PR merges. No new tracker issues; #187 remains the single tracker.
ScriptedAlchemy commentedon Sep 2, 2026
Systematic Claude host-parity pass — started (slice 1 underway)
Per the standing decision to implement every stable documented host surface host-by-host (Claude first), this issue is now the tracker for a slice-based pass. Each slice lands as separate reviewable PRs with honest capability rows, dated doc citations, closed schemas, artifact-validator coverage, and host-install proof against the locally observed Claude Code binary (2.1.257; capability pin stays 2.1.250).
Slice 1 (in flight) — highest-value manifest surfaces
bin/PATH executables with the org-distribution prohibition — merged, feat(claude): emit plugin bin/ executables (#187 slice 1) #282settings.jsondefaults (agent,subagentStatusLine) — merged, feat(claude): emit plugin-root settings.json defaults (#187 slice 1) #284 (native proof recorded thatclaude plugin validate --strictnever inspectssettings.json, so compiler diagnostics are the only author guard)userConfig(types, validation fields, sensitive storage, source precedence, shell-substitution prohibitions) — in progressdependencies(semver ranges, cross-marketplace allowlist, resolution rules as evidence) — in progressPlanned remaining slices
displayName,defaultEnabled, custom path replace/add), remainingcommands/discovery gaps, workflows, output styles,channels(builds on slice-1 userConfig), experimental themes/monitors as honestly-degraded rows.marketplace.jsonfields (incl.strict,headersHelper,allowCrossMarketplaceDependenciesOnfollow-up from the dependencies PR), source matrix,@skills-dirrestrictions, install scopes/trust/synced/managed, managed restrictions, CLI lifecycle coverage rows.${CLAUDE_PLUGIN_DATA}alternative, cache copy/link + orphan/symlink semantics, the path-token substitution matrix by component/field, persistent-data deletion (--keep-data).Agents (
agents/+ the plugin-agent security contract) stay behind the #100 stage-2 G5 gate (#220) and are excluded until that gate lifts; slice-1 settings records the linkage via theclaude.settings.agent.deferredwarning.Checklist items get checked off with PR references as they merge.
feat(claude): emit manifest metadata fields and pin component path ru…
feat(claude): emit manifest metadata fields and pin component path ru…
feat(claude): emit channel declarations bound to plugin MCP servers (#…
feat(claude): emit plugin workflows and output styles (#187) (#300)
feat(claude): emit experimental themes and monitors (#187) (#302)
ScriptedAlchemy commentedon Sep 2, 2026
Slice 2 — manifest completion: merged ✅
All four Slice 2 PRs are on
main; checklist items above are checked off with per-item evidence notes.4e514e4c6displayName,metadata,defaultEnabled) + custom component-path replace/add rules pinned as evidence33e9d082dchannelsbound to plugin MCP servers2b5a9857eworkflows/,output-styles/)8a38720feEvidence highlights and honest gaps
claude plugin validate --strictaccepts dangling channel server names (soclaude.channels.server.unknownis the only pre-enable binding guard), accepts output styles with no frontmatter, and never inspects default-location theme/monitor contents (malformed themes/monitors pass). Pinned closed schemas + compiler diagnostics are the content guard in each case, and PROVENANCE records every tightening (e.g.${user_config.*}rejected in monitor commands because the CLI supplies noCLAUDE_PLUGIN_OPTION_variables to monitors;on-skill-invoke:<skill>requires the named skill to be emitted by the plugin).commands/agents/hooks/workflows/outputStylesoverrides) are not emitted — the adapter emits canonical default locations only, soplugin.schema.jsonstays closed on that axis. Themes/monitors avoid the unstableexperimental.*manifest keys (strict host rejects the deprecated top-levelmonitorskey), using default-location documents instead.bin/payload-directory normalizer, now hardened with realpath containment (a symlinked payload directory resolving outside the project is rejected — this tightening applies tobin/too). The artifact validator gained single-wildcard schema families (themes/*.json) so every dynamically named document is schema-validated and owned.pluginadapter marks all six new rowsunavailable(Claude-only), following thelspprecedent.Updated remaining-slice status
marketplace.jsonfields (incl.strict,headersHelper, and theallowCrossMarketplaceDependenciesOncarry-over from feat(claude): emit plugin dependencies (#187 slice 1) #290), source matrix,@skills-dirrestrictions, install scopes/trust/synced/managed, managed restrictions, CLI lifecycle coverage rows.${CLAUDE_PLUGIN_DATA}alternative, cache copy/link + orphan/symlink semantics, path-token substitution matrix, persistent-data deletion (--keep-data).if/exec-formargs/timeout/asyncfields, per-event I/O and blocking rules, matcher modes, plugin-scoped MCP naming/timing. Includes the userConfig shell-substitution enforcement inside hook/MCP planning deferred from feat(claude): emit userConfig manifest options (#187 slice 1) #287. Canonical event-family selection stays on Compile semantic Agent event routes into native host hooks #97.agents/+ the plugin-agent security contract stay behind the Compile capability-aware host component bundles #100 stage-2 G5 gate (docs(capabilities): record the #100 stage 2 agents-component deferral in pinned capability notes #220) until lifted.feat(claude): pin distribution policy capability evidence (#187) (#308)
ScriptedAlchemy commentedon Sep 2, 2026
Slice 3 (marketplace & distribution) is merged. Three PRs:
distributionPolicycapability rows (@skills-diridentity + trust/MCP/LSP/monitor gates, install scopes, reload, trust gates, synced plugins, managed scope, all six managed restrictions, plugin suggestions, CLI lifecycle) recordedunavailablewith dated doc citations, plus native proofs exercisingclaude plugin/claude plugin marketplacelifecycle commands against the real binary in an isolated config directory. adapterRevision claude 1.14.0 / plugin 1.13.0.claude.marketplaceoverlay covering every documented top-level and plugin-entry field (owner/contact/metadata,strict, dependency signals, relevance,allowCrossMarketplaceDependenciesOn— closing the slice-1 follow-up from feat(claude): emit plugin dependencies (#187 slice 1) #290).marketplace.schema.jsonexpanded to the full closed contract and re-pinned in PROVENANCE. Honest tightening:headers/headersHelperare rejected withclaude.marketplace.plugin.headers(.helper).inapplicableon non-archive sources because native strict validation fails them there. adapterRevision claude 1.15.0 / plugin 1.14.0.sha256:digests, HTTPS-only archive URLs, documented command modes) andclaude.marketplace.plugin.source.*diagnostics. Theheaders/headersHelperrestriction is lifted for archive sources. Native proofs: strict validation accepts a document exercising every form; negative proofs pin CLI rejection of short SHAs, HTTP archive URLs, and unknown command modes. adapterRevision claude 1.16.0 / plugin 1.15.0.All gates ran locally post-rebase on each PR: scoped suites + native Claude proofs (
AGENT_BUNDLE_NATIVE_HOST_CONTRACTS=1), typecheck, lint — all green (final run: 396 tests, 0 failed, 0 skipped).Remaining slices:
agents/emission with the full documented field set (name,description,model,effort,maxTurns,tools,disallowedTools,skills,memory,background,isolation: worktree) plus enforcement of the plugin-agent security contract (reject/omithooks,mcpServers,permissionMode).${CLAUDE_PLUGIN_DATA}alternative, cache copy/link semantics and containment,${CLAUDE_PLUGIN_ROOT}/${CLAUDE_PLUGIN_DATA}/${CLAUDE_PROJECT_DIR}substitution by component/field, persistent-data deletion and--keep-data. Most of this is host-owned runtime behavior and will likely land as evidence-backed capability rows plus whatever compile-time validation applies (e.g. lockfile presence checks, substitution-site validation).ScriptedAlchemy commentedon Sep 3, 2026
Closing: every documented Claude surface in this checklist is now delivered or explicitly tracked. All 23 items are checked with pinned, dated evidence. The systematic pass ran as five slices:
bin/executables (feat(claude): emit plugin bin/ executables (#187 slice 1) #282),settings.jsondefaults (feat(claude): emit plugin-root settings.json defaults (#187 slice 1) #284),userConfig(feat(claude): emit userConfig manifest options (#187 slice 1) #287), plugin dependencies (feat(claude): emit plugin dependencies (#187 slice 1) #290).marketplace.jsoncontract including theallowCrossMarketplaceDependenciesOnfollow-up (feat(claude): complete marketplace manifest contract (#187) #310), complete source matrix (feat(claude): support marketplace source matrix #314).unavailableciting the deliberate docs(capabilities): record the #100 stage 2 agents-component deferral in pinned capability notes #220/meta-framework: execution plan and sequencing #107 stage-2 deferral. Native proof: Claude Code 2.1.257 strict validation accepts a plugin agent with all documented fields and a fixture declaringhooks,mcpServers, andpermissionMode: bypassPermissionswithout warning — the loader-side ignore contract has no validator enforcement, so compiler-side rejection rides the future gated re-admission increment.${CLAUDE_PLUGIN_DATA}alternative, cache/orphan/symlink lifecycle, and persistent-data deletion pinned asunavailablehost behavior; path substitution recordeddegradedwith the closed component/field table now enforced (claude.substitution.token.unsupported), including an honest tightening that stops emitting a never-substituted MCP stdiocwd.Acceptance criteria check:
capabilities/claude-2.1.250.json— the table grew from its pre-pass baseline to cover commands, agents, workflows, output styles, themes/monitors, bin, settings, userConfig, channels, dependencies, marketplace manifest + source matrix,@skills-dir, install scopes/trust/managed policy, CLI lifecycle, and package/cache/data lifecycle.claude.*diagnostics (danglingsettings.agent, inapplicable marketplace headers, unsupported substitution tokens, etc.).Follow-up parity passes continue on #188 (Codex) and #189 (Cursor).