docs: SPA pattern noted, todo cleared; harness-base git config mkDefault

programs.git.config.user.{name,email} in harness-base.nix now mkDefault
so the per-agent applied flake's override merges without mkForce.
This commit is contained in:
müde 2026-05-15 17:17:48 +02:00
parent 124fd97288
commit 070b237d03
3 changed files with 35 additions and 19 deletions

View file

@ -21,8 +21,8 @@ hive-c0re/ host daemon + CLI (one binary, subcommand-dispatched)
src/actions.rs approve/deny/destroy
src/auto_update.rs startup rebuild scan + ensure_manager
src/lifecycle.rs `nixos-container` shellouts, per-agent flake generator
src/dashboard.rs axum HTTP UI: containers, approvals, async-form actions
assets/ CSS + JS shipped via include_str!
src/dashboard.rs axum HTTP: static shell + /api/state JSON + actions
assets/ index.html, dashboard.css, app.js (include_str!)
hive-ag3nt/ in-container harness crate; produces TWO binaries
src/lib.rs re-exports + DEFAULT_SOCKET, DEFAULT_WEB_PORT
@ -120,6 +120,32 @@ nix/
marks them `failed` with note `"agent state dir missing"` so they fall out
of `pending`. They stay in sqlite for audit.
## Web UI shape
Both the dashboard (port 7000) and the per-agent web UIs (8000 /
8100-8999) are SPAs with the same skeleton:
- `GET /` → static `assets/index.html` (placeholders for state-driven
sections).
- `GET /static/*.css` + `GET /static/*.js` → static assets shipped via
`include_str!` so there's no runtime file dependency.
- `GET /api/state` → JSON snapshot the JS app renders into the DOM.
- `POST /<action>` (approve, deny, kill, restart, rebuild, destroy,
request-spawn, update-all, send, login/*) → idempotent action endpoints.
- `GET /events/stream` (per-agent) and `GET /messages/stream` (dashboard)
are `text/event-stream` SSE for live updates.
The JS app handles all `form[data-async]` submissions via a delegated
listener: read `data-confirm`, swap the button to a spinner, POST
`application/x-www-form-urlencoded` (axum's `Form` extractor rejects
multipart), then on success call `refreshState()` (re-fetch `/api/state`
and re-render). No full-page reloads.
Per-agent + dashboard state shapes live in `dashboard.rs::StateSnapshot`
and `web_ui.rs::StateSnapshot`. When adding new state fields, plumb
through the snapshot struct and the relevant `assets/app.js` render
function — never reach for server-side HTML rendering again.
## Agent MCP surface + turn loop
The harness ships an embedded MCP server (rmcp 1.7) that claude launches as

View file

@ -30,15 +30,6 @@ Pick anything from here when relevant. Cross-cutting design notes live in
only see them by watching the live panel of the agent that sent them.
- **Per-agent UI substance.** Show last N inbox messages, last turn timing,
link back to dashboard.
- **Static-asset SPA-style web UI.** Move toward: `index.html` is static,
CSS/JS is static, all dynamic state is fetched over SSE / JSON endpoints.
Currently the index HTML is server-rendered with state-dependent
fragments inlined; the live event stream + async forms are already SSE /
fetch. Goal is a cleaner split so the UI is one HTML file + JS app +
small JSON API.
- **Background JS refresh on the live panel.** Already there for sends;
any remaining places that reload the whole page should switch to fetch +
partial updates.
- **xterm.js terminal** embedded per-agent, attached to a PTY exposed by
the harness. Pairs well with the unprivileged-container work — would let
the operator drop into the container without `nixos-container root-login`.

View file

@ -1,4 +1,4 @@
{ pkgs, ... }:
{ pkgs, lib, ... }:
{
# Shared scaffolding for any hyperhive harness container — both
# sub-agents (`agent-base.nix`) and the manager (`manager.nix`) extend
@ -18,18 +18,17 @@
# Git is needed by claude's Bash tool (for the agent <-> manager config
# request flow) and by hive-c0re's own setup_applied / setup_proposed.
# `programs.git.enable` installs the binary + manages `/etc/gitconfig`
# declaratively so the inline module in `applied/<name>/flake.nix` can
# override `user.name` / `user.email` per agent without fighting a raw
# `environment.etc."gitconfig"` block.
# The per-agent `applied/<name>/flake.nix` overrides `user.name` and
# `user.email` with the agent's identity — values here are `mkDefault`
# so the per-agent override wins without needing `mkForce`.
programs.git = {
enable = true;
config = {
user = {
name = "hyperhive";
email = "hyperhive@local";
name = lib.mkDefault "hyperhive";
email = lib.mkDefault "hyperhive@local";
};
init.defaultBranch = "main";
init.defaultBranch = lib.mkDefault "main";
};
};