docs: publish translated docs in twelve languages and the tool that maintains them

Merged
MA
2mo ago
+89737-54

Ships the docs in twelve languages — de, es, fr, hi, ja, ko, pt (Brazilian), ru,
tr, uk, zh and zh-hant, each at /<code>/ — machine-translated from the English
pages, plus the small tool that keeps them current. English stays
the only source; everything under i18n/<lang>/pages/ is generated. Supersedes
#3231 and #3265 (same goal; this takes the review of both into account —
notably no anchor edits to the English docs, no nav-label subsystem, no
second-model gate, no state file).

  • scripts/docs/translations.py — three commands: status, translate --lang X [--pages …], stage [--lang X]. Pages are split at ## sections; only sections whose English changed are re-translated
    and everything else is carried forward byte-for-byte, so a one-line English
    edit is a one-line translated diff. Heading ids come from the site renderer
    itself and are pinned into the translation; code blocks are re-imposed from the
    English mechanically and link targets are checked against it. Provenance (section hashes) lives
    in each generated page's front matter — no side state.
  • Corrections are inputs: i18n/<lang>/instructions.md (register, voice,
    typography) and glossary.json (terms, keep-list, banned renderings), then
    translate --pages … for the affected pages; the generated pages are never
    hand-edited.
  • Build: language sites are staged (English overlaid with translations, a
    short notice after each H1 — machine-translated / behind the English page /
    shown in English), sidebar titles come from each translated page's own H1,
    and language builds are non-strict (missing snippet files included), so an
    English-only PR can't fail because of translations; a page whose English has
    changed since is served exactly as generated under an "outdated" notice until
    refreshed, and a page never translated is shown in English. The language sites
    add about a minute to the docs build in total; the API reference is linked,
    not rebuilt per language.
  • The language switcher shows code - name and keeps you on the current page
    when you change language. docs/translations.md explains all this to readers.

Intentional behavior changes

None to the SDK. The docs build now also produces the twelve language sites;
anthropic is added in a non-default translate dependency group (normal
installs don't get it).

Review notes

  • Registers/terminology are provisional pending native review — Portuguese has a
    reviewer lined up; reading order: i18n/general-prompt.md →
    i18n/pt/instructions.md + glossary.json → a few pages under
    i18n/pt/pages/ → docs/translations.md → the tool.
  • Known follow-ups: CJK search segmentation needs a Zensical bump (blocked on
    packaging, tracked separately); French spacing uses ordinary rather than
    no-break spaces (the model won't emit U+00A0; a small deterministic pass could); the "API Reference" nav label stays English
    on language sites; a handful of terminology consistency notes for native
    reviewers are listed in i18n/<lang>/glossary.json notes as provisional.
  • Running the tool needs ANTHROPIC_API_KEY; nothing in CI calls the API.
  • What the tool checks mechanically is deliberately bounded: heading skeleton
    and ids, code blocks, link targets, inline code, admonition/tab markers and
    list/table counts, per section. Placement within a section, glossary
    keep-terms, block titles and anything else about the prose is left to review
    of the (ordinary, human-reviewed) PR that commits regenerated pages.

AI Disclaimer