feat(i18n): add Korean (ko) locale
- Dominant language
- TypeScript
- Stars
- 5.4k
- Forks
- 502
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 715
Description
English
## Problem
Maka ships `['zh-CN','zh-TW','en']` after #3853 and will ship `['zh-CN','zh-TW','en']` after #3853 (`packages/core/src/ui-locale.ts: UI_LOCALES`). A system with `ko`/`ko-KR` falls back to `en`. There is no tracking issue that defines scope, acceptance and incremental delivery for a new locale, so work cannot be claimed, split, or reviewed by domain.
Adding a locale is not “translate a file”. Per #2672 it must use the typed `UiCatalog` contract, a single Desktop locale authority, and domain-owned catalogs, without a global translation file or new i18n framework.
## Desired outcome
A typed, domain-owned `ko` locale:
- `UiLocale` includes `ko` on top of `['zh-CN','zh-TW','en']`; `resolveSystemUiLocale` recognizes `ko`/`ko-KR`/`ko_KR`; `uiLocaleToIntlLocale` maps to `ko-KR`
- Every user-facing copy domain provides `ko` via `UiCatalog` (Desktop ~25 catalogs, `packages/ui`, `packages/core`, CLI human help / TUI chrome)
- Renderer and post-startup native surfaces resolve the same `preference → system → en` locale; machine-readable output, logs, protocol, JSONL, model output remain locale-independent
- No new i18n framework, no global catalog, no translation of logs/protocol/model output/user content
## Alternatives or workarounds
Keep English fallback for `ko` systems, or maintain a private fork. Both fragment review and duplicate the `zh-TW` effort in #3853.
## Background
Follows #2672 contract and reuses #3853 patterns for `zh-TW`. Builds on #3853's `['zh-CN','zh-TW','en']` contract — see #3853 discussion for canonical shape. Existing foundation: `UiLocale`/`UiLocalePreference` in `@maka/core`, `LocaleProvider` in Renderer, `DesktopLocaleAuthority` in `apps/desktop/src/main/desktop-locale-authority.ts`.
## Scope (incremental — not one PR)
Split by domain, each a separate PR with `Fixes #`:
1. `core` — locale model (`ui-locale.ts`: `UI_LOCALES`, `isUiLocale`, `resolveSystemUiLocale`, `uiLocaleToIntlLocale`) + tests
2. `desktop` slice 1 — `settings-preferences` / `onboarding` / `shell` / `permissions`
3. `desktop` slice 2 — remaining `settings-*` / `conversation` / `artifact` / `browser` / `mcp` / `plan-mode`
4. `packages/ui` + `packages/core` error copy
5. `packages/cli` — human help / TUI chrome (explicit `override` + system fallback)
6. Native — notifications, upgrade dialogs, diagnostics + `e2e/fixtures.ts` `ko` flag
Reference for catalog inventory:
`apps/desktop/src/renderer/locales/*.ts` (25 files), `apps/desktop/src/main/*copy.ts` (3), `packages/ui/src/*copy.ts` (8), `packages/core/src/connection-error-copy.ts`, `packages/cli/src/cli-ui-locale.ts`
## Non-goals
- Adopt i18next / ICU / external TMS
- Single global translation file
- Translate logs, JSONL, protocol, machine-readable CLI output
- One-shot full-repo rewrite (see #2672)
## Acceptance criteria
- `ko` selectable (Follow system / 한국어 / English / 中文), `auto` + `ko` system → `ko`
- `en` shows no Korean, `ko` shows no untranslated fallback where catalog exists
- Locale switch re-renders existing session history without rewriting stored events
- `npm run lint && npm run format:check && npm run build && npm run typecheck` green; `npm --workspace @maka/core test` and `npm --workspace @maka/ui test` with `ko` coverage; new `toolId` without `ko` entry fails typecheck (`UiCatalog`)
- Each slice PR includes bilocale unit tests and screenshots for UI slices
## Task list
- [ ] #3975 — core: add `ko` to `UiLocale` model
- [ ] #3977 — desktop slice 1: settings-preferences/onboarding/shell/permissions
- [ ] #3976 — desktop slice 2: remaining settings/conversation/artifact/browser/mcp/plan-mode
- [ ] #3978 — shared UI — packages/ui and core error copy
- [ ] #3979 — CLI — human help and TUI chrome
- [ ] #3980 — native surfaces and E2E fixtures
## Verification
Per-PR: bilocale tests, Storybook/Desktop screenshots at 1280 + 430, `knip` for touched workspaces. Machine-readable CLI/Runtime Host contracts unchanged.
中文
## 问题
当前仅 `zh/en`,`ko` 系统回退英文。无追踪 Issue 导致范围、验收、增量交付无法认领与分域评审。按 #2672,新增语言必须走类型化 `UiCatalog` + 统一 authority + 领域拥有文案。
## 期望结果
同英文:`UI_LOCALES` 含 `ko`,全链路 `preference → system → en` 解析一致,各域通过 `UiCatalog` 提供 `ko`,不引入新框架,不翻译日志/协议/机读输出。
## 替代方案
保持英文回退或私有 fork,均割裂且重复 #3853。
(Scope / 非目标 / 验收 / 验证 同英文)
한국어
## 문제
Maka는 현재 `['zh','en']`이며 #3853 이후 `['zh-CN','zh-TW','en']`을 제공합니다 (`packages/core/src/ui-locale.ts: UI_LOCALES`)., `ko`/`ko-KR` 시스템은 `en`으로 폴백됩니다. 새로운 로케일에 대한 범위, 완료 기준, 점진적 제공 방안을 정의하는 추적 이슈가 없어 작업을 클레임하거나 도메인별로 분할·리뷰할 수 없습니다.
로케일 추가는 “파일 하나 번역”이 아닙니다. #2672에 따라 타입이 보장된 `UiCatalog` 계약, 단일 Desktop locale authority, 도메인 소유 카탈로그를 사용해야 하며, 전역 번역 파일이나 새로운 i18n 프레임워크 없이 진행해야 합니다.
## 기대 결과
타입이 보장되고 도메인이 소유하는 `ko` 로케일:
- `UiLocale`에 `ko` 포함; `resolveSystemUiLocale`가 `ko`/`ko-KR`/`ko_KR` 인식; `uiLocaleToIntlLocale`이 `ko-KR`로 매핑
- 모든 사용자 대상 카피 도메인이 `UiCatalog`를 통해 `ko` 제공 (Desktop 약 25개 카탈로그, `packages/ui`, `packages/core`, CLI human help / TUI 크롬)
- Renderer와 시작 후 네이티브 서피스가 동일한 `preference → system → en` 로케일을 해석; 머신 리더블 출력, 로그, 프로토콜, JSONL, 모델 출력은 로케일과 무관하게 유지
- 새로운 i18n 프레임워크 없음, 전역 카탈로그 없음, 로그/프로토콜/모델 출력/사용자 콘텐츠 번역 없음
## 대안 또는 우회 방법
`ko` 시스템에서 영어 폴백을 유지하거나 private fork를 유지합니다. 두 경우 모두 리뷰를 분절시키고 #3853의 `zh-TW` 노력을 중복시킵니다.
## 배경
#2672 계약을 따르고 `zh-TW`에 대한 #3853 패턴을 재사용합니다. 기존 기반: `@maka/core`의 `UiLocale`/`UiLocalePreference`, Renderer의 `LocaleProvider`, `apps/desktop/src/main/desktop-locale-authority.ts`의 `DesktopLocaleAuthority`.
## 범위 (점진적 — 한 번에 하나의 PR이 아님)
도메인별로 분할, 각각 `Fixes #`가 있는 별도 PR:
1. `core` — 로케일 모델 (`ui-locale.ts`: `UI_LOCALES`, `isUiLocale`, `resolveSystemUiLocale`, `uiLocaleToIntlLocale`) + 테스트
2. `desktop` slice 1 — `settings-preferences` / `onboarding` / `shell` / `permissions`
3. `desktop` slice 2 — 나머지 `settings-*` / `conversation` / `artifact` / `browser` / `mcp` / `plan-mode`
4. `packages/ui` + `packages/core` 오류 카피
5. `packages/cli` — human help / TUI 크롬 (명시적 `override` + 시스템 폴백)
6. 네이티브 — 알림, 업그레이드 대화상자, 진단 + `e2e/fixtures.ts` `ko` 플래그
카탈로그 인벤토리 참조:
`apps/desktop/src/renderer/locales/*.ts` (25개 파일), `apps/desktop/src/main/*copy.ts` (3개), `packages/ui/src/*copy.ts` (8개), `packages/core/src/connection-error-copy.ts`, `packages/cli/src/cli-ui-locale.ts`
## 제외 목표
- i18next / ICU / 외부 TMS 도입
- 단일 전역 번역 파일
- 로그, JSONL, 프로토콜, 머신 리더블 CLI 출력 번역
- 한 번에 전체 저장소 재작성 ( #2672 참조)
## 승인 기준
- `ko` 선택 가능 (시스템 따름 / 한국어 / English / 中文), `auto` + `ko` 시스템 → `ko`
- `en`에서는 한국어가, `ko`에서는 카탈로그가 존재하는 곳에서 번역되지 않은 폴백이 표시되지 않음
- 로케일 전환 시 저장된 이벤트를 다시 쓰지 않고 기존 세션 히스토리를 다시 렌더링
- `npm run lint && npm run format:check && npm run build && npm run typecheck` 통과; `npm --workspace @maka/core test` 및 `npm --workspace @maka/ui test`가 `ko` 커버리지와 함께 통과; `ko` 항목이 없는 새로운 `toolId`는 타입 체크 실패 (`UiCatalog`)
- 각 슬라이스 PR에는 이중 로케일 단위 테스트와 UI 슬라이스에 대한 스크린샷 포함
## 작업 목록
- [ ] #3975 — core: add `ko` to `UiLocale` model
- [ ] #3977 — desktop slice 1: settings-preferences/onboarding/shell/permissions
- [ ] #3976 — desktop slice 2: remaining settings/conversation/artifact/browser/mcp/plan-mode
- [ ] #3978 — shared UI — packages/ui and core error copy
- [ ] #3979 — CLI — human help and TUI chrome
- [ ] #3980 — native surfaces and E2E fixtures
## 검증
PR별: 이중 로케일 테스트, 1280 + 430에서의 Storybook/Desktop 스크린샷, 변경된 워크스페이스에 대한 `knip`. 머신 리더블 CLI/Runtime Host 계약은 변경 없음.
### Sub-issues
- #3975 — core — add ko to UiLocale model
- #3977 — desktop slice 1 — settings-preferences/onboarding/shell/permissions
- #3976 — desktop slice 2 — remaining settings/conversation/artifact/browser/mcp/plan-mode
- #3978 — shared UI — packages/ui and core error copy
- #3979 — CLI — human help and TUI chrome
- #3980 — native surfaces and E2E fixtures
Contributor guide
Research direction
Start with the referenced sub-issues, beginning at packages/core/src/ui-locale.ts and its locale tests to understand the existing zh-CN/zh-TW contract. Then use the listed catalog files and DesktopLocaleAuthority as the map for each domain slice. Done means the six slices provide typed ko catalogs, preserve locale-independent machine output, pass the listed checks, and include bilocale tests or UI screenshots where required.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, desktop, internationalization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100