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: sprint-status-view
3
- description: Display sprint progress with assigned items, type distinction, and remaining capacity
3
+ description: Display sprint progress with capacity, items, and backlog. Regenerates sprint-status.yaml.
4
4
  type: skill
5
5
  triggers:
6
6
  - "sprint status view"
@@ -9,194 +9,255 @@ triggers:
9
9
 
10
10
  # Sprint Status View Workflow
11
11
 
12
- Extension workflow that displays sprint progress with assigned items (stories + bugs), type distinction, and remaining capacity.
13
-
14
- > **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/`.
12
+ Display sprint status with capacity, items, and backlog summary. Regenerates `sprint-status.yaml` from authoritative sources.
15
13
 
16
14
  <workflow>
17
15
 
18
- <step n="1" goal="Discover all sprint artifact files">
19
- <action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
20
- <check if="no sprint files found">
16
+ <step n="1" goal="Suggest running /cleanup-done first">
17
+ <output>
18
+ **Tip:** Consider running `/cleanup-done` before viewing sprint status to archive completed items and free capacity.
19
+ </output>
20
+ <action>Continue to next step (advisory only -- do not auto-invoke /cleanup-done)</action>
21
+ </step>
22
+
23
+ <step n="2" goal="Load data sources">
24
+ <action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover all sprint entity files</action>
25
+ <action>Store discovered sprint files as {{sprint_files}} list</action>
26
+
27
+ <action>Read `_bmad-output/implementation-artifacts/backlog.yaml` if it exists</action>
28
+ <action>Store the backlog items list as {{backlog_items}} (or empty list if file not found)</action>
29
+
30
+ <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files (fallback for bug metadata)</action>
31
+ <action>For each bug file found, parse YAML frontmatter to extract: title, severity, status</action>
32
+ <action>Store as {{bug_metadata_map}} keyed by file basename (e.g., `bug-login-crash`)</action>
33
+
34
+ <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` if it exists (fallback for story status when backlog.yaml is missing or incomplete)</action>
35
+ <action>Parse development_status section into {{status_fallback_map}} -- key: story key, value: status</action>
36
+ <action>Exclude epic-* keys and *-retrospective keys from the fallback map</action>
37
+
38
+ <check if="no sprint files found AND no backlog.yaml exists">
21
39
  <output>
22
- ℹ️ **No Sprints Found**
40
+ **No Sprint Data Found**
23
41
 
24
- No sprint plan files exist yet (`sprint-plan-*.yaml`).
42
+ No sprint files exist (`sprints/sprint-*.yaml`) and no `backlog.yaml` was found.
25
43
 
26
44
  **To get started:**
27
- - Run `/add-sprint` to create your first sprint
28
- - Run `/add-to-sprint` to assign backlog items to it
45
+ 1. Run `/generate-backlog` to create a backlog from your epics
46
+ 2. Run `/add-sprint` to create your first sprint
47
+ 3. Run `/add-to-sprint` to assign backlog items to it
29
48
  </output>
30
49
  <action>Exit workflow</action>
31
50
  </check>
32
- <action>For each sprint file found, read the full YAML content and store as {{sprint_plans}} list</action>
33
- <action>Sort {{sprint_plans}} by sprint_number ascending</action>
34
51
  </step>
35
52
 
