UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

2,930 lines 166 kB
//#endregion
//#region src/wizard/i18n/index.ts
const LOCALES = {
	en: {
		common: {
			back: "Back",
			done: "Done",
			docs: "Docs:",
			finished: "Finished",
			noAuth: "No auth",
			password: "Password",
			required: "Required",
			minute: "{count} minute",
			minutes: "{count} minutes",
			second: "{count} second",
			seconds: "{count} seconds",
			skip: "Skip",
			skipForNow: "Skip for now",
			tokenRecommended: "Token (recommended)"
		},
		wizard: {
			customProvider: {
				apiBaseUrl: "API Base URL",
				apiKeyPrompt: "API Key (leave blank if not required)",
				changeBaseUrl: "Change base URL",
				changeBaseUrlAndModel: "Change base URL and model",
				changeModel: "Change model",
				compatibility: "Endpoint compatibility",
				compatibilityAnthropic: "Anthropic-compatible",
				compatibilityAnthropicHint: "Uses /messages",
				compatibilityOpenAi: "OpenAI-compatible",
				compatibilityOpenAiHint: "Uses /chat/completions",
				compatibilityOpenAiResponses: "OpenAI Responses-compatible",
				compatibilityOpenAiResponsesHint: "Uses /responses",
				compatibilityUnknown: "Unknown (detect automatically)",
				compatibilityUnknownHint: "Probes OpenAI Chat, OpenAI Responses, then Anthropic endpoints",
				detectionFailed: "Could not detect endpoint type.",
				detectionFailedNote: "This endpoint did not respond to OpenAI Chat, OpenAI Responses, or Anthropic style requests.",
				detectionNoteTitle: "Endpoint detection",
				detectionProgress: "Detecting endpoint type...",
				detectedAnthropic: "Detected Anthropic-compatible endpoint.",
				detectedOpenAi: "Detected OpenAI-compatible endpoint.",
				detectedOpenAiResponses: "Detected OpenAI Responses-compatible endpoint.",
				endpointId: "Endpoint ID",
				endpointIdRequired: "Endpoint ID is required.",
				endpointIdRenamed: "Endpoint ID \"{from}\" already exists for a different base URL. Using \"{to}\".",
				endpointIdTitle: "Endpoint ID",
				imageInput: "Does this model support image input?",
				modelAlias: "Model alias (optional)",
				modelAliasPlaceholder: "e.g. local, ollama",
				modelId: "Model ID",
				modelIdPlaceholder: "e.g. llama3, claude-3-7-sonnet",
				modelIdRequired: "Model ID is required",
				retryChoice: "What would you like to change?",
				verifying: "Verifying...",
				verificationFailedError: "Verification failed: {error}",
				verificationFailedStatus: "Verification failed: status {status}",
				verificationSuccessful: "Verification successful.",
				validUrl: "Please enter a valid URL (e.g. http://...)"
			},
			gateway: {
				accessProtection: "Gateway access protection",
				auth: "Gateway auth",
				authPasswordStoredMessage: "Where is this gateway password stored?",
				authPasswordMode: "How do you want to provide the gateway password?",
				authTokenMode: "How do you want to provide the gateway token?",
				authTokenStoredMessage: "Where is this gateway token stored?",
				bindAddress: "Gateway bind address",
				bindAuto: "Auto (Loopback -> LAN)",
				bindAutoHint: "Try loopback first",
				bindCustom: "Custom IP",
				bindCustomHint: "Bind to one local address",
				bindCustomIp: "Custom IP address",
				bindLan: "LAN (0.0.0.0)",
				bindLanHint: "Reachable on your local network",
				bindLoopback: "Loopback (127.0.0.1)",
				bindLoopbackHint: "This machine only",
				bindTailnet: "Tailnet (Tailscale IP)",
				bindTailnetHint: "Reachable over Tailscale",
				existingPasswordConfirm: "Use existing gateway password ({password})?",
				existingTokenConfirm: "Use existing gateway token ({token})?",
				passwordPrompt: "Gateway password",
				plaintextPasswordHint: "Stores the password directly in OpenClaw config",
				plaintextPasswordLabel: "Enter password now",
				plaintextTokenHint: "Default",
				plaintextTokenLabel: "Generate/store plaintext token",
				port: "Gateway port",
				refHint: "Store a reference instead of plaintext",
				refLabel: "Use SecretRef",
				remotePasswordMode: "How do you want to provide this gateway password?",
				remoteTokenMode: "How do you want to provide this gateway token?",
				tailscaleExposure: "Tailscale exposure",
				tailscaleReset: "Reset Tailscale serve/funnel on exit?",
				tokenPlaceholder: "Needed for multi-machine or non-loopback access",
				tokenPrompt: "Gateway token",
				tokenPromptGenerate: "Gateway token (blank to generate)",
				websocketUrl: "Gateway WebSocket URL"
			},
			gatewayTailscale: {
				docsNote: "Docs:\nhttps://docs.openclaw.ai/gateway/tailscale\nhttps://docs.openclaw.ai/web",
				funnel: "Funnel",
				funnelHint: "Public HTTPS via Tailscale Funnel (internet)",
				missingBinNote: "Tailscale binary not found in PATH or /Applications.\nEnsure Tailscale is installed from:\n  https://tailscale.com/download/mac\n\nYou can continue setup, but serve/funnel will fail at runtime.",
				off: "Off",
				offHint: "No Tailscale exposure",
				serve: "Serve",
				serveHint: "Private HTTPS for your tailnet (devices on Tailscale)",
				warningTitle: "Tailscale Warning"
			},
			hooks: {
				configuredTitle: "Hooks Configured",
				enable: "Enable hooks?",
				introTitle: "Hooks",
				noHooksMessage: "No eligible hooks found. You can configure hooks later in your config.",
				noHooksTitle: "No Hooks Available"
			},
			completion: {
				cacheFailed: "Failed to generate completion cache. Run `{command}` later.",
				enable: "Enable {shell} shell completion for {cli}?",
				installed: "Shell completion installed. {reloadHint}",
				reloadPowerShell: "Restart your shell or run: {command}",
				reloadShell: "Restart your shell or run: source {profile}",
				title: "Shell completion"
			},
			migration: {
				apply: "Apply this migration now?",
				appliedTitle: "Migration applied",
				cancelled: "migration cancelled",
				complete: "Migration complete. Run `openclaw doctor` next.",
				previewTitle: "Migration preview",
				source: "Migration source",
				sourceAgentHome: "Source agent home",
				sourcePathHint: "Enter a source path next",
				targetWorkspace: "Target workspace directory"
			},
			plugins: {
				configureBackHint: "Return to section menu",
				configureEmpty: "No plugins with configurable fields found.",
				configureEmptyTitle: "Plugins",
				configureFieldsTitle: "Plugin setup",
				configurePlugin: "Configure {plugin}",
				configureSelect: "Select plugin to configure",
				configureSelectOnboard: "Configure plugins (select to set up now, or skip)",
				configuredCount: "{configured}/{total} configured",
				currentValue: "Keep current ({value})",
				downloadFromClawHub: "Download from ClawHub ({spec})",
				downloadFromNpm: "Download from npm ({spec})",
				enableFailed: "Cannot enable {plugin}: {reason}.",
				fieldsCount: "{count} field{plural}",
				installFailed: "Failed to install {spec}: {error}",
				installFailedShort: "Install failed: {plugin}",
				installPluginPrompt: "Install {plugin} plugin?",
				installTimedOut: "Installing {spec} timed out after {duration}.",
				installTimedOutShort: "Install timed out: {plugin}",
				installedPlugin: "Installed {plugin} plugin",
				installingPlugin: "Installing {plugin} plugin…",
				installTitle: "Plugin install",
				noRemoteInstallSource: "No remote install source is available for {plugin}. Returning to selection.",
				officialInstall: "Install optional plugins",
				officialSkipHint: "Continue without installing optional plugins",
				preparingInstall: "Preparing",
				returningToSelection: "Returning to selection.",
				arrayPromptSuffix: " (comma-separated, empty to clear)",
				arrayPlaceholder: "value1, value2",
				sensitiveField: "\"{label}\" is sensitive. Set it via:\n  openclaw config set plugins.entries.{plugin}.config.{field} <value>\nor use the Web UI Settings page.",
				sensitiveTitle: "Sensitive field",
				skipConfigHint: "Continue without configuring plugins",
				useLocalPluginPath: "Use local plugin path",
				useLocalPluginPathInstead: "Use local plugin path instead? ({path})",
				useNpmPackageInstead: "Use npm package instead? ({spec})"
			},
			model: {
				allProviders: "All providers",
				browseAll: "Browse all models",
				configuredTitle: "Model configured",
				current: "current",
				currentNotInCatalog: "current (not in catalog)",
				allowed: "allowed",
				allowedNotInCatalog: "allowed (not in catalog)",
				allowlistPicker: "Models in /model picker (multi-select)",
				allowlistText: "Allowlist models (comma-separated provider/model; blank to keep current)",
				clearAllowlist: "Clear the model allowlist? (shows all models)",
				configured: "configured",
				configuredNotInCatalog: "configured (not in catalog)",
				defaultModel: "Default model",
				defaultModelBlankToKeep: "Default model (blank to keep)",
				defaultSet: "Default model set to {model}",
				defaultSetForAgent: "Default model set to {model} for agent \"{agent}\".",
				enterManually: "Enter model manually",
				filterByProvider: "Filter models by provider",
				keepCurrent: "Keep current ({value})",
				keepCurrentDefault: "Keep current (default: {value})",
				keptExistingDefault: "Kept existing default model {current}; {selected} is available.",
				loadsProviderCatalogs: "loads provider catalogs",
				loadingModels: "Loading available models",
				modelCount: "{count} model{plural}",
				providerSetupUnavailable: "Provider setup requires agent and runtime context.",
				providerSetupUnavailableTitle: "Provider setup unavailable",
				removeProviderModels: "Remove these provider models from the /model picker?",
				resolvesTo: "resolves to {value}"
			},
			remote: {
				auth: "Gateway auth",
				bonjour: "Discover gateway on LAN (Bonjour)?",
				connectionMethod: "Connection method",
				directAccessTitle: "Direct remote",
				enterUrlManually: "Enter URL manually",
				foundGateways: "Found {count} gateway(s)",
				fingerprintMissing: "not advertised (connection will not be pinned)",
				gatewayPasswordStoredMessage: "Where is this gateway password stored?",
				gatewayTokenStoredMessage: "Where is this gateway token stored?",
				insecureRemoteUrl: "Use wss:// for remote hosts, or ws://127.0.0.1/localhost via SSH tunnel. Break-glass: OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 for trusted private networks.",
				directDefaultsTls: "Direct remote access defaults to TLS.",
				loopbackSshHint: "If your gateway is loopback-only, choose SSH tunnel and keep ws://127.0.0.1:18789.",
				noGatewaysFound: "No gateways found",
				passwordPrompt: "Gateway password",
				plaintextPasswordHint: "Stores the password directly in OpenClaw config",
				plaintextPasswordLabel: "Enter password now",
				plaintextTokenHint: "Stores the token directly in OpenClaw config",
				plaintextTokenLabel: "Enter token now",
				searchProgress: "Searching for gateways...",
				selectGateway: "Select gateway",
				sshTunnel: "SSH tunnel (loopback)",
				sshTunnelTitle: "SSH tunnel",
				tokenPrompt: "Gateway token",
				trustGateway: "Trust this gateway? Host: {host} TLS fingerprint: {fingerprint}",
				validWebSocketUrl: "URL must start with ws:// or wss://",
				websocketUrl: "Gateway WebSocket URL"
			},
			setup: {
				authChoiceRequired: "auth choice is required",
				channelsTitle: "Channels",
				configHandling: "Config handling",
				existingConfigTitle: "Existing config detected",
				flowAdvanced: "Manual setup",
				flowAdvancedHint: "Choose Gateway port, network exposure, Tailscale, and auth.",
				flowQuickstart: "QuickStart (recommended)",
				flowQuickstartHint: "Recommended local setup. Change details later with {command}.",
				intro: "OpenClaw setup",
				invalidConfigTitle: "Invalid config",
				keepCurrent: "Keep current values",
				localGateway: "Local gateway (this machine)",
				localGatewayMissing: "No gateway detected ({url})",
				localGatewayReachable: "Gateway reachable ({url})",
				modifyCurrent: "Review and update",
				pluginCompatibilityTitle: "Plugin compatibility",
				quickstartOnlyLocal: "QuickStart only supports local gateways. Switching to Manual mode.",
				quickstartTitle: "QuickStart",
				quickstartAuthTokenDefault: "Token (default)",
				quickstartDirectChannels: "Direct to chat channels.",
				quickstartGatewayAuth: "Gateway auth: {auth}",
				quickstartGatewayBind: "Gateway bind: {bind}",
				quickstartGatewayCustomIp: "Gateway custom IP: {host}",
				quickstartGatewayPort: "Gateway port: {port}",
				quickstartKeepSettings: "Keeping your current gateway settings:",
				quickstartTailscaleExposure: "Tailscale exposure: {exposure}",
				remoteConfigured: "Remote gateway configured.",
				remoteGateway: "Remote gateway (info-only)",
				remoteGatewayMissing: "No remote URL configured yet",
				remoteGatewayReachable: "Gateway reachable ({url})",
				remoteGatewayUnreachable: "Configured but unreachable ({url})",
				resetBefore: "Reset before setup",
				resetConfig: "Config only",
				resetConfigCredsSessions: "Config + creds + sessions",
				resetFull: "Full reset (config + creds + sessions + workspace)",
				resetScope: "Reset scope",
				riskNotAccepted: "risk not accepted",
				searchTitle: "Search",
				setupMode: "Setup mode",
				secretRefProbeFailed: "Could not resolve {field} SecretRef for setup probe.",
				skillsTitle: "Skills",
				skipChannels: "Skipping channel setup.",
				skipSearch: "Skipping search setup.",
				skipSkills: "Skipping skills setup.",
				whatSetup: "What do you want to set up?",
				workspaceDirectory: "Workspace directory"
			},
			security: {
				askForHelp: "Ask someone experienced to help before enabling tools or exposing it to the internet.",
				baselineDmSessions: "Shared inboxes: isolate DM sessions (session.dmScope: per-channel-peer) and keep tool access minimal.",
				baselinePairing: "Pairing/allowlists + mention gating.",
				baselineSandbox: "Sandbox + least-privilege tools.",
				baselineSecrets: "Keep secrets out of the agent's reachable filesystem.",
				baselineSharedInbox: "Multi-user/shared inbox: split trust boundaries (separate gateway/credentials, ideally separate OS users/hosts).",
				baselineStrongModel: "Use the strongest available model for any bot with tools or untrusted inboxes.",
				beta: "OpenClaw is a hobby project and still in beta. Expect sharp edges.",
				confirm: "I understand this is personal-by-default and shared/multi-user use requires lock-down. Continue?",
				hardeningRequired: "If you're not comfortable with security hardening and access control, don't run OpenClaw.",
				learnMore: "Learn more",
				notMultitenant: "OpenClaw is not a hostile multi-tenant boundary by default.",
				personalAgent: "By default, OpenClaw is a personal agent: one trusted operator boundary.",
				promptRisk: "A bad prompt can trick it into doing unsafe things.",
				recommendedBaseline: "Recommended baseline",
				runRegularly: "Run regularly",
				sharedAuthority: "If multiple users can message one tool-enabled agent, they share that delegated tool authority.",
				title: "Security disclaimer",
				toolAccess: "This bot can read files and run actions if tools are enabled."
			},
			skills: {
				configure: "Configure skills now? (recommended)",
				containerBrewHidden: "Brew-only skill installs are hidden in Linux containers because the official image does not ship Homebrew.",
				containerBrewManual: "Use a custom image with Homebrew preinstalled or install those dependencies manually.",
				containerInstallsTitle: "Container skill installs",
				docsLine: "Docs: https://docs.openclaw.ai/skills",
				enterEnv: "Enter {env}",
				homebrewCommand: "Show Homebrew install command?",
				homebrewInstallTitle: "Homebrew install",
				homebrewRecommendedTitle: "Homebrew recommended",
				installDeps: "Install missing skill dependencies",
				installFailed: "Install failed: {name}{code}{detail}",
				installed: "Installed {name}",
				installedWithWarnings: "Installed {name} (with warnings)",
				installing: "Installing {name}...",
				nodeManager: "Preferred node manager for skill installs",
				setEnv: "Set {env} for {name}?",
				skipDepsHint: "Continue without installing dependencies",
				statusTitle: "Skills status",
				allReadyTitle: "All skills ready"
			},
			channels: {
				account: "{label} account",
				configuredAction: "{label} already configured. What do you want to do?",
				configuredDeleteUnsupported: "{label} does not support deleting config entries.",
				configureDmPolicies: "Configure DM access policies now? (default: pairing)",
				deleteAccount: "Delete {label} account \"{account}\"?",
				deleteConfig: "Delete config",
				dmAccessTitle: "{label} DM access",
				dmPolicy: "{label} DM policy",
				dmPolicyAllowlist: "Allowlist DMs: {policyKey}=\"allowlist\" + {allowFromKey} entries.",
				dmPolicyAllowlistOption: "Allowlist (specific users only)",
				dmPolicyApprove: "Approve: {command}",
				dmPolicyDefault: "Default: pairing (unknown DMs get a pairing code).",
				dmPolicyDisabledOption: "Disabled (ignore DMs)",
				dmPolicyMultiUser: "Multi-user DMs: run: {command} (or \"per-account-channel-peer\" for multi-account channels) to isolate sessions.",
				dmPolicyOpen: "Public DMs: {policyKey}=\"open\" + {allowFromKey} includes \"*\".",
				dmPolicyOpenOption: "Open (public inbound DMs)",
				dmPolicyPairing: "Pairing (recommended)",
				docs: "Docs: {link}",
				disabledBeforeSetup: "{channel} cannot be configured while {hint}. Enable it before setup.",
				disabledDuringSetup: "{channel} cannot be configured while {hint}. Enable it, then run {command} again.",
				disableKeepConfig: "Disable (keeps config)",
				doneHint: "Done",
				modifySettings: "Modify settings",
				noInteractiveSetup: "{channel} does not have an interactive setup screen yet. Run {command} for supported flags.",
				pluginEnableFailed: "Cannot enable {channel}: {reason}. Run {command} to inspect plugin state.",
				pluginMissingRecoverable: "{channel} plugin not available (continuing with setup). If the channel still doesn't work after setup, run `{listCommand}` and `{enableCommand}`, then restart the gateway.",
				pluginNotAvailable: "{channel} plugin not available.",
				removeTitle: "Remove channel",
				select: "Select a channel",
				selectQuickstart: "Select channel (QuickStart)",
				selectedTitle: "Selected channels",
				setupConfirm: "Set up a chat channel now?",
				setupTitle: "Channel setup",
				skipLeaveAsIs: "Skip (leave as-is)",
				skipLaterHint: "You can add channels later via `{command}`",
				statusTitle: "Channel status",
				statusBundledEnable: "bundled · enable to use",
				statusConfigured: "configured",
				statusConfiguredConnectionNotVerified: "configured (connection not verified)",
				statusConfiguredPluginDisabled: "configured (plugin disabled)",
				statusConnectedAs: "connected as {name}",
				statusInstallPluginEnable: "install plugin to enable",
				statusInstalled: "installed",
				statusInstalledPluginDisabled: "installed (plugin disabled)",
				statusLinked: "linked",
				statusNeedsAppCredentials: "needs app credentials",
				statusNeedsAppCreds: "needs app creds",
				statusNeedsAuth: "needs auth",
				statusNeedsHostNick: "needs host + nick",
				statusNeedsPrivateKey: "needs private key",
				statusNeedsQrLogin: "needs QR login",
				statusNeedsServiceAccount: "needs service account",
				statusNeedsSetup: "needs setup",
				statusNeedsToken: "needs token",
				statusNeedsTokens: "needs tokens",
				statusNeedsTokenIncomingWebhook: "needs token + incoming webhook",
				statusNeedsTokenUrl: "needs token + url",
				statusNeedsTokenSecret: "needs token + secret",
				statusNeedsUsernameTokenClientId: "needs username, token, and clientId",
				statusNotLinked: "not linked",
				statusNotConfigured: "not configured",
				statusLoggedIn: "logged in",
				statusRecommendedConfigured: "recommended · configured",
				statusRecommendedLoggedIn: "recommended · logged in",
				statusRecommendedNewcomerFriendly: "recommended · newcomer-friendly",
				statusRecommendedQrLogin: "recommended · QR login",
				statusSelfHostedChat: "self-hosted chat",
				statusSignalCliFound: "signal-cli found",
				statusSignalCliMissing: "signal-cli missing",
				statusUrbitMessenger: "urbit messenger",
				resolvedTitle: "Resolved"
			},
			feishu: {
				allowFromPrompt: "Feishu allowFrom (user open_ids)",
				allowlistFindUser: "You can find user open_id in Feishu admin console or via API.",
				allowlistIntro: "Allowlist Feishu DMs by open_id or user_id.",
				allowlistTitle: "Feishu allowlist",
				appIdPrompt: "Enter Feishu App ID",
				appSecretKeep: "Feishu App Secret already configured. Keep it?",
				appSecretPrompt: "Enter Feishu App Secret",
				botConfigured: "Bot configured.",
				configuring: "Configuring...",
				credentialsEnvTip: "Tip: you can also set FEISHU_APP_ID / FEISHU_APP_SECRET env vars.",
				credentialsStepCreateApp: "2) Create a self-built app",
				credentialsStepGetCredentials: "3) Get App ID and App Secret from Credentials page",
				credentialsStepOpenPlatform: "1) Go to Feishu Open Platform (open.feishu.cn)",
				credentialsStepPermissions: "4) Enable required permissions: im:message, im:chat, contact:user.base:readonly",
				credentialsStepPublish: "5) Publish the app or add it to a test group",
				credentialsTitle: "Feishu credentials",
				domainFeishu: "Feishu (feishu.cn) - China",
				domainLark: "Lark (larksuite.com) - International",
				domainPrompt: "Which Feishu domain?",
				examples: "Examples:",
				existingBotPrompt: "We found an existing bot (App ID: {appId}). Use it for this setup?",
				fetchingConfig: "Fetching configuration results...",
				groupPolicyAllowlist: "Allowlist - only respond in specific groups",
				groupPolicyDisabled: "Disabled - don't respond in groups",
				groupPolicyOpen: "Open - respond in all groups (requires mention)",
				groupPolicyPrompt: "Group chat policy",
				scanCompleted: "Scan completed.",
				scanDenied: "User denied authorization. Falling back to manual input.",
				scanError: "Registration error: {error}. Falling back to manual input.",
				scanExpired: "Session expired. Falling back to manual input.",
				scanQr: "Scan the QR with Lark/Feishu on your phone. If the mobile app does not react, rerun setup and choose manual input.",
				scanTimedOut: "Scan timed out. Falling back to manual input.",
				scanTitle: "Feishu scan-to-create",
				scanUnavailable: "Scan-to-create is not available in this environment. Falling back to manual input.",
				setupMethodManual: "Enter App ID and App Secret manually",
				setupMethodPrompt: "How do you want to connect Feishu?",
				setupMethodScan: "Scan a QR code to create a bot automatically",
				setupTitle: "Feishu setup"
			},
			telegram: {
				allowFromInvalid: "Telegram allowFrom requires numeric sender ids. DM your bot first, then copy from.id from logs or getUpdates.",
				allowFromPrompt: "Telegram allowFrom (numeric sender id)",
				allowlistTitle: "Telegram allowlist",
				botToken: "Telegram bot token",
				tokenEnvPrompt: "TELEGRAM_BOT_TOKEN detected. Use env var?",
				tokenEnvTip: "Tip: you can also set TELEGRAM_BOT_TOKEN in your env.",
				tokenHelpCopyToken: "3) Copy the token (looks like 123456:ABC...)",
				tokenHelpNewBot: "2) Run /newbot (or /mybots)",
				tokenHelpOpenBotFather: "1) Open Telegram and chat with @BotFather",
				tokenInputPrompt: "Enter Telegram bot token",
				tokenKeepPrompt: "Telegram token already configured. Keep it?",
				userIdHelpGetUpdates: "2) Or call https://api.telegram.org/bot<bot_token>/getUpdates and read message.from.id",
				userIdHelpLogs: "1) DM your bot, then read from.id in `{command}` (safest)",
				userIdHelpThirdParty: "3) Third-party: DM @userinfobot or @getidsbot",
				userIdTitle: "Telegram user id",
				website: "Website: {url}"
			},
			discord: {
				allowFromInvalidWithoutToken: "Bot token missing; use numeric user ids (or mention form) only.",
				allowFromPrompt: "Discord allowFrom (usernames or ids)",
				allowlistIntro: "Allowlist Discord DMs by username (we resolve to user ids).",
				allowlistTitle: "Discord allowlist",
				botToken: "Discord bot token",
				channelsLabel: "Discord channels",
				examples: "Examples:",
				multipleEntries: "Multiple entries: comma-separated.",
				tokenEnvPrompt: "DISCORD_BOT_TOKEN detected. Use env var?",
				tokenHelpCopyToken: "2) Bot -> Add Bot -> Reset Token -> copy token",
				tokenHelpCreateApplication: "1) Discord Developer Portal -> Applications -> New Application",
				tokenHelpInviteBot: "3) OAuth2 -> URL Generator -> scope 'bot' -> invite to your server",
				tokenHelpMessageContentIntent: "Tip: enable Message Content Intent if you need message text. (Bot -> Privileged Gateway Intents -> Message Content Intent)",
				tokenInputPrompt: "Enter Discord bot token",
				tokenKeepPrompt: "Discord token already configured. Keep it?"
			},
			googlechat: {
				allowFromPrompt: "Google Chat allowFrom (users/<id> or raw email; avoid users/<email>)",
				appUrl: "App URL",
				appUrlRecommended: "App URL (recommended)",
				authMethod: "Google Chat auth method",
				projectNumber: "Project number",
				serviceAccountFile: "Service account JSON file",
				serviceAccountInline: "Paste service account JSON",
				serviceAccountJson: "Service account JSON (single line)",
				serviceAccountPath: "Service account JSON path",
				setupAudience: "Webhook verification requires audience type + audience value.",
				setupScopes: "Set the Chat API scopes in your service account and configure the Chat app URL.",
				setupServiceAccount: "Google Chat apps use service-account auth and an HTTPS webhook.",
				setupTitle: "Google Chat setup",
				useEnvPrompt: "Use GOOGLE_CHAT_SERVICE_ACCOUNT env vars?",
				webhookAudienceType: "Webhook audience type"
			},
			line: {
				allowFromInvalid: "LINE allowFrom requires raw user ids like U1234567890abcdef1234567890abcdef.",
				allowFromPrompt: "LINE allowFrom (user id)",
				allowlistIntro: "Allowlist LINE DMs by user id.",
				allowlistTitle: "LINE allowlist",
				channelAccessToken: "channel access token",
				channelSecret: "channel secret",
				completionDefaultWebhook: "Default webhook URL: https://<gateway-host>/line/webhook",
				completionEnableWebhook: "Enable Use webhook in the LINE console after saving credentials.",
				completionWebhookPath: "If you set channels.line.webhookPath, update the URL to match.",
				examples: "Examples:",
				helpCopyCredentials: "2) Copy the channel access token and channel secret",
				helpEnableWebhook: "3) Enable Use webhook in the Messaging API settings",
				helpOpenConsole: "1) Open the LINE Developers Console and create or pick a Messaging API channel",
				helpWebhookUrl: "4) Point the webhook at https://<gateway-host>/line/webhook",
				idsCaseSensitive: "LINE ids are case-sensitive.",
				messagingApiTitle: "LINE Messaging API",
				multipleEntries: "Multiple entries: comma-separated.",
				secretEnvPrompt: "LINE_CHANNEL_SECRET detected. Use env var?",
				secretInputPrompt: "Enter LINE channel secret",
				secretKeepPrompt: "LINE channel secret already configured. Keep it?",
				tokenEnvPrompt: "LINE_CHANNEL_ACCESS_TOKEN detected. Use env var?",
				tokenInputPrompt: "Enter LINE channel access token",
				tokenKeepPrompt: "LINE channel access token already configured. Keep it?",
				webhookTitle: "LINE webhook"
			},
			slack: {
				allowFromInvalidWithoutToken: "Slack token missing; use user ids (or mention form) only.",
				allowFromPrompt: "Slack allowFrom (usernames or ids)",
				allowlistIntro: "Allowlist Slack DMs by username (we resolve to user ids).",
				allowlistTitle: "Slack allowlist",
				appToken: "Slack app token",
				appTokenInput: "Enter Slack app token (xapp-...)",
				appTokenKeep: "Slack app token already configured. Keep it?",
				botToken: "Slack bot token",
				botTokenInput: "Enter Slack bot token (xoxb-...)",
				botTokenKeep: "Slack bot token already configured. Keep it?",
				channelsLabel: "Slack channels",
				envPrompt: "SLACK_BOT_TOKEN + SLACK_APP_TOKEN detected. Use env vars?",
				examples: "Examples:",
				interactiveRepliesPrompt: "Enable Slack interactive replies (buttons/selects) for agent responses?",
				multipleEntries: "Multiple entries: comma-separated.",
				socketModeTokensTitle: "Slack socket mode tokens"
			},
			mattermost: {
				baseUrlPrompt: "Enter Mattermost base URL",
				botToken: "bot token",
				botTokenInput: "Enter Mattermost bot token",
				botTokenKeep: "Mattermost bot token already configured. Keep it?",
				botTokenTitle: "Mattermost bot token",
				envPrompt: "MATTERMOST_BOT_TOKEN + MATTERMOST_URL detected. Use env vars?",
				helpBaseUrl: "3) Use your server base URL (e.g., https://chat.example.com)",
				helpBotMember: "Tip: the bot must be a member of any channel you want it to monitor.",
				helpCreateBot: "2) Create a bot + copy its token",
				helpOpenConsole: "1) Mattermost System Console -> Integrations -> Bot Accounts"
			},
			nextcloudTalk: {
				allowFromPrompt: "Nextcloud Talk allowFrom (user id)",
				apiPassword: "API password",
				apiPasswordInput: "Enter Nextcloud Talk API password",
				apiPasswordKeep: "Nextcloud Talk API password already configured. Keep it?",
				apiUserPrompt: "Nextcloud Talk API user",
				botSecret: "bot secret",
				botSecretEnvPrompt: "NEXTCLOUD_TALK_BOT_SECRET detected. Use env var?",
				botSecretInput: "Enter Nextcloud Talk bot secret",
				botSecretKeep: "Nextcloud Talk bot secret already configured. Keep it?",
				configureApiCredentials: "Configure optional Nextcloud Talk API credentials for room lookups?",
				helpCopySecret: "3) Copy the shared secret you used in the command",
				helpEnableRoom: "4) Enable the bot in your Nextcloud Talk room settings",
				helpEnvTip: "Tip: you can also set NEXTCLOUD_TALK_BOT_SECRET in your env.",
				helpInstallCommand: "2) Run: ./occ talk:bot:install \"OpenClaw\" \"<shared-secret>\" \"<webhook-url>\" --feature webhook --feature response --feature reaction",
				helpSsh: "1) SSH into your Nextcloud server",
				instanceUrlPrompt: "Enter Nextcloud instance URL (e.g., https://cloud.example.com)",
				setupTitle: "Nextcloud Talk bot setup",
				userIdHelpAdmin: "1) Check the Nextcloud admin panel for user IDs",
				userIdHelpLogs: "2) Or look at the webhook payload logs when someone messages",
				userIdHelpLowercase: "3) User IDs are typically lowercase usernames in Nextcloud",
				userIdTitle: "Nextcloud Talk user id"
			},
			msteams: {
				allowFromPrompt: "MS Teams allowFrom (usernames or ids)",
				allowlistIntro: "Allowlist MS Teams DMs by display name, UPN/email, or user id.",
				allowlistResolve: "We resolve names to user IDs via Microsoft Graph when credentials allow.",
				allowlistTitle: "MS Teams allowlist",
				appIdPrompt: "Enter MS Teams App ID",
				appPasswordPrompt: "Enter MS Teams App Password",
				channelLookupFailed: "Channel lookup failed; keeping entries as typed. {error}",
				channelsLabel: "MS Teams channels",
				couldNotResolve: "Could not resolve: {entries}",
				credentialsKeep: "MS Teams credentials already configured. Keep them?",
				credentialsTitle: "MS Teams credentials",
				delegatedAuthConfigured: "Delegated auth configured",
				delegatedAuthPrompt: "Enable delegated auth? (required for reactions and write operations)",
				delegatedAuthRetry: "You can retry later via the setup wizard.",
				delegatedAuthTitle: "MS Teams delegated auth",
				delegatedOAuthProgress: "MSTeams Delegated OAuth",
				enterAtLeastOneUser: "Enter at least one user.",
				envPrompt: "MSTEAMS_APP_ID + MSTEAMS_APP_PASSWORD + MSTEAMS_TENANT_ID detected. Use env vars?",
				examples: "Examples:",
				graphLookupUnavailable: "Graph lookup unavailable. Use user IDs only.",
				helpAzureBot: "1) Azure Bot registration -> get App ID + Tenant ID",
				helpClientSecret: "2) Add a client secret (App Password)",
				helpEnvTip: "Tip: you can also set MSTEAMS_APP_ID / MSTEAMS_APP_PASSWORD / MSTEAMS_TENANT_ID.",
				helpWebhook: "3) Set webhook URL + messaging endpoint",
				resolvedChannels: "Resolved channels: {entries}",
				resolvedTeams: "Resolved teams: {entries}",
				tenantIdPrompt: "Enter MS Teams Tenant ID",
				unresolvedKept: "Unresolved (kept as typed): {entries}"
			},
			whatsapp: {
				allowedSenderNumbers: "Allowed sender numbers (comma-separated, E.164)",
				allowFromPrompt: "WhatsApp allowFrom (optional pre-allowlist)",
				allowlistModeEnabled: "Allowlist mode enabled.",
				allowlistTitle: "WhatsApp allowlist",
				credentialsStored: "Credentials are stored under {authDir}/ for future runs.",
				dmAccessTitle: "WhatsApp DM access",
				dmPolicyAllowlistOnly: "Allowlist only (block unknown senders)",
				dmPolicyDisabled: "Disabled (ignore WhatsApp DMs)",
				dmPolicyPrompt: "WhatsApp DM policy",
				dmPolicySetAllowlist: "- dmPolicy set to allowlist (pairing skipped)",
				helpTitle: "WhatsApp help",
				keepCurrentAllowFrom: "Keep current allowFrom",
				linkLater: "Run `{command}` later to link WhatsApp.",
				linkNowPrompt: "Link WhatsApp now (QR)?",
				linkingTitle: "WhatsApp linking",
				numberTitle: "WhatsApp number",
				ownerNumberNote: "We need the sender/owner number so OpenClaw can allowlist you.",
				personalNumberPrompt: "Your personal WhatsApp number (the phone you will message from)",
				personalPhoneLabel: "This is my personal phone number",
				personalPhoneModeEnabled: "Personal phone mode enabled.",
				personalPhoneTitle: "WhatsApp personal phone",
				phoneSetupPrompt: "WhatsApp phone setup",
				relinkPrompt: "WhatsApp already linked. Re-link now?",
				scanQr: "Scan the QR with WhatsApp on your phone.",
				separatePhoneLabel: "Separate phone just for OpenClaw",
				setAllowFromNumbers: "Set allowFrom to specific numbers",
				unsetAllowFromDefault: "Unset allowFrom (default)",
				unsetAllowFromPairing: "Unset allowFrom (use pairing approvals only)"
			},
			nostr: {
				allowFromPrompt: "Nostr allowFrom",
				allowlistIntro: "Allowlist Nostr DMs by npub or hex pubkey.",
				allowlistTitle: "Nostr allowlist",
				examples: "Examples:",
				helpEnvVars: "Env vars supported: NOSTR_PRIVATE_KEY (default account only).",
				helpPrivateKeyFormat: "Use a Nostr private key in nsec or 64-character hex format.",
				helpRelaysOptional: "Relay URLs are optional. Leave blank to keep the default relay set.",
				multipleEntries: "Multiple entries: comma-separated.",
				privateKeyEnvPrompt: "NOSTR_PRIVATE_KEY detected. Use env var?",
				privateKeyInput: "Nostr private key (nsec... or hex)",
				privateKeyKeep: "Nostr private key already configured. Keep it?",
				privateKeyTitle: "Nostr private key",
				relaysTitle: "Nostr relays",
				relayUrlsKeep: "Relay URLs set ({value}). Keep them?",
				relayUrlsPrompt: "Relay URLs (comma-separated, optional)",
				relaysWsOnly: "Use ws:// or wss:// relay URLs.",
				setupTitle: "Nostr setup"
			},
			irc: {
				allowFromInvalid: "Use an IRC nick or nick!user@host entry.",
				allowFromPrompt: "IRC allowFrom (nick or nick!user@host)",
				allowlistIntro: "Allowlist IRC DMs by sender.",
				allowlistTitle: "IRC allowlist",
				autoJoinPrompt: "Auto-join IRC channels (optional, comma-separated)",
				envPrompt: "IRC_HOST and IRC_NICK detected. Use env vars?",
				examples: "Examples:",
				helpEnvVars: "Env vars supported: IRC_HOST, IRC_PORT, IRC_TLS, IRC_NICK, IRC_USERNAME, IRC_REALNAME, IRC_PASSWORD, IRC_CHANNELS, IRC_NICKSERV_PASSWORD, IRC_NICKSERV_REGISTER_EMAIL.",
				helpGroupControl: "Set channels.irc.groupPolicy=\"allowlist\" and channels.irc.groups for tighter channel control.",
				helpMentionGate: "Note: IRC channels are mention-gated by default. To allow unmentioned replies, set channels.irc.groups[\"#channel\"].requireMention=false (or \"*\" for all).",
				helpNeedsHostNick: "IRC needs server host + bot nick.",
				helpNickServOptional: "Optional: NickServ identify/register can be configured after the basic account fields.",
				helpRecommendedTls: "Recommended: TLS on port 6697.",
				multipleEntries: "Multiple entries: comma-separated.",
				nextRestartGateway: "Next: restart gateway and verify status.",
				nextStatusCommand: "Command: openclaw channels status --probe",
				nextStepsTitle: "IRC next steps",
				nickPrompt: "IRC nick",
				nickServConfigurePrompt: "Configure NickServ identify/register?",
				nickServPasswordEnvPrompt: "IRC_NICKSERV_PASSWORD detected. Use env var?",
				nickServPasswordPrompt: "NickServ password (blank to disable NickServ auth)",
				nickServRegisterEmailPrompt: "NickServ register email",
				nickServRegisterPrompt: "Send NickServ REGISTER on connect?",
				nickServServicePrompt: "NickServ service nick",
				nickServUpdatePrompt: "Update NickServ settings?",
				realNamePrompt: "IRC real name",
				requireMentionPrompt: "Require @mention to reply in IRC channels?",
				serverHostPrompt: "IRC server host",
				serverPortPrompt: "IRC server port",
				setupTitle: "IRC setup",
				tlsPrompt: "Use TLS for IRC?",
				usernamePrompt: "IRC username"
			},
			tlon: {
				addGroupsPrompt: "Add group channels manually? (optional)",
				autoDiscoveryPrompt: "Enable auto-discovery of group channels?",
				dmAllowlistPrompt: "DM allowlist (comma-separated ship names)",
				groupChannelsPrompt: "Group channels (comma-separated)",
				helpExampleShip: "Example ship: ~sampel-palnet",
				helpExampleUrl: "Example URL: https://your-ship-host",
				helpNeedsUrlCode: "You need your Urbit ship URL and login code.",
				helpPrivateNetwork: "If your ship URL is on a private network (LAN/localhost), you must explicitly allow it during setup.",
				loginCodePrompt: "Login code",
				privateNetworkPrompt: "Ship URL looks like a private/internal host. Allow private network access? (SSRF risk)",
				restrictDmsPrompt: "Restrict DMs with an allowlist?",
				setupTitle: "Tlon setup",
				shipPrompt: "Ship name",
				shipUrlPrompt: "Ship URL"
			},
			synologyChat: {
				accessControlTitle: "Synology Chat access control",
				allowedUserIdsInvalid: "Synology Chat user ids must be numeric.",
				allowedUserIdsPrompt: "Allowed Synology Chat user ids",
				allowlistIntro: "Allowlist Synology Chat DMs by numeric user id.",
				allowlistTitle: "Synology Chat allowlist",
				defaultPath: "Default path: {path}",
				examples: "Examples:",
				helpAllowedUsers: "4) Keep allowed user IDs handy for DM allowlisting",
				helpIncomingWebhook: "1) Create an incoming webhook in Synology Chat and copy its URL",
				helpOutgoingWebhook: "2) Create an outgoing webhook and copy its secret token",
				helpPointWebhook: "3) Point the outgoing webhook to https://<gateway-host>{path}",
				incomingWebhookHelpReplies: "This is the URL OpenClaw uses to send replies back to Chat.",
				incomingWebhookHelpUseUrl: "Use the incoming webhook URL from Synology Chat integrations.",
				incomingWebhookKeep: "Incoming webhook URL set ({value}). Keep it?",
				incomingWebhookTitle: "Synology Chat incoming webhook",
				incomingWebhookUrlPrompt: "Incoming webhook URL",
				multipleEntries: "Multiple entries: comma-separated.",
				outgoingWebhookPathHelp: "Change this only if you need multiple Synology Chat webhook routes.",
				outgoingWebhookPathKeep: "Outgoing webhook path set ({value}). Keep it?",
				outgoingWebhookPathPrompt: "Outgoing webhook path (optional)",
				outgoingWebhookPathTitle: "Synology Chat outgoing webhook path",
				setupTitle: "Synology Chat webhook setup",
				tokenEnvPrompt: "SYNOLOGY_CHAT_TOKEN detected. Use env var?",
				tokenInput: "Enter Synology Chat outgoing webhook token",
				tokenKeep: "Synology Chat webhook token already configured. Keep it?",
				webhookTokenTitle: "Synology Chat webhook token"
			},
			signal: {
				accountKeep: "Signal account set ({value}). Keep it?",
				allowFromPrompt: "Signal allowFrom (E.164 or uuid)",
				allowlistIntro: "Allowlist Signal DMs by sender id.",
				allowlistTitle: "Signal allowlist",
				botNumberPrompt: "Signal bot number (E.164)",
				examples: "Examples:",
				installPrompt: "signal-cli not found. Install now?",
				multipleEntries: "Multiple entries: comma-separated.",
				nextLinkDevice: "Link device with: signal-cli link -n \"OpenClaw\"",
				nextScanQr: "Scan QR in Signal -> Linked Devices",
				nextStepsTitle: "Signal next steps",
				reinstallPrompt: "signal-cli detected. Reinstall/update now?"
			},
			zalo: {
				allowFromNumeric: "Use a numeric Zalo user id",
				allowFromPrompt: "Zalo allowFrom (user id)",
				botToken: "bot token",
				botTokenTitle: "Zalo bot token",
				helpCreateBot: "2) Create a bot and get the token",
				helpEnvTip: "Tip: you can also set ZALO_BOT_TOKEN in your env.",
				helpOpenPlatform: "1) Open Zalo Bot Platform: https://bot.zaloplatforms.com",
				helpTokenFormat: "3) Token looks like 12345689:abc-xyz",
				tokenEnvPrompt: "ZALO_BOT_TOKEN detected. Use env var?",
				tokenInput: "Enter Zalo bot token",
				tokenKeep: "Zalo token already configured. Keep it?",
				webhookModePrompt: "Use webhook mode for Zalo?",
				webhookPathPrompt: "Webhook path (optional)",
				webhookSecret: "webhook secret",
				webhookSecretInput: "Webhook secret (8-256 chars)",
				webhookSecretKeep: "Zalo webhook secret already configured. Keep it?",
				webhookSecretLength: "Webhook secret must be between 8 and 256 characters.",
				webhookTitle: "Zalo webhook",
				webhookUrlPrompt: "Webhook URL (https://...) "
			},
			zalouser: {
				allowFromPlaceholder: "Alice, 123456789, or leave empty to configure later",
				allowFromPrompt: "Zalouser allowFrom (name or user id)",
				allowlistTitle: "Zalo Personal allowlist",
				couldNotResolve: "Could not resolve: {entries}. Use numeric user ids or exact friend names.",
				directChatsBlocked: "Direct chats will stay blocked until you add people later.",
				dmAccessTitle: "Zalo Personal DM access",
				dmHelpAllowlist: "- allowlist: only listed people can DM",
				dmHelpAllowlistEmpty: "If you choose allowlist now, you can leave it empty and add people later.",
				dmHelpDisabled: "- disabled: ignore DMs",
				dmHelpOpen: "- open: anyone can DM",
				dmHelpPairing: "- pairing (default): unknown people get a pairing code",
				dmHelpSeparate: "Direct chats are configured separately from group chats.",
				dmPolicyPrompt: "Zalo Personal DM policy",
				groupChatsBlocked: "Group chats will stay blocked until you add groups later.",
				groupLookupFailed: "Group lookup failed; keeping entries as typed. {error}",
				groupMentionRequirement: "Mention requirement stays on by default for groups you allow later.",
				groupsLookupTip: "Tip: use `{command}` after onboarding to find group IDs.",
				groupsPlaceholder: "Family, Work, 123456789, or leave empty for now",
				groupsTitle: "Zalo groups",
				helpQrLogin: "Zalo Personal Account login via QR code.",
				helpZcaJs: "This plugin uses zca-js directly (no external CLI dependency).",
				keepSessionPrompt: "Zalo Personal already logged in. Keep session?",
				loginPendingTitle: "Login pending",
				loginQrPrompt: "Login via QR code now?",
				noDmAllowlist: "No DM allowlist entries added yet.",
				noGroupAllowlist: "No group allowlist entries added yet.",
				peersLookupTip: "Tip: use `{command}` to look up people after onboarding.",
				qrImageSaved: "QR image saved to: {path}",
				qrImageWriteFailed: "Could not write QR image file; use gateway web login UI instead.",
				qrLoginTitle: "QR Login",
				qrScannedPrompt: "Did you scan and approve the QR on your phone?",
				scanApproveContinue: "Scan + approve on phone, then continue.",
				setupTitle: "Zalo Personal Setup"
			},
			twitch: {
				accessTokenKeep: "Access token already configured. Keep it?",
				allowFromPrompt: "Twitch allowFrom (user IDs, one per line, recommended for security)",
				botUsernamePrompt: "Twitch bot username",
				channelJoinPrompt: "Channel to join",
				clientIdPrompt: "Twitch Client ID",
				clientSecretPrompt: "Twitch Client Secret (for token refresh)",
				envPrompt: "Twitch env var OPENCLAW_TWITCH_ACCESS_TOKEN detected. Use env token?",
				helpCopyToken: "3. Copy the token (starts with 'oauth:') and Client ID",
				helpCreateApp: "1. Create a Twitch application at https://dev.twitch.tv/console",
				helpEnvVars: "Env vars supported: OPENCLAW_TWITCH_ACCESS_TOKEN",
				helpGenerateToken: "2. Generate a token with scopes: chat:read and chat:write",
				helpRequiresBot: "Twitch requires a bot account with OAuth token.",
				helpTokenTools: "   Use https://twitchtokengenerator.com/ or https://twitchapps.com/tmi/",
				oauthTokenPrompt: "Twitch OAuth token (oauth:...)",
				refreshTokenInputPrompt: "Twitch Refresh Token",
				refreshTokenPrompt: "Enable automatic token refresh (requires client secret and refresh token)?",
				setupTitle: "Twitch setup"
			},
			imessage: {
				imsgFound: "imsg found",
				imsgMissing: "imsg missing"
			},
			channelsPrimer: {
				approveWith: "Approve with: {command}",
				docs: "Docs: {link}",
				inboundSafety: "Inbound DM safety defaults to pairing: unknown senders get a pairing code first.",
				multiUserDm: "For multi-user DMs, isolate sessions with: {command} (or \"per-account-channel-peer\" for multi-account channels).",
				openDm: "Open/public DMs require dmPolicy=\"open\" plus allowFrom=[\"*\"].",
				title: "How channels work",
				blurbs: {
					clickclack: "self-hosted chat via first-class ClickClack bot tokens.",
					discord: "very well supported right now.",
					feishu: "飞书/Lark enterprise messaging.",
					googlechat: "Google Workspace Chat app with HTTP webhook.",
					imessage: "Local iMessage/SMS through the imsg bridge, including private API message actions when enabled.",
					irc: "classic IRC networks with DM/channel routing and pairing controls.",
					line: "LINE Messaging API webhook bot.",
					mattermost: "self-hosted Slack-style chat; install the plugin to enable.",
					matrix: "open protocol; install the plugin to enable.",
					msteams: "Teams SDK; enterprise support.",
					nextcloudTalk: "Self-hosted chat via Nextcloud Talk webhook bots.",
					nostr: "Decentralized protocol; encrypted DMs via NIP-04.",
					qqbot: "Connect to QQ via official QQ Bot API",
					signal: "signal-cli linked device; more setup (David Reagans: \"Hop on Discord.\").",
					slack: "supported (Socket Mode).",
					synologyChat: "Connect your Synology NAS Chat to OpenClaw with full agent capabilities.",
					telegram: "simplest way to get started — register a bot with @BotFather and get going.",
					tlon: "decentralized messaging on Urbit; install the plugin to enable.",
					twitch: "Twitch chat integration",
					wecom: "Enterprise messaging and documents, scheduling, task tools.",
					whatsapp: "works with your own number; recommend a separate phone + eSIM.",
					yuanbao: "Tencent Yuanbao AI assistant conversation channel.",
					zalo: "Vietnam-focused messaging platform with Bot API.",
					zalouser: "Zalo personal account via QR code login."
				}
			},
			search: {
				chooseProvider: "Choose a provider. Some providers need an API key, and some work key-free.",
				configured: "configured",
				configureLaterHint: "Configure later with openclaw configure --section web",
				docsLine: "Docs: {url}",
				intro: "Web search lets your agent look things up online.",
				keyFree: "key-free",
				noProvidersAction: "Enable plugins or remove deny rules, then run setup again.",
				noProvidersByPolicy: "No web search providers are currently available under this plugin policy.",
				providerPrompt: "Search provider",
				title: "Web search"
			},
			finalize: {
				addNodes: "Add nodes for extra features:",
				alreadyInstalled: "Gateway service already installed",
				backupWorkspace: "Back up your agent workspace.",
				browserHatch: "Hatch in Browser",
				codexNativeSearchOnly: "Used only for Codex-capable models.",
				codexNativeSearchTitle: "Codex native search",
				controlUiTitle: "Control UI",
				controlUiDocs: "Docs: https://docs.openclaw.ai/web/control-ui",
				dashboardCopyPaste: "Copy/paste this URL in a browser on this machine to control OpenClaw.",
				dashboardLinkWithToken: "Dashboard link (with token): {url}",
				dashboardOpened: "Opened in your browser. Keep that tab to control OpenClaw.",
				dashboardOpenAnytime: "Open the dashboard anytime: {command}",
				dashboardReady: "Dashboard ready",
				dashboardTokenMemory: "Web UI keeps dashboard URL tokens in memory for the current tab and strips them from the URL after load.",
				dashboardTokenPrompt: "If prompted: paste the token into Control UI settings (or use the tokenized dashboard URL).",
				dashboardWhenReady: "When you're ready: {command}",
				daemonRuntime: "Gateway service runtime",
				daemonRuntimeNode: "Node (recommended)",
				daemonRuntimeNodeHint: "Required for WhatsApp + Telegram. Bun can corrupt memory on reconnect.",
				editBootstrap: "Edit BOOTSTRAP.md later to change how the agent introduces itself.",
				bootstrapHatchMessage: "Wake up, my friend!",
				firstTerminalChat: "The first Terminal chat run will send: \"Wake up, my friend!\"",
				gatewayInstallBlocked: "Gateway install blocked:",
				gatewayInstallFixAuth: "Fix gateway auth config/token input and rerun setup.",
				gatewayNotDetected: "Gateway not detected yet.",
				gatewayNotDetectedStatus: "Gateway: not detected{detail}",
				gatewayReachable: "Gateway: reachable",
				gatewayService: "Gateway service",
				gatewayServiceInstalled: "Gateway service installed.",
				gatewayServiceInstalling: "Installing Gateway service...",
				gatewayServiceInstallFailed: "Gateway service install failed.",
				gatewayServiceInstallFailedWithError: "Gateway service install failed: {error}",
				gatewayServicePreparing: "Preparing Gateway service...",
				gatewayServiceRestarted: "Gateway service restarted.",
				gatewayServiceRestarting: "Restarting Gateway service...",
				gatewayServiceRestartScheduled: "Gateway service restart scheduled.",
				gatewayServiceUninstalled: "Gateway service uninstalled.",
				gatewayServiceUninstalling: "Uninstalling Gateway service...",
				gatewayTokenGenerate: "Generate token: {command}",
				gatewayTokenShared: "Gateway token: shared auth for the Gateway + Control UI.",
				gatewayTokenStored: "Stored in: $OPENCLAW_CONFIG_PATH (default: ~/.openclaw/openclaw.json) under gateway.auth.token, or in OPENCLAW_GATEWAY_TOKEN.",
				gatewayTokenView: "View token: {command}",
				gatewayWsUrl: "Gateway WS: {url}",
				hatchLater: "Hatch later",
				hatchPrompt: "How do you want to hatch your agent?",
				hatchYourAgent: "Hatch your agent",
				healthCheckHelp: "Health check help",
				installGateway: "Install Gateway service (recommended)",
				laterTitle: "Later",
				managedWebSearchSkipped: "Managed web search provider was skipped.",
				noBackgroundGatewayExpected: "Setup was run without Gateway service install, so no background gateway is expected.",
				nodeAndroid: "Android app (camera/canvas)",
				nodeIos: "iOS app (camera/canvas)",
				nodeMac: "macOS app (system + notifications)",
				optionalApps: "Optional apps",
				outroDashboardLink: "Onboarding complete. Use the dashboard link above to control OpenClaw.",
				outroDashboardOpened: "Onboarding complete. Dashboard opened; keep that tab to control OpenClaw.",
				outroSeeded: "Onboarding complete. Web UI seeded in the background; open it anytime with the dashboard link above.",
				quickstartNodeRuntime: "QuickStart uses Node for the Gateway service (stable + supported).",
				reinstall: "Reinstall",
				rerunInstallDaemon: "Or rerun with: {command}",
				restart: "Restart",
				securityReminder: "Running agents on your computer is risky — harden your setup: https://docs.openclaw.ai/security",
				secretRefAuthFailed: "Could not resolve {field} SecretRef for setup auth.",
				skipHealthNextTime: "Or skip this probe next time: {command}",
				skipControlUi: "Skipping Control UI/TUI prompts.",
				startGatewayNow: "Start now: {command}",
				systemdInstallSkipped: "Systemd user services are unavailable; skipping service install. Use your container supervisor or `docker compose up -d`.",
				systemdLingerReason: "Linux installs use a systemd user service by default. Without lingering, systemd stops the user session on logout/idle and kills the Gateway.",
				systemdUnavailable: "Systemd user services are unavailable. Skipping lingering checks and service install.",
				terminalHatch: "Hatch in Terminal (recommended)",
				webDocs: "Docs: https://docs.openclaw.ai/tools/web",
				webSearchAutoDetected: "Web search is available via {provider} (auto-detected).",
				webSearchDisabled: "Web search ({provider}) is configured but disabled.",
				webSearchEnabled: "Web search is enabled, so your agent can look things up online when needed.",
				webSearchGetKey: "Get your key at: {url}",
				webSearchAuthProfile: "Credential: existing {provider} auth profile.",
				webSearchKeyEnv: "API key: provided via {env} env var.",
				webSearchKeyRef: "API key: configured via secret reference.",
				webSearchKeyStored: "API key: stored in config.",
				webSearchNeedsKey: "web_search will not work until a key is added.",
				webSearchNoKey: "Provider {provider} is selected but no API key was found.",
				webSearchOAuthProfile: "Credential: existing {provider} OAuth sign-in.",
				webSearchProvider: "Provider: {provider}",
				webSearchProviderUnavailable: "Web search provider {provider} is selected but unavailable under the current plugin policy.",
				webSearchReenable: "Re-enable: {command}",
				webSearchSkipped: "Web search was skipped. You can enable it later:",
				webSearchTitle: "Web search",
				webSearchUnavailableAction: "web_search will not work until the provider is re-enabled or a different provider is selected.",
				webUiUrl: "Web UI: {url}",
				webUiWithTokenUrl: "Web UI (with token): {url}",
				whatNow: "What now: https://openclaw.ai/showcase (\"What People Are Building\").",
				whatNowTitle: "What now",
				workspaceBackupTitle: "Workspace backup",
				workspaceDocs: "Docs: https://docs.openclaw.ai/concepts/agent-workspace",
				workspaceReady: "Your workspace is ready."
			},
			gatewayNotes: {
				bindTitle: "Gateway bind",
				tailscaleBindLoopback: "Tailscale exposure requires bind=loopback. I will switch the bind address to loopback.",
				tailscaleFunnelPassword: "Tailscale Funnel requires password auth. I will switch Gateway auth to password."
			}
		}
	},
	"zh-CN": {
		common: {
			back: "返回",
			done: "完成",
			docs: "文档:",
			finished: "完成",
			noAuth: "不启用认证",
			password: "密码",
			required: "必填",
			minute: "{count} 分钟",
			minutes: "{count} 分钟",
			second: "{count} 秒",
			seconds: "{count} 秒",
			skip: "跳过",
			skipForNow: "暂时跳过",
			tokenRecommended: "令牌(推荐)"
		},
		wizard: {
			customProvider: {
				apiBaseUrl: "API 基础 URL",
				apiKeyPrompt: "API Key(不需要可留空)",
				changeBaseUrl: "修改基础 URL",
				changeBaseUrlAndModel: "修改基础 URL 和模型",
				changeModel: "修改模型",
				compatibility: "端点兼容性",
				compatibilityAnthropic: "兼容 Anthropic",
				compatibilityAnthropicHint: "使用 /messages",
				compatibilityOpenAi: "兼容 OpenAI",
				compatibilityOpenAiHint: "使用 /chat/completions",
				compatibilityOpenAiResponses: "兼容 OpenAI Responses",
				compatibilityOpenAiResponsesHint: "使用 /responses",
				compatibilityUnknown: "未知(自动检测)",
				compatibilityUnknownHint: "先探测 OpenAI Chat、OpenAI Responses,再探测 Anthropic 端点",
				detectionFailed: "无法检测端点类型。",
				detectionFailedNote: "这个端点没有响应 OpenAI Chat、OpenAI Responses 或 Anthropic 风格的请求。",
				detectionNoteTitle: "端点检测",
				detectionProgress: "正在检测端点类型...",
				detectedAnthropic: "检测到兼容 Anthropic 的端点。",
				detectedOpenAi: "检测到兼容 OpenAI 的端点。",
				detectedOpenAiResponses: "检测到兼容 OpenAI Responses 的端点。",
				endpointId: "端点 ID",
				endpointIdRequired: "端点 ID 必填。",
				endpointIdRenamed: "端点 ID \"{from}\" 已用于不同的基础 URL。将使用 \"{to}\"。",
				endpointIdTitle: "端点 ID",
				imageInput: "这个模型支持图片输入吗?",
				modelAlias: "模型别名(可选)",
				modelAliasPlaceholder: "例如 local、ollama",
				modelId: "模型 ID",
				modelIdPlaceholder: "例如 llama3、claude-3-7-sonnet",
				modelIdRequired: "模型 ID 必填",
				retryChoice: "你想修改哪一项?",
				verifying: "正在验证...",
				verificationFailedError: "验证失败:{error}",
				verificationFailedStatus: "验证失败:状态码 {status}",
				verificationSuccessful: "验证成功。",
				validUrl: "请输入有效 URL(例如 http://...)"
			},
			gateway: {
				accessProtection: "Gateway 访问保护",
				auth: "Gateway 认证",
				authPasswordStoredMessage: "这个 Gateway 密码存在哪里?",
				authPasswordMode: "你想如何提供 Gateway 密码?",
				authTokenMode: "你想如何提供 Gateway 令牌?",
				authTokenStoredMessage: "这个 Gateway 令牌存在哪里?",
				bindAddress: "Gateway 绑定地址",
				bindAuto: "自动(Loopback -> LAN)",
				bindAutoHint: "先尝试 loopback",
				bindCustom: "自定义 IP",
				bindCustomHint: "绑定到一个本机地址",
				bindCustomIp: "自定义 IP 地址",
				bindLan: "LAN (0.0.0.0)",
				bindLanHint: "局域网可访问",
				bindLoopback: "Loopback (127.0.0.1)",
				bindLoopbackHint: "仅本机可访问",
				bindTailnet: "Tailnet(Tailscale IP)",
				bindTailnetHint: "通过 Tailscale 访问",
				existingPasswordConfirm: "使用已有 Gateway 密码({password})?",
				existingTokenConfirm: "使用已有 Gateway 令牌({token})?",
				passwordPrompt: "Gateway 密码",
				plaintextPasswordHint: "直接把密码存入 OpenClaw 配置",
				plaintextPasswordLabel: "现在输入密码",
				plaintextTokenHint: "默认",
				plaintextTokenLabel: "生成/保存明文令牌",
				port: "Gateway 端口",
				refHint: "保存引用而不是明文",
				refLabel: "使用 SecretRef",
				remotePasswordMode: "你想如何提供这个 Gateway 密码?",
				remoteTokenMode: "你想如何提供这个 Gateway 令牌?",
				tailscaleExposure: "Tailscale 暴露方式",
				tailscaleReset: "退出时重置 Tailscale serve/funnel?",
				tokenPlaceholder: "多机器或非 loopback 访问需要使用",
				tokenPrompt: "Gateway 令牌",
				tokenPromptGenerate: "Gateway 令牌(留空则生成)",
				websocketUrl: "Gateway WebSocket URL"
			},
			gatewayTailscale: {
				docsNote: "文档:\nhttps://docs.openclaw.ai/gateway/tailscale\nhttps://docs.openclaw.ai/web",
				funnel: "Funnel",
				funnelHint: "通过 Tailscale Funnel 暴露公网 HTTPS",
				missingBinNote: "没有在 PATH 或 /Applications 中找到 Tailscale。\n请从以下地址安装 Tailscale:\n  https://tailscale.com/download/mac\n\n可以继续设置,但 serve/funnel 运行时会失败。",
				off: "关闭",
				offHint: "不通过 Tailscale 暴露",
				serve: "Serve",
				serveHint: "面向你的 tailnet 设备提供私有 HTTPS",
				warningTitle: "Tailscale 警告"
			},
			hooks: {
				configuredTitle: "Hooks 已配置",
				enable: "启用 hooks?",
				introTitle: "Hooks",
				noHooksMessage: "没有找到可用 hook。你可以稍后在配置中设置 hooks。",
				noHooksTitle: "没有可用 Hooks"
			},
			completion: {
				cacheFailed: "生成 completion 缓存失败。稍后运行 `{command}`。",
				enable: "为 {cli} 启用 {shell} shell completion?",
				installed: "Shell completion 已安装。{reloadHint}",
				reloadPowerShell: "重启 shell 或运行:{command}",
				reloadShell: "重启 shell 或运行:source {profile}",
				title: "Shell completion"
			},
			migration: {
				apply: "现在应用这次迁移?",
				appliedTitle: "迁移已应用",
				cancelled: "迁移已取消",
				complete: "迁移完成。下一步运行 `openclaw doctor`。",
				previewTitle: "迁移预览",
				source: "迁移来源",
				sourceAgentHome: "源 agent home",
				sourcePathHint: "下一步输入源路径",
				targetWorkspace: "目标工作区目录"
			},
			plugins: {
				configureBackHint: "返回分区菜单",
				configureEmpty: "没有找到带可配置字段的插件。",
				configureEmptyTitle: "插件",
				configureFieldsTitle: "插件设置",
				configurePlugin: "配置 {plugin}",
				configureSelect: "选择要配置的插件",
				configureSelectOnboard: "配置插件(选择现在设置,或跳过)",
				configuredCount: "已配置 {configured}/{total}",
				currentValue: "保留当前值({value})",
				downloadFromClawHub: "从 ClawHub 下载({spec})",
				downloadFromNpm: "从 npm 下载({spec})",
				enableFailed: "无法启用 {plugin}:{reason}。",
				fieldsCount: "{count} 个字段",
				installFailed: "安装 {spec} 失败:{error}",
				installFailedShort: "安装失败:{plugin}",
				installPluginPrompt: "安装 {plugin} 插件?",
				installTimedOut: "安装 {spec} 超时,已等待 {duration}。",
				installTimedOutShort: "安装超时:{plugin}",
				installedPlugin: "已安装 {plugin} 插件",
				installingPlugin: "正在安装 {plugin} 插件...",
				installTitle: "插件安装",
				noRemoteInstallSource: "{plugin} 没有可用的远程安装源。返回选择。",
				officialInstall: "安装可选插件",
				officialSkipHint: "继续,不安装可选插件",
				preparingInstall: "正在准备",
				returningToSelection: "返回选择。",
				arrayPromptSuffix: "(逗号分隔,留空则清除)",
				arrayPlaceholder: "value1, value2",
				sensitiveField: "\"{label}\" 是敏感字段。请通过以下方式设置:\n  openclaw config set plugins.entries.{plugin}.config.{field} <value>\n或使用 Web UI 设置页。",
				sensitiveTitle: "敏感字段",
				skipConfigHint: "继续,不配置插件",
				useLocalPluginPath: "使用本地插件路径",
				useLocalPluginPathInstead: "改用本地插件路径?({path})",
				useNpmPackageInstead: "改用 npm 包?({spec})"
			},
			model: {
				allProviders: "所有 provider",
				browseAll: "浏览所有模型",
				configuredTitle: "模型已配置",
				current: "当前值",
				currentNotInCatalog: "当前值(不在目录中)",
				allowed: "已允许",
				allowedNotInCatalog: "已允许(不在目录中)",
				allowlistPicker: "/model 选择器中的模型(多选)",
				allowlistText: "允许的模型(逗号分隔 provider/model;留空则保留当前值)",
				clearAllowlist: "清空模型允许列表?(将显示所有模型)",
				configured: "已配置",
				configuredNotInCatalog: "已配置(不在目录中)",
				defaultModel: "默认模型",
				defaultModelBlankToKeep: "默认模型(留空则保留)",
				defaultSet: "默认模型已设置为 {model}",
				defaultSetForAgent: "agent \"{agent}\" 的默认模型已设置为 {model}。",
				enterManually: "手动输入模型",
				filterByProvider: "按 provider 筛选模型",
				keepCurrent: "保留当前值({value})",
				keepCurrentDefault: "保留当前值(默认:{value})",
				keptExistingDefault: "已保留当前默认模型 {current};{selected} 可用。",
				loadsProviderCatalogs: "加载 provider 模型目录",
				loadingModels: "正在加载可用模型",
				modelCount: "{count} 个模型",
				providerSetupUnavailable: "Provider 设置需要 agent 和运行时上下文。",
				providerSetupUnavailableTitle: "Provider 设置不可用",
				removeProviderModels: "从 /model 选择器中移除这些 provider 模型?",
				resolvesTo: "解析为 {value}"
			},
			remote: {
				auth: "Gateway 认证",
				bonjour: "在局域网发现 Gateway(Bonjour)?",
				connectionMethod: "连接方式",
				directAccessTitle: "直接远程访问",
				enterUrlManually: "手动输入 URL",
				foundGateways: "找到 {count} 个 Gateway",
				fingerprintMissing: "未公布(连接不会固定指纹)",
				gatewayPasswordStoredMessage: "这个 Gateway 密码存在哪里?",
				gatewayTokenStoredMessage: "这个 Gateway 令牌存在哪里?",
				insecureRemoteUrl: "远程主机请使用 wss://,或通过 SSH 隧道使用 ws://127.0.0.1/localhost。紧急绕过:可信私有网络可设置 OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1。",
				directDefaultsTls: "直接远程访问默认使用 TLS。",
				loopbackSshHint: "如果 Gateway 仅监听 loopback,请选择 SSH 隧道并保持 ws://127.0.0.1:18789。",
				noGatewaysFound: "没有找到 Gateway",
				passwordPrompt: "Gateway 密码",
				plaintextPasswordHint: "直接把密码存入 OpenClaw 配置",
				plaintextPasswordLabel: "现在输入密码",
				plaintextTokenHint: "直接把令牌存入 OpenClaw 配置",
				plaintextTokenLabel: "现在输入令牌",
				searchProgress: "正在搜索 Gateway...",
				selectGateway: "选择 Gateway",
				sshTunnel: "SSH 隧道(loopback)",
				sshTunnelTitle: "SSH 隧道",
				tokenPrompt: "Gateway 令牌",
				trustGateway: "信任这个 Gateway?主机:{host} TLS 指纹:{fingerprint}",
				validWebSocketUrl: "URL 必须以 ws:// 或 wss:// 开头",
				websocketUrl: "Gateway WebSocket URL"
			},
			setup: {
				authChoiceRequired: "必须选择认证方式",
				channelsTitle: "频道",
				configHandling: "配置处理",
				existingConfigTitle: "检测到已有配置",
				flowAdvanced: "手动设置",
				flowAdvancedHint: "选择 Gateway 端口、网络暴露、Tailscale 和认证方式。",
				flowQuickstart: "QuickStart(推荐)",
				flowQuickstartHint: "推荐的本地设置。之后可用 {command} 修改细节。",
				intro: "OpenClaw 设置",
				invalidConfigTitle: "配置无效",
				keepCurrent: "保留当前值",
				localGateway: "本机 Gateway",
				localGatewayMissing: "未检测到 Gateway({url})",
				localGatewayReachable: "Gateway 可访问({url})",
				modifyCurrent: "查看并更新",
				pluginCompatibilityTitle: "插件兼容性",
				quickstartOnlyLocal: "QuickStart 仅支持本地 Gateway。将切换到手动模式。",
				quickstartTitle: "QuickStart",
				quickstartAuthTokenDefault: "令牌(默认)",
				quickstartDirectChannels: "直接进入聊天频道设置。",
				quickstartGatewayAuth: "Gateway 认证:{auth}",
				quickstartGatewayBind: "Gateway 绑定:{bind}",
				quickstartGatewayCustomIp: "Gateway 自定义 IP:{host}",
				quickstartGatewayPort: "Gateway 端口:{port}",
				quickstartKeepSettings: "保留当前 Gateway 设置:",
				quickstartTailscaleExposure: "Tailscale 暴露方式:{exposure}",
				remoteConfigured: "远程 Gateway 已配置。",
				remoteGateway: "远程 Gateway(仅信息)",
				remoteGatewayMissing: "尚未配置远程 URL",
				remoteGatewayReachable: "Gateway 可访问({url})",
				remoteGatewayUnreachable: "已配置但无法访问({url})",
				resetBefore: "设置前重置",
				resetConfig: "仅配置",
				resetConfigCredsSessions: "配置 + 凭据 + 会话",
				resetFull: "完全重置(配置 + 凭据 + 会话 + 工作区)",
				resetScope: "重置范围",
				riskNotAccepted: "未确认风险",
				searchTitle: "搜索",
				setupMode: "设置模式",
				secretRefProbeFailed: "无法解析用于设置探测的 {field} SecretRef。",
				skillsTitle: "技能",
				skipChannels: "跳过频道设置。",
				skipSearch: "跳过搜索设置。",
				skipSkills: "跳过技能设置。",
				whatSetup: "你想设置什么?",
				workspaceDirectory: "工作区目录"
			},
			security: {
				askForHelp: "启用工具或暴露到互联网之前,请找有经验的人协助。",
				baselineDmSessions: "共享收件箱:隔离 DM 会话(session.dmScope: per-channel-peer),并尽量减少工具访问权限。",
				baselinePairing: "配对/允许列表 + @ 提及门控。",
				baselineSandbox: "沙箱 + 最小权限工具。",
				baselineSecrets: "不要把密钥放在 agent 可访问的文件系统中。",
				baselineSharedInbox: "多用户/共享收件箱:拆分信任边界(分离 gateway/凭据,最好使用独立 OS 用户/主机)。",
				baselineStrongModel: "对启用工具或面对不可信收件箱的 bot,使用可用的最强模型。",
				beta: "OpenClaw 是一个爱好项目,仍处于 beta 阶段。请预期会有边缘问题。",
				confirm: "我理解 OpenClaw 默认面向个人使用;共享/多用户使用需要加固。继续?",
				hardeningRequired: "如果你不熟悉安全加固和访问控制,请不要运行 OpenClaw。",
				learnMore: "了解更多",
				notMultitenant: "OpenClaw 默认不是敌对多租户安全边界。",
				personalAgent: "默认情况下,OpenClaw 是个人 agent:一个可信操作者边界。",
				promptRisk: "恶意 prompt 可能诱导它执行不安全操作。",
				recommendedBaseline: "建议基线",
				runRegularly: "定期运行",
				sharedAuthority: "如果多个用户能向同一个启用工具的 agent 发消息,他们会共享这份委托工具权限。",
				title: "安全免责声明",
				toolAccess: "如果启用了工具,这个 bot 可以读取文件并执行操作。"
			},
			skills: {
				configure: "现在配置技能?(推荐)",
				containerBrewHidden: "在 Linux 容器中会隐藏仅支持 brew 的技能安装项,因为官方镜像不包含 Homebrew。",
				containerBrewManual: "请使用预装 Homebrew 的自定义镜像,或手动安装这些依赖。",
				containerInstallsTitle: "容器技能安装",
				docsLine: "文档:https://docs.openclaw.ai/skills",
				enterEnv: "输入 {env}",
				homebrewCommand: "显示 Homebrew 安装命令?",
				homebrewInstallTitle: "Homebrew 安装",
				homebrewRecommendedTitle: "建议安装 Homebrew",
				installDeps: "安装缺失的技能依赖",
				installFailed: "安装失败:{name}{code}{detail}",
				installed: "已安装 {name}",
				installedWithWarnings: "已安装 {name}(有警告)",
				installing: "正在安装 {name}...",
				nodeManager: "技能安装首选 Node 管理器",
				setEnv: "为 {name} 设置 {env}?",
				skipDepsHint: "继续,不安装依赖",
				statusTitle: "技能状态",
				allReadyTitle: "所有技能已就绪"
			},
			channels: {
				account: "{label} 账号",
				configuredAction: "{label} 已配置。你想怎么处理?",
				configuredDeleteUnsupported: "{label} 不支持删除配置项。",
				configureDmPolicies: "现在配置 DM 访问策略?(默认:配对)",
				deleteAccount: "删除 {label} 账号 \"{account}\"?",
				deleteConfig: "删除配置",
				dmAccessTitle: "{label} DM 访问",
				dmPolicy: "{label} DM 策略",
				dmPolicyAllowlist: "允许列表 DM:{policyKey}=\"allowlist\" + {allowFromKey} 条目。",
				dmPolicyAllowlistOption: "允许列表(仅指定用户)",
				dmPolicyApprove: "批准:{command}",
				dmPolicyDefault: "默认:配对(未知 DM 会获得配对码)。",
				dmPolicyDisabledOption: "禁用(忽略 DM)",
				dmPolicyMultiUser: "多用户 DM:运行 {command} 来隔离会话(多账号频道也可用 \"per-account-channel-peer\")。",
				dmPolicyOpen: "公开 DM:{policyKey}=\"open\" + {allowFromKey} 包含 \"*\"。",
				dmPolicyOpenOption: "开放(公开接收入站 DM)",
				dmPolicyPairing: "配对(推荐)",
				docs: "文档:{link}",
				disabledBeforeSetup: "{channel} 当前为 {hint},无法配置。请先启用再设置。",
				disabledDuringSetup: "{channel} 当前为 {hint},无法配置。启用后再运行 {command}。",
				disableKeepConfig: "禁用(保留配置)",
				doneHint: "完成",
				modifySettings: "修改设置",
				noInteractiveSetup: "{channel} 还没有交互式设置界面。运行 {command} 查看支持的参数。",
				pluginEnableFailed: "无法启用 {channel}:{reason}。运行 {command} 查看插件状态。",
				pluginMissingRecoverable: "{channel} 插件不可用(继续设置)。如果设置后频道仍无法工作,请运行 `{listCommand}` 和 `{enableCommand}`,然后重启 Gateway。",
				pluginNotAvailable: "{channel} 插件不可用。",
				removeTitle: "移除频道",
				select: "选择频道",
				selectQuickstart: "选择频道(QuickStart)",
				selectedTitle: "已选择频道",
				setupConfirm: "现在设置聊天频道?",
				setupTitle: "频道设置",
				skipLeaveAsIs: "跳过(保持不变)",
				skipLaterHint: "稍后可以通过 `{command}` 添加频道",
				statusTitle: "频道状态",
				statusBundledEnable: "已内置 · 启用后可用",
				statusConfigured: "已配置",
				statusConfiguredConnectionNotVerified: "已配置(连接未验证)",
				statusConfiguredPluginDisabled: "已配置(插件已禁用)",
				statusConnectedAs: "已连接为 {name}",
				statusInstallPluginEnable: "安装插件后启用",
				statusInstalled: "已安装",
				statusInstalledPluginDisabled: "已安装(插件已禁用)",
				statusLinked: "已连接",
				statusNeedsAppCredentials: "需要 app 凭据",
				statusNeedsAppCreds: "需要 app 凭据",
				statusNeedsAuth: "需要认证",
				statusNeedsHostNick: "需要 host + nick",
				statusNeedsPrivateKey: "需要私钥",
				statusNeedsQrLogin: "需要二维码登录",
				statusNeedsServiceAccount: "需要 service account",
				statusNeedsSetup: "需要设置",
				statusNeedsToken: "需要 token",
				statusNeedsTokens: "需要 token",
				statusNeedsTokenIncomingWebhook: "需要 token + incoming webhook",
				statusNeedsTokenUrl: "需要 token + url",
				statusNeedsTokenSecret: "需要 token + secret",
				statusNeedsUsernameTokenClientId: "需要 username、token 和 clientId",
				statusNotLinked: "未连接",
				statusNotConfigured: "未配置",
				statusLoggedIn: "已登录",
				statusRecommendedConfigured: "推荐 · 已配置",
				statusRecommendedLoggedIn: "推荐 · 已登录",
				statusRecommendedNewcomerFriendly: "推荐 · 新手友好",
				statusRecommendedQrLogin: "推荐 · 二维码登录",
				statusSelfHostedChat: "自托管聊天",
				statusSignalCliFound: "已找到 signal-cli",
				statusSignalCliMissing: "缺少 signal-cli",
				statusUrbitMessenger: "urbit messenger",
				resolvedTitle: "已解析"
			},
			feishu: {
				allowFromPrompt: "Feishu allowFrom(用户 open_id)",
				allowlistFindUser: "可以在飞书管理后台或通过 API 找到用户 open_id。",
				allowlistIntro: "通过 open_id 或 user_id 为 Feishu DM 设置允许列表。",
				allowlistTitle: "Feishu 允许列表",
				appIdPrompt: "输入 Feishu App ID",
				appSecretKeep: "Feishu App Secret 已配置。保留当前值?",
				appSecretPrompt: "输入 Feishu App Secret",
				botConfigured: "Bot 已配置。",
				configuring: "正在配置...",
				credentialsEnvTip: "提示:也可以设置 FEISHU_APP_ID / FEISHU_APP_SECRET 环境变量。",
				credentialsStepCreateApp: "2) 创建自建应用",
				credentialsStepGetCredentials: "3) 在凭据页面获取 App ID 和 App Secret",
				credentialsStepOpenPlatform: "1) 打开飞书开放平台(open.feishu.cn)",
				credentialsStepPermissions: "4) 启用所需权限:im:message、im:chat、contact:user.base:readonly",
				credentialsStepPublish: "5) 发布应用,或把它加入测试群",
				credentialsTitle: "Feishu 凭据",
				domainFeishu: "Feishu (feishu.cn) - 中国",
				domainLark: "Lark (larksuite.com) - 国际版",
				domainPrompt: "选择 Feishu 域名?",
				examples: "示例:",
				existingBotPrompt: "发现已有 bot(App ID:{appId})。用于本次设置?",
				fetchingConfig: "正在获取配置结果...",
				groupPolicyAllowlist: "允许列表 - 只在指定群中响应",
				groupPolicyDisabled: "禁用 - 不响应群聊",
				groupPolicyOpen: "开放 - 在所有群中响应(需要提及)",
				groupPolicyPrompt: "群聊策略",
				scanCompleted: "扫码完成。",
				scanDenied: "用户拒绝授权。改为手动输入。",
				scanError: "注册错误:{error}。改为手动输入。",
				scanExpired: "会话已过期。改为手动输入。",
				scanQr: "请用手机上的 Lark/飞书扫描二维码。如果手机应用没有反应,请重新运行设置并选择手动输入。",
				scanTimedOut: "扫码超时。改为手动输入。",
				scanTitle: "Feishu 扫码创建",
				scanUnavailable: "当前环境不支持扫码创建。改为手动输入。",
				setupMethodManual: "手动输入 App ID 和 App Secret",
				setupMethodPrompt: "你想如何连接 Feishu?",
				setupMethodScan: "扫描二维码自动创建 bot",
				setupTitle: "Feishu 设置"
			},
			telegram: {
				allowFromInvalid: "Telegram allowFrom 需要数字发送者 ID。先给 bot 发一条 DM,然后从日志或 getUpdates 中复制 from.id。",
				allowFromPrompt: "Telegram allowFrom(数字发送者 ID)",
				allowlistTitle: "Telegram 允许列表",
				botToken: "Telegram bot token",
				tokenEnvPrompt: "检测到 TELEGRAM_BOT_TOKEN。使用环境变量?",
				tokenEnvTip: "提示:也可以在环境变量中设置 TELEGRAM_BOT_TOKEN。",
				tokenHelpCopyToken: "3) 复制 token(格式类似 123456:ABC...)",
				tokenHelpNewBot: "2) 运行 /newbot(或 /mybots)",
				tokenHelpOpenBotFather: "1) 打开 Telegram 并与 @BotFather 对话",
				tokenInputPrompt: "输入 Telegram bot token",
				tokenKeepPrompt: "Telegram token 已配置。保留当前值?",
				userIdHelpGetUpdates: "2) 或调用 https://api.telegram.org/bot<bot_token>/getUpdates 并读取 message.from.id",
				userIdHelpLogs: "1) 先给你的 bot 发送 DM,然后在 `{command}` 中读取 from.id(最安全)",
				userIdHelpThirdParty: "3) 第三方方式:给 @userinfobot 或 @getidsbot 发送 DM",
				userIdTitle: "Telegram 用户 ID",
				website: "网站:{url}"
			},
			discord: {
				allowFromInvalidWithoutToken: "缺少 bot token;只能使用数字用户 ID(或 mention 形式)。",
				allowFromPrompt: "Discord allowFrom(用户名或 ID)",
				allowlistIntro: "通过用户名为 Discord DM 设置允许列表(会解析为用户 ID)。",
				allowlistTitle: "Discord 允许列表",
				botToken: "Discord bot token",
				channelsLabel: "Discord 频道",
				examples: "示例:",
				multipleEntries: "多个条目请用逗号分隔。",
				tokenEnvPrompt: "检测到 DISCORD_BOT_TOKEN。使用环境变量?",
				tokenHelpCopyToken: "2) Bot -> Add Bot -> Reset Token -> 复制 token",
				tokenHelpCreateApplication: "1) Discord Developer Portal -> Applications -> New Application",
				tokenHelpInviteBot: "3) OAuth2 -> URL Generator -> scope 'bot' -> 邀请到你的服务器",
				tokenHelpMessageContentIntent: "提示:如需读取消息文本,请启用 Message Content Intent。(Bot -> Privileged Gateway Intents -> Message Content Intent)",
				tokenInputPrompt: "输入 Discord bot token",
				tokenKeepPrompt: "Discord token 已配置。保留当前值?"
			},
			googlechat: {
				allowFromPrompt: "Google Chat allowFrom(users/<id> 或原始邮箱;避免 users/<email>)",
				appUrl: "App URL",
				appUrlRecommended: "App URL(推荐)",
				authMethod: "Google Chat 认证方式",
				projectNumber: "Project number",
				serviceAccountFile: "Service account JSON 文件",
				serviceAccountInline: "粘贴 service account JSON",
				serviceAccountJson: "Service account JSON(单行)",
				serviceAccountPath: "Service account JSON 路径",
				setupAudience: "Webhook 验证需要 audience 类型和 audience 值。",
				setupScopes: "在 service account 中设置 Chat API scopes,并配置 Chat app URL。",
				setupServiceAccount: "Google Chat app 使用 service-account 认证和 HTTPS webhook。",
				setupTitle: "Google Chat 设置",
				useEnvPrompt: "使用 GOOGLE_CHAT_SERVICE_ACCOUNT 环境变量?",
				webhookAudienceType: "Webhook audience 类型"
			},
			line: {
				allowFromInvalid: "LINE allowFrom 需要原始用户 ID,例如 U1234567890abcdef1234567890abcdef。",
				allowFromPrompt: "LINE allowFrom(用户 ID)",
				allowlistIntro: "通过用户 ID 为 LINE DM 设置允许列表。",
				allowlistTitle: "LINE 允许列表",
				channelAccessToken: "channel access token",
				channelSecret: "channel secret",
				completionDefaultWebhook: "默认 webhook URL:https://<gateway-host>/line/webhook",
				completionEnableWebhook: "保存凭据后,在 LINE 控制台启用 Use webhook。",
				completionWebhookPath: "如果设置了 channels.line.webhookPath,请同步更新 URL。",
				examples: "示例:",
				helpCopyCredentials: "2) 复制 channel access token 和 channel secret",
				helpEnableWebhook: "3) 在 Messaging API 设置中启用 Use webhook",
				helpOpenConsole: "1) 打开 LINE Developers Console 并创建或选择 Messaging API channel",
				helpWebhookUrl: "4) 将 webhook 指向 https://<gateway-host>/line/webhook",
				idsCaseSensitive: "LINE ID 区分大小写。",
				messagingApiTitle: "LINE Messaging API",
				multipleEntries: "多个条目请用逗号分隔。",
				secretEnvPrompt: "检测到 LINE_CHANNEL_SECRET。使用环境变量?",
				secretInputPrompt: "输入 LINE channel secret",
				secretKeepPrompt: "LINE channel secret 已配置。保留当前值?",
				tokenEnvPrompt: "检测到 LINE_CHANNEL_ACCESS_TOKEN。使用环境变量?",
				tokenInputPrompt: "输入 LINE channel access token",
				tokenKeepPrompt: "LINE channel access token 已配置。保留当前值?",
				webhookTitle: "LINE webhook"
			},
			slack: {
				allowFromInvalidWithoutToken: "缺少 Slack token;只能使用用户 ID(或 mention 形式)。",
				allowFromPrompt: "Slack allowFrom(用户名或 ID)",
				allowlistIntro: "通过用户名为 Slack DM 设置允许列表(会解析为用户 ID)。",
				allowlistTitle: "Slack 允许列表",
				appToken: "Slack app token",
				appTokenInput: "输入 Slack app token(xapp-...)",
				appTokenKeep: "Slack app token 已配置。保留当前值?",
				botToken: "Slack bot token",
				botTokenInput: "输入 Slack bot token(xoxb-...)",
				botTokenKeep: "Slack bot token 已配置。保留当前值?",
				channelsLabel: "Slack 频道",
				envPrompt: "检测到 SLACK_BOT_TOKEN + SLACK_APP_TOKEN。使用环境变量?",
				examples: "示例:",
				interactiveRepliesPrompt: "为 agent 响应启用 Slack 交互回复(按钮/选择器)?",
				multipleEntries: "多个条目请用逗号分隔。",
				socketModeTokensTitle: "Slack socket mode token"
			},
			mattermost: {
				baseUrlPrompt: "输入 Mattermost 基础 URL",
				botToken: "bot token",
				botTokenInput: "输入 Mattermost bot token",
				botTokenKeep: "Mattermost bot token 已配置。保留当前值?",
				botTokenTitle: "Mattermost bot token",
				envPrompt: "检测到 MATTERMOST_BOT_TOKEN + MATTERMOST_URL。使用环境变量?",
				helpBaseUrl: "3) 使用你的服务器基础 URL(例如 https://chat.example.com)",
				helpBotMember: "提示:bot 必须加入任何你希望它监控的频道。",
				helpCreateBot: "2) 创建 bot 并复制它的 token",
				helpOpenConsole: "1) Mattermost System Console -> Integrations -> Bot Accounts"
			},
			nextcloudTalk: {
				allowFromPrompt: "Nextcloud Talk allowFrom(用户 ID)",
				apiPassword: "API 密码",
				apiPasswordInput: "输入 Nextcloud Talk API 密码",
				apiPasswordKeep: "Nextcloud Talk API 密码已配置。保留当前值?",
				apiUserPrompt: "Nextcloud Talk API 用户",
				botSecret: "bot secret",
				botSecretEnvPrompt: "检测到 NEXTCLOUD_TALK_BOT_SECRET。使用环境变量?",
				botSecretInput: "输入 Nextcloud Talk bot secret",
				botSecretKeep: "Nextcloud Talk bot secret 已配置。保留当前值?",
				configureApiCredentials: "配置可选的 Nextcloud Talk API 凭据用于房间查找?",
				helpCopySecret: "3) 复制你在命令中使用的 shared secret",
				helpEnableRoom: "4) 在 Nextcloud Talk 房间设置中启用 bot",
				helpEnvTip: "提示:也可以在环境变量中设置 NEXTCLOUD_TALK_BOT_SECRET。",
				helpInstallCommand: "2) 运行:./occ talk:bot:install \"OpenClaw\" \"<shared-secret>\" \"<webhook-url>\" --feature webhook --feature response --feature reaction",
				helpSsh: "1) SSH 进入你的 Nextcloud 服务器",
				instanceUrlPrompt: "输入 Nextcloud 实例 URL(例如 https://cloud.example.com)",
				setupTitle: "Nextcloud Talk bot 设置",
				userIdHelpAdmin: "1) 在 Nextcloud 管理后台查看用户 ID",
				userIdHelpLogs: "2) 或在有人发消息时查看 webhook payload 日志",
				userIdHelpLowercase: "3) 用户 ID 通常是 Nextcloud 中的小写用户名",
				userIdTitle: "Nextcloud Talk 用户 ID"
			},
			msteams: {
				allowFromPrompt: "MS Teams allowFrom(用户名或 ID)",
				allowlistIntro: "通过显示名称、UPN/邮箱或用户 ID 为 MS Teams DM 设置允许列表。",
				allowlistResolve: "凭据允许时,会通过 Microsoft Graph 将名称解析为用户 ID。",
				allowlistTitle: "MS Teams 允许列表",
				appIdPrompt: "输入 MS Teams App ID",
				appPasswordPrompt: "输入 MS Teams App Password",
				channelLookupFailed: "频道查找失败;保留原始输入。{error}",
				channelsLabel: "MS Teams 频道",
				couldNotResolve: "无法解析:{entries}",
				credentialsKeep: "MS Teams 凭据已配置。保留当前值?",
				credentialsTitle: "MS Teams 凭据",
				delegatedAuthConfigured: "Delegated auth 已配置",
				delegatedAuthPrompt: "启用 delegated auth?(reaction 和写操作需要)",
				delegatedAuthRetry: "之后可以通过设置向导重试。",
				delegatedAuthTitle: "MS Teams delegated auth",
				delegatedOAuthProgress: "MSTeams Delegated OAuth",
				enterAtLeastOneUser: "至少输入一个用户。",
				envPrompt: "检测到 MSTEAMS_APP_ID + MSTEAMS_APP_PASSWORD + MSTEAMS_TENANT_ID。使用环境变量?",
				examples: "示例:",
				graphLookupUnavailable: "Graph 查找不可用。请只使用用户 ID。",
				helpAzureBot: "1) Azure Bot registration -> 获取 App ID + Tenant ID",
				helpClientSecret: "2) 添加 client secret(App Password)",
				helpEnvTip: "提示:也可以设置 MSTEAMS_APP_ID / MSTEAMS_APP_PASSWORD / MSTEAMS_TENANT_ID。",
				helpWebhook: "3) 设置 webhook URL 和 messaging endpoint",
				resolvedChannels: "已解析频道:{entries}",
				resolvedTeams: "已解析团队:{entries}",
				tenantIdPrompt: "输入 MS Teams Tenant ID",
				unresolvedKept: "未解析(保留原始输入):{entries}"
			},
			whatsapp: {
				allowedSenderNumbers: "允许的发送者号码(逗号分隔,E.164)",
				allowFromPrompt: "WhatsApp allowFrom(可选预允许列表)",
				allowlistModeEnabled: "已启用允许列表模式。",
				allowlistTitle: "WhatsApp 允许列表",
				credentialsStored: "凭据会存储在 {authDir}/ 下供之后运行使用。",
				dmAccessTitle: "WhatsApp DM 访问",
				dmPolicyAllowlistOnly: "仅允许列表(阻止未知发送者)",
				dmPolicyDisabled: "禁用(忽略 WhatsApp DM)",
				dmPolicyPrompt: "WhatsApp DM 策略",
				dmPolicySetAllowlist: "- dmPolicy 已设为 allowlist(跳过配对)",
				helpTitle: "WhatsApp 帮助",
				keepCurrentAllowFrom: "保留当前 allowFrom",
				linkLater: "稍后运行 `{command}` 连接 WhatsApp。",
				linkNowPrompt: "现在连接 WhatsApp(QR)?",
				linkingTitle: "WhatsApp 连接",
				numberTitle: "WhatsApp 号码",
				ownerNumberNote: "需要发送者/所有者号码,以便 OpenClaw 将你加入允许列表。",
				personalNumberPrompt: "你的个人 WhatsApp 号码(你将用来发消息的手机)",
				personalPhoneLabel: "这是我的个人手机号码",
				personalPhoneModeEnabled: "已启用个人手机模式。",
				personalPhoneTitle: "WhatsApp 个人手机",
				phoneSetupPrompt: "WhatsApp 手机设置",
				relinkPrompt: "WhatsApp 已连接。现在重新连接?",
				scanQr: "请用手机上的 WhatsApp 扫描二维码。",
				separatePhoneLabel: "OpenClaw 专用独立手机",
				setAllowFromNumbers: "将 allowFrom 设置为指定号码",
				unsetAllowFromDefault: "取消设置 allowFrom(默认)",
				unsetAllowFromPairing: "取消设置 allowFrom(仅使用配对批准)"
			},
			nostr: {
				allowFromPrompt: "Nostr allowFrom",
				allowlistIntro: "按 npub 或十六进制公钥为 Nostr DM 设置允许列表。",
				allowlistTitle: "Nostr 允许列表",
				examples: "示例:",
				helpEnvVars: "支持环境变量:NOSTR_PRIVATE_KEY(仅默认账号)。",
				helpPrivateKeyFormat: "使用 nsec 或 64 字符十六进制格式的 Nostr 私钥。",
				helpRelaysOptional: "Relay URL 是可选的。留空会保留默认 relay 集合。",
				multipleEntries: "多个条目请用逗号分隔。",
				privateKeyEnvPrompt: "检测到 NOSTR_PRIVATE_KEY。使用环境变量?",
				privateKeyInput: "Nostr 私钥(nsec... 或 hex)",
				privateKeyKeep: "Nostr 私钥已配置。保留当前值?",
				privateKeyTitle: "Nostr 私钥",
				relaysTitle: "Nostr relays",
				relayUrlsKeep: "Relay URL 已设置({value})。保留?",
				relayUrlsPrompt: "Relay URL(逗号分隔,可选)",
				relaysWsOnly: "使用 ws:// 或 wss:// relay URL。",
				setupTitle: "Nostr 设置"
			},
			irc: {
				allowFromInvalid: "请输入 IRC nick 或 nick!user@host 条目。",
				allowFromPrompt: "IRC allowFrom(nick 或 nick!user@host)",
				allowlistIntro: "按发送者为 IRC DM 设置允许列表。",
				allowlistTitle: "IRC 允许列表",
				autoJoinPrompt: "自动加入 IRC 频道(可选,逗号分隔)",
				envPrompt: "检测到 IRC_HOST 和 IRC_NICK。使用环境变量?",
				examples: "示例:",
				helpEnvVars: "支持环境变量:IRC_HOST、IRC_PORT、IRC_TLS、IRC_NICK、IRC_USERNAME、IRC_REALNAME、IRC_PASSWORD、IRC_CHANNELS、IRC_NICKSERV_PASSWORD、IRC_NICKSERV_REGISTER_EMAIL。",
				helpGroupControl: "设置 channels.irc.groupPolicy=\"allowlist\" 和 channels.irc.groups 可收紧频道控制。",
				helpMentionGate: "IRC 频道默认需要 @mention 才回复。如需允许非 mention 回复,设置 channels.irc.groups[\"#channel\"].requireMention=false(或用 \"*\" 表示全部)。",
				helpNeedsHostNick: "IRC 需要服务器 host 和 bot nick。",
				helpNickServOptional: "可选:完成基础账号字段后可配置 NickServ identify/register。",
				helpRecommendedTls: "推荐:TLS 使用 6697 端口。",
				multipleEntries: "多个条目请用逗号分隔。",
				nextRestartGateway: "下一步:重启 gateway 并验证状态。",
				nextStatusCommand: "命令:openclaw channels status --probe",
				nextStepsTitle: "IRC 后续步骤",
				nickPrompt: "IRC nick",
				nickServConfigurePrompt: "配置 NickServ identify/register?",
				nickServPasswordEnvPrompt: "检测到 IRC_NICKSERV_PASSWORD。使用环境变量?",
				nickServPasswordPrompt: "NickServ 密码(留空则禁用 NickServ 认证)",
				nickServRegisterEmailPrompt: "NickServ 注册邮箱",
				nickServRegisterPrompt: "连接时发送 NickServ REGISTER?",
				nickServServicePrompt: "NickServ 服务 nick",
				nickServUpdatePrompt: "更新 NickServ 设置?",
				realNamePrompt: "IRC real name",
				requireMentionPrompt: "IRC 频道回复是否要求 @mention?",
				serverHostPrompt: "IRC 服务器 host",
				serverPortPrompt: "IRC 服务器端口",
				setupTitle: "IRC 设置",
				tlsPrompt: "IRC 使用 TLS?",
				usernamePrompt: "IRC username"
			},
			tlon: {
				addGroupsPrompt: "手动添加群组频道?(可选)",
				autoDiscoveryPrompt: "启用群组频道自动发现?",
				dmAllowlistPrompt: "DM 允许列表(ship 名称,逗号分隔)",
				groupChannelsPrompt: "群组频道(逗号分隔)",
				helpExampleShip: "ship 示例:~sampel-palnet",
				helpExampleUrl: "URL 示例:https://your-ship-host",
				helpNeedsUrlCode: "需要你的 Urbit ship URL 和登录码。",
				helpPrivateNetwork: "如果 ship URL 位于私有网络(LAN/localhost),设置时必须明确允许。",
				loginCodePrompt: "登录码",
				privateNetworkPrompt: "Ship URL 看起来是私有/内部 host。允许私有网络访问?(SSRF 风险)",
				restrictDmsPrompt: "使用允许列表限制 DM?",
				setupTitle: "Tlon 设置",
				shipPrompt: "Ship 名称",
				shipUrlPrompt: "Ship URL"
			},
			synologyChat: {
				accessControlTitle: "Synology Chat 访问控制",
				allowedUserIdsInvalid: "Synology Chat 用户 ID 必须是数字。",
				allowedUserIdsPrompt: "允许的 Synology Chat 用户 ID",
				allowlistIntro: "按数字用户 ID 为 Synology Chat DM 设置允许列表。",
				allowlistTitle: "Synology Chat 允许列表",
				defaultPath: "默认路径:{path}",
				examples: "示例:",
				helpAllowedUsers: "4) 准备好允许的用户 ID,用于 DM allowlist",
				helpIncomingWebhook: "1) 在 Synology Chat 创建 incoming webhook 并复制 URL",
				helpOutgoingWebhook: "2) 创建 outgoing webhook 并复制 secret token",
				helpPointWebhook: "3) 将 outgoing webhook 指向 https://<gateway-host>{path}",
				incomingWebhookHelpReplies: "这是 OpenClaw 用来向 Chat 发送回复的 URL。",
				incomingWebhookHelpUseUrl: "使用 Synology Chat 集成里的 incoming webhook URL。",
				incomingWebhookKeep: "Incoming webhook URL 已设置({value})。保留?",
				incomingWebhookTitle: "Synology Chat incoming webhook",
				incomingWebhookUrlPrompt: "Incoming webhook URL",
				multipleEntries: "多个条目请用逗号分隔。",
				outgoingWebhookPathHelp: "仅在需要多个 Synology Chat webhook 路由时修改。",
				outgoingWebhookPathKeep: "Outgoing webhook path 已设置({value})。保留?",
				outgoingWebhookPathPrompt: "Outgoing webhook path(可选)",
				outgoingWebhookPathTitle: "Synology Chat outgoing webhook path",
				setupTitle: "Synology Chat webhook 设置",
				tokenEnvPrompt: "检测到 SYNOLOGY_CHAT_TOKEN。使用环境变量?",
				tokenInput: "输入 Synology Chat outgoing webhook token",
				tokenKeep: "Synology Chat webhook token 已配置。保留当前值?",
				webhookTokenTitle: "Synology Chat webhook token"
			},
			signal: {
				accountKeep: "Signal 账号已设置({value})。保留?",
				allowFromPrompt: "Signal allowFrom(E.164 或 uuid)",
				allowlistIntro: "按发送者 ID 为 Signal DM 设置允许列表。",
				allowlistTitle: "Signal 允许列表",
				botNumberPrompt: "Signal bot 号码(E.164)",
				examples: "示例:",
				installPrompt: "未找到 signal-cli。现在安装?",
				multipleEntries: "多个条目请用逗号分隔。",
				nextLinkDevice: "绑定设备:signal-cli link -n \"OpenClaw\"",
				nextScanQr: "在 Signal -> Linked Devices 中扫描二维码",
				nextStepsTitle: "Signal 后续步骤",
				reinstallPrompt: "已检测到 signal-cli。现在重新安装/更新?"
			},
			zalo: {
				allowFromNumeric: "请使用数字 Zalo 用户 ID",
				allowFromPrompt: "Zalo allowFrom(用户 ID)",
				botToken: "bot token",
				botTokenTitle: "Zalo bot token",
				helpCreateBot: "2) 创建 bot 并获取 token",
				helpEnvTip: "提示:也可以在环境变量中设置 ZALO_BOT_TOKEN。",
				helpOpenPlatform: "1) 打开 Zalo Bot Platform:https://bot.zaloplatforms.com",
				helpTokenFormat: "3) Token 类似 12345689:abc-xyz",
				tokenEnvPrompt: "检测到 ZALO_BOT_TOKEN。使用环境变量?",
				tokenInput: "输入 Zalo bot token",
				tokenKeep: "Zalo token 已配置。保留当前值?",
				webhookModePrompt: "为 Zalo 使用 webhook 模式?",
				webhookPathPrompt: "Webhook 路径(可选)",
				webhookSecret: "webhook secret",
				webhookSecretInput: "Webhook secret(8-256 个字符)",
				webhookSecretKeep: "Zalo webhook secret 已配置。保留当前值?",
				webhookSecretLength: "Webhook secret 必须为 8 到 256 个字符。",
				webhookTitle: "Zalo webhook",
				webhookUrlPrompt: "Webhook URL(https://...)"
			},
			zalouser: {
				allowFromPlaceholder: "Alice、123456789,或留空稍后配置",
				allowFromPrompt: "Zalo Personal allowFrom(名称或用户 ID)",
				allowlistTitle: "Zalo Personal 允许列表",
				couldNotResolve: "无法解析:{entries}。请使用数字用户 ID 或精确好友名称。",
				directChatsBlocked: "在之后添加联系人前,直接聊天会保持阻止。",
				dmAccessTitle: "Zalo Personal DM 访问",
				dmHelpAllowlist: "- allowlist:只有列出的联系人可以 DM",
				dmHelpAllowlistEmpty: "如果现在选择 allowlist,可以先留空,之后再添加联系人。",
				dmHelpDisabled: "- disabled:忽略 DM",
				dmHelpOpen: "- open:任何人都可以 DM",
				dmHelpPairing: "- pairing(默认):未知联系人会获得配对码",
				dmHelpSeparate: "直接聊天和群聊会分开配置。",
				dmPolicyPrompt: "Zalo Personal DM 策略",
				groupChatsBlocked: "在之后添加群组前,群聊会保持阻止。",
				groupLookupFailed: "群组查找失败;保留原始输入。{error}",
				groupMentionRequirement: "之后允许的群组默认仍需要 mention。",
				groupsLookupTip: "提示:onboarding 后用 `{command}` 查找群组 ID。",
				groupsPlaceholder: "Family、Work、123456789,或暂时留空",
				groupsTitle: "Zalo 群组",
				helpQrLogin: "Zalo Personal 账号通过二维码登录。",
				helpZcaJs: "该插件直接使用 zca-js(无外部 CLI 依赖)。",
				keepSessionPrompt: "Zalo Personal 已登录。保留会话?",
				loginPendingTitle: "登录待完成",
				loginQrPrompt: "现在通过二维码登录?",
				noDmAllowlist: "尚未添加 DM 允许列表条目。",
				noGroupAllowlist: "尚未添加群组允许列表条目。",
				peersLookupTip: "提示:onboarding 后用 `{command}` 查找联系人。",
				qrImageSaved: "二维码图片已保存到:{path}",
				qrImageWriteFailed: "无法写入二维码图片文件;请改用 gateway web login UI。",
				qrLoginTitle: "二维码登录",
				qrScannedPrompt: "你已经在手机上扫描并批准二维码了吗?",
				scanApproveContinue: "在手机上扫描并批准,然后继续。",
				setupTitle: "Zalo Personal 设置"
			},
			twitch: {
				accessTokenKeep: "Access token 已配置。保留当前值?",
				allowFromPrompt: "Twitch allowFrom(用户 ID,每行一个,建议用于安全控制)",
				botUsernamePrompt: "Twitch bot 用户名",
				channelJoinPrompt: "要加入的频道",
				clientIdPrompt: "Twitch Client ID",
				clientSecretPrompt: "Twitch Client Secret(用于 token 刷新)",
				envPrompt: "检测到 Twitch 环境变量 OPENCLAW_TWITCH_ACCESS_TOKEN。使用环境 token?",
				helpCopyToken: "3. 复制 token(以 'oauth:' 开头)和 Client ID",
				helpCreateApp: "1. 在 https://dev.twitch.tv/console 创建 Twitch 应用",
				helpEnvVars: "支持环境变量:OPENCLAW_TWITCH_ACCESS_TOKEN",
				helpGenerateToken: "2. 生成带 chat:read 和 chat:write scopes 的 token",
				helpRequiresBot: "Twitch 需要一个带 OAuth token 的 bot 账号。",
				helpTokenTools: "   可使用 https://twitchtokengenerator.com/ 或 https://twitchapps.com/tmi/",
				oauthTokenPrompt: "Twitch OAuth token(oauth:...)",
				refreshTokenInputPrompt: "Twitch Refresh Token",
				refreshTokenPrompt: "启用自动 token 刷新?(需要 client secret 和 refresh token)",
				setupTitle: "Twitch 设置"
			},
			imessage: {
				imsgFound: "已找到 imsg",
				imsgMissing: "未找到 imsg"
			},
			channelsPrimer: {
				approveWith: "批准配对:{command}",
				docs: "文档:{link}",
				inboundSafety: "入站 DM 安全默认使用配对:未知发送者会先获得配对码。",
				multiUserDm: "多用户 DM 请隔离会话:{command}(多账号频道也可用 \"per-account-channel-peer\")。",
				openDm: "开放/公开 DM 需要 dmPolicy=\"open\",并且 allowFrom=[\"*\"]。",
				title: "频道工作方式",
				blurbs: {
					clickclack: "通过一等 ClickClack bot token 连接自托管聊天。",
					discord: "目前支持很完善。",
					feishu: "飞书/Lark 企业消息。",
					googlechat: "通过 HTTP webhook 接入 Google Workspace Chat app。",
					imessage: "通过 imsg bridge 本地接入 iMessage/SMS;启用后支持私有 API 消息动作。",
					irc: "经典 IRC 网络,支持 DM/频道路由和配对控制。",
					line: "LINE Messaging API webhook bot。",
					mattermost: "自托管 Slack 风格聊天;安装插件后启用。",
					matrix: "开放协议;安装插件后启用。",
					msteams: "Teams SDK;企业支持。",
					nextcloudTalk: "通过 Nextcloud Talk webhook bot 接入自托管聊天。",
					nostr: "去中心化协议;通过 NIP-04 发送加密 DM。",
					qqbot: "通过官方 QQ Bot API 连接 QQ。",
					signal: "signal-cli 绑定设备;需要更多设置(David Reagans:\"Hop on Discord.\")。",
					slack: "支持 Socket Mode。",
					synologyChat: "将 Synology NAS Chat 连接到 OpenClaw,并启用完整 agent 能力。",
					telegram: "最容易上手:在 @BotFather 注册 bot 后即可开始。",
					tlon: "Urbit 上的去中心化消息;安装插件后启用。",
					twitch: "Twitch 聊天集成。",
					wecom: "企业消息与文档、日程和任务工具。",
					whatsapp: "使用你自己的号码;建议准备单独手机和 eSIM。",
					yuanbao: "腾讯元宝 AI 助手会话频道。",
					zalo: "面向越南市场、支持 Bot API 的消息平台。",
					zalouser: "通过二维码登录接入 Zalo 个人账号。"
				}
			},
			search: {
				chooseProvider: "选择一个提供方。有些提供方需要 API key,有些无需 key。",
				configured: "已配置",
				configureLaterHint: "稍后可用 openclaw configure --section web 配置",
				docsLine: "文档:{url}",
				intro: "Web search 可以让 agent 在线查询资料。",
				keyFree: "无需 key",
				noProvidersAction: "请启用插件或移除 deny 规则,然后重新运行设置。",
				noProvidersByPolicy: "当前插件策略下没有可用的 web search 提供方。",
				providerPrompt: "搜索提供方",
				title: "网页搜索"
			},
			finalize: {
				addNodes: "添加节点以启用更多功能:",
				alreadyInstalled: "Gateway 服务已安装",
				backupWorkspace: "备份你的 agent 工作区。",
				browserHatch: "在浏览器中启动",
				codexNativeSearchOnly: "仅用于支持 Codex 的模型。",
				codexNativeSearchTitle: "Codex 原生搜索",
				controlUiTitle: "Control UI",
				controlUiDocs: "文档:https://docs.openclaw.ai/web/control-ui",
				dashboardCopyPaste: "在本机浏览器中复制/粘贴这个 URL 来控制 OpenClaw。",
				dashboardLinkWithToken: "Dashboard 链接(含令牌):{url}",
				dashboardOpened: "已在浏览器中打开。保留该标签页以控制 OpenClaw。",
				dashboardOpenAnytime: "随时打开 dashboard:{command}",
				dashboardReady: "Dashboard 已就绪",
				dashboardTokenMemory: "Web UI 会把 dashboard URL 中的令牌保存在当前标签页内存中,并在加载后从 URL 中移除。",
				dashboardTokenPrompt: "如果被提示:把令牌粘贴到 Control UI 设置中(或使用带令牌的 dashboard URL)。",
				dashboardWhenReady: "准备好后运行:{command}",
				daemonRuntime: "Gateway 服务运行时",
				daemonRuntimeNode: "Node(推荐)",
				daemonRuntimeNodeHint: "WhatsApp + Telegram 需要使用。Bun 重新连接时可能造成内存损坏。",
				editBootstrap: "之后可编辑 BOOTSTRAP.md 来修改 agent 的自我介绍方式。",
				bootstrapHatchMessage: "醒醒,我的朋友!",
				firstTerminalChat: "第一次终端聊天会发送:\"醒醒,我的朋友!\"",
				gatewayInstallBlocked: "Gateway 安装被阻止:",
				gatewayInstallFixAuth: "修复 Gateway 认证配置/令牌输入后重新运行设置。",
				gatewayNotDetected: "尚未检测到 Gateway。",
				gatewayNotDetectedStatus: "Gateway:未检测到{detail}",
				gatewayReachable: "Gateway:可访问",
				gatewayService: "Gateway 服务",
				gatewayServiceInstalled: "Gateway 服务已安装。",
				gatewayServiceInstalling: "正在安装 Gateway 服务...",
				gatewayServiceInstallFailed: "Gateway 服务安装失败。",
				gatewayServiceInstallFailedWithError: "Gateway 服务安装失败:{error}",
				gatewayServicePreparing: "正在准备 Gateway 服务...",
				gatewayServiceRestarted: "Gateway 服务已重启。",
				gatewayServiceRestarting: "正在重启 Gateway 服务...",
				gatewayServiceRestartScheduled: "Gateway 服务重启已排队。",
				gatewayServiceUninstalled: "Gateway 服务已卸载。",
				gatewayServiceUninstalling: "正在卸载 Gateway 服务...",
				gatewayTokenGenerate: "生成令牌:{command}",
				gatewayTokenShared: "Gateway 令牌:Gateway 和 Control UI 的共享认证。",
				gatewayTokenStored: "存储位置:$OPENCLAW_CONFIG_PATH(默认 ~/.openclaw/openclaw.json)中的 gateway.auth.token,或 OPENCLAW_GATEWAY_TOKEN。",
				gatewayTokenView: "查看令牌:{command}",
				gatewayWsUrl: "Gateway WS:{url}",
				hatchLater: "稍后启动",
				hatchPrompt: "你想如何启动 agent?",
				hatchYourAgent: "启动你的 agent",
				healthCheckHelp: "健康检查帮助",
				installGateway: "安装 Gateway 服务(推荐)",
				laterTitle: "稍后",
				managedWebSearchSkipped: "已跳过托管 web search provider。",
				noBackgroundGatewayExpected: "本次设置未安装 Gateway 服务,因此不会有后台 Gateway。",
				nodeAndroid: "Android app(camera/canvas)",
				nodeIos: "iOS app(camera/canvas)",
				nodeMac: "macOS app(system + notifications)",
				optionalApps: "可选应用",
				outroDashboardLink: "Onboarding 完成。使用上面的 dashboard 链接控制 OpenClaw。",
				outroDashboardOpened: "Onboarding 完成。Dashboard 已打开;保留该标签页以控制 OpenClaw。",
				outroSeeded: "Onboarding 完成。Web UI 已在后台初始化,可随时用上面的 dashboard 链接打开。",
				quickstartNodeRuntime: "QuickStart 使用 Node 运行 Gateway 服务(稳定且受支持)。",
				reinstall: "重新安装",
				rerunInstallDaemon: "或重新运行:{command}",
				restart: "重启",
				securityReminder: "在你的电脑上运行 agent 存在风险,请加固设置:https://docs.openclaw.ai/security",
				secretRefAuthFailed: "无法解析用于设置认证的 {field} SecretRef。",
				skipHealthNextTime: "下次也可跳过此探测:{command}",
				skipControlUi: "跳过 Control UI/TUI 提示。",
				startGatewayNow: "现在启动:{command}",
				systemdInstallSkipped: "systemd 用户服务不可用;跳过服务安装。请使用你的容器 supervisor 或 `docker compose up -d`。",
				systemdLingerReason: "Linux 安装默认使用 systemd 用户服务。没有 lingering 时,systemd 会在用户会话退出/空闲后停止会话并终止 Gateway。",
				systemdUnavailable: "systemd 用户服务不可用。跳过 lingering 检查和服务安装。",
				terminalHatch: "在终端中启动(推荐)",
				webDocs: "文档:https://docs.openclaw.ai/tools/web",
				webSearchAutoDetected: "Web search 可通过 {provider} 使用(自动检测)。",
				webSearchDisabled: "Web search({provider})已配置但被禁用。",
				webSearchEnabled: "Web search 已启用,agent 可在需要时在线查询。",
				webSearchGetKey: "获取 key:{url}",
				webSearchAuthProfile: "凭据:使用已有 {provider} auth profile。",
				webSearchKeyEnv: "API key:通过 {env} 环境变量提供。",
				webSearchKeyRef: "API key:通过 secret reference 配置。",
				webSearchKeyStored: "API key:已存入配置。",
				webSearchNeedsKey: "添加 key 前 web_search 无法工作。",
				webSearchNoKey: "已选择 provider {provider},但没有找到 API key。",
				webSearchOAuthProfile: "凭据:使用已有 {provider} OAuth 登录。",
				webSearchProvider: "Provider:{provider}",
				webSearchProviderUnavailable: "已选择 Web search provider {provider},但当前插件策略下不可用。",
				webSearchReenable: "重新启用:{command}",
				webSearchSkipped: "已跳过 web search。之后可启用:",
				webSearchTitle: "Web search",
				webSearchUnavailableAction: "重新启用该 provider 或选择其他 provider 前,web_search 无法工作。",
				webUiUrl: "Web UI:{url}",
				webUiWithTokenUrl: "Web UI(含令牌):{url}",
				whatNow: "下一步:https://openclaw.ai/showcase(\"What People Are Building\")。",
				whatNowTitle: "下一步",
				workspaceBackupTitle: "工作区备份",
				workspaceDocs: "文档:https://docs.openclaw.ai/concepts/agent-workspace",
				workspaceReady: "你的工作区已就绪。"
			},
			gatewayNotes: {
				bindTitle: "Gateway 绑定",
				tailscaleBindLoopback: "Tailscale 暴露要求 bind=loopback。将把绑定地址切换为 loopback。",
				tailscaleFunnelPassword: "Tailscale Funnel 要求使用密码认证。将把 Gateway 认证切换为密码。"
			}
		}
	},
	"zh-TW": {
		common: {
			back: "返回",
			done: "完成",
			docs: "文件:",
			finished: "完成",
			noAuth: "不啟用認證",
			password: "密碼",
			required: "必填",
			minute: "{count} 分鐘",
			minutes: "{count} 分鐘",
			second: "{count} 秒",
			seconds: "{count} 秒",
			skip: "略過",
			skipForNow: "暫時略過",
			tokenRecommended: "權杖(建議)"
		},
		wizard: {
			customProvider: {
				apiBaseUrl: "API 基礎 URL",
				apiKeyPrompt: "API Key(不需要可留空)",
				changeBaseUrl: "修改基礎 URL",
				changeBaseUrlAndModel: "修改基礎 URL 和模型",
				changeModel: "修改模型",
				compatibility: "端點相容性",
				compatibilityAnthropic: "相容 Anthropic",
				compatibilityAnthropicHint: "使用 /messages",
				compatibilityOpenAi: "相容 OpenAI",
				compatibilityOpenAiHint: "使用 /chat/completions",
				compatibilityOpenAiResponses: "相容 OpenAI Responses",
				compatibilityOpenAiResponsesHint: "使用 /responses",
				compatibilityUnknown: "未知(自動偵測)",
				compatibilityUnknownHint: "先探測 OpenAI Chat、OpenAI Responses,再探測 Anthropic 端點",
				detectionFailed: "無法偵測端點類型。",
				detectionFailedNote: "這個端點沒有回應 OpenAI Chat、OpenAI Responses 或 Anthropic 風格的請求。",
				detectionNoteTitle: "端點偵測",
				detectionProgress: "正在偵測端點類型...",
				detectedAnthropic: "偵測到相容 Anthropic 的端點。",
				detectedOpenAi: "偵測到相容 OpenAI 的端點。",
				detectedOpenAiResponses: "偵測到相容 OpenAI Responses 的端點。",
				endpointId: "端點 ID",
				endpointIdRequired: "端點 ID 必填。",
				endpointIdRenamed: "端點 ID \"{from}\" 已用於不同的基礎 URL。將使用 \"{to}\"。",
				endpointIdTitle: "端點 ID",
				imageInput: "這個模型支援圖片輸入嗎?",
				modelAlias: "模型別名(選填)",
				modelAliasPlaceholder: "例如 local、ollama",
				modelId: "模型 ID",
				modelIdPlaceholder: "例如 llama3、claude-3-7-sonnet",
				modelIdRequired: "模型 ID 必填",
				retryChoice: "你想修改哪一項?",
				verifying: "正在驗證...",
				verificationFailedError: "驗證失敗:{error}",
				verificationFailedStatus: "驗證失敗:狀態碼 {status}",
				verificationSuccessful: "驗證成功。",
				validUrl: "請輸入有效 URL(例如 http://...)"
			},
			gateway: {
				accessProtection: "Gateway 存取保護",
				auth: "Gateway 認證",
				authPasswordStoredMessage: "這個 Gateway 密碼存在哪裡?",
				authPasswordMode: "你想如何提供 Gateway 密碼?",
				authTokenMode: "你想如何提供 Gateway 權杖?",
				authTokenStoredMessage: "這個 Gateway 權杖存在哪裡?",
				bindAddress: "Gateway 綁定位址",
				bindAuto: "自動(Loopback -> LAN)",
				bindAutoHint: "先嘗試 loopback",
				bindCustom: "自訂 IP",
				bindCustomHint: "綁定到一個本機位址",
				bindCustomIp: "自訂 IP 位址",
				bindLan: "LAN (0.0.0.0)",
				bindLanHint: "區域網路可存取",
				bindLoopback: "Loopback (127.0.0.1)",
				bindLoopbackHint: "僅本機可存取",
				bindTailnet: "Tailnet(Tailscale IP)",
				bindTailnetHint: "透過 Tailscale 存取",
				existingPasswordConfirm: "使用既有 Gateway 密碼({password})?",
				existingTokenConfirm: "使用既有 Gateway 權杖({token})?",
				passwordPrompt: "Gateway 密碼",
				plaintextPasswordHint: "直接把密碼存入 OpenClaw 設定",
				plaintextPasswordLabel: "現在輸入密碼",
				plaintextTokenHint: "預設",
				plaintextTokenLabel: "產生/儲存明文權杖",
				port: "Gateway 連接埠",
				refHint: "儲存參照而不是明文",
				refLabel: "使用 SecretRef",
				remotePasswordMode: "你想如何提供這個 Gateway 密碼?",
				remoteTokenMode: "你想如何提供這個 Gateway 權杖?",
				tailscaleExposure: "Tailscale 暴露方式",
				tailscaleReset: "離開時重置 Tailscale serve/funnel?",
				tokenPlaceholder: "多機器或非 loopback 存取需要使用",
				tokenPrompt: "Gateway 權杖",
				tokenPromptGenerate: "Gateway 權杖(留空則產生)",
				websocketUrl: "Gateway WebSocket URL"
			},
			gatewayTailscale: {
				docsNote: "文件:\nhttps://docs.openclaw.ai/gateway/tailscale\nhttps://docs.openclaw.ai/web",
				funnel: "Funnel",
				funnelHint: "透過 Tailscale Funnel 暴露公開 HTTPS",
				missingBinNote: "沒有在 PATH 或 /Applications 中找到 Tailscale。\n請從以下位址安裝 Tailscale:\n  https://tailscale.com/download/mac\n\n可以繼續設定,但 serve/funnel 執行時會失敗。",
				off: "關閉",
				offHint: "不透過 Tailscale 暴露",
				serve: "Serve",
				serveHint: "面向你的 tailnet 裝置提供私有 HTTPS",
				warningTitle: "Tailscale 警告"
			},
			hooks: {
				configuredTitle: "Hooks 已設定",
				enable: "啟用 hooks?",
				introTitle: "Hooks",
				noHooksMessage: "沒有找到可用 hook。你可以稍後在設定中設定 hooks。",
				noHooksTitle: "沒有可用 Hooks"
			},
			completion: {
				cacheFailed: "產生 completion 快取失敗。稍後執行 `{command}`。",
				enable: "為 {cli} 啟用 {shell} shell completion?",
				installed: "Shell completion 已安裝。{reloadHint}",
				reloadPowerShell: "重新啟動 shell 或執行:{command}",
				reloadShell: "重新啟動 shell 或執行:source {profile}",
				title: "Shell completion"
			},
			migration: {
				apply: "現在套用這次遷移?",
				appliedTitle: "遷移已套用",
				cancelled: "遷移已取消",
				complete: "遷移完成。下一步執行 `openclaw doctor`。",
				previewTitle: "遷移預覽",
				source: "遷移來源",
				sourceAgentHome: "來源 agent home",
				sourcePathHint: "下一步輸入來源路徑",
				targetWorkspace: "目標工作區目錄"
			},
			plugins: {
				configureBackHint: "返回分區選單",
				configureEmpty: "沒有找到帶可設定欄位的插件。",
				configureEmptyTitle: "插件",
				configureFieldsTitle: "插件設定",
				configurePlugin: "設定 {plugin}",
				configureSelect: "選擇要設定的插件",
				configureSelectOnboard: "設定插件(選擇現在設定,或略過)",
				configuredCount: "已設定 {configured}/{total}",
				currentValue: "保留目前值({value})",
				downloadFromClawHub: "從 ClawHub 下載({spec})",
				downloadFromNpm: "從 npm 下載({spec})",
				enableFailed: "無法啟用 {plugin}:{reason}。",
				fieldsCount: "{count} 個欄位",
				installFailed: "安裝 {spec} 失敗:{error}",
				installFailedShort: "安裝失敗:{plugin}",
				installPluginPrompt: "安裝 {plugin} 插件?",
				installTimedOut: "安裝 {spec} 逾時,已等待 {duration}。",
				installTimedOutShort: "安裝逾時:{plugin}",
				installedPlugin: "已安裝 {plugin} 插件",
				installingPlugin: "正在安裝 {plugin} 插件...",
				installTitle: "插件安裝",
				noRemoteInstallSource: "{plugin} 沒有可用的遠端安裝來源。返回選擇。",
				officialInstall: "安裝可選插件",
				officialSkipHint: "繼續,不安裝可選插件",
				preparingInstall: "正在準備",
				returningToSelection: "返回選擇。",
				arrayPromptSuffix: "(逗號分隔,留空則清除)",
				arrayPlaceholder: "value1, value2",
				sensitiveField: "\"{label}\" 是敏感欄位。請透過以下方式設定:\n  openclaw config set plugins.entries.{plugin}.config.{field} <value>\n或使用 Web UI 設定頁。",
				sensitiveTitle: "敏感欄位",
				skipConfigHint: "繼續,不設定插件",
				useLocalPluginPath: "使用本機插件路徑",
				useLocalPluginPathInstead: "改用本機插件路徑?({path})",
				useNpmPackageInstead: "改用 npm 套件?({spec})"
			},
			model: {
				allProviders: "所有 provider",
				browseAll: "瀏覽所有模型",
				configuredTitle: "模型已設定",
				current: "目前值",
				currentNotInCatalog: "目前值(不在目錄中)",
				allowed: "已允許",
				allowedNotInCatalog: "已允許(不在目錄中)",
				allowlistPicker: "/model 選擇器中的模型(多選)",
				allowlistText: "允許的模型(逗號分隔 provider/model;留空則保留目前值)",
				clearAllowlist: "清空模型允許清單?(將顯示所有模型)",
				configured: "已設定",
				configuredNotInCatalog: "已設定(不在目錄中)",
				defaultModel: "預設模型",
				defaultModelBlankToKeep: "預設模型(留空則保留)",
				defaultSet: "預設模型已設定為 {model}",
				defaultSetForAgent: "agent \"{agent}\" 的預設模型已設定為 {model}。",
				enterManually: "手動輸入模型",
				filterByProvider: "按 provider 篩選模型",
				keepCurrent: "保留目前值({value})",
				keepCurrentDefault: "保留目前值(預設:{value})",
				keptExistingDefault: "已保留目前預設模型 {current};{selected} 可用。",
				loadsProviderCatalogs: "載入 provider 模型目錄",
				loadingModels: "正在載入可用模型",
				modelCount: "{count} 個模型",
				providerSetupUnavailable: "Provider 設定需要 agent 和執行環境上下文。",
				providerSetupUnavailableTitle: "Provider 設定不可用",
				removeProviderModels: "從 /model 選擇器中移除這些 provider 模型?",
				resolvesTo: "解析為 {value}"
			},
			remote: {
				auth: "Gateway 認證",
				bonjour: "在區域網路發現 Gateway(Bonjour)?",
				connectionMethod: "連線方式",
				directAccessTitle: "直接遠端存取",
				enterUrlManually: "手動輸入 URL",
				foundGateways: "找到 {count} 個 Gateway",
				fingerprintMissing: "未公布(連線不會固定指紋)",
				gatewayPasswordStoredMessage: "這個 Gateway 密碼存在哪裡?",
				gatewayTokenStoredMessage: "這個 Gateway 權杖存在哪裡?",
				insecureRemoteUrl: "遠端主機請使用 wss://,或透過 SSH 通道使用 ws://127.0.0.1/localhost。緊急繞過:可信私有網路可設定 OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1。",
				directDefaultsTls: "直接遠端存取預設使用 TLS。",
				loopbackSshHint: "如果 Gateway 僅監聽 loopback,請選擇 SSH 通道並保持 ws://127.0.0.1:18789。",
				noGatewaysFound: "沒有找到 Gateway",
				passwordPrompt: "Gateway 密碼",
				plaintextPasswordHint: "直接把密碼存入 OpenClaw 設定",
				plaintextPasswordLabel: "現在輸入密碼",
				plaintextTokenHint: "直接把權杖存入 OpenClaw 設定",
				plaintextTokenLabel: "現在輸入權杖",
				searchProgress: "正在搜尋 Gateway...",
				selectGateway: "選擇 Gateway",
				sshTunnel: "SSH 通道(loopback)",
				sshTunnelTitle: "SSH 通道",
				tokenPrompt: "Gateway 權杖",
				trustGateway: "信任這個 Gateway?主機:{host} TLS 指紋:{fingerprint}",
				validWebSocketUrl: "URL 必須以 ws:// 或 wss:// 開頭",
				websocketUrl: "Gateway WebSocket URL"
			},
			setup: {
				authChoiceRequired: "必須選擇認證方式",
				channelsTitle: "頻道",
				configHandling: "設定處理",
				existingConfigTitle: "偵測到既有設定",
				flowAdvanced: "手動設定",
				flowAdvancedHint: "選擇 Gateway 連接埠、網路暴露、Tailscale 和認證方式。",
				flowQuickstart: "QuickStart(建議)",
				flowQuickstartHint: "建議的本機設定。之後可用 {command} 修改細節。",
				intro: "OpenClaw 設定",
				invalidConfigTitle: "設定無效",
				keepCurrent: "保留目前值",
				localGateway: "本機 Gateway",
				localGatewayMissing: "未偵測到 Gateway({url})",
				localGatewayReachable: "Gateway 可存取({url})",
				modifyCurrent: "檢視並更新",
				pluginCompatibilityTitle: "插件相容性",
				quickstartOnlyLocal: "QuickStart 僅支援本機 Gateway。將切換到手動模式。",
				quickstartTitle: "QuickStart",
				quickstartAuthTokenDefault: "權杖(預設)",
				quickstartDirectChannels: "直接進入聊天頻道設定。",
				quickstartGatewayAuth: "Gateway 認證:{auth}",
				quickstartGatewayBind: "Gateway 綁定:{bind}",
				quickstartGatewayCustomIp: "Gateway 自訂 IP:{host}",
				quickstartGatewayPort: "Gateway 連接埠:{port}",
				quickstartKeepSettings: "保留目前 Gateway 設定:",
				quickstartTailscaleExposure: "Tailscale 暴露方式:{exposure}",
				remoteConfigured: "遠端 Gateway 已設定。",
				remoteGateway: "遠端 Gateway(僅資訊)",
				remoteGatewayMissing: "尚未設定遠端 URL",
				remoteGatewayReachable: "Gateway 可存取({url})",
				remoteGatewayUnreachable: "已設定但無法存取({url})",
				resetBefore: "設定前重置",
				resetConfig: "僅設定",
				resetConfigCredsSessions: "設定 + 憑證 + 工作階段",
				resetFull: "完全重置(設定 + 憑證 + 工作階段 + 工作區)",
				resetScope: "重置範圍",
				riskNotAccepted: "未確認風險",
				searchTitle: "搜尋",
				setupMode: "設定模式",
				secretRefProbeFailed: "無法解析用於設定探測的 {field} SecretRef。",
				skillsTitle: "技能",
				skipChannels: "略過頻道設定。",
				skipSearch: "略過搜尋設定。",
				skipSkills: "略過技能設定。",
				whatSetup: "你想設定什麼?",
				workspaceDirectory: "工作區目錄"
			},
			security: {
				askForHelp: "啟用工具或暴露到網際網路之前,請找有經驗的人協助。",
				baselineDmSessions: "共享收件箱:隔離 DM 工作階段(session.dmScope: per-channel-peer),並盡量減少工具存取權限。",
				baselinePairing: "配對/允許清單 + @ 提及門控。",
				baselineSandbox: "沙箱 + 最小權限工具。",
				baselineSecrets: "不要把密鑰放在 agent 可存取的檔案系統中。",
				baselineSharedInbox: "多使用者/共享收件箱:拆分信任邊界(分離 gateway/憑證,最好使用獨立 OS 使用者/主機)。",
				baselineStrongModel: "對啟用工具或面對不可信收件箱的 bot,使用可用的最強模型。",
				beta: "OpenClaw 是一個興趣專案,仍處於 beta 階段。請預期會有邊緣問題。",
				confirm: "我理解 OpenClaw 預設面向個人使用;共享/多使用者使用需要加固。繼續?",
				hardeningRequired: "如果你不熟悉安全加固和存取控制,請不要執行 OpenClaw。",
				learnMore: "了解更多",
				notMultitenant: "OpenClaw 預設不是敵對多租戶安全邊界。",
				personalAgent: "預設情況下,OpenClaw 是個人 agent:一個可信操作者邊界。",
				promptRisk: "惡意 prompt 可能誘導它執行不安全操作。",
				recommendedBaseline: "建議基線",
				runRegularly: "定期執行",
				sharedAuthority: "如果多個使用者能向同一個啟用工具的 agent 傳訊息,他們會共享這份委託工具權限。",
				title: "安全免責聲明",
				toolAccess: "如果啟用了工具,這個 bot 可以讀取檔案並執行操作。"
			},
			skills: {
				configure: "現在設定技能?(建議)",
				containerBrewHidden: "在 Linux 容器中會隱藏僅支援 brew 的技能安裝項,因為官方映像檔不包含 Homebrew。",
				containerBrewManual: "請使用預先安裝 Homebrew 的自訂映像檔,或手動安裝這些依賴。",
				containerInstallsTitle: "容器技能安裝",
				docsLine: "文件:https://docs.openclaw.ai/skills",
				enterEnv: "輸入 {env}",
				homebrewCommand: "顯示 Homebrew 安裝命令?",
				homebrewInstallTitle: "Homebrew 安裝",
				homebrewRecommendedTitle: "建議安裝 Homebrew",
				installDeps: "安裝缺少的技能依賴",
				installFailed: "安裝失敗:{name}{code}{detail}",
				installed: "已安裝 {name}",
				installedWithWarnings: "已安裝 {name}(有警告)",
				installing: "正在安裝 {name}...",
				nodeManager: "技能安裝首選 Node 管理器",
				setEnv: "為 {name} 設定 {env}?",
				skipDepsHint: "繼續,不安裝依賴",
				statusTitle: "技能狀態",
				allReadyTitle: "所有技能已就緒"
			},
			channels: {
				account: "{label} 帳號",
				configuredAction: "{label} 已設定。你想怎麼處理?",
				configuredDeleteUnsupported: "{label} 不支援刪除設定項。",
				configureDmPolicies: "現在設定 DM 存取策略?(預設:配對)",
				deleteAccount: "刪除 {label} 帳號 \"{account}\"?",
				deleteConfig: "刪除設定",
				dmAccessTitle: "{label} DM 存取",
				dmPolicy: "{label} DM 策略",
				dmPolicyAllowlist: "允許清單 DM:{policyKey}=\"allowlist\" + {allowFromKey} 項目。",
				dmPolicyAllowlistOption: "允許清單(僅指定使用者)",
				dmPolicyApprove: "核准:{command}",
				dmPolicyDefault: "預設:配對(未知 DM 會取得配對碼)。",
				dmPolicyDisabledOption: "停用(忽略 DM)",
				dmPolicyMultiUser: "多使用者 DM:執行 {command} 來隔離工作階段(多帳號頻道也可用 \"per-account-channel-peer\")。",
				dmPolicyOpen: "公開 DM:{policyKey}=\"open\" + {allowFromKey} 包含 \"*\"。",
				dmPolicyOpenOption: "開放(公開接收入站 DM)",
				dmPolicyPairing: "配對(建議)",
				docs: "文件:{link}",
				disabledBeforeSetup: "{channel} 目前為 {hint},無法設定。請先啟用再設定。",
				disabledDuringSetup: "{channel} 目前為 {hint},無法設定。啟用後再執行 {command}。",
				disableKeepConfig: "停用(保留設定)",
				doneHint: "完成",
				modifySettings: "修改設定",
				noInteractiveSetup: "{channel} 還沒有互動式設定畫面。執行 {command} 查看支援的參數。",
				pluginEnableFailed: "無法啟用 {channel}:{reason}。執行 {command} 查看插件狀態。",
				pluginMissingRecoverable: "{channel} 插件不可用(繼續設定)。如果設定後頻道仍無法運作,請執行 `{listCommand}` 和 `{enableCommand}`,然後重新啟動 Gateway。",
				pluginNotAvailable: "{channel} 插件不可用。",
				removeTitle: "移除頻道",
				select: "選擇頻道",
				selectQuickstart: "選擇頻道(QuickStart)",
				selectedTitle: "已選擇頻道",
				setupConfirm: "現在設定聊天頻道?",
				setupTitle: "頻道設定",
				skipLeaveAsIs: "略過(保持不變)",
				skipLaterHint: "稍後可以透過 `{command}` 新增頻道",
				statusTitle: "頻道狀態",
				statusBundledEnable: "已內建 · 啟用後可用",
				statusConfigured: "已設定",
				statusConfiguredConnectionNotVerified: "已設定(連線未驗證)",
				statusConfiguredPluginDisabled: "已設定(插件已停用)",
				statusConnectedAs: "已連線為 {name}",
				statusInstallPluginEnable: "安裝插件後啟用",
				statusInstalled: "已安裝",
				statusInstalledPluginDisabled: "已安裝(插件已停用)",
				statusLinked: "已連接",
				statusNeedsAppCredentials: "需要 app 憑證",
				statusNeedsAppCreds: "需要 app 憑證",
				statusNeedsAuth: "需要認證",
				statusNeedsHostNick: "需要 host + nick",
				statusNeedsPrivateKey: "需要私鑰",
				statusNeedsQrLogin: "需要 QR code 登入",
				statusNeedsServiceAccount: "需要 service account",
				statusNeedsSetup: "需要設定",
				statusNeedsToken: "需要 token",
				statusNeedsTokens: "需要 token",
				statusNeedsTokenIncomingWebhook: "需要 token + incoming webhook",
				statusNeedsTokenUrl: "需要 token + url",
				statusNeedsTokenSecret: "需要 token + secret",
				statusNeedsUsernameTokenClientId: "需要 username、token 和 clientId",
				statusNotLinked: "未連接",
				statusNotConfigured: "未設定",
				statusLoggedIn: "已登入",
				statusRecommendedConfigured: "建議 · 已設定",
				statusRecommendedLoggedIn: "建議 · 已登入",
				statusRecommendedNewcomerFriendly: "建議 · 新手友善",
				statusRecommendedQrLogin: "建議 · QR code 登入",
				statusSelfHostedChat: "自託管聊天",
				statusSignalCliFound: "已找到 signal-cli",
				statusSignalCliMissing: "缺少 signal-cli",
				statusUrbitMessenger: "urbit messenger",
				resolvedTitle: "已解析"
			},
			feishu: {
				allowFromPrompt: "Feishu allowFrom(使用者 open_id)",
				allowlistFindUser: "可以在飛書管理後台或透過 API 找到使用者 open_id。",
				allowlistIntro: "透過 open_id 或 user_id 為 Feishu DM 設定允許清單。",
				allowlistTitle: "Feishu 允許清單",
				appIdPrompt: "輸入 Feishu App ID",
				appSecretKeep: "Feishu App Secret 已設定。保留目前值?",
				appSecretPrompt: "輸入 Feishu App Secret",
				botConfigured: "Bot 已設定。",
				configuring: "正在設定...",
				credentialsEnvTip: "提示:也可以設定 FEISHU_APP_ID / FEISHU_APP_SECRET 環境變數。",
				credentialsStepCreateApp: "2) 建立自建應用",
				credentialsStepGetCredentials: "3) 在憑證頁面取得 App ID 和 App Secret",
				credentialsStepOpenPlatform: "1) 打開飛書開放平台(open.feishu.cn)",
				credentialsStepPermissions: "4) 啟用所需權限:im:message、im:chat、contact:user.base:readonly",
				credentialsStepPublish: "5) 發布應用,或把它加入測試群",
				credentialsTitle: "Feishu 憑證",
				domainFeishu: "Feishu (feishu.cn) - 中國",
				domainLark: "Lark (larksuite.com) - 國際版",
				domainPrompt: "選擇 Feishu 網域?",
				examples: "範例:",
				existingBotPrompt: "發現既有 bot(App ID:{appId})。用於本次設定?",
				fetchingConfig: "正在取得設定結果...",
				groupPolicyAllowlist: "允許清單 - 只在指定群中回應",
				groupPolicyDisabled: "停用 - 不回應群聊",
				groupPolicyOpen: "開放 - 在所有群中回應(需要提及)",
				groupPolicyPrompt: "群聊策略",
				scanCompleted: "掃碼完成。",
				scanDenied: "使用者拒絕授權。改為手動輸入。",
				scanError: "註冊錯誤:{error}。改為手動輸入。",
				scanExpired: "工作階段已過期。改為手動輸入。",
				scanQr: "請用手機上的 Lark/飛書掃描 QR code。如果手機應用程式沒有反應,請重新執行設定並選擇手動輸入。",
				scanTimedOut: "掃碼逾時。改為手動輸入。",
				scanTitle: "Feishu 掃碼建立",
				scanUnavailable: "目前環境不支援掃碼建立。改為手動輸入。",
				setupMethodManual: "手動輸入 App ID 和 App Secret",
				setupMethodPrompt: "你想如何連接 Feishu?",
				setupMethodScan: "掃描 QR code 自動建立 bot",
				setupTitle: "Feishu 設定"
			},
			telegram: {
				allowFromInvalid: "Telegram allowFrom 需要數字傳送者 ID。先給 bot 發一則 DM,然後從日誌或 getUpdates 中複製 from.id。",
				allowFromPrompt: "Telegram allowFrom(數字傳送者 ID)",
				allowlistTitle: "Telegram 允許清單",
				botToken: "Telegram bot token",
				tokenEnvPrompt: "偵測到 TELEGRAM_BOT_TOKEN。使用環境變數?",
				tokenEnvTip: "提示:也可以在環境變數中設定 TELEGRAM_BOT_TOKEN。",
				tokenHelpCopyToken: "3) 複製 token(格式類似 123456:ABC...)",
				tokenHelpNewBot: "2) 執行 /newbot(或 /mybots)",
				tokenHelpOpenBotFather: "1) 打開 Telegram 並與 @BotFather 對話",
				tokenInputPrompt: "輸入 Telegram bot token",
				tokenKeepPrompt: "Telegram token 已設定。保留目前值?",
				userIdHelpGetUpdates: "2) 或呼叫 https://api.telegram.org/bot<bot_token>/getUpdates 並讀取 message.from.id",
				userIdHelpLogs: "1) 先給你的 bot 傳送 DM,然後在 `{command}` 中讀取 from.id(最安全)",
				userIdHelpThirdParty: "3) 第三方方式:給 @userinfobot 或 @getidsbot 傳送 DM",
				userIdTitle: "Telegram 使用者 ID",
				website: "網站:{url}"
			},
			discord: {
				allowFromInvalidWithoutToken: "缺少 bot token;只能使用數字使用者 ID(或 mention 形式)。",
				allowFromPrompt: "Discord allowFrom(使用者名稱或 ID)",
				allowlistIntro: "透過使用者名稱為 Discord DM 設定允許清單(會解析為使用者 ID)。",
				allowlistTitle: "Discord 允許清單",
				botToken: "Discord bot token",
				channelsLabel: "Discord 頻道",
				examples: "範例:",
				multipleEntries: "多個項目請用逗號分隔。",
				tokenEnvPrompt: "偵測到 DISCORD_BOT_TOKEN。使用環境變數?",
				tokenHelpCopyToken: "2) Bot -> Add Bot -> Reset Token -> 複製 token",
				tokenHelpCreateApplication: "1) Discord Developer Portal -> Applications -> New Application",
				tokenHelpInviteBot: "3) OAuth2 -> URL Generator -> scope 'bot' -> 邀請到你的伺服器",
				tokenHelpMessageContentIntent: "提示:如需讀取訊息文字,請啟用 Message Content Intent。(Bot -> Privileged Gateway Intents -> Message Content Intent)",
				tokenInputPrompt: "輸入 Discord bot token",
				tokenKeepPrompt: "Discord token 已設定。保留目前值?"
			},
			googlechat: {
				allowFromPrompt: "Google Chat allowFrom(users/<id> 或原始信箱;避免 users/<email>)",
				appUrl: "App URL",
				appUrlRecommended: "App URL(建議)",
				authMethod: "Google Chat 認證方式",
				projectNumber: "Project number",
				serviceAccountFile: "Service account JSON 檔案",
				serviceAccountInline: "貼上 service account JSON",
				serviceAccountJson: "Service account JSON(單行)",
				serviceAccountPath: "Service account JSON 路徑",
				setupAudience: "Webhook 驗證需要 audience 類型和 audience 值。",
				setupScopes: "在 service account 中設定 Chat API scopes,並設定 Chat app URL。",
				setupServiceAccount: "Google Chat app 使用 service-account 認證和 HTTPS webhook。",
				setupTitle: "Google Chat 設定",
				useEnvPrompt: "使用 GOOGLE_CHAT_SERVICE_ACCOUNT 環境變數?",
				webhookAudienceType: "Webhook audience 類型"
			},
			line: {
				allowFromInvalid: "LINE allowFrom 需要原始使用者 ID,例如 U1234567890abcdef1234567890abcdef。",
				allowFromPrompt: "LINE allowFrom(使用者 ID)",
				allowlistIntro: "透過使用者 ID 為 LINE DM 設定允許清單。",
				allowlistTitle: "LINE 允許清單",
				channelAccessToken: "channel access token",
				channelSecret: "channel secret",
				completionDefaultWebhook: "預設 webhook URL:https://<gateway-host>/line/webhook",
				completionEnableWebhook: "儲存憑證後,在 LINE 控制台啟用 Use webhook。",
				completionWebhookPath: "如果設定了 channels.line.webhookPath,請同步更新 URL。",
				examples: "範例:",
				helpCopyCredentials: "2) 複製 channel access token 和 channel secret",
				helpEnableWebhook: "3) 在 Messaging API 設定中啟用 Use webhook",
				helpOpenConsole: "1) 打開 LINE Developers Console 並建立或選擇 Messaging API channel",
				helpWebhookUrl: "4) 將 webhook 指向 https://<gateway-host>/line/webhook",
				idsCaseSensitive: "LINE ID 區分大小寫。",
				messagingApiTitle: "LINE Messaging API",
				multipleEntries: "多個項目請用逗號分隔。",
				secretEnvPrompt: "偵測到 LINE_CHANNEL_SECRET。使用環境變數?",
				secretInputPrompt: "輸入 LINE channel secret",
				secretKeepPrompt: "LINE channel secret 已設定。保留目前值?",
				tokenEnvPrompt: "偵測到 LINE_CHANNEL_ACCESS_TOKEN。使用環境變數?",
				tokenInputPrompt: "輸入 LINE channel access token",
				tokenKeepPrompt: "LINE channel access token 已設定。保留目前值?",
				webhookTitle: "LINE webhook"
			},
			slack: {
				allowFromInvalidWithoutToken: "缺少 Slack token;只能使用使用者 ID(或 mention 形式)。",
				allowFromPrompt: "Slack allowFrom(使用者名稱或 ID)",
				allowlistIntro: "透過使用者名稱為 Slack DM 設定允許清單(會解析為使用者 ID)。",
				allowlistTitle: "Slack 允許清單",
				appToken: "Slack app token",
				appTokenInput: "輸入 Slack app token(xapp-...)",
				appTokenKeep: "Slack app token 已設定。保留目前值?",
				botToken: "Slack bot token",
				botTokenInput: "輸入 Slack bot token(xoxb-...)",
				botTokenKeep: "Slack bot token 已設定。保留目前值?",
				channelsLabel: "Slack 頻道",
				envPrompt: "偵測到 SLACK_BOT_TOKEN + SLACK_APP_TOKEN。使用環境變數?",
				examples: "範例:",
				interactiveRepliesPrompt: "為 agent 回應啟用 Slack 互動回覆(按鈕/選單)?",
				multipleEntries: "多個項目請用逗號分隔。",
				socketModeTokensTitle: "Slack socket mode token"
			},
			mattermost: {
				baseUrlPrompt: "輸入 Mattermost 基礎 URL",
				botToken: "bot token",
				botTokenInput: "輸入 Mattermost bot token",
				botTokenKeep: "Mattermost bot token 已設定。保留目前值?",
				botTokenTitle: "Mattermost bot token",
				envPrompt: "偵測到 MATTERMOST_BOT_TOKEN + MATTERMOST_URL。使用環境變數?",
				helpBaseUrl: "3) 使用你的伺服器基礎 URL(例如 https://chat.example.com)",
				helpBotMember: "提示:bot 必須加入任何你希望它監控的頻道。",
				helpCreateBot: "2) 建立 bot 並複製它的 token",
				helpOpenConsole: "1) Mattermost System Console -> Integrations -> Bot Accounts"
			},
			nextcloudTalk: {
				allowFromPrompt: "Nextcloud Talk allowFrom(使用者 ID)",
				apiPassword: "API 密碼",
				apiPasswordInput: "輸入 Nextcloud Talk API 密碼",
				apiPasswordKeep: "Nextcloud Talk API 密碼已設定。保留目前值?",
				apiUserPrompt: "Nextcloud Talk API 使用者",
				botSecret: "bot secret",
				botSecretEnvPrompt: "偵測到 NEXTCLOUD_TALK_BOT_SECRET。使用環境變數?",
				botSecretInput: "輸入 Nextcloud Talk bot secret",
				botSecretKeep: "Nextcloud Talk bot secret 已設定。保留目前值?",
				configureApiCredentials: "設定可選的 Nextcloud Talk API 憑證用於房間查找?",
				helpCopySecret: "3) 複製你在命令中使用的 shared secret",
				helpEnableRoom: "4) 在 Nextcloud Talk 房間設定中啟用 bot",
				helpEnvTip: "提示:也可以在環境變數中設定 NEXTCLOUD_TALK_BOT_SECRET。",
				helpInstallCommand: "2) 執行:./occ talk:bot:install \"OpenClaw\" \"<shared-secret>\" \"<webhook-url>\" --feature webhook --feature response --feature reaction",
				helpSsh: "1) SSH 進入你的 Nextcloud 伺服器",
				instanceUrlPrompt: "輸入 Nextcloud 實例 URL(例如 https://cloud.example.com)",
				setupTitle: "Nextcloud Talk bot 設定",
				userIdHelpAdmin: "1) 在 Nextcloud 管理後台查看使用者 ID",
				userIdHelpLogs: "2) 或在有人傳訊息時查看 webhook payload 日誌",
				userIdHelpLowercase: "3) 使用者 ID 通常是 Nextcloud 中的小寫使用者名稱",
				userIdTitle: "Nextcloud Talk 使用者 ID"
			},
			msteams: {
				allowFromPrompt: "MS Teams allowFrom(使用者名稱或 ID)",
				allowlistIntro: "透過顯示名稱、UPN/信箱或使用者 ID 為 MS Teams DM 設定允許清單。",
				allowlistResolve: "憑證允許時,會透過 Microsoft Graph 將名稱解析為使用者 ID。",
				allowlistTitle: "MS Teams 允許清單",
				appIdPrompt: "輸入 MS Teams App ID",
				appPasswordPrompt: "輸入 MS Teams App Password",
				channelLookupFailed: "頻道查找失敗;保留原始輸入。{error}",
				channelsLabel: "MS Teams 頻道",
				couldNotResolve: "無法解析:{entries}",
				credentialsKeep: "MS Teams 憑證已設定。保留目前值?",
				credentialsTitle: "MS Teams 憑證",
				delegatedAuthConfigured: "Delegated auth 已設定",
				delegatedAuthPrompt: "啟用 delegated auth?(reaction 和寫入操作需要)",
				delegatedAuthRetry: "之後可以透過設定精靈重試。",
				delegatedAuthTitle: "MS Teams delegated auth",
				delegatedOAuthProgress: "MSTeams Delegated OAuth",
				enterAtLeastOneUser: "至少輸入一個使用者。",
				envPrompt: "偵測到 MSTEAMS_APP_ID + MSTEAMS_APP_PASSWORD + MSTEAMS_TENANT_ID。使用環境變數?",
				examples: "範例:",
				graphLookupUnavailable: "Graph 查找不可用。請只使用使用者 ID。",
				helpAzureBot: "1) Azure Bot registration -> 取得 App ID + Tenant ID",
				helpClientSecret: "2) 新增 client secret(App Password)",
				helpEnvTip: "提示:也可以設定 MSTEAMS_APP_ID / MSTEAMS_APP_PASSWORD / MSTEAMS_TENANT_ID。",
				helpWebhook: "3) 設定 webhook URL 和 messaging endpoint",
				resolvedChannels: "已解析頻道:{entries}",
				resolvedTeams: "已解析團隊:{entries}",
				tenantIdPrompt: "輸入 MS Teams Tenant ID",
				unresolvedKept: "未解析(保留原始輸入):{entries}"
			},
			whatsapp: {
				allowedSenderNumbers: "允許的傳送者號碼(逗號分隔,E.164)",
				allowFromPrompt: "WhatsApp allowFrom(可選預允許清單)",
				allowlistModeEnabled: "已啟用允許清單模式。",
				allowlistTitle: "WhatsApp 允許清單",
				credentialsStored: "憑證會儲存在 {authDir}/ 下供之後執行使用。",
				dmAccessTitle: "WhatsApp DM 存取",
				dmPolicyAllowlistOnly: "僅允許清單(阻止未知傳送者)",
				dmPolicyDisabled: "停用(忽略 WhatsApp DM)",
				dmPolicyPrompt: "WhatsApp DM 策略",
				dmPolicySetAllowlist: "- dmPolicy 已設為 allowlist(略過配對)",
				helpTitle: "WhatsApp 說明",
				keepCurrentAllowFrom: "保留目前 allowFrom",
				linkLater: "稍後執行 `{command}` 連接 WhatsApp。",
				linkNowPrompt: "現在連接 WhatsApp(QR)?",
				linkingTitle: "WhatsApp 連接",
				numberTitle: "WhatsApp 號碼",
				ownerNumberNote: "需要傳送者/擁有者號碼,以便 OpenClaw 將你加入允許清單。",
				personalNumberPrompt: "你的個人 WhatsApp 號碼(你將用來傳訊息的手機)",
				personalPhoneLabel: "這是我的個人手機號碼",
				personalPhoneModeEnabled: "已啟用個人手機模式。",
				personalPhoneTitle: "WhatsApp 個人手機",
				phoneSetupPrompt: "WhatsApp 手機設定",
				relinkPrompt: "WhatsApp 已連接。現在重新連接?",
				scanQr: "請用手機上的 WhatsApp 掃描 QR code。",
				separatePhoneLabel: "OpenClaw 專用獨立手機",
				setAllowFromNumbers: "將 allowFrom 設定為指定號碼",
				unsetAllowFromDefault: "取消設定 allowFrom(預設)",
				unsetAllowFromPairing: "取消設定 allowFrom(僅使用配對核准)"
			},
			nostr: {
				allowFromPrompt: "Nostr allowFrom",
				allowlistIntro: "依 npub 或十六進位公鑰為 Nostr DM 設定允許清單。",
				allowlistTitle: "Nostr 允許清單",
				examples: "範例:",
				helpEnvVars: "支援環境變數:NOSTR_PRIVATE_KEY(僅預設帳號)。",
				helpPrivateKeyFormat: "使用 nsec 或 64 字元十六進位格式的 Nostr 私鑰。",
				helpRelaysOptional: "Relay URL 是可選的。留空會保留預設 relay 集合。",
				multipleEntries: "多個項目請用逗號分隔。",
				privateKeyEnvPrompt: "偵測到 NOSTR_PRIVATE_KEY。使用環境變數?",
				privateKeyInput: "Nostr 私鑰(nsec... 或 hex)",
				privateKeyKeep: "Nostr 私鑰已設定。保留目前值?",
				privateKeyTitle: "Nostr 私鑰",
				relaysTitle: "Nostr relays",
				relayUrlsKeep: "Relay URL 已設定({value})。保留?",
				relayUrlsPrompt: "Relay URL(逗號分隔,可選)",
				relaysWsOnly: "使用 ws:// 或 wss:// relay URL。",
				setupTitle: "Nostr 設定"
			},
			irc: {
				allowFromInvalid: "請輸入 IRC nick 或 nick!user@host 項目。",
				allowFromPrompt: "IRC allowFrom(nick 或 nick!user@host)",
				allowlistIntro: "依傳送者為 IRC DM 設定允許清單。",
				allowlistTitle: "IRC 允許清單",
				autoJoinPrompt: "自動加入 IRC 頻道(可選,逗號分隔)",
				envPrompt: "偵測到 IRC_HOST 和 IRC_NICK。使用環境變數?",
				examples: "範例:",
				helpEnvVars: "支援環境變數:IRC_HOST、IRC_PORT、IRC_TLS、IRC_NICK、IRC_USERNAME、IRC_REALNAME、IRC_PASSWORD、IRC_CHANNELS、IRC_NICKSERV_PASSWORD、IRC_NICKSERV_REGISTER_EMAIL。",
				helpGroupControl: "設定 channels.irc.groupPolicy=\"allowlist\" 和 channels.irc.groups 可收緊頻道控制。",
				helpMentionGate: "IRC 頻道預設需要 @mention 才回覆。如需允許非 mention 回覆,設定 channels.irc.groups[\"#channel\"].requireMention=false(或用 \"*\" 表示全部)。",
				helpNeedsHostNick: "IRC 需要伺服器 host 和 bot nick。",
				helpNickServOptional: "可選:完成基礎帳號欄位後可設定 NickServ identify/register。",
				helpRecommendedTls: "建議:TLS 使用 6697 連接埠。",
				multipleEntries: "多個項目請用逗號分隔。",
				nextRestartGateway: "下一步:重新啟動 gateway 並驗證狀態。",
				nextStatusCommand: "命令:openclaw channels status --probe",
				nextStepsTitle: "IRC 後續步驟",
				nickPrompt: "IRC nick",
				nickServConfigurePrompt: "設定 NickServ identify/register?",
				nickServPasswordEnvPrompt: "偵測到 IRC_NICKSERV_PASSWORD。使用環境變數?",
				nickServPasswordPrompt: "NickServ 密碼(留空則停用 NickServ 認證)",
				nickServRegisterEmailPrompt: "NickServ 註冊信箱",
				nickServRegisterPrompt: "連線時傳送 NickServ REGISTER?",
				nickServServicePrompt: "NickServ 服務 nick",
				nickServUpdatePrompt: "更新 NickServ 設定?",
				realNamePrompt: "IRC real name",
				requireMentionPrompt: "IRC 頻道回覆是否要求 @mention?",
				serverHostPrompt: "IRC 伺服器 host",
				serverPortPrompt: "IRC 伺服器連接埠",
				setupTitle: "IRC 設定",
				tlsPrompt: "IRC 使用 TLS?",
				usernamePrompt: "IRC username"
			},
			tlon: {
				addGroupsPrompt: "手動新增群組頻道?(可選)",
				autoDiscoveryPrompt: "啟用群組頻道自動發現?",
				dmAllowlistPrompt: "DM 允許清單(ship 名稱,逗號分隔)",
				groupChannelsPrompt: "群組頻道(逗號分隔)",
				helpExampleShip: "ship 範例:~sampel-palnet",
				helpExampleUrl: "URL 範例:https://your-ship-host",
				helpNeedsUrlCode: "需要你的 Urbit ship URL 和登入碼。",
				helpPrivateNetwork: "如果 ship URL 位於私有網路(LAN/localhost),設定時必須明確允許。",
				loginCodePrompt: "登入碼",
				privateNetworkPrompt: "Ship URL 看起來是私有/內部 host。允許私有網路存取?(SSRF 風險)",
				restrictDmsPrompt: "使用允許清單限制 DM?",
				setupTitle: "Tlon 設定",
				shipPrompt: "Ship 名稱",
				shipUrlPrompt: "Ship URL"
			},
			synologyChat: {
				accessControlTitle: "Synology Chat 存取控制",
				allowedUserIdsInvalid: "Synology Chat 使用者 ID 必須是數字。",
				allowedUserIdsPrompt: "允許的 Synology Chat 使用者 ID",
				allowlistIntro: "依數字使用者 ID 為 Synology Chat DM 設定允許清單。",
				allowlistTitle: "Synology Chat 允許清單",
				defaultPath: "預設路徑:{path}",
				examples: "範例:",
				helpAllowedUsers: "4) 準備好允許的使用者 ID,用於 DM allowlist",
				helpIncomingWebhook: "1) 在 Synology Chat 建立 incoming webhook 並複製 URL",
				helpOutgoingWebhook: "2) 建立 outgoing webhook 並複製 secret token",
				helpPointWebhook: "3) 將 outgoing webhook 指向 https://<gateway-host>{path}",
				incomingWebhookHelpReplies: "這是 OpenClaw 用來向 Chat 傳送回覆的 URL。",
				incomingWebhookHelpUseUrl: "使用 Synology Chat 整合裡的 incoming webhook URL。",
				incomingWebhookKeep: "Incoming webhook URL 已設定({value})。保留?",
				incomingWebhookTitle: "Synology Chat incoming webhook",
				incomingWebhookUrlPrompt: "Incoming webhook URL",
				multipleEntries: "多個項目請用逗號分隔。",
				outgoingWebhookPathHelp: "僅在需要多個 Synology Chat webhook 路由時修改。",
				outgoingWebhookPathKeep: "Outgoing webhook path 已設定({value})。保留?",
				outgoingWebhookPathPrompt: "Outgoing webhook path(可選)",
				outgoingWebhookPathTitle: "Synology Chat outgoing webhook path",
				setupTitle: "Synology Chat webhook 設定",
				tokenEnvPrompt: "偵測到 SYNOLOGY_CHAT_TOKEN。使用環境變數?",
				tokenInput: "輸入 Synology Chat outgoing webhook token",
				tokenKeep: "Synology Chat webhook token 已設定。保留目前值?",
				webhookTokenTitle: "Synology Chat webhook token"
			},
			signal: {
				accountKeep: "Signal 帳號已設定({value})。保留?",
				allowFromPrompt: "Signal allowFrom(E.164 或 uuid)",
				allowlistIntro: "依傳送者 ID 為 Signal DM 設定允許清單。",
				allowlistTitle: "Signal 允許清單",
				botNumberPrompt: "Signal bot 號碼(E.164)",
				examples: "範例:",
				installPrompt: "未找到 signal-cli。現在安裝?",
				multipleEntries: "多個項目請用逗號分隔。",
				nextLinkDevice: "綁定裝置:signal-cli link -n \"OpenClaw\"",
				nextScanQr: "在 Signal -> Linked Devices 中掃描 QR code",
				nextStepsTitle: "Signal 後續步驟",
				reinstallPrompt: "已偵測到 signal-cli。現在重新安裝/更新?"
			},
			zalo: {
				allowFromNumeric: "請使用數字 Zalo 使用者 ID",
				allowFromPrompt: "Zalo allowFrom(使用者 ID)",
				botToken: "bot token",
				botTokenTitle: "Zalo bot token",
				helpCreateBot: "2) 建立 bot 並取得 token",
				helpEnvTip: "提示:也可以在環境變數中設定 ZALO_BOT_TOKEN。",
				helpOpenPlatform: "1) 開啟 Zalo Bot Platform:https://bot.zaloplatforms.com",
				helpTokenFormat: "3) Token 類似 12345689:abc-xyz",
				tokenEnvPrompt: "偵測到 ZALO_BOT_TOKEN。使用環境變數?",
				tokenInput: "輸入 Zalo bot token",
				tokenKeep: "Zalo token 已設定。保留目前值?",
				webhookModePrompt: "為 Zalo 使用 webhook 模式?",
				webhookPathPrompt: "Webhook 路徑(可選)",
				webhookSecret: "webhook secret",
				webhookSecretInput: "Webhook secret(8-256 個字元)",
				webhookSecretKeep: "Zalo webhook secret 已設定。保留目前值?",
				webhookSecretLength: "Webhook secret 必須為 8 到 256 個字元。",
				webhookTitle: "Zalo webhook",
				webhookUrlPrompt: "Webhook URL(https://...)"
			},
			zalouser: {
				allowFromPlaceholder: "Alice、123456789,或留空稍後設定",
				allowFromPrompt: "Zalo Personal allowFrom(名稱或使用者 ID)",
				allowlistTitle: "Zalo Personal 允許清單",
				couldNotResolve: "無法解析:{entries}。請使用數字使用者 ID 或精確好友名稱。",
				directChatsBlocked: "在之後新增聯絡人前,直接聊天會保持阻止。",
				dmAccessTitle: "Zalo Personal DM 存取",
				dmHelpAllowlist: "- allowlist:只有列出的聯絡人可以 DM",
				dmHelpAllowlistEmpty: "如果現在選擇 allowlist,可以先留空,之後再新增聯絡人。",
				dmHelpDisabled: "- disabled:忽略 DM",
				dmHelpOpen: "- open:任何人都可以 DM",
				dmHelpPairing: "- pairing(預設):未知聯絡人會取得配對碼",
				dmHelpSeparate: "直接聊天和群聊會分開設定。",
				dmPolicyPrompt: "Zalo Personal DM 策略",
				groupChatsBlocked: "在之後新增群組前,群聊會保持阻止。",
				groupLookupFailed: "群組查找失敗;保留原始輸入。{error}",
				groupMentionRequirement: "之後允許的群組預設仍需要 mention。",
				groupsLookupTip: "提示:onboarding 後用 `{command}` 查找群組 ID。",
				groupsPlaceholder: "Family、Work、123456789,或暫時留空",
				groupsTitle: "Zalo 群組",
				helpQrLogin: "Zalo Personal 帳號透過 QR code 登入。",
				helpZcaJs: "該插件直接使用 zca-js(無外部 CLI 依賴)。",
				keepSessionPrompt: "Zalo Personal 已登入。保留工作階段?",
				loginPendingTitle: "登入待完成",
				loginQrPrompt: "現在透過 QR code 登入?",
				noDmAllowlist: "尚未新增 DM 允許清單項目。",
				noGroupAllowlist: "尚未新增群組允許清單項目。",
				peersLookupTip: "提示:onboarding 後用 `{command}` 查找聯絡人。",
				qrImageSaved: "QR code 圖片已儲存到:{path}",
				qrImageWriteFailed: "無法寫入 QR code 圖片檔;請改用 gateway web login UI。",
				qrLoginTitle: "QR code 登入",
				qrScannedPrompt: "你已經在手機上掃描並核准 QR code 了嗎?",
				scanApproveContinue: "在手機上掃描並核准,然後繼續。",
				setupTitle: "Zalo Personal 設定"
			},
			twitch: {
				accessTokenKeep: "Access token 已設定。保留目前值?",
				allowFromPrompt: "Twitch allowFrom(使用者 ID,每行一個,建議用於安全控制)",
				botUsernamePrompt: "Twitch bot 使用者名稱",
				channelJoinPrompt: "要加入的頻道",
				clientIdPrompt: "Twitch Client ID",
				clientSecretPrompt: "Twitch Client Secret(用於 token 更新)",
				envPrompt: "偵測到 Twitch 環境變數 OPENCLAW_TWITCH_ACCESS_TOKEN。使用環境 token?",
				helpCopyToken: "3. 複製 token(以 'oauth:' 開頭)和 Client ID",
				helpCreateApp: "1. 在 https://dev.twitch.tv/console 建立 Twitch 應用",
				helpEnvVars: "支援環境變數:OPENCLAW_TWITCH_ACCESS_TOKEN",
				helpGenerateToken: "2. 產生帶 chat:read 和 chat:write scopes 的 token",
				helpRequiresBot: "Twitch 需要一個帶 OAuth token 的 bot 帳號。",
				helpTokenTools: "   可使用 https://twitchtokengenerator.com/ 或 https://twitchapps.com/tmi/",
				oauthTokenPrompt: "Twitch OAuth token(oauth:...)",
				refreshTokenInputPrompt: "Twitch Refresh Token",
				refreshTokenPrompt: "啟用自動 token 更新?(需要 client secret 和 refresh token)",
				setupTitle: "Twitch 設定"
			},
			imessage: {
				imsgFound: "已找到 imsg",
				imsgMissing: "未找到 imsg"
			},
			channelsPrimer: {
				approveWith: "核准配對:{command}",
				docs: "文件:{link}",
				inboundSafety: "入站 DM 安全預設使用配對:未知傳送者會先取得配對碼。",
				multiUserDm: "多使用者 DM 請隔離工作階段:{command}(多帳號頻道也可用 \"per-account-channel-peer\")。",
				openDm: "開放/公開 DM 需要 dmPolicy=\"open\",並且 allowFrom=[\"*\"]。",
				title: "頻道運作方式",
				blurbs: {
					clickclack: "透過一等 ClickClack bot token 連接自託管聊天。",
					discord: "目前支援很完善。",
					feishu: "飛書/Lark 企業訊息。",
					googlechat: "透過 HTTP webhook 接入 Google Workspace Chat app。",
					imessage: "透過 imsg bridge 本機接入 iMessage/SMS;啟用後支援私有 API 訊息動作。",
					irc: "經典 IRC 網路,支援 DM/頻道路由和配對控制。",
					line: "LINE Messaging API webhook bot。",
					mattermost: "自託管 Slack 風格聊天;安裝插件後啟用。",
					matrix: "開放協定;安裝插件後啟用。",
					msteams: "Teams SDK;企業支援。",
					nextcloudTalk: "透過 Nextcloud Talk webhook bot 接入自託管聊天。",
					nostr: "去中心化協定;透過 NIP-04 傳送加密 DM。",
					qqbot: "透過官方 QQ Bot API 連接 QQ。",
					signal: "signal-cli 綁定裝置;需要更多設定(David Reagans:\"Hop on Discord.\")。",
					slack: "支援 Socket Mode。",
					synologyChat: "將 Synology NAS Chat 連接到 OpenClaw,並啟用完整 agent 能力。",
					telegram: "最容易上手:在 @BotFather 註冊 bot 後即可開始。",
					tlon: "Urbit 上的去中心化訊息;安裝插件後啟用。",
					twitch: "Twitch 聊天整合。",
					wecom: "企業訊息與文件、行程和任務工具。",
					whatsapp: "使用你自己的號碼;建議準備單獨手機和 eSIM。",
					yuanbao: "騰訊元寶 AI 助手會話頻道。",
					zalo: "面向越南市場、支援 Bot API 的訊息平台。",
					zalouser: "透過 QR code 登入接入 Zalo 個人帳號。"
				}
			},
			search: {
				chooseProvider: "選擇一個提供方。有些提供方需要 API key,有些無需 key。",
				configured: "已設定",
				configureLaterHint: "稍後可用 openclaw configure --section web 設定",
				docsLine: "文件:{url}",
				intro: "Web search 可以讓 agent 線上查詢資料。",
				keyFree: "無需 key",
				noProvidersAction: "請啟用插件或移除 deny 規則,然後重新執行設定。",
				noProvidersByPolicy: "目前插件策略下沒有可用的 web search 提供方。",
				providerPrompt: "搜尋提供方",
				title: "網頁搜尋"
			},
			finalize: {
				addNodes: "新增節點以啟用更多功能:",
				alreadyInstalled: "Gateway 服務已安裝",
				backupWorkspace: "備份你的 agent 工作區。",
				browserHatch: "在瀏覽器中啟動",
				codexNativeSearchOnly: "僅用於支援 Codex 的模型。",
				codexNativeSearchTitle: "Codex 原生搜尋",
				controlUiTitle: "Control UI",
				controlUiDocs: "文件:https://docs.openclaw.ai/web/control-ui",
				dashboardCopyPaste: "在本機瀏覽器中複製/貼上這個 URL 來控制 OpenClaw。",
				dashboardLinkWithToken: "Dashboard 連結(含權杖):{url}",
				dashboardOpened: "已在瀏覽器中開啟。保留該分頁以控制 OpenClaw。",
				dashboardOpenAnytime: "隨時開啟 dashboard:{command}",
				dashboardReady: "Dashboard 已就緒",
				dashboardTokenMemory: "Web UI 會把 dashboard URL 中的權杖保存在目前分頁記憶體中,並在載入後從 URL 中移除。",
				dashboardTokenPrompt: "如果被提示:把權杖貼到 Control UI 設定中(或使用帶權杖的 dashboard URL)。",
				dashboardWhenReady: "準備好後執行:{command}",
				daemonRuntime: "Gateway 服務執行環境",
				daemonRuntimeNode: "Node(建議)",
				daemonRuntimeNodeHint: "WhatsApp + Telegram 需要使用。Bun 重新連線時可能造成記憶體損壞。",
				editBootstrap: "之後可編輯 BOOTSTRAP.md 來修改 agent 的自我介紹方式。",
				bootstrapHatchMessage: "醒醒,我的朋友!",
				firstTerminalChat: "第一次終端機聊天會傳送:\"醒醒,我的朋友!\"",
				gatewayInstallBlocked: "Gateway 安裝被阻止:",
				gatewayInstallFixAuth: "修復 Gateway 認證設定/權杖輸入後重新執行設定。",
				gatewayNotDetected: "尚未偵測到 Gateway。",
				gatewayNotDetectedStatus: "Gateway:未偵測到{detail}",
				gatewayReachable: "Gateway:可存取",
				gatewayService: "Gateway 服務",
				gatewayServiceInstalled: "Gateway 服務已安裝。",
				gatewayServiceInstalling: "正在安裝 Gateway 服務...",
				gatewayServiceInstallFailed: "Gateway 服務安裝失敗。",
				gatewayServiceInstallFailedWithError: "Gateway 服務安裝失敗:{error}",
				gatewayServicePreparing: "正在準備 Gateway 服務...",
				gatewayServiceRestarted: "Gateway 服務已重新啟動。",
				gatewayServiceRestarting: "正在重新啟動 Gateway 服務...",
				gatewayServiceRestartScheduled: "Gateway 服務重新啟動已排程。",
				gatewayServiceUninstalled: "Gateway 服務已解除安裝。",
				gatewayServiceUninstalling: "正在解除安裝 Gateway 服務...",
				gatewayTokenGenerate: "產生權杖:{command}",
				gatewayTokenShared: "Gateway 權杖:Gateway 和 Control UI 的共享認證。",
				gatewayTokenStored: "儲存位置:$OPENCLAW_CONFIG_PATH(預設 ~/.openclaw/openclaw.json)中的 gateway.auth.token,或 OPENCLAW_GATEWAY_TOKEN。",
				gatewayTokenView: "查看權杖:{command}",
				gatewayWsUrl: "Gateway WS:{url}",
				hatchLater: "稍後啟動",
				hatchPrompt: "你想如何啟動 agent?",
				hatchYourAgent: "啟動你的 agent",
				healthCheckHelp: "健康檢查說明",
				installGateway: "安裝 Gateway 服務(建議)",
				laterTitle: "稍後",
				managedWebSearchSkipped: "已略過託管 web search provider。",
				noBackgroundGatewayExpected: "本次設定未安裝 Gateway 服務,因此不會有背景 Gateway。",
				nodeAndroid: "Android app(camera/canvas)",
				nodeIos: "iOS app(camera/canvas)",
				nodeMac: "macOS app(system + notifications)",
				optionalApps: "可選應用",
				outroDashboardLink: "Onboarding 完成。使用上面的 dashboard 連結控制 OpenClaw。",
				outroDashboardOpened: "Onboarding 完成。Dashboard 已開啟;保留該分頁以控制 OpenClaw。",
				outroSeeded: "Onboarding 完成。Web UI 已在背景初始化,可隨時用上面的 dashboard 連結開啟。",
				quickstartNodeRuntime: "QuickStart 使用 Node 執行 Gateway 服務(穩定且受支援)。",
				reinstall: "重新安裝",
				rerunInstallDaemon: "或重新執行:{command}",
				restart: "重新啟動",
				securityReminder: "在你的電腦上執行 agent 存在風險,請加固設定:https://docs.openclaw.ai/security",
				secretRefAuthFailed: "無法解析用於設定認證的 {field} SecretRef。",
				skipHealthNextTime: "下次也可略過此探測:{command}",
				skipControlUi: "略過 Control UI/TUI 提示。",
				startGatewayNow: "現在啟動:{command}",
				systemdInstallSkipped: "systemd 使用者服務不可用;略過服務安裝。請使用你的容器 supervisor 或 `docker compose up -d`。",
				systemdLingerReason: "Linux 安裝預設使用 systemd 使用者服務。沒有 lingering 時,systemd 會在使用者工作階段退出/閒置後停止工作階段並終止 Gateway。",
				systemdUnavailable: "systemd 使用者服務不可用。略過 lingering 檢查和服務安裝。",
				terminalHatch: "在終端機中啟動(建議)",
				webDocs: "文件:https://docs.openclaw.ai/tools/web",
				webSearchAutoDetected: "Web search 可透過 {provider} 使用(自動偵測)。",
				webSearchDisabled: "Web search({provider})已設定但被停用。",
				webSearchEnabled: "Web search 已啟用,agent 可在需要時線上查詢。",
				webSearchGetKey: "取得 key:{url}",
				webSearchAuthProfile: "憑證:使用已有 {provider} auth profile。",
				webSearchKeyEnv: "API key:透過 {env} 環境變數提供。",
				webSearchKeyRef: "API key:透過 secret reference 設定。",
				webSearchKeyStored: "API key:已存入設定。",
				webSearchNeedsKey: "新增 key 前 web_search 無法運作。",
				webSearchNoKey: "已選擇 provider {provider},但沒有找到 API key。",
				webSearchOAuthProfile: "憑證:使用已有 {provider} OAuth 登入。",
				webSearchProvider: "Provider:{provider}",
				webSearchProviderUnavailable: "已選擇 Web search provider {provider},但目前插件策略下不可用。",
				webSearchReenable: "重新啟用:{command}",
				webSearchSkipped: "已略過 web search。之後可啟用:",
				webSearchTitle: "Web search",
				webSearchUnavailableAction: "重新啟用該 provider 或選擇其他 provider 前,web_search 無法運作。",
				webUiUrl: "Web UI:{url}",
				webUiWithTokenUrl: "Web UI(含權杖):{url}",
				whatNow: "下一步:https://openclaw.ai/showcase(\"What People Are Building\")。",
				whatNowTitle: "下一步",
				workspaceBackupTitle: "工作區備份",
				workspaceDocs: "文件:https://docs.openclaw.ai/concepts/agent-workspace",
				workspaceReady: "你的工作區已就緒。"
			},
			gatewayNotes: {
				bindTitle: "Gateway 綁定",
				tailscaleBindLoopback: "Tailscale 暴露要求 bind=loopback。將把綁定位址切換為 loopback。",
				tailscaleFunnelPassword: "Tailscale Funnel 要求使用密碼認證。將把 Gateway 認證切換為密碼。"
			}
		}
	}
};
function normalizeLocaleToken(raw) {
	return (raw ?? "").trim().split(".")[0]?.split("@")[0]?.replaceAll("_", "-") ?? "";
}
function resolveWizardLocale(value) {
	const normalized = normalizeLocaleToken(value);
	if (!normalized) return "en";
	const lower = normalized.toLowerCase();
	if (lower === "en" || lower.startsWith("en-")) return "en";
	if (lower === "zh-tw" || lower === "zh-hk" || lower === "zh-mo" || lower.includes("hant")) return "zh-TW";
	if (lower === "zh" || lower === "zh-cn" || lower === "zh-sg" || lower.includes("hans")) return "zh-CN";
	return "en";
}
function resolveWizardLocaleFromEnv(env = process.env) {
	return resolveWizardLocale(env.OPENCLAW_LOCALE ?? env.LC_ALL ?? env.LC_MESSAGES ?? env.LANG);
}
function readKey(map, key) {
	let value = map;
	for (const segment of key.split(".")) {
		if (!value || typeof value === "string") return;
		value = value[segment];
	}
	return typeof value === "string" ? value : void 0;
}
function interpolate(value, params) {
	if (!params) return value;
	return value.replace(/\{([A-Za-z0-9_]+)\}/g, (match, key) => {
		const param = params[key];
		return param === void 0 || param === null ? match : String(param);
	});
}
function wizardT(key, params, options) {
	return interpolate(readKey(LOCALES[options?.locale ?? resolveWizardLocaleFromEnv()], key) ?? readKey(LOCALES["en"], key) ?? key, params);
}
const t = wizardT;
function createSetupTranslator(options) {
	const normalizedPrefix = options?.keyPrefix?.replace(/\.$/, "");
	return (key, params) => {
		return wizardT(normalizedPrefix && !key.startsWith("common.") && !key.startsWith("wizard.") ? `${normalizedPrefix}.${key}` : key, params, { locale: options?.locale });
	};
}
//#endregion
export { t as n, wizardT as r, createSetupTranslator as t };