diff --git a/src/resources/extensions/gsd/roadmap-slices.ts b/src/resources/extensions/gsd/roadmap-slices.ts index 4c4cb4ceb..c5487ed80 100644 --- a/src/resources/extensions/gsd/roadmap-slices.ts +++ b/src/resources/extensions/gsd/roadmap-slices.ts @@ -41,8 +41,8 @@ export function expandDependencies(deps: string[]): string[] { } function extractSlicesSection(content: string): string { - // Match "## Slices", "## Slice Overview", "## Slice Table", etc. - const headingMatch = /^## Slice(?:s| Overview| Table| Summary| Status)\b.*$/m.exec(content); + // Match "## Slices", "## Slice Overview", "## Slice Table", "## Slice Roadmap", etc. + const headingMatch = /^## Slice(?:s| Overview| Table| Summary| Status| Roadmap)\b.*$/m.exec(content); if (!headingMatch || headingMatch.index == null) return ""; const start = headingMatch.index + headingMatch[0].length; diff --git a/src/resources/extensions/gsd/tests/roadmap-slices.test.ts b/src/resources/extensions/gsd/tests/roadmap-slices.test.ts index f326dd858..182c72732 100644 --- a/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +++ b/src/resources/extensions/gsd/tests/roadmap-slices.test.ts @@ -236,6 +236,32 @@ test("parseRoadmapSlices: ## Slices with valid checkboxes does NOT invoke prose assert.equal(slices[0]?.done, true); }); +// ── Regression test for #1940 ─────────────────────────────────────────────── +// '## Slice Roadmap' header is not recognized by extractSlicesSection, causing +// checkbox-format slices to be missed and all slices reported as incomplete. + +test("parseRoadmapSlices: ## Slice Roadmap heading recognized (#1940)", () => { + const roadmapContent = [ + "# M002: Current Milestone", "", + "**Vision:** Ship it.", "", + "## Slice Roadmap", "", + "- [x] **S01: Foundation** `risk:low` `depends:[]`", + " > After this: base layer works.", + "- [x] **S02: Core Logic** `risk:medium` `depends:[S01]`", + "- [ ] **S03: Polish** `risk:low` `depends:[S01,S02]`", "", + "## Boundary Map", + ].join("\n"); + const slices = parseRoadmapSlices(roadmapContent); + assert.equal(slices.length, 3, "should parse 3 slices under '## Slice Roadmap'"); + assert.equal(slices[0]?.id, "S01"); + assert.equal(slices[0]?.done, true, "S01 should be marked done"); + assert.equal(slices[1]?.id, "S02"); + assert.equal(slices[1]?.done, true, "S02 should be marked done"); + assert.equal(slices[2]?.id, "S03"); + assert.equal(slices[2]?.done, false, "S03 should be pending"); + assert.deepEqual(slices[2]?.depends, ["S01", "S02"]); +}); + test("parseRoadmapSlices: ## Slices with only non-matching lines returns prose fallback results", () => { const weirdContent = `# M020: Odd