codex-plugin-doctor 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,13 +11,24 @@ It catches packaging, metadata, security, and runtime protocol problems before a
11
11
 
12
12
  ## Status
13
13
 
14
- Codex Plugin Doctor is an early public CLI release.
14
+ Codex Plugin Doctor is a public CLI on the 1.0 readiness track.
15
15
 
16
16
  - Primary surface: GitHub repository and npm package
17
17
  - Distribution today: `npm install -g`, local source install, `npm link`, `npm pack`, GitHub Releases
18
18
  - Public npm package: `codex-plugin-doctor`
19
19
  - License: [MIT](./LICENSE)
20
20
 
21
+ ## 1.0 Readiness
22
+
23
+ The 0.21.x line is reserved for release-candidate readiness work rather than new feature expansion.
24
+
25
+ - Public JSON schema surfaces and existing rule IDs/default severities are treated as stable through 1.0.
26
+ - Runtime probing remains opt-in because it executes package-local MCP servers.
27
+ - The project remains Codex-first; broader MCP Doctor positioning stays a post-1.0 expansion path.
28
+ - 1.0 release candidates should add no new feature work unless a blocker is discovered.
29
+
30
+ See [v1.0 Readiness Checklist](./docs/engineering/v1.0-readiness-checklist.md) for the exact RC smoke plan.
31
+
21
32
  ## Why This Exists
22
33
 
23
34
  Codex plugin packages can fail in several places:
@@ -33,7 +44,7 @@ This tool gives plugin authors a repeatable preflight check before distribution.
33
44
 
34
45
  ## What It Checks
35
46
 
36
- Static validation:
47
+ Static validation:
37
48
 
38
49
  - required `.codex-plugin/plugin.json`
39
50
  - manifest fields: `name`, `version`, `description`
@@ -42,18 +53,18 @@ Static validation:
42
53
  - YAML single-line and block-scalar skill descriptions
43
54
  - `.mcp.json` structure
44
55
  - path traversal risks
45
- - hard-coded secret-like env values
46
- - description quality heuristics tuned against real plugin packages
47
-
48
- Security scorecard with `security`:
49
-
50
- - shell wrapper command warnings for MCP servers
51
- - encoded shell command failures
52
- - remote content piped into shell failures
53
- - MCP server `cwd` paths that escape the package root
54
- - plain HTTP remote transport warnings
55
-
56
- Runtime MCP validation with `--runtime`:
56
+ - hard-coded secret-like env values
57
+ - description quality heuristics tuned against real plugin packages
58
+
59
+ Security scorecard with `security`:
60
+
61
+ - shell wrapper command warnings for MCP servers
62
+ - encoded shell command failures
63
+ - remote content piped into shell failures
64
+ - MCP server `cwd` paths that escape the package root
65
+ - plain HTTP remote transport warnings
66
+
67
+ Runtime MCP validation with `--runtime`:
57
68
 
58
69
  - `initialize`
59
70
  - `notifications/initialized`
@@ -73,13 +84,13 @@ Output formats:
73
84
  - human text output
74
85
  - JSON reports
75
86
  - Markdown reports
76
- - Shields-compatible badge JSON and static badge Markdown
77
- - validation history JSONL and trend summaries
78
- - deterministic local attestation artifacts
79
- - output contract and rule catalog freeze metadata
80
- - bundled validation corpus reports
81
- - `--output` file writing
82
- - CI summary and artifact generation
87
+ - Shields-compatible badge JSON and static badge Markdown
88
+ - validation history JSONL and trend summaries
89
+ - deterministic local attestation artifacts
90
+ - output contract and rule catalog freeze metadata
91
+ - bundled validation corpus reports
92
+ - `--output` file writing
93
+ - CI summary and artifact generation
83
94
 
84
95
  ## Quick Start
85
96
 
@@ -98,15 +109,15 @@ If you already have Codex installed locally and do not know plugin paths, discov
98
109
 
99
110
  ```bash
100
111
  codex-plugin-doctor list --installed
101
- codex-plugin-doctor check --installed
102
- codex-plugin-doctor check --installed --all-summary
103
- codex-plugin-doctor check --installed --compat --all-summary
104
- codex-plugin-doctor audit --installed --security --compat
105
- codex-plugin-doctor audit --installed --security --compat --policy security
106
- codex-plugin-doctor mcp path/to/mcp-package
107
- codex-plugin-doctor check --installed github
108
- codex-plugin-doctor explain plugin.manifest.missing
109
- ```
112
+ codex-plugin-doctor check --installed
113
+ codex-plugin-doctor check --installed --all-summary
114
+ codex-plugin-doctor check --installed --compat --all-summary
115
+ codex-plugin-doctor audit --installed --security --compat
116
+ codex-plugin-doctor audit --installed --security --compat --policy security
117
+ codex-plugin-doctor mcp path/to/mcp-package
118
+ codex-plugin-doctor check --installed github
119
+ codex-plugin-doctor explain plugin.manifest.missing
120
+ ```
110
121
 
111
122
  Run from source:
112
123
 
@@ -176,128 +187,128 @@ x plugin.security.hard_coded_secret
176
187
  Run these from a Codex plugin package root:
177
188
 
178
189
  ```bash
