Skip to content

feat: show background task commands and live output - #1

Merged
tarunravi merged 3 commits into
mainfrom
feat/background-task-visibility-main
Sep 29, 2026
Merged

tarunravi merged 3 commits into
mainfrom
feat/background-task-visibility-main

Conversation

@tarunravi

Copy link
Copy Markdown
Owner

Background Bash tasks were opaque: the composer banner said "Waiting on background task: " but showed no command or output, so a user could not tell whether a task was, say, a dev server holding a port.

How it works

  • Roster enrichment (Claude adapter). Each background task is joined to the Bash tool call that started it, recording the command, tool_use_id, start time, and the output file named in the Bash ack, so all of it is known while the task runs. background_tasks_changed snapshots keep these fields.
  • Output tail RPC. orchestration.getBackgroundTaskOutput returns the last 200 lines / 64 KiB of a task's output. The client names a task, never a path; the server reads only the file on that thread's roster, and only an absolute <taskId>.output.
  • Per-environment routing. The web client sends both RPCs over the thread's own environment connection, so remote and devbox threads read the file on the host that owns it, with no extra tunnel.
  • Views. The thread details panel gets a Background section. A right-panel view shows the command, elapsed time, a per-task Stop (SDK stopTask), and a polled, auto-scrolling tail. Clicking the banner opens a popover over the composer that lists the tasks, tails the selected one inline, and links to the panel view.
  • Thread-wide Stop. On feat/side-chat (e0e47af), the banner's Stop did nothing after a turn settled: ClaudeAdapterV2.interruptTurn rejected it with "is not the active turn", so a dev server kept its port. main already fixes this in 069058c (fix(server): Stop ends a Claude thread's background work after the turn settles pingdotgg/t3code#13792) by closing the Claude process, so this PR relies on that fix instead of adding its own. The popover's per-task Stop uses stopTask and leaves the session running.

Tests

Adapter tests cover the command/tool-use/output-file capture and per-task stop, and main's settled-Stop tests still pass with the richer task data. A replay-fixture check confirms the enriched roster; the tail has bounds and path-restriction tests; web tests cover selection logic and the list. Typecheck (TS 6.0.3) and lint show nothing new. In the adapter, orchestration, ws, contracts and web chat suites, the only failures (Antigravity file system ×2, ProviderTurnStartService.memory ×4, one runtimeLayer rollback test) also fail on unmodified main.

Screenshots (from the feat/side-chat-based test build; the Stop pair shows this branch's earlier stopTask fix): after-01-banner-shows-command.png, after-02-right-panel-live-tail.png, after-05-details-background-section.png, after-popover-open-two-tasks.png, after-popover-compact-title-right-panel.png, before-thread-stop.png, after-thread-stop.png, after-07-subagent-lineage-unchanged.png.

Claude Opus 5.5 in Claude Code.

tarunravi and others added 3 commits September 29, 2026 00:35
Claude background Bash tasks were opaque: the composer banner showed only a
description, and nothing showed what a task printed or whether it was, for
example, a dev server holding a port.

The Claude adapter now joins each background task to the Bash tool call that
started it, recording the command, tool_use_id, start time, and the output file
named in the Bash ack. A new read-only RPC tails that file (last 200 lines /
64 KiB) and only reads the output file registered on the thread's roster. A
second RPC stops one task through the SDK's stop_task control request.

The thread details panel lists running background tasks next to Lineage, and
the composer banner shows each command; both open a right-panel view with the
command, elapsed time, a per-task Stop, and a polled, auto-scrolling tail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Checking on a background task meant leaving the conversation for the right
panel. The banner summary is now a popover trigger: it rises from the banner
with one row per task (command, elapsed time, per-task Stop), tails the selected
task inline, and offers "Open in panel" for the full view. It shows the only
task by default, and polling stops when it closes. The banner title shortens
at narrow widths so the commands stay visible beside an open right panel.

The tail, Stop button, and row list are shared with the right-panel view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The popover measured its unconstrained output width before adopting the
banner's, then collision shifting pushed it to the window's left edge. A new
PopoverPopup width="anchor" sizes the positioner itself to the anchor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL labels Sep 29, 2026
@tarunravi
tarunravi merged commit 6ac1838 into main Sep 29, 2026
7 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant