Y3R C4LL is the operator inbox alone: no P3NDING APPR0VALS section, no approval cards or history, no approval_resolved subscription, no approval browser notifications, and the tab count and title prefix count unread operator messages only. The H0M3 tile text drops "approvals". The deny form was the only data-prompt form, so bindAsyncForms' prompt branch, themedPrompt and its dialog styles go too, along with the approval-only CSS (.approval*, .approvals-history, .btn-deny, the status/glyph colours and .history-note).
374 lines
16 KiB
HTML
374 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: read-only scheduled-prompts list. 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 the other standalone pages are reachable from
|
|
the H0M3 hub (served at /), not from the dashboard tab strip —
|
|
the strip holds only in-page tabs. Contextual deep-links into
|
|
the log viewer (an agent's logs, a build entry's log) live
|
|
inside the relevant dashboard content. -->
|
|
</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>
|
|
<!-- JobqRollup mount point, kept outside #containers-section
|
|
deliberately — that section is wiped + rebuilt on every
|
|
container-list render (see swarm.js::renderContainers), which
|
|
would tear down and remount the Preact tree on every
|
|
container-state tick. Mounted once by swarm.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>
|
|
|
|
<!-- Y3R C4LL: things blocked on operator decision — the operator
|
|
inbox; surfaces 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>
|
|
|
|
<!-- Operator-local preferences (browser notifications). Was its own
|
|
S3TT1NGS page (`/settings.html`); mara moved it in here since a
|
|
standalone page for one toggle didn't earn its own tile. State
|
|
lives in the browser's localStorage — NOTIF.bind() (common.js)
|
|
wires the buttons, same dispatch NOTIF.show() already used for
|
|
inbox notifications above. -->
|
|
<h2>◆ PR3F3R3NC3S ◆</h2>
|
|
<div class="divider">
|
|
══════════════════════════════════════════════════════════════
|
|
</div>
|
|
<p class="meta">
|
|
operator-local preferences. these live in the browser's localStorage
|
|
— they do not sync between devices and do not survive a profile
|
|
wipe.
|
|
</p>
|
|
<h3>◇ browser notifications</h3>
|
|
<p class="meta">
|
|
desktop notifications for broker messages addressed to you. requires
|
|
a secure context (https or localhost). mute silences the
|
|
notifications without revoking the OS-level permission.
|
|
</p>
|
|
<div id="notif-row" class="notif-row">
|
|
<button
|
|
type="button"
|
|
id="notif-enable"
|
|
class="btn btn-notif"
|
|
hidden
|
|
>
|
|
🔔 enable notifications
|
|
</button>
|
|
<button type="button" id="notif-mute" class="btn btn-notif" hidden>
|
|
🔕 mute
|
|
</button>
|
|
<button
|
|
type="button"
|
|
id="notif-unmute"
|
|
class="btn btn-notif"
|
|
hidden
|
|
>
|
|
🔔 unmute
|
|
</button>
|
|
<span id="notif-status" class="meta" hidden></span>
|
|
</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: read-only list of the scheduled prompts left in the
|
|
hive's store, driven by GET /api/schedules (re-fetched on tab
|
|
activation). Nothing on the hive fires them; the banner points
|
|
at `swarmctl schedule`, where schedules live now.
|
|
See docs/web-ui/dashboard.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="server-warn server-warn-warn" role="note">
|
|
⚠ this page is slated for removal. the hive no longer fires these
|
|
schedules — they live at swarm level now: recreate each one with
|
|
<code>swarmctl schedule add</code> (see
|
|
<code>docs/swarm/schedules.md</code>).
|
|
</p>
|
|
<p class="meta">
|
|
read-only: every schedule still in the hive's table, kept so it can
|
|
be copied over.
|
|
</p>
|
|
<div id="schedules-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`). -->
|
|
</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 (clicked file previews, journald logs,
|
|
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>
|