Skip to content

feat(i18n): add Turkish (tr) locale - #11577

Closed
ByEzel93 wants to merge 2 commits into
stablyai:mainfrom
ByEzel93:feat/add-turkish-language
Closed

ByEzel93 wants to merge 2 commits into
stablyai:mainfrom
ByEzel93:feat/add-turkish-language

Conversation

@ByEzel93

Copy link
Copy Markdown

Summary

Adds complete Turkish (tr) language support. Users can now pick Türkçe in Settings → Appearance → Language, and find that setting by searching either Language or Dil from any interface locale.

All 11,728 localization keys are translated. verify:localization-catalog reports tr.json coverage: 11728/11728 translated, 0 missing, which makes it the only fully covered non-English catalog today (es/ja/ko/zh are each at 11691/11728).

New files

  • src/renderer/src/i18n/locales/tr.json — full Turkish catalog
  • docs/readme/README.tr.md — Turkish README

Locale registration

  • src/shared/ui-language.ts — UI_LANGUAGE_TURKISH, union member, values set
  • src/shared/ui-locale.ts — tr in SUPPORTED_UI_LOCALES + language→locale resolution
  • src/renderer/src/i18n/supported-languages.ts — selector entry with Türkçe fallback label
  • src/renderer/src/i18n/i18n.ts + src/main/i18n/main-i18n.ts — lazy loader entries for renderer and main process
  • src/renderer/src/components/settings/appearance-search.ts — Türkçe plus the native Dil search keyword
  • en/es/ja/ko/zh.json — added only the settings.appearance.language.turkish label so Turkish appears in every locale's selector. No existing translations were modified.
  • config/localization-coverage-allowlist.json — records the Dil keyword, mirroring the existing Idioma entry

Docs — Türkçe linked from the main README and all six translated READMEs, following the existing pattern where each README lists every language but its own.

Translation notes

Brand names, CLI commands, flags, file paths, code identifiers, CSS class strings, and test IDs are deliberately left in English.

One thing worth flagging: the key extractor sweeps some non-UI strings into the catalog, and the existing es/ja catalogs translated them — producing entries like 'mac' → 'impermeable' (raincoat), 'slug' → 'ナメクジ' (the animal), and 'text-foreground' → 'texto-primer plano' (a CSS class). The Turkish catalog does not carry those over. Happy to open a separate issue for the other locales if that would help.

Placeholder parity ({{value0}}, {{count}}, named variables) was verified programmatically across all 11,728 keys — zero mismatches.

Screenshots

No visual change — no layout, component, or styling changes. The only user-visible difference is the new "Türkçe" entry in the language selector, and Turkish strings once it is selected.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or explained why tests were not needed

Extended the existing locale tests to cover tr: main-i18n-lazy-locale, lazy-locale, locale-english-regression, native-chat-locales, smart-workspace-jira-locales, ui-language, ui-locale, osc52-clipboard-copy, osc52-clipboard-toast. These are the tests that would catch a missing loader registration or an untranslated catalog, which are the realistic regressions for this change.

All three localization verifiers pass: verify:localization-catalog (11728/11728), verify:localization-coverage, verify:localization-extraction.

Full suite: 41,472 passed. Five unrelated tests are flaky locally (WSL hook relay, relay agent-exec, electron-vite dev startup) — a different subset failed on each run and none touch i18n, so I left them alone.

One test contract was relaxed, deliberately: native-chat-locales.test.ts asserted that composer.model differs from English in every locale. "Model" is spelled identically in Turkish, so that key moved into the existing non-empty-only group next to the on/off loanword exception, with a comment explaining why. Every other assertion in that test is unchanged. Happy to revert and translate the key differently if you'd rather keep the contract strict.

AI Review Report

Reviewed with Claude Code. Risks checked and findings:

  • Cross-platform (macOS / Linux / Windows): No platform-specific code paths, keyboard shortcut logic, path handling, shell invocation, or Electron platform branching is touched — this is a data catalog plus registry entries. Verified that Turkish strings for existing shortcut labels leave the ⌘/⇧ vs Ctrl+/Shift+ placeholders and their surrounding markup intact, so per-platform label rendering is unaffected.
  • SSH / remote / local: The catalog is bundled and lazy-imported the same way in both renderer and main. The main-process loader was registered alongside the renderer one, so remote and SSH sessions resolve tr identically to local ones. No filesystem, process, credential, or network assumptions were added.
  • Agents & integrations: No agent, provider, or integration logic changed. Provider-neutral review vocabulary is preserved — pull request/merge request/PR/MR and the GitHub/GitLab/Jira/Linear product names are left untranslated so GitHub-specific wording does not leak into GitLab or other provider surfaces.
  • Git providers: No git command, capability probe, or provider branching touched.
  • Performance: Catalogs are lazy-loaded per locale, so tr.json is only fetched when Turkish is active — zero cost for everyone else. No new modules, imports, or work on any hot path.
  • UI quality: No styling changes. Turkish runs longer than English, so button and menu labels were kept short to avoid truncation in narrow surfaces such as the status bar and sidebar.

Flagged and fixed during review: a handful of half-translated strings left mid-sentence in English (e.g. "Bir project so we can authenticate to GitLab seçin."), and several inconsistencies where the same English string had been rendered two different ways. Both classes were found by scripted audits over the catalog and corrected.

Security Audit

No new inputs, IPC channels, command execution, path handling, auth flows, secrets, or dependencies. The change is inert translation data rendered through the existing i18next pipeline, which escapes interpolation by default, so the added strings cannot introduce injection. Interpolation placeholders were verified to match English exactly across all keys, so no format string can silently drop or invent a variable. No follow-up needed.

Notes

  • No platform-specific behavior in this PR.
  • Turkish plural handling follows the convention already used by the es/ja/ko/zh catalogs for the auto-extracted plural-suffix keys.
  • If maintainers prefer the extractor's non-UI strings (CSS classes, test IDs, code identifiers) to be translated for consistency with es/ja, say the word and I will align — I left them in English on purpose, since translating them is what produced the incorrect entries noted above.

X (Twitter): https://x.com/ezelphp

Add complete Turkish translations for all 11,728 localization keys and
register `tr` across the renderer and main-process locale loaders.

- New catalog `src/renderer/src/i18n/locales/tr.json` (100% coverage)
- Register `tr` in ui-language, ui-locale, and both lazy locale loaders
- Show "Türkçe" in the language selector and settings search
- Add `docs/readme/README.tr.md` and link it from every README language row
- Extend locale tests to cover `tr`

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ByEzel93
ByEzel93 requested a review from brennanb2025 as a code owner July 30, 2026 15:11
Comment thread src/renderer/src/i18n/locales/tr.json Outdated
"8d1e160ed1": "Kenar çubuğunu yeniden deneyin veya bu yüzeyi yeniden yüklemek için sekme değiştirin.",
"ed6b168d00": "Sağ kenar çubuğu bir hatayla karşılaştı.",
"03a14f6b5b": "Sayfayı yeniden deneyin veya başka bir Orca yüzeyine gidin.",
"b7a714db1e": "This page bir hatayla karşılaştı.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 The phrase "This page" was not translated — only "bir hatayla karşılaştı." is in Turkish. Every sibling key in this error-boundary block is fully in Turkish (e.g. "Orca'da bir renderer hatası oluştu.", "Durum çubuğu bir hatayla karşılaştı."), so this mixed string will render the English prefix verbatim to Turkish-speaking users when this page-level error fires. The English source (b7a714db1e) is "This page hit an error."

Suggested change
"b7a714db1e": "This page bir hatayla karşılaştı.",
"b7a714db1e": "Bu sayfa bir hatayla karşılaştı.",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed. I also swept the catalog for the same pattern and found 42 more cases where a Turkish sentence frame wrapped untranslated English (mostly "No X found" → "Hiçbir checks bulunamadı"). All 43 are corrected in the follow-up commit.

