Skip to content

Translations into 22 languages - #42

Merged
mbeczynski merged 4 commits into
mainfrom
feat/tlumaczenia
Nov 3, 2026
Merged

mbeczynski merged 4 commits into
mainfrom
feat/tlumaczenia

Conversation

@mbeczynski

Copy link
Copy Markdown
Contributor

The app, CLI output and notifications in the same 22 languages as the RenaCode games: ar, da, de, en, es, fi, fr, he, it, ja, ko, ms, nb, nl, pl, pt-BR, ru, sv, th, tr, zh-Hans, zh-Hant.

How

  • Kept the existing L10n.tr tables (English text as the key) instead of a String Catalog: the .app is assembled by cloudmachine-agent build-app from swift build output and the CLI under launchd uses the same strings, so a SwiftPM resource bundle with .lproj folders would be a new failure point in the release. English and Polish are unchanged.
  • 20 new tables, L10nTranslations+<code>.swift.
  • Language: the system's preferred languages, matched by Foundation like a localized app (zh-TW -> zh-Hant, pt-PT -> pt-BR, nn/no -> nb, [uk, pl] -> pl); English when nothing matches. CM_LANGUAGE goes through the same matching (de, de_DE, zh-Hant...).
  • Info.plist: CFBundleDevelopmentRegion + CFBundleLocalizations (22). SwiftUI scenes are right-to-left for ar/he.

Tests

  • L10nTests checks every key in every language: present and not empty; the same %@ (or a complete %1$@...%n$@); %% kept and no stray %; the same line breaks and indented lines; no control, bidi or zero-width characters; no Polish letters outside pl; no entry equal to the Polish text; at most 3% equal to English. Plus language detection, Info.plist vs the language list, and tests of the checks themselves.
  • Canaries: a German entry removed, a Japanese %@ changed to %d, a Polish word put into the German table. Each made the test fail with the right message.
  • swift-format lint --strict, swift build, swift test (318) pass locally.

Review

  • An independent spot check of de, fr, ja, ar (labels, warnings, data-safety texts) found term clashes and labels quoted differently than the buttons. Fixed in the second commit. All ja/ko positional placeholders were checked, and one fix followed.
  • Not proofread by native speakers. The other 16 languages only passed the automatic checks.

Limits

  • RTL: the menu-bar panel was rendered offscreen in Arabic and mirrors correctly. The dashboard sidebar moves to the right, but its scrolling content does not render offscreen, so it was not seen. The app was not launched, because start-up reloads the launchd agents of the running service.
  • The window frame and system menus follow the system language (CFBundleLocalizations), not CM_LANGUAGE.
  • Ages show the unit abbreviations min/h in every language, as before in Polish (BackupHealth.formatAge).
  • Counts arrive as text in %@ (no plural rules). Translations use wording that works for any number, such as "Files: %@".

Release

Merging to main changes mac-app/Sources/** and mac-app/Resources/**, so release.yml publishes a new patch version (DMG + cask). This PR also touches Info.plist, so the release workflow runs on the PR as well.

A branch merged later that adds L10n.tr keys (for example fix/rclone-start-timeout-2) must add them to all 22 tables, or L10nTests fails.

🤖 Generated with Claude Code

mbeczynski and others added 2 commits November 3, 2026 12:50
- L10n.Language: ar, da, de, en, es, fi, fr, he, it, ja, ko, ms, nb, nl,
  pl, pt-BR, ru, sv, th, tr, zh-Hans, zh-Hant. The language is matched
  against the system's preferred languages the way macOS does it
  (zh-TW -> zh-Hant, pt-PT -> pt-BR, a missing first choice falls through
  to the next one); English otherwise. CM_LANGUAGE takes any of the codes.
- English and Polish unchanged; the other 20 languages in
  L10nTranslations+<code>.swift, keyed by the English text like the
  Polish tables.
- Info.plist declares CFBundleLocalizations, so macOS picks the same
  language for its own parts; the SwiftUI scenes are right-to-left for
  Arabic and Hebrew.
- L10nTests check every key in every language: present, not empty, the
  same %@ placeholders (or a complete %1$@...%n$@ set), %% kept, no stray
  %, the same line breaks and indented lines, no control, bidi or
  zero-width characters, no Polish letters outside Polish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- CM_LANGUAGE goes through the same matching as the preferred languages,
  so pl-PL, de_DE, zh_Hant, pt and no work too; an unknown value leaves
  the system setting in charge.
- English is chosen only for an English preference: Foundation answers
  "en" when nothing matches, and that no longer stops the walk through
  the preferred languages.
- New test: no table may repeat the Polish text, and at most 3% of a
  table may equal the English key (names, units, words spelled alike).
- Proofreading de, fr, ja, ar: one term per role (buffer guard vs backup
  watchdog), button names quoted as their labels, "deleted" -> "gave up
  uploading" (ja), Apple's term for Full Disk Access (ar), counts as
  "Files: %@" in Arabic, imperatives in the French setup steps.
- ja/ko: all positional placeholders checked; the yes/no answer in
  "paused by the guard %@" now follows the question.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbeczynski
mbeczynski merged commit eaccf0f into main Nov 3, 2026
4 checks passed
@mbeczynski
mbeczynski deleted the feat/tlumaczenia branch November 3, 2026 12:39
mbeczynski added a commit that referenced this pull request Nov 4, 2026
The 58 vm-encrypt strings in the 20 languages added by #42, one table per
language (L10nTranslations+Encryption-<code>.swift) merged into the main
one, with each language's existing terms (Keychain, Full Disk Access, the
machine, the buffer guard). L10nTests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AU1Mhxpy65J75YYTkmt7NF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant