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,213 @@
1
+ /**
2
+ * Dependency Graph Builder
3
+ *
4
+ * Handles building and analyzing dependency graphs.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { DependencyNode } = require('./dependency-node');
10
+ const { DEPENDENCY_TYPES, ANALYZED_EXTENSIONS, SKIP_DIRECTORIES } = require('./dependency-types');
11
+
12
+ /**
13
+ * Dependency graph building utilities
14
+ */
15
+ class DependencyGraphBuilder {
16
+ constructor(options = {}) {
17
+ this.options = options;
18
+ this.nodes = new Map();
19
+ }
20
+
21
+ /**
22
+ * Build dependency graph from root path
23
+ */
24
+ async buildGraph(rootPath = process.cwd()) {
25
+ const files = await this.getAllFiles(rootPath);
26
+
27
+ for (const filePath of files) {
28
+ const node = new DependencyNode(filePath);
29
+
30
+ // Extract dependencies from file
31
+ const dependencies = await this.extractDependencies(filePath);
32
+ for (const dep of dependencies) {
33
+ node.addDependency(dep.path, dep.type);
34
+
35
+ // Add reverse dependency
36
+ const depNode = this.getOrCreateNode(dep.path);
37
+ depNode.addDependent(filePath);
38
+ }
39
+
40
+ this.nodes.set(filePath, node);
41
+ }
42
+
43
+ return this.nodes;
44
+ }
45
+
46
+ /**
47
+ * Get all files to analyze
48
+ */
49
+ async getAllFiles(rootPath) {
50
+ const files = [];
51
+
52
+ const walkDir = (dir) => {
53
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
54
+
55
+ for (const entry of entries) {
56
+ const fullPath = path.join(dir, entry.name);
57
+
58
+ if (entry.isDirectory()) {
59
+ // Skip certain directories
60
+ if (this.shouldSkipDirectory(fullPath)) {
61
+ continue;
62
+ }
63
+ walkDir(fullPath);
64
+ } else if (entry.isFile()) {
65
+ // Only include certain file types
66
+ if (this.shouldIncludeFile(fullPath)) {
67
+ files.push(fullPath);
68
+ }
69
+ }
70
+ }
71
+ };
72
+
73
+ walkDir(rootPath);
74
+ return files;
75
+ }
76
+
77
+ /**
78
+ * Check if directory should be skipped
79
+ */
80
+ shouldSkipDirectory(dirPath) {
81
+ const dirName = path.basename(dirPath);
82
+ return SKIP_DIRECTORIES.includes(dirName) || dirName.startsWith('.');
83
+ }
84
+
85
+ /**
86
+ * Check if file should be included
87
+ */
88
+ shouldIncludeFile(filePath) {
89
+ const ext = path.extname(filePath);
90
+
91
+ if (!ANALYZED_EXTENSIONS.includes(ext)) {
92
+ return false;
93
+ }
94
+
95
+ if (this.options.ignoreTestFiles && filePath.includes('test')) {
96
+ return false;
97
+ }
98
+
99
+ if (this.options.ignoreVendorFiles && filePath.includes('vendor')) {
100
+ return false;
101
+ }
102
+
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * Extract dependencies from file
108
+ */
109
+ async extractDependencies(filePath) {
110
+ const dependencies = [];
111
+
112
+ try {
113
+ const content = fs.readFileSync(filePath, 'utf8');
114
+ const lines = content.split('\n');
115
+
116
+ for (const line of lines) {
117
+ const trimmed = line.trim();
118
+
119
+ // ES6 imports
120
+ const importMatch = trimmed.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
121
+ if (importMatch) {
122
+ const depPath = this.resolveDependencyPath(filePath, importMatch[1]);
123
+ if (depPath) {
124
+ dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.IMPORT });
125
+ }
126
+ }
127
+
128
+ // CommonJS requires
129
+ const requireMatch = trimmed.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
130
+ if (requireMatch) {
131
+ const depPath = this.resolveDependencyPath(filePath, requireMatch[1]);
132
+ if (depPath) {
133
+ dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.REQUIRE });
134
+ }
135
+ }
136
+
137
+ // Dynamic imports
138
+ const dynamicMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
139
+ if (dynamicMatch) {
140
+ const depPath = this.resolveDependencyPath(filePath, dynamicMatch[1]);
141
+ if (depPath) {
142
+ dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.DYNAMIC });
143
+ }
144
+ }
145
+ }
146
+
147
+ } catch (error) {
148
+ // Skip files that can't be read
149
+ }
150
+
151
+ return dependencies;
152
+ }
153
+
154
+ /**
155
+ * Resolve dependency path to absolute path
156
+ */
157
+ resolveDependencyPath(fromPath, importPath) {
158
+ if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
159
+ // Skip non-relative imports (node_modules, etc.)
160
+ return null;
161
+ }
162
+
163
+ const absolutePath = path.resolve(path.dirname(fromPath), importPath);
164
+
165
+ // Try different extensions
166
+ const extensions = ['.js', '.jsx', '.ts', '.tsx', '/index.js', '/index.jsx', '/index.ts', '/index.tsx'];
167
+
168
+ for (const ext of extensions) {
169
+ const testPath = absolutePath + ext;
170
+ if (fs.existsSync(testPath)) {
171
+ return path.resolve(testPath);
172
+ }
173
+ }
174
+
175
+ return null;
176
+ }
177
+
178
+ /**
179
+ * Get or create node
180
+ */
181
+ getOrCreateNode(filePath) {
182
+ if (!this.nodes.has(filePath)) {
183
+ this.nodes.set(filePath, new DependencyNode(filePath));
184
+ }
185
+ return this.nodes.get(filePath);
186
+ }
187
+
188
+ /**
189
+ * Calculate total dependencies
190
+ */
191
+ calculateTotalDependencies() {
192
+ let total = 0;
193
+ for (const node of this.nodes.values()) {
194
+ total += node.getDependencyCount();
195
+ }
196
+ return total;
197
+ }
198
+
199
+ /**
200
+ * Get graph statistics
201
+ */
202
+ getStatistics() {
203
+ return {
204
+ totalFiles: this.nodes.size,
205
+ totalDependencies: this.calculateTotalDependencies(),
206
+ averageDependencies: this.nodes.size > 0 ? this.calculateTotalDependencies() / this.nodes.size : 0
207
+ };
208
+ }
209
+ }
210
+
211
+ module.exports = {
212
+ DependencyGraphBuilder
213
+ };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Resolution Strategy
3
+ *
4
+ * Represents a strategy for resolving circular dependencies.
5
+ */
6
+
7
+ /**
8
+ * Resolution strategy class
9
+ */
10
+ class ResolutionStrategy {
11
+ constructor(type, description, effort, risk) {
12
+ this.type = type;
13
+ this.description = description;
14
+ this.effort = effort; // 1-10 scale
15
+ this.risk = risk; // 1-10 scale
16
+ this.steps = [];
17
+ this.applicable = true;
18
+ }
19
+
20
+ addStep(step) {
21
+ this.steps.push(step);
22
+ }
23
+
24
+ setApplicable(applicable) {
25
+ this.applicable = applicable;
26
+ }
27
+
28
+ getSummary() {
29
+ return {
30
+ type: this.type,
31
+ description: this.description,
32
+ effort: this.effort,
33
+ risk: this.risk,
34
+ steps: this.steps,
35
+ applicable: this.applicable
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Get total score (effort + risk)
41
+ */
42
+ getScore() {
43
+ return this.effort + this.risk;
44
+ }
45
+
46
+ /**
47
+ * Check if strategy is low risk
48
+ */
49
+ isLowRisk() {
50
+ return this.risk <= 3;
51
+ }
52
+
53
+ /**
54
+ * Check if strategy is low effort
55
+ */
56
+ isLowEffort() {
57
+ return this.effort <= 5;
58
+ }
59
+
60
+ /**
61
+ * Get recommended priority
62
+ */
63
+ getPriority() {
64
+ if (this.isLowRisk() && this.isLowEffort()) return 'high';
65
+ if (this.isLowRisk() || this.isLowEffort()) return 'medium';
66
+ return 'low';
67
+ }
68
+ }
69
+
70
+ module.exports = {
71
+ ResolutionStrategy
72
+ };
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Strategy Generator
3
+ *
4
+ * Generates resolution strategies for circular dependencies.
5
+ */
6
+
7
+ const { ResolutionStrategy } = require('./resolution-strategy');
8
+
9
+ /**
10
+ * Strategy generation utilities
11
+ */
12
+ class StrategyGenerator {
13
+ constructor(nodes) {
14
+ this.nodes = nodes;
15
+ }
16
+
17
+ /**
18
+ * Generate strategies for all cycles
19
+ */
20
+ generateStrategies(cycles) {
21
+ const allStrategies = [];
22
+
23
+ for (const cycle of cycles) {
24
+ const strategies = this.generateStrategiesForCycle(cycle);
25
+ allStrategies.push(...strategies);
26
+ }
27
+
28
+ return allStrategies;
29
+ }
30
+
31
+ /**
32
+ * Generate strategies for a specific cycle
33
+ */
34
+ generateStrategiesForCycle(cycle) {
35
+ const strategies = [];
36
+
37
+ // Strategy 1: Extract common dependencies
38
+ const extractStrategy = this.generateExtractStrategy(cycle);
39
+ strategies.push(extractStrategy);
40
+
41
+ // Strategy 2: Invert dependency
42
+ const invertStrategy = this.generateInvertStrategy(cycle);
43
+ strategies.push(invertStrategy);
44
+
45
+ // Strategy 3: Introduce interface/abstraction
46
+ const interfaceStrategy = this.generateInterfaceStrategy(cycle);
47
+ strategies.push(interfaceStrategy);
48
+
49
+ // Strategy 4: Merge modules
50
+ const mergeStrategy = this.generateMergeStrategy(cycle);
51
+ strategies.push(mergeStrategy);
52
+
53
+ // Strategy 5: Dependency injection
54
+ const diStrategy = this.generateDIStrategy(cycle);
55
+ strategies.push(diStrategy);
56
+
57
+ return strategies.filter(s => s.applicable);
58
+ }
59
+
60
+ /**
61
+ * Generate extract common dependencies strategy
62
+ */
63
+ generateExtractStrategy(cycle) {
64
+ const strategy = new ResolutionStrategy(
65
+ 'extract_common',
66
+ 'Extract common dependencies into a shared module',
67
+ 6,
68
+ 4
69
+ );
70
+
71
+ strategy.addStep('Analyze all files in the cycle for common dependencies');
72
+ strategy.addStep('Create a new module for shared dependencies');
73
+ strategy.addStep('Update all files to import from the shared module');
74
+ strategy.addStep('Remove duplicate dependencies from individual files');
75
+
76
+ // Check if applicable
77
+ const commonDeps = this.findCommonDependencies(cycle);
78
+ strategy.setApplicable(commonDeps.length > 1);
79
+
80
+ return strategy;
81
+ }
82
+
83
+ /**
84
+ * Generate invert dependency strategy
85
+ */
86
+ generateInvertStrategy(cycle) {
87
+ const strategy = new ResolutionStrategy(
88
+ 'invert_dependency',
89
+ 'Invert one dependency in the cycle',
90
+ 4,
91
+ 3
92
+ );
93
+
94
+ strategy.addStep('Identify the dependency to invert');
95
+ strategy.addStep('Use dependency injection or events instead');
96
+ strategy.addStep('Update the dependent file');
97
+ strategy.addStep('Test the inverted dependency');
98
+
99
+ // Always applicable for cycles of length 2
100
+ strategy.setApplicable(cycle.length <= 3);
101
+
102
+ return strategy;
103
+ }
104
+
105
+ /**
106
+ * Generate interface/abstraction strategy
107
+ */
108
+ generateInterfaceStrategy(cycle) {
109
+ const strategy = new ResolutionStrategy(
110
+ 'interface_abstraction',
111
+ 'Introduce interface/abstraction to break cycle',
112
+ 7,
113
+ 5
114
+ );
115
+
116
+ strategy.addStep('Design an interface for the shared functionality');
117
+ strategy.addStep('Create the interface module');
118
+ strategy.addStep('Implement the interface in one of the modules');
119
+ strategy.addStep('Update other modules to use the interface');
120
+ strategy.addStep('Remove direct dependencies');
121
+
122
+ // Check if applicable (needs TypeScript or similar)
123
+ strategy.setApplicable(this.hasTypeScriptFiles(cycle));
124
+
125
+ return strategy;
126
+ }
127
+
128
+ /**
129
+ * Generate merge modules strategy
130
+ */
131
+ generateMergeStrategy(cycle) {
132
+ const strategy = new ResolutionStrategy(
133
+ 'merge_modules',
134
+ 'Merge modules in the cycle',
135
+ 3,
136
+ 2
137
+ );
138
+
139
+ strategy.addStep('Identify modules that can be safely merged');
140
+ strategy.addStep('Create merged module');
141
+ strategy.addStep('Update all dependencies');
142
+ strategy.addStep('Remove original modules');
143
+
144
+ // Check if applicable (small files only)
145
+ strategy.setApplicable(this.canMergeModules(cycle));
146
+
147
+ return strategy;
148
+ }
149
+
150
+ /**
151
+ * Generate dependency injection strategy
152
+ */
153
+ generateDIStrategy(cycle) {
154
+ const strategy = new ResolutionStrategy(
155
+ 'dependency_injection',
156
+ 'Use dependency injection to break cycle',
157
+ 8,
158
+ 6
159
+ );
160
+
161
+ strategy.addStep('Create a dependency injection container');
162
+ strategy.addStep('Register dependencies in the container');
163
+ strategy.addStep('Update modules to use injected dependencies');
164
+ strategy.addStep('Configure the injection at application startup');
165
+
166
+ // Always applicable
167
+ strategy.setApplicable(true);
168
+
169
+ return strategy;
170
+ }
171
+
172
+ /**
173
+ * Find common dependencies in a cycle
174
+ */
175
+ findCommonDependencies(cycle) {
176
+ const dependencyCounts = new Map();
177
+
178
+ for (const filePath of cycle) {
179
+ const node = this.nodes.get(filePath);
180
+ if (node) {
181
+ for (const dep of node.dependencies) {
182
+ const depPath = typeof dep === 'object' ? dep.path : dep;
183
+ dependencyCounts.set(depPath, (dependencyCounts.get(depPath) || 0) + 1);
184
+ }
185
+ }
186
+ }
187
+
188
+ return Array.from(dependencyCounts.entries())
189
+ .filter(([_, count]) => count > 1)
190
+ .map(([path, _]) => path);
191
+ }
192
+
193
+ /**
194
+ * Check if cycle has TypeScript files
195
+ */
196
+ hasTypeScriptFiles(cycle) {
197
+ return cycle.some(filePath => filePath.endsWith('.ts') || filePath.endsWith('.tsx'));
198
+ }
199
+
200
+ /**
201
+ * Check if modules can be merged
202
+ */
203
+ canMergeModules(cycle) {
204
+ for (const filePath of cycle) {
205
+ const node = this.nodes.get(filePath);
206
+ if (node && node.metadata.size > 200) {
207
+ return false;
208
+ }
209
+ }
210
+ return true;
211
+ }
212
+
213
+ /**
214
+ * Get best strategy for a cycle
215
+ */
216
+ getBestStrategy(cycle) {
217
+ const strategies = this.generateStrategiesForCycle(cycle);
218
+ if (strategies.length === 0) return null;
219
+
220
+ // Sort by score (effort + risk)
221
+ strategies.sort((a, b) => a.getScore() - b.getScore());
222
+
223
+ return strategies[0];
224
+ }
225
+ }
226
+
227
+ module.exports = {
228
+ StrategyGenerator
229
+ };