@testchimp/cli 0.1.14 → 0.1.15
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 +42 -12
- package/dist/core/schemas.d.ts +11 -2
- package/dist/core/schemas.js +14 -2
- package/dist/core/tools.js +49 -16
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -634,39 +634,69 @@ export function buildCliProgram() {
|
|
|
634
634
|
console.log(out);
|
|
635
635
|
});
|
|
636
636
|
program
|
|
637
|
-
.command("
|
|
638
|
-
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "
|
|
637
|
+
.command("report-sast-findings")
|
|
638
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-sast-findings").description)
|
|
639
639
|
.addOption(jsonInputOption())
|
|
640
|
-
.option("--id <scanId>")
|
|
640
|
+
.option("--id <scanId>", "Security scan id")
|
|
641
|
+
.option("--report-file <path>", "Path to full Semgrep CLI JSON report")
|
|
641
642
|
.action(async (opts) => {
|
|
642
643
|
const body = {};
|
|
643
644
|
if (opts.id)
|
|
644
645
|
body.id = String(opts.id);
|
|
645
|
-
|
|
646
|
+
if (opts.reportFile)
|
|
647
|
+
body.reportFile = String(opts.reportFile);
|
|
648
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
649
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
650
|
+
throw new Error("id is required");
|
|
651
|
+
}
|
|
652
|
+
if (!merged.reportFile || String(merged.reportFile).trim() === "") {
|
|
653
|
+
throw new Error("reportFile is required (--report-file)");
|
|
654
|
+
}
|
|
655
|
+
const out = await runTool("report-sast-findings", { id: String(merged.id).trim(), reportFile: String(merged.reportFile).trim() }, { postMcp });
|
|
646
656
|
console.log(out);
|
|
647
657
|
});
|
|
648
658
|
program
|
|
649
|
-
.command("
|
|
650
|
-
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "
|
|
659
|
+
.command("report-secrets-findings")
|
|
660
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-secrets-findings").description)
|
|
651
661
|
.addOption(jsonInputOption())
|
|
652
|
-
.option("--id <scanId>")
|
|
662
|
+
.option("--id <scanId>", "Security scan id")
|
|
663
|
+
.option("--report-file <path>", "Path to full Gitleaks JSON report")
|
|
653
664
|
.action(async (opts) => {
|
|
654
665
|
const body = {};
|
|
655
666
|
if (opts.id)
|
|
656
667
|
body.id = String(opts.id);
|
|
657
|
-
|
|
668
|
+
if (opts.reportFile)
|
|
669
|
+
body.reportFile = String(opts.reportFile);
|
|
670
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
671
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
672
|
+
throw new Error("id is required");
|
|
673
|
+
}
|
|
674
|
+
if (!merged.reportFile || String(merged.reportFile).trim() === "") {
|
|
675
|
+
throw new Error("reportFile is required (--report-file)");
|
|
676
|
+
}
|
|
677
|
+
const out = await runTool("report-secrets-findings", { id: String(merged.id).trim(), reportFile: String(merged.reportFile).trim() }, { postMcp });
|
|
658
678
|
console.log(out);
|
|
659
679
|
});
|
|
660
680
|
program
|
|
661
|
-
.command("
|
|
662
|
-
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "
|
|
681
|
+
.command("report-deps-findings")
|
|
682
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "report-deps-findings").description)
|
|
663
683
|
.addOption(jsonInputOption())
|
|
664
|
-
.option("--id <scanId>")
|
|
684
|
+
.option("--id <scanId>", "Security scan id")
|
|
685
|
+
.option("--report-file <path>", "Path to full Trivy JSON report")
|
|
665
686
|
.action(async (opts) => {
|
|
666
687
|
const body = {};
|
|
667
688
|
if (opts.id)
|
|
668
689
|
body.id = String(opts.id);
|
|
669
|
-
|
|
690
|
+
if (opts.reportFile)
|
|
691
|
+
body.reportFile = String(opts.reportFile);
|
|
692
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
693
|
+
if (!merged.id || String(merged.id).trim() === "") {
|
|
694
|
+
throw new Error("id is required");
|
|
695
|
+
}
|
|
696
|
+
if (!merged.reportFile || String(merged.reportFile).trim() === "") {
|
|
697
|
+
throw new Error("reportFile is required (--report-file)");
|
|
698
|
+
}
|
|
699
|
+
const out = await runTool("report-deps-findings", { id: String(merged.id).trim(), reportFile: String(merged.reportFile).trim() }, { postMcp });
|
|
670
700
|
console.log(out);
|
|
671
701
|
});
|
|
672
702
|
program
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -577,8 +577,17 @@ export declare const reportDastFindingsInput: z.ZodObject<{
|
|
|
577
577
|
id: z.ZodString;
|
|
578
578
|
reportFile: z.ZodString;
|
|
579
579
|
}, z.core.$strip>;
|
|
580
|
-
export declare const
|
|
581
|
-
id: z.
|
|
580
|
+
export declare const reportSastFindingsInput: z.ZodObject<{
|
|
581
|
+
id: z.ZodString;
|
|
582
|
+
reportFile: z.ZodString;
|
|
583
|
+
}, z.core.$strip>;
|
|
584
|
+
export declare const reportSecretsFindingsInput: z.ZodObject<{
|
|
585
|
+
id: z.ZodString;
|
|
586
|
+
reportFile: z.ZodString;
|
|
587
|
+
}, z.core.$strip>;
|
|
588
|
+
export declare const reportDepsFindingsInput: z.ZodObject<{
|
|
589
|
+
id: z.ZodString;
|
|
590
|
+
reportFile: z.ZodString;
|
|
582
591
|
}, z.core.$strip>;
|
|
583
592
|
/** UpsertScreenStatesRequest JSON (proto camelCase). */
|
|
584
593
|
export declare const upsertScreenStatesInput: z.ZodObject<{
|
package/dist/core/schemas.js
CHANGED
|
@@ -252,8 +252,20 @@ export const reportDastFindingsInput = z.object({
|
|
|
252
252
|
/** Path to ZAP Traditional JSON report file */
|
|
253
253
|
reportFile: z.string().min(1),
|
|
254
254
|
});
|
|
255
|
-
export const
|
|
256
|
-
id: z.string().min(1)
|
|
255
|
+
export const reportSastFindingsInput = z.object({
|
|
256
|
+
id: z.string().min(1),
|
|
257
|
+
/** Path to full Semgrep CLI JSON report file */
|
|
258
|
+
reportFile: z.string().min(1),
|
|
259
|
+
});
|
|
260
|
+
export const reportSecretsFindingsInput = z.object({
|
|
261
|
+
id: z.string().min(1),
|
|
262
|
+
/** Path to full Gitleaks JSON report file */
|
|
263
|
+
reportFile: z.string().min(1),
|
|
264
|
+
});
|
|
265
|
+
export const reportDepsFindingsInput = z.object({
|
|
266
|
+
id: z.string().min(1),
|
|
267
|
+
/** Path to full Trivy JSON report file */
|
|
268
|
+
reportFile: z.string().min(1),
|
|
257
269
|
});
|
|
258
270
|
const screenStatesEntrySchema = z.object({
|
|
259
271
|
screen: z.string().optional(),
|
package/dist/core/tools.js
CHANGED
|
@@ -481,8 +481,10 @@ export const TOOL_DEFINITIONS = [
|
|
|
481
481
|
},
|
|
482
482
|
{
|
|
483
483
|
kebab: "get-security-scan-config",
|
|
484
|
-
description: "Fetch security scan config by scan id (
|
|
485
|
-
"Pass id (CLI: --id).
|
|
484
|
+
description: "Fetch security scan config by scan id (detail.dastCheckConfig / detail.sastCheckConfig / " +
|
|
485
|
+
"detail.depsCheckConfig / detail.leaksCheckConfig, release label, status). Pass id (CLI: --id). " +
|
|
486
|
+
"Used by /testchimp run security scan. For DAST honour allowActiveScan / useEphemeralSandbox / scope " +
|
|
487
|
+
"on dastCheckConfig.",
|
|
486
488
|
inputSchema: S.getSecurityScanConfigInput,
|
|
487
489
|
execute: async (args, { postMcp }) => {
|
|
488
490
|
const a = args;
|
|
@@ -492,7 +494,8 @@ export const TOOL_DEFINITIONS = [
|
|
|
492
494
|
{
|
|
493
495
|
kebab: "update-scan-progress",
|
|
494
496
|
description: "Update a scan's status. status must be one of: QUEUED, IN_PROGRESS, COMPLETED, EXCEPTION. " +
|
|
495
|
-
"Call IN_PROGRESS when starting
|
|
497
|
+
"Call IN_PROGRESS when starting. Each scan is a single checker type: the category playbook " +
|
|
498
|
+
"sets COMPLETED after a successful report-*-findings (or EXCEPTION on hard failure).",
|
|
496
499
|
inputSchema: S.updateScanProgressInput,
|
|
497
500
|
execute: async (args, { postMcp }) => {
|
|
498
501
|
const a = args;
|
|
@@ -506,7 +509,7 @@ export const TOOL_DEFINITIONS = [
|
|
|
506
509
|
kebab: "report-dast-findings",
|
|
507
510
|
description: "Upload a ZAP Traditional JSON report for a security scan. Pass --id and --report-file <path>. " +
|
|
508
511
|
"Backend parses alerts, dedupes by bug hash, and inserts new SECURITY bugs linked to the scan. " +
|
|
509
|
-
"Does not mark the scan COMPLETED.",
|
|
512
|
+
"Does not mark the scan COMPLETED — the DAST playbook calls update-scan-progress COMPLETED after this.",
|
|
510
513
|
inputSchema: S.reportDastFindingsInput,
|
|
511
514
|
execute: async (args, { postMcp }) => {
|
|
512
515
|
const a = args;
|
|
@@ -519,22 +522,52 @@ export const TOOL_DEFINITIONS = [
|
|
|
519
522
|
},
|
|
520
523
|
},
|
|
521
524
|
{
|
|
522
|
-
kebab: "
|
|
523
|
-
description: "
|
|
524
|
-
|
|
525
|
-
|
|
525
|
+
kebab: "report-sast-findings",
|
|
526
|
+
description: "Upload a full Semgrep CLI JSON report for a SAST security scan. Pass --id and --report-file <path>. " +
|
|
527
|
+
"Backend stores the raw report, parses results, dedupes by bug hash, and inserts new SECURITY bugs. " +
|
|
528
|
+
"Does not mark the scan COMPLETED — the SAST playbook calls update-scan-progress COMPLETED after this.",
|
|
529
|
+
inputSchema: S.reportSastFindingsInput,
|
|
530
|
+
execute: async (args, { postMcp }) => {
|
|
531
|
+
const a = args;
|
|
532
|
+
const { readFile } = await import("node:fs/promises");
|
|
533
|
+
const reportJson = await readFile(a.reportFile, "utf8");
|
|
534
|
+
return postMcp("/api/mcp/report_sast_findings", {
|
|
535
|
+
scanId: a.id.trim(),
|
|
536
|
+
reportJson,
|
|
537
|
+
});
|
|
538
|
+
},
|
|
526
539
|
},
|
|
527
540
|
{
|
|
528
|
-
kebab: "
|
|
529
|
-
description: "
|
|
530
|
-
|
|
531
|
-
|
|
541
|
+
kebab: "report-secrets-findings",
|
|
542
|
+
description: "Upload a full Gitleaks JSON report for a secrets security scan. Pass --id and --report-file <path>. " +
|
|
543
|
+
"Backend redacts secret payloads, stores the report, dedupes by bug hash, and inserts SECURITY bugs. " +
|
|
544
|
+
"Does not mark the scan COMPLETED — the secrets playbook calls update-scan-progress COMPLETED after this.",
|
|
545
|
+
inputSchema: S.reportSecretsFindingsInput,
|
|
546
|
+
execute: async (args, { postMcp }) => {
|
|
547
|
+
const a = args;
|
|
548
|
+
const { readFile } = await import("node:fs/promises");
|
|
549
|
+
const reportJson = await readFile(a.reportFile, "utf8");
|
|
550
|
+
return postMcp("/api/mcp/report_secrets_findings", {
|
|
551
|
+
scanId: a.id.trim(),
|
|
552
|
+
reportJson,
|
|
553
|
+
});
|
|
554
|
+
},
|
|
532
555
|
},
|
|
533
556
|
{
|
|
534
|
-
kebab: "
|
|
535
|
-
description: "
|
|
536
|
-
|
|
537
|
-
|
|
557
|
+
kebab: "report-deps-findings",
|
|
558
|
+
description: "Upload a full Trivy JSON report for a dependency security scan. Pass --id and --report-file <path>. " +
|
|
559
|
+
"Backend stores the report, filters by security profile / ignore-unfixed, dedupes, and inserts SECURITY bugs. " +
|
|
560
|
+
"Does not mark the scan COMPLETED — the deps playbook calls update-scan-progress COMPLETED after this.",
|
|
561
|
+
inputSchema: S.reportDepsFindingsInput,
|
|
562
|
+
execute: async (args, { postMcp }) => {
|
|
563
|
+
const a = args;
|
|
564
|
+
const { readFile } = await import("node:fs/promises");
|
|
565
|
+
const reportJson = await readFile(a.reportFile, "utf8");
|
|
566
|
+
return postMcp("/api/mcp/report_deps_findings", {
|
|
567
|
+
scanId: a.id.trim(),
|
|
568
|
+
reportJson,
|
|
569
|
+
});
|
|
570
|
+
},
|
|
538
571
|
},
|
|
539
572
|
{
|
|
540
573
|
kebab: "upsert-screen-states",
|