179
- codex-plugin-doctor --version
180
- codex-plugin-doctor self-test
181
- codex-plugin-doctor doctor
182
- codex-plugin-doctor doctor contract
183
- codex-plugin-doctor doctor contract --json --output output-contract.json
184
- codex-plugin-doctor doctor corpus
185
- codex-plugin-doctor doctor corpus --json --output validation-corpus.json
186
- codex-plugin-doctor doctor npm codex-plugin-doctor
187
- codex-plugin-doctor doctor npm codex-plugin-doctor --json --output npm-preinstall.json
188
- codex-plugin-doctor doctor attest .
189
- codex-plugin-doctor doctor attest . --json --output attestation.json
190
- codex-plugin-doctor doctor inspector .
191
- codex-plugin-doctor doctor inspector . --server context7 --json --output inspector-command.json
192
- codex-plugin-doctor doctor diff --before ./old-plugin --after ./new-plugin
193
- codex-plugin-doctor doctor diff --before ./old-plugin --after ./new-plugin --json --output risk-diff.json
194
- codex-plugin-doctor doctor recommend .
195
- codex-plugin-doctor doctor recommend . --json --output recommendations.json
196
- codex-plugin-doctor doctor trust .
197
- codex-plugin-doctor doctor trust . --json --output trust-score.json
198
- codex-plugin-doctor doctor perf .
199
- codex-plugin-doctor doctor perf . --json --output perf.json
200
- codex-plugin-doctor doctor export --bundle .
201
- codex-plugin-doctor doctor export --bundle . --output doctor-bundle.json
202
- codex-plugin-doctor doctor snapshot
203
- codex-plugin-doctor doctor snapshot --json
204
- codex-plugin-doctor doctor snapshot --output doctor-snapshot.json
205
- codex-plugin-doctor doctor clients
206
- codex-plugin-doctor doctor --update-check
207
- codex-plugin-doctor audit --installed
208
- codex-plugin-doctor audit --installed --security --compat
209
- codex-plugin-doctor audit --installed --security --compat --json --output local-audit.json
210
- codex-plugin-doctor audit --installed --security --compat --cache
211
- codex-plugin-doctor audit --installed --changed --cache
212
- codex-plugin-doctor mcp .
213
- codex-plugin-doctor mcp . --json
214
- codex-plugin-doctor mcp . --json --output mcp-doctor.json
215
- codex-plugin-doctor init my-plugin
216
- codex-plugin-doctor init my-mcp --template mcp-stdio
217
- codex-plugin-doctor init remote-mcp --template mcp-http
218
- codex-plugin-doctor init runtime-demo --template full-runtime
219
- codex-plugin-doctor security .
220
- codex-plugin-doctor security . --scorecard
221
- codex-plugin-doctor security . --json
222
- codex-plugin-doctor security . --policy security
223
- codex-plugin-doctor compat .
224
- codex-plugin-doctor compat . --all --scorecard
225
- codex-plugin-doctor compat . --client codex
226
- codex-plugin-doctor compat . --client generic-mcp
190
+ codex-plugin-doctor --version
191
+ codex-plugin-doctor self-test
192
+ codex-plugin-doctor doctor
193
+ codex-plugin-doctor doctor contract
194
+ codex-plugin-doctor doctor contract --json --output output-contract.json
195
+ codex-plugin-doctor doctor corpus
196
+ codex-plugin-doctor doctor corpus --json --output validation-corpus.json
197
+ codex-plugin-doctor doctor npm codex-plugin-doctor
198
+ codex-plugin-doctor doctor npm codex-plugin-doctor --json --output npm-preinstall.json
199
+ codex-plugin-doctor doctor attest .
200
+ codex-plugin-doctor doctor attest . --json --output attestation.json
201
+ codex-plugin-doctor doctor inspector .
202
+ codex-plugin-doctor doctor inspector . --server context7 --json --output inspector-command.json
203
+ codex-plugin-doctor doctor diff --before ./old-plugin --after ./new-plugin
204
+ codex-plugin-doctor doctor diff --before ./old-plugin --after ./new-plugin --json --output risk-diff.json
205
+ codex-plugin-doctor doctor recommend .
206
+ codex-plugin-doctor doctor recommend . --json --output recommendations.json
207
+ codex-plugin-doctor doctor trust .
208
+ codex-plugin-doctor doctor trust . --json --output trust-score.json
209
+ codex-plugin-doctor doctor perf .
210
+ codex-plugin-doctor doctor perf . --json --output perf.json
211
+ codex-plugin-doctor doctor export --bundle .
212
+ codex-plugin-doctor doctor export --bundle . --output doctor-bundle.json
213
+ codex-plugin-doctor doctor snapshot
214
+ codex-plugin-doctor doctor snapshot --json
215
+ codex-plugin-doctor doctor snapshot --output doctor-snapshot.json
216
+ codex-plugin-doctor doctor clients
217
+ codex-plugin-doctor doctor --update-check
218
+ codex-plugin-doctor audit --installed
219
+ codex-plugin-doctor audit --installed --security --compat
220
+ codex-plugin-doctor audit --installed --security --compat --json --output local-audit.json
221
+ codex-plugin-doctor audit --installed --security --compat --cache
222
+ codex-plugin-doctor audit --installed --changed --cache
223
+ codex-plugin-doctor mcp .
224
+ codex-plugin-doctor mcp . --json
225
+ codex-plugin-doctor mcp . --json --output mcp-doctor.json
226
+ codex-plugin-doctor init my-plugin
227
+ codex-plugin-doctor init my-mcp --template mcp-stdio
228
+ codex-plugin-doctor init remote-mcp --template mcp-http
229
+ codex-plugin-doctor init runtime-demo --template full-runtime
230
+ codex-plugin-doctor security .
231
+ codex-plugin-doctor security . --scorecard
232
+ codex-plugin-doctor security . --json
233
+ codex-plugin-doctor security . --policy security
234
+ codex-plugin-doctor compat .
235
+ codex-plugin-doctor compat . --all --scorecard
236
+ codex-plugin-doctor compat . --client codex
237
+ codex-plugin-doctor compat . --client generic-mcp
227
238
  codex-plugin-doctor compat . --client claude-desktop
