@kevinrabun/judges 3.58.0 → 3.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/adoption-track.d.ts +5 -0
  6. package/dist/commands/adoption-track.d.ts.map +1 -0
  7. package/dist/commands/adoption-track.js +247 -0
  8. package/dist/commands/adoption-track.js.map +1 -0
  9. package/dist/commands/api-misuse.d.ts +5 -0
  10. package/dist/commands/api-misuse.d.ts.map +1 -0
  11. package/dist/commands/api-misuse.js +261 -0
  12. package/dist/commands/api-misuse.js.map +1 -0
  13. package/dist/commands/completion-audit.d.ts +5 -0
  14. package/dist/commands/completion-audit.d.ts.map +1 -0
  15. package/dist/commands/completion-audit.js +297 -0
  16. package/dist/commands/completion-audit.js.map +1 -0
  17. package/dist/commands/context-blind.d.ts +5 -0
  18. package/dist/commands/context-blind.d.ts.map +1 -0
  19. package/dist/commands/context-blind.js +273 -0
  20. package/dist/commands/context-blind.js.map +1 -0
  21. package/dist/commands/cross-file-consistency.d.ts +5 -0
  22. package/dist/commands/cross-file-consistency.d.ts.map +1 -0
  23. package/dist/commands/cross-file-consistency.js +255 -0
  24. package/dist/commands/cross-file-consistency.js.map +1 -0
  25. package/dist/commands/example-leak.d.ts +5 -0
  26. package/dist/commands/example-leak.d.ts.map +1 -0
  27. package/dist/commands/example-leak.js +233 -0
  28. package/dist/commands/example-leak.js.map +1 -0
  29. package/dist/commands/finding-budget.d.ts +5 -0
  30. package/dist/commands/finding-budget.d.ts.map +1 -0
  31. package/dist/commands/finding-budget.js +233 -0
  32. package/dist/commands/finding-budget.js.map +1 -0
  33. package/dist/commands/hallucination-detect.d.ts +5 -0
  34. package/dist/commands/hallucination-detect.d.ts.map +1 -0
  35. package/dist/commands/hallucination-detect.js +351 -0
  36. package/dist/commands/hallucination-detect.js.map +1 -0
  37. package/dist/commands/logic-lint.d.ts +5 -0
  38. package/dist/commands/logic-lint.d.ts.map +1 -0
  39. package/dist/commands/logic-lint.js +256 -0
  40. package/dist/commands/logic-lint.js.map +1 -0
  41. package/dist/commands/over-abstraction.d.ts +5 -0
  42. package/dist/commands/over-abstraction.d.ts.map +1 -0
  43. package/dist/commands/over-abstraction.js +308 -0
  44. package/dist/commands/over-abstraction.js.map +1 -0
  45. package/dist/commands/phantom-import.d.ts +5 -0
  46. package/dist/commands/phantom-import.d.ts.map +1 -0
  47. package/dist/commands/phantom-import.js +261 -0
  48. package/dist/commands/phantom-import.js.map +1 -0
  49. package/dist/commands/review-digest.d.ts +5 -0
  50. package/dist/commands/review-digest.d.ts.map +1 -0
  51. package/dist/commands/review-digest.js +266 -0
  52. package/dist/commands/review-digest.js.map +1 -0
  53. package/dist/commands/review-focus.d.ts +5 -0
  54. package/dist/commands/review-focus.d.ts.map +1 -0
  55. package/dist/commands/review-focus.js +197 -0
  56. package/dist/commands/review-focus.js.map +1 -0
  57. package/dist/commands/security-theater.d.ts +5 -0
  58. package/dist/commands/security-theater.d.ts.map +1 -0
  59. package/dist/commands/security-theater.js +279 -0
  60. package/dist/commands/security-theater.js.map +1 -0
  61. package/dist/commands/spec-conform.d.ts +5 -0
  62. package/dist/commands/spec-conform.d.ts.map +1 -0
  63. package/dist/commands/spec-conform.js +305 -0
  64. package/dist/commands/spec-conform.js.map +1 -0
  65. package/dist/commands/stale-pattern.d.ts +5 -0
  66. package/dist/commands/stale-pattern.d.ts.map +1 -0
  67. package/dist/commands/stale-pattern.js +294 -0
  68. package/dist/commands/stale-pattern.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Phantom import — detect hallucinated imports, non-existent modules, and wrong export names.
