fix(i18n): correct Korean mistranslations

Correct Korean locale mistranslations, preserve cross-locale overrides while splitting KO data, and add regression coverage for key-specific localization repairs.
This commit is contained in:
JinHyeok Jeong
2026-06-19 15:52:05 -07:00
committed by GitHub
parent b17d8fc293
commit b346717234
15 changed files with 7093 additions and 1923 deletions
@@ -0,0 +1,126 @@
export const CROSS_LOCALE_KEY_OVERRIDES = {
'auto.components.GitLabItemDialog.4168eb2c51': {
zh: '解决',
ja: '解決'
},
'auto.components.TaskPage.524f095d55': {
zh: '待评审',
ja: 'レビュー待ち'
},
'auto.components.TaskPage.9cd11ba218': {
zh: 'Jira',
ja: 'Jira'
},
'auto.components.github.PRFilterDropdowns.19bb6f115f': {
zh: 'reviewed-by',
ja: 'reviewed-by'
},
'auto.components.onboarding.OnboardingFlow.a5e5da02f7': {
zh: '集成',
ja: '連携'
},
'auto.components.settings.TasksPane.6b23a34f6d': {
zh: 'Jira',
ja: 'Jira'
},
'auto.components.settings.integrations.search.03a7b275be': {
zh: 'ADO',
ja: 'ADO'
},
'auto.components.settings.integrations.search.129fc59aa8': {
zh: 'Gitea',
ja: 'Gitea'
},
'auto.components.settings.integrations.search.20540996ef': {
zh: '凭据',
ja: '認証情報'
},
'auto.components.settings.integrations.search.581844769a': {
zh: 'MR',
ja: 'MR'
},
'auto.components.settings.integrations.search.617603509b': {
zh: 'Jira 集成',
ja: 'Jira 連携'
},
'auto.components.settings.integrations.search.67a2a0e868': {
zh: 'Bitbucket 集成',
ja: 'Bitbucket 連携'
},
'auto.components.settings.integrations.search.aab86d64e5': {
zh: 'Gitea 集成',
ja: 'Gitea 連携'
},
'auto.components.settings.integrations.search.af6611fa6e': {
zh: 'Azure DevOps 集成',
ja: 'Azure DevOps 連携'
},
'auto.components.settings.integrations.search.b027b4b318': {
zh: 'Linear 集成',
ja: 'Linear 連携'
},
'auto.components.settings.integrations.search.b40cbe5de4': {
zh: 'glab',
ja: 'glab'
},
'auto.components.settings.integrations.search.b50b71ef9d': {
zh: 'GitLab 集成',
ja: 'GitLab 連携'
},
'auto.components.settings.integrations.search.b79c21bd42': {
zh: 'GitHub',
ja: 'GitHub'
},
'auto.components.settings.integrations.search.c450244ad7': {
zh: '集成',
ja: '連携'
},
'auto.components.settings.integrations.search.e1263dd748': {
zh: 'Jira',
ja: 'Jira'
},
'auto.components.settings.integrations.search.f16e41cc72': {
zh: 'GitHub 集成',
ja: 'GitHub 連携'
},
'auto.components.settings.jira.integration.card.09742875cd': {
zh: 'Jira',
ja: 'Jira'
},
'auto.components.sidebar.workspace.status.409528031f': {
zh: '评审',
ja: 'レビュー'
},
'auto.components.sidebar.workspace.status.6c1efa2cf8': {
zh: '评审中',
ja: 'レビュー中'
},
'auto.components.sidebar.workspace.status.caebe3c10f': {
zh: 'Conductor 评审',
ja: 'Conductor レビュー'
},
'auto.components.sidebar.worktree.list.groups.6798dc7c94': {
zh: '评审中',
ja: 'レビュー中'
},
'auto.components.skills.SkillsPage.b088e0785d': {
zh: '测试版',
ja: 'ベータ'
},
'auto.components.status.bar.WorkspaceSpaceCompactPanel.c361440dc0': {
zh: '测试版',
ja: 'ベータ'
},
'auto.components.workspace.cleanup.WorkspaceCleanupDialog.1b18868569': {
zh: '待评审',
ja: 'レビュー待ち'
},
'auto.components.workspace.space.WorkspaceSpacePage.e8d6ba11ab': {
zh: '测试版',
ja: 'ベータ'
},
'auto.hooks.useSettingsNavigationMetadata.40d80bad8a': {
zh: '测试版',
ja: 'ベータ'
}
}
@@ -0,0 +1,14 @@
import { CROSS_LOCALE_KEY_OVERRIDES } from './locale-cross-locale-key-overrides.mjs'
import { KO_KEY_OVERRIDES } from './locale-ko-key-overrides.mjs'
export function mergeLocaleKeyOverrides(base) {
const merged = { ...base }
for (const [key, overrides] of Object.entries(CROSS_LOCALE_KEY_OVERRIDES)) {
merged[key] = { ...merged[key], ...overrides }
}
for (const [key, overrides] of Object.entries(KO_KEY_OVERRIDES)) {
// KO split overrides can share keys with zh/ja repairs; merge per locale.
merged[key] = { ...merged[key], ...overrides }
}
return merged
}
+5 -4
View File
@@ -1,8 +1,8 @@
import { KO_KEY_OVERRIDES } from './locale-ko-key-overrides.mjs'
import { mergeLocaleKeyOverrides } from './locale-key-override-merge.mjs'
// Key-specific overrides from high-visibility UI audit (P0/P1/P2).
// Why: some fixes depend on full key context, not English value alone.
export const LOCALE_KEY_OVERRIDES = {
const BASE_LOCALE_KEY_OVERRIDES = {
// "Open in" is a submenu header for "open in <app>"; bare で開く reads as broken JP.
'auto.components.sidebar.WorktreeOpenInMenu.8009ab69a6': { ja: 'アプリで開く' },
// "Assigned to me" filter; the MT past-passive 割り当てられました reads as a sentence, not a filter label.
@@ -600,6 +600,7 @@ export const LOCALE_KEY_OVERRIDES = {
ja: 'レビューコメントを追加しました。'
},
// Port forwarding "Forward" is 転送, not the browser-navigation 進む.
'auto.components.right.sidebar.PortsPanel.c9d106547a': { ja: '転送' },
...KO_KEY_OVERRIDES
'auto.components.right.sidebar.PortsPanel.c9d106547a': { ja: '転送' }
}
export const LOCALE_KEY_OVERRIDES = mergeLocaleKeyOverrides(BASE_LOCALE_KEY_OVERRIDES)
File diff suppressed because it is too large Load Diff
+17 -157
View File
@@ -1,158 +1,18 @@
// Korean key overrides from high-visibility UI audit round 4.
export const KO_KEY_OVERRIDES = {
'auto.hooks.useSettingsNavigationMetadata.40d80bad8a': {
ko: '베타',
zh: '测试版',
ja: 'ベータ'
},
'auto.components.settings.integrations.search.c450244ad7': {
ko: '연동',
zh: '集成',
ja: '連携'
},
'auto.components.settings.integrations.search.e1263dd748': {
ko: 'Jira',
zh: 'Jira',
ja: 'Jira'
},
'auto.components.settings.integrations.search.581844769a': {
ko: 'MR',
zh: 'MR',
ja: 'MR'
},
'auto.components.settings.integrations.search.129fc59aa8': {
ko: 'Gitea',
zh: 'Gitea',
ja: 'Gitea'
},
'auto.components.settings.integrations.search.03a7b275be': {
ko: 'ADO',
zh: 'ADO',
ja: 'ADO'
},
'auto.components.settings.integrations.search.f16e41cc72': {
ko: 'GitHub 연동',
zh: 'GitHub 集成',
ja: 'GitHub 連携'
},
'auto.components.settings.integrations.search.b50b71ef9d': {
ko: 'GitLab 연동',
zh: 'GitLab 集成',
ja: 'GitLab 連携'
},
'auto.components.settings.integrations.search.aab86d64e5': {
ko: 'Gitea 연동',
zh: 'Gitea 集成',
ja: 'Gitea 連携'
},
'auto.components.settings.integrations.search.617603509b': {
ko: 'Jira 연동',
zh: 'Jira 集成',
ja: 'Jira 連携'
},
'auto.components.settings.integrations.search.af6611fa6e': {
ko: 'Azure DevOps 연동',
zh: 'Azure DevOps 集成',
ja: 'Azure DevOps 連携'
},
'auto.components.settings.integrations.search.67a2a0e868': {
ko: 'Bitbucket 연동',
zh: 'Bitbucket 集成',
ja: 'Bitbucket 連携'
},
'auto.components.settings.integrations.search.b027b4b318': {
ko: 'Linear 연동',
zh: 'Linear 集成',
ja: 'Linear 連携'
},
'auto.components.settings.integrations.search.b79c21bd42': {
ko: 'GitHub',
zh: 'GitHub',
ja: 'GitHub'
},
'auto.components.settings.integrations.search.b40cbe5de4': {
ko: 'glab',
zh: 'glab',
ja: 'glab'
},
'auto.components.settings.integrations.search.20540996ef': {
ko: '자격 증명',
zh: '凭据',
ja: '認証情報'
},
'auto.components.skills.SkillsPage.b088e0785d': {
ko: '베타',
zh: '测试版',
ja: 'ベータ'
},
'auto.components.workspace.space.WorkspaceSpacePage.e8d6ba11ab': {
ko: '베타',
zh: '测试版',
ja: 'ベータ'
},
'auto.components.status.bar.WorkspaceSpaceCompactPanel.c361440dc0': {
ko: '베타',
zh: '测试版',
ja: 'ベータ'
},
'auto.components.github.PRFilterDropdowns.19bb6f115f': {
ko: 'reviewed-by',
zh: 'reviewed-by',
ja: 'reviewed-by'
},
'auto.components.TaskPage.9cd11ba218': {
ko: 'Jira',
zh: 'Jira',
ja: 'Jira'
},
'auto.components.settings.TasksPane.6b23a34f6d': {
ko: 'Jira',
zh: 'Jira',
ja: 'Jira'
},
'auto.components.settings.jira.integration.card.09742875cd': {
ko: 'Jira',
zh: 'Jira',
ja: 'Jira'
},
'auto.components.workspace.cleanup.WorkspaceCleanupDialog.1b18868569': {
ko: '리뷰 필요',
zh: '待评审',
ja: 'レビュー待ち'
},
'auto.components.onboarding.OnboardingFlow.a5e5da02f7': {
ko: '연동',
zh: '集成',
ja: '連携'
},
'auto.components.GitLabItemDialog.4168eb2c51': {
ko: '해결',
zh: '解决',
ja: '解決'
},
'auto.components.sidebar.workspace.status.6c1efa2cf8': {
ko: '리뷰 중',
zh: '评审中',
ja: 'レビュー中'
},
'auto.components.sidebar.workspace.status.409528031f': {
ko: '리뷰',
zh: '评审',
ja: 'レビュー'
},
'auto.components.sidebar.workspace.status.caebe3c10f': {
ko: 'Conductor 리뷰',
zh: 'Conductor 评审',
ja: 'Conductor レビュー'
},
'auto.components.sidebar.workspace.list.groups.6798dc7c94': {
ko: '리뷰 중',
zh: '评审中',
ja: 'レビュー中'
},
'auto.components.TaskPage.524f095d55': {
ko: '리뷰 필요',
zh: '待评审',
ja: 'レビュー待ち'
}
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
// Korean key-specific overrides (reviewed in full UI context: product names, git terms, and
// labels MT mistranslated). Stored as a JSON data file — too many entries to inline under the
// .mjs max-lines limit — and loaded here so the catalog scripts keep a single ko key-override source.
const jsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'locale-ko-key-overrides.json')
let parsed
try {
parsed = JSON.parse(fs.readFileSync(jsonPath, 'utf8'))
} catch (error) {
// Name the file: a bare JSON.parse SyntaxError doesn't say which file failed.
throw new Error(`Failed to load ${path.basename(jsonPath)}: ${error.message}`)
}
export const KO_KEY_OVERRIDES = parsed
@@ -0,0 +1,14 @@
import fs from 'node:fs'
import { describe, expect, it } from 'vitest'
describe('locale-ko-key-overrides', () => {
it('keeps Korean key override data scoped to Korean values', () => {
const overrides = JSON.parse(
fs.readFileSync(new URL('./locale-ko-key-overrides.json', import.meta.url), 'utf8')
)
for (const value of Object.values(overrides)) {
expect(Object.keys(value)).toEqual(['ko'])
}
})
})
+63 -1
View File
@@ -233,5 +233,67 @@ export const KO_VALUE_OVERRIDES = {
'Review recent changes in this workspace. Focus on correctness risks, UX regressions, missing tests, and follow-up tasks. Keep the report short and actionable.':
'이 워크스페이스의 최근 변경사항을 리뷰하세요. 정확성 위험, UX 회귀, 누락된 테스트 및 후속 작업에 중점을 둡니다. 보고서를 짧고 실행 가능하게 유지하세요.',
'Check for stuck work, stale generated files, failing validation, and anything that needs human attention. Report only actionable issues.':
'작업 중단, 오래 생성된 파일, 유효성 검사 실패 및 사람의 주의가 필요한 모든 사항을 확인하세요. 실행 가능한 이슈만 보고하세요.'
'작업 중단, 오래 생성된 파일, 유효성 검사 실패 및 사람의 주의가 필요한 모든 사항을 확인하세요. 실행 가능한 이슈만 보고하세요.',
'Pipeline': '파이프라인',
'Jobs': '작업',
'Completed': '완료됨',
'Posting…': '게시 중…',
'thread': '스레드',
'Close issue': '이슈 닫기',
'Close as completed': '완료로 닫기',
'Checks': '체크',
'Refresh checks': '체크 새로고침',
'Check rerun requested': '체크 재실행이 요청되었습니다',
'Pull': '풀',
'Sync': '동기화',
'Publish Branch': '브랜치 게시',
'Stage at least one file to commit': '커밋할 파일을 하나 이상 스테이지하세요',
'Commit staged changes': '스테이지된 변경 사항 커밋',
'No commits yet': '아직 커밋이 없습니다',
'Paste': '붙여넣기',
'Next match': '다음 일치 항목',
'Previous match': '이전 일치 항목',
'Key': '키',
'Prompt': '프롬프트',
'Label': '레이블',
'Action': '작업',
'Views': '뷰',
'Jira JQL, e.g. project = ABC AND statusCategory != Done': 'Jira JQL, 예: project = ABC AND statusCategory != Done',
'npm run dev': 'npm run dev',
'/goal': '/goal',
'Grab': '가져오기',
'Change': '변경',
'Intent': '의도',
'Take back': '제어권 가져오기',
'Android': 'Android',
'Network': '네트워크',
'Available on': '지원 플랫폼',
'Git Bash': 'Git Bash',
'Set': '설정',
'Test': '테스트',
'Azure DevOps': 'Azure DevOps',
'Review providers': '리뷰 제공자',
'Task providers': '작업 제공자',
'Available Hosts': '사용 가능한 호스트',
'Refresh PR checks': 'PR 체크 새로고침',
'Run on': '실행 위치',
'Clone project': '프로젝트 클론',
'Smart': '스마트',
'Workspace name': '워크스페이스 이름',
'• inferred pricing': '• 추정 가격',
'Run context': '실행 컨텍스트',
'Dirty': '변경 있음',
'Unread': '읽지 않음',
'Home': '홈',
'Local': '로컬',
'Reveal file': '파일 표시',
'new markdown': '새 Markdown',
'new shell': '새 shell',
'trash worktree': '워크트리 휴지통으로 이동',
'AI': 'AI',
'Server': '서버',
'Web': '웹',
'Code': '코드',
'Folder': '폴더',
'Hermes automation created.': 'Hermes 자동화가 생성되었습니다.'
}
@@ -82,6 +82,14 @@ describe('locale-translation-policy ko round 5', () => {
).toBe(
'작업 중단, 오래 생성된 파일, 유효성 검사 실패 및 사람의 주의가 필요한 모든 사항을 확인하세요. 실행 가능한 이슈만 보고하세요.'
)
expect(
repairTranslatedValue({
key: 'auto.components.GitLabItemDialog.02cbe2de44',
enValue: 'Pipeline',
localeValue: '파이프라인',
locale: 'ko'
})
).toBe('파이프라인')
})
it('keeps protected workflow terms in English', () => {
+1 -1
View File
@@ -374,7 +374,7 @@ function applyBrandMistranslationFixes(enValue, localeValue, locale, key = '') {
for (const [brand, wrongForms] of Object.entries(mistranslations).sort(
([left], [right]) => right.length - left.length
)) {
if (!enValue.includes(brand)) {
if (!includesPreservedLatinTerm(enValue, brand)) {
continue
}
// Why: terminal/theme "Cursor" labels name the on-screen カーソル, not the Cursor product —
@@ -583,4 +583,23 @@ describe('locale-translation-policy', () => {
})
).toBe('폰트')
})
it('merges split Korean key overrides without dropping other locale repairs', () => {
expect(
repairTranslatedValue({
key: 'auto.components.GitHubItemDialog.8c45901789',
enValue: 'Request reviewer {{value0}}',
localeValue: '请求审阅者 {{value0}}',
locale: 'zh'
})
).toBe('请求评审人 {{value0}}')
expect(
repairTranslatedValue({
key: 'auto.components.right.sidebar.PortsPanel.c9d106547a',
enValue: 'Forward',
localeValue: '進む',
locale: 'ja'
})
).toBe('転送')
})
})
+4 -1
View File
@@ -4402,10 +4402,10 @@
"5f5142a62a": "Previous icon"
},
"AppearancePane": {
"3057983501": "Unassigned",
"872af9556e": "System Tray",
"2edf606c46": "Minimize to Tray on Close",
"b707773a0d": "When enabled, closing the window keeps Orca running in the system tray instead of quitting.",
"3057983501": "Unassigned",
"0cd9b8228f": "Choose the app icon shown in the Dock and window switcher.",
"ca1590d42f": "App Icon",
"61d842eca0": "Show the Orca Mobile shortcut in the sidebar. It remains available from Toolbox.",
@@ -9080,6 +9080,9 @@
"copyCommand": "Copy command"
}
}
},
"SourceControlEntryContextMenu": {
"a1f2c8d901": "View"
}
}
},
+3
View File
@@ -9080,6 +9080,9 @@
"copyCommand": "Copy command"
}
}
},
"SourceControlEntryContextMenu": {
"a1f2c8d901": "View"
}
}
},
+3
View File
@@ -9080,6 +9080,9 @@
"copyCommand": "Copy command"
}
}
},
"SourceControlEntryContextMenu": {
"a1f2c8d901": "View"
}
}
},
File diff suppressed because it is too large Load Diff
+3
View File
@@ -9080,6 +9080,9 @@
"copyCommand": "Copy command"
}
}
},
"SourceControlEntryContextMenu": {
"a1f2c8d901": "View"
}
}
},