ma-agents 3.1.0 → 3.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/.opencode/skills/.ma-agents.json +99 -99
- package/.roo/rules/00-ma-agents.md +13 -0
- package/.roo/skills/.ma-agents.json +241 -0
- package/.roo/skills/MANIFEST.yaml +254 -0
- package/.roo/skills/ai-audit-trail/SKILL.md +23 -0
- package/.roo/skills/auto-bug-detection/SKILL.md +169 -0
- package/.roo/skills/cmake-best-practices/SKILL.md +64 -0
- package/.roo/skills/cmake-best-practices/examples/cmake.md +59 -0
- package/.roo/skills/code-documentation/SKILL.md +57 -0
- package/.roo/skills/code-documentation/examples/cpp.md +29 -0
- package/.roo/skills/code-documentation/examples/csharp.md +28 -0
- package/.roo/skills/code-documentation/examples/javascript_typescript.md +28 -0
- package/.roo/skills/code-documentation/examples/python.md +57 -0
- package/.roo/skills/code-review/SKILL.md +43 -0
- package/.roo/skills/commit-message/SKILL.md +79 -0
- package/.roo/skills/cpp-best-practices/SKILL.md +234 -0
- package/.roo/skills/cpp-best-practices/examples/modern-idioms.md +189 -0
- package/.roo/skills/cpp-best-practices/examples/naming-and-organization.md +102 -0
- package/.roo/skills/cpp-concurrency-safety/SKILL.md +60 -0
- package/.roo/skills/cpp-concurrency-safety/examples/concurrency.md +73 -0
- package/.roo/skills/cpp-const-correctness/SKILL.md +63 -0
- package/.roo/skills/cpp-const-correctness/examples/const_correctness.md +54 -0
- package/.roo/skills/cpp-memory-handling/SKILL.md +42 -0
- package/.roo/skills/cpp-memory-handling/examples/modern-cpp.md +49 -0
- package/.roo/skills/cpp-memory-handling/examples/smart-pointers.md +46 -0
- package/.roo/skills/cpp-modern-composition/SKILL.md +64 -0
- package/.roo/skills/cpp-modern-composition/examples/composition.md +51 -0
- package/.roo/skills/cpp-robust-interfaces/SKILL.md +55 -0
- package/.roo/skills/cpp-robust-interfaces/examples/interfaces.md +56 -0
- package/.roo/skills/create-hardened-docker-skill/SKILL.md +637 -0
- package/.roo/skills/create-hardened-docker-skill/scripts/create-all.sh +489 -0
- package/.roo/skills/csharp-best-practices/SKILL.md +278 -0
- package/.roo/skills/docker-hardening-verification/SKILL.md +28 -0
- package/.roo/skills/docker-hardening-verification/scripts/verify-hardening.sh +39 -0
- package/.roo/skills/docker-image-signing/SKILL.md +28 -0
- package/.roo/skills/docker-image-signing/scripts/sign-image.sh +33 -0
- package/.roo/skills/document-revision-history/SKILL.md +104 -0
- package/.roo/skills/git-workflow-skill/SKILL.md +194 -0
- package/.roo/skills/git-workflow-skill/hooks/commit-msg +61 -0
- package/.roo/skills/git-workflow-skill/hooks/pre-commit +38 -0
- package/.roo/skills/git-workflow-skill/hooks/prepare-commit-msg +56 -0
- package/.roo/skills/git-workflow-skill/scripts/finish-feature.sh +192 -0
- package/.roo/skills/git-workflow-skill/scripts/install-hooks.sh +55 -0
- package/.roo/skills/git-workflow-skill/scripts/start-feature.sh +110 -0
- package/.roo/skills/git-workflow-skill/scripts/validate-workflow.sh +229 -0
- package/.roo/skills/js-ts-dependency-mgmt/SKILL.md +49 -0
- package/.roo/skills/js-ts-dependency-mgmt/examples/dependency_mgmt.md +60 -0
- package/.roo/skills/js-ts-security-skill/SKILL.md +64 -0
- package/.roo/skills/js-ts-security-skill/scripts/verify-security.sh +136 -0
- package/.roo/skills/logging-best-practices/SKILL.md +50 -0
- package/.roo/skills/logging-best-practices/examples/cpp.md +36 -0
- package/.roo/skills/logging-best-practices/examples/csharp.md +49 -0
- package/.roo/skills/logging-best-practices/examples/javascript.md +77 -0
- package/.roo/skills/logging-best-practices/examples/python.md +57 -0
- package/.roo/skills/logging-best-practices/references/logging-standards.md +29 -0
- package/.roo/skills/open-presentation/SKILL.md +35 -0
- package/.roo/skills/opentelemetry-best-practices/SKILL.md +34 -0
- package/.roo/skills/opentelemetry-best-practices/examples/go.md +32 -0
- package/.roo/skills/opentelemetry-best-practices/examples/javascript.md +58 -0
- package/.roo/skills/opentelemetry-best-practices/examples/python.md +37 -0
- package/.roo/skills/opentelemetry-best-practices/references/otel-standards.md +37 -0
- package/.roo/skills/python-best-practices/SKILL.md +385 -0
- package/.roo/skills/python-dependency-mgmt/SKILL.md +42 -0
- package/.roo/skills/python-dependency-mgmt/examples/dependency_mgmt.md +67 -0
- package/.roo/skills/python-security-skill/SKILL.md +56 -0
- package/.roo/skills/python-security-skill/examples/security.md +56 -0
- package/.roo/skills/self-signed-cert/SKILL.md +42 -0
- package/.roo/skills/self-signed-cert/scripts/generate-cert.ps1 +45 -0
- package/.roo/skills/self-signed-cert/scripts/generate-cert.sh +43 -0
- package/.roo/skills/skill-creator/SKILL.md +196 -0
- package/.roo/skills/skill-creator/references/output-patterns.md +82 -0
- package/.roo/skills/skill-creator/references/workflows.md +28 -0
- package/.roo/skills/skill-creator/scripts/init_skill.py +208 -0
- package/.roo/skills/skill-creator/scripts/package_skill.py +99 -0
- package/.roo/skills/skill-creator/scripts/quick_validate.py +113 -0
- package/.roo/skills/story-status-lookup/SKILL.md +78 -0
- package/.roo/skills/test-accompanied-development/SKILL.md +50 -0
- package/.roo/skills/test-generator/SKILL.md +65 -0
- package/.roo/skills/vercel-react-best-practices/SKILL.md +109 -0
- package/.roo/skills/verify-hardened-docker-skill/SKILL.md +442 -0
- package/.roo/skills/verify-hardened-docker-skill/scripts/verify-docker-hardening.sh +439 -0
- package/README.md +50 -3
- package/lib/agents.js +23 -0
- package/lib/bmad-extension/module-help.csv +8 -4
- package/lib/bmad-extension/skills/add-sprint/SKILL.md +126 -40
- package/lib/bmad-extension/skills/add-to-sprint/SKILL.md +116 -142
- package/lib/bmad-extension/skills/cleanup-done/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cleanup-done/SKILL.md +159 -0
- package/lib/bmad-extension/skills/cleanup-done/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/create-bug-story/SKILL.md +75 -7
- package/lib/bmad-extension/skills/generate-backlog/SKILL.md +183 -0
- package/lib/bmad-extension/skills/generate-backlog/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/modify-sprint/SKILL.md +63 -0
- package/lib/bmad-extension/skills/prioritize-backlog/.gitkeep +0 -0
- package/lib/bmad-extension/skills/prioritize-backlog/SKILL.md +195 -0
- package/lib/bmad-extension/skills/prioritize-backlog/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/remove-from-sprint/.gitkeep +0 -0
- package/lib/bmad-extension/skills/remove-from-sprint/SKILL.md +163 -0
- package/lib/bmad-extension/skills/remove-from-sprint/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sprint-status-view/SKILL.md +199 -138
- package/lib/bmad-extension/workflows/add-sprint/workflow.md +129 -39
- package/lib/bmad-extension/workflows/add-to-sprint/workflow.md +3 -205
- package/lib/bmad-extension/workflows/modify-sprint/workflow.md +5 -0
- package/lib/bmad-extension/workflows/sprint-status-view/workflow.md +3 -192
- package/package.json +4 -3
- package/test/roo-code-agent.test.js +166 -0
- package/test/roo-code-injection.test.js +172 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: add-sprint
|
|
3
|
-
description: Guided workflow to create a new sprint with capacity limits for
|
|
3
|
+
description: Guided workflow to create a new sprint entity with capacity limits, optional ISO dates, and structured YAML schema for sprint planning
|
|
4
4
|
type: skill
|
|
5
5
|
triggers:
|
|
6
6
|
- "add sprint"
|
|
@@ -9,17 +9,35 @@ triggers:
|
|
|
9
9
|
|
|
10
10
|
# Add Sprint Workflow
|
|
11
11
|
|
|
12
|
-
Guided workflow to create a new sprint with capacity limits
|
|
12
|
+
Guided workflow to create a new sprint entity with capacity limits, optional ISO dates, and structured YAML schema.
|
|
13
13
|
|
|
14
14
|
<workflow>
|
|
15
15
|
|
|
16
|
-
<step n="1" goal="Gather sprint number and name">
|
|
17
|
-
<action>Ask the user for the sprint number
|
|
18
|
-
<ask>What is the sprint number? (e.g., 1)</ask>
|
|
19
|
-
<action>Store as {{
|
|
20
|
-
<
|
|
21
|
-
<action>
|
|
22
|
-
<
|
|
16
|
+
<step n="1" goal="Gather and validate sprint number and name">
|
|
17
|
+
<action>Ask the user for the sprint number</action>
|
|
18
|
+
<ask>What is the sprint number? (positive integer, e.g., 1, 2, 3)</ask>
|
|
19
|
+
<action>Store input as {{sprint_number_input}}</action>
|
|
20
|
+
<action>Validate {{sprint_number_input}} matches `^[1-9]\d*$` (positive integer, no leading zeros, no non-numeric characters)</action>
|
|
21
|
+
<action>Validate {{sprint_number_input}} is <= 9999</action>
|
|
22
|
+
<check if="{{sprint_number_input}} fails validation (zero, negative, non-numeric, leading zeros like '03', or > 9999)">
|
|
23
|
+
<output>❌ Invalid sprint number: "{{sprint_number_input}}". Must be a positive integer (1-9999), no leading zeros.</output>
|
|
24
|
+
<goto step="1" />
|
|
25
|
+
</check>
|
|
26
|
+
<action>Store as {{sprint_number}} (integer)</action>
|
|
27
|
+
<action>Construct {{sprint_id}} = "sprint-{{sprint_number}}"</action>
|
|
28
|
+
|
|
29
|
+
<!-- Smart default name: detect naming patterns from existing sprints -->
|
|
30
|
+
<action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover existing sprint files</action>
|
|
31
|
+
<action>If existing sprints found, read the `name` field from the most recent one (highest sprint number)</action>
|
|
32
|
+
<action>Infer a smart default name:
|
|
33
|
+
- If previous name follows a sequential pattern with a numeric suffix (e.g., "app04"), suggest the next increment (e.g., "app05")
|
|
34
|
+
- If previous name follows a date pattern (e.g., "2026-W14"), suggest the next date interval
|
|
35
|
+
- If previous name is "Sprint {n}", suggest "Sprint {{sprint_number}}"
|
|
36
|
+
- If no pattern detected or no existing sprints, default to "Sprint {{sprint_number}}"
|
|
37
|
+
</action>
|
|
38
|
+
<ask>Sprint name? (press Enter for "{{default_name}}", or type a custom name):</ask>
|
|
39
|
+
<action>If user presses Enter or leaves blank, set {{sprint_name}} = "{{default_name}}"</action>
|
|
40
|
+
<action>If user provides input, store as {{sprint_name}}</action>
|
|
23
41
|
</step>
|
|
24
42
|
|
|
25
43
|
<step n="2" goal="Gather capacity as positive integer">
|
|
@@ -34,32 +52,71 @@ Guided workflow to create a new sprint with capacity limits for realistic sprint
|
|
|
34
52
|
<action>Store as {{capacity}} (integer)</action>
|
|
35
53
|
</step>
|
|
36
54
|
|
|
37
|
-
<step n="
|
|
38
|
-
<action>Explain: start
|
|
39
|
-
<ask>Optional — Sprint start
|
|
40
|
-
<action>Store as {{
|
|
41
|
-
<
|
|
42
|
-
|
|
55
|
+
<step n="3a" goal="Gather optional start date (ISO format)">
|
|
56
|
+
<action>Explain: start and end dates are optional ISO dates (YYYY-MM-DD format). Press Enter to skip.</action>
|
|
57
|
+
<ask>Optional — Sprint start date (YYYY-MM-DD, press Enter to skip):</ask>
|
|
58
|
+
<action>Store input as {{start_input}}</action>
|
|
59
|
+
<check if="{{start_input}} is not empty">
|
|
60
|
+
<action>Validate {{start_input}} matches regex `^\d{4}-\d{2}-\d{2}$`</action>
|
|
61
|
+
<action>Verify {{start_input}} resolves to a real calendar date (reject impossible dates like 2026-02-30, 2026-13-45, etc.)</action>
|
|
62
|
+
<check if="{{start_input}} fails date validation">
|
|
63
|
+
<output>❌ Invalid date: "{{start_input}}". Must be a valid date in YYYY-MM-DD format (e.g., 2026-04-01).</output>
|
|
64
|
+
<goto step="3a" />
|
|
65
|
+
</check>
|
|
66
|
+
</check>
|
|
67
|
+
<action>Store as {{start_date}} (valid ISO date string, or empty string "" if skipped)</action>
|
|
68
|
+
</step>
|
|
69
|
+
|
|
70
|
+
<step n="3b" goal="Gather optional end date (ISO format)">
|
|
71
|
+
<ask>Optional — Sprint end date (YYYY-MM-DD, press Enter to skip):</ask>
|
|
72
|
+
<action>Store input as {{end_input}}</action>
|
|
73
|
+
<check if="{{end_input}} is not empty">
|
|
74
|
+
<action>Validate {{end_input}} matches regex `^\d{4}-\d{2}-\d{2}$`</action>
|
|
75
|
+
<action>Verify {{end_input}} resolves to a real calendar date</action>
|
|
76
|
+
<check if="{{end_input}} fails date validation">
|
|
77
|
+
<output>❌ Invalid date: "{{end_input}}". Must be a valid date in YYYY-MM-DD format (e.g., 2026-04-14).</output>
|
|
78
|
+
<goto step="3b" />
|
|
79
|
+
</check>
|
|
80
|
+
</check>
|
|
81
|
+
<action>Store as {{end_date}} (valid ISO date string, or empty string "" if skipped)</action>
|
|
82
|
+
|
|
83
|
+
<check if="both {{start_date}} and {{end_date}} are non-empty AND {{start_date}} > {{end_date}}">
|
|
84
|
+
<output>❌ Invalid date range: start date ({{start_date}}) is after end date ({{end_date}}). Start must be on or before end.</output>
|
|
85
|
+
<goto step="3a" />
|
|
86
|
+
</check>
|
|
43
87
|
</step>
|
|
44
88
|
|
|
45
89
|
<step n="4" goal="Confirm and validate all inputs">
|
|
46
90
|
<output>
|
|
47
91
|
## Sprint Summary — Please Confirm
|
|
48
92
|
|
|
49
|
-
- **Sprint
|
|
50
|
-
- **Sprint Name:** {{sprint_name}}
|
|
93
|
+
- **Sprint ID:** {{sprint_id}}
|
|
94
|
+
- **Sprint Name:** "{{sprint_name}}"
|
|
95
|
+
- **Status:** planning
|
|
51
96
|
- **Capacity (max items):** {{capacity}}
|
|
52
|
-
- **Start
|
|
53
|
-
- **End
|
|
54
|
-
- **
|
|
97
|
+
- **Start Date:** {{start_date}} *(empty if skipped)*
|
|
98
|
+
- **End Date:** {{end_date}} *(empty if skipped)*
|
|
99
|
+
- **Items:** [] *(empty — items assigned via /add-to-sprint)*
|
|
100
|
+
- **Output File:** `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`
|
|
55
101
|
</output>
|
|
56
102
|
<ask>Confirm creation? [y] Yes / [n] Cancel / [e] Edit a field:</ask>
|
|
57
103
|
<check if="user selects 'e'">
|
|
58
104
|
<ask>Which field to edit? (number / name / capacity / start / end)</ask>
|
|
59
105
|
<check if="field == 'number'">
|
|
60
|
-
<ask>New sprint number
|
|
61
|
-
<action>Store as {{
|
|
62
|
-
<action>
|
|
106
|
+
<ask>New sprint number? (positive integer, 1-9999)</ask>
|
|
107
|
+
<action>Store input as {{sprint_number_input}}</action>
|
|
108
|
+
<action>Validate {{sprint_number_input}} matches `^[1-9]\d*$` and is <= 9999</action>
|
|
109
|
+
<check if="{{sprint_number_input}} fails validation">
|
|
110
|
+
<output>❌ Invalid sprint number: "{{sprint_number_input}}". Must be a positive integer (1-9999), no leading zeros.</output>
|
|
111
|
+
<goto step="4" />
|
|
112
|
+
</check>
|
|
113
|
+
<action>Store as {{sprint_number}} (integer)</action>
|
|
114
|
+
<action>Construct {{sprint_id}} = "sprint-{{sprint_number}}"</action>
|
|
115
|
+
<action>If sprint name was using previous default "Sprint {old_n}", update to "Sprint {{sprint_number}}"</action>
|
|
116
|
+
<action>Check if file exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
|
|
117
|
+
<check if="file already exists at new path">
|
|
118
|
+
<output>⚠️ A sprint entity already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`. You will be prompted to overwrite at creation.</output>
|
|
119
|
+
</check>
|
|
63
120
|
<goto step="4" />
|
|
64
121
|
</check>
|
|
65
122
|
<check if="field == 'name'">
|
|
@@ -68,45 +125,74 @@ Guided workflow to create a new sprint with capacity limits for realistic sprint
|
|
|
68
125
|
<goto step="4" />
|
|
69
126
|
</check>
|
|
70
127
|
<check if="field == 'capacity'"><goto step="2" /></check>
|
|
71
|
-
<check if="field == 'start'"><goto step="
|
|
72
|
-
<check if="field == 'end'"><goto step="
|
|
128
|
+
<check if="field == 'start'"><goto step="3a" /></check>
|
|
129
|
+
<check if="field == 'end'"><goto step="3b" /></check>
|
|
130
|
+
<check if="field is not recognized">
|
|
131
|
+
<output>❌ Unrecognized field: "{{field}}". Valid options: number, name, capacity, start, end.</output>
|
|
132
|
+
<goto step="4" />
|
|
133
|
+
</check>
|
|
73
134
|
</check>
|
|
74
135
|
<check if="user selects 'n'">
|
|
75
136
|
<output>❌ Sprint creation cancelled.</output>
|
|
76
137
|
<action>Exit workflow</action>
|
|
77
138
|
</check>
|
|
139
|
+
<check if="user input is not 'y', 'n', or 'e'">
|
|
140
|
+
<output>❌ Unrecognized option: "{{user_input}}". Please enter [y] Yes, [n] Cancel, or [e] Edit a field.</output>
|
|
141
|
+
<goto step="4" />
|
|
142
|
+
</check>
|
|
78
143
|
</step>
|
|
79
144
|
|
|
80
|
-
<step n="5" goal="Generate sprint
|
|
81
|
-
<action>Determine output path: `_bmad-output/implementation-artifacts/
|
|
82
|
-
<action>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
145
|
+
<step n="5" goal="Generate sprint entity YAML file">
|
|
146
|
+
<action>Determine output path: `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
|
|
147
|
+
<action>Ensure directory `_bmad-output/implementation-artifacts/sprints/` exists (create if needed)</action>
|
|
148
|
+
|
|
149
|
+
<!-- Overwrite protection for new path -->
|
|
150
|
+
<action>Check if file already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
|
|
151
|
+
<check if="file already exists at new path">
|
|
152
|
+
<anchor id="overwrite_prompt" />
|
|
153
|
+
<output>⚠️ A sprint entity already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`.</output>
|
|
154
|
+
<ask>Overwrite existing sprint? [y] Yes / [n] Cancel:</ask>
|
|
86
155
|
<check if="user selects 'n'">
|
|
87
|
-
<output>❌ Sprint creation cancelled to preserve existing sprint
|
|
156
|
+
<output>❌ Sprint creation cancelled to preserve existing sprint.</output>
|
|
88
157
|
<action>Exit workflow</action>
|
|
89
158
|
</check>
|
|
159
|
+
<check if="user input is not 'y' or 'n'">
|
|
160
|
+
<output>❌ Unrecognized option: "{{user_input}}". Please enter [y] Yes or [n] Cancel.</output>
|
|
161
|
+
<goto anchor="overwrite_prompt" />
|
|
162
|
+
</check>
|
|
90
163
|
</check>
|
|
164
|
+
|
|
165
|
+
<!-- Advisory check for old-format file -->
|
|
166
|
+
<action>Check if file exists at old path: `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`</action>
|
|
167
|
+
<check if="old-format file exists">
|
|
168
|
+
<output>ℹ️ **Note:** An old-format sprint file exists at `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`. The new sprint will be created at the new path. The old file is NOT auto-migrated — review or remove it manually if no longer needed.</output>
|
|
169
|
+
</check>
|
|
170
|
+
|
|
91
171
|
<action>Get current ISO timestamp for created_date and last_modified</action>
|
|
92
|
-
<action>Write sprint
|
|
172
|
+
<action>Write sprint entity YAML to `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml` with this structure:
|
|
93
173
|
|
|
94
174
|
```yaml
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
capacity: {{capacity}}
|
|
98
|
-
assigned_items: []
|
|
175
|
+
id: {{sprint_id}}
|
|
176
|
+
name: "{{sprint_name}}"
|
|
99
177
|
status: planning
|
|
100
|
-
|
|
101
|
-
|
|
178
|
+
capacity: {{capacity}}
|
|
179
|
+
start: "{{start_date}}"
|
|
180
|
+
end: "{{end_date}}"
|
|
181
|
+
items: []
|
|
102
182
|
created_date: "{{current_iso_timestamp}}"
|
|
103
183
|
last_modified: "{{current_iso_timestamp}}"
|
|
104
184
|
```
|
|
185
|
+
|
|
186
|
+
**YAML output rules:**
|
|
187
|
+
- Always quote the `name` field to handle special characters
|
|
188
|
+
- `start` and `end` are empty string `""` if skipped
|
|
189
|
+
- `items` is always empty array `[]` at creation
|
|
190
|
+
- `status` is always `planning` at creation (never `active` or `closed`)
|
|
105
191
|
</action>
|
|
106
192
|
<output>
|
|
107
193
|
✅ **Sprint created successfully!**
|
|
108
194
|
|
|
109
|
-
- **File:** `_bmad-output/implementation-artifacts/
|
|
195
|
+
- **File:** `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`
|
|
110
196
|
- **Sprint:** {{sprint_name}}
|
|
111
197
|
- **Capacity:** {{capacity}} items
|
|
112
198
|
- **Status:** planning
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: add-to-sprint
|
|
3
|
-
description: Guided workflow to assign backlog items to a sprint
|
|
3
|
+
description: Guided workflow to assign backlog items to a sprint from the flat prioritized backlog
|
|
4
4
|
type: skill
|
|
5
5
|
triggers:
|
|
6
6
|
- "add to sprint"
|
|
@@ -9,204 +9,178 @@ triggers:
|
|
|
9
9
|
|
|
10
10
|
# Add-to-Sprint Workflow
|
|
11
11
|
|
|
12
|
-
Guided workflow to assign backlog items
|
|
12
|
+
Guided workflow to assign unassigned backlog items to a sprint from the flat prioritized backlog.
|
|
13
13
|
|
|
14
14
|
<workflow>
|
|
15
15
|
|
|
16
|
-
<step n="
|
|
17
|
-
<action>Read `_bmad-output/implementation-artifacts/
|
|
18
|
-
<action>Parse the
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
<action>Infer story title from key (e.g., `12-1-add-sprint-workflow` → "Add Sprint Workflow")</action>
|
|
25
|
-
</step>
|
|
26
|
-
|
|
27
|
-
<step n="1b" goal="Discover bug story backlog items">
|
|
28
|
-
<action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files</action>
|
|
29
|
-
<check if="no bug files found">
|
|
30
|
-
<action>Set {{bug_stories}} = [] (empty list)</action>
|
|
31
|
-
</check>
|
|
32
|
-
<check if="bug files found">
|
|
33
|
-
<action>For each bug file, parse YAML frontmatter to extract: `type`, `severity`, `title`</action>
|
|
34
|
-
<action>Store as {{bug_stories}} — list of objects with: file, type (bug), severity, title</action>
|
|
35
|
-
</check>
|
|
36
|
-
</step>
|
|
37
|
-
|
|
38
|
-
<step n="1c" goal="Filter out items already assigned to any sprint">
|
|
39
|
-
<action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all existing sprint artifact files</action>
|
|
40
|
-
<action>For each sprint file found, read its assigned_items list</action>
|
|
41
|
-
<action>Build {{all_assigned_items}} = flat set of every item identifier (story keys and bug basenames) across ALL sprint plans</action>
|
|
42
|
-
<action>Filter {{user_stories}}: remove any story whose key is present in {{all_assigned_items}}</action>
|
|
43
|
-
<action>Filter {{bug_stories}}: remove any bug whose file basename is present in {{all_assigned_items}}</action>
|
|
44
|
-
<action>Items already assigned to any sprint will NOT appear in the backlog — this prevents duplicate assignment</action>
|
|
45
|
-
<check if="no sprint files found">
|
|
46
|
-
<action>Set {{all_assigned_items}} = [] — no filtering needed when no sprints exist yet</action>
|
|
16
|
+
<step n="1" goal="Load backlog and identify unassigned items">
|
|
17
|
+
<action>Read `_bmad-output/implementation-artifacts/backlog.yaml`</action>
|
|
18
|
+
<action>Parse the `backlog` array. Filter items where `sprint` is `null` (unassigned).</action>
|
|
19
|
+
<action>Sort filtered items by `priority` ascending (lowest number = highest priority).</action>
|
|
20
|
+
<action>Store as {{unassigned_items}} list.</action>
|
|
21
|
+
<check if="no unassigned items remain">
|
|
22
|
+
<output>All backlog items are already assigned to sprints. Nothing to assign.</output>
|
|
23
|
+
<action>Exit workflow</action>
|
|
47
24
|
</check>
|
|
48
25
|
</step>
|
|
49
26
|
|
|
50
|
-
<step n="2" goal="
|
|
51
|
-
<action>
|
|
52
|
-
<action>Stories and bugs are peers — no epic grouping (FR65)</action>
|
|
53
|
-
<output>
|
|
54
|
-
## 📋 Backlog Items
|
|
55
|
-
|
|
56
|
-
| # | ID / File | Title | Type | Status/Severity |
|
|
57
|
-
|---|---|---|---|---|
|
|
58
|
-
{{#each backlog_items}}
|
|
59
|
-
| {{@index+1}} | {{id}} | {{title}} | {{type}} | {{status_or_severity}} |
|
|
60
|
-
{{/each}}
|
|
61
|
-
|
|
62
|
-
*Total: {{story_count}} stories, {{bug_count}} bugs*
|
|
63
|
-
</output>
|
|
64
|
-
</step>
|
|
65
|
-
|
|
66
|
-
<step n="3" goal="List available sprints and select target sprint">
|
|
67
|
-
<action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
|
|
27
|
+
<step n="2" goal="Load sprints and select target">
|
|
28
|
+
<action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover all sprint files</action>
|
|
68
29
|
<check if="no sprint files found">
|
|
69
|
-
<output
|
|
30
|
+
<output>No sprints exist. Run `/add-sprint` first to create a sprint before assigning items.</output>
|
|
70
31
|
<action>Exit workflow</action>
|
|
71
32
|
</check>
|
|
72
|
-
<action>
|
|
33
|
+
<action>Read each sprint file; extract: id, name, status, capacity, items (array length = assigned count)</action>
|
|
34
|
+
<action>Sort sprints by status: `active` first, then `planning`, then `closed`</action>
|
|
35
|
+
<action>Display sprints table (closed sprints shown but marked as not selectable):</action>
|
|
73
36
|
<output>
|
|
74
|
-
##
|
|
37
|
+
## Available Sprints
|
|
75
38
|
|
|
76
|
-
| # |
|
|
77
|
-
|
|
39
|
+
| # | ID | Name | Status | Capacity | Assigned | Remaining |
|
|
40
|
+
|---|---|---|---|---|---|---|
|
|
78
41
|
{{#each sprints}}
|
|
79
|
-
| {{@index+1}} | {{
|
|
42
|
+
| {{@index+1}} | {{id}} | {{name}} | {{status}} | {{capacity}} | {{assigned_count}} | {{remaining}} |
|
|
80
43
|
{{/each}}
|
|
44
|
+
|
|
45
|
+
*Closed sprints are shown for reference but cannot be selected.*
|
|
81
46
|
</output>
|
|
82
|
-
<
|
|
83
|
-
|
|
47
|
+
<check if="exactly one active sprint exists">
|
|
48
|
+
<output>Auto-selecting active sprint: {{active_sprint.name}} ({{active_sprint.id}})</output>
|
|
49
|
+
<ask>Proceed with this sprint? [y] Yes / [n] Choose a different sprint:</ask>
|
|
50
|
+
<check if="user selects 'y'">
|
|
51
|
+
<action>Set {{target_sprint}} = the active sprint</action>
|
|
52
|
+
</check>
|
|
53
|
+
<check if="user selects 'n'">
|
|
54
|
+
<ask>Select target sprint by number (active or planning only):</ask>
|
|
55
|
+
<action>Validate selection is not a closed sprint</action>
|
|
56
|
+
<action>Store as {{target_sprint}}</action>
|
|
57
|
+
</check>
|
|
58
|
+
</check>
|
|
59
|
+
<check if="no active sprint exists OR multiple active/planning sprints">
|
|
60
|
+
<ask>Select target sprint by number (active or planning only):</ask>
|
|
61
|
+
<action>Validate selection is not a closed sprint</action>
|
|
62
|
+
<check if="user selected a closed sprint">
|
|
63
|
+
<output>Closed sprints cannot receive new items. Select an active or planning sprint.</output>
|
|
64
|
+
<goto step="2" />
|
|
65
|
+
</check>
|
|
66
|
+
<action>Store as {{target_sprint}}</action>
|
|
67
|
+
</check>
|
|
84
68
|
</step>
|
|
85
69
|
|
|
86
|
-
<step n="
|
|
87
|
-
<action>Calculate: {{assigned_count}} = length of {{target_sprint.
|
|
70
|
+
<step n="3" goal="Display sprint capacity and unassigned backlog items">
|
|
71
|
+
<action>Calculate: {{assigned_count}} = length of {{target_sprint.items}}</action>
|
|
88
72
|
<action>Calculate: {{remaining_capacity}} = {{target_sprint.capacity}} - {{assigned_count}}</action>
|
|
89
73
|
<output>
|
|
90
|
-
## Sprint Capacity: {{target_sprint.
|
|
74
|
+
## Sprint Capacity: {{target_sprint.name}} ({{target_sprint.id}})
|
|
91
75
|
|
|
92
|
-
|
|
93
|
-
- **Assigned:** {{assigned_count}} items
|
|
94
|
-
- **Remaining:** {{remaining_capacity}} slots
|
|
76
|
+
[{{capacity_bar}}] {{assigned_count}}/{{target_sprint.capacity}} items ({{remaining_capacity}} remaining)
|
|
95
77
|
|
|
96
78
|
{{#if remaining_capacity <= 0}}
|
|
97
|
-
|
|
79
|
+
Warning: This sprint is at or over capacity. Adding items will exceed the limit.
|
|
98
80
|
{{/if}}
|
|
99
81
|
</output>
|
|
100
|
-
</step>
|
|
101
|
-
|
|
102
|
-
<step n="5" goal="Select candidate items for this sprint">
|
|
103
|
-
<ask>Which backlog items do you want to consider for this sprint? Enter item numbers (comma-separated), or "all" to evaluate the full backlog:</ask>
|
|
104
|
-
<check if="user enters 'all'">
|
|
105
|
-
<action>Set {{candidate_items}} = all items in {{backlog_items}} (the full filtered backlog list from step 2)</action>
|
|
106
|
-
</check>
|
|
107
|
-
<check if="user enters item numbers">
|
|
108
|
-
<action>Resolve the entered numbers against the backlog table from step 2 and set {{candidate_items}} = those specific items</action>
|
|
109
|
-
</check>
|
|
110
|
-
</step>
|
|
111
82
|
|
|
112
|
-
<
|
|
113
|
-
<action>For each item in {{candidate_items}}, evaluate and score across criteria:
|
|
114
|
-
- **Business value:** High (H) / Medium (M) / Low (L) — impact on users or project goals
|
|
115
|
-
- **Dependency status:** Blocked (blocked by another item) / Blocking (blocks other items) / Independent
|
|
116
|
-
- **Severity** (bugs only): Critical / High / Medium / Low — N/A for stories
|
|
117
|
-
- **Effort estimation:** Small (S ≤ 1 day) / Medium (M 2–3 days) / Large (L 4+ days)
|
|
118
|
-
</action>
|
|
119
|
-
<action>Generate a ranked ordering recommendation, factoring in:
|
|
120
|
-
1. Blocking dependencies first (items that unlock others)
|
|
121
|
-
2. High business value + low/medium effort (quick wins)
|
|
122
|
-
3. Critical/High bugs ahead of Medium/Low bugs
|
|
123
|
-
4. Avoid blocked items unless capacity allows waiting
|
|
124
|
-
</action>
|
|
83
|
+
<action>Take the top 20 items from {{unassigned_items}} (or all if fewer than 20)</action>
|
|
125
84
|
<output>
|
|
126
|
-
##
|
|
85
|
+
## Unassigned Backlog Items
|
|
127
86
|
|
|
128
|
-
|
|
|
129
|
-
|
|
130
|
-
{{#each
|
|
131
|
-
| {{
|
|
87
|
+
| # | ID | Title | Type | Priority | Severity |
|
|
88
|
+
|---|---|---|---|---|---|
|
|
89
|
+
{{#each displayed_items}}
|
|
90
|
+
| {{@index+1}} | {{id}} | {{title}} | {{type}} | {{priority}} | {{severity_or_na}} |
|
|
132
91
|
{{/each}}
|
|
133
92
|
|
|
134
|
-
|
|
93
|
+
*Showing {{displayed_count}} of {{total_unassigned}} unassigned items.*
|
|
135
94
|
</output>
|
|
136
95
|
</step>
|
|
137
96
|
|
|
138
|
-
<step n="
|
|
139
|
-
<ask>
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
- [r] Re-rank items (provide new priority order)
|
|
143
|
-
- [x] Cancel without assigning
|
|
144
|
-
|
|
145
|
-
Choice:</ask>
|
|
146
|
-
<check if="user selects 'x'">
|
|
147
|
-
<output>❌ Assignment cancelled — no changes made.</output>
|
|
97
|
+
<step n="4" goal="Prompt for item selection">
|
|
98
|
+
<ask>Select items to add (comma-separated numbers, 'all' for all shown, or 'q' to cancel):</ask>
|
|
99
|
+
<check if="user enters 'q'">
|
|
100
|
+
<output>Assignment cancelled -- no changes made.</output>
|
|
148
101
|
<action>Exit workflow</action>
|
|
149
102
|
</check>
|
|
150
|
-
<check if="user
|
|
151
|
-
<
|
|
152
|
-
<action>Update {{confirmed_items}} with user selection</action>
|
|
153
|
-
</check>
|
|
154
|
-
<check if="user selects 'r'">
|
|
155
|
-
<ask>Enter item numbers in your preferred priority order (comma-separated). Only items you include will be assigned — items not listed will be excluded from this session and remain in the unassigned backlog:</ask>
|
|
156
|
-
<action>Set {{confirmed_items}} = only the items matching the user-provided numbers, in the order provided. Items from {{candidate_items}} NOT mentioned are excluded from assignment in this session (they remain available in the backlog for future sprints).</action>
|
|
103
|
+
<check if="user enters 'all'">
|
|
104
|
+
<action>Set {{selected_items}} = all displayed items from step 3</action>
|
|
157
105
|
</check>
|
|
158
|
-
<check if="user
|
|
159
|
-
<action>
|
|
106
|
+
<check if="user enters comma-separated numbers">
|
|
107
|
+
<action>Parse and validate each number is within the displayed list range</action>
|
|
108
|
+
<check if="any number is invalid or out of range">
|
|
109
|
+
<output>Invalid selection: {{invalid_numbers}}. Enter numbers from the list above.</output>
|
|
110
|
+
<goto step="4" />
|
|
111
|
+
</check>
|
|
112
|
+
<action>Set {{selected_items}} = the items corresponding to the entered numbers</action>
|
|
160
113
|
</check>
|
|
161
|
-
<action>Store confirmed ranking in {{confirmed_ranking}} for auditability (included in workflow output)</action>
|
|
162
114
|
</step>
|
|
163
115
|
|
|
164
|
-
<step n="
|
|
165
|
-
<action>For each item in {{
|
|
166
|
-
<action>Re-calculate current assigned count (
|
|
167
|
-
<check if="
|
|
168
|
-
<output
|
|
116
|
+
<step n="5" goal="Capacity check and assignment">
|
|
117
|
+
<action>For each item in {{selected_items}}, in order:</action>
|
|
118
|
+
<action>Re-calculate current assigned count (accounts for items already added in this session)</action>
|
|
119
|
+
<check if="adding this item would exceed capacity">
|
|
120
|
+
<output>Capacity Warning: Adding "{{item.title}}" ({{item.id}}) would bring assigned items to {{new_count}}/{{target_sprint.capacity}} -- exceeding sprint capacity by {{overage}}.</output>
|
|
169
121
|
<ask>Options:
|
|
170
122
|
- [a] Add anyway (over-capacity acknowledged)
|
|
171
123
|
- [s] Skip this item
|
|
172
|
-
- [
|
|
124
|
+
- [q] Quit (stop assigning, keep items already assigned this session)
|
|
173
125
|
|
|
174
126
|
Choice:</ask>
|
|
175
127
|
<check if="user selects 's'">
|
|
176
|
-
<action>Skip this item
|
|
128
|
+
<action>Skip this item -- do not add to sprint. Continue to next item.</action>
|
|
129
|
+
</check>
|
|
130
|
+
<check if="user selects 'q'">
|
|
131
|
+
<action>Stop processing remaining items. Proceed to step 6 with items confirmed so far.</action>
|
|
177
132
|
</check>
|
|
178
|
-
<check if="user selects '
|
|
179
|
-
<
|
|
180
|
-
<action>Exit workflow</action>
|
|
133
|
+
<check if="user selects 'a'">
|
|
134
|
+
<action>Proceed with adding this item despite over-capacity.</action>
|
|
181
135
|
</check>
|
|
182
136
|
</check>
|
|
183
|
-
<action>
|
|
184
|
-
|
|
137
|
+
<action>For each confirmed item:
|
|
138
|
+
- Add item ID to {{target_sprint}}.items array
|
|
139
|
+
- Set item's `sprint` field in backlog.yaml to {{target_sprint.id}}
|
|
140
|
+
- Update {{target_sprint}}.last_modified to current ISO timestamp
|
|
141
|
+
</action>
|
|
142
|
+
<action>Store all confirmed items as {{assigned_items}} for the summary.</action>
|
|
185
143
|
</step>
|
|
186
144
|
|
|
187
|
-
<step n="
|
|
188
|
-
<
|
|
189
|
-
|
|
145
|
+
<step n="6" goal="Persist changes and display summary">
|
|
146
|
+
<check if="no items were confirmed for assignment">
|
|
147
|
+
<output>No items were assigned. No files modified.</output>
|
|
148
|
+
<action>Exit workflow</action>
|
|
149
|
+
</check>
|
|
150
|
+
<action>**Dual-write — both files must be updated for consistency:**</action>
|
|
151
|
+
<action>Write updated `_bmad-output/implementation-artifacts/backlog.yaml`:
|
|
152
|
+
- Preserve all existing fields on all items
|
|
153
|
+
- Only the `sprint` field changes on assigned items (set to {{target_sprint.id}})
|
|
154
|
+
</action>
|
|
155
|
+
<check if="backlog.yaml write fails">
|
|
156
|
+
<output>**Error:** Failed to write backlog.yaml. No changes persisted. Sprint file NOT modified.</output>
|
|
157
|
+
<action>Exit workflow</action>
|
|
158
|
+
</check>
|
|
159
|
+
<action>Write updated `_bmad-output/implementation-artifacts/sprints/{{target_sprint.id}}.yaml`:
|
|
160
|
+
- Append confirmed item IDs to the `items` array
|
|
190
161
|
- Update `last_modified` to current ISO timestamp
|
|
162
|
+
- Preserve all other fields unchanged
|
|
191
163
|
</action>
|
|
192
|
-
<
|
|
164
|
+
<check if="sprint file write fails">
|
|
165
|
+
<output>**Warning: Inconsistent state!** backlog.yaml was updated but sprint file write failed. The `sprint` field in backlog.yaml now references {{target_sprint.id}} but the sprint file's `items` array is stale. Re-run `/add-to-sprint` or manually fix `sprints/{{target_sprint.id}}.yaml`.</output>
|
|
166
|
+
</check>
|
|
167
|
+
<action>**Do NOT read or write sprint-plan-*.yaml or sprint-status.yaml**</action>
|
|
193
168
|
<output>
|
|
194
|
-
##
|
|
195
|
-
|
|
196
|
-
**Sprint:** {{target_sprint.sprint_name}}
|
|
197
|
-
**Items assigned this session:** {{assigned_this_session}}
|
|
169
|
+
## Assignment Complete
|
|
198
170
|
|
|
199
|
-
|
|
171
|
+
**Sprint:** {{target_sprint.name}} ({{target_sprint.id}})
|
|
172
|
+
**Items assigned this session:** {{assigned_count_this_session}}
|
|
200
173
|
|
|
201
|
-
|
|
|
202
|
-
|
|
203
|
-
{{#each
|
|
204
|
-
| {{
|
|
174
|
+
| # | ID | Title | Type | Priority |
|
|
175
|
+
|---|---|---|---|---|
|
|
176
|
+
{{#each assigned_items}}
|
|
177
|
+
| {{@index+1}} | {{id}} | {{title}} | {{type}} | {{priority}} |
|
|
205
178
|
{{/each}}
|
|
206
179
|
|
|
207
|
-
**
|
|
180
|
+
**Capacity Usage:** {{new_assigned_total}}/{{target_sprint.capacity}} items ({{new_remaining}} remaining)
|
|
208
181
|
|
|
209
182
|
**Next Steps:**
|
|
183
|
+
- Use `/add-to-sprint` again to assign more items
|
|
210
184
|
- Use `/modify-sprint` to adjust capacity or remove items
|
|
211
185
|
- Use `/sprint-status-view` to view the full sprint with all assigned items
|
|
212
186
|
</output>
|
|
File without changes
|