docs: refresh CLAUDE.md for system-prompt-file, helper events, dashboard buttons, ui shape; TODO.md drop operator-inbox (done)
This commit is contained in:
parent
ace13cd785
commit
abfd2cce4b
2 changed files with 100 additions and 24 deletions
121
CLAUDE.md
121
CLAUDE.md
|
|
@ -35,7 +35,11 @@ hive-ag3nt/ in-container harness crate; produces TWO binaries
|
||||||
src/login_session.rs drives `claude auth login` over stdio pipes
|
src/login_session.rs drives `claude auth login` over stdio pipes
|
||||||
src/bin/hive-ag3nt.rs sub-agent main
|
src/bin/hive-ag3nt.rs sub-agent main
|
||||||
src/bin/hive-m1nd.rs manager main
|
src/bin/hive-m1nd.rs manager main
|
||||||
assets/ CSS + JS for the per-agent UI
|
assets/ index.html, agent.css, app.js (include_str!)
|
||||||
|
prompts/ static role/tools/settings for claude (include_str!):
|
||||||
|
agent.md — sub-agent system prompt
|
||||||
|
manager.md — manager system prompt
|
||||||
|
claude-settings.json — --settings JSON
|
||||||
|
|
||||||
hive-sh4re/ wire types (HostRequest/Response, AgentRequest/Response,
|
hive-sh4re/ wire types (HostRequest/Response, AgentRequest/Response,
|
||||||
ManagerRequest/Response, Message, Approval, HelperEvent)
|
ManagerRequest/Response, Message, Approval, HelperEvent)
|
||||||
|
|
@ -71,11 +75,11 @@ nix/
|
||||||
- **Actions are factored.** `approve` / `deny` / `destroy` live in
|
- **Actions are factored.** `approve` / `deny` / `destroy` live in
|
||||||
`actions.rs`; the admin socket and the dashboard POST handlers both call
|
`actions.rs`; the admin socket and the dashboard POST handlers both call
|
||||||
into them so the two surfaces never drift.
|
into them so the two surfaces never drift.
|
||||||
- **Async forms.** Dashboard mutating forms carry `data-async`; the
|
- **Async forms.** Dashboard + per-agent mutating forms carry `data-async`;
|
||||||
`assets/async_forms.js` helper intercepts submit, shows a spinner, and
|
a delegated `submit` listener in `assets/app.js` intercepts, shows a
|
||||||
fetches with `application/x-www-form-urlencoded` (axum `Form` extractor
|
spinner, POSTs with `application/x-www-form-urlencoded` (axum `Form`
|
||||||
rejects multipart). New mutating forms should add `data-async` and
|
extractor rejects multipart), calls `refreshState()` on success. New
|
||||||
optionally `data-confirm`.
|
mutating forms should add `data-async` and optionally `data-confirm`.
|
||||||
|
|
||||||
## Gotchas / lessons learned
|
## Gotchas / lessons learned
|
||||||
|
|
||||||
|
|
@ -167,17 +171,27 @@ Manager additionally:
|
||||||
config change for any agent (including `hm1nd` for self-mods).
|
config change for any agent (including `hm1nd` for self-mods).
|
||||||
|
|
||||||
The shared per-turn plumbing lives in `hive_ag3nt::turn::{write_mcp_config,
|
The shared per-turn plumbing lives in `hive_ag3nt::turn::{write_mcp_config,
|
||||||
run_turn, drive_turn, emit_turn_end, wait_for_login}` so the two binaries
|
write_settings, write_system_prompt, run_turn, drive_turn, emit_turn_end,
|
||||||
can't drift.
|
wait_for_login}` so the two binaries can't drift.
|
||||||
|
|
||||||
|
On harness boot, three files get dropped next to the mcp socket at
|
||||||
|
`/run/hive/`:
|
||||||
|
|
||||||
|
- `claude-mcp-config.json` — re-invokes the running binary as `mcp` child.
|
||||||
|
- `claude-settings.json` — `--settings` blob (auto-compact/auto-memory
|
||||||
|
off, effortLevel medium).
|
||||||
|
- `claude-system-prompt.md` — rendered from `prompts/{agent,manager}.md`
|
||||||
|
with `{label}` substituted. Passed via `--system-prompt-file`.
|
||||||
|
|
||||||
Each turn:
|
Each turn:
|
||||||
|
|
||||||
```
|
```
|
||||||
claude --print --verbose --output-format stream-json --model haiku \
|
claude --print --verbose --output-format stream-json --model haiku \
|
||||||
--continue --settings '{"autoCompactEnabled":false,"autoMemoryEnabled":false}' \
|
--continue --settings /run/hive/claude-settings.json \
|
||||||
--mcp-config <path> --strict-mcp-config \
|
--system-prompt-file /run/hive/claude-system-prompt.md \
|
||||||
|
--mcp-config /run/hive/claude-mcp-config.json --strict-mcp-config \
|
||||||
--tools <builtins> --allowedTools <builtins+mcp>
|
--tools <builtins> --allowedTools <builtins+mcp>
|
||||||
# prompt piped over stdin
|
# wake prompt piped over stdin — minimal, just from/body + optional unread hint
|
||||||
```
|
```
|
||||||
|
|
||||||
`--continue` keeps a persistent session per agent (claude stores sessions in
|
`--continue` keeps a persistent session per agent (claude stores sessions in
|
||||||
|
|
@ -187,14 +201,15 @@ overflow, retry once).
|
||||||
|
|
||||||
**Loop control.** The harness pops one inbox message per cycle (the wake
|
**Loop control.** The harness pops one inbox message per cycle (the wake
|
||||||
signal — Recv long-polls server-side for up to 30s waking instantly on a new
|
signal — Recv long-polls server-side for up to 30s waking instantly on a new
|
||||||
broker `Sent` event for this agent) and hands claude a prompt naming the
|
broker `Sent` event for this agent), peeks the remaining inbox depth with
|
||||||
agent, the sender, the body, and the MCP tools. Claude drives any further
|
`Status`, and emits `TurnStart { from, body, unread }`. The wake prompt
|
||||||
`recv`/`send` itself.
|
piped to claude includes a one-line `({unread} more pending — drain via …)`
|
||||||
|
hint when `unread > 0`. Claude drives any further `recv`/`send` itself.
|
||||||
|
|
||||||
**Tool envelope** (`mcp::run_tool_envelope`): every MCP tool handler logs
|
**Tool envelope** (`mcp::run_tool_envelope`): every MCP tool handler logs
|
||||||
the request, runs the body, appends a status line (e.g.
|
the request, runs the body, logs the result. Pre-/post-log only; the old
|
||||||
`[status] 3 unread message(s) in inbox` from a non-mutating `Status` peek),
|
`[status] N unread message(s)` appendage was removed once unread moved
|
||||||
logs the result. New tools call this helper.
|
into the wake prompt + UI header. New tools call this helper.
|
||||||
|
|
||||||
**Tool whitelist** (`mcp::ALLOWED_BUILTIN_TOOLS`):
|
**Tool whitelist** (`mcp::ALLOWED_BUILTIN_TOOLS`):
|
||||||
- Allowed built-ins: `Bash`, `Edit`, `Glob`, `Grep`, `Read`, `TodoWrite`,
|
- Allowed built-ins: `Bash`, `Edit`, `Glob`, `Grep`, `Read`, `TodoWrite`,
|
||||||
|
|
@ -207,9 +222,27 @@ logs the result. New tools call this helper.
|
||||||
|
|
||||||
**Live view.** Each agent runs an `events::Bus` (a
|
**Live view.** Each agent runs an `events::Bus` (a
|
||||||
`tokio::sync::broadcast<LiveEvent>` wrapper). The harness emits
|
`tokio::sync::broadcast<LiveEvent>` wrapper). The harness emits
|
||||||
`TurnStart`, `Stream(value)` (one per parsed stream-json line), `Note`,
|
`TurnStart { from, body, unread }`, `Stream(value)` (one per parsed
|
||||||
`TurnEnd`. The web UI subscribes via `/events/stream` (SSE) and a JS panel
|
stream-json line), `Note`, `TurnEnd { ok, note }`. The web UI subscribes
|
||||||
appends rows. No full-page reload — operator input stays put.
|
via `/events/stream` (SSE) and a JS panel (terminal-themed: Crust bg, inset
|
||||||
|
shadow, monospace) renders rows:
|
||||||
|
|
||||||
|
- `TurnStart` → `◆ TURN ← <from> · N unread` header + indented body.
|
||||||
|
- `Stream` `tool_use` → `→ Read /path` / `→ Bash $ cmd` /
|
||||||
|
`→ send → operator: "..."` etc., per-tool pretty rather than raw JSON.
|
||||||
|
- `Stream` `tool_result` short → flat `← ...`; long → collapsed
|
||||||
|
`<details>` `▸ ← Nl · headline` (click to expand full body).
|
||||||
|
- `Stream` `thinking` → shows the thinking text if claude provided one,
|
||||||
|
otherwise the bare `· thinking …` indicator.
|
||||||
|
- `Stream` `system init`, `result`, `rate_limit_event` are dropped — too
|
||||||
|
noisy and `TurnEnd` already says the turn finished.
|
||||||
|
- `Note` → `· text`.
|
||||||
|
- `TurnEnd` → `✓ turn ok` / `✗ turn fail — note` and triggers a
|
||||||
|
`refreshState()` so the page form view reflects state transitions
|
||||||
|
(e.g. login just landed).
|
||||||
|
|
||||||
|
The operator send form sits below the live panel, so the tail is what
|
||||||
|
you read first.
|
||||||
|
|
||||||
## Manager (hm1nd) is hive-c0re-managed
|
## Manager (hm1nd) is hive-c0re-managed
|
||||||
|
|
||||||
|
|
@ -237,6 +270,36 @@ Differences from sub-agents:
|
||||||
block from your host NixOS config. hyperhive creates and updates the
|
block from your host NixOS config. hyperhive creates and updates the
|
||||||
manager itself now.
|
manager itself now.
|
||||||
|
|
||||||
|
**Manager policy** (from `prompts/manager.md`): the manager does NOT
|
||||||
|
rubber-stamp sub-agent config requests. It verifies (role match, package
|
||||||
|
legitimacy, cheaper alternative, blast radius) before committing +
|
||||||
|
calling `request_apply_commit`. For ambiguous cases or anything that
|
||||||
|
needs human signal, the manager forwards the question to the operator
|
||||||
|
via `send(to: "operator", ...)` — a dedicated `mcp__hyperhive__ask_operator`
|
||||||
|
tool with proper pause/resume semantics is in [TODO.md](TODO.md).
|
||||||
|
|
||||||
|
## Helper events to the manager
|
||||||
|
|
||||||
|
`Coordinator::notify_manager(&HelperEvent)` enqueues an inbox message
|
||||||
|
from sender `system` with the event JSON in the body. The manager
|
||||||
|
harness no longer short-circuits these — they drive a regular claude
|
||||||
|
turn so the manager can react. Variants
|
||||||
|
(`hive_sh4re::HelperEvent`):
|
||||||
|
|
||||||
|
- `ApprovalResolved { id, agent, commit_ref, status, note }` — fired by
|
||||||
|
`actions::approve` + `actions::deny` whenever an approval transitions
|
||||||
|
to its terminal state.
|
||||||
|
- `Spawned { agent, ok, note }` — `actions::approve` (Spawn-kind) +
|
||||||
|
admin `HostRequest::Spawn`.
|
||||||
|
- `Rebuilt { agent, ok, note }` — `auto_update::rebuild_agent` (covers
|
||||||
|
startup scan + manual `/rebuild` from dashboard) + `actions::approve`
|
||||||
|
(ApplyCommit).
|
||||||
|
- `Killed { agent }` — admin `HostRequest::Kill` + dashboard `/kill`.
|
||||||
|
- `Destroyed { agent }` — `actions::destroy`.
|
||||||
|
|
||||||
|
To add a new event: new `HelperEvent` variant + call sites + update
|
||||||
|
`prompts/manager.md` so the manager knows the new shape.
|
||||||
|
|
||||||
## Auto-update on startup
|
## Auto-update on startup
|
||||||
|
|
||||||
`hive-c0re serve` runs `auto_update::run` in a background task right after
|
`hive-c0re serve` runs `auto_update::run` in a background task right after
|
||||||
|
|
@ -252,7 +315,23 @@ auto-update is a no-op — rebuild manually.
|
||||||
The dashboard surfaces pending updates per agent: a clickable "needs update
|
The dashboard surfaces pending updates per agent: a clickable "needs update
|
||||||
↻" badge appears whenever the marker differs from current rev. The badge
|
↻" badge appears whenever the marker differs from current rev. The badge
|
||||||
POSTs `/rebuild/<name>`, calling the same `auto_update::rebuild_agent`
|
POSTs `/rebuild/<name>`, calling the same `auto_update::rebuild_agent`
|
||||||
path so manual triggers and the startup scan can't drift.
|
path so manual triggers and the startup scan can't drift. When at least
|
||||||
|
one container is stale, a top-level `↻ UPD4TE 4LL` button appears that
|
||||||
|
loops over every stale container.
|
||||||
|
|
||||||
|
## Dashboard action surface
|
||||||
|
|
||||||
|
Container row buttons (rendered per-state by `assets/app.js`):
|
||||||
|
|
||||||
|
- Always: `↻ R3BU1LD` (calls `lifecycle::rebuild`), and for sub-agents
|
||||||
|
`DESTR0Y` (container removed, state + creds kept).
|
||||||
|
- Running: `↺ R3ST4RT` + (sub-agents only) `■ ST0P`.
|
||||||
|
- Stopped: `▶ ST4RT`.
|
||||||
|
- Stale marker: clickable `needs update ↻` badge (same target as rebuild
|
||||||
|
but only shown when out of date).
|
||||||
|
|
||||||
|
Top of the containers list: `↻ UPD4TE 4LL` (when any stale) + the
|
||||||
|
"R3QU3ST SP4WN" form for queuing a new agent through the approval flow.
|
||||||
|
|
||||||
## Approval flow
|
## Approval flow
|
||||||
|
|
||||||
|
|
|
||||||
3
TODO.md
3
TODO.md
|
|
@ -25,9 +25,6 @@ Pick anything from here when relevant. Cross-cutting design notes live in
|
||||||
|
|
||||||
## UI / UX
|
## UI / UX
|
||||||
|
|
||||||
- **Operator inbox view.** Drain replies addressed to `operator` and show
|
|
||||||
them on the dashboard. Today they accumulate in sqlite unread; you can
|
|
||||||
only see them by watching the live panel of the agent that sent them.
|
|
||||||
- **Per-agent UI substance.** Show last N inbox messages, last turn timing,
|
- **Per-agent UI substance.** Show last N inbox messages, last turn timing,
|
||||||
link back to dashboard.
|
link back to dashboard.
|
||||||
- **xterm.js terminal** embedded per-agent, attached to a PTY exposed by
|
- **xterm.js terminal** embedded per-agent, attached to a PTY exposed by
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue