Skip to content

Add the /translate skill, with translator and reviewer agents, style sheets and a glossary - #1204

Merged
timche merged 6 commits into
betafrom
i18n-translate-skill
Oct 20, 2026
Merged

timche merged 6 commits into
betafrom
i18n-translate-skill

Conversation

@timche

@timche timche commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Slice 3 of translating Meru's interface, after the groundwork in #1197 (#1197). This adds the tooling that writes and reviews translations. No catalog other than English ships yet, so with English alone /translate says there is nothing to translate and stops.

  • /translate (.claude/skills/translate/SKILL.md):
    1. Extracts strings.
    2. Collects each shipped locale's untranslated and fuzzy entries, in both the app catalog and the Gmail preload catalog. When the English of an entry changed, it adds the old translation as prior art; collect.ts reads that from git, because extract --clean drops obsolete entries.
    3. Runs one translator per locale, in parallel.
    4. Runs one translation-reviewer per locale. The reviewer's findings go back to the same translator, continued, for at most two rounds.
    5. Finishes with CI's checks: check sync --clean, check missing, i18n:check and compile --strict.
  • Agents. translator runs on claude-opus-5-5 at high effort, and translation-reviewer on claude-sonnet-5-5 at medium effort. These come from a blind test of the three current models on real strings in German, Polish and Japanese.
  • Ten style sheets (languages/<tag>.md). Each holds its language's address form, label form, capitalization, Settings word, plural categories and traps, with Apple's words read from the macOS Mail and AppKit string tables.
  • A glossary of Meru's terms, with one fixed translation per catalog. It uses Apple's word unless the string names something Gmail also shows; then Gmail's word wins, so German Undo is Rückgängig machen. Gmail's words carry a Gmail Help source for each locale.
  • CLAUDE.md says CI stays strict: a contributor without Claude Code gets a red run, and the maintainer runs /translate on the pull request before merging.
  • tsconfig.json now includes .claude/skills/**/*.ts, so collect.ts is typechecked.

Proof

Run on a scratch branch from this one that ships de, pl and ja, with a plural message and a <0> tag message added. On beta there is no /translate to run.

Before /translate:

$ bunx lingui check missing --mode catalog --verbose --workers 1
FAIL missing: Found 33 missing translation(s) before applying fallbackLocales.
packages/shared/i18n/locales/de.po: mfnAuh: ({count, plural, one {# tab hibernated} other {# tabs hibernated}})
packages/shared/i18n/locales/de.po: jz9i11: (Press <0>Cmd+K</0> to search your accounts.)
… de, pl and ja across both catalogs

After env -u CLAUDE_CODE_EFFORT_LEVEL claude -p "/translate". Three translators ran in parallel, then three reviewers, and all passed review:

PASS sync: Catalogs are in sync with extract output.
PASS missing: No missing translations found before applying fallbackLocales.
No catalog problems in en, de, pl, ja.
Compiling message catalogs… Done in 114ms   (compile --strict)
  • German uses du: Drücke <0>Cmd+K</0>, um deine Accounts zu durchsuchen. The toast reads Rückgängig machen and Nachricht gesendet.
  • Polish has all four plural forms: Zahibernowano # kartę / karty / kart / karty.
  • Japanese uses です/ます and Apple's punctuation: このメッセージを削除してもよろしいですか?

Reviewer. I planted German Ihres, a dropped <0> tag, a dropped {systemLabel}, a Polish plural without few and a Japanese half-width comma. The reviewers named all five.

Fix loop. A finding sent back with SendMessage reached the original German translator. It fixed the entry, and the re-review passed under claude -p.

Prior art. When two entries share the comment "Menu item" and one is reworded, the reworded one is paired with its own old translation, at a similarity of 0.92, and never with the other entry's.

fmt:check, lint, types and bun test --isolate pass.

Risk

Low. The change is tooling and docs; no app code changes. Revert the squash commit to undo it.

@timche
timche merged commit 71329ff into beta Oct 20, 2026
9 checks passed
@timche
timche deleted the i18n-translate-skill branch October 20, 2026 14:34
timche added a commit that referenced this pull request Oct 23, 2026
…sheets and a glossary (#1204)

* Add the /translate skill, with translator and reviewer agents, style sheets and a glossary

* Pair prior art by similarity, giving each old entry to at most one new one

* Warn when the collector's --base does not resolve

* Typecheck the skills' scripts with the root tsconfig

* Use Gmail's word for what Gmail also shows, with sources per locale

* Follow Apple's Japanese punctuation: half-width ? and !, and curly quotes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant