@snipcodeit/mgw 0.1.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/LICENSE +21 -0
- package/README.md +517 -0
- package/bin/mgw-install.cjs +81 -0
- package/commands/ask.md +416 -0
- package/commands/assign.md +333 -0
- package/commands/board.md +1679 -0
- package/commands/help.md +119 -0
- package/commands/init.md +250 -0
- package/commands/issue.md +469 -0
- package/commands/issues.md +109 -0
- package/commands/link.md +122 -0
- package/commands/milestone.md +952 -0
- package/commands/next.md +375 -0
- package/commands/pr.md +277 -0
- package/commands/project.md +1801 -0
- package/commands/review.md +260 -0
- package/commands/roadmap.md +489 -0
- package/commands/run.md +1282 -0
- package/commands/status.md +526 -0
- package/commands/sync.md +243 -0
- package/commands/update.md +282 -0
- package/commands/workflows/board-sync.md +404 -0
- package/commands/workflows/github.md +385 -0
- package/commands/workflows/gsd.md +377 -0
- package/commands/workflows/state.md +412 -0
- package/commands/workflows/validation.md +144 -0
- package/dist/bin/mgw.cjs +291 -0
- package/dist/claude-Vp9qvImH.cjs +466 -0
- package/dist/lib/index.cjs +395 -0
- package/package.json +51 -0
- package/templates/schema.json +164 -0
- package/templates/vision-brief-schema.json +98 -0
package/commands/sync.md
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mgw:sync
|
|
3
|
+
description: Reconcile local .mgw/ state with GitHub — archive completed, flag drift
|
|
4
|
+
argument-hint: ""
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- Edit
|
|
10
|
+
- AskUserQuestion
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<objective>
|
|
14
|
+
Catch drift between GitHub and local .mgw/ state. For each active issue, checks
|
|
15
|
+
if the GitHub issue is still open, if linked PRs were merged/closed, and if tracked
|
|
16
|
+
branches still exist. Moves completed items to .mgw/completed/, cleans up branches
|
|
17
|
+
and lingering worktrees, flags inconsistencies.
|
|
18
|
+
|
|
19
|
+
Run periodically or when starting a new session to get a clean view.
|
|
20
|
+
</objective>
|
|
21
|
+
|
|
22
|
+
<execution_context>
|
|
23
|
+
@~/.claude/commands/mgw/workflows/state.md
|
|
24
|
+
@~/.claude/commands/mgw/workflows/github.md
|
|
25
|
+
@~/.claude/commands/mgw/workflows/gsd.md
|
|
26
|
+
@~/.claude/commands/mgw/workflows/validation.md
|
|
27
|
+
</execution_context>
|
|
28
|
+
|
|
29
|
+
<process>
|
|
30
|
+
|
|
31
|
+
<step name="scan_active">
|
|
32
|
+
**Scan all active issue states:**
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
ls .mgw/active/*.json 2>/dev/null
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If no active issues → "No active MGW issues. Nothing to sync."
|
|
39
|
+
|
|
40
|
+
For each file, load the JSON state.
|
|
41
|
+
</step>
|
|
42
|
+
|
|
43
|
+
<step name="check_each">
|
|
44
|
+
**For each active issue, check GitHub state:**
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Issue state
|
|
48
|
+
gh issue view ${NUMBER} --json state,closed -q '{state: .state, closed: .closed}'
|
|
49
|
+
|
|
50
|
+
# PR state (if linked_pr exists)
|
|
51
|
+
gh pr view ${PR_NUMBER} --json state,mergedAt -q '{state: .state, mergedAt: .mergedAt}' 2>/dev/null
|
|
52
|
+
|
|
53
|
+
# Branch existence
|
|
54
|
+
git branch --list ${BRANCH_NAME} | grep -q . && echo "local" || echo "no-local"
|
|
55
|
+
git ls-remote --heads origin ${BRANCH_NAME} | grep -q . && echo "remote" || echo "no-remote"
|
|
56
|
+
|
|
57
|
+
# Worktree existence
|
|
58
|
+
git worktree list | grep -q "${BRANCH_NAME}" && echo "worktree" || echo "no-worktree"
|
|
59
|
+
|
|
60
|
+
# Comment delta (detect unreviewed comments since triage)
|
|
61
|
+
CURRENT_COMMENTS=$(gh issue view ${NUMBER} --json comments --jq '.comments | length' 2>/dev/null || echo "0")
|
|
62
|
+
STORED_COMMENTS="${triage.last_comment_count}" # From state file, may be null/missing
|
|
63
|
+
if [ -n "$STORED_COMMENTS" ] && [ "$STORED_COMMENTS" != "null" ]; then
|
|
64
|
+
COMMENT_DELTA=$(($CURRENT_COMMENTS - $STORED_COMMENTS))
|
|
65
|
+
else
|
|
66
|
+
COMMENT_DELTA=0 # No baseline — skip comment drift
|
|
67
|
+
fi
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**GSD milestone consistency check (maps-to links):**
|
|
71
|
+
|
|
72
|
+
Read all maps-to links from .mgw/cross-refs.json:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
MAPS_TO_LINKS=$(python3 -c "
|
|
76
|
+
import json
|
|
77
|
+
with open('.mgw/cross-refs.json') as f:
|
|
78
|
+
data = json.load(f)
|
|
79
|
+
links = data.get('links', [])
|
|
80
|
+
maps_to = [l for l in links if l.get('type') == 'maps-to']
|
|
81
|
+
print(json.dumps(maps_to))
|
|
82
|
+
")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For each maps-to link (format: { "a": "milestone:N", "b": "gsd-milestone:id", "type": "maps-to" }):
|
|
86
|
+
1. Extract the GitHub milestone number from "a" (parse "milestone:N")
|
|
87
|
+
2. Extract the GSD milestone ID from "b" (parse "gsd-milestone:id")
|
|
88
|
+
3. Check if this GSD milestone ID appears in either:
|
|
89
|
+
- .planning/ROADMAP.md header (active milestone)
|
|
90
|
+
- .planning/MILESTONES.md (archived milestones)
|
|
91
|
+
4. If found in neither: flag as inconsistent
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Check each maps-to link
|
|
95
|
+
echo "$MAPS_TO_LINKS" | python3 -c "
|
|
96
|
+
import json, sys, os
|
|
97
|
+
|
|
98
|
+
links = json.load(sys.stdin)
|
|
99
|
+
inconsistent = []
|
|
100
|
+
|
|
101
|
+
for link in links:
|
|
102
|
+
a = link.get('a', '')
|
|
103
|
+
b = link.get('b', '')
|
|
104
|
+
|
|
105
|
+
if not a.startswith('milestone:') or not b.startswith('gsd-milestone:'):
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
github_num = a.split(':')[1]
|
|
109
|
+
gsd_id = b.split(':', 1)[1]
|
|
110
|
+
|
|
111
|
+
found = False
|
|
112
|
+
|
|
113
|
+
# Check ROADMAP.md
|
|
114
|
+
if os.path.exists('.planning/ROADMAP.md'):
|
|
115
|
+
with open('.planning/ROADMAP.md') as f:
|
|
116
|
+
content = f.read()
|
|
117
|
+
if gsd_id in content:
|
|
118
|
+
found = True
|
|
119
|
+
|
|
120
|
+
# Check MILESTONES.md
|
|
121
|
+
if not found and os.path.exists('.planning/MILESTONES.md'):
|
|
122
|
+
with open('.planning/MILESTONES.md') as f:
|
|
123
|
+
content = f.read()
|
|
124
|
+
if gsd_id in content:
|
|
125
|
+
found = True
|
|
126
|
+
|
|
127
|
+
if not found:
|
|
128
|
+
inconsistent.append({'github_milestone': github_num, 'gsd_id': gsd_id})
|
|
129
|
+
|
|
130
|
+
for i in inconsistent:
|
|
131
|
+
print(f\"WARN: GitHub milestone #{i['github_milestone']} maps to GSD milestone '{i['gsd_id']}' which was not found in .planning/\")
|
|
132
|
+
|
|
133
|
+
if not inconsistent:
|
|
134
|
+
print('GSD milestone links: all consistent')
|
|
135
|
+
"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Classify each issue into:
|
|
139
|
+
- **Completed:** Issue closed AND (PR merged OR no PR expected)
|
|
140
|
+
- **Stale:** PR merged but issue still open (auto-close missed)
|
|
141
|
+
- **Orphaned:** Branch deleted but work incomplete
|
|
142
|
+
- **Active:** Still in progress, everything consistent
|
|
143
|
+
- **Drift:** State file says one thing, GitHub says another
|
|
144
|
+
- **Unreviewed comments:** COMMENT_DELTA > 0 — new comments posted since triage that haven't been classified
|
|
145
|
+
</step>
|
|
146
|
+
|
|
147
|
+
<step name="health_check">
|
|
148
|
+
**GSD health check (if .planning/ exists):**
|
|
149
|
+
|
|
150
|
+
For repos with GSD initialized, run a health check and include in the sync report:
|
|
151
|
+
```bash
|
|
152
|
+
if [ -d ".planning" ]; then
|
|
153
|
+
HEALTH=$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs validate health 2>/dev/null || echo '{"status":"unknown"}')
|
|
154
|
+
fi
|
|
155
|
+
```
|
|
156
|
+
This is read-only and additive — health status is included in the sync summary but does not block any reconciliation actions.
|
|
157
|
+
</step>
|
|
158
|
+
|
|
159
|
+
<step name="reconcile">
|
|
160
|
+
**Take action per classification:**
|
|
161
|
+
|
|
162
|
+
| Classification | Action |
|
|
163
|
+
|---------------|--------|
|
|
164
|
+
| Completed | Move state file to .mgw/completed/, clean up branch + worktree |
|
|
165
|
+
| Stale | Report: "Issue #N still open but PR #M merged — close issue?" |
|
|
166
|
+
| Orphaned | Report: "Branch deleted for #N but issue still open" |
|
|
167
|
+
| Active | No action, include in summary |
|
|
168
|
+
| Drift | Report specific mismatch, offer to update state |
|
|
169
|
+
|
|
170
|
+
**Branch cleanup for completed items:**
|
|
171
|
+
|
|
172
|
+
For each completed issue with linked branches:
|
|
173
|
+
```bash
|
|
174
|
+
# Remove any lingering worktree first
|
|
175
|
+
WORKTREE_DIR=".worktrees/${BRANCH_NAME}"
|
|
176
|
+
if [ -d "${WORKTREE_DIR}" ]; then
|
|
177
|
+
git worktree remove "${WORKTREE_DIR}" 2>/dev/null
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Clean up empty worktree parent dirs
|
|
181
|
+
rmdir .worktrees/issue 2>/dev/null
|
|
182
|
+
rmdir .worktrees 2>/dev/null
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Ask user before deleting branches:
|
|
186
|
+
```
|
|
187
|
+
AskUserQuestion(
|
|
188
|
+
header: "Branch Cleanup",
|
|
189
|
+
question: "Delete merged branches for completed issues?",
|
|
190
|
+
options: [
|
|
191
|
+
{ label: "Delete all", description: "Remove local + remote branches for all completed issues" },
|
|
192
|
+
{ label: "Local only", description: "Remove local branches, keep remote" },
|
|
193
|
+
{ label: "Skip", description: "Keep all branches" }
|
|
194
|
+
]
|
|
195
|
+
)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
If user approves:
|
|
199
|
+
```bash
|
|
200
|
+
# Delete local branch
|
|
201
|
+
git branch -d ${BRANCH_NAME} 2>/dev/null
|
|
202
|
+
|
|
203
|
+
# Delete remote branch (if user chose "Delete all")
|
|
204
|
+
git push origin --delete ${BRANCH_NAME} 2>/dev/null
|
|
205
|
+
```
|
|
206
|
+
</step>
|
|
207
|
+
|
|
208
|
+
<step name="report">
|
|
209
|
+
**Present sync summary:**
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
213
|
+
MGW ► SYNC
|
|
214
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
215
|
+
|
|
216
|
+
Active: ${active_count} issues in progress
|
|
217
|
+
Completed: ${completed_count} archived
|
|
218
|
+
Stale: ${stale_count} need attention
|
|
219
|
+
Orphaned: ${orphaned_count} need attention
|
|
220
|
+
Comments: ${comment_drift_count} issues with unreviewed comments
|
|
221
|
+
Branches: ${deleted_count} cleaned up
|
|
222
|
+
${HEALTH ? 'GSD Health: ' + HEALTH.status : ''}
|
|
223
|
+
|
|
224
|
+
${details_for_each_non_active_item}
|
|
225
|
+
${comment_drift_details ? 'Unreviewed comments:\n' + comment_drift_details : ''}
|
|
226
|
+
${gsd_milestone_consistency ? 'GSD Milestone Links:\n' + gsd_milestone_consistency : ''}
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
</step>
|
|
230
|
+
|
|
231
|
+
</process>
|
|
232
|
+
|
|
233
|
+
<success_criteria>
|
|
234
|
+
- [ ] All .mgw/active/ files scanned
|
|
235
|
+
- [ ] GitHub state checked for each issue, PR, branch
|
|
236
|
+
- [ ] Comment delta checked for each active issue
|
|
237
|
+
- [ ] GSD milestone consistency checked for all maps-to links
|
|
238
|
+
- [ ] Completed items moved to .mgw/completed/
|
|
239
|
+
- [ ] Lingering worktrees cleaned up for completed items
|
|
240
|
+
- [ ] Branch deletion offered for completed items
|
|
241
|
+
- [ ] Stale/orphaned/drift items flagged (including comment drift and milestone inconsistencies)
|
|
242
|
+
- [ ] Summary presented
|
|
243
|
+
</success_criteria>
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mgw:update
|
|
3
|
+
description: Post a structured status comment on a GitHub issue
|
|
4
|
+
argument-hint: "<issue-number> [message]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- Edit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<objective>
|
|
13
|
+
Post professional, structured status comments on GitHub issues. These comments serve
|
|
14
|
+
as a machine-readable audit trail — MGW reads them back for resume detection, sync,
|
|
15
|
+
and progress tracking.
|
|
16
|
+
|
|
17
|
+
Called automatically by mgw:run at every pipeline checkpoint, or manually with a custom
|
|
18
|
+
message. Each comment follows a consistent format with metadata headers and collapsible
|
|
19
|
+
detail sections.
|
|
20
|
+
|
|
21
|
+
When called without a message, auto-detects update type from .mgw/ pipeline_stage.
|
|
22
|
+
When called with a message, posts that as a custom update.
|
|
23
|
+
|
|
24
|
+
Appends cross-references from .mgw/cross-refs.json if related work exists.
|
|
25
|
+
Logs comment ID in state file to prevent duplicates.
|
|
26
|
+
</objective>
|
|
27
|
+
|
|
28
|
+
<execution_context>
|
|
29
|
+
@~/.claude/commands/mgw/workflows/state.md
|
|
30
|
+
@~/.claude/commands/mgw/workflows/github.md
|
|
31
|
+
</execution_context>
|
|
32
|
+
|
|
33
|
+
<context>
|
|
34
|
+
$ARGUMENTS — expects: <issue-number> [optional message]
|
|
35
|
+
</context>
|
|
36
|
+
|
|
37
|
+
<process>
|
|
38
|
+
|
|
39
|
+
<step name="parse_args">
|
|
40
|
+
**Parse issue number and optional message:**
|
|
41
|
+
|
|
42
|
+
First token: issue number (required).
|
|
43
|
+
Remaining tokens: custom message (optional).
|
|
44
|
+
|
|
45
|
+
If no issue number, check .mgw/active/ for exactly one active issue. If exactly one, use it. If zero or multiple, prompt:
|
|
46
|
+
```
|
|
47
|
+
AskUserQuestion(
|
|
48
|
+
header: "Which Issue?",
|
|
49
|
+
question: "Which issue number do you want to update?",
|
|
50
|
+
followUp: null
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
</step>
|
|
54
|
+
|
|
55
|
+
<step name="read_state">
|
|
56
|
+
**Read issue state:**
|
|
57
|
+
|
|
58
|
+
Find state file: `.mgw/active/${ISSUE_NUMBER}-*.json`
|
|
59
|
+
|
|
60
|
+
If not found → error: "No active MGW state for issue #${ISSUE_NUMBER}. Run /mgw:issue ${ISSUE_NUMBER} first."
|
|
61
|
+
|
|
62
|
+
Load state as $STATE.
|
|
63
|
+
|
|
64
|
+
Also load project.json if it exists (for milestone/phase context):
|
|
65
|
+
```bash
|
|
66
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
67
|
+
MGW_DIR="${REPO_ROOT}/.mgw"
|
|
68
|
+
PROJECT_JSON=""
|
|
69
|
+
if [ -f "${MGW_DIR}/project.json" ]; then
|
|
70
|
+
PROJECT_JSON=$(cat "${MGW_DIR}/project.json")
|
|
71
|
+
fi
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Extract milestone and phase context:
|
|
75
|
+
```bash
|
|
76
|
+
if [ -n "$PROJECT_JSON" ]; then
|
|
77
|
+
MILESTONE_CONTEXT=$(echo "$PROJECT_JSON" | python3 -c "
|
|
78
|
+
import json, sys
|
|
79
|
+
p = json.load(sys.stdin)
|
|
80
|
+
for m in p['milestones']:
|
|
81
|
+
for i in m.get('issues', []):
|
|
82
|
+
if i.get('github_number') == ${ISSUE_NUMBER}:
|
|
83
|
+
print(f\"Milestone: {m['name']} | Phase {i['phase_number']}: {i['phase_name']}\")
|
|
84
|
+
break
|
|
85
|
+
" 2>/dev/null || echo "")
|
|
86
|
+
fi
|
|
87
|
+
```
|
|
88
|
+
</step>
|
|
89
|
+
|
|
90
|
+
<step name="build_comment">
|
|
91
|
+
**Build comment body:**
|
|
92
|
+
|
|
93
|
+
If custom message provided → use it wrapped in the standard format:
|
|
94
|
+
```markdown
|
|
95
|
+
> **MGW** · `status-update` · ${timestamp}
|
|
96
|
+
> ${MILESTONE_CONTEXT}
|
|
97
|
+
|
|
98
|
+
${custom_message}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If no custom message → auto-detect from pipeline_stage and build structured comment:
|
|
102
|
+
|
|
103
|
+
**All comments follow this format:**
|
|
104
|
+
```markdown
|
|
105
|
+
> **MGW** · `${stage_label}` · ${timestamp}
|
|
106
|
+
> ${MILESTONE_CONTEXT}
|
|
107
|
+
|
|
108
|
+
### ${Stage Title}
|
|
109
|
+
|
|
110
|
+
${Stage-specific body with structured data}
|
|
111
|
+
|
|
112
|
+
<details>
|
|
113
|
+
<summary>Pipeline State</summary>
|
|
114
|
+
|
|
115
|
+
| Field | Value |
|
|
116
|
+
|-------|-------|
|
|
117
|
+
| Stage | `${pipeline_stage}` |
|
|
118
|
+
| Route | `${gsd_route}` |
|
|
119
|
+
| Branch | `${branch_name}` |
|
|
120
|
+
| Duration | ${elapsed} |
|
|
121
|
+
|
|
122
|
+
</details>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Stage-specific templates:**
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
**`triaged`** — Posted after triage analysis completes:
|
|
130
|
+
```markdown
|
|
131
|
+
> **MGW** · `triage-complete` · ${timestamp}
|
|
132
|
+
> ${MILESTONE_CONTEXT}
|
|
133
|
+
|
|
134
|
+
### Triage Complete
|
|
135
|
+
|
|
136
|
+
| | |
|
|
137
|
+
|---|---|
|
|
138
|
+
| **Scope** | ${scope_size} — ${file_count} files across ${system_list} |
|
|
139
|
+
| **Validity** | ${validity_status} |
|
|
140
|
+
| **Security** | ${security_risk} |
|
|
141
|
+
| **Route** | \`${gsd_route}\` — ${route_reasoning} |
|
|
142
|
+
| **Conflicts** | ${conflicts_or_none} |
|
|
143
|
+
|
|
144
|
+
Work begins on branch \`${branch_name}\`.
|
|
145
|
+
|
|
146
|
+
<details>
|
|
147
|
+
<summary>Affected Files</summary>
|
|
148
|
+
|
|
149
|
+
${file_list_as_bullet_points}
|
|
150
|
+
|
|
151
|
+
</details>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
**`planning`** — Posted after GSD planner completes:
|
|
157
|
+
```markdown
|
|
158
|
+
> **MGW** · `planning-complete` · ${timestamp}
|
|
159
|
+
> ${MILESTONE_CONTEXT}
|
|
160
|
+
|
|
161
|
+
### Planning Complete
|
|
162
|
+
|
|
163
|
+
Plan created via \`${gsd_route}\` with ${task_count} task(s).
|
|
164
|
+
|
|
165
|
+
| Task | Files | Action |
|
|
166
|
+
|------|-------|--------|
|
|
167
|
+
${task_table_from_plan}
|
|
168
|
+
|
|
169
|
+
Execution starting.
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
**`executing`** — Posted during/after GSD executor:
|
|
175
|
+
```markdown
|
|
176
|
+
> **MGW** · `execution-complete` · ${timestamp}
|
|
177
|
+
> ${MILESTONE_CONTEXT}
|
|
178
|
+
|
|
179
|
+
### Execution Complete
|
|
180
|
+
|
|
181
|
+
${commit_count} atomic commit(s) on branch \`${branch_name}\`.
|
|
182
|
+
|
|
183
|
+
**Changes:**
|
|
184
|
+
${file_changes_grouped_by_module}
|
|
185
|
+
|
|
186
|
+
**Tests:** ${test_status}
|
|
187
|
+
|
|
188
|
+
Preparing pull request.
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
**`verifying`** — Posted after GSD verifier (--full mode only):
|
|
194
|
+
```markdown
|
|
195
|
+
> **MGW** · `verification` · ${timestamp}
|
|
196
|
+
> ${MILESTONE_CONTEXT}
|
|
197
|
+
|
|
198
|
+
### Verification
|
|
199
|
+
|
|
200
|
+
${must_have_count}/${must_have_total} must-haves passed.
|
|
201
|
+
|
|
202
|
+
| Check | Status |
|
|
203
|
+
|-------|--------|
|
|
204
|
+
${verification_table}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
**`pr-created`** — Posted after PR is created:
|
|
210
|
+
```markdown
|
|
211
|
+
> **MGW** · `pr-ready` · ${timestamp}
|
|
212
|
+
> ${MILESTONE_CONTEXT}
|
|
213
|
+
|
|
214
|
+
### PR Ready
|
|
215
|
+
|
|
216
|
+
**PR #${pr_number}** — [${pr_title}](${pr_url})
|
|
217
|
+
|
|
218
|
+
Testing procedures posted on the PR.
|
|
219
|
+
This issue will auto-close when the PR is merged.
|
|
220
|
+
|
|
221
|
+
<details>
|
|
222
|
+
<summary>Pipeline Summary</summary>
|
|
223
|
+
|
|
224
|
+
| Stage | Duration | Status |
|
|
225
|
+
|-------|----------|--------|
|
|
226
|
+
| Triage | ${triage_duration} | ✓ |
|
|
227
|
+
| Planning | ${planning_duration} | ✓ |
|
|
228
|
+
| Execution | ${execution_duration} | ✓ |
|
|
229
|
+
${verification_row}
|
|
230
|
+
| PR Creation | ${pr_duration} | ✓ |
|
|
231
|
+
| **Total** | **${total_duration}** | |
|
|
232
|
+
|
|
233
|
+
</details>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
**Append cross-references** if .mgw/cross-refs.json has links for this issue:
|
|
239
|
+
```markdown
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
<sub>Related: ${cross_ref_list} · Managed by [MGW](https://github.com/snipcodeit/mgw)</sub>
|
|
243
|
+
```
|
|
244
|
+
</step>
|
|
245
|
+
|
|
246
|
+
<step name="post_comment">
|
|
247
|
+
**Post comment and log:**
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
gh issue comment $ISSUE_NUMBER --body "$COMMENT_BODY"
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Capture comment URL from output.
|
|
254
|
+
|
|
255
|
+
Update state file: append to comments_posted array:
|
|
256
|
+
```json
|
|
257
|
+
{ "type": "${update_type}", "timestamp": "$(node ~/.claude/get-shit-done/bin/gsd-tools.cjs current-timestamp --raw)", "url": "${comment_url}" }
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Write updated state back to `.mgw/active/${filename}.json`.
|
|
261
|
+
</step>
|
|
262
|
+
|
|
263
|
+
<step name="report">
|
|
264
|
+
**Report to user:**
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
Posted ${update_type} comment on #${ISSUE_NUMBER}: ${comment_url}
|
|
268
|
+
```
|
|
269
|
+
</step>
|
|
270
|
+
|
|
271
|
+
</process>
|
|
272
|
+
|
|
273
|
+
<success_criteria>
|
|
274
|
+
- [ ] Issue number parsed from args or auto-detected from single active issue
|
|
275
|
+
- [ ] State file read from .mgw/active/
|
|
276
|
+
- [ ] Milestone/phase context loaded from project.json if available
|
|
277
|
+
- [ ] Comment body built (auto-detected type or custom message)
|
|
278
|
+
- [ ] Comment follows structured format with metadata header
|
|
279
|
+
- [ ] Cross-references appended if present
|
|
280
|
+
- [ ] Comment posted via gh issue comment
|
|
281
|
+
- [ ] Comment ID logged in state file (no duplicates)
|
|
282
|
+
</success_criteria>
|