@greptile-apps

greptile-apps Bot commented Jul 30, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR adds complete Turkish (tr) locale support across all 11,728 i18n keys, making it the first non-English catalog with full coverage. Registration is wired correctly in both the renderer and main-process lazy loaders, the locale constants, the settings search index, and the language selector.

  • tr.json — 11,728 keys translated with zero placeholder mismatches against en.json; technical strings (CSS classes, CLI commands, code identifiers) are correctly left in English.
  • Registration — ui-language.ts, ui-locale.ts, i18n.ts, main-i18n.ts, supported-languages.ts, and appearance-search.ts each receive the minimum one-line addition that mirrors the existing locale pattern.
  • Tests — All locale-level test suites (lazy-locale, main-i18n-lazy-locale, native-chat-locales, osc52-clipboard-*, ui-language, ui-locale, smart-workspace-jira-locales) are extended to cover tr; the native-chat-locales composer.model assertion is intentionally relaxed to non-empty because "Model" is a Turkish loanword.

Confidence Score: 5/5

Safe to merge — this is a data catalog addition with no logic, UI layout, or platform-specific changes.

All 11,728 keys are present and covered, placeholder parity with English is verified, both the renderer and main-process loaders are registered, and every relevant locale test suite is extended to include tr. The only deliberate contract change (the composer.model non-empty assertion) is clearly justified and documented inline.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
src/renderer/src/i18n/locales/tr.json New 11,728-key Turkish catalog; all placeholders match English exactly, no untranslated sentences found, technical strings (CSS, CLI commands) correctly left in English
src/shared/ui-language.ts Adds UI_LANGUAGE_TURKISH constant, BuiltInUiLanguage union member, and set entry — mirrors the existing pattern for all other locales
src/shared/ui-locale.ts Adds 'tr' to SUPPORTED_UI_LOCALES and a resolveUiLocale branch for UI_LANGUAGE_TURKISH; pattern is consistent with existing locale branches
src/renderer/src/i18n/i18n.ts Adds lazy loader for tr.json in the renderer; single-line addition consistent with other locale loaders
src/main/i18n/main-i18n.ts Adds lazy loader for tr.json in the main process; ensures Turkish resolves identically in SSH/remote sessions
src/renderer/src/i18n/supported-languages.ts Adds Turkish to UI_LANGUAGE_CHOICES and UI_LANGUAGE_CHOICE_FALLBACKS with correct 'Türkçe' label
src/renderer/src/components/settings/appearance-search.ts Adds Turkish search keyword 'Türkçe' and native 'Dil' search term so Turkish speakers can find the language setting from any locale
src/renderer/src/i18n/native-chat-locales.test.ts Deliberately relaxes the composer.model assertion to non-empty (from differs-from-English) because 'Model' is a loanword in Turkish; documented with an inline comment
config/localization-coverage-allowlist.json Records the native 'Dil' keyword following the existing 'Idioma' pattern; no other changes

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User selects Turkish\nin Settings → Appearance] --> B{resolveUiLocale}
    B -->|UI_LANGUAGE_TURKISH| C[returns 'tr']
    C --> D[Renderer lazy loader\ni18n.ts]
    C --> E[Main-process lazy loader\nmain-i18n.ts]
    D --> F[tr.json catalog\n11728 keys]
    E --> F
    F --> G[i18next pipeline\nauto-escapes interpolation]
    G --> H[Turkish UI rendered]

    I[Search: 'Dil' or 'Türkçe'\nin Settings search] --> J[appearance-search.ts\ntranslateSearchKeyword]
    J --> A
Loading

Reviews (2): Last reviewed commit: "fix(i18n): translate remaining half-tran..." | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • src/renderer/src/i18n/locales/tr.json
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a6aebe1b-013e-4357-b799-c70ef37b2ae8

