Commit graph hyperhive/docs/web-ui
Author SHA1 Message Date
atlas
9e76589be3 docs: 10 cited nix options that do not exist, two in pasteable blocks
An option name that is absent reads exactly like one that is present —
the reader has no way to tell, and the failure surfaces as a nixos eval
error at deploy time. Two namespace reorgs the prose never followed:
`forge.*` moved under `swarm.`, and several flat paths under `c0re.`.

  docs/networking/gateway.md:335   services.hyperhive.forge = { … }
  docs/networking/gateway.md:367   forge.rootUrl        → swarm.forge.rootUrl
  docs/networking/gateway.md:389   frontend             → c0re.frontend
  docs/tools/hivectl.md:193        agentCpuQuota        → c0re.agentCpuQuota
  docs/tools/hivectl.md:317        forge.behindGateway  → swarm.forge.behindGateway
  docs/agent-lifecycle/persistence.md:404   agentCpuQuota → c0re.agentCpuQuota
  docs/web-ui/dashboard.md:610     modelPrices          → c0re.modelPrices
  docs/web-ui/dashboard.md:789     forge.publicUrl      → swarm.forge.publicUrl

Both `gateway.md` blocks are fenced nix an operator is meant to paste.

Two sites needed more than a rename:

  dashboard.md:781 cited `gateway.enable` as a live opt-in. It was
  removed; `gateway.md:269` already says the gateway is unconditional,
  and `hive-c0re/environment.nix:208` sets HIVE_GATEWAY_ENABLED = "1"
  with no condition. Rewritten to say so, keeping the flag-absent
  fallback the dashboard still implements.

  turn-loop/config.md:4 attributed the page's knobs to
  `services.hyperhive.agents.<name>`. No such option exists — every
  knob the page documents is agent-side `hyperhive.*`, set in the
  agent's own agent.nix.

Measured against the module system rather than a grep: `nix build
.#docs` renders nixosOptionsDoc over the evaluated trees (279 option
paths). That arm alone is wrong — it omits `internal = true` options
and called `gateway.localNames` and `swarm.peerHives` dead, so a second
arm requires the literal path to appear in nix/ and rescues exactly
those. Four remaining unresolved citations are correct prose saying
`gateway.enable` / `network.{enable,isolateContainers,upstreamDns}`
were removed, and are left alone.

Closes #3948
2026-09-02 17:17:09 +02:00
atlas
39b95c2ede treefmt: apply prettier
Pure `nix fmt` output from the commit before this one — no hand edits.
203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs.

Reproduce with `nix develop -c nix fmt` on the parent commit; the result
should be byte-identical to this tree.

None of the 13 `.prettierignore` entries appears here — verified by
intersecting the changed-file list against the ignore file, with a
control proving the intersection finds a match when one exists.
2026-09-02 15:25:07 +02:00
iris
07b62612b0 docs: restructure into topic subdirectories, collapse duplicated index
Per mara's go-ahead on hyperhive#3902 ("getting started is good, but
terminal rendering does not go in there i think"):

Moved 21 top-level docs/*.md files into 7 new topic subdirectories
(existing web-ui/, turn-loop/, swarm/, tools/, crates/ untouched):
  getting-started/  setup.md
  agent-lifecycle/  agent-hierarchy.md, approvals.md, persistence.md
  trust-boundary/   boundary.md, security.md
  integrations/     forge.md, matrix.md, github.md, knowledge.md
  networking/       gateway.md, network.md, snapshot-store.md
  scheduler/        jobq.md, coordinator.md, ci.md, observability.md
  process/          conventions.md, gotchas.md, pr-review-gate.md
  web-ui/           terminal-rendering.md (moved into the EXISTING dir,
                    per mara's correction to the original getting-started
                    guess -- it's UI implementation detail, not onboarding)

The physical layout now matches docs/README.md's own topical headers,
which already amounted to this taxonomy -- see the scoping comment on
the issue for the two findings that motivated this (a genuine
duplication between CLAUDE.md's old "Reading paths" list and
docs/README.md's grouped one, since drifted out of sync with each
other; and the flat layout not matching the grouping we already had).

Fixed every cross-reference this moved across the whole repo (~120
files: docs/ internal links at every depth, Rust doc comments, nix
module option docs, crate READMEs) -- verified two ways: a grep sweep
confirming zero remaining references to any old path, and a script
that resolves every markdown link in docs/**/*.md + CLAUDE.md +
README.md against the filesystem and reports anything that doesn't
exist (zero broken links).

Collapsed CLAUDE.md's "Reading paths" section (the duplicate) down to
a pointer at docs/README.md, now the single index. Rewrote
docs/README.md itself to use the new subdirectory paths and added the
one doc it was missing that CLAUDE.md's old copy had (pr-review-gate.md).

