@kevinrabun/judges 3.99.0 → 3.100.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 +13 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +63 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/finding-auto-triage.d.ts +5 -0
- package/dist/commands/finding-auto-triage.d.ts.map +1 -0
- package/dist/commands/finding-auto-triage.js +109 -0
- package/dist/commands/finding-auto-triage.js.map +1 -0
- package/dist/commands/finding-change-impact.d.ts +5 -0
- package/dist/commands/finding-change-impact.d.ts.map +1 -0
- package/dist/commands/finding-change-impact.js +108 -0
- package/dist/commands/finding-change-impact.js.map +1 -0
- package/dist/commands/finding-context-enrich.d.ts +5 -0
- package/dist/commands/finding-context-enrich.d.ts.map +1 -0
- package/dist/commands/finding-context-enrich.js +90 -0
- package/dist/commands/finding-context-enrich.js.map +1 -0
- package/dist/commands/finding-false-positive-learn.d.ts +5 -0
- package/dist/commands/finding-false-positive-learn.d.ts.map +1 -0
- package/dist/commands/finding-false-positive-learn.js +86 -0
- package/dist/commands/finding-false-positive-learn.js.map +1 -0
- package/dist/commands/review-deployment-gate.d.ts +5 -0
- package/dist/commands/review-deployment-gate.d.ts.map +1 -0
- package/dist/commands/review-deployment-gate.js +95 -0
- package/dist/commands/review-deployment-gate.js.map +1 -0
- package/dist/commands/review-environment-config.d.ts +5 -0
- package/dist/commands/review-environment-config.d.ts.map +1 -0
- package/dist/commands/review-environment-config.js +103 -0
- package/dist/commands/review-environment-config.js.map +1 -0
- package/dist/commands/review-multi-repo-sync.d.ts +5 -0
- package/dist/commands/review-multi-repo-sync.d.ts.map +1 -0
- package/dist/commands/review-multi-repo-sync.js +116 -0
- package/dist/commands/review-multi-repo-sync.js.map +1 -0
- package/dist/commands/review-session-replay.d.ts +5 -0
- package/dist/commands/review-session-replay.d.ts.map +1 -0
- package/dist/commands/review-session-replay.js +82 -0
- package/dist/commands/review-session-replay.js.map +1 -0
- package/dist/commands/review-stakeholder-report.d.ts +5 -0
- package/dist/commands/review-stakeholder-report.d.ts.map +1 -0
- package/dist/commands/review-stakeholder-report.js +76 -0
- package/dist/commands/review-stakeholder-report.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-auto-triage.d.ts","sourceRoot":"","sources":["../../src/commands/finding-auto-triage.ts"],"names":[],"mappings":"AAAA;;GAEG;AA+DH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6EzD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-auto-triage — Automatically triage findings by severity, confidence, and context.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
6
|
+
function matchesRule(finding, rule) {
|
|
7
|
+
if (rule.field === "severity") {
|
|
8
|
+
if (rule.operator === "eq")
|
|
9
|
+
return finding.severity === rule.value;
|
|
10
|
+
}
|
|
11
|
+
if (rule.field === "ruleId") {
|
|
12
|
+
if (rule.operator === "eq")
|
|
13
|
+
return finding.ruleId === rule.value;
|
|
14
|
+
if (rule.operator === "contains")
|
|
15
|
+
return finding.ruleId.includes(String(rule.value));
|
|
16
|
+
}
|
|
17
|
+
if (rule.field === "confidence") {
|
|
18
|
+
const conf = finding.confidence ?? 0;
|
|
19
|
+
if (rule.operator === "gte")
|
|
20
|
+
return conf >= Number(rule.value);
|
|
21
|
+
if (rule.operator === "lte")
|
|
22
|
+
return conf <= Number(rule.value);
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
function triageFindings(findings, config) {
|
|
27
|
+
const sorted = [...config.rules].sort((a, b) => b.priority - a.priority);
|
|
28
|
+
return findings.map((f) => {
|
|
29
|
+
const matched = sorted.find((r) => matchesRule(f, r));
|
|
30
|
+
return {
|
|
31
|
+
ruleId: f.ruleId,
|
|
32
|
+
title: f.title,
|
|
33
|
+
severity: f.severity,
|
|
34
|
+
action: matched ? matched.action : config.defaultAction,
|
|
35
|
+
matchedRule: matched ? `${matched.field} ${matched.operator} ${matched.value}` : "default",
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
40
|
+
export function runFindingAutoTriage(argv) {
|
|
41
|
+
const configIdx = argv.indexOf("--config");
|
|
42
|
+
const configPath = configIdx >= 0 ? argv[configIdx + 1] : ".judges-triage.json";
|
|
43
|
+
const findingsIdx = argv.indexOf("--findings");
|
|
44
|
+
const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
|
|
45
|
+
const formatIdx = argv.indexOf("--format");
|
|
46
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
47
|
+
const initMode = argv.includes("--init");
|
|
48
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
49
|
+
console.log(`
|
|
50
|
+
judges finding-auto-triage — Automatically triage findings
|
|
51
|
+
|
|
52
|
+
Usage:
|
|
53
|
+
judges finding-auto-triage --findings <path> [--config <path>] [--format table|json]
|
|
54
|
+
judges finding-auto-triage --init [--config <path>]
|
|
55
|
+
|
|
56
|
+
Options:
|
|
57
|
+
--findings <path> Path to findings JSON file
|
|
58
|
+
--config <path> Triage rules config (default: .judges-triage.json)
|
|
59
|
+
--init Create default triage config
|
|
60
|
+
--format <fmt> Output format: table (default), json
|
|
61
|
+
--help, -h Show this help
|
|
62
|
+
`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (initMode) {
|
|
66
|
+
const defaultConfig = {
|
|
67
|
+
rules: [
|
|
68
|
+
{ field: "severity", operator: "eq", value: "critical", action: "accept", priority: 100 },
|
|
69
|
+
{ field: "severity", operator: "eq", value: "high", action: "accept", priority: 90 },
|
|
70
|
+
{ field: "confidence", operator: "lte", value: 0.3, action: "ignore", priority: 80 },
|
|
71
|
+
],
|
|
72
|
+
defaultAction: "defer",
|
|
73
|
+
lastUpdated: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
76
|
+
console.log(`Created default triage config: ${configPath}`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!findingsPath || !existsSync(findingsPath)) {
|
|
80
|
+
console.error("Provide --findings <path> to a valid findings JSON file.");
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!existsSync(configPath)) {
|
|
85
|
+
console.error(`Triage config not found: ${configPath}. Run with --init to create one.`);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
|
|
90
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
91
|
+
const results = triageFindings(findings, config);
|
|
92
|
+
if (format === "json") {
|
|
93
|
+
console.log(JSON.stringify(results, null, 2));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
console.log(`\nAuto-Triage Results (${results.length} findings)`);
|
|
97
|
+
console.log("═".repeat(80));
|
|
98
|
+
console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(12)} ${"Action".padEnd(10)} Matched Rule`);
|
|
99
|
+
console.log(" " + "─".repeat(75));
|
|
100
|
+
for (const r of results) {
|
|
101
|
+
console.log(` ${r.ruleId.padEnd(25)} ${r.severity.padEnd(12)} ${r.action.padEnd(10)} ${r.matchedRule}`);
|
|
102
|
+
}
|
|
103
|
+
const accepted = results.filter((r) => r.action === "accept").length;
|
|
104
|
+
const deferred = results.filter((r) => r.action === "defer").length;
|
|
105
|
+
const ignored = results.filter((r) => r.action === "ignore").length;
|
|
106
|
+
console.log(`\n Accept: ${accepted} | Defer: ${deferred} | Ignore: ${ignored}`);
|
|
107
|
+
console.log("═".repeat(80));
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=finding-auto-triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-auto-triage.js","sourceRoot":"","sources":["../../src/commands/finding-auto-triage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-change-impact.d.ts","sourceRoot":"","sources":["../../src/commands/finding-change-impact.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4EH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4D3D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-change-impact — Assess the impact of code changes on existing findings.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
6
|
+
function assessImpact(findings, changes) {
|
|
7
|
+
const results = [];
|
|
8
|
+
const changedLineSets = new Map();
|
|
9
|
+
for (const ch of changes) {
|
|
10
|
+
const s = new Set([...ch.linesAdded, ...ch.linesRemoved]);
|
|
11
|
+
changedLineSets.set(ch.path, s);
|
|
12
|
+
}
|
|
13
|
+
for (const f of findings) {
|
|
14
|
+
const fLines = f.lineNumbers ?? [];
|
|
15
|
+
let bestImpact = "none";
|
|
16
|
+
const affected = [];
|
|
17
|
+
let matchedPath = "";
|
|
18
|
+
for (const ch of changes) {
|
|
19
|
+
const changedLines = changedLineSets.get(ch.path);
|
|
20
|
+
if (!changedLines)
|
|
21
|
+
continue;
|
|
22
|
+
const overlap = fLines.filter((ln) => changedLines.has(ln));
|
|
23
|
+
if (overlap.length > 0) {
|
|
24
|
+
bestImpact = "direct";
|
|
25
|
+
affected.push(...overlap);
|
|
26
|
+
matchedPath = ch.path;
|
|
27
|
+
}
|
|
28
|
+
else if (fLines.length > 0 && bestImpact === "none") {
|
|
29
|
+
const nearThreshold = 5;
|
|
30
|
+
const nearby = fLines.some((ln) => {
|
|
31
|
+
for (const cl of changedLines) {
|
|
32
|
+
if (Math.abs(ln - cl) <= nearThreshold)
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
});
|
|
37
|
+
if (nearby) {
|
|
38
|
+
bestImpact = "indirect";
|
|
39
|
+
matchedPath = ch.path;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
results.push({
|
|
44
|
+
ruleId: f.ruleId,
|
|
45
|
+
title: f.title,
|
|
46
|
+
severity: f.severity,
|
|
47
|
+
impactLevel: bestImpact,
|
|
48
|
+
affectedLines: affected,
|
|
49
|
+
filePath: matchedPath,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
55
|
+
export function runFindingChangeImpact(argv) {
|
|
56
|
+
const findingsIdx = argv.indexOf("--findings");
|
|
57
|
+
const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
|
|
58
|
+
const changesIdx = argv.indexOf("--changes");
|
|
59
|
+
const changesPath = changesIdx >= 0 ? argv[changesIdx + 1] : "";
|
|
60
|
+
const formatIdx = argv.indexOf("--format");
|
|
61
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
62
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
63
|
+
console.log(`
|
|
64
|
+
judges finding-change-impact — Assess impact of code changes on findings
|
|
65
|
+
|
|
66
|
+
Usage:
|
|
67
|
+
judges finding-change-impact --findings <path> --changes <path> [--format table|json]
|
|
68
|
+
|
|
69
|
+
Options:
|
|
70
|
+
--findings <path> Path to findings JSON file
|
|
71
|
+
--changes <path> Path to changes JSON file (array of {path, linesAdded, linesRemoved})
|
|
72
|
+
--format <fmt> Output format: table (default), json
|
|
73
|
+
--help, -h Show this help
|
|
74
|
+
`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (!findingsPath || !existsSync(findingsPath)) {
|
|
78
|
+
console.error("Provide --findings <path> to a valid findings JSON file.");
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!changesPath || !existsSync(changesPath)) {
|
|
83
|
+
console.error("Provide --changes <path> to a valid changes JSON file.");
|
|
84
|
+
process.exitCode = 1;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
|
|
88
|
+
const changes = JSON.parse(readFileSync(changesPath, "utf-8"));
|
|
89
|
+
const results = assessImpact(findings, changes);
|
|
90
|
+
if (format === "json") {
|
|
91
|
+
console.log(JSON.stringify(results, null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
console.log(`\nChange Impact Analysis (${results.length} findings)`);
|
|
95
|
+
console.log("═".repeat(80));
|
|
96
|
+
console.log(` ${"Rule ID".padEnd(25)} ${"Severity".padEnd(12)} ${"Impact".padEnd(12)} Affected Lines`);
|
|
97
|
+
console.log(" " + "─".repeat(75));
|
|
98
|
+
for (const r of results) {
|
|
99
|
+
const lines = r.affectedLines.length > 0 ? r.affectedLines.join(", ") : "—";
|
|
100
|
+
console.log(` ${r.ruleId.padEnd(25)} ${r.severity.padEnd(12)} ${r.impactLevel.padEnd(12)} ${lines}`);
|
|
101
|
+
}
|
|
102
|
+
const direct = results.filter((r) => r.impactLevel === "direct").length;
|
|
103
|
+
const indirect = results.filter((r) => r.impactLevel === "indirect").length;
|
|
104
|
+
const none = results.filter((r) => r.impactLevel === "none").length;
|
|
105
|
+
console.log(`\n Direct: ${direct} | Indirect: ${indirect} | None: ${none}`);
|
|
106
|
+
console.log("═".repeat(80));
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=finding-change-impact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-change-impact.js","sourceRoot":"","sources":["../../src/commands/finding-change-impact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-context-enrich.d.ts","sourceRoot":"","sources":["../../src/commands/finding-context-enrich.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4CH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2E5D"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-context-enrich — Enrich findings with surrounding code context and metadata.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
6
|
+
function extractContext(filePath, lineNumbers, contextSize) {
|
|
7
|
+
if (!existsSync(filePath)) {
|
|
8
|
+
return { snippet: [], start: 0, end: 0 };
|
|
9
|
+
}
|
|
10
|
+
const lines = readFileSync(filePath, "utf-8").split("\n");
|
|
11
|
+
if (lineNumbers.length === 0) {
|
|
12
|
+
return { snippet: [], start: 0, end: 0 };
|
|
13
|
+
}
|
|
14
|
+
const minLine = Math.max(0, Math.min(...lineNumbers) - 1 - contextSize);
|
|
15
|
+
const maxLine = Math.min(lines.length, Math.max(...lineNumbers) + contextSize);
|
|
16
|
+
return {
|
|
17
|
+
snippet: lines.slice(minLine, maxLine),
|
|
18
|
+
start: minLine + 1,
|
|
19
|
+
end: maxLine,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
23
|
+
export function runFindingContextEnrich(argv) {
|
|
24
|
+
const findingsIdx = argv.indexOf("--findings");
|
|
25
|
+
const findingsPath = findingsIdx >= 0 ? argv[findingsIdx + 1] : "";
|
|
26
|
+
const fileIdx = argv.indexOf("--file");
|
|
27
|
+
const filePath = fileIdx >= 0 ? argv[fileIdx + 1] : "";
|
|
28
|
+
const contextIdx = argv.indexOf("--context");
|
|
29
|
+
const contextSize = contextIdx >= 0 ? parseInt(argv[contextIdx + 1], 10) : 3;
|
|
30
|
+
const formatIdx = argv.indexOf("--format");
|
|
31
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
32
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
33
|
+
console.log(`
|
|
34
|
+
judges finding-context-enrich — Enrich findings with code context
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
judges finding-context-enrich --findings <path> --file <path> [--context <n>] [--format table|json]
|
|
38
|
+
|
|
39
|
+
Options:
|
|
40
|
+
--findings <path> Path to findings JSON file
|
|
41
|
+
--file <path> Source file to extract context from
|
|
42
|
+
--context <n> Lines of context around findings (default: 3)
|
|
43
|
+
--format <fmt> Output format: table (default), json
|
|
44
|
+
--help, -h Show this help
|
|
45
|
+
`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (!findingsPath || !existsSync(findingsPath)) {
|
|
49
|
+
console.error("Provide --findings <path> to a valid findings JSON file.");
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const findings = JSON.parse(readFileSync(findingsPath, "utf-8"));
|
|
54
|
+
const enriched = [];
|
|
55
|
+
for (const f of findings) {
|
|
56
|
+
const lineNumbers = f.lineNumbers ?? [];
|
|
57
|
+
const ctx = filePath ? extractContext(filePath, lineNumbers, contextSize) : { snippet: [], start: 0, end: 0 };
|
|
58
|
+
enriched.push({
|
|
59
|
+
ruleId: f.ruleId,
|
|
60
|
+
title: f.title,
|
|
61
|
+
severity: f.severity,
|
|
62
|
+
description: f.description,
|
|
63
|
+
recommendation: f.recommendation,
|
|
64
|
+
codeSnippet: ctx.snippet,
|
|
65
|
+
lineStart: ctx.start,
|
|
66
|
+
lineEnd: ctx.end,
|
|
67
|
+
contextLines: contextSize,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (format === "json") {
|
|
71
|
+
console.log(JSON.stringify(enriched, null, 2));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
console.log(`\nEnriched Findings (${enriched.length})`);
|
|
75
|
+
console.log("═".repeat(80));
|
|
76
|
+
for (const e of enriched) {
|
|
77
|
+
console.log(`\n [${e.severity.toUpperCase()}] ${e.ruleId}: ${e.title}`);
|
|
78
|
+
console.log(` ${e.description}`);
|
|
79
|
+
console.log(` Recommendation: ${e.recommendation}`);
|
|
80
|
+
if (e.codeSnippet.length > 0) {
|
|
81
|
+
console.log(` Code (lines ${e.lineStart}–${e.lineEnd}):`);
|
|
82
|
+
for (let i = 0; i < e.codeSnippet.length; i++) {
|
|
83
|
+
console.log(` ${String(e.lineStart + i).padStart(4)} | ${e.codeSnippet[i]}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
console.log(" " + "─".repeat(75));
|
|
87
|
+
}
|
|
88
|
+
console.log("═".repeat(80));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=finding-context-enrich.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-context-enrich.js","sourceRoot":"","sources":["../../src/commands/finding-context-enrich.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-false-positive-learn.d.ts","sourceRoot":"","sources":["../../src/commands/finding-false-positive-learn.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqBH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuFjE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-false-positive-learn — Track false positive patterns to improve future triage.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
6
|
+
export function runFindingFalsePositiveLearn(argv) {
|
|
7
|
+
const storeIdx = argv.indexOf("--store");
|
|
8
|
+
const storePath = storeIdx >= 0 ? argv[storeIdx + 1] : ".judges-false-positives.json";
|
|
9
|
+
const formatIdx = argv.indexOf("--format");
|
|
10
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
11
|
+
const addMode = argv.includes("--add");
|
|
12
|
+
const ruleIdx = argv.indexOf("--rule");
|
|
13
|
+
const ruleId = ruleIdx >= 0 ? argv[ruleIdx + 1] : "";
|
|
14
|
+
const patternIdx = argv.indexOf("--pattern");
|
|
15
|
+
const pattern = patternIdx >= 0 ? argv[patternIdx + 1] : "";
|
|
16
|
+
const reasonIdx = argv.indexOf("--reason");
|
|
17
|
+
const reason = reasonIdx >= 0 ? argv[reasonIdx + 1] : "";
|
|
18
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
19
|
+
console.log(`
|
|
20
|
+
judges finding-false-positive-learn — Track false positive patterns
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
judges finding-false-positive-learn [--store <path>] [--format table|json]
|
|
24
|
+
judges finding-false-positive-learn --add --rule <id> --pattern <pat> --reason <text> [--store <path>]
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--store <path> FP store file (default: .judges-false-positives.json)
|
|
28
|
+
--add Add a new false positive pattern
|
|
29
|
+
--rule <id> Rule ID of the false positive
|
|
30
|
+
--pattern <pat> Code pattern that triggers the FP
|
|
31
|
+
--reason <text> Why this is a false positive
|
|
32
|
+
--format <fmt> Output format: table (default), json
|
|
33
|
+
--help, -h Show this help
|
|
34
|
+
`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const store = existsSync(storePath)
|
|
38
|
+
? JSON.parse(readFileSync(storePath, "utf-8"))
|
|
39
|
+
: { entries: [], lastUpdated: new Date().toISOString() };
|
|
40
|
+
if (addMode) {
|
|
41
|
+
if (!ruleId || !pattern || !reason) {
|
|
42
|
+
console.error("Provide --rule, --pattern, and --reason when using --add.");
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const existing = store.entries.find((e) => e.ruleId === ruleId && e.pattern === pattern);
|
|
47
|
+
if (existing) {
|
|
48
|
+
existing.occurrences += 1;
|
|
49
|
+
existing.reason = reason;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
store.entries.push({
|
|
53
|
+
ruleId,
|
|
54
|
+
pattern,
|
|
55
|
+
reason,
|
|
56
|
+
reportedAt: new Date().toISOString(),
|
|
57
|
+
occurrences: 1,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
store.lastUpdated = new Date().toISOString();
|
|
61
|
+
writeFileSync(storePath, JSON.stringify(store, null, 2));
|
|
62
|
+
console.log(`Recorded false positive pattern for ${ruleId}.`);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (format === "json") {
|
|
66
|
+
console.log(JSON.stringify(store, null, 2));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log("\nFalse Positive Patterns");
|
|
70
|
+
console.log("═".repeat(80));
|
|
71
|
+
if (store.entries.length === 0) {
|
|
72
|
+
console.log(" No false positive patterns recorded yet.");
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(` ${"Rule ID".padEnd(25)} ${"Pattern".padEnd(20)} ${"Count".padEnd(8)} Reason`);
|
|
76
|
+
console.log(" " + "─".repeat(75));
|
|
77
|
+
for (const e of store.entries) {
|
|
78
|
+
const pat = e.pattern.length > 18 ? e.pattern.slice(0, 15) + "..." : e.pattern;
|
|
79
|
+
const rsn = e.reason.length > 25 ? e.reason.slice(0, 22) + "..." : e.reason;
|
|
80
|
+
console.log(` ${e.ruleId.padEnd(25)} ${pat.padEnd(20)} ${String(e.occurrences).padEnd(8)} ${rsn}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
console.log(`\n Total patterns: ${store.entries.length}`);
|
|
84
|
+
console.log("═".repeat(80));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=finding-false-positive-learn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-false-positive-learn.js","sourceRoot":"","sources":["../../src/commands/finding-false-positive-learn.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAiB7D,+EAA+E;AAE/E,MAAM,UAAU,4BAA4B,CAAC,IAAc;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B,CAAC;IACtF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAef,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAuB,UAAU,CAAC,SAAS,CAAC;QACrD,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAwB;QACtE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAE3D,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAC3E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;QACzF,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;YAC1B,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBACjB,MAAM;gBACN,OAAO;gBACP,MAAM;gBACN,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,WAAW,EAAE,CAAC;aACf,CAAC,CAAC;QACL,CAAC;QAED,KAAK,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,uCAAuC,MAAM,GAAG,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC7F,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAEnC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/E,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-deployment-gate.d.ts","sourceRoot":"","sources":["../../src/commands/review-deployment-gate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiDH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkF5D"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-deployment-gate — Configure deployment gates based on review thresholds.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
6
|
+
function evaluateGate(rule, metrics) {
|
|
7
|
+
const actual = metrics[rule.metric] ?? 0;
|
|
8
|
+
let passed = false;
|
|
9
|
+
if (rule.operator === "gte")
|
|
10
|
+
passed = actual >= rule.threshold;
|
|
11
|
+
else if (rule.operator === "lte")
|
|
12
|
+
passed = actual <= rule.threshold;
|
|
13
|
+
else if (rule.operator === "eq")
|
|
14
|
+
passed = actual === rule.threshold;
|
|
15
|
+
return {
|
|
16
|
+
name: rule.name,
|
|
17
|
+
metric: rule.metric,
|
|
18
|
+
threshold: rule.threshold,
|
|
19
|
+
actual,
|
|
20
|
+
passed,
|
|
21
|
+
blocking: rule.blocking,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
25
|
+
export function runReviewDeploymentGate(argv) {
|
|
26
|
+
const configIdx = argv.indexOf("--config");
|
|
27
|
+
const configPath = configIdx >= 0 ? argv[configIdx + 1] : ".judges-deployment-gate.json";
|
|
28
|
+
const metricsIdx = argv.indexOf("--metrics");
|
|
29
|
+
const metricsPath = metricsIdx >= 0 ? argv[metricsIdx + 1] : "";
|
|
30
|
+
const formatIdx = argv.indexOf("--format");
|
|
31
|
+
const format = formatIdx >= 0 ? argv[formatIdx + 1] : "table";
|
|
32
|
+
const initMode = argv.includes("--init");
|
|
33
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
34
|
+
console.log(`
|
|
35
|
+
judges review-deployment-gate — Configure deployment gates
|
|
36
|
+
|
|
37
|
+
Usage:
|
|
38
|
+
judges review-deployment-gate --metrics <path> [--config <path>] [--format table|json]
|
|
39
|
+
judges review-deployment-gate --init [--config <path>]
|
|
40
|
+
|
|
41
|
+
Options:
|
|
42
|
+
--metrics <path> Path to metrics JSON ({score, criticalCount, highCount, totalFindings})
|
|
43
|
+
--config <path> Gate config file (default: .judges-deployment-gate.json)
|
|
44
|
+
--init Create default gate config
|
|
45
|
+
--format <fmt> Output format: table (default), json
|
|
46
|
+
--help, -h Show this help
|
|
47
|
+
`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (initMode) {
|
|
51
|
+
const defaultConfig = {
|
|
52
|
+
gates: [
|
|
53
|
+
{ name: "Min Score", metric: "score", operator: "gte", threshold: 70, blocking: true },
|
|
54
|
+
{ name: "No Criticals", metric: "criticalCount", operator: "lte", threshold: 0, blocking: true },
|
|
55
|
+
{ name: "Max High", metric: "highCount", operator: "lte", threshold: 3, blocking: false },
|
|
56
|
+
],
|
|
57
|
+
lastUpdated: new Date().toISOString(),
|
|
58
|
+
};
|
|
59
|
+
writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
60
|
+
console.log(`Created default gate config: ${configPath}`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (!metricsPath || !existsSync(metricsPath)) {
|
|
64
|
+
console.error("Provide --metrics <path> to a valid metrics JSON file.");
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (!existsSync(configPath)) {
|
|
69
|
+
console.error(`Gate config not found: ${configPath}. Run with --init to create one.`);
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const metrics = JSON.parse(readFileSync(metricsPath, "utf-8"));
|
|
74
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
75
|
+
const results = config.gates.map((g) => evaluateGate(g, metrics));
|
|
76
|
+
if (format === "json") {
|
|
77
|
+
console.log(JSON.stringify(results, null, 2));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const allPassed = results.every((r) => r.passed || !r.blocking);
|
|
81
|
+
console.log(`\nDeployment Gate Evaluation`);
|
|
82
|
+
console.log("═".repeat(70));
|
|
83
|
+
console.log(` ${"Gate".padEnd(20)} ${"Metric".padEnd(18)} ${"Threshold".padEnd(12)} ${"Actual".padEnd(10)} Result`);
|
|
84
|
+
console.log(" " + "─".repeat(65));
|
|
85
|
+
for (const r of results) {
|
|
86
|
+
const status = r.passed ? "PASS" : r.blocking ? "BLOCK" : "WARN";
|
|
87
|
+
console.log(` ${r.name.padEnd(20)} ${r.metric.padEnd(18)} ${String(r.threshold).padEnd(12)} ${String(r.actual).padEnd(10)} ${status}`);
|
|
88
|
+
}
|
|
89
|
+
console.log(`\n Overall: ${allPassed ? "DEPLOY ALLOWED" : "DEPLOY BLOCKED"}`);
|
|
90
|
+
console.log("═".repeat(70));
|
|
91
|
+
if (!allPassed) {
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=review-deployment-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-deployment-gate.js","sourceRoot":"","sources":["../../src/commands/review-deployment-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-environment-config.d.ts","sourceRoot":"","sources":["../../src/commands/review-environment-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8G/D"}
|