| name | tmux |
| description | Drive tmux sessions, windows, panes, and commands directly via the tmux CLI. |
| allowed-tools | Bash |
Use tmux CLI commands directly.
Sessions
tmux new-session -d -s <name> [-c <start-dir>]
tmux kill-session -t <name>
tmux list-sessions -F '#{session_name} #{session_windows} #{session_created}'
tmux rename-session -t <old> <new>
echo "$TMUX_PANE"
tmux display-message -p '#S'
Windows
tmux list-windows -t <session> -F '#{window_index} #{window_name} #{window_active}'
tmux new-window -t <session> -n <name> [-c <start-dir>]
tmux select-window -t <session>:<index-or-name>
tmux rename-window -t <session>:<index> <new-name>
tmux kill-window -t <session>:<index>
Panes
tmux list-panes -s -t <session> -F '#{pane_id} #{window_index} #{pane_index} #{pane_active} #{pane_current_command}'
tmux list-panes -t <session>:<window> -F '#{pane_id} #{pane_index} #{pane_active}'
tmux split-window -t <pane-id> [-h|-v] [-c <start-dir>]
tmux select-pane -t <pane-id>
tmux kill-pane -t <pane-id>
tmux resize-pane -t <pane-id> [-U|-D|-L|-R] <N>
tmux resize-pane -t <pane-id> -Z
Pane IDs look like %0, %1, etc. Target syntax: session:window.pane or bare pane id %N.
Sending keys
tmux send-keys -t <pane-id> '<text>'
tmux send-keys -t <pane-id> '<command>' Enter
tmux send-keys -t <pane-id> '' Enter
tmux send-keys -t <pane-id> '' Escape
tmux send-keys -t <pane-id> -l '<text>'
tmux send-keys -t <pane-id> '' Tab
tmux send-keys -t <pane-id> '' Up
tmux send-keys -t <pane-id> '' C-c
Capturing pane output
tmux capture-pane -t <pane-id> -p [-S -<N>]
tmux capture-pane -t <pane-id> -p -S -500
tmux capture-pane -t <pane-id> -p -e -J
Use -e -J whenever you need to verify visual state (selections, focus, colors). Plain -p strips all ANSI codes, making it impossible to distinguish selected from unselected items.
Execute a command and reliably capture its exit code
Wrap commands in unique markers to extract output and exit code from captured pane content:
CMD_ID="tmux_$(date +%s%N | sha256sum | head -c 8)"
tmux send-keys -t <pane-id> \
"echo TMUX_START_${CMD_ID}; <your-command>; echo TMUX_DONE_${CMD_ID}_\$?" \
Enter
sleep <estimated-duration>
OUTPUT=$(tmux capture-pane -t <pane-id> -p -S -2000)
RESULT=$(echo "$OUTPUT" \
| awk "/TMUX_START_${CMD_ID}/{found=1; next} /TMUX_DONE_${CMD_ID}_/{print; found=0; exit} found")
EXIT_CODE=$(echo "$OUTPUT" | grep -oP "TMUX_DONE_${CMD_ID}_\K[0-9]+")
Polling until done
for i in $(seq 1 30); do
OUTPUT=$(tmux capture-pane -t <pane-id> -p -S -2000)
if echo "$OUTPUT" | grep -q "TMUX_DONE_${CMD_ID}_"; then
EXIT_CODE=$(echo "$OUTPUT" | grep -oP "TMUX_DONE_${CMD_ID}_\K[0-9]+")
RESULT=$(echo "$OUTPUT" \
| awk "/TMUX_START_${CMD_ID}/{found=1; next} /TMUX_DONE_${CMD_ID}_/{found=0; exit} found")
break
fi
sleep 1
done
Simulating mouse clicks
tmux passes SGR mouse escape sequences directly to pane applications:
ESC[<Pb;Px;PyM = button press (Pb=button, Px=col, Py=row, 1-indexed)
ESC[<Pb;Px;Pym = button release
Button codes: 0=left, 1=middle, 2=right, 64=wheel-up, 65=wheel-down
tmux set-option -t <session> mouse on
tmux send-keys -t <pane-id> $'\x1b[<0;10;5M'$'\x1b[<0;10;5m'
tmux send-keys -t <pane-id> $'\x1b[<2;20;3M'$'\x1b[<2;20;3m'
tmux send-keys -t <pane-id> $'\x1b[<65;1;1M'
tmux send-keys -t <pane-id> $'\x1b[<64;1;1M'
Helper function
tmux_click() {
local pane=$1 col=$2 row=$3 btn=${4:-0}
tmux set-option -t "$pane" mouse on 2>/dev/null || true
tmux send-keys -t "$pane" $'\x1b'"[<${btn};${col};${row}M"$'\x1b'"[<${btn};${col};${row}m"
}
Mouse events only reach applications that have enabled mouse reporting (e.g. vim, less, ncurses TUIs, Zellij plugin panes). If the application hasn't enabled mouse mode, use keyboard navigation instead.
Coordinates are terminal-absolute. For split-pane TUIs (e.g. Zellij with a sidebar + main pane), pass the full terminal row/col — the application translates internally. Do not subtract anything for pane borders or pane position. Row 1 = top of terminal, col 1 = left edge. The pane border itself occupies row 1 (and col 1) of the pane's screen area; the first clickable content row is row 2.
Working with isolated sockets
tmux -L agent-socket new-session -d -s main
tmux -L agent-socket send-keys -t main 'echo hello' Enter
tmux -L agent-socket capture-pane -t main -p
tmux -L agent-socket kill-server
Common patterns
Spawn a shell, run a command, capture result:
tmux new-session -d -s work -c /tmp
CMD_ID="job_$(date +%s)"
tmux send-keys -t work "echo START_${CMD_ID}; ls -la; echo DONE_${CMD_ID}_\$?" Enter
sleep 0.5
tmux capture-pane -t work -p -S -100
Check if a session exists:
tmux has-session -t <name> 2>/dev/null && echo "exists" || echo "missing"
Wait for a pane's command to become shell (idle):
while [[ "$(tmux display-message -t <pane-id> -p '#{pane_current_command}')" != "zsh" ]]; do
sleep 0.2
done