- .prettierrc: proseWrap=preserve (no prose reflow)
- .prettierignore: exclude hivectl-cli.md (auto-generated) + 11 docs
with multi-line list-item continuations prettier would strip to col 0
(CommonMark limitation in prettier's list handling)
- format 16 markdown files: cosmetic only (*→_, table alignment,
heading normalisation) — verified no broken continuations, idempotent
Several paths in the dashboard docs had bugs:
- /dashboard/stream and /dashboard/history were missing the /api/
prefix (7 occurrences). Verified correct paths from frontend source:
flow.js:212 ('/api/dashboard/history'), core.js:305, tabs.js:1517,
builds.js:624 (all '/api/dashboard/stream'); backend routes match.
- GET /api/build-logs/stream/{id} was wrong; the actual route (and
what common.js:323 calls) is GET /api/build-logs/id/{id}/stream.
Also adds two missing endpoint entries to the API reference section:
- GET /api/build-logs/id/{id}/stream (the live SSE stream)
- GET /api/build-logs/id/{id}/raw (the plain-text download link)
- POST /api/schedules/{id}/pause and /resume (mentioned in prose at
the SCH3DUL3S section but absent from the endpoint list)
The POST /meta-update prefix fix is already in-flight on a separate
branch; left untouched here to avoid conflict.
POST /meta-update was documented without the /api/ prefix in two
places (BU1LDS section prose + endpoint list). The actual route is
/api/meta-update (hive-c0re/src/dashboard.rs).
/cancel-reminder/{id} and /retry-reminder/{id} were documented without
the /api/ prefix in two places (SCH3DUL3S tab prose + endpoint list).
The actual routes (hive-c0re/src/dashboard.rs) and the frontend JS
(tabs.js) both use /api/cancel-reminder/ and /api/retry-reminder/.
Both loose-ends flyout and ask-bind prose referenced the bare path
without the /api/ prefix. The code was fixed in 98b5e976 to use the
correct path; dashboard.md already documents it correctly as
POST /api/answer-question/{id}. Align agent.md to match.
The broker's recent_for was fixed to filter acked_at IS NULL (commit
5264828091), so the agent inbox flyout
now shows only unread messages and empties after 'mark all read'.
The agent.md prose still described the old behaviour ('shows the
most-recent N regardless of ack state; the list stays put after drain').
Update it to match: unread-only, list empties on reload after drain.
The schedule pause/resume button (added in PR #2053) was missing from
the dashboard.md SCH3DUL3S tab docs. The action column listed only three
actions (fire-now, edit, cancel); the pause/resume toggle was undocumented.
Add the full action-column breakdown with the pause/resume semantics:
- paused rows show a 'paused' badge in the next column
- sorted middle bucket (after active, before cancelled)
- fire-now button is disabled while paused
- routes to /api/schedules/{id}/pause or /resume
The QueueKind enum has graceful_stop, start, and stop variants but the
dashboard QUEUE_KIND_GLYPH map only covered rebuild/meta_update/spawn/
destroy/restart/startup_sweep/perm_change — the three missing kinds
rendered as '?' in the build queue UI.
This became visible with the deferred start-after-rebuild change: a fast-lane
Start entry now appears as a child of its Rebuild parent, but showed the
fallback '?' glyph.
Glyphs assigned: graceful_stop=⏹, start=▶, stop=■.
Also update the dashboard.md kind-glyph list to include all nine kinds and
note that deferred start-after-rebuild entries also use parent_id grouping.
The graceful-stop description at the ■ ST0P confirm-dialog paragraph
referenced `/kill/<name>?graceful=1` and `/kill/<name>` (bare, no /api/
prefix; lax bool `1` instead of `true`).
The backend has registered these under /api/ since the /api/-prefix
migration, and the frontend was updated to send `graceful=true` (not `1`)
in commit f2f1a0b3 (fix: send graceful=true not =1 for the kill query param).
Align the docs with shipped code.
Follow-up to the destroy-guard removal — the bootstrap/root container is
now destroyable end-to-end. The frontend already offered DESTR0Y/PURG3
for every container; the only manager-gating left was a stale doc-comment
('destroy/purge hidden for the manager') and a vestigial bare block
wrapping the menu appends. Drop both (no behaviour change), and update the
dashboard.md menu doc: 'disabled for the bootstrap container' -> available
for any container (hive-c0re recreates it on next startup if destroyed).
Schedule columns, tool-group/capability defaults, terminal addressing
(@root), destroy/move guards, and approval-resolution notes now refer to
the root agent (or the submitting agent, for approval flows) rather than
'the manager'. Also fixed the stale 'moving the manager' move-refusal
example (the root agent is reparentable) to a cycle example.
Follow-up to the stats 'all' time-range feature: the agent and hive
stats endpoint docs enumerated the window options but predated 'all'.
Add it to the /api/stats and /api/stats-hive window lists, and note
that 'all' ranges from the earliest recorded turn with an adaptive
bucket width.
The 'Dashboard endpoints' list was half-migrated: newer routes were
documented under /api/* but the older ones (approve, deny, the
rebuild/kill/restart/start/destroy lifecycle group, purge-tombstone,
answer-question, cancel-question, request-spawn, update-all, op-send)
were still listed bare. The dashboard FE calls all of them under /api/
since the route migration, so the doc was stale. Prefix the bare entries
(plus the two inline references) to match what the FE actually requests.
Documentation-only; no behaviour change.
The M4TR1X ACC0UNTS section described the pre-heartbeat state: a
snapshot 'written at startup / rewritten each daemon (re)start' with an
'ambiguous' as_of, and the live-status dot as a 'dashboard-side
follow-up'. All three shipped since:
- the daemon now force-rewrites the snapshot every ~30s (heartbeat), so
as_of advances while alive and a stalled value is an honest dead-daemon
signal — documented, with the full dot state table (green / dim-green
'no heartbeat' age case / amber container-down + offline / grey);
- the login endpoint moved to /api/matrix-account-login and its failure
body is RFC 9457 application/problem+json (message in detail), not the
old 4xx { error } — corrected, with the 400/500 status scheme.
The C0R3 rebuild queue only linked out to the logs page (logs →). Add an
inline live-log panel under the queue that streams the currently-running
rebuild's build output, so the operator watches progress without leaving the
page.
One panel keyed to the running entry's build_log_id (the queue runs one build
at a time), reusing the build-log SSE the logs page already uses
(GET /api/build-logs/id/{id}/stream; frames stdout_append/stderr_append/done).
It lives in its own container (#rebuild-live-log) outside rebuild-queue-section
so the queue's per-row re-render — rows rebuild as the build step advances —
never tears down the open stream; it reconnects only when the running
build_log_id changes and won't reopen a stream that already sent done. Sticky-
bottom scroll, collapsible, live/ok/fail badge, raw download. Hidden when
nothing is building; each row keeps its logs → link for full history.
Frontend-only — no backend change (endpoint + build_log_id already existed).
Closes#1860.
The deny-reason dialog moved from window.prompt() to a themed resizable
textarea (Enter submits, Shift+Enter newline). Update the dashboard route
reference that still described the old single-line window.prompt() flow.
Closes#1849.
The SW4RM tab rendered a per-transient spinner list above the container
list, duplicating the running-step badge already shown on each agent card.
Replace it with a single compact amber banner that appears when the rebuild
queue has active (queued/running) entries — 'build queue — N running / M
queued — view queue →', linking to the full queue on /core.html. Per-agent
detail stays on the cards; the top of the tab just gives the at-a-glance
summary + a jump to the queue. Closes#1817.
Frontend half of #1806 (batch start has no visible running-action feedback).
damocles is routing dashboard start/hard-stop through the rebuild queue as
QueueKind::Start ('start') / Stop ('stop') so they get the same async
queued->running card progression as restart/rebuild/graceful-stop (the sync
transient_guard flash is too brief to see, esp. in a sequential bulk loop).
This adds the row-renderer label cases: 'start' -> starting/start queued,
'stop' -> stopping/stop queued (mirrors the graceful_stop case from #1791).
Forward-compatible: no-op until the backend emits those kinds. Doc updated.
Two fixes from review:
- Liveness: /api/state isn't polled while online (only during login), so
hooking refreshBashTasks to it only populated on cold load. Bash tasks
start + finish asynchronously between turns, so add a light ~4s interval
to keep the tasks pill live; the /api/state-time call now just does the
first-paint populate. Doc note corrected to match.
- Move the blocking dir scan + per-file reads in /api/bash-tasks off the
async executor via tokio::task::spawn_blocking (damocles nit).
#1790 landed hivectl --graceful (enqueues the same GracefulStop as the
dashboard POST). Flip the dashboard.md note from 'CLI flag is still a no-op'
to noting both paths behave identically. hivectl-cli.md is regenerated by
#1790's clap doc-comment, so no edit needed there.
#1785 routes a graceful stop through the rebuild queue as a GracefulStop
entry (wire kind 'graceful_stop'). The SW4RM container-row badge renderer
didn't recognise that kind, so an in-flight graceful stop fell through to
the generic 'rebuilding' / 'rebuild queued' label. Add the case so the card
shows 'stopping…' (running) / 'stop queued' (queued), giving the graceful
stop the same live card progress as a rebuild. Doc the badge kind too.
#1785 landed the real backend: POST /kill/<name>?graceful=1 enqueues a
GracefulStop rebuild-queue transient (one stop-checkpoint turn to flush
state, 3-min timeout falls back to hard stop). Update the dashboard doc note
which still said the backend treated graceful the same as a hard stop. Also
note hivectl --graceful remains a no-op pending a separate gating change.
The dashboard now routes all confirms/prompts/error notices through the
in-app themed dialog system (modal.js: themedConfirm / themedPrompt /
themedToast) instead of native browser chrome, and the stop action carries
a 'stop gracefully' checkbox that POSTs /kill/<name>?graceful=1. Document
both in the web-ui reference, with the note that the backend quiesce is
still being implemented so the graceful flag currently behaves as a hard
stop.
The M4TR1X ACC0UNTS section said the agent picker is populated from
`state.agents`, which never existed on /api/state — the same stale
field the code read. Sync the doc to the live roster field.
The per-row S4V3 buttons + per-agent POST /api/{capabilities,tool-groups}/{agent}
were replaced by a single page-level "save all (N agents)" button posting one
atomic batch to POST /api/permissions. Update the dashboard doc to match:
- both matrices stage edits in-browser; nothing writes until "save all"
- describes the batch contract (changes[] with omitted=unchanged / included=full
replace), the caps+groups coalesce-to-one-rebuild-per-agent behaviour, the
atomic validate-all-or-reject semantics, and the dirty-guard on live re-render
- drops the stale per-row save-column (.cap-save-col / .tg-save-col) description;
notes the data-baseline / data-agent dirty-tracking attributes
Documents what shipped in the save-all change; no code change.
BE-1 (the list endpoint) lives at GET /api/matrix-accounts (reads go under
/api/, matching /api/state and /api/operator-inbox); the page was calling
the un-prefixed /matrix-accounts. Correct the fetch + the contract comment +
the docs reference. POST /matrix-account-login (mutation, root path like
/approve) is unchanged.
Per-account token-failure isolation is now live on the matrix daemon, so a
bad credential entered via this form can no longer take down the agent's
whole matrix session — remove the experimental notice (+ its now-unused CSS).
Also relabel the account list 'configured accounts' -> 'provisioned accounts'
to match the v1 read path (lists accounts with a stored token; a
config-declared-but-unprovisioned account appears once provisioned through
the form). Docs + module header updated to match.
New standalone H0M3 page (/matrix-accounts.html) and tile. An agent
picker drives a list of that agent's configured matrix accounts (name,
homeserver, token-stored status) and a provision form that logs in by
password or stores an existing token.
Frontend half of the per-agent external matrix-account provisioning
work. Built against the v1 backend contract:
GET /matrix-accounts?agent=<name>
-> { accounts: [ { name, homeserver, token_present } ] }
POST /matrix-account-login (x-www-form-urlencoded, operator-auth)
fields: agent, account, homeserver, mode=password|token,
user_id?, password?, token?
-> 2xx { ok, user_id } | 4xx { error }
The token is never echoed back; secret inputs are cleared on submit.
Token-status dot reflects token-stored, not live session (a true
up/down indicator needs the daemon account registry, a follow-up). The
form carries an experimental notice pending per-account failure
isolation on the matrix daemon.
Blocked from merge on the backend endpoints and the daemon
failure-isolation fix; opening for review + to pin the UI/backend wire
contract.
Completes the audit log end-to-end. The backend now emits an
audit_entry_added event on /dashboard/stream per privileged action (the
new row flattened at top level). logs.js already subscribes to that stream
for the BUILD tab; add a branch that prepends the new row to the AUDIT
table's cached list (de-duped by id against the cold fetch), bumps the
'latest N of M' total, and re-renders while the AUDIT tab is in view — so
a restart shows up without a manual refresh. Docs updated to match.
The LOGS page gained a fourth sub-tab (AUDIT) surfacing the
agent-initiated privileged-action audit trail. Document the sub-tab
(lazy fetch, filterable table, outcome/denied badge colouring, the
latest-N-of-total clamp, 30s relative-time ticker) alongside BUILD /
AGENT / SYSTEM, add #audit to the hash-routing list, and add the
GET /api/audit-log endpoint to the API reference.
The per-agent stats page gained a "first-turn ctx" summary chip (the
input tokens of the most recent fresh session's first turn — a
system-prompt/CLAUDE.md sprawl proxy), but agent.md's chip-row
description didn't mention it. Add it next to the reminder chips, noting
the stats.rs derive and the inert-until-capture behaviour (omitted from
JSON until the sessions / turn_stats.session_id capture has rows).
The C0R3 page PR moved the SYST3M tab off the dashboard onto the
standalone /core.html page, leaving the web-ui docs describing a tab that
no longer exists.
- dashboard.md: retitle the "SYST3M tab" section to "C0R3 page
(/core.html)" and reframe its intro — it's now a standalone page off the
H0M3 hub with a createTabStrip sub-tab nav (default R3BU1LD QU3U3), its
own core.js bundle on /dashboard/stream; the dashboard keeps only the
rebuild-queue state for the SW4RM "building…" badges.
- correct the chrome tab-strip list to the actual in-page tabs
(SW4RM / Y3R C4LL / P3RM1SS10NS / SCH3DUL3S) and note SYST3M / ST4TS /
S3TT1NGS / FL0W / L0GS / M4TR1X are all standalone pages off H0M3.
- fix the container-load poll reference (core.js, while the C0NT41N3R
L04D sub-tab is active) and the stray "SYST3M ›" panel references.
- drive-by: the schedules endpoint doc said "SYST3M scheduled-prompts
panel" — it's the SCH3DUL3S panel; corrected.
- web-ui.md index: same tab-list correction + C0R3 page pointer.
Follow-up to the turn-time feature: the terminal now stamps a wall-clock
time on the turn-start / turn-end rows and an elapsed duration on
turn-end, sourced from a per-event `ts` (unix seconds) that the backend
serializes as a flattened sibling of the event tag on both the live SSE
frame and each history row.
- terminal-rendering.md: add the `.turn-time` row to the taxonomy table
+ a note on the ts source and the graceful degradation when a frame
omits ts.
- web-ui/agent.md: note the ts sibling on the emitted events, and the
time/duration suffixes on the TurnStart / TurnEnd renderings.
Split the palette into two standalone stylesheets:
- colors.css — the 16 base16 slots (--base00..--base0F). This is the
entire theme swap contract; a generator (e.g. a stylix base16 scheme,
which is natively base00-base0F) replaces only this file.
- theme.css — the semantic layer (--bg, --purple, …) derived from the
base16 slots via var()/color-mix. Never changes on a swap.
Every page links colors.css then theme.css; theme.css does NOT @import
colors.css (that would re-bake the slots into it) — they're separate
dist outputs so a swap touches just colors.css. Pixel-identical refactor:
base16 defaults are Catppuccin Mocha and the three off-slot vars
(--crust, --muted, --subtext0) derive via color-mix reproducing their
exact prior hexes.
Wires colors.css through both build.mjs CSS entry lists, the
@hive/shared exports map, and all 7 page templates. css-vars.md + the
frontend.nix output-list comment updated.
Per operator request: instead of a disk-specific alert, surface a generic
server-warnings banner at the very top of every page, so new system
warnings can be added backend-side with no frontend change.
- hive-c0re `host_stats`: `server_warnings() -> Vec<ServerWarning>`
(`{ kind, level, message }`). The threshold logic lives server-side; the
host disk-pressure check (a `statvfs` probe of `/nix`: ≥85% used → warn,
≥95% → crit) is the first and only producer today. No new deps (libc).
- `/api/state` carries `server_warnings` (replaces the disk-specific
field). Empty when all clear.
- frontend: `renderServerWarnings` / `initServerWarnings` in `common.js`
inject a sticky top-of-<body> banner and render the list, coloured by
`level`. Wired on every page — dashboard (live, via refreshState),
FL0W, L0GS, H0M3. No per-warning frontend code; adding a warning kind
is a pure backend change.
cargo check/clippy/fmt + npm run build green. Closes#1518.
Swarm-level companion to the per-agent favorite-tools doughnut (#1433).
Aggregates each agent's bash_commands(ts, head) table (written by
hive-bash-mcp) across the whole hive and surfaces the top-10 most-run
command heads on the dashboard ST4TS tab, alongside the existing model
mix.
- hive_stats.rs: AgentAgg gains a `bash` head→count map, filled by a new
guarded `read_bash_heads()` that reuses read_agent's read-only
connection. A missing `bash_commands` table (capture hasn't run for
that agent) or any read error yields an empty map — isolated from
read_agent's error path so it never drops an agent from the rollup.
HiveStats gains `bash_mix: Vec<KeyCount>` (busiest-first, top 10).
Unit tests cover the per-head tally + window cutoff and the
missing-table degrade-to-empty path (in-memory sqlite).
- dashboard: a "favorite tools (bash commands across the swarm)" CSS-bar
list on the ST4TS pane, mirroring the model-mix bars. Header + list
stay hidden until bash_mix has data, so a fresh hive shows no empty
block. (Dashboard ships no chart lib — bars, not a doughnut.)
- docs: dashboard.md ST4TS section documents the new rollup.
Closes#1449. Inert until the hive-bash-mcp capture (#1448, merged) has
recorded data across agents.