2026-07-11 03:25:58 +08:00

2156 lines
132 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.tokens': '{count} tokens',
'common.rename': 'Rename',
'common.retry': 'Retry',
'common.loading': 'Loading...',
'common.select': 'Select',
'common.enable': 'Enable',
'common.disable': 'Disable',
'common.active': 'ACTIVE',
'common.error': 'Error',
'common.copyFailed': 'Copy failed.',
'common.copied': 'Copied',
// ─── Sidebar ──────────────────────────────────────
'sidebar.newSession': 'New session',
'sidebar.scheduled': 'Scheduled',
'sidebar.skills': 'Skills',
'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',
'search.global.trigger': 'Search chats',
'search.global.placeholder': 'Search all chats…',
'search.global.recentTitle': 'Recent chats',
'search.global.noResults': 'No matches found',
'search.global.matchCount': '{count} matches',
'search.global.truncated': 'Showing first {count} chats — refine your query',
'search.global.roleUser': 'You',
'search.global.roleAssistant': 'Assistant',
'search.global.loading': 'Searching…',
'search.global.error': 'Search failed',
'search.global.close': 'Close',
'sidebar.projects': 'Projects',
'sidebar.projectMenu': 'Project menu',
'sidebar.newProject': 'New project',
'sidebar.archiveAllChats': 'Archive all chats',
'sidebar.organizeSidebar': 'Organize sidebar',
'sidebar.sortCondition': 'Sort condition',
'sidebar.organizeByProject': 'By project',
'sidebar.organizeByRecentProject': 'Recent projects',
'sidebar.organizeByTime': 'By time',
'sidebar.sortByCreatedAt': 'Created time',
'sidebar.sortByUpdatedAt': 'Updated time',
'sidebar.newBlankProject': 'New blank project',
'sidebar.useExistingFolder': 'Use existing folder',
'sidebar.chooseProjectFolderUnavailable': 'Folder selection is only available in the desktop app.',
'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.hideProjectFromSidebar': 'Hide from Sidebar',
'sidebar.restoreProjectToSidebar': 'Restore to Sidebar',
'sidebar.restoreHiddenProjects': 'Restore hidden projects ({count})',
'sidebar.projectHidden': '{project} was hidden from the sidebar. Existing sessions were not deleted.',
'sidebar.newSessionInProject': 'New session in {project}',
'sidebar.showMoreSessions': 'Expand display',
'sidebar.showFewerSessions': 'Collapse display',
'sidebar.expandProject': 'Expand {project}',
'sidebar.collapseProject': 'Collapse {project}',
'sidebar.worktree': 'worktree',
'sidebar.sessionRunning': 'Session running',
'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',
// ─── Open With ─────────────────────────────────────
'openWith.title': 'Open with',
'openWith.inAppBrowser': 'In-app browser',
'openWith.systemBrowser': 'System browser',
'openWith.workspacePreview': 'Workspace preview',
'openWith.openInTarget': 'Open in {target}',
'openWith.revealInTarget': 'Reveal in {target}',
'openWith.fileType.document': 'Document',
'openWith.fileType.web': 'Web',
'openWith.fileType.image': 'Image',
'openWith.fileType.code': 'Code',
'openWith.fileType.file': 'File',
// ─── Assistant Output Targets ──────────────────────
'assistantOutputs.kind.markdown': 'Markdown',
'assistantOutputs.kind.html': 'HTML',
'assistantOutputs.kind.image': 'Image',
'assistantOutputs.kind.localhost': 'Localhost',
'assistantOutputs.moreOutputs': '+{count} more',
'assistantOutputs.open': 'Open',
// ─── 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.showNavigator': 'Show file navigator',
'workspace.hideNavigator': 'Hide file navigator',
'workbench.modeSwitch': 'Workbench mode',
'workbench.modeWorkspace': 'Files',
'workbench.modeBrowser': 'Browser',
'workbench.expand': 'Expand panel',
'workbench.close': 'Close',
'workbench.tabTitle': 'Workbench',
'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.copyAbsolutePath': 'Copy absolute 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.trace': 'Trace',
'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.profileTitle': 'Profile',
'settings.activity.profilePrivacy': 'Local only',
'settings.activity.defaultHandle': 'github.com/NanmiCoder/cc-haha',
'settings.activity.editProfile': 'Edit profile',
'settings.activity.displayName': 'Display name',
'settings.activity.subtitle': 'Second line',
'settings.activity.displayNameHelper': 'Edit the display name and second line; URLs in the second line open as links.',
'settings.activity.avatar': 'Avatar',
'settings.activity.avatarHelper': 'PNG, JPEG, or WebP up to 2 MB.',
'settings.activity.changeAvatar': 'Change avatar',
'settings.activity.removeAvatar': 'Remove avatar',
'settings.activity.saveProfile': 'Save',
'settings.activity.cancelEdit': 'Cancel',
'settings.activity.profileSaved': 'Saved locally',
'settings.activity.profileSaveFailed': 'Could not save profile',
'settings.activity.subtitleLoading': 'Based on local Claude Code CLI session transcripts',
'settings.activity.totalTokens': 'Total tokens',
'settings.activity.peakTokens': 'Peak tokens',
'settings.activity.longestTask': 'Longest task',
'settings.activity.currentStreak': 'Current streak',
'settings.activity.longestStreak': 'Longest streak',
'settings.activity.noDuration': '0m',
'settings.activity.tokenActivity': 'Token Activity',
'settings.activity.mode.daily': 'Daily',
'settings.activity.mode.weekly': 'Weekly',
'settings.activity.mode.cumulative': 'Cumulative',
'settings.activity.modeHelp.daily': "Daily: each square is that day's token usage.",
'settings.activity.modeHelp.weekly': "Weekly: each column is one week's total token usage.",
'settings.activity.modeHelp.cumulative': 'Cumulative: each column is total tokens up to that week.',
'settings.activity.emptyTitle': 'No local usage yet',
'settings.activity.emptyBody': 'Start a CLI or desktop session and completed model replies will appear here.',
'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.weekRange': '{start} - {end}',
'settings.activity.cumulativeThrough': 'Through {date}',
'settings.activity.tokenValue': '{tokens} Tokens',
'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.count.runOne': '{count} run',
'settings.activity.count.runOther': '{count} runs',
'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.activityInsights': 'Activity insights',
'settings.activity.activeRate': 'Active rate',
'settings.activity.mostUsedModel': 'Most used model',
'settings.activity.exploredSkills': 'Skills explored',
'settings.activity.totalSkillUses': 'Skill uses',
'settings.activity.totalToolCalls': 'Tool calls',
'settings.activity.totalSessions': 'Total sessions',
'settings.activity.mostUsedPluginsAndSkills': 'Most used plugins & skills',
'settings.activity.none': 'None',
'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.infoLabel': 'Terminal setup help',
'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.preferencesTitle': 'Startup shell',
'settings.terminal.preferencesBody': 'Use for new terminal sessions and after restart.',
'settings.terminal.startupShell': 'Startup shell',
'settings.terminal.customPath': 'Custom shell path',
'settings.terminal.customPathPlaceholder': 'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
'settings.terminal.customPathRequired': 'Enter a shell path before saving.',
'settings.terminal.customPathAbsolute': 'Custom shell path must be an absolute Windows path.',
'settings.terminal.saveShell': 'Save shell',
'settings.terminal.saveShellSuccess': 'Saved. Restart or open a new terminal to apply it.',
'settings.terminal.shell.system': 'System default',
'settings.terminal.shell.systemDesc': 'Keep the current COMSPEC-based behavior.',
'settings.terminal.shell.pwsh': 'PowerShell 7 (pwsh)',
'settings.terminal.shell.pwshDesc': 'Use pwsh.exe when it is installed.',
'settings.terminal.shell.powershell': 'Windows PowerShell',
'settings.terminal.shell.powershellDesc': 'Use the built-in powershell.exe.',
'settings.terminal.shell.cmd': 'Command Prompt',
'settings.terminal.shell.cmdDesc': 'Use cmd.exe explicitly.',
'settings.terminal.shell.custom': 'Custom executable',
'settings.terminal.shell.customDesc': 'Launch an absolute shell executable path.',
'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',
'settings.terminal.bashPathLabel': 'Bash Path',
'settings.terminal.bashPathDescription': 'Windows defaults to CMD as the terminal shell. If tool calls use Unix commands (grep, sed, etc.), configure the path to a Bash executable here (e.g., Git Bash).',
'settings.terminal.bashPathSave': 'Save',
'settings.terminal.bashPathReset': 'Reset to default',
'settings.terminal.bashPathSaved': 'Saved',
'settings.terminal.bashPathInvalid': 'Path does not exist. Select a valid Bash executable.',
'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 > ChatGPT Official Login
'settings.chatgptOfficialLogin.intro': 'Sign in with ChatGPT to use GPT models from desktop sessions.',
'settings.chatgptOfficialLogin.loginButton': 'Sign in with ChatGPT',
'settings.chatgptOfficialLogin.loginStarting': 'Starting sign-in...',
'settings.chatgptOfficialLogin.logoutButton': 'Sign out',
'settings.chatgptOfficialLogin.logoutProcessing': 'Signing out...',
'settings.chatgptOfficialLogin.loggedInPrefix': 'Signed in as',
'settings.chatgptOfficialLogin.accountUnknown': 'ChatGPT account',
'settings.chatgptOfficialLogin.openBrowserFailed': 'Unable to open browser. Copy the authorization link and open it manually.',
'settings.chatgptOfficialLogin.copyAuthorizeUrl': 'Copy authorization link',
'settings.chatgptOfficialLogin.copyLinkFailed': 'Unable to copy authorization link.',
'settings.chatgptOfficialLogin.errorPrefix': 'ChatGPT OAuth error: ',
// 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.openaiOfficialName': 'ChatGPT Official',
'settings.providers.openaiOfficialDesc': 'OpenAI OAuth via your ChatGPT account — 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.dragToReorder': 'Drag to reorder',
'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.model1mSupportShort': '1M',
'settings.providers.modelIdPlaceholder': 'Model ID',
'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 models 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.providers.toolSearchEnabled': 'Enable Tool Search',
'settings.providers.toolSearchDesc': 'Load MCP and deferred tools on demand to reduce initial tool schema tokens. Disable it for weak models or providers that reject tool references.',
'settings.providers.toolSearchUnsupported': 'Only Anthropic Messages providers support Tool Search here. OpenAI proxy formats keep full tool schemas available.',
'settings.providers.disableExperimentalBetas': 'Disable experimental beta headers',
'settings.providers.disableExperimentalBetasDesc': 'Sets CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 for this provider to avoid beta API shapes that third-party gateways may reject.',
// 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 Telegram, WeChat, DingTalk, WhatsApp, or Feishu. For setup details, see',
'settings.adapters.configurationDocs': 'documentation link',
'settings.adapters.descriptionAfterDocs': '.',
'settings.adapters.telegram': 'Telegram',
'settings.adapters.feishu': 'Feishu',
'settings.adapters.wechat': 'WeChat',
'settings.adapters.dingtalk': 'DingTalk',
'settings.adapters.whatsapp': 'WhatsApp',
'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.feishuCreateBotTitle': 'Need a Feishu bot?',
'settings.adapters.feishuCreateBotDesc': 'Use the documented OpenClaw template to create a Feishu bot with the required permissions already configured. Then paste the App ID and App Secret below.',
'settings.adapters.feishuCreateBotAction': 'Create Feishu bot',
'settings.adapters.feishuCreateBotStepCreate': 'Create the bot from the template.',
'settings.adapters.feishuCreateBotStepFill': 'Copy its App ID and App Secret, then fill them in here.',
'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.waAllowedUsersPlaceholder': 'e.g. 15551234567@s.whatsapp.net',
'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, WhatsApp, or Telegram private chat. WeChat and WhatsApp require 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.platform.whatsapp': 'WhatsApp',
'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.dingtalkUnbindBotConfirm': 'Unbind this DingTalk bot account? You will need to scan again before DingTalk can receive or send messages.',
'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.wechatUnbindAccountConfirm': 'Unbind this WeChat account? You will need to scan again before WeChat can receive or send messages.',
'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.adapters.whatsappBind': 'Scan to Bind',
'settings.adapters.whatsappRebind': 'Rescan',
'settings.adapters.whatsappConnected': 'WhatsApp is bound',
'settings.adapters.whatsappNotConnected': 'WhatsApp is not bound',
'settings.adapters.whatsappQrHint': 'Generate a QR code, then scan it from WhatsApp > Linked devices. The adapter restarts after binding.',
'settings.adapters.whatsappQrAlt': 'WhatsApp binding QR code',
'settings.adapters.whatsappWaiting': 'Waiting for WhatsApp scan confirmation...',
'settings.adapters.whatsappBindSuccess': 'WhatsApp bound successfully.',
'settings.adapters.whatsappBindFailed': 'Failed to bind WhatsApp.',
'settings.adapters.whatsappUnbindAccount': 'Unbind WhatsApp account',
'settings.adapters.whatsappUnbindAccountConfirm': 'Unbind this WhatsApp account? You will need to scan again before WhatsApp can receive or send messages.',
'settings.adapters.whatsappUnbound': 'WhatsApp account unbound.',
'settings.adapters.whatsappUnbindFailed': 'Failed to unbind WhatsApp.',
'settings.adapters.whatsappAllowedUsersHint': 'QR binding links the WhatsApp Web account only. Users still need to send a pairing code, or you can add allowed WhatsApp JIDs here.',
// Settings > MCP
'settings.mcp.title': 'MCP servers',
'settings.mcp.description': 'Connect external tools and data sources for Claude Code. Local, project, and user scopes follow the same behavior as the CLI.',
'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 projects `.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': 'Choose Local for one project, Project for `.mcp.json`, or User for all projects.',
'settings.mcp.currentProjectHint': 'Selected project: {path}',
'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': 'Configure {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.redirectDescription': 'Skills now live in the unified Skill Center, where marketplace and installed skills are managed together.',
'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.searchLabel': 'Search skills',
'settings.skills.searchPlaceholder': 'Search skills by name, description, or source...',
'settings.skills.searchResultCount': '{count} of {total} skills match',
'settings.skills.clearSearch': 'Clear skill search',
'settings.skills.noSearchResults': 'No matching skills',
'settings.skills.noSearchResultsHint': 'Try another keyword or clear search to show every skill.',
'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.edit': 'Edit',
'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.discardUnsavedConfirm': 'Discard unsaved memory changes?',
'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.selectionCount': '{count} selected',
'settings.plugins.clearSelection': 'Clear',
'settings.plugins.enableSelected': 'Enable selected',
'settings.plugins.disableSelected': 'Disable selected',
'settings.plugins.selectPlugin': 'Select {name}',
'settings.plugins.bulkEnableTitle': 'Enable {count} selected plugins?',
'settings.plugins.bulkDisableTitle': 'Disable {count} selected plugins?',
'settings.plugins.bulkEnableBody': 'This will enable {names} and apply plugin changes to the current desktop runtime.',
'settings.plugins.bulkDisableBody': 'This will disable {names} and apply plugin changes to the current desktop runtime.',
'settings.plugins.bulkEnableToast': 'Enabled {count} plugins and applied plugin changes.',
'settings.plugins.bulkDisableToast': 'Disabled {count} plugins and applied plugin changes.',
'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 - Storage
'settings.general.modeSwitchTitle': 'Switch data storage location?',
'settings.general.modeSwitchConfirm': 'Save and Restart',
'settings.general.storageTitle': 'Data Storage Location',
'settings.general.storageDescription': 'Advanced, low-frequency setting. After switching, sessions, Skills, MCP, plugins, provider settings, tasks, and caches are read from the new directory.',
'settings.general.storageSystemTitle': 'Use system directory',
'settings.general.storageSystemDescription': 'Return to the default data source. If CLAUDE_CONFIG_DIR is set in the launch environment, that environment variable still takes priority.',
'settings.general.storagePortableTitle': 'Use portable directory',
'settings.general.storagePortableDescription': 'Store desktop data in a folder you choose. Use this for external drives or app bundles you want to move together.',
'settings.general.storagePortableDirLabel': 'Portable data directory',
'settings.general.storagePortableDirPlaceholder': 'Choose a folder for cc-haha data',
'settings.general.storageChooseDir': 'Choose Folder',
'settings.general.storageChooseDirTitle': 'Choose portable data directory',
'settings.general.storageUseDefaultPortableDir': 'Use the default portable folder beside the app',
'settings.general.storageApplyPortable': 'Use This Folder and Restart',
'settings.general.storageActiveDir': 'Current active data directory',
'settings.general.storageEnvironmentHint': 'The current directory is controlled by the CLAUDE_CONFIG_DIR environment variable. In-app switching cannot override it; remove CLAUDE_CONFIG_DIR from the launch environment to return to the system directory.',
'settings.general.storageEnvironmentSwitchBlocked': 'CLAUDE_CONFIG_DIR currently controls the data directory. Remove it from the launch environment before switching back to the system directory.',
'settings.general.storageRestartHint': 'The storage change has been saved. Restart the app for the new data directory to take effect.',
'settings.general.storageMoveHint': 'Switching directories does not migrate existing data. Copy projects, skills, plugins, cc-haha, and related folders from the old directory if you want old sessions to keep appearing. For a portable bundle, keep this folder beside the app and zip them together.',
'settings.general.storageNoDirError': 'Choose or enter a portable data directory first.',
'settings.general.storagePickerError': 'Could not open the folder picker. Paste the folder path manually.',
'settings.general.storageRestartError': 'The change was saved, but automatic restart failed. Restart the app manually.',
'settings.general.storageSwitchPortableBody': 'After switching, the desktop app will read and write sessions, settings, Skills, MCP, plugins, tasks, and caches in this directory.',
'settings.general.storageSwitchDefaultBody': 'After switching back, the desktop app will use the system data source again. Data in the portable directory is not deleted or moved back automatically.',
'settings.general.storageSwitchRestartBody': 'The app will stop the local server and adapter processes, then relaunch. The new directory takes effect after restart.',
// 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.outputStyleTitle': 'Output Style',
'settings.general.outputStyleDescription': 'Choose how Claude communicates in new or restarted sessions.',
'settings.general.outputStyleBuiltin.default.label': 'Default',
'settings.general.outputStyleBuiltin.default.description': 'Claude completes coding tasks efficiently and provides concise responses',
'settings.general.outputStyleBuiltin.explanatory.label': 'Explanatory',
'settings.general.outputStyleBuiltin.explanatory.description': 'Claude explains its implementation choices and codebase patterns',
'settings.general.outputStyleBuiltin.learning.label': 'Learning',
'settings.general.outputStyleBuiltin.learning.description': 'Claude pauses and asks you to write small pieces of code for hands-on practice',
'settings.general.outputStyleSelectLabel': 'Select output style',
'settings.general.outputStyleLoading': 'Loading output styles...',
'settings.general.outputStyleSaved': 'Output style saved.',
'settings.general.outputStyleRestartHint': 'Running sessions keep their current prompt. Start a new session, continue in a fresh process, or restart the session for this to apply.',
'settings.general.outputStyleScopeLocal': 'Current project',
'settings.general.outputStyleScopeUser': 'User settings',
'settings.general.outputStyleScopeLocalHint': 'Saved to .claude/settings.local.json for the active project.',
'settings.general.outputStyleScopeUserHint': 'Saved to your user settings because no active project is selected.',
'settings.general.outputStyleSourceBuiltIn': 'Built-in',
'settings.general.outputStyleSourceUser': 'User style',
'settings.general.outputStyleSourceProject': 'Project style',
'settings.general.outputStyleSourceLocal': 'Local project style',
'settings.general.outputStyleSourcePolicy': 'Managed style',
'settings.general.outputStyleSourcePlugin': 'Plugin style',
'settings.general.defaultPermissionTitle': 'Default Session Permissions',
'settings.general.defaultPermissionDescription': 'Choose the permission mode applied when a new desktop chat session starts.',
'settings.general.defaultPermissionLabel': 'New session permission mode',
'settings.general.defaultPermissionHint': 'Individual sessions can still be changed from the chat permission selector.',
'settings.general.defaultPermissionScope': 'Each new session workspace',
'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.xhigh': 'X-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.autoDreamTitle': 'Auto-dream',
'settings.general.autoDreamDescription': 'Periodically consolidates auto-memory in the background after enough sessions have changed.',
'settings.general.autoDreamEnabled': 'Enable Auto-dream',
'settings.general.autoDreamHintOn': 'The desktop app can run memory consolidation after eligible sessions finish.',
'settings.general.autoDreamHintOff': 'Off by default because it can run background model calls.',
'settings.general.autoDreamConfirmTitle': 'Enable Auto-dream?',
'settings.general.autoDreamConfirmKeepRunning': 'Keep the desktop app running so background memory consolidation can start after eligible sessions finish.',
'settings.general.autoDreamConfirmTokenCost': 'Auto-dream uses additional model tokens when it reviews and rewrites memory files.',
'settings.general.autoDreamConfirmEnable': 'Enable Auto-dream',
'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.traceTitle': 'Agent trace',
'settings.general.traceDescription': 'Collect local model request traces for stuck sessions, failed calls, and unexpected waits.',
'settings.general.traceEnabled': 'Collect agent traces',
'settings.general.traceHintOn': 'New sessions write compact requests, responses, and status events to the local cc-haha traces directory.',
'settings.general.traceHintOff': 'No new traces will be written. Existing records remain available in the trace list.',
'settings.general.chatSendBehaviorTitle': 'Message Sending',
'settings.general.chatSendBehaviorDescription': 'Choose how the desktop chat composer submits messages.',
'settings.general.chatSendBehaviorEnter': 'Enter sends',
'settings.general.chatSendBehaviorEnterDescription': 'Shift+Enter inserts a new line.',
'settings.general.chatSendBehaviorModifier': 'Ctrl/Cmd+Enter sends',
'settings.general.chatSendBehaviorModifierDescription': 'Enter and Shift+Enter insert new lines.',
'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': 'Tokens from older versions cannot be recovered. Regenerate once and the token will be kept permanently and stay viewable.',
'settings.general.h5AccessPublicHost': 'Access host / IP',
'settings.general.h5AccessPublicHostPlaceholder': '192.168.1.100',
'settings.general.h5AccessCurrentPort': 'Current port',
'settings.general.h5AccessCurrentPortUnknown': 'Auto',
'settings.general.h5AccessFixedPort': 'Fixed port',
'settings.general.h5AccessFixedPortPlaceholder': 'Auto',
'settings.general.h5AccessFixedPortInvalid': 'Port must be an integer between 1024 and 65535.',
'settings.general.h5AccessFixedPortHint': 'Without a fixed port the previous port is reused automatically; pin one for reverse proxies and other setups that need a stable port. Port changes apply after restarting the app.',
'settings.general.h5AccessFixedPortRestartNote': 'Fixed port {fixedPort} takes effect after restarting the app; currently still running on {activePort}.',
'settings.general.h5AccessDisconnectGrace': 'Disconnect grace (sec)',
'settings.general.h5AccessDisconnectGracePlaceholder': '30',
'settings.general.h5AccessDisconnectGraceInvalid': 'Must be an integer between 5 and 86400 seconds.',
'settings.general.h5AccessDisconnectGraceHint': 'When a phone locks its screen or backgrounds the app and disconnects, a running task is never interrupted — it finishes in the background and the result shows on reconnect. The CLI is only stopped after this idle period once the task is done and no client is attached (default 30s). Raise it for remote use on the go, e.g. 600.',
'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': 'For LAN access, change only the host / IP; the current service port is reused. Enter a full URL for reverse proxies.',
'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.h5AccessStaleHostTitle': 'Saved H5 host is no longer reachable',
'settings.general.h5AccessStaleHostBody': 'The saved host {storedHost} is not bound to any active interface on this machine. Phones scanning the QR code will fail to connect. We recommend switching to the current LAN IP.',
'settings.general.h5AccessStaleHostNoSuggestion': 'The saved host {storedHost} is not bound to any active interface on this machine. Phones scanning the QR code will fail to connect. Please check this machines network connection, or switch to a reverse proxy URL.',
'settings.general.h5AccessStaleHostApply': 'Switch to {suggestedHost}',
'settings.general.h5AccessProxyNote': 'Currently using a reverse proxy URL. Phones reach the desktop through the public domain / tunnel you configured. Make sure your proxy is still up.',
'settings.general.networkTitle': 'Network',
'settings.general.networkDescription': 'Controls provider API requests made by desktop sessions.',
'settings.general.networkProxyModeDirect': 'Direct connection',
'settings.general.networkProxyModeDirectDescription': 'Do not use inherited proxy settings for provider API requests.',
'settings.general.networkProxyModeSystem': 'System proxy',
'settings.general.networkProxyModeSystemDescription': 'Use proxy settings inherited by the app process.',
'settings.general.networkProxyModeManual': 'Manual proxy',
'settings.general.networkProxyModeManualDescription': 'Use the HTTP or HTTPS proxy URL entered below.',
'settings.general.networkProxyUrl': 'Proxy URL',
'settings.general.networkProxyUrlHint': 'HTTP and HTTPS proxy URLs are supported. For authenticated proxies, use http://user:password@127.0.0.1:7890; the URL is saved with network settings.',
'settings.general.networkProxyUrlInvalid': 'Enter an HTTP or HTTPS proxy URL.',
'settings.general.networkProxyUrlRequired': 'Enter a proxy URL.',
'settings.general.networkTimeout': 'AI request timeout',
'settings.general.networkTimeoutValue': '{seconds}s',
'settings.general.networkTimeoutHint': 'Applies to provider requests, streaming first responses, and provider connection tests. Supports 30-1800 seconds; slow providers may need several minutes before the first streamed byte.',
'settings.general.networkTimeoutUnit': 'sec',
'settings.general.networkTimeoutDecrease': 'Decrease by 30 seconds',
'settings.general.networkTimeoutIncrease': 'Increase by 30 seconds',
'settings.general.networkTimeoutRequired': 'Enter a timeout.',
'settings.general.networkTimeoutRange': 'Enter a whole number from {min} to {max} seconds.',
'settings.general.networkSaved': 'Network settings saved.',
'settings.general.networkScopeHint': 'Does not change the separate app update proxy.',
'settings.general.networkSave': 'Save',
'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.dropFilesTitle': 'Drop files here',
'chat.dropFilesHint': 'Attached as file paths.',
'chat.workspaceReferencesOnly': 'Added {count} workspace references',
'chat.contextReferencesOnly': 'Added {count} references',
'chat.addSelectionToChat': 'Add to chat',
'chat.branchFromHere': 'Fork a new conversation',
'chat.branchSuccess': 'Created forked conversation "{title}".',
'chat.branchError': 'Failed to branch from this message. Detail: {detail}',
'chat.userMessageReference': 'User message',
'chat.assistantMessageReference': 'Assistant message',
'chat.slashCommands': 'Slash commands',
'chat.pendingMessageGuide': 'Guide',
'chat.pendingMessageGuideNow': 'Guide now',
'chat.pendingMessageEdit': 'Edit queued message',
'chat.pendingMessageDelete': 'Delete queued message',
'chat.pendingMessageEditInput': 'Queued message text',
'chat.goalEvent.created': 'Goal set',
'chat.goalEvent.replaced': 'Goal set',
'chat.goalEvent.statusTitle': 'Goal status',
'chat.goalEvent.paused': 'Goal paused',
'chat.goalEvent.resumed': 'Goal resumed',
'chat.goalEvent.completed': 'Goal completed',
'chat.goalEvent.cleared': 'Goal cleared',
'chat.goalEvent.continuing': 'Goal continuing',
'chat.goalEvent.message': 'Goal update',
'chat.goalEvent.objective': 'Objective: {value}',
'chat.goalEvent.statusValue': 'Status: {value}',
'chat.goalEvent.budget': 'Budget: {value}',
'chat.goalEvent.continuations': 'Continuations: {value}',
'chat.compactSummary.compacting': 'Compacting context',
'chat.compactSummary.title': 'Context compacted',
'chat.compactSummary.autoTitle': 'Context automatically compacted',
'chat.compactSummary.manualTitle': 'Context manually compacted',
'chat.compactSummary.trigger.manual': 'manual',
'chat.compactSummary.trigger.auto': 'auto',
'chat.compactSummary.tokens': '{count} tokens before compact',
'chat.compactSummary.messages': '{count} messages summarized',
'chat.activeGoal.title': 'Active goal',
'chat.activeGoal.running': 'Loop running',
'chat.activeGoal.active': 'Active',
'chat.activeGoal.paused': 'Paused',
'chat.activeGoal.completed': 'Completed',
'chat.activeGoal.budget': 'Budget {value}',
'chat.activeGoal.continuations': 'Continuations {value}',
'chat.activeGoal.elapsed': 'Elapsed {value}',
'chat.backgroundAgents.title': 'Background agents',
'chat.backgroundAgents.count': '{count} active or recent',
'chat.backgroundAgents.agent': 'agent',
'chat.backgroundTasks.title': 'Background tasks',
'chat.backgroundTasks.runningCountOne': '{count} running task',
'chat.backgroundTasks.runningCountMany': '{count} running tasks',
'chat.backgroundTasks.finishedCountOne': '{count} finished task',
'chat.backgroundTasks.finishedCountMany': '{count} finished tasks',
'chat.backgroundTasks.running': 'Running',
'chat.backgroundTasks.finished': 'Finished',
'chat.backgroundTasks.clear': 'Clear',
'chat.backgroundTasks.close': 'Close background tasks',
'chat.backgroundTasks.command': 'Background command',
'chat.backgroundTasks.workflow': 'Background workflow',
'chat.backgroundTasks.task': 'Background task',
'chat.backgroundTasks.type.agent': 'Agent',
'chat.backgroundTasks.type.bash': 'Bash',
'chat.backgroundTasks.type.workflow': 'Workflow',
'chat.backgroundTasks.type.task': 'Task',
'chat.backgroundAgents.tokens': '{count} tokens',
'chat.backgroundAgents.status.running': 'running',
'chat.backgroundAgents.status.completed': 'completed',
'chat.backgroundAgents.status.failed': 'failed',
'chat.backgroundAgents.status.stopped': 'stopped',
'chat.duration.seconds': '{seconds}s',
'chat.duration.minutesSeconds': '{minutes}m {seconds}s',
'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.turnChangesOpenInWorkspaceAria': 'Open {path} in workspace',
'chat.turnChangesShowMore': 'Show {count} more files',
'chat.turnChangesShowLess': 'Show less',
// ─── 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',
'permission.planReadyTitle': 'Ready to code?',
'permission.planPreviewTitle': "Claude's plan",
'permission.planRequestedPermissions': 'Requested permissions',
'permission.planApprove': 'Approve plan',
'permission.planKeepPlanning': 'Keep planning',
'permission.planFeedbackPlaceholder': 'Tell Claude what to change',
'permission.planEmpty': 'No plan content available.',
'permission.planApproved': 'Plan approved',
'permission.planRejected': 'Plan rejected',
// ─── 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.completed': 'Completed',
'question.customResponse': 'Or type a custom response:',
'question.typePlaceholder': 'Type your answer...',
'question.submit': 'Submit',
'question.answeredPrefix': 'Answered: ',
'question.resultPrefix': 'Result: ',
// ─── Thinking Block ──────────────────────────────────────
'thinking.label': 'Thinking',
'thinking.labelDone': 'Thought',
// ─── Tool Calls ──────────────────────────────────────
'tool.errorOutput': 'Error Output',
'tool.toolOutput': 'Tool Output',
'tool.toolInput': 'Tool Input',
'tool.partialInput': 'Partial input',
'tool.writerPreview': 'Writer',
'tool.writerPreviewLatest': 'Showing latest {visible} of {total} lines',
'tool.contentStats': '{lines} · {chars}',
'tool.contentStatsLatest': 'Showing latest {visible} / {total} lines · {chars}',
'tool.lineCountSingular': '{count} line',
'tool.lineCountPlural': '{count} lines',
'tool.charCountSingular': '{count} char',
'tool.charCountPlural': '{count} chars',
'tool.generatingContent': 'Generating content',
'tool.preparingEdit': 'Preparing edit',
'tool.preparingTool': 'Preparing tool',
'tool.stopped': 'Stopped',
'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.fullPermissions': 'Full permissions',
'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 (MonFri)',
'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',
'permMode.disabledDuringTurn': 'Cannot switch permissions while session is active',
// 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.',
// ─── Session Activity ──────────────────────────────────────
'session.activity.title': 'Activity',
'session.activity.close': 'Close activity',
'session.activity.clearFinished': 'Clear finished',
'session.activity.openTeamMember': 'Open team member {name}',
'session.activity.openRun': 'Open run {name}',
'session.activity.openBackgroundTask': 'Open background task {name}',
'session.activity.stopBackgroundTask': 'Stop background task {name}',
'session.activity.stoppingBackgroundTask': 'Stopping background task {name}',
'session.activity.details.title': 'Details',
'session.activity.details.type': 'Type',
'session.activity.details.description': 'Description',
'session.activity.details.summary': 'Summary',
'session.activity.details.outputFile': 'Output file',
'session.activity.details.usage': 'Usage',
'session.activity.section.tasks': 'Tasks',
'session.activity.section.team': 'Team',
'session.activity.section.backgroundTasks': 'Background Tasks',
'session.activity.section.subagents': 'SubAgents',
'session.activity.section.sources': 'Sources',
'session.activity.empty.tasks': 'No tasks',
'session.activity.empty.team': 'No team members',
'session.activity.empty.backgroundTasks': 'No background tasks',
'session.activity.empty.subagents': 'No SubAgents',
'session.activity.empty.sources': 'No sources',
'session.activity.task.completed': 'Task completed',
'session.activity.task.inProgress': 'Task in progress',
'session.activity.task.pending': 'Task pending',
'session.activity.tasks.earlier': 'Earlier tasks',
'session.activity.tasks.earlierSummary': 'Earlier turns: {completed}/{total} completed',
'session.activity.status.pending': 'Pending',
'session.activity.status.inProgress': 'In progress',
'session.activity.status.completed': 'Completed',
'session.activity.status.running': 'Running',
'session.activity.status.failed': 'Failed',
'session.activity.status.stopped': 'Stopped',
'session.activity.status.idle': 'Idle',
'session.activity.status.error': 'Error',
'session.activity.status.unknown': 'Unknown',
// ─── SubAgent Run ──────────────────────────────────────
'subagentRun.refresh': 'Refresh SubAgent run',
'subagentRun.loading': 'Loading SubAgent run...',
'subagentRun.source': 'Source',
'subagentRun.agent': 'Agent',
'subagentRun.unknown': 'Unknown',
'subagentRun.task': 'Task',
'subagentRun.updated': 'Updated',
'subagentRun.output': 'Output',
'subagentRun.agentInvocation': 'Agent invocation',
'subagentRun.parentToolInput': 'Parent Agent tool input',
'subagentRun.parentToolCall': 'Parent Agent Tool Call',
'subagentRun.transcript': 'Transcript',
'subagentRun.noTranscript': 'No local transcript messages captured for this SubAgent.',
'subagentRun.truncated': 'Showing first 50 and latest 950 entries',
'subagentRun.source.transcript': 'Transcript',
'subagentRun.source.sessionHistory': 'Session history',
'subagentRun.source.liveTask': 'Live task',
'subagentRun.source.none': 'None',
'subagentRun.status.completed': 'Completed',
'subagentRun.status.failed': 'Failed',
'subagentRun.status.stopped': 'Stopped',
'subagentRun.status.running': 'Running',
'subagentRun.status.unknown': 'Unknown',
'subagentRun.result.completedFallback': 'SubAgent completed without a result payload.',
'subagentRun.result.failedFallback': 'SubAgent failed without an error payload.',
'subagentRun.result.stoppedFallback': 'SubAgent stopped without a result payload.',
'subagentRun.result.noneFallback': 'No result available.',
// ─── 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.downloaded': 'Update downloaded. Restart when you are ready to use it.',
'update.idle': 'Check for updates to compare your installed version with the latest GitHub Release.',
'update.installAndRestart': 'Install and restart',
'update.installing': 'Installing update...',
'update.now': 'Update now',
'update.later': 'Later',
'update.progress': 'Downloading update... {progress}%',
'update.progressBytes': 'Downloading update... {downloaded} downloaded',
'update.proxyAdvanced': 'Advanced update proxy',
'update.proxyModeManual': 'Manual proxy',
'update.proxyModeManualDescription': 'Use a local HTTP proxy address you provide.',
'update.proxyModeSystem': 'System proxy',
'update.proxyModeSystemDescription': 'Use the OS HTTP/HTTPS proxy automatically.',
'update.proxySave': 'Save',
'update.proxyScopeHint': 'This only affects app update checks and downloads.',
'update.proxyUrl': 'Proxy URL',
'update.proxyUrlHint': 'HTTP and HTTPS proxy URLs are supported, for example http://127.0.0.1:7890.',
'update.proxyUrlInvalid': 'Enter an HTTP or HTTPS proxy URL.',
'update.proxyUrlRequired': 'Enter a proxy URL.',
'update.releaseNotes': 'Release Notes',
'update.readyBody': 'v{version} has been downloaded. Restart when you are ready to use it.',
'update.readyTitle': 'Update ready',
'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.historyLoadFailed': 'Failed to load session history.',
'session.workspaceUnavailable': 'Workspace unavailable: {dir}',
'session.timeJustNow': 'just now',
'session.timeMinutes': '{n}m ago',
'session.timeHours': '{n}h ago',
'session.timeDays': '{n}d ago',
'trace.open': 'Trace',
'trace.title': 'Model trace',
'trace.loadFailed': 'Failed to load trace',
'trace.apiCalls': 'API calls',
'trace.failedCalls': 'Failed',
'trace.duration': 'Duration',
'trace.elapsed': 'Elapsed',
'trace.completed': 'Completed',
'trace.wallTime': 'Wall time',
'trace.modelTime': 'Model time',
'trace.toolTime': 'Tool time',
'trace.models': 'Models',
'trace.request': 'Request',
'trace.response': 'Response',
'trace.status': 'Status',
'trace.live': 'Live',
'trace.updatedAt': 'Updated',
'trace.copySessionId': 'Copy session ID',
'trace.refresh': 'Refresh trace',
'trace.openWindow': 'Open in separate window',
'trace.delete': 'Delete trace',
'trace.noResponse': 'No response body captured',
'trace.emptyTitle': 'No trace calls yet',
'trace.emptyBody': 'This session has no captured model calls. New desktop sessions record compact request and response previews automatically.',
'trace.tokens': 'Tokens',
'trace.snapshotEmpty': 'Trace snapshot is empty.',
'trace.errors': 'Errors',
'trace.focus': 'Focus',
'trace.searchSpans': 'Search spans',
'trace.noMatchingSpans': 'No matching spans',
'trace.filter.all': 'All',
'trace.filter.llm': 'LLM',
'trace.filter.tools': 'Tools',
'trace.filter.errors': 'Errors',
'trace.sidechain': 'sub',
'trace.turnLabel': 'Turn {index}',
'trace.waitingForResult': 'Waiting for result',
'trace.started': 'Started',
'trace.provider': 'Provider',
'trace.model': 'Model',
'trace.childSpans': 'Child spans',
'trace.requestBody': 'Request body',
'trace.requestHeaders': 'Request headers',
'trace.responseBody': 'Response body',
'trace.responseHeaders': 'Response headers',
'trace.toolResult': 'Tool result',
'trace.truncatedShort': 'truncated',
'trace.noData': 'No data',
'trace.llmCalls': 'LLM calls',
'trace.toolCalls': 'Tool calls',
'trace.status.ok': 'ok',
'trace.status.error': 'error',
'trace.status.pending': 'pending',
'trace.message.user': 'User message',
'trace.message.assistant': 'Assistant message',
'trace.message.system': 'System message',
'trace.message.toolRequest': 'Assistant tool request',
'trace.message.toolResult': 'Tool result',
'trace.toolError': 'Tool error',
'trace.modelCall': 'Model call',
'trace.sessionActivity': 'Session activity',
'trace.diagnosis.modelError': 'Model call failed',
'trace.diagnosis.toolError': 'Tool execution failed',
'trace.diagnosis.eventError': 'Trace event failed',
'trace.diagnosis.pendingModel': 'Waiting for model response',
'trace.diagnosis.pendingTool': 'Waiting for tool result',
'trace.diagnosis.waitingForAgent': 'User message has not entered an agent step',
'trace.diagnosis.empty': 'No diagnostic events',
'trace.diagnosis.healthy': 'No blocking point detected',
'trace.event.apiCallStarted': 'API call started',
'trace.event.apiCallCompleted': 'API call completed',
'trace.event.apiCallFailed': 'API call failed',
'trace.event.apiCallAborted': 'API call aborted',
'trace.event.responseCaptureFailed': 'Response capture failed',
'trace.event.upstreamFetchStarted': 'Upstream fetch started',
'trace.event.upstreamFetchCompleted': 'Upstream fetch completed',
'trace.event.upstreamFetchFailed': 'Upstream fetch failed',
'trace.section.response': 'Response',
'trace.section.messages': 'Messages',
'trace.section.systemPrompt': 'System prompt',
'trace.section.tools': 'Tools',
'trace.section.parameters': 'Parameters',
'trace.section.raw': 'Raw',
'trace.section.input': 'Input',
'trace.section.result': 'Result',
'trace.section.meta': 'Meta',
'trace.section.content': 'Content',
'trace.section.event': 'Event',
'trace.section.metadata': 'Metadata',
'trace.detail.stopReason': 'Stop reason',
'trace.detail.streaming': 'Waiting for the model response...',
'trace.detail.aborted': 'The request was aborted before the response completed (timeout or cancellation).',
'trace.status.aborted': 'Aborted',
'trace.detail.legacyTruncated': 'Legacy truncated record; the semantic view is unavailable. See Raw below.',
'trace.detail.fetchFailed': 'Failed to load the full record; showing the truncated preview.',
'trace.detail.earlierMessages': 'Show {count} earlier messages',
'trace.detail.chars': '{count} chars',
'trace.detail.thinking': 'thinking',
'trace.detail.toolUseId': 'Tool use ID',
'trace.detail.phase': 'Phase',
'trace.detail.severity': 'Severity',
'trace.detail.message': 'Message',
'trace.tree.aria': 'Trace timeline',
'trace.tree.toggleTurn': 'Toggle turn',
'trace.list.eyebrow': 'Agent trace',
'trace.list.title': 'Trace list',
'trace.list.collecting': 'Collecting',
'trace.list.paused': 'Paused',
'trace.list.settings': 'Trace settings',
'trace.list.sessions': 'Sessions',
'trace.list.searchPlaceholder': 'Search title, session ID, or project path',
'trace.list.emptyTitle': 'No trace records yet',
'trace.list.emptyBody': 'When collection is enabled, new desktop sessions write model-call traces to the local traces directory.',
'trace.list.loadFailed': 'Failed to load trace list',
'trace.list.loadedCount': 'Showing {shown} of {total}',
'trace.list.loadMore': 'Load more',
'trace.list.deleteConfirmTitle': 'Delete trace session',
'trace.list.deleteConfirmBody': 'Delete trace data for "{title}"? Chat history is not deleted.',
'trace.list.deleteFailed': 'Failed to delete trace session',
// ─── 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.',
// ─── Business Errors ──────────────────────────────────────
'businessError.pdf_too_large': 'The PDF is too large for the selected model. Convert it to text or use a smaller PDF.',
'businessError.pdf_password_protected': 'The PDF is password protected. Unlock or convert it before sending it again.',
'businessError.pdf_invalid': 'The PDF file is not valid. Convert it to text or send a different file.',
'businessError.image_too_large': 'The image is too large for the selected model. Resize it or send a smaller image.',
'businessError.image_unsupported': 'This model does not support images. Continue with text, or switch to a vision-capable model and send the image again.',
'businessError.request_too_large': 'The request is too large for the selected model. Remove large files or retry with a smaller message.',
'businessError.prompt_too_long': 'The prompt is too long for the selected model. Compact the conversation or retry with less context.',
'businessError.auto_mode_unavailable': 'Auto mode is unavailable for your current plan.',
// ─── Server Status Verbs ──────────────────────────────────────
'serverVerb.Thinking': 'Thinking',
'serverVerb.Compacting conversation': 'Compacting context',
'serverVerb.Running': 'Running',
'serverVerb.Working': 'Working',
'serverVerb.Creating worktree': 'Creating worktree',
'serverVerb.Task started': 'Task started',
'serverVerb.Task in progress': 'Task in progress',
'chat.retry.title': 'Request failed, retrying',
'chat.retry.attempt': 'retry {attempt}/{max}',
'chat.retry.httpStatus': 'HTTP {status}',
'chat.retry.networkError': 'network error',
'chat.retry.waiting': 'waiting {seconds}s',
'chat.retry.retrying': 'retrying now…',
'chat.fallback.title': 'Network hiccup — switched to non-streaming mode',
'chat.fallback.detail': 'response arrives in one piece, this can take a while',
// ─── 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',
// ─── Slash Command Descriptions ──────────────────────────────────────
'slashCmd.agent.description': 'Run a prompt with a selected Agent',
'slashCmd.mcp.description': 'Open available MCP tools for the current chat context',
'slashCmd.skills.description': 'Browse user-invocable skills for the current chat context',
'slashCmd.help.description': 'Show available desktop and agent commands',
'slashCmd.status.description': 'Show session status, usage, and context',
'slashCmd.cost.description': 'Show session usage and costs',
'slashCmd.context.description': 'Show current context usage',
'slashCmd.plugin.description': 'Open desktop plugin controls in Settings',
'slashCmd.memory.description': 'Open project memory files in Settings',
'slashCmd.doctor.description': 'Open Doctor in Diagnostics',
'slashCmd.compact.description': 'Compact conversation context',
'slashCmd.clear.description': 'Clear conversation history',
'slashCmd.goal.description': 'Set a completion goal',
'slashCmd.review.description': 'Review code changes',
'slashCmd.commit.description': 'Create a git commit',
'slashCmd.pr.description': 'Create a pull request',
'slashCmd.init.description': 'Initialize project CLAUDE.md',
'slashCmd.bug.description': 'Report a bug',
'slashCmd.config.description': 'Open configuration',
'slashCmd.login.description': 'Switch Anthropic accounts',
'slashCmd.logout.description': 'Sign out of current account',
'slashCmd.model.description': 'Switch AI model',
'slashCmd.permissions.description': 'View or manage tool permissions',
'slashCmd.terminal-setup.description': 'Set up terminal integration',
'slashCmd.vim.description': 'Toggle vim editing mode',
'tabs.closeConfirmStop': 'Stop & Close',
'tabs.closeAllConfirmTitle': 'Sessions Running',
'tabs.closeAllConfirmMessage': '{count} sessions are still running. Stop them before closing these tabs?',
'tabs.closeAllConfirmStop': 'Stop All & Close',
'tabs.sessionRunning': 'Session running',
'tabs.openTerminal': 'Open Terminal',
'tabs.showWorkspace': 'Show Workspace',
'tabs.hideWorkspace': 'Hide Workspace',
'tabs.showBrowser': 'Show Browser',
'tabs.hideBrowser': 'Hide Browser',
// Skills Market
'sidebar.market': 'Skills Market',
'market.title': 'Skills Market',
'market.subtitle': 'Browse, preview and install skills from ClawHub and SkillHub.',
'market.searchPlaceholder': 'Search skills by name, keyword…',
'market.clearSearch': 'Clear search',
'market.resultCount': '{count} skills',
'market.loadMore': 'Load more',
'market.loadingMore': 'Loading more…',
'market.loading': 'Loading skills…',
'market.empty': 'No skills available',
'market.emptyHint': 'Both sources returned no results. Check the source status above.',
'market.emptySearch': 'No skills match your search',
'market.emptySearchHint': 'Try different keywords or clear the filters.',
'market.error.list': 'Failed to load the skills market',
'market.retry': 'Retry',
'market.filter.source': 'Source',
'market.filter.security': 'Security',
'market.filter.installed': 'Install status',
'market.source.all': 'All sources',
'market.source.clawhub': 'ClawHub',
'market.source.skillhub': 'SkillHub',
'market.security.all': 'All security states',
'market.security.verified': 'Verified',
'market.security.benign': 'Scanned safe',
'market.security.unknown': 'Not audited',
'market.security.flagged': 'Flagged',
'market.securityHint.verified': 'Published by a verified author and passed the sources security scan.',
'market.securityHint.benign': 'The sources security scan found no risks.',
'market.securityHint.unknown': 'No security audit data from the source — review the files before installing.',
'market.securityHint.flagged': 'The sources security scan flagged potential risks.',
'market.disclaimer.title': 'Use third-party skills with care.',
'market.disclaimer.body': 'Skills come from community sources and are not audited by this app. Review the files before installing — ideally have AI scan them for safety first.',
'market.disclaimer.dismiss': 'Dismiss disclaimer',
'market.installedFilter.all': 'All skills',
'market.installedFilter.installed': 'Installed',
'market.installedFilter.installable': 'Not installed',
'market.sourceStatus.ok': 'Online',
'market.sourceStatus.degraded': 'Degraded',
'market.sourceStatus.failed': 'Unavailable',
'market.sourceStatus.cached': 'Cached',
'market.sourceStatus.cachedAt': 'Cached {time}',
'market.card.by': 'by {author}',
'market.card.moreTags': '+{count}',
'market.install.state.installed': 'Installed',
'market.install.state.installable': 'Installable',
'market.install.state.notInstallable': 'Not installable',
'market.install.action': 'Install',
'market.install.installing': 'Installing…',
'market.uninstall.action': 'Uninstall',
'market.uninstall.uninstalling': 'Uninstalling…',
'market.uninstall.confirmTitle': 'Uninstall skill',
'market.uninstall.confirmMessage': 'Remove "{name}" from your local skills? The files under {path} will be deleted.',
'market.uninstall.success': '"{name}" was uninstalled.',
'market.reason.empty-file-list': 'This skill has no installable files (missing SKILL.md).',
'market.reason.file-too-large': 'This skill contains files that exceed the size limit.',
'market.reason.too-many-files': 'This skill contains too many files to install safely.',
'market.reason.invalid-name': 'The skill name cannot be used as a local directory name.',
'market.reason.name-conflict': 'A local skill with the same name already exists. Rename or remove it first.',
'market.reason.source-unavailable': 'The source of this skill is currently unavailable.',
'market.detail.back': 'Back to market',
'market.detail.overview': 'Overview',
'market.detail.files': 'Files',
'market.detail.author': 'Author',
'market.detail.version': 'Version',
'market.detail.updated': 'Updated',
'market.detail.category': 'Category',
'market.detail.license': 'License',
'market.detail.downloads': 'Downloads',
'market.detail.installs': 'Installs',
'market.detail.stars': 'Stars',
'market.detail.securityReport': 'Security reports',
'market.detail.viewReport': 'View report',
'market.detail.mirror': 'Also listed on {source}',
'market.detail.requiresApiKey': 'Requires API key',
'market.detail.loadError': 'Failed to load skill details',
'market.detail.noDescription': 'This skill provides no description.',
'market.file.empty': 'Select a file on the left to preview it.',
'market.file.truncated': 'Preview truncated — the file is larger than the preview limit.',
'market.file.loadError': 'Failed to load this file',
'market.file.noFiles': 'No files available for this skill.',
'market.installConfirm.title': 'Install skill',
'market.installConfirm.message': 'Install "{name}" from {source}?',
'market.installConfirm.location': 'Install location',
'market.installConfirm.effectNote': 'The skill becomes available in new sessions after installation.',
'market.installConfirm.riskBenign': 'Security scans found no risks in this skill.',
'market.installConfirm.riskVerified': 'This skill is from a verified publisher and passed security scans.',
'market.installConfirm.riskUnknown': 'This skill has not been security-audited. Review its files before installing.',
'market.installConfirm.riskFlagged': 'Security scans flagged this skill as potentially risky. Install only if you trust it.',
'market.installConfirm.confirm': 'Install',
'market.installConfirm.cancel': 'Cancel',
'market.installSuccess': '"{name}" installed. It becomes available in new sessions.',
'market.installError.network': 'Install failed: could not reach the skill source. Check your network and retry.',
'market.installError.checksum': 'Install aborted: a downloaded file failed integrity verification. Do not retry until the source is trustworthy.',
'market.installError.exists': 'Install failed: this skill is already installed or being installed.',
'market.installError.disk': 'Install failed: could not write to disk. Check permissions and free space.',
'market.installError.notInstallable': 'Install failed: this skill cannot be installed.',
'market.installError.generic': 'Install failed: {message}',
} as const
export type TranslationKey = keyof typeof en