@kevinrabun/judges 3.84.0 → 3.85.0

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +63 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-cve-lookup.d.ts +5 -0
  6. package/dist/commands/finding-cve-lookup.d.ts.map +1 -0
  7. package/dist/commands/finding-cve-lookup.js +98 -0
  8. package/dist/commands/finding-cve-lookup.js.map +1 -0
  9. package/dist/commands/finding-dependency-risk.d.ts +5 -0
  10. package/dist/commands/finding-dependency-risk.d.ts.map +1 -0
  11. package/dist/commands/finding-dependency-risk.js +118 -0
  12. package/dist/commands/finding-dependency-risk.js.map +1 -0
  13. package/dist/commands/finding-security-hotspot.d.ts +5 -0
  14. package/dist/commands/finding-security-hotspot.d.ts.map +1 -0
  15. package/dist/commands/finding-security-hotspot.js +176 -0
  16. package/dist/commands/finding-security-hotspot.js.map +1 -0
  17. package/dist/commands/finding-suppression-log.d.ts +5 -0
  18. package/dist/commands/finding-suppression-log.d.ts.map +1 -0
  19. package/dist/commands/finding-suppression-log.js +175 -0
  20. package/dist/commands/finding-suppression-log.js.map +1 -0
  21. package/dist/commands/finding-timeline-view.d.ts +5 -0
  22. package/dist/commands/finding-timeline-view.d.ts.map +1 -0
  23. package/dist/commands/finding-timeline-view.js +99 -0
  24. package/dist/commands/finding-timeline-view.js.map +1 -0
  25. package/dist/commands/review-batch-run.d.ts +5 -0
  26. package/dist/commands/review-batch-run.d.ts.map +1 -0
  27. package/dist/commands/review-batch-run.js +150 -0
  28. package/dist/commands/review-batch-run.js.map +1 -0
  29. package/dist/commands/review-diff-highlight.d.ts +5 -0
  30. package/dist/commands/review-diff-highlight.d.ts.map +1 -0
  31. package/dist/commands/review-diff-highlight.js +180 -0
  32. package/dist/commands/review-diff-highlight.js.map +1 -0
  33. package/dist/commands/review-output-filter.d.ts +5 -0
  34. package/dist/commands/review-output-filter.d.ts.map +1 -0
  35. package/dist/commands/review-output-filter.js +113 -0
  36. package/dist/commands/review-output-filter.js.map +1 -0
  37. package/dist/commands/review-pr-template.d.ts +5 -0
  38. package/dist/commands/review-pr-template.d.ts.map +1 -0
  39. package/dist/commands/review-pr-template.js +105 -0
  40. package/dist/commands/review-pr-template.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Finding-cve-lookup — Look up CVE references in findings.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Helpers ────────────────────────────────────────────────────────────────
