@kevinrabun/judges 3.97.0 → 3.98.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-cwe-lookup.d.ts +5 -0
  6. package/dist/commands/finding-cwe-lookup.d.ts.map +1 -0
  7. package/dist/commands/finding-cwe-lookup.js +149 -0
  8. package/dist/commands/finding-cwe-lookup.js.map +1 -0
  9. package/dist/commands/finding-duplicate-detect.d.ts +5 -0
  10. package/dist/commands/finding-duplicate-detect.d.ts.map +1 -0
  11. package/dist/commands/finding-duplicate-detect.js +114 -0
  12. package/dist/commands/finding-duplicate-detect.js.map +1 -0
  13. package/dist/commands/finding-patch-preview.d.ts +5 -0
  14. package/dist/commands/finding-patch-preview.d.ts.map +1 -0
  15. package/dist/commands/finding-patch-preview.js +104 -0
  16. package/dist/commands/finding-patch-preview.js.map +1 -0
  17. package/dist/commands/finding-priority-matrix.d.ts +5 -0
  18. package/dist/commands/finding-priority-matrix.d.ts.map +1 -0
  19. package/dist/commands/finding-priority-matrix.js +103 -0
  20. package/dist/commands/finding-priority-matrix.js.map +1 -0
  21. package/dist/commands/review-cicd-integrate.d.ts +5 -0
  22. package/dist/commands/review-cicd-integrate.d.ts.map +1 -0
  23. package/dist/commands/review-cicd-integrate.js +123 -0
  24. package/dist/commands/review-cicd-integrate.js.map +1 -0
  25. package/dist/commands/review-language-profile.d.ts +5 -0
  26. package/dist/commands/review-language-profile.d.ts.map +1 -0
  27. package/dist/commands/review-language-profile.js +73 -0
  28. package/dist/commands/review-language-profile.js.map +1 -0
  29. package/dist/commands/review-org-dashboard.d.ts +5 -0
  30. package/dist/commands/review-org-dashboard.d.ts.map +1 -0
  31. package/dist/commands/review-org-dashboard.js +69 -0
  32. package/dist/commands/review-org-dashboard.js.map +1 -0
  33. package/dist/commands/review-report-archive.d.ts +5 -0
  34. package/dist/commands/review-report-archive.d.ts.map +1 -0
  35. package/dist/commands/review-report-archive.js +101 -0
  36. package/dist/commands/review-report-archive.js.map +1 -0
  37. package/dist/commands/review-sla-config.d.ts +5 -0
  38. package/dist/commands/review-sla-config.d.ts.map +1 -0
  39. package/dist/commands/review-sla-config.js +89 -0
  40. package/dist/commands/review-sla-config.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-cwe-lookup — Look up CWE details for finding rule IDs.
