Commit graph hyperhive/docs
Author SHA1 Message Date
iris
7e5b496aa8 dashboard: fire-now button on schedule rows (closes #467)
Operator wants to trigger a scheduled prompt immediately
instead of waiting for the next interval. Adds a `↯ fire now`
button on every active schedule row, next to `✕ cancel all`.

Semantics (per design discussion with damocles):

- recurring schedules → out-of-band pulse, `next_fire_at_unix`
  untouched; the regular cadence keeps firing on the original
  schedule. Operator gets an extra fan-out, not a phase shift.
- one-shots → consumed after the manual fire. Operator's
  intent reads as "the scheduled time was wrong, send NOW";
  leaving the original time would be surprising.

Confirm dialog spells out the recurring-vs-one-shot
difference up front so the operator knows what they're about
to do. Button is disabled when every target is already
cancelled (nothing to fire).

Talks to `POST /api/schedules/{id}/fire-now` (damocles is
wiring the backend in parallel). Mauve styling distinguishes
it from cancel (red) and submit (amber); fits the existing
btn pattern.

docs/web-ui.md updated.
2026-05-26 17:06:14 +02:00
iris
dd92ef07fa dashboard: inline edit form on schedule rows (closes #474)
Per damocles's PATCH /api/schedules/{id} backend (#475), each
non-cancelled schedule row gets a `✎ edit` button that toggles
an inline form pre-filled with current values. Editable:

- body (textarea)
- description (blank to clear)
- next-fire (datetime-local)
- interval (shared composer from #466 — all-zero flips to one-shot)

Targets stay immutable per the design call with damocles:
per-target last-result history is keyed on them; cancel + new
schedule is the documented retarget workaround. The form
surfaces the active target list as a read-only note explaining
this.

Submit semantics — the form computes a PATCH diff against the
original schedule and only includes keys for fields that
actually changed. Blank description → `null` (clear), all-zero
interval on a recurring schedule → `null` (flip to one-shot).
No-op submit (no fields changed) just closes the edit form.

Refactored the interval composer (#466) into a shared
`buildIntervalComposer({ label, namePrefix, initialSeconds })`
helper so the new-schedule and edit-schedule forms use the same
chip/d/h/m/s/preview widget. New-schedule form behavior
unchanged; edit-form input names are prefixed `edit_interval_`
to avoid FormData collisions when both happen to mount.

State survives state-poll re-renders via `editingSchedules`
(Set of ids being edited) + `scheduleEditCarry` (per-id
mid-edit values) — same pattern the new-schedule form uses
with `readScheduleFormCarry`.
2026-05-26 15:58:28 +02:00
damocles
d0a1ee037b hive-forge: make --json a global flag (closes #421) 2026-05-26 15:55:59 +02:00
iris
caa0c6ce4c dashboard: friendlier interval input for scheduled prompts (closes #466)
Replaces the single raw-seconds field in the SCH3DUL3D PR0MPTS
creation form with a structured composer:

- Preset chip row (1m / 5m / 15m / 30m / 1h / 6h / 12h / 1d / 7d
  / one-shot) that fills the parts inputs in one click
- Four small d/h/m/s number inputs combined into total seconds
  on submit (all-zero = one-shot, preserving the backend null
  semantic)
- Live "↻ every …" preview using the existing fmtDuration helper
  so the operator sees what they're about to queue

Carry semantics extended to round-trip the split fields across
state-poll re-renders; legacy `interval` carry still honoured if
an older bundle is in the page.

Docs (web-ui.md) updated to describe the new composer.
2026-05-26 15:55:20 +02:00
iris
4fdc061c9d dashboard: move queued reminders into SCH3DUL3S tab (closes #460)
mara wanted one place for everything that fires at a future time.
The QU3U3D R3M1ND3RS section moves out of the SYST3M tab and
lands at the bottom of the SCH3DUL3S tab, below QU3U3D SCH3DUL3S.

Pure layout change — refreshReminders() and /api/reminders
unchanged; the section just lives under a different parent now.
Reminders don't contribute to the SCH3DUL3S pill count (kept as
"active schedules" only — reminders are self-scheduled and high
cardinality; adding them would make the pill noisy).

docs/web-ui.md picks up a SCH3DUL3S tab section (the previous
docs lumped the schedules subsection under SYST3M, but the tab
has been separate since #459); reminders subsection follows
schedules in the same tab.
2026-05-26 13:39:42 +02:00
lexis
0b92d597f8 docs: document scheduled prompts tab in SYST3M (follow-up to #461) 2026-05-26 11:58:51 +02:00
lexis
22d970fbe9 docs: add scheduled_prompts to file map + manager schedule tools (follow-up to #454) 2026-05-26 11:46:51 +02:00
lexis
f221cdbb37 docs: document side-panel drag-to-resize and SharedWorker SSE multiplexing (follow-up to #451 #453) 2026-05-26 11:46:17 +02:00
lexis
8dc3432570 docs: document agent selection bar and approval source chip (follow-up to #443 #436) 2026-05-26 01:21:49 +02:00
lexis
d494413c7f docs: clarify approval row is marked failed, not absent, on flake validation failure 2026-05-26 00:19:24 +02:00
lexis
f3e6490432 docs: document flake.lock validation on request_apply_commit (follow-up to #434) 2026-05-26 00:19:24 +02:00
lexis
e750b08f58 docs: scope get_agent_meta clearing list to status fields only 2026-05-26 00:13:30 +02:00
lexis
04e67aaa03 docs: add running field to get_agent_meta, document stopped-container display (follow-up to #433) 2026-05-26 00:13:30 +02:00
lexis
8d40499e8d docs: document auth_failed / needs_login-on-401 behavior (follow-up to #423) 2026-05-25 22:55:24 +02:00
lexis
599a71254a docs: add comments verb to CLAUDE.md, prompts, and gotchas (follow-up to #420) 2026-05-25 21:16:54 +02:00
lexis
0e17459943 docs: correct agent icon size to 5em after #413 cap 2026-05-25 20:50:16 +02:00
damocles
7e12da83e2 hive-forge: update agent/manager prompts + gotchas for rust rewrite (mara@#407) 2026-05-25 02:16:53 +02:00
lexis
38920d3af1 docs: update web-ui.md for agent header redesign and in-flight rebuild badge (#394 #398) 2026-05-25 02:00:47 +02:00
lexis
e9cce17828 docs: update web-ui.md for tabbed layout, topology tree, per-agent overhaul (#366 #373 #381) 2026-05-25 00:45:56 +02:00
damocles
0b03d5bcfb topology: meta-repo agent hierarchy + ContainerView.parent (#361) 2026-05-24 04:47:55 +02:00
iris
229c4292e9 frontend: cut over Rust binaries to ServeDir; delete legacy assets
Phase 4 of #273 — the actual switch. Both axum routers now serve
their static surface via `tower_http::services::ServeDir` mounted
as a fallback service, reading the dist path from `HIVE_STATIC_DIR`
(set by Phase 3's NixOS module wiring).

Deletes:
- `hive-c0re/assets/{index.html, app.js, dashboard.css}`
- `hive-ag3nt/assets/{index.html, app.js, agent.css, stats.html,
   stats.js, screen.html}`
- The whole `hive-fr0nt/` crate (workspace member dropped, both
  hive-c0re and hive-ag3nt drop their `hive-fr0nt.workspace = true`
  dep). Its contents now live as `@hive/shared` under
  `frontend/packages/shared/`.

Rust changes:
- `hive-c0re/src/dashboard.rs`: remove `serve_index`, `serve_css`,
  `serve_app_js`, `serve_shared_js`, `serve_marked_js`,
  `serve_favicon` (all six `include_str!` handlers); replace their
  routes with a single `.fallback_service(ServeDir::new(static_dir))`
  on the router. Fail closed (anyhow::bail) if `HIVE_STATIC_DIR` is
  unset or not a directory at startup.
- `hive-ag3nt/src/web_ui.rs`: remove `serve_index`, `serve_css`,
  `serve_app_js`, `serve_shared_js`, `serve_marked_js`,
  `serve_stats`, `serve_stats_js`, `serve_screen`; same
  `fallback_service` pattern. `serve_icon` stays (consumes
  `/etc/hyperhive/icon.svg` + `branding/hyperhive.svg` fallback,
  neither of which lives under the frontend dist).
- `AgentLink` URLs for stats/screen switched from `/stats` / `/screen`
  to `/stats.html` / `/screen.html` since ServeDir doesn't auto-
  append the extension and the on-disk filename is the natural URL
  post-cutover.
- `Cargo.toml` (workspace): drop `hive-fr0nt` member + workspace
  dep, add `tower-http = { version = "0.6", features = ["fs"] }`.
- `hive-c0re/Cargo.toml` + `hive-ag3nt/Cargo.toml`: drop the
  `hive-fr0nt.workspace = true` dep, add `tower-http.workspace =
  true`.

Docs updated:
- `CLAUDE.md`: file map reflects `frontend/` (was `hive-fr0nt/` +
  `assets/`) and the ServeDir/HIVE_STATIC_DIR shape.
- `docs/web-ui.md` 'Shape (shared by both)' section: describes the
  ServeDir fallback + bundled-by-esbuild surface, no more
  `include_str!` references.
- `docs/terminal-rendering.md`: src paths point at
  `frontend/packages/{agent,shared}/src/`; marked is the npm dep,
  not vendored UMD.

Validation:
- `cargo check --workspace` — clean (5 warnings, all pre-existing
  in `rebuild_queue.rs`, none on changed files).
- `cargo clippy --workspace --all-targets` — clean (11 warnings,
  same pre-existing source).
- `cd frontend && npm run build` from the prior commit's lockfile
  produces the dist directories the new routers consume:
    dashboard: `dist/{index.html, static/{app.js, dashboard.css}}`
    agent:     `dist/{index.html, stats.html, screen.html,
                       static/{app.js, stats.js, agent.css}}`
  (favicon.svg lands in dashboard/ during the nix build —
  `nix/frontend.nix` install phase copies `branding/hyperhive.svg`
  there, since it's outside the npm tree.)

Refs #273.
2026-05-23 14:51:01 +02:00
lexis
4c425ede69 docs: document rebuild queue panel + module (follow-up to #340) 2026-05-23 12:27:03 +02:00
damocles
73871f18c3 set_status: consolidate whoami into get_agent_meta with optional name 2026-05-23 11:32:33 +02:00
iris
222a5b4dc6 dashboard+agent: agent backend owns its nav links; dashboard proxies
The previous take put a shared NavLink wire type in hive-sh4re and
duplicated the link-building logic across crates. Per @mara on #326:
that doesn't fit the eventual frontend/backend split goal (#273).
The agent backend is the natural source of truth for what links its
own page exposes; hive-c0re just passes the list through to the
dashboard.

* hive-ag3nt/src/web_ui.rs: agent_links now also serves the
  config-repo link + reads agent-declared dashboardLinks extras
  from {state_dir}/hyperhive-dashboard-links.json. AgentLink gains a
  kind enum (Container | Forge | External) so the frontend can build
  the right href no matter which surface is rendering. The host
  header is no longer used — URLs are paths for Container/Forge,
  absolute for External.

* hive-c0re/src/dashboard.rs: new GET /api/agent/{name}/links route,
  a same-origin proxy that fetches the agent's /api/state and
  forwards just the links field. No shared wire type — hive-c0re
  treats the payload as opaque JSON (serde_json::Value). All failure
  modes degrade to an empty list so the dashboard still renders.

* hive-c0re/assets/app.js: container card head row gets an async-
  populated icon-only nav strip from the proxy. The hardcoded stats
  link, the standalone config-repo trigger, and the extras block are
  gone. The deployed:<sha> chip stays — the agent harness can't know
  its own deployed sha, so this chip is how the operator sees what's
  live alongside the agent's (root-only) config link.

* hive-ag3nt/assets/app.js: agent page meta-links rendered via
  el() / textContent (DOM build) so agent-declared icon / label / url
  strings never reach innerHTML. kind-based href resolution mirrors
  the dashboard side.

* docs/web-ui.md: dashboard + per-agent sections updated for the new
  architecture.

Closes #262.
2026-05-23 02:11:40 +02:00
iris
7f97acf19e dashboard: render META INPUTS as a full tree with bulk select
Remove the depth-2 cap in walk_meta_inputs so every fetched input
at every depth is surfaced, not just two levels (issue #275). The
uncapped walk needs a guard: a visited-node set makes it a spanning
tree — each fetched node walked once, at its shallowest path — so
shared subtrees don't re-walk and a cycle can't recurse forever.
A two-pass walk (claim a node's direct inputs before descending)
keeps shallow inputs at a shallow path.

Frontend: renderMetaInputs indents each row by its slash-path depth
and shows the leaf segment (full path on hover), plus a select-all /
select-none control so a long input list isn't ticked box by box.
2026-05-22 23:50:20 +02:00
lexis
40589c8510 docs: update spawn flow docs for apply_commit handling first spawn (follow-up to 66f1568) 2026-05-22 22:34:42 +02:00
lexis
3abb00c327 docs: add request_update_meta_inputs to manager tools (follow-up to 3e098c5) 2026-05-22 22:34:42 +02:00
lexis
96f93f3b5e docs: add request_next_turn to turn-loop.md (follow-up to c99261b) 2026-05-22 22:34:42 +02:00
iris
4a27ef7304 dashboard: derive ctx badge thresholds from the model context window 2026-05-22 22:32:32 +02:00
iris
2f1b846baf dashboard: show meta-update progress in the META INPUTS panel
post_meta_update returns 200 immediately and runs the nix flake
update + agent-rebuild ripple in a background task, so the META
INPUTS panel looked idle for the whole multi-minute window (#259).

Track in-flight runs with a Coordinator atomic counter, exposed via
an RAII MetaUpdateGuard held across run_meta_update. Surface it as
the meta_update_running snapshot field plus a MetaUpdateRunning SSE
event (flipped only when the count crosses 0, so concurrent runs
flip the flag once). The panel shows a pulsing in-progress banner
and disables the update button while a run is active.
2026-05-22 21:54:28 +02:00
iris
a9a10b631f dashboard: show when an approval was requested (closes #272) 2026-05-22 20:06:45 +02:00
iris
9b9277db78 fix: vendor marked UMD build so window.marked is defined (issue #244) 2026-05-22 16:33:13 +02:00
damocles
6ca72074c4 docs: move sandbox threat model to docs/security.md, add code reference 2026-05-22 12:28:04 +02:00
iris
15e44955a8 web: clickable links in terminal rows and dashboard messages (issue #233) 2026-05-22 01:17:38 +02:00
iris
f510a321df screen: add match-size — RFB SetDesktopSize to resize the remote desktop 2026-05-21 23:15:36 +02:00
iris
ab1f8d6e33 dashboard: icon fallback on real img load failure, not container-state guess 2026-05-21 22:01:38 +02:00
iris
16f614f45d dashboard: dimmed default icon for unreachable containers
A stopped or mid-transient (restarting / rebuilding) container's
web server isn't answering, so its <url>/icon background-image
just failed to an empty box on the card.

When the container isn't reachable (not running, or a transient
is in flight) the icon now falls back to the dimmed hyperhive
mark — /favicon.svg, served by the dashboard itself so it's
always loadable — greyscaled + lowered opacity via the
.icon-unreachable class.

closes #195
2026-05-21 21:56:39 +02:00
iris
f42ba9b561 dashboard file preview: markdown tabs + raster image rendering
Follow-up to #188. Two additions to the side-panel file preview:

- Markdown files get a rendered/plain tabbed view (was: always
  rendered, no way to see source) — same tab pattern as SVG.
- Raster images (png/jpg/gif/webp/bmp/ico/avif) render as an
  <img>. /api/state-file previously from_utf8_lossy-stringified
  every file and served text/plain, which corrupts binary; it
  now serves image files as raw bytes with their real
  content-type (over-cap images are rejected, not truncated —
  a clipped binary is corrupt).

buildSvgPanel generalised to buildTabbedPreview, shared by SVG +
markdown. .svg-host/.svg-render renamed .preview-host/.img-preview
since they now back images + md too.

closes #192
2026-05-21 21:49:15 +02:00
iris
a8ab91ecd8 dashboard: render SVG file previews
SVG files in the side-panel file preview showed only raw source.
Add a rendered/source tabbed view: 'rendered' (default) shows the
image, 'source' shows the markup.

The image loads via an <img> data: URI — <img>-loaded SVG runs in
the browser's secure static mode (scripts + external fetches
disabled), so an untrusted SVG from an agent's state dir can't
execute code in the dashboard origin. Tabs reuse the existing
diff-base-tab styling; a checkerboard backs the image so
transparent regions read clearly.

closes #188
2026-05-21 20:40:30 +02:00
iris
fc3490086b agent page: assemble forge URL backend-side
Per review: build the full forge profile URL in the harness instead
of the client. /api/state now returns forge_url: Option<String>
(assembled from the request Host header — resolves against whatever
host the operator reached the page on), replacing the forge_present
bool. The JS just links forge_url when present — no client-side URL
construction.
2026-05-21 20:27:43 +02:00
iris
6ab667901d agent page: link to the agent's forge profile
Add a '⬡ forge ↗' link to the per-agent page's meta row, next to
the stats + screen links. It opens the agent's Forgejo profile
(http://<host>:3000/<label> — the per-agent forge user is named
after the agent) in a new tab.

- web_ui.rs: StateSnapshot gains forge_present, true when the
  agent's forge-token file exists in the state dir (same signal
  that tells the agent it has a forge account).
- index.html / app.js: hidden link, shown + href-filled when
  forge_present, mirroring the existing gui_enabled/screen-link
  pattern. Host comes from window.location so it works off
  whatever host the page is served from.

closes #185
2026-05-21 20:27:43 +02:00
iris
9abcda280a dashboard: full-height square agent icon, icon-left card layout
The agent icon was a 26px <img> inline in the card head, hidden via
onerror when a stopped container's web server didn't answer — which
collapsed the slot and shifted the row.

Restructure the live container card as icon-left / body-right:
- the icon is a background-image div with aspect-ratio 1 and
  align-self stretch — full card height, square, and (being a
  background) it has no intrinsic size, so loading or failing it
  can never reflow the row;
- a failed load (stopped container) falls through to a placeholder
  fill instead of collapsing;
- the three content lines move into a .card-body column.

Tombstone rows keep the plain stacked layout (:not(.tombstone)).

closes #177
2026-05-21 19:19:47 +02:00
iris
4539091f3c terminal: show recv wait/max params + bash [bg] flag
recv tool-use rows rendered as a bare recv() regardless of args,
hiding whether a turn is parked on a long-poll (wait_seconds) or
draining a burst (max). fmtToolUse now surfaces both. Bash rows
gain a [bg] flag when run_in_background is set.

closes #158
2026-05-21 17:57:24 +02:00
damocles
6a643f2fd2 docs: update turn-loop get_loose_ends, add hive-forge and cp gotchas 2026-05-20 22:00:05 +02:00
iris
939df10a61 docs: document model/context-window config, dynamic watermarks, rate-limit scoping 2026-05-20 16:55:13 +02:00
iris
69604407a9 docs: update for recent commits (rate limiting, reply threading, screen, auto-reset, two-step spawn, ctx chip) 2026-05-20 16:52:18 +02:00
damocles
3c672ed6b2 add allowedBashPatterns NixOS option for finer-grained Bash tool approval 2026-05-20 13:35:28 +02:00
damocles
9cbb05bb86 add proactive context-size compaction with a notes-checkpoint turn 2026-05-20 13:27:57 +02:00
damocles
4715e88fff docs: move backlog to forge issue tracker, extract boundary doc 2026-05-20 12:19:16 +02:00
damocles
44c86b9278 docs: correct stale recv_blocking + vacuum references 2026-05-20 12:10:34 +02:00