#406 was the JS-split refactor: pull shared helpers into common.js (step 1), pull the flow-only IIFEs into flow.js (step 2), then rename the legacy combined entry from app.js to tabs.js (step 3 — this commit) to reflect that the bundle now owns the dashboard tabs surface only. What moved: - `frontend/packages/dashboard/src/app.js` → `tabs.js` - `build.mjs` entry: `src('app.js')` → `src('tabs.js')`; output is now `static/tabs.js` - `index.html` `<script>` src: `/static/app.js` → `/static/tabs.js`; the FL0W-section comment retouched - `flow.html` reference from `/static/app.js`-as-tabs to `/static/tabs.js`; notif + offscreen-inbox comments rewired to point at the correct owners (common.js for NOTIF, flow.js for renderInbox) - `common.js`, `flow.js`, `tabs.js` headers: scrub stale "app.js" references; document that #406 steps 2 + 3 are done and both pages import directly from common.js - `dashboard.css` comments: every "by app.js" → "by tabs.js" - `docs/web-ui.md`, `docs/conventions.md`: legacy `assets/app.js` → `assets/tabs.js` (the path prefix is itself stale from a much-earlier rename, but consistent with the rest of those docs) - `CLAUDE.md` file map: refresh the dashboard package's src/ and dist/ layouts to reflect the post-split shape (tabs.js, flow.js, common.js, stream-worker.js) What did NOT move: - `frontend/packages/agent/src/app.js` (per-agent UI entry) stays named `app.js` — it's a separate package, has only one entry point, no split happened there - The two "no-op when target absent" guards in renderContainers and renderQuestions are kept as belt-and-suspenders for any future page that adds tabs.js without the corresponding sections; comments updated to note this rather than the pre-split flow.html reason Functional behaviour identical; this is a pure rename + comment sweep.
120 lines
5.5 KiB
HTML
120 lines
5.5 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>hyperhive // FL0W</title>
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
<link rel="stylesheet" href="/static/dashboard.css">
|
|
</head>
|
|
<body class="flow-shell">
|
|
|
|
<!-- Fixed-overlay chrome — just the tab strip (#389 follow-up:
|
|
slug moved to the dashboard's page footer; the flow page is a
|
|
full-viewport terminal with no normal-flow footer position, so
|
|
the slug simply doesn't appear here). The operator can still
|
|
switch tabs from the flow page without navigating back; FL0W is
|
|
the current page, SW4RM / Y3R C4LL / SYST3M cross-link to the
|
|
dashboard with the matching hash. -->
|
|
<header class="dashboard-chrome flow-chrome" id="flow-header">
|
|
<nav class="tabbar" id="tabbar" role="tablist">
|
|
<a class="tab" href="/#swarm" role="tab" data-tab="swarm">
|
|
<span class="tab-label">◆ SW4RM ◆</span>
|
|
<span class="tab-count" id="tab-count-swarm" hidden></span>
|
|
</a>
|
|
<a class="tab" href="/#call" role="tab" data-tab="call">
|
|
<span class="tab-label">◆ Y3R C4LL ◆</span>
|
|
<span class="tab-count tab-count-attn" id="tab-count-call" hidden></span>
|
|
</a>
|
|
<a class="tab" href="/#system" role="tab" data-tab="system">
|
|
<span class="tab-label">◆ SYST3M ◆</span>
|
|
<span class="tab-count" id="tab-count-system" hidden></span>
|
|
</a>
|
|
<a class="tab" href="/#schedules" role="tab" data-tab="schedules">
|
|
<span class="tab-label">◆ SCH3DUL3S ◆</span>
|
|
<span class="tab-count" id="tab-count-schedules" hidden></span>
|
|
</a>
|
|
<a class="tab tab-link active" id="tab-flow" href="/flow.html"
|
|
aria-current="page"
|
|
title="all-agents chat — you are here">
|
|
<span class="tab-label">◆ FL0W ◆</span>
|
|
<span class="tab-count" id="tab-count-flow" hidden></span>
|
|
</a>
|
|
|
|
<!-- Notif controls cohabit with the tabs (always-on chrome).
|
|
Same IDs as on the dashboard so the shared NOTIF binding
|
|
(from common.js, imported by both tabs.js and flow.js)
|
|
picks them up unchanged. -->
|
|
<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>
|
|
</nav>
|
|
</header>
|
|
|
|
<!-- Operator inbox flyout trigger — count + click → side panel
|
|
(singleton, declared below). Hidden until the inbox is non-
|
|
empty. Mirrors the agent page's pill pattern (#362). -->
|
|
<button type="button" id="inbox-pill" class="flow-pill" hidden
|
|
title="open operator inbox">
|
|
<span class="flow-pill-icon" aria-hidden="true">📬</span>
|
|
<span class="flow-pill-label">inbox</span>
|
|
<span class="flow-pill-count" id="inbox-pill-count">0</span>
|
|
</button>
|
|
|
|
<!-- Main content: the full-viewport terminal. Padded for the
|
|
overlay header + composer so the first/last rows stay
|
|
reachable. -->
|
|
<main class="flow-main">
|
|
<div class="terminal-wrap">
|
|
<div id="msgflow" class="live terminal"><div class="meta">connecting…</div></div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- Fixed-overlay composer at the bottom. Same frosted treatment
|
|
as the header — symmetric framing, terminal goes edge-to-edge
|
|
between them. -->
|
|
<footer class="flow-composer">
|
|
<div id="op-compose" class="op-compose">
|
|
<span id="op-compose-prompt" class="op-compose-prompt">@—></span>
|
|
<textarea id="op-compose-input" class="op-compose-input"
|
|
placeholder="@agent message… (enter sends, shift+enter newline, tab completes @-mention)"
|
|
rows="1" autocomplete="off"></textarea>
|
|
<div id="op-compose-suggest" class="op-compose-suggest" hidden></div>
|
|
</div>
|
|
</footer>
|
|
|
|
<!-- Inbox rendered offscreen — kept in the DOM so flow.js's
|
|
renderInbox keeps working unchanged. The pill click handler
|
|
opens the side panel which displays a clone of the list. The
|
|
legacy section heading would otherwise be visible; hidden
|
|
here. -->
|
|
<div id="inbox-section" class="flow-inbox-headless" hidden>
|
|
<p class="meta">loading…</p>
|
|
</div>
|
|
|
|
<!-- Slide-in side panel. Singleton — JS swaps the title + body
|
|
and toggles `.open`. On this page only used to surface the
|
|
operator inbox flyout; the dashboard's other panel uses
|
|
(approval diffs, file previews, logs) don't apply here. -->
|
|
<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>
|
|
|
|
<!-- Flow-specific bundle (#406 step 2). Contains the broker
|
|
terminal init, the operator-inbox derived store, the inbox
|
|
pill flyout, and the @-mention composer. Tab renderers etc.
|
|
live in `/static/tabs.js` which /flow.html doesn't load. -->
|
|
<script type="module" src="/static/flow.js" defer></script>
|
|
</body>
|
|
</html>
|