maestro-flow 0.3.4 → 0.3.6

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.
Files changed (105) hide show
  1. package/.claude/commands/maestro-brainstorm.md +10 -1
  2. package/.claude/commands/maestro-milestone-audit.md +1 -1
  3. package/.claude/commands/maestro-milestone-complete.md +2 -1
  4. package/.claude/commands/maestro-milestone-release.md +96 -0
  5. package/.claude/commands/maestro-phase-add.md +9 -1
  6. package/.claude/commands/maestro-phase-transition.md +9 -1
  7. package/.claude/commands/maestro.md +6 -0
  8. package/.claude/commands/manage-codebase-rebuild.md +76 -50
  9. package/.claude/commands/manage-codebase-refresh.md +9 -1
  10. package/.claude/commands/quality-refactor.md +1 -1
  11. package/.claude/commands/quality-sync.md +9 -1
  12. package/.claude/commands/spec-setup.md +1 -1
  13. package/.codex/skills/maestro-coordinate/SKILL.md +20 -6
  14. package/.codex/skills/maestro-init/SKILL.md +167 -167
  15. package/.codex/skills/maestro-phase-add/SKILL.md +154 -154
  16. package/.codex/skills/maestro-phase-transition/SKILL.md +173 -173
  17. package/.codex/skills/maestro-verify/SKILL.md +566 -566
  18. package/.codex/skills/manage-codebase-rebuild/SKILL.md +5 -5
  19. package/.codex/skills/manage-codebase-refresh/SKILL.md +5 -5
  20. package/.codex/skills/manage-issue/SKILL.md +7 -7
  21. package/.codex/skills/manage-issue-analyze/SKILL.md +8 -8
  22. package/.codex/skills/manage-issue-discover/SKILL.md +503 -503
  23. package/.codex/skills/manage-issue-execute/SKILL.md +9 -9
  24. package/.codex/skills/manage-issue-plan/SKILL.md +8 -8
  25. package/.codex/skills/manage-learn/SKILL.md +7 -7
  26. package/.codex/skills/manage-memory/SKILL.md +72 -72
  27. package/.codex/skills/manage-memory-capture/SKILL.md +86 -86
  28. package/.codex/skills/manage-status/SKILL.md +2 -2
  29. package/.codex/skills/quality-business-test/SKILL.md +8 -8
  30. package/.codex/skills/quality-debug/SKILL.md +5 -5
  31. package/.codex/skills/quality-integration-test/SKILL.md +544 -544
  32. package/.codex/skills/quality-refactor/SKILL.md +6 -6
  33. package/.codex/skills/quality-retrospective/SKILL.md +13 -13
  34. package/.codex/skills/quality-review/SKILL.md +408 -408
  35. package/.codex/skills/quality-sync/SKILL.md +6 -6
  36. package/.codex/skills/quality-test/SKILL.md +5 -5
  37. package/.codex/skills/quality-test-gen/SKILL.md +447 -447
  38. package/.codex/skills/spec-add/SKILL.md +5 -5
  39. package/.codex/skills/spec-load/SKILL.md +5 -5
  40. package/.codex/skills/spec-map/SKILL.md +5 -5
  41. package/.codex/skills/spec-setup/SKILL.md +2 -2
  42. package/.codex/skills/team-coordinate/SKILL.md +1 -1
  43. package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +19 -10
  44. package/.codex/skills/team-coordinate/roles/coordinator/role.md +2 -2
  45. package/.codex/skills/team-executor/SKILL.md +1 -1
  46. package/.codex/skills/team-executor/roles/executor/commands/monitor.md +20 -9
  47. package/.codex/skills/team-lifecycle-v4/SKILL.md +2 -2
  48. package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +31 -12
  49. package/.codex/skills/team-lifecycle-v4/roles/coordinator/role.md +1 -1
  50. package/.codex/skills/team-quality-assurance/SKILL.md +1 -1
  51. package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +20 -9
  52. package/.codex/skills/team-quality-assurance/roles/coordinator/role.md +1 -1
  53. package/.codex/skills/team-review/SKILL.md +1 -1
  54. package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +20 -9
  55. package/.codex/skills/team-review/roles/coordinator/role.md +1 -1
  56. package/.codex/skills/team-tech-debt/SKILL.md +1 -1
  57. package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +20 -9
  58. package/.codex/skills/team-tech-debt/roles/coordinator/role.md +1 -1
  59. package/.codex/skills/team-testing/SKILL.md +2 -2
  60. package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +20 -9
  61. package/.codex/skills/team-testing/roles/coordinator/role.md +1 -1
  62. package/chains/singles/spec-map.json +2 -2
  63. package/dashboard/dist-server/dashboard/src/server/agents/codex-app-server-adapter.d.ts +4 -0
  64. package/dashboard/dist-server/dashboard/src/server/agents/codex-app-server-adapter.js +47 -1
  65. package/dashboard/dist-server/dashboard/src/server/agents/codex-app-server-adapter.js.map +1 -1
  66. package/dashboard/dist-server/src/commands/delegate.d.ts +23 -0
  67. package/dashboard/dist-server/src/commands/delegate.js +91 -55
  68. package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
  69. package/dist/src/brainstorm-visualize/frame.d.ts +8 -0
  70. package/dist/src/brainstorm-visualize/frame.d.ts.map +1 -0
  71. package/dist/src/brainstorm-visualize/frame.js +655 -0
  72. package/dist/src/brainstorm-visualize/frame.js.map +1 -0
  73. package/dist/src/brainstorm-visualize/server.d.ts +2 -0
  74. package/dist/src/brainstorm-visualize/server.d.ts.map +1 -0
  75. package/dist/src/brainstorm-visualize/server.js +180 -0
  76. package/dist/src/brainstorm-visualize/server.js.map +1 -0
  77. package/dist/src/cli.js +11 -1
  78. package/dist/src/cli.js.map +1 -1
  79. package/dist/src/commands/brainstorm-visualize.d.ts +3 -0
  80. package/dist/src/commands/brainstorm-visualize.d.ts.map +1 -0
  81. package/dist/src/commands/brainstorm-visualize.js +337 -0
  82. package/dist/src/commands/brainstorm-visualize.js.map +1 -0
  83. package/dist/src/commands/core-memory.d.ts +3 -0
  84. package/dist/src/commands/core-memory.d.ts.map +1 -0
  85. package/dist/src/commands/core-memory.js +101 -0
  86. package/dist/src/commands/core-memory.js.map +1 -0
  87. package/dist/src/commands/delegate.d.ts +23 -0
  88. package/dist/src/commands/delegate.d.ts.map +1 -1
  89. package/dist/src/commands/delegate.js +91 -55
  90. package/dist/src/commands/delegate.js.map +1 -1
  91. package/dist/src/commands/install-backend.d.ts.map +1 -1
  92. package/dist/src/commands/install-backend.js +5 -2
  93. package/dist/src/commands/install-backend.js.map +1 -1
  94. package/dist/src/mcp/delegate-channel-relay.d.ts.map +1 -1
  95. package/dist/src/mcp/delegate-channel-relay.js +6 -0
  96. package/dist/src/mcp/delegate-channel-relay.js.map +1 -1
  97. package/dist/src/mcp/server.d.ts.map +1 -1
  98. package/dist/src/mcp/server.js +28 -1
  99. package/dist/src/mcp/server.js.map +1 -1
  100. package/dist/src/tools/index.d.ts +1 -6
  101. package/dist/src/tools/index.d.ts.map +1 -1
  102. package/dist/src/tools/index.js +1 -460
  103. package/dist/src/tools/index.js.map +1 -1
  104. package/package.json +2 -1
  105. package/.claude/commands/spec-map.md +0 -82
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: maestro-spec-add
2
+ name: spec-add
3
3
  description: Add a spec entry (bug, pattern, decision, or rule) to the appropriate specs file