3
+ */
4
+ export declare function runFindingCweLookup(argv: string[]): void;
5
+ //# sourceMappingURL=finding-cwe-lookup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-cwe-lookup.d.ts","sourceRoot":"","sources":["../../src/commands/finding-cwe-lookup.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8EH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0FxD"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Finding-cwe-lookup — Look up CWE details for finding rule IDs.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CWE database (embedded subset) ────────────────────────────────────────
6
+ const CWE_DB = {
7
+ "sql-injection": {
8
+ id: "CWE-89",
9
+ name: "SQL Injection",
10
+ description: "Improper neutralization of special elements used in an SQL command",
11
+ mitigation: "Use parameterized queries or prepared statements",
12
+ },
13
+ xss: {
14
+ id: "CWE-79",
15
+ name: "Cross-site Scripting",
16
+ description: "Improper neutralization of input during web page generation",
17
+ mitigation: "Sanitize output and use Content Security Policy",
18
+ },
19
+ "path-traversal": {
20
+ id: "CWE-22",
21
+ name: "Path Traversal",
22
+ description: "Improper limitation of a pathname to a restricted directory",
23
+ mitigation: "Validate and canonicalize file paths",
24
+ },
25
+ "command-injection": {
26
+ id: "CWE-78",
27
+ name: "OS Command Injection",
28
+ description: "Improper neutralization of special elements used in an OS command",
29
+ mitigation: "Avoid shell commands; use safe APIs",
30
+ },
31
+ "hardcoded-secret": {
32
+ id: "CWE-798",
33
+ name: "Hardcoded Credentials",
34
+ description: "Use of hard-coded credentials in source code",
35
+ mitigation: "Use environment variables or secret managers",
36
+ },
37
+ "insecure-deserialization": {
38
+ id: "CWE-502",
39
+ name: "Insecure Deserialization",
40
+ description: "Deserialization of untrusted data",
41
+ mitigation: "Validate serialized data or use safe alternatives",
42
+ },
43
+ "broken-auth": {
44
+ id: "CWE-287",
45
+ name: "Improper Authentication",
46
+ description: "Missing or improper authentication mechanism",
47
+ mitigation: "Implement robust authentication with MFA",
48
+ },
49
+ ssrf: {
50
+ id: "CWE-918",
51
+ name: "Server-Side Request Forgery",
52
+ description: "Server-side request to unintended location",
53
+ mitigation: "Validate and restrict outbound requests",
54
+ },
55
+ "open-redirect": {
56
+ id: "CWE-601",
57
+ name: "Open Redirect",
58
+ description: "URL redirection to untrusted site",
59
+ mitigation: "Validate redirect URLs against allowlist",
60
+ },
61
+ xxe: {
62
+ id: "CWE-611",
63
+ name: "XML External Entities",
64
+ description: "Improper restriction of XML external entity reference",
65
+ mitigation: "Disable external entity processing",
66
+ },
67
+ };
68
+ // ─── CLI ────────────────────────────────────────────────────────────────────
69
+ export function runFindingCweLookup(argv) {
70
+ const reportIdx = argv.indexOf("--report");
71
+ const ruleIdx = argv.indexOf("--rule");
72
+ const formatIdx = argv.indexOf("--format");
73
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
74
+ if (argv.includes("--help") || argv.includes("-h")) {
75
+ console.log(`
76
+ judges finding-cwe-lookup — Look up CWE details for findings
77
+
78
+ Usage:
79
+ judges finding-cwe-lookup [--report <path>] [--rule <ruleId>]
80
+ [--format table|json]
81
+
82
+ Options:
83
+ --report <path> Report file to look up CWEs for all findings
84
+ --rule <ruleId> Look up a single rule ID
85
+ --format <fmt> Output format: table (default), json
86
+ --help, -h Show this help
87
+ `);
88
+ return;
89
+ }
90
+ // Single rule lookup
91
+ if (ruleIdx >= 0) {
92
+ const ruleId = argv[ruleIdx + 1];
93
+ const key = ruleId.split("/").pop() ?? ruleId;
94
+ const cwe = CWE_DB[key] ?? null;
95
+ if (format === "json") {
96
+ console.log(JSON.stringify({ ruleId, cwe }, null, 2));
97
+ }
98
+ else if (cwe !== null) {
99
+ console.log(`\n ${cwe.id}: ${cwe.name}`);
100
+ console.log(` ${cwe.description}`);
101
+ console.log(` Mitigation: ${cwe.mitigation}`);
102
+ }
103
+ else {
104
+ console.log(` No CWE mapping found for: ${ruleId}`);
105
+ }
106
+ return;
107
+ }
108
+ // Report lookup
109
+ if (reportIdx < 0) {
110
+ console.error("Supply --report <path> or --rule <ruleId>");
111
+ process.exitCode = 1;
112
+ return;
113
+ }
114
+ const reportPath = argv[reportIdx + 1];
115
+ if (!existsSync(reportPath)) {
116
+ console.error(`Report not found: ${reportPath}`);
117
+ process.exitCode = 1;
118
+ return;
119
+ }
120
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
121
+ const findings = report.findings ?? [];
122
+ const results = findings.map((f) => {
123
+ const key = f.ruleId.split("/").pop() ?? f.ruleId;
124
+ return { ruleId: f.ruleId, title: f.title, cwe: CWE_DB[key] ?? null };
125
+ });
126
+ if (format === "json") {
127
+ console.log(JSON.stringify(results, null, 2));
128
+ return;
129
+ }
130
+ console.log(`\nCWE Lookup`);
131
+ console.log("═".repeat(70));
132
+ const mapped = results.filter((r) => r.cwe !== null);
133
+ const unmapped = results.filter((r) => r.cwe === null);
134
+ if (mapped.length > 0) {
135
+ console.log(" Mapped:");
136
+ for (const r of mapped) {
137
+ console.log(` ${r.ruleId.padEnd(25)} → ${r.cwe.id} (${r.cwe.name})`);
138
+ }
139
+ }
140
+ if (unmapped.length > 0) {
141
+ console.log(" No CWE mapping:");
142
+ for (const r of unmapped) {
143
+ console.log(` ${r.ruleId.padEnd(25)} ${r.title}`);
144
+ }
145
+ }
146
+ console.log(`\n Coverage: ${mapped.length}/${results.length} findings mapped to CWEs`);
147
+ console.log("═".repeat(70));
148
+ }
149
+ //# sourceMappingURL=finding-cwe-lookup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-cwe-lookup.js","sourceRoot":"","sources":["../../src/commands/finding-cwe-lookup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-duplicate-detect — Detect duplicate or near-duplicate findings.
3
+ */
4
+ export declare function runFindingDuplicateDetect(argv: string[]): void;
5
+ //# sourceMappingURL=finding-duplicate-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-duplicate-detect.d.ts","sourceRoot":"","sources":["../../src/commands/finding-duplicate-detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+G9D"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Finding-duplicate-detect — Detect duplicate or near-duplicate findings.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingDuplicateDetect(argv) {
7
+ const reportIdx = argv.indexOf("--report");
8
+ const thresholdIdx = argv.indexOf("--threshold");
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ const threshold = thresholdIdx >= 0 ? parseFloat(argv[thresholdIdx + 1]) : 0.8;
12
+ if (argv.includes("--help") || argv.includes("-h")) {
13
+ console.log(`
14
+ judges finding-duplicate-detect — Detect duplicate findings
15
+
16
+ Usage:
17
+ judges finding-duplicate-detect --report <path> [--threshold <n>]
18
+ [--format table|json]
19
+
20
+ Options:
21
+ --report <path> Report file with findings
22
+ --threshold <n> Similarity threshold 0-1 (default: 0.8)
23
+ --format <fmt> Output format: table (default), json
24
+ --help, -h Show this help
25
+ `);
26
+ return;
27
+ }
28
+ if (reportIdx < 0) {
29
+ console.error("Missing --report <path>");
30
+ process.exitCode = 1;
31
+ return;
32
+ }
33
+ const reportPath = argv[reportIdx + 1];
34
+ if (!existsSync(reportPath)) {
35
+ console.error(`Report not found: ${reportPath}`);
36
+ process.exitCode = 1;
37
+ return;
38
+ }
39
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
40
+ const findings = report.findings ?? [];
41
+ if (findings.length < 2) {
42
+ console.log("Need at least 2 findings to detect duplicates.");
43
+ return;
44
+ }
45
+ // Group by exact ruleId match first
46
+ const ruleGroups = {};
47
+ for (let i = 0; i < findings.length; i++) {
48
+ const key = findings[i].ruleId;
49
+ if (ruleGroups[key] === undefined) {
50
+ ruleGroups[key] = [];
51
+ }
52
+ ruleGroups[key].push(i);
53
+ }
54
+ // Then check title similarity within different rules
55
+ const duplicates = [];
56
+ // Exact rule duplicates
57
+ for (const [ruleId, indices] of Object.entries(ruleGroups)) {
58
+ if (indices.length > 1) {
59
+ duplicates.push({
60
+ representativeRule: ruleId,
61
+ title: findings[indices[0]].title,
62
+ count: indices.length,
63
+ indices,
64
+ });
65
+ }
66
+ }
67
+ // Near-duplicate by title similarity across different rules
68
+ const checked = new Set();
69
+ for (let i = 0; i < findings.length; i++) {
70
+ for (let j = i + 1; j < findings.length; j++) {
71
+ if (findings[i].ruleId === findings[j].ruleId)
72
+ continue;
73
+ const key = `${i}:${j}`;
74
+ if (checked.has(key))
75
+ continue;
76
+ checked.add(key);
77
+ const sim = jaccardSimilarity(findings[i].title, findings[j].title);
78
+ if (sim >= threshold) {
79
+ duplicates.push({
80
+ representativeRule: `${findings[i].ruleId} ~ ${findings[j].ruleId}`,
81
+ title: findings[i].title,
82
+ count: 2,
83
+ indices: [i, j],
84
+ });
85
+ }
86
+ }
87
+ }
88
+ if (format === "json") {
89
+ console.log(JSON.stringify({ threshold, duplicates }, null, 2));
90
+ return;
91
+ }
92
+ console.log(`\nDuplicate Detection (threshold: ${threshold})`);
93
+ console.log("═".repeat(65));
94
+ if (duplicates.length === 0) {
95
+ console.log(" No duplicates detected.");
96
+ }
97
+ else {
98
+ for (const d of duplicates) {
99
+ console.log(` [${d.count}x] ${d.representativeRule}`);
100
+ console.log(` "${d.title}"`);
101
+ console.log(` Indices: ${d.indices.join(", ")}`);
102
+ }
103
+ }
104
+ console.log(`\n Total findings: ${findings.length} | Duplicate groups: ${duplicates.length}`);
105
+ console.log("═".repeat(65));
106
+ }
107
+ function jaccardSimilarity(a, b) {
108
+ const setA = new Set(a.toLowerCase().split(/\s+/));
109
+ const setB = new Set(b.toLowerCase().split(/\s+/));
110
+ const intersection = new Set([...setA].filter((x) => setB.has(x)));
111
+ const union = new Set([...setA, ...setB]);
112
+ return union.size === 0 ? 0 : intersection.size / union.size;
113
+ }
114
+ //# sourceMappingURL=finding-duplicate-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-duplicate-detect.js","sourceRoot":"","sources":["../../src/commands/finding-duplicate-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-patch-preview — Preview how patches would modify source files.
3
+ */
4
+ export declare function runFindingPatchPreview(argv: string[]): void;
5
+ //# sourceMappingURL=finding-patch-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-patch-preview.d.ts","sourceRoot":"","sources":["../../src/commands/finding-patch-preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0H3D"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Finding-patch-preview — Preview how patches would modify source files.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingPatchPreview(argv) {
7
+ const reportIdx = argv.indexOf("--report");
8
+ const sourceIdx = argv.indexOf("--source");
9
+ const contextIdx = argv.indexOf("--context");
10
+ const formatIdx = argv.indexOf("--format");
11
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
12
+ const contextLines = contextIdx >= 0 ? parseInt(argv[contextIdx + 1], 10) : 3;
13
+ if (argv.includes("--help") || argv.includes("-h")) {
14
+ console.log(`
15
+ judges finding-patch-preview — Preview patch modifications
16
+
17
+ Usage:
18
+ judges finding-patch-preview --report <path> --source <path>
19
+ [--context <n>] [--format table|json]
20
+
21
+ Options:
22
+ --report <path> Report file with findings
23
+ --source <path> Source file to preview patches against
24
+ --context <n> Context lines around changes (default: 3)
25
+ --format <fmt> Output format: table (default), json
26
+ --help, -h Show this help
27
+ `);
28
+ return;
29
+ }
30
+ if (reportIdx < 0 || sourceIdx < 0) {
31
+ console.error("Missing --report <path> and --source <path>");
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ const reportPath = argv[reportIdx + 1];
36
+ const sourcePath = argv[sourceIdx + 1];
37
+ if (!existsSync(reportPath)) {
38
+ console.error(`Report not found: ${reportPath}`);
39
+ process.exitCode = 1;
40
+ return;
41
+ }
42
+ if (!existsSync(sourcePath)) {
43
+ console.error(`Source not found: ${sourcePath}`);
44
+ process.exitCode = 1;
45
+ return;
46
+ }
47
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
48
+ const findings = (report.findings ?? []).filter((f) => f.patch !== undefined && f.patch !== null);
49
+ const sourceContent = readFileSync(sourcePath, "utf-8");
50
+ const sourceLines = sourceContent.split("\n");
51
+ if (findings.length === 0) {
52
+ console.log("No findings with patches to preview.");
53
+ return;
54
+ }
55
+ const previews = [];
56
+ for (const f of findings) {
57
+ const patchStr = String(f.patch);
58
+ const patchLines = patchStr.split("\n");
59
+ const firstLine = patchLines[0] ?? "";
60
+ const lineIdx = sourceLines.findIndex((l) => l.includes(firstLine.trim()));
61
+ const applicable = lineIdx >= 0;
62
+ const start = Math.max(0, lineIdx - contextLines);
63
+ const end = Math.min(sourceLines.length - 1, lineIdx + contextLines);
64
+ const affectedLines = [];
65
+ if (applicable) {
66
+ for (let i = start; i <= end; i++) {
67
+ affectedLines.push(i + 1);
68
+ }
69
+ }
70
+ const snippet = applicable
71
+ ? sourceLines
72
+ .slice(start, end + 1)
73
+ .map((l, i) => {
74
+ const lineNum = start + i + 1;
75
+ const marker = lineNum === lineIdx + 1 ? ">" : " ";
76
+ return `${marker} ${String(lineNum).padStart(4)} | ${l}`;
77
+ })
78
+ .join("\n")
79
+ : "(patch target not found in source)";
80
+ previews.push({
81
+ ruleId: f.ruleId,
82
+ title: f.title,
83
+ patchSnippet: snippet,
84
+ applicable,
85
+ affectedLines,
86
+ });
87
+ }
88
+ if (format === "json") {
89
+ console.log(JSON.stringify(previews, null, 2));
90
+ return;
91
+ }
92
+ console.log(`\nPatch Preview — ${sourcePath}`);
93
+ console.log("═".repeat(70));
94
+ for (const p of previews) {
95
+ const status = p.applicable ? "APPLICABLE" : "NOT FOUND";
96
+ console.log(`\n [${status}] ${p.ruleId} — ${p.title}`);
97
+ console.log(" " + "─".repeat(60));
98
+ console.log(p.patchSnippet);
99
+ }
100
+ const applicableCount = previews.filter((p) => p.applicable).length;
101
+ console.log(`\n ${applicableCount}/${previews.length} patches applicable`);
102
+ console.log("═".repeat(70));
103
+ }
104
+ //# sourceMappingURL=finding-patch-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-patch-preview.js","sourceRoot":"","sources":["../../src/commands/finding-patch-preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-priority-matrix — Create a priority matrix (urgency × impact) for findings.
3
+ */
4
+ export declare function runFindingPriorityMatrix(argv: string[]): void;
5
+ //# sourceMappingURL=finding-priority-matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-priority-matrix.d.ts","sourceRoot":"","sources":["../../src/commands/finding-priority-matrix.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmCH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgG7D"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Finding-priority-matrix — Create a priority matrix (urgency × impact) for findings.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Matrix model ───────────────────────────────────────────────────────────
6
+ const URGENCY = {
7
+ critical: 5,
8
+ high: 4,
9
+ medium: 3,
10
+ low: 2,
11
+ info: 1,
12
+ };
13
+ function classifyPriority(score) {
14
+ if (score >= 20)
15
+ return "P0-Immediate";
16
+ if (score >= 12)
17
+ return "P1-High";
18
+ if (score >= 6)
19
+ return "P2-Medium";
20
+ if (score >= 3)
21
+ return "P3-Low";
22
+ return "P4-Backlog";
23
+ }
24
+ // ─── CLI ────────────────────────────────────────────────────────────────────
25
+ export function runFindingPriorityMatrix(argv) {
26
+ const reportIdx = argv.indexOf("--report");
27
+ const priorityIdx = argv.indexOf("--priority");
28
+ const formatIdx = argv.indexOf("--format");
29
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
30
+ const priorityFilter = priorityIdx >= 0 ? argv[priorityIdx + 1] : "";
31
+ if (argv.includes("--help") || argv.includes("-h")) {
32
+ console.log(`
33
+ judges finding-priority-matrix — Create urgency × impact priority matrix
34
+
35
+ Usage:
36
+ judges finding-priority-matrix --report <path> [--priority <level>]
37
+ [--format table|json]
38
+
39
+ Options:
40
+ --report <path> Report file with findings
41
+ --priority <level> Filter: P0-Immediate, P1-High, P2-Medium, P3-Low, P4-Backlog
42
+ --format <fmt> Output format: table (default), json
43
+ --help, -h Show this help
44
+ `);
45
+ return;
46
+ }
47
+ if (reportIdx < 0) {
48
+ console.error("Missing --report <path>");
49
+ process.exitCode = 1;
50
+ return;
51
+ }
52
+ const reportPath = argv[reportIdx + 1];
53
+ if (!existsSync(reportPath)) {
54
+ console.error(`Report not found: ${reportPath}`);
55
+ process.exitCode = 1;
56
+ return;
57
+ }
58
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
59
+ const findings = report.findings ?? [];
60
+ if (findings.length === 0) {
61
+ console.log("No findings to prioritize.");
62
+ return;
63
+ }
64
+ const entries = findings.map((f) => {
65
+ const urgency = URGENCY[f.severity] ?? 1;
66
+ const conf = f.confidence ?? 0.5;
67
+ const impact = Math.round(urgency * conf * 2);
68
+ const score = urgency * impact;
69
+ return {
70
+ ruleId: f.ruleId,
71
+ title: f.title,
72
+ severity: f.severity,
73
+ urgency,
74
+ impact,
75
+ priority: classifyPriority(score),
76
+ score,
77
+ };
78
+ });
79
+ entries.sort((a, b) => b.score - a.score);
80
+ const display = priorityFilter.length > 0 ? entries.filter((e) => e.priority === priorityFilter) : entries;
81
+ if (format === "json") {
82
+ console.log(JSON.stringify(display, null, 2));
83
+ return;
84
+ }
85
+ console.log(`\nPriority Matrix`);
86
+ console.log("═".repeat(80));
87
+ console.log(` ${"Priority".padEnd(15)} ${"Score".padEnd(7)} ${"Urgency".padEnd(9)} ${"Impact".padEnd(8)} ${"Rule".padEnd(22)} Title`);
88
+ console.log(" " + "─".repeat(75));
89
+ for (const e of display) {
90
+ console.log(` ${e.priority.padEnd(15)} ${String(e.score).padEnd(7)} ${String(e.urgency).padEnd(9)} ${String(e.impact).padEnd(8)} ${e.ruleId.padEnd(22)} ${e.title}`);
91
+ }
92
+ // Summary counts
93
+ const counts = {};
94
+ for (const e of entries) {
95
+ counts[e.priority] = (counts[e.priority] ?? 0) + 1;
96
+ }
97
+ console.log(`\n Summary:`);
98
+ for (const [p, c] of Object.entries(counts).sort()) {
99
+ console.log(` ${p.padEnd(15)} ${c} finding(s)`);
100
+ }
101
+ console.log("═".repeat(80));
102
+ }
103
+ //# sourceMappingURL=finding-priority-matrix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-priority-matrix.js","sourceRoot":"","sources":["../../src/commands/finding-priority-matrix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-cicd-integrate — Generate CI/CD integration configs for Judges.
3
+ */
4
+ export declare function runReviewCicdIntegrate(argv: string[]): void;
5
+ //# sourceMappingURL=review-cicd-integrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-cicd-integrate.d.ts","sourceRoot":"","sources":["../../src/commands/review-cicd-integrate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiEH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiE3D"}