From f965e35761b868e715416387a23f3250c69963f4 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:39:32 +0200 Subject: [PATCH 1/8] =?UTF-8?q?docs(web-ui/agent):=20fix=20stale=20/answer?= =?UTF-8?q?-question/{id}=20=E2=86=92=20/api/answer-question/{id}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both loose-ends flyout and ask-bind prose referenced the bare path without the /api/ prefix. The code was fixed in 98b5e976 to use the correct path; dashboard.md already documents it correctly as POST /api/answer-question/{id}. Align agent.md to match. --- docs/web-ui/agent.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/web-ui/agent.md b/docs/web-ui/agent.md index f37869e5..711934f9 100644 --- a/docs/web-ui/agent.md +++ b/docs/web-ui/agent.md @@ -154,7 +154,7 @@ After the drain the inbox list empties on reload (the filter is `acked_at IS NULL`, so drained messages disappear). Loose-ends flyout: questions, approvals, and reminders pending against this agent (`GET /api/loose-ends`); question rows carry an inline answer form that POSTs cross-origin to -the core dashboard's `/answer-question/{id}` so the operator answers +the core dashboard's `POST /api/answer-question/{id}` so the operator answers *as operator* (see `docs/boundary.md`). Tasks flyout: in-flight bash tasks (`GET /api/bash-tasks`); each row shows status (`▶ running` / `◷ queued`), the task id, elapsed time, and a truncated one-line @@ -172,7 +172,7 @@ the slot list and pairs each unbound slot with the first unclaimed pending operator-bound question whose `question` text matches the slot's stashed `_askQuestion`. On match the slot mounts the `buildAnswerForm` (same form shape as the loose-ends flyout — -POSTs to the core's `/answer-question/{id}` cross-origin). Slots +POSTs to the core's `POST /api/answer-question/{id}` cross-origin). Slots stay in the array after binding so the reconciler can flip them to a neutral `[resolved]` tag when the question later disappears from the pending list. Disappearance can mean answered, cancelled From 2f504247edf32291768dcc37090024e6b6c97090 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:42:14 +0200 Subject: [PATCH 2/8] docs(turn-loop): document optional HTTP MCP transport (httpPort) When hyperhive.mcp.httpPort is set in agent.nix, the hive-mcp-http systemd daemon runs the embedded MCP server as a persistent streamable- HTTP service; claude-mcp-config.json points at the HTTP URL instead of spawning a stdio child per turn. Document both modes in the subcommand list and the on-boot files section. --- docs/turn-loop.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/turn-loop.md b/docs/turn-loop.md index e221233b..06e8be61 100644 --- a/docs/turn-loop.md +++ b/docs/turn-loop.md @@ -66,8 +66,10 @@ Three subcommands: - `serve` — long-running harness loop (the inbox poll + claude-pump + ack/requeue cycle described above). -- `mcp` — stdio MCP server claude spawns via `--mcp-config` per - turn. Same binary, different mode. +- `mcp` — MCP server. Default: stdio child claude spawns via + `--mcp-config` per turn. With `--http `, runs as a persistent + streamable-HTTP daemon instead (used by the `hive-mcp-http` + systemd unit when `hyperhive.mcp.httpPort` is set). - `wake --from --body ` — push a message into our own inbox so the next turn fires with the given body. Used by co-process daemons (matrix bridge, scraper, webhook listeners) @@ -267,9 +269,13 @@ next turn picks it up like any other inbox message. `hive_ag3nt::turn::write_*` writes two files next to the per-agent socket at `/run/hive/` once at startup: -- `claude-mcp-config.json` — re-invokes the running binary as `mcp` - child (so the same binary serves as harness + as claude's MCP - child process). +- `claude-mcp-config.json` — by default re-invokes the running binary + as `mcp` stdio child (so the same binary serves as harness + MCP + server per turn). When `hyperhive.mcp.httpPort` is set in the + agent's NixOS config, the config instead points claude at the + persistent `hive-mcp-http` daemon (`http://127.0.0.1:{port}/mcp`) + — no stdio child per turn; trades the per-turn re-registration race + for a hard dependency on the daemon's uptime (`Restart=always`). - `claude-system-prompt.md` — rendered from `hive-ag3nt/prompts/system.md` by `hive_ag3nt::prompt::render`: HTML-comment markers (`...`, From 3036472a55500ee7030235dd44f29030b68ae808 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:43:48 +0200 Subject: [PATCH 3/8] docs(tools/forge): note that comments verb includes PR review bodies hive-forge comments on a PR now merges review bodies (the summary text from approve / request-changes / comment reviews) into the comment listing, fixed in 1cff77f5. The verb list inline comment and the 'Which read verb when' table row both said 'only the comments' which was stale. Updated both to reflect the review-body inclusion. --- docs/tools/forge.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools/forge.md b/docs/tools/forge.md index fb5c5821..8ff08374 100644 --- a/docs/tools/forge.md +++ b/docs/tools/forge.md @@ -34,7 +34,7 @@ hive-forge pr status --pr 42 # PR health (mergeable / CI / review hive-forge issue create --title "..." --body "..." # --- flat aliases below remain valid (hidden) --- hive-forge view 42 # title + body + comments (marks thread read) -hive-forge comments 42 # list all comments (human-readable; marks thread read) +hive-forge comments 42 # list all comments (human-readable; marks thread read); for PRs, review bodies merged in hive-forge comments 42 --tail 10 # last 10 comments (count-then-page; efficient on long threads) hive-forge --json comments 42 # same as above, JSON array (global flag) hive-forge comment 42 --body "..." # post comment (inline body) @@ -95,7 +95,7 @@ distinct output shape — pick by what you need: |------|------|-------| | The full human view of one item — title, body, **and** every comment in order | `view ` | prose dump; **marks the thread read** (clears the read-before-comment guard). Top-level `view` auto-detects issue-or-PR by number; scoped `issue view ` / `pr view ` do the same when you already know the kind | | Just the structured metadata of one item (state, labels, assignees, head sha…) | `issue ` / `pr ` | JSON object | -| Only the comments (skip the body), e.g. to catch up a long thread | `comments ` [`--tail N`] | comment list; **marks read** | +| Only the comments (skip the body), e.g. to catch up a long thread; for PRs, review bodies (approve/request-changes/comment summaries) are merged in too | `comments ` [`--tail N`] | comment + review-body list; **marks read** | | One specific comment by its id | `comment-show ` | single comment | | The audit trail — closes, label/assignee changes, commit refs, merges (no comment bodies) | `timeline ` | event list | | The code change | `diff ` | unified diff | From 9162ce7dc717c9641e34a26940c88ba8f12b4924 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:53:55 +0200 Subject: [PATCH 4/8] docs(turn-loop): document active bash tasks in get_loose_ends output feat 3c853c2b58ce7ba5e9df1af94c87f9412d0148f8 added active bash tasks to the get_loose_ends response but only updated the MCP server tool description string; the docs/turn-loop.md entry for the tool still only mentioned questions and reminders. Add 'active local tasks published by external MCP daemons (e.g. running bash tasks from hive-bash-mcp)' to the tool description so agents reading the reference docs see the full picture. --- docs/turn-loop.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/turn-loop.md b/docs/turn-loop.md index 06e8be61..9c03d80b 100644 --- a/docs/turn-loop.md +++ b/docs/turn-loop.md @@ -539,13 +539,14 @@ ttl_seconds?, to?)`, `answer(id, answer)`. `cancel_loose_end(kind, id)`, `remind(message, delay_seconds? | at_unix_timestamp?)`, `request_next_turn()`. -- `get_loose_ends(agent?)` — list pending questions (asked/owed) and - scheduled reminders. Each row carries an id + kind for - `cancel_loose_end`. Omit `agent` to list your own threads. Pass - `agent: ""` to inspect a direct child agent (always - accessible per topology enforcement); non-children require the - `query_agent_state` capability. The `"*"` hive-wide query is not - available on the agent socket. +- `get_loose_ends(agent?)` — list pending questions (asked/owed), + scheduled reminders, and active local tasks published by external MCP + daemons (e.g. running bash tasks from `hive-bash-mcp`). Each row + carries an id + kind for `cancel_loose_end`. Omit `agent` to list + your own threads. Pass `agent: ""` to inspect a direct child + agent (always accessible per topology enforcement); non-children + require the `query_agent_state` capability. The `"*"` hive-wide + query is not available on the agent socket. - `cancel_loose_end` — withdraw a `question` (posts `[cancelled by ]`), hard-delete a `reminder`, or cancel a pending `approval` row. Agents may only cancel rows they own; the `approval` kind is From c7c2536e3411033880fb200e8bdc6bfa92e6efe4 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:55:39 +0200 Subject: [PATCH 5/8] docs(tools/bash): document mcp__bash__kill tool MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat b16629801bfd2c88ba2a5b201d93ca4fd1939036 added the kill tool to hive-bash-mcp but docs/tools/bash.md wasn't updated. The tool was described only in the MCP server tool-description string; add a proper section to the reference doc. kill(id, force?) fires SIGINT (force: false, default) or SIGKILL (force: true) to the task's process group. Fire-and-forget — the completion wake fires as usual. A pending task is cancelled outright. Escalation pattern: SIGINT first, then force: true if it doesn't exit. --- docs/tools/bash.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/tools/bash.md b/docs/tools/bash.md index be9f8205..7b46886b 100644 --- a/docs/tools/bash.md +++ b/docs/tools/bash.md @@ -56,6 +56,24 @@ silently blocked. Exposed as `mcp__bash__status`. +### `kill(id, force?)` + +Stop a running or pending task by its ID (from `run`). Fire-and-forget: +sends the signal and returns without waiting — handle the completion +wake (`from: "bash-task-"`) on a future turn. + +- `force: false` (default) — SIGINT to the task's **process group** + (graceful; lets the process clean up). The whole process group is + signalled, so children spawned by the shell (cargo, nix, etc.) are + also stopped. +- `force: true` — SIGKILL. + +If a SIGINT'd task doesn't exit, call `kill` again with `force: true`. +A still-pending task is cancelled before it starts. The task ends as +`killed` and fires the usual completion wake. + +Exposed as `mcp__bash__kill`. + ## Namespace note `run` and `status` live in the `bash` MCP server, not `hyperhive`. So From eb04225ddf20c5230d3b2928caa0b90b3a2dee3a Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 12:56:21 +0200 Subject: [PATCH 6/8] docs(tools/bash): add killed to status tool status enum The kill tool (previous commit) produces the 'killed' terminal status, but the status tool docs listed only pending/running/done/timed_out/ interrupted. Add 'killed' to complete the enum. --- docs/tools/bash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/bash.md b/docs/tools/bash.md index 7b46886b..4bdf6aa2 100644 --- a/docs/tools/bash.md +++ b/docs/tools/bash.md @@ -40,7 +40,7 @@ Exposed as `mcp__bash__run`. Poll the status of a task submitted with `run`. Returns: -- `status` — `pending` / `running` / `done` / `timed_out` / `interrupted` +- `status` — `pending` / `running` / `done` / `timed_out` / `interrupted` / `killed` - `exit_code` — set when done - run duration - last 4 KiB of stdout and stderr (full output in the `.out` / `.err` files) From 64d60e5cdb1de085d8af13d896e385acaa1fb287 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 14:09:51 +0200 Subject: [PATCH 7/8] docs(turn-loop): mention kill in bash allowed-tools note The allowed-tools note only named run/status; kill is also always available since the bash MCP server uses allowedTools = ["*"]. Reword to name all three and explain the wildcard mechanism. --- docs/turn-loop.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/turn-loop.md b/docs/turn-loop.md index 9c03d80b..92678187 100644 --- a/docs/turn-loop.md +++ b/docs/turn-loop.md @@ -645,9 +645,9 @@ status hint moved to the wake prompt + UI header. `Bash` is disallowed — shell execution goes through `mcp__bash__run` (background tasks with structured output + -task-id tracking) instead of an interactive shell. The `run` / -`status` MCP tools (`mcp__bash__run` / `mcp__bash__status`) are always -in the `--allowedTools` list. +task-id tracking) instead of an interactive shell. The bash MCP server +(`run` / `status` / `kill`) uses `allowedTools = ["*"]` so all +`mcp__bash__*` tools are always available regardless of tool groups. `WebFetch` / `WebSearch` are off by default; enable the `web_tools` tool group in the P3RM1SS10NS tab and rebuild the agent to enable them. From dd67cfbe97188b9051b452f0c433f3c97d4bf425 Mon Sep 17 00:00:00 2001 From: iris Date: Thu, 2 Jul 2026 14:10:11 +0200 Subject: [PATCH 8/8] docs(tools/bash): fix stale sh -c -> bash invocation note feat 2d97401f changed the bash runner from sh to bash but docs/tools/bash.md still said 'sh -c '. Correct to 'runs via bash'. --- docs/tools/bash.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/bash.md b/docs/tools/bash.md index 4bdf6aa2..85c899a0 100644 --- a/docs/tools/bash.md +++ b/docs/tools/bash.md @@ -11,7 +11,7 @@ invocation regardless of tool groups. ### `run(cmd, timeout_secs?, wait_seconds?, name?)` -Submit a shell command for background execution (`sh -c `). +Submit a shell command for background execution (runs via `bash`). Stdout and stderr stream to `harness/bash-tasks/.{out,err}`. When the task completes (or times out, or the process errors), the harness fires a wake with `from: "bash-task-"` and the exit code