Skip to main content

Module background_task_feed

Module background_task_feed 

Source
Expand description

The Claude CLI’s own structured task feed → db_background_tasks.

The CLI reports every task it runs on the agent’s stdout as system lines:

  • task_started — task_id, tool_use_id, description, task_type (local_bash, local_agent, local_workflow), is_backgrounded, and owned_by_subagent when a subagent launched it.
  • task_updated — task_id plus a patch: {is_backgrounded: true} when a running command is moved to the background, {status, end_time} when it ends (completed, failed, killed).
  • task_notification — task_id, tool_use_id, final status (completed, failed, stopped) and a summary.

These arrive on the PARENT agent’s stream even for tasks a subagent owns. Before this module nothing read them: the registry learned about a background task only from the renderer spotting the “Command running in background with ID:” result text, and learned it had ended only from a <task-notification> user message in the same pane. A subagent’s task gets the first but never the second, so its row stayed running forever; a top-level task’s result now carries empty stdout plus a structured backgroundTaskId, so the text match missed it entirely. See docs/specs/SPEC_BACKGROUND_TASK_STRUCTURED_FEED_AND_SWARM_OWNERSHIP_2026_09_27.md.

Scope: backgrounded local_bash tasks only, which is what the registry has always held. Subagents (local_agent) are Swarm’s subagent watcher’s job. The renderer’s existing observe/complete pushes still run; every write here is the same idempotent background_task_observe/background_task_complete call, so whichever arrives first wins and the other is a no-op or a refresh.

Structs§

Pending 🔒
A shell task seen starting on this stream, remembered until it ends so a later task_updated (which names only the task_id) can be applied.
TaskFeed 🔒
Per-stream state: one per stdout reader. Holds only shell tasks that have started and not yet ended, plus the owners of subagent Bash calls whose task_started hasn’t arrived yet, so it stays small.

Enums§

TaskFeedEvent 🔒
One task-feed line, reduced to what the registry needs.

Constants§

MAX_UNCLAIMED_OWNERS 🔒
Bound on TaskFeed::owners. Entries are normally consumed by the task_started that follows within the same message; this only guards against a stream shape where that never happens.

Functions§

complete_if_running 🔒
Complete tool_use_id’s row if it is still running. The CLI usually reports an end twice (task_updated, then task_notification); only a still-running row is completed, so the first end time stands and subscribers hear it once.
observe 🔒
Create the row if needed, then record the CLI’s description as its label (replacing the renderer’s generic “Bash” if it got there first) and its owner.
parse 🔒
Pure parse of one stdout line. None for anything that isn’t a task-feed line about a shell task.
publish_background_task_updated 🔒
Notify subscribers that block_id’s db_background_tasks state changed (observed, pid recorded, or completed), so the frontend can re-query COMMAND_LIST_BACKGROUND_TASKS instead of polling. Live-only (persist: 0) — a late subscriber gets the current state via the mount-time list query, not event replay. Deliberately carries no task data itself (just an invalidation signal): the list query is the single source of truth for the actual rows. See docs/specs/SPEC_BACKGROUND_TASK_DASHBOARD_INTELLIGENCE_2026_08_20.md §3.2.
str_field 🔒
terminal_status 🔒
Terminal statuses as the CLI spells them. Anything unrecognised ends the task as stopped rather than leaving it running — the same lenient rule the renderer’s parseTaskNotification applies.