tmux · diff

git:20260312.164b23b to git:20261009.8eb2fa0

8 added, 34 removed. Audit A to A.

---
name: tmux
description: Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
metadata: {"bubbles":{"emoji":"🧵","os":["darwin","linux"],"requires":{"bins":["tmux"]}}}
---
# tmux Skill
Use tmux only when you need an interactive TTY. Prefer exec background mode for long-running, non-interactive tasks.
## Quickstart (isolated socket, exec tool)
```bash
SOCKET_DIR="${BUBBLES_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/bubbles-tmux-sockets}"
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/bubbles.sock"
SESSION=bubbles-python
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'PYTHON_BASIC_REPL=1 python3 -q' Enter
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
```
After starting a session, always print monitor commands:
```
To monitor:
tmux -S "$SOCKET" attach -t "$SESSION"
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
```
## Socket convention
- Use `BUBBLES_TMUX_SOCKET_DIR` environment variable.
- Default socket path: `"$BUBBLES_TMUX_SOCKET_DIR/bubbles.sock"`.
## Targeting panes and naming
- Target format: `session:window.pane` (defaults to `:0.0`).
- Keep names short; avoid spaces.
- Inspect: `tmux -S "$SOCKET" list-sessions`, `tmux -S "$SOCKET" list-panes -a`.
## Finding sessions
- List sessions on your socket: `{baseDir}/scripts/find-sessions.sh -S "$SOCKET"`.
- Scan all sockets: `{baseDir}/scripts/find-sessions.sh --all` (uses `BUBBLES_TMUX_SOCKET_DIR`).
## Sending input safely
- Prefer literal sends: `tmux -S "$SOCKET" send-keys -t target -l -- "$cmd"`.
- Control keys: `tmux -S "$SOCKET" send-keys -t target C-c`.
## Watching output
- Capture recent history: `tmux -S "$SOCKET" capture-pane -p -J -t target -S -200`.
- Wait for prompts: `{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern'`.
- Attaching is OK; detach with `Ctrl+b d`.
## Spawning processes
- For python REPLs, set `PYTHON_BASIC_REPL=1` (non-basic REPL breaks send-keys flows).
## Windows / WSL
- tmux is supported on macOS/Linux. On Windows, use WSL and install tmux inside WSL.
- - This skill is gated to `darwin`/`linux` and requires `tmux` on PATH.
-
- ## Orchestrating Coding Agents (Codex, Claude Code)
-
- tmux excels at running multiple coding agents in parallel:
-
- ```bash
- SOCKET="${TMPDIR:-/tmp}/codex-army.sock"
-
- # Create multiple sessions
- for i in 1 2 3 4 5; do
- tmux -S "$SOCKET" new-session -d -s "agent-$i"
- done
-
- # Launch agents in different workdirs
- tmux -S "$SOCKET" send-keys -t agent-1 "cd /tmp/project1 && codex --yolo 'Fix bug X'" Enter
- tmux -S "$SOCKET" send-keys -t agent-2 "cd /tmp/project2 && codex --yolo 'Fix bug Y'" Enter
-
- # Poll for completion (check if prompt returned)
- for sess in agent-1 agent-2; do
- if tmux -S "$SOCKET" capture-pane -p -t "$sess" -S -3 | grep -q "❯"; then
- echo "$sess: DONE"
- else
- echo "$sess: Running..."
- fi
- done
+ - Check the actual platform and `tmux` executable before use; metadata is not an enforced dependency installer or OS gate.
- # Get full output from completed session
- tmux -S "$SOCKET" capture-pane -p -t agent-1 -S -500
- ```
+ ## Agent lifecycle
- **Tips:**
- - Use separate git worktrees for parallel fixes (no branch conflicts)
- - `pnpm install` first before running codex in fresh clones
- - Check for shell prompt (`❯` or `$`) to detect completion
- - Codex needs `--yolo` or `--full-auto` for non-interactive fixes
+ Bubblebot owns its background task lifecycle. Do not launch extra Codex/Claude
+ agents in detached tmux sessions: they would escape task status, cancellation,
+ and result routing. Use the Bubblebot task capability when available; a task
+ that needs additional managed work reports that request to the main Agent.
+ Use native process execution for ordinary long-running commands, reserving tmux
+ for a genuinely interactive TTY that this task can track and clean up.
## Cleanup
- Kill a session: `tmux -S "$SOCKET" kill-session -t "$SESSION"`.
- Kill all sessions on a socket: `tmux -S "$SOCKET" list-sessions -F '#{session_name}' | xargs -r -n1 tmux -S "$SOCKET" kill-session -t`.
- Remove everything on the private socket: `tmux -S "$SOCKET" kill-server`.
## Helper: wait-for-text.sh
`{baseDir}/scripts/wait-for-text.sh` polls a pane for a regex (or fixed string) with a timeout.
```bash
{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]
```
- `-t`/`--target` pane target (required)
- `-p`/`--pattern` regex to match (required); add `-F` for fixed string
- `-T` timeout seconds (integer, default 15)
- `-i` poll interval seconds (default 0.5)
- `-l` history lines to search (integer, default 1000)