Files
CodePilot/src/i18n/en.ts
T
7418andClaude Opus 4.6 16edf9f59c feat: CLI Tools — curated tool catalog, detection, install, chat awareness
New sidebar page for managing system CLI tools (ffmpeg, jq, ripgrep, yt-dlp, pandoc).

Core modules:
- cli-tools-catalog.ts: static catalog of 6 curated tools + EXTRA_WELL_KNOWN_BINS
- cli-tools-detect.ts: system detection via which/where + --version (2min cache)
- cli-tools-context.ts: builds <available_cli_tools> block for chat system prompt

API routes:
- GET /api/cli-tools/catalog, /installed, /[id]/status, /[id]/detail
- POST /api/cli-tools/[id]/install (SSE streaming), /[id]/describe (AI gen)

UI components:
- CliToolsManager: installed + recommended sections with grid layout
- CliToolCard: two variants (installed/recommended) with status badges
- CliToolDetailDialog: intro, use cases, guide steps, example prompts
- CliToolInstallDialog: SSE-based install progress with live terminal log

Chat integration:
- Chat input toolbar: Terminal icon opens CLI tool picker popover
- System prompt injection: buildCliToolsContext() in /api/chat
- MessageInput: CLI popover with search, keyboard nav, locale-aware prefill
- NavRail + ChatListPanel: frosted glass (bg-sidebar/80 backdrop-blur-xl)
- SlashCommandButton: Lightning icon, unified 16px toolbar icons
- input-group: shadow-md → shadow-sm
- Model selector: searchable popover with provider grouping

Docs:
- docs/handover/cli-tools.md + apps/site/content/docs/{en,zh}/cli-tools.mdx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 19:56:29 +08:00

907 lines
48 KiB
TypeScript

/**
* English translations — source of truth.
* Every key defined here becomes part of the `TranslationKey` type.
* Other locale files must implement `Record<TranslationKey, string>`.
*/
const en = {
// ── Navigation ──────────────────────────────────────────────
'nav.chats': 'Chats',
'nav.extensions': 'Extensions',
'nav.settings': 'Settings',
'nav.autoApproveOn': 'Auto-approve is ON',
'nav.lightMode': 'Light mode',
'nav.darkMode': 'Dark mode',
'nav.toggleTheme': 'Toggle theme',
'nav.bridge': 'Bridge',
'nav.cliTools': 'CLI Tools',
// ── Chat list panel ─────────────────────────────────────────
'chatList.justNow': 'just now',
'chatList.minutesAgo': '{n}m',
'chatList.hoursAgo': '{n}h',
'chatList.daysAgo': '{n}d',
'chatList.newConversation': 'New Conversation',
'chatList.delete': 'Delete',
'chatList.searchSessions': 'Search sessions...',
'chatList.noSessions': 'No sessions yet',
'chatList.importFromCli': 'Import from Claude Code',
'chatList.addProjectFolder': 'Add project folder',
'chatList.threads': 'Threads',
// ── Message list ────────────────────────────────────────────
'messageList.claudeChat': 'CodePilot Chat',
'messageList.emptyDescription': 'Start a conversation with CodePilot. Ask questions, get help with code, or explore ideas.',
'messageList.loadEarlier': 'Load earlier messages',
'messageList.loading': 'Loading...',
// ── Message input ───────────────────────────────────────────
'messageInput.attachFiles': 'Attach files',
'messageInput.helpDesc': 'Show available commands and tips',
'messageInput.clearDesc': 'Clear conversation history',
'messageInput.costDesc': 'Show token usage statistics',
'messageInput.compactDesc': 'Compress conversation context',
'messageInput.doctorDesc': 'Diagnose project health',
'messageInput.initDesc': 'Initialize CLAUDE.md for project',
'messageInput.reviewDesc': 'Review code quality',
'messageInput.terminalSetupDesc': 'Configure terminal settings',
'messageInput.memoryDesc': 'Edit project memory file',
'messageInput.modeCode': 'Code',
'messageInput.modePlan': 'Plan',
'messageInput.aiSuggested': 'AI Suggested',
// ── Streaming message ───────────────────────────────────────
'streaming.thinking': 'Thinking...',
'streaming.allowForSession': 'Allow for Session',
'streaming.allowed': 'Allowed',
'streaming.denied': 'Denied',
// ── Chat view / session page ────────────────────────────────
'chat.newConversation': 'New Conversation',
// ── Settings: General ───────────────────────────────────────
'settings.title': 'Settings',
'settings.description': 'Manage CodePilot and Claude CLI settings',
'settings.general': 'General',
'settings.providers': 'Providers',
'settings.claudeCli': 'Claude CLI',
'settings.codepilot': 'CodePilot',
'settings.version': 'Version {version}',
'settings.checkForUpdates': 'Check for Updates',
'settings.checking': 'Checking...',
'settings.updateAvailable': 'Update available: v{version}',
'settings.viewRelease': 'View Release',
'settings.latestVersion': "You're on the latest version.",
'settings.autoApproveTitle': 'Auto-approve All Actions',
'settings.autoApproveDesc': 'Skip all permission checks and auto-approve every tool action. This is dangerous and should only be used for trusted tasks.',
'settings.autoApproveWarning': 'All tool actions will be auto-approved without confirmation. Use with caution.',
'settings.autoApproveDialogTitle': 'Enable Auto-approve All Actions?',
'settings.autoApproveDialogDesc': 'This will bypass all permission checks. Claude will be able to execute any tool action without asking for your confirmation, including:',
'settings.autoApproveShellCommands': 'Running arbitrary shell commands',
'settings.autoApproveFileOps': 'Reading, writing, and deleting files',
'settings.autoApproveNetwork': 'Making network requests',
'settings.autoApproveTrustWarning': 'Only enable this if you fully trust the task at hand. This setting applies to all new chat sessions.',
'settings.cancel': 'Cancel',
'settings.enableAutoApprove': 'Enable Auto-approve',
'settings.language': 'Language',
'settings.languageDesc': 'Choose the display language for the interface',
'settings.usage': 'Usage',
// ── Settings: Appearance ──────────────────────────────────────
'settings.appearance': 'Appearance',
'settings.appearanceDesc': 'Customize the look and feel of CodePilot',
'settings.themeMode': 'Theme Mode',
'settings.themeModeDesc': 'Choose between light, dark, or system preference',
'settings.themeFamily': 'Color Theme',
'settings.themeFamilyDesc': 'Select a color palette for the interface',
'settings.modeLight': 'Light',
'settings.modeDark': 'Dark',
'settings.modeSystem': 'System',
// ── Settings: Usage Stats ───────────────────────────────────
'usage.totalTokens': 'Total Tokens',
'usage.totalCost': 'Total Cost',
'usage.sessions': 'Sessions',
'usage.cacheHitRate': 'Cache Hit Rate',
'usage.input': 'In',
'usage.output': 'Out',
'usage.cached': 'cached',
'usage.dailyChart': 'Daily Token Usage',
'usage.loading': 'Loading...',
'usage.loadError': 'Failed to load usage stats',
'usage.noData': 'No usage data yet',
'usage.noDataHint': 'Start a conversation to see statistics here.',
// ── Settings: CLI ───────────────────────────────────────────
'cli.permissions': 'Permissions',
'cli.permissionsDesc': 'Configure permission settings for Claude CLI',
'cli.envVars': 'Environment Variables',
'cli.envVarsDesc': 'Environment variables passed to Claude',
'cli.form': 'Form',
'cli.json': 'JSON',
'cli.save': 'Save',
'cli.format': 'Format',
'cli.reset': 'Reset',
'cli.settingsSaved': 'Settings saved successfully',
'cli.confirmSaveTitle': 'Confirm Save',
'cli.confirmSaveDesc': 'This will overwrite your current ~/.claude/settings.json file. Are you sure you want to continue?',
// ── Settings: Providers ─────────────────────────────────────
'provider.addProvider': 'Add Provider',
'provider.editProvider': 'Edit Provider',
'provider.deleteProvider': 'Delete Provider',
'provider.deleteConfirm': 'Are you sure you want to delete "{name}"? This action cannot be undone.',
'provider.deleting': 'Deleting...',
'provider.delete': 'Delete',
'provider.noProviders': 'No providers configured',
'provider.addToStart': 'Add a provider to get started',
'provider.quickPresets': 'Quick Presets',
'provider.customProviders': 'Custom Providers',
'provider.active': 'Active',
'provider.configured': 'Configured',
'provider.name': 'Name',
'provider.providerType': 'Provider Type',
'provider.apiKey': 'API Key',
'provider.authToken': 'Auth Token',
'provider.authStyle': 'Auth Style',
'provider.baseUrl': 'Base URL',
'provider.modelName': 'Model Name',
'provider.advancedOptions': 'Advanced Options',
'provider.extraEnvVars': 'Extra Environment Variables',
'provider.notes': 'Notes',
'provider.notesPlaceholder': 'Optional notes about this provider...',
'provider.saving': 'Saving...',
'provider.update': 'Update',
'provider.envDetected': 'Detected from environment',
'provider.default': 'Default',
'provider.setDefault': 'Set as Default',
'provider.environment': 'Environment',
'provider.connectedProviders': 'Connected Providers',
'provider.noConnected': 'No providers connected yet',
'provider.connect': 'Connect',
'provider.disconnect': 'Disconnect',
'provider.disconnecting': 'Disconnecting...',
'provider.disconnectProvider': 'Disconnect Provider',
'provider.disconnectConfirm': 'Are you sure you want to disconnect "{name}"? This action cannot be undone.',
'provider.ccSwitchHint': 'Claude Code configurations added via tools like cc switch may not be readable by CodePilot. We recommend re-adding your provider here.',
'provider.addProviderSection': 'Add Provider',
'provider.addProviderDesc': 'Select a provider to connect. Most presets only require an API key.',
// ── Right panel / Files ─────────────────────────────────────
'panel.files': 'Files',
'panel.tasks': 'Tasks',
'panel.openPanel': 'Open panel',
'panel.closePanel': 'Close panel',
// ── File tree ───────────────────────────────────────────────
'fileTree.filterFiles': 'Filter files...',
'fileTree.refresh': 'Refresh',
'fileTree.noFiles': 'No files found',
'fileTree.selectFolder': 'Select a project folder to view files',
// ── File preview ────────────────────────────────────────────
'filePreview.backToTree': 'Back to file tree',
'filePreview.lines': '{count} lines',
'filePreview.copyPath': 'Copy path',
'filePreview.failedToLoad': 'Failed to load file',
// ── Doc preview ─────────────────────────────────────────────
'docPreview.htmlPreview': 'HTML Preview',
// ── Extensions page ─────────────────────────────────────────
'extensions.title': 'Extensions',
'extensions.skills': 'Skills',
'extensions.mcpServers': 'MCP Servers',
// ── Skills ──────────────────────────────────────────────────
'skills.noSelected': 'No skill selected',
'skills.selectOrCreate': 'Select a skill from the list or create a new one',
'skills.newSkill': 'New Skill',
'skills.loadingSkills': 'Loading skills...',
'skills.noSkillsFound': 'No skills found',
'skills.searchSkills': 'Search skills...',
'skills.createSkill': 'Create Skill',
'skills.nameRequired': 'Name is required',
'skills.nameInvalid': 'Name can only contain letters, numbers, hyphens, and underscores',
'skills.skillName': 'Skill Name',
'skills.scope': 'Scope',
'skills.global': 'Global',
'skills.project': 'Project',
'skills.template': 'Template',
'skills.blank': 'Blank',
'skills.commitHelper': 'Commit Helper',
'skills.codeReviewer': 'Code Reviewer',
'skills.saved': 'Saved',
'skills.save': 'Save',
'skills.edit': 'Edit',
'skills.preview': 'Preview',
'skills.splitView': 'Split view',
'skills.deleteConfirm': 'Click again to confirm',
'skills.placeholder': 'Write your skill prompt in Markdown...',
'skills.mySkills': 'My Skills',
'skills.marketplace': 'Marketplace',
'skills.marketplaceSearch': 'Search Skills.sh...',
'skills.install': 'Install',
'skills.installed': 'Installed',
'skills.installing': 'Installing...',
'skills.uninstall': 'Uninstall',
'skills.installs': 'installs',
'skills.source': 'Source',
'skills.installedAt': 'Installed At',
'skills.installSuccess': 'Installation Complete',
'skills.installFailed': 'Installation Failed',
'skills.searchNoResults': 'No skills found',
'skills.marketplaceError': 'Failed to load marketplace',
'skills.marketplaceHint': 'Browse the Skills Marketplace',
'skills.marketplaceHintDesc': 'Search and install community skills from Skills.sh',
'skills.noReadme': 'No description available for this skill',
// ── MCP ─────────────────────────────────────────────────────
'mcp.addServer': 'Add Server',
'mcp.loadingServers': 'Loading MCP servers...',
'mcp.serverConfig': 'MCP Server Configuration',
'mcp.noServers': 'No MCP servers configured',
'mcp.noServersDesc': "Add an MCP server to extend Claude's capabilities",
'mcp.arguments': 'Arguments:',
'mcp.environment': 'Environment:',
'mcp.listTab': 'List',
'mcp.jsonTab': 'JSON Config',
'mcp.editServer': 'Edit Server',
'mcp.serverName': 'Server Name',
'mcp.serverType': 'Server Type',
'mcp.command': 'Command',
'mcp.argsLabel': 'Arguments (one per line)',
'mcp.url': 'URL',
'mcp.headers': 'Headers (JSON)',
'mcp.envVars': 'Environment Variables (JSON)',
'mcp.formTab': 'Form',
'mcp.jsonEditTab': 'JSON',
'mcp.saveChanges': 'Save Changes',
// ── Folder picker ───────────────────────────────────────────
'folderPicker.title': 'Select a project folder',
'folderPicker.loading': 'Loading...',
'folderPicker.noSubdirs': 'No subdirectories',
'folderPicker.cancel': 'Cancel',
'folderPicker.select': 'Select This Folder',
// ── Import session dialog ───────────────────────────────────
'import.title': 'Import Session from Claude CLI',
'import.searchSessions': 'Search sessions...',
'import.noSessions': 'No sessions found',
'import.import': 'Import',
'import.importing': 'Importing...',
'import.justNow': 'just now',
'import.minutesAgo': '{n}m ago',
'import.hoursAgo': '{n}h ago',
'import.daysAgo': '{n}d ago',
'import.messages': '{n} msg',
'import.messagesPlural': '{n} msgs',
// ── Connection status ───────────────────────────────────────
'connection.notInstalled': 'Claude Code is not installed',
'connection.installed': 'Claude Code is installed',
'connection.version': 'Version: {version}',
'connection.installPrompt': 'To use Claude Code features, you need to install the Claude Code CLI.',
'connection.runCommand': 'Run the following command in your terminal:',
'connection.installAuto': 'Install Claude Code Automatically',
'connection.refresh': 'Refresh',
'connection.installClaude': 'Install Claude Code',
'connection.connected': 'Connected',
'connection.disconnected': 'Disconnected',
'connection.checking': 'Checking',
// ── Install wizard ──────────────────────────────────────────
'install.title': 'Install Claude Code',
'install.checkingPrereqs': 'Checking prerequisites...',
'install.alreadyInstalled': 'Claude Code is already installed',
'install.readyToInstall': 'Ready to install',
'install.installing': 'Installing Claude Code...',
'install.complete': 'Installation complete',
'install.failed': 'Installation failed',
'install.copyLogs': 'Copy Logs',
'install.copied': 'Copied',
'install.install': 'Install',
'install.cancel': 'Cancel',
'install.retry': 'Retry',
'install.done': 'Done',
'install.recheck': 'Recheck',
'install.copy': 'Copy',
'install.homebrewRequired': 'Homebrew is required',
'install.homebrewDescription': 'Homebrew is the package manager for macOS. Node.js installation requires it.',
'install.homebrewSteps': 'Follow these steps:',
'install.homebrewStep1': 'Open Terminal',
'install.homebrewStep2': 'Paste the command above and press Enter',
'install.homebrewStep3': 'Follow the on-screen instructions to complete the installation',
'install.homebrewStep4': 'Come back here and click "Recheck"',
// ── Task list ───────────────────────────────────────────────
'tasks.all': 'All',
'tasks.active': 'Active',
'tasks.done': 'Done',
'tasks.addPlaceholder': 'Add a task...',
'tasks.addTask': 'Add task',
'tasks.loading': 'Loading tasks...',
'tasks.noTasks': 'No tasks yet',
'tasks.noMatching': 'No matching tasks',
// ── Tool call block ─────────────────────────────────────────
'tool.running': 'running',
'tool.success': 'success',
'tool.error': 'error',
// ── Common ──────────────────────────────────────────────────
'common.cancel': 'Cancel',
'common.save': 'Save',
'common.delete': 'Delete',
'common.loading': 'Loading...',
'common.close': 'Close',
'common.enabled': 'Enabled',
'common.disabled': 'Disabled',
// ── Error boundary ────────────────────────────────────────
'error.title': 'Something went wrong',
'error.description': 'An unexpected error occurred. You can try again or reload the app.',
'error.showDetails': 'Show details',
'error.hideDetails': 'Hide details',
'error.tryAgain': 'Try Again',
'error.reloadApp': 'Reload App',
// ── Update ─────────────────────────────────────────────────
'update.newVersionAvailable': 'New Version Available',
'update.downloading': 'Downloading',
'update.restartToUpdate': 'Restart to Update',
'update.restartNow': 'Restart Now',
'update.readyToInstall': 'CodePilot v{version} is ready — restart to update',
'update.installUpdate': 'Download & Install',
'update.later': 'Later',
// ── Image Generation ──────────────────────────────────────
'imageGen.toggle': 'Image Generation',
'imageGen.toggleLabel': 'Image Agent',
'imageGen.toggleTooltip': 'Toggle Image Agent — AI analyzes intent and generates single or batch images',
'imageGen.generating': 'Generating image...',
'imageGen.params': 'Generation Parameters',
'imageGen.aspectRatio': 'Aspect Ratio',
'imageGen.resolution': 'Resolution',
'imageGen.generate': 'Generate',
'imageGen.regenerate': 'Regenerate',
'imageGen.download': 'Download',
'imageGen.prompt': 'Prompt',
'imageGen.model': 'Model',
'imageGen.noApiKey': 'Please configure Gemini API Key in Settings > Providers',
'imageGen.error': 'Image generation failed',
'imageGen.success': 'Image generated successfully',
'imageGen.referenceImages': 'Reference Images',
'imageGen.uploadReference': 'Upload reference image',
'imageGen.resetChat': 'Reset conversation',
'imageGen.multiTurnHint': 'You can describe changes to modify the generated image',
'imageGen.settings': 'Generation Settings',
'imageGen.generated': 'Generated image',
'imageGen.confirmTitle': 'Image Generation',
'imageGen.editPrompt': 'Edit prompt',
'imageGen.generateButton': 'Generate',
'imageGen.retryButton': 'Retry',
'imageGen.generatingStatus': 'Generating...',
'imageGen.stopButton': 'Stop',
// ── Batch Image Generation ─────────────────────────────────
'batchImageGen.toggle': 'Batch Generate',
'batchImageGen.toggleTooltip': 'Toggle batch image generation mode',
'batchImageGen.entryTitle': 'Batch Image Generation',
'batchImageGen.stylePrompt': 'Style Prompt',
'batchImageGen.stylePromptPlaceholder': 'Describe the visual style for all images...',
'batchImageGen.uploadDocs': 'Upload Documents',
'batchImageGen.uploadDocsHint': 'Upload text/markdown files as source content',
'batchImageGen.count': 'Image Count',
'batchImageGen.countAuto': 'Auto',
'batchImageGen.aspectRatioStrategy': 'Aspect Ratio',
'batchImageGen.resolution': 'Resolution',
'batchImageGen.generatePlan': 'Generate Plan',
'batchImageGen.planning': 'Planning...',
'batchImageGen.planPreviewTitle': 'Generation Plan',
'batchImageGen.planSummary': 'Plan Summary',
'batchImageGen.editPrompt': 'Edit prompt',
'batchImageGen.addItem': 'Add Item',
'batchImageGen.removeItem': 'Remove',
'batchImageGen.regeneratePlan': 'Regenerate Plan',
'batchImageGen.confirmAndExecute': 'Confirm & Execute',
'batchImageGen.executing': 'Executing...',
'batchImageGen.totalProgress': 'Progress',
'batchImageGen.itemPending': 'Pending',
'batchImageGen.itemProcessing': 'Generating...',
'batchImageGen.itemCompleted': 'Done',
'batchImageGen.itemFailed': 'Failed',
'batchImageGen.retryFailed': 'Retry Failed',
'batchImageGen.retryItem': 'Retry',
'batchImageGen.pause': 'Pause',
'batchImageGen.resume': 'Resume',
'batchImageGen.cancel': 'Cancel',
'batchImageGen.syncToChat': 'Sync to Conversation',
'batchImageGen.syncComplete': 'Synced to conversation',
'batchImageGen.syncMode': 'Sync Mode',
'batchImageGen.syncManual': 'Manual',
'batchImageGen.syncAutoBatch': 'Auto Batch',
'batchImageGen.completed': 'Batch generation complete',
'batchImageGen.completedStats': '{completed}/{total} images generated',
'batchImageGen.noProvider': 'Please configure a text generation provider in Settings',
'batchImageGen.tags': 'Tags',
'batchImageGen.sourceRefs': 'Sources',
'batchImageGen.prompt': 'Prompt',
'batchImageGen.aspectRatio': 'Ratio',
'batchImageGen.imageSize': 'Size',
// ── Gallery ─────────────────────────────────────────────────
'gallery.title': 'Gallery',
'gallery.empty': 'No images generated yet',
'gallery.emptyHint': 'Generate images in chat to see them here.',
'gallery.filterByTag': 'Filter by tag',
'gallery.dateFrom': 'From',
'gallery.dateTo': 'To',
'gallery.sortNewest': 'Newest first',
'gallery.sortOldest': 'Oldest first',
'gallery.newestFirst': 'Newest first',
'gallery.oldestFirst': 'Oldest first',
'gallery.filters': 'Filters',
'gallery.clearFilters': 'Clear filters',
'gallery.loadMore': 'Load more',
'gallery.openChat': 'Open Chat',
'gallery.delete': 'Delete',
'gallery.confirmDelete': 'Confirm delete?',
'gallery.deleteConfirm': 'Delete this image? This cannot be undone.',
'gallery.tags': 'Tags',
'gallery.addTag': 'Add tag',
'gallery.newTag': 'New tag name',
'gallery.newTagPlaceholder': 'New tag name...',
'gallery.cancel': 'Cancel',
'gallery.removeTag': 'Remove tag',
'gallery.noTags': 'No tags',
'gallery.generatedAt': 'Generated at',
'gallery.viewDetails': 'View details',
'gallery.imageDetail': 'Image Detail',
'gallery.prompt': 'Prompt',
'gallery.download': 'Download',
'gallery.favorites': 'Favorites',
'gallery.favoritesOnly': 'Favorites',
'gallery.addToFavorites': 'Add to favorites',
'gallery.removeFromFavorites': 'Remove from favorites',
// ── Provider: Gemini Image ──────────────────────────────────
'provider.chatProviders': 'Chat Providers',
'provider.mediaProviders': 'Media Providers',
'provider.geminiImageDesc': 'Nano Banana Pro — AI image generation by Google Gemini',
// ── CLI dynamic field labels ──────────────────────────────
'cli.loadingSettings': 'Loading settings...',
'cli.field.skipDangerousModePermissionPrompt': 'Skip Dangerous Mode Permission Prompt',
'cli.field.verbose': 'Verbose',
'cli.field.theme': 'Theme',
'cli.formatError': 'Cannot format: invalid JSON',
// ── Split screen ─────────────────────────────────────────────
'split.splitScreen': 'Split Screen',
'split.closeSplit': 'Close Split',
'split.splitGroup': 'Split',
'chatList.splitScreen': 'Split Screen',
// ── Telegram (Bridge) ──────────────────────────────────────
'telegram.credentials': 'Bot Credentials',
'telegram.credentialsDesc': 'Enter your Telegram Bot token and chat ID',
'telegram.botToken': 'Bot Token',
'telegram.chatId': 'Chat ID',
'telegram.chatIdHint': 'Send /start to your bot first, then click "Auto Detect" to fill in your Chat ID',
'telegram.detectChatId': 'Auto Detect',
'telegram.chatIdDetected': 'Chat ID detected: {id} ({name})',
'telegram.chatIdDetectFailed': 'Could not detect Chat ID. Send /start to the bot first, then try again.',
'telegram.verify': 'Test Connection',
'telegram.verified': 'Connection verified',
'telegram.verifiedAs': 'Connected as @{name}',
'telegram.verifyFailed': 'Connection failed',
'telegram.enterTokenFirst': 'Enter a bot token first',
'telegram.setupGuide': 'Setup Guide',
'telegram.step1': 'Open Telegram and search for @BotFather',
'telegram.step2': 'Send /newbot and follow the prompts to create a bot',
'telegram.step3': 'Copy the bot token and paste it above',
'telegram.step4': 'Click "Test Connection" to verify the token is valid',
'telegram.step5': 'Send /start to your bot, then click "Auto Detect" next to the Chat ID field',
'telegram.step6': 'Click "Save" to store your credentials',
// ── Feishu (Bridge) ──────────────────────────────────────
'feishu.credentials': 'App Credentials',
'feishu.credentialsDesc': 'Enter your Feishu App ID and App Secret',
'feishu.appId': 'App ID',
'feishu.appSecret': 'App Secret',
'feishu.domain': 'Platform',
'feishu.domainFeishu': 'Feishu (feishu.cn)',
'feishu.domainLark': 'Lark (larksuite.com)',
'feishu.domainHint': 'Choose Feishu for China mainland or Lark for international',
'feishu.verify': 'Test Connection',
'feishu.verified': 'Connection verified',
'feishu.verifiedAs': 'Connected as {name}',
'feishu.verifyFailed': 'Connection failed',
'feishu.enterCredentialsFirst': 'Enter App ID and App Secret first',
'feishu.allowedUsers': 'Allowed Users',
'feishu.allowedUsersDesc': 'Comma-separated open_id or chat_id values allowed to use bridge',
'feishu.allowedUsersHint': 'Leave empty to allow all users',
'feishu.groupSettings': 'Group Chat Settings',
'feishu.groupSettingsDesc': 'Control how the bot responds in group chats',
'feishu.groupPolicy': 'Group Policy',
'feishu.groupPolicyOpen': 'Open — respond in all groups',
'feishu.groupPolicyAllowlist': 'Allowlist — only specified groups',
'feishu.groupPolicyDisabled': 'Disabled — ignore all group messages',
'feishu.groupAllowFrom': 'Allowed Groups',
'feishu.groupAllowFromHint': 'Comma-separated chat_id values of allowed groups',
'feishu.requireMention': 'Require @mention',
'feishu.requireMentionDesc': 'Only respond in groups when the bot is @mentioned',
'feishu.setupGuide': 'Setup Guide',
'feishu.step1': 'Go to Feishu Open Platform (open.feishu.cn) and create a custom app',
'feishu.step2': 'Enable the Bot capability in the app features',
'feishu.step3': 'Copy the App ID and App Secret from the Credentials page',
'feishu.step4': 'Add event subscription: im.message.receive_v1',
'feishu.step5': 'Publish the app version and approve it in the admin console',
'feishu.step6': 'Paste the credentials above and click "Test Connection" to verify',
// ── Settings: Remote Bridge ────────────────────────────────
'settings.bridge': 'Remote Bridge',
'bridge.title': 'Remote Bridge',
'bridge.description': 'Control Claude from external channels like Telegram or Feishu',
'bridge.enabled': 'Enable Remote Bridge',
'bridge.enabledDesc': 'Allow external messaging channels to interact with Claude',
'bridge.activeHint': 'Bridge is active. External channels can send tasks to Claude.',
'bridge.status': 'Bridge Status',
'bridge.statusConnected': 'Connected',
'bridge.statusDisconnected': 'Disconnected',
'bridge.statusStarting': 'Starting...',
'bridge.statusStopping': 'Stopping...',
'bridge.activeBindings': '{count} active binding(s)',
'bridge.noBindings': 'No active bindings',
'bridge.channels': 'Channels',
'bridge.channelsDesc': 'Enable or disable individual messaging channels',
'bridge.telegramChannel': 'Telegram',
'bridge.telegramChannelDesc': 'Receive and respond to messages via Telegram Bot',
'bridge.bindings': 'Active Sessions',
'bridge.bindingsDesc': 'Current session bindings from external channels',
'bridge.bindingChat': 'Chat',
'bridge.bindingChannel': 'Channel',
'bridge.bindingCreated': 'Created',
'bridge.bindingStatus': 'Status',
'bridge.noActiveBindings': 'No active session bindings',
'bridge.defaults': 'Defaults',
'bridge.defaultsDesc': 'Default settings for bridge-initiated sessions',
'bridge.defaultWorkDir': 'Working Directory',
'bridge.defaultWorkDirHint': 'Default project folder for bridge sessions',
'bridge.defaultModel': 'Model',
'bridge.defaultModelHint': 'Default model for bridge sessions',
'bridge.browse': 'Browse',
'bridge.start': 'Start Bridge',
'bridge.stop': 'Stop Bridge',
'bridge.starting': 'Starting...',
'bridge.stopping': 'Stopping...',
'bridge.autoStart': 'Auto-start Bridge',
'bridge.autoStartDesc': 'Automatically start the bridge when the application launches',
'bridge.adapterRunning': 'Running',
'bridge.adapterStopped': 'Stopped',
'bridge.adapterLastMessage': 'Last message',
'bridge.adapterLastError': 'Last error',
'bridge.adapters': 'Adapter Status',
'bridge.adaptersDesc': 'Real-time status of each channel adapter',
'bridge.telegramSettings': 'Telegram Settings',
'bridge.telegramSettingsDesc': 'Configure Telegram Bot credentials for bridge',
'bridge.allowedUsers': 'Allowed Users',
'bridge.allowedUsersDesc': 'Comma-separated Telegram user IDs allowed to use bridge',
'bridge.allowedUsersHint': 'Leave empty to allow only the Chat ID configured above',
'bridge.feishuChannel': 'Feishu',
'bridge.feishuChannelDesc': 'Receive and respond to messages via Feishu Bot',
'bridge.feishuSettings': 'Feishu Settings',
'bridge.feishuSettingsDesc': 'Configure Feishu App credentials for bridge',
'bridge.discordChannel': 'Discord',
'bridge.discordChannelDesc': 'Receive and respond to messages via Discord Bot',
'bridge.discordSettings': 'Discord Settings',
'bridge.discordSettingsDesc': 'Configure Discord Bot credentials for bridge',
'bridge.qqChannel': 'QQ',
'bridge.qqChannelDesc': 'Receive and respond to messages via QQ Bot (private chat)',
'bridge.qqSettings': 'QQ Settings',
'bridge.qqSettingsDesc': 'Configure QQ Bot credentials for bridge',
// ── Settings: Discord Bridge ─────────────────────────────────
'discord.credentials': 'Bot Credentials',
'discord.credentialsDesc': 'Enter your Discord Bot token',
'discord.botToken': 'Bot Token',
'discord.verify': 'Test Connection',
'discord.verified': 'Connection verified',
'discord.verifiedAs': 'Connected as {name}',
'discord.verifyFailed': 'Connection failed',
'discord.enterTokenFirst': 'Enter a bot token first',
'discord.allowedUsers': 'Authorization',
'discord.allowedUsersDesc': 'Control which users and channels can interact with the bot',
'discord.allowedUserIds': 'Allowed User IDs',
'discord.allowedUsersHint': 'Discord user IDs, comma-separated for multiple. Denies all when both users and channels are empty.',
'discord.allowedChannelIds': 'Allowed Channel IDs',
'discord.allowedChannelsHint': 'Discord channel IDs, comma-separated for multiple.',
'discord.guildSettings': 'Server & Group Settings',
'discord.guildSettingsDesc': 'Control how the bot responds in Discord servers',
'discord.allowedGuilds': 'Allowed Server (Guild) IDs',
'discord.allowedGuildsHint': 'Guild IDs, comma-separated for multiple. Leave empty to allow all servers.',
'discord.groupPolicy': 'Server Message Policy',
'discord.groupPolicyOpen': 'Open — respond in all server channels',
'discord.groupPolicyDisabled': 'Disabled — ignore all server messages (DM only)',
'discord.requireMention': 'Require @mention',
'discord.requireMentionDesc': 'Only respond in servers when the bot is @mentioned',
'discord.streamPreview': 'Stream Preview',
'discord.streamPreviewDesc': 'Show real-time response preview by editing messages',
'discord.setupGuide': 'Configuration Guide',
'discord.setupBotTitle': 'Create a Discord Bot',
'discord.step1': 'Go to Discord Developer Portal (discord.com/developers), click "New Application" to create an app',
'discord.step2': 'Navigate to "Bot" in the sidebar, click "Add Bot" to create the bot',
'discord.step3': 'Scroll down to "Privileged Gateway Intents", enable the "MESSAGE CONTENT INTENT" toggle',
'discord.step4': 'Click "Reset Token" to copy the Bot Token, paste it in the "Bot Credentials" section above and save',
'discord.step5': 'Go to "OAuth2 → URL Generator", check "bot" under Scopes, then check "Send Messages" and "Read Message History" under Bot Permissions',
'discord.step6': 'Copy the generated invite URL, open it in your browser to invite the Bot to your server',
'discord.step7': 'Click "Test Connection" above — if the bot name appears, setup is complete',
'discord.setupIdTitle': 'Getting IDs (Developer Mode required)',
'discord.stepDevMode': 'Open Discord → User Settings → Advanced → enable "Developer Mode"',
'discord.stepUserId': 'User ID: right-click your avatar or username → "Copy User ID"',
'discord.stepChannelId': 'Channel ID: right-click a channel name in the sidebar → "Copy Channel ID"',
'discord.stepGuildId': 'Server ID: right-click the server name at the top-left → "Copy Server ID"',
// ── Settings: QQ Bridge ────────────────────────────────────
'qq.credentials': 'Bot Credentials',
'qq.credentialsDesc': 'Enter your QQ Bot App ID and App Secret',
'qq.appId': 'App ID',
'qq.appSecret': 'App Secret',
'qq.verify': 'Test Connection',
'qq.verified': 'Connection verified',
'qq.verifyFailed': 'Connection failed',
'qq.enterCredentialsFirst': 'Enter App ID and App Secret first',
'qq.allowedUsers': 'Allowed Users',
'qq.allowedUsersDesc': 'Comma-separated user_openid values allowed to use bridge',
'qq.allowedUsersHint': 'Leave empty to allow all users',
'qq.imageSettings': 'Image Settings',
'qq.imageSettingsDesc': 'Control how the bot handles images from QQ',
'qq.imageEnabled': 'Enable Image Input',
'qq.imageEnabledDesc': 'Allow receiving and processing images from QQ',
'qq.maxImageSize': 'Max Image Size (MB)',
'qq.maxImageSizeHint': 'Maximum image file size in MB (default: 20)',
'qq.setupGuide': 'Setup Guide',
'qq.step1': 'Go to QQ Bot Quick Setup page (q.qq.com/qqbot/openclaw) to create a bot and generate App ID & App Secret',
'qq.step2': 'Paste the App ID and App Secret above and click "Save"',
'qq.step3': 'Click "Test Connection" to verify the credentials are valid',
'qq.step4': 'Go back to the Bridge page, enable the QQ channel toggle, and start the bridge',
'qq.step5': 'Add your QQ bot as a friend and send it a message to start chatting',
// ── Assistant Workspace ──────────────────────────────
'settings.assistant': 'Assistant',
'assistant.workspaceTitle': 'Assistant Workspace',
'assistant.workspaceDesc': 'Configure a directory for persistent AI personality and memory',
'assistant.workspacePath': 'Workspace Path',
'assistant.workspacePathHint': 'Select a directory (e.g. your Obsidian vault) to store assistant files',
'assistant.selectFolder': 'Select Folder',
'assistant.initialize': 'Initialize',
'assistant.initializing': 'Initializing...',
'assistant.initialized': 'Workspace initialized',
'assistant.pathNotSet': 'No workspace path configured',
'assistant.fileStatus': 'File Status',
'assistant.fileExists': 'exists',
'assistant.fileMissing': 'missing',
'assistant.fileChars': '{count} chars',
'assistant.onboardingTitle': 'Onboarding',
'assistant.onboardingDesc': 'Answer questions to personalize your assistant',
'assistant.onboardingComplete': 'Onboarding complete',
'assistant.onboardingNotStarted': 'Not started',
'assistant.startOnboarding': 'Start Onboarding',
'assistant.redoOnboarding': 'Redo Onboarding',
'assistant.onboardingQ1': 'How should I address you?',
'assistant.onboardingQ2': 'What name should I use for myself?',
'assistant.onboardingQ3': 'Do you prefer "concise and direct" or "detailed explanations"?',
'assistant.onboardingQ4': 'Do you prefer "minimal interruptions" or "proactive suggestions"?',
'assistant.onboardingQ5': 'What are your three hard boundaries?',
'assistant.onboardingQ6': 'What are your three most important current goals?',
'assistant.onboardingQ7': 'Do you prefer output as "lists", "reports", or "conversation summaries"?',
'assistant.onboardingQ8': 'What information may be written to long-term memory?',
'assistant.onboardingQ9': 'What information must never be written to long-term memory?',
'assistant.onboardingQ10': 'What three things should I do first when entering a project?',
'assistant.onboardingQ11': 'How do you organize your materials? (by project / time / topic / mixed)',
'assistant.onboardingQ12': 'Where should new information go by default?',
'assistant.onboardingQ13': 'How should completed tasks be archived?',
'assistant.checkInTitle': 'Daily Check-in',
'assistant.checkInDesc': 'Quick daily update to keep your assistant current',
'assistant.lastCheckIn': 'Last check-in',
'assistant.checkInToday': 'Completed today',
'assistant.checkInNeeded': 'Check-in available',
'assistant.startCheckIn': 'Start Check-in',
'assistant.checkInQ1': 'What did you work on or accomplish today?',
'assistant.checkInQ2': 'Any changes to your current priorities or goals?',
'assistant.checkInQ3': 'Anything you would like me to remember going forward?',
'assistant.refreshDocs': 'Refresh Directory Docs',
'assistant.refreshingDocs': 'Refreshing...',
'assistant.docsRefreshed': 'Directory docs refreshed',
// ── Taxonomy ──────────────────────────────────────────
'assistant.taxonomyTitle': 'Taxonomy',
'assistant.taxonomyDesc': 'Categories learned from your workspace structure',
'assistant.taxonomyEmpty': 'No categories detected',
'assistant.taxonomyRole': 'Role',
'assistant.taxonomyConfidence': 'Confidence',
'assistant.taxonomySource': 'Source',
'assistant.taxonomyPaths': 'Paths',
// ── Index ─────────────────────────────────────────────
'assistant.indexTitle': 'File Index',
'assistant.indexDesc': 'Indexed files for search and retrieval',
'assistant.indexFiles': '{count} files indexed',
'assistant.indexChunks': '{count} chunks',
'assistant.indexStale': '{count} stale',
'assistant.indexLastIndexed': 'Last indexed',
'assistant.indexReindex': 'Reindex',
'assistant.indexReindexing': 'Reindexing...',
// ── Hotset ────────────────────────────────────────────
'assistant.hotsetTitle': 'Hotset',
'assistant.hotsetDesc': 'Frequently accessed files loaded into context',
'assistant.hotsetEmpty': 'No frequent files yet',
'assistant.hotsetPinned': 'Pinned',
'assistant.hotsetFrequent': 'Frequent',
// ── Organize ──────────────────────────────────────────
'assistant.organizeTitle': 'Organization',
'assistant.organizeDesc': 'Archive and organize workspace content',
'assistant.organizeArchive': 'Archive Old Memories',
'assistant.organizeArchiving': 'Archiving...',
'assistant.organizeArchived': '{count} memories archived',
'assistant.organizeSuggest': 'Suggest Evolution',
'assistant.organizeSuggesting': 'Analyzing...',
// ── Assistant Workspace Switch Banner ─────────────────
'assistant.switchedBanner': 'Assistant directory has been switched to {path}. This session is no longer bound to assistant features.',
'assistant.openNewAssistant': 'Open New Assistant Project',
'assistant.sessionUnbound': 'Session unbound from assistant',
// ── Workspace Inspect & Confirmation ──────────────────
'assistant.inspecting': 'Checking...',
'assistant.inspectFailed': 'Failed to inspect path',
'assistant.pathNotExist': 'Path does not exist',
'assistant.pathNotDirectory': 'Path is not a directory',
'assistant.pathNotReadable': 'Directory is not readable',
'assistant.pathNotWritable': 'Directory is not writable',
'assistant.pathInvalid': 'Invalid path',
'assistant.confirmEmptyTitle': 'Initialize New Workspace',
'assistant.confirmEmptyDesc': 'This is an empty directory. Initialize it as a new assistant workspace?',
'assistant.confirmNormalTitle': 'Initialize Workspace Here',
'assistant.confirmNormalDesc': 'This directory already contains files. Initialize assistant workspace here?',
'assistant.confirmNormalHint': 'An .assistant folder, soul.md, memory.md and other assistant files will be created.',
'assistant.confirmInitialize': 'Initialize',
'assistant.confirmExistingTitle': 'Existing Workspace Detected',
'assistant.confirmExistingDesc': 'This directory already contains an assistant workspace. How would you like to proceed?',
'assistant.summaryOnboarding': 'Onboarding',
'assistant.summaryLastCheckIn': 'Last Check-in',
'assistant.summaryFileCount': 'Files',
'assistant.summaryNever': 'Never',
'assistant.takeoverContinue': 'Continue with existing config',
'assistant.takeoverReonboard': 'Re-onboard (keep files, reset onboarding)',
'assistant.confirmPartialTitle': 'Partial Workspace Detected',
'assistant.confirmPartialDesc': 'Partial assistant data was found in this directory. Repair and continue using it?',
'assistant.confirmRepair': 'Repair & Continue',
'assistant.confirmNotFoundTitle': 'Create New Directory',
'assistant.confirmNotFoundDesc': 'This path does not exist yet. Create the directory and initialize it as a new assistant workspace?',
'assistant.confirmCreate': 'Create & Initialize',
'assistant.workspaceInvalid': 'Configured workspace path is invalid',
// ── Composer ──────────────────────────────────────────────
'composer.slashCommand': 'Commands',
'composer.slashCommandTooltip': 'Insert slash command',
'composer.manageSkills': 'Manage skills',
'composer.searchModels': 'Search models...',
'composer.manageProviders': 'Manage providers',
'composer.designAgent': 'Design Agent',
'composer.designAgentTooltip': 'Enable AI design & image generation',
// ── Permission ────────────────────────────────────────────
'permission.default': 'Default',
'permission.fullAccess': 'Full Access',
'permission.fullAccessWarning': 'Full Access mode will automatically approve all permission requests without confirmation. This includes file writes, shell commands, and network requests. Only enable this if you fully trust the current task.',
'permission.sessionPermission': 'Chat Permission',
// ── Context Usage ─────────────────────────────────────────
'context.usage': 'Context Usage',
'context.model': 'Model',
'context.used': 'Used',
'context.total': 'Total',
'context.percentage': 'Usage',
'context.cacheRead': 'Cache Read',
'context.cacheCreation': 'Cache Creation',
'context.outputTokens': 'Output Tokens',
'context.estimate': 'Estimated from the most recent response',
'context.noData': 'No context usage data yet',
'context.unknown': 'Unknown',
// ── SDK Capabilities: Effort ──────────────────────────────
'messageInput.effort.label': 'Effort Level',
'messageInput.effort.low': 'Low',
'messageInput.effort.medium': 'Medium',
'messageInput.effort.high': 'High',
'messageInput.effort.max': 'Max',
// ── SDK Capabilities: Rewind ──────────────────────────────
'messageList.rewindToHere': 'Rewind to here',
'messageList.rewindConfirm': 'Confirm rewind',
'messageList.rewindCancel': 'Cancel',
'messageList.rewindDone': 'Files rewound successfully',
// ── SDK Capabilities: MCP Runtime ─────────────────────────
'mcp.runtimeStatus': 'Runtime Status',
'mcp.refresh': 'Refresh',
'mcp.noActiveSession': 'Start a conversation to see live status',
'mcp.noRuntimeStatus': 'No runtime status available',
'mcp.reconnect': 'Reconnect',
'mcp.enable': 'Enable',
// ── SDK Capabilities: Thinking ────────────────────────────
'settings.thinkingMode': 'Thinking Mode',
'settings.thinkingModeDesc': 'Control Claude\'s extended thinking behavior',
'settings.thinkingAdaptive': 'Adaptive',
'settings.thinkingEnabled': 'Enabled',
'settings.thinkingDisabled': 'Disabled',
// ── SDK Capabilities: Account ─────────────────────────────
'settings.accountInfo': 'Account Information',
'settings.email': 'Email',
'settings.organization': 'Organization',
'settings.subscription': 'Subscription',
// ── CLI Tools ─────────────────────────────────────────────
'cliTools.title': 'CLI Tools',
'cliTools.description': 'Manage CLI tools for AI-assisted workflows',
'cliTools.installed': 'Installed',
'cliTools.recommended': 'Recommended',
'cliTools.allInstalled': 'All recommended tools are installed!',
'cliTools.install': 'Install',
'cliTools.installing': 'Installing',
'cliTools.installSuccess': 'Installation Complete',
'cliTools.installFailed': 'Installation Failed',
'cliTools.detail': 'Details',
'cliTools.detailIntro': 'Introduction',
'cliTools.useCases': 'Use Cases',
'cliTools.guideSteps': 'Getting Started',
'cliTools.examplePrompts': 'Example Prompts',
'cliTools.copy': 'Copy',
'cliTools.homepage': 'Homepage',
'cliTools.docs': 'Documentation',
'cliTools.noDescription': 'No description yet — use AI Describe to generate',
'cliTools.toolInfo': 'Tool Info',
'cliTools.version': 'Version',
'cliTools.path': 'Path',
'cliTools.brewNotInstalled': 'Homebrew not detected',
'cliTools.brewInstallGuide': 'Most recommended tools require Homebrew. Run this command in your terminal to install it:',
'cliTools.viewDocs': 'View CodePilot documentation',
'cliTools.searchPlaceholder': 'Search CLI tools...',
'cliTools.noToolsDetected': 'No installed CLI tools detected',
'cliTools.goInstall': 'Go install CLI tools',
'cliTools.manageCli': 'Manage CLI tools',
'cliTools.selectTool': 'Select CLI tool',
'cliTools.autoDescribe': 'AI-enhance description',
'cliTools.autoDescribeFailed': 'AI description failed — check your provider settings',
'cliTools.batchDescribe': 'AI Describe',
'cliTools.batchDescribeIntro': 'Use AI to generate descriptions for installed tools. Results will be shown on each tool card.',
'cliTools.batchProvider': 'Provider',
'cliTools.batchModel': 'Model',
'cliTools.batchSkipExisting': 'Skip tools with existing descriptions ({count})',
'cliTools.batchToolCount': 'Will process {count} / {total} tools',
'cliTools.batchNoProvider': 'No compatible providers available. Coding Plan proxies (Kimi, GLM, MiniMax, etc.) are not supported — please configure an Anthropic API or OpenRouter provider.',
'cliTools.batchStart': 'Start',
'cliTools.batchSuccess': '{count} succeeded',
'cliTools.batchFailed': '{count} failed',
'cliTools.batchNothingToProcess': 'Nothing to process',
'cliTools.cancel': 'Cancel',
'cliTools.done': 'Done',
'cliTools.category.media': 'Media',
'cliTools.category.data': 'Data',
'cliTools.category.search': 'Search',
'cliTools.category.download': 'Download',
'cliTools.category.document': 'Document',
'cliTools.category.productivity': 'Productivity',
'cliTools.noInstallMethod': 'No automated install available for your platform',
'cliTools.systemDetected': 'System Detected',
} as const;
export type TranslationKey = keyof typeof en;
export default en;