The save-all change updated the visible copy + the JS but left this HTML
pane comment describing the old per-row "POSTs to the respective /{agent}
endpoint" flow. Correct it to the page-level save-all → POST /api/permissions
batch (caps + groups coalesce into one rebuild per agent). Comment-only.
287 lines
16 KiB
HTML
287 lines
16 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<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/dashboard.css">
|
||
</head>
|
||
<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">
|
||
<!-- Back to the H0M3 menu hub (served at /). Sub-pages and the
|
||
dashboard all link back to the landing page rather than to each
|
||
other — H0M3 is the single navigation hub. -->
|
||
<a class="dash-home-back" href="/" title="back to the H0M3 menu">← home</a>
|
||
<nav class="tabbar" id="tabbar" role="tablist">
|
||
<a class="tab" id="tab-swarm" href="#swarm" role="tab"
|
||
aria-controls="tab-pane-swarm"
|
||
data-tab="swarm">
|
||
<span class="tab-label">◆ SW4RM ◆</span>
|
||
<span class="tab-count" id="tab-count-swarm" hidden></span>
|
||
</a>
|
||
<a class="tab" id="tab-call" href="#call" role="tab"
|
||
aria-controls="tab-pane-call"
|
||
data-tab="call">
|
||
<span class="tab-label">◆ Y3R C4LL ◆</span>
|
||
<span class="tab-count tab-count-attn" id="tab-count-call" hidden></span>
|
||
</a>
|
||
<!-- SYST3M moved to its own standalone page (/core.html, "C0R3"),
|
||
reached from the H0M3 hub — keeps the dashboard tab strip lean.
|
||
The rebuild-queue STATE still lives in tabs.js (it drives the
|
||
"building…" badges on SW4RM agent cards); only the SYST3M tab +
|
||
its section renderers moved out. -->
|
||
<!-- P3RM1SS10NS: per-agent capability grants and tool-group
|
||
assignments. Both tables are fetched on tab activation. -->
|
||
<a class="tab" id="tab-permissions" href="#permissions" role="tab"
|
||
aria-controls="tab-pane-permissions"
|
||
data-tab="permissions">
|
||
<span class="tab-label">◆ P3RM1SS10NS ◆</span>
|
||
</a>
|
||
|
||
<!-- SCH3DUL3S: scheduled-prompts surface. List of queued
|
||
schedules + an operator-direct creation form. Count pill
|
||
mirrors the active (non-cancelled) schedule count; hidden
|
||
when zero. -->
|
||
<a class="tab" id="tab-schedules" href="#schedules" role="tab"
|
||
aria-controls="tab-pane-schedules"
|
||
data-tab="schedules">
|
||
<span class="tab-label">◆ SCH3DUL3S ◆</span>
|
||
<span class="tab-count" id="tab-count-schedules" hidden></span>
|
||
</a>
|
||
|
||
<!-- ST4TS lives on its own page now (`/stats.html`), reached from
|
||
the H0M3 hub — the hive-wide rollup is a standalone read-only
|
||
view, not part of the operational tab strip. -->
|
||
|
||
<!-- (Peer hives are no longer a tab — they render as a headline
|
||
under SW4RM. See tab-pane-swarm.) -->
|
||
|
||
<!-- FL0W, L0GS, and M4TR1X are separate pages reachable from the
|
||
H0M3 hub (served at /), not from the dashboard tab strip — the
|
||
strip holds only real in-page tabs now. Contextual deep-links
|
||
into the log viewer (an agent's logs, a build entry's log)
|
||
still live inside the relevant dashboard content. -->
|
||
|
||
<!-- S3TT1NGS lives on its own page now (`/settings.html`), reached
|
||
from the H0M3 hub — operator-local prefs don't need a slot in
|
||
the operational tab strip. -->
|
||
</nav>
|
||
</header>
|
||
|
||
<!-- Tab panes. createTabStrip (@hive/shared/tabs.js) keeps exactly one
|
||
visible by toggling the `hidden` attribute, resolved from the URL
|
||
hash (default SW4RM). 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
|
||
sticky chrome above + the footer below span the full width. -->
|
||
<div class="page-content">
|
||
<main class="dashboard-main">
|
||
|
||
<!-- SW4RM: the swarm itself. 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 SW4RM already says it. -->
|
||
<section class="tab-pane" id="tab-pane-swarm" data-tab-pane="swarm" hidden
|
||
role="tabpanel" aria-labelledby="tab-swarm">
|
||
<!-- Swarm / hive identity headline. Populated by refreshState from
|
||
hive_name + swarm_name; stays hidden when neither is set. -->
|
||
<h2 id="swarm-identity" hidden></h2>
|
||
<div id="containers-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
<!-- Peer hives (federated swarms). The headline block is hidden
|
||
entirely when nothing is federated; renderPeerHives then drops
|
||
a quiet "no peer hives configured" note into #peers-section. -->
|
||
<div id="peers-block" hidden>
|
||
<h2>◆ P33R H1V3S ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<p class="meta">peer hives in this swarm. click a card to open that hive's dashboard.</p>
|
||
</div>
|
||
<div id="peers-section"></div>
|
||
</section>
|
||
|
||
<!-- Y3R C4LL: things blocked on operator decision. Approvals +
|
||
questions read as the same concept ("something is waiting on
|
||
you"); both surface their full bodies inline so the operator
|
||
can decide without leaving the pane. -->
|
||
<section class="tab-pane" id="tab-pane-call" data-tab-pane="call" hidden
|
||
role="tabpanel" aria-labelledby="tab-call">
|
||
<!-- 1NB0X: unread agent→operator messages. Fetched on
|
||
tab activation + cold load, appended live from the broker
|
||
stream, cleared via "mark all read". Count folds into the
|
||
Y3R C4LL pill so messages aren't missed. -->
|
||
<h2>◆ 1NB0X ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<div id="operator-inbox-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
|
||
<h2>◆ P3NDING APPR0VALS ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<div id="approvals-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
|
||
<h2>◆ M1ND H4S QU3STI0NS ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<div id="questions-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SYST3M pane moved to /core.html (the standalone "C0R3" page):
|
||
meta inputs, rebuild queue, kept state, container load. Reached
|
||
from the H0M3 hub. -->
|
||
|
||
<!-- P3RM1SS10NS: per-agent capability grants + tool-group
|
||
assignments. Both tables are column-driven from the backend
|
||
(GET /api/capabilities, GET /api/tool-groups) so new entries
|
||
require no UI change. Edits stage in-browser across both
|
||
matrices; the single page-level "save all" button POSTs every
|
||
changed agent to /api/permissions in one atomic batch (caps +
|
||
groups coalesce into one rebuild per agent). -->
|
||
<section class="tab-pane" id="tab-pane-permissions" data-tab-pane="permissions" hidden
|
||
role="tabpanel" aria-labelledby="tab-permissions">
|
||
<h2>◆ C4P4B1L1T13S ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<p class="meta">per-agent capability grants. capabilities unlock gated MCP tools and system access. toggle any cells across both tables, then hit "save all" at the bottom — each changed agent rebuilds exactly once.</p>
|
||
<div id="capabilities-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
|
||
<!-- T00L GR0UPS: per-agent tool-group permission matrix. Rows = agents,
|
||
cols = tool groups fetched from GET /api/tool-groups.
|
||
Checking / unchecking is staged in the UI; the single page-level
|
||
"save all" button POSTs every changed agent to
|
||
/api/permissions in one atomic batch, coalescing caps + groups
|
||
per agent into one rebuild each.
|
||
Absent agents default to the role default (shown in parens). -->
|
||
<h2>◆ T00L GR0UPS ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<p class="meta">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).</p>
|
||
<div id="tool-groups-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
|
||
<!-- Page-level save bar (save-all issue): one button for the whole
|
||
permissions page. Staged checkbox edits across BOTH matrices are
|
||
diffed against their render-time baselines and POSTed together to
|
||
/api/permissions; caps + groups for one agent coalesce into a
|
||
single rebuild. Disabled until something is dirty. The atomic
|
||
batch either fully lands (queued ✓ → rebuilding) or fully fails
|
||
(error note, nothing applied). -->
|
||
<div class="perm-save-bar">
|
||
<button type="button" id="perm-save-all" class="btn btn-approve" disabled>save all</button>
|
||
<span id="perm-save-note" class="meta"></span>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- SCH3DUL3S: scheduled prompts. Creation + edit are folded
|
||
into the same table — empty bottom row is the create form
|
||
(fill cells, click +), inline-edit-row expands on the `✎`
|
||
toggle for existing schedules. Schedules list driven by
|
||
GET /api/schedules; POST /api/schedules to create, PATCH
|
||
/api/schedules/{id} to edit, POST /api/schedules/{id}/cancel
|
||
for per-target / whole-row cancel. Live updates via
|
||
`schedules_changed` SSE; tab activation re-fetches as a
|
||
safety net for disconnect windows.
|
||
See docs/web-ui.md::SCH3DUL3S tab. -->
|
||
<section class="tab-pane" id="tab-pane-schedules" data-tab-pane="schedules" hidden
|
||
role="tabpanel" aria-labelledby="tab-schedules">
|
||
<h2>◆ SCH3DUL3S ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<p class="meta">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 <code>✕ cancel all</code>.</p>
|
||
<div id="schedules-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
|
||
<!-- QU3U3D R3M1ND3RS: self-scheduled agent reminders. Lives
|
||
on this tab so the operator has one place for everything
|
||
that fires at a future time — operator-set schedules
|
||
above, agent-self reminders here. Backed by GET
|
||
/api/reminders; live updates via `reminders_changed` SSE;
|
||
refreshReminders() called from refreshState + tab
|
||
activation as safety net for disconnect windows. -->
|
||
<h2>◆ QU3U3D R3M1ND3RS ◆</h2>
|
||
<div class="divider">══════════════════════════════════════════════════════════════</div>
|
||
<p class="meta">reminders agents have queued for themselves but not yet delivered. cancel to drop a stuck or unwanted entry.</p>
|
||
<div id="reminders-section">
|
||
<p class="meta">loading…</p>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ST4TS: hive-wide turn-stats aggregate lives on its own page now
|
||
(`/stats.html`), reached from the H0M3 hub. The markup + the
|
||
hive-stats render JS moved there; when tabs.js boots on the
|
||
dashboard the renderers are simply gone (no stats tab to
|
||
activate). -->
|
||
|
||
<!-- FL0W: lives on its own page now (`/flow.html`). The
|
||
message-flow + inbox + compose DOM only exists there — when
|
||
tabs.js boots on this page the corresponding renderers
|
||
no-op silently (each guard is `if (!el) return`). -->
|
||
|
||
<!-- S3TT1NGS: operator-local preferences (browser-notification
|
||
toggle) live on their own page now (`/settings.html`), reached
|
||
from the H0M3 hub. The notif buttons moved there verbatim;
|
||
`NOTIF.show()` on this page still fires (it reads the same
|
||
localStorage + browser permission the settings page sets). -->
|
||
|
||
</main>
|
||
</div><!-- /.page-content -->
|
||
|
||
<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>
|
||
</footer>
|
||
|
||
<!-- Slide-in detail panel. Long content (clicked file previews,
|
||
approval diffs, journald logs, applied config) opens here
|
||
instead of expanding inline. Singleton — JS swaps the title +
|
||
body and toggles `.open`. Lives outside the tab panes so it
|
||
overlays any active tab. -->
|
||
<div id="side-panel" class="side-panel" aria-hidden="true">
|
||
<div class="side-panel-backdrop" id="side-panel-backdrop"></div>
|
||
<aside class="side-panel-drawer" role="dialog" aria-modal="true"
|
||
aria-labelledby="side-panel-title">
|
||
<header class="side-panel-head">
|
||
<span class="side-panel-title" id="side-panel-title"></span>
|
||
<button type="button" class="side-panel-close" id="side-panel-close"
|
||
title="close (esc)">✕</button>
|
||
</header>
|
||
<div class="side-panel-body" id="side-panel-body"></div>
|
||
</aside>
|
||
</div>
|
||
|
||
<!-- 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.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>
|