UNPKG

@lsendel/claude-agents

Version:

Supercharge Claude Code with specialized AI sub-agents for code review, testing, debugging, documentation & more. Now with process & standards management! Easy CLI tool to install, manage & create custom AI agents for enhanced development workflow

232 lines (205 loc) 7.73 kB
import { program } from 'commander'; import chalk from 'chalk'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { logger } from './utils/logger.js'; import { CLIError } from './utils/errors.js'; // Commands import { installCommand } from './commands/install.js'; import { listCommand } from './commands/list.js'; import { enableCommand } from './commands/enable.js'; import { disableCommand } from './commands/disable.js'; import { infoCommand } from './commands/info.js'; import { createCommand } from './commands/create.js'; import { removeCommand } from './commands/remove.js'; import { updateCommand } from './commands/update.js'; import { syncCommand } from './commands/sync.js'; import { syncProcessesCommandConfig } from './commands/sync-processes.js'; import { syncStandardsCommandConfig } from './commands/sync-standards.js'; import { migrateCommandConfig } from './commands/migrate.js'; import { optimizeCommandConfig } from './commands/optimize.js'; import { validateCommandConfig } from './commands/validate.js'; import { cleanupCommandConfig } from './commands/cleanup.js'; import { checkForUpdates } from './utils/update-checker.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Read package.json for version const packageJson = JSON.parse( readFileSync(join(__dirname, '..', 'package.json'), 'utf-8') ); // ASCII Art Banner logger.info(chalk.blue(` ╔═══════════════════════════════════════════╗ ║ Claude Sub-Agents Manager ║ ║ Enhance Claude Code with AI Agents ║ ╚═══════════════════════════════════════════╝ `)); program .name('claude-agents') .description('CLI tool to manage Claude Code sub-agents') .version(packageJson.version); // Install command program .command('install [agents...]') .description('Install sub-agents to your system') .option('-p, --project', 'Install to project directory instead of user directory') .option('-a, --all', 'Install all available agents') .action((agents, options) => installCommand(agents, options)); // List command program .command('list') .description('List available and installed agents') .option('-i, --installed', 'Show only installed agents') .option('-a, --available', 'Show only available agents') .action(listCommand); // Enable command program .command('enable <agent>') .description('Enable a specific agent') .option('-p, --project', 'Enable in project scope') .action(enableCommand); // Disable command program .command('disable <agent>') .description('Disable a specific agent without removing it') .option('-p, --project', 'Disable in project scope') .action(disableCommand); // Info command program .command('info <agent>') .description('Show detailed information about an agent') .action(infoCommand); // Create command program .command('create') .description('Create a new custom agent') .option('-n, --name <name>', 'Agent name') .option('-t, --template <template>', 'Use a template (basic, advanced)') .action(createCommand); // Remove command program .command('remove <agent>') .alias('uninstall') .description('Remove an installed agent') .option('-p, --project', 'Remove from project scope') .action(removeCommand); // Update command program .command(updateCommand.name) .description(updateCommand.description) .option('-a, --all', 'Update all installed agents') .option('-p, --project', 'Update agents in project scope') .option('-f, --force', 'Force update without confirmation') .option('--preserve-custom', 'Preserve custom modifications') .action(updateCommand.action); // Sync command program .command('sync') .description('Sync externally installed agents with configuration') .option('-a, --auto', 'Auto-register without confirmation') .option('-c, --commands', 'Also check for orphaned commands') .option('-f, --force-copy', 'Force copy all agents to project directory') .action(syncCommand); // Sync processes command const syncProcessesCmd = program .command(syncProcessesCommandConfig.command) .description(syncProcessesCommandConfig.description); syncProcessesCommandConfig.options.forEach(opt => { syncProcessesCmd.option(...opt); }); syncProcessesCmd.action(syncProcessesCommandConfig.action); // Sync standards command const syncStandardsCmd = program .command(syncStandardsCommandConfig.command) .description(syncStandardsCommandConfig.description); syncStandardsCommandConfig.options.forEach(opt => { syncStandardsCmd.option(...opt); }); syncStandardsCmd.action(syncStandardsCommandConfig.action); // Cleanup command const cleanupCmd = program .command(cleanupCommandConfig.command) .description(cleanupCommandConfig.description); cleanupCommandConfig.options.forEach(opt => { cleanupCmd.option(...opt); }); cleanupCmd.action(cleanupCommandConfig.action); // Migrate command const migrateCmd = program .command(migrateCommandConfig.command) .description(migrateCommandConfig.description); migrateCommandConfig.options.forEach(opt => { migrateCmd.option(...opt); }); migrateCmd.action(migrateCommandConfig.action); // Optimize command const optimizeCmd = program .command(optimizeCommandConfig.command) .description(optimizeCommandConfig.description); optimizeCommandConfig.options.forEach(opt => { optimizeCmd.option(...opt); }); optimizeCmd.action(optimizeCommandConfig.action); // Validate command const validateCmd = program .command(validateCommandConfig.command) .description(validateCommandConfig.description); validateCommandConfig.options.forEach(opt => { validateCmd.option(...opt); }); validateCmd.action(validateCommandConfig.action); // Config command program .command('config <setting> [value]') .description('Configure settings (e.g., config autosync on/off)') .action(async (setting, value) => { const { enableAutoSync, disableAutoSync, isAutoSyncEnabled } = await import('./utils/auto-sync.js'); if (setting === 'autosync') { if (value === 'on' || value === 'true') { enableAutoSync(); } else if (value === 'off' || value === 'false') { disableAutoSync(); } else if (!value) { console.log(`Auto-sync is currently: ${isAutoSyncEnabled() ? chalk.green('enabled') : chalk.gray('disabled')}`); } else { console.log(chalk.red('Invalid value. Use "on" or "off"')); } } else { console.log(chalk.red(`Unknown setting: ${setting}`)); console.log(chalk.gray('Available settings: autosync')); } }); // Version command with update check program .command('version') .description('Show version and check for updates') .action(async () => { logger.info(`${packageJson.name} v${packageJson.version}`); await checkForUpdates(false); }); // Check for updates on startup (silently) checkForUpdates(true); // Wrap command execution for error handling const originalParse = program.parse.bind(program); program.parse = async (...args) => { try { return await originalParse(...args); } catch (error) { if (error instanceof CLIError) { process.exit(error.code || 1); } else { logger.error('Unexpected error:', error.message); if (process.env.DEBUG === 'true') { logger.error(error.stack); } process.exit(1); } } }; // Parse command line arguments program.parse(process.argv); // Show help if no command provided if (!process.argv.slice(2).length) { program.outputHelp(); }