@kevinrabun/judges 3.52.0 → 3.53.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/code-similarity.d.ts +9 -0
- package/dist/commands/code-similarity.d.ts.map +1 -0
- package/dist/commands/code-similarity.js +232 -0
- package/dist/commands/code-similarity.js.map +1 -0
- package/dist/commands/compliance-weight.d.ts +9 -0
- package/dist/commands/compliance-weight.d.ts.map +1 -0
- package/dist/commands/compliance-weight.js +273 -0
- package/dist/commands/compliance-weight.js.map +1 -0
- package/dist/commands/cross-pr-regression.d.ts +9 -0
- package/dist/commands/cross-pr-regression.d.ts.map +1 -0
- package/dist/commands/cross-pr-regression.js +298 -0
- package/dist/commands/cross-pr-regression.js.map +1 -0
- package/dist/commands/doc-drift.d.ts +9 -0
- package/dist/commands/doc-drift.d.ts.map +1 -0
- package/dist/commands/doc-drift.js +259 -0
- package/dist/commands/doc-drift.js.map +1 -0
- package/dist/commands/exception-consistency.d.ts +7 -0
- package/dist/commands/exception-consistency.d.ts.map +1 -0
- package/dist/commands/exception-consistency.js +193 -0
- package/dist/commands/exception-consistency.js.map +1 -0
- package/dist/commands/refactor-safety.d.ts +9 -0
- package/dist/commands/refactor-safety.d.ts.map +1 -0
- package/dist/commands/refactor-safety.js +274 -0
- package/dist/commands/refactor-safety.js.map +1 -0
- package/dist/commands/resource-cleanup.d.ts +7 -0
- package/dist/commands/resource-cleanup.d.ts.map +1 -0
- package/dist/commands/resource-cleanup.js +236 -0
- package/dist/commands/resource-cleanup.js.map +1 -0
- package/dist/commands/team-trust.d.ts +8 -0
- package/dist/commands/team-trust.d.ts.map +1 -0
- package/dist/commands/team-trust.js +175 -0
- package/dist/commands/team-trust.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exception consistency — detect inconsistent exception handling
|
|
3
|
+
* patterns within a codebase: thrown-but-uncaught, asymmetric
|
|
4
|
+
* try/catch/finally, unhandled promise rejections, mixed strategies.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
7
|
+
import { join, extname } from "path";
|
|
8
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
9
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".java", ".cs", ".go", ".rs"]);
|
|
10
|
+
function collectFiles(dir, max = 500) {
|
|
11
|
+
const files = [];
|
|
12
|
+
function walk(d) {
|
|
13
|
+
if (files.length >= max)
|
|
14
|
+
return;
|
|
15
|
+
let entries;
|
|
16
|
+
try {
|
|
17
|
+
entries = readdirSync(d);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const e of entries) {
|
|
23
|
+
if (files.length >= max)
|
|
24
|
+
return;
|
|
25
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
26
|
+
continue;
|
|
27
|
+
const full = join(d, e);
|
|
28
|
+
try {
|
|
29
|
+
if (statSync(full).isDirectory())
|
|
30
|
+
walk(full);
|
|
31
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
32
|
+
files.push(full);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* skip */
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
walk(dir);
|
|
40
|
+
return files;
|
|
41
|
+
}
|
|
42
|
+
// ─── Patterns ───────────────────────────────────────────────────────────────
|
|
43
|
+
const PATTERNS = [
|
|
44
|
+
{
|
|
45
|
+
name: "empty-catch",
|
|
46
|
+
regex: /catch\s*\([^)]*\)\s*\{\s*\}/,
|
|
47
|
+
severity: "high",
|
|
48
|
+
message: "Empty catch block silently swallows exception",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "catch-ignore-error",
|
|
52
|
+
regex: /catch\s*\(\s*_?\s*\)\s*\{/,
|
|
53
|
+
severity: "medium",
|
|
54
|
+
message: "Catch block ignores error variable",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "throw-string",
|
|
58
|
+
regex: /throw\s+['"`]/,
|
|
59
|
+
severity: "medium",
|
|
60
|
+
message: "Throwing a string literal instead of an Error object",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: "catch-console-only",
|
|
64
|
+
regex: /catch\s*\([^)]*\)\s*\{\s*console\.(log|error|warn)\([^)]*\);\s*\}/,
|
|
65
|
+
severity: "medium",
|
|
66
|
+
message: "Catch block only logs — error is not re-thrown or handled",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "unhandled-promise",
|
|
70
|
+
regex: /\.then\([^)]*\)\s*(?!\.catch)/,
|
|
71
|
+
severity: "medium",
|
|
72
|
+
message: "Promise chain without .catch() — potential unhandled rejection",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "async-no-try",
|
|
76
|
+
regex: /async\s+function\s+\w+[^{]*\{(?:(?!try\s*\{)[\s\S])*await\s/,
|
|
77
|
+
severity: "low",
|
|
78
|
+
message: "Async function uses await without try/catch",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "catch-rethrow-same",
|
|
82
|
+
regex: /catch\s*\(\s*(\w+)\s*\)\s*\{\s*throw\s+\1\s*;?\s*\}/,
|
|
83
|
+
severity: "low",
|
|
84
|
+
message: "Catch block only re-throws the same error — unnecessary try/catch",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "generic-catch",
|
|
88
|
+
regex: /catch\s*\(\s*(\w+)\s*:\s*any\s*\)/,
|
|
89
|
+
severity: "low",
|
|
90
|
+
message: "Catching 'any' type — use typed error handling",
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
94
|
+
function analyzeFile(filePath) {
|
|
95
|
+
let content;
|
|
96
|
+
try {
|
|
97
|
+
content = readFileSync(filePath, "utf-8");
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const lines = content.split("\n");
|
|
103
|
+
const issues = [];
|
|
104
|
+
for (let i = 0; i < lines.length; i++) {
|
|
105
|
+
const line = lines[i];
|
|
106
|
+
// Check multi-line context (current + next 2 lines)
|
|
107
|
+
const context = lines.slice(i, Math.min(i + 3, lines.length)).join("\n");
|
|
108
|
+
for (const pat of PATTERNS) {
|
|
109
|
+
if ((pat.regex.test(context) && pat.regex.test(line)) ||
|
|
110
|
+
((i === 0 || !pat.regex.test(lines.slice(i - 1, i + 2).join("\n"))) && pat.regex.test(context))) {
|
|
111
|
+
// Deduplicate: only flag once per match block
|
|
112
|
+
if (!issues.some((x) => x.file === filePath && Math.abs(x.line - (i + 1)) < 3 && x.kind === pat.name)) {
|
|
113
|
+
issues.push({ file: filePath, line: i + 1, kind: pat.name, message: pat.message, severity: pat.severity });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Detect mixed strategies: both callbacks and promises in same file
|
|
119
|
+
const hasCallbacks = /\bcallback\s*\(|function\s*\(\s*err\b/.test(content);
|
|
120
|
+
const hasPromises = /\.then\s*\(|new\s+Promise\s*\(|async\s/.test(content);
|
|
121
|
+
if (hasCallbacks && hasPromises) {
|
|
122
|
+
issues.push({
|
|
123
|
+
file: filePath,
|
|
124
|
+
line: 1,
|
|
125
|
+
kind: "mixed-strategy",
|
|
126
|
+
message: "File mixes callback-style (err) and promise/async patterns — consider unifying",
|
|
127
|
+
severity: "low",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return issues;
|
|
131
|
+
}
|
|
132
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
133
|
+
export function runExceptionConsistency(argv) {
|
|
134
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
135
|
+
console.log(`
|
|
136
|
+
judges exception-consistency — Detect inconsistent exception handling
|
|
137
|
+
|
|
138
|
+
Usage:
|
|
139
|
+
judges exception-consistency [dir]
|
|
140
|
+
judges exception-consistency src/ --severity high
|
|
141
|
+
judges exception-consistency --format json
|
|
142
|
+
|
|
143
|
+
Options:
|
|
144
|
+
[dir] Directory to scan (default: .)
|
|
145
|
+
--severity <level> Filter by minimum severity (high|medium|low)
|
|
146
|
+
--format json JSON output
|
|
147
|
+
--help, -h Show this help
|
|
148
|
+
`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
152
|
+
const severityFilter = argv.find((_a, i) => argv[i - 1] === "--severity") || "low";
|
|
153
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
154
|
+
const severityOrder = { high: 3, medium: 2, low: 1 };
|
|
155
|
+
const minSev = severityOrder[severityFilter] || 1;
|
|
156
|
+
const files = collectFiles(dir);
|
|
157
|
+
const allIssues = [];
|
|
158
|
+
for (const f of files) {
|
|
159
|
+
const issues = analyzeFile(f);
|
|
160
|
+
allIssues.push(...issues.filter((x) => severityOrder[x.severity] >= minSev));
|
|
161
|
+
}
|
|
162
|
+
allIssues.sort((a, b) => severityOrder[b.severity] - severityOrder[a.severity]);
|
|
163
|
+
if (format === "json") {
|
|
164
|
+
console.log(JSON.stringify({ issues: allIssues, filesScanned: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
console.log(`\n Exception Consistency — ${files.length} files scanned, ${allIssues.length} issue(s)\n ──────────────────────────`);
|
|
168
|
+
if (allIssues.length === 0) {
|
|
169
|
+
console.log(" ✅ No inconsistent exception handling detected");
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const byKind = new Map();
|
|
173
|
+
for (const issue of allIssues) {
|
|
174
|
+
byKind.set(issue.kind, (byKind.get(issue.kind) || 0) + 1);
|
|
175
|
+
}
|
|
176
|
+
console.log("\n Summary:");
|
|
177
|
+
for (const [kind, count] of byKind) {
|
|
178
|
+
console.log(` ${kind}: ${count}`);
|
|
179
|
+
}
|
|
180
|
+
console.log("\n Details:");
|
|
181
|
+
for (const issue of allIssues.slice(0, 50)) {
|
|
182
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "⚪";
|
|
183
|
+
console.log(` ${icon} [${issue.severity}] ${issue.file}:${issue.line}`);
|
|
184
|
+
console.log(` ${issue.message}`);
|
|
185
|
+
}
|
|
186
|
+
if (allIssues.length > 50) {
|
|
187
|
+
console.log(`\n ... and ${allIssues.length - 50} more issue(s)`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
console.log("");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=exception-consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exception-consistency.js","sourceRoot":"","sources":["../../src/commands/exception-consistency.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refactor safety — analyze proposed refactorings for breaking changes,
|
|
3
|
+
* incomplete migrations, orphaned references, and behavioral changes.
|
|
4
|
+
*
|
|
5
|
+
* Compares two directory snapshots or a list of changed files against
|
|
6
|
+
* the broader codebase to detect incomplete refactors.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runRefactorSafety(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=refactor-safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refactor-safety.d.ts","sourceRoot":"","sources":["../../src/commands/refactor-safety.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4NH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4EtD"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refactor safety — analyze proposed refactorings for breaking changes,
|
|
3
|
+
* incomplete migrations, orphaned references, and behavioral changes.
|
|
4
|
+
*
|
|
5
|
+
* Compares two directory snapshots or a list of changed files against
|
|
6
|
+
* the broader codebase to detect incomplete refactors.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, readdirSync, statSync, existsSync } from "fs";
|
|
9
|
+
import { join, extname, relative } from "path";
|
|
10
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
11
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".java", ".cs", ".go", ".rs"]);
|
|
12
|
+
function collectFiles(dir, max = 500) {
|
|
13
|
+
const files = [];
|
|
14
|
+
function walk(d) {
|
|
15
|
+
if (files.length >= max)
|
|
16
|
+
return;
|
|
17
|
+
let entries;
|
|
18
|
+
try {
|
|
19
|
+
entries = readdirSync(d);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
for (const e of entries) {
|
|
25
|
+
if (files.length >= max)
|
|
26
|
+
return;
|
|
27
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
28
|
+
continue;
|
|
29
|
+
const full = join(d, e);
|
|
30
|
+
try {
|
|
31
|
+
if (statSync(full).isDirectory())
|
|
32
|
+
walk(full);
|
|
33
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
34
|
+
files.push(full);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
/* skip */
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
walk(dir);
|
|
42
|
+
return files;
|
|
43
|
+
}
|
|
44
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
45
|
+
function extractExports(content) {
|
|
46
|
+
const exports = [];
|
|
47
|
+
const exportRegex = /\bexport\s+(?:function|class|const|let|type|interface|enum)\s+(\w+)/g;
|
|
48
|
+
let m;
|
|
49
|
+
while ((m = exportRegex.exec(content)) !== null)
|
|
50
|
+
exports.push(m[1]);
|
|
51
|
+
const defaultExport = /\bexport\s+default\s+(?:function|class)?\s*(\w+)?/g;
|
|
52
|
+
while ((m = defaultExport.exec(content)) !== null) {
|
|
53
|
+
if (m[1])
|
|
54
|
+
exports.push(m[1]);
|
|
55
|
+
}
|
|
56
|
+
return exports;
|
|
57
|
+
}
|
|
58
|
+
function extractImports(content) {
|
|
59
|
+
const imports = [];
|
|
60
|
+
const importRegex = /import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
|
|
61
|
+
let m;
|
|
62
|
+
while ((m = importRegex.exec(content)) !== null) {
|
|
63
|
+
const names = m[1]
|
|
64
|
+
.split(",")
|
|
65
|
+
.map((n) => n
|
|
66
|
+
.trim()
|
|
67
|
+
.split(/\s+as\s+/)[0]
|
|
68
|
+
.trim())
|
|
69
|
+
.filter(Boolean);
|
|
70
|
+
imports.push({ names, source: m[2] });
|
|
71
|
+
}
|
|
72
|
+
return imports;
|
|
73
|
+
}
|
|
74
|
+
function analyzeRefactorSafety(files, dir) {
|
|
75
|
+
const issues = [];
|
|
76
|
+
// Build export map: symbol → file
|
|
77
|
+
const exportMap = new Map();
|
|
78
|
+
const fileContents = new Map();
|
|
79
|
+
for (const f of files) {
|
|
80
|
+
let content;
|
|
81
|
+
try {
|
|
82
|
+
content = readFileSync(f, "utf-8");
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
fileContents.set(f, content);
|
|
88
|
+
const exports = extractExports(content);
|
|
89
|
+
for (const exp of exports) {
|
|
90
|
+
exportMap.set(exp, f);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Check for orphaned imports (importing symbols that no file exports)
|
|
94
|
+
for (const [filePath, content] of fileContents) {
|
|
95
|
+
const imports = extractImports(content);
|
|
96
|
+
const lines = content.split("\n");
|
|
97
|
+
for (const imp of imports) {
|
|
98
|
+
// Only check local imports (starting with . or ..)
|
|
99
|
+
if (!imp.source.startsWith("."))
|
|
100
|
+
continue;
|
|
101
|
+
for (const name of imp.names) {
|
|
102
|
+
// Check if any file exports this symbol
|
|
103
|
+
if (!exportMap.has(name)) {
|
|
104
|
+
const lineNum = lines.findIndex((l) => l.includes(name) && l.includes("import")) + 1;
|
|
105
|
+
issues.push({
|
|
106
|
+
file: filePath,
|
|
107
|
+
line: lineNum || 1,
|
|
108
|
+
kind: "orphaned-import",
|
|
109
|
+
message: `Import '${name}' from '${imp.source}' — symbol not found in any scanned file exports`,
|
|
110
|
+
severity: "high",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Detect renamed/removed patterns
|
|
117
|
+
for (const [filePath, content] of fileContents) {
|
|
118
|
+
const lines = content.split("\n");
|
|
119
|
+
// Check for TODO/FIXME indicating incomplete refactor
|
|
120
|
+
for (let i = 0; i < lines.length; i++) {
|
|
121
|
+
const line = lines[i];
|
|
122
|
+
if (/\/\/\s*(TODO|FIXME|HACK|XXX)\s*:?\s*(refactor|rename|migrate|move|deprecated)/i.test(line)) {
|
|
123
|
+
issues.push({
|
|
124
|
+
file: filePath,
|
|
125
|
+
line: i + 1,
|
|
126
|
+
kind: "incomplete-refactor-marker",
|
|
127
|
+
message: `Found refactor marker: ${line.trim().substring(0, 80)}`,
|
|
128
|
+
severity: "medium",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Detect deprecated usage
|
|
133
|
+
for (let i = 0; i < lines.length; i++) {
|
|
134
|
+
if (/@deprecated/i.test(lines[i])) {
|
|
135
|
+
// Find the symbol being deprecated
|
|
136
|
+
const nextLine = lines[i + 1] || "";
|
|
137
|
+
const symbolMatch = nextLine.match(/\b(function|class|const|let|var)\s+(\w+)/);
|
|
138
|
+
if (symbolMatch) {
|
|
139
|
+
const deprecatedName = symbolMatch[2];
|
|
140
|
+
// Count references across codebase
|
|
141
|
+
let refs = 0;
|
|
142
|
+
for (const [otherFile, otherContent] of fileContents) {
|
|
143
|
+
if (otherFile === filePath)
|
|
144
|
+
continue;
|
|
145
|
+
const regex = new RegExp(`\\b${deprecatedName}\\b`, "g");
|
|
146
|
+
const matches = otherContent.match(regex);
|
|
147
|
+
if (matches)
|
|
148
|
+
refs += matches.length;
|
|
149
|
+
}
|
|
150
|
+
if (refs > 0) {
|
|
151
|
+
issues.push({
|
|
152
|
+
file: filePath,
|
|
153
|
+
line: i + 1,
|
|
154
|
+
kind: "deprecated-still-used",
|
|
155
|
+
message: `@deprecated symbol '${deprecatedName}' still referenced ${refs} time(s) across codebase`,
|
|
156
|
+
severity: "high",
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Detect type assertion overuse (potential behavioral change masking)
|
|
163
|
+
const assertionCount = (content.match(/\bas\s+\w/g) || []).length;
|
|
164
|
+
if (assertionCount > 10) {
|
|
165
|
+
issues.push({
|
|
166
|
+
file: filePath,
|
|
167
|
+
line: 1,
|
|
168
|
+
kind: "excessive-type-assertions",
|
|
169
|
+
message: `${assertionCount} type assertions — may mask type incompatibilities from refactoring`,
|
|
170
|
+
severity: "low",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Detect dead files (files with exports but no imports from other files)
|
|
175
|
+
for (const [filePath, content] of fileContents) {
|
|
176
|
+
const exports = extractExports(content);
|
|
177
|
+
if (exports.length === 0)
|
|
178
|
+
continue;
|
|
179
|
+
// Skip entry points
|
|
180
|
+
const rel = relative(dir, filePath);
|
|
181
|
+
if (rel.includes("index.") || rel.includes("main.") || rel.includes("cli.") || rel.includes("test"))
|
|
182
|
+
continue;
|
|
183
|
+
let referenced = false;
|
|
184
|
+
for (const [otherFile, otherContent] of fileContents) {
|
|
185
|
+
if (otherFile === filePath)
|
|
186
|
+
continue;
|
|
187
|
+
if (exports.some((exp) => otherContent.includes(exp))) {
|
|
188
|
+
referenced = true;
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (!referenced) {
|
|
193
|
+
issues.push({
|
|
194
|
+
file: filePath,
|
|
195
|
+
line: 1,
|
|
196
|
+
kind: "potentially-dead-file",
|
|
197
|
+
message: `File exports [${exports.slice(0, 3).join(", ")}${exports.length > 3 ? "..." : ""}] but none appear imported elsewhere`,
|
|
198
|
+
severity: "low",
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return issues.sort((a, b) => {
|
|
203
|
+
const sev = { high: 3, medium: 2, low: 1 };
|
|
204
|
+
return sev[b.severity] - sev[a.severity];
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
208
|
+
export function runRefactorSafety(argv) {
|
|
209
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
210
|
+
console.log(`
|
|
211
|
+
judges refactor-safety — Analyze refactoring safety
|
|
212
|
+
|
|
213
|
+
Usage:
|
|
214
|
+
judges refactor-safety [dir]
|
|
215
|
+
judges refactor-safety src/ --severity high
|
|
216
|
+
judges refactor-safety --format json
|
|
217
|
+
|
|
218
|
+
Options:
|
|
219
|
+
[dir] Directory to scan (default: .)
|
|
220
|
+
--severity <level> Filter by minimum severity (high|medium|low)
|
|
221
|
+
--format json JSON output
|
|
222
|
+
--help, -h Show this help
|
|
223
|
+
|
|
224
|
+
Detects:
|
|
225
|
+
• Orphaned imports (importing symbols that don't exist)
|
|
226
|
+
• Deprecated symbols still in use
|
|
227
|
+
• Incomplete refactor markers (TODO/FIXME with refactor keywords)
|
|
228
|
+
• Excessive type assertions masking type changes
|
|
229
|
+
• Potentially dead files (exported but never imported)
|
|
230
|
+
`);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
234
|
+
const severityFilter = argv.find((_a, i) => argv[i - 1] === "--severity") || "low";
|
|
235
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
236
|
+
if (!existsSync(dir)) {
|
|
237
|
+
console.error(` Directory not found: ${dir}`);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
const severityOrder = { high: 3, medium: 2, low: 1 };
|
|
241
|
+
const minSev = severityOrder[severityFilter] || 1;
|
|
242
|
+
const files = collectFiles(dir);
|
|
243
|
+
const allIssues = analyzeRefactorSafety(files, dir).filter((x) => severityOrder[x.severity] >= minSev);
|
|
244
|
+
if (format === "json") {
|
|
245
|
+
console.log(JSON.stringify({ issues: allIssues, filesScanned: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
console.log(`\n Refactor Safety — ${files.length} files scanned, ${allIssues.length} issue(s)\n ──────────────────────────`);
|
|
249
|
+
if (allIssues.length === 0) {
|
|
250
|
+
console.log(" ✅ No refactoring safety issues detected");
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
const byKind = new Map();
|
|
254
|
+
for (const issue of allIssues) {
|
|
255
|
+
byKind.set(issue.kind, (byKind.get(issue.kind) || 0) + 1);
|
|
256
|
+
}
|
|
257
|
+
console.log("\n Summary:");
|
|
258
|
+
for (const [kind, count] of byKind) {
|
|
259
|
+
console.log(` ${kind}: ${count}`);
|
|
260
|
+
}
|
|
261
|
+
console.log("\n Details:");
|
|
262
|
+
for (const issue of allIssues.slice(0, 50)) {
|
|
263
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "⚪";
|
|
264
|
+
console.log(` ${icon} [${issue.severity}] ${issue.file}:${issue.line}`);
|
|
265
|
+
console.log(` ${issue.message}`);
|
|
266
|
+
}
|
|
267
|
+
if (allIssues.length > 50) {
|
|
268
|
+
console.log(`\n ... and ${allIssues.length - 50} more`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
console.log("");
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=refactor-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refactor-safety.js","sourceRoot":"","sources":["../../src/commands/refactor-safety.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource cleanup — validate that allocated resources are properly
|
|
3
|
+
* freed: file handles, DB connections, timers, event listeners,
|
|
4
|
+
* streams with try-finally or equivalent cleanup mechanisms.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runResourceCleanup(argv: string[]): void;
|
|
7
|
+
//# sourceMappingURL=resource-cleanup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-cleanup.d.ts","sourceRoot":"","sources":["../../src/commands/resource-cleanup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+LH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8EvD"}
|