diff --git a/src/cli/index.ts b/src/cli/index.ts index 19c6214..ea7ab4b 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -97,11 +97,138 @@ export function createCli(serverHandler?: (port?: number) => Promise): Com } }); - program + // Agent command group + const agentCommand = program .command('agent') - .description('Manage agents') - .action(() => { - console.log('cw agent: not implemented'); + .description('Manage agents'); + + // cw agent spawn --name --task + agentCommand + .command('spawn ') + .description('Spawn a new agent to work on a task') + .requiredOption('--name ', 'Human-readable name for the agent (e.g., gastown)') + .requiredOption('--task ', 'Task ID to assign to agent') + .option('--cwd ', 'Working directory for agent') + .action(async (prompt: string, options: { name: string; task: string; cwd?: string }) => { + try { + const client = createDefaultTrpcClient(); + const agent = await client.spawnAgent.mutate({ + name: options.name, + taskId: options.task, + prompt, + cwd: options.cwd, + }); + console.log(`Agent '${agent.name}' spawned`); + console.log(` ID: ${agent.id}`); + console.log(` Task: ${agent.taskId}`); + console.log(` Status: ${agent.status}`); + console.log(` Worktree: ${agent.worktreeId}`); + } catch (error) { + console.error('Failed to spawn agent:', (error as Error).message); + process.exit(1); + } + }); + + // cw agent stop + agentCommand + .command('stop ') + .description('Stop a running agent by name') + .action(async (name: string) => { + try { + const client = createDefaultTrpcClient(); + const result = await client.stopAgent.mutate({ name }); + console.log(`Agent '${result.name}' stopped`); + } catch (error) { + console.error('Failed to stop agent:', (error as Error).message); + process.exit(1); + } + }); + + // cw agent list + agentCommand + .command('list') + .description('List all agents') + .action(async () => { + try { + const client = createDefaultTrpcClient(); + const agents = await client.listAgents.query(); + if (agents.length === 0) { + console.log('No agents found'); + return; + } + console.log('Agents:'); + for (const agent of agents) { + const status = agent.status === 'waiting_for_input' ? 'WAITING' : agent.status.toUpperCase(); + console.log(` ${agent.name} [${status}] - ${agent.taskId}`); + } + } catch (error) { + console.error('Failed to list agents:', (error as Error).message); + process.exit(1); + } + }); + + // cw agent get + agentCommand + .command('get ') + .description('Get agent details by name') + .action(async (name: string) => { + try { + const client = createDefaultTrpcClient(); + const agent = await client.getAgent.query({ name }); + if (!agent) { + console.log(`Agent '${name}' not found`); + return; + } + console.log(`Agent: ${agent.name}`); + console.log(` ID: ${agent.id}`); + console.log(` Task: ${agent.taskId}`); + console.log(` Session: ${agent.sessionId ?? '(none)'}`); + console.log(` Worktree: ${agent.worktreeId}`); + console.log(` Status: ${agent.status}`); + console.log(` Created: ${agent.createdAt}`); + console.log(` Updated: ${agent.updatedAt}`); + } catch (error) { + console.error('Failed to get agent:', (error as Error).message); + process.exit(1); + } + }); + + // cw agent resume + agentCommand + .command('resume ') + .description('Resume an agent that is waiting for input') + .action(async (name: string, response: string) => { + try { + const client = createDefaultTrpcClient(); + const result = await client.resumeAgent.mutate({ name, prompt: response }); + console.log(`Agent '${result.name}' resumed`); + } catch (error) { + console.error('Failed to resume agent:', (error as Error).message); + process.exit(1); + } + }); + + // cw agent result + agentCommand + .command('result ') + .description('Get agent execution result') + .action(async (name: string) => { + try { + const client = createDefaultTrpcClient(); + const result = await client.getAgentResult.query({ name }); + if (!result) { + console.log('No result available (agent may still be running)'); + return; + } + console.log(`Result: ${result.success ? 'SUCCESS' : 'FAILED'}`); + console.log(` Message: ${result.message}`); + if (result.filesModified?.length) { + console.log(` Files modified: ${result.filesModified.join(', ')}`); + } + } catch (error) { + console.error('Failed to get result:', (error as Error).message); + process.exit(1); + } }); program