maestro-flow 0.3.28 → 0.3.29
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.
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: maestro-ralph-execute
|
|
3
|
+
description: Single-step executor — find next pending command in ralph session, execute by type (decision/skill/cli), hand off to next iteration
|
|
4
|
+
argument-hint: "[session-id]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
- Bash
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
- Skill
|
|
13
|
+
---
|
|
14
|
+
<purpose>
|
|
15
|
+
Single-step executor for ralph command chains. Each invocation:
|
|
16
|
+
1. Finds the next pending command in the ralph session JSON
|
|
17
|
+
2. Executes it based on node type (decision → ralph, skill → Skill(), cli → delegate)
|
|
18
|
+
3. Updates status.json
|
|
19
|
+
4. Hands off to next iteration via self-invocation or ralph callback
|
|
20
|
+
|
|
21
|
+
Three node types drive different execution + handoff patterns:
|
|
22
|
+
- **decision**: `Skill("maestro-ralph")` — ralph re-evaluates state, may expand chain
|
|
23
|
+
- **skill**: `Skill({ skill, args })` — synchronous in-session → `Skill("maestro-ralph-execute")`
|
|
24
|
+
- **cli**: `maestro delegate` background → STOP → callback → `Skill("maestro-ralph-execute")`
|
|
25
|
+
|
|
26
|
+
Mutual invocation with `/maestro-ralph` forms a persistent self-perpetuating work loop.
|
|
27
|
+
</purpose>
|
|
28
|
+
|
|
29
|
+
<context>
|
|
30
|
+
$ARGUMENTS — optional session ID. If omitted, finds latest running ralph session.
|
|
31
|
+
|
|
32
|
+
**Session discovery:**
|
|
33
|
+
Scan `.workflow/.ralph/ralph-*/status.json` for `status == "running"`, sorted by `created_at` descending.
|
|
34
|
+
If $ARGUMENTS matches a session ID pattern, use that specific session.
|
|
35
|
+
</context>
|
|
36
|
+
|
|
37
|
+
<execution>
|
|
38
|
+
|
|
39
|
+
## Step 1: Locate Session
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
If $ARGUMENTS matches ralph-* pattern:
|
|
43
|
+
session_path = .workflow/.ralph/{$ARGUMENTS}/status.json
|
|
44
|
+
Else:
|
|
45
|
+
Scan .workflow/.ralph/ralph-*/status.json
|
|
46
|
+
Filter: status == "running"
|
|
47
|
+
Sort: created_at DESC
|
|
48
|
+
Take first
|
|
49
|
+
|
|
50
|
+
If no session found:
|
|
51
|
+
Output: "无运行中的 ralph 会话。使用 /maestro-ralph 创建新会话。"
|
|
52
|
+
End.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Read status.json → extract: `id`, `commands[]`, `current`, `status`, `phase`.
|
|
56
|
+
|
|
57
|
+
## Step 2: Find Next Pending Command
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
next = commands.find(cmd => cmd.status == "pending")
|
|
61
|
+
|
|
62
|
+
If no pending command:
|
|
63
|
+
→ Step 5 (Complete)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Step 2.5: Assemble Args (context propagation)
|
|
67
|
+
|
|
68
|
+
Before execution, enrich `next.args` with context from session and prior outputs.
|
|
69
|
+
|
|
70
|
+
**Context sources (priority order):**
|
|
71
|
+
1. `status.json.intent` — user's original input text
|
|
72
|
+
2. `status.json.phase` — current phase number
|
|
73
|
+
3. `status.json.milestone` — current milestone name
|
|
74
|
+
4. `.workflow/state.json.artifacts[]` — latest artifacts for path resolution
|
|
75
|
+
5. Previous completed command outputs — scratch dirs, session IDs
|
|
76
|
+
|
|
77
|
+
**Placeholder substitution in args:**
|
|
78
|
+
```
|
|
79
|
+
{phase} → status.phase
|
|
80
|
+
{milestone} → status.milestone
|
|
81
|
+
{intent} → status.intent
|
|
82
|
+
{scratch_dir} → latest artifact path for current phase from state.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Per-command enrichment** (when args is empty or only has phase number):
|
|
86
|
+
|
|
87
|
+
| Command | Required context | Source |
|
|
88
|
+
|---------|-----------------|--------|
|
|
89
|
+
| maestro-brainstorm | topic description | `status.intent` — pass as `"{intent}"` |
|
|
90
|
+
| maestro-roadmap | description + context | `status.intent` — pass as `"{intent}"` |
|
|
91
|
+
| maestro-analyze | phase or topic | `{phase}` or `"{intent}"` if no phase |
|
|
92
|
+
| maestro-plan | phase or --dir | `{phase}`, or `--dir {scratch_dir}` if standalone |
|
|
93
|
+
| maestro-execute | phase or --dir | `{phase}`, or `--dir {scratch_dir}` if standalone |
|
|
94
|
+
| maestro-verify | phase | `{phase}` |
|
|
95
|
+
| quality-debug | gap context | Read previous step's error or gap summary from artifact dir |
|
|
96
|
+
| quality-* | phase | `{phase}` |
|
|
97
|
+
|
|
98
|
+
**Artifact dir resolution for --dir args:**
|
|
99
|
+
```
|
|
100
|
+
Read .workflow/state.json
|
|
101
|
+
Filter artifacts: milestone == session.milestone, phase == session.phase
|
|
102
|
+
For plan commands: find latest type=="analyze" artifact → --dir .workflow/scratch/{path}
|
|
103
|
+
For execute commands: find latest type=="plan" artifact → --dir .workflow/scratch/{path}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Write enriched args back to status.json** so resume preserves them:
|
|
107
|
+
```
|
|
108
|
+
next.args = enriched_args
|
|
109
|
+
Write status.json
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Step 3: Mark Running + Update JSON
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
next.status = "running"
|
|
116
|
+
next.started_at = new Date().toISOString()
|
|
117
|
+
status.current = next.index
|
|
118
|
+
status.updated_at = new Date().toISOString()
|
|
119
|
+
|
|
120
|
+
Write status.json
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Display step banner:
|
|
124
|
+
```
|
|
125
|
+
------------------------------------------------------------
|
|
126
|
+
[{next.index}/{commands.length - 1}] {next.skill} [{next.type}]
|
|
127
|
+
------------------------------------------------------------
|
|
128
|
+
Args: {next.args}
|
|
129
|
+
{next.type == "decision" ? "Retry: " + JSON.parse(next.args).retry_count + "/" + JSON.parse(next.args).max_retries : ""}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Context weight hint** (after 4+ completed steps):
|
|
133
|
+
```
|
|
134
|
+
If completed_count >= 4:
|
|
135
|
+
Display: ⚡ 已执行 {completed_count} 步,上下文较重。可 /maestro-ralph continue 在新上下文恢复。
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Step 4: Execute by Type
|
|
139
|
+
|
|
140
|
+
### 4a. decision node
|
|
141
|
+
|
|
142
|
+
Decision nodes hand control back to ralph for re-evaluation.
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
Skill({ skill: "maestro-ralph" })
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Ralph will:
|
|
149
|
+
1. Detect the running decision node in status.json
|
|
150
|
+
2. Evaluate execution results (verify gaps, test failures, etc.)
|
|
151
|
+
3. Optionally expand commands[] with fix loops
|
|
152
|
+
4. Mark the decision node completed
|
|
153
|
+
5. Call `Skill("maestro-ralph-execute")` to resume
|
|
154
|
+
|
|
155
|
+
**After Skill("maestro-ralph") returns, this execution ends.** Ralph handles the handoff.
|
|
156
|
+
|
|
157
|
+
### 4b. skill node
|
|
158
|
+
|
|
159
|
+
Synchronous in-session execution.
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
Skill({ skill: next.skill, args: next.args })
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
On success:
|
|
166
|
+
```
|
|
167
|
+
next.status = "completed"
|
|
168
|
+
next.completed_at = new Date().toISOString()
|
|
169
|
+
Write status.json
|
|
170
|
+
|
|
171
|
+
Display: [N/total] ✓ {next.skill} completed
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
On failure (Skill throws or produces error):
|
|
175
|
+
```
|
|
176
|
+
next.status = "failed"
|
|
177
|
+
next.error = "{error message}"
|
|
178
|
+
next.completed_at = new Date().toISOString()
|
|
179
|
+
Write status.json
|
|
180
|
+
|
|
181
|
+
Display: [N/total] ✗ {next.skill} failed: {error}
|
|
182
|
+
AskUserQuestion: "retry / skip / abort"
|
|
183
|
+
retry → reset next.status = "pending", next.error = null → Skill("maestro-ralph-execute")
|
|
184
|
+
skip → next.status = "skipped" → Skill("maestro-ralph-execute")
|
|
185
|
+
abort → status.status = "paused" → Write status.json → End.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Then hand off:
|
|
189
|
+
```
|
|
190
|
+
Skill({ skill: "maestro-ralph-execute" })
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 4c. cli node
|
|
194
|
+
|
|
195
|
+
Background delegate execution with stop-and-wait pattern.
|
|
196
|
+
|
|
197
|
+
Resolve CLI tool from session or default config:
|
|
198
|
+
```
|
|
199
|
+
cli_tool = session.cli_tool || "gemini" // from ralph status.json or fallback
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
Bash({
|
|
204
|
+
command: `maestro delegate "PURPOSE: 执行 /${next.skill} ${next.args}; success = 命令正常完成并产出 artifact
|
|
205
|
+
TASK: 运行 /${next.skill} ${next.args}
|
|
206
|
+
MODE: write
|
|
207
|
+
CONTEXT: @**/*
|
|
208
|
+
EXPECTED: 产出写入 .workflow/scratch/,artifact 注册到 state.json
|
|
209
|
+
CONSTRAINTS: 严格按照 /${next.skill} 的正常流程执行" --to ${cli_tool} --mode write`,
|
|
210
|
+
run_in_background: true,
|
|
211
|
+
timeout: 600000
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
STOP — wait for background callback.
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**On callback:**
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
Retrieve output: maestro delegate output <exec_id>
|
|
221
|
+
|
|
222
|
+
next.status = "completed"
|
|
223
|
+
next.completed_at = new Date().toISOString()
|
|
224
|
+
Write status.json
|
|
225
|
+
|
|
226
|
+
Display: [N/total] ✓ {next.skill} completed [cli]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
On failure:
|
|
230
|
+
```
|
|
231
|
+
next.status = "failed"
|
|
232
|
+
next.error = "{error details}"
|
|
233
|
+
Write status.json
|
|
234
|
+
|
|
235
|
+
AskUserQuestion: "retry / skip / abort"
|
|
236
|
+
(same as 4b failure handling)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Then hand off:
|
|
240
|
+
```
|
|
241
|
+
Skill({ skill: "maestro-ralph-execute" })
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Step 5: Complete Session
|
|
245
|
+
|
|
246
|
+
When no pending commands remain:
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
status.status = "completed"
|
|
250
|
+
status.updated_at = new Date().toISOString()
|
|
251
|
+
Write status.json
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Display completion report:
|
|
255
|
+
```
|
|
256
|
+
============================================================
|
|
257
|
+
RALPH COMPLETE
|
|
258
|
+
============================================================
|
|
259
|
+
Session: {id}
|
|
260
|
+
Phase: {phase}
|
|
261
|
+
Steps: {completed}/{total}
|
|
262
|
+
|
|
263
|
+
{commands.map(cmd => {
|
|
264
|
+
icon = cmd.status == "completed" ? "✓" :
|
|
265
|
+
cmd.status == "skipped" ? "—" :
|
|
266
|
+
cmd.status == "failed" ? "✗" : " "
|
|
267
|
+
type_badge = cmd.type == "decision" ? "◆" :
|
|
268
|
+
cmd.type == "cli" ? "⚡" : " "
|
|
269
|
+
return ` [${icon}] ${cmd.index}. ${type_badge} ${cmd.skill} ${cmd.args} [${cmd.type}]`
|
|
270
|
+
})}
|
|
271
|
+
============================================================
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
**End.**
|
|
275
|
+
|
|
276
|
+
</execution>
|
|
277
|
+
|
|
278
|
+
<error_codes>
|
|
279
|
+
| Code | Severity | Description | Recovery |
|
|
280
|
+
|------|----------|-------------|----------|
|
|
281
|
+
| E001 | error | No running ralph session found | Suggest /maestro-ralph to create |
|
|
282
|
+
| E002 | error | Session status.json corrupt or unreadable | Show path, suggest manual check |
|
|
283
|
+
| E003 | error | CLI delegate failed + user chose abort | Mark paused, suggest /maestro-ralph continue |
|
|
284
|
+
| W001 | warning | Step completed with warnings | Log and continue |
|
|
285
|
+
| W002 | warning | Context getting heavy (step >= 4) | Hint: /maestro-ralph continue for fresh context |
|
|
286
|
+
</error_codes>
|
|
287
|
+
|
|
288
|
+
<success_criteria>
|
|
289
|
+
- [ ] Session discovery finds latest running ralph session
|
|
290
|
+
- [ ] Pending command correctly identified from commands[]
|
|
291
|
+
- [ ] decision nodes hand off to maestro-ralph via Skill()
|
|
292
|
+
- [ ] skill nodes execute synchronously via Skill() and self-invoke next
|
|
293
|
+
- [ ] cli nodes use maestro delegate with run_in_background + stop pattern
|
|
294
|
+
- [ ] status.json updated after every status change (resume-safe)
|
|
295
|
+
- [ ] Failure handling offers retry/skip/abort
|
|
296
|
+
- [ ] Completion report shows all steps with status icons
|
|
297
|
+
- [ ] Self-invocation chain continues until all commands complete
|
|
298
|
+
</success_criteria>
|