context-forge
Version:
AI orchestration platform with autonomous teams, enhancement planning, migration tools, 25+ slash commands, checkpoints & hooks. Multi-IDE: Claude, Cursor, Windsurf, Cline, Copilot
372 lines (347 loc) ⢠19.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.migrateCommand = void 0;
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const path_1 = __importDefault(require("path"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const adapters_1 = require("../../adapters");
const projectAnalyzer_1 = require("../../services/projectAnalyzer");
const migrationAnalyzer_1 = require("../../services/migrationAnalyzer");
const migration_1 = require("../prompts/migration");
const generators_1 = require("../../generators");
const migrationPrp_1 = require("../../generators/migrationPrp");
const migrationCheckpoints_1 = require("../../generators/migrationCheckpoints");
const migrationHooks_1 = require("../../generators/migrationHooks");
const errorRecoveryService_1 = require("../../services/errorRecoveryService");
exports.migrateCommand = new commander_1.Command('migrate')
.description('Create a comprehensive migration plan for technology stack transitions')
.option('-o, --output <path>', 'output directory for migration files', '.')
.option('-s, --source <stack>', 'source technology stack (auto-detected if not provided)')
.option('-t, --target <stack>', 'target technology stack')
.option('-i, --ide <ide>', 'target IDE (claude, cursor, windsurf, cline, roo, gemini, copilot)', (value) => {
const validIDEs = (0, adapters_1.getSupportedIDEs)();
const ides = value.split(',').map((ide) => ide.trim());
for (const ide of ides) {
if (!validIDEs.includes(ide)) {
throw new Error(`Invalid IDE: ${ide}. Valid options: ${validIDEs.join(', ')}`);
}
}
return ides;
})
.option('--analyze-only', 'only analyze and show migration complexity without generating files')
.option('--quick', 'skip detailed analysis and use quick migration setup')
.action(async (options) => {
console.log(chalk_1.default.blue.bold('\nš Context Forge Migration Assistant\n'));
console.log(chalk_1.default.gray("Let's create a safe migration plan for your technology transition.\n"));
const spinner = (0, ora_1.default)();
const projectPath = process.cwd();
const outputPath = path_1.default.resolve(options.output);
const errorRecovery = new errorRecoveryService_1.ErrorRecoveryService();
let config;
try {
// Initialize services
const projectAnalyzer = new projectAnalyzer_1.ProjectAnalyzer(projectPath);
// Step 1: Analyze current project
spinner.start('Analyzing current project...');
const basicAnalysis = await projectAnalyzer.analyzeBasic();
spinner.succeed(`Current stack detected: ${basicAnalysis.techStack.join(', ')}`);
// Display project overview
console.log(chalk_1.default.cyan('\nš Current Project Analysis:'));
console.log(` ⢠Type: ${basicAnalysis.projectType}`);
console.log(` ⢠Tech Stack: ${basicAnalysis.techStack.join(', ')}`);
console.log(` ⢠Components: ${basicAnalysis.fileStats.components} files`);
console.log(` ⢠API Routes: ${basicAnalysis.fileStats.routes} files`);
console.log(` ⢠Test Files: ${basicAnalysis.fileStats.tests}`);
// Determine target stack
let targetStack = {};
if (options.target) {
targetStack.name = options.target;
}
else if (!options.quick) {
// Will be determined in prompts
targetStack = {};
}
// Initialize migration analyzer
const migrationAnalyzer = new migrationAnalyzer_1.MigrationAnalyzer(projectPath, targetStack);
// Step 2: Analyze migration complexity
if (!options.quick) {
spinner.start('Analyzing migration complexity...');
const migrationAnalysis = await migrationAnalyzer.analyzeMigration(basicAnalysis);
spinner.succeed('Migration analysis complete');
// Display framework detection results
if (migrationAnalysis.sourceStack.metadata) {
console.log(chalk_1.default.cyan('\nš Framework Detection:'));
console.log(` ⢠Primary: ${chalk_1.default.green(migrationAnalysis.sourceStack.name)} v${migrationAnalysis.sourceStack.version || 'unknown'} (${migrationAnalysis.sourceStack.metadata.confidence}% confidence)`);
const otherFrameworks = migrationAnalysis.sourceStack.metadata.detectedFrameworks
.filter((f) => (f.variant || f.framework) !== migrationAnalysis.sourceStack.name)
.slice(0, 3);
if (otherFrameworks.length > 0) {
console.log(' ⢠Also detected:');
otherFrameworks.forEach((f) => {
const name = f.variant || f.framework;
console.log(` - ${name} ${f.version ? `v${f.version}` : ''} (${f.confidence}% confidence)`);
});
}
}
// Display migration complexity
console.log(chalk_1.default.cyan('\nšÆ Migration Analysis:'));
console.log(` ⢠Complexity: ${chalk_1.default.yellow(migrationAnalysis.complexity.level.toUpperCase())} (${migrationAnalysis.complexity.score}/100)`);
console.log(` ⢠Recommended Strategy: ${chalk_1.default.green(migrationAnalysis.recommendedStrategy)}`);
console.log(` ⢠Estimated Duration: ${chalk_1.default.yellow(migrationAnalysis.estimatedDuration)}`);
console.log(` ⢠Shared Resources: ${migrationAnalysis.sharedResources.length}`);
console.log(` ⢠Risk Factors: ${migrationAnalysis.risks.length}`);
if (migrationAnalysis.complexity.factors.length > 0) {
console.log(chalk_1.default.cyan('\nš Complexity Factors:'));
migrationAnalysis.complexity.factors.forEach((factor) => {
const impact = 'ā'.repeat(factor.impact) + 'ā'.repeat(10 - factor.impact);
console.log(` ⢠${factor.name}: [${impact}] ${factor.impact}/10`);
console.log(` ${chalk_1.default.gray(factor.description)}`);
});
}
if (migrationAnalysis.breakingChangesSummary &&
migrationAnalysis.breakingChangesSummary.total > 0) {
console.log(chalk_1.default.cyan('\nš§ Breaking Changes:'));
console.log(` ⢠Total: ${chalk_1.default.yellow(migrationAnalysis.breakingChangesSummary.total)} changes detected`);
console.log(` ⢠Critical: ${chalk_1.default.red(migrationAnalysis.breakingChangesSummary.critical)}`);
console.log(` ⢠Automatable: ${chalk_1.default.green(migrationAnalysis.breakingChangesSummary.automatable)}`);
console.log(` ⢠Est. Hours: ${chalk_1.default.yellow(migrationAnalysis.breakingChangesSummary.estimatedHours)}`);
if (migrationAnalysis.breakingChanges && migrationAnalysis.breakingChanges.length > 0) {
console.log(chalk_1.default.gray('\n Top Breaking Changes:'));
migrationAnalysis.breakingChanges.slice(0, 3).forEach((change) => {
const icon = change.severity === 'critical' ? 'š“' : change.severity === 'high' ? 'š”' : 'š¢';
console.log(` ${icon} ${change.description}`);
if (change.automatable) {
console.log(chalk_1.default.green(` ā Automatable - ${change.effort} effort`));
}
else {
console.log(chalk_1.default.yellow(` ā Manual migration required - ${change.effort} effort`));
}
});
}
}
if (migrationAnalysis.dependencyAnalysis &&
migrationAnalysis.dependencyAnalysis.totalDependencies > 0) {
console.log(chalk_1.default.cyan('\nš¦ Dependency Analysis:'));
console.log(` ⢠Total Dependencies: ${chalk_1.default.yellow(migrationAnalysis.dependencyAnalysis.totalDependencies)}`);
console.log(` ⢠Incompatible: ${chalk_1.default.red(migrationAnalysis.dependencyAnalysis.incompatibleCount)}`);
console.log(` ⢠Replacements Available: ${chalk_1.default.green(migrationAnalysis.dependencyAnalysis.hasReplacements)}`);
console.log(` ⢠Complexity: ${chalk_1.default.yellow(migrationAnalysis.dependencyAnalysis.migrationComplexity.toUpperCase())}`);
if (migrationAnalysis.dependencyAnalysis.incompatible.length > 0) {
console.log(chalk_1.default.gray('\n Top Incompatible Dependencies:'));
migrationAnalysis.dependencyAnalysis.incompatible.slice(0, 3).forEach((dep) => {
const icon = dep.severity === 'critical' ? 'š“' : dep.severity === 'high' ? 'š”' : 'š¢';
console.log(` ${icon} ${dep.package} - ${dep.reason}`);
if (dep.resolution) {
console.log(chalk_1.default.green(` ā ${dep.resolution}`));
}
});
}
}
if (migrationAnalysis.risks.length > 0) {
console.log(chalk_1.default.cyan('\nā ļø Migration Risks:'));
migrationAnalysis.risks.slice(0, 5).forEach((risk) => {
const icon = risk.impact === 'critical' ? 'š“' : risk.impact === 'high' ? 'š”' : 'š¢';
console.log(` ${icon} ${risk.description}`);
console.log(` Impact: ${risk.impact}, Probability: ${risk.probability}`);
console.log(` Mitigation: ${chalk_1.default.gray(risk.mitigation)}`);
});
}
if (options.analyzeOnly) {
console.log(chalk_1.default.green('\nā
Analysis complete!'));
return;
}
}
// Step 3: Run migration prompts
spinner.stop(); // Stop spinner before interactive prompts
config = await (0, migration_1.runMigrationPrompts)(basicAnalysis, targetStack, options.ide, options.quick);
// Step 4: Generate migration artifacts
console.log(chalk_1.default.blue.bold('\nš Generating migration artifacts...\n'));
// Generate base documentation
spinner.start('Generating base documentation...');
await (0, generators_1.generateDocumentation)(config, outputPath);
spinner.succeed('Base documentation generated');
// Generate migration-specific PRPs
if (config.migrationConfig) {
spinner.start('Generating migration PRPs...');
const migrationPRPs = await (0, migrationPrp_1.generateMigrationPRPs)(config);
for (const prp of migrationPRPs) {
const prpPath = path_1.default.join(outputPath, prp.path);
await fs_extra_1.default.ensureDir(path_1.default.dirname(prpPath));
await fs_extra_1.default.writeFile(prpPath, prp.content);
}
spinner.succeed(`Generated ${migrationPRPs.length} migration PRPs`);
// Generate migration checkpoints
if (config.extras.checkpoints) {
spinner.start('Generating migration checkpoints...');
await (0, migrationCheckpoints_1.generateMigrationCheckpoints)(config);
// Checkpoints are integrated into slash commands
spinner.succeed('Migration checkpoints configured');
}
// Generate migration hooks
if (config.extras.hooks) {
spinner.start('Generating migration hooks...');
const hooks = await (0, migrationHooks_1.generateMigrationHooks)(config);
for (const hook of hooks) {
const hookPath = path_1.default.join(outputPath, hook.path);
await fs_extra_1.default.ensureDir(path_1.default.dirname(hookPath));
await fs_extra_1.default.writeFile(hookPath, hook.content);
if (hook.path.endsWith('.py')) {
await fs_extra_1.default.chmod(hookPath, 0o755);
}
}
spinner.succeed(`Generated ${hooks.length} migration hooks`);
}
}
// Generate migration summary
const summaryContent = await generateMigrationSummary(config, basicAnalysis);
const summaryPath = path_1.default.join(outputPath, 'MIGRATION_PLAN.md');
await fs_extra_1.default.writeFile(summaryPath, summaryContent);
// Success message
console.log(chalk_1.default.green.bold('\n⨠Migration plan generated successfully!\n'));
// Show file structure
console.log(chalk_1.default.cyan('š Generated Migration Structure:'));
console.log(chalk_1.default.gray(' ' + outputPath + '/'));
console.log(' āāā MIGRATION_PLAN.md');
console.log(' āāā CLAUDE.md (updated with migration context)');
if (config && config.migrationConfig) {
console.log(' āāā PRPs/');
console.log(' ā āāā migration-overview.md');
config.migrationConfig.migrationPhases.forEach((phase, index) => {
const isLast = index === config.migrationConfig.migrationPhases.length - 1;
console.log(` ā ${isLast ? 'āāā' : 'āāā'} phase-${phase.id}.md`);
});
if (config.extras.checkpoints) {
console.log(' āāā .claude/');
console.log(' ā āāā commands/');
console.log(' ā āāā migration/');
console.log(' ā āāā migration-status.md');
console.log(' ā āāā migration-checkpoint.md');
}
}
// Next steps
console.log(chalk_1.default.blue.bold('\nšÆ Next Steps:\n'));
console.log(chalk_1.default.white('1. Review MIGRATION_PLAN.md for the complete strategy'));
console.log(chalk_1.default.white('2. Check PRPs folder for phase-specific implementation guides'));
console.log(chalk_1.default.white('3. Use /migration-status to track progress'));
console.log(chalk_1.default.white('4. Follow checkpoints at critical milestones'));
console.log(chalk_1.default.white('5. Test rollback procedures before production changes'));
if (config && config.migrationConfig && config.migrationConfig.sharedResources.length > 0) {
console.log(chalk_1.default.yellow('\nā ļø Important Reminders:'));
config.migrationConfig.sharedResources.forEach((resource) => {
if (resource.criticalityLevel === 'critical') {
console.log(chalk_1.default.red(` ⢠${resource.name}: ${resource.migrationStrategy}`));
}
});
}
}
catch (error) {
spinner.fail('Migration planning failed');
// Use error recovery service to provide intelligent suggestions
await errorRecovery.handleError(error, {
command: 'migrate',
operation: 'migration planning',
projectPath,
config,
});
throw error;
}
});
async function generateMigrationSummary(config, basicAnalysis) {
const migration = config.migrationConfig;
if (!migration) {
return '# Migration Plan\n\nNo migration configuration generated.';
}
return `# Migration Plan: ${config.projectName}
Generated on: ${new Date().toLocaleString()}
## Executive Summary
**Migration**: ${migration.sourceStack.name} ā ${migration.targetStack.name}
**Strategy**: ${migration.strategy}
**Risk Level**: ${migration.riskLevel.toUpperCase()}
**Estimated Duration**: ${migration.migrationPhases.length} phases
## Current State Analysis
- **Project Type**: ${config.projectType}
- **Current Stack**: ${basicAnalysis.techStack.join(', ')}
- **Components**: ${basicAnalysis.fileStats.components} files
- **API Routes**: ${basicAnalysis.fileStats.routes} files
- **Test Coverage**: ${basicAnalysis.fileStats.tests} test files
## Migration Strategy: ${migration.strategy}
${migration.strategy === 'parallel-run'
? `### Parallel Run Approach
Both systems will run simultaneously during migration, allowing for:
- Zero downtime migration
- Gradual traffic shifting
- Easy rollback capability
- A/B testing opportunities`
: migration.strategy === 'incremental'
? `### Incremental Migration
Features will be migrated one at a time, providing:
- Reduced risk per deployment
- Continuous delivery capability
- Early feedback opportunities
- Flexible timeline management`
: `### Big Bang Migration
Complete system replacement in a single cutover:
- Shortest overall timeline
- Single testing phase
- Clear cutover point
- Requires comprehensive preparation`}
## Shared Resources
${migration.sharedResources
.map((resource) => `### ${resource.name} (${resource.type})
- **Criticality**: ${resource.criticalityLevel}
- **Strategy**: ${resource.migrationStrategy}
- **Description**: ${resource.description}`)
.join('\n\n')}
## Migration Phases
${migration.migrationPhases
.map((phase, index) => `### Phase ${index + 1}: ${phase.name}
**Duration**: ${phase.estimatedDuration}
**Rollback Point**: ${phase.rollbackPoint ? 'ā
Yes' : 'ā No'}
${phase.description}
#### Validation Criteria
${phase.validationCriteria.map((criteria) => `- ${criteria}`).join('\n')}
#### Critical Checkpoints
${phase.criticalCheckpoints
.map((checkpoint) => `- **${checkpoint.name}**: ${checkpoint.description}`)
.join('\n')}
`)
.join('\n')}
## Risk Management
### Identified Risks
${migration.rollbackStrategy.triggers
.map((trigger) => `- **${trigger.condition}** (${trigger.severity}): ${trigger.action}`)
.join('\n')}
### Rollback Strategy
- **Automatic Rollback**: ${migration.rollbackStrategy.automatic ? 'Enabled' : 'Manual'}
- **Data Backup Required**: ${migration.rollbackStrategy.dataBackupRequired ? 'Yes' : 'No'}
- **Estimated Rollback Time**: ${migration.rollbackStrategy.estimatedTime}
## Success Criteria
1. All validation criteria met for each phase
2. No critical issues in production
3. Performance metrics within acceptable range
4. Zero data loss during migration
5. Successful rollback capability demonstrated
## Commands and Tools
### Migration Management
- \`/migration-status\` - Check current migration progress
- \`/migration-checkpoint [phase]\` - Trigger manual checkpoint
- \`/migration-validate\` - Run validation suite
- \`/migration-rollback [phase]\` - Execute rollback procedure
### Monitoring
- \`/migration-compare\` - Compare old vs new system metrics
- \`/migration-logs\` - View migration-specific logs
- \`/migration-health\` - System health check
## Resources
- PRPs folder contains detailed implementation guides for each phase
- .claude/hooks contains migration-specific automation
- Checkpoint system will pause at critical points for verification
---
*Generated by Context Forge Migration Assistant*
`;
}
//# sourceMappingURL=migrate.js.map