feat(maestro): clear AwaitingInput glow once a pane has been focused

A session's rail glows AwaitingInput even after the operator has already
looked at it. Clients now report pane focus (POST /:id/focus); the daemon
clears the glow to Idle after 5s of continuous focus and keeps it cleared
until the session does new work, so a fresh Active cycle is required to
glow again.
This commit is contained in:
Miguel Palhas
2026-09-02 18:03:26 +01:00
parent 63191c7be1
commit f7e7a77912
12 changed files with 465 additions and 2 deletions
+26
View File
@@ -211,6 +211,32 @@ arriving at `POST /api/sessions/:id/activity` is parsed strictly and an unknown
state is a 4xx: an agent posting a state the daemon does not know is a bug in
the agent, and answering 204 would hide it.
## Focus clears `AwaitingInput`
A session's pane — the pane a client's own attach view is showing, never a
sidebar highlight — clears its `AwaitingInput` glow once it has been
**continuously focused for 5 seconds**: the operator has looked, so the rail
stops asking for attention and the card reads as `Idle` instead. This is a
real state change, not a client-side paint-over — the daemon computes it, so
every client watching the session (web, TUI, a second pane on the same
session) sees the same colour.
The acknowledgement is sticky: it survives losing focus, and holds until the
session is genuinely `Active` again — new work, not merely a refocus. Only
after that fresh `Active` cycle does the *next* `AwaitingInput` glow again.
Unfocusing and refocusing alone never re-arms it.
This applies uniformly to `AwaitingInput` from either source — the daemon's
own inference or an agent's report (#105) — since the rail draws them
identically. It does not touch `Error`; that state's own TTL (below) is
unrelated and unaffected by focus.
Each client reports its own pane's focus with `POST /api/sessions/:id/focus`
(`{"focused": bool}`) whenever the pane it is showing changes — on attach, on
switching which session a pane shows, and on leaving the pane. A client
sends `false` for the session it just left before `true` for the session it
lands on, so a click that swaps panes never briefly reports both focused.
## Keyboard walk
`j`/`k` (and the arrow keys) move a highlight through the sidebar. Both clients