@mathonsunday/dead-code-toolkit 0.1.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/README.md +356 -0
- package/dist/analyzer.d.ts +23 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +173 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/checkers/knipChecker.d.ts +11 -0
- package/dist/checkers/knipChecker.d.ts.map +1 -0
- package/dist/checkers/knipChecker.js +226 -0
- package/dist/checkers/knipChecker.js.map +1 -0
- package/dist/checkers/typescriptChecker.d.ts +10 -0
- package/dist/checkers/typescriptChecker.d.ts.map +1 -0
- package/dist/checkers/typescriptChecker.js +174 -0
- package/dist/checkers/typescriptChecker.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +204 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/detectors.d.ts +29 -0
- package/dist/config/detectors.d.ts.map +1 -0
- package/dist/config/detectors.js +159 -0
- package/dist/config/detectors.js.map +1 -0
- package/dist/config/templates.d.ts +76 -0
- package/dist/config/templates.d.ts.map +1 -0
- package/dist/config/templates.js +191 -0
- package/dist/config/templates.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/reporters/jsonReporter.d.ts +68 -0
- package/dist/reporters/jsonReporter.d.ts.map +1 -0
- package/dist/reporters/jsonReporter.js +161 -0
- package/dist/reporters/jsonReporter.js.map +1 -0
- package/dist/setup/hookInstaller.d.ts +36 -0
- package/dist/setup/hookInstaller.d.ts.map +1 -0
- package/dist/setup/hookInstaller.js +196 -0
- package/dist/setup/hookInstaller.js.map +1 -0
- package/dist/setup/installer.d.ts +10 -0
- package/dist/setup/installer.d.ts.map +1 -0
- package/dist/setup/installer.js +156 -0
- package/dist/setup/installer.js.map +1 -0
- package/dist/setup/packageJsonUpdater.d.ts +54 -0
- package/dist/setup/packageJsonUpdater.d.ts.map +1 -0
- package/dist/setup/packageJsonUpdater.js +129 -0
- package/dist/setup/packageJsonUpdater.js.map +1 -0
- package/dist/src/analyzer.d.ts +23 -0
- package/dist/src/analyzer.d.ts.map +1 -0
- package/dist/src/analyzer.js +173 -0
- package/dist/src/analyzer.js.map +1 -0
- package/dist/src/checkers/knipChecker.d.ts +11 -0
- package/dist/src/checkers/knipChecker.d.ts.map +1 -0
- package/dist/src/checkers/knipChecker.js +226 -0
- package/dist/src/checkers/knipChecker.js.map +1 -0
- package/dist/src/checkers/typescriptChecker.d.ts +10 -0
- package/dist/src/checkers/typescriptChecker.d.ts.map +1 -0
- package/dist/src/checkers/typescriptChecker.js +174 -0
- package/dist/src/checkers/typescriptChecker.js.map +1 -0
- package/dist/src/config/detectors.d.ts +29 -0
- package/dist/src/config/detectors.d.ts.map +1 -0
- package/dist/src/config/detectors.js +159 -0
- package/dist/src/config/detectors.js.map +1 -0
- package/dist/src/config/templates.d.ts +76 -0
- package/dist/src/config/templates.d.ts.map +1 -0
- package/dist/src/config/templates.js +191 -0
- package/dist/src/config/templates.js.map +1 -0
- package/dist/src/index.d.ts +13 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +17 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/reporters/jsonReporter.d.ts +68 -0
- package/dist/src/reporters/jsonReporter.d.ts.map +1 -0
- package/dist/src/reporters/jsonReporter.js +161 -0
- package/dist/src/reporters/jsonReporter.js.map +1 -0
- package/dist/src/setup/hookInstaller.d.ts +36 -0
- package/dist/src/setup/hookInstaller.d.ts.map +1 -0
- package/dist/src/setup/hookInstaller.js +196 -0
- package/dist/src/setup/hookInstaller.js.map +1 -0
- package/dist/src/setup/installer.d.ts +10 -0
- package/dist/src/setup/installer.d.ts.map +1 -0
- package/dist/src/setup/installer.js +156 -0
- package/dist/src/setup/installer.js.map +1 -0
- package/dist/src/setup/packageJsonUpdater.d.ts +54 -0
- package/dist/src/setup/packageJsonUpdater.d.ts.map +1 -0
- package/dist/src/setup/packageJsonUpdater.js +129 -0
- package/dist/src/setup/packageJsonUpdater.js.map +1 -0
- package/dist/src/types.d.ts +177 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -0
- package/dist/types.d.ts +177 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knip integration for detecting unused exports, files, and dependencies
|
|
3
|
+
* Knip performs symbol-level analysis to find unused code
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
/**
|
|
7
|
+
* Run Knip analysis on a project
|
|
8
|
+
* Requires Knip to be installed as a dependency
|
|
9
|
+
*/
|
|
10
|
+
export async function runKnipCheck(projectRoot) {
|
|
11
|
+
const startTime = Date.now();
|
|
12
|
+
try {
|
|
13
|
+
// Check if knip is available
|
|
14
|
+
if (!isKnipInstalled()) {
|
|
15
|
+
return {
|
|
16
|
+
type: 'knip',
|
|
17
|
+
status: 'skipped',
|
|
18
|
+
findings: [],
|
|
19
|
+
executionTime: Date.now() - startTime,
|
|
20
|
+
error: 'Knip not installed. Install with: npm install --save-dev knip',
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// Run knip and capture output
|
|
24
|
+
const output = await executeKnip(projectRoot);
|
|
25
|
+
// Parse knip output into findings
|
|
26
|
+
const findings = parseKnipOutput(output);
|
|
27
|
+
return {
|
|
28
|
+
type: 'knip',
|
|
29
|
+
status: findings.length > 0 ? 'success' : 'success', // success even if issues found
|
|
30
|
+
findings,
|
|
31
|
+
executionTime: Date.now() - startTime,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : 'Unknown error running Knip';
|
|
36
|
+
return {
|
|
37
|
+
type: 'knip',
|
|
38
|
+
status: 'failure',
|
|
39
|
+
findings: [],
|
|
40
|
+
executionTime: Date.now() - startTime,
|
|
41
|
+
error: `Knip check failed: ${message}`,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if Knip is installed and available
|
|
47
|
+
*/
|
|
48
|
+
function isKnipInstalled() {
|
|
49
|
+
try {
|
|
50
|
+
execSync('npm list knip 2>/dev/null', { stdio: 'ignore' });
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Execute Knip and return JSON output
|
|
59
|
+
*/
|
|
60
|
+
async function executeKnip(projectRoot) {
|
|
61
|
+
try {
|
|
62
|
+
// Run knip with JSON output
|
|
63
|
+
// Note: Knip output format varies by version
|
|
64
|
+
// For now, we'll parse the standard text output
|
|
65
|
+
const result = execSync('npx knip --reporter json 2>&1', {
|
|
66
|
+
cwd: projectRoot,
|
|
67
|
+
encoding: 'utf-8',
|
|
68
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer for large projects
|
|
69
|
+
});
|
|
70
|
+
// Parse JSON output if available
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(result);
|
|
73
|
+
return parsed;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// If JSON parsing fails, try text format
|
|
77
|
+
return parseKnipTextOutput(result);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
// Knip exits with non-zero code when issues found
|
|
82
|
+
// Re-run to capture output
|
|
83
|
+
const result = execSync('npx knip --reporter json 2>&1 || true', {
|
|
84
|
+
cwd: projectRoot,
|
|
85
|
+
encoding: 'utf-8',
|
|
86
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
87
|
+
});
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(result);
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return parseKnipTextOutput(result);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Parse Knip text output (fallback for JSON parsing failure)
|
|
99
|
+
*/
|
|
100
|
+
function parseKnipTextOutput(output) {
|
|
101
|
+
const issues = [];
|
|
102
|
+
// Parse typical Knip output format
|
|
103
|
+
// Example: "src/utils/unused.ts:1:1: Unused export 'helper'"
|
|
104
|
+
const lines = output.split('\n');
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
if (!line.trim())
|
|
107
|
+
continue;
|
|
108
|
+
// Match pattern: file:line:column: message
|
|
109
|
+
const match = line.match(/^(.+):(\d+):(\d+):\s*(.+)$/);
|
|
110
|
+
if (match) {
|
|
111
|
+
const [, filePath, , , message] = match;
|
|
112
|
+
// Determine issue type from message
|
|
113
|
+
let type = 'unused';
|
|
114
|
+
let exportName;
|
|
115
|
+
if (message.includes('unused')) {
|
|
116
|
+
type = 'unused';
|
|
117
|
+
// Try to extract export name
|
|
118
|
+
const exportMatch = message.match(/['"]([\w$]+)['"]/);
|
|
119
|
+
if (exportMatch)
|
|
120
|
+
exportName = exportMatch[1];
|
|
121
|
+
}
|
|
122
|
+
else if (message.includes('unresolved')) {
|
|
123
|
+
type = 'unresolved';
|
|
124
|
+
}
|
|
125
|
+
else if (message.includes('unlisted')) {
|
|
126
|
+
type = 'unlisted';
|
|
127
|
+
}
|
|
128
|
+
else if (message.includes('uncalled')) {
|
|
129
|
+
type = 'uncalled';
|
|
130
|
+
}
|
|
131
|
+
issues.push({
|
|
132
|
+
type,
|
|
133
|
+
filePath,
|
|
134
|
+
exportName,
|
|
135
|
+
severity: 'warn',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
issues,
|
|
141
|
+
hasErrors: issues.length > 0,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Convert Knip issues to standardized Finding format
|
|
146
|
+
*/
|
|
147
|
+
function parseKnipOutput(output) {
|
|
148
|
+
const findings = [];
|
|
149
|
+
for (const issue of output.issues) {
|
|
150
|
+
const finding = {
|
|
151
|
+
category: mapKnipTypeToCategory(issue.type),
|
|
152
|
+
severity: 'warning', // Knip outputs are typically warnings
|
|
153
|
+
file: issue.filePath,
|
|
154
|
+
message: formatKnipMessage(issue),
|
|
155
|
+
fixable: isKnipFixable(issue.type),
|
|
156
|
+
suggestion: getKnipSuggestion(issue),
|
|
157
|
+
source: 'knip',
|
|
158
|
+
rule: issue.type,
|
|
159
|
+
};
|
|
160
|
+
findings.push(finding);
|
|
161
|
+
}
|
|
162
|
+
return findings;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Map Knip issue type to standard category
|
|
166
|
+
*/
|
|
167
|
+
function mapKnipTypeToCategory(type) {
|
|
168
|
+
switch (type) {
|
|
169
|
+
case 'unused':
|
|
170
|
+
return 'unused-export';
|
|
171
|
+
case 'unresolved':
|
|
172
|
+
return 'type-error';
|
|
173
|
+
case 'unlisted':
|
|
174
|
+
return 'unused-dependency';
|
|
175
|
+
case 'uncalled':
|
|
176
|
+
return 'unused-var';
|
|
177
|
+
default:
|
|
178
|
+
return 'unused-export';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Format Knip issue into human-readable message
|
|
183
|
+
*/
|
|
184
|
+
function formatKnipMessage(issue) {
|
|
185
|
+
switch (issue.type) {
|
|
186
|
+
case 'unused':
|
|
187
|
+
return issue.exportName
|
|
188
|
+
? `Export '${issue.exportName}' is unused`
|
|
189
|
+
: 'Unused export';
|
|
190
|
+
case 'unresolved':
|
|
191
|
+
return `Unresolved import or reference`;
|
|
192
|
+
case 'unlisted':
|
|
193
|
+
return `Unlisted dependency`;
|
|
194
|
+
case 'uncalled':
|
|
195
|
+
return `Function or method never called`;
|
|
196
|
+
default:
|
|
197
|
+
return 'Dead code detected';
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Determine if a Knip issue can be auto-fixed
|
|
202
|
+
*/
|
|
203
|
+
function isKnipFixable(type) {
|
|
204
|
+
// Only unused exports can be reliably auto-fixed
|
|
205
|
+
return type === 'unused';
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get suggestion for fixing a Knip issue
|
|
209
|
+
*/
|
|
210
|
+
function getKnipSuggestion(issue) {
|
|
211
|
+
switch (issue.type) {
|
|
212
|
+
case 'unused':
|
|
213
|
+
return issue.exportName
|
|
214
|
+
? `Remove 'export' keyword or the entire '${issue.exportName}' declaration`
|
|
215
|
+
: 'Remove this export or use it somewhere in your codebase';
|
|
216
|
+
case 'unresolved':
|
|
217
|
+
return 'Check the import path is correct and the module exists';
|
|
218
|
+
case 'unlisted':
|
|
219
|
+
return 'Add this to your package.json dependencies';
|
|
220
|
+
case 'uncalled':
|
|
221
|
+
return 'Remove this function or call it somewhere';
|
|
222
|
+
default:
|
|
223
|
+
return 'Review and consider removing this code';
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=knipChecker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knipChecker.js","sourceRoot":"","sources":["../../src/checkers/knipChecker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript compiler integration for detecting type errors
|
|
3
|
+
* Uses tsc to compile and collect diagnostics
|
|
4
|
+
*/
|
|
5
|
+
import type { CheckResult } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Run TypeScript type checking on a project
|
|
8
|
+
*/
|
|
9
|
+
export declare function runTypeScriptCheck(projectRoot: string): Promise<CheckResult>;
|
|
10
|
+
//# sourceMappingURL=typescriptChecker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescriptChecker.d.ts","sourceRoot":"","sources":["../../src/checkers/typescriptChecker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,aAAa,CAAC;AAWxD;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqClF"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript compiler integration for detecting type errors
|
|
3
|
+
* Uses tsc to compile and collect diagnostics
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
/**
|
|
7
|
+
* Run TypeScript type checking on a project
|
|
8
|
+
*/
|
|
9
|
+
export async function runTypeScriptCheck(projectRoot) {
|
|
10
|
+
const startTime = Date.now();
|
|
11
|
+
try {
|
|
12
|
+
// Check if TypeScript is available
|
|
13
|
+
if (!isTypeScriptInstalled()) {
|
|
14
|
+
return {
|
|
15
|
+
type: 'typescript',
|
|
16
|
+
status: 'skipped',
|
|
17
|
+
findings: [],
|
|
18
|
+
executionTime: Date.now() - startTime,
|
|
19
|
+
error: 'TypeScript not installed. Install with: npm install --save-dev typescript',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Run tsc and capture diagnostics
|
|
23
|
+
const errors = await executeTypeScriptCheck(projectRoot);
|
|
24
|
+
// Convert to findings
|
|
25
|
+
const findings = parseTypeScriptErrors(errors);
|
|
26
|
+
return {
|
|
27
|
+
type: 'typescript',
|
|
28
|
+
status: findings.length > 0 ? 'success' : 'success',
|
|
29
|
+
findings,
|
|
30
|
+
executionTime: Date.now() - startTime,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
35
|
+
return {
|
|
36
|
+
type: 'typescript',
|
|
37
|
+
status: 'failure',
|
|
38
|
+
findings: [],
|
|
39
|
+
executionTime: Date.now() - startTime,
|
|
40
|
+
error: `TypeScript check failed: ${message}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if TypeScript is installed
|
|
46
|
+
*/
|
|
47
|
+
function isTypeScriptInstalled() {
|
|
48
|
+
try {
|
|
49
|
+
execSync('npm list typescript 2>/dev/null', { stdio: 'ignore' });
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Execute TypeScript compiler and capture errors
|
|
58
|
+
*/
|
|
59
|
+
async function executeTypeScriptCheck(projectRoot) {
|
|
60
|
+
try {
|
|
61
|
+
// Run tsc with noEmit to check types without emitting
|
|
62
|
+
// The command may exit with non-zero code if errors found
|
|
63
|
+
execSync('npx tsc --noEmit 2>&1', {
|
|
64
|
+
cwd: projectRoot,
|
|
65
|
+
stdio: 'pipe',
|
|
66
|
+
});
|
|
67
|
+
// If we got here, no errors
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// Parse the error output
|
|
72
|
+
const output = error instanceof Error && 'stdout' in error
|
|
73
|
+
? error.stdout?.toString() ||
|
|
74
|
+
error.message
|
|
75
|
+
: String(error);
|
|
76
|
+
return parseTypeScriptOutput(output);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse TypeScript compiler output into structured errors
|
|
81
|
+
* Format: file.ts:line:col - error TS1234: message
|
|
82
|
+
*/
|
|
83
|
+
function parseTypeScriptOutput(output) {
|
|
84
|
+
const errors = [];
|
|
85
|
+
const lines = output.split('\n');
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
if (!line.trim())
|
|
88
|
+
continue;
|
|
89
|
+
// Match TypeScript error format: file:line:col - error TSxxxx: message
|
|
90
|
+
const match = line.match(/^(.+):(\d+):(\d+)\s*-\s*(error|warning)\s*TS(\d+):\s*(.+)$/);
|
|
91
|
+
if (match) {
|
|
92
|
+
const [, file, lineStr, colStr, severity, code, message] = match;
|
|
93
|
+
errors.push({
|
|
94
|
+
file,
|
|
95
|
+
line: parseInt(lineStr, 10),
|
|
96
|
+
column: parseInt(colStr, 10),
|
|
97
|
+
code: parseInt(code, 10),
|
|
98
|
+
message,
|
|
99
|
+
severity: severity || 'error',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return errors;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Convert TypeScript errors to standardized Finding format
|
|
107
|
+
*/
|
|
108
|
+
function parseTypeScriptErrors(errors) {
|
|
109
|
+
return errors
|
|
110
|
+
.map((error) => {
|
|
111
|
+
// Map common TypeScript error codes
|
|
112
|
+
const category = mapTypeScriptErrorCode(error.code);
|
|
113
|
+
return {
|
|
114
|
+
category,
|
|
115
|
+
severity: error.severity === 'error' ? 'error' : 'warning',
|
|
116
|
+
file: error.file,
|
|
117
|
+
line: error.line,
|
|
118
|
+
column: error.column,
|
|
119
|
+
message: error.message,
|
|
120
|
+
fixable: isTypeScriptFixable(),
|
|
121
|
+
suggestion: getTypeScriptSuggestion(error.code),
|
|
122
|
+
source: 'typescript',
|
|
123
|
+
rule: `TS${error.code}`,
|
|
124
|
+
};
|
|
125
|
+
})
|
|
126
|
+
.filter((f) =>
|
|
127
|
+
// Filter to only type-related errors that are relevant to dead code
|
|
128
|
+
f.rule !== 'TS6133' && // "is declared but never used" - covered by other tools
|
|
129
|
+
f.rule !== 'TS6138' // "are declared but never used" - covered by other tools
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Map TypeScript error code to dead code category
|
|
134
|
+
*/
|
|
135
|
+
function mapTypeScriptErrorCode(code) {
|
|
136
|
+
// 6133: variable declared but never used
|
|
137
|
+
// 6138: variables never used
|
|
138
|
+
// 7006: parameter never used
|
|
139
|
+
// 18004: type never used
|
|
140
|
+
// 2304: name not found
|
|
141
|
+
// 2307: cannot find module
|
|
142
|
+
if (code === 6133 || code === 6138)
|
|
143
|
+
return 'unused-var';
|
|
144
|
+
if (code === 7006)
|
|
145
|
+
return 'unused-param';
|
|
146
|
+
if (code === 18004)
|
|
147
|
+
return 'unused-export';
|
|
148
|
+
if (code === 2304 || code === 2307)
|
|
149
|
+
return 'type-error';
|
|
150
|
+
return 'type-error';
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Check if TypeScript error can be auto-fixed
|
|
154
|
+
*/
|
|
155
|
+
function isTypeScriptFixable() {
|
|
156
|
+
// Some TypeScript errors could theoretically be fixed
|
|
157
|
+
// but we'll be conservative and only mark known fixable ones
|
|
158
|
+
return false; // Default: not fixable via automation
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get suggestion for fixing TypeScript error
|
|
162
|
+
*/
|
|
163
|
+
function getTypeScriptSuggestion(code) {
|
|
164
|
+
const suggestions = {
|
|
165
|
+
6133: 'Remove the variable or use it in your code',
|
|
166
|
+
6138: 'Remove unused variables or use them',
|
|
167
|
+
7006: 'Remove the parameter or use it in the function',
|
|
168
|
+
18004: 'Remove the type definition or use it',
|
|
169
|
+
2304: 'Check that this name is defined and imported correctly',
|
|
170
|
+
2307: 'Verify the module path and that the package is installed',
|
|
171
|
+
};
|
|
172
|
+
return suggestions[code] || 'Fix this TypeScript error';
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=typescriptChecker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescriptChecker.js","sourceRoot":"","sources":["../../src/checkers/typescriptChecker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../cli/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI entry point for dead code toolkit
|
|
4
|
+
* Provides command-line interface for analysis and fixing
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { resolve } from 'path';
|
|
8
|
+
import { analyzeDeadCode } from '../src/analyzer.js';
|
|
9
|
+
import { createJSONReport, formatJSONReport, createLLMSummary } from '../src/reporters/jsonReporter.js';
|
|
10
|
+
import { setupProject } from '../src/setup/installer.js';
|
|
11
|
+
const program = new Command();
|
|
12
|
+
program
|
|
13
|
+
.name('dead-code-toolkit')
|
|
14
|
+
.description('Comprehensive dead code detection and cleanup for TypeScript projects')
|
|
15
|
+
.version('0.1.0');
|
|
16
|
+
/**
|
|
17
|
+
* analyze command - run dead code analysis
|
|
18
|
+
*/
|
|
19
|
+
program
|
|
20
|
+
.command('analyze')
|
|
21
|
+
.description('Analyze project for dead code')
|
|
22
|
+
.option('-p, --path <path>', 'Project root directory', process.cwd())
|
|
23
|
+
.option('--checks <list>', 'Comma-separated list of checks to run (knip,typescript,all)', 'all')
|
|
24
|
+
.option('--fix', 'Automatically fix issues')
|
|
25
|
+
.option('--dry-run', 'Show what would be fixed without modifying files')
|
|
26
|
+
.option('--json', 'Output as JSON')
|
|
27
|
+
.option('--summary', 'Output brief summary')
|
|
28
|
+
.option('-v, --verbose', 'Verbose output')
|
|
29
|
+
.action(async (options) => {
|
|
30
|
+
const projectRoot = resolve(options.path);
|
|
31
|
+
// Parse checks
|
|
32
|
+
const checks = options.checks === 'all' ? undefined : options.checks.split(',').map((c) => c.trim());
|
|
33
|
+
if (options.verbose) {
|
|
34
|
+
console.log(`[Dead Code Toolkit] Starting analysis...`);
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const result = await analyzeDeadCode({
|
|
38
|
+
projectRoot,
|
|
39
|
+
checks: checks,
|
|
40
|
+
fix: options.fix && !options.dryRun,
|
|
41
|
+
verbose: options.verbose,
|
|
42
|
+
});
|
|
43
|
+
if (options.json) {
|
|
44
|
+
// Output as JSON
|
|
45
|
+
const report = createJSONReport(result);
|
|
46
|
+
console.log(formatJSONReport(report));
|
|
47
|
+
}
|
|
48
|
+
else if (options.summary) {
|
|
49
|
+
// Output brief summary
|
|
50
|
+
const summary = createLLMSummary(result);
|
|
51
|
+
console.log(summary.summary);
|
|
52
|
+
console.log('\nAction items:');
|
|
53
|
+
for (const item of summary.actionItems) {
|
|
54
|
+
console.log(` ⢠${item}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Output human-readable format
|
|
59
|
+
console.log('\nš Dead Code Analysis Results');
|
|
60
|
+
console.log('ā'.repeat(50));
|
|
61
|
+
console.log(`\nStatus: ${result.status.toUpperCase()}`);
|
|
62
|
+
console.log(`Total Issues: ${result.summary.totalIssues}`);
|
|
63
|
+
console.log(`Fixable: ${result.summary.fixableCount}`);
|
|
64
|
+
console.log(`Execution Time: ${result.executionTime}ms`);
|
|
65
|
+
if (result.summary.totalIssues > 0) {
|
|
66
|
+
console.log('\nIssues by Category:');
|
|
67
|
+
for (const [category, count] of Object.entries(result.summary.byCategory)) {
|
|
68
|
+
console.log(` ⢠${category}: ${count}`);
|
|
69
|
+
}
|
|
70
|
+
console.log('\nTop Issues:');
|
|
71
|
+
for (const finding of result.findings.slice(0, 5)) {
|
|
72
|
+
console.log(` ${finding.severity.toUpperCase()} [${finding.source}] ${finding.file}`);
|
|
73
|
+
console.log(` ${finding.message}`);
|
|
74
|
+
if (finding.suggestion) {
|
|
75
|
+
console.log(` š” ${finding.suggestion}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (result.findings.length > 5) {
|
|
79
|
+
console.log(` ... and ${result.findings.length - 5} more`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log('\nā
No dead code detected!');
|
|
84
|
+
}
|
|
85
|
+
console.log('\nš Recommendations:');
|
|
86
|
+
const recommendations = createLLMSummary(result).actionItems;
|
|
87
|
+
for (const rec of recommendations) {
|
|
88
|
+
console.log(` ⢠${rec}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Exit with appropriate code
|
|
92
|
+
process.exit(result.status === 'success' || result.status === 'partial' ? 0 : 1);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
96
|
+
console.error(`\nā Analysis failed: ${message}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
/**
|
|
101
|
+
* setup command - automated setup
|
|
102
|
+
*/
|
|
103
|
+
program
|
|
104
|
+
.command('setup')
|
|
105
|
+
.description('Setup dead code detection in a project')
|
|
106
|
+
.option('-p, --path <path>', 'Project root directory', process.cwd())
|
|
107
|
+
.option('--hooks', 'Install pre-commit hooks', true)
|
|
108
|
+
.option('--no-install', 'Skip dependency installation')
|
|
109
|
+
.option('-v, --verbose', 'Verbose output')
|
|
110
|
+
.action(async (options) => {
|
|
111
|
+
const projectRoot = resolve(options.path);
|
|
112
|
+
console.log('\nš Setting up Dead Code Toolkit');
|
|
113
|
+
console.log('ā'.repeat(50));
|
|
114
|
+
try {
|
|
115
|
+
const result = await setupProject({
|
|
116
|
+
projectRoot,
|
|
117
|
+
setupHooks: options.hooks !== false,
|
|
118
|
+
installDependencies: options.noInstall !== true,
|
|
119
|
+
verbose: options.verbose,
|
|
120
|
+
});
|
|
121
|
+
if (result.status === 'failure') {
|
|
122
|
+
console.error('\nā Setup failed:');
|
|
123
|
+
for (const error of result.errors || []) {
|
|
124
|
+
console.error(` ⢠${error}`);
|
|
125
|
+
}
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
console.log('\nā
Setup Complete!');
|
|
129
|
+
if (result.filesCreated.length > 0) {
|
|
130
|
+
console.log('\nš Files created:');
|
|
131
|
+
for (const file of result.filesCreated) {
|
|
132
|
+
console.log(` ⢠${file}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (result.scriptsAdded.length > 0) {
|
|
136
|
+
console.log('\nš Scripts added to package.json:');
|
|
137
|
+
for (const script of result.scriptsAdded) {
|
|
138
|
+
console.log(` ⢠npm run ${script}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (result.dependenciesInstalled.length > 0) {
|
|
142
|
+
console.log('\nš¦ Dependencies installed:');
|
|
143
|
+
for (const dep of result.dependenciesInstalled) {
|
|
144
|
+
console.log(` ⢠${dep}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (result.nextSteps.length > 0) {
|
|
148
|
+
console.log('\nš Next steps:');
|
|
149
|
+
for (const step of result.nextSteps) {
|
|
150
|
+
console.log(` ⢠${step}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (result.errors && result.errors.length > 0) {
|
|
154
|
+
console.log('\nā ļø Warnings:');
|
|
155
|
+
for (const error of result.errors) {
|
|
156
|
+
console.log(` ⢠${error}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
process.exit(result.status === 'success' || result.status === 'partial' ? 0 : 1);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
163
|
+
console.error(`\nā Setup failed: ${message}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
/**
|
|
168
|
+
* check command - run individual checks
|
|
169
|
+
*/
|
|
170
|
+
program
|
|
171
|
+
.command('check:knip')
|
|
172
|
+
.description('Run only Knip analysis')
|
|
173
|
+
.option('-p, --path <path>', 'Project root directory', process.cwd())
|
|
174
|
+
.option('-v, --verbose', 'Verbose output')
|
|
175
|
+
.action(async (options) => {
|
|
176
|
+
const result = await analyzeDeadCode({
|
|
177
|
+
projectRoot: resolve(options.path),
|
|
178
|
+
checks: ['knip'],
|
|
179
|
+
verbose: options.verbose,
|
|
180
|
+
});
|
|
181
|
+
console.log(`Knip check: ${result.summary.totalIssues} issues found`);
|
|
182
|
+
process.exit(result.status === 'failure' ? 1 : 0);
|
|
183
|
+
});
|
|
184
|
+
program
|
|
185
|
+
.command('check:types')
|
|
186
|
+
.description('Run only TypeScript type check')
|
|
187
|
+
.option('-p, --path <path>', 'Project root directory', process.cwd())
|
|
188
|
+
.option('-v, --verbose', 'Verbose output')
|
|
189
|
+
.action(async (options) => {
|
|
190
|
+
const result = await analyzeDeadCode({
|
|
191
|
+
projectRoot: resolve(options.path),
|
|
192
|
+
checks: ['typescript'],
|
|
193
|
+
verbose: options.verbose,
|
|
194
|
+
});
|
|
195
|
+
console.log(`TypeScript check: ${result.summary.totalIssues} issues found`);
|
|
196
|
+
process.exit(result.status === 'failure' ? 1 : 0);
|
|
197
|
+
});
|
|
198
|
+
// Parse command line arguments
|
|
199
|
+
program.parse(process.argv);
|
|
200
|
+
// Show help if no command
|
|
201
|
+
if (process.argv.length < 3) {
|
|
202
|
+
program.outputHelp();
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../cli/index.ts"],"names":[],"mappings":"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"}
|