Operator brief (#394): the header had thirteen distinct visual elements in one flex row with three different border-radius languages, four colour treatments, three label styles. Mara's direction: - agent icon bigger (full header height) as the identity anchor - title glow stays - nav links lose their default-anchor underline - overflow `⋯` absorbs `↻ R3BU1LD` + `↻ new session` (rare, destructive — both worth one extra click; rebuild is normally done from the dashboard) - accent stacking in the state strip stays — that's the vibe ## Layout shape Three flex columns in `.agent-header`: [icon · full height] [main column · 2 rows] [pills + ⋯] The main column carries row 1 (`◆ AGENT ◆` title + meta-nav) on top and row 2 (alive · state · model · ctx · cost · last-turn · cancel-turn) below. ## Changes ### `index.html` - Wrap title + nav in `.agent-header-row .agent-header-title-row`; wrap state-row siblings in `.agent-header-row .agent-state-row`; both go inside a new `.agent-header-main` column. - Right cluster `.agent-header-pills` contains the inbox + loose pills + a new `<button id="overflow-btn">⋯</button>` trigger. - Drop static `#new-session-btn` from `#state-row` — moved into the overflow menu, populated dynamically. - Add `<div id="overflow-menu" role="menu" hidden>` as a sibling of `<header>` (lives outside the header so its `position: fixed` popover isn't trapped by any header stacking context). ### `agent.css` - `--agent-header-h: 4.6em → 6em` so the icon can be square + full height without crowding the two-row main column. Terminal padding-top + status overlay top + tail-pill all derive from this variable, so they follow automatically. - `.agent-header { align-items: stretch }` lets the icon stretch to full height; `.agent-icon { height: 100%; aspect-ratio: 1 }` sizes it as a square off the stretched height. - `.agent-nav-link` rule added — `text-decoration: none`, cyan + soft glow, hover lights brighter (mara's spec). - `.overflow-btn` (round trigger) + `.overflow-menu` (frosted popover, fixed-position) + `.overflow-item` (rows with an icon column + label, hover ink matches per-action accent — cyan for dashboard, amber for rebuild/new-session). - Remove the old `#state-row` selector (layout now provided by `.agent-state-row` + `.agent-header-row`). ### `app.js` - `setHeader` no longer appends DASHB04RD / R3BU1LD chips into the title — title is just the identity glyph now. Both actions get rendered into the overflow menu by `populateOverflowMenu()`. - `populateOverflowMenu(label, dashUrl)` builds three rows: `↑ dashboard` (anchor), `↻ rebuild container` (button — same POST-form action as before), `↻ new claude session` (button — same `/api/new-session` call as the legacy header button). - Overflow toggle / outside-click / Escape dismissal — same pattern as the side-panel flyout (`Panel`). - Drop the static `new-session-btn` IIFE binder; the dynamically- rendered menu item owns its handler now. - Drop the per-nav-link inline `marginLeft` (layout gap comes from the new `.agent-nav { gap }` rule). ## Validation - `npm run build` clean. - Build deltas: agent.css 21.0kb → 23.6kb (overflow + nav rules + comments), app.js 117.4kb → 118.9kb (menu builder + toggle). - Browser smoke test isn't possible from inside iris's container. Worth eyeballing post-deploy: - Icon fills the full header height as a square - Title glow + uppercase styling preserved - Nav links render without underline; hover lights brighter - `⋯` opens a frosted popover with `↑ dashboard`, `↻ rebuild container`, `↻ new claude session` - Rebuild confirm + POST works the same as the legacy chip - New-session confirm + POST works the same as the legacy button - State strip still wraps when crowded (model/ctx/cost multi-line on narrow viewports) - Cancel-turn button still appears while thinking and clears on turn end - Terminal padding-top adjusts to the new 6em header height (no row hidden under the chrome) |
||
|---|---|---|
| .. | ||
| 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).