5.2 KiB
Per-agent terminal: row taxonomy + inconsistencies
Snapshot of how the per-agent web UI's live pane renders each
event kind today, written up so the next coherence pass has a
reference to work from. Source of truth lives in
hive-ag3nt/assets/app.js (renderStream,
fmtToolUse, renderRichToolUse, renderToolResult,
renderTaskEvent) + hive-fr0nt/assets/terminal.css (the
shared .live .<class> styling).
Row taxonomy
| CSS class | Prefix glyph | Color | Triggered by | Source |
|---|---|---|---|---|
.turn-start |
◆ TURN ← <from> |
amber, bold, top-margin, amber left rule | LiveEvent::TurnStart |
harness wake |
.turn-body |
(inline under turn-start) | fg dimmed 85% | same | the wake-prompt body |
.turn-end-ok |
✓ turn ok |
green, green left rule | LiveEvent::TurnEnd { ok: true } |
harness |
.turn-end-fail |
✗ turn fail — note |
red, red left rule | LiveEvent::TurnEnd { ok: false } |
harness |
.text |
none | fg/white, indented | claude assistant.content[].text |
stream-json |
.thinking |
· or · thinking … |
muted, italic | claude assistant.content[].thinking |
stream-json |
.tool-use |
→ Name args… |
cyan | assistant.content[].tool_use |
stream-json |
.tool-use <details> |
→ Name path · +N |
cyan, body is diff | rich tool_use (Write/Edit) | renderRichToolUse |
.tool-use <details> |
→ send → to · headline |
cyan, body is text | mcp__hyperhive__send | renderRichToolUse |
.tool-result |
← <txt> |
muted | short user.content[].tool_result (≤120c) |
stream-json |
.tool-result-block <details> |
▸ ← Nl · headline |
muted, body is text | long tool_result (>120c) |
stream-json |
.tool-use |
⌁ task <id> started · <desc> [type] |
cyan | claude Task-tool subagent event | renderTaskEvent |
.turn-end-ok / .turn-end-fail / .tool-result |
⌁ task <id> ✓/✗/◌ <status> · <desc> · → <output_file> |
green / red / muted | claude Task-tool result | renderTaskEvent |
.note |
· <text> |
muted | LiveEvent::Note (harness chatter, /cancel /compact /new-session, stderr lines, etc.) |
harness |
.sys |
· {json…} |
muted | anything renderStream doesn't recognise |
catch-all |
.result |
(defined, never emitted today) | green | — | — |
| Banner shimmer | mauve | turn in flight (ref-counted) | setBannerActive |
Where the inconsistencies live
-
Glyph vocabulary drifts:
- tool_use uses
→ - tool_result uses
← - thinking uses
· - notes use
· - turn-end ok/fail use
✓ / ✗ - turn-start uses
◆ - task events use
⌁ - The
·glyph is overloaded across thinking, notes, sys.
- tool_use uses
-
What gets a
<details>block vs a flat row is per-tool ad-hoc: Write/Edit always expand, send always expands, every other tool_use is flat regardless of input size.tool_resultis flat if ≤120 chars otherwise<details>. -
Stderr handling: claude's stderr lines come through as
LiveEvent::Notewithtext: "stderr: <line>"— they render as muted· stderr: …, identical styling to harness notes about /compact / /model. No red-tinted "this is an error" affordance for stderr. -
Catch-all
.sysrows are visually identical to.noterows — both muted, both·prefix. They look like normal notes despite usually being "an event renderStream couldn't classify". Unmatched stream shapes (rate limit warnings under odd type/subtype combos, future claude additions, etc.) silently fall through. -
.tool-useranges from one-liner (Read foo.md) to multi-page collapsed diff — same color, same prefix glyph, very different visual weight. A small marker on the collapsed<details>summary would help (the▸is present in.tool-result-blocksummaries but absent in tool-use<details>summaries). -
Cancel/compact/new-session notes are styled the same as autonomous harness chatter; nothing flags them as "operator initiated."
Suggested coherence pass
Pick one scheme and audit all renderers to match. A concrete proposal:
→cyan: outbound action (tool_use, send)←muted: inbound result (tool_result)◆amber: turn framing (turn_start)✓ / ✗: success / failure, green / red (turn_end, task_notification)⌁mauve: subagent / background event (task_*)·muted: ambient note, italic for thinking!orange: caught error (stderr lines, .sys catch-all that landed something the renderer didn't recognise)
Plus: every tool_use <details> summary gets ▸ so collapsed
content is visually announced. Operator-initiated notes get a
distinct prefix (op· or similar) so they're easier to spot in
the scrollback.
The .sys catch-all should escalate visually — a louder
"unrecognised event" rendering surfaces silently-dropped event
shapes for future fix-up rather than hiding them in the muted
note stream.
Dashboard side (not covered here)
The main dashboard's message-flow pane is a different beast:
broker messages render as .msgrow grid lines (ts / arrow /
from / → / to / body) with separate styling. The current file
focuses only on the per-agent terminal.