Agent skill

cmux-orchestrator

Dispatch and supervise multiple Claude Code workers in cmux workspaces. Crash-resilient, model-routed, file-based coordination. Triggers on "orchestrate", "dispatch", "오케스트레이터", "cmux workers".

Stars 0
Forks 0

Install this agent skill to your Project

npx add-skill https://github.com/devseunggwan/my-skills/tree/main/skills/cmux-orchestrator

SKILL.md

cmux Orchestrator

Overview

Dispatches tasks to independent Claude Code workers running in cmux workspaces. Each worker is a separate process — master crash does NOT kill workers.

Core principle: Workers are independent. Coordination is file-based. Crashes are recoverable.

Chains: turbo-setup → execute → turbo-deliver as a full pipeline per worker.

Architecture

┌──────────────────────────────────────────────┐
│            Orchestrator (this skill)          │
│                                              │
│  Queue ──▶ Dispatch ──▶ Supervise ──▶ Collect│
│  (.json)   (cmux API)   (poll loop)  (.jsonl)│
└──────────────┬───────────────┬───────────────┘
               │               │
     ┌─────────┼─────────┐    │
     ▼         ▼         ▼    ▼
  [ws:1]    [ws:2]    [ws:3]  results/
  claude    claude    claude   ├─ w1.jsonl
  --sonnet  --haiku   --opus   ├─ w2.jsonl
  task-1    task-2    task-3   └─ w3.jsonl

When to Use

  • Multiple independent tasks to execute in parallel
  • Batch processing (code reviews, test runs, migrations)
  • Any work that benefits from crash isolation
  • Triggers: "orchestrate", "dispatch", "오케스트레이터", "cmux workers"

Inputs

User provides a task list:

다음 작업들을 병렬로 처리해주세요:
1. laplace-airflow-dags PR #7042 코드 리뷰
2. laplace-web-v2 issue #300 구현
3. Hub #789 상태 확인

Or a structured task file:

json
// /tmp/orchestrator/tasks.json
[
  {"description": "PR #7042 코드 리뷰", "complexity": "medium", "cwd": "/path/to/repo"},
  {"description": "issue #300 구현", "complexity": "medium", "cwd": "/path/to/repo"},
  {"description": "Hub #789 상태 확인", "complexity": "low", "cwd": "/path/to/repo"}
]

Process

Step 1: Parse Tasks + Route Models

For each task, determine complexity and assign model:

Task → Complexity Router → Model Assignment
  "코드 리뷰"     → medium  → sonnet
  "구현"           → medium  → sonnet
  "상태 확인"      → low     → haiku
  "아키텍처 설계"  → high    → opus

Routing rules (from CLAUDE.md Model Routing Rules):

  • find, search, list, status, checkhaiku
  • implement, fix, test, review, refactorsonnet
  • architect, design, security, incident, debugopus
  • Default: sonnet

Present the dispatch plan and ask for confirmation:

═══════════════════════════════════════════════
 Dispatch Plan
═══════════════════════════════════════════════

 #  Task                          Model    Budget
 1  PR #7042 코드 리뷰            sonnet   $0.50
 2  issue #300 구현               sonnet   $1.00
 3  Hub #789 상태 확인            haiku    $0.10

 Total budget: $1.60
 Max concurrent workers: 3

 Proceed? (y/n)
═══════════════════════════════════════════════

Step 2: Initialize Orchestrator State

bash
ORCH_DIR="/tmp/cmux-orchestrator-$(date +%s)"
mkdir -p "$ORCH_DIR/logs" "$ORCH_DIR/results"

Create state files:

bash
# queue.json — pending tasks
# workers.json — active workers
# completed.json — finished results

Step 3: Dispatch Workers

For each task, create a cmux workspace:

bash
dispatch_worker() {
  local task_id="$1" description="$2" model="$3" cwd="$4" budget="$5"
  local log_file="$ORCH_DIR/logs/${task_id}.jsonl"

  local cmd="claude -p '${description}' \
    --output-format stream-json --verbose \
    --permission-mode auto \
    --model ${model} \
    --max-budget-usd ${budget} \
    2>&1 | tee ${log_file}; \
    echo '===WORKER_DONE===' >> ${log_file}"

  local raw=$(cmux new-workspace --cwd "$cwd" --command "$cmd")
  local ws=$(echo "$raw" | sed 's/^OK //')

  cmux rename-workspace --workspace "$ws" "[w${task_id}] ${description:0:25}"

  # Get surface ref for monitoring
  local surface=$(cmux list-pane-surfaces --workspace "$ws" 2>/dev/null \
    | grep -oP 'surface:\d+' | head -1)

  # Register worker
  echo "{\"id\":\"${task_id}\",\"ws\":\"${ws}\",\"surface\":\"${surface}\",\"status\":\"running\",\"log\":\"${log_file}\"}"
}

Step 4: Supervise (Poll Loop)

Monitor all workers until completion:

bash
supervise() {
  local poll_interval=10
  local stuck_threshold=300  # 5 min

  while true; do
    local all_done=true
    local running=0
    local completed=0
    local failed=0

    for worker in $(jq -c '.[]' "$ORCH_DIR/workers.json"); do
      local ws=$(echo "$worker" | jq -r '.ws')
      local task_id=$(echo "$worker" | jq -r '.id')
      local status=$(echo "$worker" | jq -r '.status')

      [ "$status" = "completed" ] || [ "$status" = "failed" ] && {
        completed=$((completed + 1)); continue
      }

      all_done=false
      running=$((running + 1))

      # Read screen to detect state
      local screen=$(cmux read-screen --workspace "$ws" --lines 5 2>/dev/null)

      if echo "$screen" | grep -q "===WORKER_DONE==="; then
        update_status "$task_id" "completed"
        collect_result "$task_id"
        completed=$((completed + 1))

      elif echo "$screen" | grep -q "Do you want to proceed"; then
        cmux send-key --workspace "$ws" Enter 2>/dev/null

      elif echo "$screen" | grep -q "Error\|FAILED\|panic"; then
        update_status "$task_id" "failed"
        failed=$((failed + 1))
      fi
    done

    # Status line
    echo -ne "\r[orchestrator] running:${running} completed:${completed} failed:${failed}  "

    $all_done && break
    sleep $poll_interval
  done
}

