import fs from 'fs/promises'; export interface ChecklistItem { text: string; checked: boolean; } /** * Parses a markdown file and extracts all checkboxes. * Matches lines like: * - [ ] Task * - [x] Completed task * * [ ] Alternative bullet */ export function parseMarkdownChecklist(content: string): ChecklistItem[] { const lines = content.split('\n'); const items: ChecklistItem[] = []; // Regex to match markdown checkboxes: - [ ] or - [x] or * [ ] or * [x] const checkboxRegex = /^[*-]\s+\[([ xX])\]\s+(.+)$/; for (const line of lines) { const trimmed = line.trim(); const match = trimmed.match(checkboxRegex); if (match) { items.push({ checked: match[1].toLowerCase() === 'x', text: match[2].trim() }); } } return items; } /** * Updates a markdown file's checkboxes based on a new checklist. * Preserves other content. */ export function updateMarkdownChecklist(content: string, newChecklist: ChecklistItem[]): string { const lines = content.split('\n'); const updatedLines = [...lines]; const checkboxRegex = /^[*-]\s+\[([ xX])\]\s+(.+)$/; let checklistIdx = 0; for (let i = 0; i < updatedLines.length; i++) { const line = updatedLines[i]; const match = line.match(checkboxRegex); if (match && checklistIdx < newChecklist.length) { const newItem = newChecklist[checklistIdx]; const prefix = line.substring(0, line.indexOf('[')); const suffix = line.substring(line.indexOf(']') + 1); // Note: This logic assumes the text matches. If it doesn't, we might need a better matching strategy. // For now, let's assume order is preserved. updatedLines[i] = `${prefix}[${newItem.checked ? 'x' : ' '}]${suffix}`; checklistIdx++; } } return updatedLines.join('\n'); }