vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850
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/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Movement Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utility functions for moving code segments between files.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Move operation types
|
|
12
|
+
*/
|
|
13
|
+
const MOVE_TYPES = {
|
|
14
|
+
EXTRACT: 'extract',
|
|
15
|
+
RELOCATE: 'relocate',
|
|
16
|
+
CONSOLIDATE: 'consolidate',
|
|
17
|
+
REORGANIZE: 'reorganize'
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create move operation
|
|
22
|
+
* @param {string} type - Move type
|
|
23
|
+
* @param {Object} source - Source information
|
|
24
|
+
* @param {Object} target - Target information
|
|
25
|
+
* @param {Object} options - Move options
|
|
26
|
+
* @returns {Object} - Move operation
|
|
27
|
+
*/
|
|
28
|
+
function createMoveOperation(type, source, target, options = {}) {
|
|
29
|
+
return {
|
|
30
|
+
type,
|
|
31
|
+
source: {
|
|
32
|
+
filePath: source.filePath,
|
|
33
|
+
startLine: source.startLine,
|
|
34
|
+
endLine: source.endLine,
|
|
35
|
+
content: source.content || null
|
|
36
|
+
},
|
|
37
|
+
target: {
|
|
38
|
+
filePath: target.filePath,
|
|
39
|
+
insertPosition: target.insertPosition || 'end',
|
|
40
|
+
content: target.content || null
|
|
41
|
+
},
|
|
42
|
+
options: {
|
|
43
|
+
updateImports: options.updateImports !== false,
|
|
44
|
+
createBackup: options.createBackup !== false,
|
|
45
|
+
validateSyntax: options.validateSyntax !== false,
|
|
46
|
+
preserveComments: options.preserveComments !== false,
|
|
47
|
+
...options
|
|
48
|
+
},
|
|
49
|
+
metadata: {
|
|
50
|
+
createdAt: new Date().toISOString(),
|
|
51
|
+
id: generateMoveId()
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generate unique move ID
|
|
58
|
+
* @returns {string} - Move ID
|
|
59
|
+
*/
|
|
60
|
+
function generateMoveId() {
|
|
61
|
+
return `move_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extract code segment
|
|
66
|
+
* @param {Array} lines - File lines
|
|
67
|
+
* @param {number} start - Start line
|
|
68
|
+
* @param {number} end - End line
|
|
69
|
+
* @returns {string} - Extracted code
|
|
70
|
+
*/
|
|
71
|
+
function extractCodeSegment(lines, start, end) {
|
|
72
|
+
return lines.slice(start - 1, end).join('\n');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Validate move operation
|
|
77
|
+
* @param {Object} operation - Move operation
|
|
78
|
+
* @returns {Object} - Validation result
|
|
79
|
+
*/
|
|
80
|
+
function validateMoveOperation(operation) {
|
|
81
|
+
const validation = {
|
|
82
|
+
isValid: true,
|
|
83
|
+
errors: [],
|
|
84
|
+
warnings: []
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Check source file exists
|
|
88
|
+
if (!fs.existsSync(operation.source.filePath)) {
|
|
89
|
+
validation.isValid = false;
|
|
90
|
+
validation.errors.push('Source file does not exist');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Check target directory exists
|
|
94
|
+
const targetDir = path.dirname(operation.target.filePath);
|
|
95
|
+
if (!fs.existsSync(targetDir)) {
|
|
96
|
+
validation.isValid = false;
|
|
97
|
+
validation.errors.push('Target directory does not exist');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check line numbers
|
|
101
|
+
if (operation.source.startLine >= operation.source.endLine) {
|
|
102
|
+
validation.isValid = false;
|
|
103
|
+
validation.errors.push('Start line must be less than end line');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check move type
|
|
107
|
+
if (!Object.values(MOVE_TYPES).includes(operation.type)) {
|
|
108
|
+
validation.isValid = false;
|
|
109
|
+
validation.errors.push('Invalid move type');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Warnings
|
|
113
|
+
if (operation.source.endLine - operation.source.startLine > 100) {
|
|
114
|
+
validation.warnings.push('Large code segment (>100 lines)');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return validation;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Calculate import dependencies
|
|
122
|
+
* @param {string} content - Code content
|
|
123
|
+
* @returns {Array} - Array of dependencies
|
|
124
|
+
*/
|
|
125
|
+
function calculateImportDependencies(content) {
|
|
126
|
+
const dependencies = [];
|
|
127
|
+
const lines = content.split('\n');
|
|
128
|
+
|
|
129
|
+
// Find require statements
|
|
130
|
+
lines.forEach(line => {
|
|
131
|
+
const requireMatch = line.match(/require\(['"]([^'"]+)['"]\)/);
|
|
132
|
+
if (requireMatch) {
|
|
133
|
+
dependencies.push({
|
|
134
|
+
type: 'require',
|
|
135
|
+
module: requireMatch[1],
|
|
136
|
+
line: line
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Find import statements
|
|
141
|
+
const importMatch = line.match(/import\s+.*\s+from\s+['"]([^'"]+)['"]/);
|
|
142
|
+
if (importMatch) {
|
|
143
|
+
dependencies.push({
|
|
144
|
+
type: 'import',
|
|
145
|
+
module: importMatch[1],
|
|
146
|
+
line: line
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
return dependencies;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Update import statements
|
|
156
|
+
* @param {string} content - File content
|
|
157
|
+
* @param {Object} changes - Import changes
|
|
158
|
+
* @returns {string} - Updated content
|
|
159
|
+
*/
|
|
160
|
+
function updateImportStatements(content, changes) {
|
|
161
|
+
let updatedContent = content;
|
|
162
|
+
|
|
163
|
+
changes.forEach(change => {
|
|
164
|
+
const { oldPath, newPath, type } = change;
|
|
165
|
+
|
|
166
|
+
if (type === 'require') {
|
|
167
|
+
const regex = new RegExp(`require\\(['"]${oldPath}['"]\\)`, 'g');
|
|
168
|
+
updatedContent = updatedContent.replace(regex, `require('${newPath}')`);
|
|
169
|
+
} else if (type === 'import') {
|
|
170
|
+
const regex = new RegExp(`from\\s+['"]${oldPath}['"]`, 'g');
|
|
171
|
+
updatedContent = updatedContent.replace(regex, `from '${newPath}'`);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return updatedContent;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Create backup of file
|
|
180
|
+
* @param {string} filePath - File path
|
|
181
|
+
* @returns {Promise<string>} - Backup file path
|
|
182
|
+
*/
|
|
183
|
+
async function createFileBackup(filePath) {
|
|
184
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
185
|
+
const backupPath = `${filePath}.backup.${timestamp}`;
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const content = await fs.promises.readFile(filePath, 'utf8');
|
|
189
|
+
await fs.promises.writeFile(backupPath, content, 'utf8');
|
|
190
|
+
return backupPath;
|
|
191
|
+
} catch (error) {
|
|
192
|
+
throw new Error(`Failed to create backup: ${error.message}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Validate syntax of code
|
|
198
|
+
* @param {string} content - Code content
|
|
199
|
+
* @returns {Object} - Syntax validation result
|
|
200
|
+
*/
|
|
201
|
+
function validateCodeSyntax(content) {
|
|
202
|
+
try {
|
|
203
|
+
// Basic syntax check using Function constructor
|
|
204
|
+
new Function(content);
|
|
205
|
+
return {
|
|
206
|
+
isValid: true,
|
|
207
|
+
errors: []
|
|
208
|
+
};
|
|
209
|
+
} catch (error) {
|
|
210
|
+
return {
|
|
211
|
+
isValid: false,
|
|
212
|
+
errors: [{
|
|
213
|
+
message: error.message,
|
|
214
|
+
line: extractErrorLine(error.message)
|
|
215
|
+
}]
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Extract error line from error message
|
|
222
|
+
* @param {string} errorMessage - Error message
|
|
223
|
+
* @returns {number} - Line number
|
|
224
|
+
*/
|
|
225
|
+
function extractErrorLine(errorMessage) {
|
|
226
|
+
const match = errorMessage.match(/at line (\d+)/);
|
|
227
|
+
return match ? parseInt(match[1]) : 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Calculate move impact
|
|
232
|
+
* @param {Object} operation - Move operation
|
|
233
|
+
* @returns {Object} - Impact analysis
|
|
234
|
+
*/
|
|
235
|
+
function calculateMoveImpact(operation) {
|
|
236
|
+
const impact = {
|
|
237
|
+
filesAffected: 1,
|
|
238
|
+
linesMoved: operation.source.endLine - operation.source.startLine + 1,
|
|
239
|
+
dependenciesAffected: 0,
|
|
240
|
+
riskLevel: 'low'
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// Calculate dependencies if source content is available
|
|
244
|
+
if (operation.source.content) {
|
|
245
|
+
const dependencies = calculateImportDependencies(operation.source.content);
|
|
246
|
+
impact.dependenciesAffected = dependencies.length;
|
|
247
|
+
|
|
248
|
+
// Risk assessment
|
|
249
|
+
if (impact.linesMoved > 50) {
|
|
250
|
+
impact.riskLevel = 'high';
|
|
251
|
+
} else if (impact.linesMoved > 20) {
|
|
252
|
+
impact.riskLevel = 'medium';
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return impact;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generate move report
|
|
261
|
+
* @param {Object} operation - Move operation
|
|
262
|
+
* @param {Object} result - Move result
|
|
263
|
+
* @returns {Object} - Move report
|
|
264
|
+
*/
|
|
265
|
+
function generateMoveReport(operation, result) {
|
|
266
|
+
return {
|
|
267
|
+
operation: {
|
|
268
|
+
id: operation.metadata.id,
|
|
269
|
+
type: operation.type,
|
|
270
|
+
executedAt: operation.metadata.createdAt
|
|
271
|
+
},
|
|
272
|
+
result: {
|
|
273
|
+
success: result.success,
|
|
274
|
+
errors: result.errors,
|
|
275
|
+
warnings: result.warnings
|
|
276
|
+
},
|
|
277
|
+
impact: calculateMoveImpact(operation),
|
|
278
|
+
files: {
|
|
279
|
+
source: operation.source.filePath,
|
|
280
|
+
target: operation.target.filePath
|
|
281
|
+
},
|
|
282
|
+
summary: {
|
|
283
|
+
linesMoved: operation.source.endLine - operation.source.startLine + 1,
|
|
284
|
+
duration: result.duration || 0
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Check for circular dependencies
|
|
291
|
+
* @param {Array} dependencies - Array of dependencies
|
|
292
|
+
* @param {string} currentModule - Current module path
|
|
293
|
+
* @returns {boolean} - Has circular dependencies
|
|
294
|
+
*/
|
|
295
|
+
function hasCircularDependencies(dependencies, currentModule) {
|
|
296
|
+
const visited = new Set();
|
|
297
|
+
const recursionStack = new Set();
|
|
298
|
+
|
|
299
|
+
function checkDependency(module) {
|
|
300
|
+
if (recursionStack.has(module)) {
|
|
301
|
+
return true; // Circular dependency detected
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (visited.has(module)) {
|
|
305
|
+
return false; // Already processed
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
visited.add(module);
|
|
309
|
+
recursionStack.add(module);
|
|
310
|
+
|
|
311
|
+
// Find dependencies of this module
|
|
312
|
+
const moduleDeps = dependencies.filter(dep => dep.module === module);
|
|
313
|
+
|
|
314
|
+
for (const dep of moduleDeps) {
|
|
315
|
+
if (checkDependency(dep.module)) {
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
recursionStack.delete(module);
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return checkDependency(currentModule);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Optimize import statements
|
|
329
|
+
* @param {string} content - File content
|
|
330
|
+
* @returns {string} - Optimized content
|
|
331
|
+
*/
|
|
332
|
+
function optimizeImportStatements(content) {
|
|
333
|
+
const lines = content.split('\n');
|
|
334
|
+
const imports = [];
|
|
335
|
+
const nonImportLines = [];
|
|
336
|
+
|
|
337
|
+
// Separate imports from other code
|
|
338
|
+
lines.forEach(line => {
|
|
339
|
+
if (line.includes('require(') || line.includes('import ')) {
|
|
340
|
+
imports.push(line);
|
|
341
|
+
} else {
|
|
342
|
+
nonImportLines.push(line);
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Sort and deduplicate imports
|
|
347
|
+
const sortedImports = [...new Set(imports)].sort();
|
|
348
|
+
|
|
349
|
+
// Reconstruct file
|
|
350
|
+
return [...sortedImports, ...nonImportLines].join('\n');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
module.exports = {
|
|
354
|
+
MOVE_TYPES,
|
|
355
|
+
createMoveOperation,
|
|
356
|
+
generateMoveId,
|
|
357
|
+
extractCodeSegment,
|
|
358
|
+
validateMoveOperation,
|
|
359
|
+
calculateImportDependencies,
|
|
360
|
+
updateImportStatements,
|
|
361
|
+
createFileBackup,
|
|
362
|
+
validateCodeSyntax,
|
|
363
|
+
extractErrorLine,
|
|
364
|
+
calculateMoveImpact,
|
|
365
|
+
generateMoveReport,
|
|
366
|
+
hasCircularDependencies,
|
|
367
|
+
optimizeImportStatements
|
|
368
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation Executor
|
|
3
|
+
*
|
|
4
|
+
* Handles execution of individual refactoring operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { EXECUTION_STATUS } = require('./execution-status');
|
|
8
|
+
const { ExecutionStrategies } = require('./execution-strategies');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Operation executor class
|
|
12
|
+
*/
|
|
13
|
+
class OperationExecutor {
|
|
14
|
+
constructor(executionStrategies) {
|
|
15
|
+
this.executionStrategies = executionStrategies;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Execute a single operation
|
|
20
|
+
*/
|
|
21
|
+
async executeOperation(operation, result) {
|
|
22
|
+
return this.executionStrategies.executeOperation(operation, result);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Execute operations in dependency order
|
|
27
|
+
*/
|
|
28
|
+
async executeOperations(plan, result, options = {}) {
|
|
29
|
+
const executedOperations = new Set();
|
|
30
|
+
let pendingOperations = new Set(plan.operations.keys());
|
|
31
|
+
|
|
32
|
+
while (pendingOperations.size > 0) {
|
|
33
|
+
// Find ready operations
|
|
34
|
+
const readyOperations = Array.from(pendingOperations)
|
|
35
|
+
.map(id => plan.operations.get(id))
|
|
36
|
+
.filter(op => op.isReady(plan.operations) && !executedOperations.has(op.id));
|
|
37
|
+
|
|
38
|
+
if (readyOperations.length === 0) {
|
|
39
|
+
// Check for circular dependencies or blocked operations
|
|
40
|
+
const blockedOps = Array.from(pendingOperations)
|
|
41
|
+
.map(id => plan.operations.get(id))
|
|
42
|
+
.filter(op => !executedOperations.has(op.id));
|
|
43
|
+
|
|
44
|
+
if (blockedOps.length > 0) {
|
|
45
|
+
throw new Error(`Circular dependency detected or operations blocked: ${blockedOps.map(op => op.id).join(', ')}`);
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Execute ready operations (with concurrency limit)
|
|
51
|
+
const batchSize = Math.min(readyOperations.length, options.maxConcurrentOperations || 3);
|
|
52
|
+
const batch = readyOperations.slice(0, batchSize);
|
|
53
|
+
|
|
54
|
+
await Promise.all(batch.map(async operation => {
|
|
55
|
+
try {
|
|
56
|
+
await this.executeOperation(operation, result);
|
|
57
|
+
executedOperations.add(operation.id);
|
|
58
|
+
pendingOperations.delete(operation.id);
|
|
59
|
+
result.executedOperations++;
|
|
60
|
+
} catch (error) {
|
|
61
|
+
result.addError(error);
|
|
62
|
+
result.failedOperations++;
|
|
63
|
+
executedOperations.add(operation.id);
|
|
64
|
+
pendingOperations.delete(operation.id);
|
|
65
|
+
|
|
66
|
+
// Don't continue on error if pauseOnError is enabled
|
|
67
|
+
if (options.pauseOnError) {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
module.exports = { OperationExecutor };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Creator
|
|
3
|
+
*
|
|
4
|
+
* Creates refactoring plans from analysis results.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { RefactoringPlan } = require('./refactoring-plan');
|
|
8
|
+
const { RefactoringOperation } = require('./refactoring-operation');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plan creator class
|
|
12
|
+
*/
|
|
13
|
+
class PlanCreator {
|
|
14
|
+
/**
|
|
15
|
+
* Create refactoring plan from analysis results
|
|
16
|
+
*/
|
|
17
|
+
createPlan(analysisResults, options = {}) {
|
|
18
|
+
const plan = new RefactoringPlan(options.name || 'Auto-generated Plan');
|
|
19
|
+
|
|
20
|
+
// Create operations based on analysis
|
|
21
|
+
for (const analysis of analysisResults.files || []) {
|
|
22
|
+
if (analysis.needsRefactoring) {
|
|
23
|
+
// Add split operation
|
|
24
|
+
const splitOp = new RefactoringOperation('split_file', analysis.filePath, {
|
|
25
|
+
estimatedDuration: 5,
|
|
26
|
+
priority: analysis.urgentRefactoring ? 'high' : 'medium'
|
|
27
|
+
});
|
|
28
|
+
plan.addOperation(splitOp);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return plan;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = { PlanCreator };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Executor
|
|
3
|
+
*
|
|
4
|
+
* Handles execution of refactoring plans.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { EXECUTION_STATUS } = require('./execution-status');
|
|
8
|
+
const { RefactoringExecutorResult } = require('./refactoring-executor-result');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Plan executor class
|
|
12
|
+
*/
|
|
13
|
+
class PlanExecutor {
|
|
14
|
+
constructor(operationExecutor, testRunner, rollbackManager, options = {}) {
|
|
15
|
+
this.operationExecutor = operationExecutor;
|
|
16
|
+
this.testRunner = testRunner;
|
|
17
|
+
this.rollbackManager = rollbackManager;
|
|
18
|
+
this.options = options;
|
|
19
|
+
|
|
20
|
+
this.currentPlan = null;
|
|
21
|
+
this.isExecuting = false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Execute a refactoring plan
|
|
26
|
+
*/
|
|
27
|
+
async executePlan(plan) {
|
|
28
|
+
if (this.isExecuting) {
|
|
29
|
+
throw new Error('Executor is already running a plan');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.currentPlan = plan;
|
|
33
|
+
this.isExecuting = true;
|
|
34
|
+
plan.setStatus(EXECUTION_STATUS.RUNNING);
|
|
35
|
+
|
|
36
|
+
const result = new RefactoringExecutorResult(plan);
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
console.log(`Executing refactoring plan: ${plan.name}`);
|
|
41
|
+
console.log(`Operations: ${plan.operations.size}`);
|
|
42
|
+
|
|
43
|
+
// Run baseline tests if enabled
|
|
44
|
+
if (this.options.runTests) {
|
|
45
|
+
console.log('Running baseline tests...');
|
|
46
|
+
await this.testRunner.runBaseline();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Execute operations in dependency order
|
|
50
|
+
await this.operationExecutor.executeOperations(plan, result, this.options);
|
|
51
|
+
|
|
52
|
+
// Run validation tests if enabled
|
|
53
|
+
if (this.options.runTests) {
|
|
54
|
+
console.log('Running validation tests...');
|
|
55
|
+
const testResult = await this.testRunner.runValidation();
|
|
56
|
+
|
|
57
|
+
if (testResult.hasRegressions) {
|
|
58
|
+
throw new Error('Tests detected regressions after refactoring');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
result.setSuccess(true);
|
|
63
|
+
plan.setStatus(EXECUTION_STATUS.COMPLETED);
|
|
64
|
+
|
|
65
|
+
console.log(`Plan execution completed successfully`);
|
|
66
|
+
|
|
67
|
+
} catch (error) {
|
|
68
|
+
result.addError(error);
|
|
69
|
+
result.setSuccess(false);
|
|
70
|
+
plan.setStatus(EXECUTION_STATUS.FAILED);
|
|
71
|
+
|
|
72
|
+
console.error(`Plan execution failed: ${error.message}`);
|
|
73
|
+
|
|
74
|
+
// Rollback if enabled and there were failures
|
|
75
|
+
if (this.options.enableRollback && result.failedOperations > 0) {
|
|
76
|
+
console.log('Performing rollback...');
|
|
77
|
+
await this.rollbackManager.rollback();
|
|
78
|
+
result.setRollbackPerformed(true);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this.options.pauseOnError) {
|
|
82
|
+
console.log('Execution paused due to error');
|
|
83
|
+
plan.setStatus(EXECUTION_STATUS.PAUSED);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
} finally {
|
|
87
|
+
result.duration = (Date.now() - startTime) / 1000;
|
|
88
|
+
this.isExecuting = false;
|
|
89
|
+
this.currentPlan = null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Cancel current execution
|
|
97
|
+
*/
|
|
98
|
+
async cancelExecution() {
|
|
99
|
+
if (!this.isExecuting || !this.currentPlan) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this.currentPlan.setStatus(EXECUTION_STATUS.CANCELLED);
|
|
104
|
+
this.isExecuting = false;
|
|
105
|
+
|
|
106
|
+
// Cancel running operations
|
|
107
|
+
for (const operation of this.currentPlan.operations.values()) {
|
|
108
|
+
if (operation.status === EXECUTION_STATUS.RUNNING) {
|
|
109
|
+
operation.setStatus(EXECUTION_STATUS.CANCELLED);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get execution status
|
|
118
|
+
*/
|
|
119
|
+
getExecutionStatus() {
|
|
120
|
+
if (!this.currentPlan) {
|
|
121
|
+
return {
|
|
122
|
+
isExecuting: false,
|
|
123
|
+
plan: null,
|
|
124
|
+
progress: 0
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
isExecuting: this.isExecuting,
|
|
130
|
+
plan: {
|
|
131
|
+
id: this.currentPlan.id,
|
|
132
|
+
name: this.currentPlan.name,
|
|
133
|
+
status: this.currentPlan.status,
|
|
134
|
+
progress: this.currentPlan.getProgress(),
|
|
135
|
+
totalOperations: this.currentPlan.operations.size,
|
|
136
|
+
completedOperations: this.currentPlan.getCompletedOperations().length,
|
|
137
|
+
failedOperations: this.currentPlan.getFailedOperations().length
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = { PlanExecutor };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates refactoring plans before execution.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Validates refactoring plans
|
|
9
|
+
*/
|
|
10
|
+
class PlanValidator {
|
|
11
|
+
/**
|
|
12
|
+
* Validate plan before execution
|
|
13
|
+
*/
|
|
14
|
+
validatePlan(plan) {
|
|
15
|
+
const issues = [];
|
|
16
|
+
|
|
17
|
+
// Check for circular dependencies
|
|
18
|
+
const visited = new Set();
|
|
19
|
+
const recursionStack = new Set();
|
|
20
|
+
|
|
21
|
+
function hasCircularDeps(operationId) {
|
|
22
|
+
if (recursionStack.has(operationId)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (visited.has(operationId)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
visited.add(operationId);
|
|
31
|
+
recursionStack.add(operationId);
|
|
32
|
+
|
|
33
|
+
const operation = plan.operations.get(operationId);
|
|
34
|
+
if (operation) {
|
|
35
|
+
for (const depId of operation.dependencies) {
|
|
36
|
+
if (hasCircularDeps(depId)) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
recursionStack.delete(operationId);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const operationId of plan.operations.keys()) {
|
|
47
|
+
if (hasCircularDeps(operationId)) {
|
|
48
|
+
issues.push(`Circular dependency detected for operation: ${operationId}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Check for missing dependencies
|
|
53
|
+
for (const operation of plan.operations.values()) {
|
|
54
|
+
for (const depId of operation.dependencies) {
|
|
55
|
+
if (!plan.operations.has(depId)) {
|
|
56
|
+
issues.push(`Missing dependency: ${depId} for operation: ${operation.id}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
isValid: issues.length === 0,
|
|
63
|
+
issues
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { PlanValidator };
|