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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: add-sprint
3
- description: Guided workflow to create a new sprint with capacity limits for realistic sprint planning
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 for realistic sprint planning.
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 (e.g., 1, 2, 3)</action>
18
- <ask>What is the sprint number? (e.g., 1)</ask>
19
- <action>Store as {{sprint_number}}</action>
20
- <ask>What is the sprint name? (e.g., "Sprint 1 Foundation") press Enter to use "Sprint {{sprint_number}}"</ask>
21
- <action>If user presses Enter or leaves blank, default to "Sprint {{sprint_number}}"</action>
22
- <action>Store as {{sprint_name}}</action>
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="3" goal="Gather optional start and end context">
38
- <action>Explain: start/end context can be dates (e.g., "2026-03-18") or milestone descriptions (e.g., "Q1 Planning Complete")</action>
39
- <ask>Optional — Sprint start context (date or milestone, press Enter to skip):</ask>
40
- <action>Store as {{start_context}} (empty string if skipped)</action>
41
- <ask>Optional Sprint end context (date or milestone, press Enter to skip):</ask>
42
- <action>Store as {{end_context}} (empty string if skipped)</action>
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 Number:** {{sprint_number}}
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 Context:** {{start_context}} *(empty if skipped)*
53
- - **End Context:** {{end_context}} *(empty if skipped)*
54
- - **Output File:** `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`
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:</ask>
61
- <action>Store as {{sprint_number}}</action>
62
- <action>If sprint name was auto-defaulted to the old "Sprint {n}", update it to "Sprint {{sprint_number}}"</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="3" /></check>
72
- <check if="field == 'end'"><goto step="3" /></check>
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 artifact file">
81
- <action>Determine output path: `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`</action>
82
- <action>Check if file already exists at output path</action>
83
- <check if="file already exists">
84
- <output>⚠️ A sprint plan already exists at `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`.</output>
85
- <ask>Overwrite existing sprint plan? [y] Yes / [n] Cancel:</ask>
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 plan.</output>
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 artifact YAML to `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml` with this structure:
172
+ <action>Write sprint entity YAML to `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml` with this structure:
93
173
 
