@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/ask.md
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mgw:ask
|
|
3
|
+
description: Route a question/observation — classify as in-scope, adjacent, separate, duplicate, or out-of-scope
|
|
4
|
+
argument-hint: "<question>"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash
|
|
7
|
+
- Read
|
|
8
|
+
- Task
|
|
9
|
+
- AskUserQuestion
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<objective>
|
|
13
|
+
During milestone execution, observations arise that need classification: is this
|
|
14
|
+
in-scope for the current issue, adjacent to a different issue, a separate concern,
|
|
15
|
+
a duplicate, or out-of-scope entirely?
|
|
16
|
+
|
|
17
|
+
/mgw:ask spawns a general-purpose agent with full project context (milestone, all
|
|
18
|
+
issues, active state, recent git diff) that classifies the question and recommends
|
|
19
|
+
an action. Read-only for the orchestrator — the agent reads state and code, MGW
|
|
20
|
+
presents the structured result.
|
|
21
|
+
</objective>
|
|
22
|
+
|
|
23
|
+
<execution_context>
|
|
24
|
+
@~/.claude/commands/mgw/workflows/state.md
|
|
25
|
+
@~/.claude/commands/mgw/workflows/github.md
|
|
26
|
+
@~/.claude/commands/mgw/workflows/gsd.md
|
|
27
|
+
@~/.claude/commands/mgw/workflows/validation.md
|
|
28
|
+
</execution_context>
|
|
29
|
+
|
|
30
|
+
<context>
|
|
31
|
+
Question text: $ARGUMENTS
|
|
32
|
+
|
|
33
|
+
Active issues context: .mgw/active/ (current work state)
|
|
34
|
+
Project context: .mgw/project.json (milestone + all issues)
|
|
35
|
+
Capability context: commands/*.md front matter (name + description per command)
|
|
36
|
+
Live state: open PRs via gh pr list, milestones via gh api
|
|
37
|
+
</context>
|
|
38
|
+
|
|
39
|
+
<process>
|
|
40
|
+
|
|
41
|
+
<step name="validate_input">
|
|
42
|
+
**Validate question text provided:**
|
|
43
|
+
|
|
44
|
+
Parse $ARGUMENTS for the question text. If missing or empty:
|
|
45
|
+
```
|
|
46
|
+
AskUserQuestion(
|
|
47
|
+
header: "Question Required",
|
|
48
|
+
question: "What question or observation do you want to classify?",
|
|
49
|
+
followUp: "Enter a question or observation (e.g., 'The slug generation doesn't handle unicode characters')"
|
|
50
|
+
)
|
|
51
|
+
```
|
|
52
|
+
Store as $QUESTION.
|
|
53
|
+
</step>
|
|
54
|
+
|
|
55
|
+
<step name="load_project_context">
|
|
56
|
+
**Load project.json for milestone and issue context:**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
60
|
+
MGW_DIR="${REPO_ROOT}/.mgw"
|
|
61
|
+
|
|
62
|
+
# Load project state
|
|
63
|
+
PROJECT_JSON=""
|
|
64
|
+
MILESTONE_CONTEXT=""
|
|
65
|
+
ALL_ISSUES_CONTEXT=""
|
|
66
|
+
|
|
67
|
+
if [ -f "${MGW_DIR}/project.json" ]; then
|
|
68
|
+
PROJECT_JSON=$(cat "${MGW_DIR}/project.json")
|
|
69
|
+
|
|
70
|
+
# Extract current milestone info
|
|
71
|
+
MILESTONE_CONTEXT=$(echo "$PROJECT_JSON" | python3 -c "
|
|
72
|
+
import json, sys
|
|
73
|
+
p = json.load(sys.stdin)
|
|
74
|
+
idx = p['current_milestone'] - 1
|
|
75
|
+
if idx < len(p['milestones']):
|
|
76
|
+
m = p['milestones'][idx]
|
|
77
|
+
print(f\"Milestone: {m['name']}\")
|
|
78
|
+
if m.get('description'):
|
|
79
|
+
print(f\"Description: {m['description']}\")
|
|
80
|
+
else:
|
|
81
|
+
print('No active milestone')
|
|
82
|
+
" 2>/dev/null || echo "No project initialized")
|
|
83
|
+
|
|
84
|
+
# Extract all issues in current milestone with titles, bodies, scopes, labels
|
|
85
|
+
ALL_ISSUES_CONTEXT=$(echo "$PROJECT_JSON" | python3 -c "
|
|
86
|
+
import json, sys
|
|
87
|
+
p = json.load(sys.stdin)
|
|
88
|
+
idx = p['current_milestone'] - 1
|
|
89
|
+
if idx >= len(p['milestones']):
|
|
90
|
+
print('No issues found')
|
|
91
|
+
sys.exit(0)
|
|
92
|
+
m = p['milestones'][idx]
|
|
93
|
+
for issue in m.get('issues', []):
|
|
94
|
+
num = issue.get('github_number', '?')
|
|
95
|
+
title = issue.get('title', 'untitled')
|
|
96
|
+
stage = issue.get('pipeline_stage', 'new')
|
|
97
|
+
labels = ', '.join(issue.get('labels', []))
|
|
98
|
+
phase = issue.get('phase_name', '')
|
|
99
|
+
scope = issue.get('scope', '')
|
|
100
|
+
print(f'#{num} [{stage}] {title}')
|
|
101
|
+
if phase:
|
|
102
|
+
print(f' Phase: {phase}')
|
|
103
|
+
if labels:
|
|
104
|
+
print(f' Labels: {labels}')
|
|
105
|
+
if scope:
|
|
106
|
+
print(f' Scope: {scope}')
|
|
107
|
+
print()
|
|
108
|
+
" 2>/dev/null || echo "")
|
|
109
|
+
else
|
|
110
|
+
MILESTONE_CONTEXT="No project initialized"
|
|
111
|
+
ALL_ISSUES_CONTEXT=""
|
|
112
|
+
fi
|
|
113
|
+
```
|
|
114
|
+
</step>
|
|
115
|
+
|
|
116
|
+
<step name="load_capability_context">
|
|
117
|
+
**Load MGW command surface, open PRs, and live milestones:**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Extract name + description from each command's front matter
|
|
121
|
+
COMMAND_SURFACE=""
|
|
122
|
+
COMMANDS_DIR="${REPO_ROOT}/commands"
|
|
123
|
+
for f in "${COMMANDS_DIR}"/*.md; do
|
|
124
|
+
CMD_NAME=$(grep -m1 "^name:" "$f" 2>/dev/null | sed 's/^name:[[:space:]]*//')
|
|
125
|
+
CMD_DESC=$(grep -m1 "^description:" "$f" 2>/dev/null | sed 's/^description:[[:space:]]*//')
|
|
126
|
+
if [ -n "$CMD_NAME" ]; then
|
|
127
|
+
COMMAND_SURFACE="${COMMAND_SURFACE}${CMD_NAME}: ${CMD_DESC}\n"
|
|
128
|
+
fi
|
|
129
|
+
done
|
|
130
|
+
|
|
131
|
+
# Fetch open PRs
|
|
132
|
+
PR_CONTEXT=$(gh pr list --state open --json number,title,headRefName \
|
|
133
|
+
--jq '.[] | "#\(.number) [\(.headRefName)] \(.title)"' 2>/dev/null || echo "No open PRs")
|
|
134
|
+
|
|
135
|
+
# Fetch live milestones from GitHub API
|
|
136
|
+
REPO_SLUG=$(gh repo view --json nameWithOwner -q .nameWithOwner 2>/dev/null || echo "")
|
|
137
|
+
MILESTONE_LIST=""
|
|
138
|
+
if [ -n "$REPO_SLUG" ]; then
|
|
139
|
+
MILESTONE_LIST=$(gh api "repos/${REPO_SLUG}/milestones" \
|
|
140
|
+
--jq '.[] | "[\(.state)] \(.title)"' 2>/dev/null || echo "")
|
|
141
|
+
fi
|
|
142
|
+
if [ -z "$MILESTONE_LIST" ]; then
|
|
143
|
+
MILESTONE_LIST="No milestones found (or GitHub API unavailable)"
|
|
144
|
+
fi
|
|
145
|
+
```
|
|
146
|
+
</step>
|
|
147
|
+
|
|
148
|
+
<step name="load_active_state">
|
|
149
|
+
**Load active issue state from .mgw/active/:**
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
ACTIVE_STATE=""
|
|
153
|
+
ACTIVE_ISSUE_NUMBER=""
|
|
154
|
+
|
|
155
|
+
ACTIVE_FILES=$(ls "${MGW_DIR}/active/"*.json 2>/dev/null)
|
|
156
|
+
if [ -n "$ACTIVE_FILES" ]; then
|
|
157
|
+
for f in ${ACTIVE_FILES}; do
|
|
158
|
+
ISSUE_DATA=$(cat "$f")
|
|
159
|
+
ISSUE_NUM=$(echo "$ISSUE_DATA" | python3 -c "import json,sys; print(json.load(sys.stdin).get('issue',{}).get('number','?'))")
|
|
160
|
+
ISSUE_TITLE=$(echo "$ISSUE_DATA" | python3 -c "import json,sys; print(json.load(sys.stdin).get('issue',{}).get('title','untitled'))")
|
|
161
|
+
PIPELINE_STAGE=$(echo "$ISSUE_DATA" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_stage','unknown'))")
|
|
162
|
+
ACTIVE_STATE="${ACTIVE_STATE}#${ISSUE_NUM} [${PIPELINE_STAGE}] ${ISSUE_TITLE}\n"
|
|
163
|
+
# Track the most recently active issue (last in list)
|
|
164
|
+
ACTIVE_ISSUE_NUMBER="$ISSUE_NUM"
|
|
165
|
+
done
|
|
166
|
+
else
|
|
167
|
+
ACTIVE_STATE="No active issues"
|
|
168
|
+
fi
|
|
169
|
+
```
|
|
170
|
+
</step>
|
|
171
|
+
|
|
172
|
+
<step name="gather_git_diff">
|
|
173
|
+
**Gather recent git diff for change context:**
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Get recent changes (staged + unstaged, limited to keep prompt reasonable)
|
|
177
|
+
RECENT_DIFF=$(git diff HEAD --stat 2>/dev/null | head -30 || echo "No changes")
|
|
178
|
+
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
179
|
+
```
|
|
180
|
+
</step>
|
|
181
|
+
|
|
182
|
+
<step name="fetch_issue_details">
|
|
183
|
+
**Fetch full issue bodies from GitHub for matching context:**
|
|
184
|
+
|
|
185
|
+
If project.json has issues, fetch their bodies for the agent to compare against:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
ISSUE_BODIES=""
|
|
189
|
+
if [ -n "$PROJECT_JSON" ]; then
|
|
190
|
+
ISSUE_NUMBERS=$(echo "$PROJECT_JSON" | python3 -c "
|
|
191
|
+
import json, sys
|
|
192
|
+
p = json.load(sys.stdin)
|
|
193
|
+
idx = p['current_milestone'] - 1
|
|
194
|
+
if idx < len(p['milestones']):
|
|
195
|
+
m = p['milestones'][idx]
|
|
196
|
+
for issue in m.get('issues', []):
|
|
197
|
+
print(issue.get('github_number', ''))
|
|
198
|
+
" 2>/dev/null)
|
|
199
|
+
|
|
200
|
+
for NUM in $ISSUE_NUMBERS; do
|
|
201
|
+
if [ -n "$NUM" ]; then
|
|
202
|
+
BODY=$(gh issue view "$NUM" --json number,title,body -q '"\(.number)|\(.title)|\(.body)"' 2>/dev/null || echo "")
|
|
203
|
+
if [ -n "$BODY" ]; then
|
|
204
|
+
ISSUE_BODIES="${ISSUE_BODIES}${BODY}\n---\n"
|
|
205
|
+
fi
|
|
206
|
+
fi
|
|
207
|
+
done
|
|
208
|
+
fi
|
|
209
|
+
```
|
|
210
|
+
</step>
|
|
211
|
+
|
|
212
|
+
<step name="spawn_classification_agent">
|
|
213
|
+
**Spawn general-purpose agent for question classification:**
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
Task(
|
|
217
|
+
prompt="
|
|
218
|
+
<files_to_read>
|
|
219
|
+
- ./CLAUDE.md (Project instructions — if exists, follow all guidelines)
|
|
220
|
+
- .agents/skills/ (Project skills — if dir exists, list skills, read SKILL.md for each, follow relevant rules)
|
|
221
|
+
</files_to_read>
|
|
222
|
+
|
|
223
|
+
You are a question classification agent for the MGW pipeline. Your job is to
|
|
224
|
+
classify a question or observation against the current project context and
|
|
225
|
+
recommend an action.
|
|
226
|
+
|
|
227
|
+
<question>
|
|
228
|
+
${QUESTION}
|
|
229
|
+
</question>
|
|
230
|
+
|
|
231
|
+
<current_milestone>
|
|
232
|
+
${MILESTONE_CONTEXT}
|
|
233
|
+
</current_milestone>
|
|
234
|
+
|
|
235
|
+
<milestone_issues>
|
|
236
|
+
${ALL_ISSUES_CONTEXT}
|
|
237
|
+
</milestone_issues>
|
|
238
|
+
|
|
239
|
+
<issue_bodies>
|
|
240
|
+
${ISSUE_BODIES}
|
|
241
|
+
</issue_bodies>
|
|
242
|
+
|
|
243
|
+
<active_work>
|
|
244
|
+
Current branch: ${CURRENT_BRANCH}
|
|
245
|
+
Active issues in .mgw/:
|
|
246
|
+
${ACTIVE_STATE}
|
|
247
|
+
</active_work>
|
|
248
|
+
|
|
249
|
+
<recent_changes>
|
|
250
|
+
${RECENT_DIFF}
|
|
251
|
+
</recent_changes>
|
|
252
|
+
|
|
253
|
+
<mgw_capabilities>
|
|
254
|
+
## MGW Command Surface
|
|
255
|
+
${COMMAND_SURFACE}
|
|
256
|
+
|
|
257
|
+
## Open Pull Requests
|
|
258
|
+
${PR_CONTEXT}
|
|
259
|
+
|
|
260
|
+
## GitHub Milestones
|
|
261
|
+
${MILESTONE_LIST}
|
|
262
|
+
</mgw_capabilities>
|
|
263
|
+
|
|
264
|
+
<classification_rules>
|
|
265
|
+
|
|
266
|
+
Classify the question into exactly ONE of these categories:
|
|
267
|
+
|
|
268
|
+
| Category | Criteria | Action |
|
|
269
|
+
|----------|----------|--------|
|
|
270
|
+
| In-scope | Directly relates to the current active issue being worked on | Include in current work — no new issue needed |
|
|
271
|
+
| Adjacent | Relates to a DIFFERENT issue in the same milestone | Note it on that issue — suggest posting a comment |
|
|
272
|
+
| Separate | Doesn't match any open issue in the milestone | Suggest filing a new issue with a title |
|
|
273
|
+
| Duplicate | Matches an existing issue (same root cause or fix) | Point to the existing issue |
|
|
274
|
+
| Out-of-scope | Beyond the current milestone entirely | Note for future planning |
|
|
275
|
+
|
|
276
|
+
Decision process:
|
|
277
|
+
1. Read the question carefully
|
|
278
|
+
2. Compare against each issue title, body, and scope in the milestone
|
|
279
|
+
3. Check if it relates to current active work (branch, diff, active state)
|
|
280
|
+
4. Look for keyword/concept overlap with existing issues
|
|
281
|
+
5. If no match, determine if it fits the milestone's theme or is out-of-scope
|
|
282
|
+
|
|
283
|
+
</classification_rules>
|
|
284
|
+
|
|
285
|
+
<output_format>
|
|
286
|
+
Return a structured classification report:
|
|
287
|
+
|
|
288
|
+
## Classification: ${CATEGORY}
|
|
289
|
+
|
|
290
|
+
### Analysis
|
|
291
|
+
- What the question is about (1-2 sentences)
|
|
292
|
+
- Why this classification was chosen (1-2 sentences)
|
|
293
|
+
|
|
294
|
+
### Related Issue
|
|
295
|
+
- Issue number and title (if adjacent or duplicate)
|
|
296
|
+
- Or 'N/A — current work' (if in-scope)
|
|
297
|
+
- Or 'No matching issue' (if separate or out-of-scope)
|
|
298
|
+
|
|
299
|
+
### Recommendation
|
|
300
|
+
- Specific actionable next step
|
|
301
|
+
- If 'separate': suggest an issue title and brief body
|
|
302
|
+
- If 'adjacent': suggest a comment to post on the related issue
|
|
303
|
+
- If 'in-scope': note what to include in current work
|
|
304
|
+
- If 'duplicate': point to the matching issue
|
|
305
|
+
- If 'out-of-scope': note for future milestone planning
|
|
306
|
+
</output_format>
|
|
307
|
+
",
|
|
308
|
+
subagent_type="general-purpose",
|
|
309
|
+
description="Classify question: ${QUESTION}"
|
|
310
|
+
)
|
|
311
|
+
```
|
|
312
|
+
</step>
|
|
313
|
+
|
|
314
|
+
<step name="present_result">
|
|
315
|
+
**Present the classification result to the user:**
|
|
316
|
+
|
|
317
|
+
Display the agent's report, then present the MGW action banner:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
321
|
+
MGW ► QUESTION ROUTING
|
|
322
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
323
|
+
|
|
324
|
+
${classification_report_from_agent}
|
|
325
|
+
|
|
326
|
+
───────────────────────────────────────────────────────
|
|
327
|
+
```
|
|
328
|
+
</step>
|
|
329
|
+
|
|
330
|
+
<step name="offer_actions">
|
|
331
|
+
**Offer follow-up actions based on classification:**
|
|
332
|
+
|
|
333
|
+
**If "Separate":**
|
|
334
|
+
```
|
|
335
|
+
AskUserQuestion(
|
|
336
|
+
header: "File New Issue?",
|
|
337
|
+
question: "Create a new issue from this observation?",
|
|
338
|
+
options: [
|
|
339
|
+
{ label: "Yes", description: "File the suggested issue via /mgw:issue" },
|
|
340
|
+
{ label: "No", description: "Note it and continue current work" }
|
|
341
|
+
]
|
|
342
|
+
)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
If user says "Yes":
|
|
346
|
+
```
|
|
347
|
+
Suggested issue ready. To file it:
|
|
348
|
+
|
|
349
|
+
gh issue create --title "${suggested_title}" --body "${suggested_body}"
|
|
350
|
+
|
|
351
|
+
Or use /mgw:project to add it to a future milestone.
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**If "Adjacent":**
|
|
355
|
+
```
|
|
356
|
+
AskUserQuestion(
|
|
357
|
+
header: "Post Comment?",
|
|
358
|
+
question: "Post a note on the related issue #${related_number}?",
|
|
359
|
+
options: [
|
|
360
|
+
{ label: "Yes", description: "Post observation as a comment on #${related_number}" },
|
|
361
|
+
{ label: "No", description: "Note it and continue current work" }
|
|
362
|
+
]
|
|
363
|
+
)
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
If user says "Yes":
|
|
367
|
+
```bash
|
|
368
|
+
gh issue comment ${related_number} --body "> **MGW** · \`observation\` · $(node ~/.claude/get-shit-done/bin/gsd-tools.cjs current-timestamp --raw)
|
|
369
|
+
|
|
370
|
+
Observation noted during work on #${ACTIVE_ISSUE_NUMBER}:
|
|
371
|
+
|
|
372
|
+
${QUESTION}"
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
Report: "Comment posted on #${related_number}."
|
|
376
|
+
|
|
377
|
+
**If "In-scope":**
|
|
378
|
+
```
|
|
379
|
+
This relates to your current work on #${ACTIVE_ISSUE_NUMBER}.
|
|
380
|
+
No action needed — include it in your current implementation.
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**If "Duplicate":**
|
|
384
|
+
```
|
|
385
|
+
This appears to duplicate #${duplicate_number} — ${duplicate_title}.
|
|
386
|
+
No new issue needed. Check that issue for existing progress.
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**If "Out-of-scope":**
|
|
390
|
+
```
|
|
391
|
+
This is beyond the current milestone scope.
|
|
392
|
+
Consider adding it to a future milestone or filing it for backlog:
|
|
393
|
+
|
|
394
|
+
gh issue create --title "${suggested_title}" --label "backlog"
|
|
395
|
+
```
|
|
396
|
+
</step>
|
|
397
|
+
|
|
398
|
+
</process>
|
|
399
|
+
|
|
400
|
+
<success_criteria>
|
|
401
|
+
- [ ] Question text parsed from $ARGUMENTS (or prompted)
|
|
402
|
+
- [ ] project.json loaded for milestone + issue context
|
|
403
|
+
- [ ] .mgw/active/ state loaded for current work context
|
|
404
|
+
- [ ] Recent git diff gathered for change context
|
|
405
|
+
- [ ] Issue bodies fetched from GitHub for comparison
|
|
406
|
+
- [ ] Classification agent spawned with full context
|
|
407
|
+
- [ ] Classification returned: in-scope, adjacent, separate, duplicate, or out-of-scope
|
|
408
|
+
- [ ] Related issue identified (if adjacent or duplicate)
|
|
409
|
+
- [ ] Actionable recommendation provided
|
|
410
|
+
- [ ] Follow-up action offered (file issue, post comment, etc.)
|
|
411
|
+
- [ ] Delegation boundary respected: agent reads code/state, MGW presents results
|
|
412
|
+
- [ ] Command surface index built from commands/*.md front matter
|
|
413
|
+
- [ ] Open PRs fetched and injected into agent context
|
|
414
|
+
- [ ] Live GitHub milestones fetched as fallback when project.json is absent
|
|
415
|
+
</success_criteria>
|
|
416
|
+
</output>
|