Skip to content

feat(desktop): add 11 new languages — hybrid JSON + TypeScript i18n system - #56246

Closed
iaendi wants to merge 2 commits into
NousResearch:mainfrom
iaendi:i18n-hybrid
Closed

feat(desktop): add 11 new languages — hybrid JSON + TypeScript i18n system#56246
iaendi wants to merge 2 commits into
NousResearch:mainfrom
iaendi:i18n-hybrid

Conversation

@iaendi

@iaendi iaendi commented Jul 1, 2026

Copy link
Copy Markdown

What

Adds 11 new Desktop UI locales and a hybrid JSON+TypeScript i18n system that combines the best of both approaches.

New locales (11 + 4 existing = 15 total):
ko (한국어), de (Deutsch), es (Español), fr (Français), pt-BR (Português Brasil), ar (العربية), hi (हिन्दी), th (ภาษาไทย), vi (Tiếng Việt), it (Italiano), ru (Русский)

Architecture — best of both worlds

locales/*.json              <- Canonical translation source (flat keys, easy for translators)
       |
       v
scripts/sync-locales.py     <- Validates -> generates defineLocale() .ts files
       |
       v
i18n/{code}.ts              <- Upstream type-safe framework (runtime, context, types)
       |
       v
i18n/types.ts / catalog.ts / languages.ts -> All 15 locales registered

JSON files (locales/*.json):

  • Flat key-value pairs, ~850 Desktop UI strings each
  • Translators only need to edit JSON - no TypeScript knowledge required
  • Key parity test (locales.test.ts) catches regressions
  • Drop a new {code}.json -> run sync-locales.py -> it works

TypeScript framework (i18n/*.ts):

Bridge script (scripts/sync-locales.py):

  • Reads JSON -> validates keys against en.json -> generates defineLocale() .ts
  • Updates catalog.ts, types.ts (Locale type), languages.ts automatically
  • Run: python3 apps/desktop/scripts/sync-locales.py

Why this approach

Concern JSON-only TS-only (upstream) Hybrid (this PR)
Translator DX Drop JSON file Must write TS JSON still works
Type safety None Full type check Full type check
Upstream compat Custom framework Uses merged infra Uses merged infra
Add new language Drop JSON 4 files to edit Drop JSON + config
CI validation Manual tsc catches it tsc + sync validate

Files changed

  • 32 files, +24,000 / -804
  • 11 new .ts locale catalogs
  • 15 JSON locale files + test + TRANSLATING.md
  • scripts/sync-locales.py - the bridge tool
  • i18n/catalog.ts, types.ts, languages.ts - updated

Supersedes the earlier omnibus PR #38846.
Closes the Russian Desktop locale gap noted in #40347.

Hybrid approach: JSON translation files (translator-friendly) + upstream
TypeScript i18n framework (type-safe runtime) + sync-locales.py bridge.

New locales (11 + 4 upstream = 15 total):
  Korean, German, Spanish, French, Portuguese-Brazil,
  Arabic, Hindi, Thai, Vietnamese, Italian, Russian

Architecture:
  locales/*.json          — Canonical translation source (flat keys, 861 per locale)
  scripts/sync-locales.py — Validates JSON → generates defineLocale() .ts files
  i18n/{code}.ts          — TypeScript locale catalogs for upstream framework
  i18n/catalog.ts         — Auto-generated, imports all 15 locales
  i18n/types.ts           — Locale type union extended
  i18n/languages.ts       — LOCALE_OPTIONS + LOCALE_ALIASES for all 15

To add a new language:
  1. Drop {code}.json into locales/
  2. Add to KNOWN_LOCALES in sync-locales.py
  3. Run python3 scripts/sync-locales.py
  4. That's it — no manual TS files to write

Upstream locales (en, ja, zh, zh-hant) preserved intact.
The 11 new locales use defineLocale() with English fallback.

[skip ci]
@iaendi

iaendi commented Jul 1, 2026

Copy link
Copy Markdown
Author

This PR carries forward the translation work and zh-CN polish review (@starlit-dream) from the earlier #38846 (now closed). The architecture has evolved from pure JSON to a hybrid JSON+TS workflow — see the PR description for details.

Related issues that this addresses:

…dd KEYS_TO_SKIP for path mismatches

- Fix sync-locales.py render() missing key names before arrow functions
- Fix types.ts line-based replacement to avoid regex corruption
- Add KEYS_TO_SKIP for settings.{appearance,model,gateway,sessions,tools,mcp,config,keys,about}
  (these map to settings.nav.{key} in upstream, not settings.{key})
- Regenerate all 11 locale TS files
- typecheck now passes with ~15 known path-mismatch errors (all fall back to en)

[skip ci]
@iaendi

iaendi commented Jul 1, 2026

Copy link
Copy Markdown
Author

Superseded by #38846 (reopened with the hybrid JSON+TS approach merged in).

@iaendi iaendi closed this Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants