@kevinrabun/judges 3.58.0 → 3.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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/adoption-track.d.ts +5 -0
  6. package/dist/commands/adoption-track.d.ts.map +1 -0
  7. package/dist/commands/adoption-track.js +247 -0
  8. package/dist/commands/adoption-track.js.map +1 -0
  9. package/dist/commands/api-misuse.d.ts +5 -0
  10. package/dist/commands/api-misuse.d.ts.map +1 -0
  11. package/dist/commands/api-misuse.js +261 -0
  12. package/dist/commands/api-misuse.js.map +1 -0
  13. package/dist/commands/completion-audit.d.ts +5 -0
  14. package/dist/commands/completion-audit.d.ts.map +1 -0
  15. package/dist/commands/completion-audit.js +297 -0
  16. package/dist/commands/completion-audit.js.map +1 -0
  17. package/dist/commands/context-blind.d.ts +5 -0
  18. package/dist/commands/context-blind.d.ts.map +1 -0
  19. package/dist/commands/context-blind.js +273 -0
  20. package/dist/commands/context-blind.js.map +1 -0
  21. package/dist/commands/cross-file-consistency.d.ts +5 -0
  22. package/dist/commands/cross-file-consistency.d.ts.map +1 -0
  23. package/dist/commands/cross-file-consistency.js +255 -0
  24. package/dist/commands/cross-file-consistency.js.map +1 -0
  25. package/dist/commands/example-leak.d.ts +5 -0
  26. package/dist/commands/example-leak.d.ts.map +1 -0
  27. package/dist/commands/example-leak.js +233 -0
  28. package/dist/commands/example-leak.js.map +1 -0
  29. package/dist/commands/finding-budget.d.ts +5 -0
  30. package/dist/commands/finding-budget.d.ts.map +1 -0
  31. package/dist/commands/finding-budget.js +233 -0
  32. package/dist/commands/finding-budget.js.map +1 -0
  33. package/dist/commands/hallucination-detect.d.ts +5 -0
  34. package/dist/commands/hallucination-detect.d.ts.map +1 -0
  35. package/dist/commands/hallucination-detect.js +351 -0
  36. package/dist/commands/hallucination-detect.js.map +1 -0
  37. package/dist/commands/logic-lint.d.ts +5 -0
  38. package/dist/commands/logic-lint.d.ts.map +1 -0
  39. package/dist/commands/logic-lint.js +256 -0
  40. package/dist/commands/logic-lint.js.map +1 -0
  41. package/dist/commands/over-abstraction.d.ts +5 -0
  42. package/dist/commands/over-abstraction.d.ts.map +1 -0
  43. package/dist/commands/over-abstraction.js +308 -0
  44. package/dist/commands/over-abstraction.js.map +1 -0
  45. package/dist/commands/phantom-import.d.ts +5 -0
  46. package/dist/commands/phantom-import.d.ts.map +1 -0
  47. package/dist/commands/phantom-import.js +261 -0
  48. package/dist/commands/phantom-import.js.map +1 -0
  49. package/dist/commands/review-digest.d.ts +5 -0
  50. package/dist/commands/review-digest.d.ts.map +1 -0
  51. package/dist/commands/review-digest.js +266 -0
  52. package/dist/commands/review-digest.js.map +1 -0
  53. package/dist/commands/review-focus.d.ts +5 -0
  54. package/dist/commands/review-focus.d.ts.map +1 -0
  55. package/dist/commands/review-focus.js +197 -0
  56. package/dist/commands/review-focus.js.map +1 -0
  57. package/dist/commands/security-theater.d.ts +5 -0
  58. package/dist/commands/security-theater.d.ts.map +1 -0
  59. package/dist/commands/security-theater.js +279 -0
  60. package/dist/commands/security-theater.js.map +1 -0
  61. package/dist/commands/spec-conform.d.ts +5 -0
  62. package/dist/commands/spec-conform.d.ts.map +1 -0
  63. package/dist/commands/spec-conform.js +305 -0
  64. package/dist/commands/spec-conform.js.map +1 -0
  65. package/dist/commands/stale-pattern.d.ts +5 -0
  66. package/dist/commands/stale-pattern.d.ts.map +1 -0
  67. package/dist/commands/stale-pattern.js +294 -0
  68. package/dist/commands/stale-pattern.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Review focus — prioritize review attention for AI-generated changes.
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", ".py", ".java", ".go", ".rs", ".cs"]);
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
+ // ─── Risk Analysis ──────────────────────────────────────────────────────────
41
+ function analyzeFileRisk(filepath) {
42
+ let content;
43
+ try {
44
+ content = readFileSync(filepath, "utf-8");
45
+ }
46
+ catch {
47
+ return { file: filepath, priority: "low", score: 0, reasons: ["Could not read file"] };
48
+ }
49
+ const reasons = [];
50
+ let riskScore = 0;
51
+ const fname = basename(filepath).toLowerCase();
52
+ // Security-sensitive patterns
53
+ if (/(?:auth|login|session|token|jwt|oauth|password|credential|secret|crypto|encrypt|decrypt|hash)/i.test(fname)) {
54
+ riskScore += 30;
55
+ reasons.push("Security-sensitive filename");
56
+ }
57
+ if (/(?:sql|exec|spawn|eval|innerHTML|dangerouslySetInnerHTML)/.test(content)) {
58
+ riskScore += 25;
59
+ reasons.push("Contains dangerous operations (sql/exec/eval/innerHTML)");
60
+ }
61
+ // Data mutation
62
+ if (/(?:DELETE|INSERT|UPDATE|DROP|TRUNCATE)\s/i.test(content)) {
63
+ riskScore += 20;
64
+ reasons.push("Contains data mutation SQL statements");
65
+ }
66
+ // Payment/financial
67
+ if (/(?:payment|billing|invoice|charge|refund|stripe|paypal|transaction)/i.test(content)) {
68
+ riskScore += 25;
69
+ reasons.push("Payment/financial logic");
70
+ }
71
+ // External API calls
72
+ const apiCallCount = (content.match(/(?:fetch|axios|http\.(?:get|post|put|delete)|request\()/g) || []).length;
73
+ if (apiCallCount > 0) {
74
+ riskScore += apiCallCount * 5;
75
+ reasons.push(`${apiCallCount} external API calls`);
76
+ }
77
+ // Complexity indicators
78
+ const lines = content.split("\n");
79
+ const lineCount = lines.length;
80
+ if (lineCount > 300) {
81
+ riskScore += 10;
82
+ reasons.push(`Large file (${lineCount} lines)`);
83
+ }
84
+ // Deep nesting
85
+ let maxDepth = 0;
86
+ let depth = 0;
87
+ for (const line of lines) {
88
+ for (const ch of line) {
89
+ if (ch === "{")
90
+ depth++;
91
+ if (ch === "}")
92
+ depth--;
93
+ if (depth > maxDepth)
94
+ maxDepth = depth;
95
+ }
96
+ }
97
+ if (maxDepth > 5) {
98
+ riskScore += 10;
99
+ reasons.push(`Deep nesting (${maxDepth} levels)`);
100
+ }
101
+ // Error handling density
102
+ const tryCatchCount = (content.match(/try\s*\{/g) || []).length;
103
+ const funcCount = (content.match(/(?:function|=>)\s*[({]/g) || []).length;
104
+ if (funcCount > 3 && tryCatchCount < funcCount * 0.2) {
105
+ riskScore += 5;
106
+ reasons.push("Low error handling coverage");
107
+ }
108
+ // State management
109
+ if (/(?:useState|useReducer|createStore|createSlice|vuex|pinia)/i.test(content)) {
110
+ riskScore += 10;
111
+ reasons.push("Contains state management logic");
112
+ }
113
+ // Database operations
114
+ if (/(?:prisma|sequelize|typeorm|mongoose|knex|drizzle|\.query\(|\.execute\()/i.test(content)) {
115
+ riskScore += 15;
116
+ reasons.push("Database operations");
117
+ }
118
+ // Middleware / interceptors
119
+ if (/(?:middleware|interceptor|guard|pipe|filter)/i.test(fname)) {
120
+ riskScore += 15;
121
+ reasons.push("Middleware/interceptor (cross-cutting concern)");
122
+ }
123
+ // Route definitions
124
+ const routeCount = (content.match(/\.(get|post|put|patch|delete|use)\s*\(\s*['"]?\//g) || []).length;
125
+ if (routeCount > 0) {
126
+ riskScore += routeCount * 3;
127
+ reasons.push(`${routeCount} route definitions`);
128
+ }
129
+ // Configuration / environment
130
+ if (/(?:config|env|settings|options)/i.test(fname)) {
131
+ riskScore += 10;
132
+ reasons.push("Configuration file");
133
+ }
134
+ const priority = riskScore >= 50 ? "critical" : riskScore >= 30 ? "high" : riskScore >= 15 ? "medium" : "low";
135
+ return { file: filepath, priority, score: Math.min(100, riskScore), reasons };
136
+ }
137
+ // ─── CLI ────────────────────────────────────────────────────────────────────
138
+ export function runReviewFocus(argv) {
139
+ if (argv.includes("--help") || argv.includes("-h")) {
140
+ console.log(`
141
+ judges review-focus — Prioritize review attention for AI-generated changes
142
+
143
+ Usage:
144
+ judges review-focus [dir]
145
+ judges review-focus src/ --format json
146
+
147
+ Options:
148
+ [dir] Directory to scan (default: .)
149
+ --format json JSON output
150
+ --top N Show only top N files (default: 15)
151
+ --help, -h Show this help
152
+
153
+ Risk signals: security-sensitive files, dangerous operations, data mutation,
154
+ payment logic, external APIs, deep nesting, state management, database ops,
155
+ middleware, route definitions, configuration.
156
+ `);
157
+ return;
158
+ }
159
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
160
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
161
+ const topN = parseInt(argv.find((_a, i) => argv[i - 1] === "--top") || "15", 10);
162
+ const files = collectFiles(dir);
163
+ const allItems = files
164
+ .map((f) => analyzeFileRisk(f))
165
+ .filter((i) => i.score > 0)
166
+ .sort((a, b) => b.score - a.score);
167
+ if (format === "json") {
168
+ console.log(JSON.stringify({
169
+ items: allItems.slice(0, topN),
170
+ totalFiles: files.length,
171
+ scoredFiles: allItems.length,
172
+ timestamp: new Date().toISOString(),
173
+ }, null, 2));
174
+ }
175
+ else {
176
+ console.log(`\n Review Focus — Top ${Math.min(topN, allItems.length)} of ${files.length} files\n ─────────────────────────────`);
177
+ if (allItems.length === 0) {
178
+ console.log(" No high-risk files detected.\n");
179
+ return;
180
+ }
181
+ for (const item of allItems.slice(0, topN)) {
182
+ const icon = item.priority === "critical"
183
+ ? "🔴"
184
+ : item.priority === "high"
185
+ ? "🟠"
186
+ : item.priority === "medium"
187
+ ? "🟡"
188
+ : "🔵";
189
+ console.log(` ${icon} [${item.score}] ${item.file}`);
190
+ console.log(` ${item.reasons.join(" | ")}`);
191
+ }
192
+ const critCount = allItems.filter((i) => i.priority === "critical").length;
193
+ const highCount = allItems.filter((i) => i.priority === "high").length;
194
+ console.log(`\n Critical: ${critCount} | High: ${highCount} | Total scored: ${allItems.length}/${files.length}\n`);
195
+ }
196
+ }
197
+ //# sourceMappingURL=review-focus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-focus.js","sourceRoot":"","sources":["../../src/commands/review-focus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Security-theater — detect security-looking code that provides no actual protection.
3
+ */
4
+ export declare function runSecurityTheater(argv: string[]): void;
5
+ //# sourceMappingURL=security-theater.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-theater.d.ts","sourceRoot":"","sources":["../../src/commands/security-theater.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4PH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiEvD"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Security-theater — detect security-looking code that provides no actual protection.
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", ".cs"]);
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
+ const trimmed = line.trim();
54
+ if (trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*"))
55
+ continue;
56
+ // Weak password hashing
57
+ if (/(?:createHash|hashlib\.)\s*\(\s*['"](?:md5|sha1)['"]\s*\)/.test(line) &&
58
+ /password|passwd|pwd/i.test(lines.slice(Math.max(0, i - 3), i + 3).join(" "))) {
59
+ issues.push({
60
+ file: filepath,
61
+ line: i + 1,
62
+ issue: "Weak password hashing (MD5/SHA1)",
63
+ severity: "high",
64
+ detail: "MD5/SHA1 are not appropriate for password hashing — use bcrypt, scrypt, or argon2",
65
+ });
66
+ }
67
+ // Hardcoded encryption keys/IVs
68
+ if (/(?:key|iv|secret|password)\s*[:=]\s*['"][A-Za-z0-9+/=]{8,}['"]/.test(line) &&
69
+ /(?:cipher|encrypt|decrypt|crypto|aes|des)/i.test(lines.slice(Math.max(0, i - 5), i + 5).join(" "))) {
70
+ issues.push({
71
+ file: filepath,
72
+ line: i + 1,
73
+ issue: "Hardcoded encryption key or IV",
74
+ severity: "high",
75
+ detail: "Encryption keys/IVs must not be hardcoded — use environment variables or key management services",
76
+ });
77
+ }
78
+ // Wildcard CORS with auth
79
+ if (/['"]Access-Control-Allow-Origin['"]\s*[:,]\s*['"]\s*[*]\s*['"]/.test(line)) {
80
+ const nearby = lines.slice(i, Math.min(i + 10, lines.length)).join(" ");
81
+ if (/(?:authorization|cookie|credentials|auth)/i.test(nearby)) {
82
+ issues.push({
83
+ file: filepath,
84
+ line: i + 1,
85
+ issue: "CORS wildcard (*) with authentication",
86
+ severity: "high",
87
+ detail: "Access-Control-Allow-Origin: * combined with authentication bypasses same-origin policy protections",
88
+ });
89
+ }
90
+ else {
91
+ issues.push({
92
+ file: filepath,
93
+ line: i + 1,
94
+ issue: "CORS wildcard (*)",
95
+ severity: "medium",
96
+ detail: "CORS wildcard allows any origin — restrict to trusted domains unless truly public",
97
+ });
98
+ }
99
+ }
100
+ // CSRF token generated but never verified
101
+ if (/csrf[_-]?token|csrfToken|_csrf/i.test(line) && /generate|create|set|assign/i.test(line)) {
102
+ const fileContent = content;
103
+ if (!/csrf.*verif|verify.*csrf|csrf.*valid|csrfProtection|csurf/i.test(fileContent)) {
104
+ issues.push({
105
+ file: filepath,
106
+ line: i + 1,
107
+ issue: "CSRF token generated but never verified",
108
+ severity: "high",
109
+ detail: "CSRF tokens must be verified on the server side — generation alone provides no protection",
110
+ });
111
+ }
112
+ }
113
+ // Rate limiting that is too lenient
114
+ if (/rateLimit|rate[_-]?limit/i.test(line)) {
115
+ const context = lines.slice(i, Math.min(i + 5, lines.length)).join(" ");
116
+ const limitMatch = context.match(/(?:max|limit|windowMs|window)\s*[:=]\s*(\d+)/);
117
+ if (limitMatch) {
118
+ const val = parseInt(limitMatch[1], 10);
119
+ if (/max|limit/i.test(limitMatch[0]) && val >= 10000) {
120
+ issues.push({
121
+ file: filepath,
122
+ line: i + 1,
123
+ issue: "Ineffective rate limiting (limit too high)",
124
+ severity: "medium",
125
+ detail: `Rate limit of ${val} requests is too permissive to be protective`,
126
+ });
127
+ }
128
+ }
129
+ }
130
+ // Validation without authorization
131
+ if (/(?:validate|sanitize|check)\s*\(\s*(?:req|request)/.test(line) || /(?:joi|yup|zod)\s*\./.test(line)) {
132
+ if (/(?:body|params|query)/.test(line)) {
133
+ const nearby = lines.slice(Math.max(0, i - 10), Math.min(i + 10, lines.length)).join(" ");
134
+ if (!/(?:auth|authorize|isAuthenticated|requireAuth|passport|jwt|token|session)/.test(nearby)) {
135
+ issues.push({
136
+ file: filepath,
137
+ line: i + 1,
138
+ issue: "Input validation without authorization check",
139
+ severity: "medium",
140
+ detail: "Validating input without checking authorization — an unauthenticated user could send valid-looking data",
141
+ });
142
+ }
143
+ }
144
+ }
145
+ // Client-side only validation
146
+ if (/(?:disabled|readonly|hidden)\s*[=:]\s*(?:true|['"]true['"])/.test(line) &&
147
+ /(?:submit|form|action)/i.test(lines.slice(Math.max(0, i - 5), i + 5).join(" "))) {
148
+ issues.push({
149
+ file: filepath,
150
+ line: i + 1,
151
+ issue: "Client-side-only form restriction",
152
+ severity: "medium",
153
+ detail: "disabled/readonly/hidden form attributes can be bypassed — enforce restrictions server-side",
154
+ });
155
+ }
156
+ // Base64 used as encryption
157
+ if (/(?:btoa|atob|Buffer\.from\([^)]*,\s*['"]base64['"]|base64[_-]?encode|base64[_-]?decode)/i.test(line)) {
158
+ const nearby = lines.slice(Math.max(0, i - 3), i + 3).join(" ");
159
+ if (/(?:encrypt|secret|password|secure|protect|hide)/i.test(nearby)) {
160
+ issues.push({
161
+ file: filepath,
162
+ line: i + 1,
163
+ issue: "Base64 used as encryption",
164
+ severity: "high",
165
+ detail: "Base64 is encoding, not encryption — it provides zero confidentiality",
166
+ });
167
+ }
168
+ }
169
+ // SQL partial parameterization
170
+ if (/(?:query|execute|exec|raw)\s*\(/.test(line)) {
171
+ const context = lines.slice(i, Math.min(i + 3, lines.length)).join(" ");
172
+ if (/\$\{|\+\s*['"]/.test(context) && /[?$]/.test(context)) {
173
+ issues.push({
174
+ file: filepath,
175
+ line: i + 1,
176
+ issue: "Partially parameterized SQL query",
177
+ severity: "high",
178
+ detail: "Query mixes parameterized values with string concatenation — fully parameterize all inputs",
179
+ });
180
+ }
181
+ }
182
+ // Commented-out security controls
183
+ if (/^\s*\/\/\s*(?:app\.use\s*\(\s*(?:helmet|csrf|cors|rateLimit)|requireAuth|isAuthenticated|authorize)/.test(line)) {
184
+ issues.push({
185
+ file: filepath,
186
+ line: i + 1,
187
+ issue: "Commented-out security middleware",
188
+ severity: "high",
189
+ detail: "Security middleware is commented out — likely left disabled from debugging",
190
+ });
191
+ }
192
+ // JWT with 'none' algorithm
193
+ if (/algorithm[s]?\s*[:=]\s*\[?\s*['"]none['"]/i.test(line)) {
194
+ issues.push({
195
+ file: filepath,
196
+ line: i + 1,
197
+ issue: "JWT 'none' algorithm allowed",
198
+ severity: "high",
199
+ detail: "Allowing 'none' algorithm in JWT verification completely disables signature checking",
200
+ });
201
+ }
202
+ // Overly long JWT expiration
203
+ if (/expiresIn\s*[:=]\s*['"](\d+)([dh])['"]/.test(line)) {
204
+ const match = line.match(/expiresIn\s*[:=]\s*['"](\d+)([dh])['"]/);
205
+ if (match) {
206
+ const val = parseInt(match[1], 10);
207
+ const unit = match[2];
208
+ if ((unit === "d" && val > 30) || (unit === "h" && val > 720)) {
209
+ issues.push({
210
+ file: filepath,
211
+ line: i + 1,
212
+ issue: "JWT expiration too long",
213
+ severity: "medium",
214
+ detail: `Token expiration of ${val}${unit} is excessively long — shorter-lived tokens reduce blast radius of theft`,
215
+ });
216
+ }
217
+ }
218
+ }
219
+ }
220
+ return issues;
221
+ }
222
+ // ─── CLI ────────────────────────────────────────────────────────────────────
223
+ export function runSecurityTheater(argv) {
224
+ if (argv.includes("--help") || argv.includes("-h")) {
225
+ console.log(`
226
+ judges security-theater — Detect security-looking code that provides no protection
227
+
228
+ Usage:
229
+ judges security-theater [dir]
230
+ judges security-theater src/ --format json
231
+
232
+ Options:
233
+ [dir] Directory to scan (default: .)
234
+ --format json JSON output
235
+ --help, -h Show this help
236
+
237
+ Checks: weak password hashing, hardcoded keys/IVs, wildcard CORS with auth,
238
+ unverified CSRF tokens, ineffective rate limiting, validation without auth,
239
+ base64-as-encryption, partial SQL parameterization, commented-out security
240
+ middleware, JWT 'none' algorithm, overly long JWT expiration.
241
+ `);
242
+ return;
243
+ }
244
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
245
+ const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
246
+ const files = collectFiles(dir);
247
+ const allIssues = [];
248
+ for (const f of files)
249
+ allIssues.push(...analyzeFile(f));
250
+ const highCount = allIssues.filter((i) => i.severity === "high").length;
251
+ const medCount = allIssues.filter((i) => i.severity === "medium").length;
252
+ const score = Math.max(0, 100 - highCount * 15 - medCount * 7 - allIssues.filter((i) => i.severity === "low").length * 3);
253
+ if (format === "json") {
254
+ console.log(JSON.stringify({
255
+ issues: allIssues,
256
+ score,
257
+ summary: { high: highCount, medium: medCount, total: allIssues.length },
258
+ timestamp: new Date().toISOString(),
259
+ }, null, 2));
260
+ }
261
+ else {
262
+ const badge = score >= 80 ? "✅ GENUINE SECURITY" : score >= 50 ? "⚠️ THEATER DETECTED" : "❌ SECURITY THEATER";
263
+ console.log(`\n Security-Theater: ${badge} (${score}/100)\n ─────────────────────────────`);
264
+ if (allIssues.length === 0) {
265
+ console.log(" No security theater detected.\n");
266
+ return;
267
+ }
268
+ for (const issue of allIssues.slice(0, 25)) {
269
+ const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
270
+ console.log(` ${icon} ${issue.issue}`);
271
+ console.log(` ${issue.file}:${issue.line}`);
272
+ console.log(` ${issue.detail}`);
273
+ }
274
+ if (allIssues.length > 25)
275
+ console.log(` ... and ${allIssues.length - 25} more`);
276
+ console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
277
+ }
278
+ }
279
+ //# sourceMappingURL=security-theater.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-theater.js","sourceRoot":"","sources":["../../src/commands/security-theater.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Spec conform — check code conformance to project conventions and style patterns.
3
+ */
4
+ export declare function runSpecConform(argv: string[]): void;
5
+ //# sourceMappingURL=spec-conform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-conform.d.ts","sourceRoot":"","sources":["../../src/commands/spec-conform.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6RH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkEnD"}