vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642
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,761 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Segment Mover
|
|
3
|
+
*
|
|
4
|
+
* Moves code segments between files while preserving functionality.
|
|
5
|
+
* Handles import updates and dependency management during moves.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { RollbackManager } = require('../utils/rollback-manager');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Move operation types
|
|
14
|
+
*/
|
|
15
|
+
const MOVE_TYPES = {
|
|
16
|
+
EXTRACT: 'extract',
|
|
17
|
+
RELOCATE: 'relocate',
|
|
18
|
+
CONSOLIDATE: 'consolidate',
|
|
19
|
+
REORGANIZE: 'reorganize'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Move result class
|
|
24
|
+
*/
|
|
25
|
+
class MoveResult {
|
|
26
|
+
constructor(operation) {
|
|
27
|
+
this.operation = operation;
|
|
28
|
+
this.success = false;
|
|
29
|
+
this.sourceModified = false;
|
|
30
|
+
this.targetCreated = false;
|
|
31
|
+
this.importsUpdated = false;
|
|
32
|
+
this.errors = [];
|
|
33
|
+
this.warnings = [];
|
|
34
|
+
this.metadata = {
|
|
35
|
+
executedAt: new Date().toISOString(),
|
|
36
|
+
linesMoved: 0,
|
|
37
|
+
filesAffected: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
addError(error) {
|
|
42
|
+
this.errors.push({
|
|
43
|
+
message: error.message,
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
stack: error.stack
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
addWarning(warning) {
|
|
50
|
+
this.warnings.push({
|
|
51
|
+
message: warning,
|
|
52
|
+
timestamp: new Date().toISOString()
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setSuccess(success) {
|
|
57
|
+
this.success = success;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setSourceModified(modified) {
|
|
61
|
+
this.sourceModified = modified;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setTargetCreated(created) {
|
|
65
|
+
this.targetCreated = created;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
setImportsUpdated(updated) {
|
|
69
|
+
this.importsUpdated = updated;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getSummary() {
|
|
73
|
+
return {
|
|
74
|
+
operation: this.operation,
|
|
75
|
+
success: this.success,
|
|
76
|
+
sourceModified: this.sourceModified,
|
|
77
|
+
targetCreated: this.targetCreated,
|
|
78
|
+
importsUpdated: this.importsUpdated,
|
|
79
|
+
linesMoved: this.metadata.linesMoved,
|
|
80
|
+
filesAffected: this.metadata.filesAffected,
|
|
81
|
+
errorCount: this.errors.length,
|
|
82
|
+
warningCount: this.warnings.length
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Move operation class
|
|
89
|
+
*/
|
|
90
|
+
class MoveOperation {
|
|
91
|
+
constructor(type, sourcePath, targetPath, options = {}) {
|
|
92
|
+
this.id = this.generateId();
|
|
93
|
+
this.type = type;
|
|
94
|
+
this.sourcePath = sourcePath;
|
|
95
|
+
this.targetPath = targetPath;
|
|
96
|
+
this.startLine = options.startLine;
|
|
97
|
+
this.endLine = options.endLine;
|
|
98
|
+
this.segmentName = options.segmentName;
|
|
99
|
+
this.updateImports = options.updateImports !== false;
|
|
100
|
+
this.preserveOriginal = options.preserveOriginal || false;
|
|
101
|
+
this.createBackup = options.createBackup !== false;
|
|
102
|
+
this.metadata = {
|
|
103
|
+
createdAt: new Date().toISOString(),
|
|
104
|
+
description: options.description || ''
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
generateId() {
|
|
109
|
+
return `move_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
validate() {
|
|
113
|
+
const errors = [];
|
|
114
|
+
|
|
115
|
+
if (!this.sourcePath) {
|
|
116
|
+
errors.push('Source path is required');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!this.targetPath) {
|
|
120
|
+
errors.push('Target path is required');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (this.startLine && this.endLine && this.startLine > this.endLine) {
|
|
124
|
+
errors.push('Start line cannot be greater than end line');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
isValid: errors.length === 0,
|
|
129
|
+
errors
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Code mover class
|
|
136
|
+
*/
|
|
137
|
+
class CodeMover {
|
|
138
|
+
constructor(options = {}) {
|
|
139
|
+
this.options = {
|
|
140
|
+
backupBeforeMove: true,
|
|
141
|
+
validateAfterMove: true,
|
|
142
|
+
updateImportsAutomatically: true,
|
|
143
|
+
preserveFormatting: true,
|
|
144
|
+
...options
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
this.rollbackManager = new RollbackManager();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Execute a move operation
|
|
152
|
+
*/
|
|
153
|
+
async executeMove(operation) {
|
|
154
|
+
const result = new MoveResult(operation);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
// Validate operation
|
|
158
|
+
const validation = operation.validate();
|
|
159
|
+
if (!validation.isValid) {
|
|
160
|
+
throw new Error(`Invalid operation: ${validation.errors.join(', ')}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Create backup if enabled
|
|
164
|
+
if (this.options.backupBeforeMove) {
|
|
165
|
+
this.rollbackManager.backupFile(operation.sourcePath);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Read source file
|
|
169
|
+
const sourceContent = fs.readFileSync(operation.sourcePath, 'utf8');
|
|
170
|
+
const sourceLines = sourceContent.split('\n');
|
|
171
|
+
|
|
172
|
+
// Extract code segment
|
|
173
|
+
const segment = this.extractSegment(sourceLines, operation);
|
|
174
|
+
result.metadata.linesMoved = segment.lines.length;
|
|
175
|
+
|
|
176
|
+
// Analyze dependencies
|
|
177
|
+
const dependencies = this.analyzeDependencies(segment.content);
|
|
178
|
+
|
|
179
|
+
// Write to target file
|
|
180
|
+
await this.writeTargetFile(operation, segment, dependencies);
|
|
181
|
+
result.setTargetCreated(true);
|
|
182
|
+
|
|
183
|
+
// Update source file
|
|
184
|
+
if (!operation.preserveOriginal) {
|
|
185
|
+
await this.updateSourceFile(operation.sourcePath, sourceLines, operation);
|
|
186
|
+
result.setSourceModified(true);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Update imports
|
|
190
|
+
if (operation.updateImports && this.options.updateImportsAutomatically) {
|
|
191
|
+
await this.updateImports(operation, dependencies);
|
|
192
|
+
result.setImportsUpdated(true);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Validate result
|
|
196
|
+
if (this.options.validateAfterMove) {
|
|
197
|
+
await this.validateMove(operation, result);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
result.metadata.filesAffected = 1 + (result.importsUpdated ? this.countAffectedFiles(dependencies) : 0);
|
|
201
|
+
result.setSuccess(true);
|
|
202
|
+
|
|
203
|
+
} catch (error) {
|
|
204
|
+
result.addError(error);
|
|
205
|
+
result.setSuccess(false);
|
|
206
|
+
|
|
207
|
+
// Rollback on error
|
|
208
|
+
await this.rollbackManager.rollback();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Extract code segment from source
|
|
216
|
+
*/
|
|
217
|
+
extractSegment(sourceLines, operation) {
|
|
218
|
+
let startIdx = 0;
|
|
219
|
+
let endIdx = sourceLines.length;
|
|
220
|
+
|
|
221
|
+
if (operation.startLine && operation.endLine) {
|
|
222
|
+
// Extract specific line range
|
|
223
|
+
startIdx = Math.max(0, operation.startLine - 1);
|
|
224
|
+
endIdx = Math.min(sourceLines.length, operation.endLine);
|
|
225
|
+
} else if (operation.segmentName) {
|
|
226
|
+
// Find segment by name (function, class, etc.)
|
|
227
|
+
const segmentRange = this.findSegmentRange(sourceLines, operation.segmentName);
|
|
228
|
+
if (segmentRange) {
|
|
229
|
+
startIdx = segmentRange.start;
|
|
230
|
+
endIdx = segmentRange.end;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const lines = sourceLines.slice(startIdx, endIdx);
|
|
235
|
+
const content = lines.join('\n');
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
lines,
|
|
239
|
+
content,
|
|
240
|
+
startLine: startIdx + 1,
|
|
241
|
+
endLine: endIdx
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Find segment range by name
|
|
247
|
+
*/
|
|
248
|
+
findSegmentRange(lines, name) {
|
|
249
|
+
for (let i = 0; i < lines.length; i++) {
|
|
250
|
+
const line = lines[i].trim();
|
|
251
|
+
|
|
252
|
+
// Function declaration
|
|
253
|
+
const funcMatch = line.match(new RegExp(`^function\\s+${name}\\s*\\(`));
|
|
254
|
+
if (funcMatch) {
|
|
255
|
+
return this.findBlockRange(lines, i);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Function expression
|
|
259
|
+
const exprMatch = line.match(new RegExp(`^(?:const|let|var)\\s+${name}\\s*=\\s*function`));
|
|
260
|
+
if (exprMatch) {
|
|
261
|
+
return this.findBlockRange(lines, i);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Arrow function
|
|
265
|
+
const arrowMatch = line.match(new RegExp(`^(?:const|let|var)\\s+${name}\\s*=\\s*\\(`));
|
|
266
|
+
if (arrowMatch) {
|
|
267
|
+
return this.findBlockRange(lines, i);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Class
|
|
271
|
+
const classMatch = line.match(new RegExp(`^class\\s+${name}\\b`));
|
|
272
|
+
if (classMatch) {
|
|
273
|
+
return this.findBlockRange(lines, i);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Object assignment
|
|
277
|
+
const objMatch = line.match(new RegExp(`^(?:const|let|var)\\s+${name}\\s*=\\s*\\{`));
|
|
278
|
+
if (objMatch) {
|
|
279
|
+
return this.findBlockRange(lines, i);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Find block range (between braces)
|
|
288
|
+
*/
|
|
289
|
+
findBlockRange(lines, startLine) {
|
|
290
|
+
let braceCount = 0;
|
|
291
|
+
let foundBrace = false;
|
|
292
|
+
|
|
293
|
+
for (let i = startLine; i < lines.length; i++) {
|
|
294
|
+
const line = lines[i];
|
|
295
|
+
|
|
296
|
+
for (let j = 0; j < line.length; j++) {
|
|
297
|
+
if (line[j] === '{') {
|
|
298
|
+
braceCount++;
|
|
299
|
+
foundBrace = true;
|
|
300
|
+
} else if (line[j] === '}') {
|
|
301
|
+
braceCount--;
|
|
302
|
+
if (foundBrace && braceCount === 0) {
|
|
303
|
+
return {
|
|
304
|
+
start: startLine,
|
|
305
|
+
end: i + 1
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
start: startLine,
|
|
314
|
+
end: lines.length
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Analyze dependencies in code segment
|
|
320
|
+
*/
|
|
321
|
+
analyzeDependencies(content) {
|
|
322
|
+
const dependencies = {
|
|
323
|
+
imports: [],
|
|
324
|
+
requires: [],
|
|
325
|
+
internalRefs: [],
|
|
326
|
+
externalRefs: []
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
const lines = content.split('\n');
|
|
330
|
+
|
|
331
|
+
for (const line of lines) {
|
|
332
|
+
const trimmed = line.trim();
|
|
333
|
+
|
|
334
|
+
// Import statements
|
|
335
|
+
if (trimmed.startsWith('import ')) {
|
|
336
|
+
const match = trimmed.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
|
|
337
|
+
if (match) {
|
|
338
|
+
dependencies.imports.push({
|
|
339
|
+
statement: trimmed,
|
|
340
|
+
module: match[1],
|
|
341
|
+
isRelative: match[1].startsWith('./') || match[1].startsWith('../')
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Require statements
|
|
347
|
+
if (trimmed.includes('require(')) {
|
|
348
|
+
const match = trimmed.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
349
|
+
if (match) {
|
|
350
|
+
dependencies.requires.push({
|
|
351
|
+
statement: trimmed,
|
|
352
|
+
module: match[1],
|
|
353
|
+
isRelative: match[1].startsWith('./') || match[1].startsWith('../')
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Variable references (simplified)
|
|
359
|
+
const varMatches = trimmed.match(/\b[a-zA-Z_]\w*\b/g);
|
|
360
|
+
if (varMatches) {
|
|
361
|
+
for (const varName of varMatches) {
|
|
362
|
+
if (!this.isKeyword(varName)) {
|
|
363
|
+
dependencies.internalRefs.push(varName);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return dependencies;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Check if word is JavaScript keyword
|
|
374
|
+
*/
|
|
375
|
+
isKeyword(word) {
|
|
376
|
+
const keywords = [
|
|
377
|
+
'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default',
|
|
378
|
+
'delete', 'do', 'else', 'export', 'extends', 'finally', 'for', 'function',
|
|
379
|
+
'if', 'import', 'in', 'instanceof', 'let', 'new', 'return', 'super', 'switch',
|
|
380
|
+
'this', 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'
|
|
381
|
+
];
|
|
382
|
+
return keywords.includes(word);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Write target file
|
|
387
|
+
*/
|
|
388
|
+
async writeTargetFile(operation, segment, dependencies) {
|
|
389
|
+
// Ensure target directory exists
|
|
390
|
+
const targetDir = path.dirname(operation.targetPath);
|
|
391
|
+
if (!fs.existsSync(targetDir)) {
|
|
392
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Generate target file content
|
|
396
|
+
const content = this.generateTargetContent(segment, dependencies);
|
|
397
|
+
|
|
398
|
+
fs.writeFileSync(operation.targetPath, content, 'utf8');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Generate content for target file
|
|
403
|
+
*/
|
|
404
|
+
generateTargetContent(segment, dependencies) {
|
|
405
|
+
let content = '';
|
|
406
|
+
|
|
407
|
+
// Add dependencies
|
|
408
|
+
for (const imp of dependencies.imports) {
|
|
409
|
+
content += imp.statement + '\n';
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
for (const req of dependencies.requires) {
|
|
413
|
+
content += req.statement + '\n';
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (dependencies.imports.length > 0 || dependencies.requires.length > 0) {
|
|
417
|
+
content += '\n';
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Add the moved code
|
|
421
|
+
content += segment.content;
|
|
422
|
+
|
|
423
|
+
// Add exports if needed
|
|
424
|
+
if (operation.segmentName) {
|
|
425
|
+
content += '\n\n';
|
|
426
|
+
content += `export default ${operation.segmentName};\n`;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return content;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Update source file
|
|
434
|
+
*/
|
|
435
|
+
async updateSourceFile(sourcePath, sourceLines, operation) {
|
|
436
|
+
let newLines;
|
|
437
|
+
|
|
438
|
+
if (operation.startLine && operation.endLine) {
|
|
439
|
+
// Remove specific line range
|
|
440
|
+
const startIdx = Math.max(0, operation.startLine - 1);
|
|
441
|
+
const endIdx = Math.min(sourceLines.length, operation.endLine);
|
|
442
|
+
|
|
443
|
+
newLines = [
|
|
444
|
+
...sourceLines.slice(0, startIdx),
|
|
445
|
+
...sourceLines.slice(endIdx)
|
|
446
|
+
];
|
|
447
|
+
} else {
|
|
448
|
+
// Remove entire segment (if found)
|
|
449
|
+
const segmentRange = this.findSegmentRange(sourceLines, operation.segmentName);
|
|
450
|
+
if (segmentRange) {
|
|
451
|
+
newLines = [
|
|
452
|
+
...sourceLines.slice(0, segmentRange.start),
|
|
453
|
+
...sourceLines.slice(segmentRange.end)
|
|
454
|
+
];
|
|
455
|
+
} else {
|
|
456
|
+
newLines = sourceLines; // No changes if segment not found
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Add import statement for moved code
|
|
461
|
+
if (operation.segmentName) {
|
|
462
|
+
const relativePath = path.relative(
|
|
463
|
+
path.dirname(sourcePath),
|
|
464
|
+
path.dirname(operation.targetPath)
|
|
465
|
+
).replace(/\\/g, '/');
|
|
466
|
+
|
|
467
|
+
const importStatement = `import ${operation.segmentName} from './${relativePath}/${path.basename(operation.targetPath, '.js')}';`;
|
|
468
|
+
newLines.unshift(importStatement);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const newContent = newLines.join('\n');
|
|
472
|
+
fs.writeFileSync(sourcePath, newContent, 'utf8');
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Update imports in dependent files
|
|
477
|
+
*/
|
|
478
|
+
async updateImports(operation, dependencies) {
|
|
479
|
+
// Find files that import from source
|
|
480
|
+
const dependentFiles = this.findDependentFiles(operation.sourcePath);
|
|
481
|
+
|
|
482
|
+
for (const depFile of dependentFiles) {
|
|
483
|
+
await this.updateFileImports(depFile, operation, dependencies);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Find files that depend on source file
|
|
489
|
+
*/
|
|
490
|
+
findDependentFiles(sourcePath) {
|
|
491
|
+
// This would search the codebase for files that import from sourcePath
|
|
492
|
+
// For now, return empty array as placeholder
|
|
493
|
+
return [];
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Update imports in a specific file
|
|
498
|
+
*/
|
|
499
|
+
async updateFileFiles(filePath, operation, dependencies) {
|
|
500
|
+
try {
|
|
501
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
502
|
+
const lines = content.split('\n');
|
|
503
|
+
|
|
504
|
+
// Update import statements to point to new location
|
|
505
|
+
const updatedLines = lines.map(line => {
|
|
506
|
+
if (line.includes(operation.sourcePath)) {
|
|
507
|
+
// Update import path
|
|
508
|
+
const relativePath = path.relative(
|
|
509
|
+
path.dirname(filePath),
|
|
510
|
+
path.dirname(operation.targetPath)
|
|
511
|
+
).replace(/\\/g, '/');
|
|
512
|
+
|
|
513
|
+
return line.replace(operation.sourcePath, relativePath);
|
|
514
|
+
}
|
|
515
|
+
return line;
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
const newContent = updatedLines.join('\n');
|
|
519
|
+
fs.writeFileSync(filePath, newContent, 'utf8');
|
|
520
|
+
|
|
521
|
+
} catch (error) {
|
|
522
|
+
// Log warning but don't fail the operation
|
|
523
|
+
console.warn(`Failed to update imports in ${filePath}:`, error.message);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Count affected files
|
|
529
|
+
*/
|
|
530
|
+
countAffectedFiles(dependencies) {
|
|
531
|
+
// Count unique files that might need import updates
|
|
532
|
+
const affectedFiles = new Set();
|
|
533
|
+
|
|
534
|
+
for (const dep of dependencies.imports) {
|
|
535
|
+
if (dep.isRelative) {
|
|
536
|
+
affectedFiles.add(dep.module);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
for (const dep of dependencies.requires) {
|
|
541
|
+
if (dep.isRelative) {
|
|
542
|
+
affectedFiles.add(dep.module);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return affectedFiles.size;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Validate move operation
|
|
551
|
+
*/
|
|
552
|
+
async validateMove(operation, result) {
|
|
553
|
+
try {
|
|
554
|
+
// Check if target file was created
|
|
555
|
+
if (!fs.existsSync(operation.targetPath)) {
|
|
556
|
+
throw new Error('Target file was not created');
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Check if target file has content
|
|
560
|
+
const targetStats = fs.statSync(operation.targetPath);
|
|
561
|
+
if (targetStats.size === 0) {
|
|
562
|
+
result.addWarning('Target file is empty');
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Validate syntax if JavaScript
|
|
566
|
+
if (operation.targetPath.endsWith('.js')) {
|
|
567
|
+
const targetContent = fs.readFileSync(operation.targetPath, 'utf8');
|
|
568
|
+
this.validateJavaScriptSyntax(targetContent);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Check source file if modified
|
|
572
|
+
if (result.sourceModified && fs.existsSync(operation.sourcePath)) {
|
|
573
|
+
const sourceContent = fs.readFileSync(operation.sourcePath, 'utf8');
|
|
574
|
+
if (operation.sourcePath.endsWith('.js')) {
|
|
575
|
+
this.validateJavaScriptSyntax(sourceContent);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
} catch (error) {
|
|
580
|
+
result.addError(error);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Validate JavaScript syntax
|
|
586
|
+
*/
|
|
587
|
+
validateJavaScriptSyntax(content) {
|
|
588
|
+
try {
|
|
589
|
+
const vm = require('vm');
|
|
590
|
+
new vm.Script(content, { filename: 'validation' });
|
|
591
|
+
} catch (error) {
|
|
592
|
+
throw new Error(`Syntax validation failed: ${error.message}`);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Extract multiple segments
|
|
598
|
+
*/
|
|
599
|
+
async extractSegments(sourcePath, segments) {
|
|
600
|
+
const results = [];
|
|
601
|
+
|
|
602
|
+
for (const segmentConfig of segments) {
|
|
603
|
+
const operation = new MoveOperation(
|
|
604
|
+
MOVE_TYPES.EXTRACT,
|
|
605
|
+
sourcePath,
|
|
606
|
+
segmentConfig.targetPath,
|
|
607
|
+
segmentConfig
|
|
608
|
+
);
|
|
609
|
+
|
|
610
|
+
const result = await this.executeMove(operation);
|
|
611
|
+
results.push(result);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return results;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Consolidate multiple segments into one file
|
|
619
|
+
*/
|
|
620
|
+
async consolidateSegments(segments, targetPath) {
|
|
621
|
+
const operation = new MoveOperation(
|
|
622
|
+
MOVE_TYPES.CONSOLIDATE,
|
|
623
|
+
segments[0].sourcePath,
|
|
624
|
+
targetPath,
|
|
625
|
+
{
|
|
626
|
+
segmentName: 'consolidated',
|
|
627
|
+
description: `Consolidate ${segments.length} segments`
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
|
|
631
|
+
// Read all segments
|
|
632
|
+
const consolidatedContent = [];
|
|
633
|
+
|
|
634
|
+
for (const segment of segments) {
|
|
635
|
+
const sourceContent = fs.readFileSync(segment.sourcePath, 'utf8');
|
|
636
|
+
const sourceLines = sourceContent.split('\n');
|
|
637
|
+
|
|
638
|
+
const segmentData = this.extractSegment(sourceLines, {
|
|
639
|
+
startLine: segment.startLine,
|
|
640
|
+
endLine: segment.endLine
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
consolidatedContent.push(segmentData.content);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// Write consolidated file
|
|
647
|
+
const targetDir = path.dirname(targetPath);
|
|
648
|
+
if (!fs.existsSync(targetDir)) {
|
|
649
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
fs.writeFileSync(targetPath, consolidatedContent.join('\n\n'), 'utf8');
|
|
653
|
+
|
|
654
|
+
return {
|
|
655
|
+
success: true,
|
|
656
|
+
segmentsConsolidated: segments.length,
|
|
657
|
+
targetPath,
|
|
658
|
+
linesWritten: consolidatedContent.join('\n\n').split('\n').length
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Preview move operation without executing
|
|
664
|
+
*/
|
|
665
|
+
previewMove(operation) {
|
|
666
|
+
try {
|
|
667
|
+
const sourceContent = fs.readFileSync(operation.sourcePath, 'utf8');
|
|
668
|
+
const sourceLines = sourceContent.split('\n');
|
|
669
|
+
|
|
670
|
+
const segment = this.extractSegment(sourceLines, operation);
|
|
671
|
+
const dependencies = this.analyzeDependencies(segment.content);
|
|
672
|
+
|
|
673
|
+
return {
|
|
674
|
+
operation,
|
|
675
|
+
segment: {
|
|
676
|
+
lines: segment.lines.length,
|
|
677
|
+
preview: segment.lines.slice(0, 10).join('\n') + (segment.lines.length > 10 ? '\n...' : '')
|
|
678
|
+
},
|
|
679
|
+
dependencies,
|
|
680
|
+
estimatedImpact: this.estimateImpact(operation, dependencies)
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
} catch (error) {
|
|
684
|
+
return {
|
|
685
|
+
operation,
|
|
686
|
+
error: error.message,
|
|
687
|
+
success: false
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Estimate impact of move operation
|
|
694
|
+
*/
|
|
695
|
+
estimateImpact(operation, dependencies) {
|
|
696
|
+
const impact = {
|
|
697
|
+
filesAffected: 1,
|
|
698
|
+
importsToUpdate: 0,
|
|
699
|
+
riskLevel: 'low'
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// Count dependent files
|
|
703
|
+
const dependentFiles = this.findDependentFiles(operation.sourcePath);
|
|
704
|
+
impact.filesAffected += dependentFiles.length;
|
|
705
|
+
impact.importsToUpdate = dependentFiles.length;
|
|
706
|
+
|
|
707
|
+
// Assess risk level
|
|
708
|
+
if (impact.filesAffected > 10) {
|
|
709
|
+
impact.riskLevel = 'high';
|
|
710
|
+
} else if (impact.filesAffected > 3) {
|
|
711
|
+
impact.riskLevel = 'medium';
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
return impact;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Get move statistics
|
|
719
|
+
*/
|
|
720
|
+
getStatistics(results) {
|
|
721
|
+
const stats = {
|
|
722
|
+
totalOperations: results.length,
|
|
723
|
+
successful: 0,
|
|
724
|
+
failed: 0,
|
|
725
|
+
totalLinesMoved: 0,
|
|
726
|
+
totalFilesAffected: 0,
|
|
727
|
+
byType: {},
|
|
728
|
+
errors: [],
|
|
729
|
+
warnings: []
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
for (const result of results) {
|
|
733
|
+
if (result.success) {
|
|
734
|
+
stats.successful++;
|
|
735
|
+
} else {
|
|
736
|
+
stats.failed++;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
stats.totalLinesMoved += result.metadata.linesMoved;
|
|
740
|
+
stats.totalFilesAffected += result.metadata.filesAffected;
|
|
741
|
+
|
|
742
|
+
const type = result.operation.type;
|
|
743
|
+
if (!stats.byType[type]) {
|
|
744
|
+
stats.byType[type] = 0;
|
|
745
|
+
}
|
|
746
|
+
stats.byType[type]++;
|
|
747
|
+
|
|
748
|
+
stats.errors.push(...result.errors);
|
|
749
|
+
stats.warnings.push(...result.warnings);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
return stats;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
module.exports = {
|
|
757
|
+
CodeMover,
|
|
758
|
+
MoveOperation,
|
|
759
|
+
MoveResult,
|
|
760
|
+
MOVE_TYPES
|
|
761
|
+
};
|