# 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 遥控入口不使用该匹配链路;本次发布并不声明整个旧框架已清除全部审计告警。