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
149 lines • 6.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AIEnhancedFixCyclesUseCase = void 0;
const CodebasePatternAnalyzer_1 = require("./ai/CodebasePatternAnalyzer");
const AIStrategySelector_1 = require("./ai/AIStrategySelector");
const AIRefactoringGenerator_1 = require("./ai/AIRefactoringGenerator");
class AIEnhancedFixCyclesUseCase {
constructor(fileSystem, strategies, aiProvider) {
this.fileSystem = fileSystem;
this.strategies = strategies;
this.aiProvider = aiProvider;
this.patternAnalyzer = new CodebasePatternAnalyzer_1.CodebasePatternAnalyzer(aiProvider, fileSystem);
this.strategySelector = new AIStrategySelector_1.AIStrategySelector(aiProvider, fileSystem);
this.refactoringGenerator = new AIRefactoringGenerator_1.AIRefactoringGenerator(aiProvider, fileSystem);
}
async execute(cycles, modules, options) {
const results = [];
let codebaseAnalysis;
if (options.useAI && this.aiProvider.isAvailable()) {
console.log('🤖 Analyzing codebase patterns with AI...');
codebaseAnalysis = await this.patternAnalyzer.analyzeArchitecture(modules);
console.log(` Architecture: ${codebaseAnalysis.architecture}`);
console.log(` Patterns found: ${codebaseAnalysis.patterns.length}`);
}
for (const cycle of cycles) {
const result = await this.fixCycle(cycle, modules, options, codebaseAnalysis);
results.push(result);
}
return results;
}
async fixCycle(cycle, modules, options, codebaseAnalysis) {
let aiRecommendation;
if (options.useAI && this.aiProvider.isAvailable() && codebaseAnalysis) {
console.log(`🤖 Getting AI recommendation for cycle ${cycle.id}...`);
aiRecommendation = await this.strategySelector.recommendStrategy(cycle, modules, codebaseAnalysis, this.strategies);
if (aiRecommendation) {
console.log(` Recommended: ${aiRecommendation.strategy} (${aiRecommendation.confidence}% confidence)`);
console.log(` Reasoning: ${aiRecommendation.reasoning}`);
}
}
const applicableStrategies = await this.findApplicableStrategies(cycle, modules, options, aiRecommendation);
if (applicableStrategies.length === 0) {
return await this.createNoStrategyResult(cycle, options, modules);
}
for (const { strategy } of applicableStrategies) {
try {
const result = await strategy.fix(cycle, modules, this.fileSystem, options.dryRun);
if (result.success && options.explainWithAI && this.aiProvider.isAvailable()) {
console.log(' ✓ Fix successful');
}
if (!result.success && options.generateCode && this.aiProvider.isAvailable()) {
console.log(' 🤖 Generating AI-powered refactoring suggestions...');
const aiSteps = await this.refactoringGenerator.generateManualSteps(cycle, modules, strategy.type);
if (aiSteps.length > 0) {
return {
...result,
manualSteps: aiSteps,
};
}
}
if (result.success || result.manualSteps) {
return result;
}
}
catch (error) {
continue;
}
}
return await this.createFailureResult(cycle, applicableStrategies, options, modules);
}
async findApplicableStrategies(cycle, modules, options, aiRecommendation) {
const applicable = [];
for (const strategy of this.strategies) {
if (options.strategies.length > 0 && !options.strategies.includes(strategy.type)) {
continue;
}
const canFix = await strategy.canFix(cycle, modules);
if (!canFix) {
continue;
}
let score = strategy.score(cycle, modules);
if (aiRecommendation &&
aiRecommendation.strategy === strategy.type &&
aiRecommendation.confidence > 70) {
score += 30;
}
applicable.push({ strategy, score });
}
return applicable.sort((a, b) => b.score - a.score);
}
async createNoStrategyResult(cycle, options, modules) {
let manualSteps = [
{
description: 'Review the circular dependency and refactor manually',
file: cycle.paths[0],
},
{
description: 'Consider extracting shared code or using dependency injection',
file: cycle.paths[0],
},
];
if (options.explainWithAI && this.aiProvider.isAvailable()) {
const explanation = await this.refactoringGenerator.explainCycle(cycle, modules);
manualSteps = [
{
description: 'AI Analysis',
file: cycle.paths[0],
code: explanation,
},
...manualSteps,
];
}
return {
cycle,
strategy: cycle.paths.length === 2 ? cycle.paths[0] : null,
success: false,
modifiedFiles: [],
createdFiles: [],
error: 'No applicable fix strategy found',
manualSteps,
};
}
async createFailureResult(cycle, attemptedStrategies, options, modules) {
const strategyNames = attemptedStrategies.map((s) => s.strategy.type).join(', ');
let manualSteps = [
{
description: 'Manual intervention required to fix this cycle',
file: cycle.paths[0],
},
];
if (options.generateCode && this.aiProvider.isAvailable() && attemptedStrategies.length > 0) {
const aiSteps = await this.refactoringGenerator.generateManualSteps(cycle, modules, attemptedStrategies[0].strategy.type);
if (aiSteps.length > 0) {
manualSteps = [...aiSteps];
}
}
return {
cycle,
strategy: attemptedStrategies[0]?.strategy.type || '',
success: false,
modifiedFiles: [],
createdFiles: [],
error: `All strategies failed: ${strategyNames}`,
manualSteps,
};
}
}
exports.AIEnhancedFixCyclesUseCase = AIEnhancedFixCyclesUseCase;
//# sourceMappingURL=AIEnhancedFixCyclesUseCase.js.map