Classified all 22 docs/*.md files first via a haiku subagent (mara's
suggestion) on two axes -- proposed grouping and operator-vs-
implementation focus -- before finalizing the taxonomy; spot-checked
the report and found internal inconsistencies (its classification
table disagreed with its own summary section for a few files), so this
taxonomy is my original proposal + the one correction mara gave
directly, not a blind application of the subagent's table. The
operator-focus data it gathered is still useful for a follow-up
content pass (docs skewing 'mixed' rather than pure operator-facing),
not addressed in this PR -- structure only.

nix fmt clean, both pre-push lints clean.
2026-09-02 01:55:37 +02:00
iris
d9937ee834 dashboard: also remove the tombstone revive trigger
mara asked on PR #3854 to remove the revive action alongside the
blank-name spawn form. Both posted to /api/request-spawn as the last
two frontend callers; with this the dashboard has no UI path left that
hits that endpoint (backend removal/decision stays damocles's call).

Drops the K3PT ST4T3 tombstone row's ⊕ R3V1V3 form, leaving PURG3 as
the only per-tombstone action. Updated the two doc/comment spots that
described the now-gone button.
2026-08-31 19:35:45 +02:00
iris
8475d9921f dashboard: remove the spawn-new-agent trigger from the Y3R C4LL tab
Frontend half of removing hive-level agent spawning (swarm-level
creation now covers it, and its forge-works confirmation just landed
in hive/hive-chat). Removes call.js's blank-name spawn-request form
(R3QU3ST SP4WN) and its now-orphaned .spawnform CSS.

Deliberately keeps core.js's tombstone-list revive action (R3V1V3) --
a different feature (respawn an *existing* agent, reusing its kept
state), not agent creation, and not what this issue asked to remove.
It happens to post to the same /api/request-spawn action with the
tombstone's own name pre-filled rather than a blank input.

Backend endpoint + wiring is a separate slice (damocles).
2026-08-31 19:30:38 +02:00
iris
b33bb7a3d3 Move dashboard settings into Y3R C4LL tab, drop standalone S3TT1NGS page
mara (issue #3817): remove the home link + page, put the setting toggle into the Y3R C4LL tab. Deleted settings.html/.js/.css; the browser-notification toggle (the only content there) now renders as a ◆ PR3F3R3NC3S ◆ section under Y3R C4LL's approvals/inbox, wired the same way (NOTIF.bind()/NOTIF.show() in common.js — no behavior change, just a new mount point). Updated build.mjs's entry lists and every doc/comment that pointed at the old page.
2026-08-31 12:57:31 +02:00
iris
146db58bab docs: trim M4TR1X-page LinksMenu paragraph to the pointer, not the impl
mara: strip impl details from docs. Dropped the nix-module name, struct literal, and gating-condition restatement — docs/swarm/ui.md::Quick links already covers that; this section only needs to say where the link lives now.
2026-08-31 12:55:40 +02:00
iris
19ed400cdd docs: M4TR1X page is reached via swarm-ui's LinksMenu, not opened directly
mara (PR#3820): the operator doesn't type /matrix/ into the browser — it's a swarm-level link (hive-matrix.nix registers it into services.hyperhive.swarm.controller.links, rendered by swarm-ui's LinksMenu). Corrected the M4TR1X page doc, and fixed the hive-matrix.nix comment that still described the removed H0M3 tile in present tense while I was in there.
2026-08-31 12:55:40 +02:00
iris
40be8222b8 docs: fix stale Matrix-tile reference in M4TR1X page section
argus (PR#3820 review): the M4TR1X page section still said the operator opens /matrix/ from the H0M3 hub's Matrix tile — that tile no longer exists after this PR removed it. Fixed to say the page is opened directly.
2026-08-31 12:55:40 +02:00
iris
2490181055 H0M3: remove Forge/Matrix tiles from hive home
mara (issue #3816): remove the swarm-service links (forge, matrix) from the hive home hub. Both surfaces are still reachable directly (forge's own public URL, /matrix/); they just no longer get a tile on H0M3. Dropped the now-dead reveal/href-fill logic in home.js and updated the two docs that described the old gating.
2026-08-31 12:55:40 +02:00
damocles
22adfd1451 remove the 1NFR4 dashboard panel and the now-writer-less audit log 2026-08-31 00:18:21 +02:00
damocles
7516a4e10e remove hive-level infra-container restart from web ui and agents 2026-08-31 00:18:21 +02:00
iris
f14056996e terminal: catch the remaining stale ask/answer references
argus, reviewing PR#3793: a third stale  ask mention survived in the
same file/table the first pass touched (docs/terminal-rendering.md's
icon legend) — tool_icon() has no ask/answer arm at all, confirmed by
reading the function directly. Swept the whole tree this time instead
of trusting the earlier narrow grep: found three more —
docs/web-ui/dashboard.md's S3TT1NGS section still documented the
expand-tool-output toggle as living on the dashboard, which moved to
the per-agent page's own SettingsMenu popover in #3780 and was never
followed up here; markdown.ts/streamRow.ts/terminal.css had the same
send/ask/answer/recv phrasing as the original two comments.
2026-08-30 20:13:49 +02:00
damocles
2850270829 hive-c0re/hive-sh4re: remove the ask/answer wire protocol + core routing 2026-08-30 01:18:17 +02:00
damocles
46183795dd hive-c0re, docs: sweep remaining stale ask/answer-dashboard references 2026-08-29 23:28:32 +02:00
damocles
ff0a6660aa dashboard: remove the Y3R C4LL questions pane (ask/answer removal, frontend) 2026-08-29 20:35:27 +02:00
iris
cd339af91b agent.css: delete dead .overflow-btn/.overflow-menu/.overflow-item rules
`OverflowMenu.tsx`/`.css` were deleted (rebuild button removed outright,
dashboard link moved into `MetaNav`), but `agent.css` still carried the
whole trigger+popover+item rule set — grepped the entire `agent`
package, none of these classnames appear in any current markup.

Also fixed three tombstone comments elsewhere in the file that pointed
at the now-also-deleted `.overflow-item-*` classes as "where it moved
to" — they'd have dangled once those rules were gone too. And two stale
doc claims caught in the same sweep: `docs/web-ui/agent.md` still listed
`OverflowMenu.tsx` in the header's component tree and described "the
overflow menu" as a live effort-picker location.
2026-08-29 10:16:00 +02:00
iris
668ccc2278 agent: remove rebuild button, move dashboard link into the links menu
mara (#3704): 'remove rebuild button, move link to dashboards into
links menu.'

The overflow (⋯) menu existed for exactly two items: the dashboard
back-link and a rebuild-container action. Rebuild is gone outright —
the dashboard's own R3BU1LD button already covers it, this was just a
rarely-used shortcut not worth its own menu. The dashboard link moves
into MetaNav's links popover (now the first item, above stats/forge/
config/extras) instead. With both gone, OverflowMenu had nothing left
to justify existing as a separate component — deleted along with its
CSS and the now-unused rebuildAction.ts (only consumer).

MetaNav gained a dashboardBase prop (Root.tsx already computes this
via resolveDashboardBase for InboxPanel/pause — reused, not
duplicated) and renders the dashboard link as a real <a>, same
treatment as every other item in that popover — no dangling
window.open()-only affordance.

Updated docs/web-ui/agent.md's Header section and the couple of
now-stale OverflowMenu references in index.html's/MetaNav.css's own
comments.

Verified: header now shows a single trailing icon-badge (was two),
popover opens with dashboard first then the agent_links() set.
tsc --noEmit clean, build clean, both pre-push lints clean.
2026-08-28 23:40:56 +02:00
iris
8e97fc6263 docs: shape.md — fix stale app.js example, app.js no longer exists
argus, non-blocking note on PR#3702: the relative-path-resolution
example still used static/app.js as its illustrative filename after
that file was deleted in the cutover. Mechanism described was still
correct, just a stale filename a future reader could get confused
chasing. Swapped to static/main.js (the agent page's own script) and
static/stats.js (the /stats subpage example, more accurate than
main.js there since that's specifically about a subpage's own
script).
2026-08-28 23:18:21 +02:00
iris
fa2b360e74 agent: cutover — index.html now serves the Preact rewrite, app.js deleted
mara: 'i merged this without realizing you still did not delete the
old code. pls follow up with ripping out the old code.'

- index.html: dropped the old static header/main/composer/overflow-
  menu markup and app.js's <script> tag. Now just <div id=preact-root>
  + <script src=static/main.js>. main.css's <link> lands after
  agent.css's — cascade order argus flagged matters for LoginFlow's
  .login-card / MetaNav's popover to win against agent.css's legacy
  rules, confirmed explicitly rather than assumed at this exact step.
- build.mjs: app.js dropped from the esbuild entryPoints (stats.js
  keeps its own bundle, unaffected — separate page, separate script).
- frontend/packages/agent/src/app.js deleted (1717 lines). screen.html
  has its own inline <script>, untouched — never depended on app.js.
- docs/web-ui/agent.md: rewrote the Header section to describe the
  real Preact component tree and the badges+pills-together layout
  (deferred from the earlier commits on this PR specifically so it
  wouldn't describe a hybrid state — this is that promised follow-up).
  Touched up the one other app.js-specific mention in the endpoints
  section. Left the Main/composer/side-panel/live-view/slash-command
  sections alone — behavior there is unchanged, verified faithfully
  ported throughout this PR's earlier commits.

Verified against the REAL dist/index.html (not the dev-preview
harness) — a scratch mock server serving the actual built output
end-to-end, screenshotted clean. tsc --noEmit clean, build clean, both
pre-push lints clean.
2026-08-28 23:14:52 +02:00
iris
638e1ac2c6 swarm-ui: delete StatusChip, migrate its 3 callers to shared Badge
mara: non-interactive Badge and StatusChip render identically (same
padding/radius/font, same tone-to-color mapping) and StatusChip's
4-tone/single-label shape is a strict subset of Badge's — no real
reason to keep both. Deletes StatusChip.tsx/.css, migrates AgentsPage's
config-PR chip, HivesPage's freshness chip, and ComponentsPage's own
table-status sample to Badge (tone/value, no onClick). Also drops the
now-redundant standalone StatusChip demo section on /components (the
Badge section already covers all 4 former chip tones plus accent).

Updated the two stale StatusChip references outside swarm-ui too:
design-guide.md's component-list example and colors.css's WCAG-
contrast-rationale comment.
2026-08-28 13:21:49 +02:00
iris
4af890f01d hive dashboard: bulk pause + resume in the selection bar
Mechanical addition to the existing bulk-action framework
(renderSelectionBar/addBulkButton, swarm.js) -- two per-agent actions
already exist (POST /api/pause/, /api/resume/, see hive-agent-menu.js),
this just gives the selection bar the same all-or-nothing enablement
rule the other six bulk buttons already use (pause enabled only when
none of the selection is already paused, and vice versa for resume).

.btn-pause reuses .badge-paused's yellow so the trigger and the
resulting state pill read as one colour; .btn-resume is green like
.btn-start (both are "go" actions). Docs updated to list both in the
Selection bar reference.
2026-08-24 11:37:04 +02:00
iris
b25aa157df swarm-ui: give Panel an optional header icon slot
Adds an `icon` prop to Panel (small emoji glyph left of the title,
aria-hidden, chosen per panel with no default) and wires it into every
current Panel caller: hives (bee), create-agent's form (robot) and info
panel (identity card, moved off the info panel's body copy where it
started as a one-off), jobs (puzzle piece), the components gallery
itself (toolbox), and the 404 page (compass). Adds a components-page
demo section and a whimsy-section pointer in the design guide.

Closes: #3508
2026-08-19 17:22:48 +02:00
iris
afe627e0a9 swarm-ui: derive theme override from colors.css instead of duplicating hex values
mara's review: the theme override read as a hand-copied duplicate of
colors.css's hex values instead of deriving from it. Restructured
colors.css to declare each palette's 16 hex values exactly once
(--mocha-baseNN, --latte-baseNN) and have every activation block
(the default, the prefers-color-scheme media query, and two new
:root[data-theme='light'|'dark'] blocks) just re-point the active
--baseNN slot at one of those two raw palettes via var() - never a
second copy of a hex value.

theme-apply.ts simplifies to match: it now only toggles a data-theme
attribute on <html>, same shape motion-apply.ts already had. No
palette values live in JS at all anymore.

Re-verified the override still genuinely outranks the media query
with the new mechanism: same seed-localStorage-while-forcing-the-
opposite-OS-preference test as before, both directions still render
the stored override correctly.
2026-08-18 23:58:48 +02:00
iris
72e087b086 swarm-ui: fix WCAG contrast failures in the light-theme accent slots
argus review: the literal Catppuccin Latte accent hexes (base08-0F)
fail badly as StatusChip fill-text (green/amber/red/yellow on
--purple-dim/base03: 1.4:1-3:1, need 4.5:1) and even as plain text on
--bg/base00 in the agent/dashboard packages that also import this file
(2.3:1-4.8:1). Root cause: Latte's own accents are calibrated against
Lattes near-white base/crust, not a mid-gray surface1; the Mocha row
does not hit this because Mochas pastel accents are already light, so
they contrast fine against a dark surface1 - Lattes saturated-but-mid
accents do not have the same headroom against Lattes own lighter
surface1.

Fix: darken each accent slot from stock Latte (same hue/saturation,
lower HSL lightness via binary search) until real WCAG contrast against
base03 clears 4.5:1 with margin - verified this also clears >7:1
against base00, so both the swarm-ui chip case and the plain-text case
elsewhere are covered by one set of values. base00-07 stay stock Latte
(no contrast role, just surfaces/foreground). Yellow and peach read
closer to olive/brown than a bright yellow/orange once darkened this
far - an inherent property of darkening a warm hue in sRGB, not a
mapping mistake; boosting saturation further did not rescue it
(checked).

Verified with headless-chromium screenshots against the built swarm-ui
bundle: StatusChip text (the exact case argus flagged) and every chip
tone on /components now read clearly.
2026-08-18 23:29:20 +02:00
iris
56e7a309e8 swarm-ui: respect prefers-color-scheme for a light theme default
colors.css shipped one fixed dark (Catppuccin Mocha) palette with no
light variant and no OS/browser-preference detection, so anyone
without a stylix-managed session (a phone browser, a future PWA
install) got the dark palette regardless of their light-mode
preference. This is an accessibility gap, not a cosmetic one - some
people need light for low-vision/contrast reasons, others need dark
for photosensitivity, the same reasoning that already gates
prefers-reduced-motion elsewhere.

Add a Catppuccin Latte row behind `@media (prefers-color-scheme:
light)`, ported through the identical base16 slot mapping (including
the existing sky-over-teal base0C substitution) so a swap between the
two rows never changes what a slot means. A stylix-generated
colors.css replaces the file wholesale with a single unconditional
:root block and has no media query in it, so a themed deployment is
unaffected either way.

Verified with headless chromium screenshots forcing both
prefers-color-scheme values against the built swarm-ui bundle - both
render with correct contrast, and the default (no forced preference)
render matches the light row.
2026-08-18 23:29:20 +02:00
iris
f0c362b688 docs: clarify dynamic colour derivation still traces to base16
Per mara's follow-up: the doc shouldn't read as 'no dynamic colour at
all' — mixing/lighter/darker derivation is fine and matches Material's
own approach, the constraint is that every derived colour still
traces back to the base16/stylix contract, not an independent source.
2026-08-18 21:21:11 +02:00
iris
61b7bb4b4d docs: rework design guide per mara's review
Addresses all 7 line comments from her REQUEST_CHANGES review:
- drop the issue-#3444 history pointer and any issue-number tracking
  refs throughout (a design guide states expectations, it isn't a
  change log or a status report)
- stop naming specific rejected technical solutions (SSE/WS) for a
  design constraint — state the chosen shape only
- flip the component-first heuristic: build the primitive first/
  alongside its first real caller, not after — the point is giving the
  next thing built ready-made blocks, not lagging behind usage
- drop the 'Open questions' section entirely — that's what the issue
  thread is for, not a doc
- stop leading Visual language with 'basis: Material Design' and then
  immediately carving out big exceptions — lead with what we actually
  want, mention Material as a minor closing influence instead
- drop 'future work'/timeline framing everywhere (motion override,
  PWA-as-future-slice, 'not shipped yet' theming caveats) — state the
  target design as the expectation, not its current build status
- reworded the stylix-wins theming bullet to drop 'build time', which
  reads wrong from a frontend dev's perspective (stylix supplies the
  palette separately, it isn't decided by the frontend's own build)
2026-08-18 21:21:11 +02:00
iris
a5864c0fde docs: fix design-guide accuracy nits argus flagged
- matrix-rain reference is in packages/dashboard/src/home.js, not
  swarm-ui — cite it correctly (dashboard package) rather than implying
  it lives inside this doc's own scope.
- drop FormField from the visible component-first inventory (it has no
  /components demo, deliberately — a real exception to the 'every new
  ui/ component gets a demo' rule stated two paragraphs later) and note
  the exception explicitly instead of leaving the contradiction.
2026-08-18 21:21:11 +02:00
iris
7dc3e710b4 docs: swarm-ui design guide
Distills the design-language discussion on #3444 into a durable
reference: visual language, motion, theming policy, data-freshness/
refresh, error UX, empty states, layout/viewport, component-first
design, and attention — plus an open-questions table pointing at the
still-unbuilt issues (#3452/#3453/#3454/#3456) instead of asserting
them as settled.

Mirrors css-vars.md's shape and links to it + to /components rather
than duplicating either. First draft for comment, not a final spec.
2026-08-18 21:21:11 +02:00
iris
1111577c91 extract build-queue rollup as a shared Preact component
New @hive/shared/jobq-rollup.js (JobqRollup.tsx + jobq-rollup.css),
mirroring JobqGraph's shape exactly: JSX use plus an imperative
mountJobqRollup(container, props) for a plain-.js call site. Fetches
Vec<hive_jobq_wire::StateCount> off `endpoint`, sums Running+Finishing
roots as "running" and Pending roots as "queued", renders nothing when
both are zero. Optional `queueHref` adds a "view queue -> " link.

Swapped dashboard's hand-rolled queue-summary banner (swarm.js) over to
this component instead of keeping two parallel implementations - same
"one shared component" pattern JobqGraph already set for the rebuild
queue tree view. Mounted once into a new #jobq-rollup-section, kept as
a sibling of (not inside) #containers-section since that section gets
replaceChildren()-wiped on every container-state render, which would
tear down and remount a Preact tree on every tick. Refreshed via the
mount handle's .refresh() on rebuild_queue_changed, same as builds.js's
JobqGraph handle.

Also mounted in swarm-ui's /jobs page, above JobqGraph, with no
queueHref (a link back to the page you're already on is noise) - the
literal ask on hyperhive#3364.

Verified: npm run build (whole workspace) and swarm-ui typecheck both
clean, comment-block + issue-ref lints run manually, headless-chromium
screenshots of both the dashboard SW4RM tab and swarm-ui's /jobs page
against mocked /api/jobq/rollup payloads - banner renders identically
in both, with and without the queue link as expected.
2026-08-16 22:08:38 +02:00
iris
ecf01f5e87 docs: remove historic framing, state what JobqGraph is now 2026-08-16 15:18:25 +02:00
iris
37161cd136 dashboard: replace <hive-jobq-graph> with a shared Preact component
Ports the shadow-DOM <hive-jobq-graph> custom element
(frontend/packages/shared/src/jobq-graph/) to a Preact component
(JobqGraph.js) shared by the dashboard and swarm-ui, per hyperhive#3310.

- JobqGraph.js: written with plain h() calls (no JSX) so the same file
  compiles unmodified under both the dashboard's text-loader CSS config
  and swarm-ui's JSX config. Exports `JobqGraph` for JSX use and
  `mountJobqGraph(container, props)` for the dashboard's non-JSX
  imperative mount, returning a `{refresh(), update()}` handle matching
  the old custom element's public surface. Same rendering contract as
  before: indented state tree, payload.label verbatim, payload.data as
  a generic key/value list, "waits on: <label>" text for Node-kind deps,
  per-state filter checkboxes, optional cancel button.
- jobq-graph.css: light-DOM adaptation of the old shadow-scoped
  stylesheet (:host -> .jg-root, otherwise unchanged).
- dashboard/src/builds.js: local mountJobqGraph() renamed to
  mountRebuildQueue() to avoid colliding with the newly-imported shared
  mountJobqGraph; cancel handling is now a plain onCancel callback
  instead of a DOM CustomEvent listener (no shadow boundary to cross
  anymore).
- dashboard + shared package.json: added preact as a dependency (matches
  swarm-ui's existing pin, 10.29.8) - the dashboard was a vanilla-JS MPA
  with no Preact/JSX pipeline before this.
- Removed the old hive-jobq-graph.js/.css entirely (confirmed via grep
  it had exactly one consumer, dashboard/src/builds.js, so this is a
  clean swap, not parallel maintenance of two implementations).
- Updated stale doc-comment references to the old element name in
  builds.html, tabs.js, swarm.js, docs/web-ui/dashboard.md, and
  hive-c0re/src/job_queue/mod.rs.

Verified: npm run build (whole frontend workspace) and npm run
typecheck (swarm-ui) both clean; cargo build/clippy/test -p hive-c0re
all clean (331 tests, 0 failures); headless-chromium screenshot of
/builds.html against a mock GET /api/jobq/graph payload confirms full
visual/behavioral parity with the old custom element (tree, filter
checkboxes, cancel buttons, error text, waits-on line, data list, live
build log panel).

This covers the dashboard-replacement half of hyperhive#3310 only. The
swarm-ui half (rendering the CreateAgent DAG on the agent-creation page)
is downstream of hyperhive#3306/#3124 landing - no swarm-ui page exists
yet to mount it in.
2026-08-16 15:18:25 +02:00
iris
c67100588e docs+nix: fix stale certFingerprint/HYPERHIVE_PEERS references (hyperhive#3294)
Follow-up to the plumbing removal: docs/swarm/README.md gets the
biggest rewrite (drops the whole "Fingerprint format" section, fixes
the runtime-effects list, the WireGuard config example + "what the
mesh does" bullet), docs/gateway.md and hive-gateway/options.nix drop
4 "needs no certFingerprint" mentions, swarm-peers-removed.nix's
migration-warning text no longer tells an upgrading operator to carry
a field over that no longer exists, swarm.nix/swarm-wireguard.nix/
swarm-controller.nix/swarm-controller's main.rs get comment fixes
where they described the now-removed HYPERHIVE_PEERS shape. Also
caught one more stale "peer hives" mention in docs/web-ui/README.md's
SW4RM tab description that the first pass on this issue missed.
2026-08-15 19:56:11 +02:00
iris
8c8f0e2758 docs+nix: fix stale peer-hives-dashboard references (hyperhive#3294)
Follow-up to the peer-hives removal: docs/web-ui/dashboard.md drops
the whole "P33R H1V3S" section + its stale #peers hash and tab-strip
mentions; docs/swarm/README.md's runtime-effects list and
cross-references point at swarm-ui's roster page instead. Nix comments
in hive-c0re/environment.nix, swarm.nix and swarm-wireguard.nix that
described HYPERHIVE_PEERS/certFingerprint as dashboard-consumed are
updated to say what's actually still true (agent identity only).

Deliberately NOT removed: the `certFingerprint` nix option itself.
It has no remaining Rust consumer, but deleting a documented,
potentially already-set option is a bigger, breaking change than
removing dead display code — flagged in docs/swarm/README.md with a
note instead of silently dropped, so an operator or reviewer can make
that call explicitly rather than have it made for them here.
2026-08-15 19:55:29 +02:00
iris
4388719b76 docs(web-ui/agent): fix stale NavLink type name
Verified against hive-agent/src/web_ui/state.rs: the struct is AgentLink
(AgentLinkKind for kind), not NavLink -- NavLink doesn't exist anywhere in
the Rust or frontend source.
2026-08-15 12:45:22 +02:00
iris
26b55f34d3 docs(web-ui/shape): fix stale CSS bundle count, SSE route prefix, bind-retry cap claims
Verified against frontend/packages/dashboard/build.mjs, hive-c0re/src/dashboard/mod.rs,
and hive-agent/src/web_ui/mod.rs:
- dashboard ships 9 page CSS bundles + colors/theme/common, not 4
- dashboard SSE routes are /api/dashboard/stream + /api/dashboard/history, not
  /dashboard/stream + /dashboard/history
- per-agent bind_with_retry has a MAX_BIND_ATTEMPTS=12 cap (gives up), unlike the
  dashboard's genuinely uncapped retry loop
- assets/swarm.js, assets/call.js -> swarm.js, call.js (no assets/ dir exists)
2026-08-15 12:45:22 +02:00
iris
3e9f2f2fd5 docs(dashboard): fix stale facts found in source-verification sweep
- server-warnings banner: was described as disk-pressure-only; it's now
  a push-based registry with multiple producers (forge/CI boot
  failures, agent-state warnings), and shown on more standalone pages
  than listed
- browser tab title: actual default/format is "hyperhive // h1ve-c0re",
  not "hive / c0re"
- SW4RM container tree: ContainerView.parent comes from
  agent_config/topology.rs, not the ambiguous dashboard/topology.rs
  (which only holds set-parent endpoints)
- T00L GR0UPS: tool-group enumeration was missing "forge"; root agent's
  default (MANAGER_DEFAULT) is not literally "all groups" -- it excludes
  forge and web_tools
- ST4TS moved to its own /stats.html page a while back; section still
  called it a dashboard tab
- P33RS is a headline block within the SW4RM tab, not its own tab --
  contradicted the doc's own chrome-header description
- active model badge: reads hyperhive-harness.json's active_model
  field, not a bare harness/hyperhive-model file
- themed dialogs: modal.js lives in the shared package
  (@hive/shared/modal.js), and themedToast takes (message, opts) not
  a single options object
- graceful stop: backend uses a Signal/Drain job-queue node pair, not
  a "GracefulStop" transient kind; hivectl flag is `stop --graceful`,
  not a bare `--graceful`
- container_state_changed event: named a nonexistent
  auto_update::rebuild_agent as an emit site; actual sites are
  actions::approve and the job queue's own node execution

Verified against hive-c0re/src (dashboard/, stats/, job_queue/,
container_view.rs), hive-sh4re/src/permissions.rs, and the dashboard
frontend package (tabs.js, stats.js, swarm.js, builds.js, modal.js).

No structural/prose changes beyond what the fact corrections required.
2026-08-15 12:45:22 +02:00
iris
4f03a82cc5 docs: fix 3 more stale dashboard.rs refs argus caught in review
hive-c0re/src/dashboard.rs became a module directory
(hive-c0re/src/dashboard/) a while back; three more references to it
as a single file survived the #3281 sweep (conventions.md x2,
web-ui/shape.md's StateSnapshot pointer). Same bug class the sweep
was hunting for, argus caught it in review.
2026-08-15 12:45:22 +02:00
iris
dd8b5db7ab docs: fix remaining stale internal references from the #3281 sweep
Two follow-ups the per-file sweep workers flagged but couldn't fix
themselves (either not their assignment, or not visible from their
worktree):

- web-ui/dashboard.md's P33RS tab named dashboard.rs, which no longer
  exists (hive-c0re/src/dashboard/ is a module dir now); the function
  moved to state_snapshot.rs.
- approvals.md and conventions.md used hive_ag3nt:: as a Rust
  module-path prefix. hive-agent is a bin-only crate (no lib target),
  so that prefix never resolved to anything; also fixed the
  hive-ag3nt/prompts/system.md path to the real hive-agent/prompts/.

All three verified directly against the current source tree, not
guessed.
2026-08-15 12:45:22 +02:00
iris
f104d39c72 docs(web-ui/agent): add section headers, dedupe shared shape/rendering detail, trim changelog framing 2026-08-15 12:45:22 +02:00
iris
721a99ed64 docs(web-ui/shape): add routes header, trim historical framing 2026-08-15 12:45:22 +02:00
iris
785b59a4bb docs(dashboard): fix misplaced CR3D3NTIALS content, dedupe, trim history 2026-08-15 12:45:22 +02:00
iris
5bd085fbac web-ui: expose per-agent paused status, add pause/resume to the agent page's own overflow menu
hive-agent's own web_ui module never exposed the agent's own paused
status to its own /api/state — the dashboard's cross-container view
knew it, but a per-agent page had no way to know it's paused. Added
StateSnapshot.paused (a direct stat of the same harness-local pause
marker hive-c0re's Coordinator::is_paused checks).

The per-agent page's ⋯ overflow menu now has a pause/resume item that
POSTs to hive-c0re's existing /api/pause/<name> / /api/resume/<name> —
the same endpoints the dashboard's <hive-agent-menu> already uses,
same cross-origin form-submit pattern the existing rebuild-container
item uses. The item's label tracks state.paused on every /api/state
refresh so a pause/resume triggered from the dashboard while this page
is open doesn't leave a stale action showing.
2026-08-11 20:42:53 +02:00
iris
ecf9ff4d80 web-ui: remove dead ask->operator inline-answer binding from the per-agent terminal
hyperhive#2922: the inline-answer slot (pendingAskBinds/reconcileAskBinds/
buildAnswerForm) depended on a since-removed /api/loose-ends endpoint
and had been silently non-functional the whole time — nothing ever
reassigned lastLooseEnds, so the reconciler always no-op'd.

Per mara's call on the issue (ask/answer is deprecated per #2850, only
the main dashboard UI needs to work, remove the broken per-agent inline
view): ripped out the dead JS (binding + form + CSS) rather than
restoring the endpoint. An ask tool call now renders like any other
tool call, no inline answer affordance; the operator answers via the
dashboard's own question surfacing.

Also fixed adjacent doc staleness this same removal made newly
contradictory (docs/web-ui/agent.md, docs/terminal-rendering.md):
the doc already described the loose-ends/bash-tasks flyouts and the
ask-binding as recently dead, but the endpoint reference table and a
header-pills bullet list still described them as live.
2026-08-11 20:21:52 +02:00
atlas
07852cabc1 feat(3088): move the gateway's nginx + dnsmasq onto the host
The gateway's nginx + dnsmasq no longer run in their own nspawn container.
`nix/host-modules/hive-gateway/default.nix` loses the
`containers.hive-gateway` wrapper and everything that existed only to punch
holes in it: `privateNetwork = false`, `CAP_NET_ADMIN`, five bind mounts,
its own `stateVersion`, `networking.firewall.enable = false`,
`networking.resolvconf.enable = false`, and the `hive-gateway-resolv`
path+service pair. 465 -> 303 lines.

The container never bought isolation here. It shared the host netns by
necessity — nginx binds the host's :80/:443, dnsmasq answers on the bridge —
so each of those settings was undoing a boundary the gateway could not
afford in the first place.

Four things made it more than a deletion, none of them visible in the nix
diff:

- The self-signed cert service also imports the hive CA leaf, so removing it
  with the container would have left nginx naming a missing cert file, which
  it refuses to load at all.
- The nginx reload is a hive-priv verb. It still needs root, but no longer
  for the reason its doc gave, and `--machine=` was both transport and
  scope — so the unit name is now hard-coded in the helper as the
  containment.
- The lifecycle verb named a container that stops existing.
- `journalctl -M hive-gateway` had no machine to enter.

Per the operator's ruling, the operator verb keeps working and agents lose
it. `InfraContainer` answered three questions that used to share an answer;
it now splits into `name()` (identity), `target()` (Container vs HostUnit),
`service_unit()` (the systemd unit), and `agent_restartable()`, which the
MCP restart path checks before the capability so the refusal cannot read as
"ask for infra_admin". `SIBLING_CONTAINERS` drops the gateway — it gates the
requests that name a container as a string — while `FromStr` still accepts
it, because that answers what a name is, not who may act on it. The
dashboard's gateway journal reads host journald filtered to `nginx.service`.

Prose was corrected where it only named a location, and re-argued where the
container was doing security work: a `0666` per-agent socket was safe
because only the gateway container had the directory bind-mounted. There is
no mount now, so the directory permissions are the whole of the access
control — the constraint holds, its mechanism doesn't.

Gate: nix fmt / clippy --all-targets -D warnings / cargo test all clean (710
tests); hivectl-cli.md regenerated from the clap tree. The nix eval was run
in both TLS shapes at this commit: every delta in the rendered
virtualHosts is one of the three intended path moves, dnsmasq settings are
byte-identical, and the absence probe flips true -> false with bindMounts
emptied.
2026-08-11 18:01:03 +02:00
iris
b785f96d30 dashboard: distinct "gave up" badge for a crash-looped container
Frontend half of the two-PR split on the systemd restart-bound work
(clause 2): once a container's unit hits systemd's bounded restart
limit and stops on its own, that read exactly like a deliberate stop
("not running") — no way to tell "gave up" from "off on purpose".

Renders ContainerView.failed as a distinct red "gave up" badge on the
container row, in place of the muted "not running" badge. Both states
have running: false; failed is the new orthogonal fact that tells them
apart, same "independent flags, no state machine" shape as
paused/needs_update/needs_login. An older backend without the field
serves failed: undefined, which reads falsy, so this degrades cleanly
to the existing single "not running" badge.

Frontend-only — no Rust changes. Safe to merge in either order
relative to the backend PR carrying ContainerView.failed itself.
2026-08-10 23:14:36 +02:00
iris
1e13b88c8c jobq graph: state filter on /api/jobq/graph + multi-select checkboxes
GET /api/jobq/graph gains a states query param (comma-separated
hive_jobq::State names): narrows the served root groups to the named
states, keeping a group whole (filtering by a root's own state, which
is already its subtree's rolled-up answer). Absent, empty, or fully
unrecognised is the identity filter, matching prior behaviour.

hive-jobq-graph.js gains a row of per-state checkboxes above the tree,
re-fetching the endpoint with the selection on toggle. Default
selection hides Done and Skipped.

Server-side filtering (not client-side hiding) so hive-jobq-graph-update's
node list, and everything downstream of it in builds.js (count pill,
live-log panel), only ever sees what's actually shown.
2026-08-10 23:05:03 +02:00
iris
e525dcb6d4 agent icon: 404 when unconfigured, client-side fallback
hive_sh4re::assets::branding_svg() resolved a server-side default
icon at runtime from HIVE_ASSETS_DIR — the only consumer was
serve_icon(), which fell back to it whenever the agent had no
`hyperhive.icon` override. Removed both the fallback and the
function: serve_icon() now 404s when /etc/hyperhive/icon.svg is
absent, and the per-agent web UI (app.js) picks up the existing
dashboard swarm.js pattern — swap the <img> src to the
frontend-bundled /favicon.svg on load failure, guarded against
looping if the fallback itself 404s.

Updated the doc/comment claims that said the server always returns
an image (docs/web-ui/agent.md, nix/agent-modules/default.nix, the
hive-c0re/forge/users.rs comment referencing the old shared-asset
set). forge-avatar-sync and the matrix avatar sync are unaffected —
both are gated on hyperhive.icon != null and never depended on the
removed fallback.
2026-08-10 20:59:59 +02:00
iris
aa14339be7 jobq-graph: re-add per-node cancel button
Fixes #3067.

<hive-jobq-graph> gains a `cancellable` attribute: any non-terminal
node (Pending/Running/Finishing) gets a small cancel button, and a
click dispatches `hive-jobq-graph-cancel` (`detail: { id }`) rather
than POSTing anything itself -- which endpoint actually cancels a
node is the host's domain concept, same "push data out, host decides"
shape `hive-jobq-graph-update` already uses.

builds.js turns it on for R3BU1LD QU3U3, confirms via themedConfirm,
then POSTs the existing `/api/rebuild-queue/{id}/cancel` endpoint.
No manual refresh needed -- cancelling flips node state, which
already fires rebuild_queue_changed over SSE, and the page's existing
handler for that tick already calls jobqGraphEl.refresh().

Also removed ~130 lines of dead `.rqe-*` CSS in system-sections.css
left over from the bespoke pre-<hive-jobq-graph> queue renderer
(confirmed zero JS references before deleting each rule; kept the
still-used `.rqe-kind`/`.rqe-agent`/`.rqe-source*`).

docs/web-ui/dashboard.md's R3BU1LD QU3U3 section updated to match
current behaviour (cancel button, waits-on text instead of the old
"no per-node actions" note, sibling order no longer implies anything
since deps render as text not a reordered rail).
2026-08-09 17:40:39 +02:00