codex-plugin-doctor 1.53.0 → 1.55.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/dist/run-cli.js CHANGED
@@ -28,6 +28,8 @@ import { buildDoctorRuntimePolicyReport, renderDoctorRuntimePolicy, renderDoctor
28
28
  import { buildDoctorReviewBundle, diffDoctorReviewBundles, renderDoctorReviewBundle, renderDoctorReviewBundleDiff, renderDoctorReviewBundleDiffJson, renderDoctorReviewBundleJson, renderDoctorReviewBundleVerification, renderDoctorReviewBundleVerificationJson, verifyDoctorReviewBundle } from "./core/review-bundle.js";
29
29
  import { buildDoctorReleaseEvidenceAssetReport, buildDoctorReleaseEvidenceReport, renderDoctorReleaseEvidenceAsset, renderDoctorReleaseEvidenceAssetJson, renderDoctorReleaseEvidence, renderDoctorReleaseEvidenceJson, renderDoctorReleaseEvidenceVerification, renderDoctorReleaseEvidenceVerificationJson, verifyDoctorReleaseEvidence } from "./core/release-evidence.js";
30
30
  import { buildDoctorNpmPackageReport, renderDoctorNpmPackageReport, renderDoctorNpmPackageReportJson } from "./core/npm-package-doctor.js";
31
+ import { buildMcpRegistryReadiness, inspectMcpRegistryServer, registryReadinessExitCode, renderMcpRegistryReadiness, renderMcpRegistryReadinessJson } from "./core/mcp-registry.js";
32
+ import { buildMcpRegistryPublicationPreflight, registryPublicationPreflightExitCode, renderMcpRegistryPublicationPreflight, renderMcpRegistryPublicationPreflightJson } from "./core/mcp-registry-preflight.js";
31
33
  import { buildDoctorRiskDiffReport, renderDoctorRiskDiffReport, renderDoctorRiskDiffReportJson } from "./core/risk-diff.js";
32
34
  import { buildDoctorInspectorReport, renderDoctorInspectorReport, renderDoctorInspectorReportJson } from "./core/inspector-bridge.js";
33
35
  import { applyFixPlan, buildFixPlan, renderApplyFixResult, renderFixPlanJsonReport, renderFixPlan } from "./core/fix-plan.js";
@@ -167,6 +169,9 @@ function parseRemoteNetworkFlags(flags, runtime) {
167
169
  }
168
170
  function printUsage(io) {
169
171
  io.writeStderr("Usage: codex-plugin-doctor check <path|--installed> [filter] [--policy codex-publish|mcp-strict|security] [--compat] [--json|--markdown|--badge-json|--badge-markdown] [--output <path>] [--history <path>] [--runtime [--allow-network [--allow-local-network]]] [--sandbox docker] [--require-runtime-approval --runtime-approval-digest <digest>] [--verbose-runtime] [--explain] [--no-animations] [--ascii] [--changed-since <ref>]\n codex-plugin-doctor audit --installed [filter] [--policy codex-publish|mcp-strict|security] [--security] [--compat] [--json] [--output <path>] [--cache] [--changed]\n codex-plugin-doctor audit deps <path> [--policy codex-publish|mcp-strict|security] [--recommend] [--json|--sarif] [--output <path>]\n codex-plugin-doctor mcp <path> [--runtime [--allow-network [--allow-local-network]]] [--json] [--output <path>]\n codex-plugin-doctor security <path> [--policy security] [--json|--scorecard]\n codex-plugin-doctor compat <path> [--all|--client <client>] [--json] [--scorecard] [--output <path>] [--install-preview|--apply --backup]\n codex-plugin-doctor suppress add <path> [--fingerprint <sha256> --reason <text> --expires-at YYYY-MM-DD] [--config <path>] [--json]\n codex-plugin-doctor suppress list <path> [--config <path>] [--json]\n codex-plugin-doctor suppress remove <path> [--fingerprint <sha256>|--index <n>] [--config <path>] [--json]\n codex-plugin-doctor fix <path> (--dry-run|--interactive --backup|--apply --backup)\n codex-plugin-doctor history <history.jsonl> [--json] [--fail-on-regression]\n codex-plugin-doctor watch <path> [--runtime] [--json] [--output <path>] [--debounce-ms <ms>] [--max-iterations <n>] [--fail-fast] [--accumulate-json <path>]\n codex-plugin-doctor doctor [npm <package>|contract|corpus [--manifest <corpus.json>] [--json] [--output <path>]|corpus metrics --manifest <corpus.json> [--json|--markdown] [--output <path>] [--min-precision <0..1>] [--min-recall <0..1>] [--max-false-positive-rate <0..1>]|runtime-plan <path> [--sandbox docker] [--json|--markdown] [--output <path>]|runtime-policy <path> [--sandbox docker] [--json] [--output <path>]|review-bundle <path> --output <dir> --sign-key-env NAME [--json] [--allow-dirty] [--allow-untagged]|review-bundle verify <bundle-dir> --target <path> --sign-key-env NAME [--json] [--output <path>] [--failures-only]|review-bundle diff --before <dir> --after <dir> [--json]|attest <path> [--sign-key-env NAME]|attest verify <attestation.json> --target <path> --sign-key-env NAME|release-evidence <path> --sign-key-env NAME [--runtime [--allow-network [--allow-local-network]]] [--sandbox docker] [--allow-dirty] [--allow-untagged] [--require-runtime-approval --runtime-approval-digest <digest>]|release-evidence verify <evidence.json> --target <path> --sign-key-env NAME|release-evidence asset <path> --tag <tag> --output <evidence.json> --sign-key-env NAME [--runtime [--allow-network [--allow-local-network]]] [--sandbox docker] [--allow-dirty] [--allow-untagged] [--require-runtime-approval --runtime-approval-digest <digest>] [--upload]|mcp <path> [--runtime [--allow-network [--allow-local-network]]]|inspector <path>|diff --before <path> --after <path>|recommend <path>|trust <path>|perf <path> [--max-total-ms <ms>] [--max-stage-ms stage=ms]|export --bundle <path>|snapshot|clients|--json|--update-check]\n codex-plugin-doctor init [path] [--template skill-only|mcp-stdio|mcp-http|full-runtime]\n codex-plugin-doctor init-ci [path]\n codex-plugin-doctor init-git-hooks [path] [--force] [--json]\n codex-plugin-doctor init-git-hooks [path] --remove [--json]\n codex-plugin-doctor completion bash|zsh|fish\n codex-plugin-doctor config validate <path> [--json]\n codex-plugin-doctor release check <path> [--json] [--runtime [--allow-network [--allow-local-network]]] [--sandbox docker]\n codex-plugin-doctor self-test\n codex-plugin-doctor list --installed\n codex-plugin-doctor explain <finding-id>\n codex-plugin-doctor --version\n\nFirst run:\n codex-plugin-doctor doctor\n codex-plugin-doctor self-test\n codex-plugin-doctor init my-plugin\n codex-plugin-doctor check . --runtime --explain");
172
+ io.writeStderr("Registry readiness: codex-plugin-doctor registry check <server.json|directory> [--json] [--output <path>] [--require-registry-readiness]\n"
173
+ + " codex-plugin-doctor registry inspect <server-name> --allow-network [--json] [--output <path>] [--require-registry-readiness]\n"
174
+ + "Registry publication preflight: codex-plugin-doctor registry preflight <server.json|directory> [--allow-network] [--json] [--output <path>] [--require-publish-ready]");
170
175
  io.writeStderr("Corpus quality regression: codex-plugin-doctor doctor corpus metrics diff --before <metrics.json> --after <metrics.json> [--fail-on-regression] [--json|--markdown] [--output <path>]");
171
176
  io.writeStderr("Suppression governance: codex-plugin-doctor suppress list <path> [--fail-on-expired] [--fail-on-invalid] [--warn-expiring-within-days <days>]\n codex-plugin-doctor suppress prune <path> [--apply] [--json]");
172
177
  io.writeStderr("Baseline gating: codex-plugin-doctor baseline create <path> --output <path> [--runtime]\n codex-plugin-doctor check <path> --baseline <path>");
@@ -2356,6 +2361,91 @@ export async function runCli(args, io = defaultIo, options = {}) {
2356
2361
  : renderApplyFixResult(result));
2357
2362
  return 0;
2358
2363
  }
2364
+ if (command === "registry") {
2365
+ const subcommand = maybePath;
2366
+ const target = remainingArgs[0];
2367
+ const flags = remainingArgs.slice(1);
2368
+ if ((subcommand !== "check" && subcommand !== "inspect" && subcommand !== "preflight") || !target || target.startsWith("--")) {
2369
+ io.writeStderr("Usage: codex-plugin-doctor registry check <server.json|directory> [--json] [--output <path>] [--require-registry-readiness]\n"
2370
+ + " codex-plugin-doctor registry inspect <server-name> --allow-network [--json] [--output <path>] [--require-registry-readiness]\n"
2371
+ + " codex-plugin-doctor registry preflight <server.json|directory> [--allow-network] [--json] [--output <path>] [--require-publish-ready]");
2372
+ return 2;
2373
+ }
2374
+ const allowedFlags = new Set([
2375
+ "--json",
2376
+ "--output",
2377
+ "--allow-network",
2378
+ "--require-registry-readiness",
2379
+ "--require-publish-ready"
2380
+ ]);
2381
+ let outputPath = null;
2382
+ for (let index = 0; index < flags.length; index += 1) {
2383
+ const flag = flags[index];
2384
+ if (!allowedFlags.has(flag)) {
2385
+ io.writeStderr(`Unknown registry flag: ${flag}.`);
2386
+ return 2;
2387
+ }
2388
+ if (flag === "--output") {
2389
+ const value = flags[index + 1];
2390
+ if (!value || value.startsWith("--")) {
2391
+ io.writeStderr("Missing path after --output.");
2392
+ return 2;
2393
+ }
2394
+ outputPath = value;
2395
+ index += 1;
2396
+ }
2397
+ }
2398
+ const allowNetwork = flags.includes("--allow-network");
2399
+ if (subcommand === "check" && allowNetwork) {
2400
+ io.writeStderr("--allow-network is not supported by registry check.");
2401
+ return 2;
2402
+ }
2403
+ if (subcommand === "inspect" && !allowNetwork) {
2404
+ io.writeStderr("registry inspect requires explicit --allow-network consent.");
2405
+ return 2;
2406
+ }
2407
+ if (subcommand === "preflight" && flags.includes("--require-registry-readiness")) {
2408
+ io.writeStderr("--require-registry-readiness is supported only by registry check or registry inspect.");
2409
+ return 2;
2410
+ }
2411
+ if (subcommand !== "preflight" && flags.includes("--require-publish-ready")) {
2412
+ io.writeStderr("--require-publish-ready is supported only by registry preflight.");
2413
+ return 2;
2414
+ }
2415
+ try {
2416
+ if (subcommand === "preflight") {
2417
+ const report = await buildMcpRegistryPublicationPreflight(target, { allowNetwork });
2418
+ const rendered = flags.includes("--json")
2419
+ ? renderMcpRegistryPublicationPreflightJson(report)
2420
+ : renderMcpRegistryPublicationPreflight(report);
2421
+ if (outputPath) {
2422
+ await writeFile(outputPath, rendered, "utf8");
2423
+ }
2424
+ io.writeStdout(rendered);
2425
+ return registryPublicationPreflightExitCode(report, flags.includes("--require-publish-ready"));
2426
+ }
2427
+ const report = subcommand === "check"
2428
+ ? await buildMcpRegistryReadiness(target)
2429
+ : await inspectMcpRegistryServer(target, { allowNetwork: true });
2430
+ const rendered = flags.includes("--json")
2431
+ ? renderMcpRegistryReadinessJson(report)
2432
+ : renderMcpRegistryReadiness(report);
2433
+ if (outputPath) {
2434
+ await writeFile(outputPath, rendered, "utf8");
2435
+ }
2436
+ io.writeStdout(rendered);
2437
+ return registryReadinessExitCode(report, flags.includes("--require-registry-readiness"));
2438
+ }
2439
+ catch (error) {
2440
+ if (subcommand === "preflight") {
2441
+ io.writeStderr("Registry publication preflight failed.");
2442
+ }
2443
+ else {
2444
+ io.writeStderr(`Registry inspection failed: ${error.message}`);
2445
+ }
2446
+ return 1;
2447
+ }
2448
+ }
2359
2449
  if (command === "security") {
2360
2450
  if (!maybePath || maybePath.startsWith("--")) {
2361
2451
  io.writeStderr("Missing target path. Usage: codex-plugin-doctor security <path> [--json|--scorecard]");
@@ -1,94 +1,94 @@
1
- # Examples
2
-
3
- This folder contains manual example packs for local testing. Unlike `tests/fixtures`, these examples are meant for humans to run directly against the CLI.
4
-
5
- ## Example Packs
6
-
7
- Use the smallest example that matches what you need to prove:
8
-
9
- - `codex-doctor-starter` for static manifest and skill validation.
10
- - `codex-doctor-runtime` for full MCP runtime probing and compatibility scoring.
11
- - `codex-doctor-risky` for security finding output.
12
- - `codex-doctor-generic-mcp` for MCP-only packages without a Codex plugin manifest.
13
-
14
- ### `codex-doctor-starter`
15
-
16
- Minimal valid Codex plugin package with one skill and no runtime MCP server.
17
-
18
- Expected result:
19
-
20
- - static validation passes
21
- - no runtime probing needed
22
-
23
- Command:
24
-
25
- ```bash
26
- codex-plugin-doctor check examples/codex-doctor-starter
27
- ```
28
-
29
- ### `codex-doctor-runtime`
30
-
31
- Valid Codex plugin package with:
32
-
33
- - skill metadata
34
- - `.mcp.json`
35
- - mock MCP stdio server
36
- - `tools/list`
37
- - `tools/call`
38
- - `resources/list`
39
- - `resources/read`
40
- - `resources/templates/list`
41
- - `prompts/list`
42
- - `prompts/get`
43
-
44
- Expected result:
45
-
46
- - static validation passes
47
- - runtime validation passes
48
- - runtime scorecard shows all supported runtime capabilities as `pass`
49
-
50
- Command:
51
-
52
- ```bash
53
- codex-plugin-doctor check examples/codex-doctor-runtime --json --runtime --verbose-runtime
54
- ```
55
-
56
- ### `codex-doctor-risky`
57
-
58
- Intentionally flawed package for showing failure output.
59
-
60
- Expected result:
61
-
62
- - security finding for hard-coded secret
63
-
64
- Command:
65
-
66
- ```bash
67
- codex-plugin-doctor check examples/codex-doctor-risky --ascii
68
- ```
69
-
70
- ### `codex-doctor-generic-mcp`
71
-
72
- Generic MCP package with a `.mcp.json` file and no Codex plugin manifest.
73
-
74
- Expected result:
75
-
76
- - `codex-plugin-doctor mcp` passes generic MCP static health checks
77
- - `codex-plugin-doctor check` still reports the missing Codex plugin manifest
78
-
79
- Command:
80
-
81
- ```bash
82
- codex-plugin-doctor mcp examples/codex-doctor-generic-mcp
83
- ```
84
-
85
- ## Suggested Local Flow
86
-
87
- ```bash
88
- npm install
89
- npm run build
90
- npm link
91
- codex-plugin-doctor check examples/codex-doctor-starter
92
- codex-plugin-doctor check examples/codex-doctor-runtime --json --runtime --verbose-runtime
93
- codex-plugin-doctor check examples/codex-doctor-risky --ascii
94
- ```
1
+ # Examples
2
+
3
+ This folder contains manual example packs for local testing. Unlike `tests/fixtures`, these examples are meant for humans to run directly against the CLI.
4
+
5
+ ## Example Packs
6
+
7
+ Use the smallest example that matches what you need to prove:
8
+
9
+ - `codex-doctor-starter` for static manifest and skill validation.
10
+ - `codex-doctor-runtime` for full MCP runtime probing and compatibility scoring.
11
+ - `codex-doctor-risky` for security finding output.
12
+ - `codex-doctor-generic-mcp` for MCP-only packages without a Codex plugin manifest.
13
+
14
+ ### `codex-doctor-starter`
15
+
16
+ Minimal valid Codex plugin package with one skill and no runtime MCP server.
17
+
18
+ Expected result:
19
+
20
+ - static validation passes
21
+ - no runtime probing needed
22
+
23
+ Command:
24
+
25
+ ```bash
26
+ codex-plugin-doctor check examples/codex-doctor-starter
27
+ ```
28
+
29
+ ### `codex-doctor-runtime`
30
+
31
+ Valid Codex plugin package with:
32
+
33
+ - skill metadata
34
+ - `.mcp.json`
35
+ - mock MCP stdio server
36
+ - `tools/list`
37
+ - `tools/call`
38
+ - `resources/list`
39
+ - `resources/read`
40
+ - `resources/templates/list`
41
+ - `prompts/list`
42
+ - `prompts/get`
43
+
44
+ Expected result:
45
+
46
+ - static validation passes
47
+ - runtime validation passes
48
+ - runtime scorecard shows all supported runtime capabilities as `pass`
49
+
50
+ Command:
51
+
52
+ ```bash
53
+ codex-plugin-doctor check examples/codex-doctor-runtime --json --runtime --verbose-runtime
54
+ ```
55
+
56
+ ### `codex-doctor-risky`
57
+
58
+ Intentionally flawed package for showing failure output.
59
+
60
+ Expected result:
61
+
62
+ - security finding for hard-coded secret
63
+
64
+ Command:
65
+
66
+ ```bash
67
+ codex-plugin-doctor check examples/codex-doctor-risky --ascii
68
+ ```
69
+
70
+ ### `codex-doctor-generic-mcp`
71
+
72
+ Generic MCP package with a `.mcp.json` file and no Codex plugin manifest.
73
+
74
+ Expected result:
75
+
76
+ - `codex-plugin-doctor mcp` passes generic MCP static health checks
77
+ - `codex-plugin-doctor check` still reports the missing Codex plugin manifest
78
+
79
+ Command:
80
+
81
+ ```bash
82
+ codex-plugin-doctor mcp examples/codex-doctor-generic-mcp
83
+ ```
84
+
85
+ ## Suggested Local Flow
86
+
87
+ ```bash
88
+ npm install
89
+ npm run build
90
+ npm link
91
+ codex-plugin-doctor check examples/codex-doctor-starter
92
+ codex-plugin-doctor check examples/codex-doctor-runtime --json --runtime --verbose-runtime
93
+ codex-plugin-doctor check examples/codex-doctor-risky --ascii
94
+ ```
@@ -1,10 +1,10 @@
1
- {
2
- "mcpServers": {
3
- "genericRuntime": {
4
- "command": "node",
5
- "args": [
6
- "server.js"
7
- ]
8
- }
9
- }
10
- }
1
+ {
2
+ "mcpServers": {
3
+ "genericRuntime": {
4
+ "command": "node",
5
+ "args": [
6
+ "server.js"
7
+ ]
8
+ }
9
+ }
10
+ }
@@ -1 +1 @@
1
- process.stdin.resume();
1
+ process.stdin.resume();
@@ -1,7 +1,7 @@
1
- {
2
- "name": "codex-doctor-risky",
3
- "version": "1.0.0",
4
- "description": "Intentionally risky sample package for showing Codex Doctor failure output.",
5
- "mcpServers": "./.mcp.json"
6
- }
7
-
1
+ {
2
+ "name": "codex-doctor-risky",
3
+ "version": "1.0.0",
4
+ "description": "Intentionally risky sample package for showing Codex Doctor failure output.",
5
+ "mcpServers": "./.mcp.json"
6
+ }
7
+
@@ -1,12 +1,12 @@
1
- {
2
- "mcpServers": {
3
- "dangerServer": {
4
- "command": "node",
5
- "args": ["./mock-server.js"],
6
- "env": {
7
- "OPENAI_API_KEY": "sk-live-example-secret-value"
8
- }
9
- }
10
- }
11
- }
12
-
1
+ {
2
+ "mcpServers": {
3
+ "dangerServer": {
4
+ "command": "node",
5
+ "args": ["./mock-server.js"],
6
+ "env": {
7
+ "OPENAI_API_KEY": "sk-live-example-secret-value"
8
+ }
9
+ }
10
+ }
11
+ }
12
+
@@ -1 +1 @@
1
- process.stdin.resume();
1
+ process.stdin.resume();
@@ -1,8 +1,8 @@
1
- {
2
- "name": "codex-doctor-runtime",
3
- "version": "1.0.0",
4
- "description": "Runtime-complete Codex Doctor sample plugin with MCP validation coverage.",
5
- "skills": "./skills/",
6
- "mcpServers": "./.mcp.json"
7
- }
8
-
1
+ {
2
+ "name": "codex-doctor-runtime",
3
+ "version": "1.0.0",
4
+ "description": "Runtime-complete Codex Doctor sample plugin with MCP validation coverage.",
5
+ "skills": "./skills/",
6
+ "mcpServers": "./.mcp.json"
7
+ }
8
+
@@ -1,9 +1,9 @@
1
- {
2
- "mcpServers": {
3
- "doctorRuntime": {
4
- "command": "node",
5
- "args": ["./mock-server.js"]
6
- }
7
- }
8
- }
9
-
1
+ {
2
+ "mcpServers": {
3
+ "doctorRuntime": {
4
+ "command": "node",
5
+ "args": ["./mock-server.js"]
6
+ }
7
+ }
8
+ }
9
+