Task System

Description

The Task System is the background and parallel work-item manager for Claude Code, rooted at src/tasks/. It provides a unified lifecycle for seven distinct task types that all share a common base state (TaskStateBase) and a five-state status machine: pending -> running -> completed | failed | killed. The three terminal states (completed, failed, killed) are detected by the helper isTerminalTaskStatus() and used to guard against injecting messages into dead tasks, to drive eviction from AppState, and to trigger cleanup paths. Every task is assigned a prefixed ID (e.g., b for bash, a for local agent, r for remote agent, t for teammate, d for dream, w for workflow, m for monitor) generated from 8 cryptographically random bytes over a 36-character alphabet, yielding roughly 2.8 trillion combinations per prefix.

The seven task types are: LocalShellTask (local_bash) for background shell commands with a stall-watchdog that detects interactive prompts; LocalAgentTask (local_agent) for local sub-agent execution with progress tracking (tool use counts, token counts, recent activities) and foreground/background toggling; RemoteAgentTask (remote_agent) for cloud-hosted agent sessions that are polled for completion and support subtypes like ultraplan, ultrareview, and autofix-pr; InProcessTeammateTask (in_process_teammate) for swarm-style parallel teammates running in the same Node.js process with AsyncLocalStorage isolation, team-aware identity, plan-mode approval, and independent permission modes; LocalMainSessionTask (a specialized local_agent with agentType: 'main-session') for backgrounding the user's current query via Ctrl+B; DreamTask (dream) for background memory-consolidation sub-agents surfaced only in the UI footer pill; and two feature-gated types -- LocalWorkflowTask (local_workflow, behind WORKFLOW_SCRIPTS) and MonitorMcpTask (monitor_mcp, behind MONITOR_TOOL).

The framework layer at src/utils/task/framework.ts provides registerTask(), updateTaskState(), evictTerminalTask(), polling via pollTasks() at a 1-second interval, and a notification system that enqueues XML-formatted <task_notification> messages into a shared message queue. Tasks are stored in AppState.tasks as a Record<string, TaskState>. Each task type implements the Task interface, which requires a name, type, and kill(taskId, setAppState) method. The stopTask() function in src/tasks/stopTask.ts provides a unified entry point for stopping any task by ID, looking it up, validating it is running, delegating to the type-specific kill(), and suppressing duplicate notifications. Six LLM-facing tools are exposed: TaskCreateTool, TaskGetTool, TaskUpdateTool, TaskListTool, TaskOutputTool, and TaskStopTool.

Key claims

Relations

Sources