36
- <step n="2" goal="Load sprint-status.yaml for user story execution statuses">
37
- <action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml`</action>
38
- <check if="file not found">
39
- <output>⚠️ `sprint-status.yaml` not found. User story execution statuses will not be available. Run `/sprint-planning` to initialize.</output>
40
- <action>Set {{story_status_map}} = {} (empty — will show data integrity warnings per missing item)</action>
41
- </check>
42
- <check if="file found">
43
- <action>Parse development_status section into {{story_status_map}} — key: story key, value: status</action>
44
- <action>Exclude epic-* keys and *-retrospective keys from the map</action>
45
- </check>
46
- </step>
47
-
48
- <step n="3" goal="Discover bug stories for type/severity data">
49
- <action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files</action>
50
- <check if="no bug files found">
51
- <action>Set {{bug_metadata_map}} = {} (empty)</action>
52
- </check>
53
- <check if="bug files found">
54
- <action>For each bug file, parse YAML frontmatter to extract: type, severity, title</action>
55
- <action>Build {{bug_metadata_map}} key: file basename (e.g., `bug-login-crash`), value: {severity, title}</action>
56
- </check>
57
- </step>
58
-
59
- <step n="4" goal="Display sprint status for each sprint">
60
- <action>For each sprint in {{sprint_plans}} (in order):</action>
61
- <action>Calculate: {{assigned_count}} = length(sprint.assigned_items)</action>
62
- <action>Calculate: {{remaining_capacity}} = sprint.capacity - {{assigned_count}}</action>
63
-
64
- <action>For each item identifier in sprint.assigned_items, resolve item details:
65
-
66
- **If item is a story (key matches regex `^\d+-\d+-.+`):**
67
- - Look up status in {{story_status_map}}[item_key]
68
- - If NOT found in {{story_status_map}}:
69
- → 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."
70
- → Display item with marker: ⚠️ [status unknown]
71
- - If found: display with current status label
72
-
73
- **If item is a bug (key matches regex `^bug-.+`):**
74
- - Look up in {{bug_metadata_map}}[item_key]
75
- - If NOT found: display with title as item_key, severity as "unknown"
76
- - If found: display with title and severity from frontmatter
77
- - Bug execution status: use `status` from bug file frontmatter if present; otherwise "not-started"
78
-
79
- **If item matches neither pattern:** display as type "Unknown" with raw identifier as title
53
+ <step n="3" goal="Display each sprint">
54
+ <action>For each sprint in {{sprint_files}}, read the full YAML content</action>
55
+ <action>Sort sprints for display: active first, then planning, then closed</action>
56
+ <action>Initialize {{total_done_in_sprints}} = 0 for step 4</action>
57
+
58
+ <action>For each sprint (in sorted order):
59
+
60
+ **If sprint.status is "closed":**
61
+ - Count total items in sprint.items
62
+ - Display collapsed summary line only
63
+
64
+ **If sprint.status is NOT "closed" (active or planning):**
65
+ - Calculate {{item_count}} = length(sprint.items)
66
+ - For each item identifier in sprint.items, resolve details:
67
+ - Look up item in {{backlog_items}} by matching `id` field
68
+ - If found in backlog: use `type`, `title`, `status`, `severity` from backlog entry
69
+ - If NOT found in backlog and item matches `^bug-`: look up in {{bug_metadata_map}} for title/severity, use status from bug frontmatter or default to "backlog"
70
+ - If NOT found in backlog and item matches a story pattern: look up in {{status_fallback_map}} for status, infer title from key, set type to "story"
71
+ - If item cannot be resolved from any source: display with raw identifier, type "unknown", status "unknown"
72
+ - If resolved item status is "done", increment {{total_done_in_sprints}}
73
+ - Build capacity bar: `[===---]` style where `=` represents filled slots and `-` represents remaining capacity
80
74
  </action>
81
75
 
76
+ <action>Display non-closed sprints:</action>
82
77
  <output>
78
+ {{#each non_closed_sprints}}
83
79
  ---
84
80
 
85
- ## 🏃 {{sprint.sprint_name}} (Sprint {{sprint.sprint_number}})
81
+ ## {{sprint.name}} ({{sprint.status}}) -- {{item_count}}/{{sprint.capacity}} items
86
82
 
87
- **Status:** {{sprint.status}} | **Capacity:** {{sprint.capacity}} items | **Assigned:** {{assigned_count}} | **Remaining:** {{remaining_capacity}}
88
- {{#if sprint.start_context}}**Start:** {{sprint.start_context}}{{/if}} {{#if sprint.end_context}}| **End:** {{sprint.end_context}}{{/if}}
83
+ {{#if sprint.start}}**Start:** {{sprint.start}}{{/if}}{{#if sprint.end}} | **End:** {{sprint.end}}{{/if}}
89
84
 
90
- {{#if over_capacity}}
91
- ⚠️ **Over capacity by {{overage}} item(s)**
92
- {{/if}}
93
-
94
- ### Assigned Items
95
-
96
- | Item | Title | Type | Status / Severity |
97
- |---|---|---|---|
85
+ | Item | Type | Status |
86
+ |---|---|---|
98
87
  {{#each resolved_items}}
99
- {{#if is_story}}
100
- | {{item_key}} | {{title}} | 📋 Story | {{status}} |
101
- {{/if}}
102
- {{#if is_bug}}
103
- | {{item_key}} | {{title}} | 🐛 Bug | Severity: {{severity}} / {{bug_status}} |
104
- {{/if}}
88
+ | {{id}} | {{#if is_story}}[story]{{/if}}{{#if is_bug}}[bug, {{severity}}]{{/if}} | {{status}} |
105
89
  {{/each}}
90
+ {{#if items_empty}}
91
+ *(No items assigned)*
92
+ {{/if}}
106
93
 
107
- {{#if data_integrity_warnings}}
108
- **⚠️ Data Integrity Warnings:**
109
- {{#each data_integrity_warnings}}
110
- - {{this}}
94
+ **Capacity:** {{capacity_bar}}
111
95
  {{/each}}
112
- {{/if}}
96
+ </output>
113
97
 
114
- {{#if assigned_items_empty}}
115
- *(No items assigned to this sprint)*
116
- {{/if}}
98
+ <action>Display closed sprints:</action>
99
+ <output>
100
+ {{#each closed_sprints}}
101
+ ---
102
+ **{{sprint.name}}** (closed) -- {{item_count}} items completed
103
+ {{/each}}
117
104
  </output>
118
105
  </step>
119
106
 
120
- <step n="5" goal="Display unassigned backlog summary">
121
- <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>
122
- <action>Collect all bug basenames from {{bug_metadata_map}} that are NOT in any sprint's assigned_items list — these are unassigned bugs</action>
123
- <action>Count unassigned stories by status: {{unassigned_by_status}}</action>
124
- <output>
107
+ <step n="4" goal="Completed items summary">
108
+ <action>Count items with status "done" that are still present in non-closed sprint files (use {{total_done_in_sprints}} from step 3)</action>
109
+ <check if="total_done_in_sprints > 0">
110
+ <output>
125
111
  ---
126
112
 
127
- ## 📦 Unassigned Backlog
113
+ ## Completed Items
128
114
 
129
- ### 📋 Unassigned Stories
115
+ {{total_done_in_sprints}} done item(s) are still in sprint files. Run `/cleanup-done` to archive them and free capacity.
116
+ </output>
117
+ </check>
118
+ <check if="total_done_in_sprints == 0">
119
+ <action>Skip this section -- no done items lingering in sprints</action>
120
+ </check>
121
+ </step>
130
122
 
131
- | Status | Count |
132
- |---|---|
133
- | backlog | {{count_backlog}} |
134
- | ready-for-dev | {{count_ready}} |
135
- | in-progress | {{count_in_progress}} |
136
- | review | {{count_review}} |
137
- | done | {{count_done}} |
123
+ <step n="5" goal="Unassigned backlog">
124
+ <action>Filter {{backlog_items}} to find items where sprint is null (unassigned)</action>
125
+ <action>Exclude items with status "done" from the unassigned list</action>
126
+ <action>Sort unassigned items by priority ascending (lowest number = highest priority)</action>
127
+ <action>Store as {{unassigned_items}}</action>
128
+ <action>Store total count as {{unassigned_total}}</action>
129
+ <action>Take top 15 items for display as {{unassigned_display}}</action>
138
130
 
139
- *Total unassigned stories: {{total_unassigned}}*
131
+ <check if="unassigned_total > 0">
132
+ <output>
133
+ ---
140
134
 
141
- ### 🐛 Unassigned Bugs
135
+ ## Unassigned Backlog
142
136
 
143
- {{#if unassigned_bugs}}
144
- | ID / File | Title | Severity |
145
- |---|---|---|
146
- {{#each unassigned_bugs}}
147
- | {{id}} | {{title}} | {{severity}} |
137
+ | # | Item | Type | Priority | Status |
138
+ |---|---|---|---|---|
139
+ {{#each unassigned_display}}
140
+ | {{priority}} | {{id}} | {{type}} | {{priority}} | {{status}} |
148
141
  {{/each}}
149
- {{else}}
150
- *(No unassigned bugs)*
151
- {{/if}}
152
-
153
- **Tip:** Use `/add-to-sprint` to assign unassigned items to a sprint.
154
- </output>
155
- </step>
156
-
157
- <step n="6" goal="Offer next actions">
158
- <ask>Options:
159
- 1. Show full unassigned backlog item list (IDs + titles + statuses)
160
- 2. Add items to a sprint — run `/add-to-sprint`
161
- 3. Modify a sprint — run `/modify-sprint`
162
- 4. Create a new sprint — run `/add-sprint`
163
- 5. Exit
142
+ {{#if unassigned_total > 15}}
164
143
 
165
- Choice:</ask>
166
- <check if="choice == 1">
167
- <action>For each unassigned story key in {{story_status_map}} not assigned to any sprint, display: key, inferred title, status</action>
168
- <action>For each unassigned bug in {{bug_metadata_map}} not assigned to any sprint, display: id, title, severity</action>
144
+ ... and {{unassigned_total - 15}} more
145
+ {{/if}}
146
+ </output>
147
+ </check>
148
+ <check if="unassigned_total == 0">
169
149
  <output>
170
- ### Full Unassigned Backlog
150
+ ---
171
151
 
172
- **Stories:**
173
- | Key | Title | Status |
174
- |---|---|---|
175
- {{#each unassigned_story_items}}
176
- | {{key}} | {{title}} | {{status}} |
177
- {{/each}}
152
+ ## Unassigned Backlog
178
153
 
179
- **Bugs:**
180
- | ID | Title | Severity |
181
- |---|---|---|
182
- {{#each unassigned_bugs}}
183
- | {{id}} | {{title}} | {{severity}} |
184
- {{/each}}
154
+ *(All backlog items are assigned to sprints)*
185
155
  </output>
156
+ </check>
157
+ </step>
158
+
159
+ <step n="6" goal="Next actions menu">
160
+ <ask>
161
+ **Next Actions:**
162
+ [1] Full backlog
163
+ [2] /add-to-sprint
164
+ [3] /remove-from-sprint
165
+ [4] /prioritize-backlog
166
+ [5] /add-sprint
167
+ [6] /cleanup-done
168
+ [7] Exit
169
+
170
+ Choice:
171
+ </ask>
172
+ <check if="choice == 1">
173
+ <action>Display all items from {{backlog_items}} in a table: id, type, priority, status, sprint, severity</action>
186
174
  <goto step="6" />
187
175
  </check>
188
176
  <check if="choice == 2">
189
- <output>▶️ Run `/add-to-sprint` to assign backlog items to a sprint.</output>
177
+ <output>Run `/add-to-sprint` to assign backlog items to a sprint.</output>
190
178
  </check>
191
179
  <check if="choice == 3">
192
- <output>▶️ Run `/modify-sprint` to add/remove items or change sprint settings.</output>
180
+ <output>Run `/remove-from-sprint` to remove items from a sprint.</output>
193
181
  </check>
194
182
  <check if="choice == 4">
195
- <output>▶️ Run `/add-sprint` to create a new sprint.</output>
183
+ <output>Run `/prioritize-backlog` to reorder backlog priorities.</output>
196
184
  </check>
197
185
  <check if="choice == 5">
186
+ <output>Run `/add-sprint` to create a new sprint.</output>
187
+ </check>
188
+ <check if="choice == 6">
189
+ <output>Run `/cleanup-done` to archive completed items from sprints.</output>
190
+ </check>
191
+ <check if="choice == 7">
198
192
  <action>Exit workflow</action>
199
193
  </check>
200
194
  </step>
201
195
 
196
+ <step n="7" goal="Regenerate sprint-status.yaml (internal)" internal="true">
197
+ <action>This step runs automatically after display (steps 3-6) completes, before the workflow exits.</action>
198
+
199
+ <action>Read existing `_bmad-output/implementation-artifacts/sprint-status.yaml` if it exists</action>
200
+ <action>Preserve the STATUS DEFINITIONS comment block at the top of the file (lines starting with `#` that define status values)</action>
201
+ <action>Preserve any epic-* keys and *-retrospective keys from the existing file</action>
202
+
203
+ <action>Build the new development_status section:
204
+ - Source 1: {{backlog_items}} from backlog.yaml -- for each item where status is NOT "done", add an entry: key = item.id, value = item.status
205
+ - Source 2: sprint entity files -- for each sprint, for each item in sprint.items, ensure the item has an entry. If the item was already added from backlog.yaml, the backlog value wins. If the item is NOT in backlog.yaml, look up status from {{bug_metadata_map}} or {{status_fallback_map}}.
206
+ - Exclude items with status "done" -- only non-done items appear in sprint-status.yaml
207
+ </action>
208
+
209
+ <action>Collect sprint metadata for header comments:
210
+ - For each sprint: id, name, status, item count, capacity
211
+ </action>
212
+
213
+ <action>Get current ISO timestamp as {{generated_at}}</action>
214
+
215
+ <action>Write `_bmad-output/implementation-artifacts/sprint-status.yaml` with this structure:
216
+
217
+ ```yaml
218
+ # generated: {{original_generated_date or generated_at}}
219
+ # updated: {{generated_at}} — regenerated by sprint-status-view
220
+ # project: {{project_name from existing file or "unknown"}}
221
+ # project_key: {{project_key from existing file or "NOKEY"}}
222
+ # tracking_system: file-system
223
+ # story_location: _bmad-output/implementation-artifacts
224
+ #
225
+ # Sprints:
226
+ {{#each sprints}}
227
+ # {{sprint.id}}: {{sprint.name}} ({{sprint.status}}) — {{item_count}}/{{sprint.capacity}} items
228
+ {{/each}}
229
+ #
230
+ # STATUS DEFINITIONS:
231
+ # ==================
232
+ # (preserve the full STATUS DEFINITIONS block from the existing file verbatim)
233
+ # If no existing file, use these defaults:
234
+ # backlog — item is in the backlog, not yet started
235
+ # ready-for-dev — story file created, ready for development
236
+ # in-progress — item is actively being worked on
237
+ # review — item is in review
238
+ # done — item is complete (excluded from this file)
239
+
240
+ {{#if preserved_epic_keys}}
241
+ # Epic tracking
242
+ {{#each preserved_epic_keys}}
243
+ {{key}}: {{value}}
244
+ {{/each}}
245
+ {{/if}}
246
+
247
+ development_status:
248
+ {{#each active_items}}
249
+ {{id}}: {{status}}
250
+ {{/each}}
251
+
252
+ {{#if preserved_retro_keys}}
253
+ # Retrospective tracking
254
+ {{#each preserved_retro_keys}}
255
+ {{key}}: {{value}}
256
+ {{/each}}
257
+ {{/if}}
258
+ ```
259
+
260
+ </action>
261
+ </step>
262
+
202
263
  </workflow>
