diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index 5989ec03..1d19c2c3 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -4,13 +4,13 @@ > [Shape (shared)](shape.md) · [Per-agent page](agent.md) -The dashboard is served at `/dashboard.html` (with the home page at `/`). -It has a fixed chrome header at the top and a `
` that shows exactly -one tab pane at a time. The URL hash (`#swarm`, `#call`, `#system`, -`#permissions`, `#schedules`, `#peers`, `#settings`) drives which pane is -active; hash changes don't reload the page. FL0W is a separate full-page -terminal at `/flow.html` — its tab-strip entry is a cross-page link -(`◆ FL0W ◆ →`), not a pane swap. +The dashboard (`/`) has a fixed chrome header at the top and a +`
` that shows exactly one tab pane at a time. The URL hash +(`#swarm`, `#call`, `#system`, `#permissions`, `#schedules`, `#peers`, `#settings`) +drives which pane is active; hash changes don't reload the page. +FL0W is a separate full-page terminal at `/flow.html` — its +tab-strip entry is a cross-page link (`◆ FL0W ◆ →`), not a pane +swap. **Chrome header** (fixed, overlays the active tab pane): - **Tab strip**: `◆ SW4RM ◆`, `◆ Y3R C4LL ◆`, `◆ SYST3M ◆`, @@ -100,17 +100,6 @@ operator, with amber pulsing border. Anatomy of each card: - **◆ answ3red (N)** — collapsible `
` below the pending list; shows the last 20 resolved questions with their answers. -**0PER4T0R 1NB0X** — messages agents have sent to `to="operator"` but -the operator hasn't read yet. Cold-loaded from `/api/operator-inbox` on -tab activation + page load; appended live from the broker `sent` stream -(deduped on row id). Each row shows sender · timestamp · body (with -file-path linkification). A `✓ mark all read` button on the right acks -all rows via `POST /api/agent/operator/mark-all-read` (reuses the existing -mark-read endpoint). Unread count folds into the Y3R C4LL tab pill so -messages are visible from any tab even while inactive. Backed by -`GET /api/operator-inbox` → `{ messages: [...] }` (id, from, body, at, -in_reply_to, file_refs). - ## SYST3M tab Passive / rare-interaction state. @@ -433,45 +422,20 @@ mark-all read). FL0W stays the pure event firehose. **MESS4GE FL0W** — live broker tail wrapped in a `.terminal-wrap`. Cold load backfills the last ~200 messages from `/dashboard/history`; live frames arrive on `/dashboard/stream`. Each row is one broker -event — `sent` or `delivered` — with `from → to: body`. When a `sent` -and `delivered` event for the same message arrive within 3 seconds -(immediate delivery to a live recipient), the row is upgraded in place -(arrow becomes green ✓, title reads "sent + delivered") instead of -rendering two near-identical lines — genuine delivery latency (recipient -was busy) still appears as a second row. Each row carries `data-from` / -`data-to` attributes; an **agent filter select in the FL0W header** narrows -the timeline to messages involving the chosen agent (matched on `from` OR -`to`), with non-matching rows hidden (`.flow-hidden` class). The selection -persists in localStorage across reloads; new rows pick up the active filter -at render time. The dropdown populates from the live container list and -stays current on add/remove; a saved selection survives even if that agent -isn't currently listed. - -The row is a `flex-wrap: wrap` container holding ts / arrow / from / sep -/ to chips inline; the **body wraps to its own full-width line below** the -chips (`flex: 1 1 100%`) so the body always gets the full row width down to -the content edge — long timestamps + agent names used to push the body ~30ch -in and force awkward narrow-column wraps. `min-width: 0` keeps -`word-break: break-word` effective so the body doesn't force the row wider -than its container. Sticky-bottom auto-scroll + "↓ N new" pill. Below the -stream sits a terminal-style compose box: `@name` picks the recipient -(sticky via localStorage; auto-complete from the live container list, -Tab/Enter to confirm; `@*` broadcasts). `POST /op-send` drops -`{from:"operator", to, body}` into the broker; the resulting SSE frame -re-renders the terminal row. Manager is addressed as `@root`. - -## Home page (`/`, `/home.html`) - -The H0M3 hub is the primary landing page (served at `/` by default). A -responsive grid of link tiles — Dashboard, Flow, Logs, Matrix (when enabled) -— each pointing to their respective surfaces. The page is a pure portal with -no tab-bar or SSE subscriptions. Typography + colours inherit from the shared -theme (Catppuccin Mocha via `common.css` + `theme.css`). The Matrix tile is -hidden until `home.js` confirms `matrix_gui_enabled` (same gating as the -dashboard's M4TR1X tab); `home.js` also fills the swarm/hive identity line -at the top. Dashboard is now served at `/dashboard.html` (route swap completed -in #1464 step 2); the home page at `/` replaces the old dashboard root. All -dashboard sub-pages include a `← Home` back-link for navigation. +event — `sent` or `delivered` — with `from → to: body`. The row is +a `flex-wrap: wrap` container holding ts / arrow / from / sep / to +chips inline; the **body wraps to its own full-width line below** +the chips (`flex: 1 1 100%`) so the body always gets the full row +width down to the content edge — long timestamps + agent names +used to push the body ~30ch in and force awkward narrow-column +wraps. `min-width: 0` keeps `word-break: break-word` effective so +the body doesn't force the row wider than its container. Sticky- +bottom auto-scroll + "↓ N new" pill. Below the stream sits a +terminal-style compose box: `@name` picks the recipient (sticky via +localStorage; auto-complete from the live container list, Tab/Enter +to confirm; `@*` broadcasts). `POST /op-send` drops +`{from:"operator", to, body}` into the broker; the resulting SSE +frame re-renders the terminal row. Manager is addressed as `@root`. ## L0GS page (`/logs.html`) @@ -835,13 +799,6 @@ that's a browser-level decision, not ours. 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. -- `GET /api/operator-inbox` — list unread messages addressed to - `to="operator"` (broker rows with `acked_at = NULL`). Cold-loaded - for the Y3R C4LL tab's ◆ 1NB0X ◆ section on page load + tab activation; - live updates fed from the broker `sent` stream. Returns - `{ messages: [{ id, from, body, at, in_reply_to, file_refs }, …] }`, - newest-first. Reuses `/api/agent/operator/mark-all-read` to ack (filters - are identical so every listed row is exactly what mark-read clears). - `POST /op-send` (`to=`, `body=`) — drop an operator-authored message into ``'s inbox. `to=*` fans out to every registered agent. Returns 200; the broker