@kevinrabun/judges 3.62.0 → 3.64.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 +14 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/auto-approve.d.ts +5 -0
- package/dist/commands/auto-approve.d.ts.map +1 -0
- package/dist/commands/auto-approve.js +189 -0
- package/dist/commands/auto-approve.js.map +1 -0
- package/dist/commands/diff-explain.d.ts +5 -0
- package/dist/commands/diff-explain.d.ts.map +1 -0
- package/dist/commands/diff-explain.js +143 -0
- package/dist/commands/diff-explain.js.map +1 -0
- package/dist/commands/finding-group.d.ts +16 -0
- package/dist/commands/finding-group.d.ts.map +1 -0
- package/dist/commands/finding-group.js +165 -0
- package/dist/commands/finding-group.js.map +1 -0
- package/dist/commands/fix-suggest.d.ts +5 -0
- package/dist/commands/fix-suggest.d.ts.map +1 -0
- package/dist/commands/fix-suggest.js +172 -0
- package/dist/commands/fix-suggest.js.map +1 -0
- package/dist/commands/ignore-list.d.ts +19 -0
- package/dist/commands/ignore-list.d.ts.map +1 -0
- package/dist/commands/ignore-list.js +166 -0
- package/dist/commands/ignore-list.js.map +1 -0
- package/dist/commands/incremental-review.d.ts +5 -0
- package/dist/commands/incremental-review.d.ts.map +1 -0
- package/dist/commands/incremental-review.js +240 -0
- package/dist/commands/incremental-review.js.map +1 -0
- package/dist/commands/multi-lang-review.d.ts +5 -0
- package/dist/commands/multi-lang-review.d.ts.map +1 -0
- package/dist/commands/multi-lang-review.js +231 -0
- package/dist/commands/multi-lang-review.js.map +1 -0
- package/dist/commands/review-cache.d.ts +23 -0
- package/dist/commands/review-cache.d.ts.map +1 -0
- package/dist/commands/review-cache.js +135 -0
- package/dist/commands/review-cache.js.map +1 -0
- package/dist/commands/review-log.d.ts +23 -0
- package/dist/commands/review-log.d.ts.map +1 -0
- package/dist/commands/review-log.js +165 -0
- package/dist/commands/review-log.js.map +1 -0
- package/dist/commands/review-priority.d.ts +5 -0
- package/dist/commands/review-priority.d.ts.map +1 -0
- package/dist/commands/review-priority.js +158 -0
- package/dist/commands/review-priority.js.map +1 -0
- package/dist/commands/review-profile.d.ts +5 -0
- package/dist/commands/review-profile.d.ts.map +1 -0
- package/dist/commands/review-profile.js +169 -0
- package/dist/commands/review-profile.js.map +1 -0
- package/dist/commands/review-stats.d.ts +5 -0
- package/dist/commands/review-stats.d.ts.map +1 -0
- package/dist/commands/review-stats.js +176 -0
- package/dist/commands/review-stats.js.map +1 -0
- package/dist/commands/review-summary.d.ts +5 -0
- package/dist/commands/review-summary.d.ts.map +1 -0
- package/dist/commands/review-summary.js +175 -0
- package/dist/commands/review-summary.js.map +1 -0
- package/dist/commands/review-template.d.ts +5 -0
- package/dist/commands/review-template.d.ts.map +1 -0
- package/dist/commands/review-template.js +213 -0
- package/dist/commands/review-template.js.map +1 -0
- package/dist/commands/rule-test.d.ts +5 -0
- package/dist/commands/rule-test.d.ts.map +1 -0
- package/dist/commands/rule-test.js +216 -0
- package/dist/commands/rule-test.js.map +1 -0
- package/dist/commands/team-config.d.ts +5 -0
- package/dist/commands/team-config.d.ts.map +1 -0
- package/dist/commands/team-config.js +235 -0
- package/dist/commands/team-config.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix-suggest — Generate concrete code fix suggestions for findings.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync } from "fs";
|
|
5
|
+
// ─── Fix patterns database ──────────────────────────────────────────────────
|
|
6
|
+
const FIX_PATTERNS = {
|
|
7
|
+
"sql-injection": {
|
|
8
|
+
problem: "User input concatenated directly into SQL query string",
|
|
9
|
+
fixDesc: "Use parameterized queries with placeholders",
|
|
10
|
+
before: "db.query(`SELECT * FROM users WHERE id = ${userId}`)",
|
|
11
|
+
after: 'db.query("SELECT * FROM users WHERE id = ?", [userId])',
|
|
12
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html"],
|
|
13
|
+
},
|
|
14
|
+
"xss-vulnerability": {
|
|
15
|
+
problem: "User-supplied data rendered without escaping",
|
|
16
|
+
fixDesc: "Sanitize output using context-appropriate encoding",
|
|
17
|
+
before: "element.innerHTML = userInput;",
|
|
18
|
+
after: "element.textContent = userInput;",
|
|
19
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html"],
|
|
20
|
+
},
|
|
21
|
+
"hardcoded-secret": {
|
|
22
|
+
problem: "Secret value hardcoded in source file",
|
|
23
|
+
fixDesc: "Move secret to environment variable or secrets manager",
|
|
24
|
+
before: 'const API_KEY = "sk-abc123...";',
|
|
25
|
+
after: "const API_KEY = process.env.API_KEY;",
|
|
26
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html"],
|
|
27
|
+
},
|
|
28
|
+
"path-traversal": {
|
|
29
|
+
problem: "File path constructed from user input without validation",
|
|
30
|
+
fixDesc: "Normalize path and validate it stays within allowed directory",
|
|
31
|
+
before: "const file = path.join(uploadDir, req.params.filename);",
|
|
32
|
+
after: "const file = path.join(uploadDir, path.basename(req.params.filename));",
|
|
33
|
+
refs: ["https://owasp.org/www-community/attacks/Path_Traversal"],
|
|
34
|
+
},
|
|
35
|
+
"insecure-random": {
|
|
36
|
+
problem: "Math.random() used for security-sensitive value",
|
|
37
|
+
fixDesc: "Use cryptographically secure random number generator",
|
|
38
|
+
before: "const token = Math.random().toString(36);",
|
|
39
|
+
after: 'const token = crypto.randomBytes(32).toString("hex");',
|
|
40
|
+
refs: ["CWE-338: Use of Cryptographically Weak PRNG"],
|
|
41
|
+
},
|
|
42
|
+
"missing-auth": {
|
|
43
|
+
problem: "Endpoint lacks authentication check",
|
|
44
|
+
fixDesc: "Add authentication middleware before handler",
|
|
45
|
+
before: "app.get('/api/data', handler);",
|
|
46
|
+
after: "app.get('/api/data', authMiddleware, handler);",
|
|
47
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html"],
|
|
48
|
+
},
|
|
49
|
+
"error-info-leak": {
|
|
50
|
+
problem: "Detailed error information sent to client",
|
|
51
|
+
fixDesc: "Return generic error response, log details server-side",
|
|
52
|
+
before: "res.status(500).json({ error: err.stack });",
|
|
53
|
+
after: 'res.status(500).json({ error: "Internal server error" });',
|
|
54
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Error_Handling_Cheat_Sheet.html"],
|
|
55
|
+
},
|
|
56
|
+
"unsafe-deserialization": {
|
|
57
|
+
problem: "Deserialization of untrusted data",
|
|
58
|
+
fixDesc: "Validate input format and use safe deserialization",
|
|
59
|
+
before: "const obj = eval('(' + input + ')');",
|
|
60
|
+
after: "const obj = JSON.parse(input);",
|
|
61
|
+
refs: ["https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html"],
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
// ─── Suggestion engine ─────────────────────────────────────────────────────
|
|
65
|
+
function suggestFix(finding) {
|
|
66
|
+
const ruleId = finding.ruleId || "unknown";
|
|
67
|
+
const known = FIX_PATTERNS[ruleId];
|
|
68
|
+
if (known) {
|
|
69
|
+
return {
|
|
70
|
+
ruleId,
|
|
71
|
+
severity: finding.severity || "medium",
|
|
72
|
+
title: finding.title,
|
|
73
|
+
problem: known.problem,
|
|
74
|
+
fixDescription: known.fixDesc,
|
|
75
|
+
beforePattern: known.before,
|
|
76
|
+
afterPattern: known.after,
|
|
77
|
+
confidence: "high",
|
|
78
|
+
references: known.refs,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// Generate generic suggestion from finding data
|
|
82
|
+
return {
|
|
83
|
+
ruleId,
|
|
84
|
+
severity: finding.severity || "medium",
|
|
85
|
+
title: finding.title,
|
|
86
|
+
problem: finding.description || "Code pattern flagged for review",
|
|
87
|
+
fixDescription: finding.recommendation || "Apply the recommended fix pattern",
|
|
88
|
+
beforePattern: "",
|
|
89
|
+
afterPattern: "",
|
|
90
|
+
confidence: "medium",
|
|
91
|
+
references: [],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
95
|
+
export function runFixSuggest(argv) {
|
|
96
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
97
|
+
console.log(`
|
|
98
|
+
judges fix-suggest — Generate concrete fix suggestions
|
|
99
|
+
|
|
100
|
+
Usage:
|
|
101
|
+
judges fix-suggest --input verdict.json
|
|
102
|
+
judges fix-suggest --input verdict.json --rule sql-injection
|
|
103
|
+
judges fix-suggest --input verdict.json --severity critical
|
|
104
|
+
judges fix-suggest --format json
|
|
105
|
+
|
|
106
|
+
Options:
|
|
107
|
+
--input <file> TribunalVerdict JSON file (required)
|
|
108
|
+
--rule <id> Suggest fixes only for a specific rule
|
|
109
|
+
--severity <level> Filter by severity
|
|
110
|
+
--limit <n> Maximum suggestions (default: 20)
|
|
111
|
+
--format json JSON output
|
|
112
|
+
--help, -h Show this help
|
|
113
|
+
|
|
114
|
+
Generates concrete before/after code patterns for each finding,
|
|
115
|
+
with links to OWASP/CWE references where applicable.
|
|
116
|
+
`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const inputPath = argv.find((_a, i) => argv[i - 1] === "--input");
|
|
120
|
+
const ruleFilter = argv.find((_a, i) => argv[i - 1] === "--rule");
|
|
121
|
+
const sevFilter = argv.find((_a, i) => argv[i - 1] === "--severity");
|
|
122
|
+
const limitStr = argv.find((_a, i) => argv[i - 1] === "--limit");
|
|
123
|
+
const limit = limitStr ? parseInt(limitStr, 10) : 20;
|
|
124
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
125
|
+
if (!inputPath) {
|
|
126
|
+
console.error("Error: --input is required. Provide a verdict JSON file.");
|
|
127
|
+
process.exitCode = 1;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let verdict;
|
|
131
|
+
try {
|
|
132
|
+
verdict = JSON.parse(readFileSync(inputPath, "utf-8"));
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
console.error(`Error: Cannot read or parse ${inputPath}`);
|
|
136
|
+
process.exitCode = 1;
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
let findings = verdict.findings || [];
|
|
140
|
+
if (ruleFilter)
|
|
141
|
+
findings = findings.filter((f) => f.ruleId === ruleFilter);
|
|
142
|
+
if (sevFilter)
|
|
143
|
+
findings = findings.filter((f) => f.severity === sevFilter);
|
|
144
|
+
findings = findings.slice(0, limit);
|
|
145
|
+
if (findings.length === 0) {
|
|
146
|
+
console.log("No findings to suggest fixes for.");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const suggestions = findings.map(suggestFix);
|
|
150
|
+
if (format === "json") {
|
|
151
|
+
console.log(JSON.stringify({ count: suggestions.length, suggestions }, null, 2));
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
console.log(`\n Fix Suggestions (${suggestions.length})\n ─────────────────────────────`);
|
|
155
|
+
for (const s of suggestions) {
|
|
156
|
+
const sevIcon = { critical: "🔴", high: "🟠", medium: "🟡", low: "🔵" };
|
|
157
|
+
const icon = sevIcon[s.severity] || "⬜";
|
|
158
|
+
console.log(`\n ${icon} [${s.severity}] ${s.ruleId}: ${s.title}`);
|
|
159
|
+
console.log(` Problem: ${s.problem}`);
|
|
160
|
+
console.log(` Fix: ${s.fixDescription}`);
|
|
161
|
+
if (s.beforePattern) {
|
|
162
|
+
console.log(` Before: ${s.beforePattern}`);
|
|
163
|
+
console.log(` After: ${s.afterPattern}`);
|
|
164
|
+
}
|
|
165
|
+
console.log(` Confidence: ${s.confidence}`);
|
|
166
|
+
if (s.references.length > 0) {
|
|
167
|
+
console.log(` References: ${s.references.join(", ")}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
console.log();
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=fix-suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-suggest.js","sourceRoot":"","sources":["../../src/commands/fix-suggest.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAiBlC,+EAA+E;AAE/E,MAAM,YAAY,GAGd;IACF,eAAe,EAAE;QACf,OAAO,EAAE,wDAAwD;QACjE,OAAO,EAAE,6CAA6C;QACtD,MAAM,EAAE,sDAAsD;QAC9D,KAAK,EAAE,wDAAwD;QAC/D,IAAI,EAAE,CAAC,wFAAwF,CAAC;KACjG;IACD,mBAAmB,EAAE;QACnB,OAAO,EAAE,8CAA8C;QACvD,OAAO,EAAE,oDAAoD;QAC7D,MAAM,EAAE,gCAAgC;QACxC,KAAK,EAAE,kCAAkC;QACzC,IAAI,EAAE,CAAC,iGAAiG,CAAC;KAC1G;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,uCAAuC;QAChD,OAAO,EAAE,wDAAwD;QACjE,MAAM,EAAE,iCAAiC;QACzC,KAAK,EAAE,sCAAsC;QAC7C,IAAI,EAAE,CAAC,oFAAoF,CAAC;KAC7F;IACD,gBAAgB,EAAE;QAChB,OAAO,EAAE,0DAA0D;QACnE,OAAO,EAAE,+DAA+D;QACxE,MAAM,EAAE,yDAAyD;QACjE,KAAK,EAAE,wEAAwE;QAC/E,IAAI,EAAE,CAAC,wDAAwD,CAAC;KACjE;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,iDAAiD;QAC1D,OAAO,EAAE,sDAAsD;QAC/D,MAAM,EAAE,2CAA2C;QACnD,KAAK,EAAE,uDAAuD;QAC9D,IAAI,EAAE,CAAC,6CAA6C,CAAC;KACtD;IACD,cAAc,EAAE;QACd,OAAO,EAAE,qCAAqC;QAC9C,OAAO,EAAE,8CAA8C;QACvD,MAAM,EAAE,gCAAgC;QACxC,KAAK,EAAE,gDAAgD;QACvD,IAAI,EAAE,CAAC,gFAAgF,CAAC;KACzF;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,2CAA2C;QACpD,OAAO,EAAE,wDAAwD;QACjE,MAAM,EAAE,6CAA6C;QACrD,KAAK,EAAE,2DAA2D;QAClE,IAAI,EAAE,CAAC,gFAAgF,CAAC;KACzF;IACD,wBAAwB,EAAE;QACxB,OAAO,EAAE,mCAAmC;QAC5C,OAAO,EAAE,oDAAoD;QAC7D,MAAM,EAAE,sCAAsC;QAC9C,KAAK,EAAE,gCAAgC;QACvC,IAAI,EAAE,CAAC,iFAAiF,CAAC;KAC1F;CACF,CAAC;AAEF,8EAA8E;AAE9E,SAAS,UAAU,CAAC,OAAgB;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEnC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,MAAM;YACN,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ;YACtC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,cAAc,EAAE,KAAK,CAAC,OAAO;YAC7B,aAAa,EAAE,KAAK,CAAC,MAAM;YAC3B,YAAY,EAAE,KAAK,CAAC,KAAK;YACzB,UAAU,EAAE,MAAM;YAClB,UAAU,EAAE,KAAK,CAAC,IAAI;SACvB,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,QAAQ;QACtC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,OAAO,CAAC,WAAW,IAAI,iCAAiC;QACjE,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,mCAAmC;QAC7E,aAAa,EAAE,EAAE;QACjB,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAClF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;IAClF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IACjF,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,CAAC;IAE1F,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAoB,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IACtC,IAAI,UAAU;QAAE,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;IAC3E,IAAI,SAAS;QAAE,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;IAC3E,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEpC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,WAAW,CAAC,MAAM,oCAAoC,CAAC,CAAC;IAE5F,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,OAAO,GAA2B,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QAChG,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;QAExC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ignore-list — Configurable ignore patterns for files, directories, and rules.
|
|
3
|
+
*/
|
|
4
|
+
interface IgnoreConfig {
|
|
5
|
+
version: string;
|
|
6
|
+
filePatterns: string[];
|
|
7
|
+
directoryPatterns: string[];
|
|
8
|
+
ruleIgnores: string[];
|
|
9
|
+
inlineSuppressions: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function shouldIgnoreFile(filePath: string, baseDir: string, config: IgnoreConfig): boolean;
|
|
12
|
+
declare function shouldIgnoreRule(ruleId: string, config: IgnoreConfig): boolean;
|
|
13
|
+
declare function filterFiles(files: string[], baseDir: string, config: IgnoreConfig): {
|
|
14
|
+
effective: string[];
|
|
15
|
+
ignored: string[];
|
|
16
|
+
};
|
|
17
|
+
export declare function runIgnoreList(argv: string[]): void;
|
|
18
|
+
export { shouldIgnoreFile, shouldIgnoreRule, filterFiles, IgnoreConfig };
|
|
19
|
+
//# sourceMappingURL=ignore-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore-list.d.ts","sourceRoot":"","sources":["../../src/commands/ignore-list.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2BH,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAgCD,iBAAS,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAc1F;AAED,iBAAS,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAEvE;AAED,iBAAS,WAAW,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,GACnB;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAa5C;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8FlD;AAGD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ignore-list — Configurable ignore patterns for files, directories, and rules.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
import { join, relative } from "path";
|
|
6
|
+
// ─── Simple glob matcher ────────────────────────────────────────────────────
|
|
7
|
+
function globToRegex(pattern) {
|
|
8
|
+
const regex = pattern
|
|
9
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&") // Escape special regex chars (but not * and ?)
|
|
10
|
+
.replace(/\*\*/g, "{{GLOBSTAR}}") // Temp placeholder for **
|
|
11
|
+
.replace(/\*/g, "[^/]*") // * matches anything except /
|
|
12
|
+
.replace(/\?/g, "[^/]") // ? matches single char except /
|
|
13
|
+
.replace(/\{\{GLOBSTAR\}\}/g, ".*"); // ** matches everything including /
|
|
14
|
+
return new RegExp(`^${regex}$`);
|
|
15
|
+
}
|
|
16
|
+
function matchGlob(filePath, pattern) {
|
|
17
|
+
try {
|
|
18
|
+
return globToRegex(pattern).test(filePath);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// ─── Default config ────────────────────────────────────────────────────────
|
|
25
|
+
function defaultIgnoreConfig() {
|
|
26
|
+
return {
|
|
27
|
+
version: "1.0.0",
|
|
28
|
+
filePatterns: [
|
|
29
|
+
"**/*.test.ts",
|
|
30
|
+
"**/*.test.js",
|
|
31
|
+
"**/*.spec.ts",
|
|
32
|
+
"**/*.spec.js",
|
|
33
|
+
"**/*.d.ts",
|
|
34
|
+
"**/fixtures/**",
|
|
35
|
+
"**/testdata/**",
|
|
36
|
+
],
|
|
37
|
+
directoryPatterns: ["node_modules", "dist", "build", "coverage", ".git", ".next", "__pycache__", "vendor"],
|
|
38
|
+
ruleIgnores: [],
|
|
39
|
+
inlineSuppressions: true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
// ─── Matching engine ───────────────────────────────────────────────────────
|
|
43
|
+
function shouldIgnoreFile(filePath, baseDir, config) {
|
|
44
|
+
const rel = relative(baseDir, filePath).replace(/\\/g, "/");
|
|
45
|
+
for (const pattern of config.filePatterns) {
|
|
46
|
+
if (matchGlob(rel, pattern))
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
// Check directory patterns
|
|
50
|
+
const parts = rel.split("/");
|
|
51
|
+
for (const dir of config.directoryPatterns) {
|
|
52
|
+
if (parts.includes(dir))
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
function shouldIgnoreRule(ruleId, config) {
|
|
58
|
+
return config.ruleIgnores.includes(ruleId);
|
|
59
|
+
}
|
|
60
|
+
function filterFiles(files, baseDir, config) {
|
|
61
|
+
const effective = [];
|
|
62
|
+
const ignored = [];
|
|
63
|
+
for (const f of files) {
|
|
64
|
+
if (shouldIgnoreFile(f, baseDir, config)) {
|
|
65
|
+
ignored.push(f);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
effective.push(f);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { effective, ignored };
|
|
72
|
+
}
|
|
73
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
74
|
+
export function runIgnoreList(argv) {
|
|
75
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
76
|
+
console.log(`
|
|
77
|
+
judges ignore-list — Manage review ignore patterns
|
|
78
|
+
|
|
79
|
+
Usage:
|
|
80
|
+
judges ignore-list init Create .judgesignore.json template
|
|
81
|
+
judges ignore-list show Show current ignore config
|
|
82
|
+
judges ignore-list test <path> Test if a path would be ignored
|
|
83
|
+
judges ignore-list --format json JSON output
|
|
84
|
+
|
|
85
|
+
Subcommands:
|
|
86
|
+
init Create a .judgesignore.json template
|
|
87
|
+
show Display current ignore configuration
|
|
88
|
+
test <path> Test whether a specific path is ignored
|
|
89
|
+
|
|
90
|
+
Options:
|
|
91
|
+
--format json JSON output
|
|
92
|
+
--help, -h Show this help
|
|
93
|
+
|
|
94
|
+
Ignore patterns are stored in .judgesignore.json and control which files,
|
|
95
|
+
directories, and rules are excluded from review.
|
|
96
|
+
`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
100
|
+
const configPath = join(".", ".judgesignore.json");
|
|
101
|
+
const subcommand = argv.find((a) => !a.startsWith("-") && a !== "ignore-list") || "show";
|
|
102
|
+
if (subcommand === "init") {
|
|
103
|
+
if (existsSync(configPath)) {
|
|
104
|
+
console.error("Error: .judgesignore.json already exists.");
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
writeFileSync(configPath, JSON.stringify(defaultIgnoreConfig(), null, 2), "utf-8");
|
|
109
|
+
console.log("Created .judgesignore.json with default patterns.");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Load config
|
|
113
|
+
let config;
|
|
114
|
+
if (existsSync(configPath)) {
|
|
115
|
+
try {
|
|
116
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
console.error("Error: .judgesignore.json is not valid JSON.");
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
config = defaultIgnoreConfig();
|
|
126
|
+
}
|
|
127
|
+
if (subcommand === "test") {
|
|
128
|
+
const testPath = argv.find((a) => !a.startsWith("-") && a !== "ignore-list" && a !== "test");
|
|
129
|
+
if (!testPath) {
|
|
130
|
+
console.error("Error: Provide a path to test.");
|
|
131
|
+
process.exitCode = 1;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const ignored = shouldIgnoreFile(testPath, ".", config);
|
|
135
|
+
if (format === "json") {
|
|
136
|
+
console.log(JSON.stringify({ path: testPath, ignored }));
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
console.log(` ${testPath}: ${ignored ? "❌ IGNORED" : "✅ INCLUDED"}`);
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Show
|
|
144
|
+
if (format === "json") {
|
|
145
|
+
console.log(JSON.stringify(config, null, 2));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
console.log(`\n Ignore Configuration\n ─────────────────────────────`);
|
|
149
|
+
console.log(` Source: ${existsSync(configPath) ? configPath : "defaults (no .judgesignore.json)"}`);
|
|
150
|
+
console.log(`\n File Patterns (${config.filePatterns.length}):`);
|
|
151
|
+
for (const p of config.filePatterns)
|
|
152
|
+
console.log(` ⬜ ${p}`);
|
|
153
|
+
console.log(`\n Directory Patterns (${config.directoryPatterns.length}):`);
|
|
154
|
+
for (const p of config.directoryPatterns)
|
|
155
|
+
console.log(` ⬜ ${p}`);
|
|
156
|
+
if (config.ruleIgnores.length > 0) {
|
|
157
|
+
console.log(`\n Ignored Rules (${config.ruleIgnores.length}):`);
|
|
158
|
+
for (const r of config.ruleIgnores)
|
|
159
|
+
console.log(` ⬜ ${r}`);
|
|
160
|
+
}
|
|
161
|
+
console.log(`\n Inline suppressions: ${config.inlineSuppressions ? "enabled" : "disabled"}`);
|
|
162
|
+
console.log();
|
|
163
|
+
}
|
|
164
|
+
// Export helpers for use by other commands
|
|
165
|
+
export { shouldIgnoreFile, shouldIgnoreRule, filterFiles };
|
|
166
|
+
//# sourceMappingURL=ignore-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore-list.js","sourceRoot":"","sources":["../../src/commands/ignore-list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incremental-review.d.ts","sourceRoot":"","sources":["../../src/commands/incremental-review.ts"],"names":[],"mappings":"AAAA;;GAEG;AA2IH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsIzD"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental-review — Only review files changed since last review.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
|
|
5
|
+
import { createHash } from "crypto";
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
import { join, dirname } from "path";
|
|
8
|
+
// ─── Hash helper ────────────────────────────────────────────────────────────
|
|
9
|
+
function hashContent(content) {
|
|
10
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
11
|
+
}
|
|
12
|
+
// ─── Git helpers ────────────────────────────────────────────────────────────
|
|
13
|
+
function getGitChangedFiles(since) {
|
|
14
|
+
try {
|
|
15
|
+
const args = since ? `diff --name-only ${since}` : "diff --name-only HEAD";
|
|
16
|
+
const output = execSync(`git ${args}`, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
17
|
+
if (!output)
|
|
18
|
+
return [];
|
|
19
|
+
return output.split("\n").filter((f) => f.length > 0);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function getGitStagedFiles() {
|
|
26
|
+
try {
|
|
27
|
+
const output = execSync("git diff --name-only --cached", {
|
|
28
|
+
encoding: "utf-8",
|
|
29
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
30
|
+
}).trim();
|
|
31
|
+
if (!output)
|
|
32
|
+
return [];
|
|
33
|
+
return output.split("\n").filter((f) => f.length > 0);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function getCurrentCommit() {
|
|
40
|
+
try {
|
|
41
|
+
return execSync("git rev-parse HEAD", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return "unknown";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ─── State management ───────────────────────────────────────────────────────
|
|
48
|
+
const STATE_DIR = join(".judges", "incremental");
|
|
49
|
+
const STATE_FILE = join(STATE_DIR, "state.json");
|
|
50
|
+
function loadState() {
|
|
51
|
+
if (!existsSync(STATE_FILE))
|
|
52
|
+
return null;
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(readFileSync(STATE_FILE, "utf-8"));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function saveState(state) {
|
|
61
|
+
mkdirSync(dirname(STATE_FILE), { recursive: true });
|
|
62
|
+
writeFileSync(STATE_FILE, JSON.stringify(state, null, 2), "utf-8");
|
|
63
|
+
}
|
|
64
|
+
// ─── Changed file detection ────────────────────────────────────────────────
|
|
65
|
+
function detectChangedFiles(state, allFiles) {
|
|
66
|
+
if (!state) {
|
|
67
|
+
return { changed: allFiles, unchanged: [], newFiles: allFiles };
|
|
68
|
+
}
|
|
69
|
+
const changed = [];
|
|
70
|
+
const unchanged = [];
|
|
71
|
+
const newFiles = [];
|
|
72
|
+
for (const file of allFiles) {
|
|
73
|
+
if (!existsSync(file))
|
|
74
|
+
continue;
|
|
75
|
+
const previousHash = state.fileHashes[file];
|
|
76
|
+
if (!previousHash) {
|
|
77
|
+
newFiles.push(file);
|
|
78
|
+
changed.push(file);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const content = readFileSync(file, "utf-8");
|
|
83
|
+
const currentHash = hashContent(content);
|
|
84
|
+
if (currentHash !== previousHash) {
|
|
85
|
+
changed.push(file);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
unchanged.push(file);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
changed.push(file);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { changed, unchanged, newFiles };
|
|
96
|
+
}
|
|
97
|
+
// ─── Update state with current hashes ───────────────────────────────────────
|
|
98
|
+
function buildStateFromFiles(files) {
|
|
99
|
+
const fileHashes = {};
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
if (!existsSync(file))
|
|
102
|
+
continue;
|
|
103
|
+
try {
|
|
104
|
+
const content = readFileSync(file, "utf-8");
|
|
105
|
+
fileHashes[file] = hashContent(content);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// skip unreadable files
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
lastReviewTimestamp: new Date().toISOString(),
|
|
113
|
+
lastCommit: getCurrentCommit(),
|
|
114
|
+
fileHashes,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
118
|
+
export function runIncrementalReview(argv) {
|
|
119
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
120
|
+
console.log(`
|
|
121
|
+
judges incremental-review — Only review files changed since last review
|
|
122
|
+
|
|
123
|
+
Usage:
|
|
124
|
+
judges incremental-review Show changed files since last review
|
|
125
|
+
judges incremental-review --git Use git diff to detect changes
|
|
126
|
+
judges incremental-review --save Save current state as baseline
|
|
127
|
+
judges incremental-review --reset Reset incremental state
|
|
128
|
+
judges incremental-review --format json JSON output
|
|
129
|
+
|
|
130
|
+
Subcommands:
|
|
131
|
+
status Show what would be reviewed (default)
|
|
132
|
+
save Save current file state as baseline
|
|
133
|
+
reset Clear incremental state
|
|
134
|
+
|
|
135
|
+
Options:
|
|
136
|
+
--git Include git-tracked changed files
|
|
137
|
+
--staged Include only staged files
|
|
138
|
+
--since <commit> Git diff since specific commit
|
|
139
|
+
--files <glob> Only consider files matching pattern
|
|
140
|
+
--save Save state after showing changes
|
|
141
|
+
--reset Clear incremental state
|
|
142
|
+
--format json JSON output
|
|
143
|
+
--help, -h Show this help
|
|
144
|
+
|
|
145
|
+
Uses content hashing and git status to skip unchanged files.
|
|
146
|
+
Run after a review to save state, then on next run only changed
|
|
147
|
+
files are flagged for review.
|
|
148
|
+
`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
152
|
+
const useGit = argv.includes("--git");
|
|
153
|
+
const useStaged = argv.includes("--staged");
|
|
154
|
+
const sinceCommit = argv.find((_a, i) => argv[i - 1] === "--since");
|
|
155
|
+
const doSave = argv.includes("--save");
|
|
156
|
+
const doReset = argv.includes("--reset");
|
|
157
|
+
if (doReset) {
|
|
158
|
+
if (existsSync(STATE_FILE)) {
|
|
159
|
+
writeFileSync(STATE_FILE, "{}", "utf-8");
|
|
160
|
+
console.log("Incremental state reset.");
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.log("No incremental state found.");
|
|
164
|
+
}
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
// Collect files to consider
|
|
168
|
+
let targetFiles;
|
|
169
|
+
if (useStaged) {
|
|
170
|
+
targetFiles = getGitStagedFiles();
|
|
171
|
+
}
|
|
172
|
+
else if (useGit || sinceCommit) {
|
|
173
|
+
targetFiles = getGitChangedFiles(sinceCommit);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// No git flag — use state-based detection
|
|
177
|
+
// Collect all tracked files from git
|
|
178
|
+
try {
|
|
179
|
+
const output = execSync("git ls-files", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
180
|
+
targetFiles = output
|
|
181
|
+
.split("\n")
|
|
182
|
+
.filter((f) => f.length > 0 && /\.(ts|js|py|go|rs|java|cs|cpp|c|rb|php|tsx|jsx)$/.test(f));
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
console.error("Error: Cannot list files. Are you in a git repository?");
|
|
186
|
+
process.exitCode = 1;
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const state = loadState();
|
|
191
|
+
const { changed, unchanged, newFiles } = detectChangedFiles(state, targetFiles);
|
|
192
|
+
if (doSave) {
|
|
193
|
+
const newState = buildStateFromFiles(targetFiles);
|
|
194
|
+
saveState(newState);
|
|
195
|
+
}
|
|
196
|
+
if (format === "json") {
|
|
197
|
+
console.log(JSON.stringify({
|
|
198
|
+
hasState: state !== null,
|
|
199
|
+
lastReview: state?.lastReviewTimestamp || null,
|
|
200
|
+
lastCommit: state?.lastCommit || null,
|
|
201
|
+
totalFiles: targetFiles.length,
|
|
202
|
+
changedFiles: changed.length,
|
|
203
|
+
unchangedFiles: unchanged.length,
|
|
204
|
+
newFiles: newFiles.length,
|
|
205
|
+
changed,
|
|
206
|
+
saved: doSave,
|
|
207
|
+
}, null, 2));
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
console.log(`\n Incremental Review Status\n ─────────────────────────────`);
|
|
211
|
+
if (state) {
|
|
212
|
+
console.log(` Last review: ${state.lastReviewTimestamp}`);
|
|
213
|
+
console.log(` Last commit: ${state.lastCommit.slice(0, 8)}`);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.log(` No previous state — all files will be reviewed`);
|
|
217
|
+
}
|
|
218
|
+
console.log(`\n Total files: ${targetFiles.length}`);
|
|
219
|
+
console.log(` Changed: ${changed.length}`);
|
|
220
|
+
console.log(` Unchanged: ${unchanged.length}`);
|
|
221
|
+
console.log(` New: ${newFiles.length}`);
|
|
222
|
+
if (changed.length > 0) {
|
|
223
|
+
console.log(`\n Files to review:`);
|
|
224
|
+
for (const f of changed.slice(0, 30)) {
|
|
225
|
+
const marker = newFiles.includes(f) ? "🆕" : "📝";
|
|
226
|
+
console.log(` ${marker} ${f}`);
|
|
227
|
+
}
|
|
228
|
+
if (changed.length > 30) {
|
|
229
|
+
console.log(` ... and ${changed.length - 30} more`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
console.log(`\n ✅ No files have changed since last review.`);
|
|
234
|
+
}
|
|
235
|
+
if (doSave) {
|
|
236
|
+
console.log(`\n 💾 State saved.`);
|
|
237
|
+
}
|
|
238
|
+
console.log();
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=incremental-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incremental-review.js","sourceRoot":"","sources":["../../src/commands/incremental-review.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-lang-review.d.ts","sourceRoot":"","sources":["../../src/commands/multi-lang-review.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsMH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsFvD"}
|