Repository navigation
fix(web,mobile): show background task endings on the call that started them - #535
Merged
Merged
Conversation
…d them A background task's end event (a backgrounded shell command or a monitor) was stamped with whichever turn was running when it arrived and rendered as its own row there. The Bash row that started it read as finished as soon as the command went to the background, with no sign of how it ended. A task left running when the provider session ended was reported on resume inside the next turn. After a manual /compact, that stale row counted as work, so the turn folded and hid the compaction divider. Web and mobile now match a background task's end event to the tool row whose call ID is the task's toolUseId. The row keeps its turn and position and shows the ending: web adds a completed, failed, or stopped mark with the provider's summary as its tooltip, and mobile adds the summary to the expanded detail. A failed ending marks the call failed. When the task ends while its call is still running (a long foreground command), the call's own result stands and no mark is added. An end event whose launching row is not loaded still shows as its own row. Mobile hid a tool row whenever any task named it as its launcher; it now hides only calls that launched agents, so background commands keep their row as on web.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
A background command's ending now shows on the Bash row that started it, instead of as a separate row in whatever turn it ends in. This also stops a stale notice from folding away the divider after
/compact.Problem
When a background task ends (a Bash command run in the background, a command moved to the background at its timeout, or a monitor), its end event gets the ID of whichever turn is running at that moment, and clients show it as its own row in that turn. The Bash row that started the command reads as finished as soon as the command moves to the background, so scrolling back up gives no sign of whether it finished, failed, or was abandoned.
When the provider process ends with a background command still running, Claude reports the task as stopped when the session next resumes ("Background shell command didn't finish before the previous session ended"). That row lands in the next turn. After a manual
/compact, it counted as work, so the turn folded behind "Worked for …" and hid the compaction divider.Change
Web and mobile match a background task's end event to the tool row whose call ID is the task's
toolUseId, which Claude includes on every task event.The shared outcome reader lives in
packages/client-runtime/src/work-log/presentation.ts. The server is unchanged. The fork feature ledger records this asbackground-task-endings. Upstream's V2 orchestrator keeps background work in the run that started it (see pingdotgg#13789). On upstreammain, pingdotgg#10295 proposed a fuller version of this and was closed while V2 is in progress.Before and after
Before: after
/compact, the stale "Task stopped" row is in the turn, which folds and hides the divider until expanded.After: the
/compactturn contains only the compaction, so the divider shows directly.After: the Bash row from the earlier turn shows a stopped mark, with Claude's summary on hover.
Validation
run_in_backgroundto a/compactthe next day, with the stopped notice the CLI sent on resume./compactis followed directly by "Compacted context 286K → 8.48K tokens".vp run devBash row with a dash mark, and hovering shows the summary./compactturn yields onecontext-compactionrow and no fold.session-logic.test.ts):threadActivity.test.ts): the ending lands on the launching row in its original turn.session-logic,MessagesTimeline.logicandMessagesTimeline, mobilethreadActivity, and client-runtimework-logall pass. Typecheck passes for web, mobile and client-runtime.Not verified: mobile on a device or emulator (covered by the feed unit test only), and completed or failed endings on screen (covered by the unit tests).
Written by an agent (Claude Code, claude-opus-5-5).