feat(i18n): add 11 new languages — Korean, German, Spanish, French, Portuguese-BR, Arabic, Hindi, Thai, Vietnamese, Italian, Russian - #227
Conversation
…ortuguese-BR, Arabic, Hindi, Thai, Vietnamese, Italian, Russian
|
Review Complete Files Reviewed: 14 By Severity:
All 11 new locale files (ar, de, es, fr, hi, it, ko, pt-br, ru, th, vi) have a structurally mismatched key hierarchy versus the Translations interface in types.ts, with bare arrow function syntax errors and flat string-to-object overwrites that will cause compilation failure and broken translations. Files Reviewed (14 files) |
There was a problem hiding this comment.
Risk: 🔴 Critical (85/100) — 1 critical finding · 10621 LOC across 14 files
Critical Structural Mismatch in 11 Locale Files
The 11 new i18n locale files introduced in this PR share an identical structural defect that makes them uncompilable and non-functional:
Three Compounding Defects
-
Key hierarchy mismatch — The files use 23 top-level keys (e.g.,
about,appearance,bootstrap,chat) that are not in theTranslationsinterface defined intypes.ts, while missing 16 required keys (assistant,desktop,settings,composer, etc.). The working reference locales (en.ts,ja.ts,zh.ts,zh-hant.ts) all follow the correct 33-key structure. -
Bare arrow function syntax errors — At ~28 locations per file, arrow functions appear without property keys (e.g.,
count => \...`). This is **not valid JavaScript/TypeScript** per ECMAScript §12.2.6 — object literal entries require aPropertyName: AssignmentExpression` form. -
String-to-object overwrites — Settings sections (
settings.appearance,settings.model, etc.) provide flat string values instead of nested objects, which will overwrite entire sub-trees inmergeTranslations().
Files Affected
apps/desktop/src/i18n/{ar,de,es,fr,hi,it,ko,pt-br,ru,th,vi}.ts — all 11 files share identical structure patterns drawn from the same generation template.
Fix Approach
Copy en.ts as the structural template for each file and map the existing translation strings into the correct nested paths. defineLocale() automatically fills untranslated keys from the English base, so partial mapping is acceptable.
|
|
||
| export const de = defineLocale( | ||
| { | ||
| appearance: { |
There was a problem hiding this comment.
🔴 All 11 new locale files are structurally mismatched with Translations type contract — compilation will fail, translations will be broken (bug)
The 11 new locale files (ar.ts, de.ts, es.ts, fr.ts, hi.ts, it.ts, ko.ts, pt-br.ts, ru.ts, th.ts, vi.ts) were generated with a structure that does not match the Translations interface in types.ts. Three compounding defects make these files unusable:
1. Structural mismatch (holistic + domain): The files use 23 top-level keys not in the Translations interface (about, appearance, bootstrap, chat, clarify, config, file, gateway, header, intro, keys, mcp, model, models, nav, pagination, previewConsole, provider, sessions, terminal, tool, tools, urlDialog) and are missing 16 required top-level keys (assistant, desktop, fileMenu, keybinds, language, modelPicker, modelVisibility, notifications, preview, prompts, remoteDisplayBanner, rightSidebar, shell, starmap, statusStack, ui). The defineLocale() function accepts TranslationOverride, a mapped type restricted to keyof Translations — extra keys cause TypeScript compilation errors. The working reference locales (en.ts, ja.ts, zh.ts, zh-hant.ts) all use the correct 33-key structure.
2. Bare arrow function syntax errors (domain-dom-001): At ~28 locations per file, arrow functions are used as bare object literal entries without a property key prefix (e.g., count => \...`instead ofupdateReady: count => `...``). This is not valid ECMAScript or TypeScript object literal syntax per §12.2.6 of the spec. Arrow functions are AssignmentExpressions, not PropertyDefinitions — they require a PropertyName + colon prefix. Each file has these syntax errors in sections: commandCenter (line ~129), about/qbout (lines 279-289), config/keys (lines 309-312), mcp (lines 336-337, 565), sessions (line 503), gateway (line 447), updates (lines 684-685), tool (lines 722, 724), clarifier (line 865), and intro (lines 879-888). These files cannot be parsed by any JavaScript/TypeScript engine.
3. String-to-object overwrite (domain-dom-002): The settings section provides flat string values for keys that are nested objects in the Translations type (e.g., settings.appearance: 'المظهر' is a string, but Translations expects settings.appearance: { title, intro, colorMode, ... }). The mergeTranslations() function at define-locale.ts:33 does result[key] = isRecord(baseValue) && isRecord(value) ? mergeTranslations(baseValue, value) : value — since the value is a string (not a record), the entire English nested object tree is overwritten with the flat string. This causes every sub-key (colorMode, toolViewTitle, theme*, etc.) to become undefined at runtime in the affected sections (appearance, model, gateway, sessions, mcp, config, keys, about, tools).
4. Duplicate key overwrites (domain-dom-003): Even after fixing the syntax errors, plural-form entries use the same parameter name repeatedly without distinguishing keys (e.g., two adjacent count => entries for singular/plural that would need distinct property names like updateReady to coexist). In the current broken form these are unreachable; after fixing syntax they would silently lose all singular/plural distinctions.
All 11 files share identical issue patterns across all sections. The files need complete restructuring to match the Translations interface structure used by en.ts, ja.ts, zh.ts, and zh-hant.ts.
💡 Suggestion: The 11 new locale files need a complete rewrite to match the Translations interface structure. The most efficient approach: (1) Copy en.ts as the structural template for each language. (2) For each translated string in the broken files, map it into the correct nested path in the new template (e.g., broken appearance.title → correct settings.appearance.title, broken chat.send → correct composer.send, broken about section bare arrow functions → correct settings.about.updateReady: count => ..., etc.). (3) The defineLocale() merge function fills any untranslated keys from the English base automatically, so partial translations are acceptable — focus on mapping existing translations correctly. (4) Ensure every property has a proper key prefix (no bare arrow functions). (5) Ensure nested objects are provided as objects, not flat strings. Verify that the resulting files satisfy the TranslationOverrides type constraint.
📋 Prompt for AI Agents
Restructure all 11 locale files (apps/desktop/src/i18n/{ar,de,es,fr,hi,it,ko,pt-br,ru,th,vi}.ts) to match the Translations interface in types.ts. Use en.ts as the structural template. For each file: (1) Replace the entire contents with a copy of en.ts's structure; (2) Map existing translation strings from the broken file into the correct nested paths — e.g., 'appearance' block (lines 5-41) maps to settings.appearance, 'chat' block maps to composer + assistant.thread, 'about' block maps to settings.about, 'keys' block maps to settings.keys, 'config' block maps to settings.config, 'gateway' block maps to settings.gateway, 'sessions' block maps to settings.sessions, 'mcp' block maps to settings.mcp, 'tool' block maps to assistant.tool, 'pagination' maps to ui.pagination, 'previewConsole' maps to preview.console, 'nav' maps to sidebar.nav, 'terminal' maps to rightSidebar, 'clarify' maps to assistant.clarify, 'model'/'models' maps to settings.model/modelPicker/modelVisibility as appropriate; (3) Fix all bare arrow functions by adding proper property keys (e.g., 'count => ...' → 'updateReady: count => ...'); (4) Replace flat string values under settings (appearance/model/gateway/sessions/mcp/config/keys/about/tools) with the proper nested object structures; (5) Fill any new or missing keys with English fallbacks from en.ts (defineLocale handles this automatically for unmatched keys). The 11 files share identical structure, so fix one first and propagate the pattern.
Summary
Adds 11 new Desktop UI locales to the i18n framework that landed in NousResearch#38241, expanding language support from 4 to 15.
Each locale uses
defineLocale()with English fallback for any missing keys. All translations have been carried over from our earlier 15-language JSON catalog (the one in PR NousResearch#38846) and converted to the upstream TypeScript format.New locales
Changes
apps/desktop/src/i18n/types.ts: ExtendLocaletype union (4 → 15)apps/desktop/src/i18n/catalog.ts: Import and register all 11 new localesapps/desktop/src/i18n/languages.ts: AddLOCALE_OPTIONSentries,LOCALE_META, andLOCALE_ALIASESfor all new localesapps/desktop/src/i18n/{ko,de,es,fr,pt-br,ar,hi,th,vi,it,ru}.ts: Full translation catalogs usingdefineLocale()Notes
LOCALE_META(endonym shown in picker), not translation keysCloses the Russian Desktop locale gap noted in NousResearch#40347.
Related: NousResearch#38846 (superseded omnibus PR)
Mirror-of: NousResearch#56220
NousResearch#56220