# El Bot > QQ 官方机器人遥控本机 Codex,使用统一的 el-bot codex CLI。 文档对应包版本 1.0.0-rc.2;使用 el-bot@next 或固定此版本,先用 el-bot --version 与 el-bot codex --help 核对安装包。 新实例使用 --profile 隔离配置、凭据、状态和 Codex 目录;旧实例保留原参数。用户在本机登录账号、填写凭据、私聊完成绑定。助手不得索要或输出密钥、完整状态。保留已有配置和会话;先做只读检查,再启动服务。 --- Source: https://docs.bot.elpsy.cn/ai/codex/ai-setup.md # 用 AI 快速接入 可以把下面的提示词交给能执行本机命令的 AI 助手,例如 Codex 或 Claude Code。 助手使用现有 CLI 完成环境检查、项目配置和连接诊断,不需要额外模型 API Key。 QQ 平台登录、密钥填写和首次 `/pair` 绑定由你在自己的设备上完成。 > **版本与实例** 使用 `el-bot@next`,或固定 `el-bot@1.0.0-rc.2`。先检查版本和子命令,再按[安装说明](https://docs.bot.elpsy.cn/development/codex-remote#安装-cli)继续。 新实例推荐使用 `--profile personal`;独立 Codex 登录、AppID 校验与恢复见[实例隔离与恢复](https://docs.bot.elpsy.cn/codex/instances)。无需 YunLeFun 账户。 ## 复制给你的 AI 助手 把项目路径替换为真实路径。已有实例请说明正在使用的 profile 或自定义路径。 ```text 请帮我把 QQ 官方机器人接入本机 Codex,使用 el-bot codex 子命令。 目标项目绝对路径:<替换为自己的项目目录> 项目名称:my-project 新实例名称:personal(已有实例时使用其原 profile 或路径) 可选的 el-bot 源码目录或本地 tgz:<有则填写> 先阅读当前版本的 docs/codex/ai-setup.md、docs/codex/instances.md 和 docs/development/codex-remote.md。 源码不可用时,读取 https://docs.bot.elpsy.cn/llms.txt 中的 Markdown 链接; 在线文档未部署或与安装包版本不同,使用对应 Git revision 的文档,不猜测参数。 请按以下步骤实际操作,并在缺少用户登录或凭据时说明当前需要我完成什么: 1. 检查操作系统、Node.js(22.18+)、包管理器、项目是否存在,以及 codex --version 和 codex login status。 2. 执行 el-bot --version 和 el-bot codex --help 确认支持子命令。旧版不支持时安装 el-bot@next, 或指定本地包、在源码目录使用 pnpm cli codex;不要在我的目标项目克隆工具仓库。 3. 用 codex --profile personal paths 核对配置、凭据、状态和 codexHome 路径。已有实例使用原参数,保留绑定、会话和其他项目, 不重复 init,不覆盖或删除状态,不启动第二个使用同一状态的实例。 4. 未初始化时执行 el-bot codex --profile personal init --project "目标项目绝对路径" --name my-project --no-prompt。 让我在本机交互终端或私有编辑器填写凭据。不要索要、读取、打印或上传 AppSecret、Token、完整凭据文件和状态内容; 不把密钥写入聊天、命令参数、项目文件或 Git。只报告路径和脱敏结果。 profile 使用独立 Codex 目录;设置 paths 中的 CODEX_HOME 后让我自己执行 codex login,不复制已有登录文件。 5. 检查 codex check;登录或凭据未完成就保留进度并提示我。完成后执行 codex check --all。 优先执行 check --all --json,读取所有 checks 的 status、summary 和 actions;退出码 1 不代表所有项目都失败。 这些检查不启动模型任务、不发送 QQ 消息。按报告处理出口 IP 白名单、独立 Codex 目录登录、model 或指定项目会话;不删除状态或自动执行 recover。 6. 引导我在 q.qq.com 启用 WebSocket、设置出口 IP 白名单,并让测试 QQ 能添加机器人。 如果原来使用 Webhook,说明切换会影响旧服务,让我决定是否切换或使用另一机器人。 7. 本地与 QQ 检查通过后,在我可见的终端运行 codex start,保持前台运行。 让我自己把终端的 /pair 绑定码私聊发给机器人,不发送给其他人,不设置开机启动。 8. 给我 QQ 验收步骤:/help 或 /menu 打开快捷菜单、/projects 点选项目(也可 /project my-project)、/status,随后由我发送 “请只回复 QQ_CODEX_READY,不使用工具、不修改文件”,最后用 /result 查询。 最后报告已执行命令、检查结果、配置路径和仍待我完成的步骤。 以上 codex 命令均使用 el-bot codex 前缀;源码模式使用 pnpm cli codex。 每一步使用相同的 --profile;已有默认实例不要擅自改为新 profile。自定义 --config、--credentials、--state 时,每一步使用同样的路径,参数放在 codex 后。 如果检查发现归档或目录变化,解释 /diagnose、/new 项目 和停止服务后 recover --project 项目的区别,保留历史,不自动重试任务。 ``` ## 助手的执行顺序 | 阶段 | 助手可以完成 | 用户完成 | | --- | --- | --- | | 检查环境 | 检测版本、项目路径、CLI 帮助、Codex 登录状态 | 必要时在本机登录 Codex | | 初始化 | 使用 `init --no-prompt` 创建项目配置与凭据模板 | 在本机填写 AppID / AppSecret | | 检查连接 | `check`、`check --all`;输出脱敏诊断 | QQ 平台设置与登录 | | 绑定和验收 | 在可见终端启动,解释 QQ 命令和预期结果 | 私聊发送绑定码与测试提示词 | `init --no-prompt` 没有读取到凭据时会生成空模板;这属于“初始化完成、QQ 凭据待填写”,不能报告已接通。 `check --all` 成功说明本机 Codex 已连接、账户信息与模型配置通过预检,且 QQ AccessToken 和网关地址可获取;网络、额度与模型服务权限仍需真实任务验证。只有 QQ 私聊收到结果并能 `/result` 查询,才能确认端到端接通。 测试提示词会调用一次 Codex 模型,可能产生账户用量;只有用户发送后才执行。 ## 非交互初始化示例 已安装新 CLI 时: ```bash el-bot codex --help el-bot codex paths codex login status el-bot codex init --project /absolute/path/to/my-project --name my-project --no-prompt el-bot codex check ``` 凭据填写与平台设置完成后: ```bash el-bot codex check --all el-bot codex start ``` 已有配置时跳过 `init`。使用 `--config` 指定新配置时,还需要显式选择对应的 `--credentials` 与 `--state`; 仅换配置不会创建独立状态。不要把状态文件放到目标项目中。 ## AI 可读的文档入口 文档构建从当前 Markdown 源文件生成以下产物,内容随版本一起更新: - [llms.txt](https://docs.bot.elpsy.cn/llms.txt):接入导航与各页 Markdown 链接。 - [llms-full.txt](https://docs.bot.elpsy.cn/llms-full.txt):AI 接入、完整协议/命令、迁移与发布文档的合集。 - 本页 Markdown:可直接交给本机助手阅读。 - 完整接入 Markdown:配置、权限、命令与排错。 `llms.txt` 是[社区提出的 AI 文档格式](https://llmstxt.org/),不会自动赋予助手账户权限或代替 QQ 平台授权。 文档与安装版本不一致时,让助手读取对应 Git revision 的原始 Markdown。 --- Source: https://docs.bot.elpsy.cn/ai/development/codex-remote.md # QQ 遥控本地 Codex 通过 QQ 官方机器人的私聊,在自己的电脑上启动 Codex 任务、继续项目会话、处理审批和查询结果。 实现使用 QQ 官方 API 和 Codex app-server 的 stdio 协议;运行时不依赖 Mirai、NapCat 或桌面浏览器调试端口。 现支持按本机版本生成 API 目录、连接已有 app-server,并通过 Codex 随应用提供的 MCP 适配器管理桌面项目、聊天、侧栏和工具。桌面宿主接入与验证条件见 [管理 Codex Desktop](https://docs.bot.elpsy.cn/codex/desktop)。 先看[功能展示](https://docs.bot.elpsy.cn/codex/),也可以复制[AI 接入提示词](https://docs.bot.elpsy.cn/codex/ai-setup),让本机助手完成环境检查与初始化。 ## 环境要求 - Node.js 22.18+;推荐使用仓库 `.node-version` 指定的 Node.js 24。 - 本机已安装 Codex CLI,执行 `codex login`;`codex app-server` 必须可用。 - 在 [QQ 开放平台](https://q.qq.com/) 创建机器人,取得 AppID 和 **AppSecret**。 - 在后台「开发设置 → 事件订阅与回调」选择 **WebSocket**,配置运行机器的出口 IP 白名单。 - 根据平台的服务范围或开发体验用户设置,让自己的 QQ 可以添加机器人并私聊。 默认 CLI 沿用本机 Codex 的账户和模型配置,也可在配置文件中指定 `model`。新实例推荐使用 `--profile` 隔离账户、凭据和会话,见[实例隔离与恢复](https://docs.bot.elpsy.cn/codex/instances)。无需 YunLeFun 账户;QQ 鉴权与本人 `/pair` 绑定仍然必需。 默认连接独立的本地 app-server,创建并恢复自己维护的项目会话。配置已有后端代理后可以绑定该后端的会话;桌面项目、聊天和侧栏管理另需连接 Desktop 宿主适配器,见[管理 Codex Desktop](https://docs.bot.elpsy.cn/codex/desktop)。 ## 安装 CLI 安装包为 `el-bot`,Codex 功能统一放在 `el-bot codex` 子命令下;`el` 别名仍可使用。 Codex 命令内置所需的工作区协议实现,运行时不依赖仓库、TypeScript、tsx, 也不要求单独安装 `qq-sdk` 或 `@el-bot/codex`。原有机器人开发入口保留为 `el-bot dev [root]`。 本文对应 `el-bot@1.0.0-rc.2`。预发布版使用 `next` 标签;安装后先检查版本与子命令: ```bash pnpm add -g el-bot@next el-bot --version el-bot codex --help # 或无需全局安装:pnpm dlx el-bot@next codex <命令> ``` 从源码构建并打包: ```bash git clone https://github.com/YunYouJun/el-bot cd el-bot pnpm install pnpm build pnpm --filter el-bot pack --pack-destination ./dist ``` 安装生成的包,之后可在任意目录运行: ```bash pnpm add -g ./dist/el-bot-1.0.0-rc.2.tgz el-bot --help el-bot codex --help ``` 需要固定版本时: ```bash pnpm add -g el-bot@1.0.0-rc.2 ``` ## 三步开始 ### 1. 初始化 ```bash el-bot codex init --project /absolute/path/to/my-project --name my-project ``` 不传 `--project` 时使用当前目录。终端会询问 AppID 和 AppSecret,密钥使用隐藏输入。 配置与凭据默认写入用户目录,文件权限为 `0600`(支持 POSIX 权限的平台),不会覆盖已有文件或清除绑定。 已有配置时,直接编辑配置增加项目即可;不必重复初始化。 | 文件 | 默认路径 | 用途 | | --- | --- | --- | | 配置 | `~/.el-bot/qq-codex.json` | 项目白名单、模型和接入方式 | | 凭据 | `~/.el-bot/qq-codex.env` | AppID、AppSecret | | 状态 | `~/.el-bot/qq-codex-state.json` | 本人绑定、项目会话、任务和消息去重 | 在脚本或非交互环境中使用 `init --no-prompt`:已有 `QQ_BOT_APP_ID`、`QQ_BOT_SECRET` 环境变量时写入凭据, 否则创建空白模板供手动填写。已有凭据文件保持原样。不要将密钥作为命令行参数传入,以免出现在进程列表和 shell 历史中。 ### 2. 检查 ```bash el-bot codex check --all ``` `check` 默认检查项目目录、请求 Codex 刷新登录信息,并核对 ChatGPT 账户的模型目录与各项目配置;`check --qq` 仅验证 QQ AccessToken 与网关地址; `check --all` 检查两者。这些命令不会启动模型任务、建立 QQ 长连接或发送消息,也不会输出访问令牌。 检查失败会返回非零退出码。 检查还会读取保存的会话,识别归档、丢失和目录变化;`--qq` / `--all` 会校验 AppID 与状态是否匹配。归档恢复见[实例隔离与恢复](https://docs.bot.elpsy.cn/codex/instances#明确恢复-不丢历史)。 模型目录检查通过不代表模型请求一定成功;网络、账户额度及服务端模型权限仍需真实任务验证。 ### 3. 启动与绑定 ```bash el-bot codex start ``` 第一次启动时,在 QQ 中私聊自己的官方机器人,发送终端显示的绑定码: ```text /pair 终端显示的绑定码 ``` 绑定码有效期为 10 分钟。绑定成功后,只有该用户的 `user_openid` 可以提交任务。 其他用户和群聊消息不会执行,也不会收到项目信息。随后直接发任务文本,或用 `/help` 查看命令。 服务需要保持运行,使用 Ctrl+C 正常退出;CLI 不会自动安装开机启动服务。 ## CLI 命令与配置 AI 助手可用 `init --no-prompt` 创建配置、`paths` 核对路径、`check --all` 做连接检查。 完整的非交互接入与用户操作边界见 [AI 快速接入](https://docs.bot.elpsy.cn/codex/ai-setup)。 | 命令 | 作用 | | --- | --- | | `el-bot codex init` | 创建配置和凭据,可用 `--project`、`--name`、`--no-prompt` | | `el-bot codex check` | 验证项目与本机 Codex,可用 `--qq` 或 `--all` | | `el-bot codex start` | 启动 QQ 遥控服务;`el-bot codex` 也会启动 | | `el-bot codex paths` | 查看实际配置、凭据、状态路径,不显示密钥 | | `el-bot codex recover --project 名称` | 停止服务后重置该项目的续聊绑定,备份状态并保留本人绑定和历史 | | `el-bot codex api` | 从本机 Codex 生成方法目录,支持 `--experimental`、`--method` | | `el-bot codex desktop-init` | 向已有配置接入桌面宿主;需管道与专用聊天 ID | | `el-bot codex desktop-check` | 只读验证宿主目录和项目列表,不运行模型 | | `el-bot codex --help` / `el-bot --version` | 查看 Codex 帮助或 el-bot 版本 | 所有 Codex 子命令支持 `--profile `、`--config `、`--credentials `、`--state `;参数放在 `codex` 后,例如: ```bash el-bot codex start --config /path/to/config.json --credentials /path/to/bot.env --state /path/to/state.json ``` 自定义路径后,初始化、检查和启动应使用相同参数。不同机器人的实例需要分别指定凭据、配置和状态文件。 仅更换 `--config` 不会自动更换默认状态文件;状态锁会阻止两个实例同时使用同一个文件。 使用 `--profile personal` 可以自动分配独立目录和 Codex 账户目录,须在该目录登录。状态自动绑定 AppID、测试环境和 Codex 目录,见[实例隔离与恢复](https://docs.bot.elpsy.cn/codex/instances)。 配置文件示例: ```json { "projects": { "el-bot": "/absolute/path/to/el-bot", "my-project": "/absolute/path/to/my-project" }, "defaultProject": "el-bot", "transport": "websocket", "sandbox": false, "messageFormat": "markdown" } ``` 项目目录必须存在;相对路径相对于配置文件,QQ 只能通过项目名称选择。 `sandbox` 指 **QQ 平台的测试环境**,与 Codex 执行沙箱无关。 如果 `codex` 不在 PATH,可以设置 `codexExecutable` 为可执行文件的绝对路径。 `model` 可覆盖本机 Codex 的默认模型。不填写时沿用当前项目的本机配置;桌面应用中的模型名可能不适用于 CLI。 若检查提示模型不在当前 ChatGPT 账户目录中,将遥控配置的 `model` 设置为检查建议的模型,再重新检查并启动。自定义模型服务及 API Key 账户不套用 ChatGPT 模型目录。 `messageFormat` 默认是 `markdown`,已有配置无需迁移;设置为 `text` 可始终使用纯文本。`image` 开启[图片卡片](#图片卡片与本地预览),默认直接上传本地 PNG 到 QQ,无需自建公网图片入口。 凭据文件格式: ```dotenv QQ_BOT_APP_ID="你的 AppID" QQ_BOT_SECRET="你的 AppSecret" ``` 显式使用 `--credentials` 或 `--profile` 时只读取对应凭据文件,环境变量不覆盖该文件,文件缺失会直接报错。 默认模式按 **完整进程环境 → 默认凭据文件 → 当前目录 `.env`** 读取;AppID 和 Secret 必须来自同一来源,半套凭据直接报错,不跨来源拼接。 旧变量 `QQ_BOT_APP_SECRET` 仍兼容;`QQ_BOT_APP_TOKEN` 不能替代 AppSecret。 只读取 QQ 凭据,不把 dotenv 中无关的变量注入 Codex 子进程。 已知自己的机器人 OpenID 时,可设置 `ownerOpenId`;它不是 QQ 数字账号。 更换绑定人需停止服务,在本机备份并移走旧状态后重新绑定;配置与已有绑定不一致时拒绝启动。 ### 旧版与源码使用 源码仍支持: ```bash pnpm cli codex init --project /absolute/path/to/project pnpm cli codex check --all pnpm cli codex start ``` 旧源码快捷入口 `pnpm qq:codex` 继续支持 `init`、`check`、`start`,以及 `--check`、`--check-qq` 和 `--config` / `--state` 启动参数。 此前生成的 `@el-bot/qq-codex` 安装包由统一的 `el-bot` 安装包替代;配置和状态路径不变,无需重新绑定。 配置优先级为显式 `--config`、当前目录 `.el-bot/qq-codex.json`、用户目录默认配置。 迁移前可运行 `paths` 核对实际路径;保持 `--state` 指向原状态即可沿用绑定和会话,不要删除状态来解决启动错误。 ### 常见连接问题 若 AccessToken 获取成功,但网关返回 `HTTP 401, code 11298`,表示调用机器的出口 IP 不在后台白名单。 添加该机器的出口 IPv4,保留仍在使用的服务器地址;更换网络后可能需要更新。 后台显示「在线」并不意味着当前电脑已有 API 访问权限。 新版后台的「查看 AppSecret」可能实际打开重置流程。重置会使旧密钥失效,影响已有服务;优先使用已保存的 AppSecret。 网关已连接但没有私聊事件时,检查后台是否仍为 Webhook、测试用户是否可添加机器人,以及绑定码是否过期。 ### 任务失败的诊断与恢复 任务失败后,QQ 会显示识别到的原因、错误类型和处理步骤。`/status` 与 `/result 任务ID` 可以再次查询;已产生的部分结果和失败类型保存在本机,重启后仍可查看。 失败卡片提供「连接诊断」;会话归档、丢失、目录变化或上下文不足时还提供绑定该任务项目的「新建会话」。也可发送 `/diagnose [项目]`。服务不可用时,停止进程后执行 `el-bot codex recover --project 名称`;使用 profile 时带上同一个 `--profile`,不会清除主人或重放任务。 | 错误类型 | 处理方式 | | --- | --- | | `authentication`:登录失效 | 在运行服务的电脑执行 `codex login`;profile 模式须设置对应 `CODEX_HOME`,完成后重启服务 | | `model`:模型不支持 | 运行 `el-bot codex check`,用检查建议的模型配置 `model`,再重启服务 | | `session-archived`:会话归档 | 发送 `/new` 后提交新任务;原会话和历史结果保留 | | `session-missing` / `project-changed`:会话或项目变化 | 核对原机器、账户与目录;需要新会话时发送 `/new` | | `quota` / `rate-limit`:额度或限流 | 检查账户额度与重置时间,或稍后重新提交 | | `context`:上下文或会话预算达到上限 | 保留必要背景,发送 `/new`,用较短提示开始 | | `network`:模型连接失败 | 检查本机网络、代理和模型服务 | | `timeout` / `connection`:本机连接不可用 | 检查 Codex 进程,重启遥控服务 | | `stop-unconfirmed`:无法确认命令终止 | 服务已停止接收新任务;在本机检查并结束该任务的命令进程,核对 Codex 终端控制接口支持后重启。不能将此状态视为命令已停止 | | `unknown`:未识别原因 | 运行 `el-bot codex check --all`,核对本机账户、模型与项目配置 | 登录信息可读取不代表访问令牌一定有效;切换 Codex 账户后,已有遥控进程可能仍持有旧凭据,需要重新登录并重启。 服务不会自动重试失败任务、切换模型或取消会话归档;由用户处理原因后重新提交。Codex 内部重试中的错误不会提前将任务标为失败。 QQ 报告使用固定的诊断文案,不转发上游原始错误、令牌、账户资料或本机路径。 ## QQ 命令 | 命令 | 作用 | | --- | --- | | 直接发送文字 | 在当前项目提交任务,继续上一次会话 | | `/run 提示词` | 明确提交提示词;可用于以 `/` 开头的内容 | | `/review [目标 JSON]` | 审查代码,默认审查未提交改动;也支持基线分支、提交或自定义要求 | | `/steer 提示词` | 向当前执行中的任务补充要求 | | `/projects [页码]` | 分页查看本地配置允许的项目,点击按钮切换 | | `/project 名称` | 切换项目,保留每个项目各自的会话 | | `/new [项目]` | 清除指定项目的续聊绑定,省略时使用当前项目;保留历史,下次任务新建会话 | | `/diagnose [项目]` | 只读检查会话归档、丢失和目录变化,不调用模型 | | `/status [页码]` | 查看当前任务、状态及待审批/待回答编号,长列表分页 | | `/stop [任务ID]` | 请求停止当前任务;指定 ID 时只停止对应任务,用 `/status` 确认最终状态 | | `/result [任务ID] [页码]` | 分页查看结果;不填任务 ID 时查看最近任务 | | `/approval ID [页码]` | 查看审批命令、文件变更或问题的完整详情 | | `/approve ID` | 批准这一条命令/文件变更请求 | | `/reject ID` | 拒绝该请求 | | `/answer ID {"问题ID":"回答"}` | 回答 Codex 的结构化问题,必须包含全部问题 ID | | `/help [分类] [页码]` / `/menu [分类] [页码]` | 打开分组帮助;图片模式支持分类内翻页;`/?`、`/帮助`、`/菜单` 也可使用 | | `/threads [游标]` / `/thread use ID` | 浏览当前项目会话,绑定已有会话 | | `/thread fork` | 复制当前会话历史并绑定新会话,不启动模型任务 | | `/models` / `/skills` / `/plugins` / `/mcp` | 浏览本机能力 | | `/api [前缀] [页码]` / `/rpc 方法 JSON` | 查阅本机版本目录,校验后调用协议 | | `/desktop projects` / `/desktop chats` / `/desktop tools` | 桌面宿主项目、聊天和工具目录 | | `/desktop schema 工具` / `/desktop call 工具 JSON` | 查阅参数,调用宿主工具 | | `/inspect ID [页码]` / `/confirm ID` / `/cancel ID` | 查看全部详情后确认一次管理写操作,或取消 | | `/manage-result ID [页码]` / `/events [页码]` | 查询管理结果和最近脱敏事件 | ### 帮助与快捷入口 绑定成功后自动展示帮助卡片;任务接收、状态、结果和审批卡片也都有「帮助菜单」按钮。 发送 `/help`、`/menu`、`/?`,或单独发送「帮助」「菜单」即可再次打开。帮助分为五类: - `/help 1`:任务与结果,包含输入任务、状态、结果和停止用法。 - `/help 2`:项目与会话,解释项目切换、续聊和新会话。 - `/help 3`:审批与回答,说明完整查看详情和单次处理流程。 - `/help 4`:API 与能力管理,包含版本目录、会话绑定和管理确认。 - `/help 5`:Codex Desktop 管理,包含桌面项目、聊天和工具入口。 图片模式每页最多展示四条命令,命令名、参数和说明使用不同样式;例如 `/help 1 2` 查看「任务与结果」第二页。按钮先在当前分类内翻页,再进入下一分类,分类编号保持不变。Markdown / 纯文本模式每类展示完整命令列表。 前三类提供「输入任务」「任务状态」「最近结果」「选择项目」「新建会话」按钮,以及文档链接;管理类提供 API 和桌面列表入口。 「输入任务」将 `/run ` 填入草稿,补齐后自行发送;「新建会话」先弹出确认,执行 `/new` 后下一条任务才创建会话,历史结果保留。 `/projects` 每页展示最多四个项目及对应按钮;名称较长时按钮文字会缩短,正文保留完整名称,可手动发送 `/project 完整名称`。 未知的斜杠命令会返回帮助卡片,不提交模型任务。中文「帮助」「菜单」只有独立成句时作为命令,诸如「帮助 修复测试」仍是任务提示。 帮助和项目浏览不依赖正在运行的模型任务,Codex 断开时仍可查询;切换项目和新建会话仍受单任务限制。 没有富文本或按钮权限时,同一页的文字指令保留,仍可手动操作。 「文档站点」打开 [el-bot 文档首页](https://docs.bot.elpsy.cn/);「使用帮助」打开[完整 QQ 命令说明](https://docs.bot.elpsy.cn/development/codex-remote#qq-%E5%91%BD%E4%BB%A4)。 卡片正文同时提供这两个链接与 [AI 接入指南](https://docs.bot.elpsy.cn/codex/ai-setup),纯文本回退保留完整网址。 链接按钮使用[官方消息按钮](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/trans/msg-btn.html)的跳转类型,直接打开网页,不发送 QQ 指令、不启动 Codex 任务。 目的地址为固定 HTTPS 文档网址,不附带用户、项目、任务或本机路径信息;模型输出中的网址仍按原文转义显示,不生成链接按钮。 新的 Codex 帮助、AI 接入和 Desktop 管理页面需部署文档后才会在线生效。部署前可以使用卡片内的五页命令帮助,或阅读仓库中的对应 Markdown。 示例: ```text /project el-bot 检查最近的变更,修复类型错误并运行测试 /status /approval a1b2c3d4 2 /approve a1b2c3d4 /result e5f6a7b8 2 ``` 同一服务只运行一个任务。任务进行中,新提示词会提示忙碌;查询、回答、审批和停止仍可使用。 项目目录发生变化后,先使用 `/new`,避免把旧会话恢复到不同目录。 ## Markdown 卡片与操作按钮 默认使用官方 C2C 的自定义 Markdown 和内联键盘:帮助、项目选择、任务接收、任务状态、结果和审批详情都有标题、正文与操作按钮。 QQ 官方于 2026-04-23 向所有机器人开放单聊与群聊自定义 Markdown;本应用当前使用单聊。 协议见[官方 Markdown 文档](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/type/markdown.html)和[发送单聊消息 API](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_openid_messages.post.html)。 | 卡片 | 操作 | | --- | --- | | 帮助菜单 | 翻页、输入任务、任务状态、最近结果、选择项目、新建会话、文档站点、使用帮助 | | 项目选择 | 翻页、点选项目、帮助菜单 | | 任务已接收 / 执行中 | 刷新状态、查看结果、停止当前任务、帮助菜单 | | 已完成 / 中断 / 失败 | 查看结果、刷新状态、填写下一条任务、帮助菜单 | | 多页结果或状态 | 上一页、下一页 | | 审批详情 | 上一页、下一页、拒绝请求、帮助菜单;全部详情送达后才显示批准本次 | | 结构化问题 | 填写回答,将 `/answer ID ` 放入输入框后自行补齐 JSON;帮助菜单 | 指令按钮发送与手动输入相同的 QQ 指令,仍经过本人校验、去重和单次审批。文档链接按钮直接打开网页。停止按钮绑定具体任务 ID,旧卡片不会误停新任务;批准请求过期或已处理后,旧按钮无效。 单聊按钮使用 `action.permission.type: 2`,由服务端根据事件中的 `author.user_openid` 校验绑定人。C2C 的 `user_openid` 不能作为客户端 `specify_user_ids` 的用户 ID 使用,否则手机 QQ 可能提示「无权限操作」,指令不会发出。更新并重启服务后,手动发送 `/help` 或 `/status` 获取新卡片;旧卡片的按钮权限不会随服务更新。 「输入任务」只填入 `/run `,不会自动开始执行。停止和批准带确认提示,服务端仍校验任务或请求是否有效。 卡片展示发送时的快照,点击「刷新状态」会发送新的卡片。任务输出和审批参数以转义后的引用正文显示,保留原文,避免输出中的链接、图片或伪造按钮被当成操作;分页不会丢失文字或拆坏 Unicode 字符。 每张卡片同时提供文字指令,便于不支持按钮的客户端使用。 若 QQ API 明确拒绝 Markdown 或按钮格式,当前进程会逐级改用「无按钮 Markdown → 纯文本」。每次尝试使用新的 `msg_seq`,仍计入同一输入最多 4 次回复的额度。 网络超时、额度限制、内容审核或未知错误不会自动重发;结果保留在本地,可发送新的 `/result` 查询。审批详情只有发送成功后才计入已查看页。 ### 色彩与高亮 正文使用官方支持的标题、加粗、引用和分隔线。项目、任务编号及审批范围加粗显示,结果正文和操作指令分区。 ⏳ 启动中、🔵 执行中、✅ 已完成、⏹️ 已中断、🔴 失败、🟡 待处理均保留文字说明,颜色只辅助识别。 按钮按官方 `render_data.style` 区分主次:蓝色线框(`1`)用于主要操作,灰色线框(`0`)用于辅助查询,白底红字(`3`)用于停止或拒绝。 官方还提供蓝底白字(`4`)样式,见[发送单聊消息 API 的 RenderData](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_openid_messages.post.html)。 这些是客户端预置样式,无法指定任意 RGB 颜色;[官方 Markdown 支持格式](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/type/markdown.html)未提供正文文字颜色、背景色或 CSS 接口,也未承诺代码块语法高亮。 实际呈现由 QQ 客户端决定。本次 macOS QQ 联调中,彩色状态符号、加粗字段和蓝色线框按钮正常显示;API 接受了样式 `3` / `4`,但客户端仍把它们显示为灰色线框。因此主操作选择已验证的蓝色线框。文档展示图用于说明预置样式,不保证每个客户端呈现完全一致。 ### 图片卡片与本地预览 当前开发构建支持在[本机客户端](https://docs.bot.elpsy.cn/development/client-tool#图片展示与本机程序)选择是否展示图片,或执行 `el-bot codex preferences --message-format image --image-theme dark` 开启深色图片、`--message-format markdown` / `--message-format text` 关闭图片。设置写入当前实例配置,保留其他字段;等待任务完成后重启生效。此设置命令尚未包含在 npm `1.0.0-rc.2`。 图片模式在本机将帮助、项目、任务状态和结果卡片渲染成 PNG,支持浅色 / 深色主题及彩色状态条。帮助图片用高对比色突出命令,参数以较小字号显示,说明另起一行;提醒独立展示,图内不堆叠长网址。默认直接上传到 QQ,以富媒体消息展示图片,再发送一条带原生按钮的简短 Markdown 操作卡片;文字指令和文档链接保留为可复制、可点击内容。 审批和结构化问题详情继续使用原生 Markdown,确保完整内容可核对、可复制,图片加载失败不会影响审批详情的送达判断。管理 API 的文字结果也沿用原有分页。 先用包含 `render` 子命令的本地构建预览,不需要 QQ 凭据或 Codex 登录: ```bash el-bot codex render --card result --theme dark --output ./result.png el-bot codex render --card help --page 1 --output ./help.png el-bot codex render --card help --page 1 --part 2 --theme dark --output ./help-next.png el-bot codex render --card result --text-file ./result.txt --output ./result-preview.png ``` 输出为 PNG,已有文件不会被覆盖。帮助预览的 `--page` 指定分类,`--part` 指定分类内页码;`--part` 仅用于帮助卡片。`--font-file`、`--font-family` 可指定本机字体;Linux 主机需安装中文字体,例如 Noto Sans CJK,或提供对应字体文件。默认使用本机字体,不下载字体、不执行结果中的 HTML 或 Markdown 链接。 要在 QQ 中展示,将配置改为: ```json { "messageFormat": "image", "image": { "transport": "upload", "theme": "dark" } } ``` 此片段合并到已有配置,保留项目、传输方式、凭据和绑定。`theme` 可选 `light` / `dark`,默认 `light`;可额外配置 `fontFiles`(本地字体路径数组)和 `fontFamily`。 只设置 `"messageFormat": "image"` 也可启用默认的浅色上传模式。`image.transport: "upload"` 按官方流程调用 `upload_prepare`,将本地 PNG 分片 PUT 到 QQ 提供的预签名地址,再调用 `upload_part_finish` 和 `files` 完成上传。使用返回的 `file_info` 发送 `msg_type: 7` 图片,随后发送按钮与可复制指令。全程使用 `srv_send_msg: false`,不发送主动消息。每张卡片通常占用两次被动回复;剩余预算不足两次时改用原生 Markdown,不上传图片,总发送尝试仍不超过 4 次。接口见[单聊预上传](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_id_upload_prepare.post.html)、[分片完成](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_id_upload_part_finish.post.html)、[上传结果](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_openid_files.post.html)。 真实 QQ 联调已验证本地 PNG 上传、平台图片链接可读取及 macOS QQ 富媒体图片展示。当前接口返回从 `1` 开始的分片编号,SDK 同时兼容文档中的从 `0` 开始编号。此机器人使用 `raw_url` 嵌入 Markdown 时,转存校验返回 `40034141`(图片转存失败);富媒体消息接受键盘字段,但 macOS QQ 未展示按钮,所以直接上传模式分两条消息展示图片和操作卡片。`raw_url` 的有效期由平台决定,本次响应为 24 小时,不作为固定配置。 状态刷新和帮助翻页按钮也已通过 macOS QQ 实机验证。QQ 会把长图缩为缩略图,点击图片可放大查看;可复制指令和文档链接仍在图片后的操作卡片中。 上传模式不启动图片 HTTP 服务,也不接收 QQ 指令中的任意本地文件路径;只上传已经渲染的当前卡片。图片内容会传到 QQ 平台,临时链接有效期由响应 `ttl` 决定;不把预签名地址、`file_info` 或令牌写进运行日志、状态文件。每张 PNG 最大 2 MiB,高度最多 4000 像素,超限回退到 Markdown。链接过期后发送 `/status`、`/result` 或 `/help` 生成新图。使用 Webhook 接收事件时,事件入口仍需公网 HTTPS;WebSocket 接收加直接上传不需要入站公网端口。 如需自行托管图片,可使用以下可选配置: ```json { "messageFormat": "image", "webhookPort": 8788, "image": { "transport": "public", "publicBaseUrl": "https://bot.example.com/qq-codex/images", "theme": "dark" } } ``` 此模式在 `127.0.0.1:webhookPort` 提供 `/qq-codex/images/<随机编号>.png`,需 HTTPS 反向代理转发图片路径,按平台要求配置图片域名。只配置 `publicBaseUrl` 的旧配置自动选择 `public`,不会改变已有接入方式。代理应只开放所需路径,关闭访问日志和外部缓存。地址使用随机 192 位编号,10 分钟后过期,不包含用户、项目或任务 ID;缓存只在内存中保存,最多 64 张、16 MiB,达到上限时淘汰旧图,退出清除。图片包含任务内容,持有链接即可读取。 `el-bot codex check` 只验证本机 PNG 渲染,不上传或发送图片。公网托管模式仍需验证反向代理与 Markdown 转存;它在一条 Markdown 消息中展示图片和按钮,并设置 `force_verify_image_resource: true`。API 成功响应不能保证所有客户端呈现一致。 渲染、上传失败时,在发送前回退为 Markdown,不消耗回复序号。平台明确拒绝富媒体图片时回退到原生 Markdown;明确拒绝 Markdown 格式时逐级尝试无按钮 Markdown、纯文本。公网图片模式也可降级为无按钮图片;转存校验明确失败时跳过图片,直接使用 Markdown。所有尝试共享既有的 4 次被动回复预算;网络超时、额度、内容审核和未知发送错误仍不自动重发。默认 Markdown 模式不启动图片 HTTP 服务。 ### 可以在频道使用吗? **QQ 官方频道支持消息收发;当前 `el-bot codex` 遥控仍只接入本人 C2C 私聊,不能直接在频道遥控。** 频道支持纯文本、Embed 和 Markdown 等消息,但自定义 Markdown 目前需要内邀开通,和已向所有机器人开放的单聊 / 群聊不同。 参考[各场景支持情况](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/type/overview.html)与[Markdown 能力说明](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/message/type/markdown.html)。 频道接入需要处理 `AT_MESSAGE_CREATE`(`PUBLIC_GUILD_MESSAGES`),并通过 `/channels/{channel_id}/messages` 回传结果。 频道用户使用 `author.id`,不能把已有 C2C `user_openid` 绑定直接用于频道;必须建立独立的本人身份校验和频道 / 子频道白名单。 官方按钮的 `enter` 自动发送能力仅适用于单聊,频道的指令按钮需用户检查输入后发送。 协议见[频道消息事件](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/channel/message/event.html)与[发送子频道消息](https://bot.q.qq.com/wiki/develop/api-v2/server-inter/channel/message/send.html)。 频道被动回复有效期为 5 分钟,长任务需要用户重新查询结果,不能照搬 C2C 的回复窗口。 频道成员可能看见任务输出与审批详情。建议先在仅本人可见的文字子频道验证;不要通过复用私聊绑定或默认接受全频道消息来接入本机执行。 ## 执行与审批 Codex 使用 `workspace-write` 沙箱、`on-request` 审批策略和用户审批者,默认不允许工具联网。 这允许 Codex 在选定项目中编辑文件;需要升级权限的执行会转发到 QQ,由绑定人决定。 项目白名单约束任务工作目录,读取范围仍由 Codex 的沙箱实现决定。 应用展示审批参数及已收到的文件变更详情。长内容分多页,查看全部页后才能 `/approve`。 审批有 10 分钟有效期,只批准单次请求,不设置“本会话全部同意”,不写入长期授权规则。 停止任务会拒绝未处理的请求。暂不支持的额外权限请求、MCP elicitation 和未知工具请求会被拒绝,不会自动放行。 `/stop` 在任务启动阶段也有效;如果正在等待 `thread/start`,完成握手后不会再提交提示词。 RC.2 在中断轮次后,按当前任务的命令编号列出并终止仍运行的终端,确认它们不再运行后才报告「已中断」。等待确认期间不接收新任务;确认失败则返回 `stop-unconfirmed` 并暂停执行入口,不清理其他任务的终端。 此停止逻辑内部使用 `thread/backgroundTerminals/list` 与 `thread/backgroundTerminals/terminate`,已在 Codex CLI 0.154.0 验证。它需要在握手中启用实验协议能力,但不会因此开放通用实验管理 API;后者仍要求显式配置 `experimentalApi`。宿主不支持终端控制时,停止会明确失败。该确认覆盖 Codex 跟踪的命令终端,不能保证停止命令自行分离或转交给外部服务的工作。 Codex 进程退出或请求超时后,服务停止接收新的执行任务,仍允许查询已有结果。修复本机配置并重启后再继续。 ## 消息、状态与重启 - QQ 回复使用 `msg_id + msg_seq`;应用最多回复同一条私聊消息 4 次,超过有效期或额度后保留结果供查询。 - 不逐 token 刷屏。默认发送接收卡片、审批卡片和最终结果;发送 `/status` 或 `/result` 可使用新的回复窗口。 - 输出按 UTF-8 字节分页,保存最近 20 个任务,每个任务最多保留最后 100,000 个字符。完整工具记录仍由本地 Codex 会话管理。 - 状态默认位于 `~/.el-bot/qq-codex-state.json`,包含绑定人、项目会话、去重记录和任务结果;文件权限为 `0600`(支持 POSIX 权限的平台)。 - 状态文件使用临时文件替换和单实例锁。不要把状态放在公开目录或允许 Codex 随意写入的项目内。 - 消息执行前先保存去重记录;平台重发不会重复启动同一任务。超过 5 分钟的历史输入不会提交为新任务。 - 进程重启会将未结束任务标为中断,**不会自动重放提示词**。查看工作区后发送新任务即可恢复绑定的会话。 - 极端断电发生在记录与执行之间时,任务可能没有开始;不会为了补偿而自动重复执行。 正常使用 Ctrl+C / SIGTERM 退出会停止接收消息、中断 Codex 并释放锁。 异常崩溃留下 `.lock` 时,先读取其中 PID,确认该进程不再运行,再手动移除锁文件。 ## WebSocket 与 Webhook 默认 `websocket` 通过 `/gateway` 取得网关地址,订阅 `GROUP_AND_C2C_EVENT`,只分派私聊文本。 实现包含心跳确认、退避重连、会话恢复和无效会话后的重新鉴权,不需要公网入站端口。 个人遥控自己的电脑,建议使用 WebSocket。电脑主动建立连接,Codex 在本机运行,无需额外部署公网回调服务。 在 QQ 后台「开发设置 → 事件订阅与回调」中也要选择 **WebSocket** 并应用切换。 仅修改本地 `transport` 不会切换平台的推送方式;网关鉴权成功也不能单独证明消息事件已送到本机。 如果机器人原本使用 Webhook,切换会改变现有服务的事件接收路径,应先确认旧服务的用途。 面向多用户、运行在常驻服务器上的机器人,可以选择 Webhook,便于复用 HTTPS 服务的部署与监控。 如果 Codex 仍在个人电脑上,Webhook 接入服务器还需要维护到本机的可靠连接,不能直接替代本地执行进程。 无论使用哪种方式,本机服务停止、电脑休眠或网络中断时,都无法继续处理遥控任务。 如果机器人后台要求使用 Webhook,修改配置: ```json { "projects": { "el-bot": "/absolute/path/to/el-bot" }, "transport": "webhook", "webhookPort": 8788 } ``` 服务只监听 `127.0.0.1:8788/qq/events`。使用自己的 HTTPS 反向代理/隧道暴露这个路径, 在 QQ 后台填写对应 HTTPS 回调地址并订阅单聊事件。 应用校验 AppID、时间戳和原始请求体的 Ed25519 签名,支持平台回调挑战;无有效签名的请求不会触发任务。 状态保存后即完成入站处理,Codex 执行及 QQ 回复在后台继续,不等待长任务完成才返回回调确认。 ## 包结构与验证 ```text QQ 官方 API / Gateway / Webhook → packages/qq-sdk → apps/qq-codex(绑定、命令、状态、审批) → packages/codex(app-server stdio) → 本机 Codex 与选定项目 ``` ```bash pnpm build pnpm typecheck pnpm typecheck:packages pnpm test pnpm lint pnpm docs:build ``` 测试使用本地 HTTP/WebSocket 服务、签名请求和模拟 JSONL 子进程,覆盖凭据刷新、重连、消息去重、 鉴权、审批、停止、崩溃与持久化。真实 QQ 联调还需要你自己的机器人凭据、后台权限和测试 QQ。 单独通过 `--check` 只代表本机 Codex 可通信,不代表 QQ 权限已经开通。 ### 真实 API 联调记录 2026-10-05 使用自有 QQ 官方机器人、QQ 桌面客户端与本机 Codex 完成了以下验证: - 使用已有 AppSecret 获取 AccessToken,配置出口 IP 白名单后成功获取网关地址。 - WebSocket 鉴权及本人私聊绑定成功,QQ 客户端收到官方 API 发出的绑定回复。 - 从 QQ 下发任务,在独立测试目录实际创建、读取标记文件,并收到 `QQ_CODEX_E2E_OK`。 - 使用 `/result` 查询结果,并在同一 Codex 会话继续任务,收到 `QQ_CODEX_RESUME_OK`。 - 升级后在 QQ 桌面客户端实际收到任务状态 / 结果 Markdown 卡片,点击「查看结果」「刷新状态」成功返回对应卡片;「输入任务」只填入草稿,没有自动执行。 - 核对括号、下划线与 Windows 路径显示,使用字符实体避免 QQ 将反斜杠括号识别为公式。 此记录验证了 WebSocket 收发和本地执行链路。Webhook、公网部署和需要审批的真实操作未包含在这次联调中; 自动化测试中的模拟验证不能替代相应环境的验收。凭据、OpenID 和会话状态仅保存在本机,不纳入仓库。 ## 社区项目参考 调研日期:2026-10-05。以下为仓库文档核对,未使用真实 QQ 账号验证;当前实现独立编写。 | 项目 | 接入路线 | 可借鉴内容 | | --- | --- | --- | | [qq-codex-bridge](https://github.com/983033995/qq-codex-bridge) | QQ 官方机器人 → 本地服务 → CDP → Codex Desktop | 桌面会话绑定、QQ 消息与媒体处理;仓库为 MIT 许可证 | | [codex-qq-bot](https://github.com/gl813788-byte/codex-qq-bot) | QQ / OneBot → 本地 Codex CLI 助手 | 会话管理与控制面板;未确认许可证,不复制实现 | 协议参考:[Codex app-server](https://learn.chatgpt.com/docs/app-server)、 [QQ API 调用](https://bot.q.qq.com/wiki/develop/api-v2/dev-prepare/interface-framework/api-use.html)、 [事件订阅](https://bot.q.qq.com/wiki/develop/api-v2/dev-prepare/interface-framework/event-emit.html)、 [单聊发送](https://bot.q.qq.com/wiki/develop/api-v2/autogen/api/v2_users_user_openid_messages.post.html)、 [回调签名](https://bot.q.qq.com/wiki/develop/api-v2/dev-prepare/interface-framework/sign.html)。 --- Source: https://docs.bot.elpsy.cn/ai/codex/desktop.md # 从 QQ 管理 Codex Desktop > **RC 中的实验功能** Desktop 宿主和共享后端管理属于显式启用的实验功能,不计入基础 C2C 遥控的稳定性承诺。 首次接入以当前安装版本的 `desktop-check` 和真实只读列表为准;尚未完成宿主联调的配置不能仅凭自动化测试宣布可用。 接入桌面适配器后,可以在 QQ 查看 Codex Desktop 的项目、聊天与工具目录,调用宿主提供的聊天、侧栏、工作树、插件和自动化工具。宿主目录会随安装版本变化;`/desktop tools` 是当前可用范围的依据。 ## 两个接入层 | 接入层 | 用途 | | --- | --- | | app-server | 项目与会话协议、模型、Skills、MCP、插件、配置和事件 | | Desktop 宿主 | 桌面项目、聊天、侧栏、工作树、插件和自动化等宿主工具 | app-server 的目录与协议功能使用 `management.enabled`、`experimentalApi` 配置;Desktop 宿主使用 `desktop.server`、`pipePath`、`threadId` 配置。 `/projects` 继续表示 el-bot 配置中的可执行项目白名单。`/desktop projects` 调用宿主的 `list_projects`,显示桌面项目。浏览桌面项目不会自动将目录加入执行白名单。 app-server 的 `project/list` 与桌面宿主的 `list_projects` 属于不同接口。它们返回的项目是否一致,取决于 Desktop 使用的后端、版本和数据源。不得把会话中的 `cwd` 去重结果称为完整桌面项目列表。 ## 本机准备 先完成[QQ 绑定和基础接入](https://docs.bot.elpsy.cn/development/codex-remote)。桌面应用需要保持运行,并提供其随应用分发的 `codex-app-tools/server.mjs` 以及 `CODEX_APP_TOOLS_PIPE_PATH` 管道。选择一个已有桌面聊天,作为管理工具调用的专用上下文。 ```bash el-bot codex desktop-init \ --thread-id <专用桌面聊天ID> \ --pipe-path <运行中宿主提供的绝对管道路径> el-bot codex desktop-check el-bot codex start ``` `desktop-init` 保留已有项目、模型、凭据和绑定;已有 `desktop` 配置时拒绝覆盖。默认定位已安装的适配器,也可用 `--server /absolute/path/to/server.mjs` 指定。所有命令支持既有的 `--config`、`--credentials` 和 `--state` 参数。 `desktop-check` 只调用工具目录和项目列表,不创建聊天、不启动模型任务、不发送 QQ 消息。它同时验证宿主可达性和专用聊天的工具调用权限。 > **宿主接入条件** 桌面适配器依赖运行中的宿主管道,是随 Codex 应用分发的能力,尚无可承诺跨版本稳定性的外部 Desktop SDK。若当前运行环境没有提供管道路径,应停在基础 app-server 接入;程序不会扫描、猜测管道或伪造宿主身份。仅找到适配器文件不代表已成功连接 Desktop。 ## 共享 app-server 默认 `codexConnection: "stdio"` 创建自己的 app-server。要连接已有后端,可配置: ```json { "codexConnection": "desktop", "codexSocket": "/absolute/path/to/app-server-control.sock", "experimentalApi": true, "management": { "enabled": true, "allowedMethods": [] } } ``` `desktop` 连接模式运行 `codex app-server proxy`;省略 `codexSocket` 使用 CLI 的默认控制套接字。它连接已经运行的后端,不会自行启动或重启 daemon。仅当 Desktop 也连接该后端时,两者共享正在加载的会话;不要把同一账户等同于同一运行进程。 服务退出只终止自己的代理进程,不停止共享 daemon。标准任务继续使用当前项目、单任务准入和原有执行审批。用 `/threads` 浏览当前项目会话,`/thread use ID` 绑定已有会话,再直接发送任务续聊。 ## QQ 命令 | 命令 | 功能 | | --- | --- | | `/desktop projects` | 桌面宿主项目列表 | | `/desktop chats` | 桌面聊天、固定项和侧栏信息 | | `/desktop tools [页码]` | 当前宿主工具目录 | | `/desktop schema 工具 [页码]` | 工具说明和输入 schema | | `/desktop call 工具 JSON` | 校验参数后调用宿主工具;写操作先生成待确认请求 | | `/api [方法前缀] [页码]` | 当前 CLI 版本生成的 app-server 方法目录 | | `/api schema 方法 [页码]` | 方法参数定义 | | `/api type 类型名 [页码]` | 查看参数中 `$ref` 引用的类型 | | `/rpc 方法 JSON` | 调用该版本提供的协议方法 | | `/models`、`/skills`、`/plugins`、`/mcp` | 浏览模型、技能、插件和 MCP 状态 | | `/threads [游标]` | 当前执行项目的会话列表 | | `/thread use ID` | 绑定当前白名单项目的已有会话 | | `/thread fork` | 复制当前会话历史,绑定新会话;不启动模型任务 | | `/review [目标 JSON]` | 代码审查,默认审查未提交改动;沿用任务审批和结果机制 | | `/steer 提示词` | 向当前执行中的任务补充要求 | | `/events [页码]` | 最近 50 条脱敏 app-server 通知 | | `/inspect ID [页码]` | 查看待确认管理操作全部详情 | | `/confirm ID`、`/cancel ID` | 执行一次管理操作或取消 | | `/manage-result ID [页码]` | 查询最近管理结果 | 这些目录命令与参数 schema 来自实际安装版本,不维护一个宣称永远完整的静态 API 清单。本机 CLI 也可以独立生成协议目录: ```bash el-bot codex api --experimental el-bot codex api --experimental --method project/list ``` 后一条同时输出引用类型,可用于查阅复杂参数。生成 schema 不运行模型;需要与运行后端匹配的 CLI 版本。`experimentalApi: true` 只开启协议协商,不会安装插件、授予宿主权限或保证实验功能可用。官方把部分插件管理 API 标为开发中,生产使用需要自行评估当前版本。 ## 管理操作示例 先浏览工具和参数,再发出具体调用: ```text /desktop projects /desktop chats /desktop schema set_thread_title /desktop call set_thread_title {"threadId":"目标聊天ID","title":"新标题"} /inspect 返回的请求ID /confirm 返回的请求ID ``` 聊天归档、固定、侧栏移动、工作树操作、插件管理和自动化使用相同流程。具体工具名及参数以 `/desktop tools` 和 `/desktop schema` 为准;没有出现在目录中的功能不会被伪装成可调用接口。 对于 app-server,例如归档当前项目的一条会话: ```text /api schema thread/archive /rpc thread/archive {"threadId":"当前项目会话ID"} /inspect 返回的请求ID /confirm 返回的请求ID ``` ## 权限与执行边界 所有命令先经过本人绑定、消息去重和持久化检查。已知只读查询直接执行;其他操作全部先展示详情,只有成功送达全部详情页后,才接受同一个请求 ID 的确认。请求 10 分钟过期,不跨进程恢复。失败、超时、重复按钮和断线不会自动重放写操作。 管理写操作与标准任务互斥;待确认时不能启动另一条标准任务。管理结果最多缓存最近 20 次,每次最多 100000 个字符,单条 QQ 消息按字节分页;进程退出后不保留这些管理结果。原有标准任务结果仍按既有状态机制保存。 `/rpc` 对已提供的线程 ID 读取并核验工作目录,对文件路径进行绝对路径与符号链接校验;会话浏览限当前项目。文件创建、删除、复制等路径必须落在执行项目白名单内。桌面工具的路径参数同样校验;无本机路径的聊天、侧栏等管理工具仍由宿主执行自己的访问检查。 模型任务的 `thread/start`、`thread/resume`、`thread/fork`、`turn/start`、`turn/steer`、`review/start` 不通过通用 `/rpc` 旁路启动;使用 `/run`、`/thread use`、`/thread fork`、`/new`、`/review` 和 `/steer`,保持单任务管理。实时音频会话和服务端任务队列暂未接入该任务机制,`thread/realtime/start`、`thread/queue/start` 不接受通用调用。账户登录、退出、配置写入、进程执行及其他特殊接口需在本机 `management.allowedMethods` 中明确许可,许可后仍逐次确认。不要为方便而批量打开特殊权限。 审查可指定目标,例如 `/review {"type":"baseBranch","branch":"main"}`、`/review {"type":"commit","sha":"提交ID"}` 或 `/review {"type":"custom","instructions":"检查鉴权边界"}`。运行中的审查同样支持 `/status`、`/stop` 和 `/result`。 工具调用始终携带配置的真实桌面聊天 ID,并由随应用提供的 MCP 适配器转交宿主。不绕过宿主的审批、账户访问或插件权限。QQ 显示的结果隐藏已识别的凭据、环境变量和本机路径;应避免让工具生成或回传私密资料。 ## 验证范围 自动化测试使用本地协议和 MCP fixture 验证目录发现、schema 校验、聊天元数据、凭据隔离、审批送达、单次执行、项目路径与符号链接边界。基础 QQ 链路的真实联调记录仍见[接入文档](https://docs.bot.elpsy.cn/development/codex-remote#真实-api-联调记录)。这些测试不代表已完成真实 Desktop 宿主联调;本机接入必须以 `desktop-check` 成功及实际只读列表为准。 协议参考:[OpenAI Docs:Codex App Server](https://learn.chatgpt.com/docs/app-server)。 --- Source: https://docs.bot.elpsy.cn/ai/codex/instances.md # 实例隔离与恢复 无需 YunLeFun 账户或额外控制台。QQ 官方 AppID / AppSecret 用于机器人鉴权,本机 Codex 登录用于模型访问;首次 `/pair` 将遥控权限限定到自己的 QQ。已有本人绑定会在重启后保留。 ## 创建独立实例 每个机器人或环境使用一个名称,例如 `personal`、`test`。名称只允许小写字母、数字、下划线和短横线,最长 64 个字符。 ```bash pnpm add -g el-bot@next el-bot codex --profile personal init --project /absolute/path/to/my-project --name my-project el-bot codex --profile personal paths ``` | 内容 | personal 实例的默认路径 | | --- | --- | | 配置 | `~/.el-bot/codex/personal/config.json` | | QQ 凭据 | `~/.el-bot/codex/personal/credentials.env` | | 绑定、任务和会话索引 | `~/.el-bot/codex/personal/state.json` | | Codex 账户配置与会话 | `~/.el-bot/codex/personal/codex/` | 新 profile 使用独立 `CODEX_HOME`,需要在该目录登录 Codex。请使用 `paths` 显示的绝对路径;以下是 macOS / Linux 示例: ```bash CODEX_HOME="$HOME/.el-bot/codex/personal/codex" codex login el-bot codex --profile personal check --all el-bot codex --profile personal check --all --json el-bot codex --profile personal start ``` Windows PowerShell 先设置 `$env:CODEX_HOME` 为 `paths` 的 `codexHome`,再执行 `codex login`。不要复制或上传另一个实例的登录文件。 初始化、检查、恢复和启动都应传入相同的 `--profile`。首启后把终端显示的 `/pair` 绑定码私聊发给机器人,后续启动无需重复绑定。 profile 的配置、凭据和状态目录独立,Codex 子进程也不会默认继承宿主的 `OPENAI_API_KEY` 等提供方密钥。需要自定义服务环境变量时,在配置中用 `codexEnvAllowlist` 指定变量名,例如 `["OPENAI_API_KEY"]`,由运行服务的环境提供值。平台运行变量、语言和代理设置继续可用;`QQ_BOT_*` 始终不传给 Codex。 这是账户和文件布局隔离,同一系统用户仍可访问这些目录;它不是容器或操作系统权限边界。 ## 自动校验机器人与环境 首次启动会将状态固定到 AppID、QQ 测试环境 `sandbox`、profile 名称和 Codex 目录,无需另一次绑定操作。之后误用另一机器人的凭据、测试环境或 Codex 目录会在连接前报错,保留原绑定和历史。 旧版状态没有 AppID 元数据。升级后首次启动使用当次本机凭据接管,先生成 `state.json.before-instance.json` 私有备份,再保存元数据;它无法推断旧状态原本属于哪个 AppID。升级前请用 `paths` 核对原文件并确认凭据属于原机器人,不要删除状态来绕过检查。 显式 `--credentials` 或 `--profile` 只读取指定实例的凭据文件,不接受环境变量覆盖,也不回退到当前目录 `.env`。AppID 和 AppSecret 必须来自同一个来源,缺少其中之一就报错。 默认模式继续按「完整进程环境 → 默认凭据文件 → 当前目录 `.env`」读取,任何来源只有半套凭据时都不会与另一个来源拼接。 未指定 profile 时,旧配置、凭据和状态路径继续有效,Codex 沿用本机目录,已有绑定无需迁移。仅更换 `--config` 不会自动隔离凭据和状态;建议新实例使用 profile。 如果要保留原 Codex 目录,也可以显式使用三组独立路径:`--config`、`--credentials`、`--state`。不要让多个进程共享状态文件。 ## 归档检测与连接诊断 ```bash el-bot codex --profile personal check --all ``` 检查会读取会话并分页查询归档列表,区分可续聊、已归档、丢失和项目路径变化。启动时提示不可续聊的项目,但保留 QQ 查询与恢复入口;每次续聊前再次检查,不会自动取消归档或重放任务。 在 QQ 中发送 `/diagnose [项目]`,可以只读查询对应项目的会话状态,不调用模型。连接断开时,会提示在本机检查和重启。 `check --all` 另外验证本机账户、模型预检、QQ 鉴权和网关访问;它不启动模型任务或 QQ 长连接。最终是否接通仍需用户在 QQ 发送测试任务并收到结果。 检查会汇总各项结果:归档会话或本机 Codex 失败不会遮住独立的 QQ 检查;AppID / 环境身份不匹配则阻止连接。 `PASS` 表示预检通过,`FAIL` 表示需要处理,`SKIP` 表示前置条件不满足。任一失败的退出码为 `1`。 `--json` 输出 `version`、`ok` 和 `checks`;每项包含 `id`、`status`、`summary`,失败时提供 `actions`。 修复命令保留本次 profile 和配置 / 凭据 / 状态路径,适合交给 AI 继续排错。报告不包含密钥、主人 ID、会话 ID 或原始服务端错误;本机路径仍应视为私人信息。 只有显式运行 `recover` 才改变续聊索引;诊断不会重置绑定、自动取消归档或重试任务。 ## 明确恢复,不丢历史 失败卡片按原因提供「连接诊断」「新建会话」按钮。新建按钮绑定失败任务所属的项目,避免切换项目后误改当前项目。 - 服务在线:发送 `/new my-project`,清除该项目的续聊索引;省略项目时使用当前项目。 - 服务不可用:先停止进程,再在本机运行 `el-bot codex --profile personal recover --project my-project`。 - 想沿用已有会话:核对原账户、目录和归档状态后,使用 `/thread use 会话ID`。归档会话须由用户明确取消归档后再绑定。 本机 `recover` 会先备份原状态并检查实例身份和状态锁,只清除指定项目的续聊绑定。本人绑定、其他项目、任务结果、消息去重记录和原 Codex 会话都保留。 恢复命令不连接 QQ、不启动模型,也不自动重试失败任务;下一条用户任务才创建新会话。备份文件含私人会话信息,勿提交到 Git 或上传。 ## 与 Desktop 连接的区别 `codexConnection: "desktop"` 使用桌面正在运行的后端,账户和会话目录由桌面决定,因此不支持 profile 的独立 Codex 目录。需要连接该后端时,使用独立 `--config`、`--credentials`、`--state` 隔离机器人数据,并遵循 [Desktop 接入](https://docs.bot.elpsy.cn/codex/desktop)。 默认 stdio 的 profile 可以单独配置桌面宿主工具;宿主工具仍操作桌面自己的账户与数据,其权限不受 profile 的 Codex 目录隔离。 --- Source: https://docs.bot.elpsy.cn/ai/codex/rc.md # RC 验收与支持范围 当前候选版本为 `1.0.0-rc.2`,发布到 npm `next`。测试时建议固定版本,便于记录与复现: ```bash pnpm add -g el-bot@1.0.0-rc.2 ``` RC 用于验证新用户安装和持续运行。基础范围是 QQ 官方 C2C 私聊与本机 stdio Codex:本人绑定、项目白名单、任务与结果、Markdown / 文字回复、审批与停止、实例隔离、连接诊断和明确恢复。 ## 安装与迁移 ```bash pnpm add -g el-bot@next el-bot --version el-bot codex --profile personal init --project /absolute/path/to/project el-bot codex --profile personal paths el-bot codex --profile personal check --all --json ``` 新 profile 在独立 Codex 目录登录;按检查报告的登录命令操作,AppSecret 只在本机填写。已有实例沿用原 profile 或三组显式路径,先检查再启动,不重复初始化、不清空状态。 完整步骤见[实例隔离与恢复](https://docs.bot.elpsy.cn/codex/instances)和[AI 接入](https://docs.bot.elpsy.cn/codex/ai-setup)。 库入口 `el-bot`、`el-bot/nest` 发布 ESM JavaScript 与类型声明,可由普通 Node.js 导入;旧框架启动器仍使用 Vite Node 加载 TypeScript 插件。 最低 Node.js 为 22.18.0,推荐仓库指定的 Node.js 24。发布流程先构建、安装和验证同一 tarball,再验证 Node.js 22.18.0 的 Linux / Windows / macOS 安装结果,最后执行 npm OIDC 发布。 ## 真实 QQ 验收 | 项目 | 操作与预期 | | --- | --- | | 首次接入 | 本人在私聊发送 `/pair`,重启后仍保持原绑定 | | 任务与结果 | 提交测试提示词,收到完成结果,`/result` 可再次查询 | | 审批同意 | 查看全部请求详情,确认明确的测试操作,只执行一次 | | 审批拒绝 | 拒绝测试操作;检查文件或命令确实没有执行 | | 停止 | 执行中 `/stop`,确认命令终止;等待超过原定运行时间,确认没有延迟文件写入。旧停止按钮不停止后来的任务 | | 重连与重启 | 网关断开后恢复;历史消息不重复启动任务,退出期间的任务不自动重放 | | 归档恢复 | `/diagnose` 明确报告归档;`/new` 或停机后的 `recover` 只清除指定项目索引,保留主人与历史 | | 多实例 | 两个 profile 的路径不同;错误 AppID / 环境 / Codex 目录被拒绝且原状态保留 | 自动化协议测试与真实 QQ / Codex 验收分别记录。`check --all` 通过只说明预检成功;有 QQ 返回结果才能确认端到端接通。 基础链路的已有记录见[真实 API 联调](https://docs.bot.elpsy.cn/development/codex-remote#真实-api-联调记录)。 ### RC.1 验证记录 2026-10-05 的本机验证使用同一候选 tarball: - 完整 lint、类型检查、构建、文档构建与 132 项测试通过。 - Node.js 22.18.0 与 24.18.0 的干净安装通过,包括库 / Nest 原生导入、严格 TypeScript 消费端检查、CLI、图片渲染与 JSON 诊断。 - 真实配置中的两个旧会话已归档;报告逐项标记失败,仍继续完成 QQ 鉴权与网关预检,返回非零退出码。 - 官方 QQ 网关已验证强制断线后恢复连接,两次收到就绪事件;该测试未发送 QQ 消息或提交模型任务。 - 已发布 tarball 的真实 QQ 任务完成并返回 `QQ_CODEX_RC_E2E_OK`;拒绝审批后,目标文件没有生成。 - 停止验收发现缺陷:QQ 报告中断后,原 shell 仍在 90 秒后写出了结束文件。RC.1 的停止验收失败,应升级 RC.2。此行为也见 [Codex 上游问题](https://github.com/openai/codex/issues/42717)。 ### RC.2 停止修复与验收 RC.2 在 `turn/interrupt` 后,只终止当前任务命令编号对应的 Codex 终端,并再次查询确认。确认失败时报告 `stop-unconfirmed`,暂停执行入口,保留历史查询;不会误清理其他任务的终端。详见[执行与审批](https://docs.bot.elpsy.cn/development/codex-remote#执行与审批)。 - 本地完整 lint、类型检查、构建与 135 项测试通过。新增回归测试覆盖延迟写入、保留其他终端、取消时命令到达的竞争和终止失败。 - 本机 Codex CLI 0.154.0 验证中断与终端终止,并观察超过原定命令时间,未产生延迟文件写入。 - 真实 QQ 停止验收通过:60 秒命令开始写入后发送 `/stop`,收到终止确认;观察 90 秒后,结束文件仍未生成。 - 停止旧服务、安装 RC.2 tarball、沿用同一状态文件启动后,QQ `/result` 返回原任务的 `QQ_CODEX_RC_E2E_OK`。主人绑定保留,原测试文件修改时间未变化,没有重放该任务。 - 单文件变更审批同意通过:QQ 查看全部两页,单次批准只新增一行 `QQ_CODEX_RC_FILE_APPROVED`。请求的 `grantRoot` 为空,没有授予目录权限;重复使用旧审批编号被拒绝。 - 命令审批拒绝通过:QQ `/reject` 后返回 `QQ_CODEX_RC_REJECTED`,目标文件不存在。待审批期间,旧任务的停止编号被拒绝,没有中断当前任务。 - RC.2 同版本正常退出、重启后,QQ 再次查询已批准任务并收到原结果;任务历史和主人绑定保留,已批准文件内容与修改时间均未变化。验收使用独立配置、项目与状态,原实例状态未被修改。 同意验收使用有限的单文件补丁;沙箱外 shell 命令的同意未执行,不能据此声称已验证该执行类型。所有实机记录使用 macOS QQ 与本机 Codex CLI 0.154.0。跨平台 CI 验证打包与协议测试,不代替其他系统上的真实 QQ 联调。 这些记录不代替 GitHub 发布门禁;发布任务还需安装同一 tarball,通过最低 Node.js 版本在 Linux / Windows / macOS 上的兼容性验证。 ## 实验与维护范围 - 默认 Markdown 保留复制和审批详情;图片模式只有完成当前机器人和 QQ 客户端的上传、展示、按钮与降级验证后,才能声明已接通。 - [Desktop 管理](https://docs.bot.elpsy.cn/codex/desktop)、共享 app-server 和实验 API 需要显式配置,依赖宿主版本,不计入基础遥控的稳定性承诺。 - 基础停止内部需要宿主支持实验终端控制协议,已测试 Codex CLI 0.154.0;不支持时明确失败。停止确认覆盖 Codex 跟踪的命令终端,不保证终止自行分离的进程或远程服务中的工作。 - 群聊、频道、后台服务自动安装与开机启动尚未纳入基础范围;电脑、网络和遥控进程需要持续可用。 - Mirai / NapCat 的旧框架与插件处于迁移维护阶段,编译后的库入口可用不代表所有旧插件已完成真实联调。剩余依赖告警与插件发布范围见[已知限制](https://docs.bot.elpsy.cn/development/monorepo#旧依赖的已知限制)。 ## 进入正式版 候选版发布到 npm `next`,正式版发布到 `latest`。完成支持范围内的真实验收、迁移验证和依赖风险说明后,再发布 `1.0.0`;实验功能仍保留显式标记。 不承诺原样重放失败任务、自动取消归档或自动扩大执行权限。 --- Source: https://docs.bot.elpsy.cn/ai/development/monorepo.md # Monorepo 开发 工程约定参考 [starter-monorepo](https://github.com/YunYouJun/starter-monorepo)。 使用 `.node-version` 指定的 Node.js 24 和 `packageManager` 固定的 pnpm 11.24.0。 ## 目录与职责 | 目录 | 用途 | | --- | --- | | `apps/qq-codex` | 私有 QQ 遥控实现模块,向统一 CLI 注册 `codex` 子命令 | | `packages/el-bot` | 机器人框架、Nest 适配器与统一 CLI,发布编译后的 ESM 和类型声明;旧启动器保留 TypeScript | | `packages/qq-sdk` | QQ 官方 API 和 webhook 验证,tsdown 构建 ESM 与类型声明 | | `packages/codex` | app-server / proxy、版本 schema 和 Desktop MCP 客户端 | | `packages/create-app` | 项目脚手架,tsdown 构建 Node CLI,随包携带模板 | | `packages/cli` | 旧版独立 CLI 草稿,尚未配置构建 | | `plugins/*` | 已有插件,保留各自的旧构建流程 | | `examples/*`、`demo` | 现有运行示例,需要自行配置机器人 | | `docs` | VitePress 文档站 | | `playground` | 预留的本地实验工作区 | `apps/*` 和 `playground` 已注册工作区。 `packages/@el-bot/plugin-niubi` 是同名旧副本,不注册到工作区。 ## 开发命令 ```bash pnpm install pnpm build # packages/* 与 apps/* 中声明了 build 的包 pnpm dev:lib # QQ SDK 与脚手架构建监听 pnpm test # 一次性执行测试,适用于 CI pnpm test:cli # 打包后在独立目录安装并验证 CLI pnpm cli codex --help # 统一 CLI 的源码入口 pnpm test:watch # 测试监听 pnpm lint pnpm typecheck # 全仓检查,包括旧插件与示例 pnpm typecheck:packages # 已声明独立类型检查的包 pnpm docs:dev pnpm docs:build pnpm docs:preview ``` `pnpm dev` 保留为 demo 开发入口;`pnpm dev:simple` 启动简单示例。 运行机器人需要配置 QQ/NapCat 连接,这些命令不属于无凭证工程验证。 CI 使用 `pnpm install --frozen-lockfile`,禁止在 CI 隐式改写锁文件。 ## 新增包 1. 在 `packages/` 创建 `package.json`、`src/index.ts`、`tsconfig.json` 和 `tsdown.config.ts`。 2. 继承根 `tsconfig.base.json`,为库生成类型声明,确保 `exports` 指向真实产物。 3. 外部依赖版本集中写入 `pnpm-workspace.yaml`,包内用 `catalog:`;内部包用 `workspace:*`。 4. 声明 `build`、`dev`、`typecheck`,需要发布时用 `prepack` 构建;新增测试放入包的 `test/` 或 `src/`。 5. 验证构建、类型检查、测试和发布包内容后再发布。 ## 依赖与兼容性 依赖版本集中在 catalog。Node.js 使用 24,TypeScript 保留 5.9,匹配 sagiri 和类型文档工具支持范围。此次检查中 TypeScript 最新版为 7,但 sagiri 仍要求 `^5.0.0`,TypeDoc 尚不支持 7;不强行跨主版本升级。 Chalk 升级为 6;`@types/node` 使用与 Node 24 对应的最新版本;c12 保留稳定版 3,避免将 RC 作为稳定更新引入。 `el-bot` 是 `el-bot` / `el` 可执行命令的唯一发布者,`apps/qq-codex` 保持私有。 CLI 将内部 Codex 客户端与 QQ 官方协议实现打包,第三方运行时依赖独立声明。 框架使用的工作区 `qq-sdk` 同样构建进发布包,由包内 `#qq-sdk` 映射引用,安装时不依赖 registry 中的同名版本。 `pnpm test:cli` 检查真实 tarball 安装、命令入口、非交互初始化、参数校验与凭据脱敏,CI 覆盖三个操作系统。 传入 `pnpm test:cli dist/el-bot-<版本>.tgz` 可验证已有安装包;发布工作流会测试并上传同一个文件。 库与插件统一使用 tsdown;旧 CLI 下载改用原生 fetch,移除 download 和闲置的 npm-run-all 依赖树。 文档已迁移到 VitePress 官方主题,使用本地搜索、当前导航配置和独立的 Vue 类型检查。 首页与 `/codex/` 展示 QQ 任务、审批和会话续聊;`/codex/ai-setup` 提供可复制的 AI 接入提示词。 `scripts/build-ai-docs.mjs` 在文档开发/构建前从当前 Markdown 生成 `llms.txt`、`llms-full.txt` 和 `/ai/` 下的原始 Markdown。 生成文件不提交 Git,由 VitePress 复制到站点产物;无需手工维护第二份指南。更新源文档后,重启开发服务器以刷新这些静态文件。 VitePress 固定为 `2.0.0-alpha.20`,与当前 Vite 8 配套;这是上游预览版,后续升级需重新验证文档构建。 2026-10-05 核对 npm dist-tags 与 [VitePress 官方文档](https://vitepress.dev/guide/getting-started):`next` 和官网均为 `2.0.0-alpha.20`,`latest` 稳定标签为 `1.6.4`。本仓库保留与最新版官网一致的预览版,并验证自定义组件、Vue 类型检查和站点构建。 选择这一版本也避免继续引用被 pnpm 信任策略拒绝的旧 Vite 5 依赖。没有关闭依赖信任检查。 全仓类型检查覆盖旧插件和示例。旧 Mirai 插件通过显式 `mirai: { qq, setting }` 配置连接, 未配置时给出明确错误;NapCat 是框架默认适配器。此次未将所有 Mirai 插件改写为 NapCat 插件。 QQ 遥控应用使用独立的官方协议实现,不加载这些旧插件。 旧模块仍依赖提升的依赖,因此暂时保留 `shamefullyHoist`。新包需完整声明自己的直接依赖。 ## npm OIDC 发布 统一 CLI 随 `el-bot` 发布,私有 `apps/qq-codex` 不单独发布。 `.github/workflows/release.yml` 使用 GitHub 托管的 Ubuntu runner,发布步骤通过 npm Trusted Publishing 获取临时凭据,不读取 `NPM_TOKEN`。 只有 `publish` job 拥有 `id-token: write`;构建与测试先完成,发布 job 下载通过验证的 `.tgz`,使用 npm 11.16.0 发布并附带 provenance。 先用 pnpm 打包,将 `catalog:` / `workspace:` 转为可安装的版本;不要在源码目录直接执行 `npm publish`。 ### 一次性配置 Trusted Publisher 在 [el-bot 的 npm 设置页](https://www.npmjs.com/package/el-bot/access) 添加 GitHub Actions Trusted Publisher: | 字段 | 值 | | --- | --- | | Organization or user | `YunYouJun` | | Repository | `el-bot` | | Workflow filename | `release.yml`,不要填写目录 | | Environment | 留空,当前 job 未设置 environment | | Allowed actions | 允许 `npm publish`,不能只允许 staged publishing | 也可以使用 npm CLI 11.15+,登录后先查看已有配置,避免重复创建: ```bash npm login --registry=https://registry.npmjs.org npm trust list el-bot # 仅在没有匹配配置时添加;按 npm 提示完成账户 2FA npm trust github el-bot --repo YunYouJun/el-bot --file release.yml --allow-publish ``` 配置以 npm 账户权限为准;GitHub 已登录不能代替 npm 登录。 确认一次真实 OIDC 发布成功后,再处理不再使用的旧发布令牌。 当前工作流不依赖令牌,但不会替你删除其他项目可能仍在使用的凭据。 2026-10-05 已在 npm 页面确认保存 `YunYouJun/el-bot` → `release.yml` 的 Trusted Publisher,允许 `npm publish`,Environment 留空。 授权配置已完成。标签触发后的实际结果以 [Release 工作流](https://github.com/YunYouJun/el-bot/actions/workflows/release.yml) 和 npm 对应版本的来源证明为准。 ### 每次发布 1. 提交并推送本次代码,确保默认分支 `dev` 的 CI 通过,且工作区干净。 2. 运行 `pnpm release`,在交互中选择尚未发布的版本;该命令只更新 `packages/el-bot/package.json`,生成 Conventional Commit、`v<版本>` 标签并推送。 3. 标签触发工作流:校验标签与包版本一致、确认 npm 不存在该版本,然后执行 lint、构建、类型检查、测试、文档构建和安装包测试。 4. prerelease 版本(例如 `1.0.0-rc.2`)发布到 `next`,正式版本发布到 `latest`;npm 发布成功后生成 GitHub Release。 本次版本为 `1.0.0-rc.2`,对应标签 `v1.0.0-rc.2` 和 npm `next`。已存在的 npm 版本不能覆盖,后续发布须选择新版本。 若其他包后续需要独立发布,应分别配置 Trusted Publisher 和版本流程;当前工作流只发布 `el-bot`。 本地可检查安装包,但不能证明 GitHub OIDC 已获 npm 授权: ```bash pnpm --filter el-bot pack --pack-destination ./dist pnpm test:cli dist/el-bot-<版本>.tgz npm publish ./dist/el-bot-<版本>.tgz --dry-run --access public --tag next --ignore-scripts ``` 只有真实 GitHub Actions 发布成功,并能在 registry 查询新版本,才算发布链路验证完成。 参考:[npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers/)、[npm trust](https://docs.npmjs.com/cli/v11/commands/npm-trust/)。 ### 旧依赖的已知限制 库与 Nest 入口编译为 ESM,并在真实安装后的消费者项目中执行导入和严格 TypeScript 检查。 `mirai-ts@2.4.8` 的导出路径与 tarball 不一致,NapCat 的 ESM 产物缺少 JSON import attribute,构建时将这两项运行代码打包以兼容普通 Node.js。 发布包同时携带公开声明所需的 `@types/ws`、`@types/node-schedule`,并按上游 Axios 定义补充 `resty-client@0.0.5` 漏发的两个类型;不关闭消费者类型检查。 本次升级固定了旧依赖链中可兼容升级的 `form-data`、`qs` 和 `js-yaml` 修复版。工作区的旧 `plugins/feeder` 仍使用停止维护的 `rss-feed-emitter` / `request`,存在 `request`、`tough-cookie`、`uuid` 上游告警;该插件不包含在本次 `el-bot` 发布包中。 旧框架的文件匹配依赖 `fast-glob` / `micromatch`,其 `braces` 依赖仍有[深层模式导致栈耗尽的告警](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm),截至本次发布没有上游修复版。勿将不可信输入直接用作文件匹配模式。Codex 遥控入口不使用该匹配链路;本次发布并不声明整个旧框架已清除全部审计告警。