UNPKG

cyclic-dependency-fixer

Version:

AI-powered tool to detect and fix circular dependencies in JavaScript/TypeScript projects. Features intelligent refactoring with Claude/GPT-4, codebase pattern learning, and context-aware fix recommendations

126 lines (117 loc) 4.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AIStrategySelector = void 0; class AIStrategySelector { constructor(aiProvider, fileSystem) { this.aiProvider = aiProvider; this.fileSystem = fileSystem; } async recommendStrategy(cycle, modules, codebaseAnalysis, availableStrategies) { if (!this.aiProvider.isAvailable()) { return null; } const cycleCode = await this.extractCycleCode(cycle, modules); const prompt = this.buildStrategyPrompt(cycle, cycleCode, codebaseAnalysis, availableStrategies); const response = await this.aiProvider.analyze({ prompt, maxTokens: 2048, temperature: 0.3, systemPrompt: `You are an expert software architect specializing in refactoring circular dependencies. Analyze the circular dependency and recommend the best fix strategy. Consider: 1. The code context and what the modules do 2. The overall codebase architecture 3. Maintainability and readability 4. Type safety 5. Performance implications Respond in JSON format: { "strategy": "extract-shared|dynamic-import|dependency-injection|move-code|barrel-file", "confidence": 0-100, "reasoning": "detailed explanation", "steps": ["step 1", "step 2", ...], "risks": ["risk 1", "risk 2", ...], "alternatives": [{"strategy": "name", "confidence": 0-100}] }`, }); return this.parseRecommendation(response.content); } async extractCycleCode(cycle, modules) { const codeSnippets = []; const uniquePaths = cycle.paths.slice(0, -1); for (const path of uniquePaths) { const module = modules.get(path); if (!module) continue; try { const content = await this.fileSystem.readFile(path); const lines = content.split('\n').slice(0, 100).join('\n'); codeSnippets.push(`// File: ${path}\n${lines}`); } catch { continue; } } return codeSnippets.join('\n\n---\n\n'); } buildStrategyPrompt(cycle, cycleCode, codebaseAnalysis, availableStrategies) { const cycleDescription = this.describeCycle(cycle); const strategyList = availableStrategies.map((s) => s.type).join(', '); return `Analyze this circular dependency and recommend the best fix strategy: **Circular Dependency:** ${cycleDescription} **Codebase Context:** - Architecture: ${codebaseAnalysis.architecture} - Uses Dependency Injection: ${codebaseAnalysis.usesDependencyInjection ? 'Yes' : 'No'} - Coding Style: ${codebaseAnalysis.codingStyle.prefersClasses ? 'OOP' : 'Functional'} - Uses Barrel Files: ${codebaseAnalysis.codingStyle.usesBarrelFiles ? 'Yes' : 'No'} **Detected Patterns:** ${codebaseAnalysis.patterns.map((p) => `- ${p.type}: ${p.description}`).join('\n')} **Code from Circular Dependencies:** ${cycleCode} **Available Fix Strategies:** ${strategyList} Strategy descriptions: - extract-shared: Create a new shared module for common code - dynamic-import: Convert static imports to dynamic imports - dependency-injection: Use dependency injection to break the cycle - move-code: Move code between files to break the cycle - barrel-file: Create a barrel file to centralize exports Recommend the BEST strategy with detailed steps.`; } describeCycle(cycle) { const lines = []; lines.push(`Cycle involves ${cycle.paths.length - 1} modules:`); cycle.paths.forEach((path, i) => { if (i < cycle.paths.length - 1) { lines.push(` ${i + 1}. ${path}`); } }); lines.push('\nImport chain:'); cycle.edges.forEach((edge) => { lines.push(` ${edge.from} -> ${edge.to} (line ${edge.importInfo.line})`); }); return lines.join('\n'); } parseRecommendation(content) { try { const jsonMatch = content.match(/\{[\s\S]*\}/); if (jsonMatch) { const parsed = JSON.parse(jsonMatch[0]); return { strategy: parsed.strategy, confidence: parsed.confidence || 50, reasoning: parsed.reasoning || 'AI recommendation', steps: parsed.steps || [], risks: parsed.risks || [], alternatives: parsed.alternatives || [], }; } } catch { } return null; } } exports.AIStrategySelector = AIStrategySelector; //# sourceMappingURL=AIStrategySelector.js.map