@kevinrabun/judges 3.57.0 → 3.58.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/assertion-density.d.ts +5 -0
  6. package/dist/commands/assertion-density.d.ts.map +1 -0
  7. package/dist/commands/assertion-density.js +264 -0
  8. package/dist/commands/assertion-density.js.map +1 -0
  9. package/dist/commands/async-safety.d.ts +5 -0
  10. package/dist/commands/async-safety.d.ts.map +1 -0
  11. package/dist/commands/async-safety.js +267 -0
  12. package/dist/commands/async-safety.js.map +1 -0
  13. package/dist/commands/clone-detect.d.ts +5 -0
  14. package/dist/commands/clone-detect.d.ts.map +1 -0
  15. package/dist/commands/clone-detect.js +233 -0
  16. package/dist/commands/clone-detect.js.map +1 -0
  17. package/dist/commands/contract-verify.d.ts +5 -0
  18. package/dist/commands/contract-verify.d.ts.map +1 -0
  19. package/dist/commands/contract-verify.js +317 -0
  20. package/dist/commands/contract-verify.js.map +1 -0
  21. package/dist/commands/dead-code-detect.d.ts +5 -0
  22. package/dist/commands/dead-code-detect.d.ts.map +1 -0
  23. package/dist/commands/dead-code-detect.js +256 -0
  24. package/dist/commands/dead-code-detect.js.map +1 -0
  25. package/dist/commands/encoding-safety.d.ts +5 -0
  26. package/dist/commands/encoding-safety.d.ts.map +1 -0
  27. package/dist/commands/encoding-safety.js +276 -0
  28. package/dist/commands/encoding-safety.js.map +1 -0
  29. package/dist/commands/input-guard.d.ts +5 -0
  30. package/dist/commands/input-guard.d.ts.map +1 -0
  31. package/dist/commands/input-guard.js +256 -0
  32. package/dist/commands/input-guard.js.map +1 -0
  33. package/dist/commands/state-integrity.d.ts +5 -0
  34. package/dist/commands/state-integrity.d.ts.map +1 -0
  35. package/dist/commands/state-integrity.js +284 -0
  36. package/dist/commands/state-integrity.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,264 @@
