-
Notifications
You must be signed in to change notification settings - Fork 1
Tools Reference
| Tool | Purpose |
|---|---|
sh_run |
Run a command → quiet structured result; full output stored, not re-emitted. background: true starts a long-running process |
sh_detail |
Pull stored stdout/stderr/meta/trace for a past run (no re-run; survives restarts) |
sh_logs |
Poll a background run's output incrementally by byte cursor, plus its status |
sh_kill |
Signal a background run's process group (stop a dev server / watch) |
sh_checkpoint |
Snapshot a directory under a label (CoW clone / rsync) |
sh_restore |
Restore a directory from a checkpoint |
sh_checkpoints |
List checkpoint labels for a project directory |
id (on sh_detail/sh_logs/sh_kill) and label (on sh_checkpoint/sh_restore)
are optional. Omitted, they resolve to the run or checkpoint you almost certainly
mean — the most recent run, the newest live background process, the next auto-N, the
newest checkpoint. A value that resolves to nothing answers with the ones that do.
sh_run also accepts cmd as an alias for command.
Removed in 0.8.0:
sh_planandsh_history. A 30-day audit of real Claude Code sessions measured 0 calls to either across 3.5k sessions whilesh_runtook 3.5k, and every tool costs a slot in the agent's context on every request. The blast-radius classifiersh_planexposed is unchanged and still gates everysh_run.
Executes a command and returns a token-aware structured result. Full output is stored
and addressable via sh_detail — never re-emitted into context.
| Option | Effect |
|---|---|
command |
The shell command (required) |
cwd |
Working directory (defaults to the server's cwd) |
full |
Return uncondensed stdout/stderr inline |
timeout_ms |
Per-command timeout (default 120s). On expiry the whole process group is killed |
expect |
Post-conditions verified in the same call (see below) |
retries / retry_on_exit / backoff_ms
|
Declarative retry; attempts reported when > 1 |
sandbox |
Real OS sandbox: true confines writes to cwd + temp; { network: false } denies network; { writable: [...] } adds roots; { protect_secrets: true } / { deny_read: [...] } block reads of secret dirs. Refuses to run if unavailable — see Sandbox and Trace
|
trace |
Structured FS/syscall trace (Linux strace); best-effort. See Sandbox and Trace
|
scrub_env |
Strip secret-shaped env vars (*_TOKEN/*_KEY/AWS_*/…) before spawn; auto-on with sandbox.protect_secrets. Reports secrets_env_scrubbed (count only) |
no_store |
Keep the run memory-only — addressable via sh_detail this session, never written to disk. For commands that may print secrets |
background |
Start a long-running process and return immediately (id + pid + status). Poll with sh_logs, stop with sh_kill. See Background processes
|
exit, stdout_contains, stdout_matches (regex), stderr_empty, file_exists,
file_absent, changed (tracked files changed), max_ms. Failures surface in
assert_ok + assertions_failed — no second ls/grep/git status needed.
id, exit, ok, ms; then attempts, stdout_lines/stderr_lines (true emitted
counts), files_changed, timed_out, stdout_truncated/stderr_truncated,
stdout_binary/stderr_binary, sandboxed, secrets_protected/secrets_env_scrubbed,
stored ("memory-only" under no_store), trace_summary/trace_unavailable,
assert_ok/assertions_failed, advice, hint, and condensed stdout/stderr.
Effects-as-data note: same-repo runs that compute
files_changedfromgit statusserialize their before→run→after window so concurrent runs never steal each other's changes.trace: true(per-process) andVEIL_EFFECTS=0opt out of that.
sh_detail { "id": "cmd9", "selector": "stdout" } // full stored stream
sh_detail { "id": "cmd9", "selector": "stdout", "match": "ERROR" } // only matching lines + numbers
sh_detail { "id": "cmd9", "selector": "meta" } // metadata only
sh_detail { "id": "cmd9", "selector": "trace" } // full syscall traceRecords are disk-backed, so this works even after the server restarts. match
greps the stored stream so you can pull a value condensing hid without dumping it all.
A normal sh_run blocks until the command exits — wrong for a dev server or a
--watch build that never does. background: true spawns it detached and returns at
once; poll its output with sh_logs and stop it with sh_kill. The same id resolves
live (in-memory) while running and via sh_detail once it exits.
sh_run { "command": "npm run dev", "background": true } // → { id, pid, status: "running", background: true }
sh_logs { "id": "cmd7" } // status + output since the start
sh_logs { "id": "cmd7", "stdout_cursor": 4096 } // ONLY new stdout since that byte cursor
sh_kill { "id": "cmd7", "signal": "SIGTERM" } // stop it (idempotent after exit)-
sh_logs—stream(stdout/stderr/both),full, and per-streamstdout_cursor/stderr_cursor(pass back the values it returns to tail only new output). Reportsstatus(running/exited/killed),exit,signal,running_ms, line counts, and agapflag if output was dropped at the byte cap between polls. -
sh_kill—signal(defaultSIGTERM, with a 2s →SIGKILLescalation); signals the whole process group. After exit it returnsalready_exited, not an error. - Background keeps
cwd,sandbox,scrub_env,no_store, but refuses options that need the command to finish —expect,preview,trace,retries,full,timeout_ms— withbackground_incompatible. - Live processes are reaped when the server shuts down (the agent disconnects), so a
background dev server is never orphaned.
VEIL_MAX_BG_PROCS(default 16) caps how many may run at once.
Every sh_run is classified before it executes: category (read-only / mutating /
destructive / network / complex / unknown), reversibility, and predicted file
effects. A top-level pipeline/list (a && b, c | d) is decomposed and classified
per-segment, worst case wins; substitution/redirect/glob are undecidable and stay
complex. Errors bias toward over-flagging, never under.
This is static analysis and advisory only — it is not an enforcement boundary and not
an execution dry-run. For the latter, use sh_run with preview: true (runs in a
disposable CoW clone) or sandbox: true (real kernel confinement).
sh_checkpoint { "label": "pre-refactor" } // CoW clone (APFS) or rsync mirror
sh_restore { "label": "pre-refactor" } // undo; refuses a target dir != origin
sh_checkpoint {} // no label → auto-1, auto-2, …
sh_restore {} // no label → the newest checkpoint
sh_checkpoints {} // list labels for the current projectCheckpoints are namespaced per project (a hash of the directory), so the same label
taken in two different projects never collides. dir overrides the target on each tool.
sh_run { "command": "npm run build", "expect": { "exit": 0, "file_exists": "dist/index.js" } }