feat(i18n): complete the Russian translation for 0.10.1 - #317
xJaroslav69 wants to merge 21 commits into
Conversation
… dictation and record (batch 2a)
…ninstall, debloat and voice studio tools (batch 2b)
…ng, usage, sponsorblock, frames and document tools (batch 2c)
|
Verified rather than trusted, and every claim in the description holds up. This is the most carefully prepared locale PR this repo has received. What I checked against
I also diffed the HTML tags inside values: 0 divergences. That is the failure mode that quietly breaks rendering, and it is clean. The contrast worth naming: a locale PR was closed here recently because the file was ~95% English under a translated label. Yours is the inverse — 2,271 strings actually moved into Russian, the plural forms follow the genitive convention rather than the «2 инструмента» calque, and you left brands and codecs alone instead of transliterating them. That is the judgement part, and it is the part a script cannot check. One thing before I merge, and it is on my side, not yours. A batch of new keys for the next release is currently in flight, which means But the merge order matters, because both rewrite the same file. I want to sequence this so that your 2,271 strings cannot be lost to a bad conflict resolution. I will handle that and merge — nothing for you to do, and please do not rebase preemptively, since that would just move the problem. The Weblate link in the README being dead is a real catch, thank you. Leave the README to me; it was rewritten for 0.9.1 and I would rather keep it in one hand. |
| "scope_channel": "Этот канал", | ||
| "scope_guild": "Весь сервер", | ||
| "run": "Найти", | ||
| "filters_hint": "Фильтры: от:имя · содержит:файл|изображение|ссылка · до:2026-01-31 · после:2026-01-01", |
There was a problem hiding this comment.
Localized filters silently fail
The hint now tells Russian users to enter от:, содержит:, до:, and после:, but the search parser only recognizes from:, has:, before:, and after: with the English values file, image, and link. Following the localized hint therefore treats the filters as ordinary search words, so the requested filtering silently fails.
| "filters_hint": "Фильтры: от:имя · содержит:файл|изображение|ссылка · до:2026-01-31 · после:2026-01-01", | |
| "filters_hint": "Фильтры: from:name · has:file|image|link · before:2026-01-31 · after:2026-01-01", |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/i18n/ru.json
Line: 6521
Comment:
**Localized filters silently fail**
The hint now tells Russian users to enter `от:`, `содержит:`, `до:`, and `после:`, but the search parser only recognizes `from:`, `has:`, `before:`, and `after:` with the English values `file`, `image`, and `link`. Following the localized hint therefore treats the filters as ordinary search words, so the requested filtering silently fails.
```suggestion
"filters_hint": "Фильтры: from:name · has:file|image|link · before:2026-01-31 · after:2026-01-01",
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.The hint told Russian users to type `от:`, `содержит:`, `до:` and `после:`, but SearchPanel only parses `from:`, `has:`, `before:` and `after:` (with the values `file`, `image`, `link`). The localized operators were pushed into the free-text query instead, so the filters silently did nothing while the hint said they worked. Keep the operators in English and translate only the "Filters:" prefix, matching every other locale, which left this hint untranslated.
|
Thanks for the review — the filter finding was a real bug, and a nasty one because it failed silently. What was wrong. Fixed in 6a272f9 by keeping the operators in English and translating only the Verified: |
tonhowtf
left a comment
There was a problem hiding this comment.
Checked key by key against main: this is not a blind rewrite — only 6 already-translated strings change (the stale ones you list), 3,844 translated keys are untouched, and 6a272f9a keeps the OmniDisc search operators in English. Good work.
It conflicts with main because 0.9.2 added 957 keys (48 new tools) that this branch doesn't have. Please rebase, run node scripts/sync-locales.mjs, and either translate the new keys or leave them as the English fallback the script fills in — both are fine. Then it merges.
# Conflicts: # src/lib/i18n/ru.json
|
Updated to 0.9.2 — thanks for the pointer. What changed
Two notes:
Unrelated heads-up
|
`main` ships `lo.json` without `settings.download.download_attachments_desc`, so `pnpm check:i18n` aborts with `[lo.json] missing: 1` on every branch, this one included — that is what the three red checks were (frontend and both smoke jobs). `sync-locales.mjs` fills a missing key with the English value, which is what it does here: one key, English fallback, no behaviour change. Translating it properly is left to a Lao speaker. Not strictly part of the Russian translation, but the locale gate cannot pass for this PR — or for `main` — until that key exists.
|
One extra file, and here is why.
I know this PR was supposed to stay on |
|
Re-checked against
The review point is resolved and this is approved in substance. It conflicts again for the same reason as last time, and that one is on me: 0.10.0 shipped while this was open and added 829 new keys (the agents/LLM section). Sorry for making you chase To finish: merge Please let #318 land first since both touch |
upstream 0.10.0 changed the English source of three keys the Russian file
had already translated, so the translations still carried the old tokens:
- study.music.albums_count: {{count}} -> {{n}}
- study.read.page_of: {{current}} -> {{cur}}
- study.library.roots: "Library roots" -> "Roots"
Without this the UI would render a literal {{count}} / {{current}}.
Verified: 0 placeholder divergences, 0 HTML-tag divergences against en.json.
Completes ru.json for 0.10.0: 9,192 / 9,192 keys, 0 missing, 0 extra,
0 placeholder divergences and 0 HTML-tag divergences (both `{{double}}`
and `{single}` styles), 97.9% of values Cyrillic.
Covers the sections the release introduced: agents/LLM (accounts, jobs,
loops, prune, rules, workspace, models, MCP, skills, observatory, limits
strip, wire probe, quota), the World (house, yard, activity, settings,
HUD), pet/omni, profile, onboarding, and the new Anki, notes, music,
player, read and Telegram surfaces.
Terminology follows the accepted 0.9.x translation and the repo's plural
convention: counters read "Род. падеж: {{count}}" («Инструментов: {{count}}»),
`_one` keys keep the singular form.
Verified:
node scripts/generate-i18n-keys.js --strict -> 9,192 keys, all 11 locales in sync
node scripts/sync-locales.mjs --check -> ru.json: +0 missing, -0 stale
placeholder / HTML-tag parity lint -> 0 divergences
|
Updated to 0.10.0 — CI is 8/8 green and the PR is mergeable again. This one can go right behind #318, as you suggested.
One unrelated heads-up, since it costs every Windows checkout a test file: with |
…tale ones
Brings ru.json to 0.10.1: 9,260 / 9,260 keys, 0 missing, 0 extra,
0 placeholder divergences, 0 HTML-tag divergences, 97.9% Cyrillic.
New in 0.10.1 and translated here: the workspace hub (Chat, Agents,
Activity, Configure, Tasks, Routines, usage and performance, the limits
strip monitor), the appearance section (design.*), job filters, loop
summaries, observatory states, skill actions, model-provider hints and
the Help entry point.
Seven strings whose English source changed in 0.10.1 follow the new
wording: home.hero_title, llm.tab.roster / llm.roster.title ("Agent
team" -> «Команда агентов»), llm.conv.empty_title, llm.conv.empty_body,
llm.mcp.reg_install ("Configure" -> «Настроить») and
llm.mcp.reg_reinstall ("Reconfigure" -> «Перенастроить»).
Terminology kept in step with the accepted translation: appearance is
«внешний вид» (as in settings.appearance.title), and the Routines entry
of the workspace navigation reads «Циклы», the name of the page it opens.
Verified:
node scripts/generate-i18n-keys.js --strict -> 9,260 keys, all 11 locales in sync
node scripts/sync-locales.mjs --check -> ru.json: +0 missing, -0 stale
placeholder / HTML-tag parity lint -> 0 divergences
|
Updated to 0.10.1 — CI is green and the PR is mergeable again. This one can go right behind #318.
Two small things you may want to pick up while this sits in the queue:
|
"от:", "содержит:", "до:" and "после:" are not words to translate: the search parser only knows `from:`, `has:`, `before:` and `after:` with the English values `file`, `image` and `link`. A Russian user following the localized hint therefore gets the filters treated as ordinary search words and the filtering silently does nothing. Every other locale keeps those tokens in English for the same reason.
|
#318 is merged, so this one is next — and, as predicted, it conflicts again, but only in one hunk: the last object of Resolution: merge "tray": {
"quit": "Выход",
"downloads_none": "Нет активных загрузок",
"downloads_active": "Активных загрузок: {{count}}",
"tooltip_active": "OmniGet — активных: {{count}}",
"tooltip_speed": "OmniGet — активных: {{count}} · {{speed}}"
}Then |
ru.json was the only conflict, in two positional hunks: - downloads.* — kept this branch's Russian values and took main's new downloads.status_bar.* block (already Russian on main); - design.* — kept this branch's Russian values and appended main's Russian tray block that landed with tonhowtf#318. The other 17 keys main added since 0.10.1 (status_bar, tray, telegram, remove_saved_dir) came in already translated.
Found while re-reading the whole file after the merge: - onboarding.agents_desc held an older English sentence verbatim — it now translates the current source, including the three starter agents and the LLM > Roster breadcrumb; - tools.common.file was "File" although it shows up as a tab label, a row label and a section heading; - downloads.history_empty and settings.advanced.concurrent_fragments_desc kept only the first half of the English text. check:i18n --strict: 9,279 keys, 11 locales in sync; 0 placeholder and 0 HTML-tag divergences; keys.ts untouched.
1k / 5k / 10k rather than 1000 / 5000 / 10000: the badges and the progress list are narrow, and a four-digit number is more likely to wrap. Matches the English source, which already writes "1k XP" and "10k XP".
|
Updated — everything you asked for is in, and CI is green on the head commit. The conflict, resolved exactly as you described: kept this branch's side for the Four values were still in English — I found them re-reading the file after the merge, and they are fixed in a separate commit so the resolution stays readable:
XP thresholds stay shortened:
Two follow-ups, both as separate PRs — nothing for you to do now:
|
What
Brings
src/lib/i18n/ru.jsonto the currentmain(0.10.1): 9,260 / 9,260 keys — 0 missing, 0 extra, values-only,keys.tsuntouched, the diff is one file.upstream/main(0.10.1) and resolvedru.jsonin favour of this PR's side, as you asked.design.*), job filters, loop summaries, observatory states, skill actions, model-provider hints and the Help entry point.home.hero_title→ «Что хотите скачать?»,llm.tab.roster/llm.roster.title("Agent team") → «Команда агентов»,llm.conv.empty_title/llm.conv.empty_body,llm.mcp.reg_install("Configure") → «Настроить»,llm.mcp.reg_reinstall("Reconfigure") → «Перенастроить».Basic/Cloze, protocol and field tokens (stdio,HTTP,URL,Id,LLM,CLI), the Lao endonymລາວ,XP/FPS/CPUlabels and two strings that are placeholders only.lo.jsonline stays gone —mainhas that key now.Three stale strings fixed earlier in this branch
study.music.albums_count{{count}} albums{{n}} album(s)Альбомов: {{n}}study.read.page_of{{current}} of {{total}}p. {{cur}}/{{total}}стр. {{cur}}/{{total}}study.library.rootsLibrary rootsRootsКорниTerminology
Kept in step with the accepted translation and the interface: appearance is «внешний вид» (as in
settings.appearance.title), the Routines entry of the workspace navigation reads «Циклы» — the name of the page it opens — and counters follow the repo convention («Род. падеж: {{count}}»,_onekeys keep the singular).Checks
Diff:
src/lib/i18n/ru.jsononly — 5,253 insertions / 5,253 deletions.Notes for maintainers
core.autocrlf=true,scripts/world-bench.mjsarrives with CRLF and vitest cannot transformsrc/lib/world/bench/compare.test.ts(29 tests never run), andsrc/lib/stores/limits-monitor.test.tsstrips imports with/^import .*;\n/gm, which never matches\r\n, so the child process dies with "Identifier 'invoke' has already been declared". Both are one-line regex/eol fixes.