@kevinrabun/judges 3.96.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 (78) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +126 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-annotation-layer.d.ts +5 -0
  6. package/dist/commands/finding-annotation-layer.d.ts.map +1 -0
  7. package/dist/commands/finding-annotation-layer.js +129 -0
  8. package/dist/commands/finding-annotation-layer.js.map +1 -0
  9. package/dist/commands/finding-cwe-lookup.d.ts +5 -0
  10. package/dist/commands/finding-cwe-lookup.d.ts.map +1 -0
  11. package/dist/commands/finding-cwe-lookup.js +149 -0
  12. package/dist/commands/finding-cwe-lookup.js.map +1 -0
  13. package/dist/commands/finding-duplicate-detect.d.ts +5 -0
  14. package/dist/commands/finding-duplicate-detect.d.ts.map +1 -0
  15. package/dist/commands/finding-duplicate-detect.js +114 -0
  16. package/dist/commands/finding-duplicate-detect.js.map +1 -0
  17. package/dist/commands/finding-impact-rank.d.ts +5 -0
  18. package/dist/commands/finding-impact-rank.d.ts.map +1 -0
  19. package/dist/commands/finding-impact-rank.js +86 -0
  20. package/dist/commands/finding-impact-rank.js.map +1 -0
  21. package/dist/commands/finding-patch-preview.d.ts +5 -0
  22. package/dist/commands/finding-patch-preview.d.ts.map +1 -0
  23. package/dist/commands/finding-patch-preview.js +104 -0
  24. package/dist/commands/finding-patch-preview.js.map +1 -0
  25. package/dist/commands/finding-priority-matrix.d.ts +5 -0
  26. package/dist/commands/finding-priority-matrix.d.ts.map +1 -0
  27. package/dist/commands/finding-priority-matrix.js +103 -0
  28. package/dist/commands/finding-priority-matrix.js.map +1 -0
  29. package/dist/commands/finding-risk-score.d.ts +5 -0
  30. package/dist/commands/finding-risk-score.d.ts.map +1 -0
  31. package/dist/commands/finding-risk-score.js +96 -0
  32. package/dist/commands/finding-risk-score.js.map +1 -0
  33. package/dist/commands/finding-trend-forecast.d.ts +5 -0
  34. package/dist/commands/finding-trend-forecast.d.ts.map +1 -0
  35. package/dist/commands/finding-trend-forecast.js +107 -0
  36. package/dist/commands/finding-trend-forecast.js.map +1 -0
  37. package/dist/commands/review-cicd-integrate.d.ts +5 -0
  38. package/dist/commands/review-cicd-integrate.d.ts.map +1 -0
  39. package/dist/commands/review-cicd-integrate.js +123 -0
  40. package/dist/commands/review-cicd-integrate.js.map +1 -0
  41. package/dist/commands/review-compliance-map.d.ts +5 -0
  42. package/dist/commands/review-compliance-map.d.ts.map +1 -0
  43. package/dist/commands/review-compliance-map.js +111 -0
  44. package/dist/commands/review-compliance-map.js.map +1 -0
  45. package/dist/commands/review-gate-config.d.ts +5 -0
  46. package/dist/commands/review-gate-config.d.ts.map +1 -0
  47. package/dist/commands/review-gate-config.js +154 -0
  48. package/dist/commands/review-gate-config.js.map +1 -0
  49. package/dist/commands/review-language-profile.d.ts +5 -0
  50. package/dist/commands/review-language-profile.d.ts.map +1 -0
  51. package/dist/commands/review-language-profile.js +73 -0
  52. package/dist/commands/review-language-profile.js.map +1 -0
  53. package/dist/commands/review-org-dashboard.d.ts +5 -0
  54. package/dist/commands/review-org-dashboard.d.ts.map +1 -0
  55. package/dist/commands/review-org-dashboard.js +69 -0
  56. package/dist/commands/review-org-dashboard.js.map +1 -0
  57. package/dist/commands/review-policy-engine.d.ts +5 -0
  58. package/dist/commands/review-policy-engine.d.ts.map +1 -0
  59. package/dist/commands/review-policy-engine.js +136 -0
  60. package/dist/commands/review-policy-engine.js.map +1 -0
  61. package/dist/commands/review-report-archive.d.ts +5 -0
  62. package/dist/commands/review-report-archive.d.ts.map +1 -0
  63. package/dist/commands/review-report-archive.js +101 -0
  64. package/dist/commands/review-report-archive.js.map +1 -0
  65. package/dist/commands/review-rollout-plan.d.ts +5 -0
  66. package/dist/commands/review-rollout-plan.d.ts.map +1 -0
  67. package/dist/commands/review-rollout-plan.js +124 -0
  68. package/dist/commands/review-rollout-plan.js.map +1 -0
  69. package/dist/commands/review-sla-config.d.ts +5 -0
  70. package/dist/commands/review-sla-config.d.ts.map +1 -0
  71. package/dist/commands/review-sla-config.js +89 -0
  72. package/dist/commands/review-sla-config.js.map +1 -0
  73. package/dist/commands/review-webhook-dispatch.d.ts +5 -0
  74. package/dist/commands/review-webhook-dispatch.d.ts.map +1 -0
  75. package/dist/commands/review-webhook-dispatch.js +100 -0
  76. package/dist/commands/review-webhook-dispatch.js.map +1 -0
  77. package/package.json +1 -1
  78. package/server.json +2 -2
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-annotation-layer — Add contextual annotations to findings.
3
+ */
4
+ export declare function runFindingAnnotationLayer(argv: string[]): void;
5
+ //# sourceMappingURL=finding-annotation-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-annotation-layer.d.ts","sourceRoot":"","sources":["../../src/commands/finding-annotation-layer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAwI9D"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Finding-annotation-layer — Add contextual annotations to findings.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runFindingAnnotationLayer(argv) {
7
+ const storeIdx = argv.indexOf("--store");
8
+ const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-annotations.json";
9
+ const formatIdx = argv.indexOf("--format");
10
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
11
+ if (argv.includes("--help") || argv.includes("-h")) {
12
+ console.log(`
13
+ judges finding-annotation-layer — Add annotations to findings
14
+
15
+ Usage:
16
+ judges finding-annotation-layer [--store <path>]
17
+ [--annotate <ruleId> --note <text> --author <name> --type <type>]
18
+ [--report <path>] [--remove <ruleId>] [--format table|json]
19
+
20
+ Options:
21
+ --store <path> Annotation store (default: .judges-annotations.json)
22
+ --annotate <rule> Add annotation for ruleId
23
+ --note <text> Annotation text
24
+ --author <name> Author name
25
+ --type <type> Type: context, false-positive, accepted-risk, defer
26
+ --report <path> Overlay annotations onto report findings
27
+ --remove <rule> Remove annotations for ruleId
28
+ --format <fmt> Output format: table (default), json
29
+ --help, -h Show this help
30
+ `);
31
+ return;
32
+ }
33
+ let store;
34
+ if (existsSync(storePath)) {
35
+ store = JSON.parse(readFileSync(storePath, "utf-8"));
36
+ }
37
+ else {
38
+ store = { annotations: [], lastUpdated: new Date().toISOString().split("T")[0] };
39
+ }
40
+ // Add annotation
41
+ const annotateIdx = argv.indexOf("--annotate");
42
+ if (annotateIdx >= 0) {
43
+ const ruleId = argv[annotateIdx + 1];
44
+ const noteIdx = argv.indexOf("--note");
45
+ const authorIdx = argv.indexOf("--author");
46
+ const typeIdx = argv.indexOf("--type");
47
+ const annotation = {
48
+ ruleId,
49
+ note: noteIdx >= 0 ? argv[noteIdx + 1] : "",
50
+ author: authorIdx >= 0 ? argv[authorIdx + 1] : "unknown",
51
+ type: (typeIdx >= 0 ? argv[typeIdx + 1] : "context"),
52
+ createdAt: new Date().toISOString().split("T")[0],
53
+ };
54
+ store.annotations.push(annotation);
55
+ store.lastUpdated = new Date().toISOString().split("T")[0];
56
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
57
+ console.log(`Annotation added for: ${ruleId}`);
58
+ return;
59
+ }
60
+ // Remove annotations
61
+ const removeIdx = argv.indexOf("--remove");
62
+ if (removeIdx >= 0) {
63
+ const ruleId = argv[removeIdx + 1];
64
+ const before = store.annotations.length;
65
+ store.annotations = store.annotations.filter((a) => a.ruleId !== ruleId);
66
+ store.lastUpdated = new Date().toISOString().split("T")[0];
67
+ writeFileSync(storePath, JSON.stringify(store, null, 2));
68
+ console.log(`Removed ${before - store.annotations.length} annotation(s) for: ${ruleId}`);
69
+ return;
70
+ }
71
+ // Overlay on report
72
+ const reportIdx = argv.indexOf("--report");
73
+ if (reportIdx >= 0) {
74
+ const reportPath = argv[reportIdx + 1];
75
+ if (!existsSync(reportPath)) {
76
+ console.error(`Report not found: ${reportPath}`);
77
+ process.exitCode = 1;
78
+ return;
79
+ }
80
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
81
+ const findings = report.findings ?? [];
82
+ const annotated = findings.map((f) => {
83
+ const matching = store.annotations.filter((a) => a.ruleId === f.ruleId);
84
+ return {
85
+ ruleId: f.ruleId,
86
+ title: f.title,
87
+ severity: f.severity,
88
+ annotations: matching,
89
+ };
90
+ });
91
+ if (format === "json") {
92
+ console.log(JSON.stringify(annotated, null, 2));
93
+ return;
94
+ }
95
+ console.log(`\nAnnotated Findings`);
96
+ console.log("═".repeat(65));
97
+ for (const af of annotated) {
98
+ console.log(` ${af.ruleId} [${af.severity}] — ${af.title}`);
99
+ if (af.annotations.length > 0) {
100
+ for (const a of af.annotations) {
101
+ console.log(` [${a.type}] ${a.note} (by ${a.author}, ${a.createdAt})`);
102
+ }
103
+ }
104
+ else {
105
+ console.log(" (no annotations)");
106
+ }
107
+ }
108
+ console.log("═".repeat(65));
109
+ return;
110
+ }
111
+ // List all annotations
112
+ if (format === "json") {
113
+ console.log(JSON.stringify(store, null, 2));
114
+ return;
115
+ }
116
+ console.log(`\nFinding Annotations`);
117
+ console.log("═".repeat(65));
118
+ if (store.annotations.length === 0) {
119
+ console.log(" No annotations. Use --annotate <ruleId> to add one.");
120
+ }
121
+ else {
122
+ for (const a of store.annotations) {
123
+ console.log(` ${a.ruleId.padEnd(25)} [${a.type}]`);
124
+ console.log(` ${a.note} — ${a.author} (${a.createdAt})`);
125
+ }
126
+ }
127
+ console.log("═".repeat(65));
128
+ }
129
+ //# sourceMappingURL=finding-annotation-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-annotation-layer.js","sourceRoot":"","sources":["../../src/commands/finding-annotation-layer.ts"],"names":[],"mappings":"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"}
@@ -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-impact-rank — Rank findings by estimated business impact.
3
+ */
4
+ export declare function runFindingImpactRank(argv: string[]): void;
5
+ //# sourceMappingURL=finding-impact-rank.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-impact-rank.d.ts","sourceRoot":"","sources":["../../src/commands/finding-impact-rank.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0BH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsFzD"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Finding-impact-rank — Rank findings by estimated business impact.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Impact model ───────────────────────────────────────────────────────────
6
+ const SEVERITY_IMPACT = {
7
+ critical: 100,
8
+ high: 70,
9
+ medium: 40,
10
+ low: 15,
11
+ info: 5,
12
+ };
13
+ // ─── CLI ────────────────────────────────────────────────────────────────────
14
+ export function runFindingImpactRank(argv) {
15
+ const reportIdx = argv.indexOf("--report");
16
+ const topIdx = argv.indexOf("--top");
17
+ const formatIdx = argv.indexOf("--format");
18
+ const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
19
+ const topN = topIdx >= 0 ? parseInt(argv[topIdx + 1], 10) : 0;
20
+ if (argv.includes("--help") || argv.includes("-h")) {
21
+ console.log(`
22
+ judges finding-impact-rank — Rank findings by business impact
23
+
24
+ Usage:
25
+ judges finding-impact-rank --report <path> [--top <n>] [--format table|json]
26
+
27
+ Options:
28
+ --report <path> Report file with findings
29
+ --top <n> Show only top N findings by impact
30
+ --format <fmt> Output format: table (default), json
31
+ --help, -h Show this help
32
+ `);
33
+ return;
34
+ }
35
+ if (reportIdx < 0) {
36
+ console.error("Missing --report <path>");
37
+ process.exitCode = 1;
38
+ return;
39
+ }
40
+ const reportPath = argv[reportIdx + 1];
41
+ if (!existsSync(reportPath)) {
42
+ console.error(`Report not found: ${reportPath}`);
43
+ process.exitCode = 1;
44
+ return;
45
+ }
46
+ const report = JSON.parse(readFileSync(reportPath, "utf-8"));
47
+ const findings = report.findings ?? [];
48
+ if (findings.length === 0) {
49
+ console.log("No findings to rank.");
50
+ return;
51
+ }
52
+ const ranked = findings.map((f) => {
53
+ const baseImpact = SEVERITY_IMPACT[f.severity] ?? 5;
54
+ const conf = f.confidence ?? 0.5;
55
+ const impactScore = Math.round(baseImpact * conf);
56
+ return {
57
+ rank: 0,
58
+ ruleId: f.ruleId,
59
+ severity: f.severity,
60
+ title: f.title,
61
+ impactScore,
62
+ recommendation: f.recommendation,
63
+ };
64
+ });
65
+ ranked.sort((a, b) => b.impactScore - a.impactScore);
66
+ ranked.forEach((r, i) => {
67
+ r.rank = i + 1;
68
+ });
69
+ const display = topN > 0 ? ranked.slice(0, topN) : ranked;
70
+ if (format === "json") {
71
+ console.log(JSON.stringify(display, null, 2));
72
+ return;
73
+ }
74
+ console.log(`\nFinding Impact Ranking`);
75
+ console.log("═".repeat(75));
76
+ console.log(` ${"#".padEnd(5)} ${"Impact".padEnd(8)} ${"Severity".padEnd(10)} ${"Rule".padEnd(25)} Title`);
77
+ console.log(" " + "─".repeat(70));
78
+ for (const r of display) {
79
+ console.log(` ${String(r.rank).padEnd(5)} ${String(r.impactScore).padEnd(8)} ${r.severity.padEnd(10)} ${r.ruleId.padEnd(25)} ${r.title}`);
80
+ }
81
+ const totalImpact = ranked.reduce((sum, r) => sum + r.impactScore, 0);
82
+ const avgImpact = Math.round(totalImpact / ranked.length);
83
+ console.log(`\n Total impact: ${totalImpact} | Average: ${avgImpact} | Findings: ${ranked.length}`);
84
+ console.log("═".repeat(75));
85
+ }
86
+ //# sourceMappingURL=finding-impact-rank.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-impact-rank.js","sourceRoot":"","sources":["../../src/commands/finding-impact-rank.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"}