You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(build,validate,doctor): run the Claude host validator and --plugin-dir load check; doctor reads enabled (AB7327) (#475, #476) (#504)
* fix(validate,build,doctor): run the Claude host validator and --plugin-dir load check from build and validate; doctor validates installed copies and reads enabled (#475, #476)
* test(packed-native): accept other hosts' informational reports in the packed Claude validation document
* docs(site): add the missing lineage-detail table header the generated reference plugin renders (#490 follow-up)
* chore(changeset): reference #504
Run the Claude Code host validator where it was missing and turn it into a load verdict. `agent-bundle build` now runs the same Claude Code checks as `validate --artifact` over every built `claude` and `plugin` target (`--host-validation` on by default, `--no-host-validation` to skip, `--strict` to promote host warnings to errors), and both commands follow the two `claude plugin validate --strict` runs with a `claude --plugin-dir <dir> plugin list --json` load check: a row with `errors` is reported as `AB7325` (a warning when the only errors are uninstalled declared dependencies), no row as `AB7311`, an unreadable listing as `AB6022`; the report carries `load.status` (`loaded`, `refused`, `unregistered`, `failed`). Without `claude` on `PATH`, `build` spawns once and reports a single informational `AB6019`. `agent-bundle doctor --host claude --from <dir>` runs the validator over the bundle and every installed copy (findings keep `AB6019`–`AB6022`, prefixed with the copy they came from) and reads each row's `enabled` flag: an installed-but-disabled copy is reported as `disabled` with the new `AB7327` warning naming the `claude plugin enable` command. The native Claude proofs now validate in plugin mode through the shared runner and record the documented symlink warning. (#504)
Copy file name to clipboardExpand all lines: docs/diagnostics.md
+53-7Lines changed: 53 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ even when no error diagnostic was reported.
36
36
|`AB7010`–`AB7013`| npm prepack inventory, artifact freshness, package bin targets, and release-version agreement. |
37
37
|`AB7200`–`AB7202`, `AB7210`–`AB7211`| Development rebuilds and live host surfaces: rebuild admission and phase failures, development host install sync, and the dev-epoch contract gate (see below). |
38
38
|`AB7xxx`| Project preparation and development rebuilds. |
39
-
|`AB7300`–`AB7326`| Read-only install Doctor: host probes, installed inventory, bundle comparison and registration proof, runtime endpoint health and identity, durable-state inventory, static bytes-at-rest validation, foreign-install detection (`AB7321`; see below), Cursor plugin hook registration / marketplace staging (`AB7322`–`AB7324`; see below), host load refusal (`AB7326`; see below), and the Cursor Agent Plugins launch proof (`AB7326`; see below). |
39
+
|`AB7300`–`AB7327`| Read-only install Doctor: host probes, installed inventory, bundle comparison and registration proof, runtime endpoint health and identity, durable-state inventory, static bytes-at-rest validation, foreign-install detection (`AB7321`; see below), Cursor plugin hook registration / marketplace staging (`AB7322`–`AB7324`; see below), host load refusal (`AB7325`; see below), the Cursor Agent Plugins launch proof (`AB7326`; see below), and a disabled Claude install (`AB7327`; see below). `AB7311` and `AB7325` are also emitted by `build` and `validate --artifact` from the Claude load check (see "Claude Code host validation"). |
40
40
|`AB8200`–`AB8209`| Workbench development runtime routes (`/api/runtime/**`): `AB8200` development runtime provider configuration, load, or lifecycle failure, `AB8201` runtime/session/run not available, `AB8202` invalid route path, `AB8203` invalid request shape, `AB8204` stale runtime generation or MCP session revision (409), `AB8205` runtime request could not be completed, `AB8206` Workbench runtime client failure, `AB8207` Agent Document decoding needs the optional `@agent-bundle/runtime` peer (503), `AB8208` stored Flight could not be decoded as an Agent Document (409), `AB8209` decoded Agent Document over the 16 MiB budget (413) or an invalid document response. |
41
41
|`AB8210`–`AB8214`| Workbench semantic lifecycle replay routes (`/api/lifecycles`, `/api/lifecycles/replays`): `AB8210` invalid path, `AB8211` malformed replay request or native envelope (400, carries the shared validator message), `AB8212` replay unavailable or could not be completed, `AB8213` stale manifest binding (409; the page repairs it with refresh → explicit re-run), `AB8214` replay over the 16 MiB budget (413). |
@@ -46,11 +46,16 @@ even when no error diagnostic was reported.
46
46
|`AB8xxx`| Development server configuration. |
47
47
|`AB9xxx`| Eval selection, harnesses, and persisted runs. |
48
48
49
-
## Claude Code host validation (`AB6019`–`AB6022`)
49
+
## Claude Code host validation (`AB6019`–`AB6022`, `AB7311`, `AB7325`)
50
50
51
-
`agent-bundle validate --artifact <dir>` runs the installed Claude Code
52
-
validator for the `claude` and `plugin` targets when `--host-validation` is on.
53
-
Claude Code decides what to check from the manifest it is pointed at: a run
51
+
`agent-bundle validate --artifact <dir>` and `agent-bundle build` run the
52
+
installed Claude Code validator for the `claude` and `plugin` targets when
53
+
`--host-validation` is on (the default for both commands; `--no-host-validation`
54
+
skips it, and programmatic `build()` calls skip it unless `hostValidation: true`
55
+
is passed). `agent-bundle doctor --host claude --from <dir>` runs the same
56
+
validator over the `--from` bundle and over every installed copy Claude lists
57
+
for the plugin, prefixing each finding with `Bundle at …` or `Installed copy at
58
+
… (scope …)`. Claude Code decides what to check from the manifest it is pointed at: a run
54
59
against the bundle directory picks `.claude-plugin/marketplace.json` when it is
55
60
present and never opens the plugin's skill, agent, command, or hook files
56
61
(Claude Code docs, "Create and distribute a plugin marketplace" →
@@ -65,12 +70,31 @@ plugin run already reported. On Claude Code 2.1.259 or later both runs add
65
70
releases fall back to the text report, attributed by its `Validating <type>:
66
71
<file>` headers.
67
72
73
+
`claude plugin validate --strict` is not a load verdict: Claude Code 2.1.250
74
+
through 2.1.260 accept manifests and component files (for example an invalid
75
+
`monitors/monitors.json`, or a `hooks` field naming the auto-loaded
76
+
`hooks/hooks.json`) that a session then refuses to load. So `build` and
77
+
`validate --artifact` follow the two validation runs with a load check,
78
+
`claude --plugin-dir <dir> plugin list --json`, and read the plugin's
79
+
`<name>@inline` row: no `errors` is `load.status: 'loaded'`; `errors` is
80
+
`refused` and `AB7325`; no row at all is `unregistered` and `AB7311`; a listing
81
+
that cannot be read is `failed` and `AB6022`. The check is read-only (the
82
+
listing writes nothing under `~/.claude`), is skipped with the two validation
83
+
runs when `claude` is absent (`AB6019`), and is skipped when the bundle has no
84
+
readable `.claude-plugin/plugin.json` name (the validation runs already report
85
+
that manifest). Doctor does not repeat it: its registration proof and the
86
+
inventory rows' `errors` already carry the same verdicts. Without `claude` on
87
+
`PATH`, `build` spawns once, reports one `AB6019`, and marks the remaining
88
+
`claude`/`plugin` targets `unavailable` without spawning again.
89
+
68
90
| Code | Severity | Meaning | Recovery |
69
91
| --- | --- | --- | --- |
70
92
|`AB6019`| info | The `claude` CLI is not installed or not on `PATH`, so host validation was skipped. Local pinned-schema validation (`AB6011`/`AB6012`) still runs. | Install Claude Code and ensure `claude` is on `PATH`, then rerun artifact validation. |
71
93
|`AB6020`| warning (error in strict mode) / info | One Claude Code validation warning, or (info) one note, from the plugin or marketplace run. The message names the validated file and Claude Code's field path, for example `(hooks hooks/hooks.json): hooks: hooks.postToolUse: unknown hook event`. Claude Code tolerates these at load time; `agent-bundle validate --strict` promotes warnings to errors, mirroring `claude plugin validate --strict`. | Run `claude plugin validate <bundle-dir>/.claude-plugin/plugin.json --strict`, repair the reported Claude artifact, and rebuild. |
72
94
|`AB6021`| error | One Claude Code validation error from the plugin or marketplace run, such as invalid JSON in `hooks/hooks.json`, frontmatter that fails to parse, or a duplicate plugin name in `marketplace.json`. Claude Code loads the plugin without the failing component or refuses the marketplace. | Same as `AB6020`. |
73
-
|`AB6022`| error | The bounded `claude --version` probe or a validation run could not start, exited nonzero without a report, timed out, exceeded 1 MiB of output, or (2.1.259+) returned no JSON report; the message carries the CLI's stderr when there is one. | Verify the Claude CLI starts and responds, then rerun `claude plugin validate <bundle-dir>/.claude-plugin/plugin.json --strict`. |
95
+
|`AB6022`| error | The bounded `claude --version` probe, a validation run, or the load check could not start, exited nonzero without a report, timed out, exceeded 1 MiB of output, (2.1.259+) returned no JSON report, or (load check) returned something other than a JSON array; the message carries the CLI's stderr when there is one. | Verify the Claude CLI starts and responds, then rerun `claude plugin validate <bundle-dir>/.claude-plugin/plugin.json --strict`. |
96
+
|`AB7311`| error | The load check's `claude --plugin-dir <dir> plugin list --json` listed no `<name>@inline` row for the bundle (`load.status: 'unregistered'`): Claude Code did not register the directory as a plugin. Doctor emits the same code from its registration proof. | Inspect `claude --plugin-dir <bundle-dir> plugin list --json` and register the intended bundle. |
97
+
|`AB7325`| error; warning when every `errors` entry is `Dependency "<name>@<marketplace>" is not installed …` (error under `--strict`) | The load check's row for the bundle carries `errors` (`load.status: 'refused'` with the strings verbatim): `claude plugin validate --strict` accepted the artifact, but a session would refuse to load it. A missing declared dependency is a property of the validating machine rather than of the artifact, so it is a warning and the build completes. Doctor emits the same code for installed copies and its registration proof (see "Host load refusal for Claude installs"). | Fix the artifact so `claude --plugin-dir <bundle-dir> plugin list --json` reports no `errors` for it, then rebuild; for a missing dependency, install it (`claude plugin install <name>@<marketplace>`) or validate where it is installed. |
@@ -872,7 +896,29 @@ pinned Claude `plugin` schema now rejects (`AB6012` at `/hooks`).
872
896
| Code | Severity | Trigger | Recovery |
873
897
| --- | --- | --- | --- |
874
898
|`AB7006`| error |`install claude` found `errors` on the plugin's row: after `claude plugin install` ran (the install itself exited 0, so the result would otherwise have been `installed`/`replaced`), or on a byte-identical existing copy that would otherwise have been reported `already-installed` (reinstalling the same bytes cannot help). The message carries the host's `errors` verbatim, the install path, and the scope. An unusable post-install listing leaves the result unverified rather than failing an install the host accepted. | Fix the artifact until `claude plugin list --json` shows no `errors` for it (the message names the cause), rebuild, and rerun `agent-bundle install claude --from <bundle-dir> --replace`. |
875
-
|`AB7325`| error | Doctor found `errors` on the plugin's row in `claude plugin list --json` (inventory entry `state: 'failed'` with `errors`; `doctor --from` comparison `status: 'load-failed'` with `errors` instead of `current`/`stale`, since the installed bytes never reach a session) or on the `--plugin-dir` registration proof row (`bundle.state: 'failed'` with `errors`, replacing the `registered` verdict). The message carries the host's `errors` verbatim. | Same as `AB7006`: fix the artifact, rebuild, and reinstall with `--replace`. |
899
+
|`AB7325`| error | Doctor found `errors` on the plugin's row in `claude plugin list --json` (inventory entry `state: 'failed'` with `errors`; `doctor --from` comparison `status: 'load-failed'` with `errors` instead of `current`/`stale`, since the installed bytes never reach a session) or on the `--plugin-dir` registration proof row (`bundle.state: 'failed'` with `errors`, replacing the `registered` verdict). The message carries the host's `errors` verbatim. `build` and `validate --artifact` emit the same code from their load check (see "Claude Code host validation"). | Same as `AB7006`: fix the artifact, rebuild, and reinstall with `--replace`. |
900
+
901
+
## Disabled Claude install (`AB7327`)
902
+
903
+
`claude plugin disable <plugin>` (or the `/plugin` menu) keeps a plugin
904
+
installed but switched off: its row in `claude plugin list --json` reports
905
+
`enabled: false`, and none of its hooks, MCP servers, or skills reach a session
"plugin enable" / "plugin disable"). Reinstalling, even with `--replace`, does
908
+
not enable it. `agent-bundle doctor --host claude` reads the flag: the
909
+
inventory entry carries `enabled: false` with `state: 'disabled'` (instead of
910
+
`installed`), and a `--from` comparison of that copy carries `enabled: false`
911
+
next to its content verdict — a disabled copy can still be `current` or
912
+
`stale`, and both facts are reported. Rows without a boolean `enabled` carry no
913
+
flag and are `installed`. A row with `errors` is `failed` (`AB7325`) whatever
914
+
its `enabled` value. A plugin that ships `defaultEnabled: false` in
915
+
`plugin.json` installs disabled by design ("Plugins reference" → "Default
916
+
enablement"); Doctor still reports `AB7327` for it, because the recovery is the
917
+
same `claude plugin enable`.
918
+
919
+
| Code | Severity | Trigger | Recovery |
920
+
| --- | --- | --- | --- |
921
+
|`AB7327`| warning |`doctor --host claude --from <dir>` compared an installed copy whose row reports `enabled: false`. The message names the plugin, version, install path, and scope. | Run `claude plugin enable <name>@<marketplace> [--scope <scope>]` (or use `/plugin` in a session), then rerun Doctor; reinstalling does not enable a disabled plugin. |
876
922
877
923
The JSON report exposes the same facts: `hosts[].inventory.findings[].errors`,
878
924
`hosts[].bundle.errors`, and `hosts[].bundle.comparison.errors`. The text
0 commit comments