@snipcodeit/mgw 0.2.1 → 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.
@@ -0,0 +1,282 @@
1
+ ---
2
+ name: mgw:run/pr-create
3
+ description: Create PR from GSD artifacts and clean up worktree
4
+ ---
5
+
6
+ <step name="create_pr">
7
+ **Create PR (task agent):**
8
+
9
+ After GSD execution completes (any route):
10
+
11
+ Push branch and gather artifacts:
12
+ ```bash
13
+ git push -u origin ${BRANCH_NAME}
14
+
15
+ # Structured summary data via gsd-tools (returns JSON with one_liner, key_files, tech_added, patterns, decisions)
16
+ SUMMARY_DATA=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs summary-extract "${gsd_artifacts_path}/*SUMMARY*" 2>/dev/null || echo '{}')
17
+ # Also keep raw summary for full context
18
+ SUMMARY=$(cat ${gsd_artifacts_path}/*SUMMARY* 2>/dev/null)
19
+ VERIFICATION=$(cat ${gsd_artifacts_path}/*VERIFICATION* 2>/dev/null)
20
+ COMMITS=$(git log ${DEFAULT_BRANCH}..HEAD --oneline)
21
+ CROSS_REFS=$(cat ${REPO_ROOT}/.mgw/cross-refs.json 2>/dev/null)
22
+ # Progress table for PR details section
23
+ PROGRESS_TABLE=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs progress table --raw 2>/dev/null || echo "")
24
+
25
+ # Milestone/phase context for PR body
26
+ MILESTONE_TITLE=""
27
+ PHASE_INFO=""
28
+ DEPENDENCY_CHAIN=""
29
+ PROJECT_BOARD_URL=""
30
+ if [ -f "${REPO_ROOT}/.mgw/project.json" ]; then
31
+ MILESTONE_TITLE=$(python3 -c "
32
+ import json
33
+ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
34
+ for m in p['milestones']:
35
+ for i in m.get('issues', []):
36
+ if i.get('github_number') == ${ISSUE_NUMBER}:
37
+ print(m['name'])
38
+ break
39
+ " 2>/dev/null || echo "")
40
+
41
+ PHASE_INFO=$(python3 -c "
42
+ import json
43
+ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
44
+ total_phases = sum(len(m.get('issues', [])) for m in p['milestones'])
45
+ for m in p['milestones']:
46
+ for i in m.get('issues', []):
47
+ if i.get('github_number') == ${ISSUE_NUMBER}:
48
+ total_in_milestone = len(m.get('issues', []))
49
+ idx = [x['github_number'] for x in m['issues']].index(${ISSUE_NUMBER}) + 1
50
+ print(f\"Phase {i['phase_number']}: {i['phase_name']} (issue {idx}/{total_in_milestone} in milestone)\")
51
+ break
52
+ " 2>/dev/null || echo "")
53
+
54
+ DEPENDENCY_CHAIN=$(python3 -c "
55
+ import json
56
+ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
57
+ refs = json.load(open('${REPO_ROOT}/.mgw/cross-refs.json'))
58
+ blockers = [l['b'].split(':')[1] for l in refs.get('links', [])
59
+ if l.get('type') == 'blocked-by' and l['a'] == 'issue:${ISSUE_NUMBER}']
60
+ blocks = [l['a'].split(':')[1] for l in refs.get('links', [])
61
+ if l.get('type') == 'blocked-by' and l['b'] == 'issue:${ISSUE_NUMBER}']
62
+ parts = []
63
+ if blockers: parts.append('Blocked by: ' + ', '.join(f'#{b}' for b in blockers))
64
+ if blocks: parts.append('Unblocks: ' + ', '.join(f'#{b}' for b in blocks))
65
+ print(' | '.join(parts) if parts else 'No dependencies')
66
+ " 2>/dev/null || echo "")
67
+
68
+ PROJECT_BOARD_URL=$(python3 -c "
69
+ import json
70
+ p = json.load(open('${REPO_ROOT}/.mgw/project.json'))
71
+ print(p.get('project', {}).get('project_board', {}).get('url', ''))
72
+ " 2>/dev/null || echo "")
73
+ fi
74
+ ```
75
+
76
+ Read issue state for context.
77
+
78
+ ```
79
+ Task(
80
+ prompt="
81
+ <files_to_read>
82
+ - ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
83
+ - .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
84
+ </files_to_read>
85
+
86
+ Create a GitHub PR for issue #${ISSUE_NUMBER}.
87
+
88
+ <issue>
89
+ Title: ${issue_title}
90
+ Body: ${issue_body}
91
+ </issue>
92
+
93
+ <milestone_context>
94
+ Milestone: ${MILESTONE_TITLE}
95
+ Phase: ${PHASE_INFO}
96
+ Dependencies: ${DEPENDENCY_CHAIN}
97
+ Board: ${PROJECT_BOARD_URL}
98
+ </milestone_context>
99
+
100
+ <summary_structured>
101
+ ${SUMMARY_DATA}
102
+ </summary_structured>
103
+
104
+ <summary_raw>
105
+ ${SUMMARY}
106
+ </summary_raw>
107
+
108
+ <verification>
109
+ ${VERIFICATION}
110
+ </verification>
111
+
112
+ <artifact_warnings>
113
+ ${ARTIFACT_CHECK}
114
+ ${KEYLINK_CHECK}
115
+ </artifact_warnings>
116
+
117
+ <commits>
118
+ ${COMMITS}
119
+ </commits>
120
+
121
+ <cross_refs>
122
+ ${CROSS_REFS}
123
+ </cross_refs>
124
+
125
+ <instructions>
126
+ 1. Build PR title: short, prefixed with fix:/feat:/refactor: based on issue labels. Under 70 characters.
127
+
128
+ 2. Build PR body using this EXACT structure (fill in from data above):
129
+
130
+ ## Summary
131
+ - 2-4 bullets of what was built and why (use one_liner from summary_structured if available)
132
+
133
+ Closes #${ISSUE_NUMBER}
134
+
135
+ ## Milestone Context
136
+ - **Milestone:** ${MILESTONE_TITLE}
137
+ - **Phase:** ${PHASE_INFO}
138
+ - **Dependencies:** ${DEPENDENCY_CHAIN}
139
+ (Skip this section entirely if MILESTONE_TITLE is empty)
140
+
141
+ ## Changes
142
+ - File-level changes grouped by module (use key_files from summary_structured)
143
+
144
+ ## Test Plan
145
+ - Verification checklist from VERIFICATION artifact
146
+
147
+ ## Cross-References
148
+ - ${CROSS_REFS entries as bullet points}
149
+ (Skip if no cross-refs)
150
+
151
+ <details>
152
+ <summary>GSD Progress</summary>
153
+
154
+ ${PROGRESS_TABLE}
155
+ </details>
156
+ (Skip if PROGRESS_TABLE is empty)
157
+
158
+ 3. Create PR: gh pr create --title '<title>' --base '${DEFAULT_BRANCH}' --head '${BRANCH_NAME}' --body '<body>'
159
+ 4. Post testing procedures as separate PR comment: gh pr comment <pr_number> --body '<testing>'
160
+ 5. Return: PR number, PR URL
161
+ </instructions>
162
+ ",
163
+ subagent_type="general-purpose",
164
+ description="Create PR for #${ISSUE_NUMBER}"
165
+ )
166
+ ```
167
+
168
+ Parse PR number and URL from agent response.
169
+
170
+ Update state (at `${REPO_ROOT}/.mgw/active/`):
171
+ - linked_pr = PR number
172
+ - pipeline_stage = "pr-created"
173
+
174
+ Add cross-ref (at `${REPO_ROOT}/.mgw/cross-refs.json`): issue → PR.
175
+ </step>
176
+
177
+ <step name="cleanup_and_complete">
178
+ **Clean up worktree, post completion, and prompt sync:**
179
+
180
+ Return to main repo and remove worktree (branch persists for PR):
181
+ ```bash
182
+ cd "${REPO_ROOT}"
183
+ git worktree remove "${WORKTREE_DIR}" 2>/dev/null
184
+ rmdir "${REPO_ROOT}/.worktrees/issue" 2>/dev/null
185
+ rmdir "${REPO_ROOT}/.worktrees" 2>/dev/null
186
+ ```
187
+
188
+ Clear MGW labels at completion:
189
+ ```bash
190
+ # Pass empty string — removes all mgw: labels without applying a new one
191
+ remove_mgw_labels_and_apply ${ISSUE_NUMBER} ""
192
+ ```
193
+
194
+ Post-completion label reconciliation:
195
+ ```bash
196
+ # Post-completion label reconciliation — verify no stray MGW labels remain
197
+ LIVE_LABELS=$(gh issue view ${ISSUE_NUMBER} --json labels --jq '[.labels[].name]' 2>/dev/null || echo "[]")
198
+ STRAY_MGW=$(echo "$LIVE_LABELS" | python3 -c "
199
+ import json, sys
200
+ labels = json.load(sys.stdin)
201
+ stray = [l for l in labels if l.startswith('mgw:')]
202
+ print('\n'.join(stray))
203
+ " 2>/dev/null || echo "")
204
+
205
+ if [ -n "$STRAY_MGW" ]; then
206
+ echo "MGW WARNING: unexpected MGW labels still on issue after completion: $STRAY_MGW" >&2
207
+ fi
208
+
209
+ # Sync live labels back to .mgw/active state file
210
+ LIVE_LABELS_LIST=$(gh issue view ${ISSUE_NUMBER} --json labels --jq '[.labels[].name]' 2>/dev/null || echo "[]")
211
+ # Update labels field in ${REPO_ROOT}/.mgw/active/${STATE_FILE} using python3 json patch:
212
+ python3 -c "
213
+ import json, sys
214
+ path = sys.argv[1]
215
+ live = json.loads(sys.argv[2])
216
+ with open(path) as f: state = json.load(f)
217
+ state['labels'] = live
218
+ with open(path, 'w') as f: json.dump(state, f, indent=2)
219
+ " "${REPO_ROOT}/.mgw/active/${STATE_FILE}" "$LIVE_LABELS_LIST" 2>/dev/null || true
220
+ ```
221
+
222
+ Extract one-liner summary for concise comment:
223
+ ```bash
224
+ ONE_LINER=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs summary-extract "${gsd_artifacts_path}/*SUMMARY*" --fields one_liner --raw 2>/dev/null || echo "")
225
+ ```
226
+
227
+ Post structured PR-ready comment directly (no sub-agent — guarantees it happens):
228
+
229
+ ```bash
230
+ DONE_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'))}")
231
+
232
+ PR_READY_BODY=$(cat <<COMMENTEOF
233
+ > **MGW** · \`pr-ready\` · ${DONE_TIMESTAMP}
234
+ > ${MILESTONE_CONTEXT}
235
+
236
+ ### PR Ready
237
+
238
+ **PR #${PR_NUMBER}** — ${PR_URL}
239
+
240
+ ${ONE_LINER}
241
+
242
+ Testing procedures posted on the PR.
243
+ This issue will auto-close when the PR is merged.
244
+
245
+ <details>
246
+ <summary>Pipeline Summary</summary>
247
+
248
+ | Stage | Status |
249
+ |-------|--------|
250
+ | Triage | ✓ |
251
+ | Planning | ✓ |
252
+ | Execution | ✓ |
253
+ | PR Creation | ✓ |
254
+
255
+ </details>
256
+ COMMENTEOF
257
+ )
258
+
259
+ gh issue comment ${ISSUE_NUMBER} --body "$PR_READY_BODY" 2>/dev/null || true
260
+ ```
261
+
262
+ Update pipeline_stage to "done" (at `${REPO_ROOT}/.mgw/active/`).
263
+
264
+ Report to user:
265
+ ```
266
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
267
+ MGW ► PIPELINE COMPLETE
268
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
269
+
270
+ Issue: #${ISSUE_NUMBER} — ${issue_title}
271
+ Route: ${gsd_route}
272
+ PR: #${PR_NUMBER} — ${PR_URL}
273
+ Branch: ${BRANCH_NAME} (worktree cleaned up)
274
+
275
+ Status comments posted. PR includes testing procedures.
276
+ Issue will auto-close on merge.
277
+
278
+ Next:
279
+ → Review the PR, then merge
280
+ → After merge: /mgw:sync to archive state and clean up branches
281
+ ```
282
+ </step>