hyperhive/hive-fr0nt/src/lib.rs
müde f8f2ccff52 agent terminal: coherence pass
layout
- unified prefix-column for every row kind: padding-left + negative
  text-indent so the glyph (→ ← · ◆ ✓ ✗ ⌁ !) sits in the same column
  whether the row is flat or a <details>. wraps hang under the body,
  not under the glyph.
- expandable rows drop the directional glyph from their summary text;
  the ▸/▾ disclosure marker from CSS sits in the prefix column instead,
  and the row's colour still carries cyan = outbound, muted = inbound.
- turn-start / turn-end de-weighted: bold/margin/tint dropped, the
  coloured left rule alone marks the boundary.

note classification
- stderr lines render orange with a `!` glyph (was muted `·`)
- operator-initiated notes (cancel/compact/model/new-session) render
  mauve italic (was muted `·` indistinguishable from harness chatter)
- catch-all .sys row escalates to orange `!` so unrecognised stream-json
  shapes surface for follow-up instead of hiding in muted noise

message-bearing rows
- send / ask / answer tool_use rich renderers default-open with the
  body inline; new ask + answer renderers (previously fell through to
  the generic JSON dump). recv tool_result also default-open, keyed by
  tracking tool_use_id → name across the stream so we know which
  result came from which tool.
- assistant text rows render markdown.
- bodies use vendored marked v4.0.2 (hive-fr0nt::MARKED_JS); falls
  back to plain text when the asset doesn't load.

extra-mcp tool pretty-print
- generic args formatter replaces the raw JSON dump for unknown tools
  (single-string field → `name k: "v"`; single dict / multi-field →
  trimmed `k: v · k: v …` summary)

dashboard .live .msgrow gets a text-indent: 0 reset so the new
hanging-indent metrics from TERMINAL_CSS don't leak into the flex-grid
broker rows.
2026-05-18 18:13:14 +02:00

42 lines
2.5 KiB
Rust

//! Shared frontend assets for the hive-c0re dashboard and the hive-ag3nt
//! per-container web UI. Both surfaces live in different binaries (and
//! different containers at runtime) but should feel like one product —
//! same colour tokens, same terminal-style live stream, same compose-box
//! ergonomics. Keeping the CSS + JS in one crate is the dumbest way to
//! make that true: both binaries `include_str!` from
//! `hive_fr0nt::assets::*` instead of growing their own copy.
//!
//! There is no Rust code beyond these `const` re-exports. The crate is a
//! container for text files and a place to write down the contract
//! between the two surfaces.
//!
//! Conventions for sharing:
//! - **CSS variables** live in [`BASE_CSS`] (colour palette, typography).
//! Page-specific stylesheets append to it; nothing else should declare
//! `--bg` / `--purple` / etc.
//! - **Terminal pane** (sticky-bottom log + `↓ N new` pill + fade-in
//! rows) lives in [`TERMINAL_CSS`] and [`TERMINAL_JS`]. Pages provide
//! a kind→renderer map; the JS owns the scroll + backfill + SSE plumbing.
//! - **Compose box** (textarea + slash-command palette + sticky
//! recipient + `@`-mention autocomplete) lives in [`COMPOSER_JS`].
//! Pages pass a config flagging which features they want; the dashboard
//! ships `@`-mentions without slash commands, the agent page ships
//! slash commands without `@`-mentions. Both render through the same
//! component so the keystrokes, error flashes, and async-form
//! behaviour stay identical.
//!
//! Loading new shared assets: add the file under `assets/`, expose it as
//! a `pub const`, and `include_str!` it from whichever
//! `dashboard.rs` / `web_ui.rs` route needs it.
pub const BASE_CSS: &str = include_str!("../assets/base.css");
pub const TERMINAL_CSS: &str = include_str!("../assets/terminal.css");
pub const TERMINAL_JS: &str = include_str!("../assets/terminal.js");
/// Vendored [marked](https://github.com/markedjs/marked) v4.0.2 UMD bundle.
/// Exposes a global `marked` with `.parse(src, opts)` returning HTML. Used
/// by the per-agent terminal to render message bodies (`send` / `recv` /
/// `ask` / `answer` / assistant text) with basic markdown — paragraphs,
/// lists, fenced + inline code, bold/italic, links. Vendored rather than
/// CDN-loaded so the per-agent page works on operator machines without
/// internet egress (the container itself never fetches it).
pub const MARKED_JS: &str = include_str!("../assets/marked.min.js");