vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,774 @@
1
+ /**
2
+ * Import Manager
3
+ *
4
+ * Manages import statement updates during refactoring operations.
5
+ * Handles import resolution, organization, and dependency tracking.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ /**
12
+ * Import types
13
+ */
14
+ const IMPORT_TYPES = {
15
+ ES6_IMPORT: 'es6_import',
16
+ COMMONJS_REQUIRE: 'commonjs_require',
17
+ DYNAMIC_IMPORT: 'dynamic_import',
18
+ TYPESCRIPT_IMPORT: 'typescript_import'
19
+ };
20
+
21
+ /**
22
+ * Import statement class
23
+ */
24
+ class ImportStatement {
25
+ constructor(type, module, specifier = null, isDefault = false) {
26
+ this.type = type;
27
+ this.module = module;
28
+ this.specifier = specifier;
29
+ this.isDefault = isDefault;
30
+ this.isTypeOnly = false;
31
+ this.isRelative = this.isRelativeModule(module);
32
+ this.originalStatement = '';
33
+ this.lineNumber = 0;
34
+ this.metadata = {
35
+ createdAt: new Date().toISOString(),
36
+ used: false,
37
+ unused: false
38
+ };
39
+ }
40
+
41
+ isRelativeModule(module) {
42
+ return module.startsWith('./') || module.startsWith('../');
43
+ }
44
+
45
+ setOriginalStatement(statement) {
46
+ this.originalStatement = statement;
47
+ }
48
+
49
+ setLineNumber(lineNumber) {
50
+ this.lineNumber = lineNumber;
51
+ }
52
+
53
+ setTypeOnly(isTypeOnly) {
54
+ this.isTypeOnly = isTypeOnly;
55
+ }
56
+
57
+ setUsed(used) {
58
+ this.metadata.used = used;
59
+ }
60
+
61
+ setUnused(unused) {
62
+ this.metadata.unused = unused;
63
+ }
64
+
65
+ generateStatement() {
66
+ switch (this.type) {
67
+ case IMPORT_TYPES.ES6_IMPORT:
68
+ if (this.isDefault) {
69
+ return `import ${this.specifier} from '${this.module}';`;
70
+ } else if (this.specifier) {
71
+ return `import { ${this.specifier} } from '${this.module}';`;
72
+ } else {
73
+ return `import '${this.module}';`;
74
+ }
75
+
76
+ case IMPORT_TYPES.COMMONJS_REQUIRE:
77
+ if (this.specifier) {
78
+ return `const ${this.specifier} = require('${this.module}');`;
79
+ } else {
80
+ return `require('${this.module}');`;
81
+ }
82
+
83
+ case IMPORT_TYPES.DYNAMIC_IMPORT:
84
+ return `import('${this.module}')`;
85
+
86
+ case IMPORT_TYPES.TYPESCRIPT_IMPORT:
87
+ const typePrefix = this.isTypeOnly ? 'type ' : '';
88
+ if (this.isDefault) {
89
+ return `import ${typePrefix}${this.specifier} from '${this.module}';`;
90
+ } else if (this.specifier) {
91
+ return `import ${typePrefix}{ ${this.specifier} } from '${this.module}';`;
92
+ } else {
93
+ return `import '${this.module}';`;
94
+ }
95
+
96
+ default:
97
+ return this.originalStatement;
98
+ }
99
+ }
100
+
101
+ getSummary() {
102
+ return {
103
+ type: this.type,
104
+ module: this.module,
105
+ specifier: this.specifier,
106
+ isDefault: this.isDefault,
107
+ isRelative: this.isRelative,
108
+ isUsed: this.metadata.used,
109
+ isUnused: this.metadata.unused,
110
+ lineNumber: this.lineNumber
111
+ };
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Import manager result class
117
+ */
118
+ class ImportManagerResult {
119
+ constructor(filePath) {
120
+ this.filePath = filePath;
121
+ this.originalImports = [];
122
+ this.updatedImports = [];
123
+ this.addedImports = [];
124
+ this.removedImports = [];
125
+ this.unusedImports = [];
126
+ this.success = false;
127
+ this.errors = [];
128
+ this.warnings = [];
129
+ this.metadata = {
130
+ processedAt: new Date().toISOString(),
131
+ importsAdded: 0,
132
+ importsRemoved: 0,
133
+ importsUpdated: 0
134
+ };
135
+ }
136
+
137
+ addOriginalImport(importStmt) {
138
+ this.originalImports.push(importStmt);
139
+ }
140
+
141
+ addUpdatedImport(importStmt) {
142
+ this.updatedImports.push(importStmt);
143
+ }
144
+
145
+ addAddedImport(importStmt) {
146
+ this.addedImports.push(importStmt);
147
+ this.metadata.importsAdded++;
148
+ }
149
+
150
+ addRemovedImport(importStmt) {
151
+ this.removedImports.push(importStmt);
152
+ this.metadata.importsRemoved++;
153
+ }
154
+
155
+ addUnusedImport(importStmt) {
156
+ this.unusedImports.push(importStmt);
157
+ }
158
+
159
+ addError(error) {
160
+ this.errors.push({
161
+ message: error.message,
162
+ timestamp: new Date().toISOString()
163
+ });
164
+ }
165
+
166
+ addWarning(warning) {
167
+ this.warnings.push({
168
+ message: warning,
169
+ timestamp: new Date().toISOString()
170
+ });
171
+ }
172
+
173
+ setSuccess(success) {
174
+ this.success = success;
175
+ }
176
+
177
+ getSummary() {
178
+ return {
179
+ filePath: this.filePath,
180
+ success: this.success,
181
+ originalImportCount: this.originalImports.length,
182
+ updatedImportCount: this.updatedImports.length,
183
+ addedImportCount: this.addedImports.length,
184
+ removedImportCount: this.removedImports.length,
185
+ unusedImportCount: this.unusedImports.length,
186
+ errorCount: this.errors.length,
187
+ warningCount: this.warnings.length
188
+ };
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Import manager class
194
+ */
195
+ class ImportManager {
196
+ constructor(options = {}) {
197
+ this.options = {
198
+ organizeImports: true,
199
+ removeUnused: true,
200
+ sortImports: true,
201
+ groupImports: true,
202
+ preserveComments: true,
203
+ updateRelativePaths: true,
204
+ ...options
205
+ };
206
+ }
207
+
208
+ /**
209
+ * Update imports in a file after refactoring
210
+ */
211
+ async updateImports(filePath, changes = []) {
212
+ const result = new ImportManagerResult(filePath);
213
+
214
+ try {
215
+ // Read file content
216
+ const content = fs.readFileSync(filePath, 'utf8');
217
+ const lines = content.split('\n');
218
+
219
+ // Parse existing imports
220
+ const existingImports = this.parseImports(lines);
221
+ for (const imp of existingImports) {
222
+ result.addOriginalImport(imp);
223
+ }
224
+
225
+ // Apply changes
226
+ const updatedImports = this.applyChanges(existingImports, changes);
227
+
228
+ // Detect unused imports
229
+ const unusedImports = this.detectUnusedImports(content, updatedImports);
230
+ for (const imp of unusedImports) {
231
+ result.addUnusedImport(imp);
232
+ }
233
+
234
+ // Remove unused if enabled
235
+ let finalImports = updatedImports;
236
+ if (this.options.removeUnused) {
237
+ finalImports = updatedImports.filter(imp => !unusedImports.includes(imp));
238
+ for (const imp of unusedImports) {
239
+ result.addRemovedImport(imp);
240
+ }
241
+ }
242
+
243
+ // Organize imports if enabled
244
+ if (this.options.organizeImports) {
245
+ finalImports = this.organizeImports(finalImports);
246
+ }
247
+
248
+ // Generate updated content
249
+ const updatedContent = this.generateUpdatedContent(content, existingImports, finalImports);
250
+
251
+ // Write updated file
252
+ fs.writeFileSync(filePath, updatedContent, 'utf8');
253
+
254
+ // Set results
255
+ for (const imp of finalImports) {
256
+ result.addUpdatedImport(imp);
257
+ }
258
+
259
+ result.setSuccess(true);
260
+
261
+ } catch (error) {
262
+ result.addError(error);
263
+ result.setSuccess(false);
264
+ }
265
+
266
+ return result;
267
+ }
268
+
269
+ /**
270
+ * Parse import statements from file lines
271
+ */
272
+ parseImports(lines) {
273
+ const imports = [];
274
+
275
+ for (let i = 0; i < lines.length; i++) {
276
+ const line = lines[i].trim();
277
+
278
+ // ES6 imports
279
+ const es6Match = line.match(/^import\s+(.+?)\s+from\s+['"]([^'"]+)['"];?\s*$/);
280
+ if (es6Match) {
281
+ const importStmt = new ImportStatement(IMPORT_TYPES.ES6_IMPORT, es6Match[2]);
282
+ importStmt.setOriginalStatement(line);
283
+ importStmt.setLineNumber(i + 1);
284
+
285
+ // Parse specifier
286
+ const specifierPart = es6Match[1].trim();
287
+ if (specifierPart.startsWith('type ')) {
288
+ importStmt.setTypeOnly(true);
289
+ importStmt.type = IMPORT_TYPES.TYPESCRIPT_IMPORT;
290
+ }
291
+
292
+ if (specifierPart === 'default' || !specifierPart.includes('{')) {
293
+ importStmt.isDefault = true;
294
+ importStmt.specifier = specifierPart.replace('type ', '').trim();
295
+ } else {
296
+ const namedMatch = specifierPart.match(/\{\s*(.+?)\s*\}/);
297
+ if (namedMatch) {
298
+ importStmt.specifier = namedMatch[1].trim();
299
+ }
300
+ }
301
+
302
+ imports.push(importStmt);
303
+ continue;
304
+ }
305
+
306
+ // CommonJS requires
307
+ const cjsMatch = line.match(/^const\s+(.+?)\s*=\s*require\s*\(\s*['"]([^'"]+)['"]\s*\);?\s*$/);
308
+ if (cjsMatch) {
309
+ const importStmt = new ImportStatement(IMPORT_TYPES.COMMONJS_REQUIRE, cjsMatch[2]);
310
+ importStmt.setOriginalStatement(line);
311
+ importStmt.setLineNumber(i + 1);
312
+ importStmt.specifier = cjsMatch[1].trim();
313
+ imports.push(importStmt);
314
+ continue;
315
+ }
316
+
317
+ // Bare require
318
+ const bareRequireMatch = line.match(/^require\s*\(\s*['"]([^'"]+)['"]\s*\);?\s*$/);
319
+ if (bareRequireMatch) {
320
+ const importStmt = new ImportStatement(IMPORT_TYPES.COMMONJS_REQUIRE, bareRequireMatch[1]);
321
+ importStmt.setOriginalStatement(line);
322
+ importStmt.setLineNumber(i + 1);
323
+ imports.push(importStmt);
324
+ continue;
325
+ }
326
+
327
+ // Dynamic imports
328
+ const dynamicMatch = line.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
329
+ if (dynamicMatch) {
330
+ const importStmt = new ImportStatement(IMPORT_TYPES.DYNAMIC_IMPORT, dynamicMatch[1]);
331
+ importStmt.setOriginalStatement(line);
332
+ importStmt.setLineNumber(i + 1);
333
+ imports.push(importStmt);
334
+ }
335
+ }
336
+
337
+ return imports;
338
+ }
339
+
340
+ /**
341
+ * Apply changes to imports
342
+ */
343
+ applyChanges(existingImports, changes) {
344
+ let updatedImports = [...existingImports];
345
+
346
+ for (const change of changes) {
347
+ switch (change.type) {
348
+ case 'add':
349
+ const newImport = this.createImportFromChange(change);
350
+ if (newImport && !this.importExists(updatedImports, newImport)) {
351
+ updatedImports.push(newImport);
352
+ }
353
+ break;
354
+
355
+ case 'remove':
356
+ updatedImports = updatedImports.filter(imp =>
357
+ imp.module !== change.module &&
358
+ imp.specifier !== change.specifier
359
+ );
360
+ break;
361
+
362
+ case 'update':
363
+ updatedImports = updatedImports.map(imp => {
364
+ if (imp.module === change.oldModule && imp.specifier === change.oldSpecifier) {
365
+ const updatedImport = new ImportStatement(imp.type, change.newModule || imp.module, change.newSpecifier || imp.specifier, imp.isDefault);
366
+ updatedImport.setLineNumber(imp.lineNumber);
367
+ return updatedImport;
368
+ }
369
+ return imp;
370
+ });
371
+ break;
372
+
373
+ case 'move':
374
+ // Update relative paths for moved files
375
+ if (change.oldPath && change.newPath) {
376
+ updatedImports = updatedImports.map(imp => {
377
+ if (imp.isRelative && imp.module.includes(change.oldPath)) {
378
+ const updatedPath = this.updateRelativePath(imp.module, change.oldPath, change.newPath);
379
+ const updatedImport = new ImportStatement(imp.type, updatedPath, imp.specifier, imp.isDefault);
380
+ updatedImport.setLineNumber(imp.lineNumber);
381
+ return updatedImport;
382
+ }
383
+ return imp;
384
+ });
385
+ }
386
+ break;
387
+ }
388
+ }
389
+
390
+ return updatedImports;
391
+ }
392
+
393
+ /**
394
+ * Create import from change object
395
+ */
396
+ createImportFromChange(change) {
397
+ const type = change.importType || IMPORT_TYPES.ES6_IMPORT;
398
+ const importStmt = new ImportStatement(type, change.module, change.specifier, change.isDefault);
399
+
400
+ if (change.isTypeOnly) {
401
+ importStmt.setTypeOnly(true);
402
+ if (type === IMPORT_TYPES.ES6_IMPORT) {
403
+ importStmt.type = IMPORT_TYPES.TYPESCRIPT_IMPORT;
404
+ }
405
+ }
406
+
407
+ return importStmt;
408
+ }
409
+
410
+ /**
411
+ * Check if import already exists
412
+ */
413
+ importExists(imports, newImport) {
414
+ return imports.some(imp =>
415
+ imp.module === newImport.module &&
416
+ imp.specifier === newImport.specifier &&
417
+ imp.type === newImport.type
418
+ );
419
+ }
420
+
421
+ /**
422
+ * Update relative path
423
+ */
424
+ updateRelativePath(currentPath, oldBasePath, newBasePath) {
425
+ // Resolve the current path relative to old base
426
+ const absolutePath = path.resolve(path.dirname(oldBasePath), currentPath);
427
+
428
+ // Calculate new relative path
429
+ const newRelativePath = path.relative(path.dirname(newBasePath), absolutePath);
430
+
431
+ // Ensure forward slashes and add ./ if needed
432
+ const normalizedPath = newRelativePath.replace(/\\/g, '/');
433
+ return normalizedPath.startsWith('.') ? normalizedPath : `./${normalizedPath}`;
434
+ }
435
+
436
+ /**
437
+ * Detect unused imports
438
+ */
439
+ detectUnusedImports(content, imports) {
440
+ const unused = [];
441
+
442
+ for (const imp of imports) {
443
+ if (!this.isImportUsed(content, imp)) {
444
+ imp.setUnused(true);
445
+ unused.push(imp);
446
+ } else {
447
+ imp.setUsed(true);
448
+ }
449
+ }
450
+
451
+ return unused;
452
+ }
453
+
454
+ /**
455
+ * Check if import is used in content
456
+ */
457
+ isImportUsed(content, importStmt) {
458
+ if (!importStmt.specifier) {
459
+ // Side-effect imports are always considered used
460
+ return true;
461
+ }
462
+
463
+ // For default imports, check for the specifier name
464
+ if (importStmt.isDefault) {
465
+ const regex = new RegExp(`\\b${importStmt.specifier}\\b`, 'g');
466
+ return regex.test(content);
467
+ }
468
+
469
+ // For named imports, check each imported name
470
+ const names = importStmt.specifier.split(',').map(name => name.trim().split(' as ')[0]);
471
+ for (const name of names) {
472
+ const regex = new RegExp(`\\b${name}\\b`, 'g');
473
+ if (regex.test(content)) {
474
+ return true;
475
+ }
476
+ }
477
+
478
+ return false;
479
+ }
480
+
481
+ /**
482
+ * Organize imports
483
+ */
484
+ organizeImports(imports) {
485
+ if (!this.options.sortImports && !this.options.groupImports) {
486
+ return imports;
487
+ }
488
+
489
+ // Group imports by type and source
490
+ const groups = {
491
+ node_builtin: [],
492
+ third_party: [],
493
+ relative: [],
494
+ absolute: [],
495
+ type: [],
496
+ other: []
497
+ };
498
+
499
+ for (const imp of imports) {
500
+ const group = this.getImportGroup(imp);
501
+ groups[group].push(imp);
502
+ }
503
+
504
+ // Sort within groups
505
+ if (this.options.sortImports) {
506
+ for (const group of Object.values(groups)) {
507
+ group.sort((a, b) => {
508
+ // Sort by module, then by specifier
509
+ if (a.module !== b.module) {
510
+ return a.module.localeCompare(b.module);
511
+ }
512
+ return (a.specifier || '').localeCompare(b.specifier || '');
513
+ });
514
+ }
515
+ }
516
+
517
+ // Flatten groups
518
+ const organized = [];
519
+ const groupOrder = ['node_builtin', 'third_party', 'absolute', 'relative', 'type', 'other'];
520
+
521
+ for (const groupName of groupOrder) {
522
+ if (groups[groupName].length > 0) {
523
+ organized.push(...groups[groupName]);
524
+ }
525
+ }
526
+
527
+ return organized;
528
+ }
529
+
530
+ /**
531
+ * Get import group for an import
532
+ */
533
+ getImportGroup(importStmt) {
534
+ if (importStmt.isTypeOnly) {
535
+ return 'type';
536
+ }
537
+
538
+ if (importStmt.isRelative) {
539
+ return 'relative';
540
+ }
541
+
542
+ // Node.js built-in modules
543
+ const nodeBuiltins = [
544
+ 'fs', 'path', 'http', 'https', 'url', 'querystring', 'util', 'events',
545
+ 'stream', 'buffer', 'child_process', 'cluster', 'os', 'crypto', 'tls',
546
+ 'net', 'dgram', 'dns', 'readline', 'repl', 'vm', 'zlib', 'console'
547
+ ];
548
+
549
+ if (nodeBuiltins.includes(importStmt.module)) {
550
+ return 'node_builtin';
551
+ }
552
+
553
+ // Third-party (starts with @ or doesn't contain .)
554
+ if (importStmt.module.startsWith('@') || !importStmt.module.includes('.')) {
555
+ return 'third_party';
556
+ }
557
+
558
+ // Absolute paths
559
+ if (importStmt.module.startsWith('/')) {
560
+ return 'absolute';
561
+ }
562
+
563
+ return 'other';
564
+ }
565
+
566
+ /**
567
+ * Generate updated content with new imports
568
+ */
569
+ generateUpdatedContent(originalContent, originalImports, updatedImports) {
570
+ const lines = originalContent.split('\n');
571
+
572
+ // Find import section
573
+ const importSection = this.findImportSection(lines, originalImports);
574
+
575
+ if (importSection.start === -1) {
576
+ // No imports found, add at the beginning
577
+ const importLines = updatedImports.map(imp => imp.generateStatement());
578
+ return [...importLines, '', ...lines].join('\n');
579
+ }
580
+
581
+ // Replace import section
582
+ const beforeImports = lines.slice(0, importSection.start);
583
+ const afterImports = lines.slice(importSection.end + 1);
584
+
585
+ const importLines = updatedImports.map(imp => imp.generateStatement());
586
+
587
+ // Add empty lines around imports if they don't exist
588
+ if (importLines.length > 0) {
589
+ if (beforeImports.length > 0 && beforeImports[beforeImports.length - 1].trim() !== '') {
590
+ importLines.unshift('');
591
+ }
592
+ if (afterImports.length > 0 && afterImports[0].trim() !== '') {
593
+ importLines.push('');
594
+ }
595
+ }
596
+
597
+ return [...beforeImports, ...importLines, ...afterImports].join('\n');
598
+ }
599
+
600
+ /**
601
+ * Find import section in lines
602
+ */
603
+ findImportSection(lines, imports) {
604
+ if (imports.length === 0) {
605
+ return { start: -1, end: -1 };
606
+ }
607
+
608
+ const start = Math.min(...imports.map(imp => imp.lineNumber - 1));
609
+ const end = Math.max(...imports.map(imp => imp.lineNumber - 1));
610
+
611
+ return { start, end };
612
+ }
613
+
614
+ /**
615
+ * Update imports for multiple files
616
+ */
617
+ async updateImportsInFiles(filePaths, changes) {
618
+ const results = [];
619
+
620
+ for (const filePath of filePaths) {
621
+ const result = await this.updateImports(filePath, changes);
622
+ results.push(result);
623
+ }
624
+
625
+ return results;
626
+ }
627
+
628
+ /**
629
+ * Add import to file
630
+ */
631
+ async addImport(filePath, module, specifier = null, options = {}) {
632
+ const change = {
633
+ type: 'add',
634
+ module,
635
+ specifier,
636
+ isDefault: options.isDefault || false,
637
+ isTypeOnly: options.isTypeOnly || false,
638
+ importType: options.importType || IMPORT_TYPES.ES6_IMPORT
639
+ };
640
+
641
+ return await this.updateImports(filePath, [change]);
642
+ }
643
+
644
+ /**
645
+ * Remove import from file
646
+ */
647
+ async removeImport(filePath, module, specifier = null) {
648
+ const change = {
649
+ type: 'remove',
650
+ module,
651
+ specifier
652
+ };
653
+
654
+ return await this.updateImports(filePath, [change]);
655
+ }
656
+
657
+ /**
658
+ * Update import paths after file moves
659
+ */
660
+ async updateImportPathsAfterMove(movedFiles) {
661
+ const results = [];
662
+
663
+ for (const movedFile of movedFiles) {
664
+ // Find files that might import the moved file
665
+ const dependentFiles = this.findDependentFiles(movedFile.oldPath);
666
+
667
+ for (const depFile of dependentFiles) {
668
+ const change = {
669
+ type: 'move',
670
+ oldPath: movedFile.oldPath,
671
+ newPath: movedFile.newPath
672
+ };
673
+
674
+ const result = await this.updateImports(depFile, [change]);
675
+ results.push(result);
676
+ }
677
+ }
678
+
679
+ return results;
680
+ }
681
+
682
+ /**
683
+ * Find files that depend on a given file
684
+ */
685
+ findDependentFiles(targetPath) {
686
+ // This would search the codebase for files that import from targetPath
687
+ // For now, return empty array as placeholder
688
+ return [];
689
+ }
690
+
691
+ /**
692
+ * Get import statistics
693
+ */
694
+ getStatistics(results) {
695
+ const stats = {
696
+ totalFiles: results.length,
697
+ successful: 0,
698
+ failed: 0,
699
+ totalImportsProcessed: 0,
700
+ totalImportsAdded: 0,
701
+ totalImportsRemoved: 0,
702
+ totalUnusedImports: 0,
703
+ errors: [],
704
+ warnings: []
705
+ };
706
+
707
+ for (const result of results) {
708
+ if (result.success) {
709
+ stats.successful++;
710
+ } else {
711
+ stats.failed++;
712
+ }
713
+
714
+ stats.totalImportsProcessed += result.originalImports.length;
715
+ stats.totalImportsAdded += result.metadata.importsAdded;
716
+ stats.totalImportsRemoved += result.metadata.importsRemoved;
717
+ stats.totalUnusedImports += result.unusedImports.length;
718
+
719
+ stats.errors.push(...result.errors);
720
+ stats.warnings.push(...result.warnings);
721
+ }
722
+
723
+ return stats;
724
+ }
725
+
726
+ /**
727
+ * Validate import statements
728
+ */
729
+ validateImports(filePath) {
730
+ const result = new ImportManagerResult(filePath);
731
+
732
+ try {
733
+ const content = fs.readFileSync(filePath, 'utf8');
734
+ const lines = content.split('\n');
735
+ const imports = this.parseImports(lines);
736
+
737
+ for (const imp of imports) {
738
+ // Check if module exists
739
+ if (imp.isRelative) {
740
+ const resolvedPath = path.resolve(path.dirname(filePath), imp.module);
741
+ if (!fs.existsSync(resolvedPath) && !fs.existsSync(resolvedPath + '.js')) {
742
+ result.addWarning(`Import module not found: ${imp.module}`);
743
+ }
744
+ }
745
+
746
+ // Check for duplicate imports
747
+ const duplicates = imports.filter(other =>
748
+ other !== imp &&
749
+ other.module === imp.module &&
750
+ other.specifier === imp.specifier
751
+ );
752
+
753
+ if (duplicates.length > 0) {
754
+ result.addWarning(`Duplicate import: ${imp.module} - ${imp.specifier}`);
755
+ }
756
+ }
757
+
758
+ result.setSuccess(true);
759
+
760
+ } catch (error) {
761
+ result.addError(error);
762
+ result.setSuccess(false);
763
+ }
764
+
765
+ return result;
766
+ }
767
+ }
768
+
769
+ module.exports = {
770
+ ImportManager,
771
+ ImportStatement,
772
+ ImportManagerResult,
773
+ IMPORT_TYPES
774
+ };