@@ -1,16 +1,38 @@
1
+ <!-- IMPORTANT: This file must be kept in sync with lib/bmad-extension/skills/add-sprint/SKILL.md
2
+ SKILL.md is the authoritative source (resolved via skill:add-sprint in module-help.csv).
3
+ This workflow.md is a legacy copy. Any changes should be made to SKILL.md first, then synced here. -->
4
+
1
5
  # Add Sprint Workflow
2
6
 
3
- Guided workflow to create a new sprint with capacity limits for realistic sprint planning.
7
+ Guided workflow to create a new sprint entity with capacity limits, optional ISO dates, and structured YAML schema.
4
8
 
5
9
  <workflow>
6
10
 
7
- <step n="1" goal="Gather sprint number and name">
8
- <action>Ask the user for the sprint number (e.g., 1, 2, 3)</action>
9
- <ask>What is the sprint number? (e.g., 1)</ask>
10
- <action>Store as {{sprint_number}}</action>
11
- <ask>What is the sprint name? (e.g., "Sprint 1 Foundation") press Enter to use "Sprint {{sprint_number}}"</ask>
12
- <action>If user presses Enter or leaves blank, default to "Sprint {{sprint_number}}"</action>
13
- <action>Store as {{sprint_name}}</action>
11
+ <step n="1" goal="Gather and validate sprint number and name">
12
+ <action>Ask the user for the sprint number</action>
13
+ <ask>What is the sprint number? (positive integer, e.g., 1, 2, 3)</ask>
14
+ <action>Store input as {{sprint_number_input}}</action>
15
+ <action>Validate {{sprint_number_input}} matches `^[1-9]\d*$` (positive integer, no leading zeros, no non-numeric characters)</action>
16
+ <action>Validate {{sprint_number_input}} is <= 9999</action>
17
+ <check if="{{sprint_number_input}} fails validation (zero, negative, non-numeric, leading zeros like '03', or > 9999)">
18
+ <output>❌ Invalid sprint number: "{{sprint_number_input}}". Must be a positive integer (1-9999), no leading zeros.</output>
19
+ <goto step="1" />
20
+ </check>
21
+ <action>Store as {{sprint_number}} (integer)</action>
22
+ <action>Construct {{sprint_id}} = "sprint-{{sprint_number}}"</action>
23
+
24
+ <!-- Smart default name: detect naming patterns from existing sprints -->
25
+ <action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover existing sprint files</action>
26
+ <action>If existing sprints found, read the `name` field from the most recent one (highest sprint number)</action>
27
+ <action>Infer a smart default name:
28
+ - If previous name follows a sequential pattern with a numeric suffix (e.g., "app04"), suggest the next increment (e.g., "app05")
29
+ - If previous name follows a date pattern (e.g., "2026-W14"), suggest the next date interval
30
+ - If previous name is "Sprint {n}", suggest "Sprint {{sprint_number}}"
31
+ - If no pattern detected or no existing sprints, default to "Sprint {{sprint_number}}"
32
+ </action>
33
+ <ask>Sprint name? (press Enter for "{{default_name}}", or type a custom name):</ask>
34
+ <action>If user presses Enter or leaves blank, set {{sprint_name}} = "{{default_name}}"</action>
35
+ <action>If user provides input, store as {{sprint_name}}</action>
14
36
  </step>
