@snipcodeit/mgw 0.2.2 → 0.3.0
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/README.md +55 -5
- package/commands/board/configure.md +205 -0
- package/commands/board/create.md +496 -0
- package/commands/board/show.md +221 -0
- package/commands/board/sync.md +417 -0
- package/commands/board/views.md +230 -0
- package/commands/board.md +23 -1543
- package/commands/milestone.md +5 -38
- package/commands/review.md +222 -42
- package/commands/run/execute.md +675 -0
- package/commands/run/pr-create.md +282 -0
- package/commands/run/triage.md +510 -0
- package/commands/run/worktree.md +54 -0
- package/commands/run.md +23 -1547
- package/commands/workflows/gsd.md +1 -13
- package/dist/bin/mgw.cjs +95 -6
- package/dist/{index-BiwU0uWA.cjs → index-s7v-ifd0.cjs} +669 -48
- package/dist/lib/index.cjs +185 -142
- package/package.json +5 -2
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mgw:run/execute
|
|
3
|
+
description: Execute GSD pipeline (quick or milestone route) and post execution update
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<step name="execute_gsd_quick">
|
|
7
|
+
**Execute GSD pipeline (quick / quick --full route):**
|
|
8
|
+
|
|
9
|
+
Only run this step if gsd_route is "gsd:quick" or "gsd:quick --full".
|
|
10
|
+
|
|
11
|
+
**Retry loop initialization:**
|
|
12
|
+
```bash
|
|
13
|
+
# Load retry state from .mgw/active/ state file
|
|
14
|
+
RETRY_COUNT=$(node -e "
|
|
15
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
16
|
+
const state = loadActiveIssue(${ISSUE_NUMBER});
|
|
17
|
+
console.log((state && typeof state.retry_count === 'number') ? state.retry_count : 0);
|
|
18
|
+
" 2>/dev/null || echo "0")
|
|
19
|
+
EXECUTION_SUCCEEDED=false
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Begin retry loop** — wraps the GSD quick execution (steps 1–11 below) with transient-failure retry:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
RETRY_LOOP:
|
|
26
|
+
while canRetry(issue_state) AND NOT EXECUTION_SUCCEEDED:
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Update pipeline_stage to "executing" in state file (at `${REPO_ROOT}/.mgw/active/`).
|
|
30
|
+
|
|
31
|
+
Determine flags:
|
|
32
|
+
- "gsd:quick" → $QUICK_FLAGS = ""
|
|
33
|
+
- "gsd:quick --full" → $QUICK_FLAGS = "--full"
|
|
34
|
+
|
|
35
|
+
Read the issue description to use as the GSD task description (full body, capped at 5000 chars for pathological issues):
|
|
36
|
+
```
|
|
37
|
+
$TASK_DESCRIPTION = "Issue #${ISSUE_NUMBER}: ${issue_title}\n\n${issue_body}" # full body, max 5000 chars
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Execute the GSD quick workflow. Read and follow the quick workflow steps:
|
|
41
|
+
|
|
42
|
+
1. **Init:** `node ~/.claude/get-shit-done/bin/gsd-tools.cjs init quick "$DESCRIPTION"`
|
|
43
|
+
Parse JSON for: planner_model, executor_model, checker_model, verifier_model, next_num, slug, date, quick_dir, task_dir.
|
|
44
|
+
|
|
45
|
+
**Handle missing .planning/:** Check `roadmap_exists` from init output. If false, do NOT
|
|
46
|
+
create GSD state files — .planning/ is owned by GSD. Only create the quick task
|
|
47
|
+
directory (GSD agents need it to store plans/summaries):
|
|
48
|
+
```bash
|
|
49
|
+
if [ "$roadmap_exists" = "false" ]; then
|
|
50
|
+
echo "NOTE: No .planning/ directory found. GSD manages its own state files."
|
|
51
|
+
echo " To create a ROADMAP.md, run /gsd:new-milestone after this pipeline."
|
|
52
|
+
mkdir -p .planning/quick
|
|
53
|
+
fi
|
|
54
|
+
```
|
|
55
|
+
MGW never writes config.json, ROADMAP.md, or STATE.md — those are GSD-owned files.
|
|
56
|
+
|
|
57
|
+
2. **Create task directory:**
|
|
58
|
+
```bash
|
|
59
|
+
QUICK_DIR=".planning/quick/${next_num}-${slug}"
|
|
60
|
+
mkdir -p "$QUICK_DIR"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
3. **Spawn planner (task agent):**
|
|
64
|
+
```
|
|
65
|
+
Task(
|
|
66
|
+
prompt="
|
|
67
|
+
<planning_context>
|
|
68
|
+
|
|
69
|
+
**Mode:** ${FULL_MODE ? 'quick-full' : 'quick'}
|
|
70
|
+
**Directory:** ${QUICK_DIR}
|
|
71
|
+
**Description:** ${TASK_DESCRIPTION}
|
|
72
|
+
|
|
73
|
+
<triage_context>
|
|
74
|
+
Scope: ${triage.scope.files} files across systems: ${triage.scope.systems}
|
|
75
|
+
Validity: ${triage.validity}
|
|
76
|
+
Security: ${triage.security_notes}
|
|
77
|
+
Conflicts: ${triage.conflicts}
|
|
78
|
+
GSD Route: ${gsd_route}
|
|
79
|
+
</triage_context>
|
|
80
|
+
|
|
81
|
+
<issue_comments>
|
|
82
|
+
${recent_comments}
|
|
83
|
+
</issue_comments>
|
|
84
|
+
|
|
85
|
+
<files_to_read>
|
|
86
|
+
- ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
|
|
87
|
+
- .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
88
|
+
</files_to_read>
|
|
89
|
+
|
|
90
|
+
</planning_context>
|
|
91
|
+
|
|
92
|
+
<constraints>
|
|
93
|
+
- Create a SINGLE plan with 1-3 focused tasks
|
|
94
|
+
- Quick tasks should be atomic and self-contained
|
|
95
|
+
- No research phase
|
|
96
|
+
${FULL_MODE ? '- Target ~40% context usage (structured for verification)' : '- Target ~30% context usage (simple, focused)'}
|
|
97
|
+
${FULL_MODE ? '- MUST generate must_haves in plan frontmatter (truths, artifacts, key_links)' : ''}
|
|
98
|
+
${FULL_MODE ? '- Each task MUST have files, action, verify, done fields' : ''}
|
|
99
|
+
</constraints>
|
|
100
|
+
|
|
101
|
+
<output>
|
|
102
|
+
Write plan to: ${QUICK_DIR}/${next_num}-PLAN.md
|
|
103
|
+
Return: ## PLANNING COMPLETE with plan path
|
|
104
|
+
</output>
|
|
105
|
+
",
|
|
106
|
+
subagent_type="gsd-planner",
|
|
107
|
+
model="{planner_model}",
|
|
108
|
+
description="Plan: ${issue_title}"
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
4. **Verify plan exists** at `${QUICK_DIR}/${next_num}-PLAN.md`
|
|
113
|
+
|
|
114
|
+
5. **Pre-flight plan structure check (gsd-tools):**
|
|
115
|
+
```bash
|
|
116
|
+
PLAN_CHECK=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify plan-structure "${QUICK_DIR}/${next_num}-PLAN.md")
|
|
117
|
+
```
|
|
118
|
+
Parse the JSON result. If structural issues found, include them in the plan-checker prompt below so it has concrete problems to evaluate rather than searching from scratch.
|
|
119
|
+
|
|
120
|
+
6. **(If --full) Spawn plan-checker, handle revision loop (max 2 iterations):**
|
|
121
|
+
```
|
|
122
|
+
Task(
|
|
123
|
+
prompt="
|
|
124
|
+
<files_to_read>
|
|
125
|
+
- ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
|
|
126
|
+
- .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
127
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan to verify)
|
|
128
|
+
</files_to_read>
|
|
129
|
+
|
|
130
|
+
<verification_context>
|
|
131
|
+
**Mode:** quick-full
|
|
132
|
+
**Task Description:** ${TASK_DESCRIPTION}
|
|
133
|
+
|
|
134
|
+
<structural_preflight>
|
|
135
|
+
${PLAN_CHECK}
|
|
136
|
+
</structural_preflight>
|
|
137
|
+
|
|
138
|
+
**Scope:** This is a quick task, not a full phase. Skip checks that require a ROADMAP phase goal. If structural_preflight flagged issues, prioritize evaluating those.
|
|
139
|
+
</verification_context>
|
|
140
|
+
|
|
141
|
+
<check_dimensions>
|
|
142
|
+
- Requirement coverage: Does the plan address the task description?
|
|
143
|
+
- Task completeness: Do tasks have files, action, verify, done fields?
|
|
144
|
+
- Key links: Are referenced files real?
|
|
145
|
+
- Scope sanity: Is this appropriately sized for a quick task (1-3 tasks)?
|
|
146
|
+
- must_haves derivation: Are must_haves traceable to the task description?
|
|
147
|
+
|
|
148
|
+
Skip: context compliance (no CONTEXT.md), cross-plan deps (single plan), ROADMAP alignment
|
|
149
|
+
</check_dimensions>
|
|
150
|
+
|
|
151
|
+
<expected_output>
|
|
152
|
+
- ## VERIFICATION PASSED — all checks pass
|
|
153
|
+
- ## ISSUES FOUND — structured issue list
|
|
154
|
+
</expected_output>
|
|
155
|
+
",
|
|
156
|
+
subagent_type="gsd-plan-checker",
|
|
157
|
+
model="{checker_model}",
|
|
158
|
+
description="Check quick plan: ${issue_title}"
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
If issues found and iteration < 2: spawn planner revision, then re-check.
|
|
163
|
+
If iteration >= 2: offer force proceed or abort.
|
|
164
|
+
|
|
165
|
+
7. **Spawn executor (task agent):**
|
|
166
|
+
```
|
|
167
|
+
Task(
|
|
168
|
+
prompt="
|
|
169
|
+
<files_to_read>
|
|
170
|
+
- ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
|
|
171
|
+
- .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
172
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan)
|
|
173
|
+
</files_to_read>
|
|
174
|
+
|
|
175
|
+
Execute quick task ${next_num}.
|
|
176
|
+
|
|
177
|
+
<constraints>
|
|
178
|
+
- Execute all tasks in the plan
|
|
179
|
+
- Commit each task atomically
|
|
180
|
+
- Create summary at: ${QUICK_DIR}/${next_num}-SUMMARY.md
|
|
181
|
+
- Do NOT update ROADMAP.md or STATE.md (GSD owns .planning/ files)
|
|
182
|
+
</constraints>
|
|
183
|
+
",
|
|
184
|
+
subagent_type="gsd-executor",
|
|
185
|
+
model="{executor_model}",
|
|
186
|
+
description="Execute: ${issue_title}"
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
8. **Verify summary (gsd-tools):**
|
|
191
|
+
```bash
|
|
192
|
+
VERIFY_RESULT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify-summary "${QUICK_DIR}/${next_num}-SUMMARY.md")
|
|
193
|
+
```
|
|
194
|
+
Parse JSON result. Use `passed` field for go/no-go. Checks summary existence, files created, and commits.
|
|
195
|
+
|
|
196
|
+
9. **(If --full) Spawn verifier:**
|
|
197
|
+
```
|
|
198
|
+
Task(
|
|
199
|
+
prompt="
|
|
200
|
+
<files_to_read>
|
|
201
|
+
- ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
|
|
202
|
+
- .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
203
|
+
- ${QUICK_DIR}/${next_num}-PLAN.md (Plan)
|
|
204
|
+
</files_to_read>
|
|
205
|
+
|
|
206
|
+
Verify quick task goal achievement.
|
|
207
|
+
Task directory: ${QUICK_DIR}
|
|
208
|
+
Task goal: ${TASK_DESCRIPTION}
|
|
209
|
+
|
|
210
|
+
Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}/${next_num}-VERIFICATION.md.",
|
|
211
|
+
subagent_type="gsd-verifier",
|
|
212
|
+
model="{verifier_model}",
|
|
213
|
+
description="Verify: ${issue_title}"
|
|
214
|
+
)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
10. **Post-execution artifact verification (non-blocking):**
|
|
218
|
+
```bash
|
|
219
|
+
ARTIFACT_CHECK=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify artifacts "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null || echo '{"passed":true}')
|
|
220
|
+
KEYLINK_CHECK=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs verify key-links "${QUICK_DIR}/${next_num}-PLAN.md" 2>/dev/null || echo '{"passed":true}')
|
|
221
|
+
```
|
|
222
|
+
Non-blocking: if either check flags issues, include them in the PR description as warnings. Do not halt the pipeline.
|
|
223
|
+
|
|
224
|
+
11. **Commit artifacts:**
|
|
225
|
+
```bash
|
|
226
|
+
node ~/.claude/get-shit-done/bin/gsd-tools.cjs commit "docs(quick-${next_num}): ${issue_title}" --files ${file_list}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Update state (at `${REPO_ROOT}/.mgw/active/`): gsd_artifacts.path = $QUICK_DIR, pipeline_stage = "verifying".
|
|
230
|
+
|
|
231
|
+
**Retry loop — on execution failure:**
|
|
232
|
+
|
|
233
|
+
If any step above fails (executor or verifier agent returns error, summary missing, etc.), capture the error and apply retry logic:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# On failure — classify and decide whether to retry
|
|
237
|
+
FAILURE_CLASS=$(node -e "
|
|
238
|
+
const { classifyFailure, canRetry, incrementRetry, getBackoffMs } = require('./lib/retry.cjs');
|
|
239
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
240
|
+
const fs = require('fs'), path = require('path');
|
|
241
|
+
|
|
242
|
+
const activeDir = path.join(process.cwd(), '.mgw', 'active');
|
|
243
|
+
const files = fs.readdirSync(activeDir);
|
|
244
|
+
const file = files.find(f => f.startsWith('${ISSUE_NUMBER}-') && f.endsWith('.json'));
|
|
245
|
+
const filePath = path.join(activeDir, file);
|
|
246
|
+
let issueState = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
247
|
+
|
|
248
|
+
// Classify the failure from the error context
|
|
249
|
+
const error = { message: '${EXECUTION_ERROR_MESSAGE}' };
|
|
250
|
+
const result = classifyFailure(error);
|
|
251
|
+
console.error('Failure classified as: ' + result.class + ' — ' + result.reason);
|
|
252
|
+
|
|
253
|
+
// Persist failure class to state
|
|
254
|
+
issueState.last_failure_class = result.class;
|
|
255
|
+
|
|
256
|
+
if (result.class === 'transient' && canRetry(issueState)) {
|
|
257
|
+
const backoff = getBackoffMs(issueState.retry_count || 0);
|
|
258
|
+
issueState = incrementRetry(issueState);
|
|
259
|
+
fs.writeFileSync(filePath, JSON.stringify(issueState, null, 2));
|
|
260
|
+
// Output: backoff ms so shell can sleep
|
|
261
|
+
console.log('retry:' + backoff + ':' + result.class);
|
|
262
|
+
} else {
|
|
263
|
+
// Permanent failure or retries exhausted — dead-letter
|
|
264
|
+
issueState.dead_letter = true;
|
|
265
|
+
fs.writeFileSync(filePath, JSON.stringify(issueState, null, 2));
|
|
266
|
+
console.log('dead_letter:' + result.class);
|
|
267
|
+
}
|
|
268
|
+
")
|
|
269
|
+
|
|
270
|
+
case "$FAILURE_CLASS" in
|
|
271
|
+
retry:*)
|
|
272
|
+
BACKOFF_MS=$(echo "$FAILURE_CLASS" | cut -d':' -f2)
|
|
273
|
+
BACKOFF_SEC=$(( (BACKOFF_MS + 999) / 1000 ))
|
|
274
|
+
echo "MGW: Transient failure detected — retrying in ${BACKOFF_SEC}s (retry ${RETRY_COUNT})..."
|
|
275
|
+
sleep "$BACKOFF_SEC"
|
|
276
|
+
RETRY_COUNT=$((RETRY_COUNT + 1))
|
|
277
|
+
# Loop back to retry
|
|
278
|
+
;;
|
|
279
|
+
dead_letter:*)
|
|
280
|
+
FAILURE_CLASS_NAME=$(echo "$FAILURE_CLASS" | cut -d':' -f2)
|
|
281
|
+
EXECUTION_SUCCEEDED=false
|
|
282
|
+
# Break out of retry loop — handled in post_execution_update
|
|
283
|
+
break
|
|
284
|
+
;;
|
|
285
|
+
esac
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
On successful execution (EXECUTION_SUCCEEDED=true): break out of retry loop, clear last_failure_class:
|
|
289
|
+
```bash
|
|
290
|
+
node -e "
|
|
291
|
+
const fs = require('fs'), path = require('path');
|
|
292
|
+
const activeDir = path.join(process.cwd(), '.mgw', 'active');
|
|
293
|
+
const files = fs.readdirSync(activeDir);
|
|
294
|
+
const file = files.find(f => f.startsWith('${ISSUE_NUMBER}-') && f.endsWith('.json'));
|
|
295
|
+
const filePath = path.join(activeDir, file);
|
|
296
|
+
const state = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
297
|
+
state.last_failure_class = null;
|
|
298
|
+
fs.writeFileSync(filePath, JSON.stringify(state, null, 2));
|
|
299
|
+
" 2>/dev/null || true
|
|
300
|
+
```
|
|
301
|
+
</step>
|
|
302
|
+
|
|
303
|
+
<step name="execute_gsd_milestone">
|
|
304
|
+
**Execute GSD pipeline (new-milestone route):**
|
|
305
|
+
|
|
306
|
+
Only run this step if gsd_route is "gsd:new-milestone".
|
|
307
|
+
|
|
308
|
+
**Retry loop initialization** (same pattern as execute_gsd_quick):
|
|
309
|
+
```bash
|
|
310
|
+
RETRY_COUNT=$(node -e "
|
|
311
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
312
|
+
const state = loadActiveIssue(${ISSUE_NUMBER});
|
|
313
|
+
console.log((state && typeof state.retry_count === 'number') ? state.retry_count : 0);
|
|
314
|
+
" 2>/dev/null || echo "0")
|
|
315
|
+
EXECUTION_SUCCEEDED=false
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Begin retry loop** — wraps the phase-execution loop (steps 2b–2e below) with transient-failure retry. Step 2 (milestone roadmap creation) is NOT wrapped in the retry loop — roadmap creation failures are always treated as permanent (require human intervention).
|
|
319
|
+
|
|
320
|
+
This is the most complex path. The orchestrator needs to:
|
|
321
|
+
|
|
322
|
+
**Resolve models for milestone agents:**
|
|
323
|
+
```bash
|
|
324
|
+
PLANNER_MODEL=$(node -e "process.stdout.write(require('./lib/gsd-adapter.cjs').resolveModel('gsd-planner'))")
|
|
325
|
+
EXECUTOR_MODEL=$(node -e "process.stdout.write(require('./lib/gsd-adapter.cjs').resolveModel('gsd-executor'))")
|
|
326
|
+
VERIFIER_MODEL=$(node -e "process.stdout.write(require('./lib/gsd-adapter.cjs').resolveModel('gsd-verifier'))")
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
1. **Discussion phase trigger for large-scope issues:**
|
|
330
|
+
|
|
331
|
+
If the issue was triaged with large scope and `gsd_route == "gsd:new-milestone"`, post
|
|
332
|
+
a scope proposal comment and set the discussing stage before proceeding to phase execution:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
DISCUSS_TIMESTAMP=$(node -e "try{process.stdout.write(require('./lib/gsd-adapter.cjs').getTimestamp())}catch(e){process.stdout.write(new Date().toISOString().replace(/\\.\\d{3}Z$/,'Z'))}")
|
|
336
|
+
|
|
337
|
+
# Build scope breakdown from triage data
|
|
338
|
+
SCOPE_SIZE="${triage.scope.size}"
|
|
339
|
+
SCOPE_BREAKDOWN="${triage.scope.files formatted as table rows}"
|
|
340
|
+
PHASE_COUNT="TBD (determined by roadmapper)"
|
|
341
|
+
|
|
342
|
+
# Post scope proposal comment using template from github.md
|
|
343
|
+
# Use Scope Proposal Comment template from @~/.claude/commands/mgw/workflows/github.md
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Set pipeline_stage to "discussing" and apply "mgw:discussing" label:
|
|
347
|
+
```bash
|
|
348
|
+
remove_mgw_labels_and_apply ${ISSUE_NUMBER} "mgw:discussing"
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Present to user:
|
|
352
|
+
```
|
|
353
|
+
AskUserQuestion(
|
|
354
|
+
header: "Scope Proposal Posted",
|
|
355
|
+
question: "A scope proposal has been posted to GitHub. Proceed with autonomous roadmap creation, or wait for stakeholder feedback?",
|
|
356
|
+
options: [
|
|
357
|
+
{ label: "Proceed", description: "Continue with roadmap creation now" },
|
|
358
|
+
{ label: "Wait", description: "Pipeline paused until stakeholder approves scope" }
|
|
359
|
+
]
|
|
360
|
+
)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
If wait: stop here. User will re-run /mgw:run after scope is approved.
|
|
364
|
+
If proceed: apply "mgw:approved" label and continue.
|
|
365
|
+
|
|
366
|
+
2. **Create milestone:** Use `gsd-tools init new-milestone` to gather context, then attempt autonomous roadmap creation from issue data:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
MILESTONE_INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init new-milestone 2>/dev/null)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Extract requirements from structured issue template fields (BLUF, What's Needed, What's Involved) if present.
|
|
373
|
+
|
|
374
|
+
If issue body contains sufficient detail (has clear requirements/scope):
|
|
375
|
+
- Spawn roadmapper agent with issue-derived requirements
|
|
376
|
+
- After roadmap generation, present to user for confirmation checkpoint:
|
|
377
|
+
```
|
|
378
|
+
AskUserQuestion(
|
|
379
|
+
header: "Milestone Roadmap Generated",
|
|
380
|
+
question: "Review the generated ROADMAP.md. Proceed with execution, revise, or switch to interactive mode?",
|
|
381
|
+
followUp: "Enter: proceed, revise, or interactive"
|
|
382
|
+
)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
If issue body lacks sufficient detail (no clear structure or too vague):
|
|
386
|
+
- Fall back to interactive mode:
|
|
387
|
+
```
|
|
388
|
+
The new-milestone route requires more detail than the issue provides.
|
|
389
|
+
Please run: /gsd:new-milestone
|
|
390
|
+
|
|
391
|
+
After the milestone is created, run /mgw:run ${ISSUE_NUMBER} again to
|
|
392
|
+
continue the pipeline through execution.
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Update pipeline_stage to "planning" (at `${REPO_ROOT}/.mgw/active/`).
|
|
396
|
+
|
|
397
|
+
2. **If resuming with pipeline_stage = "planning" and ROADMAP.md exists:**
|
|
398
|
+
Discover phases from ROADMAP and run the full per-phase GSD lifecycle:
|
|
399
|
+
|
|
400
|
+
```bash
|
|
401
|
+
ROADMAP_ANALYSIS=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs roadmap analyze)
|
|
402
|
+
# Parse ROADMAP_ANALYSIS JSON for list of phases:
|
|
403
|
+
# Each phase has: phase_number, phase_name, phase_slug
|
|
404
|
+
PHASE_LIST=$(echo "$ROADMAP_ANALYSIS" | python3 -c "
|
|
405
|
+
import json, sys
|
|
406
|
+
data = json.load(sys.stdin)
|
|
407
|
+
for p in data.get('phases', []):
|
|
408
|
+
print(f\"{p['number']}|{p['name']}|{p.get('slug', '')}\")
|
|
409
|
+
")
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
For each phase in order:
|
|
413
|
+
|
|
414
|
+
**a. Scaffold phase directory, then init:**
|
|
415
|
+
|
|
416
|
+
`init plan-phase` requires the phase directory to exist before it can locate it.
|
|
417
|
+
Use `scaffold phase-dir` first (which creates the directory from ROADMAP data),
|
|
418
|
+
then call `init plan-phase` to get planner/checker model assignments.
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
# Generate slug from phase name (lowercase, hyphens, no special chars)
|
|
422
|
+
PHASE_SLUG=$(echo "${PHASE_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
|
|
423
|
+
|
|
424
|
+
# Scaffold creates the directory and returns the path
|
|
425
|
+
SCAFFOLD=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs scaffold phase-dir --phase "${PHASE_NUMBER}" --name "${PHASE_SLUG}")
|
|
426
|
+
phase_dir=$(echo "$SCAFFOLD" | python3 -c "import json,sys; print(json.load(sys.stdin)['directory'])")
|
|
427
|
+
|
|
428
|
+
# Now init plan-phase can find the directory for model resolution
|
|
429
|
+
PHASE_INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init plan-phase "${PHASE_NUMBER}")
|
|
430
|
+
# Parse PHASE_INIT JSON for: planner_model, checker_model
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
**b. Spawn planner agent (gsd:plan-phase):**
|
|
434
|
+
```
|
|
435
|
+
Task(
|
|
436
|
+
prompt="
|
|
437
|
+
<files_to_read>
|
|
438
|
+
- ./CLAUDE.md (Project instructions -- if exists, follow all guidelines)
|
|
439
|
+
- .agents/skills/ (Project skills -- if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
440
|
+
- .planning/ROADMAP.md (Phase definitions and requirements)
|
|
441
|
+
- .planning/STATE.md (If exists -- project state)
|
|
442
|
+
</files_to_read>
|
|
443
|
+
|
|
444
|
+
You are the GSD planner. Plan phase ${PHASE_NUMBER}: ${PHASE_NAME}.
|
|
445
|
+
|
|
446
|
+
Read and follow the plan-phase workflow:
|
|
447
|
+
@~/.claude/get-shit-done/workflows/plan-phase.md
|
|
448
|
+
|
|
449
|
+
Phase directory: ${phase_dir}
|
|
450
|
+
Phase number: ${PHASE_NUMBER}
|
|
451
|
+
|
|
452
|
+
Create PLAN.md file(s) in the phase directory. Each plan must have:
|
|
453
|
+
- Frontmatter with phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
|
|
454
|
+
- Objective, context, tasks, verification, success criteria, output sections
|
|
455
|
+
- Each task with files, action, verify, done fields
|
|
456
|
+
|
|
457
|
+
Commit the plan files when done.
|
|
458
|
+
",
|
|
459
|
+
subagent_type="gsd-planner",
|
|
460
|
+
model="${PLANNER_MODEL}",
|
|
461
|
+
description="Plan phase ${PHASE_NUMBER}: ${PHASE_NAME}"
|
|
462
|
+
)
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**c. Verify plans exist:**
|
|
466
|
+
```bash
|
|
467
|
+
PLAN_COUNT=$(ls ${phase_dir}/*-PLAN.md 2>/dev/null | wc -l)
|
|
468
|
+
if [ "$PLAN_COUNT" -eq 0 ]; then
|
|
469
|
+
echo "ERROR: No plans created for phase ${PHASE_NUMBER}. Skipping phase execution."
|
|
470
|
+
# Post error comment and continue to next phase
|
|
471
|
+
gh issue comment ${ISSUE_NUMBER} --body "> **MGW** \`phase-error\` Phase ${PHASE_NUMBER} planning produced no plans. Skipping." 2>/dev/null || true
|
|
472
|
+
continue
|
|
473
|
+
fi
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**d. Init execute-phase and spawn executor agent (gsd:execute-phase):**
|
|
477
|
+
```bash
|
|
478
|
+
EXEC_INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs init execute-phase "${PHASE_NUMBER}")
|
|
479
|
+
# Parse EXEC_INIT JSON for: executor_model, verifier_model, phase_dir, plans, incomplete_plans, plan_count
|
|
480
|
+
```
|
|
481
|
+
```
|
|
482
|
+
Task(
|
|
483
|
+
prompt="
|
|
484
|
+
<files_to_read>
|
|
485
|
+
- ./CLAUDE.md (Project instructions -- if exists, follow all guidelines)
|
|
486
|
+
- .agents/skills/ (Project skills -- if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
487
|
+
- ${phase_dir}/*-PLAN.md (Plans to execute)
|
|
488
|
+
</files_to_read>
|
|
489
|
+
|
|
490
|
+
You are the GSD executor. Execute all plans for phase ${PHASE_NUMBER}: ${PHASE_NAME}.
|
|
491
|
+
|
|
492
|
+
Read and follow the execute-phase workflow:
|
|
493
|
+
@~/.claude/get-shit-done/workflows/execute-phase.md
|
|
494
|
+
|
|
495
|
+
Phase: ${PHASE_NUMBER}
|
|
496
|
+
Phase directory: ${phase_dir}
|
|
497
|
+
|
|
498
|
+
Execute each plan's tasks in wave order. For each plan:
|
|
499
|
+
1. Execute all tasks
|
|
500
|
+
2. Commit each task atomically
|
|
501
|
+
3. Create SUMMARY.md in the phase directory
|
|
502
|
+
|
|
503
|
+
Do NOT update ROADMAP.md or STATE.md directly -- those are managed by GSD tools.
|
|
504
|
+
",
|
|
505
|
+
subagent_type="gsd-executor",
|
|
506
|
+
model="${EXECUTOR_MODEL}",
|
|
507
|
+
description="Execute phase ${PHASE_NUMBER}: ${PHASE_NAME}"
|
|
508
|
+
)
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**e. Spawn verifier agent (gsd:verify-phase):**
|
|
512
|
+
```
|
|
513
|
+
Task(
|
|
514
|
+
prompt="
|
|
515
|
+
<files_to_read>
|
|
516
|
+
- ./CLAUDE.md (Project instructions -- if exists, follow all guidelines)
|
|
517
|
+
- .agents/skills/ (Project skills -- if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
518
|
+
- ${phase_dir}/*-PLAN.md (Plans with must_haves)
|
|
519
|
+
- ${phase_dir}/*-SUMMARY.md (Execution summaries)
|
|
520
|
+
</files_to_read>
|
|
521
|
+
|
|
522
|
+
Verify phase ${PHASE_NUMBER}: ${PHASE_NAME} goal achievement.
|
|
523
|
+
|
|
524
|
+
Read and follow the verify-phase workflow:
|
|
525
|
+
@~/.claude/get-shit-done/workflows/verify-phase.md
|
|
526
|
+
|
|
527
|
+
Phase: ${PHASE_NUMBER}
|
|
528
|
+
Phase directory: ${phase_dir}
|
|
529
|
+
|
|
530
|
+
Check must_haves from plan frontmatter against actual codebase.
|
|
531
|
+
Create VERIFICATION.md in the phase directory.
|
|
532
|
+
",
|
|
533
|
+
subagent_type="gsd-verifier",
|
|
534
|
+
model="${VERIFIER_MODEL}",
|
|
535
|
+
description="Verify phase ${PHASE_NUMBER}: ${PHASE_NAME}"
|
|
536
|
+
)
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
**f. Post phase-complete comment directly (no sub-agent):**
|
|
540
|
+
```bash
|
|
541
|
+
PHASE_TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
542
|
+
VERIFICATION_STATUS=$(grep -m1 "^## " "${phase_dir}/"*-VERIFICATION.md 2>/dev/null | head -1 || echo "Verification complete")
|
|
543
|
+
PHASE_BODY=$(cat <<COMMENTEOF
|
|
544
|
+
> **MGW** · \`phase-complete\` · ${PHASE_TIMESTAMP}
|
|
545
|
+
> ${MILESTONE_CONTEXT}
|
|
546
|
+
|
|
547
|
+
### Phase ${PHASE_NUMBER} Complete — ${PHASE_NAME}
|
|
548
|
+
|
|
549
|
+
Execution complete. See ${phase_dir} for plans, summaries, and verification.
|
|
550
|
+
|
|
551
|
+
**Verification:** ${VERIFICATION_STATUS}
|
|
552
|
+
COMMENTEOF
|
|
553
|
+
)
|
|
554
|
+
gh issue comment ${ISSUE_NUMBER} --body "$PHASE_BODY" 2>/dev/null || true
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
**Retry loop — on phase execution failure** (apply same pattern as execute_gsd_quick):
|
|
558
|
+
|
|
559
|
+
If a phase's executor or verifier fails, capture the error and apply retry logic via `classifyFailure()`, `canRetry()`, `incrementRetry()`, and `getBackoffMs()` from `lib/retry.cjs`. Only the failing phase is retried (restart from step 2b for that phase). If the failure is transient and `canRetry()` is true: sleep backoff, call `incrementRetry()`, loop. If permanent or retries exhausted: set `dead_letter = true`, set `last_failure_class`, break the retry loop.
|
|
560
|
+
|
|
561
|
+
On successful completion of all phases: clear `last_failure_class`, set `EXECUTION_SUCCEEDED=true`.
|
|
562
|
+
|
|
563
|
+
After ALL phases complete → update pipeline_stage to "verifying" (at `${REPO_ROOT}/.mgw/active/`).
|
|
564
|
+
</step>
|
|
565
|
+
|
|
566
|
+
<step name="post_execution_update">
|
|
567
|
+
**Post execution-complete comment on issue (or failure comment if dead_letter):**
|
|
568
|
+
|
|
569
|
+
Read `dead_letter` and `last_failure_class` from current issue state:
|
|
570
|
+
```bash
|
|
571
|
+
DEAD_LETTER=$(node -e "
|
|
572
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
573
|
+
const state = loadActiveIssue(${ISSUE_NUMBER});
|
|
574
|
+
console.log(state && state.dead_letter === true ? 'true' : 'false');
|
|
575
|
+
" 2>/dev/null || echo "false")
|
|
576
|
+
|
|
577
|
+
LAST_FAILURE_CLASS=$(node -e "
|
|
578
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
579
|
+
const state = loadActiveIssue(${ISSUE_NUMBER});
|
|
580
|
+
console.log((state && state.last_failure_class) ? state.last_failure_class : 'unknown');
|
|
581
|
+
" 2>/dev/null || echo "unknown")
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**If dead_letter === true — post failure comment and halt:**
|
|
585
|
+
```bash
|
|
586
|
+
if [ "$DEAD_LETTER" = "true" ]; then
|
|
587
|
+
FAIL_TIMESTAMP=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs current-timestamp --raw 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
588
|
+
RETRY_COUNT_CURRENT=$(node -e "
|
|
589
|
+
const { loadActiveIssue } = require('./lib/state.cjs');
|
|
590
|
+
const state = loadActiveIssue(${ISSUE_NUMBER});
|
|
591
|
+
console.log((state && typeof state.retry_count === 'number') ? state.retry_count : 0);
|
|
592
|
+
" 2>/dev/null || echo "0")
|
|
593
|
+
|
|
594
|
+
FAIL_BODY=$(cat <<COMMENTEOF
|
|
595
|
+
> **MGW** · \`pipeline-failed\` · ${FAIL_TIMESTAMP}
|
|
596
|
+
> ${MILESTONE_CONTEXT}
|
|
597
|
+
|
|
598
|
+
### Pipeline Failed
|
|
599
|
+
|
|
600
|
+
Issue #${ISSUE_NUMBER} — ${issue_title}
|
|
601
|
+
|
|
602
|
+
| | |
|
|
603
|
+
|---|---|
|
|
604
|
+
| **Failure class** | \`${LAST_FAILURE_CLASS}\` |
|
|
605
|
+
| **Retries attempted** | ${RETRY_COUNT_CURRENT} of 3 |
|
|
606
|
+
| **Status** | Dead-lettered — requires human intervention |
|
|
607
|
+
|
|
608
|
+
**Failure class meaning:**
|
|
609
|
+
- \`transient\` — retry exhausted (rate limit, network, or overload)
|
|
610
|
+
- \`permanent\` — unrecoverable (auth, missing deps, bad config)
|
|
611
|
+
- \`needs-info\` — issue is ambiguous or incomplete
|
|
612
|
+
|
|
613
|
+
**To retry after resolving root cause:**
|
|
614
|
+
\`\`\`
|
|
615
|
+
/mgw:run ${ISSUE_NUMBER} --retry
|
|
616
|
+
\`\`\`
|
|
617
|
+
COMMENTEOF
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
gh issue comment ${ISSUE_NUMBER} --body "$FAIL_BODY" 2>/dev/null || true
|
|
621
|
+
gh issue edit ${ISSUE_NUMBER} --add-label "pipeline-failed" 2>/dev/null || true
|
|
622
|
+
gh label create "pipeline-failed" --description "Pipeline execution failed" --color "d73a4a" --force 2>/dev/null || true
|
|
623
|
+
|
|
624
|
+
# Update pipeline_stage to failed
|
|
625
|
+
node -e "
|
|
626
|
+
const fs = require('fs'), path = require('path');
|
|
627
|
+
const activeDir = path.join(process.cwd(), '.mgw', 'active');
|
|
628
|
+
const files = fs.readdirSync(activeDir);
|
|
629
|
+
const file = files.find(f => f.startsWith('${ISSUE_NUMBER}-') && f.endsWith('.json'));
|
|
630
|
+
const filePath = path.join(activeDir, file);
|
|
631
|
+
const state = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
632
|
+
state.pipeline_stage = 'failed';
|
|
633
|
+
fs.writeFileSync(filePath, JSON.stringify(state, null, 2));
|
|
634
|
+
" 2>/dev/null || true
|
|
635
|
+
|
|
636
|
+
echo "MGW: Pipeline dead-lettered for #${ISSUE_NUMBER} (class: ${LAST_FAILURE_CLASS}). Use --retry after fixing root cause."
|
|
637
|
+
exit 1
|
|
638
|
+
fi
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
**Otherwise — post execution-complete comment:**
|
|
642
|
+
|
|
643
|
+
After GSD execution completes successfully, post a structured update before creating the PR:
|
|
644
|
+
|
|
645
|
+
```bash
|
|
646
|
+
COMMIT_COUNT=$(git rev-list ${DEFAULT_BRANCH}..HEAD --count 2>/dev/null || echo "0")
|
|
647
|
+
TEST_STATUS=$(npm test 2>&1 >/dev/null && echo "passing" || echo "failing")
|
|
648
|
+
FILE_CHANGES=$(git diff --stat ${DEFAULT_BRANCH}..HEAD 2>/dev/null | tail -1)
|
|
649
|
+
EXEC_TIMESTAMP=$(node -e "try{process.stdout.write(require('./lib/gsd-adapter.cjs').getTimestamp())}catch(e){process.stdout.write(new Date().toISOString().replace(/\\.\\d{3}Z$/,'Z'))}")
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
Post the execution-complete comment directly (no sub-agent — guarantees it happens):
|
|
653
|
+
|
|
654
|
+
```bash
|
|
655
|
+
EXEC_BODY=$(cat <<COMMENTEOF
|
|
656
|
+
> **MGW** · \`execution-complete\` · ${EXEC_TIMESTAMP}
|
|
657
|
+
> ${MILESTONE_CONTEXT}
|
|
658
|
+
|
|
659
|
+
### Execution Complete
|
|
660
|
+
|
|
661
|
+
${COMMIT_COUNT} atomic commit(s) on branch \`${BRANCH_NAME}\`.
|
|
662
|
+
|
|
663
|
+
**Changes:** ${FILE_CHANGES}
|
|
664
|
+
|
|
665
|
+
**Tests:** ${TEST_STATUS}
|
|
666
|
+
|
|
667
|
+
Preparing pull request.
|
|
668
|
+
COMMENTEOF
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
gh issue comment ${ISSUE_NUMBER} --body "$EXEC_BODY" 2>/dev/null || true
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
Update pipeline_stage to "pr-pending" (at `${REPO_ROOT}/.mgw/active/`).
|
|
675
|
+
</step>
|