Task System
- Entity ID:
ent-20260410-362bd3ec4562 - Type:
service - Scope:
shared - Status:
active
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
- Five-state lifecycle with three terminal states. Tasks transition through
pending -> running -> completed | failed | killed. The functionisTerminalTaskStatus()insrc/Task.ts(line 27) returns true forcompleted,failed, andkilled, gating message injection, eviction, and cleanup. - Task IDs use type-specific single-character prefixes followed by 8 random characters. Prefixes are:
b(local_bash),a(local_agent),r(remote_agent),t(in_process_teammate),w(local_workflow),m(monitor_mcp),d(dream). The ID alphabet is0123456789abcdefghijklmnopqrstuvwxyz(36 chars), producing ~2.8 trillion combinations per type (src/Task.ts, lines 79-106). - InProcessTeammateTask caps UI messages at 50 to control memory. The
TEAMMATE_MESSAGES_UI_CAPconstant (set to 50 insrc/tasks/InProcessTeammateTask/types.ts, line 101) limits thetask.messagesarray, which exists only for the transcript dialog. A BQ analysis found ~20 MB RSS per agent at 500+ turns and ~125 MB per concurrent agent in swarm bursts; one whale session launched 292 agents in 2 minutes and reached 36.8 GB. - LocalShellTask includes a stall watchdog for interactive-prompt detection. A 5-second polling interval checks whether output has stopped growing for 45 seconds and the last line matches common prompt patterns (e.g.,
(y/n),Continue?,Press Enter). When triggered, it enqueues a notification advising the model to kill and re-run with piped input (src/tasks/LocalShellTask/LocalShellTask.tsx, lines 26-104). - Terminal tasks are evicted from AppState after notification, with a 30-second grace period for agent panel tasks.
evictTerminalTask()insrc/utils/task/framework.ts(line 125) removes tasks only whenisTerminalTaskStatusis true andnotifiedis true. ForLocalAgentTaskStatetasks, eviction is deferred untilevictAfter(set toDate.now() + PANEL_GRACE_MSwherePANEL_GRACE_MS = 30_000) has passed, so the coordinator panel can display completed results briefly.
Relations
- depends on
AppState-- all task state is stored inAppState.tasksand mutated viasetAppState - depends on
MessageQueueManager(src/utils/messageQueueManager.ts) -- task notifications are delivered viaenqueuePendingNotification() - depends on
AgentTool/runAgent--LocalAgentTaskandInProcessTeammateTaskdelegate execution to the agent runner - depends on
ShellCommand(src/utils/ShellCommand.ts) --LocalShellTaskwraps spawned shell processes - depends on
Teleport API(src/utils/teleport.ts) --RemoteAgentTaskpolls remote cloud sessions viapollRemoteSessionEvents() - depends on
autoDreamservice (src/services/autoDream/) --DreamTaskis spawned by the auto-dream memory consolidation system - used by
TaskCreateTool,TaskGetTool,TaskUpdateTool,TaskListTool,TaskOutputTool,TaskStopTool-- six LLM-facing tools that create, query, update, list, read output from, and stop tasks - used by
BackgroundTasksDialogUI component -- renders the footer pill and detail dialog for background tasks - used by
LocalMainSessionTask-- extendsLocalAgentTaskstate to support backgrounding the main session via Ctrl+B
Sources
src/Task.ts-- base types (TaskType,TaskStatus,TaskStateBase,Taskinterface), ID generation,isTerminalTaskStatus()src/tasks.ts-- task registry (getAllTasks(),getTaskByType())src/tasks/types.ts--TaskStateunion type,BackgroundTaskState,isBackgroundTask()src/tasks/stopTask.ts-- unifiedstopTask()entry point withStopTaskErrorsrc/tasks/pillLabel.ts-- footer pill label logicsrc/tasks/LocalShellTask/LocalShellTask.tsx-- shell task spawn, stall watchdog, notificationsrc/tasks/LocalShellTask/guards.ts--LocalShellTaskStatetype and guardsrc/tasks/LocalShellTask/killShellTasks.ts--killTask(),killShellTasksForAgent()src/tasks/LocalAgentTask/LocalAgentTask.tsx-- local agent task state, progress tracking, kill, notificationsrc/tasks/RemoteAgentTask/RemoteAgentTask.tsx-- remote agent task state, polling, completion checkers, review/plan extractionsrc/tasks/InProcessTeammateTask/InProcessTeammateTask.tsx-- teammate task lifecycle, shutdown, message injectionsrc/tasks/InProcessTeammateTask/types.ts--InProcessTeammateTaskState,TeammateIdentity, message capsrc/tasks/DreamTask/DreamTask.ts-- dream task registration, turn tracking, phase detectionsrc/tasks/LocalMainSessionTask.ts-- main session backgrounding via Ctrl+B, foreground restoresrc/utils/task/framework.ts--registerTask(),updateTaskState(),evictTerminalTask(),pollTasks(),generateTaskAttachments()src/utils/task/diskOutput.ts-- task output file management