ma-agents 2.20.3 → 2.22.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 (149) hide show
  1. package/.opencode/skills/.ma-agents.json +241 -0
  2. package/.opencode/skills/MANIFEST.yaml +254 -0
  3. package/.opencode/skills/ai-audit-trail/SKILL.md +23 -0
  4. package/.opencode/skills/auto-bug-detection/SKILL.md +169 -0
  5. package/.opencode/skills/cmake-best-practices/SKILL.md +64 -0
  6. package/.opencode/skills/cmake-best-practices/examples/cmake.md +59 -0
  7. package/.opencode/skills/code-documentation/SKILL.md +57 -0
  8. package/.opencode/skills/code-documentation/examples/cpp.md +29 -0
  9. package/.opencode/skills/code-documentation/examples/csharp.md +28 -0
  10. package/.opencode/skills/code-documentation/examples/javascript_typescript.md +28 -0
  11. package/.opencode/skills/code-documentation/examples/python.md +57 -0
  12. package/.opencode/skills/code-review/SKILL.md +43 -0
  13. package/.opencode/skills/commit-message/SKILL.md +79 -0
  14. package/.opencode/skills/cpp-best-practices/SKILL.md +234 -0
  15. package/.opencode/skills/cpp-best-practices/examples/modern-idioms.md +189 -0
  16. package/.opencode/skills/cpp-best-practices/examples/naming-and-organization.md +102 -0
  17. package/.opencode/skills/cpp-concurrency-safety/SKILL.md +60 -0
  18. package/.opencode/skills/cpp-concurrency-safety/examples/concurrency.md +73 -0
  19. package/.opencode/skills/cpp-const-correctness/SKILL.md +63 -0
  20. package/.opencode/skills/cpp-const-correctness/examples/const_correctness.md +54 -0
  21. package/.opencode/skills/cpp-memory-handling/SKILL.md +42 -0
  22. package/.opencode/skills/cpp-memory-handling/examples/modern-cpp.md +49 -0
  23. package/.opencode/skills/cpp-memory-handling/examples/smart-pointers.md +46 -0
  24. package/.opencode/skills/cpp-modern-composition/SKILL.md +64 -0
  25. package/.opencode/skills/cpp-modern-composition/examples/composition.md +51 -0
  26. package/.opencode/skills/cpp-robust-interfaces/SKILL.md +55 -0
  27. package/.opencode/skills/cpp-robust-interfaces/examples/interfaces.md +56 -0
  28. package/.opencode/skills/create-hardened-docker-skill/SKILL.md +637 -0
  29. package/.opencode/skills/create-hardened-docker-skill/scripts/create-all.sh +489 -0
  30. package/.opencode/skills/csharp-best-practices/SKILL.md +278 -0
  31. package/.opencode/skills/docker-hardening-verification/SKILL.md +28 -0
  32. package/.opencode/skills/docker-hardening-verification/scripts/verify-hardening.sh +39 -0
  33. package/.opencode/skills/docker-image-signing/SKILL.md +28 -0
  34. package/.opencode/skills/docker-image-signing/scripts/sign-image.sh +33 -0
  35. package/.opencode/skills/document-revision-history/SKILL.md +104 -0
  36. package/.opencode/skills/git-workflow-skill/SKILL.md +194 -0
  37. package/.opencode/skills/git-workflow-skill/hooks/commit-msg +61 -0
  38. package/.opencode/skills/git-workflow-skill/hooks/pre-commit +38 -0
  39. package/.opencode/skills/git-workflow-skill/hooks/prepare-commit-msg +56 -0
  40. package/.opencode/skills/git-workflow-skill/scripts/finish-feature.sh +192 -0
  41. package/.opencode/skills/git-workflow-skill/scripts/install-hooks.sh +55 -0
  42. package/.opencode/skills/git-workflow-skill/scripts/start-feature.sh +110 -0
  43. package/.opencode/skills/git-workflow-skill/scripts/validate-workflow.sh +229 -0
  44. package/.opencode/skills/js-ts-dependency-mgmt/SKILL.md +49 -0
  45. package/.opencode/skills/js-ts-dependency-mgmt/examples/dependency_mgmt.md +60 -0
  46. package/.opencode/skills/js-ts-security-skill/SKILL.md +64 -0
  47. package/.opencode/skills/js-ts-security-skill/scripts/verify-security.sh +136 -0
  48. package/.opencode/skills/logging-best-practices/SKILL.md +50 -0
  49. package/.opencode/skills/logging-best-practices/examples/cpp.md +36 -0
  50. package/.opencode/skills/logging-best-practices/examples/csharp.md +49 -0
  51. package/.opencode/skills/logging-best-practices/examples/javascript.md +77 -0
  52. package/.opencode/skills/logging-best-practices/examples/python.md +57 -0
  53. package/.opencode/skills/logging-best-practices/references/logging-standards.md +29 -0
  54. package/.opencode/skills/open-presentation/SKILL.md +35 -0
  55. package/.opencode/skills/opentelemetry-best-practices/SKILL.md +34 -0
  56. package/.opencode/skills/opentelemetry-best-practices/examples/go.md +32 -0
  57. package/.opencode/skills/opentelemetry-best-practices/examples/javascript.md +58 -0
  58. package/.opencode/skills/opentelemetry-best-practices/examples/python.md +37 -0
  59. package/.opencode/skills/opentelemetry-best-practices/references/otel-standards.md +37 -0
  60. package/.opencode/skills/python-best-practices/SKILL.md +385 -0
  61. package/.opencode/skills/python-dependency-mgmt/SKILL.md +42 -0
  62. package/.opencode/skills/python-dependency-mgmt/examples/dependency_mgmt.md +67 -0
  63. package/.opencode/skills/python-security-skill/SKILL.md +56 -0
  64. package/.opencode/skills/python-security-skill/examples/security.md +56 -0
  65. package/.opencode/skills/self-signed-cert/SKILL.md +42 -0
  66. package/.opencode/skills/self-signed-cert/scripts/generate-cert.ps1 +45 -0
  67. package/.opencode/skills/self-signed-cert/scripts/generate-cert.sh +43 -0
  68. package/.opencode/skills/skill-creator/SKILL.md +196 -0
  69. package/.opencode/skills/skill-creator/references/output-patterns.md +82 -0
  70. package/.opencode/skills/skill-creator/references/workflows.md +28 -0
  71. package/.opencode/skills/skill-creator/scripts/init_skill.py +208 -0
  72. package/.opencode/skills/skill-creator/scripts/package_skill.py +99 -0
  73. package/.opencode/skills/skill-creator/scripts/quick_validate.py +113 -0
  74. package/.opencode/skills/story-status-lookup/SKILL.md +78 -0
  75. package/.opencode/skills/test-accompanied-development/SKILL.md +50 -0
  76. package/.opencode/skills/test-generator/SKILL.md +65 -0
  77. package/.opencode/skills/vercel-react-best-practices/SKILL.md +109 -0
  78. package/.opencode/skills/verify-hardened-docker-skill/SKILL.md +442 -0
  79. package/.opencode/skills/verify-hardened-docker-skill/scripts/verify-docker-hardening.sh +439 -0
  80. package/AiAudit.md +5 -0
  81. package/QUICK_START.md +11 -5
  82. package/README.md +52 -1
  83. package/bin/cli.js +31 -4
  84. package/docs/BMAD_AI_Development_Training.pptx +0 -0
  85. package/docs/technical-notes/context-persistence-research.md +434 -0
  86. package/docs/technical-notes/enforcement-hooks-research.md +415 -0
  87. package/lib/agents.js +34 -0
  88. package/lib/bmad-extension/agents/bmm-architect.customize.yaml +5 -0
  89. package/lib/bmad-extension/agents/bmm-bmad-master.customize.yaml +5 -0
  90. package/lib/bmad-extension/agents/bmm-cyber.customize.yaml +30 -0
  91. package/lib/bmad-extension/agents/bmm-dev.customize.yaml +5 -0
  92. package/lib/bmad-extension/agents/bmm-devops.customize.yaml +30 -0
  93. package/lib/bmad-extension/agents/bmm-mil498.customize.yaml +42 -0
  94. package/lib/bmad-extension/agents/bmm-pm.customize.yaml +5 -0
  95. package/lib/bmad-extension/agents/bmm-qa.customize.yaml +5 -0
  96. package/lib/bmad-extension/agents/bmm-sm.customize.yaml +5 -0
  97. package/lib/bmad-extension/agents/bmm-sre.customize.yaml +30 -0
  98. package/lib/bmad-extension/agents/bmm-tech-writer.customize.yaml +5 -0
  99. package/lib/bmad-extension/agents/bmm-ux-designer.customize.yaml +5 -0
  100. package/lib/bmad-extension/module-help.csv +7 -0
  101. package/lib/bmad-extension/module.yaml +3 -0
  102. package/lib/bmad-extension/workflows/add-sprint/workflow.md +112 -0
  103. package/lib/bmad-extension/workflows/add-to-sprint/workflow.md +206 -0
  104. package/lib/bmad-extension/workflows/create-bug-story/workflow.md +186 -0
  105. package/lib/bmad-extension/workflows/modify-sprint/workflow.md +250 -0
  106. package/lib/bmad-extension/workflows/project-context-expansion/workflow.md +229 -0
  107. package/lib/bmad-extension/workflows/sprint-status-view/workflow.md +193 -0
  108. package/lib/bmad.js +168 -36
  109. package/lib/hooks/claude-code/verify-manifest.js +56 -0
  110. package/lib/installer.js +282 -1
  111. package/lib/methodology/BMAD_AI_Development_Training.pptx +0 -0
  112. package/lib/methodology/version.json +7 -0
  113. package/lib/skill-authoring.js +732 -0
  114. package/lib/templates/project-context.template.md +47 -0
  115. package/opencode.json +8 -0
  116. package/package.json +2 -2
  117. package/skills/auto-bug-detection/SKILL.md +165 -0
  118. package/skills/auto-bug-detection/skill.json +8 -0
  119. package/skills/code-review/SKILL.md +40 -0
  120. package/skills/cpp-best-practices/SKILL.md +230 -0
  121. package/skills/cpp-best-practices/examples/modern-idioms.md +189 -0
  122. package/skills/cpp-best-practices/examples/naming-and-organization.md +102 -0
  123. package/skills/cpp-best-practices/skill.json +25 -0
  124. package/skills/csharp-best-practices/SKILL.md +274 -0
  125. package/skills/csharp-best-practices/skill.json +23 -0
  126. package/skills/git-workflow-skill/skill.json +1 -1
  127. package/skills/open-presentation/SKILL.md +31 -0
  128. package/skills/open-presentation/skill.json +11 -0
  129. package/skills/python-best-practices/SKILL.md +381 -0
  130. package/skills/python-best-practices/skill.json +26 -0
  131. package/skills/story-status-lookup/SKILL.md +74 -0
  132. package/skills/story-status-lookup/skill.json +8 -0
  133. package/test/agent-injection-strategy.test.js +13 -7
  134. package/test/bmad-extension.test.js +237 -0
  135. package/test/bmad-output-policy.test.js +119 -0
  136. package/test/build-bmad-args.test.js +361 -0
  137. package/test/create-agent.test.js +232 -0
  138. package/test/enforcement-hooks.test.js +324 -0
  139. package/test/generate-project-context.test.js +337 -0
  140. package/test/integration-verification.test.js +402 -0
  141. package/test/opencode-agent.test.js +150 -0
  142. package/test/opencode-json-error.test.js +260 -0
  143. package/test/opencode-json-injection.test.js +256 -0
  144. package/test/opencode-json-merge.test.js +299 -0
  145. package/test/skill-authoring.test.js +272 -0
  146. package/test/skill-customize-agent.test.js +253 -0
  147. package/test/skill-mandatory.test.js +235 -0
  148. package/test/skill-validation.test.js +378 -0
  149. package/test/yes-flag.test.js +1 -1