15
37
 
16
38
  <step n="2" goal="Gather capacity as positive integer">
@@ -25,32 +47,71 @@ Guided workflow to create a new sprint with capacity limits for realistic sprint
25
47
  <action>Store as {{capacity}} (integer)</action>
26
48
  </step>
27
49
 
28
- <step n="3" goal="Gather optional start and end context">
29
- <action>Explain: start/end context can be dates (e.g., "2026-03-18") or milestone descriptions (e.g., "Q1 Planning Complete")</action>
30
- <ask>Optional — Sprint start context (date or milestone, press Enter to skip):</ask>
31
- <action>Store as {{start_context}} (empty string if skipped)</action>
32
- <ask>Optional Sprint end context (date or milestone, press Enter to skip):</ask>
33
- <action>Store as {{end_context}} (empty string if skipped)</action>
50
+ <step n="3a" goal="Gather optional start date (ISO format)">
51
+ <action>Explain: start and end dates are optional ISO dates (YYYY-MM-DD format). Press Enter to skip.</action>
52
+ <ask>Optional — Sprint start date (YYYY-MM-DD, press Enter to skip):</ask>
53
+ <action>Store input as {{start_input}}</action>
54
+ <check if="{{start_input}} is not empty">
55
+ <action>Validate {{start_input}} matches regex `^\d{4}-\d{2}-\d{2}$`</action>
56
+ <action>Verify {{start_input}} resolves to a real calendar date (reject impossible dates like 2026-02-30, 2026-13-45, etc.)</action>
57
+ <check if="{{start_input}} fails date validation">
58
+ <output>❌ Invalid date: "{{start_input}}". Must be a valid date in YYYY-MM-DD format (e.g., 2026-04-01).</output>
59
+ <goto step="3a" />
60
+ </check>
61
+ </check>
62
+ <action>Store as {{start_date}} (valid ISO date string, or empty string "" if skipped)</action>
63
+ </step>
64
+
65
+ <step n="3b" goal="Gather optional end date (ISO format)">
66
+ <ask>Optional — Sprint end date (YYYY-MM-DD, press Enter to skip):</ask>
67
+ <action>Store input as {{end_input}}</action>
68
+ <check if="{{end_input}} is not empty">
69
+ <action>Validate {{end_input}} matches regex `^\d{4}-\d{2}-\d{2}$`</action>
70
+ <action>Verify {{end_input}} resolves to a real calendar date</action>
71
+ <check if="{{end_input}} fails date validation">
72
+ <output>❌ Invalid date: "{{end_input}}". Must be a valid date in YYYY-MM-DD format (e.g., 2026-04-14).</output>
73
+ <goto step="3b" />
74
+ </check>
75
+ </check>
76
+ <action>Store as {{end_date}} (valid ISO date string, or empty string "" if skipped)</action>
77
+
78
+ <check if="both {{start_date}} and {{end_date}} are non-empty AND {{start_date}} > {{end_date}}">
79
+ <output>❌ Invalid date range: start date ({{start_date}}) is after end date ({{end_date}}). Start must be on or before end.</output>
80
+ <goto step="3a" />
81
+ </check>
34
82
  </step>
