About tmux-agent-tools
A skill for managing AI coding CLI workers in tmux through the agent-tmux command set. It provides verified task dispatch, bounded supervision, structured results, and worker cleanup for agent workflows.
Key features
- 01Run coding CLIs as managed tmux workers
- 02Dispatch tasks with submission verification
- 03Track worker status and bounded waits
- 04Collect structured result.json outputs
- 05Coordinate multiple workers with watch
- 06Manage sessions and worker cleanup
Use cases
- 01Supervise long-running Claude Code or Codex tasks
- 02Collect structured results from delegated workers
- 03Coordinate completion across multiple workers
- 04Resume and inspect worker sessions
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ ohyeh/ tmux-agent-tools --skill tmux-agent-toolsAfter installing, type/tmux-agent-toolsin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agents/openai.yamlreferences/cheatsheets.mdcontracts.mdcore-workflow.mdmulti-agent.mdprofiles.mdrecipes.mdsecurity.mdtroubleshooting.mdschemas/dashboard.schema.jsonfanout-summary.schema.jsonresult-status-summary.schema.jsonscripts/agent-tmuxinstall-binscripts/lib/channel.contract.node.tscollector.contract.node.tscollector.node.tsdotted-target.contract.node.tseaw-table.tsscripts/lib/fixtures/composer/agy-busy.txtagy-draft.txtagy-empty.txtagy-multiline.txtagy-permission.txtclaude-busy-start.txtclaude-busy.txtclaude-done.txtclaude-draft.txtclaude-empty.txtclaude-multiline.txtDetails
From the project READMETmux Agent Tools
Fast paths (read this first)
Non-negotiable rules:
- Engine-only — never type raw
tmuxat a worker. Drive every worker throughagent-tmux <cli>subcommands (send-wait,status,result,capture,stop); read-only inventory istmux-agent-sessions list, not rawtmux ls. Rawtmuxbypasses naming, redaction, result contracts, and cleanup. Before concluding the engine lacks a command, check the capability table below; plain shell is a last resort for genuine gaps — say why. - A
sendis not done until submission is verified. Baresendcan leave text unsent in the input box. Default tosend-wait: it appends a fresh nonce and waits for it, confirming the prompt landed. - Every blocking wait takes a timeout — never hand-roll
sleep/polling loops. Multiple workers: one boundedwatch --any|--all|--count <n> --timeout <s> --json …. Mixed-engine fleets: trustreason:result_updatedor resolve withtmux-agent-sessions. - Reusing a worker for a follow-up task?
result initfirst, thensend-wait, thenresult wait-required— never reuse withoutresult init, or the wait returns the stale prior result. Details:references/multi-agent.md#persistent-teammates-worker-reuse.
Fast answers:
- Bounded task with no follow-ups? Default to interactive
start(headed): the tmux pane is the debug surface —capture,status, or attaching shows exactly what the CLI is doing, mid-run and post-mortem.start --headless(claude -p/codex exec) is OPT-IN only: user explicitly asks for it, or the output is trivially verifiable and nobody will need to inspect the run. A headless failure leaves only an exit code and a stdout file — repeatedly observed to cost long blind-debugging sessions (user ruling 2026-08-03: headed by default). - Wrapper not on PATH? Run it from this bundle:
<skill-dir>/scripts/agent-tmux codex …. - Worker "failed" but the pane says PASS? Exit code is not the verdict — see
references/core-workflow.md#5-read-the-agents-structured-result("Exit code is not the verdict") before re-dispatching or reporting failure. - Auto-delegate substantial work? Use the inline-vs-worker gate in the
using-tmux-agent-toolsskill (absorbed there, no longer a separate subagent); details live inreferences/core-workflow.md. - Long-running external CLI worker (Codex or Claude Code)? Dispatch it with ONE
agent-tmux <cli> assign <name> <dir> <prompt-file>call — the stepwise sequence (start → result init → send → confirm-processing → blocking supervise) IS the supervision, so the proxy hosts it and nothing else (the OLD per-worker polling proxy stays retired, 2026-08-08). The host is ONE supervision proxy — ageneral-purposesubagent onsonnetlow whose brief runs that singleassigncall and reports its exit code (seemodel-dispatch.md§4, 2026-08-17/18 rulings). Parent foregroundassignis banned in ALL forms,--detachincluded, and is denied at the tool call by thetmux-assign-host-gatehook; parentrun_in_backgroundis REQUIRED, not a last-resort fallback, whenever the proxy reports anything non-terminal — measured 2026-08-30, the harness reaps a proxy's foreground call at ~600s and a subagent has noTaskOutput, so a reaped proxy can only report in-flight and the parent must own the wait itself (a task orphaned by a terminated subagent notifies nobody; incident c48c0d3a lost 2h40m that way). Log the reason in the run dir, and never pipe the listener — a trailing| tailreportstail's status, so the wrapper'sexit 2reads as success. The parent MUST NOT additionally pollstatus/capture/probeunlessassignreports a failed step or the user asks; harvest with boundedresult wait-required --wait <s>calls. Apendingresult is a TERMINATING PROCEDURE, not a verdict: keep waiting within the bound → bound expires still pending, re-prompt the worker ONCE with the literal path fromresult --path <name>and wait one more bounded round → only then may a pane capture stand in, labelled UNCONFIRMED and never shipped as a verified answer. Heedassign'sresult-path delivery UNCONFIRMEDwarning — a worker that never learned its path can never write result.json, so thatpendingis permanent. Teardown order: stand the proxy DOWN BEFORE stopping the worker it supervises, or the proxy is stranded on a signal that can no longer arrive. Never brief a proxy to return the worker's output verbatim — it is forbidden to read that output, so the brief is unsatisfiable; have the WORKER write to a declared artifact path and read that file yourself. - Writing the worker prompt? Shape it with the
delegation-templatesskill: GOAL / ACCEPTANCE / REPORT + common footer, plus its tmux addendum (no-cascade ban + literal result path). - New or renamed CLI? Add a profile with
bin=…, then prove it withdoctor --jsonandstart --dry-run; seereferences/profiles.md.
Overview
agent-tmux <cli> <command> runs any AI coding CLI as a managed tmux worker; claude/codex/agy are built-in presets, other CLIs use an optional profile. There are no per-CLI binaries — always spell agent-tmux <cli> <command>.
Required preflight and safe invocation
Before the first worker command:
- Resolve the wrapper bundle instead of assuming PATH. Probe, in order,
<repo-dir>/skills/tmux-agent-tools/scripts,~/.agents/skills/tmux-agent-tools/scripts,~/.claude/skills/tmux-agent-tools/scripts, and~/.codex/skills/tmux-agent-tools/scripts; use bare wrapper names only when no bundle exists and PATH lookup succeeds. - Run the resolved
agent-tmux <cli> setupand stop if preflight fails. - Pass the raw task as a separately quoted argument or prompt-file content.
Never interpolate task text into
eval,sh -c, or a constructed shell command. - Pass task-specific credentials only through
--secret KEY=URI. Never embed credential values in task text or a constructed shell command.
When to use
- Long-running Claude/Codex/agy/custom CLI work that needs later supervision.
- A worker must write structured
result.jsonfor a parent agent or wrapper. - You need verified follow-up sends, liveness/status checks, bounded waits, or cleanup.
- Multiple workers need first/all/N completion via one wrapper
watchcall.
Command choice
| Need | Use |
|---|---|
| Run Claude Code / Codex / agy as a worker | agent-tmux claude / agent-tmux codex / agent-tmux agy |
| Any other CLI (gemini, cursor, grok, custom) | agent-tmux <cli> (+ optional profile) |
| Any worker, including bounded one-shots | interactive start (headed) — pane = debug surface; DEFAULT |
| Trivially verifiable fire-and-collect, user opted in | start --headless — completion = process exit; failures leave only exit code + stdout file |
| Local working directory | start |
| Repo on another host, tmux stays local | start-ssh |
| Pin a model for one run | start --model <m> <name> <dir> '<prompt>' |
| Continue an existing CLI session UUID | resume (opt-in, off by default) |
| Don't know which wrapper owns a session | tmux-agent-sessions resolve --name <n> --json first |
| Two-party exchange / one-to-many work | tmux-agent-dialogue / tmux-agent-fanout |
| Read-only inventory or evidence polling | tmux-agent-sessions / tmux-agent-monitor |
Start flags precede positionals: start --exact --model <m> <name> <dir>; a misplaced flag exits 2.
Full capability table (every subcommand + when to use it): references/cheatsheets.md.
When not to use
- A one-off shell command or a simple file read, search, test, or build — run it directly instead of spawning a worker.
- Externally visible, destructive, or privacy-sensitive work unless the user has already authorized it.
The 6 commands you need most
# Dispatch a prompt-file task: ONE command runs the whole verified sequence
# (start -> result init -> send --from-file -> confirm the pane is processing
# -> blocking supervise). Prefer this over hand-chaining the steps; it cannot
# be misordered and it catches "task never reached the CLI" before waiting.
agent-tmux codex assign job ~/repo /abs/path/prompt.txt
# Bounded one-shot (headed by default; add --headless only when the user opted in):
agent-tmux codex start --exact job ~/repo 'Task. Write final JSON to the wrapper-provided result path when done.'
agent-tmux codex result wait-required job --fields status,summary --wait 600 --json # returns at process exit
agent-tmux codex supervise --result-required --silent-while-unchanged --json job # one silent call until terminal event
agent-tmux codex stop job
# Interactive one-worker flow (only when follow-ups are needed): start -> send-wait -> supervise -> stop.
agent-tmux codex start --exact worker ~/repo 'Task. Write final JSON to the wrapper-provided result path when done.'
agent-tmux codex send-wait worker 'Follow-up instruction.' 180
agent-tmux codex status --json worker
agent-tmux codex result --json --wait 30 worker
agent-tmux codex stop worker
# Multiple workers: block on first/all/N completion with one bounded call.
agent-tmux codex watch --any --timeout 600 --json w1 w2 w3
Full walkthrough: references/core-workflow.md.
v5 ledger (non-Claude hosts)
Codex, Cursor, and agy do not load the Claude function-hook mod. They use the same v5 ledger, the .v3/ tree under the state root. Node entry points in this bundle: scripts/lib/collector.node.ts (one collector per host session) and scripts/lib/workers.cli.node.ts (cancel, unlock). The workers TUI is scripts/tmux-agent-tui [--session <id>] [--cwd <dir>]: with a session id it is the owner and acts on that session's workers; without one it is a read-only viewer. It needs Node >= 22.18 and a TTY (exit 2 otherwise; --help needs neither). After a skill update, re-run scripts/install-bin: it links only the scripts that existed when it last ran, and agent-tmux <cli> doctor names the missing links. Layout, ownership, and delivery are in the repository document mods/tmux-agent/README.md (收集端); this skill does not restate that layout. Bash guard (tool.call) is Claude-only. Across hosts on one tailnet: scripts/tmux-agent-relay (ensure, send <host> <worker> <text>, roster) and start-ssh --sentinel … --notify (the remote exit lands in status --json as exit_source: "relay"); trust model and refusals are in the README section "Relay (tailnet)".
result.json completion contract
Agents write $TMUX_AGENT_DIR/<name>/result.json with schema_version: 1, canonical status (success|failed|blocked|needs-input), summary, artifacts, and errors (optional verdict/decision, and commit — the full 40-hex sha when a success delivers a commit; the tmux-agent mod checks it is a commit that descends from the dispatch base (HEAD when the episode began) and delivers commit <sha12> verified (…) or success claimed, commit <sha> NOT verified: <reason>; omit it when no commit was made). The first prompt send of a session injects the literal result path (every family by default); the worker cannot rely on $TMUX_AGENT_RESULT inside tool sandboxes. Branch in this order — never scrape the pane when a valid result exists: .present -> .valid -> .body.
--fields names keys in THAT contract, never a prompt placeholder: harvesting with artifact_path (which no worker writes) left two finished workers unharvested for ~24 minutes on 2026-09-08. Ask for status,summary, read .body, and request a produced file as .body.artifacts. A terminal result missing a requested field now exits 3 (event:"contract-mismatch", worker body attached) instead of waiting — fix the field list, do not re-dispatch. A CLI that cannot launch exits 4 at assign step 0 with blocked_reason (keychain_locked, login_required, quota_exhausted, cli_not_found) and starts nothing: report the blocker, do not wait. For a TUI that submits on every newline, dispatch with assign --prompt-delivery file-ref (profile prompt_delivery; agy ships it) — agy received one pasted prompt as 12 separate inputs, GOAL and CONTEXT never arriving, and still reported assigned:true.
agent-tmux codex result --json --wait 30 worker
agent-tmux codex supervise --result-required --silent-while-unchanged --json worker
If .present:false, the agent never wrote the file — re-prompt with the literal path from result --path <name>. Full schema, worked example, status --json fields, approval-gate exit codes, concurrency model: references/contracts.md.
Safety
- Wrappers use permissive CLI flags by default (
--dangerously-skip-permissionsfor Claude,--yolofor Codex). Never use for destructive, privacy-sensitive, externally visible, payment, or irreversible work without explicit user authorization. status --jsonreportsconfirmation_detected:trueplusblocked_reasonwhen a pane appears to wait for confirmation. It does not auto-accept; answer only after you trust it.- Before spawning more than one worker: ask the user for tool+model+effort per worker, set a worker upper bound, and forbid cascade spawning in every prompt. Details:
references/multi-agent.md. - Secret injection (
--secret KEY=URI, fail-closed) and audit log (TMUX_AGENT_TOOLS_AUDIT_LOG):references/security.md.
References
Load these only when you hit the relevant scenario — they are not needed for routine use:
references/core-workflow.md— full single-worker workflow, session naming, remote sessions, peer-review, approval gates, the inline-vs-worker gate.references/profiles.md— custom CLI profile keys, precedence, examples, detection overrides.references/cheatsheets.md— full capability table, scenario commands, marker pitfalls, failure triage.references/multi-agent.md— dialogue/fanout rules, bridge pattern, SSH participants, github-comment behavior.references/contracts.md—status --json/result.jsonschemas, approval exit codes, concurrency, inventory/cleanup.references/security.md— secret injection, audit log, environment overrides, pre-flight checks.references/troubleshooting.md— failure modes and fixes for stuck/unsent/stale-marker scenarios.references/recipes.md— copy-pasteable workflows (approval gate, fanout, DAG).
Bundled schemas
schemas/ ships result-status-summary.schema.json and fanout-summary.schema.json — the offline fallback the scripts already resolve for result.json validation when no other copy is found on disk.
The agents/ subagent bundle (tmux-delegate.md, claude-oneshot.md, codex-oneshot.md) is retired — see CHANGELOG. The inline-vs-worker gate and the one-shot forwarding pattern they carried now live in the using-tmux-agent-tools skill's decision tree; there is nothing to install into ~/.claude/agents/ anymore.