vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739
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 +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Size Analyzer
|
|
3
|
+
* Utility to scan codebase and identify files exceeding the 555-line constitutional limit
|
|
4
|
+
* Part of specs/010-555-max-file-size implementation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Size categories based on line count
|
|
12
|
+
*/
|
|
13
|
+
const SIZE_CATEGORIES = {
|
|
14
|
+
SMALL: { max: 200, label: 'SMALL' },
|
|
15
|
+
MEDIUM: { max: 400, label: 'MEDIUM' },
|
|
16
|
+
LARGE: { max: 555, label: 'LARGE' },
|
|
17
|
+
XLARGE: { max: Infinity, label: 'XLARGE' }
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Refactoring priority based on how far over the limit
|
|
22
|
+
*/
|
|
23
|
+
const REFACTORING_PRIORITIES = {
|
|
24
|
+
LOW: { threshold: 0, label: 'LOW' }, // Under limit
|
|
25
|
+
MEDIUM: { threshold: 556, label: 'MEDIUM' }, // 1-200 over limit
|
|
26
|
+
HIGH: { threshold: 755, label: 'HIGH' }, // 201-500 over limit
|
|
27
|
+
CRITICAL: { threshold: 1055, label: 'CRITICAL' } // 500+ over limit
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Default exclusion patterns
|
|
32
|
+
*/
|
|
33
|
+
const DEFAULT_EXCLUSIONS = [
|
|
34
|
+
'node_modules',
|
|
35
|
+
'.git',
|
|
36
|
+
'dist',
|
|
37
|
+
'build',
|
|
38
|
+
'coverage',
|
|
39
|
+
'.next',
|
|
40
|
+
'.cache',
|
|
41
|
+
'vendor',
|
|
42
|
+
'third-party',
|
|
43
|
+
'external'
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Count lines in a file
|
|
48
|
+
* @param {string} filePath - Path to file
|
|
49
|
+
* @returns {number} Line count
|
|
50
|
+
*/
|
|
51
|
+
function countLines(filePath) {
|
|
52
|
+
try {
|
|
53
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
54
|
+
return content.split('\n').length;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Determine size category for a file
|
|
62
|
+
* @param {number} lineCount - Number of lines in file
|
|
63
|
+
* @returns {string} Size category label
|
|
64
|
+
*/
|
|
65
|
+
function getSizeCategory(lineCount) {
|
|
66
|
+
if (lineCount <= SIZE_CATEGORIES.SMALL.max) return SIZE_CATEGORIES.SMALL.label;
|
|
67
|
+
if (lineCount <= SIZE_CATEGORIES.MEDIUM.max) return SIZE_CATEGORIES.MEDIUM.label;
|
|
68
|
+
if (lineCount <= SIZE_CATEGORIES.LARGE.max) return SIZE_CATEGORIES.LARGE.label;
|
|
69
|
+
return SIZE_CATEGORIES.XLARGE.label;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Determine refactoring priority for a file
|
|
74
|
+
* @param {number} lineCount - Number of lines in file
|
|
75
|
+
* @returns {string} Priority label
|
|
76
|
+
*/
|
|
77
|
+
function getRefactoringPriority(lineCount) {
|
|
78
|
+
if (lineCount <= SIZE_CATEGORIES.LARGE.max) return REFACTORING_PRIORITIES.LOW.label;
|
|
79
|
+
if (lineCount < REFACTORING_PRIORITIES.HIGH.threshold) return REFACTORING_PRIORITIES.MEDIUM.label;
|
|
80
|
+
if (lineCount < REFACTORING_PRIORITIES.CRITICAL.threshold) return REFACTORING_PRIORITIES.HIGH.label;
|
|
81
|
+
return REFACTORING_PRIORITIES.CRITICAL.label;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Check if a path should be excluded
|
|
86
|
+
* @param {string} filePath - Path to check
|
|
87
|
+
* @param {string[]} exclusions - Array of exclusion patterns
|
|
88
|
+
* @returns {boolean} True if should be excluded
|
|
89
|
+
*/
|
|
90
|
+
function shouldExclude(filePath, exclusions) {
|
|
91
|
+
return exclusions.some(pattern => filePath.includes(pattern));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Recursively scan directory for source files
|
|
96
|
+
* @param {string} dirPath - Directory to scan
|
|
97
|
+
* @param {string[]} extensions - File extensions to include
|
|
98
|
+
* @param {string[]} exclusions - Patterns to exclude
|
|
99
|
+
* @returns {string[]} Array of file paths
|
|
100
|
+
*/
|
|
101
|
+
function scanDirectory(dirPath, extensions = ['.js', '.jsx', '.ts', '.tsx'], exclusions = DEFAULT_EXCLUSIONS) {
|
|
102
|
+
const files = [];
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
106
|
+
|
|
107
|
+
for (const entry of entries) {
|
|
108
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
109
|
+
|
|
110
|
+
if (shouldExclude(fullPath, exclusions)) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (entry.isDirectory()) {
|
|
115
|
+
files.push(...scanDirectory(fullPath, extensions, exclusions));
|
|
116
|
+
} else if (entry.isFile()) {
|
|
117
|
+
const ext = path.extname(entry.name);
|
|
118
|
+
if (extensions.includes(ext)) {
|
|
119
|
+
files.push(fullPath);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
// Skip directories we can't read
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return files;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Analyze a single file
|
|
132
|
+
* @param {string} filePath - Path to file
|
|
133
|
+
* @param {string} basePath - Base path for relative path calculation
|
|
134
|
+
* @returns {Object} File analysis object
|
|
135
|
+
*/
|
|
136
|
+
function analyzeFile(filePath, basePath = process.cwd()) {
|
|
137
|
+
const lineCount = countLines(filePath);
|
|
138
|
+
const relativePath = path.relative(basePath, filePath);
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
filePath: relativePath,
|
|
142
|
+
absolutePath: filePath,
|
|
143
|
+
lineCount,
|
|
144
|
+
sizeCategory: getSizeCategory(lineCount),
|
|
145
|
+
refactoringPriority: getRefactoringPriority(lineCount),
|
|
146
|
+
exceedsLimit: lineCount > SIZE_CATEGORIES.LARGE.max,
|
|
147
|
+
overLimit: Math.max(0, lineCount - SIZE_CATEGORIES.LARGE.max)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Analyze all files in a directory
|
|
153
|
+
* @param {string} dirPath - Directory to analyze
|
|
154
|
+
* @param {Object} options - Analysis options
|
|
155
|
+
* @returns {Object} Analysis results
|
|
156
|
+
*/
|
|
157
|
+
function analyzeDirectory(dirPath, options = {}) {
|
|
158
|
+
const {
|
|
159
|
+
extensions = ['.js', '.jsx', '.ts', '.tsx'],
|
|
160
|
+
exclusions = DEFAULT_EXCLUSIONS,
|
|
161
|
+
sortBy = 'lineCount'
|
|
162
|
+
} = options;
|
|
163
|
+
|
|
164
|
+
const files = scanDirectory(dirPath, extensions, exclusions);
|
|
165
|
+
const analyses = files.map(f => analyzeFile(f, dirPath));
|
|
166
|
+
|
|
167
|
+
// Sort by specified field (default: lineCount descending)
|
|
168
|
+
analyses.sort((a, b) => {
|
|
169
|
+
if (sortBy === 'lineCount') {
|
|
170
|
+
return b.lineCount - a.lineCount;
|
|
171
|
+
}
|
|
172
|
+
return a[sortBy] > b[sortBy] ? 1 : -1;
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Calculate statistics
|
|
176
|
+
const totalFiles = analyses.length;
|
|
177
|
+
const violations = analyses.filter(a => a.exceedsLimit);
|
|
178
|
+
const compliantFiles = totalFiles - violations.length;
|
|
179
|
+
|
|
180
|
+
const byCategory = {
|
|
181
|
+
SMALL: analyses.filter(a => a.sizeCategory === 'SMALL').length,
|
|
182
|
+
MEDIUM: analyses.filter(a => a.sizeCategory === 'MEDIUM').length,
|
|
183
|
+
LARGE: analyses.filter(a => a.sizeCategory === 'LARGE').length,
|
|
184
|
+
XLARGE: analyses.filter(a => a.sizeCategory === 'XLARGE').length
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const byPriority = {
|
|
188
|
+
LOW: analyses.filter(a => a.refactoringPriority === 'LOW').length,
|
|
189
|
+
MEDIUM: analyses.filter(a => a.refactoringPriority === 'MEDIUM').length,
|
|
190
|
+
HIGH: analyses.filter(a => a.refactoringPriority === 'HIGH').length,
|
|
191
|
+
CRITICAL: analyses.filter(a => a.refactoringPriority === 'CRITICAL').length
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
totalFiles,
|
|
196
|
+
compliantFiles,
|
|
197
|
+
violations: violations.length,
|
|
198
|
+
compliancePercentage: totalFiles > 0 ? (compliantFiles / totalFiles * 100).toFixed(2) : 100,
|
|
199
|
+
byCategory,
|
|
200
|
+
byPriority,
|
|
201
|
+
files: analyses,
|
|
202
|
+
violatingFiles: violations
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Generate a human-readable report
|
|
208
|
+
* @param {Object} analysis - Analysis results from analyzeDirectory
|
|
209
|
+
* @returns {string} Formatted report
|
|
210
|
+
*/
|
|
211
|
+
function generateReport(analysis) {
|
|
212
|
+
const lines = [];
|
|
213
|
+
|
|
214
|
+
lines.push('='.repeat(80));
|
|
215
|
+
lines.push('FILE SIZE COMPLIANCE REPORT');
|
|
216
|
+
lines.push('Constitutional Limit: 555 lines per file');
|
|
217
|
+
lines.push('='.repeat(80));
|
|
218
|
+
lines.push('');
|
|
219
|
+
|
|
220
|
+
lines.push('SUMMARY');
|
|
221
|
+
lines.push('-'.repeat(80));
|
|
222
|
+
lines.push(`Total Files Scanned: ${analysis.totalFiles}`);
|
|
223
|
+
lines.push(`Compliant Files: ${analysis.compliantFiles}`);
|
|
224
|
+
lines.push(`Violations: ${analysis.violations}`);
|
|
225
|
+
lines.push(`Compliance Rate: ${analysis.compliancePercentage}%`);
|
|
226
|
+
lines.push('');
|
|
227
|
+
|
|
228
|
+
lines.push('BY SIZE CATEGORY');
|
|
229
|
+
lines.push('-'.repeat(80));
|
|
230
|
+
lines.push(`SMALL (≤200 lines): ${analysis.byCategory.SMALL}`);
|
|
231
|
+
lines.push(`MEDIUM (201-400): ${analysis.byCategory.MEDIUM}`);
|
|
232
|
+
lines.push(`LARGE (401-555): ${analysis.byCategory.LARGE}`);
|
|
233
|
+
lines.push(`XLARGE (>555): ${analysis.byCategory.XLARGE} ⚠️ VIOLATIONS`);
|
|
234
|
+
lines.push('');
|
|
235
|
+
|
|
236
|
+
lines.push('REFACTORING PRIORITY');
|
|
237
|
+
lines.push('-'.repeat(80));
|
|
238
|
+
lines.push(`LOW (compliant): ${analysis.byPriority.LOW}`);
|
|
239
|
+
lines.push(`MEDIUM (1-200 over): ${analysis.byPriority.MEDIUM}`);
|
|
240
|
+
lines.push(`HIGH (201-500 over): ${analysis.byPriority.HIGH}`);
|
|
241
|
+
lines.push(`CRITICAL (500+ over): ${analysis.byPriority.CRITICAL}`);
|
|
242
|
+
lines.push('');
|
|
243
|
+
|
|
244
|
+
if (analysis.violations > 0) {
|
|
245
|
+
lines.push('VIOLATIONS (files exceeding 555-line limit)');
|
|
246
|
+
lines.push('-'.repeat(80));
|
|
247
|
+
|
|
248
|
+
analysis.violatingFiles.forEach((file, idx) => {
|
|
249
|
+
const priority = file.refactoringPriority;
|
|
250
|
+
const icon = priority === 'CRITICAL' ? '🔴' : priority === 'HIGH' ? '🟠' : '🟡';
|
|
251
|
+
lines.push(`${icon} [${priority}] ${file.filePath}`);
|
|
252
|
+
lines.push(` ${file.lineCount} lines (${file.overLimit} over limit)`);
|
|
253
|
+
});
|
|
254
|
+
lines.push('');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
lines.push('='.repeat(80));
|
|
258
|
+
|
|
259
|
+
return lines.join('\n');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
module.exports = {
|
|
263
|
+
countLines,
|
|
264
|
+
getSizeCategory,
|
|
265
|
+
getRefactoringPriority,
|
|
266
|
+
analyzeFile,
|
|
267
|
+
analyzeDirectory,
|
|
268
|
+
generateReport,
|
|
269
|
+
SIZE_CATEGORIES,
|
|
270
|
+
REFACTORING_PRIORITIES,
|
|
271
|
+
DEFAULT_EXCLUSIONS
|
|
272
|
+
};
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import Statement Updater Utility
|
|
3
|
+
*
|
|
4
|
+
* Handles updating import statements when files are refactored or moved.
|
|
5
|
+
* Supports ES6 imports, CommonJS requires, and dynamic imports.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { parse } = require('@babel/parser');
|
|
11
|
+
const traverse = require('@babel/traverse').default;
|
|
12
|
+
|
|
13
|
+
class ImportUpdater {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = {
|
|
16
|
+
dryRun: options.dryRun || false,
|
|
17
|
+
verbose: options.verbose || false,
|
|
18
|
+
backup: options.backup !== false,
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Update import statements in a file based on a mapping of old to new paths
|
|
25
|
+
*/
|
|
26
|
+
updateImports(filePath, importMappings) {
|
|
27
|
+
if (!fs.existsSync(filePath)) {
|
|
28
|
+
throw new Error(`File not found: ${filePath}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
32
|
+
const updatedContent = this._updateImportStatements(content, importMappings);
|
|
33
|
+
|
|
34
|
+
if (updatedContent !== content) {
|
|
35
|
+
if (this.options.backup) {
|
|
36
|
+
this._createBackup(filePath, content);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!this.options.dryRun) {
|
|
40
|
+
fs.writeFileSync(filePath, updatedContent);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (this.options.verbose) {
|
|
44
|
+
console.log(`Updated imports in: ${filePath}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return updatedContent !== content;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Update imports across multiple files
|
|
53
|
+
*/
|
|
54
|
+
updateImportsBatch(filePaths, importMappings) {
|
|
55
|
+
const results = {
|
|
56
|
+
updated: [],
|
|
57
|
+
failed: [],
|
|
58
|
+
skipped: []
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
for (const filePath of filePaths) {
|
|
62
|
+
try {
|
|
63
|
+
const updated = this.updateImports(filePath, importMappings);
|
|
64
|
+
if (updated) {
|
|
65
|
+
results.updated.push(filePath);
|
|
66
|
+
} else {
|
|
67
|
+
results.skipped.push(filePath);
|
|
68
|
+
}
|
|
69
|
+
} catch (error) {
|
|
70
|
+
results.failed.push({ filePath, error: error.message });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Extract all import statements from a file
|
|
79
|
+
*/
|
|
80
|
+
extractImports(filePath) {
|
|
81
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
82
|
+
const imports = [];
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const ast = parse(content, {
|
|
86
|
+
sourceType: 'module',
|
|
87
|
+
plugins: ['jsx', 'typescript', 'decorators-legacy']
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
traverse(ast, {
|
|
91
|
+
ImportDeclaration: (path) => {
|
|
92
|
+
imports.push({
|
|
93
|
+
type: 'import',
|
|
94
|
+
source: path.node.source.value,
|
|
95
|
+
specifiers: path.node.specifiers.map(spec => ({
|
|
96
|
+
type: spec.type,
|
|
97
|
+
imported: spec.imported?.name,
|
|
98
|
+
local: spec.local.name,
|
|
99
|
+
default: spec.type === 'ImportDefaultSpecifier'
|
|
100
|
+
})),
|
|
101
|
+
line: path.node.loc?.start.line
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
CallExpression: (path) => {
|
|
105
|
+
if (path.node.callee.name === 'require') {
|
|
106
|
+
const arg = path.node.arguments[0];
|
|
107
|
+
if (arg && arg.type === 'StringLiteral') {
|
|
108
|
+
imports.push({
|
|
109
|
+
type: 'require',
|
|
110
|
+
source: arg.value,
|
|
111
|
+
line: path.node.loc?.start.line
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
Import: (path) => {
|
|
117
|
+
if (path.parent.type === 'CallExpression' &&
|
|
118
|
+
path.parent.callee.type === 'Import') {
|
|
119
|
+
const arg = path.parent.arguments[0];
|
|
120
|
+
if (arg && arg.type === 'StringLiteral') {
|
|
121
|
+
imports.push({
|
|
122
|
+
type: 'dynamic',
|
|
123
|
+
source: arg.value,
|
|
124
|
+
line: path.node.loc?.start.line
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
} catch (error) {
|
|
131
|
+
// Fallback to regex parsing if AST parsing fails
|
|
132
|
+
return this._extractImportsRegex(content);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return imports;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Generate import mappings based on file movements
|
|
140
|
+
*/
|
|
141
|
+
generateImportMappings(fileMovements) {
|
|
142
|
+
const mappings = {};
|
|
143
|
+
|
|
144
|
+
for (const movement of fileMovements) {
|
|
145
|
+
const { oldPath, newPath } = movement;
|
|
146
|
+
const oldDir = path.dirname(oldPath);
|
|
147
|
+
const newDir = path.dirname(newPath);
|
|
148
|
+
|
|
149
|
+
// Generate relative path mappings
|
|
150
|
+
const relativeMappings = this._generateRelativeMappings(oldDir, newDir);
|
|
151
|
+
Object.assign(mappings, relativeMappings);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return mappings;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Update import statements in content
|
|
159
|
+
*/
|
|
160
|
+
_updateImportStatements(content, importMappings) {
|
|
161
|
+
let updatedContent = content;
|
|
162
|
+
|
|
163
|
+
// Update ES6 imports
|
|
164
|
+
updatedContent = this._updateES6Imports(updatedContent, importMappings);
|
|
165
|
+
|
|
166
|
+
// Update CommonJS requires
|
|
167
|
+
updatedContent = this._updateCommonJSRequires(updatedContent, importMappings);
|
|
168
|
+
|
|
169
|
+
// Update dynamic imports
|
|
170
|
+
updatedContent = this._updateDynamicImports(updatedContent, importMappings);
|
|
171
|
+
|
|
172
|
+
return updatedContent;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Update ES6 import statements
|
|
177
|
+
*/
|
|
178
|
+
_updateES6Imports(content, importMappings) {
|
|
179
|
+
const importRegex = /(import\s+(?:.*?\s+from\s+)?['"])([^'"]+)(['"])/g;
|
|
180
|
+
|
|
181
|
+
return content.replace(importRegex, (match, prefix, importPath, suffix) => {
|
|
182
|
+
const updatedPath = this._resolveImportPath(importPath, importMappings);
|
|
183
|
+
return prefix + updatedPath + suffix;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Update CommonJS require statements
|
|
189
|
+
*/
|
|
190
|
+
_updateCommonJSRequires(content, importMappings) {
|
|
191
|
+
const requireRegex = /(require\s*\(\s*['"])([^'"]+)(['"]\s*\))/g;
|
|
192
|
+
|
|
193
|
+
return content.replace(requireRegex, (match, prefix, requirePath, suffix) => {
|
|
194
|
+
const updatedPath = this._resolveImportPath(requirePath, importMappings);
|
|
195
|
+
return prefix + updatedPath + suffix;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Update dynamic import statements
|
|
201
|
+
*/
|
|
202
|
+
_updateDynamicImports(content, importMappings) {
|
|
203
|
+
const dynamicImportRegex = /(import\s*\(\s*['"])([^'"]+)(['"]\s*\))/g;
|
|
204
|
+
|
|
205
|
+
return content.replace(dynamicImportRegex, (match, prefix, importPath, suffix) => {
|
|
206
|
+
const updatedPath = this._resolveImportPath(importPath, importMappings);
|
|
207
|
+
return prefix + updatedPath + suffix;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Resolve import path based on mappings
|
|
213
|
+
*/
|
|
214
|
+
_resolveImportPath(importPath, mappings) {
|
|
215
|
+
// Direct mapping
|
|
216
|
+
if (mappings[importPath]) {
|
|
217
|
+
return mappings[importPath];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Try to resolve relative paths
|
|
221
|
+
for (const [oldPath, newPath] of Object.entries(mappings)) {
|
|
222
|
+
if (importPath.startsWith(oldPath)) {
|
|
223
|
+
return importPath.replace(oldPath, newPath);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return importPath;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Generate relative path mappings
|
|
232
|
+
*/
|
|
233
|
+
_generateRelativeMappings(oldDir, newDir) {
|
|
234
|
+
const mappings = {};
|
|
235
|
+
|
|
236
|
+
// This is a simplified implementation
|
|
237
|
+
// In practice, you'd need to consider all possible relative paths
|
|
238
|
+
// that could reference the moved file
|
|
239
|
+
|
|
240
|
+
return mappings;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Extract imports using regex (fallback method)
|
|
245
|
+
*/
|
|
246
|
+
_extractImportsRegex(content) {
|
|
247
|
+
const imports = [];
|
|
248
|
+
|
|
249
|
+
// ES6 imports
|
|
250
|
+
const importRegex = /import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/g;
|
|
251
|
+
let match;
|
|
252
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
253
|
+
imports.push({
|
|
254
|
+
type: 'import',
|
|
255
|
+
source: match[1]
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// CommonJS requires
|
|
260
|
+
const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
261
|
+
while ((match = requireRegex.exec(content)) !== null) {
|
|
262
|
+
imports.push({
|
|
263
|
+
type: 'require',
|
|
264
|
+
source: match[1]
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return imports;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Create backup of original file
|
|
273
|
+
*/
|
|
274
|
+
_createBackup(filePath, content) {
|
|
275
|
+
const backupPath = `${filePath}.backup.${Date.now()}`;
|
|
276
|
+
fs.writeFileSync(backupPath, content);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = ImportUpdater;
|