228
239
  codex-plugin-doctor compat . --client claude-desktop --install-preview
229
240
  codex-plugin-doctor compat . --client claude-desktop --apply --backup
230
- codex-plugin-doctor compat . --client cursor
231
- codex-plugin-doctor compat . --client cursor --install-preview
232
- codex-plugin-doctor compat . --client cursor --apply --backup
233
- codex-plugin-doctor compat . --client cline
234
- codex-plugin-doctor compat . --client cline --install-preview
235
- codex-plugin-doctor compat . --scorecard
236
- codex-plugin-doctor compat . --json
237
- codex-plugin-doctor compat . --json --output compatibility.json
238
- codex-plugin-doctor check .
239
- codex-plugin-doctor check . --profile ci
240
- codex-plugin-doctor check . --profile strict
241
- codex-plugin-doctor check . --profile publish
242
- codex-plugin-doctor check . --policy codex-publish
243
- codex-plugin-doctor check . --policy mcp-strict
244
- codex-plugin-doctor check . --policy security
245
- codex-plugin-doctor check . --json
246
- codex-plugin-doctor check . --explain
247
- codex-plugin-doctor check . --json --output report.json
248
- codex-plugin-doctor check . --markdown --output report.md
241
+ codex-plugin-doctor compat . --client cursor
242
+ codex-plugin-doctor compat . --client cursor --install-preview
243
+ codex-plugin-doctor compat . --client cursor --apply --backup
244
+ codex-plugin-doctor compat . --client cline
245
+ codex-plugin-doctor compat . --client cline --install-preview
246
+ codex-plugin-doctor compat . --scorecard
247
+ codex-plugin-doctor compat . --json
248
+ codex-plugin-doctor compat . --json --output compatibility.json
249
+ codex-plugin-doctor check .
250
+ codex-plugin-doctor check . --profile ci
251
+ codex-plugin-doctor check . --profile strict
252
+ codex-plugin-doctor check . --profile publish
253
+ codex-plugin-doctor check . --policy codex-publish
254
+ codex-plugin-doctor check . --policy mcp-strict
255
+ codex-plugin-doctor check . --policy security
256
+ codex-plugin-doctor check . --json
257
+ codex-plugin-doctor check . --explain
258
+ codex-plugin-doctor check . --json --output report.json
259
+ codex-plugin-doctor check . --markdown --output report.md
249
260
  codex-plugin-doctor check . --badge-json --output doctor-badge.json
250
261
  codex-plugin-doctor check . --badge-markdown
251
262
  codex-plugin-doctor check . --sarif --output results.sarif
252
263
  codex-plugin-doctor check . --ascii
253
264
  codex-plugin-doctor check . --no-animations
