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.
Files changed (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
@@ -0,0 +1,568 @@
1
+ /**
2
+ * File Splitter Core
3
+ *
4
+ * Core file splitting logic and operations.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { RollbackManager } = require('../utils/rollback-manager');
10
+ const { SPLIT_TYPES, FileSplitResult, SplitOperation } = require('./file-splitter-types');
11
+
12
+ /**
13
+ * File splitter class
14
+ */
15
+ class FileSplitter {
16
+ constructor(options = {}) {
17
+ this.options = {
18
+ maxModuleSize: 300,
19
+ minModuleSize: 20,
20
+ backupBeforeSplit: true,
21
+ validateAfterSplit: true,
22
+ updateImports: true,
23
+ ...options
24
+ };
25
+
26
+ this.rollbackManager = new RollbackManager();
27
+ }
28
+
29
+ /**
30
+ * Split a file based on analysis results
31
+ */
32
+ async splitFile(fileAnalysis, splitPoints = null) {
33
+ const result = new FileSplitResult(fileAnalysis.filePath);
34
+
35
+ try {
36
+ // Create backup if enabled
37
+ if (this.options.backupBeforeSplit) {
38
+ this.rollbackManager.backupFile(fileAnalysis.filePath);
39
+ }
40
+
41
+ // Read original file
42
+ const originalContent = fs.readFileSync(fileAnalysis.filePath, 'utf8');
43
+ const originalLines = originalContent.split('\n');
44
+
45
+ result.metadata.originalSize = originalLines.length;
46
+
47
+ // Determine split points if not provided
48
+ const points = splitPoints || this.determineSplitPoints(fileAnalysis, originalLines);
49
+
50
+ if (points.length === 0) {
51
+ result.addWarning('No suitable split points found');
52
+ result.setSuccess(true);
53
+ return result;
54
+ }
55
+
56
+ // Execute splits
57
+ const splits = await this.executeSplits(fileAnalysis, originalLines, points);
58
+
59
+ // Update original file
60
+ await this.updateOriginalFile(fileAnalysis.filePath, originalLines, splits);
61
+
62
+ // Update imports in dependent files
63
+ if (this.options.updateImports) {
64
+ await this.updateImports(splits);
65
+ }
66
+
67
+ // Validate results
68
+ if (this.options.validateAfterSplit) {
69
+ await this.validateSplits(splits);
70
+ }
71
+
72
+ // Compile results
73
+ for (const split of splits) {
74
+ if (split.success) {
75
+ result.addSplit(split);
76
+ result.metadata.totalSplitSize += split.metadata.lineCount;
77
+ } else {
78
+ result.addError(new Error(`Split failed: ${split.name}`));
79
+ }
80
+ }
81
+
82
+ result.setSuccess(result.errors.length === 0);
83
+
84
+ } catch (error) {
85
+ result.addError(error);
86
+ result.setSuccess(false);
87
+
88
+ // Rollback on error
89
+ await this.rollbackManager.rollback();
90
+ }
91
+
92
+ return result;
93
+ }
94
+
95
+ /**
96
+ * Determine optimal split points
97
+ */
98
+ determineSplitPoints(fileAnalysis, lines) {
99
+ const splitPoints = [];
100
+ const boundaries = fileAnalysis.boundaries;
101
+
102
+ if (!boundaries || !boundaries.boundaries) {
103
+ return splitPoints;
104
+ }
105
+
106
+ // Find functions that can be extracted
107
+ const functions = boundaries.boundaries.filter(b =>
108
+ b.type === 'function' &&
109
+ b.lineCount >= this.options.minModuleSize &&
110
+ b.lineCount <= this.options.maxModuleSize &&
111
+ b.name !== ''
112
+ );
113
+
114
+ for (const func of functions) {
115
+ splitPoints.push({
116
+ type: SPLIT_TYPES.FUNCTION_EXTRACTION,
117
+ name: func.name,
118
+ startLine: func.startLine,
119
+ endLine: func.endLine,
120
+ suggestedPath: this.suggestOutputPath(fileAnalysis.filePath, func.name, 'function')
121
+ });
122
+ }
123
+
124
+ // Find classes that can be extracted
125
+ const classes = boundaries.boundaries.filter(b =>
126
+ b.type === 'class' &&
127
+ b.lineCount >= this.options.minModuleSize &&
128
+ b.lineCount <= this.options.maxModuleSize &&
129
+ b.name !== ''
130
+ );
131
+
132
+ for (const cls of classes) {
133
+ splitPoints.push({
134
+ type: SPLIT_TYPES.CLASS_EXTRACTION,
135
+ name: cls.name,
136
+ startLine: cls.startLine,
137
+ endLine: cls.endLine,
138
+ suggestedPath: this.suggestOutputPath(fileAnalysis.filePath, cls.name, 'class')
139
+ });
140
+ }
141
+
142
+ // Sort by line number
143
+ return splitPoints.sort((a, b) => a.startLine - b.startLine);
144
+ }
145
+
146
+ /**
147
+ * Execute split operations
148
+ */
149
+ async executeSplits(fileAnalysis, originalLines, splitPoints) {
150
+ const splits = [];
151
+
152
+ for (const splitPoint of splitPoints) {
153
+ try {
154
+ const split = new SplitOperation(
155
+ splitPoint.type,
156
+ splitPoint.name,
157
+ splitPoint.startLine,
158
+ splitPoint.endLine,
159
+ splitPoint.suggestedPath
160
+ );
161
+
162
+ // Extract content
163
+ const content = this.extractContent(originalLines, splitPoint.startLine, splitPoint.endLine);
164
+ split.setContent(content);
165
+
166
+ // Analyze dependencies
167
+ const dependencies = this.analyzeDependencies(content, fileAnalysis.filePath);
168
+ for (const dep of dependencies) {
169
+ split.addDependency(dep);
170
+ }
171
+
172
+ // Analyze exports
173
+ const exports = this.analyzeExports(content);
174
+ for (const exp of exports) {
175
+ split.addExport(exp);
176
+ }
177
+
178
+ // Write split file
179
+ await this.writeSplitFile(split);
180
+
181
+ split.setSuccess(true);
182
+ splits.push(split);
183
+
184
+ } catch (error) {
185
+ const split = new SplitOperation(
186
+ splitPoint.type,
187
+ splitPoint.name,
188
+ splitPoint.startLine,
189
+ splitPoint.endLine,
190
+ splitPoint.suggestedPath
191
+ );
192
+ split.addError(error);
193
+ split.setSuccess(false);
194
+ splits.push(split);
195
+ }
196
+ }
197
+
198
+ return splits;
199
+ }
200
+
201
+ /**
202
+ * Extract content from lines
203
+ */
204
+ extractContent(lines, startLine, endLine) {
205
+ // Convert to 0-based indexing
206
+ const startIndex = startLine - 1;
207
+ const endIndex = Math.min(endLine, lines.length);
208
+
209
+ return lines.slice(startIndex, endIndex).join('\n');
210
+ }
211
+
212
+ /**
213
+ * Analyze dependencies in extracted content
214
+ */
215
+ analyzeDependencies(content, originalFilePath) {
216
+ const dependencies = [];
217
+ const lines = content.split('\n');
218
+
219
+ for (const line of lines) {
220
+ const trimmed = line.trim();
221
+
222
+ // Find import statements
223
+ if (trimmed.startsWith('import ')) {
224
+ const match = trimmed.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
225
+ if (match) {
226
+ dependencies.push({
227
+ type: 'import',
228
+ path: match[1],
229
+ isRelative: match[1].startsWith('./') || match[1].startsWith('../')
230
+ });
231
+ }
232
+ }
233
+
234
+ // Find require statements
235
+ if (trimmed.startsWith('const ') && trimmed.includes('require(')) {
236
+ const match = trimmed.match(/require\(['"]([^'"]+)['"]\)/);
237
+ if (match) {
238
+ dependencies.push({
239
+ type: 'require',
240
+ path: match[1],
241
+ isRelative: match[1].startsWith('./') || match[1].startsWith('../')
242
+ });
243
+ }
244
+ }
245
+ }
246
+
247
+ return dependencies;
248
+ }
249
+
250
+ /**
251
+ * Analyze exports in extracted content
252
+ */
253
+ analyzeExports(content) {
254
+ const exports = [];
255
+ const lines = content.split('\n');
256
+
257
+ for (const line of lines) {
258
+ const trimmed = line.trim();
259
+
260
+ // Find export statements
261
+ if (trimmed.startsWith('export ')) {
262
+ // Named exports
263
+ const namedMatch = trimmed.match(/export\s+(?:const|let|var|function|class)\s+(\w+)/);
264
+ if (namedMatch) {
265
+ exports.push({
266
+ type: 'named',
267
+ name: namedMatch[1],
268
+ isDefault: false
269
+ });
270
+ }
271
+
272
+ // Default exports
273
+ if (trimmed.includes('export default')) {
274
+ const defaultMatch = trimmed.match(/export default\s+(?:function|class)?\s*(\w+)?/);
275
+ const name = defaultMatch ? defaultMatch[1] : 'default';
276
+ exports.push({
277
+ type: 'default',
278
+ name,
279
+ isDefault: true
280
+ });
281
+ }
282
+ }
283
+ }
284
+
285
+ return exports;
286
+ }
287
+
288
+ /**
289
+ * Write split file
290
+ */
291
+ async writeSplitFile(split) {
292
+ // Ensure output directory exists
293
+ const outputDir = path.dirname(split.outputPath);
294
+ if (!fs.existsSync(outputDir)) {
295
+ fs.mkdirSync(outputDir, { recursive: true });
296
+ }
297
+
298
+ // Generate file content with proper imports/exports
299
+ const fileContent = this.generateSplitFileContent(split);
300
+
301
+ fs.writeFileSync(split.outputPath, fileContent, 'utf8');
302
+ }
303
+
304
+ /**
305
+ * Generate content for split file
306
+ */
307
+ generateSplitFileContent(split) {
308
+ let content = '';
309
+
310
+ // Add dependencies
311
+ for (const dep of split.dependencies) {
312
+ if (dep.type === 'import') {
313
+ content += `import ${dep.path};\n`;
314
+ } else if (dep.type === 'require') {
315
+ content += `const ${dep.path} = require('${dep.path}');\n`;
316
+ }
317
+ }
318
+
319
+ if (split.dependencies.length > 0) {
320
+ content += '\n';
321
+ }
322
+
323
+ // Add the extracted content
324
+ content += split.content;
325
+
326
+ // Add exports if needed
327
+ if (split.exports.length > 0) {
328
+ content += '\n\n';
329
+ for (const exp of split.exports) {
330
+ if (exp.isDefault) {
331
+ content += `export default ${exp.name};\n`;
332
+ } else {
333
+ content += `export { ${exp.name} };\n`;
334
+ }
335
+ }
336
+ }
337
+
338
+ return content;
339
+ }
340
+
341
+ /**
342
+ * Update original file to remove extracted content
343
+ */
344
+ async updateOriginalFile(filePath, originalLines, splits) {
345
+ // Mark lines to remove
346
+ const linesToRemove = new Set();
347
+
348
+ for (const split of splits) {
349
+ if (split.success) {
350
+ for (let i = split.startLine - 1; i < split.endLine; i++) {
351
+ linesToRemove.add(i);
352
+ }
353
+ }
354
+ }
355
+
356
+ // Create new content
357
+ const newLines = originalLines.filter((_, index) => !linesToRemove.has(index));
358
+
359
+ // Add import statements for extracted modules
360
+ const importStatements = this.generateImportStatements(splits);
361
+ if (importStatements.length > 0) {
362
+ newLines.unshift(...importStatements);
363
+ }
364
+
365
+ // Write updated file
366
+ const newContent = newLines.join('\n');
367
+ fs.writeFileSync(filePath, newContent, 'utf8');
368
+ }
369
+
370
+ /**
371
+ * Generate import statements for extracted modules
372
+ */
373
+ generateImportStatements(splits) {
374
+ const imports = [];
375
+
376
+ for (const split of splits) {
377
+ if (!split.success) continue;
378
+
379
+ const relativePath = path.relative(
380
+ path.dirname(split.outputPath),
381
+ path.dirname(split.outputPath) // This should be original file's directory
382
+ ).replace(/\\/g, '/');
383
+
384
+ for (const exp of split.exports) {
385
+ if (exp.isDefault) {
386
+ imports.push(`import ${exp.name} from './${relativePath}/${path.basename(split.outputPath, '.js')}';`);
387
+ } else {
388
+ imports.push(`import { ${exp.name} } from './${relativePath}/${path.basename(split.outputPath, '.js')}';`);
389
+ }
390
+ }
391
+ }
392
+
393
+ return imports.length > 0 ? [''] : imports;
394
+ }
395
+
396
+ /**
397
+ * Update imports in dependent files
398
+ */
399
+ async updateImports(splits) {
400
+ // This would analyze the codebase for files that import from the original file
401
+ // and update their import statements to include the new split files
402
+ // For now, this is a placeholder implementation
403
+
404
+ for (const split of splits) {
405
+ if (!split.success) continue;
406
+
407
+ // Find files that might need import updates
408
+ const dependentFiles = this.findDependentFiles(split.outputPath);
409
+
410
+ for (const depFile of dependentFiles) {
411
+ await this.updateFileImports(depFile, split);
412
+ }
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Find files that depend on a split file
418
+ */
419
+ findDependentFiles(splitFilePath) {
420
+ // Placeholder implementation - would search codebase for imports
421
+ return [];
422
+ }
423
+
424
+ /**
425
+ * Update imports in a specific file
426
+ */
427
+ async updateFileImports(filePath, split) {
428
+ // Placeholder implementation - would update import statements
429
+ }
430
+
431
+ /**
432
+ * Validate split results
433
+ */
434
+ async validateSplits(splits) {
435
+ for (const split of splits) {
436
+ if (!split.success) continue;
437
+
438
+ try {
439
+ // Check if file exists and is readable
440
+ if (!fs.existsSync(split.outputPath)) {
441
+ throw new Error(`Split file not created: ${split.outputPath}`);
442
+ }
443
+
444
+ // Check file size
445
+ const stats = fs.statSync(split.outputPath);
446
+ const content = fs.readFileSync(split.outputPath, 'utf8');
447
+ const lineCount = content.split('\n').length;
448
+
449
+ if (lineCount > this.options.maxModuleSize) {
450
+ split.addError(new Error(`Split file too large: ${lineCount} lines`));
451
+ }
452
+
453
+ // Basic syntax validation
454
+ if (split.outputPath.endsWith('.js')) {
455
+ this.validateJavaScriptSyntax(content);
456
+ }
457
+
458
+ } catch (error) {
459
+ split.addError(error);
460
+ }
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Validate JavaScript syntax
466
+ */
467
+ validateJavaScriptSyntax(content) {
468
+ try {
469
+ const vm = require('vm');
470
+ new vm.Script(content, { filename: 'validation' });
471
+ } catch (error) {
472
+ throw new Error(`Syntax validation failed: ${error.message}`);
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Suggest output path for split
478
+ */
479
+ suggestOutputPath(originalPath, name, type) {
480
+ const dir = path.dirname(originalPath);
481
+ const baseName = name.toLowerCase().replace(/[^a-z0-9]/g, '-');
482
+ return path.join(dir, `${baseName}.js`);
483
+ }
484
+
485
+ /**
486
+ * Batch split multiple files
487
+ */
488
+ async splitFiles(fileAnalyses) {
489
+ const results = [];
490
+
491
+ for (const analysis of fileAnalyses) {
492
+ const result = await this.splitFile(analysis);
493
+ results.push(result);
494
+ }
495
+
496
+ return results;
497
+ }
498
+
499
+ /**
500
+ * Preview split operations without executing
501
+ */
502
+ previewSplits(fileAnalysis) {
503
+ const originalContent = fs.readFileSync(fileAnalysis.filePath, 'utf8');
504
+ const originalLines = originalContent.split('\n');
505
+
506
+ const splitPoints = this.determineSplitPoints(fileAnalysis, originalLines);
507
+ const previews = [];
508
+
509
+ for (const splitPoint of splitPoints) {
510
+ const content = this.extractContent(originalLines, splitPoint.startLine, splitPoint.endLine);
511
+ const dependencies = this.analyzeDependencies(content, fileAnalysis.filePath);
512
+ const exports = this.analyzeExports(content);
513
+
514
+ previews.push({
515
+ type: splitPoint.type,
516
+ name: splitPoint.name,
517
+ startLine: splitPoint.startLine,
518
+ endLine: splitPoint.endLine,
519
+ lineCount: splitPoint.endLine - splitPoint.startLine + 1,
520
+ outputPath: splitPoint.suggestedPath,
521
+ dependencies,
522
+ exports,
523
+ preview: content.split('\n').slice(0, 5).join('\n') + (content.split('\n').length > 5 ? '\n...' : '')
524
+ });
525
+ }
526
+
527
+ return previews;
528
+ }
529
+
530
+ /**
531
+ * Get split statistics
532
+ */
533
+ getStatistics(results) {
534
+ const stats = {
535
+ totalFiles: results.length,
536
+ successfulSplits: 0,
537
+ failedSplits: 0,
538
+ totalSplits: 0,
539
+ averageSplitsPerFile: 0,
540
+ totalLinesExtracted: 0,
541
+ errors: [],
542
+ warnings: []
543
+ };
544
+
545
+ for (const result of results) {
546
+ if (result.success) {
547
+ stats.successfulSplits++;
548
+ } else {
549
+ stats.failedSplits++;
550
+ }
551
+
552
+ stats.totalSplits += result.metadata.splitCount;
553
+ stats.totalLinesExtracted += result.metadata.totalSplitSize;
554
+
555
+ stats.errors.push(...result.errors);
556
+ stats.warnings.push(...result.warnings);
557
+ }
558
+
559
+ stats.averageSplitsPerFile = results.length > 0 ?
560
+ stats.totalSplits / results.length : 0;
561
+
562
+ return stats;
563
+ }
564
+ }
565
+
566
+ module.exports = {
567
+ FileSplitter
568
+ };
@@ -0,0 +1,136 @@
1
+ /**
2
+ * File Splitter Types
3
+ *
4
+ * Contains data structures and constants for file splitting operations.
5
+ */
6
+
7
+ /**
8
+ * Split operation types
9
+ */
10
+ const SPLIT_TYPES = {
11
+ FUNCTION_EXTRACTION: 'function_extraction',
12
+ CLASS_EXTRACTION: 'class_extraction',
13
+ MODULE_EXTRACTION: 'module_extraction',
14
+ UTILITY_EXTRACTION: 'utility_extraction',
15
+ CONSTANT_EXTRACTION: 'constant_extraction'
16
+ };
17
+
18
+ /**
19
+ * File split result class
20
+ */
21
+ class FileSplitResult {
22
+ constructor(originalFile) {
23
+ this.originalFile = originalFile;
24
+ this.splits = [];
25
+ this.success = false;
26
+ this.errors = [];
27
+ this.warnings = [];
28
+ this.metadata = {
29
+ createdAt: new Date().toISOString(),
30
+ originalSize: 0,
31
+ totalSplitSize: 0,
32
+ splitCount: 0
33
+ };
34
+ }
35
+
36
+ addSplit(split) {
37
+ this.splits.push(split);
38
+ this.metadata.splitCount++;
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
+ getSummary() {
61
+ return {
62
+ originalFile: this.originalFile,
63
+ success: this.success,
64
+ splitCount: this.metadata.splitCount,
65
+ originalSize: this.metadata.originalSize,
66
+ totalSplitSize: this.metadata.totalSplitSize,
67
+ errorCount: this.errors.length,
68
+ warningCount: this.warnings.length,
69
+ splits: this.splits.map(split => split.getSummary())
70
+ };
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Split operation class
76
+ */
77
+ class SplitOperation {
78
+ constructor(type, name, startLine, endLine, outputPath) {
79
+ this.type = type;
80
+ this.name = name;
81
+ this.startLine = startLine;
82
+ this.endLine = endLine;
83
+ this.outputPath = outputPath;
84
+ this.content = '';
85
+ this.dependencies = [];
86
+ this.exports = [];
87
+ this.success = false;
88
+ this.errors = [];
89
+ this.metadata = {
90
+ createdAt: new Date().toISOString(),
91
+ lineCount: endLine - startLine + 1
92
+ };
93
+ }
94
+
95
+ setContent(content) {
96
+ this.content = content;
97
+ }
98
+
99
+ addDependency(dependency) {
100
+ this.dependencies.push(dependency);
101
+ }
102
+
103
+ addExport(exportName) {
104
+ this.exports.push(exportName);
105
+ }
106
+
107
+ setSuccess(success) {
108
+ this.success = success;
109
+ }
110
+
111
+ addError(error) {
112
+ this.errors.push({
113
+ message: error.message,
114
+ timestamp: new Date().toISOString()
115
+ });
116
+ }
117
+
118
+ getSummary() {
119
+ return {
120
+ type: this.type,
121
+ name: this.name,
122
+ outputPath: this.outputPath,
123
+ lineCount: this.metadata.lineCount,
124
+ success: this.success,
125
+ dependencyCount: this.dependencies.length,
126
+ exportCount: this.exports.length,
127
+ errorCount: this.errors.length
128
+ };
129
+ }
130
+ }
131
+
132
+ module.exports = {
133
+ SPLIT_TYPES,
134
+ FileSplitResult,
135
+ SplitOperation
136
+ };