diff --git a/site/scripts/sync-wiki.mjs b/site/scripts/sync-wiki.mjs index a8a8ad6d..a2464e78 100755 --- a/site/scripts/sync-wiki.mjs +++ b/site/scripts/sync-wiki.mjs @@ -63,6 +63,19 @@ function extractTitle(body, fallback) { return fallback; } +/** Strip the first ATX H1 — Starlight already renders `title` as the page H1. */ +function stripLeadingH1(body) { + const lines = body.split(/\r?\n/); + let i = 0; + while (i < lines.length && lines[i].trim() === '') i += 1; + if (i < lines.length && /^#\s+/.test(lines[i])) { + i += 1; + while (i < lines.length && lines[i].trim() === '') i += 1; + return lines.slice(i).join('\n'); + } + return body; +} + function yamlEscape(s) { if (/[:#{}[\],&*!|>'"%@`]|^[-?]|\n/.test(s) || s !== s.trim()) { return JSON.stringify(s); @@ -158,6 +171,7 @@ function writeDoc(wikiRel, sourceAbs) { const fallbackTitle = path.basename(wikiRel, '.md'); const title = extractTitle(body, fallbackTitle); + body = stripLeadingH1(body); body = rewriteMarkdownLinks(body, wikiRel); const out = `---\ntitle: ${yamlEscape(title)}\n---\n\n${body.trimStart()}`; diff --git a/wiki/log/DEVLOG.md b/wiki/log/DEVLOG.md index 51a41d70..8af8d953 100644 --- a/wiki/log/DEVLOG.md +++ b/wiki/log/DEVLOG.md @@ -5,6 +5,15 @@ Type: log ``` Reverse chronological implementation notes. Keep this factual: what changed, why, checks, and spec impact. +## 2026-07-08 - Starlight: strip leading H1 (no doubled titles) + +- Intent: Starlight renders frontmatter `title` as the page H1; sync was + also leaving the markdown `#` heading, so every page showed the title + twice. +- Changed: `site/scripts/sync-wiki.mjs` strips the first ATX H1 after + extracting `title`; redeployed orphan `pages`. +- Checks: sync spot-check on constitution + compute; `./tools/site-deploy.sh`. + ## 2026-07-08 - Starlight site CI: sed + pnpm build scripts - Intent: `.tangled/workflows/site.yml` failed — pnpm's `astro` shim