Claude Tmux Session Awareness
This skill enables Claude to work effectively within tmux sessions created by cctmux.
Philosophy
Terminal as Workspace: Tmux panes provide dedicated spaces for background processes without cluttering the main conversation. Use panes for:
- Development servers
- File watchers
- Test runners in watch mode
- Build processes
- Log tailing
Visibility Over Convenience: Processes running in visible panes are easier to monitor and debug than hidden background processes.
Create Then Launch: Always create panes first, then use send-keys to launch applications. This ensures proper shell environment and allows easy process restart.
Session Discovery
Environment Variables
When running in a cctmux session, these environment variables are available:
$CCTMUX_SESSION # The tmux session name (e.g., "my-project")
$CCTMUX_PROJECT_DIR # The project directory path
Detecting cctmux Session
Before attempting tmux operations, verify you're in a cctmux session:
if [ -n "$CCTMUX_SESSION" ]; then
echo "Running in cctmux session: $CCTMUX_SESSION"
fi
Pane Management
Discover Window Index AND Pane IDs First (CRITICAL)
Both the window index AND pane indices are NOT always 0. cctmux sessions may use window index 1 and pane indices starting at 1 or any other value. Hardcoding :0.0 or :0.1 will target the wrong pane or fail entirely.
Always discover actual values before targeting panes. The easiest way is the built-in machine-readable listing — no format-string parsing:
# One-shot JSON: pane_id, index, active, command, size, path, title per pane
cctmux panes --json
Raw tmux equivalents when you need specific format fields:
# Get the window index (use this before any pane operations)
W=$(tmux list-panes -t "$CCTMUX_SESSION" -F "#{window_index}" | head -1)
# Get all pane IDs with their commands (pane IDs like %15 are STABLE and UNIQUE)
tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_current_command}"
Prefer Pane IDs Over Positional Indices (CRITICAL)
Pane IDs (e.g., %15, %16) are always stable and safe to target. Positional indices (.0, .1, .2) shift when panes are created/destroyed and don't always start at 0.
When creating new panes, always capture the pane ID with -d -P -F "#{pane_id}":
# -d = don't switch focus, -P -F = print the new pane's ID
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 30)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
When targeting existing panes, look up pane IDs from list-panes, never assume indices:
# Find pane IDs and what's running in each
tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_current_command}"
# Output example: %15 claude %16 bash %17 bash
# Then target by pane ID
tmux send-keys -t "%16" "npm run dev" Enter
Identify the Main (Claude) Pane (CRITICAL)
Never send commands to the pane where Claude Code is running. The main pane is where YOU (Claude) are executing — sending commands there will type into your own input.
Identify the main pane before targeting others:
# The active pane is typically the Claude pane
MAIN_PANE=$(tmux display-message -t "$CCTMUX_SESSION" -p "#{pane_id}")
# List all panes — your pane shows as the claude/python process
tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_current_command}"
# Target only panes that are NOT your main pane (bash/idle panes are safe targets)
Examine Current State
Always check the current pane layout before making changes and present it to the user in a markdown table so they can make informed decisions about where to place tools.
# List all panes with window index, IDs, sizes, and running process
tmux list-panes -t "$CCTMUX_SESSION" -F "#{window_index}.#{pane_index}: #{pane_id} #{pane_width}x#{pane_height} #{pane_current_command}"
After running this command, display results to the user as a table like:
| Pane | Size | Process |
|---|---|---|
| 1 (main) | 120x55 | claude |
| 2 | 90x27 | bash (idle) |
| 3 | 90x27 | cctmux-tasks |
This gives the user visibility into the current layout so they can instruct you where to launch processes, which panes to reuse, or how to rearrange things.
Creating Panes
IMPORTANT: Always create panes without commands, then use send-keys to launch applications. This ensures:
- Proper shell environment with all exports
- Ability to restart processes with up-arrow + Enter
- Consistent behavior across different shells
Horizontal Split (side by side)
# Split with 30% width on the right
tmux split-window -t "$CCTMUX_SESSION" -h -p 30
# Split with specific column width
tmux split-window -t "$CCTMUX_SESSION" -h -l 80
Vertical Split (stacked)
# Split with 20% height on the bottom
tmux split-window -t "$CCTMUX_SESSION" -v -p 20
# Split with specific line count
tmux split-window -t "$CCTMUX_SESSION" -v -l 10
Launching Applications in Panes
After creating a pane, use send-keys to launch applications. Always capture the pane ID:
# Create pane and capture its ID, then launch application
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 30)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
Navigating Panes
# Select pane by pane ID (preferred — always stable)
tmux select-pane -t "%15"
# Select pane by direction (no index needed)
tmux select-pane -t "$CCTMUX_SESSION" -L # Left
tmux select-pane -t "$CCTMUX_SESSION" -R # Right
tmux select-pane -t "$CCTMUX_SESSION" -U # Up
tmux select-pane -t "$CCTMUX_SESSION" -D # Down
Resizing Panes
# Resize by cell count
tmux resize-pane -t "$CCTMUX_SESSION" -L 10 # Shrink left
tmux resize-pane -t "$CCTMUX_SESSION" -R 10 # Expand right
tmux resize-pane -t "$CCTMUX_SESSION" -U 5 # Shrink up
tmux resize-pane -t "$CCTMUX_SESSION" -D 5 # Expand down
# Resize to percentage
tmux resize-pane -t "$CCTMUX_SESSION" -x 70% # Set width
tmux resize-pane -t "$CCTMUX_SESSION" -y 80% # Set height
Sending Commands to Panes
# Send command to specific pane by pane ID (preferred)
tmux send-keys -t "%16" "npm run dev" Enter
# Send Ctrl+C to stop a process
tmux send-keys -t "%16" C-c
# Restart a process (Ctrl+C, then run again)
tmux send-keys -t "%16" C-c
tmux send-keys -t "%16" "npm run dev" Enter
Driving Another Claude in a Pane
When orchestrating a second Claude Code instance in another pane — driving it with send-keys, reading its state with capture-pane — knowing when it finishes a turn and submitting commands reliably both have gotchas. For the hardened idle-or-heartbeat poller, the single-call command-submission pattern (and why a separate Enter lands on autosuggestion ghost text), and how to answer a remote question menu, read references/driving-claude-panes.md in this skill's directory.
The idle-or-heartbeat poller is packaged as a built-in command — prefer it over hand-rolling the capture loop:
# Block until the pane's Claude goes idle (exit 0) or the 5-min heartbeat fires (exit 2)
cctmux wait-idle %15 --json
# Tune: --timeout 300 --interval 10 --silence 60 --lines 25; --pattern for non-Claude spinners
Run it in the background (run_in_background: true) so you are re-invoked when it exits, then read its JSON (state, elapsed, tail), handle the pane, and re-arm.
Closing Panes
# Close specific pane by pane ID (preferred)
tmux kill-pane -t "%16"
# Close all panes except the current one
tmux kill-pane -t "$CCTMUX_SESSION" -a
Background Process Patterns
Dev Server Pattern
Create a dedicated pane for a development server:
# Check if we need a dev server pane
pane_count=$(tmux list-panes -t "$CCTMUX_SESSION" | wc -l)
if [ "$pane_count" -eq 1 ]; then
# Create pane for dev server, capture its ID
DEV_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 30)
# Launch dev server
tmux send-keys -t "$DEV_PANE" "npm run dev" Enter
fi
File Watcher Pattern
Run file watchers in a bottom pane:
# Create small bottom pane for watcher output, capture its ID
WATCH_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -v -l 8)
tmux send-keys -t "$WATCH_PANE" "npm run watch" Enter
Test Watch Pattern
Run tests in watch mode:
# Create right pane for test output, capture its ID
TEST_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 40)
tmux send-keys -t "$TEST_PANE" "npm test -- --watch" Enter
Multiple Processes Layout
For complex setups with multiple background processes:
# Create right column (50%), capture its ID
RIGHT_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 50)
# Launch dev server in right pane
tmux send-keys -t "$RIGHT_PANE" "npm run dev" Enter
# Split right pane for tests (bottom half of right column), capture its ID
BOTTOM_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$RIGHT_PANE" -v -p 50)
# Launch test watcher in new bottom-right pane
tmux send-keys -t "$BOTTOM_PANE" "npm test -- --watch" Enter
Predefined Layouts
cctmux supports several predefined layouts via the --layout / -l option:
| Layout | Description |
|---|---|
default |
No initial split, panes created on demand |
editor |
70/30 horizontal split (main + side pane) |
monitor |
80/20 vertical split (main + bottom bar) |
triple |
Main + 2 side panes (50/50, right split vertically) |
cc-mon |
Claude + session monitor + task monitor |
full-monitor |
Claude + session + tasks + activity dashboard |
dashboard |
Large activity dashboard with session sidebar |
ralph |
Shell + ralph monitor side-by-side (60/40) |
ralph-full |
Claude + ralph monitor + git monitor + task monitor (2x2 grid) |
git-mon |
Claude (60%) + git status monitor (40%) |
CC-Mon Layout
The cc-mon layout is designed for monitoring Claude Code activity:
-------------------------------
| CLAUDE | cctmux-session |
| 50% | 50% |
| |----------------|
| | cctmux-tasks -g|
| | 50% |
-------------------------------
Start with this layout:
cctmux -l cc-mon
This layout provides:
- Left pane (50%): Main Claude Code session
- Top-right pane: Real-time session monitor showing tool calls, thinking blocks, and token usage
- Bottom-right pane: Task dependency graph showing current task progress
Full-Monitor Layout
The full-monitor layout adds the activity dashboard for complete visibility:
-----------------------------------------
| | cctmux-session 30% |
| CLAUDE |-----------------------------|
| 60% | cctmux-tasks -g 35% |
| |-----------------------------|
| | cctmux-activity 35% |
-----------------------------------------
Start with this layout:
cctmux -l full-monitor
Dashboard Layout
The dashboard layout is optimized for reviewing usage statistics:
-----------------------------------------
| | cctmux-session |
| cctmux-activity | 30% |
| 70% |----------------|
| | mini shell |
| | 30% |
-----------------------------------------
Start with this layout:
cctmux -l dashboard
Par Mode
Par mode sets up a triple layout with task stats and git monitor. For the full idempotent activation script and layout diagram, read references/par-mode.md in this skill's directory.
Saved Layouts
cctmux supports saving and recalling pane arrangements. For the full save/recall/delete workflow, storage format, safety rules, and example layouts, read references/saved-layouts.md in this skill's directory. When a user asks about layouts, check saved layouts first before creating new ones.
Command Reference
First, discover pane IDs: tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_current_command}"
Create panes with ID capture: PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 30)
| Action | Command |
|---|---|
| List panes as JSON | cctmux panes --json |
| Wait for a Claude pane to go idle | cctmux wait-idle %N --json (exit 0 idle, 2 heartbeat) |
| List panes (with IDs) | tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_width}x#{pane_height} #{pane_current_command}" |
| Get main pane ID | MAIN=$(tmux display-message -t "$CCTMUX_SESSION" -p "#{pane_id}") |
| Split + capture ID | PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h [-p %]) |
| Select pane | tmux select-pane -t "$PANE_ID" |
| Send keys | tmux send-keys -t "$PANE_ID" "cmd" Enter |
| Send Ctrl+C | tmux send-keys -t "$PANE_ID" C-c |
| Kill pane | tmux kill-pane -t "$PANE_ID" |
| Resize width | tmux resize-pane -t "$CCTMUX_SESSION" -x N% |
| Resize height | tmux resize-pane -t "$CCTMUX_SESSION" -y N% |
Anti-Patterns
Don't Use Hardcoded Pane Indices
❌ Assuming pane indices start at 0
# Bad: pane indices may start at 1 or any number — this could target your own Claude pane!
tmux send-keys -t "$CCTMUX_SESSION:$W.0" "some command" Enter
tmux send-keys -t "$CCTMUX_SESSION:$W.1" "npm run dev" Enter
✅ Use captured pane IDs or discover actual IDs first
# Good: capture ID when creating
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h -p 30)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
# Good: discover IDs for existing panes
tmux list-panes -t "$CCTMUX_SESSION" -F "#{pane_id} #{pane_current_command}"
tmux send-keys -t "%16" "npm run dev" Enter
Don't Launch Commands Directly in split-window
❌ Running commands as split-window arguments
# Bad: command runs in subshell, no shell history, exits on completion
tmux split-window -t "$CCTMUX_SESSION" -h "npm run dev"
✅ Create pane with -d flag, capture ID, then send-keys
# Good: proper shell environment, can restart with up-arrow, -d keeps focus
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
Don't Create Unnecessary Panes
❌ Creating a pane for a one-off command
# Bad: pane for single command
tmux split-window -t "$CCTMUX_SESSION" -h
✅ Use panes for persistent processes
# Good: pane for long-running dev server
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
Always Use -d Flag (Don't Steal Focus)
❌ Creating pane without -d (steals focus to new pane)
# Bad: focus moves to new pane, then you must manually select back
tmux split-window -t "$CCTMUX_SESSION" -h
✅ Use -d to stay in current pane
# Good: -d keeps focus in current pane, no need to select-pane back
NEW_PANE=$(tmux split-window -d -P -F "#{pane_id}" -t "$CCTMUX_SESSION" -h)
tmux send-keys -t "$NEW_PANE" "npm run dev" Enter
Don't Over-Split
❌ Creating too many panes
# Bad: 5+ panes become hard to manage
✅ Use 2-4 panes maximum
# Good: main pane + 1-2 utility panes
Check Before Creating
❌ Blindly creating panes
# Bad: might duplicate existing layout
tmux split-window ...
✅ Check existing state first
# Good: verify current layout
tmux list-panes -t "$CCTMUX_SESSION"
Monitors
cctmux includes five monitor CLI tools: cctmux-tasks (task dependencies), cctmux-session (session events), cctmux-activity (usage dashboard), cctmux-git (repo status), and cctmux-agents (subagent tracking). For full CLI options, display features, and pane setup examples, read references/monitors.md in this skill's directory.
Ralph Loop
The Ralph Loop (cctmux-ralph) is an automated iterative development engine. For project file format, CLI commands, completion detection, layouts, and state file details, read references/ralph.md in this skill's directory.
Configuration
cctmux supports layered configuration:
- User config:
~/.config/cctmux/config.yaml— base settings - Project config:
.cctmux.yamlin project root — shared team overrides (committed to repo) - Project local config:
.cctmux.yaml.localin project root — personal overrides (gitignored)
Values are deep-merged (last wins). Set ignore_parent_configs: true in a project config to skip user config entirely.
Configuration File Structure
# Default Claude arguments
default_claude_args: ""
# Default layout (default, editor, monitor, triple, cc-mon, full-monitor, dashboard, ralph, ralph-full, git-mon)
default_layout: default
# Session monitor settings
session_monitor:
show_thinking: true
show_results: true
show_progress: true
show_system: false
show_snapshots: false
show_cwd: false
show_threading: false
show_stop_reasons: true
show_turn_durations: true
show_hook_errors: true
show_service_tier: false
show_sidechain: true
max_events: 50
# Task monitor settings
task_monitor:
show_owner: true
show_metadata: false
show_description: true
show_graph: true
show_acceptance: true
show_work_log: false
max_tasks: 100
# Activity monitor settings
activity_monitor:
default_days: 14
show_heatmap: true
show_cost: true
show_model_usage: true
show_hour_distribution: false
Configuration Presets
All monitors support --preset for quick configuration:
| Preset | Description |
|---|---|
minimal |
Essential info only, reduced visual noise |
verbose |
All information displayed, including optional fields |
debug |
Maximum detail for troubleshooting |
cctmux-session --preset minimal
cctmux-tasks --preset verbose
cctmux-activity --preset debug
CLI flags override both config file and preset values.
Team Mode
For team workflows (cctmux team), read references/team.md in this skill's directory for team-specific environment variables, agent configuration, and the skill prompt acceptance pattern. For team coordination (task delegation, messaging, progress tracking), load the cc-team-lead skill.
Troubleshooting
"Not in cctmux session"
If $CCTMUX_SESSION is not set, you're not in a cctmux-managed session. Either:
- Start a new session with
cctmux - Use standard tmux commands without the session variable
"Can't split window: pane too small"
The terminal is too small for more splits. Either:
- Resize the terminal window
- Close existing panes before creating new ones
- Use smaller split percentages
Process Not Starting
If a command doesn't start in the new pane:
- Check the command syntax
- Verify the working directory
- Use
tmux capture-pane -p -t "$CCTMUX_SESSION:$W.N"to see pane output