import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DOCS_PATH = path.resolve(__dirname, '..', 'app-docs.md'); let cachedSections = []; let cachedMtimeMs = 0; function slugify(text) { return String(text || '') .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, ''); } async function loadSections() { const stats = await fs.stat(DOCS_PATH); if (cachedSections.length && cachedMtimeMs === stats.mtimeMs) return cachedSections; const raw = await fs.readFile(DOCS_PATH, 'utf8'); const parts = raw.split(/^##\s+/m); const first = parts.shift() || ''; const sections = []; const overview = first.replace(/^#.*$/m, '').trim(); if (overview) { sections.push({ id: 'overview', title: 'Overview', content: overview, }); } parts.forEach((part) => { const lines = part.split('\n'); const title = (lines.shift() || '').trim(); const content = lines.join('\n').trim(); if (!title || !content) return; sections.push({ id: slugify(title), title, content, }); }); cachedSections = sections; cachedMtimeMs = stats.mtimeMs; return sections; } export async function listAppDocSections() { const sections = await loadSections(); return sections.map(({ id, title }) => ({ id, title })); } export async function readAppDocSection(sectionId) { const target = String(sectionId || '').trim().toLowerCase(); if (!target) return null; const sections = await loadSections(); return sections.find((section) => section.id === target || section.title.toLowerCase() === target ) || null; }