running-interactive-commands-with-tmux
Controls interactive CLI tools (vim, git rebase -i, REPLs) through tmux detached sessions and send-keys. Use when running tools requiring terminal interaction, programmatic editor control, or orchestrating Claude Code sessions. Triggers include "interactive command", "vim", "REPL", "tmux", or "git rebase -i".
Best use case
running-interactive-commands-with-tmux is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Controls interactive CLI tools (vim, git rebase -i, REPLs) through tmux detached sessions and send-keys. Use when running tools requiring terminal interaction, programmatic editor control, or orchestrating Claude Code sessions. Triggers include "interactive command", "vim", "REPL", "tmux", or "git rebase -i".
Teams using running-interactive-commands-with-tmux should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/running-interactive-commands-with-tmux/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How running-interactive-commands-with-tmux Compares
| Feature / Agent | running-interactive-commands-with-tmux | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Controls interactive CLI tools (vim, git rebase -i, REPLs) through tmux detached sessions and send-keys. Use when running tools requiring terminal interaction, programmatic editor control, or orchestrating Claude Code sessions. Triggers include "interactive command", "vim", "REPL", "tmux", or "git rebase -i".
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Using tmux for Interactive Commands
## Overview
Interactive CLI tools (vim, interactive git rebase, REPLs, etc.) cannot be controlled through standard bash because they require a real terminal. tmux provides detached sessions that can be controlled programmatically via `send-keys` and `capture-pane`.
## When to Use
**Use tmux when:**
- Running vim, nano, or other text editors programmatically
- Controlling interactive REPLs (Python, Node, etc.)
- Handling interactive git commands (`git rebase -i`, `git add -p`)
- Working with full-screen terminal apps (htop, etc.)
- Commands that require terminal control codes or readline
**Don't use for:**
- Simple non-interactive commands (use regular Bash tool)
- Commands that accept input via stdin redirection
- One-shot commands that don't need interaction
## Quick Reference
| Task | Command |
|------|---------|
| Start session | `tmux new-session -d -s <name> <command>` |
| Send input | `tmux send-keys -t <name> 'text' Enter` |
| Capture output | `tmux capture-pane -t <name> -p` |
| Stop session | `tmux kill-session -t <name>` |
| List sessions | `tmux list-sessions` |
## Core Pattern
### Before (Won't Work)
```bash
# This hangs because vim expects interactive terminal
bash -c "vim file.txt"
```
### After (Works)
```bash
# Create detached tmux session
tmux new-session -d -s edit_session vim file.txt
# Send commands (Enter, Escape are tmux key names)
tmux send-keys -t edit_session 'i' 'Hello World' Escape ':wq' Enter
# Capture what's on screen
tmux capture-pane -t edit_session -p
# Clean up
tmux kill-session -t edit_session
```
## Implementation
### Basic Workflow
1. **Create detached session** with the interactive command
2. **Wait briefly** for initialization (100-500ms depending on command)
3. **Send input** using `send-keys` (can send special keys like Enter, Escape)
4. **Capture output** using `capture-pane -p` to see current screen state
5. **Repeat** steps 3-4 as needed
6. **Terminate** session when done
### Special Keys
Common tmux key names:
- `Enter` - Return/newline
- `Escape` - ESC key
- `C-c` - Ctrl+C
- `C-x` - Ctrl+X
- `Up`, `Down`, `Left`, `Right` - Arrow keys
- `Space` - Space bar
- `BSpace` - Backspace
### Working Directory
Specify working directory when creating session:
```bash
tmux new-session -d -s git_session -c /path/to/repo git rebase -i HEAD~3
```
### Helper Wrapper
For easier use, see `/home/jesse/git/interactive-command/tmux-wrapper.sh`:
```bash
# Start session
/path/to/tmux-wrapper.sh start <session-name> <command> [args...]
# Send input
/path/to/tmux-wrapper.sh send <session-name> 'text' Enter
# Capture current state
/path/to/tmux-wrapper.sh capture <session-name>
# Stop
/path/to/tmux-wrapper.sh stop <session-name>
```
## Common Patterns
### Python REPL
```bash
tmux new-session -d -s python python3 -i
tmux send-keys -t python 'import math' Enter
tmux send-keys -t python 'print(math.pi)' Enter
tmux capture-pane -t python -p # See output
tmux kill-session -t python
```
### Vim Editing
```bash
tmux new-session -d -s vim vim /tmp/file.txt
sleep 0.3 # Wait for vim to start
tmux send-keys -t vim 'i' 'New content' Escape ':wq' Enter
# File is now saved
```
### Interactive Git Rebase
```bash
tmux new-session -d -s rebase -c /repo/path git rebase -i HEAD~3
sleep 0.5
tmux capture-pane -t rebase -p # See rebase editor
# Send commands to modify rebase instructions
tmux send-keys -t rebase 'Down' 'Home' 'squash' Escape
tmux send-keys -t rebase ':wq' Enter
```
## Common Mistakes
### Not Waiting After Session Start
**Problem:** Capturing immediately after `new-session` shows blank screen
**Fix:** Add brief sleep (100-500ms) before first capture
```bash
tmux new-session -d -s sess command
sleep 0.3 # Let command initialize
tmux capture-pane -t sess -p
```
### Forgetting Enter Key
**Problem:** Commands typed but not executed
**Fix:** Explicitly send Enter
```bash
tmux send-keys -t sess 'print("hello")' Enter # Note: Enter is separate argument
```
### Using Wrong Key Names
**Problem:** `tmux send-keys -t sess '\n'` doesn't work
**Fix:** Use tmux key names: `Enter`, not `\n`
```bash
tmux send-keys -t sess 'text' Enter # ✓
tmux send-keys -t sess 'text\n' # ✗
```
### Not Cleaning Up Sessions
**Problem:** Orphaned tmux sessions accumulate
**Fix:** Always kill sessions when done
```bash
tmux kill-session -t session_name
# Or check for existing: tmux has-session -t name 2>/dev/null
```
## Progressive Details
For advanced patterns including Claude Code orchestration and remote monitoring protocols, see sections below.
<!-- progressive: advanced-tmux-patterns -->
## Controlling Claude Code Sessions in tmux
### The Two-Step Pattern (CRITICAL)
Claude Code running in tmux requires a **two-step command pattern**:
1. **Queue the command**: Send command with C-m (appears in prompt but doesn't execute)
2. **Execute the command**: Send C-m again (executes the queued command)
**Example - Sending a Command to Claude Code**:
```bash
# Step 1: Queue the command in the Claude Code prompt
tmux send-keys -t csv-import 'date -u +"%Y-%m-%d %H:%M:%S UTC"' C-m
# Step 2: Send Return to execute the queued command
tmux send-keys -t csv-import C-m
# Step 3: Monitor output after brief wait
sleep 3 && tmux capture-pane -t csv-import -p | tail -15
```
### Launching Claude Code in tmux
Create a detached tmux session running Claude Code:
```bash
# Create tmux session with Claude Code
tmux new-session -d -s csv-import -c /path/to/project
# Send the Claude Code launch command (two steps)
tmux send-keys -t csv-import 'claude -p "your prompt here"' C-m
tmux send-keys -t csv-import C-m
# Monitor session startup
sleep 5 && tmux capture-pane -t csv-import -p | tail -30
```
### Common Operations
**Execute a prompt**:
```bash
# Queue the command
tmux send-keys -t csv-import 'claude -p "analyze the codebase"' C-m
# Execute it
tmux send-keys -t csv-import C-m
# Monitor progress
sleep 2 && tmux capture-pane -t csv-import -p | tail -40
```
**Send multi-line prompts** (use heredoc in file, reference in command):
```bash
# Create prompt file first
cat > /tmp/prompt.txt <<'EOF'
Your detailed prompt here
with multiple lines
EOF
# Send command referencing file
tmux send-keys -t csv-import 'claude -p "$(cat /tmp/prompt.txt)"' C-m
tmux send-keys -t csv-import C-m
```
**Monitor ongoing execution**:
```bash
# Continuous monitoring (every 30 seconds)
while true; do
echo "=== Status at $(date -u +"%H:%M:%S") ==="
tmux capture-pane -t csv-import -p | tail -25
sleep 30
done
```
**Check if Claude Code is still active**:
```bash
# Capture current state
tmux capture-pane -t csv-import -p | tail -20
# Look for indicators:
# - "Garnishing..." = processing
# - Fresh prompt = ready for next command
# - Error messages = needs attention
```
### Critical Mistakes with Claude Code
**❌ WRONG - Single C-m (command queued but not executed)**:
```bash
tmux send-keys -t csv-import 'date' C-m
# Command appears in prompt but doesn't run!
```
**✅ CORRECT - Two-step pattern**:
```bash
tmux send-keys -t csv-import 'date' C-m # Queue
tmux send-keys -t csv-import C-m # Execute
```
**❌ WRONG - Using Enter instead of C-m**:
```bash
tmux send-keys -t csv-import 'command' Enter Enter
# May not work consistently with Claude Code
```
**✅ CORRECT - Use C-m for Return**:
```bash
tmux send-keys -t csv-import 'command' C-m # Queue
tmux send-keys -t csv-import C-m # Execute
```
### Workflow Example: CSV Processing Pipeline
```bash
# 1. Launch Claude Code session
tmux new-session -d -s csv-import -c /path/to/project
tmux send-keys -t csv-import 'claude' C-m
tmux send-keys -t csv-import C-m
sleep 5
# 2. Send initial processing command
tmux send-keys -t csv-import 'claude -p "Extract CSV rows 2-401"' C-m
tmux send-keys -t csv-import C-m
# 3. Monitor progress
sleep 30 && tmux capture-pane -t csv-import -p | tail -30
# 4. Send next step after completion
tmux send-keys -t csv-import 'claude -p "Transform to JSON"' C-m
tmux send-keys -t csv-import C-m
# 5. Continue monitoring
while tmux capture-pane -t csv-import -p | grep -q "Garnishing"; do
echo "Still processing..."
sleep 15
done
echo "Processing complete"
```
### Troubleshooting Claude Code in tmux
**Symptom**: Command appears in prompt but doesn't execute
- **Cause**: Forgot second C-m
- **Fix**: Send additional `tmux send-keys -t session-name C-m`
**Symptom**: Can't see what's happening
- **Cause**: Capture timing issue
- **Fix**: Add sleep before capture, increase tail lines
```bash
sleep 3 && tmux capture-pane -t csv-import -p | tail -40
```
**Symptom**: Session becomes unresponsive
- **Cause**: Claude Code waiting for input or error state
- **Fix**: Capture full pane to see error, send C-c to interrupt
```bash
tmux capture-pane -t csv-import -p
tmux send-keys -t csv-import C-c # Interrupt
```
## Remote Orchestration Protocol for Claude Code Sessions
### Overview
When orchestrating a Claude Code session running in tmux from another Claude Code instance, you need a systematic approach to monitor progress, detect issues, and guide execution.
### Session State Detection
**Parse capture-pane output to determine state:**
| Indicator | State | Action |
|-----------|-------|--------|
| `> ` at bottom with no activity | **IDLE** | Ready for new command |
| `⏺` bullet points updating | **ACTIVE** | Processing, monitor |
| `Garnishing...` | **PROCESSING** | Wait for completion |
| `Context left until auto-compact: X%` | **LOW_CONTEXT** | May need `/clear` soon |
| `API Error` or `Error:` | **ERROR** | Needs intervention |
| `Todos` with checkboxes | **PROGRESS** | Check task status |
| `☐` unchecked boxes | **PENDING** | Tasks remaining |
| `☒` or `☑` checked boxes | **COMPLETED** | Tasks done |
### Monitoring Cycle Protocol
**Every monitoring cycle should:**
1. **Capture current state**:
```bash
tmux capture-pane -t SESSION -p | tail -60
```
2. **Detect session state** from indicators above
3. **Log to scratch pad** with timestamp and findings
4. **Take action based on state**:
- IDLE + pending tasks → Send nudge command
- ERROR → Analyze and send recovery command
- ACTIVE → Continue monitoring
- LOW_CONTEXT → Prepare for context reset
### Intervention Commands
**Nudge idle session to continue:**
```bash
# Simple continuation nudge
tmux send-keys -t SESSION 'continue with the next task in the plan' C-m
sleep 0.5
tmux send-keys -t SESSION C-m
```
**Recovery from API error:**
```bash
# Acknowledge error and retry
tmux send-keys -t SESSION 'The previous operation encountered an API error. Please retry the last step.' C-m
sleep 0.5
tmux send-keys -t SESSION C-m
```
**Context compaction trigger:**
```bash
# Tell session to compact and continue
tmux send-keys -t SESSION '/clear' C-m
sleep 2
tmux send-keys -t SESSION 'Resume execution of docs/plans/2025-11-25-full-csv-transformation.md from where we left off' C-m
sleep 0.5
tmux send-keys -t SESSION C-m
```
**Progress check request:**
```bash
# Ask for status update
tmux send-keys -t SESSION 'What is the current progress? Which batch/task are you on?' C-m
sleep 0.5
tmux send-keys -t SESSION C-m
```
### Orchestrator Decision Tree
```
START MONITORING CYCLE
│
▼
┌───────────────────┐
│ Capture pane │
│ (last 60 lines) │
└─────────┬─────────┘
│
▼
┌───────────────────┐ ┌─────────────────┐
│ Is session IDLE? │─YES─▶│ Check pending │
│ ("> " at bottom) │ │ tasks in output │
└─────────┬─────────┘ └────────┬────────┘
│NO │
▼ ▼
┌───────────────────┐ ┌─────────────────┐
│ Is there ERROR? │─YES─▶│ Send recovery │
│ (API/tool error) │ │ command │
└─────────┬─────────┘ └────────┬────────┘
│NO │
▼ │
┌───────────────────┐ │
│ Is context LOW? │─YES─▶ Log warning, prepare /clear
│ (<15% remaining) │ │
└─────────┬─────────┘ │
│NO │
▼ │
┌───────────────────┐ │
│ Session ACTIVE │ │
│ Continue monitor │◀──────────────┘
└───────────────────┘
│
▼
SLEEP 30-60s
│
▼
NEXT CYCLE
```
### Long-Running Orchestration Pattern
For multi-hour workflows like CSV transformation:
```bash
# Orchestration scratch pad file
SCRATCH_PAD="/tmp/orchestration-$(date +%Y%m%d).md"
SESSION="eddy-csv-transform"
# Initialize scratch pad
echo "# Orchestration Log - $(date -u +"%Y-%m-%d %H:%M:%S UTC")" > $SCRATCH_PAD
# Monitoring loop
while true; do
TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC")
OUTPUT=$(tmux capture-pane -t $SESSION -p | tail -60)
# Log to scratch pad
echo "" >> $SCRATCH_PAD
echo "## Check: $TIMESTAMP" >> $SCRATCH_PAD
echo '```' >> $SCRATCH_PAD
echo "$OUTPUT" | tail -20 >> $SCRATCH_PAD
echo '```' >> $SCRATCH_PAD
# State detection
if echo "$OUTPUT" | grep -q "API Error\|Error:"; then
echo "**STATUS**: ERROR detected" >> $SCRATCH_PAD
# Send recovery command
tmux send-keys -t $SESSION 'retry the last operation that failed' C-m
sleep 0.5
tmux send-keys -t $SESSION C-m
echo "**ACTION**: Sent retry command" >> $SCRATCH_PAD
elif echo "$OUTPUT" | grep -q "^> $" | tail -1; then
# Check if truly idle (prompt visible, no activity)
if echo "$OUTPUT" | grep -q "☐"; then
echo "**STATUS**: IDLE with pending tasks" >> $SCRATCH_PAD
tmux send-keys -t $SESSION 'continue with the next pending task' C-m
sleep 0.5
tmux send-keys -t $SESSION C-m
echo "**ACTION**: Sent continuation nudge" >> $SCRATCH_PAD
fi
elif echo "$OUTPUT" | grep -q "Context left.*[0-9]%"; then
CONTEXT_PCT=$(echo "$OUTPUT" | grep -o "Context left.*[0-9]*%" | grep -o "[0-9]*")
if [ "$CONTEXT_PCT" -lt 15 ]; then
echo "**STATUS**: LOW CONTEXT ($CONTEXT_PCT%)" >> $SCRATCH_PAD
echo "**WARNING**: May need /clear soon" >> $SCRATCH_PAD
fi
else
echo "**STATUS**: ACTIVE/PROCESSING" >> $SCRATCH_PAD
fi
# Sleep before next check
sleep 45
done
```
### Sub-Agent Orchestration Pattern
When using a sub-agent to monitor remotely:
```python
Task(
description="Monitor and orchestrate CSV transformation",
prompt="""You are orchestrating a Claude Code session running in tmux session 'eddy-csv-transform'.
**YOUR MISSION**: Continuously monitor the session and guide it to completion of the full CSV transformation plan.
**MONITORING PROTOCOL**:
1. Capture current state: `tmux capture-pane -t eddy-csv-transform -p | tail -60`
2. Analyze state indicators (IDLE, ACTIVE, ERROR, LOW_CONTEXT)
3. Log findings to your scratch pad
4. Take appropriate action if needed
5. Sleep 45 seconds
6. REPEAT until all 20 batches complete
**STATE INDICATORS**:
- `> ` with no activity = IDLE, may need nudge
- `☐` unchecked = pending tasks
- `☒` checked = completed tasks
- `API Error` = needs recovery
- `Context left: X%` where X<15 = needs /clear
**INTERVENTION COMMANDS**:
- Nudge: `tmux send-keys -t eddy-csv-transform 'continue' C-m && sleep 0.5 && tmux send-keys -t eddy-csv-transform C-m`
- Recovery: `tmux send-keys -t eddy-csv-transform 'retry' C-m && sleep 0.5 && tmux send-keys -t eddy-csv-transform C-m`
**SUCCESS CRITERIA**:
- All 20 batches transformed, QA'd, and imported
- 1,916 universities in database with v3.9 schema
- PROGRESS.md shows all batches complete
**NEVER STOP** monitoring until the mission is complete or user intervenes.""",
subagent_type="general-purpose"
)
```
### Health Check Commands
**Quick status check:**
```bash
# One-liner status
tmux capture-pane -t SESSION -p | tail -5
```
**Full diagnostic:**
```bash
# Complete session dump
tmux capture-pane -t SESSION -p -S -1000 > /tmp/session-dump.txt
```
**Check if session exists:**
```bash
tmux has-session -t SESSION 2>/dev/null && echo "EXISTS" || echo "NOT FOUND"
```
### Recovery Scenarios
**Session crashed/closed:**
```bash
# Recreate session and resume
tmux new-session -d -s SESSION -c /path/to/project
tmux send-keys -t SESSION 'claude' C-m
sleep 3
tmux send-keys -t SESSION C-m
sleep 5
tmux send-keys -t SESSION 'Resume execution of the plan from where we left off' C-m
tmux send-keys -t SESSION C-m
```
**Session stuck on permission prompt:**
```bash
# Press 'y' to accept
tmux send-keys -t SESSION 'y' C-m
```
**Session needs user attention:**
```bash
# Check what it's asking for
tmux capture-pane -t SESSION -p | tail -20
# Respond accordingly
```
## Real-World Impact
- Enables programmatic control of vim/nano for file editing
- Allows automation of interactive git workflows (rebase, add -p)
- Makes REPL-based testing/debugging possible
- Unblocks any tool that requires terminal interaction
- **Enables orchestrating Claude Code sessions from another Claude Code instance**
- **Remote monitoring protocol for long-running multi-hour workflows**
- **Automatic error recovery and continuation nudging**
- No need to build custom PTY management - tmux handles it all
<!-- /progressive -->Related Skills
kitt-create-slash-commands
Expert guidance for creating slash commands. Use when working with slash commands, creating custom commands, understanding command structure, or learning YAML configuration.
tmux
Remote control tmux sessions for interactive CLIs (python, gdb, etc.) by sending keystrokes and scraping pane output.
agent-ops-code-review-interactive
Interactive code review for agent iterations. Captures comments, tracks resolution status, and integrates with git diffs.
agent-friendly-commands
Use these when you want low-noise lint/test output (good for LLM/CI logs) while staying aligned with repo policy.
bgo
Automates the complete Blender build-go workflow, from building and packaging your extension/add-on to removing old versions, installing, enabling, and launching Blender for quick testing and iteration.
mcp-create-declarative-agent
Skill converted from mcp-create-declarative-agent.prompt.md
MCP Architecture Expert
Design and implement Model Context Protocol servers for standardized AI-to-data integration with resources, tools, prompts, and security best practices
mathem-shopping
Automatiserar att logga in på Mathem.se, söka och lägga till varor från en lista eller recept, hantera ersättningar enligt policy och reservera leveranstid, men lämnar varukorgen redo för manuell checkout.
math-modeling
本技能应在用户要求"数学建模"、"建模比赛"、"数模论文"、"数学建模竞赛"、"建模分析"、"建模求解"或提及数学建模相关任务时使用。适用于全国大学生数学建模竞赛(CUMCM)、美国大学生数学建模竞赛(MCM/ICM)等各类数学建模比赛。
matchms
Mass spectrometry analysis. Process mzML/MGF/MSP, spectral similarity (cosine, modified cosine), metadata harmonization, compound ID, for metabolomics and MS data processing.
managing-traefik
Manages Traefik reverse proxy for local development. Use when routing domains to local services, configuring CORS, checking service health, or debugging connectivity issues.
managing-skills
Install, find, update, and manage agent skills. Use when the user wants to add a new skill, search for skills that do something, check if skills are up to date, or update existing skills. Triggers on: install skill, add skill, get skill, find skill, search skill, update skill, check skills, list skills.