From f5e8cb952e162f4f05eeb97a4ebad7bf33eb3a6f Mon Sep 17 00:00:00 2001 From: Hojin Date: Fri, 2 Oct 2026 21:04:16 +0900 Subject: [PATCH] fix(i18n): distinguish Korean workspace and worktree labels Correct 22 Korean labels to match the workspace or worktree named by their English source. Pin the same values in the Korean key overrides and cover catalog values and repair-policy stability with regression tests. Fixes #11727 Co-Authored-By: Claude Opus 5.5 --- config/scripts/locale-ko-key-overrides.json | 65 +++++- .../scripts/locale-ko-key-overrides.test.mjs | 221 ++++++++++++++++++ .../ko-ui-semantic-mistranslations.test.ts | 38 +++ src/renderer/src/i18n/locales/ko.json | 44 ++-- 4 files changed, 345 insertions(+), 23 deletions(-) diff --git a/config/scripts/locale-ko-key-overrides.json b/config/scripts/locale-ko-key-overrides.json index b0f99275b438..f2acc821985a 100644 --- a/config/scripts/locale-ko-key-overrides.json +++ b/config/scripts/locale-ko-key-overrides.json @@ -488,6 +488,9 @@ "auto.components.TaskPage.fe28c9821f": { "ko": "보기" }, + "auto.components.TaskPage.linearEmptyUnfilteredScope": { + "ko": "이 워크스페이스 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요." + }, "auto.components.Terminal.5b2c1a9e44": { "ko": "agent CLI를 찾지 못했습니다. 하나를 설치하거나 설정에서 기본 agent를 선택하세요." }, @@ -1151,6 +1154,9 @@ "auto.components.feature.wall.review.notes.diff.rows.f621c734f8": { "ko": "메모 · 줄" }, + "auto.components.floating.terminal.FloatingTerminalToggleButton.4cb418b991": { + "ko": "플로팅 워크스페이스 표시, 새 활동" + }, "auto.components.github.CloseReasonDropdown.e1f2a3b4c5": { "ko": "닫기 사유 선택" }, @@ -1373,6 +1379,15 @@ "auto.components.jira.connect.dialog.fdd26d81cc": { "ko": "Atlassian 계정 설정" }, + "auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesBody": { + "ko": "상태, 담당자, 레이블 필터는 단일 Linear 워크스페이스의 ID를 사용합니다. 해당 속성으로 필터링할 워크스페이스 하나를 선택하세요." + }, + "auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesTitle": { + "ko": "워크스페이스 선택" + }, + "auto.components.linear-issue-attribute-filter-dropdowns.teamRequired": { + "ko": "이 워크스페이스의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요." + }, "auto.components.linear.api.key.dialog.57a66522c8": { "ko": "연결 중" }, @@ -1955,6 +1970,12 @@ "auto.components.right.sidebar.right.panel.comment.composer.542bf6a7e2": { "ko": "기울임" }, + "auto.components.right.sidebar.source.control.ai.push.failure.launch.216f762bd7": { + "ko": "워크스페이스 연결을 확인할 수 없습니다." + }, + "auto.components.right.sidebar.source.control.ai.recovery.launch.216f762bd7": { + "ko": "워크스페이스 연결을 확인할 수 없습니다." + }, "auto.components.right.sidebar.source.control.discard.confirmation.2ae5a785b3": { "ko": "스테이징되지 않은 변경 사항을 모두 삭제하시겠습니까?" }, @@ -2321,6 +2342,12 @@ "auto.components.settings.IntegrationsPane.e74de656ce": { "ko": "glab auth login" }, + "auto.components.settings.LinearAgentSkillGuide.noteLinkedBody": { + "ko": "작업에서 만든 워크트리는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다." + }, + "auto.components.settings.LinearAgentSkillPane.howToUseDescription": { + "ko": "카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크트리에서 사용하세요." + }, "auto.components.settings.ManageSessionsSection.2896a50f50": { "ko": "terminal {{value0}}(으)로 이동" }, @@ -4082,6 +4109,9 @@ "auto.components.setup.guide.SetupGuideProgressRing.dac3a4724a": { "ko": "설정 단계 {{value1}}개 중 {{value0}}개 완료" }, + "auto.components.shared.useDaemonActions.a702d4196e": { + "ko": "이 작업은 모든 워크스페이스의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다." + }, "auto.components.shared.useDaemonActions.d18f3005c2": { "ko": "세션 {{value0}}개{{value1}}이(가) 종료를 거부했습니다." }, @@ -4151,6 +4181,9 @@ "auto.components.sidebar.DeleteWorktreeWarningPanels.c4f96a6e18": { "ko": "메인 워크트리" }, + "auto.components.sidebar.ForgetSshWorkspaceDialog.disconnectedBody": { + "ko": "이 워크스페이스의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요." + }, "auto.components.sidebar.HostRemoveDialog.1a2b3c4d5e": { "ko": "{{value0}} 제거됨" }, @@ -4172,6 +4205,15 @@ "auto.components.sidebar.HostRemoveDialog.8b9c0d1e2f": { "ko": "호스트 제거" }, + "auto.components.sidebar.HostRemoveDialog.manyWorkspaces": { + "ko": "워크스페이스 {{count}}개" + }, + "auto.components.sidebar.HostRemoveDialog.oneWorkspace": { + "ko": "워크스페이스 1개" + }, + "auto.components.sidebar.HostRemoveDialog.workspacesFailed": { + "ko": "이 호스트에서 워크스페이스 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다." + }, "auto.components.sidebar.HostRenameDialog.1a2b3c4d5e": { "ko": "호스트 이름 바꾸기" }, @@ -4341,7 +4383,7 @@ "ko": "고정" }, "auto.components.sidebar.WorktreeContextMenu.8d9cd19d09": { - "ko": "상위 워크스페이스 열기" + "ko": "상위 워크트리 열기" }, "auto.components.sidebar.WorktreeContextMenu.8dacff1fe0": { "ko": "읽음으로 표시" @@ -4361,6 +4403,9 @@ "auto.components.sidebar.WorktreeList.f94466bc39": { "ko": "그룹 삭제 후에도 {{value0}}/{{value1}} 프로젝트{{value2}}가 남아 있습니다." }, + "auto.components.sidebar.WorktreeList.failedUnnestWorkspace": { + "ko": "워크스페이스 펼치기 실패" + }, "auto.components.sidebar.WorktreeList.groupDeleteFailed": { "ko": "그룹을 삭제하지 못했습니다." }, @@ -4394,6 +4439,12 @@ "auto.components.sidebar.add.repo.local.start.actions.sshCreateUnavailable": { "ko": "아직 SSH 호스트에서는 사용할 수 없습니다." }, + "auto.components.sidebar.delete.worktree.toast.locked": { + "ko": "이 워크스페이스는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요." + }, + "auto.components.sidebar.delete.worktree.toast.lockedReason": { + "ko": "이 워크스페이스는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요." + }, "auto.components.sidebar.index.b826a98b6f": { "ko": "사용 중" }, @@ -4805,6 +4856,9 @@ "auto.components.tab.group.AiVaultSessionDropLayer.openLocalWorkspace": { "ko": "세션을 재개하기 전에 로컬 워크스페이스를 여세요." }, + "auto.components.tab.group.AiVaultSessionDropLayer.openSupportedWorkspace": { + "ko": "세션을 재개하기 전에 워크스페이스를 여세요." + }, "auto.components.tab.group.AiVaultSessionDropLayer.sessionQueued": { "ko": "세션이 대기열에 추가됨" }, @@ -4901,6 +4955,12 @@ "auto.components.terminal.pane.TerminalSessionStateSaveFailureDialog.6bee0c8f17": { "ko": "디스크 공간 분석기 열기" }, + "auto.components.terminal.pane.TerminalSshReconnectOverlay.removeWorkspaceButton": { + "ko": "워크스페이스 제거" + }, + "auto.components.terminal.pane.TerminalSshReconnectOverlay.removedBody": { + "ko": "이 워크스페이스의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크스페이스를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다." + }, "auto.components.terminal.quick.commands.TerminalQuickCommandAppendEnterSwitch.5fa607d807": { "ko": "Enter 추가" }, @@ -4973,6 +5033,9 @@ "auto.lib.projectSkillRuntime.wslUnavailable": { "ko": "이 스킬을 설치하려면 프로젝트 런타임에 WSL이 필요합니다." }, + "auto.lib.sidebarWorktreeActivation.wakeEphemeralVmFailed": { + "ko": "임시 VM 워크스페이스 활성화 실패" + }, "auto.lib.source.control.agent.action.plan.3f0ea9aa0d": { "ko": "agent 시작 명령을 만들 수 없습니다." }, diff --git a/config/scripts/locale-ko-key-overrides.test.mjs b/config/scripts/locale-ko-key-overrides.test.mjs index da98d401e544..4ab7f3ea451f 100644 --- a/config/scripts/locale-ko-key-overrides.test.mjs +++ b/config/scripts/locale-ko-key-overrides.test.mjs @@ -2,6 +2,156 @@ import fs from 'node:fs' import { describe, expect, it } from 'vitest' +import { + repairTranslatedValue, + repairCatalog, + setLeaf, + collectStringLeaves +} from './locale-translation-policy.mjs' + +const enCatalog = JSON.parse( + fs.readFileSync(new URL('../../src/renderer/src/i18n/locales/en.json', import.meta.url), 'utf8') +) +const koCatalog = JSON.parse( + fs.readFileSync(new URL('../../src/renderer/src/i18n/locales/ko.json', import.meta.url), 'utf8') +) +const enValues = new Map(collectStringLeaves(enCatalog).map(({ key, value }) => [key, value])) + +const workspaceTermCorrections = [ + { + key: 'auto.components.TaskPage.linearEmptyUnfilteredScope', + before: '이 워크트리 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요.', + expected: '이 워크스페이스 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요.' + }, + { + key: 'auto.components.floating.terminal.FloatingTerminalToggleButton.4cb418b991', + before: '플로팅 워크트리 표시, 새 활동', + expected: '플로팅 워크스페이스 표시, 새 활동' + }, + { + key: 'auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesBody', + before: + '상태, 담당자, 레이블 필터는 단일 Linear �크트리의 ID를 사용합니다. 필터링할 워크트리를 선택하세요.', + expected: + '상태, 담당자, 레이블 필터는 단일 Linear 워크스페이스의 ID를 사용합니다. 해당 속성으로 필터링할 워크스페이스 하나를 선택하세요.' + }, + { + key: 'auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesTitle', + before: '워크트리 선택', + expected: '워크스페이스 선택' + }, + { + key: 'auto.components.linear-issue-attribute-filter-dropdowns.teamRequired', + before: '이 워크트리의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요.', + expected: '이 워크스페이스의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요.' + }, + { + key: 'auto.components.right.sidebar.source.control.ai.push.failure.launch.216f762bd7', + before: '워크트리 연결을 확인할 수 없습니다.', + expected: '워크스페이스 연결을 확인할 수 없습니다.' + }, + { + key: 'auto.components.right.sidebar.source.control.ai.recovery.launch.216f762bd7', + before: '워크트리 연결을 확인할 수 없습니다.', + expected: '워크스페이스 연결을 확인할 수 없습니다.' + }, + { + key: 'auto.components.settings.LinearAgentSkillGuide.noteLinkedBody', + before: + '작업에서 만든 워크스페이스는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다.', + expected: + '작업에서 만든 워크트리는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다.' + }, + { + key: 'auto.components.settings.LinearAgentSkillPane.howToUseDescription', + before: + '카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크스페이스에서 사용하세요.', + expected: + '카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크트리에서 사용하세요.' + }, + { + key: 'auto.components.shared.useDaemonActions.a702d4196e', + before: + '이 작업은 모든 워크트리의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다.', + expected: + '이 작업은 모든 워크스페이스의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다.' + }, + { + key: 'auto.components.sidebar.ForgetSshWorkspaceDialog.disconnectedBody', + before: + '이 워크트리의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요.', + expected: + '이 워크스페이스의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요.' + }, + { + key: 'auto.components.sidebar.HostRemoveDialog.manyWorkspaces', + before: '워크트리 {{count}}개', + expected: '워크스페이스 {{count}}개' + }, + { + key: 'auto.components.sidebar.HostRemoveDialog.oneWorkspace', + before: '워크트리 1개', + expected: '워크스페이스 1개' + }, + { + key: 'auto.components.sidebar.HostRemoveDialog.workspacesFailed', + before: + '이 호스트에서 워크트리 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다.', + expected: + '이 호스트에서 워크스페이스 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다.' + }, + { + key: 'auto.components.sidebar.WorktreeContextMenu.8d9cd19d09', + before: '상위 워크스페이스 열기', + expected: '상위 워크트리 열기' + }, + { + key: 'auto.components.sidebar.WorktreeList.failedUnnestWorkspace', + before: '워크트리 펼치기 실패', + expected: '워크스페이스 펼치기 실패' + }, + { + key: 'auto.components.sidebar.delete.worktree.toast.locked', + before: + '이 워크트리는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.', + expected: + '이 워크스페이스는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.' + }, + { + key: 'auto.components.sidebar.delete.worktree.toast.lockedReason', + before: + '이 워크트리는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.', + expected: + '이 워크스페이스는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.' + }, + { + key: 'auto.components.tab.group.AiVaultSessionDropLayer.openSupportedWorkspace', + before: '세션을 재개하기 전에 워크트리를 여세요.', + expected: '세션을 재개하기 전에 워크스페이스를 여세요.' + }, + { + key: 'auto.components.terminal.pane.TerminalSshReconnectOverlay.removeWorkspaceButton', + before: '워크트리 제거', + expected: '워크스페이스 제거' + }, + { + key: 'auto.components.terminal.pane.TerminalSshReconnectOverlay.removedBody', + before: + '이 워크트리의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크트리를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다.', + expected: + '이 워크스페이스의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크스페이스를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다.' + }, + { + key: 'auto.lib.sidebarWorktreeActivation.wakeEphemeralVmFailed', + before: '임시 VM 워크트리 활성화 실패', + expected: '임시 VM 워크스페이스 활성화 실패' + } +] + +function placeholders(value) { + return (value.match(/{{[^{}]+}}/g) ?? []).sort() +} + describe('locale-ko-key-overrides', () => { it('keeps Korean key override data scoped to Korean values', () => { const overrides = JSON.parse( @@ -11,4 +161,75 @@ describe('locale-ko-key-overrides', () => { expect(Object.keys(value)).toEqual(['ko']) } }) + + it('repairs the 22 Korean workspace/worktree object mismatches', () => { + for (const { key, before, expected } of workspaceTermCorrections) { + const enValue = enValues.get(key) + expect(enValue, key).toBeTypeOf('string') + expect(repairTranslatedValue({ key, enValue, localeValue: before, locale: 'ko' }), key).toBe( + expected + ) + } + }) + + it('keeps corrected Korean workspace/worktree values stable', () => { + for (const { key, expected } of workspaceTermCorrections) { + const enValue = enValues.get(key) + const first = repairTranslatedValue({ key, enValue, localeValue: expected, locale: 'ko' }) + expect(first, key).toBe(expected) + expect(repairTranslatedValue({ key, enValue, localeValue: first, locale: 'ko' }), key).toBe( + expected + ) + expect(repairTranslatedValue({ key, enValue, localeValue: enValue, locale: 'ko' }), key).toBe( + expected + ) + } + }) + + it('preserves all 22 terms through catalog repair', () => { + const catalog = structuredClone(koCatalog) + for (const { key, before } of workspaceTermCorrections) { + setLeaf(catalog, key, before) + } + for (let pass = 0; pass < 2; pass += 1) { + repairCatalog(enCatalog, catalog, 'ko') + const repaired = new Map(collectStringLeaves(catalog).map(({ key, value }) => [key, value])) + for (const { key, expected } of workspaceTermCorrections) { + expect(repaired.get(key), key).toBe(expected) + } + } + + const shippedCatalog = structuredClone(koCatalog) + repairCatalog(enCatalog, shippedCatalog, 'ko') + const shipped = new Map( + collectStringLeaves(shippedCatalog).map(({ key, value }) => [key, value]) + ) + for (const { key, expected } of workspaceTermCorrections) { + expect(shipped.get(key), key).toBe(expected) + } + }) + + it('preserves placeholders and Git unlock command literals', () => { + for (const { key, before, expected } of workspaceTermCorrections) { + const enValue = enValues.get(key) + const repaired = repairTranslatedValue({ key, enValue, localeValue: before, locale: 'ko' }) + const tokens = placeholders(enValue) + for (const value of [before, expected, repaired]) { + expect(placeholders(value), key).toEqual(tokens) + } + + if (key.startsWith('auto.components.sidebar.delete.worktree.toast.locked')) { + for (const value of [enValue, before, expected, repaired]) { + expect(value, key).toContain('git worktree unlock ') + if (key.endsWith('lockedReason')) { + expect(value, key).toContain('{{value0}}') + } + } + } + if (key === 'auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesBody') { + expect(expected, key).not.toContain('\uFFFD') + expect(repaired, key).not.toContain('\uFFFD') + } + } + }) }) diff --git a/src/renderer/src/i18n/ko-ui-semantic-mistranslations.test.ts b/src/renderer/src/i18n/ko-ui-semantic-mistranslations.test.ts index 437bcd9102bb..072198edda63 100644 --- a/src/renderer/src/i18n/ko-ui-semantic-mistranslations.test.ts +++ b/src/renderer/src/i18n/ko-ui-semantic-mistranslations.test.ts @@ -4,6 +4,44 @@ import { describe, expect, it } from 'vitest' import ko from './locales/ko.json' const correctedValues = { + 'auto.components.TaskPage.linearEmptyUnfilteredScope': + '이 워크스페이스 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요.', + 'auto.components.floating.terminal.FloatingTerminalToggleButton.4cb418b991': + '플로팅 워크스페이스 표시, 새 활동', + 'auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesBody': + '상태, 담당자, 레이블 필터는 단일 Linear 워크스페이스의 ID를 사용합니다. 해당 속성으로 필터링할 워크스페이스 하나를 선택하세요.', + 'auto.components.linear-issue-attribute-filter-dropdowns.allWorkspacesTitle': '워크스페이스 선택', + 'auto.components.linear-issue-attribute-filter-dropdowns.teamRequired': + '이 워크스페이스의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요.', + 'auto.components.right.sidebar.source.control.ai.push.failure.launch.216f762bd7': + '워크스페이스 연결을 확인할 수 없습니다.', + 'auto.components.right.sidebar.source.control.ai.recovery.launch.216f762bd7': + '워크스페이스 연결을 확인할 수 없습니다.', + 'auto.components.settings.LinearAgentSkillGuide.noteLinkedBody': + '작업에서 만든 워크트리는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다.', + 'auto.components.settings.LinearAgentSkillPane.howToUseDescription': + '카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크트리에서 사용하세요.', + 'auto.components.shared.useDaemonActions.a702d4196e': + '이 작업은 모든 워크스페이스의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다.', + 'auto.components.sidebar.ForgetSshWorkspaceDialog.disconnectedBody': + '이 워크스페이스의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요.', + 'auto.components.sidebar.HostRemoveDialog.manyWorkspaces': '워크스페이스 {{count}}개', + 'auto.components.sidebar.HostRemoveDialog.oneWorkspace': '워크스페이스 1개', + 'auto.components.sidebar.HostRemoveDialog.workspacesFailed': + '이 호스트에서 워크스페이스 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다.', + 'auto.components.sidebar.WorktreeContextMenu.8d9cd19d09': '상위 워크트리 열기', + 'auto.components.sidebar.WorktreeList.failedUnnestWorkspace': '워크스페이스 펼치기 실패', + 'auto.components.sidebar.delete.worktree.toast.locked': + '이 워크스페이스는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.', + 'auto.components.sidebar.delete.worktree.toast.lockedReason': + '이 워크스페이스는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.', + 'auto.components.tab.group.AiVaultSessionDropLayer.openSupportedWorkspace': + '세션을 재개하기 전에 워크스페이스를 여세요.', + 'auto.components.terminal.pane.TerminalSshReconnectOverlay.removeWorkspaceButton': + '워크스페이스 제거', + 'auto.components.terminal.pane.TerminalSshReconnectOverlay.removedBody': + '이 워크스페이스의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크스페이스를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다.', + 'auto.lib.sidebarWorktreeActivation.wakeEphemeralVmFailed': '임시 VM 워크스페이스 활성화 실패', 'auto.components.settings.AutoRenameBranchFromWorkSetting.d9b65054ef': ') 작업을 요약하는 짧은 이름으로 변경됩니다. Orca가 직접 이름 붙인 브랜치만 이름을 바꾸며, 푸시된 후에는 이름을 바꾸지 않습니다.', 'auto.components.settings.source.control.action.recipe.options.commitMessage': diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index a503c3347d81..897a0adbe2d1 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -791,7 +791,7 @@ "wslDefault": "WSL 기본값" }, "sidebarWorktreeActivation": { - "wakeEphemeralVmFailed": "임시 VM 워크트리 활성화 실패" + "wakeEphemeralVmFailed": "임시 VM 워크스페이스 활성화 실패" }, "ephemeralVmWorkspaceTarget": { "projectRootRegistrationFailed": "런타임에서 레시피로 생성된 프로젝트 루트 등록 실패", @@ -2181,7 +2181,7 @@ "noMatchingIssuesLoaded": "일치하는 이슈를 불러오지 않았습니다.", "editReviewersWithCurrent": "리뷰어 편집: {{value0}}", "linearEmptyAttributeFilter": "선택한 필터와 일치하는 이슈가 없습니다. 필터를 지우거나 다른 조건을 시도하세요.", - "linearEmptyUnfilteredScope": "이 워크트리 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요.", + "linearEmptyUnfilteredScope": "이 워크스페이스 범위에 이슈가 없습니다. 검색하거나 팀을 조정해 보세요.", "linearFetchMore": "더 불러오기", "linearHasWorktreeLoadFailed": "Orca 워크스페이스에 연결된 Linear 이슈를 불러올 수 없습니다.", "linearHasWorktreePartialLoadFailed": "Orca 워크스페이스에 연결된 일부 Linear 이슈를 불러올 수 없습니다. 새로 고쳐 다시 시도하세요.", @@ -3234,8 +3234,8 @@ "connectingButton": "연결 중...", "connectButton": "연결", "removedTitle": "SSH 호스트가 제거됨", - "removedBody": "이 워크트리의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크트리를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다.", - "removeWorkspaceButton": "워크트리 제거" + "removedBody": "이 워크스페이스의 SSH 호스트가 제거되어 더 이상 연결할 수 없습니다. 워크스페이스를 제거하여 정리하세요 — 원격 파일은 그대로 남아 있습니다.", + "removeWorkspaceButton": "워크스페이스 제거" }, "TerminalRemoteRuntimeReconnectBanner": { "retryingTitle": "원격 런타임에 다시 연결 중", @@ -3294,7 +3294,7 @@ "localWorkspacesOnly": "기록에서 재개하기는 로컬 워크스페이스에서만 사용할 수 있습니다.", "openLocalWorkspace": "세션을 재개하기 전에 로컬 워크스페이스를 여세요.", "sessionQueued": "세션이 대기열에 추가됨", - "openSupportedWorkspace": "세션을 재개하기 전에 워크트리를 여세요.", + "openSupportedWorkspace": "세션을 재개하기 전에 워크스페이스를 여세요.", "localSessionSshWorkspaceUnsupported": "이 세션의 기록은 이 컴퓨터에 저장되어 있어 SSH 워크스페이스에서는 재개할 수 없습니다. 대신 로컬 워크스페이스에 놓으세요.", "sessionHostMismatchUnsupported": "이 세션은 다른 호스트에 속합니다. 같은 호스트의 워크스페이스에 놓으세요." }, @@ -5553,7 +5553,7 @@ "e091caab15": "프로젝트를 찾을 수 없습니다.", "439fa94d53": "업데이트", "579b1a8e61": "상위에서 제거", - "8d9cd19d09": "상위 워크스페이스 열기", + "8d9cd19d09": "상위 워크트리 열기", "d35dfeae58": "그룹에서 제거", "76865d827f": "그룹으로 이동", "503ec0f8e6": "프로젝트의 새 그룹", @@ -5622,7 +5622,7 @@ "hostDisconnected": "연결 끊김", "failedNestWorkspace": "워크스페이스를 중첩하지 못했습니다", "sidebarRowMissing": "대상이 더 이상 존재하지 않습니다", - "failedUnnestWorkspace": "워크트리 펼치기 실패", + "failedUnnestWorkspace": "워크스페이스 펼치기 실패", "groupRenameFailed": "그룹 이름을 바꾸지 못했습니다.", "groupRenameFailedDesc": "Orca는 그룹 호스트에게 새 이름을 확인할 수 없습니다. 다시 연결한 후 그룹을 다시 확인하세요." }, @@ -5784,8 +5784,8 @@ "ead7b8ee15": "파일이 변경되었습니다. 어쨌든 삭제하려면 강제 삭제를 사용하세요.", "905fc8efac": "Git은 이미 이 워크스페이스를 제거했습니다. 강제 삭제를 사용하여 Orca에서 삭제합니다.", "0899ebdb28": "Git은 이미 이 워크스페이스를 잊어버렸지만 해당 디렉터리는 여전히 디스크에 있습니다. 강제 삭제를 사용하여 분리된 디렉터리를 제거합니다.", - "locked": "이 워크트리는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.", - "lockedReason": "이 워크트리는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.", + "locked": "이 워크스페이스는 Git에 의해 잠겨 있습니다. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.", + "lockedReason": "이 워크스페이스는 Git에 의해 잠겨 있습니다. Git 보고: {{value0}}. 저장소에서 git worktree unlock 을 실행한 후 삭제를 다시 시도하세요.", "unstoppedPty": "Orca는 이 워크스페이스의 모든 터미널이 종료되었는지 확인할 수 없어 파일을 삭제하기 전에 중지되었습니다. 어쨌든 제거하려면 강제 삭제를 사용하십시오.", "unstoppedPtyLive": "이 워크스페이스에는 여전히 실행 중인 터미널이 있으므로 Orca는 파일을 삭제하기 전에 중지되었습니다. 강제 삭제는 해당 작업을 종료하고 해당 작업에 포함된 커밋되지 않은 작업을 모두 삭제합니다.", "runningAgentSession": "Orca는 이 워크스페이스의 모든 에이전트 세션이 닫혔는지 확인할 수 없어 파일을 삭제하기 전에 중지되었습니다. 어쨌든 제거하려면 강제 삭제를 사용하십시오.", @@ -6025,9 +6025,9 @@ "6f7a8b9c0d": "취소", "7a8b9c0d1e": "설정 열기", "8b9c0d1e2f": "호스트 제거", - "workspacesFailed": "이 호스트에서 워크트리 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다.", - "oneWorkspace": "워크트리 1개", - "manyWorkspaces": "워크트리 {{count}}개", + "workspacesFailed": "이 호스트에서 워크스페이스 {{count}}개를 제거할 수 없었습니다. 재시도할 수 있도록 호스트가 유지되었습니다.", + "oneWorkspace": "워크스페이스 1개", + "manyWorkspaces": "워크스페이스 {{count}}개", "hostHasWorkspacesDefault": "이 컴퓨터에서 {{value0}}과(와) 해당 자격 증명을 제거합니다. {{value1}}은(는) Orca에 남아 있습니다 — 원격 파일은 변경되지 않습니다.", "alsoDeleteRemote": "{{value1}}에서 이러한 {{value0}}도 삭제", "alsoForgetLocal": "Orca에서 이러한 {{value0}}도 제거", @@ -6187,7 +6187,7 @@ "reconnectFailed": "재연결 실패", "forgetBody": "이 작업 공간을 Orca에서만 제거합니다. 파일, Git 워크트리, {{host}}의 브랜치는 그대로 유지됩니다.", "title": "Delete “{{name}}”?", - "disconnectedBody": "이 워크트리의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요.", + "disconnectedBody": "이 워크스페이스의 SSH 호스트가 연결되어 있지 않습니다. 재연결하여 원격에서도 삭제하거나 Orca에서만 제거하세요.", "ghostBody": "{{host}}은(는) 더 이상 저장된 SSH 호스트가 아니므로 이 워크스페이스는 라이브 호스트에 연결되어 있지 않습니다. Orca에서 제거만 할 수 있으며, 원격의 파일과 브랜치는 그대로 유지됩니다.", "cancel": "취소", "forget": "Orca에서 제거", @@ -6338,7 +6338,7 @@ "c34fb1098d": "터미널 탭이 닫히고 종료 요청이 전송되었습니다.", "d9657ac204": "터미널 세션 종료 요청이 전송되었습니다.", "e8f25bd903": "터미널 정리를 완료할 수 없습니다.", - "a702d4196e": "이 작업은 모든 워크트리의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다.", + "a702d4196e": "이 작업은 모든 워크스페이스의 모든 터미널 탭을 닫고 현재 터미널 세션의 종료를 요청합니다. 저장되지 않은 터미널 작업은 손실됩니다. 데몬 자체는 계속 실행되며 새 터미널은 즉시 열 수 있습니다. 이 작업은 되돌릴 수 없습니다.", "01d6b7c64e": "열린 터미널과 에이전트가 다시 시작됩니다. 원격 호스트의 터미널은 영향을 받지 않습니다.", "922548bc66": "터미널 서비스를 다시 시작하시겠습니까?" }, @@ -11316,7 +11316,7 @@ "description": "Orca에서 Linear 이슈를 탐색하고 연결된 워크스페이스를 시작하며 /orca-linear로 에이전트가 이슈를 업데이트할 수 있습니다.", "skillTitle": "Linear 스킬", "howToUse": "프롬프트 예시", - "howToUseDescription": "카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크스페이스에서 사용하세요.", + "howToUseDescription": "카드를 클릭해 프롬프트를 복사하세요. 스킬을 설치한 후 Linear에 연결된 워크트리에서 사용하세요.", "terminalTitle": "Linear 스킬 설정", "terminalAriaLabel": "Linear 스킬 설치 터미널", "manageConnectionHint": "연결된 Linear 워크스페이스와 API 키는 다음에서 확인할 수 있습니다.", @@ -11658,7 +11658,7 @@ "notesTitle": "알아두면 좋은 점", "notesIntro": "Linear를 연결하고 스킬을 설치한 후 참고할 내용입니다.", "noteLinkedTitle": "Linear 이슈에서 시작", - "noteLinkedBody": "작업에서 만든 워크스페이스는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다.", + "noteLinkedBody": "작업에서 만든 워크트리는 이슈가 컨텍스트로 연결되어 있어 이슈 작업이 가장 원활합니다.", "noteSlashTitle": "/orca-linear 언급", "noteSlashBody": "채팅에서 /orca-linear를 사용하거나 자연어로 요청하면 해당 턴에 에이전트가 스킬을 불러옵니다.", "noteKeysTitle": "키는 런타임별로 저장", @@ -12996,7 +12996,7 @@ "push": { "failure": { "launch": { - "216f762bd7": "워크트리 연결을 확인할 수 없습니다.", + "216f762bd7": "워크스페이스 연결을 확인할 수 없습니다.", "4f4e0418a0": "에이전트 프롬프트를 구성할 수 없습니다.", "f2b47026e8": "푸시 실패 프롬프트가 비어 있습니다. 소스 컨트롤 AI 설정을 업데이트하세요.", "d481ab22f9": "저장된 AI 에이전트를 사용할 수 없습니다. 사용자 지정 시작에서 다른 에이전트를 선택하세요.", @@ -13018,7 +13018,7 @@ "d481ab22f9": "저장된 AI 에이전트를 사용할 수 없습니다. 사용자 지정 시작에서 다른 에이전트를 선택하세요.", "9bbd9077a2": "활성화된 AI 에이전트가 없습니다. 설정에서 에이전트를 구성하세요.", "5540ff50cc": "에이전트 시작 명령을 구성할 수 없습니다.", - "216f762bd7": "워크트리 연결을 확인할 수 없습니다.", + "216f762bd7": "워크스페이스 연결을 확인할 수 없습니다.", "success": "{{value0}} 실패에 대한 AI 에이전트가 시작되었습니다." } } @@ -14165,7 +14165,7 @@ }, "FloatingTerminalToggleButton": { "3b04b065b5": "플로팅 워크스페이스 표시", - "4cb418b991": "플로팅 워크트리 표시, 새 활동", + "4cb418b991": "플로팅 워크스페이스 표시, 새 활동", "5785dd9148": "플로팅 워크스페이스 최소화", "bfe7809a70": "{{value0}} 플로팅 워크스페이스({{value1}})" }, @@ -16888,10 +16888,10 @@ }, "linear-issue-attribute-filter-dropdowns": { "removeFilter": "{{value0}} 필터 제거", - "teamRequired": "이 워크트리의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요.", + "teamRequired": "이 워크스페이스의 상태, 담당자, 레이블을 로드하려면 팀을 선택하세요.", "filters": "필터", - "allWorkspacesTitle": "워크트리 선택", - "allWorkspacesBody": "상태, 담당자, 레이블 필터는 단일 Linear �크트리의 ID를 사용합니다. 필터링할 워크트리를 선택하세요.", + "allWorkspacesTitle": "워크스페이스 선택", + "allWorkspacesBody": "상태, 담당자, 레이블 필터는 단일 Linear 워크스페이스의 ID를 사용합니다. 해당 속성으로 필터링할 워크스페이스 하나를 선택하세요.", "optionsFromTeam": "{{team}}의 옵션", "clearAll": "모든 필터 지우기", "partialCoverage": "부분 연결",