@testchimp/cli 0.1.12 → 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 +112 -0
- package/dist/core/schemas.d.ts +22 -0
- package/dist/core/schemas.js +20 -0
- package/dist/core/tools.js +70 -0
- package/package.json +1 -1
package/dist/cli/program.js
CHANGED
|
@@ -557,6 +557,118 @@ export function buildCliProgram() {
|
|
|
557
557
|
const out = await runTool("list-screen-states", merged, { postMcp });
|
|
558
558
|
console.log(out);
|
|
559
559
|
});
|
|
560
|
+
program
|
|
561
|
+
.command("get-release")
|
|
562
|
+
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-release").description)
|
|
563
|
+
.addOption(jsonInputOption())
|
|
564
|
+
.option("--version <version>", "Release version / label (McpGetReleaseRequest.version)")
|
|
565
|
+
.action(async (opts) => {
|
|
566
|
+
const body = {};
|
|
567
|
+
if (opts.version)
|
|
568
|
+
body.version = String(opts.version);
|
|
569
|
+
const merged = mergeBodies(body, opts.jsonInput);
|
|
570
|
+
if (!merged.version || String(merged.version).trim() === "") {
|
|
571
|
+
throw new Error("version is required (--version or --json-input {\"version\":\"...\"})");
|
|
572
|
+
}
|
|
573
|
+
const out = await runTool("get-release", { version: String(merged.version).trim() }, { postMcp });
|
|
574
|
+
console.log(out);
|
|
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
|
+
});
|
|
560
672
|
program
|
|
561
673
|
.command("upsert-screen-states")
|
|
562
674
|
.description(TOOL_DEFINITIONS.find((t) => t.kebab === "upsert-screen-states").description)
|
package/dist/core/schemas.d.ts
CHANGED
|
@@ -558,6 +558,28 @@ export declare const getBunnyshellWorkflowJobLogsInput: z.ZodObject<{
|
|
|
558
558
|
export declare const listScreenStatesInput: z.ZodObject<{
|
|
559
559
|
environment: z.ZodOptional<z.ZodString>;
|
|
560
560
|
}, z.core.$strip>;
|
|
561
|
+
export declare const getReleaseInput: z.ZodObject<{
|
|
562
|
+
version: z.ZodString;
|
|
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>;
|
|
561
583
|
/** UpsertScreenStatesRequest JSON (proto camelCase). */
|
|
562
584
|
export declare const upsertScreenStatesInput: z.ZodObject<{
|
|
563
585
|
screenStates: z.ZodArray<z.ZodObject<{
|
package/dist/core/schemas.js
CHANGED
|
@@ -235,6 +235,26 @@ export const getBunnyshellWorkflowJobLogsInput = z.object({
|
|
|
235
235
|
export const listScreenStatesInput = z.object({
|
|
236
236
|
environment: z.string().optional(),
|
|
237
237
|
});
|
|
238
|
+
export const getReleaseInput = z.object({
|
|
239
|
+
/** Release catalog version / label — maps to McpGetReleaseRequest.version */
|
|
240
|
+
version: z.string().min(1),
|
|
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
|
+
});
|
|
238
258
|
const screenStatesEntrySchema = z.object({
|
|
239
259
|
screen: z.string().optional(),
|
|
240
260
|
states: z.array(z.string()),
|
package/dist/core/tools.js
CHANGED
|
@@ -466,6 +466,76 @@ export const TOOL_DEFINITIONS = [
|
|
|
466
466
|
return postMcp("/api/mcp/list_screen_states", body);
|
|
467
467
|
},
|
|
468
468
|
},
|
|
469
|
+
{
|
|
470
|
+
kebab: "get-release",
|
|
471
|
+
description: "Fetch release catalog details for a version/label in the current project " +
|
|
472
|
+
"(McpGetReleaseRequest/Response: cut git SHA, prior release + SHA, focus areas, payload). " +
|
|
473
|
+
"Pass version (CLI: --version). Authenticated via project API key.",
|
|
474
|
+
inputSchema: S.getReleaseInput,
|
|
475
|
+
execute: async (args, { postMcp }) => {
|
|
476
|
+
const a = args;
|
|
477
|
+
// McpGetReleaseRequest — camelCase JSON field names per JsonFormat
|
|
478
|
+
const body = { version: a.version.trim() };
|
|
479
|
+
return postMcp("/api/mcp/get_release", body);
|
|
480
|
+
},
|
|
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
|
+
},
|
|
469
539
|
{
|
|
470
540
|
kebab: "upsert-screen-states",
|
|
471
541
|
description: "Merge screen names and state strings into the project's relational atlas (idempotent upsert). " +
|