From 88889700c2d7ff5be3b793da6a36217dd1c328e9 Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 30 Jan 2026 19:58:55 +0100 Subject: [PATCH] feat(04-02): define AgentManager port interface and domain types - AgentStatus type for agent lifecycle states - SpawnAgentOptions for spawn configuration - AgentInfo for agent state representation - AgentResult for execution results - AgentManager interface with spawn, stop, list, get, getByName, resume, getResult --- src/agent/index.ts | 15 +++++ src/agent/types.ts | 136 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 src/agent/index.ts create mode 100644 src/agent/types.ts diff --git a/src/agent/index.ts b/src/agent/index.ts new file mode 100644 index 0000000..fb4f985 --- /dev/null +++ b/src/agent/index.ts @@ -0,0 +1,15 @@ +/** + * Agent Module - Public API + * + * Exports the AgentManager port interface and related types. + * All consumers should import from this index file. + */ + +// Port interface and types +export type { + AgentStatus, + SpawnAgentOptions, + AgentInfo, + AgentResult, + AgentManager, +} from './types.js'; diff --git a/src/agent/types.ts b/src/agent/types.ts new file mode 100644 index 0000000..3bc55f5 --- /dev/null +++ b/src/agent/types.ts @@ -0,0 +1,136 @@ +/** + * Agent Module Types + * + * Port interface for agent lifecycle management. + * AgentManager is the PORT. Implementations are ADAPTERS. + */ + +export type AgentStatus = 'idle' | 'running' | 'waiting_for_input' | 'stopped' | 'crashed'; + +/** + * Options for spawning a new agent + */ +export interface SpawnAgentOptions { + /** Human-readable name for the agent (e.g., 'gastown', 'chinatown') */ + name: string; + /** Task ID to assign to agent */ + taskId: string; + /** Initial prompt/instruction for the agent */ + prompt: string; + /** Optional working directory (defaults to worktree path) */ + cwd?: string; +} + +/** + * Represents a Claude agent instance + */ +export interface AgentInfo { + /** Unique identifier for this agent */ + id: string; + /** Human-readable name for the agent */ + name: string; + /** Task this agent is working on */ + taskId: string; + /** Claude CLI session ID for resumption (null until first run completes) */ + sessionId: string | null; + /** WorktreeManager worktree ID */ + worktreeId: string; + /** Current status (waiting_for_input = paused on AskUserQuestion) */ + status: AgentStatus; + /** When the agent was created */ + createdAt: Date; + /** Last activity timestamp */ + updatedAt: Date; +} + +/** + * Result from agent execution + */ +export interface AgentResult { + /** Whether the task completed successfully */ + success: boolean; + /** Result message or error description */ + message: string; + /** Files modified during execution */ + filesModified?: string[]; +} + +/** + * AgentManager Port Interface + * + * Manages Claude agent lifecycle - spawn, stop, list, resume. + * + * Covers requirements: + * - AGENT-01: Spawn new agent with task assignment + * - AGENT-02: Stop running agent + * - AGENT-03: List all agents with status + * - AGENT-04: Resume agent session + * - AGENT-05: Background mode (implementation detail) + */ +export interface AgentManager { + /** + * Spawn a new agent to work on a task. + * + * Creates isolated worktree, starts Claude SDK session, + * and begins executing the prompt. + * + * @param options - Spawn configuration + * @returns Agent info with session ID for later resumption + */ + spawn(options: SpawnAgentOptions): Promise; + + /** + * Stop a running agent. + * + * Gracefully stops the agent's work. Worktree is preserved + * for potential resumption. + * + * @param agentId - Agent to stop + */ + stop(agentId: string): Promise; + + /** + * List all agents with their current status. + * + * @returns Array of all agents + */ + list(): Promise; + + /** + * Get a specific agent by ID. + * + * @param agentId - Agent ID + * @returns Agent if found, null otherwise + */ + get(agentId: string): Promise; + + /** + * Get a specific agent by name. + * + * @param name - Agent name (human-readable) + * @returns Agent if found, null otherwise + */ + getByName(name: string): Promise; + + /** + * Resume an agent that's waiting for input. + * + * Used when agent paused on AskUserQuestion and user provides response. + * Uses stored session ID to continue with full context. + * Agent must be in 'waiting_for_input' status. + * + * @param agentId - Agent to resume + * @param prompt - User's response to continue the agent + */ + resume(agentId: string, prompt: string): Promise; + + /** + * Get the result of an agent's work. + * + * Only available after agent completes or stops. + * + * @param agentId - Agent ID + * @returns Result if available, null if agent still running + */ + getResult(agentId: string): Promise; +}