Repository navigation
fix(i18n): keep ko workspace, worktree, and primary distinct - #11728
Turtle-Hwan wants to merge 15 commits into
Conversation
Greptile SummaryThis PR fixes Korean i18n terminology confusion between workspace, worktree, and primary — three distinct concepts that had collapsed into overlapping or incorrect renderings — and repairs the
Confidence Score: 5/5Safe to merge — all changes are offline tooling and generated locale data; no runtime source is touched. The repair pipeline refactoring is clean: the bootstrap guard correctly skips non-string leaves without touching the locale catalog, the applyPolicyRepairs helper faithfully preserves the existing order of brand-fix → phrase-fix → glossary → CJK spacing, and the new CI gate closes the drift detection gap. The English-guard regexes use mutually exclusive conditions (negative lookaheads for the workspace-only / worktree-only cases) so the rules cannot chain-fire on each other. Test coverage exercises every rule path including the two tricky edge cases (dual-term preservation and working-tree passthrough). All 42,085 tests and the three localization gates passed in CI. Files Needing Attention: No files require special attention.
|
| Filename | Overview |
|---|---|
| config/scripts/locale-workspace-worktree-glossary.mjs | New repair stage implementing English-guarded regex rules for workspace/worktree/primary per locale. Guard logic is mutually exclusive for the workspace-only vs worktree-only cases (negative lookaheads prevent both firing when en names both terms). All rules are exercised by dedicated tests. |
| config/scripts/locale-translation-policy.mjs | Extracts applyPolicyRepairs helper (deduplicating three identical call chains), inserts applyWorkspaceWorktreeGlossary after phrase fixes, adds repairCatalog bootstrap guard (typeof current !== 'string'), exports countCatalogRepairDrifts for non-mutating CI checks, and adds Continue-action exemptions. Refactoring is clean with no behavioral regression on existing code paths. |
| config/scripts/repair-locale-catalog.mjs | Adds --check mode (read-only drift detection) with correct exit code 1 on dirty, returns clean boolean in result object, and wires checkOnly through main(). The check-only path loads a Map clone for cache so the original is not mutated. |
| config/scripts/verify-localization-repair.mjs | New CI gate that uses countCatalogRepairDrifts against ko/ja/zh catalogs and returns exit 1 on any drift. Spanish is deliberately excluded (comment explains bulk MT drift not yet addressed). Wired into the lint script in package.json. |
| config/scripts/locale-workspace-worktree-glossary-ko.test.mjs | Comprehensive tests covering all ko glossary rules: term swaps (workspace↔worktree), dual-term preservation, primary-vs-default disambiguation, working-tree override pin, phrase-rule passthrough, and the repairCatalog bootstrap guard. Comment on the three working-tree keys clearly attributes the guarantee to key overrides after the previous review thread. |
| config/scripts/locale-continue-action-exemptions.mjs | New module distinguishing the 'Continue' action button from the Continue agent product name. Correctly exempts multi-word 'Continue in New Session' values and a specific MobileHero key from the brand-revert and never-translate guards. |
| config/scripts/locale-ko-key-overrides.json | Adds eight key overrides for strings where MT produced errors beyond terminology (primary-branch following, Linear workspace body with corrupted character, working-tree paraphrases). Overrides for BaseRefPicker already use the corrected 주 브랜치 form; RepositoryPane overrides retain 기본 워크트리 for the 'default worktree' (default, not primary) sense. |
| src/renderer/src/i18n/locales/ko.json | 137 leaf updates: 작업 트리 → 워크트리 throughout, workspace/worktree swap corrections, 기본 → 주 on primary-worktree/checkout/branch contexts. Generated by the repair script; spot-checked key cases match the PR's before/after table. |
| src/renderer/src/i18n/locales/zh.json | Bulk drift cleanup (工作区/工作树 swaps + 主要→主 badge) produced by the unblocked repairCatalog running for the first time. Changes mirror the same glossary logic as ko. |
| config/scripts/locale-ja-phrase-fixes.mjs | Adds two phrase-fix rules to re-space 'AIagent' gluing caused by the エージェント→agent brand revert. The character-class lookbehind correctly inserts the gap between preceding Japanese and the AI token. |
| package.json | Adds verify:localization-repair script and appends it to the lint gate, closing the gap where catalog drift went undetected for 276 leaves. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[repairTranslatedValue] --> B{Key override?}
B -- yes --> C[applyPolicyRepairs\nwith keyOverride value]
B -- no --> D{Value override?}
D -- yes --> E[applyPolicyRepairs\nwith valueOverride value]
D -- no --> F{shouldPreserveEnglishValue?}
F -- yes --> G[Return enValue unchanged]
F -- no --> H[applyPolicyRepairs\nwith localeValue]
subgraph applyPolicyRepairs
P1[applyBrandMistranslationFixes]
P2[applyPhraseFixes]
P3[applyWorkspaceWorktreeGlossary NEW]
P4[applyCjkLatinTermSpacing]
P1 --> P2 --> P3 --> P4
end
C --> applyPolicyRepairs
E --> applyPolicyRepairs
H --> applyPolicyRepairs
Reviews (5): Last reviewed commit: "fix(i18n): Consolidate workspace/worktre..." | Re-trigger Greptile
|
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:
📝 WalkthroughWalkthroughUpdated Japanese, Korean, and Chinese renderer catalogs with standardized terminology, spacing, and localized UI messages. Added guarded glossary repairs for workspace, worktree, primary, and AI-agent terms. Added Continue action exemptions and locale overrides. Added catalog drift counting, check-only repair mode, verification commands, tests, package wiring, workflow integration, and localization workflow documentation. 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 8b1a9bdd-c6b9-461e-99f5-e6943f46c684
📥 Commits
Reviewing files that changed from the base of the PR and between 4f00b21 and e41d6088ee46b3b062367a03998198c6aedab625.
📒 Files selected for processing (8)
.github/CONTRIBUTING.mdAGENTS.mdconfig/scripts/locale-ko-key-overrides.jsonconfig/scripts/locale-ko-phrase-fixes-round5.mjsconfig/scripts/locale-ko-phrase-fixes-round6.mjsconfig/scripts/locale-translation-policy-ko-round6.test.mjsconfig/scripts/locale-translation-policy.mjssrc/renderer/src/i18n/locales/ko.json
There was a problem hiding this comment.
Actionable comments posted: 5
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fe237727-a2d7-476f-97f1-c15f0acb4c4d
📥 Commits
Reviewing files that changed from the base of the PR and between e41d6088ee46b3b062367a03998198c6aedab625 and d71191277d1e9fb4bee6bbe884c7f6bc8c95abc8.
📒 Files selected for processing (12)
.github/CONTRIBUTING.mdAGENTS.mdconfig/scripts/locale-ja-phrase-fixes-round6.mjsconfig/scripts/locale-ja-phrase-fixes.mjsconfig/scripts/locale-translation-policy-ja-round6.test.mjsconfig/scripts/locale-translation-policy-ko-round6.test.mjsconfig/scripts/locale-translation-policy-zh-round6.test.mjsconfig/scripts/locale-zh-phrase-fixes-round5.mjsconfig/scripts/locale-zh-phrase-fixes-round6.mjssrc/renderer/src/i18n/locales/ja.jsonsrc/renderer/src/i18n/locales/ko.jsonsrc/renderer/src/i18n/locales/zh.json
🚧 Files skipped from review as they are similar to previous changes (2)
- .github/CONTRIBUTING.md
- src/renderer/src/i18n/locales/ko.json
AmethystLiang
left a comment
There was a problem hiding this comment.
Review summary
Reviewed the full branch (ko/ja/zh terminology guards, Continue-action vs Continue-agent split, catalog repair skip for missing keys, and the shared workspace-worktree-phrase-fixes.mjs consolidation).
What looks solid
- Workspace ≠ worktree and primary ≠ default are enforced via English-guarded phrase rules, so dual-term strings keep both terms.
- Catalogs are repair-idempotent (0 leaf drift on re-run) and pass
verify:localization-catalog. - Continue action buttons translate; agent catalog bare "Continue" stays Latin.
- ja AI agent spacing and zh agent-detection wording regressions from the brand-revert path are fixed and regression-tested.
- Missing-key
repairCatalogguard is covered.
Checks run locally
- vitest: ko/ja/zh round6 + continue/AI agent + base policy tests — 40/40 pass
- catalog defect audit (workspace/worktree swaps, glued AIagent, broken 未检测) — clean
pnpm verify:localization-catalog— clean
No further code changes needed from this review.
8595418 to
085b42d
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
config/scripts/verify-localization-repair.mjs (1)
52-54: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winLet validation output flush before exit.
process.exit(await main())can terminate the process beforeconsole.errorandconsole.logoutput drains through CI pipes. Setprocess.exitCodeinstead and let Node.js exit naturally.Suggested change
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { - process.exit(await main()) + process.exitCode = await main() }#!/usr/bin/env bash set -euo pipefail node --input-type=module <<'EOF' import { spawnSync } from 'node:child_process' for (const mode of ['process.exit(1)', 'process.exitCode = 1']) { const source = `process.stderr.write('x'.repeat(1_000_000)); ${mode}` const result = spawnSync(process.execPath, ['--input-type=module', '--eval', source], { encoding: 'utf8', }) console.log(mode, { status: result.status, bytes: result.stderr.length }) } EOF.github/workflows/pr.yml (1)
99-115: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winDeclare read-only permissions for
root_directory_guard.If
.github/workflows/pr.ymlhas no workflow-level restriction, this job can inherit broadGITHUB_TOKENpermissions while executing.github/scripts/check-root-directory-entries.sh. Addcontents: readto this job, or verify an equivalent workflow-level restriction.Suggested change
root_directory_guard: name: root directory guard runs-on: ubuntu-latest + permissions: + contents: read#!/usr/bin/env bash set -euo pipefail sed -n '1,125p' .github/workflows/pr.yml
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 127c9a83-0f21-47b3-9a60-67f554928fb6
📥 Commits
Reviewing files that changed from the base of the PR and between 8595418d1bd7ac6f69b6802550383144f21b7942 and 085b42d763a600516a39f6d8fd290d35d0958229.
📒 Files selected for processing (22)
.github/CONTRIBUTING.md.github/workflows/pr.ymlconfig/scripts/locale-continue-action-exemptions.mjsconfig/scripts/locale-continue-action-key-overrides.mjsconfig/scripts/locale-ja-phrase-fixes.mjsconfig/scripts/locale-key-override-merge.mjsconfig/scripts/locale-ko-key-overrides.jsonconfig/scripts/locale-ko-phrase-fixes-round5.mjsconfig/scripts/locale-translation-policy-continue-and-ai-agent.test.mjsconfig/scripts/locale-translation-policy.mjsconfig/scripts/locale-value-overrides.mjsconfig/scripts/locale-workspace-worktree-glossary-ja.test.mjsconfig/scripts/locale-workspace-worktree-glossary-ko.test.mjsconfig/scripts/locale-workspace-worktree-glossary-zh.test.mjsconfig/scripts/locale-workspace-worktree-glossary.mjsconfig/scripts/locale-workspace-worktree-glossary.test.mjsconfig/scripts/locale-zh-phrase-fixes-round5.mjsconfig/scripts/localization-package-contract.test.mjsconfig/scripts/repair-locale-catalog.mjsconfig/scripts/verify-localization-repair.mjsconfig/scripts/verify-localization-repair.test.mjspackage.json
🚧 Files skipped from review as they are similar to previous changes (20)
- config/scripts/locale-zh-phrase-fixes-round5.mjs
- package.json
- config/scripts/locale-continue-action-key-overrides.mjs
- config/scripts/locale-key-override-merge.mjs
- config/scripts/locale-workspace-worktree-glossary-ja.test.mjs
- config/scripts/verify-localization-repair.test.mjs
- config/scripts/locale-continue-action-exemptions.mjs
- config/scripts/locale-workspace-worktree-glossary.test.mjs
- config/scripts/locale-workspace-worktree-glossary-zh.test.mjs
- config/scripts/locale-workspace-worktree-glossary-ko.test.mjs
- config/scripts/repair-locale-catalog.mjs
- config/scripts/locale-workspace-worktree-glossary.mjs
- .github/CONTRIBUTING.md
- config/scripts/locale-ja-phrase-fixes.mjs
- config/scripts/locale-value-overrides.mjs
- config/scripts/locale-translation-policy-continue-and-ai-agent.test.mjs
- config/scripts/locale-ko-key-overrides.json
- config/scripts/locale-ko-phrase-fixes-round5.mjs
- config/scripts/locale-translation-policy.mjs
- config/scripts/localization-package-contract.test.mjs
repairCatalog passed undefined to repairTranslatedValue whenever en.json carried a key the locale catalog had not been bootstrapped with yet (40 such keys today), crashing the script before any repair landed. Skip those leaves and apply the pending phrase-fix policy to ko.json (276 leaf updates).
Korean copy rendered "Remove workspace" as 워크트리 제거 and "Open Parent Worktree" as 상위 워크스페이스 열기, so delete and remove prompts named a different object than the one the action touches. worktree also alternated between 워크트리 and 작업 트리, and Orca-git "primary" collapsed into 기본 — the same word the catalog already uses for "default branch", which left the primary-worktree badge reading as a default-branch marker. Fix the glossary rather than the catalog: round 6 phrase fixes pin workspace/worktree/primary per locale, guarded so strings naming both terms and the separate "working tree" concept are left alone. Five BaseRefPicker, RepositoryPane, and Linear strings needed key overrides where the surrounding MT was wrong too, including one with a corrupted character. Document the distinction in CONTRIBUTING and AGENTS so the next locale pass does not re-merge them.
Review feedback. The working-tree test read as if it exercised the phrase rules, but all three keys carry key overrides, so it pins the shipped Korean rather than the rule path — the companion test covers the rules. Rename it and say so. CONTRIBUTING had the same gap: lexical swaps are phrase fixes, the working-tree paraphrase is a key override, and pointing at one file would send the next locale pass looking in the wrong place.
Add phrase-fix rules and test coverage for Japanese and Chinese to keep workspace/worktree and primary/default distinct—mirrors the Korean fixes from prior rounds. Simplify localization guidance in docs.
Terminology distinctions are now enforced through automated guards in the locale catalog repair process.
Move locale-specific fixes for workspace / worktree / primary distinction into a shared file. Centralizes the cross-locale terminology strategy and reduces duplication across Japanese, Korean, and Chinese catalogs.
Distinguish "Continue" action button from the Continue agent brand in translations. Add exemptions and key-specific overrides to prevent brand reverts from flattening action text. Include comprehensive tests for Continue/agent distinction, ja AI agent spacing, and zh agent wording.
Point contributors at workspace-worktree-phrase-fixes.mjs so the shared guards stay discoverable after the round6 consolidation.
Keep that guidance in CONTRIBUTING only; AGENTS.md did not need the branch-local addition.
Extracted workspace/worktree/primary terminology from scattered phrase-fix modules into locale-workspace-worktree-glossary.mjs, now applied as its own repair stage (after generic MT fixes). This ensures domain terms are protected from earlier phrase-fix rules that might re-swap them, preventing confusion when copy describes workspace deletion vs worktree deletion. Added verify:localization-repair gate for ko/ja/zh in CI, --check mode for repair-locale-catalog, and updated CONTRIBUTING.md workflow documentation.
085b42d to
39c9bdb
Compare
|
Thanks for catching this — the crash is real and reproduces on I've split the fix out on its own with a regression test and credited you as the author — it's in #12514. I left the catalog regeneration your PR also carried out of that branch so the guard can land on its own; happy to take the regeneration as a follow-up. Sorry for the slow turnaround on this one. |
…#11728) en.json carries ~190 keys per locale that the locale catalogs have not been bootstrapped with yet, so every repair-locale-catalog run threw a TypeError before doing any work. Skip missing leaves instead. Split out of #11728 so the crash fix can land without the catalog regeneration, which still needs native-speaker review. Co-authored-by: Turtle-Hwan <turtlehwan@gmail.com> Co-authored-by: Orca <help@stably.ai>
|
Merged into Closing this in favour of that. Thank you for the fix, and sorry it took as long as it did to get through. |
Fixes #11727.
Problem
Korean copy names the wrong object in delete and remove flows. Remove workspace renders as
워크트리 제거("Remove worktree") and Open Parent Worktree as상위 워크스페이스 열기("Open parent workspace") — different objects, removed by different actions.worktreealso alternates between워크트리and작업 트리across 112 strings, and Orca's gitprimarycollapsed into기본, the word the catalog already uses for default, leaving the primary-worktree badge reading as a default-branch marker.The catalog is generated, so the fix belongs in the glossary:
repair-locale-catalog.mjsrewrites every leaf fromconfig/scripts/, and a hand-edited value would not survive the next run.Fix
Two commits, reviewable independently.
1 —
repairCatalogguard. The repair script could not run at all: it passedundefinedintorepairTranslatedValuefor anyen.jsonkey the locale catalog hadn't been bootstrapped with yet (40 today) and crashed inapplyBrandMistranslationFixes. Skipping those leaves unblocks it, which also applies 276 leaf updates that already-declared rules had never reached —작업 공간 → 워크스페이스among them. This commit is pure tooling repair; the diff it produces is the repo's own policy catching up.2 — the terminology. A round-6 phrase-fix set pins the vocabulary:
Rules are guarded on the English source, so a string naming both terms (
This workspace cannot be forked into a git worktree.) keeps both, andprimaryoutside the git vocabulary (Primary action clicked, X11primary selection) keeps기본. Eight strings needed key overrides where the MT was wrong beyond terminology —Following primary branch (X)had become "the next default branch", and one Linear string carried a corrupted character (단일 Linear �크트리의 ID).working-treeis deliberately not folded into a third loanword. In UI copy it only ever qualifies a file ("no working-tree file is available to edit"), where what's missing is the file, not the worktree; those three strings are paraphrased.CONTRIBUTING.mdnow records the contract, including that git's own vocabulary overlaps the two senses and that git stderr matchers must never be translated.137 leaf updates. No runtime source is touched — locale data plus two offline build scripts.
Validation
pnpm lint— clean, including all three localization gatespnpm typecheck— cleanpnpm test— 42,085 passed, 3,976 filesnpx vitest run config/scripts/locale-translation-policy-ko-round6.test.mjs— 9 passeden.json↔ko.jsonaudit after the change: 0 remaining defects in every class above, the only survivingprimary → 기본pairs being the two intentional non-git onesThe new tests assert the terminology contract, not whole sentences. Full-string equality is used only where the string is a single term (
워크트리 삭제,주); everything else asserts which term must and must not appear, so copy can be reworded later without breaking them while a swapped term still fails immediately. One case pins therepairCatalogguard; one asserts an unmappedworking-treestring passes through untouched rather than silently acquiring the wrong term.Copy changes
No visual change beyond the strings themselves. Representative before/after:
TerminalSshReconnectOverlay.removeWorkspaceButtonWorktreeContextMenu.8d9cd19d09WorktreeContextMenu.deleteWorktreeWorktreeCard.7d517f82e2(badge)WorktreeCard.0777de5970(tooltip)WorktreeContextMenu.primaryDeleteDisabledNotes
bootstrap/repairscripts, never at app runtime. One corrected string sits on the SSH reconnect path; the change is copy-only and its handler is untouched.kowas audited.zh,ja, andestranslate through the same context-free path, so the class is likely present there — [Bug]: Chinese translation error: Automation missed-run Grace field mistranslated as “elegance” / “divine grace” #11505 looks like an instance. Kept out of this PR to keep it reviewable.verify:localization-catalogand friends check key parity and coverage but not whether a catalog agrees with the glossary, which is how 276 leaves of drift went unnoticed. Arepair --checkgate would close that; happy to send it separately rather than widen this PR.wsl-hook-relay-live.integration.test.tsfails against a staleout/relay/wsl/bundle because it only rebuilds when the bundle is absent (node config/scripts/build-relay.mjsclears it), andai-vault-session-worktree-map.test.tsxasserts a 150 ms wall-clock budget that can be exceeded under full-suite parallel load while passing 3/3 in isolation.X: @turtlehwan