Per operator spec at #360#issuecomment-3333:
- full-screen terminal
- frosted-glass header overlaid on top
- inbox + loose-ends → flyout
- no a/b flag, just ship it
## Layout
`frontend/packages/agent/src/index.html` restructured to a three-zone
fixed-overlay shape:
- `<header.agent-header>` — fixed top, frosted glass via
`backdrop-filter: blur(12px) saturate(140%)`. Holds icon + title +
nav links + state-row (badges/buttons) + two new pill buttons that
surface inbox / loose-ends counts (and open the side panel on click).
- `<main.agent-main>` — fills the viewport. Terminal positioned absolute
inset:0 with padding-top/-bottom + scroll-padding equal to the
floating header/composer heights so first/last rows stay reachable
and `↓ N new` pill anchors land in the visible scroll zone.
- `<footer.agent-composer>` — fixed bottom, mirror-frosted. Owns
`#term-input`; dropped the in-frame dashed separator (border-top
+ box-shadow on the bar already separate it from the terminal).
- `<div.side-panel>` — singleton drawer (copy of the dashboard
pattern, candidate for extraction into @hive/shared). Inbox +
loose-ends details render here instead of expanding inline.
Dropped from the page: the pre-banner ASCII shimmer (`<pre.banner>`)
and the in-page `<details>` collapsibles for inbox + loose-ends. The
banner JS path (`setBannerActive`) is now a no-op (early-returns on
missing element); kept as dead code rather than ripped out to keep
the diff focused.
## JS
`frontend/packages/agent/src/app.js`:
- New `Panel` singleton with `open(name, title, content)` +
`close()` + `refresh(name, title, content)` (no-op if a different
view owns the panel — lets live updates re-render an open view
without grabbing focus from a closed one). Mirror of the
dashboard's Panel module; the duplication is intentional for now.
- `renderInbox` + `renderLooseEnds` refactored: update the header
pill counts, hide/show the pills, and `Panel.refresh` if the
matching view is open. The list-building DOM logic moved into
`buildInboxList` + `buildLooseEndsList` so the pill click handler
can call them on the latest snapshot kept in `lastInbox` /
`lastLooseEnds` module state.
- Pill click handlers `Panel.open(...)` with the freshly built list.
- Auto-expand behavior on first appearance dropped (the pill +
count badge is the discoverable signal; auto-popping the flyout
would interrupt whatever the operator is doing).
- `setHeader` no longer touches `#banner` (element removed); title +
dashboard back-link + rebuild button still get appended to `#title`.
## CSS
`frontend/packages/agent/src/agent.css` major additions, scoped
`body.agent-shell` so the sibling `stats.html` (which doesn't apply
the shell class) keeps its normal-document scroll + `.banner` ASCII
header via a `body:not(.agent-shell)` block.
New CSS custom properties on :root: `--agent-header-h`,
`--agent-composer-h`, `--agent-frost-bg`, `--agent-frost-blur`. The
terminal's padding + scroll-padding derive from these so a single
height tweak ripples consistently.
Added `.header-pill` (inbox/loose-ends triggers) +
`.agent-status-overlay` (centred login card when status != online).
Side-panel rules copied from `dashboard.css` with one delta: width
caps at 640px (vs dashboard's 760px) since per-agent inbox / loose-
ends rows are narrower than approval diffs / file previews.
## Validation
- `npm run build` — succeeds both workspaces.
- agent: `dist/static/{app.js (115kb), stats.js (435kb), agent.css (21kb)}`
- dashboard unchanged (no shared sources touched).
- Browser smoke test isn't possible from inside iris's container
(no JS engine) — op-side check on next deploy.
Closes#360.
The src/index.html / src/stats.html files reference assets at URLs
like /static/app.js, /static/dashboard.css. The initial Phase 1 build
flattened everything to dist/{app.js, dashboard.css, ...} which would
have forced the Phase 4 Rust ServeDir mount to do URL rewriting just
to make the existing HTML references resolve.
Rework: bundles now write to dist/static/, HTML stays at dist/ top
level. Layout matches the URLs the HTML uses, so the Phase 4 mount
is the simplest possible `fallback_service(ServeDir::new(dist))`.
No source-file changes — just the esbuild outfile/outdir paths.
Rebuilt; verified asset filenames + sizes unchanged.
Refs #273.
Phase 1 of the backend/frontend code split (#273). Additive — no
existing code is touched; the legacy hive-c0re/assets, hive-ag3nt/
assets and hive-fr0nt/assets trees stay in place until the Rust
cutover later in this branch.
Layout:
frontend/package.json npm workspaces root
frontend/packages/shared/ @hive/shared
src/{base,terminal}.css + terminal.js (ES module)
src/index.js re-exports terminal.js
frontend/packages/dashboard/ @hive/dashboard
src/{index.html, app.js, dashboard.css} ported from hive-c0re/assets
build.mjs esbuild config → dist/
frontend/packages/agent/ @hive/agent
src/{index,stats,screen}.html + agent.css
+ {app,stats}.js ported from hive-ag3nt/assets
build.mjs esbuild config → dist/
Changes vs the existing assets:
- terminal.js is an ES module exporting { create, linkify } instead
of assigning to window.HiveTerminal. The dashboard / agent app.js
files re-expose them on window so the IIFE bodies keep working
unchanged through Phase 1; the global aliases can be dropped in a
follow-up once the IIFEs are unwrapped.
- marked is imported from the marked@4.3.0 npm package (replacing
the vendored hive-fr0nt/assets/marked.umd.js bundle).
- chart.js is imported from chart.js@4.4.4 (replacing the jsDelivr
CDN script tag on the per-agent stats page — page now works
offline / on operator machines without internet egress).
- dashboard.css and agent.css both gain @import lines at the top
that pull base.css + terminal.css from @hive/shared, replacing
the runtime string concatenation in serve_css.
- index.html / stats.html collapse from three / two script tags to
one type="module" tag pointing at the bundled output.
package-lock.json is intentionally omitted from this commit — npm
isn't available in the iris container yet (approval pending) and the
lockfile will land in the next commit on this branch once the
toolchain is in place. The PR will not be opened until it's there.
Phase 2 (nix derivations), Phase 3 (container plumbing + the
hyperhive.frontend.extraFiles option for per-agent layering), and
Phase 4 (Rust cutover to tower_http::ServeDir, delete hive-fr0nt
+ legacy assets dirs) land as follow-up commits on this same
branch.
Refs #273.