| name | sdk-reference-docs |
| description | How the SDK reference docs pipeline works — regenerating references for the Python/TypeScript/Go/Ruby SDKs, adding a new SDK language, and known gotchas. Use when working on docs generation, sdks/*/docs generators, or content/docs/reference. |
| version | 1 |
| last_updated | "2026-08-24T00:00:00.000Z" |
| self_updating | true |
📝 SELF-UPDATING DOCUMENT: Verify against the actual codebase and update this file when it drifts.
Overview
The SDK reference sections under frontend/docs/content/docs/reference/{python,typescript,go,ruby} are generated from SDK source — doc comments and docstrings are the source of truth. Never hand-edit generated .mdx; the next regeneration overwrites it. To change reference content, edit the doc comment/docstring in the SDK and regenerate.
Commands
task generate-sdk-docs
task generate-sdk-docs-python
task generate-sdk-docs-typescript
task generate-sdk-docs-go
task generate-sdk-docs-ruby
All four pipelines are fully deterministic; no AI/LLM is involved anywhere and no API keys are needed.
CI: .github/workflows/gen-sdk-docs.yml runs on pushes to main touching sdks/** or pkg/worker/** (the Go generator also reads pkg/worker for the Context interfaces). It detects which SDKs changed, regenerates only those, opens a PR labeled autogenerated-sdk-docs, and requests auto-squash-merge. workflow_dispatch only runs from main. Optional SDK_DOCS_PR_TOKEN secret (PAT/App token) makes generated PRs trigger normal CI.
Per-language pipelines
| Language | Pipeline | Notes |
|---|
| Python | mkdocs (mkdocstrings, markdown-export plugin) → deterministic converter → mdx | Feature-client md stubs are auto-created from Hatchet client introspection. Doc prose lives in docstrings; the converter is verbatim-faithful. |
| TypeScript | typedoc (custom theme docs/markdown-theme.mjs) → docs/generate.ts | entryPoints derived by globbing src/v1/client/features/*.ts — new feature clients need zero config. |
| Go | sdks/go/docs/generator (stdlib go/doc) | Feature clients auto-discovered from Client methods returning *features.X. Also parses pkg/worker. |
| Ruby | sdks/ruby/docs/generate.rb (YARD registry + RBS sigs) | Static parse — no SDK gem install needed. New public methods on core classes auto-append. |
Ownership rules
- Generators own: every
.mdx in their section + feature-clients/meta.json.
- Section
meta.json (e.g. python/meta.json) is merged, not overwritten: existing order and separator strings (e.g. ---Python Specifics---) are preserved; new pages auto-append; dead entries are removed.
- Hand-authored pages exist only in Python (asyncio, pydantic, lifespans, dependency-injection, dataclasses) — generators never touch them.
reference/meta.json (top-level) is hand-maintained. Nothing generates it.
- Generators hard-fail if an emitted page is unreachable from a meta.json.
Gotchas (learned the hard way)
- fumadocs dropdown: a
root: true folder only appears in the section dropdown if it has an index page or a direct page child. The Reference folder deliberately has neither — its tab is added manually in app/(docs)/layout.tsx via getLayoutTabs() + a hand-built tab bound with $folder (for active-state detection), pointing at /reference/changelog. /reference also redirects there in next.config.mjs.
- Never put
{/* */} JSX comments in this repo's MDX — the prettier pass rewrites * to _ inside them, producing invalid MDX that 500s the whole docs site.
- Determinism is a requirement: every generator must produce byte-identical output across runs (sorted iteration everywhere), or CI churns endless PRs. Verify with a double run + checksum diff. Output must not depend on optional tooling: the Go generator hard-fails if frontend/docs prettier is missing (a silent skip once shipped unformatted pages via CI while local runs looked clean).
- golangci-lint: repo uses v2 config;
os.WriteFile in generators must use 0o600.
- Don't edit
frontend/docs/pages/** — that's the dead pre-fumadocs tree.
- No em dashes in docs content (
.cursor/rules/docs-writing-style.mdc): use commas, parentheses, or separate sentences. Generated pages inherit them from SDK doc comments, so fix them at the source.
Adding a new SDK language
- Build a generator under
sdks/<lang>/docs/ with a generate.sh entry point (or go run ./docs/generator style) that emits the standard layout: client.mdx, context.mdx, runnables.mdx, feature-clients/*.mdx + feature-clients/meta.json, into frontend/docs/content/docs/reference/<lang>/. Use content/docs/reference/python/ as the style template. Auto-discover feature clients from source; no hand-lists.
- Hand-write the initial
<lang>/meta.json (client, context, feature-clients, runnables); the generator merges it afterward.
- Add a
generate-sdk-docs-<lang> task to the root Taskfile and wire it into generate-sdk-docs.
- Add the language to
.github/workflows/gen-sdk-docs.yml: the for lang in ... loop in the detect step, a toolchain setup step if needed, and a conditional generate step.
- Add
"<lang>" to frontend/docs/content/docs/reference/meta.json.