codex-plugin-doctor 1.46.1 → 1.47.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 +23 -14
- package/dist/core/attestation.d.ts +1 -0
- package/dist/core/attestation.js +1 -1
- package/dist/core/external-validation-corpus.d.ts +88 -0
- package/dist/core/external-validation-corpus.js +271 -0
- package/dist/core/init-git-hooks.js +43 -4
- package/dist/core/output-contract.js +8 -2
- package/dist/core/release-check.d.ts +2 -1
- package/dist/core/release-check.js +2 -1
- package/dist/core/release-evidence.d.ts +5 -2
- package/dist/core/release-evidence.js +12 -2
- package/dist/core/runtime-plan.d.ts +5 -1
- package/dist/core/runtime-plan.js +13 -1
- package/dist/core/runtime-policy.d.ts +5 -1
- package/dist/core/runtime-policy.js +3 -2
- package/dist/core/runtime-probe.d.ts +2 -1
- package/dist/core/runtime-probe.js +100 -18
- package/dist/core/runtime-sandbox.d.ts +21 -0
- package/dist/core/runtime-sandbox.js +68 -0
- package/dist/core/validate-plugin.js +19 -8
- package/dist/core/validation-corpus.d.ts +4 -2
- package/dist/core/validation-corpus.js +12 -1
- package/dist/domain/types.d.ts +11 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/reporting/render-json-report.js +3 -0
- package/dist/reporting/render-markdown-report.js +3 -0
- package/dist/reporting/render-text-report.js +3 -0
- package/dist/run-cli.js +122 -19
- package/package.json +1 -1
|
@@ -12,6 +12,9 @@ export function buildJsonReport(result, options) {
|
|
|
12
12
|
...(result.runtimeScorecard
|
|
13
13
|
? { runtimeScorecard: result.runtimeScorecard }
|
|
14
14
|
: {}),
|
|
15
|
+
...(result.runtimeExecution
|
|
16
|
+
? { runtimeExecution: result.runtimeExecution }
|
|
17
|
+
: {}),
|
|
15
18
|
findingCounts: {
|
|
16
19
|
fail: failCount,
|
|
17
20
|
warn: warnCount,
|
|
@@ -23,6 +23,9 @@ export function buildMarkdownReport(result, options) {
|
|
|
23
23
|
if (result.baselineSummary) {
|
|
24
24
|
lines.push(`| Baseline New | ${result.baselineSummary.new} |`, `| Baseline Matched | ${result.baselineSummary.matched} |`, `| Baseline Resolved | ${result.baselineSummary.resolved} |`);
|
|
25
25
|
}
|
|
26
|
+
if (result.runtimeExecution) {
|
|
27
|
+
lines.push("", `Runtime backend: ${result.runtimeExecution.backend.toUpperCase()}`, `Runtime isolation: network=${result.runtimeExecution.network}, package=${result.runtimeExecution.packageMount}`);
|
|
28
|
+
}
|
|
26
29
|
if (result.findings.length === 0 && !result.suppressedFindings?.length) {
|
|
27
30
|
lines.push("", result.baselineSummary ? "No new findings." : "No findings.");
|
|
28
31
|
return lines.join("\n");
|
|
@@ -42,6 +42,9 @@ export function renderTextReport(result, options = {}) {
|
|
|
42
42
|
if (result.baselineSummary) {
|
|
43
43
|
lines.push(`Baseline: ${result.baselineSummary.new} new, ${result.baselineSummary.matched} matched, ${result.baselineSummary.resolved} resolved`);
|
|
44
44
|
}
|
|
45
|
+
if (result.runtimeExecution) {
|
|
46
|
+
lines.push(`Runtime backend: ${result.runtimeExecution.backend.toUpperCase()}`, `Runtime isolation: network=${result.runtimeExecution.network}, package=${result.runtimeExecution.packageMount}`);
|
|
47
|
+
}
|
|
45
48
|
if (result.findings.length === 0 && !result.suppressedFindings?.length) {
|
|
46
49
|
if (result.runtimeScorecard) {
|
|
47
50
|
lines.push("", "Runtime Scorecard", "----------------");
|
package/dist/run-cli.js
CHANGED
|
@@ -20,6 +20,7 @@ import { buildDoctorExportBundle, renderDoctorExportBundle, renderDoctorExportBu
|
|
|
20
20
|
import { buildDoctorAttestation, renderDoctorAttestation, renderDoctorAttestationJson, renderDoctorAttestationVerification, renderDoctorAttestationVerificationJson, verifyDoctorAttestation } from "./core/attestation.js";
|
|
21
21
|
import { buildDoctorOutputContract, renderDoctorOutputContract, renderDoctorOutputContractJson } from "./core/output-contract.js";
|
|
22
22
|
import { buildDoctorValidationCorpusReport, renderDoctorValidationCorpusJson, renderDoctorValidationCorpusReport } from "./core/validation-corpus.js";
|
|
23
|
+
import { buildExternalValidationCorpusReport, ExternalCorpusManifestError } from "./core/external-validation-corpus.js";
|
|
23
24
|
import { buildDoctorPerformanceReport, renderDoctorPerformanceReport, renderDoctorPerformanceReportJson } from "./core/performance-report.js";
|
|
24
25
|
import { buildDoctorRuntimePlan, evaluateRuntimeApproval, renderDoctorRuntimePlan, renderDoctorRuntimePlanMarkdown, renderDoctorRuntimePlanJson, runtimeApprovalPassed } from "./core/runtime-plan.js";
|
|
25
26
|
import { buildDoctorRuntimePolicyReport, renderDoctorRuntimePolicy, renderDoctorRuntimePolicyJson } from "./core/runtime-policy.js";
|
|
@@ -81,8 +82,24 @@ const defaultIo = {
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
};
|
|
85
|
+
class CliUsageError extends Error {
|
|
86
|
+
}
|
|
87
|
+
function parseRuntimeSandbox(flags, options = { requireRuntime: true }) {
|
|
88
|
+
const index = flags.indexOf("--sandbox");
|
|
89
|
+
if (index === -1) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const value = flags[index + 1];
|
|
93
|
+
if (value !== "docker") {
|
|
94
|
+
throw new CliUsageError("Expected --sandbox docker.");
|
|
95
|
+
}
|
|
96
|
+
if (options.requireRuntime !== false && !flags.includes("--runtime")) {
|
|
97
|
+
throw new CliUsageError("--sandbox docker requires --runtime.");
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
84
101
|
function printUsage(io) {
|
|
85
|
-
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] [--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> [--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|runtime-plan <path> [--json|--markdown] [--output <path>]|runtime-policy <path> [--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 [--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 [--upload]|mcp <path>|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]\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");
|
|
102
|
+
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] [--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> [--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>]|runtime-plan <path> [--runtime --sandbox docker] [--json|--markdown] [--output <path>]|runtime-policy <path> [--runtime --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 --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 [--upload]|mcp <path>|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 --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");
|
|
86
103
|
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]");
|
|
87
104
|
io.writeStderr("Baseline gating: codex-plugin-doctor baseline create <path> --output <path> [--runtime]\n codex-plugin-doctor check <path> --baseline <path>");
|
|
88
105
|
}
|
|
@@ -805,6 +822,17 @@ function parseSelectedFixActionIndexes(answer, actionCount) {
|
|
|
805
822
|
}
|
|
806
823
|
export async function runCli(args, io = defaultIo, options = {}) {
|
|
807
824
|
const [command, maybePath, ...remainingArgs] = args;
|
|
825
|
+
const runtimeSandboxSupported = (command === "check" &&
|
|
826
|
+
!args.includes("--installed") &&
|
|
827
|
+
!args.includes("--changed-since")) ||
|
|
828
|
+
(command === "release" && maybePath === "check") ||
|
|
829
|
+
(command === "doctor" &&
|
|
830
|
+
(["runtime-plan", "runtime-policy"].includes(maybePath ?? "") ||
|
|
831
|
+
(maybePath === "release-evidence" && remainingArgs[0] !== "verify")));
|
|
832
|
+
if (args.includes("--sandbox") && !runtimeSandboxSupported) {
|
|
833
|
+
io.writeStderr("--sandbox is supported only by single-package check, release check, runtime-plan, runtime-policy, and release-evidence.");
|
|
834
|
+
return 2;
|
|
835
|
+
}
|
|
808
836
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
809
837
|
io.writeStdout(packageVersion);
|
|
810
838
|
return 0;
|
|
@@ -933,6 +961,14 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
933
961
|
const markdownOutput = runtimePlanFlags.includes("--markdown");
|
|
934
962
|
const outputIndex = runtimePlanFlags.indexOf("--output");
|
|
935
963
|
const outputPath = outputIndex === -1 ? null : runtimePlanFlags[outputIndex + 1];
|
|
964
|
+
let runtimeSandbox;
|
|
965
|
+
try {
|
|
966
|
+
runtimeSandbox = parseRuntimeSandbox(runtimePlanFlags, { requireRuntime: false });
|
|
967
|
+
}
|
|
968
|
+
catch (error) {
|
|
969
|
+
io.writeStderr(error.message);
|
|
970
|
+
return 2;
|
|
971
|
+
}
|
|
936
972
|
if (!targetPath) {
|
|
937
973
|
io.writeStderr("Missing target path for runtime plan.");
|
|
938
974
|
return 2;
|
|
@@ -945,7 +981,7 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
945
981
|
io.writeStderr("Use either --json or --markdown, not both.");
|
|
946
982
|
return 2;
|
|
947
983
|
}
|
|
948
|
-
const plan = await buildDoctorRuntimePlan(targetPath);
|
|
984
|
+
const plan = await buildDoctorRuntimePlan(targetPath, new Date().toISOString(), runtimeSandbox ? { sandbox: runtimeSandbox } : {});
|
|
949
985
|
const renderedPlan = jsonOutput
|
|
950
986
|
? renderDoctorRuntimePlanJson(plan)
|
|
951
987
|
: markdownOutput
|
|
@@ -965,6 +1001,14 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
965
1001
|
const jsonOutput = runtimePolicyFlags.includes("--json");
|
|
966
1002
|
const outputIndex = runtimePolicyFlags.indexOf("--output");
|
|
967
1003
|
const outputPath = outputIndex === -1 ? null : runtimePolicyFlags[outputIndex + 1];
|
|
1004
|
+
let runtimeSandbox;
|
|
1005
|
+
try {
|
|
1006
|
+
runtimeSandbox = parseRuntimeSandbox(runtimePolicyFlags, { requireRuntime: false });
|
|
1007
|
+
}
|
|
1008
|
+
catch (error) {
|
|
1009
|
+
io.writeStderr(error.message);
|
|
1010
|
+
return 2;
|
|
1011
|
+
}
|
|
968
1012
|
if (!targetPath) {
|
|
969
1013
|
io.writeStderr("Missing target path for runtime policy.");
|
|
970
1014
|
return 2;
|
|
@@ -973,7 +1017,7 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
973
1017
|
io.writeStderr("Missing path after --output.");
|
|
974
1018
|
return 2;
|
|
975
1019
|
}
|
|
976
|
-
const report = await buildDoctorRuntimePolicyReport(targetPath);
|
|
1020
|
+
const report = await buildDoctorRuntimePolicyReport(targetPath, new Date().toISOString(), runtimeSandbox ? { sandbox: runtimeSandbox } : {});
|
|
977
1021
|
const renderedReport = jsonOutput
|
|
978
1022
|
? renderDoctorRuntimePolicyJson(report)
|
|
979
1023
|
: renderDoctorRuntimePolicy(report);
|
|
@@ -1138,6 +1182,15 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1138
1182
|
const runtimeApprovalDigest = runtimeApprovalDigestIndex === -1
|
|
1139
1183
|
? null
|
|
1140
1184
|
: assetFlags[runtimeApprovalDigestIndex + 1];
|
|
1185
|
+
const runtime = assetFlags.includes("--runtime");
|
|
1186
|
+
let runtimeSandbox;
|
|
1187
|
+
try {
|
|
1188
|
+
runtimeSandbox = parseRuntimeSandbox(assetFlags);
|
|
1189
|
+
}
|
|
1190
|
+
catch (error) {
|
|
1191
|
+
io.writeStderr(error.message);
|
|
1192
|
+
return 2;
|
|
1193
|
+
}
|
|
1141
1194
|
if (!targetPath) {
|
|
1142
1195
|
io.writeStderr("Missing target path for release evidence asset.");
|
|
1143
1196
|
return 2;
|
|
@@ -1193,13 +1246,13 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1193
1246
|
allowUntagged,
|
|
1194
1247
|
requireRuntimeApproval,
|
|
1195
1248
|
runtimeApprovalDigest,
|
|
1249
|
+
runtime,
|
|
1250
|
+
...(runtimeSandbox ? { sandbox: runtimeSandbox } : {}),
|
|
1196
1251
|
environment: {
|
|
1197
1252
|
env: terminalContext.env,
|
|
1198
1253
|
platform: terminalContext.platform
|
|
1199
1254
|
},
|
|
1200
|
-
runCheck: options.runCheckImpl
|
|
1201
|
-
? (pathToCheck) => options.runCheckImpl(pathToCheck)
|
|
1202
|
-
: undefined,
|
|
1255
|
+
runCheck: options.runCheckImpl ?? runCheck,
|
|
1203
1256
|
performanceThresholds: parsedThresholds.thresholds
|
|
1204
1257
|
});
|
|
1205
1258
|
await writeFile(resolvedOutputPath, renderDoctorReleaseEvidenceJson(evidence), "utf8");
|
|
@@ -1298,6 +1351,15 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1298
1351
|
const runtimeApprovalDigest = runtimeApprovalDigestIndex === -1
|
|
1299
1352
|
? null
|
|
1300
1353
|
: evidenceFlags[runtimeApprovalDigestIndex + 1];
|
|
1354
|
+
const runtime = evidenceFlags.includes("--runtime");
|
|
1355
|
+
let runtimeSandbox;
|
|
1356
|
+
try {
|
|
1357
|
+
runtimeSandbox = parseRuntimeSandbox(evidenceFlags);
|
|
1358
|
+
}
|
|
1359
|
+
catch (error) {
|
|
1360
|
+
io.writeStderr(error.message);
|
|
1361
|
+
return 2;
|
|
1362
|
+
}
|
|
1301
1363
|
if (outputIndex !== -1 && (!outputPath || outputPath.startsWith("--"))) {
|
|
1302
1364
|
io.writeStderr("Missing path after --output.");
|
|
1303
1365
|
return 2;
|
|
@@ -1336,13 +1398,13 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1336
1398
|
allowUntagged,
|
|
1337
1399
|
requireRuntimeApproval,
|
|
1338
1400
|
runtimeApprovalDigest,
|
|
1401
|
+
runtime,
|
|
1402
|
+
...(runtimeSandbox ? { sandbox: runtimeSandbox } : {}),
|
|
1339
1403
|
environment: {
|
|
1340
1404
|
env: terminalContext.env,
|
|
1341
1405
|
platform: terminalContext.platform
|
|
1342
1406
|
},
|
|
1343
|
-
runCheck: options.runCheckImpl
|
|
1344
|
-
? (pathToCheck) => options.runCheckImpl(pathToCheck)
|
|
1345
|
-
: undefined,
|
|
1407
|
+
runCheck: options.runCheckImpl ?? runCheck,
|
|
1346
1408
|
performanceThresholds: parsedThresholds.thresholds
|
|
1347
1409
|
});
|
|
1348
1410
|
const reportJson = renderDoctorReleaseEvidenceJson(report);
|
|
@@ -1357,16 +1419,39 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
1357
1419
|
const jsonOutput = remainingArgs.includes("--json");
|
|
1358
1420
|
const outputIndex = remainingArgs.indexOf("--output");
|
|
1359
1421
|
const outputPath = outputIndex === -1 ? null : remainingArgs[outputIndex + 1];
|
|
1422
|
+
const manifestIndex = remainingArgs.indexOf("--manifest");
|
|
1423
|
+
const manifestPath = manifestIndex === -1 ? null : remainingArgs[manifestIndex + 1];
|
|
1360
1424
|
if (outputIndex !== -1 && (!outputPath || outputPath.startsWith("--"))) {
|
|
1361
1425
|
io.writeStderr("Missing path after --output.");
|
|
1362
1426
|
return 2;
|
|
1363
1427
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1428
|
+
if (manifestIndex !== -1 && (!manifestPath || manifestPath.startsWith("--"))) {
|
|
1429
|
+
io.writeStderr("Missing path after --manifest.");
|
|
1430
|
+
return 2;
|
|
1431
|
+
}
|
|
1432
|
+
let report;
|
|
1433
|
+
try {
|
|
1434
|
+
report = manifestPath
|
|
1435
|
+
? await buildExternalValidationCorpusReport(manifestPath, {
|
|
1436
|
+
environment: {
|
|
1437
|
+
env: terminalContext.env,
|
|
1438
|
+
platform: terminalContext.platform
|
|
1439
|
+
}
|
|
1440
|
+
})
|
|
1441
|
+
: await buildDoctorValidationCorpusReport({
|
|
1442
|
+
environment: {
|
|
1443
|
+
env: terminalContext.env,
|
|
1444
|
+
platform: terminalContext.platform
|
|
1445
|
+
}
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
catch (error) {
|
|
1449
|
+
if (error instanceof ExternalCorpusManifestError) {
|
|
1450
|
+
io.writeStderr(error.message);
|
|
1451
|
+
return 2;
|
|
1368
1452
|
}
|
|
1369
|
-
|
|
1453
|
+
throw error;
|
|
1454
|
+
}
|
|
1370
1455
|
const reportJson = renderDoctorValidationCorpusJson(report);
|
|
1371
1456
|
if (outputPath) {
|
|
1372
1457
|
await writeFile(outputPath, reportJson, "utf8");
|
|
@@ -2262,6 +2347,14 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2262
2347
|
: remainingArgs.slice(1);
|
|
2263
2348
|
const jsonOutput = releaseFlags.includes("--json");
|
|
2264
2349
|
const runtimeProbeEnabled = releaseFlags.includes("--runtime");
|
|
2350
|
+
let runtimeSandbox;
|
|
2351
|
+
try {
|
|
2352
|
+
runtimeSandbox = parseRuntimeSandbox(releaseFlags);
|
|
2353
|
+
}
|
|
2354
|
+
catch (error) {
|
|
2355
|
+
io.writeStderr(error.message);
|
|
2356
|
+
return 2;
|
|
2357
|
+
}
|
|
2265
2358
|
const requireRuntimeApproval = releaseFlags.includes("--require-runtime-approval");
|
|
2266
2359
|
const runtimeApprovalDigestIndex = releaseFlags.indexOf("--runtime-approval-digest");
|
|
2267
2360
|
const runtimeApprovalDigest = runtimeApprovalDigestIndex === -1
|
|
@@ -2277,7 +2370,7 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2277
2370
|
return 2;
|
|
2278
2371
|
}
|
|
2279
2372
|
if (requireRuntimeApproval) {
|
|
2280
|
-
const runtimePlan = await buildDoctorRuntimePlan(targetPath);
|
|
2373
|
+
const runtimePlan = await buildDoctorRuntimePlan(targetPath, new Date().toISOString(), runtimeSandbox ? { sandbox: runtimeSandbox } : {});
|
|
2281
2374
|
const approval = evaluateRuntimeApproval(runtimePlan, {
|
|
2282
2375
|
required: true,
|
|
2283
2376
|
approvedDigest: runtimeApprovalDigest
|
|
@@ -2291,6 +2384,7 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2291
2384
|
env: terminalContext.env,
|
|
2292
2385
|
platform: terminalContext.platform,
|
|
2293
2386
|
runtime: runtimeProbeEnabled,
|
|
2387
|
+
...(runtimeSandbox ? { runtimeSandbox } : {}),
|
|
2294
2388
|
runCheck: options.runCheckImpl
|
|
2295
2389
|
});
|
|
2296
2390
|
const output = jsonOutput
|
|
@@ -2331,6 +2425,14 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2331
2425
|
: maybePath && maybePath.startsWith("--")
|
|
2332
2426
|
? [maybePath, ...remainingArgs]
|
|
2333
2427
|
: remainingArgs;
|
|
2428
|
+
let runtimeSandbox;
|
|
2429
|
+
try {
|
|
2430
|
+
runtimeSandbox = parseRuntimeSandbox(normalizedFlags);
|
|
2431
|
+
}
|
|
2432
|
+
catch (error) {
|
|
2433
|
+
io.writeStderr(error.message);
|
|
2434
|
+
return 2;
|
|
2435
|
+
}
|
|
2334
2436
|
const jsonOutput = normalizedFlags.includes("--json");
|
|
2335
2437
|
const markdownOutput = normalizedFlags.includes("--markdown");
|
|
2336
2438
|
const badgeJsonOutput = normalizedFlags.includes("--badge-json");
|
|
@@ -2458,7 +2560,7 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2458
2560
|
});
|
|
2459
2561
|
const runCheckImpl = options.runCheckImpl ?? runCheck;
|
|
2460
2562
|
if (!checkInstalled && effectiveRuntimeProbeEnabled && requireRuntimeApproval) {
|
|
2461
|
-
const runtimePlan = await buildDoctorRuntimePlan(targetPath);
|
|
2563
|
+
const runtimePlan = await buildDoctorRuntimePlan(targetPath, new Date().toISOString(), runtimeSandbox ? { sandbox: runtimeSandbox } : {});
|
|
2462
2564
|
const approval = evaluateRuntimeApproval(runtimePlan, {
|
|
2463
2565
|
required: true,
|
|
2464
2566
|
approvedDigest: runtimeApprovalDigest
|
|
@@ -2580,9 +2682,10 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2580
2682
|
const doctorConfig = applyPolicyToDoctorConfig(applyCheckProfile(await loadDoctorConfig(targetPath, configPath), checkProfile), policy);
|
|
2581
2683
|
const configuredResult = applyDoctorConfig(await runCheckImpl(targetPath, {
|
|
2582
2684
|
runtime: effectiveRuntimeProbeEnabled,
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
:
|
|
2685
|
+
...(runtimeSandbox ? { runtimeSandbox } : {}),
|
|
2686
|
+
...(effectiveRuntimeProbeEnabled && verboseRuntime
|
|
2687
|
+
? { runtimeTranscript: (line) => io.writeStderr(line) }
|
|
2688
|
+
: {})
|
|
2586
2689
|
}), doctorConfig);
|
|
2587
2690
|
const result = baseline
|
|
2588
2691
|
? applyValidationBaseline(configuredResult, baseline, {
|
package/package.json
CHANGED