1
+ /**
2
+ * Assertion density — measure and enforce guard-clause and invariant density in critical code.
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"]);
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
+ function analyzeFile(filepath) {
42
+ const issues = [];
43
+ let content;
44
+ try {
45
+ content = readFileSync(filepath, "utf-8");
46
+ }
47
+ catch {
48
+ return issues;
49
+ }
50
+ // Skip test files
51
+ if (/\.test\.|\.spec\.|__test__|fixture/i.test(filepath))
52
+ return issues;
53
+ const lines = content.split("\n");
54
+ for (let i = 0; i < lines.length; i++) {
55
+ const line = lines[i];
56
+ // Function definition — check for precondition guards
57
+ const funcMatch = line.match(/(?:function\s+(\w+)|(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[^=]+=>\s*\{))/);
58
+ if (funcMatch) {
59
+ const funcName = funcMatch[1] || funcMatch[2];
60
+ if (funcName && funcName.length > 2 && !funcName.startsWith("_")) {
61
+ let depth = 0;
62
+ let funcEnd = i;
63
+ let started = false;
64
+ for (let j = i; j < Math.min(i + 60, lines.length); j++) {
65
+ for (const ch of lines[j]) {
66
+ if (ch === "{") {
67
+ depth++;
68
+ started = true;
69
+ }
70
+ if (ch === "}")
71
+ depth--;
72
+ }
73
+ if (started && depth <= 0) {
74
+ funcEnd = j;
75
+ break;
76
+ }
77
+ }
78
+ const funcBody = lines.slice(i + 1, Math.min(funcEnd, i + 30));
79
+ const bodyText = funcBody.join("\n");
80
+ const bodyLength = funcBody.filter((l) => l.trim().length > 0).length;
81
+ if (bodyLength > 8) {
82
+ // Check for guard clauses
83
+ const hasGuards = /if\s*\(!|if\s*\(\s*\w+\s*===?\s*(?:null|undefined|false|0|''|"")|\bthrow\b|\bassert\b|invariant\(|precondition/i.test(funcBody.slice(0, 5).join("\n"));
84
+ const hasParamValidation = /typeof\s+\w+|instanceof|isNaN|isFinite|Array\.isArray|!==?\s*(?:null|undefined)/i.test(funcBody.slice(0, 5).join("\n"));
85
+ if (!hasGuards && !hasParamValidation) {
86
+ // Check if function takes parameters that should be validated
87
+ const paramLine = lines[i];
88
+ const hasParams = /\(\s*\w+/.test(paramLine) && !/\(\s*\)\s*/.test(paramLine);
89
+ if (hasParams) {
90
+ issues.push({
91
+ file: filepath,
92
+ line: i + 1,
93
+ issue: "Function without precondition guards",
94
+ severity: "medium",
95
+ detail: `\`${funcName}\` takes parameters but has no guard clauses — add validation for unexpected inputs`,
96
+ });
97
+ }
98
+ }
99
+ // Check for division without zero-check
100
+ if (/\/\s*\w+/.test(bodyText) && !/\/\s*\d+[^.]|\/\/|\/\*|\*\//.test(bodyText)) {
101
+ if (!/=== 0|!== 0|> 0|< 0|isNaN|isFinite|zero/i.test(bodyText)) {
102
+ // Only flag if dividing by a variable
103
+ const divMatch = bodyText.match(/\/\s*([a-zA-Z]\w*)/);
104
+ if (divMatch && !/length|size|count|PI|max|min/i.test(divMatch[1])) {
105
+ issues.push({
106
+ file: filepath,
107
+ line: i + 1,
108
+ issue: "Division without zero-check",
109
+ severity: "medium",
110
+ detail: `Division by \`${divMatch[1]}\` without verifying non-zero — may cause Infinity/NaN`,
111
+ });
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ // Switch without default
119
+ if (/^\s*switch\s*\(/.test(line)) {
120
+ let depth = 0;
121
+ let switchEnd = i;
122
+ let started = false;
123
+ for (let j = i; j < Math.min(i + 50, lines.length); j++) {
124
+ for (const ch of lines[j]) {
125
+ if (ch === "{") {
126
+ depth++;
127
+ started = true;
128
+ }
129
+ if (ch === "}")
130
+ depth--;
131
+ }
132
+ if (started && depth <= 0) {
133
+ switchEnd = j;
134
+ break;
135
+ }
136
+ }
137
+ const switchBody = lines.slice(i, switchEnd + 1).join("\n");
138
+ if (!/\bdefault\s*:/i.test(switchBody)) {
139
+ issues.push({
140
+ file: filepath,
141
+ line: i + 1,
142
+ issue: "Switch without default case",
143
+ severity: "medium",
144
+ detail: "Switch statement has no default — unhandled values will silently fall through",
145
+ });
146
+ }
147
+ }
148
+ // Array access without bounds check
149
+ if (/\w+\[\s*\w+\s*\]/.test(line) && !/\[\s*['"]/.test(line)) {
150
+ const accessMatch = line.match(/(\w+)\[\s*(\w+)\s*\]/);
151
+ if (accessMatch) {
152
+ const arr = accessMatch[1];
153
+ const idx = accessMatch[2];
154
+ // Only flag if index is a variable (not string, not 0/1)
155
+ if (/^[a-zA-Z]/.test(idx) && !/length|size|map|filter|reduce|find|forEach|Object|Math|console/i.test(arr)) {
156
+ const block = lines.slice(Math.max(0, i - 3), Math.min(i + 2, lines.length)).join("\n");
157
+ if (!/\.length|bounds|range|<|>|>=|<=|if\s*\(|assert|check|valid/i.test(block)) {
158
+ issues.push({
159
+ file: filepath,
160
+ line: i + 1,
161
+ issue: "Array access without bounds check",
162
+ severity: "low",
163
+ detail: `\`${arr}[${idx}]\` accessed without verifying index is within bounds`,
164
+ });
165
+ }
166
+ }
167
+ }
168
+ }
169
+ // Optional chaining overuse (hiding real bugs)
170
+ const optionalChainCount = (line.match(/\?\./g) || []).length;
171
+ if (optionalChainCount > 3) {
172
+ issues.push({
173
+ file: filepath,
174
+ line: i + 1,
175
+ issue: "Excessive optional chaining",
176
+ severity: "low",
177
+ detail: `${optionalChainCount} optional chains in one expression — may indicate unclear data contract`,
178
+ });
179
+ }
180
+ // Parsing without isNaN check
181
+ if (/(?:parseInt|parseFloat|Number)\s*\(/.test(line)) {
182
+ const block = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
183
+ if (!/isNaN|isFinite|Number\.is|!==\s*NaN|\|\||[?][?]/i.test(block)) {
184
+ issues.push({
185
+ file: filepath,
186
+ line: i + 1,
187
+ issue: "Number parsing without NaN check",
188
+ severity: "low",
189
+ detail: "parseInt/parseFloat/Number can return NaN — check before using the result",
190
+ });
191
+ }
192
+ }
193
+ // Map/object key access without existence check
194
+ if (/\.get\s*\(\s*\w+\s*\)/.test(line) && !/Map|WeakMap|Headers|URLSearchParams/i.test(line)) {
195
+ const block = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
196
+ if (!/if\s*\(|has\s*\(|undefined|null|\?\./i.test(block)) {
197
+ issues.push({
198
+ file: filepath,
199
+ line: i + 1,
200
+ issue: "Map.get without existence check",
201
+ severity: "low",
202
+ detail: "Map.get() returns undefined for missing keys — check with .has() or handle undefined",
203
+ });
204
+ }
205
+ }
206
+ }
207
+ return issues;
208
+ }
209
+ // ─── CLI ────────────────────────────────────────────────────────────────────
210
+ export function runAssertionDensity(argv) {
211
+ if (argv.includes("--help") || argv.includes("-h")) {
212
+ console.log(`
213
+ judges assertion-density — Measure guard-clause and invariant density in critical code
214
+
215
+ Usage:
216
+ judges assertion-density [dir]
217
+ judges assertion-density src/ --format json
218
+
219
+ Options:
220
+ [dir] Directory to scan (default: .)
221
+ --format json JSON output
222
+ --help, -h Show this help
223
+
224
+ Checks: functions without preconditions, division without zero-check, switch without default,
225
+ array access without bounds check, number parsing without NaN check, excessive optional chaining.
226
+ `);
227
+ return;
228
+ }
229
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
230
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
231
+ const files = collectFiles(dir);
232
+ const allIssues = [];
233
+ for (const f of files)
234
+ allIssues.push(...analyzeFile(f));
235
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
236
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
237
+ const score = Math.max(0, 100 - highCount * 8 - medCount * 3);
238
+ if (format === "json") {
239
+ console.log(JSON.stringify({
240
+ issues: allIssues,
241
+ score,
242
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
243
+ timestamp: new Date().toISOString(),
244
+ }, null, 2));
245
+ }
246
+ else {
247
+ const badge = score >= 80 ? "✅ DEFENSIVE" : score >= 50 ? "⚠️ OPTIMISTIC" : "❌ FRAGILE";
248
+ console.log(`\n Assertion Density: ${badge} (${score}/100)\n ─────────────────────────────`);
249
+ if (allIssues.length === 0) {
250
+ console.log(" No assertion density issues detected.\n");
251
+ return;
252
+ }
253
+ for (const issue of allIssues.slice(0, 25)) {
254
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
255
+ console.log(` ${icon} ${issue.issue}`);
256
+ console.log(` ${issue.file}:${issue.line}`);
257
+ console.log(` ${issue.detail}`);
258
+ }
259
+ if (allIssues.length > 25)
260
+ console.log(` ... and ${allIssues.length - 25} more`);
261
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
262
+ }
263
+ }
264
+ //# sourceMappingURL=assertion-density.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertion-density.js","sourceRoot":"","sources":["../../src/commands/assertion-density.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Async safety — detect async/await anti-patterns, fire-and-forget promises, and swallowed rejections.
3
+ */
4
+ export declare function runAsyncSafety(argv: string[]): void;
5
+ //# sourceMappingURL=async-safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-safety.d.ts","sourceRoot":"","sources":["../../src/commands/async-safety.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0OH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+DnD"}
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Async safety — detect async/await anti-patterns, fire-and-forget promises, and swallowed rejections.
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"]);
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
+ function analyzeFile(filepath) {
42
+ const issues = [];
43
+ let content;
44
+ try {
45
+ content = readFileSync(filepath, "utf-8");
46
+ }
47
+ catch {
48
+ return issues;
49
+ }
50
+ const lines = content.split("\n");
51
+ // Skip test files for some checks
52
+ const isTest = /\.test\.|\.spec\.|__test__/i.test(filepath);
53
+ for (let i = 0; i < lines.length; i++) {
54
+ const line = lines[i];
55
+ // Fire-and-forget: calling async function without await
56
+ if (/(?:^|\s)\w+\([^)]*\)\s*;?\s*$/.test(line.trim()) && !line.includes("await") && !line.includes("return")) {
57
+ const _prevLines = lines.slice(Math.max(0, i - 5), i + 1).join("\n");
58
+ // Check if the called function is async
59
+ const callMatch = line.trim().match(/^(\w+)\s*\(/);
60
+ if (callMatch) {
61
+ const funcName = callMatch[1];
62
+ if (content.includes(`async function ${funcName}`) || content.includes(`async ${funcName}`)) {
63
+ if (!/void\s+\w+|\/\/.*fire.and.forget|\/\/.*intentional|event.*handler|\.on\(/i.test(line)) {
64
+ issues.push({
65
+ file: filepath,
66
+ line: i + 1,
67
+ issue: "Fire-and-forget async call",
68
+ severity: "high",
69
+ detail: `\`${funcName}()\` is async but called without \`await\` — errors will be silently swallowed`,
70
+ });
71
+ }
72
+ }
73
+ }
74
+ }
75
+ // .then() without .catch()
76
+ if (/\.then\s*\(/.test(line) && !line.includes(".catch")) {
77
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
78
+ if (!block.includes(".catch")) {
79
+ issues.push({
80
+ file: filepath,
81
+ line: i + 1,
82
+ issue: ".then() without .catch()",
83
+ severity: "medium",
84
+ detail: "Promise chain has no error handler — rejection will be unhandled",
85
+ });
86
+ }
87
+ }
88
+ // async function that never awaits
89
+ if (/async\s+(?:function\s+)?(\w+)/.test(line)) {
90
+ const funcName = line.match(/async\s+(?:function\s+)?(\w+)/)?.[1] || "anonymous";
91
+ // Find the function body
92
+ let depth = 0;
93
+ let funcEnd = i;
94
+ let started = false;
95
+ for (let j = i; j < Math.min(i + 50, lines.length); j++) {
96
+ for (const ch of lines[j]) {
97
+ if (ch === "{") {
98
+ depth++;
99
+ started = true;
100
+ }
101
+ if (ch === "}")
102
+ depth--;
103
+ }
104
+ if (started && depth <= 0) {
105
+ funcEnd = j;
106
+ break;
107
+ }
108
+ }
109
+ const funcBody = lines.slice(i + 1, funcEnd).join("\n");
110
+ if (funcBody.length > 10 && !/await\b|\.then\(|yield\b/i.test(funcBody)) {
111
+ issues.push({
112
+ file: filepath,
113
+ line: i + 1,
114
+ issue: "Async function without await",
115
+ severity: "medium",
116
+ detail: `\`${funcName}\` is declared async but never awaits — unnecessary wrapper adds overhead`,
117
+ });
118
+ }
119
+ }
120
+ // try/catch around async with empty catch
121
+ if (/try\s*\{/.test(line)) {
122
+ const block = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
123
+ if (/await\b/.test(block)) {
124
+ const catchMatch = block.match(/catch\s*\(\s*\w*\s*\)\s*\{\s*\}/);
125
+ if (catchMatch) {
126
+ issues.push({
127
+ file: filepath,
128
+ line: i + 1,
129
+ issue: "Async try/catch with empty handler",
130
+ severity: "high",
131
+ detail: "Awaited operation errors are silently swallowed — log or rethrow",
132
+ });
133
+ }
134
+ }
135
+ }
136
+ // Promise constructor anti-pattern (async executor)
137
+ if (/new\s+Promise\s*\(\s*async/.test(line)) {
138
+ issues.push({
139
+ file: filepath,
140
+ line: i + 1,
141
+ issue: "Async Promise constructor",
142
+ severity: "high",
143
+ detail: "Async executor in Promise constructor — rejections inside async can't be caught by the Promise",
144
+ });
145
+ }
146
+ // await in loop (performance issue)
147
+ if (!isTest && /^\s*(?:for|while)\s*\(/.test(line)) {
148
+ const loopBlock = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
149
+ const awaitCount = (loopBlock.match(/await\b/g) || []).length;
150
+ if (awaitCount >= 1 && !/sequential|order.*matters|rate.*limit|throttle/i.test(loopBlock)) {
151
+ issues.push({
152
+ file: filepath,
153
+ line: i + 1,
154
+ issue: "Sequential await in loop",
155
+ severity: "low",
156
+ detail: "Awaiting inside loop runs iterations sequentially — use Promise.all for parallel execution if order doesn't matter",
157
+ });
158
+ }
159
+ }
160
+ // Mixing callbacks and promises
161
+ if (/\.then\s*\(/.test(line) && /callback|cb\s*\(|next\s*\(/i.test(line)) {
162
+ issues.push({
163
+ file: filepath,
164
+ line: i + 1,
165
+ issue: "Mixed callback and promise patterns",
166
+ severity: "medium",
167
+ detail: "Mixing callbacks with .then() chains — pick one pattern to avoid missed error paths",
168
+ });
169
+ }
170
+ // Unhandled promise rejection risk (process-level)
171
+ if (/process\.on\s*\(\s*['"]unhandledRejection['"]/.test(line)) {
172
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
173
+ if (/process\.exit/i.test(block)) {
174
+ issues.push({
175
+ file: filepath,
176
+ line: i + 1,
177
+ issue: "Unhandled rejection handler exits process",
178
+ severity: "low",
179
+ detail: "Consider graceful shutdown instead of immediate exit on unhandled rejections",
180
+ });
181
+ }
182
+ }
183
+ // Promise.all without error isolation
184
+ if (/Promise\.all\s*\(/.test(line) && !isTest) {
185
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
186
+ if (!/Promise\.allSettled|\.catch|try|catch/i.test(block)) {
187
+ issues.push({
188
+ file: filepath,
189
+ line: i + 1,
190
+ issue: "Promise.all without error isolation",
191
+ severity: "medium",
192
+ detail: "One promise rejection cancels all — use Promise.allSettled if partial results are acceptable",
193
+ });
194
+ }
195
+ }
196
+ // setTimeout/setInterval with async callback but no error handling
197
+ if (/(?:setTimeout|setInterval)\s*\(\s*async/.test(line)) {
198
+ const block = lines.slice(i, Math.min(i + 10, lines.length)).join("\n");
199
+ if (!/try|catch|\.catch/i.test(block)) {
200
+ issues.push({
201
+ file: filepath,
202
+ line: i + 1,
203
+ issue: "Async timer callback without error handling",
204
+ severity: "high",
205
+ detail: "Async callback in setTimeout/setInterval — errors become unhandled rejections",
206
+ });
207
+ }
208
+ }
209
+ }
210
+ return issues;
211
+ }
212
+ // ─── CLI ────────────────────────────────────────────────────────────────────
213
+ export function runAsyncSafety(argv) {
214
+ if (argv.includes("--help") || argv.includes("-h")) {
215
+ console.log(`
216
+ judges async-safety — Detect async/await anti-patterns and fire-and-forget promises
217
+
218
+ Usage:
219
+ judges async-safety [dir]
220
+ judges async-safety 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: fire-and-forget calls, .then() without .catch(), async without await,
228
+ async Promise constructors, await in loops, async timer callbacks, Promise.all without error isolation.
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 allIssues = [];
236
+ for (const f of files)
237
+ allIssues.push(...analyzeFile(f));
238
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
239
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
240
+ const score = Math.max(0, 100 - highCount * 10 - medCount * 4);
241
+ if (format === "json") {
242
+ console.log(JSON.stringify({
243
+ issues: allIssues,
244
+ score,
245
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
246
+ timestamp: new Date().toISOString(),
247
+ }, null, 2));
248
+ }
249
+ else {
250
+ const badge = score >= 80 ? "✅ SAFE" : score >= 50 ? "⚠️ RISKY" : "❌ HAZARDOUS";
251
+ console.log(`\n Async Safety: ${badge} (${score}/100)\n ─────────────────────────────`);
252
+ if (allIssues.length === 0) {
253
+ console.log(" No async safety issues detected.\n");
254
+ return;
255
+ }
256
+ for (const issue of allIssues.slice(0, 25)) {
257
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
258
+ console.log(` ${icon} ${issue.issue}`);
259
+ console.log(` ${issue.file}:${issue.line}`);
260
+ console.log(` ${issue.detail}`);
261
+ }
262
+ if (allIssues.length > 25)
263
+ console.log(` ... and ${allIssues.length - 25} more`);
264
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
265
+ }
266
+ }
267
+ //# sourceMappingURL=async-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-safety.js","sourceRoot":"","sources":["../../src/commands/async-safety.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Clone detect — find duplicated logic blocks that should be extracted into shared functions.
3
+ */
4
+ export declare function runCloneDetect(argv: string[]): void;
5
+ //# sourceMappingURL=clone-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone-detect.d.ts","sourceRoot":"","sources":["../../src/commands/clone-detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6MH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6DnD"}