Working on the docs
How this site is built: Fumadocs, the generated Python reference, local preview and the GitHub Pages deployment.
The site lives in docs/ and is a Fumadocs app on
Next.js, exported statically and published to GitHub Pages by
.github/workflows/docs.yml.
docs/
content/docs/ the hand-written pages (MDX) and meta.json ordering
content/docs/developer/reference/ generated from the Python package, gitignored
scripts/generate-docs.mjs turns fumapy's JSON into the reference pages
app/, components/, lib/ the Next.js appLocal preview
Node 22 and the Python environment from the developer guide.
cd docs && npm ci && cd ..
# the Python reference: extract docstrings to JSON, then render MDX
uv pip install ./docs/node_modules/fumadocs-python
PYTHONPATH=. .venv/bin/fumapy-generate webstation_broker --dir docs
(cd docs && npm run generate)
# live preview on http://localhost:3000
(cd docs && npm run dev)
# or the exact static export the workflow publishes
(cd docs && NEXT_PUBLIC_BASE_PATH=/romm-broker npm run build && npm run start)fumapy-generate needs the package importable and its distribution metadata
present, hence PYTHONPATH=. after a pip install of the project. Regenerate
whenever docstrings change; the reference folder is ignored by git and rebuilt
on every deploy, so nothing generated is ever committed.
The Python reference
fumadocs-python ships a
Python package, fumapy, that loads the package with griffe, parses the
Google-style docstrings, and writes one JSON document. scripts/generate-docs.mjs
converts that into MDX under content/docs/developer/reference/, one folder
per module and one page per class, with every function rendered as a card
carrying its signature, parameters, return value and collapsible source.
The script does three things the stock converter does not:
- Rewrites
Raises:,Yields:,Warns:andExamples:sections into text, since the converter only renders the description and admonitions. - Drops
selfandclsfrom signatures and parameter lists. - Unescapes
<and{inside inline code, which the converter escapes everywhere and CommonMark would otherwise show literally.
It also strips the package name from paths and links so a module lands at
reference/emulators/base rather than reference/webstation_broker/emulators/base.
Writing pages
Pages are MDX with a title and description in the frontmatter (quote them;
a bare colon breaks the YAML). meta.json in each folder fixes the order and
the sidebar label. Available components beyond Markdown: Callout, Cards
and Card, Tabs and Tab, Steps and Step. Fenced code blocks take a
language and an optional title="..."; use txt for anything Shiki has no
grammar for.
Link between pages with site-absolute paths (/docs/api/exit); the base path
is added at build time.
Deployment
docs.yml runs on pushes to master that touch docs/, the package, or the
workflow itself, and on manual dispatch. It installs the package and
fumadocs-python, generates the reference, builds the static export with
NEXT_PUBLIC_BASE_PATH set from actions/configure-pages, and deploys with
actions/deploy-pages. The repository's Pages source must be set to
"GitHub Actions"; no gh-pages branch is involved. A fork with Pages enabled
the same way gets its own copy at https://<owner>.github.io/<repo>/.