From 60ba6c2a2d037517f8067f8458a571f5247c1e5a Mon Sep 17 00:00:00 2001 From: 5Hyeons Date: Wed, 5 Aug 2026 20:42:25 +0900 Subject: [PATCH 1/4] fix(i18n): localize the remaining contextual tour steps The automations fix only routed its own two steps through translate(), so every other tour still rendered raw English titles and bodies next to already-localized Next/Back/Done controls. Give every step a stable id and move the copy lookup into one module keyed by that id, so a new step is localized by construction and a coverage test fails when it is not. --- config/scripts/locale-ko-key-overrides.json | 93 +++++++++ .../contextual-tour-overlay-measurement.ts | 46 +---- .../contextual-tour-step-copy.test.ts | 42 ++++ .../contextual-tour-step-copy.ts | 195 ++++++++++++++++++ src/renderer/src/i18n/locales/en.json | 83 ++++++++ src/renderer/src/i18n/locales/ko.json | 83 ++++++++ src/shared/contextual-tours.ts | 15 ++ 7 files changed, 519 insertions(+), 38 deletions(-) create mode 100644 src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts create mode 100644 src/renderer/src/components/contextual-tours/contextual-tour-step-copy.ts diff --git a/config/scripts/locale-ko-key-overrides.json b/config/scripts/locale-ko-key-overrides.json index e8d13941ffaa..15252e168e42 100644 --- a/config/scripts/locale-ko-key-overrides.json +++ b/config/scripts/locale-ko-key-overrides.json @@ -5089,5 +5089,98 @@ }, "auto.components.right.sidebar.AiVaultPanel.noAgentsSelected": { "ko": "선택된 에이전트가 없습니다" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.parallel.body": { + "ko": "워크트리마다 자체 브랜치를 가지므로 병렬로 진행하는 작업이 서로 섞이지 않습니다." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.parallel.title": { + "ko": "다른 작업을 병렬로 시작하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.action": { + "ko": "Terminal 분할" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.body": { + "ko": "{terminal.splitRight} 키로 두 번째 Terminal 창을 열거나, 창을 우클릭해 분할 옵션을 확인하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.title": { + "ko": "Terminal 창 분할" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.annotate.body": { + "ko": "요소에 주석을 달고 그 메모를 agent에 보내세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.annotate.title": { + "ko": "디자인 피드백을 화면에 바로 남기기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.grab.body": { + "ko": "grab 도구로 페이지 요소의 컨텍스트를 복사해 agent에 전달하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.grab.title": { + "ko": "agent를 위한 페이지 컨텍스트 가져오기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.logins.body": { + "ko": "기존 로그인 정보를 Orca로 가져와 바로 로그인 상태를 유지하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.browser.logins.title": { + "ko": "로그인 상태 유지" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.body": { + "ko": "여기의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.title": { + "ko": "모든 repo에서 agent 실행하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.body": { + "ko": "집중하고 있는 워크트리를 어지럽히지 않고 agent, 임시 Terminal, 노트, 브라우저 탭을 열 수 있습니다." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.title": { + "ko": "스크래치패드로도 사용하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.filter.body": { + "ko": "프리셋과 검색으로 이슈, 리뷰, merge requests, 작업의 범위를 좁히세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.filter.title": { + "ko": "필요한 작업만 필터링하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.source.body": { + "ko": "페이지를 이동하지 않고 연결된 제공자와 프로젝트 필터를 전환하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.source.title": { + "ko": "작업 소스 선택" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.start.body": { + "ko": "작업, 이슈, 리뷰, merge request에서 시작 또는 열기를 눌러 해당 컨텍스트를 워크스페이스로 가져오세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.tasks.start.title": { + "ko": "작업 항목에서 시작하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.lanes.body": { + "ko": "상태가 바뀌면 워크스페이스를 레인 사이로 끌어다 놓으세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.lanes.title": { + "ko": "레인을 따라 작업 옮기기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.plan.body": { + "ko": "프로젝트별이 아니라 상태별로 워크스페이스를 보고 싶을 때 보드를 사용하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.plan.title": { + "ko": "보드에서 작업 계획하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.agent.body": { + "ko": "이 워크트리가 생성될 때 열릴 agent를 선택하세요." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.agent.title": { + "ko": "작업을 시작할 agent 선택" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.name.body": { + "ko": "연결된 작업에서 시작하면 짧은 이슈나 PR 이름을 사용합니다. 비워 두면 첫 agent 메시지에서 이름이 자동으로 지정됩니다." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.name.title": { + "ko": "이름을 정하거나 기존 작업에서 시작하기" + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.project.body": { + "ko": "Orca는 각 작업을 기준 브랜치에서 분기한 자체 워크트리로 분리합니다." + }, + "auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.project.title": { + "ko": "프로젝트 선택" } } diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.ts b/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.ts index 1fe945a42cbf..ce27baa9e773 100644 --- a/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.ts +++ b/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.ts @@ -11,6 +11,7 @@ import { getVisibleContextualTourStepIndexes } from './contextual-tour-gate' import type { ActiveTourRenderState } from './ContextualTourOverlaySurface' +import { getLocalizedContextualTourStepCopy } from './contextual-tour-step-copy' import { translate } from '@/i18n/i18n' export type ContextualTourMeasurementAction = @@ -28,36 +29,6 @@ export type ContextualTourOverlayMeasurementResult = telemetryTotalSteps: number } -// Why: keyed by the step's stable id, not its position — inserting a step must -// not shift localized copy onto a neighbour. Thunks keep translate() out of -// module scope so the lookup resolves in the language active at render time. -const LOCALIZED_STEP_COPY: Record string; body: () => string }> = { - 'automations-intro': { - title: () => - translate( - 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.intro.title', - 'What is an automation?' - ), - body: () => - translate( - 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.intro.body', - 'Automations run agent work on a schedule. Add an automation by clicking this button.' - ) - }, - 'automations-results': { - title: () => - translate( - 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.results.title', - 'Find the results' - ), - body: () => - translate( - 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.results.body', - 'Runs show when automations ran, what happened, and where to inspect their output.' - ) - } -} - export function getContextualTourDisplayProgress(args: { tour: ContextualTour visibleStepIndexes: readonly number[] @@ -119,13 +90,10 @@ export function measureContextualTourOverlayRenderState(args: { ) const activeStep = args.tour.steps[args.activeStepIndex] const target = activeStep ? getMeasurableContextualTourTarget(activeStep.targetSelector) : null - const localizedCopy = activeStep?.id ? LOCALIZED_STEP_COPY[activeStep.id] : undefined - const localizedTitle = localizedCopy ? localizedCopy.title() : activeStep?.title - const localizedBody = localizedCopy - ? localizedCopy.body() - : activeStep - ? getContextualTourStepCopy(activeStep) - : undefined + const localizedCopy = getLocalizedContextualTourStepCopy(activeStep?.id) + const localizedTitle = localizedCopy?.title ?? activeStep?.title + const localizedBody = + localizedCopy?.body ?? (activeStep ? getContextualTourStepCopy(activeStep) : undefined) const progress = getContextualTourDisplayProgress({ tour: args.tour, visibleStepIndexes, @@ -162,7 +130,9 @@ export function measureContextualTourOverlayRenderState(args: { 'Next' ) } as const) - : activeStep.primaryAction + : activeStep.primaryAction && localizedCopy?.primaryActionLabel + ? { ...activeStep.primaryAction, label: localizedCopy.primaryActionLabel } + : activeStep.primaryAction const secondaryAction = sidebarAlreadyVisible ? undefined : activeStep.secondaryAction return { diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts new file mode 100644 index 000000000000..aca338ec63b2 --- /dev/null +++ b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts @@ -0,0 +1,42 @@ +// @vitest-environment happy-dom + +import { afterEach, describe, expect, it } from 'vitest' +import { CONTEXTUAL_TOURS, type ContextualTour } from '../../../../shared/contextual-tours' +import { setRendererUiLanguage } from '@/i18n/i18n' +import { getLocalizedContextualTourStepCopy } from './contextual-tour-step-copy' + +afterEach(async () => { + await setRendererUiLanguage('en') +}) + +describe('contextual tour step copy', () => { + it('translates every tour step, so no step falls back to English mid-tour', async () => { + await setRendererUiLanguage('ko') + + for (const tour of CONTEXTUAL_TOURS as readonly ContextualTour[]) { + for (const step of tour.steps) { + const copy = getLocalizedContextualTourStepCopy(step.id) + expect(copy, `${tour.id} step "${step.title}" has no localized copy`).toBeDefined() + expect(copy?.title).not.toBe(step.title) + expect(copy?.body).not.toBe(step.body) + if (step.primaryAction) { + expect(copy?.primaryActionLabel).not.toBe(step.primaryAction.label) + } + } + } + }) + + it('renders the floating workspace copy in Korean', async () => { + await setRendererUiLanguage('ko') + + expect(getLocalizedContextualTourStepCopy('floating-workspace-scratchpad')?.title).toBe( + '스크래치패드로도 사용하기' + ) + }) + + it('falls back to English copy for the active locale', () => { + expect(getLocalizedContextualTourStepCopy('floating-workspace-repos')?.title).toBe( + 'Run an agent across every repo' + ) + }) +}) diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.ts b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.ts new file mode 100644 index 000000000000..b574285ed04e --- /dev/null +++ b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.ts @@ -0,0 +1,195 @@ +import { translate } from '@/i18n/i18n' + +export type LocalizedContextualTourStepCopy = { + title: string + body: string + primaryActionLabel?: string +} + +// Automations keys are unchanged from the original fix so its shipped translations still resolve. + +// Why: keyed by the step's stable id, not its position — inserting a step must +// not shift localized copy onto a neighbour. Thunks keep translate() out of +// module scope so the lookup resolves in the language active at render time. +const LOCALIZED_STEP_COPY: Record LocalizedContextualTourStepCopy> = { + 'workspace-board-plan': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.plan.title', + 'Plan work on the board' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.plan.body', + 'Use the board when you want to see workspaces by status instead of by project.' + ) + }), + 'workspace-board-lanes': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.lanes.title', + 'Move work through lanes' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.board.lanes.body', + 'Drag workspaces between lanes as their status changes.' + ) + }), + 'agent-sessions-split': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.title', + 'Split a terminal pane' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.body', + 'Open a second terminal pane with {terminal.splitRight}, or right-click the pane for split options.' + ), + primaryActionLabel: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.split.action', + 'Split terminal' + ) + }), + 'agent-sessions-parallel': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.parallel.title', + 'Start another task in parallel' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.agent.sessions.parallel.body', + 'Each worktree gets its own branch, so parallel work stays separate.' + ) + }), + 'browser-grab': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.grab.title', + 'Grab page context for agents' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.grab.body', + "Use the grab tool to copy a page element's context for agents." + ) + }), + 'browser-annotate': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.annotate.title', + 'Mark design feedback in place' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.annotate.body', + 'Annotate elements and send those notes to an agent.' + ) + }), + 'browser-logins': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.logins.title', + 'Stay logged in' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.browser.logins.body', + 'Bring your existing logins into Orca to stay signed in immediately.' + ) + }), + 'tasks-source': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.source.title', + 'Choose the work source' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.source.body', + 'Switch between connected providers and project filters without changing pages.' + ) + }), + 'tasks-filter': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.filter.title', + 'Filter to the work you need' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.filter.body', + 'Use presets and search to narrow issues, reviews, merge requests, or tasks.' + ) + }), + 'tasks-start': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.start.title', + 'Start from work items' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.tasks.start.body', + 'Use Start or Open on a task, issue, review, or merge request to bring its context into a workspace.' + ) + }), + 'automations-intro': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.intro.title', + 'What is an automation?' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.intro.body', + 'Automations run agent work on a schedule. Add an automation by clicking this button.' + ) + }), + 'automations-results': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.results.title', + 'Find the results' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.overlay.measurement.automations.results.body', + 'Runs show when automations ran, what happened, and where to inspect their output.' + ) + }), + 'floating-workspace-repos': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.title', + 'Run an agent across every repo' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.body', + 'Agents here run in any folder you choose. Point one at the directory above your services to work across all your repos at once.' + ) + }), + 'floating-workspace-scratchpad': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.title', + 'Or use it as a scratchpad' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.body', + 'Open agents, scratch terminals, notes, and browser tabs without cluttering the worktree you’re focused on.' + ) + }), + 'workspace-creation-project': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.project.title', + 'Pick a project' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.project.body', + 'Orca isolates each task in its own worktree, branched off your base.' + ) + }), + 'workspace-creation-name': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.name.title', + 'Name it, or start from existing work' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.name.body', + 'Start from a linked task for a short issue or PR name. Or leave it blank to auto-name it from your first agent message.' + ) + }), + 'workspace-creation-agent': () => ({ + title: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.agent.title', + 'Choose what agent starts the work' + ), + body: translate( + 'auto.components.contextual.tours.contextual.tour.step.copy.workspace.creation.agent.body', + 'Pick the agent that should be opened when this worktree is created.' + ) + }) +} + +export function getLocalizedContextualTourStepCopy( + stepId: string | undefined +): LocalizedContextualTourStepCopy | undefined { + return stepId ? LOCALIZED_STEP_COPY[stepId]?.() : undefined +} diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 996d7138ea06..f8aa67838386 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -13599,6 +13599,89 @@ } } } + }, + "step": { + "copy": { + "workspace": { + "board": { + "plan": { + "title": "Plan work on the board", + "body": "Use the board when you want to see workspaces by status instead of by project." + }, + "lanes": { + "title": "Move work through lanes", + "body": "Drag workspaces between lanes as their status changes." + } + }, + "creation": { + "project": { + "title": "Pick a project", + "body": "Orca isolates each task in its own worktree, branched off your base." + }, + "name": { + "title": "Name it, or start from existing work", + "body": "Start from a linked task for a short issue or PR name. Or leave it blank to auto-name it from your first agent message." + }, + "agent": { + "title": "Choose what agent starts the work", + "body": "Pick the agent that should be opened when this worktree is created." + } + } + }, + "agent": { + "sessions": { + "split": { + "title": "Split a terminal pane", + "body": "Open a second terminal pane with {terminal.splitRight}, or right-click the pane for split options.", + "action": "Split terminal" + }, + "parallel": { + "title": "Start another task in parallel", + "body": "Each worktree gets its own branch, so parallel work stays separate." + } + } + }, + "browser": { + "grab": { + "title": "Grab page context for agents", + "body": "Use the grab tool to copy a page element's context for agents." + }, + "annotate": { + "title": "Mark design feedback in place", + "body": "Annotate elements and send those notes to an agent." + }, + "logins": { + "title": "Stay logged in", + "body": "Bring your existing logins into Orca to stay signed in immediately." + } + }, + "tasks": { + "source": { + "title": "Choose the work source", + "body": "Switch between connected providers and project filters without changing pages." + }, + "filter": { + "title": "Filter to the work you need", + "body": "Use presets and search to narrow issues, reviews, merge requests, or tasks." + }, + "start": { + "title": "Start from work items", + "body": "Use Start or Open on a task, issue, review, or merge request to bring its context into a workspace." + } + }, + "floating": { + "workspace": { + "repos": { + "title": "Run an agent across every repo", + "body": "Agents here run in any folder you choose. Point one at the directory above your services to work across all your repos at once." + }, + "scratchpad": { + "title": "Or use it as a scratchpad", + "body": "Open agents, scratch terminals, notes, and browser tabs without cluttering the worktree you’re focused on." + } + } + } + } } } } diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index bb5bbc4b4da9..5a02ff99f7cb 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -13329,6 +13329,89 @@ } } } + }, + "step": { + "copy": { + "workspace": { + "board": { + "plan": { + "title": "보드에서 작업 계획하기", + "body": "프로젝트별이 아니라 상태별로 워크스페이스를 보고 싶을 때 보드를 사용하세요." + }, + "lanes": { + "title": "레인을 따라 작업 옮기기", + "body": "상태가 바뀌면 워크스페이스를 레인 사이로 끌어다 놓으세요." + } + }, + "creation": { + "project": { + "title": "프로젝트 선택", + "body": "Orca는 각 작업을 기준 브랜치에서 분기한 자체 워크트리로 분리합니다." + }, + "name": { + "title": "이름을 정하거나 기존 작업에서 시작하기", + "body": "연결된 작업에서 시작하면 짧은 이슈나 PR 이름을 사용합니다. 비워 두면 첫 agent 메시지에서 이름이 자동으로 지정됩니다." + }, + "agent": { + "title": "작업을 시작할 agent 선택", + "body": "이 워크트리가 생성될 때 열릴 agent를 선택하세요." + } + } + }, + "agent": { + "sessions": { + "split": { + "title": "Terminal 창 분할", + "body": "{terminal.splitRight} 키로 두 번째 Terminal 창을 열거나, 창을 우클릭해 분할 옵션을 확인하세요.", + "action": "Terminal 분할" + }, + "parallel": { + "title": "다른 작업을 병렬로 시작하기", + "body": "워크트리마다 자체 브랜치를 가지므로 병렬로 진행하는 작업이 서로 섞이지 않습니다." + } + } + }, + "browser": { + "grab": { + "title": "agent를 위한 페이지 컨텍스트 가져오기", + "body": "grab 도구로 페이지 요소의 컨텍스트를 복사해 agent에 전달하세요." + }, + "annotate": { + "title": "디자인 피드백을 화면에 바로 남기기", + "body": "요소에 주석을 달고 그 메모를 agent에 보내세요." + }, + "logins": { + "title": "로그인 상태 유지", + "body": "기존 로그인 정보를 Orca로 가져와 바로 로그인 상태를 유지하세요." + } + }, + "tasks": { + "source": { + "title": "작업 소스 선택", + "body": "페이지를 이동하지 않고 연결된 제공자와 프로젝트 필터를 전환하세요." + }, + "filter": { + "title": "필요한 작업만 필터링하기", + "body": "프리셋과 검색으로 이슈, 리뷰, merge requests, 작업의 범위를 좁히세요." + }, + "start": { + "title": "작업 항목에서 시작하기", + "body": "작업, 이슈, 리뷰, merge request에서 시작 또는 열기를 눌러 해당 컨텍스트를 워크스페이스로 가져오세요." + } + }, + "floating": { + "workspace": { + "repos": { + "title": "모든 repo에서 agent 실행하기", + "body": "여기의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." + }, + "scratchpad": { + "title": "스크래치패드로도 사용하기", + "body": "집중하고 있는 워크트리를 어지럽히지 않고 agent, 임시 Terminal, 노트, 브라우저 탭을 열 수 있습니다." + } + } + } + } } } } diff --git a/src/shared/contextual-tours.ts b/src/shared/contextual-tours.ts index 623a0bbd6ec8..e8484b35f84d 100644 --- a/src/shared/contextual-tours.ts +++ b/src/shared/contextual-tours.ts @@ -57,6 +57,7 @@ export const CONTEXTUAL_TOURS = [ id: 'workspace-board', steps: [ { + id: 'workspace-board-plan', title: 'Plan work on the board', body: 'Use the board when you want to see workspaces by status instead of by project.', targetSelector: '[data-contextual-tour-target="workspace-board-center"]', @@ -64,6 +65,7 @@ export const CONTEXTUAL_TOURS = [ preferredPlacement: 'bottom' }, { + id: 'workspace-board-lanes', title: 'Move work through lanes', body: 'Drag workspaces between lanes as their status changes.', targetSelector: @@ -75,6 +77,7 @@ export const CONTEXTUAL_TOURS = [ id: 'workspace-agent-sessions', steps: [ { + id: 'agent-sessions-split', title: 'Split a terminal pane', body: 'Open a second terminal pane with {terminal.splitRight}, or right-click the pane for split options.', targetSelector: @@ -85,6 +88,7 @@ export const CONTEXTUAL_TOURS = [ advanceOnFeatureInteraction: 'terminal-pane-split' }, { + id: 'agent-sessions-parallel', title: 'Start another task in parallel', body: 'Each worktree gets its own branch, so parallel work stays separate.', targetSelector: '[data-contextual-tour-target="workspace-create-control"]', @@ -98,6 +102,7 @@ export const CONTEXTUAL_TOURS = [ id: 'browser', steps: [ { + id: 'browser-grab', title: 'Grab page context for agents', body: "Use the grab tool to copy a page element's context for agents.", targetSelector: '[data-contextual-tour-target="browser-grab-control"]', @@ -105,12 +110,14 @@ export const CONTEXTUAL_TOURS = [ preferredPlacement: 'bottom' }, { + id: 'browser-annotate', title: 'Mark design feedback in place', body: 'Annotate elements and send those notes to an agent.', targetSelector: '[data-contextual-tour-target="browser-annotation-control"]', preferredPlacement: 'bottom' }, { + id: 'browser-logins', title: 'Stay logged in', body: 'Bring your existing logins into Orca to stay signed in immediately.', // Prefer the always-visible Import button; fall back to the overflow-menu @@ -126,17 +133,20 @@ export const CONTEXTUAL_TOURS = [ id: 'tasks', steps: [ { + id: 'tasks-source', title: 'Choose the work source', body: 'Switch between connected providers and project filters without changing pages.', targetSelector: '[data-contextual-tour-target="tasks-source-filters"]', requiredForStart: true }, { + id: 'tasks-filter', title: 'Filter to the work you need', body: 'Use presets and search to narrow issues, reviews, merge requests, or tasks.', targetSelector: '[data-contextual-tour-target="tasks-search-presets"]' }, { + id: 'tasks-start', title: 'Start from work items', body: 'Use Start or Open on a task, issue, review, or merge request to bring its context into a workspace.', targetSelector: @@ -166,6 +176,7 @@ export const CONTEXTUAL_TOURS = [ id: 'floating-workspace', steps: [ { + id: 'floating-workspace-repos', title: 'Run an agent across every repo', body: 'Agents here run in any folder you choose. Point one at the directory above your services to work across all your repos at once.', // Why: the per-action anchors only render in the empty state; fall back @@ -176,6 +187,7 @@ export const CONTEXTUAL_TOURS = [ preferredPlacement: 'left' }, { + id: 'floating-workspace-scratchpad', title: 'Or use it as a scratchpad', body: 'Open agents, scratch terminals, notes, and browser tabs without cluttering the worktree you’re focused on.', targetSelector: @@ -189,18 +201,21 @@ export const CONTEXTUAL_TOURS = [ allowedActiveModals: ['new-workspace-composer'], steps: [ { + id: 'workspace-creation-project', title: 'Pick a project', body: 'Orca isolates each task in its own worktree, branched off your base.', targetSelector: '[data-contextual-tour-target="workspace-creation-project"]', requiredForStart: true }, { + id: 'workspace-creation-name', title: 'Name it, or start from existing work', body: 'Start from a linked task for a short issue or PR name. Or leave it blank to auto-name it from your first agent message.', targetSelector: '[data-contextual-tour-target="workspace-creation-name"]', control: { kind: 'auto-rename-branch-from-work' } }, { + id: 'workspace-creation-agent', title: 'Choose what agent starts the work', body: 'Pick the agent that should be opened when this worktree is created.', targetSelector: '[data-contextual-tour-target="workspace-creation-agent"]' From dcd396b2307b4333601ba5f5528eb52822a34d0f Mon Sep 17 00:00:00 2001 From: 5Hyeons Date: Wed, 5 Aug 2026 21:05:44 +0900 Subject: [PATCH 2/4] fix(i18n): translate the contextual tour steps for es, ja, and zh The tour catalog ships five locales; ko alone left Spanish, Japanese, and Chinese users on the English fallback for the same steps. --- src/renderer/src/i18n/locales/es.json | 98 ++++++++++++++++++++++++++- src/renderer/src/i18n/locales/ja.json | 98 ++++++++++++++++++++++++++- src/renderer/src/i18n/locales/zh.json | 98 ++++++++++++++++++++++++++- 3 files changed, 288 insertions(+), 6 deletions(-) diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index 095de652a6ac..e96b9fe01570 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -13306,7 +13306,8 @@ "4a9568f773": "Atrás", "4f86e2a10b": "Saltar recorrido", "d974f32a83": "Descartar recorrido", - "ffa4412b66": "próximo" + "ffa4412b66": "próximo", + "complete": "Hecho" }, "ContextualTourProgressDots": { "7734cb8ad3": "de", @@ -13316,7 +13317,100 @@ "tour": { "overlay": { "measurement": { - "38b3155418": "Próximo" + "38b3155418": "Próximo", + "automations": { + "intro": { + "title": "¿Qué es una automatización?", + "body": "Las automatizaciones ejecutan trabajo de agentes según una programación. Añade una automatización con este botón." + }, + "results": { + "title": "Consulta los resultados", + "body": "Las ejecuciones muestran cuándo se ejecutaron las automatizaciones, qué ocurrió y dónde revisar su salida." + } + } + } + }, + "step": { + "copy": { + "workspace": { + "board": { + "plan": { + "title": "Planifica el trabajo en el tablero", + "body": "Usa el tablero cuando quieras ver los espacios de trabajo por estado en lugar de por proyecto." + }, + "lanes": { + "title": "Mueve el trabajo entre carriles", + "body": "Arrastra los espacios de trabajo entre carriles a medida que cambia su estado." + } + }, + "creation": { + "project": { + "title": "Elige un proyecto", + "body": "Orca aísla cada tarea en su propio worktree, creado a partir de tu rama base." + }, + "name": { + "title": "Ponle nombre o parte de trabajo existente", + "body": "Parte de una tarea vinculada para usar un nombre corto de incidencia o PR. O déjalo en blanco para nombrarlo automáticamente a partir de tu primer mensaje al agente." + }, + "agent": { + "title": "Elige qué agente empieza el trabajo", + "body": "Elige el agente que debe abrirse cuando se cree este worktree." + } + } + }, + "agent": { + "sessions": { + "split": { + "title": "Divide un panel de terminal", + "body": "Abre un segundo panel de terminal con {terminal.splitRight} o haz clic derecho en el panel para ver las opciones de división.", + "action": "Dividir terminal" + }, + "parallel": { + "title": "Empieza otra tarea en paralelo", + "body": "Cada worktree tiene su propia rama, así que el trabajo en paralelo se mantiene separado." + } + } + }, + "browser": { + "grab": { + "title": "Captura el contexto de la página para los agentes", + "body": "Usa la herramienta de captura para copiar el contexto de un elemento de la página para los agentes." + }, + "annotate": { + "title": "Marca el feedback de diseño sobre la página", + "body": "Anota elementos y envía esas notas a un agente." + }, + "logins": { + "title": "Mantén la sesión iniciada", + "body": "Lleva tus inicios de sesión existentes a Orca para seguir conectado de inmediato." + } + }, + "tasks": { + "source": { + "title": "Elige el origen del trabajo", + "body": "Cambia entre proveedores conectados y filtros de proyecto sin cambiar de página." + }, + "filter": { + "title": "Filtra hasta el trabajo que necesitas", + "body": "Usa los preajustes y la búsqueda para acotar incidencias, revisiones, merge requests o tareas." + }, + "start": { + "title": "Empieza desde los elementos de trabajo", + "body": "Usa Iniciar o Abrir en una tarea, incidencia, revisión o merge request para llevar su contexto a un espacio de trabajo." + } + }, + "floating": { + "workspace": { + "repos": { + "title": "Ejecuta un agente en todos los repositorios", + "body": "Los agentes de aquí se ejecutan en la carpeta que elijas. Apunta uno al directorio superior a tus servicios para trabajar en todos tus repositorios a la vez." + }, + "scratchpad": { + "title": "O úsalo como bloc de notas", + "body": "Abre agentes, terminales temporales, notas y pestañas del navegador sin saturar el worktree en el que estás concentrado." + } + } + } } } } diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 4ed7237ae844..f0742b71a6c7 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -13306,7 +13306,8 @@ "4a9568f773": "戻る", "4f86e2a10b": "ツアーをスキップ", "d974f32a83": "ツアーを閉じる", - "ffa4412b66": "次" + "ffa4412b66": "次", + "complete": "完了" }, "ContextualTourProgressDots": { "7734cb8ad3": "の", @@ -13316,7 +13317,100 @@ "tour": { "overlay": { "measurement": { - "38b3155418": "次へ" + "38b3155418": "次へ", + "automations": { + "intro": { + "title": "オートメーションとは?", + "body": "オートメーションはスケジュールに従って agent の作業を実行します。このボタンからオートメーションを追加できます。" + }, + "results": { + "title": "結果を確認する", + "body": "実行履歴では、オートメーションがいつ実行され、何が起きて、出力をどこで確認できるかがわかります。" + } + } + } + }, + "step": { + "copy": { + "workspace": { + "board": { + "plan": { + "title": "ボードで作業を計画する", + "body": "プロジェクト別ではなく状態別にワークスペースを見たいときはボードを使います。" + }, + "lanes": { + "title": "レーン間で作業を動かす", + "body": "状態が変わったら、ワークスペースをレーン間にドラッグします。" + } + }, + "creation": { + "project": { + "title": "プロジェクトを選ぶ", + "body": "Orca は各タスクをベースブランチから分岐した専用のワークツリーに分離します。" + }, + "name": { + "title": "名前を付けるか、既存の作業から始める", + "body": "リンクされたタスクから始めると、短い issue 名や PR 名が使われます。空欄のままにすると、最初の agent メッセージから自動で名前が付きます。" + }, + "agent": { + "title": "作業を開始する agent を選ぶ", + "body": "このワークツリーが作成されたときに開く agent を選びます。" + } + } + }, + "agent": { + "sessions": { + "split": { + "title": "Terminal ペインを分割する", + "body": "{terminal.splitRight} で 2 つ目の Terminal ペインを開くか、ペインを右クリックして分割オプションを表示します。", + "action": "Terminal を分割" + }, + "parallel": { + "title": "別のタスクを並行して始める", + "body": "ワークツリーごとに専用のブランチがあるため、並行して進める作業が混ざりません。" + } + } + }, + "browser": { + "grab": { + "title": "agent 向けにページのコンテキストを取得する", + "body": "grab ツールでページ要素のコンテキストをコピーして agent に渡します。" + }, + "annotate": { + "title": "デザインのフィードバックをその場で残す", + "body": "要素に注釈を付けて、そのメモを agent に送ります。" + }, + "logins": { + "title": "ログイン状態を保つ", + "body": "既存のログイン情報を Orca に取り込んで、すぐにログイン状態を保ちます。" + } + }, + "tasks": { + "source": { + "title": "作業のソースを選ぶ", + "body": "ページを移動せずに、接続済みのプロバイダーとプロジェクトフィルターを切り替えます。" + }, + "filter": { + "title": "必要な作業だけに絞り込む", + "body": "プリセットと検索で issues、レビュー、merge requests、タスクを絞り込みます。" + }, + "start": { + "title": "作業アイテムから始める", + "body": "タスク、issue、レビュー、merge request で開始または開くを押すと、そのコンテキストをワークスペースに取り込めます。" + } + }, + "floating": { + "workspace": { + "repos": { + "title": "すべての repo で agent を実行する", + "body": "ここの agent は選んだ任意のフォルダーで実行されます。サービスの 1 つ上のディレクトリを指定すれば、すべての repo をまとめて扱えます。" + }, + "scratchpad": { + "title": "スクラッチパッドとしても使える", + "body": "集中しているワークツリーを散らかさずに、agent、一時的な Terminal、ノート、ブラウザータブを開けます。" + } + } + } } } } diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index e7529643e5e2..9636cfb6671c 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -13326,7 +13326,8 @@ "4a9568f773": "返回", "4f86e2a10b": "跳过导览", "d974f32a83": "关闭导览", - "ffa4412b66": "下一步" + "ffa4412b66": "下一步", + "complete": "完成" }, "ContextualTourProgressDots": { "7734cb8ad3": "的", @@ -13336,7 +13337,100 @@ "tour": { "overlay": { "measurement": { - "38b3155418": "下一步" + "38b3155418": "下一步", + "automations": { + "intro": { + "title": "什么是自动化?", + "body": "自动化会按计划运行智能体任务。点击此按钮添加自动化。" + }, + "results": { + "title": "查看运行结果", + "body": "运行记录会显示自动化何时运行、发生了什么,以及在哪里查看输出。" + } + } + } + }, + "step": { + "copy": { + "workspace": { + "board": { + "plan": { + "title": "在看板中规划工作", + "body": "想按状态而不是按项目查看工作区时,请使用看板。" + }, + "lanes": { + "title": "在泳道之间移动工作", + "body": "状态变化时,把工作区拖到相应的泳道。" + } + }, + "creation": { + "project": { + "title": "选择项目", + "body": "Orca 会把每个任务隔离到基于基础分支创建的独立工作树中。" + }, + "name": { + "title": "命名,或从已有工作开始", + "body": "从关联的任务开始可获得简短的 issue 或 PR 名称。留空则会根据你的第一条智能体消息自动命名。" + }, + "agent": { + "title": "选择由哪个智能体开始工作", + "body": "选择创建此工作树时要打开的智能体。" + } + } + }, + "agent": { + "sessions": { + "split": { + "title": "拆分终端窗格", + "body": "使用 {terminal.splitRight} 打开第二个终端窗格,或右键点击窗格查看拆分选项。", + "action": "拆分终端" + }, + "parallel": { + "title": "并行开始另一个任务", + "body": "每个工作树都有自己的分支,因此并行进行的工作互不干扰。" + } + } + }, + "browser": { + "grab": { + "title": "为智能体抓取页面上下文", + "body": "使用抓取工具复制页面元素的上下文,供智能体使用。" + }, + "annotate": { + "title": "就地标注设计反馈", + "body": "为元素添加批注,并把这些备注发送给智能体。" + }, + "logins": { + "title": "保持登录状态", + "body": "把现有登录信息导入 Orca,立即保持登录状态。" + } + }, + "tasks": { + "source": { + "title": "选择工作来源", + "body": "无需切换页面即可在已连接的提供方和项目筛选之间切换。" + }, + "filter": { + "title": "筛选出你需要的工作", + "body": "使用预设和搜索来缩小 issues、评审、merge requests 或任务的范围。" + }, + "start": { + "title": "从工作项开始", + "body": "在任务、issue、评审或 merge request 上点击开始或打开,即可把其上下文带入工作区。" + } + }, + "floating": { + "workspace": { + "repos": { + "title": "在所有存储库中运行智能体", + "body": "这里的智能体可在你选择的任意文件夹中运行。把它指向服务所在目录的上一级,即可一次性处理所有存储库。" + }, + "scratchpad": { + "title": "也可当作草稿区使用", + "body": "打开智能体、临时终端、笔记和浏览器标签页,同时不会弄乱你正在专注的工作树。" + } + } + } } } } From b10f8080058cf199a46dc866208053c8fe953037 Mon Sep 17 00:00:00 2001 From: 5Hyeons Date: Wed, 5 Aug 2026 22:02:22 +0900 Subject: [PATCH 3/4] fix(i18n): require step ids and correct the Spanish tour labels Addresses CodeRabbit review: a required `id` makes a new step without a stable copy anchor a type error rather than a silent English fallback, the coverage test now fails on a missing action label instead of an undefined one, and the Spanish Next label and name-step title use idiomatic wording. --- .../contextual-tour-overlay-measurement.test.ts | 1 + .../contextual-tours/contextual-tour-step-copy.test.ts | 1 + src/renderer/src/i18n/locales/es.json | 6 +++--- src/shared/contextual-tours.ts | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.test.ts b/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.test.ts index 4b2ce9631ca1..f6c35e5dd857 100644 --- a/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.test.ts +++ b/src/renderer/src/components/contextual-tours/contextual-tour-overlay-measurement.test.ts @@ -79,6 +79,7 @@ describe('contextual tour overlay measurement', () => { ...automations, steps: [ { + id: 'inserted-step', title: 'Inserted step', body: 'Added ahead of the localized steps.', targetSelector: '[data-contextual-tour-target="automations-create"]' diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts index aca338ec63b2..781502ae0fdb 100644 --- a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts +++ b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts @@ -20,6 +20,7 @@ describe('contextual tour step copy', () => { expect(copy?.title).not.toBe(step.title) expect(copy?.body).not.toBe(step.body) if (step.primaryAction) { + expect(copy?.primaryActionLabel).toBeDefined() expect(copy?.primaryActionLabel).not.toBe(step.primaryAction.label) } } diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index e96b9fe01570..96717e48e500 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -13306,7 +13306,7 @@ "4a9568f773": "Atrás", "4f86e2a10b": "Saltar recorrido", "d974f32a83": "Descartar recorrido", - "ffa4412b66": "próximo", + "ffa4412b66": "Siguiente", "complete": "Hecho" }, "ContextualTourProgressDots": { @@ -13317,7 +13317,7 @@ "tour": { "overlay": { "measurement": { - "38b3155418": "Próximo", + "38b3155418": "Siguiente", "automations": { "intro": { "title": "¿Qué es una automatización?", @@ -13349,7 +13349,7 @@ "body": "Orca aísla cada tarea en su propio worktree, creado a partir de tu rama base." }, "name": { - "title": "Ponle nombre o parte de trabajo existente", + "title": "Ponle nombre o usa un elemento de trabajo existente", "body": "Parte de una tarea vinculada para usar un nombre corto de incidencia o PR. O déjalo en blanco para nombrarlo automáticamente a partir de tu primer mensaje al agente." }, "agent": { diff --git a/src/shared/contextual-tours.ts b/src/shared/contextual-tours.ts index e8484b35f84d..c33f806ad3f4 100644 --- a/src/shared/contextual-tours.ts +++ b/src/shared/contextual-tours.ts @@ -31,7 +31,7 @@ export type ContextualTourStepPlacement = 'top' | 'right' | 'bottom' | 'left' export type ContextualTourStep = { // Stable anchor for localized copy — position-keyed translations shift onto the wrong step when one is inserted. - id?: string + id: string title: string body: string targetSelector: string From 3f406b553f3ffa590c6b463dc483980ebb71d4ef Mon Sep 17 00:00:00 2001 From: 5Hyeons Date: Wed, 5 Aug 2026 22:36:52 +0900 Subject: [PATCH 4/4] fix(i18n): polish the Korean floating workspace tour copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Native-reader feedback: "이곳의" reads better than "여기의", the title now says what the step actually offers (one agent covering every repo), and the scratchpad step uses a plain Korean word instead of a transliteration. --- config/scripts/locale-ko-key-overrides.json | 6 +++--- .../contextual-tours/contextual-tour-step-copy.test.ts | 2 +- src/renderer/src/i18n/locales/ko.json | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/scripts/locale-ko-key-overrides.json b/config/scripts/locale-ko-key-overrides.json index 15252e168e42..ff2b6005ffa8 100644 --- a/config/scripts/locale-ko-key-overrides.json +++ b/config/scripts/locale-ko-key-overrides.json @@ -5124,16 +5124,16 @@ "ko": "로그인 상태 유지" }, "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.body": { - "ko": "여기의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." + "ko": "이곳의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." }, "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.repos.title": { - "ko": "모든 repo에서 agent 실행하기" + "ko": "agent 하나로 모든 repo 다루기" }, "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.body": { "ko": "집중하고 있는 워크트리를 어지럽히지 않고 agent, 임시 Terminal, 노트, 브라우저 탭을 열 수 있습니다." }, "auto.components.contextual.tours.contextual.tour.step.copy.floating.workspace.scratchpad.title": { - "ko": "스크래치패드로도 사용하기" + "ko": "메모장처럼 사용하기" }, "auto.components.contextual.tours.contextual.tour.step.copy.tasks.filter.body": { "ko": "프리셋과 검색으로 이슈, 리뷰, merge requests, 작업의 범위를 좁히세요." diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts index 781502ae0fdb..ef3a6a79ff8f 100644 --- a/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts +++ b/src/renderer/src/components/contextual-tours/contextual-tour-step-copy.test.ts @@ -31,7 +31,7 @@ describe('contextual tour step copy', () => { await setRendererUiLanguage('ko') expect(getLocalizedContextualTourStepCopy('floating-workspace-scratchpad')?.title).toBe( - '스크래치패드로도 사용하기' + '메모장처럼 사용하기' ) }) diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 5a02ff99f7cb..f1fd050068f3 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -13402,11 +13402,11 @@ "floating": { "workspace": { "repos": { - "title": "모든 repo에서 agent 실행하기", - "body": "여기의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." + "title": "agent 하나로 모든 repo 다루기", + "body": "이곳의 agent는 선택한 어떤 폴더에서도 실행됩니다. 서비스들의 상위 디렉터리를 지정하면 모든 repo에서 한 번에 작업할 수 있습니다." }, "scratchpad": { - "title": "스크래치패드로도 사용하기", + "title": "메모장처럼 사용하기", "body": "집중하고 있는 워크트리를 어지럽히지 않고 agent, 임시 Terminal, 노트, 브라우저 탭을 열 수 있습니다." } }