4
4
  argument-hint: "<type> <content>"
5
5
  allowed-tools: Read, Write, Bash, Glob, Grep
@@ -10,10 +10,10 @@ allowed-tools: Read, Write, Bash, Glob, Grep
10
10
  ## Usage
11
11
 
12
12
  ```bash
13
- $maestro-spec-add "pattern Always use named exports for utility functions"
14
- $maestro-spec-add "bug Off-by-one in pagination when page=0"
15
- $maestro-spec-add "decision Use Zod for runtime validation over io-ts"
16
- $maestro-spec-add "rule All API endpoints must return structured error objects"
13
+ $spec-add "pattern Always use named exports for utility functions"
14
+ $spec-add "bug Off-by-one in pagination when page=0"
15
+ $spec-add "decision Use Zod for runtime validation over io-ts"
16
+ $spec-add "rule All API endpoints must return structured error objects"
17
17
  ```
18
18
 
19
19
  **Arguments**: `<type> <content>` where type is one of: bug, pattern, decision, rule, debug, test, review, validation.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: maestro-spec-load
2
+ name: spec-load
3
3
  description: Load relevant specs for current context, optionally filtered by category or keyword
4
4
  argument-hint: "[--category <type>] [keyword]"
5
5
  allowed-tools: Read, Bash, Glob, Grep