254
- codex-plugin-doctor check . --runtime
255
- codex-plugin-doctor check . --config .codex-doctor.json
256
- codex-plugin-doctor check . --history validation-history.jsonl
257
- codex-plugin-doctor history validation-history.jsonl
258
- codex-plugin-doctor history validation-history.jsonl --json
259
- codex-plugin-doctor history validation-history.jsonl --fail-on-regression
260
- codex-plugin-doctor fix . --dry-run
261
- codex-plugin-doctor fix . --interactive --backup
262
- codex-plugin-doctor fix . --apply --backup
263
- codex-plugin-doctor check . --json --runtime --verbose-runtime
264
- ```
265
-
266
- `self-test` runs the bundled runtime-complete sample through static validation, runtime MCP probes, and the compatibility scorecard. It is the fastest post-install check after `npm install -g codex-plugin-doctor`.
267
-
268
- `doctor` checks the local environment, including package version, platform, Node version, npm global prefix, Codex home, and Codex plugin cache visibility. The text output also includes recommended next commands for self-test, installed plugin discovery, runtime checks, compatibility scoring, and CI setup. `doctor contract` publishes the machine-readable output contract, including public JSON schema surfaces, stable-through-1.0 compatibility metadata, and a frozen rule catalog digest. Add `--json` for automation or `--output output-contract.json` to write the contract to disk. `doctor corpus` runs the bundled validation corpus against healthy runtime, risky security, and starter skill packages, then reports whether each case matched its expected outcome. Add `--json` for automation or `--output validation-corpus.json` to write the corpus report to disk. `doctor npm <package>` runs a preinstall scan by packing the npm package with scripts disabled, extracting the publish tarball, and running validation, security, trust, and recommendation checks against the shipped contents. Add `--json` for automation or `--output npm-preinstall.json` to write the report to disk. `doctor attest <path>` creates a deterministic local attestation with a package fingerprint, report digest, validation/security/compatibility/trust summary, and unsigned verification metadata. Add `--json` for automation or `--output attestation.json` to write the artifact to disk. `doctor inspector <path>` builds a safe MCP Inspector launch command from a packaged `.mcp.json` file without starting the Inspector proxy automatically. Use `--server <name>` when the package contains multiple MCP server entries. `doctor diff --before <path> --after <path>` compares two package roots and reports new findings, resolved findings, trust score delta, and whether risk increased. `doctor recommend <path>` turns validation, security, and compatibility signals into a prioritized action plan with blocker, high, medium, and info actions. Add `--json` for automation or `--output recommendations.json` to write the report to disk. `doctor trust <path>` creates a local trust score from package lifecycle scripts, dependency specs, and MCP security findings. Use it before release when you want supply-chain risks summarized as one score. `doctor perf <path>` profiles the shared package analysis pipeline and reports per-stage durations for validation, config, security, compatibility, trust, recommendations, and total runtime. `doctor export --bundle <path>` creates a redacted operator handoff bundle that includes validation JSON, security scorecard data, compatibility matrix, recommendations, and trust score in one file. `doctor snapshot` creates a redacted diagnostics bundle with environment health, client config readiness, installed plugin metadata, and next commands. Add `--json` for machine-readable output or `--output doctor-snapshot.json` to write the bundle to disk. `doctor clients` reports local Codex, Claude Desktop, Cursor, Cline, and Windsurf config readiness. `doctor --update-check` compares the installed CLI version with the latest npm version and prints the upgrade command when a newer release is available.
269
-
270
- `audit --installed` runs a local ecosystem audit against every discovered Codex plugin in the installed plugin cache. Add `--security` to include security scorecards, `--compat` to include the all-client compatibility matrix, and `--json --output local-audit.json` when you want a shareable machine-readable report. Add `--cache` to reuse unchanged plugin results between runs; add `--changed` to only report plugins whose fingerprint changed since the last cached audit. Use `--cache-file path/to/audit-cache.json` when CI or scripted runs need an explicit cache location.
271
-
272
- `--policy codex-publish|mcp-strict|security` applies opinionated gates without requiring a local `.codex-doctor.json`. `codex-publish` fails warnings and enables runtime probes for release checks, `mcp-strict` does the same for MCP-heavy packages, and `security` fails warning-level security findings so advisory risks can block a local audit or CI gate.
273
-
274
- `mcp <path>` diagnoses generic MCP packages that may not have a Codex plugin manifest. It looks for `.mcp.json` or a manifest `mcpServers` reference, validates the top-level `mcpServers` object and server transports, adds MCP command-surface security findings, and includes the all-client compatibility matrix in the same report.
275
-
276
- `init [path] --template ...` creates targeted starter packages. `skill-only` is the default minimal skill package, `mcp-stdio` adds a local stdio MCP config and mock server, `mcp-http` scaffolds a streamable HTTP MCP config, and `full-runtime` generates a stdio sample that passes the runtime protocol probes.
277
-
278
- `security <path>` renders a focused package security scorecard. It reuses the existing package security findings, then adds deeper MCP command-surface checks for shell wrappers, encoded shell payloads, remote pipe-to-shell startup patterns, `cwd` values outside the plugin root, and plain HTTP URLs. Use `--json` for automation or `--scorecard` for a compact status view.
279
-
280
- `compat --client claude-desktop` checks whether the MCP package can be added to the local Claude Desktop setup. On Windows it looks for `%APPDATA%\Claude\claude_desktop_config.json`; on macOS it looks for `~/Library/Application Support/Claude/claude_desktop_config.json`. A valid existing config returns `PASS`, a missing Claude Desktop install returns `WARN`, and a malformed local config returns `FAIL` so you do not add new servers into a broken config file. If the package server name already exists in Claude Desktop, the command returns `WARN` with the duplicate server name. Add `--install-preview` to print the JSON snippet that should be merged into `claude_desktop_config.json`; it does not modify files. Use `--apply --backup` only when you want the CLI to create a timestamped backup and merge the server config. Apply mode refuses to overwrite duplicate server names.
281
-
282
- `compat --client cursor` checks whether the MCP package can be added to Cursor. It prefers a project-level `.cursor/mcp.json` when one already exists in the target package, then falls back to the global `~/.cursor/mcp.json` path. A valid existing config returns `PASS`, a missing Cursor config returns `WARN`, malformed JSON returns `FAIL`, and duplicate MCP server names return `WARN`. Add `--install-preview` to print the JSON snippet that should be merged into Cursor's `mcp.json`; it does not modify files. Use `--apply --backup` only when you want the CLI to create a timestamped backup and merge the server config. Apply mode refuses to overwrite duplicate server names.
283
-
284
- `compat --client cline` checks whether the MCP package can be added to Cline. It uses `CLINE_DIR/data/settings/cline_mcp_settings.json` when `CLINE_DIR` is set, otherwise `~/.cline/data/settings/cline_mcp_settings.json`. Add `--install-preview` to print the JSON snippet that should be merged into `cline_mcp_settings.json`.
285
-
286
- `compat --all` makes the all-client matrix explicit when you want Codex, Generic MCP, Claude Desktop, Cursor, Cline, and Windsurf in one run. `compat --scorecard` turns the compatibility matrix into a compact score summary. `PASS` maps to `100`, `WARN` maps to `70`, and `FAIL` or `SKIPPED` maps to `0`.
287
-
288
- `check --installed --compat --all-summary` validates every discovered Codex plugin from the local plugin cache and appends a compact compatibility summary for Codex, Generic MCP, Claude Desktop, Cursor, Cline, and Windsurf. This is the fastest repo-free audit when a user does not know individual plugin paths.
289
-
290
- `check --profile ci|strict|publish` applies named validation policies. `ci` keeps default behavior, `strict` fails on warnings, and `publish` fails on warnings while enabling runtime probing by default.
291
-
292
- `check --explain` adds inline rule catalog context to text reports, including why a finding matters, a more detailed fix path, and a compact example.
293
-
294
- `check --badge-json` emits Shields endpoint-compatible JSON such as `{"schemaVersion":1,"label":"doctor","message":"PASS","color":"brightgreen"}`. `check --badge-markdown` emits a static shields.io Markdown badge for README or release notes. Badge output is intentionally limited to single package checks, not `check --installed`.
295
-
296
- `check --history <path>` appends a compact JSONL validation snapshot after a single package check. `history <path>` reads the JSONL file and compares the latest run to the previous run, including status, finding-count deltas, and whether the latest run regressed. Add `history --json` for automation output or `history --fail-on-regression` when CI should fail after a worse latest run.
297
-
298
- `fix --dry-run` renders safe automatic fix plans without changing files. `fix --interactive --backup` shows the same numbered plan, then applies everything after `yes` or only selected action numbers such as `1,3`. `fix --apply --backup` applies supported safe fixes, such as manifest defaults and missing skills directories, after creating backups.
299
-
300
- Optional local policy file:
265
+ codex-plugin-doctor check . --runtime
266
+ codex-plugin-doctor check . --config .codex-doctor.json
267
+ codex-plugin-doctor check . --history validation-history.jsonl
268
+ codex-plugin-doctor history validation-history.jsonl
269
+ codex-plugin-doctor history validation-history.jsonl --json
270
+ codex-plugin-doctor history validation-history.jsonl --fail-on-regression
271
+ codex-plugin-doctor fix . --dry-run
272
+ codex-plugin-doctor fix . --interactive --backup
273
+ codex-plugin-doctor fix . --apply --backup
274
+ codex-plugin-doctor check . --json --runtime --verbose-runtime
275
+ ```
276
+
277
+ `self-test` runs the bundled runtime-complete sample through static validation, runtime MCP probes, and the compatibility scorecard. It is the fastest post-install check after `npm install -g codex-plugin-doctor`.
278
+
279
+ `doctor` checks the local environment, including package version, platform, Node version, npm global prefix, Codex home, and Codex plugin cache visibility. The text output also includes recommended next commands for self-test, installed plugin discovery, runtime checks, compatibility scoring, and CI setup. `doctor contract` publishes the machine-readable output contract, including public JSON schema surfaces, stable-through-1.0 compatibility metadata, and a frozen rule catalog digest. Add `--json` for automation or `--output output-contract.json` to write the contract to disk. `doctor corpus` runs the bundled validation corpus against healthy runtime, risky security, and starter skill packages, then reports whether each case matched its expected outcome. Add `--json` for automation or `--output validation-corpus.json` to write the corpus report to disk. `doctor npm <package>` runs a preinstall scan by packing the npm package with scripts disabled, extracting the publish tarball, and running validation, security, trust, and recommendation checks against the shipped contents. Add `--json` for automation or `--output npm-preinstall.json` to write the report to disk. `doctor attest <path>` creates a deterministic local attestation with a package fingerprint, report digest, validation/security/compatibility/trust summary, and unsigned verification metadata. Add `--json` for automation or `--output attestation.json` to write the artifact to disk. `doctor inspector <path>` builds a safe MCP Inspector launch command from a packaged `.mcp.json` file without starting the Inspector proxy automatically. Use `--server <name>` when the package contains multiple MCP server entries. `doctor diff --before <path> --after <path>` compares two package roots and reports new findings, resolved findings, trust score delta, and whether risk increased. `doctor recommend <path>` turns validation, security, and compatibility signals into a prioritized action plan with blocker, high, medium, and info actions. Add `--json` for automation or `--output recommendations.json` to write the report to disk. `doctor trust <path>` creates a local trust score from package lifecycle scripts, dependency specs, and MCP security findings. Use it before release when you want supply-chain risks summarized as one score. `doctor perf <path>` profiles the shared package analysis pipeline and reports per-stage durations for validation, config, security, compatibility, trust, recommendations, and total runtime. `doctor export --bundle <path>` creates a redacted operator handoff bundle that includes validation JSON, security scorecard data, compatibility matrix, recommendations, and trust score in one file. `doctor snapshot` creates a redacted diagnostics bundle with environment health, client config readiness, installed plugin metadata, and next commands. Add `--json` for machine-readable output or `--output doctor-snapshot.json` to write the bundle to disk. `doctor clients` reports local Codex, Claude Desktop, Cursor, Cline, and Windsurf config readiness. `doctor --update-check` compares the installed CLI version with the latest npm version and prints the upgrade command when a newer release is available.
280
+
281
+ `audit --installed` runs a local ecosystem audit against every discovered Codex plugin in the installed plugin cache. Add `--security` to include security scorecards, `--compat` to include the all-client compatibility matrix, and `--json --output local-audit.json` when you want a shareable machine-readable report. Add `--cache` to reuse unchanged plugin results between runs; add `--changed` to only report plugins whose fingerprint changed since the last cached audit. Use `--cache-file path/to/audit-cache.json` when CI or scripted runs need an explicit cache location.
282
+
283
+ `--policy codex-publish|mcp-strict|security` applies opinionated gates without requiring a local `.codex-doctor.json`. `codex-publish` fails warnings and enables runtime probes for release checks, `mcp-strict` does the same for MCP-heavy packages, and `security` fails warning-level security findings so advisory risks can block a local audit or CI gate.
284
+
285
+ `mcp <path>` diagnoses generic MCP packages that may not have a Codex plugin manifest. It looks for `.mcp.json` or a manifest `mcpServers` reference, validates the top-level `mcpServers` object and server transports, adds MCP command-surface security findings, and includes the all-client compatibility matrix in the same report.
286
+
287
+ `init [path] --template ...` creates targeted starter packages. `skill-only` is the default minimal skill package, `mcp-stdio` adds a local stdio MCP config and mock server, `mcp-http` scaffolds a streamable HTTP MCP config, and `full-runtime` generates a stdio sample that passes the runtime protocol probes.
288
+
289
+ `security <path>` renders a focused package security scorecard. It reuses the existing package security findings, then adds deeper MCP command-surface checks for shell wrappers, encoded shell payloads, remote pipe-to-shell startup patterns, `cwd` values outside the plugin root, and plain HTTP URLs. Use `--json` for automation or `--scorecard` for a compact status view.
290
+
291
+ `compat --client claude-desktop` checks whether the MCP package can be added to the local Claude Desktop setup. On Windows it looks for `%APPDATA%\Claude\claude_desktop_config.json`; on macOS it looks for `~/Library/Application Support/Claude/claude_desktop_config.json`. A valid existing config returns `PASS`, a missing Claude Desktop install returns `WARN`, and a malformed local config returns `FAIL` so you do not add new servers into a broken config file. If the package server name already exists in Claude Desktop, the command returns `WARN` with the duplicate server name. Add `--install-preview` to print the JSON snippet that should be merged into `claude_desktop_config.json`; it does not modify files. Use `--apply --backup` only when you want the CLI to create a timestamped backup and merge the server config. Apply mode refuses to overwrite duplicate server names.
292
+
293
+ `compat --client cursor` checks whether the MCP package can be added to Cursor. It prefers a project-level `.cursor/mcp.json` when one already exists in the target package, then falls back to the global `~/.cursor/mcp.json` path. A valid existing config returns `PASS`, a missing Cursor config returns `WARN`, malformed JSON returns `FAIL`, and duplicate MCP server names return `WARN`. Add `--install-preview` to print the JSON snippet that should be merged into Cursor's `mcp.json`; it does not modify files. Use `--apply --backup` only when you want the CLI to create a timestamped backup and merge the server config. Apply mode refuses to overwrite duplicate server names.
294
+
295
+ `compat --client cline` checks whether the MCP package can be added to Cline. It uses `CLINE_DIR/data/settings/cline_mcp_settings.json` when `CLINE_DIR` is set, otherwise `~/.cline/data/settings/cline_mcp_settings.json`. Add `--install-preview` to print the JSON snippet that should be merged into `cline_mcp_settings.json`.
296
+
297
+ `compat --all` makes the all-client matrix explicit when you want Codex, Generic MCP, Claude Desktop, Cursor, Cline, and Windsurf in one run. `compat --scorecard` turns the compatibility matrix into a compact score summary. `PASS` maps to `100`, `WARN` maps to `70`, and `FAIL` or `SKIPPED` maps to `0`.
298
+
299
+ `check --installed --compat --all-summary` validates every discovered Codex plugin from the local plugin cache and appends a compact compatibility summary for Codex, Generic MCP, Claude Desktop, Cursor, Cline, and Windsurf. This is the fastest repo-free audit when a user does not know individual plugin paths.
300
+
301
+ `check --profile ci|strict|publish` applies named validation policies. `ci` keeps default behavior, `strict` fails on warnings, and `publish` fails on warnings while enabling runtime probing by default.
302
+
303
+ `check --explain` adds inline rule catalog context to text reports, including why a finding matters, a more detailed fix path, and a compact example.
304
+
305
+ `check --badge-json` emits Shields endpoint-compatible JSON such as `{"schemaVersion":1,"label":"doctor","message":"PASS","color":"brightgreen"}`. `check --badge-markdown` emits a static shields.io Markdown badge for README or release notes. Badge output is intentionally limited to single package checks, not `check --installed`.
306
+
307
+ `check --history <path>` appends a compact JSONL validation snapshot after a single package check. `history <path>` reads the JSONL file and compares the latest run to the previous run, including status, finding-count deltas, and whether the latest run regressed. Add `history --json` for automation output or `history --fail-on-regression` when CI should fail after a worse latest run.
308
+
309
+ `fix --dry-run` renders safe automatic fix plans without changing files. `fix --interactive --backup` shows the same numbered plan, then applies everything after `yes` or only selected action numbers such as `1,3`. `fix --apply --backup` applies supported safe fixes, such as manifest defaults and missing skills directories, after creating backups.
310
+
311
+ Optional local policy file:
301
312
 
