# Translate

Translate anything under i18n/ into the project's locales with parallel subagents, ...

- Repository: https://github.com/thewh1teagle/vibe (7983 stars)
- Category: Git and review
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add thewh1teagle/vibe --skill translate -g -a claude-code -y`
Codex: `npx skills add thewh1teagle/vibe --skill translate -g -a codex -y`
Cursor: `npx skills add thewh1teagle/vibe --skill translate -g -a cursor -y`
Gemini CLI: `npx skills add thewh1teagle/vibe --skill translate -g -a gemini-cli -y`

## Description

Translate anything under i18n/ into the project's locales with parallel subagents, desktop and website catalogs, changelog entries, docs pages, then verify the structure, stamp the source hashes and run the audit. Use when the user asks to translate strings, release notes or docs, to fill missing locale keys, or invokes /translate.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Translate

```
i18n/desktop/<locale>.json          app strings      22 locales (desktop: true)
i18n/website/<locale>.json          site strings     15 locales (website: true)
i18n/changelog/<version>.md         release notes    English at the top level,
i18n/changelog/<locale>/<version>.md                 translations under a locale dir
i18n/docs/en-US/<slug>.md           docs pages       same shape
i18n/docs/<locale>/<slug>.md
```

`i18n/locales.json` is the roster, filter on `desktop` / `website`. Never edit
`en-US`; it is the source. A missing translation falls back to English whole, so
partial coverage is safe to ship.

## 1. Find what is missing

```bash
uv run scripts/check_i18n.py        # catalogs, changelog and docs coverage
```

For catalogs, the per-locale gap:

```bash
uv run python - <<'PY'
import json, pathlib
en = json.load(open("i18n/desktop/en-US.json"))
for p in sorted(pathlib.Path("i18n/desktop").glob("*.json")):
    if p.stem == "en-US": continue
    missing = [k for k in en if k not in json.load(open(p))]
    if missing: print(p.stem, len(missing))
PY
```

## 2. Fan out, one subagent per locale

Write the brief **once** to a scratch file, then spawn one cheap subagent
(`model: sonnet`) per locale in a **single message**, each pointing at that file
and naming only its own locale and output path. Never translate locale after
locale yourself; that is hours of serial work for no gain.

The brief must carry these rules, every one of them was a real defect at some
point:

The rest: https://github.com/thewh1teagle/vibe/blob/HEAD/.claude/skills/translate/SKILL.md
