docs: refresh for the dashboard rework + recent harness commits
- web-ui.md: side panel, approval card + 3-way diff base, stats page, forge config links, removed agent.nix viewer, per-agent loose-ends inline answer. - approvals.md: forge mirror section + diff base toggle. - turn-loop.md: recv(max), get_logs, remind, loose-ends, whoami. - agent.md / manager.md prompts: recv(max), remind, get_logs. - CLAUDE.md: forge.rs / stats.rs / hive-forge.nix in the file map, scratchpad refresh. also: forgejo migrations.ALLOW_LOCALNETWORKS = true so an in-hive mirror of the hyperhive repo can import from a localhost source.
This commit is contained in:
parent
94781ccd08
commit
6ab3810e18
7 changed files with 205 additions and 36 deletions
108
docs/web-ui.md
108
docs/web-ui.md
|
|
@ -54,12 +54,21 @@ soon as they blur.
|
|||
**`<details>` open-state preservation:** any collapsible element
|
||||
tagged with `data-restore-key="<stable-key>"` survives the
|
||||
refresh. `snapshotOpenDetails()` walks managed sections before
|
||||
render, `restoreOpenDetails()` re-applies after. Used today for
|
||||
the journald viewer (`journal:<container>`), the agent-config
|
||||
viewer (`agent-config:<name>`), and approval diff blocks
|
||||
(`approval-diff:<id>`). Setting `.open = true` programmatically
|
||||
also fires the `toggle` event, so any lazy-fetch wired to it
|
||||
re-runs cleanly on restore.
|
||||
render, `restoreOpenDetails()` re-applies after. Long-content
|
||||
drill-ins (file previews, diffs, journald logs) now open in the
|
||||
**side panel** (see below) rather than expanding inline, so the
|
||||
only restore-keyed `<details>` left is the answered-questions
|
||||
history list.
|
||||
|
||||
**Side panel (dashboard):** long content opens in a drawer that
|
||||
swipes in from the right — a singleton `#side-panel` with a
|
||||
titled header, a close button, and a scrollable body. Closes on
|
||||
the button, a backdrop click, or `Escape`. `Panel.open(title,
|
||||
node)` swaps the body; the JS builders for file previews,
|
||||
approval diffs, and journald logs all render into it. Markdown
|
||||
file previews (`.md` / `.markdown`) render through the vendored
|
||||
`marked` bundle (`GET /static/marked.js`) into a `.md` block;
|
||||
other files stay raw in a `<pre>`.
|
||||
|
||||
Both bind their listeners with `SO_REUSEADDR` via
|
||||
`tokio::net::TcpSocket` plus a retry loop on `AddrInUse` (12 tries,
|
||||
|
|
@ -136,21 +145,50 @@ Two-line layout (`assets/app.js::renderContainers`):
|
|||
on sub-agents, `↺ R3ST4RT` + (sub-agents) `■ ST0P` when running,
|
||||
`▶ ST4RT` when stopped. Buttons dim + disable while a transient
|
||||
lifecycle action is in flight.
|
||||
- Plus two collapsible `<details>` blocks:
|
||||
- `↳ logs · <container>` — lazy-fetches journald output via
|
||||
`GET /api/journal/{name}?unit=...&lines=...` (`journalctl -M
|
||||
<container> -b --no-pager --output=short-iso`). A unit
|
||||
dropdown switches between the harness service (default) and
|
||||
the full machine journal; refresh button re-fetches.
|
||||
- `↳ agent.nix · <name>` — lazy-fetches the applied config
|
||||
file via `GET /api/agent-config/{name}` (read-only mirror of
|
||||
`/var/lib/hyperhive/applied/<name>/agent.nix`). Mutating
|
||||
this still requires `request_apply_commit` + approval.
|
||||
- Line 3: drill-in triggers —
|
||||
- `↳ logs · <container>` — opens the side panel and lazy-
|
||||
fetches journald via `GET /api/journal/{name}?unit=&lines=`
|
||||
(`journalctl -M <container> -b --no-pager --output=short-iso`).
|
||||
A unit dropdown (harness service / full machine journal) and
|
||||
a refresh button live in the panel.
|
||||
- `↳ config repo ↗` — link to the agent's applied config repo
|
||||
on the bundled forge (`agent-configs/<name>`), opened in a
|
||||
new tab. Shown only when `forge_present`. Replaces the old
|
||||
one-file `agent.nix` viewer — the forge shows the full repo
|
||||
with history. Mutating config still requires
|
||||
`request_apply_commit` + approval.
|
||||
|
||||
`↻ UPD4TE 4LL` button appears above the containers list when any
|
||||
agent is stale. Banner pulses on each broker SSE event
|
||||
(`pulseBanner` with a 4s grace timer).
|
||||
|
||||
### Approval card
|
||||
|
||||
Each pending approval renders as a card (`assets/app.js::
|
||||
renderApprovals`) with three stacked sections:
|
||||
|
||||
- **identity header** — glyph, `#id`, agent, kind chip, and (for
|
||||
`apply_commit`) the short proposal sha as `<code>`.
|
||||
- **what-changed body** — the manager's description, then
|
||||
drill-in triggers: `↳ view diff` opens the diff in the side
|
||||
panel; `↳ commit on forge ↗` deep-links the proposal commit
|
||||
into `agent-configs/<agent>` (shown only when `forge_present`).
|
||||
Spawn approvals show a one-line "container will be created"
|
||||
note instead.
|
||||
- **decision actions** — `◆ APPR0VE` and `DENY`. Deny pops a
|
||||
`prompt()` for an optional reason carried to the manager as
|
||||
`HelperEvent::ApprovalResolved.note`.
|
||||
|
||||
The diff panel has a 3-way base toggle — **vs applied** (the
|
||||
running tree, served instantly from the diff already on the
|
||||
approval), **vs last-approved**, **vs previous proposal** — the
|
||||
latter two fetched on click from `GET /api/approval-diff/{id}
|
||||
?base=approved|previous`. Each line is classified client-side
|
||||
(`+` / `-` / `@@` / `--- ` / `+++ ` → add / del / hunk / file).
|
||||
|
||||
A `pending · N` / `history · N` tab pair switches the section
|
||||
between the live queue and the last 30 resolved approvals.
|
||||
|
||||
### Browser notifications
|
||||
|
||||
Pure frontend (`Notification` API). Three signals trigger them:
|
||||
|
|
@ -198,9 +236,13 @@ not ours.
|
|||
the operator inbox without a snapshot refetch. Used by the
|
||||
compose textbox under MESS4GE FL0W.
|
||||
- `GET /api/journal/{name}?unit=&lines=` — journalctl viewer for
|
||||
a managed container.
|
||||
- `GET /api/agent-config/{name}` — read-only view of the applied
|
||||
`agent.nix`.
|
||||
a managed container; rendered in the side panel.
|
||||
- `GET /api/approval-diff/{id}?base=applied|approved|previous` —
|
||||
on-demand unified diff for an `ApplyCommit` approval against
|
||||
the chosen base (running tree / last approved proposal /
|
||||
previous queued proposal). Raw diff text, classified
|
||||
client-side. `GET /static/marked.js` serves the vendored
|
||||
`marked` bundle the side panel uses for markdown previews.
|
||||
- `GET /api/state-file?path=<host-or-container-path>` — bounded
|
||||
text read of a file under the per-agent `state/` subtree or
|
||||
the shared `/var/lib/hyperhive/shared/`. Accepts the
|
||||
|
|
@ -343,8 +385,16 @@ Layout, top to bottom:
|
|||
- Inbox `<details>` block (collapsed): `inbox · N` — last 30
|
||||
messages addressed to this agent, fetched via
|
||||
`AgentRequest::Recent { limit: 30 }`. (Separate from
|
||||
`AgentRequest::Recv { wait_seconds }` which the harness uses
|
||||
internally to long-poll the broker.)
|
||||
`AgentRequest::Recv { wait_seconds, max }` which the harness
|
||||
uses internally to long-poll the broker.)
|
||||
- Loose-ends `<details>` block: `loose ends · N` — questions,
|
||||
approvals, and reminders pending against this agent (the
|
||||
`get_loose_ends` data, via `GET /api/loose-ends`). Question
|
||||
rows carry an inline answer form (textarea — Enter submits,
|
||||
Shift+Enter newlines); submitting POSTs cross-origin to the
|
||||
core dashboard's `/answer-question/{id}` so the operator
|
||||
answers *as operator*. The per-agent socket deliberately gets
|
||||
no operator-authority path — see `TODO-ops.md`.
|
||||
- Terminal-wrap: live event tail (sticky-bottom auto-scroll +
|
||||
`↓ N new` pill when not at bottom) followed by an
|
||||
operator-input textarea acting as a prompt.
|
||||
|
|
@ -454,3 +504,19 @@ Bus events (new vocabulary on `/events/stream`):
|
|||
totals).
|
||||
- `turn_state_changed { state, since_unix }` — drives the
|
||||
state badge (`idle`/`thinking`/`compacting`).
|
||||
|
||||
### Stats page
|
||||
|
||||
`GET /stats` is a separate per-agent page (served by the
|
||||
harness, linked from the per-agent page's `📊 stats →` and from
|
||||
each dashboard container row). Turn analytics, read-only, from
|
||||
`/state/hyperhive-turn-stats.sqlite`. `GET /api/stats?window=
|
||||
24h|7d|30d` returns a time-bucketed `Snapshot`; the page renders
|
||||
it with Chart.js (vendored from a CDN). Charts: turns,
|
||||
duration (p50 · p95 · avg), context tokens, token cost per
|
||||
bucket, a **turns-by-model** stacked bar (model choice drives
|
||||
token cost, so it sits directly under the cost chart), and
|
||||
doughnuts for tool / wake-source / result mix. A summary chip
|
||||
row carries window totals. `stats.rs` opens the sqlite db
|
||||
read-only and degrades to an empty snapshot on any error — the
|
||||
page is decorative, never authoritative.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue