codex-plugin-doctor 1.78.0 → 1.79.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 +15 -2
- package/dist/core/mcp-prompt-catalog.js +2 -0
- package/dist/core/mcp-resource-template-catalog.d.ts +36 -0
- package/dist/core/mcp-resource-template-catalog.js +55 -0
- package/dist/core/mcp-resource-template-definition.d.ts +28 -0
- package/dist/core/mcp-resource-template-definition.js +116 -0
- package/dist/core/mcp-resource-template-diff.d.ts +43 -0
- package/dist/core/mcp-resource-template-diff.js +136 -0
- package/dist/core/mcp-resource-template-file.d.ts +31 -0
- package/dist/core/mcp-resource-template-file.js +118 -0
- package/dist/core/mcp-resource-template-impact.d.ts +21 -0
- package/dist/core/mcp-resource-template-impact.js +74 -0
- package/dist/core/mcp-stdio-tool-catalog.d.ts +1 -1
- package/dist/core/mcp-stdio-tool-catalog.js +6 -6
- package/dist/core/mcp-tool-catalog.d.ts +8 -6
- package/dist/core/mcp-tool-catalog.js +7 -5
- package/dist/core/mcp-tool-response-file.d.ts +1 -1
- package/dist/core/mcp-tool-response-file.js +3 -2
- package/dist/core/output-contract.js +172 -1
- package/dist/reporting/render-mcp-resource-template-catalog-report.d.ts +2 -0
- package/dist/reporting/render-mcp-resource-template-catalog-report.js +33 -0
- package/dist/reporting/render-mcp-resource-template-diff-markdown.d.ts +2 -0
- package/dist/reporting/render-mcp-resource-template-diff-markdown.js +39 -0
- package/dist/reporting/render-mcp-resource-template-diff-report.d.ts +2 -0
- package/dist/reporting/render-mcp-resource-template-diff-report.js +48 -0
- package/dist/reporting/render-mcp-resource-template-file-report.d.ts +5 -0
- package/dist/reporting/render-mcp-resource-template-file-report.js +31 -0
- package/dist/run-cli.d.ts +7 -0
- package/dist/run-cli.js +60 -6
- package/package.json +1 -1
package/dist/run-cli.d.ts
CHANGED
|
@@ -2,8 +2,11 @@ import { discoverMcpServer } from "./core/mcp-discovery.js";
|
|
|
2
2
|
import { captureMcpToolCatalog, inspectMcpToolCatalog } from "./core/mcp-tool-catalog.js";
|
|
3
3
|
import { captureStdioMcpToolCatalog } from "./core/mcp-stdio-tool-catalog.js";
|
|
4
4
|
import { captureMcpPromptCatalog, captureStdioMcpPromptCatalog } from "./core/mcp-prompt-catalog.js";
|
|
5
|
+
import { captureMcpResourceTemplateCatalog, captureStdioMcpResourceTemplateCatalog } from "./core/mcp-resource-template-catalog.js";
|
|
5
6
|
import { compareMcpPromptFiles } from "./core/mcp-prompt-diff.js";
|
|
6
7
|
import { inspectMcpPromptFile } from "./core/mcp-prompt-file.js";
|
|
8
|
+
import { compareMcpResourceTemplateFiles } from "./core/mcp-resource-template-diff.js";
|
|
9
|
+
import { inspectMcpResourceTemplateFile } from "./core/mcp-resource-template-file.js";
|
|
7
10
|
import { inspectMcpToolFile } from "./core/mcp-tool-file.js";
|
|
8
11
|
import { compareMcpToolFiles } from "./core/mcp-tool-diff.js";
|
|
9
12
|
import { buildCorpusQualityMetricsDiffReport, buildCorpusQualityMetricsReport } from "./core/corpus-quality-metrics.js";
|
|
@@ -27,9 +30,13 @@ export interface RunCliOptions {
|
|
|
27
30
|
captureMcpToolCatalogImpl?: typeof captureMcpToolCatalog;
|
|
28
31
|
captureStdioMcpToolCatalogImpl?: typeof captureStdioMcpToolCatalog;
|
|
29
32
|
compareMcpPromptFilesImpl?: typeof compareMcpPromptFiles;
|
|
33
|
+
compareMcpResourceTemplateFilesImpl?: typeof compareMcpResourceTemplateFiles;
|
|
34
|
+
inspectMcpResourceTemplateFileImpl?: typeof inspectMcpResourceTemplateFile;
|
|
30
35
|
inspectMcpPromptFileImpl?: typeof inspectMcpPromptFile;
|
|
31
36
|
captureMcpPromptCatalogImpl?: typeof captureMcpPromptCatalog;
|
|
32
37
|
captureStdioMcpPromptCatalogImpl?: typeof captureStdioMcpPromptCatalog;
|
|
38
|
+
captureMcpResourceTemplateCatalogImpl?: typeof captureMcpResourceTemplateCatalog;
|
|
39
|
+
captureStdioMcpResourceTemplateCatalogImpl?: typeof captureStdioMcpResourceTemplateCatalog;
|
|
33
40
|
discoverMcpServerImpl?: typeof discoverMcpServer;
|
|
34
41
|
terminalContext?: CliTerminalContext;
|
|
35
42
|
runCheckImpl?: typeof runCheck;
|
package/dist/run-cli.js
CHANGED
|
@@ -26,8 +26,11 @@ import { discoverMcpServer } from "./core/mcp-discovery.js";
|
|
|
26
26
|
import { captureMcpToolCatalog, inspectMcpToolCatalog } from "./core/mcp-tool-catalog.js";
|
|
27
27
|
import { captureStdioMcpToolCatalog, resolveMcpStdioServer } from "./core/mcp-stdio-tool-catalog.js";
|
|
28
28
|
import { captureMcpPromptCatalog, captureStdioMcpPromptCatalog } from "./core/mcp-prompt-catalog.js";
|
|
29
|
+
import { captureMcpResourceTemplateCatalog, captureStdioMcpResourceTemplateCatalog } from "./core/mcp-resource-template-catalog.js";
|
|
29
30
|
import { compareMcpPromptFiles } from "./core/mcp-prompt-diff.js";
|
|
30
31
|
import { inspectMcpPromptFile } from "./core/mcp-prompt-file.js";
|
|
32
|
+
import { compareMcpResourceTemplateFiles } from "./core/mcp-resource-template-diff.js";
|
|
33
|
+
import { inspectMcpResourceTemplateFile } from "./core/mcp-resource-template-file.js";
|
|
31
34
|
import { inspectMcpToolFile, isBlockedOfflinePath } from "./core/mcp-tool-file.js";
|
|
32
35
|
import { saveMcpListResponse } from "./core/mcp-tool-response-file.js";
|
|
33
36
|
import { compareMcpToolFiles } from "./core/mcp-tool-diff.js";
|
|
@@ -36,9 +39,13 @@ import { renderMcpToolDiffReport } from "./reporting/render-mcp-tool-diff-report
|
|
|
36
39
|
import { renderMcpToolFileReport } from "./reporting/render-mcp-tool-file-report.js";
|
|
37
40
|
import { renderMcpToolCatalogReport } from "./reporting/render-mcp-tool-catalog-report.js";
|
|
38
41
|
import { renderMcpPromptCatalogReport } from "./reporting/render-mcp-prompt-catalog-report.js";
|
|
42
|
+
import { renderMcpResourceTemplateCatalogReport } from "./reporting/render-mcp-resource-template-catalog-report.js";
|
|
39
43
|
import { renderMcpPromptDiffMarkdown } from "./reporting/render-mcp-prompt-diff-markdown.js";
|
|
40
44
|
import { renderMcpPromptDiffReport } from "./reporting/render-mcp-prompt-diff-report.js";
|
|
41
45
|
import { renderMcpPromptFileReport } from "./reporting/render-mcp-prompt-file-report.js";
|
|
46
|
+
import { renderMcpResourceTemplateDiffMarkdown } from "./reporting/render-mcp-resource-template-diff-markdown.js";
|
|
47
|
+
import { renderMcpResourceTemplateDiffReport } from "./reporting/render-mcp-resource-template-diff-report.js";
|
|
48
|
+
import { renderMcpResourceTemplateFileReport } from "./reporting/render-mcp-resource-template-file-report.js";
|
|
42
49
|
import { renderMcpDiscoveryReport } from "./reporting/render-mcp-discovery-report.js";
|
|
43
50
|
import { buildDoctorValidationCorpusReport, renderDoctorValidationCorpusJson, renderDoctorValidationCorpusReport } from "./core/validation-corpus.js";
|
|
44
51
|
import { buildExternalValidationCorpusReport, ExternalCorpusManifestError } from "./core/external-validation-corpus.js";
|
|
@@ -122,10 +129,17 @@ const toolsDiffUsage = "Usage: codex-plugin-doctor doctor tools-diff --before <p
|
|
|
122
129
|
const toolsFileUsage = "Usage: codex-plugin-doctor doctor tools-file <path> [--json]";
|
|
123
130
|
const promptsDiffUsage = "Usage: codex-plugin-doctor doctor prompts-diff --before <path> --after <path> [--json|--markdown] [--fail-on any|breaking] [--show-names]";
|
|
124
131
|
const promptsFileUsage = "Usage: codex-plugin-doctor doctor prompts-file <path> [--json]";
|
|
132
|
+
const resourceTemplatesDiffUsage = "Usage: codex-plugin-doctor doctor resource-templates-diff --before <path> --after <path> [--json|--markdown] [--fail-on any|breaking] [--show-names]";
|
|
133
|
+
const resourceTemplatesFileUsage = "Usage: codex-plugin-doctor doctor resource-templates-file <path> [--json]";
|
|
125
134
|
const toolsUsage = "Usage: codex-plugin-doctor doctor tools <url> --allow-network [--allow-local-network] [--json] [--save-response <path>] [--bearer-token-env <NAME>]\n codex-plugin-doctor doctor tools <path> --server <name> --runtime [--sandbox docker [--env <NAME>]...] [--require-runtime-approval [--runtime-approval-digest <digest>]] [--json] [--save-response <path>]";
|
|
135
|
+
const resourceTemplatesUsage = "Usage: codex-plugin-doctor doctor resource-templates <url> --allow-network [--allow-local-network] [--json] [--save-response <path>] [--bearer-token-env <NAME>]\n codex-plugin-doctor doctor resource-templates <path> --server <name> --runtime [--sandbox docker [--env <NAME>]...] [--require-runtime-approval [--runtime-approval-digest <digest>]] [--json] [--save-response <path>]";
|
|
126
136
|
const promptsUsage = "Usage: codex-plugin-doctor doctor prompts <url> --allow-network [--allow-local-network] [--json] [--save-response <path>] [--bearer-token-env <NAME>]\n codex-plugin-doctor doctor prompts <path> --server <name> --runtime [--sandbox docker [--env <NAME>]...] [--require-runtime-approval [--runtime-approval-digest <digest>]] [--json] [--save-response <path>]";
|
|
127
|
-
const TOOL_CATALOG_COMMAND = { name: "tools", noun: "Tool", method: "tools/list", usage: toolsUsage };
|
|
128
|
-
const PROMPT_CATALOG_COMMAND = { name: "prompts", noun: "Prompt", method: "prompts/list", usage: promptsUsage };
|
|
137
|
+
const TOOL_CATALOG_COMMAND = { name: "tools", noun: "Tool", plural: "tools", method: "tools/list", resultKey: "tools", usage: toolsUsage };
|
|
138
|
+
const PROMPT_CATALOG_COMMAND = { name: "prompts", noun: "Prompt", plural: "prompts", method: "prompts/list", resultKey: "prompts", usage: promptsUsage };
|
|
139
|
+
const RESOURCE_TEMPLATE_CATALOG_COMMAND = {
|
|
140
|
+
name: "resource-templates", noun: "Resource template", plural: "resource templates",
|
|
141
|
+
method: "resources/templates/list", resultKey: "resourceTemplates", usage: resourceTemplatesUsage
|
|
142
|
+
};
|
|
129
143
|
const discoveryUsage = "Usage: codex-plugin-doctor doctor discover <url> --allow-network [--allow-local-network] [--json] [--bearer-token-env <NAME>]";
|
|
130
144
|
const bearerTokenHelp = "--bearer-token-env reads a bearer token from the named environment variable and sends it only over HTTPS or to an approved loopback target; the token is never printed or saved.";
|
|
131
145
|
const ENVIRONMENT_VARIABLE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
@@ -195,7 +209,7 @@ async function finishCatalogCommand(io, kind, status, output, items, cache, save
|
|
|
195
209
|
io.writeStderr(`${kind.noun} catalog response was not saved because enumeration did not complete.`);
|
|
196
210
|
return 2;
|
|
197
211
|
}
|
|
198
|
-
const saved = await saveMcpListResponse(savePath, kind.
|
|
212
|
+
const saved = await saveMcpListResponse(savePath, kind.resultKey, items, cache);
|
|
199
213
|
if (saved.kind !== "saved") {
|
|
200
214
|
io.writeStderr({
|
|
201
215
|
"path-blocked": `${kind.noun} catalog response was not saved because the path is not a local file path.`,
|
|
@@ -205,7 +219,7 @@ async function finishCatalogCommand(io, kind, status, output, items, cache, save
|
|
|
205
219
|
}[saved.kind]);
|
|
206
220
|
return 2;
|
|
207
221
|
}
|
|
208
|
-
io.writeStderr(`Saved a complete ${kind.method} response with ${saved.count} ${kind.
|
|
222
|
+
io.writeStderr(`Saved a complete ${kind.method} response with ${saved.count} ${kind.plural} (${saved.bytes} bytes).`);
|
|
209
223
|
return exitCode;
|
|
210
224
|
}
|
|
211
225
|
function finishToolCatalogCommand(io, snapshot, json, savePath) {
|
|
@@ -216,6 +230,10 @@ function finishPromptCatalogCommand(io, snapshot, json, savePath) {
|
|
|
216
230
|
const report = snapshot.report;
|
|
217
231
|
return finishCatalogCommand(io, PROMPT_CATALOG_COMMAND, report.status, json ? JSON.stringify(report, null, 2) : renderMcpPromptCatalogReport(report), snapshot.prompts, snapshot.cache, savePath);
|
|
218
232
|
}
|
|
233
|
+
function finishResourceTemplateCatalogCommand(io, snapshot, json, savePath) {
|
|
234
|
+
const report = snapshot.report;
|
|
235
|
+
return finishCatalogCommand(io, RESOURCE_TEMPLATE_CATALOG_COMMAND, report.status, json ? JSON.stringify(report, null, 2) : renderMcpResourceTemplateCatalogReport(report), snapshot.templates, snapshot.cache, savePath);
|
|
236
|
+
}
|
|
219
237
|
async function runHttpCatalogCommand(url, flags, io, env, kind, run) {
|
|
220
238
|
const allowedFlags = new Set(["--allow-network", "--allow-local-network", "--json"]);
|
|
221
239
|
const switches = [];
|
|
@@ -520,10 +538,13 @@ function printUsage(io) {
|
|
|
520
538
|
io.writeStderr(discoveryUsage);
|
|
521
539
|
io.writeStderr(toolsUsage);
|
|
522
540
|
io.writeStderr(promptsUsage);
|
|
541
|
+
io.writeStderr(resourceTemplatesUsage);
|
|
523
542
|
io.writeStderr(toolsFileUsage);
|
|
524
543
|
io.writeStderr(toolsDiffUsage);
|
|
525
544
|
io.writeStderr(promptsFileUsage);
|
|
526
545
|
io.writeStderr(promptsDiffUsage);
|
|
546
|
+
io.writeStderr(resourceTemplatesFileUsage);
|
|
547
|
+
io.writeStderr(resourceTemplatesDiffUsage);
|
|
527
548
|
io.writeStderr("Registry readiness: codex-plugin-doctor registry check <server.json|directory> [--json] [--output <path>] [--require-registry-readiness]\n"
|
|
528
549
|
+ " codex-plugin-doctor registry inspect <server-name> --allow-network [--json] [--output <path>] [--require-registry-readiness]\n"
|
|
529
550
|
+ "Registry publication preflight: codex-plugin-doctor registry preflight <server.json|directory> [--allow-network] [--json] [--output <path>] [--require-publish-ready]");
|
|
@@ -1487,10 +1508,10 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1487
1508
|
(command === "doctor" &&
|
|
1488
1509
|
(["runtime-plan", "runtime-policy"].includes(maybePath ?? "") ||
|
|
1489
1510
|
(maybePath === "release-evidence" && remainingArgs[0] !== "verify") ||
|
|
1490
|
-
(
|
|
1511
|
+
(["tools", "prompts", "resource-templates"].includes(maybePath ?? "") && remainingArgs.includes("--server")))) ||
|
|
1491
1512
|
(command === "init-ci" && args.includes("--tools-diff-server"));
|
|
1492
1513
|
if (args.includes("--sandbox") && !runtimeSandboxSupported) {
|
|
1493
|
-
io.writeStderr("--sandbox is supported only by single-package check, release check, runtime-plan, runtime-policy, release-evidence, doctor tools --server, doctor prompts --server, and init-ci --tools-diff-server.");
|
|
1514
|
+
io.writeStderr("--sandbox is supported only by single-package check, release check, runtime-plan, runtime-policy, release-evidence, doctor tools --server, doctor prompts --server, doctor resource-templates --server, and init-ci --tools-diff-server.");
|
|
1494
1515
|
return 2;
|
|
1495
1516
|
}
|
|
1496
1517
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
@@ -1572,6 +1593,24 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1572
1593
|
}
|
|
1573
1594
|
return runOfflineFileCommand(remainingArgs, io, promptsFileUsage, options.inspectMcpPromptFileImpl ?? inspectMcpPromptFile, renderMcpPromptFileReport);
|
|
1574
1595
|
}
|
|
1596
|
+
if (maybePath === "resource-templates-diff") {
|
|
1597
|
+
if (remainingArgs.length === 1 && remainingArgs[0] === "--help") {
|
|
1598
|
+
io.writeStdout(`${resourceTemplatesDiffUsage}\nCompares two saved MCP resources/templates/list responses offline. Changes are classified heuristically as breaking, compatible, or unclassified; no resource is read and compatibility is not tested.\n--fail-on breaking exits 1 only for breaking or unclassified changes (default: any change or input warning).
|
|
1599
|
+
--show-names adds template names and the variable behind each reason; reports omit both, and never include URI templates, so keep the flag out of public output such as pull request comments.`);
|
|
1600
|
+
return 0;
|
|
1601
|
+
}
|
|
1602
|
+
return runOfflineDiffCommand(remainingArgs, io, resourceTemplatesDiffUsage, (beforePath, afterPath, showNames) => {
|
|
1603
|
+
const compare = options.compareMcpResourceTemplateFilesImpl ?? compareMcpResourceTemplateFiles;
|
|
1604
|
+
return showNames ? compare(beforePath, afterPath, { showNames: true }) : compare(beforePath, afterPath);
|
|
1605
|
+
}, (report, markdown) => markdown ? renderMcpResourceTemplateDiffMarkdown(report) : renderMcpResourceTemplateDiffReport(report));
|
|
1606
|
+
}
|
|
1607
|
+
if (maybePath === "resource-templates-file") {
|
|
1608
|
+
if (remainingArgs.length === 1 && remainingArgs[0] === "--help") {
|
|
1609
|
+
io.writeStdout(`${resourceTemplatesFileUsage}\nInspects one saved UTF-8 MCP resources/templates/list response. No server connection or resource read.`);
|
|
1610
|
+
return 0;
|
|
1611
|
+
}
|
|
1612
|
+
return runOfflineFileCommand(remainingArgs, io, resourceTemplatesFileUsage, options.inspectMcpResourceTemplateFileImpl ?? inspectMcpResourceTemplateFile, renderMcpResourceTemplateFileReport);
|
|
1613
|
+
}
|
|
1575
1614
|
if (maybePath === "tools") {
|
|
1576
1615
|
if (remainingArgs.length === 1 && remainingArgs[0] === "--help") {
|
|
1577
1616
|
io.writeStdout(`${toolsUsage}\nTool catalog structure only; tools are not executed.\n--server starts the named stdio server from the package MCP configuration after explicit --runtime consent and stops it after reading the tool list.\n${forwardedEnvironmentHelp}\n--save-response writes a complete enumeration as one tools/list response for doctor tools-file and tools-diff; nothing is written when enumeration is incomplete.\n${bearerTokenHelp}`);
|
|
@@ -1607,6 +1646,21 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1607
1646
|
}
|
|
1608
1647
|
return runHttpCatalogCommand(target, flags, io, terminalContext.env, PROMPT_CATALOG_COMMAND, async (url, catalogOptions, json, savePath) => finishPromptCatalogCommand(io, await (options.captureMcpPromptCatalogImpl ?? captureMcpPromptCatalog)(url, catalogOptions), json, savePath));
|
|
1609
1648
|
}
|
|
1649
|
+
if (maybePath === "resource-templates") {
|
|
1650
|
+
if (remainingArgs.length === 1 && remainingArgs[0] === "--help") {
|
|
1651
|
+
io.writeStdout(`${resourceTemplatesUsage}\nResource template catalog structure only; no resource is read.\n--server starts the named stdio server from the package MCP configuration after explicit --runtime consent and stops it after reading the resource template list.\n${forwardedEnvironmentHelp}\n--save-response writes a complete enumeration as one resources/templates/list response for doctor resource-templates-file and resource-templates-diff; nothing is written when enumeration is incomplete.\n${bearerTokenHelp}`);
|
|
1652
|
+
return 0;
|
|
1653
|
+
}
|
|
1654
|
+
const [target, ...flags] = remainingArgs;
|
|
1655
|
+
if (!target || target.startsWith("-")) {
|
|
1656
|
+
io.writeStderr(resourceTemplatesUsage);
|
|
1657
|
+
return 2;
|
|
1658
|
+
}
|
|
1659
|
+
if (flags.includes("--server")) {
|
|
1660
|
+
return runStdioCatalogCommand(target, flags, io, terminalContext.env, RESOURCE_TEMPLATE_CATALOG_COMMAND, async (server, captureOptions, json, savePath) => finishResourceTemplateCatalogCommand(io, await (options.captureStdioMcpResourceTemplateCatalogImpl ?? captureStdioMcpResourceTemplateCatalog)(server, captureOptions), json, savePath));
|
|
1661
|
+
}
|
|
1662
|
+
return runHttpCatalogCommand(target, flags, io, terminalContext.env, RESOURCE_TEMPLATE_CATALOG_COMMAND, async (url, catalogOptions, json, savePath) => finishResourceTemplateCatalogCommand(io, await (options.captureMcpResourceTemplateCatalogImpl ?? captureMcpResourceTemplateCatalog)(url, catalogOptions), json, savePath));
|
|
1663
|
+
}
|
|
1610
1664
|
if (maybePath === "discover") {
|
|
1611
1665
|
if (remainingArgs.length === 1 && remainingArgs[0] === "--help") {
|
|
1612
1666
|
io.writeStdout(`${discoveryUsage}\nHTTP discovery only; runtime behavior is not tested.\n${bearerTokenHelp}`);
|
package/package.json
CHANGED