sdk-reference-docs
hatchet-dev/hatchet/.claude/skills/sdk-reference-docs/SKILL.md
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.
Skill8.1k starsChanged 35 days ago
What's in it
- Overview
- Commands
- Per-language pipelines
- Ownership rules
- Gotchas (learned the hard way)
- Adding a new SDK language
---
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.0
last_updated: 2026-08-24
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
```bash
task generate-sdk-docs # all four languages (also part of `task generate`)
task generate-sdk-docs-python # sdks/python/docs/generate.sh
task generate-sdk-docs-typescript # sdks/typescript/docs/generate.sh
task generate-sdk-docs-go # (cd sdks/go && go run ./docs/generator)
task generate-sdk-docs-ruby # sdks/ruby/docs/generate.sh
```
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. So is `reference/index.mdx`.
- Generators hard-fail if an emitted page is unreachable from a meta.json.
- Each generator also emits `<lang>/index.mdx` (the section overview) from the shared hand-maintained mapping `frontend/docs/reference-map.json`, which pairs each canonical feature-client concept with per-language page slugs and its user-guide page. Generators hard-fail on an emitted feature-client page with no mapping entry, a mapping slug matching no emitted page, or a guide path that does not exist. Adding a feature client to any SDK therefore requires adding (or extending) its `reference-map.json` entry.
## Gotchas (learned the hard way)
1. **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 now has a hand-maintained `index.mdx`, and `app/(docs)/layout.tsx` still adds a fallback tab bound with `$folder` (for active-state detection), deduped by URL, pointing at `/reference`. The per-language sections also have generated index pages, so `/reference/<lang>` serves an overview rather than redirecting to the client page.
2. **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.
3. **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).
4. **golangci-lint**: repo uses v2 config; `os.WriteFile` in generators must use `0o600`.
5. Don't edit `frontend/docs/pages/**` — that's the dead pre-fumadocs tree.
6. **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
1. 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.
2. Hand-write the initial `<lang>/meta.json` (`client`, `context`, `feature-clients`, `runnables`); the generator merges it afterward.
3. Add a `generate-sdk-docs-<lang>` task to the root Taskfile and wire it into `generate-sdk-docs`.
4. 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.
5. Add `"<lang>"` to `frontend/docs/content/docs/reference/meta.json`.
More agent context in hatchet-dev/hatchet
8 other files this repository gives its agents.
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

