feat(console): one session-status vocabulary everywhere, incl. working vs idle (v0.321.0) - #590
Merged
Merged
Conversation
…g vs idle (v0.321.0)
The console carried three parallel dialects for "what is this session doing":
a status dot that only knew live-vs-dead, a "waiting" bell threaded by prop to
two surfaces, and the chain rail's own words. The same run could read *green*
in the sidebar, *bell* in the terminal tab strip and *running* in the rail,
while the honest answer was "it finished its turn ten minutes ago".
Introduce a single `SessionState` — waiting → working → idle → stopped /
crashed / done, priority-ordered by what needs a human — and a single
`<SessionStatus>` renderer, used by the sidebar, the terminal tab strip, the
session cards + rows, the session header, the chat rail, the chain rail and
chips, the standalone terminal page, and the automation run list.
- working vs idle is the distinction that was missing. The server already
computed `working` (a turn in flight, from `busy_since`, cleared by the
runtime's turn-end beacon) and only the Chat rail read it; everywhere else a
pane mid-generation and a pane that finished its turn an hour ago drew the
same solid green dot. `working` pulses emerald, `idle` ("ready") is a hollow
emerald ring.
- The bell is part of the vocabulary rather than a separate widget, so "needs
you" reaches every surface including the sidebar. The blocked set (server
`blocked` ∪ open notification cards) moved from a prop to `WaitingCtx`, which
is why surfaces that never received the prop can show it at all.
- The state WORD ships beside the dot on the sidebar (agent subline) and on
inactive tab-strip tabs, so a strip of six terminals says which is generating.
- `headless` left the dot — the hollow ring now means "not busy"; the
unattended axis keeps its own marker (Headless badge / sidebar Cpu glyph).
- Sessions filter: added Working; Blocked renamed "Needs you".
- `ChainNode` gained `working` (same busy_since rule) so the hand-off rail can
tell a generating delegate from a merely warm one.
Verified against a scratch tenant with a stubbed session corpus covering every
state (sidebar, cards, rows, tab strip screenshotted); typecheck + both builds +
test:governance (19 passed) clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ZUfffxY4hKv7M6wMCcaTz
This was referenced Aug 8, 2026
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.
Why
You can't tell from the sidebar (or a strip of open terminals) which sessions are working, which are done, and which need you. The bell existed but only on two surfaces.
Root cause: three parallel dialects for the same fact.
running/waiting on you/pass…)workingdotAnd the one distinction that actually matters was thrown away: the server already computes
working(a turn in flight, frombusy_since, cleared by the runtime's turn-end beacon) — only the Chat rail read it. Everywhere else a pane mid-generation and a pane that finished its turn an hour ago drew the same solid green dot.What
One
SessionState, priority-ordered by what needs a human, and one<SessionStatus>renderer used on every surface:waitingworkingidlestoppedcrasheddoneblocked∪ open notification cards) moved from a prop toWaitingCtx, which is why surfaces that never got the prop can show it at all.headlessleft the dot (the hollow ring now means "not busy"); the unattended axis keeps the Headless badge / sidebarCpuglyph.ChainNodegainedworkingso the hand-off rail distinguishes a generating delegate from a warm one. The rail keeps its richer finished words (pass / failed / partial / duplicate / no report) — that's what it's for.Verification
Scratch tenant + a stubbed session corpus covering every state; sidebar, cards, rows and the terminal tab strip screenshotted.
npm run typecheck, both builds,npm run test:governance(19 passed) clean.Deploy note: touches
src/terminal.ts→ needs a build + server restart, plus the web bundle.🤖 Generated with Claude Code
https://claude.ai/code/session_015ZUfffxY4hKv7M6wMCcaTz