20260915-1901-astro-starlight-migration Rebuild the docs site on Astro + Starlight with on-demand rendering
- status: completed
- priority: P1
- owner: claude/session-20260915-1901
- completedAt: 2026-09-16 06:30
- createdAt: 2026-09-15 19:01
Description
章节标题:“Description”The site is a VitePress 1.6.4 static build deployed to Cloudflare Workers as assets only. VitePress has no runtime rendering: it is build-time SSG plus a client SPA, with no dynamic routes, no request-time data loading and no access to Cloudflare bindings. Upcoming work needs dynamic content served from the same site, so the framework has to change.
Target: Astro 7 + Starlight, Cloudflare adapter, hybrid rendering. Starlight pages stay
prerendered (prerender: true is its default even under output: 'server'), so the 294 existing
Markdown pages keep today's cost and latency profile as static assets, and only routes that opt
out with export const prerender = false execute in a Worker.
Acceptance criteria:
- Every URL the current build publishes still resolves, with no change to
_redirectssemantics. - The generated explorer sidebar, breadcrumbs, frontmatter meta block, directory index pages and
the generated
docs/sitemap.mdbehave as they do today. - Chinese full-text search is no worse than the current MiniSearch bigram tokenizer.
- The three Mermaid pages still render, with ELK layout.
bun run docs:lintpasses unchanged; the quality gate command still works.- At least one route renders on demand in a Worker and can read a Cloudflare binding.
- Non-Markdown linked assets are still copied into the build output, with the 25 MiB guard intact.
ActiveForm
章节标题:“ActiveForm”Rebuilding the docs site on Astro + Starlight
Dependencies
章节标题:“Dependencies”- blocked by: (none)
- blocks: (none)
Notes
章节标题:“Notes”Plan: docs/plan/20260915-1901-astro-starlight-migration.md.
The concrete dynamic feature is not yet specified; this task delivers the platform, not the feature.
Execution: BKD three-tier campaign
章节标题:“Execution: BKD three-tier campaign”- campaignId:
l1-5k89db54-20260915190438, project7li8qh57, baseBranchmain - L1 (coordination, main worktree, no cron): issue
5k89db54 - L2-A
yf6wxxkf- platform: scaffold, in-place content loader (G1), hybrid rendering (G4). Blocks B and C. - L2-B
v61em621- site shell: sidebar, breadcrumb, doc meta, CSS, Mermaid (G3). Held in todo until A merges. - L2-C
fut7wvuf- build pipeline: search (G2), asset copy, redirects, URL parity, deploy. Held in todo until A merges. - G4 uses a runtime probe route only; no Cloudflare resource (D1/KV/R2) is provisioned in this campaign.
- Removal of
.vitepress/is held in L2-C until L1 releases it after B merges.
Progress
章节标题:“Progress”- 2026-09-16: G1 achieved. Astro 7.3.2 + Starlight 0.42.0 render all 287 pages in place
from
bizplan/anddocs/at byte-identical URLs.docsLoader()is not used; a plainglob()loader (base., patternsbizplan/**/*.md,docs/**/*.md,!docs/templates/**) withgenerateIdstripping.mdand a trailing/indexpreserves case and dots.git status --porcelain bizplan docsempty; 52-vs-52 empty route diff on a three-directory sample;docs:lintgreen withscripts/lint-docs.mjsunmodified. - Accepted deviations, recorded so they are not re-litigated:
- 61 of 287 pages carry no YAML frontmatter (all of
docs/plan/anddocs/task/, plusdocs/changelog.mdand one file underdocs/decisions/). AparseDatawrapper injectstitlefrom the first#heading, mirroring the fallback.vitepress/site-tree.tsalready uses. Downstream sidebar and meta code must tolerate absentkind/status. - Astro 7.3.2 defaults to the Saetteri Markdown processor;
markdown.remarkPluginsthrows. The leading-H1 strip is an mdast plugin viamarkdown.processor: satteri({ mdastPlugins }), avoiding a second processor and the@astrojs/markdown-remarkdependency. - Starlight's own Markdown transforms only run under
src/content/docs, so heading anchor links are missing for in-place content. Fixed bymarkdown.processedDirs: ['bizplan','docs']in the Starlight options block; assigned to L2-B.
- 61 of 287 pages carry no YAML frontmatter (all of
- This BKD server parses six-field cron expressions (seconds first);
*/15 * * * *would mean every 15 seconds. Campaign crons use0 */15 * * * *. - Open: the root
index.mdis a VitePresslayout: homehero page with no Starlight equivalent and is excluded from the collection, so/has no page. Awaiting the owner's decision; assigned to L2-B either way. - 2026-09-16: Platform workstream merged twice. Second pass closed a site-wide regression the URL
set diff could not see: Astro does not rewrite relative Markdown links, so 215 of 288 pages
emitted in-site hrefs that 404. A mdast plugin now resolves each
.mdlink against its linking file and maps it through the collection's own id rule, sharing oneDOC_PATTERNwith the loader so a link is only rewritten once its target is a published page. 1271 links rewritten; the residual is 4 external GitHub links plus one transient. - The body heading now outranks a diverging frontmatter title, restoring descriptive prose on 25
index pages that the leading-heading strip was deleting. Accepted cost:
<title>, Pagefind result titles and prev/next labels carry the long form on those pages. - The content invariant is a commit-range diff against
git merge-base main HEAD, not a fixed baseline: a fixed SHA reported L1's own PMA commits as workstream violations.