use std::borrow::Cow;
use super::messages::Msg;
pub(super) fn zh_cn(msg: Msg<'_>) -> Cow<'static, str> {
match msg {
Msg::WelcomeBannerLine1 =>
"欢迎使用 AtomCode,请选择一项开始:".into(),
Msg::WelcomeBannerLine2 =>
"(↑↓ 切换,Enter 确认,Esc 跳过)".into(),
Msg::WelcomeOptionCodingPlan => "配置 CodingPlan".into(),
Msg::WelcomeOptionCodingPlanHint => "免费额度 · 推荐".into(),
Msg::WelcomeOptionConfigureManually => "手动配置".into(),
Msg::WelcomeOptionConfigureManuallyHint => "使用 API key".into(),
Msg::WelcomeOptionSkip => "暂时跳过".into(),
Msg::WelcomeOptionSkipHint => "稍后再说".into(),
Msg::CodingPlanSetupFailed { error } =>
format!("CodingPlan 设置失败:{error}").into(),
Msg::CpReauthAfter401 =>
" ⚠ 登录凭证已失效 — 正在重新登录...\n".into(),
Msg::ChatAuthExpired =>
"认证已过期,请执行 /login 重新登录".into(),
Msg::CpSetupHeader =>
" AtomCode CodingPlan 配置:\n\n".into(),
Msg::CpLoggedIn { who, username, email } =>
format!(" ✓ 已登录:{} ({},{})\n", who, username, email).into(),
Msg::CpStepSkipped { reason } =>
format!(" ✓ {}\n", reason).into(),
Msg::CpLoginFailed { error } =>
format!(" × 登录失败 — {}\n", error).into(),
Msg::CpClaimed { message, plan_type } =>
format!(" ✓ CodingPlan 已领取 — {}(CodingPlan {})\n", message, plan_type).into(),
Msg::CpClaimSuccessFallback => "成功".into(),
Msg::CpAlreadyClaimed { reason } =>
format!(" ✓ CodingPlan 已领取 — {}\n", reason).into(),
Msg::CpClaimFailed { error } =>
format!(" × CodingPlan 套餐配置失败 — {}\n", error).into(),
Msg::CpClaimFailedBare =>
" × CodingPlan 套餐配置失败\n".into(),
Msg::CpClaimTierSucceeded { tier } =>
format!(" ✓ CodingPlan {} 生效\n", tier).into(),
Msg::CpClaimTierAlreadyHeld { tier } =>
format!(" ✓ CodingPlan {} 生效\n", tier).into(),
Msg::CpClaimTierFailed { tier, reason } =>
format!(" × CodingPlan {} 套餐配置失败 — {}\n", tier, reason).into(),
Msg::CpAddedProviders { count, plural_s: _ } =>
format!(" ✓ 已添加 {} 个 Provider:\n", count).into(),
Msg::CpLocked { name } =>
format!(" \x1b[31m× {} (需要升级成 Pro 以上套餐)\x1b[39m\n", name).into(),
Msg::CpProviderRow { provider, model, default_suffix } =>
format!(" • {} → {}{}\n", provider, model, default_suffix).into(),
Msg::CpDefaultSuffix => " (默认)".into(),
Msg::CpVisionAuto { kind } =>
format!(" ✓ 视觉预处理器 → {} (自动检测)\n", kind).into(),
Msg::CpVisionUserSupplied { kind } =>
format!(" ✓ 视觉预处理器 → {} (保留用户设置)\n", kind).into(),
Msg::CpVisionCleared =>
" ⚠ 视觉预处理器已清除 — 当前模型列表中没有可用的 VL/OCR 模型\n".into(),
Msg::CpModelsSkipped { reason } =>
format!(" ✓ 模型步骤已跳过 — {}\n", reason).into(),
Msg::CpModelsFailed { error } =>
format!(" × 模型步骤失败 — {}\n", error).into(),
Msg::CpStatusHeader =>
" ✓ CodingPlan 状态:\n".into(),
Msg::CpPlanPending { plan } =>
format!(" 套餐:{} · 正在激活\n", plan).into(),
Msg::CpPlanActive { plan, expires_at, remaining_days, total_days } =>
format!(
" 套餐:{} · 到期时间 {}(剩余 {}d / 共 {}d)\n",
plan, expires_at, remaining_days, total_days,
).into(),
Msg::CpUsageLine { usage, reset_at, duration } =>
format!(" 用量:{} · 重置于 {}({} 后)\n", usage, reset_at, duration).into(),
Msg::CpMonthlyQuotaExhausted { duration } =>
format!(" 用量:本月用量已耗尽,等 {} 后再使用\n", duration).into(),
Msg::CpWindowQuotaExhausted =>
" ⚠ 当前窗口配额已耗尽\n".into(),
Msg::CpWindowQuotaHint { hint } =>
format!(" ⚠ {}\n", hint).into(),
Msg::CpStatusFetchSkipped { reason } =>
format!(" ⚠ 状态获取已跳过 — {}\n", reason).into(),
Msg::CpStatusFetchFailed { error } =>
format!(" ⚠ 状态获取失败(非致命) — {}\n", error).into(),
Msg::CpOfficialBuildRequired => Cow::Borrowed(
"此功能需要官方 AtomCode 构建,请前往 \
https://atomgit.com/atomgit_atomcode/atomcode/releases 下载安装。",
),
Msg::CpAuthRequired => Cow::Borrowed(
"未登录 AtomCode CodingPlan。请运行 /login 完成登录后再发送请求。",
),
Msg::CpSignStaleClockSkew => Cow::Borrowed(
"请求被服务端拒绝:签名时间戳已过期。请校准本地系统时间(NTP 同步)后重试。",
),
Msg::CpSignReplayPersisted => Cow::Borrowed(
"请求多次被识别为重放,请重新运行命令。",
),
Msg::CpSignVersionTooOld => Cow::Borrowed(
"当前 AtomCode 版本过旧,已不兼容 CodingPlan。请升级 AtomCode 后继续使用。",
),
Msg::CpUpgradeRequired => Cow::Borrowed(
"需要升级才能继续使用 CodingPlan,请前往官方发布页安装最新版 AtomCode。",
),
Msg::ErrUnsupportedLocale { input } =>
format!("不支持的语言:{input}").into(),
Msg::StatusNoProvider =>
"未配置 Provider · 使用 /provider 配置".into(),
Msg::StatusOfficialBuildRequired =>
"CodingPlan 需要官方构建".into(),
Msg::StatusUpgradeHint { version } =>
format!("↑ {version} 可用 · 使用 /upgrade 升级").into(),
Msg::StatusUpgradeHintPm { version } =>
format!("↑ {version} 可用 · 运行 brew upgrade atomcode 升级").into(),
Msg::StatusModelNotConfigured =>
"(未配置)".into(),
Msg::StatusClipboardImageHint =>
"剪贴板有图片 · ctrl+v 粘贴".into(),
Msg::StatusClipboardImageHintSlash =>
"剪贴板有图片 · /paste 粘贴".into(),
Msg::StatusWebuiHint =>
"提示:使用 /webui 在浏览器中打开 AtomCode".into(),
Msg::StatusBody { model, dir, config, tokens } =>
format!(
" 模型: {}\n 目录: {}\n 配置文件:{}\n Token: {}\n",
model, dir, config, tokens,
).into(),
Msg::StatusCpNotSignedIn =>
" CodingPlan:(未登录 — 运行 /login 进行配置)\n".into(),
Msg::StatusCpFetchFailed { error } =>
format!(" CodingPlan:(状态获取失败 — {})\n", error).into(),
Msg::StatusCpNoActive =>
" CodingPlan:(无激活套餐 — 运行 /login)\n".into(),
Msg::StatusCpLine { plan, expires_at, remaining_days, total_days } =>
format!(
" CodingPlan:{} · 到期 {}({}d / 共 {}d)\n",
plan, expires_at, remaining_days, total_days,
).into(),
Msg::StatusCpUsage { usage, reset_at, duration } =>
format!(" 用量:{} · 重置于 {}({} 后)\n", usage, reset_at, duration).into(),
Msg::StatusCpMonthlyExhausted { duration } =>
format!(" ⚠ 本月用量已耗尽,等 {} 后再使用\n", duration).into(),
Msg::StatusCpWindowExhausted =>
" ⚠ 当前窗口配额已耗尽\n".into(),
Msg::StatusCpWindowHint { hint } =>
format!(" ⚠ {}\n", hint).into(),
Msg::StatusInstructionFilesHeader =>
" 指令文件:\n".into(),
Msg::StatusInstructionPresent { path, label } =>
format!(" ✓ {} ({})\n", path, label).into(),
Msg::StatusInstructionMissing { label } =>
format!(" × {} — 未找到\n", label).into(),
Msg::HelpAvailableCommands =>
" 可用命令:\n".into(),
Msg::KeybindingsHelp => r#" 键盘快捷键
── 输入 ──
Enter 发送消息
Ctrl+J 插入换行(所有终端通用)
\ 后接 Enter 插入换行(atomcode 兜底,所有终端通用)
Alt+Enter 插入换行 *
Shift+Enter 插入换行 **
/ 打开斜杠命令菜单
Tab 自动补全
Backspace / Ctrl+H 删除上一个字符
Delete / Ctrl+? 删除下一个字符
Ctrl+W 删除前一个单词
Ctrl+U 清空当前行
Ctrl+K 删除到行尾
Ctrl+A / Home 跳到行首
Ctrl+E / End 跳到行尾
Left / Right 光标左右移动
── 历史 ──
Up 上一条输入
Down 下一条输入
── 翻看输出 ──
用终端原生 scrollback(cmd+↑/↓、鼠标滚轮、tmux copy-mode 等都生效)
鼠标拖选 + Ctrl+C 复制(atomcode 不接管鼠标)
── 会话 ──
Ctrl+C 取消当前轮 / 关闭弹层
Ctrl+D 退出 atomcode
Ctrl+L 清屏
Ctrl+O 切换工具实时输出
Ctrl+V 粘贴(文本 + 图片)
── 斜杠菜单 / 弹层导航 ──
Up / Down 移动选择
Enter 确认
Esc 取消 / 关闭弹层
Tab 插入当前高亮命令
* Alt+Enter 在多数终端可用;macOS Apple Terminal 需在
Settings → Profiles → Keyboard 启用 "Use Option as Meta key"
才会发送换行。
** Shift+Enter 需要终端区分该按键,目前已知支持的有:
Kitty / WezTerm / iTerm2(启用 Report Modifiers)/
Windows Terminal / Ghostty / Warp。其他终端(包括 macOS
Apple Terminal、默认 xterm、GNOME Terminal、VS Code 集成
终端)不区分 Shift+Enter 与 Enter,请用 Ctrl+J 或 \ + Enter。
提示:输入 /help 查看完整斜杠命令列表。
"#.into(),
Msg::ProviderWizardHeader =>
" Provider 管理 — 添加 / 编辑 / 删除 / 设为默认。按 Esc 取消。\n".into(),
Msg::ProviderWizardCancelled =>
"(已取消)".into(),
Msg::ProviderMenuAdd => "添加".into(),
Msg::ProviderMenuAddDesc => "添加新 Provider".into(),
Msg::ProviderMenuEdit => "编辑".into(),
Msg::ProviderMenuEditDesc => "编辑已有 Provider".into(),
Msg::ProviderMenuDelete => "删除".into(),
Msg::ProviderMenuDeleteDesc => "移除 Provider".into(),
Msg::ProviderMenuSetDefault => "设为默认".into(),
Msg::ProviderMenuSetDefaultDesc => "切换默认 Provider".into(),
Msg::ProviderImportPrompt =>
"粘贴模板自动识别(curl / JSON / TOML),或直接回车手动填写:".into(),
Msg::ProviderImportParsed { base_url, type_name, model } =>
format!("已识别:{base_url} · {type_name} · {model}").into(),
Msg::ProviderImportFailed =>
"未能识别为模板,请重贴 curl / JSON / TOML,或留空回车手动填写。".into(),
Msg::ProviderNoProviders =>
"尚未配置任何 Provider。".into(),
Msg::ProviderDeleteConfirm { name } =>
format!("删除 \"{name}\"?[y/N]").into(),
Msg::ProviderDeleted { name } =>
format!("已移除 \"{name}\"。").into(),
Msg::ProviderDeleteKept => "(已保留)".into(),
Msg::ProviderDefaultSet { name } =>
format!("默认已设为 {name}。").into(),
Msg::ProviderAdded { name, model } =>
format!("已添加 Provider \"{name}\",并切换到 {name} · {model}。").into(),
Msg::ProviderUpdated { name } =>
format!("已更新 \"{name}\"。").into(),
Msg::ProviderStepName => "Provider 名称?".into(),
Msg::ProviderStepType => "类型?(openai / claude / ollama)".into(),
Msg::ProviderStepTypeWithHint { current } =>
format!("类型?[{current}](openai / claude / ollama,留空保持不变)").into(),
Msg::ProviderStepBaseUrl =>
"Base URL?(例:https://api.deepseek.com/v1)".into(),
Msg::ProviderStepBaseUrlWithHint { current } =>
format!("Base URL?[{current}](留空保持不变)").into(),
Msg::ProviderDefaultHint => "Provider 默认值".into(),
Msg::ProviderStepApiKey =>
"API 密钥?(留空不设置)".into(),
Msg::ProviderStepApiKeyWithHint { hint } =>
format!("API 密钥?[{hint}]").into(),
Msg::ProviderStepApiKeySet => "已设置 — 留空保持不变".into(),
Msg::ProviderStepApiKeyUnset => "未设置".into(),
Msg::ProviderStepModel => "模型?".into(),
Msg::ProviderStepModelWithHint { current } =>
format!("模型?[{current}](留空保持不变)").into(),
Msg::ProviderNameEmpty => "名称不能为空。".into(),
Msg::ProviderBaseUrlEmpty => "Base URL 不能为空。".into(),
Msg::ProviderUnknownType =>
"未知类型。请选择 openai / claude / ollama。".into(),
Msg::ProviderUnknownTypeEdit =>
"未知类型。请选择 openai / claude / ollama 或留空。".into(),
Msg::ProviderModelEmpty => "模型不能为空。".into(),
Msg::ProviderEditKeep => "(保持不变)".into(),
Msg::ProviderTypeInferred { type_name } =>
format!("已识别类型:{type_name}").into(),
Msg::ProviderStepNameDefault { default } =>
format!("Provider 名称?[{default}](留空使用此名)").into(),
Msg::ProviderStepProgress { current, total } =>
format!("({current}/{total})").into(),
Msg::ModelSwitched { provider, model } =>
format!(" 已切换到 {provider} · {model}\n").into(),
Msg::SessionLoadFailed { error } =>
format!("加载会话失败:{error}").into(),
Msg::SessionResumedLabel { name } =>
format!("已恢复:{name}").into(),
Msg::SessionTimeJustNow => "刚刚".into(),
Msg::SessionTimeMinAgo { n } => format!("{n}分钟前").into(),
Msg::SessionTimeHourAgo { n } => format!("{n}小时前").into(),
Msg::SessionTimeDayAgo { n } => format!("{n}天前").into(),
Msg::SessionMsgCount { count } =>
format!("{count} 条消息").into(),
Msg::SessionNameEmpty =>
"会话名不能为空".into(),
Msg::SessionNameTooLong { max } =>
format!("会话名过长(最多 {max} 个字符)").into(),
Msg::SessionNameControlChars =>
"会话名不能包含控制字符".into(),
Msg::SessionListFailed { error } =>
format!("列出会话失败:{error}").into(),
Msg::SessionRenamed { old, new } =>
format!(" 已重命名:'{old}' -> '{new}'").into(),
Msg::SessionSaveFailed { error } =>
format!("保存会话失败:{error}。未持久化新名称。").into(),
Msg::SessionNoneSelected =>
"未选中会话".into(),
Msg::SessionRenameEditing { buffer } =>
format!("> {buffer}_ [Enter: 确认, Esc: 取消]").into(),
Msg::DirCurrent => "当前".into(),
Msg::DirNotExists { path } =>
format!("目录已不存在:{path}").into(),
Msg::DirChanged { path } =>
format!(" 已切换到:{path}\n").into(),
Msg::DirNotADirectory { path } =>
format!("不是目录:{path}").into(),
Msg::IssueCancelled => "(已取消)".into(),
Msg::IssueNewOn { owner, repo } =>
format!("在 atomgit.com/{owner}/{repo} 创建 Issue").into(),
Msg::IssueStep1 =>
"步骤 1/2 — 输入标题(必填,按 Esc 取消):".into(),
Msg::IssueStep2 =>
"步骤 2/2 — 输入描述(Shift+Enter 换行,Enter 提交,Esc 取消):".into(),
Msg::IssueTitleConfirmed { title } =>
format!("✓ 标题:{title}").into(),
Msg::IssueCreated { number, title, url } =>
format!(" [issue] ✓ 已创建 #{number}:{title}\n {url}\n").into(),
Msg::IssueCreateFailed { error } =>
format!(" [issue] × 创建失败:{error}\n").into(),
Msg::IssueRequiredField { field } =>
format!("(必填 — 请输入 {field},或按 Esc 取消)").into(),
Msg::LanguageSwitched { label, locale } =>
format!(" ✓ 已切换语言为 {label}({locale})。\n").into(),
Msg::IdleHintPrefix =>
"输入内容,或按 ".into(),
Msg::IdleHintSlash => "/".into(),
Msg::IdleHintSuffix =>
" 浏览命令".into(),
Msg::IdleHintFull =>
"输入内容,或按 / 浏览命令".into(),
Msg::IdleHintProvider => "/provider".into(),
Msg::IdleHintProviderSuffix =>
"添加自定义模型".into(),
Msg::IdleHintProviderFull =>
"使用 /provider 添加自定义模型".into(),
Msg::IdleHintCodingplan => "/login".into(),
Msg::IdleHintCodingplanSuffix =>
"领取免费 Token 额度".into(),
Msg::IdleHintCodingplanFull =>
"使用 /login 领取免费 Token 额度".into(),
Msg::IdleHintWebui => "/webui".into(),
Msg::IdleHintWebuiSuffix =>
"在浏览器中同步会话".into(),
Msg::IdleHintWebuiFull =>
"使用 /webui 在浏览器中同步会话".into(),
Msg::CmdSwitchedPlanMode =>
" 已切换到 Plan 模式(只读探索)。\n".into(),
Msg::CmdSwitchedBuildMode =>
" 已切换到 Build 模式(完整执行)。\n".into(),
Msg::CmdNewSession =>
" 新会话已开始。\n".into(),
Msg::CmdNoProviders =>
" 未配置任何 Provider。\n".into(),
Msg::CmdNoSessions =>
" 未找到历史会话。请先开始一段对话。\n".into(),
Msg::CmdUnknownCommand { name } =>
format!("未知命令:/{name}").into(),
Msg::CmdLoginFailed { error } =>
format!("登录失败:{error}").into(),
Msg::CmdLogoutDone =>
" 已退出 AtomGit 登录。权限已刷新。\n".into(),
Msg::CmdLogoutFailed { error } =>
format!("退出登录失败:{error}").into(),
Msg::CmdWhoamiNotSignedIn =>
" 尚未登录。使用 /login 进行认证。\n".into(),
Msg::CmdReloadDone { provider, model } =>
format!(" 配置已重载。当前:{provider} · {model}\n").into(),
Msg::CmdReloadFailed { error } =>
format!("重载失败:{error}(保留先前配置)").into(),
Msg::CmdUndoNotSupported =>
" 撤销功能暂不支持。\n".into(),
Msg::CmdUndoDone { target, last } =>
format!(" ↩ 已退回到第 {target} 轮之前(删除第 {target}~{last} 轮)。你的提示词已填回输入框。\n").into(),
Msg::CmdUndoDiskWarning =>
" ⚠ 仅回滚了对话记忆,磁盘文件未恢复。如需还原代码,请手动处理或用 /diff 查看。\n".into(),
Msg::CmdUndoNoTurns =>
" 没有可撤销的轮次。\n".into(),
Msg::CmdUndoOutOfRange { requested, available } =>
format!(" 无效的轮次 {requested}(当前共 {available} 轮)。\n").into(),
Msg::CmdUndoBusy =>
" 当前回合进行中,无法撤销——请先按 Esc 取消。\n".into(),
Msg::CmdUndoBadArg =>
" 用法:/undo 或 /undo N(N 为轮次号)。\n".into(),
Msg::CmdNoChanges =>
" (无变更)\n".into(),
Msg::CmdCheckingUpdate =>
" 正在检查更新...\n".into(),
Msg::CmdNoActiveProvider =>
"未配置活跃的 Provider。使用 /provider 添加一个。".into(),
Msg::ApprovalPromptAlt { tool, detail } =>
format!("允许 {}({})?[Y]是 / [N]否 / [A]总是", tool, detail).into(),
Msg::ApprovalWaitingLabel =>
"▶ 等待审批:".into(),
Msg::ApprovalAllow => " 允许 ".into(),
Msg::ApprovalAlways => " 总是 ".into(),
Msg::ApprovalDeny => " 拒绝".into(),
Msg::Cancelled => "(已取消)".into(),
Msg::ErrorPrefix { msg } =>
format!("[错误:{msg}]").into(),
Msg::UpgradeSuccess { from, to } =>
format!(" ✓ 已升级 {} → {}\n", from, to).into(),
Msg::UpgradeManifestFetched { version } =>
format!(" 最新版本: {}\n", version).into(),
Msg::UpgradeDownloading { pct, bytes, total } =>
format!(" 下载中 {}% ({} / {} bytes)\n", pct, bytes, total).into(),
Msg::UpgradeVerifying =>
" 正在校验 SHA256\n".into(),
Msg::UpgradeReplacing =>
" 正在替换二进制文件\n".into(),
Msg::UpgradeDone { version, backup } =>
format!("\n✓ 已升级到 {}(旧版本保留为 {})\n 正在重启新版本...\n", version, backup).into(),
Msg::UpgradeAlreadyLatest { current, latest } =>
format!(
" ✓ 已是最新版本,无需更新(当前 {},远端最新 {})。如需重装请加 --force。\n",
current, latest
).into(),
Msg::UpgradeFailed { error } =>
format!("升级失败: {}", error).into(),
Msg::UpgradeRolledBack { exe, backup } =>
format!("\n✓ 已回滚。当前二进制: {};另一版本保存在 {}\n 正在重启回滚版本...\n", exe, backup).into(),
Msg::KbdHintMacos =>
" ⚠ 终端不支持增强键盘协议。\n 请使用 Ctrl+Enter 插入换行(Shift+Enter 不可用)。\n\n".into(),
Msg::KbdHintOther =>
" ⚠ 终端不支持增强键盘协议。\n 请使用 Alt+Enter 或 Ctrl+Enter 插入换行(Shift+Enter 不可用)。\n\n".into(),
Msg::BackgroundComplete { turns } =>
format!(" 后台任务完成({} 轮):\n", turns).into(),
Msg::BackgroundFailed { turns } =>
format!(" 后台任务失败,共 {} 轮:\n", turns).into(),
Msg::BackgroundFilesEdited =>
" 已编辑的文件:\n".into(),
Msg::ConfigProviderLabel { provider, path } =>
format!(" Provider:{}\n 配置文件:{}\n\n", provider, path).into(),
Msg::CostReport { prompt, completion, cached, cache_rate, total, cost } =>
format!(
" 提示 Token: {}\n 补全 Token: {}\n 缓存 Token: {}({}% 命中率)\n Token 总计: {}\n 预估费用: {}\n",
prompt, completion, cached, cache_rate, total, cost
).into(),
Msg::ThinkStatus { status, budget, provider } =>
format!(
" 深度思考:{}\n 预算:{} Token\n Provider:{}\n\n 用法:/think on | off | budget <N>\n",
status, budget, provider
).into(),
Msg::ThinkEnabled { budget } =>
format!(" 深度思考已启用(预算:{} Token)。\n", budget).into(),
Msg::ThinkDisabled =>
" 深度思考已禁用。\n".into(),
Msg::ThinkBudgetSet { n } =>
format!(" 思考预算已设为 {} Token。\n", n).into(),
Msg::ThinkBudgetTooSmall { n } =>
format!("预算必须 >= 1024(当前 {})", n).into(),
Msg::ThinkBudgetUsage =>
"用法:/think budget <数字>".into(),
Msg::ThinkUsage =>
" 用法:/think [on | off | budget <N>]\n".into(),
Msg::RememberUsage =>
"用法:/remember <要记住的内容>(--global 为全局范围)".into(),
Msg::ForgetUsage =>
"用法:/forget <关键词>".into(),
Msg::BackgroundUsage =>
" 用法:/background <任务描述>\n".into(),
Msg::InitAlreadyExists { path } =>
format!(" {} 已存在。使用 `/init --force` 覆盖。\n", path).into(),
Msg::InitWrote { path, bytes } =>
format!(" 已写入 {}({} 字节)。编辑以自定义;下一条消息生效。\n", path, bytes).into(),
Msg::InitFailed { error } =>
format!(" /init 失败:{}\n", error).into(),
Msg::CdWorkingDir { cwd } =>
format!(" 工作目录:{}\n 无最近项目。使用 `/cd <路径>` 切换。\n", cwd).into(),
Msg::DiffFailed { error } =>
format!("git diff 失败:{}", error).into(),
Msg::UpgradePackageManaged =>
"本版本由 HarmonyBrew 管理,请运行 `brew upgrade atomcode` 升级".into(),
Msg::UpgradeUnknownArg { arg } =>
format!("未知的 /upgrade 参数:{}\n 用法:/upgrade [rollback|--force]", arg).into(),
Msg::SkillsNone =>
" 没有可调用的技能。\n".into(),
Msg::SkillsAvailable =>
" 可用技能:\n".into(),
Msg::SkillUnknown { name } =>
format!("未知技能:{}(输入 /skills 查看列表)", name).into(),
Msg::McpReloading { count } =>
format!(" 正在重载 MCP 服务器...({} 个已配置)\n", count).into(),
Msg::McpConnecting =>
" 正在连接:\n".into(),
Msg::McpConnectingServer { name } =>
format!(" - {} 连接中...\n", name).into(),
Msg::McpNoServersConfigured =>
" 未配置 MCP 服务器。\n".into(),
Msg::McpClearedReconnecting { removed } =>
format!(" ✓ 已清除 {} 个 MCP 工具。正在后台重新连接...\n", removed).into(),
Msg::McpClearedNoServers { removed } =>
format!(" ✓ 已清除 {} 个 MCP 工具。无需连接。\n", removed).into(),
Msg::McpToolsUsage =>
" 用法:/mcp tools <服务器名>\n 示例:/mcp tools filesystem\n".into(),
Msg::McpToolsListing { server } =>
format!(" 正在列出 '{}' 的 MCP 工具...\n", server).into(),
Msg::McpNoRegistry =>
" MCP 注册表未加载。请先运行 /mcp reload。\n".into(),
Msg::McpServersHeader =>
" MCP 服务器:\n".into(),
Msg::McpReloadFailed { error } =>
format!("MCP 重载失败:无法加载 .mcp.json / $ATOMCODE_HOME/mcp.json:{:#}", error).into(),
Msg::McpOAuthLoginUsage =>
" 用法:/mcp login <服务名>\n 示例:/mcp login github\n".into(),
Msg::McpOAuthLogoutUsage =>
" 用法:/mcp logout <服务名>\n 示例:/mcp logout github\n".into(),
Msg::McpOAuthLoadConfigFailed { error } =>
format!(" MCP OAuth 登录失败:无法加载配置:{error}\n").into(),
Msg::McpOAuthServerNotFound { server } =>
format!(" MCP OAuth 登录失败:配置中未找到服务 '{server}'。\n").into(),
Msg::McpOAuthStarting { server } =>
format!(" 正在浏览器中启动 '{server}' 的 MCP OAuth 流程...\n").into(),
Msg::McpOAuthSaved { provider, server } =>
format!(" 已保存 MCP 服务 '{server}' 的 {provider} OAuth Token。运行 /mcp reload 完成连接。\n").into(),
Msg::McpOAuthFailed { error } =>
format!(" MCP OAuth 失败:{error}\n").into(),
Msg::McpOAuthTokenRemoved { server } =>
format!(" 已移除 MCP 服务 '{server}' 保存的 OAuth Token。\n").into(),
Msg::McpOAuthNoToken { server } =>
format!(" 未找到 MCP 服务 '{server}' 保存的 OAuth Token。\n").into(),
Msg::McpOAuthLogoutFailed { error } =>
format!(" MCP OAuth 登出失败:{error}\n").into(),
Msg::McpServerConnected { name } =>
format!("✓ MCP 服务 '{name}' 已连接").into(),
Msg::McpServerFailed { name, error } =>
format!("× MCP 服务 '{name}' 失败:{error}").into(),
Msg::LspServerStarted { name, ext } =>
format!("✓ LSP 服务 '{name}' 已为 .{ext} 启动").into(),
Msg::LspServerFailed { name, ext, error } =>
format!("× LSP 服务 '{name}'(.{ext})失败:{error}").into(),
Msg::WorktreeUsage =>
" 用法:\n /worktree create <分支> [基准] 创建工作树并切换\n /worktree list 列出所有工作树\n /worktree done 切回原始目录\n /worktree cleanup <分支> 清理工作树\n".into(),
Msg::WorktreeCreateUsage =>
" 用法:/worktree create <分支> [基准]\n 示例:/worktree create fix-bug main\n".into(),
Msg::WorktreeCreated { branch, base, path } =>
format!(" ✓ 工作树已创建\n 分支:{}(基于 {})\n 路径:{}\n 工作目录已切换\n", branch, base, path).into(),
Msg::WorktreeCreateFailed { error } =>
format!("工作树创建失败:{}", error).into(),
Msg::WorktreeNoActive =>
" 没有活跃的工作树。\n".into(),
Msg::WorktreeListFailed { error } =>
format!("工作树列表失败:{}", error).into(),
Msg::WorktreeActiveHeader =>
" 活跃工作树:\n".into(),
Msg::WorktreeHasChanges => "(有变更)".into(),
Msg::WorktreeClean => "(无变更)".into(),
Msg::WorktreeCurrent => " ← 当前".into(),
Msg::WorktreeDoneBack { path } =>
format!(" ✓ 工作目录已切回:{}\n", path).into(),
Msg::WorktreeDoneMergeHint { branch } =>
format!(" 提示:使用 'git merge {}' 或创建 PR 合入主分支\n", branch).into(),
Msg::WorktreeNoSession =>
" 没有活跃的工作树会话。先使用 /worktree create 创建一个。\n".into(),
Msg::WorktreeCleanupUsage =>
" 用法:/worktree cleanup <分支> [--force]\n".into(),
Msg::WorktreeCleaned { branch } =>
format!(" ✓ 工作树 '{}' 已清理\n", branch).into(),
Msg::WorktreeCleanedSwitched { path } =>
format!(" 工作目录已切回:{}\n", path).into(),
Msg::WorktreeCleanupUncommitted { branch } =>
format!(" ⚠ 工作树 '{}' 有未提交的变更。\n 使用 /worktree cleanup {} --force 强制清理\n", branch, branch).into(),
Msg::WorktreeCleanupFailed { error } =>
format!("工作树清理失败:{}", error).into(),
Msg::HelpCustomCommandsHeader =>
" 自定义命令:\n".into(),
Msg::HelpCustomNone =>
" (无)\n\n".into(),
Msg::HelpCustomCreateHint =>
" 创建方式:~/.atomcode/commands/<名称>.md 或 .atomcode/commands/<名称>.md\n".into(),
Msg::HelpSourceGlobal => "全局".into(),
Msg::HelpSourceProject => "项目".into(),
Msg::SetupHeader { installed, skipped, failed, duration_ms } =>
format!("\n✅ Setup 完成 — {} 装好, {} 跳过, {} 失败 · 耗时 {}ms\n\n", installed, skipped, failed, duration_ms).into(),
Msg::SetupInstalledLabel =>
"已安装:\n".into(),
Msg::SetupSkippedLabel =>
"\n跳过:\n".into(),
Msg::SetupFailedLabel =>
"\n失败:\n".into(),
Msg::SetupInstalledRow { kind, slug, path } =>
format!(" ✓ {}:{} → {}\n", kind, slug, path).into(),
Msg::SetupSkippedRow { kind, slug, reason } =>
format!(" - {}:{} ({:?})\n", kind, slug, reason).into(),
Msg::SetupFailedRow { kind, slug, error } =>
format!(" × {}:{} — {}\n", kind, slug, error).into(),
Msg::CmdSetupTip =>
"\u{1f4a1} 提示:运行 \x1b[1;96m/setup\x1b[0m 可自动为该项目配置 hooks、skills 和 MCP。".into(),
Msg::CmdSetupRunning =>
"正在运行 atomcode setup...".into(),
Msg::CmdSetupSkillsReloaded { count } =>
format!(" 🔄 Skills 已重载 — {} 个可用", count).into(),
Msg::CmdSetupError { error } =>
format!("setup 错误:{error}").into(),
Msg::CmdSetupRunningSkill =>
" 🚀 正在运行 setup skill — 分析项目并生成推荐...".into(),
Msg::CmdSetupSkillMissing =>
"setup skill 未找到 — 请重新运行 /setup 以重新安装".into(),
Msg::PluginUsage =>
"用法:/plugin [marketplace add|remove|update|list | install <p>@<m> | uninstall <p>@<m> | reload | list]".into(),
Msg::PluginMarketplaceUsage =>
"用法:/plugin marketplace [add|remove|update|list] <参数>".into(),
Msg::PluginInstallUsage =>
"用法:/plugin install <插件名> 或 <插件>@<市场>".into(),
Msg::PluginInstallNotFound { plugin } =>
format!("未在任何市场中找到插件 `{plugin}`。使用 /plugin marketplace list 查看已注册的市场。").into(),
Msg::PluginInstallAmbiguous { plugin } =>
format!("插件 `{plugin}` 存在于多个市场中,请指定:").into(),
Msg::PluginUninstallUsage =>
"用法:/plugin uninstall <插件名> 或 <插件>@<市场>".into(),
Msg::PluginUninstallNotFound { plugin } =>
format!("插件 `{plugin}` 未安装。使用 /plugin list 查看已安装插件。").into(),
Msg::PluginUninstallAmbiguous { plugin } =>
format!("插件 `{plugin}` 从多个市场安装,请指定卸载哪一个:\n").into(),
Msg::PluginNoMarketplaces =>
"未注册任何市场".into(),
Msg::PluginMarketplacesHeader =>
"已注册的市场:".into(),
Msg::PluginNoInstalled =>
"未安装任何插件".into(),
Msg::PluginInstalledHeader =>
"已安装的插件:".into(),
Msg::PluginMarketplaceCloning { url } =>
format!("正在从 {url} 克隆 marketplace…").into(),
Msg::PluginMarketplaceRemoved { name } =>
format!("已移除 marketplace `{name}`").into(),
Msg::PluginMarketplaceRemoveFailed { error } =>
format!("移除 marketplace 失败:{error}").into(),
Msg::PluginMarketplaceUpdating { name } =>
format!("正在更新 marketplace `{name}`…").into(),
Msg::PluginMarketplaceListFailed { error } =>
format!("列出 marketplace 失败:{error}").into(),
Msg::PluginInstalling { plugin, marketplace } =>
format!("正在安装 `{plugin}@{marketplace}`…").into(),
Msg::PluginInstallingByName { plugin } =>
format!("正在安装 `{plugin}`…").into(),
Msg::PluginAlreadyInstalled { id } =>
format!(" 插件 `{id}` 已安装。\n PS: 如需重新安装,请先执行 `/plugin uninstall {id}`,然后再执行 `/plugin install {id}`\n").into(),
Msg::PluginMgrBrowse => "浏览并安装".into(),
Msg::PluginMgrAdd => "添加市场…".into(),
Msg::PluginMgrRemove => "移除市场…".into(),
Msg::PluginMgrInstalled { count } => format!("已安装 ({count})").into(),
Msg::PluginMgrInstalledMark => "✓ 已安装".into(),
Msg::PluginMgrHintNav => "↑/↓ 选择 · ⏎ 进入 · esc 返回".into(),
Msg::PluginMgrHintToggle => "⏎ 安装/卸载 · esc 返回".into(),
Msg::PluginMgrHintRemove => "⏎ 移除 · esc 返回".into(),
Msg::PluginMgrHintUninstall => "⏎ 卸载 · esc 返回".into(),
Msg::PluginMgrHintUrl => "输入/粘贴 git URL · ⏎ 添加 · esc 取消".into(),
Msg::PluginMgrHintPending => "安装中,请稍候… · esc 返回".into(),
Msg::PluginMgrInstallingLabel => "安装中…".into(),
Msg::PluginMgrEmptyMarketplaces => "暂无市场,请选「添加市场…」".into(),
Msg::PluginMgrEmptyPlugins => "该市场暂无插件。".into(),
Msg::PluginMgrEmptyInstalled => "暂无已安装插件。".into(),
Msg::PluginMgrCloning => "正在克隆市场…".into(),
Msg::PluginMgrInstalling { plugin } => format!("正在安装 {plugin}…").into(),
Msg::PluginMgrEscToCancel => "Esc 取消".into(),
Msg::PluginScopeUser => "为你安装(用户级)".into(),
Msg::PluginScopeUserDesc => "~/.atomcode/plugins — 所有项目可见".into(),
Msg::PluginScopeProject => "为所有协作者安装(项目级)".into(),
Msg::PluginScopeProjectDesc => ".atomcode/plugins — 通过 git 共享".into(),
Msg::PluginScopeLocal => "仅在本仓库为你安装(本地级)".into(),
Msg::PluginScopeLocalDesc => ".atomcode/plugins/local — 不提交到 git".into(),
Msg::PluginScopeHint => "↑↓ 选择范围 · Enter 确认 · Esc 返回".into(),
Msg::PluginUninstalled { plugin, marketplace } =>
format!("已卸载 `{plugin}@{marketplace}`").into(),
Msg::PluginUninstallFailed { error } =>
format!("卸载失败:{error}").into(),
Msg::PluginListFailed { error } =>
format!("列出插件失败:{error}").into(),
Msg::PluginReloadDone { skills, warnings } =>
format!("插件已重新加载:{skills} 个 skill,{warnings} 个警告").into(),
Msg::PluginGitNotFound =>
"💡 当前环境未安装 git 或 git 不在 PATH 中,插件市场自动安装和自动更新已禁用。请安装 git(macOS 可执行 `xcode-select --install`,Ubuntu 可执行 `sudo apt install git`)后重启 AtomCode。".into(),
Msg::PluginMarketplaceAdded { name, commit, count } =>
format!("✓ 已添加 marketplace `{name}`(commit {commit},共 {count} 个插件)").into(),
Msg::PluginMarketplaceUpdated { name, commit } =>
format!("✓ marketplace `{name}` 已更新至 {commit}").into(),
Msg::PluginInstallDone { plugin, marketplace, loaded, skipped, show_details_hint } => {
let hint = if show_details_hint { " (按 Ctrl+O 查看详情)" } else { "" };
format!("✓ 已安装 `{plugin}@{marketplace}` —— 加载 {loaded} 个 skill,跳过 {skipped} 个{hint}").into()
}
Msg::SetupAutoReloaded { skills, warnings } =>
format!("✓ Setup 完成,已自动刷新:{skills} 个 skill,{warnings} 个警告").into(),
Msg::CmdDescWebui => "启动浏览器 webui(子命令:stop / lan / --host <地址>)".into(),
Msg::CmdDescSetup =>
"扫描项目、安装种子文件并运行 setup skill [hooks|mcp|skills|all]".into(),
Msg::CmdDescResume => "恢复上次会话".into(),
Msg::CmdDescRename => "重命名当前会话".into(),
Msg::CmdDescLogin => "使用 AtomGit OAuth 登录并领取 CodingPlan 模型".into(),
Msg::CmdDescLogout => "退出 AtomGit 登录".into(),
Msg::CmdDescWhoami => "显示当前登录用户".into(),
Msg::CmdDescModel => "切换 Provider / 模型".into(),
Msg::CmdDescProvider => "管理 Provider(添加 / 编辑 / 删除)".into(),
Msg::CmdDescStatus => "显示会话状态".into(),
Msg::CmdDescConfig => "显示配置文件路径".into(),
Msg::CmdDescReload => "从磁盘重新加载 $ATOMCODE_HOME/config.toml".into(),
Msg::CmdDescCd => "切换工作目录".into(),
Msg::CmdDescInit => "从工作目录生成 .atomcode.md 项目指令".into(),
Msg::CmdDescBg => "后台会话:/bg、/bg list、/bg <N>、/bg drop <N>".into(),
Msg::CmdDescBackground => "在隔离的后台上下文中运行一次性任务(只读工具子集)".into(),
Msg::CmdDescDiff => "显示 git diff".into(),
Msg::CmdDescClear => "清屏".into(),
Msg::CmdDescSession => "开始新会话(清除对话)".into(),
Msg::CmdDescCost => "显示 Token 费用".into(),
Msg::CmdDescContext => "显示上下文预算明细".into(),
Msg::CmdDescCompact => "压缩对话历史".into(),
Msg::CmdDescRemember => "保存记忆(/remember --global 为全局)".into(),
Msg::CmdDescForget => "删除匹配的记忆".into(),
Msg::CmdDescMemory => "显示所有已保存的记忆".into(),
Msg::CmdDescMcp => "显示 MCP 服务器状态(子命令:reload)".into(),
Msg::CmdDescUndo => "撤销:把对话记忆回退一轮(/undo 或 /undo N)".into(),
Msg::CmdDescWorktree => "Git 工作树隔离(create/list/done/cleanup)".into(),
Msg::CmdDescUpgrade => "升级到最新版本(子命令:rollback)".into(),
Msg::CmdDescIssue => "为 AtomCode 报告 Bug / 提出功能建议(交互式向导)".into(),
Msg::CmdDescPlan => "切换到 Plan 模式(只读探索)".into(),
Msg::CmdDescBuild => "切换到 Build 模式(完整执行)".into(),
Msg::CmdDescThink => "深度思考控制(on/off/budget N)".into(),
Msg::CmdDescHelp => "显示帮助".into(),
Msg::CmdDescKeys => "显示键盘快捷键".into(),
Msg::CmdDescLanguage => "切换显示语言".into(),
Msg::CmdDescQuit => "退出 AtomCode".into(),
Msg::CmdDescSkills => "浏览已加载的技能".into(),
Msg::CmdDescPlugin => "插件市场(子命令:marketplace, install, uninstall, reload, list)".into(),
Msg::CmdDescPaste => "从剪贴板粘贴图片(Windows 下 Ctrl+V 被终端拦截时的备用入口)".into(),
Msg::CmdDescGuide => "向 atomcode-guide 提问使用方法".into(),
Msg::GuideMenuHeader => "📖 AtomCode 使用指南 — 输入 /guide <问题> 提问".into(),
Msg::GuideMenuTopics => "常用话题:".into(),
Msg::GuideMenuGettingStarted => "怎么开始使用 首次安装、登录、配置".into(),
Msg::GuideMenuSwitchModel => "怎么切换模型 /model /provider 操作".into(),
Msg::GuideMenuMcp => "怎么用 MCP MCP 服务器配置与管理".into(),
Msg::GuideMenuSkills => "怎么用技能和插件 /skills /plugin 使用".into(),
Msg::GuideMenuMemory => "怎么用记忆功能 /remember /forget /memory".into(),
Msg::GuideMenuBackground => "怎么用后台任务 /bg 后台执行".into(),
Msg::GuideMenuContext => "怎么管理上下文 /compact /context /cost".into(),
Msg::GuideMenuKeybindings => "快捷键有哪些 键盘快捷键参考".into(),
Msg::GuideMenuConfig => "怎么配置 config.toml 配置说明".into(),
Msg::GuideMenuTip => "
提示:输入 /guide <你的问题> 获取具体回答。
例如:/guide 怎么切换模型
".into(),
Msg::GuideMenuDocUrl => " 完整文档:https://atomcode.atomgit.com/docs/zh/".into(),
Msg::CmdGuideInstalling => "正在安装 ask skill,请稍候...".into(),
Msg::CmdGuideAutoInstall => "ask skill 未安装,正在自动安装 atomcode@atomcode-skills...".into(),
Msg::CmdGuideAutoInvoke { topic } =>
format!("ask skill 安装完成,正在回答: {}", topic).into(),
Msg::CmdGuideSkillNotFound =>
"安装完成但未找到 ask skill,请运行 /plugin reload 后重试".into(),
Msg::CmdGuideInstallFailed { error } =>
format!("安装 ask skill 失败: {}. 请手动运行 /plugin install atomcode@atomcode-skills", error).into(),
Msg::CmdPasteNoImage => "剪贴板中没有图片。".into(),
Msg::ConfigSaveFailed { error } =>
format!("配置保存失败:{}", error).into(),
Msg::OnboardingStepHeaderWelcome => "第 1/3 步 · 欢迎".into(),
Msg::OnboardingStepHeaderLanguage => "第 2/3 步 · 语言".into(),
Msg::OnboardingStepHeaderSetup => "第 3/3 步 · 配置".into(),
Msg::OnboardingPanelTitle => "AtomCode".into(),
Msg::OnboardingIntroVersionLine { v } =>
format!("版本 {v} · 在终端里运行的 AI 编程代理").into(),
Msg::OnboardingIntroBullet1 =>
"• 多步骤 agent loop · 内置代码图工具".into(),
Msg::OnboardingIntroBullet2 =>
"• 兼容所有 OpenAI 风格 API".into(),
Msg::OnboardingIntroBullet3 =>
"• 通过 CodingPlan 获取免费额度".into(),
Msg::OnboardingIntroPressEnter => "按 Enter 继续。".into(),
Msg::OnboardingIntroCtrlC => "Ctrl+C 可随时退出。".into(),
Msg::OnboardingIntroCompactTagline =>
"在终端里运行的 AI 编程代理。".into(),
Msg::OnboardingLanguageTitleBilingual =>
"Choose your language / 选择语言".into(),
Msg::OnboardingLanguagePrompt =>
"选择界面语言。任何时候都可以用 `/language` 修改。".into(),
Msg::OnboardingLanguageOptionAuto =>
"自动检测 (LC_ALL / LANG)".into(),
Msg::OnboardingLanguageOptionEn => "English".into(),
Msg::OnboardingLanguageOptionZhCn => "简体中文 (Simplified Chinese)".into(),
Msg::OnboardingSetupTitle => "想怎么开始?".into(),
Msg::OnboardingNavHint =>
"1-3 选择 · Enter 确认 · ← 返回 · Esc 跳过".into(),
Msg::OnboardingConfirmClear =>
"/welcome 会清屏。是否继续?[y/N]".into(),
Msg::CmdWelcomeDescription => "重新运行 onboarding 向导".into(),
Msg::VisionPreprocessSuccess { char_count } =>
format!("✓ VL 识别图片成功,返回 {char_count} chars").into(),
Msg::TurnSummary { done, turn_count, tool_call_count, duration, total_tokens } =>
format!("✓ {done} · {turn_count} 轮 · {tool_call_count} 工具 · {duration} · {total_tokens} tokens").into(),
Msg::TurnSummaryError { turn_count, tool_call_count, duration, total_tokens } =>
format!("✗ 已中断 · {turn_count} 轮 · {tool_call_count} 工具 · {duration} · {total_tokens} tokens").into(),
Msg::LoginQrHeader =>
" 登录 AtomGit — 使用微信扫描下方二维码:\n\n".into(),
Msg::LoginUrlAfterQr =>
"\n\n 或在浏览器打开下方链接:\n ".into(),
Msg::LoginNoQrNoUrl =>
" 当前终端无法渲染二维码,\n \
且该平台不支持基于 URL 的登录。\n \
请改用支持 Unicode 的终端以显示二维码。".into(),
Msg::LoginUrlOnly =>
" 在浏览器中打开此链接以登录 AtomGit:\n ".into(),
Msg::LoginCancelHint => "\n\n 按 ESC 取消\n".into(),
Msg::CtxUsageHeader => "上下文用量".into(),
Msg::CtxUsageNoTurns => "(请至少完成一轮对话 — 统计在每轮结束时记录)".into(),
Msg::CtxUsageWaiting => "(等待首轮完成 — 当前仅为部分统计)".into(),
Msg::CtxProvider => "Provider".into(),
Msg::CtxCtxName => "ctx".into(),
Msg::CtxLabelSystemPrompt => "系统提示".into(),
Msg::CtxLabelToolDefs => "工具定义".into(),
Msg::CtxLabelColdZone => "冷区".into(),
Msg::CtxLabelMessages => "消息".into(),
Msg::CtxLabelFree => "空闲".into(),
Msg::CtxMessagesInWindow { n } => format!("窗口内消息数:{n}").into(),
Msg::CtxSystemPromptHeader => "=== 系统提示 ===".into(),
Msg::CtxSystemPromptEmpty => "(为空 — 完成一轮对话后捕获)".into(),
Msg::CtxTokensSuffix => "tokens".into(),
Msg::CompactNothingShort => "(无需压缩 — 当前对话较短)\n".into(),
Msg::CompactStarting => "(正在使用 LLM 摘要进行压缩...)\n".into(),
Msg::CompactNothingNoSavings { before, after } =>
format!("(无需压缩 — 压缩后不会节省 token:{} → {})\n", before, after).into(),
Msg::CompactDropped { messages, before, after } =>
format!("(已压缩 — 丢弃 {} 条消息,{} → {} tokens)\n", messages, before, after).into(),
Msg::ModelNoImageSupport { model } => format!(
"当前模型 \"{}\" 不支持图片输入,且未配置 vision_preprocessor_provider。\
请用 /model 切换到支持视觉的模型,或在配置中设置 vision_preprocessor_provider。",
model
)
.into(),
Msg::BypassWarningBanner =>
"\u{26a0} --dangerously-skip-permissions 已启用:所有工具调用将自动批准(无权限提示)\n".into(),
Msg::BypassWarningHeadless =>
"[headless] --dangerously-skip-permissions:所有工具调用将自动批准".into(),
Msg::BypassBadge =>
"\u{26a0} BYPASS".into(),
Msg::CtrlCAgainToExit => " (再次按 Ctrl+C 退出)\n".into(),
Msg::HintMultiLineInput =>
" \u{24d8} 多行输入:在行尾加 `\\` 再按 Enter。\n \
所有终端均可用。(Shift / Alt / Ctrl + Enter 在部分终端也支持,\n \
取决于该终端的键盘协议 — 可以试试看。)\n\n"
.into(),
Msg::BgHelp =>
" /bg 将当前会话放到后台,打开新的前台会话\n /bg list 列出后台会话\n /bg <N> 恢复第 N 号后台会话\n /bg drop <N> 丢弃第 N 号后台会话\n /bg help 显示此帮助\n".into(),
Msg::BgListEmpty => " 没有后台会话。\n".into(),
Msg::BgListHeader => " # ID 状态 创建时间 摘要\n".into(),
Msg::BgListRow { slot, short_id, state, age, summary } =>
format!(" {:<3} {:<8} {:<9} {:<8} {}\n", slot, short_id, state, age, summary).into(),
Msg::BgStateRunning => "运行中".into(),
Msg::BgStateIdle => "空闲".into(),
Msg::BgStateDone => "已完成".into(),
Msg::BgStateCancelled => "已取消".into(),
Msg::BgStateError => "错误".into(),
Msg::BgAgeNow => "刚刚".into(),
Msg::BgAgeMinutes { n } => format!("{n} 分钟").into(),
Msg::BgAgeHours { n } => format!("{n} 小时").into(),
Msg::BgAgeDays { n } => format!("{n} 天").into(),
Msg::BgSlotLimitReached { max } =>
format!("后台槽位已达上限({max})").into(),
Msg::BgBackgroundCurrent { new_id, slot, old_id, state } =>
format!(" 新前台会话 [{new_id}]\n 后台:[#{slot}] {old_id}(状态:{state})\n").into(),
Msg::BgInvalidSlot { slot, available } =>
format!("无效的后台槽位 {slot}(可用:{available})").into(),
Msg::BgNoRuntimeClient => "后台槽位没有运行时客户端".into(),
Msg::BgResumed { slot, short_id } =>
format!(" 已恢复后台 [#{slot}] {short_id}\n").into(),
Msg::BgPreviousForegroundMoved { slot } =>
format!(" 原前台会话已移至 [#{slot}]\n").into(),
Msg::BgDropped { slot, short_id } =>
format!(" 已丢弃后台 [#{slot}] {short_id}\n").into(),
Msg::BgTaskStarted { slot, short_id } =>
format!(" 后台:[#{slot}] {short_id}(状态:运行中)\n").into(),
Msg::BgTaskTimedOut { secs } =>
format!("后台任务超时({secs} 秒)。").into(),
Msg::BgTaskError { error } =>
format!("错误:{error}").into(),
Msg::BgTaskCancelled => "已取消。".into(),
Msg::BgTaskNoSummary => "任务完成(无摘要文本)。".into(),
}
}
#[cfg(test)]
mod codingplan_crypto_tests {
use super::*;
use crate::i18n::Msg;
#[test]
fn zh_official_build_required_mentions_official_and_releases() {
let s = zh_cn(Msg::CpOfficialBuildRequired);
assert!(s.contains("官方"));
assert!(s.contains("releases") || s.contains("发布"));
}
#[test]
fn zh_stale_clock_mentions_time() {
let s = zh_cn(Msg::CpSignStaleClockSkew);
assert!(s.contains("时间") || s.contains("时钟"));
}
#[test]
fn zh_replay_persisted_is_non_empty() {
let s = zh_cn(Msg::CpSignReplayPersisted);
assert!(!s.is_empty());
}
#[test]
fn zh_version_too_old_mentions_upgrade() {
let s = zh_cn(Msg::CpSignVersionTooOld);
assert!(s.contains("升级") || s.contains("更新"));
}
#[test]
fn zh_upgrade_required_is_non_empty() {
let s = zh_cn(Msg::CpUpgradeRequired);
assert!(!s.is_empty());
}
}