Compare commits

..
Author SHA1 Message Date
damocles
f5351eb59c fix(#1194): update Execution tool names + frontend + docs 2026-06-03 21:20:49 +02:00
damocles
18e0e8fc2b rename bash tools: bash_run/bash_status → run/status (#1186) 2026-06-03 21:20:49 +02:00
9 changed files with 29 additions and 27 deletions

View file

@ -285,7 +285,7 @@ binary flavor.
| `messaging` | `send`, `recv`, `ask`, `answer` | | `messaging` | `send`, `recv`, `ask`, `answer` |
| `meta` | `set_status`, `get_agent_meta` | | `meta` | `set_status`, `get_agent_meta` |
| `inbox` | `get_loose_ends`, `cancel_loose_end`, `remind`, `request_next_turn` | | `inbox` | `get_loose_ends`, `cancel_loose_end`, `remind`, `request_next_turn` |
| `execution` | `bash_run`, `bash_status` | | `execution` | `run`, `status` (`mcp__bash__run`, `mcp__bash__status`) |
| `lifecycle` | `kill`, `start`, `restart`, `update` *(privileged)* | | `lifecycle` | `kill`, `start`, `restart`, `update` *(privileged)* |
| `approvals` | `request_init_config`, `request_apply_commit`, `request_update_meta_inputs` *(privileged)* | | `approvals` | `request_init_config`, `request_apply_commit`, `request_update_meta_inputs` *(privileged)* |
| `scheduling` | `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, `edit_schedule`, `list_schedules` *(privileged)* | | `scheduling` | `request_schedule_prompt`, `fire_schedule_now`, `cancel_schedule`, `edit_schedule`, `list_schedules` *(privileged)* |

View file

@ -35,7 +35,7 @@ force-clear `HOST_ADDRESS` / `LOCAL_ADDRESS` / `HOST_ADDRESS6` /
The hive-c0re service sets `path = [ pkgs.git "/run/current-system/sw" ]`. The hive-c0re service sets `path = [ pkgs.git "/run/current-system/sw" ]`.
In-container harness services do the same so anything an agent adds In-container harness services do the same so anything an agent adds
to its own `agent.nix` (`environment.systemPackages`) is visible to to its own `agent.nix` (`environment.systemPackages`) is visible to
the `bash_run` MCP tool (and any other in-container process) without the `mcp__bash__run` MCP tool (and any other in-container process) without
editing the service definition. editing the service definition.
`environment.HYPERHIVE_GIT` bakes git's absolute path in (read by `environment.HYPERHIVE_GIT` bakes git's absolute path in (read by
`lifecycle::git_command()`) for the host. `lifecycle::git_command()`) for the host.

View file

@ -177,7 +177,7 @@ Under `/var/lib/hyperhive/agents/<name>/`:
agent consumption. Bind-mounted to `/agents/<name>/harness` agent consumption. Bind-mounted to `/agents/<name>/harness`
inside the container (`$HYPERHIVE_HARNESS_DIR`). Contents: inside the container (`$HYPERHIVE_HARNESS_DIR`). Contents:
- `bash-tasks/` — task JSON + stdout/stderr files for - `bash-tasks/` — task JSON + stdout/stderr files for
background `bash_run` jobs. JSON files are background `mcp__bash__run` jobs. JSON files are
`<id>.json` (status + tails), `<id>.out` / `<id>.err` `<id>.json` (status + tails), `<id>.out` / `<id>.err`
(full captured output). Task files persist until container (full captured output). Task files persist until container
purge. purge.

View file

@ -373,20 +373,21 @@ it as a stdio child via `--mcp-config`. The hyperhive socket name is
continue without waiting for an external message. The next turn starts continue without waiting for an external message. The next turn starts
with `from: "self"` and `body: "continue"`. No-op if new inbox with `from: "self"` and `body: "continue"`. No-op if new inbox
messages arrive before this turn ends. No args. messages arrive before this turn ends. No args.
- `bash_run(cmd, timeout_secs?)` — submit a shell command for - `run(cmd, timeout_secs?)` — submit a shell command for
background execution (`sh -c <cmd>`). Returns a task ID immediately; background execution (`sh -c <cmd>`). Returns a task ID immediately;
the command runs asynchronously in a harness-managed tokio task. Stdout the command runs asynchronously in a harness-managed tokio task. Stdout
and stderr stream to `harness/bash-tasks/<id>.{out,err}`. When the and stderr stream to `harness/bash-tasks/<id>.{out,err}`. When the
task completes (or times out, or the process errors), the harness wakes task completes (or times out, or the process errors), the harness wakes
the agent with a summary body — handle on a future turn. Default the agent with a summary body — handle on a future turn. Default
timeout 180s; pass `timeout_secs` to override. Requires the timeout 180s; pass `timeout_secs` to override. Requires the
`execution` tool group. `execution` tool group. Exposed as `mcp__bash__run`.
- `bash_status(id)` — poll the status of a task submitted with - `status(id)` — poll the status of a task submitted with
`bash_run`. Returns status (`pending`/`running`/`done`/`timed_out`/ `run`. Returns status (`pending`/`running`/`done`/`timed_out`/
`interrupted`), exit code, run duration, and the last 4 KiB of stdout `interrupted`), exit code, run duration, and the last 4 KiB of stdout
and stderr (full output in the `.out`/`.err` files). Tasks marked and stderr (full output in the `.out`/`.err` files). Tasks marked
`interrupted` had their process killed by a harness restart; a best- `interrupted` had their process killed by a harness restart; a best-
effort wake was still sent so the agent is not silently blocked. effort wake was still sent so the agent is not silently blocked.
Exposed as `mcp__bash__status`.
### Waking the agent from inside the container ### Waking the agent from inside the container
@ -581,9 +582,10 @@ status hint moved to the wake prompt + UI header.
- Allowed MCP tools: as listed above per flavor. - Allowed MCP tools: as listed above per flavor.
`Bash` is disallowed — shell execution goes through `Bash` is disallowed — shell execution goes through
`mcp__hyperhive__bash_run` (background tasks with structured output + `mcp__bash__run` (background tasks with structured output +
task-id tracking) instead of an interactive shell. The `bash_run` / task-id tracking) instead of an interactive shell. The `run` /
`bash_status` MCP tools are always in the `--allowedTools` list. `status` MCP tools (`mcp__bash__run` / `mcp__bash__status`) are always
in the `--allowedTools` list.
`WebFetch` / `WebSearch` are off by default; enable the `web_tools` `WebFetch` / `WebSearch` are off by default; enable the `web_tools`
tool group in the P3RM1SS10NS tab and rebuild the agent to enable them. tool group in the P3RM1SS10NS tab and rebuild the agent to enable them.

View file

@ -1254,13 +1254,13 @@ window.marked = marked;
case 'mcp__hyperhive__kill': return short + ' ' + (input.name || ''); case 'mcp__hyperhive__kill': return short + ' ' + (input.name || '');
case 'mcp__hyperhive__request_apply_commit': case 'mcp__hyperhive__request_apply_commit':
return short + ' ' + (input.agent || '') + ' @ ' + (input.commit_ref || '').slice(0, 12); return short + ' ' + (input.agent || '') + ' @ ' + (input.commit_ref || '').slice(0, 12);
case 'mcp__bash__bash_run': { case 'mcp__bash__run': {
// Rich renderer handles the full body; this summary covers any // Rich renderer handles the full body; this summary covers any
// fallback path and the details summary line. // fallback path and the details summary line.
const firstLine = String(input.cmd || '').split('\n')[0]; const firstLine = String(input.cmd || '').split('\n')[0];
return short + ' $ ' + trim(firstLine.trim(), 72); return short + ' $ ' + trim(firstLine.trim(), 72);
} }
case 'mcp__bash__bash_status': case 'mcp__bash__status':
return short + ' id:' + (input.id || '?') return short + ' id:' + (input.id || '?')
+ (input.wait_seconds != null ? ' · wait ' + input.wait_seconds + 's' : ''); + (input.wait_seconds != null ? ' · wait ' + input.wait_seconds + 's' : '');
default: return fmtArgsGeneric(short, input); default: return fmtArgsGeneric(short, input);
@ -1354,10 +1354,10 @@ window.marked = marked;
// Bash task runner — show full command in an expandable pre block so // Bash task runner — show full command in an expandable pre block so
// multi-line scripts are readable. Summary uses the first line so the // multi-line scripts are readable. Summary uses the first line so the
// row is identifiable without expanding. // row is identifiable without expanding.
if (name === 'mcp__bash__bash_run') { if (name === 'mcp__bash__run') {
const cmd = String(input.cmd || ''); const cmd = String(input.cmd || '');
const firstLine = cmd.split('\n')[0]; const firstLine = cmd.split('\n')[0];
const summary = 'bash_run* $ ' + trim(firstLine.trim(), 72); const summary = 'run* $ ' + trim(firstLine.trim(), 72);
return api.details('tool-use', summary, '$ ' + cmd); return api.details('tool-use', summary, '$ ' + cmd);
} }
return null; return null;

View file

@ -2003,7 +2003,7 @@ pub const SERVER_NAME: &str = "hyperhive";
/// exist in the session. Web egress (`WebFetch`/`WebSearch`) are /// exist in the session. Web egress (`WebFetch`/`WebSearch`) are
/// tool-group-gated (`web_tools`) — off by default. Nested agents /// tool-group-gated (`web_tools`) — off by default. Nested agents
/// (`Task`) are intentionally omitted. `Bash` is disallowed — shell /// (`Task`) are intentionally omitted. `Bash` is disallowed — shell
/// execution goes through `mcp__hive_bash__bash_run` (background tasks /// execution goes through `mcp__bash__run` (background tasks
/// with structured output via `hive-bash-mcp`) instead of a raw interactive shell. `TodoWrite` /// with structured output via `hive-bash-mcp`) instead of a raw interactive shell. `TodoWrite`
/// is omitted because the todo list lives in claude's in-process session /// is omitted because the todo list lives in claude's in-process session
/// state and silently evaporates on /compact or session reset — agents /// state and silently evaporates on /compact or session reset — agents

View file

@ -142,7 +142,7 @@ struct BashRunArgs {
/// `timed_out` when the limit is exceeded. /// `timed_out` when the limit is exceeded.
#[serde(default)] #[serde(default)]
timeout_secs: Option<u64>, timeout_secs: Option<u64>,
/// Optional inline wait: `bash_run` polls for up to `wait_seconds` /// Optional inline wait: `run` polls for up to `wait_seconds`
/// (capped at 30) before returning. When the task finishes within the /// (capped at 30) before returning. When the task finishes within the
/// window the full status is returned immediately and no wake is fired; /// window the full status is returned immediately and no wake is fired;
/// when the timeout expires the task keeps running and the normal /// when the timeout expires the task keeps running and the normal
@ -158,9 +158,9 @@ fn default_wait() -> Option<u64> {
#[derive(Debug, Deserialize, JsonSchema)] #[derive(Debug, Deserialize, JsonSchema)]
struct BashStatusArgs { struct BashStatusArgs {
/// Task ID returned by `bash_run`. /// Task ID returned by `run`.
id: String, id: String,
/// Optional inline wait: `bash_status` polls for up to `wait_seconds` /// Optional inline wait: `status` polls for up to `wait_seconds`
/// (capped at 30) before returning. Useful to avoid a separate /// (capped at 30) before returning. Useful to avoid a separate
/// round-trip when the task is expected to finish soon. /// round-trip when the task is expected to finish soon.
#[serde(default)] #[serde(default)]
@ -176,7 +176,7 @@ impl BashMcp {
description = "Run a shell command in the background. Returns a task ID immediately — \ description = "Run a shell command in the background. Returns a task ID immediately — \
do NOT wait inline. When the command finishes, the harness fires a wake with \ do NOT wait inline. When the command finishes, the harness fires a wake with \
`from: \"bash-task-<id>\"` and the exit code + last stdout lines in the body; \ `from: \"bash-task-<id>\"` and the exit code + last stdout lines in the body; \
handle it on a future turn. Use `bash_status` to poll the task status within \ handle it on a future turn. Use `status` to poll the task status within \
the same turn if needed. `timeout_secs` defaults to 180. Pass `wait_seconds` \ the same turn if needed. `timeout_secs` defaults to 180. Pass `wait_seconds` \
(capped at 30) to wait inline for fast commands: when the task finishes within \ (capped at 30) to wait inline for fast commands: when the task finishes within \
the window the full status is returned immediately and no wake is fired; when \ the window the full status is returned immediately and no wake is fired; when \
@ -184,7 +184,7 @@ impl BashMcp {
response is returned. `wait_seconds` defaults to 3; pass `wait_seconds: 0` to \ response is returned. `wait_seconds` defaults to 3; pass `wait_seconds: 0` to \
disable inline waiting and always get the immediate response." disable inline waiting and always get the immediate response."
)] )]
async fn bash_run(&self, Parameters(args): Parameters<BashRunArgs>) -> String { async fn run(&self, Parameters(args): Parameters<BashRunArgs>) -> String {
let req = DaemonRequest::BashRun { let req = DaemonRequest::BashRun {
cmd: args.cmd, cmd: args.cmd,
timeout_secs: args.timeout_secs, timeout_secs: args.timeout_secs,
@ -202,7 +202,7 @@ impl BashMcp {
} }
#[tool( #[tool(
description = "Check the status of a background bash task by its ID (from `bash_run`). \ description = "Check the status of a background bash task by its ID (from `run`). \
Returns the current status (pending/running/done/timed_out/interrupted), exit code \ Returns the current status (pending/running/done/timed_out/interrupted), exit code \
if finished, and a tail of stdout/stderr. Full output lives in \ if finished, and a tail of stdout/stderr. Full output lives in \
`harness/bash-tasks/<id>.out` / `.err`. \ `harness/bash-tasks/<id>.out` / `.err`. \
@ -210,7 +210,7 @@ impl BashMcp {
task finishes within the window the full status is returned immediately. Useful to \ task finishes within the window the full status is returned immediately. Useful to \
avoid a separate round-trip when the task is expected to finish soon." avoid a separate round-trip when the task is expected to finish soon."
)] )]
async fn bash_status(&self, Parameters(args): Parameters<BashStatusArgs>) -> String { async fn status(&self, Parameters(args): Parameters<BashStatusArgs>) -> String {
let id = args.id.clone(); let id = args.id.clone();
let req = DaemonRequest::BashStatus { let req = DaemonRequest::BashStatus {
id: args.id, id: args.id,

View file

@ -804,7 +804,7 @@ pub enum ToolGroup {
Scheduling, Scheduling,
/// `get_logs` - *(privileged)* /// `get_logs` - *(privileged)*
Diagnostics, Diagnostics,
/// `bash_run`, `bash_status` /// `run`, `status` (via `mcp__bash__*`)
Execution, Execution,
/// Claude built-in web egress tools: `WebFetch` (retrieve a URL) and /// Claude built-in web egress tools: `WebFetch` (retrieve a URL) and
/// `WebSearch` (search the web). Both are omitted from `--tools` by /// `WebSearch` (search the web). Both are omitted from `--tools` by
@ -843,7 +843,7 @@ impl ToolGroup {
"list_schedules", "list_schedules",
], ],
Self::Diagnostics => &["get_logs"], Self::Diagnostics => &["get_logs"],
Self::Execution => &["bash_run", "bash_status"], Self::Execution => &["run", "status"],
Self::WebTools => &[], Self::WebTools => &[],
} }
} }
@ -928,7 +928,7 @@ impl ToolGroup {
Self::Diagnostics => { Self::Diagnostics => {
"get_logs — read a sub-agent container's systemd journal (privileged)" "get_logs — read a sub-agent container's systemd journal (privileged)"
} }
Self::Execution => "bash_run, bash_status — run shell commands in the container", Self::Execution => "run, status — run shell commands via mcp__bash__run / mcp__bash__status",
Self::WebTools => "WebFetch, WebSearch — Claude built-in web egress; not MCP tools", Self::WebTools => "WebFetch, WebSearch — Claude built-in web egress; not MCP tools",
} }
} }

View file

@ -134,7 +134,7 @@ in
default = [ ]; default = [ ];
description = '' description = ''
Deprecated - has no effect. The built-in Bash tool is fully Deprecated - has no effect. The built-in Bash tool is fully
disabled regardless of this list; agents use mcp__hyperhive__bash_run disabled regardless of this list; agents use mcp__bash__run
instead. Remove this option from your agent.nix. instead. Remove this option from your agent.nix.
''; '';
visible = false; visible = false;
@ -612,7 +612,7 @@ in
config = { config = {
warnings = lib.optional (config.hyperhive.allowedBashPatterns != [ ]) '' warnings = lib.optional (config.hyperhive.allowedBashPatterns != [ ]) ''
hyperhive.allowedBashPatterns is deprecated and has no effect. hyperhive.allowedBashPatterns is deprecated and has no effect.
The built-in Bash tool is fully disabled; agents use mcp__hyperhive__bash_run instead. The built-in Bash tool is fully disabled; agents use mcp__bash__run instead.
Remove allowedBashPatterns from your agent.nix. Remove allowedBashPatterns from your agent.nix.
''; '';