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.
- package/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,809 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circular Dependency Resolver
|
|
3
|
+
*
|
|
4
|
+
* Detects and resolves circular dependencies in the codebase.
|
|
5
|
+
* Provides strategies for breaking cycles while maintaining functionality.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Dependency types
|
|
13
|
+
*/
|
|
14
|
+
const DEPENDENCY_TYPES = {
|
|
15
|
+
IMPORT: 'import',
|
|
16
|
+
REQUIRE: 'require',
|
|
17
|
+
DYNAMIC: 'dynamic',
|
|
18
|
+
INDIRECT: 'indirect'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Cycle severity levels
|
|
23
|
+
*/
|
|
24
|
+
const CYCLE_SEVERITY = {
|
|
25
|
+
LOW: 'low',
|
|
26
|
+
MEDIUM: 'medium',
|
|
27
|
+
HIGH: 'high',
|
|
28
|
+
CRITICAL: 'critical'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dependency node class
|
|
33
|
+
*/
|
|
34
|
+
class DependencyNode {
|
|
35
|
+
constructor(filePath) {
|
|
36
|
+
this.filePath = filePath;
|
|
37
|
+
this.dependencies = new Set();
|
|
38
|
+
this.dependents = new Set();
|
|
39
|
+
this.visited = false;
|
|
40
|
+
this.visiting = false;
|
|
41
|
+
this.metadata = {
|
|
42
|
+
size: 0,
|
|
43
|
+
type: this.detectFileType(),
|
|
44
|
+
package: this.extractPackage()
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
detectFileType() {
|
|
49
|
+
const ext = path.extname(this.filePath).toLowerCase();
|
|
50
|
+
if (['.js', '.jsx', '.ts', '.tsx'].includes(ext)) return 'javascript';
|
|
51
|
+
if (ext === '.json') return 'json';
|
|
52
|
+
return 'other';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
extractPackage() {
|
|
56
|
+
const match = this.filePath.match(/packages\/([^\/]+)/);
|
|
57
|
+
return match ? match[1] : 'root';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
addDependency(filePath, type = DEPENDENCY_TYPES.IMPORT) {
|
|
61
|
+
this.dependencies.add({ path: filePath, type });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
addDependent(filePath) {
|
|
65
|
+
this.dependents.add(filePath);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
hasDependency(filePath) {
|
|
69
|
+
return this.dependencies.has(filePath);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getDependencyCount() {
|
|
73
|
+
return this.dependencies.size;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getDependentCount() {
|
|
77
|
+
return this.dependents.size;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Circular dependency class
|
|
83
|
+
*/
|
|
84
|
+
class CircularDependency {
|
|
85
|
+
constructor(cycle) {
|
|
86
|
+
this.cycle = cycle;
|
|
87
|
+
this.length = cycle.length;
|
|
88
|
+
this.severity = this.calculateSeverity();
|
|
89
|
+
this.impact = this.calculateImpact();
|
|
90
|
+
this.resolution = null;
|
|
91
|
+
this.metadata = {
|
|
92
|
+
detectedAt: new Date().toISOString(),
|
|
93
|
+
confidence: 0.8
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
calculateSeverity() {
|
|
98
|
+
if (this.length === 2) return CYCLE_SEVERITY.CRITICAL;
|
|
99
|
+
if (this.length === 3) return CYCLE_SEVERITY.HIGH;
|
|
100
|
+
if (this.length <= 5) return CYCLE_SEVERITY.MEDIUM;
|
|
101
|
+
return CYCLE_SEVERITY.LOW;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
calculateImpact() {
|
|
105
|
+
let impact = 0;
|
|
106
|
+
|
|
107
|
+
// Impact based on cycle length
|
|
108
|
+
impact += (6 - Math.min(this.length, 6)) * 10;
|
|
109
|
+
|
|
110
|
+
// Impact based on file types
|
|
111
|
+
for (const filePath of this.cycle) {
|
|
112
|
+
if (filePath.includes('packages/core')) impact += 15;
|
|
113
|
+
if (filePath.includes('packages/cli')) impact += 10;
|
|
114
|
+
if (filePath.includes('packages/electron-app')) impact += 8;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return Math.min(100, impact);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
setResolution(resolution) {
|
|
121
|
+
this.resolution = resolution;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getSummary() {
|
|
125
|
+
return {
|
|
126
|
+
cycle: this.cycle,
|
|
127
|
+
length: this.length,
|
|
128
|
+
severity: this.severity,
|
|
129
|
+
impact: this.impact,
|
|
130
|
+
resolution: this.resolution,
|
|
131
|
+
confidence: this.metadata.confidence
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Resolution strategy class
|
|
138
|
+
*/
|
|
139
|
+
class ResolutionStrategy {
|
|
140
|
+
constructor(type, description, effort, risk) {
|
|
141
|
+
this.type = type;
|
|
142
|
+
this.description = description;
|
|
143
|
+
this.effort = effort; // 1-10 scale
|
|
144
|
+
this.risk = risk; // 1-10 scale
|
|
145
|
+
this.steps = [];
|
|
146
|
+
this.applicable = true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
addStep(step) {
|
|
150
|
+
this.steps.push(step);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setApplicable(applicable) {
|
|
154
|
+
this.applicable = applicable;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
getSummary() {
|
|
158
|
+
return {
|
|
159
|
+
type: this.type,
|
|
160
|
+
description: this.description,
|
|
161
|
+
effort: this.effort,
|
|
162
|
+
risk: this.risk,
|
|
163
|
+
steps: this.steps,
|
|
164
|
+
applicable: this.applicable
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Circular dependency resolver result class
|
|
171
|
+
*/
|
|
172
|
+
class CircularDependencyResult {
|
|
173
|
+
constructor() {
|
|
174
|
+
this.cycles = [];
|
|
175
|
+
this.strategies = [];
|
|
176
|
+
this.resolved = [];
|
|
177
|
+
this.failed = [];
|
|
178
|
+
this.metadata = {
|
|
179
|
+
analyzedAt: new Date().toISOString(),
|
|
180
|
+
totalFiles: 0,
|
|
181
|
+
totalDependencies: 0
|
|
182
|
+
};
|
|
183
|
+
this.errors = [];
|
|
184
|
+
this.warnings = [];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
addCycle(cycle) {
|
|
188
|
+
this.cycles.push(cycle);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
addStrategy(strategy) {
|
|
192
|
+
this.strategies.push(strategy);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
addResolved(resolution) {
|
|
196
|
+
this.resolved.push(resolution);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
addFailed(failure) {
|
|
200
|
+
this.failed.push(failure);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
addError(error) {
|
|
204
|
+
this.errors.push({
|
|
205
|
+
message: error.message,
|
|
206
|
+
timestamp: new Date().toISOString()
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
addWarning(warning) {
|
|
211
|
+
this.warnings.push({
|
|
212
|
+
message: warning,
|
|
213
|
+
timestamp: new Date().toISOString()
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
getSummary() {
|
|
218
|
+
return {
|
|
219
|
+
cyclesFound: this.cycles.length,
|
|
220
|
+
strategiesGenerated: this.strategies.length,
|
|
221
|
+
cyclesResolved: this.resolved.length,
|
|
222
|
+
cyclesFailed: this.failed.length,
|
|
223
|
+
totalFiles: this.metadata.totalFiles,
|
|
224
|
+
totalDependencies: this.metadata.totalDependencies,
|
|
225
|
+
errorCount: this.errors.length,
|
|
226
|
+
warningCount: this.warnings.length
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Circular dependency resolver class
|
|
233
|
+
*/
|
|
234
|
+
class CircularDependencyResolver {
|
|
235
|
+
constructor(options = {}) {
|
|
236
|
+
this.options = {
|
|
237
|
+
maxDepth: 10,
|
|
238
|
+
includeIndirect: true,
|
|
239
|
+
ignoreTestFiles: true,
|
|
240
|
+
ignoreVendorFiles: true,
|
|
241
|
+
generateStrategies: true,
|
|
242
|
+
autoResolve: false,
|
|
243
|
+
...options
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
this.nodes = new Map();
|
|
247
|
+
this.result = new CircularDependencyResult();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Analyze codebase for circular dependencies
|
|
252
|
+
*/
|
|
253
|
+
async analyze(rootPath = process.cwd()) {
|
|
254
|
+
console.log('Analyzing circular dependencies...');
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
// Build dependency graph
|
|
258
|
+
await this.buildDependencyGraph(rootPath);
|
|
259
|
+
|
|
260
|
+
// Detect cycles
|
|
261
|
+
await this.detectCycles();
|
|
262
|
+
|
|
263
|
+
// Generate resolution strategies
|
|
264
|
+
if (this.options.generateStrategies) {
|
|
265
|
+
await this.generateStrategies();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Auto-resolve if enabled
|
|
269
|
+
if (this.options.autoResolve) {
|
|
270
|
+
await this.autoResolve();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this.result.metadata.totalFiles = this.nodes.size;
|
|
274
|
+
this.result.metadata.totalDependencies = this.calculateTotalDependencies();
|
|
275
|
+
|
|
276
|
+
console.log(`Analysis complete: ${this.result.cycles.length} cycles found`);
|
|
277
|
+
|
|
278
|
+
} catch (error) {
|
|
279
|
+
this.result.addError(error);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return this.result;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Build dependency graph
|
|
287
|
+
*/
|
|
288
|
+
async buildDependencyGraph(rootPath) {
|
|
289
|
+
const files = await this.getAllFiles(rootPath);
|
|
290
|
+
|
|
291
|
+
for (const filePath of files) {
|
|
292
|
+
const node = new DependencyNode(filePath);
|
|
293
|
+
|
|
294
|
+
// Extract dependencies from file
|
|
295
|
+
const dependencies = await this.extractDependencies(filePath);
|
|
296
|
+
for (const dep of dependencies) {
|
|
297
|
+
node.addDependency(dep.path, dep.type);
|
|
298
|
+
|
|
299
|
+
// Add reverse dependency
|
|
300
|
+
const depNode = this.getOrCreateNode(dep.path);
|
|
301
|
+
depNode.addDependent(filePath);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
this.nodes.set(filePath, node);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Get all files to analyze
|
|
310
|
+
*/
|
|
311
|
+
async getAllFiles(rootPath) {
|
|
312
|
+
const files = [];
|
|
313
|
+
|
|
314
|
+
const walkDir = (dir) => {
|
|
315
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
316
|
+
|
|
317
|
+
for (const entry of entries) {
|
|
318
|
+
const fullPath = path.join(dir, entry.name);
|
|
319
|
+
|
|
320
|
+
if (entry.isDirectory()) {
|
|
321
|
+
// Skip certain directories
|
|
322
|
+
if (this.shouldSkipDirectory(fullPath)) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
walkDir(fullPath);
|
|
326
|
+
} else if (entry.isFile()) {
|
|
327
|
+
// Only include certain file types
|
|
328
|
+
if (this.shouldIncludeFile(fullPath)) {
|
|
329
|
+
files.push(fullPath);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
walkDir(rootPath);
|
|
336
|
+
return files;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Check if directory should be skipped
|
|
341
|
+
*/
|
|
342
|
+
shouldSkipDirectory(dirPath) {
|
|
343
|
+
const dirName = path.basename(dirPath);
|
|
344
|
+
const skipDirs = [
|
|
345
|
+
'node_modules', '.git', 'dist', 'build', 'coverage',
|
|
346
|
+
'.vscode', '.idea', '.cursor', '.windsurf'
|
|
347
|
+
];
|
|
348
|
+
|
|
349
|
+
return skipDirs.includes(dirName) || dirName.startsWith('.');
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Check if file should be included
|
|
354
|
+
*/
|
|
355
|
+
shouldIncludeFile(filePath) {
|
|
356
|
+
const ext = path.extname(filePath);
|
|
357
|
+
const includeExts = ['.js', '.jsx', '.ts', '.tsx'];
|
|
358
|
+
|
|
359
|
+
if (!includeExts.includes(ext)) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (this.options.ignoreTestFiles && filePath.includes('test')) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (this.options.ignoreVendorFiles && filePath.includes('vendor')) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Extract dependencies from file
|
|
376
|
+
*/
|
|
377
|
+
async extractDependencies(filePath) {
|
|
378
|
+
const dependencies = [];
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
382
|
+
const lines = content.split('\n');
|
|
383
|
+
|
|
384
|
+
for (const line of lines) {
|
|
385
|
+
const trimmed = line.trim();
|
|
386
|
+
|
|
387
|
+
// ES6 imports
|
|
388
|
+
const importMatch = trimmed.match(/import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"]/);
|
|
389
|
+
if (importMatch) {
|
|
390
|
+
const depPath = this.resolveDependencyPath(filePath, importMatch[1]);
|
|
391
|
+
if (depPath) {
|
|
392
|
+
dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.IMPORT });
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// CommonJS requires
|
|
397
|
+
const requireMatch = trimmed.match(/require\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
398
|
+
if (requireMatch) {
|
|
399
|
+
const depPath = this.resolveDependencyPath(filePath, requireMatch[1]);
|
|
400
|
+
if (depPath) {
|
|
401
|
+
dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.REQUIRE });
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Dynamic imports
|
|
406
|
+
const dynamicMatch = trimmed.match(/import\s*\(\s*['"]([^'"]+)['"]\s*\)/);
|
|
407
|
+
if (dynamicMatch) {
|
|
408
|
+
const depPath = this.resolveDependencyPath(filePath, dynamicMatch[1]);
|
|
409
|
+
if (depPath) {
|
|
410
|
+
dependencies.push({ path: depPath, type: DEPENDENCY_TYPES.DYNAMIC });
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
} catch (error) {
|
|
416
|
+
// Skip files that can't be read
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return dependencies;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Resolve dependency path to absolute path
|
|
424
|
+
*/
|
|
425
|
+
resolveDependencyPath(fromPath, importPath) {
|
|
426
|
+
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
|
|
427
|
+
// Skip non-relative imports (node_modules, etc.)
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const absolutePath = path.resolve(path.dirname(fromPath), importPath);
|
|
432
|
+
|
|
433
|
+
// Try different extensions
|
|
434
|
+
const extensions = ['.js', '.jsx', '.ts', '.tsx', '/index.js', '/index.jsx', '/index.ts', '/index.tsx'];
|
|
435
|
+
|
|
436
|
+
for (const ext of extensions) {
|
|
437
|
+
const testPath = absolutePath + ext;
|
|
438
|
+
if (fs.existsSync(testPath)) {
|
|
439
|
+
return path.resolve(testPath);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Detect cycles using DFS
|
|
448
|
+
*/
|
|
449
|
+
async detectCycles() {
|
|
450
|
+
const visited = new Set();
|
|
451
|
+
|
|
452
|
+
for (const [filePath, node] of this.nodes) {
|
|
453
|
+
if (!visited.has(filePath)) {
|
|
454
|
+
const cycle = this.findCycle(filePath, new Set(), new Set());
|
|
455
|
+
if (cycle.length > 0) {
|
|
456
|
+
const circularDep = new CircularDependency(cycle);
|
|
457
|
+
this.result.addCycle(circularDep);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Find cycle starting from a node
|
|
465
|
+
*/
|
|
466
|
+
findCycle(startPath, currentPath, visiting) {
|
|
467
|
+
const node = this.nodes.get(startPath);
|
|
468
|
+
if (!node) return [];
|
|
469
|
+
|
|
470
|
+
visiting.add(startPath);
|
|
471
|
+
|
|
472
|
+
for (const dep of node.dependencies) {
|
|
473
|
+
const depPath = typeof dep === 'object' ? dep.path : dep;
|
|
474
|
+
|
|
475
|
+
if (depPath === startPath) {
|
|
476
|
+
// Found cycle
|
|
477
|
+
return [startPath];
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (visiting.has(depPath)) {
|
|
481
|
+
// Found cycle through current path
|
|
482
|
+
return [depPath, startPath];
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (!currentPath.has(depPath)) {
|
|
486
|
+
const cycle = this.findCycle(depPath, currentPath, visiting);
|
|
487
|
+
if (cycle.length > 0) {
|
|
488
|
+
if (cycle[cycle.length - 1] === startPath) {
|
|
489
|
+
return cycle;
|
|
490
|
+
} else {
|
|
491
|
+
return [...cycle, startPath];
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
visiting.delete(startPath);
|
|
498
|
+
currentPath.add(startPath);
|
|
499
|
+
|
|
500
|
+
return [];
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Generate resolution strategies
|
|
505
|
+
*/
|
|
506
|
+
async generateStrategies() {
|
|
507
|
+
for (const cycle of this.result.cycles) {
|
|
508
|
+
const strategies = this.generateStrategiesForCycle(cycle);
|
|
509
|
+
for (const strategy of strategies) {
|
|
510
|
+
this.result.addStrategy(strategy);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Generate strategies for a specific cycle
|
|
517
|
+
*/
|
|
518
|
+
generateStrategiesForCycle(cycle) {
|
|
519
|
+
const strategies = [];
|
|
520
|
+
|
|
521
|
+
// Strategy 1: Extract common dependencies
|
|
522
|
+
const extractStrategy = this.generateExtractStrategy(cycle);
|
|
523
|
+
strategies.push(extractStrategy);
|
|
524
|
+
|
|
525
|
+
// Strategy 2: Invert dependency
|
|
526
|
+
const invertStrategy = this.generateInvertStrategy(cycle);
|
|
527
|
+
strategies.push(invertStrategy);
|
|
528
|
+
|
|
529
|
+
// Strategy 3: Introduce interface/abstraction
|
|
530
|
+
const interfaceStrategy = this.generateInterfaceStrategy(cycle);
|
|
531
|
+
strategies.push(interfaceStrategy);
|
|
532
|
+
|
|
533
|
+
// Strategy 4: Merge modules
|
|
534
|
+
const mergeStrategy = this.generateMergeStrategy(cycle);
|
|
535
|
+
strategies.push(mergeStrategy);
|
|
536
|
+
|
|
537
|
+
// Strategy 5: Dependency injection
|
|
538
|
+
const diStrategy = this.generateDIStrategy(cycle);
|
|
539
|
+
strategies.push(diStrategy);
|
|
540
|
+
|
|
541
|
+
return strategies.filter(s => s.applicable);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Generate extract common dependencies strategy
|
|
546
|
+
*/
|
|
547
|
+
generateExtractStrategy(cycle) {
|
|
548
|
+
const strategy = new ResolutionStrategy(
|
|
549
|
+
'extract_common',
|
|
550
|
+
'Extract common dependencies into a shared module',
|
|
551
|
+
6,
|
|
552
|
+
4
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
strategy.addStep('Analyze all files in the cycle for common dependencies');
|
|
556
|
+
strategy.addStep('Create a new module for shared dependencies');
|
|
557
|
+
strategy.addStep('Update all files to import from the shared module');
|
|
558
|
+
strategy.addStep('Remove duplicate dependencies from individual files');
|
|
559
|
+
|
|
560
|
+
// Check if applicable
|
|
561
|
+
const commonDeps = this.findCommonDependencies(cycle);
|
|
562
|
+
strategy.setApplicable(commonDeps.length > 1);
|
|
563
|
+
|
|
564
|
+
return strategy;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Generate invert dependency strategy
|
|
569
|
+
*/
|
|
570
|
+
generateInvertStrategy(cycle) {
|
|
571
|
+
const strategy = new ResolutionStrategy(
|
|
572
|
+
'invert_dependency',
|
|
573
|
+
'Invert one dependency in the cycle',
|
|
574
|
+
4,
|
|
575
|
+
3
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
strategy.addStep('Identify the dependency to invert');
|
|
579
|
+
strategy.addStep('Use dependency injection or events instead');
|
|
580
|
+
strategy.addStep('Update the dependent file');
|
|
581
|
+
strategy.addStep('Test the inverted dependency');
|
|
582
|
+
|
|
583
|
+
// Always applicable for cycles of length 2
|
|
584
|
+
strategy.setApplicable(cycle.length <= 3);
|
|
585
|
+
|
|
586
|
+
return strategy;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Generate interface/abstraction strategy
|
|
591
|
+
*/
|
|
592
|
+
generateInterfaceStrategy(cycle) {
|
|
593
|
+
const strategy = new ResolutionStrategy(
|
|
594
|
+
'interface_abstraction',
|
|
595
|
+
'Introduce interface/abstraction to break cycle',
|
|
596
|
+
7,
|
|
597
|
+
5
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
strategy.addStep('Design an interface for the shared functionality');
|
|
601
|
+
strategy.addStep('Create the interface module');
|
|
602
|
+
strategy.addStep('Implement the interface in one of the modules');
|
|
603
|
+
strategy.addStep('Update other modules to use the interface');
|
|
604
|
+
strategy.addStep('Remove direct dependencies');
|
|
605
|
+
|
|
606
|
+
// Check if applicable (needs TypeScript or similar)
|
|
607
|
+
strategy.setApplicable(this.hasTypeScriptFiles(cycle));
|
|
608
|
+
|
|
609
|
+
return strategy;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Generate merge modules strategy
|
|
614
|
+
*/
|
|
615
|
+
generateMergeStrategy(cycle) {
|
|
616
|
+
const strategy = new ResolutionStrategy(
|
|
617
|
+
'merge_modules',
|
|
618
|
+
'Merge modules in the cycle',
|
|
619
|
+
3,
|
|
620
|
+
2
|
|
621
|
+
);
|
|
622
|
+
|
|
623
|
+
strategy.addStep('Identify modules that can be safely merged');
|
|
624
|
+
strategy.addStep('Create merged module');
|
|
625
|
+
strategy.addStep('Update all dependencies');
|
|
626
|
+
strategy.addStep('Remove original modules');
|
|
627
|
+
|
|
628
|
+
// Check if applicable (small files only)
|
|
629
|
+
strategy.setApplicable(this.canMergeModules(cycle));
|
|
630
|
+
|
|
631
|
+
return strategy;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Generate dependency injection strategy
|
|
636
|
+
*/
|
|
637
|
+
generateDIStrategy(cycle) {
|
|
638
|
+
const strategy = new ResolutionStrategy(
|
|
639
|
+
'dependency_injection',
|
|
640
|
+
'Use dependency injection to break cycle',
|
|
641
|
+
8,
|
|
642
|
+
6
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
strategy.addStep('Create a dependency injection container');
|
|
646
|
+
strategy.addStep('Register dependencies in the container');
|
|
647
|
+
strategy.addStep('Update modules to use injected dependencies');
|
|
648
|
+
strategy.addStep('Configure the injection at application startup');
|
|
649
|
+
|
|
650
|
+
// Always applicable
|
|
651
|
+
strategy.setApplicable(true);
|
|
652
|
+
|
|
653
|
+
return strategy;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Find common dependencies in a cycle
|
|
658
|
+
*/
|
|
659
|
+
findCommonDependencies(cycle) {
|
|
660
|
+
const dependencyCounts = new Map();
|
|
661
|
+
|
|
662
|
+
for (const filePath of cycle) {
|
|
663
|
+
const node = this.nodes.get(filePath);
|
|
664
|
+
if (node) {
|
|
665
|
+
for (const dep of node.dependencies) {
|
|
666
|
+
const depPath = typeof dep === 'object' ? dep.path : dep;
|
|
667
|
+
dependencyCounts.set(depPath, (dependencyCounts.get(depPath) || 0) + 1);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
return Array.from(dependencyCounts.entries())
|
|
673
|
+
.filter(([_, count]) => count > 1)
|
|
674
|
+
.map(([path, _]) => path);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Check if cycle has TypeScript files
|
|
679
|
+
*/
|
|
680
|
+
hasTypeScriptFiles(cycle) {
|
|
681
|
+
return cycle.some(filePath => filePath.endsWith('.ts') || filePath.endsWith('.tsx'));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Check if modules can be merged
|
|
686
|
+
*/
|
|
687
|
+
canMergeModules(cycle) {
|
|
688
|
+
for (const filePath of cycle) {
|
|
689
|
+
const node = this.nodes.get(filePath);
|
|
690
|
+
if (node && node.metadata.size > 200) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return true;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Auto-resolve cycles
|
|
699
|
+
*/
|
|
700
|
+
async autoResolve() {
|
|
701
|
+
for (const cycle of this.result.cycles) {
|
|
702
|
+
if (cycle.severity === CYCLE_SEVERITY.CRITICAL) {
|
|
703
|
+
// Try to resolve critical cycles automatically
|
|
704
|
+
const strategy = this.result.strategies.find(s => s.applicable && s.effort <= 5);
|
|
705
|
+
if (strategy) {
|
|
706
|
+
try {
|
|
707
|
+
const resolution = await this.applyStrategy(cycle, strategy);
|
|
708
|
+
this.result.addResolved(resolution);
|
|
709
|
+
} catch (error) {
|
|
710
|
+
this.result.addFailed({ cycle, strategy, error: error.message });
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Apply a resolution strategy
|
|
719
|
+
*/
|
|
720
|
+
async applyStrategy(cycle, strategy) {
|
|
721
|
+
// This would implement the actual resolution
|
|
722
|
+
// For now, return a placeholder resolution
|
|
723
|
+
return {
|
|
724
|
+
cycle: cycle.cycle,
|
|
725
|
+
strategy: strategy.type,
|
|
726
|
+
success: true,
|
|
727
|
+
changes: []
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Get or create node
|
|
733
|
+
*/
|
|
734
|
+
getOrCreateNode(filePath) {
|
|
735
|
+
if (!this.nodes.has(filePath)) {
|
|
736
|
+
this.nodes.set(filePath, new DependencyNode(filePath));
|
|
737
|
+
}
|
|
738
|
+
return this.nodes.get(filePath);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Calculate total dependencies
|
|
743
|
+
*/
|
|
744
|
+
calculateTotalDependencies() {
|
|
745
|
+
let total = 0;
|
|
746
|
+
for (const node of this.nodes.values()) {
|
|
747
|
+
total += node.getDependencyCount();
|
|
748
|
+
}
|
|
749
|
+
return total;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Get statistics
|
|
754
|
+
*/
|
|
755
|
+
getStatistics() {
|
|
756
|
+
const cyclesBySeverity = {
|
|
757
|
+
[CYCLE_SEVERITY.CRITICAL]: 0,
|
|
758
|
+
[CYCLE_SEVERITY.HIGH]: 0,
|
|
759
|
+
[CYCLE_SEVERITY.MEDIUM]: 0,
|
|
760
|
+
[CYCLE_SEVERITY.LOW]: 0
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
for (const cycle of this.result.cycles) {
|
|
764
|
+
cyclesBySeverity[cycle.severity]++;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
return {
|
|
768
|
+
totalFiles: this.result.metadata.totalFiles,
|
|
769
|
+
totalDependencies: this.result.metadata.totalDependencies,
|
|
770
|
+
cyclesFound: this.result.cycles.length,
|
|
771
|
+
cyclesBySeverity,
|
|
772
|
+
strategiesGenerated: this.result.strategies.length,
|
|
773
|
+
cyclesResolved: this.result.resolved.length,
|
|
774
|
+
cyclesFailed: this.result.failed.length
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Export dependency graph
|
|
780
|
+
*/
|
|
781
|
+
exportGraph(format = 'json') {
|
|
782
|
+
const graph = {
|
|
783
|
+
nodes: Array.from(this.nodes.entries()).map(([path, node]) => ({
|
|
784
|
+
path,
|
|
785
|
+
dependencies: Array.from(node.dependencies),
|
|
786
|
+
dependents: Array.from(node.dependents),
|
|
787
|
+
metadata: node.metadata
|
|
788
|
+
})),
|
|
789
|
+
cycles: this.result.cycles.map(cycle => cycle.getSummary()),
|
|
790
|
+
strategies: this.result.strategies.map(strategy => strategy.getSummary())
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
if (format === 'json') {
|
|
794
|
+
return JSON.stringify(graph, null, 2);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
return graph;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
module.exports = {
|
|
802
|
+
CircularDependencyResolver,
|
|
803
|
+
CircularDependencyResult,
|
|
804
|
+
CircularDependency,
|
|
805
|
+
DependencyNode,
|
|
806
|
+
ResolutionStrategy,
|
|
807
|
+
DEPENDENCY_TYPES,
|
|
808
|
+
CYCLE_SEVERITY
|
|
809
|
+
};
|