Skip to content

Docs site tooling

The documentation site treats contract API pages as generated output, not hand-written MDX.

pnpm docs:openapi:prepare copies contract-repo/openapi and contract-repo/schemas into apps/docs/src/generated/openapi, then normalizes JSON Schema boolean schemas so starlight-openapi can render the OpenAPI 3.1 contract set.

The API reference is generated by the Starlight build, not authored as MDX:

  1. Contract source changes land in contract-repo.
  2. docs:openapi:prepare stages normalized OpenAPI and JSON Schema files under apps/docs/src/generated/openapi.
  3. starlight-openapi generates /api/public/ and /api/internal/ pages and injects their sidebar groups.
  4. starlight-typedoc generates /api/client-sdk/ pages from documented TypeScript client exports.
  5. docs:routes:verify checks the built route output for generated API, client SDK, and LLM-readable docs pages.
  6. Generated output stays ignored by Git, so the contract repo remains the source of truth.

The prepare step is a gate, not a convenience copy. It fails before Astro runs if public-api.yaml, internal-api.yaml, or the schema source tree is missing, and it verifies that the staged generated OpenAPI files exist after normalization. This prevents silently publishing stale hand-written API pages.

Generated OpenAPI staging and generated TypeDoc content are ignored by Git. Local development expects contract-repo beside assembly-repo. CI sets SANMOPIA_CONTRACT_REPO_DIR after checking out yamonco/sanmopia-modernization-contract.

Use the root scripts instead of calling Astro directly:

Terminal window
pnpm docs:dev
pnpm docs:tooling:check
pnpm docs:routes:verify
pnpm docs:check
pnpm docs:build
pnpm docs:check:links

docs:tooling:check is part of the standard docs lifecycle. It verifies that the required Starlight plugin set and direct docs-tooling dependencies are installed with pinned versions, the plugins are wired in astro.config.mjs, generated OpenAPI files exist after the prepare step, generated OpenAPI/TypeDoc outputs remain ignored by Git, every root docs lifecycle script runs docs:openapi:prepare and docs:tooling:check, and hand-written api/public or api/internal reference directories do not exist. This keeps the API reference generated from contracts instead of drifting into hand-maintained docs.

docs:routes:verify runs after docs:build. It fails when the built Starlight output no longer contains generated /api/public/, /api/internal/, a known public operation route, a known internal operation route, the generated TypeDoc client SDK index, llms.txt, or a representative .md.txt export. It also checks that the OpenAPI source still defines the expected operation IDs before trusting the generated route paths. This closes the gap between “OpenAPI YAML was staged” and “Starlight actually published API pages.”

apps/docs/starlight-plugin-policy.json is the machine-readable plugin decision registry. docs:tooling:check reads it and fails when a standard plugin is missing, not pinned, or not wired in astro.config.mjs; it also fails if a plugin marked as deferred is installed without updating the registry. This turns the “do not reinvent Starlight plumbing” rule into a build gate instead of a prose-only ADR.

The docs site uses Starlight plugins for repeatable behavior. The standard set is intentionally OSS/plugin-first so we do not rebuild documentation plumbing in local Astro components:

PluginRole
starlight-openapiGenerates Public API and Internal API reference pages from contract OpenAPI files.
starlight-typedocGenerates the Client SDK reference from documented contract TypeScript exports.
starlight-auto-sidebarAdds metadata-backed control over autogenerated sidebar labels, ordering, depth, and badges.
starlight-sidebar-topicsSplits the large migration docs into API, architecture, domain, migration, and decision navigation topics.
starlight-view-modesAdds Zen mode for long C4, API, ADR, and migration checklist pages.
starlight-github-alertsRenders GitHub-style Markdown alerts as Starlight asides, so imported issue/PR notes do not need custom MDX.
starlight-kbdProvides a standard keyboard-shortcut authoring surface for operator and developer workflow docs.
starlight-llm-actionsAdds print/PDF and open-in-LLM page actions without local PageTitle UI plumbing. Raw Markdown copy/view actions stay disabled here because starlight-md-txt owns per-page raw exports.
starlight-image-zoomAdds zoom support to rendered images, including exported architecture diagrams.
starlight-codeblock-fullscreenMakes long code, YAML, and Mermaid blocks readable in fullscreen.
starlight-scroll-to-topAdds a scroll-to-top control with progress ring for long migration/reference pages.
starlight-sidebar-swipeMakes the sidebar swipeable on mobile, which matters for long operator and migration checklists.
starlight-telescopeAdds keyboard-first fuzzy page navigation for large API, ADR, and source-mining docs.
starlight-tagsAdds a central tag catalog plus generated /tags/ pages for cross-topic API, ADR, migration, frontend, backend, and operations discovery.
starlight-llms-txtPublishes /llms.txt, /llms-full.txt, and /llms-small.txt for AI-readable docs snapshots.
starlight-md-txtPublishes per-page .md.txt routes for agent-readable page-level context without custom route code.
starlight-links-validatorValidates internal links when SANMOPIA_DOCS_VALIDATE_LINKS=true.

Smallest recommended plugin set for API reference generation:

WorkflowKeep / addReason
Contract API referenceKeep starlight-openapi plus docs:openapi:prepareGenerates Public/Internal API pages from OpenAPI 3.1 contract files and avoids hand-written endpoint MDX.
API source stagingKeep local prepare/check scriptsScripts copy and normalize contract OpenAPI/JSON Schema files before Starlight runs; no extra docs plugin needed.
Interactive API playgroundDefer starlight-openapi-rapidoc or Scalar-style embedsUseful only if operators need in-browser request execution; it would add UI surface beyond current reference-read workflow.
TypeScript API docsKeep starlight-typedocGenerates the Client SDK reference from documented exports in contract-repo/packages/ts-client/src/index.ts without hand-written helper/type pages.

