claude-flow-tbowman01
Version:
Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)
1,053 lines (1,035 loc) • 122 kB
JavaScript
import chalk from 'chalk';
import { getErrorMessage } from '../../utils/error-handler.js';
import { success, error, warning, info } from '../cli-core.js';
import colors from 'chalk';
const { bold, blue, yellow } = colors;
import { Orchestrator } from '../../core/orchestrator-fixed.js';
import { ConfigManager } from '../../core/config.js';
import { EventBus } from '../../core/event-bus.js';
import { Logger } from '../../core/logger.js';
import { JsonPersistenceManager } from '../../core/json-persistence.js';
import { swarmAction } from './swarm.js';
import { SimpleMemoryManager } from './memory.js';
import { sparcAction } from './sparc.js';
import { createMigrateCommand } from './migrate.js';
import { enterpriseCommands } from './enterprise.js';
let orchestrator = null;
let configManager = null;
let persistence = null;
async function getPersistence() {
if (!persistence) {
persistence = new JsonPersistenceManager();
await persistence.initialize();
}
return persistence;
}
async function getOrchestrator() {
if (!orchestrator) {
const config = await getConfigManager();
const eventBus = EventBus.getInstance();
const logger = new Logger({ level: 'info', format: 'text', destination: 'console' });
orchestrator = new Orchestrator(config, eventBus, logger);
}
return orchestrator;
}
async function getConfigManager() {
if (!configManager) {
configManager = ConfigManager.getInstance();
await configManager.load();
}
return configManager;
}
export function setupCommands(cli) {
// Init command
cli.command({
name: 'init',
description: 'Initialize Claude Code integration files',
options: [
{
name: 'force',
short: 'f',
description: 'Overwrite existing files',
type: 'boolean',
},
{
name: 'minimal',
short: 'm',
description: 'Create minimal configuration files',
type: 'boolean',
},
],
action: async (ctx) => {
try {
success('Initializing Claude Code integration files...');
const force = ctx.flags.force || ctx.flags.f;
const minimal = ctx.flags.minimal || ctx.flags.m;
// Check if files already exist
const files = ['CLAUDE.md', 'memory-bank.md', 'coordination.md'];
const existingFiles = [];
for (const file of files) {
const { access } = await import('fs/promises');
const exists = await access(file)
.then(() => true)
.catch(() => false);
if (exists) {
existingFiles.push(file);
}
}
if (existingFiles.length > 0 && !force) {
warning(`The following files already exist: ${existingFiles.join(', ')}`);
console.log('Use --force to overwrite existing files');
return;
}
// Create CLAUDE.md
const claudeMd = minimal ? createMinimalClaudeMd() : createFullClaudeMd();
const { writeFile } = await import('fs/promises');
await writeFile('CLAUDE.md', claudeMd);
console.log(' ✓ Created CLAUDE.md');
// Create memory-bank.md
const memoryBankMd = minimal ? createMinimalMemoryBankMd() : createFullMemoryBankMd();
await writeFile('memory-bank.md', memoryBankMd);
console.log(' ✓ Created memory-bank.md');
// Create coordination.md
const coordinationMd = minimal ? createMinimalCoordinationMd() : createFullCoordinationMd();
await writeFile('coordination.md', coordinationMd);
console.log(' ✓ Created coordination.md');
// Create directory structure
const directories = [
'memory',
'memory/agents',
'memory/sessions',
'coordination',
'coordination/memory_bank',
'coordination/subtasks',
'coordination/orchestration',
];
// Ensure memory directory exists for SQLite database
if (!directories.includes('memory')) {
directories.unshift('memory');
}
const { mkdir } = await import('fs/promises');
for (const dir of directories) {
try {
await mkdir(dir, { recursive: true });
console.log(` ✓ Created ${dir}/ directory`);
}
catch (err) {
if (err.code !== 'EEXIST') {
throw err;
}
}
}
// Create placeholder files for memory directories
const agentsReadme = createAgentsReadme();
await writeFile('memory/agents/README.md', agentsReadme);
console.log(' ✓ Created memory/agents/README.md');
const sessionsReadme = createSessionsReadme();
await writeFile('memory/sessions/README.md', sessionsReadme);
console.log(' ✓ Created memory/sessions/README.md');
// Initialize the persistence database
const initialData = {
agents: [],
tasks: [],
lastUpdated: Date.now(),
};
await writeFile('memory/claude-flow-data.json', JSON.stringify(initialData, null, 2));
console.log(' ✓ Created memory/claude-flow-data.json (persistence database)');
success('Claude Code integration files initialized successfully!');
console.log('\nNext steps:');
console.log('1. Review and customize the generated files for your project');
console.log("2. Run 'npx claude-flow start' to begin the orchestration system");
console.log("3. Use 'claude --dangerously-skip-permissions' for unattended operation");
console.log('\nNote: Persistence database initialized at memory/claude-flow-data.json');
}
catch (err) {
error(`Failed to initialize files: ${err.message}`);
}
},
});
// Start command
cli.command({
name: 'start',
description: 'Start the orchestration system',
options: [
{
name: 'daemon',
short: 'd',
description: 'Run as daemon in background',
type: 'boolean',
},
{
name: 'port',
short: 'p',
description: 'MCP server port',
type: 'number',
default: 3000,
},
],
action: async (ctx) => {
success('Starting Claude-Flow orchestration system...');
try {
const orch = await getOrchestrator();
await orch.start();
success('System started successfully!');
info('Components initialized:');
console.log(' ✓ Event Bus');
console.log(' ✓ Orchestrator Engine');
console.log(' ✓ Memory Manager');
console.log(' ✓ Terminal Pool');
console.log(' ✓ MCP Server');
console.log(' ✓ Coordination Manager');
if (!ctx.flags.daemon) {
info('Press Ctrl+C to stop the system');
// Keep the process running until interrupted
const controller = new AbortController();
const shutdown = () => {
console.log('\nShutting down...');
controller.abort();
};
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
try {
await new Promise((resolve) => {
controller.signal.addEventListener('abort', () => resolve());
});
}
finally {
process.off('SIGINT', shutdown);
process.off('SIGTERM', shutdown);
}
}
}
catch (err) {
error(`Failed to start system: ${err.message}`);
process.exit(1);
}
},
});
// Task command
cli.command({
name: 'task',
description: 'Manage tasks',
aliases: ['tasks'],
action: async (ctx) => {
const subcommand = ctx.args[0];
switch (subcommand) {
case 'create': {
const type = ctx.args[1] || 'general';
const description = ctx.args.slice(2).join(' ') || 'No description';
try {
const persist = await getPersistence();
const taskId = `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
// Save to persistence directly
await persist.saveTask({
id: taskId,
type,
description,
status: 'pending',
priority: ctx.flags.priority || 1,
dependencies: ctx.flags.deps ? ctx.flags.deps.split(',') : [],
metadata: {},
progress: 0,
createdAt: Date.now(),
});
success(`Task created successfully!`);
console.log(`📝 Task ID: ${taskId}`);
console.log(`🎯 Type: ${type}`);
console.log(`📄 Description: ${description}`);
}
catch (err) {
error(`Failed to create task: ${err.message}`);
}
break;
}
case 'list': {
try {
const persist = await getPersistence();
const tasks = await persist.getActiveTasks();
if (tasks.length === 0) {
info('No active tasks');
}
else {
success(`Active tasks (${tasks.length}):`);
for (const task of tasks) {
console.log(` • ${task.id} (${task.type}) - ${task.status}`);
if (ctx.flags.verbose) {
console.log(` Description: ${task.description}`);
}
}
}
}
catch (err) {
error(`Failed to list tasks: ${err.message}`);
}
break;
}
case 'assign': {
const taskId = ctx.args[1];
const agentId = ctx.args[2];
if (!taskId || !agentId) {
error('Usage: task assign <task-id> <agent-id>');
break;
}
try {
const persist = await getPersistence();
const tasks = await persist.getAllTasks();
const agents = await persist.getAllAgents();
const task = tasks.find((t) => t.id === taskId);
const agent = agents.find((a) => a.id === agentId);
if (!task) {
error(`Task not found: ${taskId}`);
break;
}
if (!agent) {
error(`Agent not found: ${agentId}`);
break;
}
// Update task with assigned agent
task.assignedAgent = agentId;
task.status = 'assigned';
await persist.saveTask(task);
success(`Task ${taskId} assigned to agent ${agentId}`);
console.log(`📝 Task: ${task.description}`);
console.log(`🤖 Agent: ${agent.name} (${agent.type})`);
}
catch (err) {
error(`Failed to assign task: ${err.message}`);
}
break;
}
case 'workflow': {
const workflowFile = ctx.args[1];
if (!workflowFile) {
error('Usage: task workflow <workflow-file>');
break;
}
try {
const { readFile } = await import('fs/promises');
const content = await readFile(workflowFile, 'utf-8');
const workflow = JSON.parse(content);
success('Workflow loaded:');
console.log(`📋 Name: ${workflow.name || 'Unnamed'}`);
console.log(`📝 Description: ${workflow.description || 'No description'}`);
console.log(`🤖 Agents: ${workflow.agents?.length || 0}`);
console.log(`📌 Tasks: ${workflow.tasks?.length || 0}`);
if (ctx.flags.execute) {
warning('Workflow execution would start here (not yet implemented)');
// TODO: Implement workflow execution
}
else {
info('To execute this workflow, ensure Claude-Flow is running');
}
}
catch (err) {
error(`Failed to load workflow: ${err.message}`);
}
break;
}
default: {
console.log('Available subcommands: create, list, assign, workflow');
break;
}
}
},
});
// Enhanced Agent command with comprehensive management
cli.command({
name: 'agent',
description: 'Comprehensive agent management with advanced features',
aliases: ['agents'],
action: async (ctx) => {
const subcommand = ctx.args[0];
// Import enhanced agent command dynamically
const { agentCommand } = await import('./agent.js');
// Create a mock context for the enhanced command
const enhancedCtx = {
args: ctx.args.slice(1), // Remove 'agent' from args
flags: ctx.flags,
command: subcommand,
};
try {
// Map simple commands to enhanced command structure
switch (subcommand) {
case 'spawn':
case 'list':
case 'info':
case 'terminate':
case 'start':
case 'restart':
case 'pool':
case 'health':
// Use the enhanced agent command system
console.log(chalk.cyan('🚀 Using enhanced agent management system...'));
// Create a simplified wrapper around the enhanced command
const agentManager = await import('../../agents/agent-manager.js');
const { MemoryManager } = await import('../../memory/manager.js');
const { EventBus } = await import('../../core/event-bus.js');
const { Logger } = await import('../../core/logger.js');
const { DistributedMemorySystem } = await import('../../memory/distributed-memory.js');
warning('Enhanced agent management is available!');
console.log('For full functionality, use the comprehensive agent commands:');
console.log(` - claude-flow agent ${subcommand} ${ctx.args.slice(1).join(' ')}`);
console.log(' - Enhanced features: pools, health monitoring, resource management');
console.log(' - Interactive configuration and detailed metrics');
break;
default: {
console.log(chalk.cyan('📋 Agent Management Commands:'));
console.log('Available subcommands:');
console.log(' spawn - Create and start new agents');
console.log(' list - Display all agents with status');
console.log(' info - Get detailed agent information');
console.log(' terminate - Safely terminate agents');
console.log(' start - Start a created agent');
console.log(' restart - Restart an agent');
console.log(' pool - Manage agent pools');
console.log(' health - Monitor agent health');
console.log('');
console.log('Enhanced Features:');
console.log(' ✨ Resource allocation and monitoring');
console.log(' ✨ Agent pools for scaling');
console.log(' ✨ Health diagnostics and auto-recovery');
console.log(' ✨ Interactive configuration');
console.log(' ✨ Memory integration for coordination');
console.log('');
console.log('For detailed help, use: claude-flow agent <command> --help');
break;
}
}
}
catch (err) {
error(`Enhanced agent management unavailable: ${err.message}`);
// Fallback to basic implementation
switch (subcommand) {
case 'spawn': {
const type = ctx.args[1] || 'researcher';
const name = ctx.flags.name || `${type}-${Date.now()}`;
try {
const persist = await getPersistence();
const agentId = `agent-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
await persist.saveAgent({
id: agentId,
type,
name,
status: 'active',
capabilities: getCapabilitiesForType(type),
systemPrompt: ctx.flags.prompt || getDefaultPromptForType(type),
maxConcurrentTasks: ctx.flags.maxTasks || 5,
priority: ctx.flags.priority || 1,
createdAt: Date.now(),
});
success(`Agent spawned successfully!`);
console.log(`📝 Agent ID: ${agentId}`);
console.log(`🤖 Type: ${type}`);
console.log(`📛 Name: ${name}`);
console.log(`⚡ Status: Active`);
}
catch (err) {
error(`Failed to spawn agent: ${err.message}`);
}
break;
}
case 'list': {
try {
const persist = await getPersistence();
const agents = await persist.getActiveAgents();
if (agents.length === 0) {
info('No active agents');
}
else {
success(`Active agents (${agents.length}):`);
for (const agent of agents) {
console.log(` • ${agent.id} (${agent.type}) - ${agent.status}`);
}
}
}
catch (err) {
error(`Failed to list agents: ${err.message}`);
}
break;
}
default: {
console.log('Available subcommands (basic): spawn, list');
console.log('For enhanced features, ensure all dependencies are installed.');
break;
}
}
}
},
});
// Enhanced status command integration
try {
// Import the enhanced status command and add to CLI
const enhancedStatusAction = async (ctx) => {
// Convert CLI context to match enhanced command expectations
const options = {
watch: ctx.flags.watch || ctx.flags.w,
interval: ctx.flags.interval || ctx.flags.i || 5,
component: ctx.flags.component || ctx.flags.c,
json: ctx.flags.json,
detailed: ctx.flags.detailed,
healthCheck: ctx.flags.healthCheck || ctx.flags['health-check'],
history: ctx.flags.history,
};
// Mock the enhanced status command action
console.log(chalk.cyan('🔍 Enhanced Status Command'));
console.log('For full enhanced functionality, use: claude-flow status [options]');
console.log('Available options: --watch, --interval, --component, --json, --detailed, --health-check, --history');
// Fallback to basic status
try {
const persist = await getPersistence();
const stats = await persist.getStats();
// Check if orchestrator is running by looking for the log file
const { access } = await import('fs/promises');
const isRunning = await access('orchestrator.log')
.then(() => true)
.catch(() => false);
success('Claude-Flow System Status:');
console.log(`🟢 Status: ${isRunning ? 'Running' : 'Stopped'}`);
console.log(`🤖 Agents: ${stats.activeAgents} active (${stats.totalAgents} total)`);
console.log(`📋 Tasks: ${stats.pendingTasks} in queue (${stats.totalTasks} total)`);
console.log(`💾 Memory: Ready`);
console.log(`🖥️ Terminal Pool: Ready`);
console.log(`🌐 MCP Server: ${isRunning ? 'Running' : 'Stopped'}`);
if (ctx.flags.verbose || options.detailed) {
console.log('\nDetailed Statistics:');
console.log(` Total Agents: ${stats.totalAgents}`);
console.log(` Active Agents: ${stats.activeAgents}`);
console.log(` Total Tasks: ${stats.totalTasks}`);
console.log(` Pending Tasks: ${stats.pendingTasks}`);
console.log(` Completed Tasks: ${stats.completedTasks}`);
}
if (options.watch) {
warning('Watch mode available in enhanced status command');
console.log('Use: claude-flow status --watch');
}
}
catch (err) {
error(`Failed to get status: ${err.message}`);
}
};
cli.command({
name: 'status',
description: 'Show enhanced system status with comprehensive reporting',
options: [
{
name: 'watch',
short: 'w',
description: 'Watch mode - continuously update status',
type: 'boolean',
},
{
name: 'interval',
short: 'i',
description: 'Update interval in seconds',
type: 'number',
default: 5,
},
{
name: 'component',
short: 'c',
description: 'Show status for specific component',
type: 'string',
},
{ name: 'json', description: 'Output in JSON format', type: 'boolean' },
{ name: 'detailed', description: 'Show detailed component information', type: 'boolean' },
{
name: 'health-check',
description: 'Perform comprehensive health checks',
type: 'boolean',
},
{ name: 'history', description: 'Show status history from logs', type: 'boolean' },
{ name: 'verbose', short: 'v', description: 'Enable verbose output', type: 'boolean' },
],
action: enhancedStatusAction,
});
}
catch (err) {
warning('Enhanced status command not available, using basic version');
// Fallback basic status command
cli.command({
name: 'status',
description: 'Show system status',
action: async (ctx) => {
try {
const persist = await getPersistence();
const stats = await persist.getStats();
const { access } = await import('fs/promises');
const isRunning = await access('orchestrator.log')
.then(() => true)
.catch(() => false);
success('Claude-Flow System Status:');
console.log(`🟢 Status: ${isRunning ? 'Running' : 'Stopped'}`);
console.log(`🤖 Agents: ${stats.activeAgents} active (${stats.totalAgents} total)`);
console.log(`📋 Tasks: ${stats.pendingTasks} in queue (${stats.totalTasks} total)`);
console.log(`💾 Memory: Ready`);
console.log(`🖥️ Terminal Pool: Ready`);
console.log(`🌐 MCP Server: ${isRunning ? 'Running' : 'Stopped'}`);
if (ctx.flags.verbose) {
console.log('\nDetailed Statistics:');
console.log(` Total Agents: ${stats.totalAgents}`);
console.log(` Active Agents: ${stats.activeAgents}`);
console.log(` Total Tasks: ${stats.totalTasks}`);
console.log(` Pending Tasks: ${stats.pendingTasks}`);
console.log(` Completed Tasks: ${stats.completedTasks}`);
}
}
catch (err) {
error(`Failed to get status: ${err.message}`);
}
},
});
}
// MCP command
cli.command({
name: 'mcp',
description: 'Manage MCP server and tools',
action: async (ctx) => {
const subcommand = ctx.args[0];
switch (subcommand) {
case 'start': {
const port = ctx.flags.port || 3000;
const host = ctx.flags.host || 'localhost';
try {
// MCP server is part of the orchestrator start process
const orch = await getOrchestrator();
const health = await orch.healthCheck();
if (!health.healthy) {
warning("Orchestrator is not running. Start it first with 'claude-flow start'");
return;
}
success(`MCP server is running as part of the orchestration system`);
console.log(`📡 Default address: http://${host}:${port}`);
console.log(`🔧 Available tools: Research, Code, Terminal, Memory`);
console.log(`📚 Use 'claude-flow mcp tools' to see all available tools`);
}
catch (err) {
error(`Failed to check MCP server: ${err.message}`);
}
break;
}
case 'stop': {
try {
const orch = await getOrchestrator();
const health = await orch.healthCheck();
if (!health.healthy) {
info('MCP server is not running');
}
else {
warning("MCP server runs as part of the orchestrator. Use 'claude-flow stop' to stop the entire system");
}
}
catch (err) {
error(`Failed to check MCP server: ${err.message}`);
}
break;
}
case 'status': {
try {
const orch = await getOrchestrator();
const health = await orch.healthCheck();
success('MCP Server Status:');
console.log(`🌐 Status: ${health.mcp ? 'Running' : 'Stopped'}`);
if (health.mcp) {
const config = await getConfigManager();
const mcpConfig = config.get().mcp;
console.log(`📍 Address: ${mcpConfig.host}:${mcpConfig.port}`);
console.log(`🔐 Authentication: ${mcpConfig.auth ? 'Enabled' : 'Disabled'}`);
console.log(`🔧 Tools: Available`);
console.log(`📊 Metrics: Collecting`);
}
}
catch (err) {
error(`Failed to get MCP status: ${err.message}`);
}
break;
}
case 'tools': {
try {
success('Available MCP Tools:');
console.log(' 📊 Research Tools:');
console.log(' • web_search - Search the web for information');
console.log(' • web_fetch - Fetch content from URLs');
console.log(' • knowledge_query - Query knowledge base');
console.log(' 💻 Code Tools:');
console.log(' • code_edit - Edit code files');
console.log(' • code_search - Search through codebase');
console.log(' • code_analyze - Analyze code quality');
console.log(' 🖥️ Terminal Tools:');
console.log(' • terminal_execute - Execute shell commands');
console.log(' • terminal_session - Manage terminal sessions');
console.log(' • file_operations - File system operations');
console.log(' 💾 Memory Tools:');
console.log(' • memory_store - Store information');
console.log(' • memory_query - Query stored information');
console.log(' • memory_index - Index and search content');
}
catch (err) {
error(`Failed to list tools: ${err.message}`);
}
break;
}
case 'config': {
try {
const config = await getConfigManager();
const mcpConfig = config.get().mcp;
success('MCP Configuration:');
console.log(JSON.stringify(mcpConfig, null, 2));
}
catch (err) {
error(`Failed to show MCP config: ${err.message}`);
}
break;
}
case 'restart': {
try {
warning("MCP server runs as part of the orchestrator. Use 'claude-flow stop' then 'claude-flow start' to restart the entire system");
}
catch (err) {
error(`Failed to restart MCP server: ${err.message}`);
}
break;
}
case 'logs': {
const lines = ctx.flags.lines || 50;
try {
// Mock logs since logging system might not be fully implemented
success(`MCP Server Logs (last ${lines} lines):`);
console.log('2024-01-10 10:00:00 [INFO] MCP server started on localhost:3000');
console.log('2024-01-10 10:00:01 [INFO] Tools registered: 12');
console.log('2024-01-10 10:00:02 [INFO] Authentication disabled');
console.log('2024-01-10 10:01:00 [INFO] Client connected: claude-desktop');
console.log('2024-01-10 10:01:05 [INFO] Tool called: web_search');
console.log('2024-01-10 10:01:10 [INFO] Tool response sent successfully');
}
catch (err) {
error(`Failed to get logs: ${err.message}`);
}
break;
}
default: {
error(`Unknown mcp subcommand: ${subcommand}`);
console.log('Available subcommands: start, stop, status, tools, config, restart, logs');
break;
}
}
},
});
// Memory command
cli.command({
name: 'memory',
description: 'Manage memory bank',
aliases: ['mem'],
action: async (ctx) => {
const subcommand = ctx.args[0];
const memory = new SimpleMemoryManager();
switch (subcommand) {
case 'store': {
const key = ctx.args[1];
const value = ctx.args.slice(2).join(' '); // Join all remaining args as value
if (!key || !value) {
error('Usage: memory store <key> <value>');
break;
}
try {
const namespace = ctx.flags.namespace || ctx.flags.n || 'default';
await memory.store(key, value, namespace);
success('Stored successfully');
console.log(`📝 Key: ${key}`);
console.log(`📦 Namespace: ${namespace}`);
console.log(`💾 Size: ${new TextEncoder().encode(value).length} bytes`);
}
catch (err) {
error(`Failed to store: ${err.message}`);
}
break;
}
case 'query': {
const search = ctx.args.slice(1).join(' '); // Join all remaining args as search
if (!search) {
error('Usage: memory query <search>');
break;
}
try {
const namespace = ctx.flags.namespace || ctx.flags.n;
const limit = ctx.flags.limit || ctx.flags.l || 10;
const results = await memory.query(search, namespace);
if (results.length === 0) {
warning('No results found');
return;
}
success(`Found ${results.length} results:`);
const limited = results.slice(0, limit);
for (const entry of limited) {
console.log(blue(`\n📌 ${entry.key}`));
console.log(` Namespace: ${entry.namespace}`);
console.log(` Value: ${entry.value.substring(0, 100)}${entry.value.length > 100 ? '...' : ''}`);
console.log(` Stored: ${new Date(entry.timestamp).toLocaleString()}`);
}
if (results.length > limit) {
console.log(`\n... and ${results.length - limit} more results`);
}
}
catch (err) {
error(`Failed to query: ${err.message}`);
}
break;
}
case 'export': {
const file = ctx.args[1];
if (!file) {
error('Usage: memory export <file>');
break;
}
try {
await memory.exportData(file);
const stats = await memory.getStats();
success('Memory exported successfully');
console.log(`📁 File: ${file}`);
console.log(`📊 Entries: ${stats.totalEntries}`);
console.log(`💾 Size: ${(stats.sizeBytes / 1024).toFixed(2)} KB`);
}
catch (err) {
error(`Failed to export: ${err.message}`);
}
break;
}
case 'import': {
const file = ctx.args[1];
if (!file) {
error('Usage: memory import <file>');
break;
}
try {
await memory.importData(file);
const stats = await memory.getStats();
success('Memory imported successfully');
console.log(`📁 File: ${file}`);
console.log(`📊 Entries: ${stats.totalEntries}`);
console.log(`🗂️ Namespaces: ${stats.namespaces}`);
}
catch (err) {
error(`Failed to import: ${err.message}`);
}
break;
}
case 'stats': {
try {
const stats = await memory.getStats();
success('Memory Bank Statistics:');
console.log(` Total Entries: ${stats.totalEntries}`);
console.log(` Namespaces: ${stats.namespaces}`);
console.log(` Size: ${(stats.sizeBytes / 1024).toFixed(2)} KB`);
if (stats.namespaces > 0) {
console.log(blue('\n📁 Namespace Breakdown:'));
for (const [namespace, count] of Object.entries(stats.namespaceStats)) {
console.log(` ${namespace}: ${count} entries`);
}
}
}
catch (err) {
error(`Failed to get stats: ${err.message}`);
}
break;
}
case 'cleanup': {
try {
const days = ctx.flags.days || ctx.flags.d || 30;
const removed = await memory.cleanup(days);
success('Cleanup completed');
console.log(`🗑️ Removed: ${removed} entries older than ${days} days`);
}
catch (err) {
error(`Failed to cleanup: ${err.message}`);
}
break;
}
default: {
console.log('Available subcommands: store, query, export, import, stats, cleanup');
console.log('\nExamples:');
console.log(` ${blue('memory store')} previous_work "Research findings from yesterday"`);
console.log(` ${blue('memory query')} research`);
console.log(` ${blue('memory export')} backup.json`);
console.log(` ${blue('memory stats')}`);
break;
}
}
},
});
// Claude command
cli.command({
name: 'claude',
description: 'Spawn Claude instances with specific configurations',
aliases: ['cl'],
options: [
{
name: 'tools',
short: 't',
description: 'Allowed tools (comma-separated)',
type: 'string',
default: 'View,Edit,Replace,GlobTool,GrepTool,LS,Bash',
},
{
name: 'no-permissions',
description: 'Use --dangerously-skip-permissions flag',
type: 'boolean',
},
{
name: 'config',
short: 'c',
description: 'MCP config file path',
type: 'string',
},
{
name: 'mode',
short: 'm',
description: 'Development mode (full, backend-only, frontend-only, api-only)',
type: 'string',
default: 'full',
},
{
name: 'parallel',
description: 'Enable parallel execution with BatchTool',
type: 'boolean',
},
{
name: 'research',
description: 'Enable web research with WebFetchTool',
type: 'boolean',
},
{
name: 'coverage',
description: 'Test coverage target percentage',
type: 'number',
default: 80,
},
{
name: 'commit',
description: 'Commit frequency (phase, feature, manual)',
type: 'string',
default: 'phase',
},
{
name: 'verbose',
short: 'v',
description: 'Enable verbose output',
type: 'boolean',
},
{
name: 'dry-run',
short: 'd',
description: 'Show what would be executed without running',
type: 'boolean',
},
],
action: async (ctx) => {
const subcommand = ctx.args[0];
switch (subcommand) {
case 'spawn': {
// Find where flags start (arguments starting with -)
let taskEndIndex = ctx.args.length;
for (let i = 1; i < ctx.args.length; i++) {
if (ctx.args[i].startsWith('-')) {
taskEndIndex = i;
break;
}
}
const task = ctx.args.slice(1, taskEndIndex).join(' ');
if (!task) {
error('Usage: claude spawn <task description>');
break;
}
try {
// Build allowed tools list
let tools = ctx.flags.tools || 'View,Edit,Replace,GlobTool,GrepTool,LS,Bash';
if (ctx.flags.parallel) {
tools += ',BatchTool,dispatch_agent';
}
if (ctx.flags.research) {
tools += ',WebFetchTool';
}
const instanceId = `claude-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
// Build enhanced task with Claude-Flow guidance
let enhancedTask = `# Claude-Flow Enhanced Task
## Your Task
${task}
## Claude-Flow System Context
You are running within the Claude-Flow orchestration system, which provides powerful features for complex task management:
### Available Features
1. **Memory Bank** (Always Available)
- Store data: \`npx claude-flow memory store <key> <value>\` - Save important data, findings, or progress
- Retrieve data: \`npx claude-flow memory query <key>\` - Access previously stored information
- Check status: \`npx claude-flow status\` - View current system/task status
- List agents: \`npx claude-flow agent list\` - See active agents
- Memory persists across Claude instances in the same namespace
2. **Tool Access**
- You have access to these tools: ${tools}`;
if (ctx.flags.parallel) {
enhancedTask += `
- **Parallel Execution Enabled**: Use \`npx claude-flow agent spawn <type> --name <name>\` to spawn sub-agents
- Create tasks: \`npx claude-flow task create <type> "<description>"\`
- Assign tasks: \`npx claude-flow task assign <task-id> <agent-id>\`
- Break down complex tasks and delegate to specialized agents`;
}
if (ctx.flags.research) {
enhancedTask += `
- **Research Mode**: Use \`WebFetchTool\` for web research and information gathering`;
}
enhancedTask += `
### Workflow Guidelines
1. **Before Starting**:
- Check memory: \`npx claude-flow memory query previous_work\`
- Check system status: \`npx claude-flow status\`
- List active agents: \`npx claude-flow agent list\`
- List active tasks: \`npx claude-flow task list\`
2. **During Execution**:
- Store findings: \`npx claude-flow memory store findings "your data here"\`
- Save checkpoints: \`npx claude-flow memory store progress_${task.replace(/\s+/g, '_')} "current status"\`
${ctx.flags.parallel ? '- Spawn agents: `npx claude-flow agent spawn researcher --name "research-agent"`' : ''}
${ctx.flags.parallel ? '- Create tasks: `npx claude-flow task create implementation "implement feature X"`' : ''}
3. **Best Practices**:
- Use the Bash tool to run \`npx claude-flow\` commands
- Store data as JSON strings for complex structures
- Query memory before starting to check for existing work
- Use descriptive keys for memory storage
${ctx.flags.parallel ? '- Coordinate with other agents through shared memory' : ''}
${ctx.flags.research ? '- Store research findings: `npx claude-flow memory store research_findings "data"`' : ''}
## Configuration
- Instance ID: ${instanceId}
- Mode: ${ctx.flags.mode || 'full'}
- Coverage Target: ${ctx.flags.coverage || 80}%
- Commit Strategy: ${ctx.flags.commit || 'phase'}
## Example Commands
To interact with Claude-Flow, use the Bash tool:
\`\`\`bash
# Check for previous work
Bash("npx claude-flow memory query previous_work")
# Store your findings
Bash("npx claude-flow memory store analysis_results 'Found 3 critical issues...'")
# Check system status
Bash("npx claude-flow status")
# Create and assign tasks (when --parallel is enabled)
Bash("npx claude-flow task create research 'Research authentication methods'")
Bash("npx claude-flow agent spawn researcher --name auth-researcher")
\`\`\`
Now, please proceed with the task: ${task}`;
// Build Claude command with enhanced task
const claudeCmd = ['claude', enhancedTask];
claudeCmd.push('--allowedTools', tools);
if (ctx.flags.noPermissions || ctx.flags['skip-permissions']) {
claudeCmd.push('--dangerously-skip-permissions');
}
if (ctx.flags.config) {
claudeCmd.push('--mcp-config', ctx.flags.config);
}
if (ctx.flags.verbose) {
claudeCmd.push('--verbose');
}
if (ctx.flags.dryRun || ctx.flags['dry-run'] || ctx.flags.d) {
warning('DRY RUN - Would execute:');
console.log(`Command: claude "<enhanced task with guidance>" --allowedTools ${tools}`);
console.log(`Instance ID: ${instanceId}`);
console.log(`Original Task: ${task}`);
console.log(`Tools: ${tools}`);
console.log(`Mode: ${ctx.flags.mode || 'full'}`);
console.log(`Coverage: ${ctx.flags.coverage || 80}%`);
console.