docs(web-ui/shape): fix stale CSS bundle count, SSE route prefix, bind-retry cap claims
Verified against frontend/packages/dashboard/build.mjs, hive-c0re/src/dashboard/mod.rs, and hive-agent/src/web_ui/mod.rs: - dashboard ships 9 page CSS bundles + colors/theme/common, not 4 - dashboard SSE routes are /api/dashboard/stream + /api/dashboard/history, not /dashboard/stream + /dashboard/history - per-agent bind_with_retry has a MAX_BIND_ATTEMPTS=12 cap (gives up), unlike the dashboard's genuinely uncapped retry loop - assets/swarm.js, assets/call.js -> swarm.js, call.js (no assets/ dir exists)
This commit is contained in:
parent
3e9f2f2fd5
commit
26b55f34d3
1 changed files with 25 additions and 19 deletions
|
|
@ -16,10 +16,14 @@
|
|||
- `GET /static/*` → bundled CSS + JS produced by esbuild
|
||||
(`frontend/packages/{dashboard,agent}/build.mjs`). Both pages
|
||||
pull the shared terminal pane + Catppuccin palette + typography
|
||||
from `@hive/shared` (was `hive-fr0nt`); the dashboard ships four
|
||||
CSS bundles (`common.css` loaded by every page, plus per-page
|
||||
`dashboard.css` / `flow.css` / `logs.css`); `common.css` inlines
|
||||
`base.css` + `terminal.css` via esbuild's `@import` resolution.
|
||||
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` / `logs.css` / `home.css` /
|
||||
`settings.css` / `stats.css` / `core.css` / `builds.css` /
|
||||
`credentials.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
|
||||
|
|
@ -42,14 +46,14 @@
|
|||
high-water mark at the moment the snapshot was assembled);
|
||||
clients use it to dedupe their buffered SSE traffic against
|
||||
the snapshot (drop frames with `seq <= snapshot.seq`).
|
||||
- `GET /dashboard/stream` (dashboard) / `GET /events/stream`
|
||||
- `GET /api/dashboard/stream` (dashboard) / `GET /events/stream`
|
||||
(per-agent) → `text/event-stream` SSE for live updates. The
|
||||
dashboard stream carries broker `Sent` / `Delivered` (mirrored
|
||||
by a forwarder task from the broker's intra-process channel)
|
||||
plus mutation events (`approval_added` / `approval_resolved`,
|
||||
`question_added` / `question_resolved`, `transient_set` /
|
||||
`transient_cleared`). Each frame carries a `seq`. The
|
||||
matching backfill endpoint is `GET /dashboard/history` (last
|
||||
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.
|
||||
|
|
@ -201,7 +205,7 @@ re-render), call `refreshState()`. State shapes live in
|
|||
`hive-c0re/src/dashboard/state_snapshot.rs::StateSnapshot` and
|
||||
`web_ui/state.rs::StateSnapshot` — when
|
||||
adding state fields, plumb through the snapshot struct and the
|
||||
relevant domain module (`assets/swarm.js`, `assets/call.js`, etc.) render function.
|
||||
relevant domain module (`swarm.js`, `call.js`, etc.) render function.
|
||||
|
||||
**Focus preservation:** `refreshState` checks whether
|
||||
`document.activeElement` sits inside one of the managed sections
|
||||
|
|
@ -277,18 +281,20 @@ previews are type-aware:
|
|||
|
||||
Both bind their TCP listener with `SO_REUSEADDR` via
|
||||
`tokio::net::TcpSocket` plus a retry loop on `AddrInUse`
|
||||
(exponential backoff capped at 2s, **no attempt cap**) so an nspawn
|
||||
restart that races the previous process's socket release resolves
|
||||
itself. The retry is uncapped on purpose: a capped budget once
|
||||
left the harness silently UI-less for the rest of its lifetime
|
||||
when a back-to-back restart held the port longer than the cap
|
||||
allowed. Genuine port collisions are preflighted host-side
|
||||
(`lifecycle::{spawn,rebuild}` refuses with a clear error,
|
||||
surfaced on the dashboard as a banner), so at this layer a
|
||||
persistent `AddrInUse` always reflects a recoverable stale
|
||||
socket — retrying forever is the safe choice. The first 12
|
||||
attempts log at WARN; after that the level drops to INFO so a
|
||||
long-held stale socket doesn't flood the journal.
|
||||
(exponential backoff capped at 2s) so an nspawn restart that races
|
||||
the previous process's socket release resolves itself, but the two
|
||||
binaries differ on the attempt budget. The dashboard's
|
||||
`bind_with_retry` (`hive-c0re/src/dashboard/mod.rs`) has **no
|
||||
attempt cap** — retrying forever is deliberate, since genuine port
|
||||
collisions are preflighted host-side (`lifecycle::{spawn,rebuild}`
|
||||
refuses with a clear error, surfaced on the dashboard as a banner),
|
||||
so at this layer a persistent `AddrInUse` always reflects a
|
||||
recoverable stale socket. Its first 12 attempts log at WARN; after
|
||||
that the level drops to INFO so a long-held stale socket doesn't
|
||||
flood the journal. The per-agent UI's `bind_with_retry`
|
||||
(`hive-agent/src/web_ui/mod.rs`) instead gives up after
|
||||
`MAX_BIND_ATTEMPTS` (12) and returns the `AddrInUse` error rather
|
||||
than looping forever.
|
||||
|
||||
The per-agent UI optionally binds a `UnixListener` instead of
|
||||
TCP when `HIVE_WEB_SOCKET` is set — the unix-socket transition
|
||||
|
|
|
|||
Loading…
Reference in a new issue