From 0a9f9a4fa643a9824c2fb0625197d623a295c58c Mon Sep 17 00:00:00 2001 From: iris Date: Sat, 4 Jul 2026 11:53:13 +0200 Subject: [PATCH 1/2] feat(agent-term): complete tool-icon and fmtToolUse coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Several MCP tools appeared with the generic wrench icon (๐Ÿ”ง) making them hard to identify in the scrollback. fmtToolUse also lacked specific formatters for some frequently-used tools, falling through to fmtArgsGeneric. Icons added: - ack_until โ†’ โœ… (mark-as-read semantics) - get_logs โ†’ ๐Ÿ“œ (log viewer) - get_host_journal โ†’ ๐Ÿ“œ (journal reader) fmtToolUse cases added: - ack_until โ†’ "ack_until* โ‰คN" (message-id bound) - get_logs โ†’ "get_logs* [NL]" - get_host_journal โ†’ "get_host_journal* [/grep/] [NL]" - restart/start/update โ†’ "restart* " etc. (previously used fmtArgsGeneric; now match kill's pattern) Closes #2188. --- frontend/packages/agent/src/app.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index 013fe80b..4eee5ecc 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -1514,6 +1514,7 @@ window.marked = marked; 'mcp__hyperhive__set_status': '๐Ÿท๏ธ', 'mcp__hyperhive__get_loose_ends': '๐Ÿชข', 'mcp__hyperhive__cancel_loose_end': 'โœ‚๏ธ', + 'mcp__hyperhive__ack_until': 'โœ…', 'mcp__hyperhive__get_agent_meta': 'โ„น๏ธ', 'mcp__hyperhive__request_next_turn': 'โฉ', 'mcp__hyperhive__restart': 'โ†ป', @@ -1521,6 +1522,8 @@ window.marked = marked; 'mcp__hyperhive__start': 'โ–ถ๏ธ', 'mcp__hyperhive__update': '๐Ÿ”„', 'mcp__hyperhive__list_containers': '๐Ÿ“‹', + 'mcp__hyperhive__get_logs': '๐Ÿ“œ', + 'mcp__hyperhive__get_host_journal': '๐Ÿ“œ', Read: '๐Ÿ“–', Write: '๐Ÿ’พ', Edit: 'โœ๏ธ', Glob: '๐Ÿ”', Grep: '๐Ÿ”', }; function toolIcon(name) { @@ -1565,6 +1568,22 @@ window.marked = marked; return short + (parts.length ? ' ' + parts.join(' ยท ') : '()'); } case 'mcp__hyperhive__kill': return short + ' ' + (input.name || ''); + case 'mcp__hyperhive__restart': return short + ' ' + (input.name || ''); + case 'mcp__hyperhive__start': return short + ' ' + (input.name || ''); + case 'mcp__hyperhive__update': return short + ' ' + (input.name || ''); + case 'mcp__hyperhive__ack_until': + return short + ' โ‰ค' + (input.up_to != null ? input.up_to : '?'); + case 'mcp__hyperhive__get_logs': + return short + ' ' + (input.agent || '?') + + (input.lines != null ? ' ยท ' + input.lines + 'L' : ''); + case 'mcp__hyperhive__get_host_journal': { + const parts = []; + if (input.container) parts.push(input.container); + else if (input.unit) parts.push(input.unit); + if (input.grep) parts.push('/' + input.grep + '/'); + if (input.lines != null) parts.push(input.lines + 'L'); + return short + (parts.length ? ' ' + parts.join(' ยท ') : '()'); + } case 'mcp__hyperhive__request_apply_commit': return short + ' ' + (input.agent || '') + ' @ ' + (input.commit_ref || '').slice(0, 12); case 'mcp__bash__run': { From fc415a72a5cf84ad98a955d4c12adf0ec7c2a191 Mon Sep 17 00:00:00 2001 From: iris Date: Sat, 4 Jul 2026 12:04:47 +0200 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20update=20stale=20tabs.js=E2=86=92sw?= =?UTF-8?q?arm.js/call.js=20references?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the SW4RM and Y3R C4LL extractions from tabs.js (PRs merged earlier), several docs still pointed at `assets/tabs.js::fn`. Update them to the authoritative module: - dashboard.md: renderContainers, buildAgentTree โ†’ swarm.js renderApprovals โ†’ call.js renderPeerHives โ†’ swarm.js - shape.md: generic "tabs.js render function" โ†’ "domain module" - conventions.md: clarify async-form listener lives in tabs.js (dashboard) AND app.js (per-agent UI) --- docs/conventions.md | 2 +- docs/web-ui/dashboard.md | 8 ++++---- docs/web-ui/shape.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/conventions.md b/docs/conventions.md index 1a0d0283..a927ec52 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -406,7 +406,7 @@ the relevant handler (`agent_server.rs`, `mcp.rs`, or `dashboard.rs`). ## Async forms Dashboard + per-agent mutating forms carry `data-async`; a delegated -`submit` listener in `assets/tabs.js` intercepts, shows a spinner, +`submit` listener in `assets/tabs.js` (+ `assets/app.js` for the per-agent UI) intercepts, shows a spinner, POSTs `application/x-www-form-urlencoded` (axum's `Form` extractor rejects multipart), calls `refreshState()` on success. New mutating forms should add `data-async` and optionally `data-confirm` (for a diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index 6a03bee6..77fdc527 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -536,7 +536,7 @@ nix config (an attrset keyed by peer domain), serialises each entry as `{ name, url }` into `state.peer_hives: Vec`, and includes the field in the `/api/state` snapshot. `tabs.js` reads `state.peer_hives` on every `refreshState` call and calls -`renderPeerHives(peers)`, which rebuilds the `#peers-section` +`swarm.js::renderPeerHives(peers)`, which rebuilds the `#peers-section` div from scratch. The `name` field is the peer's DNS domain (the attrset key); `url` @@ -707,7 +707,7 @@ the tooltip says "select โ€ฆ for bulk actions" or "deselect โ€ฆ (or press Esc to clear all)". The `` points at `/icon`; load failure falls back to the dimmed hyperhive mark (`/favicon.svg`). The card body sits to the right with three stacked lines -(`assets/tabs.js::renderContainers`). +(`assets/swarm.js::renderContainers`). **Icon layout + load strategy:** the `` is absolutely positioned (`inset: 0`) inside the `.container-icon` wrapper โ€” @@ -885,7 +885,7 @@ the dashboard and CLI paths behave identically.) ### Topology tree Container rows render as a forest, not a flat list โ€” each agent -sits indented under its declared parent. `tabs.js::buildAgentTree` +sits indented under its declared parent. `swarm.js::buildAgentTree` walks `ContainerView.parent` for every container in the snapshot and produces a render order with per-row depth + sibling-position info: @@ -979,7 +979,7 @@ every render before the bar appears. ## Approval card -Each pending approval renders as a card (`assets/tabs.js:: +Each pending approval renders as a card (`assets/call.js:: renderApprovals`) with three stacked sections: - **identity header** โ€” glyph, `#id`, agent, kind chip, and a diff --git a/docs/web-ui/shape.md b/docs/web-ui/shape.md index 87fb8b15..933e7f4d 100644 --- a/docs/web-ui/shape.md +++ b/docs/web-ui/shape.md @@ -187,7 +187,7 @@ listener: read `data-confirm`, swap the button to a spinner, POST re-render), call `refreshState()`. State shapes live in `dashboard.rs::StateSnapshot` and `web_ui.rs::StateSnapshot` โ€” when adding state fields, plumb through the snapshot struct and the -relevant `assets/tabs.js` render function. +relevant domain module (`assets/swarm.js`, `assets/call.js`, etc.) render function. **Focus preservation:** `refreshState` checks whether `document.activeElement` sits inside one of the managed sections