tmux

star 0

Remote control tmux sessions for interactive CLIs (python, gdb, etc.) by sending keystrokes and scraping pane output. provenance: syncrescendence

syncrescendence By syncrescendence schedule Updated 3/3/2026

name: tmux description: "Remote control tmux sessions for interactive CLIs (python, gdb, etc.) by sending keystrokes and scraping pane output. provenance: syncrescendence" license: Vibecoded

tmux Skill

Use tmux as a programmable terminal multiplexer for interactive work. Works on Linux and macOS with stock tmux; avoid custom config by using a private socket.

Quickstart (isolated socket)

SOCKET_DIR=${TMPDIR:-/tmp}/claude-tmux-sockets  # well-known dir for all agent sockets
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/claude.sock"                # keep agent sessions separate from your personal tmux
SESSION=claude-python                           # slug-like names; avoid spaces
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'python3 -q' Enter
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200  # watch output
tmux -S "$SOCKET" kill-session -t "$SESSION"                   # clean up

After starting a session ALWAYS tell the user how to monitor the session by giving them a command to copy paste:

To monitor this session yourself:
  tmux -S "$SOCKET" attach -t claude-lldb

Or to capture the output once:
  tmux -S "$SOCKET" capture-pane -p -J -t claude-lldb:0.0 -S -200

This must ALWAYS be printed right after a session was started and once again at the end of the tool loop. But the earlier you send it, the happier the user will be.

Socket convention

  • Agents MUST place tmux sockets under CLAUDE_TMUX_SOCKET_DIR (defaults to ${TMPDIR:-/tmp}/claude-tmux-sockets) and use tmux -S "$SOCKET" so we can enumerate/clean them. Create the dir first: mkdir -p "$CLAUDE_TMUX_SOCKET_DIR".
  • Default socket path to use unless you must isolate further: SOCKET="$CLAUDE_TMUX_SOCKET_DIR/claude.sock".

Targeting panes and naming

  • Target format: {session}:{window}.{pane}, defaults to :0.0 if omitted. Keep names short (e.g., claude-py, claude-gdb).
  • Use -S "$SOCKET" consistently to stay on the private socket path. If you need user config, drop -f /dev/null; otherwise -f /dev/null gives a clean config.
  • Inspect: tmux -S "$SOCKET" list-sessions, tmux -S "$SOCKET" list-panes -a.

Finding sessions

  • List sessions on your active socket with metadata: ./scripts/find-sessions.sh -S "$SOCKET"; add -q partial-name to filter.
  • Scan all sockets under the shared directory: ./scripts/find-sessions.sh --all (uses CLAUDE_TMUX_SOCKET_DIR or ${TMPDIR:-/tmp}/claude-tmux-sockets).

Sending input safely

  • Prefer literal sends to avoid shell splitting: tmux -L "$SOCKET" send-keys -t target -l -- "$cmd"
  • When composing inline commands, use single quotes or ANSI C quoting to avoid expansion: tmux ... send-keys -t target -- $'python3 -m http.server 8000'.
  • To send control keys: tmux ... send-keys -t target C-c, C-d, C-z, Escape, etc.

Watching output

  • Capture recent history (joined lines to avoid wrapping artifacts): tmux -L "$SOCKET" capture-pane -p -J -t target -S -200.
  • For continuous monitoring, poll with the helper script (below) instead of tmux wait-for (which does not watch pane output).
  • You can also temporarily attach to observe: tmux -L "$SOCKET" attach -t "$SESSION"; detach with Ctrl+b d.
  • When giving instructions to a user, explicitly print a copy/paste monitor command alongside the action don't assume they remembered the command.

Spawning Processes

Some special rules for processes:

  • when asked to debug, use lldb by default
  • when starting a python interactive shell, always set the PYTHON_BASIC_REPL=1 environment variable. This is very important as the non-basic console interferes with your send-keys.

Synchronizing / waiting for prompts

  • Use timed polling to avoid races with interactive tools. Example: wait for a Python prompt before sending code:
    ./scripts/wait-for-text.sh -t "$SESSION":0.0 -p '^>>>' -T 15 -l 4000
    
  • For long-running commands, poll for completion text ("Type quit to exit", "Program exited", etc.) before proceeding.

Interactive tool recipes

  • Python REPL: tmux ... send-keys -- 'python3 -q' Enter; wait for ^>>>; send code with -l; interrupt with C-c. Always with PYTHON_BASIC_REPL.
  • gdb: tmux ... send-keys -- 'gdb --quiet ./a.out' Enter; disable paging tmux ... send-keys -- 'set pagination off' Enter; break with C-c; issue bt, info locals, etc.; exit via quit then confirm y.
  • Other TTY apps (ipdb, psql, mysql, node, bash): same pattern -- start the program, poll for its prompt, then send literal text and Enter.

Cleanup

  • Kill a session when done: 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

./scripts/wait-for-text.sh polls a pane for a regex (or fixed string) with a timeout. Works on Linux/macOS with bash + tmux + grep.

./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 from the pane (integer, default 1000)
  • Exits 0 on first match, 1 on timeout. On failure prints the last captured text to stderr to aid debugging.

Syncrescendence Integration

Used for Cockpit tmux pane management across the Syncrescendence constellation's multi-machine infrastructure:

  • Socket Directory -- Within Syncrescendence, the tmux socket directory is /tmp/syncrescendence-tmux/ (overriding the default claude-tmux-sockets). Set CLAUDE_TMUX_SOCKET_DIR=/tmp/syncrescendence-tmux/ before invoking any tmux commands within the constellation.
  • Cockpit Pane Management -- The Cockpit script (orchestration/scripts/cockpit.sh) manages tmux panes on the Mac mini (Psyche's home, 5120x1440 ultrawide). This skill provides the low-level tmux primitives that the cockpit script orchestrates at a higher level.
  • Agent Session Naming -- Within Syncrescendence, tmux sessions follow the naming convention sync-{agent} (e.g., sync-ajna, sync-psyche, sync-commander). This ensures agent sessions are identifiable and don't collide with personal tmux usage.
  • Cross-Machine Sessions -- MacBook Air (Ajna's home) and Mac mini (Psyche's home) each have their own tmux socket directories. Use SSH tunneling for cross-machine tmux session access when needed.
  • Pane Layout -- Cockpit Pane 1 = Psyche (CTO), NOT Ajna. This is a critical operational detail. When targeting cockpit panes, always verify which agent maps to which pane index via orchestration/scripts/cockpit.sh configuration.
  • Cleanup Protocol -- On constellation shutdown, all sync-* sessions under /tmp/syncrescendence-tmux/ should be killed via tmux -S /tmp/syncrescendence-tmux/claude.sock kill-server.
Install via CLI
npx skills add https://github.com/syncrescendence/syncrescendence --skill tmux
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
syncrescendence
syncrescendence Explore all skills →