@@ -10,10 +10,10 @@ allowed-tools: Read, Bash, Glob, Grep
10
10
  ## Usage
11
11
 
12
12
  ```bash
13
- $maestro-spec-load
14
- $maestro-spec-load "--category execution"
15
- $maestro-spec-load "authentication"
16
- $maestro-spec-load "--category debug error handling"
13
+ $spec-load
14
+ $spec-load "--category execution"
15
+ $spec-load "authentication"
16
+ $spec-load "--category debug error handling"
17
17
  ```
18
18
 
19
19
  **Flags**: `--category <type>` filters by spec category. Optional keyword searches within loaded files.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: maestro-spec-map
2
+ name: spec-map
3
3
  description: Analyze codebase with 4 parallel mapper agents via CSV wave pipeline. Produces .workflow/codebase/ documents for tech-stack, architecture, features, and cross-cutting concerns.
4
4
  argument-hint: "[-y|--yes] [-c|--concurrency 4] [--continue] \"[focus area]\""
5
5
  allowed-tools: spawn_agents_on_csv, Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
@@ -14,10 +14,10 @@ When `--yes` or `-y`: Auto-confirm mapper assignment, skip validation.
14
14
  ## Usage
15
15
 
16
16
  ```bash
17
- $maestro-spec-map ""
18
- $maestro-spec-map "auth"
19
- $maestro-spec-map -c 4 "api layer"
20
- $maestro-spec-map --continue "map-auth-20260318"
17
+ $spec-map ""
18
+ $spec-map "auth"
19
+ $spec-map -c 4 "api layer"
20
+ $spec-map --continue "map-auth-20260318"
21
21
  ```
22
22
 
23
23
  **Flags**:
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: maestro-spec-setup
2
+ name: spec-setup
3
3
  description: Initialize project specs by scanning codebase for conventions and tech stack
4
4
  argument-hint: ""
5
5
  allowed-tools: Read, Write, Bash, Glob, Grep
@@ -10,7 +10,7 @@ allowed-tools: Read, Write, Bash, Glob, Grep
10
10
  ## Usage
11
11
 
12
12
  ```bash
13
- $maestro-spec-setup
13
+ $spec-setup
14
14
  ```
15
15
 
16
16
  No arguments. Scans the codebase and generates spec files in `.workflow/specs/`.
@@ -160,7 +160,7 @@ pipeline_phase: <pipeline-phase>
160
160
  })
161
161
  ```
162
162
 
163
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target: <name> })` each worker.
163
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target: <name> })` each worker.
164
164
 
165
165
  **Inner Loop roles** (role has 2+ serial same-prefix tasks): Set `inner_loop: true`. The team-worker agent handles the loop internally.
166
166
 
@@ -226,7 +226,7 @@ Report blockers immediately via team_msg type="blocker".
226
226
  Report completion via team_msg type="task_complete" after report_agent_job_result.`
227
227
  })
228
228
  // Collect results — use task_name for stable targeting (v4):
229
- const result = wait_agent({ timeout_ms: 900000 })
229
+ const result = wait_agent({ timeout_ms: 1800000 }) // 30 min
230
230
 
231
231
  // Drain progress from message bus (before processing results)
