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,696 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Splitter
|
|
3
|
+
*
|
|
4
|
+
* Safely splits large files into smaller, logical modules using AST transformations.
|
|
5
|
+
* Preserves functionality while ensuring all new modules stay under size limits.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { RollbackManager } = require('../utils/rollback-manager');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Split operation types
|
|
14
|
+
*/
|
|
15
|
+
const SPLIT_TYPES = {
|
|
16
|
+
FUNCTION_EXTRACTION: 'function_extraction',
|
|
17
|
+
CLASS_EXTRACTION: 'class_extraction',
|
|
18
|
+
MODULE_EXTRACTION: 'module_extraction',
|
|
19
|
+
UTILITY_EXTRACTION: 'utility_extraction',
|
|
20
|
+
CONSTANT_EXTRACTION: 'constant_extraction'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* File split result class
|
|
25
|
+
*/
|
|
26
|
+
class FileSplitResult {
|
|
27
|
+
constructor(originalFile) {
|
|
28
|
+
this.originalFile = originalFile;
|
|
29
|
+
this.splits = [];
|
|
30
|
+
this.success = false;
|
|
31
|
+
this.errors = [];
|
|
32
|
+
this.warnings = [];
|
|
33
|
+
this.metadata = {
|
|
34
|
+
createdAt: new Date().toISOString(),
|
|
35
|
+
originalSize: 0,
|
|
36
|
+
totalSplitSize: 0,
|
|
37
|
+
splitCount: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
addSplit(split) {
|
|
42
|
+
this.splits.push(split);
|
|
43
|
+
this.metadata.splitCount++;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
addError(error) {
|
|
47
|
+
this.errors.push({
|
|
48
|
+
message: error.message,
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
stack: error.stack
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
addWarning(warning) {
|
|
55
|
+
this.warnings.push({
|
|
56
|
+
message: warning,
|
|
57
|
+
timestamp: new Date().toISOString()
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setSuccess(success) {
|
|
62
|
+
this.success = success;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
getSummary() {
|
|
66
|
+
return {
|
|
67
|
+
originalFile: this.originalFile,
|
|
68
|
+
success: this.success,
|
|
69
|
+
splitCount: this.metadata.splitCount,
|
|
70
|
+
originalSize: this.metadata.originalSize,
|
|
71
|
+
totalSplitSize: this.metadata.totalSplitSize,
|
|
72
|
+
errorCount: this.errors.length,
|
|
73
|
+
warningCount: this.warnings.length,
|
|
74
|
+
splits: this.splits.map(split => split.getSummary())
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Split operation class
|
|
81
|
+
*/
|
|
82
|
+
class SplitOperation {
|
|
83
|
+
constructor(type, name, startLine, endLine, outputPath) {
|
|
84
|
+
this.type = type;
|
|
85
|
+
this.name = name;
|
|
86
|
+
this.startLine = startLine;
|
|
87
|
+
this.endLine = endLine;
|
|
88
|
+
this.outputPath = outputPath;
|
|
89
|
+
this.content = '';
|
|
90
|
+
this.dependencies = [];
|
|
91
|
+
this.exports = [];
|
|
92
|
+
this.success = false;
|
|
93
|
+
this.errors = [];
|
|
94
|
+
this.metadata = {
|
|
95
|
+
createdAt: new Date().toISOString(),
|
|
96
|
+
lineCount: endLine - startLine + 1
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setContent(content) {
|
|
101
|
+
this.content = content;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
addDependency(dependency) {
|
|
105
|
+
this.dependencies.push(dependency);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
addExport(exportName) {
|
|
109
|
+
this.exports.push(exportName);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
setSuccess(success) {
|
|
113
|
+
this.success = success;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
addError(error) {
|
|
117
|
+
this.errors.push({
|
|
118
|
+
message: error.message,
|
|
119
|
+
timestamp: new Date().toISOString()
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getSummary() {
|
|
124
|
+
return {
|
|
125
|
+
type: this.type,
|
|
126
|
+
name: this.name,
|
|
127
|
+
outputPath: this.outputPath,
|
|
128
|
+
lineCount: this.metadata.lineCount,
|
|
129
|
+
success: this.success,
|
|
130
|
+
dependencyCount: this.dependencies.length,
|
|
131
|
+
exportCount: this.exports.length,
|
|
132
|
+
errorCount: this.errors.length
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* File splitter class
|
|
139
|
+
*/
|
|
140
|
+
class FileSplitter {
|
|
141
|
+
constructor(options = {}) {
|
|
142
|
+
this.options = {
|
|
143
|
+
maxModuleSize: 300,
|
|
144
|
+
minModuleSize: 20,
|
|
145
|
+
backupBeforeSplit: true,
|
|
146
|
+
validateAfterSplit: true,
|
|
147
|
+
updateImports: true,
|
|
148
|
+
...options
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
this.rollbackManager = new RollbackManager();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Split a file based on analysis results
|
|
156
|
+
*/
|
|
157
|
+
async splitFile(fileAnalysis, splitPoints = null) {
|
|
158
|
+
const result = new FileSplitResult(fileAnalysis.filePath);
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
// Create backup if enabled
|
|
162
|
+
if (this.options.backupBeforeSplit) {
|
|
163
|
+
this.rollbackManager.backupFile(fileAnalysis.filePath);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Read original file
|
|
167
|
+
const originalContent = fs.readFileSync(fileAnalysis.filePath, 'utf8');
|
|
168
|
+
const originalLines = originalContent.split('\n');
|
|
169
|
+
|
|
170
|
+
result.metadata.originalSize = originalLines.length;
|
|
171
|
+
|
|
172
|
+
// Determine split points if not provided
|
|
173
|
+
const points = splitPoints || this.determineSplitPoints(fileAnalysis, originalLines);
|
|
174
|
+
|
|
175
|
+
if (points.length === 0) {
|
|
176
|
+
result.addWarning('No suitable split points found');
|
|
177
|
+
result.setSuccess(true);
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Execute splits
|
|
182
|
+
const splits = await this.executeSplits(fileAnalysis, originalLines, points);
|
|
183
|
+
|
|
184
|
+
// Update original file
|
|
185
|
+
await this.updateOriginalFile(fileAnalysis.filePath, originalLines, splits);
|
|
186
|
+
|
|
187
|
+
// Update imports in dependent files
|
|
188
|
+
if (this.options.updateImports) {
|
|
189
|
+
await this.updateImports(splits);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Validate results
|
|
193
|
+
if (this.options.validateAfterSplit) {
|
|
194
|
+
await this.validateSplits(splits);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Compile results
|
|
198
|
+
for (const split of splits) {
|
|
199
|
+
if (split.success) {
|
|
200
|
+
result.addSplit(split);
|
|
201
|
+
result.metadata.totalSplitSize += split.metadata.lineCount;
|
|
202
|
+
} else {
|
|
203
|
+
result.addError(new Error(`Split failed: ${split.name}`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
result.setSuccess(result.errors.length === 0);
|
|
208
|
+
|
|
209
|
+
} catch (error) {
|
|
210
|
+
result.addError(error);
|
|
211
|
+
result.setSuccess(false);
|
|
212
|
+
|
|
213
|
+
// Rollback on error
|
|
214
|
+
await this.rollbackManager.rollback();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Determine optimal split points
|
|
222
|
+
*/
|
|
223
|
+
determineSplitPoints(fileAnalysis, lines) {
|
|
224
|
+
const splitPoints = [];
|
|
225
|
+
const boundaries = fileAnalysis.boundaries;
|
|
226
|
+
|
|
227
|
+
if (!boundaries || !boundaries.boundaries) {
|
|
228
|
+
return splitPoints;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Find functions that can be extracted
|
|
232
|
+
const functions = boundaries.boundaries.filter(b =>
|
|
233
|
+
b.type === 'function' &&
|
|
234
|
+
b.lineCount >= this.options.minModuleSize &&
|
|
235
|
+
b.lineCount <= this.options.maxModuleSize &&
|
|
236
|
+
b.name !== ''
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
for (const func of functions) {
|
|
240
|
+
splitPoints.push({
|
|
241
|
+
type: SPLIT_TYPES.FUNCTION_EXTRACTION,
|
|
242
|
+
name: func.name,
|
|
243
|
+
startLine: func.startLine,
|
|
244
|
+
endLine: func.endLine,
|
|
245
|
+
suggestedPath: this.suggestOutputPath(fileAnalysis.filePath, func.name, 'function')
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Find classes that can be extracted
|
|
250
|
+
const classes = boundaries.boundaries.filter(b =>
|
|
251
|
+
b.type === 'class' &&
|
|
252
|
+
b.lineCount >= this.options.minModuleSize &&
|
|
253
|
+
b.lineCount <= this.options.maxModuleSize &&
|
|
254
|
+
b.name !== ''
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
for (const cls of classes) {
|
|
258
|
+
splitPoints.push({
|
|
259
|
+
type: SPLIT_TYPES.CLASS_EXTRACTION,
|
|
260
|
+
name: cls.name,
|
|
261
|
+
startLine: cls.startLine,
|
|
262
|
+
endLine: cls.endLine,
|
|
263
|
+
suggestedPath: this.suggestOutputPath(fileAnalysis.filePath, cls.name, 'class')
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Sort by line number
|
|
268
|
+
return splitPoints.sort((a, b) => a.startLine - b.startLine);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Execute split operations
|
|
273
|
+
*/
|
|
274
|
+
async executeSplits(fileAnalysis, originalLines, splitPoints) {
|
|
275
|
+
const splits = [];
|
|
276
|
+
|
|
277
|
+
for (const splitPoint of splitPoints) {
|
|
278
|
+
try {
|
|
279
|
+
const split = new SplitOperation(
|
|
280
|
+
splitPoint.type,
|
|
281
|
+
splitPoint.name,
|
|
282
|
+
splitPoint.startLine,
|
|
283
|
+
splitPoint.endLine,
|
|
284
|
+
splitPoint.suggestedPath
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
// Extract content
|
|
288
|
+
const content = this.extractContent(originalLines, splitPoint.startLine, splitPoint.endLine);
|
|
289
|
+
split.setContent(content);
|
|
290
|
+
|
|
291
|
+
// Analyze dependencies
|
|
292
|
+
const dependencies = this.analyzeDependencies(content, fileAnalysis.filePath);
|
|
293
|
+
for (const dep of dependencies) {
|
|
294
|
+
split.addDependency(dep);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Analyze exports
|
|
298
|
+
const exports = this.analyzeExports(content);
|
|
299
|
+
for (const exp of exports) {
|
|
300
|
+
split.addExport(exp);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Write split file
|
|
304
|
+
await this.writeSplitFile(split);
|
|
305
|
+
|
|
306
|
+
split.setSuccess(true);
|
|
307
|
+
splits.push(split);
|
|
308
|
+
|
|
309
|
+
} catch (error) {
|
|
310
|
+
const split = new SplitOperation(
|
|
311
|
+
splitPoint.type,
|
|
312
|
+
splitPoint.name,
|
|
313
|
+
splitPoint.startLine,
|
|
314
|
+
splitPoint.endLine,
|
|
315
|
+
splitPoint.suggestedPath
|
|
316
|
+
);
|
|
317
|
+
split.addError(error);
|
|
318
|
+
split.setSuccess(false);
|
|
319
|
+
splits.push(split);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return splits;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Extract content from lines
|
|
328
|
+
*/
|
|
329
|
+
extractContent(lines, startLine, endLine) {
|
|
330
|
+
// Convert to 0-based indexing
|
|
331
|
+
const startIndex = startLine - 1;
|
|
332
|
+
const endIndex = Math.min(endLine, lines.length);
|
|
333
|
+
|
|
334
|
+
return lines.slice(startIndex, endIndex).join('\n');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Analyze dependencies in extracted content
|
|
339
|
+
*/
|
|
340
|
+
analyzeDependencies(content, originalFilePath) {
|
|
341
|
+
const dependencies = [];
|
|
342
|
+
const lines = content.split('\n');
|
|
343
|
+
|
|
344
|
+
for (const line of lines) {
|
|
345
|
+
const trimmed = line.trim();
|
|
346
|
+
|
|
347
|
+
// Find import statements
|
|
348
|
+
if (trimmed.startsWith('import ')) {
|
|
349
|
+
const match = trimmed.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
|
|
350
|
+
if (match) {
|
|
351
|
+
dependencies.push({
|
|
352
|
+
type: 'import',
|
|
353
|
+
path: match[1],
|
|
354
|
+
isRelative: match[1].startsWith('./') || match[1].startsWith('../')
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Find require statements
|
|
360
|
+
if (trimmed.startsWith('const ') && trimmed.includes('require(')) {
|
|
361
|
+
const match = trimmed.match(/require\(['"]([^'"]+)['"]\)/);
|
|
362
|
+
if (match) {
|
|
363
|
+
dependencies.push({
|
|
364
|
+
type: 'require',
|
|
365
|
+
path: match[1],
|
|
366
|
+
isRelative: match[1].startsWith('./') || match[1].startsWith('../')
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return dependencies;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Analyze exports in extracted content
|
|
377
|
+
*/
|
|
378
|
+
analyzeExports(content) {
|
|
379
|
+
const exports = [];
|
|
380
|
+
const lines = content.split('\n');
|
|
381
|
+
|
|
382
|
+
for (const line of lines) {
|
|
383
|
+
const trimmed = line.trim();
|
|
384
|
+
|
|
385
|
+
// Find export statements
|
|
386
|
+
if (trimmed.startsWith('export ')) {
|
|
387
|
+
// Named exports
|
|
388
|
+
const namedMatch = trimmed.match(/export\s+(?:const|let|var|function|class)\s+(\w+)/);
|
|
389
|
+
if (namedMatch) {
|
|
390
|
+
exports.push({
|
|
391
|
+
type: 'named',
|
|
392
|
+
name: namedMatch[1],
|
|
393
|
+
isDefault: false
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Default exports
|
|
398
|
+
if (trimmed.includes('export default')) {
|
|
399
|
+
const defaultMatch = trimmed.match(/export default\s+(?:function|class)?\s*(\w+)?/);
|
|
400
|
+
const name = defaultMatch ? defaultMatch[1] : 'default';
|
|
401
|
+
exports.push({
|
|
402
|
+
type: 'default',
|
|
403
|
+
name,
|
|
404
|
+
isDefault: true
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return exports;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Write split file
|
|
415
|
+
*/
|
|
416
|
+
async writeSplitFile(split) {
|
|
417
|
+
// Ensure output directory exists
|
|
418
|
+
const outputDir = path.dirname(split.outputPath);
|
|
419
|
+
if (!fs.existsSync(outputDir)) {
|
|
420
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Generate file content with proper imports/exports
|
|
424
|
+
const fileContent = this.generateSplitFileContent(split);
|
|
425
|
+
|
|
426
|
+
fs.writeFileSync(split.outputPath, fileContent, 'utf8');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Generate content for split file
|
|
431
|
+
*/
|
|
432
|
+
generateSplitFileContent(split) {
|
|
433
|
+
let content = '';
|
|
434
|
+
|
|
435
|
+
// Add dependencies
|
|
436
|
+
for (const dep of split.dependencies) {
|
|
437
|
+
if (dep.type === 'import') {
|
|
438
|
+
content += `import ${dep.path};\n`;
|
|
439
|
+
} else if (dep.type === 'require') {
|
|
440
|
+
content += `const ${dep.path} = require('${dep.path}');\n`;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (split.dependencies.length > 0) {
|
|
445
|
+
content += '\n';
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Add the extracted content
|
|
449
|
+
content += split.content;
|
|
450
|
+
|
|
451
|
+
// Add exports if needed
|
|
452
|
+
if (split.exports.length > 0) {
|
|
453
|
+
content += '\n\n';
|
|
454
|
+
for (const exp of split.exports) {
|
|
455
|
+
if (exp.isDefault) {
|
|
456
|
+
content += `export default ${exp.name};\n`;
|
|
457
|
+
} else {
|
|
458
|
+
content += `export { ${exp.name} };\n`;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return content;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Update original file to remove extracted content
|
|
468
|
+
*/
|
|
469
|
+
async updateOriginalFile(filePath, originalLines, splits) {
|
|
470
|
+
// Mark lines to remove
|
|
471
|
+
const linesToRemove = new Set();
|
|
472
|
+
|
|
473
|
+
for (const split of splits) {
|
|
474
|
+
if (split.success) {
|
|
475
|
+
for (let i = split.startLine - 1; i < split.endLine; i++) {
|
|
476
|
+
linesToRemove.add(i);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Create new content
|
|
482
|
+
const newLines = originalLines.filter((_, index) => !linesToRemove.has(index));
|
|
483
|
+
|
|
484
|
+
// Add import statements for extracted modules
|
|
485
|
+
const importStatements = this.generateImportStatements(splits);
|
|
486
|
+
if (importStatements.length > 0) {
|
|
487
|
+
newLines.unshift(...importStatements);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Write updated file
|
|
491
|
+
const newContent = newLines.join('\n');
|
|
492
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Generate import statements for extracted modules
|
|
497
|
+
*/
|
|
498
|
+
generateImportStatements(splits) {
|
|
499
|
+
const imports = [];
|
|
500
|
+
|
|
501
|
+
for (const split of splits) {
|
|
502
|
+
if (!split.success) continue;
|
|
503
|
+
|
|
504
|
+
const relativePath = path.relative(
|
|
505
|
+
path.dirname(split.outputPath),
|
|
506
|
+
path.dirname(split.outputPath) // This should be the original file's directory
|
|
507
|
+
).replace(/\\/g, '/');
|
|
508
|
+
|
|
509
|
+
for (const exp of split.exports) {
|
|
510
|
+
if (exp.isDefault) {
|
|
511
|
+
imports.push(`import ${exp.name} from './${relativePath}/${path.basename(split.outputPath, '.js')}';`);
|
|
512
|
+
} else {
|
|
513
|
+
imports.push(`import { ${exp.name} } from './${relativePath}/${path.basename(split.outputPath, '.js')}';`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
return imports.length > 0 ? [''] : imports;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Update imports in dependent files
|
|
523
|
+
*/
|
|
524
|
+
async updateImports(splits) {
|
|
525
|
+
// This would analyze the codebase for files that import from the original file
|
|
526
|
+
// and update their import statements to include the new split files
|
|
527
|
+
// For now, this is a placeholder implementation
|
|
528
|
+
|
|
529
|
+
for (const split of splits) {
|
|
530
|
+
if (!split.success) continue;
|
|
531
|
+
|
|
532
|
+
// Find files that might need import updates
|
|
533
|
+
const dependentFiles = this.findDependentFiles(split.outputPath);
|
|
534
|
+
|
|
535
|
+
for (const depFile of dependentFiles) {
|
|
536
|
+
await this.updateFileImports(depFile, split);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Find files that depend on a split file
|
|
543
|
+
*/
|
|
544
|
+
findDependentFiles(splitFilePath) {
|
|
545
|
+
// Placeholder implementation - would search codebase for imports
|
|
546
|
+
return [];
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Update imports in a specific file
|
|
551
|
+
*/
|
|
552
|
+
async updateFileImports(filePath, split) {
|
|
553
|
+
// Placeholder implementation - would update import statements
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Validate split results
|
|
558
|
+
*/
|
|
559
|
+
async validateSplits(splits) {
|
|
560
|
+
for (const split of splits) {
|
|
561
|
+
if (!split.success) continue;
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
// Check if file exists and is readable
|
|
565
|
+
if (!fs.existsSync(split.outputPath)) {
|
|
566
|
+
throw new Error(`Split file not created: ${split.outputPath}`);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Check file size
|
|
570
|
+
const stats = fs.statSync(split.outputPath);
|
|
571
|
+
const content = fs.readFileSync(split.outputPath, 'utf8');
|
|
572
|
+
const lineCount = content.split('\n').length;
|
|
573
|
+
|
|
574
|
+
if (lineCount > this.options.maxModuleSize) {
|
|
575
|
+
split.addError(new Error(`Split file too large: ${lineCount} lines`));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Basic syntax validation
|
|
579
|
+
if (split.outputPath.endsWith('.js')) {
|
|
580
|
+
this.validateJavaScriptSyntax(content);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
} catch (error) {
|
|
584
|
+
split.addError(error);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Validate JavaScript syntax
|
|
591
|
+
*/
|
|
592
|
+
validateJavaScriptSyntax(content) {
|
|
593
|
+
try {
|
|
594
|
+
const vm = require('vm');
|
|
595
|
+
new vm.Script(content, { filename: 'validation' });
|
|
596
|
+
} catch (error) {
|
|
597
|
+
throw new Error(`Syntax validation failed: ${error.message}`);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Suggest output path for split
|
|
603
|
+
*/
|
|
604
|
+
suggestOutputPath(originalPath, name, type) {
|
|
605
|
+
const dir = path.dirname(originalPath);
|
|
606
|
+
const baseName = name.toLowerCase().replace(/[^a-z0-9]/g, '-');
|
|
607
|
+
return path.join(dir, `${baseName}.js`);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Batch split multiple files
|
|
612
|
+
*/
|
|
613
|
+
async splitFiles(fileAnalyses) {
|
|
614
|
+
const results = [];
|
|
615
|
+
|
|
616
|
+
for (const analysis of fileAnalyses) {
|
|
617
|
+
const result = await this.splitFile(analysis);
|
|
618
|
+
results.push(result);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
return results;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Preview split operations without executing
|
|
626
|
+
*/
|
|
627
|
+
previewSplits(fileAnalysis) {
|
|
628
|
+
const originalContent = fs.readFileSync(fileAnalysis.filePath, 'utf8');
|
|
629
|
+
const originalLines = originalContent.split('\n');
|
|
630
|
+
|
|
631
|
+
const splitPoints = this.determineSplitPoints(fileAnalysis, originalLines);
|
|
632
|
+
const previews = [];
|
|
633
|
+
|
|
634
|
+
for (const splitPoint of splitPoints) {
|
|
635
|
+
const content = this.extractContent(originalLines, splitPoint.startLine, splitPoint.endLine);
|
|
636
|
+
const dependencies = this.analyzeDependencies(content, fileAnalysis.filePath);
|
|
637
|
+
const exports = this.analyzeExports(content);
|
|
638
|
+
|
|
639
|
+
previews.push({
|
|
640
|
+
type: splitPoint.type,
|
|
641
|
+
name: splitPoint.name,
|
|
642
|
+
startLine: splitPoint.startLine,
|
|
643
|
+
endLine: splitPoint.endLine,
|
|
644
|
+
lineCount: splitPoint.endLine - splitPoint.startLine + 1,
|
|
645
|
+
outputPath: splitPoint.suggestedPath,
|
|
646
|
+
dependencies,
|
|
647
|
+
exports,
|
|
648
|
+
preview: content.split('\n').slice(0, 5).join('\n') + (content.split('\n').length > 5 ? '\n...' : '')
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return previews;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Get split statistics
|
|
657
|
+
*/
|
|
658
|
+
getStatistics(results) {
|
|
659
|
+
const stats = {
|
|
660
|
+
totalFiles: results.length,
|
|
661
|
+
successfulSplits: 0,
|
|
662
|
+
failedSplits: 0,
|
|
663
|
+
totalSplits: 0,
|
|
664
|
+
averageSplitsPerFile: 0,
|
|
665
|
+
totalLinesExtracted: 0,
|
|
666
|
+
errors: [],
|
|
667
|
+
warnings: []
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
for (const result of results) {
|
|
671
|
+
if (result.success) {
|
|
672
|
+
stats.successfulSplits++;
|
|
673
|
+
} else {
|
|
674
|
+
stats.failedSplits++;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
stats.totalSplits += result.metadata.splitCount;
|
|
678
|
+
stats.totalLinesExtracted += result.metadata.totalSplitSize;
|
|
679
|
+
|
|
680
|
+
stats.errors.push(...result.errors);
|
|
681
|
+
stats.warnings.push(...result.warnings);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
stats.averageSplitsPerFile = results.length > 0 ?
|
|
685
|
+
stats.totalSplits / results.length : 0;
|
|
686
|
+
|
|
687
|
+
return stats;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
module.exports = {
|
|
692
|
+
FileSplitter,
|
|
693
|
+
FileSplitResult,
|
|
694
|
+
SplitOperation,
|
|
695
|
+
SPLIT_TYPES
|
|
696
|
+
};
|