
Tmux
Let your agent inspect and drive existing tmux panes—capture output, send keys, and monitor prompts—when interactive CLIs cannot run as one-shot shell commands.
Overview
tmux is a journey-wide agent skill that controls existing tmux sessions and panes—capture output and send keys—whenever a solo builder needs to steer interactive CLIs before committing to one-shot commands.
Install
npx skills add https://github.com/steipete/clawdis --skill tmuxWhat is this skill?
- List sessions, windows, and panes with standard tmux ls and list-* commands
- Capture pane scrollback including full history via capture-pane -S -
- Send literal text and Enter separately with send-keys -l -- to avoid newline paste bugs
- Send control keys: C-c, C-d, and Escape for REPL and installer prompts
- Documented target format session:window.pane (e.g. shared:0.0) and tail-based prompt checks
- Documented send-keys control examples: C-c, C-d, Escape
Adoption & trust: 4.1k installs on skills.sh; 378k GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+200% hot-view momentum).
What problem does it solve?
Your agent cannot see or answer prompts inside a long-running interactive terminal session running outside a single shell invocation.
Who is it for?
Indie devs pairing agents with tmux-based worker layouts on darwin/linux for coding agents, REPLs, and multi-pane dev setups.
Skip if: Windows-native workflows without tmux, or jobs that should stay purely non-interactive background processes.
When should I use this skill?
User needs to list, capture, or send input to existing interactive tmux sessions rather than one-shot shell commands.
What do I get? / Deliverables
The agent can target panes by name, read scrollback, submit input safely, and verify prompts before continuing automation.
- Pane capture text for agent context
- Successful key/text injection into target pane
- Session lifecycle commands when spawning workers
Recommended Skills
Journey fit
Useful at every journey phase - explore requirements and options before committing to a direction.
Where it fits
Paste a long API token into a pane running an OAuth CLI without breaking on embedded newlines.
Watch an interactive release script pane and send C-c if a prompt stalls mid-deploy.
Capture full scrollback from a worker pane after an overnight job to decide next remediation steps.
Read the last 20 lines of a support REPL session before suggesting the next command to a stuck user flow.
How it compares
Terminal session control skill—not a process manager replacement and not the same as generic background shell execution.
Common Questions / FAQ
Who is tmux for?
Solo builders and agent power users on Mac or Linux who already run tmux and want Claude Code-style agents to read and drive those panes.
When should I use tmux?
During Build when driving dev servers or REPLs, during Ship when watching interactive deploy scripts, and during Operate when diagnosing hung panes—anytime existing interactive sessions need agent I/O.
Is tmux safe to install?
It instructs local tmux control only; review the Security Audits panel on this page and restrict which sessions your agent may target in shared machines.
SKILL.md
READMESKILL.md - Tmux
# tmux Use for existing interactive tmux sessions. For one-shot commands, use normal shell. For new non-interactive background jobs, use background execution. ## Basics ```bash tmux ls tmux list-windows -t shared tmux list-panes -t shared:0 tmux capture-pane -t shared:0.0 -p tmux capture-pane -t shared:0.0 -p -S - ``` Target format: `session:window.pane`, e.g. `shared:0.0`. ## Send input Literal text, then Enter: ```bash tmux send-keys -t shared:0.0 -l -- "Please continue" tmux send-keys -t shared:0.0 Enter ``` Special keys: ```bash tmux send-keys -t shared:0.0 C-c tmux send-keys -t shared:0.0 C-d tmux send-keys -t shared:0.0 Escape ``` Use `-l --` for arbitrary text. Split text and Enter to avoid paste/newline surprises. ## Sessions ```bash tmux new-session -d -s worker tmux rename-session -t old new tmux kill-session -t worker ``` ## Prompt checks ```bash tmux capture-pane -t worker-3 -p | tail -20 tmux capture-pane -t worker-3 -p | rg "proceed|permission|Yes|No|❯" ``` Approve/select only when the prompt is understood: ```bash tmux send-keys -t worker-3 -l -- "y" tmux send-keys -t worker-3 Enter ``` ## Helpers - `scripts/find-sessions.sh`: discover sessions. - `scripts/wait-for-text.sh`: wait until pane output contains text. ## Notes - `capture-pane -p` prints to stdout for scripts. - `-S -` captures full scrollback. - tmux sessions persist across SSH disconnects. #!/usr/bin/env bash set -euo pipefail usage() { cat <<'USAGE' Usage: find-sessions.sh [-L socket-name|-S socket-path|-A] [-q pattern] List tmux sessions on a socket (default tmux socket if none provided). Options: -L, --socket tmux socket name (passed to tmux -L) -S, --socket-path tmux socket path (passed to tmux -S) -A, --all scan all sockets under OPENCLAW_TMUX_SOCKET_DIR -q, --query case-insensitive substring to filter session names -h, --help show this help USAGE } socket_name="" socket_path="" query="" scan_all=false socket_dir="${OPENCLAW_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/openclaw-tmux-sockets}" while [[ $# -gt 0 ]]; do case "$1" in -L|--socket) socket_name="${2-}"; shift 2 ;; -S|--socket-path) socket_path="${2-}"; shift 2 ;; -A|--all) scan_all=true; shift ;; -q|--query) query="${2-}"; shift 2 ;; -h|--help) usage; exit 0 ;; *) echo "Unknown option: $1" >&2; usage; exit 1 ;; esac done if [[ "$scan_all" == true && ( -n "$socket_name" || -n "$socket_path" ) ]]; then echo "Cannot combine --all with -L or -S" >&2 exit 1 fi if [[ -n "$socket_name" && -n "$socket_path" ]]; then echo "Use either -L or -S, not both" >&2 exit 1 fi if ! command -v tmux >/dev/null 2>&1; then echo "tmux not found in PATH" >&2 exit 1 fi list_sessions() { local label="$1"; shift local tmux_cmd=(tmux "$@") if ! sessions="$("${tmux_cmd[@]}" list-sessions -F '#{session_name}\t#{session_attached}\t#{session_created_string}' 2>/dev/null)"; then echo "No tmux server found on $label" >&2 return 1 fi if [[ -n "$query" ]]; then sessions="$(printf '%s\n' "$sessions" | grep -i -- "$query" || true)" fi if [[ -z "$sessions" ]]; then echo "No sessions found on $label" return 0 fi echo "Sessions on $label:" printf '%s\n' "$sessions" | while IFS=$'\t' read -r name attached created; do attached_label=$([[ "$attached" == "1" ]] && echo "attached" || echo "detached") printf ' - %s (%s, start