3
+ */
4
+ import { readFileSync, readdirSync, statSync, existsSync } from "fs";
5
+ import { join, extname, dirname, resolve } from "path";
6
+ // ─── File Collection ────────────────────────────────────────────────────────
7
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx"]);
8
+ function collectFiles(dir, max = 300) {
9
+ const files = [];
10
+ function walk(d) {
11
+ if (files.length >= max)
12
+ return;
13
+ let entries;
14
+ try {
15
+ entries = readdirSync(d);
16
+ }
17
+ catch {
18
+ return;
19
+ }
20
+ for (const e of entries) {
21
+ if (files.length >= max)
22
+ return;
23
+ if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
24
+ continue;
25
+ const full = join(d, e);
26
+ try {
27
+ if (statSync(full).isDirectory())
28
+ walk(full);
29
+ else if (CODE_EXTS.has(extname(full)))
30
+ files.push(full);
31
+ }
32
+ catch {
33
+ /* skip */
34
+ }
35
+ }
36
+ }
37
+ walk(dir);
38
+ return files;
39
+ }
40
+ // ─── Exports Index ──────────────────────────────────────────────────────────
41
+ function buildExportsMap(files) {
42
+ const exports = new Map();
43
+ for (const filepath of files) {
44
+ let content;
45
+ try {
46
+ content = readFileSync(filepath, "utf-8");
47
+ }
48
+ catch {
49
+ continue;
50
+ }
51
+ const names = new Set();
52
+ // export function/class/const/let/var/type/interface/enum
53
+ for (const m of content.matchAll(/export\s+(?:default\s+)?(?:function|class|const|let|var|type|interface|enum)\s+(\w+)/g)) {
54
+ names.add(m[1]);
55
+ }
56
+ // export { ... }
57
+ for (const m of content.matchAll(/export\s*\{([^}]+)\}/g)) {
58
+ for (const name of m[1].split(",")) {
59
+ const cleaned = name
60
+ .trim()
61
+ .split(/\s+as\s+/)[0]
62
+ .trim();
63
+ if (cleaned)
64
+ names.add(cleaned);
65
+ }
66
+ }
67
+ // export default
68
+ if (/export\s+default\s/.test(content))
69
+ names.add("default");
70
+ exports.set(filepath, names);
71
+ }
72
+ return exports;
73
+ }
74
+ // ─── Analysis ───────────────────────────────────────────────────────────────
75
+ function analyzeFile(filepath, exportsMap, projectDir) {
76
+ const issues = [];
77
+ let content;
78
+ try {
79
+ content = readFileSync(filepath, "utf-8");
80
+ }
81
+ catch {
82
+ return issues;
83
+ }
84
+ const lines = content.split("\n");
85
+ for (let i = 0; i < lines.length; i++) {
86
+ const line = lines[i];
87
+ // import from relative path
88
+ const relImport = line.match(/import\s+(?:\{[^}]*\}|[\w*]+(?:\s*,\s*\{[^}]*\})?)\s+from\s+['"](\.[^'"]+)['"]/);
89
+ if (relImport) {
90
+ const importPath = relImport[1];
91
+ const dir = dirname(filepath);
92
+ const candidates = [
93
+ resolve(dir, importPath),
94
+ resolve(dir, importPath + ".ts"),
95
+ resolve(dir, importPath + ".tsx"),
96
+ resolve(dir, importPath + ".js"),
97
+ resolve(dir, importPath + ".jsx"),
98
+ resolve(dir, importPath, "index.ts"),
99
+ resolve(dir, importPath, "index.js"),
100
+ ];
101
+ const resolved = candidates.find((c) => existsSync(c));
102
+ if (!resolved) {
103
+ issues.push({
104
+ file: filepath,
105
+ line: i + 1,
106
+ issue: "Import resolves to non-existent file",
107
+ severity: "high",
108
+ detail: `\`${importPath}\` does not exist — AI may have hallucinated this module path`,
109
+ });
110
+ }
111
+ else {
112
+ // Check named imports exist in target
113
+ const namedMatch = line.match(/import\s*\{([^}]+)\}\s*from/);
114
+ if (namedMatch) {
115
+ const targetExports = exportsMap.get(resolved);
116
+ if (targetExports) {
117
+ const imported = namedMatch[1]
118
+ .split(",")
119
+ .map((n) => n
120
+ .trim()
121
+ .split(/\s+as\s+/)[0]
122
+ .trim())
123
+ .filter(Boolean);
124
+ for (const name of imported) {
125
+ if (!targetExports.has(name)) {
126
+ issues.push({
127
+ file: filepath,
128
+ line: i + 1,
129
+ issue: "Named import does not exist in target",
130
+ severity: "high",
131
+ detail: `\`${name}\` is not exported from \`${importPath}\` — may be a hallucinated export name`,
132
+ });
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ // Common hallucinated npm packages (AI often invents package names)
140
+ const npmImport = line.match(/import\s+.*\s+from\s+['"]([a-z@][a-z0-9./_-]*)['"]/);
141
+ if (npmImport && !npmImport[1].startsWith(".")) {
142
+ const pkg = npmImport[1]
143
+ .split("/")
144
+ .slice(0, npmImport[1].startsWith("@") ? 2 : 1)
145
+ .join("/");
146
+ // Check if package exists in node_modules
147
+ const nmPath = join(projectDir, "node_modules", pkg);
148
+ if (!existsSync(nmPath)) {
149
+ // Check if it's in package.json
150
+ try {
151
+ const pkgJson = JSON.parse(readFileSync(join(projectDir, "package.json"), "utf-8"));
152
+ const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies, ...pkgJson.peerDependencies };
153
+ if (!allDeps[pkg]) {
154
+ issues.push({
155
+ file: filepath,
156
+ line: i + 1,
157
+ issue: "Import from uninstalled package",
158
+ severity: "high",
159
+ detail: `\`${pkg}\` is not in package.json or node_modules — may be a hallucinated package`,
160
+ });
161
+ }
162
+ }
163
+ catch {
164
+ /* skip */
165
+ }
166
+ }
167
+ }
168
+ // require() of non-existent relative path
169
+ const requireMatch = line.match(/require\s*\(\s*['"](\.[^'"]+)['"]\s*\)/);
170
+ if (requireMatch) {
171
+ const reqPath = requireMatch[1];
172
+ const dir = dirname(filepath);
173
+ const candidates = [
174
+ resolve(dir, reqPath),
175
+ resolve(dir, reqPath + ".ts"),
176
+ resolve(dir, reqPath + ".js"),
177
+ resolve(dir, reqPath + ".json"),
178
+ resolve(dir, reqPath, "index.js"),
179
+ ];
180
+ if (!candidates.some((c) => existsSync(c))) {
181
+ issues.push({
182
+ file: filepath,
183
+ line: i + 1,
184
+ issue: "require() of non-existent module",
185
+ severity: "high",
186
+ detail: `\`${reqPath}\` does not resolve to any file — may be hallucinated`,
187
+ });
188
+ }
189
+ }
190
+ // Importing from deprecated / removed Node.js APIs
191
+ const deprecatedImport = line.match(/(?:import|require)\s*(?:\(?\s*['"])(sys|_linklist|constants|punycode|domain|v8\/tools|node:sys)['"](?:\))?/);
192
+ if (deprecatedImport) {
193
+ issues.push({
194
+ file: filepath,
195
+ line: i + 1,
196
+ issue: "Import of deprecated Node.js module",
197
+ severity: "medium",
198
+ detail: `\`${deprecatedImport[1]}\` is deprecated or removed — AI may be referencing outdated API`,
199
+ });
200
+ }
201
+ }
202
+ return issues;
203
+ }
204
+ // ─── CLI ────────────────────────────────────────────────────────────────────
205
+ export function runPhantomImport(argv) {
206
+ if (argv.includes("--help") || argv.includes("-h")) {
207
+ console.log(`
208
+ judges phantom-import — Detect hallucinated imports and non-existent modules
209
+
210
+ Usage:
211
+ judges phantom-import [dir]
212
+ judges phantom-import src/ --format json
213
+
214
+ Options:
215
+ [dir] Directory to scan (default: .)
216
+ --format json JSON output
217
+ --help, -h Show this help
218
+
219
+ Checks: non-existent relative imports, hallucinated named exports, uninstalled packages,
220
+ deprecated Node.js modules, require() of missing files.
221
+ `);
222
+ return;
223
+ }
224
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
225
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
226
+ const projectDir = resolve(dir);
227
+ const files = collectFiles(dir);
228
+ const exportsMap = buildExportsMap(files);
229
+ const allIssues = [];
230
+ for (const f of files)
231
+ allIssues.push(...analyzeFile(f, exportsMap, projectDir));
232
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
233
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
234
+ const score = Math.max(0, 100 - highCount * 15 - medCount * 5);
235
+ if (format === "json") {
236
+ console.log(JSON.stringify({
237
+ issues: allIssues,
238
+ score,
239
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
240
+ timestamp: new Date().toISOString(),
241
+ }, null, 2));
242
+ }
243
+ else {
244
+ const badge = score >= 80 ? "✅ CLEAN" : score >= 50 ? "⚠️ SUSPECT" : "❌ PHANTOMS";
245
+ console.log(`\n Phantom Import: ${badge} (${score}/100)\n ─────────────────────────────`);
246
+ if (allIssues.length === 0) {
247
+ console.log(" No phantom imports detected.\n");
248
+ return;
249
+ }
250
+ for (const issue of allIssues.slice(0, 25)) {
251
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
252
+ console.log(` ${icon} ${issue.issue}`);
253
+ console.log(` ${issue.file}:${issue.line}`);
254
+ console.log(` ${issue.detail}`);
255
+ }
256
+ if (allIssues.length > 25)
257
+ console.log(` ... and ${allIssues.length - 25} more`);
258
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
259
+ }
260
+ }
261
+ //# sourceMappingURL=phantom-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phantom-import.js","sourceRoot":"","sources":["../../src/commands/phantom-import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-digest — generate concise, role-appropriate review summaries.
3
+ */
4
+ export declare function runReviewDigest(argv: string[]): void;
5
+ //# sourceMappingURL=review-digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-digest.d.ts","sourceRoot":"","sources":["../../src/commands/review-digest.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiOH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmFpD"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Review-digest — generate concise, role-appropriate review summaries.
3
+ */
4
+ import { readFileSync, readdirSync, statSync, writeFileSync } from "fs";
5
+ import { join, extname, relative } from "path";
6
+ // ─── File Collection ────────────────────────────────────────────────────────
7
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".cs", ".rb", ".rs"]);
8
+ function collectFiles(dir, max = 300) {
9
+ const files = [];
10
+ function walk(d) {
11
+ if (files.length >= max)
12
+ return;
13
+ let entries;
14
+ try {
15
+ entries = readdirSync(d);
16
+ }
17
+ catch {
18
+ return;
19
+ }
20
+ for (const e of entries) {
21
+ if (files.length >= max)
22
+ return;
23
+ if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
24
+ continue;
25
+ const full = join(d, e);
26
+ try {
27
+ if (statSync(full).isDirectory())
28
+ walk(full);
29
+ else if (CODE_EXTS.has(extname(full)))
30
+ files.push(full);
31
+ }
32
+ catch {
33
+ /* skip */
34
+ }
35
+ }
36
+ }
37
+ walk(dir);
38
+ return files;
39
+ }
40
+ const QUICK_PATTERNS = [
41
+ { regex: /eval\s*\(/, category: "Security", title: "eval() usage", severity: "critical", autoFix: false },
42
+ {
43
+ regex: /(?:password|secret|api[_-]?key)\s*[:=]\s*['"][^'"]+['"]/,
44
+ category: "Security",
45
+ title: "Hardcoded credential",
46
+ severity: "critical",
47
+ autoFix: false,
48
+ },
49
+ { regex: /TODO|FIXME|HACK|XXX/, category: "Debt", title: "Open TODO/FIXME", severity: "low", autoFix: false },
50
+ { regex: /console\.\w+\s*\(/, category: "Quality", title: "Console statement", severity: "low", autoFix: true },
51
+ {
52
+ regex: /catch\s*\(\s*\w*\s*\)\s*\{\s*\}/,
53
+ category: "Reliability",
54
+ title: "Empty catch block",
55
+ severity: "medium",
56
+ autoFix: false,
57
+ },
58
+ {
59
+ regex: /any(?:\s*[;,)\]}]|\s*$)/,
60
+ category: "Types",
61
+ title: "Explicit 'any' type",
62
+ severity: "low",
63
+ autoFix: false,
64
+ },
65
+ {
66
+ regex: /(?:\.innerHTML|\.outerHTML)\s*=/,
67
+ category: "Security",
68
+ title: "innerHTML assignment (XSS risk)",
69
+ severity: "high",
70
+ autoFix: false,
71
+ },
72
+ {
73
+ regex: /new\s+Buffer\s*\(/,
74
+ category: "Security",
75
+ title: "Deprecated new Buffer()",
76
+ severity: "high",
77
+ autoFix: true,
78
+ },
79
+ {
80
+ regex: /process\.exit\s*\(/,
81
+ category: "Reliability",
82
+ title: "process.exit() call",
83
+ severity: "medium",
84
+ autoFix: false,
85
+ },
86
+ {
87
+ regex: /(?:setTimeout|setInterval)\s*\(\s*['"]/,
88
+ category: "Security",
89
+ title: "String passed to timer (implicit eval)",
90
+ severity: "high",
91
+ autoFix: false,
92
+ },
93
+ {
94
+ regex: /\.then\s*\([^)]*\)\s*(?:;|\n)\s*(?!\.catch)/,
95
+ category: "Reliability",
96
+ title: "Unhandled promise rejection",
97
+ severity: "medium",
98
+ autoFix: false,
99
+ },
100
+ { regex: /debugger\b/, category: "Quality", title: "Debugger statement", severity: "medium", autoFix: true },
101
+ ];
102
+ // ─── Analysis ───────────────────────────────────────────────────────────────
103
+ function analyzeFile(filepath, baseDir) {
104
+ const findings = [];
105
+ let content;
106
+ try {
107
+ content = readFileSync(filepath, "utf-8");
108
+ }
109
+ catch {
110
+ return findings;
111
+ }
112
+ const lines = content.split("\n");
113
+ const rel = relative(baseDir, filepath);
114
+ for (let i = 0; i < lines.length; i++) {
115
+ const line = lines[i];
116
+ const trimmed = line.trim();
117
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*"))
118
+ continue;
119
+ for (const pattern of QUICK_PATTERNS) {
120
+ if (pattern.regex.test(line)) {
121
+ findings.push({
122
+ file: rel,
123
+ line: i + 1,
124
+ severity: pattern.severity,
125
+ category: pattern.category,
126
+ title: pattern.title,
127
+ autoFixable: pattern.autoFix,
128
+ });
129
+ }
130
+ }
131
+ }
132
+ return findings;
133
+ }
134
+ function buildDigest(allFindings) {
135
+ const critical = allFindings.filter((f) => f.severity === "critical").length;
136
+ const high = allFindings.filter((f) => f.severity === "high").length;
137
+ const medium = allFindings.filter((f) => f.severity === "medium").length;
138
+ const low = allFindings.filter((f) => f.severity === "low").length;
139
+ const autoFixable = allFindings.filter((f) => f.autoFixable).length;
140
+ const riskScore = Math.max(0, 100 - critical * 20 - high * 10 - medium * 4 - low * 1);
141
+ // Top categories
142
+ const catMap = new Map();
143
+ for (const f of allFindings)
144
+ catMap.set(f.category, (catMap.get(f.category) || 0) + 1);
145
+ const topCategories = [...catMap.entries()]
146
+ .sort((a, b) => b[1] - a[1])
147
+ .slice(0, 5)
148
+ .map(([category, count]) => ({ category, count }));
149
+ // Hot files
150
+ const fileMap = new Map();
151
+ for (const f of allFindings)
152
+ fileMap.set(f.file, (fileMap.get(f.file) || 0) + 1);
153
+ const hotFiles = [...fileMap.entries()]
154
+ .sort((a, b) => b[1] - a[1])
155
+ .slice(0, 5)
156
+ .map(([file, count]) => ({ file, count }));
157
+ // Action items
158
+ const actionItems = [];
159
+ if (critical > 0)
160
+ actionItems.push(`Fix ${critical} critical finding(s) immediately`);
161
+ if (high > 0)
162
+ actionItems.push(`Address ${high} high-severity finding(s) before merge`);
163
+ if (autoFixable > 0)
164
+ actionItems.push(`${autoFixable} finding(s) can be auto-fixed`);
165
+ if (hotFiles.length > 0)
166
+ actionItems.push(`Focus on ${hotFiles[0].file} (${hotFiles[0].count} findings)`);
167
+ // Start here — top 5 most impactful
168
+ const startHere = allFindings.filter((f) => f.severity === "critical" || f.severity === "high").slice(0, 5);
169
+ const badge = riskScore >= 80 ? "LOW RISK" : riskScore >= 50 ? "MODERATE RISK" : "HIGH RISK";
170
+ return {
171
+ riskScore,
172
+ badge,
173
+ totalFindings: allFindings.length,
174
+ critical,
175
+ high,
176
+ medium,
177
+ low,
178
+ autoFixable,
179
+ topCategories,
180
+ hotFiles,
181
+ actionItems,
182
+ startHere,
183
+ };
184
+ }
185
+ // ─── CLI ────────────────────────────────────────────────────────────────────
186
+ export function runReviewDigest(argv) {
187
+ if (argv.includes("--help") || argv.includes("-h")) {
188
+ console.log(`
189
+ judges review-digest — Generate concise, role-appropriate review summaries
190
+
191
+ Usage:
192
+ judges review-digest [dir]
193
+ judges review-digest src/ --format json
194
+ judges review-digest src/ --out digest.md
195
+
196
+ Options:
197
+ [dir] Directory to scan (default: .)
198
+ --format json JSON output
199
+ --out <file> Write digest to file
200
+ --help, -h Show this help
201
+
202
+ Generates: risk score, top categories, hot files, action items,
203
+ "start here" list of most impactful findings, auto-fix counts.
204
+ `);
205
+ return;
206
+ }
207
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
208
+ const outFile = argv.find((_a, i) => argv[i - 1] === "--out");
209
+ const dir = argv.find((a) => !a.startsWith("-") &&
210
+ argv.indexOf(a) > 0 &&
211
+ argv[argv.indexOf(a) - 1] !== "--format" &&
212
+ argv[argv.indexOf(a) - 1] !== "--out") || ".";
213
+ const files = collectFiles(dir);
214
+ const allFindings = [];
215
+ for (const f of files)
216
+ allFindings.push(...analyzeFile(f, dir));
217
+ const digest = buildDigest(allFindings);
218
+ if (format === "json") {
219
+ const json = JSON.stringify({ digest, findings: allFindings, timestamp: new Date().toISOString() }, null, 2);
220
+ if (outFile) {
221
+ writeFileSync(outFile, json, "utf-8");
222
+ console.log(`Digest written to ${outFile}`);
223
+ }
224
+ else
225
+ console.log(json);
226
+ }
227
+ else {
228
+ const icon = digest.riskScore >= 80 ? "✅" : digest.riskScore >= 50 ? "⚠️ " : "❌";
229
+ let out = `\n Review Digest: ${icon} ${digest.badge} (${digest.riskScore}/100)\n ─────────────────────────────\n`;
230
+ out += ` Findings: ${digest.totalFindings} (${digest.critical} critical, ${digest.high} high, ${digest.medium} medium, ${digest.low} low)\n`;
231
+ out += ` Auto-fixable: ${digest.autoFixable}\n\n`;
232
+ if (digest.actionItems.length > 0) {
233
+ out += ` Action Items:\n`;
234
+ for (const item of digest.actionItems)
235
+ out += ` → ${item}\n`;
236
+ out += `\n`;
237
+ }
238
+ if (digest.startHere.length > 0) {
239
+ out += ` Start Here (highest impact):\n`;
240
+ for (const f of digest.startHere) {
241
+ const icon2 = f.severity === "critical" ? "🔴" : "🟡";
242
+ out += ` ${icon2} [${f.category}] ${f.title} — ${f.file}:${f.line}\n`;
243
+ }
244
+ out += `\n`;
245
+ }
246
+ if (digest.hotFiles.length > 0) {
247
+ out += ` Hot Files:\n`;
248
+ for (const h of digest.hotFiles)
249
+ out += ` ${h.file} — ${h.count} finding(s)\n`;
250
+ out += `\n`;
251
+ }
252
+ if (digest.topCategories.length > 0) {
253
+ out += ` Top Categories:\n`;
254
+ for (const c of digest.topCategories)
255
+ out += ` ${c.category}: ${c.count}\n`;
256
+ out += `\n`;
257
+ }
258
+ if (outFile) {
259
+ writeFileSync(outFile, out, "utf-8");
260
+ console.log(`Digest written to ${outFile}`);
261
+ }
262
+ else
263
+ console.log(out);
264
+ }
265
+ }
266
+ //# sourceMappingURL=review-digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-digest.js","sourceRoot":"","sources":["../../src/commands/review-digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review focus — prioritize review attention for AI-generated changes.
3
+ */
4
+ export declare function runReviewFocus(argv: string[]): void;
5
+ //# sourceMappingURL=review-focus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-focus.d.ts","sourceRoot":"","sources":["../../src/commands/review-focus.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6JH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuEnD"}