@ikunin/sprintpilot 2.1.4 → 2.1.5
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.
|
@@ -109,10 +109,11 @@ function safeExistsSync(p) {
|
|
|
109
109
|
// back to "story/unknown" because state.story_key is null on a fresh
|
|
110
110
|
// sprint (CREATE_STORY hasn't run yet; for nano there's no CREATE_STORY
|
|
111
111
|
// at all and quick-dev reads sprint-status itself). Returns the first
|
|
112
|
-
//
|
|
112
|
+
// non-done STORY key (filtering out epic rollup headers), or null when:
|
|
113
113
|
// - the status file doesn't exist (pre-planning)
|
|
114
114
|
// - all stories are done (sprint complete)
|
|
115
115
|
// - the file can't be parsed
|
|
116
|
+
// - the only non-done entries are epic rollups (no real stories yet)
|
|
116
117
|
function resolveNextStoryKey(projectRoot) {
|
|
117
118
|
if (!projectRoot) return null;
|
|
118
119
|
const sprintStatusPath = path.join(
|
|
@@ -126,12 +127,48 @@ function resolveNextStoryKey(projectRoot) {
|
|
|
126
127
|
const raw = fs.readFileSync(sprintStatusPath, 'utf8');
|
|
127
128
|
const stories = parseSprintStatuses(raw);
|
|
128
129
|
const remaining = remainingStoriesFrom(stories);
|
|
129
|
-
|
|
130
|
+
// parseStatuses returns every key under `development_status:` —
|
|
131
|
+
// including BMad's epic rollup headers (`epic-4: in-progress`).
|
|
132
|
+
// Filter them out so we don't ask the orchestrator to branch on an
|
|
133
|
+
// epic identifier (the v2.1.4 hotfix shipped without this filter and
|
|
134
|
+
// a user reported branch: story/epic-4 instead of story/4-8-...).
|
|
135
|
+
const realStories = remaining.filter(looksLikeStoryKey);
|
|
136
|
+
return realStories.length > 0 ? realStories[0] : null;
|
|
130
137
|
} catch (_e) {
|
|
131
138
|
return null;
|
|
132
139
|
}
|
|
133
140
|
}
|
|
134
141
|
|
|
142
|
+
// Tell story keys apart from non-story bookkeeping entries in
|
|
143
|
+
// sprint-status.yaml. BMad development_status: holds three kinds of
|
|
144
|
+
// entries that parseStatuses returns side-by-side:
|
|
145
|
+
//
|
|
146
|
+
// 1. Real stories — `4-8-realm-wide-matcher` / `epic-1-game-engine`.
|
|
147
|
+
// Always have at least one hyphen AFTER the epic identifier.
|
|
148
|
+
// 2. Epic rollup headers — `epic-4` / bare `4`. The status reflects
|
|
149
|
+
// child-story rollup, not a unit of work for the autopilot.
|
|
150
|
+
// 3. Retrospective entries — `4-retrospective` / `epic-4-retrospective`.
|
|
151
|
+
// Status tracks whether the per-epic retro ritual has run; not a
|
|
152
|
+
// story to dev.
|
|
153
|
+
//
|
|
154
|
+
// Reject (2) and (3). The v2.1.4 hotfix shipped without this filter and
|
|
155
|
+
// the user reported `branch: story/epic-4` instead of the real next
|
|
156
|
+
// pending story. The v2.1.5 hotfix extends the filter to retrospectives
|
|
157
|
+
// after a follow-up report.
|
|
158
|
+
function looksLikeStoryKey(key) {
|
|
159
|
+
if (typeof key !== 'string' || !key) return false;
|
|
160
|
+
// Retrospective entries (`-retrospective` suffix, with or without epic
|
|
161
|
+
// prefix). Match anywhere the suffix appears so `epic-4-retrospective`
|
|
162
|
+
// and `4-retrospective` are both rejected.
|
|
163
|
+
if (/-retrospective$/i.test(key)) return false;
|
|
164
|
+
// Strip any leading `epic-` prefix and require a remaining hyphen.
|
|
165
|
+
// `epic-4` → `4` → no hyphen → epic header (reject).
|
|
166
|
+
// `epic-1-game-engine` → `1-game-engine` → has hyphen → story (accept).
|
|
167
|
+
// `4-8-realm-wide-matcher` → unchanged → has hyphen → story (accept).
|
|
168
|
+
const withoutEpicPrefix = key.replace(/^epic-/i, '');
|
|
169
|
+
return withoutEpicPrefix.includes('-');
|
|
170
|
+
}
|
|
171
|
+
|
|
135
172
|
// Derive the epic identifier from a BMad story key. Convention:
|
|
136
173
|
// `epic-N-slug` → `epic-N`; `<epic>-<story>-<slug>` → `<epic>`.
|
|
137
174
|
// Returns null when the key doesn't parse cleanly. Kept in sync with
|
package/package.json
CHANGED