codex-plugin-doctor 1.38.0 → 1.39.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 +2 -2
- package/dist/core/init-git-hooks.js +75 -37
- package/dist/rules/rule-catalog.js +9 -0
- package/dist/run-cli.js +64 -1
- package/dist/security/security-audit.js +19 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -402,9 +402,9 @@ jobs:
|
|
|
402
402
|
runs-on: ubuntu-latest
|
|
403
403
|
steps:
|
|
404
404
|
- uses: actions/checkout@v5
|
|
405
|
-
- uses: Esquetta/CodexPluginDoctor@v1.
|
|
405
|
+
- uses: Esquetta/CodexPluginDoctor@v1.39.0
|
|
406
406
|
with:
|
|
407
|
-
version: "1.
|
|
407
|
+
version: "1.39.0"
|
|
408
408
|
path: .
|
|
409
409
|
runtime: "true"
|
|
410
410
|
policy: codex-publish
|
|
@@ -1,39 +1,77 @@
|
|
|
1
1
|
import { chmod, mkdir, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
3
|
+
const isWindows = process.platform === "win32";
|
|
4
|
+
const preCommitHook = isWindows
|
|
5
|
+
? [
|
|
6
|
+
"@echo off",
|
|
7
|
+
"REM Generated by codex-plugin-doctor init git-hooks",
|
|
8
|
+
"REM Validates the plugin package before every commit.",
|
|
9
|
+
"",
|
|
10
|
+
"echo Codex Plugin Doctor: running pre-commit validation...",
|
|
11
|
+
"",
|
|
12
|
+
"call npx --yes codex-plugin-doctor check . --profile ci",
|
|
13
|
+
"",
|
|
14
|
+
"if %ERRORLEVEL% neq 0 (",
|
|
15
|
+
" echo.",
|
|
16
|
+
" echo Plugin validation failed. Commit blocked.",
|
|
17
|
+
" echo Run 'codex-plugin-doctor check .' to see full diagnostics.",
|
|
18
|
+
" exit /b 1",
|
|
19
|
+
")",
|
|
20
|
+
""
|
|
21
|
+
].join("\r\n")
|
|
22
|
+
: [
|
|
23
|
+
"#!/usr/bin/env sh",
|
|
24
|
+
"# Generated by codex-plugin-doctor init git-hooks",
|
|
25
|
+
"# Validates the plugin package before every commit.",
|
|
26
|
+
"",
|
|
27
|
+
"echo \"Codex Plugin Doctor: running pre-commit validation...\"",
|
|
28
|
+
"",
|
|
29
|
+
"npx --yes codex-plugin-doctor check . --profile ci",
|
|
30
|
+
"",
|
|
31
|
+
"if [ $? -ne 0 ]; then",
|
|
32
|
+
" echo \"\"",
|
|
33
|
+
" echo \"Plugin validation failed. Commit blocked.\"",
|
|
34
|
+
" echo \"Run 'codex-plugin-doctor check .' to see full diagnostics.\"",
|
|
35
|
+
" exit 1",
|
|
36
|
+
"fi",
|
|
37
|
+
""
|
|
38
|
+
].join("\n");
|
|
39
|
+
const prePushHook = isWindows
|
|
40
|
+
? [
|
|
41
|
+
"@echo off",
|
|
42
|
+
"REM Generated by codex-plugin-doctor init git-hooks",
|
|
43
|
+
"REM Validates the plugin package before every push.",
|
|
44
|
+
"",
|
|
45
|
+
"echo Codex Plugin Doctor: running pre-push validation...",
|
|
46
|
+
"",
|
|
47
|
+
"call npx --yes codex-plugin-doctor check . --profile ci --runtime",
|
|
48
|
+
"",
|
|
49
|
+
"if %ERRORLEVEL% neq 0 (",
|
|
50
|
+
" echo.",
|
|
51
|
+
" echo Plugin validation failed. Push blocked.",
|
|
52
|
+
" echo Run 'codex-plugin-doctor check . --runtime' to see full diagnostics.",
|
|
53
|
+
" exit /b 1",
|
|
54
|
+
")",
|
|
55
|
+
""
|
|
56
|
+
].join("\r\n")
|
|
57
|
+
: [
|
|
58
|
+
"#!/usr/bin/env sh",
|
|
59
|
+
"# Generated by codex-plugin-doctor init git-hooks",
|
|
60
|
+
"# Validates the plugin package before every push.",
|
|
61
|
+
"",
|
|
62
|
+
"echo \"Codex Plugin Doctor: running pre-push validation...\"",
|
|
63
|
+
"",
|
|
64
|
+
"npx --yes codex-plugin-doctor check . --profile ci --runtime",
|
|
65
|
+
"",
|
|
66
|
+
"if [ $? -ne 0 ]; then",
|
|
67
|
+
" echo \"\"",
|
|
68
|
+
" echo \"Plugin validation failed. Push blocked.\"",
|
|
69
|
+
" echo \"Run 'codex-plugin-doctor check . --runtime' to see full diagnostics.\"",
|
|
70
|
+
" exit 1",
|
|
71
|
+
"fi",
|
|
72
|
+
""
|
|
73
|
+
].join("\n");
|
|
74
|
+
const hookExtension = isWindows ? ".bat" : "";
|
|
37
75
|
async function fileExists(filePath) {
|
|
38
76
|
try {
|
|
39
77
|
await stat(filePath);
|
|
@@ -57,7 +95,7 @@ async function writeHook(hookPath, content, force) {
|
|
|
57
95
|
export async function removeGitHooks(targetPath) {
|
|
58
96
|
const rootPath = path.resolve(targetPath);
|
|
59
97
|
const hooksDir = path.join(rootPath, ".git", "hooks");
|
|
60
|
-
const hookNames = ["pre-commit", "pre-push"];
|
|
98
|
+
const hookNames = [`pre-commit${hookExtension}`, `pre-push${hookExtension}`, "pre-commit", "pre-push"];
|
|
61
99
|
const removed = [];
|
|
62
100
|
const skipped = [];
|
|
63
101
|
for (const name of hookNames) {
|
|
@@ -82,8 +120,8 @@ export async function initGitHooks(targetPath, options = {}) {
|
|
|
82
120
|
await mkdir(hooksDir, { recursive: true });
|
|
83
121
|
const hookPaths = [];
|
|
84
122
|
const preExisting = [];
|
|
85
|
-
const preCommitPath = path.join(hooksDir,
|
|
86
|
-
const prePushPath = path.join(hooksDir,
|
|
123
|
+
const preCommitPath = path.join(hooksDir, `pre-commit${hookExtension}`);
|
|
124
|
+
const prePushPath = path.join(hooksDir, `pre-push${hookExtension}`);
|
|
87
125
|
const wasPreCommitExisting = await writeHook(preCommitPath, preCommitHook, force);
|
|
88
126
|
hookPaths.push(preCommitPath);
|
|
89
127
|
if (wasPreCommitExisting) {
|
|
@@ -260,6 +260,15 @@ export const ruleCatalog = [
|
|
|
260
260
|
fix: "Use `127.0.0.1` or `localhost` in server URLs and transport configuration unless external access is explicitly required.",
|
|
261
261
|
example: '{ "url": "http://127.0.0.1:3000/mcp" }'
|
|
262
262
|
},
|
|
263
|
+
{
|
|
264
|
+
id: "plugin.skill.external_http_reference",
|
|
265
|
+
category: "skill",
|
|
266
|
+
defaultSeverity: "warn",
|
|
267
|
+
summary: "A packaged skill text references an external HTTP/HTTPS URL.",
|
|
268
|
+
why: "External URLs in skill instructions can lead to link rot, phishing risk, or unauthorized telemetry when an agent follows them.",
|
|
269
|
+
fix: "Replace the external URL with a local reference, or document the link only in the plugin README where reviewers can see it.",
|
|
270
|
+
example: "Replace `https://example.com/docs` with a local `docs/setup.md` reference."
|
|
271
|
+
},
|
|
263
272
|
{
|
|
264
273
|
id: "plugin.security.prompt_injection_text",
|
|
265
274
|
category: "security",
|
package/dist/run-cli.js
CHANGED
|
@@ -78,7 +78,7 @@ const defaultIo = {
|
|
|
78
78
|
}
|
|
79
79
|
};
|
|
80
80
|
function printUsage(io) {
|
|
81
|
-
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]\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 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");
|
|
81
|
+
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 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");
|
|
82
82
|
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]");
|
|
83
83
|
}
|
|
84
84
|
const suppressUsageText = [
|
|
@@ -2254,6 +2254,8 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2254
2254
|
const runtimeApprovalDigest = runtimeApprovalDigestIndex === -1
|
|
2255
2255
|
? null
|
|
2256
2256
|
: normalizedFlags[runtimeApprovalDigestIndex + 1];
|
|
2257
|
+
const changedSinceIndex = normalizedFlags.indexOf("--changed-since");
|
|
2258
|
+
const changedSinceRef = changedSinceIndex === -1 ? null : normalizedFlags[changedSinceIndex + 1];
|
|
2257
2259
|
if (outputIndex !== -1 && (!outputPath || outputPath.startsWith("--"))) {
|
|
2258
2260
|
io.writeStderr("Missing path after --output.");
|
|
2259
2261
|
return 2;
|
|
@@ -2282,6 +2284,14 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2282
2284
|
io.writeStderr("Missing path after --history.");
|
|
2283
2285
|
return 2;
|
|
2284
2286
|
}
|
|
2287
|
+
if (changedSinceIndex !== -1 && (!changedSinceRef || changedSinceRef.startsWith("--"))) {
|
|
2288
|
+
io.writeStderr("Missing ref after --changed-since.");
|
|
2289
|
+
return 2;
|
|
2290
|
+
}
|
|
2291
|
+
if (changedSinceIndex !== -1 && checkInstalled) {
|
|
2292
|
+
io.writeStderr("--changed-since requires a single package target.");
|
|
2293
|
+
return 2;
|
|
2294
|
+
}
|
|
2285
2295
|
if (runtimeApprovalDigestIndex !== -1 &&
|
|
2286
2296
|
(!runtimeApprovalDigest || runtimeApprovalDigest.startsWith("--"))) {
|
|
2287
2297
|
io.writeStderr("Missing digest after --runtime-approval-digest.");
|
|
@@ -2384,6 +2394,59 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2384
2394
|
? createLiveStatusRenderer(io, getSpinner(outputPolicy.style === "ascii" ? "ascii" : "doctor"))
|
|
2385
2395
|
: null;
|
|
2386
2396
|
renderer?.start("Validating package");
|
|
2397
|
+
if (changedSinceRef) {
|
|
2398
|
+
const { execFile } = await import("node:child_process");
|
|
2399
|
+
try {
|
|
2400
|
+
const gitOutput = await new Promise((resolve, reject) => {
|
|
2401
|
+
execFile("git", ["diff", "--name-only", `${changedSinceRef}...HEAD`], { cwd: path.resolve(targetPath) }, (error, stdout, stderr) => {
|
|
2402
|
+
if (error) {
|
|
2403
|
+
reject(new Error(stderr.trim() || error.message));
|
|
2404
|
+
return;
|
|
2405
|
+
}
|
|
2406
|
+
resolve(stdout);
|
|
2407
|
+
});
|
|
2408
|
+
});
|
|
2409
|
+
const changedFiles = gitOutput.split("\n").filter(Boolean);
|
|
2410
|
+
if (changedFiles.length === 0) {
|
|
2411
|
+
io.writeStdout("No changed files since the given ref.");
|
|
2412
|
+
return 0;
|
|
2413
|
+
}
|
|
2414
|
+
const changedDirs = new Set();
|
|
2415
|
+
for (const file of changedFiles) {
|
|
2416
|
+
const dir = path.dirname(file);
|
|
2417
|
+
changedDirs.add(dir);
|
|
2418
|
+
}
|
|
2419
|
+
let allPassed = true;
|
|
2420
|
+
let validatedCount = 0;
|
|
2421
|
+
for (const dir of changedDirs) {
|
|
2422
|
+
const pluginRoot = path.resolve(targetPath, dir);
|
|
2423
|
+
const manifestPath = path.join(pluginRoot, ".codex-plugin", "plugin.json");
|
|
2424
|
+
try {
|
|
2425
|
+
await (await import("node:fs/promises")).stat(manifestPath);
|
|
2426
|
+
}
|
|
2427
|
+
catch {
|
|
2428
|
+
continue;
|
|
2429
|
+
}
|
|
2430
|
+
const pluginResult = applyDoctorConfig(await runCheckImpl(pluginRoot, {
|
|
2431
|
+
runtime: effectiveRuntimeProbeEnabled
|
|
2432
|
+
}), applyPolicyToDoctorConfig(applyCheckProfile(await loadDoctorConfig(pluginRoot, configPath), checkProfile), policy));
|
|
2433
|
+
io.writeStdout(`\n${pluginResult.targetPath}: ${pluginResult.status.toUpperCase()}`);
|
|
2434
|
+
validatedCount += 1;
|
|
2435
|
+
if (pluginResult.status !== "pass") {
|
|
2436
|
+
allPassed = false;
|
|
2437
|
+
for (const finding of pluginResult.findings) {
|
|
2438
|
+
io.writeStdout(` ${finding.severity === "fail" ? "FAIL" : "WARN"} ${finding.id}: ${finding.message}`);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
io.writeStdout(`\n\nValidated ${validatedCount} changed plugins.`);
|
|
2443
|
+
return allPassed ? 0 : 1;
|
|
2444
|
+
}
|
|
2445
|
+
catch (error) {
|
|
2446
|
+
io.writeStderr(`--changed-since requires a git repository. ${error.message}`);
|
|
2447
|
+
return 2;
|
|
2448
|
+
}
|
|
2449
|
+
}
|
|
2387
2450
|
const result = applyDoctorConfig(await runCheckImpl(targetPath, {
|
|
2388
2451
|
runtime: effectiveRuntimeProbeEnabled,
|
|
2389
2452
|
runtimeTranscript: effectiveRuntimeProbeEnabled && verboseRuntime
|
|
@@ -254,6 +254,23 @@ export function auditMcpServerConfig(rootPath, parsedConfig, options = {}) {
|
|
|
254
254
|
}
|
|
255
255
|
return findings;
|
|
256
256
|
}
|
|
257
|
+
const externalUrlPattern = /https?:\/\/[^\s`"'<>)]+/gi;
|
|
258
|
+
async function auditSkillExternalReferences(rootPath) {
|
|
259
|
+
const findings = [];
|
|
260
|
+
for (const filePath of await collectPromptPoisoningScanFiles(rootPath)) {
|
|
261
|
+
const content = await readFile(filePath, "utf8");
|
|
262
|
+
const matches = content.match(externalUrlPattern);
|
|
263
|
+
if (!matches) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const uniqueUrls = [...new Set(matches)];
|
|
267
|
+
const relativeFilePath = path.relative(rootPath, filePath).replace(/\\/g, "/");
|
|
268
|
+
for (const url of uniqueUrls.slice(0, 5)) {
|
|
269
|
+
findings.push(buildFinding("warn", "plugin.skill.external_http_reference", `The packaged text file \`${relativeFilePath}\` references external URL \`${url}\`.`, "External URLs in skill instructions can lead to link rot, phishing risk, or unauthorized telemetry when an agent follows them.", "Replace the external URL with a local reference, or document the link only in the plugin README where reviewers can see it.", { filePath: relativeFilePath, url }));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return findings;
|
|
273
|
+
}
|
|
257
274
|
async function collectPromptPoisoningScanFiles(rootPath, currentPath = rootPath) {
|
|
258
275
|
const entries = await readdir(currentPath, { withFileTypes: true });
|
|
259
276
|
const filePaths = [];
|
|
@@ -404,7 +421,8 @@ export async function buildSecurityAudit(targetPath) {
|
|
|
404
421
|
...validationSecurityFindings,
|
|
405
422
|
...(await auditMcpCommandSurface(discoveredPackage)),
|
|
406
423
|
...(await auditChildProcessSourceSurface(discoveredPackage.rootPath)),
|
|
407
|
-
...(await auditPromptPoisoningSurface(discoveredPackage.rootPath))
|
|
424
|
+
...(await auditPromptPoisoningSurface(discoveredPackage.rootPath)),
|
|
425
|
+
...(await auditSkillExternalReferences(discoveredPackage.rootPath))
|
|
408
426
|
];
|
|
409
427
|
return buildSecurityAuditFromFindings(discoveredPackage.rootPath, findings);
|
|
410
428
|
}
|
package/package.json
CHANGED