6
+ const CVE_PATTERN = /CVE-\d{4}-\d{4,}/gi;
7
+ function extractCves(verdict) {
8
+ const refs = [];
9
+ for (const f of verdict.findings) {
10
+ const sources = [
11
+ { text: f.title, source: "title" },
12
+ { text: f.description || "", source: "description" },
13
+ { text: f.recommendation || "", source: "recommendation" },
14
+ { text: f.ruleId || "", source: "ruleId" },
15
+ { text: f.reference || "", source: "reference" },
16
+ ];
17
+ for (const { text, source } of sources) {
18
+ const matches = text.match(CVE_PATTERN);
19
+ if (matches) {
20
+ for (const cveId of matches) {
21
+ // avoid duplicates per finding
22
+ if (!refs.some((r) => r.cveId === cveId.toUpperCase() && r.ruleId === f.ruleId)) {
23
+ refs.push({
24
+ cveId: cveId.toUpperCase(),
25
+ ruleId: f.ruleId,
26
+ title: f.title,
27
+ severity: (f.severity || "medium").toLowerCase(),
28
+ source,
29
+ context: text.length > 80 ? text.slice(0, 80) + "…" : text,
30
+ });
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+ return refs.sort((a, b) => a.cveId.localeCompare(b.cveId));
37
+ }
38
+ // ─── CLI ────────────────────────────────────────────────────────────────────
39
+ export function runFindingCveLookup(argv) {
40
+ const fileIdx = argv.indexOf("--file");
41
+ const formatIdx = argv.indexOf("--format");
42
+ const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : undefined;
43
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
44
+ if (argv.includes("--help") || argv.includes("-h")) {
45
+ console.log(`
46
+ judges finding-cve-lookup — Extract CVE references from findings
47
+
48
+ Usage:
49
+ judges finding-cve-lookup --file <verdict.json> [--format table|json]
50
+
51
+ Options:
52
+ --file <path> Path to verdict JSON file (required)
53
+ --format <fmt> Output format: table (default), json
54
+ --help, -h Show this help
55
+ `);
56
+ return;
57
+ }
58
+ if (!filePath) {
59
+ console.error("Error: --file required");
60
+ process.exitCode = 1;
61
+ return;
62
+ }
63
+ if (!existsSync(filePath)) {
64
+ console.error(`Error: not found: ${filePath}`);
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ let verdict;
69
+ try {
70
+ verdict = JSON.parse(readFileSync(filePath, "utf-8"));
71
+ }
72
+ catch {
73
+ console.error("Error: invalid JSON");
74
+ process.exitCode = 1;
75
+ return;
76
+ }
77
+ const refs = extractCves(verdict);
78
+ if (refs.length === 0) {
79
+ console.log("No CVE references found in findings.");
80
+ return;
81
+ }
82
+ if (format === "json") {
83
+ console.log(JSON.stringify(refs, null, 2));
84
+ return;
85
+ }
86
+ console.log(`\nCVE References (${refs.length} found)`);
87
+ console.log("═".repeat(75));
88
+ console.log(`${"CVE ID".padEnd(20)} ${"Severity".padEnd(10)} ${"Rule".padEnd(25)} Source`);
89
+ console.log("─".repeat(75));
90
+ for (const r of refs) {
91
+ const rule = r.ruleId.length > 23 ? r.ruleId.slice(0, 23) + "…" : r.ruleId;
92
+ console.log(`${r.cveId.padEnd(20)} ${r.severity.padEnd(10)} ${rule.padEnd(25)} ${r.source}`);
93
+ }
94
+ console.log("═".repeat(75));
95
+ const unique = new Set(refs.map((r) => r.cveId));
96
+ console.log(`\n${unique.size} unique CVE(s) across ${refs.length} reference(s)`);
97
+ }
98
+ //# sourceMappingURL=finding-cve-lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-cve-lookup.js","sourceRoot":"","sources":["../../src/commands/finding-cve-lookup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAc9C,+EAA+E;AAE/E,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC,SAAS,WAAW,CAAC,OAAwB;IAC3C,MAAM,IAAI,GAAmB,EAAE,CAAC;IAEhC,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG;YACd,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;YAClC,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE;YACpD,EAAE,IAAI,EAAE,CAAC,CAAC,cAAc,IAAI,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE;YAC1D,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;YAC1C,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE;SACjD,CAAC;QAEF,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACxC,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,+BAA+B;oBAC/B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;wBAChF,IAAI,CAAC,IAAI,CAAC;4BACR,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;4BAC1B,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,KAAK,EAAE,CAAC,CAAC,KAAK;4BACd,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC,WAAW,EAAE;4BAChD,MAAM;4BACN,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI;yBAC3D,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAE9D,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QACxC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAElC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,yBAAyB,IAAI,CAAC,MAAM,eAAe,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-dependency-risk — Assess risk level of project dependencies.
3
+ */
4
+ export declare function runFindingDependencyRisk(argv: string[]): void;
5
+ //# sourceMappingURL=finding-dependency-risk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dependency-risk.d.ts","sourceRoot":"","sources":["../../src/commands/finding-dependency-risk.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmFH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgE7D"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Finding-dependency-risk — Assess risk level of project dependencies.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Helpers ────────────────────────────────────────────────────────────────
6
+ const KNOWN_RISKY_PATTERNS = [
7
+ { pattern: /^eval-/, reason: "eval-prefixed package" },
8
+ { pattern: /^exec-/, reason: "exec-prefixed package" },
9
+ { pattern: /^shell-/, reason: "shell-prefixed package" },
10
+ ];
11
+ function assessDep(name, version, type) {
12
+ const reasons = [];
13
+ let score = 0;
14
+ // version range checks
15
+ if (version === "*" || version === "latest") {
16
+ reasons.push("unpinned version (*)");
17
+ score += 30;
18
+ }
19
+ else if (version.startsWith(">=")) {
20
+ reasons.push("open-ended version range (>=)");
21
+ score += 20;
22
+ }
23
+ else if (version.startsWith("^") && version.includes("0.")) {
24
+ reasons.push("caret range on 0.x (breaking changes expected)");
25
+ score += 15;
26
+ }
27
+ // name pattern checks
28
+ for (const { pattern, reason } of KNOWN_RISKY_PATTERNS) {
29
+ if (pattern.test(name)) {
30
+ reasons.push(reason);
31
+ score += 25;
32
+ }
33
+ }
34
+ // scoped package is slightly less risky
35
+ if (!name.startsWith("@")) {
36
+ reasons.push("unscoped package");
37
+ score += 5;
38
+ }
39
+ // production deps carry higher baseline risk
40
+ if (type === "production") {
41
+ score += 5;
42
+ }
43
+ const riskLevel = score >= 50 ? "critical" : score >= 30 ? "high" : score >= 15 ? "medium" : "low";
44
+ return { name, version, type, riskScore: score, riskLevel, reasons };
45
+ }
46
+ function analyzeDeps(pkgPath) {
47
+ const raw = readFileSync(pkgPath, "utf-8");
48
+ const pkg = JSON.parse(raw);
49
+ const results = [];
50
+ const deps = pkg.dependencies || {};
51
+ for (const [name, ver] of Object.entries(deps)) {
52
+ results.push(assessDep(name, String(ver), "production"));
53
+ }
54
+ const devDeps = pkg.devDependencies || {};
55
+ for (const [name, ver] of Object.entries(devDeps)) {
56
+ results.push(assessDep(name, String(ver), "development"));
57
+ }
58
+ return results.sort((a, b) => b.riskScore - a.riskScore);
59
+ }
60
+ // ─── CLI ────────────────────────────────────────────────────────────────────
61
+ export function runFindingDependencyRisk(argv) {
62
+ const fileIdx = argv.indexOf("--file");
63
+ const formatIdx = argv.indexOf("--format");
64
+ const minIdx = argv.indexOf("--min-risk");
65
+ const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : "package.json";
66
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
67
+ const minRisk = minIdx >= 0 ? argv[minIdx + 1] : "low";
68
+ if (argv.includes("--help") || argv.includes("-h")) {
69
+ console.log(`
70
+ judges finding-dependency-risk — Assess dependency risk levels
71
+
72
+ Usage:
73
+ judges finding-dependency-risk [--file <package.json>]
74
+ [--min-risk low|medium|high|critical] [--format table|json]
75
+
76
+ Options:
77
+ --file <path> Path to package.json (default: package.json)
78
+ --min-risk <lvl> Minimum risk level to show (default: low)
79
+ --format <fmt> Output format: table (default), json
80
+ --help, -h Show this help
81
+ `);
82
+ return;
83
+ }
84
+ if (!existsSync(filePath)) {
85
+ console.error(`Error: not found: ${filePath}`);
86
+ process.exitCode = 1;
87
+ return;
88
+ }
89
+ let results;
90
+ try {
91
+ results = analyzeDeps(filePath);
92
+ }
93
+ catch {
94
+ console.error("Error: invalid package.json");
95
+ process.exitCode = 1;
96
+ return;
97
+ }
98
+ const riskOrder = { low: 0, medium: 1, high: 2, critical: 3 };
99
+ const minLevel = riskOrder[minRisk] || 0;
100
+ results = results.filter((r) => (riskOrder[r.riskLevel] || 0) >= minLevel);
101
+ if (format === "json") {
102
+ console.log(JSON.stringify(results, null, 2));
103
+ return;
104
+ }
105
+ console.log(`\nDependency Risk Analysis (${results.length} dependencies)`);
106
+ console.log("═".repeat(75));
107
+ console.log(`${"Package".padEnd(30)} ${"Version".padEnd(12)} ${"Type".padEnd(12)} ${"Score".padEnd(7)} Risk`);
108
+ console.log("─".repeat(75));
109
+ for (const r of results) {
110
+ const name = r.name.length > 28 ? r.name.slice(0, 28) + "…" : r.name;
111
+ console.log(`${name.padEnd(30)} ${r.version.padEnd(12)} ${r.type.padEnd(12)} ${String(r.riskScore).padEnd(7)} ${r.riskLevel}`);
112
+ for (const reason of r.reasons) {
113
+ console.log(` └─ ${reason}`);
114
+ }
115
+ }
116
+ console.log("═".repeat(75));
117
+ }
118
+ //# sourceMappingURL=finding-dependency-risk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-dependency-risk.js","sourceRoot":"","sources":["../../src/commands/finding-dependency-risk.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAa9C,+EAA+E;AAE/E,MAAM,oBAAoB,GAAG;IAC3B,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE;IACtD,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE;IACtD,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,wBAAwB,EAAE;CACzD,CAAC;AAEF,SAAS,SAAS,CAAC,IAAY,EAAE,OAAe,EAAE,IAAkC;IAClF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,uBAAuB;IACvB,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACrC,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC9C,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;SAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;QAC/D,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;IAED,sBAAsB;IACtB,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,oBAAoB,EAAE,CAAC;QACvD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,KAAK,IAAI,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,6CAA6C;IAC7C,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IAEnG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACvE,CAAC;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAc,EAAE,CAAC;IAE9B,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;AAC3D,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,wBAAwB,CAAC,IAAc;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IACnE,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEvD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;CAYf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,OAAkB,CAAC;IACvB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QAC7C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAA2B,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACtF,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;IAE3E,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC9G,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,OAAO,CAAC,GAAG,CACT,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAClH,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-security-hotspot — Identify security-sensitive code zones.
3
+ */
4
+ export declare function runFindingSecurityHotspot(argv: string[]): void;
5
+ //# sourceMappingURL=finding-security-hotspot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-security-hotspot.d.ts","sourceRoot":"","sources":["../../src/commands/finding-security-hotspot.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6IH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsE9D"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Finding-security-hotspot — Identify security-sensitive code zones.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ const HOTSPOT_RULES = [
6
+ {
7
+ category: "crypto",
8
+ pattern: /\b(md5|sha1)\b/i,
9
+ severity: "high",
10
+ description: "Weak hash algorithm",
11
+ recommendation: "Use SHA-256 or stronger",
12
+ },
13
+ {
14
+ category: "crypto",
15
+ pattern: /\b(DES|RC4|ECB)\b/,
16
+ severity: "critical",
17
+ description: "Weak cipher or mode",
18
+ recommendation: "Use AES-GCM or ChaCha20",
19
+ },
20
+ {
21
+ category: "auth",
22
+ pattern: /password\s*=\s*["'][^"']+["']/i,
23
+ severity: "critical",
24
+ description: "Hardcoded password",
25
+ recommendation: "Use environment variables or secrets manager",
26
+ },
27
+ {
28
+ category: "auth",
29
+ pattern: /api[_-]?key\s*=\s*["'][^"']+["']/i,
30
+ severity: "critical",
31
+ description: "Hardcoded API key",
32
+ recommendation: "Use environment variables or secrets manager",
33
+ },
34
+ {
35
+ category: "injection",
36
+ pattern: /\beval\s*\(/,
37
+ severity: "high",
38
+ description: "Use of eval()",
39
+ recommendation: "Avoid eval; use safe parsing alternatives",
40
+ },
41
+ {
42
+ category: "injection",
43
+ pattern: /\bexec\s*\(/,
44
+ severity: "medium",
45
+ description: "Use of exec()",
46
+ recommendation: "Validate and sanitize inputs before exec",
47
+ },
48
+ {
49
+ category: "injection",
50
+ pattern: /innerHTML\s*=/,
51
+ severity: "medium",
52
+ description: "Direct innerHTML assignment",
53
+ recommendation: "Use textContent or sanitize HTML",
54
+ },
55
+ {
56
+ category: "data",
57
+ pattern: /\b(console\.log|print|puts)\b.*password/i,
58
+ severity: "high",
59
+ description: "Logging sensitive data",
60
+ recommendation: "Remove sensitive data from logs",
61
+ },
62
+ {
63
+ category: "network",
64
+ pattern: /http:\/\//,
65
+ severity: "low",
66
+ description: "Insecure HTTP URL",
67
+ recommendation: "Use HTTPS",
68
+ },
69
+ {
70
+ category: "network",
71
+ pattern: /rejectUnauthorized\s*:\s*false/,
72
+ severity: "high",
73
+ description: "TLS validation disabled",
74
+ recommendation: "Enable certificate validation",
75
+ },
76
+ {
77
+ category: "file",
78
+ pattern: /\.\.\//g,
79
+ severity: "medium",
80
+ description: "Path traversal pattern",
81
+ recommendation: "Validate and sanitize file paths",
82
+ },
83
+ {
84
+ category: "sql",
85
+ pattern: /\bSELECT\b.*\+\s*\w+/i,
86
+ severity: "high",
87
+ description: "Potential SQL injection (string concat)",
88
+ recommendation: "Use parameterized queries",
89
+ },
90
+ ];
91
+ function scanFile(filePath) {
92
+ const content = readFileSync(filePath, "utf-8");
93
+ const lines = content.split("\n");
94
+ const hotspots = [];
95
+ for (let i = 0; i < lines.length; i++) {
96
+ const line = lines[i];
97
+ const trimmed = line.trim();
98
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("#"))
99
+ continue;
100
+ for (const rule of HOTSPOT_RULES) {
101
+ if (rule.pattern.test(line)) {
102
+ hotspots.push({
103
+ line: i + 1,
104
+ category: rule.category,
105
+ pattern: rule.pattern.source,
106
+ severity: rule.severity,
107
+ description: rule.description,
108
+ recommendation: rule.recommendation,
109
+ });
110
+ }
111
+ }
112
+ }
113
+ return hotspots;
114
+ }
115
+ // ─── CLI ────────────────────────────────────────────────────────────────────
116
+ export function runFindingSecurityHotspot(argv) {
117
+ const formatIdx = argv.indexOf("--format");
118
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
119
+ if (argv.includes("--help") || argv.includes("-h")) {
120
+ console.log(`
121
+ judges finding-security-hotspot — Identify security-sensitive code
122
+
123
+ Usage:
124
+ judges finding-security-hotspot <file1> [file2 ...] [--format table|json]
125
+
126
+ Options:
127
+ --format <fmt> Output format: table (default), json
128
+ --help, -h Show this help
129
+ `);
130
+ return;
131
+ }
132
+ const files = argv.filter((a) => !a.startsWith("--") && (argv.indexOf(a) === 0 || argv[argv.indexOf(a) - 1] !== "--format"));
133
+ if (files.length === 0) {
134
+ console.error("Error: provide one or more file paths");
135
+ process.exitCode = 1;
136
+ return;
137
+ }
138
+ const allHotspots = [];
139
+ for (const f of files) {
140
+ if (!existsSync(f)) {
141
+ console.error(`Warning: not found: ${f}`);
142
+ continue;
143
+ }
144
+ try {
145
+ const hs = scanFile(f);
146
+ for (const h of hs) {
147
+ allHotspots.push({ ...h, file: f });
148
+ }
149
+ }
150
+ catch {
151
+ console.error(`Warning: cannot read: ${f}`);
152
+ }
153
+ }
154
+ if (allHotspots.length === 0) {
155
+ console.log("No security hotspots found.");
156
+ return;
157
+ }
158
+ if (format === "json") {
159
+ console.log(JSON.stringify(allHotspots, null, 2));
160
+ return;
161
+ }
162
+ console.log(`\nSecurity Hotspots (${allHotspots.length} found)`);
163
+ console.log("═".repeat(80));
164
+ console.log(`${"File".padEnd(25)} ${"Line".padEnd(7)} ${"Sev".padEnd(10)} ${"Cat".padEnd(12)} Description`);
165
+ console.log("─".repeat(80));
166
+ for (const h of allHotspots.sort((a, b) => {
167
+ const sevOrder = { critical: 0, high: 1, medium: 2, low: 3 };
168
+ return (sevOrder[a.severity] || 3) - (sevOrder[b.severity] || 3);
169
+ })) {
170
+ const name = h.file.length > 23 ? "…" + h.file.slice(-22) : h.file;
171
+ console.log(`${name.padEnd(25)} ${String(h.line).padEnd(7)} ${h.severity.padEnd(10)} ${h.category.padEnd(12)} ${h.description}`);
172
+ console.log(`${" ".repeat(25)} ${"".padEnd(7)} ${"".padEnd(10)} ${"".padEnd(12)} → ${h.recommendation}`);
173
+ }
174
+ console.log("═".repeat(80));
175
+ }
176
+ //# sourceMappingURL=finding-security-hotspot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-security-hotspot.js","sourceRoot":"","sources":["../../src/commands/finding-security-hotspot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-suppression-log — Log and track suppressed findings.
3
+ */
4
+ export declare function runFindingSuppressionLog(argv: string[]): void;
5
+ //# sourceMappingURL=finding-suppression-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-suppression-log.d.ts","sourceRoot":"","sources":["../../src/commands/finding-suppression-log.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8CH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoK7D"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Finding-suppression-log — Log and track suppressed findings.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ // ─── Helpers ────────────────────────────────────────────────────────────────
6
+ const LOG_PATH = ".judges/suppression-log.json";
7
+ function loadLog() {
8
+ if (!existsSync(LOG_PATH)) {
9
+ return { version: 1, entries: [], lastUpdated: new Date().toISOString() };
10
+ }
11
+ try {
12
+ return JSON.parse(readFileSync(LOG_PATH, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: 1, entries: [], lastUpdated: new Date().toISOString() };
16
+ }
17
+ }
18
+ function saveLog(log) {
19
+ const dir = LOG_PATH.substring(0, LOG_PATH.lastIndexOf("/"));
20
+ if (!existsSync(dir))
21
+ mkdirSync(dir, { recursive: true });
22
+ log.lastUpdated = new Date().toISOString();
23
+ writeFileSync(LOG_PATH, JSON.stringify(log, null, 2));
24
+ }
25
+ // ─── CLI ────────────────────────────────────────────────────────────────────
26
+ export function runFindingSuppressionLog(argv) {
27
+ const sub = argv[0];
28
+ if (argv.includes("--help") || argv.includes("-h") || !sub) {
29
+ console.log(`
30
+ judges finding-suppression-log — Log suppressed findings
31
+
32
+ Usage:
33
+ judges finding-suppression-log add --file <verdict.json> --rule <ruleId>
34
+ --reason <text> [--by <name>]
35
+ judges finding-suppression-log show [--format table|json]
36
+ judges finding-suppression-log clear [--rule <ruleId>]
37
+ judges finding-suppression-log stats
38
+
39
+ Subcommands:
40
+ add Suppress a finding from a verdict file
41
+ show Show suppression log
42
+ clear Clear suppressions (all or by rule)
43
+ stats Show suppression statistics
44
+
45
+ Options:
46
+ --file <path> Verdict JSON file (for add)
47
+ --rule <ruleId> Rule ID to suppress/clear
48
+ --reason <text> Reason for suppression
49
+ --by <name> Who suppressed (default: "user")
50
+ --format <fmt> Output format: table (default), json
51
+ --help, -h Show this help
52
+ `);
53
+ return;
54
+ }
55
+ const fileIdx = argv.indexOf("--file");
56
+ const ruleIdx = argv.indexOf("--rule");
57
+ const reasonIdx = argv.indexOf("--reason");
58
+ const byIdx = argv.indexOf("--by");
59
+ const formatIdx = argv.indexOf("--format");
60
+ const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : undefined;
61
+ const ruleId = ruleIdx >= 0 ? argv[ruleIdx + 1] : undefined;
62
+ const reason = reasonIdx >= 0 ? argv[reasonIdx + 1] : "no reason given";
63
+ const by = byIdx >= 0 ? argv[byIdx + 1] : "user";
64
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
65
+ if (sub === "add") {
66
+ if (!filePath) {
67
+ console.error("Error: --file required");
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ if (!ruleId) {
72
+ console.error("Error: --rule required");
73
+ process.exitCode = 1;
74
+ return;
75
+ }
76
+ if (!existsSync(filePath)) {
77
+ console.error(`Error: not found: ${filePath}`);
78
+ process.exitCode = 1;
79
+ return;
80
+ }
81
+ let verdict;
82
+ try {
83
+ verdict = JSON.parse(readFileSync(filePath, "utf-8"));
84
+ }
85
+ catch {
86
+ console.error("Error: invalid JSON");
87
+ process.exitCode = 1;
88
+ return;
89
+ }
90
+ const matching = verdict.findings.filter((f) => f.ruleId === ruleId);
91
+ if (matching.length === 0) {
92
+ console.error(`No findings with rule: ${ruleId}`);
93
+ process.exitCode = 1;
94
+ return;
95
+ }
96
+ const log = loadLog();
97
+ for (const f of matching) {
98
+ log.entries.push({
99
+ ruleId: f.ruleId,
100
+ title: f.title,
101
+ severity: f.severity || "medium",
102
+ suppressedAt: new Date().toISOString(),
103
+ reason,
104
+ suppressedBy: by,
105
+ });
106
+ }
107
+ saveLog(log);
108
+ console.log(`Suppressed ${matching.length} finding(s) for rule ${ruleId}`);
109
+ return;
110
+ }
111
+ if (sub === "show") {
112
+ const log = loadLog();
113
+ if (log.entries.length === 0) {
114
+ console.log("No suppressions logged.");
115
+ return;
116
+ }
117
+ if (format === "json") {
118
+ console.log(JSON.stringify(log, null, 2));
119
+ return;
120
+ }
121
+ console.log(`\nSuppression Log (${log.entries.length} entries)`);
122
+ console.log("═".repeat(70));
123
+ console.log(`${"Rule".padEnd(25)} ${"Severity".padEnd(10)} ${"By".padEnd(10)} Date`);
124
+ console.log("─".repeat(70));
125
+ for (const e of log.entries) {
126
+ console.log(`${e.ruleId.padEnd(25)} ${e.severity.padEnd(10)} ${e.suppressedBy.padEnd(10)} ${e.suppressedAt.slice(0, 10)}`);
127
+ console.log(` Reason: ${e.reason}`);
128
+ }
129
+ console.log("═".repeat(70));
130
+ return;
131
+ }
132
+ if (sub === "clear") {
133
+ const log = loadLog();
134
+ if (ruleId) {
135
+ const before = log.entries.length;
136
+ log.entries = log.entries.filter((e) => e.ruleId !== ruleId);
137
+ saveLog(log);
138
+ console.log(`Cleared ${before - log.entries.length} suppression(s) for ${ruleId}`);
139
+ }
140
+ else {
141
+ log.entries = [];
142
+ saveLog(log);
143
+ console.log("Cleared all suppressions.");
144
+ }
145
+ return;
146
+ }
147
+ if (sub === "stats") {
148
+ const log = loadLog();
149
+ if (log.entries.length === 0) {
150
+ console.log("No suppressions logged.");
151
+ return;
152
+ }
153
+ const byRule = new Map();
154
+ const bySev = new Map();
155
+ for (const e of log.entries) {
156
+ byRule.set(e.ruleId, (byRule.get(e.ruleId) || 0) + 1);
157
+ bySev.set(e.severity, (bySev.get(e.severity) || 0) + 1);
158
+ }
159
+ console.log(`\nSuppression Stats (${log.entries.length} total)`);
160
+ console.log("═".repeat(40));
161
+ console.log("By severity:");
162
+ for (const [sev, count] of bySev) {
163
+ console.log(` ${sev}: ${count}`);
164
+ }
165
+ console.log("\nBy rule:");
166
+ for (const [rule, count] of [...byRule.entries()].sort((a, b) => b[1] - a[1])) {
167
+ console.log(` ${rule}: ${count}`);
168
+ }
169
+ console.log("═".repeat(40));
170
+ return;
171
+ }
172
+ console.error(`Error: unknown subcommand: ${sub}`);
173
+ process.exitCode = 1;
174
+ }
175
+ //# sourceMappingURL=finding-suppression-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-suppression-log.js","sourceRoot":"","sources":["../../src/commands/finding-suppression-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-timeline-view — Show findings on a timeline.
3
+ */
4
+ export declare function runFindingTimelineView(argv: string[]): void;
5
+ //# sourceMappingURL=finding-timeline-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-timeline-view.d.ts","sourceRoot":"","sources":["../../src/commands/finding-timeline-view.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmDH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAyE3D"}