302
313
  ```json
303
314
  {
@@ -310,10 +321,10 @@ Run these when you want Codex Plugin Doctor to find plugins from the local Codex
310
321
 
311
322
  ```bash
312
323
  codex-plugin-doctor list --installed
313
- codex-plugin-doctor check --installed
314
- codex-plugin-doctor check --installed --all-summary
315
- codex-plugin-doctor check --installed --compat --all-summary
316
- codex-plugin-doctor check --installed github
324
+ codex-plugin-doctor check --installed
325
+ codex-plugin-doctor check --installed --all-summary
326
+ codex-plugin-doctor check --installed --compat --all-summary
327
+ codex-plugin-doctor check --installed github
317
328
  codex-plugin-doctor check --installed github --runtime --no-animations
318
329
  codex-plugin-doctor explain plugin.security.hard_coded_secret
319
330
  ```
@@ -331,14 +342,17 @@ jobs:
331
342
  runs-on: ubuntu-latest
332
343
  steps:
333
344
  - uses: actions/checkout@v4
334
- - uses: Esquetta/CodexPluginDoctor@v0.9.0
335
- with:
336
- version: "0.9.0"
337
- path: .
338
- runtime: "false"
345
+ - uses: Esquetta/CodexPluginDoctor@v0.21.0
346
+ with:
347
+ version: "0.21.0"
348
+ path: .
349
+ runtime: "true"
350
+ policy: codex-publish
351
+ upload-artifact: "true"
352
+ artifact-name: codex-plugin-doctor-reports
339
353
  ```
