{
  "common": {
    "save": "Save",
    "reset": "Reset",
    "cancel": "Cancel",
    "confirm": "Confirm",
    "delete": "Delete",
    "edit": "Edit",
    "create": "Create",
    "upload": "Upload",
    "download": "Download",
    "refresh": "Refresh",
    "retry": "Retry",
    "search": "Search",
    "enable": "Enable",
    "disable": "Disable",
    "enabled": "Enabled",
    "disabled": "Disabled",
    "preview": "Preview",
    "view": "View",
    "content": "Content",
    "loading": "Loading...",
    "copy": "Copy",
    "copied": "Copied to clipboard",
    "copyFailed": "Failed to copy to clipboard",
    "contentPlaceholder": "Enter content...",
    "help": "Help",
    "close": "Close",
    "back": "Back",
    "actions": "Actions",
    "total": "Total {{count}}",
    "clear": "Clear",
    "paste": "Paste",
    "yes": "Yes",
    "no": "No"
  },
  "desktop": {
    "closeWindow": {
      "title": "Close Window",
      "description": "What would you like to do when closing the window? Quitting the app stops all running tasks and scheduled jobs.",
      "remember": "Remember my choice",
      "showWindow": "Show Window",
      "minimizeToTray": "Minimize to Tray",
      "quitApp": "Quit App",
      "preference": "Close Window",
      "askEveryTime": "Ask every time"
    }
  },
  "chunkError": {
    "title": "Failed to load page",
    "subTitle": "This may be caused by a network issue or an application update.",
    "genericTitle": "Something went wrong",
    "genericSubTitle": "An unexpected error occurred while rendering this page.",
    "reload": "Reload"
  },
  "appCenter": {
    "backToList": "Back",
    "search": "Search apps...",
    "allCategories": "All",
    "noApps": "No apps installed yet",
    "noResults": "No apps match your search",
    "loadFailed": "Failed to load apps. Please retry.",
    "appNotLoaded": "This app is not loaded yet. Open it once from the sidebar, then retry.",
    "marketSectionTitle": "More from the app market",
    "uninstall": "Uninstall",
    "uninstallConfirmTitle": "Uninstall app?",
    "uninstallConfirmContent": "This will delete the app directory of \"{{name}}\". This cannot be undone.",
    "uninstallSuccess": "App uninstalled",
    "uninstallFailed": "Uninstall failed",
    "installSuccess": "Installed",
    "installFailed": "Install failed",
    "searchMarket": "Search app market...",
    "marketEmpty": "No apps found",
    "install": "Install",
    "details": "Details",
    "featured": "Featured",
    "featuredApps": "Featured Apps",
    "allApps": "All Apps",
    "refreshApp": "Refresh App",
    "appRefreshed": "App refreshed",
    "aboutApp": "About App",
    "exitApp": "Exit App",
    "moreOptions": "More Options",
    "backToListHint": "Back to app list (ESC)",
    "version": "Version",
    "id": "ID",
    "category": "Category",
    "description": "Description"
  },
  "nav": {
    "chat": "Chat",
    "control": "Control",
    "channels": "Channels",
    "sessions": "Sessions",
    "inbox": "Inbox",
    "apps": "Apps",
    "cronJobs": "Cron Jobs",
    "heartbeat": "Heartbeat",
    "agent": "Workspace",
    "workspace": "Files",
    "skills": "Skills",
    "skillPool": "Skill Pool",
    "market": "Skill Market",
    "tools": "Tools",
    "mcp": "MCP",
    "acp": "ACP",
    "agentConfig": "Configuration",
    "agents": "Agent Management",
    "settings": "Settings",
    "models": "Models",
    "environments": "Environments",
    "security": "Security",
    "tokenUsage": "Token Usage",
    "agentStats": "Agent Statistics",
    "voiceTranscription": "Voice Transcription",
    "debug": "Debug",
    "plugins": "Plugins",
    "backups": "Backups",
    "pluginManager": "Plugin Manager"
  },
  "sidebar": {
    "newVersion": "New version available: v{{version}}, click to upgrade",
    "updateModal": {
      "title": "New version available: v{{version}}",
      "viewReleases": "View Releases",
      "installDesktopUpdate": "Update Now",
      "desktopInstallHint": "QwenPaw Desktop {{version}} is ready to install. The app will restart after the update.",
      "checking": "Checking for updates…",
      "checkingHint": "Confirming the latest release",
      "downloading": "Downloading update",
      "downloadingTo": "Updating to version {{version}}",
      "downloadProgress": "{{done}} / {{total}} · {{rate}}",
      "installing": "Installing update",
      "willRestart": "The app will restart automatically when done.",
      "stepPrepare": "Prepare",
      "stepDownloading": "Download",
      "stepInstalling": "Install",
      "failedTitle": "Update failed",
      "back": "Back",
      "retry": "Retry",
      "errors": {
        "network": "Couldn't reach the update server. Check your internet and try again.",
        "signature": "Update file signature invalid. Try downloading again.",
        "appLocation": "QwenPaw is running from a read-only macOS location. Move QwenPaw.app to the Applications folder, launch it from there, then try updating again.",
        "other": "Update failed."
      },
      "updateLater": "Download in Background",
      "backgroundDownloading": "Downloading in background…",
      "readyToInstall": "Update ready",
      "readyToInstallHint": "v{{version}} update is downloaded. Restart to install and launch the new version.",
      "restartNow": "Update Now",
      "backgroundFailed": "Background download failed"
    },
    "settings": {
      "language": "Language",
      "theme": "Theme",
      "mode": "Mode"
    },
    "simpleMode": "Simple Mode",
    "fullMode": "Full Mode"
  },
  "debug": {
    "title": "Debug",
    "desc": "View the backend daemon log file to help diagnose issues. Logs refresh automatically while this page is open.",
    "level": {
      "all": "All"
    },
    "backend": {
      "title": "Backend logs",
      "autoRefresh": "Auto refresh",
      "newestFirst": "Newest first",
      "updatedAt": "Updated at",
      "path": "Log file",
      "notFound": "Backend log file was not found yet.",
      "placeholder": "Backend log output will appear here.",
      "loadFailed": "Failed to load backend logs",
      "searchPlaceholder": "Search backend logs..."
    },
    "actions": {
      "refreshBackend": "Refresh backend logs",
      "refreshSuccess": "Logs refreshed",
      "copyBackend": "Copy backend logs"
    }
  },
  "inbox": {
    "title": "Inbox",
    "tabApprovals": "Approvals",
    "tabPushMessages": "Push Messages",
    "tabHarvests": "AI Harvest",
    "summaryApprovals": "Approvals",
    "summaryPushUnread": "Unread Push",
    "summaryHarvests": "Harvests",
    "from": "From:",
    "skillAutoUpdateTitle": "Skill auto-sync",
    "skillPoolSender": "Skill Pool",
    "skillAutoUpdated": "Skill \"{{skill}}\" changed — auto-synced to: {{agents}}",
    "skillAutoUpdateFailed": "Skill \"{{skill}}\" auto-sync failed for: {{agents}}",
    "requestedBy": "By",
    "markRead": "Mark Read",
    "markAllRead": "Mark All Read",
    "markAllReadNoUnread": "No unread messages",
    "markAllReadSuccess": "Marked {{count}} messages as read",
    "selectAllCurrentPage": "Select current page",
    "selectedItems": "{{count}} selected",
    "batchDeleteButton": "Batch Delete",
    "batchOperation": "Batch",
    "exitBatch": "Exit Batch",
    "batchDeleteConfirm": "Delete {{count}} selected push messages?",
    "batchDeleteSuccess": "Deleted {{count}} push messages",
    "pushCronHeader": "Cron Job: {{name}}",
    "viewDetails": "View Details",
    "deleteMessageConfirm": "Delete this push message?",
    "viewAll": "View All",
    "read": "Read",
    "approve": "Approve",
    "reject": "Reject",
    "ready": "Ready",
    "harvestNow": "Harvest Now",
    "createHarvest": "Create Harvest",
    "createFirstHarvest": "Create Your First Harvest",
    "createSuccess": "Harvest created successfully",
    "emptyApprovals": "No pending approvals",
    "emptyPush": "No push messages",
    "emptyHarvests": "No harvests yet",
    "statusReadyToHarvest": "Ready to Harvest",
    "statusGrowing": "Growing",
    "harvestedTimes": "Harvested {{count}} times",
    "harvestSuccessRate": "Success Rate {{rate}}%",
    "messageDetailComingSoon": "Message detail view - Coming soon!",
    "harvestSettingsComingSoon": "Harvest settings - Coming soon!",
    "messageDetailTitle": "Execution Detail",
    "detailCronTitle": "Cron Job: {{name}}",
    "detailHeartbeatTitle": "Heartbeat",
    "messageNotFound": "Message not found",
    "detailTaskName": "Task Name",
    "detailTaskId": "Task ID",
    "detailStatus": "Status",
    "detailSeverity": "Severity",
    "detailAgent": "Agent",
    "detailSource": "Source",
    "detailSourceCronJob": "Cron Job",
    "detailSourceHeartbeat": "Heartbeat",
    "detailTrigger": "Trigger",
    "detailDuration": "Duration",
    "detailExecutedAt": "Executed At",
    "detailReceivedAt": "Received At",
    "detailRunId": "Run ID",
    "detailContent": "Output",
    "detailPayload": "Payload",
    "detailExecutionTrace": "Execution Trace",
    "detailTraceEmpty": "No execution trace available",
    "filterByAgent": "Filter by agent",
    "filterBySourceType": "Filter by source",
    "sourceTypeCron": "Cron",
    "sourceTypeHeartbeat": "Heartbeat",
    "sourceTypeMemory": "Memory"
  },
  "acp": {
    "title": "ACP",
    "loading": "Loading ACP configuration...",
    "builtin": "Built-in",
    "custom": "Custom",
    "create": "Add Custom Agent",
    "createTitle": "Create ACP Agent",
    "createSuccess": "ACP agent created",
    "editTitle": "Edit ACP Configuration",
    "agentKey": "Agent Key",
    "agentKeyRequired": "Please enter an agent key",
    "agentKeyInvalid": "Agent key can only contain letters, numbers, underscores, and hyphens",
    "agentKeyExists": "This agent key already exists",
    "enabled": "Enabled",
    "command": "Command",
    "commandRequired": "Please enter a command",
    "args": "Arguments",
    "argsHelp": "One argument per line",
    "env": "Environment Variables",
    "envHelp": "Use KEY=VALUE format on each line",
    "envInvalidLine": "Invalid environment variable format: {{line}}",
    "trusted": "Trusted",
    "toolParseMode": "Tool Parse Mode",
    "toolParseModeRequired": "Please select a tool parse mode",
    "stdioBufferLimit": "Stdio Buffer Limit",
    "stdioBufferLimitHelp": "Maximum stdio line buffer size in bytes for the ACP subprocess.",
    "stdioBufferLimitRequired": "Please enter a stdio buffer limit",
    "stdioBufferLimitMin": "Stdio buffer limit must be at least 1 byte",
    "docs": "Setup Docs",
    "docsHelp": "Open the ACP integration docs and jump to the \"How to configure external runners\" section",
    "notSet": "Not set",
    "configSaved": "ACP configuration saved",
    "configFailed": "Failed to save ACP configuration",
    "deleteTitle": "Delete {{name}}",
    "deleteConfirm": "Delete this ACP agent? This action cannot be undone.",
    "deleteSuccess": "ACP agent deleted",
    "deleteFailed": "Failed to delete ACP agent",
    "nodeSettings": "Node Settings",
    "nodePath": "Node path",
    "chooseOtherNode": "Choose another Node...",
    "selectNodePath": "Select Node path",
    "nodePathPrompt": "Enter the node executable path",
    "nodeSaved": "Node settings saved",
    "nodeLoadFailed": "Failed to load Node settings",
    "nodeSaveFailed": "Node path is unavailable",
    "nodeRuntime": {
      "bundled": "Bundled Node",
      "system": "System Node",
      "custom": "Custom Node"
    },
    "nodeRuntimeReason": {
      "systemNodeMissing": "System Node was not detected",
      "nodeMissing": "Node path does not exist",
      "npxMissing": "npx was not found",
      "versionCheckFailed": "Version check failed",
      "unavailable": "Unavailable"
    }
  },
  "voiceTranscription": {
    "title": "Voice Transcription",
    "description": "Configure how incoming audio and voice messages are handled.",
    "saveSuccess": "Audio mode saved",
    "saveFailed": "Failed to save audio mode",
    "audioModeLabel": "Audio Mode",
    "audioModeDescription": "Choose how voice messages from channels (Discord, Telegram, etc.) are processed before being sent to the model.",
    "modeAuto": "Auto (Recommended)",
    "modeAutoDesc": "Transcribe audio to text using the selected transcription provider, then send the text to the model. If transcription is unavailable or disabled, a file-uploaded placeholder is shown instead. Audio is never sent directly to the model in this mode. Works with all models.",
    "modeNative": "Native Audio",
    "modeNativeDesc": "Send the audio file directly to the model without transcription. This is the only mode that sends audio to the model. Only works with specific audio-capable models (e.g. gpt-4o-audio). Most models do not support this and will reject the message.",
    "ffmpegReady": "ffmpeg is installed. Audio conversion is available for native mode.",
    "ffmpegMissing": "ffmpeg is not installed.",
    "ffmpegMissingDesc": "Native audio mode requires ffmpeg to convert audio formats (e.g. .ogg to .wav). Install ffmpeg as a system package to enable this mode.",
    "providerTypeLabel": "Transcription Provider",
    "providerTypeDescription": "Choose the transcription backend. Select Disabled if you do not need voice transcription.",
    "providerTypeDisabled": "Disabled",
    "providerTypeDisabledDesc": "No transcription. Voice messages will show a file-uploaded placeholder.",
    "providerTypeWhisperApi": "Whisper API",
    "providerTypeWhisperApiDesc": "Use an OpenAI-compatible Whisper API endpoint from a configured provider (e.g. OpenAI, Ollama).",
    "providerTypeLocalWhisper": "Local Whisper",
    "providerTypeLocalWhisperDesc": "Run transcription locally using the openai-whisper Python library. Requires both ffmpeg and openai-whisper to be installed.",
    "localWhisperReady": "Local Whisper is ready. Both ffmpeg and openai-whisper are installed.",
    "localWhisperMissing": "Local Whisper is not ready. Missing dependencies must be installed.",
    "localWhisperMissingDesc": "ffmpeg: {{ffmpeg}} | openai-whisper: {{whisper}}. Install missing dependencies: ffmpeg (system package) and openai-whisper (uv pip install openai-whisper, or install QwenPaw with the [whisper] extra).",
    "providerLabel": "Whisper API Provider",
    "providerDescription": "Select which provider to use for audio transcription via the Whisper API. Only providers with a Whisper-compatible endpoint are shown.",
    "providerPlaceholder": "Select a provider...",
    "noProvidersWarning": "No transcription-capable providers found. Configure an OpenAI provider to enable voice transcription.",
    "transcriptionInfoTitle": "How transcription works",
    "transcriptionInfoDesc": "Whisper API transcription uses an OpenAI-compatible /v1/audio/transcriptions endpoint. This requires a configured provider with a Whisper-compatible endpoint — for example, an OpenAI provider. Select a specific provider above to enable transcription.",
    "transcriptionInfoDescLocal": "Local Whisper transcription runs the openai-whisper library directly on your machine. It requires both ffmpeg (for audio decoding) and the openai-whisper Python package to be installed. No API key or network connection is needed. Install with: uv pip install 'qwenpaw[whisper]'."
  },
  "backup": {
    "title": "Backups",
    "description": "Backup and restore agent workspaces and configurations.",
    "create": "Create Backup",
    "import": "Import",
    "export": "Export",
    "restore": "Restore",
    "delete": "Delete",
    "batchDelete": "Delete Selected",
    "batchDeleteConfirm": "Are you sure you want to delete {{count}} backup(s)? This action cannot be undone.",
    "deleteConfirm": "Are you sure you want to delete this backup? This action cannot be undone.",
    "name": "Name",
    "createdAt": "Created",
    "scopeSummary": "Scope",
    "descriptionLabel": "Description",
    "noBackups": "No backups yet. Create one to backup your current configuration.",
    "loadFailed": "Failed to load backups",
    "createTitle": "Create Backup",
    "backupMode": "Backup Mode",
    "fullBackup": "Full Backup",
    "fullBackupDesc": "Backup everything including all agent workspaces, global settings, skill pool, and secrets",
    "customBackup": "Custom Backup",
    "partialBackup": "Partial Backup",
    "partialBackupDesc": "Customize what to backup",
    "nameRequired": "Backup name is required",
    "namePlaceholder": "Enter backup name",
    "descriptionPlaceholder": "Optional description...",
    "scopeAgents": "Agent Workspaces",
    "scopeGlobalConfig": "Global Settings",
    "scopeSkillPool": "Skill Pool",
    "scopeSecrets": "Secrets",
    "scopeSecretsHint": "Includes model provider secrets (API keys), environment variables, and other sensitive information",
    "securityNotice": "This backup may contain sensitive credentials. Agent workspaces include channel credentials (bot tokens, app secrets, etc.), and model provider secrets include API keys. Do not share backup files with others.",
    "searchPlaceholder": "Search backups by name or ID...",
    "total": "Total {{count}}",
    "agentsPlaceholder": "Select agent workspaces (leave empty for all)",
    "selectAll": "Select All",
    "deselectAll": "Deselect All",
    "createSuccess": "Backup created successfully",
    "createFailed": "Failed to create backup",
    "restoreTitle": "Restore Backup",
    "restoreScope": "Restore Scope",
    "restoreFullWarning": "Full restore will completely replace all contents of the current instance (including all agents, global config, skill pool, and secrets). This action cannot be undone. Related features will be unavailable during restore. Please restart the service after restoration is complete.",
    "agentGroupExisting": "Existing",
    "agentGroupNew": "New",
    "agentExists": "Exists",
    "agentNew": "New",
    "agentActionReplace": "Overwrite",
    "agentActionAdd": "New",
    "agentColumnName": "Agent",
    "agentColumnWorkspace": "Workspace",
    "agentTotal": "{{count}} agents total",
    "noAgentsInBackup": "No agent workspaces in this backup",
    "loadingAgents": "Loading agent list...",
    "agentSearchPlaceholder": "Search by name or ID...",
    "agentSearchTotal": "{{count}} of {{total}} agents",
    "restoreCustomSummary": "{{existing}} existing · {{added}} new selected",
    "defaultWorkspaceDirUnused": "No new agents selected",
    "otherOptions": "Other Options",
    "defaultWorkspaceDirDefault": "<Default path>/{{aid}}",
    "restoreWarningModify": "Restoring will modify current configurations. This action cannot be undone.",
    "restoreWarningRestart": "Related features will be unavailable during restore. Please restart the service after restoration is complete.",
    "preRestoreBackupTitle": "Create Pre-Restore Backup",
    "preRestoreBackupContent": "The restore operation is irreversible. Would you like to create a backup of the current state first? This allows you to rollback if any issues occur during restoration.",
    "preRestoreBackupYes": "Yes, create backup first",
    "preRestoreBackupNo": "No, restore directly",
    "preRestoreBackupDesc": "Auto-created backup before restore",
    "preRestoreBackupFailed": "Failed to create pre-restore backup",
    "preRestoreBackupSuccess": "Pre-restore backup created successfully, ID: {{id}}",
    "creatingPreRestoreBackup": "Creating pre-restore backup...",
    "skipAndRestore": "Skip and continue to restore",
    "restoreConfirm": "I confirm that I want to restore this backup",
    "restoreMode": "Restore Mode",
    "restoreModeFull": "Full Restore",
    "restoreModeFullDesc": "Completely replace all contents of the current instance, including all agents, global config, skill pool and secrets",
    "restoreModeCustom": "Custom Restore",
    "restoreModeCustomDesc": "Select the contents to restore, such as specific agents, config, etc.; existing agents not included in this restore will be preserved",
    "restoreModeFullDisabled": "Full backup only",
    "defaultWorkspaceDir": "Agent Default Workspace Directory",
    "defaultWorkspaceDirPlaceholder": "Leave empty to use ~/.qwenpaw/workspaces",
    "defaultWorkspaceDirHint": "If the agent's original workspace path does not exist, the agent will be saved under <default path>/<agent ID>. If it exists, the agent's original workspace path will be used.",
    "restoreStrategy": "Restore strategy",
    "restoreStrategyPreserve": "Preserve local security and MCP",
    "restoreStrategyPreserveDesc": "Keep this instance's security guards and MCP configuration.",
    "restoreStrategyRestore": "Restore these settings from backup",
    "restoreStrategyRestoreDesc": "Use the backup's security and MCP configuration.",
    "restoreSuccess": "Backup restored successfully. Please restart the service.",
    "restoreSuccessPreserved": "Backup restored successfully. Preserved local settings: {{keys}}. Please restart the service.",
    "restoreSuccessWithBackup": "Backup restored successfully. Pre-restore backup ID: {{preRestoreId}}. Please restart the service.",
    "restoreFailed": "Failed to restore backup",
    "restoreTargetBusy": "Restore failed because these directories are still in use. Close the browser or process using them, then retry. If they remain locked, restart the system and try again.",
    "detailLoadFailed": "Failed to load backup details; restore is unavailable",
    "trustLocalBanner": "Local backup - full restore by default",
    "trustForeignBanner": "Imported backup - local security and MCP are preserved by default",
    "trustLegacyBanner": "Legacy backup - trust confirmation is required before restore",
    "trustForeignTitle": "Trust this backup?",
    "trustLegacyTitle": "Trust legacy backup?",
    "unknownBackupName": "Backup archive",
    "trustForeignDesc": "This backup was not signed by this instance. Only continue if you trust the source; local security and MCP settings will be preserved by default when restored.",
    "trustLegacyDesc": "This older backup has no local signature. Only continue if you trust where it came from; this instance will sign it before restore.",
    "deleteSuccess": "Backup(s) deleted successfully",
    "deleteFailed": "Failed to delete backup(s)",
    "exportFailed": "Failed to export backup",
    "exportWarningTitle": "Sensitive Information Warning",
    "exportWarningContent": "This backup may contain sensitive credential information. Agent workspaces contain channel credentials (such as bot tokens, app secrets, etc.), and model provider secrets contain API Keys. Do not share backup files with others.",
    "exportConfirm": "Confirm Export",
    "importTitle": "Import Backup",
    "importSuccess": "Backup imported successfully",
    "importFailed": "Failed to import backup",
    "importConflictTitle": "Backup Already Exists",
    "importConflictDesc": "A backup with the same ID already exists. Do you want to overwrite it?",
    "importReplace": "Overwrite",
    "agents": "{{count}} Agent(s)",
    "allAgents": "All Agents",
    "globalConfig": "Global Settings",
    "skillPool": "Skill Pool",
    "secrets": "Secrets",
    "selected": "{{count}} selected",
    "fileCount": "{{count}} files",
    "totalSize": "{{size}}",
    "progressStarting": "Starting backup...",
    "progressAgent": "Backing up agent {{index}} / {{total}}...",
    "progressSaving": "Saving backup file...",
    "progressDone": "Backup complete",
    "localModelsNotice": "Backup files do not include local model files. For cross-device migration, you will need to re-download the required local models on the target device."
  },
  "workspace": {
    "title": "Files",
    "workspacePath": "Workspace:",
    "noFiles": "No files",
    "coreFiles": "Core Files",
    "coreFilesDesc": "Bootstrap persona, identity, and tool guidance.",
    "uploadTooltip": "ZIP files only",
    "uploadTooltipWithLimit": "ZIP files only, max {{limit}}MB",
    "selectFile": "Select a file to edit",
    "fileContent": "File content...",
    "uploadSuccess": "File uploaded successfully",
    "uploadFailed": "File upload failed",
    "downloadPreparing": "Preparing workspace download...",
    "downloadSuccess": "Workspace downloaded successfully",
    "downloadFailed": "Workspace download failed",
    "zipOnly": "Only .zip files are supported for upload",
    "fileSizeExceeded": "File size exceeds {{limit}}MB limit. Current file: {{size}}MB",
    "systemPromptToggleTooltip": "Enable/disable this file in system prompt",
    "memoryFileWarning": "MEMORY.md is typically queried on-demand by the agent using tools. Loading it into the system prompt may cause the context to become too long.",
    "configUpdated": "System prompt configuration updated",
    "configUpdateFailed": "Failed to update system prompt configuration",
    "attribution": "Workspace design partly inspired by the OpenClaw project — thank you! 🐾",
    "saveSuccess": "Saved successfully",
    "saveFailed": "Save failed",
    "saving": "Saving...",
    "saved": "Saved",
    "unsaved": "Unsaved"
  },
  "agent": {
    "parent": "Settings",
    "agents": "Agents",
    "management": "Agent Management",
    "pageDescription": "Create, configure, and manage multiple AI agents with custom workspaces and identities.",
    "name": "Name",
    "id": "ID",
    "description": "Description",
    "workspace": "Workspace Path",
    "create": "Create Agent",
    "createTitle": "Create New Agent",
    "createSuccess": "Agent created successfully",
    "createFailed": "Failed to create agent",
    "edit": "Edit",
    "editTitle": "Edit Agent - {{name}}",
    "updateSuccess": "Agent updated successfully",
    "updateFailed": "Failed to update agent",
    "delete": "Delete",
    "deleteConfirm": "Confirm Delete Agent",
    "deleteConfirmDesc": "Agent will be unavailable after deletion, but workspace files will be kept",
    "deleteSuccess": "Agent deleted successfully",
    "deleteFailed": "Failed to delete agent",
    "selectAgent": "Select Agent",
    "defaultDisplayName": "Default Agent",
    "currentWorkspace": "Current Agent",
    "switchSuccess": "Agent switched successfully",
    "switchFailed": "Failed to switch agent",
    "loadFailed": "Failed to load agent list",
    "loadConfigFailed": "Failed to load agent config",
    "saveFailed": "Failed to save agent",
    "idRequired": "Please enter agent ID",
    "idLabel": "Agent ID (optional)",
    "idHelp": "Leave empty to auto-generate. Only letters, digits, hyphens and underscores allowed.",
    "idPattern": "ID can only contain letters, numbers, underscores and hyphens",
    "idPlaceholder": "e.g.: my-agent",
    "nameRequired": "Please enter agent name",
    "namePlaceholder": "e.g.: My Agent",
    "descriptionPlaceholder": "Briefly describe this agent's purpose...",
    "workspaceHelp": "Leave empty to auto-generate in ~/.qwenpaw/workspaces/<id>",
    "dragHandleTooltip": "Drag to reorder agents",
    "reorderSuccess": "Agent order saved",
    "reorderFailed": "Failed to save agent order",
    "defaultNotEditable": "Default agent cannot be edited",
    "defaultNotDeletable": "Default agent cannot be deleted",
    "disable": "Disable",
    "enable": "Enable",
    "disabled": "Disabled",
    "disableConfirm": "Confirm Disable Agent",
    "disableConfirmDesc": "The agent instance will not start after disabling, but will remain visible in the list",
    "enableConfirm": "Confirm Enable Agent",
    "enableConfirmDesc": "The agent will be available for switching after enabling",
    "disableSuccess": "Agent disabled successfully",
    "enableSuccess": "Agent enabled successfully",
    "toggleFailed": "Failed to toggle agent state",
    "enableAgent": "Enable {{name}}",
    "disableAgent": "Disable {{name}}",
    "disabledAgents": "Disabled ({{count}})",
    "pinnedAgents": "Pinned",
    "otherAgents": "Other agents",
    "pinned": "Pinned",
    "defaultPinned": "The default agent is always pinned",
    "longPressToPin": "Press and hold to pin",
    "longPressToUnpin": "Press and hold to unpin",
    "pinAgent": "Pin agent",
    "unpinAgent": "Unpin agent",
    "pinSuccess": "Agent pinned",
    "unpinSuccess": "Agent unpinned",
    "pinFailed": "Failed to update pinned state",
    "status": {
      "disabled": "Disabled",
      "pending": "Waiting to start",
      "starting": "Starting",
      "running": "Running",
      "failed": "Startup failed",
      "waitUntilStarted": "Available after startup completes"
    },
    "defaultNotDisablable": "Default agent cannot be disabled",
    "currentAgentDeleted": "Current agent has been deleted, automatically switched to default agent",
    "currentAgentDisabled": "Current agent has been disabled, automatically switched to default agent",
    "switchedToDefault": "Automatically switched to default agent",
    "cannotSwitchToDisabled": "This agent is disabled, please enable it in the management page first",
    "initialSkills": "Initial Skills",
    "initialSkillsHelp": "Select skills to add from the pool. You can add or remove skills later.",
    "selectAll": "All",
    "selectBuiltin": "Builtin",
    "selectNone": "None",
    "noPoolSkills": "No skills available in pool",
    "addSkillsToAgent": "Add Skills",
    "model": "Model",
    "modelHelp": "Assign a specific LLM model to this agent. Leave empty to use the global default.",
    "modelPlaceholder": "Use global default",
    "noConfiguredModels": "No configured models",
    "modelColumn": "Model",
    "copyTooltip": "Copy agent configuration",
    "copyDefaultTooltip": "Copy using the default agent as a template",
    "copyTitle": "Copy Agent Configuration",
    "copyNameLabel": "New agent name",
    "copyOptionsLabel": "Copy content",
    "copyOptionAgentJson": "agent.json (required)",
    "copyOptionAgentJsonHint": "Always copies the parsed source config and resets ID, name, workspace, and channels. This is not a byte-for-byte copy of the on-disk agent.json.",
    "copyOptionMdFiles": "AGENTS / SOUL / PROFILE / HEARTBEAT / BOOTSTRAP.md",
    "copyOptionSkills": "skills/ + manifest",
    "copyOptionJobs": "jobs.json",
    "copyOptionJobsHint": "Copies job definitions only, not run history. The new agent will start running them on schedule after creation.",
    "copySuccess": "Agent configuration copied successfully",
    "copyFailed": "Failed to copy agent configuration"
  },
  "skills": {
    "title": "Skills",
    "description": "Manage agent skills and capabilities.",
    "importHub": "Upload via URL",
    "supportedSources": "Supported sources:",
    "importSkills": "Import Skill",
    "enterSkillUrl": "Enter Skill URL",
    "supportedSkillUrlSources": "Supported Skill Marketplaces:",
    "urlExamples": "URL examples:",
    "urlValid": "Valid URL from {{source}}",
    "invalidUrl": "Invalid URL",
    "clickToFill": "Click to fill in URL",
    "invalidSkillUrlSource": "Please verify the skill URL is from a supported marketplace",
    "type": "Type",
    "installedFrom": "Installed from",
    "source": "Source",
    "path": "Path",
    "tags": "Tags",
    "builtin": "Built-in",
    "custom": "Custom",
    "addSkill": "Add Skill",
    "createSkill": "Create Skill",
    "viewSkill": "View Skill",
    "editSkill": "Edit Skill",
    "skillName": "Skill Name",
    "skillContent": "Skill Content",
    "pleaseInputName": "Please input skill name",
    "pleaseInputContent": "Please input skill content",
    "skillNamePlaceholder": "e.g., weather_query",
    "contentPlaceholder": "[Format]\n---\nname: skill_name (required, lowercase with underscores)\ndescription: Brief description (required)\n---\n\nSkill implementation (Markdown format)\n\n[Example]\n---\nname: weather_query\ndescription: Query weather info for a city\n---\n\n## Features\nQuery real-time weather data.\n\n## Usage\nUser inputs city name, returns weather info.",
    "createSuccess": "Skill created successfully",
    "createFailed": "Failed to create skill",
    "deleteConfirm": "Are you sure you want to delete this skill?",
    "deleteSuccess": "Skill deleted successfully",
    "deleteFailed": "Failed to delete skill",
    "batchEnable": "Enable",
    "batchDisable": "Disable",
    "batchEnableSuccess": "{{count}} skills enabled",
    "batchEnablePartial": "{{enabled}} enabled, {{failed}} failed",
    "batchEnableFailed": "Batch enable failed",
    "batchDisableSuccess": "{{count}} skills disabled",
    "batchDisablePartial": "{{disabled}} disabled, {{failed}} failed",
    "batchDisableFailed": "Batch disable failed",
    "batchDeleteTitle": "Delete {{count}} skills?",
    "batchDeleteSuccess": "{{count}} skills deleted",
    "batchDeletePartial": "{{deleted}} deleted, {{failed}} failed",
    "batchDeleteFailed": "Batch delete failed",
    "selectedCount": "{{count}} selected",
    "updateSuccess": "Skill updated successfully",
    "updateFailed": "Failed to update skill",
    "frontmatterRequired": "Skills must start and end with ---",
    "frontmatterNameRequired": "Skills missing required field : name",
    "frontmatterDescriptionRequired": "Skills missing required field : description",
    "editNotSupported": "Failed to edit skill",
    "editNote": "Tip: You can edit skill content, channels, and config here.",
    "create": "Create",
    "optimizeWithAI": "AI Optimize",
    "stopOptimize": "Stop",
    "optimizeSuccess": "Skill optimized successfully",
    "optimizeFailed": "Failed to optimize skill",
    "noContentToOptimize": "No content to optimize",
    "cancelImport": "Cancel Import",
    "importCancelled": "Skill import cancelled",
    "importTimeout": "Skill import timed out. Please retry or check your network.",
    "uploadSkill": "Upload Skill",
    "uploadZip": "Upload via Zip",
    "uploadSuccess": "Skill uploaded successfully",
    "uploadFailed": "Skill upload failed",
    "uploadNoChange": "No new skills were imported. They may already exist.",
    "zipOnly": "Only .zip files are supported for upload",
    "fileSizeExceeded": "File size exceeds {{limit}}MB limit. Current file: {{size}}MB",
    "channels": "Channels",
    "allChannels": "All",
    "lastUpdated": "Updated",
    "searchPlaceholder": "Filter by name",
    "listView": "List view",
    "gridView": "Grid view",
    "refreshHint": "Refresh skills from disk",
    "poolSync": "Sync Status",
    "uploadedToPool": "Uploaded to skill pool",
    "downloadedToWorkspace": "Downloaded to current workspace",
    "builtinUpgradeTitle": "Upgrade Built-in Skill",
    "builtinUpgradeContent": "A newer version of built-in skill \"{{name}}\" is available in the pool. Overwrite the current version?",
    "languageSwitchTitle": "Switch Skill Language",
    "languageSwitchContent": "The following skills have a different language version in the pool and will be overwritten:",
    "overwriteExistingList": "The following skills already exist and will be overwritten:",
    "nameConflict": "Name conflict detected. Suggested rename has been filled.",
    "uploadToPoolHint": "Upload selected workspace skills to the shared local skill pool",
    "downloadFromPool": "Load from Skill Pool",
    "uploadToPool": "Sync to Skill Pool",
    "selectWorkspaceSkill": "Select current workspace skill",
    "selectPoolItem": "Select skill pool item",
    "renameOptional": "Rename (optional)",
    "renamePlaceholder": "Suggested rename will appear here on conflict",
    "renameSingleOnly": "Rename is available only when exactly one skill is selected.",
    "selectAll": "Select All",
    "clearSelection": "Clear",
    "downloadSkillPool": "Download Skill Pool",
    "uploadSkillPool": "Upload Skill Pool",
    "config": "Config",
    "configPlaceholder": "{\"KEY\": \"value\"}",
    "configInvalidJson": "Invalid JSON format",
    "configSaved": "Config saved",
    "emptyStateBadge": "New workspaces start empty",
    "emptyStateTitle": "This agent does not have any skills yet",
    "emptyStateText": "This is expected. New workspaces do not come with skills automatically. Download skills from the local pool or create one here to equip this agent.",
    "emptyStateDownload": "Download from Skill Pool",
    "emptyStateCreate": "Create First Skill",
    "loadFailed": "Failed to load skills",
    "refreshFailed": "Failed to refresh skills",
    "createdSuccessfully": "Created successfully",
    "saveFailed": "Failed to save",
    "importFailed": "Import failed",
    "disabledSuccessfully": "Disabled successfully",
    "enabledSuccessfully": "Enabled successfully",
    "operationFailed": "Operation failed",
    "provideUrl": "Please provide a hub skill URL",
    "validUrl": "Please enter a valid URL starting with http:// or https://",
    "importedSkill": "Imported skill: {{name}}",
    "batchOperation": "Batch Operation",
    "exitBatch": "Exit Batch",
    "noSearchResults": "No skills found matching your search",
    "filterByTag": "Filter by tag",
    "noTags": "No tags available",
    "enabledSkills": "Enabled Skills",
    "disabledSkills": "Disabled Skills",
    "active": "active"
  },
  "skillPool": {
    "description": "Shared local skill pool for built-in skills and workspace uploads. External hub imports such as ClawHub or LobeHub are separate.",
    "broadcast": "Broadcast to Agents",
    "broadcastHint": "Broadcast skills to selected agents",
    "refreshHint": "Refresh skill pool from disk",
    "deleteExternalConfirm": "This deletes the external skill files at {{path}} from disk.",
    "deleteExternalBatchWarning": "Selected external skills will be permanently deleted from disk.",
    "broadcastTitle": "Broadcast {{name}}",
    "autoUpdate": "Auto Sync",
    "autoUpdateOnHint": "Auto Sync is on; content changes sync to its agents automatically.",
    "autoUpdateEnableHint": "Turn on Auto Sync: push content changes to agents that already have this skill.",
    "autoUpdateDisableHint": "Turn off Auto Sync for this skill.",
    "autoUpdateEnabled": "Auto Sync enabled for {{name}}",
    "autoUpdateDisabled": "Auto Sync disabled for {{name}}",
    "autoUpdateFailed": "Failed to update Auto Sync setting",
    "autoUpdateAgentsPlaceholder": "All agents that have this skill",
    "autoUpdateAgentsHint": "Leave empty to sync every agent that already has the skill. Selecting agents pins updates to them (and installs the skill where missing).",
    "renameAffectsTitle": "Rename in agents too?",
    "renameAffectsContent": "\"{{from}}\" is installed in {{count}} agent(s). Rename to \"{{to}}\"",
    "importBuiltin": "Update Built-in Skills",
    "importBuiltinHint": "Update built-in skills to the latest version",
    "importBuiltinAlertHint": "{{count}} built-in changes need review",
    "importBuiltinSuccess": "Built-ins imported: {{names}}",
    "importBuiltinConflicts": "Skipped due to name conflicts: {{names}}",
    "importBuiltinNoChanges": "No built-in changes to import",
    "importBuiltinFailed": "Built-in import failed",
    "importBuiltinConflictTitle": "Builtin conflicts detected",
    "importBuiltinConflictContent": "The following built-ins differ from the current pool copy. Confirm to overwrite them from source.",
    "sourceVersion": "Source version",
    "currentVersion": "Current version",
    "builtinLanguage": "Language",
    "langDefault": "Default",
    "langDefaultTooltip": "Keep each skill in its current language",
    "langEn": "English",
    "langZh": "Chinese",
    "builtinLanguageChangeTitle": "Switch built-in language?",
    "builtinLanguageChangeContent": "Overwrite the pool copy of \"{{name}}\" with the {{language}} built-in version?",
    "builtinLanguageChangeSuccess": "\"{{name}}\" switched to {{language}}",
    "builtinLanguageChangeFailed": "Failed to switch built-in language",
    "importStatusMissing": "Missing in pool",
    "importStatusCurrent": "Already current",
    "importStatusOutdated": "Outdated",
    "importStatusLanguageSwitchTo": "Overwrite with the {{language}} version",
    "importStatusConflict": "Conflict",
    "builtinNoticeSummary": "{{count}} built-in changes detected",
    "builtinNoticeLineAdded": "Added: {{names}}",
    "builtinNoticeLineMissing": "Missing: {{names}}",
    "builtinNoticeLineUpdated": "Updated: {{names}}",
    "builtinNoticeLineRemoved": "Removed: {{names}}",
    "zipImport": "ZIP Import",
    "create": "Create",
    "edit": "Edit",
    "delete": "Delete",
    "descriptionLabel": "Description",
    "tags": "Tags",
    "tagsPlaceholder": "Select or type to add tags",
    "tagTooLong": "Tag must be at most {{max}} characters",
    "filterByTag": "Filter by tag",
    "version": "Version",
    "createTitle": "Create Skill Pool Item",
    "editTitle": "Edit {{name}}",
    "skillNamePlaceholder": "Skill name",
    "contentPlaceholder": "SKILL.md content",
    "nameConflict": "Name conflict detected. Suggested rename applied.",
    "deletedFromPool": "Deleted from skill pool",
    "deleteBuiltinConfirm": "This removes the built-in skill from the pool. You can import it again later from source.",
    "deleteConfirm": "This removes the skill from the shared local skill pool.",
    "deleteTitle": "Delete {{name}}?",
    "batchDeleteTitle": "Delete {{count}} pool skills?",
    "batchDeleteSuccess": "{{count}} pool skills deleted",
    "batchDeletePartial": "{{deleted}} deleted, {{failed}} failed",
    "batchDeleteFailed": "Batch delete failed",
    "zipImportFailed": "ZIP import failed",
    "externalHubHint": "External hub import is separate from the local Skill Pool.",
    "imported": "Imported: {{names}}",
    "noNewImports": "No new skills imported",
    "allBuiltin": "All Built-in",
    "selectWorkspaces": "Broadcast to workspace(s)",
    "allWorkspaces": "All Workspaces",
    "optionalRename": "Optional rename",
    "back": "Back",
    "skillCount": "{{count}} skills",
    "skillName": "Skill Name",
    "status": "Status",
    "installedFrom": "Installed from",
    "updateBuiltin": "Update",
    "updateConfirmTitle": "Update {{name}}",
    "updateConfirmContent": "Update to version {{version}}? This will replace the current pool copy with the latest built-in version.",
    "updateSuccess": "Updated successfully",
    "updateFailed": "Update failed",
    "broadcastSuccess": "Broadcast completed",
    "broadcastFailed": "Broadcast failed",
    "overwriteConfirm": "Overwrite existing skills?",
    "overwriteTargetsContent": "The following existing targets will be overwritten:",
    "builtinOverwriteTargetsContent": "The following built-in targets have different versions and will be overwritten:",
    "renameAndRetry": "A skill with this name already exists. Use the suggested name?",
    "multiConflictTitle": "Multiple Conflicts Detected",
    "multiConflictDesc": "The following skills already exist. Please resolve conflicts individually and retry:",
    "singleConflictRename": "\"{{name}}\" already exists. Rename to \"{{suggested}}\" to proceed?",
    "statusUpToDate": "Up-to-date",
    "statusSynced": "Synced",
    "statusOutdated": "Outdated",
    "statusNotSynced": "Not synced",
    "statusConflict": "Conflict",
    "renameEntry": "New name for \"{{name}}\":",
    "builtin": "Built-in",
    "custom": "Custom"
  },
  "mcp": {
    "title": "MCP Clients",
    "create": "Create Client",
    "formatSupport": "Supported formats",
    "standardFormat": "Standard (mcpServers wrapper)",
    "directFormat": "Direct (key → config object)",
    "singleFormat": "Single client (flat fields)",
    "emptyState": "No MCP clients configured yet",
    "loadError": "Failed to load MCP clients",
    "createSuccess": "MCP client created successfully",
    "createError": "Failed to create MCP client",
    "updateSuccess": "MCP client updated successfully",
    "updateError": "Failed to update MCP client",
    "enableSuccess": "MCP client enabled successfully",
    "disableSuccess": "MCP client disabled successfully",
    "toggleError": "Failed to toggle MCP client status",
    "deleteConfirm": "Are you sure you want to delete this MCP client?",
    "deleteSuccess": "MCP client deleted successfully",
    "deleteError": "Failed to delete MCP client",
    "maskedFieldHint": "Sensitive fields are masked with ***. In-place edits on masked values are not supported — replace with the full new value to modify.",
    "tools": "Tools & Permissions",
    "noTools": "No tools available from this MCP server",
    "toolsLoadError": "Failed to load tools from MCP server",
    "toolsConnecting": "MCP server is still connecting, please try again in a moment",
    "toolSchema": "Description & Parameters",
    "access": {
      "title": "Access",
      "button": "Access",
      "summary": "MCP access policy",
      "clientSection": "Overall Access",
      "toolSection": "Tool Access",
      "default": "Default",
      "sourceType": "Source",
      "sourceValue": "Source Value",
      "sourceValueAllChannels": "All Channels",
      "subjectType": "Object",
      "subjectValue": "Object Value",
      "effectLabel": "Policy",
      "source": {
        "channel": "Channel"
      },
      "subjectTypeOption": {
        "all": "All",
        "user": "User"
      },
      "sourceValuePlaceholder": {
        "channel": "console / dingtalk"
      },
      "subjectValuePlaceholder": "e.g. alice",
      "subjectValuePlaceholderSelectedSource": "user ID in selected source",
      "subjectValuePlaceholderScoped": "{{source}} user ID",
      "subjectValueAll": "All",
      "recentUserPlaceholder": "User ID is scoped to the selected source; type or select again",
      "noRecentUsers": "No recent users for this source; type a user ID manually",
      "ambiguousUserSourceWarning": "User IDs are scoped by source. Select a specific channel to avoid cross-channel matches.",
      "unknownUserValueWarning": "This user ID is not in recent active users. Saving is allowed.",
      "validation": {
        "missingUserValue": "Select a specific source and enter a valid user ID.",
        "ambiguousUserSource": "User rules must target a specific channel, not all channels.",
        "unknownUserValue": "This user ID is not in recent active users. Saving is allowed."
      },
      "addRule": "Add Rule",
      "deleteRule": "Delete Rule",
      "noClientRules": "No rules",
      "noRules": "No rules, uses default policy",
      "inherit": "Inherit ({{effect}})",
      "stale": "Not found",
      "disabledTools": "This MCP client is disabled; saved access rules can still be edited.",
      "discardTitle": "Discard unsaved changes?",
      "discardContent": "Unsaved access policy changes will be lost.",
      "loadError": "Failed to load MCP access policy",
      "saveSuccess": "MCP access policy saved",
      "saveError": "Failed to save MCP access policy",
      "unmanagedRules": "{{count}} advanced rule(s)",
      "effect": {
        "allow": "Allow",
        "ask": "Ask",
        "deny": "Deny"
      }
    },
    "tab": {
      "json": "JSON Import",
      "form": "Form Mode"
    },
    "form": {
      "key": "Client Key",
      "keyPlaceholder": "my-mcp-server",
      "keyRequired": "Client key is required",
      "name": "Display Name",
      "namePlaceholder": "My MCP Server",
      "nameRequired": "Display name is required",
      "transport": "Transport",
      "url": "Server URL",
      "urlRequired": "URL is required for remote MCP servers",
      "command": "Command",
      "commandRequired": "Command is required for stdio transport",
      "args": "Arguments (space or newline separated)",
      "description": "Description",
      "descriptionPlaceholder": "Optional description",
      "env": "Environment Variables",
      "envPlaceholder": "KEY=VALUE (one per line)"
    },
    "oauth": {
      "enableOAuth": "Use OAuth Authorization",
      "manage": "OAuth",
      "authorized": "Authorized",
      "notAuthorized": "Not Authorized",
      "expired": "Token Expired",
      "failed": "Authorization Failed",
      "waiting": "Waiting for authorization...",
      "authorize": "Authorize",
      "reauthorize": "Re-authorize",
      "revoke": "Revoke",
      "startFailed": "Failed to start OAuth flow",
      "authFailed": "OAuth authorization failed",
      "popupBlocked": "Popup was blocked by the browser. Please allow popups and try again.",
      "windowClosed": "Authorization window was closed. Please try again.",
      "noUrl": "Please enter a server URL first",
      "noClientKey": "Please create the client first",
      "showAdvanced": "Advanced options",
      "hideAdvanced": "Hide advanced options",
      "clientId": "Client ID (optional)",
      "clientIdPlaceholder": "Leave empty to use Dynamic Client Registration",
      "scope": "Scope (optional)",
      "scopePlaceholder": "openid profile email",
      "authEndpoint": "Authorization Endpoint (override)",
      "tokenEndpoint": "Token Endpoint (override)",
      "endpointHint": "Leave empty to auto-discover from the MCP server. Fill in to skip discovery."
    }
  },
  "heartbeat": {
    "title": "Heartbeat",
    "description": "Run HEARTBEAT.md at a fixed interval for self-checks. By default runs silently without affecting current conversations, or optionally send replies to the last chat channel.",
    "enabled": "Enable heartbeat",
    "every": "Interval",
    "everyRequired": "Required",
    "everyMin": "Must be at least 1",
    "timeoutSeconds": "Execution timeout (seconds)",
    "timeoutRequired": "Required",
    "timeoutMin": "Must be at least 1",
    "timeoutMax": "Must be at most 3600",
    "unitMinutes": "Minutes",
    "unitHours": "Hours",
    "target": "Reply target",
    "targetMain": "Silent mode (default, no channel output)",
    "targetLast": "Send to last chat channel",
    "targetInbox": "Send to inbox",
    "activeHours": "Active hours (optional)",
    "activeStart": "Start time",
    "activeEnd": "End time",
    "loadFailed": "Failed to load heartbeat config",
    "saveSuccess": "Saved successfully; heartbeat hot-reloaded",
    "saveFailed": "Failed to save heartbeat config",
    "runNow": "Run Now",
    "runNowSuccess": "Heartbeat triggered. Check Inbox or target channel shortly.",
    "runNowFailed": "Failed to trigger heartbeat run"
  },
  "cronJobs": {
    "title": "Cron Jobs",
    "description": "Create and manage scheduled tasks that automatically execute at specified times. ",
    "createJob": "Create Job",
    "createFromTemplate": "Create From Template",
    "editJob": "Edit Job",
    "templateModalTitle": "Choose a Task Template",
    "templateModalDescription": "Pick a built-in template and tweak key parameters in the drawer before saving.",
    "useTemplate": "Use Template",
    "templateTagPersonal": "Personal",
    "templateTagTeam": "Team",
    "templateTagReminder": "Reminder",
    "templateTagCalendar": "Calendar",
    "templateTagCalendarRecommended": "Calendar Recommended",
    "confirmDelete": "Confirm Delete",
    "deleteConfirm": "Are you sure you want to delete this Cron Job?",
    "okText": "OK",
    "cancelText": "Cancel",
    "deleteText": "Delete",
    "id": "Job ID",
    "name": "Job Name",
    "enabled": "Status",
    "saveResultToInbox": "Save result to Inbox",
    "saveResultToInboxTooltip": "When enabled, successful executions with successful delivery are stored in Inbox. Delivery failures are always written to Inbox as fallback.",
    "scheduleType": "Schedule Type",
    "scheduleFilterAll": "All Schedule Types",
    "scheduleTypeRecurring": "Recurring",
    "scheduleTypeOnce": "Scheduled",
    "scheduleCron": "Schedule (Cron)",
    "scheduleCronLabel": "Schedule (Cron)",
    "onceRunAt": "Run At",
    "repeatEnabled": "Repeat",
    "repeatEnabledTooltip": "Enable recurring schedule from this start time",
    "repeatFrequency": "Repeat Frequency",
    "repeatEveryDays": "Repeat Every (days)",
    "repeatEveryPrefix": "Every",
    "repeatEverySuffix": "day(s)",
    "repeatEndType": "End Repeat",
    "repeatEndNever": "Never",
    "repeatEndUntil": "End on date",
    "repeatEndCount": "Limited count",
    "repeatUntil": "End Date",
    "repeatCount": "Run Count",
    "scheduleTimezone": "Timezone",
    "cronType": "Frequency",
    "cronTypeHourly": "Hourly",
    "cronTypeDaily": "Daily",
    "cronTypeWeekly": "Weekly",
    "cronTypeCustom": "Custom",
    "cronTime": "Time",
    "cronDaysOfWeek": "Days of Week",
    "cronDayMon": "Monday",
    "cronDayTue": "Tuesday",
    "cronDayWed": "Wednesday",
    "cronDayThu": "Thursday",
    "cronDayFri": "Friday",
    "cronDaySat": "Saturday",
    "cronDaySun": "Sunday",
    "cronCustomExpression": "Cron Expression",
    "taskText": "Message content",
    "action": "Action",
    "disable": "Disable",
    "executeNow": "Execute Now",
    "edit": "Edit",
    "delete": "Delete",
    "totalItems": "Total {{count}} items",
    "perPage": "/ page",
    "pleaseInputId": "Please input job ID",
    "pleaseInputName": "Please input job name",
    "pleaseInputCron": "Please input cron expression",
    "pleaseSelectScheduleType": "Please select schedule type",
    "pleaseInputRunAt": "Please select run time",
    "pleaseInputRepeatEveryDays": "Please enter repeat interval (days)",
    "pleaseSelectRepeatEndType": "Please select end condition",
    "pleaseInputRepeatUntil": "Please select end date",
    "pleaseInputRepeatCount": "Please enter run count",
    "validation": {
      "cronRequired": "Cron expression is required for recurring schedules.",
      "runAtRequired": "Execution time is required for one-time schedules.",
      "repeatUntilRequired": "Please select an end date when using \"End on date\".",
      "repeatCountRequired": "Please provide a run count when using \"Limited count\".",
      "repeatUntilAfterRunAt": "The end date must be later than the execution time. Please choose an end date after the execution time.",
      "textRequired": "Message content is required when task type is text.",
      "requestRequired": "Request content is required when task type is agent.",
      "invalidCronExpression": "Invalid cron expression. Please use a 5-field cron format."
    },
    "pleaseSelectTaskType": "Please select task type",
    "pleaseInputRequest": "Please input request content",
    "pleaseInputMessageContent": "Please enter message content",
    "pleaseInputChannel": "Please input target channel",
    "pleaseInputUserId": "Please input target user ID",
    "pleaseInputSessionId": "Please input target session ID",
    "jobIdPlaceholder": "e.g., daily-report-job",
    "jobNamePlaceholder": "e.g., Daily Morning Report",
    "selectTimezone": "Select timezone",
    "taskDescriptionPlaceholder": "For simple text tasks, enter the message body to send...",
    "invalidJsonFormat": "Invalid JSON format",
    "jsonFormatRequired": "JSON format required",
    "taskType": "Task Type",
    "text": "Message content",
    "requestInput": "Request Content",
    "requestSessionId": "Request Session ID",
    "requestUserId": "Request User ID",
    "dispatchChannel": "Target Channel",
    "dispatchTargetUserId": "Target User ID",
    "dispatchTargetSessionId": "Target Session ID",
    "dispatchMode": "Delivery Mode",
    "silentDelivery": "Silent delivery",
    "runtimeShareSession": "Share Session",
    "runtimeMaxConcurrency": "Max Concurrency",
    "runtimeTimeoutSeconds": "Timeout (seconds)",
    "runtimeMisfireGraceSeconds": "Misfire Grace (seconds)",
    "runtimeToolSafety": "Tool Safety Check",
    "idTooltip": "System-generated, non-editable, unique UUID assigned at task creation.",
    "nameTooltip": "A friendly name to help you identify this job.",
    "cronTooltip": "Define when the task should run",
    "cronExample": "Common examples: '0 9 * * *' = 9 AM daily | '*/30 * * * *' = every 30 min | '0 */2 * * *' = every 2 hours | '0 0 * * 0' = Sunday midnight",
    "cronHelper": "New to Cron expressions?",
    "cronHelperLink": "Use online generator",
    "timezoneTooltip": "Timezone for the cron schedule. Default: UTC",
    "taskTypeTooltip": "Choose 'text' for simple message tasks, or 'agent' for complex agent workflows.",
    "textTooltip": "Simple message task: this is the actual message body. Required when task type is 'text'.",
    "requestInputTooltip": "Message content in JSON format. This is what the agent will receive and process. Required when task type is 'agent'.",
    "requestInputExample": "Format: [{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"Your message here\"}]}]",
    "requestSessionIdTooltip": "Session ID for the request context. Use 'default' if unsure.",
    "requestUserIdTooltip": "User ID that initiates the request. Use 'system' for automated tasks.",
    "dispatchChannelTooltip": "Target channel where the response will be sent (e.g., 'console', 'discord', 'imessage').",
    "dispatchTargetUserIdTooltip": "User ID who will receive the response in the target channel.",
    "dispatchTargetSessionIdTooltip": "Session ID where the response will be delivered in the target channel.",
    "dispatchModeTooltip": "Choose 'stream' for real-time responses or 'final' for complete responses only.",
    "silentDeliveryTooltip": "Run the agent task and keep its session and trace, but do not send results to the channel.",
    "shareSessionTooltip": "When enabled, shares session with target user. When disabled, each run creates isolated context with unique run ID. Suitable for independent tasks without memory. Default: enabled",
    "maxConcurrencyTooltip": "Maximum number of this job that can run simultaneously. Default: 1",
    "timeoutSecondsTooltip": "Maximum execution time in seconds. Job will be terminated if exceeded.",
    "misfireGraceSecondsTooltip": "Grace period for missed executions. If a job misses its scheduled time by more than this, it won't run.",
    "toolSafetyTooltip": "When enabled, risky tool calls require user approval (may block unattended cron jobs). When disabled, all tools execute without approval prompts, suitable for trusted automated tasks. Default: disabled",
    "executeNowTitle": "Execute Task Now",
    "executeNowContent": "Are you sure you want to execute \"{{name}}\" now?",
    "executeNowConfirm": "Execute Now",
    "listView": "List View",
    "calendarView": "Calendar View",
    "calendarEmptyHint": "No scheduled jobs yet. Create scheduled jobs to see them on the calendar.",
    "calendarMoreItems": "+{{count}} more",
    "calendarDayListTitle": "Scheduled jobs on {{date}}",
    "executionHistory": "History",
    "historyTitle": "History - {{name}}",
    "historyEmpty": "No execution records yet.",
    "historyStatusSuccess": "Success",
    "historyStatusFailed": "Failed",
    "historyStatusRunning": "Running",
    "historyStatusCancelled": "Cancelled",
    "historyTriggerScheduled": "Triggered by schedule",
    "historyTriggerManual": "Triggered manually",
    "historyExpand": "Expand",
    "historyCollapse": "Collapse",
    "templates": {
      "dailyTechNewsBrief": {
        "title": "Daily Tech News Brief",
        "description": "At 09:30 on weekdays, compile trending tech headlines into a short digest.",
        "frequency": "Weekdays 09:30 (30 9 * * 1-5)"
      },
      "dailyEveningReflection": {
        "title": "Daily Evening Reflection",
        "description": "At 20:00 on weekdays, prompt a quick reflection on work completed today.",
        "frequency": "Weekdays 20:00 (0 20 * * 1-5)"
      },
      "weekendRelaxationReminder": {
        "title": "Weekend Relaxation Reminder",
        "description": "On weekend mornings, push curated hot movie picks for a lighter break.",
        "frequency": "Weekends 10:00 (0 10 * * 6,0)"
      },
      "pomodoroBreakReminder": {
        "title": "Pomodoro Break Reminder",
        "description": "During work hours, remind every 25 minutes to hydrate or rest your eyes.",
        "frequency": "Weekdays 09:00-17:59 every 25 min (*/25 9-17 * * 1-5)"
      },
      "petCareReminder": {
        "title": "Pet Deworming/Vaccine Reminder",
        "description": "On the 15th each month at night, remind pet deworming or vaccine follow-up.",
        "frequency": "Monthly on the 15th at 20:00 (0 20 15 * *)"
      },
      "onceTextBirthdayReminder": {
        "title": "Birthday Reminder",
        "description": "Remind that xx has a birthday on Jan 1.",
        "frequency": "Run at: 2026-01-01 09:00"
      },
      "onceAgentBusinessTripPrep": {
        "title": "Business Trip Prep",
        "description": "Check destination weather and provide trip preparation suggestions.",
        "frequency": "Run at: 2026-01-01 20:00"
      },
      "repeatCountTextMedicineReminder": {
        "title": "Medication Reminder (14 runs)",
        "description": "Remind to take medicine on time for a 14-run course.",
        "frequency": "First run: 2026-01-01 09:00 | Every 1 day | 14 runs"
      },
      "repeatCountAgentDietPlan": {
        "title": "14-Day Meal Plan",
        "description": "Generate and send daily meal suggestions for 14 days.",
        "frequency": "First run: 2026-01-01 08:00 | Every 1 day | 14 runs"
      },
      "repeatUntilTextWeeklyMeeting": {
        "title": "Weekly Meeting Reminder (2 months)",
        "description": "Send a weekly meeting reminder until the configured deadline.",
        "frequency": "First run: 2026-01-02 08:45 | Every 7 days | Until 2026-03-01"
      },
      "repeatUntilAgentWeeklySummary": {
        "title": "Pre-Meeting Weekly Summary",
        "description": "Before each weekly meeting, summarize the last week's memory.",
        "frequency": "First run: 2026-01-02 08:30 | Every 7 days | Until 2026-03-01"
      }
    }
  },
  "channels": {
    "title": "Channels",
    "description": "Manage and configure message channels",
    "loading": "Loading channels...",
    "configSaved": "Configuration saved successfully",
    "configFailed": "Failed to save configuration",
    "channelType": "Channel Type",
    "status": "Status",
    "totalItems": "Total {{count}} items",
    "botPrefix": "Bot Prefix",
    "showToolCalls": "Show Tool Call Information",
    "showToolCallsTooltip": "Show tool call information to users (turn off to hide)",
    "showToolResults": "Show Tool Result Information",
    "showToolResultsTooltip": "Show tool result information to users (turn off to hide)",
    "toolCallMaxLength": "Tool Call Maximum Display Length",
    "toolResultMaxLength": "Tool Result Maximum Display Length",
    "toolMaxLengthTooltip": "Set to 0 for unlimited length",
    "showThinking": "Show Thinking",
    "showThinkingTooltip": "Show model thinking/reasoning content to users (turn off to hide)",
    "noTextDebounce": "No-text Debounce",
    "noTextDebounceTooltip": "When enabled, media-only messages (image/video/file) are buffered until a text message arrives, then merged. Disable to process all messages immediately. Voice messages are always processed immediately.",
    "streamingEnabled": "Streaming Output",
    "streamingEnabledDingtalkHint": "Only effective when message type is Card",
    "streamingEnabledFeishuHint": "Requires enabling cardkit:card:write permission in the Feishu Open Platform permission management page",
    "ackMessage": "Acknowledgment Message",
    "ackMessageTooltip": "Send an instant reply when a message is received, before agent processing begins. Leave empty to disable.",
    "ackMessagePlaceholder": "⏳ Processing...",
    "notSet": "Not set",
    "clickCardToEdit": "Click card to edit",
    "settings": "Settings",
    "channelSettings": "Channel Settings",
    "pleaseInputDbPath": "Please input DB path",
    "pleaseInputPollInterval": "Please input poll interval",
    "discordBotToken": "Discord bot token",
    "acceptBotMessages": "Accept Bot Messages",
    "acceptBotMessagesTooltip": "When enabled, messages from other bots will be accepted",
    "httpProxyPlaceholder": "http://127.0.0.1:18118",
    "httpProxyAuthPlaceholder": "user:password",
    "dbPathPlaceholder": "~/Library/Messages/chat.db",
    "botPrefixPlaceholder": "@bot",
    "dmPolicy": "DM Policy",
    "dmPolicyTooltip": "Control who can interact with the bot via direct message. Open: everyone; Allowlist: authorized users only",
    "groupPolicy": "Group Policy",
    "groupPolicyTooltip": "Control who can interact with the bot in group chats. Open: everyone; Allowlist: authorized users only",
    "requireMention": "Require @Mention",
    "requireMentionTooltip": "When enabled, bot only responds in group chats when explicitly @mentioned",
    "policyOpen": "Open",
    "policyAllowlist": "Allowlist",
    "allowFrom": "Allowlist Users",
    "allowFromTooltip": "List of user IDs allowed to interact with the bot. Enable allowlist first, then DM the bot to see your ID in the deny message",
    "allowFromPlaceholder": "Enter user ID and press Enter to add",
    "denyMessage": "Access Denied Message",
    "denyMessageTooltip": "Custom message shown to users when access is denied",
    "twilioAccountSid": "Twilio Account SID",
    "twilioAuthToken": "Twilio Auth Token",
    "phoneNumber": "Phone Number",
    "phoneNumberSid": "Phone Number SID",
    "phoneNumberSidHelp": "Found under Phone Numbers → Active Numbers in the Twilio Console.",
    "ttsProvider": "TTS Provider",
    "ttsVoice": "TTS Voice",
    "sttProvider": "STT Provider",
    "language": "Language",
    "welcomeGreeting": "Welcome Greeting",
    "welcomeText": "Welcome Message",
    "welcomeTextTooltip": "Message automatically sent when a user enters a single chat session with the bot for the first time that day",
    "welcomeTextPlaceholder": "e.g. Hello! I'm QwenPaw. How can I help you?",
    "loginWeCom": "Get WeCom QR Code",
    "wecomSetupGuide": "When creating a bot via QR code, please select \"Skip Authorization\" when asked to authorize bot capabilities. If you select \"Confirm Authorization\", users other than the bot creator may not be able to interact with the bot.",
    "wecomScanAuth": "Scan to Authorize",
    "wecomAuthHint": "Scan the QR code above with WeCom to authorize. Bot ID and Secret will be filled in automatically.",
    "wecomAuthSuccess": "WeCom bot authorized. Bot ID and Secret have been filled in.",
    "wecomQrcodeFailed": "Failed to get WeCom QR code. Please try again.",
    "slackBotToken": "Bot Token",
    "slackBotTokenTooltip": "Slack Bot User OAuth Token, starts with xoxb-",
    "slackAppToken": "App Token",
    "slackAppTokenTooltip": "Slack App-Level Token for Socket Mode, starts with xapp-",
    "slackProxyTooltip": "HTTP proxy URL for connecting to Slack API",
    "dingtalkSetupGuide": "Scan the QR code with DingTalk to create a bot instantly. A DingTalk app will be created automatically and Client ID / Client Secret will be filled in.",
    "dingtalkScanAuth": "Scan to Create Bot",
    "dingtalkGetQrcode": "Get DingTalk QR Code",
    "dingtalkScanHint": "Scan the QR code above with DingTalk. Client ID and Client Secret will be filled in automatically after authorization.",
    "dingtalkAuthSuccess": "DingTalk bot created. Client ID and Client Secret have been filled in.",
    "dingtalkQrcodeFailed": "Failed to get DingTalk QR code. Please try again.",
    "dingtalkQrcodeExpired": "QR code expired, please get a new one.",
    "qqSetupGuide": "Use QQ to scan the QR code to authorize the bot. After scanning, the APP ID and Client Secret will be automatically retrieved and filled in.",
    "qqScanAuth": "Scan the QR code to authorize the bot",
    "qqGetQrcode": "Get QQ QR code",
    "qqScanHint": "Please use QQ to scan the QR code above. Once authorization is complete, the APP ID and Client Secret will be automatically filled in.",
    "qqAuthSuccess": "QQ bot authorization successful. The APP ID and Client Secret have been automatically filled in.",
    "qqQrcodeFailed": "Failed to retrieve the QQ QR code; please try again later",
    "qqQrcodeExpired": "The QR code has expired; please retrieve a new one",
    "atSenderOnReply": "@ Sender on Reply",
    "atSenderOnReplyTooltip": "When enabled, the bot will @mention the sender in its first reply message in group chats. Note: In card mode, @mention only works for enterprise internal members.",
    "dingtalkEndpoint": "API Endpoint",
    "dingtalkEndpointTooltip": "Custom API endpoint for private DingTalk deployments. Leave empty to use the official default.",
    "wecomCancelled": "Authorization cancelled",
    "wecomAuthFailed": "Authorization failed: {{msg}}",
    "voiceSetupGuide": "Set up a Twilio account, purchase a phone number, then enter your credentials below. Find your Account SID and Auth Token on the Twilio Console dashboard. The Phone Number SID is listed under Phone Numbers → Active Numbers.",
    "voiceSetupLink": "Open Twilio Console",
    "sipSetupGuide": "Configure a SIP registrar (e.g. Asterisk, FreeSWITCH) and enter your SIP credentials below. In Dev mode, pyVoIP handles SIP/RTP locally. In Production mode, LiveKit SIP Server is used.",
    "sipMode": "SIP Mode",
    "sipModeTooltip": "Dev: pure-Python pyVoIP for local testing. Production: LiveKit SIP Server for high concurrency.",
    "sipServer": "SIP Server",
    "sipServerPlaceholder": "Leave empty to use built-in registrar",
    "sipServerPlaceholderLivekit": "Not needed for LiveKit mode",
    "sipUsername": "SIP Username",
    "sipPassword": "SIP Password",
    "sipPort": "SIP Port",
    "sipTransport": "Transport",
    "sipDashscopeApiKey": "DashScope API Key",
    "sipDashscopeApiKeyTooltip": "API key for Aliyun DashScope STT/TTS. If empty, falls back to the DASHSCOPE_API_KEY environment variable.",
    "livekitUrl": "LiveKit URL",
    "livekitApiKey": "LiveKit API Key",
    "livekitApiSecret": "LiveKit API Secret",
    "livekitSipTrunkId": "LiveKit SIP Trunk ID",
    "livekitRoomName": "LiveKit Room Name",
    "livekitRoomNameTooltip": "The LiveKit room name to join and wait for SIP calls. Must match the room name in your SIP Dispatch Rule.",
    "xiaoyiSetupGuide": "Please create an agent on Huawei Developer Platform and get AK/SK and Agent ID. AK/SK can be found in the credential management page.",
    "filterAll": "All",
    "builtin": "Built-in",
    "custom": "Custom",
    "feishuRegion": "Region",
    "feishuRegionTooltip": "Choose Feishu for China or Lark for International",
    "feishuChina": "Feishu (China)",
    "feishuInternational": "Lark (International)",
    "feishuScanGuide": "Scan the QR code with Feishu to create a bot instantly. A Feishu app will be created automatically and App ID / App Secret will be filled in.",
    "feishuScanLogin": "Scan to Create Bot",
    "feishuGetQrcode": "Get Feishu QR Code",
    "feishuScanHint": "Scan the QR code above with Feishu. App ID and App Secret will be filled in automatically after authorization.",
    "feishuAuthSuccess": "Feishu bot created. App ID and App Secret have been filled in.",
    "feishuQrcodeExpired": "QR code expired, please get a new one.",
    "feishuQrcodeFailed": "Failed to get Feishu QR code. Please try again.",
    "wechatSetupGuide": "WeChat personal account Bot (iLink protocol). On first start without a Bot Token, a QR code login URL will be printed; scan to authorize. The token is saved locally for future use.",
    "wechatContextTokenLimit": "WeChat iLink platform limitation: each user message's context_token allows a maximum of 10 reply messages. This is a hard limit enforced by the platform. It is recommended to disable thinking and tool output, or enable Message Merge to avoid exceeding the limit and causing message send failures.",
    "wechatBotToken": "Bot Token",
    "wechatBotTokenTooltip": "Bearer token obtained after QR code login. Leave empty to trigger QR code login on startup.",
    "wechatBotTokenPlaceholder": "Auto-filled after QR login, or paste manually",
    "wechatBotTokenFile": "Token File Path",
    "wechatBotTokenFileTooltip": "Path to persist the bot token. Defaults to ~/.qwenpaw/wechat_bot_token",
    "wechatMediaDir": "Media Directory",
    "wechatMessageMerge": "Message Merge",
    "wechatMessageMergeTooltip": "Merge multiple reply messages into fewer messages to avoid hitting the WeChat 10-message limit per context_token. When enabled with delay 0, all text replies are merged into a single message sent at the end. A positive delay (in ms) merges adjacent messages within that time window.",
    "wechatMessageMergeDelayMs": "Merge Delay (ms)",
    "wechatMessageMergeDelayMsTooltip": "Time window for adjacent message merging. Set to 0 to merge all messages into one final reply. A positive value (e.g. 1000) will buffer messages for that duration before sending.",
    "wechatMessageMergeDelayMsValidation": "Please enter a valid non-negative integer",
    "wechatScanLogin": "Scan to Login",
    "wechatGetQrcode": "Get Login QR Code",
    "wechatScanHint": "Scan the QR code with WeChat, then click Save",
    "wechatQrcodeFailed": "Failed to fetch QR code, please try again",
    "wechatLoginSuccess": "WeChat login successful, token has been filled in",
    "wechatQrcodeExpired": "QR code expired, please get a new one",
    "shareSessionInGroup": "Share Context in Group",
    "shareSessionInGroupTooltip": "When enabled, all group members share the same conversation context. When disabled, each member has their own independent context.",
    "accessControlEnabled": "Access Control",
    "accessControlEnabledTooltip": "When enabled, only whitelisted users can interact with this bot. Unknown users will be prompted with their ID and added to the pending approval list.",
    "accessControlDm": "DM Access Control",
    "accessControlDmTooltip": "When enabled, only whitelisted users can interact with the bot in direct messages",
    "accessControlGroup": "Group Access Control",
    "accessControlGroupTooltip": "When enabled, only whitelisted users can interact with the bot in group chats",
    "dmDisabled": "Disable DM",
    "dmDisabledTooltip": "When enabled, the bot will completely ignore all direct messages",
    "groupDisabled": "Disable Group",
    "groupDisabledTooltip": "When enabled, the bot will completely ignore all group messages",
    "manageAccessControl": "Access Control",
    "pendingApprovals": "Pending Approvals",
    "whitelist": "Whitelist",
    "blacklist": "Blacklist",
    "addUser": "Add User",
    "addUserPlaceholder": "Enter user ID",
    "userId": "User ID",
    "username": "Username",
    "channel": "Channel",
    "firstMessage": "First Message",
    "time": "Time",
    "actions": "Actions",
    "approve": "Whitelist",
    "deny": "Blacklist",
    "dismiss": "Dismiss",
    "noWhitelistUsers": "No whitelist users",
    "noBlacklistUsers": "No blacklist users",
    "noPendingApprovals": "No pending approvals",
    "userAdded": "User added successfully",
    "userRemoved": "User deleted successfully",
    "approveSuccess": "User added to whitelist",
    "denySuccess": "User added to blacklist",
    "dismissSuccess": "Pending entry dismissed",
    "operationFailed": "Operation failed",
    "remark": "Remark",
    "usernamePlaceholder": "Enter username (optional)",
    "remarkPlaceholder": "Enter a remark (optional)",
    "filterByChannel": "Filter by channel",
    "selectToOperate": "Select items to operate",
    "selectedCount": "{{count}} selected",
    "batchApprove": "Approve",
    "batchDeny": "Blacklist",
    "batchDismiss": "Dismiss",
    "batchApproveConfirm": "Approve {{count}} selected users?",
    "batchDenyConfirm": "Blacklist {{count}} selected users?",
    "batchDismissConfirm": "Dismiss {{count}} selected users?",
    "batchSuccess": "{{count}} users processed successfully",
    "batchRemove": "Delete",
    "batchRemoveConfirm": "Delete {{count}} selected users?",
    "enabledSection": "Enabled",
    "enabledCount": "{{count}}",
    "availableSection": "Available",
    "enableAction": "Enable",
    "noEnabledChannels": "No enabled channels",
    "goEnableChannels": "Enable channels"
  },
  "sessions": {
    "title": "Sessions",
    "description": "View and manage active chat sessions",
    "loading": "Loading sessions...",
    "confirmDelete": "Confirm Delete",
    "deleteConfirm": "Are you sure you want to delete this session?",
    "batchDeleteConfirm": "Are you sure you want to delete selected {{count}} sessions?",
    "deleteSuccess": "Session deleted successfully",
    "deleteFailed": "Failed to delete session",
    "batchDeleteSuccess": "Successfully deleted {{count}} session(s)",
    "batchDeleteFailed": "Failed to batch delete sessions",
    "saveSuccess": "Session saved successfully",
    "saveFailed": "Failed to save session",
    "batchDeleteButton": "Batch Delete",
    "filterTitle": "Filter by Title",
    "filterUserId": "Filter by User ID",
    "filterChannel": "Filter by Channel",
    "allChannels": "All Channels",
    "totalItems": "Total {{count}} items",
    "selectedItems": "Selected {{count}} items",
    "editSession": "Edit Session",
    "pleaseInputName": "Please input session name",
    "sessionNamePlaceholder": "Session name",
    "activeTab": "Active",
    "archivedTab": "Archived",
    "archivedAtColumn": "Archived At",
    "archive": {
      "action": "Archive",
      "unaction": "Unarchive",
      "batchAction": "Batch Archive",
      "success": "Chat archived",
      "successHint": "Chat archived. View in Control > Sessions > Archived.",
      "failed": "Failed to archive",
      "unarchiveSuccess": "Chat unarchived",
      "unarchiveFailed": "Failed to unarchive",
      "batchSuccess": "{{count}} chat(s) archived",
      "batchFailed": "Failed to batch archive",
      "batchUnaction": "Batch Unarchive",
      "batchUnarchiveSuccess": "{{count}} chat(s) unarchived",
      "batchUnarchiveFailed": "Failed to batch unarchive",
      "groupLabel": "Archived ({{count}})",
      "modalTitle": "Archived Chats",
      "unarchiveAll": "Unarchive All",
      "noArchived": "No archived chats"
    }
  },
  "environments": {
    "parent": "Settings",
    "environments": "Environment Variables",
    "title": "Environment Variables",
    "description": "Configure key-value environment variables for agents and skills.",
    "key": "Key",
    "value": "Value",
    "variableNamePlaceholder": "VARIABLE_NAME",
    "valuePlaceholder": "value",
    "insertRowBelow": "Insert row below",
    "deleteRow": "Delete row",
    "deleteVariable": "Delete Variable",
    "deleteConfirm": "Delete \"{{name}}\"?",
    "deleteSelected": "Delete Selected",
    "deleteSelectedConfirm": "Delete {{label}}?",
    "keyRequired": "Key is required",
    "invalidKeyFormat": "Invalid key format",
    "duplicateKey": "Duplicate key",
    "saveSuccess": "Environment variables saved",
    "saveFailed": "Failed to save",
    "deleteSuccess": "\"{{name}}\" deleted",
    "deleteFailed": "Failed to delete",
    "noVariables": "No environment variables configured yet.",
    "addVariable": "Add Variable",
    "loading": "Loading…",
    "retry": "Retry",
    "of": "of",
    "selected": "selected",
    "variable": "variable",
    "variables": "variables",
    "showValue": "Show value",
    "hideValue": "Hide value"
  },
  "modelSelector": {
    "selectModel": "Select model",
    "noConfiguredModels": "No configured models",
    "noFreeModels": "No free models available",
    "switchFailed": "Failed to switch model",
    "searchModels": "Search models...",
    "noModelsFound": "No matching models found",
    "free": "Free",
    "vision": "Vision",
    "freeBannerText": "Free models may have rate limits and limited availability. Refer to the provider for details.",
    "moreProviders": "More free providers (API Key required)",
    "proBannerText": "Showing models configured in Settings.",
    "connectToUse": "Connect {{provider}} to use free models",
    "configureApiKey": "Configure {{provider}} API Key to use free models",
    "configureApiKeyTitle": "Go to Configuration",
    "configureApiKeyConfirm": "You will be redirected to the Models page to configure {{provider}} API Key. Continue?",
    "goToConfigure": "Go to Configure",
    "noModelsDiscovered": "Connected. Models loading...",
    "oauthTitle": "Connect to {{provider}}",
    "oauthDescription": "A new browser window will open for you to authorize access to {{provider}}. Your API key will be saved automatically.",
    "oauthContinue": "Continue",
    "oauthWaiting": "Waiting for authorization...",
    "oauthWaitingDescription": "Please complete the authorization in the browser window.",
    "oauthConnected": "Successfully connected to {{provider}}",
    "oauthFailed": "Authorization failed, please try again",
    "viewMore": "View more ({{count}})"
  },
  "tokenUsage": {
    "title": "Token Usage",
    "totalTokens": "Total Tokens",
    "totalCalls": "Total Calls",
    "promptTokens": "Prompt Tokens",
    "completionTokens": "Completion Tokens",
    "byModel": "By Model",
    "byDate": "By Date",
    "model": "Model",
    "date": "Date",
    "loadFailed": "Failed to load token usage",
    "noData": "No token usage data in the selected period",
    "modelTrend": "Model Usage Trend",
    "tokenTypeChart": "Token Type Trend",
    "selectAll": "Select All",
    "allSelected": "All",
    "itemsSelected": "{{count}} selected",
    "selectModels": "Select models",
    "selectTokenTypes": "Select token types"
  },
  "agentStats": {
    "title": "Agent Statistics",
    "description": "View agent statistics for the selected time period.",
    "totalSessions": "Total Sessions",
    "totalMessages": "Total Messages",
    "userMessages": "User Messages",
    "assistantMessages": "Assistant Messages",
    "promptTokens": "Prompt Tokens",
    "completionTokens": "Completion Tokens",
    "llmCalls": "LLM Calls",
    "toolCalls": "Tool Calls",
    "channel": "Channel",
    "sessionCount": "Sessions",
    "sessions": "Sessions",
    "newSessions": "New Sessions",
    "activeSessions": "Active Sessions",
    "messages": "Messages",
    "messageTrend": "Message Trend",
    "sessionTrend": "Session Trend",
    "tokenTrend": "Token Trend",
    "llmAndToolTrend": "LLM & Tool Call Trend",
    "sessionsByChannel": "Sessions by Channel",
    "messagesByChannel": "Messages by Channel",
    "totalSessionsTooltip": "Total chat sessions created, each session is an independent conversation context",
    "totalMessagesTooltip": "Total messages across all sessions, including both user and assistant messages",
    "promptTokensTooltip": "Total prompt tokens sent to the LLM",
    "completionTokensTooltip": "Total completion tokens generated by the LLM",
    "llmCallsTooltip": "Number of LLM API calls, each request counts as one call",
    "toolCallsTooltip": "Number of times the agent decided to invoke a tool; a single LLM call may produce multiple tool-use intents",
    "messageTrendTooltip": "Trend comparing user messages vs assistant messages",
    "sessionTrendTooltip": "Trend comparing new sessions vs active sessions; orange bars are sessions created that day, blue bars are sessions with messages that day",
    "tokenTrendTooltip": "Trend of prompt and completion token consumption",
    "llmAndToolTrendTooltip": "Trend comparing LLM calls vs tool-use intents",
    "sessionsByChannelTooltip": "Distribution of sessions by messaging channel; sessions without a channel are grouped under Console",
    "messagesByChannelTooltip": "Distribution of total messages by messaging channel",
    "loadFailed": "Failed to load statistics",
    "noData": "No statistics data in the selected period",
    "retry": "Retry"
  },
  "models": {
    "llmConfiguration": "LLM Configuration",
    "providersTitle": "Providers",
    "providersDescription": "Configure API keys and endpoints for each provider.",
    "llmTitle": "Models",
    "defaultLlm": "Default LLM",
    "notConfiguredYet": "Not configured",
    "llmDescription": "Set the global default LLM model from an authorized provider. You can choose a specific model for each Agent in the Chat page.",
    "configureProvider": "Configure {{name}}",
    "baseURL": "Base URL",
    "apiKey": "API Key",
    "advancedConfig": "Advanced Configuration",
    "authMode": "Authentication Mode",
    "authModeApiKey": "API Key (x-api-key)",
    "authModeAuthToken": "Auth Token (Authorization: Bearer)",
    "customHeaders": "Custom Headers",
    "customHeadersHint": "Appended to every API request, e.g. x-app: cli",
    "customHeaderKey": "Header Name",
    "customHeaderValue": "Header Value",
    "addHeader": "+ Add Header",
    "generateConfig": "Generation Parameters",
    "generateConfigHint": "Generation parameters expressed as a JSON object. They will be expanded and passed into the generation request (`openai.chat.completions` or `anthropic.messages`).",
    "generateConfigInvalidJson": "Please enter valid JSON",
    "generateConfigMustBeObject": "Generation parameters must be a JSON object",
    "modelAdvancedConfig": "Model Advanced Config",
    "modelGenerateConfig": "Model Generation Parameters",
    "modelGenerateConfigHint": "Generation parameters expressed as a JSON object for this model. They will be expanded and passed into the generation request. These override provider-level advanced configuration.",
    "modelConfigSaved": "Configuration saved for model {{name}}",
    "modelConfigSaveFailed": "Failed to save model configuration",
    "modelConfigLabel": "Model Config",
    "maxTokensLabel": "Max Tokens",
    "maxTokensHint": "Maximum output tokens per response",
    "maxInputLengthLabel": "Max Context Length",
    "maxInputLengthHint": "Model context window size, controls context compaction threshold (≥1000)",
    "relayReasoningLabel": "Relay Reasoning",
    "relayReasoningHint": "Relay reasoning contents back to subsequent conversation turns",
    "thinkingModeLabel": "Enable Thinking",
    "thinkingModeHint": "Turn on to enable model thinking/reasoning. Turn off to disable thinking.",
    "thinkingBudgetLabel": "Thinking Budget",
    "thinkingBudgetHint": "Using model default thinking budget",
    "switchToManual": "Manual",
    "switchToAuto": "Auto",
    "reasoningEffortLabel": "Reasoning Effort",
    "reasoningEffortHint": "Controls reasoning depth (OpenAI-family)",
    "protocol": "Protocol",
    "protocolHint": "Choose the provider API protocol for this configuration.",
    "selectProtocol": "Please select a protocol",
    "protocolOpenAI": "OpenAI-compatible (Chat Completions)",
    "protocolOpenAIResponse": "OpenAI-compatible (Response API)",
    "protocolAnthropic": "Anthropic (Messages API)",
    "currentKey": "Current: {{key}}",
    "startsWith": "Starts with \"{{prefix}}\"",
    "optionalSelfHosted": "Optional for self-hosted services",
    "leaveBlankKeep": "Leave blank to keep current key",
    "enterApiKey": "Enter API key ({{prefix}}...)",
    "enterApiKeyOptional": "Enter API key (optional)",
    "openAIEndpoint": "OpenAI endpoint, e.g. https://api.openai.com/v1",
    "openAICompatibleEndpoint": "OpenAI-compatible endpoint, e.g. https://api.example.com (append /v1 only if your provider requires it)",
    "azureEndpointHint": "Azure OpenAI endpoint, e.g. https://<resource>.openai.azure.com/openai/v1",
    "anthropicEndpointHint": "Anthropic endpoint, e.g. https://api.anthropic.com",
    "ollamaEndpointHint": "Ollama endpoint, e.g. http://localhost:11434",
    "lmstudioEndpointHint": "LM Studio endpoint, e.g. http://localhost:1234/v1",
    "apiEndpointHint": "API endpoint, e.g. https://api.example.com",
    "pleaseEnterBaseURL": "Please enter the API base URL",
    "selectBaseURL": "Select a base URL",
    "selectBaseURLHint": "Select the regional endpoint for this provider",
    "pleaseEnterValidURL": "Please enter a valid URL",
    "apiKeyShouldStart": "API Key should start with \"{{prefix}}\"",
    "configurationSaved": "{{name}} configuration saved",
    "failedToSaveConfig": "Failed to save configuration",
    "revokeAuthorization": "Revoke Authorization",
    "revokeConfirmContent": "Are you sure you want to remove the API key for {{name}}? The current LLM model configuration will also be cleared.",
    "revokeConfirmSimple": "Are you sure you want to remove the API key for {{name}}?",
    "authorizationRevoked": "{{name}} authorization revoked, LLM model cleared",
    "authorizationRevokedSimple": "{{name}} authorization revoked",
    "failedToRevoke": "Failed to revoke authorization",
    "active": "Active: {{provider}} / {{model}}",
    "provider": "Provider",
    "model": "Model",
    "selectProvider": "Select provider (must be authorized)",
    "selectModel": "Select a model",
    "llmModelUpdated": "LLM Model updated",
    "failedToSave": "Failed to save",
    "freeModelWarningTitle": "Free Model Notice",
    "freeModelWarningMessage": "Free models may have limited availability. Please refer to the provider's terms of service:",
    "freeModelWarningDontShowAgain": "Do not show this again",
    "saved": "Saved",
    "save": "Save",
    "cancel": "Cancel",
    "loading": "Loading...",
    "retry": "Retry",
    "notSet": "Not set",
    "notRequired": "Not required",
    "available": "Available",
    "unavailable": "Unavailable",
    "providerAvailable": "Ready (with models)",
    "providerNoModels": "Not Ready (no models)",
    "providerNotConfigured": "Not Ready (not configured)",
    "settings": "Settings",
    "actions": "Actions",
    "search": "Search",
    "searchPlaceholder": "Search providers...",
    "searchModelPlaceholder": "Search models...",
    "custom": "Custom",
    "builtin": "Built-in",
    "freeTierGroup": "Free Tier",
    "paidGroup": "Paid",
    "localCustomGroup": "Local & Custom",
    "cloudGroup": "Cloud Providers",
    "configuredGroup": "Configured",
    "configuredOnline": "providers online",
    "noConfigured": "No providers configured yet. Select one below to get started.",
    "goConfigureBtn": "Configure a Provider",
    "availableGroup": "Available Providers",
    "clickToConfigure": "Click to configure",
    "configureAction": "Configure →",
    "endpointCount": "{{count}} endpoints",
    "connect": "OAuth",
    "saveApiKey": "Save",
    "addProvider": "Add Provider",
    "addProviderTitle": "Add Custom Provider",
    "providerIdLabel": "Provider ID",
    "providerIdPlaceholder": "e.g. openai, google, anthropic",
    "providerIdHint": "Lowercase letters, digits, hyphens, underscores. Cannot be changed later.",
    "providerNameLabel": "Display Name",
    "providerNamePlaceholder": "e.g. OpenAI, Google Gemini",
    "defaultBaseUrlLabel": "Default Base URL",
    "defaultBaseUrlPlaceholder": "e.g. https://api.example.com",
    "apiKeyPrefixLabel": "API Key Prefix (optional)",
    "apiKeyPrefixPlaceholder": "e.g. sk-",
    "providerCreated": "Provider \"{{name}}\" created",
    "providerCreateFailed": "Failed to create provider",
    "deleteProvider": "Delete Provider",
    "deleteProviderConfirm": "Delete custom provider \"{{name}}\" and all its models? This cannot be undone.",
    "providerDeleted": "Provider \"{{name}}\" deleted",
    "providerDeleteFailed": "Failed to delete provider",
    "disableProvider": "Disable Provider",
    "disableProviderConfirm": "Clear API key for \"{{name}}\"? The provider will become unconfigured.",
    "disableBtn": "Disable",
    "changeApiKey": "Change",
    "selectVariant": "Select {{name}} Variant",
    "providerDisabled": "Provider \"{{name}}\" disabled",
    "manageModels": "Models",
    "models": "Models",
    "manageModelsTitle": "{{provider}} — Model Management",
    "userAdded": "User-added",
    "addModel": "Add Model",
    "addModels": "Add Models",
    "autoDiscoverModels": "Auto Discover Models",
    "addModelTitle": "Add Model to {{provider}}",
    "modelIdLabel": "Model ID",
    "modelIdPlaceholder": "e.g. gpt-4o, gemini-2.0-flash",
    "modelDiscoveryUnavailableHint": "No available models were found. This provider may not support model list discovery, so please enter the model ID manually.",
    "modelNameLabel": "Model Name",
    "modelNameRequired": "Please enter model name",
    "modelNamePlaceholder": "e.g. GPT-4o, Gemini 2.0 Flash",
    "modelAdded": "Model \"{{name}}\" added",
    "modelAddFailed": "Failed to add model",
    "modelAlreadyExists": "Model ID \"{{id}}\" already exists",
    "autoDiscoverModelsSuccess": "Auto discovery complete. Added {{count}} models",
    "autoDiscoverModelsNoNew": "Auto discovery complete. No new models were added",
    "autoDiscoverModelsFailed": "Failed to auto discover models",
    "removeModel": "Remove",
    "removeModelConfirm": "Remove model \"{{name}}\" from {{provider}}?",
    "modelRemoved": "Model \"{{name}}\" removed",
    "modelRemoveFailed": "Failed to remove model",
    "loadMore": "Load more ({{count}})",
    "modelsCount": "{{count}} models",
    "noModels": "No models",
    "addModelFirst": "Please add a model first",
    "modelList": "Model List",
    "clearAll": "Clear All",
    "filteredModelsLoaded": "Filtered models loaded: {{count}}",
    "filterFailed": "Failed to filter models",
    "clearAllModels": "Clear All Models",
    "clearAllModelsConfirm": "Clear all {{count}} extra models? This cannot be undone.",
    "allModelsCleared": "Cleared {{count}} models",
    "filterModels": "Filter Models",
    "filterByProvider": "Provider:",
    "searchProviderPlaceholder": "Search provider name",
    "selectAllProviders": "Select All",
    "clearProviderSelection": "Deselect All",
    "noMatchingProviders": "No matching providers",
    "filterByModality": "Input Modality:",
    "filterFreeOnly": "Free Models Only:",
    "getModels": "Get Models",
    "discovered": "Available Models:",
    "add": "Add",
    "local": "Local",
    "localType": "Type",
    "localEmbedded": "Embedded (in-process)",
    "localDownloadFirst": "Model service not started",
    "localDownloadModel": "Download Model",
    "localModelsTitle": "{{provider}} — Local Models",
    "localNoModels": "No downloaded models yet",
    "localRepoId": "Model Repository ID",
    "localRepoIdRequired": "Please enter a model repository ID",
    "localRepoIdPlaceholder": "e.g. Qwen/Qwen3-0.6B-GGUF",
    "localFilename": "Filename (optional)",
    "localFilenamePlaceholder": "e.g. mistral-7b.Q4_K_M.gguf",
    "localFilenameHint": "Leave empty to auto-select the best quantization",
    "localSource": "Source",
    "localDownloadSuccess": "Model downloaded successfully",
    "localDownloadFailed": "Failed to download model",
    "localDeleteModel": "Delete Model",
    "localDeleteConfirm": "Delete local model \"{{name}}\"? The model file will be removed from disk.",
    "localModelDeleted": "Model \"{{name}}\" deleted",
    "localDeleteFailed": "Failed to delete model",
    "localDownloadPending": "Preparing to download...",
    "localDownloading": "Downloading {{repo}}... This may take a few minutes.",
    "localDownloadNavigateHint": "You can navigate away — the download will continue in the background.",
    "localDownloadInProgress": "A download is already in progress",
    "localDownloaded": "Downloaded",
    "localNotDownloaded": "Not downloaded",
    "localNoRecommendedModels": "This device is not powerful enough to run local models",
    "localCancelDownloadTitle": "Cancel download",
    "localCancelDownloadAction": "Cancel download",
    "localCancelDownloadConfirm": "Cancel download of \"{{repo}}\"?",
    "localDownloadCancelled": "Download cancelled",
    "localCancelDownloadFailed": "Failed to cancel download",
    "localLlamacppName": "Inference engine",
    "localLlamacppInstallHint": "Install the local runtime before downloading or starting a model.",
    "localInstallLlamacpp": "Install llama.cpp",
    "localLlamacppInstallStarted": "llama.cpp download started",
    "localLlamacppInstallSuccess": "llama.cpp installed successfully",
    "localLlamacppInstallFailed": "Failed to install llama.cpp",
    "localRuntimeSectionTitle": "Inference Engine",
    "localRuntimeSectionDescription": "Powered by Llama.cpp",
    "localRuntimeComputeHint": "CPU is used by default. For GPU acceleration, use Ollama or LM Studio.",
    "localRuntimeInstalled": "Installed",
    "localRuntimeUpdateAvailable": "Update available",
    "localRuntimeUpdateAction": "Click to download the latest version",
    "localRuntimeUpdateConfirmTitle": "Confirm llama.cpp update",
    "localRuntimeUpdateConfirmContent": "Updating will overwrite the currently installed llama.cpp version. Confirm to start downloading and installing the latest version.",
    "localRuntimeUpdateConfirmContentWithServer": "Updating will overwrite the currently installed llama.cpp version and stop the currently running model service ({{model}}). Confirm to start downloading and installing the latest version.",
    "localRuntimeUnsupported": "Unsupported",
    "localRuntimeMissing": "Missing",
    "localServerRunningTitle": "Current local server",
    "localServerOnline": "Running",
    "localServerIdle": "Dead",
    "localServerUnavailable": "Issue",
    "localNoActiveModel": "No active model",
    "localNoDownloadedModelsHint": "Download a suitable model before starting the local inference service.",
    "localDownloadModelFirst": "Download the model first",
    "localEngineInstallStateLabel": "Install",
    "localEngineRunStateLabel": "Status",
    "localEngineCurrentModelLabel": "Current served model",
    "localEngineNextStepLabel": "Next step",
    "localEngineHealthLabel": "Engine health",
    "localEngineStatusHint": "Please download and start a suitable model from the list below",
    "localStartServer": "Start",
    "localStopServer": "Stop",
    "localServerStartFailed": "Failed to start local server",
    "localServerStopFailed": "Failed to stop local server",
    "localServerSwitchTitle": "Switch running model",
    "localServerSwitchConfirm": "The current server is running {{current}}. Switch to {{next}}?",
    "localSwitchModel": "Switch",
    "localModelPathMissing": "This downloaded model is missing a local path.",
    "localModelsSectionTitle": "Local Models",
    "localModelsSectionDescription": "Downloaded models can be started immediately. Only one model download and one local server instance can run at a time.",
    "localModelsLockedHint": "Please install llama.cpp first",
    "localAlternativeRuntimeHint": "Please try Ollama or LM Studio",
    "localModelsCount": "Downloaded {{downloaded}} / {{total}}",
    "localCurrentDownloadTitle": "Current download",
    "localAdvancedConfigTitle": "Advanced Local Settings",
    "localAdvancedConfigDescription": "These settings apply to the embedded local inference runtime. Max context length changes take effect the next time the local server starts.",
    "localAdvancedConfigSaved": "Advanced local settings saved",
    "localAdvancedConfigSaveFailed": "Failed to save advanced local settings",
    "localMaxContextLengthLabel": "Max Context Length",
    "localMaxContextLengthHint": "Maximum token count for the model context window, determining how much history fits in each request. Changes take effect the next time the local server starts.",
    "localMaxContextLengthRequired": "Please enter max context length",
    "localMaxContextLengthMin": "Max context length must be at least {{min}}",
    "localMaxContextLengthPlaceholder": "Enter max context length",
    "localServerPortLabel": "Server Port",
    "localServerPortHint": "Leave this empty to let llama.cpp bind an available port automatically. Enter a port to reuse that fixed port on future startups. Changes take effect the next time the local server starts.",
    "localServerPortRange": "Server port must be between {{min}} and {{max}}",
    "localServerPortPlaceholder": "Leave empty to auto-select a port",
    "localGenerateConfigHint": "Configure local model generation parameters as a JSON object. These fields will be expanded into subsequent generation requests.",
    "localCustomModelTitle": "Custom model download",
    "localCustomModelHint": "Enter a model repository ID. GGUF format only.",
    "localSourceHuggingFace": "Hugging Face",
    "localSourceModelScope": "ModelScope",
    "ollamaModelNamePlaceholder": "e.g. mistral:7b, qwen3:8b",
    "testConnection": "Test Connection",
    "testConnectionSuccess": "Connection test successful",
    "testConnectionFailed": "Connection test failed",
    "testConnectionFailedWithMessage": "Connection test failed: {{message}}",
    "testConnectionError": "An error occurred while testing connection",
    "discoverModels": "Discover Models",
    "discoverModelsFailed": "Failed to discover models",
    "ollamaFetchModelsFailed": "Failed to fetch Ollama models. Please check the error details.",
    "modelTestFailed": "Model validation failed, please check if the model ID is correct",
    "modelTestFailedConfirm": "Model connection test failed: {{message}}. Do you still want to add this model?",
    "autoDiscoveredAndAdded": "Auto-discovered {{count}} models and added {{added}} new model(s)",
    "autoDiscoveredNoNew": "Auto-discovered {{count}} models; model list is already up to date",
    "autoDiscoverFailed": "Automatic model discovery failed; you can add models manually",
    "tagImage": "Image",
    "tagVideo": "Video",
    "tagTextOnly": "Text Only",
    "tagMultimodal": "Multimodal",
    "tagVision": "Vision",
    "tagText": "Text",
    "free": "Free",
    "probeMultimodal": "Test Multimodal",
    "probeImage": "Image",
    "probeVideo": "Video",
    "probeSupported": "Supported: {{types}}",
    "probeNotSupported": "This model does not support multimodal input",
    "probeFailed": "Probe failed",
    "tagNotProbed": "Not Probed",
    "modalityVision": "Image",
    "modalityAudio": "Audio",
    "modalityVideo": "Video",
    "modalityFile": "File",
    "modalityText": "Text only",
    "perMillionIn": "/1M in",
    "perMillionOut": "/1M out"
  },
  "agentConfig": {
    "title": "Configuration",
    "description": "Configure agent runtime parameters",
    "reactAgentTitle": "ReAct Agent",
    "llmRetryTitle": "LLM Auto Retry",
    "llmRetryEnabled": "Enable Auto Retry",
    "llmRetryEnabledTooltip": "Automatically retry transient LLM API failures such as rate limits, timeouts, or connection errors. Applies to new requests after saving.",
    "llmMaxRetries": "Max Retries",
    "llmMaxRetriesTooltip": "Maximum number of extra retry attempts for a retryable LLM request failure.",
    "llmMaxRetriesPlaceholder": "Enter max retries",
    "llmMaxRetriesRequired": "Max retries is required",
    "llmMaxRetriesMin": "Max retries must be at least 1",
    "llmBackoffBase": "Backoff Base Delay (s)",
    "llmBackoffBaseTooltip": "Base delay before the first retry. Later retries use exponential backoff from this value.",
    "llmBackoffBasePlaceholder": "Enter base delay",
    "llmBackoffBaseRequired": "Backoff base delay is required",
    "llmBackoffBaseMin": "Backoff base delay must be at least 0.1 seconds",
    "llmBackoffCap": "Backoff Max Delay (s)",
    "llmBackoffCapTooltip": "Maximum cap for exponential retry backoff delays.",
    "llmBackoffCapPlaceholder": "Enter max delay",
    "llmBackoffCapRequired": "Backoff max delay is required",
    "llmBackoffCapMin": "Backoff max delay must be at least 0.5 seconds",
    "llmBackoffCapGteBase": "Backoff max delay must be greater than or equal to the base delay",
    "llmRateLimiterTitle": "LLM Rate Limiter",
    "llmMaxConcurrent": "Max Concurrent Calls",
    "llmMaxConcurrentTooltip": "Maximum number of LLM calls allowed in-flight at the same time. Shared across all agents; only the first initialization takes effect until restart.",
    "llmMaxConcurrentPlaceholder": "Enter max concurrent calls",
    "llmMaxConcurrentRequired": "Max concurrent calls is required",
    "llmMaxConcurrentRange": "Max concurrent calls must be at least 1",
    "llmMaxQpm": "Max QPM (Queries Per Minute)",
    "llmMaxQpmTooltip": "Maximum requests allowed within a 60-second sliding window. Requests exceeding this limit wait before being dispatched — proactively preventing 429 rate-limit errors. 0 = disabled.",
    "llmMaxQpmPlaceholder": "Enter max QPM (0 = unlimited)",
    "llmMaxQpmRequired": "Max QPM is required",
    "llmMaxQpmRange": "Max QPM must be at least 0",
    "llmRateLimitPause": "Rate Limit Pause (s)",
    "llmRateLimitPauseTooltip": "Default pause duration (seconds) applied globally when a 429 rate-limit response is received. Overridden by the API's Retry-After header when present.",
    "llmRateLimitPausePlaceholder": "Enter pause duration",
    "llmRateLimitPauseRequired": "Rate limit pause is required",
    "llmRateLimitPauseMin": "Rate limit pause must be at least 1 second",
    "llmRateLimitJitter": "Rate Limit Jitter (s)",
    "llmRateLimitJitterTooltip": "Random jitter range (seconds) added on top of the pause so concurrent waiters stagger their wake-up and avoid a new burst.",
    "llmRateLimitJitterPlaceholder": "Enter jitter range",
    "llmRateLimitJitterRequired": "Rate limit jitter is required",
    "llmRateLimitJitterMin": "Rate limit jitter must be at least 0 seconds",
    "llmAcquireTimeout": "Slot Acquire Timeout (s)",
    "llmAcquireTimeoutTooltip": "Maximum time (seconds) a caller will wait to acquire a rate-limiter slot before giving up with an error.",
    "llmAcquireTimeoutPlaceholder": "Enter acquire timeout",
    "llmAcquireTimeoutRequired": "Slot acquire timeout is required",
    "llmAcquireTimeoutMin": "Slot acquire timeout must be at least 10 seconds",
    "llmAcquireTimeoutGtPauseJitter": "Slot acquire timeout must be greater than rate limit pause + jitter",
    "contextManagementTitle": "Context Management",
    "memoryManagerBackend": "Long-term Memory Management Backend",
    "memoryManagerBackendTooltip": "Backend for the memory manager. Choose remelight (local files), adbpg (cloud database), or none (disable memory).",
    "memoryManagerBackendRestartWarning": "Switching the long-term memory management backend does not support hot reload. Save and restart QwenPaw for changes to take effect.",
    "maxIters": "Max Iterations",
    "maxItersTooltip": "Maximum number of reasoning-acting iterations for ReAct agent",
    "maxItersPlaceholder": "Enter max iterations",
    "maxItersRequired": "Max iterations is required",
    "maxItersMin": "Max iterations must be at least 1",
    "agentLoopTitle": "Agent Loop Settings",
    "loopMode": {
      "builtIn": "Built-in",
      "builtInNote": "Pipeline locked · Values editable",
      "templateSectionTitle": "Loop templates",
      "templateSectionDescription": "Choose a built-in template or add your own.",
      "defaultTab": "Default",
      "goalTab": "Goal",
      "missionTab": "Mission",
      "defaultDescription": "The standard guarded ReAct loop used outside an explicit mode.",
      "goalDescription": "A bounded persistent loop for concrete, verifiable goals.",
      "missionDescription": "A persistent pipeline for longer-running, multi-step missions.",
      "gatePipeline": "Gate pipeline",
      "repetitionTitle": "Repetition protection",
      "repetitionDescription": "Detect repeated tool calls and intervene.",
      "iterationTitle": "Iteration limit",
      "iterationDescription": "Bound the number of ReAct iterations.",
      "retryTitle": "Qualitative completion check",
      "retryDescription": "Triggered when the agent produces a text response without tool calls.",
      "goalTurnTitle": "Goal turn limit",
      "goalTurnDescription": "Limit turns within one active goal.",
      "maxGoalTurns": "Maximum goal turns",
      "goalBudgetTitle": "Goal token budget",
      "goalBudgetDescription": "Stop when the complete goal reaches its budget.",
      "maxGoalTokens": "Maximum goal tokens",
      "goalCompletionTitle": "Goal completion check",
      "goalCompletionDescription": "Read the explicit goal status before stopping.",
      "goalCompletionReadOnly": "Completion is controlled by the built-in goal status protocol.",
      "missionProgressTitle": "Mission progress check",
      "missionProgressDescription": "Continue until mission stories pass or the limit is reached.",
      "missionProgressReadOnly": "Completion is controlled by the built-in Mission story status.",
      "missionIterationTitle": "Mission iteration limit",
      "missionIterationDescription": "Set the default execution limit for new Missions.",
      "workerAttemptsTitle": "Worker attempts",
      "workerAttemptsDescription": "Limit Worker retries after a Story fails verification.",
      "missionVerificationTitle": "Mission verification policy",
      "missionVerificationDescription": "Define the default verification guidance and test command.",
      "defaultMaxMissionIterations": "Default maximum execution rounds",
      "defaultMaxMissionIterationsTooltip": "Used when /mission does not specify --max-iterations.",
      "maxRetriesPerStory": "Maximum retries per Story",
      "maxRetriesPerStoryTooltip": "Worker retries after a failed or partial Verifier result.",
      "defaultVerificationInstructions": "Verification guidance (optional)",
      "defaultVerificationInstructionsHelp": "Natural-language guidance applied to every Mission verifier.",
      "defaultVerificationInstructionsPlaceholder": "For example: Check Windows path handling and inspect the rendered UI.",
      "defaultVerifyCommand": "Default test command (optional)",
      "defaultVerifyCommandHelp": "The verifier attempts this through normal tools and permissions. /mission --verify overrides it.",
      "defaultVerifyCommandPlaceholder": "For example: pytest -q",
      "enableRepetitionProtection": "Enable repetition protection",
      "removeRule": "Remove rule",
      "custom": "Custom",
      "customDescription": "Build a saved pipeline from QwenPaw-owned gates.",
      "duplicate": "Duplicate",
      "delete": "Delete",
      "displayName": "Display name",
      "duplicateModeName": "A loop mode with this name already exists.",
      "slashCommand": "Slash command",
      "description": "Description",
      "availableToAgent": "Available to this agent",
      "runsTopToBottom": "Runs from top to bottom",
      "addGate": "Add gate",
      "emptyPipeline": "Add at least one Gate to make this mode available.",
      "iterationGateTitle": "Iteration limit",
      "iterationGateDescription": "Stop after a fixed number of loop iterations.",
      "doomGateTitle": "Repetition protection",
      "doomGateDescription": "Detect repeated tool calls and change strategy.",
      "tokenGateTitle": "Token budget",
      "tokenGateDescription": "Limit prompt and completion token usage.",
      "timeoutGateTitle": "Loop time limit",
      "timeoutGateDescription": "Stop at the next Loop boundary after elapsed time; running work is not interrupted.",
      "toolBudgetGateTitle": "Tool-call budget",
      "toolBudgetGateDescription": "Limit all calls and selected tools.",
      "retryGateTitle": "Early-stop retry",
      "retryGateDescription": "Prompt the agent to verify before ending.",
      "rubricGateTitle": "Completion rubric",
      "rubricGateDescription": "Evaluate explicit criteria and revise when needed.",
      "qualitativeRubricTitle": "Qualitative completion check",
      "qualitativeRubricDescription": "Check text responses without tool calls using natural-language criteria.",
      "qualitativeRubric": "Natural-language completion criteria",
      "qualitativeRubricHelp": "Triggered only for text responses without tool calls. The agent continues when work remains.",
      "completionRubricTitle": "Completion signal check",
      "completionRubricDescription": "Check text responses without tool calls for a completion signal.",
      "completionRubricHelp": "Triggered after text responses without tool calls. The agent outputs the completion signal when done; otherwise it keeps working until the maximum evaluation rounds is reached.",
      "completionPrompt": "Completion check prompt",
      "completionPromptHelp": "Describe when the result is complete. QwenPaw automatically injects the completion-signal output instruction.",
      "completionSignal": "Completion signal",
      "completionSignalHelp": "QwenPaw injects this signal into the check prompt and instructs the agent to output only it. Matching is exact after trimming whitespace and ignoring case.",
      "removeCriterion": "Remove criterion {{number}}",
      "totalTokensHelp": "Maximum combined input and output tokens used by this turn.",
      "promptTokensHelp": "Includes system instructions, conversation context, tool schemas, and tool results.",
      "completionTokensHelp": "Maximum tokens generated by the model during this turn.",
      "maxIterations": "Maximum iterations",
      "historyWindow": "History window",
      "similarityThreshold": "Similarity threshold",
      "totalTokens": "Maximum total tokens",
      "promptTokens": "Maximum input tokens",
      "completionTokens": "Maximum output tokens",
      "maxSeconds": "Maximum seconds",
      "maxSecondsHelp": "Elapsed time is checked after the current model response or tool call completes. Running work is not interrupted.",
      "allToolCalls": "All tool calls",
      "perToolLimits": "Per-tool limits",
      "toolName": "Tool name",
      "callLimitAria": "{{name}} call limit",
      "removeToolLimitAria": "Remove {{name}} limit",
      "addToolLimit": "Add per-tool limit",
      "maxRetries": "Maximum retries",
      "retryInstruction": "Retry instruction",
      "passThreshold": "Pass threshold",
      "maxEvaluations": "Maximum evaluation rounds",
      "graderError": "Grader error",
      "stopSafely": "Stop safely",
      "verifyOnceMore": "Verify once more",
      "completionCriteria": "Completion criteria",
      "criterionPlaceholder": "Describe observable completion",
      "required": "Required",
      "weight": "Weight",
      "addCriterion": "Add criterion",
      "moveGateAria": "Move {{title}}",
      "removeGate": "Remove gate",
      "newModeName": "New Loop Mode",
      "defaultCustomDescription": "A custom gate pipeline.",
      "copyName": "{{name}} Copy",
      "createModeAria": "Create custom loop mode",
      "createModeTitle": "Create custom loop mode",
      "startingTemplate": "Starting template",
      "startingPipeline": "Starting pipeline",
      "blankPipelineHint": "Start empty and add gates later",
      "safeTemplate": "Safe run",
      "researchTemplate": "Budgeted research",
      "qualityTemplate": "Quality first",
      "blankTemplate": "Blank pipeline"
    },
    "doomLoopEnabled": "Repetition Protection",
    "doomLoopEnabledTooltip": "Automatically intervene when the agent gets stuck repeating the same actions",
    "doomLoopAfter": "After",
    "doomLoopRepetitions": "identical actions",
    "doomLoopStopAction": "Pause & Ask for Help",
    "doomLoopWarnAction": "Send Reminder",
    "doomLoopSimpleMode": "Simple",
    "doomLoopAdvancedMode": "Advanced",
    "doomLoopWindowSize": "Detection Range",
    "doomLoopWindowSizeTooltip": "How many recent actions to check for repetition",
    "doomLoopSimilarity": "Match Sensitivity",
    "doomLoopSimilarityTooltip": "How similar actions must be to count as repetition (lower = stricter)",
    "doomLoopStages": "Intervention Rules",
    "doomLoopAction": "Action",
    "doomLoopPrompt": "Message",
    "doomLoopPromptPlaceholder": "Reminder message or pause reason...",
    "doomLoopAddStage": "Add Rule",
    "iterationTitle": "Iteration Limit",
    "iterationEnabled": "Enable Iteration Limit",
    "iterationEnabledTooltip": "Stop the agent after a fixed number of loop turns",
    "iterationMaxIterations": "Maximum Iterations",
    "iterationMaxIterationsTooltip": "Maximum number of loop turns before stopping",
    "rubricTitle": "Qualitative Completion Check",
    "rubricEnabled": "Enable Qualitative Completion Check",
    "rubricEnabledTooltip": "Triggered only when the agent produces a text response without tool calls.",
    "rubricPrompt": "Natural-Language Completion Criteria",
    "rubricPromptTooltip": "The prompt injected to ask the agent to evaluate task completion",
    "rubricDesc": "When the agent produces a text response without tool calls, apply natural-language completion criteria and ask it to continue when work remains.",
    "rubricPromptPlaceholder": "You did not call any tool. If the task is complete, confirm. Otherwise, continue with tool calls.",
    "rubricMaxInterventions": "Maximum Evaluation Rounds",
    "rubricMaxInterventionsTooltip": "Maximum completion checks for text responses without tool calls during one turn.",
    "inLoopModes": "Enable in /goal & /mission modes",
    "inLoopModesTooltip": "Also apply this gate when /goal or /mission loop mode is active",
    "comingSoonEditable": "Custom configuration will be available in a future release.",
    "simpleMode": "Simple",
    "advancedMode": "Advanced",
    "comingSoon": "Coming Soon",
    "reactModeTab": "Loop Template - Default",
    "goalModeTab": "Loop Template - Goal",
    "missionModeTab": "Loop Template - Mission",
    "goalModeInfoTitle": "Goal Mode vs Default",
    "goalModeInfo": "Default mode stops after producing a reply. Goal mode keeps the agent looping toward a goal, using Rubric evaluation to determine completion. All operations run within the current agent context.",
    "missionModeInfoTitle": "Mission Mode vs Goal Mode",
    "missionModeInfo": "Mission mode auto-decomposes complex tasks into sub-tasks, executed by independent Worker sub-agents and verified by Verifier sub-agents. Each sub-task runs in its own context, preventing context pollution of the main session. Best for complex multi-step engineering tasks.",
    "goalIterationGate": "Goal Iteration Gate",
    "goalIterationGateDesc": "Limits the number of agent turns within a goal session. Tracks iteration count and token usage.",
    "goalBudgetGate": "Token Budget Gate",
    "goalBudgetGateDesc": "Enforces a token spending limit for the goal session. Stops the agent when budget is exceeded.",
    "goalRubricGate": "Goal Completion Rubric",
    "goalRubricGateDesc": "Evaluates whether the goal has been achieved by checking the session status.",
    "goalDoomGate": "Repetition Protection",
    "goalDoomGateDesc": "Detects repetitive patterns during goal execution and triggers intervention.",
    "missionProgressGate": "Mission Progress Gate",
    "missionProgressGateDesc": "Tracks PRD user story completion. Continues until all stories pass or max iterations reached.",
    "missionIterBypass": "Iteration Bypass",
    "missionIterBypassDesc": "Temporarily lifts the ReAct iteration limit during mission execution to allow long-running phases.",
    "customLoopTitle": "Custom Loop Modes",
    "customLoopDesc": "Create your own loop modes with custom gate combinations. Coming soon.",
    "autoGenerateSessionTitle": "Auto-generate session titles",
    "autoGenerateSessionTitleTooltip": "After the first user message in a new chat, run a short background LLM call to replace the truncated placeholder with a concise title. Costs one extra short LLM call per new chat. Turn off to keep the placeholder and skip the spend.",
    "shellCommandTimeout": "Shell Command Timeout (s)",
    "shellCommandTimeoutTooltip": "Default timeout in seconds for the execute_shell_command tool. The LLM can still override this per-call via the timeout parameter. Useful for long-running tasks like compilation or data processing.",
    "shellCommandTimeoutPlaceholder": "Enter timeout",
    "shellCommandTimeoutRequired": "Shell command timeout is required",
    "shellCommandTimeoutMin": "Shell command timeout must be at least 1 second",
    "shellCommandExecutable": "Shell Executable",
    "shellCommandExecutableTooltip": "Path to the shell used by execute_shell_command. Linux/macOS: e.g. /bin/bash, /bin/zsh. Windows: supports powershell.exe, pwsh.exe, or POSIX-like shells such as Git Bash. When empty, falls back to the $SHELL environment variable, then to the platform default (/bin/sh on Unix, cmd.exe on Windows).",
    "shellCommandExecutablePlaceholder": "e.g. /bin/bash or powershell.exe (empty = auto-detect)",
    "maxInputLength": "Max Input Length",
    "maxInputLengthTooltip": "Maximum input length (tokens) for the model context window",
    "maxInputLengthPlaceholder": "Enter max input length",
    "maxInputLengthRequired": "Max input length is required",
    "maxInputLengthMin": "Max input length must be at least 1000",
    "contextCompactRatio": "Compaction Threshold Ratio",
    "contextCompactRatioTooltip": "Compaction is triggered when the context length reaches this fraction of the max context length",
    "contextCompactRatioRequired": "Context compact ratio is required",
    "contextCompactThreshold": "Compaction Threshold (tokens)",
    "contextCompactThresholdTooltip": "Auto-calculated from max context length × compaction ratio. Compaction triggers when context exceeds this value.",
    "contextCompactThresholdPlaceholder": "Auto-calculated",
    "contextCompactReserveRatio": "Reserve Threshold Ratio",
    "contextCompactReserveRatioTooltip": "Calculates the target recent-tail budget. Scroll also applies a minimum recent budget and a 40K cap, and always keeps the complete active turn.",
    "contextCompactReserveRatioRequired": "Context reserve ratio is required",
    "contextCompactReserveThreshold": "Reserve Threshold (tokens)",
    "contextCompactReserveThresholdTooltip": "The effective target used to split the recent tail. This is a soft target; boundary messages and the complete active turn may increase the retained amount.",
    "contextCompactReserveThresholdPlaceholder": "Auto-calculated",
    "toolResultCompactRecentN": "Recent Tool Results Range",
    "toolResultCompactRecentNTooltip": "Number of recent tool-result-bearing messages that use the larger recent preview limit in Native context mode",
    "toolResultCompactRecentNRequired": "Recent tool results range is required",
    "toolResultCompactOldThreshold": "Older Tool Result Preview Bytes",
    "toolResultCompactOldThresholdTooltip": "Maximum preview bytes for older tool results in Native context mode.",
    "toolResultCompactOldThresholdPlaceholder": "Enter preview byte limit",
    "toolResultCompactOldThresholdRequired": "Older tool result preview bytes is required",
    "toolResultCompactRecentThreshold": "Recent Tool Result Preview Bytes",
    "toolResultCompactRecentThresholdTooltip": "Maximum preview bytes before a tool result enters agent context. In Scroll mode, this also limits each recall_history page and read_file response.",
    "toolResultCompactRecentThresholdPlaceholder": "Enter preview byte limit",
    "toolResultCompactRecentThresholdRequired": "Recent tool result preview bytes is required",
    "toolResultCompactRetentionDays": "Complete Tool Result Retention Days",
    "toolResultCompactRetentionDaysTooltip": "Independent retention period for complete tool result artifacts. After cleanup, history.db may still retain a bounded preview.",
    "toolResultCompactRetentionDaysRequired": "Complete tool result retention days is required",
    "historyRetentionDays": "History Retention Days",
    "historyRetentionDaysTooltip": "Days of durable chat history to keep. Older rows are purged automatically on startup and on agent teardown.",
    "historyRetentionDaysRequired": "History retention days is required",
    "historyRetentionDaysForeverWarning": "Set to 0 keeps history forever — storage will grow without bound.",
    "historyRetentionDaysLargeWarning": "A large retention window may consume significant storage.",
    "exemptFileExtensions": "Exempt File Extensions",
    "exemptFileExtensionsTooltip": "In Native context mode, read_file results for these extensions always use the larger recent preview limit",
    "exemptFileExtensionsPlaceholder": ".md, .txt, .json",
    "exemptToolNames": "Exempt Tool Names",
    "exemptToolNamesTooltip": "In Native context mode, results from these tools always use the larger recent preview limit",
    "exemptToolNamesPlaceholder": "chat_with_agent, list_agents",
    "language": "Agent Language",
    "languageTooltip": "Language for agent persona files (SOUL.md, AGENTS.md, etc.). Changing this will re-copy MD files in the selected language.",
    "languageConfirmTitle": "Change Agent Language",
    "languageConfirmContent": "Changing the language will overwrite the following files with the new language version:\n\n  SOUL.md, AGENTS.md, PROFILE.md, MEMORY.md, BOOTSTRAP.md, HEARTBEAT.md\n\nIf you have customized any of these files, please back them up first. Your other files will not be affected.",
    "languageConfirmOk": "Change Language",
    "languageSaveSuccess": "Language updated successfully",
    "languageSaveSuccessWithFiles": "Language updated, {{count}} MD file(s) copied",
    "languageSaveFailed": "Failed to update language",
    "saveSuccess": "Configuration saved successfully",
    "saveFailed": "Failed to save configuration",
    "timezone": "User Timezone",
    "timezoneTooltip": "Used for scheduled tasks, time display, and agent context. Defaults to your system timezone.",
    "timezoneRequired": "Please select a timezone",
    "selectTimezone": "Select timezone",
    "timezoneSaveSuccess": "Timezone updated successfully",
    "timezoneSaveFailed": "Failed to update timezone",
    "loadFailed": "Failed to load configuration",
    "historyMaxLength": "Max History Length",
    "historyMaxLengthTooltip": "Maximum output length (characters) for the /history command",
    "historyMaxLengthRequired": "Max history length is required",
    "historyMaxLengthMin": "Max history length must be at least 1000",
    "historyMaxLengthPlaceholder": "Enter max length",
    "contextCompactTitle": "Context Compact Config",
    "contextCompactEnabled": "Enable Context Compaction",
    "contextCompactEnabledTooltip": "Automatically compact the context to prevent context window overflow",
    "tokenCountModel": "Token Count Model",
    "tokenCountModelTooltip": "Model name used for precise token counting; set to \"default\" to use built-in estimation",
    "tokenCountModelPlaceholder": "Model name or default",
    "tokenCountUseMirror": "Use HuggingFace Mirror",
    "tokenCountUseMirrorTooltip": "Use a HuggingFace mirror site when downloading tokenizers",
    "tokenCountEstimateDivisor": "byte/Token Estimate Divisor",
    "tokenCountEstimateDivisorTooltip": "Divisor for byte-based token estimation (tokens ≈ byte_length / divisor). Recommended value: 3.75 ~ 4.",
    "tokenCountEstimateDivisorRequired": "Estimate divisor is required",
    "tokenCountEstimateDivisorMin": "Estimate divisor must be between 2 and 5",
    "toolResultCompactTitle": "Tool Result Compact Config",
    "toolResultCompactEnabled": "Enable Tool Result Compaction",
    "toolResultCompactEnabledTooltip": "Compact oversized tool call results to save context space",
    "memorySummaryTitle": "Long-term Memory Config",
    "memorySummaryEnabled": "Activate Memory Summary",
    "memorySummaryEnabledTooltip": "Automatically generate and save memory summaries during context compaction",
    "dreamCronEnabled": "Enable Dream",
    "dreamCronEnabledTooltip": "Enable the scheduled dream-based memory optimization job",
    "dreamCron": "Dream Schedule",
    "dreamCronTooltip": "Cron expression for periodically optimizing long-term memories through dream state. Scheduled runs start after a random delay of 0–60 seconds to avoid simultaneous calls; use the switch above to enable or disable it",
    "dreamCronPlaceholder": "0 23 * * *",
    "dreamCronRequired": "Enter a cron expression when Dream is enabled",
    "dreamCronInvalid": "Enter a valid 5-field cron expression",
    "autoMemorySearch": "Auto Memory Search (Beta)",
    "autoMemorySearchTooltip": "Auto memory search to run on every conversation turn. Each query will automatically invoke memory search capabilities, helping QwenPaw understand you better — but this increases token consumption.",
    "autoMaxResults": "Auto Search Max Results",
    "autoMaxResultsTooltip": "Maximum number of results returned when auto memory search is enabled",
    "autoMaxResultsRequired": "Max results is required",
    "autoMaxResultsMin": "Max results must be at least 1",
    "embeddingConfigTitle": "Embedding Model Config",
    "embeddingBackend": "Embedding SDK Type",
    "embeddingBackendTooltip": "SDK type used to call the embedding model",
    "embeddingBackendPlaceholder": "Select an SDK type",
    "embeddingApiKey": "API Key",
    "embeddingApiKeyTooltip": "API key for the embedding provider; leave blank if no authentication is required",
    "embeddingApiKeyPlaceholder": "Leave blank if not required",
    "embeddingBaseUrl": "Base URL",
    "embeddingBaseUrlTooltip": "Base URL of the embedding API. For OpenAI-compatible backends, this custom endpoint is optional; API Key and Model Name are required.",
    "embeddingBaseUrlPlaceholder": "https://dashscope.aliyuncs.com/compatible-mode/v1",
    "embeddingHost": "Host",
    "embeddingHostTooltip": "Ollama host URL. Leave blank to use Ollama's default host.",
    "embeddingHostPlaceholder": "http://localhost:11434",
    "embeddingModelName": "Model Name",
    "embeddingModelNameTooltip": "Embedding model name. Required for every embedding backend.",
    "embeddingModelNamePlaceholder": "text-embedding-v4",
    "embeddingEnableCache": "Enable Embedding Cache",
    "embeddingEnableCacheTooltip": "Cache embedding results to reduce repeated computation",
    "embeddingMaxCacheSize": "Max Cache Size",
    "embeddingMaxCacheSizeTooltip": "Maximum number of entries in the embedding cache",
    "embeddingMaxCacheSizeRequired": "Max cache size is required",
    "embeddingUseDimensions": "Use Custom Dimensions",
    "embeddingUseDimensionsTooltip": "Use custom embedding dimensions (only supported by some models)",
    "embeddingDimensions": "Embedding Dimensions",
    "embeddingDimensionsTooltip": "Number of embedding dimensions; takes effect when custom dimensions are enabled",
    "embeddingDimensionsRequired": "Embedding dimensions is required",
    "embeddingDimensionsMin": "Dimensions must be at least 1",
    "embeddingMaxInputLength": "Max Input Length",
    "embeddingMaxInputLengthTooltip": "Maximum input length (tokens) for a single embedding request",
    "embeddingMaxInputLengthRequired": "Max input length is required",
    "embeddingMaxBatchSize": "Max Batch Size",
    "embeddingMaxBatchSizeTooltip": "Maximum number of items in a single batch embedding request",
    "embeddingMaxBatchSizeRequired": "Max batch size is required",
    "embeddingRestartWarning": "Embedding model config does not support hot reload. Save and restart the service for changes to take effect.",
    "toolExecutionLevelTitle": "Tool Execution Security",
    "toolExecutionLevel": {
      "title": "Tool Execution Security",
      "alertMessage": "Configure tool call approval policy to control the security level when agents execute tools",
      "strict": "Strict Mode",
      "strictDesc": "All tool calls require approval, highest security level",
      "smart": "Smart Mode",
      "smartDesc": "Low-risk tools auto-approved, medium+ risk tools require approval",
      "auto": "Auto Mode",
      "autoDesc": "Only tools explicitly marked for approval require approval (default)",
      "off": "Off Mode",
      "offDesc": "Disable all tool approvals, all tools execute automatically"
    },
    "saveLevelSuccess": "Tool execution security level saved",
    "saveLevelFailed": "Failed to save tool execution security level",
    "maxContextLength": "Max Context Length",
    "maxContextLengthTooltip": "Maximum token count for the model context window, determining how much history fits in each request",
    "maxContextLengthRequired": "Max context length is required",
    "maxContextLengthMin": "Max context length must be at least 1000",
    "maxContextLengthPlaceholder": "Enter max context length",
    "embeddingActivationNote": "Embedding is enabled when the selected backend has the required fields.",
    "embeddingEnableHint": "Embedding is enabled when the selected backend has the required fields: Model Name plus API Key for OpenAI-compatible or Gemini backends; Model Name for Ollama.",
    "rebuildMemoryIndex": "Rebuild Memory Index",
    "rebuildMemoryIndexWarning": "This clears and rebuilds the memory search index and may consume significant CPU and memory. Use it only to repair a damaged index or abnormal search results.",
    "rebuildMemoryIndexConfirmTitle": "Rebuild the memory index?",
    "rebuildMemoryIndexConfirm": "CPU and memory usage may increase significantly during the rebuild. This is not recommended unless the index is damaged or needs repair.",
    "rebuildMemoryIndexSuccess": "Memory index rebuild completed",
    "rebuildMemoryIndexFailed": "Memory index rebuild failed: {{error}}",
    "toolResultCompactRecentGtOld": "Recent tool result preview bytes must be greater than or equal to compact preview bytes",
    "lightContextTitle": "Context Management",
    "remeLightMemoryTitle": "Long-term Memory",
    "dialogPath": "Dialog Storage Path",
    "dialogPathTooltip": "Relative path for dialog persistence storage (relative to working_dir)",
    "dialogPathPlaceholder": "dialog",
    "contextCompactCollapseLabel": "Context Compaction",
    "toolResultPruningCollapseLabel": "Tool Result Pruning",
    "autoMemorySearchCollapseLabel": "Auto Memory Search",
    "embeddingConfigCollapseLabel": "Embedding Model Config",
    "summarizeWhenCompact": "Memory on Compact",
    "summarizeWhenCompactTooltip": "Automatically generate and save memory during context compaction",
    "inboxPushEnabled": "Memory Result Inbox Notifications",
    "inboxPushEnabledTooltip": "Push auto-memory, auto-dream, and auto-resource results to the inbox. Disable this to reduce inbox messages without stopping the memory jobs.",
    "autoMemoryInterval": "Auto Memory Interval",
    "autoMemoryIntervalTooltip": "Trigger auto memory every N user queries. 0 disables periodic auto memory. 1 means auto memory after every query. Recommended: 2-5; setting 1 requires attention to high token usage.",
    "autoMemoryIntervalPlaceholder": "Enter 0 to disable periodic auto memory",
    "autoMemoryIntervalRequired": "Auto memory interval is required",
    "autoMemoryIntervalMin": "Auto memory interval must be at least 0",
    "contextManagerBackend": "Context Manager Backend",
    "contextManagerBackendTooltip": "Backend type for the context manager. Currently only Light is supported.",
    "contextStrategy": "Context Strategy",
    "contextStrategyTooltip": "How the agent manages long context. Scroll (recommended) persists evicted turns to a durable history store and recalls them on demand; Native uses in-place compression. Restart QwenPaw for changes to take effect.",
    "contextStrategyScroll": "Scroll",
    "contextStrategyNative": "Native",
    "backendRestartWarning": "Switching backends does not support hot reload. Save and restart QwenPaw for changes to take effect.",
    "adbpgMemoryTitle": "ADBPG Long-term Memory",
    "adbpgConfig": {
      "title": "ADBPG Memory Configuration",
      "restBaseUrl": "REST Base URL",
      "restApiKey": "REST API Key",
      "memoryIsolation": "Memory Isolation (per-agent)",
      "searchTimeout": "Search Timeout"
    }
  },
  "tools": {
    "title": "Built-in Tools",
    "description": "Manage built-in tools and their enabled status. Disabled tools will not be available to the agent.",
    "emptyState": "No tools configured",
    "loadError": "Failed to load tools",
    "enableSuccess": "Tool enabled successfully",
    "disableSuccess": "Tool disabled successfully",
    "toggleError": "Failed to toggle tool status",
    "enableAll": "Enable All",
    "disableAll": "Disable All",
    "enableAllSuccess": "All tools enabled",
    "disableAllSuccess": "All tools disabled",
    "allEnabled": "All tools are already enabled",
    "allDisabled": "All tools are already disabled",
    "asyncExecution": "Async Execution",
    "asyncExecutionEnabled": "Async execution enabled",
    "asyncExecutionDisabled": "Async execution disabled",
    "configure": "Configure",
    "configured": "Configured",
    "requiresConfig": "Requires configuration",
    "configSaved": "Configuration saved",
    "configSaveError": "Failed to save configuration",
    "active": "active",
    "available": "Available",
    "noEnabled": "No tools enabled",
    "goEnableBtn": "Go enable",
    "configureAction": "Configure →",
    "enableAction": "Enable →"
  },
  "modelConfig": {
    "promptTitle": "LLM Model Required — Select in Chat After Configuration",
    "promptMessage": "Chat requires an LLM model to function. Please configure a model first, then select it from the model selector at the top of the Chat page.",
    "configureButton": "Configure Model",
    "skipButton": "Skip",
    "chatDisabledTitle": "Chat Disabled",
    "chatDisabledMessage": "Chat functionality is disabled because no model is configured. Please configure a model to enable chat.",
    "configureNow": "Configure Model",
    "modelNotConfigured": "Please configure a model in Settings before using chat"
  },
  "header": {
    "changelog": "Changelog",
    "docs": "Doc",
    "tutorial": "Tutorial",
    "featureDemos": "Feature Demos",
    "faq": "FAQ",
    "github": "GitHub",
    "resources": "Documentation",
    "updateAvailable": "Update Available"
  },
  "theme": {
    "dark": "Dark",
    "light": "Light",
    "system": "System"
  },
  "chat": {
    "modelSelectTooltip": "Select model",
    "newChatTooltip": "New chat",
    "searchTooltip": "Search all chats",
    "chatHistoryTooltip": "Chat history",
    "wideModeTooltip": "Wide mode",
    "normalModeTooltip": "Normal mode",
    "allChats": "All Chats",
    "createNewChat": "Create New Chat",
    "pinDrawer": "Pin",
    "unpinDrawer": "Unpin",
    "statusIdle": "Idle",
    "statusInProgress": "In progress",
    "disclaimer": "Works for you, grows with you",
    "greeting": "Hello, how can I help you today?",
    "description": "I am a helpful assistant that can help you with your questions.",
    "prompt1": "Let's start a new journey!",
    "prompt2": "Can you tell me what skills you have?",
    "inputPlaceholder": "\"↑↓\" for message navigation · \"/\" for quick commands (\"/approve\" or \"/deny\" during approvals)",
    "longTextUploadPrompt": "Please read the uploaded prompt file and answer it.",
    "emptyOutputError": "The assistant returned an empty response.",
    "commands": {
      "clear": {
        "description": "Clear the conversation context"
      },
      "compact": {
        "description": "Compact the conversation context; optional instruction supported"
      },
      "approve": {
        "description": "Approve the pending tool action and continue execution"
      },
      "deny": {
        "description": "Deny the pending tool action"
      },
      "mission": {
        "description": "Mission mode — Decomposes tasks into sub-agents with isolated context"
      },
      "skills": {
        "description": "List chat-available skills and expose explicit skill commands"
      },
      "plan": {
        "description": "Create a structured plan to decompose the task into subtasks"
      },
      "goal": {
        "description": "Goal loop — Agent pursues a goal continuously, auto-evaluates via Rubric"
      }
    },
    "attachments": {
      "tooltip": "Supports documents, images, videos, audio and more formats",
      "tooltipImageOnly": "Current model supports image upload only",
      "tooltipNoMultimodal": "No multimodal capability detected for current model, images or videos may not be processed correctly",
      "fileSizeLimit": "File size limit: {{limit}}MB",
      "fileSizeExceeded": "File size exceeds {{limit}}MB limit. Current file: {{size}}MB",
      "multimodalDisabled": "Current model does not support file upload",
      "multimodalWarning": "No multimodal capability detected for current model, images or videos may not be processed correctly",
      "imageOnlyAccept": "Current model only supports image files",
      "imageOnlyWarning": "Current model only supports images, non-image files like videos may not be processed correctly"
    },
    "rateLimitHit": "The current model is rate-limited. Try switching to another free model.",
    "turnUsagePopover": {
      "ariaLabel": "View turn token and context usage",
      "turn": "This turn",
      "turnEstimated": "This turn ~",
      "tok": "tok",
      "inOut": "in {{inTok}} · out {{outTok}}",
      "contextLabel": "Context window:",
      "manageContext": "Manage context",
      "compact": "Compact",
      "new": "New chat"
    },
    "rateLimitMessage": "Rate limit reached. Switch to another free model:",
    "rateLimitSwitched": "Switched to {{model}}",
    "speech": {
      "startRecording": "Start voice recording (Ctrl+Shift+M)",
      "stopRecording": "Stop recording (Ctrl+Shift+M)",
      "transcribing": "Transcribing...",
      "transcriptionDisabled": "Transcription is disabled. Configure a provider in Settings > Voice Transcription.",
      "transcriptionFailed": "Voice transcription failed",
      "microphoneError": "Could not access microphone",
      "fileTooLarge": "Recording file is too large ({{size}}MB). Maximum allowed: {{limit}}MB",
      "recordingTooLong": "Recording exceeds duration limit ({{limit}}s)"
    },
    "search": {
      "title": "Search Chat",
      "tooltip": "Search current chat",
      "placeholder": "Search messages...",
      "noResults": "No results found",
      "resultsCount": "Found {{count}} result(s)",
      "searching": "Searching {{progress}}...",
      "loading": "Loading...",
      "userMessage": "User",
      "assistantMessage": "Assistant",
      "titleMatch": "Title"
    },
    "contextMenu": {
      "open": "Open",
      "rename": "Rename",
      "pin": "Pin",
      "unpin": "Unpin",
      "delete": "Delete"
    },
    "queue": {
      "title": "Message Queue",
      "paused": "Paused",
      "sendFailed": "Send failed",
      "resume": "Resume queue",
      "pause": "Pause queue",
      "clear": "Clear queue",
      "dragSort": "Drag to reorder",
      "edit": "Edit",
      "retry": "Retry",
      "skip": "Skip",
      "interruptAndSend": "Interrupt & send",
      "delete": "Delete",
      "file": "File",
      "noChatWarning": "Please send a message first to create a conversation before using the queue",
      "queueFull": "Queue is full (max {{max}} items), please send or remove some messages first",
      "otherTabOwner": "This tab queues only; sending is handled by another tab"
    },
    "group": {
      "pinned": "Pinned",
      "today": "Today",
      "week": "Within 7 days",
      "month": "Within 30 days",
      "older": "Earlier"
    },
    "sessionPanel": {
      "searchConversations": "Search conversations…",
      "noResults": "No results",
      "noConversations": "No conversations yet",
      "loadingConversations": "Loading…"
    },
    "conversationHistory": "Conversation History",
    "history": {
      "empty": "No chat history"
    },
    "sessionGroup": {
      "today": "Today",
      "recent": "Last 7 days",
      "earlier": "Earlier"
    }
  },
  "security": {
    "parent": "Settings",
    "security": "Security",
    "title": "Security",
    "description": "Manage security features for tools and skills.",
    "toolGuardTitle": "Tool Guard",
    "toolGuardDescription": "Configure security scanning for tool calls. Dangerous operations will require your explicit approval before execution.",
    "enabled": "Enable Tool Guard",
    "enabledTooltip": "When enabled, tool calls are scanned for dangerous patterns before execution",
    "sandboxEnabled": "Enable Sandbox Execution",
    "sandboxEnabledTooltip": "When enabled, shell commands with no matching rule run silently inside the sandbox. When disabled, such commands run directly without the sandbox (no approval prompt). Either way, secret-file reads and dangerous commands (e.g. rm -rf /, sudo) are still blocked or require approval.",
    "sandboxDegradedWarning": "Sandbox is configured as enabled, but QwenPaw is not running as administrator. The sandbox will be inactive for this session. To use the sandbox, restart QwenPaw with administrator privileges.",
    "guardedTools": "Guarded Tools",
    "guardedToolsTooltip": "Tools that require approval when dangerous patterns are detected. Leave empty to use the built-in default set.",
    "guardedToolsPlaceholder": "Select tools or type custom tool names",
    "deniedTools": "Denied Tools",
    "deniedToolsTooltip": "Tools that are always rejected without asking for approval",
    "deniedToolsPlaceholder": "Select tools to always deny",
    "saveSuccess": "Tool guard settings saved",
    "saveFailed": "Failed to save tool guard settings",
    "loadFailed": "Failed to load tool guard settings",
    "rules": {
      "title": "Detection Rules",
      "description": "Rules define regex patterns that trigger security alerts. Built-in rules can be disabled; custom rules can be added, edited, or deleted.",
      "id": "Rule ID",
      "severity": "Severity",
      "descriptionCol": "Description",
      "source": "Source",
      "actions": "Actions",
      "builtin": "Built-in",
      "custom": "Custom",
      "enable": "Enable",
      "disable": "Disable",
      "edit": "Edit",
      "delete": "Delete",
      "add": "Add Rule",
      "addTitle": "Add Custom Rule",
      "editTitle": "Edit Custom Rule",
      "ruleId": "Rule ID",
      "ruleIdRequired": "Rule ID is required",
      "duplicateId": "A rule with this ID already exists",
      "tools": "Target Tools",
      "toolsPlaceholder": "Leave empty to match all tools",
      "params": "Target Parameters",
      "paramsPlaceholder": "Leave empty to match all parameters",
      "severityLabel": "Severity",
      "categoryLabel": "Category",
      "patterns": "Regex Patterns",
      "patternsRequired": "At least one pattern is required",
      "patternsTooltip": "One regex per line. Matched against tool parameter values (case-insensitive).",
      "excludePatterns": "Exclude Patterns",
      "excludePatternsTooltip": "One regex per line. If any matches, the rule is skipped for that value.",
      "descriptionLabel": "Description",
      "descriptionPlaceholder": "What does this rule detect?",
      "remediationLabel": "Remediation",
      "remediationPlaceholder": "Suggested action when this rule triggers",
      "preview": "Preview",
      "previewTitle": "Rule Details",
      "actionLabel": "Action",
      "actionApproval": "Require Approval",
      "autoDeny": "Auto Deny",
      "autoDenyTooltip": "When enabled, tool calls matching this rule will be automatically denied without requiring manual approval",
      "autoDenyEnable": "Enable auto deny for this rule",
      "autoDenyDisable": "Disable auto deny for this rule",
      "allTools": "All tools",
      "allParams": "All parameters",
      "descriptions": {
        "TOOL_CMD_CONTROL_CHARS": "Command contains non-printable control characters that could bypass security checks",
        "TOOL_CMD_DANGEROUS_MV": "Detects 'mv' command that may move or overwrite files unexpectedly",
        "TOOL_CMD_DANGEROUS_RM": "Detects 'rm' command that may cause data loss",
        "TOOL_CMD_DOS_FORK_BOMB": "Detects classic Bash fork bombs and mass process termination",
        "TOOL_CMD_FIND_DELETE": "Detects 'find -delete' command that may cause data loss",
        "TOOL_CMD_FS_DESTRUCTION": "Detects low-level disk formatting or wiping commands",
        "TOOL_CMD_IFS_INJECTION": "Command uses $IFS variable which could bypass security validation",
        "TOOL_CMD_JQ_FILE_FLAGS": "jq command uses flags that could read arbitrary files or execute external code",
        "TOOL_CMD_JQ_SYSTEM": "jq command contains system() function which can execute arbitrary shell commands",
        "TOOL_CMD_OBFUSCATED_EXEC": "Detects execution of base64 encoded strings passed directly to a shell interpreter",
        "TOOL_CMD_PIPE_TO_SHELL": "Detects 'curl | bash' patterns used to download and immediately execute remote payloads",
        "TOOL_CMD_PRIVILEGE_ESCALATION": "Detects privilege escalation attempts using sudo, su, doas, pkexec, or runas",
        "TOOL_CMD_PROCESS_KILL": "Detects process termination commands that may kill critical processes",
        "TOOL_CMD_PROC_ENVIRON": "Command accesses /proc/*/environ which could expose sensitive environment variables",
        "TOOL_CMD_REVERSE_SHELL": "Detects attempts to establish reverse shells or unauthorized network tunnels",
        "TOOL_CMD_SERVICE_RESTART": "Detects service management commands that can disrupt system services",
        "TOOL_CMD_SYSTEM_REBOOT": "Detects system reboot or shutdown commands that will terminate the host system",
        "TOOL_CMD_SYSTEM_TAMPERING": "Detects access to cron jobs, SSH keys, or sudo permissions (including reads and modifications)",
        "TOOL_CMD_UNICODE_WHITESPACE": "Command contains Unicode whitespace characters that could cause parsing inconsistencies",
        "TOOL_CMD_UNSAFE_PERMISSIONS": "Detects global permission downgrades (chmod 777) or setting immutable flags",
        "TOOL_CMD_ZSH_DANGEROUS": "Command uses Zsh-specific builtins that can bypass security checks"
      },
      "categories": {
        "command_injection": "Command Injection",
        "code_execution": "Code Execution",
        "data_exfiltration": "Data Exfiltration",
        "path_traversal": "Path Traversal",
        "sensitive_file_access": "Sensitive File Access",
        "network_abuse": "Network Abuse",
        "credential_exposure": "Credential Exposure",
        "resource_abuse": "Resource Abuse",
        "privilege_escalation": "Privilege Escalation",
        "prompt_injection": "Prompt Injection",
        "other": "Other"
      }
    },
    "shellEvasion": {
      "title": "Shell Evasion Detection",
      "description": "Configure which shell evasion and obfuscation detection checks are enabled. These checks detect techniques that attempt to hide malicious intent from simpler regex-only detection.",
      "checks": {
        "command_substitution": {
          "name": "Command Substitution",
          "description": "Detects $(), backticks, process substitution, and other command substitution patterns"
        },
        "obfuscated_flags": {
          "name": "Obfuscated Flags",
          "description": "Detects ANSI-C quoting, locale quoting, and empty-quote flag obfuscation"
        },
        "backslash_escaped_whitespace": {
          "name": "Backslash Escaped Whitespace",
          "description": "Detects backslash-escaped spaces/tabs that can alter command parsing"
        },
        "backslash_escaped_operators": {
          "name": "Backslash Escaped Operators",
          "description": "Detects backslash before shell operators (;|&<>) that can hide command structure"
        },
        "newlines": {
          "name": "Hidden Newlines",
          "description": "Detects newlines and carriage returns that could separate hidden commands"
        },
        "comment_quote_desync": {
          "name": "Comment Quote Desync",
          "description": "Detects quote characters inside # comments that can desync quote tracking"
        },
        "quoted_newline": {
          "name": "Quoted Newline",
          "description": "Detects newlines inside quoted strings followed by #-prefixed lines that can hide arguments"
        }
      }
    },
    "fileGuard": {
      "title": "File Guard",
      "description": "Protect sensitive files and directories from being accessed by agent tools. Paths added here will be blocked across all tool calls.",
      "enableLabel": "Enable File Guard",
      "path": "Path",
      "actions": "Actions",
      "add": "Add",
      "inputPlaceholder": "Enter file or directory path (e.g. ~/.ssh/ or /etc/passwd)",
      "empty": "No custom sensitive paths configured",
      "directory": "Directory",
      "removeConfirm": "Remove this path from the protected list?",
      "duplicate": "This path is already in the list",
      "saveSuccess": "File guard settings saved",
      "saveFailed": "Failed to save file guard settings",
      "loadFailed": "Failed to load file guard settings",
      "allowPreviewOutsideWorkspace": "Allow Console Preview Outside Workspace",
      "allowPreviewOutsideWorkspaceDesc": "Allow previewing files outside the workspace directory in console. Sensitive file protection still applies."
    },
    "allowNoAuthHosts": {
      "title": "Allow No Auth Hosts",
      "warningTitle": "Security Warning",
      "warningDescription": "IP addresses in this list can access API endpoints without authentication. By default, localhost (127.0.0.1 and ::1) are allowed for CLI access. Only add trusted IP addresses. WARNING: Adding untrusted IPs poses a serious security risk.",
      "ipAddress": "IP Address",
      "actions": "Actions",
      "add": "Add",
      "inputPlaceholder": "Enter IP address (e.g., 192.168.1.100 or ::1)",
      "empty": "No IP addresses configured",
      "default": "Default",
      "removeConfirm": "Remove this IP address from the whitelist?",
      "duplicate": "This IP address is already in the list",
      "invalidIP": "Invalid IP address format",
      "saveSuccess": "Allow no auth hosts settings saved",
      "saveFailed": "Failed to save allow no auth hosts settings",
      "loadFailed": "Failed to load allow no auth hosts settings"
    },
    "skillScanner": {
      "title": "Skill Scanner",
      "description": "Automatically scan skills for security threats before enabling or installing. Unsafe skills can be blocked or whitelisted.",
      "mode": "Scanner Mode",
      "modeTooltip": "Controls how the scanner handles unsafe skills: block, warn only, or disabled",
      "modeBlock": "Block",
      "modeWarn": "Warn Only",
      "modeOff": "Off",
      "timeout": "Scan Timeout (seconds)",
      "timeoutTooltip": "Maximum time to wait for a scan to complete (5-300 seconds)",
      "saveSuccess": "Skill scanner settings saved",
      "saveFailed": "Failed to save skill scanner settings",
      "scanAlerts": {
        "title": "Scan Alerts",
        "empty": "No security alerts",
        "clearAll": "Clear All",
        "clearConfirm": "Clear all scan alerts?",
        "skillName": "Skill",
        "action": "Action",
        "actionBlocked": "Blocked",
        "actionWarned": "Warned",
        "time": "Time",
        "actions": "Actions",
        "allowSkill": "Add to Whitelist",
        "remove": "Remove",
        "viewFindings": "View Details"
      },
      "whitelist": {
        "title": "Whitelist",
        "empty": "No skills are whitelisted",
        "skillName": "Skill",
        "addedAt": "Added At",
        "contentHash": "Content Hash",
        "actions": "Actions",
        "remove": "Remove",
        "removeConfirm": "Remove this skill from the whitelist?",
        "addSuccess": "Skill added to whitelist",
        "removeSuccess": "Skill removed from whitelist",
        "addFailed": "Failed to add skill to whitelist",
        "removeFailed": "Failed to remove skill from whitelist",
        "removeWillDisable": "The skill will also be disabled after removal.",
        "removeAndDisabled": "Skill removed from whitelist and disabled"
      },
      "scanError": {
        "title": "Security Issues Detected",
        "description": "The following security issues were found:",
        "warnDescription": "Security issues were found but the skill was still enabled (warn mode):",
        "goToWhitelist": "Go to Whitelist",
        "moreFindings": "{{count}} more issues not shown (see Security → Skill Scanner for the full list)."
      }
    }
  },
  "login": {
    "title": "Login to QwenPaw",
    "registerTitle": "Create Account",
    "firstUserHint": "Create your admin account to get started",
    "usernamePlaceholder": "Username",
    "passwordPlaceholder": "Password",
    "usernameRequired": "Please enter your username",
    "passwordRequired": "Please enter your password",
    "submit": "Login",
    "register": "Register",
    "failed": "Login failed, please check your credentials",
    "registerSuccess": "Registration successful",
    "registerFailed": "Registration failed",
    "authNotEnabled": "Authentication is not enabled",
    "logout": "Logout",
    "logoutSuccess": "Logged out successfully",
    "sessionExpired": "Session expired, please login again",
    "unauthorized": "Unauthorized, please login"
  },
  "account": {
    "title": "Account",
    "currentPassword": "Current Password",
    "currentPasswordRequired": "Please enter your current password",
    "newUsername": "New Username",
    "newUsernamePlaceholder": "Leave blank to keep current",
    "newPassword": "New Password",
    "newPasswordPlaceholder": "Leave blank to keep current",
    "confirmPassword": "Confirm New Password",
    "confirmPasswordPlaceholder": "Re-enter new password",
    "passwordMismatch": "Passwords do not match",
    "save": "Save Changes",
    "updateSuccess": "Account updated successfully",
    "updateFailed": "Failed to update account",
    "wrongPassword": "Current password is incorrect",
    "nothingToUpdate": "Please enter a new username or password",
    "passwordEmpty": "Password cannot be blank",
    "usernameEmpty": "Username cannot be blank"
  },
  "approval": {
    "title": "Security Approval Required",
    "ownerAgent": "Owner Agent",
    "executingAgent": "Executing Agent",
    "tool": "Tool",
    "severity": "Severity",
    "findings": "Findings",
    "parameters": "Parameters",
    "approve": "Approve",
    "deny": "Deny",
    "source": "Source",
    "builtinSource": "Built-in",
    "subSession": "Sub-Agent",
    "approved": "Tool call approved",
    "denied": "Tool call denied",
    "approveFailed": "Failed to approve",
    "denyFailed": "Failed to deny",
    "timeoutAutoDenied": "Timed out, auto denied",
    "acknowledge": "Got it",
    "approvePattern": "Always Allow",
    "strictModeHint": "Always allow is unavailable in strict mode",
    "approveExact": "Just Once",
    "approvalScope": "Approval scope",
    "details": "Details"
  },
  "pluginManager": {
    "title": "Plugin Manager",
    "description": "Install, manage, and remove plugins without restarting the service.",
    "installed": "Installed Plugins",
    "noPlugins": "No plugins installed yet",
    "installBtn": "Install Plugin",
    "publishBtn": "Publish Plugin",
    "installTitle": "Install Plugin",
    "dropPrimary": "Drop folder or ZIP here",
    "dropSecondary": "or click to browse a ZIP file",
    "orFromUrl": "or from URL",
    "installFromUrl": "Install from URL",
    "urlPlaceholder": "https://example.com/plugin.zip",
    "zipOnly": "Only ZIP files can be dropped as files — drag a folder for directory install",
    "dropFailed": "Failed to read dropped folder",
    "restartHint": "Some plugins (e.g. hooks, monkey-patches) may require an app restart to fully take effect or be removed.",
    "installing": "Installing...",
    "installSuccess": "Plugin installed successfully",
    "installFailed": "Plugin installation failed",
    "uninstall": "Uninstall",
    "uninstallConfirm": "Uninstall plugin \"{{name}}\"? This cannot be undone. Some plugins may require an app restart to be fully removed.",
    "uninstalling": "Uninstalling...",
    "uninstallSuccess": "Plugin uninstalled successfully",
    "uninstallFailed": "Plugin uninstallation failed",
    "statusLoaded": "Running",
    "statusUnloaded": "Not loaded",
    "type": "Type",
    "version": "Version",
    "author": "Author",
    "unknown": "Unknown",
    "loadFailed": "Failed to load plugin list",
    "confirmTitle": "Confirm Uninstall",
    "officialTitle": "Official Plugins",
    "officialDesc": "Install published plugins from the download CDN.",
    "catalogRefresh": "Refresh",
    "catalogEmpty": "No official plugins available (CDN catalog may be empty)",
    "catalogLoadFailed": "Failed to load official plugin catalog",
    "catalogInstall": "Install",
    "catalogReinstall": "Reinstall",
    "catalogUpgrade": "Upgrade available",
    "catalogUpgradeBtn": "Upgrade",
    "catalogInstalled": "Installed",
    "catalogSha256": "SHA256",
    "kindBundle": "Bundle",
    "kindTool": "Tool",
    "filterByName": "Filter by name",
    "filterByKind": "Filter by kind",
    "marketTitle": "Plugin Market",
    "marketEmpty": "No plugins found in market",
    "marketLoadFailed": "Failed to load plugin market",
    "marketUnavailable": "Plugin Market is currently under maintenance, please try again later",
    "marketSearch": "Search plugins...",
    "marketAll": "All",
    "marketCategory": "Filter by category",
    "marketSearchResult": "Found {{count}} plugins matching \"{{keyword}}\"",
    "marketDetails": "Details",
    "marketDownloads": "Downloads",
    "marketDeveloper": "Developer",
    "marketSortLabel": "Sort plugins",
    "marketSortDownloads": "Most downloaded",
    "marketSortUpdated": "Recently updated",
    "marketSortFavorites": "Most favorited",
    "compatWarningTitle": "Compatibility Warning",
    "compatWarningContent": "This plugin is labeled for QwenPaw {{labels}}. Your QwenPaw version is {{version}}. Installing it may cause errors. Are you sure you want to continue?",
    "compatWarningConfirm": "Install anyway"
  },
  "codingMode": {
    "title": "Coding Mode",
    "experimental": "Experimental Feature",
    "experimentalDesc": "Coding Mode transforms QwenPaw into a lightweight Web IDE with a code editor, file tree, Git integration, and AI-powered coding assistance.",
    "experimentalNote": "This feature is experimental and still under active development. Some functionality may be limited or change in future updates.",
    "confirmBtn": "Confirm",
    "enterTooltip": "Enter Coding Mode",
    "exitTooltip": "Exit Coding Mode",
    "btnCode": "Code",
    "btnChat": "Chat",
    "selectProject": "Select Coding Project",
    "selectProjectDesc": "Choose a project to work on, or use the default workspace",
    "tabWorkspace": "Default Workspace",
    "tabClone": "Clone Repository",
    "tabLocal": "Import Local Project",
    "tabNew": "New Project",
    "workspaceDesc": "Use the current agent's workspace directory",
    "cloneUrl": "Git Repository URL",
    "cloneUrlPlaceholder": "https://github.com/user/repo.git",
    "cloneName": "Project Name (optional)",
    "cloneNamePlaceholder": "Leave empty to infer from URL",
    "cloneBtn": "Start Clone",
    "cloning": "Cloning...",
    "localPath": "Local Directory Path",
    "localPathPlaceholder": "/Users/yourname/my-project",
    "localPathHint": "Enter the absolute path to your local project",
    "openBtn": "Import",
    "newName": "Project Name",
    "newNamePlaceholder": "my-project",
    "createBtn": "Create Project",
    "switchProject": "Switch Project",
    "currentProject": "Current Project",
    "resetToWorkspace": "Reset to Default Workspace",
    "dropPrimary": "Drag a folder here, or click to browse",
    "dropSecondary": "Drag from Finder or paste a path below",
    "pathHint": "Please enter the full absolute path (starting with / or ~)",
    "importing": "Importing...",
    "dropFailed": "Failed to read folder",
    "workingDir": "Working directory",
    "importCopyNote": "The folder will be copied into coding_projects/. Original files will not be modified.",
    "importCopyDesc": "Import creates a copy of the folder. The Agent works on the copy and your original files stay untouched. To work directly on the original, use \"Open Directory\" instead.",
    "tabOpenDir": "Open Directory",
    "openDirDesc": "Open an existing local directory — no files will be copied",
    "openDirBtn": "Open This Directory",
    "openDirLoading": "Loading...",
    "openDirEmpty": "No subdirectories here",
    "openDirHome": "Home",
    "openDirRefresh": "Refresh",
    "openDirHiddenFolders": "Hidden Folders"
  },
  "market": {
    "searchPlaceholder": "Search skills across platforms",
    "categoryAll": "All",
    "categoryPlaceholder": "Search category",
    "searchResult": "Found {{count}} skills matching \"{{keyword}}\"",
    "providerUnavailable": "Provider unavailable",
    "noResults": "No results",
    "startTyping": "Type a query above to search the market",
    "browseHint": "Pick a category or enter a keyword to browse skills in {{providers}}",
    "noDescription": "No description provided",
    "browseMarket": "Browse Market",
    "installQueue": "Install queue",
    "clearCompleted": "Clear",
    "retry": "Retry",
    "status": {
      "queued": "Queued",
      "installing": "Installing",
      "completed": "Done",
      "failed": "Failed",
      "cancelled": "Cancelled"
    },
    "loadMore": "Load more",
    "noMoreResults": "No more results",
    "detail": {
      "title": "Skill details",
      "version": "Version",
      "author": "Author",
      "sourceUrl": "Install URL",
      "slug": "Slug",
      "missing": "—"
    },
    "stats": {
      "downloads": "Downloads",
      "stars": "Stars",
      "installs": "Installs",
      "likes": "Likes",
      "views": "Views",
      "category": "Category",
      "updatedAt": "Updated"
    },
    "queueMsg": {
      "timedOut": "Install timed out",
      "failedPrefix": "Failed: {{msg}}"
    }
  },
  "startup": {
    "starting": "Starting backend...",
    "checking": "Connecting to backend...",
    "error": "Backend failed to start.",
    "errorHint": "The backend process could not be launched. Check application logs for details.",
    "errorDetails": "Show error details",
    "timeout": "Backend failed to start within {{seconds}} seconds.",
    "timeoutHint": "Backend failed to start. Please retry, or check application logs for details.",
    "retry": "Retry"
  },
  "tool": {
    "readFile": "Read {{file}}",
    "readFileDefault": "Read file",
    "writeFile": "Create {{file}}",
    "writeFileDefault": "Create file",
    "editFile": "Edit {{file}}",
    "editFileDefault": "Edit file",
    "appendFile": "Append {{file}}",
    "appendFileDefault": "Append file",
    "grepSearch": "Grep {{pattern}}",
    "grepSearchDefault": "Grep search",
    "globSearch": "Glob {{pattern}}",
    "globSearchDefault": "Glob search",
    "viewImage": "View image {{file}}",
    "viewImageDefault": "View image",
    "viewVideo": "View video {{file}}",
    "viewVideoDefault": "View video",
    "desktopScreenshot": "Screenshot desktop",
    "sendFile": "Send {{file}}",
    "sendFileDefault": "Send file",
    "browserUse": "Browse {{detail}}",
    "browserNavigate": "Browse open {{url}}",
    "browserNavigateDefault": "Browse open page",
    "browserClick": "Browse click",
    "browserType": "Browse type",
    "browserSnapshot": "Browse snapshot",
    "browserScroll": "Browse scroll",
    "getCurrentTime": "Get current time",
    "setTimezone": "Set {{timezone}}",
    "getTokenUsage": "Query token usage",
    "memorySearch": "Search memory {{query}}",
    "memorySearchDefault": "Search memory",
    "listAgents": "List agents",
    "chatWithAgent": "Chat {{agent}}",
    "chatWithAgentDefault": "Chat agent",
    "submitToAgent": "Submit {{agent}}{{task}}",
    "submitToAgentDefault": "Submit task",
    "checkAgentTask": "Check {{agent}} #{{taskId}}",
    "checkAgentTaskAgent": "Check {{agent}}",
    "checkAgentTaskDefault": "Check task",
    "delegateExternalAgent": "Delegate {{runner}}",
    "delegateExternalAgentDefault": "Delegate external agent",
    "materializeSkill": "Create {{skill}}",
    "materializeSkillDefault": "Create skill",
    "shell": "Run {{command}}",
    "shellDefault": "Run command",
    "formatTable": {
      "file": "File",
      "lineNumber": "Line",
      "score": "Score",
      "summary": "Summary",
      "name": "Name",
      "id": "ID",
      "description": "Description",
      "status": "Status"
    },
    "loading": "Loading...",
    "inputProgress": "{{count}} chars",
    "rawInputPreview": "Live raw input (last 4,096 characters)",
    "browserAction": {
      "startHeaded": "Start browser (headed)",
      "start": "Start browser",
      "stop": "Stop browser",
      "open": "Open {{url}}",
      "openDefault": "Open page",
      "navigate": "Navigate {{url}}",
      "navigateDefault": "Navigate",
      "navigateBack": "Go back",
      "click": "Click {{selector}}",
      "clickDefault": "Click element",
      "type": "Type {{text}}",
      "typeDefault": "Type text",
      "snapshot": "Get snapshot",
      "screenshot": "Screenshot {{path}}",
      "screenshotDefault": "Screenshot",
      "eval": "Eval {{code}}",
      "evalDefault": "Evaluate code",
      "runCode": "Run {{code}}",
      "runCodeDefault": "Run code",
      "closePage": "Close page",
      "tabs": "Tabs {{action}}",
      "tabsDefault": "Manage tabs",
      "fillForm": "Fill form",
      "fileUpload": "Upload {{filename}}",
      "fileUploadDefault": "Upload file",
      "fileDownload": "Download {{target}}",
      "fileDownloadDefault": "Download file",
      "pressKey": "Press {{key}}",
      "pressKeyDefault": "Press key",
      "hover": "Hover {{selector}}",
      "hoverDefault": "Hover element",
      "drag": "Drag",
      "selectOption": "Select option",
      "waitFor": "Wait for {{target}}",
      "waitForDefault": "Wait for element",
      "resize": "Resize {{w}}x{{h}}",
      "resizeDefault": "Resize window",
      "pdf": "Export PDF {{path}}",
      "pdfDefault": "Export PDF",
      "install": "Install",
      "batch": "Batch"
    },
    "lineBadge": {
      "lines": "{{count}} lines",
      "addLines": "+{{count}} lines",
      "delLines": "-{{count}} lines",
      "matches": "{{count}} matches",
      "files": "{{count}} files"
    },
    "inlineResult": {
      "taskId": "Task #{{id}}",
      "submitted": "Submitted"
    },
    "execute": "Run {{tool}}",
    "executeDefault": "Run tool"
  },
  "preview": {
    "error": {
      "SENSITIVE_FILE_BLOCKED": "This file is blocked by File Guard (sensitive file protection).",
      "OUTSIDE_WORKSPACE": "This file is outside the workspace scope. Enable \"Allow Console Preview Outside Workspace\" in Settings → Security → File Guard.",
      "FORBIDDEN": "Access denied: insufficient permissions to preview this file.",
      "NOT_FOUND": "File not found. It may have been moved or deleted. If a relative path was used, please try using an absolute path instead.",
      "LOAD_FAILED": "Failed to load file preview.",
      "LOAD_FAILED_DETAIL": "Failed to load file preview: {{detail}}"
    }
  },
  "loop": {
    "budget": {
      "low": "Low",
      "medium": "Med",
      "high": "High"
    },
    "status": {
      "pause": "Pause",
      "resume": "Resume",
      "stop": "Stop"
    },
    "gotoSettings": "Agent Loop Settings",
    "selectorTitle": "Loop mode",
    "selectorHint": "Choose how the agent should continue",
    "selectorAria": "Select loop mode",
    "builtInModes": "Built-in",
    "customModes": "Custom and plugins",
    "starting": "Starting",
    "running": "Running",
    "awaiting_user": "Waiting for your reply",
    "activePersistentDescription": "This mode remains active for the conversation until it finishes or you start over.",
    "activeCustomDescription": "This custom mode remains active until you use /mode off, /clear, or /new.",
    "loadError": "Some loop modes could not be loaded.",
    "retry": "Retry",
    "modes": {
      "default": {
        "name": "Default",
        "description": "The standard guarded agent loop."
      },
      "goal": {
        "name": "Goal",
        "description": "Work persistently toward a concrete, verifiable goal."
      },
      "mission": {
        "name": "Mission",
        "description": "Run a structured, persistent multi-step task."
      }
    }
  }
}
