diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index 12044a1e..4d9049cd 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -186,10 +186,13 @@ window.marked = marked; if (!menu) return; menu.replaceChildren(); - // ↑ dashboard — host dashboard back-link. + // ↑ dashboard — host dashboard back-link. The dashboard SPA lives at + // `dashboard.html` (the `/` root now serves the H0M3 menu hub), so the + // link targets that file; `dashUrl` itself stays the API origin used + // for the rebuild / answer-question / mark-all-read POSTs below. menu.append(el('a', { class: 'overflow-item overflow-item-dashboard', - href: dashUrl, + href: dashUrl + 'dashboard.html', target: '_blank', rel: 'noopener', role: 'menuitem', diff --git a/frontend/packages/agent/src/stats.js b/frontend/packages/agent/src/stats.js index 01c5ee92..b2560e26 100644 --- a/frontend/packages/agent/src/stats.js +++ b/frontend/packages/agent/src/stats.js @@ -403,12 +403,13 @@ window.Chart = Chart; document.getElementById('title').textContent = '◆ ' + s.label + ' ◆'; const dl = document.getElementById('dashboard-link'); // When accessed via hive-gateway the page lives at `/agent//` - // on the same origin as the dashboard (`/`). Detect via path prefix + // on the same origin as the dashboard. Detect via path prefix // rather than the direct port (which is unreachable or wrong scheme - // behind HTTPS TLS termination). + // behind HTTPS TLS termination). The dashboard SPA lives at + // `dashboard.html` — the `/` root now serves the H0M3 menu hub. dl.href = window.location.pathname.startsWith('/agent/') - ? window.location.origin + '/' - : 'http://' + window.location.hostname + ':' + s.dashboard_port + '/'; + ? window.location.origin + '/dashboard.html' + : 'http://' + window.location.hostname + ':' + s.dashboard_port + '/dashboard.html'; } catch (_) { /* non-fatal */ } } diff --git a/frontend/packages/dashboard/build.mjs b/frontend/packages/dashboard/build.mjs index d8a46579..334a3623 100644 --- a/frontend/packages/dashboard/build.mjs +++ b/frontend/packages/dashboard/build.mjs @@ -1,29 +1,38 @@ // esbuild build for @hive/dashboard. Output layout (`dist/`): // -// dist/index.html served by the Rust router at GET / +// dist/index.html H0M3 menu hub — served by the Rust +// router at GET / (the landing page) +// dist/dashboard.html the operator dashboard SPA — served +// at GET /dashboard.html // dist/flow.html served at GET /flow.html // dist/logs.html served at GET /logs.html -// dist/static/tabs.js /index.html entry — tab renderers + +// dist/static/home.js index.html (H0M3) entry — menu tiles + +// matrix-tile gating + identity line +// dist/static/tabs.js dashboard.html entry — tab renderers + // tab routing + refreshState // dist/static/flow.js /flow.html entry — broker terminal + -// operator inbox + @-mention composer +// @-mention composer // dist/static/logs.js /logs.html entry — build/agent/system // log viewer sub-tabs -// dist/static/{tabs,flow,logs}.js.map source map siblings +// dist/static/{home,tabs,flow,logs}.js.map source map siblings // dist/static/common.css loaded by every page (@hive/shared // imports + shared typography/badges/ // buttons/inbox/side-panel) -// dist/static/dashboard.css /index.html only (dashboard-specific) +// dist/static/dashboard.css dashboard.html only (dashboard-specific) // dist/static/flow.css /flow.html only (flow chrome + composer) // dist/static/logs.css /logs.html only (log viewer sub-tabs) +// dist/static/home.css index.html (H0M3) only (tile grid) // -// All three JS entries bundle `./common.js` (DOM helpers, Panel singleton, +// Each JS entry bundles `./common.js` (DOM helpers, Panel singleton, // NOTIF, path linkification) independently — esbuild inlines the shared // module into each bundle rather than emitting a shared chunk (no // `splitting: true`). The Rust binary mounts `dist/` as a -// `tower_http::ServeDir` fallback; the layout above keeps every URL -// the HTML files reference reachable without rewriting paths in the -// HTML. +// `tower_http::ServeDir` fallback (`append_index_html_on_directories` +// serves index.html at /); the layout above keeps every URL the HTML +// files reference reachable without rewriting paths in the HTML. The +// dashboard SPA lives at /dashboard.html (a plain file, not a /dashboard/ +// prefix) so it never shadows the exact-match /dashboard/stream + +// /dashboard/history SSE routes registered before the ServeDir fallback. import { build } from 'esbuild'; import { mkdirSync, copyFileSync, rmSync } from 'node:fs'; @@ -91,7 +100,7 @@ for (const entry of ['theme.css', 'common.css', 'dashboard.css', 'flow.css', 'lo }); } -for (const html of ['index.html', 'flow.html', 'logs.html', 'home.html']) { +for (const html of ['index.html', 'dashboard.html', 'flow.html', 'logs.html']) { copyFileSync(src(html), dist(html)); } diff --git a/frontend/packages/dashboard/src/common.js b/frontend/packages/dashboard/src/common.js index 1f71925b..36c812eb 100644 --- a/frontend/packages/dashboard/src/common.js +++ b/frontend/packages/dashboard/src/common.js @@ -1,4 +1,4 @@ -// Shared dashboard helpers used by both index.html (./tabs.js) and +// Shared dashboard helpers used by both dashboard.html (./tabs.js) and // flow.html (./flow.js): pure DOM helpers, the side-panel singleton, // the OS-notification module, and the path-link / file-preview // infrastructure for the side panel. diff --git a/frontend/packages/dashboard/src/dashboard.css b/frontend/packages/dashboard/src/dashboard.css index efa8ef6e..80c7976b 100644 --- a/frontend/packages/dashboard/src/dashboard.css +++ b/frontend/packages/dashboard/src/dashboard.css @@ -30,6 +30,19 @@ body.dashboard-shell { padding: 0.4em 0 0; margin: 0 -1.5em 1em; } +/* ← home back-link to the H0M3 hub. Small purple link top-left of the + chrome, mirroring the .logs-back treatment the sub-pages use so the + navigation reads consistently. Full chrome unification (a shared, + reusable tab/back-link component) is a later step. */ +.dash-home-back { + display: inline-block; + color: var(--purple); + text-decoration: none; + font-size: 0.82em; + padding: 0.1em 1em 0; + white-space: nowrap; +} +.dash-home-back:hover { text-decoration: underline; } .banner-thin { text-align: center; margin: 0; diff --git a/frontend/packages/dashboard/src/dashboard.html b/frontend/packages/dashboard/src/dashboard.html new file mode 100644 index 00000000..f3e73322 --- /dev/null +++ b/frontend/packages/dashboard/src/dashboard.html @@ -0,0 +1,390 @@ + + + + + + hyperhive // h1ve-c0re + + + + + + + + +
+ + ← home + + + +
+ + +
+ + +
+
+

