hyperhive/frontend
Repository files (latest commit first)
Filename Latest commit message Latest commit date
iris a08aacfdf6 swarm-ui: client-local settings surface (theme + reduced-motion overrides)
Adds the settings surface + storage plumbing swarm-ui has been missing:
nowhere to put a client-local preference and no shared code for one to
build on. Scoped small per explicit direction ("small thing somewhere",
localStorage, theme and motion in scope for now) rather than a full
/settings route + nav entry for two toggles.

- frontend/packages/swarm-ui/src/lib/settings-storage.ts: generic
  useLocalSetting<T>(key, fallback) hook - read once, write through,
  stay in sync with other same-tab consumers of the same key via a
  small module-level pub/sub (localStorage's own storage event only
  fires cross-tab).
- frontend/packages/swarm-ui/src/lib/theme-apply.ts: tri-state
  system/light/dark override, applied by setting the 16 base16 custom
  properties inline on <html> (an inline style always outranks a
  stylesheet rule, including a media-query-gated one) - colors.css's
  own comment on its light-mode block already named this as the
  intended mechanism for a future override.
- frontend/packages/swarm-ui/src/lib/motion-apply.ts: tri-state
  system/reduce/allow override, applied as a data-motion attribute.
  Currently inert - swarm-ui has zero CSS animations yet - included
  because the marginal cost riding alongside the theme override is
  near zero and it was named in the same scoping answer; the first
  swarm-ui animation's own CSS is what makes this do anything.
- frontend/packages/swarm-ui/src/shell/SettingsMenu.{tsx,css}: a
  header icon-button + popover holding both selects, same shape as
  LinksMenu (manages its own state, not a ui/ primitive, hence no
  ComponentsPage demo - same exception LinksMenu already established).
- Shell.tsx/.css: mounts the two override-application hooks once
  (every route renders through one Shell), and wraps SettingsMenu +
  LinksMenu in a single .shell-header-actions flex wrapper so one
  margin-left: auto pushes both to the right edge together - two
  adjacent auto-margins on separate elements split the space between
  them instead of sitting flush.

Verified the override actually outranks the media query, not just
"looks right": seeded localStorage with each override value while
forcing the opposite OS-level prefers-color-scheme via headless
chromium, both directions render the stored override, not the forced
OS preference. Typecheck and build clean.
2026-08-18 23:58:48 +02:00
..
packages swarm-ui: client-local settings surface (theme + reduced-motion overrides) 2026-08-18 23:58:48 +02:00
.gitignore frontend: add npm workspace scaffold under frontend/ 2026-05-23 14:51:01 +02:00
npm-deps-hash nix: single-source frontend npmDepsHash into frontend/npm-deps-hash 2026-08-16 15:57:22 +02:00
package-lock.json dashboard: replace <hive-jobq-graph> with a shared Preact component 2026-08-16 15:18:25 +02:00
package.json swarm-ui: bootstrap new swarm-level frontend (Preact + wouter + TS + JSX) 2026-08-11 21:31:44 +02:00
README.md frontend: add npm workspace scaffold under frontend/ 2026-05-23 14:51:01 +02:00

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; buildNpmPackage in 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.mjs is ~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).