From 8dc34325708b08c56e5b1a3dcb01cf26ca1e5a71 Mon Sep 17 00:00:00 2001 From: lexis Date: Tue, 26 May 2026 01:15:42 +0200 Subject: [PATCH] docs: document agent selection bar and approval source chip (follow-up to #443 #436) --- docs/web-ui.md | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/docs/web-ui.md b/docs/web-ui.md index a54d2de9..094777b9 100644 --- a/docs/web-ui.md +++ b/docs/web-ui.md @@ -183,7 +183,8 @@ One operation runs at a time; the worker drains FIFO. Each row shows a state glyph (`⏸` queued / `▶` running / `✔` done / `✖` failed / `⊘` cancelled), kind glyph + verb (`↻ rebuild`, `◆ meta_update`, `✨ spawn`, `🗑 destroy`), agent name, source -chip (`manual | meta_update | auto_update | crash_recover`), +chip (`manual | meta_update | auto_update | crash_recover | approval` +— green for operator-approved config changes; #436), timing, and an optional reason / error. Meta-update cascade rebuilds nest under their parent entry (`parent_id` grouping; `rqe-child` CSS class). Dedup: re-enqueueing a still-queued op @@ -233,16 +234,14 @@ not `@hm1nd` (the container name). ### Container row -A full-height **square agent icon** on the left (the agent's -`/icon`, an `` absolutely positioned inside a wrapper div so -its load state can never reflow the row), and the card body on -the right with three stacked lines -(`assets/app.js::renderContainers`). The `` points straight -at `/icon`; if it actually fails to load (container stopped -or mid-transient, web server not answering) the `error` handler -falls it back to the dimmed hyperhive mark (`/favicon.svg`) -instead of an empty box — a real load-failure fallback, not a -guess from container state. +A full-height **square agent icon** (5em, capped) on the left. The +icon is the **selection toggle**: click (or Enter/Space) adds/removes +the agent from the selection set; `aria-pressed` reflects the state; +the tooltip says "select … for bulk actions" or "deselect … (or press +Esc to clear all)". The `` points at `/icon`; load failure +falls back to the dimmed hyperhive mark (`/favicon.svg`). The card +body sits to the right with three stacked lines +(`assets/app.js::renderContainers`). - Line 1: agent name (link → new tab), m1nd/ag3nt chip, an **icon-only nav strip** populated async from the agent backend @@ -285,10 +284,8 @@ guess from container state. ≥ 50% and red ≥ 75% of that window (the harness compaction watermarks). When the window can't be resolved the badge falls back to fixed 100k / 150k thresholds. (issue #66) -- Line 2: action buttons — `↻ R3BU1LD` always, `DESTR0Y` + `PURG3` - on sub-agents, `↺ R3ST4RT` + (sub-agents) `■ ST0P` when running, - `▶ ST4RT` when stopped. Buttons dim + disable while a transient - lifecycle action is in flight. +- Line 2: status badges only (no per-card action buttons — actions + moved to the **selection bar**, see below). - Line 3: drill-in triggers — - `↳ logs · ` — opens the side panel and lazy- fetches journald via `GET /api/journal/{name}?unit=&lines=` @@ -306,6 +303,26 @@ guess from container state. agent is stale. Banner pulses on each broker SSE event (`pulseBanner` with a 4s grace timer). +### Selection bar + +When one or more agents are selected (via icon click), a sticky +frosted-mauve bar slides up from the bottom of the viewport +(`#selection-bar`, `position: fixed; bottom: 0`). It shows: + +- **Count + names** — "N agents selected · name1, name2, …" +- **Bulk action buttons** — only enabled when ALL selected agents + support the action; disabled with a tooltip naming the blockers + when the selection is mixed: + - `↺ R3ST4RT` — running agents only + - `■ ST0P` — running agents only (manager included; no special-case) + - `▶ ST4RT` — stopped agents only + - `↻ R3BU1LD` — always available + - `DESTR0Y` / `PURG3` — sub-agents only (disabled if manager selected) +- **`✕ clear`** button + `Esc` key clear the entire selection. + +Stale selections (agents destroyed while selected) are pruned on +every render before the bar appears. + ### Approval card Each pending approval renders as a card (`assets/app.js::