ma-agents 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -2
- package/lib/bmad-extension/module-help.csv +8 -4
- package/lib/bmad-extension/skills/add-sprint/SKILL.md +126 -40
- package/lib/bmad-extension/skills/add-to-sprint/SKILL.md +116 -142
- package/lib/bmad-extension/skills/cleanup-done/.gitkeep +0 -0
- package/lib/bmad-extension/skills/cleanup-done/SKILL.md +159 -0
- package/lib/bmad-extension/skills/cleanup-done/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/create-bug-story/SKILL.md +75 -7
- package/lib/bmad-extension/skills/generate-backlog/SKILL.md +183 -0
- package/lib/bmad-extension/skills/generate-backlog/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/modify-sprint/SKILL.md +63 -0
- package/lib/bmad-extension/skills/prioritize-backlog/.gitkeep +0 -0
- package/lib/bmad-extension/skills/prioritize-backlog/SKILL.md +195 -0
- package/lib/bmad-extension/skills/prioritize-backlog/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/remove-from-sprint/.gitkeep +0 -0
- package/lib/bmad-extension/skills/remove-from-sprint/SKILL.md +163 -0
- package/lib/bmad-extension/skills/remove-from-sprint/bmad-skill-manifest.yaml +3 -0
- package/lib/bmad-extension/skills/sprint-status-view/SKILL.md +199 -138
- package/lib/bmad-extension/workflows/add-sprint/workflow.md +129 -39
- package/lib/bmad-extension/workflows/add-to-sprint/workflow.md +3 -205
- package/lib/bmad-extension/workflows/modify-sprint/workflow.md +5 -0
- package/lib/bmad-extension/workflows/sprint-status-view/workflow.md +3 -192
- package/package.json +1 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: generate-backlog
|
|
3
|
+
description: Generate or refresh a flat backlog.yaml from epics and bug stories, preserving existing priority and sprint assignments
|
|
4
|
+
type: skill
|
|
5
|
+
triggers:
|
|
6
|
+
- "generate backlog"
|
|
7
|
+
- "refresh backlog"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Generate Backlog Workflow
|
|
11
|
+
|
|
12
|
+
Generate or refresh a flat `backlog.yaml` from epic stories and bug reports. Preserves existing priority and sprint assignments, appends new items, removes stale items, and re-numbers priorities 1..N.
|
|
13
|
+
|
|
14
|
+
<workflow>
|
|
15
|
+
|
|
16
|
+
<step n="1" goal="Load sources">
|
|
17
|
+
<action>Read `_bmad-output/planning-artifacts/epics.md` — this is the master list of epics with their stories.</action>
|
|
18
|
+
<check if="epics.md does not exist">
|
|
19
|
+
<output>**Error:** `_bmad-output/planning-artifacts/epics.md` not found. Cannot generate backlog without an epics file.</output>
|
|
20
|
+
<action>Exit workflow</action>
|
|
21
|
+
</check>
|
|
22
|
+
|
|
23
|
+
<action>Glob `_bmad-output/implementation-artifacts/bug-*.md` to discover all bug story files.</action>
|
|
24
|
+
<action>Store the list of bug files as {{bug_files}} (may be empty — zero bugs is valid).</action>
|
|
25
|
+
|
|
26
|
+
<action>Read `_bmad-output/implementation-artifacts/sprint-status.yaml` if it exists — this provides the current status of each story (done, in-progress, backlog, etc.).</action>
|
|
27
|
+
<action>Store the status map as {{status_map}} (keyed by story id). If the file does not exist, use an empty map.</action>
|
|
28
|
+
|
|
29
|
+
<action>Read `_bmad-output/implementation-artifacts/backlog.yaml` if it exists — this is the existing backlog to merge with.</action>
|
|
30
|
+
<action>Store the existing backlog items as {{existing_items}} (list). If the file does not exist, use an empty list.</action>
|
|
31
|
+
|
|
32
|
+
<output>
|
|
33
|
+
**Sources loaded:**
|
|
34
|
+
- epics.md: found
|
|
35
|
+
- Bug files: {{bug_files | length}} file(s)
|
|
36
|
+
- sprint-status.yaml: {{status_map exists ? "found" : "not found (empty status)"}}
|
|
37
|
+
- Existing backlog.yaml: {{existing_items | length}} item(s)
|
|
38
|
+
</output>
|
|
39
|
+
</step>
|
|
40
|
+
|
|
41
|
+
<step n="2" goal="Extract stories from epics">
|
|
42
|
+
<action>Parse `epics.md` to extract every story from every epic. Each epic is a level-2 heading (`## Epic N: ...`) and each story within it is a level-3 heading (`### Story N.M: ...`) or a list item following the pattern `- **Story N.M:** Title` or `- N.M: Title`.</action>
|
|
43
|
+
|
|
44
|
+
<action>For each story found:
|
|
45
|
+
- Derive {{story_id}} as a kebab-case slug: `"{epic_number}-{story_number}-{title_slug}"` (e.g., `"5-5-explicit-parameter-passing"`)
|
|
46
|
+
- Title slug: lowercase, replace spaces/underscores with hyphens, remove non-alphanumeric/non-hyphen characters, collapse consecutive hyphens, trim leading/trailing hyphens
|
|
47
|
+
- Set {{epic}} to the epic number (integer)
|
|
48
|
+
- Set {{title}} to the story title text
|
|
49
|
+
- Look up status from {{status_map}} using the story identifier. If found and status is `done`, skip this story (exclude from backlog). If found, use that status. If not found, default to `backlog`.
|
|
50
|
+
- Set {{type}} = `story`
|
|
51
|
+
- Set {{severity}} = `null`
|
|
52
|
+
- Set {{sprint}} = `null`
|
|
53
|
+
- Set {{priority}} = `null` (will be assigned during merge/sort)
|
|
54
|
+
</action>
|
|
55
|
+
|
|
56
|
+
<action>Store the extracted stories as {{extracted_stories}} list.</action>
|
|
57
|
+
<output>Extracted {{extracted_stories | length}} active stories from epics (done items excluded).</output>
|
|
58
|
+
</step>
|
|
59
|
+
|
|
60
|
+
<step n="3" goal="Extract bugs">
|
|
61
|
+
<action>For each file in {{bug_files}}:
|
|
62
|
+
- Read the file and parse the YAML frontmatter (between `---` delimiters)
|
|
63
|
+
- Extract `title`, `severity`, and `status` from frontmatter
|
|
64
|
+
- Derive {{bug_id}} from the **filename**, not the title: strip the `bug-` prefix and `.md` extension, then uppercase to `"BUG-{slug}"` (e.g., `bug-login-crash.md` → `BUG-login-crash`)
|
|
65
|
+
- Use `status` from frontmatter directly (bugs track their own status). If `status` is missing, default to `backlog`. If status is `done`, skip this bug (exclude from backlog).
|
|
66
|
+
- Build a backlog item:
|
|
67
|
+
- id: {{bug_id}}
|
|
68
|
+
- type: `bug`
|
|
69
|
+
- epic: `null`
|
|
70
|
+
- title: {{title}}
|
|
71
|
+
- priority: `null` (assigned during merge/sort)
|
|
72
|
+
- status: {{frontmatter_status or "backlog"}}
|
|
73
|
+
- sprint: `null`
|
|
74
|
+
- severity: {{severity}}
|
|
75
|
+
</action>
|
|
76
|
+
|
|
77
|
+
<action>Store the extracted bugs as {{extracted_bugs}} list.</action>
|
|
78
|
+
<output>Extracted {{extracted_bugs | length}} active bugs (done items excluded).</output>
|
|
79
|
+
</step>
|
|
80
|
+
|
|
81
|
+
<step n="4" goal="Merge with existing backlog">
|
|
82
|
+
<action>Combine {{extracted_stories}} and {{extracted_bugs}} into {{new_items}} list.</action>
|
|
83
|
+
|
|
84
|
+
<action>Build a lookup map from {{existing_items}} keyed by `id`.</action>
|
|
85
|
+
|
|
86
|
+
<action>For each item in {{new_items}}:
|
|
87
|
+
- If an item with the same `id` exists in {{existing_items}}:
|
|
88
|
+
- **Preserve** the existing `priority` value
|
|
89
|
+
- **Preserve** the existing `sprint` assignment
|
|
90
|
+
- **Update** `status` from the freshly extracted value (which may reflect sprint-status.yaml changes)
|
|
91
|
+
- **Update** `title`, `type`, `epic`, `severity` from the freshly extracted values (source of truth)
|
|
92
|
+
- If no matching item exists in {{existing_items}}:
|
|
93
|
+
- This is a new item — keep all freshly extracted values
|
|
94
|
+
- Set `priority` to `null` (will be placed at the end during sort)
|
|
95
|
+
</action>
|
|
96
|
+
|
|
97
|
+
<action>Identify stale items: any item in {{existing_items}} whose `id` does NOT appear in {{new_items}}. These items no longer exist in the source files and should be removed.</action>
|
|
98
|
+
|
|
99
|
+
<action>Store the final merged list as {{merged_items}}.</action>
|
|
100
|
+
<action>Store the count of new items added as {{new_count}}.</action>
|
|
101
|
+
<action>Store the count of stale items removed as {{stale_count}}.</action>
|
|
102
|
+
<action>Store the count of preserved items as {{preserved_count}}.</action>
|
|
103
|
+
|
|
104
|
+
<output>
|
|
105
|
+
**Merge results:**
|
|
106
|
+
- Preserved (existing): {{preserved_count}}
|
|
107
|
+
- New items added: {{new_count}}
|
|
108
|
+
- Stale items removed: {{stale_count}}
|
|
109
|
+
</output>
|
|
110
|
+
</step>
|
|
111
|
+
|
|
112
|
+
<step n="5" goal="Write backlog.yaml">
|
|
113
|
+
<action>Sort {{merged_items}} for final output:
|
|
114
|
+
1. Items WITH an existing numeric `priority` come first, sorted ascending by priority
|
|
115
|
+
2. Items WITHOUT a priority (`null`) come after, sorted by:
|
|
116
|
+
a. `type`: bugs before stories (bugs get priority attention)
|
|
117
|
+
b. `severity` for bugs: critical > high > medium > low
|
|
118
|
+
c. `epic` number ascending for stories (lower epics first)
|
|
119
|
+
d. `id` alphabetically as final tiebreaker
|
|
120
|
+
</action>
|
|
121
|
+
|
|
122
|
+
<action>Re-number priorities sequentially 1..N across all items in the sorted list.</action>
|
|
123
|
+
|
|
124
|
+
<action>Get current ISO timestamp as {{generated_at}}.</action>
|
|
125
|
+
|
|
126
|
+
<action>Write `_bmad-output/implementation-artifacts/backlog.yaml` with this structure:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
# Flat Backlog — auto-generated by generate-backlog
|
|
130
|
+
# Generated: {{generated_at}}
|
|
131
|
+
# Total items: {{merged_items | length}}
|
|
132
|
+
#
|
|
133
|
+
# Schema per item:
|
|
134
|
+
# id, type, epic, title, priority, status, sprint, severity
|
|
135
|
+
|
|
136
|
+
backlog:
|
|
137
|
+
- id: "5-5-explicit-parameter-passing"
|
|
138
|
+
type: story
|
|
139
|
+
epic: 5
|
|
140
|
+
title: "Explicit Parameter Passing"
|
|
141
|
+
priority: 1
|
|
142
|
+
status: backlog
|
|
143
|
+
sprint: null
|
|
144
|
+
severity: null
|
|
145
|
+
# ... remaining items ...
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**YAML output rules:**
|
|
149
|
+
- Always quote `id` and `title` fields (they contain hyphens and special characters)
|
|
150
|
+
- `epic` is an integer for stories, `null` for bugs
|
|
151
|
+
- `sprint` is a string like `"sprint-3"` if assigned, or `null`
|
|
152
|
+
- `severity` is a string (`critical`, `high`, `medium`, `low`) for bugs, `null` for stories
|
|
153
|
+
- `status` is one of: `backlog`, `ready-for-dev`, `in-progress`, `review` (done items excluded)
|
|
154
|
+
- `priority` is always a positive integer (1 = highest priority)
|
|
155
|
+
- Use 2-space indentation for YAML
|
|
156
|
+
</action>
|
|
157
|
+
|
|
158
|
+
<output>Backlog written to `_bmad-output/implementation-artifacts/backlog.yaml` with {{merged_items | length}} items.</output>
|
|
159
|
+
</step>
|
|
160
|
+
|
|
161
|
+
<step n="6" goal="Report summary">
|
|
162
|
+
<output>
|
|
163
|
+
## Backlog Generation Complete
|
|
164
|
+
|
|
165
|
+
| Metric | Count |
|
|
166
|
+
|----------------------|-------|
|
|
167
|
+
| Total items | {{merged_items | length}} |
|
|
168
|
+
| Stories | {{story_count}} |
|
|
169
|
+
| Bugs | {{bug_count}} |
|
|
170
|
+
| New items added | {{new_count}} |
|
|
171
|
+
| Stale items removed | {{stale_count}} |
|
|
172
|
+
| Items preserved | {{preserved_count}} |
|
|
173
|
+
|
|
174
|
+
**Output:** `_bmad-output/implementation-artifacts/backlog.yaml`
|
|
175
|
+
|
|
176
|
+
**Next Steps:**
|
|
177
|
+
- Review priorities — new items are appended at the end; reorder as needed
|
|
178
|
+
- Use `/add-to-sprint` to assign high-priority items to the current sprint
|
|
179
|
+
- Use `/sprint-status-view` to see sprint progress
|
|
180
|
+
</output>
|
|
181
|
+
</step>
|
|
182
|
+
|
|
183
|
+
</workflow>
|
|
@@ -7,12 +7,75 @@ triggers:
|
|
|
7
7
|
- "edit sprint"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
<!-- PARTIALLY REWORKED: Item assignment is handled by /add-to-sprint (Story 17.4).
|
|
11
|
+
Item removal is handled by /remove-from-sprint (Story 17.5).
|
|
12
|
+
Sprint activation (planning -> active) is handled below (Step 3e).
|
|
13
|
+
The legacy workflow below still references old sprint-plan-{n}.yaml paths for
|
|
14
|
+
other operations. A full rework of modify-sprint is planned for a future story. -->
|
|
15
|
+
|
|
16
|
+
> **Note:** Item assignment and removal are now handled by `/add-to-sprint` and `/remove-from-sprint`. Use the **Activate Sprint** option below to transition a sprint from `planning` to `active`.
|
|
17
|
+
|
|
10
18
|
# Modify Sprint Workflow
|
|
11
19
|
|
|
12
20
|
Guided workflow to modify an existing sprint — add/remove items, change capacity, update metadata.
|
|
13
21
|
|
|
14
22
|
<workflow>
|
|
15
23
|
|
|
24
|
+
<step n="3e" goal="Activate a sprint (planning -> active)">
|
|
25
|
+
<action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover all sprint files</action>
|
|
26
|
+
<check if="no sprint files found">
|
|
27
|
+
<output>No sprints found. Run `/add-sprint` first.</output>
|
|
28
|
+
<action>Exit workflow</action>
|
|
29
|
+
</check>
|
|
30
|
+
<action>Read each sprint file; extract: id, name, status, capacity, items count</action>
|
|
31
|
+
<action>Display sprints table</action>
|
|
32
|
+
<output>
|
|
33
|
+
## Available Sprints
|
|
34
|
+
|
|
35
|
+
| # | ID | Name | Status | Items | Capacity |
|
|
36
|
+
|---|---|---|---|---|---|
|
|
37
|
+
{{#each sprints}}
|
|
38
|
+
| {{@index+1}} | {{id}} | {{name}} | {{status}} | {{items_count}} | {{capacity}} |
|
|
39
|
+
{{/each}}
|
|
40
|
+
</output>
|
|
41
|
+
<ask>Which sprint to activate? (enter number, or 'q' to cancel):</ask>
|
|
42
|
+
<check if="user enters 'q'">
|
|
43
|
+
<output>Cancelled.</output>
|
|
44
|
+
<action>Exit workflow</action>
|
|
45
|
+
</check>
|
|
46
|
+
<action>Store selected sprint as {{target_sprint}}</action>
|
|
47
|
+
|
|
48
|
+
<!-- Validate transition -->
|
|
49
|
+
<check if="target_sprint.status != 'planning'">
|
|
50
|
+
<output>Only sprints in `planning` status can be activated. Sprint "{{target_sprint.name}}" is currently `{{target_sprint.status}}`.</output>
|
|
51
|
+
<action>Exit workflow</action>
|
|
52
|
+
</check>
|
|
53
|
+
|
|
54
|
+
<!-- Check single-active constraint -->
|
|
55
|
+
<action>Check if any other sprint has status `active`</action>
|
|
56
|
+
<check if="another sprint is already active">
|
|
57
|
+
<output>Cannot activate "{{target_sprint.name}}" — sprint "{{active_sprint.name}}" ({{active_sprint.id}}) is already active. Close it first before activating another sprint.</output>
|
|
58
|
+
<action>Exit workflow</action>
|
|
59
|
+
</check>
|
|
60
|
+
|
|
61
|
+
<ask>Activate "{{target_sprint.name}}" ({{target_sprint.id}})? This will set status to `active`. [y] Yes / [n] Cancel:</ask>
|
|
62
|
+
<check if="user selects 'n'">
|
|
63
|
+
<output>Cancelled.</output>
|
|
64
|
+
<action>Exit workflow</action>
|
|
65
|
+
</check>
|
|
66
|
+
|
|
67
|
+
<action>Set target_sprint.status = "active"</action>
|
|
68
|
+
<action>Update `last_modified` to current ISO timestamp</action>
|
|
69
|
+
<action>Write updated sprint file to `_bmad-output/implementation-artifacts/sprints/{{target_sprint.id}}.yaml`</action>
|
|
70
|
+
<output>
|
|
71
|
+
Sprint "{{target_sprint.name}}" is now **active**.
|
|
72
|
+
|
|
73
|
+
**Next Steps:**
|
|
74
|
+
- Use `/add-to-sprint` to assign backlog items
|
|
75
|
+
- Use `/sprint-status-view` to see sprint progress
|
|
76
|
+
</output>
|
|
77
|
+
</step>
|
|
78
|
+
|
|
16
79
|
<step n="1" goal="List available sprints and select one to modify">
|
|
17
80
|
<action>Glob `_bmad-output/implementation-artifacts/sprint-plan-*.yaml` to discover all sprint artifact files</action>
|
|
18
81
|
<check if="no sprint files found">
|
|
File without changes
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prioritize-backlog
|
|
3
|
+
description: Reprioritize backlog items using multiple criteria — severity, business value, dependencies, type, age
|
|
4
|
+
type: skill
|
|
5
|
+
triggers:
|
|
6
|
+
- "prioritize backlog"
|
|
7
|
+
- "reorder backlog"
|
|
8
|
+
- "reprioritize"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Prioritize-Backlog Workflow
|
|
12
|
+
|
|
13
|
+
Reprioritize backlog items using multiple criteria — severity, business value, dependencies, type, and age.
|
|
14
|
+
|
|
15
|
+
<workflow>
|
|
16
|
+
|
|
17
|
+
<step n="1" goal="Load backlog and dependency data">
|
|
18
|
+
<action>Read `_bmad-output/implementation-artifacts/backlog.yaml`</action>
|
|
19
|
+
<check if="file missing or empty (no items)">
|
|
20
|
+
<output>No backlog found or backlog is empty. Nothing to prioritize.</output>
|
|
21
|
+
<action>Exit workflow</action>
|
|
22
|
+
</check>
|
|
23
|
+
<action>Store all backlog items as {{backlog_items}}</action>
|
|
24
|
+
<action>Infer implicit dependencies: stories belonging to the same epic are assumed to be sequential (lower story number before higher)</action>
|
|
25
|
+
<action>Read `_bmad-output/implementation-artifacts/epics.md` (or equivalent epics source) for any explicitly declared dependencies</action>
|
|
26
|
+
<action>Build {{dependency_map}} — for each item, list the IDs it depends on (must be completed before it can start)</action>
|
|
27
|
+
</step>
|
|
28
|
+
|
|
29
|
+
<step n="2" goal="Display current backlog ordering">
|
|
30
|
+
<output>
|
|
31
|
+
## Current Backlog
|
|
32
|
+
|
|
33
|
+
| # | Priority | ID | Title | Type | Epic | Status | Sprint | Severity | Dependencies |
|
|
34
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
35
|
+
{{#each backlog_items}}
|
|
36
|
+
| {{@index+1}} | {{priority}} | {{id}} | {{title}} | {{type}} | {{epic}} | {{status}} | {{sprint}} | {{severity}} | {{dependencies}} |
|
|
37
|
+
{{/each}}
|
|
38
|
+
|
|
39
|
+
*Total: {{backlog_items.length}} items*
|
|
40
|
+
</output>
|
|
41
|
+
</step>
|
|
42
|
+
|
|
43
|
+
<step n="3" goal="Choose prioritization mode">
|
|
44
|
+
<ask>Choose prioritization mode:
|
|
45
|
+
1. **Full reprioritization** — enter items in desired order, remaining appended at end
|
|
46
|
+
2. **Quick adjust** — move individual items up/down
|
|
47
|
+
3. **Auto-suggest** — AI analysis with weighted criteria
|
|
48
|
+
4. **Cancel**
|
|
49
|
+
|
|
50
|
+
Choice:</ask>
|
|
51
|
+
<check if="choice == 4">
|
|
52
|
+
<output>Cancelled. No changes made.</output>
|
|
53
|
+
<action>Exit workflow</action>
|
|
54
|
+
</check>
|
|
55
|
+
</step>
|
|
56
|
+
|
|
57
|
+
<step n="3a" goal="Full reprioritization" if="choice == 1">
|
|
58
|
+
<ask>Enter item numbers in your desired priority order (comma-separated). Items not listed will be appended in their current relative order:</ask>
|
|
59
|
+
<action>Resolve entered numbers against the backlog table from step 2</action>
|
|
60
|
+
<action>Build {{new_order}}: user-specified items first (in given order), then remaining items appended in their original relative order</action>
|
|
61
|
+
<goto step="4" />
|
|
62
|
+
</step>
|
|
63
|
+
|
|
64
|
+
<step n="3b" goal="Quick adjust" if="choice == 2">
|
|
65
|
+
<action>Initialize {{new_order}} as a copy of the current {{backlog_items}} list (preserving current ordering)</action>
|
|
66
|
+
<ask>Select item number to move:</ask>
|
|
67
|
+
<action>Store selected item as {{item_to_move}}</action>
|
|
68
|
+
<ask>Move to:
|
|
69
|
+
- Enter a position number (1 = top, N = bottom)
|
|
70
|
+
- Or enter 'u' to move up one position, 'd' to move down one position
|
|
71
|
+
|
|
72
|
+
Target:</ask>
|
|
73
|
+
<action>Move {{item_to_move}} to the specified position in {{new_order}}</action>
|
|
74
|
+
<output>Moved "{{item_to_move.title}}" to position {{new_position}}.</output>
|
|
75
|
+
<ask>Continue? [m] Move another item / [d] Done adjusting:</ask>
|
|
76
|
+
<check if="user selects 'm'">
|
|
77
|
+
<action>Display current ordering</action>
|
|
78
|
+
<goto step="3b" />
|
|
79
|
+
</check>
|
|
80
|
+
<check if="user selects 'd'">
|
|
81
|
+
<goto step="4" />
|
|
82
|
+
</check>
|
|
83
|
+
</step>
|
|
84
|
+
|
|
85
|
+
<step n="3c" goal="Auto-suggest prioritization" if="choice == 3">
|
|
86
|
+
<action>Analyze all backlog items using weighted criteria:
|
|
87
|
+
1. **Blocking dependencies** (highest weight) — items that block other items should come first
|
|
88
|
+
2. **Severity** (bugs only) — critical > high > medium > low
|
|
89
|
+
3. **Business value** — infer from epic priority, item description, and type
|
|
90
|
+
4. **Type priority** — bugs generally before stories of equal value
|
|
91
|
+
5. **Age** — older items (lower story numbers, earlier creation) get slight priority boost
|
|
92
|
+
</action>
|
|
93
|
+
<action>Generate {{suggested_order}} with rationale for each item's position</action>
|
|
94
|
+
<output>
|
|
95
|
+
## Auto-Suggested Priority Order
|
|
96
|
+
|
|
97
|
+
| New # | ID | Title | Type | Rationale |
|
|
98
|
+
|---|---|---|---|---|
|
|
99
|
+
{{#each suggested_order}}
|
|
100
|
+
| {{@index+1}} | {{id}} | {{title}} | {{type}} | {{rationale}} |
|
|
101
|
+
{{/each}}
|
|
102
|
+
</output>
|
|
103
|
+
<ask>Options:
|
|
104
|
+
- [a] Accept this ordering
|
|
105
|
+
- [m] Modify (switch to full reprioritization with this as starting point)
|
|
106
|
+
- [r] Reject (return to mode selection)
|
|
107
|
+
|
|
108
|
+
Choice:</ask>
|
|
109
|
+
<check if="user selects 'a'">
|
|
110
|
+
<action>Set {{new_order}} = {{suggested_order}}</action>
|
|
111
|
+
<goto step="4" />
|
|
112
|
+
</check>
|
|
113
|
+
<check if="user selects 'm'">
|
|
114
|
+
<action>Set current backlog display to {{suggested_order}}</action>
|
|
115
|
+
<goto step="3a" />
|
|
116
|
+
</check>
|
|
117
|
+
<check if="user selects 'r'">
|
|
118
|
+
<goto step="3" />
|
|
119
|
+
</check>
|
|
120
|
+
</step>
|
|
121
|
+
|
|
122
|
+
<step n="4" goal="Dependency validation">
|
|
123
|
+
<action>For each item in {{new_order}}, check if it appears before any item it depends on</action>
|
|
124
|
+
<check if="dependency violations found">
|
|
125
|
+
<output>
|
|
126
|
+
**Dependency Warning:** The following items appear before their dependencies:
|
|
127
|
+
|
|
128
|
+
{{#each violations}}
|
|
129
|
+
- **{{item.id}}** (position {{item.position}}) depends on **{{dependency.id}}** (position {{dependency.position}})
|
|
130
|
+
{{/each}}
|
|
131
|
+
</output>
|
|
132
|
+
<ask>How to proceed?
|
|
133
|
+
- [o] Override — keep current order despite dependency warnings
|
|
134
|
+
- [f] Fix — automatically reorder to satisfy dependencies
|
|
135
|
+
- [c] Cancel — return to mode selection
|
|
136
|
+
|
|
137
|
+
Choice:</ask>
|
|
138
|
+
<check if="user selects 'f'">
|
|
139
|
+
<action>Reorder {{new_order}} to satisfy dependency constraints (move dependency items before their dependents, preserving relative order otherwise)</action>
|
|
140
|
+
<output>Dependencies fixed. Updated ordering applied.</output>
|
|
141
|
+
</check>
|
|
142
|
+
<check if="user selects 'c'">
|
|
143
|
+
<goto step="3" />
|
|
144
|
+
</check>
|
|
145
|
+
<!-- if 'o', proceed with current order -->
|
|
146
|
+
</check>
|
|
147
|
+
</step>
|
|
148
|
+
|
|
149
|
+
<step n="5" goal="Confirm and persist new ordering">
|
|
150
|
+
<output>
|
|
151
|
+
## Old vs New Priority Order
|
|
152
|
+
|
|
153
|
+
| Position | Old | New |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
{{#each comparison}}
|
|
156
|
+
| {{position}} | {{old_id}} — {{old_title}} | {{new_id}} — {{new_title}} |
|
|
157
|
+
{{/each}}
|
|
158
|
+
</output>
|
|
159
|
+
<ask>Provide a brief reason for this reprioritization:</ask>
|
|
160
|
+
<action>Store as {{reason}}</action>
|
|
161
|
+
<ask>Confirm? [y] Apply / [n] Cancel / [e] Edit order:</ask>
|
|
162
|
+
<check if="user selects 'n'">
|
|
163
|
+
<output>Cancelled. No changes made.</output>
|
|
164
|
+
<action>Exit workflow</action>
|
|
165
|
+
</check>
|
|
166
|
+
<check if="user selects 'e'">
|
|
167
|
+
<goto step="3" />
|
|
168
|
+
</check>
|
|
169
|
+
<check if="user input is not 'y', 'n', or 'e'">
|
|
170
|
+
<output>Unrecognized option: "{{user_input}}". Please enter [y], [n], or [e].</output>
|
|
171
|
+
<goto step="5" />
|
|
172
|
+
</check>
|
|
173
|
+
|
|
174
|
+
<action>Update `_bmad-output/implementation-artifacts/backlog.yaml`:
|
|
175
|
+
- Rewrite items in {{new_order}} sequence
|
|
176
|
+
- Set priority fields sequentially: 1, 2, 3, ..., N
|
|
177
|
+
- Add or update header comment: `# Reprioritized: {{current_date}} — {{reason}}`
|
|
178
|
+
- Preserve all other item fields unchanged
|
|
179
|
+
</action>
|
|
180
|
+
<output>
|
|
181
|
+
## Reprioritization Complete
|
|
182
|
+
|
|
183
|
+
**Items reordered:** {{new_order.length}}
|
|
184
|
+
**Reason:** {{reason}}
|
|
185
|
+
**Date:** {{current_date}}
|
|
186
|
+
|
|
187
|
+
Updated priorities written to `_bmad-output/implementation-artifacts/backlog.yaml`.
|
|
188
|
+
|
|
189
|
+
**Next Steps:**
|
|
190
|
+
- Use `/sprint-status-view` to review sprint assignments
|
|
191
|
+
- Use `/add-to-sprint` to assign top-priority items to a sprint
|
|
192
|
+
</output>
|
|
193
|
+
</step>
|
|
194
|
+
|
|
195
|
+
</workflow>
|
|
File without changes
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remove-from-sprint
|
|
3
|
+
description: Remove items from a sprint and return them to the unassigned backlog
|
|
4
|
+
type: skill
|
|
5
|
+
triggers:
|
|
6
|
+
- "remove from sprint"
|
|
7
|
+
- "unassign from sprint"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Remove-from-Sprint Workflow
|
|
11
|
+
|
|
12
|
+
Remove items from a sprint and return them to the unassigned backlog.
|
|
13
|
+
|
|
14
|
+
<workflow>
|
|
15
|
+
|
|
16
|
+
<step n="1" goal="List sprints that have items and select one">
|
|
17
|
+
<action>Glob `_bmad-output/implementation-artifacts/sprints/sprint-*.yaml` to discover all sprint files</action>
|
|
18
|
+
<check if="no sprint files found">
|
|
19
|
+
<output>No sprints found. Run `/add-sprint` first to create a sprint.</output>
|
|
20
|
+
<action>Exit workflow</action>
|
|
21
|
+
</check>
|
|
22
|
+
<action>For each sprint file, read and extract: id, name, status, capacity, items (array), last_modified</action>
|
|
23
|
+
<action>Filter to sprints that have at least 1 item in their items array</action>
|
|
24
|
+
<check if="no sprints have items">
|
|
25
|
+
<output>No sprints contain any items. Nothing to remove.</output>
|
|
26
|
+
<action>Exit workflow</action>
|
|
27
|
+
</check>
|
|
28
|
+
<output>
|
|
29
|
+
## Sprints with Items
|
|
30
|
+
|
|
31
|
+
| # | Sprint | Status | Items | Capacity | Last Modified |
|
|
32
|
+
|---|---|---|---|---|---|
|
|
33
|
+
{{#each filtered_sprints}}
|
|
34
|
+
| {{@index+1}} | {{name}} ({{id}}) | {{status}} | {{items_count}} | {{capacity}} | {{last_modified}} |
|
|
35
|
+
{{/each}}
|
|
36
|
+
</output>
|
|
37
|
+
<ask>Select sprint (enter number):</ask>
|
|
38
|
+
<action>Store selected sprint as {{target_sprint}}</action>
|
|
39
|
+
<action>Store {{session_last_modified}} = {{target_sprint.last_modified}} for concurrency guard</action>
|
|
40
|
+
</step>
|
|
41
|
+
|
|
42
|
+
<step n="2" goal="Display sprint items with backlog metadata">
|
|
43
|
+
<action>Read `_bmad-output/implementation-artifacts/backlog.yaml`</action>
|
|
44
|
+
<action>For each item ID in {{target_sprint.items}}, look up metadata from backlog.yaml to get: title, type, status, priority</action>
|
|
45
|
+
<action>If an item is not found in backlog.yaml, infer title from ID (kebab-case to title case) and mark type/status/priority as "unknown"</action>
|
|
46
|
+
<output>
|
|
47
|
+
## Items in {{target_sprint.name}}
|
|
48
|
+
|
|
49
|
+
| # | ID | Title | Type | Status | Priority |
|
|
50
|
+
|---|---|---|---|---|---|
|
|
51
|
+
{{#each sprint_items}}
|
|
52
|
+
| {{@index+1}} | {{id}} | {{title}} | {{type}} | {{status}} | {{priority}} |
|
|
53
|
+
{{/each}}
|
|
54
|
+
</output>
|
|
55
|
+
</step>
|
|
56
|
+
|
|
57
|
+
<step n="3" goal="Prompt for items to remove">
|
|
58
|
+
<ask>Which items to remove? Enter item numbers (comma-separated), 'all' to remove all, or 'q' to cancel:</ask>
|
|
59
|
+
<check if="user enters 'q'">
|
|
60
|
+
<output>Cancelled. No changes made.</output>
|
|
61
|
+
<action>Exit workflow</action>
|
|
62
|
+
</check>
|
|
63
|
+
<check if="user enters 'all'">
|
|
64
|
+
<action>Set {{items_to_remove}} = all items in {{target_sprint.items}}</action>
|
|
65
|
+
</check>
|
|
66
|
+
<check if="user enters item numbers">
|
|
67
|
+
<action>Resolve entered numbers against the table from step 2</action>
|
|
68
|
+
<action>Set {{items_to_remove}} = selected items</action>
|
|
69
|
+
</check>
|
|
70
|
+
</step>
|
|
71
|
+
|
|
72
|
+
<step n="4" goal="Confirm removal">
|
|
73
|
+
<output>
|
|
74
|
+
## Confirm Removal
|
|
75
|
+
|
|
76
|
+
The following items will be removed from **{{target_sprint.name}}** and returned to the unassigned backlog:
|
|
77
|
+
|
|
78
|
+
{{#each items_to_remove}}
|
|
79
|
+
- {{id}} — {{title}}
|
|
80
|
+
{{/each}}
|
|
81
|
+
|
|
82
|
+
**Note:** Item status will NOT be changed. Items retain their current status.
|
|
83
|
+
</output>
|
|
84
|
+
<ask>Proceed? [y] Yes / [n] Cancel / [e] Edit selection:</ask>
|
|
85
|
+
<check if="user selects 'n'">
|
|
86
|
+
<output>Cancelled. No changes made.</output>
|
|
87
|
+
<action>Exit workflow</action>
|
|
88
|
+
</check>
|
|
89
|
+
<check if="user selects 'e'">
|
|
90
|
+
<goto step="3" />
|
|
91
|
+
</check>
|
|
92
|
+
<check if="user input is not 'y', 'n', or 'e'">
|
|
93
|
+
<output>Unrecognized option: "{{user_input}}". Please enter [y], [n], or [e].</output>
|
|
94
|
+
<goto step="4" />
|
|
95
|
+
</check>
|
|
96
|
+
</step>
|
|
97
|
+
|
|
98
|
+
<step n="5" goal="Concurrency guard — re-read sprint before writing">
|
|
99
|
+
<action>Re-read the sprint file: `_bmad-output/implementation-artifacts/sprints/{{target_sprint.id}}.yaml`</action>
|
|
100
|
+
<action>Extract the current `last_modified` timestamp from the file</action>
|
|
101
|
+
<check if="current file last_modified != {{session_last_modified}}">
|
|
102
|
+
<output>
|
|
103
|
+
**Conflict Detected:** The sprint file was modified since this session started.
|
|
104
|
+
|
|
105
|
+
**Session started with:** `last_modified: {{session_last_modified}}`
|
|
106
|
+
**Current file has:** `last_modified: {{current_file_last_modified}}`
|
|
107
|
+
</output>
|
|
108
|
+
<ask>How to proceed?
|
|
109
|
+
- [o] Overwrite with your changes (your modifications replace current file)
|
|
110
|
+
- [r] Reload — restart from current file state
|
|
111
|
+
- [x] Cancel — discard all changes
|
|
112
|
+
|
|
113
|
+
Choice:</ask>
|
|
114
|
+
<check if="choice == 'x'">
|
|
115
|
+
<output>Cancelled. Sprint file not modified.</output>
|
|
116
|
+
<action>Exit workflow</action>
|
|
117
|
+
</check>
|
|
118
|
+
<check if="choice == 'r'">
|
|
119
|
+
<action>Reload {{target_sprint}} from current file content</action>
|
|
120
|
+
<action>Update {{session_last_modified}} to current file's last_modified</action>
|
|
121
|
+
<output>Reloaded sprint from current state. Restarting item selection.</output>
|
|
122
|
+
<goto step="2" />
|
|
123
|
+
</check>
|
|
124
|
+
<!-- if 'o', proceed to write with session changes -->
|
|
125
|
+
</check>
|
|
126
|
+
</step>
|
|
127
|
+
|
|
128
|
+
<step n="6" goal="Remove items from sprint and update backlog">
|
|
129
|
+
<action>For each item in {{items_to_remove}}:
|
|
130
|
+
1. Remove the item ID from the sprint's `items` array
|
|
131
|
+
2. In `backlog.yaml`, find the matching backlog entry and set its `sprint` field to null (or remove it)
|
|
132
|
+
3. Do NOT change the item's `status` field — status is preserved as-is
|
|
133
|
+
</action>
|
|
134
|
+
<action>**Dual-write — both files must be updated for consistency:**</action>
|
|
135
|
+
<action>Update `last_modified` in the sprint file to current ISO timestamp</action>
|
|
136
|
+
<action>Write the updated sprint file: `_bmad-output/implementation-artifacts/sprints/{{target_sprint.id}}.yaml`</action>
|
|
137
|
+
<check if="sprint file write fails">
|
|
138
|
+
<output>**Error:** Failed to write sprint file. No changes persisted. Backlog NOT modified.</output>
|
|
139
|
+
<action>Exit workflow</action>
|
|
140
|
+
</check>
|
|
141
|
+
<action>Write the updated `_bmad-output/implementation-artifacts/backlog.yaml`</action>
|
|
142
|
+
<check if="backlog.yaml write fails">
|
|
143
|
+
<output>**Warning: Inconsistent state!** Sprint file was updated but backlog.yaml write failed. Items have been removed from the sprint's `items` array but their `sprint` field in backlog.yaml still references {{target_sprint.id}}. Re-run `/remove-from-sprint` or manually fix backlog.yaml.</output>
|
|
144
|
+
</check>
|
|
145
|
+
<output>
|
|
146
|
+
## Removal Complete
|
|
147
|
+
|
|
148
|
+
**Sprint:** {{target_sprint.name}} ({{target_sprint.id}})
|
|
149
|
+
|
|
150
|
+
**Removed items:**
|
|
151
|
+
{{#each items_to_remove}}
|
|
152
|
+
- {{id}} — {{title}} (status unchanged: {{status}})
|
|
153
|
+
{{/each}}
|
|
154
|
+
|
|
155
|
+
**Updated sprint capacity:** {{new_items_count}}/{{target_sprint.capacity}} items ({{new_remaining}} remaining)
|
|
156
|
+
|
|
157
|
+
**Next Steps:**
|
|
158
|
+
- Use `/add-to-sprint` to reassign items to a different sprint
|
|
159
|
+
- Use `/sprint-status-view` to view sprint progress
|
|
160
|
+
</output>
|
|
161
|
+
</step>
|
|
162
|
+
|
|
163
|
+
</workflow>
|