Skip to content

THI-463: Rail: a sonar strip and a Next queue in the agent's words (design A) - #59

Open
tdody wants to merge 3 commits into
mainfrom
thibaultdody/thi-463-rail-a-sonar-strip-and-a-next-queue-in
Open

tdody wants to merge 3 commits into
mainfrom
thibaultdody/thi-463-rail-a-sonar-strip-and-a-next-queue-in

Conversation

@tdody

@tdody tdody commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

This builds design A ("Sonar strip"), one of three rail redesigns mocked up side by side with today's rail: the options. The other two were B ("Sorted in place") and C ("Focus / All").

It fixes most of what the 2026-11-09 rail critique (23/40) found: broken agents were invisible, the attention rows dropped what the agent said, colour and motion reported nothing new, and branch headers doubled the rail's height.

What changes

  • Sonar strip, pinned to the top of the rail. One line per track, one blip per pane. A blip's shape says the state as well as its colour, so it reads without colour too:

    State Blip
    asks orange filled circle, pulsing
    broken red square
    done green ring, dimmer after an hour
    working amber three-quarter sweep
    idle small grey dot
    shell short bar

    Clicking a blip opens its pane. Clicking a track's name shows only that track in the tree; this replaces the filter chips.

  • A Next queue replaces NEEDS YOU, READY and RUNNING. It lists panes that ask (longest wait first), then broken ones, then finished ones.

    • Broken means an API error, or failing CI on an open PR, unless the agent is already working on it. A failing PR gets one card, however many panes show it, the same way Clawd counts it.
    • Each card shows what the agent said, its track (not the tmux session) and the reason it's there.
      • A permission request shows its command in mono.
      • An ask shows the newest notify message.
      • A finished pane shows the first sentence of its reply, as the done banner does.
    • Three cards show; the rest fold into "+N".
    • × marks a done card seen without opening it, or dismisses an event's card.
  • ⌘J opens the next pane that wants you, from anywhere, including the terminal. Repeated presses walk the queue in order, skip the pane already on screen, and start over once every card has been opened.

  • PINNED stays, without its green tint. ACTIVITY is unchanged.

  • A quieter tree:

    • A branch gets a header only when two or more panes in a multi-branch track share it. A pane alone on its branch shows the branch, in mono, on its selected card.
    • Each row has an age column: how long it has waited for you, or how long since its last turn finished. A waiting pane's age turns amber after 10 minutes and red after an hour.
    • Only asking panes pulse. Done no longer pulses, and nothing pulses under prefers-reduced-motion.
    • ↻ shows only when memory, not age, triggers it. The detail header still shows both.
    • Context shows on a compact row only once it's in the warning band. A raw token count now reads "653k ctx".
    • The PR chip, with its CI glyph, moves to the row's first line.
    • "+" (new tab) moves into the track header.
  • Shared logic, so the rail and Clawd agree:

    • isCiFailing and prKey are shared with Clawd's CI duty.
    • The done and needs-input banner wording is shared with the Next cards.
    • A banner's Mark seen now also dismisses that pane's notify(done) events, so they can't come back in its place.
  • Accessibility:

    • Blips and cards are buttons with names that include the state.
    • The hover actions show when the row has keyboard focus, with a focus outline.
    • Section headers are 10px labels again. A rule-ordering bug had set them in 13px.
  • Cleanup:

    • DESIGN.md describes the strip, Next cards, blip shapes and the asks-only pulse.
    • Removed now-dead code: the attention-row tints and dots, filter chips, the wt-meta strip, NewTabRow, WorktreeMeta, maxSeverity, the branch-order pref and its server field.

Testing

  • npm test: 1451 pass. New cases cover:
    • paneBlip, buildNext, nextToOpen, isCiFailing
    • the Next card's words (nextWords)
    • the clustering rule in mergeLiveAndPrefs
    • markReadySeen / dismissEvents
    • isNextKey
    • render checks for the strip, cards and clusters
  • bin/check is clean. uv run pytest tests/routes/test_prefs.py passes (the only Python change).
  • Checked on a dev instance (:17375) against the live panes:
    • the strip stays pinned while the tree scrolls
    • the track scope works
    • ⌘J from inside the terminal opened the first card (CI failing)
    • no console errors
  • An independent review found eight issues; all are fixed in the third commit.
    • A card click didn't release the layout freeze.
    • ⌘J bounced back to the top of the queue.
    • Each pane on a failing PR got its own card.
    • × on a done card let its event card come back.
    • An asking card showed the oldest question, not the newest.
    • A track scope could strand the tree when its track emptied.
    • Asks and working blips had the same shape.
    • A role=button card hid its × from screen readers.

Assumptions to challenge

  • Failing CI counts on any PR a pane shows, including one picked up from the branch rather than linked, as Clawd's CI duty already does. A pane on a PR you're only reviewing will sit in Next until CI goes green; broken cards have no ×.
  • THI-440 (the API-error flag sticking after a text-only reply) looks fixed by THI-455: error-then-only-text now expects False. Next relies on that flag.
  • Done panes stay in Next until seen, however old, as READY did. Their blip dims after an hour. This overrides THI-456's "a done pane pulses for about an hour".
  • Pre-existing: .impeccable/design.json still describes the old attention headers. /impeccable document regenerates it.

Not in this PR

  • THI-458's roving-tabindex tree (↑/↓ between rows).
  • THI-431's bare-key shortcuts (j/k, a, r, ?).

Covers most of THI-456, THI-457, THI-459 and THI-460.

🤖 Generated with Claude Code

tdody and others added 3 commits November 9, 2026 14:23
…DS YOU/READY/RUNNING; broken panes join it, branches cluster only when shared, only asks pulse, ⌘J opens the next (THI-463)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pulse (THI-463)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ened, one card per failing PR, the newest question shows, × dismisses a pane's events together, working blips sweep (THI-463)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant