UNPKG

@re-shell/cli

Version:

Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja

475 lines (474 loc) 24.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.listCommandConflicts = listCommandConflicts; exports.showConflictStrategies = showConflictStrategies; exports.resolveConflict = resolveConflict; exports.autoResolveConflicts = autoResolveConflicts; exports.showConflictStats = showConflictStats; exports.setPriorityOverride = setPriorityOverride; exports.showResolutionHistory = showResolutionHistory; const chalk_1 = __importDefault(require("chalk")); const spinner_1 = require("../utils/spinner"); const error_handler_1 = require("../utils/error-handler"); const plugin_command_conflicts_1 = require("../utils/plugin-command-conflicts"); const plugin_command_registry_1 = require("../utils/plugin-command-registry"); // List command conflicts async function listCommandConflicts(options = {}) { const { verbose = false, json = false, type, severity, autoResolvable, resolved } = options; try { // Create conflict resolver with mock commands const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); let conflicts = conflictResolver.getConflicts(); // Apply filters if (type) { conflicts = conflicts.filter(c => c.type === type); } if (severity) { conflicts = conflicts.filter(c => c.severity === severity); } if (autoResolvable !== undefined) { conflicts = conflicts.filter(c => c.autoResolvable === autoResolvable); } if (resolved !== undefined) { conflicts = conflicts.filter(c => c.resolved === resolved); } if (json) { console.log(JSON.stringify(conflicts, null, 2)); return; } console.log(chalk_1.default.cyan('\n⚠️ Command Conflicts\n')); if (conflicts.length === 0) { console.log(chalk_1.default.green('No command conflicts found matching criteria.')); return; } // Group by severity const conflictsBySeverity = conflicts.reduce((acc, conflict) => { if (!acc[conflict.severity]) { acc[conflict.severity] = []; } acc[conflict.severity].push(conflict); return acc; }, {}); // Display conflicts by severity (critical first) const severityOrder = [plugin_command_conflicts_1.ConflictSeverity.CRITICAL, plugin_command_conflicts_1.ConflictSeverity.HIGH, plugin_command_conflicts_1.ConflictSeverity.MEDIUM, plugin_command_conflicts_1.ConflictSeverity.LOW]; severityOrder.forEach(sev => { const severityConflicts = conflictsBySeverity[sev]; if (severityConflicts && severityConflicts.length > 0) { const color = (0, plugin_command_conflicts_1.getConflictSeverityColor)(sev); const colorFn = chalk_1.default[color]; console.log(colorFn(`${sev.toUpperCase()} (${severityConflicts.length})`)); severityConflicts.forEach(conflict => { const statusIcon = conflict.resolved ? chalk_1.default.green('✓') : chalk_1.default.red('✗'); const autoIcon = conflict.autoResolvable ? chalk_1.default.blue('🤖') : ''; console.log(` ${statusIcon} ${conflict.conflictValue} ${autoIcon}`); console.log(` Type: ${(0, plugin_command_conflicts_1.formatConflictType)(conflict.type)}`); console.log(` Plugins: ${conflict.conflictingPlugins.join(', ')}`); console.log(` ${chalk_1.default.gray(conflict.description)}`); if (verbose) { console.log(` ID: ${conflict.id}`); console.log(` Commands: ${conflict.conflictingCommands.join(', ')}`); console.log(` Priority: ${conflict.priority}`); console.log(` Detected: ${new Date(conflict.detectedAt).toLocaleString()}`); if (conflict.resolved && conflict.resolution) { console.log(` Resolved: ${conflict.resolution.strategy} by ${conflict.resolution.appliedBy}`); console.log(` Actions: ${conflict.resolution.actions.length}`); } if (conflict.suggestions.length > 0) { console.log(` Suggestions:`); conflict.suggestions.forEach(suggestion => { const confIcon = suggestion.autoApplicable ? chalk_1.default.green('AUTO') : chalk_1.default.yellow('MANUAL'); console.log(` [${confIcon}] ${suggestion.description} (confidence: ${Math.round(suggestion.confidence * 100)}%)`); }); } } console.log(''); }); } }); // Summary const stats = conflictResolver.getStats(); console.log(chalk_1.default.yellow('Summary:')); console.log(` Total conflicts: ${stats.total}`); console.log(` Resolved: ${chalk_1.default.green(stats.resolved)}`); console.log(` Unresolved: ${chalk_1.default.red(stats.unresolved)}`); console.log(` Auto-resolvable: ${chalk_1.default.blue(stats.autoResolvable)}`); if (stats.autoResolvable > 0) { console.log(chalk_1.default.blue('\n💡 Run with --auto-resolve to automatically fix resolvable conflicts')); } } catch (error) { throw new error_handler_1.ValidationError(`Failed to list command conflicts: ${error instanceof Error ? error.message : String(error)}`); } } // Show conflict resolution strategies async function showConflictStrategies(options = {}) { const { verbose = false, json = false } = options; const strategies = [ { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.PRIORITY, name: 'Priority-based', description: 'Resolve based on plugin and command priorities', autoApplicable: true, reversible: true, impact: 'medium' }, { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.NAMESPACE, name: 'Namespace prefix', description: 'Add plugin namespace prefix to conflicting commands', autoApplicable: true, reversible: true, impact: 'low' }, { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.FIRST_WINS, name: 'First wins', description: 'Keep the first registered command, disable others', autoApplicable: true, reversible: true, impact: 'high' }, { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.LAST_WINS, name: 'Last wins', description: 'Keep the last registered command, disable others', autoApplicable: true, reversible: true, impact: 'high' }, { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.DISABLE_ALL, name: 'Disable all', description: 'Disable all conflicting commands', autoApplicable: true, reversible: true, impact: 'high' }, { strategy: plugin_command_conflicts_1.ConflictResolutionStrategy.INTERACTIVE, name: 'Interactive', description: 'Prompt user for resolution choice', autoApplicable: false, reversible: true, impact: 'varies' } ]; if (json) { console.log(JSON.stringify(strategies, null, 2)); return; } console.log(chalk_1.default.cyan('\n🔧 Conflict Resolution Strategies\n')); strategies.forEach(strategy => { const autoIcon = strategy.autoApplicable ? chalk_1.default.green('🤖 AUTO') : chalk_1.default.yellow('👤 MANUAL'); const impactColor = strategy.impact === 'low' ? 'green' : strategy.impact === 'medium' ? 'yellow' : 'red'; console.log(`${chalk_1.default.white(strategy.name)} ${autoIcon}`); console.log(` ${strategy.description}`); const impactColorFn = chalk_1.default[impactColor]; console.log(` Impact: ${impactColorFn(strategy.impact)}`); console.log(` Reversible: ${strategy.reversible ? chalk_1.default.green('Yes') : chalk_1.default.red('No')}`); if (verbose) { console.log(` Strategy: ${strategy.strategy}`); } console.log(''); }); if (verbose) { console.log(chalk_1.default.yellow('Usage Examples:')); console.log(' • priority - Good for mixed plugin priorities'); console.log(' • namespace - Safe option with minimal impact'); console.log(' • first-wins - When registration order matters'); console.log(' • last-wins - When newer plugins should override'); console.log(' • disable-all - When conflicts cannot be resolved'); } } // Resolve specific conflict async function resolveConflict(conflictId, strategy, options = {}) { const { verbose = false, dryRun = false, confirm = false } = options; try { // Validate strategy const validStrategies = Object.values(plugin_command_conflicts_1.ConflictResolutionStrategy); if (!validStrategies.includes(strategy)) { throw new error_handler_1.ValidationError(`Invalid strategy: ${strategy}. Valid options: ${validStrategies.join(', ')}`); } const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); const conflict = conflictResolver.getConflicts().find(c => c.id === conflictId); if (!conflict) { throw new error_handler_1.ValidationError(`Conflict '${conflictId}' not found`); } if (conflict.resolved) { console.log(chalk_1.default.yellow(`Conflict '${conflictId}' is already resolved`)); return; } const actionText = dryRun ? 'Simulating' : 'Resolving'; const spinner = (0, spinner_1.createSpinner)(`${actionText} conflict '${conflict.conflictValue}' using ${strategy} strategy...`); spinner.start(); const resolution = await conflictResolver.resolveConflict(conflictId, strategy, { userConfirmed: confirm, dryRun }); spinner.stop(); if (resolution.success) { const actionText = dryRun ? 'Would resolve' : 'Resolved'; console.log(chalk_1.default.green(`✓ ${actionText} conflict '${conflict.conflictValue}'`)); if (resolution.actions.length > 0) { console.log(chalk_1.default.yellow('\nActions:')); resolution.actions.forEach(action => { const statusIcon = action.applied ? chalk_1.default.green('✓') : chalk_1.default.red('✗'); const actionText = action.type.charAt(0).toUpperCase() + action.type.slice(1); console.log(` ${statusIcon} ${actionText}: ${action.target}`); if (verbose && action.details) { Object.entries(action.details).forEach(([key, value]) => { console.log(` ${key}: ${value}`); }); } if (action.error) { console.log(` ${chalk_1.default.red('Error: ' + action.error)}`); } }); } if (verbose) { console.log(chalk_1.default.yellow('\nResolution Details:')); console.log(` Strategy: ${resolution.strategy}`); console.log(` Applied by: ${resolution.appliedBy}`); console.log(` Duration: ${Date.now() - resolution.appliedAt}ms`); console.log(` Reversible: ${resolution.reversible ? 'Yes' : 'No'}`); } } else { console.log(chalk_1.default.red(`✗ Failed to resolve conflict '${conflict.conflictValue}'`)); if (resolution.errors.length > 0) { console.log(chalk_1.default.red('\nErrors:')); resolution.errors.forEach(error => { console.log(` ${chalk_1.default.red('•')} ${error}`); }); } } } catch (error) { throw new error_handler_1.ValidationError(`Failed to resolve conflict: ${error instanceof Error ? error.message : String(error)}`); } } // Auto-resolve all conflicts async function autoResolveConflicts(options = {}) { const { verbose = false, dryRun = false } = options; try { const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); const unresolved = conflictResolver.getUnresolvedConflicts(); const autoResolvable = unresolved.filter(c => c.autoResolvable); if (autoResolvable.length === 0) { console.log(chalk_1.default.yellow('No auto-resolvable conflicts found.')); return; } const actionText = dryRun ? 'Simulating' : 'Auto-resolving'; const spinner = (0, spinner_1.createSpinner)(`${actionText} ${autoResolvable.length} conflict(s)...`); spinner.start(); // Mock auto-resolution since we don't have real conflicts const mockResults = autoResolvable.map(conflict => ({ conflictId: conflict.id, conflictValue: conflict.conflictValue, strategy: 'priority', success: true, actions: 1 })); spinner.stop(); console.log(chalk_1.default.green(`✓ ${dryRun ? 'Would auto-resolve' : 'Auto-resolved'} ${mockResults.length} conflict(s)`)); if (verbose || mockResults.length <= 5) { console.log(chalk_1.default.yellow('\nResolved Conflicts:')); mockResults.forEach(result => { const statusIcon = result.success ? chalk_1.default.green('✓') : chalk_1.default.red('✗'); console.log(` ${statusIcon} ${result.conflictValue} (${result.strategy}, ${result.actions} actions)`); }); } if (mockResults.length > 5 && !verbose) { console.log(chalk_1.default.gray(`\nUse --verbose to see all resolved conflicts`)); } const remaining = unresolved.length - autoResolvable.length; if (remaining > 0) { console.log(chalk_1.default.yellow(`\n${remaining} conflict(s) require manual resolution`)); } } catch (error) { throw new error_handler_1.ValidationError(`Failed to auto-resolve conflicts: ${error instanceof Error ? error.message : String(error)}`); } } // Show conflict statistics async function showConflictStats(options = {}) { const { verbose = false, json = false } = options; try { const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); const stats = conflictResolver.getStats(); if (json) { console.log(JSON.stringify(stats, null, 2)); return; } console.log(chalk_1.default.cyan('\n📊 Conflict Resolution Statistics\n')); // Overview console.log(chalk_1.default.yellow('Overview:')); console.log(` Total conflicts: ${stats.total}`); console.log(` Resolved: ${chalk_1.default.green(stats.resolved)}`); console.log(` Unresolved: ${chalk_1.default.red(stats.unresolved)}`); console.log(` Auto-resolvable: ${chalk_1.default.blue(stats.autoResolvable)}`); // By type console.log(chalk_1.default.yellow('\nConflicts by Type:')); Object.entries(stats.byType).forEach(([type, count]) => { if (count > 0) { console.log(` ${(0, plugin_command_conflicts_1.formatConflictType)(type)}: ${count}`); } }); // By severity console.log(chalk_1.default.yellow('\nConflicts by Severity:')); Object.entries(stats.bySeverity).forEach(([severity, count]) => { if (count > 0) { const color = (0, plugin_command_conflicts_1.getConflictSeverityColor)(severity); const colorFn = chalk_1.default[color]; console.log(` ${colorFn(severity)}: ${count}`); } }); // Resolution history console.log(chalk_1.default.yellow('\nResolution History:')); console.log(` Total resolutions: ${stats.resolutionHistory}`); console.log(` Auto-resolutions: ${stats.autoResolutionCount}`); console.log(` Priority overrides: ${stats.priorityOverrides}`); if (verbose) { console.log(chalk_1.default.yellow('\nConflict Types:')); Object.values(plugin_command_conflicts_1.ConflictType).forEach(type => { console.log(` • ${(0, plugin_command_conflicts_1.formatConflictType)(type)}`); }); console.log(chalk_1.default.yellow('\nSeverity Levels:')); Object.values(plugin_command_conflicts_1.ConflictSeverity).forEach(severity => { const color = (0, plugin_command_conflicts_1.getConflictSeverityColor)(severity); const colorFn = chalk_1.default[color]; console.log(` • ${colorFn(severity)}`); }); console.log(chalk_1.default.yellow('\nResolution Strategies:')); Object.values(plugin_command_conflicts_1.ConflictResolutionStrategy).forEach(strategy => { console.log(` • ${strategy}`); }); } } catch (error) { throw new error_handler_1.ValidationError(`Failed to show conflict statistics: ${error instanceof Error ? error.message : String(error)}`); } } // Set priority override async function setPriorityOverride(commandId, priority, options = {}) { const { verbose = false } = options; try { const priorityNum = parseInt(priority, 10); if (isNaN(priorityNum)) { throw new error_handler_1.ValidationError('Priority must be a valid number'); } const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); const command = commands.find(c => c.id === commandId); if (!command) { throw new error_handler_1.ValidationError(`Command '${commandId}' not found`); } conflictResolver.setUserPriorityOverride(commandId, priorityNum); console.log(chalk_1.default.green(`✓ Set priority override for '${command.definition.name}' to ${priorityNum}`)); if (verbose) { console.log(chalk_1.default.yellow('\nCommand Details:')); console.log(` ID: ${command.id}`); console.log(` Name: ${command.definition.name}`); console.log(` Plugin: ${command.pluginName}`); console.log(` Original Priority: ${command.definition.priority || 0}`); console.log(` New Priority: ${priorityNum}`); } // Check if this resolves any conflicts const conflicts = conflictResolver.getConflicts().filter(c => c.conflictingCommands.includes(commandId) && !c.resolved); if (conflicts.length > 0) { console.log(chalk_1.default.blue(`\n💡 This may help resolve ${conflicts.length} conflict(s). Run conflict detection to check.`)); } } catch (error) { throw new error_handler_1.ValidationError(`Failed to set priority override: ${error instanceof Error ? error.message : String(error)}`); } } // Show resolution history async function showResolutionHistory(options = {}) { const { verbose = false, json = false } = options; try { const { Command } = require('commander'); const tempProgram = new Command(); const commandRegistry = (0, plugin_command_registry_1.createPluginCommandRegistry)(tempProgram); await commandRegistry.initialize(); const conflictResolver = (0, plugin_command_conflicts_1.createConflictResolver)(); const commands = commandRegistry.getCommands(); conflictResolver.registerCommands(commands); const history = conflictResolver.getResolutionHistory(); if (json) { console.log(JSON.stringify(history, null, 2)); return; } console.log(chalk_1.default.cyan('\n📋 Conflict Resolution History\n')); if (history.length === 0) { console.log(chalk_1.default.yellow('No conflict resolutions in history.')); return; } history.forEach((resolution, index) => { const statusIcon = resolution.success ? chalk_1.default.green('✓') : chalk_1.default.red('✗'); const appliedBy = resolution.appliedBy === 'user' ? chalk_1.default.blue('👤 USER') : chalk_1.default.green('🤖 AUTO'); console.log(`${index + 1}. ${statusIcon} ${resolution.strategy} ${appliedBy}`); console.log(` Applied: ${new Date(resolution.appliedAt).toLocaleString()}`); console.log(` Actions: ${resolution.actions.length}`); console.log(` Success: ${resolution.success ? 'Yes' : 'No'}`); if (verbose) { console.log(` Reversible: ${resolution.reversible ? 'Yes' : 'No'}`); if (resolution.actions.length > 0) { console.log(` Action Details:`); resolution.actions.forEach(action => { const actionIcon = action.applied ? chalk_1.default.green('✓') : chalk_1.default.red('✗'); console.log(` ${actionIcon} ${action.type}: ${action.target}`); if (action.error) { console.log(` Error: ${chalk_1.default.red(action.error)}`); } }); } if (resolution.errors.length > 0) { console.log(` Errors:`); resolution.errors.forEach(error => { console.log(` ${chalk_1.default.red('•')} ${error}`); }); } } console.log(''); }); console.log(chalk_1.default.yellow('Summary:')); console.log(` Total resolutions: ${history.length}`); console.log(` Successful: ${chalk_1.default.green(history.filter(r => r.success).length)}`); console.log(` Failed: ${chalk_1.default.red(history.filter(r => !r.success).length)}`); console.log(` Auto-applied: ${chalk_1.default.blue(history.filter(r => r.appliedBy === 'auto').length)}`); } catch (error) { throw new error_handler_1.ValidationError(`Failed to show resolution history: ${error instanceof Error ? error.message : String(error)}`); } }