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.
Files changed (107) hide show
  1. package/.opencode/skills/.ma-agents.json +99 -99
  2. package/.roo/rules/00-ma-agents.md +13 -0
  3. package/.roo/skills/.ma-agents.json +241 -0
  4. package/.roo/skills/MANIFEST.yaml +254 -0
  5. package/.roo/skills/ai-audit-trail/SKILL.md +23 -0
  6. package/.roo/skills/auto-bug-detection/SKILL.md +169 -0
  7. package/.roo/skills/cmake-best-practices/SKILL.md +64 -0
  8. package/.roo/skills/cmake-best-practices/examples/cmake.md +59 -0
  9. package/.roo/skills/code-documentation/SKILL.md +57 -0
  10. package/.roo/skills/code-documentation/examples/cpp.md +29 -0
  11. package/.roo/skills/code-documentation/examples/csharp.md +28 -0
  12. package/.roo/skills/code-documentation/examples/javascript_typescript.md +28 -0
  13. package/.roo/skills/code-documentation/examples/python.md +57 -0
  14. package/.roo/skills/code-review/SKILL.md +43 -0
  15. package/.roo/skills/commit-message/SKILL.md +79 -0
  16. package/.roo/skills/cpp-best-practices/SKILL.md +234 -0
  17. package/.roo/skills/cpp-best-practices/examples/modern-idioms.md +189 -0
  18. package/.roo/skills/cpp-best-practices/examples/naming-and-organization.md +102 -0
  19. package/.roo/skills/cpp-concurrency-safety/SKILL.md +60 -0
  20. package/.roo/skills/cpp-concurrency-safety/examples/concurrency.md +73 -0
  21. package/.roo/skills/cpp-const-correctness/SKILL.md +63 -0
  22. package/.roo/skills/cpp-const-correctness/examples/const_correctness.md +54 -0
  23. package/.roo/skills/cpp-memory-handling/SKILL.md +42 -0
  24. package/.roo/skills/cpp-memory-handling/examples/modern-cpp.md +49 -0
  25. package/.roo/skills/cpp-memory-handling/examples/smart-pointers.md +46 -0
  26. package/.roo/skills/cpp-modern-composition/SKILL.md +64 -0
  27. package/.roo/skills/cpp-modern-composition/examples/composition.md +51 -0
  28. package/.roo/skills/cpp-robust-interfaces/SKILL.md +55 -0
  29. package/.roo/skills/cpp-robust-interfaces/examples/interfaces.md +56 -0
  30. package/.roo/skills/create-hardened-docker-skill/SKILL.md +637 -0
  31. package/.roo/skills/create-hardened-docker-skill/scripts/create-all.sh +489 -0
  32. package/.roo/skills/csharp-best-practices/SKILL.md +278 -0
  33. package/.roo/skills/docker-hardening-verification/SKILL.md +28 -0
  34. package/.roo/skills/docker-hardening-verification/scripts/verify-hardening.sh +39 -0
  35. package/.roo/skills/docker-image-signing/SKILL.md +28 -0
  36. package/.roo/skills/docker-image-signing/scripts/sign-image.sh +33 -0
  37. package/.roo/skills/document-revision-history/SKILL.md +104 -0
  38. package/.roo/skills/git-workflow-skill/SKILL.md +194 -0
  39. package/.roo/skills/git-workflow-skill/hooks/commit-msg +61 -0
  40. package/.roo/skills/git-workflow-skill/hooks/pre-commit +38 -0
  41. package/.roo/skills/git-workflow-skill/hooks/prepare-commit-msg +56 -0
  42. package/.roo/skills/git-workflow-skill/scripts/finish-feature.sh +192 -0
  43. package/.roo/skills/git-workflow-skill/scripts/install-hooks.sh +55 -0
  44. package/.roo/skills/git-workflow-skill/scripts/start-feature.sh +110 -0
  45. package/.roo/skills/git-workflow-skill/scripts/validate-workflow.sh +229 -0
  46. package/.roo/skills/js-ts-dependency-mgmt/SKILL.md +49 -0
  47. package/.roo/skills/js-ts-dependency-mgmt/examples/dependency_mgmt.md +60 -0
  48. package/.roo/skills/js-ts-security-skill/SKILL.md +64 -0
  49. package/.roo/skills/js-ts-security-skill/scripts/verify-security.sh +136 -0
  50. package/.roo/skills/logging-best-practices/SKILL.md +50 -0
  51. package/.roo/skills/logging-best-practices/examples/cpp.md +36 -0
  52. package/.roo/skills/logging-best-practices/examples/csharp.md +49 -0
  53. package/.roo/skills/logging-best-practices/examples/javascript.md +77 -0
  54. package/.roo/skills/logging-best-practices/examples/python.md +57 -0
  55. package/.roo/skills/logging-best-practices/references/logging-standards.md +29 -0
  56. package/.roo/skills/open-presentation/SKILL.md +35 -0
  57. package/.roo/skills/opentelemetry-best-practices/SKILL.md +34 -0
  58. package/.roo/skills/opentelemetry-best-practices/examples/go.md +32 -0
  59. package/.roo/skills/opentelemetry-best-practices/examples/javascript.md +58 -0
  60. package/.roo/skills/opentelemetry-best-practices/examples/python.md +37 -0
  61. package/.roo/skills/opentelemetry-best-practices/references/otel-standards.md +37 -0
  62. package/.roo/skills/python-best-practices/SKILL.md +385 -0
  63. package/.roo/skills/python-dependency-mgmt/SKILL.md +42 -0
  64. package/.roo/skills/python-dependency-mgmt/examples/dependency_mgmt.md +67 -0
  65. package/.roo/skills/python-security-skill/SKILL.md +56 -0
  66. package/.roo/skills/python-security-skill/examples/security.md +56 -0
  67. package/.roo/skills/self-signed-cert/SKILL.md +42 -0
  68. package/.roo/skills/self-signed-cert/scripts/generate-cert.ps1 +45 -0
  69. package/.roo/skills/self-signed-cert/scripts/generate-cert.sh +43 -0
  70. package/.roo/skills/skill-creator/SKILL.md +196 -0
  71. package/.roo/skills/skill-creator/references/output-patterns.md +82 -0
  72. package/.roo/skills/skill-creator/references/workflows.md +28 -0
  73. package/.roo/skills/skill-creator/scripts/init_skill.py +208 -0
  74. package/.roo/skills/skill-creator/scripts/package_skill.py +99 -0
  75. package/.roo/skills/skill-creator/scripts/quick_validate.py +113 -0
  76. package/.roo/skills/story-status-lookup/SKILL.md +78 -0
  77. package/.roo/skills/test-accompanied-development/SKILL.md +50 -0
  78. package/.roo/skills/test-generator/SKILL.md +65 -0
  79. package/.roo/skills/vercel-react-best-practices/SKILL.md +109 -0
  80. package/.roo/skills/verify-hardened-docker-skill/SKILL.md +442 -0
  81. package/.roo/skills/verify-hardened-docker-skill/scripts/verify-docker-hardening.sh +439 -0
  82. package/README.md +50 -3
  83. package/lib/agents.js +23 -0
  84. package/lib/bmad-extension/module-help.csv +8 -4
  85. package/lib/bmad-extension/skills/add-sprint/SKILL.md +126 -40
  86. package/lib/bmad-extension/skills/add-to-sprint/SKILL.md +116 -142
  87. package/lib/bmad-extension/skills/cleanup-done/.gitkeep +0 -0
  88. package/lib/bmad-extension/skills/cleanup-done/SKILL.md +159 -0
  89. package/lib/bmad-extension/skills/cleanup-done/bmad-skill-manifest.yaml +3 -0
  90. package/lib/bmad-extension/skills/create-bug-story/SKILL.md +75 -7
  91. package/lib/bmad-extension/skills/generate-backlog/SKILL.md +183 -0
  92. package/lib/bmad-extension/skills/generate-backlog/bmad-skill-manifest.yaml +3 -0
  93. package/lib/bmad-extension/skills/modify-sprint/SKILL.md +63 -0
  94. package/lib/bmad-extension/skills/prioritize-backlog/.gitkeep +0 -0
  95. package/lib/bmad-extension/skills/prioritize-backlog/SKILL.md +195 -0
  96. package/lib/bmad-extension/skills/prioritize-backlog/bmad-skill-manifest.yaml +3 -0
  97. package/lib/bmad-extension/skills/remove-from-sprint/.gitkeep +0 -0
  98. package/lib/bmad-extension/skills/remove-from-sprint/SKILL.md +163 -0
  99. package/lib/bmad-extension/skills/remove-from-sprint/bmad-skill-manifest.yaml +3 -0
  100. package/lib/bmad-extension/skills/sprint-status-view/SKILL.md +199 -138
  101. package/lib/bmad-extension/workflows/add-sprint/workflow.md +129 -39
  102. package/lib/bmad-extension/workflows/add-to-sprint/workflow.md +3 -205
  103. package/lib/bmad-extension/workflows/modify-sprint/workflow.md +5 -0
  104. package/lib/bmad-extension/workflows/sprint-status-view/workflow.md +3 -192
  105. package/package.json +4 -3
  106. package/test/roo-code-agent.test.js +166 -0
  107. package/test/roo-code-injection.test.js +172 -0
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: cleanup-done
3
+ description: Archive done stories and bugs — move files to done/ subfolder and remove from sprint/backlog
4
+ type: skill
5
+ triggers:
6
+ - "cleanup done"
7
+ - "archive done items"
8
+ ---
9
+
10
+ # Cleanup-Done Workflow
11
+
12
+ Archive done stories and bugs — move files to the `done/` subfolder and remove from sprint/backlog tracking.
13
+
14
+ <workflow>
15
+
16
+ <step n="1" goal="Identify all done items across data sources">
17
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` — collect all story keys where status is `done`</action>
18
+ <action>Read `_bmad-output/implementation-artifacts/backlog.yaml` — collect all items where status is `done`</action>
19
+ <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` — for each bug file, parse YAML frontmatter and collect those with `status: done`</action>
20
+ <action>Deduplicate across all three sources — build {{done_items}} as a unified list with: id, title, type (story/bug), source_file</action>
21
+ <check if="no done items found">
22
+ <output>No items with status `done` found across sprint-status.yaml, backlog.yaml, or bug files. Nothing to archive.</output>
23
+ <action>Exit workflow</action>
24
+ </check>
25
+ </step>
26
+
27
+ <step n="2" goal="Display done items and confirm archival scope">
28
+ <output>
29
+ ## Done Items Ready for Archival
30
+
31
+ | # | ID | Title | Type | Source |
32
+ |---|---|---|---|---|
33
+ {{#each done_items}}
34
+ | {{@index+1}} | {{id}} | {{title}} | {{type}} | {{source}} |
35
+ {{/each}}
36
+
37
+ *Total: {{done_items.length}} items*
38
+ </output>
39
+ <ask>Options:
40
+ - [a] Archive all
41
+ - [s] Select specific items (enter item numbers)
42
+ - [q] Cancel
43
+
44
+ Choice:</ask>
45
+ <check if="user selects 'q'">
46
+ <output>Cancelled. No changes made.</output>
47
+ <action>Exit workflow</action>
48
+ </check>
49
+ <check if="user selects 'a'">
50
+ <action>Set {{items_to_archive}} = all {{done_items}}</action>
51
+ </check>
52
+ <check if="user selects 's'">
53
+ <ask>Enter item numbers to archive (comma-separated):</ask>
54
+ <action>Resolve entered numbers against the table above</action>
55
+ <action>Set {{items_to_archive}} = selected items</action>
56
+ </check>
57
+ </step>
58
+
59
+ <step n="3" goal="Ensure done/ directory exists">
60
+ <action>Check if `_bmad-output/implementation-artifacts/done/` directory exists</action>
61
+ <action>If not, create it</action>
62
+ </step>
63
+
64
+ <step n="4" goal="Move files to done/ directory">
65
+ <action>For each item in {{items_to_archive}}:
66
+
67
+ **Stories** (type == story):
68
+ - Source: `_bmad-output/implementation-artifacts/{id}.md`
69
+ - Destination: `_bmad-output/implementation-artifacts/done/{id}.md`
70
+ - Use rename/move operation
71
+ - Skip if source file does not exist (log warning)
72
+ - Skip if destination file already exists (log warning — do not overwrite)
73
+
74
+ **Bugs** (type == bug):
75
+ - Source: `_bmad-output/implementation-artifacts/bug-{slug}.md`
76
+ - Destination: `_bmad-output/implementation-artifacts/done/bug-{slug}.md`
77
+ - Use rename/move operation
78
+ - Skip if source file does not exist (log warning)
79
+ - Skip if destination file already exists (log warning — do not overwrite)
80
+ </action>
81
+ <action>Track results: {{moved}}, {{skipped_missing}}, {{skipped_exists}}</action>
82
+ </step>
83
+
84
+ <step n="5" goal="Remove done IDs from sprint files">
85
+ <action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to find all sprint files</action>
86
+ <action>For each sprint file:
87
+ - Read the sprint's `items` array
88
+ - Check if any item IDs in the array match {{items_to_archive}}
89
+ - If NO matches found: skip this sprint file entirely (no modification needed)
90
+ - If matches found:
91
+ - Remove the matching item IDs from the array
92
+ - If items array becomes empty AND sprint status is `active`: auto-close the sprint by setting status to `closed`
93
+ - Update `last_modified` to current ISO timestamp
94
+ - Write the updated sprint file
95
+ </action>
96
+ </step>
97
+
98
+ <step n="6" goal="Remove done items from backlog.yaml">
99
+ <action>Read `_bmad-output/implementation-artifacts/backlog.yaml`</action>
100
+ <action>Remove all entries whose ID is in {{items_to_archive}}</action>
101
+ <action>Re-number remaining item priorities sequentially: 1, 2, 3, ..., N</action>
102
+ <action>Write updated `_bmad-output/implementation-artifacts/backlog.yaml`</action>
103
+ </step>
104
+
105
+ <step n="7" goal="Remove done entries from sprint-status.yaml">
106
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml`</action>
107
+ <action>In the `development_status` section:
108
+ - Remove done story keys that are in {{items_to_archive}}
109
+ - Remove done bug keys that are in {{items_to_archive}}
110
+ - Do NOT remove epic keys (keys matching `epic-*`)
111
+ - Do NOT remove retrospective keys (keys ending with `-retrospective`)
112
+ - If all stories belonging to an epic have been removed: set that epic's status to `done`
113
+ - Preserve YAML comments where possible
114
+ </action>
115
+ <action>Write updated `_bmad-output/implementation-artifacts/sprint-status.yaml`</action>
116
+ </step>
117
+
118
+ <step n="8" goal="Report summary">
119
+ <output>
120
+ ## Archival Complete
121
+
122
+ **Files moved to `done/`:** {{moved_count}}
123
+ {{#each moved_items}}
124
+ - {{id}} ({{type}}) -> done/
125
+ {{/each}}
126
+
127
+ {{#if skipped_missing.length}}
128
+ **Skipped (source missing):** {{skipped_missing.length}}
129
+ {{#each skipped_missing}}
130
+ - {{id}} — source file not found
131
+ {{/each}}
132
+ {{/if}}
133
+
134
+ {{#if skipped_exists.length}}
135
+ **Skipped (already in done/):** {{skipped_exists.length}}
136
+ {{#each skipped_exists}}
137
+ - {{id}} — destination already exists
138
+ {{/each}}
139
+ {{/if}}
140
+
141
+ **Sprint updates:**
142
+ {{#each updated_sprints}}
143
+ - {{sprint_id}}: removed {{removed_count}} item(s){{#if auto_closed}} — auto-closed (no remaining items){{/if}}
144
+ {{/each}}
145
+
146
+ **Backlog:** {{backlog_removed_count}} items removed, priorities renumbered 1..{{backlog_remaining_count}}
147
+
148
+ **Sprint-status.yaml:** {{status_removed_count}} entries removed
149
+ {{#if epics_marked_done.length}}
150
+ - Epics marked done: {{#each epics_marked_done}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}
151
+ {{/if}}
152
+
153
+ **Next Steps:**
154
+ - Use `/sprint-status-view` to verify updated sprint state
155
+ - Use `/prioritize-backlog` to reorder remaining backlog items
156
+ </output>
157
+ </step>
158
+
159
+ </workflow>
@@ -0,0 +1,3 @@
1
+ type: skill
2
+ name: cleanup-done
3
+ module: ma-skills
@@ -55,7 +55,32 @@ Guided workflow to create a structured bug story from a detected defect and add
55
55
  <action>Store as {{actual_behavior}}</action>
56
56
  </step>
57
57
 
58
- <step n="4" goal="Gather root cause hypothesis and affected files">
58
+ <step n="4" goal="Gather version and bug type">
59
+ <ask>What version was this bug found in? (optional — press Enter to skip; e.g., "2.3.1", "v1.0.0-rc2")</ask>
60
+ <action>Store as {{version_found}} (empty string if skipped)</action>
61
+
62
+ <output>
63
+ **Bug type classifications:**
64
+ - `regression` — Previously working feature now broken
65
+ - `functional` — Feature does not work as specified
66
+ - `performance` — Unacceptable latency, throughput, or resource usage
67
+ - `security` — Vulnerability or authentication/authorization flaw
68
+ - `ui` — Visual or interaction defect
69
+ - `data` — Data corruption, loss, or incorrect transformation
70
+ - `integration` — Failure at system/service boundaries
71
+ - `other` — Does not fit the above categories
72
+ </output>
73
+ <ask>What is the bug type? [regression / functional / performance / security / ui / data / integration / other] (default: functional)</ask>
74
+ <action>Store as {{bug_type}}</action>
75
+ <action>If empty or blank, default to "functional"</action>
76
+ <action>Normalize to lowercase</action>
77
+ <check if="{{bug_type}} is not one of: regression, functional, performance, security, ui, data, integration, other">
78
+ <output>❌ Bug type must be one of: regression, functional, performance, security, ui, data, integration, other.</output>
79
+ <goto step="4" />
80
+ </check>
81
+ </step>
82
+
83
+ <step n="5" goal="Gather root cause hypothesis and affected files">
59
84
  <ask>What is your root cause hypothesis? (optional — press Enter to skip; e.g., "Null check missing in validateUser()")</ask>
60
85
  <action>Store as {{root_cause}} (empty string if skipped)</action>
61
86
 
@@ -67,7 +92,7 @@ Guided workflow to create a structured bug story from a detected defect and add
67
92
  <action>Store as {{suggested_fix}} (empty string if skipped)</action>
68
93
  </step>
69
94
 
70
- <step n="5" goal="Confirm all bug details before writing">
95
+ <step n="6" goal="Confirm all bug details before writing">
71
96
  <action>Derive {{title_slug}} by converting {{bug_title}} to lowercase kebab-case:
72
97
  - Convert to lowercase
73
98
  - Replace spaces and underscores with hyphens
@@ -82,6 +107,8 @@ Guided workflow to create a structured bug story from a detected defect and add
82
107
 
83
108
  - **Title:** {{bug_title}}
84
109
  - **Severity:** {{severity}}
110
+ - **Bug Type:** {{bug_type}}
111
+ - **Version Found:** {{version_found}} *(empty if skipped)*
85
112
  - **Affected Component:** {{affected_component}}
86
113
  - **Reproduction Steps:** {{reproduction_steps}}
87
114
  - **Expected Behavior:** {{expected_behavior}}
@@ -93,14 +120,15 @@ Guided workflow to create a structured bug story from a detected defect and add
93
120
  </output>
94
121
  <ask>Confirm creation? [y] Yes / [n] Cancel / [e] Edit a field:</ask>
95
122
  <check if="user selects 'e'">
96
- <ask>Which field to edit? (title / severity / component / steps / expected / actual / root-cause / files / fix)</ask>
123
+ <ask>Which field to edit? (title / severity / component / steps / expected / actual / version / bug-type / root-cause / files / fix)</ask>
97
124
  <check if="field == 'title' OR field == 'severity'"><goto step="1" /></check>
98
125
  <check if="field == 'component' OR field == 'steps'"><goto step="2" /></check>
99
126
  <check if="field == 'expected' OR field == 'actual'"><goto step="3" /></check>
100
- <check if="field == 'root-cause' OR field == 'files' OR field == 'fix'"><goto step="4" /></check>
127
+ <check if="field == 'version' OR field == 'bug-type'"><goto step="4" /></check>
128
+ <check if="field == 'root-cause' OR field == 'files' OR field == 'fix'"><goto step="5" /></check>
101
129
  <check if="none of the above matched">
102
- <output>❌ Unrecognized field. Valid options: title / severity / component / steps / expected / actual / root-cause / files / fix</output>
103
- <goto step="5" />
130
+ <output>❌ Unrecognized field. Valid options: title / severity / component / steps / expected / actual / version / bug-type / root-cause / files / fix</output>
131
+ <goto step="6" />
104
132
  </check>
105
133
  </check>
106
134
  <check if="user selects 'n'">
@@ -109,7 +137,7 @@ Guided workflow to create a structured bug story from a detected defect and add
109
137
  </check>
110
138
  </step>
111
139
 
112
- <step n="6" goal="Write bug story file">
140
+ <step n="7" goal="Write bug story file">
113
141
  <action>Check if {{output_file}} already exists</action>
114
142
  <check if="file already exists">
115
143
  <output>⚠️ A bug story already exists at `{{output_file}}`.</output>
@@ -136,7 +164,10 @@ Guided workflow to create a structured bug story from a detected defect and add
136
164
  ```
137
165
  ---
138
166
  type: bug
167
+ status: backlog
139
168
  severity: {{severity}}
169
+ bug_type: {{bug_type}}
170
+ version_found: {{version_found}}
140
171
  title: {{bug_title}}
141
172
  ---
142
173
 
@@ -183,8 +214,45 @@ title: {{bug_title}}
183
214
  - **File:** `{{output_file}}`
184
215
  - **Title:** {{bug_title}}
185
216
  - **Severity:** {{severity}}
217
+ - **Bug Type:** {{bug_type}}
186
218
  - **Component:** {{affected_component}}
219
+ </output>
220
+ </step>
221
+
222
+ <step n="8" goal="Add bug entry to backlog.yaml">
223
+ <action>Check if `_bmad-output/implementation-artifacts/backlog.yaml` exists</action>
224
+
225
+ <check if="backlog.yaml exists">
226
+ <action>Read `_bmad-output/implementation-artifacts/backlog.yaml`</action>
227
+ <action>Determine the next priority number by finding the highest existing priority value and adding 1</action>
228
+ <action>Append a new entry at the end of the backlog items list with the following format:
229
+ ```yaml
230
+ - id: "BUG-{{title_slug}}"
231
+ type: bug
232
+ epic: null
233
+ title: "{{bug_title}}"
234
+ priority: N
235
+ status: backlog
236
+ sprint: null
237
+ severity: {{severity}}
238
+ ```
239
+ Where N is the next priority number.
240
+ </action>
241
+ <action>Re-number all priorities sequentially (1, 2, 3, ...) from top to bottom to ensure no gaps</action>
242
+ <action>Write the updated backlog.yaml back to disk</action>
243
+ <output>
244
+ 📋 **Backlog updated!** Added `BUG-{{title_slug}}` to `_bmad-output/implementation-artifacts/backlog.yaml` with priority {{N}}.
245
+ </output>
246
+ </check>
187
247
 
248
+ <check if="backlog.yaml does not exist">
249
+ <output>
250
+ ℹ️ No `backlog.yaml` found at `_bmad-output/implementation-artifacts/backlog.yaml`.
251
+ Run `/generate-backlog` to create a backlog that will include this bug story.
252
+ </output>
253
+ </check>
254
+
255
+ <output>
188
256
  **Next Steps:**
189
257
  - Use `/add-to-sprint` to assign this bug to the current sprint
190
258
  - Use `/sprint-status-view` to see all sprint items including this bug
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: generate-backlog
3
+ description: Generate or refresh a flat backlog.yaml from epics and bug stories, preserving existing priority and sprint assignments
4
+ type: skill
5
+ triggers:
6
+ - "generate backlog"
7
+ - "refresh backlog"
8
+ ---
9
+
10
+ # Generate Backlog Workflow
11
+
12
+ Generate or refresh a flat `backlog.yaml` from epic stories and bug reports. Preserves existing priority and sprint assignments, appends new items, removes stale items, and re-numbers priorities 1..N.
13
+
14
+ <workflow>
15
+
16
+ <step n="1" goal="Load sources">
17
+ <action>Read `_bmad-output/planning-artifacts/epics.md` — this is the master list of epics with their stories.</action>
18
+ <check if="epics.md does not exist">
19
+ <output>**Error:** `_bmad-output/planning-artifacts/epics.md` not found. Cannot generate backlog without an epics file.</output>
20
+ <action>Exit workflow</action>
21
+ </check>
22
+
23
+ <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files.</action>
24
+ <action>Store the list of bug files as {{bug_files}} (may be empty — zero bugs is valid).</action>
25
+
26
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` if it exists — this provides the current status of each story (done, in-progress, backlog, etc.).</action>
27
+ <action>Store the status map as {{status_map}} (keyed by story id). If the file does not exist, use an empty map.</action>
28
+
29
+ <action>Read `_bmad-output/implementation-artifacts/backlog.yaml` if it exists — this is the existing backlog to merge with.</action>
30
+ <action>Store the existing backlog items as {{existing_items}} (list). If the file does not exist, use an empty list.</action>
31
+
32
+ <output>
33
+ **Sources loaded:**
34
+ - epics.md: found
35
+ - Bug files: {{bug_files | length}} file(s)
36
+ - sprint-status.yaml: {{status_map exists ? "found" : "not found (empty status)"}}
37
+ - Existing backlog.yaml: {{existing_items | length}} item(s)
38
+ </output>
39
+ </step>
40
+
41
+ <step n="2" goal="Extract stories from epics">
42
+ <action>Parse `epics.md` to extract every story from every epic. Each epic is a level-2 heading (`## Epic N: ...`) and each story within it is a level-3 heading (`### Story N.M: ...`) or a list item following the pattern `- **Story N.M:** Title` or `- N.M: Title`.</action>
43
+
44
+ <action>For each story found:
45
+ - Derive {{story_id}} as a kebab-case slug: `"{epic_number}-{story_number}-{title_slug}"` (e.g., `"5-5-explicit-parameter-passing"`)
46
+ - Title slug: lowercase, replace spaces/underscores with hyphens, remove non-alphanumeric/non-hyphen characters, collapse consecutive hyphens, trim leading/trailing hyphens
47
+ - Set {{epic}} to the epic number (integer)
48
+ - Set {{title}} to the story title text
49
+ - Look up status from {{status_map}} using the story identifier. If found and status is `done`, skip this story (exclude from backlog). If found, use that status. If not found, default to `backlog`.
50
+ - Set {{type}} = `story`
51
+ - Set {{severity}} = `null`
52
+ - Set {{sprint}} = `null`
53
+ - Set {{priority}} = `null` (will be assigned during merge/sort)
54
+ </action>
55
+
56
+ <action>Store the extracted stories as {{extracted_stories}} list.</action>
57
+ <output>Extracted {{extracted_stories | length}} active stories from epics (done items excluded).</output>
58
+ </step>
59
+
60
+ <step n="3" goal="Extract bugs">
61
+ <action>For each file in {{bug_files}}:
62
+ - Read the file and parse the YAML frontmatter (between `---` delimiters)
63
+ - Extract `title`, `severity`, and `status` from frontmatter
64
+ - Derive {{bug_id}} from the **filename**, not the title: strip the `bug-` prefix and `.md` extension, then uppercase to `"BUG-{slug}"` (e.g., `bug-login-crash.md` → `BUG-login-crash`)
65
+ - Use `status` from frontmatter directly (bugs track their own status). If `status` is missing, default to `backlog`. If status is `done`, skip this bug (exclude from backlog).
66
+ - Build a backlog item:
67
+ - id: {{bug_id}}
68
+ - type: `bug`
69
+ - epic: `null`
70
+ - title: {{title}}
71
+ - priority: `null` (assigned during merge/sort)
72
+ - status: {{frontmatter_status or "backlog"}}
73
+ - sprint: `null`
74
+ - severity: {{severity}}
75
+ </action>
76
+
77
+ <action>Store the extracted bugs as {{extracted_bugs}} list.</action>
78
+ <output>Extracted {{extracted_bugs | length}} active bugs (done items excluded).</output>
79
+ </step>
80
+
81
+ <step n="4" goal="Merge with existing backlog">
82
+ <action>Combine {{extracted_stories}} and {{extracted_bugs}} into {{new_items}} list.</action>
83
+
84
+ <action>Build a lookup map from {{existing_items}} keyed by `id`.</action>
85
+
86
+ <action>For each item in {{new_items}}:
87
+ - If an item with the same `id` exists in {{existing_items}}:
88
+ - **Preserve** the existing `priority` value
89
+ - **Preserve** the existing `sprint` assignment
90
+ - **Update** `status` from the freshly extracted value (which may reflect sprint-status.yaml changes)
91
+ - **Update** `title`, `type`, `epic`, `severity` from the freshly extracted values (source of truth)
92
+ - If no matching item exists in {{existing_items}}:
93
+ - This is a new item — keep all freshly extracted values
94
+ - Set `priority` to `null` (will be placed at the end during sort)
95
+ </action>
96
+
97
+ <action>Identify stale items: any item in {{existing_items}} whose `id` does NOT appear in {{new_items}}. These items no longer exist in the source files and should be removed.</action>
98
+
99
+ <action>Store the final merged list as {{merged_items}}.</action>
100
+ <action>Store the count of new items added as {{new_count}}.</action>
101
+ <action>Store the count of stale items removed as {{stale_count}}.</action>
102
+ <action>Store the count of preserved items as {{preserved_count}}.</action>
103
+
104
+ <output>
105
+ **Merge results:**
106
+ - Preserved (existing): {{preserved_count}}
107
+ - New items added: {{new_count}}
108
+ - Stale items removed: {{stale_count}}
109
+ </output>
110
+ </step>
111
+
112
+ <step n="5" goal="Write backlog.yaml">
113
+ <action>Sort {{merged_items}} for final output:
114
+ 1. Items WITH an existing numeric `priority` come first, sorted ascending by priority
115
+ 2. Items WITHOUT a priority (`null`) come after, sorted by:
116
+ a. `type`: bugs before stories (bugs get priority attention)
117
+ b. `severity` for bugs: critical > high > medium > low
118
+ c. `epic` number ascending for stories (lower epics first)
119
+ d. `id` alphabetically as final tiebreaker
120
+ </action>
121
+
122
+ <action>Re-number priorities sequentially 1..N across all items in the sorted list.</action>
123
+
124
+ <action>Get current ISO timestamp as {{generated_at}}.</action>
125
+
126
+ <action>Write `_bmad-output/implementation-artifacts/backlog.yaml` with this structure:
127
+
128
+ ```yaml
129
+ # Flat Backlog — auto-generated by generate-backlog
130
+ # Generated: {{generated_at}}
131
+ # Total items: {{merged_items | length}}
132
+ #
133
+ # Schema per item:
134
+ # id, type, epic, title, priority, status, sprint, severity
135
+
136
+ backlog:
137
+ - id: "5-5-explicit-parameter-passing"
138
+ type: story
139
+ epic: 5
140
+ title: "Explicit Parameter Passing"
141
+ priority: 1
142
+ status: backlog
143
+ sprint: null
144
+ severity: null
145
+ # ... remaining items ...
146
+ ```
147
+
148
+ **YAML output rules:**
149
+ - Always quote `id` and `title` fields (they contain hyphens and special characters)
150
+ - `epic` is an integer for stories, `null` for bugs
151
+ - `sprint` is a string like `"sprint-3"` if assigned, or `null`
152
+ - `severity` is a string (`critical`, `high`, `medium`, `low`) for bugs, `null` for stories
153
+ - `status` is one of: `backlog`, `ready-for-dev`, `in-progress`, `review` (done items excluded)
154
+ - `priority` is always a positive integer (1 = highest priority)
155
+ - Use 2-space indentation for YAML
156
+ </action>
157
+
158
+ <output>Backlog written to `_bmad-output/implementation-artifacts/backlog.yaml` with {{merged_items | length}} items.</output>
159
+ </step>
160
+
161
+ <step n="6" goal="Report summary">
162
+ <output>
163
+ ## Backlog Generation Complete
164
+
165
+ | Metric | Count |
166
+ |----------------------|-------|
167
+ | Total items | {{merged_items | length}} |
168
+ | Stories | {{story_count}} |
169
+ | Bugs | {{bug_count}} |
170
+ | New items added | {{new_count}} |
171
+ | Stale items removed | {{stale_count}} |
172
+ | Items preserved | {{preserved_count}} |
173
+
174
+ **Output:** `_bmad-output/implementation-artifacts/backlog.yaml`
175
+
176
+ **Next Steps:**
177
+ - Review priorities — new items are appended at the end; reorder as needed
178
+ - Use `/add-to-sprint` to assign high-priority items to the current sprint
179
+ - Use `/sprint-status-view` to see sprint progress
180
+ </output>
181
+ </step>
182
+
183
+ </workflow>
@@ -0,0 +1,3 @@
1
+ type: skill
2
+ name: generate-backlog
3
+ module: ma-skills
@@ -7,12 +7,75 @@ triggers:
7
7
  - "edit sprint"
8
8
  ---
9
9
 
10
+ <!-- PARTIALLY REWORKED: Item assignment is handled by /add-to-sprint (Story 17.4).
11
+ Item removal is handled by /remove-from-sprint (Story 17.5).
12
+ Sprint activation (planning -> active) is handled below (Step 3e).
13
+ The legacy workflow below still references old sprint-plan-{n}.yaml paths for
14
+ other operations. A full rework of modify-sprint is planned for a future story. -->
15
+
16
+ > **Note:** Item assignment and removal are now handled by `/add-to-sprint` and `/remove-from-sprint`. Use the **Activate Sprint** option below to transition a sprint from `planning` to `active`.
17
+
10
18
  # Modify Sprint Workflow
11
19
 
12
20
  Guided workflow to modify an existing sprint — add/remove items, change capacity, update metadata.
13
21
 
14
22
  <workflow>
15
23
 
24
+ <step n="3e" goal="Activate a sprint (planning -> active)">
25
+ <action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover all sprint files</action>
26
+ <check if="no sprint files found">
27
+ <output>No sprints found. Run `/add-sprint` first.</output>
28
+ <action>Exit workflow</action>
29
+ </check>
30
+ <action>Read each sprint file; extract: id, name, status, capacity, items count</action>
31
+ <action>Display sprints table</action>
32
+ <output>
33
+ ## Available Sprints
34
+
35
+ | # | ID | Name | Status | Items | Capacity |
36
+ |---|---|---|---|---|---|
37
+ {{#each sprints}}
38
+ | {{@index+1}} | {{id}} | {{name}} | {{status}} | {{items_count}} | {{capacity}} |
39
+ {{/each}}
40
+ </output>
41
+ <ask>Which sprint to activate? (enter number, or 'q' to cancel):</ask>
42
+ <check if="user enters 'q'">
43
+ <output>Cancelled.</output>
44
+ <action>Exit workflow</action>
45
+ </check>
46
+ <action>Store selected sprint as {{target_sprint}}</action>
47
+
48
+ <!-- Validate transition -->
49
+ <check if="target_sprint.status != 'planning'">
50
+ <output>Only sprints in `planning` status can be activated. Sprint "{{target_sprint.name}}" is currently `{{target_sprint.status}}`.</output>
51
+ <action>Exit workflow</action>
52
+ </check>
53
+
54
+ <!-- Check single-active constraint -->
55
+ <action>Check if any other sprint has status `active`</action>
56
+ <check if="another sprint is already active">
57
+ <output>Cannot activate "{{target_sprint.name}}" — sprint "{{active_sprint.name}}" ({{active_sprint.id}}) is already active. Close it first before activating another sprint.</output>
58
+ <action>Exit workflow</action>
59
+ </check>
60
+
61
+ <ask>Activate "{{target_sprint.name}}" ({{target_sprint.id}})? This will set status to `active`. [y] Yes / [n] Cancel:</ask>
62
+ <check if="user selects 'n'">
63
+ <output>Cancelled.</output>
64
+ <action>Exit workflow</action>
65
+ </check>
66
+
67
+ <action>Set target_sprint.status = "active"</action>
68
+ <action>Update `last_modified` to current ISO timestamp</action>
69
+ <action>Write updated sprint file to `_bmad-output/implementation-artifacts/sprints/{{target_sprint.id}}.yaml`</action>
70
+ <output>
71
+ Sprint "{{target_sprint.name}}" is now **active**.
72
+
73
+ **Next Steps:**
74
+ - Use `/add-to-sprint` to assign backlog items
75
+ - Use `/sprint-status-view` to see sprint progress
76
+ </output>
77
+ </step>
78
+
16
79
  <step n="1" goal="List available sprints and select one to modify">
17
80
  <action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
18
81
  <check if="no sprint files found">