340
354
 
341
- For runtime probing, SARIF output, installed plugin cache checks, and pinned release examples, see [GitHub Action Usage](./docs/engineering/github-action-usage.md).
355
+ The action writes `codex-plugin-doctor-summary.md`, `codex-plugin-doctor-report.json`, and optional `codex-plugin-doctor.sarif` files to `codex-plugin-doctor-reports`, appends the Markdown report to the GitHub Actions step summary, uploads the report directory as an artifact, and then returns the real validation exit code. For runtime probing, SARIF output, installed plugin cache checks, CI policy presets, and pinned release examples, see [GitHub Action Usage](./docs/engineering/github-action-usage.md).
342
356
 
343
357
  To self-test this repository after cloning it:
344
358
 
@@ -376,12 +390,12 @@ Recent validation waves covered:
376
390
 
377
391
  Release preparation is reproducible from the repository:
378
392
 
379
- ```bash
380
- npm run prepare-release
381
- npm run release-check
382
- ```
383
-
384
- `prepare-release` runs tests, builds the TypeScript output, and performs `npm pack --dry-run`. `release-check` adds release preflight checks for a clean git tree, existing npm versions, existing version tags, tests, build, and pack dry-run.
393
+ ```bash
394
+ npm run prepare-release
395
+ npm run release-check
396
+ ```
397
+
398
+ `prepare-release` runs tests, builds the TypeScript output, and performs `npm pack --dry-run`. `release-check` adds release preflight checks for a clean git tree, existing npm versions, existing version tags, tests, build, and pack dry-run.
385
399
 
