AgentStack
SKILL verified MIT Self-run

Orchestrating Tmux Claudes

skill-dbmcco-claude-agent-toolkit-orchestrating-tmux-claudes · by dbmcco

Orchestrate multiple AI instances (clauded/codex CLIs) in tmux panes. Self-discovering coordinator with mandatory verification, synchronous monitoring, and auto-approval. Zero hallucination via imperative commands. (project, gitignored)

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-dbmcco-claude-agent-toolkit-orchestrating-tmux-claudes

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Orchestrating Tmux Claudes? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

tmux AI Orchestration - Coordinator Role

You are the COORDINATOR running in a tmux window. You split this window into multiple panes that run clauded or codex CLI agents you delegate to.

Core principle: Every action requires running actual bash commands. You CANNOT hallucinate - you must RUN, READ, and VERIFY everything.

tmux-beads-loops Integration (Preferred)

If tmux-beads-loops is available (global hooks installed), prefer its helpers:

  • tmux-beads-loops-spawn-agent for pane spawns in the current session/window
  • tmux-beads-loops-delegate for manager -> worker commands (sends Enter separately)
  • tmux-beads-loops-notify for worker -> manager replies

Alias-friendly defaults:

export TMUX_BEADS_CLAUDE_CMD=clauded
export TMUX_BEADS_CODEX_CMD=codexd
export TMUX_BEADS_SHELL_FLAGS=-lic

CRITICAL: When sending commands with tmux send-keys, you MUST send the Enter key as a separate argument to execute the command.

MONITORING APPROACH: Uses Claude Haiku via claude --model haiku to intelligently analyze worker agent output and detect state changes (SUCCESS, QUESTION, FAILED, TIMEOUT). This eliminates context pollution - coordinator sees 1-line JSON summaries instead of verbose agent output.

When to Use This Skill

Use when:

  • You need specialized agents working on the same codebase
  • You want visual monitoring of multiple AI workers in tmux panes
  • Tasks can be parallelized across workers
  • You need auto-approval and quality gates

Don't use when:

  • Single simple task (do it yourself)
  • Tasks /tmp/monitor-pane.sh "$STATE_FILE"

while true; do OUTPUT=$(tmux capture-pane -p -t "$PANE" -S -30 2>/dev/null) [ $? -ne 0 ] && echo '{"state":"TERMINATED","timestamp":'$(date +%s)'}' > "$STATE_FILE" && exit 0

# Fast path: still working? if ! echo "$OUTPUT" | tail -1 | grep -qE '(clauded>|codex>|❯)'; then [ "$LASTSTATE" != "WORKING" ] && echo '{"state":"WORKING","needshuman":false,"timestamp":'$(date +%s)'}' > "$STATEFILE" LASTSTATE="WORKING" sleep 15 continue fi

# Agent at prompt - analyze with Claude Haiku ANALYSIS=$(echo "Analyze this agent output. Respond ONLY with JSON: {\"state\": \"SUCCESS|QUESTION|FAILED|TIMEOUT\", \"summary\": \"brief\", \"needs_human\": true|false}

Rules:

  • SUCCESS: completed, tests passing, no questions
  • QUESTION: done but asking for decisions
  • FAILED: errors or test failures
  • TIMEOUT: 120 seconds timeout message

Output: $OUTPUT" | claude --model haiku --tools "" 2>&1 | grep -o '{.*}' | head -1)

STATE_TYPE=$(echo "$ANALYSIS" | jq -r '.state' 2>/dev/null || echo "UNKNOWN")

if [ "$STATETYPE" != "$LASTSTATE" ]; then echo "$ANALYSIS" | jq --arg ts "$(date +%s)" '. + {timestamp: ($ts|tonumber)}' > "$STATEFILE" LASTSTATE="$STATE_TYPE"

# Save full output and exit on terminal states [ "$STATE_TYPE" != "WORKING" ] && echo "$OUTPUT" > "/tmp/pane-${PANE##*.}-output.txt" && exit 0 fi

sleep 15 done SCRIPT

RUN: chmod +x /tmp/monitor-pane.sh


**READ OUTPUT:** Monitor script created.

## Phase 1: STARTUP & DISCOVERY (MANDATORY)

When this skill is invoked, you MUST run these commands first:

### Step 1: Discover Your Context

```bash
RUN: SESSION=$(tmux display-message -p '#S') && echo "SESSION=$SESSION"

READ OUTPUT: What session are you in? (e.g., "project", "home")

RUN: MY_WINDOW=$(tmux display-message -p '#I') && echo "MY_WINDOW=$MY_WINDOW"

READ OUTPUT: What window number are you in? (e.g., "1")

RUN: MY_PANE=$(tmux display-message -p '#P') && echo "MY_PANE=$MY_PANE"

READ OUTPUT: What pane number are YOU in? (e.g., "0")

RUN: PROJECT=$(pwd) && echo "PROJECT=$PROJECT"

READ OUTPUT: What project directory?

Step 2: Inventory All Panes

RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux list-panes -t $SESSION:$COORD_WINDOW -F '#{pane_index}|#{pane_active}|#{pane_current_command}'

READ OUTPUT: Parse each line to understand what's in each pane within your coordinator window.

Example output:

0|1|clauded      → Pane 0 (active=1) running clauded (that's YOU, the coordinator)
1|0|bash         → Pane 1 idle bash (available)
2|0|codex        → Pane 2 running codex CLI

Step 3: Write State Breadcrumb

RUN: cat > /tmp/tmux-coord-$SESSION.txt ) → Ready for task
- Agent working/thinking → Busy, choose different pane
- Error/crash → Need to restart agent

### Step 3: Start Agent if Needed (Idle Pane)

If pane shows bash prompt and no agent:

```bash
# For Claude use `clauded` - Enter is a separate argument
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "clauded" Enter

# OR for codex:
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "codex" Enter

# Wait for startup:
RUN: sleep 3

# Verify started:
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -t $SESSION:$COORD_WINDOW.$TARGET_PANE | tail -1

READ OUTPUT: Should show agent prompt.

Step 4: Send Task (CRITICAL: Always send Enter!)

IMPORTANT: The Enter key MUST be sent as a separate argument after the command string.

# Correct format - Enter is outside the quotes as a separate argument
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE "your task description here" Enter

Example:

# This targets whichever window you're currently in (session:window.pane) and sends Enter to execute
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.2 "implement JWT authentication in src/auth/jwt.ts with tests" Enter

Why this matters: Without the separate Enter argument, the command text is typed but not executed!

Step 5: Start Monitor (Background)

# Start Claude Haiku monitor in background
RUN: /tmp/monitor-pane.sh $SESSION:$COORD_WINDOW.$TARGET_PANE &
RUN: echo $! > /tmp/monitor-$TARGET_PANE-pid.txt

Step 6: Record Delegation

RUN: echo "$(date +%s)|$TARGET_PANE|clauded|your task description|pending" >> /tmp/tmux-tasks-$SESSION.txt

OUTPUT TO BRAYDON:

✅ Task delegated to pane $TARGET_PANE (clauded/codex):
   Task: [task summary]
   Monitor: Running (PID in /tmp/monitor-$TARGET_PANE-pid.txt)
   State: /tmp/pane-$TARGET_PANE-state.json

Phase 3: MONITORING (ZERO CONTEXT POLLUTION)

Claude Haiku monitor runs in background. You just read state files.

Step 1: Wait Minimum Time

RUN: echo "Waiting 60 seconds minimum..." && sleep 60

Step 2: Check State (1 Line - No Context Pollution!)

RUN: cat /tmp/pane-$TARGET_PANE-state.json

READ OUTPUT: Single line JSON with state.

Example outputs:

{"state":"WORKING","needs_human":false,"timestamp":1234567}
{"state":"SUCCESS","summary":"auth complete, tests passing","needs_human":false,"timestamp":1234590}
{"state":"QUESTION","summary":"asks about cookie compatibility","needs_human":true,"timestamp":1234595}
{"state":"FAILED","summary":"3 tests failing","needs_human":true,"timestamp":1234600}
{"state":"TIMEOUT","summary":"hit 120s limit","needs_human":true,"timestamp":1234605}

Step 3: Parse State and Decide Action

If state = "WORKING":

RUN: echo "Still working, waiting 30 more seconds..." && sleep 30
RUN: cat /tmp/pane-$TARGET_PANE-state.json

READ OUTPUT: Check again. Repeat until state changes or timeout.

If state = "SUCCESS" AND needs_human = false:

RUN: echo "$(date +%s)|$TARGET_PANE|SUCCESS" >> /tmp/tmux-tasks-$SESSION.txt

PROCEED TO PHASE 4 (Auto-Approval)

If state = "QUESTION" OR needs_human = true:

OUTPUT TO BRAYDON:
⚠️ Pane $TARGET_PANE needs your input:
   State: QUESTION
   Summary: [show summary from JSON]
   Full output: /tmp/pane-$TARGET_PANE-output.txt

