Phase 1 of stylix integration (#1457): extract the Catppuccin palette into a dedicated, separately-linked stylesheet so a theme swap can replace just that file without rebuilding the rest of the frontend. - shared/src/theme.css (new): the `:root` palette, moved out of base.css (which now holds only the body typography it references). - shared/package.json: export `./theme.css`. - dashboard/src/theme.css + agent/src/theme.css (new): one-line re-exports of @hive/shared/theme.css so each package's esbuild emits its own standalone `dist/static/theme.css` (palette is NOT inlined into the page bundles). - both build.mjs: add theme.css to the CSS build list. - every page (dashboard index/flow/logs, agent index/stats/screen): link `theme.css` first, ahead of the page CSS, so the `:root` vars resolve for everything. - docs/web-ui/css-vars.md: document the split + the no-rebuild rationale. Behaviour-neutral — same colours, just relocated. Verified both `npm run build` outputs: theme.css emits standalone (383b) with the palette; no `--*` palette defs duplicated into common.css/agent.css. Phase 2 (nix derivation that swaps theme.css from stylix colours) is a follow-up; touches nix/frontend.nix, coordinating with damocles. Part of #1457.
114 lines
5.5 KiB
HTML
114 lines
5.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>hyperhive agent</title>
|
|
<link rel="icon" type="image/svg+xml" href="icon">
|
|
<link rel="stylesheet" href="static/theme.css">
|
|
<link rel="stylesheet" href="static/agent.css">
|
|
</head>
|
|
<body class="agent-shell">
|
|
|
|
<!-- Fixed-overlay header — see docs/web-ui.md::Per-agent page
|
|
for the three-column layout (icon · main · pills). All asset
|
|
/ API hrefs are relative — see docs/web-ui.md::Per-agent
|
|
relative paths for the document-baseURI resolution model. -->
|
|
<header class="agent-header" id="agent-header">
|
|
<img class="agent-icon" src="icon" alt="">
|
|
|
|
<div class="agent-header-main">
|
|
<div class="agent-header-row agent-header-title-row">
|
|
<h2 id="title">◆ … ◆</h2>
|
|
<!-- Meta-nav: backend-supplied links (stats / screen / forge /
|
|
…) plus a client-injected `↑ dashboard` link prepended in
|
|
setHeader so the host dashboard stays one click away
|
|
without a separate button styled differently. -->
|
|
<nav class="meta agent-nav" id="meta-links"></nav>
|
|
</div>
|
|
|
|
<!-- Hive identity line: "swarm / hive" label. Hidden until JS
|
|
populates it from /api/state (hive_name + swarm_name). -->
|
|
<div class="agent-header-row agent-hive-row">
|
|
<span class="agent-hive-label" hidden></span>
|
|
</div>
|
|
|
|
<div id="state-row" class="agent-state-row agent-header-row">
|
|
<span id="alive-badge" class="status-badge status-loading" title="harness reachability">…</span>
|
|
<span id="state-badge" class="state-badge state-loading">… booting</span>
|
|
<span id="model-chip" class="model-chip" hidden></span>
|
|
<span id="ctx-badge" class="ctx-badge" hidden title="tokens used in the current context window"></span>
|
|
<span id="cost-badge" class="ctx-badge" hidden title="cumulative tokens billed across the last turn (sum across every inference; tool-heavy turns rebill the cached prompt per call)"></span>
|
|
<span id="last-turn" class="last-turn" hidden></span>
|
|
<button type="button" id="cancel-btn" class="btn-cancel-turn" hidden>■ cancel turn</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right cluster: flyout triggers + overflow menu. Pills stay
|
|
hidden until their list is non-empty; the overflow `⋯` is
|
|
always visible. Rebuild + new-session + logout live inside
|
|
it — see docs/web-ui.md::Per-agent page (Overflow button)
|
|
for the rare-destructive-extra-click rationale. -->
|
|
<div class="agent-header-pills">
|
|
<button type="button" id="inbox-pill" class="header-pill header-pill-inbox" hidden
|
|
title="open inbox flyout">
|
|
<span class="header-pill-icon" aria-hidden="true">📬</span>
|
|
<span class="header-pill-label">inbox</span>
|
|
<span class="header-pill-count" id="inbox-count">0</span>
|
|
</button>
|
|
<button type="button" id="loose-ends-pill" class="header-pill header-pill-loose" hidden
|
|
title="open loose-ends flyout">
|
|
<span class="header-pill-icon" aria-hidden="true">🪢</span>
|
|
<span class="header-pill-label">loose ends</span>
|
|
<span class="header-pill-count" id="loose-ends-count">0</span>
|
|
</button>
|
|
<button type="button" id="overflow-btn" class="overflow-btn"
|
|
aria-haspopup="menu" aria-expanded="false"
|
|
title="more actions">⋯</button>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Overflow popover. Sits outside the header so the header's
|
|
`overflow: hidden`-adjacent ancestors don't clip it; positioned
|
|
in JS relative to the overflow button (top-right anchor). -->
|
|
<div id="overflow-menu" class="overflow-menu" role="menu" hidden></div>
|
|
|
|
<!-- Main content area. The terminal fills it edge-to-edge and
|
|
scrolls behind the floating header + composer. The `#status`
|
|
overlay renders only when login is required (transient first-
|
|
time-setup state); otherwise the terminal owns the screen. -->
|
|
<main class="agent-main" id="agent-main">
|
|
<div id="status" class="agent-status-overlay"></div>
|
|
<div class="terminal-wrap">
|
|
<div id="live" class="live terminal"><div class="meta">connecting…</div></div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Fixed-overlay composer. Same frosted-glass treatment as the
|
|
header for symmetric framing. Empty until the harness sets up
|
|
the textarea via `renderTermInput`. -->
|
|
<footer class="agent-composer" id="agent-composer">
|
|
<div id="term-input" class="term-input"></div>
|
|
</footer>
|
|
|
|
<!-- Slide-in side panel. Singleton — JS swaps the title + body
|
|
and toggles `.open`. Shared shape with the dashboard's panel
|
|
(candidate for extraction into @hive/shared in a follow-up). -->
|
|
<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>
|
|
|
|
<!-- Single bundled entry. esbuild folds @hive/shared/terminal.js and
|
|
the marked npm package into app.js. -->
|
|
<script type="module" src="static/app.js" defer></script>
|
|
</body>
|
|
</html>
|