@bryan-thompson/inspector-assessment-cli 1.22.0 → 1.22.1
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/build/assess-full.js +112 -3
- package/build/lib/jsonl-events.js +12 -0
- package/package.json +1 -1
package/build/assess-full.js
CHANGED
|
@@ -25,7 +25,26 @@ import { generatePolicyComplianceReport } from "../../client/lib/services/assess
|
|
|
25
25
|
import { compareAssessments } from "../../client/lib/lib/assessmentDiffer.js";
|
|
26
26
|
import { formatDiffAsMarkdown } from "../../client/lib/lib/reportFormatters/DiffReportFormatter.js";
|
|
27
27
|
import { AssessmentStateManager } from "./assessmentState.js";
|
|
28
|
-
import { emitServerConnected, emitToolDiscovered, emitToolsDiscoveryComplete, emitAssessmentComplete, emitTestBatch, emitVulnerabilityFound, emitAnnotationMissing, emitAnnotationMisaligned, emitAnnotationReviewRecommended, emitAnnotationAligned, } from "./lib/jsonl-events.js";
|
|
28
|
+
import { emitServerConnected, emitToolDiscovered, emitToolsDiscoveryComplete, emitAssessmentComplete, emitTestBatch, emitVulnerabilityFound, emitAnnotationMissing, emitAnnotationMisaligned, emitAnnotationReviewRecommended, emitAnnotationAligned, emitModulesConfigured, } from "./lib/jsonl-events.js";
|
|
29
|
+
// Valid module names derived from ASSESSMENT_CATEGORY_METADATA
|
|
30
|
+
const VALID_MODULE_NAMES = Object.keys(ASSESSMENT_CATEGORY_METADATA);
|
|
31
|
+
/**
|
|
32
|
+
* Validate module names from CLI input
|
|
33
|
+
*/
|
|
34
|
+
function validateModuleNames(input, flagName) {
|
|
35
|
+
const names = input
|
|
36
|
+
.split(",")
|
|
37
|
+
.map((n) => n.trim())
|
|
38
|
+
.filter(Boolean);
|
|
39
|
+
const invalid = names.filter((n) => !VALID_MODULE_NAMES.includes(n));
|
|
40
|
+
if (invalid.length > 0) {
|
|
41
|
+
console.error(`Error: Invalid module name(s) for ${flagName}: ${invalid.join(", ")}`);
|
|
42
|
+
console.error(`Valid modules: ${VALID_MODULE_NAMES.join(", ")}`);
|
|
43
|
+
setTimeout(() => process.exit(1), 10);
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
return names;
|
|
47
|
+
}
|
|
29
48
|
/**
|
|
30
49
|
* Load server configuration from Claude Code's MCP settings
|
|
31
50
|
*/
|
|
@@ -317,7 +336,8 @@ function buildConfig(options) {
|
|
|
317
336
|
enableSourceCodeAnalysis: !!options.sourceCodePath,
|
|
318
337
|
};
|
|
319
338
|
if (options.fullAssessment !== false) {
|
|
320
|
-
|
|
339
|
+
// Start with all modules enabled by default
|
|
340
|
+
const allModules = {
|
|
321
341
|
functionality: true,
|
|
322
342
|
security: true,
|
|
323
343
|
documentation: true,
|
|
@@ -336,6 +356,23 @@ function buildConfig(options) {
|
|
|
336
356
|
prompts: true,
|
|
337
357
|
crossCapability: true,
|
|
338
358
|
};
|
|
359
|
+
// Apply --only-modules filter (whitelist mode)
|
|
360
|
+
if (options.onlyModules?.length) {
|
|
361
|
+
for (const key of Object.keys(allModules)) {
|
|
362
|
+
// Disable all modules except those in the whitelist
|
|
363
|
+
allModules[key] = options.onlyModules.includes(key);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Apply --skip-modules filter (blacklist mode)
|
|
367
|
+
if (options.skipModules?.length) {
|
|
368
|
+
for (const module of options.skipModules) {
|
|
369
|
+
if (module in allModules) {
|
|
370
|
+
allModules[module] = false;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
config.assessmentCategories =
|
|
375
|
+
allModules;
|
|
339
376
|
}
|
|
340
377
|
// Temporal/rug pull detection configuration
|
|
341
378
|
if (options.temporalInvocations) {
|
|
@@ -519,6 +556,25 @@ async function runFullAssessment(options) {
|
|
|
519
556
|
return {};
|
|
520
557
|
}
|
|
521
558
|
const config = buildConfig(options);
|
|
559
|
+
// Emit modules_configured event for consumer progress tracking
|
|
560
|
+
if (config.assessmentCategories) {
|
|
561
|
+
const enabled = [];
|
|
562
|
+
const skipped = [];
|
|
563
|
+
for (const [key, value] of Object.entries(config.assessmentCategories)) {
|
|
564
|
+
if (value) {
|
|
565
|
+
enabled.push(key);
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
skipped.push(key);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const reason = options.onlyModules?.length
|
|
572
|
+
? "only-modules"
|
|
573
|
+
: options.skipModules?.length
|
|
574
|
+
? "skip-modules"
|
|
575
|
+
: "default";
|
|
576
|
+
emitModulesConfigured(enabled, skipped, reason);
|
|
577
|
+
}
|
|
522
578
|
const orchestrator = new AssessmentOrchestrator(config);
|
|
523
579
|
if (!options.jsonOnly) {
|
|
524
580
|
if (orchestrator.isClaudeEnabled()) {
|
|
@@ -825,6 +881,36 @@ function parseArgs() {
|
|
|
825
881
|
case "--skip-temporal":
|
|
826
882
|
options.skipTemporal = true;
|
|
827
883
|
break;
|
|
884
|
+
case "--skip-modules": {
|
|
885
|
+
const skipValue = args[++i];
|
|
886
|
+
if (!skipValue) {
|
|
887
|
+
console.error("Error: --skip-modules requires a comma-separated list");
|
|
888
|
+
setTimeout(() => process.exit(1), 10);
|
|
889
|
+
options.helpRequested = true;
|
|
890
|
+
return options;
|
|
891
|
+
}
|
|
892
|
+
options.skipModules = validateModuleNames(skipValue, "--skip-modules");
|
|
893
|
+
if (options.skipModules.length === 0 && skipValue) {
|
|
894
|
+
options.helpRequested = true;
|
|
895
|
+
return options;
|
|
896
|
+
}
|
|
897
|
+
break;
|
|
898
|
+
}
|
|
899
|
+
case "--only-modules": {
|
|
900
|
+
const onlyValue = args[++i];
|
|
901
|
+
if (!onlyValue) {
|
|
902
|
+
console.error("Error: --only-modules requires a comma-separated list");
|
|
903
|
+
setTimeout(() => process.exit(1), 10);
|
|
904
|
+
options.helpRequested = true;
|
|
905
|
+
return options;
|
|
906
|
+
}
|
|
907
|
+
options.onlyModules = validateModuleNames(onlyValue, "--only-modules");
|
|
908
|
+
if (options.onlyModules.length === 0 && onlyValue) {
|
|
909
|
+
options.helpRequested = true;
|
|
910
|
+
return options;
|
|
911
|
+
}
|
|
912
|
+
break;
|
|
913
|
+
}
|
|
828
914
|
case "--help":
|
|
829
915
|
case "-h":
|
|
830
916
|
printHelp();
|
|
@@ -845,6 +931,13 @@ function parseArgs() {
|
|
|
845
931
|
}
|
|
846
932
|
}
|
|
847
933
|
}
|
|
934
|
+
// Validate mutual exclusivity of --skip-modules and --only-modules
|
|
935
|
+
if (options.skipModules?.length && options.onlyModules?.length) {
|
|
936
|
+
console.error("Error: --skip-modules and --only-modules are mutually exclusive");
|
|
937
|
+
setTimeout(() => process.exit(1), 10);
|
|
938
|
+
options.helpRequested = true;
|
|
939
|
+
return options;
|
|
940
|
+
}
|
|
848
941
|
if (!options.serverName) {
|
|
849
942
|
console.error("Error: --server is required");
|
|
850
943
|
printHelp();
|
|
@@ -880,11 +973,23 @@ Options:
|
|
|
880
973
|
--full Enable all assessment modules (default)
|
|
881
974
|
--temporal-invocations <n> Number of invocations per tool for rug pull detection (default: 25)
|
|
882
975
|
--skip-temporal Skip temporal/rug pull testing (faster assessment)
|
|
976
|
+
--skip-modules <list> Skip specific modules (comma-separated)
|
|
977
|
+
--only-modules <list> Run only specific modules (comma-separated)
|
|
883
978
|
--json Output only JSON path (no console summary)
|
|
884
979
|
--verbose, -v Enable verbose logging
|
|
885
980
|
--help, -h Show this help message
|
|
886
981
|
|
|
887
|
-
|
|
982
|
+
Module Selection:
|
|
983
|
+
--skip-modules and --only-modules are mutually exclusive.
|
|
984
|
+
Use --skip-modules for faster runs by disabling expensive modules.
|
|
985
|
+
Use --only-modules to focus on specific areas (e.g., tool annotation PRs).
|
|
986
|
+
|
|
987
|
+
Valid module names:
|
|
988
|
+
functionality, security, documentation, errorHandling, usability,
|
|
989
|
+
mcpSpecCompliance, aupCompliance, toolAnnotations, prohibitedLibraries,
|
|
990
|
+
manifestValidation, portability, temporal, resources, prompts, crossCapability
|
|
991
|
+
|
|
992
|
+
Assessment Modules (16 total):
|
|
888
993
|
• Functionality - Tests all tools work correctly
|
|
889
994
|
• Security - Prompt injection & vulnerability testing
|
|
890
995
|
• Documentation - README completeness checks
|
|
@@ -905,6 +1010,10 @@ Examples:
|
|
|
905
1010
|
mcp-assess-full --server my-server --format markdown --include-policy
|
|
906
1011
|
mcp-assess-full --server my-server --compare ./baseline.json
|
|
907
1012
|
mcp-assess-full --server my-server --compare ./baseline.json --diff-only --format markdown
|
|
1013
|
+
|
|
1014
|
+
# Module selection examples:
|
|
1015
|
+
mcp-assess-full my-server --skip-modules security,aupCompliance # Fast CI run
|
|
1016
|
+
mcp-assess-full my-server --only-modules functionality,toolAnnotations # Annotation PR review
|
|
908
1017
|
`);
|
|
909
1018
|
}
|
|
910
1019
|
/**
|
|
@@ -178,3 +178,15 @@ export function emitAnnotationAligned(tool, confidence, annotations) {
|
|
|
178
178
|
annotations,
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* Emit modules_configured event to inform consumers which modules are enabled.
|
|
183
|
+
* Useful for accurate progress tracking when using --skip-modules or --only-modules.
|
|
184
|
+
*/
|
|
185
|
+
export function emitModulesConfigured(enabled, skipped, reason) {
|
|
186
|
+
emitJSONL({
|
|
187
|
+
event: "modules_configured",
|
|
188
|
+
enabled,
|
|
189
|
+
skipped,
|
|
190
|
+
reason,
|
|
191
|
+
});
|
|
192
|
+
}
|
package/package.json
CHANGED