mcpField
T
tmux-agent-tools

tmux-agent-tools

github.com/ohyehAgent workflows0330 installsUpdated today
Repository

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

  1. 01Run coding CLIs as managed tmux workers
  2. 02Dispatch tasks with submission verification
  3. 03Track worker status and bounded waits
  4. 04Collect structured result.json outputs
  5. 05Coordinate multiple workers with watch
  6. 06Manage sessions and worker cleanup

Use cases

  1. 01Supervise long-running Claude Code or Codex tasks
  2. 02Collect structured results from delegated workers
  3. 03Coordinate completion across multiple workers
  4. 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-tools

After installing, type/tmux-agent-toolsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

agents/
openai.yaml
references/
cheatsheets.md
contracts.md
core-workflow.md
multi-agent.md
profiles.md
recipes.md
security.md
troubleshooting.md
schemas/
dashboard.schema.json
fanout-summary.schema.json
result-status-summary.schema.json
scripts/
agent-tmux
install-bin
scripts/lib/
channel.contract.node.ts
collector.contract.node.ts
collector.node.ts
dotted-target.contract.node.ts
eaw-table.ts
scripts/lib/fixtures/composer/
agy-busy.txt
agy-draft.txt
agy-empty.txt
agy-multiline.txt
agy-permission.txt
claude-busy-start.txt
claude-busy.txt
claude-done.txt
claude-draft.txt
claude-empty.txt
claude-multiline.txt

Details

From the project README

Tmux Agent Tools

Fast paths (read this first)

Non-negotiable rules:

  1. Engine-only — never type raw tmux at a worker. Drive every worker through agent-tmux <cli> subcommands (send-wait, status, result, capture, stop); read-only inventory is tmux-agent-sessions list, not raw tmux ls. Raw tmux bypasses 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.
  2. A send is not done until submission is verified. Bare send can leave text unsent in the input box. Default to send-wait: it appends a fresh nonce and waits for it, confirming the prompt landed.
  3. Every blocking wait takes a timeout — never hand-roll sleep/polling loops. Multiple workers: one bounded watch --any|--all|--count <n> --timeout <s> --json …. Mixed-engine fleets: trust reason:result_updated or resolve with tmux-agent-sessions.
  4. Reusing a worker for a follow-up task? result init first, then send-wait, then result wait-required — never reuse without result 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-tools skill (absorbed there, no longer a separate subagent); details live in references/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 — a general-purpose subagent on sonnet low whose brief runs that single assign call and reports its exit code (see model-dispatch.md §4, 2026-08-17/18 rulings). Parent foreground assign is banned in ALL forms, --detach included, and is denied at the tool call by the tmux-assign-host-gate hook; parent run_in_background is 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 no TaskOutput, 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 | tail reports tail's status, so the wrapper's exit 2 reads as success. The parent MUST NOT additionally poll status/capture/probe unless assign reports a failed step or the user asks; harvest with bounded result wait-required --wait <s> calls. A pending result 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 from result --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. Heed assign's result-path delivery UNCONFIRMED warning — a worker that never learned its path can never write result.json, so that pending is 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-templates skill: 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 with doctor --json and start --dry-run; see references/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:

  1. 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.
  2. Run the resolved agent-tmux <cli> setup and stop if preflight fails.
  3. 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.
  4. 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.json for 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 watch call.

Command choice

NeedUse
Run Claude Code / Codex / agy as a workeragent-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-shotsinteractive start (headed) — pane = debug surface; DEFAULT
Trivially verifiable fire-and-collect, user opted instart --headless — completion = process exit; failures leave only exit code + stdout file
Local working directorystart
Repo on another host, tmux stays localstart-ssh
Pin a model for one runstart --model <m> <name> <dir> '<prompt>'
Continue an existing CLI session UUIDresume (opt-in, off by default)
Don't know which wrapper owns a sessiontmux-agent-sessions resolve --name <n> --json first
Two-party exchange / one-to-many worktmux-agent-dialogue / tmux-agent-fanout
Read-only inventory or evidence pollingtmux-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-permissions for Claude, --yolo for Codex). Never use for destructive, privacy-sensitive, externally visible, payment, or irreversible work without explicit user authorization.
  • status --json reports confirmation_detected:true plus blocked_reason when 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.json schemas, 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.

Comments

Markdown supported