diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index bd3753ff..3c8cbe53 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -759,9 +759,9 @@ dashboard doesn't pre-check whether the agent is reachable, it just lets the `` try and listens for an `error` event. On failure the handler swaps the `src` to `/favicon.svg` (served by the dashboard itself, always reachable) and adds the -`icon-unreachable` class for the dimmed look. When the container -is known stopped up front (`ContainerView.running = false`) the -fallback fires immediately, skipping the doomed `/icon` +`icon-unreachable` class for the dimmed look. When the dashboard +already knows the container is stopped (`ContainerView.running = false`) +the fallback fires immediately, skipping the doomed `/icon` fetch entirely. **Line 1** β€” agent name (link β†’ new tab), m1nd/ag3nt chip, an @@ -771,8 +771,8 @@ own backend. The response (`DashboardState`) carries: `links` (nav strip entries β€” `πŸ“Š stats`, `πŸ–₯ screen` when GUI is enabled, `⬑ forge profile`, `↳ agent-configs mirror`, plus any agent-declared `dashboardLinks` extras), `status_text` / `status_set_at` (agent -self-reported status β€” the `(set N ago)` chip is stamped `data-set-at` -and ticks every 30s to stay fresh across the long-lived keyed row +self-reported status β€” the `(set N ago)` chip carries a `data-set-at` +stamp and ticks every 30s to stay fresh across the long-lived keyed row cache), `rate_limited`, `ctx_tokens` / `context_window_tokens` (context-window badge data). The agent backend is the single source of truth for all of these. The dashboard resolves each `AgentLink.kind` @@ -789,17 +789,17 @@ Gateway-off is the flag-absent fallback (a dashboard served outside a hyperhive deploy): base URL is `http://:` (direct TCP). Forge links resolve against `state.forge_public_url` (sourced from -`services.hyperhive.swarm.forge.publicUrl`) and are omitted entirely when +`services.hyperhive.swarm.forge.publicUrl`) and disappear entirely when that's unset β€” never guessed from `:3000`. External links are already absolute. The same base URL drives the primary agent-name link + favicon fetch, so the whole row routes through the gateway as a unit. **When the container is stopped** (`ContainerView.running = false`), -the async `dashboard-state` fetch is skipped entirely (the agent -web server is down), so the badge chain is replaced by a single -badge, the nav strip is empty, and status text / rate-limited / ctx -badges are suppressed. The agent icon goes straight to the dimmed +the dashboard skips the async `dashboard-state` fetch entirely (the agent +web server is down), so a single badge replaces the badge chain, +the nav strip is empty, and status text / rate-limited / ctx +badges disappear. The agent icon goes straight to the dimmed `/favicon.svg` fallback instead of attempting a doomed load from the container's URL. Static fields β€” `needs_update`, `deployed_sha`, `pending_reminders`, `parent`, `config` link β€” remain visible @@ -823,13 +823,13 @@ older backend without the field serves `failed: undefined`, which reads falsy β€” degrades cleanly to the single `not running` badge. When the container is running, status badges follow β€” `⊘ rate -limited` (red, while the harness is parked after a 429), `needs +limited` (red, while the harness parks itself after a 429), `needs login`, `needs update` β€” plus **one `◐ pending-state…` pill per active transient** (replaces buttons during operator-initiated start / stop / restart / rebuild / destroy). An agent can carry **multiple transients at once** β€” for example a lease-exempt `prebuild` running alongside a `stop_for_update` on the same agent β€” and each -renders as its own independent badge rather than being collapsed +renders as its own independent badge instead of collapsing into one label, matching the existing multi-badge convention this line already uses for `paused`/`needs_update`/model/ctx. @@ -877,13 +877,13 @@ container is running and the harness has persisted a model name (the `active_model` field of `hyperhive-harness.json`, the consolidated harness state file in the agent's state dir). Read by hive-c0re's `ContainerView` (`read_active_model`); absent until the agent has -completed at least one turn and stale values are suppressed for -stopped containers. +completed at least one turn, and hive-c0re suppresses stale values +for stopped containers. **`ctx Β· Nk` chip** shows the agent's last-turn context size, populated from `DashboardState.ctx_tokens` (absent until the agent has completed at least one turn). The chip colour (green / -yellow / red) is keyed off `DashboardState.context_window_tokens` +yellow / red) keys off `DashboardState.context_window_tokens` (the real context window for the model the agent last ran on, authoritative from the agent side); the badge goes yellow β‰₯ 50% and red β‰₯ 75% of that window, matching the harness compaction @@ -936,8 +936,8 @@ that wants step-level counts instead, unused here. All confirmations, prompts, and transient error notices use an in-app themed dialog system (`@hive/shared/modal.js`) rather than the browser's native `confirm()` / `prompt()` / `alert()` chrome, so -they match the Catppuccin palette and can't be styled away by the -OS. Three primitives, all built on the `openDialog` core: +they match the Catppuccin palette and the OS can't style them away. +Three primitives, all built on the `openDialog` core: - `themedConfirm({ message, danger, confirmLabel, checkboxes })` β€” a modal confirm that resolves to `null` on cancel or an object @@ -987,8 +987,8 @@ text-glyph-painted**: each indent lane is its own positioned `` so CSS can draw full-height vertical bars that bridge the gap between sibling rows. Plain text box-drawing characters (`β”œβ”€`, `└─`, `β”‚ `) would only paint one text-line tall and leave visible breaks between -the taller-than-one-line container cards, so the bars are drawn as -CSS borders instead: a continuation bar runs the full height of an +the taller-than-one-line container cards, so CSS borders draw the +bars instead: a continuation bar runs the full height of an ancestor's still-open subtree, and the joint at a row's own depth is `β”œ` (more siblings below) or `β””` (last sibling β€” the line stops at the row's icon midline). Exact lane widths and positioning live in @@ -1007,7 +1007,7 @@ toggles its selection (an in-memory `Set`); `Esc` or the bar's switches in-memory β€” the bar just hides on non-SW4RM tabs since other tabs don't show the agent cards needed to cross-reference. -When one or more agents are selected (via the icon), a sticky +When the operator selects one or more agents (via the icon), a sticky frosted-mauve bar slides up from the bottom of the viewport (`#selection-bar`, `position: fixed; bottom: 0`). It shows: @@ -1043,8 +1043,8 @@ frosted-mauve bar slides up from the bottom of the viewport the tree repaints without a page reload. - **`βœ• clear`** button + `Esc` key clear the entire selection. -Stale selections (agents destroyed while selected) are pruned on -every render before the bar appears. +Every render prunes stale selections (agents destroyed while +selected) before the bar appears. ## Approval card @@ -1186,9 +1186,9 @@ below β€” some endpoints aren't in it yet. bodies at 1 MiB. Selection-time backing for the inline path-link preview. - Detection of which tokens *are* path links is done + The broker forwarder detects which tokens *are* path links **server-side at broker-message ingest**, not client-side: - the broker forwarder calls `scan_validated_paths(body)` β€” + it calls `scan_validated_paths(body)` β€” same allow-list helper the read endpoint uses β€” and attaches the verified file tokens to the event as `file_refs: Vec`. The client trusts that list and linkifies only those tokens, @@ -1241,7 +1241,7 @@ below β€” some endpoints aren't in it yet. Writes the capability set for `{agent}` to `/var/lib/hyperhive/meta/capabilities.json` and queues a rebuild so `HIVE_CAPABILITIES` takes effect. Agent name validated; - unknown capability strings are rejected (400). `guard_agent_name` + unknown capability strings rejected (400). `guard_agent_name` applied. - `POST /api/permissions` β€” batch perm apply for the save-all permissions button. Body @@ -1251,10 +1251,11 @@ below β€” some endpoints aren't in it yet. replace semantics as the per-agent endpoints above). Each affected agent gets ONE combined `PermChange` queue entry, so changing both an agent's tool-groups and capabilities triggers a single rebuild, - not two. **Atomic**: every change is validated first (agent names via + not two. **Atomic**: the endpoint validates every change first (agent names via `guard_agent_name`, group + capability names) and on any validation - error nothing is written or enqueued (non-2xx `{ error }`); rows with - both fields omitted are skipped, not errors. Returns `200 "ok"` on + error nothing is written or enqueued (non-2xx `{ error }`); it skips + rows with both fields omitted rather than erroring on them. + Returns `200 "ok"` on success. - `GET /api/schedules` β€” list all schedules (active and recently cancelled) for the SCH3DUL3S scheduled-prompts panel. @@ -1283,8 +1284,8 @@ below β€” some endpoints aren't in it yet. pulse. Fires the schedule body once immediately to every active target. Recurring schedules: `next_fire_at_unix` is untouched; the regular cadence continues. One-shots: the - schedule is consumed (cancelled) after the manual fan-out. - Per-target `last_result` is annotated as a manual fire so + manual fan-out consumes the schedule (cancels it). + The endpoint annotates per-target `last_result` as a manual fire so the audit trail distinguishes scheduled fires from operator- triggered ones. - `POST /api/schedules/{id}/pause` β€” pause a recurring or @@ -1331,8 +1332,8 @@ payload): (`actions::approve`), the job queue's own node execution (`job_queue::exec`, for example after a rebuild's stop/swap/start steps or a destroy's teardown step) β€” and from the 10s - `crash_watch` poll. Client upserts/removes by name; the - pending overlay is read from `transientsState` since the + `crash_watch` poll. Client upserts/removes by name and + reads the pending overlay from `transientsState` since the payload doesn't carry it. - `rebuild_queue_changed` (seq) β€” **payload-free trigger**, fired on every queue mutation (enqueue, state transition, dedup collapse, @@ -1362,8 +1363,8 @@ payload): assignments: `BTreeMap>`) β€” full snapshot of capability grants. Emitted from the rebuild-queue worker after a `PermChange` / Capabilities entry commits the JSON file. Payload - matches `GET /api/capabilities` shape so `renderCapabilities` can - be called directly. P3RM1SS10NS tab subscribes; activation + matches `GET /api/capabilities` shape so the client can call + `renderCapabilities` directly. P3RM1SS10NS tab subscribes; activation re-fetch still runs as a safety net. - `tool_groups_changed` (seq, groups: `Vec`, descriptions: map, assignments: `BTreeMap>`) β€” full snapshot of