diff --git a/ui/src/i18n/lib/registry.ts b/ui/src/i18n/lib/registry.ts index d61911053bf..e13ccea5707 100644 --- a/ui/src/i18n/lib/registry.ts +++ b/ui/src/i18n/lib/registry.ts @@ -10,7 +10,7 @@ type LazyLocaleRegistration = { export const DEFAULT_LOCALE: Locale = "en"; -const LAZY_LOCALES: readonly LazyLocale[] = ["zh-CN", "zh-TW", "pt-BR", "de", "es"]; +const LAZY_LOCALES: readonly LazyLocale[] = ["zh-CN", "zh-TW", "pt-BR", "de", "es", "ko-KR"]; const LAZY_LOCALE_REGISTRY: Record = { "zh-CN": { @@ -33,6 +33,10 @@ const LAZY_LOCALE_REGISTRY: Record = { exportName: "es", loader: () => import("../locales/es.ts"), }, + "ko-KR": { + exportName: "ko_KR", + loader: () => import("../locales/ko-KR.ts"), + }, }; export const SUPPORTED_LOCALES: ReadonlyArray = [DEFAULT_LOCALE, ...LAZY_LOCALES]; @@ -58,6 +62,9 @@ export function resolveNavigatorLocale(navLang: string): Locale { if (navLang.startsWith("es")) { return "es"; } + if (navLang.startsWith("ko")) { + return "ko-KR"; + } return DEFAULT_LOCALE; } diff --git a/ui/src/i18n/lib/types.ts b/ui/src/i18n/lib/types.ts index 8b25ecbc6da..4cb82fb8ad5 100644 --- a/ui/src/i18n/lib/types.ts +++ b/ui/src/i18n/lib/types.ts @@ -1,6 +1,6 @@ export type TranslationMap = { [key: string]: string | TranslationMap }; -export type Locale = "en" | "zh-CN" | "zh-TW" | "pt-BR" | "de" | "es"; +export type Locale = "en" | "zh-CN" | "zh-TW" | "pt-BR" | "de" | "es" | "ko-KR"; export interface I18nConfig { locale: Locale; diff --git a/ui/src/i18n/locales/de.ts b/ui/src/i18n/locales/de.ts index 7fd638766e7..8466eb1666c 100644 --- a/ui/src/i18n/locales/de.ts +++ b/ui/src/i18n/locales/de.ts @@ -127,5 +127,6 @@ export const de: TranslationMap = { ptBR: "Português (Brasilianisches Portugiesisch)", de: "Deutsch", es: "Spanisch (Español)", + koKR: "한국어 (Koreanisch)", }, }; diff --git a/ui/src/i18n/locales/en.ts b/ui/src/i18n/locales/en.ts index 4d7beb928ad..16e1e5e0e54 100644 --- a/ui/src/i18n/locales/en.ts +++ b/ui/src/i18n/locales/en.ts @@ -175,6 +175,7 @@ export const en: TranslationMap = { ptBR: "Português (Brazilian Portuguese)", de: "Deutsch (German)", es: "Español (Spanish)", + koKR: "한국어 (Korean)", }, cron: { summary: { diff --git a/ui/src/i18n/locales/es.ts b/ui/src/i18n/locales/es.ts index 091cd2ca937..dc00635c812 100644 --- a/ui/src/i18n/locales/es.ts +++ b/ui/src/i18n/locales/es.ts @@ -126,6 +126,7 @@ export const es: TranslationMap = { ptBR: "Portugués brasileño (Português)", de: "Deutsch (Alemán)", es: "Español", + koKR: "한국어 (Coreano)", }, cron: { summary: { diff --git a/ui/src/i18n/locales/ko-KR.ts b/ui/src/i18n/locales/ko-KR.ts new file mode 100644 index 00000000000..2ce706e6de6 --- /dev/null +++ b/ui/src/i18n/locales/ko-KR.ts @@ -0,0 +1,144 @@ +import type { TranslationMap } from "../lib/types.ts"; +import { en } from "./en.ts"; + +export const ko_KR: TranslationMap = { + ...en, + common: { + ...en.common, + version: "버전", + health: "상태", + ok: "정상", + offline: "오프라인", + connect: "연결", + refresh: "새로고침", + enabled: "사용", + disabled: "사용 안 함", + docs: "문서", + resources: "리소스", + }, + nav: { + ...en.nav, + chat: "채팅", + control: "제어", + agent: "에이전트", + settings: "설정", + expand: "사이드바 펼치기", + collapse: "사이드바 접기", + }, + tabs: { + ...en.tabs, + agents: "에이전트", + overview: "개요", + channels: "채널", + instances: "인스턴스", + sessions: "세션", + usage: "사용량", + cron: "크론 작업", + skills: "스킬", + nodes: "노드", + chat: "채팅", + config: "구성", + debug: "디버그", + logs: "로그", + }, + subtitles: { + ...en.subtitles, + agents: "에이전트 작업 공간, 도구, ID를 관리합니다.", + overview: "게이트웨이 상태와 연결 상태를 빠르게 확인합니다.", + channels: "채널과 설정을 관리합니다.", + instances: "연결된 클라이언트/노드의 프레즌스 신호를 표시합니다.", + sessions: "활성 세션을 확인하고 세션 기본값을 조정합니다.", + usage: "API 사용량과 비용을 모니터링합니다.", + cron: "깨우기 및 반복 에이전트 실행을 예약합니다.", + skills: "스킬 사용 가능 여부와 API 키 주입을 관리합니다.", + nodes: "페어링된 장치, 권한, 명령 노출 범위를 관리합니다.", + chat: "빠른 개입을 위한 게이트웨이 직접 채팅 세션입니다.", + config: "~/.openclaw/openclaw.json을 안전하게 수정합니다.", + debug: "게이트웨이 스냅샷, 이벤트, 수동 RPC 호출입니다.", + logs: "게이트웨이 파일 로그를 실시간으로 확인합니다.", + }, + overview: { + ...en.overview, + access: { + ...en.overview.access, + title: "게이트웨이 접근", + subtitle: "대시보드 연결 위치와 인증 방식을 설정합니다.", + wsUrl: "웹소켓 URL", + token: "게이트웨이 토큰", + password: "비밀번호 (저장 안 함)", + sessionKey: "기본 세션 키", + language: "언어", + connectHint: "연결 변경 사항을 적용하려면 연결을 클릭하세요.", + trustedProxy: "신뢰 프록시를 통해 인증됨", + }, + snapshot: { + ...en.overview.snapshot, + title: "스냅샷", + subtitle: "최신 게이트웨이 핸드셰이크 정보입니다.", + status: "상태", + uptime: "가동 시간", + tickInterval: "틱 간격", + lastChannelsRefresh: "최근 채널 새로고침", + channelsHint: "채널 탭에서 WhatsApp, Telegram, Discord, Signal, iMessage를 연결하세요.", + }, + stats: { + ...en.overview.stats, + instances: "인스턴스", + instancesHint: "최근 5분 내 프레즌스 신호", + sessions: "세션", + sessionsHint: "게이트웨이가 추적한 최근 세션 키", + cron: "크론", + cronNext: "다음 깨우기 {time}", + }, + notes: { + ...en.overview.notes, + title: "노트", + subtitle: "원격 제어 환경용 빠른 안내", + tailscaleTitle: "Tailscale Serve", + tailscaleText: "게이트웨이를 루프백+테일넷 인증으로 유지하려면 Serve 모드를 권장합니다.", + sessionTitle: "세션 정리", + sessionText: "컨텍스트 초기화에는 /new 또는 sessions.patch를 사용하세요.", + cronTitle: "크론 알림", + cronText: "반복 실행에는 격리된 세션을 사용하세요.", + }, + auth: { + ...en.overview.auth, + required: + "이 게이트웨이는 인증이 필요합니다. 토큰 또는 비밀번호를 입력하고 연결을 클릭하세요.", + failed: + "인증에 실패했습니다. {command}로 토큰이 포함된 URL을 다시 복사하거나 토큰을 갱신한 뒤 연결하세요.", + }, + pairing: { + ...en.overview.pairing, + hint: "이 장치는 게이트웨이 호스트의 페어링 승인이 필요합니다.", + mobileHint: + "모바일에서는 데스크톱의 openclaw dashboard --no-open 출력에서 URL(#token 포함) 전체를 복사하세요.", + }, + insecure: { + ...en.overview.insecure, + hint: "현재 페이지는 HTTP이므로 브라우저가 장치 신원 정보를 차단합니다. HTTPS(Tailscale Serve)를 사용하거나 게이트웨이 호스트에서 {url}을 여세요.", + stayHttp: "HTTP를 유지해야 한다면 {config}(토큰 전용)를 설정하세요.", + }, + }, + chat: { + ...en.chat, + disconnected: "게이트웨이 연결이 끊어졌습니다.", + refreshTitle: "채팅 데이터 새로고침", + thinkingToggle: "어시스턴트 사고/작업 출력 토글", + focusToggle: "집중 모드 토글(사이드바 + 헤더 숨김)", + hideCronSessions: "크론 세션 숨기기", + showCronSessions: "크론 세션 보기", + showCronSessionsHidden: "크론 세션 보기 ({count}개 숨김)", + onboardingDisabled: "온보딩 중 비활성화", + }, + languages: { + ...en.languages, + en: "English", + zhCN: "简体中文 (중국어 간체)", + zhTW: "繁體中文 (중국어 번체)", + ptBR: "Português (브라질 포르투갈어)", + de: "Deutsch (독일어)", + es: "Español (스페인어)", + koKR: "한국어 (Korean)", + }, +}; diff --git a/ui/src/i18n/locales/pt-BR.ts b/ui/src/i18n/locales/pt-BR.ts index cb9ba1ba283..b8d0959f9f2 100644 --- a/ui/src/i18n/locales/pt-BR.ts +++ b/ui/src/i18n/locales/pt-BR.ts @@ -175,5 +175,6 @@ export const pt_BR: TranslationMap = { ptBR: "Português (Português Brasileiro)", de: "Deutsch (Alemão)", es: "Español (Espanhol)", + koKR: "한국어 (Coreano)", }, }; diff --git a/ui/src/i18n/locales/zh-CN.ts b/ui/src/i18n/locales/zh-CN.ts index b039be16f41..c7bdd9cf156 100644 --- a/ui/src/i18n/locales/zh-CN.ts +++ b/ui/src/i18n/locales/zh-CN.ts @@ -172,6 +172,7 @@ export const zh_CN: TranslationMap = { ptBR: "Português (巴西葡萄牙语)", de: "Deutsch (德语)", es: "Español (西班牙语)", + koKR: "한국어 (韩语)", }, cron: { summary: { diff --git a/ui/src/i18n/locales/zh-TW.ts b/ui/src/i18n/locales/zh-TW.ts index a6a616209e7..53b15721b08 100644 --- a/ui/src/i18n/locales/zh-TW.ts +++ b/ui/src/i18n/locales/zh-TW.ts @@ -172,5 +172,6 @@ export const zh_TW: TranslationMap = { ptBR: "Português (巴西葡萄牙語)", de: "Deutsch (德語)", es: "Español (西班牙語)", + koKR: "한국어 (韓語)", }, };