# Sdk Reference Docs

> 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.

- Skill: `hatchet-dev/sdk-reference-docs` (Agent Skill)
- Install (CLI): `npx skillmds@latest add hatchet-dev/sdk-reference-docs`
- Raw SKILL.md: https://api.skillmd.com/api/skills/hatchet-dev/sdk-reference-docs/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: hatchet-dev (https://skillmd.com/u/hatchet-dev)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/hatchet-dev/sdk-reference-docs

---


**📝 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`.

