@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.
Files changed (94) hide show
  1. package/README.md +356 -0
  2. package/dist/analyzer.d.ts +23 -0
  3. package/dist/analyzer.d.ts.map +1 -0
  4. package/dist/analyzer.js +173 -0
  5. package/dist/analyzer.js.map +1 -0
  6. package/dist/checkers/knipChecker.d.ts +11 -0
  7. package/dist/checkers/knipChecker.d.ts.map +1 -0
  8. package/dist/checkers/knipChecker.js +226 -0
  9. package/dist/checkers/knipChecker.js.map +1 -0
  10. package/dist/checkers/typescriptChecker.d.ts +10 -0
  11. package/dist/checkers/typescriptChecker.d.ts.map +1 -0
  12. package/dist/checkers/typescriptChecker.js +174 -0
  13. package/dist/checkers/typescriptChecker.js.map +1 -0
  14. package/dist/cli/index.d.ts +7 -0
  15. package/dist/cli/index.d.ts.map +1 -0
  16. package/dist/cli/index.js +204 -0
  17. package/dist/cli/index.js.map +1 -0
  18. package/dist/config/detectors.d.ts +29 -0
  19. package/dist/config/detectors.d.ts.map +1 -0
  20. package/dist/config/detectors.js +159 -0
  21. package/dist/config/detectors.js.map +1 -0
  22. package/dist/config/templates.d.ts +76 -0
  23. package/dist/config/templates.d.ts.map +1 -0
  24. package/dist/config/templates.js +191 -0
  25. package/dist/config/templates.js.map +1 -0
  26. package/dist/index.d.ts +13 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +17 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/reporters/jsonReporter.d.ts +68 -0
  31. package/dist/reporters/jsonReporter.d.ts.map +1 -0
  32. package/dist/reporters/jsonReporter.js +161 -0
  33. package/dist/reporters/jsonReporter.js.map +1 -0
  34. package/dist/setup/hookInstaller.d.ts +36 -0
  35. package/dist/setup/hookInstaller.d.ts.map +1 -0
  36. package/dist/setup/hookInstaller.js +196 -0
  37. package/dist/setup/hookInstaller.js.map +1 -0
  38. package/dist/setup/installer.d.ts +10 -0
  39. package/dist/setup/installer.d.ts.map +1 -0
  40. package/dist/setup/installer.js +156 -0
  41. package/dist/setup/installer.js.map +1 -0
  42. package/dist/setup/packageJsonUpdater.d.ts +54 -0
  43. package/dist/setup/packageJsonUpdater.d.ts.map +1 -0
  44. package/dist/setup/packageJsonUpdater.js +129 -0
  45. package/dist/setup/packageJsonUpdater.js.map +1 -0
  46. package/dist/src/analyzer.d.ts +23 -0
  47. package/dist/src/analyzer.d.ts.map +1 -0
  48. package/dist/src/analyzer.js +173 -0
  49. package/dist/src/analyzer.js.map +1 -0
  50. package/dist/src/checkers/knipChecker.d.ts +11 -0
  51. package/dist/src/checkers/knipChecker.d.ts.map +1 -0
  52. package/dist/src/checkers/knipChecker.js +226 -0
  53. package/dist/src/checkers/knipChecker.js.map +1 -0
  54. package/dist/src/checkers/typescriptChecker.d.ts +10 -0
  55. package/dist/src/checkers/typescriptChecker.d.ts.map +1 -0
  56. package/dist/src/checkers/typescriptChecker.js +174 -0
  57. package/dist/src/checkers/typescriptChecker.js.map +1 -0
  58. package/dist/src/config/detectors.d.ts +29 -0
  59. package/dist/src/config/detectors.d.ts.map +1 -0
  60. package/dist/src/config/detectors.js +159 -0
  61. package/dist/src/config/detectors.js.map +1 -0
  62. package/dist/src/config/templates.d.ts +76 -0
  63. package/dist/src/config/templates.d.ts.map +1 -0
  64. package/dist/src/config/templates.js +191 -0
  65. package/dist/src/config/templates.js.map +1 -0
  66. package/dist/src/index.d.ts +13 -0
  67. package/dist/src/index.d.ts.map +1 -0
  68. package/dist/src/index.js +17 -0
  69. package/dist/src/index.js.map +1 -0
  70. package/dist/src/reporters/jsonReporter.d.ts +68 -0
  71. package/dist/src/reporters/jsonReporter.d.ts.map +1 -0
  72. package/dist/src/reporters/jsonReporter.js +161 -0
  73. package/dist/src/reporters/jsonReporter.js.map +1 -0
  74. package/dist/src/setup/hookInstaller.d.ts +36 -0
  75. package/dist/src/setup/hookInstaller.d.ts.map +1 -0
  76. package/dist/src/setup/hookInstaller.js +196 -0
  77. package/dist/src/setup/hookInstaller.js.map +1 -0
  78. package/dist/src/setup/installer.d.ts +10 -0
  79. package/dist/src/setup/installer.d.ts.map +1 -0
  80. package/dist/src/setup/installer.js +156 -0
  81. package/dist/src/setup/installer.js.map +1 -0
  82. package/dist/src/setup/packageJsonUpdater.d.ts +54 -0
  83. package/dist/src/setup/packageJsonUpdater.d.ts.map +1 -0
  84. package/dist/src/setup/packageJsonUpdater.js +129 -0
  85. package/dist/src/setup/packageJsonUpdater.js.map +1 -0
  86. package/dist/src/types.d.ts +177 -0
  87. package/dist/src/types.d.ts.map +1 -0
  88. package/dist/src/types.js +5 -0
  89. package/dist/src/types.js.map +1 -0
  90. package/dist/types.d.ts +177 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +5 -0
  93. package/dist/types.js.map +1 -0
  94. package/package.json +84 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * JSON reporter - formats analysis results as JSON for programmatic consumption
3
+ * Optimized for LLM interpretation
4
+ */
5
+ /**
6
+ * Convert analysis result to JSON report
7
+ */
8
+ export function createJSONReport(result) {
9
+ return {
10
+ version: '1.0',
11
+ timestamp: new Date().toISOString(),
12
+ status: result.status,
13
+ summary: {
14
+ totalIssues: result.summary.totalIssues,
15
+ fixableIssues: result.summary.fixableCount,
16
+ byCategory: result.summary.byCategory,
17
+ bySeverity: {
18
+ errors: result.summary.errorCount,
19
+ warnings: result.summary.warningCount,
20
+ info: result.summary.infoCount,
21
+ },
22
+ executionTimeMs: result.executionTime,
23
+ },
24
+ findings: result.findings.map((f, i) => findingToJSON(f, i)),
25
+ recommendations: generateRecommendations(result),
26
+ checksRun: result.checkResults.map((c) => c.type),
27
+ };
28
+ }
29
+ /**
30
+ * Convert individual finding to JSON format
31
+ */
32
+ function findingToJSON(finding, index) {
33
+ return {
34
+ id: `finding_${index}`,
35
+ category: finding.category,
36
+ severity: finding.severity,
37
+ file: finding.file,
38
+ location: finding.line
39
+ ? {
40
+ line: finding.line,
41
+ column: finding.column,
42
+ }
43
+ : undefined,
44
+ message: finding.message,
45
+ fixable: finding.fixable,
46
+ suggestion: finding.suggestion,
47
+ source: finding.source,
48
+ rule: finding.rule,
49
+ };
50
+ }
51
+ /**
52
+ * Generate actionable recommendations based on findings
53
+ */
54
+ function generateRecommendations(result) {
55
+ const recommendations = [];
56
+ // Count fixable vs unfixable
57
+ const fixable = result.findings.filter((f) => f.fixable).length;
58
+ const unfixable = result.findings.length - fixable;
59
+ // Fixable issues
60
+ if (fixable > 0) {
61
+ recommendations.push(`Run 'npm run dead-code:fix' to automatically fix ${fixable} issue${fixable !== 1 ? 's' : ''}`);
62
+ }
63
+ // Unused exports
64
+ const unusedExports = result.findings.filter((f) => f.category === 'unused-export');
65
+ if (unusedExports.length > 0) {
66
+ recommendations.push(`Review and remove ${unusedExports.length} unused export${unusedExports.length !== 1 ? 's' : ''} from your codebase`);
67
+ }
68
+ // Unused files
69
+ const unusedFiles = result.findings.filter((f) => f.category === 'unused-file');
70
+ if (unusedFiles.length > 0) {
71
+ recommendations.push(`Consider deleting ${unusedFiles.length} unused file${unusedFiles.length !== 1 ? 's' : ''} (manual review recommended)`);
72
+ }
73
+ // Type errors
74
+ const typeErrors = result.findings.filter((f) => f.severity === 'error');
75
+ if (typeErrors.length > 0) {
76
+ recommendations.push(`Fix ${typeErrors.length} type error${typeErrors.length !== 1 ? 's' : ''} to ensure code correctness`);
77
+ }
78
+ // Union/type issues
79
+ const unionIssues = result.findings.filter((f) => f.category === 'union-issue');
80
+ if (unionIssues.length > 0) {
81
+ recommendations.push(`Review ${unionIssues.length} union type issue${unionIssues.length !== 1 ? 's' : ''} for type safety`);
82
+ }
83
+ // General suggestions
84
+ if (unfixable > 0 && fixable === 0) {
85
+ recommendations.push(`Manually review and fix the ${unfixable} remaining issue${unfixable !== 1 ? 's' : ''}`);
86
+ }
87
+ if (result.findings.length === 0) {
88
+ recommendations.push('✓ No dead code detected! Your codebase is clean.');
89
+ }
90
+ return recommendations;
91
+ }
92
+ /**
93
+ * Format JSON report as indented string for display
94
+ */
95
+ export function formatJSONReport(report) {
96
+ return JSON.stringify(report, null, 2);
97
+ }
98
+ /**
99
+ * Format JSON report as compact string for logging
100
+ */
101
+ export function formatJSONReportCompact(report) {
102
+ return JSON.stringify(report);
103
+ }
104
+ export function createLLMSummary(result) {
105
+ const topIssues = [];
106
+ const categoryMap = new Map();
107
+ for (const finding of result.findings) {
108
+ const key = finding.category;
109
+ const current = categoryMap.get(key) || { count: 0, severities: new Set(), fixable: 0 };
110
+ current.count++;
111
+ current.severities.add(finding.severity);
112
+ if (finding.fixable)
113
+ current.fixable++;
114
+ categoryMap.set(key, current);
115
+ }
116
+ // Convert to top issues sorted by count
117
+ for (const [type, data] of categoryMap) {
118
+ const severity = Array.from(data.severities).sort()[0] || 'info';
119
+ topIssues.push({
120
+ count: data.count,
121
+ type,
122
+ severity,
123
+ fixable: data.fixable,
124
+ });
125
+ }
126
+ topIssues.sort((a, b) => b.count - a.count);
127
+ // Generate readable summary
128
+ let status = 'clean';
129
+ if (result.findings.length === 0) {
130
+ status = 'success';
131
+ }
132
+ else if (result.findings.some((f) => f.severity === 'error')) {
133
+ status = 'failure';
134
+ }
135
+ else if (result.findings.length > 0) {
136
+ status = 'partial';
137
+ }
138
+ const summary = generateSummaryText(result, topIssues);
139
+ return {
140
+ status,
141
+ totalIssues: result.findings.length,
142
+ summary,
143
+ topIssues,
144
+ actionItems: generateRecommendations(result),
145
+ };
146
+ }
147
+ function generateSummaryText(result, topIssues) {
148
+ if (result.findings.length === 0) {
149
+ return 'Your codebase is clean with no dead code detected.';
150
+ }
151
+ const parts = [`Found ${result.findings.length} issues:`];
152
+ for (const issue of topIssues.slice(0, 3)) {
153
+ const fixStr = issue.fixable > 0 ? ` (${issue.fixable} auto-fixable)` : '';
154
+ parts.push(` • ${issue.count}x ${issue.type}${fixStr}`);
155
+ }
156
+ if (topIssues.length > 3) {
157
+ parts.push(` • ... and ${topIssues.length - 3} more categories`);
158
+ }
159
+ return parts.join('\n');
160
+ }
161
+ //# sourceMappingURL=jsonReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonReporter.js","sourceRoot":"","sources":["../../src/reporters/jsonReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Git hooks installer
3
+ * Sets up Husky and pre-commit hooks
4
+ */
5
+ /**
6
+ * Check if Husky is installed
7
+ */
8
+ export declare function isHuskyInstalled(projectRoot: string): boolean;
9
+ /**
10
+ * Initialize Husky in a project
11
+ */
12
+ export declare function initializeHusky(projectRoot: string): boolean;
13
+ /**
14
+ * Create .husky directory
15
+ */
16
+ export declare function createHuskyDirectory(projectRoot: string): string;
17
+ /**
18
+ * Install pre-commit hook
19
+ */
20
+ export declare function installPreCommitHook(projectRoot: string): boolean;
21
+ /**
22
+ * Install commit-msg hook for conventional commits
23
+ */
24
+ export declare function installCommitMsgHook(projectRoot: string): boolean;
25
+ /**
26
+ * Create commitlint config
27
+ */
28
+ export declare function createCommitLintConfig(projectRoot: string): boolean;
29
+ /**
30
+ * Full hook setup
31
+ */
32
+ export declare function setupAllHooks(projectRoot: string): {
33
+ success: boolean;
34
+ errors: string[];
35
+ };
36
+ //# sourceMappingURL=hookInstaller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hookInstaller.d.ts","sourceRoot":"","sources":["../../src/setup/hookInstaller.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAgB7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAuB5D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA8BjE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA8BjE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA8CnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CA0BA"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Git hooks installer
3
+ * Sets up Husky and pre-commit hooks
4
+ */
5
+ import { existsSync, mkdirSync, writeFileSync, chmodSync, readFileSync } from 'fs';
6
+ import { execSync } from 'child_process';
7
+ import { resolve } from 'path';
8
+ import { generatePreCommitHook } from '../config/templates.js';
9
+ /**
10
+ * Check if Husky is installed
11
+ */
12
+ export function isHuskyInstalled(projectRoot) {
13
+ try {
14
+ // Check if husky is in package.json or node_modules
15
+ const packageJsonPath = resolve(projectRoot, 'package.json');
16
+ if (existsSync(packageJsonPath)) {
17
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
18
+ return !!(packageJson.devDependencies?.husky ||
19
+ packageJson.dependencies?.husky ||
20
+ existsSync(resolve(projectRoot, 'node_modules/husky')));
21
+ }
22
+ return false;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ /**
29
+ * Initialize Husky in a project
30
+ */
31
+ export function initializeHusky(projectRoot) {
32
+ try {
33
+ if (!isHuskyInstalled(projectRoot)) {
34
+ console.log('[Hook Installer] Installing Husky...');
35
+ execSync('npx husky install', {
36
+ cwd: projectRoot,
37
+ stdio: 'inherit',
38
+ });
39
+ }
40
+ else {
41
+ console.log('[Hook Installer] Husky already installed');
42
+ // Run husky install to ensure hooks are set up
43
+ execSync('npx husky install', {
44
+ cwd: projectRoot,
45
+ stdio: 'ignore',
46
+ });
47
+ }
48
+ return true;
49
+ }
50
+ catch (error) {
51
+ console.error(`[Hook Installer] Failed to initialize Husky: ${error instanceof Error ? error.message : String(error)}`);
52
+ return false;
53
+ }
54
+ }
55
+ /**
56
+ * Create .husky directory
57
+ */
58
+ export function createHuskyDirectory(projectRoot) {
59
+ const huskyDir = resolve(projectRoot, '.husky');
60
+ if (!existsSync(huskyDir)) {
61
+ mkdirSync(huskyDir, { recursive: true });
62
+ }
63
+ return huskyDir;
64
+ }
65
+ /**
66
+ * Install pre-commit hook
67
+ */
68
+ export function installPreCommitHook(projectRoot) {
69
+ try {
70
+ const huskyDir = createHuskyDirectory(projectRoot);
71
+ const preCommitPath = resolve(huskyDir, 'pre-commit');
72
+ // Check if hook already exists
73
+ let existingContent = '';
74
+ if (existsSync(preCommitPath)) {
75
+ existingContent = readFileSync(preCommitPath, 'utf-8');
76
+ }
77
+ // Generate new hook content
78
+ const newContent = generatePreCommitHook();
79
+ // Only write if different
80
+ if (existingContent !== newContent) {
81
+ writeFileSync(preCommitPath, newContent);
82
+ chmodSync(preCommitPath, 0o755); // Make executable
83
+ console.log('[Hook Installer] Created .husky/pre-commit');
84
+ }
85
+ else {
86
+ console.log('[Hook Installer] .husky/pre-commit already up to date');
87
+ }
88
+ return true;
89
+ }
90
+ catch (error) {
91
+ console.error(`[Hook Installer] Failed to install pre-commit hook: ${error instanceof Error ? error.message : String(error)}`);
92
+ return false;
93
+ }
94
+ }
95
+ /**
96
+ * Install commit-msg hook for conventional commits
97
+ */
98
+ export function installCommitMsgHook(projectRoot) {
99
+ try {
100
+ const huskyDir = createHuskyDirectory(projectRoot);
101
+ const commitMsgPath = resolve(huskyDir, 'commit-msg');
102
+ const content = `#!/bin/sh
103
+ # Commit message validation via commitlint
104
+ npx --no-install commitlint --edit "$1"`;
105
+ // Check if exists and is the same
106
+ let existingContent = '';
107
+ if (existsSync(commitMsgPath)) {
108
+ existingContent = readFileSync(commitMsgPath, 'utf-8');
109
+ }
110
+ if (existingContent !== content) {
111
+ writeFileSync(commitMsgPath, content);
112
+ chmodSync(commitMsgPath, 0o755);
113
+ console.log('[Hook Installer] Created .husky/commit-msg');
114
+ }
115
+ else {
116
+ console.log('[Hook Installer] .husky/commit-msg already up to date');
117
+ }
118
+ return true;
119
+ }
120
+ catch (error) {
121
+ console.error(`[Hook Installer] Failed to install commit-msg hook: ${error instanceof Error ? error.message : String(error)}`);
122
+ return false;
123
+ }
124
+ }
125
+ /**
126
+ * Create commitlint config
127
+ */
128
+ export function createCommitLintConfig(projectRoot) {
129
+ try {
130
+ const configPath = resolve(projectRoot, 'commitlint.config.js');
131
+ // Check if already exists
132
+ if (existsSync(configPath)) {
133
+ console.log('[Hook Installer] commitlint.config.js already exists');
134
+ return true;
135
+ }
136
+ const content = `module.exports = {
137
+ extends: ['@commitlint/config-conventional'],
138
+ rules: {
139
+ 'type-enum': [
140
+ 2,
141
+ 'always',
142
+ [
143
+ 'feat',
144
+ 'fix',
145
+ 'refactor',
146
+ 'perf',
147
+ 'test',
148
+ 'docs',
149
+ 'chore',
150
+ 'style',
151
+ 'ci',
152
+ 'revert',
153
+ ],
154
+ ],
155
+ 'type-case': [2, 'always', 'lowerCase'],
156
+ 'subject-case': [2, 'always', 'lowerCase'],
157
+ 'subject-full-stop': [2, 'never', '.'],
158
+ 'subject-empty': [2, 'never'],
159
+ 'header-max-length': [2, 'always', 72],
160
+ },
161
+ };`;
162
+ writeFileSync(configPath, content);
163
+ console.log('[Hook Installer] Created commitlint.config.js');
164
+ return true;
165
+ }
166
+ catch (error) {
167
+ console.error(`[Hook Installer] Failed to create commitlint config: ${error instanceof Error ? error.message : String(error)}`);
168
+ return false;
169
+ }
170
+ }
171
+ /**
172
+ * Full hook setup
173
+ */
174
+ export function setupAllHooks(projectRoot) {
175
+ const errors = [];
176
+ // Initialize Husky
177
+ if (!initializeHusky(projectRoot)) {
178
+ errors.push('Failed to initialize Husky');
179
+ }
180
+ // Install hooks
181
+ if (!installPreCommitHook(projectRoot)) {
182
+ errors.push('Failed to install pre-commit hook');
183
+ }
184
+ if (!installCommitMsgHook(projectRoot)) {
185
+ errors.push('Failed to install commit-msg hook');
186
+ }
187
+ // Create config
188
+ if (!createCommitLintConfig(projectRoot)) {
189
+ errors.push('Failed to create commitlint config');
190
+ }
191
+ return {
192
+ success: errors.length === 0,
193
+ errors,
194
+ };
195
+ }
196
+ //# sourceMappingURL=hookInstaller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hookInstaller.js","sourceRoot":"","sources":["../../src/setup/hookInstaller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Main setup orchestrator
3
+ * Coordinates all setup tasks (configs, dependencies, hooks)
4
+ */
5
+ import type { SetupOptions, SetupResult } from '../types.js';
6
+ /**
7
+ * Main setup function
8
+ */
9
+ export declare function setupProject(options: SetupOptions): Promise<SetupResult>;
10
+ //# sourceMappingURL=installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/setup/installer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU7D;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2E9E"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Main setup orchestrator
3
+ * Coordinates all setup tasks (configs, dependencies, hooks)
4
+ */
5
+ import { existsSync, writeFileSync } from 'fs';
6
+ import { resolve } from 'path';
7
+ import { execSync } from 'child_process';
8
+ import { detectProjectConfig } from '../config/detectors.js';
9
+ import { generateKnipConfigJSON, generateTypeCoverageConfigJSON, generateLintStagedConfigJSON, } from '../config/templates.js';
10
+ import { updatePackageJson, formatDependenciesForInstall } from './packageJsonUpdater.js';
11
+ import { setupAllHooks } from './hookInstaller.js';
12
+ /**
13
+ * Main setup function
14
+ */
15
+ export async function setupProject(options) {
16
+ const result = {
17
+ status: 'success',
18
+ filesCreated: [],
19
+ scriptsAdded: [],
20
+ dependenciesInstalled: [],
21
+ nextSteps: [],
22
+ errors: [],
23
+ };
24
+ try {
25
+ // Validate project root
26
+ if (!existsSync(options.projectRoot)) {
27
+ throw new Error(`Project root does not exist: ${options.projectRoot}`);
28
+ }
29
+ if (options.verbose) {
30
+ console.log(`[Setup] Starting setup in: ${options.projectRoot}`);
31
+ }
32
+ // Detect project configuration
33
+ const projectConfig = detectProjectConfig(options.projectRoot);
34
+ if (options.verbose) {
35
+ console.log(`[Setup] Detected project type: ${projectConfig.type}`);
36
+ }
37
+ // Step 1: Create configuration files
38
+ const configFiles = await createConfigFiles(options.projectRoot, projectConfig);
39
+ result.filesCreated.push(...configFiles);
40
+ // Step 2: Update package.json
41
+ const packageJsonUpdate = updatePackageJson(options.projectRoot, {
42
+ addScripts: true,
43
+ installDependencies: options.installDependencies !== false,
44
+ });
45
+ result.scriptsAdded.push(...packageJsonUpdate.scriptsAdded);
46
+ if (options.verbose && packageJsonUpdate.scriptsAdded.length > 0) {
47
+ console.log(`[Setup] Added ${packageJsonUpdate.scriptsAdded.length} npm scripts`);
48
+ }
49
+ // Step 3: Install dependencies
50
+ if (options.installDependencies !== false) {
51
+ const depsToInstall = packageJsonUpdate.dependenciesToInstall;
52
+ if (Object.keys(depsToInstall).length > 0) {
53
+ await installDependencies(options.projectRoot, depsToInstall, options.verbose);
54
+ result.dependenciesInstalled.push(...Object.keys(depsToInstall));
55
+ }
56
+ }
57
+ // Step 4: Setup Git hooks
58
+ if (options.setupHooks !== false) {
59
+ const hookResult = setupAllHooks(options.projectRoot);
60
+ if (!hookResult.success) {
61
+ result.errors?.push(...hookResult.errors);
62
+ result.status = 'partial';
63
+ }
64
+ // Mark hooks as part of setup
65
+ result.filesCreated.push('.husky/pre-commit', '.husky/commit-msg', 'commitlint.config.js');
66
+ }
67
+ // Generate next steps
68
+ result.nextSteps = generateNextSteps(projectConfig, result);
69
+ if (options.verbose) {
70
+ console.log(`[Setup] Setup complete! Status: ${result.status}`);
71
+ }
72
+ return result;
73
+ }
74
+ catch (error) {
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ result.status = 'failure';
77
+ result.errors?.push(message);
78
+ return result;
79
+ }
80
+ }
81
+ /**
82
+ * Create configuration files
83
+ */
84
+ async function createConfigFiles(projectRoot, projectConfig) {
85
+ const filesCreated = [];
86
+ // Check for existing configs
87
+ if (projectConfig.existingConfigs.knip) {
88
+ console.log('[Setup] knip.json already exists, skipping');
89
+ }
90
+ else {
91
+ // Create knip.json
92
+ const knipConfig = generateKnipConfigJSON(projectConfig);
93
+ const knipPath = resolve(projectRoot, 'knip.json');
94
+ writeFileSync(knipPath, knipConfig);
95
+ filesCreated.push('knip.json');
96
+ console.log('[Setup] Created knip.json');
97
+ }
98
+ // Create typecoveragerc.json (always overwrite with updated config)
99
+ const typeCoverageConfig = generateTypeCoverageConfigJSON(projectConfig);
100
+ const typeCoveragePath = resolve(projectRoot, 'typecoveragerc.json');
101
+ writeFileSync(typeCoveragePath, typeCoverageConfig);
102
+ filesCreated.push('typecoveragerc.json');
103
+ console.log('[Setup] Created typecoveragerc.json');
104
+ // Create .lintstagedrc.json (always overwrite)
105
+ const lintStagedConfig = generateLintStagedConfigJSON();
106
+ const lintStagedPath = resolve(projectRoot, '.lintstagedrc.json');
107
+ writeFileSync(lintStagedPath, lintStagedConfig);
108
+ filesCreated.push('.lintstagedrc.json');
109
+ console.log('[Setup] Created .lintstagedrc.json');
110
+ // Note: ESLint config is not auto-created as it may conflict with existing configs
111
+ if (!projectConfig.existingConfigs.eslint) {
112
+ console.log('[Setup] ⚠️ ESLint config not found. Add these rules to your eslint.config.js:');
113
+ console.log(' @typescript-eslint/no-redundant-type-constituents: warn');
114
+ console.log(' @typescript-eslint/no-unused-vars: [warn, {argsIgnorePattern: "^_"}]');
115
+ }
116
+ return filesCreated;
117
+ }
118
+ /**
119
+ * Install npm dependencies
120
+ */
121
+ async function installDependencies(projectRoot, dependencies, verbose) {
122
+ const deps = formatDependenciesForInstall(dependencies);
123
+ if (verbose) {
124
+ console.log(`[Setup] Installing ${deps.length} dependencies...`);
125
+ }
126
+ try {
127
+ execSync(`npm install --save-dev ${deps.join(' ')}`, {
128
+ cwd: projectRoot,
129
+ stdio: verbose ? 'inherit' : 'ignore',
130
+ });
131
+ if (verbose) {
132
+ console.log(`[Setup] Dependencies installed`);
133
+ }
134
+ }
135
+ catch (error) {
136
+ throw new Error(`Failed to install dependencies: ${error instanceof Error ? error.message : String(error)}`);
137
+ }
138
+ }
139
+ /**
140
+ * Generate next steps for user
141
+ */
142
+ function generateNextSteps(projectConfig, result) {
143
+ const steps = [];
144
+ steps.push('Run: npm run dead-code to check for dead code');
145
+ steps.push('Review findings and consider running: npm run dead-code:fix');
146
+ if (result.scriptsAdded.includes('verify')) {
147
+ steps.push('Use: npm run verify to run all quality checks');
148
+ }
149
+ if (!projectConfig.existingConfigs.eslint) {
150
+ steps.push('⚠️ Update your ESLint config to include dead code detection rules');
151
+ }
152
+ steps.push('Configure pre-commit hooks: git commit -m "message"');
153
+ steps.push('Read: npx dead-code-toolkit --help for more commands');
154
+ return steps;
155
+ }
156
+ //# sourceMappingURL=installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/setup/installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * package.json updater
3
+ * Safely updates package.json with new scripts and dependencies
4
+ */
5
+ interface PackageJson {
6
+ name?: string;
7
+ version?: string;
8
+ scripts?: Record<string, string>;
9
+ dependencies?: Record<string, string>;
10
+ devDependencies?: Record<string, string>;
11
+ [key: string]: unknown;
12
+ }
13
+ /**
14
+ * Read package.json from project
15
+ */
16
+ export declare function readPackageJson(projectRoot: string): PackageJson;
17
+ /**
18
+ * Write package.json back to disk
19
+ */
20
+ export declare function writePackageJson(projectRoot: string, packageJson: PackageJson): void;
21
+ /**
22
+ * Add scripts to package.json
23
+ * Returns list of added scripts
24
+ */
25
+ export declare function addScripts(packageJson: PackageJson): string[];
26
+ /**
27
+ * Get recommended dev dependencies
28
+ */
29
+ export declare function getRecommendedDevDependencies(): Record<string, string>;
30
+ /**
31
+ * Check which dev dependencies are already installed
32
+ */
33
+ export declare function getInstalledDevDependencies(packageJson: PackageJson): Record<string, string>;
34
+ /**
35
+ * Get missing dev dependencies that need to be installed
36
+ */
37
+ export declare function getMissingDevDependencies(packageJson: PackageJson): Record<string, string>;
38
+ /**
39
+ * Format dependencies for npm install command
40
+ */
41
+ export declare function formatDependenciesForInstall(deps: Record<string, string>): string[];
42
+ /**
43
+ * Update package.json with all necessary changes
44
+ */
45
+ export declare function updatePackageJson(projectRoot: string, options?: {
46
+ addScripts?: boolean;
47
+ installDependencies?: boolean;
48
+ }): {
49
+ scriptsAdded: string[];
50
+ dependenciesToInstall: Record<string, string>;
51
+ updated: boolean;
52
+ };
53
+ export {};
54
+ //# sourceMappingURL=packageJsonUpdater.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packageJsonUpdater.d.ts","sourceRoot":"","sources":["../../src/setup/packageJsonUpdater.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAWhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,CAUpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,EAAE,CAgB7D;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUtE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY5F;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY1F;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAEnF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAO,GACpE;IACD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,EAAE,OAAO,CAAC;CAClB,CA8BA"}