export function addFileMarker(content, recipe) { const marker = `\n`; const lines = content.split('\n'); if (lines[0]?.trim() === '---') { const endIndex = lines.findIndex((line, i) => i > 0 && line.trim() === '---'); if (endIndex !== -1) { return [ ...lines.slice(0, endIndex + 1), marker.trimEnd(), ...lines.slice(endIndex + 1) ].join('\n'); } } return marker + content; } export function hasFileMarker(content, recipe) { const expected = ``; return content.includes(expected); } export function stripFrontmatter(content) { const lines = content.split('\n'); if (lines[0]?.trim() === '---') { const endIndex = lines.findIndex((line, i) => i > 0 && line.trim() === '---'); if (endIndex !== -1) { return lines.slice(endIndex + 1).join('\n').trimStart(); } } return content; } export function wrapSection(content, recipe) { const startMarker = ``; const endMarker = ``; return `${startMarker}\n${content}\n${endMarker}`; } export function hasSection(content, recipe) { const startMarker = ``; return content.includes(startMarker); } export function replaceSection(content, recipe, newSection) { const startMarker = ``; const endMarker = ``; const startIndex = content.indexOf(startMarker); const endIndex = content.indexOf(endMarker); if (startIndex === -1 || endIndex === -1) { return content; } return content.slice(0, startIndex) + newSection + content.slice(endIndex + endMarker.length); } export function removeSection(content, recipe) { const startMarker = ``; const endMarker = ``; const startIndex = content.indexOf(startMarker); const endIndex = content.indexOf(endMarker); if (startIndex === -1 || endIndex === -1) { return content; } let before = content.slice(0, startIndex); let after = content.slice(endIndex + endMarker.length); // Clean up extra newlines before = before.trimEnd(); after = after.trimStart(); if (before && after) { return before + '\n\n' + after; } return before + after; } /** * Parse YAML frontmatter from markdown content. * Returns { frontmatter: Object|null, body: string }. * Only handles simple key: value pairs (no nested objects, no arrays). */ export function parseFrontmatter(content) { const lines = content.split('\n'); if (lines[0]?.trim() !== '---') { return { frontmatter: null, body: content }; } const endIndex = lines.findIndex((line, i) => i > 0 && line.trim() === '---'); if (endIndex === -1) { return { frontmatter: null, body: content }; } const frontmatter = {}; for (let i = 1; i < endIndex; i++) { const line = lines[i]; const colonIndex = line.indexOf(':'); if (colonIndex > 0) { const key = line.slice(0, colonIndex).trim(); const value = line.slice(colonIndex + 1).trim(); frontmatter[key] = value; } } const body = lines.slice(endIndex + 1).join('\n').trimStart(); return { frontmatter, body }; } /** * Serialize a frontmatter object into YAML frontmatter block. */ export function stringifyFrontmatter(frontmatter) { const lines = ['---']; for (const [key, value] of Object.entries(frontmatter)) { lines.push(`${key}: ${value}`); } lines.push('---'); return lines.join('\n'); }