{"skill":{"slug":"tmux","displayName":"Tmux","summary":"Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.","description":"---\nname: tmux\ndescription: Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.\nmetadata: {\"clawdbot\":{\"emoji\":\"🧵\",\"os\":[\"darwin\",\"linux\"],\"requires\":{\"bins\":[\"tmux\"]}}}\n---\n\n# tmux Skill (Clawdbot)\n\nUse tmux only when you need an interactive TTY. Prefer bash background mode for long-running, non-interactive tasks.\n\n## Quickstart (isolated socket, bash tool)\n\n```bash\nSOCKET_DIR=\"${CLAWDBOT_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/clawdbot-tmux-sockets}\"\nmkdir -p \"$SOCKET_DIR\"\nSOCKET=\"$SOCKET_DIR/clawdbot.sock\"\nSESSION=clawdbot-python\n\ntmux -S \"$SOCKET\" new -d -s \"$SESSION\" -n shell\ntmux -S \"$SOCKET\" send-keys -t \"$SESSION\":0.0 -- 'PYTHON_BASIC_REPL=1 python3 -q' Enter\ntmux -S \"$SOCKET\" capture-pane -p -J -t \"$SESSION\":0.0 -S -200\n```\n\nAfter starting a session, always print monitor commands:\n\n```\nTo monitor:\n  tmux -S \"$SOCKET\" attach -t \"$SESSION\"\n  tmux -S \"$SOCKET\" capture-pane -p -J -t \"$SESSION\":0.0 -S -200\n```\n\n## Socket convention\n\n- Use `CLAWDBOT_TMUX_SOCKET_DIR` (default `${TMPDIR:-/tmp}/clawdbot-tmux-sockets`).\n- Default socket path: `\"$CLAWDBOT_TMUX_SOCKET_DIR/clawdbot.sock\"`.\n\n## Targeting panes and naming\n\n- Target format: `session:window.pane` (defaults to `:0.0`).\n- Keep names short; avoid spaces.\n- Inspect: `tmux -S \"$SOCKET\" list-sessions`, `tmux -S \"$SOCKET\" list-panes -a`.\n\n## Finding sessions\n\n- List sessions on your socket: `{baseDir}/scripts/find-sessions.sh -S \"$SOCKET\"`.\n- Scan all sockets: `{baseDir}/scripts/find-sessions.sh --all` (uses `CLAWDBOT_TMUX_SOCKET_DIR`).\n\n## Sending input safely\n\n- Prefer literal sends: `tmux -S \"$SOCKET\" send-keys -t target -l -- \"$cmd\"`.\n- Control keys: `tmux -S \"$SOCKET\" send-keys -t target C-c`.\n\n## Watching output\n\n- Capture recent history: `tmux -S \"$SOCKET\" capture-pane -p -J -t target -S -200`.\n- Wait for prompts: `{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern'`.\n- Attaching is OK; detach with `Ctrl+b d`.\n\n## Spawning processes\n\n- For python REPLs, set `PYTHON_BASIC_REPL=1` (non-basic REPL breaks send-keys flows).\n\n## Windows / WSL\n\n- tmux is supported on macOS/Linux. On Windows, use WSL and install tmux inside WSL.\n- This skill is gated to `darwin`/`linux` and requires `tmux` on PATH.\n\n## Orchestrating Coding Agents (Codex, Claude Code)\n\ntmux excels at running multiple coding agents in parallel:\n\n```bash\nSOCKET=\"${TMPDIR:-/tmp}/codex-army.sock\"\n\n# Create multiple sessions\nfor i in 1 2 3 4 5; do\n  tmux -S \"$SOCKET\" new-session -d -s \"agent-$i\"\ndone\n\n# Launch agents in different workdirs\ntmux -S \"$SOCKET\" send-keys -t agent-1 \"cd /tmp/project1 && codex --yolo 'Fix bug X'\" Enter\ntmux -S \"$SOCKET\" send-keys -t agent-2 \"cd /tmp/project2 && codex --yolo 'Fix bug Y'\" Enter\n\n# Poll for completion (check if prompt returned)\nfor sess in agent-1 agent-2; do\n  if tmux -S \"$SOCKET\" capture-pane -p -t \"$sess\" -S -3 | grep -q \"❯\"; then\n    echo \"$sess: DONE\"\n  else\n    echo \"$sess: Running...\"\n  fi\ndone\n\n# Get full output from completed session\ntmux -S \"$SOCKET\" capture-pane -p -t agent-1 -S -500\n```\n\n**Tips:**\n- Use separate git worktrees for parallel fixes (no branch conflicts)\n- `pnpm install` first before running codex in fresh clones\n- Check for shell prompt (`❯` or `$`) to detect completion\n- Codex needs `--yolo` or `--full-auto` for non-interactive fixes\n\n## Cleanup\n\n- Kill a session: `tmux -S \"$SOCKET\" kill-session -t \"$SESSION\"`.\n- Kill all sessions on a socket: `tmux -S \"$SOCKET\" list-sessions -F '#{session_name}' | xargs -r -n1 tmux -S \"$SOCKET\" kill-session -t`.\n- Remove everything on the private socket: `tmux -S \"$SOCKET\" kill-server`.\n\n## Helper: wait-for-text.sh\n\n`{baseDir}/scripts/wait-for-text.sh` polls a pane for a regex (or fixed string) with a timeout.\n\n```bash\n{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]\n```\n\n- `-t`/`--target` pane target (required)\n- `-p`/`--pattern` regex to match (required); add `-F` for fixed string\n- `-T` timeout seconds (integer, default 15)\n- `-i` poll interval seconds (default 0.5)\n- `-l` history lines to search (integer, default 1000)\n","tags":{"latest":"1.0.0"},"stats":{"comments":3,"downloads":29350,"installsAllTime":1409,"installsCurrent":1405,"stars":43,"versions":1},"createdAt":1767545387948,"updatedAt":1778485729679},"latestVersion":{"version":"1.0.0","createdAt":1767545387948,"changelog":"","license":null},"metadata":{"setup":[],"os":["darwin","linux"],"systems":null},"owner":{"handle":"steipete","userId":"s179zksw999xz8ms4cy7pb2fr183m5jq","displayName":"Peter Steinberger","image":"https://avatars.githubusercontent.com/u/58493?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1779912380880}}