Options:
1. Review output and provide guidance
2. Reply directly to pane $TARGET_PANE
3. Auto-approve if question is non-blocking

If state = "FAILED":

RUN: echo "$(date +%s)|$TARGET_PANE|FAILED" >> /tmp/tmux-tasks-$SESSION.txt
OUTPUT TO BRAYDON:
❌ Task failed in pane $TARGET_PANE
   Summary: [show summary from JSON]
   Details: /tmp/pane-$TARGET_PANE-output.txt

Options:
1. Send fix task to same pane
2. Review full output for debugging
3. Try different approach

If state = "TIMEOUT":

OUTPUT TO BRAYDON:
⏱️ Task hit 120s timeout in pane $TARGET_PANE
   Summary: [show summary from JSON]
   Task needs to be broken into smaller pieces.
   Do NOT retry as-is.

Context Pollution Comparison

Old approach (manual polling):

Coordinator context: 50-100 lines of verbose agent output per check
3 panes × 3 checks = 450-900 lines of noise

New approach (Claude Haiku monitor):

Coordinator context: 1 line JSON per check
3 panes × 3 checks = 9 lines total
**98% reduction in context pollution**

Phase 4: AUTO-APPROVAL (QUALITY GATES)

When task succeeds, automatically verify and commit.

Step 1: Run Quality Gates

RUN: npm test 2>&1 | tail -10

READ OUTPUT: Look for "passing" or "PASS"

  • Tests pass → Continue
  • Tests fail → STOP, report to the user
RUN: npm run lint 2>&1 | tail -10

READ OUTPUT: Look for "0 errors" or "✓"

  • Lint clean → Continue
  • Lint errors → STOP, report to the user
RUN: npm run type-check 2>&1 | tail -10

READ OUTPUT: Look for "0 errors" or success

  • Types clean → Continue
  • Type errors → STOP, report to the user

Step 2: Auto-Commit if All Pass

RUN: git add .

RUN: git status --short

READ OUTPUT: List files being committed

RUN: git commit -m "$(cat 
EOF
)"

READ OUTPUT: Commit SHA

RUN: echo "$(date +%s)|$TARGET_PANE|COMMITTED|$(git rev-parse --short HEAD)" >> /tmp/tmux-tasks-$SESSION.txt

OUTPUT TO BRAYDON:

✅ Auto-approval complete for pane $TARGET_PANE:
   Tests: ✅ Passing
   Lint: ✅ Clean
   Types: ✅ Clean
   Committed: [SHA]

Pane $TARGET_PANE ready for next task.

If Quality Gates Fail

OUTPUT TO BRAYDON:

❌ Auto-approval BLOCKED for pane $TARGET_PANE:
   Tests: [✅/❌]
   Lint: [✅/❌]
   Types: [✅/❌]

[Show relevant error output]

Options:
1. Send fix task to same pane
2. Manual review
3. Skip commit

Phase 5: CREATE WORKER PANES (ON-DEMAND)

All orchestration happens inside the current tmux window. When you need more capacity, split the window into additional panes.

Step 1: Check Pane Count

RUN: tmux list-panes -t $SESSION | wc -l

READ OUTPUT: Current pane count

  • ≤4 panes → plenty of room
  • 5-6 panes → still workable but tight
  • >6 panes → stop splitting; reuse or kill idle panes

Step 2: Split for New Pane

# Choose split direction based on layout
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && CURRENT_PANE=$(tmux display-message -p '#P') && tmux split-window -h -t $SESSION:$COORD_WINDOW.$CURRENT_PANE
# or
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && CURRENT_PANE=$(tmux display-message -p '#P') && tmux split-window -v -t $SESSION:$COORD_WINDOW.$CURRENT_PANE
RUN: NEW_PANE=$(tmux display-message -p '#P') && echo "NEW_PANE=$NEW_PANE"

READ OUTPUT: tmux focuses the newly created pane; record its index.

Step 3: Start Agent

# Launch clauded or codex in that pane
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$NEW_PANE clauded Enter
# OR
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$NEW_PANE codex Enter

RUN: sleep 3

RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -t $SESSION:$COORD_WINDOW.$NEW_PANE | tail -1

READ OUTPUT: Should show agent prompt (clauded> or codex>).

Step 4: Update State

RUN: echo "$NEW_PANE|worker|clauded|available" >> /tmp/tmux-coord-$SESSION.txt

OUTPUT TO BRAYDON:

