mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-21 14:03:35 +08:00
The desktop sidebar needed a project-first navigation model that keeps worktree sessions attached to their source project instead of scattering them as separate paths. The UI now renders sessions under project groups with project-level actions and persisted ordering, while the server exposes a logical project root for worktree transcripts. Constraint: Existing memory directory tree work must remain separate from the session sidebar behavior. Rejected: Group by raw transcript projectPath | worktree paths fragment the same repository into multiple sidebar projects. Confidence: high Scope-risk: moderate Directive: Keep future sidebar grouping keyed by projectRoot before projectPath so isolated worktrees stay under their source repository. Tested: cd desktop && bun run test -- src/components/layout/Sidebar.test.tsx Tested: bun test src/server/__tests__/sessions.test.ts Tested: git diff --check
1392 lines
83 KiB
TypeScript
1392 lines
83 KiB
TypeScript
export const en = {
|
||
// ─── Common ──────────────────────────────────────
|
||
'common.cancel': 'Cancel',
|
||
'common.save': 'Save',
|
||
'common.delete': 'Delete',
|
||
'common.add': 'Add',
|
||
'common.run': 'Run',
|
||
'common.send': 'Send',
|
||
'common.stop': 'Stop',
|
||
'common.rename': 'Rename',
|
||
'common.retry': 'Retry',
|
||
'common.loading': 'Loading...',
|
||
'common.select': 'Select',
|
||
'common.enable': 'Enable',
|
||
'common.disable': 'Disable',
|
||
'common.active': 'ACTIVE',
|
||
'common.copyFailed': 'Copy failed.',
|
||
|
||
// ─── Sidebar ──────────────────────────────────────
|
||
'sidebar.newSession': 'New session',
|
||
'sidebar.scheduled': 'Scheduled',
|
||
'sidebar.terminal': 'Terminal',
|
||
'sidebar.settings': 'Settings',
|
||
'sidebar.searchPlaceholder': 'Search sessions...',
|
||
'sidebar.noSessions': 'No sessions yet',
|
||
'sidebar.noMatching': 'No matching sessions',
|
||
'sidebar.sessionListFailed': 'Session list failed to load',
|
||
'sidebar.refreshSessions': 'Refresh sessions',
|
||
'sidebar.projects': 'Projects',
|
||
'sidebar.projectActions': 'Project actions for {project}',
|
||
'sidebar.pinProject': 'Pin Project',
|
||
'sidebar.unpinProject': 'Unpin Project',
|
||
'sidebar.openInFinder': 'Open in Finder',
|
||
'sidebar.openInFinderFailed': 'Could not open the project in Finder.',
|
||
'sidebar.openInFinderUnavailable': 'No file manager is available.',
|
||
'sidebar.createPermanentWorktree': 'Create Permanent Worktree',
|
||
'sidebar.renameProject': 'Rename Project',
|
||
'sidebar.archiveSessions': 'Archive Conversations',
|
||
'sidebar.removeProject': 'Remove',
|
||
'sidebar.newSessionInProject': 'New session in {project}',
|
||
'sidebar.showMoreSessions': 'Show {count} more',
|
||
'sidebar.showFewerSessions': 'Show fewer',
|
||
'sidebar.expandProject': 'Expand {project}',
|
||
'sidebar.collapseProject': 'Collapse {project}',
|
||
'sidebar.worktree': 'worktree',
|
||
'sidebar.missingDir': 'missing dir',
|
||
'sidebar.confirmDelete': 'Delete this session? This cannot be undone.',
|
||
'sidebar.batchManage': 'Batch manage',
|
||
'sidebar.batchSelectedCount': '{count} selected',
|
||
'sidebar.batchSelectAll': 'Select all',
|
||
'sidebar.batchDeselectAll': 'Deselect all',
|
||
'sidebar.batchSelectGroup': 'Select {group}',
|
||
'sidebar.batchDeleteSelected': 'Delete selected ({count})',
|
||
'sidebar.batchDeleteConfirm': 'Delete {count} sessions? This cannot be undone.',
|
||
'sidebar.batchDeleteConfirmBody': 'The following sessions will be deleted:',
|
||
'sidebar.batchDeleteMore': '...and {count} more',
|
||
'sidebar.batchExit': 'Cancel batch mode',
|
||
'sidebar.batchDeleteSucceeded': 'Deleted {count} sessions.',
|
||
'sidebar.batchDeleteFailed': '{count} sessions could not be deleted.',
|
||
'sidebar.allProjects': 'All projects',
|
||
'sidebar.other': 'Other',
|
||
'sidebar.timeGroup.today': 'Today',
|
||
'sidebar.timeGroup.yesterday': 'Yesterday',
|
||
'sidebar.timeGroup.last7days': 'Last 7 days',
|
||
'sidebar.timeGroup.last30days': 'Last 30 days',
|
||
'sidebar.timeGroup.older': 'Older',
|
||
'sidebar.collapse': 'Collapse sidebar',
|
||
'sidebar.expand': 'Expand sidebar',
|
||
|
||
// ─── Title Bar ──────────────────────────────────────
|
||
'titlebar.code': 'Code',
|
||
'titlebar.terminal': 'Terminal',
|
||
'titlebar.history': 'History',
|
||
|
||
// ─── Open Project ──────────────────────────────────────
|
||
'openProject.openProject': 'Open project',
|
||
'openProject.openIn': 'Open in {target}',
|
||
'openProject.openFailed': 'Could not open project',
|
||
|
||
// ─── Workspace Panel ───────────────────────────────
|
||
'workspace.changedFiles': 'Changed files',
|
||
'workspace.allFiles': 'All files',
|
||
'workspace.viewTabs': 'Workspace views',
|
||
'workspace.previewTabs': 'Preview tabs',
|
||
'workspace.filterPlaceholder': 'Filter files...',
|
||
'workspace.clearFilter': 'Clear file filter',
|
||
'workspace.refresh': 'Refresh workspace',
|
||
'workspace.closePanel': 'Close workspace panel',
|
||
'workspace.resizePanel': 'Resize workspace panel',
|
||
'workspace.closeTab': 'Close tab',
|
||
'workspace.preview': 'Preview',
|
||
'workspace.previewEmpty': 'Select a file to preview.',
|
||
'workspace.notGitRepo': 'Not a git repository.',
|
||
'workspace.missingWorkdir': 'Working directory is missing.',
|
||
'workspace.loadError': 'Failed to load workspace data.',
|
||
'workspace.noChanges': 'No changes',
|
||
'workspace.noFiles': 'No files',
|
||
'workspace.noMatchingFiles': 'No matching files',
|
||
'workspace.previewKind.diff': 'Diff',
|
||
'workspace.previewKind.file': 'File',
|
||
'workspace.previewState.loading': 'Loading preview...',
|
||
'workspace.previewState.binary': 'Binary file preview is unavailable.',
|
||
'workspace.previewState.tooLarge': 'File is too large to preview.',
|
||
'workspace.previewState.missing': 'File not found.',
|
||
'workspace.imagePreviewUnavailable': 'Image preview is unavailable.',
|
||
'workspace.previewLineLimit': 'Showing first {count} of {total} loaded lines.',
|
||
'workspace.previewAllLines': 'Showing all {total} loaded lines.',
|
||
'workspace.showAllLoadedLines': 'Show all loaded lines',
|
||
'workspace.collapsePreview': 'Collapse preview',
|
||
'workspace.addToChat': 'Add to chat',
|
||
'workspace.addSelectionToChat': 'Add to chat',
|
||
'workspace.copyPath': 'Copy path',
|
||
'workspace.pathCopied': 'Path copied.',
|
||
'workspace.localComment': 'Local comment',
|
||
'workspace.commentLine': 'Comment line {line}',
|
||
'workspace.commentLineTarget': 'Line {line}',
|
||
'workspace.commentPlaceholder': 'Describe what should change here...',
|
||
'workspace.addCommentToChat': 'Add comment',
|
||
|
||
// ─── Status Bar ──────────────────────────────────────
|
||
'status.connected': 'Connected',
|
||
'status.connecting': 'Connecting...',
|
||
'status.reconnecting': 'Reconnecting...',
|
||
'status.disconnected': 'Disconnected',
|
||
|
||
// ─── Settings ──────────────────────────────────────
|
||
'settings.title': 'Settings',
|
||
'settings.tab.providers': 'Providers',
|
||
'settings.tab.permissions': 'Permissions',
|
||
'settings.tab.activity': 'Token usage',
|
||
'settings.tab.general': 'General',
|
||
'settings.tab.h5Access': 'H5 Access',
|
||
'settings.tab.terminal': 'Terminal',
|
||
'settings.tab.skills': 'Skills',
|
||
'settings.tab.mcp': 'MCP',
|
||
'settings.tab.plugins': 'Plugins',
|
||
'settings.tab.diagnostics': 'Diagnostics',
|
||
|
||
// Settings > Usage
|
||
'settings.activity.title': 'Token usage',
|
||
'settings.activity.subtitleLoading': 'Based on local Claude Code CLI session transcripts',
|
||
'settings.activity.metric.yesterday': 'Yesterday',
|
||
'settings.activity.metric.today': 'Today',
|
||
'settings.activity.metric.last4': 'Last 4 days',
|
||
'settings.activity.metric.last30': '30 days',
|
||
'settings.activity.metric.streak': 'Streak',
|
||
'settings.activity.metric.bestStreak': 'best {days} days',
|
||
'settings.activity.heatmapLabel': 'Token usage by day',
|
||
'settings.activity.count.sessionOne': '{count} session',
|
||
'settings.activity.count.sessionOther': '{count} sessions',
|
||
'settings.activity.count.dayOne': '{count} day',
|
||
'settings.activity.count.dayOther': '{count} days',
|
||
'settings.activity.weekday.mon': 'Mon',
|
||
'settings.activity.weekday.wed': 'Wed',
|
||
'settings.activity.weekday.fri': 'Fri',
|
||
'settings.activity.selectedDay': 'Selected day',
|
||
'settings.activity.sessions': 'Sessions',
|
||
'settings.activity.tokens': 'Tokens',
|
||
'settings.activity.messages': 'Messages',
|
||
'settings.activity.tools': 'Tools',
|
||
'settings.activity.less': 'Less',
|
||
'settings.activity.more': 'More',
|
||
|
||
// Settings > Terminal
|
||
'settings.terminal.title': 'Terminal',
|
||
'settings.terminal.description': 'Run host-machine commands for plugin, skill, and MCP setup. The desktop app includes claude-haha; replace documented claude <args> with claude-haha <args>, for example: claude-haha plugin install ... or claude-haha mcp add ...',
|
||
'settings.terminal.clear': 'Clear',
|
||
'settings.terminal.restart': 'Restart',
|
||
'settings.terminal.windowTitle': 'Host shell',
|
||
'settings.terminal.unavailableTitle': 'Desktop runtime required',
|
||
'settings.terminal.unavailableBody': 'Open this page in the packaged desktop app to start an interactive terminal.',
|
||
'settings.terminal.status.idle': 'Idle',
|
||
'settings.terminal.status.starting': 'Starting',
|
||
'settings.terminal.status.running': 'Running',
|
||
'settings.terminal.status.exited': 'Exited',
|
||
'settings.terminal.status.error': 'Error',
|
||
'settings.terminal.status.unavailable': 'Unavailable',
|
||
'terminal.newTab': 'New Terminal',
|
||
'terminal.openInTab': 'Open in Tab',
|
||
'terminal.closePanel': 'Close terminal panel',
|
||
'terminal.resizePanel': 'Resize terminal panel',
|
||
|
||
// Settings > Diagnostics
|
||
'settings.diagnostics.title': 'Diagnostics',
|
||
'settings.diagnostics.description': 'Server and CLI runtime logs for debugging startup, provider, and session failures.',
|
||
'settings.diagnostics.refresh': 'Refresh',
|
||
'settings.diagnostics.totalSize': 'Log size',
|
||
'settings.diagnostics.events': 'Events',
|
||
'settings.diagnostics.recentErrors': '24h warnings',
|
||
'settings.diagnostics.retention': 'Retention',
|
||
'settings.diagnostics.retentionValue': '{days} days / {size}',
|
||
'settings.diagnostics.logDirectory': 'Log directory',
|
||
'settings.diagnostics.openDirectory': 'Open',
|
||
'settings.diagnostics.exportBundle': 'Export Bundle',
|
||
'settings.diagnostics.copySummary': 'Copy Error Summary',
|
||
'settings.diagnostics.clearLogs': 'Clear Logs',
|
||
'settings.diagnostics.recentEvents': 'Recent Events',
|
||
'settings.diagnostics.privacyNote': 'Exported diagnostics are sanitized and do not include chat content, file contents, full environment variables, or API keys.',
|
||
'settings.diagnostics.noEvents': 'No diagnostic events yet.',
|
||
'settings.diagnostics.noRecentErrors': 'No recent warnings or errors.',
|
||
'settings.diagnostics.loadFailed': 'Failed to load diagnostics.',
|
||
'settings.diagnostics.openFailed': 'Failed to open diagnostics directory.',
|
||
'settings.diagnostics.exportFailed': 'Failed to export diagnostics bundle.',
|
||
'settings.diagnostics.exported': 'Exported {file}',
|
||
'settings.diagnostics.summaryCopied': 'Error summary copied.',
|
||
'settings.diagnostics.copyFailed': 'Failed to copy error summary.',
|
||
'settings.diagnostics.confirmClear': 'Clear all local diagnostic logs and exported bundles?',
|
||
'settings.diagnostics.cleared': 'Diagnostics cleared.',
|
||
'settings.diagnostics.clearFailed': 'Failed to clear diagnostics.',
|
||
'settings.diagnostics.eventDetails': 'Details',
|
||
'settings.diagnostics.doctorTitle': 'Doctor',
|
||
'settings.diagnostics.doctorDescription': 'Safe desktop repair for startup and UI state problems.',
|
||
'settings.diagnostics.doctorProtectedData': 'Never touches chat history, model config, skills, MCP, IM, or OAuth.',
|
||
'settings.diagnostics.doctorSafeKeys': 'Clears only: cc-haha-open-tabs, cc-haha-session-runtime, cc-haha-theme, cc-haha-locale, and cc-haha.persistence.schemaVersion.',
|
||
'settings.diagnostics.runDoctor': 'Run Doctor',
|
||
'settings.diagnostics.doctorCompleted': 'Doctor completed.',
|
||
'settings.diagnostics.doctorPartial': 'Doctor completed with {count} local cleanup issue(s).',
|
||
'settings.diagnostics.doctorFailed': 'Doctor failed.',
|
||
'settings.diagnostics.doctorResultLocal': 'Cleared {count} safe UI key(s).',
|
||
'settings.diagnostics.doctorResultFailedKeys': '{count} key(s) could not be removed.',
|
||
'settings.diagnostics.doctorServerRan': 'Server Doctor repair also ran.',
|
||
'settings.diagnostics.doctorServerUnavailable': 'Server Doctor was unavailable, so only local repair ran.',
|
||
'errorBoundary.title': 'Something went wrong.',
|
||
'errorBoundary.description': 'The error was recorded in Diagnostics.',
|
||
|
||
// Settings > Claude Official Login
|
||
'settings.claudeOfficialLogin.intro': 'Using official Claude models requires signing in to your Claude.ai account. Click the button below to open the official Claude login page in your browser; you\'ll be returned here after authorizing.',
|
||
'settings.claudeOfficialLogin.loginButton': 'Sign in to Claude',
|
||
'settings.claudeOfficialLogin.loginStarting': 'Opening…',
|
||
'settings.claudeOfficialLogin.logoutButton': 'Sign out',
|
||
'settings.claudeOfficialLogin.logoutProcessing': 'Processing…',
|
||
'settings.claudeOfficialLogin.loggedInPrefix': 'Signed in (Claude',
|
||
'settings.claudeOfficialLogin.subTypeUnknown': 'Unknown',
|
||
'settings.claudeOfficialLogin.errorPrefix': 'Error: ',
|
||
'settings.claudeOfficialLogin.openBrowserFailed': 'Failed to open browser; please visit the authorization URL manually.',
|
||
|
||
// Settings > Providers
|
||
'settings.providers.title': 'Providers',
|
||
'settings.providers.description': 'Manage API providers for model access.',
|
||
'settings.providers.addProvider': 'Add Provider',
|
||
'settings.providers.officialName': 'Claude Official',
|
||
'settings.providers.officialDesc': 'Anthropic native — no API key required',
|
||
'settings.providers.connected': 'Connected ({latency}ms)',
|
||
'settings.providers.failed': 'Failed: {error}',
|
||
'settings.providers.connectivityOk': '① Connectivity ({latency}ms)',
|
||
'settings.providers.connectivityFailed': '① Connectivity failed: {error}',
|
||
'settings.providers.proxyOk': '② Proxy pipeline ({latency}ms)',
|
||
'settings.providers.proxyFailed': '② Proxy failed: {error}',
|
||
'settings.providers.confirmDelete': 'Delete provider "{name}"? This cannot be undone.',
|
||
'settings.providers.activate': 'Activate',
|
||
'settings.providers.default': 'Default',
|
||
'settings.providers.setDefault': 'Set default',
|
||
'settings.providers.test': 'Test',
|
||
'settings.providers.edit': 'Edit',
|
||
'settings.providers.requestFailed': 'Request failed',
|
||
'settings.providers.addTitle': 'Add Provider',
|
||
'settings.providers.editTitle': 'Edit Provider',
|
||
'settings.providers.preset': 'Preset',
|
||
'settings.providers.name': 'Name',
|
||
'settings.providers.namePlaceholder': 'Provider name',
|
||
'settings.providers.notes': 'Notes',
|
||
'settings.providers.notesPlaceholder': 'Optional notes...',
|
||
'settings.providers.baseUrl': 'Base URL',
|
||
'settings.providers.baseUrlPlaceholder': 'https://api.example.com/anthropic',
|
||
'settings.providers.apiKey': 'API Key',
|
||
'settings.providers.apiKeyKeep': 'API Key (leave blank to keep current)',
|
||
'settings.providers.getApiKey': 'Get API Key',
|
||
'settings.providers.modelMapping': 'Model Mapping',
|
||
'settings.providers.mainModel': 'Main Model',
|
||
'settings.providers.haikuModel': 'Haiku Model',
|
||
'settings.providers.sonnetModel': 'Sonnet Model',
|
||
'settings.providers.opusModel': 'Opus Model',
|
||
'settings.providers.sameAsMain': 'Same as main',
|
||
'settings.providers.contextSettingsTitle': 'Context and auto-compact',
|
||
'settings.providers.contextSettingsDesc': 'Preset limits are applied automatically. Edit only when the provider changes limits or you use a custom model ID.',
|
||
'settings.providers.contextSettingsEdit': 'Advanced',
|
||
'settings.providers.contextSettingsHide': 'Hide',
|
||
'settings.providers.contextSummaryAuto': 'Auto-detect configured models; unknown models use the built-in fallback',
|
||
'settings.providers.contextFallbackAuto': 'Unknown models: auto',
|
||
'settings.providers.contextFallbackSummary': 'Unknown models: {tokens}',
|
||
'settings.providers.modelContextWindows': 'Model context windows',
|
||
'settings.providers.mainContextWindow': 'Main model context',
|
||
'settings.providers.haikuContextWindow': 'Haiku model context',
|
||
'settings.providers.sonnetContextWindow': 'Sonnet model context',
|
||
'settings.providers.opusContextWindow': 'Opus model context',
|
||
'settings.providers.contextWindowPlaceholder': 'e.g. 200000',
|
||
'settings.providers.modelContextWindowsDesc': 'Use each model’s real context window. Presets are filled automatically; blank values fall back to built-in detection or 200K.',
|
||
'settings.providers.modelContextWindowNumberError': 'Enter an integer.',
|
||
'settings.providers.modelContextWindowRangeError': 'Must be between 16000 and 10000000.',
|
||
'settings.providers.autoCompactWindow': 'Unknown Model Fallback Window',
|
||
'settings.providers.autoCompactWindowPlaceholder': 'Optional, e.g. 200000',
|
||
'settings.providers.autoCompactWindowDesc': 'Only used for models that cannot be identified; configured model windows take precedence.',
|
||
'settings.providers.autoCompactWindowNumberError': 'Enter an integer.',
|
||
'settings.providers.autoCompactWindowRangeError': 'Must be between 16000 and 10000000.',
|
||
'settings.providers.testConnection': 'Test Connection',
|
||
'settings.providers.settingsJson': 'Settings JSON',
|
||
'settings.providers.settingsJsonDesc': '~/.claude/cc-haha/settings.json — edit directly, will be written on save.',
|
||
'settings.providers.jsonError': 'JSON syntax error: {error}',
|
||
'settings.providers.apiFormat': 'API Format',
|
||
'settings.providers.apiFormatAnthropic': 'Anthropic Messages (native)',
|
||
'settings.providers.apiFormatOpenaiChat': 'OpenAI Chat Completions (proxy)',
|
||
'settings.providers.apiFormatOpenaiResponses': 'OpenAI Responses API (proxy)',
|
||
'settings.providers.proxyHint': 'Requests will be translated via the local proxy',
|
||
'settings.providers.authStrategy': 'Auth Variable',
|
||
'settings.providers.authStrategyApiKey': 'API Key (ANTHROPIC_API_KEY)',
|
||
'settings.providers.authStrategyApiKeyDesc': 'Direct Anthropic API access using x-api-key.',
|
||
'settings.providers.authStrategyAuthToken': 'Bearer Token (ANTHROPIC_AUTH_TOKEN)',
|
||
'settings.providers.authStrategyAuthTokenDesc': 'Most third-party Anthropic-compatible services using Authorization Bearer.',
|
||
'settings.providers.authStrategyAuthTokenEmptyApiKey': 'Bearer + Empty API_KEY',
|
||
'settings.providers.authStrategyAuthTokenEmptyApiKeyDesc': 'OpenRouter/Ollama-style setups that must avoid falling back to an Anthropic API key.',
|
||
'settings.providers.authStrategyDualSameToken': 'Write token to both variables',
|
||
'settings.providers.authStrategyDualSameTokenDesc': 'Services such as Hugging Face Router that check both variables.',
|
||
'settings.providers.authStrategyDualDummy': 'Write dummy to both variables',
|
||
'settings.providers.authStrategyDualDummyDesc': 'Local vLLM-compatible services that only need placeholder auth values.',
|
||
|
||
// Settings > Permissions
|
||
'settings.permissions.title': 'Permission Mode',
|
||
'settings.permissions.description': 'Controls how tool execution permissions are handled.',
|
||
'settings.permissions.default': 'Ask permissions',
|
||
'settings.permissions.defaultDesc': 'Ask before executing tools',
|
||
'settings.permissions.acceptEdits': 'Accept edits',
|
||
'settings.permissions.acceptEditsDesc': 'Auto-approve file edits, ask for others',
|
||
'settings.permissions.plan': 'Plan mode',
|
||
'settings.permissions.planDesc': 'Think and plan without executing',
|
||
'settings.permissions.bypass': 'Bypass all',
|
||
'settings.permissions.bypassDesc': 'Skip all permission checks (dangerous)',
|
||
|
||
// Settings > Adapters
|
||
'settings.tab.adapters': 'IM Adapters',
|
||
'settings.adapters.description': 'Configure IM adapters to chat with Claude Code via WeChat, DingTalk, Telegram, or Feishu.',
|
||
'settings.adapters.telegram': 'Telegram',
|
||
'settings.adapters.feishu': 'Feishu',
|
||
'settings.adapters.wechat': 'WeChat',
|
||
'settings.adapters.dingtalk': 'DingTalk',
|
||
'settings.adapters.botToken': 'Bot Token',
|
||
'settings.adapters.botTokenPlaceholder': 'Paste token from @BotFather',
|
||
'settings.adapters.appId': 'App ID',
|
||
'settings.adapters.appIdPlaceholder': 'e.g. cli_xxx',
|
||
'settings.adapters.appSecret': 'App Secret',
|
||
'settings.adapters.appSecretPlaceholder': 'From Feishu Open Platform',
|
||
'settings.adapters.encryptKey': 'Encrypt Key',
|
||
'settings.adapters.encryptKeyPlaceholder': 'Optional',
|
||
'settings.adapters.verificationToken': 'Verification Token',
|
||
'settings.adapters.verificationTokenPlaceholder': 'Optional',
|
||
'settings.adapters.allowedUsers': 'Allowed Users',
|
||
'settings.adapters.allowedUsersHint': 'Comma-separated. Leave empty to allow paired users only.',
|
||
'settings.adapters.tgAllowedUsersPlaceholder': 'e.g. 123456789, 987654321',
|
||
'settings.adapters.fsAllowedUsersPlaceholder': 'e.g. ou_xxx, ou_yyy',
|
||
'settings.adapters.wcAllowedUsersPlaceholder': 'e.g. wx_user_id_1, wx_user_id_2',
|
||
'settings.adapters.dtAllowedUsersPlaceholder': 'e.g. manager001, staff_yyy',
|
||
'settings.adapters.defaultProject': 'Default Project',
|
||
'settings.adapters.defaultProjectHint': 'Default working directory for new IM sessions. If empty, the bot uses the current user working directory.',
|
||
'settings.adapters.streamingCard': 'Streaming Card Mode',
|
||
'settings.adapters.streamingCardDesc': 'Real-time card updates for better experience',
|
||
'settings.adapters.serverUrl': 'Server URL',
|
||
'settings.adapters.serverUrlPlaceholder': 'ws://127.0.0.1:3456',
|
||
'settings.adapters.save': 'Save',
|
||
'settings.adapters.saved': 'Saved',
|
||
'settings.adapters.saving': 'Saving...',
|
||
'settings.adapters.startHint': 'After saving, run adapter: cd adapters && bun run {platform}',
|
||
'settings.adapters.pairing': 'Pairing',
|
||
'settings.adapters.pairingDesc': 'Generate a pairing code and send it to the Bot via IM private chat to bind your identity.',
|
||
'settings.adapters.generateCode': 'Generate Code',
|
||
'settings.adapters.regenerateCode': 'Regenerate',
|
||
'settings.adapters.codeExpired': 'Expired',
|
||
'settings.adapters.codeExpiresIn': 'Expires in',
|
||
'settings.adapters.minutes': 'min',
|
||
'settings.adapters.pairingCodeHint': 'Send this code to the Bot in DingTalk, Feishu, WeChat, or Telegram private chat. WeChat requires QR binding first.',
|
||
'settings.adapters.pairedUsers': 'Paired Users',
|
||
'settings.adapters.noPairedUsers': 'No paired users yet',
|
||
'settings.adapters.unbind': 'Unbind',
|
||
'settings.adapters.unbindConfirm': 'Are you sure you want to unbind this user? They will need to re-pair to use the bot.',
|
||
'settings.adapters.platform.telegram': 'Telegram',
|
||
'settings.adapters.platform.feishu': 'Feishu',
|
||
'settings.adapters.platform.wechat': 'WeChat',
|
||
'settings.adapters.platform.dingtalk': 'DingTalk',
|
||
'settings.adapters.dingtalkQrTitle': 'Bind DingTalk bot with QR',
|
||
'settings.adapters.dingtalkQrDesc': 'Scan with the DingTalk mobile app to create and authorize the bot. Client ID / Secret are saved automatically when it succeeds.',
|
||
'settings.adapters.dingtalkStartAuth': 'Scan to bind',
|
||
'settings.adapters.dingtalkUnbindBot': 'Unbind bot account',
|
||
'settings.adapters.dingtalkQrAlt': 'DingTalk authorization QR code',
|
||
'settings.adapters.dingtalkWaiting': 'Waiting for DingTalk scan confirmation...',
|
||
'settings.adapters.dingtalkBound': 'DingTalk bot is bound.',
|
||
'settings.adapters.dingtalkAuthFailed': 'DingTalk QR authorization failed.',
|
||
'settings.adapters.dingtalkAuthExpired': 'DingTalk QR authorization expired. Generate a new QR code.',
|
||
'settings.adapters.dingtalkUnbindFailed': 'Failed to unbind DingTalk.',
|
||
'settings.adapters.dingtalkClientId': 'Client ID',
|
||
'settings.adapters.dingtalkClientIdPlaceholder': 'Filled by QR auth, or enter manually',
|
||
'settings.adapters.dingtalkClientSecret': 'Client Secret',
|
||
'settings.adapters.dingtalkClientSecretPlaceholder': 'Filled by QR auth, or enter manually',
|
||
'settings.adapters.dingtalkEndpoint': 'Stream Endpoint',
|
||
'settings.adapters.dingtalkEndpointPlaceholder': 'Default https://api.dingtalk.com',
|
||
'settings.adapters.dingtalkPermissionCardTemplateId': 'Permission Card Template ID',
|
||
'settings.adapters.dingtalkPermissionCardTemplateIdPlaceholder': 'Optional interactive card template ID',
|
||
'settings.adapters.dingtalkPermissionCardTemplateIdHint': 'When set, permission requests use a DingTalk interactive card first. Leave empty to use /allow, /always, /deny text approval.',
|
||
'settings.adapters.wechatBind': 'Scan to Bind',
|
||
'settings.adapters.wechatRebind': 'Rescan',
|
||
'settings.adapters.wechatConnected': 'WeChat is bound',
|
||
'settings.adapters.wechatNotConnected': 'WeChat is not bound',
|
||
'settings.adapters.wechatQrHint': 'Generate a QR code, scan it in WeChat, then confirm. The adapter restarts after binding.',
|
||
'settings.adapters.wechatQrAlt': 'WeChat binding QR code',
|
||
'settings.adapters.wechatWaiting': 'Waiting for WeChat confirmation...',
|
||
'settings.adapters.wechatBindSuccess': 'WeChat bound successfully.',
|
||
'settings.adapters.wechatUnbindAccount': 'Unbind WeChat account',
|
||
'settings.adapters.wechatUnbound': 'WeChat account unbound.',
|
||
'settings.adapters.wechatUnbindFailed': 'Failed to unbind WeChat.',
|
||
'settings.adapters.wechatAllowedUsersHint': 'QR binding enables the account only. Users still need to send a pairing code, or you can add allowed WeChat user IDs here.',
|
||
|
||
// Settings > MCP
|
||
'settings.mcp.title': 'MCP servers',
|
||
'settings.mcp.description': 'Connect external tools and data sources for Claude Code. Add, edit, reconnect, and disable servers without leaving the desktop app.',
|
||
'settings.mcp.addServer': 'Add server',
|
||
'settings.mcp.empty': 'No MCP servers configured yet',
|
||
'settings.mcp.emptyHint': 'Add a custom stdio, HTTP, or SSE MCP server to start extending tool access.',
|
||
'settings.mcp.stats.total': 'Total servers',
|
||
'settings.mcp.stats.connected': 'Connected now',
|
||
'settings.mcp.stats.attention': 'Need attention',
|
||
'settings.mcp.scope.project': 'Project',
|
||
'settings.mcp.scope.local': 'Local',
|
||
'settings.mcp.scope.user': 'User',
|
||
'settings.mcp.scope.plugin': 'Plugin',
|
||
'settings.mcp.scopeDesc.local': 'Private to you for one project. Stored in your user config, scoped by the selected project.',
|
||
'settings.mcp.scopeDesc.project': 'Shared with the team through the selected project’s `.mcp.json`.',
|
||
'settings.mcp.scopeDesc.user': 'Available in all projects for your user account.',
|
||
'settings.mcp.scope.dynamic': 'Built-in',
|
||
'settings.mcp.scope.enterprise': 'Enterprise',
|
||
'settings.mcp.scope.claudeai': 'Claude.ai',
|
||
'settings.mcp.scope.managed': 'Managed',
|
||
'settings.mcp.transport.http': 'Streamable HTTP',
|
||
'settings.mcp.globalOnlyHint': 'This page manages only user-global MCP servers for speed. Project-specific MCP will move into the chat slash-command experience.',
|
||
'settings.mcp.form.back': 'Back to servers',
|
||
'settings.mcp.form.createTitle': 'Connect to a custom MCP',
|
||
'settings.mcp.form.createHint': 'Set up a custom MCP server with the fields supported by Claude Code today.',
|
||
'settings.mcp.form.editTitle': 'Update {name} MCP',
|
||
'settings.mcp.form.editHint': 'Review connection details, save changes, or reconnect this server from the desktop app.',
|
||
'settings.mcp.form.transportLocked': 'If you would like to switch MCP server type, uninstall first.',
|
||
'settings.mcp.form.uninstall': 'Uninstall',
|
||
'settings.mcp.form.reconnect': 'Reconnect',
|
||
'settings.mcp.form.save': 'Save',
|
||
'settings.mcp.form.name': 'Name',
|
||
'settings.mcp.form.namePlaceholder': 'MCP server name',
|
||
'settings.mcp.form.scope': 'Config scope',
|
||
'settings.mcp.form.transport': 'Transport',
|
||
'settings.mcp.form.status': 'Status',
|
||
'settings.mcp.form.location': 'Config location',
|
||
'settings.mcp.form.rawConfig': 'Raw config',
|
||
'settings.mcp.form.command': 'Command to launch',
|
||
'settings.mcp.form.commandPlaceholder': 'npx',
|
||
'settings.mcp.form.commandHostHint': 'STDIO MCP commands run on the host machine. Install runtimes like Node.js, Python, Bun, or uv yourself and make sure the command is available in PATH.',
|
||
'settings.mcp.form.arguments': 'Arguments',
|
||
'settings.mcp.form.argumentPlaceholder': 'chrome-devtools-mcp@latest',
|
||
'settings.mcp.form.addArgument': 'Add argument',
|
||
'settings.mcp.form.environmentVariables': 'Environment variables',
|
||
'settings.mcp.form.addEnv': 'Add environment variable',
|
||
'settings.mcp.form.keyPlaceholder': 'Key',
|
||
'settings.mcp.form.valuePlaceholder': 'Value',
|
||
'settings.mcp.form.url': 'URL',
|
||
'settings.mcp.form.sseUrl': 'SSE URL',
|
||
'settings.mcp.form.urlPlaceholder': 'https://mcp.example.com/mcp',
|
||
'settings.mcp.form.headers': 'Headers',
|
||
'settings.mcp.form.addHeader': 'Add header',
|
||
'settings.mcp.form.oauthClientId': 'OAuth client ID',
|
||
'settings.mcp.form.oauthClientIdPlaceholder': 'Optional client ID',
|
||
'settings.mcp.form.oauthCallbackPort': 'OAuth callback port',
|
||
'settings.mcp.form.oauthCallbackPortPlaceholder': 'Optional fixed callback port',
|
||
'settings.mcp.form.headersHelper': 'Headers helper script',
|
||
'settings.mcp.form.headersHelperPlaceholder': 'Optional helper command path',
|
||
'settings.mcp.form.deleteTitle': 'Delete MCP server',
|
||
'settings.mcp.form.cancel': 'Cancel',
|
||
'settings.mcp.form.confirmDelete': 'Delete',
|
||
'settings.mcp.form.deleteConfirm': 'Delete MCP server "{name}"? This cannot be undone.',
|
||
'settings.mcp.form.deleteConfirmBody': 'Delete MCP server "{name}"? This action cannot be undone.',
|
||
'settings.mcp.targetProject.title': 'Target project',
|
||
'settings.mcp.targetProject.selected': 'Currently viewing local and shared MCP servers for: {path}',
|
||
'settings.mcp.targetProject.empty': 'Choose a project to inspect project-private or project-shared MCP servers.',
|
||
'settings.mcp.targetProject.emptyWithCurrent': 'Choose a target project. The current active session is: {path}',
|
||
'settings.mcp.targetProject.localSelected': 'This server will be private to you inside: {path}',
|
||
'settings.mcp.targetProject.localEmpty': 'Choose the project that should receive this private MCP server.',
|
||
'settings.mcp.targetProject.projectSelected': 'This server will be shared through: {path}/.mcp.json',
|
||
'settings.mcp.targetProject.projectEmpty': 'Choose the project whose `.mcp.json` should receive this shared MCP server.',
|
||
'settings.mcp.targetProject.globalTitle': 'Global install target',
|
||
'settings.mcp.targetProject.globalHint': 'User scope does not need a target project. It is stored in your global Claude config and is available everywhere.',
|
||
'settings.mcp.toast.created': 'Created MCP server "{name}"',
|
||
'settings.mcp.toast.saved': 'Saved MCP server "{name}"',
|
||
'settings.mcp.toast.deleted': 'Deleted MCP server "{name}"',
|
||
'settings.mcp.toast.enabled': 'Enabled MCP server "{name}"',
|
||
'settings.mcp.toast.disabled': 'Disabled MCP server "{name}"',
|
||
'settings.mcp.toast.reconnected': 'Reconnected MCP server "{name}"',
|
||
'settings.mcp.toast.saveFailed': 'Failed to save MCP server',
|
||
'settings.mcp.toast.deleteFailed': 'Failed to delete MCP server',
|
||
'settings.mcp.toast.toggleFailed': 'Failed to update MCP server state',
|
||
'settings.mcp.toast.reconnectFailed': 'Failed to reconnect MCP server',
|
||
|
||
// Settings > Agents
|
||
'settings.tab.agents': 'Agents',
|
||
'settings.agents.title': 'Installed Agents',
|
||
'settings.agents.description': 'Browse agents available to Claude across built-in, project, and user sources. Use /agents in TUI to inspect active sources and overrides.',
|
||
'settings.agents.browserTitle': 'Browse installed agents',
|
||
'settings.agents.browserEyebrow': 'Agent Browser',
|
||
'settings.agents.entryEyebrow': 'Agent Profile',
|
||
'settings.agents.empty': 'No agents available yet.',
|
||
'settings.agents.emptyHint': 'Add agent definitions in your Claude settings or project to see them here.',
|
||
'settings.agents.model': 'Model',
|
||
'settings.agents.tools': 'Tools',
|
||
'settings.agents.systemPrompt': 'System Prompt',
|
||
'settings.agents.noDescription': 'No description',
|
||
'settings.agents.noSystemPrompt': 'No system prompt defined.',
|
||
'settings.agents.backToList': 'Back to list',
|
||
'settings.agents.agentCount': '{count} agents',
|
||
'settings.agents.summary.totalAgents': 'Total agents',
|
||
'settings.agents.summary.activeAgents': 'Active agents',
|
||
'settings.agents.summary.sources': 'Sources',
|
||
'settings.agents.summary.source': 'Source',
|
||
'settings.agents.summary.model': 'Model',
|
||
'settings.agents.summary.tools': 'Tools',
|
||
'settings.agents.summary.status': 'Status',
|
||
'settings.agents.groupHint': '{count} agents available from {source}',
|
||
'settings.agents.status.active': 'Active',
|
||
'settings.agents.status.available': 'Available',
|
||
'settings.agents.overriddenBy': 'Overridden by {source}',
|
||
'settings.agents.overriddenByShort': 'shadowed by {source}',
|
||
'settings.agents.toolCount': '{count} tools',
|
||
'settings.agents.noTools': 'No tool restriction',
|
||
'settings.agents.promptHint': 'Read the current system prompt and compare how this agent is scoped.',
|
||
'settings.agents.source.userSettings': 'User',
|
||
'settings.agents.source.projectSettings': 'Project',
|
||
'settings.agents.source.localSettings': 'Local',
|
||
'settings.agents.source.policySettings': 'Managed',
|
||
'settings.agents.source.plugin': 'Plugin',
|
||
'settings.agents.source.flagSettings': 'CLI arg',
|
||
'settings.agents.source.built-in': 'Built-in',
|
||
|
||
// Settings > Skills
|
||
'settings.skills.title': 'Installed Skills',
|
||
'settings.skills.description': 'Skills extend Claude with specialized capabilities. Manage skills in ~/.claude/skills/',
|
||
'settings.skills.browserTitle': 'Browse installed skills',
|
||
'settings.skills.browserEyebrow': 'Skill Browser',
|
||
'settings.skills.browserDescription': 'Inspect bundled, project, and user skills, compare their scope, and open each skill folder to read its docs and source files.',
|
||
'settings.skills.entryEyebrow': 'Skill Entry',
|
||
'settings.skills.slashCommand': '/slash',
|
||
'settings.skills.tokenEstimate': '~{count} tokens',
|
||
'settings.skills.tokenEstimateShort': '~{count}',
|
||
'settings.skills.summary.totalSkills': 'Total skills',
|
||
'settings.skills.summary.totalFiles': 'Files',
|
||
'settings.skills.summary.sources': 'Sources',
|
||
'settings.skills.summary.tokens': 'Estimated tokens',
|
||
'settings.skills.summary.source': 'Source',
|
||
'settings.skills.summary.entry': 'Entry',
|
||
'settings.skills.groupHint': '{count} skills available from {source}',
|
||
'settings.skills.ready': 'Ready',
|
||
'settings.skills.unavailable': 'Unavailable',
|
||
'settings.skills.empty': 'No skills installed',
|
||
'settings.skills.emptyHint': 'Add skills to ~/.claude/skills/ to get started',
|
||
'settings.skills.back': 'Back to list',
|
||
'settings.skills.files': 'files',
|
||
'settings.skills.entryFile': 'entry file',
|
||
'settings.skills.metaTitle': 'Skill metadata',
|
||
'settings.skills.filesPanel': 'Files',
|
||
'settings.skills.filesPanelHint': 'Browse the entry file and supporting implementation files.',
|
||
'settings.skills.readingMode': 'Viewing in {mode}',
|
||
'settings.skills.docMode': 'document mode',
|
||
'settings.skills.codeMode': 'code mode',
|
||
'settings.skills.source.user': 'User',
|
||
'settings.skills.source.project': 'Project',
|
||
'settings.skills.source.plugin': 'Plugin',
|
||
'settings.skills.source.mcp': 'MCP',
|
||
'settings.skills.source.bundled': 'Built-in',
|
||
|
||
// Settings > Memory
|
||
'settings.tab.memory': 'Memory',
|
||
'settings.memory.title': 'Project Memory',
|
||
'settings.memory.description': 'Inspect and edit the Markdown memory files Claude writes for each project. These files are stored under ~/.claude/projects/<project>/memory/ and are loaded by the CLI runtime.',
|
||
'settings.memory.refresh': 'Refresh',
|
||
'settings.memory.projects': 'Projects',
|
||
'settings.memory.files': 'Memory files',
|
||
'settings.memory.resourceManager': 'Resource manager',
|
||
'settings.memory.editor': 'Editor',
|
||
'settings.memory.preview': 'Preview',
|
||
'settings.memory.rendered': 'Rendered',
|
||
'settings.memory.emptyProjects': 'No memory projects found.',
|
||
'settings.memory.emptyFiles': 'No memory files found yet.',
|
||
'settings.memory.selectFile': 'Select a memory file.',
|
||
'settings.memory.selectProject': 'Select a project.',
|
||
'settings.memory.noFileSelected': 'No file selected',
|
||
'settings.memory.current': 'Current',
|
||
'settings.memory.indexFile': 'Index',
|
||
'settings.memory.missing': 'Missing',
|
||
'settings.memory.fileCount': '{count} files',
|
||
'settings.memory.unsaved': 'Unsaved',
|
||
'settings.memory.saved': 'Saved',
|
||
'settings.memory.revert': 'Revert',
|
||
'settings.memory.projectSearchPlaceholder': 'Search projects by path...',
|
||
'settings.memory.fileSearchPlaceholder': 'Search memory files...',
|
||
'settings.memory.resourceSearchPlaceholder': 'Search projects or memory files...',
|
||
'settings.memory.noProjectMatches': 'No projects match this search.',
|
||
'settings.memory.noFileMatches': 'No memory files match this search.',
|
||
'settings.memory.clearSearch': 'Clear search',
|
||
'settings.memory.toggleFolder': 'Toggle {name}',
|
||
|
||
// Settings > Plugins
|
||
'settings.plugins.title': 'Installed Plugins',
|
||
'settings.plugins.description': 'Inspect installed plugins, see their health, and apply changes to the desktop runtime.',
|
||
'settings.plugins.browserTitle': 'Browse installed plugins',
|
||
'settings.plugins.browserEyebrow': 'Plugin Manager',
|
||
'settings.plugins.browserDescription': 'Plugins bundle skills, agents, hooks, MCP servers, and language tooling. This view keeps the desktop surface focused on installed plugins, health, and apply-to-runtime feedback.',
|
||
'settings.plugins.entryEyebrow': 'Plugin Detail',
|
||
'settings.plugins.summary.total': 'Total plugins',
|
||
'settings.plugins.summary.enabled': 'Enabled',
|
||
'settings.plugins.summary.attention': 'Needs attention',
|
||
'settings.plugins.summary.marketplaces': 'Marketplaces',
|
||
'settings.plugins.summary.skills': 'Skills',
|
||
'settings.plugins.summary.agents': 'Agents',
|
||
'settings.plugins.summary.mcp': 'MCP',
|
||
'settings.plugins.summary.hooks': 'Hooks',
|
||
'settings.plugins.group.attention': 'Needs attention',
|
||
'settings.plugins.group.enabled': 'Enabled',
|
||
'settings.plugins.group.disabled': 'Disabled',
|
||
'settings.plugins.groupHint': '{count} plugins in this section',
|
||
'settings.plugins.refresh': 'Refresh',
|
||
'settings.plugins.apply': 'Apply changes',
|
||
'settings.plugins.applyHint': 'Enable, disable, and update changes become active after applying them to the current desktop runtime.',
|
||
'settings.plugins.lastReload': 'Last apply: {enabled} active plugins, {skills} plugin skills, {errors} errors.',
|
||
'settings.plugins.reloadToast': 'Applied plugin changes: {enabled} active plugins, {skills} skills, {errors} errors.',
|
||
'settings.plugins.marketplacesTitle': 'Known marketplaces',
|
||
'settings.plugins.marketplacesHint': 'Read-only summary of marketplace sources already configured for this machine.',
|
||
'settings.plugins.marketplaceAutoUpdateOn': 'Auto-update on',
|
||
'settings.plugins.marketplaceAutoUpdateOff': 'Auto-update off',
|
||
'settings.plugins.marketplaceInstalledCount': '{count} installed',
|
||
'settings.plugins.marketplaceUpdatedAt': 'Updated {value}',
|
||
'settings.plugins.status.enabled': 'Enabled',
|
||
'settings.plugins.status.disabled': 'Disabled',
|
||
'settings.plugins.status.attention': 'Attention',
|
||
'settings.plugins.scope.user': 'User',
|
||
'settings.plugins.scope.project': 'Project',
|
||
'settings.plugins.scope.local': 'Local',
|
||
'settings.plugins.scope.managed': 'Managed',
|
||
'settings.plugins.scope.builtin': 'Built-in',
|
||
'settings.plugins.empty': 'No plugins installed',
|
||
'settings.plugins.emptyHint': 'Install plugins from Claude Code to manage them here.',
|
||
'settings.plugins.back': 'Back to list',
|
||
'settings.plugins.noDescription': 'No description available for this plugin.',
|
||
'settings.plugins.errorCount': '{count} errors',
|
||
'settings.plugins.enable': 'Enable',
|
||
'settings.plugins.disable': 'Disable',
|
||
'settings.plugins.update': 'Update',
|
||
'settings.plugins.uninstall': 'Uninstall',
|
||
'settings.plugins.confirmUninstall': 'Uninstall plugin "{name}"? This removes the installed copy for the selected scope.',
|
||
'settings.plugins.author': 'Author: {value}',
|
||
'settings.plugins.projectPath': 'Project: {value}',
|
||
'settings.plugins.installPath': 'Installed at: {value}',
|
||
'settings.plugins.managedHint': 'This plugin is managed by policy and cannot be changed from the desktop app.',
|
||
'settings.plugins.builtinHint': 'Built-in plugins can be reloaded here, but install and uninstall actions are not exposed.',
|
||
'settings.plugins.errorsTitle': 'Plugin errors',
|
||
'settings.plugins.capabilitiesTitle': 'Bundled capabilities',
|
||
'settings.plugins.capabilitiesHint': 'Capabilities exposed by this plugin after loading its manifest and runtime integrations.',
|
||
'settings.plugins.sharedNavigationDisabled': 'Enable this plugin and apply changes before opening its skills, agents, or MCP entries in the shared management pages.',
|
||
'settings.plugins.capabilityEmpty': 'None exposed',
|
||
'settings.plugins.capability.skills': '{count} skills',
|
||
'settings.plugins.capability.agents': '{count} agents',
|
||
'settings.plugins.capability.mcpServers': '{count} MCP servers',
|
||
'settings.plugins.capabilityLabel.skills': 'Skills',
|
||
'settings.plugins.capabilityLabel.commands': 'Commands',
|
||
'settings.plugins.capabilityLabel.agents': 'Agents',
|
||
'settings.plugins.capabilityLabel.hooks': 'Hooks',
|
||
'settings.plugins.capabilityLabel.mcpServers': 'MCP servers',
|
||
'settings.plugins.capabilityLabel.lspServers': 'LSP servers',
|
||
|
||
// Settings > About
|
||
'settings.tab.about': 'About',
|
||
'settings.about.version': 'Version',
|
||
'settings.about.changelog': 'Release Notes',
|
||
'settings.about.repo': 'GitHub Repository',
|
||
'settings.about.starHint': 'If this project helps you, consider giving it a Star',
|
||
'settings.about.feedback': 'Report an Issue',
|
||
'settings.about.feedbackDesc': 'Open a GitHub Issue for bugs or usage questions',
|
||
'settings.about.author': 'Author',
|
||
'settings.about.socialMedia': 'Social Media',
|
||
'settings.about.updates': 'App Updates',
|
||
'settings.about.updatesDesc': 'Check GitHub Releases, download the installer, and relaunch after install.',
|
||
|
||
// Settings > Computer Use
|
||
'settings.tab.computerUse': 'Computer Use',
|
||
'settings.computerUse.title': 'Computer Use',
|
||
'settings.computerUse.description': 'Allow Claude to take screenshots, click, type, and control your computer. Requires Python 3. On macOS, accessibility permissions are also needed.',
|
||
'settings.computerUse.enabledToggle': 'Enabled',
|
||
'settings.computerUse.disabledHint': 'Computer Use is off. New sessions will not inject the computer-use MCP server or expose desktop-control tools to the Coding Agent.',
|
||
'settings.computerUse.notSupported': 'Computer Use is only supported on macOS and Windows.',
|
||
'settings.computerUse.python': 'Python 3',
|
||
'settings.computerUse.pythonNotFound': 'Not installed. Please install Python 3 first.',
|
||
'settings.computerUse.pythonFound': 'Installed',
|
||
'settings.computerUse.pythonCustomInvalid': 'Custom interpreter unavailable',
|
||
'settings.computerUse.pythonPathLabel': 'Python Interpreter Path',
|
||
'settings.computerUse.pythonPathPlaceholder': 'Auto-detect, or choose python.exe / python3',
|
||
'settings.computerUse.pythonPathHint': 'Leave empty to auto-detect. Choose the Python executable from conda, pyenv, or another custom environment to prefer it for runtime setup.',
|
||
'settings.computerUse.pythonPathBrowse': 'Browse',
|
||
'settings.computerUse.pythonPathSave': 'Apply',
|
||
'settings.computerUse.pythonPathAuto': 'Auto',
|
||
'settings.computerUse.pythonPathSaved': 'Saved. Rechecks will prefer this interpreter.',
|
||
'settings.computerUse.pythonPathSaveFailed': 'Save failed. Try again.',
|
||
'settings.computerUse.pythonPathDialogTitle': 'Select Python Interpreter',
|
||
'settings.computerUse.pythonPathDialogFailed': 'Could not open the file picker. Paste the path manually.',
|
||
'settings.computerUse.venv': 'Virtual Environment',
|
||
'settings.computerUse.venvReady': 'Ready',
|
||
'settings.computerUse.venvNotReady': 'Not created',
|
||
'settings.computerUse.deps': 'Dependencies',
|
||
'settings.computerUse.depsReady': 'Installed',
|
||
'settings.computerUse.depsNotReady': 'Not installed',
|
||
'settings.computerUse.accessibility': 'Accessibility Permission',
|
||
'settings.computerUse.screenRecording': 'Screen Recording Permission',
|
||
'settings.computerUse.permGranted': 'Granted',
|
||
'settings.computerUse.permDenied': 'Denied — open System Settings > Privacy & Security to grant',
|
||
'settings.computerUse.permUnknown': 'Setup environment first to check',
|
||
'settings.computerUse.permScreenRecordingUnknownSoft': 'Auto-detection can be unreliable here; if System Settings already shows it enabled, Computer Use can usually proceed',
|
||
'settings.computerUse.permScreenRecordingManual': 'Cannot auto-detect — please verify in System Settings',
|
||
'settings.computerUse.setupBtn': 'Install Environment',
|
||
'settings.computerUse.setupRunning': 'Installing...',
|
||
'settings.computerUse.setupSuccess': 'Environment setup complete!',
|
||
'settings.computerUse.setupFail': 'Setup failed',
|
||
'settings.computerUse.allReady': 'All checks passed. Computer Use is ready.',
|
||
'settings.computerUse.downloadPython': 'Download Python 3',
|
||
'settings.computerUse.recheckBtn': 'Recheck Status',
|
||
'settings.computerUse.requirementsLabel': 'Required packages',
|
||
'settings.computerUse.appsTitle': 'Authorized Apps',
|
||
'settings.computerUse.appsDescription': 'Pre-authorize apps for Computer Use. Authorized apps can be controlled by Claude without runtime prompts.',
|
||
'settings.computerUse.appsLoading': 'Loading installed apps...',
|
||
'settings.computerUse.appsEmpty': 'No installed apps found. Please setup the environment first.',
|
||
'settings.computerUse.appsSearch': 'Search apps...',
|
||
'settings.computerUse.appsSaved': 'Saved',
|
||
'settings.computerUse.openAccessibility': 'Open Accessibility Settings',
|
||
'settings.computerUse.openScreenRecording': 'Open Screen Recording Settings',
|
||
'settings.computerUse.permRestartHint': 'After granting, restart the app for it to take effect.',
|
||
'settings.computerUse.flagClipboard': 'Clipboard Access',
|
||
'settings.computerUse.flagSystemKeys': 'System Key Combos',
|
||
|
||
// Settings > General
|
||
'settings.general.appearanceTitle': 'Appearance',
|
||
'settings.general.appearanceDescription': 'Switch between the warm classic workspace, dark workspace, and a pure white workspace.',
|
||
'settings.general.appearance.light': 'Warm Classic',
|
||
'settings.general.appearance.dark': 'Dark',
|
||
'settings.general.appearance.white': 'Pure White',
|
||
'settings.general.languageTitle': 'Language',
|
||
'settings.general.languageDescription': 'Choose the display language for the application.',
|
||
'settings.general.responseLangTitle': 'Response Language',
|
||
'settings.general.responseLangDescription': 'Instruct Claude to always respond in a specific language.',
|
||
'settings.general.responseLangDefault': 'Default (English)',
|
||
'settings.general.effortTitle': 'Effort Level',
|
||
'settings.general.effortDescription': 'Controls how much computation the model uses.',
|
||
'settings.general.effort.low': 'Low',
|
||
'settings.general.effort.medium': 'Medium',
|
||
'settings.general.effort.high': 'High',
|
||
'settings.general.effort.max': 'Max',
|
||
'settings.general.thinkingTitle': 'Thinking Mode',
|
||
'settings.general.thinkingDescription': 'Controls whether new sessions start with model thinking enabled. When off, compatible providers such as DeepSeek receive an explicit non-thinking parameter.',
|
||
'settings.general.thinkingEnabled': 'Enable thinking mode',
|
||
'settings.general.thinkingHint': 'Turn this off to start new sessions with --thinking disabled; useful for DeepSeek V4 Flash/Pro and other non-thinking workflows.',
|
||
'settings.general.notificationsTitle': 'System Notifications',
|
||
'settings.general.notificationsDescription': 'Use native OS notifications for permission prompts, agent replies, and scheduled task results.',
|
||
'settings.general.notificationsEnabled': 'Enable system notifications',
|
||
'settings.general.notificationsHintOn': 'When enabled, the app will request notification permission and use the OS notification center.',
|
||
'settings.general.notificationsHintOff': 'When disabled, permission prompts, agent replies, and scheduled tasks will not send desktop notifications.',
|
||
'settings.general.notificationsStatus': 'Permission',
|
||
'settings.general.notificationsStatusGranted': 'Granted',
|
||
'settings.general.notificationsStatusDenied': 'Blocked by system settings',
|
||
'settings.general.notificationsStatusDefault': 'Not requested',
|
||
'settings.general.notificationsStatusUnsupported': 'Unavailable in this environment',
|
||
'settings.general.notificationsAuthorize': 'Authorize',
|
||
'settings.general.notificationsOpenSettings': 'Open Settings',
|
||
'settings.general.notificationsTestTitle': 'Claude Code Haha notifications are enabled',
|
||
'settings.general.notificationsTestBody': 'Permission prompts and completed agent replies will now use system notifications.',
|
||
'settings.general.h5AccessTitle': 'H5 Access',
|
||
'settings.general.h5AccessDescription': 'Expose the desktop H5 app on your local network. Phones connect with a QR link that includes a short-lived H5 token.',
|
||
'settings.general.h5AccessEnabled': 'Enable H5 access',
|
||
'settings.general.h5AccessEnabledHint': 'The desktop server listens on the LAN address and allows access to desktop sessions.',
|
||
'settings.general.h5AccessStatusEnabled': 'Enabled',
|
||
'settings.general.h5AccessTokenPreview': 'Token preview',
|
||
'settings.general.h5AccessDisabledValue': 'Disabled',
|
||
'settings.general.h5AccessDisable': 'Disable',
|
||
'settings.general.h5AccessGenerateToken': 'Generate token',
|
||
'settings.general.h5AccessRegenerate': 'Regenerate token',
|
||
'settings.general.h5AccessGeneratedToken': 'Generated token',
|
||
'settings.general.h5AccessGeneratedTokenHint': 'Shown once. Copy it now and store it like a password.',
|
||
'settings.general.h5AccessShowToken': 'Show token',
|
||
'settings.general.h5AccessCopy': 'Copy',
|
||
'settings.general.h5AccessCopyUrl': 'Copy H5 URL',
|
||
'settings.general.h5AccessCopyLaunchUrl': 'Copy QR link',
|
||
'settings.general.h5AccessUrlCopied': 'H5 URL copied.',
|
||
'settings.general.h5AccessLaunchUrlCopied': 'QR link copied.',
|
||
'settings.general.h5AccessHideToken': 'Hide token',
|
||
'settings.general.h5AccessTokenNotAvailable': 'Regenerate to show a new token.',
|
||
'settings.general.h5AccessPublicUrl': 'Public URL',
|
||
'settings.general.h5AccessPublicUrlPlaceholder': 'https://chat.example.com',
|
||
'settings.general.h5AccessAllowedOrigins': 'Allowed origins',
|
||
'settings.general.h5AccessAllowedOriginsPlaceholder': 'https://chat.example.com, https://phone.example',
|
||
'settings.general.h5AccessOriginsHint': 'Enter one origin per line or separate multiple origins with commas.',
|
||
'settings.general.h5AccessOpenHint': 'Leave blank to use the detected LAN URL. Set this only when you expose H5 through a stable address.',
|
||
'settings.general.h5AccessSave': 'Save H5 settings',
|
||
'settings.general.h5AccessUrl': 'H5 URL',
|
||
'settings.general.h5AccessQrTitle': 'Phone connection',
|
||
'settings.general.h5AccessQrHint': 'Scan to open H5 with the token already filled in.',
|
||
'settings.general.h5AccessQrRefreshHint': 'Click Generate token to create a QR link that can be scanned.',
|
||
'settings.general.h5AccessQrEmptyHint': 'Generate a token to create the QR code.',
|
||
'settings.general.h5AccessQrAlt': 'H5 access QR code',
|
||
'settings.general.h5AccessSafetyNote': 'Only enable this on trusted networks. Anyone with the QR link can reach the desktop capabilities exposed by H5.',
|
||
'settings.general.h5AccessConfirmTitle': 'Enable LAN H5 access?',
|
||
'settings.general.h5AccessConfirmBody': 'This will expose the desktop H5 app on your LAN address and port. Devices with the QR token can access desktop sessions and related controls. Continue only on a trusted network.',
|
||
'settings.general.h5AccessConfirmEnable': 'Enable H5 access',
|
||
'settings.general.h5AccessError': 'Failed to update H5 access settings.',
|
||
'settings.general.webFetchPreflightTitle': 'WebFetch Preflight',
|
||
'settings.general.webFetchPreflightDescription': 'Desktop sessions skip Claude\'s domain preflight by default to avoid false failures on third-party providers and restricted networks.',
|
||
'settings.general.webFetchPreflightEnabled': 'Skip WebFetch domain preflight',
|
||
'settings.general.webFetchPreflightHint': 'Turn this off only if you explicitly want to restore the upstream safety preflight before each WebFetch request.',
|
||
'settings.general.webSearchTitle': 'WebSearch',
|
||
'settings.general.webSearchDescription': 'Choose how agent web search is resolved across official Claude, third-party providers, and local fallback keys.',
|
||
'settings.general.webSearch.mode.auto': 'Auto',
|
||
'settings.general.webSearch.mode.tavily': 'Tavily',
|
||
'settings.general.webSearch.mode.brave': 'Brave',
|
||
'settings.general.webSearch.mode.anthropic': 'Claude',
|
||
'settings.general.webSearch.mode.disabled': 'Off',
|
||
'settings.general.webSearchTavilyKey': 'Tavily API key',
|
||
'settings.general.webSearchBraveKey': 'Brave Search API key',
|
||
'settings.general.webSearchBravePlaceholder': 'Brave Search token',
|
||
'settings.general.webSearchGetApiKey': 'Get API key',
|
||
'settings.general.webSearchTavilyApiKeyLink': 'Get Tavily API key',
|
||
'settings.general.webSearchBraveApiKeyLink': 'Get Brave Search API key',
|
||
'settings.general.webSearchTavilyFreeHint': 'Create an account and copy a key; the free tier includes 1000 credits.',
|
||
'settings.general.webSearchBraveFreeHint': 'Create an account to generate a Search API key with free usage for testing.',
|
||
'settings.general.webSearchHint': 'Auto uses native Claude web search for Claude model names, then falls back to Tavily and Brave keys.',
|
||
'settings.general.webSearchSave': 'Save',
|
||
'settings.general.uiZoom': 'UI Zoom',
|
||
'settings.general.uiZoomDescription': 'Adjust the size of the entire interface.',
|
||
'settings.general.uiZoomShortcutHint': 'Shortcuts are faster:',
|
||
'settings.general.uiZoomShortcutMac': 'macOS',
|
||
'settings.general.uiZoomShortcutWindows': 'Windows / Linux',
|
||
'settings.general.uiZoomShortcutResetHint': '0 resets zoom to 100%.',
|
||
'settings.general.uiZoomReset': 'Reset UI zoom to 100%',
|
||
|
||
// ─── Empty Session ──────────────────────────────────────
|
||
'empty.title': 'New session',
|
||
'empty.subtitle': 'Start a fresh coding session. Claude is ready to help you build, debug, and architect your project.',
|
||
'empty.placeholder': 'Ask anything...',
|
||
'empty.addFiles': 'Add files or photos',
|
||
'empty.slashCommands': 'Slash commands',
|
||
'empty.failedToCreate': 'Failed to create session',
|
||
'empty.createError.workdirMissing': 'The project folder is missing or is not a directory. Pick an existing project and try again.',
|
||
'empty.createError.notGit': 'This project is not a Git repository, so branch launch is unavailable. Start in the current folder or pick a Git project.',
|
||
'empty.createError.branchNotFound': 'The selected branch no longer exists. Refresh the project context and choose another branch.',
|
||
'empty.createError.dirtyWorktree': 'Current project has uncommitted changes. Direct branch switching was blocked; enable "Isolated worktree" or commit/stash your changes first.',
|
||
'empty.createError.branchCheckedOut': 'That branch is already checked out in another worktree. Enable "Isolated worktree" or choose a different branch.',
|
||
'empty.createError.worktreeCreateFailed': 'Could not create the isolated worktree. Check that Git can write to this repository, then try again. Detail: {detail}',
|
||
'empty.createError.switchFailed': 'Could not switch the current project branch. Check the Git error, keep your changes safe, then try again. Detail: {detail}',
|
||
'empty.createError.contextFailed': 'Could not inspect this Git project. Check the repository state and try again.',
|
||
|
||
// ─── Repository Launch Controls ──────────────────────────────────────
|
||
'repoLaunch.selectBranch': 'Select branch',
|
||
'repoLaunch.searchBranch': 'Search branches',
|
||
'repoLaunch.noBranch': 'No branch',
|
||
'repoLaunch.noBranchMatch': 'No matching branches',
|
||
'repoLaunch.currentBranch': 'Current branch',
|
||
'repoLaunch.localBranch': 'Local branch',
|
||
'repoLaunch.remoteBranch': 'Remote branch',
|
||
'repoLaunch.checkedOut': 'Checked out in another worktree',
|
||
'repoLaunch.worktreeCurrent': 'Current worktree',
|
||
'repoLaunch.worktreeIsolated': 'Isolated worktree',
|
||
'repoLaunch.selectWorktree': 'Select worktree mode',
|
||
'repoLaunch.missingWorkdir': 'Working directory is missing.',
|
||
'repoLaunch.dirtyWarning': 'Uncommitted changes detected. Direct switching may be blocked; use isolated worktree to continue without touching this folder.',
|
||
'repoLaunch.checkedOutWarning': 'Selected branch is already checked out in another worktree. Direct launch may be blocked by Git; use "Isolated worktree" to avoid changing directories.',
|
||
|
||
// ─── Chat Input ──────────────────────────────────────
|
||
'chat.placeholder': 'Ask Claude to edit, debug or explain...',
|
||
'chat.placeholderMissing': 'This session points to a missing workspace. Create a new session or pick another project.',
|
||
'chat.addFiles': 'Add files or photos',
|
||
'chat.workspaceReferencesOnly': 'Added {count} workspace references',
|
||
'chat.contextReferencesOnly': 'Added {count} references',
|
||
'chat.addSelectionToChat': 'Add to chat',
|
||
'chat.userMessageReference': 'User message',
|
||
'chat.assistantMessageReference': 'Assistant message',
|
||
'chat.slashCommands': 'Slash commands',
|
||
'slash.mcp.title': 'Available MCP tools',
|
||
'slash.mcp.subtitle': 'Global and current-project MCP servers available in this chat context.',
|
||
'slash.mcp.subtitleWithProject': 'Showing global plus project MCP for: {path}',
|
||
'slash.mcp.emptyTitle': 'No MCP servers available',
|
||
'slash.mcp.emptyBody': 'No global or project MCP servers are available for this chat context.',
|
||
'slash.mcp.projectBadge': 'Project: {name}',
|
||
'slash.skills.title': 'Available skills',
|
||
'slash.skills.subtitle': 'User-invocable skills available in the current context.',
|
||
'slash.skills.subtitleWithProject': 'Showing skills for: {path}',
|
||
'slash.skills.emptyTitle': 'No skills available',
|
||
'slash.skills.emptyBody': 'No user-invocable skills were found for this context.',
|
||
'slash.plugins.title': 'Plugins',
|
||
'slash.plugins.subtitle': 'Plugin management will move into this slash-command surface.',
|
||
'slash.plugins.emptyTitle': 'Plugins panel coming soon',
|
||
'slash.plugins.emptyBody': 'This shared slash-command panel is wired up now; plugin data will be connected next.',
|
||
'slash.help.title': 'Slash commands',
|
||
'slash.help.subtitle': 'Run agent workflows, inspect session state, or open desktop panels.',
|
||
'slash.help.group.context': 'Context',
|
||
'slash.help.group.project': 'Project',
|
||
'slash.help.group.desktop': 'Desktop',
|
||
'slash.help.group.more': 'More',
|
||
'slash.help.moreAvailable': '{count} more commands available. Type / to search the full command list.',
|
||
'slash.inspector.title': 'Session inspector',
|
||
'slash.inspector.close': 'Close session inspector',
|
||
'slash.inspector.loading': 'Loading session data',
|
||
'slash.inspector.error.noActiveSession': 'No active session selected.',
|
||
'slash.inspector.error.unavailable': 'Session inspector data is unavailable. Restart the desktop server so /api/sessions/:id/inspection is loaded.',
|
||
'slash.inspector.tab.status': 'Status',
|
||
'slash.inspector.tab.usage': 'Usage',
|
||
'slash.inspector.tab.context': 'Context',
|
||
'slash.inspector.status.cliStatus': 'CLI Status',
|
||
'slash.inspector.status.running': 'Running',
|
||
'slash.inspector.status.notRunning': 'Not running',
|
||
'slash.inspector.status.activeModel': 'Active Model',
|
||
'slash.inspector.status.unknown': 'Unknown',
|
||
'slash.inspector.status.mcpConnections': 'MCP Connections',
|
||
'slash.inspector.status.connected': 'connected',
|
||
'slash.inspector.status.failed': 'failed',
|
||
'slash.inspector.status.registeredTools': 'Registered Tools',
|
||
'slash.inspector.status.commands': 'commands',
|
||
'slash.inspector.status.sessionMetadata': 'Session metadata',
|
||
'slash.inspector.status.version': 'Version',
|
||
'slash.inspector.status.sessionId': 'Session ID',
|
||
'slash.inspector.status.workingDirectory': 'Working Directory',
|
||
'slash.inspector.status.permissionMode': 'Permission Mode',
|
||
'slash.inspector.status.authToken': 'Auth Token',
|
||
'slash.inspector.status.outputStyle': 'Output Style',
|
||
'slash.inspector.status.default': 'Default',
|
||
'slash.inspector.status.mcpServers': 'MCP servers',
|
||
'slash.inspector.status.refresh': 'Refresh',
|
||
'slash.inspector.status.contextWindow': 'Context window',
|
||
'slash.inspector.usage.emptyTitle': 'No usage data yet',
|
||
'slash.inspector.usage.emptyBody': 'Usage appears after the CLI session starts and completes at least one turn.',
|
||
'slash.inspector.usage.contextSnapshotNotice': 'Showing token usage from the current context snapshot. Usage updates dynamically as context is fetched.',
|
||
'slash.inspector.usage.transcriptNotice': 'Showing usage reconstructed from the session transcript. API duration is only available for the currently running CLI process.',
|
||
'slash.inspector.usage.unknownCost': 'Costs may be inaccurate because one or more models have unknown pricing.',
|
||
'slash.inspector.usage.totalCost': 'Total cost',
|
||
'slash.inspector.usage.source': 'Source',
|
||
'slash.inspector.usage.source.contextSnapshot': 'Context snapshot',
|
||
'slash.inspector.usage.source.transcript': 'Transcript',
|
||
'slash.inspector.usage.source.currentProcess': 'Current process',
|
||
'slash.inspector.usage.apiDuration': 'API duration',
|
||
'slash.inspector.usage.wallDuration': 'Wall duration',
|
||
'slash.inspector.usage.usageSpan': 'Usage span',
|
||
'slash.inspector.usage.codeChanges': 'Code changes',
|
||
'slash.inspector.usage.input': 'Input',
|
||
'slash.inspector.usage.output': 'Output',
|
||
'slash.inspector.usage.cacheReadWrite': 'Cache read / write',
|
||
'slash.inspector.usage.webSearch': 'Web search',
|
||
'slash.inspector.usage.byModel': 'Usage by Model',
|
||
'slash.inspector.usage.tokens': 'Tokens',
|
||
'slash.inspector.usage.noModelTitle': 'No model usage',
|
||
'slash.inspector.usage.noModelBody': 'Token usage will appear here after a model response is recorded.',
|
||
'slash.inspector.context.loading': 'Loading context data',
|
||
'slash.inspector.context.emptyTitle': 'No context data yet',
|
||
'slash.inspector.context.emptyBody': 'Context usage requires an active CLI session.',
|
||
'slash.inspector.context.windowUsage': 'Context window usage',
|
||
'slash.inspector.context.used': 'used',
|
||
'slash.inspector.context.free': 'Free',
|
||
'slash.inspector.context.messages': 'Messages',
|
||
'slash.inspector.context.assistant': 'assistant',
|
||
'slash.inspector.context.toolResults': 'Tool results',
|
||
'slash.inspector.context.context': 'Context',
|
||
'slash.inspector.context.categoryTitle': 'Estimated usage by category',
|
||
'slash.inspector.context.noCategoriesTitle': 'No context categories',
|
||
'slash.inspector.context.noCategoriesBody': 'Context categories will appear after the CLI reports context analysis.',
|
||
'slash.inspector.context.memoryFiles': 'Memory files',
|
||
'slash.inspector.context.noMemoryFiles': 'No memory files are loaded in this session.',
|
||
'slash.inspector.context.openMemory': 'Open Memory',
|
||
'contextIndicator.ariaLabel': 'Context usage {percent}',
|
||
'contextIndicator.pendingAria': 'Context usage not calculated',
|
||
'contextIndicator.loadingAria': 'Context usage loading',
|
||
'contextIndicator.unavailableAria': 'Context usage unavailable',
|
||
'contextIndicator.title': 'Context',
|
||
'contextIndicator.modelUnknown': 'Unknown model',
|
||
'contextIndicator.used': 'Used',
|
||
'contextIndicator.free': 'Free',
|
||
'contextIndicator.window': 'Window',
|
||
'contextIndicator.loading': 'Loading context usage...',
|
||
'contextIndicator.pendingDetail': 'Context usage will be calculated after the session starts.',
|
||
'contextIndicator.unavailable': 'n/a',
|
||
'contextIndicator.unavailableDetail': 'Context usage is unavailable for this session.',
|
||
'contextIndicator.updatedUnknown': 'Not refreshed yet',
|
||
'contextIndicator.updatedNow': 'Updated just now',
|
||
'contextIndicator.updatedMinutes': 'Updated {count}m ago',
|
||
'contextIndicator.estimate': 'Estimate',
|
||
'chat.navigate': 'navigate',
|
||
'chat.select': 'select',
|
||
'chat.dismiss': 'dismiss',
|
||
'chat.stopTitle': 'Stop generation (Cmd+.)',
|
||
'chat.jumpToLatest': 'Latest',
|
||
'chat.memorySavedTitle': 'Saved {count} memory file(s)',
|
||
'chat.memorySavedFromToolsTitle': 'Saved {count} memory item(s)',
|
||
'chat.memoryReferencedTitle': '{count} memory reference(s)',
|
||
'chat.memoryOpenSettings': 'Open Memory',
|
||
'chat.memoryMoreFiles': '+{count} more',
|
||
'chat.memoryTechnicalDetails': 'Tool details',
|
||
'chat.rewindSuccessWithCode': 'Rewound {count} messages and restored tracked files.',
|
||
'chat.rewindSuccessConversationOnly': 'Rewound {count} messages. No file checkpoint was available for this turn.',
|
||
'chat.turnChangesTitle': '{count} files changed',
|
||
'chat.turnChangesLatestCardLabel': 'Turn changed files',
|
||
'chat.turnChangesHistoricalCardLabel': 'Turn changed files',
|
||
'chat.turnChangesLatestSubtitle': 'Current turn checkpoint',
|
||
'chat.turnChangesHistoricalSubtitle': 'Saved turn checkpoint',
|
||
'chat.turnChangesLatestUndo': 'Undo current turn',
|
||
'chat.turnChangesHistoricalUndo': 'Rewind to before this turn',
|
||
'chat.turnChangesUndoing': 'Undoing...',
|
||
'chat.turnChangesLatestUndoAria': 'Undo current turn changes',
|
||
'chat.turnChangesHistoricalUndoAria': 'Rewind to before this turn',
|
||
'chat.turnChangesLatestConfirmTitle': 'Undo current turn?',
|
||
'chat.turnChangesHistoricalConfirmTitle': 'Rewind to before this turn?',
|
||
'chat.turnChangesLatestConfirmBody': 'This will rewind the latest assistant response and restore tracked files for this turn.',
|
||
'chat.turnChangesHistoricalConfirmBody': 'This will rewind the conversation to before this turn and restore tracked files for that checkpoint.',
|
||
'chat.turnChangesLatestConfirmUndo': 'Undo current turn',
|
||
'chat.turnChangesHistoricalConfirmUndo': 'Rewind to before this turn',
|
||
'chat.turnChangesShowDiffAria': 'Show diff for {path}',
|
||
'chat.turnChangesHideDiffAria': 'Hide diff for {path}',
|
||
'chat.turnChangesDiffLoading': 'Loading diff...',
|
||
'chat.turnChangesDiffUnavailable': 'Diff unavailable.',
|
||
|
||
// ─── Streaming Indicator ──────────────────────────────────────
|
||
'streaming.thinking': 'Thinking',
|
||
'streaming.running': 'Running',
|
||
'streaming.working': 'Working',
|
||
|
||
// ─── Permission Dialog ──────────────────────────────────────
|
||
'permission.allowEditFile': 'Allow Claude to {toolName} {fileName}?',
|
||
'permission.allowEditFileGeneric': 'Allow Claude to {toolName} this file?',
|
||
'permission.allowBash': 'Allow Claude to run this command?',
|
||
'permission.allowTool': 'Allow Claude to use {toolName}?',
|
||
'permission.awaitingApproval': 'Awaiting approval',
|
||
'permission.responded': 'Responded',
|
||
'permission.allow': 'Allow',
|
||
'permission.allowForSession': 'Allow for session',
|
||
'permission.deny': 'Deny',
|
||
'permission.hideDetails': 'Hide details',
|
||
'permission.showFullInput': 'Show full input',
|
||
'permission.replacingContent': 'Replacing content in file',
|
||
|
||
// ─── Computer Use Approval ──────────────────────────────────────
|
||
'computerUseApproval.titleApps': 'Computer Use wants to control these apps',
|
||
'computerUseApproval.titleTcc': 'Computer Use needs macOS permissions',
|
||
'computerUseApproval.reason': 'Why Claude is asking',
|
||
'computerUseApproval.allow': 'Allow for session',
|
||
'computerUseApproval.deny': 'Deny',
|
||
'computerUseApproval.alreadyGranted': 'Already granted for this session',
|
||
'computerUseApproval.notInstalled': 'App not installed',
|
||
'computerUseApproval.sensitiveApp': 'This app is treated as sensitive and deserves extra review.',
|
||
'computerUseApproval.alsoRequested': 'Also requested',
|
||
'computerUseApproval.hideWhileWorking': '{count} other apps will be hidden while Claude works.',
|
||
'computerUseApproval.hideWhileWorkingRestore': '{count} other apps will be hidden while Claude works, then restored when Claude is done.',
|
||
'computerUseApproval.accessibility': 'Accessibility',
|
||
'computerUseApproval.screenRecording': 'Screen Recording',
|
||
'computerUseApproval.granted': 'Granted',
|
||
'computerUseApproval.notGranted': 'Not granted',
|
||
'computerUseApproval.openAccessibility': 'Open Accessibility',
|
||
'computerUseApproval.openScreenRecording': 'Open Screen Recording',
|
||
'computerUseApproval.tryAgain': 'Try again',
|
||
'computerUseApproval.tccHint': 'Grant the missing permissions in System Settings, then come back and choose "Try again".',
|
||
'computerUseApproval.tryAgainHint': 'Try again returns control to Claude so it can call request_access once more after macOS permission changes take effect.',
|
||
|
||
// ─── Ask User Question ──────────────────────────────────────
|
||
'question.needsInput': 'Claude needs your input',
|
||
'question.answered': 'Answered',
|
||
'question.customResponse': 'Or type a custom response:',
|
||
'question.typePlaceholder': 'Type your answer...',
|
||
'question.submit': 'Submit',
|
||
'question.answeredPrefix': 'Answered: ',
|
||
|
||
// ─── Thinking Block ──────────────────────────────────────
|
||
'thinking.label': 'Thinking',
|
||
|
||
// ─── Tool Calls ──────────────────────────────────────
|
||
'tool.errorOutput': 'Error Output',
|
||
'tool.toolOutput': 'Tool Output',
|
||
'tool.toolInput': 'Tool Input',
|
||
'tool.readFileContents': 'Read file contents',
|
||
'tool.createFile': 'Create file',
|
||
'tool.updateFileContents': 'Update file contents',
|
||
'tool.linesChanged': '{count} lines changed',
|
||
'tool.linesCreated': '{count} lines created',
|
||
'tool.linesOutput': '{count} lines output',
|
||
'tool.result': '{toolName} result',
|
||
'tool.resultGeneric': 'Tool result',
|
||
'tool.error': 'ERROR',
|
||
'tool.success': 'SUCCESS',
|
||
'tool.showLess': 'Show less',
|
||
'tool.showMore': 'Show {count} more characters',
|
||
|
||
// ─── Tool Group Verbs ──────────────────────────────────────
|
||
'toolGroup.readOne': 'Read 1 file',
|
||
'toolGroup.readMany': 'Read {count} files',
|
||
'toolGroup.createdOne': 'created a file',
|
||
'toolGroup.createdMany': 'created {count} files',
|
||
'toolGroup.editedOne': 'edited a file',
|
||
'toolGroup.editedMany': 'edited {count} files',
|
||
'toolGroup.ranOne': 'ran a command',
|
||
'toolGroup.ranMany': 'ran {count} commands',
|
||
'toolGroup.foundFiles': 'found files',
|
||
'toolGroup.searchedOne': 'searched code',
|
||
'toolGroup.searchedMany': 'searched {count} patterns',
|
||
'toolGroup.agentOne': 'dispatched an agent',
|
||
'toolGroup.agentMany': 'dispatched {count} agents',
|
||
'agentStatus.starting': 'Starting',
|
||
'agentStatus.running': 'Running',
|
||
'agentStatus.done': 'Done',
|
||
'agentStatus.failed': 'Failed',
|
||
'agentStatus.stopped': 'Stopped',
|
||
'agentStatus.noActivity': 'No tool activity yet',
|
||
'agentStatus.viewResult': 'View result',
|
||
'agentStatus.resultTitle': 'Agent result',
|
||
'toolGroup.searchedWeb': 'searched the web',
|
||
'toolGroup.fetchedOne': 'fetched a page',
|
||
'toolGroup.fetchedMany': 'fetched {count} pages',
|
||
|
||
// ─── Tasks ──────────────────────────────────────
|
||
'tasks.title': 'Tasks',
|
||
'tasks.completed': 'Tasks completed',
|
||
'tasks.dismissCompleted': 'Hide completed tasks',
|
||
'tasks.newTask': '+ New task',
|
||
'tasks.emptyTitle': 'No scheduled tasks yet.',
|
||
'tasks.emptyDesc': 'Create a recurring task to automate your engineering workflows.',
|
||
'tasks.createNew': 'Create new task',
|
||
'tasks.totalTasks': 'Total Tasks',
|
||
'tasks.active': 'Active',
|
||
'tasks.disabled': 'Disabled',
|
||
|
||
// ─── New Task Modal ──────────────────────────────────────
|
||
'newTask.title': 'New scheduled task',
|
||
'newTask.localWarning': 'Local tasks only run while your computer is awake.',
|
||
'newTask.name': 'Name',
|
||
'newTask.namePlaceholder': 'daily-code-review',
|
||
'newTask.description': 'Description',
|
||
'newTask.descPlaceholder': "Review yesterday's commits and flag anything concerning",
|
||
'newTask.frequency': 'Frequency',
|
||
'newTask.everyNMinutes': 'Every N minutes',
|
||
'newTask.everyNHours': 'Every N hours',
|
||
'newTask.daily': 'Daily',
|
||
'newTask.weekdays': 'Weekdays (Mon–Fri)',
|
||
'newTask.specificDays': 'Specific days of week',
|
||
'newTask.monthly': 'Monthly',
|
||
'newTask.customCron': 'Custom cron expression',
|
||
'newTask.intervalMinutes': 'Every {n} minutes',
|
||
'newTask.intervalHours': 'Every {n} hours',
|
||
'newTask.atMinute': 'at minute :{m}',
|
||
'newTask.onMonthDay': 'On day {d} of each month',
|
||
'newTask.cronFormatHint': 'Format: minute hour day-of-month month day-of-week',
|
||
'newTask.invalidCron': 'Invalid cron expression',
|
||
'newTask.daySun': 'Sun',
|
||
'newTask.dayMon': 'Mon',
|
||
'newTask.dayTue': 'Tue',
|
||
'newTask.dayWed': 'Wed',
|
||
'newTask.dayThu': 'Thu',
|
||
'newTask.dayFri': 'Fri',
|
||
'newTask.daySat': 'Sat',
|
||
'newTask.delayNote': 'Scheduled tasks use a randomized delay of several minutes for server performance.',
|
||
'newTask.create': 'Create task',
|
||
'newTask.promptPlaceholder': 'Look at the commits from the last 24 hours. Summarize what changed, call out any risky patterns or missing tests, and note anything worth following up on.',
|
||
'newTask.notification': 'Notification',
|
||
'newTask.notifyOnComplete': 'Push notification on completion',
|
||
'newTask.notifyChannels': 'Notification channels',
|
||
'newTask.notifyHint': 'Send a native desktop notification or IM message when the task finishes.',
|
||
'newTask.notifyDesktop': 'Desktop',
|
||
'newTask.notConfigured': 'Not configured',
|
||
'newTask.noChannelConfigured': 'No IM channels configured yet. Go to Settings → IM Adapters to set up.',
|
||
'newTask.noChannelSelected': 'Select at least one notification channel.',
|
||
|
||
// ─── Cron Descriptions ──────────────────────────────────────
|
||
'cron.everyMinute': 'Runs every minute',
|
||
'cron.everyNMinutes': 'Runs every {n} minutes',
|
||
'cron.everyHour': 'Runs every hour',
|
||
'cron.everyNHours': 'Runs every {n} hours',
|
||
'cron.everyNHoursAtMinute': 'Runs every {n} hours at :{m}',
|
||
'cron.dailyAt': 'Runs daily at {time}',
|
||
'cron.weekdaysAt': 'Runs on weekdays at {time}',
|
||
'cron.specificDaysAt': 'Runs every {days} at {time}',
|
||
'cron.monthlyAt': 'Runs on the {day}th of every month at {time}',
|
||
'cron.customSchedule': 'Custom: {cron}',
|
||
'cron.dow.0': 'Sun',
|
||
'cron.dow.1': 'Mon',
|
||
'cron.dow.2': 'Tue',
|
||
'cron.dow.3': 'Wed',
|
||
'cron.dow.4': 'Thu',
|
||
'cron.dow.5': 'Fri',
|
||
'cron.dow.6': 'Sat',
|
||
|
||
// ─── Task Actions & Logs ──────────────────────────────────────
|
||
'tasks.runNow': 'Run now',
|
||
'tasks.confirmRun': 'Execute this task immediately?',
|
||
'tasks.confirmDisable': 'Disable this scheduled task?',
|
||
'tasks.confirmEnable': 'Enable this scheduled task?',
|
||
'tasks.confirmDelete': 'Permanently delete this task and all its logs?',
|
||
'tasks.running': 'Running...',
|
||
'tasks.viewLogs': 'Logs',
|
||
'tasks.logsTitle': 'Execution logs',
|
||
'tasks.noLogs': 'No execution logs yet',
|
||
'tasks.runStatus.running': 'Running',
|
||
'tasks.runStatus.completed': 'Completed',
|
||
'tasks.runStatus.failed': 'Failed',
|
||
'tasks.runStatus.timeout': 'Timeout',
|
||
'tasks.duration': '{s}s',
|
||
'tasks.viewOutput': 'Summary',
|
||
'tasks.hideOutput': 'Hide',
|
||
'tasks.close': 'Close',
|
||
'tasks.edit': 'Edit',
|
||
'tasks.editTitle': 'Edit scheduled task',
|
||
'tasks.saveChanges': 'Save changes',
|
||
'tasks.openSession': 'View conversation',
|
||
'tasks.createdAt': 'Created: ',
|
||
'tasks.lastRunAt': 'Last run: ',
|
||
'tasks.outputHintSession': 'Click "View conversation" to see the full output in session view.',
|
||
'tasks.noOutputText': 'No output available.',
|
||
|
||
// ─── Prompt Editor ──────────────────────────────────────
|
||
'promptEditor.worktree': 'worktree',
|
||
'promptEditor.bypassWarning': 'Bypass mode grants full system access',
|
||
'promptEditor.within': 'within',
|
||
'promptEditor.selectFolder': '— select a folder to limit scope',
|
||
|
||
// ─── Permission Mode Selector ──────────────────────────────────────
|
||
'permMode.executionPermissions': 'Execution Permissions',
|
||
'permMode.askPermissions': 'Ask permissions',
|
||
'permMode.askPermDesc': 'Confirm file edits and higher-risk commands when CLI asks',
|
||
'permMode.autoAccept': 'Auto accept edits',
|
||
'permMode.autoAcceptDesc': 'Claude writes to disk without asking',
|
||
'permMode.planMode': 'Plan mode',
|
||
'permMode.planModeDesc': 'Architecture & reasoning only, no files',
|
||
'permMode.bypass': 'Bypass permissions',
|
||
'permMode.bypassDesc': 'Full tool access for shell and file system',
|
||
'permMode.dontAsk': "Don't ask",
|
||
'permMode.enableBypassTitle': 'Enable bypass permissions?',
|
||
'permMode.enableBypassSubtitle': 'This grants full access to your system',
|
||
'permMode.enableBypassBody': 'Claude will have <strong>unrestricted</strong> access to execute shell commands and modify files within:',
|
||
'permMode.permReadWrite': 'Read, write, and delete any files',
|
||
'permMode.permShell': 'Execute arbitrary shell commands',
|
||
'permMode.permPackages': 'Install or remove packages',
|
||
'permMode.enableBypassBtn': 'Enable bypass',
|
||
|
||
// Mode labels (compact, for chips)
|
||
'permMode.label.default': 'Ask permissions',
|
||
'permMode.label.acceptEdits': 'Auto accept',
|
||
'permMode.label.plan': 'Plan mode',
|
||
'permMode.label.bypassPermissions': 'Bypass',
|
||
'permMode.label.dontAsk': "Don't ask",
|
||
|
||
// ─── Model Selector ──────────────────────────────────────
|
||
'model.selectModel': 'Select model',
|
||
'model.configuration': 'Model Configuration',
|
||
'model.effort': 'Effort',
|
||
|
||
// ─── Directory Picker ──────────────────────────────────────
|
||
'dirPicker.selectProject': 'Select a project...',
|
||
'dirPicker.recent': 'Recent',
|
||
'dirPicker.noRecent': 'No recent projects',
|
||
'dirPicker.chooseFolder': 'Choose a different folder',
|
||
'dirPicker.chooseProjectFolder': 'Choose project folder',
|
||
'dirPicker.useThisFolder': 'Use this folder',
|
||
'dirPicker.noSubdirs': 'No subdirectories',
|
||
|
||
// ─── File Search ──────────────────────────────────────
|
||
'fileSearch.searching': 'Searching...',
|
||
'fileSearch.noMatch': 'No files match',
|
||
'fileSearch.noFiles': 'No files in this directory',
|
||
'fileSearch.accessDenied': 'Cannot access this directory',
|
||
'fileSearch.loadFailed': 'Failed to load directory',
|
||
'fileSearch.navigate': 'navigate',
|
||
'fileSearch.attach': 'attach',
|
||
'fileSearch.select': 'select',
|
||
'fileSearch.open': 'open folder',
|
||
'fileSearch.close': 'close',
|
||
'fileSearch.directory': 'folder',
|
||
'fileSearch.currentDirectory': 'current folder',
|
||
'fileSearch.folderTag': 'folder',
|
||
'fileSearch.fileTag': 'file',
|
||
'fileSearch.openFolder': 'Open folder',
|
||
|
||
// ─── Teams ──────────────────────────────────────
|
||
'teams.backToLeader': '\u2190 Back to Leader',
|
||
'teams.viewing': 'Viewing:',
|
||
'teams.transcript': 'transcript',
|
||
'teams.noMessages': 'No messages yet',
|
||
'teams.team': 'Team:',
|
||
'teams.members': 'members',
|
||
'teams.working': 'Working...',
|
||
'teams.thinking': 'Thinking...',
|
||
'teams.running': 'running',
|
||
'teams.leader': 'team-lead',
|
||
'teams.memberPlaceholder': 'Message this teammate directly...',
|
||
'teams.memberSessionHint': 'Messages here go straight to this teammate while you watch its transcript update.',
|
||
|
||
// ─── Scheduled Tasks Pages ──────────────────────────────────────
|
||
'scheduledPage.title': 'Scheduled tasks',
|
||
'scheduledPage.subtitle': 'Run tasks on a schedule or whenever you need them. Type {code} in any existing session to create one.',
|
||
'scheduledPage.desktopNotice': 'Scheduled tasks only run while the desktop app is open. Make sure it stays running for tasks to fire on time.',
|
||
'scheduledPage.oldSubtitle': 'Manage automated operational routines and background maintenance.',
|
||
'scheduledPage.executionMode': 'Execution Mode',
|
||
'scheduledPage.localMode': 'Local Mode',
|
||
'scheduledPage.remoteMode': 'Remote Mode',
|
||
'scheduledPage.nextRun': 'Next Run',
|
||
'scheduledPage.systemHealth': 'System Health',
|
||
'scheduledPage.activeSession': 'Active Session',
|
||
'scheduledPage.colTaskName': 'Task Name',
|
||
'scheduledPage.colFrequency': 'Frequency',
|
||
'scheduledPage.colLastResult': 'Last Result',
|
||
'scheduledPage.colNextExecution': 'Next Execution',
|
||
'scheduledPage.colActions': 'Actions',
|
||
'scheduledPage.endOfList': 'End of scheduled list',
|
||
'scheduledPage.pausedTasks': '9 other tasks are currently paused or disabled for maintenance.',
|
||
'scheduledPage.recentLogs': 'Recent Output Logs',
|
||
'scheduledPage.viewArtifacts': 'View Full Artifacts',
|
||
'scheduledPage.resourceAllocation': 'Resource Allocation',
|
||
'scheduledPage.cpuCapacity': 'CPU Capacity',
|
||
'scheduledPage.memoryLoad': 'Memory Load',
|
||
'scheduledPage.connectedLocal': 'Connected to local node',
|
||
'scheduledPage.thisMonth': '{count} this month',
|
||
|
||
// ─── Update Checker ──────────────────────────────────────
|
||
'update.available': 'v{version} available',
|
||
'update.availableLabel': 'Available',
|
||
'update.checking': 'Checking for updates...',
|
||
'update.checkNow': 'Check now',
|
||
'update.checkedAt': 'Last checked {time}',
|
||
'update.currentVersionUnknown': 'Unknown',
|
||
'update.newVersion': 'New version v{version} available',
|
||
'update.downloading': 'Downloading...',
|
||
'update.idle': 'Check for updates to compare your installed version with the latest GitHub Release.',
|
||
'update.now': 'Update now',
|
||
'update.later': 'Later',
|
||
'update.progress': 'Downloading update... {progress}%',
|
||
'update.progressBytes': 'Downloading update... {downloaded} downloaded',
|
||
'update.releaseNotes': 'Release Notes',
|
||
'update.restarting': 'Restarting to finish update...',
|
||
'update.upToDate': 'You are up to date on v{version}.',
|
||
'update.failed': 'Update failed: {error}',
|
||
|
||
// ─── Active Session ──────────────────────────────────────
|
||
'session.untitled': 'Untitled Session',
|
||
'session.active': 'session active',
|
||
'session.lastUpdated': 'last updated {time}',
|
||
'session.messages': '{count} messages',
|
||
'session.workspaceUnavailable': 'Workspace unavailable: {dir}',
|
||
'session.timeJustNow': 'just now',
|
||
'session.timeMinutes': '{n}m ago',
|
||
'session.timeHours': '{n}h ago',
|
||
'session.timeDays': '{n}d ago',
|
||
|
||
// ─── App Shell ──────────────────────────────────────
|
||
'app.serverFailed': 'Local server failed to start',
|
||
'app.serverFailedHint': 'Please include a screenshot of this diagnostic panel when reporting the issue.',
|
||
'app.startupError': 'Startup error',
|
||
'app.serverLogs': 'Server logs',
|
||
'app.copyDiagnostics': 'Copy diagnostics',
|
||
'app.copiedDiagnostics': 'Copied',
|
||
'app.launching': 'Launching local workspace...',
|
||
|
||
// ─── Error Codes ──────────────────────────────────────
|
||
'error.CLI_NOT_RUNNING': 'CLI process is not running. The session may have ended or the process crashed.',
|
||
'error.CLI_START_FAILED': 'Failed to start CLI process.',
|
||
'error.CLI_AUTH_REQUIRED': 'Authentication is required. Please log in.',
|
||
'error.CLI_SESSION_CONFLICT': 'Session is already in use by another process.',
|
||
'error.CLI_SPAWN_FAILED': 'Failed to spawn CLI subprocess.',
|
||
'error.CLI_ERROR': 'An error occurred during processing.',
|
||
'error.WORKDIR_INVALID': 'Working directory is invalid or does not exist.',
|
||
'error.PARSE_ERROR': 'Invalid message format.',
|
||
'error.UNKNOWN_TYPE': 'Unknown message type.',
|
||
'error.BAD_REQUEST': 'Bad request.',
|
||
'error.NOT_FOUND': 'Resource not found.',
|
||
'error.INTERNAL_ERROR': 'Internal server error.',
|
||
|
||
// ─── Server Status Verbs ──────────────────────────────────────
|
||
'serverVerb.Thinking': 'Thinking',
|
||
'serverVerb.Running': 'Running',
|
||
'serverVerb.Working': 'Working',
|
||
'serverVerb.Creating worktree': 'Creating worktree',
|
||
'serverVerb.Task started': 'Task started',
|
||
'serverVerb.Task in progress': 'Task in progress',
|
||
|
||
// ─── Tabs ──────────────────────────────────────
|
||
'tabs.close': 'Close',
|
||
'tabs.closeOthers': 'Close Others',
|
||
'tabs.closeLeft': 'Close to the Left',
|
||
'tabs.closeRight': 'Close to the Right',
|
||
'tabs.closeAll': 'Close All',
|
||
'tabs.closeConfirmTitle': 'Session Running',
|
||
'tabs.closeConfirmMessage': 'This session is still running. What would you like to do?',
|
||
'tabs.closeConfirmKeep': 'Keep Running',
|
||
'tabs.closeConfirmStop': 'Stop & Close',
|
||
'tabs.openTerminal': 'Open Terminal',
|
||
'tabs.showWorkspace': 'Show Workspace',
|
||
'tabs.hideWorkspace': 'Hide Workspace',
|
||
} as const
|
||
|
||
export type TranslationKey = keyof typeof en
|