35
83
 
36
84
  <step n="4" goal="Confirm and validate all inputs">
37
85
  <output>
38
86
  ## Sprint Summary — Please Confirm
39
87
 
40
- - **Sprint Number:** {{sprint_number}}
41
- - **Sprint Name:** {{sprint_name}}
88
+ - **Sprint ID:** {{sprint_id}}
89
+ - **Sprint Name:** "{{sprint_name}}"
90
+ - **Status:** planning
42
91
  - **Capacity (max items):** {{capacity}}
43
- - **Start Context:** {{start_context}} *(empty if skipped)*
44
- - **End Context:** {{end_context}} *(empty if skipped)*
45
- - **Output File:** `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`
92
+ - **Start Date:** {{start_date}} *(empty if skipped)*
93
+ - **End Date:** {{end_date}} *(empty if skipped)*
94
+ - **Items:** [] *(empty — items assigned via /add-to-sprint)*
95
+ - **Output File:** `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`
46
96
  </output>
47
97
  <ask>Confirm creation? [y] Yes / [n] Cancel / [e] Edit a field:</ask>
48
98
  <check if="user selects 'e'">
49
99
  <ask>Which field to edit? (number / name / capacity / start / end)</ask>
50
100
  <check if="field == 'number'">
51
- <ask>New sprint number:</ask>
52
- <action>Store as {{sprint_number}}</action>
53
- <action>If sprint name was auto-defaulted to the old "Sprint {n}", update it to "Sprint {{sprint_number}}"</action>
101
+ <ask>New sprint number? (positive integer, 1-9999)</ask>
102
+ <action>Store input as {{sprint_number_input}}</action>
103
+ <action>Validate {{sprint_number_input}} matches `^[1-9]\d*$` and is <= 9999</action>
104
+ <check if="{{sprint_number_input}} fails validation">
105
+ <output>❌ Invalid sprint number: "{{sprint_number_input}}". Must be a positive integer (1-9999), no leading zeros.</output>
106
+ <goto step="4" />
107
+ </check>
108
+ <action>Store as {{sprint_number}} (integer)</action>
109
+ <action>Construct {{sprint_id}} = "sprint-{{sprint_number}}"</action>
110
+ <action>If sprint name was using previous default "Sprint {old_n}", update to "Sprint {{sprint_number}}"</action>
111
+ <action>Check if file exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
112
+ <check if="file already exists at new path">
113
+ <output>⚠️ A sprint entity already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`. You will be prompted to overwrite at creation.</output>
114
+ </check>
54
115
  <goto step="4" />
55
116
  </check>
56
117
  <check if="field == 'name'">
@@ -59,45 +120,74 @@ Guided workflow to create a new sprint with capacity limits for realistic sprint
59
120
  <goto step="4" />
60
121
  </check>
61
122
  <check if="field == 'capacity'"><goto step="2" /></check>
62
- <check if="field == 'start'"><goto step="3" /></check>
63
- <check if="field == 'end'"><goto step="3" /></check>
123
+ <check if="field == 'start'"><goto step="3a" /></check>
124
+ <check if="field == 'end'"><goto step="3b" /></check>
125
+ <check if="field is not recognized">
126
+ <output>❌ Unrecognized field: "{{field}}". Valid options: number, name, capacity, start, end.</output>
127
+ <goto step="4" />
128
+ </check>
64
129
  </check>
65
130
  <check if="user selects 'n'">
66
131
  <output>❌ Sprint creation cancelled.</output>
67
132
  <action>Exit workflow</action>
68
133
  </check>
134
+ <check if="user input is not 'y', 'n', or 'e'">
135
+ <output>❌ Unrecognized option: "{{user_input}}". Please enter [y] Yes, [n] Cancel, or [e] Edit a field.</output>
136
+ <goto step="4" />
137
+ </check>
69
138
  </step>
70
139
 
71
- <step n="5" goal="Generate sprint artifact file">
72
- <action>Determine output path: `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`</action>
73
- <action>Check if file already exists at output path</action>
74
- <check if="file already exists">
75
- <output>⚠️ A sprint plan already exists at `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`.</output>
76
- <ask>Overwrite existing sprint plan? [y] Yes / [n] Cancel:</ask>
140
+ <step n="5" goal="Generate sprint entity YAML file">
141
+ <action>Determine output path: `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
142
+ <action>Ensure directory `_bmad-output/implementation-artifacts/sprints/` exists (create if needed)</action>
143
+
144
+ <!-- Overwrite protection for new path -->
145
+ <action>Check if file already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`</action>
146
+ <check if="file already exists at new path">
147
+ <anchor id="overwrite_prompt" />
148
+ <output>⚠️ A sprint entity already exists at `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`.</output>
149
+ <ask>Overwrite existing sprint? [y] Yes / [n] Cancel:</ask>
77
150
  <check if="user selects 'n'">
78
- <output>❌ Sprint creation cancelled to preserve existing sprint plan.</output>
151
+ <output>❌ Sprint creation cancelled to preserve existing sprint.</output>
79
152
  <action>Exit workflow</action>
80
153
  </check>
154
+ <check if="user input is not 'y' or 'n'">
155
+ <output>❌ Unrecognized option: "{{user_input}}". Please enter [y] Yes or [n] Cancel.</output>
156
+ <goto anchor="overwrite_prompt" />
157
+ </check>
81
158
  </check>
159
+
160
+ <!-- Advisory check for old-format file -->
161
+ <action>Check if file exists at old path: `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`</action>
162
+ <check if="old-format file exists">
163
+ <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>
164
+ </check>
165
+
82
166
  <action>Get current ISO timestamp for created_date and last_modified</action>
83
- <action>Write sprint artifact YAML to `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml` with this structure:
167
+ <action>Write sprint entity YAML to `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml` with this structure:
84
168
 
85
169
  ```yaml