@@ -0,0 +1,250 @@
1
+ # Modify Sprint Workflow
2
+
3
+ Guided workflow to modify an existing sprint — add/remove items, change capacity, update metadata.
4
+
5
+ <workflow>
6
+
7
+ <step n="1" goal="List available sprints and select one to modify">
8
+ <action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
9
+ <check if="no sprint files found">
10
+ <output>❌ No sprint plans found. Run `/add-sprint` first to create a sprint.</output>
11
+ <action>Exit workflow</action>
12
+ </check>
13
+ <action>For each sprint file found, read and extract: sprint_number, sprint_name, capacity, assigned_items, status, last_modified</action>
14
+ <output>
15
+ ## 🏃 Available Sprints
16
+
17
+ | # | Sprint | Status | Capacity | Assigned | Remaining | Last Modified |
18
+ |---|---|---|---|---|---|---|
19
+ {{#each sprints}}
20
+ | {{@index+1}} | {{sprint_name}} (Sprint {{sprint_number}}) | {{status}} | {{capacity}} | {{assigned_count}} | {{remaining}} | {{last_modified}} |
21
+ {{/each}}
22
+ </output>
23
+ <ask>Select sprint to modify (enter number):</ask>
24
+ <action>Store selected sprint as {{target_sprint}}</action>
25
+ <action>Store {{session_last_modified}} = {{target_sprint.last_modified}} for later concurrency guard check</action>
26
+ </step>
27
+
28
+ <step n="2" goal="Display current sprint state">
29
+ <action>Initialize {{working_assigned_items}} = copy of {{target_sprint.assigned_items}} — this working list accumulates all add/remove changes made during this session before the final save</action>
30
+ <action>Calculate remaining capacity: {{remaining}} = {{target_sprint.capacity}} - length({{working_assigned_items}})</action>
31
+ <output>
32
+ ## Sprint: {{target_sprint.sprint_name}} (Sprint {{target_sprint.sprint_number}})
33
+
34
+ - **Status:** {{target_sprint.status}}
35
+ - **Capacity:** {{target_sprint.capacity}} items
36
+ - **Assigned Items:** {{assigned_count}} / {{target_sprint.capacity}} ({{remaining}} remaining)
37
+ - **Start Context:** {{target_sprint.start_context}}
38
+ - **End Context:** {{target_sprint.end_context}}
39
+ - **Last Modified:** {{target_sprint.last_modified}}
40
+
41
+ ### Assigned Items
42
+ {{#if assigned_items_empty}}
43
+ *(No items assigned yet)*
44
+ {{else}}
45
+ {{#each target_sprint.assigned_items}}
46
+ - {{this}}
47
+ {{/each}}
48
+ {{/if}}
49
+ </output>
50
+ </step>
51
+
52
+ <step n="3" goal="Present modification menu">
53
+ <ask>What would you like to modify?
54
+
55
+ 1. **Add item** — assign a new backlog item to this sprint
56
+ 2. **Remove item** — remove an assigned item from this sprint
57
+ 3. **Change capacity** — update the sprint's maximum item capacity
58
+ 4. **Update metadata** — change sprint name, start/end context, or status
59
+ 5. **Done** — save all changes and exit
60
+
61
+ Choice:</ask>
62
+ <check if="choice == 5 or 'done'">
63
+ <goto step="5" />
64
+ </check>
65
+ </step>
66
+
67
+ <step n="3a" goal="Add item" if="choice == 1">
68
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` to get all user story keys and statuses</action>
69
+ <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` for bug stories; parse YAML frontmatter for type, severity, title</action>
70
+ <action>Read ALL `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` files to build {{all_assigned_items}} — flat set of every item identifier assigned to any sprint (including the current sprint's {{working_assigned_items}})</action>
71
+ <action>Filter user stories: exclude items whose key is in {{all_assigned_items}} (already assigned to any sprint)</action>
72
+ <action>Filter bug stories: exclude items whose file basename is in {{all_assigned_items}} (already assigned to any sprint)</action>
73
+ <action>Build {{unassigned_items}} from the filtered stories and bugs, with: id, title, type (Story/Bug), status</action>
74
+ <output>
75
+ ## Unassigned Backlog Items
76
+
77
+ | # | ID / File | Title | Type | Status |
78
+ |---|---|---|---|---|
79
+ {{#each unassigned_items}}
80
+ | {{@index+1}} | {{id}} | {{title}} | {{type}} | {{status}} |
81
+ {{/each}}
82
+ </output>
83
+ <ask>Select item to add (enter number):</ask>
84
+ <action>Store selected item as {{item_to_add}}</action>
85
+ <action>Calculate: {{new_assigned_count}} = current assigned count + 1</action>
86
+ <check if="{{new_assigned_count}} > {{target_sprint.capacity}}">
87
+ <output>⚠️ **Capacity Warning:** Adding "{{item_to_add.title}}" would bring assigned items to {{new_assigned_count}}/{{target_sprint.capacity}} — exceeding capacity by {{overage}}.</output>
88
+ <ask>Options:
89
+ - [a] Add anyway (over-capacity acknowledged)
90
+ - [s] Skip — do not add this item
91
+ - [c] Change capacity first (select option 3 from menu)
92
+
93
+ Choice:</ask>
94
+ <check if="choice == 's'">
95
+ <goto step="3" />
96
+ </check>
97
+ <check if="choice == 'c'">
98
+ <goto step="3c" />
99
+ </check>
100
+ </check>
101
+ <action>Add {{item_to_add}} identifier to {{working_assigned_items}} list</action>
102
+ <action>Calculate remaining: {{remaining}} = {{target_sprint.capacity}} - length({{working_assigned_items}})</action>
103
+ <output>✅ Added "{{item_to_add.title}}" to sprint. Updated capacity: {{length(working_assigned_items)}}/{{target_sprint.capacity}} items ({{remaining}} remaining)</output>
104
+ <goto step="3" />
105
+ </step>
106
+
107
+ <step n="3b" goal="Remove item" if="choice == 2">
108
+ <check if="{{working_assigned_items}} is empty">
109
+ <output>ℹ️ No items are currently assigned to this sprint.</output>
110
+ <goto step="3" />
111
+ </check>
112
+ <action>Resolve each identifier in {{working_assigned_items}} to its display name and type:
113
+ - For story identifiers (matching pattern `^\d+-\d+-.+`): infer title from key by converting kebab segments to title case (e.g., `12-1-add-sprint-workflow` → "Add Sprint Workflow"); type = "Story"; look up status in sprint-status.yaml if available
114
+ - For bug identifiers (matching pattern `^bug-.+`): look up in bug-*.md frontmatter (re-glob if not already loaded this step) for title and severity; type = "Bug"
115
+ - If resolution fails for any identifier, display the raw identifier as title with type "Unknown"
116
+ </action>
117
+ <output>
118
+ ## Currently Assigned Items
119
+
120
+ | # | ID / File | Title | Type |
121
+ |---|---|---|---|
122
+ {{#each working_assigned_items}}
123
+ | {{@index+1}} | {{id}} | {{title}} | {{type}} |
124
+ {{/each}}
125
+ </output>
126
+ <ask>Select item to remove (enter number):</ask>
127
+ <action>Remove selected item from {{working_assigned_items}} list</action>
128
+ <action>Calculate remaining: {{remaining}} = {{target_sprint.capacity}} - length({{working_assigned_items}})</action>
129
+ <output>✅ Removed item from sprint. Updated capacity: {{length(working_assigned_items)}}/{{target_sprint.capacity}} items ({{remaining}} remaining)</output>
130
+ <goto step="3" />
131
+ </step>
132
+
133
+ <step n="3c" goal="Change capacity" if="choice == 3">
134
+ <ask>Enter new capacity (positive integer — current: {{target_sprint.capacity}}):</ask>
135
+ <action>Validate input is a positive integer (greater than zero)</action>
136
+ <check if="input is NOT a positive integer">
137
+ <output>❌ Invalid capacity. Must be a positive integer greater than zero.</output>
138
+ <goto step="3c" />
139
+ </check>
140
+ <action>Store {{new_capacity}} = validated integer input</action>
141
+ <action>Calculate: {{new_remaining}} = {{new_capacity}} - length({{working_assigned_items}})</action>
142
+ <output>✅ Capacity updated: {{target_sprint.capacity}} → {{new_capacity}} ({{new_remaining}} slots remaining with current {{length(working_assigned_items)}} assigned items)</output>
143
+ <action>Update {{target_sprint.capacity}} = {{new_capacity}} in working state</action>
144
+ <goto step="3" />
145
+ </step>
146
+
147
+ <step n="3d" goal="Update metadata" if="choice == 4">
148
+ <ask>Which metadata to update?
149
+ 1. Sprint name (current: "{{target_sprint.sprint_name}}")
150
+ 2. Start context (current: "{{target_sprint.start_context}}")
151
+ 3. End context (current: "{{target_sprint.end_context}}")
152
+ 4. Status (current: {{target_sprint.status}} — options: planning / active / completed)
153
+ 5. Back to menu
154
+
155
+ Choice:</ask>
156
+ <check if="choice == 1">
157
+ <ask>New sprint name:</ask>
158
+ <action>Update {{target_sprint.sprint_name}} in working state</action>
159
+ <output>✅ Sprint name updated.</output>
160
+ </check>
161
+ <check if="choice == 2">
162
+ <ask>New start context (date or milestone):</ask>
163
+ <action>Update {{target_sprint.start_context}} in working state</action>
164
+ <output>✅ Start context updated.</output>
165
+ </check>
166
+ <check if="choice == 3">
167
+ <ask>New end context (date or milestone):</ask>
168
+ <action>Update {{target_sprint.end_context}} in working state</action>
169
+ <output>✅ End context updated.</output>
170
+ </check>
171
+ <check if="choice == 4">
172
+ <ask>New status (planning / active / completed):</ask>
173
+ <action>Validate input is one of: planning, active, completed</action>
174
+ <check if="invalid status">
175
+ <output>❌ Invalid status. Choose: planning, active, or completed.</output>
176
+ </check>
177
+ <action>Update {{target_sprint.status}} in working state</action>
178
+ <output>✅ Sprint status updated.</output>
179
+ </check>
180
+ <check if="choice == 5">
181
+ <goto step="3" />
182
+ </check>
183
+ <goto step="3" />
184
+ </step>
185
+
186
+ <step n="4" goal="Concurrency guard — re-read before writing">
187
+ <action>Re-read the sprint artifact file: `_bmad-output/implementation-artifacts/sprint-plan-{{target_sprint.sprint_number}}.yaml`</action>
188
+ <action>Extract the current `last_modified` timestamp from the file</action>
189
+ <check if="current file last_modified != {{session_last_modified}}">
190
+ <output>
191
+ ⚠️ **Conflict Detected:** The sprint artifact was modified externally since this session started.
192
+
193
+ **Session started with:** `last_modified: {{session_last_modified}}`
194
+ **Current file has:** `last_modified: {{current_file_last_modified}}`
195
+
196
+ **Current sprint state (re-read from file):**
197
+ </output>
198
+ <action>Display the full current state of the sprint artifact (re-read content)</action>
199
+ <ask>The file has changed. Review the current state above and confirm how to proceed:
200
+ - [o] Overwrite with your changes from this session (your modifications will replace current file content)
201
+ - [m] Merge — restart modifications from the current file state
202
+ - [x] Cancel — discard all session changes
203
+
204
+ Choice:</ask>
205
+ <check if="choice == 'x'">
206
+ <output>❌ Changes discarded. Sprint file not modified.</output>
207
+ <action>Exit workflow</action>
208
+ </check>
209
+ <check if="choice == 'm'">
210
+ <action>Reload {{target_sprint}} from current file content</action>
211
+ <action>Update {{session_last_modified}} to current file's last_modified</action>
212
+ <action>Reset {{working_assigned_items}} to current file's assigned_items</action>
213
+ <output>🔄 Reloaded sprint from current state. Please re-apply your modifications.</output>
214
+ <goto step="3" />
215
+ </check>
216
+ <!-- if 'o', proceed to write with session changes -->
217
+ </check>
218
+ </step>
219
+
220
+ <step n="5" goal="Persist changes to sprint artifact">
221
+ <action>Invoke concurrency guard (Step 4) before writing</action>
222
+ <action>Get current ISO timestamp for last_modified</action>
223
+ <action>Write updated sprint data back to `_bmad-output/implementation-artifacts/sprint-plan-{{target_sprint.sprint_number}}.yaml`:
224
+ - Update `sprint_name` if changed
225
+ - Update `capacity` if changed
226
+ - Update `assigned_items` with final working list
227
+ - Update `status` if changed
228
+ - Update `start_context` if changed
229
+ - Update `end_context` if changed
230
+ - Update `last_modified` to current ISO timestamp
231
+ - Preserve `sprint_number`, `created_date` unchanged
232
+ </action>
233
+ <action>**Do NOT modify sprint-status.yaml** — sprint membership is exclusively in sprint-plan-{n}.yaml. sprint-status.yaml is read-only from this workflow.</action>
234
+ <action>Calculate final remaining capacity</action>
235
+ <output>
236
+ ## ✅ Sprint Updated Successfully
237
+
238
+ **Sprint:** {{target_sprint.sprint_name}} (Sprint {{target_sprint.sprint_number}})
239
+ **File:** `_bmad-output/implementation-artifacts/sprint-plan-{{target_sprint.sprint_number}}.yaml`
240
+ **Capacity:** {{final_capacity}} items ({{final_remaining}} remaining)
241
+ **Assigned Items:** {{final_assigned_count}}
242
+ **Status:** {{target_sprint.status}}
243
+
244
+ **Next Steps:**
245
+ - Use `/add-to-sprint` to assign more backlog items
246
+ - Use `/sprint-status-view` to view full sprint progress
247
+ </output>
248
+ </step>
249
+
250
+ </workflow>
@@ -0,0 +1,229 @@
1
+ # Project Context Expansion Workflow
2
+
3
+ Post-retrospective companion workflow to update `_bmad-output/project-context.md` with
4
+ patterns and conventions discovered during the sprint.
5
+
6
+ Run this workflow at the end of `/bmad-retrospective` to close the living document lifecycle loop.
7
+ The agent proposes additions; the human decides what gets written.
8
+
9
+ <workflow>
10
+
11
+ <step n="1" goal="Check whether project-context.md exists">
12
+
13
+ <action>Check if `_bmad-output/project-context.md` exists in the project root</action>
14
+
15
+ <check if="file does NOT exist">
16
+ <output>
17
+ ℹ️ **No project-context.md found.**
18
+
19
+ `_bmad-output/project-context.md` does not exist in this project yet.
20
+
21
+ To create it, either:
22
+ - Run `npx ma-agents install` at the project level (auto-generates on first install)
23
+ - Run `/bmad-generate-project-context` to create it manually
24
+
25
+ Skipping project-context expansion — nothing to update.
26
+ </output>
27
+ <action>Exit workflow</action>
28
+ </check>
29
+
30
+ <check if="file exists">
31
+ <output>
32
+ ✅ Found `_bmad-output/project-context.md` — proceeding with expansion review.
33
+ </output>
34
+ </check>
35
+
36
+ </step>
37
+
38
+ <step n="2" goal="Read and present the current Project-Specific Rules section">
39
+
40
+ <action>Read the complete contents of `_bmad-output/project-context.md`</action>
41
+
42
+ <action>Extract the `## Project-Specific Rules` section:
43
+ - Find the line starting with `## Project-Specific Rules`
44
+ - Read all content until the next `##` section header (or end of file)
45
+ - Store as {{current_rules_content}}
46
+ </action>
47
+
48
+ <check if="{{current_rules_content}} contains only the TODO comment or is effectively empty">
49
+ <action>Set {{rules_are_empty}} = true</action>
50
+ </check>
51
+
52
+ <check if="{{current_rules_content}} contains substantive rules">
53
+ <action>Set {{rules_are_empty}} = false</action>
54
+ </check>
55
+
56
+ <output>
57
+ ## Current Project-Specific Rules
58
+
59
+ {{current_rules_content}}
60
+
61
+ ---
62
+
63
+ I will now review the retrospective discussion to propose additions to this section.
64
+ </output>
65
+
66
+ </step>
67
+
68
+ <step n="3" goal="Gather sprint patterns — from retrospective context or user input">
69
+
70
+ <action>Check whether there is active retrospective context in this session (i.e., this workflow
71
+ was invoked immediately after running /bmad-retrospective and discussion content is available).
72
+ </action>
73
+
74
+ <check if="retrospective context IS present in this session">
75
+ <action>Use the retrospective discussion to identify patterns, conventions, and lessons.
76
+ Skip the user prompt below — proceed directly to the proposal step.
77
+ </action>
78
+ </check>
79
+
80
+ <check if="retrospective context is NOT present (workflow invoked cold or standalone)">
81
+ <output>
82
+ ℹ️ **No retrospective session detected in this context.**
83
+
84
+ This workflow is designed to run after `/bmad-retrospective`, but it can also be used
85
+ standalone to capture any conventions or patterns you've observed.
86
+ </output>
87
+ <ask>
88
+ Briefly describe the patterns or conventions you want to add to Project-Specific Rules.
89
+ For example: "agents kept omitting error handling in async functions" or
90
+ "we decided all PRs need a test-plan section in the description".
91
+
92
+ You can also just say "run retrospective first" to cancel.
93
+ </ask>
94
+ <check if="user says 'run retrospective first' or equivalent cancel">
95
+ <output>
96
+ ℹ️ To get the most value, run `/bmad-retrospective` first, then invoke `/project-context-expansion`
97
+ at the end of that session. No changes made.
98
+ </output>
99
+ <action>Exit workflow</action>
100
+ </check>
101
+ <action>Store the user-described patterns as {{sprint_patterns}} and use them as the source
102
+ material for the proposal in the next action below.
103
+ </action>
104
+ </check>
105
+
106
+ <action>Based on the retrospective discussion OR user-described patterns, identify items that
107
+ should become standing rules for AI agents — specifically:
108
+ - Coding conventions agents got wrong or needed correction on during the sprint
109
+ - Patterns agents should consistently apply in this project
110
+ - Architectural decisions that agents must respect (and that are not obvious from the code)
111
+ - Testing or review conventions specific to this project
112
+ - Gotchas or anti-patterns agents kept producing that should be explicitly prohibited
113
+ - Workflow or communication rules specific to this team's practices
114
+ </action>
115
+
116
+ <action>Filter OUT anything that belongs in other sections:
117
+ - Technology Stack updates → belongs in `## Technology Stack` (use `/bmad-generate-project-context`)
118
+ - Mandatory pre-task rules → belongs in `## AI Agent Mandatory Rules` (set at install time)
119
+ - Do NOT propose changes to any section other than `## Project-Specific Rules`
120
+ </action>
121
+
122
+ <check if="no relevant patterns found from retrospective">
123
+ <output>
124
+ ℹ️ **No new rules to propose.**
125
+
126
+ Based on the retrospective discussion, no patterns were identified that would add value
127
+ as standing rules in `## Project-Specific Rules`. The section is already up to date.
128
+
129
+ If you noticed patterns the agents got wrong, you can manually edit
130
+ `_bmad-output/project-context.md` to add your own rules at any time.
131
+ </output>
132
+ <action>Exit workflow</action>
133
+ </check>
134
+
135
+ <action>Draft proposed additions as clear, imperative rules:
136
+ - Each rule is a single actionable statement (e.g., "Always use X when Y")
137
+ - Rules are specific enough to change agent behavior, not vague principles
138
+ - Each rule is distinct — no overlap with existing rules
139
+ - Store as {{proposed_additions}}
140
+ </action>
141
+
142
+ <output>
143
+ ## Proposed Additions to Project-Specific Rules
144
+
145
+ Based on patterns from this sprint's retrospective, here are the additions I recommend:
146
+
147
+ {{proposed_additions}}
148
+
149
+ ---
150
+
151
+ **Review these carefully.** These additions will be appended to `## Project-Specific Rules`
152
+ in `_bmad-output/project-context.md` and will govern all future AI agent sessions.
153
+ </output>
154
+
155
+ </step>
156
+
157
+ <step n="4" goal="Human review and confirmation gate">
158
+
159
+ <ask>
160
+ Review the proposed additions above.
161
+
162
+ Options:
163
+ - **[y] Accept all** — append all proposed additions as shown
164
+ - **[n] Reject all** — skip without any changes
165
+ - **[e] Edit** — describe which rules to add, remove, or reword before writing
166
+ </ask>
167
+
168
+ <check if="user selects 'n'">
169
+ <output>
170
+ ❌ **Expansion skipped.** No changes were made to `_bmad-output/project-context.md`.
171
+ </output>
172
+ <action>Exit workflow</action>
173
+ </check>
174
+
175
+ <check if="user selects 'e'">
176
+ <ask>Describe your edits — which rules to keep, drop, or reword:</ask>
177
+ <action>Apply user edits to {{proposed_additions}}</action>
178
+ <action>Re-display the revised proposal</action>
179
+ <ask>Proceed with this revised version? [y] Yes / [n] Cancel:</ask>
180
+ <check if="user selects 'n'">
181
+ <output>
182
+ ❌ **Expansion cancelled.** No changes were made to `_bmad-output/project-context.md`.
183
+ </output>
184
+ <action>Exit workflow</action>
185
+ </check>
186
+ </check>
187
+
188
+ </step>
189
+
190
+ <step n="5" goal="Write approved additions to Project-Specific Rules only">
191
+
192
+ <action>Read the current full contents of `_bmad-output/project-context.md` again (to ensure freshness)</action>
193
+
194
+ <action>Locate the `## Project-Specific Rules` section:
195
+ - Find the line starting with `## Project-Specific Rules`
196
+ - Identify the end of the section (next `##` header or end of file)
197
+ - Preserve all existing content in the section — do NOT remove or reorder existing rules
198
+ </action>
199
+
200
+ <action>Append the approved additions at the END of the `## Project-Specific Rules` section,
201
+ before the next `##` header. Insert a blank line separator if the section is not empty.
202
+ </action>
203
+
204
+ <action>CRITICAL CONSTRAINTS — do NOT touch any other section:
205
+ - Do NOT modify `## AI Agent Mandatory Rules`
206
+ - Do NOT modify `## Technology Stack`
207
+ - Do NOT modify any other section
208
+ - Do NOT reformat or reorganize the file
209
+ - Only append to `## Project-Specific Rules`
210
+ </action>
211
+
212
+ <action>Save the updated `_bmad-output/project-context.md`</action>
213
+
214
+ <output>
215
+ ✅ **Project-Specific Rules updated successfully!**
216
+
217
+ - **File:** `_bmad-output/project-context.md`
218
+ - **Rules added:** {{count_of_added_rules}}
219
+
220
+ The new rules will be active in all AI agent sessions that load `project-context.md`
221
+ via `critical_actions` (all BMAD agents load it automatically on activation).
222
+
223
+ **Next:** Commit `_bmad-output/project-context.md` to version control so the rules
224
+ are shared across the team and persist across sessions.
225
+ </output>
226
+
227
+ </step>
228
+
229
+ </workflow>
@@ -0,0 +1,193 @@
1
+ # Sprint Status View Workflow
2
+
3
+ Extension workflow that displays sprint progress with assigned items (stories + bugs), type distinction, and remaining capacity.
4
+
5
+ > **Architecture mandate:** This workflow is a NEW extension at `lib/bmad-extension/workflows/sprint-status-view/`. It does NOT modify any files under `_bmad/bmm/workflows/`.
6
+
7
+ <workflow>
8
+
9
+ <step n="1" goal="Discover all sprint artifact files">
10
+ <action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
11
+ <check if="no sprint files found">
12
+ <output>
13
+ ℹ️ **No Sprints Found**
14
+
15
+ No sprint plan files exist yet (`sprint-plan-*.yaml`).
16
+
17
+ **To get started:**
18
+ - Run `/add-sprint` to create your first sprint
19
+ - Run `/add-to-sprint` to assign backlog items to it
20
+ </output>
21
+ <action>Exit workflow</action>
22
+ </check>
23
+ <action>For each sprint file found, read the full YAML content and store as {{sprint_plans}} list</action>
24
+ <action>Sort {{sprint_plans}} by sprint_number ascending</action>
25
+ </step>
26
+
27
+ <step n="2" goal="Load sprint-status.yaml for user story execution statuses">
28
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml`</action>
29
+ <check if="file not found">
30
+ <output>⚠️ `sprint-status.yaml` not found. User story execution statuses will not be available. Run `/sprint-planning` to initialize.</output>
31
+ <action>Set {{story_status_map}} = {} (empty — will show data integrity warnings per missing item)</action>
32
+ </check>
33
+ <check if="file found">
34
+ <action>Parse development_status section into {{story_status_map}} — key: story key, value: status</action>
35
+ <action>Exclude epic-* keys and *-retrospective keys from the map</action>
36
+ </check>
37
+ </step>
38
+
39
+ <step n="3" goal="Discover bug stories for type/severity data">
40
+ <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files</action>
41
+ <check if="no bug files found">
42
+ <action>Set {{bug_metadata_map}} = {} (empty)</action>
43
+ </check>
44
+ <check if="bug files found">
45
+ <action>For each bug file, parse YAML frontmatter to extract: type, severity, title</action>
46
+ <action>Build {{bug_metadata_map}} — key: file basename (e.g., `bug-login-crash`), value: {severity, title}</action>
47
+ </check>
48
+ </step>
49
+
50
+ <step n="4" goal="Display sprint status for each sprint">
51
+ <action>For each sprint in {{sprint_plans}} (in order):</action>
52
+ <action>Calculate: {{assigned_count}} = length(sprint.assigned_items)</action>
53
+ <action>Calculate: {{remaining_capacity}} = sprint.capacity - {{assigned_count}}</action>
54
+
55
+ <action>For each item identifier in sprint.assigned_items, resolve item details:
56
+
57
+ **If item is a story (key matches regex `^\d+-\d+-.+`):**
58
+ - Look up status in {{story_status_map}}[item_key]
59
+ - If NOT found in {{story_status_map}}:
60
+ → Record as DATA INTEGRITY WARNING: "Item {item_key} has no status entry in sprint-status.yaml — run /sprint-planning to initialize status tracking for this item."
61
+ → Display item with marker: ⚠️ [status unknown]
62
+ - If found: display with current status label
63
+
64
+ **If item is a bug (key matches regex `^bug-.+`):**
65
+ - Look up in {{bug_metadata_map}}[item_key]
66
+ - If NOT found: display with title as item_key, severity as "unknown"
67
+ - If found: display with title and severity from frontmatter
68
+ - Bug execution status: use `status` from bug file frontmatter if present; otherwise "not-started"
69
+
70
+ **If item matches neither pattern:** display as type "Unknown" with raw identifier as title
71
+ </action>
72
+
73
+ <output>
74
+ ---
75
+
76
+ ## 🏃 {{sprint.sprint_name}} (Sprint {{sprint.sprint_number}})
77
+
78
+ **Status:** {{sprint.status}} | **Capacity:** {{sprint.capacity}} items | **Assigned:** {{assigned_count}} | **Remaining:** {{remaining_capacity}}
79
+ {{#if sprint.start_context}}**Start:** {{sprint.start_context}}{{/if}} {{#if sprint.end_context}}| **End:** {{sprint.end_context}}{{/if}}
80
+
81
+ {{#if over_capacity}}
82
+ ⚠️ **Over capacity by {{overage}} item(s)**
83
+ {{/if}}
84
+
85
+ ### Assigned Items
86
+
87
+ | Item | Title | Type | Status / Severity |
88
+ |---|---|---|---|
89
+ {{#each resolved_items}}
90
+ {{#if is_story}}
91
+ | {{item_key}} | {{title}} | 📋 Story | {{status}} |
92
+ {{/if}}
93
+ {{#if is_bug}}
94
+ | {{item_key}} | {{title}} | 🐛 Bug | Severity: {{severity}} / {{bug_status}} |
95
+ {{/if}}
96
+ {{/each}}
97
+
98
+ {{#if data_integrity_warnings}}
99
+ **⚠️ Data Integrity Warnings:**
100
+ {{#each data_integrity_warnings}}
101
+ - {{this}}
102
+ {{/each}}
103
+ {{/if}}
104
+
105
+ {{#if assigned_items_empty}}
106
+ *(No items assigned to this sprint)*
107
+ {{/if}}
108
+ </output>
109
+ </step>
110
+
111
+ <step n="5" goal="Display unassigned backlog summary">
112
+ <action>Collect all item keys from {{story_status_map}} that are NOT in any sprint's assigned_items list — these are unassigned user stories</action>
113
+ <action>Collect all bug basenames from {{bug_metadata_map}} that are NOT in any sprint's assigned_items list — these are unassigned bugs</action>
114
+ <action>Count unassigned stories by status: {{unassigned_by_status}}</action>
115
+ <output>
116
+ ---
117
+
118
+ ## 📦 Unassigned Backlog
119
+
120
+ ### 📋 Unassigned Stories
121
+
122
+ | Status | Count |
123
+ |---|---|
124
+ | backlog | {{count_backlog}} |
125
+ | ready-for-dev | {{count_ready}} |
126
+ | in-progress | {{count_in_progress}} |
127
+ | review | {{count_review}} |
128
+ | done | {{count_done}} |
129
+
130
+ *Total unassigned stories: {{total_unassigned}}*
131
+
132
+ ### 🐛 Unassigned Bugs
133
+
134
+ {{#if unassigned_bugs}}
135
+ | ID / File | Title | Severity |
136
+ |---|---|---|
137
+ {{#each unassigned_bugs}}
138
+ | {{id}} | {{title}} | {{severity}} |
139
+ {{/each}}
140
+ {{else}}
141
+ *(No unassigned bugs)*
142
+ {{/if}}
143
+
144
+ **Tip:** Use `/add-to-sprint` to assign unassigned items to a sprint.
145
+ </output>
146
+ </step>
147
+
148
+ <step n="6" goal="Offer next actions">
149
+ <ask>Options:
150
+ 1. Show full unassigned backlog item list (IDs + titles + statuses)
151
+ 2. Add items to a sprint — run `/add-to-sprint`
152
+ 3. Modify a sprint — run `/modify-sprint`
153
+ 4. Create a new sprint — run `/add-sprint`
154
+ 5. Exit
155
+
156
+ Choice:</ask>
157
+ <check if="choice == 1">
158
+ <action>For each unassigned story key in {{story_status_map}} not assigned to any sprint, display: key, inferred title, status</action>
159
+ <action>For each unassigned bug in {{bug_metadata_map}} not assigned to any sprint, display: id, title, severity</action>
160
+ <output>
161
+ ### Full Unassigned Backlog
162
+
163
+ **Stories:**
164
+ | Key | Title | Status |
165
+ |---|---|---|
166
+ {{#each unassigned_story_items}}
167
+ | {{key}} | {{title}} | {{status}} |
168
+ {{/each}}
169
+
170
+ **Bugs:**
171
+ | ID | Title | Severity |
172
+ |---|---|---|
173
+ {{#each unassigned_bugs}}
174
+ | {{id}} | {{title}} | {{severity}} |
175
+ {{/each}}
176
+ </output>
177
+ <goto step="6" />
178
+ </check>
179
+ <check if="choice == 2">
180
+ <output>▶️ Run `/add-to-sprint` to assign backlog items to a sprint.</output>
181
+ </check>
182
+ <check if="choice == 3">
183
+ <output>▶️ Run `/modify-sprint` to add/remove items or change sprint settings.</output>
184
+ </check>
185
+ <check if="choice == 4">
186
+ <output>▶️ Run `/add-sprint` to create a new sprint.</output>
187
+ </check>
188
+ <check if="choice == 5">
189
+ <action>Exit workflow</action>
190
+ </check>
191
+ </step>
192
+
193
+ </workflow>