📥 Commits

Reviewing files that changed from the base of the PR and between 0158828 and 25766c5.

📒 Files selected for processing (1)
  • src/renderer/src/i18n/locales/tr.json

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Turkish as a supported UI language with shared normalization and locale-resolution handling. Turkish translations are added to language labels and lazy-loading maps, with language-search keywords and localization coverage configuration updated. Main and renderer tests now validate Turkish loading, translations, and localized feature copy. Documentation adds a complete Turkish README and updates language-selector links across existing README files.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely states the main change: adding Turkish locale support.
Description check ✅ Passed All required sections are present and filled with relevant details, including screenshots, testing, review, security, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Fix 43 entries where a Turkish sentence frame was left wrapping untranslated
English, mostly the "No X found" pattern rendering as "Hiçbir checks bulunamadı".

Includes the `This page hit an error.` case flagged in review.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@AmethystLiang

Copy link
Copy Markdown
Contributor

thanks for the PR. would love to add Turkish support. we're doing some workflow improvements on how we can maintain multi-language translation going forward, and will land the PR once our new workflow lands

@ByEzel93

Copy link
Copy Markdown
Author

thanks for the PR. would love to add Turkish support. we're doing some workflow improvements on how we can maintain multi-language translation going forward, and will land the PR once our new workflow lands

Thanks for the update, Glad to hear Turkish support will be added. Looking forward to the new translation workflow. Feel free to let me know if any changes are needed on my side. Thanks

@nwparker

nwparker commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Thank you for putting this together — and I am sorry it sat unanswered for so long, which is on us, not you.

We are not taking on new UI locales right now. Orca ships en/es/ja/ko/zh, and each one carries ongoing cost beyond the initial catalog: every new English string has to be re-translated, the build-time repair policy needs per-locale glossary and override rules, and mistranslations reach users in surfaces nobody on the team can read. We are currently working through a backlog of correctness bugs in the five we already ship, and adding a sixth before that is under control would not be fair to the people using it.

That is a decision about our capacity, not about the quality of your work. Closing so the queue reflects reality rather than leaving it open indefinitely — if that changes, this is easy to reopen and we will come back to the contributors who offered first.

Thanks again for the time you put in.

@nwparker nwparker closed this Aug 4, 2026
@nwparker

nwparker commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

I'm sorry — I closed this, and that was the wrong call. Reopening it.

