// Korean dictionary. Mirror the shape of src/lang/en.ts — // missing keys fall back to English per createI18n's fallbackLocale. // // ⚠️ `` 같은 꺾쇠 괄호가 들어간 문자열은 vue-i18n 의 XSS // 탐지에 걸려 "Detected HTML in '…' message" 경고가 발생하므로 // 반드시 **함수 형식** 으로 작성한다. 자세한 내용은 en.ts 의 // 헤더 주석 참고. const koMessages = { common: { downloadZip: "ZIP", downloadFailed: "다운로드 실패", save: "저장", cancel: "취소", loading: "불러오는 중...", close: "닫기", dismiss: "닫기", add: "추가", remove: "삭제", yes: "예", no: "아니오", saving: "저장 중...", saved: "저장됨", noResultsYet: "아직 결과가 없습니다", noImageYet: "아직 이미지가 없습니다", sendChat: "새 채팅 시작", }, sessionTabBar: { newSession: "새 세션", // 한국어는 단·복수 구분이 없어 같은 문자열이지만 vue-i18n 의 // pluralization 규약에 맞추기 위해 `|` 구분자를 유지합니다. activeSessions: "활성 세션 {count}개 (에이전트 실행 중)", unreadReplies: "읽지 않은 답장 {count}개", unreadDot: "새 답장", origin: { scheduler: "스케줄러에서 시작됨", skill: "스킬에서 시작됨", bridge: "브리지에서 시작됨", }, }, chatInput: { placeholder: "Claude에게 메시지…", send: "전송", stop: "중지", runningPlaceholder: "실행 중… Enter로 대기열에 추가", removeBuffered: "대기열 메시지 제거", attachFile: "파일 첨부", fileTooLarge: "파일이 너무 큽니다 ({sizeMB} MB). 최대 30 MB 까지 가능합니다.", unsupportedFileType: "지원되지 않는 파일 형식입니다. 이미지, PDF, DOCX, XLSX, PPTX, 텍스트 파일만 지원됩니다.", attachImageFailed: "이미지를 첨부하지 못했습니다: {error}", stopFailed: "처리를 중지하지 못했습니다: {error}", dropHint: "파일을 놓아서 첨부", tooManyFiles: "한 번에 최대 {max}개까지 첨부할 수 있습니다.", removeAttachment: "{name} 제거", attachmentFallbackName: "첨부파일", voice: { start: "음성 입력 시작", stop: "음성 입력 중지", }, }, cspViolation: { notice: "⚠ 뷰가 {host}를 불러오려 했지만 콘텐츠 보안 정책({directive})이 차단했습니다. 허용하려면 신뢰하는 경우에만 config/csp.json에 호스트를 추가하세요.", dismiss: "닫기", }, sessionHistoryPanel: { filters: { all: "전체", unread: "읽지 않음", bookmarked: "북마크", longRunning: "장기 (24h+)", human: "사람", scheduler: "스케줄러", skill: "스킬", bridge: "브리지", }, failedToRefresh: "⚠ 새로고침 실패: {error}", showingLastKnown: " — 마지막으로 불러온 목록을 표시하고 있습니다.", noSessions: "아직 세션이 없습니다.", noMatching: "일치하는 세션이 없습니다.", running: "실행 중", noMessages: "(메시지 없음)", openRowAria: "세션 열기: {preview}", rowMenuAria: "세션 작업", bookmark: "북마크 추가", unbookmark: "북마크 해제", delete: "삭제", deleteConfirm: "이 세션을 삭제하시겠습니까?\n\n{preview}\n\n이 작업은 되돌릴 수 없습니다.", }, notificationBell: { notifications: "알림", activeSection: "진행 중", historySection: "기록", noActive: "활성 알림이 없습니다", noHistory: "최근 활동이 없습니다", clearAll: "모두 지우기", dismiss: "닫기", cancel: "취소", showMore: "더 보기 ({count})", showLess: "접기", openTarget: "열기", expandDetails: "상세 보기", }, pluginDiagnostics: { title: "플러그인 구성 문제", hostBody: '플러그인 "{plugin}"이(가) {label} 키 "{key}"을(를) 등록하려고 했으나 호스트에서 예약된 키이므로 거부되었습니다. 플러그인의 항목이 삭제되었습니다.', intraBody: '플러그인 "{first}"과(와) "{second}"이(가) 동일한 {dimension} "{key}"을(를) 등록합니다. "{first}"이(가) 먼저 등록했으므로 "{second}"의 등록은 무시됩니다.', }, shadowedEnv: { title: "셸 환경 변수가 .env를 덮어쓰고 있습니다", body: "셸과 .env 양쪽에 모두 설정되어 있습니다: {keys}. 셸의 값이 우선하므로 .env는 무시됩니다. .env를 수정했다면 셸의 값을 갱신하거나 해제한 뒤 다시 시작하세요.", }, optionalDeps: { // 영구 저장된 기존 히스토리 항목과의 호환을 위해 일반적인 `title` 키는 // 그대로 둔다. 새 발화는 `titleNotFound` / `titleNotResponding` 사용. title: "선택적 의존성을 사용할 수 없습니다", titleNotFound: "{command}이(가) 설치되어 있지 않습니다", titleNotResponding: "{command}이(가) 실행 중이 아닙니다", notFound: "{command}을(를) 찾을 수 없습니다 — 관련 기능이 비활성화되었습니다. {command}을(를) 설치한 후 MulmoClaude를 재시작하면 활성화됩니다.", notResponding: "{command}은(는) 설치되어 있지만 실행 중이 아닙니다 — 관련 기능이 비활성화되었습니다. {command}을(를) 시작한 후 MulmoClaude를 재시작하면 활성화됩니다.", }, billingMigration: { title: "인보이스 기능이 온디맨드 설정으로 이동했습니다", body: "번들로 제공되던 clients, worklog, invoice, profile 컬렉션이 대시보드에서 제거되었지만 데이터는 안전하게 그대로 유지됩니다. 클라이언트 및 작업 시간 기록을 설정한 다음 인보이스를 설정하도록 요청하면 다시 만들어지고 기존 레코드가 다시 표시됩니다.", }, backendOffline: { title: "백엔드에 연결할 수 없습니다", body: "MulmoClaude 서버가 실행 중이 아닐 수 있습니다. 개발 서버를 확인한 후 다시 시도하세요.", retry: "다시 시도", }, pluginErrorBoundary: { title: "플러그인 {pkg}이(가) 충돌했습니다", subtitle: "플러그인 렌더링에 실패했습니다. 오류가 콘솔에 기록되었습니다.", showDetails: "세부 정보 표시", hideDetails: "세부 정보 숨기기", retry: "다시 시도", }, remoteHostOffline: { title: "원격 호스트 연결 끊김", body: "다시 연결하기 전에는 휴대폰에서 이 기기로 보낼 수 없습니다.", reconnect: "다시 연결", }, remoteHost: { title: "원격 호스트", online: "원격 호스트 온라인", offline: "원격 호스트 오프라인", uid: "uid {uid}", signIn: "Google로 로그인", connecting: "연결 중…", disconnect: "연결 해제", disconnecting: "연결 해제 중…", noToken: "Google 로그인에서 idToken을 반환하지 않았습니다", connectFailed: "연결 실패", disconnectFailed: "연결 해제 실패", signInFailed: "Google 로그인 실패", statusFailed: "상태를 불러오지 못했습니다", description: "원격 액세스를 사용하면 모바일 기기에서 이 MulmoClaude의 컬렉션과 피드에 연결할 수 있습니다.", howTo: "휴대폰에서 {url} 을(를) 열고 같은 Google 계정으로 로그인하세요.", customViewHint: "모바일에 최적화된 뷰가 필요하다면, 일반 custom view가 아닌 {keyword} 를(을) 만들어 달라고 Claude에게 요청하세요.", qrHint: "휴대폰 카메라로 이 QR 코드를 스캔해도 열 수 있습니다.", }, sidebarHeader: { newMessages: "새 메시지", home: "최신 채팅으로 이동", toolCallHistory: "도구 호출 기록", settings: "설정", settingsGeminiMissing: "설정 — Gemini API 키 없음", todayJournal: "오늘의 요약", todayJournalNotFound: "아직 요약이 없습니다 — 잠시 대화하면 journal이 생성합니다.", todayJournalLoadFailed: "journal 로드에 실패했습니다 (status {status}): {error}", copyMarkdown: "대화를 Markdown으로 복사", copiedMarkdown: "복사됨", }, rightSidebar: { permalink: "선택된 메시지의 고유 링크", copyPermalink: "선택된 메시지의 고유 링크 복사", copiedPermalink: "복사됨!", toggleSystemPrompt: "시스템 프롬프트 토글", systemPrompt: "시스템 프롬프트", availableTools: "사용 가능한 도구", toggleToolDescription: "도구 설명 토글", toolCallHistory: "도구 호출 기록", copyHistory: "도구 호출 기록 복사", copiedHistory: "복사됨!", noToolCalls: "아직 도구 호출이 없습니다", arguments: "인자", error: "오류", result: "결과", running: "실행 중...", mcpHint: { title: (ctx: { named: (key: "server") => string }) => `${ctx.named("server")} 설정 도움말`, requiredKeys: "필수 키", setupGuide: "설정 가이드 열기", }, }, fileTreePane: { sort: "정렬:", sortByName: "이름순 정렬", name: "이름", sortByRecent: "수정일순 정렬 (최신순)", recent: "최근", reference: "참조", // "RO" = Read-Only. 간결한 배지로 표시하기 위해 영문 약어 유지. readOnlyBadge: "RO", showSystemFiles: "시스템 파일 표시", showSystemFilesTitle: "사용자 콘텐츠(data/, artifacts/, config/)에 더해 에이전트 내부 최상위 디렉터리(conversations/, feeds/ 등)까지 표시합니다.", }, fileTree: { dropHint: "여기에 파일을 놓으면 이 폴더에 저장됩니다", upload: { progress: "업로드 중 {done}/{total}…", done: "파일 {count}개를 저장했습니다", failed: "파일 {count}개를 저장하지 못했습니다", }, workspace: "(워크스페이스)", recentlyChanged: "최근 변경됨", newFileMenuItem: "새 파일", newFileInputAria: "새 파일 이름", newFilePlaceholder: { wikiPage: "페이지 slug", summary: "요약 이름", document: "문서 이름", html: "페이지 이름", story: "스토리 이름", }, newFileError: { empty: "파일 이름을 입력하세요.", unsafe: "파일 이름에 사용할 수 없는 문자가 포함되어 있습니다.", exists: "{filename} 파일이 이미 존재합니다.", saveFailed: "파일을 생성할 수 없습니다. 다시 시도해 주세요.", }, }, lockStatusPopup: { sandboxEnabledTooltip: "샌드박스 활성화 (Docker)", noSandboxTooltip: "샌드박스 없음 (Docker 미발견)", sandboxEnabledLabel: "샌드박스 활성화:", sandboxEnabledBody: "Docker 가 실행 중입니다. 파일 시스템 접근이 격리됩니다.", noSandboxLabel: "샌드박스 없음:", noSandboxBodyPrefix: "Claude 가 이 컴퓨터의 모든 파일에 접근할 수 있습니다. 파일 시스템 격리를 활성화하려면", noSandboxBodySuffix: "을(를) 설치하세요.", dockerDesktop: "Docker Desktop", hostCredentials: "연결된 호스트 인증 정보:", credsLoading: "불러오는 중…", sshAgent: "SSH 에이전트:", forwarded: "전달됨", notForwarded: "전달되지 않음", mountedConfigs: "마운트된 설정:", none: "없음", testIsolation: "샌드박스 격리 테스트:", }, settingsModal: { title: "설정", version: "MulmoClaude v{version}", tabs: { gemini: "Gemini API 키", tools: "허용된 도구", mcp: "MCP 서버", dirs: "디렉터리", refs: "참조 디렉터리", map: "지도", photos: "사진", google: "Google", model: "모델", voice: "음성", chatIndex: "채팅 인덱스", journal: "저널", notifications: "Web Push", skills: "스킬", roles: "역할", quit: "종료", }, groups: { llm: "LLM", servers: "서버", workspace: "워크스페이스", notifications: "알림", plugins: "플러그인", management: "관리", server: "서버", }, navAriaLabel: "설정 섹션", googleTab: { description: "Google 계정을 연결하면 이 컴퓨터에서 Google API(우선 캘린더)를 직접 호출할 수 있습니다. 리프레시 토큰은 이 컴퓨터에만 저장되며 Google 이외에는 전송되지 않습니다.", statusLinked: "연결됨", statusNotLinked: "연결되지 않음", statusPending: "브라우저에서 동의가 완료되기를 기다리는 중…", connect: "Google 계정 연결", unlink: "연결 해제", unlinkConfirm: "Google 계정 연결을 해제할까요? 저장된 토큰은 취소되고 이 컴퓨터에서 삭제됩니다.", clientSecretAmbiguous: "~/.secrets/에서 client_secret_*.json 파일이 여러 개 발견되었습니다. 저장된 토큰과 OAuth 클라이언트가 어긋나지 않도록 하나만 남겨 주세요.", loadError: "Google 연결 상태를 불러오지 못했습니다.", connectError: "Google 인증 절차를 시작하지 못했습니다.", unlinkError: "Google 연결 해제에 실패했습니다.", }, mapTab: { description: "지도 플러그인에서 사용하는 Google Maps API 키를 설정합니다. 키는 로컬에 저장되며 Google Maps 외부로는 전송되지 않습니다.", apiKeyLabel: "Google Maps API 키", apiKeyPlaceholder: "AIza…", helperText: "{consoleLink}에서 키를 만들거나 복사하세요.", requiredApis: "활성화 필요: Maps JavaScript API, Geocoding API, Places API (New), Directions API.", configured: "구성됨", notConfigured: "구성되지 않음", clear: "지우기", loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, photosTab: { description: "채팅 또는 연결된 bridge로 받은 사진의 개인정보 설정입니다. EXIF 위치 데이터는 민감하므로, 자동 수집을 원하지 않으면 체크박스를 해제하세요.", autoCaptureLabel: "사진 위치 데이터 자동 수집", autoCaptureHint: "켜진 경우, EXIF GPS가 있는 업로드된 이미지마다 data/locations/에 위치 sidecar가 생성됩니다. 끄면 자동 수집이 중단되지만 필요할 때 LLM이 EXIF를 수동으로 읽을 수 있습니다.", statusOn: "자동 수집 켜짐", statusOff: "자동 수집 꺼짐", loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, quitTab: { description: "이 컴퓨터에서 실행 중인 MulmoClaude 서버를 종료합니다. 아이콘으로 시작한 경우 이 탭을 닫아도 서버는 계속 실행됩니다. 터미널 없이 종료하는 방법이 여기입니다.", // Message function form — skips vue-i18n's message compiler so the // literal `@` in `mulmoclaude@latest` is not parsed as a linked-message // reference (the compiler throws, and the whole tab renders as nothing). restartHint: () => "다시 시작하려면 MulmoClaude 아이콘을 두 번 클릭하세요(또는 `npx mulmoclaude@latest`).", quitLabel: "MulmoClaude 종료", confirmBody: "서버가 멈추고 이 페이지는 동작하지 않게 됩니다. 진행 중인 작업은 중단됩니다.", confirmLabel: "종료", stopping: "종료하는 중…", stoppedTitle: "MulmoClaude가 종료되었습니다", stoppedBody: "이 탭을 닫아도 됩니다. 다시 시작하려면 아이콘을 두 번 클릭하세요.", error: "서버를 종료하지 못했습니다", }, notificationsTab: { description: "여기서 시작한 작업이 완료되면 등록된 기기로 푸시 알림을 보냅니다. 질문을 남기고 자리를 비운 뒤 답변이 준비되는 순간을 알고 싶을 때 유용합니다.", enableLabel: "작업 완료 시 Web Push 보내기", enableHint: "여기서 시작한 채팅이 완료되면 실행됩니다. 예약 작업이나 백그라운드 작업에서는 실행되지 않습니다.", remoteHostNote: "RemoteHost 연결(로그인 제공)과 등록된 기기가 하나 이상 필요합니다. 둘 중 하나라도 없으면 아무 동작도 하지 않습니다.", macosRemindersLabel: "작업 완료 시 macOS 미리 알림 만들기", macosRemindersHint: "완료된 작업을 기본 미리 알림 목록에 추가합니다. iCloud를 통해 iPhone에 동기화되며, iPhone에서 알림이 전달됩니다.", macosRemindersForcedOff: "시작할 때 --disable-macos-reminders 또는 DISABLE_MACOS_REMINDER_NOTIFICATIONS로 꺼졌습니다. 플래그를 제거하거나 환경 변수를 해제한 뒤 다시 시작하면 여기서 제어할 수 있습니다.", statusOn: "Web Push 켜짐", statusOff: "Web Push 꺼짐", loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, modelTab: { description: "Claude Code가 각 턴에 사용하는 추론 effort를 제어합니다. 설정하지 않으면 Claude의 기본값이 사용됩니다.", effortLabel: "추론 effort", effortUnset: "(미설정 — Claude 기본값 사용)", helperText: "레벨이 높을수록 사고 시간이 늘어나지만 지연 시간과 토큰 사용량도 증가합니다.", configured: "Effort: {level}", notConfigured: "미설정", loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, voiceTab: { description: "음성으로 채팅 메시지를 입력합니다. 오디오는 MulmoClaude를 실행하는 컴퓨터에서 로컬로 전사되며 외부 서비스로 전송되지 않습니다.", requirements: "macOS에서만 사용할 수 있습니다. whisper.cpp 서버가 필요하며 yarn build:whisper 로 빌드하세요 (README의 Local Voice Input 섹션 참조).", unsupported: "음성 입력에는 whisper.cpp 서버가 설치된 macOS가 필요합니다. 이 컴퓨터에서는 사용할 수 없습니다.", enableLabel: "음성 입력 활성화", enableHint: "켜면 음성 모델(1–3 GB)을 한 번 다운로드합니다. 이후 채팅 입력란에 마이크 버튼이 표시됩니다.", modelLabel: "음성 모델", downloading: "모델 다운로드 중… {percent}%", ready: "모델 준비 완료", downloadError: "모델 다운로드에 실패했습니다.", retry: "다시 시도", loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, chatIndexTab: { description: "채팅 기록의 AI 제목/요약 자동 생성을 설정합니다. 기본값은 off 이며, 자동화 계열 세션(scheduler / 시스템 워커)은 on 상태여도 항상 제외됩니다. 사람 세션만 턴 종료 시 요약이 한 번 실행됩니다.", modeLabel: "채팅 인덱스 모델", helperText: "Haiku 가 더 저렴하고, Sonnet 은 길고 주제가 바뀌는 세션에서 더 정확한 제목을 만듭니다.", mode: { off: "꺼짐", haiku: "Haiku", sonnet: "Sonnet", }, status: { off: "인덱싱: 꺼짐", haiku: "Haiku 로 인덱싱 중", sonnet: "Sonnet 으로 인덱싱 중", }, loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, journalTab: { description: "일일 저널 자동 생성 설정입니다. 최근 채팅 세션을 journal/*.md 로 요약하고 지속 메모(memory.md)를 추출합니다. 기본값은 off. 자동화 세션(scheduler / 시스템 워커)은 이 설정과 무관하게 항상 제외됩니다.", modeLabel: "저널 모델", helperText: "Haiku 가 더 저렴하고, Sonnet 은 일일/주제 요약 품질이 더 좋습니다. 매시 실행은 이 설정이 켜져 있을 때만 동작합니다.", mode: { off: "꺼짐", haiku: "Haiku", sonnet: "Sonnet", }, status: { off: "저널: 꺼짐", haiku: "Haiku 로 저널 실행 중", sonnet: "Sonnet 으로 저널 실행 중", }, loadError: "설정을 불러오지 못했습니다", saveError: "저장에 실패했습니다", }, // `` 슬롯 — `envKey` / `envFile` 은 SettingsModal.vue 에서 // 인라인 `` 로 렌더링되므로 변수명·파일명은 번역하지 않고 // 남깁니다. geminiRequired: "이미지 생성에는 {envKey} 가 필요합니다. {envFile} 에 추가하고 앱을 재시작해주세요.", geminiAskButton: "Claude 에게 질문", geminiAskMessage: "이 앱에서 Gemini API 키는 어떤 역할을 하나요?", toolNamesLabel: "도구 이름", invalidToolNamesPrefix: "다음은 비표준으로 보입니다 (예상 접두사", invalidToolNamesSuffix: "):", mcpToolsError: "⚠ MCP 도구 상태를 가져올 수 없습니다: {error}. 활성화 여부와 무관하게 모든 도구를 표시합니다.", changesHint: "변경 사항은 다음 메시지부터 적용됩니다. 재시작은 필요하지 않습니다.", cannotSaveTooltip: "설정을 성공적으로 불러오기 전에는 저장할 수 없습니다", saving: "저장 중…", loadingLabel: "불러오는 중…", unsavedMarker: "●", unsavedToolsConfirm: "허용된 도구에 저장되지 않은 변경 사항이 있습니다. 계속 닫으시겠습니까?", unsavedMcpDraftConfirm: "MCP 서버 초안이 아직 열려 있습니다. 계속 닫으시겠습니까?", mcpSaveFailed: "MCP 서버 변경 사항을 저장하지 못했습니다.", }, canvasViewToggle: { stackViewTooltip: "스택 보기 · 클릭하여 단일 보기로 전환", singleViewTooltip: "단일 보기 · 클릭하여 스택 보기로 전환", switchToSingle: "단일 보기로 전환", switchToStack: "스택 보기로 전환", }, sessionHistoryToggle: { showTooltip: "왼쪽에 세션 기록 패널 표시", hideTooltip: "세션 기록 패널 숨기기", show: "세션 기록 표시", hide: "세션 기록 숨기기", }, sessionHistoryExpand: { expandTooltip: "세션 기록 패널을 전체 너비로 확장", collapseTooltip: "세션 기록 패널 축소", expand: "세션 기록 확장", collapse: "세션 기록 축소", }, settingsWorkspaceDirs: { explanation: "{dataDir} 와 {artifactsDir} 아래에서 파일을 정리하기 위한 커스텀 디렉터리입니다. Claude 는 이를 참조해 파일 저장 위치를 결정합니다.", noEntries: "설정된 커스텀 디렉터리가 없습니다.", addDirTitle: "디렉터리 추가", pathPlaceholder: "data/clients 또는 artifacts/reports", descPlaceholder: "설명 (이 폴더에 무엇을 보관할지)", errPathRequired: "경로를 입력하세요", errMustStartWith: "data/ 또는 artifacts/ 로 시작해야 합니다", errAlreadyExists: "이미 존재합니다", }, settingsReferenceDirs: { explanation: "Claude 가 읽을 수는 있지만 수정할 수 없는 외부 디렉터리입니다. Docker 모드에서는 읽기 전용으로 마운트됩니다. Obsidian 볼트, 프로젝트 코드, 문서 폴더를 참조할 때 유용합니다.", noEntries: "설정된 참조 디렉터리가 없습니다.", addDirTitle: "참조 디렉터리 추가", pathPlaceholder: "/Users/me/ObsidianVault 또는 ~/Documents/notes", labelPlaceholder: "라벨 (선택 — 기본값은 폴더 이름)", readOnlyBadge: "읽기 전용", errPathRequired: "경로를 입력하세요", errMustBeAbsolute: "절대 경로이거나 ~/ 로 시작해야 합니다", errAlreadyExists: "이미 존재합니다", errLabelConflict: '라벨 "{label}" 은(는) 이미 사용 중입니다', }, dashboard: { empty: "즐겨찾는 컬렉션이 아직 없습니다.", emptyHint: "컬렉션을 고정(★)하면 여기에 표시됩니다.", viewTable: "테이블", viewCalendar: "캘린더", viewKanban: "칸반", viewPickerLabel: "보기 선택", openFull: "더블클릭하여 전체 보기 열기", dragHint: "드래그하여 순서 변경", resizeHint: "드래그하여 높이 조절", }, pluginLauncher: { chat: { label: "채팅" }, dashboard: { label: "대시보드" }, automations: { label: "자동화" }, wiki: { label: "위키" }, collections: { label: "컬렉션" }, feeds: { label: "피드" }, accounting: { label: "회계" }, files: { label: "파일" }, }, shortcuts: { pin: "런처에 고정", unpin: "런처에서 고정 해제", zoneAriaLabel: "고정된 바로가기", reorder: { open: "바로가기 순서 변경", title: "순서 변경", moveUp: "위로", moveDown: "아래로", }, }, fileContentHeader: { showRendered: "렌더링된 Markdown 표시", showRaw: "원본 표시", rendered: "렌더링", raw: "원본", closeFile: "파일 닫기", revealInOs: "폴더에서 보기", revealInOsFailed: "폴더를 열 수 없습니다", }, fileContentRenderer: { download: "ZIP", downloadZip: "자체 포함 zip으로 다운로드(에셋 포함)", downloadError: "다운로드 실패", selectFile: "파일을 선택하세요", htmlPreview: "HTML 미리보기", pdfPreview: "PDF 미리보기", parseError: "파싱 오류", editJson: "JSON 편집", jsonEditorLabel: "JSON 편집기", invalidJson: "잘못된 JSON", undo: "실행 취소", redo: "다시 실행", editMarp: "슬라이드 소스 편집", marpEditorLabel: "Marp 슬라이드 소스", openInOs: "OS에서 열기", openingInOs: "여는 중…", openInOsFailed: "OS에서 열 수 없습니다", }, filesView: { chatPlaceholder: "이 파일에 대해 질문하세요…", }, systemFiles: { schemaLabel: "스키마", showDetails: "자세히 보기", hideDetails: "자세히 숨기기", editPolicy: { "agent-managed-but-hand-editable": "에이전트 관리 (수동 편집 가능)", "user-editable": "사용자 편집 가능", "agent-managed": "에이전트 관리", "fragile-format": "취약한 형식", ephemeral: "임시 파일", }, mcp: { title: "MCP 서버", summary: "에이전트에 연결된 외부 Model Context Protocol 서버. HTTP 또는 stdio 서버를 추가하여 도구를 확장할 수 있습니다.", }, settings: { title: "앱 설정", summary: "사용자 편집 가능한 동작 환경설정 — Gemini API 키, 허용된 도구, 샌드박스 설정 등.", }, schedulerTasks: { title: "스케줄러 작업", summary: "일정에 따라 실행되는 반복 에이전트 자동화. Automations UI 에서 관리하며, 이 파일이 디스크상의 정본입니다.", }, schedulerOverrides: { title: "스케줄러 오버라이드", summary: "시스템 기본 일정 위에 덮어쓰는 작업별 시간 / 간격 오버라이드. 반복 작업 시간을 변경해 달라고 요청하면 에이전트가 여기에 기록합니다.", }, schedulerItems: { title: "스케줄러 아이템 큐", summary: "발화 대기 중인 예약 호출 큐. 에이전트 관리 — 각 필드의 의미를 정확히 알지 않으면 수동 편집하지 마세요.", }, wikiIndex: { title: "위키 인덱스", summary: "모든 위키 페이지의 자동 생성 인덱스. 위키 편집 시마다 새로 갱신되므로 수동 편집하면 덮어써집니다.", }, wikiLog: { title: "위키 편집 로그", summary: "위키 페이지 생성 및 편집 활동 로그. 에이전트 관리이며 추가만 가능 — 최근 변경 피드로 유용합니다.", }, wikiSummary: { title: "위키 요약", summary: "위키의 자동 생성 개요 — 주제 클러스터, 페이지 수, 최근 활동. 에이전트가 새로 갱신합니다.", }, wikiSchema: { title: "위키 스키마", summary: "에이전트가 위키 페이지 일관성을 유지하기 위해 참조하는 형식 명세. 취약 — 특정 구조를 기대하므로 에이전트 주도 편집을 권장합니다.", }, memory: { title: "메모리", summary: "당신에 관한 정제된 사실로, 새 대화의 컨텍스트로 항상 로드됩니다. journal 추출기가 자동으로 추가하며 수동 편집도 가능합니다.", }, summariesIndex: { title: "요약 인덱스", summary: "journal 이 생성하는 일별 및 주제별 요약 링크 모음. 에이전트 관리 — journal 실행 시마다 새로 갱신됩니다.", }, rolesJson: { title: "역할 정의 (JSON)", summary: "역할 설정 — 모델 선택, MCP 서버, 허용 플러그인, 쿼리 제안. 사용자 편집 가능, 재시작 불필요.", }, rolesMd: { title: "역할 설명 (Markdown)", summary: "역할의 페르소나와 시스템 프롬프트 본문. 이 역할이 활성화되면 컨텍스트로 로드됩니다. 사용자 편집 가능, 다음 메시지부터 적용.", }, journalDaily: { title: "일별 journal 요약", summary: "journal 패스가 채팅 세션에서 추출한 하루치 활동의 자동 생성 요약입니다.", }, journalTopic: { title: "주제별 journal", summary: "특정 주제에 대한 장기 메모로, 해당 주제에 대한 대화가 이어질수록 누적되고 갱신됩니다. 에이전트 관리.", }, }, settingsMcpTab: { explanation: "외부 MCP 서버를 추가합니다. HTTP 서버는 모든 모드에서 동작합니다. Stdio 서버는 샌드박스 이미지의 {npx} / {node} / {tsx} 를 사용하며, Docker 가 활성화된 경우 경로는 워크스페이스 안에 있어야 합니다.", localhostRewrite: "Docker 모드에서는 {localhost} 가 {hostDockerInternal} 로 재작성됩니다.", noServers: "아직 구성된 MCP 서버가 없습니다.", enabled: "활성화됨", urlLabel: "URL:", commandLabel: "명령:", dockerStdioUnsupported: "⚠ Docker 샌드박스가 켜져 있는 동안에는 실행되지 않습니다.", dockerStdioHostExecActive: "⚠ 호스트에서 실행됩니다 — 이 서버는 Docker 샌드박스를 벗어납니다.", dockerStdioHostExecOptIn: "그래도 호스트에서 실행(고급). 이 서버는 로컬 HTTP 게이트웨이를 통해 Docker 샌드박스 밖에서 실행되며 컴퓨터에 접근할 수 있습니다.", learnMore: "자세히 보기", addServerButton: "+ MCP 서버 추가", nameLabel: "이름", namePlaceholder: "my-server", typeHttp: "HTTP", typeStdio: "Stdio (명령)", urlFieldLabel: "URL", urlPlaceholder: "https://example.com/mcp", commandFieldLabel: "명령", argsLabel: "인자 (한 줄에 하나)", // Message function 형태 — vue-i18n 의 메시지 컴파일러를 우회해 // 리터럴 `@` 가 linked message 참조로 해석되는 것을 막습니다. argsPlaceholder: () => "-y\n@modelcontextprotocol/server-filesystem\n/workspace/path", errNoName: "이름을 입력하거나, 이름을 유추할 수 있는 URL / 인자를 입력하세요.", errBadName: "이름은 소문자로 시작해야 하며 [a-z0-9_-] 만 포함할 수 있습니다.", errIdExists: '서버 id "{id}" 는 이미 존재합니다.', errBadHttpUrl: "HTTP URL 은 http:// 또는 https:// 로 시작해야 합니다", pendingEntryWarning: "대기 중인 MCP 서버 항목을 완료하거나 취소하세요.", customHeading: "사용자 정의 서버", catalog: { heading: "사전 설정된 MCP 서버", audience: { general: "🟢 일반", developer: "🔵 개발자" }, risk: { low: "낮음", medium: "중간", high: "높음" }, upstream: "📦 소스", setupGuide: "📚 설정", entry: { memory: { displayName: "메모리", description: "Claude 가 세션을 넘어 대화 내용을 기억합니다.", }, sequentialThinking: { displayName: "단계별 사고", description: "복잡한 문제를 단계별로 해결하도록 돕습니다.", }, context7: { displayName: "Context7 (라이브러리 문서)", description: "주요 라이브러리의 최신 문서를 가져옵니다 — 모델의 학습 시점을 넘어선 정보원.", }, deepwiki: { displayName: "DeepWiki (GitHub 저장소 위키)", description: "임의의 GitHub 저장소에 질문하여 위키 스타일의 구조화된 답변을 받습니다.", }, notion: { displayName: "Notion", description: "Notion 워크스페이스 읽기·쓰기 — 페이지, 데이터베이스, 검색 지원.", field: { apiKey: { label: "Notion 통합 토큰", help: "Notion 통합을 만들고 Internal Integration Secret 을 복사하세요. 🔑 로 통합 페이지를 열 수 있습니다.", }, }, }, slack: { displayName: "Slack", description: "Slack 워크스페이스 채널 목록, 메시지 전송, 기록 검색.", field: { botToken: { label: "Bot 토큰", help: "Slack 앱 → OAuth & Permissions → Bot User OAuth Token. xoxb- 로 시작합니다.", }, teamId: { label: "팀 / 워크스페이스 ID", help: "team.info 호출 또는 워크스페이스 URL 에서 확인 — T01ABC23DEF 형식입니다.", }, }, }, googleMaps: { displayName: "Google Maps", description: "장소 검색, 경로 안내, 위치 정보 조회.", field: { apiKey: { label: "Google Maps API 키", help: "Google Cloud Console → APIs & Services → Credentials → API 키 만들기. Places + Directions 활성화.", }, }, }, appleNative: { displayName: "Apple 네이티브 앱 (macOS)", description: "AppleScript로 미리 알림 / 캘린더 / 메모 / 메일 / 지도 읽기·쓰기. macOS 전용 — 자격 증명 불필요.", }, gmail: { displayName: "Gmail", description: "Gmail 읽기·전송·라벨 지정. 사용자 본인의 Google Cloud 프로젝트에서 발급한 OAuth 클라이언트를 사용 (앱 검수 불필요).", field: { credentials: { label: "credentials.json 경로", help: "Google Cloud Console → APIs & Services → Credentials → OAuth 클라이언트 ID (Desktop app). credentials.json을 다운로드하여 절대 경로를 입력하세요.", }, }, }, googleCalendar: { displayName: "Google 캘린더", description: "Google 캘린더 일정 읽기·생성. Gmail과 동일한 BYO credentials.json 방식.", field: { credentials: { label: "credentials.json 경로", help: "Gmail과 동일한 Google Cloud OAuth 클라이언트를 재사용하거나, 캘린더 전용으로 별도 생성하세요.", }, }, }, googleDrive: { displayName: "Google 드라이브", description: "Google 드라이브 파일 검색·읽기. BYO Google OAuth 자격 증명 — 토큰은 로컬에 캐시됩니다.", field: { credentials: { label: "credentials.json 경로", help: "Google Cloud Console → APIs & Services → Credentials → OAuth 클라이언트 ID (Desktop app). 동일 프로젝트에서 Google Drive API를 활성화하세요.", }, }, }, github: { displayName: "GitHub", description: "Personal Access Token으로 리포지토리 / 이슈 / PR / 검색 액세스. 토큰 범위를 좁게 설정하세요 — 쓰기 범위(`repo` 등)를 부여하면 에이전트가 접근 가능한 모든 리포지토리에 push할 수 있습니다.", field: { token: { label: "Personal Access Token", help: "GitHub → Settings → Developer settings → Personal access tokens. 에이전트가 다룰 리포지토리만 지정하는 fine-grained token을 권장합니다.", }, }, }, linear: { displayName: "Linear", description: "Personal API key로 Linear의 이슈 / 프로젝트 / 사이클 읽기·쓰기.", field: { apiKey: { label: "Linear API 키", help: "Linear → Settings → API → Personal API keys. 🔑 를 눌러 페이지를 열고 Create key 를 클릭하세요.", }, }, }, weatherOpenMeteo: { displayName: "날씨 (Open-Meteo)", description: "전 세계 무료 일기예보와 현재 기상 정보 — API 키 불필요.", }, spotify: { displayName: "Spotify", description: "트랙 검색, 플레이리스트 관리, 재생 제어. BYO Spotify 개발자 앱 — Client ID만 (PKCE 플로우, Client Secret 불필요).", field: { clientId: { label: "Client ID", help: "Spotify Developer Dashboard → Create app, Redirect URI를 http://127.0.0.1:8888/callback 으로 설정, Client ID 복사. 그 다음 터미널에서 한 번만 `SPOTIFY_CLIENT_ID= npx spotify-mcp@latest auth` 실행해 로그인하세요 (리프레시 토큰은 ~/.spotify-mcp/tokens.json 에 캐시).", }, }, }, youtubeTranscript: { displayName: "YouTube 자막", description: "공개된 YouTube 동영상의 URL로 자막을 가져옵니다. 자격 증명 불필요.", }, }, config: { howToGet: "발급 방법", install: "설치", errMissingRequired: "필수 항목 누락: {fields}", requiredMarker: "*", requiredAria: "필수", }, }, }, pluginScheduler: { previewIcon: "📅", previewAutomations: "자동화 {count}개", previewMore: "+ {count}개 더…", }, pluginSchedulerTasks: { recommendedFrequencies: "권장 주기", tableTaskType: "작업 유형", tableSuggestedSchedule: "권장 일정", noTasks: "예약된 작업이 없습니다", runNow: "지금 실행", enable: "활성화", disable: "비활성화", delete: "삭제", nextRun: "다음 실행: {time}", originSystem: "시스템", originUser: "사용자", originSkill: "스킬", runFailed: "실행 실패: {error}", toggleFailed: "토글 실패: {error}", deleteFailed: "삭제 실패: {error}", detailsToggle: "상세 보기", promptLabel: "프롬프트", roleLabel: "역할", confirmDelete: "작업 「{name}」을(를) 삭제하시겠습니까? 되돌릴 수 없습니다.", hintNewsRss: "뉴스 / RSS 가져오기", hintJournal: "일일 저널 처리", hintWiki: "위키 유지 관리", hintMemory: "메모리 추출", hintCalendar: "캘린더 / 연락처 동기화", }, pluginCanvas: { undo: "실행 취소", redo: "다시 실행", clear: "지우기", styleLabel: "스타일:", stylePromptWithPath: "`{path}`의 이미지를 {style} 스타일 이미지로 변환해 주세요.", stylePromptNoPath: "캔버스에 그린 그림을 {style} 스타일 이미지로 변환해 주세요.", saveFailed: "저장 안 됨", }, pluginWiki: { backToIndex: "목차로 돌아가기", pdf: "PDF", pdfFailed: "⚠ PDF 실패", tabIndex: "목차", tabLog: "로그", tabLint: "Lint", tabGraph: "그래프", graphEmpty: "아직 그래프로 표시할 링크가 없습니다.", linkedReferences: "역링크", empty: "Wiki 가 비어 있습니다. Wiki Manager 에게 소스를 수집하도록 요청하세요.", previewMore: "+ {count}개 더…", chatPlaceholder: "이 페이지에 대해 질문…", emptyPage: "「{title}」 페이지가 아직 없습니다.", emptyContent: "「{title}」 페이지는 존재하지만 내용이 없습니다.", createPage: "이 Wiki 페이지 작성 요청", updatePage: "이 Wiki 페이지 업데이트 요청", tagFilterAll: "전체", noMatches: "#{tag} 태그가 달린 페이지가 없습니다", lintChat: "Wiki 점검", taskCountMismatch: "Wiki 원본과 렌더링 결과의 작업 수가 일치하지 않아, 파일 손상을 방지하기 위해 토글이 거부되었습니다.", metadataCreated: "생성", metadataUpdated: "업데이트", metadataEditor: "편집자", pageEditHeader: "Wiki 편집", snapshotExpired: "스냅샷 만료됨 — 현재 페이지 표시 중", snapshotLoadError: "스냅샷을 불러오지 못했습니다 — 페이지가 여전히 존재할 수 있습니다. 새로고침해 보세요.", pageDeleted: "페이지가 삭제되었습니다", history: { tabContent: "본문", tabHistory: "기록", empty: "아직 기록이 없습니다 — 이 페이지를 편집하면 첫 번째 버전이 여기에 기록됩니다.", loading: "기록을 불러오는 중…", backToList: "기록 목록으로 돌아가기", restoreButton: "이 버전으로 복원", restoreConfirmTitle: "이 버전으로 복원하시겠습니까?", restoreConfirmBody: "{editor}이(가) {ts}에 저장한 버전으로 페이지를 복원합니다. 현재 페이지는 교체되지만 기존 기록은 유지됩니다.", restoreConfirmAction: "복원", restoreConfirmCancel: "취소", restoreSuccessToast: "페이지를 복원했습니다.", restoreFailureBanner: "복원에 실패했습니다: {error}", compareCurrent: "현재 페이지와 비교", comparePrevious: "이전 버전과 비교", diffNoPrevious: "비교할 이전 버전이 없습니다.", diffNoChanges: "이 버전과 비교 대상 사이에 내용 차이가 없습니다.", editorBadgeUser: "사용자", editorBadgeLLM: "LLM", editorBadgeSystem: "시스템", hiddenLines: "변경되지 않은 {count}줄 숨김", expandHidden: "표시", }, }, pluginPresentForm: { fallbackTitle: "양식", fieldCount: "{count}개 항목", submitted: "제출됨", errorSummary: "다음 오류를 수정해주세요", requiredMarker: "*", selectOption: "선택하세요", charactersCount: "{current} / {max} 자", charactersCountNoMax: "{current} 자", submit: "제출", progress: "필수 항목 {total}개 중 {filled}개 입력됨", }, pluginPresentSvg: { saveAsPng: "PNG 로 다운로드", png: "PNG", saveAsPdf: "PDF 로 저장 (인쇄 대화 상자 열기)", pdf: "PDF", untitled: "SVG 도형", editSource: "SVG 소스 편집", cancel: "취소", applyChanges: "변경 사항 적용", saving: "저장 중...", saveError: "⚠ 저장 실패: {error}", exportError: "⚠ 내보내기 실패: {error}", loadingSource: "소스를 불러오는 중…", sourceError: "소스 로드 실패: {error}", }, photoLocations: { title: "사진 위치 정보", summary: "{total}개 캡처됨 · {withGps}개 GPS 포함", mapHint: 'Claude에게 "지도에 표시해줘"라고 요청하면 Google Map 플러그인으로 일괄 표시됩니다.', loading: "로드 중…", empty: "아직 캡처된 사진 위치가 없습니다. GPS 태그가 있는 사진을 채팅이나 연결된 bridge로 보내면 누적되기 시작합니다.", noGps: "GPS 데이터 없음", }, pluginManageSkills: { deleteProjectSkill: "이 프로젝트 스킬 삭제", unstarPresetSkill: "이 프리셋 별표 해제 — 카탈로그로 돌아갑니다", heading: "스킬", previewCount: "{count}개 스킬", previewMore: "+{count}개 더", // 함수 형식으로 vue-i18n 의 메시지 컴파일러를 우회한다. 일반 // 문자열이면 `` 이 HTML 조각으로 간주되어 매번 "Detected // HTML in '…' message" 경고가 발생한다. subheading: ({ named }: { named: (key: string) => unknown }) => `${named("count")}개 사용 가능 · 클릭해서 보기 · "Run" 은 / 형식으로 호출합니다`, emptyWithPath: "스킬을 찾을 수 없습니다. {path} 아래에 스킬 폴더를 추가하세요.", emptySkillPath: "~/.claude/skills/", selectHint: "왼쪽에서 스킬을 선택해 SKILL.md 를 확인하세요.", loading: "불러오는 중…", fieldDescription: "설명", fieldBody: "본문 (Markdown)", emptyBody: "(본문 비어 있음)", btnEdit: "편집", btnDelete: "삭제", btnUnstar: "별표 해제", errListFailed: "스킬 목록 불러오기 실패: {error}", errDetailFailed: "스킬 상세 불러오기 실패: {error}", errSaveFailed: "저장 실패: {error}", errDeleteFailed: "삭제 실패", confirmDelete: '스킬 "{name}" 을(를) 삭제할까요? ~/mulmoclaude/.claude/skills/{name}/SKILL.md 가 제거됩니다.', confirmUnstar: '"{name}" 을(를) 카탈로그로 되돌릴까요? 프롬프트에는 더 이상 로드되지 않지만, 카탈로그의 복사본은 남아 있어 언제든 다시 별표할 수 있습니다.', sectionActive: "활성", sectionCatalog: "카탈로그", sectionLegendActive: "Claude가 지금 사용할 수 있는 스킬. 대화 흐름에서 Claude가 자동으로 사용하거나, 스킬 이름을 입력해 호출할 수 있습니다. {system} 시스템(동봉 mc-) / {project} 프로젝트(편집 가능, 이 워크스페이스 전용) / {user} 사용자(~/.claude/skills/ 의 스킬).", sectionLegendCatalog: "카탈로그: {star}를 누르면 활성이 되는 스킬. 활성에서 {star}를 해제하면 카탈로그로 돌아가고 Claude는 사용하지 않게 됩니다 (스킬은 삭제되지 않습니다).", catalogEmpty: "사용 가능한 프리셋 스킬이 없습니다.", catalogPresetHeading: "프리셋", catalogStar: "별 표시", catalogStarred: "별 표시됨", sourceUserTitle: "사용자 스킬 (~/.claude/skills/, 모든 워크스페이스 공통)", sourceSystemTitle: "시스템 스킬 (동봉, mc- 접두사 — 읽기 전용, 런처 부팅 시 덮어씀)", sourceProjectTitle: "프로젝트 스킬 (워크스페이스 .claude/skills/, 이 워크스페이스 전용)", sourcePresetTitle: "프리셋 카탈로그 — 별 표시를 눌러 이 워크스페이스에 활성화", errCatalogListFailed: "카탈로그를 불러오지 못했습니다: {error}", errCatalogStarFailed: "스킬에 별 표시를 추가하지 못했습니다: {error}", errCatalogPreviewFailed: "스킬 미리보기를 불러오지 못했습니다: {error}", catalogAddRepo: "스킬 저장소 추가", catalogAddRepoTitle: "스킬 저장소 추가", catalogRepoUrlLabel: "GitHub URL", catalogRepoUrlPlaceholder: "https://github.com/owner/repo", catalogRepoSubpathLabel: "하위 경로 (선택)", catalogRepoSubpathPlaceholder: "skills", catalogAddRepoSubmit: "설치", catalogAddRepoSuggestions: "추천 저장소", catalogUninstallRepo: "저장소 제거", catalogUpdateRepo: "저장소 업데이트(최신 다시 가져오기)", catalogRepoOpenLink: "GitHub에서 저장소 열기(새 탭)", catalogUninstallConfirm: "이 저장소를 제거할까요? 이미 별표한 스킬은 활성 목록에 남습니다.", catalogRepoInstalling: "설치 중…", catalogRepoEmpty: "이 저장소에서 스킬을 찾을 수 없습니다.", sourceExternalTitle: "외부 스킬 (GitHub 저장소에서 설치 — 별표로 활성화)", errCatalogRepoListFailed: "설치된 저장소를 불러오지 못했습니다: {error}", errCatalogRepoInstallFailed: "저장소 설치에 실패했습니다: {error}", errCatalogRepoUninstallFailed: "저장소 제거에 실패했습니다: {error}", errCatalogRepoInvalidUrl: "GitHub 저장소 URL을 입력하세요.", }, pluginManageRoles: { heading: "커스텀 역할", roleCount: "{count}개 역할", addButton: "+ 추가", createPanel: "새 역할 만들기", fieldId: "ID", fieldName: "이름", fieldIcon: "아이콘", fieldPrompt: "프롬프트", fieldPlugins: "플러그인", fieldStarterQueries: "시작 질문", onePerLine: "(한 줄에 하나)", helpLink: "?", idFormatted: "({id})", missingEnv: "({env} 누락)", requiresEnv: ".env 에 {env} 가 필요합니다", collapse: "접기", expand: "펼치기", idPlaceholder: "unique-id", creating: "생성 중…", create: "생성", updating: "업데이트 중…", update: "업데이트", cancel: "취소", delete: "삭제", emptyHint: '아직 커스텀 역할이 없습니다. "+ 추가" 를 누르거나 Claude 에게 만들어달라고 요청하세요.', errIdRequired: "ID 는 필수입니다.", errIdInvalid: "ID 는 영문, 숫자, '-', '_' 만 포함할 수 있습니다.", errNameRequired: "이름은 필수입니다.", errIdDuplicate: "ID 가 '{id}' 인 역할이 이미 존재합니다.", errCreateFailed: "생성 실패", errSaveFailed: "저장 실패", errDeleteFailed: "삭제 실패", errNetworkError: "네트워크 오류", errServerError: "서버 오류: {status}", errRefreshFailed: "저장했지만 목록을 새로고침하지 못했습니다.", confirmDelete: "역할 「{name}」을(를) 삭제하시겠습니까? 되돌릴 수 없습니다.", }, pluginUiImage: { promptLabel: "{label}:", }, markdownMermaid: { loadFailed: "⚠ Mermaid 로드 실패: {error}", renderFailed: "⚠ Mermaid 렌더링 실패: {error}", }, pluginTextResponse: { pdf: "PDF", pdfFailed: "⚠ PDF 실패", editContent: "텍스트 내용 편집", applyChanges: "변경 사항 적용", copyLabel: "복사", speakerSystem: "시스템", speakerUser: "나", speakerAssistant: "어시스턴트", copiedLabel: "복사됨!", cancel: "취소", seededByPlugin: "{pkg}에서", seededByPluginTooltip: "이 메시지는 사용자가 보낸 것이 아니라 {pkg} 플러그인에서 작성한 것입니다.", truncatedForRender: "이 메시지는 매우 깁니다(총 {total}자). 탭이 멈추지 않도록 앞부분만 표시됩니다 — {omitted}자 숨김. 전체 원문은 복사 버튼으로 가져올 수 있습니다.", }, pluginSkill: { noDescription: "(설명 없음)", }, pluginSpreadsheet: { previewUntitled: "스프레드시트", previewSheets: "{count}개 시트", untitled: "스프레드시트", excel: "Excel", valuePlaceholder: "값", valueOrFormulaPlaceholder: "값 또는 수식 (예: 100 또는 SUM(B2:B11))", formatPlaceholder: "형식 (예: $#,##0.00)", loading: "스프레드시트를 불러오는 중...", noData: "사용 가능한 스프레드시트 데이터가 없습니다", editData: "스프레드시트 데이터 편집", applyChanges: "변경 사항 적용", dataMustBeArray: "데이터는 시트 배열이어야 합니다", loadFailed: "스프레드시트 불러오기 실패: {error}", invalidJsonAlert: "잘못된 JSON 형식: {error}", unknownError: "알 수 없는 오류", update: "업데이트", stringType: "문자열", formulaType: "수식", }, app: { startConversation: "대화 시작", thinking: "생각 중…", }, suggestionsPanel: { suggestions: "추천", skills: "스킬", tooltip: "추천 및 스킬", emptySuggestions: "추천이 없습니다.", emptySkills: "설치된 스킬이 없습니다.", skillsError: "스킬을 불러오지 못했습니다: {error}", sendEditHint: "클릭하여 전송 · shift+클릭 으로 편집", }, settingsToolsTab: { // 에서 명명 슬롯 `allowedTools` 와 `claudeMcp` 로 렌더링되므로 // `` 태그는 스타일을 유지하면서 본문은 번역 가능합니다. explanation: "{allowedTools} 를 통해 Claude 에 전달할 추가 도구 이름. 한 줄에 하나씩. {claudeMcp} 로 인증을 완료한 후 Claude Code 내장 MCP 서버 (Gmail / Google 캘린더 등) 를 사용할 때 유용합니다.", connectorsSectionTitle: "연결된 커넥터", connectorsEmpty: "커넥터를 찾을 수 없습니다.", connectorConnected: "연결됨", connectorDisconnected: "연결 안 됨", connectorsGuide: "Slack, Gmail 등의 커넥터로 Claude가 계정에 접근할 수 있습니다. 커넥터 추가 및 제거는 Claude Desktop 또는 {configLink}에서 할 수 있습니다. (claude.ai로 이동합니다)", connectorsConfigLinkText: "여기", }, confirmModal: { defaultTitle: "확인", defaultConfirm: "확인", defaultCancel: "취소", }, }; export default koMessages;