loading…

+
+
+ + +
+ +

◆ 1NB0X ◆

+
══════════════════════════════════════════════════════════════
+
+

loading…

+
+ +

◆ P3NDING APPR0VALS ◆

+
══════════════════════════════════════════════════════════════
+
+

loading…

+
+ +

◆ M1ND H4S QU3STI0NS ◆

+
══════════════════════════════════════════════════════════════
+
+

loading…

+
+
+ + +
+

◆ M3T4 1NPUTS ◆

+
══════════════════════════════════════════════════════════════
+

select inputs to nix flake update in /meta/. selected agents rebuild in sequence after the lock bump; manager learns each outcome via the usual rebuilt system event.

+
+

loading…

+
+ +

◆ R3BU1LD QU3U3 ◆

+
══════════════════════════════════════════════════════════════
+

pending + running rebuilds, meta-updates, and first-spawns. one runs at a time; meta-update cascades nest under their parent. dedup: re-enqueueing a still-queued op collapses into the existing entry.

+
+

loading…

+
+ +

◆ K3PT ST4T3 ◆

+
══════════════════════════════════════════════════════════════
+
+

loading…

+
+ + +

◆ C0NT41N3R L04D ◆

+
══════════════════════════════════════════════════════════════
+

live cpu + memory per agent container, from cgroup v2 on the host. cpu is % of total host capacity (all cores), sampled over ~200ms each refresh; polled every 5s while this tab is open. network is omitted on purpose — agents share the host netns, so there is no per-container counter (see docs/network.md).

+
+

loading…

+
+ +
+ + +
+

◆ C4P4B1L1T13S ◆

+
══════════════════════════════════════════════════════════════
+

per-agent capability grants. capabilities unlock gated MCP tools and system access. saving queues a rebuild for the affected agent.

+
+

loading…

+
+ + +

◆ T00L GR0UPS ◆

+
══════════════════════════════════════════════════════════════
+

per-agent tool-group permissions. columns are filled from the backend — adding a new group requires no UI change. agents without an explicit entry use the role default (agents: messaging, meta, inbox, execution; manager: all). saving queues a rebuild.

+
+

loading…

+
+
+ + +
+

◆ P33R H1V3S ◆

+
══════════════════════════════════════════════════════════════
+

peer hives in this swarm. click a card to open that hive's dashboard.

+
+

loading…

+
+
+ + +
+

◆ SCH3DUL3S ◆

+
══════════════════════════════════════════════════════════════
+

all schedules currently in the table. fill the bottom row to queue a new schedule (operator-direct, no approval gate; recurring when an interval is set). cancel a single target with the row button or the whole schedule with ✕ cancel all.

+
+

loading…

+
+ + +

◆ QU3U3D R3M1ND3RS ◆

+
══════════════════════════════════════════════════════════════
+

reminders agents have queued for themselves but not yet delivered. cancel to drop a stuck or unwanted entry.

+
+

loading…

+
+
+ + +
+

◆ ST4TS ◆

+
══════════════════════════════════════════════════════════════
+

hive-wide turn statistics, aggregated across every agent over the selected window. cost is a rough estimate from approximate per-model list prices — it drifts and is a ballpark, not a bill.

+
+ + + + + + +
+
+

◇ busiest agents

+

loading…

+

◇ model mix (turns across the swarm)

+
+
+ + + + +
+

◆ S3TT1NGS ◆

+
══════════════════════════════════════════════════════════════
+

operator-local preferences. these live in the browser's localStorage — they do not sync between devices and do not survive a profile wipe.

+ +

◇ browser notifications

+

desktop notifications for new approvals, new operator questions, and broker messages addressed to you. requires a secure context (https or localhost). mute silences the notifications without revoking the OS-level permission.

+
+ + + + +
+
+ +
+ + + + + + + + + + + + + diff --git a/frontend/packages/dashboard/src/flow.html b/frontend/packages/dashboard/src/flow.html index 8535b569..9608204a 100644 --- a/frontend/packages/dashboard/src/flow.html +++ b/frontend/packages/dashboard/src/flow.html @@ -11,12 +11,12 @@ - +
- ← dashboard + ← home FL0W