Claude
Skills
Sign in
Back

skill-system-tmux

Included with Lifetime
$97 forever

Tmux execution support for long-running and persistent commands. Load this skill when you need to: (1) run commands expected to exceed tool timeout (over 60s), (2) start persistent servers or dev processes, (3) run TUI/interactive applications, (4) execute parallel isolated tasks in separate sessions, (5) run remote commands over SSH that must survive disconnection, (6) handle tmux errors like 'capture-pane blocked in interactive_bash'. Trigger phrases: 'run in background', 'start server', 'long-running', 'tmux session', 'keep running', 'persistent process', 'dev server', 'training script', 'git clone large repo', 'docker build', 'capture-pane blocked'.

Cloud & DevOpsscripts

What this skill does


# Skill System Tmux

Route shell commands through tmux when they risk timeout, require persistence, or need interactive terminal access. This skill provides decision heuristics and session management conventions — not tmux tutorials.

## Decision Matrix

Use this matrix to decide: **direct bash** vs **tmux**.

| Condition | Route | Examples |
|---|---|---|
| Estimated time > 60s | tmux | `git clone <large>`, `npm install`, `docker build`, training scripts |
| Command does not self-terminate | tmux | `npm run dev`, `python app.py`, `jupyter notebook` |
| Requires TUI or interactive input | tmux | `vim`, `htop`, `pudb`, `claude` |
| Parallel isolated execution needed | tmux | Multiple agents, concurrent test suites |
| Remote execution over SSH | tmux | Commands that must survive connection drops |
| Atomic, non-interactive, fast (<30s) | direct bash | `ls`, `grep`, `git status`, `cat`, `mkdir` |
| Single-shot with expected output | direct bash | `python script.py` (fast), `git diff`, `npm test` (short) |

**Default: direct bash.** Only route to tmux when a condition above is met.

### Time Estimation Heuristics

Commands likely to exceed timeout:

- **Git operations**: `clone` (large repos), `push` (large payloads), `checkout` (>1GB working tree)
- **Package install**: `npm install`, `pip install` (many deps), `cargo build`
- **Build tools**: `docker build`, `make` (large projects), `webpack` (production builds)
- **Data processing**: Training scripts, preprocessing pipelines, large file transfers
- **CI/test suites**: Full test runs on large projects

## Session Naming Convention

Use project-context naming for human readability:

```
Format: {project}-{purpose}

Agent-created sessions (MANDATORY prefix):
  oc-{purpose}        # e.g., oc-audit, oc-verify, oc-render
  oc-{project}-{task}  # e.g., oc-skills-build, oc-subproject-test

User/infra sessions (no prefix required):
  postgres-dev
  frontend-watch
  ml-training
```

Rules:
- **Agent-created sessions MUST use `oc-` prefix** — enables bulk identification and cleanup
- Lowercase, hyphens for separators (not underscores)
- Include project context for multi-project environments
- Reuse well-known `oc-` session names when they exist (e.g., `oc-exp-runner`)
- If you inherit a legacy agent session without the prefix, rename it to `oc-*` before reuse
- Never create sessions with numeric-only names (e.g., `531`)

## Core Patterns

### Pattern 1: Fire and Forget (Background Task)

For long-running commands where you don't need real-time output:

```bash
# Kill any existing session with same name, then start fresh
tmux kill-session -t {session} 2>/dev/null || true
tmux new-session -d -s {session} bash -c '{command}'
```

Using `interactive_bash` tool:
```
tmux_command: new-session -d -s {session}
tmux_command: send-keys -t {session} "{command}" Enter
```

### Pattern 2: Persistent Server

For dev servers or processes that must keep running:

```
tmux_command: new-session -d -s {session}
tmux_command: send-keys -t {session} "{command}" Enter
```

Check if running later:
```
tmux_command: has-session -t {session}
```

### Pattern 3: Output Capture

Read what a tmux session has produced:

```
tmux_command: capture-pane -p -t {session}
```

For longer history (last 1000 lines):
```
tmux_command: capture-pane -p -t {session} -S -1000
```

### Pattern 4: Readiness Detection

After sending a command, poll to detect completion:

1. Capture the pane output
2. Look for shell prompt at end of output (regex: `/(\\$|>|#)\s*$/m`)
3. If prompt appears, command has finished
4. If no prompt after expected duration, assume still running or hung

### Pattern 5: Clean Shutdown

Always clean up sessions when done:

```
tmux_command: kill-session -t {session}
```

**Kill-before-new pattern** prevents zombie sessions:
```
tmux_command: kill-session -t {session}
# (ignore error if doesn't exist)
tmux_command: new-session -d -s {session}
```

### Pattern 6: Bulk Resource Reclaim

Reclaim all agent-created sessions and detect stale resources. Run this when:
- Machine feels sluggish or memory is high
- Before/after long agent work sessions
- User requests cleanup

**Step 1: Identify agent sessions**
```bash
tmux list-sessions -F '#{session_name} #{session_activity}' | grep '^oc-'
```

**Step 2: Kill all agent sessions**
```bash
tmux list-sessions -F '#{session_name}' | grep '^oc-' | xargs -I{} tmux kill-session -t {}
```

**Step 3: Detect stale non-agent sessions**

A session is likely stale if:
- Last activity > 6 hours ago AND no running foreground process
- Session has only an idle shell prompt (capture-pane shows just `$` or `╰─`)

```bash
# List sessions with last activity timestamp
tmux list-sessions -F '#{session_name} #{session_activity}'
# Compare #{session_activity} (epoch) against current time
# Capture pane of suspects to verify idle state
```

**Step 4: Reclaim orphaned processes**
```bash
# Find opencode processes whose parent tmux pane was killed
ps aux | grep opencode | grep -v grep
# Check if port is held by a zombie
lsof -i :{port} 2>/dev/null
# Force kill if needed (SIGTERM first, SIGKILL if unresponsive after 5s)
kill {pid} && sleep 5 && kill -0 {pid} 2>/dev/null && kill -9 {pid}
```

**Important**: Never kill known non-agent infra sessions without explicit user confirmation. Legacy names from sibling projects should be normalized to `oc-*` before they are treated as agent-managed sessions.

## Integration with Agent Tools

### `interactive_bash` Tool

The primary interface. Pass tmux subcommands directly (without `tmux` prefix):

```
# Create session
tmux_command: new-session -d -s oc-my-session

# Send command
tmux_command: send-keys -t oc-my-session "npm run dev" Enter

# Read output
tmux_command: capture-pane -p -t oc-my-session

# Kill session
tmux_command: kill-session -t oc-my-session
```

### `bash` Tool with Timeout

For commands near the timeout boundary, prefer increasing `timeout` parameter over tmux:

```
bash(command="npm install", timeout=300000)  # 5 min timeout
```

Use tmux only when:
- Timeout cannot be reliably estimated
- Process must persist beyond the current tool call
- Interactive/TUI access is needed

## Known Errors & Workarounds

### `capture-pane` blocked in `interactive_bash`

**Error**: `'capture-pane' is blocked in interactive_bash`

This is the most common tmux error. The `interactive_bash` tool blocks certain tmux subcommands (including `capture-pane`, `pipe-pane`, `save-buffer`). **Always use the `Bash` tool instead** for these operations.

```bash
# WRONG — will be blocked:
# interactive_bash: tmux_command: capture-pane -p -t oc-dev-server

# CORRECT — use Bash tool:
tmux capture-pane -p -t oc-dev-server

# Capture with history (last 1000 lines):
tmux capture-pane -p -t oc-dev-server -S -1000

# Capture and grep for specific output:
tmux capture-pane -p -t oc-dev-server | grep -i "error\|ready\|listening"
```

**Rule**: For any tmux read-only operation (`capture-pane`, `list-sessions`, `display-message`, `show-options`), prefer the `Bash` tool. Reserve `interactive_bash` for mutations (`send-keys`, `new-session`, `kill-session`).

### `session not found` after kill/recreate

**Error**: `can't find session: oc-xxx`

Common when kill-before-new pattern races. Add a small guard:

```bash
tmux kill-session -t oc-build 2>/dev/null || true
tmux new-session -d -s oc-build bash -c 'make all'
```

### `duplicate session` on new-session

**Error**: `duplicate session: oc-xxx`

The session already exists. Either reuse it or kill-before-new:

```bash
# Reuse (send new command to existing session):
tmux send-keys -t oc-build "make clean && make all" Enter

# Or kill and recreate:
tmux kill-session -t oc-build 2>/dev/null || true
tmux new-session -d -s oc-build bash -c 'make all'
```

### `no server running` / tmux not started

**Error**: `no server running on /tmp/tmux-*/default`

No tmux server is running. Any `new-session` command will start one automatically:

```bash
tmux new-sessio

Related in Cloud & DevOps