claude-flow
Version:
Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)
1,310 lines (1,136 loc) • 104 kB
text/typescript
import chalk from 'chalk';
import { getErrorMessage } from '../../utils/error-handler.js';
import { CLI, success, error, warning, info, VERSION } from "../cli-core.js";
import type { Command, CommandContext } 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 type { MemoryManager } from "../../memory/manager.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";
// Import enhanced orchestration commands
import { startCommand } from "./start.js";
import { statusCommand } from "./status.js";
import { monitorCommand } from "./monitor.js";
import { sessionCommand } from "./session.js";
let orchestrator: Orchestrator | null = null;
let configManager: ConfigManager | null = null;
let persistence: JsonPersistenceManager | null = null;
async function getPersistence(): Promise<JsonPersistenceManager> {
if (!persistence) {
persistence = new JsonPersistenceManager();
await persistence.initialize();
}
return persistence;
}
async function getOrchestrator(): Promise<Orchestrator> {
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(): Promise<ConfigManager> {
if (!configManager) {
configManager = ConfigManager.getInstance();
await configManager.load();
}
return configManager;
}
export function setupCommands(cli: CLI): void {
// 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: CommandContext) => {
try {
success("Initializing Claude Code integration files...");
const force = ctx.flags.force as boolean || ctx.flags.f as boolean;
const minimal = ctx.flags.minimal as boolean || ctx.flags.m as boolean;
// 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 as any).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 as Error).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: CommandContext) => {
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<void>((resolve) => {
controller.signal.addEventListener('abort', () => resolve());
});
} finally {
process.off("SIGINT", shutdown);
process.off("SIGTERM", shutdown);
}
}
} catch (err) {
error(`Failed to start system: ${(err as Error).message}`);
process.exit(1);
}
},
});
// Task command
cli.command({
name: "task",
description: "Manage tasks",
aliases: ["tasks"],
action: async (ctx: CommandContext) => {
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 as number || 1,
dependencies: ctx.flags.deps ? (ctx.flags.deps as string).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 as Error).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 as Error).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 as Error).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 as Error).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: CommandContext) => {
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 as Error).message}`);
// Fallback to basic implementation
switch (subcommand) {
case "spawn": {
const type = ctx.args[1] || "researcher";
const name = ctx.flags.name as string || `${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 as string || getDefaultPromptForType(type),
maxConcurrentTasks: ctx.flags.maxTasks as number || 5,
priority: ctx.flags.priority as number || 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 as Error).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 as Error).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: CommandContext) => {
// 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 as Error).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: CommandContext) => {
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 as Error).message}`);
}
}
});
}
// MCP command
cli.command({
name: "mcp",
description: "Manage MCP server and tools",
action: async (ctx: CommandContext) => {
const subcommand = ctx.args[0];
switch (subcommand) {
case "start": {
const port = ctx.flags.port as number || 3000;
const host = ctx.flags.host as string || "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 as Error).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 as Error).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 as Error).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 as Error).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 as Error).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 as Error).message}`);
}
break;
}
case "logs": {
const lines = ctx.flags.lines as number || 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 as Error).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: CommandContext) => {
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 as string || ctx.flags.n as string || "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 as Error).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 as string || ctx.flags.n as string;
const limit = ctx.flags.limit as number || ctx.flags.l as number || 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 as Error).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 as Error).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 as Error).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 as Error).message}`);
}
break;
}
case "cleanup": {
try {
const days = ctx.flags.days as number || ctx.flags.d as number || 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 as Error).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: CommandContext) => {
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 as string || "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 as string);
}
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.log(`Commit: ${ctx.flags.commit || "phase"}`);
console.log(`\nEnhanced Features:`);
console.log(` - Memory Bank enabled via: npx claude-flow memory commands`);
console.log(` - Coordination ${ctx.flags.parallel ? 'enabled' : 'disabled'}`);
console.log(` - Access Claude-Flow features through Bash tool`);
return;
}
success(`Spawning Claude instance: ${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.log(`💾 Commit: ${ctx.flags.commit || "phase"}`);
console.log(`✨ Enhanced with Claude-Flow guidance for memory and coordination`);
console.log('');
console.log('📋 Task will be enhanced with:');
console.log(' - Memory Bank instructions (store/retrieve)');
console.log(' - Coordination capabilities (swarm management)');
console.log(' - Best practices for multi-agent workflows');
console.log('');
// Execute Claude command
const { spawn } = await import("child_process");
const child = spawn("claude", claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')), {
env: {
...process.env,
CLAUDE_INSTANCE_ID: instanceId,
CLAUDE_FLOW_MODE: ctx.flags.mode as string || "full",
CLAUDE_FLOW_COVERAGE: (ctx.flags.coverage || 80).toString(),
CLAUDE_FLOW_COMMIT: ctx.flags.commit as string || "phase",
// Add Claude-Flow specific features
CLAUDE_FLOW_MEMORY_ENABLED: 'true',
CLAUDE_FLOW_MEMORY_NAMESPACE: 'default',
CLAUDE_FLOW_COORDINATION_ENABLED: ctx.flags.parallel ? 'true' : 'false',
CLAUDE_FLOW_FEATURES: 'memory,coordination,swarm',
},
stdio: "inherit",
});
const status = await new Promise((resolve) => {
child.on("close", (code) => {
resolve({ success: code === 0, code });
});
});
if ((status as any).success) {
success(`Claude instance ${instanceId} completed successfully`);
} else {
error(`Claude instance ${instanceId} exited with code ${(status as any).code}`);
}
} catch (err) {
error(`Failed to spawn Claude: ${(err as Error).message}`);
}
break;
}
case "batch": {
const workflowFile = ctx.args[1];
if (!workflowFile) {
error("Usage: claude batch <workflow-file>");
break;
}
try {
const { readFile } = await import("fs/promises");
const content = await readFile(workflowFile, "utf-8");
const workflow = JSON.parse(content);
success(`Loading workflow: ${workflow.name || "Unnamed"}`);
console.log(`📋 Tasks: ${workflow.tasks?.length || 0}`);
if (!workflow.tasks || workflow.tasks.length === 0) {
warning("No tasks found in workflow");
return;
}
const promises = [];
for (const task of workflow.tasks) {
const claudeCmd = ["claude", `"${task.description || task.name}"`];
// Add tools
if (task.tools) {
const toolsList = Array.isArray(task.tools) ? task.tools.join(",") : task.tools;
claudeCmd.push("--allowedTools", toolsList);
}
// Add flags
if (task.skipPermissions || task.dangerouslySkipPermissions) {
claudeCmd.push("--dangerously-skip-permissions");
}
if (task.config) {
claudeCmd.push("--mcp-config", task.config);
}
const taskId = task.id || `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
if (ctx.flags.dryRun || ctx.flags["dry-run"]) {
console.log(`\n${yellow("DRY RUN")} - Task: ${task.name || taskId}`);
console.log(`Command: ${claudeCmd.join(" ")}`);
continue;
}
console.log(`\n🚀 Spawning Claude for task: ${task.name || taskId}`);
const { spawn } = await import("child_process");
const child = spawn("claude", claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')), {
env: {
...process.env,
CLAUDE_TASK_ID: taskId,
CLAUDE_TASK_TYPE: task.type || "general",
},
stdio: "inherit",
});
if (workflow.parallel) {
promises.push(new Promise((resolve) => {
child.on("close", (code) => {
resolve({ success: code === 0, code });
});
}));
} else {
// Wait for completion if sequential
const status = await new Promise((resolve) => {
child.on("close", (code) => {
resolve({ success: code === 0, code });
});
});
if (!(status as any).success) {
error(`Task ${taskId} failed with code ${(status as any).code}`);
}
}
}
if (workflow.parallel && promises.length > 0) {
success("All Claude instances spawned in parallel mode");
const results = await Promise.all(promises);
const failed = results.filter((s: any) => !s.success).length;
if (failed > 0) {
warning(`${failed} tasks failed`);
} else {
success("All tasks completed successfully");
}
}
} catch (err) {
error(`Failed to process workflow: ${(err as Error).message}`);
}
break;
}
default: {
console.log("Available subcommands: spawn, batch");
console.log("\nExamples:");
console.log(" claude-flow claude spawn \"implement user authentication\" --research --parallel");
console.log(" claude-flow claude spawn \"fix bug in payment system\" --no-permissions");
console.log(" claude-flow claude batch workflow.json --dry-run");
break;
}
}
},
});
// Enhanced monitor command integration
try {
const enhancedMonitorAction = async (ctx: CommandContext) => {
// Convert CLI context to match enhanced command expectations
const options = {
interval: ctx.flags.interval || ctx.flags.i || 2,
compact: ctx.flags.compact || ctx.flags.c,
focus: ctx.flags.focus || ctx.flags.f,
alerts: c