docs(web-ui/shape): add routes header, trim historical framing

This commit is contained in:
iris 2026-08-15 11:43:50 +02:00 committed by mara
commit 721a99ed64

View file

@ -3,6 +3,8 @@
> Part of [Web UI](../web-ui.md). See also:
> [Dashboard layout](dashboard.md) · [Per-agent page](agent.md)
## Shared routes
- `GET /``index.html` from the bundled frontend dist (see
`frontend/`). Both binaries' routers declare their dynamic
endpoints first and then `fallback_service(ServeDir::new(...))`
@ -19,8 +21,8 @@
`dashboard.css` / `flow.css` / `logs.css`); `common.css` inlines
`base.css` + `terminal.css` via esbuild's `@import` resolution.
`terminal.js` exports `{ create, linkify }` as ES module
members (no more `window.HiveTerminal` global outside the
back-compat shim the IIFE bodies still use). The dashboard's
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
this terminal — sticky-bottom auto-scroll, "↓ N new" pill,
history backfill, SSE plumbing all live there. Each page
@ -209,13 +211,11 @@ soon as they blur.
**Atomic section repaint:** every managed-section renderer goes
through `paintAtomic(liveRoot, build)`: the builder appends into
a fresh `DocumentFragment` (off-DOM) and the commit is one
`replaceChildren` call. The naive `root.innerHTML = ''; root.append(...)`
shape was visibly flashing empty on every poll cycle — on async
paths the await yield gave the browser a paint opportunity between
the clear and the re-append, and on complex builds (many `el()`
allocations) layout could escape the per-task budget even on the
synchronous path. The fragment approach keeps the intermediate
empty state invisible. Builders receive the fragment as their
`replaceChildren` call, so the intermediate empty state is never
visible — clearing and re-appending directly into the live root can
leave it empty for a paint (on async builders) or a whole frame (on
large synchronous ones), which reads as a visible flash on every
poll cycle. Builders receive the fragment as their
`root`, so existing renderer code carries over unchanged; early
returns inside the builder still commit whatever was appended
before they returned.