diff --git a/desktop/src/i18n/index.test.tsx b/desktop/src/i18n/index.test.tsx index 9247db29c..fc675998c 100644 --- a/desktop/src/i18n/index.test.tsx +++ b/desktop/src/i18n/index.test.tsx @@ -1,7 +1,7 @@ import { act, renderHook } from '@testing-library/react' import { afterEach, describe, expect, it } from 'vitest' import { useSettingsStore } from '../stores/settingsStore' -import { useTranslation } from '.' +import { translate, useTranslation } from '.' describe('useTranslation', () => { afterEach(() => { @@ -26,4 +26,17 @@ describe('useTranslation', () => { }) expect(result.current).not.toBe(initial) }) + + it('resolves every registered locale to its own translation', () => { + expect(translate('en', 'common.save')).toBe('Save') + expect(translate('zh', 'common.save')).toBe('保存') + expect(translate('zh-TW', 'common.save')).toBe('儲存') + expect(translate('jp', 'common.save')).toBe('保存') + expect(translate('kr', 'common.save')).toBe('저장') + }) + + it('interpolates params across the new locales', () => { + expect(translate('jp', 'session.timeMinutes', { n: 5 })).toBe('5 分前') + expect(translate('kr', 'session.timeMinutes', { n: 5 })).toBe('5분 전') + }) }) diff --git a/desktop/src/i18n/index.ts b/desktop/src/i18n/index.ts index f7964c1fe..95b854e85 100644 --- a/desktop/src/i18n/index.ts +++ b/desktop/src/i18n/index.ts @@ -2,10 +2,19 @@ import { useCallback } from 'react' import { useSettingsStore } from '../stores/settingsStore' import { en, type TranslationKey } from './locales/en' import { zh } from './locales/zh' +import { zh as zhTW } from './locales/zh-TW' +import { jp } from './locales/jp' +import { kr } from './locales/kr' -export type Locale = 'en' | 'zh' +export type Locale = 'en' | 'zh' | 'zh-TW' | 'jp' | 'kr' -const translations: Record> = { en, zh } +const translations: Record> = { + en, + zh, + 'zh-TW': zhTW, + jp, + kr, +} /** * Translate a key with optional interpolation params. diff --git a/desktop/src/i18n/locales/jp.ts b/desktop/src/i18n/locales/jp.ts new file mode 100644 index 000000000..98d26b176 --- /dev/null +++ b/desktop/src/i18n/locales/jp.ts @@ -0,0 +1,1702 @@ +import type { TranslationKey } from './en' + +export const jp: Record = { + // ─── Common ────────────────────────────────────── + 'common.cancel': 'キャンセル', + 'common.save': '保存', + 'common.delete': '削除', + 'common.add': '追加', + 'common.run': '実行', + 'common.send': '送信', + 'common.stop': '停止', + 'common.rename': '名前を変更', + 'common.retry': '再試行', + 'common.loading': '読み込み中...', + 'common.select': '選択', + 'common.enable': '有効化', + 'common.disable': '無効化', + 'common.active': 'アクティブ', + 'common.error': 'エラー', + 'common.copyFailed': 'コピーに失敗しました。', + + // ─── Sidebar ────────────────────────────────────── + 'sidebar.newSession': '新しいセッション', + 'sidebar.scheduled': 'スケジュール', + 'sidebar.terminal': 'ターミナル', + 'sidebar.settings': '設定', + 'sidebar.searchPlaceholder': 'セッションを検索...', + 'sidebar.noSessions': 'セッションがありません', + 'sidebar.noMatching': '一致するセッションがありません', + 'sidebar.sessionListFailed': 'セッション一覧の読み込みに失敗しました', + 'sidebar.refreshSessions': 'セッションを更新', + 'sidebar.projects': 'プロジェクト', + 'sidebar.projectMenu': 'プロジェクトメニュー', + 'sidebar.newProject': '新しいプロジェクト', + 'sidebar.archiveAllChats': 'すべてのチャットをアーカイブ', + 'sidebar.organizeSidebar': 'サイドバーを整理', + 'sidebar.sortCondition': '並び替え条件', + 'sidebar.organizeByProject': 'プロジェクト別', + 'sidebar.organizeByRecentProject': '最近のプロジェクト', + 'sidebar.organizeByTime': '時間順', + 'sidebar.sortByCreatedAt': '作成日時', + 'sidebar.sortByUpdatedAt': '更新日時', + 'sidebar.newBlankProject': '新しい空のプロジェクト', + 'sidebar.useExistingFolder': '既存のフォルダを使用', + 'sidebar.chooseProjectFolderUnavailable': 'フォルダの選択はデスクトップアプリでのみ利用できます。', + 'sidebar.projectActions': '{project} のプロジェクト操作', + 'sidebar.pinProject': 'プロジェクトをピン留め', + 'sidebar.unpinProject': 'ピン留めを解除', + 'sidebar.openInFinder': 'Finder で開く', + 'sidebar.openInFinderFailed': 'プロジェクトを Finder で開けませんでした。', + 'sidebar.openInFinderUnavailable': '利用できるファイルマネージャーがありません。', + 'sidebar.hideProjectFromSidebar': 'サイドバーから非表示', + 'sidebar.restoreProjectToSidebar': 'サイドバーに復元', + 'sidebar.restoreHiddenProjects': '非表示のプロジェクトを復元 ({count})', + 'sidebar.projectHidden': '{project} をサイドバーから非表示にしました。既存のセッションは削除されていません。', + 'sidebar.newSessionInProject': '{project} で新しいセッション', + 'sidebar.showMoreSessions': '表示を展開', + 'sidebar.showFewerSessions': '表示を折りたたむ', + 'sidebar.expandProject': '{project} を展開', + 'sidebar.collapseProject': '{project} を折りたたむ', + 'sidebar.worktree': 'worktree', + 'sidebar.sessionRunning': 'セッション実行中', + 'sidebar.missingDir': 'ディレクトリがありません', + 'sidebar.confirmDelete': 'このセッションを削除しますか?この操作は取り消せません。', + 'sidebar.batchManage': '一括管理', + 'sidebar.batchSelectedCount': '{count} 件選択中', + 'sidebar.batchSelectAll': 'すべて選択', + 'sidebar.batchDeselectAll': 'すべて選択解除', + 'sidebar.batchSelectGroup': '{group} を選択', + 'sidebar.batchDeleteSelected': '選択項目を削除 ({count})', + 'sidebar.batchDeleteConfirm': '{count} 件のセッションを削除しますか?この操作は取り消せません。', + 'sidebar.batchDeleteConfirmBody': '以下のセッションが削除されます:', + 'sidebar.batchDeleteMore': '...他 {count} 件', + 'sidebar.batchExit': '一括モードをキャンセル', + 'sidebar.batchDeleteSucceeded': '{count} 件のセッションを削除しました。', + 'sidebar.batchDeleteFailed': '{count} 件のセッションを削除できませんでした。', + 'sidebar.allProjects': 'すべてのプロジェクト', + 'sidebar.other': 'その他', + 'sidebar.timeGroup.today': '今日', + 'sidebar.timeGroup.yesterday': '昨日', + 'sidebar.timeGroup.last7days': '過去 7 日間', + 'sidebar.timeGroup.last30days': '過去 30 日間', + 'sidebar.timeGroup.older': 'それ以前', + 'sidebar.collapse': 'サイドバーを折りたたむ', + 'sidebar.expand': 'サイドバーを展開', + + // ─── Title Bar ────────────────────────────────────── + 'titlebar.code': 'コード', + 'titlebar.terminal': 'ターミナル', + 'titlebar.history': '履歴', + + // ─── Open Project ────────────────────────────────────── + 'openProject.openProject': 'プロジェクトを開く', + 'openProject.openIn': '{target} で開く', + 'openProject.openFailed': 'プロジェクトを開けませんでした', + + // ─── Open With ───────────────────────────────────── + 'openWith.title': '開く方法', + 'openWith.inAppBrowser': 'アプリ内ブラウザ', + 'openWith.systemBrowser': 'システムブラウザ', + 'openWith.workspacePreview': 'ワークスペースプレビュー', + 'openWith.openInTarget': '{target} で開く', + 'openWith.revealInTarget': '{target} で表示', + 'openWith.fileType.document': 'ドキュメント', + 'openWith.fileType.web': 'Web', + 'openWith.fileType.image': '画像', + 'openWith.fileType.code': 'コード', + 'openWith.fileType.file': 'ファイル', + + // ─── Assistant Output Targets ────────────────────── + 'assistantOutputs.kind.markdown': 'Markdown', + 'assistantOutputs.kind.html': 'HTML', + 'assistantOutputs.kind.image': '画像', + 'assistantOutputs.kind.localhost': 'Localhost', + 'assistantOutputs.moreOutputs': '+{count} 件', + 'assistantOutputs.open': '開く', + + // ─── Workspace Panel ─────────────────────────────── + 'workspace.changedFiles': '変更されたファイル', + 'workspace.allFiles': 'すべてのファイル', + 'workspace.viewTabs': 'ワークスペースビュー', + 'workspace.previewTabs': 'プレビュータブ', + 'workspace.filterPlaceholder': 'ファイルを絞り込み...', + 'workspace.clearFilter': 'ファイルフィルターをクリア', + 'workspace.refresh': 'ワークスペースを更新', + 'workspace.closePanel': 'ワークスペースパネルを閉じる', + 'workspace.resizePanel': 'ワークスペースパネルのサイズを変更', + 'workbench.modeSwitch': 'ワークベンチモード', + 'workbench.modeWorkspace': 'ファイル', + 'workbench.modeBrowser': 'ブラウザ', + 'workbench.close': '閉じる', + 'workspace.closeTab': 'タブを閉じる', + 'workspace.preview': 'プレビュー', + 'workspace.previewEmpty': 'プレビューするファイルを選択してください。', + 'workspace.notGitRepo': 'Git リポジトリではありません。', + 'workspace.missingWorkdir': '作業ディレクトリが見つかりません。', + 'workspace.loadError': 'ワークスペースデータの読み込みに失敗しました。', + 'workspace.noChanges': '変更なし', + 'workspace.noFiles': 'ファイルなし', + 'workspace.noMatchingFiles': '一致するファイルなし', + 'workspace.previewKind.diff': '差分', + 'workspace.previewKind.file': 'ファイル', + 'workspace.previewState.loading': 'プレビューを読み込み中...', + 'workspace.previewState.binary': 'バイナリファイルはプレビューできません。', + 'workspace.previewState.tooLarge': 'ファイルが大きすぎてプレビューできません。', + 'workspace.previewState.missing': 'ファイルが見つかりません。', + 'workspace.imagePreviewUnavailable': '画像をプレビューできません。', + 'workspace.previewLineLimit': '読み込まれた {total} 行のうち最初の {count} 行を表示しています。', + 'workspace.previewAllLines': '読み込まれた {total} 行すべてを表示しています。', + 'workspace.showAllLoadedLines': '読み込まれた行をすべて表示', + 'workspace.collapsePreview': 'プレビューを折りたたむ', + 'workspace.addToChat': 'チャットに追加', + 'workspace.addSelectionToChat': 'チャットに追加', + 'workspace.copyPath': 'パスをコピー', + 'workspace.copyAbsolutePath': '絶対パスをコピー', + 'workspace.pathCopied': 'パスをコピーしました。', + 'workspace.localComment': 'ローカルコメント', + 'workspace.commentLine': '{line} 行目にコメント', + 'workspace.commentLineTarget': '{line} 行目', + 'workspace.commentPlaceholder': 'ここで何を変更すべきか説明してください...', + 'workspace.addCommentToChat': 'コメントを追加', + + // ─── Status Bar ────────────────────────────────────── + 'status.connected': '接続済み', + 'status.connecting': '接続中...', + 'status.reconnecting': '再接続中...', + 'status.disconnected': '切断されました', + + // ─── Settings ────────────────────────────────────── + 'settings.title': '設定', + 'settings.tab.providers': 'プロバイダー', + 'settings.tab.permissions': '権限', + 'settings.tab.activity': 'トークン使用量', + 'settings.tab.general': '一般', + 'settings.tab.h5Access': 'H5 アクセス', + 'settings.tab.terminal': 'ターミナル', + 'settings.tab.skills': 'スキル', + 'settings.tab.mcp': 'MCP', + 'settings.tab.plugins': 'プラグイン', + 'settings.tab.diagnostics': '診断', + + // Settings > Usage + 'settings.activity.title': 'トークン使用量', + 'settings.activity.profileTitle': 'プロフィール', + 'settings.activity.profilePrivacy': 'ローカルのみ', + 'settings.activity.defaultHandle': 'github.com/NanmiCoder/cc-haha', + 'settings.activity.editProfile': 'プロフィールを編集', + 'settings.activity.displayName': '表示名', + 'settings.activity.subtitle': '2 行目', + 'settings.activity.displayNameHelper': '表示名と 2 行目を編集します。2 行目の URL はリンクとして開きます。', + 'settings.activity.avatar': 'アバター', + 'settings.activity.avatarHelper': 'PNG、JPEG、または WebP(最大 2 MB)。', + 'settings.activity.changeAvatar': 'アバターを変更', + 'settings.activity.removeAvatar': 'アバターを削除', + 'settings.activity.saveProfile': '保存', + 'settings.activity.cancelEdit': 'キャンセル', + 'settings.activity.profileSaved': 'ローカルに保存しました', + 'settings.activity.profileSaveFailed': 'プロフィールを保存できませんでした', + 'settings.activity.subtitleLoading': 'ローカルの Claude Code CLI セッション記録に基づきます', + 'settings.activity.totalTokens': '合計トークン数', + 'settings.activity.peakTokens': 'ピークトークン数', + 'settings.activity.longestTask': '最長タスク', + 'settings.activity.currentStreak': '現在の連続日数', + 'settings.activity.longestStreak': '最長の連続日数', + 'settings.activity.noDuration': '0分', + 'settings.activity.tokenActivity': 'トークンアクティビティ', + 'settings.activity.mode.daily': '日次', + 'settings.activity.mode.weekly': '週次', + 'settings.activity.mode.cumulative': '累積', + 'settings.activity.modeHelp.daily': '日次: 各マスはその日のトークン使用量です。', + 'settings.activity.modeHelp.weekly': '週次: 各列は 1 週間のトークン使用量の合計です。', + 'settings.activity.modeHelp.cumulative': '累積: 各列はその週までのトークン総数です。', + 'settings.activity.emptyTitle': 'ローカルの使用履歴がまだありません', + 'settings.activity.emptyBody': 'CLI またはデスクトップセッションを開始すると、完了したモデルの応答がここに表示されます。', + 'settings.activity.metric.yesterday': '昨日', + 'settings.activity.metric.today': '今日', + 'settings.activity.metric.last4': '過去 4 日間', + 'settings.activity.metric.last30': '30 日間', + 'settings.activity.metric.streak': '連続日数', + 'settings.activity.metric.bestStreak': '最高 {days} 日間', + 'settings.activity.heatmapLabel': '日別のトークン使用量', + 'settings.activity.weekRange': '{start} - {end}', + 'settings.activity.cumulativeThrough': '{date} まで', + 'settings.activity.tokenValue': '{tokens} トークン', + 'settings.activity.count.sessionOne': '{count} セッション', + 'settings.activity.count.sessionOther': '{count} セッション', + 'settings.activity.count.dayOne': '{count} 日', + 'settings.activity.count.dayOther': '{count} 日', + 'settings.activity.weekday.mon': '月', + 'settings.activity.weekday.wed': '水', + 'settings.activity.weekday.fri': '金', + 'settings.activity.selectedDay': '選択した日', + 'settings.activity.sessions': 'セッション', + 'settings.activity.tokens': 'トークン', + 'settings.activity.messages': 'メッセージ', + 'settings.activity.tools': 'ツール', + 'settings.activity.less': '少ない', + 'settings.activity.more': '多い', + + // Settings > Terminal + 'settings.terminal.title': 'ターミナル', + 'settings.terminal.description': 'プラグイン、スキル、MCP のセットアップ用にホストマシンのコマンドを実行します。デスクトップアプリには claude-haha が含まれています。ドキュメントの claude を claude-haha に置き換えてください。例: claude-haha plugin install ... や claude-haha mcp add ...', + 'settings.terminal.infoLabel': 'ターミナルセットアップのヘルプ', + 'settings.terminal.clear': 'クリア', + 'settings.terminal.restart': '再起動', + 'settings.terminal.windowTitle': 'ホストシェル', + 'settings.terminal.unavailableTitle': 'デスクトップランタイムが必要です', + 'settings.terminal.unavailableBody': 'インタラクティブなターミナルを開始するには、このページをパッケージ版デスクトップアプリで開いてください。', + 'settings.terminal.preferencesTitle': '起動シェル', + 'settings.terminal.preferencesBody': '新しいターミナルセッションと再起動後に使用されます。', + 'settings.terminal.startupShell': '起動シェル', + 'settings.terminal.customPath': 'カスタムシェルのパス', + 'settings.terminal.customPathPlaceholder': 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', + 'settings.terminal.customPathRequired': '保存する前にシェルのパスを入力してください。', + 'settings.terminal.customPathAbsolute': 'カスタムシェルのパスは Windows の絶対パスである必要があります。', + 'settings.terminal.saveShell': 'シェルを保存', + 'settings.terminal.saveShellSuccess': '保存しました。適用するには再起動するか、新しいターミナルを開いてください。', + 'settings.terminal.shell.system': 'システムのデフォルト', + 'settings.terminal.shell.systemDesc': '現在の COMSPEC ベースの動作を維持します。', + 'settings.terminal.shell.pwsh': 'PowerShell 7 (pwsh)', + 'settings.terminal.shell.pwshDesc': 'インストールされている場合は pwsh.exe を使用します。', + 'settings.terminal.shell.powershell': 'Windows PowerShell', + 'settings.terminal.shell.powershellDesc': '組み込みの powershell.exe を使用します。', + 'settings.terminal.shell.cmd': 'コマンドプロンプト', + 'settings.terminal.shell.cmdDesc': 'cmd.exe を明示的に使用します。', + 'settings.terminal.shell.custom': 'カスタム実行ファイル', + 'settings.terminal.shell.customDesc': '絶対パスのシェル実行ファイルを起動します。', + 'settings.terminal.status.idle': 'アイドル', + 'settings.terminal.status.starting': '起動中', + 'settings.terminal.status.running': '実行中', + 'settings.terminal.status.exited': '終了', + 'settings.terminal.status.error': 'エラー', + 'settings.terminal.status.unavailable': '利用不可', + 'settings.terminal.bashPathLabel': 'Bash のパス', + 'settings.terminal.bashPathDescription': 'Windows ではターミナルシェルのデフォルトは CMD です。ツール呼び出しで Unix コマンド(grep、sed など)を使用する場合は、ここで Bash 実行ファイル(例: Git Bash)のパスを設定してください。', + 'settings.terminal.bashPathSave': '保存', + 'settings.terminal.bashPathReset': 'デフォルトにリセット', + 'settings.terminal.bashPathSaved': '保存しました', + 'settings.terminal.bashPathInvalid': 'パスが存在しません。有効な Bash 実行ファイルを選択してください。', + 'terminal.newTab': '新しいターミナル', + 'terminal.openInTab': 'タブで開く', + 'terminal.closePanel': 'ターミナルパネルを閉じる', + 'terminal.resizePanel': 'ターミナルパネルのサイズを変更', + + // Settings > Diagnostics + 'settings.diagnostics.title': '診断', + 'settings.diagnostics.description': '起動、プロバイダー、セッションの失敗をデバッグするためのサーバーおよび CLI ランタイムログ。', + 'settings.diagnostics.refresh': '更新', + 'settings.diagnostics.totalSize': 'ログサイズ', + 'settings.diagnostics.events': 'イベント', + 'settings.diagnostics.recentErrors': '24 時間の警告', + 'settings.diagnostics.retention': '保持期間', + 'settings.diagnostics.retentionValue': '{days} 日 / {size}', + 'settings.diagnostics.logDirectory': 'ログディレクトリ', + 'settings.diagnostics.openDirectory': '開く', + 'settings.diagnostics.exportBundle': 'バンドルをエクスポート', + 'settings.diagnostics.copySummary': 'エラー概要をコピー', + 'settings.diagnostics.clearLogs': 'ログをクリア', + 'settings.diagnostics.recentEvents': '最近のイベント', + 'settings.diagnostics.privacyNote': 'エクスポートされる診断情報はサニタイズされており、チャット内容、ファイル内容、すべての環境変数、API キーは含まれません。', + 'settings.diagnostics.noEvents': '診断イベントはまだありません。', + 'settings.diagnostics.noRecentErrors': '最近の警告やエラーはありません。', + 'settings.diagnostics.loadFailed': '診断情報の読み込みに失敗しました。', + 'settings.diagnostics.openFailed': '診断ディレクトリを開けませんでした。', + 'settings.diagnostics.exportFailed': '診断バンドルのエクスポートに失敗しました。', + 'settings.diagnostics.exported': '{file} をエクスポートしました', + 'settings.diagnostics.summaryCopied': 'エラー概要をコピーしました。', + 'settings.diagnostics.copyFailed': 'エラー概要のコピーに失敗しました。', + 'settings.diagnostics.confirmClear': 'ローカルの診断ログとエクスポート済みバンドルをすべてクリアしますか?', + 'settings.diagnostics.cleared': '診断情報をクリアしました。', + 'settings.diagnostics.clearFailed': '診断情報のクリアに失敗しました。', + 'settings.diagnostics.eventDetails': '詳細', + 'settings.diagnostics.doctorTitle': 'Doctor', + 'settings.diagnostics.doctorDescription': '起動および UI 状態の問題に対する安全なデスクトップ修復。', + 'settings.diagnostics.doctorProtectedData': 'チャット履歴、モデル設定、スキル、MCP、IM、OAuth には一切影響しません。', + 'settings.diagnostics.doctorSafeKeys': 'クリアされるのは次のみ: cc-haha-open-tabs、cc-haha-session-runtime、cc-haha-theme、cc-haha-locale、cc-haha.persistence.schemaVersion。', + 'settings.diagnostics.runDoctor': 'Doctor を実行', + 'settings.diagnostics.doctorCompleted': 'Doctor が完了しました。', + 'settings.diagnostics.doctorPartial': 'Doctor は完了しましたが、{count} 件のローカルクリーンアップの問題があります。', + 'settings.diagnostics.doctorFailed': 'Doctor が失敗しました。', + 'settings.diagnostics.doctorResultLocal': '{count} 件の安全な UI キーをクリアしました。', + 'settings.diagnostics.doctorResultFailedKeys': '{count} 件のキーを削除できませんでした。', + 'settings.diagnostics.doctorServerRan': 'サーバー側の Doctor 修復も実行されました。', + 'settings.diagnostics.doctorServerUnavailable': 'サーバー側の Doctor が利用できなかったため、ローカル修復のみ実行されました。', + 'errorBoundary.title': '問題が発生しました。', + 'errorBoundary.description': 'エラーは診断に記録されました。', + + // Settings > Claude Official Login + 'settings.claudeOfficialLogin.intro': '公式 Claude モデルを使用するには、Claude.ai アカウントにサインインする必要があります。下のボタンをクリックすると、ブラウザで公式 Claude ログインページが開きます。承認後、ここに戻ります。', + 'settings.claudeOfficialLogin.loginButton': 'Claude にサインイン', + 'settings.claudeOfficialLogin.loginStarting': '起動中…', + 'settings.claudeOfficialLogin.logoutButton': 'サインアウト', + 'settings.claudeOfficialLogin.logoutProcessing': '処理中…', + 'settings.claudeOfficialLogin.loggedInPrefix': 'サインイン済み (Claude', + 'settings.claudeOfficialLogin.subTypeUnknown': '不明', + 'settings.claudeOfficialLogin.errorPrefix': 'エラー: ', + 'settings.claudeOfficialLogin.openBrowserFailed': 'ブラウザを開けませんでした。承認 URL に手動でアクセスしてください。', + + // Settings > ChatGPT Official Login + 'settings.chatgptOfficialLogin.intro': 'デスクトップセッションで GPT モデルを使用するには、ChatGPT でサインインしてください。', + 'settings.chatgptOfficialLogin.loginButton': 'ChatGPT でサインイン', + 'settings.chatgptOfficialLogin.loginStarting': 'サインインを開始中...', + 'settings.chatgptOfficialLogin.logoutButton': 'サインアウト', + 'settings.chatgptOfficialLogin.logoutProcessing': 'サインアウト中...', + 'settings.chatgptOfficialLogin.loggedInPrefix': 'サインイン中:', + 'settings.chatgptOfficialLogin.accountUnknown': 'ChatGPT アカウント', + 'settings.chatgptOfficialLogin.openBrowserFailed': 'ブラウザを開けません。承認リンクをコピーして手動で開いてください。', + 'settings.chatgptOfficialLogin.copyAuthorizeUrl': '承認リンクをコピー', + 'settings.chatgptOfficialLogin.copyLinkFailed': '承認リンクをコピーできません。', + 'settings.chatgptOfficialLogin.errorPrefix': 'ChatGPT OAuth エラー: ', + + // Settings > Providers + 'settings.providers.title': 'プロバイダー', + 'settings.providers.description': 'モデルにアクセスするための API プロバイダーを管理します。', + 'settings.providers.addProvider': 'プロバイダーを追加', + 'settings.providers.officialName': 'Claude 公式', + 'settings.providers.officialDesc': 'Anthropic ネイティブ — API キー不要', + 'settings.providers.openaiOfficialName': 'ChatGPT 公式', + 'settings.providers.openaiOfficialDesc': 'ChatGPT アカウントによる OpenAI OAuth — API キー不要', + 'settings.providers.connected': '接続済み ({latency}ms)', + 'settings.providers.failed': '失敗: {error}', + 'settings.providers.connectivityOk': '① 接続 ({latency}ms)', + 'settings.providers.connectivityFailed': '① 接続に失敗しました: {error}', + 'settings.providers.proxyOk': '② プロキシパイプライン ({latency}ms)', + 'settings.providers.proxyFailed': '② プロキシ失敗: {error}', + 'settings.providers.confirmDelete': 'プロバイダー「{name}」を削除しますか?この操作は取り消せません。', + 'settings.providers.activate': '有効化', + 'settings.providers.default': 'デフォルト', + 'settings.providers.setDefault': 'デフォルトに設定', + 'settings.providers.test': 'テスト', + 'settings.providers.edit': '編集', + 'settings.providers.requestFailed': 'リクエストに失敗しました', + 'settings.providers.addTitle': 'プロバイダーを追加', + 'settings.providers.editTitle': 'プロバイダーを編集', + 'settings.providers.preset': 'プリセット', + 'settings.providers.name': '名前', + 'settings.providers.namePlaceholder': 'プロバイダー名', + 'settings.providers.notes': 'メモ', + 'settings.providers.notesPlaceholder': '任意のメモ...', + 'settings.providers.baseUrl': 'ベース URL', + 'settings.providers.baseUrlPlaceholder': 'https://api.example.com/anthropic', + 'settings.providers.apiKey': 'API キー', + 'settings.providers.apiKeyKeep': 'API キー(空欄のままにすると現在の値を保持)', + 'settings.providers.getApiKey': 'API キーを取得', + 'settings.providers.modelMapping': 'モデルマッピング', + 'settings.providers.mainModel': 'メインモデル', + 'settings.providers.haikuModel': 'Haiku モデル', + 'settings.providers.sonnetModel': 'Sonnet モデル', + 'settings.providers.opusModel': 'Opus モデル', + 'settings.providers.sameAsMain': 'メインと同じ', + 'settings.providers.contextSettingsTitle': 'コンテキストと自動コンパクト', + 'settings.providers.contextSettingsDesc': 'プリセットの上限は自動的に適用されます。プロバイダーが上限を変更した場合やカスタムモデル ID を使用する場合のみ編集してください。', + 'settings.providers.contextSettingsEdit': '詳細設定', + 'settings.providers.contextSettingsHide': '非表示', + 'settings.providers.contextSummaryAuto': '設定済みモデルを自動検出します。不明なモデルは組み込みのフォールバックを使用します', + 'settings.providers.contextFallbackAuto': '不明なモデル: 自動', + 'settings.providers.contextFallbackSummary': '不明なモデル: {tokens}', + 'settings.providers.modelContextWindows': 'モデルのコンテキストウィンドウ', + 'settings.providers.mainContextWindow': 'メインモデルのコンテキスト', + 'settings.providers.haikuContextWindow': 'Haiku モデルのコンテキスト', + 'settings.providers.sonnetContextWindow': 'Sonnet モデルのコンテキスト', + 'settings.providers.opusContextWindow': 'Opus モデルのコンテキスト', + 'settings.providers.contextWindowPlaceholder': '例: 200000', + 'settings.providers.modelContextWindowsDesc': '各モデルの実際のコンテキストウィンドウを使用します。プリセットは自動的に入力されます。空欄の場合は組み込み検出または 200K にフォールバックします。', + 'settings.providers.modelContextWindowNumberError': '整数を入力してください。', + 'settings.providers.modelContextWindowRangeError': '16000 から 10000000 の間で指定してください。', + 'settings.providers.autoCompactWindow': '不明なモデルのフォールバックウィンドウ', + 'settings.providers.autoCompactWindowPlaceholder': '任意、例: 200000', + 'settings.providers.autoCompactWindowDesc': '識別できないモデルにのみ使用されます。設定済みモデルのウィンドウが優先されます。', + 'settings.providers.autoCompactWindowNumberError': '整数を入力してください。', + 'settings.providers.autoCompactWindowRangeError': '16000 から 10000000 の間で指定してください。', + 'settings.providers.testConnection': '接続をテスト', + 'settings.providers.settingsJson': '設定 JSON', + 'settings.providers.settingsJsonDesc': '~/.claude/cc-haha/settings.json — 直接編集できます。保存時に書き込まれます。', + 'settings.providers.jsonError': 'JSON 構文エラー: {error}', + 'settings.providers.apiFormat': 'API 形式', + 'settings.providers.apiFormatAnthropic': 'Anthropic Messages(ネイティブ)', + 'settings.providers.apiFormatOpenaiChat': 'OpenAI Chat Completions(プロキシ)', + 'settings.providers.apiFormatOpenaiResponses': 'OpenAI Responses API(プロキシ)', + 'settings.providers.proxyHint': 'リクエストはローカルプロキシ経由で変換されます', + 'settings.providers.authStrategy': '認証変数', + 'settings.providers.authStrategyApiKey': 'API キー (ANTHROPIC_API_KEY)', + 'settings.providers.authStrategyApiKeyDesc': 'x-api-key を使用した Anthropic API への直接アクセス。', + 'settings.providers.authStrategyAuthToken': 'Bearer トークン (ANTHROPIC_AUTH_TOKEN)', + 'settings.providers.authStrategyAuthTokenDesc': 'Authorization Bearer を使用する、ほとんどのサードパーティ製 Anthropic 互換サービス向け。', + 'settings.providers.authStrategyAuthTokenEmptyApiKey': 'Bearer + 空の API_KEY', + 'settings.providers.authStrategyAuthTokenEmptyApiKeyDesc': 'Anthropic API キーへのフォールバックを避ける必要がある OpenRouter / Ollama 形式の構成向け。', + 'settings.providers.authStrategyDualSameToken': '両方の変数にトークンを書き込む', + 'settings.providers.authStrategyDualSameTokenDesc': '両方の変数をチェックする Hugging Face Router などのサービス向け。', + 'settings.providers.authStrategyDualDummy': '両方の変数にダミー値を書き込む', + 'settings.providers.authStrategyDualDummyDesc': 'プレースホルダーの認証値のみが必要な、ローカルの vLLM 互換サービス向け。', + + // Settings > Permissions + 'settings.permissions.title': '権限モード', + 'settings.permissions.description': 'ツール実行の権限の扱い方を制御します。', + 'settings.permissions.default': '権限を確認', + 'settings.permissions.defaultDesc': 'ツールを実行する前に確認します', + 'settings.permissions.acceptEdits': '編集を承認', + 'settings.permissions.acceptEditsDesc': 'ファイル編集は自動承認し、それ以外は確認します', + 'settings.permissions.plan': 'プランモード', + 'settings.permissions.planDesc': '実行せずに思考と計画を行います', + 'settings.permissions.bypass': 'すべてバイパス', + 'settings.permissions.bypassDesc': 'すべての権限チェックをスキップします(危険)', + + // Settings > Adapters + 'settings.tab.adapters': 'IM アダプター', + 'settings.adapters.description': 'WeChat、DingTalk、Telegram、Feishu 経由で Claude Code とチャットできるよう IM アダプターを設定します。', + 'settings.adapters.telegram': 'Telegram', + 'settings.adapters.feishu': 'Feishu', + 'settings.adapters.wechat': 'WeChat', + 'settings.adapters.dingtalk': 'DingTalk', + 'settings.adapters.botToken': 'Bot トークン', + 'settings.adapters.botTokenPlaceholder': '@BotFather から取得したトークンを貼り付け', + 'settings.adapters.appId': 'App ID', + 'settings.adapters.appIdPlaceholder': '例: cli_xxx', + 'settings.adapters.appSecret': 'App Secret', + 'settings.adapters.appSecretPlaceholder': 'Feishu 開放プラットフォームから取得', + 'settings.adapters.feishuCreateBotTitle': 'Feishu ボットが必要ですか?', + 'settings.adapters.feishuCreateBotDesc': '必要な権限が設定済みの Feishu ボットを、ドキュメント記載の OpenClaw テンプレートで作成します。その後、下に App ID と App Secret を貼り付けてください。', + 'settings.adapters.feishuCreateBotAction': 'Feishu ボットを作成', + 'settings.adapters.feishuCreateBotStepCreate': 'テンプレートからボットを作成します。', + 'settings.adapters.feishuCreateBotStepFill': 'その App ID と App Secret をコピーして、ここに入力します。', + 'settings.adapters.encryptKey': 'Encrypt Key', + 'settings.adapters.encryptKeyPlaceholder': '任意', + 'settings.adapters.verificationToken': 'Verification Token', + 'settings.adapters.verificationTokenPlaceholder': '任意', + 'settings.adapters.allowedUsers': '許可ユーザー', + 'settings.adapters.allowedUsersHint': 'カンマ区切り。空欄の場合はペア済みユーザーのみ許可します。', + 'settings.adapters.tgAllowedUsersPlaceholder': '例: 123456789, 987654321', + 'settings.adapters.fsAllowedUsersPlaceholder': '例: ou_xxx, ou_yyy', + 'settings.adapters.wcAllowedUsersPlaceholder': '例: wx_user_id_1, wx_user_id_2', + 'settings.adapters.dtAllowedUsersPlaceholder': '例: manager001, staff_yyy', + 'settings.adapters.defaultProject': 'デフォルトプロジェクト', + 'settings.adapters.defaultProjectHint': '新しい IM セッションのデフォルト作業ディレクトリ。空欄の場合、ボットは現在のユーザーの作業ディレクトリを使用します。', + 'settings.adapters.streamingCard': 'ストリーミングカードモード', + 'settings.adapters.streamingCardDesc': 'より快適な体験のためにカードをリアルタイムで更新します', + 'settings.adapters.serverUrl': 'サーバー URL', + 'settings.adapters.serverUrlPlaceholder': 'ws://127.0.0.1:3456', + 'settings.adapters.save': '保存', + 'settings.adapters.saved': '保存しました', + 'settings.adapters.saving': '保存中...', + 'settings.adapters.startHint': '保存後、アダプターを実行します: cd adapters && bun run {platform}', + 'settings.adapters.pairing': 'ペアリング', + 'settings.adapters.pairingDesc': 'ペアリングコードを生成し、IM の個別チャットでボットに送信して本人確認をひも付けます。', + 'settings.adapters.generateCode': 'コードを生成', + 'settings.adapters.regenerateCode': '再生成', + 'settings.adapters.codeExpired': '期限切れ', + 'settings.adapters.codeExpiresIn': '有効期限', + 'settings.adapters.minutes': '分', + 'settings.adapters.pairingCodeHint': 'このコードを DingTalk、Feishu、WeChat、Telegram の個別チャットでボットに送信してください。WeChat の場合は先に QR コードでのひも付けが必要です。', + 'settings.adapters.pairedUsers': 'ペア済みユーザー', + 'settings.adapters.noPairedUsers': 'ペア済みユーザーはまだいません', + 'settings.adapters.unbind': 'ひも付け解除', + 'settings.adapters.unbindConfirm': 'このユーザーのひも付けを解除してもよろしいですか?ボットを使用するには再度ペアリングが必要になります。', + 'settings.adapters.platform.telegram': 'Telegram', + 'settings.adapters.platform.feishu': 'Feishu', + 'settings.adapters.platform.wechat': 'WeChat', + 'settings.adapters.platform.dingtalk': 'DingTalk', + 'settings.adapters.dingtalkQrTitle': 'QR コードで DingTalk ボットをひも付け', + 'settings.adapters.dingtalkQrDesc': 'DingTalk モバイルアプリでスキャンしてボットを作成・承認します。成功すると Client ID / Secret が自動的に保存されます。', + 'settings.adapters.dingtalkStartAuth': 'スキャンしてひも付け', + 'settings.adapters.dingtalkUnbindBot': 'ボットアカウントのひも付けを解除', + 'settings.adapters.dingtalkQrAlt': 'DingTalk 承認用 QR コード', + 'settings.adapters.dingtalkWaiting': 'DingTalk のスキャン確認を待っています...', + 'settings.adapters.dingtalkBound': 'DingTalk ボットがひも付けられました。', + 'settings.adapters.dingtalkAuthFailed': 'DingTalk QR コードの承認に失敗しました。', + 'settings.adapters.dingtalkAuthExpired': 'DingTalk QR コードの承認の有効期限が切れました。新しい QR コードを生成してください。', + 'settings.adapters.dingtalkUnbindFailed': 'DingTalk のひも付け解除に失敗しました。', + 'settings.adapters.dingtalkUnbindBotConfirm': 'この DingTalk ボットアカウントのひも付けを解除しますか?DingTalk がメッセージを送受信できるようにするには、再度スキャンが必要になります。', + 'settings.adapters.dingtalkClientId': 'Client ID', + 'settings.adapters.dingtalkClientIdPlaceholder': 'QR 認証で自動入力、または手動で入力', + 'settings.adapters.dingtalkClientSecret': 'Client Secret', + 'settings.adapters.dingtalkClientSecretPlaceholder': 'QR 認証で自動入力、または手動で入力', + 'settings.adapters.dingtalkEndpoint': 'Stream エンドポイント', + 'settings.adapters.dingtalkEndpointPlaceholder': 'デフォルト https://api.dingtalk.com', + 'settings.adapters.dingtalkPermissionCardTemplateId': '権限カードテンプレート ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdPlaceholder': '任意のインタラクティブカードテンプレート ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdHint': '設定すると、権限リクエストはまず DingTalk のインタラクティブカードを使用します。空欄の場合は /allow、/always、/deny のテキスト承認を使用します。', + 'settings.adapters.wechatBind': 'スキャンしてひも付け', + 'settings.adapters.wechatRebind': '再スキャン', + 'settings.adapters.wechatConnected': 'WeChat はひも付け済みです', + 'settings.adapters.wechatNotConnected': 'WeChat はひも付けされていません', + 'settings.adapters.wechatQrHint': 'QR コードを生成し、WeChat でスキャンして確認します。ひも付け後にアダプターが再起動します。', + 'settings.adapters.wechatQrAlt': 'WeChat ひも付け用 QR コード', + 'settings.adapters.wechatWaiting': 'WeChat の確認を待っています...', + 'settings.adapters.wechatBindSuccess': 'WeChat のひも付けに成功しました。', + 'settings.adapters.wechatUnbindAccount': 'WeChat アカウントのひも付けを解除', + 'settings.adapters.wechatUnbindAccountConfirm': 'この WeChat アカウントのひも付けを解除しますか?WeChat がメッセージを送受信できるようにするには、再度スキャンが必要になります。', + 'settings.adapters.wechatUnbound': 'WeChat アカウントのひも付けを解除しました。', + 'settings.adapters.wechatUnbindFailed': 'WeChat のひも付け解除に失敗しました。', + 'settings.adapters.wechatAllowedUsersHint': 'QR コードのひも付けはアカウントを有効化するだけです。ユーザーは引き続きペアリングコードを送信する必要があります。または、ここに許可する WeChat ユーザー ID を追加できます。', + + // Settings > MCP + 'settings.mcp.title': 'MCP サーバー', + 'settings.mcp.description': 'Claude Code 用に外部ツールやデータソースを接続します。Local、Project、User の各スコープは CLI と同じ動作に従います。', + 'settings.mcp.addServer': 'サーバーを追加', + 'settings.mcp.empty': 'MCP サーバーはまだ設定されていません', + 'settings.mcp.emptyHint': 'カスタムの stdio、HTTP、または SSE の MCP サーバーを追加して、ツールアクセスの拡張を始めましょう。', + 'settings.mcp.stats.total': 'サーバー総数', + 'settings.mcp.stats.connected': '現在接続中', + 'settings.mcp.stats.attention': '要対応', + 'settings.mcp.scope.project': 'プロジェクト', + 'settings.mcp.scope.local': 'ローカル', + 'settings.mcp.scope.user': 'ユーザー', + 'settings.mcp.scope.plugin': 'プラグイン', + 'settings.mcp.scopeDesc.local': '1 つのプロジェクト内で自分専用です。ユーザー設定に保存され、選択したプロジェクトにスコープが限定されます。', + 'settings.mcp.scopeDesc.project': '選択したプロジェクトの `.mcp.json` を通じてチームと共有されます。', + 'settings.mcp.scopeDesc.user': 'ユーザーアカウントのすべてのプロジェクトで利用できます。', + 'settings.mcp.scope.dynamic': '組み込み', + 'settings.mcp.scope.enterprise': 'エンタープライズ', + 'settings.mcp.scope.claudeai': 'Claude.ai', + 'settings.mcp.scope.managed': '管理対象', + 'settings.mcp.transport.http': 'Streamable HTTP', + 'settings.mcp.globalOnlyHint': '1 つのプロジェクト用には Local、`.mcp.json` 用には Project、すべてのプロジェクト用には User を選択してください。', + 'settings.mcp.currentProjectHint': '選択中のプロジェクト: {path}', + 'settings.mcp.form.back': 'サーバー一覧に戻る', + 'settings.mcp.form.createTitle': 'カスタム MCP に接続', + 'settings.mcp.form.createHint': '現在 Claude Code がサポートするフィールドでカスタム MCP サーバーをセットアップします。', + 'settings.mcp.form.editTitle': '{name} MCP を更新', + 'settings.mcp.form.editHint': '接続の詳細を確認し、変更を保存するか、このサーバーをデスクトップアプリから再接続します。', + 'settings.mcp.form.transportLocked': 'MCP サーバーの種類を切り替えるには、まずアンインストールしてください。', + 'settings.mcp.form.uninstall': 'アンインストール', + 'settings.mcp.form.reconnect': '再接続', + 'settings.mcp.form.save': '保存', + 'settings.mcp.form.name': '名前', + 'settings.mcp.form.namePlaceholder': 'MCP サーバー名', + 'settings.mcp.form.scope': '設定スコープ', + 'settings.mcp.form.transport': 'トランスポート', + 'settings.mcp.form.status': 'ステータス', + 'settings.mcp.form.location': '設定の場所', + 'settings.mcp.form.rawConfig': '生の設定', + 'settings.mcp.form.command': '起動コマンド', + 'settings.mcp.form.commandPlaceholder': 'npx', + 'settings.mcp.form.commandHostHint': 'STDIO の MCP コマンドはホストマシン上で実行されます。Node.js、Python、Bun、uv などのランタイムはご自身でインストールし、コマンドが PATH 上で利用できることを確認してください。', + 'settings.mcp.form.arguments': '引数', + 'settings.mcp.form.argumentPlaceholder': 'chrome-devtools-mcp@latest', + 'settings.mcp.form.addArgument': '引数を追加', + 'settings.mcp.form.environmentVariables': '環境変数', + 'settings.mcp.form.addEnv': '環境変数を追加', + 'settings.mcp.form.keyPlaceholder': 'キー', + 'settings.mcp.form.valuePlaceholder': '値', + 'settings.mcp.form.url': 'URL', + 'settings.mcp.form.sseUrl': 'SSE URL', + 'settings.mcp.form.urlPlaceholder': 'https://mcp.example.com/mcp', + 'settings.mcp.form.headers': 'ヘッダー', + 'settings.mcp.form.addHeader': 'ヘッダーを追加', + 'settings.mcp.form.oauthClientId': 'OAuth クライアント ID', + 'settings.mcp.form.oauthClientIdPlaceholder': '任意のクライアント ID', + 'settings.mcp.form.oauthCallbackPort': 'OAuth コールバックポート', + 'settings.mcp.form.oauthCallbackPortPlaceholder': '任意の固定コールバックポート', + 'settings.mcp.form.headersHelper': 'ヘッダーヘルパースクリプト', + 'settings.mcp.form.headersHelperPlaceholder': '任意のヘルパーコマンドのパス', + 'settings.mcp.form.deleteTitle': 'MCP サーバーを削除', + 'settings.mcp.form.cancel': 'キャンセル', + 'settings.mcp.form.confirmDelete': '削除', + 'settings.mcp.form.deleteConfirm': 'MCP サーバー「{name}」を削除しますか?この操作は取り消せません。', + 'settings.mcp.form.deleteConfirmBody': 'MCP サーバー「{name}」を削除しますか?この操作は取り消せません。', + 'settings.mcp.targetProject.title': '対象プロジェクト', + 'settings.mcp.targetProject.selected': '現在、次のプロジェクトのローカルおよび共有 MCP サーバーを表示しています: {path}', + 'settings.mcp.targetProject.empty': 'プロジェクト専用または共有の MCP サーバーを確認するプロジェクトを選択してください。', + 'settings.mcp.targetProject.emptyWithCurrent': '対象プロジェクトを選択してください。現在アクティブなセッション: {path}', + 'settings.mcp.targetProject.localSelected': 'このサーバーは次の中で自分専用になります: {path}', + 'settings.mcp.targetProject.localEmpty': 'このプライベート MCP サーバーを受け取るプロジェクトを選択してください。', + 'settings.mcp.targetProject.projectSelected': 'このサーバーは次を通じて共有されます: {path}/.mcp.json', + 'settings.mcp.targetProject.projectEmpty': 'この共有 MCP サーバーを `.mcp.json` で受け取るプロジェクトを選択してください。', + 'settings.mcp.targetProject.globalTitle': 'グローバルインストール対象', + 'settings.mcp.targetProject.globalHint': 'User スコープは対象プロジェクトを必要としません。グローバルの Claude 設定に保存され、どこからでも利用できます。', + 'settings.mcp.toast.created': 'MCP サーバー「{name}」を作成しました', + 'settings.mcp.toast.saved': 'MCP サーバー「{name}」を保存しました', + 'settings.mcp.toast.deleted': 'MCP サーバー「{name}」を削除しました', + 'settings.mcp.toast.enabled': 'MCP サーバー「{name}」を有効化しました', + 'settings.mcp.toast.disabled': 'MCP サーバー「{name}」を無効化しました', + 'settings.mcp.toast.reconnected': 'MCP サーバー「{name}」を再接続しました', + 'settings.mcp.toast.saveFailed': 'MCP サーバーの保存に失敗しました', + 'settings.mcp.toast.deleteFailed': 'MCP サーバーの削除に失敗しました', + 'settings.mcp.toast.toggleFailed': 'MCP サーバーの状態の更新に失敗しました', + 'settings.mcp.toast.reconnectFailed': 'MCP サーバーの再接続に失敗しました', + + // Settings > Agents + 'settings.tab.agents': 'エージェント', + 'settings.agents.title': 'インストール済みエージェント', + 'settings.agents.description': '組み込み、プロジェクト、ユーザーの各ソースにわたって Claude が利用できるエージェントを閲覧します。TUI で /agents を使うと、アクティブなソースとオーバーライドを確認できます。', + 'settings.agents.browserTitle': 'インストール済みエージェントを閲覧', + 'settings.agents.browserEyebrow': 'エージェントブラウザ', + 'settings.agents.entryEyebrow': 'エージェントプロフィール', + 'settings.agents.empty': '利用できるエージェントはまだありません。', + 'settings.agents.emptyHint': 'Claude の設定またはプロジェクトにエージェント定義を追加すると、ここに表示されます。', + 'settings.agents.model': 'モデル', + 'settings.agents.tools': 'ツール', + 'settings.agents.systemPrompt': 'システムプロンプト', + 'settings.agents.noDescription': '説明なし', + 'settings.agents.noSystemPrompt': 'システムプロンプトは定義されていません。', + 'settings.agents.backToList': '一覧に戻る', + 'settings.agents.agentCount': '{count} エージェント', + 'settings.agents.summary.totalAgents': 'エージェント総数', + 'settings.agents.summary.activeAgents': 'アクティブなエージェント', + 'settings.agents.summary.sources': 'ソース', + 'settings.agents.summary.source': 'ソース', + 'settings.agents.summary.model': 'モデル', + 'settings.agents.summary.tools': 'ツール', + 'settings.agents.summary.status': 'ステータス', + 'settings.agents.groupHint': '{source} から利用できるエージェント: {count}', + 'settings.agents.status.active': 'アクティブ', + 'settings.agents.status.available': '利用可能', + 'settings.agents.overriddenBy': '{source} によって上書き', + 'settings.agents.overriddenByShort': '{source} により隠蔽', + 'settings.agents.toolCount': '{count} ツール', + 'settings.agents.noTools': 'ツール制限なし', + 'settings.agents.promptHint': '現在のシステムプロンプトを読み、このエージェントのスコープを比較します。', + 'settings.agents.source.userSettings': 'ユーザー', + 'settings.agents.source.projectSettings': 'プロジェクト', + 'settings.agents.source.localSettings': 'ローカル', + 'settings.agents.source.policySettings': '管理対象', + 'settings.agents.source.plugin': 'プラグイン', + 'settings.agents.source.flagSettings': 'CLI 引数', + 'settings.agents.source.built-in': '組み込み', + + // Settings > Skills + 'settings.skills.title': 'インストール済みスキル', + 'settings.skills.description': 'スキルは Claude に専門的な機能を追加します。スキルは ~/.claude/skills/ で管理します', + 'settings.skills.browserTitle': 'インストール済みスキルを閲覧', + 'settings.skills.browserEyebrow': 'スキルブラウザ', + 'settings.skills.browserDescription': 'バンドル、プロジェクト、ユーザーのスキルを確認し、スコープを比較し、各スキルフォルダを開いてドキュメントやソースファイルを読みます。', + 'settings.skills.searchLabel': 'スキルを検索', + 'settings.skills.searchPlaceholder': '名前、説明、ソースでスキルを検索...', + 'settings.skills.searchResultCount': '{total} 件中 {count} 件のスキルが一致', + 'settings.skills.clearSearch': 'スキル検索をクリア', + 'settings.skills.noSearchResults': '一致するスキルがありません', + 'settings.skills.noSearchResultsHint': '別のキーワードを試すか、検索をクリアしてすべてのスキルを表示してください。', + 'settings.skills.entryEyebrow': 'スキルエントリ', + 'settings.skills.slashCommand': '/slash', + 'settings.skills.tokenEstimate': '約 {count} トークン', + 'settings.skills.tokenEstimateShort': '約 {count}', + 'settings.skills.summary.totalSkills': 'スキル総数', + 'settings.skills.summary.totalFiles': 'ファイル', + 'settings.skills.summary.sources': 'ソース', + 'settings.skills.summary.tokens': '推定トークン数', + 'settings.skills.summary.source': 'ソース', + 'settings.skills.summary.entry': 'エントリ', + 'settings.skills.groupHint': '{source} から利用できるスキル: {count}', + 'settings.skills.ready': '準備完了', + 'settings.skills.unavailable': '利用不可', + 'settings.skills.empty': 'スキルがインストールされていません', + 'settings.skills.emptyHint': '~/.claude/skills/ にスキルを追加して始めましょう', + 'settings.skills.back': '一覧に戻る', + 'settings.skills.files': 'ファイル', + 'settings.skills.entryFile': 'エントリファイル', + 'settings.skills.metaTitle': 'スキルのメタデータ', + 'settings.skills.filesPanel': 'ファイル', + 'settings.skills.filesPanelHint': 'エントリファイルと補助的な実装ファイルを閲覧します。', + 'settings.skills.readingMode': '{mode} で表示中', + 'settings.skills.docMode': 'ドキュメントモード', + 'settings.skills.codeMode': 'コードモード', + 'settings.skills.source.user': 'ユーザー', + 'settings.skills.source.project': 'プロジェクト', + 'settings.skills.source.plugin': 'プラグイン', + 'settings.skills.source.mcp': 'MCP', + 'settings.skills.source.bundled': '組み込み', + + // Settings > Memory + 'settings.tab.memory': 'メモリ', + 'settings.memory.title': 'プロジェクトメモリ', + 'settings.memory.description': 'Claude が各プロジェクト向けに書き込む Markdown メモリファイルを確認・編集します。これらのファイルは ~/.claude/projects//memory/ の下に保存され、CLI ランタイムによって読み込まれます。', + 'settings.memory.refresh': '更新', + 'settings.memory.projects': 'プロジェクト', + 'settings.memory.files': 'メモリファイル', + 'settings.memory.resourceManager': 'リソースマネージャー', + 'settings.memory.editor': 'エディター', + 'settings.memory.preview': 'プレビュー', + 'settings.memory.rendered': 'レンダリング後', + 'settings.memory.emptyProjects': 'メモリのあるプロジェクトが見つかりません。', + 'settings.memory.emptyFiles': 'メモリファイルはまだ見つかりません。', + 'settings.memory.selectFile': 'メモリファイルを選択してください。', + 'settings.memory.selectProject': 'プロジェクトを選択してください。', + 'settings.memory.noFileSelected': 'ファイルが選択されていません', + 'settings.memory.current': '現在', + 'settings.memory.indexFile': 'インデックス', + 'settings.memory.missing': '見つかりません', + 'settings.memory.fileCount': '{count} ファイル', + 'settings.memory.unsaved': '未保存', + 'settings.memory.saved': '保存済み', + 'settings.memory.revert': '元に戻す', + 'settings.memory.projectSearchPlaceholder': 'パスでプロジェクトを検索...', + 'settings.memory.fileSearchPlaceholder': 'メモリファイルを検索...', + 'settings.memory.resourceSearchPlaceholder': 'プロジェクトまたはメモリファイルを検索...', + 'settings.memory.noProjectMatches': 'この検索に一致するプロジェクトはありません。', + 'settings.memory.noFileMatches': 'この検索に一致するメモリファイルはありません。', + 'settings.memory.clearSearch': '検索をクリア', + 'settings.memory.toggleFolder': '{name} を切り替え', + + // Settings > Plugins + 'settings.plugins.title': 'インストール済みプラグイン', + 'settings.plugins.description': 'インストール済みプラグインを確認し、状態を把握し、デスクトップランタイムに変更を適用します。', + 'settings.plugins.browserTitle': 'インストール済みプラグインを閲覧', + 'settings.plugins.browserEyebrow': 'プラグインマネージャー', + 'settings.plugins.browserDescription': 'プラグインはスキル、エージェント、フック、MCP サーバー、言語ツールをまとめたものです。このビューでは、インストール済みプラグイン、状態、ランタイムへの適用フィードバックにデスクトップ画面を集中させます。', + 'settings.plugins.entryEyebrow': 'プラグインの詳細', + 'settings.plugins.summary.total': 'プラグイン総数', + 'settings.plugins.summary.enabled': '有効', + 'settings.plugins.summary.attention': '要対応', + 'settings.plugins.summary.marketplaces': 'マーケットプレイス', + 'settings.plugins.summary.skills': 'スキル', + 'settings.plugins.summary.agents': 'エージェント', + 'settings.plugins.summary.mcp': 'MCP', + 'settings.plugins.summary.hooks': 'フック', + 'settings.plugins.group.attention': '要対応', + 'settings.plugins.group.enabled': '有効', + 'settings.plugins.group.disabled': '無効', + 'settings.plugins.groupHint': 'このセクションには {count} 個のプラグインがあります', + 'settings.plugins.refresh': '更新', + 'settings.plugins.apply': '変更を適用', + 'settings.plugins.applyHint': '有効化、無効化、更新の変更は、現在のデスクトップランタイムに適用した後で有効になります。', + 'settings.plugins.lastReload': '前回の適用: アクティブなプラグイン {enabled} 個、プラグインスキル {skills} 個、エラー {errors} 件。', + 'settings.plugins.reloadToast': 'プラグインの変更を適用しました: アクティブなプラグイン {enabled} 個、スキル {skills} 個、エラー {errors} 件。', + 'settings.plugins.marketplacesTitle': '既知のマーケットプレイス', + 'settings.plugins.marketplacesHint': 'このマシンに既に設定済みのマーケットプレイスソースの読み取り専用の概要です。', + 'settings.plugins.marketplaceAutoUpdateOn': '自動更新オン', + 'settings.plugins.marketplaceAutoUpdateOff': '自動更新オフ', + 'settings.plugins.marketplaceInstalledCount': '{count} 個インストール済み', + 'settings.plugins.marketplaceUpdatedAt': '更新日時 {value}', + 'settings.plugins.status.enabled': '有効', + 'settings.plugins.status.disabled': '無効', + 'settings.plugins.status.attention': '要対応', + 'settings.plugins.scope.user': 'ユーザー', + 'settings.plugins.scope.project': 'プロジェクト', + 'settings.plugins.scope.local': 'ローカル', + 'settings.plugins.scope.managed': '管理対象', + 'settings.plugins.scope.builtin': '組み込み', + 'settings.plugins.empty': 'プラグインがインストールされていません', + 'settings.plugins.emptyHint': 'Claude Code からプラグインをインストールすると、ここで管理できます。', + 'settings.plugins.back': '一覧に戻る', + 'settings.plugins.noDescription': 'このプラグインの説明はありません。', + 'settings.plugins.errorCount': '{count} 件のエラー', + 'settings.plugins.enable': '有効化', + 'settings.plugins.disable': '無効化', + 'settings.plugins.update': '更新', + 'settings.plugins.uninstall': 'アンインストール', + 'settings.plugins.confirmUninstall': 'プラグイン「{name}」をアンインストールしますか?選択したスコープのインストール済みコピーが削除されます。', + 'settings.plugins.author': '作者: {value}', + 'settings.plugins.projectPath': 'プロジェクト: {value}', + 'settings.plugins.installPath': 'インストール先: {value}', + 'settings.plugins.managedHint': 'このプラグインはポリシーによって管理されており、デスクトップアプリから変更できません。', + 'settings.plugins.builtinHint': '組み込みプラグインはここで再読み込みできますが、インストールやアンインストールの操作は表示されません。', + 'settings.plugins.errorsTitle': 'プラグインのエラー', + 'settings.plugins.capabilitiesTitle': 'バンドルされた機能', + 'settings.plugins.capabilitiesHint': 'このプラグインがマニフェストとランタイム統合を読み込んだ後に公開する機能です。', + 'settings.plugins.sharedNavigationDisabled': '共有管理ページでこのプラグインのスキル、エージェント、MCP エントリを開く前に、プラグインを有効化して変更を適用してください。', + 'settings.plugins.capabilityEmpty': '公開なし', + 'settings.plugins.capability.skills': '{count} スキル', + 'settings.plugins.capability.agents': '{count} エージェント', + 'settings.plugins.capability.mcpServers': '{count} MCP サーバー', + 'settings.plugins.capabilityLabel.skills': 'スキル', + 'settings.plugins.capabilityLabel.commands': 'コマンド', + 'settings.plugins.capabilityLabel.agents': 'エージェント', + 'settings.plugins.capabilityLabel.hooks': 'フック', + 'settings.plugins.capabilityLabel.mcpServers': 'MCP サーバー', + 'settings.plugins.capabilityLabel.lspServers': 'LSP サーバー', + + // Settings > About + 'settings.tab.about': '情報', + 'settings.about.version': 'バージョン', + 'settings.about.changelog': 'リリースノート', + 'settings.about.repo': 'GitHub リポジトリ', + 'settings.about.starHint': 'このプロジェクトが役立った場合は、Star を付けることをご検討ください', + 'settings.about.feedback': '問題を報告', + 'settings.about.feedbackDesc': 'バグや使い方の質問について GitHub Issue を作成します', + 'settings.about.author': '作者', + 'settings.about.socialMedia': 'ソーシャルメディア', + 'settings.about.updates': 'アプリの更新', + 'settings.about.updatesDesc': 'GitHub Releases を確認し、インストーラーをダウンロードして、インストール後に再起動します。', + + // Settings > Computer Use + 'settings.tab.computerUse': 'コンピューター操作', + 'settings.computerUse.title': 'コンピューター操作', + 'settings.computerUse.description': 'Claude がスクリーンショットを撮影し、クリック、入力を行い、コンピューターを操作できるようにします。Python 3 が必要です。macOS ではアクセシビリティ権限も必要です。', + 'settings.computerUse.enabledToggle': '有効', + 'settings.computerUse.disabledHint': 'コンピューター操作はオフです。新しいセッションでは、computer-use MCP サーバーを注入したり、デスクトップ操作ツールをコーディングエージェントに公開したりしません。', + 'settings.computerUse.notSupported': 'コンピューター操作は macOS と Windows でのみサポートされます。', + 'settings.computerUse.python': 'Python 3', + 'settings.computerUse.pythonNotFound': 'インストールされていません。まず Python 3 をインストールしてください。', + 'settings.computerUse.pythonFound': 'インストール済み', + 'settings.computerUse.pythonCustomInvalid': 'カスタムインタープリターが利用できません', + 'settings.computerUse.pythonPathLabel': 'Python インタープリターのパス', + 'settings.computerUse.pythonPathPlaceholder': '自動検出、または python.exe / python3 を選択', + 'settings.computerUse.pythonPathHint': '空欄のままにすると自動検出します。ランタイムのセットアップで優先したい場合は、conda、pyenv、その他のカスタム環境の Python 実行ファイルを選択してください。', + 'settings.computerUse.pythonPathBrowse': '参照', + 'settings.computerUse.pythonPathSave': '適用', + 'settings.computerUse.pythonPathAuto': '自動', + 'settings.computerUse.pythonPathSaved': '保存しました。再チェック時はこのインタープリターを優先します。', + 'settings.computerUse.pythonPathSaveFailed': '保存に失敗しました。もう一度お試しください。', + 'settings.computerUse.pythonPathDialogTitle': 'Python インタープリターを選択', + 'settings.computerUse.pythonPathDialogFailed': 'ファイルピッカーを開けませんでした。パスを手動で貼り付けてください。', + 'settings.computerUse.venv': '仮想環境', + 'settings.computerUse.venvReady': '準備完了', + 'settings.computerUse.venvNotReady': '未作成', + 'settings.computerUse.deps': '依存関係', + 'settings.computerUse.depsReady': 'インストール済み', + 'settings.computerUse.depsNotReady': '未インストール', + 'settings.computerUse.accessibility': 'アクセシビリティ権限', + 'settings.computerUse.screenRecording': '画面収録権限', + 'settings.computerUse.permGranted': '許可済み', + 'settings.computerUse.permDenied': '拒否 — システム設定 > プライバシーとセキュリティ を開いて許可してください', + 'settings.computerUse.permUnknown': '確認するにはまず環境をセットアップしてください', + 'settings.computerUse.permScreenRecordingUnknownSoft': 'ここでは自動検出が不安定な場合があります。システム設定で既に有効と表示されていれば、通常はコンピューター操作を続行できます', + 'settings.computerUse.permScreenRecordingManual': '自動検出できません — システム設定で確認してください', + 'settings.computerUse.setupBtn': '環境をインストール', + 'settings.computerUse.setupRunning': 'インストール中...', + 'settings.computerUse.setupSuccess': '環境のセットアップが完了しました!', + 'settings.computerUse.setupFail': 'セットアップに失敗しました', + 'settings.computerUse.allReady': 'すべてのチェックに合格しました。コンピューター操作の準備が整いました。', + 'settings.computerUse.downloadPython': 'Python 3 をダウンロード', + 'settings.computerUse.recheckBtn': 'ステータスを再チェック', + 'settings.computerUse.requirementsLabel': '必要なパッケージ', + 'settings.computerUse.appsTitle': '承認済みアプリ', + 'settings.computerUse.appsDescription': 'コンピューター操作用にアプリを事前承認します。承認済みアプリは、実行時の確認なしに Claude が操作できます。', + 'settings.computerUse.appsLoading': 'インストール済みアプリを読み込み中...', + 'settings.computerUse.appsEmpty': 'インストール済みアプリが見つかりません。まず環境をセットアップしてください。', + 'settings.computerUse.appsSearch': 'アプリを検索...', + 'settings.computerUse.appsSaved': '保存しました', + 'settings.computerUse.openAccessibility': 'アクセシビリティ設定を開く', + 'settings.computerUse.openScreenRecording': '画面収録設定を開く', + 'settings.computerUse.permRestartHint': '許可後、有効にするためにアプリを再起動してください。', + 'settings.computerUse.flagClipboard': 'クリップボードアクセス', + 'settings.computerUse.flagSystemKeys': 'システムキーの組み合わせ', + + // Settings > General - Storage + 'settings.general.modeSwitchTitle': 'データ保存場所を切り替えますか?', + 'settings.general.modeSwitchConfirm': '保存して再起動', + 'settings.general.storageTitle': 'データ保存場所', + 'settings.general.storageDescription': '高度で使用頻度の低い設定です。切り替え後は、セッション、スキル、MCP、プラグイン、プロバイダー設定、タスク、キャッシュが新しいディレクトリから読み込まれます。', + 'settings.general.storageSystemTitle': 'システムディレクトリを使用', + 'settings.general.storageSystemDescription': 'デフォルトのデータソースに戻します。起動環境で CLAUDE_CONFIG_DIR が設定されている場合は、その環境変数が引き続き優先されます。', + 'settings.general.storagePortableTitle': 'ポータブルディレクトリを使用', + 'settings.general.storagePortableDescription': '選択したフォルダにデスクトップのデータを保存します。外付けドライブや、一緒に移動したいアプリバンドルに使用してください。', + 'settings.general.storagePortableDirLabel': 'ポータブルデータディレクトリ', + 'settings.general.storagePortableDirPlaceholder': 'cc-haha データ用のフォルダを選択', + 'settings.general.storageChooseDir': 'フォルダを選択', + 'settings.general.storageChooseDirTitle': 'ポータブルデータディレクトリを選択', + 'settings.general.storageUseDefaultPortableDir': 'アプリの隣にあるデフォルトのポータブルフォルダを使用', + 'settings.general.storageApplyPortable': 'このフォルダを使用して再起動', + 'settings.general.storageActiveDir': '現在アクティブなデータディレクトリ', + 'settings.general.storageEnvironmentHint': '現在のディレクトリは CLAUDE_CONFIG_DIR 環境変数によって制御されています。アプリ内での切り替えではこれを上書きできません。システムディレクトリに戻すには、起動環境から CLAUDE_CONFIG_DIR を削除してください。', + 'settings.general.storageEnvironmentSwitchBlocked': '現在 CLAUDE_CONFIG_DIR がデータディレクトリを制御しています。システムディレクトリに戻す前に、起動環境からこれを削除してください。', + 'settings.general.storageRestartHint': '保存場所の変更を保存しました。新しいデータディレクトリを有効にするには、アプリを再起動してください。', + 'settings.general.storageMoveHint': 'ディレクトリを切り替えても既存のデータは移行されません。以前のセッションを引き続き表示したい場合は、古いディレクトリから projects、skills、plugins、cc-haha および関連フォルダをコピーしてください。ポータブルバンドルにする場合は、このフォルダをアプリの隣に置いて一緒に zip 化してください。', + 'settings.general.storageNoDirError': 'まずポータブルデータディレクトリを選択または入力してください。', + 'settings.general.storagePickerError': 'フォルダピッカーを開けませんでした。フォルダのパスを手動で貼り付けてください。', + 'settings.general.storageRestartError': '変更は保存されましたが、自動再起動に失敗しました。アプリを手動で再起動してください。', + 'settings.general.storageSwitchPortableBody': '切り替え後、デスクトップアプリはこのディレクトリでセッション、設定、スキル、MCP、プラグイン、タスク、キャッシュを読み書きします。', + 'settings.general.storageSwitchDefaultBody': '元に戻すと、デスクトップアプリは再びシステムのデータソースを使用します。ポータブルディレクトリ内のデータは自動的に削除されたり戻されたりすることはありません。', + 'settings.general.storageSwitchRestartBody': 'アプリはローカルサーバーとアダプタープロセスを停止してから再起動します。新しいディレクトリは再起動後に有効になります。', + + // Settings > General + 'settings.general.appearanceTitle': '外観', + 'settings.general.appearanceDescription': '暖かみのあるクラシックワークスペース、ダークワークスペース、純白ワークスペースを切り替えます。', + 'settings.general.appearance.light': '暖色クラシック', + 'settings.general.appearance.dark': 'ダーク', + 'settings.general.appearance.white': '純白', + 'settings.general.languageTitle': '言語', + 'settings.general.languageDescription': 'アプリケーションの表示言語を選択します。', + 'settings.general.responseLangTitle': '応答言語', + 'settings.general.responseLangDescription': 'Claude が常に特定の言語で応答するよう指示します。', + 'settings.general.responseLangDefault': 'デフォルト(英語)', + 'settings.general.effortTitle': '労力レベル', + 'settings.general.effortDescription': 'モデルが使用する計算量を制御します。', + 'settings.general.effort.low': '低', + 'settings.general.effort.medium': '中', + 'settings.general.effort.high': '高', + 'settings.general.effort.max': '最大', + 'settings.general.thinkingTitle': '思考モード', + 'settings.general.thinkingDescription': '新しいセッションをモデルの思考を有効にして開始するかどうかを制御します。オフの場合、DeepSeek などの対応プロバイダーには明示的に非思考パラメーターが渡されます。', + 'settings.general.thinkingEnabled': '思考モードを有効にする', + 'settings.general.thinkingHint': '新しいセッションを --thinking 無効で開始するにはこれをオフにします。DeepSeek V4 Flash/Pro やその他の非思考ワークフローに便利です。', + 'settings.general.notificationsTitle': 'システム通知', + 'settings.general.notificationsDescription': '権限の確認、エージェントの応答、スケジュールタスクの結果に OS ネイティブの通知を使用します。', + 'settings.general.notificationsEnabled': 'システム通知を有効にする', + 'settings.general.notificationsHintOn': '有効にすると、アプリは通知権限を要求し、OS の通知センターを使用します。', + 'settings.general.notificationsHintOff': '無効にすると、権限の確認、エージェントの応答、スケジュールタスクはデスクトップ通知を送信しません。', + 'settings.general.notificationsStatus': '権限', + 'settings.general.notificationsStatusGranted': '許可済み', + 'settings.general.notificationsStatusDenied': 'システム設定でブロックされています', + 'settings.general.notificationsStatusDefault': '未要求', + 'settings.general.notificationsStatusUnsupported': 'この環境では利用できません', + 'settings.general.notificationsAuthorize': '許可する', + 'settings.general.notificationsOpenSettings': '設定を開く', + 'settings.general.notificationsTestTitle': 'Claude Code Haha の通知が有効になりました', + 'settings.general.notificationsTestBody': '権限の確認と完了したエージェントの応答に、これからシステム通知が使用されます。', + 'settings.general.chatSendBehaviorTitle': 'メッセージの送信', + 'settings.general.chatSendBehaviorDescription': 'デスクトップのチャット入力欄でメッセージを送信する方法を選択します。', + 'settings.general.chatSendBehaviorEnter': 'Enter で送信', + 'settings.general.chatSendBehaviorEnterDescription': 'Shift+Enter で改行を挿入します。', + 'settings.general.chatSendBehaviorModifier': 'Ctrl/Cmd+Enter で送信', + 'settings.general.chatSendBehaviorModifierDescription': 'Enter と Shift+Enter で改行を挿入します。', + 'settings.general.h5AccessTitle': 'H5 アクセス', + 'settings.general.h5AccessDescription': 'デスクトップ H5 アプリをローカルネットワークに公開します。スマートフォンは、有効期限の短い H5 トークンを含む QR リンクで接続します。', + 'settings.general.h5AccessEnabled': 'H5 アクセスを有効にする', + 'settings.general.h5AccessEnabledHint': 'デスクトップサーバーが LAN アドレスで待ち受け、デスクトップセッションへのアクセスを許可します。', + 'settings.general.h5AccessStatusEnabled': '有効', + 'settings.general.h5AccessTokenPreview': 'トークンプレビュー', + 'settings.general.h5AccessDisabledValue': '無効', + 'settings.general.h5AccessDisable': '無効化', + 'settings.general.h5AccessGenerateToken': 'トークンを生成', + 'settings.general.h5AccessRegenerate': 'トークンを再生成', + 'settings.general.h5AccessGeneratedToken': '生成されたトークン', + 'settings.general.h5AccessGeneratedTokenHint': '一度だけ表示されます。今すぐコピーし、パスワードのように保管してください。', + 'settings.general.h5AccessShowToken': 'トークンを表示', + 'settings.general.h5AccessCopy': 'コピー', + 'settings.general.h5AccessCopyUrl': 'H5 URL をコピー', + 'settings.general.h5AccessCopyLaunchUrl': 'QR リンクをコピー', + 'settings.general.h5AccessUrlCopied': 'H5 URL をコピーしました。', + 'settings.general.h5AccessLaunchUrlCopied': 'QR リンクをコピーしました。', + 'settings.general.h5AccessHideToken': 'トークンを非表示', + 'settings.general.h5AccessTokenNotAvailable': '新しいトークンを表示するには再生成してください。', + 'settings.general.h5AccessPublicHost': 'アクセスホスト / IP', + 'settings.general.h5AccessPublicHostPlaceholder': '192.168.1.100', + 'settings.general.h5AccessCurrentPort': '現在のポート', + 'settings.general.h5AccessCurrentPortUnknown': '自動', + 'settings.general.h5AccessPublicUrl': '公開 URL', + 'settings.general.h5AccessPublicUrlPlaceholder': 'https://chat.example.com', + 'settings.general.h5AccessAllowedOrigins': '許可するオリジン', + 'settings.general.h5AccessAllowedOriginsPlaceholder': 'https://chat.example.com, https://phone.example', + 'settings.general.h5AccessOriginsHint': '1 行に 1 つのオリジンを入力するか、複数のオリジンをカンマで区切ってください。', + 'settings.general.h5AccessOpenHint': 'LAN アクセスの場合は、ホスト / IP のみを変更してください。現在のサービスポートが再利用されます。リバースプロキシの場合は完全な URL を入力してください。', + 'settings.general.h5AccessSave': 'H5 設定を保存', + 'settings.general.h5AccessUrl': 'H5 URL', + 'settings.general.h5AccessQrTitle': 'スマートフォン接続', + 'settings.general.h5AccessQrHint': 'スキャンすると、トークンが入力済みの状態で H5 が開きます。', + 'settings.general.h5AccessQrRefreshHint': '「トークンを生成」をクリックすると、スキャンできる QR リンクが作成されます。', + 'settings.general.h5AccessQrEmptyHint': 'QR コードを作成するにはトークンを生成してください。', + 'settings.general.h5AccessQrAlt': 'H5 アクセス用 QR コード', + 'settings.general.h5AccessSafetyNote': '信頼できるネットワークでのみ有効にしてください。QR リンクを持つ誰もが、H5 が公開するデスクトップ機能にアクセスできます。', + 'settings.general.h5AccessConfirmTitle': 'LAN H5 アクセスを有効にしますか?', + 'settings.general.h5AccessConfirmBody': 'これにより、デスクトップ H5 アプリが LAN アドレスとポートで公開されます。QR トークンを持つデバイスは、デスクトップセッションと関連する操作にアクセスできます。信頼できるネットワークでのみ続行してください。', + 'settings.general.h5AccessConfirmEnable': 'H5 アクセスを有効にする', + 'settings.general.h5AccessError': 'H5 アクセス設定の更新に失敗しました。', + 'settings.general.h5AccessStaleHostTitle': '保存された H5 ホストに到達できなくなりました', + 'settings.general.h5AccessStaleHostBody': '保存されたホスト {storedHost} は、このマシンのアクティブなインターフェースにバインドされていません。QR コードをスキャンしたスマートフォンは接続に失敗します。現在の LAN IP に切り替えることをお勧めします。', + 'settings.general.h5AccessStaleHostNoSuggestion': '保存されたホスト {storedHost} は、このマシンのアクティブなインターフェースにバインドされていません。QR コードをスキャンしたスマートフォンは接続に失敗します。このマシンのネットワーク接続を確認するか、リバースプロキシ URL に切り替えてください。', + 'settings.general.h5AccessStaleHostApply': '{suggestedHost} に切り替え', + 'settings.general.h5AccessProxyNote': '現在リバースプロキシ URL を使用しています。スマートフォンは、設定した公開ドメイン / トンネルを通じてデスクトップに到達します。プロキシが稼働中であることを確認してください。', + 'settings.general.networkTitle': 'ネットワーク', + 'settings.general.networkDescription': 'デスクトップセッションが行うプロバイダー API リクエストを制御します。', + 'settings.general.networkProxyModeSystem': 'システムプロキシ', + 'settings.general.networkProxyModeSystemDescription': 'アプリプロセスが継承したプロキシ設定を使用します。', + 'settings.general.networkProxyModeManual': '手動プロキシ', + 'settings.general.networkProxyModeManualDescription': '以下に入力した HTTP または HTTPS プロキシ URL を使用します。', + 'settings.general.networkProxyUrl': 'プロキシ URL', + 'settings.general.networkProxyUrlHint': 'HTTP および HTTPS プロキシ URL に対応しています。例: http://127.0.0.1:7890。', + 'settings.general.networkProxyUrlInvalid': 'HTTP または HTTPS のプロキシ URL を入力してください。', + 'settings.general.networkProxyUrlRequired': 'プロキシ URL を入力してください。', + 'settings.general.networkTimeout': 'AI リクエストのタイムアウト', + 'settings.general.networkTimeoutValue': '{seconds}秒', + 'settings.general.networkTimeoutHint': 'プロバイダーへのリクエスト、ストリーミングの最初の応答、プロバイダー接続テストに適用されます。5〜600 秒に対応します。', + 'settings.general.networkTimeoutUnit': '秒', + 'settings.general.networkTimeoutDecrease': '30 秒減らす', + 'settings.general.networkTimeoutIncrease': '30 秒増やす', + 'settings.general.networkTimeoutRequired': 'タイムアウトを入力してください。', + 'settings.general.networkTimeoutRange': '{min} から {max} 秒までの整数を入力してください。', + 'settings.general.networkSaved': 'ネットワーク設定を保存しました。', + 'settings.general.networkScopeHint': '別途設定するアプリ更新用プロキシは変更されません。', + 'settings.general.networkSave': '保存', + 'settings.general.webFetchPreflightTitle': 'WebFetch プリフライト', + 'settings.general.webFetchPreflightDescription': 'デスクトップセッションは、サードパーティプロバイダーや制限されたネットワークでの誤った失敗を避けるため、デフォルトで Claude のドメインプリフライトをスキップします。', + 'settings.general.webFetchPreflightEnabled': 'WebFetch のドメインプリフライトをスキップ', + 'settings.general.webFetchPreflightHint': '各 WebFetch リクエスト前の上流の安全プリフライトを明示的に復元したい場合のみ、これをオフにしてください。', + 'settings.general.webSearchTitle': 'WebSearch', + 'settings.general.webSearchDescription': 'エージェントのウェブ検索を、公式 Claude、サードパーティプロバイダー、ローカルのフォールバックキーのどれで解決するかを選択します。', + 'settings.general.webSearch.mode.auto': '自動', + 'settings.general.webSearch.mode.tavily': 'Tavily', + 'settings.general.webSearch.mode.brave': 'Brave', + 'settings.general.webSearch.mode.anthropic': 'Claude', + 'settings.general.webSearch.mode.disabled': 'オフ', + 'settings.general.webSearchTavilyKey': 'Tavily API キー', + 'settings.general.webSearchBraveKey': 'Brave Search API キー', + 'settings.general.webSearchBravePlaceholder': 'Brave Search トークン', + 'settings.general.webSearchGetApiKey': 'API キーを取得', + 'settings.general.webSearchTavilyApiKeyLink': 'Tavily API キーを取得', + 'settings.general.webSearchBraveApiKeyLink': 'Brave Search API キーを取得', + 'settings.general.webSearchTavilyFreeHint': 'アカウントを作成してキーをコピーしてください。無料プランには 1000 クレジットが含まれます。', + 'settings.general.webSearchBraveFreeHint': 'アカウントを作成すると、テスト用の無料枠付きで Search API キーを生成できます。', + 'settings.general.webSearchHint': '自動の場合、Claude のモデル名にはネイティブの Claude ウェブ検索を使用し、その後 Tavily と Brave のキーにフォールバックします。', + 'settings.general.webSearchSave': '保存', + 'settings.general.uiZoom': 'UI ズーム', + 'settings.general.uiZoomDescription': 'インターフェース全体のサイズを調整します。', + 'settings.general.uiZoomShortcutHint': 'ショートカットの方が速いです:', + 'settings.general.uiZoomShortcutMac': 'macOS', + 'settings.general.uiZoomShortcutWindows': 'Windows / Linux', + 'settings.general.uiZoomShortcutResetHint': '0 でズームを 100% にリセットします。', + 'settings.general.uiZoomReset': 'UI ズームを 100% にリセット', + + // ─── Empty Session ────────────────────────────────────── + 'empty.title': '新しいセッション', + 'empty.subtitle': '新しいコーディングセッションを開始します。Claude は、プロジェクトの構築、デバッグ、設計をお手伝いする準備ができています。', + 'empty.placeholder': '何でも質問してください...', + 'empty.addFiles': 'ファイルまたは写真を追加', + 'empty.slashCommands': 'スラッシュコマンド', + 'empty.failedToCreate': 'セッションの作成に失敗しました', + 'empty.createError.workdirMissing': 'プロジェクトフォルダが見つからないか、ディレクトリではありません。既存のプロジェクトを選択してもう一度お試しください。', + 'empty.createError.notGit': 'このプロジェクトは Git リポジトリではないため、ブランチでの起動は利用できません。現在のフォルダで開始するか、Git プロジェクトを選択してください。', + 'empty.createError.branchNotFound': '選択したブランチは存在しなくなりました。プロジェクトコンテキストを更新して、別のブランチを選択してください。', + 'empty.createError.dirtyWorktree': '現在のプロジェクトに未コミットの変更があります。ブランチの直接切り替えはブロックされました。「独立した worktree」を有効にするか、変更を先にコミット/スタッシュしてください。', + 'empty.createError.branchCheckedOut': 'そのブランチは別の worktree で既にチェックアウトされています。「独立した worktree」を有効にするか、別のブランチを選択してください。', + 'empty.createError.worktreeCreateFailed': '独立した worktree を作成できませんでした。Git がこのリポジトリに書き込めることを確認してから、もう一度お試しください。詳細: {detail}', + 'empty.createError.switchFailed': '現在のプロジェクトブランチを切り替えできませんでした。Git のエラーを確認し、変更を安全に保ってから、もう一度お試しください。詳細: {detail}', + 'empty.createError.contextFailed': 'この Git プロジェクトを検査できませんでした。リポジトリの状態を確認してもう一度お試しください。', + + // ─── Repository Launch Controls ────────────────────────────────────── + 'repoLaunch.selectBranch': 'ブランチを選択', + 'repoLaunch.searchBranch': 'ブランチを検索', + 'repoLaunch.noBranch': 'ブランチなし', + 'repoLaunch.noBranchMatch': '一致するブランチがありません', + 'repoLaunch.currentBranch': '現在のブランチ', + 'repoLaunch.localBranch': 'ローカルブランチ', + 'repoLaunch.remoteBranch': 'リモートブランチ', + 'repoLaunch.checkedOut': '別の worktree でチェックアウト済み', + 'repoLaunch.worktreeCurrent': '現在の worktree', + 'repoLaunch.worktreeIsolated': '独立した worktree', + 'repoLaunch.selectWorktree': 'worktree モードを選択', + 'repoLaunch.missingWorkdir': '作業ディレクトリが見つかりません。', + 'repoLaunch.dirtyWarning': '未コミットの変更が検出されました。直接切り替えはブロックされる場合があります。このフォルダに触れずに続行するには、独立した worktree を使用してください。', + 'repoLaunch.checkedOutWarning': '選択したブランチは別の worktree で既にチェックアウトされています。直接起動は Git によってブロックされる場合があります。ディレクトリの変更を避けるには「独立した worktree」を使用してください。', + + // ─── Chat Input ────────────────────────────────────── + 'chat.placeholder': '編集、デバッグ、説明を Claude に依頼...', + 'chat.placeholderMissing': 'このセッションは見つからないワークスペースを指しています。新しいセッションを作成するか、別のプロジェクトを選択してください。', + 'chat.addFiles': 'ファイルまたは写真を追加', + 'chat.dropFilesTitle': 'ここにファイルをドロップ', + 'chat.dropFilesHint': 'ファイルパスとして添付されます。', + 'chat.workspaceReferencesOnly': 'ワークスペース参照を {count} 件追加しました', + 'chat.contextReferencesOnly': '参照を {count} 件追加しました', + 'chat.addSelectionToChat': 'チャットに追加', + 'chat.branchFromHere': '新しい会話を分岐', + 'chat.branchSuccess': '分岐した会話「{title}」を作成しました。', + 'chat.branchError': 'このメッセージから分岐できませんでした。詳細: {detail}', + 'chat.userMessageReference': 'ユーザーメッセージ', + 'chat.assistantMessageReference': 'アシスタントメッセージ', + 'chat.slashCommands': 'スラッシュコマンド', + 'chat.goalEvent.created': 'ゴールを設定しました', + 'chat.goalEvent.replaced': 'ゴールを設定しました', + 'chat.goalEvent.statusTitle': 'ゴールのステータス', + 'chat.goalEvent.paused': 'ゴールを一時停止しました', + 'chat.goalEvent.resumed': 'ゴールを再開しました', + 'chat.goalEvent.completed': 'ゴールを完了しました', + 'chat.goalEvent.cleared': 'ゴールをクリアしました', + 'chat.goalEvent.message': 'ゴールの更新', + 'chat.goalEvent.objective': '目標: {value}', + 'chat.goalEvent.statusValue': 'ステータス: {value}', + 'chat.goalEvent.budget': '予算: {value}', + 'chat.goalEvent.continuations': '継続回数: {value}', + 'chat.compactSummary.compacting': 'コンテキストを圧縮中', + 'chat.compactSummary.title': 'コンテキストを圧縮しました', + 'chat.compactSummary.autoTitle': 'コンテキストを自動的に圧縮しました', + 'chat.compactSummary.manualTitle': 'コンテキストを手動で圧縮しました', + 'chat.compactSummary.trigger.manual': '手動', + 'chat.compactSummary.trigger.auto': '自動', + 'chat.compactSummary.tokens': '圧縮前は {count} トークン', + 'chat.compactSummary.messages': '{count} 件のメッセージを要約しました', + 'chat.activeGoal.title': 'アクティブなゴール', + 'chat.activeGoal.running': 'ループ実行中', + 'chat.activeGoal.active': 'アクティブ', + 'chat.activeGoal.paused': '一時停止中', + 'chat.activeGoal.completed': '完了', + 'chat.activeGoal.budget': '予算 {value}', + 'chat.activeGoal.continuations': '継続回数 {value}', + 'chat.activeGoal.elapsed': '経過 {value}', + 'chat.backgroundAgents.title': 'バックグラウンドエージェント', + 'chat.backgroundAgents.count': '{count} 件がアクティブまたは最近', + 'chat.backgroundAgents.agent': 'エージェント', + 'chat.backgroundTasks.command': 'バックグラウンドコマンド', + 'chat.backgroundTasks.workflow': 'バックグラウンドワークフロー', + 'chat.backgroundTasks.task': 'バックグラウンドタスク', + 'chat.backgroundAgents.tokens': '{count} トークン', + 'chat.backgroundAgents.status.running': '実行中', + 'chat.backgroundAgents.status.completed': '完了', + 'chat.backgroundAgents.status.failed': '失敗', + 'chat.backgroundAgents.status.stopped': '停止', + 'slash.mcp.title': '利用可能な MCP ツール', + 'slash.mcp.subtitle': 'このチャットコンテキストで利用できる、グローバルおよび現在のプロジェクトの MCP サーバー。', + 'slash.mcp.subtitleWithProject': '次のグローバルおよびプロジェクトの MCP を表示中: {path}', + 'slash.mcp.emptyTitle': '利用可能な MCP サーバーがありません', + 'slash.mcp.emptyBody': 'このチャットコンテキストで利用できるグローバルまたはプロジェクトの MCP サーバーがありません。', + 'slash.mcp.projectBadge': 'プロジェクト: {name}', + 'slash.skills.title': '利用可能なスキル', + 'slash.skills.subtitle': '現在のコンテキストで利用できる、ユーザーが呼び出せるスキル。', + 'slash.skills.subtitleWithProject': '次のスキルを表示中: {path}', + 'slash.skills.emptyTitle': '利用可能なスキルがありません', + 'slash.skills.emptyBody': 'このコンテキストで、ユーザーが呼び出せるスキルが見つかりませんでした。', + 'slash.plugins.title': 'プラグイン', + 'slash.plugins.subtitle': 'プラグイン管理はこのスラッシュコマンド画面に移動します。', + 'slash.plugins.emptyTitle': 'プラグインパネルは近日公開', + 'slash.plugins.emptyBody': 'この共有スラッシュコマンドパネルは現在接続済みです。プラグインデータは次に接続されます。', + 'slash.help.title': 'スラッシュコマンド', + 'slash.help.subtitle': 'エージェントのワークフローを実行したり、セッション状態を確認したり、デスクトップパネルを開いたりします。', + 'slash.help.group.context': 'コンテキスト', + 'slash.help.group.project': 'プロジェクト', + 'slash.help.group.desktop': 'デスクトップ', + 'slash.help.group.more': 'その他', + 'slash.help.moreAvailable': 'あと {count} 個のコマンドが利用できます。/ を入力してコマンド一覧全体を検索してください。', + 'slash.inspector.title': 'セッションインスペクター', + 'slash.inspector.close': 'セッションインスペクターを閉じる', + 'slash.inspector.loading': 'セッションデータを読み込み中', + 'slash.inspector.error.noActiveSession': 'アクティブなセッションが選択されていません。', + 'slash.inspector.error.unavailable': 'セッションインスペクターのデータが利用できません。/api/sessions/:id/inspection が読み込まれるよう、デスクトップサーバーを再起動してください。', + 'slash.inspector.tab.status': 'ステータス', + 'slash.inspector.tab.usage': '使用量', + 'slash.inspector.tab.context': 'コンテキスト', + 'slash.inspector.status.cliStatus': 'CLI ステータス', + 'slash.inspector.status.running': '実行中', + 'slash.inspector.status.notRunning': '実行されていません', + 'slash.inspector.status.activeModel': 'アクティブなモデル', + 'slash.inspector.status.unknown': '不明', + 'slash.inspector.status.mcpConnections': 'MCP 接続', + 'slash.inspector.status.connected': '接続済み', + 'slash.inspector.status.failed': '失敗', + 'slash.inspector.status.registeredTools': '登録済みツール', + 'slash.inspector.status.commands': 'コマンド', + 'slash.inspector.status.sessionMetadata': 'セッションのメタデータ', + 'slash.inspector.status.version': 'バージョン', + 'slash.inspector.status.sessionId': 'セッション ID', + 'slash.inspector.status.workingDirectory': '作業ディレクトリ', + 'slash.inspector.status.permissionMode': '権限モード', + 'slash.inspector.status.authToken': '認証トークン', + 'slash.inspector.status.outputStyle': '出力スタイル', + 'slash.inspector.status.default': 'デフォルト', + 'slash.inspector.status.mcpServers': 'MCP サーバー', + 'slash.inspector.status.refresh': '更新', + 'slash.inspector.status.contextWindow': 'コンテキストウィンドウ', + 'slash.inspector.usage.emptyTitle': '使用量データはまだありません', + 'slash.inspector.usage.emptyBody': 'CLI セッションが開始され、少なくとも 1 ターン完了すると使用量が表示されます。', + 'slash.inspector.usage.contextSnapshotNotice': '現在のコンテキストスナップショットからトークン使用量を表示しています。使用量はコンテキストの取得に応じて動的に更新されます。', + 'slash.inspector.usage.transcriptNotice': 'セッションの記録から再構築した使用量を表示しています。API 所要時間は、現在実行中の CLI プロセスでのみ利用できます。', + 'slash.inspector.usage.unknownCost': '1 つ以上のモデルの料金が不明なため、コストが不正確な場合があります。', + 'slash.inspector.usage.totalCost': '合計コスト', + 'slash.inspector.usage.source': 'ソース', + 'slash.inspector.usage.source.contextSnapshot': 'コンテキストスナップショット', + 'slash.inspector.usage.source.transcript': '記録', + 'slash.inspector.usage.source.currentProcess': '現在のプロセス', + 'slash.inspector.usage.apiDuration': 'API 所要時間', + 'slash.inspector.usage.wallDuration': '実時間', + 'slash.inspector.usage.usageSpan': '使用期間', + 'slash.inspector.usage.codeChanges': 'コードの変更', + 'slash.inspector.usage.input': '入力', + 'slash.inspector.usage.output': '出力', + 'slash.inspector.usage.cacheReadWrite': 'キャッシュ読み取り / 書き込み', + 'slash.inspector.usage.webSearch': 'ウェブ検索', + 'slash.inspector.usage.byModel': 'モデル別の使用量', + 'slash.inspector.usage.tokens': 'トークン', + 'slash.inspector.usage.noModelTitle': 'モデルの使用量がありません', + 'slash.inspector.usage.noModelBody': 'モデルの応答が記録されると、ここにトークン使用量が表示されます。', + 'slash.inspector.context.loading': 'コンテキストデータを読み込み中', + 'slash.inspector.context.emptyTitle': 'コンテキストデータはまだありません', + 'slash.inspector.context.emptyBody': 'コンテキストの使用量にはアクティブな CLI セッションが必要です。', + 'slash.inspector.context.windowUsage': 'コンテキストウィンドウの使用量', + 'slash.inspector.context.used': '使用済み', + 'slash.inspector.context.free': '空き', + 'slash.inspector.context.messages': 'メッセージ', + 'slash.inspector.context.assistant': 'アシスタント', + 'slash.inspector.context.toolResults': 'ツールの結果', + 'slash.inspector.context.context': 'コンテキスト', + 'slash.inspector.context.categoryTitle': 'カテゴリ別の推定使用量', + 'slash.inspector.context.noCategoriesTitle': 'コンテキストカテゴリがありません', + 'slash.inspector.context.noCategoriesBody': 'CLI がコンテキスト分析を報告すると、コンテキストカテゴリが表示されます。', + 'slash.inspector.context.memoryFiles': 'メモリファイル', + 'slash.inspector.context.noMemoryFiles': 'このセッションにはメモリファイルが読み込まれていません。', + 'slash.inspector.context.openMemory': 'メモリを開く', + 'contextIndicator.ariaLabel': 'コンテキスト使用量 {percent}', + 'contextIndicator.pendingAria': 'コンテキスト使用量は未計算', + 'contextIndicator.loadingAria': 'コンテキスト使用量を読み込み中', + 'contextIndicator.unavailableAria': 'コンテキスト使用量は利用不可', + 'contextIndicator.title': 'コンテキスト', + 'contextIndicator.modelUnknown': '不明なモデル', + 'contextIndicator.used': '使用済み', + 'contextIndicator.free': '空き', + 'contextIndicator.window': 'ウィンドウ', + 'contextIndicator.loading': 'コンテキスト使用量を読み込み中...', + 'contextIndicator.pendingDetail': 'コンテキスト使用量はセッション開始後に計算されます。', + 'contextIndicator.unavailable': 'なし', + 'contextIndicator.unavailableDetail': 'このセッションではコンテキスト使用量は利用できません。', + 'contextIndicator.updatedUnknown': 'まだ更新されていません', + 'contextIndicator.updatedNow': 'たった今更新', + 'contextIndicator.updatedMinutes': '{count} 分前に更新', + 'contextIndicator.estimate': '推定', + 'chat.navigate': '移動', + 'chat.select': '選択', + 'chat.dismiss': '閉じる', + 'chat.stopTitle': '生成を停止 (Cmd+.)', + 'chat.jumpToLatest': '最新', + 'chat.memorySavedTitle': '{count} 件のメモリファイルを保存しました', + 'chat.memorySavedFromToolsTitle': '{count} 件のメモリ項目を保存しました', + 'chat.memoryReferencedTitle': '{count} 件のメモリ参照', + 'chat.memoryOpenSettings': 'メモリを開く', + 'chat.memoryMoreFiles': '+{count} 件', + 'chat.memoryTechnicalDetails': 'ツールの詳細', + 'chat.rewindSuccessWithCode': '{count} 件のメッセージを巻き戻し、追跡対象のファイルを復元しました。', + 'chat.rewindSuccessConversationOnly': '{count} 件のメッセージを巻き戻しました。このターンには利用できるファイルチェックポイントがありませんでした。', + 'chat.turnChangesTitle': '{count} 個のファイルが変更されました', + 'chat.turnChangesLatestCardLabel': 'ターンで変更されたファイル', + 'chat.turnChangesHistoricalCardLabel': 'ターンで変更されたファイル', + 'chat.turnChangesLatestSubtitle': '現在のターンのチェックポイント', + 'chat.turnChangesHistoricalSubtitle': '保存済みターンのチェックポイント', + 'chat.turnChangesLatestUndo': '現在のターンを元に戻す', + 'chat.turnChangesHistoricalUndo': 'このターンの前まで巻き戻す', + 'chat.turnChangesUndoing': '元に戻しています...', + 'chat.turnChangesLatestUndoAria': '現在のターンの変更を元に戻す', + 'chat.turnChangesHistoricalUndoAria': 'このターンの前まで巻き戻す', + 'chat.turnChangesLatestConfirmTitle': '現在のターンを元に戻しますか?', + 'chat.turnChangesHistoricalConfirmTitle': 'このターンの前まで巻き戻しますか?', + 'chat.turnChangesLatestConfirmBody': '最新のアシスタントの応答を巻き戻し、このターンの追跡対象ファイルを復元します。', + 'chat.turnChangesHistoricalConfirmBody': '会話をこのターンの前まで巻き戻し、そのチェックポイントの追跡対象ファイルを復元します。', + 'chat.turnChangesLatestConfirmUndo': '現在のターンを元に戻す', + 'chat.turnChangesHistoricalConfirmUndo': 'このターンの前まで巻き戻す', + 'chat.turnChangesOpenInWorkspaceAria': '{path} をワークスペースで開く', + 'chat.turnChangesShowMore': 'さらに {count} 個のファイルを表示', + 'chat.turnChangesShowLess': '表示を減らす', + + // ─── Streaming Indicator ────────────────────────────────────── + 'streaming.thinking': '思考中', + 'streaming.running': '実行中', + 'streaming.working': '作業中', + + // ─── Permission Dialog ────────────────────────────────────── + 'permission.allowEditFile': 'Claude が {fileName} を {toolName} することを許可しますか?', + 'permission.allowEditFileGeneric': 'Claude がこのファイルを {toolName} することを許可しますか?', + 'permission.allowBash': 'Claude がこのコマンドを実行することを許可しますか?', + 'permission.allowTool': 'Claude が {toolName} を使用することを許可しますか?', + 'permission.awaitingApproval': '承認待ち', + 'permission.responded': '応答済み', + 'permission.allow': '許可', + 'permission.allowForSession': 'このセッションで許可', + 'permission.deny': '拒否', + 'permission.hideDetails': '詳細を非表示', + 'permission.showFullInput': '入力全体を表示', + 'permission.replacingContent': 'ファイル内のコンテンツを置換中', + + // ─── Computer Use Approval ────────────────────────────────────── + 'computerUseApproval.titleApps': 'コンピューター操作がこれらのアプリを操作しようとしています', + 'computerUseApproval.titleTcc': 'コンピューター操作には macOS の権限が必要です', + 'computerUseApproval.reason': 'Claude が要求している理由', + 'computerUseApproval.allow': 'このセッションで許可', + 'computerUseApproval.deny': '拒否', + 'computerUseApproval.alreadyGranted': 'このセッションでは既に許可されています', + 'computerUseApproval.notInstalled': 'アプリがインストールされていません', + 'computerUseApproval.sensitiveApp': 'このアプリは機密として扱われ、追加の確認が必要です。', + 'computerUseApproval.alsoRequested': '同時に要求中', + 'computerUseApproval.hideWhileWorking': 'Claude の作業中、他の {count} 個のアプリが非表示になります。', + 'computerUseApproval.hideWhileWorkingRestore': 'Claude の作業中、他の {count} 個のアプリが非表示になり、Claude の完了後に復元されます。', + 'computerUseApproval.accessibility': 'アクセシビリティ', + 'computerUseApproval.screenRecording': '画面収録', + 'computerUseApproval.granted': '許可済み', + 'computerUseApproval.notGranted': '未許可', + 'computerUseApproval.openAccessibility': 'アクセシビリティを開く', + 'computerUseApproval.openScreenRecording': '画面収録を開く', + 'computerUseApproval.tryAgain': '再試行', + 'computerUseApproval.tccHint': 'システム設定で不足している権限を許可してから、ここに戻って「再試行」を選択してください。', + 'computerUseApproval.tryAgainHint': '再試行すると Claude に制御が戻り、macOS の権限変更が反映された後に request_access をもう一度呼び出せます。', + + // ─── Ask User Question ────────────────────────────────────── + 'question.needsInput': 'Claude が入力を必要としています', + 'question.answered': '回答済み', + 'question.completed': '完了', + 'question.customResponse': 'または、独自の回答を入力してください:', + 'question.typePlaceholder': '回答を入力...', + 'question.submit': '送信', + 'question.answeredPrefix': '回答: ', + 'question.resultPrefix': '結果: ', + + // ─── Thinking Block ────────────────────────────────────── + 'thinking.label': '思考中', + 'thinking.labelDone': '思考完了', + + // ─── Tool Calls ────────────────────────────────────── + 'tool.errorOutput': 'エラー出力', + 'tool.toolOutput': 'ツール出力', + 'tool.toolInput': 'ツール入力', + 'tool.partialInput': '部分的な入力', + 'tool.writerPreview': 'Writer', + 'tool.writerPreviewLatest': '{total} 行のうち最新の {visible} 行を表示中', + 'tool.generatingContent': 'コンテンツを生成中', + 'tool.preparingEdit': '編集を準備中', + 'tool.preparingTool': 'ツールを準備中', + 'tool.readFileContents': 'ファイルの内容を読み取り', + 'tool.createFile': 'ファイルを作成', + 'tool.updateFileContents': 'ファイルの内容を更新', + 'tool.linesChanged': '{count} 行が変更されました', + 'tool.linesCreated': '{count} 行が作成されました', + 'tool.linesOutput': '{count} 行が出力されました', + 'tool.result': '{toolName} の結果', + 'tool.resultGeneric': 'ツールの結果', + 'tool.error': 'エラー', + 'tool.success': '成功', + 'tool.showLess': '表示を減らす', + 'tool.showMore': 'さらに {count} 文字を表示', + + // ─── Tool Group Verbs ────────────────────────────────────── + 'toolGroup.readOne': 'ファイルを 1 件読み取り', + 'toolGroup.readMany': '{count} 件のファイルを読み取り', + 'toolGroup.createdOne': 'ファイルを作成しました', + 'toolGroup.createdMany': '{count} 件のファイルを作成しました', + 'toolGroup.editedOne': 'ファイルを編集しました', + 'toolGroup.editedMany': '{count} 件のファイルを編集しました', + 'toolGroup.ranOne': 'コマンドを実行しました', + 'toolGroup.ranMany': '{count} 件のコマンドを実行しました', + 'toolGroup.foundFiles': 'ファイルを検索しました', + 'toolGroup.searchedOne': 'コードを検索しました', + 'toolGroup.searchedMany': '{count} 件のパターンを検索しました', + 'toolGroup.agentOne': 'エージェントを 1 件起動しました', + 'toolGroup.agentMany': '{count} 件のエージェントを起動しました', + 'agentStatus.starting': '起動中', + 'agentStatus.running': '実行中', + 'agentStatus.done': '完了', + 'agentStatus.failed': '失敗', + 'agentStatus.stopped': '停止', + 'agentStatus.noActivity': 'まだツールの動作がありません', + 'agentStatus.viewResult': '結果を表示', + 'agentStatus.resultTitle': 'エージェントの結果', + 'toolGroup.searchedWeb': 'ウェブを検索しました', + 'toolGroup.fetchedOne': 'ページを 1 件取得しました', + 'toolGroup.fetchedMany': '{count} 件のページを取得しました', + + // ─── Tasks ────────────────────────────────────── + 'tasks.title': 'タスク', + 'tasks.completed': '完了したタスク', + 'tasks.dismissCompleted': '完了したタスクを非表示', + 'tasks.newTask': '+ 新しいタスク', + 'tasks.emptyTitle': 'スケジュールされたタスクはまだありません。', + 'tasks.emptyDesc': '繰り返しタスクを作成して、エンジニアリングのワークフローを自動化しましょう。', + 'tasks.createNew': '新しいタスクを作成', + 'tasks.totalTasks': 'タスク総数', + 'tasks.active': 'アクティブ', + 'tasks.disabled': '無効', + + // ─── New Task Modal ────────────────────────────────────── + 'newTask.title': '新しいスケジュールタスク', + 'newTask.localWarning': 'ローカルタスクは、コンピューターが起動している間のみ実行されます。', + 'newTask.fullPermissions': 'すべての権限', + 'newTask.name': '名前', + 'newTask.namePlaceholder': 'daily-code-review', + 'newTask.description': '説明', + 'newTask.descPlaceholder': '昨日のコミットをレビューし、気になる点を指摘する', + 'newTask.frequency': '頻度', + 'newTask.everyNMinutes': 'N 分ごと', + 'newTask.everyNHours': 'N 時間ごと', + 'newTask.daily': '毎日', + 'newTask.weekdays': '平日(月〜金)', + 'newTask.specificDays': '特定の曜日', + 'newTask.monthly': '毎月', + 'newTask.customCron': 'カスタム cron 式', + 'newTask.intervalMinutes': '{n} 分ごと', + 'newTask.intervalHours': '{n} 時間ごと', + 'newTask.atMinute': ':{m} 分に', + 'newTask.onMonthDay': '毎月 {d} 日に', + 'newTask.cronFormatHint': '形式: 分 時 日 月 曜日', + 'newTask.invalidCron': '無効な cron 式', + 'newTask.daySun': '日', + 'newTask.dayMon': '月', + 'newTask.dayTue': '火', + 'newTask.dayWed': '水', + 'newTask.dayThu': '木', + 'newTask.dayFri': '金', + 'newTask.daySat': '土', + 'newTask.delayNote': 'スケジュールタスクは、サーバーのパフォーマンスのために数分のランダムな遅延を使用します。', + 'newTask.create': 'タスクを作成', + 'newTask.promptPlaceholder': '過去 24 時間のコミットを確認してください。何が変わったかを要約し、リスクのあるパターンや不足しているテストを指摘し、フォローアップする価値のある点を書き留めてください。', + 'newTask.notification': '通知', + 'newTask.notifyOnComplete': '完了時にプッシュ通知', + 'newTask.notifyChannels': '通知チャンネル', + 'newTask.notifyHint': 'タスクの完了時に、OS ネイティブのデスクトップ通知または IM メッセージを送信します。', + 'newTask.notifyDesktop': 'デスクトップ', + 'newTask.notConfigured': '未設定', + 'newTask.noChannelConfigured': 'IM チャンネルがまだ設定されていません。設定 → IM アダプター でセットアップしてください。', + 'newTask.noChannelSelected': '少なくとも 1 つの通知チャンネルを選択してください。', + + // ─── Cron Descriptions ────────────────────────────────────── + 'cron.everyMinute': '毎分実行', + 'cron.everyNMinutes': '{n} 分ごとに実行', + 'cron.everyHour': '毎時実行', + 'cron.everyNHours': '{n} 時間ごとに実行', + 'cron.everyNHoursAtMinute': '{n} 時間ごとに :{m} 分に実行', + 'cron.dailyAt': '毎日 {time} に実行', + 'cron.weekdaysAt': '平日の {time} に実行', + 'cron.specificDaysAt': '毎週 {days} の {time} に実行', + 'cron.monthlyAt': '毎月 {day} 日の {time} に実行', + 'cron.customSchedule': 'カスタム: {cron}', + 'cron.dow.0': '日', + 'cron.dow.1': '月', + 'cron.dow.2': '火', + 'cron.dow.3': '水', + 'cron.dow.4': '木', + 'cron.dow.5': '金', + 'cron.dow.6': '土', + + // ─── Task Actions & Logs ────────────────────────────────────── + 'tasks.runNow': '今すぐ実行', + 'tasks.confirmRun': 'このタスクをすぐに実行しますか?', + 'tasks.confirmDisable': 'このスケジュールタスクを無効にしますか?', + 'tasks.confirmEnable': 'このスケジュールタスクを有効にしますか?', + 'tasks.confirmDelete': 'このタスクとそのすべてのログを完全に削除しますか?', + 'tasks.running': '実行中...', + 'tasks.viewLogs': 'ログ', + 'tasks.logsTitle': '実行ログ', + 'tasks.noLogs': '実行ログはまだありません', + 'tasks.runStatus.running': '実行中', + 'tasks.runStatus.completed': '完了', + 'tasks.runStatus.failed': '失敗', + 'tasks.runStatus.timeout': 'タイムアウト', + 'tasks.duration': '{s}秒', + 'tasks.viewOutput': '概要', + 'tasks.hideOutput': '非表示', + 'tasks.close': '閉じる', + 'tasks.edit': '編集', + 'tasks.editTitle': 'スケジュールタスクを編集', + 'tasks.saveChanges': '変更を保存', + 'tasks.openSession': '会話を表示', + 'tasks.createdAt': '作成: ', + 'tasks.lastRunAt': '最終実行: ', + 'tasks.outputHintSession': '「会話を表示」をクリックすると、セッションビューで出力全体を確認できます。', + 'tasks.noOutputText': '利用できる出力はありません。', + + // ─── Prompt Editor ────────────────────────────────────── + 'promptEditor.worktree': 'worktree', + 'promptEditor.bypassWarning': 'バイパスモードはシステムへの完全なアクセスを許可します', + 'promptEditor.within': '範囲:', + 'promptEditor.selectFolder': '— スコープを限定するフォルダを選択', + + // ─── Permission Mode Selector ────────────────────────────────────── + 'permMode.executionPermissions': '実行権限', + 'permMode.askPermissions': '権限を確認', + 'permMode.askPermDesc': 'CLI が要求したときに、ファイル編集やリスクの高いコマンドを確認します', + 'permMode.autoAccept': '編集を自動承認', + 'permMode.autoAcceptDesc': 'Claude が確認なしでディスクに書き込みます', + 'permMode.planMode': 'プランモード', + 'permMode.planModeDesc': '設計と推論のみ、ファイルは扱いません', + 'permMode.bypass': '権限をバイパス', + 'permMode.bypassDesc': 'シェルとファイルシステムへの完全なツールアクセス', + 'permMode.dontAsk': '確認しない', + 'permMode.enableBypassTitle': '権限のバイパスを有効にしますか?', + 'permMode.enableBypassSubtitle': 'これによりシステムへの完全なアクセスが許可されます', + 'permMode.enableBypassBody': 'Claude は次の範囲内で、シェルコマンドの実行とファイルの変更に 無制限の アクセスを持ちます:', + 'permMode.permReadWrite': 'あらゆるファイルの読み取り、書き込み、削除', + 'permMode.permShell': '任意のシェルコマンドの実行', + 'permMode.permPackages': 'パッケージのインストールまたは削除', + 'permMode.enableBypassBtn': 'バイパスを有効化', + + // Mode labels (compact, for chips) + 'permMode.label.default': '権限を確認', + 'permMode.label.acceptEdits': '自動承認', + 'permMode.label.plan': 'プランモード', + 'permMode.label.bypassPermissions': 'バイパス', + 'permMode.label.dontAsk': '確認しない', + + // ─── Model Selector ────────────────────────────────────── + 'model.selectModel': 'モデルを選択', + 'model.configuration': 'モデル設定', + 'model.effort': '労力', + + // ─── Directory Picker ────────────────────────────────────── + 'dirPicker.selectProject': 'プロジェクトを選択...', + 'dirPicker.recent': '最近', + 'dirPicker.noRecent': '最近のプロジェクトはありません', + 'dirPicker.chooseFolder': '別のフォルダを選択', + 'dirPicker.chooseProjectFolder': 'プロジェクトフォルダを選択', + 'dirPicker.useThisFolder': 'このフォルダを使用', + 'dirPicker.noSubdirs': 'サブディレクトリがありません', + + // ─── File Search ────────────────────────────────────── + 'fileSearch.searching': '検索中...', + 'fileSearch.noMatch': '一致するファイルがありません', + 'fileSearch.noFiles': 'このディレクトリにファイルがありません', + 'fileSearch.accessDenied': 'このディレクトリにアクセスできません', + 'fileSearch.loadFailed': 'ディレクトリの読み込みに失敗しました', + 'fileSearch.navigate': '移動', + 'fileSearch.attach': '添付', + 'fileSearch.select': '選択', + 'fileSearch.open': 'フォルダを開く', + 'fileSearch.close': '閉じる', + 'fileSearch.directory': 'フォルダ', + 'fileSearch.currentDirectory': '現在のフォルダ', + 'fileSearch.folderTag': 'フォルダ', + 'fileSearch.fileTag': 'ファイル', + 'fileSearch.openFolder': 'フォルダを開く', + + // ─── Teams ────────────────────────────────────── + 'teams.backToLeader': '\u2190 \u30ea\u30fc\u30c0\u30fc\u306b\u623b\u308b', + 'teams.viewing': '\u8868\u793a\u4e2d:', + 'teams.transcript': '記録', + 'teams.noMessages': 'メッセージはまだありません', + 'teams.team': 'チーム:', + 'teams.members': 'メンバー', + 'teams.working': '作業中...', + 'teams.thinking': '思考中...', + 'teams.running': '実行中', + 'teams.leader': 'team-lead', + 'teams.memberPlaceholder': 'このメンバーに直接メッセージを送信...', + 'teams.memberSessionHint': 'ここでのメッセージはこのメンバーに直接届き、記録の更新を見ながらやり取りできます。', + + // ─── Scheduled Tasks Pages ────────────────────────────────────── + 'scheduledPage.title': 'スケジュールタスク', + 'scheduledPage.subtitle': 'タスクをスケジュール実行したり、必要なときに実行したりします。既存のセッションで {code} を入力すると作成できます。', + 'scheduledPage.desktopNotice': 'スケジュールタスクは、デスクトップアプリが開いている間のみ実行されます。タスクが時間どおりに実行されるよう、アプリを起動したままにしてください。', + 'scheduledPage.oldSubtitle': '自動化された運用ルーチンとバックグラウンドメンテナンスを管理します。', + 'scheduledPage.executionMode': '実行モード', + 'scheduledPage.localMode': 'ローカルモード', + 'scheduledPage.remoteMode': 'リモートモード', + 'scheduledPage.nextRun': '次回実行', + 'scheduledPage.systemHealth': 'システムの状態', + 'scheduledPage.activeSession': 'アクティブなセッション', + 'scheduledPage.colTaskName': 'タスク名', + 'scheduledPage.colFrequency': '頻度', + 'scheduledPage.colLastResult': '前回の結果', + 'scheduledPage.colNextExecution': '次回の実行', + 'scheduledPage.colActions': '操作', + 'scheduledPage.endOfList': 'スケジュール一覧の末尾', + 'scheduledPage.pausedTasks': '他の 9 件のタスクは現在、メンテナンスのために一時停止または無効になっています。', + 'scheduledPage.recentLogs': '最近の出力ログ', + 'scheduledPage.viewArtifacts': '成果物全体を表示', + 'scheduledPage.resourceAllocation': 'リソース割り当て', + 'scheduledPage.cpuCapacity': 'CPU 容量', + 'scheduledPage.memoryLoad': 'メモリ負荷', + 'scheduledPage.connectedLocal': 'ローカルノードに接続済み', + 'scheduledPage.thisMonth': '今月 {count} 件', + + // ─── Update Checker ────────────────────────────────────── + 'update.available': 'v{version} が利用可能', + 'update.availableLabel': '利用可能', + 'update.checking': '更新を確認中...', + 'update.checkNow': '今すぐ確認', + 'update.checkedAt': '最終確認 {time}', + 'update.currentVersionUnknown': '不明', + 'update.newVersion': '新しいバージョン v{version} が利用可能', + 'update.downloading': 'ダウンロード中...', + 'update.downloaded': '更新をダウンロードしました。使用する準備ができたら再起動してください。', + 'update.idle': '更新を確認して、インストール済みのバージョンを最新の GitHub Release と比較します。', + 'update.installAndRestart': 'インストールして再起動', + 'update.installing': '更新をインストール中...', + 'update.now': '今すぐ更新', + 'update.later': '後で', + 'update.progress': '更新をダウンロード中... {progress}%', + 'update.progressBytes': '更新をダウンロード中... {downloaded} ダウンロード済み', + 'update.proxyAdvanced': '高度な更新プロキシ', + 'update.proxyModeManual': '手動プロキシ', + 'update.proxyModeManualDescription': '指定したローカルの HTTP プロキシアドレスを使用します。', + 'update.proxyModeSystem': 'システムプロキシ', + 'update.proxyModeSystemDescription': 'OS の HTTP/HTTPS プロキシを自動的に使用します。', + 'update.proxySave': '保存', + 'update.proxyScopeHint': 'これはアプリの更新確認とダウンロードにのみ影響します。', + 'update.proxyUrl': 'プロキシ URL', + 'update.proxyUrlHint': 'HTTP および HTTPS プロキシ URL に対応しています。例: http://127.0.0.1:7890。', + 'update.proxyUrlInvalid': 'HTTP または HTTPS のプロキシ URL を入力してください。', + 'update.proxyUrlRequired': 'プロキシ URL を入力してください。', + 'update.releaseNotes': 'リリースノート', + 'update.readyBody': 'v{version} をダウンロードしました。使用する準備ができたら再起動してください。', + 'update.readyTitle': '更新の準備完了', + 'update.restarting': '更新を完了するために再起動中...', + 'update.upToDate': 'v{version} は最新です。', + 'update.failed': '更新に失敗しました: {error}', + + // ─── Active Session ────────────────────────────────────── + 'session.untitled': '無題のセッション', + 'session.active': 'セッションがアクティブ', + 'session.lastUpdated': '最終更新 {time}', + 'session.messages': '{count} 件のメッセージ', + 'session.historyLoadFailed': 'セッション履歴の読み込みに失敗しました。', + 'session.workspaceUnavailable': 'ワークスペースが利用できません: {dir}', + 'session.timeJustNow': 'たった今', + 'session.timeMinutes': '{n} 分前', + 'session.timeHours': '{n} 時間前', + 'session.timeDays': '{n} 日前', + + // ─── App Shell ────────────────────────────────────── + 'app.serverFailed': 'ローカルサーバーの起動に失敗しました', + 'app.serverFailedHint': '問題を報告する際は、この診断パネルのスクリーンショットを添付してください。', + 'app.startupError': '起動エラー', + 'app.serverLogs': 'サーバーログ', + 'app.copyDiagnostics': '診断情報をコピー', + 'app.copiedDiagnostics': 'コピーしました', + 'app.launching': 'ローカルワークスペースを起動中...', + + // ─── Error Codes ────────────────────────────────────── + 'error.CLI_NOT_RUNNING': 'CLI プロセスが実行されていません。セッションが終了したか、プロセスがクラッシュした可能性があります。', + 'error.CLI_START_FAILED': 'CLI プロセスの起動に失敗しました。', + 'error.CLI_AUTH_REQUIRED': '認証が必要です。ログインしてください。', + 'error.CLI_SESSION_CONFLICT': 'セッションは既に別のプロセスで使用されています。', + 'error.CLI_SPAWN_FAILED': 'CLI サブプロセスの生成に失敗しました。', + 'error.CLI_ERROR': '処理中にエラーが発生しました。', + 'error.WORKDIR_INVALID': '作業ディレクトリが無効か、存在しません。', + 'error.PARSE_ERROR': 'メッセージの形式が無効です。', + 'error.UNKNOWN_TYPE': '不明なメッセージタイプです。', + 'error.BAD_REQUEST': '不正なリクエストです。', + 'error.NOT_FOUND': 'リソースが見つかりません。', + 'error.INTERNAL_ERROR': 'サーバー内部エラーです。', + + // ─── Business Errors ────────────────────────────────────── + 'businessError.pdf_too_large': 'PDF が選択したモデルには大きすぎます。テキストに変換するか、より小さい PDF を使用してください。', + 'businessError.pdf_password_protected': 'PDF はパスワードで保護されています。再送信する前にロックを解除するか、変換してください。', + 'businessError.pdf_invalid': 'PDF ファイルが無効です。テキストに変換するか、別のファイルを送信してください。', + 'businessError.image_too_large': '画像が選択したモデルには大きすぎます。サイズを変更するか、より小さい画像を送信してください。', + 'businessError.image_unsupported': 'このモデルは画像をサポートしていません。テキストで続行するか、ビジョン対応モデルに切り替えて画像を再送信してください。', + 'businessError.request_too_large': 'リクエストが選択したモデルには大きすぎます。大きなファイルを削除するか、より短いメッセージで再試行してください。', + 'businessError.prompt_too_long': 'プロンプトが選択したモデルには長すぎます。会話を圧縮するか、コンテキストを減らして再試行してください。', + 'businessError.auto_mode_unavailable': '自動モードは現在のプランでは利用できません。', + + // ─── Server Status Verbs ────────────────────────────────────── + 'serverVerb.Thinking': '思考中', + 'serverVerb.Compacting conversation': 'コンテキストを圧縮中', + 'serverVerb.Running': '実行中', + 'serverVerb.Working': '作業中', + 'serverVerb.Creating worktree': 'worktree を作成中', + 'serverVerb.Task started': 'タスクを開始しました', + 'serverVerb.Task in progress': 'タスクを実行中', + 'chat.retry.title': 'リクエストに失敗、再試行中', + 'chat.retry.attempt': '再試行 {attempt}/{max}', + 'chat.retry.httpStatus': 'HTTP {status}', + 'chat.retry.networkError': 'ネットワークエラー', + 'chat.retry.waiting': '{seconds} 秒待機中', + + // ─── Tabs ────────────────────────────────────── + 'tabs.close': '閉じる', + 'tabs.closeOthers': '他を閉じる', + 'tabs.closeLeft': '左側を閉じる', + 'tabs.closeRight': '右側を閉じる', + 'tabs.closeAll': 'すべて閉じる', + 'tabs.closeConfirmTitle': 'セッション実行中', + 'tabs.closeConfirmMessage': 'このセッションはまだ実行中です。どうしますか?', + 'tabs.closeConfirmKeep': '実行を継続', + // ─── Slash Command Descriptions ────────────────────────────────────── + 'slashCmd.agent.description': '選択した Agent でプロンプトを実行', + 'slashCmd.mcp.description': '現在のチャットコンテキストで利用可能な MCP ツールを開く', + 'slashCmd.skills.description': '現在のチャットコンテキストでユーザーが呼び出せるスキルを閲覧', + 'slashCmd.help.description': '利用可能なデスクトップおよびエージェントのコマンドを表示', + 'slashCmd.status.description': 'セッションのステータス、使用量、コンテキストを表示', + 'slashCmd.cost.description': 'セッションの使用量とコストを表示', + 'slashCmd.context.description': '現在のコンテキスト使用量を表示', + 'slashCmd.plugin.description': '設定でデスクトップのプラグイン操作を開く', + 'slashCmd.memory.description': '設定でプロジェクトのメモリファイルを開く', + 'slashCmd.doctor.description': '診断で Doctor を開く', + 'slashCmd.compact.description': '会話のコンテキストを圧縮', + 'slashCmd.clear.description': '会話履歴をクリア', + 'slashCmd.goal.description': '完了ゴールを設定', + 'slashCmd.review.description': 'コードの変更をレビュー', + 'slashCmd.commit.description': 'git コミットを作成', + 'slashCmd.pr.description': 'プルリクエストを作成', + 'slashCmd.init.description': 'プロジェクトの CLAUDE.md を初期化', + 'slashCmd.bug.description': 'バグを報告', + 'slashCmd.config.description': '設定を開く', + 'slashCmd.login.description': 'Anthropic アカウントを切り替え', + 'slashCmd.logout.description': '現在のアカウントからサインアウト', + 'slashCmd.model.description': 'AI モデルを切り替え', + 'slashCmd.permissions.description': 'ツールの権限を表示または管理', + 'slashCmd.terminal-setup.description': 'ターミナル統合をセットアップ', + 'slashCmd.vim.description': 'Vim 編集モードを切り替え', + + 'tabs.closeConfirmStop': '停止して閉じる', + 'tabs.closeAllConfirmTitle': 'セッション実行中', + 'tabs.closeAllConfirmMessage': '{count} 件のセッションがまだ実行中です。これらのタブを閉じる前に停止しますか?', + 'tabs.closeAllConfirmStop': 'すべて停止して閉じる', + 'tabs.sessionRunning': 'セッション実行中', + 'tabs.openTerminal': 'ターミナルを開く', + 'tabs.showWorkspace': 'ワークスペースを表示', + 'tabs.hideWorkspace': 'ワークスペースを非表示', + 'tabs.showBrowser': 'ブラウザを表示', + 'tabs.hideBrowser': 'ブラウザを非表示', +} diff --git a/desktop/src/i18n/locales/kr.ts b/desktop/src/i18n/locales/kr.ts new file mode 100644 index 000000000..7160e04c7 --- /dev/null +++ b/desktop/src/i18n/locales/kr.ts @@ -0,0 +1,1702 @@ +import type { TranslationKey } from './en' + +export const kr: Record = { + // ─── Common ────────────────────────────────────── + 'common.cancel': '취소', + 'common.save': '저장', + 'common.delete': '삭제', + 'common.add': '추가', + 'common.run': '실행', + 'common.send': '전송', + 'common.stop': '중지', + 'common.rename': '이름 바꾸기', + 'common.retry': '다시 시도', + 'common.loading': '불러오는 중...', + 'common.select': '선택', + 'common.enable': '사용', + 'common.disable': '사용 안 함', + 'common.active': '활성', + 'common.error': '오류', + 'common.copyFailed': '복사하지 못했습니다.', + + // ─── Sidebar ────────────────────────────────────── + 'sidebar.newSession': '새 세션', + 'sidebar.scheduled': '예약 작업', + 'sidebar.terminal': '터미널', + 'sidebar.settings': '설정', + 'sidebar.searchPlaceholder': '세션 검색...', + 'sidebar.noSessions': '아직 세션이 없습니다', + 'sidebar.noMatching': '일치하는 세션이 없습니다', + 'sidebar.sessionListFailed': '세션 목록을 불러오지 못했습니다', + 'sidebar.refreshSessions': '세션 새로 고침', + 'sidebar.projects': '프로젝트', + 'sidebar.projectMenu': '프로젝트 메뉴', + 'sidebar.newProject': '새 프로젝트', + 'sidebar.archiveAllChats': '모든 채팅 보관', + 'sidebar.organizeSidebar': '사이드바 정리', + 'sidebar.sortCondition': '정렬 조건', + 'sidebar.organizeByProject': '프로젝트별', + 'sidebar.organizeByRecentProject': '최근 프로젝트', + 'sidebar.organizeByTime': '시간순', + 'sidebar.sortByCreatedAt': '생성 시간', + 'sidebar.sortByUpdatedAt': '업데이트 시간', + 'sidebar.newBlankProject': '새 빈 프로젝트', + 'sidebar.useExistingFolder': '기존 폴더 사용', + 'sidebar.chooseProjectFolderUnavailable': '폴더 선택은 데스크톱 앱에서만 사용할 수 있습니다.', + 'sidebar.projectActions': '{project}의 프로젝트 작업', + 'sidebar.pinProject': '프로젝트 고정', + 'sidebar.unpinProject': '고정 해제', + 'sidebar.openInFinder': 'Finder에서 열기', + 'sidebar.openInFinderFailed': 'Finder에서 프로젝트를 열 수 없습니다.', + 'sidebar.openInFinderUnavailable': '사용할 수 있는 파일 관리자가 없습니다.', + 'sidebar.hideProjectFromSidebar': '사이드바에서 숨기기', + 'sidebar.restoreProjectToSidebar': '사이드바로 복원', + 'sidebar.restoreHiddenProjects': '숨긴 프로젝트 복원 ({count})', + 'sidebar.projectHidden': '{project}을(를) 사이드바에서 숨겼습니다. 기존 세션은 삭제되지 않았습니다.', + 'sidebar.newSessionInProject': '{project}에서 새 세션', + 'sidebar.showMoreSessions': '펼쳐서 표시', + 'sidebar.showFewerSessions': '접어서 표시', + 'sidebar.expandProject': '{project} 펼치기', + 'sidebar.collapseProject': '{project} 접기', + 'sidebar.worktree': 'worktree', + 'sidebar.sessionRunning': '세션 실행 중', + 'sidebar.missingDir': '디렉터리 없음', + 'sidebar.confirmDelete': '이 세션을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.', + 'sidebar.batchManage': '일괄 관리', + 'sidebar.batchSelectedCount': '{count}개 선택됨', + 'sidebar.batchSelectAll': '모두 선택', + 'sidebar.batchDeselectAll': '모두 선택 해제', + 'sidebar.batchSelectGroup': '{group} 선택', + 'sidebar.batchDeleteSelected': '선택 항목 삭제 ({count})', + 'sidebar.batchDeleteConfirm': '{count}개의 세션을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.', + 'sidebar.batchDeleteConfirmBody': '다음 세션이 삭제됩니다:', + 'sidebar.batchDeleteMore': '...외 {count}개', + 'sidebar.batchExit': '일괄 모드 취소', + 'sidebar.batchDeleteSucceeded': '{count}개의 세션을 삭제했습니다.', + 'sidebar.batchDeleteFailed': '{count}개의 세션을 삭제하지 못했습니다.', + 'sidebar.allProjects': '모든 프로젝트', + 'sidebar.other': '기타', + 'sidebar.timeGroup.today': '오늘', + 'sidebar.timeGroup.yesterday': '어제', + 'sidebar.timeGroup.last7days': '지난 7일', + 'sidebar.timeGroup.last30days': '지난 30일', + 'sidebar.timeGroup.older': '그 이전', + 'sidebar.collapse': '사이드바 접기', + 'sidebar.expand': '사이드바 펼치기', + + // ─── Title Bar ────────────────────────────────────── + 'titlebar.code': '코드', + 'titlebar.terminal': '터미널', + 'titlebar.history': '기록', + + // ─── Open Project ────────────────────────────────────── + 'openProject.openProject': '프로젝트 열기', + 'openProject.openIn': '{target}에서 열기', + 'openProject.openFailed': '프로젝트를 열 수 없습니다', + + // ─── Open With ───────────────────────────────────── + 'openWith.title': '열기 방식', + 'openWith.inAppBrowser': '앱 내 브라우저', + 'openWith.systemBrowser': '시스템 브라우저', + 'openWith.workspacePreview': '작업 공간 미리 보기', + 'openWith.openInTarget': '{target}에서 열기', + 'openWith.revealInTarget': '{target}에서 표시', + 'openWith.fileType.document': '문서', + 'openWith.fileType.web': '웹', + 'openWith.fileType.image': '이미지', + 'openWith.fileType.code': '코드', + 'openWith.fileType.file': '파일', + + // ─── Assistant Output Targets ────────────────────── + 'assistantOutputs.kind.markdown': 'Markdown', + 'assistantOutputs.kind.html': 'HTML', + 'assistantOutputs.kind.image': '이미지', + 'assistantOutputs.kind.localhost': 'Localhost', + 'assistantOutputs.moreOutputs': '+{count}개', + 'assistantOutputs.open': '열기', + + // ─── Workspace Panel ─────────────────────────────── + 'workspace.changedFiles': '변경된 파일', + 'workspace.allFiles': '모든 파일', + 'workspace.viewTabs': '작업 공간 보기', + 'workspace.previewTabs': '미리 보기 탭', + 'workspace.filterPlaceholder': '파일 필터링...', + 'workspace.clearFilter': '파일 필터 지우기', + 'workspace.refresh': '작업 공간 새로 고침', + 'workspace.closePanel': '작업 공간 패널 닫기', + 'workspace.resizePanel': '작업 공간 패널 크기 조정', + 'workbench.modeSwitch': '워크벤치 모드', + 'workbench.modeWorkspace': '파일', + 'workbench.modeBrowser': '브라우저', + 'workbench.close': '닫기', + 'workspace.closeTab': '탭 닫기', + 'workspace.preview': '미리 보기', + 'workspace.previewEmpty': '미리 볼 파일을 선택하세요.', + 'workspace.notGitRepo': 'Git 저장소가 아닙니다.', + 'workspace.missingWorkdir': '작업 디렉터리가 없습니다.', + 'workspace.loadError': '작업 공간 데이터를 불러오지 못했습니다.', + 'workspace.noChanges': '변경 사항 없음', + 'workspace.noFiles': '파일 없음', + 'workspace.noMatchingFiles': '일치하는 파일 없음', + 'workspace.previewKind.diff': '변경 내용', + 'workspace.previewKind.file': '파일', + 'workspace.previewState.loading': '미리 보기 불러오는 중...', + 'workspace.previewState.binary': '바이너리 파일은 미리 볼 수 없습니다.', + 'workspace.previewState.tooLarge': '파일이 너무 커서 미리 볼 수 없습니다.', + 'workspace.previewState.missing': '파일을 찾을 수 없습니다.', + 'workspace.imagePreviewUnavailable': '이미지를 미리 볼 수 없습니다.', + 'workspace.previewLineLimit': '불러온 {total}줄 중 처음 {count}줄을 표시합니다.', + 'workspace.previewAllLines': '불러온 {total}줄을 모두 표시합니다.', + 'workspace.showAllLoadedLines': '불러온 줄 모두 표시', + 'workspace.collapsePreview': '미리 보기 접기', + 'workspace.addToChat': '채팅에 추가', + 'workspace.addSelectionToChat': '채팅에 추가', + 'workspace.copyPath': '경로 복사', + 'workspace.copyAbsolutePath': '절대 경로 복사', + 'workspace.pathCopied': '경로를 복사했습니다.', + 'workspace.localComment': '로컬 댓글', + 'workspace.commentLine': '{line}번째 줄에 댓글', + 'workspace.commentLineTarget': '{line}번째 줄', + 'workspace.commentPlaceholder': '여기서 무엇을 변경해야 하는지 설명하세요...', + 'workspace.addCommentToChat': '댓글 추가', + + // ─── Status Bar ────────────────────────────────────── + 'status.connected': '연결됨', + 'status.connecting': '연결 중...', + 'status.reconnecting': '다시 연결 중...', + 'status.disconnected': '연결 끊김', + + // ─── Settings ────────────────────────────────────── + 'settings.title': '설정', + 'settings.tab.providers': '공급자', + 'settings.tab.permissions': '권한', + 'settings.tab.activity': '토큰 사용량', + 'settings.tab.general': '일반', + 'settings.tab.h5Access': 'H5 액세스', + 'settings.tab.terminal': '터미널', + 'settings.tab.skills': '스킬', + 'settings.tab.mcp': 'MCP', + 'settings.tab.plugins': '플러그인', + 'settings.tab.diagnostics': '진단', + + // Settings > Usage + 'settings.activity.title': '토큰 사용량', + 'settings.activity.profileTitle': '프로필', + 'settings.activity.profilePrivacy': '로컬 전용', + 'settings.activity.defaultHandle': 'github.com/NanmiCoder/cc-haha', + 'settings.activity.editProfile': '프로필 편집', + 'settings.activity.displayName': '표시 이름', + 'settings.activity.subtitle': '둘째 줄', + 'settings.activity.displayNameHelper': '표시 이름과 둘째 줄을 편집합니다. 둘째 줄의 URL은 링크로 열립니다.', + 'settings.activity.avatar': '아바타', + 'settings.activity.avatarHelper': 'PNG, JPEG 또는 WebP, 최대 2MB.', + 'settings.activity.changeAvatar': '아바타 변경', + 'settings.activity.removeAvatar': '아바타 제거', + 'settings.activity.saveProfile': '저장', + 'settings.activity.cancelEdit': '취소', + 'settings.activity.profileSaved': '로컬에 저장됨', + 'settings.activity.profileSaveFailed': '프로필을 저장할 수 없습니다', + 'settings.activity.subtitleLoading': '로컬 Claude Code CLI 세션 기록을 기반으로 합니다', + 'settings.activity.totalTokens': '총 토큰 수', + 'settings.activity.peakTokens': '최대 토큰 수', + 'settings.activity.longestTask': '최장 작업', + 'settings.activity.currentStreak': '현재 연속 기록', + 'settings.activity.longestStreak': '최장 연속 기록', + 'settings.activity.noDuration': '0분', + 'settings.activity.tokenActivity': '토큰 활동', + 'settings.activity.mode.daily': '일별', + 'settings.activity.mode.weekly': '주별', + 'settings.activity.mode.cumulative': '누적', + 'settings.activity.modeHelp.daily': '일별: 각 칸은 그날의 토큰 사용량입니다.', + 'settings.activity.modeHelp.weekly': '주별: 각 열은 한 주의 총 토큰 사용량입니다.', + 'settings.activity.modeHelp.cumulative': '누적: 각 열은 해당 주까지의 총 토큰 수입니다.', + 'settings.activity.emptyTitle': '아직 로컬 사용 기록이 없습니다', + 'settings.activity.emptyBody': 'CLI 또는 데스크톱 세션을 시작하면 완료된 모델 응답이 여기에 표시됩니다.', + 'settings.activity.metric.yesterday': '어제', + 'settings.activity.metric.today': '오늘', + 'settings.activity.metric.last4': '지난 4일', + 'settings.activity.metric.last30': '30일', + 'settings.activity.metric.streak': '연속 기록', + 'settings.activity.metric.bestStreak': '최고 {days}일', + 'settings.activity.heatmapLabel': '일별 토큰 사용량', + 'settings.activity.weekRange': '{start} - {end}', + 'settings.activity.cumulativeThrough': '{date}까지', + 'settings.activity.tokenValue': '{tokens} 토큰', + 'settings.activity.count.sessionOne': '{count} 세션', + 'settings.activity.count.sessionOther': '{count} 세션', + 'settings.activity.count.dayOne': '{count}일', + 'settings.activity.count.dayOther': '{count}일', + 'settings.activity.weekday.mon': '월', + 'settings.activity.weekday.wed': '수', + 'settings.activity.weekday.fri': '금', + 'settings.activity.selectedDay': '선택한 날짜', + 'settings.activity.sessions': '세션', + 'settings.activity.tokens': '토큰', + 'settings.activity.messages': '메시지', + 'settings.activity.tools': '도구', + 'settings.activity.less': '적음', + 'settings.activity.more': '많음', + + // Settings > Terminal + 'settings.terminal.title': '터미널', + 'settings.terminal.description': '플러그인, 스킬, MCP 설정을 위해 호스트 컴퓨터의 명령을 실행합니다. 데스크톱 앱에는 claude-haha가 포함되어 있습니다. 문서의 claude 를 claude-haha 로 바꾸세요. 예: claude-haha plugin install ... 또는 claude-haha mcp add ...', + 'settings.terminal.infoLabel': '터미널 설정 도움말', + 'settings.terminal.clear': '지우기', + 'settings.terminal.restart': '다시 시작', + 'settings.terminal.windowTitle': '호스트 셸', + 'settings.terminal.unavailableTitle': '데스크톱 런타임이 필요합니다', + 'settings.terminal.unavailableBody': '대화형 터미널을 시작하려면 이 페이지를 패키지된 데스크톱 앱에서 여세요.', + 'settings.terminal.preferencesTitle': '시작 셸', + 'settings.terminal.preferencesBody': '새 터미널 세션과 다시 시작 후에 사용됩니다.', + 'settings.terminal.startupShell': '시작 셸', + 'settings.terminal.customPath': '사용자 지정 셸 경로', + 'settings.terminal.customPathPlaceholder': 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', + 'settings.terminal.customPathRequired': '저장하기 전에 셸 경로를 입력하세요.', + 'settings.terminal.customPathAbsolute': '사용자 지정 셸 경로는 Windows 절대 경로여야 합니다.', + 'settings.terminal.saveShell': '셸 저장', + 'settings.terminal.saveShellSuccess': '저장했습니다. 적용하려면 다시 시작하거나 새 터미널을 여세요.', + 'settings.terminal.shell.system': '시스템 기본값', + 'settings.terminal.shell.systemDesc': '현재 COMSPEC 기반 동작을 유지합니다.', + 'settings.terminal.shell.pwsh': 'PowerShell 7 (pwsh)', + 'settings.terminal.shell.pwshDesc': '설치되어 있으면 pwsh.exe를 사용합니다.', + 'settings.terminal.shell.powershell': 'Windows PowerShell', + 'settings.terminal.shell.powershellDesc': '기본 제공 powershell.exe를 사용합니다.', + 'settings.terminal.shell.cmd': '명령 프롬프트', + 'settings.terminal.shell.cmdDesc': 'cmd.exe를 명시적으로 사용합니다.', + 'settings.terminal.shell.custom': '사용자 지정 실행 파일', + 'settings.terminal.shell.customDesc': '절대 경로의 셸 실행 파일을 실행합니다.', + 'settings.terminal.status.idle': '유휴', + 'settings.terminal.status.starting': '시작 중', + 'settings.terminal.status.running': '실행 중', + 'settings.terminal.status.exited': '종료됨', + 'settings.terminal.status.error': '오류', + 'settings.terminal.status.unavailable': '사용 불가', + 'settings.terminal.bashPathLabel': 'Bash 경로', + 'settings.terminal.bashPathDescription': 'Windows에서는 터미널 셸 기본값이 CMD입니다. 도구 호출이 Unix 명령(grep, sed 등)을 사용하는 경우 여기에 Bash 실행 파일(예: Git Bash) 경로를 설정하세요.', + 'settings.terminal.bashPathSave': '저장', + 'settings.terminal.bashPathReset': '기본값으로 재설정', + 'settings.terminal.bashPathSaved': '저장됨', + 'settings.terminal.bashPathInvalid': '경로가 존재하지 않습니다. 유효한 Bash 실행 파일을 선택하세요.', + 'terminal.newTab': '새 터미널', + 'terminal.openInTab': '탭에서 열기', + 'terminal.closePanel': '터미널 패널 닫기', + 'terminal.resizePanel': '터미널 패널 크기 조정', + + // Settings > Diagnostics + 'settings.diagnostics.title': '진단', + 'settings.diagnostics.description': '시작, 공급자, 세션 실패를 디버깅하기 위한 서버 및 CLI 런타임 로그입니다.', + 'settings.diagnostics.refresh': '새로 고침', + 'settings.diagnostics.totalSize': '로그 크기', + 'settings.diagnostics.events': '이벤트', + 'settings.diagnostics.recentErrors': '24시간 경고', + 'settings.diagnostics.retention': '보존 기간', + 'settings.diagnostics.retentionValue': '{days}일 / {size}', + 'settings.diagnostics.logDirectory': '로그 디렉터리', + 'settings.diagnostics.openDirectory': '열기', + 'settings.diagnostics.exportBundle': '번들 내보내기', + 'settings.diagnostics.copySummary': '오류 요약 복사', + 'settings.diagnostics.clearLogs': '로그 지우기', + 'settings.diagnostics.recentEvents': '최근 이벤트', + 'settings.diagnostics.privacyNote': '내보낸 진단 정보는 정제되며 채팅 내용, 파일 내용, 전체 환경 변수, API 키는 포함하지 않습니다.', + 'settings.diagnostics.noEvents': '아직 진단 이벤트가 없습니다.', + 'settings.diagnostics.noRecentErrors': '최근 경고나 오류가 없습니다.', + 'settings.diagnostics.loadFailed': '진단 정보를 불러오지 못했습니다.', + 'settings.diagnostics.openFailed': '진단 디렉터리를 열지 못했습니다.', + 'settings.diagnostics.exportFailed': '진단 번들을 내보내지 못했습니다.', + 'settings.diagnostics.exported': '{file}을(를) 내보냈습니다', + 'settings.diagnostics.summaryCopied': '오류 요약을 복사했습니다.', + 'settings.diagnostics.copyFailed': '오류 요약을 복사하지 못했습니다.', + 'settings.diagnostics.confirmClear': '모든 로컬 진단 로그와 내보낸 번들을 지우시겠습니까?', + 'settings.diagnostics.cleared': '진단 정보를 지웠습니다.', + 'settings.diagnostics.clearFailed': '진단 정보를 지우지 못했습니다.', + 'settings.diagnostics.eventDetails': '세부 정보', + 'settings.diagnostics.doctorTitle': 'Doctor', + 'settings.diagnostics.doctorDescription': '시작 및 UI 상태 문제를 위한 안전한 데스크톱 복구입니다.', + 'settings.diagnostics.doctorProtectedData': '채팅 기록, 모델 구성, 스킬, MCP, IM, OAuth는 절대 건드리지 않습니다.', + 'settings.diagnostics.doctorSafeKeys': '다음만 지웁니다: cc-haha-open-tabs, cc-haha-session-runtime, cc-haha-theme, cc-haha-locale, cc-haha.persistence.schemaVersion.', + 'settings.diagnostics.runDoctor': 'Doctor 실행', + 'settings.diagnostics.doctorCompleted': 'Doctor가 완료되었습니다.', + 'settings.diagnostics.doctorPartial': 'Doctor가 완료되었지만 {count}건의 로컬 정리 문제가 있습니다.', + 'settings.diagnostics.doctorFailed': 'Doctor가 실패했습니다.', + 'settings.diagnostics.doctorResultLocal': '{count}개의 안전한 UI 키를 지웠습니다.', + 'settings.diagnostics.doctorResultFailedKeys': '{count}개의 키를 제거하지 못했습니다.', + 'settings.diagnostics.doctorServerRan': '서버 측 Doctor 복구도 실행되었습니다.', + 'settings.diagnostics.doctorServerUnavailable': '서버 측 Doctor를 사용할 수 없어 로컬 복구만 실행되었습니다.', + 'errorBoundary.title': '문제가 발생했습니다.', + 'errorBoundary.description': '오류가 진단에 기록되었습니다.', + + // Settings > Claude Official Login + 'settings.claudeOfficialLogin.intro': '공식 Claude 모델을 사용하려면 Claude.ai 계정에 로그인해야 합니다. 아래 버튼을 클릭하면 브라우저에서 공식 Claude 로그인 페이지가 열립니다. 승인 후 이곳으로 돌아옵니다.', + 'settings.claudeOfficialLogin.loginButton': 'Claude에 로그인', + 'settings.claudeOfficialLogin.loginStarting': '여는 중…', + 'settings.claudeOfficialLogin.logoutButton': '로그아웃', + 'settings.claudeOfficialLogin.logoutProcessing': '처리 중…', + 'settings.claudeOfficialLogin.loggedInPrefix': '로그인됨 (Claude', + 'settings.claudeOfficialLogin.subTypeUnknown': '알 수 없음', + 'settings.claudeOfficialLogin.errorPrefix': '오류: ', + 'settings.claudeOfficialLogin.openBrowserFailed': '브라우저를 열지 못했습니다. 승인 URL에 수동으로 접속하세요.', + + // Settings > ChatGPT Official Login + 'settings.chatgptOfficialLogin.intro': '데스크톱 세션에서 GPT 모델을 사용하려면 ChatGPT로 로그인하세요.', + 'settings.chatgptOfficialLogin.loginButton': 'ChatGPT로 로그인', + 'settings.chatgptOfficialLogin.loginStarting': '로그인 시작 중...', + 'settings.chatgptOfficialLogin.logoutButton': '로그아웃', + 'settings.chatgptOfficialLogin.logoutProcessing': '로그아웃 중...', + 'settings.chatgptOfficialLogin.loggedInPrefix': '로그인 계정:', + 'settings.chatgptOfficialLogin.accountUnknown': 'ChatGPT 계정', + 'settings.chatgptOfficialLogin.openBrowserFailed': '브라우저를 열 수 없습니다. 승인 링크를 복사하여 수동으로 여세요.', + 'settings.chatgptOfficialLogin.copyAuthorizeUrl': '승인 링크 복사', + 'settings.chatgptOfficialLogin.copyLinkFailed': '승인 링크를 복사할 수 없습니다.', + 'settings.chatgptOfficialLogin.errorPrefix': 'ChatGPT OAuth 오류: ', + + // Settings > Providers + 'settings.providers.title': '공급자', + 'settings.providers.description': '모델 액세스를 위한 API 공급자를 관리합니다.', + 'settings.providers.addProvider': '공급자 추가', + 'settings.providers.officialName': 'Claude 공식', + 'settings.providers.officialDesc': 'Anthropic 네이티브 — API 키 불필요', + 'settings.providers.openaiOfficialName': 'ChatGPT 공식', + 'settings.providers.openaiOfficialDesc': 'ChatGPT 계정을 통한 OpenAI OAuth — API 키 불필요', + 'settings.providers.connected': '연결됨 ({latency}ms)', + 'settings.providers.failed': '실패: {error}', + 'settings.providers.connectivityOk': '① 연결 ({latency}ms)', + 'settings.providers.connectivityFailed': '① 연결 실패: {error}', + 'settings.providers.proxyOk': '② 프록시 파이프라인 ({latency}ms)', + 'settings.providers.proxyFailed': '② 프록시 실패: {error}', + 'settings.providers.confirmDelete': '공급자 "{name}"을(를) 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.', + 'settings.providers.activate': '활성화', + 'settings.providers.default': '기본값', + 'settings.providers.setDefault': '기본값으로 설정', + 'settings.providers.test': '테스트', + 'settings.providers.edit': '편집', + 'settings.providers.requestFailed': '요청에 실패했습니다', + 'settings.providers.addTitle': '공급자 추가', + 'settings.providers.editTitle': '공급자 편집', + 'settings.providers.preset': '사전 설정', + 'settings.providers.name': '이름', + 'settings.providers.namePlaceholder': '공급자 이름', + 'settings.providers.notes': '메모', + 'settings.providers.notesPlaceholder': '선택 사항 메모...', + 'settings.providers.baseUrl': '기본 URL', + 'settings.providers.baseUrlPlaceholder': 'https://api.example.com/anthropic', + 'settings.providers.apiKey': 'API 키', + 'settings.providers.apiKeyKeep': 'API 키 (비워 두면 현재 값 유지)', + 'settings.providers.getApiKey': 'API 키 가져오기', + 'settings.providers.modelMapping': '모델 매핑', + 'settings.providers.mainModel': '메인 모델', + 'settings.providers.haikuModel': 'Haiku 모델', + 'settings.providers.sonnetModel': 'Sonnet 모델', + 'settings.providers.opusModel': 'Opus 모델', + 'settings.providers.sameAsMain': '메인과 동일', + 'settings.providers.contextSettingsTitle': '컨텍스트 및 자동 압축', + 'settings.providers.contextSettingsDesc': '사전 설정 한도가 자동으로 적용됩니다. 공급자가 한도를 변경하거나 사용자 지정 모델 ID를 사용할 때만 편집하세요.', + 'settings.providers.contextSettingsEdit': '고급', + 'settings.providers.contextSettingsHide': '숨기기', + 'settings.providers.contextSummaryAuto': '구성된 모델을 자동 감지합니다. 알 수 없는 모델은 기본 제공 폴백을 사용합니다', + 'settings.providers.contextFallbackAuto': '알 수 없는 모델: 자동', + 'settings.providers.contextFallbackSummary': '알 수 없는 모델: {tokens}', + 'settings.providers.modelContextWindows': '모델 컨텍스트 창', + 'settings.providers.mainContextWindow': '메인 모델 컨텍스트', + 'settings.providers.haikuContextWindow': 'Haiku 모델 컨텍스트', + 'settings.providers.sonnetContextWindow': 'Sonnet 모델 컨텍스트', + 'settings.providers.opusContextWindow': 'Opus 모델 컨텍스트', + 'settings.providers.contextWindowPlaceholder': '예: 200000', + 'settings.providers.modelContextWindowsDesc': '각 모델의 실제 컨텍스트 창을 사용합니다. 사전 설정은 자동으로 입력됩니다. 비워 두면 기본 제공 감지 또는 200K로 폴백합니다.', + 'settings.providers.modelContextWindowNumberError': '정수를 입력하세요.', + 'settings.providers.modelContextWindowRangeError': '16000에서 10000000 사이여야 합니다.', + 'settings.providers.autoCompactWindow': '알 수 없는 모델 폴백 창', + 'settings.providers.autoCompactWindowPlaceholder': '선택 사항, 예: 200000', + 'settings.providers.autoCompactWindowDesc': '식별할 수 없는 모델에만 사용됩니다. 구성된 모델 창이 우선합니다.', + 'settings.providers.autoCompactWindowNumberError': '정수를 입력하세요.', + 'settings.providers.autoCompactWindowRangeError': '16000에서 10000000 사이여야 합니다.', + 'settings.providers.testConnection': '연결 테스트', + 'settings.providers.settingsJson': '설정 JSON', + 'settings.providers.settingsJsonDesc': '~/.claude/cc-haha/settings.json — 직접 편집할 수 있습니다. 저장 시 기록됩니다.', + 'settings.providers.jsonError': 'JSON 구문 오류: {error}', + 'settings.providers.apiFormat': 'API 형식', + 'settings.providers.apiFormatAnthropic': 'Anthropic Messages (네이티브)', + 'settings.providers.apiFormatOpenaiChat': 'OpenAI Chat Completions (프록시)', + 'settings.providers.apiFormatOpenaiResponses': 'OpenAI Responses API (프록시)', + 'settings.providers.proxyHint': '요청은 로컬 프록시를 통해 변환됩니다', + 'settings.providers.authStrategy': '인증 변수', + 'settings.providers.authStrategyApiKey': 'API 키 (ANTHROPIC_API_KEY)', + 'settings.providers.authStrategyApiKeyDesc': 'x-api-key를 사용한 Anthropic API 직접 액세스.', + 'settings.providers.authStrategyAuthToken': 'Bearer 토큰 (ANTHROPIC_AUTH_TOKEN)', + 'settings.providers.authStrategyAuthTokenDesc': 'Authorization Bearer를 사용하는 대부분의 타사 Anthropic 호환 서비스용.', + 'settings.providers.authStrategyAuthTokenEmptyApiKey': 'Bearer + 빈 API_KEY', + 'settings.providers.authStrategyAuthTokenEmptyApiKeyDesc': 'Anthropic API 키로 폴백하지 않아야 하는 OpenRouter/Ollama 형식 구성용.', + 'settings.providers.authStrategyDualSameToken': '두 변수 모두에 토큰 쓰기', + 'settings.providers.authStrategyDualSameTokenDesc': '두 변수를 모두 확인하는 Hugging Face Router 같은 서비스용.', + 'settings.providers.authStrategyDualDummy': '두 변수 모두에 더미 값 쓰기', + 'settings.providers.authStrategyDualDummyDesc': '자리 표시자 인증 값만 필요한 로컬 vLLM 호환 서비스용.', + + // Settings > Permissions + 'settings.permissions.title': '권한 모드', + 'settings.permissions.description': '도구 실행 권한을 처리하는 방식을 제어합니다.', + 'settings.permissions.default': '권한 확인', + 'settings.permissions.defaultDesc': '도구를 실행하기 전에 확인합니다', + 'settings.permissions.acceptEdits': '편집 수락', + 'settings.permissions.acceptEditsDesc': '파일 편집은 자동 승인하고 나머지는 확인합니다', + 'settings.permissions.plan': '계획 모드', + 'settings.permissions.planDesc': '실행하지 않고 사고와 계획만 합니다', + 'settings.permissions.bypass': '모두 우회', + 'settings.permissions.bypassDesc': '모든 권한 확인을 건너뜁니다 (위험)', + + // Settings > Adapters + 'settings.tab.adapters': 'IM 어댑터', + 'settings.adapters.description': 'WeChat, DingTalk, Telegram, Feishu를 통해 Claude Code와 채팅할 수 있도록 IM 어댑터를 구성합니다.', + 'settings.adapters.telegram': 'Telegram', + 'settings.adapters.feishu': 'Feishu', + 'settings.adapters.wechat': 'WeChat', + 'settings.adapters.dingtalk': 'DingTalk', + 'settings.adapters.botToken': '봇 토큰', + 'settings.adapters.botTokenPlaceholder': '@BotFather에서 받은 토큰 붙여넣기', + 'settings.adapters.appId': 'App ID', + 'settings.adapters.appIdPlaceholder': '예: cli_xxx', + 'settings.adapters.appSecret': 'App Secret', + 'settings.adapters.appSecretPlaceholder': 'Feishu 개방 플랫폼에서 가져오기', + 'settings.adapters.feishuCreateBotTitle': 'Feishu 봇이 필요하신가요?', + 'settings.adapters.feishuCreateBotDesc': '필요한 권한이 이미 구성된 Feishu 봇을 문서에 안내된 OpenClaw 템플릿으로 만드세요. 그런 다음 아래에 App ID와 App Secret을 붙여넣으세요.', + 'settings.adapters.feishuCreateBotAction': 'Feishu 봇 만들기', + 'settings.adapters.feishuCreateBotStepCreate': '템플릿에서 봇을 만듭니다.', + 'settings.adapters.feishuCreateBotStepFill': 'App ID와 App Secret을 복사하여 여기에 입력합니다.', + 'settings.adapters.encryptKey': 'Encrypt Key', + 'settings.adapters.encryptKeyPlaceholder': '선택 사항', + 'settings.adapters.verificationToken': 'Verification Token', + 'settings.adapters.verificationTokenPlaceholder': '선택 사항', + 'settings.adapters.allowedUsers': '허용된 사용자', + 'settings.adapters.allowedUsersHint': '쉼표로 구분합니다. 비워 두면 페어링된 사용자만 허용합니다.', + 'settings.adapters.tgAllowedUsersPlaceholder': '예: 123456789, 987654321', + 'settings.adapters.fsAllowedUsersPlaceholder': '예: ou_xxx, ou_yyy', + 'settings.adapters.wcAllowedUsersPlaceholder': '예: wx_user_id_1, wx_user_id_2', + 'settings.adapters.dtAllowedUsersPlaceholder': '예: manager001, staff_yyy', + 'settings.adapters.defaultProject': '기본 프로젝트', + 'settings.adapters.defaultProjectHint': '새 IM 세션의 기본 작업 디렉터리입니다. 비어 있으면 봇은 현재 사용자 작업 디렉터리를 사용합니다.', + 'settings.adapters.streamingCard': '스트리밍 카드 모드', + 'settings.adapters.streamingCardDesc': '더 나은 환경을 위해 카드를 실시간으로 업데이트합니다', + 'settings.adapters.serverUrl': '서버 URL', + 'settings.adapters.serverUrlPlaceholder': 'ws://127.0.0.1:3456', + 'settings.adapters.save': '저장', + 'settings.adapters.saved': '저장됨', + 'settings.adapters.saving': '저장 중...', + 'settings.adapters.startHint': '저장 후 어댑터를 실행하세요: cd adapters && bun run {platform}', + 'settings.adapters.pairing': '페어링', + 'settings.adapters.pairingDesc': '페어링 코드를 생성하여 IM 개인 채팅으로 봇에 보내 본인 확인을 연결합니다.', + 'settings.adapters.generateCode': '코드 생성', + 'settings.adapters.regenerateCode': '다시 생성', + 'settings.adapters.codeExpired': '만료됨', + 'settings.adapters.codeExpiresIn': '만료까지', + 'settings.adapters.minutes': '분', + 'settings.adapters.pairingCodeHint': '이 코드를 DingTalk, Feishu, WeChat 또는 Telegram 개인 채팅에서 봇에 보내세요. WeChat은 먼저 QR 연결이 필요합니다.', + 'settings.adapters.pairedUsers': '페어링된 사용자', + 'settings.adapters.noPairedUsers': '아직 페어링된 사용자가 없습니다', + 'settings.adapters.unbind': '연결 해제', + 'settings.adapters.unbindConfirm': '이 사용자의 연결을 해제하시겠습니까? 봇을 사용하려면 다시 페어링해야 합니다.', + 'settings.adapters.platform.telegram': 'Telegram', + 'settings.adapters.platform.feishu': 'Feishu', + 'settings.adapters.platform.wechat': 'WeChat', + 'settings.adapters.platform.dingtalk': 'DingTalk', + 'settings.adapters.dingtalkQrTitle': 'QR로 DingTalk 봇 연결', + 'settings.adapters.dingtalkQrDesc': 'DingTalk 모바일 앱으로 스캔하여 봇을 만들고 승인합니다. 성공하면 Client ID / Secret이 자동으로 저장됩니다.', + 'settings.adapters.dingtalkStartAuth': '스캔하여 연결', + 'settings.adapters.dingtalkUnbindBot': '봇 계정 연결 해제', + 'settings.adapters.dingtalkQrAlt': 'DingTalk 승인 QR 코드', + 'settings.adapters.dingtalkWaiting': 'DingTalk 스캔 확인을 기다리는 중...', + 'settings.adapters.dingtalkBound': 'DingTalk 봇이 연결되었습니다.', + 'settings.adapters.dingtalkAuthFailed': 'DingTalk QR 코드 승인에 실패했습니다.', + 'settings.adapters.dingtalkAuthExpired': 'DingTalk QR 코드 승인이 만료되었습니다. 새 QR 코드를 생성하세요.', + 'settings.adapters.dingtalkUnbindFailed': 'DingTalk 연결 해제에 실패했습니다.', + 'settings.adapters.dingtalkUnbindBotConfirm': '이 DingTalk 봇 계정의 연결을 해제하시겠습니까? DingTalk가 메시지를 주고받을 수 있으려면 다시 스캔해야 합니다.', + 'settings.adapters.dingtalkClientId': 'Client ID', + 'settings.adapters.dingtalkClientIdPlaceholder': 'QR 인증으로 자동 입력되거나 수동으로 입력', + 'settings.adapters.dingtalkClientSecret': 'Client Secret', + 'settings.adapters.dingtalkClientSecretPlaceholder': 'QR 인증으로 자동 입력되거나 수동으로 입력', + 'settings.adapters.dingtalkEndpoint': 'Stream 엔드포인트', + 'settings.adapters.dingtalkEndpointPlaceholder': '기본값 https://api.dingtalk.com', + 'settings.adapters.dingtalkPermissionCardTemplateId': '권한 카드 템플릿 ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdPlaceholder': '선택 사항 대화형 카드 템플릿 ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdHint': '설정하면 권한 요청에 먼저 DingTalk 대화형 카드를 사용합니다. 비워 두면 /allow, /always, /deny 텍스트 승인을 사용합니다.', + 'settings.adapters.wechatBind': '스캔하여 연결', + 'settings.adapters.wechatRebind': '다시 스캔', + 'settings.adapters.wechatConnected': 'WeChat이 연결되었습니다', + 'settings.adapters.wechatNotConnected': 'WeChat이 연결되지 않았습니다', + 'settings.adapters.wechatQrHint': 'QR 코드를 생성하고 WeChat에서 스캔한 다음 확인하세요. 연결 후 어댑터가 다시 시작됩니다.', + 'settings.adapters.wechatQrAlt': 'WeChat 연결 QR 코드', + 'settings.adapters.wechatWaiting': 'WeChat 확인을 기다리는 중...', + 'settings.adapters.wechatBindSuccess': 'WeChat 연결에 성공했습니다.', + 'settings.adapters.wechatUnbindAccount': 'WeChat 계정 연결 해제', + 'settings.adapters.wechatUnbindAccountConfirm': '이 WeChat 계정의 연결을 해제하시겠습니까? WeChat이 메시지를 주고받을 수 있으려면 다시 스캔해야 합니다.', + 'settings.adapters.wechatUnbound': 'WeChat 계정 연결을 해제했습니다.', + 'settings.adapters.wechatUnbindFailed': 'WeChat 연결 해제에 실패했습니다.', + 'settings.adapters.wechatAllowedUsersHint': 'QR 연결은 계정만 활성화합니다. 사용자는 여전히 페어링 코드를 보내야 하거나, 여기에 허용할 WeChat 사용자 ID를 추가할 수 있습니다.', + + // Settings > MCP + 'settings.mcp.title': 'MCP 서버', + 'settings.mcp.description': 'Claude Code용 외부 도구와 데이터 소스를 연결합니다. Local, Project, User 범위는 CLI와 동일하게 동작합니다.', + 'settings.mcp.addServer': '서버 추가', + 'settings.mcp.empty': '아직 구성된 MCP 서버가 없습니다', + 'settings.mcp.emptyHint': '사용자 지정 stdio, HTTP 또는 SSE MCP 서버를 추가하여 도구 액세스 확장을 시작하세요.', + 'settings.mcp.stats.total': '총 서버', + 'settings.mcp.stats.connected': '현재 연결됨', + 'settings.mcp.stats.attention': '주의 필요', + 'settings.mcp.scope.project': '프로젝트', + 'settings.mcp.scope.local': '로컬', + 'settings.mcp.scope.user': '사용자', + 'settings.mcp.scope.plugin': '플러그인', + 'settings.mcp.scopeDesc.local': '한 프로젝트 내에서 본인 전용입니다. 사용자 구성에 저장되며 선택한 프로젝트로 범위가 제한됩니다.', + 'settings.mcp.scopeDesc.project': '선택한 프로젝트의 `.mcp.json`을 통해 팀과 공유됩니다.', + 'settings.mcp.scopeDesc.user': '사용자 계정의 모든 프로젝트에서 사용할 수 있습니다.', + 'settings.mcp.scope.dynamic': '기본 제공', + 'settings.mcp.scope.enterprise': '엔터프라이즈', + 'settings.mcp.scope.claudeai': 'Claude.ai', + 'settings.mcp.scope.managed': '관리됨', + 'settings.mcp.transport.http': 'Streamable HTTP', + 'settings.mcp.globalOnlyHint': '한 프로젝트용은 Local, `.mcp.json`용은 Project, 모든 프로젝트용은 User를 선택하세요.', + 'settings.mcp.currentProjectHint': '선택한 프로젝트: {path}', + 'settings.mcp.form.back': '서버 목록으로 돌아가기', + 'settings.mcp.form.createTitle': '사용자 지정 MCP에 연결', + 'settings.mcp.form.createHint': '현재 Claude Code가 지원하는 필드로 사용자 지정 MCP 서버를 설정합니다.', + 'settings.mcp.form.editTitle': '{name} MCP 업데이트', + 'settings.mcp.form.editHint': '연결 세부 정보를 확인하고 변경 사항을 저장하거나 데스크톱 앱에서 이 서버를 다시 연결합니다.', + 'settings.mcp.form.transportLocked': 'MCP 서버 유형을 전환하려면 먼저 제거하세요.', + 'settings.mcp.form.uninstall': '제거', + 'settings.mcp.form.reconnect': '다시 연결', + 'settings.mcp.form.save': '저장', + 'settings.mcp.form.name': '이름', + 'settings.mcp.form.namePlaceholder': 'MCP 서버 이름', + 'settings.mcp.form.scope': '구성 범위', + 'settings.mcp.form.transport': '전송', + 'settings.mcp.form.status': '상태', + 'settings.mcp.form.location': '구성 위치', + 'settings.mcp.form.rawConfig': '원시 구성', + 'settings.mcp.form.command': '실행 명령', + 'settings.mcp.form.commandPlaceholder': 'npx', + 'settings.mcp.form.commandHostHint': 'STDIO MCP 명령은 호스트 컴퓨터에서 실행됩니다. Node.js, Python, Bun, uv 같은 런타임은 직접 설치하고 명령이 PATH에서 사용 가능한지 확인하세요.', + 'settings.mcp.form.arguments': '인수', + 'settings.mcp.form.argumentPlaceholder': 'chrome-devtools-mcp@latest', + 'settings.mcp.form.addArgument': '인수 추가', + 'settings.mcp.form.environmentVariables': '환경 변수', + 'settings.mcp.form.addEnv': '환경 변수 추가', + 'settings.mcp.form.keyPlaceholder': '키', + 'settings.mcp.form.valuePlaceholder': '값', + 'settings.mcp.form.url': 'URL', + 'settings.mcp.form.sseUrl': 'SSE URL', + 'settings.mcp.form.urlPlaceholder': 'https://mcp.example.com/mcp', + 'settings.mcp.form.headers': '헤더', + 'settings.mcp.form.addHeader': '헤더 추가', + 'settings.mcp.form.oauthClientId': 'OAuth 클라이언트 ID', + 'settings.mcp.form.oauthClientIdPlaceholder': '선택 사항 클라이언트 ID', + 'settings.mcp.form.oauthCallbackPort': 'OAuth 콜백 포트', + 'settings.mcp.form.oauthCallbackPortPlaceholder': '선택 사항 고정 콜백 포트', + 'settings.mcp.form.headersHelper': '헤더 도우미 스크립트', + 'settings.mcp.form.headersHelperPlaceholder': '선택 사항 도우미 명령 경로', + 'settings.mcp.form.deleteTitle': 'MCP 서버 삭제', + 'settings.mcp.form.cancel': '취소', + 'settings.mcp.form.confirmDelete': '삭제', + 'settings.mcp.form.deleteConfirm': 'MCP 서버 "{name}"을(를) 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.', + 'settings.mcp.form.deleteConfirmBody': 'MCP 서버 "{name}"을(를) 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.', + 'settings.mcp.targetProject.title': '대상 프로젝트', + 'settings.mcp.targetProject.selected': '현재 다음 프로젝트의 로컬 및 공유 MCP 서버를 표시하고 있습니다: {path}', + 'settings.mcp.targetProject.empty': '프로젝트 전용 또는 공유 MCP 서버를 확인할 프로젝트를 선택하세요.', + 'settings.mcp.targetProject.emptyWithCurrent': '대상 프로젝트를 선택하세요. 현재 활성 세션: {path}', + 'settings.mcp.targetProject.localSelected': '이 서버는 다음 안에서 본인 전용이 됩니다: {path}', + 'settings.mcp.targetProject.localEmpty': '이 비공개 MCP 서버를 받을 프로젝트를 선택하세요.', + 'settings.mcp.targetProject.projectSelected': '이 서버는 다음을 통해 공유됩니다: {path}/.mcp.json', + 'settings.mcp.targetProject.projectEmpty': '이 공유 MCP 서버를 `.mcp.json`으로 받을 프로젝트를 선택하세요.', + 'settings.mcp.targetProject.globalTitle': '전역 설치 대상', + 'settings.mcp.targetProject.globalHint': 'User 범위는 대상 프로젝트가 필요 없습니다. 전역 Claude 구성에 저장되며 어디서나 사용할 수 있습니다.', + 'settings.mcp.toast.created': 'MCP 서버 "{name}"을(를) 만들었습니다', + 'settings.mcp.toast.saved': 'MCP 서버 "{name}"을(를) 저장했습니다', + 'settings.mcp.toast.deleted': 'MCP 서버 "{name}"을(를) 삭제했습니다', + 'settings.mcp.toast.enabled': 'MCP 서버 "{name}"을(를) 사용 설정했습니다', + 'settings.mcp.toast.disabled': 'MCP 서버 "{name}"을(를) 사용 중지했습니다', + 'settings.mcp.toast.reconnected': 'MCP 서버 "{name}"을(를) 다시 연결했습니다', + 'settings.mcp.toast.saveFailed': 'MCP 서버를 저장하지 못했습니다', + 'settings.mcp.toast.deleteFailed': 'MCP 서버를 삭제하지 못했습니다', + 'settings.mcp.toast.toggleFailed': 'MCP 서버 상태를 업데이트하지 못했습니다', + 'settings.mcp.toast.reconnectFailed': 'MCP 서버를 다시 연결하지 못했습니다', + + // Settings > Agents + 'settings.tab.agents': '에이전트', + 'settings.agents.title': '설치된 에이전트', + 'settings.agents.description': '기본 제공, 프로젝트, 사용자 소스 전반에서 Claude가 사용할 수 있는 에이전트를 살펴봅니다. TUI에서 /agents를 사용하면 활성 소스와 재정의를 확인할 수 있습니다.', + 'settings.agents.browserTitle': '설치된 에이전트 살펴보기', + 'settings.agents.browserEyebrow': '에이전트 브라우저', + 'settings.agents.entryEyebrow': '에이전트 프로필', + 'settings.agents.empty': '아직 사용할 수 있는 에이전트가 없습니다.', + 'settings.agents.emptyHint': 'Claude 설정이나 프로젝트에 에이전트 정의를 추가하면 여기에 표시됩니다.', + 'settings.agents.model': '모델', + 'settings.agents.tools': '도구', + 'settings.agents.systemPrompt': '시스템 프롬프트', + 'settings.agents.noDescription': '설명 없음', + 'settings.agents.noSystemPrompt': '정의된 시스템 프롬프트가 없습니다.', + 'settings.agents.backToList': '목록으로 돌아가기', + 'settings.agents.agentCount': '{count} 에이전트', + 'settings.agents.summary.totalAgents': '총 에이전트', + 'settings.agents.summary.activeAgents': '활성 에이전트', + 'settings.agents.summary.sources': '소스', + 'settings.agents.summary.source': '소스', + 'settings.agents.summary.model': '모델', + 'settings.agents.summary.tools': '도구', + 'settings.agents.summary.status': '상태', + 'settings.agents.groupHint': '{source}에서 사용 가능한 에이전트 {count}개', + 'settings.agents.status.active': '활성', + 'settings.agents.status.available': '사용 가능', + 'settings.agents.overriddenBy': '{source}에 의해 재정의됨', + 'settings.agents.overriddenByShort': '{source}에 의해 가려짐', + 'settings.agents.toolCount': '{count} 도구', + 'settings.agents.noTools': '도구 제한 없음', + 'settings.agents.promptHint': '현재 시스템 프롬프트를 읽고 이 에이전트의 범위를 비교합니다.', + 'settings.agents.source.userSettings': '사용자', + 'settings.agents.source.projectSettings': '프로젝트', + 'settings.agents.source.localSettings': '로컬', + 'settings.agents.source.policySettings': '관리됨', + 'settings.agents.source.plugin': '플러그인', + 'settings.agents.source.flagSettings': 'CLI 인수', + 'settings.agents.source.built-in': '기본 제공', + + // Settings > Skills + 'settings.skills.title': '설치된 스킬', + 'settings.skills.description': '스킬은 Claude에 전문 기능을 추가합니다. 스킬은 ~/.claude/skills/에서 관리합니다', + 'settings.skills.browserTitle': '설치된 스킬 살펴보기', + 'settings.skills.browserEyebrow': '스킬 브라우저', + 'settings.skills.browserDescription': '번들, 프로젝트, 사용자 스킬을 확인하고 범위를 비교하며, 각 스킬 폴더를 열어 문서와 소스 파일을 읽습니다.', + 'settings.skills.searchLabel': '스킬 검색', + 'settings.skills.searchPlaceholder': '이름, 설명 또는 소스로 스킬 검색...', + 'settings.skills.searchResultCount': '{total}개 중 {count}개의 스킬이 일치', + 'settings.skills.clearSearch': '스킬 검색 지우기', + 'settings.skills.noSearchResults': '일치하는 스킬이 없습니다', + 'settings.skills.noSearchResultsHint': '다른 키워드를 시도하거나 검색을 지워 모든 스킬을 표시하세요.', + 'settings.skills.entryEyebrow': '스킬 항목', + 'settings.skills.slashCommand': '/slash', + 'settings.skills.tokenEstimate': '약 {count} 토큰', + 'settings.skills.tokenEstimateShort': '약 {count}', + 'settings.skills.summary.totalSkills': '총 스킬', + 'settings.skills.summary.totalFiles': '파일', + 'settings.skills.summary.sources': '소스', + 'settings.skills.summary.tokens': '예상 토큰 수', + 'settings.skills.summary.source': '소스', + 'settings.skills.summary.entry': '항목', + 'settings.skills.groupHint': '{source}에서 사용 가능한 스킬 {count}개', + 'settings.skills.ready': '준비됨', + 'settings.skills.unavailable': '사용 불가', + 'settings.skills.empty': '설치된 스킬이 없습니다', + 'settings.skills.emptyHint': '~/.claude/skills/에 스킬을 추가하여 시작하세요', + 'settings.skills.back': '목록으로 돌아가기', + 'settings.skills.files': '파일', + 'settings.skills.entryFile': '항목 파일', + 'settings.skills.metaTitle': '스킬 메타데이터', + 'settings.skills.filesPanel': '파일', + 'settings.skills.filesPanelHint': '항목 파일과 보조 구현 파일을 살펴봅니다.', + 'settings.skills.readingMode': '{mode}(으)로 보는 중', + 'settings.skills.docMode': '문서 모드', + 'settings.skills.codeMode': '코드 모드', + 'settings.skills.source.user': '사용자', + 'settings.skills.source.project': '프로젝트', + 'settings.skills.source.plugin': '플러그인', + 'settings.skills.source.mcp': 'MCP', + 'settings.skills.source.bundled': '기본 제공', + + // Settings > Memory + 'settings.tab.memory': '메모리', + 'settings.memory.title': '프로젝트 메모리', + 'settings.memory.description': 'Claude가 각 프로젝트용으로 작성하는 Markdown 메모리 파일을 확인하고 편집합니다. 이 파일들은 ~/.claude/projects//memory/ 아래에 저장되며 CLI 런타임에 의해 로드됩니다.', + 'settings.memory.refresh': '새로 고침', + 'settings.memory.projects': '프로젝트', + 'settings.memory.files': '메모리 파일', + 'settings.memory.resourceManager': '리소스 관리자', + 'settings.memory.editor': '편집기', + 'settings.memory.preview': '미리 보기', + 'settings.memory.rendered': '렌더링됨', + 'settings.memory.emptyProjects': '메모리가 있는 프로젝트를 찾을 수 없습니다.', + 'settings.memory.emptyFiles': '아직 메모리 파일을 찾을 수 없습니다.', + 'settings.memory.selectFile': '메모리 파일을 선택하세요.', + 'settings.memory.selectProject': '프로젝트를 선택하세요.', + 'settings.memory.noFileSelected': '선택된 파일이 없습니다', + 'settings.memory.current': '현재', + 'settings.memory.indexFile': '인덱스', + 'settings.memory.missing': '없음', + 'settings.memory.fileCount': '{count} 파일', + 'settings.memory.unsaved': '저장 안 됨', + 'settings.memory.saved': '저장됨', + 'settings.memory.revert': '되돌리기', + 'settings.memory.projectSearchPlaceholder': '경로로 프로젝트 검색...', + 'settings.memory.fileSearchPlaceholder': '메모리 파일 검색...', + 'settings.memory.resourceSearchPlaceholder': '프로젝트 또는 메모리 파일 검색...', + 'settings.memory.noProjectMatches': '이 검색과 일치하는 프로젝트가 없습니다.', + 'settings.memory.noFileMatches': '이 검색과 일치하는 메모리 파일이 없습니다.', + 'settings.memory.clearSearch': '검색 지우기', + 'settings.memory.toggleFolder': '{name} 전환', + + // Settings > Plugins + 'settings.plugins.title': '설치된 플러그인', + 'settings.plugins.description': '설치된 플러그인을 확인하고 상태를 파악하며 데스크톱 런타임에 변경 사항을 적용합니다.', + 'settings.plugins.browserTitle': '설치된 플러그인 살펴보기', + 'settings.plugins.browserEyebrow': '플러그인 관리자', + 'settings.plugins.browserDescription': '플러그인은 스킬, 에이전트, 후크, MCP 서버, 언어 도구를 묶은 것입니다. 이 화면은 설치된 플러그인, 상태, 런타임 적용 피드백에 데스크톱 화면을 집중시킵니다.', + 'settings.plugins.entryEyebrow': '플러그인 세부 정보', + 'settings.plugins.summary.total': '총 플러그인', + 'settings.plugins.summary.enabled': '사용', + 'settings.plugins.summary.attention': '주의 필요', + 'settings.plugins.summary.marketplaces': '마켓플레이스', + 'settings.plugins.summary.skills': '스킬', + 'settings.plugins.summary.agents': '에이전트', + 'settings.plugins.summary.mcp': 'MCP', + 'settings.plugins.summary.hooks': '후크', + 'settings.plugins.group.attention': '주의 필요', + 'settings.plugins.group.enabled': '사용', + 'settings.plugins.group.disabled': '사용 안 함', + 'settings.plugins.groupHint': '이 섹션에는 {count}개의 플러그인이 있습니다', + 'settings.plugins.refresh': '새로 고침', + 'settings.plugins.apply': '변경 사항 적용', + 'settings.plugins.applyHint': '사용, 사용 안 함, 업데이트 변경 사항은 현재 데스크톱 런타임에 적용한 후 적용됩니다.', + 'settings.plugins.lastReload': '마지막 적용: 활성 플러그인 {enabled}개, 플러그인 스킬 {skills}개, 오류 {errors}건.', + 'settings.plugins.reloadToast': '플러그인 변경 사항을 적용했습니다: 활성 플러그인 {enabled}개, 스킬 {skills}개, 오류 {errors}건.', + 'settings.plugins.marketplacesTitle': '알려진 마켓플레이스', + 'settings.plugins.marketplacesHint': '이 컴퓨터에 이미 구성된 마켓플레이스 소스의 읽기 전용 요약입니다.', + 'settings.plugins.marketplaceAutoUpdateOn': '자동 업데이트 켜짐', + 'settings.plugins.marketplaceAutoUpdateOff': '자동 업데이트 꺼짐', + 'settings.plugins.marketplaceInstalledCount': '{count}개 설치됨', + 'settings.plugins.marketplaceUpdatedAt': '{value} 업데이트됨', + 'settings.plugins.status.enabled': '사용', + 'settings.plugins.status.disabled': '사용 안 함', + 'settings.plugins.status.attention': '주의', + 'settings.plugins.scope.user': '사용자', + 'settings.plugins.scope.project': '프로젝트', + 'settings.plugins.scope.local': '로컬', + 'settings.plugins.scope.managed': '관리됨', + 'settings.plugins.scope.builtin': '기본 제공', + 'settings.plugins.empty': '설치된 플러그인이 없습니다', + 'settings.plugins.emptyHint': 'Claude Code에서 플러그인을 설치하면 여기서 관리할 수 있습니다.', + 'settings.plugins.back': '목록으로 돌아가기', + 'settings.plugins.noDescription': '이 플러그인에 대한 설명이 없습니다.', + 'settings.plugins.errorCount': '{count}건의 오류', + 'settings.plugins.enable': '사용', + 'settings.plugins.disable': '사용 안 함', + 'settings.plugins.update': '업데이트', + 'settings.plugins.uninstall': '제거', + 'settings.plugins.confirmUninstall': '플러그인 "{name}"을(를) 제거하시겠습니까? 선택한 범위의 설치된 복사본이 삭제됩니다.', + 'settings.plugins.author': '작성자: {value}', + 'settings.plugins.projectPath': '프로젝트: {value}', + 'settings.plugins.installPath': '설치 위치: {value}', + 'settings.plugins.managedHint': '이 플러그인은 정책에 의해 관리되며 데스크톱 앱에서 변경할 수 없습니다.', + 'settings.plugins.builtinHint': '기본 제공 플러그인은 여기서 다시 로드할 수 있지만 설치 및 제거 작업은 표시되지 않습니다.', + 'settings.plugins.errorsTitle': '플러그인 오류', + 'settings.plugins.capabilitiesTitle': '번들된 기능', + 'settings.plugins.capabilitiesHint': '이 플러그인이 매니페스트와 런타임 통합을 로드한 후 노출하는 기능입니다.', + 'settings.plugins.sharedNavigationDisabled': '공유 관리 페이지에서 이 플러그인의 스킬, 에이전트, MCP 항목을 열기 전에 플러그인을 사용 설정하고 변경 사항을 적용하세요.', + 'settings.plugins.capabilityEmpty': '노출 없음', + 'settings.plugins.capability.skills': '{count} 스킬', + 'settings.plugins.capability.agents': '{count} 에이전트', + 'settings.plugins.capability.mcpServers': '{count} MCP 서버', + 'settings.plugins.capabilityLabel.skills': '스킬', + 'settings.plugins.capabilityLabel.commands': '명령', + 'settings.plugins.capabilityLabel.agents': '에이전트', + 'settings.plugins.capabilityLabel.hooks': '후크', + 'settings.plugins.capabilityLabel.mcpServers': 'MCP 서버', + 'settings.plugins.capabilityLabel.lspServers': 'LSP 서버', + + // Settings > About + 'settings.tab.about': '정보', + 'settings.about.version': '버전', + 'settings.about.changelog': '릴리스 노트', + 'settings.about.repo': 'GitHub 저장소', + 'settings.about.starHint': '이 프로젝트가 도움이 되었다면 Star를 눌러 주세요', + 'settings.about.feedback': '문제 신고', + 'settings.about.feedbackDesc': '버그나 사용 관련 질문은 GitHub Issue를 작성하세요', + 'settings.about.author': '작성자', + 'settings.about.socialMedia': '소셜 미디어', + 'settings.about.updates': '앱 업데이트', + 'settings.about.updatesDesc': 'GitHub Releases를 확인하고 설치 관리자를 다운로드한 후 설치 후 다시 시작합니다.', + + // Settings > Computer Use + 'settings.tab.computerUse': '컴퓨터 사용', + 'settings.computerUse.title': '컴퓨터 사용', + 'settings.computerUse.description': 'Claude가 스크린샷을 찍고 클릭, 입력하며 컴퓨터를 제어할 수 있도록 허용합니다. Python 3가 필요합니다. macOS에서는 접근성 권한도 필요합니다.', + 'settings.computerUse.enabledToggle': '사용', + 'settings.computerUse.disabledHint': '컴퓨터 사용이 꺼져 있습니다. 새 세션은 computer-use MCP 서버를 주입하거나 데스크톱 제어 도구를 코딩 에이전트에 노출하지 않습니다.', + 'settings.computerUse.notSupported': '컴퓨터 사용은 macOS와 Windows에서만 지원됩니다.', + 'settings.computerUse.python': 'Python 3', + 'settings.computerUse.pythonNotFound': '설치되어 있지 않습니다. 먼저 Python 3를 설치하세요.', + 'settings.computerUse.pythonFound': '설치됨', + 'settings.computerUse.pythonCustomInvalid': '사용자 지정 인터프리터를 사용할 수 없습니다', + 'settings.computerUse.pythonPathLabel': 'Python 인터프리터 경로', + 'settings.computerUse.pythonPathPlaceholder': '자동 감지 또는 python.exe / python3 선택', + 'settings.computerUse.pythonPathHint': '비워 두면 자동 감지합니다. 런타임 설정에서 우선하려면 conda, pyenv 또는 기타 사용자 지정 환경의 Python 실행 파일을 선택하세요.', + 'settings.computerUse.pythonPathBrowse': '찾아보기', + 'settings.computerUse.pythonPathSave': '적용', + 'settings.computerUse.pythonPathAuto': '자동', + 'settings.computerUse.pythonPathSaved': '저장했습니다. 다시 확인할 때 이 인터프리터를 우선합니다.', + 'settings.computerUse.pythonPathSaveFailed': '저장에 실패했습니다. 다시 시도하세요.', + 'settings.computerUse.pythonPathDialogTitle': 'Python 인터프리터 선택', + 'settings.computerUse.pythonPathDialogFailed': '파일 선택기를 열 수 없습니다. 경로를 수동으로 붙여넣으세요.', + 'settings.computerUse.venv': '가상 환경', + 'settings.computerUse.venvReady': '준비됨', + 'settings.computerUse.venvNotReady': '만들어지지 않음', + 'settings.computerUse.deps': '종속성', + 'settings.computerUse.depsReady': '설치됨', + 'settings.computerUse.depsNotReady': '설치되지 않음', + 'settings.computerUse.accessibility': '접근성 권한', + 'settings.computerUse.screenRecording': '화면 기록 권한', + 'settings.computerUse.permGranted': '허용됨', + 'settings.computerUse.permDenied': '거부됨 — 시스템 설정 > 개인정보 보호 및 보안 을 열어 허용하세요', + 'settings.computerUse.permUnknown': '확인하려면 먼저 환경을 설정하세요', + 'settings.computerUse.permScreenRecordingUnknownSoft': '여기서는 자동 감지가 불안정할 수 있습니다. 시스템 설정에서 이미 사용으로 표시되어 있으면 일반적으로 컴퓨터 사용을 계속할 수 있습니다', + 'settings.computerUse.permScreenRecordingManual': '자동 감지할 수 없습니다 — 시스템 설정에서 확인하세요', + 'settings.computerUse.setupBtn': '환경 설치', + 'settings.computerUse.setupRunning': '설치 중...', + 'settings.computerUse.setupSuccess': '환경 설정이 완료되었습니다!', + 'settings.computerUse.setupFail': '설정에 실패했습니다', + 'settings.computerUse.allReady': '모든 검사를 통과했습니다. 컴퓨터 사용 준비가 완료되었습니다.', + 'settings.computerUse.downloadPython': 'Python 3 다운로드', + 'settings.computerUse.recheckBtn': '상태 다시 확인', + 'settings.computerUse.requirementsLabel': '필요한 패키지', + 'settings.computerUse.appsTitle': '승인된 앱', + 'settings.computerUse.appsDescription': '컴퓨터 사용을 위해 앱을 사전 승인합니다. 승인된 앱은 실행 중 확인 없이 Claude가 제어할 수 있습니다.', + 'settings.computerUse.appsLoading': '설치된 앱을 불러오는 중...', + 'settings.computerUse.appsEmpty': '설치된 앱을 찾을 수 없습니다. 먼저 환경을 설정하세요.', + 'settings.computerUse.appsSearch': '앱 검색...', + 'settings.computerUse.appsSaved': '저장됨', + 'settings.computerUse.openAccessibility': '접근성 설정 열기', + 'settings.computerUse.openScreenRecording': '화면 기록 설정 열기', + 'settings.computerUse.permRestartHint': '허용한 후 적용하려면 앱을 다시 시작하세요.', + 'settings.computerUse.flagClipboard': '클립보드 액세스', + 'settings.computerUse.flagSystemKeys': '시스템 키 조합', + + // Settings > General - Storage + 'settings.general.modeSwitchTitle': '데이터 저장 위치를 전환하시겠습니까?', + 'settings.general.modeSwitchConfirm': '저장하고 다시 시작', + 'settings.general.storageTitle': '데이터 저장 위치', + 'settings.general.storageDescription': '고급, 사용 빈도가 낮은 설정입니다. 전환 후에는 세션, 스킬, MCP, 플러그인, 공급자 설정, 작업, 캐시를 새 디렉터리에서 읽습니다.', + 'settings.general.storageSystemTitle': '시스템 디렉터리 사용', + 'settings.general.storageSystemDescription': '기본 데이터 소스로 돌아갑니다. 시작 환경에 CLAUDE_CONFIG_DIR이 설정되어 있으면 해당 환경 변수가 여전히 우선합니다.', + 'settings.general.storagePortableTitle': '포터블 디렉터리 사용', + 'settings.general.storagePortableDescription': '선택한 폴더에 데스크톱 데이터를 저장합니다. 외장 드라이브나 함께 옮기려는 앱 번들에 사용하세요.', + 'settings.general.storagePortableDirLabel': '포터블 데이터 디렉터리', + 'settings.general.storagePortableDirPlaceholder': 'cc-haha 데이터용 폴더 선택', + 'settings.general.storageChooseDir': '폴더 선택', + 'settings.general.storageChooseDirTitle': '포터블 데이터 디렉터리 선택', + 'settings.general.storageUseDefaultPortableDir': '앱 옆의 기본 포터블 폴더 사용', + 'settings.general.storageApplyPortable': '이 폴더를 사용하고 다시 시작', + 'settings.general.storageActiveDir': '현재 활성 데이터 디렉터리', + 'settings.general.storageEnvironmentHint': '현재 디렉터리는 CLAUDE_CONFIG_DIR 환경 변수로 제어됩니다. 앱 내 전환으로는 이를 재정의할 수 없습니다. 시스템 디렉터리로 돌아가려면 시작 환경에서 CLAUDE_CONFIG_DIR을 제거하세요.', + 'settings.general.storageEnvironmentSwitchBlocked': '현재 CLAUDE_CONFIG_DIR이 데이터 디렉터리를 제어합니다. 시스템 디렉터리로 돌아가기 전에 시작 환경에서 이를 제거하세요.', + 'settings.general.storageRestartHint': '저장 위치 변경이 저장되었습니다. 새 데이터 디렉터리를 적용하려면 앱을 다시 시작하세요.', + 'settings.general.storageMoveHint': '디렉터리를 전환해도 기존 데이터는 마이그레이션되지 않습니다. 이전 세션을 계속 표시하려면 이전 디렉터리에서 projects, skills, plugins, cc-haha 및 관련 폴더를 복사하세요. 포터블 번들의 경우 이 폴더를 앱 옆에 두고 함께 압축하세요.', + 'settings.general.storageNoDirError': '먼저 포터블 데이터 디렉터리를 선택하거나 입력하세요.', + 'settings.general.storagePickerError': '폴더 선택기를 열 수 없습니다. 폴더 경로를 수동으로 붙여넣으세요.', + 'settings.general.storageRestartError': '변경 사항은 저장되었지만 자동 다시 시작에 실패했습니다. 앱을 수동으로 다시 시작하세요.', + 'settings.general.storageSwitchPortableBody': '전환 후 데스크톱 앱은 이 디렉터리에서 세션, 설정, 스킬, MCP, 플러그인, 작업, 캐시를 읽고 씁니다.', + 'settings.general.storageSwitchDefaultBody': '다시 전환하면 데스크톱 앱은 다시 시스템 데이터 소스를 사용합니다. 포터블 디렉터리의 데이터는 자동으로 삭제되거나 되돌려지지 않습니다.', + 'settings.general.storageSwitchRestartBody': '앱이 로컬 서버와 어댑터 프로세스를 중지한 후 다시 시작합니다. 새 디렉터리는 다시 시작 후에 적용됩니다.', + + // Settings > General + 'settings.general.appearanceTitle': '모양', + 'settings.general.appearanceDescription': '따뜻한 클래식 작업 공간, 어두운 작업 공간, 순백색 작업 공간 사이를 전환합니다.', + 'settings.general.appearance.light': '따뜻한 클래식', + 'settings.general.appearance.dark': '어둡게', + 'settings.general.appearance.white': '순백색', + 'settings.general.languageTitle': '언어', + 'settings.general.languageDescription': '애플리케이션의 표시 언어를 선택합니다.', + 'settings.general.responseLangTitle': '응답 언어', + 'settings.general.responseLangDescription': 'Claude가 항상 특정 언어로 응답하도록 지시합니다.', + 'settings.general.responseLangDefault': '기본값(영어)', + 'settings.general.effortTitle': '노력 수준', + 'settings.general.effortDescription': '모델이 사용하는 계산량을 제어합니다.', + 'settings.general.effort.low': '낮음', + 'settings.general.effort.medium': '보통', + 'settings.general.effort.high': '높음', + 'settings.general.effort.max': '최대', + 'settings.general.thinkingTitle': '사고 모드', + 'settings.general.thinkingDescription': '새 세션을 모델 사고를 사용으로 시작할지 제어합니다. 꺼져 있으면 DeepSeek 같은 호환 공급자에 명시적인 비사고 매개변수가 전달됩니다.', + 'settings.general.thinkingEnabled': '사고 모드 사용', + 'settings.general.thinkingHint': '새 세션을 --thinking 비활성화로 시작하려면 이를 끄세요. DeepSeek V4 Flash/Pro 및 기타 비사고 워크플로에 유용합니다.', + 'settings.general.notificationsTitle': '시스템 알림', + 'settings.general.notificationsDescription': '권한 확인, 에이전트 응답, 예약 작업 결과에 OS 기본 알림을 사용합니다.', + 'settings.general.notificationsEnabled': '시스템 알림 사용', + 'settings.general.notificationsHintOn': '사용하면 앱이 알림 권한을 요청하고 OS 알림 센터를 사용합니다.', + 'settings.general.notificationsHintOff': '사용 안 하면 권한 확인, 에이전트 응답, 예약 작업이 데스크톱 알림을 보내지 않습니다.', + 'settings.general.notificationsStatus': '권한', + 'settings.general.notificationsStatusGranted': '허용됨', + 'settings.general.notificationsStatusDenied': '시스템 설정에 의해 차단됨', + 'settings.general.notificationsStatusDefault': '요청되지 않음', + 'settings.general.notificationsStatusUnsupported': '이 환경에서는 사용할 수 없습니다', + 'settings.general.notificationsAuthorize': '허용', + 'settings.general.notificationsOpenSettings': '설정 열기', + 'settings.general.notificationsTestTitle': 'Claude Code Haha 알림이 사용 설정되었습니다', + 'settings.general.notificationsTestBody': '이제 권한 확인과 완료된 에이전트 응답에 시스템 알림이 사용됩니다.', + 'settings.general.chatSendBehaviorTitle': '메시지 전송', + 'settings.general.chatSendBehaviorDescription': '데스크톱 채팅 입력창에서 메시지를 전송하는 방식을 선택합니다.', + 'settings.general.chatSendBehaviorEnter': 'Enter로 전송', + 'settings.general.chatSendBehaviorEnterDescription': 'Shift+Enter로 줄을 바꿉니다.', + 'settings.general.chatSendBehaviorModifier': 'Ctrl/Cmd+Enter로 전송', + 'settings.general.chatSendBehaviorModifierDescription': 'Enter와 Shift+Enter로 줄을 바꿉니다.', + 'settings.general.h5AccessTitle': 'H5 액세스', + 'settings.general.h5AccessDescription': '데스크톱 H5 앱을 로컬 네트워크에 공개합니다. 휴대폰은 수명이 짧은 H5 토큰이 포함된 QR 링크로 연결합니다.', + 'settings.general.h5AccessEnabled': 'H5 액세스 사용', + 'settings.general.h5AccessEnabledHint': '데스크톱 서버가 LAN 주소에서 수신 대기하고 데스크톱 세션에 대한 액세스를 허용합니다.', + 'settings.general.h5AccessStatusEnabled': '사용', + 'settings.general.h5AccessTokenPreview': '토큰 미리 보기', + 'settings.general.h5AccessDisabledValue': '사용 안 함', + 'settings.general.h5AccessDisable': '사용 안 함', + 'settings.general.h5AccessGenerateToken': '토큰 생성', + 'settings.general.h5AccessRegenerate': '토큰 다시 생성', + 'settings.general.h5AccessGeneratedToken': '생성된 토큰', + 'settings.general.h5AccessGeneratedTokenHint': '한 번만 표시됩니다. 지금 복사하여 비밀번호처럼 보관하세요.', + 'settings.general.h5AccessShowToken': '토큰 표시', + 'settings.general.h5AccessCopy': '복사', + 'settings.general.h5AccessCopyUrl': 'H5 URL 복사', + 'settings.general.h5AccessCopyLaunchUrl': 'QR 링크 복사', + 'settings.general.h5AccessUrlCopied': 'H5 URL을 복사했습니다.', + 'settings.general.h5AccessLaunchUrlCopied': 'QR 링크를 복사했습니다.', + 'settings.general.h5AccessHideToken': '토큰 숨기기', + 'settings.general.h5AccessTokenNotAvailable': '새 토큰을 표시하려면 다시 생성하세요.', + 'settings.general.h5AccessPublicHost': '액세스 호스트 / IP', + 'settings.general.h5AccessPublicHostPlaceholder': '192.168.1.100', + 'settings.general.h5AccessCurrentPort': '현재 포트', + 'settings.general.h5AccessCurrentPortUnknown': '자동', + 'settings.general.h5AccessPublicUrl': '공개 URL', + 'settings.general.h5AccessPublicUrlPlaceholder': 'https://chat.example.com', + 'settings.general.h5AccessAllowedOrigins': '허용된 출처', + 'settings.general.h5AccessAllowedOriginsPlaceholder': 'https://chat.example.com, https://phone.example', + 'settings.general.h5AccessOriginsHint': '한 줄에 하나의 출처를 입력하거나 여러 출처를 쉼표로 구분하세요.', + 'settings.general.h5AccessOpenHint': 'LAN 액세스의 경우 호스트 / IP만 변경하세요. 현재 서비스 포트가 재사용됩니다. 리버스 프록시의 경우 전체 URL을 입력하세요.', + 'settings.general.h5AccessSave': 'H5 설정 저장', + 'settings.general.h5AccessUrl': 'H5 URL', + 'settings.general.h5AccessQrTitle': '휴대폰 연결', + 'settings.general.h5AccessQrHint': '스캔하면 토큰이 입력된 상태로 H5가 열립니다.', + 'settings.general.h5AccessQrRefreshHint': "'토큰 생성'을 클릭하면 스캔할 수 있는 QR 링크가 만들어집니다.", + 'settings.general.h5AccessQrEmptyHint': 'QR 코드를 만들려면 토큰을 생성하세요.', + 'settings.general.h5AccessQrAlt': 'H5 액세스 QR 코드', + 'settings.general.h5AccessSafetyNote': '신뢰할 수 있는 네트워크에서만 사용하세요. QR 링크가 있는 누구나 H5가 노출하는 데스크톱 기능에 접근할 수 있습니다.', + 'settings.general.h5AccessConfirmTitle': 'LAN H5 액세스를 사용하시겠습니까?', + 'settings.general.h5AccessConfirmBody': '이렇게 하면 데스크톱 H5 앱이 LAN 주소와 포트에 공개됩니다. QR 토큰이 있는 기기는 데스크톱 세션과 관련 제어에 접근할 수 있습니다. 신뢰할 수 있는 네트워크에서만 계속하세요.', + 'settings.general.h5AccessConfirmEnable': 'H5 액세스 사용', + 'settings.general.h5AccessError': 'H5 액세스 설정을 업데이트하지 못했습니다.', + 'settings.general.h5AccessStaleHostTitle': '저장된 H5 호스트에 더 이상 연결할 수 없습니다', + 'settings.general.h5AccessStaleHostBody': '저장된 호스트 {storedHost}이(가) 이 컴퓨터의 활성 인터페이스에 바인딩되어 있지 않습니다. QR 코드를 스캔하는 휴대폰은 연결에 실패합니다. 현재 LAN IP로 전환하는 것을 권장합니다.', + 'settings.general.h5AccessStaleHostNoSuggestion': '저장된 호스트 {storedHost}이(가) 이 컴퓨터의 활성 인터페이스에 바인딩되어 있지 않습니다. QR 코드를 스캔하는 휴대폰은 연결에 실패합니다. 이 컴퓨터의 네트워크 연결을 확인하거나 리버스 프록시 URL로 전환하세요.', + 'settings.general.h5AccessStaleHostApply': '{suggestedHost}(으)로 전환', + 'settings.general.h5AccessProxyNote': '현재 리버스 프록시 URL을 사용하고 있습니다. 휴대폰은 구성한 공개 도메인 / 터널을 통해 데스크톱에 연결됩니다. 프록시가 계속 작동 중인지 확인하세요.', + 'settings.general.networkTitle': '네트워크', + 'settings.general.networkDescription': '데스크톱 세션이 수행하는 공급자 API 요청을 제어합니다.', + 'settings.general.networkProxyModeSystem': '시스템 프록시', + 'settings.general.networkProxyModeSystemDescription': '앱 프로세스가 상속한 프록시 설정을 사용합니다.', + 'settings.general.networkProxyModeManual': '수동 프록시', + 'settings.general.networkProxyModeManualDescription': '아래에 입력한 HTTP 또는 HTTPS 프록시 URL을 사용합니다.', + 'settings.general.networkProxyUrl': '프록시 URL', + 'settings.general.networkProxyUrlHint': 'HTTP 및 HTTPS 프록시 URL을 지원합니다. 예: http://127.0.0.1:7890.', + 'settings.general.networkProxyUrlInvalid': 'HTTP 또는 HTTPS 프록시 URL을 입력하세요.', + 'settings.general.networkProxyUrlRequired': '프록시 URL을 입력하세요.', + 'settings.general.networkTimeout': 'AI 요청 시간 초과', + 'settings.general.networkTimeoutValue': '{seconds}초', + 'settings.general.networkTimeoutHint': '공급자 요청, 스트리밍 첫 응답, 공급자 연결 테스트에 적용됩니다. 5~600초를 지원합니다.', + 'settings.general.networkTimeoutUnit': '초', + 'settings.general.networkTimeoutDecrease': '30초 줄이기', + 'settings.general.networkTimeoutIncrease': '30초 늘리기', + 'settings.general.networkTimeoutRequired': '시간 초과를 입력하세요.', + 'settings.general.networkTimeoutRange': '{min}에서 {max}초까지의 정수를 입력하세요.', + 'settings.general.networkSaved': '네트워크 설정을 저장했습니다.', + 'settings.general.networkScopeHint': '별도의 앱 업데이트 프록시는 변경되지 않습니다.', + 'settings.general.networkSave': '저장', + 'settings.general.webFetchPreflightTitle': 'WebFetch 사전 확인', + 'settings.general.webFetchPreflightDescription': '데스크톱 세션은 타사 공급자와 제한된 네트워크에서의 잘못된 실패를 피하기 위해 기본적으로 Claude의 도메인 사전 확인을 건너뜁니다.', + 'settings.general.webFetchPreflightEnabled': 'WebFetch 도메인 사전 확인 건너뛰기', + 'settings.general.webFetchPreflightHint': '각 WebFetch 요청 전에 업스트림 안전 사전 확인을 명시적으로 복원하려는 경우에만 이를 끄세요.', + 'settings.general.webSearchTitle': 'WebSearch', + 'settings.general.webSearchDescription': '에이전트 웹 검색을 공식 Claude, 타사 공급자, 로컬 폴백 키 중 어디에서 해결할지 선택합니다.', + 'settings.general.webSearch.mode.auto': '자동', + 'settings.general.webSearch.mode.tavily': 'Tavily', + 'settings.general.webSearch.mode.brave': 'Brave', + 'settings.general.webSearch.mode.anthropic': 'Claude', + 'settings.general.webSearch.mode.disabled': '끄기', + 'settings.general.webSearchTavilyKey': 'Tavily API 키', + 'settings.general.webSearchBraveKey': 'Brave Search API 키', + 'settings.general.webSearchBravePlaceholder': 'Brave Search 토큰', + 'settings.general.webSearchGetApiKey': 'API 키 가져오기', + 'settings.general.webSearchTavilyApiKeyLink': 'Tavily API 키 가져오기', + 'settings.general.webSearchBraveApiKeyLink': 'Brave Search API 키 가져오기', + 'settings.general.webSearchTavilyFreeHint': '계정을 만들고 키를 복사하세요. 무료 플랜에는 1000 크레딧이 포함됩니다.', + 'settings.general.webSearchBraveFreeHint': '계정을 만들면 테스트용 무료 사용량으로 Search API 키를 생성할 수 있습니다.', + 'settings.general.webSearchHint': '자동은 Claude 모델 이름에는 네이티브 Claude 웹 검색을 사용하고, 그다음 Tavily와 Brave 키로 폴백합니다.', + 'settings.general.webSearchSave': '저장', + 'settings.general.uiZoom': 'UI 확대/축소', + 'settings.general.uiZoomDescription': '인터페이스 전체의 크기를 조정합니다.', + 'settings.general.uiZoomShortcutHint': '단축키가 더 빠릅니다:', + 'settings.general.uiZoomShortcutMac': 'macOS', + 'settings.general.uiZoomShortcutWindows': 'Windows / Linux', + 'settings.general.uiZoomShortcutResetHint': '0으로 확대/축소를 100%로 재설정합니다.', + 'settings.general.uiZoomReset': 'UI 확대/축소를 100%로 재설정', + + // ─── Empty Session ────────────────────────────────────── + 'empty.title': '새 세션', + 'empty.subtitle': '새 코딩 세션을 시작합니다. Claude가 프로젝트를 구축하고 디버깅하며 설계하도록 도울 준비가 되어 있습니다.', + 'empty.placeholder': '무엇이든 물어보세요...', + 'empty.addFiles': '파일 또는 사진 추가', + 'empty.slashCommands': '슬래시 명령', + 'empty.failedToCreate': '세션을 만들지 못했습니다', + 'empty.createError.workdirMissing': '프로젝트 폴더가 없거나 디렉터리가 아닙니다. 기존 프로젝트를 선택하고 다시 시도하세요.', + 'empty.createError.notGit': '이 프로젝트는 Git 저장소가 아니므로 브랜치 시작을 사용할 수 없습니다. 현재 폴더에서 시작하거나 Git 프로젝트를 선택하세요.', + 'empty.createError.branchNotFound': '선택한 브랜치가 더 이상 존재하지 않습니다. 프로젝트 컨텍스트를 새로 고치고 다른 브랜치를 선택하세요.', + 'empty.createError.dirtyWorktree': '현재 프로젝트에 커밋되지 않은 변경 사항이 있습니다. 브랜치 직접 전환이 차단되었습니다. "독립 worktree"를 사용하거나 먼저 변경 사항을 커밋/스태시하세요.', + 'empty.createError.branchCheckedOut': '해당 브랜치는 다른 worktree에서 이미 체크아웃되어 있습니다. "독립 worktree"를 사용하거나 다른 브랜치를 선택하세요.', + 'empty.createError.worktreeCreateFailed': '독립 worktree를 만들 수 없습니다. Git이 이 저장소에 쓸 수 있는지 확인한 후 다시 시도하세요. 세부 정보: {detail}', + 'empty.createError.switchFailed': '현재 프로젝트 브랜치를 전환할 수 없습니다. Git 오류를 확인하고 변경 사항을 안전하게 보관한 후 다시 시도하세요. 세부 정보: {detail}', + 'empty.createError.contextFailed': '이 Git 프로젝트를 검사할 수 없습니다. 저장소 상태를 확인하고 다시 시도하세요.', + + // ─── Repository Launch Controls ────────────────────────────────────── + 'repoLaunch.selectBranch': '브랜치 선택', + 'repoLaunch.searchBranch': '브랜치 검색', + 'repoLaunch.noBranch': '브랜치 없음', + 'repoLaunch.noBranchMatch': '일치하는 브랜치 없음', + 'repoLaunch.currentBranch': '현재 브랜치', + 'repoLaunch.localBranch': '로컬 브랜치', + 'repoLaunch.remoteBranch': '원격 브랜치', + 'repoLaunch.checkedOut': '다른 worktree에서 체크아웃됨', + 'repoLaunch.worktreeCurrent': '현재 worktree', + 'repoLaunch.worktreeIsolated': '독립 worktree', + 'repoLaunch.selectWorktree': 'worktree 모드 선택', + 'repoLaunch.missingWorkdir': '작업 디렉터리가 없습니다.', + 'repoLaunch.dirtyWarning': '커밋되지 않은 변경 사항이 감지되었습니다. 직접 전환이 차단될 수 있습니다. 이 폴더를 건드리지 않고 계속하려면 독립 worktree를 사용하세요.', + 'repoLaunch.checkedOutWarning': '선택한 브랜치는 다른 worktree에서 이미 체크아웃되어 있습니다. Git에 의해 직접 시작이 차단될 수 있습니다. 디렉터리 변경을 피하려면 "독립 worktree"를 사용하세요.', + + // ─── Chat Input ────────────────────────────────────── + 'chat.placeholder': '편집, 디버그 또는 설명을 Claude에 요청...', + 'chat.placeholderMissing': '이 세션은 없는 작업 공간을 가리킵니다. 새 세션을 만들거나 다른 프로젝트를 선택하세요.', + 'chat.addFiles': '파일 또는 사진 추가', + 'chat.dropFilesTitle': '여기에 파일을 드롭하세요', + 'chat.dropFilesHint': '파일 경로로 첨부됩니다.', + 'chat.workspaceReferencesOnly': '작업 공간 참조 {count}개를 추가했습니다', + 'chat.contextReferencesOnly': '참조 {count}개를 추가했습니다', + 'chat.addSelectionToChat': '채팅에 추가', + 'chat.branchFromHere': '새 대화 분기', + 'chat.branchSuccess': '분기된 대화 "{title}"을(를) 만들었습니다.', + 'chat.branchError': '이 메시지에서 분기할 수 없습니다. 세부 정보: {detail}', + 'chat.userMessageReference': '사용자 메시지', + 'chat.assistantMessageReference': '어시스턴트 메시지', + 'chat.slashCommands': '슬래시 명령', + 'chat.goalEvent.created': '목표 설정됨', + 'chat.goalEvent.replaced': '목표 설정됨', + 'chat.goalEvent.statusTitle': '목표 상태', + 'chat.goalEvent.paused': '목표 일시 중지됨', + 'chat.goalEvent.resumed': '목표 재개됨', + 'chat.goalEvent.completed': '목표 완료됨', + 'chat.goalEvent.cleared': '목표 지워짐', + 'chat.goalEvent.message': '목표 업데이트', + 'chat.goalEvent.objective': '목표: {value}', + 'chat.goalEvent.statusValue': '상태: {value}', + 'chat.goalEvent.budget': '예산: {value}', + 'chat.goalEvent.continuations': '연속 실행: {value}', + 'chat.compactSummary.compacting': '컨텍스트 압축 중', + 'chat.compactSummary.title': '컨텍스트가 압축됨', + 'chat.compactSummary.autoTitle': '컨텍스트가 자동으로 압축됨', + 'chat.compactSummary.manualTitle': '컨텍스트가 수동으로 압축됨', + 'chat.compactSummary.trigger.manual': '수동', + 'chat.compactSummary.trigger.auto': '자동', + 'chat.compactSummary.tokens': '압축 전 {count} 토큰', + 'chat.compactSummary.messages': '{count}개의 메시지를 요약했습니다', + 'chat.activeGoal.title': '활성 목표', + 'chat.activeGoal.running': '루프 실행 중', + 'chat.activeGoal.active': '활성', + 'chat.activeGoal.paused': '일시 중지됨', + 'chat.activeGoal.completed': '완료됨', + 'chat.activeGoal.budget': '예산 {value}', + 'chat.activeGoal.continuations': '연속 실행 {value}', + 'chat.activeGoal.elapsed': '경과 {value}', + 'chat.backgroundAgents.title': '백그라운드 에이전트', + 'chat.backgroundAgents.count': '{count}개 활성 또는 최근', + 'chat.backgroundAgents.agent': '에이전트', + 'chat.backgroundTasks.command': '백그라운드 명령', + 'chat.backgroundTasks.workflow': '백그라운드 워크플로', + 'chat.backgroundTasks.task': '백그라운드 작업', + 'chat.backgroundAgents.tokens': '{count} 토큰', + 'chat.backgroundAgents.status.running': '실행 중', + 'chat.backgroundAgents.status.completed': '완료', + 'chat.backgroundAgents.status.failed': '실패', + 'chat.backgroundAgents.status.stopped': '중지됨', + 'slash.mcp.title': '사용 가능한 MCP 도구', + 'slash.mcp.subtitle': '이 채팅 컨텍스트에서 사용 가능한 전역 및 현재 프로젝트 MCP 서버입니다.', + 'slash.mcp.subtitleWithProject': '다음의 전역 및 프로젝트 MCP를 표시 중: {path}', + 'slash.mcp.emptyTitle': '사용 가능한 MCP 서버가 없습니다', + 'slash.mcp.emptyBody': '이 채팅 컨텍스트에서 사용 가능한 전역 또는 프로젝트 MCP 서버가 없습니다.', + 'slash.mcp.projectBadge': '프로젝트: {name}', + 'slash.skills.title': '사용 가능한 스킬', + 'slash.skills.subtitle': '현재 컨텍스트에서 사용 가능한, 사용자가 호출할 수 있는 스킬입니다.', + 'slash.skills.subtitleWithProject': '다음의 스킬을 표시 중: {path}', + 'slash.skills.emptyTitle': '사용 가능한 스킬이 없습니다', + 'slash.skills.emptyBody': '이 컨텍스트에서 사용자가 호출할 수 있는 스킬을 찾을 수 없습니다.', + 'slash.plugins.title': '플러그인', + 'slash.plugins.subtitle': '플러그인 관리가 이 슬래시 명령 화면으로 이동합니다.', + 'slash.plugins.emptyTitle': '플러그인 패널 곧 제공', + 'slash.plugins.emptyBody': '이 공유 슬래시 명령 패널은 현재 연결되어 있습니다. 플러그인 데이터는 다음에 연결됩니다.', + 'slash.help.title': '슬래시 명령', + 'slash.help.subtitle': '에이전트 워크플로를 실행하거나, 세션 상태를 확인하거나, 데스크톱 패널을 엽니다.', + 'slash.help.group.context': '컨텍스트', + 'slash.help.group.project': '프로젝트', + 'slash.help.group.desktop': '데스크톱', + 'slash.help.group.more': '더 보기', + 'slash.help.moreAvailable': '{count}개의 명령을 더 사용할 수 있습니다. /를 입력하여 전체 명령 목록을 검색하세요.', + 'slash.inspector.title': '세션 검사기', + 'slash.inspector.close': '세션 검사기 닫기', + 'slash.inspector.loading': '세션 데이터 불러오는 중', + 'slash.inspector.error.noActiveSession': '선택된 활성 세션이 없습니다.', + 'slash.inspector.error.unavailable': '세션 검사기 데이터를 사용할 수 없습니다. /api/sessions/:id/inspection이 로드되도록 데스크톱 서버를 다시 시작하세요.', + 'slash.inspector.tab.status': '상태', + 'slash.inspector.tab.usage': '사용량', + 'slash.inspector.tab.context': '컨텍스트', + 'slash.inspector.status.cliStatus': 'CLI 상태', + 'slash.inspector.status.running': '실행 중', + 'slash.inspector.status.notRunning': '실행되지 않음', + 'slash.inspector.status.activeModel': '활성 모델', + 'slash.inspector.status.unknown': '알 수 없음', + 'slash.inspector.status.mcpConnections': 'MCP 연결', + 'slash.inspector.status.connected': '연결됨', + 'slash.inspector.status.failed': '실패', + 'slash.inspector.status.registeredTools': '등록된 도구', + 'slash.inspector.status.commands': '명령', + 'slash.inspector.status.sessionMetadata': '세션 메타데이터', + 'slash.inspector.status.version': '버전', + 'slash.inspector.status.sessionId': '세션 ID', + 'slash.inspector.status.workingDirectory': '작업 디렉터리', + 'slash.inspector.status.permissionMode': '권한 모드', + 'slash.inspector.status.authToken': '인증 토큰', + 'slash.inspector.status.outputStyle': '출력 스타일', + 'slash.inspector.status.default': '기본값', + 'slash.inspector.status.mcpServers': 'MCP 서버', + 'slash.inspector.status.refresh': '새로 고침', + 'slash.inspector.status.contextWindow': '컨텍스트 창', + 'slash.inspector.usage.emptyTitle': '아직 사용량 데이터가 없습니다', + 'slash.inspector.usage.emptyBody': 'CLI 세션이 시작되고 최소 한 턴이 완료되면 사용량이 표시됩니다.', + 'slash.inspector.usage.contextSnapshotNotice': '현재 컨텍스트 스냅샷의 토큰 사용량을 표시합니다. 사용량은 컨텍스트를 가져오는 대로 동적으로 업데이트됩니다.', + 'slash.inspector.usage.transcriptNotice': '세션 기록에서 재구성한 사용량을 표시합니다. API 소요 시간은 현재 실행 중인 CLI 프로세스에서만 사용할 수 있습니다.', + 'slash.inspector.usage.unknownCost': '하나 이상의 모델 요금이 알려져 있지 않아 비용이 부정확할 수 있습니다.', + 'slash.inspector.usage.totalCost': '총 비용', + 'slash.inspector.usage.source': '소스', + 'slash.inspector.usage.source.contextSnapshot': '컨텍스트 스냅샷', + 'slash.inspector.usage.source.transcript': '기록', + 'slash.inspector.usage.source.currentProcess': '현재 프로세스', + 'slash.inspector.usage.apiDuration': 'API 소요 시간', + 'slash.inspector.usage.wallDuration': '실제 시간', + 'slash.inspector.usage.usageSpan': '사용 기간', + 'slash.inspector.usage.codeChanges': '코드 변경', + 'slash.inspector.usage.input': '입력', + 'slash.inspector.usage.output': '출력', + 'slash.inspector.usage.cacheReadWrite': '캐시 읽기 / 쓰기', + 'slash.inspector.usage.webSearch': '웹 검색', + 'slash.inspector.usage.byModel': '모델별 사용량', + 'slash.inspector.usage.tokens': '토큰', + 'slash.inspector.usage.noModelTitle': '모델 사용량 없음', + 'slash.inspector.usage.noModelBody': '모델 응답이 기록되면 여기에 토큰 사용량이 표시됩니다.', + 'slash.inspector.context.loading': '컨텍스트 데이터 불러오는 중', + 'slash.inspector.context.emptyTitle': '아직 컨텍스트 데이터가 없습니다', + 'slash.inspector.context.emptyBody': '컨텍스트 사용량에는 활성 CLI 세션이 필요합니다.', + 'slash.inspector.context.windowUsage': '컨텍스트 창 사용량', + 'slash.inspector.context.used': '사용됨', + 'slash.inspector.context.free': '여유', + 'slash.inspector.context.messages': '메시지', + 'slash.inspector.context.assistant': '어시스턴트', + 'slash.inspector.context.toolResults': '도구 결과', + 'slash.inspector.context.context': '컨텍스트', + 'slash.inspector.context.categoryTitle': '카테고리별 예상 사용량', + 'slash.inspector.context.noCategoriesTitle': '컨텍스트 카테고리 없음', + 'slash.inspector.context.noCategoriesBody': 'CLI가 컨텍스트 분석을 보고하면 컨텍스트 카테고리가 표시됩니다.', + 'slash.inspector.context.memoryFiles': '메모리 파일', + 'slash.inspector.context.noMemoryFiles': '이 세션에는 메모리 파일이 로드되어 있지 않습니다.', + 'slash.inspector.context.openMemory': '메모리 열기', + 'contextIndicator.ariaLabel': '컨텍스트 사용량 {percent}', + 'contextIndicator.pendingAria': '컨텍스트 사용량이 계산되지 않음', + 'contextIndicator.loadingAria': '컨텍스트 사용량 불러오는 중', + 'contextIndicator.unavailableAria': '컨텍스트 사용량을 사용할 수 없음', + 'contextIndicator.title': '컨텍스트', + 'contextIndicator.modelUnknown': '알 수 없는 모델', + 'contextIndicator.used': '사용됨', + 'contextIndicator.free': '여유', + 'contextIndicator.window': '창', + 'contextIndicator.loading': '컨텍스트 사용량 불러오는 중...', + 'contextIndicator.pendingDetail': '컨텍스트 사용량은 세션 시작 후에 계산됩니다.', + 'contextIndicator.unavailable': '없음', + 'contextIndicator.unavailableDetail': '이 세션에서는 컨텍스트 사용량을 사용할 수 없습니다.', + 'contextIndicator.updatedUnknown': '아직 새로 고치지 않음', + 'contextIndicator.updatedNow': '방금 업데이트됨', + 'contextIndicator.updatedMinutes': '{count}분 전 업데이트됨', + 'contextIndicator.estimate': '추정', + 'chat.navigate': '이동', + 'chat.select': '선택', + 'chat.dismiss': '닫기', + 'chat.stopTitle': '생성 중지 (Cmd+.)', + 'chat.jumpToLatest': '최신', + 'chat.memorySavedTitle': '{count}개의 메모리 파일을 저장했습니다', + 'chat.memorySavedFromToolsTitle': '{count}개의 메모리 항목을 저장했습니다', + 'chat.memoryReferencedTitle': '{count}개의 메모리 참조', + 'chat.memoryOpenSettings': '메모리 열기', + 'chat.memoryMoreFiles': '+{count}개', + 'chat.memoryTechnicalDetails': '도구 세부 정보', + 'chat.rewindSuccessWithCode': '{count}개의 메시지를 되감고 추적된 파일을 복원했습니다.', + 'chat.rewindSuccessConversationOnly': '{count}개의 메시지를 되감았습니다. 이 턴에는 사용할 수 있는 파일 체크포인트가 없었습니다.', + 'chat.turnChangesTitle': '{count}개의 파일이 변경됨', + 'chat.turnChangesLatestCardLabel': '턴에서 변경된 파일', + 'chat.turnChangesHistoricalCardLabel': '턴에서 변경된 파일', + 'chat.turnChangesLatestSubtitle': '현재 턴 체크포인트', + 'chat.turnChangesHistoricalSubtitle': '저장된 턴 체크포인트', + 'chat.turnChangesLatestUndo': '현재 턴 실행 취소', + 'chat.turnChangesHistoricalUndo': '이 턴 이전으로 되감기', + 'chat.turnChangesUndoing': '실행 취소 중...', + 'chat.turnChangesLatestUndoAria': '현재 턴 변경 사항 실행 취소', + 'chat.turnChangesHistoricalUndoAria': '이 턴 이전으로 되감기', + 'chat.turnChangesLatestConfirmTitle': '현재 턴을 실행 취소하시겠습니까?', + 'chat.turnChangesHistoricalConfirmTitle': '이 턴 이전으로 되감으시겠습니까?', + 'chat.turnChangesLatestConfirmBody': '최신 어시스턴트 응답을 되감고 이 턴의 추적된 파일을 복원합니다.', + 'chat.turnChangesHistoricalConfirmBody': '대화를 이 턴 이전으로 되감고 해당 체크포인트의 추적된 파일을 복원합니다.', + 'chat.turnChangesLatestConfirmUndo': '현재 턴 실행 취소', + 'chat.turnChangesHistoricalConfirmUndo': '이 턴 이전으로 되감기', + 'chat.turnChangesOpenInWorkspaceAria': '{path}을(를) 작업 공간에서 열기', + 'chat.turnChangesShowMore': '{count}개의 파일 더 보기', + 'chat.turnChangesShowLess': '적게 보기', + + // ─── Streaming Indicator ────────────────────────────────────── + 'streaming.thinking': '사고 중', + 'streaming.running': '실행 중', + 'streaming.working': '작업 중', + + // ─── Permission Dialog ────────────────────────────────────── + 'permission.allowEditFile': 'Claude가 {fileName}을(를) {toolName}하도록 허용하시겠습니까?', + 'permission.allowEditFileGeneric': 'Claude가 이 파일을 {toolName}하도록 허용하시겠습니까?', + 'permission.allowBash': 'Claude가 이 명령을 실행하도록 허용하시겠습니까?', + 'permission.allowTool': 'Claude가 {toolName}을(를) 사용하도록 허용하시겠습니까?', + 'permission.awaitingApproval': '승인 대기 중', + 'permission.responded': '응답함', + 'permission.allow': '허용', + 'permission.allowForSession': '이 세션에서 허용', + 'permission.deny': '거부', + 'permission.hideDetails': '세부 정보 숨기기', + 'permission.showFullInput': '전체 입력 표시', + 'permission.replacingContent': '파일 내용 교체 중', + + // ─── Computer Use Approval ────────────────────────────────────── + 'computerUseApproval.titleApps': '컴퓨터 사용이 이 앱들을 제어하려고 합니다', + 'computerUseApproval.titleTcc': '컴퓨터 사용에 macOS 권한이 필요합니다', + 'computerUseApproval.reason': 'Claude가 요청하는 이유', + 'computerUseApproval.allow': '이 세션에서 허용', + 'computerUseApproval.deny': '거부', + 'computerUseApproval.alreadyGranted': '이 세션에서는 이미 허용됨', + 'computerUseApproval.notInstalled': '앱이 설치되지 않음', + 'computerUseApproval.sensitiveApp': '이 앱은 민감한 것으로 처리되며 추가 검토가 필요합니다.', + 'computerUseApproval.alsoRequested': '함께 요청됨', + 'computerUseApproval.hideWhileWorking': 'Claude가 작업하는 동안 다른 {count}개의 앱이 숨겨집니다.', + 'computerUseApproval.hideWhileWorkingRestore': 'Claude가 작업하는 동안 다른 {count}개의 앱이 숨겨졌다가 Claude가 완료되면 복원됩니다.', + 'computerUseApproval.accessibility': '접근성', + 'computerUseApproval.screenRecording': '화면 기록', + 'computerUseApproval.granted': '허용됨', + 'computerUseApproval.notGranted': '허용되지 않음', + 'computerUseApproval.openAccessibility': '접근성 열기', + 'computerUseApproval.openScreenRecording': '화면 기록 열기', + 'computerUseApproval.tryAgain': '다시 시도', + 'computerUseApproval.tccHint': '시스템 설정에서 부족한 권한을 허용한 후 돌아와 "다시 시도"를 선택하세요.', + 'computerUseApproval.tryAgainHint': '다시 시도하면 Claude에 제어가 돌아가 macOS 권한 변경이 적용된 후 request_access를 한 번 더 호출할 수 있습니다.', + + // ─── Ask User Question ────────────────────────────────────── + 'question.needsInput': 'Claude가 입력을 필요로 합니다', + 'question.answered': '응답함', + 'question.completed': '완료', + 'question.customResponse': '또는 직접 응답을 입력하세요:', + 'question.typePlaceholder': '답변 입력...', + 'question.submit': '제출', + 'question.answeredPrefix': '응답: ', + 'question.resultPrefix': '결과: ', + + // ─── Thinking Block ────────────────────────────────────── + 'thinking.label': '사고 중', + 'thinking.labelDone': '사고 완료', + + // ─── Tool Calls ────────────────────────────────────── + 'tool.errorOutput': '오류 출력', + 'tool.toolOutput': '도구 출력', + 'tool.toolInput': '도구 입력', + 'tool.partialInput': '부분 입력', + 'tool.writerPreview': 'Writer', + 'tool.writerPreviewLatest': '{total}줄 중 최신 {visible}줄 표시 중', + 'tool.generatingContent': '콘텐츠 생성 중', + 'tool.preparingEdit': '편집 준비 중', + 'tool.preparingTool': '도구 준비 중', + 'tool.readFileContents': '파일 내용 읽기', + 'tool.createFile': '파일 만들기', + 'tool.updateFileContents': '파일 내용 업데이트', + 'tool.linesChanged': '{count}줄 변경됨', + 'tool.linesCreated': '{count}줄 생성됨', + 'tool.linesOutput': '{count}줄 출력됨', + 'tool.result': '{toolName} 결과', + 'tool.resultGeneric': '도구 결과', + 'tool.error': '오류', + 'tool.success': '성공', + 'tool.showLess': '적게 보기', + 'tool.showMore': '{count}자 더 보기', + + // ─── Tool Group Verbs ────────────────────────────────────── + 'toolGroup.readOne': '파일 1개 읽음', + 'toolGroup.readMany': '파일 {count}개 읽음', + 'toolGroup.createdOne': '파일을 만들었습니다', + 'toolGroup.createdMany': '파일 {count}개를 만들었습니다', + 'toolGroup.editedOne': '파일을 편집했습니다', + 'toolGroup.editedMany': '파일 {count}개를 편집했습니다', + 'toolGroup.ranOne': '명령을 실행했습니다', + 'toolGroup.ranMany': '명령 {count}개를 실행했습니다', + 'toolGroup.foundFiles': '파일을 찾았습니다', + 'toolGroup.searchedOne': '코드를 검색했습니다', + 'toolGroup.searchedMany': '패턴 {count}개를 검색했습니다', + 'toolGroup.agentOne': '에이전트 1개를 디스패치했습니다', + 'toolGroup.agentMany': '에이전트 {count}개를 디스패치했습니다', + 'agentStatus.starting': '시작 중', + 'agentStatus.running': '실행 중', + 'agentStatus.done': '완료', + 'agentStatus.failed': '실패', + 'agentStatus.stopped': '중지됨', + 'agentStatus.noActivity': '아직 도구 활동이 없습니다', + 'agentStatus.viewResult': '결과 보기', + 'agentStatus.resultTitle': '에이전트 결과', + 'toolGroup.searchedWeb': '웹을 검색했습니다', + 'toolGroup.fetchedOne': '페이지 1개를 가져왔습니다', + 'toolGroup.fetchedMany': '페이지 {count}개를 가져왔습니다', + + // ─── Tasks ────────────────────────────────────── + 'tasks.title': '작업', + 'tasks.completed': '완료된 작업', + 'tasks.dismissCompleted': '완료된 작업 숨기기', + 'tasks.newTask': '+ 새 작업', + 'tasks.emptyTitle': '아직 예약된 작업이 없습니다.', + 'tasks.emptyDesc': '반복 작업을 만들어 엔지니어링 워크플로를 자동화하세요.', + 'tasks.createNew': '새 작업 만들기', + 'tasks.totalTasks': '총 작업', + 'tasks.active': '활성', + 'tasks.disabled': '사용 안 함', + + // ─── New Task Modal ────────────────────────────────────── + 'newTask.title': '새 예약 작업', + 'newTask.localWarning': '로컬 작업은 컴퓨터가 켜져 있는 동안에만 실행됩니다.', + 'newTask.fullPermissions': '모든 권한', + 'newTask.name': '이름', + 'newTask.namePlaceholder': 'daily-code-review', + 'newTask.description': '설명', + 'newTask.descPlaceholder': '어제 커밋을 검토하고 우려되는 점을 표시', + 'newTask.frequency': '빈도', + 'newTask.everyNMinutes': 'N분마다', + 'newTask.everyNHours': 'N시간마다', + 'newTask.daily': '매일', + 'newTask.weekdays': '평일(월~금)', + 'newTask.specificDays': '특정 요일', + 'newTask.monthly': '매월', + 'newTask.customCron': '사용자 지정 cron 식', + 'newTask.intervalMinutes': '{n}분마다', + 'newTask.intervalHours': '{n}시간마다', + 'newTask.atMinute': ':{m}분에', + 'newTask.onMonthDay': '매월 {d}일에', + 'newTask.cronFormatHint': '형식: 분 시 일 월 요일', + 'newTask.invalidCron': '잘못된 cron 식', + 'newTask.daySun': '일', + 'newTask.dayMon': '월', + 'newTask.dayTue': '화', + 'newTask.dayWed': '수', + 'newTask.dayThu': '목', + 'newTask.dayFri': '금', + 'newTask.daySat': '토', + 'newTask.delayNote': '예약 작업은 서버 성능을 위해 몇 분의 무작위 지연을 사용합니다.', + 'newTask.create': '작업 만들기', + 'newTask.promptPlaceholder': '지난 24시간의 커밋을 확인하세요. 무엇이 바뀌었는지 요약하고, 위험한 패턴이나 누락된 테스트를 지적하며, 후속 조치가 필요한 점을 기록하세요.', + 'newTask.notification': '알림', + 'newTask.notifyOnComplete': '완료 시 푸시 알림', + 'newTask.notifyChannels': '알림 채널', + 'newTask.notifyHint': '작업이 완료되면 OS 기본 데스크톱 알림 또는 IM 메시지를 보냅니다.', + 'newTask.notifyDesktop': '데스크톱', + 'newTask.notConfigured': '구성되지 않음', + 'newTask.noChannelConfigured': '아직 구성된 IM 채널이 없습니다. 설정 → IM 어댑터 에서 설정하세요.', + 'newTask.noChannelSelected': '하나 이상의 알림 채널을 선택하세요.', + + // ─── Cron Descriptions ────────────────────────────────────── + 'cron.everyMinute': '매분 실행', + 'cron.everyNMinutes': '{n}분마다 실행', + 'cron.everyHour': '매시간 실행', + 'cron.everyNHours': '{n}시간마다 실행', + 'cron.everyNHoursAtMinute': '{n}시간마다 :{m}분에 실행', + 'cron.dailyAt': '매일 {time}에 실행', + 'cron.weekdaysAt': '평일 {time}에 실행', + 'cron.specificDaysAt': '매주 {days} {time}에 실행', + 'cron.monthlyAt': '매월 {day}일 {time}에 실행', + 'cron.customSchedule': '사용자 지정: {cron}', + 'cron.dow.0': '일', + 'cron.dow.1': '월', + 'cron.dow.2': '화', + 'cron.dow.3': '수', + 'cron.dow.4': '목', + 'cron.dow.5': '금', + 'cron.dow.6': '토', + + // ─── Task Actions & Logs ────────────────────────────────────── + 'tasks.runNow': '지금 실행', + 'tasks.confirmRun': '이 작업을 즉시 실행하시겠습니까?', + 'tasks.confirmDisable': '이 예약 작업을 사용 안 함으로 설정하시겠습니까?', + 'tasks.confirmEnable': '이 예약 작업을 사용하시겠습니까?', + 'tasks.confirmDelete': '이 작업과 모든 로그를 영구적으로 삭제하시겠습니까?', + 'tasks.running': '실행 중...', + 'tasks.viewLogs': '로그', + 'tasks.logsTitle': '실행 로그', + 'tasks.noLogs': '아직 실행 로그가 없습니다', + 'tasks.runStatus.running': '실행 중', + 'tasks.runStatus.completed': '완료', + 'tasks.runStatus.failed': '실패', + 'tasks.runStatus.timeout': '시간 초과', + 'tasks.duration': '{s}초', + 'tasks.viewOutput': '요약', + 'tasks.hideOutput': '숨기기', + 'tasks.close': '닫기', + 'tasks.edit': '편집', + 'tasks.editTitle': '예약 작업 편집', + 'tasks.saveChanges': '변경 사항 저장', + 'tasks.openSession': '대화 보기', + 'tasks.createdAt': '생성: ', + 'tasks.lastRunAt': '마지막 실행: ', + 'tasks.outputHintSession': '"대화 보기"를 클릭하면 세션 보기에서 전체 출력을 볼 수 있습니다.', + 'tasks.noOutputText': '사용할 수 있는 출력이 없습니다.', + + // ─── Prompt Editor ────────────────────────────────────── + 'promptEditor.worktree': 'worktree', + 'promptEditor.bypassWarning': '우회 모드는 시스템에 대한 전체 액세스를 허용합니다', + 'promptEditor.within': '범위:', + 'promptEditor.selectFolder': '— 범위를 제한할 폴더 선택', + + // ─── Permission Mode Selector ────────────────────────────────────── + 'permMode.executionPermissions': '실행 권한', + 'permMode.askPermissions': '권한 확인', + 'permMode.askPermDesc': 'CLI가 요청할 때 파일 편집과 위험도가 높은 명령을 확인합니다', + 'permMode.autoAccept': '편집 자동 수락', + 'permMode.autoAcceptDesc': 'Claude가 확인 없이 디스크에 씁니다', + 'permMode.planMode': '계획 모드', + 'permMode.planModeDesc': '설계 및 추론만, 파일은 다루지 않음', + 'permMode.bypass': '권한 우회', + 'permMode.bypassDesc': '셸과 파일 시스템에 대한 전체 도구 액세스', + 'permMode.dontAsk': '확인 안 함', + 'permMode.enableBypassTitle': '권한 우회를 사용하시겠습니까?', + 'permMode.enableBypassSubtitle': '이렇게 하면 시스템에 대한 전체 액세스가 허용됩니다', + 'permMode.enableBypassBody': 'Claude는 다음 범위 내에서 셸 명령 실행과 파일 수정에 무제한 액세스를 갖게 됩니다:', + 'permMode.permReadWrite': '모든 파일 읽기, 쓰기, 삭제', + 'permMode.permShell': '임의의 셸 명령 실행', + 'permMode.permPackages': '패키지 설치 또는 제거', + 'permMode.enableBypassBtn': '우회 사용', + + // Mode labels (compact, for chips) + 'permMode.label.default': '권한 확인', + 'permMode.label.acceptEdits': '자동 수락', + 'permMode.label.plan': '계획 모드', + 'permMode.label.bypassPermissions': '우회', + 'permMode.label.dontAsk': '확인 안 함', + + // ─── Model Selector ────────────────────────────────────── + 'model.selectModel': '모델 선택', + 'model.configuration': '모델 구성', + 'model.effort': '노력', + + // ─── Directory Picker ────────────────────────────────────── + 'dirPicker.selectProject': '프로젝트 선택...', + 'dirPicker.recent': '최근', + 'dirPicker.noRecent': '최근 프로젝트가 없습니다', + 'dirPicker.chooseFolder': '다른 폴더 선택', + 'dirPicker.chooseProjectFolder': '프로젝트 폴더 선택', + 'dirPicker.useThisFolder': '이 폴더 사용', + 'dirPicker.noSubdirs': '하위 디렉터리가 없습니다', + + // ─── File Search ────────────────────────────────────── + 'fileSearch.searching': '검색 중...', + 'fileSearch.noMatch': '일치하는 파일이 없습니다', + 'fileSearch.noFiles': '이 디렉터리에 파일이 없습니다', + 'fileSearch.accessDenied': '이 디렉터리에 접근할 수 없습니다', + 'fileSearch.loadFailed': '디렉터리를 불러오지 못했습니다', + 'fileSearch.navigate': '이동', + 'fileSearch.attach': '첨부', + 'fileSearch.select': '선택', + 'fileSearch.open': '폴더 열기', + 'fileSearch.close': '닫기', + 'fileSearch.directory': '폴더', + 'fileSearch.currentDirectory': '현재 폴더', + 'fileSearch.folderTag': '폴더', + 'fileSearch.fileTag': '파일', + 'fileSearch.openFolder': '폴더 열기', + + // ─── Teams ────────────────────────────────────── + 'teams.backToLeader': '\u2190 \ub9ac\ub354\ub85c \ub3cc\uc544\uac00\uae30', + 'teams.viewing': '\ubcf4\ub294 \uc911:', + 'teams.transcript': '기록', + 'teams.noMessages': '아직 메시지가 없습니다', + 'teams.team': '팀:', + 'teams.members': '멤버', + 'teams.working': '작업 중...', + 'teams.thinking': '사고 중...', + 'teams.running': '실행 중', + 'teams.leader': 'team-lead', + 'teams.memberPlaceholder': '이 팀원에게 직접 메시지 보내기...', + 'teams.memberSessionHint': '여기서 보내는 메시지는 이 팀원에게 바로 전달되며, 기록이 업데이트되는 것을 보면서 주고받을 수 있습니다.', + + // ─── Scheduled Tasks Pages ────────────────────────────────────── + 'scheduledPage.title': '예약 작업', + 'scheduledPage.subtitle': '작업을 예약 실행하거나 필요할 때 실행하세요. 기존 세션에서 {code}을(를) 입력하면 만들 수 있습니다.', + 'scheduledPage.desktopNotice': '예약 작업은 데스크톱 앱이 열려 있는 동안에만 실행됩니다. 작업이 제시간에 실행되도록 앱을 계속 실행해 두세요.', + 'scheduledPage.oldSubtitle': '자동화된 운영 루틴과 백그라운드 유지 관리를 관리합니다.', + 'scheduledPage.executionMode': '실행 모드', + 'scheduledPage.localMode': '로컬 모드', + 'scheduledPage.remoteMode': '원격 모드', + 'scheduledPage.nextRun': '다음 실행', + 'scheduledPage.systemHealth': '시스템 상태', + 'scheduledPage.activeSession': '활성 세션', + 'scheduledPage.colTaskName': '작업 이름', + 'scheduledPage.colFrequency': '빈도', + 'scheduledPage.colLastResult': '마지막 결과', + 'scheduledPage.colNextExecution': '다음 실행', + 'scheduledPage.colActions': '작업', + 'scheduledPage.endOfList': '예약 목록의 끝', + 'scheduledPage.pausedTasks': '다른 9개의 작업이 현재 유지 관리를 위해 일시 중지되었거나 사용 안 함으로 설정되어 있습니다.', + 'scheduledPage.recentLogs': '최근 출력 로그', + 'scheduledPage.viewArtifacts': '전체 결과물 보기', + 'scheduledPage.resourceAllocation': '리소스 할당', + 'scheduledPage.cpuCapacity': 'CPU 용량', + 'scheduledPage.memoryLoad': '메모리 부하', + 'scheduledPage.connectedLocal': '로컬 노드에 연결됨', + 'scheduledPage.thisMonth': '이번 달 {count}개', + + // ─── Update Checker ────────────────────────────────────── + 'update.available': 'v{version} 사용 가능', + 'update.availableLabel': '사용 가능', + 'update.checking': '업데이트 확인 중...', + 'update.checkNow': '지금 확인', + 'update.checkedAt': '마지막 확인 {time}', + 'update.currentVersionUnknown': '알 수 없음', + 'update.newVersion': '새 버전 v{version} 사용 가능', + 'update.downloading': '다운로드 중...', + 'update.downloaded': '업데이트를 다운로드했습니다. 사용할 준비가 되면 다시 시작하세요.', + 'update.idle': '업데이트를 확인하여 설치된 버전을 최신 GitHub Release와 비교합니다.', + 'update.installAndRestart': '설치하고 다시 시작', + 'update.installing': '업데이트 설치 중...', + 'update.now': '지금 업데이트', + 'update.later': '나중에', + 'update.progress': '업데이트 다운로드 중... {progress}%', + 'update.progressBytes': '업데이트 다운로드 중... {downloaded} 다운로드됨', + 'update.proxyAdvanced': '고급 업데이트 프록시', + 'update.proxyModeManual': '수동 프록시', + 'update.proxyModeManualDescription': '제공한 로컬 HTTP 프록시 주소를 사용합니다.', + 'update.proxyModeSystem': '시스템 프록시', + 'update.proxyModeSystemDescription': 'OS의 HTTP/HTTPS 프록시를 자동으로 사용합니다.', + 'update.proxySave': '저장', + 'update.proxyScopeHint': '이것은 앱 업데이트 확인과 다운로드에만 영향을 줍니다.', + 'update.proxyUrl': '프록시 URL', + 'update.proxyUrlHint': 'HTTP 및 HTTPS 프록시 URL을 지원합니다. 예: http://127.0.0.1:7890.', + 'update.proxyUrlInvalid': 'HTTP 또는 HTTPS 프록시 URL을 입력하세요.', + 'update.proxyUrlRequired': '프록시 URL을 입력하세요.', + 'update.releaseNotes': '릴리스 노트', + 'update.readyBody': 'v{version}을(를) 다운로드했습니다. 사용할 준비가 되면 다시 시작하세요.', + 'update.readyTitle': '업데이트 준비 완료', + 'update.restarting': '업데이트를 완료하기 위해 다시 시작 중...', + 'update.upToDate': 'v{version}은(는) 최신입니다.', + 'update.failed': '업데이트에 실패했습니다: {error}', + + // ─── Active Session ────────────────────────────────────── + 'session.untitled': '제목 없는 세션', + 'session.active': '세션 활성', + 'session.lastUpdated': '마지막 업데이트 {time}', + 'session.messages': '{count}개의 메시지', + 'session.historyLoadFailed': '세션 기록을 불러오지 못했습니다.', + 'session.workspaceUnavailable': '작업 공간을 사용할 수 없습니다: {dir}', + 'session.timeJustNow': '방금', + 'session.timeMinutes': '{n}분 전', + 'session.timeHours': '{n}시간 전', + 'session.timeDays': '{n}일 전', + + // ─── App Shell ────────────────────────────────────── + 'app.serverFailed': '로컬 서버를 시작하지 못했습니다', + 'app.serverFailedHint': '문제를 신고할 때 이 진단 패널의 스크린샷을 첨부해 주세요.', + 'app.startupError': '시작 오류', + 'app.serverLogs': '서버 로그', + 'app.copyDiagnostics': '진단 정보 복사', + 'app.copiedDiagnostics': '복사됨', + 'app.launching': '로컬 작업 공간을 시작하는 중...', + + // ─── Error Codes ────────────────────────────────────── + 'error.CLI_NOT_RUNNING': 'CLI 프로세스가 실행되고 있지 않습니다. 세션이 종료되었거나 프로세스가 충돌했을 수 있습니다.', + 'error.CLI_START_FAILED': 'CLI 프로세스를 시작하지 못했습니다.', + 'error.CLI_AUTH_REQUIRED': '인증이 필요합니다. 로그인하세요.', + 'error.CLI_SESSION_CONFLICT': '세션이 이미 다른 프로세스에서 사용 중입니다.', + 'error.CLI_SPAWN_FAILED': 'CLI 하위 프로세스를 생성하지 못했습니다.', + 'error.CLI_ERROR': '처리 중 오류가 발생했습니다.', + 'error.WORKDIR_INVALID': '작업 디렉터리가 잘못되었거나 존재하지 않습니다.', + 'error.PARSE_ERROR': '메시지 형식이 잘못되었습니다.', + 'error.UNKNOWN_TYPE': '알 수 없는 메시지 유형입니다.', + 'error.BAD_REQUEST': '잘못된 요청입니다.', + 'error.NOT_FOUND': '리소스를 찾을 수 없습니다.', + 'error.INTERNAL_ERROR': '서버 내부 오류입니다.', + + // ─── Business Errors ────────────────────────────────────── + 'businessError.pdf_too_large': 'PDF가 선택한 모델에 비해 너무 큽니다. 텍스트로 변환하거나 더 작은 PDF를 사용하세요.', + 'businessError.pdf_password_protected': 'PDF가 비밀번호로 보호되어 있습니다. 다시 보내기 전에 잠금을 해제하거나 변환하세요.', + 'businessError.pdf_invalid': 'PDF 파일이 유효하지 않습니다. 텍스트로 변환하거나 다른 파일을 보내세요.', + 'businessError.image_too_large': '이미지가 선택한 모델에 비해 너무 큽니다. 크기를 조정하거나 더 작은 이미지를 보내세요.', + 'businessError.image_unsupported': '이 모델은 이미지를 지원하지 않습니다. 텍스트로 계속하거나, 비전 지원 모델로 전환하여 이미지를 다시 보내세요.', + 'businessError.request_too_large': '요청이 선택한 모델에 비해 너무 큽니다. 큰 파일을 제거하거나 더 짧은 메시지로 다시 시도하세요.', + 'businessError.prompt_too_long': '프롬프트가 선택한 모델에 비해 너무 깁니다. 대화를 압축하거나 컨텍스트를 줄여 다시 시도하세요.', + 'businessError.auto_mode_unavailable': '자동 모드는 현재 요금제에서 사용할 수 없습니다.', + + // ─── Server Status Verbs ────────────────────────────────────── + 'serverVerb.Thinking': '사고 중', + 'serverVerb.Compacting conversation': '컨텍스트 압축 중', + 'serverVerb.Running': '실행 중', + 'serverVerb.Working': '작업 중', + 'serverVerb.Creating worktree': 'worktree 만드는 중', + 'serverVerb.Task started': '작업 시작됨', + 'serverVerb.Task in progress': '작업 진행 중', + 'chat.retry.title': '요청 실패, 다시 시도 중', + 'chat.retry.attempt': '다시 시도 {attempt}/{max}', + 'chat.retry.httpStatus': 'HTTP {status}', + 'chat.retry.networkError': '네트워크 오류', + 'chat.retry.waiting': '{seconds}초 대기 중', + + // ─── Tabs ────────────────────────────────────── + 'tabs.close': '닫기', + 'tabs.closeOthers': '다른 탭 닫기', + 'tabs.closeLeft': '왼쪽 탭 닫기', + 'tabs.closeRight': '오른쪽 탭 닫기', + 'tabs.closeAll': '모두 닫기', + 'tabs.closeConfirmTitle': '세션 실행 중', + 'tabs.closeConfirmMessage': '이 세션은 아직 실행 중입니다. 어떻게 하시겠습니까?', + 'tabs.closeConfirmKeep': '계속 실행', + // ─── Slash Command Descriptions ────────────────────────────────────── + 'slashCmd.agent.description': '선택한 Agent로 프롬프트 실행', + 'slashCmd.mcp.description': '현재 채팅 컨텍스트에서 사용 가능한 MCP 도구 열기', + 'slashCmd.skills.description': '현재 채팅 컨텍스트에서 사용자가 호출할 수 있는 스킬 살펴보기', + 'slashCmd.help.description': '사용 가능한 데스크톱 및 에이전트 명령 표시', + 'slashCmd.status.description': '세션 상태, 사용량, 컨텍스트 표시', + 'slashCmd.cost.description': '세션 사용량과 비용 표시', + 'slashCmd.context.description': '현재 컨텍스트 사용량 표시', + 'slashCmd.plugin.description': '설정에서 데스크톱 플러그인 제어 열기', + 'slashCmd.memory.description': '설정에서 프로젝트 메모리 파일 열기', + 'slashCmd.doctor.description': '진단에서 Doctor 열기', + 'slashCmd.compact.description': '대화 컨텍스트 압축', + 'slashCmd.clear.description': '대화 기록 지우기', + 'slashCmd.goal.description': '완료 목표 설정', + 'slashCmd.review.description': '코드 변경 검토', + 'slashCmd.commit.description': 'git 커밋 만들기', + 'slashCmd.pr.description': '풀 리퀘스트 만들기', + 'slashCmd.init.description': '프로젝트 CLAUDE.md 초기화', + 'slashCmd.bug.description': '버그 신고', + 'slashCmd.config.description': '구성 열기', + 'slashCmd.login.description': 'Anthropic 계정 전환', + 'slashCmd.logout.description': '현재 계정에서 로그아웃', + 'slashCmd.model.description': 'AI 모델 전환', + 'slashCmd.permissions.description': '도구 권한 보기 또는 관리', + 'slashCmd.terminal-setup.description': '터미널 통합 설정', + 'slashCmd.vim.description': 'Vim 편집 모드 전환', + + 'tabs.closeConfirmStop': '중지하고 닫기', + 'tabs.closeAllConfirmTitle': '세션 실행 중', + 'tabs.closeAllConfirmMessage': '{count}개의 세션이 아직 실행 중입니다. 이 탭들을 닫기 전에 중지하시겠습니까?', + 'tabs.closeAllConfirmStop': '모두 중지하고 닫기', + 'tabs.sessionRunning': '세션 실행 중', + 'tabs.openTerminal': '터미널 열기', + 'tabs.showWorkspace': '작업 공간 표시', + 'tabs.hideWorkspace': '작업 공간 숨기기', + 'tabs.showBrowser': '브라우저 표시', + 'tabs.hideBrowser': '브라우저 숨기기', +} diff --git a/desktop/src/i18n/locales/zh-TW.ts b/desktop/src/i18n/locales/zh-TW.ts new file mode 100644 index 000000000..c3f504552 --- /dev/null +++ b/desktop/src/i18n/locales/zh-TW.ts @@ -0,0 +1,1702 @@ +import type { TranslationKey } from './en' + +export const zh: Record = { + // ─── Common ────────────────────────────────────── + 'common.cancel': '取消', + 'common.save': '儲存', + 'common.delete': '刪除', + 'common.add': '新增', + 'common.run': '執行', + 'common.send': '傳送', + 'common.stop': '停止', + 'common.rename': '重新命名', + 'common.retry': '重試', + 'common.loading': '載入中...', + 'common.select': '選擇', + 'common.enable': '啟用', + 'common.disable': '禁用', + 'common.active': '已啟用', + 'common.error': '錯誤', + 'common.copyFailed': '複製失敗。', + + // ─── Sidebar ────────────────────────────────────── + 'sidebar.newSession': '新建會話', + 'sidebar.scheduled': '定時任務', + 'sidebar.terminal': '終端', + 'sidebar.settings': '設定', + 'sidebar.searchPlaceholder': '搜尋會話...', + 'sidebar.noSessions': '暫無會話', + 'sidebar.noMatching': '沒有匹配的會話', + 'sidebar.sessionListFailed': '會話列表載入失敗', + 'sidebar.refreshSessions': '重新整理會話列表', + 'sidebar.projects': '專案', + 'sidebar.projectMenu': '專案選單', + 'sidebar.newProject': '新建專案', + 'sidebar.archiveAllChats': '歸檔所有聊天', + 'sidebar.organizeSidebar': '整理側邊欄', + 'sidebar.sortCondition': '排序條件', + 'sidebar.organizeByProject': '按專案', + 'sidebar.organizeByRecentProject': '近期專案', + 'sidebar.organizeByTime': '按時間順序', + 'sidebar.sortByCreatedAt': '建立時間', + 'sidebar.sortByUpdatedAt': '更新時間', + 'sidebar.newBlankProject': '新建空白專案', + 'sidebar.useExistingFolder': '使用現有資料夾', + 'sidebar.chooseProjectFolderUnavailable': '選擇資料夾僅在桌面端可用。', + 'sidebar.projectActions': '{project} 專案操作', + 'sidebar.pinProject': '置頂專案', + 'sidebar.unpinProject': '取消置頂專案', + 'sidebar.openInFinder': '在“訪達”中開啟', + 'sidebar.openInFinderFailed': '無法在訪達中開啟專案。', + 'sidebar.openInFinderUnavailable': '沒有可用的檔案管理器。', + 'sidebar.hideProjectFromSidebar': '從側邊欄隱藏', + 'sidebar.restoreProjectToSidebar': '恢復到側邊欄', + 'sidebar.restoreHiddenProjects': '恢復隱藏專案({count})', + 'sidebar.projectHidden': '已從側邊欄隱藏 {project},已有會話不會被刪除。', + 'sidebar.newSessionInProject': '在 {project} 中新建會話', + 'sidebar.showMoreSessions': '展開顯示', + 'sidebar.showFewerSessions': '摺疊顯示', + 'sidebar.expandProject': '展開 {project}', + 'sidebar.collapseProject': '摺疊 {project}', + 'sidebar.worktree': 'worktree', + 'sidebar.sessionRunning': '會話執行中', + 'sidebar.missingDir': '目錄缺失', + 'sidebar.confirmDelete': '確定要刪除這個會話嗎?此操作不可撤銷。', + 'sidebar.batchManage': '批次管理', + 'sidebar.batchSelectedCount': '已選 {count} 個', + 'sidebar.batchSelectAll': '全選', + 'sidebar.batchDeselectAll': '取消全選', + 'sidebar.batchSelectGroup': '選擇{group}', + 'sidebar.batchDeleteSelected': '刪除已選 ({count})', + 'sidebar.batchDeleteConfirm': '確定要刪除 {count} 個會話嗎?此操作不可撤銷。', + 'sidebar.batchDeleteConfirmBody': '以下會話將被刪除:', + 'sidebar.batchDeleteMore': '...還有 {count} 條', + 'sidebar.batchExit': '退出批次管理', + 'sidebar.batchDeleteSucceeded': '已刪除 {count} 個會話。', + 'sidebar.batchDeleteFailed': '有 {count} 個會話刪除失敗。', + 'sidebar.allProjects': '所有專案', + 'sidebar.other': '其他', + 'sidebar.timeGroup.today': '今天', + 'sidebar.timeGroup.yesterday': '昨天', + 'sidebar.timeGroup.last7days': '最近 7 天', + 'sidebar.timeGroup.last30days': '最近 30 天', + 'sidebar.timeGroup.older': '更早', + 'sidebar.collapse': '摺疊側邊欄', + 'sidebar.expand': '展開側邊欄', + + // ─── Title Bar ────────────────────────────────────── + 'titlebar.code': '程式碼', + 'titlebar.terminal': '終端', + 'titlebar.history': '歷史', + + // ─── Open Project ────────────────────────────────────── + 'openProject.openProject': '開啟專案', + 'openProject.openIn': '用 {target} 開啟', + 'openProject.openFailed': '無法開啟專案', + + // ─── Open With ───────────────────────────────────── + 'openWith.title': '開啟方式', + 'openWith.inAppBrowser': '應用內瀏覽器', + 'openWith.systemBrowser': '系統瀏覽器', + 'openWith.workspacePreview': '工作臺預覽', + 'openWith.openInTarget': '用 {target} 開啟', + 'openWith.revealInTarget': '在 {target} 中顯示', + 'openWith.fileType.document': '文件', + 'openWith.fileType.web': '網頁', + 'openWith.fileType.image': '圖片', + 'openWith.fileType.code': '程式碼', + 'openWith.fileType.file': '檔案', + + // ─── Assistant Output Targets ────────────────────── + 'assistantOutputs.kind.markdown': 'Markdown', + 'assistantOutputs.kind.html': 'HTML', + 'assistantOutputs.kind.image': '圖片', + 'assistantOutputs.kind.localhost': '本地服務', + 'assistantOutputs.moreOutputs': '+{count} 個輸出', + 'assistantOutputs.open': '開啟', + + // ─── Workspace Panel ─────────────────────────────── + 'workspace.changedFiles': '已更改檔案', + 'workspace.allFiles': '所有檔案', + 'workspace.viewTabs': '工作區檢視', + 'workspace.previewTabs': '預覽標籤', + 'workspace.filterPlaceholder': '篩選檔案...', + 'workspace.clearFilter': '清除檔案篩選', + 'workspace.refresh': '重新整理工作區', + 'workspace.closePanel': '關閉工作區面板', + 'workspace.resizePanel': '調整工作區寬度', + 'workbench.modeSwitch': '工作臺模式', + 'workbench.modeWorkspace': '檔案', + 'workbench.modeBrowser': '瀏覽器', + 'workbench.close': '關閉', + 'workspace.closeTab': '關閉標籤', + 'workspace.preview': '預覽', + 'workspace.previewEmpty': '選擇一個檔案進行預覽。', + 'workspace.notGitRepo': '當前目錄不是 Git 倉庫。', + 'workspace.missingWorkdir': '工作目錄不存在。', + 'workspace.loadError': '工作區資料載入失敗。', + 'workspace.noChanges': '沒有變更', + 'workspace.noFiles': '沒有檔案', + 'workspace.noMatchingFiles': '沒有匹配的檔案', + 'workspace.previewKind.diff': 'Diff', + 'workspace.previewKind.file': '檔案', + 'workspace.previewState.loading': '正在載入預覽...', + 'workspace.previewState.binary': '二進位制檔案暫不支援預覽。', + 'workspace.previewState.tooLarge': '檔案過大,無法預覽。', + 'workspace.previewState.missing': '檔案不存在。', + 'workspace.imagePreviewUnavailable': '圖片無法預覽。', + 'workspace.previewLineLimit': '正在顯示已載入內容的前 {count} / {total} 行。', + 'workspace.previewAllLines': '正在顯示全部 {total} 行已載入內容。', + 'workspace.showAllLoadedLines': '顯示全部已載入行', + 'workspace.collapsePreview': '收起預覽', + 'workspace.addToChat': '新增到聊天', + 'workspace.addSelectionToChat': '新增到對話', + 'workspace.copyPath': '複製路徑', + 'workspace.copyAbsolutePath': '複製絕對路徑', + 'workspace.pathCopied': '路徑已複製。', + 'workspace.localComment': '本地評論', + 'workspace.commentLine': '評論第 {line} 行', + 'workspace.commentLineTarget': '第 {line} 行', + 'workspace.commentPlaceholder': '描述你希望這裡怎麼改...', + 'workspace.addCommentToChat': '新增評論', + + // ─── Status Bar ────────────────────────────────────── + 'status.connected': '已連線', + 'status.connecting': '連線中...', + 'status.reconnecting': '重連中...', + 'status.disconnected': '已斷開', + + // ─── Settings ────────────────────────────────────── + 'settings.title': '設定', + 'settings.tab.providers': '服務商', + 'settings.tab.permissions': '許可權', + 'settings.tab.activity': 'Token 用量', + 'settings.tab.general': '通用', + 'settings.tab.h5Access': 'H5 訪問', + 'settings.tab.terminal': '終端', + 'settings.tab.skills': '技能', + 'settings.tab.mcp': 'MCP', + 'settings.tab.plugins': '外掛', + 'settings.tab.diagnostics': '診斷', + + // Settings > Usage + 'settings.activity.title': 'Token 用量', + 'settings.activity.profileTitle': '個人資料', + 'settings.activity.profilePrivacy': '僅本地', + 'settings.activity.defaultHandle': 'github.com/NanmiCoder/cc-haha', + 'settings.activity.editProfile': '編輯個人資料', + 'settings.activity.displayName': '顯示名稱', + 'settings.activity.subtitle': '第二行', + 'settings.activity.displayNameHelper': '修改主名稱和第二行;第二行如果是網址會自動作為連結開啟。', + 'settings.activity.avatar': '頭像', + 'settings.activity.avatarHelper': '支援 PNG、JPEG 或 WebP,最大 2 MB。', + 'settings.activity.changeAvatar': '更換頭像', + 'settings.activity.removeAvatar': '移除頭像', + 'settings.activity.saveProfile': '儲存', + 'settings.activity.cancelEdit': '取消', + 'settings.activity.profileSaved': '已儲存到本地', + 'settings.activity.profileSaveFailed': '儲存個人資料失敗', + 'settings.activity.subtitleLoading': '基於本機 Claude Code CLI 會話記錄統計', + 'settings.activity.totalTokens': '累計 Token 數', + 'settings.activity.peakTokens': '峰值 Token 數', + 'settings.activity.longestTask': '最長任務時長', + 'settings.activity.currentStreak': '當前連續天數', + 'settings.activity.longestStreak': '最長連續天數', + 'settings.activity.noDuration': '0 分鐘', + 'settings.activity.tokenActivity': 'Token 活動', + 'settings.activity.mode.daily': '每日', + 'settings.activity.mode.weekly': '每週', + 'settings.activity.mode.cumulative': '累計', + 'settings.activity.modeHelp.daily': '每日:每個格子表示當天 Token 用量。', + 'settings.activity.modeHelp.weekly': '每週:每一列表示這一週的 Token 總量。', + 'settings.activity.modeHelp.cumulative': '累計:每一列表示截至該周的累計 Token 總量。', + 'settings.activity.emptyTitle': '暫無本地用量', + 'settings.activity.emptyBody': '啟動 CLI 或桌面會話並完成模型回覆後,這裡會顯示統計。', + 'settings.activity.metric.yesterday': '昨天', + 'settings.activity.metric.today': '今天', + 'settings.activity.metric.last4': '近 4 天', + 'settings.activity.metric.last30': '30 天', + 'settings.activity.metric.streak': '連續活躍', + 'settings.activity.metric.bestStreak': '最長 {days} 天', + 'settings.activity.heatmapLabel': '按天統計的 Token 用量', + 'settings.activity.weekRange': '{start} - {end}', + 'settings.activity.cumulativeThrough': '截至 {date}', + 'settings.activity.tokenValue': '{tokens} Token', + 'settings.activity.count.sessionOne': '{count} 次會話', + 'settings.activity.count.sessionOther': '{count} 次會話', + 'settings.activity.count.dayOne': '{count} 天', + 'settings.activity.count.dayOther': '{count} 天', + 'settings.activity.weekday.mon': '週一', + 'settings.activity.weekday.wed': '週三', + 'settings.activity.weekday.fri': '週五', + 'settings.activity.selectedDay': '選中日期', + 'settings.activity.sessions': '會話', + 'settings.activity.tokens': 'Token', + 'settings.activity.messages': '訊息', + 'settings.activity.tools': '工具', + 'settings.activity.less': '少', + 'settings.activity.more': '多', + + // Settings > Terminal + 'settings.terminal.title': '終端', + 'settings.terminal.description': '直接執行宿主機命令,用於安裝外掛、Skills、MCP 等擴充套件。桌面端已內建 claude-haha;文件裡的 claude <引數> 可替換成 claude-haha <引數>,例如 claude-haha plugin install ... 或 claude-haha mcp add ...', + 'settings.terminal.infoLabel': '終端安裝說明', + 'settings.terminal.clear': '清屏', + 'settings.terminal.restart': '重啟', + 'settings.terminal.windowTitle': '宿主機 Shell', + 'settings.terminal.unavailableTitle': '需要桌面端執行時', + 'settings.terminal.unavailableBody': '請在打包後的桌面端裡開啟這個頁面,才能啟動互動式終端。', + 'settings.terminal.preferencesTitle': '啟動 Shell', + 'settings.terminal.preferencesBody': '用於新開的終端會話,以及點選重啟後的終端。', + 'settings.terminal.startupShell': '啟動 Shell', + 'settings.terminal.customPath': '自定義 Shell 路徑', + 'settings.terminal.customPathPlaceholder': 'C:\\Program Files\\PowerShell\\7\\pwsh.exe', + 'settings.terminal.customPathRequired': '儲存前請先填寫 Shell 路徑。', + 'settings.terminal.customPathAbsolute': '自定義 Shell 路徑必須是絕對 Windows 路徑。', + 'settings.terminal.saveShell': '儲存 Shell', + 'settings.terminal.saveShellSuccess': '已儲存。重啟終端或新開終端後生效。', + 'settings.terminal.shell.system': '系統預設', + 'settings.terminal.shell.systemDesc': '保持當前基於 COMSPEC 的行為。', + 'settings.terminal.shell.pwsh': 'PowerShell 7 (pwsh)', + 'settings.terminal.shell.pwshDesc': '安裝了 pwsh.exe 時優先使用它。', + 'settings.terminal.shell.powershell': 'Windows PowerShell', + 'settings.terminal.shell.powershellDesc': '使用系統自帶的 powershell.exe。', + 'settings.terminal.shell.cmd': '命令提示符', + 'settings.terminal.shell.cmdDesc': '明確使用 cmd.exe。', + 'settings.terminal.shell.custom': '自定義可執行檔案', + 'settings.terminal.shell.customDesc': '啟動一個絕對路徑的 Shell 可執行檔案。', + 'settings.terminal.status.idle': '空閒', + 'settings.terminal.status.starting': '啟動中', + 'settings.terminal.status.running': '執行中', + 'settings.terminal.status.exited': '已退出', + 'settings.terminal.status.error': '錯誤', + 'settings.terminal.status.unavailable': '不可用', + 'settings.terminal.bashPathLabel': 'Bash 路徑', + 'settings.terminal.bashPathDescription': 'Windows 下預設使用 CMD 作為終端。如果工具呼叫 grep、sed 等 Unix 命令,請在此配置 Bash 可執行檔案路徑(如 Git Bash)。', + 'settings.terminal.bashPathSave': '儲存', + 'settings.terminal.bashPathReset': '恢復預設', + 'settings.terminal.bashPathSaved': '已儲存', + 'settings.terminal.bashPathInvalid': '路徑不存在,請選擇有效的 Bash 可執行檔案', + 'terminal.newTab': '新建終端', + 'terminal.openInTab': '在 Tab 中開啟', + 'terminal.closePanel': '關閉終端面板', + 'terminal.resizePanel': '調整終端面板大小', + + // Settings > Diagnostics + 'settings.diagnostics.title': '診斷', + 'settings.diagnostics.description': '記錄服務端與 CLI 的啟動、服務商、會話執行錯誤,便於復現和定位問題。', + 'settings.diagnostics.refresh': '重新整理', + 'settings.diagnostics.totalSize': '日誌大小', + 'settings.diagnostics.events': '事件數', + 'settings.diagnostics.recentErrors': '24h 警告', + 'settings.diagnostics.retention': '保留策略', + 'settings.diagnostics.retentionValue': '{days} 天 / {size}', + 'settings.diagnostics.logDirectory': '日誌目錄', + 'settings.diagnostics.openDirectory': '開啟', + 'settings.diagnostics.exportBundle': '匯出診斷包', + 'settings.diagnostics.copySummary': '複製錯誤摘要', + 'settings.diagnostics.clearLogs': '清理日誌', + 'settings.diagnostics.recentEvents': '最近事件', + 'settings.diagnostics.privacyNote': '匯出的診斷包會脫敏,不包含聊天內容、檔案內容、完整環境變數或 API Key。', + 'settings.diagnostics.noEvents': '暫無診斷事件。', + 'settings.diagnostics.noRecentErrors': '最近沒有警告或錯誤。', + 'settings.diagnostics.loadFailed': '載入診斷資訊失敗。', + 'settings.diagnostics.openFailed': '開啟診斷目錄失敗。', + 'settings.diagnostics.exportFailed': '匯出診斷包失敗。', + 'settings.diagnostics.exported': '已匯出 {file}', + 'settings.diagnostics.summaryCopied': '錯誤摘要已複製。', + 'settings.diagnostics.copyFailed': '複製錯誤摘要失敗。', + 'settings.diagnostics.confirmClear': '確定清理所有本地診斷日誌和已匯出的診斷包?', + 'settings.diagnostics.cleared': '診斷日誌已清理。', + 'settings.diagnostics.clearFailed': '清理診斷日誌失敗。', + 'settings.diagnostics.eventDetails': '詳情', + 'settings.diagnostics.doctorTitle': 'Doctor', + 'settings.diagnostics.doctorDescription': '用於啟動和介面狀態問題的安全桌面修復。', + 'settings.diagnostics.doctorProtectedData': '絕不會觸碰聊天曆史、模型配置、Skills、MCP、IM 或 OAuth。', + 'settings.diagnostics.doctorSafeKeys': '只會清理:cc-haha-open-tabs、cc-haha-session-runtime、cc-haha-theme、cc-haha-locale 和 cc-haha.persistence.schemaVersion。', + 'settings.diagnostics.runDoctor': '執行 Doctor', + 'settings.diagnostics.doctorCompleted': 'Doctor 已執行完成。', + 'settings.diagnostics.doctorPartial': 'Doctor 已完成,但有 {count} 個本地清理項處理失敗。', + 'settings.diagnostics.doctorFailed': 'Doctor 執行失敗。', + 'settings.diagnostics.doctorResultLocal': '已清理 {count} 個安全 UI 鍵。', + 'settings.diagnostics.doctorResultFailedKeys': '有 {count} 個鍵無法移除。', + 'settings.diagnostics.doctorServerRan': '服務端 Doctor 修復也已執行。', + 'settings.diagnostics.doctorServerUnavailable': '服務端 Doctor 不可用,因此只執行了本地修復。', + 'errorBoundary.title': '出現異常。', + 'errorBoundary.description': '錯誤已記錄到診斷日誌。', + + // Settings > Claude Official Login + 'settings.claudeOfficialLogin.intro': '使用官方 Claude 模型需要登入你的 Claude.ai 賬號。點選下方按鈕,瀏覽器會開啟 Claude 官方登入頁面,授權後自動回到這裡。', + 'settings.claudeOfficialLogin.loginButton': '登入 Claude 賬號', + 'settings.claudeOfficialLogin.loginStarting': '正在啟動…', + 'settings.claudeOfficialLogin.logoutButton': '登出', + 'settings.claudeOfficialLogin.logoutProcessing': '處理中…', + 'settings.claudeOfficialLogin.loggedInPrefix': '已登入(Claude', + 'settings.claudeOfficialLogin.subTypeUnknown': '未知', + 'settings.claudeOfficialLogin.errorPrefix': '錯誤:', + 'settings.claudeOfficialLogin.openBrowserFailed': '無法開啟瀏覽器,請手動訪問授權連結。', + + // Settings > ChatGPT Official Login + 'settings.chatgptOfficialLogin.intro': '登入 ChatGPT 後,就可以在桌面端會話裡使用 GPT 模型。', + 'settings.chatgptOfficialLogin.loginButton': '登入 ChatGPT', + 'settings.chatgptOfficialLogin.loginStarting': '正在啟動登入...', + 'settings.chatgptOfficialLogin.logoutButton': '退出登入', + 'settings.chatgptOfficialLogin.logoutProcessing': '正在退出...', + 'settings.chatgptOfficialLogin.loggedInPrefix': '已登入', + 'settings.chatgptOfficialLogin.accountUnknown': 'ChatGPT 賬號', + 'settings.chatgptOfficialLogin.openBrowserFailed': '無法開啟瀏覽器。請複製授權連結並手動開啟。', + 'settings.chatgptOfficialLogin.copyAuthorizeUrl': '複製授權連結', + 'settings.chatgptOfficialLogin.copyLinkFailed': '無法複製授權連結。', + 'settings.chatgptOfficialLogin.errorPrefix': 'ChatGPT OAuth 錯誤:', + + // Settings > Providers + 'settings.providers.title': '服務商', + 'settings.providers.description': '管理 API 服務商以訪問模型。', + 'settings.providers.addProvider': '新增服務商', + 'settings.providers.officialName': 'Claude 官方', + 'settings.providers.officialDesc': 'Anthropic 原生接入 — 無需 API 金鑰', + 'settings.providers.openaiOfficialName': 'ChatGPT 官方', + 'settings.providers.openaiOfficialDesc': '透過 ChatGPT 賬號完成 OpenAI OAuth — 無需 API 金鑰', + 'settings.providers.connected': '已連線 ({latency}ms)', + 'settings.providers.failed': '失敗: {error}', + 'settings.providers.connectivityOk': '① 連通 ({latency}ms)', + 'settings.providers.connectivityFailed': '① 連通失敗: {error}', + 'settings.providers.proxyOk': '② 代理轉換 ({latency}ms)', + 'settings.providers.proxyFailed': '② 代理轉換失敗: {error}', + 'settings.providers.confirmDelete': '刪除服務商 "{name}"?此操作不可撤銷。', + 'settings.providers.activate': '啟用', + 'settings.providers.default': '預設', + 'settings.providers.setDefault': '設為預設', + 'settings.providers.test': '測試', + 'settings.providers.edit': '編輯', + 'settings.providers.requestFailed': '請求失敗', + 'settings.providers.addTitle': '新增服務商', + 'settings.providers.editTitle': '編輯服務商', + 'settings.providers.preset': '預設', + 'settings.providers.name': '名稱', + 'settings.providers.namePlaceholder': '服務商名稱', + 'settings.providers.notes': '備註', + 'settings.providers.notesPlaceholder': '可選備註...', + 'settings.providers.baseUrl': '介面地址', + 'settings.providers.baseUrlPlaceholder': 'https://api.example.com/anthropic', + 'settings.providers.apiKey': 'API 金鑰', + 'settings.providers.apiKeyKeep': 'API 金鑰(留空保持不變)', + 'settings.providers.getApiKey': '獲取 API Key', + 'settings.providers.modelMapping': '模型對映', + 'settings.providers.mainModel': '主模型', + 'settings.providers.haikuModel': 'Haiku 模型', + 'settings.providers.sonnetModel': 'Sonnet 模型', + 'settings.providers.opusModel': 'Opus 模型', + 'settings.providers.sameAsMain': '與主模型相同', + 'settings.providers.contextSettingsTitle': '上下文與自動壓縮', + 'settings.providers.contextSettingsDesc': '預設會自動應用模型視窗。只有服務商調整限制,或使用自定義模型 ID 時才需要修改。', + 'settings.providers.contextSettingsEdit': '高階', + 'settings.providers.contextSettingsHide': '收起', + 'settings.providers.contextSummaryAuto': '自動識別已配置模型;未知模型使用內建兜底', + 'settings.providers.contextFallbackAuto': '未知模型:自動', + 'settings.providers.contextFallbackSummary': '未知模型:{tokens}', + 'settings.providers.modelContextWindows': '模型上下文視窗', + 'settings.providers.mainContextWindow': '主模型上下文', + 'settings.providers.haikuContextWindow': 'Haiku 模型上下文', + 'settings.providers.sonnetContextWindow': 'Sonnet 模型上下文', + 'settings.providers.opusContextWindow': 'Opus 模型上下文', + 'settings.providers.contextWindowPlaceholder': '例如 200000', + 'settings.providers.modelContextWindowsDesc': '按每個模型的真實上下文填寫,內建預設會自動帶出,留空則走內建識別或預設 200K。', + 'settings.providers.modelContextWindowNumberError': '請輸入整數。', + 'settings.providers.modelContextWindowRangeError': '範圍必須在 16000 到 10000000 之間。', + 'settings.providers.autoCompactWindow': '未知模型兜底視窗', + 'settings.providers.autoCompactWindowPlaceholder': '可選,例如 200000', + 'settings.providers.autoCompactWindowDesc': '僅用於無法識別的模型;已配置的模型視窗會優先使用。', + 'settings.providers.autoCompactWindowNumberError': '請輸入整數。', + 'settings.providers.autoCompactWindowRangeError': '範圍必須在 16000 到 10000000 之間。', + 'settings.providers.testConnection': '測試連線', + 'settings.providers.settingsJson': '設定 JSON', + 'settings.providers.settingsJsonDesc': '~/.claude/cc-haha/settings.json — 直接編輯,儲存時寫入。', + 'settings.providers.jsonError': 'JSON 語法錯誤: {error}', + 'settings.providers.apiFormat': 'API 格式', + 'settings.providers.apiFormatAnthropic': 'Anthropic Messages (原生)', + 'settings.providers.apiFormatOpenaiChat': 'OpenAI Chat Completions (代理轉換)', + 'settings.providers.apiFormatOpenaiResponses': 'OpenAI Responses API (代理轉換)', + 'settings.providers.proxyHint': '請求將透過本地代理轉換協議格式', + 'settings.providers.authStrategy': '認證變數', + 'settings.providers.authStrategyApiKey': 'API Key (ANTHROPIC_API_KEY)', + 'settings.providers.authStrategyApiKeyDesc': '直連 Anthropic 官方 API,傳送 x-api-key。', + 'settings.providers.authStrategyAuthToken': 'Bearer Token (ANTHROPIC_AUTH_TOKEN)', + 'settings.providers.authStrategyAuthTokenDesc': '大多數第三方 Anthropic 相容服務,傳送 Authorization Bearer。', + 'settings.providers.authStrategyAuthTokenEmptyApiKey': 'Bearer + 清空 API_KEY', + 'settings.providers.authStrategyAuthTokenEmptyApiKeyDesc': 'OpenRouter/Ollama 等場景,避免回退到 Anthropic API key。', + 'settings.providers.authStrategyDualSameToken': '兩個變數寫同一個 Token', + 'settings.providers.authStrategyDualSameTokenDesc': 'Hugging Face Router 等同時檢查兩個變數的服務。', + 'settings.providers.authStrategyDualDummy': '兩個變數寫 dummy', + 'settings.providers.authStrategyDualDummyDesc': 'vLLM 等本地相容服務,只需要佔位認證值。', + + // Settings > Permissions + 'settings.permissions.title': '許可權模式', + 'settings.permissions.description': '控制工具執行許可權的處理方式。', + 'settings.permissions.default': '詢問許可權', + 'settings.permissions.defaultDesc': '執行工具前先詢問', + 'settings.permissions.acceptEdits': '接受編輯', + 'settings.permissions.acceptEditsDesc': '自動批准檔案編輯,其他操作仍詢問', + 'settings.permissions.plan': '計劃模式', + 'settings.permissions.planDesc': '僅思考和規劃,不執行操作', + 'settings.permissions.bypass': '跳過全部', + 'settings.permissions.bypassDesc': '跳過所有許可權檢查(危險)', + + // Settings > Adapters + 'settings.tab.adapters': 'IM 接入', + 'settings.adapters.description': '配置即時通訊介面卡,透過微信、釘釘、Telegram 或飛書與 Claude Code 對話。', + 'settings.adapters.telegram': 'Telegram', + 'settings.adapters.feishu': '飛書', + 'settings.adapters.wechat': '微信', + 'settings.adapters.dingtalk': '釘釘', + 'settings.adapters.botToken': 'Bot Token', + 'settings.adapters.botTokenPlaceholder': '貼上從 @BotFather 獲取的 Token', + 'settings.adapters.appId': 'App ID', + 'settings.adapters.appIdPlaceholder': '如 cli_xxx', + 'settings.adapters.appSecret': 'App Secret', + 'settings.adapters.appSecretPlaceholder': '從飛書開放平臺獲取', + 'settings.adapters.feishuCreateBotTitle': '還沒有飛書機器人?', + 'settings.adapters.feishuCreateBotDesc': '使用文件中的官方 OpenClaw 模板,一鍵建立已預配許可權的飛書機器人。建立後把 App ID 和 App Secret 填到下方。', + 'settings.adapters.feishuCreateBotAction': '一鍵建立飛書機器人', + 'settings.adapters.feishuCreateBotStepCreate': '點選模板建立機器人。', + 'settings.adapters.feishuCreateBotStepFill': '複製 App ID 和 App Secret,回到這裡填寫。', + 'settings.adapters.encryptKey': 'Encrypt Key', + 'settings.adapters.encryptKeyPlaceholder': '可選', + 'settings.adapters.verificationToken': 'Verification Token', + 'settings.adapters.verificationTokenPlaceholder': '可選', + 'settings.adapters.allowedUsers': '允許的使用者', + 'settings.adapters.allowedUsersHint': '逗號分隔。留空則只允許已配對使用者。', + 'settings.adapters.tgAllowedUsersPlaceholder': '如 123456789, 987654321', + 'settings.adapters.fsAllowedUsersPlaceholder': '如 ou_xxx, ou_yyy', + 'settings.adapters.wcAllowedUsersPlaceholder': '如 wx_user_id_1, wx_user_id_2', + 'settings.adapters.dtAllowedUsersPlaceholder': '如 manager001, staff_yyy', + 'settings.adapters.defaultProject': '預設專案', + 'settings.adapters.defaultProjectHint': '新 IM 會話的預設工作目錄。留空則使用當前使用者工作目錄。', + 'settings.adapters.streamingCard': '流式卡片模式', + 'settings.adapters.streamingCardDesc': '實時更新訊息內容,體驗更好', + 'settings.adapters.serverUrl': '伺服器地址', + 'settings.adapters.serverUrlPlaceholder': 'ws://127.0.0.1:3456', + 'settings.adapters.save': '儲存', + 'settings.adapters.saved': '已儲存', + 'settings.adapters.saving': '儲存中...', + 'settings.adapters.startHint': '儲存後執行介面卡:cd adapters && bun run {platform}', + 'settings.adapters.pairing': '配對管理', + 'settings.adapters.pairingDesc': '生成配對碼後在 IM 私聊中傳送給 Bot,完成身份繫結。', + 'settings.adapters.generateCode': '生成配對碼', + 'settings.adapters.regenerateCode': '重新生成', + 'settings.adapters.codeExpired': '已過期', + 'settings.adapters.codeExpiresIn': '有效期剩餘', + 'settings.adapters.minutes': '分鐘', + 'settings.adapters.pairingCodeHint': '請在釘釘、飛書、微信或 Telegram 私聊中傳送此配對碼給 Bot。微信需要先完成掃碼繫結。', + 'settings.adapters.pairedUsers': '已配對使用者', + 'settings.adapters.noPairedUsers': '暫無已配對使用者', + 'settings.adapters.unbind': '解綁', + 'settings.adapters.unbindConfirm': '確定要解綁該使用者嗎?解綁後需重新配對才能使用。', + 'settings.adapters.platform.telegram': 'Telegram', + 'settings.adapters.platform.feishu': '飛書', + 'settings.adapters.platform.wechat': '微信', + 'settings.adapters.platform.dingtalk': '釘釘', + 'settings.adapters.dingtalkQrTitle': '掃碼繫結釘釘機器人', + 'settings.adapters.dingtalkQrDesc': '使用釘釘手機 App 掃碼,一鍵建立並授權機器人。成功後會自動儲存 Client ID / Secret 並重啟介面卡。', + 'settings.adapters.dingtalkStartAuth': '掃碼繫結', + 'settings.adapters.dingtalkUnbindBot': '解除機器人繫結', + 'settings.adapters.dingtalkQrAlt': '釘釘授權二維碼', + 'settings.adapters.dingtalkWaiting': '等待釘釘掃碼確認...', + 'settings.adapters.dingtalkBound': '釘釘機器人已繫結。', + 'settings.adapters.dingtalkAuthFailed': '釘釘掃碼授權失敗。', + 'settings.adapters.dingtalkAuthExpired': '釘釘掃碼授權已過期,請重新生成二維碼。', + 'settings.adapters.dingtalkUnbindFailed': '釘釘解綁失敗。', + 'settings.adapters.dingtalkUnbindBotConfirm': '確定解除這個釘釘機器人繫結嗎?解除後需要重新掃碼,釘釘才能繼續收發訊息。', + 'settings.adapters.dingtalkClientId': 'Client ID', + 'settings.adapters.dingtalkClientIdPlaceholder': '掃碼後自動填寫,也可手動輸入', + 'settings.adapters.dingtalkClientSecret': 'Client Secret', + 'settings.adapters.dingtalkClientSecretPlaceholder': '掃碼後自動填寫,也可手動輸入', + 'settings.adapters.dingtalkEndpoint': 'Stream Endpoint', + 'settings.adapters.dingtalkEndpointPlaceholder': '預設 https://api.dingtalk.com', + 'settings.adapters.dingtalkPermissionCardTemplateId': '許可權卡片模板 ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdPlaceholder': '可選,互動卡片模板 ID', + 'settings.adapters.dingtalkPermissionCardTemplateIdHint': '填寫後許可權請求會優先傳送釘釘互動卡片;留空則使用 /allow、/always、/deny 文字授權。', + 'settings.adapters.wechatBind': '掃碼繫結', + 'settings.adapters.wechatRebind': '重新掃碼', + 'settings.adapters.wechatConnected': '微信已繫結', + 'settings.adapters.wechatNotConnected': '微信未繫結', + 'settings.adapters.wechatQrHint': '生成二維碼後使用微信掃碼並確認,繫結完成後介面卡會自動重啟。', + 'settings.adapters.wechatQrAlt': '微信繫結二維碼', + 'settings.adapters.wechatWaiting': '等待微信掃碼確認...', + 'settings.adapters.wechatBindSuccess': '微信繫結成功。', + 'settings.adapters.wechatUnbindAccount': '解除微信繫結', + 'settings.adapters.wechatUnbindAccountConfirm': '確定解除這個微信賬號繫結嗎?解除後需要重新掃碼,微信才能繼續收發訊息。', + 'settings.adapters.wechatUnbound': '微信繫結已解除。', + 'settings.adapters.wechatUnbindFailed': '微信解綁失敗。', + 'settings.adapters.wechatAllowedUsersHint': '微信掃碼只繫結賬號能力;使用者仍需傳送配對碼,或在這裡額外填寫允許的微信使用者 ID。', + + // Settings > MCP + 'settings.mcp.title': 'MCP 服務', + 'settings.mcp.description': '在桌面端直接管理外部工具與資料來源。Local、Project、User 三種範圍與 CLI 保持一致。', + 'settings.mcp.addServer': '新增服務', + 'settings.mcp.empty': '還沒有配置 MCP 服務', + 'settings.mcp.emptyHint': '先新增一個自定義的 STDIO、HTTP 或 SSE MCP 服務。', + 'settings.mcp.stats.total': '服務總數', + 'settings.mcp.stats.connected': '當前已連線', + 'settings.mcp.stats.attention': '需要處理', + 'settings.mcp.scope.project': '專案共享', + 'settings.mcp.scope.local': '專案私有', + 'settings.mcp.scope.user': '全域性使用者', + 'settings.mcp.scope.plugin': '外掛', + 'settings.mcp.scopeDesc.local': '只對你自己生效,但繫結到某一個專案。配置寫在使用者配置裡,同時帶上選中的專案上下文。', + 'settings.mcp.scopeDesc.project': '寫入選中專案的 `.mcp.json`,專案成員共享。', + 'settings.mcp.scopeDesc.user': '寫入你的全域性 Claude 配置,對所有專案生效。', + 'settings.mcp.scope.dynamic': '內建', + 'settings.mcp.scope.enterprise': '企業託管', + 'settings.mcp.scope.claudeai': 'Claude.ai', + 'settings.mcp.scope.managed': '受管控', + 'settings.mcp.transport.http': 'Streamable HTTP', + 'settings.mcp.globalOnlyHint': '選擇專案私有、專案共享或全域性使用者範圍。', + 'settings.mcp.currentProjectHint': '當前專案:{path}', + 'settings.mcp.form.back': '返回服務列表', + 'settings.mcp.form.createTitle': '連線自定義 MCP', + 'settings.mcp.form.createHint': '按當前 Claude Code 支援的欄位新增一個自定義 MCP 服務。', + 'settings.mcp.form.editTitle': '更新 {name} MCP', + 'settings.mcp.form.editHint': '檢視連線資訊、儲存修改,或直接在桌面端重連這個服務。', + 'settings.mcp.form.transportLocked': '如果你想切換 MCP 服務型別,請先解除安裝後重新新增。', + 'settings.mcp.form.uninstall': '解除安裝', + 'settings.mcp.form.reconnect': '重連', + 'settings.mcp.form.save': '儲存', + 'settings.mcp.form.name': '名稱', + 'settings.mcp.form.namePlaceholder': 'MCP 服務名稱', + 'settings.mcp.form.scope': '配置範圍', + 'settings.mcp.form.transport': '傳輸方式', + 'settings.mcp.form.status': '狀態', + 'settings.mcp.form.location': '配置位置', + 'settings.mcp.form.rawConfig': '原始配置', + 'settings.mcp.form.command': '啟動命令', + 'settings.mcp.form.commandPlaceholder': 'npx', + 'settings.mcp.form.commandHostHint': 'STDIO MCP 命令會直接在宿主機上執行。像 Node.js、Python、Bun、uv 這類執行時需要使用者自己安裝,並確保這個命令在 PATH 裡可用。', + 'settings.mcp.form.arguments': '引數', + 'settings.mcp.form.argumentPlaceholder': 'chrome-devtools-mcp@latest', + 'settings.mcp.form.addArgument': '新增引數', + 'settings.mcp.form.environmentVariables': '環境變數', + 'settings.mcp.form.addEnv': '新增環境變數', + 'settings.mcp.form.keyPlaceholder': '鍵', + 'settings.mcp.form.valuePlaceholder': '值', + 'settings.mcp.form.url': 'URL', + 'settings.mcp.form.sseUrl': 'SSE 地址', + 'settings.mcp.form.urlPlaceholder': 'https://mcp.example.com/mcp', + 'settings.mcp.form.headers': '請求頭', + 'settings.mcp.form.addHeader': '新增請求頭', + 'settings.mcp.form.oauthClientId': 'OAuth Client ID', + 'settings.mcp.form.oauthClientIdPlaceholder': '可選 Client ID', + 'settings.mcp.form.oauthCallbackPort': 'OAuth 回撥埠', + 'settings.mcp.form.oauthCallbackPortPlaceholder': '可選固定回撥埠', + 'settings.mcp.form.headersHelper': 'Headers Helper 指令碼', + 'settings.mcp.form.headersHelperPlaceholder': '可選的輔助指令碼路徑', + 'settings.mcp.form.deleteTitle': '刪除 MCP 服務', + 'settings.mcp.form.cancel': '取消', + 'settings.mcp.form.confirmDelete': '刪除', + 'settings.mcp.form.deleteConfirm': '確定刪除 MCP 服務 “{name}” 嗎?此操作不可撤銷。', + 'settings.mcp.form.deleteConfirmBody': '確定刪除 MCP 服務 “{name}” 嗎?此操作不可撤銷。', + 'settings.mcp.targetProject.title': '目標專案', + 'settings.mcp.targetProject.selected': '當前展示的是這個專案下的私有/共享 MCP:{path}', + 'settings.mcp.targetProject.empty': '先選擇一個專案,才能檢視專案私有或專案共享的 MCP。', + 'settings.mcp.targetProject.emptyWithCurrent': '請先選擇目標專案。當前啟用會話的專案是:{path}', + 'settings.mcp.targetProject.localSelected': '這個 MCP 會作為“專案私有”安裝到:{path}', + 'settings.mcp.targetProject.localEmpty': '請選擇要安裝這個私有 MCP 的專案。', + 'settings.mcp.targetProject.projectSelected': '這個 MCP 會寫入:{path}/.mcp.json,作為專案共享配置。', + 'settings.mcp.targetProject.projectEmpty': '請選擇要寫入 `.mcp.json` 的專案。', + 'settings.mcp.targetProject.globalTitle': '全域性安裝目標', + 'settings.mcp.targetProject.globalHint': '全域性使用者不需要選擇專案。它會寫入你的全域性 Claude 配置,並對所有專案生效。', + 'settings.mcp.toast.created': '已建立 MCP 服務 “{name}”', + 'settings.mcp.toast.saved': '已儲存 MCP 服務 “{name}”', + 'settings.mcp.toast.deleted': '已刪除 MCP 服務 “{name}”', + 'settings.mcp.toast.enabled': '已啟用 MCP 服務 “{name}”', + 'settings.mcp.toast.disabled': '已禁用 MCP 服務 “{name}”', + 'settings.mcp.toast.reconnected': '已重連 MCP 服務 “{name}”', + 'settings.mcp.toast.saveFailed': '儲存 MCP 服務失敗', + 'settings.mcp.toast.deleteFailed': '刪除 MCP 服務失敗', + 'settings.mcp.toast.toggleFailed': '更新 MCP 服務狀態失敗', + 'settings.mcp.toast.reconnectFailed': '重連 MCP 服務失敗', + + // Settings > Agents + 'settings.tab.agents': 'Agents', + 'settings.agents.title': '已安裝的 Agents', + 'settings.agents.description': '瀏覽 Claude 當前可用的 Agents,包括內建、專案和使用者來源。可在 TUI 中使用 /agents 檢視當前生效項與覆蓋關係。', + 'settings.agents.browserTitle': '瀏覽已安裝 Agents', + 'settings.agents.browserEyebrow': 'Agent 瀏覽器', + 'settings.agents.entryEyebrow': 'Agent 檔案', + 'settings.agents.empty': '暫無可用 Agent。', + 'settings.agents.emptyHint': '在 Claude 設定或當前專案中新增 Agent 定義後,就會顯示在這裡。', + 'settings.agents.model': '模型', + 'settings.agents.tools': '工具', + 'settings.agents.systemPrompt': '系統提示詞', + 'settings.agents.noDescription': '暫無描述', + 'settings.agents.noSystemPrompt': '未定義系統提示詞。', + 'settings.agents.backToList': '返回列表', + 'settings.agents.agentCount': '{count} 個 Agent', + 'settings.agents.summary.totalAgents': 'Agent 總數', + 'settings.agents.summary.activeAgents': '生效中', + 'settings.agents.summary.sources': '來源型別', + 'settings.agents.summary.source': '來源', + 'settings.agents.summary.model': '模型', + 'settings.agents.summary.tools': '工具', + 'settings.agents.summary.status': '狀態', + 'settings.agents.groupHint': '{source}中有 {count} 個 Agent 可用', + 'settings.agents.status.active': '已生效', + 'settings.agents.status.available': '可檢視', + 'settings.agents.overriddenBy': '被 {source} 覆蓋', + 'settings.agents.overriddenByShort': '被 {source} 覆蓋', + 'settings.agents.toolCount': '{count} 個工具', + 'settings.agents.noTools': '未限制工具', + 'settings.agents.promptHint': '閱讀當前 system prompt,並對比這個 Agent 的職責範圍。', + 'settings.agents.source.userSettings': '使用者', + 'settings.agents.source.projectSettings': '專案', + 'settings.agents.source.localSettings': '本地', + 'settings.agents.source.policySettings': '託管', + 'settings.agents.source.plugin': '外掛', + 'settings.agents.source.flagSettings': 'CLI 引數', + 'settings.agents.source.built-in': '內建', + + // Settings > Skills + 'settings.skills.title': '已安裝技能', + 'settings.skills.description': '技能擴充套件 Claude 的能力。在 ~/.claude/skills/ 中管理技能。', + 'settings.skills.browserTitle': '瀏覽已安裝技能', + 'settings.skills.browserEyebrow': '技能瀏覽器', + 'settings.skills.browserDescription': '檢視內建、專案和使用者技能,比較它們的來源與規模,並開啟技能目錄閱讀文件和原始碼檔案。', + 'settings.skills.searchLabel': '搜尋技能', + 'settings.skills.searchPlaceholder': '搜尋技能名稱、描述或來源...', + 'settings.skills.searchResultCount': '匹配 {count} / {total} 個技能', + 'settings.skills.clearSearch': '清空技能搜尋', + 'settings.skills.noSearchResults': '沒有匹配的技能', + 'settings.skills.noSearchResultsHint': '換一個關鍵詞,或清空搜尋檢視全部技能。', + 'settings.skills.entryEyebrow': '技能入口', + 'settings.skills.slashCommand': '/斜槓命令', + 'settings.skills.tokenEstimate': '約 {count} tokens', + 'settings.skills.tokenEstimateShort': '約 {count}', + 'settings.skills.summary.totalSkills': '技能總數', + 'settings.skills.summary.totalFiles': '檔案數', + 'settings.skills.summary.sources': '來源型別', + 'settings.skills.summary.tokens': '預估 tokens', + 'settings.skills.summary.source': '來源', + 'settings.skills.summary.entry': '入口檔案', + 'settings.skills.groupHint': '{source}中有 {count} 個技能可用', + 'settings.skills.ready': '可檢視', + 'settings.skills.unavailable': '不可用', + 'settings.skills.empty': '暫無已安裝技能', + 'settings.skills.emptyHint': '在 ~/.claude/skills/ 中新增技能即可開始', + 'settings.skills.back': '返回列表', + 'settings.skills.files': '個檔案', + 'settings.skills.entryFile': '入口檔案', + 'settings.skills.metaTitle': '技能後設資料', + 'settings.skills.filesPanel': '檔案', + 'settings.skills.filesPanelHint': '瀏覽入口檔案及其配套實現檔案。', + 'settings.skills.readingMode': '當前為{mode}', + 'settings.skills.docMode': '文件模式', + 'settings.skills.codeMode': '程式碼模式', + 'settings.skills.source.user': '使用者', + 'settings.skills.source.project': '專案', + 'settings.skills.source.plugin': '外掛', + 'settings.skills.source.mcp': 'MCP', + 'settings.skills.source.bundled': '內建', + + // Settings > Memory + 'settings.tab.memory': '記憶', + 'settings.memory.title': '專案記憶', + 'settings.memory.description': '檢視和編輯 Claude 為每個專案寫入的 Markdown 記憶檔案。這些檔案存放在 ~/.claude/projects//memory/,會被 CLI 執行時載入。', + 'settings.memory.refresh': '重新整理', + 'settings.memory.projects': '專案', + 'settings.memory.files': '記憶檔案', + 'settings.memory.resourceManager': '資源管理器', + 'settings.memory.editor': '編輯', + 'settings.memory.preview': '預覽', + 'settings.memory.rendered': '已渲染', + 'settings.memory.emptyProjects': '還沒有找到記憶專案。', + 'settings.memory.emptyFiles': '還沒有找到記憶檔案。', + 'settings.memory.selectFile': '選擇一個記憶檔案。', + 'settings.memory.selectProject': '選擇一個專案。', + 'settings.memory.noFileSelected': '未選擇檔案', + 'settings.memory.current': '當前', + 'settings.memory.indexFile': '索引', + 'settings.memory.missing': '目錄缺失', + 'settings.memory.fileCount': '{count} 個檔案', + 'settings.memory.unsaved': '未儲存', + 'settings.memory.saved': '已儲存', + 'settings.memory.revert': '還原', + 'settings.memory.projectSearchPlaceholder': '按路徑搜尋專案...', + 'settings.memory.fileSearchPlaceholder': '搜尋記憶檔案...', + 'settings.memory.resourceSearchPlaceholder': '搜尋專案或記憶檔案...', + 'settings.memory.noProjectMatches': '沒有匹配的專案。', + 'settings.memory.noFileMatches': '沒有匹配的記憶檔案。', + 'settings.memory.clearSearch': '清空搜尋', + 'settings.memory.toggleFolder': '展開或摺疊 {name}', + + // Settings > Plugins + 'settings.plugins.title': '已安裝外掛', + 'settings.plugins.description': '檢視已安裝外掛、執行狀態,並把外掛變更應用到桌面端執行時。', + 'settings.plugins.browserTitle': '瀏覽已安裝外掛', + 'settings.plugins.browserEyebrow': '外掛管理', + 'settings.plugins.browserDescription': '外掛會把技能、Agent、Hook、MCP 服務和語言工具打包在一起。這裡先聚焦已安裝外掛、健康狀態和應用變更反饋,不把 CLI 的整套複雜互動直接搬過來。', + 'settings.plugins.entryEyebrow': '外掛詳情', + 'settings.plugins.summary.total': '外掛總數', + 'settings.plugins.summary.enabled': '已啟用', + 'settings.plugins.summary.attention': '需關注', + 'settings.plugins.summary.marketplaces': '市場', + 'settings.plugins.summary.skills': '技能', + 'settings.plugins.summary.agents': 'Agents', + 'settings.plugins.summary.mcp': 'MCP', + 'settings.plugins.summary.hooks': 'Hooks', + 'settings.plugins.group.attention': '需關注', + 'settings.plugins.group.enabled': '已啟用', + 'settings.plugins.group.disabled': '已禁用', + 'settings.plugins.groupHint': '此分組下共有 {count} 個外掛', + 'settings.plugins.refresh': '重新整理', + 'settings.plugins.apply': '應用變更', + 'settings.plugins.applyHint': '啟用、禁用或更新後,需要把外掛變更重新應用到當前桌面端執行時。', + 'settings.plugins.lastReload': '最近一次應用:{enabled} 個活躍外掛,{skills} 個外掛技能,{errors} 個錯誤。', + 'settings.plugins.reloadToast': '外掛變更已應用:{enabled} 個活躍外掛,{skills} 個技能,{errors} 個錯誤。', + 'settings.plugins.marketplacesTitle': '已知外掛市場', + 'settings.plugins.marketplacesHint': '這裡只展示當前機器已經配置好的 marketplace 來源摘要。', + 'settings.plugins.marketplaceAutoUpdateOn': '自動更新開', + 'settings.plugins.marketplaceAutoUpdateOff': '自動更新關', + 'settings.plugins.marketplaceInstalledCount': '已安裝 {count} 個', + 'settings.plugins.marketplaceUpdatedAt': '更新於 {value}', + 'settings.plugins.status.enabled': '已啟用', + 'settings.plugins.status.disabled': '已禁用', + 'settings.plugins.status.attention': '需關注', + 'settings.plugins.scope.user': '使用者', + 'settings.plugins.scope.project': '專案', + 'settings.plugins.scope.local': '本地', + 'settings.plugins.scope.managed': '託管', + 'settings.plugins.scope.builtin': '內建', + 'settings.plugins.empty': '暫無已安裝外掛', + 'settings.plugins.emptyHint': '先在 Claude Code 裡安裝外掛,桌面端就可以在這裡管理。', + 'settings.plugins.back': '返回列表', + 'settings.plugins.noDescription': '這個外掛沒有可用描述。', + 'settings.plugins.errorCount': '{count} 個錯誤', + 'settings.plugins.enable': '啟用', + 'settings.plugins.disable': '禁用', + 'settings.plugins.update': '更新', + 'settings.plugins.uninstall': '解除安裝', + 'settings.plugins.confirmUninstall': '確定解除安裝外掛“{name}”嗎?會刪除當前 scope 下的安裝副本。', + 'settings.plugins.author': '作者:{value}', + 'settings.plugins.projectPath': '專案:{value}', + 'settings.plugins.installPath': '安裝位置:{value}', + 'settings.plugins.managedHint': '這個外掛由策略託管,不能在桌面端修改。', + 'settings.plugins.builtinHint': '內建外掛支援在這裡重新應用,但不開放安裝和解除安裝操作。', + 'settings.plugins.errorsTitle': '外掛錯誤', + 'settings.plugins.capabilitiesTitle': '打包能力', + 'settings.plugins.capabilitiesHint': '根據外掛 manifest 和執行時整合解析出的能力列表。', + 'settings.plugins.sharedNavigationDisabled': '先啟用外掛並應用變更,才能在共享管理頁中開啟它的技能、Agent 或 MCP 條目。', + 'settings.plugins.capabilityEmpty': '沒有暴露', + 'settings.plugins.capability.skills': '{count} 個技能', + 'settings.plugins.capability.agents': '{count} 個 Agent', + 'settings.plugins.capability.mcpServers': '{count} 個 MCP 服務', + 'settings.plugins.capabilityLabel.skills': '技能', + 'settings.plugins.capabilityLabel.commands': '命令', + 'settings.plugins.capabilityLabel.agents': 'Agents', + 'settings.plugins.capabilityLabel.hooks': 'Hooks', + 'settings.plugins.capabilityLabel.mcpServers': 'MCP 服務', + 'settings.plugins.capabilityLabel.lspServers': 'LSP 服務', + + // Settings > About + 'settings.tab.about': '關於', + 'settings.about.version': '版本', + 'settings.about.changelog': '更新日誌', + 'settings.about.repo': 'GitHub 倉庫', + 'settings.about.starHint': '如果這個專案對你有幫助,歡迎給個 Star', + 'settings.about.feedback': '反饋問題', + 'settings.about.feedbackDesc': '遇到 Bug 或使用問題,前往 GitHub Issue 提交反饋', + 'settings.about.author': '作者', + 'settings.about.socialMedia': '社交媒體', + 'settings.about.updates': '應用更新', + 'settings.about.updatesDesc': '檢查 GitHub Releases,下載安裝包,並在安裝後自動重啟。', + + // Settings > Computer Use + 'settings.tab.computerUse': 'Computer Use', + 'settings.computerUse.title': 'Computer Use', + 'settings.computerUse.description': '允許 Claude 截圖、點選、打字並控制你的電腦。需要 Python 3,macOS 上還需要輔助功能許可權。', + 'settings.computerUse.enabledToggle': '啟用', + 'settings.computerUse.disabledHint': 'Computer Use 已關閉。新會話不會注入 computer-use MCP,也不會把桌面控制工具暴露給 Coding Agent。', + 'settings.computerUse.notSupported': 'Computer Use 僅支援 macOS 和 Windows。', + 'settings.computerUse.python': 'Python 3', + 'settings.computerUse.pythonNotFound': '未安裝,請先安裝 Python 3。', + 'settings.computerUse.pythonFound': '已安裝', + 'settings.computerUse.pythonCustomInvalid': '自定義直譯器不可用', + 'settings.computerUse.pythonPathLabel': 'Python 直譯器路徑', + 'settings.computerUse.pythonPathPlaceholder': '自動檢測,或選擇 python.exe / python3', + 'settings.computerUse.pythonPathHint': '留空則自動檢測;選擇 conda、pyenv 或自定義環境裡的 Python 可執行檔案後會優先使用它建立執行環境。', + 'settings.computerUse.pythonPathBrowse': '選擇', + 'settings.computerUse.pythonPathSave': '應用', + 'settings.computerUse.pythonPathAuto': '自動', + 'settings.computerUse.pythonPathSaved': '已儲存,重新檢測會優先使用這個直譯器。', + 'settings.computerUse.pythonPathSaveFailed': '儲存失敗,請稍後重試。', + 'settings.computerUse.pythonPathDialogTitle': '選擇 Python 直譯器', + 'settings.computerUse.pythonPathDialogFailed': '無法開啟檔案選擇器,請手動貼上路徑。', + 'settings.computerUse.venv': '虛擬環境', + 'settings.computerUse.venvReady': '已就緒', + 'settings.computerUse.venvNotReady': '未建立', + 'settings.computerUse.deps': '依賴包', + 'settings.computerUse.depsReady': '已安裝', + 'settings.computerUse.depsNotReady': '未安裝', + 'settings.computerUse.accessibility': '輔助功能許可權', + 'settings.computerUse.screenRecording': '螢幕錄製許可權', + 'settings.computerUse.permGranted': '已授權', + 'settings.computerUse.permDenied': '未授權 — 請前往「系統設定 > 隱私與安全性」授權', + 'settings.computerUse.permUnknown': '請先安裝環境後檢測', + 'settings.computerUse.permScreenRecordingUnknownSoft': '自動檢測結果不穩定;如果系統設定裡已授權,通常可以直接使用', + 'settings.computerUse.permScreenRecordingManual': '無法自動檢測 — 請在系統設定中手動確認已授權', + 'settings.computerUse.setupBtn': '安裝環境', + 'settings.computerUse.setupRunning': '安裝中...', + 'settings.computerUse.setupSuccess': '環境安裝完成!', + 'settings.computerUse.setupFail': '安裝失敗', + 'settings.computerUse.allReady': '所有檢查透過,Computer Use 已就緒。', + 'settings.computerUse.downloadPython': '下載 Python 3', + 'settings.computerUse.recheckBtn': '重新檢測', + 'settings.computerUse.requirementsLabel': '需要的 Python 包', + 'settings.computerUse.appsTitle': '已授權應用', + 'settings.computerUse.appsDescription': '預先授權 App,Claude 將可以直接控制這些 App,無需執行時彈窗確認。', + 'settings.computerUse.appsLoading': '載入已安裝的 App...', + 'settings.computerUse.appsEmpty': '未找到已安裝的 App,請先安裝環境。', + 'settings.computerUse.appsSearch': '搜尋 App...', + 'settings.computerUse.appsSaved': '已儲存', + 'settings.computerUse.openAccessibility': '開啟輔助功能設定', + 'settings.computerUse.openScreenRecording': '開啟螢幕錄製設定', + 'settings.computerUse.permRestartHint': '授權後需重啟 App 才能生效。', + 'settings.computerUse.flagClipboard': '剪貼簿訪問', + 'settings.computerUse.flagSystemKeys': '系統快捷鍵', + + // Settings > General - Storage + 'settings.general.modeSwitchTitle': '切換資料儲存位置?', + 'settings.general.modeSwitchConfirm': '儲存並重啟', + 'settings.general.storageTitle': '資料儲存位置', + 'settings.general.storageDescription': '低頻高階設定。切換後,會話記錄、Skills、MCP、外掛、Provider 配置、任務和快取都會從新的目錄讀取。', + 'settings.general.storageSystemTitle': '使用系統目錄', + 'settings.general.storageSystemDescription': '回到預設資料來源。若啟動環境設定了 CLAUDE_CONFIG_DIR,則仍會優先使用該環境變數指定的目錄。', + 'settings.general.storagePortableTitle': '使用便攜目錄', + 'settings.general.storagePortableDescription': '把桌面端資料寫入你選擇的資料夾,適合放在行動硬碟或和應用一起打包遷移。', + 'settings.general.storagePortableDirLabel': '便攜資料目錄', + 'settings.general.storagePortableDirPlaceholder': '選擇一個用於儲存 cc-haha 資料的資料夾', + 'settings.general.storageChooseDir': '選擇目錄', + 'settings.general.storageChooseDirTitle': '選擇便攜資料目錄', + 'settings.general.storageUseDefaultPortableDir': '使用應用旁邊的預設便攜目錄', + 'settings.general.storageApplyPortable': '使用這個目錄並重啟', + 'settings.general.storageActiveDir': '當前實際讀取目錄', + 'settings.general.storageEnvironmentHint': '當前目錄由 CLAUDE_CONFIG_DIR 環境變數控制。應用內切換不會覆蓋這個環境變數;如需回到系統目錄,請先移除啟動環境裡的 CLAUDE_CONFIG_DIR。', + 'settings.general.storageEnvironmentSwitchBlocked': '當前由 CLAUDE_CONFIG_DIR 環境變數控制。請先移除啟動環境裡的 CLAUDE_CONFIG_DIR,再切回系統目錄。', + 'settings.general.storageRestartHint': '已儲存切換請求。請重啟應用,讓新的資料目錄生效。', + 'settings.general.storageMoveHint': '切換目錄不會自動搬遷舊資料。如果希望舊會話繼續出現,請把原目錄下的 projects、skills、plugins、cc-haha 等資料複製到新目錄。要做便攜包,建議把目錄放在應用旁邊並一起壓縮。', + 'settings.general.storageNoDirError': '請先選擇或填寫一個便攜資料目錄。', + 'settings.general.storagePickerError': '無法開啟目錄選擇器,請手動貼上目錄路徑。', + 'settings.general.storageRestartError': '切換已儲存,但自動重啟失敗,請手動重啟應用。', + 'settings.general.storageSwitchPortableBody': '切換後,桌面端會從下面這個目錄讀取和寫入會話、配置、Skills、MCP、外掛、任務和快取。', + 'settings.general.storageSwitchDefaultBody': '切回系統目錄後,桌面端會回到系統預設資料來源。當前便攜目錄中的資料不會被刪除,也不會自動遷回。', + 'settings.general.storageSwitchRestartBody': '應用將先關閉本地服務和介面卡程序,然後自動重啟。重啟後新目錄才會生效。', + + // Settings > General + 'settings.general.appearanceTitle': '配色主題', + 'settings.general.appearanceDescription': '在經典暖色、暗色與純白工作區之間切換。', + 'settings.general.appearance.light': '經典暖色', + 'settings.general.appearance.dark': '暗色', + 'settings.general.appearance.white': '純白', + 'settings.general.languageTitle': '語言', + 'settings.general.languageDescription': '選擇應用程式的顯示語言。', + 'settings.general.responseLangTitle': '回覆語言', + 'settings.general.responseLangDescription': '指定 Claude 始終以某種語言回覆。', + 'settings.general.responseLangDefault': '預設(英語)', + 'settings.general.effortTitle': '推理強度', + 'settings.general.effortDescription': '控制模型使用的計算量。', + 'settings.general.effort.low': '低', + 'settings.general.effort.medium': '中', + 'settings.general.effort.high': '高', + 'settings.general.effort.max': '最大', + 'settings.general.thinkingTitle': '思考模式', + 'settings.general.thinkingDescription': '控制新會話是否啟用模型思考。關閉後,DeepSeek 等相容供應商會收到顯式非思考模式引數。', + 'settings.general.thinkingEnabled': '啟用思考模式', + 'settings.general.thinkingHint': '關閉後會以 --thinking disabled 啟動新會話;適合 DeepSeek V4 Flash/Pro 等需要非思考模式的模型。', + 'settings.general.notificationsTitle': '系統通知', + 'settings.general.notificationsDescription': '使用作業系統原生通知提醒授權確認、Agent 回覆完成和定時任務結果。', + 'settings.general.notificationsEnabled': '啟用系統通知', + 'settings.general.notificationsHintOn': '開啟後會請求系統通知許可權,並透過系統通知中心提醒。', + 'settings.general.notificationsHintOff': '關閉後,授權確認、Agent 回覆和定時任務都不會傳送桌面通知。', + 'settings.general.notificationsStatus': '許可權', + 'settings.general.notificationsStatusGranted': '已授權', + 'settings.general.notificationsStatusDenied': '已被系統設定阻止', + 'settings.general.notificationsStatusDefault': '尚未請求', + 'settings.general.notificationsStatusUnsupported': '當前環境不可用', + 'settings.general.notificationsAuthorize': '授權通知', + 'settings.general.notificationsOpenSettings': '開啟系統設定', + 'settings.general.notificationsTestTitle': 'Claude Code Haha 通知已啟用', + 'settings.general.notificationsTestBody': '後續授權確認和 Agent 回覆完成都會透過系統通知提醒。', + 'settings.general.chatSendBehaviorTitle': '訊息傳送方式', + 'settings.general.chatSendBehaviorDescription': '選擇桌面端對話輸入框如何傳送訊息。', + 'settings.general.chatSendBehaviorEnter': 'Enter 傳送', + 'settings.general.chatSendBehaviorEnterDescription': 'Shift+Enter 換行。', + 'settings.general.chatSendBehaviorModifier': 'Ctrl/Cmd+Enter 傳送', + 'settings.general.chatSendBehaviorModifierDescription': 'Enter 和 Shift+Enter 都會換行。', + 'settings.general.h5AccessTitle': 'H5 訪問', + 'settings.general.h5AccessDescription': '在區域網內暴露桌面端 H5 應用。手機透過帶 H5 token 的二維碼快速連線。', + 'settings.general.h5AccessEnabled': '啟用 H5 訪問', + 'settings.general.h5AccessEnabledHint': '桌面服務會監聽區域網地址,並開放桌面會話相關能力。', + 'settings.general.h5AccessStatusEnabled': '已啟用', + 'settings.general.h5AccessTokenPreview': '令牌預覽', + 'settings.general.h5AccessDisabledValue': '未啟用', + 'settings.general.h5AccessDisable': '關閉', + 'settings.general.h5AccessGenerateToken': '生成令牌', + 'settings.general.h5AccessRegenerate': '重新生成令牌', + 'settings.general.h5AccessGeneratedToken': '生成的令牌', + 'settings.general.h5AccessGeneratedTokenHint': '僅顯示一次,請立即複製並像密碼一樣儲存。', + 'settings.general.h5AccessShowToken': '顯示令牌', + 'settings.general.h5AccessCopy': '複製', + 'settings.general.h5AccessCopyUrl': '複製 H5 連結', + 'settings.general.h5AccessCopyLaunchUrl': '複製掃碼連結', + 'settings.general.h5AccessUrlCopied': 'H5 連結已複製。', + 'settings.general.h5AccessLaunchUrlCopied': '掃碼連結已複製。', + 'settings.general.h5AccessHideToken': '隱藏令牌', + 'settings.general.h5AccessTokenNotAvailable': '重新生成後可顯示新的令牌。', + 'settings.general.h5AccessPublicHost': '訪問主機 / IP', + 'settings.general.h5AccessPublicHostPlaceholder': '192.168.1.100', + 'settings.general.h5AccessCurrentPort': '當前埠', + 'settings.general.h5AccessCurrentPortUnknown': '自動', + 'settings.general.h5AccessPublicUrl': '公開訪問 URL', + 'settings.general.h5AccessPublicUrlPlaceholder': 'https://chat.example.com', + 'settings.general.h5AccessAllowedOrigins': '允許的來源', + 'settings.general.h5AccessAllowedOriginsPlaceholder': 'https://chat.example.com, https://phone.example', + 'settings.general.h5AccessOriginsHint': '每行一個來源,或使用逗號分隔多個來源。', + 'settings.general.h5AccessOpenHint': '普通區域網訪問只改主機 / IP,埠使用當前服務埠。反向代理可直接填完整 URL。', + 'settings.general.h5AccessSave': '儲存 H5 設定', + 'settings.general.h5AccessUrl': 'H5 連結', + 'settings.general.h5AccessQrTitle': '手機連線', + 'settings.general.h5AccessQrHint': '掃碼會直接開啟 H5,並自動帶上 token。', + 'settings.general.h5AccessQrRefreshHint': '點選“生成令牌”後會建立可掃碼的連線。', + 'settings.general.h5AccessQrEmptyHint': '生成令牌後會在這裡顯示二維碼。', + 'settings.general.h5AccessQrAlt': 'H5 訪問二維碼', + 'settings.general.h5AccessSafetyNote': '只在可信網路中啟用。拿到二維碼連結的人可以訪問 H5 暴露的桌面能力。', + 'settings.general.h5AccessConfirmTitle': '啟用區域網 H5 訪問?', + 'settings.general.h5AccessConfirmBody': '這會把桌面 H5 應用暴露到區域網地址和埠。持有二維碼 token 的裝置可以訪問桌面會話和相關控制能力。請只在可信網路中繼續。', + 'settings.general.h5AccessConfirmEnable': '啟用 H5 訪問', + 'settings.general.h5AccessError': '更新 H5 設定失敗。', + 'settings.general.h5AccessStaleHostTitle': '當前儲存的訪問主機已不可達', + 'settings.general.h5AccessStaleHostBody': '儲存的 {storedHost} 不在本機當前的任何網絡卡上。手機掃碼會連不上。建議切到本機當前的區域網 IP。', + 'settings.general.h5AccessStaleHostNoSuggestion': '儲存的 {storedHost} 不在本機當前的任何網絡卡上。手機掃碼會連不上。請檢查本機的網路連線,或改填反向代理 URL。', + 'settings.general.h5AccessStaleHostApply': '切到 {suggestedHost}', + 'settings.general.h5AccessProxyNote': '當前使用的是反向代理 URL,手機掃碼會經公網/隧道返回桌面端。請確認你的反代仍能工作。', + 'settings.general.networkTitle': '網路', + 'settings.general.networkDescription': '控制桌面會話發起的服務商 API 請求。', + 'settings.general.networkProxyModeSystem': '系統代理', + 'settings.general.networkProxyModeSystemDescription': '使用應用程序繼承到的代理設定。', + 'settings.general.networkProxyModeManual': '手動代理', + 'settings.general.networkProxyModeManualDescription': '使用下方填寫的 HTTP 或 HTTPS 代理地址。', + 'settings.general.networkProxyUrl': '代理地址', + 'settings.general.networkProxyUrlHint': '支援 HTTP 和 HTTPS 代理,例如 http://127.0.0.1:7890。', + 'settings.general.networkProxyUrlInvalid': '請輸入 HTTP 或 HTTPS 代理地址。', + 'settings.general.networkProxyUrlRequired': '請輸入代理地址。', + 'settings.general.networkTimeout': 'AI 請求超時', + 'settings.general.networkTimeoutValue': '{seconds} 秒', + 'settings.general.networkTimeoutHint': '用於服務商請求、流式首個響應,以及服務商連線測試。支援 5-600 秒。', + 'settings.general.networkTimeoutUnit': '秒', + 'settings.general.networkTimeoutDecrease': '減少 30 秒', + 'settings.general.networkTimeoutIncrease': '增加 30 秒', + 'settings.general.networkTimeoutRequired': '請輸入超時時間。', + 'settings.general.networkTimeoutRange': '請輸入 {min}-{max} 秒之間的整數。', + 'settings.general.networkSaved': '網路設定已儲存。', + 'settings.general.networkScopeHint': '不會影響單獨的應用更新代理。', + 'settings.general.networkSave': '儲存', + 'settings.general.webFetchPreflightTitle': 'WebFetch 預檢', + 'settings.general.webFetchPreflightDescription': '桌面端預設跳過 Claude 的域名預檢,避免第三方服務商或受限網路下出現誤報失敗。', + 'settings.general.webFetchPreflightEnabled': '跳過 WebFetch 域名預檢', + 'settings.general.webFetchPreflightHint': '只有在你明確需要恢復上游預設安全預檢時,才建議關閉這個選項。', + 'settings.general.webSearchTitle': 'WebSearch', + 'settings.general.webSearchDescription': '配置 Agent 聯網搜尋在 Claude 原生、第三方供應商和本地 fallback key 之間如何選擇。', + 'settings.general.webSearch.mode.auto': '自動', + 'settings.general.webSearch.mode.tavily': 'Tavily', + 'settings.general.webSearch.mode.brave': 'Brave', + 'settings.general.webSearch.mode.anthropic': 'Claude', + 'settings.general.webSearch.mode.disabled': '關閉', + 'settings.general.webSearchTavilyKey': 'Tavily API Key', + 'settings.general.webSearchBraveKey': 'Brave Search API Key', + 'settings.general.webSearchBravePlaceholder': 'Brave Search token', + 'settings.general.webSearchGetApiKey': '獲取 API Key', + 'settings.general.webSearchTavilyApiKeyLink': '獲取 Tavily API Key', + 'settings.general.webSearchBraveApiKeyLink': '獲取 Brave Search API Key', + 'settings.general.webSearchTavilyFreeHint': '註冊賬號即可複製 API Key,免費額度包含 1000 Credits。', + 'settings.general.webSearchBraveFreeHint': '註冊賬號後可建立 Search API Key,免費額度可用於測試。', + 'settings.general.webSearchHint': '自動模式會對 Claude 模型名優先使用原生 WebSearch,失敗或非 Claude 模型時再使用 Tavily/Brave。', + 'settings.general.webSearchSave': '儲存', + 'settings.general.uiZoom': '介面縮放', + 'settings.general.uiZoomDescription': '調整整個介面的顯示大小。', + 'settings.general.uiZoomShortcutHint': '快捷鍵更直接:', + 'settings.general.uiZoomShortcutMac': 'macOS', + 'settings.general.uiZoomShortcutWindows': 'Windows / Linux', + 'settings.general.uiZoomShortcutResetHint': '0 表示恢復到 100%。', + 'settings.general.uiZoomReset': '重置介面縮放到 100%', + + // ─── Empty Session ────────────────────────────────────── + 'empty.title': '新建會話', + 'empty.subtitle': '開始一個新的編碼會話。Claude 已準備好幫你構建、除錯和架構你的專案。', + 'empty.placeholder': '隨便問點什麼...', + 'empty.addFiles': '新增檔案或圖片', + 'empty.slashCommands': '斜槓命令', + 'empty.failedToCreate': '建立會話失敗', + 'empty.createError.workdirMissing': '專案目錄不存在或不是資料夾。請選擇一個存在的專案後重試。', + 'empty.createError.notGit': '當前專案不是 Git 倉庫,無法選擇分支啟動。可以直接在當前目錄開始,或改選一個 Git 專案。', + 'empty.createError.branchNotFound': '選中的分支已經不存在。請重新整理專案上下文後重新選擇分支。', + 'empty.createError.dirtyWorktree': '當前專案有未提交改動,已阻止直接切換分支。請開啟“獨立工作樹”,或先提交/暫存這些改動。', + 'empty.createError.branchCheckedOut': '該分支已在其他工作樹中檢出。請開啟“獨立工作樹”,或選擇其他分支。', + 'empty.createError.worktreeCreateFailed': '無法建立獨立工作樹。請確認 Git 可以寫入此倉庫後重試。詳情:{detail}', + 'empty.createError.switchFailed': '無法切換當前專案分支。請先確認 Git 錯誤並保護好本地改動後重試。詳情:{detail}', + 'empty.createError.contextFailed': '無法檢查這個 Git 專案。請確認倉庫狀態後重試。', + + // ─── Repository Launch Controls ────────────────────────────────────── + 'repoLaunch.selectBranch': '選擇分支', + 'repoLaunch.searchBranch': '搜尋分支', + 'repoLaunch.noBranch': '無分支', + 'repoLaunch.noBranchMatch': '沒有匹配的分支', + 'repoLaunch.currentBranch': '當前分支', + 'repoLaunch.localBranch': '本地分支', + 'repoLaunch.remoteBranch': '遠端分支', + 'repoLaunch.checkedOut': '已在其他工作樹中檢出', + 'repoLaunch.worktreeCurrent': '當前工作樹', + 'repoLaunch.worktreeIsolated': '獨立工作樹', + 'repoLaunch.selectWorktree': '選擇工作樹模式', + 'repoLaunch.missingWorkdir': '工作目錄不存在。', + 'repoLaunch.dirtyWarning': '檢測到未提交變更,直接切換可能會被阻止;使用獨立工作樹可以繼續,且不會改動當前目錄。', + 'repoLaunch.checkedOutWarning': '選中的分支已在其他工作樹中檢出。直接啟動可能會被 Git 阻止;使用“獨立工作樹”可以避免切換當前目錄。', + + // ─── Chat Input ────────────────────────────────────── + 'chat.placeholder': '讓 Claude 編輯、除錯或解釋程式碼...', + 'chat.placeholderMissing': '此會話指向的工作目錄缺失。請新建會話或選擇其他專案。', + 'chat.addFiles': '新增檔案或圖片', + 'chat.dropFilesTitle': '鬆手新增檔案', + 'chat.dropFilesHint': '會以檔案路徑附加到當前輸入。', + 'chat.workspaceReferencesOnly': '已新增 {count} 個工作區引用', + 'chat.contextReferencesOnly': '已新增 {count} 個引用', + 'chat.addSelectionToChat': '新增到對話', + 'chat.branchFromHere': 'Fork 一個新對話', + 'chat.branchSuccess': '已 Fork 新對話“{title}”。', + 'chat.branchError': '從該訊息 Fork 新對話失敗。詳情:{detail}', + 'chat.userMessageReference': '使用者訊息', + 'chat.assistantMessageReference': 'AI 回覆', + 'chat.slashCommands': '斜槓命令', + 'chat.goalEvent.created': '目標已設定', + 'chat.goalEvent.replaced': '目標已設定', + 'chat.goalEvent.statusTitle': '目標狀態', + 'chat.goalEvent.paused': '目標已暫停', + 'chat.goalEvent.resumed': '目標已恢復', + 'chat.goalEvent.completed': '目標已完成', + 'chat.goalEvent.cleared': '目標已清除', + 'chat.goalEvent.message': '目標更新', + 'chat.goalEvent.objective': '目標:{value}', + 'chat.goalEvent.statusValue': '狀態:{value}', + 'chat.goalEvent.budget': '預算:{value}', + 'chat.goalEvent.continuations': '續作次數:{value}', + 'chat.compactSummary.compacting': '上下文正在壓縮', + 'chat.compactSummary.title': '上下文已壓縮', + 'chat.compactSummary.autoTitle': '上下文已自動壓縮', + 'chat.compactSummary.manualTitle': '上下文已手動壓縮', + 'chat.compactSummary.trigger.manual': '手動', + 'chat.compactSummary.trigger.auto': '自動', + 'chat.compactSummary.tokens': '壓縮前 {count} tokens', + 'chat.compactSummary.messages': '已摘要 {count} 條訊息', + 'chat.activeGoal.title': '當前目標', + 'chat.activeGoal.running': '自迴圈執行中', + 'chat.activeGoal.active': '進行中', + 'chat.activeGoal.paused': '已暫停', + 'chat.activeGoal.completed': '已完成', + 'chat.activeGoal.budget': '預算 {value}', + 'chat.activeGoal.continuations': '續作次數 {value}', + 'chat.activeGoal.elapsed': '已用時 {value}', + 'chat.backgroundAgents.title': '後臺 Agent', + 'chat.backgroundAgents.count': '{count} 個執行中或最近任務', + 'chat.backgroundAgents.agent': 'agent', + 'chat.backgroundTasks.command': '後臺命令', + 'chat.backgroundTasks.workflow': '後臺工作流', + 'chat.backgroundTasks.task': '後臺任務', + 'chat.backgroundAgents.tokens': '{count} tokens', + 'chat.backgroundAgents.status.running': '執行中', + 'chat.backgroundAgents.status.completed': '已完成', + 'chat.backgroundAgents.status.failed': '失敗', + 'chat.backgroundAgents.status.stopped': '已停止', + 'slash.mcp.title': '可用 MCP 工具', + 'slash.mcp.subtitle': '展示當前聊天上下文裡的全域性 MCP 和當前專案 MCP。', + 'slash.mcp.subtitleWithProject': '當前展示全域性 MCP 以及這個專案的 MCP:{path}', + 'slash.mcp.emptyTitle': '沒有可用的 MCP 服務', + 'slash.mcp.emptyBody': '當前聊天上下文裡沒有可用的全域性或專案 MCP 服務。', + 'slash.mcp.projectBadge': '專案:{name}', + 'slash.skills.title': '可用技能', + 'slash.skills.subtitle': '展示當前上下文裡可直接呼叫的技能。', + 'slash.skills.subtitleWithProject': '當前展示專案下的技能:{path}', + 'slash.skills.emptyTitle': '沒有可用技能', + 'slash.skills.emptyBody': '當前上下文裡沒有找到可直接呼叫的技能。', + 'slash.plugins.title': '外掛', + 'slash.plugins.subtitle': '外掛管理後續會接到這個斜槓命令面板裡。', + 'slash.plugins.emptyTitle': '外掛面板即將接入', + 'slash.plugins.emptyBody': '這套共享的斜槓命令面板已經接通,外掛資料下一步接進來。', + 'slash.help.title': '斜槓命令', + 'slash.help.subtitle': '執行 Agent 工作流、檢視會話狀態,或開啟桌面端面板。', + 'slash.help.group.context': '上下文', + 'slash.help.group.project': '專案', + 'slash.help.group.desktop': '桌面端', + 'slash.help.group.more': '更多', + 'slash.help.moreAvailable': '還有 {count} 條命令可用。輸入 / 可以搜尋完整命令列表。', + 'slash.inspector.title': '會話檢查器', + 'slash.inspector.close': '關閉會話檢查器', + 'slash.inspector.loading': '正在載入會話資料', + 'slash.inspector.error.noActiveSession': '當前沒有選中的活躍會話。', + 'slash.inspector.error.unavailable': '會話檢查器資料不可用。請重啟桌面端後端,讓 /api/sessions/:id/inspection 介面生效。', + 'slash.inspector.tab.status': '狀態', + 'slash.inspector.tab.usage': '用量', + 'slash.inspector.tab.context': '上下文', + 'slash.inspector.status.cliStatus': 'CLI 狀態', + 'slash.inspector.status.running': '執行中', + 'slash.inspector.status.notRunning': '未執行', + 'slash.inspector.status.activeModel': '當前模型', + 'slash.inspector.status.unknown': '未知', + 'slash.inspector.status.mcpConnections': 'MCP 連線', + 'slash.inspector.status.connected': '已連線', + 'slash.inspector.status.failed': '失敗', + 'slash.inspector.status.registeredTools': '註冊工具', + 'slash.inspector.status.commands': '條命令', + 'slash.inspector.status.sessionMetadata': '會話後設資料', + 'slash.inspector.status.version': '版本', + 'slash.inspector.status.sessionId': '會話 ID', + 'slash.inspector.status.workingDirectory': '工作目錄', + 'slash.inspector.status.permissionMode': '許可權模式', + 'slash.inspector.status.authToken': '認證令牌', + 'slash.inspector.status.outputStyle': '輸出樣式', + 'slash.inspector.status.default': '預設', + 'slash.inspector.status.mcpServers': 'MCP 服務', + 'slash.inspector.status.refresh': '重新整理', + 'slash.inspector.status.contextWindow': '上下文視窗', + 'slash.inspector.usage.emptyTitle': '暫無用量資料', + 'slash.inspector.usage.emptyBody': 'CLI 會話啟動並完成至少一輪迴復後,這裡會顯示用量。', + 'slash.inspector.usage.contextSnapshotNotice': '當前展示來自上下文快照的 token 用量。上下文資料重新整理後會同步更新。', + 'slash.inspector.usage.transcriptNotice': '當前展示從會話記錄重建的用量。API 耗時只對正在執行的 CLI 程序可用。', + 'slash.inspector.usage.unknownCost': '部分模型價格未知,費用統計可能不準確。', + 'slash.inspector.usage.totalCost': '總費用', + 'slash.inspector.usage.source': '來源', + 'slash.inspector.usage.source.contextSnapshot': '上下文快照', + 'slash.inspector.usage.source.transcript': '會話記錄', + 'slash.inspector.usage.source.currentProcess': '當前程序', + 'slash.inspector.usage.apiDuration': 'API 耗時', + 'slash.inspector.usage.wallDuration': '總耗時', + 'slash.inspector.usage.usageSpan': '用量跨度', + 'slash.inspector.usage.codeChanges': '程式碼改動', + 'slash.inspector.usage.input': '輸入', + 'slash.inspector.usage.output': '輸出', + 'slash.inspector.usage.cacheReadWrite': '快取讀 / 寫', + 'slash.inspector.usage.webSearch': '網頁搜尋', + 'slash.inspector.usage.byModel': '按模型統計', + 'slash.inspector.usage.tokens': 'Tokens', + 'slash.inspector.usage.noModelTitle': '暫無模型用量', + 'slash.inspector.usage.noModelBody': '記錄到模型回覆後,這裡會顯示 token 用量。', + 'slash.inspector.context.loading': '正在載入上下文資料', + 'slash.inspector.context.emptyTitle': '暫無上下文資料', + 'slash.inspector.context.emptyBody': '上下文用量需要活躍的 CLI 會話。', + 'slash.inspector.context.windowUsage': '上下文視窗用量', + 'slash.inspector.context.used': '已使用', + 'slash.inspector.context.free': '剩餘', + 'slash.inspector.context.messages': '訊息', + 'slash.inspector.context.assistant': '助手', + 'slash.inspector.context.toolResults': '工具結果', + 'slash.inspector.context.context': '上下文', + 'slash.inspector.context.categoryTitle': '按類別估算', + 'slash.inspector.context.noCategoriesTitle': '暫無上下文分類', + 'slash.inspector.context.noCategoriesBody': 'CLI 返回上下文分析後,這裡會顯示分類資料。', + 'slash.inspector.context.memoryFiles': '記憶檔案', + 'slash.inspector.context.noMemoryFiles': '當前會話沒有載入記憶檔案。', + 'slash.inspector.context.openMemory': '開啟記憶', + 'contextIndicator.ariaLabel': '上下文用量 {percent}', + 'contextIndicator.pendingAria': '上下文用量待計算', + 'contextIndicator.loadingAria': '上下文用量載入中', + 'contextIndicator.unavailableAria': '上下文用量不可用', + 'contextIndicator.title': '上下文', + 'contextIndicator.modelUnknown': '未知模型', + 'contextIndicator.used': '已使用', + 'contextIndicator.free': '剩餘', + 'contextIndicator.window': '視窗', + 'contextIndicator.loading': '正在載入上下文用量...', + 'contextIndicator.pendingDetail': '會話啟動後計算上下文用量。', + 'contextIndicator.unavailable': '不可用', + 'contextIndicator.unavailableDetail': '此會話暫時無法獲取上下文用量。', + 'contextIndicator.updatedUnknown': '尚未重新整理', + 'contextIndicator.updatedNow': '剛剛更新', + 'contextIndicator.updatedMinutes': '{count} 分鐘前更新', + 'contextIndicator.estimate': '估算', + 'chat.navigate': '導航', + 'chat.select': '選擇', + 'chat.dismiss': '關閉', + 'chat.stopTitle': '停止生成 (Cmd+.)', + 'chat.jumpToLatest': '回到最新', + 'chat.memorySavedTitle': '已儲存 {count} 個記憶檔案', + 'chat.memorySavedFromToolsTitle': '儲存了 {count} 條記憶', + 'chat.memoryReferencedTitle': '{count} 條記憶引用', + 'chat.memoryOpenSettings': '開啟記憶', + 'chat.memoryMoreFiles': '還有 {count} 個', + 'chat.memoryTechnicalDetails': '工具詳情', + 'chat.rewindSuccessWithCode': '已回滾 {count} 條訊息,並恢復相關檔案。', + 'chat.rewindSuccessConversationOnly': '已回滾 {count} 條訊息。這一輪沒有可用的檔案檢查點。', + 'chat.turnChangesTitle': '{count} 個檔案已更改', + 'chat.turnChangesLatestCardLabel': '輪次已更改檔案', + 'chat.turnChangesHistoricalCardLabel': '輪次已更改檔案', + 'chat.turnChangesLatestSubtitle': '當前輪次檢查點', + 'chat.turnChangesHistoricalSubtitle': '歷史輪次檢查點', + 'chat.turnChangesLatestUndo': '撤銷當前輪次', + 'chat.turnChangesHistoricalUndo': '回滾到這一輪之前', + 'chat.turnChangesUndoing': '正在撤銷...', + 'chat.turnChangesLatestUndoAria': '撤銷當前輪次變更', + 'chat.turnChangesHistoricalUndoAria': '回滾到這一輪之前', + 'chat.turnChangesLatestConfirmTitle': '撤銷當前輪次?', + 'chat.turnChangesHistoricalConfirmTitle': '回滾到這一輪之前?', + 'chat.turnChangesLatestConfirmBody': '這會回滾最近一次助手回覆,並恢復這一輪中被跟蹤的檔案變更。', + 'chat.turnChangesHistoricalConfirmBody': '這會把會話回滾到這一輪之前,並恢復該檢查點對應的檔案變更。', + 'chat.turnChangesLatestConfirmUndo': '撤銷當前輪次', + 'chat.turnChangesHistoricalConfirmUndo': '回滾到這一輪之前', + 'chat.turnChangesOpenInWorkspaceAria': '在工作區開啟 {path}', + 'chat.turnChangesShowMore': '再顯示 {count} 個檔案', + 'chat.turnChangesShowLess': '收起', + + // ─── Streaming Indicator ────────────────────────────────────── + 'streaming.thinking': '思考中', + 'streaming.running': '執行中', + 'streaming.working': '工作中', + + // ─── Permission Dialog ────────────────────────────────────── + 'permission.allowEditFile': '允許 Claude {toolName} {fileName}?', + 'permission.allowEditFileGeneric': '允許 Claude {toolName}此檔案?', + 'permission.allowBash': '允許 Claude 執行此命令?', + 'permission.allowTool': '允許 Claude 使用 {toolName}?', + 'permission.awaitingApproval': '等待審批', + 'permission.responded': '已響應', + 'permission.allow': '允許', + 'permission.allowForSession': '本次會話允許', + 'permission.deny': '拒絕', + 'permission.hideDetails': '隱藏詳情', + 'permission.showFullInput': '顯示完整輸入', + 'permission.replacingContent': '替換檔案內容', + + // ─── Computer Use Approval ────────────────────────────────────── + 'computerUseApproval.titleApps': 'Computer Use 想控制這些應用', + 'computerUseApproval.titleTcc': 'Computer Use 需要 macOS 許可權', + 'computerUseApproval.reason': '請求原因', + 'computerUseApproval.allow': '本次會話允許', + 'computerUseApproval.deny': '拒絕', + 'computerUseApproval.alreadyGranted': '本次會話已授權', + 'computerUseApproval.notInstalled': '應用未安裝', + 'computerUseApproval.sensitiveApp': '該應用屬於高敏感類別,請額外確認後再授權。', + 'computerUseApproval.alsoRequested': '同時請求了', + 'computerUseApproval.hideWhileWorking': 'Claude 工作時會隱藏另外 {count} 個應用。', + 'computerUseApproval.hideWhileWorkingRestore': 'Claude 工作時會隱藏另外 {count} 個應用,結束後會自動恢復。', + 'computerUseApproval.accessibility': '輔助功能', + 'computerUseApproval.screenRecording': '螢幕錄製', + 'computerUseApproval.granted': '已授權', + 'computerUseApproval.notGranted': '未授權', + 'computerUseApproval.openAccessibility': '開啟輔助功能設定', + 'computerUseApproval.openScreenRecording': '開啟螢幕錄製設定', + 'computerUseApproval.tryAgain': '稍後重試', + 'computerUseApproval.tccHint': '先在系統設定裡授予缺失許可權,返回後再點“稍後重試”。', + 'computerUseApproval.tryAgainHint': '“稍後重試”會把控制權交還給 Claude,讓它在 macOS 許可權生效後重新呼叫 request_access。', + + // ─── Ask User Question ────────────────────────────────────── + 'question.needsInput': 'Claude 需要你的輸入', + 'question.answered': '已回答', + 'question.completed': '已結束', + 'question.customResponse': '或輸入自定義回覆:', + 'question.typePlaceholder': '輸入你的回答...', + 'question.submit': '提交', + 'question.answeredPrefix': '已回答: ', + 'question.resultPrefix': '結果: ', + + // ─── Thinking Block ────────────────────────────────────── + 'thinking.label': '思考中', + 'thinking.labelDone': '已思考', + + // ─── Tool Calls ────────────────────────────────────── + 'tool.errorOutput': '錯誤輸出', + 'tool.toolOutput': '工具輸出', + 'tool.toolInput': '工具輸入', + 'tool.partialInput': '部分輸入', + 'tool.writerPreview': 'Writer', + 'tool.writerPreviewLatest': '正在顯示最新 {visible} / {total} 行', + 'tool.generatingContent': '正在生成內容', + 'tool.preparingEdit': '正在準備編輯', + 'tool.preparingTool': '正在準備工具', + 'tool.readFileContents': '讀取檔案內容', + 'tool.createFile': '建立檔案', + 'tool.updateFileContents': '更新檔案內容', + 'tool.linesChanged': '{count} 行已更改', + 'tool.linesCreated': '{count} 行已建立', + 'tool.linesOutput': '{count} 行輸出', + 'tool.result': '{toolName} 結果', + 'tool.resultGeneric': '工具結果', + 'tool.error': '錯誤', + 'tool.success': '成功', + 'tool.showLess': '收起', + 'tool.showMore': '展開 {count} 個字元', + + // ─── Tool Group Verbs ────────────────────────────────────── + 'toolGroup.readOne': '讀取了 1 個檔案', + 'toolGroup.readMany': '讀取了 {count} 個檔案', + 'toolGroup.createdOne': '建立了一個檔案', + 'toolGroup.createdMany': '建立了 {count} 個檔案', + 'toolGroup.editedOne': '編輯了一個檔案', + 'toolGroup.editedMany': '編輯了 {count} 個檔案', + 'toolGroup.ranOne': '執行了一條命令', + 'toolGroup.ranMany': '執行了 {count} 條命令', + 'toolGroup.foundFiles': '查詢到檔案', + 'toolGroup.searchedOne': '搜尋了程式碼', + 'toolGroup.searchedMany': '搜尋了 {count} 個模式', + 'toolGroup.agentOne': '派遣了一個代理', + 'toolGroup.agentMany': '派遣了 {count} 個代理', + 'agentStatus.starting': '開始中', + 'agentStatus.running': '進行中', + 'agentStatus.done': '完成', + 'agentStatus.failed': '失敗', + 'agentStatus.stopped': '已停止', + 'agentStatus.noActivity': '暫時還沒有工具活動', + 'agentStatus.viewResult': '檢視結果', + 'agentStatus.resultTitle': 'Agent 結果', + 'toolGroup.searchedWeb': '搜尋了網頁', + 'toolGroup.fetchedOne': '獲取了一個頁面', + 'toolGroup.fetchedMany': '獲取了 {count} 個頁面', + + // ─── Tasks ────────────────────────────────────── + 'tasks.title': '任務', + 'tasks.completed': '已完成的任務', + 'tasks.dismissCompleted': '隱藏已完成任務', + 'tasks.newTask': '+ 新建任務', + 'tasks.emptyTitle': '暫無定時任務。', + 'tasks.emptyDesc': '建立定時任務來自動化你的工程工作流。', + 'tasks.createNew': '建立新任務', + 'tasks.totalTasks': '總任務數', + 'tasks.active': '活躍', + 'tasks.disabled': '已禁用', + + // ─── New Task Modal ────────────────────────────────────── + 'newTask.title': '新建定時任務', + 'newTask.localWarning': '本地任務僅在電腦喚醒時執行。', + 'newTask.fullPermissions': '所有許可權', + 'newTask.name': '名稱', + 'newTask.namePlaceholder': 'daily-code-review', + 'newTask.description': '描述', + 'newTask.descPlaceholder': '審查昨天的提交併標記可疑之處', + 'newTask.frequency': '頻率', + 'newTask.everyNMinutes': '每 N 分鐘', + 'newTask.everyNHours': '每 N 小時', + 'newTask.daily': '每天', + 'newTask.weekdays': '工作日(週一至週五)', + 'newTask.specificDays': '指定星期幾', + 'newTask.monthly': '每月', + 'newTask.customCron': '自定義 Cron 表示式', + 'newTask.intervalMinutes': '每 {n} 分鐘', + 'newTask.intervalHours': '每 {n} 小時', + 'newTask.atMinute': '在第 :{m} 分鐘', + 'newTask.onMonthDay': '每月第 {d} 天', + 'newTask.cronFormatHint': '格式:分 時 日 月 星期', + 'newTask.invalidCron': '無效的 Cron 表示式', + 'newTask.daySun': '日', + 'newTask.dayMon': '一', + 'newTask.dayTue': '二', + 'newTask.dayWed': '三', + 'newTask.dayThu': '四', + 'newTask.dayFri': '五', + 'newTask.daySat': '六', + 'newTask.delayNote': '定時任務會使用隨機延遲以最佳化伺服器效能。', + 'newTask.create': '建立任務', + 'newTask.promptPlaceholder': '檢視過去 24 小時的提交。總結變更內容,標記有風險的模式或缺失的測試,並記錄值得跟進的事項。', + 'newTask.notification': '通知', + 'newTask.notifyOnComplete': '完成後推送通知', + 'newTask.notifyChannels': '通知渠道', + 'newTask.notifyHint': '任務完成後傳送原生桌面通知或 IM 訊息。', + 'newTask.notifyDesktop': '桌面', + 'newTask.notConfigured': '未配置', + 'newTask.noChannelConfigured': '尚未配置任何 IM 渠道,請前往 設定 → IM 接入 進行配置。', + 'newTask.noChannelSelected': '請至少選擇一個通知渠道。', + + // ─── Cron 描述 ────────────────────────────────────── + 'cron.everyMinute': '每分鐘執行', + 'cron.everyNMinutes': '每 {n} 分鐘執行', + 'cron.everyHour': '每小時執行', + 'cron.everyNHours': '每 {n} 小時執行', + 'cron.everyNHoursAtMinute': '每 {n} 小時在第 :{m} 分鐘執行', + 'cron.dailyAt': '每天 {time} 執行', + 'cron.weekdaysAt': '工作日 {time} 執行', + 'cron.specificDaysAt': '每{days} {time} 執行', + 'cron.monthlyAt': '每月 {day} 日 {time} 執行', + 'cron.customSchedule': '自定義:{cron}', + 'cron.dow.0': '週日', + 'cron.dow.1': '週一', + 'cron.dow.2': '週二', + 'cron.dow.3': '週三', + 'cron.dow.4': '週四', + 'cron.dow.5': '週五', + 'cron.dow.6': '週六', + + // ─── 任務操作與日誌 ────────────────────────────────────── + 'tasks.runNow': '立即執行', + 'tasks.confirmRun': '確定要立即執行此任務嗎?', + 'tasks.confirmDisable': '確定要禁用此定時任務嗎?', + 'tasks.confirmEnable': '確定要啟用此定時任務嗎?', + 'tasks.confirmDelete': '確定要永久刪除此任務及其所有日誌嗎?', + 'tasks.running': '執行中...', + 'tasks.viewLogs': '日誌', + 'tasks.logsTitle': '執行記錄', + 'tasks.noLogs': '暫無執行記錄', + 'tasks.runStatus.running': '執行中', + 'tasks.runStatus.completed': '已完成', + 'tasks.runStatus.failed': '失敗', + 'tasks.runStatus.timeout': '超時', + 'tasks.duration': '{s}秒', + 'tasks.viewOutput': '摘要', + 'tasks.hideOutput': '收起', + 'tasks.close': '關閉', + 'tasks.edit': '編輯', + 'tasks.editTitle': '編輯定時任務', + 'tasks.saveChanges': '儲存修改', + 'tasks.openSession': '檢視完整對話', + 'tasks.createdAt': '建立於 ', + 'tasks.lastRunAt': '上次執行 ', + 'tasks.outputHintSession': '點選「檢視完整對話」可在會話中檢視完整輸出。', + 'tasks.noOutputText': '暫無輸出內容。', + + // ─── Prompt Editor ────────────────────────────────────── + 'promptEditor.worktree': '工作樹', + 'promptEditor.bypassWarning': '跳過模式將授予完整系統訪問許可權', + 'promptEditor.within': '範圍', + 'promptEditor.selectFolder': '— 選擇資料夾以限制範圍', + + // ─── Permission Mode Selector ────────────────────────────────────── + 'permMode.executionPermissions': '執行許可權', + 'permMode.askPermissions': '詢問許可權', + 'permMode.askPermDesc': 'CLI 請求時確認檔案編輯和高風險命令', + 'permMode.autoAccept': '自動接受編輯', + 'permMode.autoAcceptDesc': 'Claude 無需詢問即可寫入磁碟', + 'permMode.planMode': '計劃模式', + 'permMode.planModeDesc': '僅架構和推理,不操作檔案', + 'permMode.bypass': '跳過許可權', + 'permMode.bypassDesc': '對 Shell 和檔案系統的完整工具訪問', + 'permMode.dontAsk': '不詢問', + 'permMode.enableBypassTitle': '啟用跳過許可權?', + 'permMode.enableBypassSubtitle': '這將授予對系統的完全訪問許可權', + 'permMode.enableBypassBody': 'Claude 將擁有不受限制的許可權來執行 Shell 命令和修改以下目錄中的檔案:', + 'permMode.permReadWrite': '讀取、寫入和刪除任何檔案', + 'permMode.permShell': '執行任意 Shell 命令', + 'permMode.permPackages': '安裝或移除軟體包', + 'permMode.enableBypassBtn': '啟用跳過', + + // Mode labels (compact, for chips) + 'permMode.label.default': '詢問許可權', + 'permMode.label.acceptEdits': '自動接受', + 'permMode.label.plan': '計劃模式', + 'permMode.label.bypassPermissions': '跳過', + 'permMode.label.dontAsk': '不詢問', + + // ─── Model Selector ────────────────────────────────────── + 'model.selectModel': '選擇模型', + 'model.configuration': '模型配置', + 'model.effort': '推理強度', + + // ─── Directory Picker ────────────────────────────────────── + 'dirPicker.selectProject': '選擇專案...', + 'dirPicker.recent': '最近', + 'dirPicker.noRecent': '暫無最近專案', + 'dirPicker.chooseFolder': '選擇其他資料夾', + 'dirPicker.chooseProjectFolder': '選擇專案資料夾', + 'dirPicker.useThisFolder': '使用此資料夾', + 'dirPicker.noSubdirs': '無子目錄', + + // ─── File Search ────────────────────────────────────── + 'fileSearch.searching': '搜尋中...', + 'fileSearch.noMatch': '沒有匹配的檔案', + 'fileSearch.noFiles': '此目錄下無檔案', + 'fileSearch.accessDenied': '無法訪問此目錄', + 'fileSearch.loadFailed': '目錄載入失敗', + 'fileSearch.navigate': '導航', + 'fileSearch.attach': '附加', + 'fileSearch.select': '選擇', + 'fileSearch.open': '開啟目錄', + 'fileSearch.close': '關閉', + 'fileSearch.directory': '目錄', + 'fileSearch.currentDirectory': '當前目錄', + 'fileSearch.folderTag': '目錄', + 'fileSearch.fileTag': '檔案', + 'fileSearch.openFolder': '開啟目錄', + + // ─── Teams ────────────────────────────────────── + 'teams.backToLeader': '\u2190 返回主控', + 'teams.viewing': '檢視:', + 'teams.transcript': '記錄', + 'teams.noMessages': '暫無訊息', + 'teams.team': '團隊:', + 'teams.members': '名成員', + 'teams.working': '正在工作中...', + 'teams.thinking': '正在思考中...', + 'teams.running': '執行中', + 'teams.leader': '主控', + 'teams.memberPlaceholder': '直接給這個 Agent 發訊息...', + 'teams.memberSessionHint': '這裡傳送的訊息會直接投遞給該 Agent,同時繼續重新整理它的 transcript。', + + // ─── Scheduled Tasks Pages ────────────────────────────────────── + 'scheduledPage.title': '定時任務', + 'scheduledPage.subtitle': '按計劃或在需要時執行任務。在任意會話中輸入 {code} 即可建立。', + 'scheduledPage.desktopNotice': '定時任務僅在桌面應用開啟時執行。請確保應用持續執行以按時觸發任務。', + 'scheduledPage.oldSubtitle': '管理自動化運維流程和後臺維護任務。', + 'scheduledPage.executionMode': '執行模式', + 'scheduledPage.localMode': '本地模式', + 'scheduledPage.remoteMode': '遠端模式', + 'scheduledPage.nextRun': '下次執行', + 'scheduledPage.systemHealth': '系統健康', + 'scheduledPage.activeSession': '活躍會話', + 'scheduledPage.colTaskName': '任務名稱', + 'scheduledPage.colFrequency': '頻率', + 'scheduledPage.colLastResult': '上次結果', + 'scheduledPage.colNextExecution': '下次執行', + 'scheduledPage.colActions': '操作', + 'scheduledPage.endOfList': '任務列表結束', + 'scheduledPage.pausedTasks': '另有 9 個任務當前已暫停或因維護而禁用。', + 'scheduledPage.recentLogs': '最近輸出日誌', + 'scheduledPage.viewArtifacts': '檢視完整產物', + 'scheduledPage.resourceAllocation': '資源分配', + 'scheduledPage.cpuCapacity': 'CPU 容量', + 'scheduledPage.memoryLoad': '記憶體負載', + 'scheduledPage.connectedLocal': '已連線到本地節點', + 'scheduledPage.thisMonth': '本月 {count}', + + // ─── 更新檢查 ────────────────────────────────────── + 'update.available': 'v{version} 可用', + 'update.availableLabel': '可更新版本', + 'update.checking': '正在檢查更新...', + 'update.checkNow': '檢查更新', + 'update.checkedAt': '上次檢查時間 {time}', + 'update.currentVersionUnknown': '未知版本', + 'update.newVersion': '新版本 v{version} 可用', + 'update.downloading': '下載中...', + 'update.downloaded': '更新已下載。方便時重啟即可使用新版。', + 'update.idle': '點選檢查更新,對比當前安裝版本和 GitHub Releases 的最新版本。', + 'update.installAndRestart': '安裝並重啟', + 'update.installing': '正在安裝更新...', + 'update.now': '立即更新', + 'update.later': '稍後', + 'update.progress': '正在下載更新... {progress}%', + 'update.progressBytes': '正在下載更新... 已下載 {downloaded}', + 'update.proxyAdvanced': '高階更新代理', + 'update.proxyModeManual': '手動代理', + 'update.proxyModeManualDescription': '使用你填寫的本地 HTTP 代理地址。', + 'update.proxyModeSystem': '系統代理', + 'update.proxyModeSystemDescription': '自動使用系統 HTTP/HTTPS 代理。', + 'update.proxySave': '儲存', + 'update.proxyScopeHint': '這裡隻影響應用自身的更新檢查和安裝包下載。', + 'update.proxyUrl': '代理地址', + 'update.proxyUrlHint': '支援 HTTP 和 HTTPS 代理,例如 http://127.0.0.1:7890。', + 'update.proxyUrlInvalid': '請輸入 HTTP 或 HTTPS 代理地址。', + 'update.proxyUrlRequired': '請輸入代理地址。', + 'update.releaseNotes': '更新說明', + 'update.readyBody': 'v{version} 已下載。方便時重啟即可使用新版。', + 'update.readyTitle': '更新已準備好', + 'update.restarting': '正在重啟以完成更新...', + 'update.upToDate': '當前已是最新版本 v{version}。', + 'update.failed': '更新失敗: {error}', + + // ─── 活躍會話 ────────────────────────────────────── + 'session.untitled': '未命名會話', + 'session.active': '會話活躍中', + 'session.lastUpdated': '最後更新 {time}', + 'session.messages': '{count} 條訊息', + 'session.historyLoadFailed': '歷史會話載入失敗。', + 'session.workspaceUnavailable': '工作目錄不可用: {dir}', + 'session.timeJustNow': '剛剛', + 'session.timeMinutes': '{n}分鐘前', + 'session.timeHours': '{n}小時前', + 'session.timeDays': '{n}天前', + + // ─── 應用外殼 ────────────────────────────────────── + 'app.serverFailed': '本地服務啟動失敗', + 'app.serverFailedHint': '反饋這個問題時,請把這塊診斷資訊截圖一起發到 issue 裡。', + 'app.startupError': '啟動錯誤', + 'app.serverLogs': '服務日誌', + 'app.copyDiagnostics': '複製診斷資訊', + 'app.copiedDiagnostics': '已複製', + 'app.launching': '正在啟動本地工作區...', + + // ─── Error Codes ────────────────────────────────────── + 'error.CLI_NOT_RUNNING': 'CLI 程序未執行。會話可能已結束或程序已崩潰。', + 'error.CLI_START_FAILED': 'CLI 程序啟動失敗。', + 'error.CLI_AUTH_REQUIRED': '需要認證。請先登入。', + 'error.CLI_SESSION_CONFLICT': '會話已被其他程序佔用。', + 'error.CLI_SPAWN_FAILED': 'CLI 子程序啟動失敗。', + 'error.CLI_ERROR': '處理過程中發生錯誤。', + 'error.WORKDIR_INVALID': '工作目錄無效或不存在。', + 'error.PARSE_ERROR': '訊息格式無效。', + 'error.UNKNOWN_TYPE': '未知的訊息型別。', + 'error.BAD_REQUEST': '請求無效。', + 'error.NOT_FOUND': '資源未找到。', + 'error.INTERNAL_ERROR': '內部伺服器錯誤。', + + // ─── 業務錯誤 ────────────────────────────────────── + 'businessError.pdf_too_large': '這個 PDF 超出了當前模型可處理的大小。請先轉成文字,或換一個更小的 PDF。', + 'businessError.pdf_password_protected': '這個 PDF 有密碼保護。請先解鎖或轉換後再傳送。', + 'businessError.pdf_invalid': '這個 PDF 檔案無效。請先轉成文字,或換一個檔案傳送。', + 'businessError.image_too_large': '這張圖片超出了當前模型可處理的大小。請壓縮圖片,或換一張更小的圖片。', + 'businessError.image_unsupported': '當前模型不支援圖片。請繼續使用文字,或切換到支援視覺的模型後重新傳送圖片。', + 'businessError.request_too_large': '這次請求超出了當前模型可處理的大小。請移除大檔案,或縮短訊息後重試。', + 'businessError.prompt_too_long': '當前上下文超出了模型限制。請先壓縮會話,或減少上下文後重試。', + 'businessError.auto_mode_unavailable': '當前套餐不支援自動模式。', + + // ─── Server Status Verbs ────────────────────────────────────── + 'serverVerb.Thinking': '思考中', + 'serverVerb.Compacting conversation': '正在壓縮上下文', + 'serverVerb.Running': '執行中', + 'serverVerb.Working': '處理中', + 'serverVerb.Creating worktree': '正在建立工作樹', + 'serverVerb.Task started': '任務已啟動', + 'serverVerb.Task in progress': '任務進行中', + 'chat.retry.title': '請求失敗,正在重試', + 'chat.retry.attempt': '第 {attempt}/{max} 次', + 'chat.retry.httpStatus': 'HTTP {status}', + 'chat.retry.networkError': '網路錯誤', + 'chat.retry.waiting': '等待 {seconds}s', + + // ─── Tabs ────────────────────────────────────── + 'tabs.close': '關閉', + 'tabs.closeOthers': '關閉其他', + 'tabs.closeLeft': '關閉左側', + 'tabs.closeRight': '關閉右側', + 'tabs.closeAll': '關閉所有', + 'tabs.closeConfirmTitle': '會話執行中', + 'tabs.closeConfirmMessage': '此會話仍在執行,你想要怎麼做?', + 'tabs.closeConfirmKeep': '保持執行', + 'tabs.closeConfirmStop': '停止並關閉', + 'tabs.closeAllConfirmTitle': '多個會話執行中', + // ─── Slash Command Descriptions ────────────────────────────────────── + 'slashCmd.agent.description': '使用指定 Agent 執行提示', + 'slashCmd.mcp.description': '開啟當前聊天上下文中可用的 MCP 工具', + 'slashCmd.skills.description': '瀏覽當前上下文中可直接呼叫的技能', + 'slashCmd.help.description': '檢視可用的桌面端與 Agent 命令', + 'slashCmd.status.description': '檢視會話狀態、用量和上下文', + 'slashCmd.cost.description': '檢視會話用量和費用', + 'slashCmd.context.description': '檢視當前上下文用量', + 'slashCmd.plugin.description': '在設定中開啟外掛管理', + 'slashCmd.memory.description': '在設定中開啟專案記憶檔案', + 'slashCmd.doctor.description': '在診斷中開啟 Doctor', + 'slashCmd.compact.description': '壓縮會話上下文', + 'slashCmd.clear.description': '清空會話歷史', + 'slashCmd.goal.description': '設定完成目標', + 'slashCmd.review.description': '審查程式碼變更', + 'slashCmd.commit.description': '建立 git 提交', + 'slashCmd.pr.description': '建立 Pull Request', + 'slashCmd.init.description': '初始化專案 CLAUDE.md', + 'slashCmd.bug.description': '報告 Bug', + 'slashCmd.config.description': '開啟配置', + 'slashCmd.login.description': '切換 Anthropic 賬戶', + 'slashCmd.logout.description': '登出當前賬戶', + 'slashCmd.model.description': '切換 AI 模型', + 'slashCmd.permissions.description': '檢視或管理工具許可權', + 'slashCmd.terminal-setup.description': '設定終端整合', + 'slashCmd.vim.description': '切換 vim 編輯模式', + + 'tabs.closeAllConfirmMessage': '仍有 {count} 個會話正在執行。關閉這些標籤前是否停止它們?', + 'tabs.closeAllConfirmStop': '全部停止並關閉', + 'tabs.sessionRunning': '會話執行中', + 'tabs.openTerminal': '開啟終端', + 'tabs.showWorkspace': '顯示工作區', + 'tabs.hideWorkspace': '隱藏工作區', + 'tabs.showBrowser': '顯示瀏覽器', + 'tabs.hideBrowser': '隱藏瀏覽器', +} diff --git a/desktop/src/lib/formatMessageTimestamp.test.ts b/desktop/src/lib/formatMessageTimestamp.test.ts index f7e83d9b1..f81055558 100644 --- a/desktop/src/lib/formatMessageTimestamp.test.ts +++ b/desktop/src/lib/formatMessageTimestamp.test.ts @@ -26,4 +26,34 @@ describe('formatMessageTimestamp', () => { expect(formatMessageTimestamp(value, t('zh'), 'zh', now)).toBe('4月20日 09:30') }) + + it('formats Japanese history with Han year/month/day characters', () => { + const weekday = new Date(2026, 4, 24, 15, 50).getTime() + expect(formatMessageTimestamp(weekday, t('jp'), 'jp', now)).toContain('15:50') + + const monthDay = new Date(2026, 3, 20, 9, 30).getTime() + expect(formatMessageTimestamp(monthDay, t('jp'), 'jp', now)).toBe('4月20日 09:30') + + const yearMonthDay = new Date(2025, 11, 15, 9, 30).getTime() + expect(formatMessageTimestamp(yearMonthDay, t('jp'), 'jp', now)).toBe('2025年12月15日 09:30') + + expect(formatMessageTimestamp(now - 5 * 60_000, t('jp'), 'jp', now)).toBe('5 分前') + }) + + it('formats Traditional Chinese history with Han year/month/day characters', () => { + const monthDay = new Date(2026, 3, 20, 9, 30).getTime() + expect(formatMessageTimestamp(monthDay, t('zh-TW'), 'zh-TW', now)).toBe('4月20日 09:30') + + const yearMonthDay = new Date(2025, 11, 15, 9, 30).getTime() + expect(formatMessageTimestamp(yearMonthDay, t('zh-TW'), 'zh-TW', now)).toBe('2025年12月15日 09:30') + }) + + it('formats Korean history via Intl (ko-KR) without Han characters', () => { + const monthDay = new Date(2026, 3, 20, 9, 30).getTime() + const out = formatMessageTimestamp(monthDay, t('kr'), 'kr', now) + expect(out).toContain('09:30') + expect(out).not.toContain('月') // Korean uses 월, never the Han 月 + + expect(formatMessageTimestamp(now - 5 * 60_000, t('kr'), 'kr', now)).toBe('5분 전') + }) }) diff --git a/desktop/src/lib/formatMessageTimestamp.ts b/desktop/src/lib/formatMessageTimestamp.ts index 455de31b6..65d71877f 100644 --- a/desktop/src/lib/formatMessageTimestamp.ts +++ b/desktop/src/lib/formatMessageTimestamp.ts @@ -52,19 +52,32 @@ function coerceDate(value: number | string | Date): Date | null { } function localeToIntl(locale: Locale): string { - return locale === 'zh' ? 'zh-CN' : 'en-US' + switch (locale) { + case 'zh': return 'zh-CN' + case 'zh-TW': return 'zh-TW' + case 'jp': return 'ja-JP' + case 'kr': return 'ko-KR' + default: return 'en-US' + } +} + +// Locales whose dates use the 年/月/日 Han characters: Chinese (Simplified/Traditional) +// and Japanese share identical glyphs. Korean uses 년/월/일, so it goes through Intl instead. +function usesHanYmd(locale: Locale): boolean { + return locale === 'zh' || locale === 'zh-TW' || locale === 'jp' } function formatWeekdayTime(date: Date, locale: Locale): string { const intlLocale = localeToIntl(locale) - const weekday = new Intl.DateTimeFormat(intlLocale, { weekday: locale === 'zh' ? 'long' : 'short' }).format(date) + const han = usesHanYmd(locale) + const weekday = new Intl.DateTimeFormat(intlLocale, { weekday: han ? 'long' : 'short' }).format(date) const time = formatClockTime(date, intlLocale) - return locale === 'zh' ? `${weekday}${time}` : `${weekday} ${time}` + return han ? `${weekday}${time}` : `${weekday} ${time}` } function formatMonthDayTime(date: Date, locale: Locale): string { const intlLocale = localeToIntl(locale) - if (locale === 'zh') { + if (usesHanYmd(locale)) { return `${date.getMonth() + 1}月${date.getDate()}日 ${formatClockTime(date, intlLocale)}` } const day = new Intl.DateTimeFormat(intlLocale, { @@ -76,7 +89,7 @@ function formatMonthDayTime(date: Date, locale: Locale): string { function formatYearMonthDayTime(date: Date, locale: Locale): string { const intlLocale = localeToIntl(locale) - if (locale === 'zh') { + if (usesHanYmd(locale)) { return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${formatClockTime(date, intlLocale)}` } const day = new Intl.DateTimeFormat(intlLocale, { diff --git a/desktop/src/pages/ActivitySettings.tsx b/desktop/src/pages/ActivitySettings.tsx index 9f73851a3..8f581c5a3 100644 --- a/desktop/src/pages/ActivitySettings.tsx +++ b/desktop/src/pages/ActivitySettings.tsx @@ -51,6 +51,9 @@ const HEAT_COLORS = [ const DATE_LOCALES: Record = { en: 'en-US', zh: 'zh-CN', + 'zh-TW': 'zh-TW', + jp: 'ja-JP', + kr: 'ko-KR', } const DEFAULT_PROFILE: DesktopProfilePreferences = { displayName: 'cc-haha', diff --git a/desktop/src/pages/Settings.tsx b/desktop/src/pages/Settings.tsx index 205c4770f..e9f25d9f2 100644 --- a/desktop/src/pages/Settings.tsx +++ b/desktop/src/pages/Settings.tsx @@ -1520,9 +1520,13 @@ function GeneralSettings() { const LANGUAGES: Array<{ value: Locale; label: string }> = [ { value: 'en', label: 'English' }, - { value: 'zh', label: '中文' }, + { value: 'zh', label: '简体中文' }, + { value: 'zh-TW', label: '繁體中文' }, + { value: 'jp', label: '日本語' }, + { value: 'kr', label: '한국어' }, ] + const RESPONSE_LANGUAGES: Array<{ value: string; label: string }> = [ { value: '', label: t('settings.general.responseLangDefault') }, { value: 'english', label: 'English' }, diff --git a/desktop/src/stores/settingsStore.ts b/desktop/src/stores/settingsStore.ts index e1aef29a5..e79992102 100644 --- a/desktop/src/stores/settingsStore.ts +++ b/desktop/src/stores/settingsStore.ts @@ -41,10 +41,12 @@ export const UI_ZOOM_STEP = APP_ZOOM_CONTROL_STEP export const UI_ZOOM_DEFAULT = DEFAULT_APP_ZOOM let desktopNotificationsSaveQueue: Promise = Promise.resolve() +const VALID_LOCALES: readonly Locale[] = ['en', 'zh', 'zh-TW', 'jp', 'kr'] + function getStoredLocale(): Locale { try { const stored = localStorage.getItem(LOCALE_STORAGE_KEY) - if (stored === 'en' || stored === 'zh') return stored + if (stored && (VALID_LOCALES as readonly string[]).includes(stored)) return stored as Locale } catch { /* localStorage unavailable */ } return 'zh' }