@kevinrabun/judges 3.55.0 → 3.57.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/api-versioning-audit.d.ts +6 -0
  6. package/dist/commands/api-versioning-audit.d.ts.map +1 -0
  7. package/dist/commands/api-versioning-audit.js +234 -0
  8. package/dist/commands/api-versioning-audit.js.map +1 -0
  9. package/dist/commands/boundary-enforce.d.ts +6 -0
  10. package/dist/commands/boundary-enforce.d.ts.map +1 -0
  11. package/dist/commands/boundary-enforce.js +256 -0
  12. package/dist/commands/boundary-enforce.js.map +1 -0
  13. package/dist/commands/cache-audit.d.ts +5 -0
  14. package/dist/commands/cache-audit.d.ts.map +1 -0
  15. package/dist/commands/cache-audit.js +220 -0
  16. package/dist/commands/cache-audit.js.map +1 -0
  17. package/dist/commands/comment-drift.d.ts +5 -0
  18. package/dist/commands/comment-drift.d.ts.map +1 -0
  19. package/dist/commands/comment-drift.js +229 -0
  20. package/dist/commands/comment-drift.js.map +1 -0
  21. package/dist/commands/error-taxonomy.d.ts +6 -0
  22. package/dist/commands/error-taxonomy.d.ts.map +1 -0
  23. package/dist/commands/error-taxonomy.js +227 -0
  24. package/dist/commands/error-taxonomy.js.map +1 -0
  25. package/dist/commands/error-ux.d.ts +5 -0
  26. package/dist/commands/error-ux.d.ts.map +1 -0
  27. package/dist/commands/error-ux.js +253 -0
  28. package/dist/commands/error-ux.js.map +1 -0
  29. package/dist/commands/event-leak.d.ts +5 -0
  30. package/dist/commands/event-leak.d.ts.map +1 -0
  31. package/dist/commands/event-leak.js +263 -0
  32. package/dist/commands/event-leak.js.map +1 -0
  33. package/dist/commands/idempotency-audit.d.ts +5 -0
  34. package/dist/commands/idempotency-audit.d.ts.map +1 -0
  35. package/dist/commands/idempotency-audit.js +223 -0
  36. package/dist/commands/idempotency-audit.js.map +1 -0
  37. package/dist/commands/log-quality.d.ts +6 -0
  38. package/dist/commands/log-quality.d.ts.map +1 -0
  39. package/dist/commands/log-quality.js +212 -0
  40. package/dist/commands/log-quality.js.map +1 -0
  41. package/dist/commands/null-safety-audit.d.ts +6 -0
  42. package/dist/commands/null-safety-audit.d.ts.map +1 -0
  43. package/dist/commands/null-safety-audit.js +222 -0
  44. package/dist/commands/null-safety-audit.js.map +1 -0
  45. package/dist/commands/ownership-map.d.ts +6 -0
  46. package/dist/commands/ownership-map.d.ts.map +1 -0
  47. package/dist/commands/ownership-map.js +229 -0
  48. package/dist/commands/ownership-map.js.map +1 -0
  49. package/dist/commands/privilege-path.d.ts +5 -0
  50. package/dist/commands/privilege-path.d.ts.map +1 -0
  51. package/dist/commands/privilege-path.js +234 -0
  52. package/dist/commands/privilege-path.js.map +1 -0
  53. package/dist/commands/retry-pattern-audit.d.ts +6 -0
  54. package/dist/commands/retry-pattern-audit.d.ts.map +1 -0
  55. package/dist/commands/retry-pattern-audit.js +216 -0
  56. package/dist/commands/retry-pattern-audit.js.map +1 -0
  57. package/dist/commands/test-isolation.d.ts +6 -0
  58. package/dist/commands/test-isolation.d.ts.map +1 -0
  59. package/dist/commands/test-isolation.js +235 -0
  60. package/dist/commands/test-isolation.js.map +1 -0
  61. package/dist/commands/timeout-audit.d.ts +5 -0
  62. package/dist/commands/timeout-audit.d.ts.map +1 -0
  63. package/dist/commands/timeout-audit.js +211 -0
  64. package/dist/commands/timeout-audit.js.map +1 -0
  65. package/dist/commands/type-boundary.d.ts +5 -0
  66. package/dist/commands/type-boundary.d.ts.map +1 -0
  67. package/dist/commands/type-boundary.js +236 -0
  68. package/dist/commands/type-boundary.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Retry pattern audit — analyze retry, backoff, and circuit-breaker patterns
3
+ * for correctness and consistency.
4
+ */
5
+ import { readFileSync, readdirSync, statSync } from "fs";
6
+ import { join, extname } from "path";
7
+ // ─── File Collection ────────────────────────────────────────────────────────
8
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go", ".rs"]);
9
+ function collectFiles(dir, max = 300) {
10
+ const files = [];
11
+ function walk(d) {
12
+ if (files.length >= max)
13
+ return;
14
+ let entries;
15
+ try {
16
+ entries = readdirSync(d);
17
+ }
18
+ catch {
19
+ return;
20
+ }
21
+ for (const e of entries) {
22
+ if (files.length >= max)
23
+ return;
24
+ if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
25
+ continue;
26
+ const full = join(d, e);
27
+ try {
28
+ if (statSync(full).isDirectory())
29
+ walk(full);
30
+ else if (CODE_EXTS.has(extname(full)))
31
+ files.push(full);
32
+ }
33
+ catch {
34
+ /* skip */
35
+ }
36
+ }
37
+ }
38
+ walk(dir);
39
+ return files;
40
+ }
41
+ // ─── Analysis ───────────────────────────────────────────────────────────────
42
+ function analyzeFile(filepath) {
43
+ const issues = [];
44
+ let content;
45
+ try {
46
+ content = readFileSync(filepath, "utf-8");
47
+ }
48
+ catch {
49
+ return issues;
50
+ }
51
+ const lines = content.split("\n");
52
+ for (let i = 0; i < lines.length; i++) {
53
+ const line = lines[i];
54
+ // Unbounded retry loops
55
+ if (/while\s*\(\s*true\s*\)|for\s*\(\s*;\s*;\s*\)/.test(line)) {
56
+ const block = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
57
+ if (/retry|attempt|fetch|request|connect/i.test(block) &&
58
+ !/maxRetries|maxAttempts|retryLimit|MAX_RETRIES/i.test(block)) {
59
+ issues.push({
60
+ file: filepath,
61
+ line: i + 1,
62
+ issue: "Unbounded retry loop",
63
+ severity: "critical",
64
+ detail: "Infinite retry without max attempts — will loop forever on persistent failures",
65
+ });
66
+ }
67
+ }
68
+ // Fixed delay (no backoff)
69
+ if (/(?:sleep|setTimeout|time\.Sleep|Thread\.sleep|delay)\s*\(\s*\d+\s*\)/i.test(line)) {
70
+ const block = lines.slice(Math.max(0, i - 5), Math.min(i + 5, lines.length)).join("\n");
71
+ if (/retry|attempt|retries/i.test(block) && !/exponential|backoff|Math\.pow|Math\.min|\*\s*2/i.test(block)) {
72
+ issues.push({
73
+ file: filepath,
74
+ line: i + 1,
75
+ issue: "Fixed retry delay",
76
+ severity: "high",
77
+ detail: "Use exponential backoff with jitter to avoid thundering herd",
78
+ });
79
+ }
80
+ }
81
+ // Missing jitter
82
+ if (/exponential|backoff|Math\.pow.*2/i.test(line)) {
83
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
84
+ if (!/jitter|Math\.random|random|rand\b/i.test(block)) {
85
+ issues.push({
86
+ file: filepath,
87
+ line: i + 1,
88
+ issue: "Backoff without jitter",
89
+ severity: "medium",
90
+ detail: "Add random jitter to prevent synchronized retry storms",
91
+ });
92
+ }
93
+ }
94
+ // Retrying non-idempotent operations
95
+ if (/retry.*(?:POST|PUT|DELETE|INSERT|UPDATE|create|write)/i.test(line) ||
96
+ /(?:POST|create|write).*retry/i.test(line)) {
97
+ issues.push({
98
+ file: filepath,
99
+ line: i + 1,
100
+ issue: "Retrying non-idempotent operation",
101
+ severity: "high",
102
+ detail: "POSTs/writes may duplicate data on retry — ensure idempotency keys",
103
+ });
104
+ }
105
+ // Hardcoded retry counts
106
+ if (/(?:maxRetries|retryCount|attempts)\s*[:=]\s*\d{2,}/i.test(line)) {
107
+ issues.push({
108
+ file: filepath,
109
+ line: i + 1,
110
+ issue: "High retry count",
111
+ severity: "medium",
112
+ detail: "Large retry counts delay failure detection — consider circuit breaker",
113
+ });
114
+ }
115
+ // Catching all errors for retry (no differentiation)
116
+ if (/catch\s*\(\s*\w*\s*\)/.test(line)) {
117
+ const block = lines.slice(i, Math.min(i + 8, lines.length)).join("\n");
118
+ if (/retry|continue|attempt/i.test(block) &&
119
+ !/status|code|instanceof|isRetryable|isTransient|4\d{2}|5\d{2}/i.test(block)) {
120
+ issues.push({
121
+ file: filepath,
122
+ line: i + 1,
123
+ issue: "Retrying all errors indiscriminately",
124
+ severity: "high",
125
+ detail: "Only retry transient errors (5xx, timeouts) — 4xx errors won't resolve on retry",
126
+ });
127
+ }
128
+ }
129
+ // Missing circuit breaker for external calls
130
+ if (/(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(line)) {
131
+ const fileContent = content;
132
+ if (/retry|retries|maxAttempts/i.test(fileContent) &&
133
+ !/circuit.?breaker|CircuitBreaker|opossum|cockatiel|polly/i.test(fileContent)) {
134
+ if (i === lines.findIndex((l) => /(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(l))) {
135
+ issues.push({
136
+ file: filepath,
137
+ line: i + 1,
138
+ issue: "Retries without circuit breaker",
139
+ severity: "medium",
140
+ detail: "Add circuit breaker to fail fast when downstream is unhealthy",
141
+ });
142
+ }
143
+ }
144
+ }
145
+ // Timeout not set
146
+ if (/(?:axios|fetch|http\.request|httpClient)\s*\(/i.test(line)) {
147
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
148
+ if (!/timeout|signal|AbortController|deadline/i.test(block)) {
149
+ issues.push({
150
+ file: filepath,
151
+ line: i + 1,
152
+ issue: "External call without timeout",
153
+ severity: "high",
154
+ detail: "Set timeouts on all external calls — retries compound unbounded waits",
155
+ });
156
+ }
157
+ }
158
+ }
159
+ return issues;
160
+ }
161
+ // ─── CLI ────────────────────────────────────────────────────────────────────
162
+ export function runRetryPatternAudit(argv) {
163
+ if (argv.includes("--help") || argv.includes("-h")) {
164
+ console.log(`
165
+ judges retry-pattern-audit — Analyze retry, backoff, and circuit-breaker patterns
166
+
167
+ Usage:
168
+ judges retry-pattern-audit [dir]
169
+ judges retry-pattern-audit src/ --format json
170
+
171
+ Options:
172
+ [dir] Directory to scan (default: .)
173
+ --format json JSON output
174
+ --help, -h Show this help
175
+
176
+ Detects: unbounded retries, fixed delays, missing jitter, non-idempotent retries,
177
+ indiscriminate error catching, missing circuit breakers, missing timeouts.
178
+ `);
179
+ return;
180
+ }
181
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
182
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
183
+ const files = collectFiles(dir);
184
+ const allIssues = [];
185
+ for (const f of files)
186
+ allIssues.push(...analyzeFile(f));
187
+ const critCount = allIssues.filter((i) => i.severity === "critical").length;
188
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
189
+ const score = allIssues.length === 0 ? 100 : Math.max(0, 100 - critCount * 25 - highCount * 10);
190
+ if (format === "json") {
191
+ console.log(JSON.stringify({
192
+ issues: allIssues,
193
+ score,
194
+ summary: { critical: critCount, high: highCount, total: allIssues.length },
195
+ timestamp: new Date().toISOString(),
196
+ }, null, 2));
197
+ }
198
+ else {
199
+ const badge = critCount > 0 ? "🚫 UNSAFE" : highCount > 0 ? "⚠️ FRAGILE" : "✅ RESILIENT";
200
+ console.log(`\n Retry Pattern Audit: ${badge} (${score}/100)\n ─────────────────────────────`);
201
+ if (allIssues.length === 0) {
202
+ console.log(" No retry pattern issues detected.\n");
203
+ return;
204
+ }
205
+ for (const issue of allIssues.slice(0, 25)) {
206
+ const icon = issue.severity === "critical" ? "🚫" : issue.severity === "high" ? "🔴" : "🟡";
207
+ console.log(` ${icon} [${issue.severity.toUpperCase()}] ${issue.issue}`);
208
+ console.log(` ${issue.file}:${issue.line}`);
209
+ console.log(` ${issue.detail}`);
210
+ }
211
+ if (allIssues.length > 25)
212
+ console.log(` ... and ${allIssues.length - 25} more`);
213
+ console.log(`\n Total: ${allIssues.length} | Critical: ${critCount} | High: ${highCount} | Score: ${score}/100\n`);
214
+ }
215
+ }
216
+ //# sourceMappingURL=retry-pattern-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-pattern-audit.js","sourceRoot":"","sources":["../../src/commands/retry-pattern-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Test isolation — detect shared mutable state, ordering dependencies,
3
+ * and resource leaks between test cases.
4
+ */
5
+ export declare function runTestIsolation(argv: string[]): void;
6
+ //# sourceMappingURL=test-isolation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-isolation.d.ts","sourceRoot":"","sources":["../../src/commands/test-isolation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0MH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgErD"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Test isolation — detect shared mutable state, ordering dependencies,
3
+ * and resource leaks between test cases.
4
+ */
5
+ import { readFileSync, readdirSync, statSync } from "fs";
6
+ import { join, extname, basename } from "path";
7
+ // ─── File Collection ────────────────────────────────────────────────────────
8
+ const TEST_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go"]);
9
+ const TEST_PATTERNS = [/\.test\./i, /\.spec\./i, /test_/i, /_test\./i];
10
+ function isTestFile(name) {
11
+ return TEST_PATTERNS.some((p) => p.test(name));
12
+ }
13
+ function collectTestFiles(dir, max = 300) {
14
+ const files = [];
15
+ function walk(d) {
16
+ if (files.length >= max)
17
+ return;
18
+ let entries;
19
+ try {
20
+ entries = readdirSync(d);
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ for (const e of entries) {
26
+ if (files.length >= max)
27
+ return;
28
+ if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
29
+ continue;
30
+ const full = join(d, e);
31
+ try {
32
+ if (statSync(full).isDirectory())
33
+ walk(full);
34
+ else if (TEST_EXTS.has(extname(full)) && isTestFile(basename(full)))
35
+ files.push(full);
36
+ }
37
+ catch {
38
+ /* skip */
39
+ }
40
+ }
41
+ }
42
+ walk(dir);
43
+ return files;
44
+ }
45
+ // ─── Analysis ───────────────────────────────────────────────────────────────
46
+ function analyzeFile(filepath) {
47
+ const issues = [];
48
+ let content;
49
+ try {
50
+ content = readFileSync(filepath, "utf-8");
51
+ }
52
+ catch {
53
+ return issues;
54
+ }
55
+ const lines = content.split("\n");
56
+ // Track scope context
57
+ let inDescribe = false;
58
+ let describeDepth = 0;
59
+ for (let i = 0; i < lines.length; i++) {
60
+ const line = lines[i];
61
+ if (/\b(?:describe|context|suite)\s*\(/.test(line)) {
62
+ inDescribe = true;
63
+ describeDepth++;
64
+ }
65
+ if (inDescribe && /^\s*\}\s*\)\s*;?\s*$/.test(line)) {
66
+ describeDepth--;
67
+ if (describeDepth <= 0)
68
+ inDescribe = false;
69
+ }
70
+ // Global mutable state
71
+ if (/^\s*(?:let|var)\s+\w+\s*=/.test(line) && !inDescribe) {
72
+ const varName = line.match(/(?:let|var)\s+(\w+)/)?.[1];
73
+ if (varName && /\b(?:state|data|count|result|output|db|conn|client|server)\b/i.test(varName)) {
74
+ issues.push({
75
+ file: filepath,
76
+ line: i + 1,
77
+ issue: "Mutable global test state",
78
+ severity: "high",
79
+ detail: `Global \`${varName}\` — tests sharing mutable state cause order-dependent failures`,
80
+ });
81
+ }
82
+ }
83
+ // Module-level side effects in test files
84
+ if (/^\s*(?:fs\.|writeFileSync|mkdirSync|execSync|spawn|createServer)/.test(line) && !inDescribe) {
85
+ issues.push({
86
+ file: filepath,
87
+ line: i + 1,
88
+ issue: "Module-level side effect",
89
+ severity: "high",
90
+ detail: "Side effects outside test blocks affect all tests in the file",
91
+ });
92
+ }
93
+ // Shared fixtures without reset
94
+ if (/\b(?:beforeAll|before)\s*\(\s*(?:async\s+)?(?:function|\(|=>)/.test(line)) {
95
+ const beforeBlock = lines.slice(i, Math.min(i + 15, lines.length)).join("\n");
96
+ const hasAfter = /\b(?:afterAll|afterEach|after)\s*\(/.test(content);
97
+ if (!hasAfter && /(?:create|setup|init|connect|insert|write)/i.test(beforeBlock)) {
98
+ issues.push({
99
+ file: filepath,
100
+ line: i + 1,
101
+ issue: "Setup without teardown",
102
+ severity: "high",
103
+ detail: "beforeAll creates resources but no afterAll/afterEach cleans them — leaked state",
104
+ });
105
+ }
106
+ }
107
+ // File system operations without cleanup
108
+ if (/(?:writeFileSync|mkdirSync|writeFile|mkdir)\s*\(/.test(line)) {
109
+ const hasCleanup = /(?:unlinkSync|rmdirSync|rimraf|rm\s*\(|removeSync|afterEach.*unlink|afterAll.*unlink)/i.test(content);
110
+ if (!hasCleanup) {
111
+ issues.push({
112
+ file: filepath,
113
+ line: i + 1,
114
+ issue: "File system write without cleanup",
115
+ severity: "medium",
116
+ detail: "Test creates files but never cleans up — pollutes workspace",
117
+ });
118
+ }
119
+ }
120
+ // Network listeners without close
121
+ if (/(?:createServer|listen)\s*\(/.test(line)) {
122
+ const hasClose = /(?:\.close\s*\(|server\.close|afterAll.*close|afterEach.*close)/i.test(content);
123
+ if (!hasClose) {
124
+ issues.push({
125
+ file: filepath,
126
+ line: i + 1,
127
+ issue: "Server started without closing",
128
+ severity: "high",
129
+ detail: "Test starts a server but never closes it — port conflicts in parallel runs",
130
+ });
131
+ }
132
+ }
133
+ // setTimeout in tests (flakiness)
134
+ if (/setTimeout\s*\(\s*(?:resolve|done|callback|cb)\s*,\s*\d+/.test(line)) {
135
+ issues.push({
136
+ file: filepath,
137
+ line: i + 1,
138
+ issue: "setTimeout for async coordination",
139
+ severity: "medium",
140
+ detail: "Timer-based waits are flaky — use event-based or polling patterns",
141
+ });
142
+ }
143
+ // Order-dependent assertions (relying on previous test state)
144
+ if (/\.toBe\(.*\+\+|\.toEqual\(.*count/i.test(line)) {
145
+ issues.push({
146
+ file: filepath,
147
+ line: i + 1,
148
+ issue: "Assertion relies on accumulated state",
149
+ severity: "medium",
150
+ detail: "Tests should be independently runnable — avoid cross-test counters",
151
+ });
152
+ }
153
+ // Shared database connections
154
+ if (/(?:mongoose\.connect|createConnection|pg\.Pool|knex|prisma\.\$connect|sequelize)/i.test(line) && !inDescribe) {
155
+ issues.push({
156
+ file: filepath,
157
+ line: i + 1,
158
+ issue: "Shared database connection",
159
+ severity: "medium",
160
+ detail: "Use per-test or per-suite DB connections with transaction rollback",
161
+ });
162
+ }
163
+ // Environment variable mutation
164
+ if (/process\.env\.\w+\s*=/.test(line)) {
165
+ const hasRestore = /process\.env\.\w+\s*=.*original|delete\s+process\.env|afterEach.*env/i.test(content);
166
+ if (!hasRestore) {
167
+ issues.push({
168
+ file: filepath,
169
+ line: i + 1,
170
+ issue: "Environment mutation without restore",
171
+ severity: "high",
172
+ detail: "Setting process.env leaks to other tests — restore in afterEach",
173
+ });
174
+ }
175
+ }
176
+ }
177
+ return issues;
178
+ }
179
+ // ─── CLI ────────────────────────────────────────────────────────────────────
180
+ export function runTestIsolation(argv) {
181
+ if (argv.includes("--help") || argv.includes("-h")) {
182
+ console.log(`
183
+ judges test-isolation — Detect test isolation violations
184
+
185
+ Usage:
186
+ judges test-isolation [dir]
187
+ judges test-isolation tests/ --format json
188
+
189
+ Options:
190
+ [dir] Directory to scan (default: .)
191
+ --format json JSON output
192
+ --help, -h Show this help
193
+
194
+ Detects: shared mutable state, missing teardown, file system leaks, unclosed servers,
195
+ setTimeout waits, environment mutations, shared DB connections.
196
+ `);
197
+ return;
198
+ }
199
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
200
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
201
+ const files = collectTestFiles(dir);
202
+ const allIssues = [];
203
+ for (const f of files)
204
+ allIssues.push(...analyzeFile(f));
205
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
206
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
207
+ const score = Math.max(0, 100 - highCount * 10 - medCount * 5);
208
+ if (format === "json") {
209
+ console.log(JSON.stringify({
210
+ issues: allIssues,
211
+ score,
212
+ summary: { files: files.length, high: highCount, medium: medCount, total: allIssues.length },
213
+ timestamp: new Date().toISOString(),
214
+ }, null, 2));
215
+ }
216
+ else {
217
+ const badge = score >= 80 ? "✅ ISOLATED" : score >= 50 ? "⚠️ LEAKY" : "❌ COUPLED";
218
+ console.log(`\n Test Isolation: ${badge} (${score}/100)\n ─────────────────────────`);
219
+ console.log(` Test files: ${files.length}\n`);
220
+ if (allIssues.length === 0) {
221
+ console.log(" No isolation issues detected.\n");
222
+ return;
223
+ }
224
+ for (const issue of allIssues.slice(0, 25)) {
225
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
226
+ console.log(` ${icon} ${issue.issue}`);
227
+ console.log(` ${issue.file}:${issue.line}`);
228
+ console.log(` ${issue.detail}`);
229
+ }
230
+ if (allIssues.length > 25)
231
+ console.log(` ... and ${allIssues.length - 25} more`);
232
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
233
+ }
234
+ }
235
+ //# sourceMappingURL=test-isolation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-isolation.js","sourceRoot":"","sources":["../../src/commands/test-isolation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Timeout audit — trace timeout and deadline settings through call chains.
3
+ */
4
+ export declare function runTimeoutAudit(argv: string[]): void;
5
+ //# sourceMappingURL=timeout-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-audit.d.ts","sourceRoot":"","sources":["../../src/commands/timeout-audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgLH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+DpD"}