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(),

        // ── /login(完整配置流程) ──
        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 } =>
            // SGR 31 / 39 = 标准红前景 + 默认色重置。用标准色(不
            // 是亮色)让终端按当前主题映射 —— Solarized / Dracula /
            // 浅色模式都会落到各自的「红」上,不会被一个写死的 RGB
            // 锁住。retained 渲染器走严格 sanitizer 会把 SGR 剥光,
            // 但 `× … (需要升级成 Pro 以上套餐)` 文本本身仍能传达含义。
            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(),

        // ── /status 命令主体 ──
        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(),

        // ── Provider 向导 ──
        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(),

        // ── Model 选择器 ──
        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(),

        // ── Issue 向导 ──
        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(),

        // ── /config ──
        Msg::ConfigProviderLabel { provider, path } =>
            format!("  Provider:{}\n  配置文件:{}\n\n", provider, path).into(),

        // ── /cost ──
        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(),

        // ── /think ──
        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(),

        // ── /remember, /forget ──
        Msg::RememberUsage =>
            "用法:/remember <要记住的内容>(--global 为全局范围)".into(),
        Msg::ForgetUsage =>
            "用法:/forget <关键词>".into(),

        // ── /background ──
        Msg::BackgroundUsage =>
            "  用法:/background <任务描述>\n".into(),

        // ── /init ──
        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(),

        // ── /cd ──
        Msg::CdWorkingDir { cwd } =>
            format!("  工作目录:{}\n  无最近项目。使用 `/cd <路径>` 切换。\n", cwd).into(),

        // ── /diff ──
        Msg::DiffFailed { error } =>
            format!("git diff 失败:{}", error).into(),

        // ── /upgrade ──
        Msg::UpgradePackageManaged =>
            "本版本由 HarmonyBrew 管理,请运行 `brew upgrade atomcode` 升级".into(),
        Msg::UpgradeUnknownArg { arg } =>
            format!("未知的 /upgrade 参数:{}\n  用法:/upgrade [rollback|--force]", arg).into(),

        // ── /skills ──
        Msg::SkillsNone =>
            "  没有可调用的技能。\n".into(),
        Msg::SkillsAvailable =>
            "  可用技能:\n".into(),
        Msg::SkillUnknown { name } =>
            format!("未知技能:{}(输入 /skills 查看列表)", name).into(),

        // ── /mcp ──
        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(),
        // /mcp login / logout
        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(),
        // MCP / LSP 服务连接反馈
        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(),

        // ── /worktree ──
        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(),

        // ── /help commands(自定义命令) ──
        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(),

        // ── /setup ──
        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(),

        // ── /plugin ──
        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(),

        // ── OnboardingWizard ──
        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(),
        // ── --dangerously-skip-permissions / -y ──
        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(),

        // ── /bg(后台会话)──
        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());
    }
}