386
400
  Related docs:
387
401
 
@@ -391,7 +405,7 @@ Related docs:
391
405
  - [Code of Conduct](./CODE_OF_CONDUCT.md)
392
406
  - [NPM Release Checklist](./docs/engineering/npm-release-checklist.md)
393
407
  - [Release Candidate Workflow](./docs/engineering/release-candidate-workflow.md)
394
- - [v0.1.0 Release Notes](./docs/engineering/v0.1.0-final-release-notes.md)
408
+ - [v1.0 Readiness Checklist](./docs/engineering/v1.0-readiness-checklist.md)
395
409
 
396
410
  ## Contributing
397
411
 
@@ -21,6 +21,13 @@ function buildWorkflow() {
21
21
  ` version: \"${packageVersion}\"`,
22
22
  " path: .",
23
23
  " runtime: \"true\"",
24
+ " policy: codex-publish",
25
+ " json: \"true\"",
26
+ " markdown: \"true\"",
27
+ " sarif: \"true\"",
28
+ " upload-artifact: \"true\"",
29
+ " step-summary: \"true\"",
30
+ " artifact-name: codex-plugin-doctor-reports",
24
31
  ""
25
32
  ].join("\n");
26
33
  }
@@ -7,6 +7,12 @@ const publicSchemaDefinitions = [
7
7
  command: "codex-plugin-doctor check <path> --json",
8
8
  required: ["schemaVersion", "generatedAt", "summary", "findings"]
9
9
  },
