@testchimp/cli 0.1.13 → 0.1.14
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/cli/program.js +96 -0
- package/dist/core/schemas.d.ts +19 -0
- package/dist/core/schemas.js +16 -0
- package/dist/core/tools.js +57 -0
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -573,6 +573,102 @@ export function buildCliProgram() {
|
|
|
573
573
|
const out = await runTool("get-release", { version: String(merged.version).trim() }, { postMcp });
|
|
574
574
|
console.log(out);
|
|
575
575
|
});
|
|
576
|
+
program
|
|
577
|
+
.command("get-security-scan-config")
|
|
578
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-security-scan-config").description)
|
|
579
|
+
.addOption(jsonInputOption())
|
|
580
|
+
.option("--id <scanId>", "Security scan id")
|
|
581
|
+
.action(async (opts) => {
|
|
582
|
+
const body = {};
|
|
583
|
+
if (opts.id)
|
|
584
|
+
body.id = String(opts.id);
|
|
585
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
586
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
587
|
+
throw new Error("id is required (--id or --json-input {\"id\":\"...\"})");
|
|
588
|
+
}
|
|
589
|
+
const out = await runTool("get-security-scan-config", { id: String(merged.id).trim() }, { postMcp });
|
|
590
|
+
console.log(out);
|
|
591
|
+
});
|
|
592
|
+
program
|
|
593
|
+
.command("update-scan-progress")
|
|
594
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "update-scan-progress").description)
|
|
595
|
+
.addOption(jsonInputOption())
|
|
596
|
+
.option("--id <scanId>", "Security scan id")
|
|
597
|
+
.option("--status <status>", "QUEUED | IN_PROGRESS | COMPLETED | EXCEPTION")
|
|
598
|
+
.action(async (opts) => {
|
|
599
|
+
const body = {};
|
|
600
|
+
if (opts.id)
|
|
601
|
+
body.id = String(opts.id);
|
|
602
|
+
if (opts.status)
|
|
603
|
+
body.status = String(opts.status);
|
|
604
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
605
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
606
|
+
throw new Error("id is required");
|
|
607
|
+
}
|
|
608
|
+
if (!merged.status || String(merged.status).trim() === "") {
|
|
609
|
+
throw new Error("status is required (QUEUED | IN_PROGRESS | COMPLETED | EXCEPTION)");
|
|
610
|
+
}
|
|
611
|
+
const out = await runTool("update-scan-progress", { id: String(merged.id).trim(), status: String(merged.status).trim() }, { postMcp });
|
|
612
|
+
console.log(out);
|
|
613
|
+
});
|
|
614
|
+
program
|
|
615
|
+
.command("report-dast-findings")
|
|
616
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-dast-findings").description)
|
|
617
|
+
.addOption(jsonInputOption())
|
|
618
|
+
.option("--id <scanId>", "Security scan id")
|
|
619
|
+
.option("--report-file <path>", "Path to ZAP Traditional JSON report")
|
|
620
|
+
.action(async (opts) => {
|
|
621
|
+
const body = {};
|
|
622
|
+
if (opts.id)
|
|
623
|
+
body.id = String(opts.id);
|
|
624
|
+
if (opts.reportFile)
|
|
625
|
+
body.reportFile = String(opts.reportFile);
|
|
626
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
627
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
628
|
+
throw new Error("id is required");
|
|
629
|
+
}
|
|
630
|
+
if (!merged.reportFile || String(merged.reportFile).trim() === "") {
|
|
631
|
+
throw new Error("reportFile is required (--report-file)");
|
|
632
|
+
}
|
|
633
|
+
const out = await runTool("report-dast-findings", { id: String(merged.id).trim(), reportFile: String(merged.reportFile).trim() }, { postMcp });
|
|
634
|
+
console.log(out);
|
|
635
|
+
});
|
|
636
|
+
program
|
|
637
|
+
.command("run-sast-scan")
|
|
638
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "run-sast-scan").description)
|
|
639
|
+
.addOption(jsonInputOption())
|
|
640
|
+
.option("--id <scanId>")
|
|
641
|
+
.action(async (opts) => {
|
|
642
|
+
const body = {};
|
|
643
|
+
if (opts.id)
|
|
644
|
+
body.id = String(opts.id);
|
|
645
|
+
const out = await runTool("run-sast-scan", mergeBodies(body, opts.jsonInput), { postMcp });
|
|
646
|
+
console.log(out);
|
|
647
|
+
});
|
|
648
|
+
program
|
|
649
|
+
.command("run-deps-scan")
|
|
650
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "run-deps-scan").description)
|
|
651
|
+
.addOption(jsonInputOption())
|
|
652
|
+
.option("--id <scanId>")
|
|
653
|
+
.action(async (opts) => {
|
|
654
|
+
const body = {};
|
|
655
|
+
if (opts.id)
|
|
656
|
+
body.id = String(opts.id);
|
|
657
|
+
const out = await runTool("run-deps-scan", mergeBodies(body, opts.jsonInput), { postMcp });
|
|
658
|
+
console.log(out);
|
|
659
|
+
});
|
|
660
|
+
program
|
|
661
|
+
.command("run-secrets-scan")
|
|
662
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "run-secrets-scan").description)
|
|
663
|
+
.addOption(jsonInputOption())
|
|
664
|
+
.option("--id <scanId>")
|
|
665
|
+
.action(async (opts) => {
|
|
666
|
+
const body = {};
|
|
667
|
+
if (opts.id)
|
|
668
|
+
body.id = String(opts.id);
|
|
669
|
+
const out = await runTool("run-secrets-scan", mergeBodies(body, opts.jsonInput), { postMcp });
|
|
670
|
+
console.log(out);
|
|
671
|
+
});
|
|
576
672
|
program
|
|
577
673
|
.command("upsert-screen-states")
|
|
578
674
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "upsert-screen-states").description)
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -561,6 +561,25 @@ export declare const listScreenStatesInput: z.ZodObject<{
|
|
|
561
561
|
export declare const getReleaseInput: z.ZodObject<{
|
|
562
562
|
version: z.ZodString;
|
|
563
563
|
}, z.core.$strip>;
|
|
564
|
+
export declare const getSecurityScanConfigInput: z.ZodObject<{
|
|
565
|
+
id: z.ZodString;
|
|
566
|
+
}, z.core.$strip>;
|
|
567
|
+
export declare const updateScanProgressInput: z.ZodObject<{
|
|
568
|
+
id: z.ZodString;
|
|
569
|
+
status: z.ZodEnum<{
|
|
570
|
+
QUEUED: "QUEUED";
|
|
571
|
+
IN_PROGRESS: "IN_PROGRESS";
|
|
572
|
+
COMPLETED: "COMPLETED";
|
|
573
|
+
EXCEPTION: "EXCEPTION";
|
|
574
|
+
}>;
|
|
575
|
+
}, z.core.$strip>;
|
|
576
|
+
export declare const reportDastFindingsInput: z.ZodObject<{
|
|
577
|
+
id: z.ZodString;
|
|
578
|
+
reportFile: z.ZodString;
|
|
579
|
+
}, z.core.$strip>;
|
|
580
|
+
export declare const stubSecurityScanInput: z.ZodObject<{
|
|
581
|
+
id: z.ZodOptional<z.ZodString>;
|
|
582
|
+
}, z.core.$strip>;
|
|
564
583
|
/** UpsertScreenStatesRequest JSON (proto camelCase). */
|
|
565
584
|
export declare const upsertScreenStatesInput: z.ZodObject<{
|
|
566
585
|
screenStates: z.ZodArray<z.ZodObject<{
|
package/dist/core/schemas.js
CHANGED
|
@@ -239,6 +239,22 @@ export const getReleaseInput = z.object({
|
|
|
239
239
|
/** Release catalog version / label — maps to McpGetReleaseRequest.version */
|
|
240
240
|
version: z.string().min(1),
|
|
241
241
|
});
|
|
242
|
+
export const getSecurityScanConfigInput = z.object({
|
|
243
|
+
id: z.string().min(1),
|
|
244
|
+
});
|
|
245
|
+
export const updateScanProgressInput = z.object({
|
|
246
|
+
id: z.string().min(1),
|
|
247
|
+
/** ScanStatus enum name: QUEUED | IN_PROGRESS | COMPLETED | EXCEPTION */
|
|
248
|
+
status: z.enum(["QUEUED", "IN_PROGRESS", "COMPLETED", "EXCEPTION"]),
|
|
249
|
+
});
|
|
250
|
+
export const reportDastFindingsInput = z.object({
|
|
251
|
+
id: z.string().min(1),
|
|
252
|
+
/** Path to ZAP Traditional JSON report file */
|
|
253
|
+
reportFile: z.string().min(1),
|
|
254
|
+
});
|
|
255
|
+
export const stubSecurityScanInput = z.object({
|
|
256
|
+
id: z.string().min(1).optional(),
|
|
257
|
+
});
|
|
242
258
|
const screenStatesEntrySchema = z.object({
|
|
243
259
|
screen: z.string().optional(),
|
|
244
260
|
states: z.array(z.string()),
|
package/dist/core/tools.js
CHANGED
|
@@ -479,6 +479,63 @@ export const TOOL_DEFINITIONS = [
|
|
|
479
479
|
return postMcp("/api/mcp/get_release", body);
|
|
480
480
|
},
|
|
481
481
|
},
|
|
482
|
+
{
|
|
483
|
+
kebab: "get-security-scan-config",
|
|
484
|
+
description: "Fetch security scan config by scan id (categories, environment, release label, status). " +
|
|
485
|
+
"Pass id (CLI: --id). Used by /testchimp run security scan.",
|
|
486
|
+
inputSchema: S.getSecurityScanConfigInput,
|
|
487
|
+
execute: async (args, { postMcp }) => {
|
|
488
|
+
const a = args;
|
|
489
|
+
return postMcp("/api/mcp/get_security_scan_config", { scanId: a.id.trim() });
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
kebab: "update-scan-progress",
|
|
494
|
+
description: "Update a scan's status. status must be one of: QUEUED, IN_PROGRESS, COMPLETED, EXCEPTION. " +
|
|
495
|
+
"Call IN_PROGRESS when starting; COMPLETED when all selected categories finish; EXCEPTION on hard failure.",
|
|
496
|
+
inputSchema: S.updateScanProgressInput,
|
|
497
|
+
execute: async (args, { postMcp }) => {
|
|
498
|
+
const a = args;
|
|
499
|
+
return postMcp("/api/mcp/update_scan_progress", {
|
|
500
|
+
scanId: a.id.trim(),
|
|
501
|
+
status: a.status,
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
kebab: "report-dast-findings",
|
|
507
|
+
description: "Upload a ZAP Traditional JSON report for a security scan. Pass --id and --report-file <path>. " +
|
|
508
|
+
"Backend parses alerts, dedupes by bug hash, and inserts new SECURITY bugs linked to the scan. " +
|
|
509
|
+
"Does not mark the scan COMPLETED.",
|
|
510
|
+
inputSchema: S.reportDastFindingsInput,
|
|
511
|
+
execute: async (args, { postMcp }) => {
|
|
512
|
+
const a = args;
|
|
513
|
+
const { readFile } = await import("node:fs/promises");
|
|
514
|
+
const reportJson = await readFile(a.reportFile, "utf8");
|
|
515
|
+
return postMcp("/api/mcp/report_dast_findings", {
|
|
516
|
+
scanId: a.id.trim(),
|
|
517
|
+
reportJson,
|
|
518
|
+
});
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
kebab: "run-sast-scan",
|
|
523
|
+
description: "Stub: Semgrep SAST scan is not implemented yet.",
|
|
524
|
+
inputSchema: S.stubSecurityScanInput,
|
|
525
|
+
execute: async () => JSON.stringify({ status: "not_implemented", tool: "run-sast-scan" }),
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
kebab: "run-deps-scan",
|
|
529
|
+
description: "Stub: Trivy dependency scan is not implemented yet.",
|
|
530
|
+
inputSchema: S.stubSecurityScanInput,
|
|
531
|
+
execute: async () => JSON.stringify({ status: "not_implemented", tool: "run-deps-scan" }),
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
kebab: "run-secrets-scan",
|
|
535
|
+
description: "Stub: Gitleaks secrets scan is not implemented yet.",
|
|
536
|
+
inputSchema: S.stubSecurityScanInput,
|
|
537
|
+
execute: async () => JSON.stringify({ status: "not_implemented", tool: "run-secrets-scan" }),
|
|
538
|
+
},
|
|
482
539
|
{
|
|
483
540
|
kebab: "upsert-screen-states",
|
|
484
541
|
description: "Merge screen names and state strings into the project's relational atlas (idempotent upsert). " +
|