@kevinrabun/judges 3.58.0 → 3.59.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/api-misuse.d.ts +5 -0
  6. package/dist/commands/api-misuse.d.ts.map +1 -0
  7. package/dist/commands/api-misuse.js +261 -0
  8. package/dist/commands/api-misuse.js.map +1 -0
  9. package/dist/commands/completion-audit.d.ts +5 -0
  10. package/dist/commands/completion-audit.d.ts.map +1 -0
  11. package/dist/commands/completion-audit.js +297 -0
  12. package/dist/commands/completion-audit.js.map +1 -0
  13. package/dist/commands/cross-file-consistency.d.ts +5 -0
  14. package/dist/commands/cross-file-consistency.d.ts.map +1 -0
  15. package/dist/commands/cross-file-consistency.js +255 -0
  16. package/dist/commands/cross-file-consistency.js.map +1 -0
  17. package/dist/commands/example-leak.d.ts +5 -0
  18. package/dist/commands/example-leak.d.ts.map +1 -0
  19. package/dist/commands/example-leak.js +233 -0
  20. package/dist/commands/example-leak.js.map +1 -0
  21. package/dist/commands/logic-lint.d.ts +5 -0
  22. package/dist/commands/logic-lint.d.ts.map +1 -0
  23. package/dist/commands/logic-lint.js +256 -0
  24. package/dist/commands/logic-lint.js.map +1 -0
  25. package/dist/commands/phantom-import.d.ts +5 -0
  26. package/dist/commands/phantom-import.d.ts.map +1 -0
  27. package/dist/commands/phantom-import.js +261 -0
  28. package/dist/commands/phantom-import.js.map +1 -0
  29. package/dist/commands/review-focus.d.ts +5 -0
  30. package/dist/commands/review-focus.d.ts.map +1 -0
  31. package/dist/commands/review-focus.js +197 -0
  32. package/dist/commands/review-focus.js.map +1 -0
  33. package/dist/commands/spec-conform.d.ts +5 -0
  34. package/dist/commands/spec-conform.d.ts.map +1 -0
  35. package/dist/commands/spec-conform.js +305 -0
  36. package/dist/commands/spec-conform.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Cross-file consistency — verify naming and pattern consistency across files.
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 analyzeConsistency(files) {
41
+ const issues = [];
42
+ // Collect cross-file data
43
+ const allFunctions = [];
44
+ const errorPatterns = [];
45
+ const importStyles = new Map();
46
+ const returnPatterns = new Map();
47
+ const logStyles = [];
48
+ for (const filepath of files) {
49
+ let content;
50
+ try {
51
+ content = readFileSync(filepath, "utf-8");
52
+ }
53
+ catch {
54
+ continue;
55
+ }
56
+ const lines = content.split("\n");
57
+ const fname = basename(filepath);
58
+ for (let i = 0; i < lines.length; i++) {
59
+ const line = lines[i];
60
+ const trimmed = line.trim();
61
+ // Collect function signatures
62
+ const funcMatch = trimmed.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)/);
63
+ if (funcMatch) {
64
+ allFunctions.push({ name: funcMatch[1], params: funcMatch[2], file: filepath, line: i + 1 });
65
+ }
66
+ // Collect error handling patterns
67
+ if (/catch\s*\(/.test(trimmed)) {
68
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
69
+ if (/console\.error/.test(block))
70
+ errorPatterns.push({ pattern: "console.error", file: filepath, line: i + 1 });
71
+ else if (/logger\.error/.test(block))
72
+ errorPatterns.push({ pattern: "logger.error", file: filepath, line: i + 1 });
73
+ else if (/throw/.test(block))
74
+ errorPatterns.push({ pattern: "rethrow", file: filepath, line: i + 1 });
75
+ else if (/return/.test(block))
76
+ errorPatterns.push({ pattern: "return-on-error", file: filepath, line: i + 1 });
77
+ }
78
+ // Collect import styles for same module
79
+ const importMatch = trimmed.match(/import\s+(?:(\w+)|(\{[^}]+\}))\s+from\s+['"]([^'"]+)['"]/);
80
+ if (importMatch) {
81
+ const mod = importMatch[3];
82
+ const entry = importStyles.get(mod) || { default: 0, named: 0, file: filepath, line: i + 1 };
83
+ if (importMatch[1])
84
+ entry.default++;
85
+ if (importMatch[2])
86
+ entry.named++;
87
+ importStyles.set(mod, entry);
88
+ }
89
+ // Collect logging styles
90
+ if (/console\.(log|warn|error|info|debug)\s*\(/.test(trimmed)) {
91
+ logStyles.push({ style: "console", file: filepath, line: i + 1 });
92
+ }
93
+ else if (/logger\.(log|warn|error|info|debug)\s*\(/.test(trimmed)) {
94
+ logStyles.push({ style: "logger", file: filepath, line: i + 1 });
95
+ }
96
+ // Collect return type patterns for similar functions
97
+ const retMatch = trimmed.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\([^)]*\)\s*:\s*([\w<>[\]| ]+)/);
98
+ if (retMatch) {
99
+ const prefix = retMatch[1].replace(/\d+$/, "").replace(/[A-Z][a-z]+$/, "");
100
+ if (prefix.length > 2) {
101
+ const entry = returnPatterns.get(prefix) || { patterns: new Set(), files: [] };
102
+ entry.patterns.add(retMatch[2].trim());
103
+ entry.files.push(`${fname}:${i + 1}`);
104
+ returnPatterns.set(prefix, entry);
105
+ }
106
+ }
107
+ }
108
+ }
109
+ // Detect inconsistencies
110
+ // 1. Similar function names with inconsistent patterns
111
+ const nameGroups = new Map();
112
+ for (const func of allFunctions) {
113
+ const prefix = func.name
114
+ .replace(/\d+$/, "")
115
+ .replace(/[A-Z][a-z]+$/, "")
116
+ .toLowerCase();
117
+ if (prefix.length > 3) {
118
+ const group = nameGroups.get(prefix) || [];
119
+ group.push(func);
120
+ nameGroups.set(prefix, group);
121
+ }
122
+ }
123
+ for (const [_prefix, group] of nameGroups) {
124
+ if (group.length >= 2) {
125
+ const paramCounts = new Set(group.map((f) => f.params.split(",").filter((p) => p.trim()).length));
126
+ if (paramCounts.size > 1 && group.length <= 5) {
127
+ const first = group[0];
128
+ issues.push({
129
+ file: first.file,
130
+ line: first.line,
131
+ issue: "Inconsistent parameter count across similar functions",
132
+ severity: "medium",
133
+ detail: `Functions with similar names have different parameter counts: ${group.map((f) => `${f.name}(${f.params.split(",").filter((p) => p.trim()).length} params)`).join(", ")}`,
134
+ });
135
+ }
136
+ }
137
+ }
138
+ // 2. Mixed error handling patterns
139
+ if (errorPatterns.length > 3) {
140
+ const patternCounts = new Map();
141
+ for (const ep of errorPatterns)
142
+ patternCounts.set(ep.pattern, (patternCounts.get(ep.pattern) || 0) + 1);
143
+ if (patternCounts.size > 2) {
144
+ const minority = [...patternCounts.entries()].sort((a, b) => a[1] - b[1])[0];
145
+ const sample = errorPatterns.find((ep) => ep.pattern === minority[0]);
146
+ if (sample) {
147
+ issues.push({
148
+ file: sample.file,
149
+ line: sample.line,
150
+ issue: "Inconsistent error handling pattern",
151
+ severity: "medium",
152
+ detail: `Project uses ${patternCounts.size} different error handling patterns — \`${minority[0]}\` is used least (${minority[1]}×)`,
153
+ });
154
+ }
155
+ }
156
+ }
157
+ // 3. Mixed import styles for same module
158
+ for (const [mod, styles] of importStyles) {
159
+ if (styles.default > 0 && styles.named > 0) {
160
+ issues.push({
161
+ file: styles.file,
162
+ line: styles.line,
163
+ issue: "Mixed import style for same module",
164
+ severity: "low",
165
+ detail: `\`${mod}\` imported both as default (${styles.default}×) and named (${styles.named}×) — AI may have used wrong import style`,
166
+ });
167
+ }
168
+ }
169
+ // 4. Mixed logging styles
170
+ if (logStyles.length > 5) {
171
+ const consoleCount = logStyles.filter((l) => l.style === "console").length;
172
+ const loggerCount = logStyles.filter((l) => l.style === "logger").length;
173
+ if (consoleCount > 0 && loggerCount > 0) {
174
+ const minority = consoleCount < loggerCount
175
+ ? logStyles.find((l) => l.style === "console")
176
+ : logStyles.find((l) => l.style === "logger");
177
+ if (minority) {
178
+ issues.push({
179
+ file: minority.file,
180
+ line: minority.line,
181
+ issue: "Mixed logging approach",
182
+ severity: "low",
183
+ detail: `Project uses both console.* (${consoleCount}×) and logger.* (${loggerCount}×) — standardize on one`,
184
+ });
185
+ }
186
+ }
187
+ }
188
+ // 5. Similar functions with inconsistent return types
189
+ for (const [_prefix, ret] of returnPatterns) {
190
+ if (ret.patterns.size > 1 && ret.files.length > 1) {
191
+ issues.push({
192
+ file: ret.files[0].split(":")[0],
193
+ line: 1,
194
+ issue: "Inconsistent return types for similar functions",
195
+ severity: "low",
196
+ detail: `Functions in the same family return different types: ${[...ret.patterns].join(", ")}`,
197
+ });
198
+ }
199
+ }
200
+ return issues;
201
+ }
202
+ // ─── CLI ────────────────────────────────────────────────────────────────────
203
+ export function runCrossFileConsistency(argv) {
204
+ if (argv.includes("--help") || argv.includes("-h")) {
205
+ console.log(`
206
+ judges cross-file-consistency — Verify naming and pattern consistency across files
207
+
208
+ Usage:
209
+ judges cross-file-consistency [dir]
210
+ judges cross-file-consistency src/ --format json
211
+
212
+ Options:
213
+ [dir] Directory to scan (default: .)
214
+ --format json JSON output
215
+ --help, -h Show this help
216
+
217
+ Checks: inconsistent parameter counts, mixed error handling, mixed import styles,
218
+ mixed logging approaches, inconsistent return types for similar functions.
219
+ `);
220
+ return;
221
+ }
222
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
223
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
224
+ const files = collectFiles(dir);
225
+ const allIssues = analyzeConsistency(files);
226
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
227
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
228
+ const score = Math.max(0, 100 - highCount * 10 - medCount * 5 - allIssues.filter((i) => i.severity === "low").length * 2);
229
+ if (format === "json") {
230
+ console.log(JSON.stringify({
231
+ issues: allIssues,
232
+ score,
233
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
234
+ timestamp: new Date().toISOString(),
235
+ }, null, 2));
236
+ }
237
+ else {
238
+ const badge = score >= 80 ? "✅ CONSISTENT" : score >= 50 ? "⚠️ MIXED" : "❌ INCONSISTENT";
239
+ console.log(`\n Cross-File Consistency: ${badge} (${score}/100)\n ─────────────────────────────`);
240
+ if (allIssues.length === 0) {
241
+ console.log(" No cross-file inconsistencies detected.\n");
242
+ return;
243
+ }
244
+ for (const issue of allIssues.slice(0, 25)) {
245
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
246
+ console.log(` ${icon} ${issue.issue}`);
247
+ console.log(` ${issue.file}:${issue.line}`);
248
+ console.log(` ${issue.detail}`);
249
+ }
250
+ if (allIssues.length > 25)
251
+ console.log(` ... and ${allIssues.length - 25} more`);
252
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
253
+ }
254
+ }
255
+ //# sourceMappingURL=cross-file-consistency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-file-consistency.js","sourceRoot":"","sources":["../../src/commands/cross-file-consistency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Example leak — detect AI-copied example/placeholder code left in production.
3
+ */
4
+ export declare function runExampleLeak(argv: string[]): void;
5
+ //# sourceMappingURL=example-leak.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example-leak.d.ts","sourceRoot":"","sources":["../../src/commands/example-leak.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6MH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4DnD"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Example leak — detect AI-copied example/placeholder code left in production.
3
+ */
4
+ import { readFileSync, readdirSync, statSync } from "fs";
5
+ import { join, extname } from "path";
6
+ // ─── File Collection ────────────────────────────────────────────────────────
7
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".rs", ".cs", ".rb"]);
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
+ // ─── Analysis ───────────────────────────────────────────────────────────────
41
+ const PLACEHOLDER_URLS = [
42
+ /https?:\/\/(?:example\.com|localhost:\d+|127\.0\.0\.1:\d+|httpbin\.org|jsonplaceholder\.typicode\.com|reqres\.in|api\.example)/i,
43
+ ];
44
+ const PLACEHOLDER_SECRETS = [
45
+ /['"](?:sk-[a-zA-Z0-9]{20,}|your[-_]?api[-_]?key|REPLACE[-_]?ME|changeme|password123|secret123|test[-_]?secret|my[-_]?secret|dummy[-_]?key|placeholder)['"]/,
46
+ ];
47
+ const EXAMPLE_NAMES = [
48
+ /(?:class|function|const|let|var)\s+(?:MyApp|MyComponent|Example\w*|Demo\w*|HelloWorld|SampleApp|TestApp|FooBar|Foo|Bar|Baz|Qux)\b/,
49
+ ];
50
+ const EXAMPLE_DATA = [
51
+ /['"](?:John Doe|Jane Doe|john@example\.com|jane@example\.com|foo@bar\.com|test@test\.com|user@example\.com|123 Main St|Acme Corp|Lorem ipsum|Alice|Bob)['"]/i,
52
+ ];
53
+ const TUTORIAL_MARKERS = [
54
+ /\/\/\s*(?:Step \d|TODO:?\s*replace|FIXME:?\s*placeholder|HACK:?\s*example|NOTE:?\s*this is (?:a |an )?(?:example|demo|sample|placeholder))/i,
55
+ /#\s*(?:Step \d|TODO:?\s*replace|FIXME:?\s*placeholder)/i,
56
+ ];
57
+ const HARDCODED_PORTS = [/(?:PORT|port)\s*[:=]\s*(?:3000|8080|8000|5000|4200|9090)\b/];
58
+ function analyzeFile(filepath) {
59
+ const issues = [];
60
+ let content;
61
+ try {
62
+ content = readFileSync(filepath, "utf-8");
63
+ }
64
+ catch {
65
+ return issues;
66
+ }
67
+ // Skip test/fixture/example files
68
+ if (/(?:test|spec|fixture|example|demo|sample|mock|stub|__test__|__spec__)/i.test(filepath))
69
+ return issues;
70
+ const lines = content.split("\n");
71
+ for (let i = 0; i < lines.length; i++) {
72
+ const line = lines[i];
73
+ // Placeholder URLs
74
+ for (const pattern of PLACEHOLDER_URLS) {
75
+ if (pattern.test(line)) {
76
+ const url = line.match(pattern)?.[0];
77
+ issues.push({
78
+ file: filepath,
79
+ line: i + 1,
80
+ issue: "Placeholder URL in non-test code",
81
+ severity: "high",
82
+ detail: `\`${url}\` is an example/localhost URL — replace with actual endpoint`,
83
+ });
84
+ break;
85
+ }
86
+ }
87
+ // Placeholder secrets
88
+ for (const pattern of PLACEHOLDER_SECRETS) {
89
+ if (pattern.test(line)) {
90
+ issues.push({
91
+ file: filepath,
92
+ line: i + 1,
93
+ issue: "Placeholder secret/key value",
94
+ severity: "high",
95
+ detail: "Example API key or placeholder secret found — replace with env variable or secret manager",
96
+ });
97
+ break;
98
+ }
99
+ }
100
+ // Example class/function names
101
+ for (const pattern of EXAMPLE_NAMES) {
102
+ if (pattern.test(line)) {
103
+ const name = line.match(/(?:class|function|const|let|var)\s+((?:Example|Demo|HelloWorld|Sample|Test|FooBar|Foo|Bar|Baz|Qux)\w*)/)?.[1];
104
+ if (name) {
105
+ issues.push({
106
+ file: filepath,
107
+ line: i + 1,
108
+ issue: "Example/placeholder name in production",
109
+ severity: "medium",
110
+ detail: `\`${name}\` looks like tutorial code — rename to something domain-specific`,
111
+ });
112
+ }
113
+ break;
114
+ }
115
+ }
116
+ // Example data
117
+ for (const pattern of EXAMPLE_DATA) {
118
+ if (pattern.test(line)) {
119
+ issues.push({
120
+ file: filepath,
121
+ line: i + 1,
122
+ issue: "Example data in non-test code",
123
+ severity: "medium",
124
+ detail: "Placeholder data (John Doe, example.com, etc.) left in production code",
125
+ });
126
+ break;
127
+ }
128
+ }
129
+ // Tutorial markers
130
+ for (const pattern of TUTORIAL_MARKERS) {
131
+ if (pattern.test(line)) {
132
+ issues.push({
133
+ file: filepath,
134
+ line: i + 1,
135
+ issue: "Tutorial comment marker",
136
+ severity: "low",
137
+ detail: "Comment from tutorial/example code — indicates AI-copied scaffold",
138
+ });
139
+ break;
140
+ }
141
+ }
142
+ // Hardcoded ports
143
+ for (const pattern of HARDCODED_PORTS) {
144
+ if (pattern.test(line) && !/process\.env|ENV|config/i.test(line)) {
145
+ issues.push({
146
+ file: filepath,
147
+ line: i + 1,
148
+ issue: "Hardcoded default port",
149
+ severity: "low",
150
+ detail: "Port hardcoded to common default — should come from config or env",
151
+ });
152
+ break;
153
+ }
154
+ }
155
+ // console.log with example text
156
+ if (/console\.log\s*\(\s*['"](?:Hello|Hi|Welcome|It works|Success|TODO|Test)\b/.test(line)) {
157
+ issues.push({
158
+ file: filepath,
159
+ line: i + 1,
160
+ issue: "Example console.log",
161
+ severity: "low",
162
+ detail: "Generic log message from tutorial — remove or replace with structured logging",
163
+ });
164
+ }
165
+ // Empty function bodies that look like stubs
166
+ if (/(?:function|=>)\s*\{[\s]*\}/.test(line) && !/test|spec|mock|stub|noop|placeholder/i.test(line)) {
167
+ issues.push({
168
+ file: filepath,
169
+ line: i + 1,
170
+ issue: "Empty function stub",
171
+ severity: "medium",
172
+ detail: "Function with empty body — may be unfinished AI-generated scaffold",
173
+ });
174
+ }
175
+ }
176
+ return issues;
177
+ }
178
+ // ─── CLI ────────────────────────────────────────────────────────────────────
179
+ export function runExampleLeak(argv) {
180
+ if (argv.includes("--help") || argv.includes("-h")) {
181
+ console.log(`
182
+ judges example-leak — Detect AI-copied example/placeholder code left in production
183
+
184
+ Usage:
185
+ judges example-leak [dir]
186
+ judges example-leak src/ --format json
187
+
188
+ Options:
189
+ [dir] Directory to scan (default: .)
190
+ --format json JSON output
191
+ --help, -h Show this help
192
+
193
+ Checks: placeholder URLs, example API keys, tutorial names, example data (John Doe, Lorem ipsum),
194
+ tutorial comments, hardcoded ports, example console.log messages, empty function stubs.
195
+ `);
196
+ return;
197
+ }
198
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
199
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
200
+ const files = collectFiles(dir);
201
+ const allIssues = [];
202
+ for (const f of files)
203
+ allIssues.push(...analyzeFile(f));
204
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
205
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
206
+ const score = Math.max(0, 100 - highCount * 12 - medCount * 4);
207
+ if (format === "json") {
208
+ console.log(JSON.stringify({
209
+ issues: allIssues,
210
+ score,
211
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
212
+ timestamp: new Date().toISOString(),
213
+ }, null, 2));
214
+ }
215
+ else {
216
+ const badge = score >= 80 ? "✅ CLEAN" : score >= 50 ? "⚠️ LEAKING" : "❌ EXAMPLE CODE";
217
+ console.log(`\n Example Leak: ${badge} (${score}/100)\n ─────────────────────────────`);
218
+ if (allIssues.length === 0) {
219
+ console.log(" No example/placeholder code detected.\n");
220
+ return;
221
+ }
222
+ for (const issue of allIssues.slice(0, 25)) {
223
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
224
+ console.log(` ${icon} ${issue.issue}`);
225
+ console.log(` ${issue.file}:${issue.line}`);
226
+ console.log(` ${issue.detail}`);
227
+ }
228
+ if (allIssues.length > 25)
229
+ console.log(` ... and ${allIssues.length - 25} more`);
230
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
231
+ }
232
+ }
233
+ //# sourceMappingURL=example-leak.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"example-leak.js","sourceRoot":"","sources":["../../src/commands/example-leak.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAYrC,+EAA+E;AAE/E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEtG,SAAS,YAAY,CAAC,GAAW,EAAE,GAAG,GAAG,GAAG;IAC1C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,SAAS,IAAI,CAAC,CAAS;QACrB,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;YAAE,OAAO;QAChC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,CAAC,CAAwB,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG;gBAAE,OAAO;YAChC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,cAAc,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO;gBAAE,SAAS;YACzF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACxB,IAAI,CAAC;gBACH,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;oBAAE,IAAI,CAAC,IAAI,CAAC,CAAC;qBACxC,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,UAAU;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E,MAAM,gBAAgB,GAAG;IACvB,iIAAiI;CAClI,CAAC;AAEF,MAAM,mBAAmB,GAAG;IAC1B,4JAA4J;CAC7J,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,mIAAmI;CACpI,CAAC;AAEF,MAAM,YAAY,GAAG;IACnB,8JAA8J;CAC/J,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,6IAA6I;IAC7I,yDAAyD;CAC1D,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,4DAA4D,CAAC,CAAC;AAEvF,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kCAAkC;IAClC,IAAI,wEAAwE,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAE3G,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,mBAAmB;QACnB,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,KAAK,EAAE,kCAAkC;oBACzC,QAAQ,EAAE,MAAM;oBAChB,MAAM,EAAE,KAAK,GAAG,+DAA+D;iBAChF,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,KAAK,EAAE,8BAA8B;oBACrC,QAAQ,EAAE,MAAM;oBAChB,MAAM,EAAE,2FAA2F;iBACpG,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;YACpC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,wGAAwG,CACzG,EAAE,CAAC,CAAC,CAAC,CAAC;gBACP,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,CAAC,GAAG,CAAC;wBACX,KAAK,EAAE,wCAAwC;wBAC/C,QAAQ,EAAE,QAAQ;wBAClB,MAAM,EAAE,KAAK,IAAI,mEAAmE;qBACrF,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;QAED,eAAe;QACf,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,KAAK,EAAE,+BAA+B;oBACtC,QAAQ,EAAE,QAAQ;oBAClB,MAAM,EAAE,wEAAwE;iBACjF,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,KAAK,EAAE,yBAAyB;oBAChC,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,mEAAmE;iBAC5E,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,KAAK,EAAE,wBAAwB;oBAC/B,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,mEAAmE;iBAC5E,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,IAAI,2EAA2E,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3F,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,KAAK,EAAE,qBAAqB;gBAC5B,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,+EAA+E;aACxF,CAAC,CAAC;QACL,CAAC;QAED,6CAA6C;QAC7C,IAAI,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpG,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,KAAK,EAAE,qBAAqB;gBAC5B,QAAQ,EAAE,QAAQ;gBAClB,MAAM,EAAE,oEAAoE;aAC7E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,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;IAC1F,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;IAE/E,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,SAAS,GAAmB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,SAAS,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzD,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACxE,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,SAAS,GAAG,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC;IAE/D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;YACE,MAAM,EAAE,SAAS;YACjB,KAAK;YACL,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE;YACvE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,KAAK,KAAK,wCAAwC,CAAC,CAAC;QAC1F,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1F,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,CAAC,MAAM,YAAY,SAAS,cAAc,QAAQ,aAAa,KAAK,QAAQ,CAAC,CAAC;IACrH,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Logic lint — detect common logic errors that AI code generators produce.
3
+ */
4
+ export declare function runLogicLint(argv: string[]): void;
5
+ //# sourceMappingURL=logic-lint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic-lint.d.ts","sourceRoot":"","sources":["../../src/commands/logic-lint.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmOH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6DjD"}