openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
2,930 lines • 166 kB
JavaScript
//#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 };