Skip to content

feat(i18n): add Russian (ru) locale to Hermes Desktop - #64929

Closed
saimon4eg wants to merge 5 commits into
NousResearch:mainfrom
saimon4eg:i18n/ru-only
Closed

feat(i18n): add Russian (ru) locale to Hermes Desktop#64929
saimon4eg wants to merge 5 commits into
NousResearch:mainfrom
saimon4eg:i18n/ru-only

Conversation

@saimon4eg

Copy link
Copy Markdown

Russian localization for Hermes Desktop

Uses the defineLocale() partial-locale pattern (same as ja.ts) — any missing keys fall back to English, so the locale stays healthy as upstream adds new keys.

What is included

  • Desktop locale (apps/desktop/src/i18n/ru.ts) — 2654 lines, all sections translated
  • Settings fieldsfieldLabels and fieldDescriptions populated via defineFieldCopy() (all config keys)
  • Web locale (web/src/i18n/ru.ts) — updated Russian translations
  • Registrationru in Locale type, catalog.ts, languages.ts, and locale aliases (ru, ru-ru, ru_ru)

What this fixes from the previous PR

  • fieldLabels and fieldDescriptions now populated (were empty {})
  • ✅ Uses defineLocale() partial pattern (was rigid Translations type — breaks on new upstream keys)
  • ✅ No install.sh changes — upstream URLs preserved
  • ✅ No ACP/IDE changes mixed in
  • ✅ No .idea/ files

Structure

apps/desktop/src/i18n/
├── ru.ts          ← new (defineLocale + defineFieldCopy)
├── types.ts       ← ru in Locale
├── catalog.ts     ← ru import + TRANSLATIONS entry
├── languages.ts   ← ru locale option + aliases

web/src/i18n/
└── ru.ts          ← updated

@alt-glitch alt-glitch added type/feature New feature or request comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Jul 15, 2026
@alt-glitch

alt-glitch commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Correction: this PR is not a duplicate. Its broad Desktop Russian locale and separate web translations have concrete scope/completeness differences from the ongoing #41677, #40701, and #50083 cluster. The maintainer sweep marked it keep_open; it remains related and needs a maintainer decision.

@saimon4eg

Copy link
Copy Markdown
Author

Why this PR should be the canonical ru-locale PR

Compared to #40701 (the earliest ru-PR marked as canonical by the triage bot), this PR is objectively more complete and closer to merge-ready:

#40701 #64929 (this)
Pattern defineLocale() defineLocale()
fieldLabels ❌ empty ✅ fully populated
fieldDescriptions ❌ empty ✅ fully populated
Translation keys 963 3,216 (3.3× more)
Web locale
settings.gateway (Cloud mode, 35+ keys)
settings.mcp (catalog, 22 keys)
skills.hub (browsing, 50+ keys)
commandCenter.maintenance (40 keys)
onboarding.fireworks
Bad aliases (be/uk/kk→ru) ✅ only ru/ru-ru/ru_ru

This PR is a superset: every key from #40701 is also present here, plus 2,200+ additional translations covering all upstream sections added since #40701 was opened.

Recent update

Just pushed a comprehensive update adding all 249 missing upstream keys (commandCenter, gateway Cloud, MCP, skills hub, updates, etc.). The locale now covers every section of the Hermes Desktop UI.

Merci!

saimon4eg and others added 4 commits July 15, 2026 17:06
- Add Russian desktop locale using defineLocale() partial pattern
- Populate fieldLabels and fieldDescriptions with Russian translations
- Register 'ru' in Locale type, catalog, language picker and aliases
- Update web Russian locale
Add 304 lines of Russian translations covering:
- assistant tool titles (browser_snapshot, browser_take_screenshot, session_search_recall)
- commandCenter maintenance, logs, sections
- composer snippets, attachUrl, queueStuckBody
- cron createDesc, editDesc, placeholders
- desktop handoff, branchStop, restart messages
- errors boundaryDesc
- messaging noTokenNeeded
- onboarding fireworks, openrouter, featuredPitch, flowSubtitles
- preview sourceLine, web restarting/reloading
- profiles createDesc, cloneFromDesc, editSoul, renameMenu
- prompts sudoDesc
- rightSidebar noProjectBody
- settings.appearance (embedsReset, toolView, translucency, uiScale)
- settings.gateway (Cloud mode — 35+ keys)
- settings.mcp (22 keys — catalog, status, testing, auth)
- settings.model (appliesDesc, auxiliaryDesc, fallbackAdd)
- settings.notifications (completionSound, testSent)
- settings.sessions (defaultDirUpdated)
- settings.toolsets (loadingModels, modelDefault, modelInUse)
- shell.statusbar (yoloOff, yoloOn)
- sidebar (allPinned, baseBranch, renameDesc, branchOff)
- skills (archive, bulkNoChange, disableAll, edit, hub — 50+ keys, provenance, sort, tabs)
- updates (applyStatus, stages, manualBody, unsupported)
A stray noTokenNeeded entry was spliced into the middle of the label
value in 676b7e0, producing a syntax error that broke vite build.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…application

Commit 676b7e0 mis-applied translation hunks, splicing inserted blocks
into the middle of existing lines throughout ru.ts. This broke the vite
build (multiple syntax errors) and left duplicated and lost keys.

- restore 13 cut lines (keys split mid-identifier or mid-string)
- remove all duplicated keys the splices introduced (26 pairs)
- re-add translations the splices swallowed: updates.stages entries,
  commandCenter maintenance keys, keybinds terminal/review/voice
  actions, settings.gateway cloud labels, settings.mcp server/tool
  toggles, settings.toolsets model labels, skills + hub strings
- restore missing closing paren of the defineLocale() call

ru.ts now parses cleanly, has zero duplicate keys, and matches en.ts
key structure exactly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Remove 'dismiss' from remoteDisplayBanner (not in type contract)
- Remove 'or' and 'escToCancel' from credentials (not in type contract)
- Remove 'tokensK' typo (only 'tokens' exists in type contract)
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for implementing the Desktop locale with the existing partial-locale pattern. Current origin/main still lacks ru in the Desktop catalog (apps/desktop/src/i18n/catalog.ts:7-12), locale union (apps/desktop/src/i18n/types.ts:8), and alias map (apps/desktop/src/i18n/languages.ts:42-68). The PR wires all of those paths and defines the locale with defineLocale() plus defineFieldCopy() (apps/desktop/src/i18n/ru.ts:1-4, :464-616).

Problems

  • No test file is changed. The existing resolver contract covers aliases, exact locale IDs, and config persistence in apps/desktop/src/i18n/languages.test.ts:6-42; add equivalent ru coverage so the new registration cannot silently regress.

Suggested changes

  • Test ru, ru-RU, and ru_ru normalization; test exact/support behavior and localeConfigValue('ru').
  • Add one runtime catalog assertion for a Russian translated string, following apps/desktop/src/i18n/runtime.test.ts:18-54.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
@alt-glitch alt-glitch added comp/dashboard Web dashboard / control panel UI (dashboard/, landing) needs-decision Awaiting maintainer decision before any implementation and removed sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades duplicate This issue or pull request already exists labels Jul 16, 2026
@antonbru

Copy link
Copy Markdown

Suggested tests for ru locale registration

Per @teknium1's review, here are the missing tests for apps/desktop/src/i18n/languages.test.ts.

Changes to the existing test suite

Additions to apps/desktop/src/i18n/languages.test.ts:

  1. normalizeLocale — Russian aliases (in the existing "normalizes supported locale aliases" test):
expect(normalizeLocale('ru')).toBe('ru')
expect(normalizeLocale('ru-RU')).toBe('ru')
expect(normalizeLocale('ru_ru')).toBe('ru')
  1. isSupportedLocaleValue / isLocale — Russian (in the existing "distinguishes exact locale ids" test):
expect(isSupportedLocaleValue('ru-RU')).toBe(true)
expect(isLocale('ru-RU')).toBe(false)
expect(isLocale('ru')).toBe(true)
  1. localeConfigValue — Russian (in the existing "returns the persisted config value" test):
expect(localeConfigValue('ru')).toBe('ru')
  1. New test: runtime catalog assertion — verifies the TRANSLATIONS['ru'] entry is wired through catalog.ts and produces actual translated strings:
import { TRANSLATIONS } from './catalog'

it('provides Russian translations for common keys', () => {
  const ru = TRANSLATIONS['ru']
  expect(ru.common.apply).toBe('Применить')
  expect(ru.common.cancel).toBe('Отмена')
  expect(ru.common.save).toBe('Сохранить')
  expect(ru.common.delete).toBe('Удалить')
  expect(ru.common.send).toBe('Отправить')
  expect(ru.common.close).toBe('Закрыть')
  expect(ru.common.loading).toBe('Загрузка...')
  expect(ru.common.error).toBe('Ошибка')
})

it('provides Russian translations for desktop-specific keys', () => {
  const ru = TRANSLATIONS['ru']
  expect(ru.boot.ready).toBe('Hermes Desktop готов')
  expect(ru.desktop.createSessionFailed).toBe('Не удалось создать сессию')
  expect(ru.desktop.promptFailed).toBe('Не удалось отправить запрос')
})

Happy to open a PR against this branch if that makes it easier to land the review feedback.

@teknium1 teknium1 added the area/i18n Localization, locales, translations label Jul 19, 2026
@saimon4eg

Copy link
Copy Markdown
Author

Superseded by #70673 — clean rebase on fresh upstream main.

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

Labels

area/i18n Localization, locales, translations comp/dashboard Web dashboard / control panel UI (dashboard/, landing) comp/desktop Electron desktop app (apps/desktop/*) needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants