@devo-bmad-custom/agent-orchestration 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devo-bmad-custom/agent-orchestration",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "BMAD Method — AI-native agile workflow system for Claude Code and compatible AI assistants",
5
5
  "keywords": [
6
6
  "bmad",
@@ -7,7 +7,7 @@ Verified, tested tmux command templates for agent orchestration. Every command i
7
7
  2. Always append `Enter` to every `tmux send-keys` call
8
8
  3. **Use `-l` (literal) flag for all free-form message content** — prevents `|`, `:`, and other chars being interpreted as tmux key sequences. Send `Enter` as a separate call after. Do NOT use `-l` for slash commands (`/color`, `/rename`, `/exit`) — those must be interpreted.
9
9
  4. Verify pane exists before any operation targeting it
10
- 5. Use `/rename` and `/color` Claude Code commands (not OSC 2 or `select-pane -T`) for agent identity
10
+ 5. **`/color` and `/rename` are sent by the spawner** via separate `tmux send-keys` calls after the agent starts — never rely on the agent's prompt to self-invoke them. Each command is its own `send-keys` call with `Enter`, with `sleep 10` between.
11
11
 
12
12
  ---
13
13
 
@@ -56,31 +56,38 @@ ROLE="dev"
56
56
  ROLE_COLOR=$(get_role_color "$ROLE")
57
57
  SPAWNER_PANE=$(tmux display-message -p "#{pane_id}")
58
58
 
59
- # 1. Split the pane
59
+ # 1. Split the pane — wait 15s for WSL bash + Claude to initialize before sending commands
60
60
  sleep 10
61
61
  tmux split-window -h -c "$PROJECT_ROOT" \
62
62
  "claude --dangerously-skip-permissions 'You are the $ROLE agent. \
63
- FIRST: run /color $ROLE_COLOR then /rename $ROLE-agent. \
64
- Spawner pane: $SPAWNER_PANE. Session file: $SESSION_FILE. \
63
+ Your spawner pane is $SPAWNER_PANE. Session file: $SESSION_FILE. \
64
+ Always use -l flag for message content in tmux send-keys. \
65
65
  Always sleep 10 before and after every tmux command. \
66
66
  Always append Enter to every tmux send-keys call. \
67
67
  Always verify pane exists before targeting it. \
68
68
  $TASK_CONTEXT'"
69
- sleep 10
69
+ sleep 15
70
70
 
71
71
  # 2. Capture new pane ID
72
72
  NEW_PANE_ID=$(tmux list-panes -F "#{pane_id}" | tail -1)
73
+
74
+ # 3. Set agent identity — spawner sends /color and /rename as separate commands.
75
+ # Do NOT combine into one send-keys call; each must be submitted individually.
76
+ sleep 10
77
+ tmux send-keys -t "$NEW_PANE_ID" "/color $ROLE_COLOR" Enter
78
+ sleep 10
79
+ tmux send-keys -t "$NEW_PANE_ID" "/rename ${ROLE}-agent" Enter
73
80
  sleep 10
74
81
 
75
- # 3. Disable OSC 2 auto-rename (we use /rename instead)
82
+ # 4. Disable OSC 2 auto-rename (we use /rename instead)
76
83
  tmux set-option -t "$NEW_PANE_ID" -p allow-rename off
77
84
  sleep 10
78
85
 
79
- # 4. Set pane border title (visible in tmux, separate from /rename)
86
+ # 5. Set pane border title (visible in tmux, separate from /rename)
80
87
  tmux select-pane -t "$NEW_PANE_ID" -T "${ROLE}-${NEW_PANE_ID}"
81
88
  sleep 10
82
89
 
83
- # 5. Rebalance layout with master awareness
90
+ # 6. Rebalance layout with master awareness
84
91
  tmux select-pane -t "$MASTER_PANE"
85
92
  sleep 10
86
93
  tmux select-layout main-vertical
@@ -204,9 +211,11 @@ else
204
211
  fi
205
212
  ```
206
213
 
207
- ### 6. `tmux_register_agent` — Agent startup: find session, register, set identity
214
+ ### 6. `tmux_register_agent` — Agent startup: find session, register
215
+
216
+ Spawned agents do NOT self-invoke `/color` or `/rename` — the spawner sends those via `tmux send-keys` before handing off the task. This template handles session registration only.
208
217
 
209
- Every agent — including the master/coordinator conversation runs this on startup BEFORE doing any work. The master conversation always runs `/color blue` + `/rename master-agent` first.
218
+ The master/coordinator conversation is the exception: it runs `/color blue` and `/rename master-agent` manually as its first two actions since there is no spawner above it.
210
219
 
211
220
  ```bash
212
221
  # Inputs: ROLE, SESSION_FILE (passed in spawn context)
@@ -217,11 +226,6 @@ SESSION_NAME=$(tmux display-message -p "#{session_name}")
217
226
  WINDOW_ID=$(tmux display-message -p "#{window_id}")
218
227
  PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")
219
228
 
220
- # 2. Set own identity via Claude Code commands
221
- # (These are sent as slash commands in the Claude conversation, not bash)
222
- # /color <role_color>
223
- # /rename <role>-agent
224
-
225
229
  # 3. Find session file
226
230
  if [ -n "$BMAD_SESSION_ID" ]; then
227
231
  SESSION_FILE="$PROJECT_ROOT/_bmad-output/sessions/$BMAD_SESSION_ID/agent-sessions.md"
@@ -349,12 +353,100 @@ sleep 10
349
353
 
350
354
  ---
351
355
 
356
+ ## Verification & Retry Protocol
357
+
358
+ Every tmux operation must be verified after execution. Never assume a command worked.
359
+
360
+ ### Verifying `/color` and `/rename` applied
361
+
362
+ After the spawner sends identity commands, verify the pane is alive and responsive:
363
+
364
+ ```bash
365
+ # After sending /color and /rename, verify pane is still active (not crashed)
366
+ sleep 10
367
+ PANE_ALIVE=$(tmux list-panes -a -F "#{pane_id}" | grep -Fx "$NEW_PANE_ID")
368
+ if [ -z "$PANE_ALIVE" ]; then
369
+ echo "ERROR: agent pane $NEW_PANE_ID died after identity commands"
370
+ exit 1
371
+ fi
372
+ # Note: /color and /rename visual effects are immediate in Claude Code.
373
+ # If the pane is alive, the commands were received.
374
+ ```
375
+
376
+ ### Verifying message delivery
377
+
378
+ Always capture the pane buffer after sending a message and grep for the key token:
379
+
380
+ ```bash
381
+ tmux_verify_delivery() {
382
+ local PANE="$1"
383
+ local TOKEN="$2" # unique substring from the message
384
+ local RETRIES=3
385
+
386
+ for i in $(seq 1 $RETRIES); do
387
+ sleep 10
388
+ FOUND=$(tmux capture-pane -t "$PANE" -p -S - | grep -F "$TOKEN")
389
+ if [ -n "$FOUND" ]; then
390
+ echo "OK: message confirmed in pane $PANE (attempt $i)"
391
+ return 0
392
+ fi
393
+ if [ $i -lt $RETRIES ]; then
394
+ echo "WARN: '$TOKEN' not found in pane $PANE, retrying ($i/$RETRIES)..."
395
+ fi
396
+ done
397
+
398
+ echo "ERROR: message '$TOKEN' never confirmed in pane $PANE after $RETRIES attempts"
399
+ return 1
400
+ }
401
+
402
+ # Usage after sending a message:
403
+ tmux send-keys -t "$TARGET_PANE" -l "$MESSAGE"
404
+ tmux send-keys -t "$TARGET_PANE" Enter
405
+ tmux_verify_delivery "$TARGET_PANE" "TASK-001" # use a unique token from the message
406
+ ```
407
+
408
+ ### Verifying agent spawned and initialized
409
+
410
+ After splitting, confirm the pane exists and Claude has started (prompt visible):
411
+
412
+ ```bash
413
+ # Wait for Claude prompt to appear in new pane (up to 30s)
414
+ READY=0
415
+ for i in 1 2 3; do
416
+ sleep 10
417
+ PROMPT=$(tmux capture-pane -t "$NEW_PANE_ID" -p -S - | grep -c "❯\|>\|Claude\|Human")
418
+ if [ "$PROMPT" -gt 0 ]; then
419
+ READY=1
420
+ break
421
+ fi
422
+ echo "Waiting for agent to initialize (attempt $i)..."
423
+ done
424
+ if [ "$READY" -eq 0 ]; then
425
+ echo "ERROR: agent pane $NEW_PANE_ID did not show prompt after 30s"
426
+ exit 1
427
+ fi
428
+ ```
429
+
430
+ ### Retry rules
431
+
432
+ | Operation | Verify by | Max retries | On failure |
433
+ |---|---|---|---|
434
+ | Message send | grep token in pane buffer | 3 | Log error, write to session file |
435
+ | `/color` / `/rename` | pane still alive | 1 | Re-send both commands |
436
+ | Pane spawn | pane ID in list + prompt visible | 3 | Kill and re-spawn |
437
+ | Layout rebalance | `tmux list-panes` shows expected count | 1 | Re-run `select-layout` |
438
+
439
+ ---
440
+
352
441
  ## Common Mistakes (Avoid These)
353
442
 
354
443
  1. **No `Enter` on send-keys** — message typed but never submitted
355
444
  2. **No sleep between tmux commands** — race conditions, stale pane lists
356
- 3. **Using OSC 2 / `select-pane -T` for naming** — Claude Code overwrites these
357
- 4. **Killing pane without `/exit` first** — leaves partial writes, git locks
358
- 5. **Using `tiled` layout instead of `main-vertical`/`main-horizontal`** breaks master position
359
- 6. **Reading pane titles for routing**unreliable; use session file pane IDs
360
- 7. **Spawning without `--dangerously-skip-permissions`**agent halts on every tool use
445
+ 3. **Combining `/color` and `/rename` in one send-keys call** — only the first command runs; send each as a separate call with `sleep 10` between
446
+ 4. **Using OSC 2 / `select-pane -T` for naming** — Claude Code overwrites these
447
+ 5. **Killing pane without `/exit` first** leaves partial writes, git locks
448
+ 6. **Using `tiled` layout instead of `main-vertical`/`main-horizontal`** breaks master position
449
+ 7. **Reading pane titles for routing** unreliable; use session file pane IDs
450
+ 8. **Spawning without `--dangerously-skip-permissions`** — agent halts on every tool use
451
+ 9. **No `-l` flag on message content** — `|` and `:` get interpreted as key sequences, message is garbled
452
+ 10. **Agent self-invoking `/color`+`/rename`** — unreliable; spawner sends these via `tmux send-keys` after the agent starts