From b6bff2556d8682bf2b37b40508d5c81a3284dbe6 Mon Sep 17 00:00:00 2001 From: lexis Date: Fri, 29 May 2026 19:36:56 +0200 Subject: [PATCH] docs(web-ui): logout, mark-all-read, cancel-X queue, qualified_label (follow-up to #576 #559 #575 #595) --- docs/web-ui.md | 53 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/docs/web-ui.md b/docs/web-ui.md index 4cf1f829..78ea2534 100644 --- a/docs/web-ui.md +++ b/docs/web-ui.md @@ -225,6 +225,12 @@ appears under the main row showing the in-flight step name (e.g. `↳ meta prepare_deploy` → `↳ nixos-container update` → `↳ finalize deploy`). Terminal transitions clear `step` on the backend so Done / Failed rows don't render stale labels. +Queued entries carry a `✕` cancel button on the right edge +(#575); running / done / failed / cancelled entries don't show +it — the backend refuses cancellation for non-`Queued` rows +anyway (`POST /api/rebuild-queue/{id}/cancel`). Successful +cancel flips the row to `⊘ cancelled` via the next +`rebuild_queue_changed` snapshot. Cold-loaded from `/api/state.rebuild_queue`; live updates via `rebuild_queue_changed` snapshot event. @@ -493,6 +499,11 @@ not ours. rebuilds can't be safely interrupted). Always 200; body is `{"cancelled": true}` on a successful flip or `{"cancelled": false}` when the entry was not in `Queued` state. +- `POST /api/agent/{name}/mark-all-read` — ack all pending broker + messages for `{name}` (#559). Backfills `delivered_at` for rows + not yet delivered and sets `acked_at = now`. Returns + `{ "marked": N }`. Agent name validated against + `[a-z0-9_-]`, 1-63 chars; 400 on bad input. - `POST /op-send` (`to=`, `body=`) — drop an operator-authored message into ``'s inbox. `to=*` fans out to every registered agent. Returns 200; the broker @@ -681,21 +692,32 @@ through. Three flex columns (#394 redesign): click opens the loose-ends flyout. - **Overflow button** (`⋯`): always visible. Opens a frosted popover (`#overflow-menu`, positioned outside the header to escape any - stacking context) with three rows: `↑ dashboard` (link), `↻ rebuild + stacking context) with four rows: `↑ dashboard` (link), `↻ rebuild container` (POST confirm, same action as the dashboard R3BU1LD button), `↻ new claude session` (POST confirm → `POST - /api/new-session`; next turn drops `--continue`). Both destructive - actions require one extra click to acknowledge (#394 — rare ops - shouldn't live in the primary state strip). + /api/new-session`; next turn drops `--continue`), `🔓 logout` + (POST confirm → `POST /api/logout`; SIGINTs any in-flight turn, + wipes OAuth credential files, flips the agent to `needs_login` + — session history preserved). All destructive actions require + one extra click to acknowledge (#394 — rare ops shouldn't live + in the primary state strip). `/api/state` is fetched once on cold load (+ while `status === 'needs_login_in_progress'`); all other updates arrive via -SSE. Snapshot includes `context_window_tokens` for the ctx badge tooltip. +SSE. Snapshot includes `context_window_tokens` for the ctx badge +tooltip, and `qualified_label` — the hive-qualified agent name +(`name@domain` form when `HYPERHIVE_HIVE_DOMAIN` is set, otherwise +just `name`). The frontend uses `qualified_label` to set the browser +tab title so two tabs from different hives are distinguishable; the +header `

` stays short (#589 phase A). **Main content** (`
`): fills the viewport and scrolls behind the fixed header + footer. - `#status` overlay: empty when online; shows the login form / OAuth - URL when `status` is `needs_login_*`. + URL when `status` is `needs_login_*`. The OAuth code input is + `type="password"` with a `👁 reveal` toggle (#568 — avoids + accidental on-screen token exposure; `autocomplete="one-time-code"` + for password-manager suppression). - Terminal-wrap: live event tail (sticky-bottom auto-scroll + `↓ N new` pill when not at bottom). @@ -710,7 +732,15 @@ dashboard's side panel shape. Carries inbox and loose-ends flyouts (opened via the header pills) as well as long content (file previews, diffs, journald logs). Inbox flyout: last 30 messages addressed to this agent (`AgentRequest::Recent { limit: 30 }`); reply messages -indented with `↳ reply ·` in amber. Loose-ends flyout: questions, +indented with `↳ reply ·` in amber. A `✓ mark all read` button +appears in the flyout header when the inbox is non-empty (#559); +clicking it confirms then POSTs cross-origin to the core +dashboard's `POST /api/agent/{name}/mark-all-read` — all pending +messages for this agent are acked, the harness won't receive +wake-prompts for them. A `{ marked: N }` pill surfaces the count. +The displayed message list stays put (it shows the most-recent N +regardless of ack state); the unread badge on the next turn-start +will reflect zero. Loose-ends flyout: questions, approvals, and reminders pending against this agent (`GET /api/loose-ends`); question rows carry an inline answer form that POSTs cross-origin to the core dashboard's `/answer-question/{id}` so the operator answers @@ -778,6 +808,9 @@ Slash commands today: - `/new-session` — `POST /api/new-session` (confirms first). Arms a one-shot on the Bus; next turn runs without `--continue`, dropping the resume session entirely. +- `/logout` — `POST /api/logout` (confirms first). Wipes OAuth + credential files, parks the agent in `needs_login`. Session + history (`~/.claude/projects/`) is preserved. Unknown `/foo` shows an error row instead of being silently sent. @@ -805,6 +838,12 @@ shaped). future turns. `Bus::set_model` emits `ModelChanged`. - `POST /api/new-session` — arm a one-shot for the next turn to drop `--continue`. Emits a `LiveEvent::Note`. +- `POST /api/logout` — SIGINT any in-flight turn, wipe OAuth + credential files (`.credentials.json` + `mcp-needs-auth-cache.json` + under `~/.claude/`), flip `LoginState::NeedsLogin`. Session + history (`~/.claude/projects/`) is preserved. Returns 200 with a + plain-text wipe summary. Emits `needs_login_idle` status via + `wait_for_login` entry. - `GET /events/history` — replay buffer for the terminal. - `GET /screen` — VNC viewer page (minimal RFB-over-WebSocket renderer). Only accessible when `hyperhive.gui.enable = true`