docs: link-check unified site + fix systemic base-prefix bug (#75)#76
Merged
Conversation
Validates internal links across the unified .docs-dist/chant/ tree assembled by scripts/build-docs.sh. Each Starlight site only validates its own slug links at build time, so cross-site references (sidebar links, MDX hrefs) between the main docs and the 12 lexicon sites go unchecked until they 404 in prod. Runs lychee in offline mode with absolute paths resolved against .docs-dist/, mirroring how GitHub Pages serves the site. Asset extensions and the Starlight pagefind index are excluded so the signal is page-to-page navigation only. Refs #75.
Root-relative links written in MDX content body (TypeDoc-generated /api/* pages, hand-written /lexicons/* references, one codegen literal) do not get the configured Astro `base` prepended at build time. Only sidebar `link:` and Starlight `slug:` entries are base-prefixed. Result: 485 broken links across 120 source files in the main docs alone. Adds rehype-base-url, a small HAST visitor (~70 lines, no deps) that walks the tree and rewrites <a href> attributes starting with "/" to start with the configured site `base` instead. Idempotent against already-prefixed links via an optional `projectBase` guard that lets cross-site /chant/... references pass through unchanged in lexicon builds. The plugin lives at packages/core/src/codegen/rehype-base-url.mjs as the single source of truth. The main docs imports it via cross-package relative path; the lexicon codegen copies it into each generated docs site so the generated Astro config can import locally. Docker and Slurm docs are hand-maintained — their astro.config.mjs files use the same relative-path import. Slurm's missing `base` config (a pre-existing bug) is also fixed in passing. Also fixes one hardcoded /serialization/output-formats link in docs-sections.ts:153 at source (writing /chant/...) since the plugin in a lexicon context would have mis-prefixed it. Verification: just docs-check-links drops from ~603 errors to 18. The remaining 18 are pre-existing cross-doc content bugs (missing chant/guide/multi-lexicon target, mis-prefixed temporal links, k8s composite relative-link confusion) tracked separately under #75. Refs #75.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related changes:
just docs-check-links— new target that runs lychee against the unified.docs-dist/chant/tree to catch cross-site link breakage that individual Starlight builds can't see.rehype-base-urlplugin — auto-prefixes root-relative<a href>attributes in MDX content with the configured Astrobase, fixing the systemic source of broken links the lychee target surfaced.The plugin is a ~70-line dependency-free HAST visitor with a
projectBaseoption so it's idempotent against already-prefixed/chant/…links. Single source of truth atpackages/core/src/codegen/rehype-base-url.mjs. The lexicon codegen (packages/core/src/codegen/docs.ts) copies it into each generated docs site; main docs and the two hand-maintained lexicon configs (docker, slurm) import it via cross-package relative path.Also fixes:
/serialization/output-formatslink indocs-sections.ts:153at source (otherwise the plugin would mis-prefix it in a lexicon context).baseconfig on slurm's astro.config.mjs.Impact
just docs-check-linkson this branch: 603 errors → 18 errors (97% reduction).The 18 remaining errors are pre-existing cross-doc content bugs unrelated to base-prefixing:
chant/guide/multi-lexicon(referenced from flyway-postgresql and gitlab-cells tutorials — target page doesn't exist)chant/lexicons/k8s/{aks,eks,gke}-composites/composite-examples(relative link confusion across k8s composite pages)chant/docs/lexicon-authoring/lint-rulesfrom temporal lint-rules (stray/docs/segment)chant/lexicons/temporal/ops/worker-profiles(wrong subdirectory)chant/lexicons/aws/guide/composite-resources(relative-path resolution)These are tracked under #75 for individual page-level fixes in follow-up.
Test plan
npx vitest run packages/core/src/codegen/rehype-base-url.test.ts— 20/20 plugin unit tests pass (edge cases: protocol-relative, anchors, already-prefixed, relative, etc.)just check— 5737 tests pass, no tsc/lint regressionsjust docs-build— succeeds end-to-end with the regenerated lexicon configsjust docs-check-links— drops from 603 to 18 errors; spot-checkedgetting-started/introduction/index.html(all/lexicons/...→/chant/lexicons/...) andapi/classes/attrref/index.html(all/api/...→/chant/api/...)🤖 Generated with Claude Code