feat(tui): make session tab status explicit - #45347
Merged
Merged
Conversation
kitlangton
marked this pull request as ready for review
August 26, 2026 18:09
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
Session tabs distinguish running work and pending input mostly through subtle colors and the wave animation. It is easy to miss that a background session is waiting for an answer or permission rather than still working.
What Changes
Keep the wave, but give each state a recognizable indicator beside the title in both the top strip and sidebar:
Settings > Tabs > Indicators switches between status icons (default) and always show numbers. The latter keeps the numbered-tab presentation without holding Control, while retaining status colors and background animations. The preference is saved as
tabs.indicators(statusornumbers) incli.jsonand applies immediately in both layouts.?!+The unread bullet appears in its final color immediately. Reading it gives a subtle brighten-and-fade into the current tab background over 180 ms, then leaves the slot blank. It never transitions through the running color. The existing background wave and clear pulse remain.
Selecting a pending
?or!keeps its glow active, easing to 70% strength over 200 ms. Leaving restores full strength without replaying ignition; the clear pulse runs only when the request resolves. Requests include child sessions, and permission takes precedence when both kinds are pending. The public plugin API still exposesattentionas a Boolean.In status-icon mode, hold Control for 300 ms to reveal numbers with their existing colors and pulse. Release or terminal blur hides them immediately. Brief chords do not flash numbers, and jump bindings are not delayed. Kitty modifier-only reports update held state before command matching, preserving transcript selections and leader sequences; associated-text reporting preserves casing.
Semantic
text.status.running,question,permission, andunreadtheme tokens distinguish running, attention, and unread colors. Built-in light/dark and standalone themes inherit defaults from their own hues and feedback tokens. The Tabs story retains alternate spinner/marker controls, reduced motion, both layouts, and idle/showcase resets for exploration.Demo
Before
2602dcd0a7, afterd521be850a. The same deterministic fixture drives real isolated sessions and the production TUI with a fictional simulated model. This 12-second, real-time sidebar crop shows the unchanged default status-icon mode: working, pending question/permission selection, unread clearing, and Control reveal/release. Setup and gaps are trimmed; no story controls or acceleration. The subsequently added number-mode setting is shown below.final-tab-status.mp4
Number-mode setting at
de2ecc2c4c, exercised through the real settings dialog in an isolated Drive session:Scope
This changes tab presentation and modifier tracking, not the execution-outcome model. Alternate spinner and unread-marker styles are story controls only; production defaults are the Braille spinner and small bullet.
Verification
The latest mode-setting regression batch passed 37 tests (404 assertions). After the preceding test cleanup, the focused TUI suite passed all 103 tests (689 assertions); the four consolidated theme tests passed with 36 assertions. TUI, CLI, and website typechecks passed, as did all 32 normal pre-push typecheck tasks. The website build, formatting, and
git diff --checkpassed.The website's generated-file check initially found pre-existing stale message-update API snapshots. The build regenerated them and the check passed; those unrelated generated diffs are excluded from this PR.
Before the test cleanup, the broader TUI batch passed 112 tests and hit the previously observed timeout in
shows jump to latest after scrolling one line above the final message; the isolated rerun passed. No scrolling code changed. An earlier full TUI run had the same intermittent failure (813 passed, 5 skipped).Coverage includes first-frame unread/error colors, marker fade and interruption, animated attention dimming without clear/reignition, delayed and cancelled Control reveal, left/right Control and focus loss, selection copying, shifted leader sequences, Caps Lock text, child-request precedence, inline layout, mouse behavior, and light/dark/custom/standalone theme fallback. The real story was also exercised at narrow and wide terminal sizes.
A separate real Drive run passed the settings workflow: switch to numbers, verify the saved preference, resize from the sidebar to the narrow top strip, and switch back to status icons. Component tests verify that number mode survives Control release and blur and can be toggled without remounting.
Both Drive captures reached every checkpoint, but its bundled Ghostty replay crashed during export. The published clip replays the unchanged PTY bytes and timestamps through Drive's alternate-parser interface with xterm-headless, using the same rendering and encoding path. All eight comparison phases and the dot's fade were visually inspected. Capture commands are not counted as passing end-to-end tests.