maestro-flow 0.3.26 → 0.3.28

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.
@@ -11,6 +11,7 @@ allowed-tools:
11
11
  - Grep
12
12
  - Agent
13
13
  - AskUserQuestion
14
+ - TodoWrite
14
15
  ---
15
16
  <purpose>
16
17
  Orchestrate all maestro commands automatically based on user intent and current project state.
@@ -28,7 +29,7 @@ Executes commands sequentially with artifact propagation between steps.
28
29
 
29
30
  <deferred_reading>
30
31
  - [maestro.md](~/.maestro/workflows/maestro.md) — read at execution start (Steps 1-3: intent analysis, chain selection, session setup)
31
- - [maestro-chain-execute.md](~/.maestro/workflows/maestro-chain-execute.md) — read when dispatching chain execution (Step 4b) or resume mode (Step 1b)
32
+ - [maestro-chain-execute.md](~/.maestro/workflows/maestro-chain-execute.md) — read when dispatching chain execution (Step 4) or resume mode
32
33
  - [maestro-super.md](~/.maestro/workflows/maestro-super.md) — read when `--super` flag is active
33
34
  </deferred_reading>
34
35
 
@@ -83,12 +84,10 @@ When `-y` is active, maestro propagates auto flags to downstream commands. Only
83
84
  Commands not listed (manage-*, spec-*, milestone-*) have no auto flags and execute as-is.
84
85
 
85
86
  In auto mode, maestro also:
86
- - Skips its own clarification (Step 4)
87
- - Skips chain confirmation (Step 5d)
87
+ - Skips intent clarification (workflow Step 2d)
88
+ - Skips chain confirmation (workflow Step 3d)
88
89
  - Auto-skips on step errors (retry once, then skip and continue)
89
90
 
90
- Context cleanup hints, context window reminders, and completion report format are defined in workflow maestro.md (Steps 7a-1, 7f).
91
-
92
91
  **Super mode (`--super`):** Read `maestro-super.md` from deferred_reading, then follow it completely.
93
92
  </execution>
94
93
 
@@ -129,10 +129,24 @@ After each barrier skill completes, read its artifacts and update `state.context
129
129
  }
130
130
  ```
131
131
 
132
+ 7. **Initialize plan tracking** (dual-track: status.json + update_plan):
133
+
134
+ ```
135
+ functions.update_plan({
136
+ plan: steps.map((step, i) => ({
137
+ id: `step-${i}`,
138
+ title: `[${i + 1}/${steps.length}] ${step.skill}${barrier(step) ? ' [BARRIER]' : ''}`,
139
+ status: "open"
140
+ }))
141
+ })
142
+ ```
143
+
132
144
  **`--dry-run`**: Display chain with `[BARRIER]` markers, stop.
133
145
 
134
146
  **User confirmation** (skip if AUTO_YES): Display plan, prompt `Proceed? (yes/no)`.
135
147
 
148
+ **`--continue` plan rebuild**: When resuming, rebuild `update_plan` from status.json — completed steps → `"completed"`, current → `"in_progress"`, rest → `"open"`.
149
+
136
150
  ### Phase 2: Wave Execution Loop
137
151
 
138
152
  **While pending steps remain**, increment `waveNum` and repeat:
@@ -151,8 +165,21 @@ After each barrier skill completes, read its artifacts and update `state.context
151
165
  ```
152
166
  4. **Read results**: Update each step's `status`, `wave_n` from results CSV
153
167
  5. **Barrier check**: If wave was a barrier skill, run barrier analysis logic (read artifacts, update context)
154
- 6. **Persist**: Append wave to `state.waves[]`, write `status.json`
155
- 7. **Abort on failure**: If any result `status === 'failed'` mark remaining steps `skipped`, set `state.status = 'aborted'`, break
168
+ 6. **Dual-track persist**:
169
+ - status.json: Append wave to `state.waves[]`, update step statuses, write `status.json`
170
+ - update_plan: Sync plan items from status.json step statuses:
171
+ ```
172
+ functions.update_plan({
173
+ plan: steps.map((step, i) => ({
174
+ id: `step-${i}`,
175
+ title: `[${i + 1}/${steps.length}] ${step.skill}`,
176
+ status: step.status === 'completed' ? 'completed'
177
+ : step.status === 'pending' && i === nextPendingIndex ? 'in_progress'
178
+ : step.status
179
+ }))
180
+ })
181
+ ```
182
+ 7. **Abort on failure**: If any result `status === 'failed'` → mark remaining steps `skipped` in both status.json and update_plan, set `state.status = 'aborted'`, break
156
183
 
