install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/elizaOS/eliza/tmux" ~/.claude/skills/comeonoliver-skillshub-tmux-e7db35 && rm -rf "$T"
manifest:
skills/elizaOS/eliza/tmux/SKILL.mdsource content
tmux Skill (Otto)
Use tmux only when you need an interactive TTY. Prefer exec background mode for long-running, non-interactive tasks.
Quickstart (isolated socket, exec tool)
SOCKET_DIR="${OTTO_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/otto-tmux-sockets}" mkdir -p "$SOCKET_DIR" SOCKET="$SOCKET_DIR/otto.sock" SESSION=otto-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
.OTTO_TMUX_SOCKET_DIR - Default socket path:
."$OTTO_TMUX_SOCKET_DIR/otto.sock"
Targeting panes and naming
- Target format:
(defaults tosession:window.pane
).: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:
(uses{baseDir}/scripts/find-sessions.sh --all
).OTTO_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 - For interactive TUI apps like Claude Code/Codex, this guidance covers how to send commands.
Do not append
in the sameEnter
. These apps may treat a fast text+Enter sequence as paste/multi-line input and not submit; this is timing-dependent. Send text andsend-keys
as separate commands with a small delay (tune per environment; increase if needed, or useEnter
if sub-second sleeps aren't supported):sleep 1
tmux -S "$SOCKET" send-keys -t target -l -- "$cmd" && sleep 0.1 && tmux -S "$SOCKET" send-keys -t target Enter
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
(non-basic REPL breaks send-keys flows).PYTHON_BASIC_REPL=1
Windows / WSL
- tmux is supported on macOS/Linux. On Windows, use WSL and install tmux inside WSL.
- This skill is gated to
/darwin
and requireslinux
on PATH.tmux
Orchestrating Coding Agents (Codex, Claude Code)
tmux excels at running multiple coding agents in parallel:
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 # When sending prompts to Claude Code/Codex TUI, split text + Enter with a delay tmux -S "$SOCKET" send-keys -t agent-1 -l -- "Please make a small edit to README.md." && sleep 0.1 && tmux -S "$SOCKET" send-keys -t agent-1 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 # Get full output from completed session tmux -S "$SOCKET" capture-pane -p -t agent-1 -S -500
Tips:
- Use separate git worktrees for parallel fixes (no branch conflicts)
first before running codex in fresh clonespnpm install- Check for shell prompt (
or❯
) to detect completion$ - Codex needs
or--yolo
for non-interactive fixes--full-auto
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.
{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]
/-t
pane target (required)--target
/-p
regex to match (required); add--pattern
for fixed string-F
timeout seconds (integer, default 15)-T
poll interval seconds (default 0.5)-i
history lines to search (integer, default 1000)-l