orquer-orchestrator
Event-driven orchestrator instructions for coordinating subordinate agents inside Orquer. Use when acting as an orchestrator managing workers across panes. Enforces zero polling, passive waiting, task
SKILL.mdskills/orquer-orchestrator/SKILL.md
GitHubOrquer Orchestrator Protocol
As an Orchestrator Agent in Orquer, you supervise one or more subordinate agents working in separate dedicated workspaces.
Cardinal Rules
- NO TERMINAL POLLING: Never loop reading terminal output (
orquer pane read) or guessing agent state every 50 seconds. The 50-second terminal watcher is deprecated and eliminated. - PASSIVE EVENT-DRIVEN WAITING: Always suspend execution on
orquer msg recv --wait. Your process sleeps until a subordinate actively sends a notification. - STRUCTURED DECISION RESOLUTION: When a subordinate is blocked on a multiple-choice decision or question, it sends an
askmessage. You MUST answer it promptly usingorquer msg reply. - NEVER SPLIT THE ORCHESTRATOR TERMINAL: The orchestrator workspace (🎯 Orchestrator) is a dedicated command deck. Never run
orquer pane split. Always launch workers in their own dedicated workspace in the sidebar usingorquer workspace create --label "<name>" --no-focus.
Workflow Guide
1. Spawning and Assigning Work to a Subordinate
To launch a worker in a dedicated workspace (in the sidebar list, never splitting the orchestrator pane):
# 1. Create a dedicated workspace in the sidebar (never split!)
# Returns the initial pane ID of the new workspace (e.g. w2:p1)
NEW_PANE=$(orquer workspace create --label "worker-1" --no-focus | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).result?.root_pane?.pane_id||''))" 2>/dev/null || orquer workspace create --label "worker-1" --no-focus | grep -o '"pane_id":"[^"]*"' | head -1 | sed 's/.*:"//; s/"$//')
# 2. Start the worker agent in that workspace pane (or send command)
orquer pane send-text "$NEW_PANE" "my-worker-agent\n"
# 3. Dispatch the task explicitly via the message bus (from 'orchestrator')
orquer msg send --to "$NEW_PANE" --from orchestrator --type task --payload '{"goal": "Build authentication module", "spec": "OAuth2"}'
2. Waiting Passively for Updates (Zero CPU / Zero Polling)
Instead of sleeping or polling, enter passive wait for incoming messages:
# Block until any message arrives for the orchestrator
MESSAGE=$(orquer msg recv --recipient orchestrator --wait --json)
You can optionally set a maximum wait timeout (in milliseconds):
# Wait up to 5 minutes (300,000 ms)
MESSAGE=$(orquer msg recv --recipient orchestrator --wait --timeout-ms 300000 --json)
3. Handling Incoming Message Types
Parse the incoming JSON message:
MSG_TYPE=$(echo "$MESSAGE" | jq -r '.msg_type')
MSG_ID=$(echo "$MESSAGE" | jq -r '.id')
SENDER=$(echo "$MESSAGE" | jq -r '.from')
Case A: ask (Subordinate Needs a Decision)
The subordinate is blocked waiting for your input. Inspect the question and available options:
QUESTION=$(echo "$MESSAGE" | jq -r '.payload.question')
OPTIONS=$(echo "$MESSAGE" | jq -r '.payload.options[]')
Evaluate the options, select the best choice, and reply:
# Reply to unblock the subordinate immediately
orquer msg reply --id "$MSG_ID" --choice "PostgreSQL"
Or shorthand:
orquer reply --id "$MSG_ID" --choice "PostgreSQL"
Case B: progress (Status Update)
The subordinate reported intermediate milestone progress. Log or review the update and resume waiting:
echo "Progress from $SENDER: $(echo "$MESSAGE" | jq -r '.payload')"
# Resume passive wait
Case C: result (Task Completed)
The subordinate has finished its assignment:
RESULT=$(echo "$MESSAGE" | jq -r '.payload')
echo "Task completed by $SENDER: $RESULT"
# Synthesize results or assign next task
Case D: error (Task Failed)
The subordinate encountered an unrecoverable failure:
ERR=$(echo "$MESSAGE" | jq -r '.payload')
echo "Task error in $SENDER: $ERR"
# Handle failure, retry, or abort
Orchestrator Loop Pattern
while true; do
MSG=$(orquer msg recv --recipient orchestrator --wait --json)
if [ -z "$MSG" ] || [ "$(echo "$MSG" | jq -r '.message')" = "null" ]; then
echo "Timeout reached or no messages."
break
fi
TYPE=$(echo "$MSG" | jq -r '.msg_type')
ID=$(echo "$MSG" | jq -r '.id')
FROM=$(echo "$MSG" | jq -r '.from')
case "$TYPE" in
ask)
Q=$(echo "$MSG" | jq -r '.payload.question')
echo "Decision required for $FROM: $Q"
# Decide choice...
CHOICE="Option A"
orquer msg reply --id "$ID" --choice "$CHOICE"
;;
result)
echo "Completed by $FROM: $(echo "$MSG" | jq '.payload')"
break
;;
error)
echo "Error from $FROM: $(echo "$MSG" | jq '.payload')"
break
;;
progress)
echo "Working: $(echo "$MSG" | jq '.payload')"
;;
esac
done