10
+ {
11
+ id: "doctor.installed.check.json",
12
+ command: "codex-plugin-doctor check --installed --json",
13
+ outputKind: "doctor.installed.check",
14
+ required: ["schemaVersion", "kind", "generatedAt", "summary", "plugins"]
15
+ },
10
16
  {
11
17
  id: "doctor.security.json",
12
18
  command: "codex-plugin-doctor security <path> --json",
@@ -0,0 +1,37 @@
1
+ import type { CompatibilityMatrix } from "../compatibility/compatibility-matrix.js";
2
+ import type { InstalledPlugin } from "../core/discover-installed-plugins.js";
3
+ import type { CheckResult, JsonReport } from "../domain/types.js";
4
+ export interface InstalledCheckItem {
5
+ plugin: InstalledPlugin;
6
+ result: CheckResult;
7
+ compatibilityMatrix?: CompatibilityMatrix;
8
+ }
9
+ export interface InstalledCheckJsonReport {
10
+ schemaVersion: "1.0.0";
11
+ kind: "doctor.installed.check";
12
+ generatedAt: string;
13
+ summary: {
14
+ status: "pass" | "warn" | "fail";
15
+ checked: number;
16
+ pass: number;
17
+ warn: number;
18
+ fail: number;
19
+ };
20
+ plugins: Array<{
21
+ plugin: {
22
+ name: string;
23
+ version?: string;
24
+ rootPath: string;
25
+ relativePath: string;
26
+ };
27
+ report: JsonReport;
28
+ compatibilityMatrix?: CompatibilityMatrix;
29
+ }>;
30
+ }
31
+ export declare function buildInstalledJsonReport(items: InstalledCheckItem[], options: {
32
+ runtimeProbeEnabled: boolean;
33
+ }): InstalledCheckJsonReport;
34
+ export declare function renderInstalledJsonReport(items: InstalledCheckItem[], options: {
35
+ runtimeProbeEnabled: boolean;
36
+ }): string;
37
+ export declare function renderInstalledSarifReport(items: InstalledCheckItem[]): string;
@@ -0,0 +1,56 @@
1
+ import { buildJsonReport } from "./render-json-report.js";
2
+ import { renderSarifReport } from "./render-sarif-report.js";
3
+ function summarizeStatus(items) {
4
+ const pass = items.filter((item) => item.result.status === "pass").length;
5
+ const warn = items.filter((item) => item.result.status === "warn").length;
6
+ const fail = items.filter((item) => item.result.status === "fail").length;
7
+ return {
8
+ status: fail > 0 ? "fail" : warn > 0 ? "warn" : "pass",
9
+ checked: items.length,
10
+ pass,
11
+ warn,
12
+ fail
13
+ };
14
+ }
15
+ export function buildInstalledJsonReport(items, options) {
16
+ return {
17
+ schemaVersion: "1.0.0",
18
+ kind: "doctor.installed.check",
19
+ generatedAt: new Date().toISOString(),
20
+ summary: summarizeStatus(items),
21
+ plugins: items.map((item) => ({
22
+ plugin: {
23
+ name: item.plugin.name,
24
+ ...(item.plugin.version ? { version: item.plugin.version } : {}),
25
+ rootPath: item.plugin.rootPath,
26
+ relativePath: item.plugin.relativePath
27
+ },
28
+ report: buildJsonReport(item.result, options),
29
+ ...(item.compatibilityMatrix ? { compatibilityMatrix: item.compatibilityMatrix } : {})
30
+ }))
31
+ };
32
+ }
33
+ export function renderInstalledJsonReport(items, options) {
34
+ return JSON.stringify(buildInstalledJsonReport(items, options), null, 2);
35
+ }
36
+ export function renderInstalledSarifReport(items) {
37
+ const runs = items.flatMap((item) => {
38
+ const sarif = JSON.parse(renderSarifReport(item.result));
39
+ return sarif.runs.map((run) => ({
40
+ ...run,
41
+ automationDetails: {
42
+ id: item.plugin.name
43
+ },
44
+ properties: {
45
+ pluginName: item.plugin.name,
46
+ ...(item.plugin.version ? { pluginVersion: item.plugin.version } : {}),
47
+ pluginPath: item.plugin.rootPath
48
+ }
49
+ }));
50
+ });
51
+ return JSON.stringify({
52
+ version: "2.1.0",
53
+ $schema: "https://json.schemastore.org/sarif-2.1.0.json",
54
+ runs
55
+ }, null, 2);
56
+ }
package/dist/run-cli.js CHANGED
@@ -30,6 +30,7 @@ import { initPluginPackage, initPluginTemplates, isInitPluginTemplate } from "./
30
30
  import { runCheck } from "./index.js";
31
31
  import { buildGenericMcpDoctor, renderGenericMcpDoctor, renderGenericMcpDoctorJson } from "./mcp/generic-mcp-doctor.js";
32
32
  import { renderInstalledSummary } from "./reporting/render-installed-summary.js";
33
+ import { renderInstalledJsonReport, renderInstalledSarifReport } from "./reporting/render-installed-machine-report.js";
33
34
  import { renderBadgeJson, renderBadgeMarkdown } from "./reporting/render-badge-report.js";
34
35
  import { renderCompatibilityScorecard } from "./reporting/render-compatibility-scorecard.js";
35
36
  import { renderCompatibilityReport } from "./reporting/render-compatibility-report.js";
@@ -1016,18 +1017,18 @@ export async function runCli(args, io = defaultIo, options = {}) {
1016
1017
  }
1017
1018
  const report = installedSummary
1018
1019
  ? renderInstalledSummary(checkedPlugins)
1019
- : checkedPlugins
1020
- .map((item) => sarifOutput
1021
- ? renderSarifReport(item.result)
1022
- : markdownOutput
1023
- ? buildMarkdownReport(item.result, { runtimeProbeEnabled: effectiveRuntimeProbeEnabled })
1024
- : jsonOutput
1025
- ? renderJsonReport(item.result, { runtimeProbeEnabled: effectiveRuntimeProbeEnabled })
1020
+ : sarifOutput
1021
+ ? renderInstalledSarifReport(checkedPlugins)
1022
+ : jsonOutput
1023
+ ? renderInstalledJsonReport(checkedPlugins, { runtimeProbeEnabled: effectiveRuntimeProbeEnabled })
1024
+ : checkedPlugins
1025
+ .map((item) => markdownOutput
1026
+ ? buildMarkdownReport(item.result, { runtimeProbeEnabled: effectiveRuntimeProbeEnabled })
1026
1027
  : renderTextReport(item.result, {
1027
1028
  ascii: outputPolicy.style === "ascii",
1028
1029
  explain: explainFindings
1029
1030
  }))
1030
- .join("\n\n");
1031
+ .join("\n\n");
1031
1032
  if (outputPath) {
1032
1033
  await writeFile(outputPath, report, "utf8");
1033
1034
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-plugin-doctor",
3
- "version": "0.19.0",
3
+ "version": "0.21.0",
4
4
  "description": "CLI-first validator for Codex plugins, skills, and MCP package surfaces with runtime MCP protocol validation.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",