93 lines
3.8 KiB
Markdown
93 lines
3.8 KiB
Markdown
# SIDEBAR.md — the session card contract
|
|
|
|
One rule for how a session is rendered as a card in the sidebar, so the web
|
|
sidebar (#107) and the TUI sidebar (#108) describe a session the same way.
|
|
Read this before changing either. Both clients implement exactly what is
|
|
written here; if it needs to change, change it here first.
|
|
|
|
A card has **line 1** always and **line 2** only when line 2 has something to
|
|
say.
|
|
|
|
## Line 1 — name + actions
|
|
|
|
- Left: the session name — `metadata.name` if present, else the command line
|
|
(same fallback both clients already use).
|
|
- Right: two actions anchored to the top-right corner: **spawn similar**
|
|
(`⧉`) and **kill** (`✕`). In the TUI these are keyboard affordances shown on
|
|
the highlighted row; in the web they are buttons. The glyphs are shared so
|
|
muscle memory transfers.
|
|
- Actions reserve their fixed width; the name truncates with `…` before it can
|
|
ever reach them. **Overlap between the name and the actions is a defect** —
|
|
that overlap is what started this milestone.
|
|
|
|
Line 1 carries no badges. The `⚠ blocked work` badge (#83) and the `exited`
|
|
badge move off this row into line 2.
|
|
|
|
## Line 2 — meta line (adaptive)
|
|
|
|
Rendered only when at least one of these holds:
|
|
|
|
1. The session has been held in its current activity state longer than
|
|
**30 seconds** (`activity_since` from #102). A freshly-active session
|
|
stays one line.
|
|
2. Its worktree holds blocked work: `blocked_work` is `Some` and not clear
|
|
(`InTheWay::is_clear()`), rendered in `formatInTheWay`'s phrasing on web
|
|
and as `⚠ <summary>` on the TUI.
|
|
3. It has exited: `status == Dead`.
|
|
4. An agent-reported state (#105) of `Error` is in force (see Precedence).
|
|
|
|
Otherwise line 2 is absent — never an empty placeholder row.
|
|
|
|
When present, line 2 reads left to right:
|
|
|
|
```
|
|
<duration> [<state badge>] [<blocked work> | exited]
|
|
```
|
|
|
|
## Colour per activity state
|
|
|
|
The state word is never spelled out — the colour carries it.
|
|
|
|
| Activity state | Web token | ratatui colour |
|
|
| ---------------- | --------- | ----------------- |
|
|
| `Active` | `--live` | `Color::Green` |
|
|
| `Idle` | `--muted` | `Color::DarkGray` |
|
|
| `AwaitingInput` | `--warn` | `Color::Yellow` |
|
|
| `Error` | `--danger`| `Color::Red` |
|
|
|
|
Web tokens resolve per theme automatically (`styles.css` defines dark, light,
|
|
and `prefers-color-scheme` variants for each). The TUI uses the plain ratatui
|
|
named colours above; do not introduce RGB values or a new palette module for
|
|
this.
|
|
|
|
The duration text inherits its state's colour; the blocked-work and exited
|
|
fragments use the muted colour (`--faint` / default style), since the ⚠ glyph
|
|
already signals severity.
|
|
|
|
## Duration format
|
|
|
|
Time spent in the **current activity state**, sourced from `activity_since`
|
|
(#102) — *not* time since spawn, and *not* time since last PTY output
|
|
(`last_activity_at`). Both clients compute it identically:
|
|
|
|
- `< 60s` → whole seconds, floored: `30s`
|
|
- `< 60m` → whole minutes, floored: `4m`
|
|
- `≥ 60m` → whole hours, floored: `2h`
|
|
|
|
No days unit, no seconds inside minutes, no rounding up. Floor everywhere so
|
|
the counter never shows a duration the state hasn't actually reached yet.
|
|
Clock granularity: re-render at least once every 30s while visible so the
|
|
cutover points land within one tick.
|
|
|
|
## Precedence
|
|
|
|
An agent-reported `ActivityState` (#105) overrides the daemon's inference for
|
|
the TTL the report carries; when the TTL expires, inference resumes. Clients
|
|
never blend the two: whichever source is in force supplies both the colour and
|
|
the clock for `activity_since`.
|
|
|
|
If a client receives an `ActivityState` variant it does not know, it must not
|
|
fail rendering: treat it as `Idle` (neutral/dim, line-2 rules apply as usual)
|
|
until the daemon sends a variant it does know. Rust clients deserialize
|
|
activity leniently for the same reason.
|