@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,211 @@
1
+ /**
2
+ * Timeout audit — trace timeout and deadline settings through call chains.
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"]);
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
+ for (let i = 0; i < lines.length; i++) {
52
+ const line = lines[i];
53
+ // Hardcoded timeout values
54
+ const hardcodedMatch = line.match(/timeout\s*[:=]\s*(\d+)/i);
55
+ if (hardcodedMatch) {
56
+ const val = parseInt(hardcodedMatch[1], 10);
57
+ if (val > 0 && !line.includes("config") && !line.includes("option") && !line.includes("env")) {
58
+ issues.push({
59
+ file: filepath,
60
+ line: i + 1,
61
+ issue: "Hardcoded timeout value",
62
+ severity: "medium",
63
+ detail: `Timeout = ${val}${val >= 1000 ? "ms" : ""} — extract to configuration for tunability`,
64
+ });
65
+ }
66
+ }
67
+ // Missing timeout on fetch/axios/http calls
68
+ if (/(?:fetch|axios|http\.(?:get|post|put|delete|request)|got|superagent)\s*\(/.test(line)) {
69
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
70
+ if (!/timeout|signal|AbortController|deadline/i.test(block)) {
71
+ issues.push({
72
+ file: filepath,
73
+ line: i + 1,
74
+ issue: "HTTP call without timeout",
75
+ severity: "high",
76
+ detail: "Network call has no timeout — can hang indefinitely under failure conditions",
77
+ });
78
+ }
79
+ }
80
+ // Missing timeout on database queries
81
+ if (/\.(?:query|execute|find|findOne|aggregate|raw)\s*\(/.test(line)) {
82
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
83
+ if (/(?:db|pool|connection|prisma|knex|sequelize|mongo)/i.test(block) &&
84
+ !/timeout|maxTimeMS|statement_timeout/i.test(block)) {
85
+ issues.push({
86
+ file: filepath,
87
+ line: i + 1,
88
+ issue: "Database query without timeout",
89
+ severity: "medium",
90
+ detail: "DB query has no timeout — long-running queries can exhaust connection pool",
91
+ });
92
+ }
93
+ }
94
+ // setTimeout with very large values
95
+ const setTimeoutMatch = line.match(/setTimeout\s*\([^,]+,\s*(\d+)\)/);
96
+ if (setTimeoutMatch) {
97
+ const val = parseInt(setTimeoutMatch[1], 10);
98
+ if (val > 300000) {
99
+ issues.push({
100
+ file: filepath,
101
+ line: i + 1,
102
+ issue: "Excessive setTimeout delay",
103
+ severity: "low",
104
+ detail: `setTimeout delay = ${Math.round(val / 1000)}s — consider persistent scheduling instead`,
105
+ });
106
+ }
107
+ }
108
+ // Promise.race without timeout
109
+ if (/Promise\.all\s*\(/.test(line)) {
110
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
111
+ if (!/timeout|Promise\.race|AbortController/i.test(block)) {
112
+ issues.push({
113
+ file: filepath,
114
+ line: i + 1,
115
+ issue: "Promise.all without timeout guard",
116
+ severity: "medium",
117
+ detail: "Promise.all can hang if any promise never resolves — wrap with Promise.race timeout",
118
+ });
119
+ }
120
+ }
121
+ // Upstream vs downstream timeout mismatch (heuristic)
122
+ if (/server.*timeout|listen.*timeout|request.*timeout/i.test(line)) {
123
+ const downstreamBlock = lines.slice(i, Math.min(i + 30, lines.length)).join("\n");
124
+ const serverTimeout = line.match(/timeout\s*[:=]\s*(\d+)/i);
125
+ const clientTimeout = downstreamBlock.match(/(?:fetch|axios|http).*timeout\s*[:=]\s*(\d+)/i);
126
+ if (serverTimeout && clientTimeout) {
127
+ const server = parseInt(serverTimeout[1], 10);
128
+ const client = parseInt(clientTimeout[1], 10);
129
+ if (client > server) {
130
+ issues.push({
131
+ file: filepath,
132
+ line: i + 1,
133
+ issue: "Downstream timeout exceeds upstream",
134
+ severity: "high",
135
+ detail: `Client timeout (${client}) > server timeout (${server}) — response may be dropped after server times out`,
136
+ });
137
+ }
138
+ }
139
+ }
140
+ // gRPC / streaming without deadline
141
+ if (/grpc|\.stream\s*\(|createReadStream|createWriteStream/i.test(line)) {
142
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
143
+ if (!/deadline|timeout|destroy|abort/i.test(block)) {
144
+ issues.push({
145
+ file: filepath,
146
+ line: i + 1,
147
+ issue: "Stream/gRPC call without deadline",
148
+ severity: "medium",
149
+ detail: "Streaming call has no deadline — can leak resources if peer becomes unresponsive",
150
+ });
151
+ }
152
+ }
153
+ }
154
+ return issues;
155
+ }
156
+ // ─── CLI ────────────────────────────────────────────────────────────────────
157
+ export function runTimeoutAudit(argv) {
158
+ if (argv.includes("--help") || argv.includes("-h")) {
159
+ console.log(`
160
+ judges timeout-audit — Trace timeout and deadline propagation gaps
161
+
162
+ Usage:
163
+ judges timeout-audit [dir]
164
+ judges timeout-audit src/ --format json
165
+
166
+ Options:
167
+ [dir] Directory to scan (default: .)
168
+ --format json JSON output
169
+ --help, -h Show this help
170
+
171
+ Checks: missing HTTP timeouts, hardcoded values, DB query timeouts,
172
+ excessive setTimeout, Promise.all without guards, downstream > upstream mismatch.
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 allIssues = [];
180
+ for (const f of files)
181
+ allIssues.push(...analyzeFile(f));
182
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
183
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
184
+ const score = Math.max(0, 100 - highCount * 10 - medCount * 4);
185
+ if (format === "json") {
186
+ console.log(JSON.stringify({
187
+ issues: allIssues,
188
+ score,
189
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
190
+ timestamp: new Date().toISOString(),
191
+ }, null, 2));
192
+ }
193
+ else {
194
+ const badge = score >= 80 ? "✅ ROBUST" : score >= 50 ? "⚠️ GAPS" : "❌ FRAGILE";
195
+ console.log(`\n Timeout Safety: ${badge} (${score}/100)\n ─────────────────────────────`);
196
+ if (allIssues.length === 0) {
197
+ console.log(" No timeout issues detected.\n");
198
+ return;
199
+ }
200
+ for (const issue of allIssues.slice(0, 25)) {
201
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
202
+ console.log(` ${icon} ${issue.issue}`);
203
+ console.log(` ${issue.file}:${issue.line}`);
204
+ console.log(` ${issue.detail}`);
205
+ }
206
+ if (allIssues.length > 25)
207
+ console.log(` ... and ${allIssues.length - 25} more`);
208
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
209
+ }
210
+ }
211
+ //# sourceMappingURL=timeout-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-audit.js","sourceRoot":"","sources":["../../src/commands/timeout-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Type boundary — check type safety at serialization boundaries.
3
+ */
4
+ export declare function runTypeBoundary(argv: string[]): void;
5
+ //# sourceMappingURL=type-boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-boundary.d.ts","sourceRoot":"","sources":["../../src/commands/type-boundary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyMH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgEpD"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Type boundary — check type safety at serialization boundaries.
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
+ for (let i = 0; i < lines.length; i++) {
52
+ const line = lines[i];
53
+ // JSON.parse without validation
54
+ if (/JSON\.parse\s*\(/.test(line)) {
55
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
56
+ // Check for type assertion without validation
57
+ if (/as\s+\w+/.test(line) || /as\s+\w+/.test(lines[i + 1] || "")) {
58
+ if (!/zod|joi|yup|ajv|validate|schema|assert|guard|is\w+\(/i.test(block)) {
59
+ issues.push({
60
+ file: filepath,
61
+ line: i + 1,
62
+ issue: "JSON.parse with unchecked type assertion",
63
+ severity: "high",
64
+ detail: "Type assertion on parsed JSON without runtime validation — external data shape is unverified",
65
+ });
66
+ }
67
+ }
68
+ // JSON.parse returning any without narrowing
69
+ if (!/:\s*\w+\s*=|as\s+\w+|validate|parse|schema/i.test(line) && !/validate|schema|guard/i.test(block)) {
70
+ issues.push({
71
+ file: filepath,
72
+ line: i + 1,
73
+ issue: "JSON.parse result used without validation",
74
+ severity: "medium",
75
+ detail: "Parsed JSON used directly — add runtime type checking for external data",
76
+ });
77
+ }
78
+ }
79
+ // Unchecked 'as' cast on external data sources
80
+ if (/\bas\s+(?!const\b)\w+/.test(line)) {
81
+ if (/(?:response|body|data|result|payload|params|query|req\.|res\.)/.test(line)) {
82
+ const block = lines.slice(Math.max(0, i - 3), Math.min(i + 3, lines.length)).join("\n");
83
+ if (!/validate|schema|guard|assert|instanceof|typeof|zod|joi|ajv/i.test(block)) {
84
+ issues.push({
85
+ file: filepath,
86
+ line: i + 1,
87
+ issue: "Type assertion on external data",
88
+ severity: "high",
89
+ detail: "Casting external data with 'as' bypasses type safety — validate at boundary",
90
+ });
91
+ }
92
+ }
93
+ }
94
+ // @ts-ignore or @ts-expect-error suppressing boundary checks
95
+ if (/@ts-ignore|@ts-expect-error/.test(line)) {
96
+ const nextLine = lines[i + 1] || "";
97
+ if (/parse|response|body|fetch|axios|request|query/i.test(nextLine)) {
98
+ issues.push({
99
+ file: filepath,
100
+ line: i + 1,
101
+ issue: "Type suppression at data boundary",
102
+ severity: "high",
103
+ detail: "ts-ignore/ts-expect-error hides type errors at external boundary — fix the types instead",
104
+ });
105
+ }
106
+ }
107
+ // any type at API boundary
108
+ if (/:\s*any\b/.test(line)) {
109
+ if (/(?:request|response|handler|controller|route|api|endpoint|middleware)/i.test(line) ||
110
+ /(?:req|res|ctx|context|body|params|query)/i.test(line)) {
111
+ issues.push({
112
+ file: filepath,
113
+ line: i + 1,
114
+ issue: "'any' type at API boundary",
115
+ severity: "medium",
116
+ detail: "Using 'any' at API boundary loses type safety — define explicit request/response types",
117
+ });
118
+ }
119
+ }
120
+ // SQL query results used without type checking
121
+ if (/\.query\s*\(|\.raw\s*\(|\.execute\s*\(/.test(line)) {
122
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
123
+ if (/as\s+\w+/.test(block) && !/validate|schema|guard|rows\.\w+/i.test(block)) {
124
+ issues.push({
125
+ file: filepath,
126
+ line: i + 1,
127
+ issue: "SQL result with unchecked type assertion",
128
+ severity: "medium",
129
+ detail: "Query result cast without validation — column types may differ from TypeScript types",
130
+ });
131
+ }
132
+ }
133
+ // process.env without validation
134
+ if (/process\.env\.\w+/.test(line)) {
135
+ if (!/!\s*$|as\s+string|\?\?|[|][|]|if\s*\(|assert|env.*schema|zod|joi/i.test(line)) {
136
+ // Only flag if used directly without null check
137
+ const block = lines.slice(Math.max(0, i - 2), Math.min(i + 2, lines.length)).join("\n");
138
+ if (!/if\s*\(|[?][?]|\|\||assert|throw|env.*config/i.test(block)) {
139
+ issues.push({
140
+ file: filepath,
141
+ line: i + 1,
142
+ issue: "process.env used without validation",
143
+ severity: "low",
144
+ detail: "Environment variable used without null check — may be undefined at runtime",
145
+ });
146
+ }
147
+ }
148
+ }
149
+ // FormData/URLSearchParams parsed without validation
150
+ if (/FormData|URLSearchParams|formData|searchParams/i.test(line) && /\.get\s*\(/.test(line)) {
151
+ const block = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
152
+ if (!/validate|schema|typeof|instanceof|zod|joi/i.test(block)) {
153
+ if (/as\s+\w+/.test(block)) {
154
+ issues.push({
155
+ file: filepath,
156
+ line: i + 1,
157
+ issue: "Form data cast without validation",
158
+ severity: "medium",
159
+ detail: "Form/URL params cast without validation — user input shape is unverified",
160
+ });
161
+ }
162
+ }
163
+ }
164
+ // Protobuf/gRPC decode without validation
165
+ if (/\.decode\s*\(|\.deserialize|\.fromBinary|\.fromJSON/i.test(line)) {
166
+ const block = lines.slice(i, Math.min(i + 5, lines.length)).join("\n");
167
+ if (!/validate|verify|check|schema/i.test(block)) {
168
+ issues.push({
169
+ file: filepath,
170
+ line: i + 1,
171
+ issue: "Deserialization without validation",
172
+ severity: "medium",
173
+ detail: "Decoded protobuf/binary data not validated — may contain unexpected fields or types",
174
+ });
175
+ }
176
+ }
177
+ }
178
+ return issues;
179
+ }
180
+ // ─── CLI ────────────────────────────────────────────────────────────────────
181
+ export function runTypeBoundary(argv) {
182
+ if (argv.includes("--help") || argv.includes("-h")) {
183
+ console.log(`
184
+ judges type-boundary — Check type safety at serialization boundaries
185
+
186
+ Usage:
187
+ judges type-boundary [dir]
188
+ judges type-boundary src/ --format json
189
+
190
+ Options:
191
+ [dir] Directory to scan (default: .)
192
+ --format json JSON output
193
+ --help, -h Show this help
194
+
195
+ Checks: JSON.parse without validation, unchecked 'as' casts on external data,
196
+ ts-ignore at boundaries, 'any' at API boundaries, SQL result casting,
197
+ unvalidated env vars, form data casting, protobuf decode.
198
+ `);
199
+ return;
200
+ }
201
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
202
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
203
+ const files = collectFiles(dir);
204
+ const allIssues = [];
205
+ for (const f of files)
206
+ allIssues.push(...analyzeFile(f));
207
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
208
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
209
+ const score = Math.max(0, 100 - highCount * 8 - medCount * 3);
210
+ if (format === "json") {
211
+ console.log(JSON.stringify({
212
+ issues: allIssues,
213
+ score,
214
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
215
+ timestamp: new Date().toISOString(),
216
+ }, null, 2));
217
+ }
218
+ else {
219
+ const badge = score >= 80 ? "✅ SAFE" : score >= 50 ? "⚠️ LEAKY" : "❌ UNSAFE";
220
+ console.log(`\n Type Boundaries: ${badge} (${score}/100)\n ─────────────────────────────`);
221
+ if (allIssues.length === 0) {
222
+ console.log(" No type boundary issues detected.\n");
223
+ return;
224
+ }
225
+ for (const issue of allIssues.slice(0, 25)) {
226
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
227
+ console.log(` ${icon} ${issue.issue}`);
228
+ console.log(` ${issue.file}:${issue.line}`);
229
+ console.log(` ${issue.detail}`);
230
+ }
231
+ if (allIssues.length > 25)
232
+ console.log(` ... and ${allIssues.length - 25} more`);
233
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
234
+ }
235
+ }
236
+ //# sourceMappingURL=type-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-boundary.js","sourceRoot":"","sources":["../../src/commands/type-boundary.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevinrabun/judges",
3
- "version": "3.55.0",
3
+ "version": "3.57.0",
4
4
  "description": "45 specialized judges that evaluate AI-generated code for security, cost, and quality.",
5
5
  "mcpName": "io.github.KevinRabun/judges",
6
6
  "type": "module",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/kevinrabun/judges",
8
8
  "source": "github"
9
9
  },
10
- "version": "3.55.0",
10
+ "version": "3.57.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.55.0",
15
+ "version": "3.57.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }