fix(web): show a thread's completion when a watch loop is still live - #7655
fix(web): show a thread's completion when a watch loop is still live#7655liaugust wants to merge 1 commit into
Conversation
The sidebar row has one status slot, and `backgroundLiveness: "monitoring"` claimed it ahead of an unread completion. Monitors are `local_bash` tasks, so any thread that leaves a dev server, a `tail -f`, or a `gh pr checks --watch` running showed `Monitoring` for as long as that shell lived and never showed `Done` — the user was never told the turn had finished. Monitoring means watch loops are the ONLY live work, so by then the turn has already settled: an unread completion or a wake is exactly the news the row exists to deliver. Resolve the label through a pure resolver that puts those attention states ahead of monitoring, and keep `working` ahead of them because real background work means the thread is not done yet. Monitoring returns to the slot once the completion has been read, so nothing is lost. The same ordering is fixed in the legacy sidebar's pill, and the project rollup priority is swapped to match so its documented "mirrors the per-thread resolver exactly" invariant still holds. `Approval`, `Input`, `Failed` and `Working` already outranked monitoring in `resolveSidebarThreadStatus`; that was untested, so it is pinned now too.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — Well-scoped UI fix with good test coverage, but the author has no prior history with this file. The change affects which status indicator users see when watch loops are running alongside unseen completions - recommend human verification of the intended behavior. You can add or adjust custom eligibility rules. Learn more. |
What Changed
The sidebar row has one status slot, and
backgroundLiveness: "monitoring"claimed it ahead of an unread completion, so a finished turn never announced itself. The label now resolves through a pureresolveSidebarThreadTopStatusKindthat puts attention states ahead of passive monitoring:workingstays ahead ofdone— real background work means the thread is not finished. Every label, icon and class is unchanged; the existing chain is keyed off the resolved kind. The legacy sidebar'sresolveThreadStatusPillhad the same ordering, andTHREAD_STATUS_PRIORITYis swapped toCompleted: 2, Monitoring: 1so the project rollup keeps its in-code "mirrors the per-thread resolver exactly" invariant.Why
backgroundLivenessis defined inpackages/contractsas "Native background work alive after the turn settles", with"monitoring"meaning "watch loops are the only live work". Whenever the row saidMonitoring, the turn had already settled — so the completion the row exists to announce was unreachable.Monitors are
local_bashtasks (ThreadBackgroundLiveness: no agent tasks, ≥1 monitor task), so a thread that leaves a dev server, atail -f, or agh pr checks --watchrunning showedMonitoringfor as long as that shell lived and could never showDoneagain.Sidebar.tsxalready contradicted itself here:shouldRecedecontains!isUnread, deliberately keeping an unread monitoring row at full prominence, while the label hid the reason.Sidebar.logic.tsstates the principle — "Unread completion is tracked separately: it describes whether a ready thread needs attention, not what the thread is currently doing" — and the neighbouringPlan Readybranch already encodes it.Approval,Input,FailedandWorkingalready outranked monitoring inresolveSidebarThreadStatus. That was untested, so it is pinned now.Surfaces
backgroundLivenessat all, so it has no equivalent label to fix.legacySidebarsetting), and the project rollup.Doneis an unread state, so opening the thread returns the slot toMonitoring. Nothing is permanently hidden either way.UI Changes
Reproduced against a dev build on an isolated
T3CODE_HOME: a real turn that leaves a backgroundsleeprunning so the monitor outlives the settled turn, with the thread left before it finished so the completion landed unseen.Reported by a nightly user (project, title and branch redacted):
Opening the thread reads the completion and monitoring returns to the slot:
Same live thread in every capture; only this diff differs between them. No motion or timing changes, so no video — the label swap is instant in both directions.
A variant showing both signals at once (
Doneplus a monitoring dot) was prototyped and left out: a second text label truncated the project name at the row's 238px width, and a new indicator is a design decision rather than part of this fix.Checklist
Built with Claude Opus 5 in T3 Code through the Claude Code harness.