@kevinrabun/judges 3.59.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 (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +56 -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/context-blind.d.ts +5 -0
  10. package/dist/commands/context-blind.d.ts.map +1 -0
  11. package/dist/commands/context-blind.js +273 -0
  12. package/dist/commands/context-blind.js.map +1 -0
  13. package/dist/commands/finding-budget.d.ts +5 -0
  14. package/dist/commands/finding-budget.d.ts.map +1 -0
  15. package/dist/commands/finding-budget.js +233 -0
  16. package/dist/commands/finding-budget.js.map +1 -0
  17. package/dist/commands/hallucination-detect.d.ts +5 -0
  18. package/dist/commands/hallucination-detect.d.ts.map +1 -0
  19. package/dist/commands/hallucination-detect.js +351 -0
  20. package/dist/commands/hallucination-detect.js.map +1 -0
  21. package/dist/commands/over-abstraction.d.ts +5 -0
  22. package/dist/commands/over-abstraction.d.ts.map +1 -0
  23. package/dist/commands/over-abstraction.js +308 -0
  24. package/dist/commands/over-abstraction.js.map +1 -0
  25. package/dist/commands/review-digest.d.ts +5 -0
  26. package/dist/commands/review-digest.d.ts.map +1 -0
  27. package/dist/commands/review-digest.js +266 -0
  28. package/dist/commands/review-digest.js.map +1 -0
  29. package/dist/commands/security-theater.d.ts +5 -0
  30. package/dist/commands/security-theater.d.ts.map +1 -0
  31. package/dist/commands/security-theater.js +279 -0
  32. package/dist/commands/security-theater.js.map +1 -0
  33. package/dist/commands/stale-pattern.d.ts +5 -0
  34. package/dist/commands/stale-pattern.d.ts.map +1 -0
  35. package/dist/commands/stale-pattern.js +294 -0
  36. package/dist/commands/stale-pattern.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Adoption-track — measure team-level Judges adoption metrics from local data.
3
+ */
4
+ import { readFileSync, readdirSync, statSync, existsSync } 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"]);
8
+ function collectFiles(dir, max = 500) {
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
+ function analyzeConfig(dir) {
41
+ const configPaths = [
42
+ join(dir, ".judgesrc"),
43
+ join(dir, ".judgesrc.json"),
44
+ join(dir, "judgesrc.json"),
45
+ join(dir, ".judges.json"),
46
+ ];
47
+ for (const p of configPaths) {
48
+ if (existsSync(p)) {
49
+ try {
50
+ const raw = readFileSync(p, "utf-8");
51
+ const config = JSON.parse(raw);
52
+ let completeness = 20; // Base for having a config at all
53
+ if (config.preset)
54
+ completeness += 15;
55
+ if (config.minSeverity)
56
+ completeness += 10;
57
+ if (config.judges && Object.keys(config.judges).length > 0)
58
+ completeness += 20;
59
+ if (config.disabledRules && config.disabledRules.length > 0)
60
+ completeness += 10;
61
+ if (config.ruleOverrides && Object.keys(config.ruleOverrides).length > 0)
62
+ completeness += 15;
63
+ if (config.disabledJudges && config.disabledJudges.length > 0)
64
+ completeness += 10;
65
+ return { config, completeness: Math.min(100, completeness) };
66
+ }
67
+ catch {
68
+ /* malformed config */
69
+ }
70
+ }
71
+ }
72
+ // Check package.json for judges config
73
+ const pkgPath = join(dir, "package.json");
74
+ if (existsSync(pkgPath)) {
75
+ try {
76
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
77
+ if (pkg.judges || pkg.judgesConfig) {
78
+ return { config: (pkg.judges || pkg.judgesConfig), completeness: 30 };
79
+ }
80
+ }
81
+ catch {
82
+ /* skip */
83
+ }
84
+ }
85
+ return { config: null, completeness: 0 };
86
+ }
87
+ // ─── Suppression tracking ───────────────────────────────────────────────────
88
+ function countSuppressions(files) {
89
+ let total = 0;
90
+ const categories = new Map();
91
+ for (const f of files) {
92
+ let content;
93
+ try {
94
+ content = readFileSync(f, "utf-8");
95
+ }
96
+ catch {
97
+ continue;
98
+ }
99
+ const suppressions = content.match(/judges-disable|judges-ignore|judges-suppress|noinspection|@suppress/gi) || [];
100
+ total += suppressions.length;
101
+ // Categorize by nearby judge name
102
+ const lines = content.split("\n");
103
+ for (let i = 0; i < lines.length; i++) {
104
+ if (/judges-disable|judges-ignore|judges-suppress/i.test(lines[i])) {
105
+ const ruleMatch = lines[i].match(/(?:judges-(?:disable|ignore|suppress))\s+(\S+)/i);
106
+ const cat = ruleMatch ? ruleMatch[1] : "unspecified";
107
+ categories.set(cat, (categories.get(cat) || 0) + 1);
108
+ }
109
+ }
110
+ }
111
+ return { total, categories };
112
+ }
113
+ // ─── Cold spots (directories with no judges integration) ────────────────────
114
+ function findColdSpots(dir, files) {
115
+ const dirCounts = new Map();
116
+ const dirFiles = new Map();
117
+ for (const f of files) {
118
+ const rel = relative(dir, f);
119
+ const parts = rel.split(/[/\\]/);
120
+ if (parts.length > 1) {
121
+ const topDir = parts[0];
122
+ dirFiles.set(topDir, (dirFiles.get(topDir) || 0) + 1);
123
+ }
124
+ }
125
+ // Directories with code but no suppression comments → likely not being reviewed
126
+ for (const f of files) {
127
+ let content;
128
+ try {
129
+ content = readFileSync(f, "utf-8");
130
+ }
131
+ catch {
132
+ continue;
133
+ }
134
+ const rel = relative(dir, f);
135
+ const parts = rel.split(/[/\\]/);
136
+ if (parts.length > 1) {
137
+ const topDir = parts[0];
138
+ if (/judges-|@judges|judges\.config/i.test(content)) {
139
+ dirCounts.set(topDir, (dirCounts.get(topDir) || 0) + 1);
140
+ }
141
+ }
142
+ }
143
+ // Directories with files but zero judges references
144
+ const coldSpots = [];
145
+ for (const [d, count] of dirFiles) {
146
+ if (count >= 3 && !dirCounts.has(d)) {
147
+ coldSpots.push(d);
148
+ }
149
+ }
150
+ return coldSpots;
151
+ }
152
+ // ─── CLI ────────────────────────────────────────────────────────────────────
153
+ export function runAdoptionTrack(argv) {
154
+ if (argv.includes("--help") || argv.includes("-h")) {
155
+ console.log(`
156
+ judges adoption-track — Measure team-level Judges adoption metrics
157
+
158
+ Usage:
159
+ judges adoption-track [dir]
160
+ judges adoption-track --format json
161
+
162
+ Options:
163
+ [dir] Directory to scan (default: .)
164
+ --format json JSON output
165
+ --help, -h Show this help
166
+
167
+ Measures: config completeness, suppression rate, rule override count,
168
+ cold spots (directories with code but no review engagement),
169
+ adoption health score.
170
+
171
+ Note: All metrics are computed from local files only — no data is sent
172
+ or stored externally.
173
+ `);
174
+ return;
175
+ }
176
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
177
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
178
+ const files = collectFiles(dir);
179
+ const { config, completeness } = analyzeConfig(dir);
180
+ const { total: suppressionTotal, categories: suppressionCats } = countSuppressions(files);
181
+ const coldSpots = findColdSpots(dir, files);
182
+ const suppressionRate = files.length > 0 ? Math.round((suppressionTotal / files.length) * 100) : 0;
183
+ const ruleOverrideCount = config?.ruleOverrides ? Object.keys(config.ruleOverrides).length : 0;
184
+ const disabledCount = config?.disabledJudges?.length || 0;
185
+ // Estimate active vs total judges (heuristic)
186
+ const totalJudgeCount = 60; // Approximate total available judges
187
+ const activeJudgeCount = totalJudgeCount - disabledCount;
188
+ const coverageEstimate = files.length > 0 ? Math.round((activeJudgeCount / totalJudgeCount) * 100) : 0;
189
+ // Health score
190
+ let healthScore = 0;
191
+ healthScore += completeness * 0.3; // Config completeness weight
192
+ healthScore += coverageEstimate * 0.3; // Coverage weight
193
+ healthScore += Math.max(0, 100 - suppressionRate * 2) * 0.2; // Low suppression is good
194
+ healthScore += Math.max(0, 100 - coldSpots.length * 15) * 0.2; // Few cold spots is good
195
+ healthScore = Math.round(Math.min(100, Math.max(0, healthScore)));
196
+ const metrics = {
197
+ configCompleteness: completeness,
198
+ coverageEstimate,
199
+ suppressionRate,
200
+ ruleOverrideCount,
201
+ activeJudgeCount,
202
+ totalJudgeCount,
203
+ coldSpots,
204
+ healthScore,
205
+ };
206
+ if (format === "json") {
207
+ console.log(JSON.stringify({
208
+ metrics,
209
+ suppressionCategories: Object.fromEntries(suppressionCats),
210
+ filesScanned: files.length,
211
+ timestamp: new Date().toISOString(),
212
+ }, null, 2));
213
+ }
214
+ else {
215
+ const badge = healthScore >= 80 ? "✅ HIGH ADOPTION" : healthScore >= 50 ? "⚠️ PARTIAL ADOPTION" : "❌ LOW ADOPTION";
216
+ console.log(`\n Adoption Track: ${badge} (${healthScore}/100)\n ─────────────────────────────`);
217
+ console.log(` Files scanned: ${files.length}`);
218
+ console.log(` Config completeness: ${completeness}%${config ? "" : " (no config found)"}`);
219
+ console.log(` Judge coverage: ${coverageEstimate}% (${activeJudgeCount}/${totalJudgeCount} judges active)`);
220
+ console.log(` Suppression rate: ${suppressionRate}% (${suppressionTotal} suppressions)`);
221
+ console.log(` Rule overrides: ${ruleOverrideCount}`);
222
+ if (suppressionCats.size > 0) {
223
+ console.log(`\n Suppressed categories:`);
224
+ for (const [cat, count] of [...suppressionCats.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10)) {
225
+ console.log(` ${cat}: ${count}`);
226
+ }
227
+ }
228
+ if (coldSpots.length > 0) {
229
+ console.log(`\n Cold spots (low/no engagement):`);
230
+ for (const spot of coldSpots.slice(0, 10))
231
+ console.log(` 📁 ${spot}/`);
232
+ }
233
+ console.log(`\n Recommendations:`);
234
+ if (completeness < 50)
235
+ console.log(` → Create or improve .judgesrc configuration`);
236
+ if (disabledCount > 10)
237
+ console.log(` → Review disabled judges — ${disabledCount} disabled may be excessive`);
238
+ if (suppressionRate > 20)
239
+ console.log(` → High suppression rate (${suppressionRate}%) — review if suppressions are justified`);
240
+ if (coldSpots.length > 0)
241
+ console.log(` → Engage cold-spot directories: ${coldSpots.slice(0, 3).join(", ")}`);
242
+ if (healthScore >= 80)
243
+ console.log(` → Adoption is healthy — maintain current practices`);
244
+ console.log();
245
+ }
246
+ }
247
+ //# sourceMappingURL=adoption-track.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adoption-track.js","sourceRoot":"","sources":["../../src/commands/adoption-track.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Context blind — flag when AI reinvents utilities already present in the codebase.
3
+ */
4
+ export declare function runContextBlind(argv: string[]): void;
5
+ //# sourceMappingURL=context-blind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-blind.d.ts","sourceRoot":"","sources":["../../src/commands/context-blind.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmOH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoEpD"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Context blind — flag when AI reinvents utilities already present in the codebase.
3
+ */
4
+ import { readFileSync, readdirSync, statSync } from "fs";
5
+ import { join, extname, basename } 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
+ function buildProjectInventory(files) {
41
+ const assets = [];
42
+ for (const filepath of files) {
43
+ let content;
44
+ try {
45
+ content = readFileSync(filepath, "utf-8");
46
+ }
47
+ catch {
48
+ continue;
49
+ }
50
+ const lines = content.split("\n");
51
+ for (let i = 0; i < lines.length; i++) {
52
+ const line = lines[i];
53
+ // Exported functions
54
+ const funcMatch = line.match(/export\s+(?:async\s+)?function\s+(\w+)/);
55
+ if (funcMatch) {
56
+ const name = funcMatch[1];
57
+ let category = "general";
58
+ if (/format|stringify|serialize|render|display/i.test(name))
59
+ category = "formatting";
60
+ else if (/validate|check|verify|assert|is[A-Z]/i.test(name))
61
+ category = "validation";
62
+ else if (/parse|deserialize|decode|extract/i.test(name))
63
+ category = "parsing";
64
+ else if (/log|error|warn|debug|trace|info/i.test(name))
65
+ category = "logging";
66
+ else if (/fetch|request|get|post|put|delete|api|http/i.test(name))
67
+ category = "http";
68
+ else if (/config|setting|option|env/i.test(name))
69
+ category = "config";
70
+ else if (/hash|encrypt|decrypt|sign|token|auth/i.test(name))
71
+ category = "security";
72
+ else if (/sort|filter|map|reduce|transform|convert/i.test(name))
73
+ category = "data-transform";
74
+ else if (/path|file|dir|folder|read|write/i.test(name))
75
+ category = "filesystem";
76
+ else if (/date|time|duration|format.*date|parse.*date/i.test(name))
77
+ category = "datetime";
78
+ assets.push({ name, type: "function", file: filepath, line: i + 1, category });
79
+ }
80
+ // Exported classes
81
+ const classMatch = line.match(/export\s+class\s+(\w+)/);
82
+ if (classMatch) {
83
+ const name = classMatch[1];
84
+ let category = "general";
85
+ if (/Error|Exception/i.test(name))
86
+ category = "error";
87
+ else if (/Logger|Log/i.test(name))
88
+ category = "logging";
89
+ else if (/Client|Service|Api/i.test(name))
90
+ category = "http";
91
+ else if (/Config|Settings/i.test(name))
92
+ category = "config";
93
+ else if (/Cache/i.test(name))
94
+ category = "cache";
95
+ else if (/Validator/i.test(name))
96
+ category = "validation";
97
+ assets.push({ name, type: "class", file: filepath, line: i + 1, category });
98
+ }
99
+ // Exported consts (utility objects, instances)
100
+ const constMatch = line.match(/export\s+const\s+(\w+)/);
101
+ if (constMatch) {
102
+ assets.push({ name: constMatch[1], type: "const", file: filepath, line: i + 1, category: "general" });
103
+ }
104
+ }
105
+ }
106
+ return assets;
107
+ }
108
+ function analyzeFile(filepath, inventory) {
109
+ const issues = [];
110
+ let content;
111
+ try {
112
+ content = readFileSync(filepath, "utf-8");
113
+ }
114
+ catch {
115
+ return issues;
116
+ }
117
+ const lines = content.split("\n");
118
+ const _fname = basename(filepath);
119
+ for (let i = 0; i < lines.length; i++) {
120
+ const line = lines[i];
121
+ // New function that duplicates an existing exported function's purpose
122
+ const newFuncMatch = line.match(/(?:function|const)\s+(\w+)\s*(?:=\s*(?:async\s*)?\(|\()/);
123
+ if (newFuncMatch && !line.includes("export")) {
124
+ const name = newFuncMatch[1];
125
+ // Check if a similarly-named exported function exists elsewhere
126
+ for (const asset of inventory) {
127
+ if (asset.file === filepath)
128
+ continue;
129
+ if (asset.name.toLowerCase() === name.toLowerCase() && asset.type === "function") {
130
+ issues.push({
131
+ file: filepath,
132
+ line: i + 1,
133
+ issue: "Reinvents existing project function",
134
+ severity: "high",
135
+ detail: `\`${name}\` already exported from \`${basename(asset.file)}:${asset.line}\` — reuse instead of reimplementing`,
136
+ });
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ // Hand-rolled validation when project has validators
142
+ const hasValidators = inventory.some((a) => a.category === "validation");
143
+ if (hasValidators && /(?:if\s*\(\s*typeof\s+\w+\s*!==?\s*['"]|if\s*\(\s*!\w+\s*\|\|\s*typeof)/.test(line)) {
144
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
145
+ const typeChecks = (block.match(/typeof\s+\w+/g) || []).length;
146
+ if (typeChecks >= 3) {
147
+ const validator = inventory.find((a) => a.category === "validation");
148
+ issues.push({
149
+ file: filepath,
150
+ line: i + 1,
151
+ issue: "Hand-rolled validation (project has validators)",
152
+ severity: "medium",
153
+ detail: `${typeChecks} inline type checks — project has validation utilities (e.g., \`${validator?.name}\` in ${validator ? basename(validator.file) : "?"})`,
154
+ });
155
+ }
156
+ }
157
+ // Custom error class when project has error hierarchy
158
+ if (/class\s+\w*Error\s+extends\s+Error/.test(line) && !line.includes("export")) {
159
+ const existingErrors = inventory.filter((a) => a.category === "error");
160
+ if (existingErrors.length > 0) {
161
+ issues.push({
162
+ file: filepath,
163
+ line: i + 1,
164
+ issue: "New error class (project has error hierarchy)",
165
+ severity: "medium",
166
+ detail: `Project already has ${existingErrors.length} error class(es) — extend existing hierarchy instead`,
167
+ });
168
+ }
169
+ }
170
+ // New HTTP client setup when project has one
171
+ if (/(?:axios\.create|new\s+(?:HttpClient|FetchClient)|createHttpClient)/i.test(line)) {
172
+ const existingClients = inventory.filter((a) => a.category === "http" && a.type === "class");
173
+ if (existingClients.length > 0) {
174
+ issues.push({
175
+ file: filepath,
176
+ line: i + 1,
177
+ issue: "New HTTP client (project has one)",
178
+ severity: "medium",
179
+ detail: `Project already has HTTP client(s) (e.g., \`${existingClients[0].name}\`) — reuse the configured instance`,
180
+ });
181
+ }
182
+ }
183
+ // New logger setup when project has one
184
+ if (/(?:new\s+Logger|createLogger|winston\.create|pino\()/i.test(line)) {
185
+ const existingLoggers = inventory.filter((a) => a.category === "logging");
186
+ if (existingLoggers.length > 0) {
187
+ issues.push({
188
+ file: filepath,
189
+ line: i + 1,
190
+ issue: "New logger (project has logging utility)",
191
+ severity: "medium",
192
+ detail: `Project already has logging (e.g., \`${existingLoggers[0].name}\`) — reuse instead of creating another`,
193
+ });
194
+ }
195
+ }
196
+ // Config loading when project has config module
197
+ if (/(?:dotenv\.config|process\.env\.\w+.*process\.env\.\w+.*process\.env)/i.test(line)) {
198
+ const existingConfig = inventory.filter((a) => a.category === "config");
199
+ if (existingConfig.length > 0) {
200
+ issues.push({
201
+ file: filepath,
202
+ line: i + 1,
203
+ issue: "Direct env access (project has config module)",
204
+ severity: "low",
205
+ detail: `Project has config utilities (e.g., \`${existingConfig[0].name}\`) — use centralized config instead of direct env access`,
206
+ });
207
+ }
208
+ }
209
+ }
210
+ return issues;
211
+ }
212
+ // ─── CLI ────────────────────────────────────────────────────────────────────
213
+ export function runContextBlind(argv) {
214
+ if (argv.includes("--help") || argv.includes("-h")) {
215
+ console.log(`
216
+ judges context-blind — Flag AI code that reinvents existing project utilities
217
+
218
+ Usage:
219
+ judges context-blind [dir]
220
+ judges context-blind src/ --format json
221
+
222
+ Options:
223
+ [dir] Directory to scan (default: .)
224
+ --format json JSON output
225
+ --help, -h Show this help
226
+
227
+ Checks: duplicate function names, hand-rolled validation, redundant error classes,
228
+ new HTTP clients, new loggers, direct env access when project has config module.
229
+ `);
230
+ return;
231
+ }
232
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
233
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
234
+ const files = collectFiles(dir);
235
+ const inventory = buildProjectInventory(files);
236
+ const allIssues = [];
237
+ for (const f of files)
238
+ allIssues.push(...analyzeFile(f, inventory));
239
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
240
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
241
+ const score = Math.max(0, 100 - highCount * 10 - medCount * 5);
242
+ if (format === "json") {
243
+ console.log(JSON.stringify({
244
+ issues: allIssues,
245
+ score,
246
+ inventory: {
247
+ functions: inventory.filter((a) => a.type === "function").length,
248
+ classes: inventory.filter((a) => a.type === "class").length,
249
+ },
250
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
251
+ timestamp: new Date().toISOString(),
252
+ }, null, 2));
253
+ }
254
+ else {
255
+ const badge = score >= 80 ? "✅ CONTEXT-AWARE" : score >= 50 ? "⚠️ BLIND SPOTS" : "❌ REINVENTING";
256
+ console.log(`\n Context Blind: ${badge} (${score}/100)\n ─────────────────────────────`);
257
+ console.log(` Project inventory: ${inventory.filter((a) => a.type === "function").length} functions, ${inventory.filter((a) => a.type === "class").length} classes`);
258
+ if (allIssues.length === 0) {
259
+ console.log(" No reinvention detected.\n");
260
+ return;
261
+ }
262
+ for (const issue of allIssues.slice(0, 25)) {
263
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
264
+ console.log(` ${icon} ${issue.issue}`);
265
+ console.log(` ${issue.file}:${issue.line}`);
266
+ console.log(` ${issue.detail}`);
267
+ }
268
+ if (allIssues.length > 25)
269
+ console.log(` ... and ${allIssues.length - 25} more`);
270
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
271
+ }
272
+ }
273
+ //# sourceMappingURL=context-blind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-blind.js","sourceRoot":"","sources":["../../src/commands/context-blind.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-budget — manage finding volume per PR to prevent alert fatigue.
3
+ */
4
+ export declare function runFindingBudget(argv: string[]): void;
5
+ //# sourceMappingURL=finding-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-budget.d.ts","sourceRoot":"","sources":["../../src/commands/finding-budget.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsMH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuFrD"}