Repository navigation
feat(i18n): add Turkish (tr) UI locale and README - #7039
Conversation
Tiny Sweeper reviewTiny Sweeper completed its review; deterministic results follow. State: Incomplete Review snapshot
Completeness: Incomplete What changedNo supported behavioral explanation was produced. Features
Tests
Findings
Resolved this pass
Pending checks: Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS) Could not review: app/src/lib/i18n/tr.ts Before merge
How this fits togetherflowchart LR
n0["LocaleOption<br/>changed<br/>2 findings"]:::blocking
n1["Locale<br/>changed<br/>1 finding"]:::flagged
n2["exit"]:::impacted
n3["parseArgs"]:::impacted
n4["parseArgs"]:::impacted
n0 -->|uses| n1
n3 -->|calls| n2
n4 -->|calls| n2
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review. 📝 WalkthroughWalkthroughThe application now supports Turkish translations and locale selection. Translation scripts process Turkish, and README files include a Turkish translation and updated language links. Three vendor subproject references also changed. ChangesTurkish Locale Support
Vendor Subproject References
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant LanguageSelect
participant localeSlice
participant I18nContext
participant Document
LanguageSelect->>localeSlice: Select Turkish locale
localeSlice->>I18nContext: Provide current locale
I18nContext->>Document: Set language and direction
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The Turkish README links work, and no issue identified in the reviewed changes needs to be fixed before merging. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The Turkish locale follows the existing presentation and language-selection design, with no identified new authorization or execution path. However, three bundled dependency updates remain unresolved, so the PR cannot be assessed as localization-only or minimal risk. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 15 files. (2 skipped: 2 unsupported.)
A rabbit taps “Türkçe” with care, Comment |
Add a full Turkish translation of all 4,592 English keys using formal address, register it in the locale type, provider, picker and browser language detection, and include tr in the i18n coverage, English-leftover and apply scripts. Tests cover picker selection, Turkish detection for tr/tr-TR, provider lang/dir, and exact placeholder parity against English.
Translate the current root README into docs/README.tr.md and link it from the language bar of the root README and every translated README.
There was a problem hiding this comment.
Requesting changes: 1 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0058 · 490,103 in / 22,961 out · 50,769 cached (10%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0036 · 291,899 in / 15,426 out · 36,491 cached (13%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0013 · 108,564 in / 4,295 out · 14,278 cached (13%) · gpt-5.6-luna
tests: $0.0001 · 16,177 in / 138 out · 0 cached (0%) · glm-5.3-flash
description: $0.0002 · 16,740 in / 114 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0004 · 41,025 in / 430 out · 0 cached (0%) · glm-5.3-flash
899d242 to
16f31ea
Compare
can, not and may are in the shared English function-word list but are
also ordinary Turkish words ("Not: ..." is a common note prefix), so a
Turkish value carrying two of them was reported as English and failed
i18n:english:check. Ignore per-locale shared words for tr, and run main()
only when invoked as a CLI so looksEnglish can be unit tested.
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0020 · 190,172 in / 10,115 out · 24,880 cached (13%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0006 · 52,877 in / 4,172 out · 6,086 cached (12%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0005 · 38,854 in / 2,902 out · 5,354 cached (14%) · gpt-5.6-luna
tests: $0.0002 · 18,007 in / 140 out · 0 cached (0%) · glm-5.3-flash
description: $0.0002 · 18,555 in / 115 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0003 · 43,678 in / 426 out · 13,440 cached (31%) · glm-5.3-flash
Checking the whole ENGLISH_FN list against Turkish also finds must (grape must), has (pure), had (limit) and don (frost), so add them to the tr shared-word set alongside can, not and may. Keep "and" (oath): it is archaic in UI copy and the strongest English signal.
There was a problem hiding this comment.
Requesting changes: 1 lane(s) blocking, worst finding is low.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0021 · 197,883 in / 9,569 out · 32,321 cached (16%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0007 · 64,043 in / 2,934 out · 11,739 cached (18%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0005 · 35,525 in / 2,701 out · 7,142 cached (20%) · gpt-5.6-luna
tests: $0.0003 · 37,297 in / 1,019 out · 13,440 cached (36%) · glm-5.3-flash
description: $0.0002 · 18,714 in / 152 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0002 · 21,692 in / 190 out · 0 cached (0%) · glm-5.3-flash
Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0226 · 498,859 in / 28,191 out · 46,824 cached (9%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0136 · 266,693 in / 12,801 out · 24,361 cached (9%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0082 · 131,064 in / 11,139 out · 16,063 cached (12%) · gpt-5.6-luna
tests: $0.0001 · 18,000 in / 373 out · 1,536 cached (9%) · glm-5.3-flash
description: $0.0001 · 18,650 in / 449 out · 1,408 cached (8%) · glm-5.3-flash
e2e: $0.0004 · 46,790 in / 1,097 out · 3,456 cached (7%) · glm-5.3-flash
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Requesting changes: 1 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0020 · 206,495 in / 8,893 out · 15,386 cached (7%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0006 · 33,547 in / 2,024 out · 4,065 cached (12%) · gpt-5.6-luna
security: $0.0006 · 33,797 in / 1,830 out · 3,577 cached (11%) · gpt-5.6-luna
tests: $0.0005 · 59,471 in / 2,018 out · 4,608 cached (8%) · glm-5.3-flash
description: $0.0001 · 19,373 in / 264 out · 1,408 cached (7%) · glm-5.3-flash
e2e: $0.0002 · 22,436 in / 295 out · 1,728 cached (8%) · glm-5.3-flash
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
There was a problem hiding this comment.
Requesting changes: 2 lane(s) blocking, worst finding is high.
Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.
$0.0365 · 684,638 in / 48,482 out · 64,039 cached (9%) · gpt-5.6-luna, glm-5.3-flash
critique: $0.0233 · 412,652 in / 28,155 out · 42,561 cached (10%) · gpt-5.6-luna, glm-5.3-flash
security: $0.0125 · 193,824 in / 17,139 out · 21,414 cached (11%) · gpt-5.6-luna
tests: $0.0001 · 18,314 in / 297 out · 0 cached (0%) · glm-5.3-flash
description: $0.0002 · 18,942 in / 634 out · 0 cached (0%) · glm-5.3-flash
e2e: $0.0002 · 21,991 in / 266 out · 0 cached (0%) · glm-5.3-flash
| { value: 'id', flag: '🇮🇩', label: 'Bahasa Indonesia' }, | ||
| { value: 'it', flag: '🇮🇹', label: 'Italiano' }, | ||
| { value: 'pl', flag: '🇵🇱', label: 'Polski' }, | ||
| { value: 'tr', flag: '🇹🇷', label: 'Türkçe' }, |
There was a problem hiding this comment.
Add the Turkish locale module before enumerating it
This makes tr a selectable locale, while the current i18n context imports ./tr and no app/src/lib/i18n/tr.ts module exists in the reviewed tree. The frontend therefore cannot build with the current imports, and selecting this option cannot provide translations. Add the complete Turkish translation module before exposing this option.
[RULE] missing-locale-module ·
| // about English there. Turkish (checked against the whole list): "can" (life/soul), "not" | ||
| // (note, as in "Not: …"), "may" (yeast), "must" (grape must), "has" (pure), "had" (limit), | ||
| // "don" (frost). "and" (oath) stays: it is archaic in UI copy and English's strongest signal. | ||
| const LOCALE_SHARED_WORDS: Readonly<Record<string, ReadonlySet<string>>> = { |
There was a problem hiding this comment.
Do not discard Turkish homographs as English signals
Removing these words unconditionally creates false negatives for English values in the Turkish locale. For example, looksEnglish("May not be available", "tr") produces no distinct English function words because both may and not are discarded, even though the entire value is English and should be reported. Use context-aware handling or retain enough signals to detect English phrases containing these homographs.
[RULE] false-negative-detection ·
| expect(reducer(undefined, { type: '@@INIT' }).current).toBe('id'); | ||
| }); | ||
|
|
||
| it.each(['tr', 'tr-TR', 'TR-tr'])('detects the Turkish browser locale %s', async language => { |
There was a problem hiding this comment.
Drive the language picker to Turkish in an E2E spec
This only verifies the initial locale inferred from navigator.language; it does not exercise the user-facing language picker, dispatching the locale change, or the resulting UI behavior. The repository rules require frontend flows to have mocked browser/desktop E2E coverage, so add an E2E case that selects Turkish through the picker and verifies the visible outcome.
[RULE] missing-e2e-coverage ·
| { value: 'id', flag: '🇮🇩', label: 'Bahasa Indonesia' }, | ||
| { value: 'it', flag: '🇮🇹', label: 'Italiano' }, | ||
| { value: 'pl', flag: '🇵🇱', label: 'Polski' }, | ||
| { value: 'tr', flag: '🇹🇷', label: 'Türkçe' }, |
There was a problem hiding this comment.
Drive the language picker to Turkish in an E2E spec
This adds a new user-facing language-selection path, but the reviewed change adds no mocked browser/desktop E2E coverage that selects tr and verifies the resulting locale behavior. Without that coverage, the missing wiring or translation failures above can regress unnoticed. Add the required E2E scenario using the repository's element helpers.
[RULE] missing-e2e-coverage ·
| ['in', 'id'], | ||
| ['it', 'it'], | ||
| ['pl', 'pl'], | ||
| ['tr', 'tr'], |
There was a problem hiding this comment.
Add the Turkish locale module before enumerating it
Adding tr to the supported-locale detection makes Turkish a reachable locale, but I18nContext.tsx imports ./tr and no app/src/lib/i18n/tr.ts module exists at this revision. A Turkish browser can now select a locale whose translation module cannot be resolved, causing the frontend build or runtime to fail. Add the complete Turkish locale module before exposing this mapping.
[RULE] missing-locale-module ·
| expect(screen.getByText('Beenden')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('serves Turkish translations left-to-right with the unknown-key fallback', () => { |
There was a problem hiding this comment.
Drive the language picker to Turkish in an E2E spec
This test dispatches setLocale('tr') directly, so it verifies provider rendering but not the user-facing language-picker flow. A registration or wiring mistake in the picker could still ship while this test passes. Add mocked browser/desktop E2E coverage that opens the picker, selects Turkish, and verifies the resulting UI and document language/direction.
[RULE] missing-e2e-coverage ·
| | 'ko' | ||
| | 'pl'; | ||
| | 'pl' | ||
| | 'tr'; |
There was a problem hiding this comment.
Drive the language picker to Turkish in an E2E spec
Adding tr as a supported locale requires coverage of the actual browser/desktop language-picker flow, not only locale-loader and reducer tests. Add a mocked frontend/desktop E2E spec that selects Turkish and verifies the resulting UI locale, using the repository's E2E element helpers.
[RULE] missing-e2e-coverage ·
Summary
tr,tr-TR).app/src/lib/i18n/tr.ts: all 4,592 current English keys translated, formal address ("siz"), placeholders preserved exactly.trin the i18n tooling:i18n-coverage.ts,i18n-find-english.ts(as a Latin-script locale), andapply-i18n-translations.ts.docs/README.tr.md, translated from the current root README, and link it from the language bar of the root README and every translated README (including the new Arabic one).Problem
tr→ Turkish foroutput_language(config/schema/types/output_language.rs), so only the frontend locale and docs were missing.Solution
Localeunion, theI18nContexttranslation map, thelocaleSliceprefix table andLanguageSelect. It is LTR, so there is no RTL work. No Rust changes.tr.tswas generated withscripts/apply-i18n-translations.ts, so keys followen.tsorder and apostrophes (e.g.OpenHuman'a) are escaped by the script.{name} için,Sil: {name}instead of{name}'e).{count} dosya).%{percent}).Submission Checklist
LanguageSelect.test.tsx(new): Turkish option is offered, it applies immediately, and switching back to English works.I18nContext.test.tsx: Turkish strings, the unknown-key fallback, andlang="tr"/dir="ltr".localeSlice.test.ts: detectstr,tr-TRandTR-tr.coverage.test.ts:tris in the parity set, plus an exact placeholder-parity check against English.docs/TEST-COVERAGE-MATRIX.mdhas no per-locale feature rows.Impact
<html lang="tr">, CSStext-transform: uppercasemapsi→İ, which is correct for Turkish text but can affect untranslated brand names in uppercase labels. Left for a follow-up if reviewers see it in practice.Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
moersoy:feat/i18n-turkishValidation Run
pnpm --filter openhuman-app format:check: changed files are clean.pnpm typecheckvitest run src/lib/i18n src/store/localeSlice.test.ts src/components/LanguageSelect.test.tsxpassed 99/99.pnpm testpassed 8,696, with 1 existing skip. TherpcMethodsdrift guard needs thevendor/submodules initialised; with them it passes 20/20.pnpm i18n:check:trhas 0 missing and 0 extra keys. 126 values are identical to English (brand and technical literals), the lowest count of any locale.pnpm i18n:english:check: 0 unexpected English values across all locales.Validation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
enfallback, theid/indetection order and RTL forarare unchanged.tr, plus exact placeholder parity.Duplicate / Superseded PR Handling
Summary by CodeRabbit