157
184
  ### Skill Call Assembly
158
185
 
@@ -196,6 +223,10 @@ Object with all fields required: `status` ("completed"|"failed"), `skill_call` (
196
223
 
197
224
  ### Phase 3: Completion Report
198
225
 
226
+ Finalize dual tracking:
227
+ - status.json: `state.status = 'completed'`
228
+ - update_plan: all steps → `"completed"` (skipped steps also marked completed)
229
+
199
230
  ```
200
231
  === COORDINATE COMPLETE ===
201
232
  Session: <sessionId>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maestro-flow",
3
- "version": "0.3.26",
3
+ "version": "0.3.28",
4
4
  "description": "Workflow orchestration CLI with MCP endpoint support and extensible architecture",
5
5
  "type": "module",
6
6
  "imports": {
@@ -3,10 +3,11 @@
3
3
  Upgraded version of maestro's original direct execution strategy.
4
4
  Reads session status.json, loops through steps with per-step engine selection,
5
5
  context propagation, post-step Gemini analysis, and error handling.
6
- Tracks all progress via status.json (the JSON file created during selection).
6
+ Dual-track progress: status.json (persistence + resume) and TodoWrite (UI visibility).
7
7
 
8
8
  **Prerequisites:**
9
9
  - Session directory with valid status.json (status: "running", pending steps)
10
+ - TodoWrite initialized by selection workflow (Step 3h) with `MAESTRO:{chain_name}:` prefix
10
11
  - $SESSION_PATH passed from maestro.md dispatch
11
12
 
12
13
  ## Step 1: Load Session
@@ -19,6 +20,18 @@ Set `$STEP_INDEX` = `current_step` (first pending step).
19
20
 
20
21
  Validate: `status == "running"` and at least one pending step exists.
21
22
 
23
+ **TodoWrite sync (resume mode):** If TodoWrite has no `MAESTRO:{chain_name}:` entries (e.g., fresh context after `/maestro -c`), rebuild from status.json:
24
+
25
+ ```javascript
26
+ const todos = steps.map((step, i) => ({
27
+ content: `MAESTRO:${chain_name}: [${i + 1}/${steps.length}] ${step.skill}`,
28
+ status: step.status === 'completed' ? 'completed'
29
+ : i === $STEP_INDEX ? 'in_progress'
30
+ : 'pending'
31
+ }));
32
+ TodoWrite({ todos });
33
+ ```
34
+
22
35
  Display banner:
23
36
 
24
37
  ```
@@ -41,9 +54,9 @@ context = {
41
54
  current_phase, // from status.json.context or top-level phase
42
55
  user_intent, // from status.json.context or top-level intent
43
56
  issue_id,
57
+ milestone_num,
44
58
  spec_session_id,
45
- scratch_dir,
46
- auto_mode // from status.json.auto_mode
59
+ scratch_dir
47
60
  }
48
61
  ```
49
62
 
@@ -52,10 +65,11 @@ context = {
52
65
  ```
53
66
  1. Substitute placeholders in step.args:
54
67
  {phase} → context.current_phase
55
- {description} → context.user_intent
68
+ {description} → context.user_intent (chainMap uses {description} as alias for user intent)
56
69
  {issue_id} → context.issue_id
57
70
  {spec_session_id} → context.spec_session_id
58
71
  {scratch_dir} → context.scratch_dir
72
+ {milestone_num} → context.milestone_num
59
73
 
60
74
  2. In auto_mode, append per-command flag if not already present:
61
75
  maestro-analyze / maestro-brainstorm / maestro-roadmap / maestro-ui-design → -y
@@ -72,22 +86,16 @@ For each step starting at `$STEP_INDEX`:
72
86
 
73
87
  ### 3a. Select engine & display banner
74
88
 
75
- Per-step engine selection:
89
+ Read `step.engine` from status.json (pre-computed by selection workflow Step 3e).
76
90
 
91
+ If `step.engine` is missing or null, fallback to auto selection:
77
92
  ```
78
- If exec_mode is 'cli' or 'skill' → force that engine for all steps.
79
-
80
- In 'auto' mode, select per step:
81
- CLI steps (heavy, context-isolated):
82
- maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm,
83
- maestro-roadmap, maestro-ui-design, quality-refactor
84
-
85
- Skill steps (observable, interactive, lightweight):
86
- everything else — verify, review, test, debug, milestone-*,
87
- manage-*, spec-*, quick, etc.
93
+ CLI: maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm,
94
+ maestro-roadmap, maestro-ui-design, quality-refactor
95
+ Internal: everything else (current-session Skill() call)
88
96
  ```
89
97
 
90
- Display: `[Step {N}/{total}] /{cmd} [{engine}] — {args}`
98
+ Display: `[Step {N}/{total}] /{step.skill} [{engine}] — {args}`
91
99
 
92
100
  Update status.json: step `status = "running"`, `engine`, `started_at`.
93
101
 
@@ -97,10 +105,10 @@ Context window hint:
97
105
 
98
106
  ### 3b. Execute (engine-dependent)
99
107
 
100
- **Skill engine** — invoke directly (synchronous, visible):
108
+ **Internal engine** — current-session Skill() call (synchronous, visible):
101
109
 
102
110
  ```
103
- Skill({ skill: step.cmd, args: assembledArgs })
111
+ Skill({ skill: step.skill, args: assembledArgs })
104
112
  ```
105
113
 
106
114
  **CLI engine** — template-driven, async, context-isolated:
@@ -132,19 +140,39 @@ CLI: capture `exec_id` from stderr `[MAESTRO_EXEC_ID=<id>]`.
132
140
 
133
141
  **Persist context back to status.json** after each step — write updated `context` field and `current_step`. This enables resume via `/maestro -c`.
134
142
 
135
- ### 3d. Handle result
136
-
137
- **Success:** mark step `status = "completed"`, set `completed_at` in status.json.
138
- CLI: save output to `step-{N}-output.txt` in session directory.
143
+ ### 3d. Handle result & sync dual tracking
144
+
145
+ **Success:**
146
+ 1. status.json: mark step `status = "completed"`, set `completed_at`
147
+ 2. TodoWrite: mark current step `completed`, next step `in_progress`
148
+ 3. CLI: save output to `step-{N}-output.txt` in session directory
149
+
150
+ ```javascript
151
+ // Dual-track update after each step
152
+ function updateDualTracking(stepIndex, total, chain_name, result) {
153
+ // 1. status.json — already updated in 3c
154
+ // 2. TodoWrite — sync UI
155
+ const todos = getAllTodos().map(todo => {
156
+ if (!todo.content.startsWith(`MAESTRO:${chain_name}:`)) return todo;
157
+ const num = extractStepNum(todo.content);
158
+ if (num === stepIndex + 1) return { ...todo, status: result };
159
+ if (num === stepIndex + 2 && result === 'completed') return { ...todo, status: 'in_progress' };
160
+ return todo;
161
+ });
162
+ TodoWrite({ todos });
163
+ }
164
+ ```
139
165
 
140
166
  **Failure:**
141
- - `auto_mode` retry once, then skip (mark `"skipped"`).
142
- - Interactive offer: Retry (max 2) / Skip / Abort.
143
- - Abort → **Error E003** — update status.json `status = "aborted"`, display resume hint: `/maestro -c`.
167
+ 1. status.json: mark step `"failed"` or `"skipped"`
168
+ 2. TodoWrite: mark step `completed` (skipped) or keep `in_progress` (retry)
169
+ 3. `auto_mode` retry once, then skip
170
+ 4. Interactive → offer: Retry (max 2) / Skip / Abort
171
+ 5. Abort → status.json `status = "aborted"`, TodoWrite mark remaining `pending`, display resume hint: `/maestro -c`
144
172
 
145
173
  ### 3e. Post-step analysis (CLI steps only)
146
174
 
147
- Skip if: step failed/skipped, or `engine == 'skill'`.
175
+ Skip if: step failed/skipped, or `engine == 'internal'`.
148
176
 
149
177
  Delegate to gemini (analysis mode, `--resume` if `gemini_session_id` exists) with prompt containing:
150
178
  - Step command, args, chain name, intent
@@ -181,7 +209,9 @@ On callback:
181
209
 
182
210
  ## Step 4: Completion Report
183
211
 
184
- Update status.json: `status = "completed"`.
212
+ Finalize dual tracking:
213
+ 1. status.json: `status = "completed"`
214
+ 2. TodoWrite: all steps marked `completed` (or `completed` for skipped)
185
215
 
186
216
  ```
187
217
  ============================================================
@@ -194,8 +224,8 @@ Update status.json: `status = "completed"`.
194
224
 
195
225
  Results:
196
226
  [✓] 1. maestro-plan — completed [cli] (quality: 85/100)
197
- [✓] 2. maestro-verify — completed [skill]
198
- [—] 3. quality-review — skipped [skill]
227
+ [✓] 2. maestro-verify — completed [internal]
228
+ [—] 3. quality-review — skipped [internal]
199
229
 
200
230
  CLI Avg Quality: {avgScore}/100 (based on {cliStepCount} cli steps)
201
231
 
@@ -290,8 +290,8 @@ Build context: `{ current_phase, user_intent, issue_id, spec_session_id: null, s
290
290
 
291
291
  ```
292
292
  MAESTRO-COORDINATE: {chain_name} (dry run)
293
- 1. ${step.cmd} {step.args}
294
- 2. ${step.cmd} {step.args}
293
+ 1. ${step.skill} {step.args}
294
+ 2. ${step.skill} {step.args}
295
295
 
296
296
  ```
297
297
 
@@ -310,7 +310,7 @@ Create session directory `.workflow/.maestro/maestro-{timestamp}/`.
310
310
 
311
311
  **Auto-flag injection** (when AUTO_YES): `maestro-analyze/-brainstorm/-roadmap/-ui-design` → `-y`, `maestro-plan` → `--auto`, `quality-test` → `--auto-fix`, `quality-retrospective` → `--auto-yes`.
312
312
 
313
- Initialize `state.json` with: session_id, intent, chain_name, auto_yes, context (phase, dirs, issue_id, gaps), waves[], and steps[] (each with index, cmd, args, status=pending).
313
+ Initialize `state.json` with: session_id, intent, chain_name, auto_yes, context (phase, dirs, issue_id, gaps), waves[], and steps[] (each with index, skill, args, status=pending).
314
314
 
315
315
  ---
316
316
 
@@ -7,7 +7,7 @@ Default `auto` mode selects engine based on chain complexity.
7
7
  **Prerequisites:**
8
8
  - None for initial invocation (can bootstrap)
9
9
  - `continue`/`next`: `.workflow/state.json` must exist
10
- - `-c` (resume): `.workflow/.maestro/*/status.json` must exist
10
+ - `-c` (resume): handled by command file before this workflow loads — not applicable here
11
11
 
12
12
  ## Step 1: Parse & Initialize
13
13
 
@@ -15,8 +15,8 @@ Default `auto` mode selects engine based on chain complexity.
15
15
 
16
16
  ```
17
17
  Parse $ARGUMENTS → extract flags, remainder is intent text.
18
- Flags: autoYes (-y/--yes), resumeMode (-c/--continue), dryRun (--dry-run)
19
- Valued: forcedChain (--chain X), execMode (--exec auto|cli|skill, default 'auto'), cliTool (--tool X, default 'claude')
18
+ Flags: autoYes (-y/--yes), dryRun (--dry-run)
19
+ Valued: execMode (--exec auto|cli|internal, default 'auto'), cliTool (--tool X, default 'claude')
20
20
  intent = arguments with all flags/valued options stripped, trimmed
21
21
  ```
22
22
 
@@ -51,9 +51,9 @@ Check `.workflow/state.json` existence.
51
51
  ============================================================
52
52
  MAESTRO COORDINATOR
53
53
  ============================================================
54
- Mode: {intent-based | state-based | resume}
54
+ Mode: {intent-based | state-based}
55
55
  Auto: {yes | no}
56
- Exec: {auto | cli | skill}
56
+ Exec: {auto | cli | internal}
57
57
  Input: {intent or "continue"}
58
58
  ```
59
59
 
@@ -61,16 +61,13 @@ Check `.workflow/state.json` existence.
61
61
 
62
62
  ### 2a: Fast path — forced chain or exact match
63
63
 
64
- **Forced chain (`--chain`):**
65
- - Validate against known chains (see [Chain Reference](#chain-reference))
66
- - If valid: skip intent analysis, jump to **Step 3**
67
- - If invalid: display valid chains, ask user to choose
68
-
69
64
  **Exact-match keywords:**
70
65
  ```
71
66
  Keyword → taskType (skip to Step 3):
72
67
  continue/next/go/继续/下一步 → 'state_continue'
73
- status/状态/dashboard → 'status'
68
+
69
+ Short-circuit (execute immediately, no chain):
70
+ status/状态/dashboard → Skill({ skill: "manage-status" }). **End.**
74
71
  ```
75
72
 
76
73
  ### 2b: Structured intent extraction (LLM-native)
@@ -160,7 +157,7 @@ Route priority:
160
157
  test: feature/code→test; default→test
161
158
  debug: default→debug
162
159
  refactor: default→refactor
163
- manage: issue→issue, milestone→milestone_audit, phase→milestone_close, memory→memory, doc→sync, codebase→codebase_refresh, config→spec_setup, team→team_coordinate; default→status
160
+ manage: issue→issue, milestone→milestone_audit, phase→milestone_close, memory→knowhow, doc→sync, codebase→codebase_refresh, config→spec_setup, team→team_coordinate; default→status
164
161
  transition: phase→milestone_close, milestone→milestone_complete; default→milestone_close
165
162
  continue: default→state_continue
166
163
  sync: doc→sync, codebase→codebase_refresh; default→sync
@@ -187,10 +184,9 @@ Display intent analysis: action, object, scope, issue_id, phase_ref, task_type,
187
184
  ### 3a: Map task_type → chain
188
185
 
189
186
  **Resolution order:**
190
- 1. `forcedChain` → `chainMap[forcedChain]`
191
- 2. `state_continue` `detectNextAction(projectState)` `{ chain, argsOverride? }`. Apply argsOverride before template substitution.
192
- 3. Task-type aliases named chain: `spec_generate`→`spec-driven`, `brainstorm`→`brainstorm-driven`, `issue_execute`→`issue-full`
193
- 4. `chainMap[taskType]` → direct lookup
187
+ 1. `state_continue` → `detectNextAction(projectState)` → `{ chain, argsOverride? }`. Apply argsOverride before template substitution.
188
+ 2. Task-type aliasesnamed chain: `spec_generate`→`spec-driven`, `brainstorm`→`brainstorm-driven`, `issue_execute`→`issue-full`
189
+ 3. `chainMap[taskType]`direct lookup
194
190
 
195
191
  Full `chainMap` and `detectNextAction` are in the [Reference Data](#reference-data) section.
196
192
 
@@ -228,21 +224,31 @@ When executing issue chains, replace `{issue_id}` in step args with resolved ID.
228
224
 
229
225
  **If `dryRun`:** Display chain visualization and exit.
230
226
  **If not `autoYes`:** Confirm with user — show numbered steps, offer: Execute / Execute from step N / Cancel.
227
+ If user chooses "Execute from step N": set `$START_STEP = N` (used in 3f to set `current_step`).
231
228
 
232
229
  ### 3e: Step-level engine selection
233
230
 
234
- Engine is selected **per step**, not per chain.
231
+ Engine is selected **per step**, not per chain. Pre-compute and write to each step's `engine` field in status.json (execution workflow reads this, does not re-compute).
235
232
 
236
233
  ```
237
- If execMode is 'cli' or 'skill' → force that engine for all steps.
234
+ If execMode is 'cli' or 'internal' → force that engine for all steps.
238
235
  In 'auto' mode, select per step:
239
236
  CLI steps (heavy, context-isolated): maestro-plan, maestro-execute, maestro-analyze, maestro-brainstorm, maestro-roadmap, maestro-ui-design, quality-refactor
240
- Skill steps (everything else): observable, interactive, lightweight (verify, review, test, debug, milestone-*, manage-*, spec-*, quick, etc.)
237
+ Internal steps (everything else): current-session Skill() call verify, review, test, debug, milestone-*, manage-*, spec-*, quick, etc.
241
238
  ```
242
239
 
243
- **Trade-off:** CLI = context isolation + template prompts + gemini analysis. Skill = direct visibility + synchronous + user can intervene.
240
+ **Trade-off:** CLI = context isolation + template prompts + gemini analysis. Internal = current-session Skill() call, direct visibility + synchronous + user can intervene.
241
+
242
+ ### 3f: Low-complexity fast path (before session creation)
243
+
244
+ If ALL conditions met:
245
+ - clarity >= 2
246
+ - task_type == `'quick'` or (action == `'create'` && object == `'feature'`)
247
+ - NOT `state_continue`
244
248
 
245
- ### 3f: Setup session
249
+ Then: `Skill({ skill: "maestro-quick", args: '"{description}"' })`. **End.** (no session created, no status.json)
250
+
251
+ ### 3g: Setup session
246
252
 
247
253
  Create session directory `.workflow/.maestro/maestro-{YYYYMMDD-HHMMSS}/` and write `status.json`:
248
254
  ```json
@@ -262,32 +268,34 @@ Create session directory `.workflow/.maestro/maestro-{YYYYMMDD-HHMMSS}/` and wri
262
268
  "current_phase": "{resolved_phase}",
263
269
  "user_intent": "{original_intent}",
264
270
  "issue_id": "{resolved_issue_id or null}",
271
+ "milestone_num": "{current_milestone_num or null}",
265
272
  "spec_session_id": null,
266
273
  "scratch_dir": null
267
274
  },
268
- "steps": [{ "index": 0, "skill": "{cmd}", "args": "{args}", "engine": null, "status": "pending", "started_at": null, "completed_at": null }],
269
- "current_step": 0,
275
+ "steps": [{ "index": 0, "skill": "{chainMap[].cmd}", "args": "{chainMap[].args}", "engine": "{cli|internal from 3e}", "status": "pending", "started_at": null, "completed_at": null }],
276
+ "current_step": "{$START_STEP or 0}",
270
277
  "status": "running"
271
278
  }
