Skip to content

Commit 3d6d83e

Browse files
committed
fix(sdd): ignore fenced Markdown examples
Task counters and clarification parsers previously only checked for unindented triple-backtick fences. Markdown examples inside tilde fences or indented code blocks were incorrectly counted as active tasks or clarification questions. Advance fence state across CommonMark fences. Signed-off-by: 1fanwang <1fannnw@gmail.com>
1 parent 6c00302 commit 3d6d83e

2 files changed

Lines changed: 34 additions & 13 deletions

File tree

plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/sdd.mjs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,35 @@ function constitutionStatus(text) {
252252
return placeholders > 0 ? "template" : "ratified";
253253
}
254254

255+
function advanceMarkdownFence(line, openFence) {
256+
const match = line.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
257+
if (!match) return { openFence, isFenceLine: false };
258+
259+
const marker = match[1][0];
260+
const length = match[1].length;
261+
const rest = match[2];
262+
if (!openFence) {
263+
if (marker === "`" && rest.includes("`")) {
264+
return { openFence: null, isFenceLine: false };
265+
}
266+
return { openFence: { marker, length }, isFenceLine: true };
267+
}
268+
if (marker === openFence.marker && length >= openFence.length && !rest.trim()) {
269+
return { openFence: null, isFenceLine: true };
270+
}
271+
return { openFence, isFenceLine: false };
272+
}
273+
255274
// Count task checkboxes in tasks.md to derive implementation progress.
256-
function taskProgress(text) {
275+
export function taskProgress(text) {
257276
if (typeof text !== "string") return { total: 0, completed: 0 };
258277
let total = 0;
259278
let completed = 0;
260-
let inFence = false;
279+
let openFence = null;
261280
for (const line of text.split(/\r?\n/)) {
262-
if (line.startsWith("```")) {
263-
inFence = !inFence;
264-
continue;
265-
}
266-
if (inFence) continue;
281+
const fenceState = advanceMarkdownFence(line, openFence);
282+
openFence = fenceState.openFence;
283+
if (fenceState.isFenceLine || openFence) continue;
267284
const m = line.match(/^\s*[-*+]\s+\[([ xX])\]/);
268285
if (!m) continue;
269286
total++;
@@ -519,13 +536,11 @@ export function readArtifact(projectRoot, featureInput, stageKey) {
519536
export function extractClarifications(text) {
520537
const clarifications = [];
521538
let section = "";
522-
let inCodeFence = false;
539+
let openFence = null;
523540
for (const line of String(text || "").split(/\r?\n/)) {
524-
if (line.startsWith("```")) {
525-
inCodeFence = !inCodeFence;
526-
continue;
527-
}
528-
if (inCodeFence) continue;
541+
const fenceState = advanceMarkdownFence(line, openFence);
542+
openFence = fenceState.openFence;
543+
if (fenceState.isFenceLine || openFence) continue;
529544
const heading = line.match(/^#{1,6}\s+(.+?)\s*$/);
530545
if (heading) {
531546
section = heading[1].trim();

plugins/spec-kit-copilot-sdd/extensions/sdd-canvas/tests/sdd.test.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ test("implementation progress scans the complete bounded tasks artifact", (t) =>
2323
write(join(featureDir, "plan.md"), "# Plan\n", 2);
2424
const tasks = [
2525
"# Tasks",
26+
"~~~markdown",
27+
"- [x] T000 Example only",
28+
"~~~",
2629
"- [x] T001 Complete near the start",
2730
"padding".repeat(10_000),
2831
"- [ ] T002 Incomplete after the 64 KiB scan prefix",
@@ -51,6 +54,9 @@ test("clarifications retain stable indices across supported markdown blocks", ()
5154
"```text",
5255
"[NEEDS CLARIFICATION: Ignore code?]",
5356
"```",
57+
" ~~~markdown",
58+
"[NEEDS CLARIFICATION: Ignore indented tilde fence?]",
59+
" ~~~",
5460
].join("\n");
5561

5662
assert.deepEqual(extractClarifications(markdown), [

0 commit comments

Comments
 (0)