232
232
  const progressMsgs = mcp__maestro-tools__team_msg({
@@ -237,15 +237,24 @@ for (const msg of (progressMsgs.result?.messages || [])) {
237
237
  }
238
238
 
239
239
  if (result.timed_out) {
240
- // Use progress trace for timeout forensics
241
- const lastProgress = (progressMsgs.result?.messages || [])
242
- .filter(m => m.data?.task_id === taskId).pop()
243
- state.tasks[taskId].status = 'timed_out'
244
- state.tasks[taskId].error = lastProgress
245
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
246
- : 'Timed out with no progress reported'
247
- close_agent({ target: taskId })
248
- // Report timeout, STOP — let user decide retry
240
+ // Status probe before closing
241
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
242
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
243
+ if (status.timed_out) {
244
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
245
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
246
+ if (forced.timed_out) {
247
+ const lastProgress = (progressMsgs.result?.messages || [])
248
+ .filter(m => m.data?.task_id === taskId).pop()
249
+ state.tasks[taskId].status = 'timed_out'
250
+ state.tasks[taskId].error = lastProgress
251
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
252
+ : 'Timed out with no progress reported'
253
+ close_agent({ target: taskId })
254
+ }
255
+ // else: forced output received, process result
256
+ }
257
+ // else: status received, continue processing
249
258
  } else {
250
259
  // Process result, update tasks.json
251
260
  close_agent({ target: taskId }) // Use task_name, not agentId
@@ -31,7 +31,7 @@ OK: Write(".workflow/.team/TC-xxx/tasks.json", ...) — task management
31
31
  OK: Read("roles/coordinator/commands/analyze-task.md") — own instructions
32
32
  OK: Read("specs/role-spec-template.md") — generating role-specs
33
33
  OK: spawn_agent({ agent_type: "team_worker", ... }) — delegation
34
- OK: wait_agent({ timeout_ms: 900000 }) — monitoring
34
+ OK: wait_agent({ timeout_ms: 1800000 }) — monitoring (30 min)
35
35
  ```
36
36
 
37
37
  **Self-check gate**: After Phase 1 analysis, before ANY other action, ask yourself:
@@ -380,7 +380,7 @@ Delegate to `@commands/dispatch.md` which creates the full task chain:
380
380
 
381
381
  ### Message Semantics
382
382
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
383
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
383
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
384
384
 
385
385
  ### Agent Lifecycle Management
386
386
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -132,7 +132,7 @@ pipeline_phase: <pipeline-phase>
132
132
  })
133
133
  ```
134
134
 
135
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target: <name> })` each worker.
135
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target: <name> })` each worker.
136
136
 
137
137
  ---
138
138
 
@@ -189,7 +189,7 @@ After spawning all ready tasks:
189
189
  const agentIds = Object.values(state.active_agents)
190
190
  .filter(a => !a.resident)
191
191
  .map(a => a.agentId)
192
- const waitResult = wait_agent({ timeout_ms: 900000 })
192
+ const waitResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
193
193
 
194
194
  // Drain progress from message bus
195
195
  const progressMsgs = mcp__maestro-tools__team_msg({
@@ -202,14 +202,25 @@ for (const msg of (progressMsgs.result?.messages || [])) {
202
202
  if (waitResult.timed_out) {
203
203
  for (const [taskId, agent] of Object.entries(state.active_agents)) {
204
204
  if (agent.resident) continue
205
- const lastProgress = (progressMsgs.result?.messages || [])
206
- .filter(m => m.data?.task_id === taskId).pop()
207
- state.tasks[taskId].status = 'timed_out'
208
- state.tasks[taskId].error = lastProgress
209
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
210
- : 'Timed out with no progress reported'
211
- close_agent({ target: agent.agentId })
212
- delete state.active_agents[taskId]
205
+ // Status probe before closing
206
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
207
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
208
+ if (status.timed_out) {
209
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
210
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
211
+ if (forced.timed_out) {
212
+ const lastProgress = (progressMsgs.result?.messages || [])
213
+ .filter(m => m.data?.task_id === taskId).pop()
214
+ state.tasks[taskId].status = 'timed_out'
215
+ state.tasks[taskId].error = lastProgress
216
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
217
+ : 'Timed out with no progress reported'
218
+ close_agent({ target: agent.agentId })
219
+ delete state.active_agents[taskId]
220
+ }
221
+ // else: forced output received, process result
222
+ }
223
+ // else: status received, continue processing
213
224
  }
214
225
  } else {
215
226
  // Collect results from discoveries/{task_id}.json
@@ -153,7 +153,7 @@ task_id: <CHECKPOINT-NNN>
153
153
  scope: [<upstream-task-ids>]
154
154
  pipeline_progress: <done>/<total> tasks completed`
155
155
  })
156
- wait_agent({ timeout_ms: 600000 })
156
+ wait_agent({ timeout_ms: 1800000 }) // 30 min
157
157
  ```
158
158
 
159
159
  ### Shutdown (pipeline complete)
@@ -196,7 +196,7 @@ For each wave in the pipeline:
196
196
  3. **Build upstream context** -- For each task, gather findings from `context_from` tasks via tasks.json and `discoveries/{id}.json`
197
197
  4. **Separate task types** -- Split into regular tasks and CHECKPOINT tasks
198
198
  5. **Spawn regular tasks** -- For each regular task, call `spawn_agent({ agent_type: "team_worker", message: "..." })`, collect agent IDs
199
- 6. **Wait** -- `wait_agent({ timeout_ms: 900000 })`
199
+ 6. **Wait** -- `wait_agent({ timeout_ms: 1800000 })` (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents.
200
200
  7. **Collect results** -- Read `discoveries/{task_id}.json` for each agent, update tasks.json status/findings/error, then `close_agent({ target })` each worker
201
201
  8. **Execute checkpoints** -- For each CHECKPOINT task, `followup_task` to supervisor, `wait_agent`, read checkpoint report from `artifacts/`, parse verdict
202
202
  9. **Handle block** -- If verdict is `block`, prompt user via `request_user_input` with options: Override / Revise upstream / Abort
@@ -151,7 +151,7 @@ After spawning all ready regular tasks:
151
151
  const taskNames = Object.entries(state.active_agents)
152
152
  .filter(([_, a]) => !a.resident)
153
153
  .map(([taskId]) => taskId)
154
- const waitResult = wait_agent({ timeout_ms: 900000 })
154
+ const waitResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
155
155
  // 4a) Drain progress from message bus (before collecting discoveries)
156
156
  const progressMsgs = mcp__maestro-tools__team_msg({
157
157
  operation: "list", session_id: sessionId, type: "progress", last: 100
@@ -173,15 +173,26 @@ if (blockerMsgs.result?.messages?.length > 0) {
173
173
  if (waitResult.timed_out) {
174
174
  // Use progress trace to understand where workers got stuck
175
175
  for (const taskId of taskNames) {
176
- const lastProgress = (progressMsgs.result?.messages || [])
177
- .filter(m => m.data?.task_id === taskId)
178
- .pop()
179
- state.tasks[taskId].status = 'timed_out'
180
- state.tasks[taskId].error = lastProgress
181
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
182
- : 'Timed out with no progress reported'
183
- close_agent({ target: taskId })
184
- delete state.active_agents[taskId]
176
+ // Status probe before closing
177
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
178
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
179
+ if (status.timed_out) {
180
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
181
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
182
+ if (forced.timed_out) {
183
+ const lastProgress = (progressMsgs.result?.messages || [])
184
+ .filter(m => m.data?.task_id === taskId)
185
+ .pop()
186
+ state.tasks[taskId].status = 'timed_out'
187
+ state.tasks[taskId].error = lastProgress
188
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
189
+ : 'Timed out with no progress reported'
190
+ close_agent({ target: taskId })
191
+ delete state.active_agents[taskId]
192
+ }
193
+ // else: forced output received, process result
194
+ }
195
+ // else: status received, continue processing
185
196
  }
186
197
  } else {
187
198
  // 5) Collect results from discoveries/{task_id}.json
@@ -234,8 +245,16 @@ For each ready CHECKPOINT task:
234
245
  scope: [${task.deps.join(', ')}]
235
246
  pipeline_progress: ${completedCount}/${totalCount} tasks completed`
236
247
  })
237
- const cpResult = wait_agent({ timeout_ms: 600000 })
238
- if (cpResult.timed_out) { /* mark checkpoint timed_out, close supervisor, STOP */ }
248
+ const cpResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
249
+ if (cpResult.timed_out) {
250
+ followup_task({ target: supervisorId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
251
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
252
+ if (status.timed_out) {
253
+ followup_task({ target: supervisorId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
254
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
255
+ if (forced.timed_out) { /* mark checkpoint timed_out, close supervisor, STOP */ }
256
+ }
257
+ }
239
258
  ```
240
259
  4. Read checkpoint report from artifacts/${task.id}-report.md
241
260
  5. Parse verdict (pass / warn / block):
@@ -170,7 +170,7 @@ Delegate to @commands/monitor.md#handleSpawnNext:
170
170
 
171
171
  ### Message Semantics
172
172
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
173
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
173
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
174
174
 
175
175
  ### Agent Lifecycle Management
176
176
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -110,7 +110,7 @@ pipeline_phase: <pipeline-phase>
110
110
  })
111
111
  ```
112
112
 
113
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target })` each worker.
113
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target })` each worker.
114
114
 
115
115
 
116
116
  ### Model Selection Guide
@@ -188,7 +188,7 @@ Report completion via team_msg type="task_complete" after report_agent_job_resul
188
188
 
189
189
  f. Add to active_workers
190
190
  5. Update session, output summary, STOP
191
- 6. Use `wait_agent({ timeout_ms: 900000 })` to wait for callbacks. Workers use `report_agent_job_result()` to send results back.
191
+ 6. Use `wait_agent({ timeout_ms: 1800000 })` to wait for callbacks (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Workers use `report_agent_job_result()` to send results back.
192
192
 
193
193
  ### Post-Wait Processing
194
194
 
@@ -205,14 +205,25 @@ for (const msg of (progressMsgs.result?.messages || [])) {
205
205
 
206
206
  if (waitResult.timed_out) {
207
207
  for (const taskId of Object.keys(state.active_workers)) {
208
- const lastProgress = (progressMsgs.result?.messages || [])
209
- .filter(m => m.data?.task_id === taskId).pop()
210
- state.tasks[taskId].status = 'timed_out'
211
- state.tasks[taskId].error = lastProgress
212
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
213
- : 'Timed out with no progress reported'
214
- close_agent({ target: taskId })
215
- delete state.active_workers[taskId]
208
+ // Status probe before closing
209
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
210
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
211
+ if (status.timed_out) {
212
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
213
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
214
+ if (forced.timed_out) {
215
+ const lastProgress = (progressMsgs.result?.messages || [])
216
+ .filter(m => m.data?.task_id === taskId).pop()
217
+ state.tasks[taskId].status = 'timed_out'
218
+ state.tasks[taskId].error = lastProgress
219
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
220
+ : 'Timed out with no progress reported'
221
+ close_agent({ target: taskId })
222
+ delete state.active_workers[taskId]
223
+ }
224
+ // else: forced output received, process result
225
+ }
226
+ // else: status received, continue processing
216
227
  }
217
228
  } else {
218
229
  // Collect results, mark completed, close agents
@@ -157,7 +157,7 @@ Delegate to @commands/monitor.md#handleSpawnNext:
157
157
 
158
158
  ### Message Semantics
159
159
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
160
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
160
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
161
161
 
162
162
  ### Agent Lifecycle Management
163
163
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -108,7 +108,7 @@ pipeline_phase: <pipeline-phase>
108
108
  })
109
109
  ```
110
110
 
111
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target })` each worker.
111
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target })` each worker.
112
112
 
113
113
 
114
114
  ### Model Selection Guide
@@ -144,7 +144,7 @@ Report completion via team_msg type="task_complete" after report_agent_job_resul
144
144
  state.active_agents[taskId] = { agentId, role, started_at: now }
145
145
 
146
146
  // 4) Wait for completion — use task_name for stable targeting (v4)
147
- const waitResult = wait_agent({ timeout_ms: 900000 })
147
+ const waitResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
148
148
 
149
149
  // Drain progress from message bus
150
150
  const progressMsgs = mcp__maestro-tools__team_msg({
@@ -155,14 +155,25 @@ for (const msg of (progressMsgs.result?.messages || [])) {
155
155
  }
156
156
 
157
157
  if (waitResult.timed_out) {
158
- const lastProgress = (progressMsgs.result?.messages || [])
159
- .filter(m => m.data?.task_id === taskId).pop()
160
- state.tasks[taskId].status = 'timed_out'
161
- state.tasks[taskId].error = lastProgress
162
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
163
- : 'Timed out with no progress reported'
164
- close_agent({ target: taskId })
165
- delete state.active_agents[taskId]
158
+ // Status probe before closing
159
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
160
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
161
+ if (status.timed_out) {
162
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
163
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
164
+ if (forced.timed_out) {
165
+ const lastProgress = (progressMsgs.result?.messages || [])
166
+ .filter(m => m.data?.task_id === taskId).pop()
167
+ state.tasks[taskId].status = 'timed_out'
168
+ state.tasks[taskId].error = lastProgress
169
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
170
+ : 'Timed out with no progress reported'
171
+ close_agent({ target: taskId })
172
+ delete state.active_agents[taskId]
173
+ }
174
+ // else: forced output received, process result
175
+ }
176
+ // else: status received, continue processing
166
177
  } else {
167
178
  // 5) Collect results
168
179
  state.tasks[taskId].status = 'completed'
@@ -157,7 +157,7 @@ Delegate to @commands/monitor.md#handleSpawnNext:
157
157
 
158
158
  ### Message Semantics
159
159
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
160
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
160
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
161
161
 
162
162
  ### Agent Lifecycle Management
163
163
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -110,7 +110,7 @@ pipeline_phase: <pipeline-phase>
110
110
  })
111
111
  ```
112
112
 
113
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target })` each worker.
113
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target })` each worker.
114
114
 
115
115
 
116
116
  ### Model Selection Guide
@@ -150,7 +150,7 @@ After spawning all ready tasks:
150
150
  ```javascript
151
151
  // 4) Batch wait — use task_name for stable targeting (v4)
152
152
  const taskNames = Object.keys(state.active_agents)
153
- const waitResult = wait_agent({ timeout_ms: 900000 })
153
+ const waitResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
154
154
 
155
155
  // Drain progress from message bus
156
156
  const progressMsgs = mcp__maestro-tools__team_msg({
@@ -162,14 +162,25 @@ for (const msg of (progressMsgs.result?.messages || [])) {
162
162
 
163
163
  if (waitResult.timed_out) {
164
164
  for (const taskId of taskNames) {
165
- const lastProgress = (progressMsgs.result?.messages || [])
166
- .filter(m => m.data?.task_id === taskId).pop()
167
- state.tasks[taskId].status = 'timed_out'
168
- state.tasks[taskId].error = lastProgress
169
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
170
- : 'Timed out with no progress reported'
171
- close_agent({ target: taskId })
172
- delete state.active_agents[taskId]
165
+ // Status probe before closing
166
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
167
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
168
+ if (status.timed_out) {
169
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
170
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
171
+ if (forced.timed_out) {
172
+ const lastProgress = (progressMsgs.result?.messages || [])
173
+ .filter(m => m.data?.task_id === taskId).pop()
174
+ state.tasks[taskId].status = 'timed_out'
175
+ state.tasks[taskId].error = lastProgress
176
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
177
+ : 'Timed out with no progress reported'
178
+ close_agent({ target: taskId })
179
+ delete state.active_agents[taskId]
180
+ }
181
+ // else: forced output received, process result
182
+ }
183
+ // else: status received, continue processing
173
184
  }
174
185
  } else {
175
186
  // 5) Collect results
@@ -153,7 +153,7 @@ Delegate to @commands/monitor.md#handleSpawnNext:
153
153
 
154
154
  ### Message Semantics
155
155
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
156
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
156
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
157
157
 
158
158
  ### Agent Lifecycle Management
159
159
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -109,7 +109,7 @@ pipeline_phase: <pipeline-phase>
109
109
  })
110
110
  ```
111
111
 
112
- After spawning, use `wait_agent({ timeout_ms: 900000 })` to collect results, then `close_agent({ target })` each worker.
112
+ After spawning, use `wait_agent({ timeout_ms: 1800000 })` to collect results (30 min). If `result.timed_out`, send STATUS_CHECK via followup_task (wait 3 min), then FINALIZE with interrupt (wait 3 min), then mark timed_out and close agents. Use `close_agent({ target })` each worker.
113
113
 
114
114
 
115
115
  ### Model Selection Guide
@@ -162,7 +162,7 @@ const genNames = ["TESTGEN-001", "TESTGEN-002"]
162
162
  for (const name of genNames) {
163
163
  spawn_agent({ agent_type: "team_worker", task_name: name, ... })
164
164
  }
165
- wait_agent({ timeout_ms: 900000 })
165
+ wait_agent({ timeout_ms: 1800000 }) // 30 min
166
166
  ```
167
167
 
168
168
  ### GC Loop Coordination
@@ -172,7 +172,7 @@ After spawning all ready tasks:
172
172
  ```javascript
173
173
  // 4) Batch wait — use task_name for stable targeting (v4)
174
174
  const taskNames = Object.keys(state.active_agents)
175
- const waitResult = wait_agent({ timeout_ms: 900000 })
175
+ const waitResult = wait_agent({ timeout_ms: 1800000 }) // 30 min
176
176
 
177
177
  // Drain progress from message bus
178
178
  const progressMsgs = mcp__maestro-tools__team_msg({
@@ -184,14 +184,25 @@ for (const msg of (progressMsgs.result?.messages || [])) {
184
184
 
185
185
  if (waitResult.timed_out) {
186
186
  for (const taskId of taskNames) {
187
- const lastProgress = (progressMsgs.result?.messages || [])
188
- .filter(m => m.data?.task_id === taskId).pop()
189
- state.tasks[taskId].status = 'timed_out'
190
- state.tasks[taskId].error = lastProgress
191
- ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
192
- : 'Timed out with no progress reported'
193
- close_agent({ target: taskId })
194
- delete state.active_agents[taskId]
187
+ // Status probe before closing
188
+ followup_task({ target: taskId, message: "STATUS_CHECK: Report current progress, findings so far, and estimated remaining work." })
189
+ const status = wait_agent({ timeout_ms: 180000 }) // 3 min
190
+ if (status.timed_out) {
191
+ followup_task({ target: taskId, message: "FINALIZE: Output all current findings immediately. Time limit reached.", interrupt: true })
192
+ const forced = wait_agent({ timeout_ms: 180000 }) // 3 min
193
+ if (forced.timed_out) {
194
+ const lastProgress = (progressMsgs.result?.messages || [])
195
+ .filter(m => m.data?.task_id === taskId).pop()
196
+ state.tasks[taskId].status = 'timed_out'
197
+ state.tasks[taskId].error = lastProgress
198
+ ? `Timed out at ${lastProgress.data.phase} (${lastProgress.data.progress_pct}%)`
199
+ : 'Timed out with no progress reported'
200
+ close_agent({ target: taskId })
201
+ delete state.active_agents[taskId]
202
+ }
203
+ // else: forced output received, process result
204
+ }
205
+ // else: status received, continue processing
195
206
  }
196
207
  } else {
197
208
  // 5) Collect results
@@ -166,7 +166,7 @@ Delegate to @commands/monitor.md#handleSpawnNext:
166
166
 
167
167
  ### Message Semantics
168
168
  - **send_message**: Queue supplementary info to a running agent. Does NOT interrupt current processing. Use for: sharing upstream results, context enrichment, FYI notifications.
169
- - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output.
169
+ - **followup_task**: Assign new work and trigger processing. Use for: waking idle agents, redirecting work, requesting new output, and status probing on timeout (STATUS_CHECK / FINALIZE cascade before closing timed-out agents).
170
170
 
171
171
  ### Agent Lifecycle Management
172
172
  - **list_agents({})**: Returns all running agents. Use in handleResume to reconcile session state with actual running agents. Use in handleComplete to verify clean shutdown.
@@ -12,10 +12,10 @@
12
12
  "nodes": {
13
13
  "spec_map": {
14
14
  "type": "command",
15
- "cmd": "spec-map",
15
+ "cmd": "manage-codebase-rebuild",
16
16
  "next": "done",
17
17
  "analyze": false,
18
- "description": "Analyze codebase with parallel mapper agents to produce codebase documents"
18
+ "description": "Analyze codebase with parallel mapper agents to produce codebase documents (consolidated into manage-codebase-rebuild)"
19
19
  },
20
20
  "done": {
21
21
  "type": "terminal",
@@ -26,6 +26,10 @@ export declare class CodexAppServerAdapter extends BaseAgentAdapter {
26
26
  private handleLine;
27
27
  private handleNotification;
28
28
  private classifyItem;
29
+ /** Get the last assistant message for a process (O(1) without re-parsing JSONL). */
30
+ getLastMessage(processId: string): string;
31
+ /** Map codex item type/name to a semantic phase label. */
32
+ private inferPhase;
29
33
  private extractText;
30
34
  private setupProcessListeners;
31
35
  private cleanup;