Current high-value Starlight plugins are installed and pinned. The July 8, 2026 catalog review keeps the standard set intentionally workflow-owned: add the must-have plugins for generated API reference, client SDK reference, navigation, search/discovery, diagram inspection, long-page reading, link checking, and agent-readable exports; do not install every catalog item when it duplicates another plugin or needs an unavailable external service. The next smallest additions, if needed later, are workflow-specific rather than default: starlight-versions for published versioned docs or Algolia DocSearch if the default Pagefind index is not enough.

Catalog sources for the current decision set are the Starlight Plugins and Integrations catalog, the starlight-openapi project page, and the starlight-versions getting started guide. The registry records why each plugin is standard or deferred.

July 2026 audit result:

CandidateDecisionReason
starlight-openapiKeepCurrent latest installed; generates OpenAPI 3.1 pages from local contract schemas.
starlight-typedocKeepGenerates client SDK reference from the contract TypeScript entry point.
starlight-image-zoomKeepCurrent latest installed; covers normal images while Mermaid SVG pan/zoom stays project-specific.
starlight-tagsKeepAdds generated tag index/detail pages from apps/docs/tags.yml, with strict unknown-tag failure to protect ubiquitous docs naming.
starlight-site-graphDefer0.5.0 and 0.4.1 both fail Astro 7 config validation because the integration receives {} where its schema expects an internal Map; revisit when upstream fixes the Starlight integration defaults.
starlight-links-validatorKeep gatedCurrent latest installed; runs only under SANMOPIA_DOCS_VALIDATE_LINKS=true to avoid slowing normal checks.
starlight-llms-txtKeepCurrent latest installed; emits AI-readable docs snapshots.
starlight-md-txtKeepAdds per-page .md.txt raw Markdown exports. Configure format: ".md.txt" explicitly because the package default is .md.
starlight-openapi-rapidocDeferBeta package and duplicates the generated reference workflow.
@scalar/astroDeferGood API UI, but not a Starlight plugin and its published peer range does not cover Astro 7.
starlight-versionsDeferUseful after first stable docs/API release; early-development plugin should not archive active migration docs yet.

Mermaid zoom is not provided by a Starlight Mermaid plugin in this repo. astro-mermaid renders Mermaid blocks, starlight-image-zoom handles normal Markdown/MDX images, and PageFrame.astro imports svgpanzoom.ts to wrap rendered Mermaid SVGs and SVG images with @beoe/pan-zoom. Keep that custom wrapper until a maintained Mermaid zoom plugin can replace both the rendering and pan/zoom behavior without losing existing diagram controls.

@pasqal-io/starlight-client-mermaid is the closest Starlight-native Mermaid plugin candidate, but it is not part of the standard set yet because its published package peers against the previous @astrojs/markdown-remark major. Revisit it only when it supports the current Astro 7 / Starlight 0.41 toolchain without peer drift.

Do not duplicate API pages manually. Add or change endpoint contracts in contract-repo/openapi plus JSON Schema first, and add or change SDK helper/type contracts in contract-repo/packages/ts-client/src. Add TypeDoc comments only for SDK surface that should be published. The Starlight build consumes those sources and regenerates the reference pages.

New Starlight plugin adoption rule:

  1. Prefer a maintained Starlight plugin over local Astro components for API references, diagram/image zoom, navigation, link checking, AI-readable exports, and long-form reading controls.
  2. Add a plugin only when it owns a repeatable docs workflow. Blog, comments, marketing UI, or duplicate search plugins are not part of the standard set.
  3. Keep docs:openapi:prepare in every root docs lifecycle script so API pages are generated from contract-repo/openapi before Starlight runs.
  4. Keep docs:routes:verify after docs:build so generated API, SDK, and agent-readable routes are proven from built output, not assumed from config.
  5. Run pnpm docs:check and pnpm docs:build after plugin changes because several Starlight plugins use route middleware or component override surfaces.

starlight-heading-badges is intentionally not part of the standard plugin set. It is useful in isolation, but it owns the same TableOfContents override surface as starlight-view-modes; carrying both would make one plugin partially ineffective unless we reintroduce custom override composition.

starlight-page-actions is also not part of the standard set. Its current dependency chain does not peer-check cleanly with the Astro 7 / Vite 8 line used by this repo. starlight-llm-actions covers the same docs workflow with a clean peer graph and adds the stable PDF/LLM handoff actions we need.

starlight-md-txt is part of the standard set with format: ".md.txt" and includeDrafts: false. The docs content must avoid angle-bracket autolinks because the plugin parses source Markdown through MDX before serializing raw page output.

Per-page LLM actions can be disabled or narrowed with the llmActions frontmatter key. The docs content schema validates that field through starlight-llm-actions/schema, so opt-outs stay intentional and typed.

Current generated API coverage includes booking service-term assembly read and projection-invalidation repair endpoints. Add future endpoint API changes to contract-repo/openapi plus JSON Schema first; Starlight then regenerates the reference pages through starlight-openapi. Add future published TypeScript client surface changes to contract-repo/packages/ts-client/src with TypeDoc comments; Starlight regenerates the client SDK reference through starlight-typedoc.

starlight-versions is still intentionally deferred. Its own documentation marks it as opinionated and early-development, and this repo has not cut stable published documentation snapshots yet. Revisit it when contract/doc release channels exist.

The docs site uses topic-level navigation for long-lived operator workflows instead of one unbounded sidebar. API reference, architecture, domain delivery, migration source map, and ADR pages each have their own topic-backed sidebar.

Generated OpenAPI and TypeScript client pages are explicitly mapped to the API topic because they are created by Starlight plugins during the build and do not exist as hand-written content pages.