16 KiB
Session Lifecycle Guide
Practical guide for managing tmux sessions through their complete lifecycle - from creation to cleanup
Overview
Tmux sessions managed by this skill follow a predictable lifecycle. Understanding these stages helps you make better decisions about when to create, reuse, or clean up sessions. This guide provides real-world workflows and decision trees for daily use.
When to use this guide:
- You're unsure whether to create a new session or reuse an existing one
- You need to debug a crashed or stuck session
- You want to understand proper cleanup workflows
- You're managing multiple parallel sessions
Lifecycle Stages
┌─────────────┐
│ PRE-CHECK │ Check existing sessions
│ (optional) │ Tool: list-sessions.sh
└──────┬──────┘
│
↓
┌─────────────┐
│ CREATE │ Spawn new tmux session
│ │ Tool: create-session.sh
└──────┬──────┘
│
↓
┌─────────────┐
│ INIT │ Wait for startup (prompt appears)
│ │ Tool: wait-for-text.sh
└──────┬──────┘
│
↓
┌─────────────┐
│ ACTIVE USE │ Send commands, capture output
│ │ Tools: safe-send.sh, wait-for-text.sh
└──────┬──────┘
│
↓
┌─────────────┐
│ IDLE │ Session exists but unused
│ │ Tool: list-sessions.sh (check status)
└──────┬──────┘
│
↓
┌─────────────┐
│ CLEANUP │ Remove dead/stale sessions
│ │ Tools: cleanup-sessions.sh, tmux kill-session
└─────────────┘
Error recovery:
- If session crashes → Check with
pane-health.sh - If session becomes zombie → Remove with
cleanup-sessions.sh - If network interruption → Reconnect using
tmux attachor resume with session name
Common Workflows
1. Quick Python Calculation (Ephemeral Session)
Use case: Run a one-off calculation, get the result, and cleanup immediately.
Duration: < 5 minutes
Commands:
# 1. Check no conflicts
./tools/list-sessions.sh
# 2. Create session
./tools/create-session.sh -n quick-calc --python
# 3. Send calculation
./tools/safe-send.sh -s quick-calc -c "import math; print(math.factorial(100))" -w ">>>" -T 10
# 4. Capture output
SOCKET=$(jq -r '.sessions["quick-calc"].socket' ~/.local/state/claude-tmux/.sessions.json)
tmux -S "$SOCKET" capture-pane -p -t quick-calc:0.0 -S -10
# 5. Cleanup immediately
tmux -S "$SOCKET" kill-session -t quick-calc
./tools/cleanup-sessions.sh
When to use: One-time calculations, quick tests, disposable experiments.
2. Long-Running Analysis (Persistent Session)
Use case: Hours or days of interactive REPL work with state preservation.
Duration: Hours to days
Commands:
# 1. Check existing sessions first
./tools/list-sessions.sh
# 2. Create persistent session with descriptive name
./tools/create-session.sh -n data-analysis-2025-11 --python
# 3. Load data (may take time)
./tools/safe-send.sh -s data-analysis-2025-11 -c "import pandas as pd" -w ">>>"
./tools/safe-send.sh -s data-analysis-2025-11 -c "df = pd.read_csv('large_dataset.csv')" -w ">>>" -T 300
# 4. Work interactively over time
./tools/safe-send.sh -s data-analysis-2025-11 -c "df.describe()" -w ">>>"
# ... hours later ...
./tools/safe-send.sh -s data-analysis-2025-11 -c "df.groupby('category').mean()" -w ">>>"
# 5. Check session health periodically
./tools/pane-health.sh -s data-analysis-2025-11
# 6. Cleanup only when done (days later)
./tools/list-sessions.sh # Verify it's the right session
tmux -S "$(jq -r '.sessions["data-analysis-2025-11"].socket' ~/.local/state/claude-tmux/.sessions.json)" kill-session -t data-analysis-2025-11
./tools/cleanup-sessions.sh
When to use: Long-running analysis, state preservation, multiple work sessions.
Best practices:
- Use descriptive names (include date or project name)
- Check health before resuming work
- Don't cleanup until completely done
- Capture important output early
3. Recovering from Crashed Session
Use case: Session died unexpectedly, need to investigate and restart.
Duration: 5-10 minutes
Commands:
# 1. Check session status
./tools/list-sessions.sh
# Output shows: status "dead" or "zombie"
# 2. Diagnose the issue
./tools/pane-health.sh -s crashed-session --format text
# Check exit code: 1=dead, 2=missing, 3=zombie
# 3. Capture any remaining output for debugging
SOCKET=$(jq -r '.sessions["crashed-session"].socket' ~/.local/state/claude-tmux/.sessions.json)
tmux -S "$SOCKET" capture-pane -p -t crashed-session:0.0 -S -200 > crash-output.txt 2>/dev/null || echo "Pane unavailable"
# 4. Remove dead session from registry
./tools/cleanup-sessions.sh # Removes dead sessions automatically
# 5. Create replacement session
./tools/create-session.sh -n crashed-session-recovery --python
# 6. Resume work with new session
./tools/safe-send.sh -s crashed-session-recovery -c "# Resuming from crash..." -w ">>>"
When to use: Session crashed, process died, debugging needed.
Troubleshooting tips:
- Always capture output before cleanup (may contain error messages)
- Check system logs if crash is mysterious:
dmesg,journalctl - Verify PYTHON_BASIC_REPL=1 was set (common cause of silent failures)
4. Multi-Session Workspace (Parallel Tasks)
Use case: Multiple parallel tasks (data loading, analysis, monitoring) in separate sessions.
Duration: Variable
Commands:
# 1. Check existing sessions
./tools/list-sessions.sh
# 2. Create multiple sessions with clear names
./tools/create-session.sh -n loader-session --python
./tools/create-session.sh -n analysis-session --python
./tools/create-session.sh -n monitor-session --python
# 3. Start parallel work
# Session 1: Load large dataset
./tools/safe-send.sh -s loader-session -c "import pandas as pd; df = pd.read_csv('huge.csv')" -w ">>>" -T 600 &
# Session 2: Run analysis on existing data
./tools/safe-send.sh -s analysis-session -c "results = analyze_data()" -w ">>>" -T 300 &
# Session 3: Monitor system
./tools/safe-send.sh -s monitor-session -c "import psutil; psutil.cpu_percent()" -w ">>>"
# 4. Check all sessions status
./tools/list-sessions.sh
# 5. Cleanup when done
./tools/cleanup-sessions.sh --all # Or cleanup individually
When to use: Parallel independent tasks, workspace organization, resource isolation.
Best practices:
- Use descriptive session names (purpose-based: loader-, analysis-, monitor-*)
- One session per major task (don't overload single session)
- Check
list-sessions.shfrequently to monitor all sessions - Cleanup all related sessions together when project complete
Decision Trees
Should I Create a New Session or Reuse?
Start
│
├─→ Is this a quick one-off task?
│ └─→ YES → Create new ephemeral session
│ (cleanup immediately after)
│
├─→ Do I have an existing session for this work?
│ ├─→ YES → Is it still alive?
│ │ ├─→ YES → Reuse existing session
│ │ └─→ NO → Create new session
│ └─→ NO → Create new session
│
└─→ Am I starting a new long-running project?
└─→ YES → Create new persistent session
(descriptive name with date/project)
Rules of thumb:
- ✅ Create new for: Different projects, parallel tasks, isolation needed
- ✅ Reuse for: Continuing same work, state preservation needed
- ❌ Don't reuse for: Unrelated tasks (state pollution), different projects
When Should I Clean Up Sessions?
Start
│
├─→ Is session marked as "dead" or "zombie"?
│ └─→ YES → Cleanup immediately
│ (./tools/cleanup-sessions.sh)
│
├─→ Has the task completed?
│ └─→ YES → Cleanup immediately
│ (tmux kill-session + cleanup-sessions.sh)
│
├─→ Is session idle for > 1 hour?
│ ├─→ AND no state preservation needed?
│ │ └─→ YES → Cleanup
│ └─→ OR state needed?
│ └─→ NO → Keep (long-running analysis)
│
└─→ Am I done for the day but continuing tomorrow?
└─→ Keep session (resume later)
Cleanup commands:
# Remove only dead/zombie sessions (safe, default)
./tools/cleanup-sessions.sh
# Remove sessions older than 1 hour
./tools/cleanup-sessions.sh --older-than 1h
# Remove all sessions (careful!)
./tools/cleanup-sessions.sh --all
# Preview what would be removed (dry-run)
./tools/cleanup-sessions.sh --dry-run
How Should I Handle Session Errors?
Error Detected
│
├─→ Is session responding to commands?
│ ├─→ NO → Check health (pane-health.sh)
│ │ ├─→ Dead/zombie → Capture output → Cleanup → Recreate
│ │ └─→ Alive but hung → Send C-c → Retry command
│ └─→ YES → Problem is elsewhere (not session)
│
├─→ Are commands being executed but output wrong?
│ └─→ Check PYTHON_BASIC_REPL=1 was set
│ └─→ Not set? Restart session with env var
│
└─→ Is prompt not appearing?
└─→ Increase timeout (-T flag)
└─→ Still failing? Check pane content manually
Tool Reference Matrix
| Lifecycle Stage | Tool | Purpose | Example Command |
|---|---|---|---|
| Pre-check | list-sessions.sh |
Check existing sessions | ./tools/list-sessions.sh |
| Create | create-session.sh |
Spawn new session | ./tools/create-session.sh -n my-session --python |
| Init | wait-for-text.sh |
Wait for startup prompt | ./tools/wait-for-text.sh -s my-session -p ">>>" -T 15 |
| Active Use | safe-send.sh |
Send commands safely | ./tools/safe-send.sh -s my-session -c "print(42)" -w ">>>" |
| Active Use | safe-send.sh (multiline) |
Send code blocks | ./tools/safe-send.sh -s my-session -m -c "def foo():\n return 42" -w ">>>" |
| Monitoring | pane-health.sh |
Check session health | ./tools/pane-health.sh -s my-session |
| Monitoring | list-sessions.sh |
View all sessions | ./tools/list-sessions.sh --json |
| Capture | tmux capture-pane |
Get session output | tmux -S $SOCKET capture-pane -p -t session:0.0 -S -100 |
| Cleanup | cleanup-sessions.sh |
Remove dead sessions | ./tools/cleanup-sessions.sh |
| Cleanup | tmux kill-session |
Terminate specific session | tmux -S $SOCKET kill-session -t my-session |
Troubleshooting Quick Reference
Session Not Found
Symptom: ./tools/safe-send.sh -s my-session -c "cmd" fails with "Session 'my-session' not found in registry"
Causes:
- Session was never created
- Session was created but not registered (
--no-registerflag used) - Session was cleaned up by mistake
Fixes:
# Check what sessions exist
./tools/list-sessions.sh
# Check if session exists outside registry
./tools/find-sessions.sh --all
# Recreate session
./tools/create-session.sh -n my-session --python
Commands Not Executing
Symptom: Commands sent but REPL shows no activity
Causes:
- PYTHON_BASIC_REPL=1 not set (most common!)
- Session crashed/dead
- Prompt not detected correctly
Fixes:
# Check session health
./tools/pane-health.sh -s my-session --format text
# Manually check what's in the pane
SOCKET=$(jq -r '.sessions["my-session"].socket' ~/.local/state/claude-tmux/.sessions.json)
tmux -S "$SOCKET" capture-pane -p -t my-session:0.0 -S -20
# If Python REPL, verify PYTHON_BASIC_REPL=1 was set
# Symptom: You'll see fancy colored prompts instead of plain >>>
# Fix: Kill and recreate with correct env var
Output Capture Issues
Symptom: tmux capture-pane returns incomplete or truncated output
Causes:
- Pane history buffer too small
- Lines wrapped due to terminal width
- ANSI color codes interfering
Fixes:
# Capture more history (-S flag = start line)
tmux -S "$SOCKET" capture-pane -p -t session:0.0 -S -500
# Join wrapped lines (-J flag)
tmux -S "$SOCKET" capture-pane -p -J -t session:0.0 -S -200
# Strip ANSI color codes
tmux -S "$SOCKET" capture-pane -p -t session:0.0 | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
Dead/Zombie Sessions
Symptom: ./tools/list-sessions.sh shows status "dead" or "zombie"
Causes:
- Process crashed
- Session was killed manually
- Out of memory / system issue
Fixes:
# Capture any remaining output for debugging
SOCKET=$(jq -r '.sessions["dead-session"].socket' ~/.local/state/claude-tmux/.sessions.json)
tmux -S "$SOCKET" capture-pane -p -t dead-session:0.0 -S -500 > debug.txt 2>/dev/null
# Remove from registry
./tools/cleanup-sessions.sh
# Recreate if needed
./tools/create-session.sh -n replacement-session --python
Multiple Sessions with Same Name
Symptom: ./tools/create-session.sh -n my-session --python fails with "session already exists"
Causes:
- Forgot to check existing sessions first
- Previous session not cleaned up
Fixes:
# Check existing sessions
./tools/list-sessions.sh
# Use different name OR cleanup old session first
tmux -S "$SOCKET" kill-session -t my-session
./tools/cleanup-sessions.sh
# Then create new session
./tools/create-session.sh -n my-session --python
Best Practices
✅ DO
-
Always check before creating
./tools/list-sessions.sh # Check for conflicts first -
Use descriptive session names
# Good: data-analysis-2025-11, debug-api-auth, monitor-prod # Bad: session1, test, tmp -
Set PYTHON_BASIC_REPL=1 for Python
# This is handled by create-session.sh --python automatically # But verify if creating manually -
Wait for prompts after every command
./tools/safe-send.sh -s session -c "command" -w ">>>" -T 10 # Always include -w flag for synchronization -
Use session registry (-s flag)
# Preferred: ./tools/safe-send.sh -s my-session -c "cmd" # Avoid: ./tools/safe-send.sh -S $SOCKET -t session:0.0 -c "cmd" -
Check health before critical operations
if ./tools/pane-health.sh -s session; then ./tools/safe-send.sh -s session -c "critical_command" fi -
Use multiline mode for code blocks
# 10x faster than line-by-line ./tools/safe-send.sh -s session -m -c "def foo():\n return 42" -w ">>>" -
Cleanup dead sessions regularly
# Run periodically or in cleanup scripts ./tools/cleanup-sessions.sh -
Capture output early and often
# Before making destructive changes tmux -S "$SOCKET" capture-pane -p -t session:0.0 -S -200 > backup.txt -
Use --dry-run for cleanup preview
# See what would be removed before executing ./tools/cleanup-sessions.sh --dry-run ./tools/cleanup-sessions.sh --older-than 2d --dry-run
❌ DON'T
- Don't create sessions without checking first - Leads to name conflicts
- Don't reuse sessions for unrelated work - State pollution causes bugs
- Don't forget -w flag when sending commands - Race conditions
- Don't skip health checks before critical operations - Pane might be dead
- Don't use generic session names - Hard to manage multiple sessions
- Don't leave dead sessions in registry - Clutters output, wastes resources
- Don't forget to cleanup ephemeral sessions - Resource leaks
- Don't send commands too fast - Wait for prompts between commands
- Don't ignore session health warnings - Investigate issues early
- Don't use line-by-line for large code blocks - Use multiline mode instead
Related References
- Session Registry Guide - Deep dive on registry system
- Direct Socket Control - Advanced manual socket management
- Main SKILL.md - Complete tmux skill documentation
Version: Documented for tmux skill v1.3.0+ (includes multiline support)