@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.
@@ -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)
@@ -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<{
@@ -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()),
@@ -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). " +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testchimp/cli",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "TestChimp CLI and MCP server — coverage, plans, EaaS, TrueCoverage (calls /api/mcp/*)",
5
5
  "type": "module",
6
6
  "main": "dist/bin/testchimp.js",