272
279
  ```
273
280
 
274
- ## Step 4: Dispatch
281
+ ### 3h: Initialize TodoWrite tracking
275
282
 
276
- ### 4a: Low-complexity fast path
283
+ Create TodoWrite entries with `MAESTRO:{chain_name}:` prefix for UI-visible progress tracking. TodoWrite and status.json form dual-track system — TodoWrite for user visibility, status.json for persistence and resume.
277
284
 
278
- If ALL conditions met:
279
- - clarity >= 2
280
- - task_type == `'quick'` or (action == `'create'` && object == `'feature'`)
281
- - NOT `forcedChain`, NOT `state_continue`
285
+ ```javascript
286
+ const todos = steps.map((step, i) => ({
287
+ content: `MAESTRO:${chain_name}: [${i + 1}/${steps.length}] ${step.skill}`,
288
+ status: i === 0 ? 'in_progress' : 'pending'
289
+ }));
290
+ TodoWrite({ todos });
291
+ ```
282
292
 
283
- Then: `Skill({ skill: "maestro-quick", args: '"{description}"' })`. **End.**
293
+ ## Step 4: Dispatch to execution workflow
284
294
 
285
- ### 4b: Standard execution read and follow execution workflow
295
+ status.json already created in Step 3g, TodoWrite initialized in Step 3h.
286
296
 
287
- For ALL chains (regardless of step count):
288
- 1. status.json already created in Step 3f with `steps[]` and `context`
289
- 2. Read `~/.maestro/workflows/maestro-chain-execute.md`
290
- 3. Follow it with `$SESSION_PATH` = session directory from Step 3f
297
+ 1. Read `~/.maestro/workflows/maestro-chain-execute.md`
298
+ 2. Follow it with `$SESSION_PATH` = session directory from Step 3g
291
299
 
292
300
  ---
293
301
 
@@ -476,8 +484,8 @@ detectNextAction(state):
476
484
  1. **Semantic Routing** — LLM-native `action × object` extraction; disambiguates "问题" by context
477
485
  2. **State-Aware** — Reads `.workflow/state.json` before routing
478
486
  3. **Quality Gates** — Issue chains auto-include review; `issue-full` is default for issue execution
479
- 4. **Per-Step Engine** — Each step independently selects Skill or CLI. Heavy steps (plan, execute, analyze, brainstorm) → CLI for context isolation. Observable steps (verify, review, test, debug, manage-*) → Skill for direct visibility. `--exec cli|skill` forces all steps.
480
- 5. **CLI Analysis Chain** — Gemini evaluates each CLI step's output, generates `next_step_hints` via `{{ANALYSIS_HINTS}}`. Skill steps skip analysis (output already visible). Sessions chained via `--resume`
487
+ 4. **Per-Step Engine** — Each step independently selects internal or CLI. Heavy steps (plan, execute, analyze, brainstorm) → CLI for context isolation. Observable steps (verify, review, test, debug, manage-*) → internal (current-session Skill()) for direct visibility. `--exec cli|internal` forces all steps.
488
+ 5. **CLI Analysis Chain** — Gemini evaluates each CLI step's output, generates `next_step_hints` via `{{ANALYSIS_HINTS}}`. Internal steps skip analysis (output already visible). Sessions chained via `--resume`
481
489
  6. **Phase Propagation** — Auto-detects and passes phase numbers to downstream commands
482
490
  7. **Auto Mode** — `-y` propagates through chain, skipping all confirmations
483
491
  8. **Resumable** — Session state in `.workflow/.maestro/` enables `-c` resume