vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739

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