From df32c11c360d10088a73efb721bc738ef63b39da Mon Sep 17 00:00:00 2001 From: Mark Beacom Date: Sun, 25 Oct 2026 11:09:15 -0400 Subject: [PATCH] fix(agent-plugin): sync into Claude without manifest warnings (0.11.1) Claude's plugin sync reported two warnings for adrkit at d94698c: it stripped the unrecognized `$schema` key from plugin.json, and it rejected a plugin description over 500 characters. The over-long copy was the marketplace entry's (550 characters), not plugin.json's (330). I removed `$schema` from .claude-plugin/plugin.json, which also clears APM's "Unrecognized plugin manifest $schema" warning, and shortened the marketplace description to 434 characters. It now names both Copilot canvases instead of only decision-review. Two manifest tests keep `$schema` out of both manifests and hold every description to 500 characters. Both fail against the 0.11.0 manifests. The plugin moves to 0.11.1 on every version-bearing surface, because Claude Code keys its plugin cache on the version. Signed-off-by: Mark Beacom --- .claude-plugin/marketplace.json | 6 ++--- AGENTS.md | 11 ++++++--- CHANGELOG.md | 12 ++++++++++ bun.lock | 2 +- docs/RELEASING.md | 2 +- docs/reference-verification-agent-plugin.md | 22 +++++++++++++++++ .../agent-plugin/.claude-plugin/plugin.json | 3 +-- packages/adapters/agent-plugin/README.md | 11 +++++---- packages/adapters/agent-plugin/apm.yml | 2 +- packages/adapters/agent-plugin/package.json | 2 +- .../skills/decision-backfill/SKILL.md | 2 +- .../skills/decision-memory/SKILL.md | 2 +- .../agent-plugin/test/manifest.test.ts | 24 +++++++++++++++++++ 13 files changed, 83 insertions(+), 18 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 63a40b2a..c287915e 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,14 +6,14 @@ }, "metadata": { "description": "Decision memory for human- and agent-authored plans.", - "version": "0.11.0" + "version": "0.11.1" }, "plugins": [ { "name": "adrkit", "source": "./packages/adapters/agent-plugin", - "description": "Load the architecture decisions that govern a change, check work against them, and audit code, documentation, and history for decisions that were never recorded. Ships decision-memory and decision-backfill skills, a read-only decision-checker agent, five slash commands, an advisory adr-review dynamic workflow for GitHub Copilot CLI, and a read-only decision-review canvas for the GitHub Copilot app, all driven by the adr CLI. Ships no MCP server: adrkit's MCP server is configured per project, and the skills use its tools when they are connected.", - "version": "0.11.0", + "description": "Load the architecture decisions that govern a change, check work against them, and audit code, documentation, and history for decisions that were never recorded. Ships decision-memory and decision-backfill skills, a read-only decision-checker agent, and five slash commands, plus an advisory adr-review workflow and two canvases for GitHub Copilot, all driven by the adr CLI. Ships no MCP server: wire adrkit's MCP server per project.", + "version": "0.11.1", "author": { "name": "Mark Beacom", "url": "https://github.com/mbeacom" diff --git a/AGENTS.md b/AGENTS.md index 18ad6fb4..00e56668 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -423,8 +423,8 @@ workflow, `adr-review` (`extensions/adrkit/`), authorized by [ADR-0045](./docs/adr/0045-ship-an-advisory-adr-review-dynamic-workflow-in-the-portable-agent-plugin.md) (**accepted**). `claude plugin validate` passes with it present; APM 0.33.0 installs it into `apm_modules` and deploys it to no target (its one warning, -`Unrecognized plugin manifest $schema`, predates the workflow); a -native opencode load is unmeasured. Independently versioned per ADR-0007, not +`Unrecognized plugin manifest $schema`, predated the workflow and is gone since +0.11.1); a native opencode load is unmeasured. Independently versioned per ADR-0007, not published to npm, and catalogued from the repository root's `.claude-plugin/marketplace.json`. Authorized by [ADR-0028](./docs/adr/0028-ship-decision-memory-as-a-portable-agent-plugin-and-omit-the-mcp-wiring-hosts-cannot-honor.md) @@ -468,6 +468,11 @@ will usually be a regression: rejects the string form outright (`commands: Invalid input`). Both hosts discover the conventional directories without them. `category` belongs to the marketplace entry, not the plugin manifest. +- **The manifest carries no `$schema`, and no description exceeds 500 + characters.** Claude's plugin sync strips `$schema` from `plugin.json` with a + warning (APM 0.33 warned too), and rejects a plugin description over 500 + characters; the marketplace entry's copy was 550 through 0.11.0. Both are + tested in `test/manifest.test.ts`. - **The manifest declares no `extensions` key either.** Measured on Copilot CLI 1.0.93: a non-string `extensions` value (three objects and an array were tried, not `null`, booleans or numbers; the string form loads) in `.claude-plugin/plugin.json` @@ -776,7 +781,7 @@ will usually be a regression: including a variable whose name ends in `_SECRET_TOKEN`. Its arrival in the app, and hook firing in the app, an interactive CLI session, and subagent child sessions, are unmeasured. -- `copilot plugin install` prints only a skill count. Version 0.11.0 should report +- `copilot plugin install` prints only a skill count. Version 0.11.1 should report two skills; that does not inventory the agent or commands — verify them in a fresh session. diff --git a/CHANGELOG.md b/CHANGELOG.md index 618fbd19..deb94b77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ Until `1.0.0`, minor releases may include breaking changes ## [Unreleased] +### Fixed + +- **The agent plugin syncs into Claude without warnings (`adrkit` 0.11.1).** + Claude's plugin sync reported two problems with the plugin: it stripped the + unrecognized `$schema` key from `plugin.json`, and it rejected the + marketplace entry's description, which was 550 characters against a limit of + 500. The key is gone, which also clears APM's `Unrecognized plugin manifest + $schema` warning, and the description now names both Copilot canvases in 434 + characters. A test holds each description to 500 characters and keeps + `$schema` out of both manifests. The plugin ships on merge to `main` and is + versioned independently of this repository. + ## [0.20.0] - 2026-10-10 This release adds a read-only REST server to the OCI image: diff --git a/bun.lock b/bun.lock index 823ee6f7..e801356b 100644 --- a/bun.lock +++ b/bun.lock @@ -12,7 +12,7 @@ }, "packages/adapters/agent-plugin": { "name": "@adrkit/agent-plugin", - "version": "0.11.0", + "version": "0.11.1", }, "packages/adapters/catalog-backstage": { "name": "@adrkit/catalog-backstage", diff --git a/docs/RELEASING.md b/docs/RELEASING.md index b34d29df..a68eaecf 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -350,7 +350,7 @@ Three consequences follow, and all three bite at the wrong moment: claude plugin validate packages/adapters/agent-plugin claude plugin validate .claude-plugin/marketplace.json cd "$(mktemp -d)" && git init -q . && printf 'name: probe\nversion: 0.0.1\ndependencies:\n apm:\n - path: %s\n' "/packages/adapters/agent-plugin" > apm.yml - for t in claude copilot opencode; do apm install --target "$t"; done # expect only APM 0.33's "Unrecognized plugin manifest $schema" warning + for t in claude copilot opencode; do apm install --target "$t"; done # expect no warning bun test packages/adapters/agent-plugin/test ``` diff --git a/docs/reference-verification-agent-plugin.md b/docs/reference-verification-agent-plugin.md index 0826f6ea..340ecef1 100644 --- a/docs/reference-verification-agent-plugin.md +++ b/docs/reference-verification-agent-plugin.md @@ -1411,3 +1411,25 @@ That remains **rung 1** after release. Publishing through `main` changes the distribution state, not the evidence state. Rung 2 requires a persistent, CI-attached reference repository and a run against the public marketplace source; rung 3 requires an adopter who is not the maintainer. Both remain open. + +## v0.11.1 manifest sync fix (2026-10-25) + +Claude's plugin sync, against `main` at `d94698c`, reported two warnings for +`adrkit` 0.11.0: + +- `Plugin 'adrkit' has unrecognized key in plugin.json: '$schema' (stripped — the SDK ignores unknown top-level fields)` +- `Plugin description must be at most 500 characters.` The marketplace entry's + description was 550 characters; `plugin.json`'s was 330. + +0.11.1 removes `$schema` from `.claude-plugin/plugin.json` and shortens the +marketplace entry's description to 434 characters. Measured on the fix: + +| Host or check | Command | Result | +| --- | --- | --- | +| Claude Code | `claude plugin validate packages/adapters/agent-plugin` | PASS (one plugin-directory warning, `ICON_MISSING`, from the directory's submission checks, not the sync) | +| Claude Code | `claude plugin validate .claude-plugin/marketplace.json` | PASS | +| Agent Package Manager 0.35.0 | `apm install --target claude`, `--target copilot`, `--target opencode` | no `$schema` warning; on `main` the same install printed `Unrecognized plugin manifest $schema`. The `bin/ executables skipped` note appears on both and predates this change | +| Unit and contract | `bun test` in `packages/adapters/agent-plugin` | 765 pass; the two new manifest tests fail against the 0.11.0 manifests | + +A fresh sync through Claude was not re-run, because it reads `main`; it is +expected to clear once this change merges. diff --git a/packages/adapters/agent-plugin/.claude-plugin/plugin.json b/packages/adapters/agent-plugin/.claude-plugin/plugin.json index f38edc1e..e9346127 100644 --- a/packages/adapters/agent-plugin/.claude-plugin/plugin.json +++ b/packages/adapters/agent-plugin/.claude-plugin/plugin.json @@ -1,8 +1,7 @@ { - "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "adrkit", "displayName": "adrkit — decision memory", - "version": "0.11.0", + "version": "0.11.1", "description": "Load the architecture decisions governing a change, check plans against them, audit existing code and documentation for missing decisions, draft new records deliberately, and (in GitHub Copilot CLI) run an advisory adr-review workflow, and open a read-only decision-review canvas in the GitHub Copilot app — driven by the adr CLI.", "author": { "name": "Mark Beacom", diff --git a/packages/adapters/agent-plugin/README.md b/packages/adapters/agent-plugin/README.md index 10e1dd2d..448e12e6 100644 --- a/packages/adapters/agent-plugin/README.md +++ b/packages/adapters/agent-plugin/README.md @@ -73,7 +73,9 @@ confirmation before executing a CLI resolved inside that worktree. ### Updating -Version 0.11.0 is a visual pass on both canvases (a shared stylesheet, light +Version 0.11.1 fixes the manifests for Claude's plugin sync (no `$schema` +key, and a marketplace description within 500 characters); nothing else +changes. 0.11.0 is a visual pass on both canvases (a shared stylesheet, light and dark fallbacks, and pan and zoom on the board graph); 0.10.0 added approve, object, and resolve controls to the `decision-board` canvas (they need `@adrkit/cli` 0.18.0 or later, `ADRKIT_REVIEWER`, and a host that can ask you @@ -205,9 +207,10 @@ CLI dynamic workflow (`extensions/adrkit/`), authorized by Outside Copilot CLI: `claude plugin validate` passes with the directory present, and Agent Package Manager 0.33.0 (`apm install --target claude|copilot|opencode`) leaves `extensions/` in `apm_modules` without deploying it to any target -(measured 2026-10-08). APM prints one warning, `Unrecognized plugin manifest -$schema`, and classifies the plugin by structure; it comes from the manifest's -`$schema` field, which predates this release, and not from `extensions/`. A native opencode load is unmeasured. +(measured 2026-10-08). Through 0.11.0 APM printed one warning, `Unrecognized +plugin manifest $schema`, from the manifest's `$schema` field and not from +`extensions/`; 0.11.1 removed the field, and APM 0.35.0 installs it with no +warning. A native opencode load is unmeasured. The workflow was measured on Copilot CLI 1.0.92, and run again through the published GitHub install on 1.0.93. Earlier versions are unmeasured, and a CLI that loads plugin extensions but predates dynamic diff --git a/packages/adapters/agent-plugin/apm.yml b/packages/adapters/agent-plugin/apm.yml index dd4fd4c2..421b35ac 100644 --- a/packages/adapters/agent-plugin/apm.yml +++ b/packages/adapters/agent-plugin/apm.yml @@ -15,7 +15,7 @@ # `description` is deliberately the shorter, CLI-listing variant of the # plugin.json description. That is the one intended difference between them. name: adrkit -version: 0.11.0 +version: 0.11.1 description: Load governing decisions, check plans, audit code or documentation for missing ADR candidates, and (Copilot) review a change in a read-only canvas. author: Mark Beacom license: Apache-2.0 diff --git a/packages/adapters/agent-plugin/package.json b/packages/adapters/agent-plugin/package.json index 7db57e51..3055a54e 100644 --- a/packages/adapters/agent-plugin/package.json +++ b/packages/adapters/agent-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@adrkit/agent-plugin", - "version": "0.11.0", + "version": "0.11.1", "description": "Portable agent plugin exposing adrkit decision memory, evidence-backed ADR backfill, and a read-only decision-review canvas (Copilot app) to GitHub Copilot CLI, Claude Code, APM, and opencode.", "type": "module", "private": true, diff --git a/packages/adapters/agent-plugin/skills/decision-backfill/SKILL.md b/packages/adapters/agent-plugin/skills/decision-backfill/SKILL.md index 51b6c06d..a046197b 100644 --- a/packages/adapters/agent-plugin/skills/decision-backfill/SKILL.md +++ b/packages/adapters/agent-plugin/skills/decision-backfill/SKILL.md @@ -5,7 +5,7 @@ license: Apache-2.0 compatibility: "Requires repository read access and git for history-backed evidence. Existing ADR reconciliation uses the `adr` CLI (@adrkit/cli), resolved from $ADRKIT_CLI, then ./node_modules/.bin/adr, then PATH. The optional adrkit MCP server may replace read-only corpus retrieval, but is not bundled." metadata: author: Mark Beacom - version: "0.11.0" + version: "0.11.1" homepage: https://adrkit.dev/backfill/ --- diff --git a/packages/adapters/agent-plugin/skills/decision-memory/SKILL.md b/packages/adapters/agent-plugin/skills/decision-memory/SKILL.md index c82425a4..2a01c6e0 100644 --- a/packages/adapters/agent-plugin/skills/decision-memory/SKILL.md +++ b/packages/adapters/agent-plugin/skills/decision-memory/SKILL.md @@ -5,7 +5,7 @@ license: Apache-2.0 compatibility: "Requires the `adr` CLI (@adrkit/cli), resolved from $ADRKIT_CLI, then ./node_modules/.bin/adr, then PATH. The adrkit MCP server is optional and is NOT bundled with this plugin — when a project has connected it separately, its tools provide the same retrieval; otherwise the CLI is the only path, and the only one that can write." metadata: author: Mark Beacom - version: "0.11.0" + version: "0.11.1" homepage: https://adrkit.dev --- diff --git a/packages/adapters/agent-plugin/test/manifest.test.ts b/packages/adapters/agent-plugin/test/manifest.test.ts index cccb8a02..1ddf8e21 100644 --- a/packages/adapters/agent-plugin/test/manifest.test.ts +++ b/packages/adapters/agent-plugin/test/manifest.test.ts @@ -151,6 +151,30 @@ describe('manifest shape the hosts actually accept', () => { expect(existsSync(join(packageRoot, '.mcp.json'))).toBe(false); }); + test('carries no `$schema` key', () => { + // Claude's plugin sync reports `unrecognized key in plugin.json: '$schema'` + // and strips it, and APM 0.33 warns `Unrecognized plugin manifest $schema`. + // No host reads it, and Copilot selects an Agent Plugins 1.0 manifest by + // its `$schema`, so a wrong value here is a classification risk too. + expect(Object.keys(plugin)).not.toContain('$schema'); + expect(Object.keys(marketplace)).not.toContain('$schema'); + }); + + test('every description fits the 500-character limit', () => { + // Claude's plugin sync rejects a plugin description over 500 characters + // ("Plugin description must be at most 500 characters"). The marketplace + // entry's copy is the one it reads, and it is the longer of the two. + const plugins = marketplace['plugins'] as Array>; + for (const [label, description] of [ + ['plugin.json', plugin['description']], + ['marketplace metadata', (marketplace['metadata'] as Record)['description']], + ...plugins.map((entry) => [`marketplace entry ${entry['name']}`, entry['description']] as const), + ] as const) { + expect(typeof description).toBe('string'); + expect({ label, over: (description as string).length > 500 }).toEqual({ label, over: false }); + } + }); + test('carries no JSON comment keys', () => { // JSON has no comments. `"//"` keys survive Copilot's loader but Claude // Code's validator reports them as unknown fields, so the reasoning goes in