{
  "source": {
    "fromChat": "来自 {{name}}（{{chat}}）：",
    "from": "来自 {{name}}：",
    "member": "成员 {{code}}",
    "delayedDelivery": "（这条消息于 {{time}} 收到，因派发失败延后送达）"
  },
  "settings": {
    "title": "聊天",
    "description": "把聊天机器人接到 Ycodium。一行一个机器人：先在对应平台建好机器人、把凭据填进来，再选一个访问模式，决定私聊和群里谁能用；用到名单时，把人填进「允许的人」。飞书可以用「连接飞书机器人」，扫一次码全部配好。获准的人私聊机器人（或把它拉进群）、在聊天里选好项目，就能派活。",
    "bots": "机器人",
    "language": {
      "label": "回话语言",
      "description": "机器人在聊天里自己说的话用什么语言：帮助、状态、确认和各种提示。中文快捷命令只在选中文时认。改了之后从机器人的下一句话起生效。",
      "zhCN": "中文",
      "en": "English"
    },
    "defaultModel": {
      "follow": "跟随聊天 / 项目默认",
      "unavailable": "{{value}}（不可用）"
    },
    "defaultPreset": {
      "none": "无预设",
      "unavailable": "{{value}}（不可用）"
    },
    "runtimeMode": {
      "approvalRequired": "命令和改文件前先问",
      "autoAcceptEdits": "自动接受改动，其他操作先问",
      "auto": "常规操作自动批准",
      "fullAccess": "命令和改动都不问"
    },
    "groupMention": {
      "always": "被 @ 才理",
      "never": "每句都理",
      "ambient": "每句都理，明显对别人说的除外"
    },
    "deliveryHttp": {
      "enabled": {
        "label": "开启主动投递 HTTP",
        "description": "默认关闭。开启后只在本机 127.0.0.1 监听，供脚本用 botId+targetId 推文字。不要暴露到公网；需要时可再配 Bearer token。"
      },
      "port": {
        "label": "投递 HTTP 端口",
        "description": "只听 127.0.0.1。默认 3847。"
      },
      "token": {
        "label": "投递 HTTP Token",
        "description": "可选。填了则请求必须带 Authorization: Bearer <token>。同机其它进程也能打 loopback，建议生产开启。"
      }
    },
    "deliveryTargets": {
      "label": "投递目标",
      "description": "调用方只保存 botId（机器人行 id）与 targetId。平台原生聊天 id 写在这里，不要随每次请求提交。"
    },
    "deliveryKind": {
      "chat": "聊天",
      "user": "用户／私聊",
      "group": "群"
    },
    "queueMode": {
      "queue": "排队（默认）",
      "steer": "插话（自动并入当前轮）"
    },
    "onOff": {
      "on": "开",
      "off": "关"
    },
    "larkPanelMode": {
      "default": "默认（全部命令）",
      "minimal": "精简"
    },
    "accessMode": {
      "allowlist": "仅白名单（默认）",
      "open": "允许所有人",
      "privateOpen": "私聊放开，群里限名单",
      "groupOpen": "私聊限名单，群里放开"
    }
  },
  "platform": {
    "lark": "飞书",
    "telegram": "Telegram",
    "wecom": "企业微信",
    "wecom-app": "企业微信应用",
    "wechat": "微信（实验）"
  },
  "column": {
    "displayName": {
      "label": "名称",
      "placeholder": "团队机器人"
    },
    "platform": {
      "label": "平台"
    },
    "larkAppId": {
      "label": "飞书应用 ID",
      "placeholder": "cli_…"
    },
    "larkAppSecret": {
      "label": "飞书应用密钥"
    },
    "telegramToken": {
      "label": "Telegram 机器人令牌"
    },
    "wecomBotId": {
      "label": "企业微信机器人 ID"
    },
    "wecomBotSecret": {
      "label": "企业微信机器人密钥"
    },
    "allowedSenders": {
      "label": "允许的人",
      "description": "该平台的用户 id，逗号分隔。在访问模式要求名单的聊天里生效；留空则谁都不能在这些聊天里使用机器人。查 id：用还不在名单上的账号，在要求名单的聊天里给机器人发一句话（群里要 @ 它），它会回复这个 id；同一账号 10 分钟内只回一次。"
    },
    "proxy": {
      "label": "代理",
      "description": "有些平台只能经本机上的某个代理才连得上，而且每个机器人可以不一样。"
    },
    "defaultModel": {
      "label": "默认模型",
      "description": "聊天未用 /model 选模型时，新会话使用此默认模型。已有会话保留原模型；发送 /new 后使用新默认。不可用时回退到项目默认。"
    },
    "defaultPreset": {
      "label": "默认预设",
      "description": "聊天未用 /preset 选预设时，新会话使用此预设。已有会话保留原预设；发送 /new 后使用新默认。不可用的预设会跳过。"
    },
    "runtimeMode": {
      "label": "聊天消息能做什么",
      "description": "获准的人都能从聊天里开一轮，所以默认故意不给满权限。不论选哪一档，要拍板的事都会摆到聊天里。"
    },
    "groupMention": {
      "label": "群里什么时候理它",
      "description": "机器人在群里什么时候回应（不选就是被 @ 才理）；单聊永远理。企业微信只把 @ 到机器人的群消息推过来，这一项对它没有效果。"
    },
    "deliveryBotId": {
      "label": "机器人",
      "description": "发消息的那个机器人。调用方把括号里的 id 当作 botId 传。",
      "placeholder": "机器人行 id"
    },
    "deliveryTargetId": {
      "label": "Target ID",
      "description": "同一机器人下唯一的别名；保存后勿改。",
      "placeholder": "release-alerts"
    },
    "deliveryName": {
      "label": "显示名",
      "placeholder": "发布告警群"
    },
    "deliveryKind": {
      "label": "类型"
    },
    "deliveryPlatformChatId": {
      "label": "平台聊天 ID",
      "description": "飞书 open_id／chat_id、Telegram chat id（论坛话题填 群号:话题号）、企微用户／群 id 等。",
      "placeholder": "oc_… / ou_… / -100…"
    },
    "queueMode": {
      "label": "忙时新消息",
      "description": "当前任务还在跑时，新来的普通文字怎么处理。排队会等当前轮结束（可点插话）；插话则自动并入当前轮，无需每次点按钮。"
    },
    "approvalTimeoutMinutes": {
      "label": "审批超时（分钟）",
      "description": "这么多分钟没人处理的审批会被自动拒绝。默认 60 分钟；请输入 0–1440 的整数，0 表示不自动拒绝；填写无效时按 60 分钟算。"
    },
    "larkPanelMode": {
      "label": "指令面板",
      "description": "聊天里 /panel 或打 / 时列出的命令范围。精简隐藏低频系统项；手动输入同一命令仍可用。"
    },
    "larkTopicOnMention": {
      "label": "被 @ 时开话题",
      "description": "有人 @ 机器人提问时，答复在那条消息下开一个飞书话题，一问一答收在话题里。已经在话题里的消息，不管开不开，答复都留在该话题里。"
    },
    "wecomNumberedHints": {
      "label": "编号应答提示",
      "description": "企微没有按钮，审批与提问靠回编号。开启时附带更完整的用法说明。"
    },
    "wecomAppStream": {
      "label": "流式回复",
      "description": "默认关闭：先回一句确认，处理完再发送完整回复。开启后，企微能边写边出时逐步显示回复；不能时，完成后自动以文本发送完整回复。开启属于试用：企业微信客户端是否显示边写边出尚未验证。"
    },
    "wecomAppCorpId": {
      "label": "企业 ID（CorpID）",
      "placeholder": "ww…"
    },
    "wecomAppAgentId": {
      "label": "应用 AgentId",
      "placeholder": "1000002"
    },
    "wecomAppSecret": {
      "label": "应用 Secret"
    },
    "wecomAppToken": {
      "label": "回调 Token"
    },
    "wecomAppEncodingAESKey": {
      "label": "EncodingAESKey",
      "placeholder": "43 位字母或数字"
    },
    "wecomAppCallbackBaseUrl": {
      "label": "公网回调基址（可选）",
      "description": "转发到本机回调端口的公网地址。填了下面就给出完整回调地址，贴进企业微信「接收消息 → 设置 API 接收」；不填只给路径。",
      "placeholder": "https://im.example.com 或 http://IP:30987"
    },
    "wecomAppApiBaseUrl": {
      "label": "API 代理地址（可选）",
      "description": "企业微信接口的基址（换 token、发消息、收发图片和文件）。留空就直连 qyapi.weixin.qq.com。出站 IP 要在这个应用的企业可信 IP 里。",
      "placeholder": "https://qyapi.weixin.qq.com"
    },
    "wecomAppListenPort": {
      "label": "本机回调端口（可选）",
      "description": "默认 30987。监听地址相同的自建应用共用一个端口；监听地址不同的两行（比如 0.0.0.0 和 127.0.0.1）要用不同端口，否则后一个监听不起来。",
      "placeholder": "30987"
    },
    "wecomAppListenHost": {
      "label": "本机监听地址（可选）",
      "description": "默认 127.0.0.1：只有本机连得上回调端口，需要在前面放反代或隧道。填 0.0.0.0 会在所有网卡上监听，等于把回调端口对外开放，要自己用防火墙控好。",
      "placeholder": "127.0.0.1"
    },
    "wechatBotToken": {
      "label": "微信机器人令牌",
      "description": "扫码绑定后得到的 bot_token。真登录尚未开放：填了也不会连上 iLink，见提案 0069 安全评审。"
    },
    "accessMode": {
      "label": "访问模式",
      "description": "仅白名单＝只有「允许的人」能触发；允许所有人＝平台能识别的发送者均可。新机器人默认仅白名单。「私聊放开，群里限名单」与「私聊限名单，群里放开」共用同一份「允许的人」；这两种模式下，无法确认是私聊还是群时，只有「允许的人」能用机器人。"
    }
  },
  "reply": {
    "deliveryFailed": "回复未能送达。请检查这个机器人的连接与权限，然后重试。",
    "connectionTest": "✅ Ycodium 连接测试\n这条测试消息由「{{name}}」机器人通过设置页的「检查连接」发出，无需回复。",
    "wecomDeliveryFailed": "这条回复没送到企业微信里的 {{recipient}}：对方不在这个应用的可见范围。到企业微信管理后台把他们加进应用的可见范围，再让 agent 重发一次。",
    "conclusionRecovered": "（重启期间完成，现在补发）",
    "notAllowed": "你不在这个机器人的允许名单里，这次点击没有生效。",
    "noDefaultModel": "项目「{{title}}」还没选 agent，开不了会话。发 /model 选一个，或者到项目设置里设个默认，再发一次消息。",
    "projectArchived": "项目「{{title}}」已归档。恢复它，或发 /repo 换个项目，再发消息。",
    "projectMissing": "这个聊天原来做的项目已经不在这台机器上了（可能被删了），开不了会话。发 /repo 重新选一个。",
    "threadGone": "之前那条会话用不了了，这个聊天改为开一条新会话。",
    "threadArchived": "这个聊天的会话「{{title}}」已归档，归档期间发来的消息不会交给 agent，取消归档后也不会补交。发 /new 开一条新会话，或在网页或其他客户端里取消归档后再发。",
    "threadStillArchived": "会话仍是归档状态，这句也没有交给 agent。",
    "dispatchFailed": "这条消息没能派出去，请稍后重发。",
    "turnFailedToStart": "{{message}}参考号 {{ref}}。",
    "turnFailedToStartQuoted": "这条消息（开头是「{{excerpt}}」）没能派出去，请稍后重发。参考号 {{ref}}。",
    "turnFailedToStartAttachment": "这条消息（带附件「{{excerpt}}」）没能派出去，请稍后重发。参考号 {{ref}}。",
    "turnRetrying": "这条消息暂时没能派出去，会在后台自动重试，不用再发一次；还是不行会再告诉你。参考号 {{ref}}。",
    "turnFailed": "这一轮没能完成：{{detail}}\n参考号 {{ref}}。可以直接再发一次；一直不行就发 /new 开个新会话。",
    "turnFailedNoDetail": "这一轮没能完成。参考号 {{ref}}。可以直接再发一次；一直不行就发 /new 开个新会话。",
    "turnFailedBrief": "这一轮没能完成：{{detail}}\n可以直接再发一次；一直不行就发 /new 开个新会话。",
    "turnFailedBriefNoDetail": "这一轮没能完成。可以直接再发一次；一直不行就发 /new 开个新会话。",
    "turnFailedWithReference": "{{message}}\n参考号 {{ref}}。",
    "turnFailedQuota": "模型额度或余额不足，这一轮没能完成。可以发 /model 换个模型再试，或请管理员补充额度后重试。",
    "turnFailedRateLimit": "模型服务正在限流，这一轮没能完成。请稍后重试。",
    "turnFailedContextLimit": "当前会话内容超过模型上下文上限，这一轮没能完成。请发 /new 开个新会话，再把请求重新发一遍。",
    "turnFailedAuth": "模型凭据缺失或无效，这一轮没能完成。请管理员检查模型配置，之后你再发一次。",
    "turnFailedModelUnavailable": "当前模型不存在或不支持所选配置，这一轮没能完成。请发 /model 查看可选模型，再发 /model 加编号（例如 /model 2）为这个聊天选一个，然后重发请求。",
    "turnFailedTransport": "暂时无法连接模型服务，这一轮没能完成。请稍后重试。",
    "attachmentReceived": "收到 {{names}}（现有 {{count}} 个待处理）。说一句想让我怎么处理。",
    "attachmentFailed": "没能收下 {{name}}：{{reason}}。",
    "attachmentReason": {
      "tooLarge": "超过了 {{limit}} 的上限",
      "downloadFailed": "下载失败了",
      "storeFailed": "保存不了",
      "empty": "文件是空的"
    },
    "attachmentLimit": "一条消息最多带 {{max}} 个附件，所以 {{name}} 没收。先发一句话处理手上这些。",
    "attachmentsNoTeam": "文件还发不到团队，这次没带上。发 /thread 回到普通会话。",
    "unsupportedType": "我还不能处理 {{type}} 类型的消息。",
    "unsupportedFolder": "文件夹没法下载，请打包成压缩文件再发。",
    "unsupportedVoice": "暂时不支持语音，请发文字。",
    "sendingFile": "正在发送 {{name}}：",
    "notAllowedYet": "你还不在允许名单里，你的用户 id 是 {{id}}，请把它填进 设置 → 插件 → 聊天 → 这个机器人的「允许的人」。",
    "received": "收到，在处理。",
    "inboundFailed": "这条消息处理时出了错，请稍后重发。",
    "inboundDeferred": "不用重发：机器下次启动时会自动处理这条消息。",
    "welcome": "已连上。直接发文字或图片就能开始，发 /help 看能用的命令。"
  },
  "approval": {
    "timedOut": "{{minutes}} 分钟时限内没人处理，已自动拒绝。",
    "timedOutReason": "{{minutes}} 分钟时限内没人处理。",
    "timedOutWithSubject": "审批「{{subject}}」：{{minutes}} 分钟时限内没人处理，已自动拒绝。",
    "allow": "允许",
    "deny": "拒绝",
    "alreadyHandled": "已处理",
    "replyHint": "回复编号，或回复「批准」/「拒绝」。",
    "replyHintFull": "回复编号即可。也可回复「批准」/「拒绝」；多选提问用逗号分隔编号。"
  },
  "question": {
    "title": "❓ 提问",
    "planTitle": "📝 计划确认",
    "planApprove": "批准计划",
    "planApproveHint": "让 agent 按这份计划开始实施。",
    "planRevise": "修改计划",
    "planReviseHint": "让 agent 先修改计划，再继续往下做。",
    "planStop": "到此为止",
    "planStopHint": "退出计划模式，不实施这份计划。",
    "freeformHint": "也可以直接回复一条消息，用自己的话作答。",
    "replyOne": "回复编号即可。",
    "replyMany": "回复编号，多个用逗号隔开。",
    "submit": "✅ 提交",
    "pickFirst": "先选一项再提交。",
    "answered": "回答：{{answer}}",
    "answerWithAttachments": "{{answer}}（带 {{count}} 个附件）",
    "attachmentsHeld": "这道题只能从选项里选，{{names}} 先留着，会跟你下一条消息一起发出。",
    "elsewhere": "已在别处回答（网页或其他客户端）。",
    "cancelled": "这道提问已结束，没有收到回答。",
    "alreadyHandled": "已处理",
    "sendFailed": "没能把你的回答交给 agent。这道提问可能已在别处回答，或已经结束。"
  },
  "queue": {
    "title": "⏳ 已排队",
    "waitRunning": "当前这一轮回复结束后自动发出。想现在就送进正在进行的这一轮，点「插话」。",
    "waitPaused": "发送已暂停（上一轮被停止或出错了）。点「恢复发送」继续。",
    "waitIdle": "马上发出。",
    "steer": "➡️ 插话",
    "withdraw": "↩️ 撤回",
    "resume": "▶️ 恢复发送",
    "steeringTitle": "⏳ 插话中…",
    "steering": "💬 正在送进当前这一轮…",
    "sendingTitle": "📤 发送中…",
    "sending": "正在发出。",
    "steeredTitle": "✅ 已插话",
    "steered": "已送进当前这一轮。",
    "sentTitle": "📤 已发送",
    "sent": "已作为单独的一轮发出。",
    "removedTitle": "🗑️ 已撤回",
    "removed": "已撤回，不会发出。",
    "steerFailed": "没能送进当前这一轮（这一轮可能刚结束或已经换了）。消息仍在排队，这一轮结束后发出。",
    "withdrawFailed": "没能撤回：这条消息已经开始发送了。",
    "resumeFailed": "没能恢复发送，稍后再试。",
    "alreadyHandled": "已处理",
    "plainNotice": "已排队：当前这一轮回复结束后发出。"
  },
  "command": {
    "teamSelected": "好，接下来每条消息都给这个项目的团队开一个目标。发 /thread 回到普通会话。",
    "threadSelected": "好，接下来开普通会话。",
    "newSession": "好，下一句话开一条新会话。",
    "stopNoSession": "这个聊天现在没有在跑的活儿。",
    "stopNoTurn": "现在没有在跑的一轮。",
    "continued": "已恢复，排着的消息开始发送。",
    "continueNothing": "没有可恢复的：这个聊天的发送没有被暂停。",
    "continueFailed": "没能恢复发送，稍后再试。",
    "stopped": "停了。会话还在，接着说就行。"
  },
  "status": {
    "routedTeam": "派给：这个项目的团队",
    "routedThread": "普通会话",
    "nothingRunning": "{{where}}。现在没有在跑的活儿。",
    "session": "会话：{{title}}",
    "running": "正在跑。想停就打 /stop。",
    "idle": "空闲着。",
    "model": "模型：{{model}}",
    "planOn": "计划模式：开",
    "project": "项目：{{title}}",
    "noProject": "还没选项目。发 /repo 选一个。"
  },
  "version": {
    "current": "Ycodium 聊天桥 v{{version}}",
    "usage": "用法：/version（不带参数）。"
  },
  "batch": {
    "usage": "用法：/{{command}}（不带参数）。",
    "noSubmission": "当前没有待提交的批次，请先发送 /batch。",
    "noBatch": "当前没有正在进行的批量输入。",
    "commandTextOnly": "批量输入命令只支持文字，去掉图片或文件后再发。",
    "started": "已进入批量输入模式，最多可发送 {{limit}} 条文字；收集期间不逐条回复，Ycodium 重启会清空已收集的内容。\n完成后发送 /send，取消请发送 /cancel。",
    "progress": "当前已处于批量输入模式，已收集 {{count}}/{{limit}} 条。\n完成后发送 /send，取消请发送 /cancel。",
    "progressFull": "当前已处于批量输入模式，已收集 {{count}}/{{limit}} 条，批次已满。\n请发送 /send 提交或 /cancel 取消。",
    "submittingSend": "当前批次正在提交，请勿重复发送 /send。",
    "submittingCancel": "批次已经提交，无法取消。\n如需停止当前任务，请发送 /stop。",
    "submittingBatch": "当前批次正在提交，请等待处理完成后再开启新批次。",
    "cancelledEmpty": "已取消批量输入。",
    "cancelled": "已取消批量输入，共丢弃 {{count}} 条消息。",
    "empty": "当前批次还没有内容，请先发送文字，或使用 /cancel 取消。",
    "introduction": "以下是用户通过批量输入模式发送的多条内容，请按顺序作为同一次输入统一处理。",
    "message": "[消息 {{index}}]",
    "textOnly": "批量输入模式目前只支持文字，不支持图片或文件，这条消息没有被收集。\n请继续发送文字，或使用 /send、/cancel。",
    "blockedCommand": "当前正在批量输入，这条命令没有被执行。\n请先发送 /send 提交，或 /cancel 取消（会丢弃已收集的消息），然后再发送刚才的命令。",
    "full": "当前批次已满，这条消息没有被收集。\n请先发送 /send 提交或 /cancel 取消，然后重新发送这条消息。",
    "reachedLimit": "已收集 {{count}}/{{limit}} 条，批次已满。\n请发送 /send 提交或 /cancel 取消。",
    "failed": "批次提交失败，已保留 {{count}} 条消息。\n请再次发送 /send 重试或 /cancel 取消。",
    "noProject": "先用 /repo 选好项目，再开始批量输入。",
    "projectArchived": "项目「{{title}}」已归档，这次没有提交，批次已保留。\n在网页或其他客户端里取消归档后，可以再发 /send。\n要换项目，先发 /cancel（会丢弃已收集的消息），用 /repo 选好项目后再重新 /batch。",
    "threadArchived": "这个聊天的会话「{{title}}」已归档，这次没有提交，批次已保留。\n在网页或其他客户端里取消归档后，可以再发 /send。\n要开新会话，先发 /cancel（会丢弃已收集的消息），再发 /new，然后重新 /batch。",
    "projectMissing": "这个聊天的项目已经不在这台机器上了，这次没有提交，批次已保留。\n要换项目，先发 /cancel（会丢弃已收集的消息），用 /repo 选好项目后再重新 /batch。",
    "teamTarget": "批量输入不支持团队会话。请先发 /thread 切回普通会话，再发 /batch。",
    "privateOnly": "批量输入模式只支持私聊，请在与机器人的私聊中使用。",
    "busy": "当前聊天有正在运行的任务、待回答问题或待审批请求。\n请先完成当前交互或发送 /stop，再使用 /batch。"
  },
  "steer": {
    "usage": "用法：/steer 补充指令。",
    "textOnly": "/steer 只支持文字，去掉图片或文件后再发。",
    "pending": "当前这一轮在等你的回答或审批，补充指令没发出。先处理完（或者发 /stop），然后再发一次 /steer。",
    "noTurn": "现在没有正在跑的这一轮，补充指令没发出。直接发消息就能开始新的一轮。",
    "sent": "补充指令已发出：这一轮还在跑就会在下一步读到，刚结束的话会作为下一条消息处理。"
  },
  "compact": {
    "usage": "用法：/compact（不带参数）。",
    "busy": "正在回复，等这一轮结束后再发一次 /compact。",
    "unsupported": "当前模型不支持压缩上下文，可先用 /model 换一个支持的模型。",
    "started": "已开始压缩上下文，完成后会在这里说一声，期间照常发消息就行。",
    "done": "上下文已压缩。",
    "failed": "压缩上下文失败，请稍后重试。",
    "stuck": "上一轮回复出错了，那一轮还没结束。先发 /stop 结束它，再发 /compact。",
    "noSession": "这个聊天还没有当前会话。发一句话开一个，或用 /sessions 和 /resume 切过去，之后再发 /compact。"
  },
  "archived": {
    "on": "已开启：会话列表会列出已归档的会话。列出来是为了找到它，看内容去网页，不能接着聊。",
    "off": "已关闭：会话列表只列出未归档的会话。",
    "usage": "用法：/archived on 或 /archived off。"
  },
  "help": {
    "permission": "· /permission —— 列出档位、新轮次的档位与机器人上限；/permission 编号或档位 ID 选择；/permission default（或「权限 默认」）回到机器人设置",
    "title": "能用的命令：",
    "continue": "· /continue —— /stop 或出错暂停了发送之后，用它恢复，排着的消息继续发出",
    "stop": "· /stop —— 停掉正在跑的这一轮，会话留着",
    "steer": "· /steer 补充指令 —— 插话：给正在跑的这一轮补一句",
    "batch": "· /batch —— 在私聊中收集最多 {{limit}} 条文字",
    "send": "· /send —— 将已收集的消息作为一次输入提交",
    "cancel": "· /cancel —— 取消批量输入并丢弃消息",
    "compact": "· /compact —— 压缩当前会话的上下文（不带参数）",
    "status": "· /status —— 现在在干什么",
    "version": "· /version —— 聊天桥的版本（不带参数）",
    "new": "· /new —— 忘掉当前会话，下一句开新的",
    "team": "· /team —— 每条消息都给这个项目的团队开一个目标；先用 /repo 选项目",
    "thread": "· /thread —— 切回普通会话",
    "aliases": "中文也行：停 / 继续发送 / 压缩 / 状态 / 新对话 / 会话列表 / 切换会话 / 会话历史 / 换模型 / 思考强度 / 权限 / 计划模式 / 换项目 / 建群 / 换团队 / 换对话。",
    "sessions": "· /sessions —— 列出本项目的会话；加 /repo 里的项目编号，列出本机器人在别的项目开过的",
    "archived": "· /archived on|off —— 让这个聊天的会话列表带上（on）或不带（off）已归档的会话；/archived 看当前开关",
    "resume": "· /resume 编号或 id 开头 —— 切会话；别的项目的会话会连同项目一起切",
    "history": "· /history [数量] —— 仅私聊：查看当前会话最近的消息（默认 {{defaultCount}} 条，最多 {{maxCount}} 条）",
    "model": "· /model —— 看这个聊天用的模型；/model 编号 或 /model 实例/模型 切换",
    "reasoning": "· /reasoning —— 看这个聊天当前模型的思考强度；/reasoning 取值 或 /reasoning 编号 切换；/reasoning default 恢复模型默认",
    "preset": "· /preset —— 看这个聊天新会话用的预设；/preset 编号 或 /preset 名字或 id 切换；/preset none 清掉聊天选择",
    "plan": "· /plan —— 开关计划模式（agent 先出计划、不动手）；/plan on、/plan off 明确设定",
    "panel": "发 /panel 打开可点的命令面板。",
    "repo": "· /repo —— 选这个聊天做哪个项目；/repo 编号 或 /repo 项目名 直接选",
    "group": "· /group 群名 —— 仅飞书：机器人建一个群并把你拉进去（别的平台的机器人建不了群）",
    "syncNote": "· 私聊附着会话后，网页上的用户文字与终态助手文字会同步到此（群聊不同步）。"
  },
  "reasoning": {
    "current": "当前思考强度：{{value}}",
    "currentUnlisted": "当前思考强度：{{value}}（已不在可选列表，换掉之前仍生效）",
    "resetNow": "思考强度已恢复为模型默认，当前会话从下一轮起使用它，这个聊天的新会话也使用它。",
    "resetNext": "思考强度已恢复为模型默认，这个聊天的新会话将使用它。",
    "notFound": "「{{query}}」不是可选的思考强度。",
    "numberOutOfRange": "编号 {{number}} 超出范围，可选 1–{{max}}。",
    "listTitle": "可选思考强度（★ 当前）：",
    "listTitleDefault": "可选思考强度（未手动选择，当前用模型默认）：",
    "more": "还有 {{count}} 项未列出。",
    "usage": "用法：/reasoning —— 看这个聊天当前模型的思考强度；/reasoning 取值 或 /reasoning 编号 切换；/reasoning default 恢复模型默认。",
    "choices": "可选：{{values}}。",
    "unsupported": "当前模型不支持切换思考强度。",
    "readFailed": "暂时读不到思考强度选项，请稍后重试。",
    "setFailed": "切换思考强度失败，请稍后重试。",
    "setNow": "思考强度已设为 {{value}}，当前会话从下一轮起使用它，这个聊天的新会话也使用它。",
    "setNext": "思考强度已设为 {{value}}，这个聊天的新会话将使用它。",
    "cleared": "新模型不支持原来的思考强度（{{value}}），已清除，改用模型默认。",
    "noModel": "这个聊天还没有模型，先用 /model 选一个。",
    "switchReadFailed": "暂时读不到新模型的思考强度选项，模型没有切换，请稍后重试。",
    "listTitlePlain": "可选思考强度："
  },
  "permission": {
    "current": "这个聊天新轮次的档位：{{mode}}",
    "ceiling": "机器人上限：{{mode}}",
    "cappedChoice": "这个聊天的选择：{{mode}}（超过机器人上限，暂不生效）",
    "ceilingMarker": "机器人上限",
    "unavailable": "不可选",
    "usage": "用法：/permission 查看档位；/permission 编号或档位 ID 选择；/permission default（或「权限 默认」）回到机器人设置。",
    "nextTurn": "从这个聊天的下一轮起生效；正在运行的轮次保持原档位。",
    "notAllowed": "只有机器人允许名单里的人能改档位。仍可发 /permission 查看档位；要改请联系机器人管理员。",
    "exceedsCeiling": "这个档位超过机器人上限（{{mode}}），没有修改聊天设置。发 /permission 看可选档位。",
    "selected": "这个聊天的档位已设为：{{mode}}",
    "reset": "已清除这个聊天的档位选择，回到机器人设置：{{mode}}",
    "saveFailed": "无法保存这个聊天的档位，没有修改聊天设置，请重试。",
    "alreadyDefault": "这个聊天未单独设置档位，正跟随机器人设置：{{mode}}",
    "numberOutOfRange": "编号 {{number}} 超出范围，列表编号为 1–{{max}}。",
    "notFound": "「{{query}}」不是可选的档位。",
    "savedChoice": "这个聊天的选择：{{mode}}",
    "following": "这个聊天未单独设置档位，跟随机器人设置。",
    "readOnly": "你不在机器人允许名单里，只能查看档位；要改请联系机器人管理员。",
    "readOnlyUnknown": "无法确认你的身份，只能查看档位；要改请联系机器人管理员。",
    "notAllowedUnknown": "无法确认你的身份，不能改档位。仍可发 /permission 查看档位；要改请联系机器人管理员。"
  },
  "history": {
    "usage": "用法：/history [数量] —— 1–{{maxCount}} 条（超出按 {{maxCount}} 条算），默认 {{defaultCount}} 条。",
    "directOnly": "在群里会把会话内容发给所有人。在与机器人的私聊里发 /history。",
    "noSession": "这个聊天还没有当前会话。发一句话开一个，或先用 /sessions 找到会话，再用 /resume 切过去。",
    "empty": "当前会话还没有能查看的消息。",
    "noneRecent": "当前会话最近的消息里没有能查看的（更早的没有往前翻）。",
    "failed": "没能读取最近的消息，稍后再试。",
    "title": "当前会话最近的消息（{{count}} 条）：",
    "user": "用户",
    "assistant": "助手",
    "image": "[图片]",
    "file": "[文件]",
    "noText": "[没有可预览的文字]",
    "truncated": "[其余文字已省略]"
  },
  "sessions": {
    "title": "本项目的会话（{{count}} 条）：",
    "empty": "本机器人还没在本项目开过会话，发一句话就会开一条。",
    "more": "还有 {{count}} 条没列出——用 /resume 加会话 id 的开头也能切到。",
    "footer": "用 /resume 编号 切换，或 /resume 加会话 id 的开头。",
    "untitled": "（无标题）",
    "unavailable": "现在读不出会话列表，稍后再试。",
    "projectNotFound": "项目编号不存在。发 /repo 看有哪些编号。",
    "projectNumberExpected": "/sessions 后面跟项目编号（/repo 列出的数字），例如 /sessions 2。",
    "project": "项目：「{{title}}」",
    "otherProjectTitle": "本机器人在项目「{{project}}」里开过的会话（{{count}} 条）：",
    "otherProjectFooter": "你仍在这个聊天当前的项目里。发 /resume 编号，或 /resume 加会话 id 的开头（本机器人开过但没列出的也行），就能切过去，聊天的项目会一起切。",
    "projectEmpty": "本机器人还没在那个项目里开过会话。想在那里开，发 /repo 加那个项目编号换过去，再发一句话。",
    "badge": {
      "current": "★ 当前",
      "running": "● 在跑",
      "elsewhere": "接在别的聊天",
      "web": "网页",
      "archived": "已归档"
    },
    "age": {
      "justNow": "刚刚",
      "minutes": "{{count}} 分钟前",
      "hours": "{{count}} 小时前",
      "days": "{{count}} 天前"
    }
  },
  "resume": {
    "notFound": "没有哪条会话对得上「{{query}}」。用 /sessions 看看有哪些。",
    "ambiguous": "对得上「{{query}}」的会话不止一条，id 开头再多给几位。",
    "busy": "这个聊天有一轮正在跑——先 /stop，再切换。",
    "already": "这个聊天已经在那条会话里了。",
    "gone": "那条会话已被删除或归档，接不上了。",
    "archived": "那条会话已归档，不能接着聊。只想看内容，去网页打开；想接着聊，先在网页或其他客户端里取消归档，再切过去，或发 /new 开新会话。",
    "runningElsewhere": "那条会话正在别的聊天里跑着一轮——先到那边停掉它。",
    "done": "已切到「{{title}}」。发一句话就从那里接着聊。",
    "doneInProject": "已切到项目「{{project}}」的会话「{{title}}」。发一句话就从那里接着聊。",
    "switchFailed": "没能切到那条会话，聊天的项目和会话都没变，稍后重发刚才那条 /resume。",
    "confirmWeb": "「{{title}}」是网页开的会话。再发一次 /resume 同一编号（或 /resume confirm）确认附着；/resume cancel 取消。",
    "cancelled": "已取消附着。",
    "nothingPending": "没有待确认的网页会话。用 /sessions 看看有哪些。"
  },
  "preset": {
    "current": "这个聊天新会话用的预设：{{preset}}",
    "botDefault": "这个聊天新会话的机器人默认预设：{{preset}}",
    "none": "这个聊天的新会话没有预设。",
    "unavailable": "{{value}}（不可用）",
    "item": "{{label}}（{{id}}）",
    "listTitle": "可选的预设：",
    "more": "还有 {{count}} 个没列出——用 /preset 名字或 id 也能选到。",
    "empty": "没有可选的预设。",
    "footer": "用 /preset 编号 切换，或 /preset 名字或 id。/preset none 清掉聊天选择，改用机器人默认预设。",
    "existing": "已有会话保留原预设。发 /new，再发一条消息，才会用上新设置。",
    "updated": "这个聊天新会话用的预设已设为：{{preset}}",
    "cleared": "已清掉聊天预设。新会话改用机器人默认预设（若已设置）。",
    "notFound": "没有唯一对得上「{{query}}」的预设。用 /preset 看看有哪些。",
    "readFailed": "现在读不出预设列表，稍后再试。",
    "textOnly": "预设命令只接受文字。去掉附件后再试。"
  },
  "model": {
    "current": "模型：{{model}}",
    "currentUnknown": "模型：还没定——新开会话时用项目的默认模型。",
    "unavailable": "现在读不出可选的模型，没法切换模型。",
    "listTitle": "可选的模型：",
    "more": "还有 {{count}} 个没列出——用 /model 实例/模型 也能选到。",
    "footer": "用 /model 编号 切换，或 /model 实例/模型。",
    "notFound": "没有唯一对得上「{{query}}」的模型。用 /model 看看有哪些。",
    "setNow": "模型已设为 {{model}}，当前会话从下一轮起用它。",
    "setNext": "模型已设为 {{model}}，下一条新会话起用它。",
    "setFailed": "没能切换当前会话的模型，稍后再试。"
  },
  "plan": {
    "on": "计划模式已开：从下一条消息起，agent 先出计划、不动手。发 /plan off 退出。",
    "off": "计划模式已关，消息照常处理。",
    "alreadyOn": "计划模式已经是开着的。",
    "alreadyOff": "计划模式已经是关着的。",
    "usage": "用法：/plan 切换计划模式；/plan on、/plan off 明确设定。"
  },
  "card": {
    "untitled": "对话",
    "status": {
      "working": "处理中…",
      "done": "已完成",
      "error": "出错了",
      "interrupted": "已中断",
      "continued": "后续见下方卡片"
    },
    "thinking": "正在思考中…",
    "usingTool": "正在使用 {{name}}…",
    "step": {
      "think": "思考",
      "command": "命令",
      "file": "改文件",
      "mcp": "mcp",
      "tool": "工具",
      "agent": "子 agent",
      "web": "搜索",
      "image": "看图",
      "omitted": "更早的 {{count}} 步"
    },
    "truncated": "…（前面 {{count}} 个字符没有显示）",
    "approval": {
      "doneTitle": "已处理",
      "timedOutTitle": "已自动拒绝",
      "originalLabel": "原审批内容：",
      "chosen": "已选：{{label}}",
      "elsewhere": "已在别处处理（网页或其他客户端）。"
    }
  },
  "panel": {
    "title": "命令面板",
    "hint": "点按钮等于打出对应的命令，也可以直接打字。",
    "wecomTruncated": "这张卡放不下全部命令。发送 /help 查看全部命令，再直接输入命令；在群里要先 @ 机器人。",
    "wecomExpired": "这个面板已过期，请重新发送 /panel；在群里要先 @ 机器人。",
    "category": {
      "session": "会话",
      "target": "派给谁",
      "system": "设置与状态"
    },
    "cmd": {
      "new": "新会话",
      "continue": "恢复发送",
      "stop": "停止本轮",
      "sessions": "会话列表",
      "team": "派给团队",
      "thread": "普通会话",
      "model": "模型",
      "planOn": "计划模式：开",
      "planOff": "计划模式：关",
      "status": "状态",
      "help": "文字说明",
      "repo": "选项目"
    },
    "back": "返回",
    "prev": "上一页",
    "next": "下一页",
    "page": "第 {{page}} / {{total}} 页",
    "loading": "加载中…",
    "working": "处理中…",
    "expired": "面板已过期，再发一次 /panel。",
    "busy": "上一步还在处理，稍等一下。",
    "loadFailed": "刚才没读出来，稍后再试。",
    "sessions": {
      "title": "选一条会话",
      "hint": "点一条切过去。"
    },
    "models": {
      "title": "选模型"
    },
    "projects": {
      "title": "选一个项目",
      "hint": "点一个项目，这个聊天就做它。",
      "pickedTitle": "已选定项目",
      "picked": "{{title}}\n发 /repo 可以更换。"
    }
  },
  "wecomSetup": {
    "action": {
      "label": "扫码创建企业微信智能机器人",
      "description": "用企业微信扫码创建智能机器人。Ycodium 会把 Bot ID 和 Secret 存进这台机器的机器人列表。"
    },
    "status": {
      "waiting": "用企业微信扫描二维码，再在企业微信里确认创建智能机器人。"
    },
    "done": "企业微信智能机器人已创建并保存。去企业微信给它发一条消息试试，再在聊天里选项目。",
    "doneNeedsAllowList": "企业微信智能机器人已创建并保存。按下面三步就能开始用：",
    "nextSteps": "1. 去企业微信给它发一条消息，它会回你的企业微信用户 id（扫码结果里没有这个 id）。\n2. 把 id 填进这个机器人那一行的「允许的人」，保存。\n3. 在聊天里选项目。",
    "failure": {
      "expired": "二维码在创建完成前过期了。点「再试一次」换一个新二维码。",
      "failed": "没能创建企业微信智能机器人。点「再试一次」重新来一遍。",
      "saveFailed": "智能机器人已创建，但没能存到这台机器上。请到企业微信里找到这个智能机器人，复制它的 Bot ID 和 Secret，点「添加机器人」手动补上。企业微信里看不到 Secret 的话，点「再试一次」重新创建一个；这次建出的机器人会留在企业微信里，可以到企业微信里删掉。"
    }
  },
  "setup": {
    "action": {
      "label": "连接飞书机器人",
      "description": "用飞书 App 扫一次码。Ycodium 会在你的账号下建好机器人应用，发布为仅自己可见，并把这个机器人连同凭据直接存进机器人列表，不用手填。",
      "badge": "测试版",
      "warning": "飞书扫码依赖飞书开发者后台的非公开接口，可能会失效。失效时请到开发者后台手动配置应用。"
    },
    "manual": {
      "createApp": {
        "title": "创建应用",
        "body": "打开飞书开发者后台，为你的企业创建一个企业自建应用，在「凭证与基础信息」里复制 App ID 和 App Secret。"
      },
      "enableBot": {
        "title": "开启机器人",
        "body": "在「应用功能」里添加「机器人」能力。"
      },
      "longConnection": {
        "title": "事件与卡片回调都用长连接",
        "body": "在「事件与回调」里，把事件订阅和回调订阅的接收方式都设为「使用长连接」，再订阅下面列出的事件和卡片回调。只改事件不改回调，所有卡片按钮都会失灵。"
      },
      "scopes": {
        "title": "添加权限",
        "body": "在「权限管理」里添加下面列出的每一项权限。少一项只会让用到它的功能失效。"
      },
      "publish": {
        "title": "发布版本",
        "body": "创建一个版本并发布。可见范围选「仅自己可见」，这样会立即通过审批，不用等管理员。"
      },
      "fillRow": {
        "title": "添加机器人",
        "body": "在设置的「聊天」分区里添加一个机器人：平台选飞书，填入 App ID 与 App Secret，把你自己的飞书用户 id 填进「允许的人」（给机器人发一条消息，它会告诉你），然后保存。"
      }
    },
    "status": {
      "waiting": "等待扫码",
      "scanned": "已扫码，请在手机上确认",
      "expired": "二维码已过期"
    },
    "step": {
      "login": "扫码登录",
      "identity": "读取账号信息",
      "findApp": "查找之前尝试时建的应用",
      "createApp": "创建应用",
      "enableBot": "开启机器人",
      "longConnection": "事件与回调切换为长连接",
      "scopes": "添加权限",
      "events": "订阅事件",
      "callbacks": "订阅卡片回调",
      "publish": "发布版本",
      "secret": "读取 App Secret"
    },
    "progress": {
      "login": "正在登录（{{n}}/{{total}}）",
      "identity": "正在读取账号信息（{{n}}/{{total}}）",
      "findApp": "正在查找之前尝试时建的应用（{{n}}/{{total}}）",
      "createApp": "正在创建应用（{{n}}/{{total}}）",
      "enableBot": "正在开启机器人（{{n}}/{{total}}）",
      "longConnection": "正在把事件与回调切换为长连接（{{n}}/{{total}}）",
      "scopes": "正在添加权限（{{n}}/{{total}}）",
      "events": "正在订阅事件（{{n}}/{{total}}）",
      "callbacks": "正在订阅卡片回调（{{n}}/{{total}}）",
      "publish": "正在发布版本（{{n}}/{{total}}）",
      "secret": "正在读取 App Secret（{{n}}/{{total}}）"
    },
    "done": "已连接并保存。去飞书里给机器人发一条消息试试，再在聊天里选项目。",
    "warn": {
      "senderUnknown": "没能读到你的飞书用户 id，所以这个机器人的「允许的人」是空的，暂时谁也用不了。给机器人发一条消息，它会回你的 id；把它填进这个机器人那一行的「允许的人」，再保存。",
      "scopesMissing": "这些权限没能自动添加：{{names}}。请到开发者后台手动添加。"
    },
    "failure": {
      "qrExpired": "二维码在扫描前过期了。请换一个新二维码再扫。",
      "scanTimeout": "没有及时扫码。请换一个新二维码再试。",
      "network": "连不上飞书开发者后台。请检查这台机器的网络或代理后重试。",
      "timeout": "飞书开发者后台响应太慢。请重试，或按手动步骤配置。",
      "sessionInvalid": "开发者后台不认这次登录。请重新扫码。",
      "consoleRejected": "开发者后台拒绝了这次请求。请按手动步骤配置，或稍后再试。",
      "ownerDenied": "这个账号不是该应用的所有者，无法修改它。请用创建该应用的账号扫码，或按手动步骤配置。",
      "verificationFailed": "后台没有保存事件配置，机器人会收不到任何消息，所以没有发布。请按手动步骤配置。",
      "publishNeedsManual": "应用已配置好，但版本没能发布。请到开发者后台手动发布，再在这里手动添加这个机器人，填入 App ID 与 App Secret。",
      "busy": "这台机器上已经有一次配置在进行。",
      "unknown": "配置因为意外错误中断。请重试，或按手动步骤配置。",
      "createUnknown": "后台没有确认应用是否已创建。请重试：之前那次建出的应用会被找回并复用。",
      "secretMissing": "应用 {{appId}} 已发布，但读不到它的 App Secret。请到开发者后台「凭证与基础信息」里复制。",
      "stopped": "配置被中止了。",
      "saveFailed": "应用 {{appId}} 已配置并发布，但机器人没能存到这里。请手动添加：平台选飞书，填入 App ID 与开发者后台「凭证与基础信息」里的 App Secret，再填「允许的人」。"
    }
  },
  "repo": {
    "autoSelected": "使用项目「{{title}}」。",
    "needProject": "这个聊天还没选项目，选定之前我不开工。选一个就开始。",
    "currentLine": "这个聊天现在在项目「{{title}}」上。",
    "noProjects": "这台机器上还没有项目，先到 Ycodium 里添加一个。",
    "more": "还有 {{count}} 个没列出——用 /repo 加项目名或名字开头也能选到。",
    "footer": "回复 /repo 编号 来选，或 /repo 加项目名。",
    "done": "已接上项目「{{title}}」，下一句话在这里开新会话。",
    "already": "这个聊天已经在项目「{{title}}」上了。",
    "notFound": "没有唯一对得上「{{query}}」的项目。发 /repo 看看有哪些。",
    "busy": "这个聊天有一轮正在跑——先 /stop，再换项目。",
    "gone": "那个项目已归档或已删除，选不了。"
  },
  "group": {
    "usage": "用法：/group 群名 —— 机器人建一个这个名字的群，并把你拉进去。",
    "created": "已建好群「{{name}}」，并把你拉进去了。到群里选项目就能开始。",
    "unsupported": "这个平台的机器人建不了群。请在 App 里自己建群，再把机器人拉进去。",
    "noSender": "我认不出你在这个平台上是谁，没法把你拉进新群。",
    "failed": "没能建群。请确认这个应用有建群和拉人的权限，再试一次。"
  },
  "sync": {
    "webUser": "网页：{{text}}"
  },
  "rowAction": {
    "checkConnection": {
      "label": "检查连接",
      "description": "验证平台凭据，并向最近的私聊发一条测试消息；不会开会话，也不会调模型。",
      "running": "正在检查 {{rowId}} …",
      "done": "连接正常",
      "doneTestFailed": "凭据正常，但测试消息没发出去",
      "doneNoTarget": "凭据正常，但还没发测试消息",
      "failed": "连接失败",
      "notSaved": "请先保存这一行再检查连接（凭据只从已保存配置读取）。",
      "credentialRef": "凭据检查参考号：{{ref}}\n{{detail}}",
      "testMessage": {
        "sent": "已发到最近私聊过机器人的人，请对方确认收到。",
        "test-target-unavailable": "还没有可用于测试的私聊。用获准使用这个机器人的账号私聊它一句，再检查。",
        "test-message-failed": "确认机器人还能在那个私聊里发消息（原因见下方），再检查。",
        "ref": "测试消息参考号：{{ref}}\n{{detail}}"
      },
      "hint": {
        "networkMultipleCauses": "这次失败背后不止一种网络问题。请检查这台机器的网络和这个机器人的「代理」设置，再检查一次。",
        "networkDns": "服务域名解析失败。请检查这台机器的 DNS 和网络设置，再检查一次。",
        "networkRefused": "目标拒绝了连接。请检查这台机器和所在网络的防火墙、安全软件是否拦了这个连接，再检查一次。",
        "networkReset": "连接被对方中断。请检查这台机器的网络，以及目标服务是否在正常运行，再检查一次。",
        "networkUnreachable": "目标网络不可达。请检查这台机器的网络出口和访问限制，再检查一次。",
        "networkTls": "TLS 或证书校验失败。请检查这台机器的系统时间、证书链和网络设置，以及代理或安全软件是否拦截了 HTTPS 连接，再检查一次。",
        "networkTimeout": "请求超时。请确认目标服务是否在正常运行，并检查这台机器的网络，再检查一次。",
        "networkProxy": "代理连接或认证失败。请检查这一行的「代理」设置和所选代理在这台机器上的配置；没设代理的话，检查这台机器或所在网络上的其他代理，再检查一次。",
        "platformRateLimited": "平台正在限流。请稍后重试。",
        "platformUnavailable": "目标服务暂时异常。请稍后重试。",
        "connecting": "还在连接，一般 20 秒内会有结果，稍后再检查一次。",
        "badToken": "这不像机器人的 token。到 BotFather 重新复制一份：数字、冒号，后面是密钥。",
        "unauthorized": "Telegram 不认这个 token，可能已经作废。到 BotFather 取现在的那一份。改好后在这里保存，机器人会自动重新连接；没有要改的也可以点下方的「重新连接」。",
        "notBot": "这个 token 不是机器人的。请用 BotFather 给的那一份。",
        "webhookActive": "这个机器人被别的服务设了 webhook，在这里收不到消息。先到那边撤掉 webhook，再检查一次。",
        "larkCredentials": "飞书不认这个 App ID 或 App Secret。到飞书开放平台这个企业自建应用的「凭证与基础信息」重新复制两项。改好后在这里保存，机器人会自动重新连接；没有要改的也可以点下方的「重新连接」。",
        "larkScope": "这个应用缺少所需权限。到飞书开放平台的「权限管理」，添加详情中列出的权限，再发布一个版本。",
        "larkBotOff": "这个应用没有启用机器人能力。到飞书开放平台的「应用能力 → 机器人」启用机器人，再发布一个版本。",
        "larkAppUnavailable": "这个应用在当前企业不可用。到飞书开放平台确认应用已启用并发布，再请管理员确认当前企业已安装并启用这个应用。",
        "wecomBotCredentials": "企业微信不认这个 Bot ID 或 Secret。到企业微信后台这个智能机器人的配置页，选择「API 模式 → 长连接」，重新复制 Bot ID 和 Secret；这里用的不是回调模式的 Token 或 EncodingAESKey。改好后在这里保存，智能机器人会自动重新连接；没有要改的也可以点下方的「重新连接」。",
        "wecomLongConnOff": "这个智能机器人没有开启长连接模式。到企业微信后台这个智能机器人的配置页选择「API 模式 → 长连接」并保存，这里会在一分钟内自动重新连上；也可以直接点下方的「重新连接」。",
        "wecomTakenOver": "另一台机器或程序在用同一个 Bot ID。让它停用这个智能机器人后，点下方的「重新连接」。",
        "wecomTrustedIp": "把这台机器的出站公网 IP 加进企业微信后台这个应用的企业可信 IP。",
        "wecomInvalidUser": "确认收件人、部门或标签存在，并在这个自建应用的可见范围内。",
        "wecomInvalidAgent": "核对企业微信后台这个自建应用的 AgentId。",
        "wecomCallbackNotSeen": "凭据有效，但自本次启动以来还没收到过通过校验的回调。到企业微信后台这个应用的「接收消息」，填入机器人设置卡上显示的回调地址并保存；企微会发来一次校验请求。这台机器必须能被企微从公网访问到。",
        "wecomCallbackSignature": "收到过回调，但签名校验或解密失败；自本次启动以来还没收到过通过校验的回调。请把回调 Token 和 EncodingAESKey 与企业微信后台这个应用的「接收消息」设置保持一致，再到后台保存一次以重新校验。"
      }
    },
    "reconnect": {
      "label": "重新连接",
      "description": "按已保存的设置断开并重新连接这个机器人。",
      "notAvailable": "这个平台还不能连接，重新连接也连不上。",
      "running": "正在重新连接 {{rowId}} …",
      "done": "已开始重新连接，结果请看机器人的连接状态。",
      "notSaved": "请先保存这一行再重新连接，动作只使用已保存的设置。",
      "notConfigured": "请先补全并保存这个机器人的设置，再重新连接。",
      "duplicate": "另一个机器人行正在使用这份凭据，请先处理重复配置再重新连接。",
      "inactive": "聊天桥已停用，请先启用再重新连接。"
    },
    "resetInbox": {
      "label": "重置收件箱",
      "confirm": "重置收件箱",
      "description": "只重置这个机器人的收件箱，并按已保存的设置重新连接。它还没处理的消息会丢失，去重记录会清空。",
      "telegramOffline": "Telegram 会跳过机器停机期间的积压消息。",
      "alreadyReadable": "这个机器人的收件箱已可读取，本次没有重置。",
      "running": "正在重置 {{rowId}} 的收件箱 …",
      "done": "收件箱已重置并开始重新连接，结果请看机器人的连接状态。它还没处理的消息已丢失，去重记录已清空。",
      "notSaved": "请先保存这个机器人，再重置收件箱。",
      "failed": "没能重置这个机器人的收件箱，它仍停止接收。请检查机器能否读写已保存的数据，再重试。",
      "reconnectFailed": "收件箱已重置，但没能开始重新连接。它还没处理的消息已丢失，去重记录已清空。"
    },
    "copyDiagnostics": {
      "label": "复制诊断",
      "description": "跑一次连接探测，生成可复制的诊断文本（不含密钥）。",
      "running": "正在生成诊断 {{rowId}} …",
      "done": "诊断报告已生成，见下方详情",
      "notSaved": "请先保存这一行再复制诊断。"
    },
    "diagnostic": {
      "ref": "参考号：{{ref}}\n{{detail}}"
    },
    "larkCallbackProbe": {
      "label": "验证卡片按钮",
      "description": "私发测试卡给这一行允许名单里的第一个人（通常就是你），等你在 {{seconds}} 秒内点击卡上的按钮。",
      "step": "私发测试卡并等待点击",
      "waiting": "测试卡已私发给允许名单里的第一个人（{{id}}，通常就是你）。请在 {{seconds}} 秒内到飞书里点卡上的按钮。",
      "notConnected": "跳过：这个机器人还没在这台机器上连上。请先用这一行的「重新连接」连上，再验证。",
      "noRecipient": "跳过：没有可接收测试卡的人。请先用「连接飞书机器人」扫码配置，扫码会自动把你加进这一行的允许名单。",
      "sendFailed": "发不出测试卡。请用这一行的「补全权限」核对消息权限，确认机器人连着，再验证。",
      "timeout": "{{seconds}} 秒内没收到测试卡的按钮回调。要是没来得及点，直接再点「验证卡片按钮」；要是点了还超时，请到开发者后台的「事件与回调」，把回调订阅设为「使用长连接」，添加 {{callbacks}} 后再验证。\n开发者后台地址：\n{{url}}",
      "toast": "已收到点击，卡片按钮可用。",
      "staleToast": "这张测试卡的验证已经结束，结果以设置面板和私信为准。要再验证，请在设置里点「验证卡片按钮」。",
      "notYoursToast": "这张测试卡是发给允许名单里第一个人的，你的点击不算在验证里，忽略就好。",
      "verified": "已收到测试卡的 card.action.trigger，卡片按钮可用。",
      "aborted": "机器人断开，验证中断。请等它恢复连接，或用这一行的「重新连接」，再验证。",
      "card": {
        "title": "🧪 验证卡片按钮",
        "body": "请在 {{seconds}} 秒内点击下方按钮；机器人所在的机器确认收到这次点击后，验证才算通过。",
        "button": "完成验证"
      },
      "notice": {
        "verified": "✅ 验证通过：已收到你点击测试卡发来的 card.action.trigger，卡片按钮可用。",
        "timeout": "⚠️ 验证超时：没收到测试卡的 card.action.trigger，还不能确认按钮可用。要是没来得及点，再点一次「验证卡片按钮」就行；要是点了还超时，请先到开发者后台的「事件与回调」，把回调订阅设为「使用长连接」并添加 card.action.trigger，再点一次「验证卡片按钮」。\n开发者后台地址：\n{{url}}",
        "sendFailed": "⚠️ 验证失败：发不出测试卡，还不能确认 card.action.trigger 可用。请在设置里用这个机器人那一行的「补全权限」核对消息权限，再点「验证卡片按钮」。",
        "aborted": "⚠️ 验证中断：机器人在确认 card.action.trigger 之前断开了。请等它恢复连接，或在设置里用这个机器人那一行的「重新连接」，再点「验证卡片按钮」。"
      }
    },
    "larkRepair": {
      "label": "补全权限",
      "description": "列出缺少的必需权限和飞书开放平台申请链接，再由管理员手动发布应用版本。",
      "step": {
        "token": "用已保存的凭据换取 tenant token",
        "scopes": "核对应用已开通的租户权限"
      },
      "missing": "有必需权限尚未开通。",
      "allGranted": "必需权限都已开通。",
      "unverified": "无法自动核对权限。",
      "missingScopes": "缺少的权限：\n{{scopes}}",
      "requiredScopes": "必需权限清单，请逐项手动核对：\n{{scopes}}\n\n应用缺少 application:application:self_manage 时无法查询自身已开通的权限，所以这份清单没能自动核对。",
      "openApplyLink": "打开飞书开放平台申请这些权限",
      "openCheckLink": "打开飞书开放平台核对并申请这些权限",
      "applyLink": "开放平台地址：\n{{url}}",
      "publishHint": "请应用管理员打开上述链接勾选权限，再到「应用发布 → 版本管理与发布 → 创建版本」发布新版本，回来点「检查连接」确认。",
      "botHint": "启用机器人请到「应用 → 添加应用能力 → 机器人」；这里不检查机器人能力。",
      "eventHint": "收消息需要在「事件与回调」里把事件订阅和回调订阅都设为「使用长连接」，再添加下面这些（这里不检查）：\n事件：{{events}}\n回调：{{callbacks}}",
      "failed": "未能核对应用的必需权限，请查看错误详情后重试。",
      "notLark": "这一行不是已保存的飞书机器人。"
    }
  },
  "menu": {
    "new": "下一句开一个新会话",
    "stop": "停掉正在跑的这一轮",
    "continue": "停下或失败之后接着发",
    "status": "看现在在干什么",
    "sessions": "列出这个聊天所在项目的会话",
    "resume": "切到某个会话（/sessions 里的编号）",
    "model": "看或换模型",
    "plan": "开关计划模式",
    "repo": "选这个聊天在哪个项目上干活",
    "team": "每条消息都给这个项目的团队开一个目标",
    "thread": "切回普通会话",
    "panel": "打开命令面板",
    "help": "列出全部命令"
  },
  "settingsSection": {
    "lastMessageError": {
      "title": "最近一条消息处理失败",
      "separator": "：",
      "code": "错误码 {{code}}",
      "reference": "参考号 {{referenceId}}"
    },
    "empty": "还没有机器人",
    "emptyGuide": "用「{{larkLabel}}」或「{{wecomLabel}}」扫一下就能建好机器人。其他平台点「{{addBotLabel}}」，填入在该平台开发者后台拿到的凭据。",
    "unavailable": "这台机器现在没有聊天桥。",
    "loadFailed": "聊天桥的设置没能读出来。",
    "retry": "再试一次",
    "general": "通用设置",
    "addBot": "添加机器人",
    "moreSettings": "更多设置",
    "moreSettingsIssues": "更多设置（{{count}} 项待修正）",
    "save": "保存",
    "revert": "撤销改动",
    "saveFailed": "没能存上。",
    "remove": "删除",
    "removeConfirm": "删除这个机器人",
    "cancel": "取消",
    "removeHint": "删掉这个机器人后，它下面所有会话的绑定都会一起丢掉。",
    "copy": "复制",
    "copied": "已复制。",
    "copyFailed": "没复制上。",
    "removeFailed": "没能删掉这个机器人。",
    "status": {
      "ready": "就绪",
      "incomplete": "待补全",
      "connecting": "连接中",
      "connected": "已连接",
      "notConnected": "未连接"
    },
    "online": "{{connected}} / {{configured}} 在线",
    "onlineLabel": "已配齐 {{configured}} 个机器人，其中 {{connected}} 个在线",
    "connection": {
      "since": "状态自 {{time}} 起",
      "failed": "上次连接没有成功。",
      "details": "详情：{{error}}",
      "reconnect": "可以点下方的「重新连接」再试。",
      "reason": {
        "inbox-unreadable": "这个机器人的收件箱读不出，已停止接收消息。可以用这张卡上的「重置收件箱」恢复。",
        "not-available": "这个平台还不能连接。",
        "invalid-app-id": "App ID 格式不正确。",
        "disconnected": "和平台的连接断了。",
        "subscription-failed": "平台没有确认订阅。",
        "taken-over": "这里的连接已被别处取代，已停止自动重连。",
        "token-unavailable": "没能换到访问令牌。",
        "credentials-rejected": "平台拒绝了凭据。"
      },
      "duplicate": "和「{{name}}」用的是同一份凭据，只连那一行。"
    },
    "secret": {
      "saved": "已经存过，留空就保持原值。",
      "clear": "清除已存的值",
      "clearUndo": "撤销清除"
    },
    "issue": {
      "required": "这一项要填。",
      "format": "这个格式不对。"
    },
    "publicField": {
      "callbackUrl": "回调地址",
      "callbackPath": "回调路径"
    },
    "action": {
      "running": "正在处理…",
      "done": "完成。",
      "close": "关闭",
      "failedToRun": "没能在这台机器上运行。",
      "saveFirst": "先保存或撤销改动。这些动作使用已保存的设置。",
      "qrTitle": "用飞书 App 扫的二维码"
    },
    "step": {
      "pending": "等待中",
      "running": "进行中",
      "done": "已完成",
      "skipped": "已跳过",
      "failed": "失败"
    },
    "select": {
      "default": "默认"
    },
    "target": {
      "description": "脚本或别的工具可以经机器人把消息发到这些地方。调用方只报机器人和目标 id，平台上的聊天 id 留在这里。",
      "add": "添加目标",
      "untitled": "新目标",
      "removeConfirm": "删除这个目标",
      "removeFailed": "这个目标没删掉。"
    },
    "publicFieldHint": {
      "callbackNeedsKeys": "填好 Token 和 EncodingAESKey 并保存后，这里给出回调地址（地址由它俩算出）。",
      "callbackPathNeedsBase": "把转发到本机的公网地址拼在这段路径前面，或在上面填公网回调基址，这里就给出完整地址。",
      "callbackFollowsKeys": "改了 Token 或 EncodingAESKey，这个地址会变，要重新贴进企业微信。"
    }
  },
  "mergeForward": {
    "title": "[合并转发的聊天记录，共 {{count}} 条]",
    "nested": "[嵌套转发，共 {{count}} 条]",
    "someone": "某人",
    "bot": "机器人",
    "unknownTime": "[时间未知]",
    "resource": {
      "image": "图片",
      "file": "文件",
      "audio": "语音",
      "video": "视频",
      "folder": "文件夹"
    },
    "unavailable": "[{{type}}：没能取到]",
    "unavailableNamed": "[{{type}} {{name}}：没能取到]",
    "omitted": "……还有 {{count}} 条没列出",
    "truncated": "……[正文已截断]"
  },
  "team": {
    "noRoster": "这个项目还没有团队名单，先在 Teams 标签里保存名单并选一名负责人。",
    "unavailable": "暂时读不到这个项目的团队名单，请确认 Teams 插件已启用后重试。",
    "invalidGoal": "目标为空或太长，请修改消息后重发。",
    "startFailed": "没能把目标交给负责人，请重发这条消息再试。",
    "startedUnnamed": "已交给负责人，目标：{{goal}}",
    "started": "已交给负责人 {{name}}，目标：{{goal}}"
  },
  "annotation": {
    "channel": {
      "wechat": "微信",
      "chat": "聊天应用"
    }
  }
}
