@kevinrabun/judges 3.82.0 → 3.84.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.
- package/CHANGELOG.md +26 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +126 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/finding-category-stats.d.ts +5 -0
- package/dist/commands/finding-category-stats.d.ts.map +1 -0
- package/dist/commands/finding-category-stats.js +105 -0
- package/dist/commands/finding-category-stats.js.map +1 -0
- package/dist/commands/finding-cluster-analysis.d.ts +5 -0
- package/dist/commands/finding-cluster-analysis.d.ts.map +1 -0
- package/dist/commands/finding-cluster-analysis.js +134 -0
- package/dist/commands/finding-cluster-analysis.js.map +1 -0
- package/dist/commands/finding-compare-runs.d.ts +5 -0
- package/dist/commands/finding-compare-runs.d.ts.map +1 -0
- package/dist/commands/finding-compare-runs.js +106 -0
- package/dist/commands/finding-compare-runs.js.map +1 -0
- package/dist/commands/finding-evidence-chain.d.ts +5 -0
- package/dist/commands/finding-evidence-chain.d.ts.map +1 -0
- package/dist/commands/finding-evidence-chain.js +148 -0
- package/dist/commands/finding-evidence-chain.js.map +1 -0
- package/dist/commands/finding-fix-priority.d.ts +5 -0
- package/dist/commands/finding-fix-priority.d.ts.map +1 -0
- package/dist/commands/finding-fix-priority.js +99 -0
- package/dist/commands/finding-fix-priority.js.map +1 -0
- package/dist/commands/finding-hotfix-suggest.d.ts +8 -0
- package/dist/commands/finding-hotfix-suggest.d.ts.map +1 -0
- package/dist/commands/finding-hotfix-suggest.js +171 -0
- package/dist/commands/finding-hotfix-suggest.js.map +1 -0
- package/dist/commands/finding-noise-filter.d.ts +8 -0
- package/dist/commands/finding-noise-filter.d.ts.map +1 -0
- package/dist/commands/finding-noise-filter.js +141 -0
- package/dist/commands/finding-noise-filter.js.map +1 -0
- package/dist/commands/finding-trend-report.d.ts +5 -0
- package/dist/commands/finding-trend-report.d.ts.map +1 -0
- package/dist/commands/finding-trend-report.js +108 -0
- package/dist/commands/finding-trend-report.js.map +1 -0
- package/dist/commands/review-approval-gate.d.ts +8 -0
- package/dist/commands/review-approval-gate.d.ts.map +1 -0
- package/dist/commands/review-approval-gate.js +191 -0
- package/dist/commands/review-approval-gate.js.map +1 -0
- package/dist/commands/review-branch-compare.d.ts +5 -0
- package/dist/commands/review-branch-compare.d.ts.map +1 -0
- package/dist/commands/review-branch-compare.js +114 -0
- package/dist/commands/review-branch-compare.js.map +1 -0
- package/dist/commands/review-changelog-entry.d.ts +8 -0
- package/dist/commands/review-changelog-entry.d.ts.map +1 -0
- package/dist/commands/review-changelog-entry.js +110 -0
- package/dist/commands/review-changelog-entry.js.map +1 -0
- package/dist/commands/review-commit-hook.d.ts +8 -0
- package/dist/commands/review-commit-hook.d.ts.map +1 -0
- package/dist/commands/review-commit-hook.js +135 -0
- package/dist/commands/review-commit-hook.js.map +1 -0
- package/dist/commands/review-file-complexity.d.ts +5 -0
- package/dist/commands/review-file-complexity.d.ts.map +1 -0
- package/dist/commands/review-file-complexity.js +138 -0
- package/dist/commands/review-file-complexity.js.map +1 -0
- package/dist/commands/review-finding-link.d.ts +8 -0
- package/dist/commands/review-finding-link.d.ts.map +1 -0
- package/dist/commands/review-finding-link.js +116 -0
- package/dist/commands/review-finding-link.js.map +1 -0
- package/dist/commands/review-quota-check.d.ts +5 -0
- package/dist/commands/review-quota-check.d.ts.map +1 -0
- package/dist/commands/review-quota-check.js +98 -0
- package/dist/commands/review-quota-check.js.map +1 -0
- package/dist/commands/review-session-save.d.ts +5 -0
- package/dist/commands/review-session-save.d.ts.map +1 -0
- package/dist/commands/review-session-save.js +174 -0
- package/dist/commands/review-session-save.js.map +1 -0
- package/dist/commands/review-skip-list.d.ts +5 -0
- package/dist/commands/review-skip-list.d.ts.map +1 -0
- package/dist/commands/review-skip-list.js +136 -0
- package/dist/commands/review-skip-list.js.map +1 -0
- package/dist/commands/review-team-assign.d.ts +8 -0
- package/dist/commands/review-team-assign.d.ts.map +1 -0
- package/dist/commands/review-team-assign.js +212 -0
- package/dist/commands/review-team-assign.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-fix-priority — Prioritize findings for fixing based on impact.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
6
|
+
const SEV_WEIGHT = { critical: 10, high: 7, medium: 4, low: 2, info: 1 };
|
|
7
|
+
function prioritize(verdict) {
|
|
8
|
+
return verdict.findings
|
|
9
|
+
.map((f) => {
|
|
10
|
+
const sev = (f.severity || "medium").toLowerCase();
|
|
11
|
+
const conf = f.confidence !== undefined && f.confidence !== null ? f.confidence : 0.7;
|
|
12
|
+
const sevScore = SEV_WEIGHT[sev] || 4;
|
|
13
|
+
const hasFix = f.recommendation ? 1.2 : 1.0;
|
|
14
|
+
const priorityScore = Math.round(sevScore * conf * hasFix * 100) / 100;
|
|
15
|
+
const reasons = [];
|
|
16
|
+
if (sev === "critical" || sev === "high")
|
|
17
|
+
reasons.push("high severity");
|
|
18
|
+
if (conf >= 0.8)
|
|
19
|
+
reasons.push("high confidence");
|
|
20
|
+
if (f.recommendation)
|
|
21
|
+
reasons.push("has fix recommendation");
|
|
22
|
+
if (f.patch)
|
|
23
|
+
reasons.push("has patch available");
|
|
24
|
+
return {
|
|
25
|
+
rank: 0,
|
|
26
|
+
ruleId: f.ruleId,
|
|
27
|
+
title: f.title,
|
|
28
|
+
severity: sev,
|
|
29
|
+
confidence: conf,
|
|
30
|
+
priorityScore,
|
|
31
|
+
reason: reasons.join(", ") || "standard priority",
|
|
32
|
+
};
|
|
33
|
+
})
|
|
34
|
+
.sort((a, b) => b.priorityScore - a.priorityScore)
|
|
35
|
+
.map((f, i) => ({ ...f, rank: i + 1 }));
|
|
36
|
+
}
|
|
37
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
38
|
+
export function runFindingFixPriority(argv) {
|
|
39
|
+
const fileIdx = argv.indexOf("--file");
|
|
40
|
+
const formatIdx = argv.indexOf("--format");
|
|
41
|
+
const topIdx = argv.indexOf("--top");
|
|
42
|
+
const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : undefined;
|
|
43
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
44
|
+
const top = topIdx >= 0 ? parseInt(argv[topIdx + 1], 10) : 0;
|
|
45
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
46
|
+
console.log(`
|
|
47
|
+
judges finding-fix-priority — Prioritize findings for fixing
|
|
48
|
+
|
|
49
|
+
Usage:
|
|
50
|
+
judges finding-fix-priority --file <verdict.json> [--format table|json]
|
|
51
|
+
[--top <n>]
|
|
52
|
+
|
|
53
|
+
Options:
|
|
54
|
+
--file <path> Path to verdict JSON file (required)
|
|
55
|
+
--format <fmt> Output format: table (default), json
|
|
56
|
+
--top <n> Show only top N findings
|
|
57
|
+
--help, -h Show this help
|
|
58
|
+
`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (!filePath) {
|
|
62
|
+
console.error("Error: --file required");
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!existsSync(filePath)) {
|
|
67
|
+
console.error(`Error: not found: ${filePath}`);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let verdict;
|
|
72
|
+
try {
|
|
73
|
+
verdict = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
console.error("Error: invalid JSON");
|
|
77
|
+
process.exitCode = 1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
let results = prioritize(verdict);
|
|
81
|
+
if (top > 0)
|
|
82
|
+
results = results.slice(0, top);
|
|
83
|
+
if (format === "json") {
|
|
84
|
+
console.log(JSON.stringify(results, null, 2));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(`\nFix Priority (${results.length} findings)`);
|
|
88
|
+
console.log("═".repeat(70));
|
|
89
|
+
console.log(`${"#".padEnd(4)} ${"Score".padEnd(8)} ${"Severity".padEnd(10)} Title`);
|
|
90
|
+
console.log("─".repeat(70));
|
|
91
|
+
for (const r of results) {
|
|
92
|
+
const title = r.title.length > 38 ? r.title.slice(0, 38) + "…" : r.title;
|
|
93
|
+
console.log(`${String(r.rank).padEnd(4)} ${String(r.priorityScore).padEnd(8)} ${r.severity.padEnd(10)} ${title}`);
|
|
94
|
+
if (r.reason)
|
|
95
|
+
console.log(` ${r.reason}`);
|
|
96
|
+
}
|
|
97
|
+
console.log("═".repeat(70));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=finding-fix-priority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-fix-priority.js","sourceRoot":"","sources":["../../src/commands/finding-fix-priority.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-hotfix-suggest — Suggest quick hotfixes for common findings.
|
|
3
|
+
*
|
|
4
|
+
* Provides targeted one-liner or small code snippets to address
|
|
5
|
+
* frequently-encountered security and quality issues.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runFindingHotfixSuggest(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=finding-hotfix-suggest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-hotfix-suggest.d.ts","sourceRoot":"","sources":["../../src/commands/finding-hotfix-suggest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiHH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4E5D"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-hotfix-suggest — Suggest quick hotfixes for common findings.
|
|
3
|
+
*
|
|
4
|
+
* Provides targeted one-liner or small code snippets to address
|
|
5
|
+
* frequently-encountered security and quality issues.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync } from "fs";
|
|
8
|
+
// ─── Hotfix Database ────────────────────────────────────────────────────────
|
|
9
|
+
const HOTFIX_PATTERNS = [
|
|
10
|
+
{
|
|
11
|
+
keywords: ["sql injection", "sql"],
|
|
12
|
+
category: "injection",
|
|
13
|
+
hotfix: "Use parameterized queries instead of string concatenation",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
keywords: ["xss", "cross-site scripting", "innerhtml"],
|
|
17
|
+
category: "xss",
|
|
18
|
+
hotfix: "Sanitize user input with DOMPurify or use textContent instead of innerHTML",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
keywords: ["eval", "code injection"],
|
|
22
|
+
category: "injection",
|
|
23
|
+
hotfix: "Replace eval() with JSON.parse() or a safe alternative",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
keywords: ["hardcoded", "password", "secret", "api key"],
|
|
27
|
+
category: "secrets",
|
|
28
|
+
hotfix: "Move secrets to environment variables or a secrets manager",
|
|
29
|
+
},
|
|
30
|
+
{ keywords: ["csrf", "cross-site request"], category: "csrf", hotfix: "Add CSRF token validation middleware" },
|
|
31
|
+
{
|
|
32
|
+
keywords: ["cors", "permissive"],
|
|
33
|
+
category: "cors",
|
|
34
|
+
hotfix: "Configure CORS with specific allowed origins instead of wildcard",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
keywords: ["md5", "sha1", "weak hash", "weak crypto"],
|
|
38
|
+
category: "crypto",
|
|
39
|
+
hotfix: "Use SHA-256 or bcrypt for password hashing",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
keywords: ["math.random", "insecure random"],
|
|
43
|
+
category: "crypto",
|
|
44
|
+
hotfix: "Use crypto.randomBytes() or crypto.getRandomValues() instead",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
keywords: ["path traversal", "directory traversal"],
|
|
48
|
+
category: "path",
|
|
49
|
+
hotfix: "Validate and sanitize file paths; use path.resolve() and check against base directory",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
keywords: ["command injection", "exec", "child_process"],
|
|
53
|
+
category: "injection",
|
|
54
|
+
hotfix: "Use execFile() with argument arrays instead of exec() with string interpolation",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
keywords: ["missing auth", "authentication", "unauthorized"],
|
|
58
|
+
category: "auth",
|
|
59
|
+
hotfix: "Add authentication middleware to protect the endpoint",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
keywords: ["missing rate limit", "rate limit"],
|
|
63
|
+
category: "availability",
|
|
64
|
+
hotfix: "Add express-rate-limit or similar middleware",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
keywords: ["information disclosure", "stack trace", "verbose error"],
|
|
68
|
+
category: "info-disclosure",
|
|
69
|
+
hotfix: "Use generic error messages in production; log details server-side only",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
keywords: ["insecure cookie", "cookie"],
|
|
73
|
+
category: "session",
|
|
74
|
+
hotfix: "Set cookie flags: httpOnly, secure, sameSite='strict'",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
keywords: ["tls", "ssl", "certificate", "rejectunauthorized"],
|
|
78
|
+
category: "transport",
|
|
79
|
+
hotfix: "Never disable TLS certificate verification in production",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
keywords: ["unused", "dead code"],
|
|
83
|
+
category: "quality",
|
|
84
|
+
hotfix: "Remove unused code to reduce attack surface and maintenance burden",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
keywords: ["logging sensitive", "log password"],
|
|
88
|
+
category: "logging",
|
|
89
|
+
hotfix: "Remove sensitive data from log statements; use structured logging with redaction",
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
function findHotfix(title, description) {
|
|
93
|
+
const combined = `${title} ${description}`.toLowerCase();
|
|
94
|
+
for (const p of HOTFIX_PATTERNS) {
|
|
95
|
+
if (p.keywords.some((kw) => combined.includes(kw))) {
|
|
96
|
+
return { category: p.category, hotfix: p.hotfix };
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
102
|
+
export function runFindingHotfixSuggest(argv) {
|
|
103
|
+
const fileIdx = argv.indexOf("--file");
|
|
104
|
+
const formatIdx = argv.indexOf("--format");
|
|
105
|
+
const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : undefined;
|
|
106
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
107
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
108
|
+
console.log(`
|
|
109
|
+
judges finding-hotfix-suggest — Suggest quick hotfixes for findings
|
|
110
|
+
|
|
111
|
+
Usage:
|
|
112
|
+
judges finding-hotfix-suggest --file <verdict.json> [--format table|json]
|
|
113
|
+
|
|
114
|
+
Options:
|
|
115
|
+
--file <path> Path to verdict JSON file (required)
|
|
116
|
+
--format <fmt> Output format: table (default), json
|
|
117
|
+
--help, -h Show this help
|
|
118
|
+
`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!filePath) {
|
|
122
|
+
console.error("Error: --file required");
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (!existsSync(filePath)) {
|
|
127
|
+
console.error(`Error: not found: ${filePath}`);
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
let verdict;
|
|
132
|
+
try {
|
|
133
|
+
verdict = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
console.error("Error: invalid JSON");
|
|
137
|
+
process.exitCode = 1;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const suggestions = [];
|
|
141
|
+
for (const f of verdict.findings) {
|
|
142
|
+
const hotfix = findHotfix(f.title, f.description);
|
|
143
|
+
if (hotfix) {
|
|
144
|
+
suggestions.push({
|
|
145
|
+
ruleId: f.ruleId,
|
|
146
|
+
title: f.title,
|
|
147
|
+
severity: f.severity || "medium",
|
|
148
|
+
hotfix: hotfix.hotfix,
|
|
149
|
+
category: hotfix.category,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (format === "json") {
|
|
154
|
+
console.log(JSON.stringify(suggestions, null, 2));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (suggestions.length === 0) {
|
|
158
|
+
console.log("No hotfix suggestions available for current findings.");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
console.log(`\nHotfix Suggestions (${suggestions.length})`);
|
|
162
|
+
console.log("═".repeat(70));
|
|
163
|
+
for (const s of suggestions) {
|
|
164
|
+
console.log(`\n [${s.severity.toUpperCase()}] ${s.title}`);
|
|
165
|
+
console.log(` Category: ${s.category}`);
|
|
166
|
+
console.log(` Hotfix: ${s.hotfix}`);
|
|
167
|
+
}
|
|
168
|
+
console.log("\n" + "═".repeat(70));
|
|
169
|
+
console.log(`${suggestions.length} of ${verdict.findings.length} findings have suggested hotfixes`);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=finding-hotfix-suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-hotfix-suggest.js","sourceRoot":"","sources":["../../src/commands/finding-hotfix-suggest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-noise-filter — Filter out noisy/low-value findings.
|
|
3
|
+
*
|
|
4
|
+
* Identifies and filters findings that are likely noise based on
|
|
5
|
+
* configurable heuristics: low confidence, common FP patterns, etc.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runFindingNoiseFilter(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=finding-noise-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-noise-filter.d.ts","sourceRoot":"","sources":["../../src/commands/finding-noise-filter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiFH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4F1D"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-noise-filter — Filter out noisy/low-value findings.
|
|
3
|
+
*
|
|
4
|
+
* Identifies and filters findings that are likely noise based on
|
|
5
|
+
* configurable heuristics: low confidence, common FP patterns, etc.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync } from "fs";
|
|
8
|
+
// ─── Noise Detection ────────────────────────────────────────────────────────
|
|
9
|
+
const NOISE_PATTERNS = [
|
|
10
|
+
{
|
|
11
|
+
test: (f) => f.confidence !== undefined && f.confidence !== null && f.confidence < 0.3,
|
|
12
|
+
reason: "low confidence (<30%)",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
test: (f) => f.title.toLowerCase().includes("todo") || f.title.toLowerCase().includes("fixme"),
|
|
16
|
+
reason: "TODO/FIXME noise",
|
|
17
|
+
},
|
|
18
|
+
{ test: (f) => (f.severity || "medium").toLowerCase() === "info", reason: "informational only" },
|
|
19
|
+
{ test: (f) => f.isAbsenceBased === true, reason: "absence-based finding" },
|
|
20
|
+
{ test: (f) => f.description.length < 20, reason: "minimal description" },
|
|
21
|
+
];
|
|
22
|
+
function filterNoise(findings, minConfidence, excludeInfo, excludeAbsence) {
|
|
23
|
+
const kept = [];
|
|
24
|
+
const filtered = [];
|
|
25
|
+
const reasons = new Map();
|
|
26
|
+
for (const f of findings) {
|
|
27
|
+
let isNoise = false;
|
|
28
|
+
let reason = "";
|
|
29
|
+
if (minConfidence > 0 && f.confidence !== undefined && f.confidence !== null && f.confidence < minConfidence) {
|
|
30
|
+
isNoise = true;
|
|
31
|
+
reason = `confidence ${(f.confidence * 100).toFixed(0)}% < ${(minConfidence * 100).toFixed(0)}%`;
|
|
32
|
+
}
|
|
33
|
+
if (!isNoise && excludeInfo && (f.severity || "medium").toLowerCase() === "info") {
|
|
34
|
+
isNoise = true;
|
|
35
|
+
reason = "informational severity excluded";
|
|
36
|
+
}
|
|
37
|
+
if (!isNoise && excludeAbsence && f.isAbsenceBased) {
|
|
38
|
+
isNoise = true;
|
|
39
|
+
reason = "absence-based finding excluded";
|
|
40
|
+
}
|
|
41
|
+
if (!isNoise) {
|
|
42
|
+
for (const p of NOISE_PATTERNS) {
|
|
43
|
+
if (p.test(f)) {
|
|
44
|
+
isNoise = true;
|
|
45
|
+
reason = p.reason;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (isNoise) {
|
|
51
|
+
filtered.push(f);
|
|
52
|
+
reasons.set(`${f.ruleId}:${f.title}`, reason);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
kept.push(f);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { kept, filtered, reasons };
|
|
59
|
+
}
|
|
60
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
61
|
+
export function runFindingNoiseFilter(argv) {
|
|
62
|
+
const fileIdx = argv.indexOf("--file");
|
|
63
|
+
const formatIdx = argv.indexOf("--format");
|
|
64
|
+
const confIdx = argv.indexOf("--min-confidence");
|
|
65
|
+
const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : undefined;
|
|
66
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
67
|
+
const minConfidence = confIdx >= 0 ? parseFloat(argv[confIdx + 1]) : 0.3;
|
|
68
|
+
const excludeInfo = argv.includes("--exclude-info");
|
|
69
|
+
const excludeAbsence = argv.includes("--exclude-absence");
|
|
70
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
71
|
+
console.log(`
|
|
72
|
+
judges finding-noise-filter — Filter noisy findings
|
|
73
|
+
|
|
74
|
+
Usage:
|
|
75
|
+
judges finding-noise-filter --file <verdict.json> [options]
|
|
76
|
+
|
|
77
|
+
Options:
|
|
78
|
+
--file <path> Path to verdict JSON file (required)
|
|
79
|
+
--min-confidence <n> Minimum confidence threshold (default: 0.3)
|
|
80
|
+
--exclude-info Exclude informational findings
|
|
81
|
+
--exclude-absence Exclude absence-based findings
|
|
82
|
+
--format <fmt> Output format: table (default), json
|
|
83
|
+
--help, -h Show this help
|
|
84
|
+
`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!filePath) {
|
|
88
|
+
console.error("Error: --file required");
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (!existsSync(filePath)) {
|
|
93
|
+
console.error(`Error: not found: ${filePath}`);
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
let verdict;
|
|
98
|
+
try {
|
|
99
|
+
verdict = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
console.error("Error: invalid JSON");
|
|
103
|
+
process.exitCode = 1;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const result = filterNoise(verdict.findings, minConfidence, excludeInfo, excludeAbsence);
|
|
107
|
+
if (format === "json") {
|
|
108
|
+
console.log(JSON.stringify({
|
|
109
|
+
kept: result.kept.length,
|
|
110
|
+
filtered: result.filtered.length,
|
|
111
|
+
keptFindings: result.kept.map((f) => ({ ruleId: f.ruleId, title: f.title, severity: f.severity })),
|
|
112
|
+
filteredFindings: result.filtered.map((f) => ({
|
|
113
|
+
ruleId: f.ruleId,
|
|
114
|
+
title: f.title,
|
|
115
|
+
reason: result.reasons.get(`${f.ruleId}:${f.title}`),
|
|
116
|
+
})),
|
|
117
|
+
}, null, 2));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
console.log(`\nNoise Filter Results`);
|
|
121
|
+
console.log("═".repeat(60));
|
|
122
|
+
console.log(`Total: ${verdict.findings.length} | Kept: ${result.kept.length} | Filtered: ${result.filtered.length}`);
|
|
123
|
+
console.log("─".repeat(60));
|
|
124
|
+
if (result.filtered.length > 0) {
|
|
125
|
+
console.log("\nFiltered (noise):");
|
|
126
|
+
for (const f of result.filtered) {
|
|
127
|
+
const reason = result.reasons.get(`${f.ruleId}:${f.title}`) || "unknown";
|
|
128
|
+
console.log(` ✕ ${f.title} — ${reason}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (result.kept.length > 0) {
|
|
132
|
+
console.log(`\nKept (${result.kept.length} findings):`);
|
|
133
|
+
for (const f of result.kept.slice(0, 10)) {
|
|
134
|
+
console.log(` ✓ [${(f.severity || "medium").toUpperCase()}] ${f.title}`);
|
|
135
|
+
}
|
|
136
|
+
if (result.kept.length > 10)
|
|
137
|
+
console.log(` ... and ${result.kept.length - 10} more`);
|
|
138
|
+
}
|
|
139
|
+
console.log("═".repeat(60));
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=finding-noise-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-noise-filter.js","sourceRoot":"","sources":["../../src/commands/finding-noise-filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-trend-report.d.ts","sourceRoot":"","sources":["../../src/commands/finding-trend-report.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmDH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+E1D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-trend-report — Generate trend reports from historical findings.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync, readdirSync } from "fs";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
7
|
+
function loadVerdictHistory(dir) {
|
|
8
|
+
if (!existsSync(dir))
|
|
9
|
+
return [];
|
|
10
|
+
const results = [];
|
|
11
|
+
const files = readdirSync(dir);
|
|
12
|
+
for (const f of files) {
|
|
13
|
+
if (!String(f).endsWith(".json"))
|
|
14
|
+
continue;
|
|
15
|
+
try {
|
|
16
|
+
const data = JSON.parse(readFileSync(join(dir, String(f)), "utf-8"));
|
|
17
|
+
if (data && data.findings) {
|
|
18
|
+
const date = data.timestamp || String(f).replace(".json", "");
|
|
19
|
+
results.push({ date, verdict: data });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
/* skip */
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return results.sort((a, b) => a.date.localeCompare(b.date));
|
|
27
|
+
}
|
|
28
|
+
function buildTrend(history) {
|
|
29
|
+
return history.map((h) => ({
|
|
30
|
+
date: h.date,
|
|
31
|
+
totalFindings: h.verdict.findings.length,
|
|
32
|
+
criticalCount: h.verdict.criticalCount,
|
|
33
|
+
highCount: h.verdict.highCount,
|
|
34
|
+
score: h.verdict.overallScore,
|
|
35
|
+
ruleCount: new Set(h.verdict.findings.map((f) => f.ruleId)).size,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
39
|
+
export function runFindingTrendReport(argv) {
|
|
40
|
+
const dirIdx = argv.indexOf("--dir");
|
|
41
|
+
const formatIdx = argv.indexOf("--format");
|
|
42
|
+
const lastIdx = argv.indexOf("--last");
|
|
43
|
+
const dir = dirIdx >= 0 ? argv[dirIdx + 1] : join(process.cwd(), ".judges", "verdicts");
|
|
44
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
45
|
+
const last = lastIdx >= 0 ? parseInt(argv[lastIdx + 1], 10) : 0;
|
|
46
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
47
|
+
console.log(`
|
|
48
|
+
judges finding-trend-report — Generate trend reports
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
judges finding-trend-report [--dir <path>] [--format table|json|chart]
|
|
52
|
+
[--last <n>]
|
|
53
|
+
|
|
54
|
+
Options:
|
|
55
|
+
--dir <path> Directory with historical verdict files
|
|
56
|
+
--format <fmt> Output format: table (default), json, chart
|
|
57
|
+
--last <n> Show only last N data points
|
|
58
|
+
--help, -h Show this help
|
|
59
|
+
`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const history = loadVerdictHistory(dir);
|
|
63
|
+
if (history.length === 0) {
|
|
64
|
+
console.log("No verdict history found.");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let trend = buildTrend(history);
|
|
68
|
+
if (last > 0)
|
|
69
|
+
trend = trend.slice(-last);
|
|
70
|
+
if (format === "json") {
|
|
71
|
+
console.log(JSON.stringify(trend, null, 2));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (format === "chart") {
|
|
75
|
+
console.log("\nFinding Trend (ASCII Chart)");
|
|
76
|
+
console.log("═".repeat(60));
|
|
77
|
+
const maxFindings = Math.max(...trend.map((t) => t.totalFindings), 1);
|
|
78
|
+
for (const t of trend) {
|
|
79
|
+
const barLen = Math.round((t.totalFindings / maxFindings) * 40);
|
|
80
|
+
const bar = "█".repeat(barLen);
|
|
81
|
+
const dateStr = t.date.slice(0, 10).padEnd(12);
|
|
82
|
+
console.log(`${dateStr} ${bar} ${t.totalFindings}`);
|
|
83
|
+
}
|
|
84
|
+
console.log("═".repeat(60));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
console.log(`\nFinding Trend Report (${trend.length} data points)`);
|
|
88
|
+
console.log("═".repeat(70));
|
|
89
|
+
console.log(`${"Date".padEnd(22)} ${"Findings".padEnd(10)} ${"Crit".padEnd(6)} ${"High".padEnd(6)} ${"Score".padEnd(7)} Rules`);
|
|
90
|
+
console.log("─".repeat(70));
|
|
91
|
+
for (const t of trend) {
|
|
92
|
+
const dateStr = t.date.slice(0, 19).padEnd(22);
|
|
93
|
+
console.log(`${dateStr} ${String(t.totalFindings).padEnd(10)} ${String(t.criticalCount).padEnd(6)} ` +
|
|
94
|
+
`${String(t.highCount).padEnd(6)} ${String(t.score).padEnd(7)} ${t.ruleCount}`);
|
|
95
|
+
}
|
|
96
|
+
if (trend.length >= 2) {
|
|
97
|
+
const first = trend[0];
|
|
98
|
+
const latest = trend[trend.length - 1];
|
|
99
|
+
const findingDelta = latest.totalFindings - first.totalFindings;
|
|
100
|
+
const scoreDelta = latest.score - first.score;
|
|
101
|
+
console.log("─".repeat(70));
|
|
102
|
+
const fd = findingDelta >= 0 ? `+${findingDelta}` : `${findingDelta}`;
|
|
103
|
+
const sd = scoreDelta >= 0 ? `+${scoreDelta}` : `${scoreDelta}`;
|
|
104
|
+
console.log(`Trend: findings ${fd}, score ${sd}`);
|
|
105
|
+
}
|
|
106
|
+
console.log("═".repeat(70));
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=finding-trend-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-trend-report.js","sourceRoot":"","sources":["../../src/commands/finding-trend-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-approval-gate — Gate reviews with configurable approval criteria.
|
|
3
|
+
*
|
|
4
|
+
* Evaluates whether a review verdict meets predefined quality gates
|
|
5
|
+
* and provides pass/fail determination for CI/CD integration.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runReviewApprovalGate(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=review-approval-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-approval-gate.d.ts","sourceRoot":"","sources":["../../src/commands/review-approval-gate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8EH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2I1D"}
|