86
- sprint_number: {{sprint_number}}
87
- sprint_name: "{{sprint_name}}"
88
- capacity: {{capacity}}
89
- assigned_items: []
170
+ id: {{sprint_id}}
171
+ name: "{{sprint_name}}"
90
172
  status: planning
91
- start_context: "{{start_context}}"
92
- end_context: "{{end_context}}"
173
+ capacity: {{capacity}}
174
+ start: "{{start_date}}"
175
+ end: "{{end_date}}"
176
+ items: []
93
177
  created_date: "{{current_iso_timestamp}}"
94
178
  last_modified: "{{current_iso_timestamp}}"
95
179
  ```
180
+
181
+ **YAML output rules:**
182
+ - Always quote the `name` field to handle special characters
183
+ - `start` and `end` are empty string `""` if skipped
184
+ - `items` is always empty array `[]` at creation
185
+ - `status` is always `planning` at creation (never `active` or `closed`)
96
186
  </action>
97
187
  <output>
98
188
  ✅ **Sprint created successfully!**
99
189
 
100
- - **File:** `_bmad-output/implementation-artifacts/sprint-plan-{{sprint_number}}.yaml`
190
+ - **File:** `_bmad-output/implementation-artifacts/sprints/{{sprint_id}}.yaml`
101
191
  - **Sprint:** {{sprint_name}}
102
192
  - **Capacity:** {{capacity}} items
103
193
  - **Status:** planning