| Filename | Latest commit message | Latest commit date |
|---|---|---|
argus flagged + mara confirmed: operators see a brief "blink" on every poll cycle when refreshState fires. Root cause for the async-fetch sections (refreshReminders, refreshSchedules): the `await resp.json()` yield is a paint opportunity the browser can take BEFORE the renderer's `root.innerHTML = ''` + `root.append` land. The "loading…" placeholder (or the previous render's stale content) may briefly show through. Fix: render off-DOM into a `DocumentFragment`, then atomically swap into the live root with `replaceChildren`. The browser only sees the new content; no intermediate empty state is reachable. Added `paintAtomic(liveRoot, build)` helper near the top of the IIFE — minimal-churn pattern where each renderer's existing `root.append(...)` body carries over unchanged, just wrapped in a builder callback that receives the fragment as its `root` parameter. Applied to the async-fetch sections argus's note + mara's report specifically called out: - `refreshReminders` (both http-error + catch paths) - `renderReminders` - `refreshSchedules` (both error paths) - `renderScheduleNewForm` (carry read still happens against the live root BEFORE the swap so mid-typing values are preserved) - `renderSchedulesList` Kept scope tight to the async paths. The sync renderers (renderContainers / renderTombstones / etc.) run inside the same JS turn as refreshState's other sync work, so the browser can't paint between their clear+populate steps — no flash to fix there. If mara still sees blink on those sections after this lands, extending the pattern is a clean follow-up. docs/web-ui.md no change needed; this is an implementation detail of the existing managed-section render machinery. |
||
| .. | ||
| packages | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
hyperhive frontend
npm workspaces project for the hyperhive browser-facing assets:
packages/shared/— shared modules used by both surfaces (terminal pane, Catppuccin palette + body typography).packages/dashboard/— the hive-c0re dashboard SPA.packages/agent/— the per-container web UI (default agent page, stats, screen).
Build
npm install # one-off; uses the checked-in package-lock.json
npm run build # builds every workspace into packages/*/dist/
The Rust binaries serve packages/dashboard/dist/ and
packages/agent/dist/ via tower_http::ServeDir at runtime; the
build derivation is wired up in nix/modules/frontend.nix. Per-agent
additions are layered on top of the default agent dist via the
hyperhive.frontend.extraFiles option in agent.nix.
Why npm + esbuild
- Hermetic: dependencies vendored via the checked-in lockfile;
buildNpmPackagein nix uses it as the source-of-truth so the output is reproducible without network access at build time. - esbuild: vanilla-JS bundler, no framework runtime overhead.
Each workspace's
build.mjsis ~30 lines. - Single-PR migration: see issue #273 for the design proposal and the four-commit shape (npm scaffold → nix derivations → container plumbing → Rust cutover).