The reasoning I gave (that we aren't taking on new built-in locales right now) is still true, but closing your PR was not the right way to act on it. You did the work, it sat for months without a reply, and then it got closed with an explanation of our constraints. That's a bad trade for you, and I apologize.

Here's what's actually going on. We do want these locales. What we can't currently take on is maintaining them in-tree, where every new English string becomes translation debt across every catalog and a mistranslation ships to users in a surface nobody on the team can read. So the direction we're working toward is the one where that maintenance sits with the people who actually speak the language: plugin language packs.

Most of that mechanism is already in the repo today:

  • a plugin manifest declares contributes.languagePacks: [{ locale, path }]
  • the pack is a plain catalog JSON with the same key shape as src/renderer/src/i18n/locales/en.json
  • packs are content-integrity verified and approval-gated at install, then registered into i18next at runtime
  • they appear in Settings → Appearance → Language next to the built-in locales
  • Intl formatting — dates, relative times, number formats — resolves through the locale tag the pack declares

The test fixture for that manifest contract uses pt-BR as its worked example, so this isn't hypothetical plumbing.

What's not there yet is the part that would make this pleasant for you: there's no authoring guide, no scaffolding to generate a starter catalog from en.json, no re-sync story when English strings change, and the glossary/repair tooling we use for the built-in locales isn't exposed to pack authors. That's the work in front of us. I'm not going to give you a date I can't keep.

I'd rather leave this open and come back to you when that lands than close it and have you find out from a changelog. If you'd prefer to close it yourself in the meantime, that's entirely your call — but it should be yours, not mine.

Thanks for the work, and sorry again for how I handled it.

@ByEzel93

ByEzel93 commented Aug 4, 2026

Copy link
Copy Markdown
Author

I'm sorry — I closed this, and that was the wrong call. Reopening it.

The reasoning I gave (that we aren't taking on new built-in locales right now) is still true, but closing your PR was not the right way to act on it. You did the work, it sat for months without a reply, and then it got closed with an explanation of our constraints. That's a bad trade for you, and I apologize.

Here's what's actually going on. We do want these locales. What we can't currently take on is maintaining them in-tree, where every new English string becomes translation debt across every catalog and a mistranslation ships to users in a surface nobody on the team can read. So the direction we're working toward is the one where that maintenance sits with the people who actually speak the language: plugin language packs.

Most of that mechanism is already in the repo today:

  • a plugin manifest declares contributes.languagePacks: [{ locale, path }]
  • the pack is a plain catalog JSON with the same key shape as src/renderer/src/i18n/locales/en.json
  • packs are content-integrity verified and approval-gated at install, then registered into i18next at runtime
  • they appear in Settings → Appearance → Language next to the built-in locales
  • Intl formatting — dates, relative times, number formats — resolves through the locale tag the pack declares

The test fixture for that manifest contract uses pt-BR as its worked example, so this isn't hypothetical plumbing.

What's not there yet is the part that would make this pleasant for you: there's no authoring guide, no scaffolding to generate a starter catalog from en.json, no re-sync story when English strings change, and the glossary/repair tooling we use for the built-in locales isn't exposed to pack authors. That's the work in front of us. I'm not going to give you a date I can't keep.

I'd rather leave this open and come back to you when that lands than close it and have you find out from a changelog. If you'd prefer to close it yourself in the meantime, that's entirely your call — but it should be yours, not mine.

Thanks for the work, and sorry again for how I handled it.

Thank you so much for taking the time to explain everything so clearly, and especially for reopening the PR. I genuinely appreciate it.

I also really appreciate the way you handled this. Your message was incredibly thoughtful, kind, and respectful, and honestly, there was no need to apologize — I completely understand the reasoning and the maintenance concerns behind the decision.

The plugin-based language pack approach makes a lot of sense to me, and I’m more than happy to support that direction.

Whenever the necessary tooling or documentation is ready, please feel free to reach out. I’m ready to do whatever is needed on my side to help bring Turkish support to Orca — whether that’s adapting the existing translation into a language pack, keeping it in sync, testing it, reviewing translations, or helping with anything else related to the Turkish locale.

Thank you again for your kindness, transparency, and for taking the time to reconsider the PR. I really appreciate it, and I’ll be happy to contribute whenever you’re ready.

@berkaysirtas

Copy link
Copy Markdown

For anyone who lands here wanting Turkish today: there is now a community language-pack plugin on the mechanism the maintainers described above, no app patching:

Repo: https://github.com/berkaysirtas/orca-turkish

Install: Settings → Plugins → Install plugin → Git URL → https://github.com/berkaysirtas/orca-turkish.git#v0.2.0, then Settings → Appearance → Language → Türkçe.

It is early (215 keys: menus, tray, language and status-bar settings, worktree palette, agent dashboard, recovery screens) and grows per release. The catalog is generated and validated with the scaffold tool proposed in #20513, so protected keys, placeholder parity and catalog limits are checked before every tag. Happy to fold in the strings from this PR with credit if @ByEzel93 is up for it.

@OrcaWin

OrcaWin commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

Thank you for this! Turkish (Türkçe) is now a built-in UI language as of #34718, so I'm closing this in its favor. If you spot wording that reads wrong, a follow-up PR against src/renderer/src/i18n/locales/tr.json (glossary in config/i18n-turkish.md) would be very welcome.

@OrcaWin OrcaWin closed this Oct 28, 2026
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.

6 participants