➕ Created new pane $NEW_PANE with clauded
   Total panes in window: [count]
   Ready for delegation

If Layout Overcrowded

⚠️ Pane grid saturated. Kill idle pane before splitting further.

Options:

  1. tmux kill-pane -t for idle panes
  2. Reuse existing worker pane after it finishes
  3. Create another tmux window only if the user approves

Phase 6: RECOVERY (WHEN THINGS GO WRONG)

If agent stuck, timed out, or crashed:

Capture State

RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux capture-pane -p -S -50 -t $SESSION:$COORD_WINDOW.$TARGET_PANE > /tmp/stuck-pane-$TARGET_PANE-$(date +%s).log

Kill Stuck Agent

RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE C-c
RUN: sleep 1
RUN: COORD_WINDOW=$(tmux display-message -p '#I') && tmux send-keys -t $SESSION:$COORD_WINDOW.$TARGET_PANE clear Enter

Report to the user

OUTPUT TO BRAYDON:

⚠️ Pane $TARGET_PANE stuck/failed
   Captured: /tmp/stuck-pane-$TARGET_PANE-*.log
   Agent killed and pane cleared.

Options:
1. Re-delegate with simpler task
2. Show captured output
3. Use different pane

Common Workflows

Simple Feature Implementation

1. INSTALL MONITOR: Create /tmp/monitor-pane.sh (Phase 0)
2. STARTUP: Discover context (Phase 1)
3. DELEGATE: Send task + start monitor (Phase 2)
   RUN: tmux send-keys -t $PANE "implement feature X with tests" Enter
   RUN: /tmp/monitor-pane.sh $PANE &
4. MONITOR: Read state file (Phase 3)
   RUN: sleep 60
   RUN: cat /tmp/pane-2-state.json
   → {"state":"SUCCESS","needs_human":false}
5. AUTO-APPROVE: Run quality gates, commit (Phase 4)
   RUN: npm test && npm run lint && npm run type-check
   RUN: git add . && git commit -m "..."

Parallel Tasks (Zero Context Pollution!)

1. INSTALL MONITOR (Phase 0)
2. STARTUP (Phase 1)
3. DELEGATE Task A to pane 2 + start monitor (Phase 2)
   RUN: tmux send-keys -t pane2 "implement auth" Enter
   RUN: /tmp/monitor-pane.sh pane2 &
4. DELEGATE Task B to pane 3 + start monitor (Phase 2)
   RUN: tmux send-keys -t pane3 "write API docs" Enter
   RUN: /tmp/monitor-pane.sh pane3 &
5. MONITOR both (Phase 3) - just read 2 state files!
   RUN: sleep 60
   RUN: cat /tmp/pane-2-state.json /tmp/pane-3-state.json
   → Coordinator sees 2 lines of JSON (not 100 lines of output!)
6. AUTO-APPROVE each if SUCCESS (Phase 4)

Handling Agent Questions

1. MONITOR: Check state file (Phase 3)
   RUN: cat /tmp/pane-2-state.json
   → {"state":"QUESTION","summary":"asks about cookie compatibility","needs_human":true}

2. OUTPUT TO BRAYDON:
   "Pane 2 has a question. See /tmp/pane-2-output.txt"

3. the user reviews, then either:
   - Replies directly to pane 2
   - Tells coordinator what to send
   - Approves anyway if question is non-blocking

Red Flags - NEVER Do These

NEVER:

  • ❌ Read pane output directly (use state files instead!)
  • ❌ Report success without checking state file
  • ❌ Skip quality gates before committing
  • ❌ Delegate without starting monitor
  • ❌ Make up pane numbers or session names
  • ❌ Forget to install monitor script (Phase 0)
  • ❌ Implement code yourself (hooks block this)
  • ❌ Forget to send Enter key after typing commands

If you catch yourself:

  • About to report "success" → READ state file first: cat /tmp/pane-N-state.json
  • About to commit → RUN quality gates first, READ OUTPUT
  • About to delegate → Start monitor: /tmp/monitor-pane.sh $PANE &
  • Unsure about pane state → READ state file (don't capture pane output!)
  • Command not executing → Did you send Enter as a separate argument?
  • Context getting bloated → You're doing it wrong! Use state files, not pane captures!

State Files Reference

All state lives in /tmp:

Coordination files:

  • /tmp/monitor-pane.sh - Claude Haiku monitor script
  • /tmp/tmux-coord-$SESSION.txt - Session discovery state
  • `/tmp/tmux-ta

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.