Step 5: Collect Results

bash
collect_result() {
  local task_id="$1"
  local log="$ORCH_DIR/logs/${task_id}.jsonl"
  local result_file="$ORCH_DIR/results/${task_id}.json"

  # Extract final result from stream-json
  python3 -c "
import json
result = None
cost = 0
with open('${log}') as f:
    for line in f:
        try:
            obj = json.loads(line)
            if obj.get('type') == 'result':
                result = obj.get('result', '')
                cost = obj.get('total_cost_usd', 0)
        except: pass
json.dump({'task_id': '${task_id}', 'result': result, 'cost': cost}, 
          open('${result_file}', 'w'), ensure_ascii=False, indent=2)
print(f'Task ${task_id}: \${cost:.4f} — {(result or \"\")[:80]}')
  "
}

Step 6: Report Summary

═══════════════════════════════════════════════
 Orchestration Complete
═══════════════════════════════════════════════

 #  Task                    Status     Cost     Result
 1  PR #7042 리뷰           ✅ done    $0.24    "3 issues found, 1 critical..."
 2  issue #300 구현         ✅ done    $0.45    "Feature implemented, tests pass..."
 3  Hub #789 확인           ✅ done    $0.03    "Status: all tasks completed..."

 Total: 3 tasks, 0 failed, $0.72 total cost
 Duration: 4m 32s
═══════════════════════════════════════════════

Crash Recovery

If the orchestrator (or master Claude session) crashes:

bash
# 1. Workers continue running (independent processes)
# 2. Restart orchestrator
# 3. Rescan cmux workspaces for [w*] prefixed names
# 4. Re-attach to workers via workspace refs
# 5. Collect completed results, resume supervision

recover_orchestrator() {
  local orch_dir="$1"

  # Find worker workspaces still alive
  cmux list-workspaces 2>/dev/null | grep '\[w' | while read line; do
    local ws=$(echo "$line" | grep -oP 'workspace:\d+')
    local screen=$(cmux read-screen --workspace "$ws" --lines 3 2>/dev/null)

    if echo "$screen" | grep -q "===WORKER_DONE==="; then
      echo "COMPLETED: $ws"
    elif echo "$screen" | grep -q "❯"; then
      echo "IDLE: $ws (may need re-dispatch)"
    else
      echo "RUNNING: $ws"
    fi
  done
}

Full Pipeline Mode

Chain turbo-setup → execute → turbo-deliver per worker:

bash
# Each worker runs the full lifecycle
full_pipeline_cmd() {
  local task="$1" model="$2" budget="$3"
  echo "claude -p '
    Phase 1: Run /turbo-setup for: ${task}
    Phase 2: Implement the task
    Phase 3: Run /turbo-deliver
  ' --output-format stream-json --verbose \
    --permission-mode auto \
    --model ${model} \
    --max-budget-usd ${budget}"
}

Integration

Workflow position:

[user provides task list]
  → [cmux-orchestrator]
     ├─ [worker 1] turbo-setup → execute → turbo-deliver
     ├─ [worker 2] turbo-setup → execute → turbo-deliver
     └─ [worker 3] turbo-setup → execute → turbo-deliver
  → [results summary]

Depends on:

  • turbo-setup (per-worker setup automation)
  • turbo-deliver (per-worker delivery automation)
  • Model Routing Rules (from CLAUDE.md)
  • cmux CLI (new-workspace, read-screen, send-key, list-workspaces)

Environment:

  • cmux must be running (cmux ping)
  • Claude Code CLI available (claude -p)
  • /tmp/cmux-orchestrator-* for state files

Expand your agent's capabilities with these related and highly-rated skills.

devseunggwan/my-skills

cmux-session-manager

cmux 세션 일상 관리 자동화. status(대시보드)/cleanup(정리+재조직) 수동 커맨드와 init(hook)/report(schedule) 자동화. Triggers on "cmux session", "세션 관리", "세션 정리", "cmux status", "cmux cleanup", "cmux tidy".

0 0
Explore
devseunggwan/my-skills

debug

Systematic 4-phase debugging — root cause investigation before any fix attempt. Use for any bug, test failure, or unexpected behavior. Triggers on "debug", "debugging", "why failing", "why broken", "root cause".

0 0
Explore
devseunggwan/my-skills

verify-completion

Enforce verification evidence before any completion claim. Tests, builds, and lint must be run with output shown — no claims without proof. Triggers on "verify", "verification", "done check", "completion check".

0 0
Explore
devseunggwan/my-skills

recover-sessions

Bulk recover Claude Code sessions after power loss or tmux crash. Interactive interview to determine recovery scope, layout, and execution mode. Triggers on "recover", "session recovery", "restore sessions", "power recovery".

0 0
Explore
devseunggwan/my-skills

finish-branch

Complete a development branch lifecycle — compound context, merge PR, clean up worktree and branch. Triggers on "cleanup", "worktree cleanup", "finish branch", "branch cleanup".

0 0
Explore
devseunggwan/my-skills

turbo-setup

Compound setup — issue + plan + branch + worktree + deps in one step. Triggers on "setup", "착수", "turbo-setup", "quick start".

0 0
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results