@kevinrabun/judges 3.56.0 → 3.58.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/assertion-density.d.ts +5 -0
- package/dist/commands/assertion-density.d.ts.map +1 -0
- package/dist/commands/assertion-density.js +264 -0
- package/dist/commands/assertion-density.js.map +1 -0
- package/dist/commands/async-safety.d.ts +5 -0
- package/dist/commands/async-safety.d.ts.map +1 -0
- package/dist/commands/async-safety.js +267 -0
- package/dist/commands/async-safety.js.map +1 -0
- package/dist/commands/cache-audit.d.ts +5 -0
- package/dist/commands/cache-audit.d.ts.map +1 -0
- package/dist/commands/cache-audit.js +220 -0
- package/dist/commands/cache-audit.js.map +1 -0
- package/dist/commands/clone-detect.d.ts +5 -0
- package/dist/commands/clone-detect.d.ts.map +1 -0
- package/dist/commands/clone-detect.js +233 -0
- package/dist/commands/clone-detect.js.map +1 -0
- package/dist/commands/comment-drift.d.ts +5 -0
- package/dist/commands/comment-drift.d.ts.map +1 -0
- package/dist/commands/comment-drift.js +229 -0
- package/dist/commands/comment-drift.js.map +1 -0
- package/dist/commands/contract-verify.d.ts +5 -0
- package/dist/commands/contract-verify.d.ts.map +1 -0
- package/dist/commands/contract-verify.js +317 -0
- package/dist/commands/contract-verify.js.map +1 -0
- package/dist/commands/dead-code-detect.d.ts +5 -0
- package/dist/commands/dead-code-detect.d.ts.map +1 -0
- package/dist/commands/dead-code-detect.js +256 -0
- package/dist/commands/dead-code-detect.js.map +1 -0
- package/dist/commands/encoding-safety.d.ts +5 -0
- package/dist/commands/encoding-safety.d.ts.map +1 -0
- package/dist/commands/encoding-safety.js +276 -0
- package/dist/commands/encoding-safety.js.map +1 -0
- package/dist/commands/error-ux.d.ts +5 -0
- package/dist/commands/error-ux.d.ts.map +1 -0
- package/dist/commands/error-ux.js +253 -0
- package/dist/commands/error-ux.js.map +1 -0
- package/dist/commands/event-leak.d.ts +5 -0
- package/dist/commands/event-leak.d.ts.map +1 -0
- package/dist/commands/event-leak.js +263 -0
- package/dist/commands/event-leak.js.map +1 -0
- package/dist/commands/idempotency-audit.d.ts +5 -0
- package/dist/commands/idempotency-audit.d.ts.map +1 -0
- package/dist/commands/idempotency-audit.js +223 -0
- package/dist/commands/idempotency-audit.js.map +1 -0
- package/dist/commands/input-guard.d.ts +5 -0
- package/dist/commands/input-guard.d.ts.map +1 -0
- package/dist/commands/input-guard.js +256 -0
- package/dist/commands/input-guard.js.map +1 -0
- package/dist/commands/privilege-path.d.ts +5 -0
- package/dist/commands/privilege-path.d.ts.map +1 -0
- package/dist/commands/privilege-path.js +234 -0
- package/dist/commands/privilege-path.js.map +1 -0
- package/dist/commands/state-integrity.d.ts +5 -0
- package/dist/commands/state-integrity.d.ts.map +1 -0
- package/dist/commands/state-integrity.js +284 -0
- package/dist/commands/state-integrity.js.map +1 -0
- package/dist/commands/timeout-audit.d.ts +5 -0
- package/dist/commands/timeout-audit.d.ts.map +1 -0
- package/dist/commands/timeout-audit.js +211 -0
- package/dist/commands/timeout-audit.js.map +1 -0
- package/dist/commands/type-boundary.d.ts +5 -0
- package/dist/commands/type-boundary.d.ts.map +1 -0
- package/dist/commands/type-boundary.js +236 -0
- package/dist/commands/type-boundary.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache audit — audit cache invalidation correctness, TTL consistency, and stampede risk.
|
|
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
|
+
const fullText = content;
|
|
52
|
+
// Detect cache set without TTL
|
|
53
|
+
for (let i = 0; i < lines.length; i++) {
|
|
54
|
+
const line = lines[i];
|
|
55
|
+
// Redis/Memcached set without expiry
|
|
56
|
+
if (/\.set\s*\(/.test(line) && /cache|redis|memcache/i.test(fullText)) {
|
|
57
|
+
const block = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
|
|
58
|
+
if (!/ttl|expire|ex\b|px\b|maxAge|max_age|EX|PX/i.test(block) && /cache/i.test(line)) {
|
|
59
|
+
issues.push({
|
|
60
|
+
file: filepath,
|
|
61
|
+
line: i + 1,
|
|
62
|
+
issue: "Cache set without TTL",
|
|
63
|
+
severity: "high",
|
|
64
|
+
detail: "Cache entry has no expiration — data will grow unbounded and may serve stale results",
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Map/Object used as cache without size limit
|
|
69
|
+
if (/new Map\(\)|:\s*Record<|:\s*\{[^}]*\}\s*=\s*\{\}/.test(line) && /cache/i.test(line)) {
|
|
70
|
+
const fileBlock = lines.slice(i, Math.min(i + 20, lines.length)).join("\n");
|
|
71
|
+
if (!/\.delete|\.clear|maxSize|max_size|evict|LRU|lru/i.test(fileBlock)) {
|
|
72
|
+
issues.push({
|
|
73
|
+
file: filepath,
|
|
74
|
+
line: i + 1,
|
|
75
|
+
issue: "In-memory cache without eviction",
|
|
76
|
+
severity: "medium",
|
|
77
|
+
detail: "Cache grows unbounded — add size limit or LRU eviction to prevent memory leaks",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Cache read without miss handler (dogpile/stampede risk)
|
|
82
|
+
if (/\.get\s*\(/.test(line) && /cache/i.test(line)) {
|
|
83
|
+
const block = lines.slice(i, Math.min(i + 10, lines.length)).join("\n");
|
|
84
|
+
if (/if\s*\(!?\s*\w+\)|=== null|=== undefined|!result/.test(block)) {
|
|
85
|
+
if (!/lock|mutex|singleflight|coalesce|dedupe/i.test(block)) {
|
|
86
|
+
issues.push({
|
|
87
|
+
file: filepath,
|
|
88
|
+
line: i + 1,
|
|
89
|
+
issue: "Cache miss without stampede protection",
|
|
90
|
+
severity: "medium",
|
|
91
|
+
detail: "Concurrent cache misses can trigger thundering herd — add lock or singleflight",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Mutation without cache invalidation
|
|
97
|
+
if (/\.(?:update|insert|delete|remove|save|create|destroy|put|patch)\s*\(/.test(line)) {
|
|
98
|
+
if (/(?:db|model|repository|store|dao|prisma|sequelize|knex)/i.test(line)) {
|
|
99
|
+
const afterBlock = lines.slice(i, Math.min(i + 8, lines.length)).join("\n");
|
|
100
|
+
if (/cache/i.test(fullText) &&
|
|
101
|
+
!/cache\.(?:del|delete|invalidate|clear|remove|bust|evict|set)/i.test(afterBlock)) {
|
|
102
|
+
issues.push({
|
|
103
|
+
file: filepath,
|
|
104
|
+
line: i + 1,
|
|
105
|
+
issue: "Data mutation without cache invalidation",
|
|
106
|
+
severity: "high",
|
|
107
|
+
detail: "Write operation not followed by cache invalidation — clients may read stale data",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// TTL inconsistency (different TTL for same logical data)
|
|
113
|
+
if (/ttl|expire|maxAge|max_age/i.test(line)) {
|
|
114
|
+
const ttlMatch = line.match(/(?:ttl|expire|maxAge|max_age)\s*[:=]\s*(\d+)/i);
|
|
115
|
+
if (ttlMatch) {
|
|
116
|
+
const val = parseInt(ttlMatch[1], 10);
|
|
117
|
+
if (val < 5) {
|
|
118
|
+
issues.push({
|
|
119
|
+
file: filepath,
|
|
120
|
+
line: i + 1,
|
|
121
|
+
issue: "Suspiciously short TTL",
|
|
122
|
+
severity: "low",
|
|
123
|
+
detail: `TTL = ${val} — extremely short TTL negates caching benefit and adds overhead`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (val > 86400000) {
|
|
127
|
+
issues.push({
|
|
128
|
+
file: filepath,
|
|
129
|
+
line: i + 1,
|
|
130
|
+
issue: "Excessively long TTL",
|
|
131
|
+
severity: "medium",
|
|
132
|
+
detail: `TTL = ${Math.round(val / 3600000)}h — very long TTL increases stale-data risk`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Cache key construction without version/namespace
|
|
138
|
+
if (/cacheKey|cache_key/i.test(line)) {
|
|
139
|
+
if (!/version|v\d+|namespace|prefix/i.test(line)) {
|
|
140
|
+
issues.push({
|
|
141
|
+
file: filepath,
|
|
142
|
+
line: i + 1,
|
|
143
|
+
issue: "Cache key without versioning",
|
|
144
|
+
severity: "low",
|
|
145
|
+
detail: "Cache key has no version prefix — schema changes may cause deserialization failures",
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// localStorage/sessionStorage without error handling
|
|
150
|
+
if (/localStorage|sessionStorage/.test(line)) {
|
|
151
|
+
const block = lines.slice(Math.max(0, i - 2), Math.min(i + 2, lines.length)).join("\n");
|
|
152
|
+
if (!/try|catch/.test(block)) {
|
|
153
|
+
issues.push({
|
|
154
|
+
file: filepath,
|
|
155
|
+
line: i + 1,
|
|
156
|
+
issue: "Web storage access without error handling",
|
|
157
|
+
severity: "medium",
|
|
158
|
+
detail: "localStorage/sessionStorage can throw in private browsing or when storage quota is exceeded",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return issues;
|
|
164
|
+
}
|
|
165
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
166
|
+
export function runCacheAudit(argv) {
|
|
167
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
168
|
+
console.log(`
|
|
169
|
+
judges cache-audit — Audit cache invalidation, TTL, and stampede risk
|
|
170
|
+
|
|
171
|
+
Usage:
|
|
172
|
+
judges cache-audit [dir]
|
|
173
|
+
judges cache-audit src/ --format json
|
|
174
|
+
|
|
175
|
+
Options:
|
|
176
|
+
[dir] Directory to scan (default: .)
|
|
177
|
+
--format json JSON output
|
|
178
|
+
--help, -h Show this help
|
|
179
|
+
|
|
180
|
+
Checks: missing TTL, unbounded in-memory cache, stampede risk, stale-after-write,
|
|
181
|
+
suspicious TTL values, unversioned cache keys, web storage error handling.
|
|
182
|
+
`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
186
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
187
|
+
const files = collectFiles(dir);
|
|
188
|
+
const allIssues = [];
|
|
189
|
+
for (const f of files)
|
|
190
|
+
allIssues.push(...analyzeFile(f));
|
|
191
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
192
|
+
const medCount = allIssues.filter((i) => i.severity === "medium").length;
|
|
193
|
+
const score = Math.max(0, 100 - highCount * 10 - medCount * 4);
|
|
194
|
+
if (format === "json") {
|
|
195
|
+
console.log(JSON.stringify({
|
|
196
|
+
issues: allIssues,
|
|
197
|
+
score,
|
|
198
|
+
summary: { high: highCount, medium: medCount, total: allIssues.length },
|
|
199
|
+
timestamp: new Date().toISOString(),
|
|
200
|
+
}, null, 2));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const badge = score >= 80 ? "✅ SOUND" : score >= 50 ? "⚠️ RISKY" : "❌ BROKEN";
|
|
204
|
+
console.log(`\n Cache Health: ${badge} (${score}/100)\n ─────────────────────────────`);
|
|
205
|
+
if (allIssues.length === 0) {
|
|
206
|
+
console.log(" No cache issues detected.\n");
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
210
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
|
|
211
|
+
console.log(` ${icon} ${issue.issue}`);
|
|
212
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
213
|
+
console.log(` ${issue.detail}`);
|
|
214
|
+
}
|
|
215
|
+
if (allIssues.length > 25)
|
|
216
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
217
|
+
console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=cache-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-audit.js","sourceRoot":"","sources":["../../src/commands/cache-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-detect.d.ts","sourceRoot":"","sources":["../../src/commands/clone-detect.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6MH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6DnD"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clone detect — find duplicated logic blocks that should be extracted into shared functions.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
5
|
+
import { join, extname } from "path";
|
|
6
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
7
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".java", ".go"]);
|
|
8
|
+
function collectFiles(dir, max = 300) {
|
|
9
|
+
const files = [];
|
|
10
|
+
function walk(d) {
|
|
11
|
+
if (files.length >= max)
|
|
12
|
+
return;
|
|
13
|
+
let entries;
|
|
14
|
+
try {
|
|
15
|
+
entries = readdirSync(d);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const e of entries) {
|
|
21
|
+
if (files.length >= max)
|
|
22
|
+
return;
|
|
23
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
24
|
+
continue;
|
|
25
|
+
const full = join(d, e);
|
|
26
|
+
try {
|
|
27
|
+
if (statSync(full).isDirectory())
|
|
28
|
+
walk(full);
|
|
29
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
30
|
+
files.push(full);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* skip */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
walk(dir);
|
|
38
|
+
return files;
|
|
39
|
+
}
|
|
40
|
+
// ─── Normalization ──────────────────────────────────────────────────────────
|
|
41
|
+
function normalize(line) {
|
|
42
|
+
return line
|
|
43
|
+
.trim()
|
|
44
|
+
.replace(/\/\/.*/, "") // strip comments
|
|
45
|
+
.replace(/\/\*.*?\*\//g, "") // strip inline comments
|
|
46
|
+
.replace(/['"][^'"]*['"]/g, "S") // normalize strings
|
|
47
|
+
.replace(/\b\d+\b/g, "N") // normalize numbers
|
|
48
|
+
.replace(/\b[a-z]\w{0,2}\b/gi, "V") // normalize short variable names
|
|
49
|
+
.replace(/\s+/g, " ") // collapse whitespace
|
|
50
|
+
.trim();
|
|
51
|
+
}
|
|
52
|
+
function extractBlocks(filepath, content, blockSize) {
|
|
53
|
+
const lines = content.split("\n");
|
|
54
|
+
const blocks = [];
|
|
55
|
+
for (let i = 0; i <= lines.length - blockSize; i++) {
|
|
56
|
+
const raw = lines.slice(i, i + blockSize);
|
|
57
|
+
const normalized = raw
|
|
58
|
+
.map(normalize)
|
|
59
|
+
.filter((l) => l.length > 3)
|
|
60
|
+
.join("|");
|
|
61
|
+
if (normalized.length > 20) {
|
|
62
|
+
blocks.push({ file: filepath, startLine: i + 1, normalized, raw: raw.join("\n") });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return blocks;
|
|
66
|
+
}
|
|
67
|
+
function detectClones(files, blockSize = 5, minSimilarity = 0.85) {
|
|
68
|
+
const issues = [];
|
|
69
|
+
const allBlocks = [];
|
|
70
|
+
for (const f of files) {
|
|
71
|
+
let content;
|
|
72
|
+
try {
|
|
73
|
+
content = readFileSync(f, "utf-8");
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
allBlocks.push(...extractBlocks(f, content, blockSize));
|
|
79
|
+
}
|
|
80
|
+
// Group by normalized form
|
|
81
|
+
const groups = new Map();
|
|
82
|
+
for (const block of allBlocks) {
|
|
83
|
+
const existing = groups.get(block.normalized);
|
|
84
|
+
if (existing) {
|
|
85
|
+
existing.push(block);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
groups.set(block.normalized, [block]);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const reported = new Set();
|
|
92
|
+
for (const [_norm, blocks] of groups) {
|
|
93
|
+
if (blocks.length < 2)
|
|
94
|
+
continue;
|
|
95
|
+
// Deduplicate overlapping blocks in same file
|
|
96
|
+
const unique = [];
|
|
97
|
+
for (const b of blocks) {
|
|
98
|
+
const isDuplicate = unique.some((u) => u.file === b.file && Math.abs(u.startLine - b.startLine) < blockSize);
|
|
99
|
+
if (!isDuplicate)
|
|
100
|
+
unique.push(b);
|
|
101
|
+
}
|
|
102
|
+
if (unique.length < 2)
|
|
103
|
+
continue;
|
|
104
|
+
// Report clones
|
|
105
|
+
for (let j = 1; j < unique.length && j < 3; j++) {
|
|
106
|
+
const key = `${unique[0].file}:${unique[0].startLine}-${unique[j].file}:${unique[j].startLine}`;
|
|
107
|
+
if (reported.has(key))
|
|
108
|
+
continue;
|
|
109
|
+
reported.add(key);
|
|
110
|
+
const sameFile = unique[0].file === unique[j].file;
|
|
111
|
+
const severity = unique.length > 3 ? "high" : unique.length > 2 ? "medium" : "low";
|
|
112
|
+
issues.push({
|
|
113
|
+
file: unique[0].file,
|
|
114
|
+
line: unique[0].startLine,
|
|
115
|
+
issue: sameFile ? "Intra-file code clone" : "Cross-file code clone",
|
|
116
|
+
severity,
|
|
117
|
+
detail: `${blockSize}-line block duplicated${sameFile ? ` at line ${unique[j].startLine}` : ` in ${unique[j].file}:${unique[j].startLine}`} — extract to shared function (${unique.length} copies total)`,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Also check for near-identical functions using a simpler heuristic
|
|
122
|
+
for (const f of files) {
|
|
123
|
+
let content;
|
|
124
|
+
try {
|
|
125
|
+
content = readFileSync(f, "utf-8");
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const lines = content.split("\n");
|
|
131
|
+
const functions = [];
|
|
132
|
+
for (let i = 0; i < lines.length; i++) {
|
|
133
|
+
const funcMatch = lines[i].match(/(?:function\s+(\w+)|(?:const|let)\s+(\w+)\s*=\s*(?:async\s*)?\()/);
|
|
134
|
+
if (funcMatch) {
|
|
135
|
+
const name = funcMatch[1] || funcMatch[2];
|
|
136
|
+
let depth = 0;
|
|
137
|
+
let end = i;
|
|
138
|
+
for (let j = i; j < Math.min(i + 50, lines.length); j++) {
|
|
139
|
+
for (const ch of lines[j]) {
|
|
140
|
+
if (ch === "{")
|
|
141
|
+
depth++;
|
|
142
|
+
if (ch === "}")
|
|
143
|
+
depth--;
|
|
144
|
+
}
|
|
145
|
+
if (depth <= 0 && j > i) {
|
|
146
|
+
end = j;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const body = lines
|
|
151
|
+
.slice(i, end + 1)
|
|
152
|
+
.map(normalize)
|
|
153
|
+
.join("|");
|
|
154
|
+
if (body.length > 30)
|
|
155
|
+
functions.push({ name, line: i + 1, body });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Compare functions within same file
|
|
159
|
+
for (let a = 0; a < functions.length; a++) {
|
|
160
|
+
for (let b = a + 1; b < functions.length; b++) {
|
|
161
|
+
if (functions[a].body === functions[b].body && functions[a].body.length > 50) {
|
|
162
|
+
const key = `func:${f}:${functions[a].line}-${functions[b].line}`;
|
|
163
|
+
if (!reported.has(key)) {
|
|
164
|
+
reported.add(key);
|
|
165
|
+
issues.push({
|
|
166
|
+
file: f,
|
|
167
|
+
line: functions[a].line,
|
|
168
|
+
issue: "Duplicate functions",
|
|
169
|
+
severity: "medium",
|
|
170
|
+
detail: `\`${functions[a].name}\` and \`${functions[b].name}\` (line ${functions[b].line}) have identical logic — extract shared implementation`,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Limit results
|
|
178
|
+
void minSimilarity;
|
|
179
|
+
return issues.slice(0, 50);
|
|
180
|
+
}
|
|
181
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
182
|
+
export function runCloneDetect(argv) {
|
|
183
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
184
|
+
console.log(`
|
|
185
|
+
judges clone-detect — Find duplicated logic blocks that should be shared functions
|
|
186
|
+
|
|
187
|
+
Usage:
|
|
188
|
+
judges clone-detect [dir]
|
|
189
|
+
judges clone-detect src/ --format json
|
|
190
|
+
|
|
191
|
+
Options:
|
|
192
|
+
[dir] Directory to scan (default: .)
|
|
193
|
+
--format json JSON output
|
|
194
|
+
--help, -h Show this help
|
|
195
|
+
|
|
196
|
+
Checks: intra-file code clones, cross-file clones, duplicate functions with renamed variables.
|
|
197
|
+
`);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
201
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
202
|
+
const files = collectFiles(dir);
|
|
203
|
+
const allIssues = detectClones(files);
|
|
204
|
+
const highCount = allIssues.filter((i) => i.severity === "high").length;
|
|
205
|
+
const medCount = allIssues.filter((i) => i.severity === "medium").length;
|
|
206
|
+
const score = Math.max(0, 100 - highCount * 8 - medCount * 3);
|
|
207
|
+
if (format === "json") {
|
|
208
|
+
console.log(JSON.stringify({
|
|
209
|
+
issues: allIssues,
|
|
210
|
+
score,
|
|
211
|
+
summary: { high: highCount, medium: medCount, total: allIssues.length },
|
|
212
|
+
timestamp: new Date().toISOString(),
|
|
213
|
+
}, null, 2));
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const badge = score >= 80 ? "✅ DRY" : score >= 50 ? "⚠️ REPETITIVE" : "❌ DUPLICATED";
|
|
217
|
+
console.log(`\n Code Clones: ${badge} (${score}/100)\n ─────────────────────────────`);
|
|
218
|
+
if (allIssues.length === 0) {
|
|
219
|
+
console.log(" No code clones detected.\n");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
for (const issue of allIssues.slice(0, 25)) {
|
|
223
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "🔵";
|
|
224
|
+
console.log(` ${icon} ${issue.issue}`);
|
|
225
|
+
console.log(` ${issue.file}:${issue.line}`);
|
|
226
|
+
console.log(` ${issue.detail}`);
|
|
227
|
+
}
|
|
228
|
+
if (allIssues.length > 25)
|
|
229
|
+
console.log(` ... and ${allIssues.length - 25} more`);
|
|
230
|
+
console.log(`\n Total: ${allIssues.length} | High: ${highCount} | Medium: ${medCount} | Score: ${score}/100\n`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=clone-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-detect.js","sourceRoot":"","sources":["../../src/commands/clone-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-drift.d.ts","sourceRoot":"","sources":["../../src/commands/comment-drift.ts"],"names":[],"mappings":"AAAA;;GAEG;AA+LH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+DpD"}
|