dashboard: serve the dashboard at /, fold kept state in as a tab, add a pages menu
Drop the H0M3 tile hub and the core page. The dashboard is now the index; kept state is its fifth tab. A pages menu in the chrome links flow, stats, API docs and the swarm UI. The swarm apex URL comes from services.hyperhive.swarm.domain via HIVE_SWARM_PUBLIC_URL and the new swarm_public_url field of the state snapshot.
This commit is contained in:
parent
265f8a47cc
commit
0622736b30
35 changed files with 661 additions and 986 deletions
|
|
@ -3,90 +3,277 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>hyperhive // h0m3</title>
|
||||
<title>hyperhive // h1ve-c0re</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="stylesheet" href="/static/colors.css" />
|
||||
<link rel="stylesheet" href="/static/theme.css" />
|
||||
<link rel="stylesheet" href="/static/common.css" />
|
||||
<link rel="stylesheet" href="/static/home.css" />
|
||||
<link rel="stylesheet" href="/static/dashboard.css" />
|
||||
</head>
|
||||
<body class="home-shell">
|
||||
<!-- Decorative matrix-rain backdrop: a dimmed full-viewport canvas of
|
||||
falling glyphs behind everything (home.js drives it). aria-hidden +
|
||||
pointer-events:none so it's purely cosmetic; glyph/bg colours are
|
||||
read from the stylix palette at runtime so a theme swap re-colours
|
||||
it, and it's disabled under prefers-reduced-motion. -->
|
||||
<canvas id="matrix-rain" aria-hidden="true"></canvas>
|
||||
<body class="dashboard-shell">
|
||||
<!-- Sticky chrome — just the tab strip. The "WE ARE THE WIRED"
|
||||
slug lives at the page footer below `<main>`; chrome is
|
||||
navigation only. Tabs route via the URL hash so F5 / back-
|
||||
button / shared links keep you on the same view. JS owns
|
||||
the show/hide. -->
|
||||
<header class="dashboard-chrome">
|
||||
<!-- Pages menu: the standalone pages (flow, stats, API docs) and the
|
||||
swarm UI. Filled by links-menu.js from /api/state. The pages link
|
||||
back to `/`, which is this dashboard. -->
|
||||
<div class="links-menu" id="links-menu"></div>
|
||||
<nav class="tabbar" id="tabbar" role="tablist">
|
||||
<a
|
||||
class="tab"
|
||||
id="tab-agents"
|
||||
href="#agents"
|
||||
role="tab"
|
||||
aria-controls="tab-pane-agents"
|
||||
data-tab="agents"
|
||||
>
|
||||
<span class="tab-label">◆ 4G3NTS ◆</span>
|
||||
<span class="tab-count" id="tab-count-agents" hidden></span>
|
||||
</a>
|
||||
<!-- The build lifecycle is three tabs here (builds.js): the rebuild
|
||||
queue with its live log, the meta flake inputs, and the build log
|
||||
history. Kept state (kept.js) is the fourth. -->
|
||||
<a
|
||||
class="tab"
|
||||
id="tab-rebuild"
|
||||
href="#rebuild"
|
||||
role="tab"
|
||||
aria-controls="tab-pane-rebuild"
|
||||
data-tab="rebuild"
|
||||
>
|
||||
<span class="tab-label">◆ R3BU1LD QU3U3 ◆</span>
|
||||
<span class="tab-count" id="tab-count-rebuild" hidden></span>
|
||||
</a>
|
||||
<a
|
||||
class="tab"
|
||||
id="tab-meta"
|
||||
href="#meta"
|
||||
role="tab"
|
||||
aria-controls="tab-pane-meta"
|
||||
data-tab="meta"
|
||||
>
|
||||
<span class="tab-label">◆ M3T4 1NPUTS ◆</span>
|
||||
</a>
|
||||
<a
|
||||
class="tab"
|
||||
id="tab-buildlogs"
|
||||
href="#buildlogs"
|
||||
role="tab"
|
||||
aria-controls="tab-pane-buildlogs"
|
||||
data-tab="buildlogs"
|
||||
>
|
||||
<span class="tab-label">◆ BUILD L0GS ◆</span>
|
||||
</a>
|
||||
<a
|
||||
class="tab"
|
||||
id="tab-kept"
|
||||
href="#kept"
|
||||
role="tab"
|
||||
aria-controls="tab-pane-kept"
|
||||
data-tab="kept"
|
||||
>
|
||||
<span class="tab-label">◆ K3PT ST4T3 ◆</span>
|
||||
<span class="tab-count" id="tab-count-kept" hidden></span>
|
||||
</a>
|
||||
|
||||
<!-- H0M3: the menu hub. A plain grid of links to every top-level
|
||||
surface. This is the page served at `/` — the landing page — with
|
||||
the dashboard relocated to /dashboard.html. No tabbar / SSE —
|
||||
it's a static portal. -->
|
||||
<!-- (Peer hives are no longer a tab — they render as a headline
|
||||
under 4G3NTS. See tab-pane-agents.) -->
|
||||
|
||||
<!-- FL0W and ST4TS are standalone pages reached from the pages
|
||||
menu at the left of this strip, not tabs — the strip holds only
|
||||
in-page tabs. -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Tab panes. createTabStrip (@hive/shared/tabs.js) keeps exactly one
|
||||
visible by toggling the `hidden` attribute, resolved from the URL
|
||||
hash (default 4G3NTS). Panes start `hidden` to avoid a flash before
|
||||
the script runs. -->
|
||||
<!-- Padded content wrapper: carries the 1.5em side gutter
|
||||
(.page-content, common.css) while <body> stays full-bleed so the
|
||||
server-warnings banner spans the full width. -->
|
||||
sticky chrome above + the footer below span the full width. -->
|
||||
<div class="page-content">
|
||||
<header class="home-header">
|
||||
<p class="banner-thin" id="hive-identity" hidden></p>
|
||||
<pre class="banner">
|
||||
░▒▓█▓▒░ ░▒▓█▓▒░ H Y P E R H I V E · H0M3 ░▒▓█▓▒░ ░▒▓█▓▒░</pre
|
||||
<main class="dashboard-main">
|
||||
<!-- 4G3NTS: the agents. Container cards (the central thing
|
||||
the operator looks at) and rebuild queue / cascade visualisation
|
||||
that drives them. No inline `C0NTAINERS` h2 heading + divider
|
||||
— the tab label 4G3NTS already says it. -->
|
||||
<section
|
||||
class="tab-pane"
|
||||
id="tab-pane-agents"
|
||||
data-tab-pane="agents"
|
||||
hidden
|
||||
role="tabpanel"
|
||||
aria-labelledby="tab-agents"
|
||||
>
|
||||
<p class="banner-thin" id="hive-rev" hidden></p>
|
||||
</header>
|
||||
<!-- Swarm / hive identity headline. Populated by refreshState from
|
||||
hive_name + swarm_name; stays hidden when neither is set. -->
|
||||
<h2 id="swarm-identity" hidden></h2>
|
||||
<!-- JobqRollup mount point, kept outside #containers-section
|
||||
deliberately — that section is wiped + rebuilt on every
|
||||
container-list render (see agents.js::renderContainers), which
|
||||
would tear down and remount the Preact tree on every
|
||||
container-state tick. Mounted once by agents.js::initJobqRollup,
|
||||
refreshed via its own handle rather than by re-rendering. -->
|
||||
<div id="jobq-rollup-section"></div>
|
||||
<div id="containers-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<main class="home-main">
|
||||
<nav class="home-menu" aria-label="hyperhive surfaces">
|
||||
<a class="home-tile" href="/dashboard.html">
|
||||
<span class="home-tile-head">
|
||||
<span class="home-tile-icon" aria-hidden="true">🖥</span>
|
||||
<span class="home-tile-label">Dashboard</span>
|
||||
</span>
|
||||
<span class="home-tile-desc">containers · builds</span>
|
||||
</a>
|
||||
<!-- R3BU1LD QU3U3: pending + running rebuilds, meta-updates, and
|
||||
first-spawns. Rendered from GET /api/jobq/graph by the
|
||||
`JobqGraph` Preact component (@hive/shared/jobq-graph.js);
|
||||
`rebuild_queue_changed` over /api/dashboard/stream is the
|
||||
refresh trigger and carries no payload of its own. -->
|
||||
<section
|
||||
class="tab-pane"
|
||||
id="tab-pane-rebuild"
|
||||
data-tab-pane="rebuild"
|
||||
hidden
|
||||
role="tabpanel"
|
||||
aria-labelledby="tab-rebuild"
|
||||
>
|
||||
<p class="meta">
|
||||
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.
|
||||
</p>
|
||||
<div id="rebuild-queue-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
<!-- Live build log of the currently-running rebuild (one runs at a
|
||||
time). Managed by renderRebuildLiveLog in builds.js, separate from
|
||||
rebuild-queue-section so the queue's row re-render never disturbs
|
||||
the open poll. -->
|
||||
<div id="rebuild-live-log" class="rebuild-live-log" hidden></div>
|
||||
</section>
|
||||
|
||||
<a class="home-tile" href="/flow.html">
|
||||
<span class="home-tile-head">
|
||||
<span class="home-tile-icon" aria-hidden="true">📡</span>
|
||||
<span class="home-tile-label">Flow</span>
|
||||
</span>
|
||||
<span class="home-tile-desc">live all-agents message firehose</span>
|
||||
</a>
|
||||
<!-- M3T4 1NPUTS: select inputs to nix flake update in /meta/. -->
|
||||
<section
|
||||
class="tab-pane"
|
||||
id="tab-pane-meta"
|
||||
data-tab-pane="meta"
|
||||
hidden
|
||||
role="tabpanel"
|
||||
aria-labelledby="tab-meta"
|
||||
>
|
||||
<p class="meta">
|
||||
select inputs to <code>nix flake update</code> in
|
||||
<code>/meta/</code>. selected agents rebuild in sequence after the
|
||||
lock bump; the submitting agent learns each outcome via the usual
|
||||
<code>rebuilt</code> system event.
|
||||
</p>
|
||||
<div id="meta-inputs-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<a class="home-tile" href="/stats.html">
|
||||
<span class="home-tile-head">
|
||||
<span class="home-tile-icon" aria-hidden="true">📊</span>
|
||||
<span class="home-tile-label">Stats</span>
|
||||
</span>
|
||||
<span class="home-tile-desc"
|
||||
>hive-wide turn stats · cost · model mix</span
|
||||
>
|
||||
</a>
|
||||
<!-- BUILD L0GS: all-agents build log history. Click a row to expand
|
||||
stdout + stderr. Live builds stream in real time. Lazy-loaded the
|
||||
first time the tab is shown; auto-refreshes when
|
||||
rebuild_queue_changed fires. Deep-link: ?id=N#buildlogs. -->
|
||||
<section
|
||||
class="tab-pane"
|
||||
id="tab-pane-buildlogs"
|
||||
data-tab-pane="buildlogs"
|
||||
hidden
|
||||
role="tabpanel"
|
||||
aria-labelledby="tab-buildlogs"
|
||||
>
|
||||
<p class="meta">
|
||||
all-agents build log history. click a row to expand stdout + stderr.
|
||||
live builds stream in real time.
|
||||
</p>
|
||||
<div class="logs-toolbar">
|
||||
<button type="button" class="btn btn-restart" id="build-refresh">
|
||||
↻ refresh
|
||||
</button>
|
||||
</div>
|
||||
<div id="build-list"><p class="meta">loading…</p></div>
|
||||
</section>
|
||||
|
||||
<a class="home-tile" href="/core.html">
|
||||
<span class="home-tile-head">
|
||||
<span class="home-tile-icon" aria-hidden="true">⬡</span>
|
||||
<span class="home-tile-label">Core</span>
|
||||
</span>
|
||||
<span class="home-tile-desc">kept state</span>
|
||||
</a>
|
||||
<!-- K3PT ST4T3: kept state from agents whose container is absent,
|
||||
with a purge button per row. Rendered by kept.js; refreshed by the
|
||||
`tombstones_changed` stream event. -->
|
||||
<section
|
||||
class="tab-pane"
|
||||
id="tab-pane-kept"
|
||||
data-tab-pane="kept"
|
||||
hidden
|
||||
role="tabpanel"
|
||||
aria-labelledby="tab-kept"
|
||||
>
|
||||
<p class="meta">
|
||||
kept state from previously tombstoned agents — recreating an agent
|
||||
with the same name reuses it.
|
||||
</p>
|
||||
<div id="tombstones-section">
|
||||
<p class="meta">loading…</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- API tile: the OpenAPI spec + Swagger UI are always served by
|
||||
hive-c0re itself (docs/web-ui/dashboard.md::Dashboard
|
||||
endpoints), so this tile is never gated/hidden. -->
|
||||
<a class="home-tile" href="/api/docs">
|
||||
<span class="home-tile-head">
|
||||
<span class="home-tile-icon" aria-hidden="true">🧬</span>
|
||||
<span class="home-tile-label">API</span>
|
||||
</span>
|
||||
<span class="home-tile-desc"
|
||||
>interactive OpenAPI spec (Swagger UI)</span
|
||||
>
|
||||
</a>
|
||||
</nav>
|
||||
<!-- ST4TS and FL0W live on their own pages (`/stats.html`,
|
||||
`/flow.html`). Their DOM only exists there — when tabs.js boots
|
||||
on this page the corresponding renderers no-op silently (each
|
||||
guard is `if (!el) return`). -->
|
||||
</main>
|
||||
</div>
|
||||
<!-- /.page-content -->
|
||||
|
||||
<script type="module" src="/static/home.js" defer></script>
|
||||
<footer>
|
||||
<pre class="banner banner-thin">
|
||||
░▒▓█▓▒░ HYPERHIVE / HIVE-C0RE / WE ARE THE WIRED ░▒▓█▓▒░</pre
|
||||
>
|
||||
<div class="divider">
|
||||
══════════════════════════════════════════════════════════════
|
||||
</div>
|
||||
<p>
|
||||
▲△▲
|
||||
<a href="https://forge.darkest.space/hyperhive/hyperhive">hyperhive</a>
|
||||
▲△▲ hive-c0re on this host ▲△▲
|
||||
</p>
|
||||
<!-- Short build id of the running hive; filled from hyperhive_rev. -->
|
||||
<p class="meta" id="hive-rev" hidden></p>
|
||||
</footer>
|
||||
|
||||
<!-- Slide-in detail panel (clicked file previews, applied config)
|
||||
is a <hive-side-panel> element
|
||||
(@hive/shared/side-panel.js) — the Panel singleton in common.js
|
||||
creates + appends it to <body> lazily on first use, so nothing
|
||||
needs to be pre-declared here. -->
|
||||
|
||||
<!-- Selection action bar. Sticky-bottom strip that slides into
|
||||
view when one or more agent cards is selected (click the icon
|
||||
to toggle). See docs/web-ui/dashboard.md::Selection bar for the bulk
|
||||
action gating + clear semantics. -->
|
||||
<div
|
||||
id="selection-bar"
|
||||
class="selection-bar"
|
||||
hidden
|
||||
role="toolbar"
|
||||
aria-label="bulk agent actions"
|
||||
>
|
||||
<span class="selection-count" id="selection-count"></span>
|
||||
<span class="selection-names" id="selection-names"></span>
|
||||
<span class="selection-actions" id="selection-actions"></span>
|
||||
<button
|
||||
type="button"
|
||||
class="btn selection-clear"
|
||||
id="selection-clear"
|
||||
title="clear selection (esc)"
|
||||
>
|
||||
✕ clear
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Single bundled entry — tabs.js is the dashboard tabs surface;
|
||||
flow.html has its own flow.js bundle. esbuild folds
|
||||
@hive/shared/terminal.js and the marked npm package into
|
||||
tabs.js. -->
|
||||
<script type="module" src="/static/tabs.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in a new issue