@kevinrabun/judges 3.50.0 → 3.51.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.
- package/CHANGELOG.md +12 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/ai-gate.d.ts +8 -0
- package/dist/commands/ai-gate.d.ts.map +1 -0
- package/dist/commands/ai-gate.js +213 -0
- package/dist/commands/ai-gate.js.map +1 -0
- package/dist/commands/ai-output-compare.d.ts +9 -0
- package/dist/commands/ai-output-compare.d.ts.map +1 -0
- package/dist/commands/ai-output-compare.js +203 -0
- package/dist/commands/ai-output-compare.js.map +1 -0
- package/dist/commands/ai-pattern-trend.d.ts +9 -0
- package/dist/commands/ai-pattern-trend.d.ts.map +1 -0
- package/dist/commands/ai-pattern-trend.js +224 -0
- package/dist/commands/ai-pattern-trend.js.map +1 -0
- package/dist/commands/arch-audit.d.ts +9 -0
- package/dist/commands/arch-audit.d.ts.map +1 -0
- package/dist/commands/arch-audit.js +284 -0
- package/dist/commands/arch-audit.js.map +1 -0
- package/dist/commands/clarity-score.d.ts +9 -0
- package/dist/commands/clarity-score.d.ts.map +1 -0
- package/dist/commands/clarity-score.js +261 -0
- package/dist/commands/clarity-score.js.map +1 -0
- package/dist/commands/hallucination-score.d.ts +9 -0
- package/dist/commands/hallucination-score.d.ts.map +1 -0
- package/dist/commands/hallucination-score.js +317 -0
- package/dist/commands/hallucination-score.js.map +1 -0
- package/dist/commands/test-suggest.d.ts +9 -0
- package/dist/commands/test-suggest.d.ts.map +1 -0
- package/dist/commands/test-suggest.js +248 -0
- package/dist/commands/test-suggest.js.map +1 -0
- package/dist/commands/vendor-lock-detect.d.ts +8 -0
- package/dist/commands/vendor-lock-detect.d.ts.map +1 -0
- package/dist/commands/vendor-lock-detect.js +289 -0
- package/dist/commands/vendor-lock-detect.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI pattern trend — track how AI-generated code patterns evolve
|
|
3
|
+
* over time in a codebase. Detect drift in hallucination signals,
|
|
4
|
+
* code quality, and AI reliance.
|
|
5
|
+
*
|
|
6
|
+
* All data local (.judges-ai-trend/).
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync } from "fs";
|
|
9
|
+
import { join, extname } from "path";
|
|
10
|
+
// ─── Metric collection ──────────────────────────────────────────────────────
|
|
11
|
+
const SKIP = new Set(["node_modules", ".git", "dist", "build", "coverage"]);
|
|
12
|
+
const EXTS = new Set([".ts", ".js", ".py", ".java", ".cs", ".go", ".rb", ".php", ".rs"]);
|
|
13
|
+
function collectFiles(dir) {
|
|
14
|
+
const result = [];
|
|
15
|
+
function walk(d) {
|
|
16
|
+
let entries;
|
|
17
|
+
try {
|
|
18
|
+
entries = readdirSync(d);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
for (const name of entries) {
|
|
24
|
+
if (SKIP.has(name) || name.startsWith("."))
|
|
25
|
+
continue;
|
|
26
|
+
const full = join(d, name);
|
|
27
|
+
try {
|
|
28
|
+
const sub = readdirSync(full);
|
|
29
|
+
void sub;
|
|
30
|
+
walk(full);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
if (EXTS.has(extname(name).toLowerCase()))
|
|
34
|
+
result.push(full);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
walk(dir);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function collectMetrics(dir) {
|
|
42
|
+
const files = collectFiles(dir);
|
|
43
|
+
let totalComplexity = 0;
|
|
44
|
+
let totalTodos = 0;
|
|
45
|
+
let totalEmptyFns = 0;
|
|
46
|
+
let totalDuplicates = 0;
|
|
47
|
+
let totalCommentLines = 0;
|
|
48
|
+
let totalLines = 0;
|
|
49
|
+
let totalGenericNames = 0;
|
|
50
|
+
let totalTryCatch = 0;
|
|
51
|
+
let totalFunctions = 0;
|
|
52
|
+
let aiIndicators = 0;
|
|
53
|
+
for (const f of files) {
|
|
54
|
+
let content;
|
|
55
|
+
try {
|
|
56
|
+
content = readFileSync(f, "utf-8");
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const lines = content.split("\n");
|
|
62
|
+
totalLines += lines.length;
|
|
63
|
+
// Complexity
|
|
64
|
+
let complexity = 1;
|
|
65
|
+
for (const line of lines) {
|
|
66
|
+
if (/\b(?:if|else\s+if|for|while|switch|catch|&&|\|\|)\b/.test(line))
|
|
67
|
+
complexity++;
|
|
68
|
+
}
|
|
69
|
+
totalComplexity += complexity;
|
|
70
|
+
// TODOs
|
|
71
|
+
totalTodos += (content.match(/\/\/\s*(?:TODO|FIXME|HACK|PLACEHOLDER)/gi) || []).length;
|
|
72
|
+
// Empty functions
|
|
73
|
+
totalEmptyFns += (content.match(/\bfunction\s+\w+\s*\([^)]*\)\s*{\s*}|=>\s*{\s*}/g) || []).length;
|
|
74
|
+
// Duplicates
|
|
75
|
+
const lineSet = new Map();
|
|
76
|
+
for (const line of lines) {
|
|
77
|
+
const trimmed = line.trim();
|
|
78
|
+
if (trimmed.length > 20)
|
|
79
|
+
lineSet.set(trimmed, (lineSet.get(trimmed) || 0) + 1);
|
|
80
|
+
}
|
|
81
|
+
for (const [, count] of lineSet) {
|
|
82
|
+
if (count >= 3)
|
|
83
|
+
totalDuplicates++;
|
|
84
|
+
}
|
|
85
|
+
// Comments
|
|
86
|
+
totalCommentLines += lines.filter((l) => /^\s*(?:\/\/|\/?\*|#)/.test(l)).length;
|
|
87
|
+
// Generic names
|
|
88
|
+
totalGenericNames += (content.match(/(?:const|let|var)\s+(?:data|result|value|item|temp|tmp)\s*[=:]/g) || [])
|
|
89
|
+
.length;
|
|
90
|
+
// Error handling
|
|
91
|
+
totalTryCatch += (content.match(/\btry\s*{/g) || []).length;
|
|
92
|
+
totalFunctions += (content.match(/\bfunction\b|=>/g) || []).length;
|
|
93
|
+
// AI indicators
|
|
94
|
+
if (/generated\s+(?:by|with)\s+(?:ai|gpt|copilot|claude)/i.test(content))
|
|
95
|
+
aiIndicators++;
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
totalFiles: files.length,
|
|
99
|
+
aiIndicatorCount: aiIndicators,
|
|
100
|
+
avgComplexity: files.length > 0 ? Math.round(totalComplexity / files.length) : 0,
|
|
101
|
+
todoCount: totalTodos,
|
|
102
|
+
emptyFunctionCount: totalEmptyFns,
|
|
103
|
+
duplicateBlockCount: totalDuplicates,
|
|
104
|
+
commentRatio: totalLines > 0 ? Math.round((totalCommentLines / totalLines) * 100) : 0,
|
|
105
|
+
genericNamingCount: totalGenericNames,
|
|
106
|
+
errorHandlingRatio: totalFunctions > 0 ? Math.round((totalTryCatch / totalFunctions) * 100) : 0,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
110
|
+
const TREND_DIR = join(".", ".judges-ai-trend");
|
|
111
|
+
function loadHistory() {
|
|
112
|
+
const histFile = join(TREND_DIR, "history.json");
|
|
113
|
+
if (!existsSync(histFile))
|
|
114
|
+
return [];
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(readFileSync(histFile, "utf-8"));
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function saveHistory(history) {
|
|
123
|
+
if (!existsSync(TREND_DIR))
|
|
124
|
+
mkdirSync(TREND_DIR, { recursive: true });
|
|
125
|
+
writeFileSync(join(TREND_DIR, "history.json"), JSON.stringify(history, null, 2));
|
|
126
|
+
}
|
|
127
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
128
|
+
export function runAiPatternTrend(argv) {
|
|
129
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
130
|
+
console.log(`
|
|
131
|
+
judges ai-pattern-trend — Track AI-generated code pattern evolution
|
|
132
|
+
|
|
133
|
+
Usage:
|
|
134
|
+
judges ai-pattern-trend [dir] Capture snapshot and show trend
|
|
135
|
+
judges ai-pattern-trend --capture Capture current metrics only
|
|
136
|
+
judges ai-pattern-trend --show Show historical trend
|
|
137
|
+
judges ai-pattern-trend --reset Clear trend history
|
|
138
|
+
|
|
139
|
+
Options:
|
|
140
|
+
--capture Capture a new snapshot without showing history
|
|
141
|
+
--show Show trend without capturing
|
|
142
|
+
--reset Clear all trend data
|
|
143
|
+
--last <n> Show last N snapshots (default: 10)
|
|
144
|
+
--format json JSON output
|
|
145
|
+
--help, -h Show this help
|
|
146
|
+
|
|
147
|
+
Tracks: AI indicators, complexity, TODOs, empty functions,
|
|
148
|
+
duplicates, comment ratio, generic naming, error handling.
|
|
149
|
+
`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
153
|
+
if (argv.includes("--reset")) {
|
|
154
|
+
saveHistory([]);
|
|
155
|
+
console.log(" Trend history cleared.");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const target = argv.find((a) => !a.startsWith("--") && !argv[argv.indexOf(a) - 1]?.startsWith("--")) || ".";
|
|
159
|
+
const showOnly = argv.includes("--show");
|
|
160
|
+
const captureOnly = argv.includes("--capture");
|
|
161
|
+
const lastN = parseInt(argv.find((_a, i) => argv[i - 1] === "--last") || "10");
|
|
162
|
+
const history = loadHistory();
|
|
163
|
+
// Capture snapshot
|
|
164
|
+
if (!showOnly) {
|
|
165
|
+
if (!existsSync(target)) {
|
|
166
|
+
console.error(` Path not found: ${target}`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const metrics = collectMetrics(target);
|
|
170
|
+
const snapshot = { timestamp: new Date().toISOString(), metrics };
|
|
171
|
+
history.push(snapshot);
|
|
172
|
+
saveHistory(history);
|
|
173
|
+
if (captureOnly) {
|
|
174
|
+
console.log(` ✅ Snapshot captured (${metrics.totalFiles} files)`);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Show trend
|
|
179
|
+
const recent = history.slice(-lastN);
|
|
180
|
+
if (format === "json") {
|
|
181
|
+
console.log(JSON.stringify({ snapshots: recent, totalSnapshots: history.length, timestamp: new Date().toISOString() }, null, 2));
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
console.log(`\n AI Pattern Trend — ${history.length} snapshots\n ──────────────────────────`);
|
|
185
|
+
if (recent.length === 0) {
|
|
186
|
+
console.log(` No data yet. Run: judges ai-pattern-trend <dir>\n`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
// Metric headers
|
|
190
|
+
const metricKeys = [
|
|
191
|
+
{ key: "totalFiles", label: "Files", higherIsWorse: false },
|
|
192
|
+
{ key: "aiIndicatorCount", label: "AI Markers", higherIsWorse: true },
|
|
193
|
+
{ key: "avgComplexity", label: "Avg Complex", higherIsWorse: true },
|
|
194
|
+
{ key: "todoCount", label: "TODOs", higherIsWorse: true },
|
|
195
|
+
{ key: "emptyFunctionCount", label: "Empty Fns", higherIsWorse: true },
|
|
196
|
+
{ key: "genericNamingCount", label: "Gen Names", higherIsWorse: true },
|
|
197
|
+
{ key: "commentRatio", label: "Comment %", higherIsWorse: false },
|
|
198
|
+
{ key: "errorHandlingRatio", label: "ErrHandl %", higherIsWorse: false },
|
|
199
|
+
];
|
|
200
|
+
console.log(`\n ${"Date".padEnd(12)} ${metricKeys.map((m) => m.label.padEnd(12)).join("")}`);
|
|
201
|
+
console.log(` ${"─".repeat(12 + metricKeys.length * 12)}`);
|
|
202
|
+
for (const snap of recent) {
|
|
203
|
+
const date = new Date(snap.timestamp).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
204
|
+
const vals = metricKeys.map((m) => String(snap.metrics[m.key]).padEnd(12)).join("");
|
|
205
|
+
console.log(` ${date.padEnd(12)} ${vals}`);
|
|
206
|
+
}
|
|
207
|
+
// Trend arrows
|
|
208
|
+
if (recent.length >= 2) {
|
|
209
|
+
const first = recent[0].metrics;
|
|
210
|
+
const last = recent[recent.length - 1].metrics;
|
|
211
|
+
console.log(`\n Trends:`);
|
|
212
|
+
for (const m of metricKeys) {
|
|
213
|
+
const delta = last[m.key] - first[m.key];
|
|
214
|
+
if (delta === 0)
|
|
215
|
+
continue;
|
|
216
|
+
const direction = delta > 0 ? "↑" : "↓";
|
|
217
|
+
const good = delta > 0 !== m.higherIsWorse;
|
|
218
|
+
const icon = good ? "✅" : "⚠️";
|
|
219
|
+
console.log(` ${icon} ${m.label}: ${direction} ${Math.abs(delta)} (${first[m.key]} → ${last[m.key]})`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
console.log("");
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=ai-pattern-trend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-pattern-trend.js","sourceRoot":"","sources":["../../src/commands/ai-pattern-trend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture audit — evaluate architectural implications of
|
|
3
|
+
* AI-generated code: coupling, separation of concerns, dependency
|
|
4
|
+
* injection, testability, scalability.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runArchAudit(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=arch-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arch-audit.d.ts","sourceRoot":"","sources":["../../src/commands/arch-audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+MH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiHjD"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture audit — evaluate architectural implications of
|
|
3
|
+
* AI-generated code: coupling, separation of concerns, dependency
|
|
4
|
+
* injection, testability, scalability.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
9
|
+
import { join, extname, relative } from "path";
|
|
10
|
+
// ─── Analysers ──────────────────────────────────────────────────────────────
|
|
11
|
+
function analyzeArchitecture(content, filePath) {
|
|
12
|
+
const lines = content.split("\n");
|
|
13
|
+
const metrics = [];
|
|
14
|
+
const issues = [];
|
|
15
|
+
// 1. Coupling — count imports / dependencies
|
|
16
|
+
const importLines = lines.filter((l) => /^\s*import\s/.test(l) || /require\s*\(/.test(l));
|
|
17
|
+
const importCount = importLines.length;
|
|
18
|
+
const couplingScore = importCount <= 5 ? 100 : importCount <= 10 ? 75 : importCount <= 20 ? 50 : importCount <= 30 ? 25 : 10;
|
|
19
|
+
metrics.push({
|
|
20
|
+
id: "coupling",
|
|
21
|
+
label: "Loose Coupling",
|
|
22
|
+
score: couplingScore,
|
|
23
|
+
weight: 20,
|
|
24
|
+
detail: `${importCount} imports`,
|
|
25
|
+
});
|
|
26
|
+
if (importCount > 15) {
|
|
27
|
+
issues.push({
|
|
28
|
+
id: "high-coupling",
|
|
29
|
+
label: "High Coupling",
|
|
30
|
+
severity: "high",
|
|
31
|
+
detail: `${importCount} imports — consider splitting this module`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// 2. Separation of concerns — detect mixed responsibilities
|
|
35
|
+
const hasDom = /document\.|querySelector|innerHTML|addEventListener/.test(content);
|
|
36
|
+
const hasDB = /createConnection|query\(|findOne|findMany|prisma\.|mongoose\.|sequelize/.test(content);
|
|
37
|
+
const hasHTTP = /fetch\(|axios\.|http\.|https\.|request\(/.test(content);
|
|
38
|
+
const hasFS = /readFileSync|writeFileSync|createReadStream|createWriteStream/.test(content);
|
|
39
|
+
const concernCount = [hasDom, hasDB, hasHTTP, hasFS].filter(Boolean).length;
|
|
40
|
+
const socScore = concernCount <= 1 ? 100 : concernCount === 2 ? 60 : 30;
|
|
41
|
+
metrics.push({
|
|
42
|
+
id: "soc",
|
|
43
|
+
label: "Separation of Concerns",
|
|
44
|
+
score: socScore,
|
|
45
|
+
weight: 20,
|
|
46
|
+
detail: `${concernCount} concern(s) detected`,
|
|
47
|
+
});
|
|
48
|
+
if (concernCount > 1) {
|
|
49
|
+
const mixed = [hasDom && "DOM", hasDB && "Database", hasHTTP && "HTTP", hasFS && "File I/O"]
|
|
50
|
+
.filter(Boolean)
|
|
51
|
+
.join(", ");
|
|
52
|
+
issues.push({ id: "mixed-concerns", label: "Mixed Concerns", severity: "medium", detail: `File mixes: ${mixed}` });
|
|
53
|
+
}
|
|
54
|
+
// 3. Dependency injection / hardcoded dependencies
|
|
55
|
+
const hardcodedNew = (content.match(/new\s+\w+\(/g) || []).length;
|
|
56
|
+
const hasConstructorInjection = /constructor\s*\([^)]*\b(?:private|public|readonly)\b/.test(content);
|
|
57
|
+
const hasParameterInjection = /function\s+\w+\s*\([^)]*:\s*\w+Interface\b/.test(content) || /\w+:\s*\w+Service\b/.test(content);
|
|
58
|
+
const diScore = hardcodedNew <= 2 || hasConstructorInjection || hasParameterInjection ? 100 : hardcodedNew <= 5 ? 60 : 30;
|
|
59
|
+
metrics.push({
|
|
60
|
+
id: "dependency-injection",
|
|
61
|
+
label: "Dependency Injection",
|
|
62
|
+
score: diScore,
|
|
63
|
+
weight: 15,
|
|
64
|
+
detail: `${hardcodedNew} direct instantiations`,
|
|
65
|
+
});
|
|
66
|
+
if (hardcodedNew > 5 && !hasConstructorInjection) {
|
|
67
|
+
issues.push({
|
|
68
|
+
id: "no-di",
|
|
69
|
+
label: "No Dependency Injection",
|
|
70
|
+
severity: "medium",
|
|
71
|
+
detail: `${hardcodedNew} hardcoded instantiations without constructor injection`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// 4. Testability
|
|
75
|
+
const exportCount = (content.match(/\bexport\s+(?:function|class|const|interface|type|enum)\b/g) || []).length;
|
|
76
|
+
const hasDefault = /\bexport\s+default\b/.test(content);
|
|
77
|
+
const hasGlobalState = /\blet\s+\w+\s*=/.test(content) && !/\bfunction\b/.test(content.split(/\blet\b/)[0] || "");
|
|
78
|
+
const sideEffects = (content.match(/console\.\w+|process\.exit|process\.env/g) || []).length;
|
|
79
|
+
const testabilityScore = (exportCount > 0 || hasDefault ? 30 : 0) +
|
|
80
|
+
(hasGlobalState ? 0 : 25) +
|
|
81
|
+
(hardcodedNew <= 3 ? 25 : 0) +
|
|
82
|
+
(sideEffects <= 3 ? 20 : sideEffects <= 8 ? 10 : 0);
|
|
83
|
+
metrics.push({ id: "testability", label: "Testability", score: Math.min(100, testabilityScore), weight: 15 });
|
|
84
|
+
if (testabilityScore < 50) {
|
|
85
|
+
issues.push({
|
|
86
|
+
id: "low-testability",
|
|
87
|
+
label: "Low Testability",
|
|
88
|
+
severity: "medium",
|
|
89
|
+
detail: "Module has global state, side effects, or no exports — hard to unit-test",
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// 5. Single Responsibility — file length & export count
|
|
93
|
+
const fileLength = lines.length;
|
|
94
|
+
const srScore = fileLength <= 200 ? 100 : fileLength <= 400 ? 70 : fileLength <= 600 ? 40 : 10;
|
|
95
|
+
metrics.push({
|
|
96
|
+
id: "srp",
|
|
97
|
+
label: "Single Responsibility",
|
|
98
|
+
score: srScore,
|
|
99
|
+
weight: 15,
|
|
100
|
+
detail: `${fileLength} lines, ${exportCount} exports`,
|
|
101
|
+
});
|
|
102
|
+
if (fileLength > 400) {
|
|
103
|
+
issues.push({
|
|
104
|
+
id: "large-file",
|
|
105
|
+
label: "Large File",
|
|
106
|
+
severity: "low",
|
|
107
|
+
detail: `${fileLength} lines — consider splitting into focused modules`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// 6. Scalability patterns
|
|
111
|
+
const hasAsync = /\basync\b/.test(content);
|
|
112
|
+
const hasErrorHandling = /\btry\s*{/.test(content) || /\.catch\(/.test(content);
|
|
113
|
+
const hasStreaming = /\bStream\b|createReadStream|pipeline\(/.test(content);
|
|
114
|
+
const _hasPooling = /pool\.|Pool\(|createPool/.test(content);
|
|
115
|
+
let scalabilityScore = 50;
|
|
116
|
+
if (hasAsync)
|
|
117
|
+
scalabilityScore += 20;
|
|
118
|
+
if (hasErrorHandling)
|
|
119
|
+
scalabilityScore += 15;
|
|
120
|
+
if (hasStreaming)
|
|
121
|
+
scalabilityScore += 15;
|
|
122
|
+
metrics.push({
|
|
123
|
+
id: "scalability",
|
|
124
|
+
label: "Scalability Patterns",
|
|
125
|
+
score: Math.min(100, scalabilityScore),
|
|
126
|
+
weight: 15,
|
|
127
|
+
});
|
|
128
|
+
void filePath;
|
|
129
|
+
return { metrics, issues };
|
|
130
|
+
}
|
|
131
|
+
function computeOverallScore(metrics) {
|
|
132
|
+
const totalWeight = metrics.reduce((sum, m) => sum + m.weight, 0);
|
|
133
|
+
const weighted = metrics.reduce((sum, m) => sum + m.score * m.weight, 0);
|
|
134
|
+
return totalWeight > 0 ? Math.round(weighted / totalWeight) : 0;
|
|
135
|
+
}
|
|
136
|
+
function gradeFor(score) {
|
|
137
|
+
if (score >= 90)
|
|
138
|
+
return "A";
|
|
139
|
+
if (score >= 80)
|
|
140
|
+
return "B";
|
|
141
|
+
if (score >= 70)
|
|
142
|
+
return "C";
|
|
143
|
+
if (score >= 60)
|
|
144
|
+
return "D";
|
|
145
|
+
return "F";
|
|
146
|
+
}
|
|
147
|
+
// ─── Scanner ────────────────────────────────────────────────────────────────
|
|
148
|
+
const SKIP = new Set(["node_modules", ".git", "dist", "build", "coverage"]);
|
|
149
|
+
const EXTS = new Set([".ts", ".js", ".py", ".java", ".cs", ".go", ".rb", ".php", ".rs"]);
|
|
150
|
+
function collectFiles(dir) {
|
|
151
|
+
const result = [];
|
|
152
|
+
function walk(d) {
|
|
153
|
+
let entries;
|
|
154
|
+
try {
|
|
155
|
+
entries = readdirSync(d);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
for (const name of entries) {
|
|
161
|
+
if (SKIP.has(name) || name.startsWith("."))
|
|
162
|
+
continue;
|
|
163
|
+
const full = join(d, name);
|
|
164
|
+
try {
|
|
165
|
+
const sub = readdirSync(full);
|
|
166
|
+
void sub;
|
|
167
|
+
walk(full);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
if (EXTS.has(extname(name).toLowerCase()))
|
|
171
|
+
result.push(full);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
walk(dir);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
179
|
+
export function runArchAudit(argv) {
|
|
180
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
181
|
+
console.log(`
|
|
182
|
+
judges arch-audit — Evaluate architectural quality of code
|
|
183
|
+
|
|
184
|
+
Usage:
|
|
185
|
+
judges arch-audit <file-or-dir>
|
|
186
|
+
judges arch-audit src/ --min-grade C
|
|
187
|
+
|
|
188
|
+
Options:
|
|
189
|
+
--min-grade <A-F> Only show files at or below this grade
|
|
190
|
+
--format json JSON output
|
|
191
|
+
--help, -h Show this help
|
|
192
|
+
|
|
193
|
+
Metrics:
|
|
194
|
+
• Loose Coupling (import count)
|
|
195
|
+
• Separation of Concerns (DOM/DB/HTTP/FS mixing)
|
|
196
|
+
• Dependency Injection (hardcoded vs. injected)
|
|
197
|
+
• Testability (exports, global state, side effects)
|
|
198
|
+
• Single Responsibility (file size, export count)
|
|
199
|
+
• Scalability Patterns (async, error handling, streaming)
|
|
200
|
+
`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
204
|
+
const minGrade = argv.find((_a, i) => argv[i - 1] === "--min-grade");
|
|
205
|
+
const target = argv.find((a) => !a.startsWith("--") && !argv[argv.indexOf(a) - 1]?.startsWith("--")) || ".";
|
|
206
|
+
if (!existsSync(target)) {
|
|
207
|
+
console.error(` Path not found: ${target}`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
let files;
|
|
211
|
+
try {
|
|
212
|
+
readdirSync(target);
|
|
213
|
+
files = collectFiles(target);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
files = [target];
|
|
217
|
+
}
|
|
218
|
+
const results = [];
|
|
219
|
+
for (const f of files) {
|
|
220
|
+
let content;
|
|
221
|
+
try {
|
|
222
|
+
content = readFileSync(f, "utf-8");
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const { metrics, issues } = analyzeArchitecture(content, f);
|
|
228
|
+
const overall = computeOverallScore(metrics);
|
|
229
|
+
results.push({ file: relative(target, f) || f, overallScore: overall, grade: gradeFor(overall), metrics, issues });
|
|
230
|
+
}
|
|
231
|
+
let filtered = results;
|
|
232
|
+
if (minGrade) {
|
|
233
|
+
const gradeOrder = ["A", "B", "C", "D", "F"];
|
|
234
|
+
const minIdx = gradeOrder.indexOf(minGrade.toUpperCase());
|
|
235
|
+
if (minIdx >= 0)
|
|
236
|
+
filtered = results.filter((r) => gradeOrder.indexOf(r.grade) >= minIdx);
|
|
237
|
+
}
|
|
238
|
+
filtered.sort((a, b) => a.overallScore - b.overallScore);
|
|
239
|
+
if (format === "json") {
|
|
240
|
+
console.log(JSON.stringify({ files: filtered, scannedFiles: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
const avgScore = results.length > 0 ? Math.round(results.reduce((s, r) => s + r.overallScore, 0) / results.length) : 0;
|
|
244
|
+
console.log(`\n Architecture Audit — ${files.length} files`);
|
|
245
|
+
console.log(` Average: ${avgScore}/100 (${gradeFor(avgScore)})\n ──────────────────────────`);
|
|
246
|
+
if (filtered.length === 0) {
|
|
247
|
+
console.log(` ✅ All files meet architecture threshold\n`);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
for (const r of filtered.slice(0, 20)) {
|
|
251
|
+
const icon = r.grade === "A" || r.grade === "B" ? "🟢" : r.grade === "C" ? "🟡" : r.grade === "D" ? "🟠" : "🔴";
|
|
252
|
+
console.log(`\n ${icon} ${r.file} — ${r.overallScore}/100 (${r.grade})`);
|
|
253
|
+
for (const m of r.metrics) {
|
|
254
|
+
const mIcon = m.score >= 70 ? "✓" : m.score >= 40 ? "~" : "✗";
|
|
255
|
+
console.log(` ${mIcon} ${m.label.padEnd(24)} ${String(m.score).padEnd(4)} ${m.detail || ""}`);
|
|
256
|
+
}
|
|
257
|
+
if (r.issues.length > 0) {
|
|
258
|
+
console.log(` Issues:`);
|
|
259
|
+
for (const issue of r.issues) {
|
|
260
|
+
const sev = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟠" : "🟡";
|
|
261
|
+
console.log(` ${sev} ${issue.label}: ${issue.detail}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (filtered.length > 20)
|
|
266
|
+
console.log(` ... and ${filtered.length - 20} more files`);
|
|
267
|
+
// Grade distribution
|
|
268
|
+
const dist = { A: 0, B: 0, C: 0, D: 0, F: 0 };
|
|
269
|
+
for (const r of results)
|
|
270
|
+
dist[r.grade]++;
|
|
271
|
+
console.log(`\n Distribution: A:${dist.A} B:${dist.B} C:${dist.C} D:${dist.D} F:${dist.F}`);
|
|
272
|
+
// Top issues
|
|
273
|
+
const allIssues = results.flatMap((r) => r.issues.map((iss) => ({ file: r.file, ...iss })));
|
|
274
|
+
const highIssues = allIssues.filter((i) => i.severity === "high");
|
|
275
|
+
if (highIssues.length > 0) {
|
|
276
|
+
console.log(`\n ⚠ ${highIssues.length} high-severity architecture issue(s):`);
|
|
277
|
+
for (const iss of highIssues.slice(0, 10)) {
|
|
278
|
+
console.log(` ${iss.file}: ${iss.detail}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
console.log("");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=arch-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arch-audit.js","sourceRoot":"","sources":["../../src/commands/arch-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clarity score — measure code readability and self-documentation
|
|
3
|
+
* specifically for AI-generated code. Flags "correct but cryptic"
|
|
4
|
+
* patterns that need documentation investment.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runClarityScore(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=clarity-score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarity-score.d.ts","sourceRoot":"","sources":["../../src/commands/clarity-score.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoLH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqGpD"}
|