94
174
  ```yaml
95
- sprint_number: {{sprint_number}}
96
- sprint_name: "{{sprint_name}}"
97
- capacity: {{capacity}}
98
- assigned_items: []
175
+ id: {{sprint_id}}
176
+ name: "{{sprint_name}}"
99
177
  status: planning
100
- start_context: "{{start_context}}"
101
- end_context: "{{end_context}}"
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/sprint-plan-{{sprint_number}}.yaml`
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 using multi-criteria prioritization
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 (stories + bugs) to a sprint using multi-criteria prioritization.
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="1a" goal="Discover user story backlog items from sprint-status.yaml">
17
- <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` — authoritative source for user story execution status</action>
18
- <action>Parse the development_status section. For each entry:
19
- - Skip epic keys (keys matching `epic-*`)
20
- - Skip retrospective keys (keys ending with `-retrospective`)
21
- - Collect story keys and their current status (backlog, ready-for-dev, in-progress, review, done)
22
- </action>
23
- <action>Store as {{user_stories}} — list of objects with: key, status</action>
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="Present flat backlog combining stories and bugs">
51
- <action>Combine {{user_stories}} and {{bug_stories}} into a flat backlog list</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>❌ No sprint plans found. Run `/add-sprint` first to create a sprint before assigning items.</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>For each sprint file found, read and extract: sprint_number, sprint_name, capacity, assigned_items count, status</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
- ## 🏃 Available Sprints
37
+ ## Available Sprints
75
38
 
76
- | # | Sprint | Status | Capacity | Assigned | Remaining |
77
- |---|---|---|---|---|---|
39
+ | # | ID | Name | Status | Capacity | Assigned | Remaining |
40
+ |---|---|---|---|---|---|---|
78
41
  {{#each sprints}}
79
- | {{@index+1}} | {{sprint_name}} | {{status}} | {{capacity}} | {{assigned_count}} | {{remaining}} |
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
- <ask>Select target sprint (enter number):</ask>
83
- <action>Store selected sprint data as {{target_sprint}}</action>
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="4" goal="Display current sprint capacity usage">
87
- <action>Calculate: {{assigned_count}} = length of {{target_sprint.assigned_items}}</action>
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.sprint_name}}
74
+ ## Sprint Capacity: {{target_sprint.name}} ({{target_sprint.id}})
91
75
 
92
- - **Capacity:** {{target_sprint.capacity}} items
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
- ⚠️ This sprint is **at or over capacity**. Adding items will exceed the limit.
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
- <step n="6" goal="Multi-criteria prioritization guidance">
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
- ## 🎯 Prioritization Analysis
85
+ ## Unassigned Backlog Items
127
86
 
128
- | Rank | ID / File | Title | Type | Business Value | Dependencies | Severity | Effort | Rationale |
129
- |---|---|---|---|---|---|---|---|---|
130
- {{#each ranked_items}}
131
- | {{rank}} | {{id}} | {{title}} | {{type}} | {{business_value}} | {{dependency_status}} | {{severity}} | {{effort}} | {{rationale}} |
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
- **Recommended selection** (up to {{remaining_capacity}} items to stay within capacity): {{recommended_selection}}
93
+ *Showing {{displayed_count}} of {{total_unassigned}} unassigned items.*
135
94
  </output>
136
95
  </step>
137
96
 
138
- <step n="7" goal="User confirms or adjusts ranking">
139
- <ask>Review the ranking above. Options:
140
- - [c] Confirm recommended selection as-is
141
- - [m] Modify selection (specify item numbers to include)
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 selects 'm'">
151
- <ask>Enter item numbers to assign (comma-separated):</ask>
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 selects 'c'">
159
- <action>Set {{confirmed_items}} = recommended selection</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="8" goal="Assign selected items to sprint with capacity enforcement">
165
- <action>For each item in {{confirmed_items}}, in confirmed ranking order:</action>
166
- <action>Re-calculate current assigned count (in case multiple items are being added)</action>
167
- <check if="assigning this item would exceed capacity">
168
- <output>⚠️ **Capacity Warning:** Adding "{{item.title}}" would bring assigned items to {{new_count}}/{{target_sprint.capacity}} exceeding sprint capacity by {{overage}}.</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
- - [m] Modify sprint capacity first via `/modify-sprint`
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 do not add to sprint. Continue to next item in the {{confirmed_items}} loop.</action>
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 'm'">
179
- <output>💡 Run `/modify-sprint` to increase capacity for {{target_sprint.sprint_name}}, then re-run `/add-to-sprint`.</output>
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>Add item identifier to {{target_sprint.assigned_items}} list in the sprint-plan-{{target_sprint.sprint_number}}.yaml artifact</action>
184
- <action>Item identifier format: story key for user stories (e.g., `12-1-add-sprint-workflow`), file basename for bugs (e.g., `bug-login-crash`)</action>
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="9" goal="Persist changes and display confirmed ranking for auditability">
188
- <action>Update `_bmad-output/implementation-artifacts/sprint-plan-{{target_sprint.sprint_number}}.yaml`:
189
- - Update `assigned_items` list with all newly assigned item identifiers
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
- <action>**Do NOT modify sprint-status.yaml** sprint membership is exclusively tracked in sprint-plan-{n}.yaml</action>
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
- ## Assignment Complete
195
-
196
- **Sprint:** {{target_sprint.sprint_name}}
197
- **Items assigned this session:** {{assigned_this_session}}
169
+ ## Assignment Complete
198
170
 
199
- ### Confirmed Ranking (Audit Record)
171
+ **Sprint:** {{target_sprint.name}} ({{target_sprint.id}})
172
+ **Items assigned this session:** {{assigned_count_this_session}}
200
173
 
201
- | Rank | ID | Title | Type | Business Value | Dependencies | Severity | Effort |
202
- |---|---|---|---|---|---|---|---|
203
- {{#each confirmed_ranking}}
204
- | {{rank}} | {{id}} | {{title}} | {{type}} | {{business_value}} | {{dependency_status}} | {{severity}} | {{effort}} |
174
+ | # | ID | Title | Type | Priority |
175
+ |---|---|---|---|---|
176
+ {{#each assigned_items}}
177
+ | {{@index+1}} | {{id}} | {{title}} | {{type}} | {{priority}} |
205
178
  {{/each}}
206
179
 
207
- **Updated Capacity:** {{new_assigned_count}}/{{target_sprint.capacity}} items used ({{new_remaining}} remaining)
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>