docs(web-ui/agent): add section headers, dedupe shared shape/rendering detail, trim changelog framing

This commit is contained in:
iris 2026-08-15 11:45:11 +02:00 committed by mara
commit f104d39c72

View file

@ -4,7 +4,11 @@
> [Shape (shared)](shape.md) · [Dashboard layout](dashboard.md) > [Shape (shared)](shape.md) · [Dashboard layout](dashboard.md)
Three fixed-position layers frame a full-viewport terminal: Three fixed-position layers frame a full-viewport terminal: a header,
scrollable main content, and a footer composer — plus a slide-in side
panel for flyouts and long content.
## Header
**Fixed-overlay header** (`<header class="agent-header">`): frosted **Fixed-overlay header** (`<header class="agent-header">`): frosted
glass — `backdrop-filter: blur` lets scrolled terminal rows show glass — `backdrop-filter: blur` lets scrolled terminal rows show
@ -121,8 +125,11 @@ just `name`). The frontend uses `qualified_label` to set the browser
tab title so two tabs from different hives are distinguishable; the tab title so two tabs from different hives are distinguishable; the
header `<h2 id="title">` stays short. header `<h2 id="title">` stays short.
## Main content
**Main content** (`<main class="agent-main">`): fills the viewport **Main content** (`<main class="agent-main">`): fills the viewport
and scrolls behind the fixed header + footer. and scrolls behind the fixed header + footer.
- `#status` overlay: empty when online; shows the login form / OAuth - `#status` overlay: empty when online; shows the login form / OAuth
URL when `status` is `needs_login_*`. The OAuth code input is URL when `status` is `needs_login_*`. The OAuth code input is
`type="password"` with a `👁 reveal` toggle that flips it back to `type="password"` with a `👁 reveal` toggle that flips it back to
@ -146,11 +153,15 @@ and scrolls behind the fixed header + footer.
`.agent-main` and `.terminal-wrap` both `inset: 0` fill the same `.agent-main` and `.terminal-wrap` both `inset: 0` fill the same
area. area.
## Footer / composer
**Fixed-overlay footer** (`<footer class="agent-composer">`): frosted **Fixed-overlay footer** (`<footer class="agent-composer">`): frosted
glass, symmetric with the header. Contains the operator-input glass, symmetric with the header. Contains the operator-input
textarea (`#term-input`) — multi-line, Enter sends, Shift+Enter textarea (`#term-input`) — multi-line, Enter sends, Shift+Enter
newlines, Tab-completes slash commands (see "Terminal-embedded newlines, Tab-completes slash commands (see [Terminal-embedded
prompt" below). prompt](#terminal-embedded-prompt) below).
## Side panel
**Side panel** (slide-in from right): singleton shared with the **Side panel** (slide-in from right): singleton shared with the
dashboard's side panel shape. Carries inbox and todos flyouts (opened dashboard's side panel shape. Carries inbox and todos flyouts (opened
@ -175,21 +186,12 @@ the checked ids to `POST /api/todos/mark-done`, which dismisses them
from the harness-local store (same effect as `cancel_loose_end(kind: from the harness-local store (same effect as `cancel_loose_end(kind:
"todo")`, just from the web UI instead of the agent's own tool calls). "todo")`, just from the web UI instead of the agent's own tool calls).
Older per-agent flyouts this doc used to describe (a "loose-ends" The todos flyout is the only per-agent flyout — there is no separate
list of questions/approvals/reminders backed by a since-removed "loose-ends" or "tasks" list. There is also no inline answer form for
`GET /api/loose-ends`, and a read-only "tasks" list of in-flight bash `ask` tool calls in this terminal: an `ask` renders like any other
tasks backed by a since-removed `GET /api/bash-tasks`) no longer tool call, and the operator answers a pending question from the
exist — todos superseded both. A third casualty of that migration — dashboard's Y3R C4LL tab instead (see
an "ask → operator" inline-answer form that used to mount under an [`terminal-rendering.md`](../terminal-rendering.md#inline-ask-operator-answer)).
`mcp__hyperhive__ask(to: "operator", ...)` row in the terminal
scrollback — depended on the same removed `/api/loose-ends` endpoint
and was found dead (hyperhive#2922: the binding never fired, so the
slot never mounted a form). Per mara's call on that issue, it was
removed rather than rebuilt — the main dashboard's own question
surfacing (`dashboard/src/swarm.js` + `call.js`) is the one supported
path for answering a pending question as the operator; this agent's
own terminal just shows the `ask` tool call like any other tool call,
with no inline answer affordance.
## Live view ## Live view
@ -202,17 +204,19 @@ seconds) — a flattened sibling of the event tag on both the live
SSE frame and the replayed history rows. The web UI: SSE frame and the replayed history rows. The web UI:
- fetches `GET /events/history` on page load and replays the last - fetches `GET /events/history` on page load and replays the last
2000 events (oldest first, with `.no-anim` so they don't 2000 events (oldest first);
stagger);
- then subscribes to `GET /events/stream` (SSE) for live tail; - then subscribes to `GET /events/stream` (SSE) for live tail;
- shows a granular state badge above the terminal, driven - shows a granular state badge above the terminal, driven
authoritatively from `/api/state.turn_state`. SSE turn_start / authoritatively from `/api/state.turn_state`. SSE turn_start /
turn_end still flip the badge instantly between renders; turn_end still flip the badge instantly between renders;
- sticky-bottom auto-scroll: scrolling up parks the view; new rows
surface a "↓ N new" pill instead of yanking;
- terminal-themed: phosphor mauve glow, Crust bg, - terminal-themed: phosphor mauve glow, Crust bg,
backdrop-filter blur, row fade-in slide-up. backdrop-filter blur, row fade-in slide-up.
The backfill/live-tail dedupe, sticky-bottom auto-scroll, and "↓ N
new" pill are the shared terminal-pane mechanics described in
[Shape](shape.md#shared-terminal-pane) — this page's log is one
instance of that same factory.
Per-stream rendering (see [`docs/terminal-rendering.md`](../terminal-rendering.md) for Per-stream rendering (see [`docs/terminal-rendering.md`](../terminal-rendering.md) for
the full row taxonomy and dispatch logic): the full row taxonomy and dispatch logic):
@ -323,9 +327,9 @@ shaped).
(`projects/<hash>/*.jsonl`), sessions, shell-snapshots, (`projects/<hash>/*.jsonl`), sessions, shell-snapshots,
plans, settings, telemetry, and the dir itself, so plans, settings, telemetry, and the dir itself, so
`claude --continue` keeps working after a fresh login. `claude --continue` keeps working after a fresh login.
Wholesale `remove_dir_all` of `~/.claude/` was the previous ⚠️ Deleting the whole `~/.claude/` directory instead breaks
shape and broke session continuity; the narrowed allow-list session continuity — logout must stay narrowed to just the
is the fix. credential files.
3. Flip `LoginState::NeedsLogin` + emit a `LiveEvent::Note` 3. Flip `LoginState::NeedsLogin` + emit a `LiveEvent::Note`
describing exactly what was wiped, then emit describing exactly what was wiped, then emit
`needs_login_idle`. The turn-loop's next iteration parks `needs_login_idle`. The turn-loop's next iteration parks