Merge pull request 'docs(maestro): replace the sidebar's activity dot with a rail' (#130) from indicators into main
ci / web (push) Successful in 3m40s
ci / rust (push) Successful in 5m49s
ci / flake (push) Successful in 6m12s

Reviewed-on: #130
This commit was merged in pull request #130.
This commit is contained in:
2026-09-02 17:00:58 +01:00
7 changed files with 154 additions and 63 deletions
+33 -11
View File
@@ -37,23 +37,45 @@ itself is not.
Line 2 reads left to right:
```
<dot> [<duration>] [<detail>] [<diff stat> | exited] <command>
[<duration>] [<detail>] [<diff stat> | exited] <command>
```
Its minimum content is therefore the dot and the command.
Its minimum content is therefore just the command.
`<dot>` is a single filled glyph (`●` on both clients) carrying the activity
state's colour, and `<duration>` follows in the same colour when shown. There
is no state word and no second badge: the dot exists so the state is still
legible when a row is dimmed or the terminal renders the duration in the
default fg. The dot is an unconditional part of line 2; the bracketed
fragments appear only when their trigger holds.
The activity state does not render as an inline glyph on line 2 — a **rail**
carries it instead: a coloured bar in the gutter to the left of the card, the
space nesting already reserves for indentation. The rail paints for every
card, `Idle` included, and is independent of whatever line 2 has to say; a
card with nothing else to report still shows its rail next to the bare
command. `<duration>` follows in the rail's colour when shown. There is no
state word and no second badge: the rail exists so the state is still legible
when a row is dimmed or the terminal renders the duration in the default fg.
In the **web client** the rail is a 5px bar positioned inside the row's own
indent gutter — it shifts outward with nesting depth exactly as the gutter
does — spanning the full card height. It carries motion, reserved for states
that need attention (DESIGN.md's "living signals" rule): a slow breathing
opacity while `Active`, a hard blink while `AwaitingInput`, a fast flash while
`Error`. `Idle` is solid and still, on purpose. `prefers-reduced-motion`
leaves every state as a solid bar.
In the **TUI** the rail is a one-column-wide block glyph (`▌`) in the state's
palette role, leading the existing indent gutter (`INDENT`/`META_INDENT`) on
both the name row and the meta row, so the two lines read as one continuous
bar. Folder headers gain a matching blank leading column so labels still
align under session names. The TUI has no render cadence to animate against,
so its rail is always static — colour is the whole signal there, as it
always was.
Either client's rail carries the accessibility duty the old inline dot did:
it is the element whose `title`/`aria-label` names the state, so status still
never relies on colour alone.
`<duration>` renders only once the session has been held in its current
activity state longer than **30 seconds** (`activity_since` from #102) — under
that threshold the duration is absent and the dot renders alone. A payload
that predates #102 (no usable `activity_since`) likewise contributes no
duration — the dot still renders. This rule now governs only the duration
that threshold the duration is absent and the rail carries the state alone. A
payload that predates #102 (no usable `activity_since`) likewise contributes
no duration — the rail still renders. This rule now governs only the duration
fragment; it no longer decides whether line 2 exists.
`<detail>` is an agent-reported string (#105) — e.g. why a session is in