/** * Mine the first unchecked task-checklist item from plan markdown. */ /** * Return the text of the first `- [ ]` item under `## Task checklist`. * If that section is missing, fall back to the first unchecked checkbox anywhere. * Returns null when none found. */ export function nextUncheckedStep(planMarkdown: string): string | null { const md = planMarkdown.replace(/\r\n/g, "\n"); const sectionMatch = /^##\s+Task checklist\s*$/im.exec(md); if (sectionMatch && sectionMatch.index !== undefined) { const start = sectionMatch.index + sectionMatch[0].length; const rest = md.slice(start); const nextHeading = /^##\s+/im.exec(rest); const body = nextHeading ? rest.slice(0, nextHeading.index) : rest; const fromSection = firstUnchecked(body); if (fromSection) return fromSection; } return firstUnchecked(md); } function firstUnchecked(text: string): string | null { const re = /^\s*[-*]\s+\[\s\]\s+(.+?)\s*$/gm; const m = re.exec(text); if (!m) return null; const item = m[1]!.trim(); if (!item || item === "(none)") return null; return item; }