dashboard: remove the flow page and the endpoints only it used
The flow page showed the raw broker message stream and had a compose box. This removes the page and its bundle, its link in the pages menu, and the styles only it used. The history endpoint that backfilled it and the operator-send endpoint behind the compose box had no other caller, so they go too, along with the broker query behind the history endpoint. The stream endpoint stays: the dashboard tabs still subscribe to it. The docs lose the FL0W section and the references to the two endpoints.
This commit is contained in:
parent
acf82beba3
commit
fa131b46a6
24 changed files with 62 additions and 1121 deletions
|
|
@ -12,7 +12,7 @@ what you actually do here.
|
|||
|
||||
Everything starts at the **dashboard**, served at `/`. A pages menu
|
||||
(the `☰` button at the left of the tab strip) links to the other
|
||||
surfaces — Flow, Stats, the API docs and the swarm UI — and each of
|
||||
surfaces — Stats, the API docs and the swarm UI — and each of
|
||||
those pages links back to the dashboard.
|
||||
|
||||
The dashboard is where you'll spend most of your time. It's a single
|
||||
|
|
@ -26,9 +26,8 @@ page with five tabs:
|
|||
- **K3PT ST4T3** — kept state from agents with no container
|
||||
(tombstones), with a purge button per entry.
|
||||
|
||||
Two things live on their own page instead, reached from the pages
|
||||
menu: **Flow** (`/flow.html`, the raw live message stream across the
|
||||
whole swarm) and **Stats** (`/stats.html`, swarm-wide usage stats).
|
||||
Usage stats live on their own page, reached from the pages menu:
|
||||
**Stats** (`/stats.html`, swarm-wide usage stats).
|
||||
|
||||
Each agent also has its own page — a full terminal view of that
|
||||
agent's session, reachable by selecting its name anywhere in the
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ swap touches only the first:
|
|||
what the app references and it **never changes on a swap**.
|
||||
|
||||
Both files live in `frontend/packages/shared/src/`. Per-page stylesheets
|
||||
(`common.css`, `dashboard.css`, `flow.css`, `agent.css`)
|
||||
(`common.css`, `dashboard.css`, `agent.css`)
|
||||
reference the **semantic** names and must **not** redeclare them or reach
|
||||
for the raw `--baseNN` slots directly. (`base.css` holds only the shared
|
||||
`body` typography — it references the palette but no longer defines it.)
|
||||
|
|
|
|||
|
|
@ -12,21 +12,21 @@ hive-c0re serves the dashboard at `/`.
|
|||
It has a fixed chrome header at the top and a `<main>` that shows exactly
|
||||
one tab pane at a time. The URL hash (`#agents`, `#rebuild`, `#meta`,
|
||||
`#buildlogs`, `#kept`) drives which pane is
|
||||
active; hash changes don't reload the page. FL0W and ST4TS
|
||||
are standalone pages reached from the pages menu, not from the
|
||||
active; hash changes don't reload the page. ST4TS
|
||||
is a standalone page reached from the pages menu, not from the
|
||||
dashboard tab strip.
|
||||
|
||||
**Chrome header** (fixed, overlays the active tab pane):
|
||||
- **Pages menu**: a `☰` button at the left of the chrome (`links-menu.js`)
|
||||
opening a popover with links to **flow** (`/flow.html`), **stats**
|
||||
opening a popover with links to **stats**
|
||||
(`/stats.html`), **api docs** (`/api/docs/`) and **swarm** (the swarm
|
||||
UI at the swarm apex domain, opened in a new tab). The swarm entry
|
||||
comes from `state.swarm_public_url`, which hive-c0re reads from
|
||||
`HIVE_SWARM_PUBLIC_URL` (set from `services.hyperhive.swarm.domain`);
|
||||
with no domain set there is no swarm entry. The standalone pages link back to `/`.
|
||||
- **Tab strip**: `◆ 4G3NTS ◆`, `◆ R3BU1LD QU3U3 ◆`, `◆ M3T4 1NPUTS ◆`,
|
||||
`◆ BUILD L0GS ◆`, `◆ K3PT ST4T3 ◆`. In-page tabs only — FL0W / ST4TS
|
||||
live on their own pages, reached from the pages menu. Count pills on
|
||||
`◆ BUILD L0GS ◆`, `◆ K3PT ST4T3 ◆`. In-page tabs only — ST4TS
|
||||
lives on its own page, reached from the pages menu. Count pills on
|
||||
4G3NTS (stale containers), R3BU1LD QU3U3 (rebuilds in flight) and
|
||||
K3PT ST4T3 (kept-state entries).
|
||||
- **Banner-thin** (`░▒▓█▓▒░ HYPERHIVE / HIVE-C0RE / WE ARE THE WIRED ░▒▓█▓▒░`)
|
||||
|
|
@ -46,10 +46,6 @@ dashboard tab strip.
|
|||
to `<swarm> / <hive> // h1ve-c0re` once `hive_name` / `swarm_name`
|
||||
arrive in the state snapshot.
|
||||
|
||||
The FL0W page uses a slim header (a `← dashboard` back-link + the page
|
||||
title) rather than the dashboard tab strip — it's a standalone surface,
|
||||
not a tab pane.
|
||||
|
||||
## 4G3NTS tab
|
||||
|
||||
**C0NTAINERS** — live containers as a flat list, one row per
|
||||
|
|
@ -212,7 +208,7 @@ entry with that id pre-expanded.
|
|||
Hive-wide turn statistics, aggregated across every agent's
|
||||
`hyperhive-turn-stats.sqlite` for the selected window. Not a dashboard
|
||||
tab — a standalone page reached from the dashboard's pages menu,
|
||||
same minimal chrome as `/flow.html`. Distinct from
|
||||
minimal chrome (a back-link and a title). Distinct from
|
||||
each agent's own `/stats` page (which carries the per-agent trend
|
||||
charts): ST4TS is the swarm-level rollup.
|
||||
|
||||
|
|
@ -249,42 +245,6 @@ the model id, longest match wins) mapping to
|
|||
`{ input, output, cache_read, cache_write }` USD-per-million-token
|
||||
prices. Models not covered fall back to hive-c0re's built-in estimate.
|
||||
|
||||
## FL0W page (`/flow.html`)
|
||||
|
||||
A dedicated full-page terminal (not a tab pane — a separate HTML
|
||||
page). Slim chrome: a `← dashboard` back-link, the FL0W
|
||||
title, and the agent-filter select (see below). No dashboard tab
|
||||
strip — FL0W is a standalone surface reached from the pages menu.
|
||||
|
||||
**MESS4GE FL0W** — live broker tail wrapped in a `.terminal-wrap`.
|
||||
Cold load backfills the last ~200 messages from `/api/dashboard/history`;
|
||||
live frames arrive on `/api/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 page upgrades the row 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 long timestamps and agent names never push the
|
||||
body into a narrow trailing column. `min-width: 0` keeps
|
||||
`word-break: break-word` effective so the body doesn't force the row wider
|
||||
than its container. Sticky-bottom autoscroll + "↓ N new" pill. Below the
|
||||
stream sits a terminal-style compose box: `@name` picks the recipient
|
||||
(sticky via localStorage; autocomplete from the live container list,
|
||||
Tab/Enter to confirm; `@*` broadcasts). `POST /api/op-send` drops
|
||||
`{from:"operator", to, body}` into the broker; the resulting SSE frame
|
||||
re-renders the terminal row. The operator addresses the root agent as `@root`.
|
||||
|
||||
## Container row
|
||||
|
||||
A full-height **square agent icon** (5em, capped) on the left. The
|
||||
|
|
@ -577,11 +537,6 @@ below — some endpoints aren't in it yet.
|
|||
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 /api/op-send` (`to=<name>`, `body=<text>`) — drop an
|
||||
operator-authored message into `<name>`'s inbox. `to=*` fans
|
||||
out to every registered agent. Returns 200; the broker
|
||||
`Sent` event re-renders the message-flow terminal without a
|
||||
snapshot refetch. Used by the compose textbox under MESS4GE FL0W.
|
||||
- `GET /api/build-logs/{agent}?limit=N` — most-recent build log
|
||||
headers for one agent, newest first. Returns
|
||||
`Vec<BuildLogHeader>` (JSON): `id`, `agent`, `kind`, `cmdline`,
|
||||
|
|
@ -621,8 +576,7 @@ below — some endpoints aren't in it yet.
|
|||
The client trusts that list and linkifies only those tokens,
|
||||
so directories, missing files, and forbidden subtrees never
|
||||
become anchors. No probe endpoint, no client-side regex
|
||||
heuristics. Historical messages get the same treatment on
|
||||
`/api/dashboard/history` backfill.
|
||||
heuristics.
|
||||
- `GET /api/reminders` — list pending reminders for the
|
||||
dashboard's queued-reminders panel.
|
||||
- `GET /api/stats-hive?window=<1h|4h|24h|3d|7d|30d|all>` — hive-wide
|
||||
|
|
@ -639,9 +593,6 @@ below — some endpoints aren't in it yet.
|
|||
- `GET /api/dashboard/stream` — unified live event channel:
|
||||
broker `sent` / `delivered`, plus the mutation events listed
|
||||
below. Each frame carries `seq`.
|
||||
- `GET /api/dashboard/history` — last ~200 broker messages
|
||||
(wrapped as `{ seq, events }`) for the message-flow
|
||||
terminal's backfill on page load.
|
||||
<!-- vale write-good.Passive = YES -->
|
||||
|
||||
## Dashboard event channel
|
||||
|
|
@ -652,9 +603,7 @@ payload):
|
|||
- `sent` / `delivered` — broker traffic, mirrored from the
|
||||
intra-process channel by a forwarder task. Both carry `id: i64`
|
||||
(the broker row id) and `in_reply_to: Option<i64>` for thread
|
||||
rendering. The dashboard message-flow terminal renders reply
|
||||
rows with a `↳ reply` tag that scroll-highlights the parent
|
||||
row on selection. Used by the message-flow terminal renderer.
|
||||
rendering.
|
||||
- `transient_set` (name, transient_kind, since_unix) /
|
||||
`transient_cleared` (name) — lifecycle action spinners. The
|
||||
client ticks the elapsed-seconds badge off `since_unix`
|
||||
|
|
@ -696,7 +645,7 @@ payload):
|
|||
forms that mutate non-event-derived state** (PURG3 +
|
||||
meta-update, since tombstones + meta_inputs aren't event-
|
||||
shaped yet). Every other section — transients,
|
||||
containers, message flow —
|
||||
containers —
|
||||
derives from `/api/dashboard/stream` after the initial snapshot,
|
||||
maintaining its own client-side store and applying events on
|
||||
top.
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@
|
|||
from `@hive/shared` (was `hive-fr0nt`); the dashboard ships one
|
||||
CSS bundle per page (`colors.css` + `theme.css` + `common.css`,
|
||||
loaded by every page, plus a page-specific bundle —
|
||||
`dashboard.css` / `flow.css` /
|
||||
`dashboard.css` /
|
||||
`stats.css`);
|
||||
`common.css` inlines `@hive/shared`'s
|
||||
`base.css` + `terminal.css` + `tabs.css` + `chrome.css` +
|
||||
`pill.css` via esbuild's `@import` resolution.
|
||||
`terminal.js` exports `{ create, linkify }` as ES module
|
||||
members; a back-compat shim in the IIFE bodies still exposes
|
||||
a `window.HiveTerminal` global for callers that need it. The dashboard's
|
||||
`#msgflow` and the per-agent `#live` log are both backed by
|
||||
a `window.HiveTerminal` global for callers that need it. The
|
||||
per-agent `#live` log is backed by
|
||||
this terminal — sticky-bottom autoscroll, "↓ N new" pill,
|
||||
history backfill, SSE plumbing all live there. Each page
|
||||
registers a kind→renderer map; unknown kinds fall through to
|
||||
|
|
@ -51,10 +51,8 @@
|
|||
dashboard stream carries broker `Sent` / `Delivered` (mirrored
|
||||
by a forwarder task from the broker's intra-process channel)
|
||||
plus mutation events (`transient_set` / `transient_cleared`). Each frame carries a `seq`. The
|
||||
matching backfill endpoint is `GET /api/dashboard/history` (last
|
||||
~200 broker messages wrapped in `{ seq, events }`) on the
|
||||
dashboard and `GET /events/history` (last 2000 `LiveEvent`s
|
||||
also wrapped in `{ seq, events }`) on the agent.
|
||||
agent's matching backfill endpoint is `GET /events/history` (last 2000
|
||||
`LiveEvent`s wrapped in `{ seq, events }`).
|
||||
**One unified channel**: browsers cap concurrent SSE
|
||||
connections per origin (~6 in Chrome). Using one channel per
|
||||
domain would exhaust this budget on a live hive; dispatching
|
||||
|
|
@ -87,9 +85,8 @@
|
|||
|
||||
## Shared terminal pane
|
||||
|
||||
The shared terminal factory in `@hive/shared/terminal.js` backs both
|
||||
surfaces' scrollable log streams (`#msgflow` on the dashboard, `#live`
|
||||
on the per-agent page). The factory wires up
|
||||
The shared terminal factory in `@hive/shared/terminal.js` backs the
|
||||
per-agent page's scrollable log stream (`#live`). The factory wires up
|
||||
sticky-bottom autoscroll, a "↓ N new" pill, history backfill, and
|
||||
SSE replay. Pages register a `kind → renderer` map; unknown kinds
|
||||
fall through to a JSON-dump note row. The factory ships three row
|
||||
|
|
|
|||
|
|
@ -69,7 +69,3 @@ read that when you need the specifics, this doc doesn't duplicate it.
|
|||
`marked.parse()` through DOMPurify into a `<div class="md">`. Applied to
|
||||
any `TermMsg` with `body_format: "markdown"`.
|
||||
|
||||
## Dashboard side (not covered here)
|
||||
|
||||
The main dashboard's message-flow pane is a different shape: broker
|
||||
messages render as `.msgrow` grid lines, not agent-terminal rows.
|
||||
|
|
|
|||
Loading…
Reference in a new issue