@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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* package.json updater
|
|
3
|
+
* Safely updates package.json with new scripts and dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
6
|
+
import { resolve } from 'path';
|
|
7
|
+
import { generatePackageJsonScripts } from '../config/templates.js';
|
|
8
|
+
/**
|
|
9
|
+
* Read package.json from project
|
|
10
|
+
*/
|
|
11
|
+
export function readPackageJson(projectRoot) {
|
|
12
|
+
const packageJsonPath = resolve(projectRoot, 'package.json');
|
|
13
|
+
try {
|
|
14
|
+
const content = readFileSync(packageJsonPath, 'utf-8');
|
|
15
|
+
return JSON.parse(content);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error(`Failed to read package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Write package.json back to disk
|
|
23
|
+
*/
|
|
24
|
+
export function writePackageJson(projectRoot, packageJson) {
|
|
25
|
+
const packageJsonPath = resolve(projectRoot, 'package.json');
|
|
26
|
+
try {
|
|
27
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
throw new Error(`Failed to write package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Add scripts to package.json
|
|
35
|
+
* Returns list of added scripts
|
|
36
|
+
*/
|
|
37
|
+
export function addScripts(packageJson) {
|
|
38
|
+
const scriptsToAdd = generatePackageJsonScripts();
|
|
39
|
+
const addedScripts = [];
|
|
40
|
+
if (!packageJson.scripts) {
|
|
41
|
+
packageJson.scripts = {};
|
|
42
|
+
}
|
|
43
|
+
for (const [name, command] of Object.entries(scriptsToAdd)) {
|
|
44
|
+
if (!packageJson.scripts[name]) {
|
|
45
|
+
packageJson.scripts[name] = command;
|
|
46
|
+
addedScripts.push(name);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return addedScripts;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get recommended dev dependencies
|
|
53
|
+
*/
|
|
54
|
+
export function getRecommendedDevDependencies() {
|
|
55
|
+
return {
|
|
56
|
+
knip: '^5.82.1',
|
|
57
|
+
'type-coverage': '^2.29.7',
|
|
58
|
+
'typescript-coverage-report': '^1.1.1',
|
|
59
|
+
husky: '^9.1.7',
|
|
60
|
+
'lint-staged': '^16.2.7',
|
|
61
|
+
'@commitlint/cli': '^20.3.1',
|
|
62
|
+
'@commitlint/config-conventional': '^20.3.1',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check which dev dependencies are already installed
|
|
67
|
+
*/
|
|
68
|
+
export function getInstalledDevDependencies(packageJson) {
|
|
69
|
+
const devDeps = packageJson.devDependencies || {};
|
|
70
|
+
const recommended = getRecommendedDevDependencies();
|
|
71
|
+
const installed = {};
|
|
72
|
+
for (const [name] of Object.entries(recommended)) {
|
|
73
|
+
if (devDeps[name]) {
|
|
74
|
+
installed[name] = devDeps[name];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return installed;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get missing dev dependencies that need to be installed
|
|
81
|
+
*/
|
|
82
|
+
export function getMissingDevDependencies(packageJson) {
|
|
83
|
+
const devDeps = packageJson.devDependencies || {};
|
|
84
|
+
const recommended = getRecommendedDevDependencies();
|
|
85
|
+
const missing = {};
|
|
86
|
+
for (const [name, version] of Object.entries(recommended)) {
|
|
87
|
+
if (!devDeps[name]) {
|
|
88
|
+
missing[name] = version;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return missing;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Format dependencies for npm install command
|
|
95
|
+
*/
|
|
96
|
+
export function formatDependenciesForInstall(deps) {
|
|
97
|
+
return Object.entries(deps).map(([name, version]) => `${name}@${version}`);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Update package.json with all necessary changes
|
|
101
|
+
*/
|
|
102
|
+
export function updatePackageJson(projectRoot, options = {}) {
|
|
103
|
+
const packageJson = readPackageJson(projectRoot);
|
|
104
|
+
let updated = false;
|
|
105
|
+
const scriptsAdded = [];
|
|
106
|
+
// Add scripts
|
|
107
|
+
if (options.addScripts !== false) {
|
|
108
|
+
const added = addScripts(packageJson);
|
|
109
|
+
if (added.length > 0) {
|
|
110
|
+
scriptsAdded.push(...added);
|
|
111
|
+
updated = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Get dependencies to install
|
|
115
|
+
let dependenciesToInstall = {};
|
|
116
|
+
if (options.installDependencies !== false) {
|
|
117
|
+
dependenciesToInstall = getMissingDevDependencies(packageJson);
|
|
118
|
+
}
|
|
119
|
+
// Write back if updated
|
|
120
|
+
if (updated) {
|
|
121
|
+
writePackageJson(projectRoot, packageJson);
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
scriptsAdded,
|
|
125
|
+
dependenciesToInstall,
|
|
126
|
+
updated,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=packageJsonUpdater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageJsonUpdater.js","sourceRoot":"","sources":["../../src/setup/packageJsonUpdater.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core analyzer - orchestrates all checkers and produces unified analysis results
|
|
3
|
+
*/
|
|
4
|
+
import type { AnalysisOptions, AnalysisResult, Finding } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Main entry point: analyze dead code in a project
|
|
7
|
+
*
|
|
8
|
+
* @param options Configuration for the analysis
|
|
9
|
+
* @returns Complete analysis results
|
|
10
|
+
*/
|
|
11
|
+
export declare function analyzeDeadCode(options: AnalysisOptions): Promise<AnalysisResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Apply fixes to a set of findings
|
|
14
|
+
*
|
|
15
|
+
* @param findings The findings to fix
|
|
16
|
+
* @param options Options for fixing
|
|
17
|
+
* @returns Result of fix attempt
|
|
18
|
+
*/
|
|
19
|
+
export declare function fixFindings(findings: Finding[], options?: {
|
|
20
|
+
dryRun?: boolean;
|
|
21
|
+
verbose?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,OAAO,EAGR,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAiEvF;AA4FD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GACpD,OAAO,CAAC,IAAI,CAAC,CAoBf"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core analyzer - orchestrates all checkers and produces unified analysis results
|
|
3
|
+
*/
|
|
4
|
+
import { resolve } from 'path';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { runKnipCheck } from './checkers/knipChecker.js';
|
|
7
|
+
import { runTypeScriptCheck } from './checkers/typescriptChecker.js';
|
|
8
|
+
/**
|
|
9
|
+
* Main entry point: analyze dead code in a project
|
|
10
|
+
*
|
|
11
|
+
* @param options Configuration for the analysis
|
|
12
|
+
* @returns Complete analysis results
|
|
13
|
+
*/
|
|
14
|
+
export async function analyzeDeadCode(options) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
// Normalize and validate project root
|
|
17
|
+
const projectRoot = resolve(options.projectRoot);
|
|
18
|
+
if (!existsSync(projectRoot)) {
|
|
19
|
+
return {
|
|
20
|
+
status: 'failure',
|
|
21
|
+
summary: {
|
|
22
|
+
totalIssues: 0,
|
|
23
|
+
byCategory: {},
|
|
24
|
+
fixableCount: 0,
|
|
25
|
+
errorCount: 0,
|
|
26
|
+
warningCount: 0,
|
|
27
|
+
infoCount: 0,
|
|
28
|
+
},
|
|
29
|
+
findings: [],
|
|
30
|
+
checkResults: [],
|
|
31
|
+
executionTime: Date.now() - startTime,
|
|
32
|
+
error: `Project root does not exist: ${projectRoot}`,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Determine which checks to run
|
|
36
|
+
const checksToRun = getChecksToRun(options.checks);
|
|
37
|
+
if (options.verbose) {
|
|
38
|
+
console.log(`[Dead Code Toolkit] Analyzing: ${projectRoot}`);
|
|
39
|
+
console.log(`[Dead Code Toolkit] Running checks: ${checksToRun.join(', ')}`);
|
|
40
|
+
}
|
|
41
|
+
// Run all checks in parallel
|
|
42
|
+
const checkResults = await Promise.all(checksToRun.map((checkType) => runCheck(checkType, projectRoot, options)));
|
|
43
|
+
// Aggregate results
|
|
44
|
+
const allFindings = checkResults.flatMap((r) => r.findings);
|
|
45
|
+
// Calculate summary
|
|
46
|
+
const summary = calculateSummary(allFindings);
|
|
47
|
+
// Determine overall status
|
|
48
|
+
let status = 'success';
|
|
49
|
+
if (allFindings.some((f) => f.severity === 'error')) {
|
|
50
|
+
status = 'failure';
|
|
51
|
+
}
|
|
52
|
+
else if (allFindings.length > 0) {
|
|
53
|
+
status = 'partial';
|
|
54
|
+
}
|
|
55
|
+
const result = {
|
|
56
|
+
status,
|
|
57
|
+
summary,
|
|
58
|
+
findings: allFindings,
|
|
59
|
+
checkResults,
|
|
60
|
+
executionTime: Date.now() - startTime,
|
|
61
|
+
};
|
|
62
|
+
if (options.verbose) {
|
|
63
|
+
console.log(`[Dead Code Toolkit] Analysis complete: ${allFindings.length} issues found`);
|
|
64
|
+
console.log(`[Dead Code Toolkit] Execution time: ${result.executionTime}ms`);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Run a specific check and handle errors gracefully
|
|
70
|
+
*/
|
|
71
|
+
async function runCheck(checkType, projectRoot, _options) {
|
|
72
|
+
try {
|
|
73
|
+
switch (checkType) {
|
|
74
|
+
case 'knip':
|
|
75
|
+
return await runKnipCheck(projectRoot);
|
|
76
|
+
case 'typescript':
|
|
77
|
+
return await runTypeScriptCheck(projectRoot);
|
|
78
|
+
default:
|
|
79
|
+
return {
|
|
80
|
+
type: checkType,
|
|
81
|
+
status: 'skipped',
|
|
82
|
+
findings: [],
|
|
83
|
+
executionTime: 0,
|
|
84
|
+
error: `Check '${checkType}' not yet implemented`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
90
|
+
return {
|
|
91
|
+
type: checkType,
|
|
92
|
+
status: 'failure',
|
|
93
|
+
findings: [],
|
|
94
|
+
executionTime: 0,
|
|
95
|
+
error: `${checkType} check failed: ${message}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Determine which checks to run
|
|
101
|
+
*/
|
|
102
|
+
function getChecksToRun(specified) {
|
|
103
|
+
if (!specified || specified.length === 0) {
|
|
104
|
+
// Default: run all available checks
|
|
105
|
+
return ['knip', 'typescript'];
|
|
106
|
+
}
|
|
107
|
+
if (specified.includes('all')) {
|
|
108
|
+
return ['knip', 'typescript'];
|
|
109
|
+
}
|
|
110
|
+
return specified.filter((c) => c !== 'all');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Calculate summary statistics from findings
|
|
114
|
+
*/
|
|
115
|
+
function calculateSummary(findings) {
|
|
116
|
+
const byCategory = {};
|
|
117
|
+
let errorCount = 0;
|
|
118
|
+
let warningCount = 0;
|
|
119
|
+
let infoCount = 0;
|
|
120
|
+
let fixableCount = 0;
|
|
121
|
+
for (const finding of findings) {
|
|
122
|
+
// Count by category
|
|
123
|
+
byCategory[finding.category] = (byCategory[finding.category] || 0) + 1;
|
|
124
|
+
// Count by severity
|
|
125
|
+
if (finding.severity === 'error') {
|
|
126
|
+
errorCount++;
|
|
127
|
+
}
|
|
128
|
+
else if (finding.severity === 'warning') {
|
|
129
|
+
warningCount++;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
infoCount++;
|
|
133
|
+
}
|
|
134
|
+
// Count fixable
|
|
135
|
+
if (finding.fixable) {
|
|
136
|
+
fixableCount++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
totalIssues: findings.length,
|
|
141
|
+
byCategory,
|
|
142
|
+
fixableCount,
|
|
143
|
+
errorCount,
|
|
144
|
+
warningCount,
|
|
145
|
+
infoCount,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Apply fixes to a set of findings
|
|
150
|
+
*
|
|
151
|
+
* @param findings The findings to fix
|
|
152
|
+
* @param options Options for fixing
|
|
153
|
+
* @returns Result of fix attempt
|
|
154
|
+
*/
|
|
155
|
+
export async function fixFindings(findings, options = {}) {
|
|
156
|
+
const fixableFindings = findings.filter((f) => f.fixable);
|
|
157
|
+
if (options.verbose) {
|
|
158
|
+
console.log(`[Dead Code Toolkit] Found ${fixableFindings.length} fixable issues`);
|
|
159
|
+
if (options.dryRun) {
|
|
160
|
+
console.log('[Dead Code Toolkit] DRY RUN - no files will be modified');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// TODO: Implement fix logic
|
|
164
|
+
// This would involve:
|
|
165
|
+
// 1. Parsing each file
|
|
166
|
+
// 2. Removing/modifying the problematic code
|
|
167
|
+
// 3. Writing back to disk (unless dryRun)
|
|
168
|
+
// 4. Validating the changes
|
|
169
|
+
if (options.verbose) {
|
|
170
|
+
console.log(`[Dead Code Toolkit] Fix complete`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knip integration for detecting unused exports, files, and dependencies
|
|
3
|
+
* Knip performs symbol-level analysis to find unused code
|
|
4
|
+
*/
|
|
5
|
+
import type { CheckResult } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Run Knip analysis on a project
|
|
8
|
+
* Requires Knip to be installed as a dependency
|
|
9
|
+
*/
|
|
10
|
+
export declare function runKnipCheck(projectRoot: string): Promise<CheckResult>;
|
|
11
|
+
//# sourceMappingURL=knipChecker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knipChecker.d.ts","sourceRoot":"","sources":["../../../src/checkers/knipChecker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,aAAa,CAAC;AAcxD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAqC5E"}
|
|
@@ -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"}
|