UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

276 lines 10.9 kB
/** * V3 CLI Update Command * Auto-update system for @claude-flow packages (ADR-025) */ import { output } from '../output.js'; import { checkForUpdates, getInstalledVersion, DEFAULT_CONFIG, } from '../update/checker.js'; import { executeMultipleUpdates, rollbackUpdate, getUpdateHistory, clearHistory, } from '../update/executor.js'; import { clearCache } from '../update/rate-limiter.js'; // Helper functions function formatUpdateType(type) { switch (type) { case 'major': return output.error('MAJOR'); case 'minor': return output.warning('minor'); case 'patch': return output.success('patch'); default: return type; } } function formatPriority(priority) { switch (priority) { case 'critical': return output.error('CRITICAL'); case 'high': return output.warning('high'); case 'normal': return output.info('normal'); case 'low': return output.dim('low'); default: return priority; } } // Subcommand: check const checkCommand = { name: 'check', description: 'Check for available @claude-flow package updates', options: [ { name: 'force', description: 'Force check (ignore rate limit)', type: 'boolean' }, { name: 'json', description: 'Output as JSON', type: 'boolean' }, ], async action(ctx) { const { flags } = ctx; if (flags.force) { process.env.CLAUDE_FLOW_FORCE_UPDATE = 'true'; } try { const { results, skipped, reason } = await checkForUpdates(DEFAULT_CONFIG); if (skipped) { output.printInfo(`Update check skipped: ${reason}`); output.writeln('Use --force to check anyway'); return { success: true }; } if (flags.json) { console.log(JSON.stringify(results, null, 2)); return { success: true }; } if (results.length === 0) { output.printSuccess('All @claude-flow packages are up to date!'); return { success: true }; } output.writeln(); output.writeln(output.highlight('═══ Available Updates ═══')); output.writeln(); output.printTable({ columns: [ { key: 'package', header: 'Package' }, { key: 'current', header: 'Current' }, { key: 'latest', header: 'Latest' }, { key: 'type', header: 'Type' }, { key: 'priority', header: 'Priority' }, { key: 'auto', header: 'Auto' }, ], data: results.map((r) => ({ package: r.package, current: r.currentVersion, latest: output.highlight(r.latestVersion), type: formatUpdateType(r.updateType), priority: formatPriority(r.priority), auto: r.shouldAutoUpdate ? output.success('yes') : output.dim('no'), })), }); output.writeln(); const autoUpdates = results.filter((r) => r.shouldAutoUpdate); const manualUpdates = results.filter((r) => !r.shouldAutoUpdate); if (autoUpdates.length > 0) { output.printInfo(`${autoUpdates.length} update(s) will be applied automatically on next startup`); } if (manualUpdates.length > 0) { output.writeln(); output.printInfo('To update manually, run:'); output.writeln(' claude-flow update all'); } return { success: true }; } finally { delete process.env.CLAUDE_FLOW_FORCE_UPDATE; } }, }; // Subcommand: all const allCommand = { name: 'all', description: 'Update all @claude-flow packages', options: [ { name: 'dry-run', description: 'Show what would be updated', type: 'boolean' }, { name: 'include-major', description: 'Include major version updates', type: 'boolean' }, ], async action(ctx) { const { flags } = ctx; process.env.CLAUDE_FLOW_FORCE_UPDATE = 'true'; try { output.printInfo('Checking for updates...'); const config = { ...DEFAULT_CONFIG, autoUpdate: { patch: true, minor: true, major: flags['include-major'] || false, }, }; const { results } = await checkForUpdates(config); if (results.length === 0) { output.printSuccess('All packages are up to date!'); return { success: true }; } // Get installed packages const installedPackages = {}; for (const update of results) { const version = getInstalledVersion(update.package); if (version) { installedPackages[update.package] = version; } } output.printInfo(`Updating ${results.length} package(s)...`); const updateResults = await executeMultipleUpdates(results, installedPackages, flags['dry-run']); const successful = updateResults.filter((r) => r.success); const failed = updateResults.filter((r) => !r.success); output.writeln(); output.writeln(output.highlight(flags['dry-run'] ? '═══ Dry Run - Would Update ═══' : '═══ Update Results ═══')); output.writeln(); if (successful.length > 0) { output.printSuccess(`${successful.length} package(s) ${flags['dry-run'] ? 'would be ' : ''}updated:`); for (const r of successful) { output.writeln(` ${output.success('✓')} ${r.package}@${r.version}`); } } if (failed.length > 0) { output.writeln(); output.printError(`${failed.length} package(s) failed:`); for (const r of failed) { output.writeln(` ${output.error('✗')} ${r.package}: ${r.error}`); } } return { success: failed.length === 0 }; } finally { delete process.env.CLAUDE_FLOW_FORCE_UPDATE; } }, }; // Subcommand: history const historyCommand = { name: 'history', description: 'View update history', options: [ { name: 'limit', short: 'n', description: 'Number of entries', type: 'string', default: '20' }, { name: 'json', description: 'Output as JSON', type: 'boolean' }, { name: 'clear', description: 'Clear history', type: 'boolean' }, ], async action(ctx) { const { flags } = ctx; if (flags.clear) { clearHistory(); output.printSuccess('Update history cleared'); return { success: true }; } const limit = parseInt(flags.limit || '20', 10); const history = getUpdateHistory(limit); if (history.length === 0) { output.printInfo('No update history available'); return { success: true }; } if (flags.json) { console.log(JSON.stringify(history, null, 2)); return { success: true }; } output.writeln(); output.writeln(output.highlight('═══ Update History ═══')); output.writeln(); output.printTable({ columns: [ { key: 'time', header: 'Time' }, { key: 'package', header: 'Package' }, { key: 'from', header: 'From' }, { key: 'to', header: 'To' }, { key: 'status', header: 'Status' }, ], data: history.map((h) => ({ time: new Date(h.timestamp).toLocaleString(), package: h.package, from: h.fromVersion, to: h.toVersion, status: h.success ? output.success('success') : output.error('failed'), })), }); return { success: true }; }, }; // Subcommand: rollback const rollbackCommand = { name: 'rollback', description: 'Rollback last update', options: [ { name: 'package', short: 'p', description: 'Specific package to rollback', type: 'string' }, ], async action(ctx) { const { flags } = ctx; const packageName = flags.package; output.printInfo(packageName ? `Rolling back ${packageName}...` : 'Rolling back last update...'); const result = await rollbackUpdate(packageName); if (result.success) { output.printSuccess(result.message); } else { output.printError(result.message); } return { success: result.success }; }, }; // Subcommand: clear-cache const clearCacheCommand = { name: 'clear-cache', description: 'Clear update check cache', async action() { clearCache(); output.printSuccess('Update cache cleared'); output.printInfo('Next startup will check for updates'); return { success: true }; }, }; // Main update command const updateCommand = { name: 'update', description: 'Manage @claude-flow package updates (ADR-025)', subcommands: [checkCommand, allCommand, historyCommand, rollbackCommand, clearCacheCommand], async action() { // Show help if no subcommand output.writeln(); output.writeln(output.highlight('═══ Update Command ═══')); output.writeln(); output.writeln('Manage @claude-flow package updates with auto-update support.'); output.writeln(); output.writeln('Subcommands:'); output.printList([ `${output.highlight('check')} - Check for available updates`, `${output.highlight('all')} - Update all packages`, `${output.highlight('history')} - View update history`, `${output.highlight('rollback')} - Rollback last update`, `${output.highlight('clear-cache')} - Clear update check cache`, ]); output.writeln(); output.writeln('Environment Variables:'); output.printList([ `${output.dim('CLAUDE_FLOW_AUTO_UPDATE=false')} - Disable auto-update`, `${output.dim('CLAUDE_FLOW_FORCE_UPDATE=true')} - Force update check`, ]); output.writeln(); output.writeln('Run "claude-flow update <subcommand> --help" for subcommand help'); return { success: true }; }, }; export default updateCommand; //# sourceMappingURL=update.js.map