chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
8339e19625
commit
d6887288d6
362
docs/zh-CN/ci.md
362
docs/zh-CN/ci.md
@ -1,94 +1,94 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要了解为什么某个 CI 作业运行了或没有运行
|
||||
- 你需要了解 CI 作业为什么运行或未运行
|
||||
- 你正在调试一个失败的 GitHub Actions 检查
|
||||
- 你正在协调一次发布验证运行或重新运行
|
||||
- 你正在更改 ClawSweeper 派发或 GitHub 活动转发
|
||||
summary: CI 作业图、范围门禁、发布总括流程和本地命令等价项
|
||||
- 你正在更改 ClawSweeper 调度或 GitHub 活动转发
|
||||
summary: CI 作业图、范围门禁、发布总控和本地命令等价项
|
||||
title: CI 流水线
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T17:33:44Z"
|
||||
generated_at: "2026-05-02T18:56:41Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 9ad5c8b39c21bf3fe6124c64938768efe4b77ef640e8207ef672a80c10291137
|
||||
source_hash: 8533e12d2ea99c6c342db46452bc448099c75e4bfc78edbb4b582118567421fd
|
||||
source_path: ci.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求时运行。`preflight` 作业会对差异进行分类,并在只有无关区域发生变更时关闭昂贵的通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为发布候选版本和广泛验证展开完整图谱。Android 通道通过 `include_android` 保持选择加入。仅发布用的插件覆盖范围位于单独的 [`插件预发布`](#plugin-prerelease) workflow 中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动 dispatch 运行。
|
||||
OpenClaw CI 会在每次推送到 `main` 以及每个拉取请求上运行。`preflight` 作业会对差异进行分类,并在仅有无关区域发生更改时关闭昂贵的通道。手动 `workflow_dispatch` 运行会有意绕过智能范围限定,并为候选发布版和广泛验证展开完整图。Android 通道通过 `include_android` 保持选择加入。仅发布相关的插件覆盖位于单独的 [`插件预发布`](#plugin-prerelease) 工作流中,并且只会从 [`完整发布验证`](#full-release-validation) 或显式手动分发运行。
|
||||
|
||||
## 流水线概览
|
||||
|
||||
| 作业 | 用途 | 运行时机 |
|
||||
| -------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `preflight` | 检测仅文档变更、变更范围、变更的扩展,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 检测私钥并审计 workflow | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm advisories 对生产 lockfile 执行无依赖审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `preflight` | 检测仅文档更改、已更改范围、已更改插件,并构建 CI 清单 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-scm-fast` | 通过 `zizmor` 检测私钥并审计工作流 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-dependency-audit` | 针对 npm 公告执行无依赖的生产锁文件审计 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `security-fast` | 快速安全作业的必需聚合 | 始终在非草稿推送和 PR 上运行 |
|
||||
| `check-dependencies` | 生产 Knip 仅依赖检查,加上未使用文件 allowlist 防护 | Node 相关变更 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用的下游产物 | Node 相关变更 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关变更 |
|
||||
| `checks-fast-contracts-channels` | 分片的渠道契约检查,并提供稳定的聚合检查结果 | Node 相关变更 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和扩展通道 | Node 相关变更 |
|
||||
| `check` | 分片的主要本地门禁等价项:生产类型、lint、防护、测试类型和严格 smoke | Node 相关变更 |
|
||||
| `check-additional` | 架构、边界、扩展表面防护、包边界和 gateway-watch 分片 | Node 相关变更 |
|
||||
| `build-smoke` | 已构建 CLI smoke 测试和启动内存 smoke | Node 相关变更 |
|
||||
| `checks` | 构建产物渠道测试的验证器 | Node 相关变更 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和 smoke 通道 | 发布用手动 CI dispatch |
|
||||
| `check-docs` | 文档格式化、lint 和断链检查 | 文档已变更 |
|
||||
| `skills-python` | 面向 Python 支持的 Skills 的 Ruff + pytest | Python Skill 相关变更 |
|
||||
| `checks-windows` | Windows 专用进程/路径测试,以及共享运行时导入说明符回归测试 | Windows 相关变更 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关变更 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关变更 |
|
||||
| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关变更 |
|
||||
| `test-performance-agent` | 可信活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动 dispatch |
|
||||
| `openclaw-performance` | 每日/按需 Kova 运行时性能报告,包含 mock-provider、deep-profile 和 GPT 5.4 live 通道 | 定时和手动 dispatch |
|
||||
| `check-dependencies` | 生产 Knip 仅依赖检查,以及未使用文件允许列表守卫 | Node 相关更改 |
|
||||
| `build-artifacts` | 构建 `dist/`、Control UI、构建产物检查,以及可复用下游产物 | Node 相关更改 |
|
||||
| `checks-fast-core` | 快速 Linux 正确性通道,例如内置/插件契约/协议检查 | Node 相关更改 |
|
||||
| `checks-fast-contracts-channels` | 带稳定聚合检查结果的分片渠道契约检查 | Node 相关更改 |
|
||||
| `checks-node-core-test` | 核心 Node 测试分片,不包括渠道、内置、契约和插件通道 | Node 相关更改 |
|
||||
| `check` | 分片的主本地门禁等价项:生产类型、lint、守卫、测试类型和严格冒烟 | Node 相关更改 |
|
||||
| `check-additional` | 架构、边界、插件表面守卫、包边界和 Gateway 网关 watch 分片 | Node 相关更改 |
|
||||
| `build-smoke` | 构建后 CLI 冒烟测试和启动内存冒烟 | Node 相关更改 |
|
||||
| `checks` | 构建产物渠道测试的验证器 | Node 相关更改 |
|
||||
| `checks-node-compat-node22` | Node 22 兼容性构建和冒烟通道 | 发布版的手动 CI 分发 |
|
||||
| `check-docs` | 文档格式化、lint 和断链检查 | 文档已更改 |
|
||||
| `skills-python` | 针对 Python 支持的 Skills 运行 Ruff + pytest | Python Skills 相关更改 |
|
||||
| `checks-windows` | Windows 特定的进程/路径测试,以及共享运行时导入说明符回归 | Windows 相关更改 |
|
||||
| `macos-node` | 使用共享构建产物的 macOS TypeScript 测试通道 | macOS 相关更改 |
|
||||
| `macos-swift` | macOS 应用的 Swift lint、构建和测试 | macOS 相关更改 |
|
||||
| `android` | 两种 flavor 的 Android 单元测试,以及一次 debug APK 构建 | Android 相关更改 |
|
||||
| `test-performance-agent` | 受信任活动后的每日 Codex 慢测试优化 | 主 CI 成功或手动分发 |
|
||||
| `openclaw-performance` | 带 mock-provider、deep-profile 和 GPT 5.4 live 通道的每日/按需 Kova 运行时性能报告 | 定时和手动分发 |
|
||||
|
||||
## 快速失败顺序
|
||||
|
||||
1. `preflight` 决定哪些通道会存在。`docs-scope` 和 `changed-scope` 逻辑是这个作业内的步骤,不是独立作业。
|
||||
1. `preflight` 决定哪些通道实际存在。`docs-scope` 和 `changed-scope` 逻辑是此作业内的步骤,不是独立作业。
|
||||
2. `security-scm-fast`、`security-dependency-audit`、`security-fast`、`check`、`check-additional`、`check-docs` 和 `skills-python` 会快速失败,不等待更重的产物和平台矩阵作业。
|
||||
3. `build-artifacts` 会与快速 Linux 通道重叠运行,让下游消费者在共享构建准备好后即可启动。
|
||||
3. `build-artifacts` 与快速 Linux 通道重叠运行,以便下游消费者能在共享构建准备好后立即开始。
|
||||
4. 更重的平台和运行时通道随后展开:`checks-fast-core`、`checks-fast-contracts-channels`、`checks-node-core-test`、`checks`、`checks-windows`、`macos-node`、`macos-swift` 和 `android`。
|
||||
|
||||
当同一 PR 或 `main` ref 上有更新的推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但在整个 workflow 已经被取代后不会继续排队。自动 CI 并发键带有版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸项不能无限期阻塞更新的 main 运行。手动完整套件运行使用 `CI-manual-v1-*`,并且不会取消正在进行的运行。
|
||||
当同一 PR 或 `main` ref 上有更新推送落地时,GitHub 可能会将被取代的作业标记为 `cancelled`。除非同一 ref 的最新运行也失败,否则应将其视为 CI 噪声。聚合分片检查使用 `!cancelled() && always()`,因此它们仍会报告正常的分片失败,但不会在整个工作流已经被取代后继续排队。自动 CI 并发键带版本号(`CI-v7-*`),因此 GitHub 侧旧队列组中的僵尸运行无法无限期阻塞更新的 main 运行。手动全套件运行使用 `CI-manual-v1-*`,且不会取消正在进行的运行。
|
||||
|
||||
## 范围和路由
|
||||
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动 dispatch 会跳过变更范围检测,并让 preflight 清单表现得像每个有范围的区域都发生了变更。
|
||||
范围逻辑位于 `scripts/ci-changed-scope.mjs`,并由 `src/scripts/ci-changed-scope.test.ts` 中的单元测试覆盖。手动分发会跳过已更改范围检测,并让预检清单表现得像每个有范围的区域都已更改。
|
||||
|
||||
- **CI workflow 编辑**会验证 Node CI 图谱以及 workflow linting,但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源代码变更。
|
||||
- **仅 CI 路由编辑、选定的廉价核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**会使用快速的仅 Node 清单路径:`preflight`、安全检查,以及单个 `checks-fast-core` 任务。当变更仅限于该快速任务直接执行的路由或 helper 表面时,此路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外防护矩阵。
|
||||
- **Windows Node 检查**限定于 Windows 专用进程/路径 wrapper、npm/pnpm/UI runner helper、包管理器配置,以及执行该通道的 CI workflow 表面;无关源代码、插件、install-smoke 和仅测试变更会留在 Linux Node 通道上。
|
||||
- **CI 工作流编辑**会验证 Node CI 图以及工作流 linting,但不会单独强制 Windows、Android 或 macOS 原生构建;这些平台通道仍限定于平台源代码更改。
|
||||
- **仅 CI 路由编辑、选定的低成本核心测试 fixture 编辑,以及窄范围插件契约 helper/测试路由编辑**会使用快速 Node-only 清单路径:`preflight`、安全检查和单个 `checks-fast-core` 任务。当更改仅限于该快速任务直接覆盖的路由或 helper 表面时,该路径会跳过构建产物、Node 22 兼容性、渠道契约、完整核心分片、内置插件分片和额外守卫矩阵。
|
||||
- **Windows Node 检查**限定于 Windows 特定的进程/路径包装器、npm/pnpm/UI 运行器 helper、包管理器配置,以及执行该通道的 CI 工作流表面;无关源码、插件、安装冒烟和仅测试更改会保留在 Linux Node 通道上。
|
||||
|
||||
最慢的 Node 测试族会被拆分或平衡,让每个作业保持较小,同时不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道成对运行,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic gateway/插件配置分布到现有仅源码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件 catch-all。include-pattern 分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分整个配置和过滤后的分片。`check-additional` 将 package-boundary 编译/canary 工作放在一起,并将运行时拓扑架构与 gateway watch 覆盖范围分开;boundary guard 分片会在一个作业内并发运行它的小型独立防护。Gateway watch、渠道测试和核心 support-boundary 分片会在 `dist/` 和 `dist-runtime/` 已构建后,于 `build-artifacts` 内并发运行。
|
||||
最慢的 Node 测试族会被拆分或平衡,让每个作业保持小规模且不过度预留 runner:渠道契约作为三个加权分片运行,小型核心单元通道成对运行,auto-reply 作为四个平衡 worker 运行(reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片),agentic Gateway 网关/插件配置则分布在现有仅源码 agentic Node 作业中,而不是等待构建产物。广泛的浏览器、QA、媒体和杂项插件测试使用各自专用的 Vitest 配置,而不是共享的插件兜底配置。包含模式分片使用 CI 分片名称记录计时条目,因此 `.artifacts/vitest-shard-timings.json` 可以区分完整配置与过滤后的分片。`check-additional` 会将包边界编译/canary 工作保持在一起,并把运行时拓扑架构与 Gateway 网关 watch 覆盖分开;边界守卫分片会在一个作业内并发运行其小型独立守卫。在 `dist/` 和 `dist-runtime/` 已构建完成后,Gateway 网关 watch、渠道测试和核心支持边界分片会在 `build-artifacts` 内并发运行。
|
||||
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。third-party flavor 没有单独的源集或 manifest;其单元测试通道仍会用 SMS/通话记录 BuildConfig 标志编译该 flavor,同时避免在每次 Android 相关推送中重复执行 debug APK 打包作业。
|
||||
Android CI 会同时运行 `testPlayDebugUnitTest` 和 `testThirdPartyDebugUnitTest`,然后构建 Play debug APK。第三方 flavor 没有单独的 source set 或 manifest;其单元测试通道仍会使用 SMS/call-log BuildConfig 标志编译该 flavor,同时避免在每个 Android 相关推送上重复执行 debug APK 打包作业。
|
||||
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并在 `dlx` 安装时禁用 pnpm 的最小发布年龄)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未审核未使用文件,或留下过时的 allowlist 条目时,未使用文件防护会失败,同时保留 Knip 无法静态解析的有意动态插件、生成文件、构建、live-test 和包桥接表面。
|
||||
`check-dependencies` 分片运行 `pnpm deadcode:dependencies`(生产 Knip 仅依赖检查,固定到最新 Knip 版本,并为 `dlx` 安装禁用 pnpm 的最低发布时间)和 `pnpm deadcode:unused-files`,后者会将 Knip 的生产未使用文件发现结果与 `scripts/deadcode-unused-files.allowlist.mjs` 进行比较。当 PR 添加新的未经审查的未使用文件,或留下过期的允许列表条目时,未使用文件守卫会失败,同时保留 Knip 无法静态解析的有意动态插件、生成产物、构建、live-test 和包桥接表面。
|
||||
|
||||
## ClawSweeper 活动转发
|
||||
|
||||
`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧桥接。它不会 checkout 或执行不可信的拉取请求代码。该 workflow 会从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App token,然后将紧凑的 `repository_dispatch` payload dispatch 到 `openclaw/clawsweeper`。
|
||||
`.github/workflows/clawsweeper-dispatch.yml` 是从 OpenClaw 仓库活动到 ClawSweeper 的目标侧桥接。它不会检出或执行不受信任的拉取请求代码。该工作流从 `CLAWSWEEPER_APP_PRIVATE_KEY` 创建 GitHub App 令牌,然后向 `openclaw/clawsweeper` 分发紧凑的 `repository_dispatch` 负载。
|
||||
|
||||
该 workflow 有四个通道:
|
||||
该工作流有四个通道:
|
||||
|
||||
- `clawsweeper_item` 用于精确的 issue 和拉取请求 review 请求;
|
||||
- `clawsweeper_comment` 用于 issue 评论中的显式 ClawSweeper 命令;
|
||||
- `clawsweeper_commit_review` 用于 `main` 推送上的 commit 级 review 请求;
|
||||
- `github_activity` 用于 ClawSweeper 智能体可以检查的一般 GitHub 活动。
|
||||
- `clawsweeper_item` 用于精确的问题和拉取请求审查请求;
|
||||
- `clawsweeper_comment` 用于问题评论中的显式 ClawSweeper 命令;
|
||||
- `clawsweeper_commit_review` 用于 `main` 推送上的提交级审查请求;
|
||||
- `github_activity` 用于 ClawSweeper 智能体可能检查的一般 GitHub 活动。
|
||||
|
||||
`github_activity` 通道只转发规范化元数据:事件类型、action、actor、repository、item number、URL、title、state,以及在存在评论或 review 时提供短摘录。它有意避免转发完整 webhook body。`openclaw/clawsweeper` 中接收用的 workflow 是 `.github/workflows/github-activity.yml`,它会将规范化事件发布到 ClawSweeper 智能体的 OpenClaw Gateway 网关 hook。
|
||||
`github_activity` 通道只转发规范化元数据:事件类型、操作、actor、仓库、条目编号、URL、标题、状态,以及存在评论或审查时的短摘录。它有意避免转发完整 webhook 正文。`openclaw/clawsweeper` 中的接收工作流是 `.github/workflows/github-activity.yml`,该工作流会将规范化事件发布到 ClawSweeper 智能体的 OpenClaw Gateway 网关钩子。
|
||||
|
||||
一般活动是观察,而不是默认投递。ClawSweeper 智能体会在其提示中收到 Discord 目标,并且只有在事件令人意外、可操作、有风险或对运维有用时,才应发布到 `#clawsweeper`。常规打开、编辑、bot 噪声、重复 webhook 噪声和正常 review 流量应返回 `NO_REPLY`。
|
||||
一般活动是观察,而不是默认投递。ClawSweeper 智能体会在其提示中收到 Discord 目标,并且只有当事件令人意外、可执行、有风险或具备运维价值时,才应发布到 `#clawsweeper`。常规打开、编辑、机器人变动、重复 webhook 噪声和正常审查流量应返回 `NO_REPLY`。
|
||||
|
||||
在整个路径中,将 GitHub 标题、评论、正文、review 文本、分支名称和 commit 消息视为不可信数据。它们是摘要和分诊的输入,而不是 workflow 或智能体运行时的指令。
|
||||
在此路径中,始终将 GitHub 标题、评论、正文、审查文本、分支名称和提交消息视为不受信任的数据。它们是用于摘要和分诊的输入,不是工作流或智能体运行时的指令。
|
||||
|
||||
## 手动 dispatches
|
||||
## 手动分发
|
||||
|
||||
手动 CI 调度运行与普通 CI 相同的作业图,但会强制启用每个非 Android 作用域 lane:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅在 `include_android=true` 时运行 Android;完整发布总控通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描,以及插件预发布 Docker lane 不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 启用发布验证 gate 并调度单独的 `Plugin Prerelease` 工作流时运行。
|
||||
手动 CI 调度运行与普通 CI 相同的作业图,但强制启用每个非 Android 范围的执行线:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS 和 Control UI i18n。独立的手动 CI 调度仅在 `include_android=true` 时运行 Android;完整发布总控工作流通过传入 `include_android=true` 启用 Android。插件预发布静态检查、仅发布使用的 `agentic-plugins` 分片、完整插件批量扫描,以及插件预发布 Docker 执行线不包含在 CI 中。Docker 预发布套件仅在 `Full Release Validation` 调度单独的 `Plugin Prerelease` 工作流并启用发布验证门禁时运行。
|
||||
|
||||
手动运行使用唯一的并发组,因此候选发布的完整套件不会被同一 ref 上的其他推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方在使用所选调度 ref 中的工作流文件时,针对分支、标签或完整提交 SHA 运行该图。
|
||||
手动运行使用唯一的并发组,因此发布候选版本的完整套件不会被同一 ref 上的另一个推送或 PR 运行取消。可选的 `target_ref` 输入允许受信任的调用方在使用所选调度 ref 中的工作流文件时,针对某个分支、标签或完整提交 SHA 运行该作业图。
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref release/YYYY.M.D
|
||||
@ -100,15 +100,15 @@ gh workflow run full-release-validation.yml --ref main -f ref=<branch-or-sha>
|
||||
|
||||
| 运行器 | 作业 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ubuntu-24.04` | `preflight`、快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`)、快速协议/契约/内置检查、分片渠道契约检查、除 lint 外的 `check` 分片、`check-additional` 分片和聚合、Node 测试聚合验证器、文档检查、Python Skills、workflow-sanity、labeler、auto-response;install-smoke preflight 也使用 GitHub 托管的 Ubuntu,以便 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`、较低权重的插件分片、`checks-fast-core`、`checks-node-compat-node22`、`check-prod-types` 和 `check-test-types` |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`、build-smoke、Linux Node 测试分片、内置插件测试分片、`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本高于节省的时间);install-smoke Docker 构建(32-vCPU 的排队时间成本高于节省的时间) |
|
||||
| `ubuntu-24.04` | `preflight`,快速安全作业和聚合(`security-scm-fast`、`security-dependency-audit`、`security-fast`),快速协议/契约/内置检查,分片渠道契约检查,除 lint 外的 `check` 分片,`check-additional` 分片和聚合,Node 测试聚合验证器,文档检查,Python Skills,workflow-sanity,labeler,auto-response;install-smoke 预检也使用 GitHub 托管的 Ubuntu,使 Blacksmith 矩阵可以更早排队 |
|
||||
| `blacksmith-4vcpu-ubuntu-2404` | `CodeQL Critical Quality`,较轻量的插件分片,`checks-fast-core`,`checks-node-compat-node22`,`check-prod-types` 和 `check-test-types` |
|
||||
| `blacksmith-8vcpu-ubuntu-2404` | `build-artifacts`,build-smoke,Linux Node 测试分片,内置插件测试分片,`android` |
|
||||
| `blacksmith-16vcpu-ubuntu-2404` | `check-lint`(对 CPU 足够敏感,8 vCPU 的成本超过了节省的时间);install-smoke Docker 构建(32-vCPU 的排队时间成本超过了节省的时间) |
|
||||
| `blacksmith-16vcpu-windows-2025` | `checks-windows` |
|
||||
| `blacksmith-6vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-node`;fork 回退到 `macos-latest` |
|
||||
| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw` 上的 `macos-swift`;fork 回退到 `macos-latest` |
|
||||
|
||||
## 本地等价命令
|
||||
## 本地等效命令
|
||||
|
||||
```bash
|
||||
pnpm changed:lanes # inspect the local changed-lane classifier for origin/main...HEAD
|
||||
@ -144,23 +144,23 @@ gh workflow run openclaw-performance.yml --ref main -f profile=diagnostic -f rep
|
||||
gh workflow run openclaw-performance.yml --ref main -f profile=smoke -f repeat=1 -f deep_profile=true -f live_gpt54=true
|
||||
```
|
||||
|
||||
该工作流从固定发布版本安装 OCM,并从固定的 `kova_ref` 输入安装 Kova,然后运行三个 lane:
|
||||
该工作流从固定版本安装 OCM,并从固定的 `kova_ref` 输入安装 Kova,然后运行三条执行线:
|
||||
|
||||
- `mock-provider`:针对本地构建运行时运行 Kova 诊断场景,并使用确定性的假 OpenAI 兼容认证。
|
||||
- `mock-deep-profile`:针对启动、Gateway 网关和 agent turn 热点进行 CPU/堆/跟踪分析。
|
||||
- `live-gpt54`:真实的 OpenAI `openai/gpt-5.4` agent turn,在 `OPENAI_API_KEY` 不可用时跳过。
|
||||
- `mock-provider`:针对本地构建运行时的 Kova 诊断场景,使用确定性的假 OpenAI 兼容凭证。
|
||||
- `mock-deep-profile`:针对启动、Gateway 网关和智能体轮次热点的 CPU/堆/追踪分析。
|
||||
- `live-gpt54`:真实的 OpenAI `openai/gpt-5.4` 智能体轮次,在 `OPENAI_API_KEY` 不可用时跳过。
|
||||
|
||||
mock-provider lane 还会在 Kova 通过后运行 OpenClaw 原生源码探针:默认、hook 和 50 插件启动场景下的 Gateway 网关启动耗时与内存;重复的 mock-OpenAI `channel-chat-baseline` hello 循环;以及针对已启动 Gateway 网关的 CLI 启动命令。源码探针 Markdown 摘要位于报告包中的 `source/index.md`,原始 JSON 位于旁边。
|
||||
mock-provider 执行线还会在 Kova 通过后运行 OpenClaw 原生源码探针:默认、hook 和 50 插件启动场景下的 Gateway 网关启动计时和内存;重复的模拟 OpenAI `channel-chat-baseline` hello 循环;以及针对已启动 Gateway 网关的 CLI 启动命令。源码探针 Markdown 摘要位于报告包中的 `source/index.md`,旁边有原始 JSON。
|
||||
|
||||
每个 lane 都会上传 GitHub 工件。配置 `CLAWGRIT_REPORTS_TOKEN` 后,工作流还会把 `report.json`、`report.md`、包、`index.md` 和源码探针工件提交到 `openclaw/clawgrit-reports`,路径为 `openclaw-performance/<ref>/<run-id>-<attempt>/<lane>/`。当前分支指针会写入 `openclaw-performance/<ref>/latest-<lane>.json`。
|
||||
每条执行线都会上传 GitHub 构件。配置 `CLAWGRIT_REPORTS_TOKEN` 后,工作流还会将 `report.json`、`report.md`、包、`index.md` 和源码探针构件提交到 `openclaw/clawgrit-reports` 的 `openclaw-performance/<ref>/<run-id>-<attempt>/<lane>/` 下。当前分支指针会写入 `openclaw-performance/<ref>/latest-<lane>.json`。
|
||||
|
||||
## 完整发布验证
|
||||
|
||||
`Full Release Validation` 是用于“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,调度 `Plugin Prerelease` 以获得仅发布使用的插件/包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以执行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram lane。使用 `rerun_group=all` 和 `release_profile=full` 时,它还会针对来自发布检查的 `release-package-under-test` 工件运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec` 可针对已发布的 npm 包重新运行相同的 Telegram 包 lane。
|
||||
`Full Release Validation` 是用于“发布前运行所有内容”的手动总控工作流。它接受分支、标签或完整提交 SHA,使用该目标调度手动 `CI` 工作流,调度 `Plugin Prerelease` 以提供仅发布使用的插件/包/静态/Docker 证明,并调度 `OpenClaw Release Checks` 以运行安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 执行线。当 `rerun_group=all` 且 `release_profile=full` 时,它还会针对发布检查产生的 `release-package-under-test` 构件运行 `NPM Telegram Beta E2E`。发布后,传入 `npm_telegram_package_spec` 可针对已发布的 npm 包重新运行同一 Telegram 包执行线。
|
||||
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解阶段矩阵、确切工作流作业名称、profile 差异、工件和定向重跑句柄。
|
||||
有关阶段矩阵、确切工作流作业名称、profile 差异、构件和定向重跑句柄,请参阅[完整发布验证](/zh-CN/reference/full-release-validation)。
|
||||
|
||||
`OpenClaw Release Publish` 是会产生变更的手动发布工作流。在发布标签已存在且 OpenClaw npm preflight 已成功后,从 `release/YYYY.M.D` 或 `main` 调度它。它会验证 `pnpm plugins:sync:check`,为所有可发布的插件包调度 `Plugin NPM Release`,为同一发布 SHA 调度 `Plugin ClawHub Release`,然后才使用保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。
|
||||
`OpenClaw Release Publish` 是会产生变更的手动发布工作流。在发布标签存在且 OpenClaw npm 预检成功后,从 `release/YYYY.M.D` 或 `main` 调度它。它会验证 `pnpm plugins:sync:check`,为所有可发布的插件包调度 `Plugin NPM Release`,为同一个发布 SHA 调度 `Plugin ClawHub Release`,并且只有在这之后才会使用保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。
|
||||
|
||||
```bash
|
||||
gh workflow run openclaw-release-publish.yml \
|
||||
@ -170,35 +170,35 @@ gh workflow run openclaw-release-publish.yml \
|
||||
-f npm_dist_tag=beta
|
||||
```
|
||||
|
||||
如果需要在快速移动的分支上提供固定提交证明,请使用辅助命令,而不是 `gh workflow run ... --ref main -f ref=<sha>`:
|
||||
对于快速移动分支上的固定提交证明,请使用辅助命令,而不是 `gh workflow run ... --ref main -f ref=<sha>`:
|
||||
|
||||
```bash
|
||||
pnpm ci:full-release --sha <full-sha>
|
||||
```
|
||||
|
||||
GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA。该辅助命令会在目标 SHA 上推送一个临时 `release-ci/<sha>-...` 分支,从该固定 ref 调度 `Full Release Validation`,验证每个子工作流的 `headSha` 与目标匹配,并在运行完成后删除临时分支。如果任何子工作流在不同 SHA 上运行,总控验证器也会失败。
|
||||
GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA。该辅助命令会在目标 SHA 处推送一个临时 `release-ci/<sha>-...` 分支,从该固定 ref 调度 `Full Release Validation`,验证每个子工作流的 `headSha` 都与目标匹配,并在运行完成时删除临时分支。如果任何子工作流在不同的 SHA 上运行,总控验证器也会失败。
|
||||
|
||||
`release_profile` 控制传递到发布检查中的 live/提供商覆盖范围。手动发布工作流默认为 `stable`;仅在你有意需要广泛的 advisory 提供商/媒体矩阵时使用 `full`。
|
||||
`release_profile` 控制传入发布检查的 live/provider 覆盖范围。手动发布工作流默认使用 `stable`;仅在你有意需要广泛的 advisory provider/media 矩阵时才使用 `full`。
|
||||
|
||||
- `minimum` 保留最快的 OpenAI/core 发布关键 lane。
|
||||
- `stable` 添加稳定的提供商/后端集合。
|
||||
- `full` 运行广泛的 advisory 提供商/媒体矩阵。
|
||||
- `minimum` 保留最快的 OpenAI/核心发布关键执行线。
|
||||
- `stable` 添加稳定的 provider/backend 集合。
|
||||
- `full` 运行广泛的 advisory provider/media 矩阵。
|
||||
|
||||
总控会记录已调度的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流被重跑并转为绿色,只需重新运行父级验证器作业来刷新总控结果和耗时摘要。
|
||||
总控工作流会记录已调度的子运行 ID,最终的 `Verify full validation` 作业会重新检查当前子运行结论,并为每个子运行追加最慢作业表。如果某个子工作流被重新运行并转为绿色,只需重新运行父验证器作业即可刷新总控结果和计时摘要。
|
||||
|
||||
为便于恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选版本使用 `all`,仅对常规完整 CI 子项使用 `ci`,仅对插件预发布子项使用 `plugin-prerelease`,对每个发布子项使用 `release-checks`,或者在总控流程上使用更窄的分组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样在完成聚焦修复后,可以把失败的发布盒重跑范围控制在有限范围内。
|
||||
为了恢复,`Full Release Validation` 和 `OpenClaw Release Checks` 都接受 `rerun_group`。对发布候选版本使用 `all`,仅对普通完整 CI 子项使用 `ci`,仅对插件预发布子项使用 `plugin-prerelease`,对每个发布子项使用 `release-checks`,或在总括项上使用更窄的分组:`install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 或 `npm-telegram`。这样可以让一次失败的发布环境在完成聚焦修复后,将重跑范围保持有界。
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任的工作流引用将选定引用解析一次为 `release-package-under-test` tarball,然后把该构件传递给 live/E2E 发布路径 Docker 工作流和包验收分片。这样可以让各个发布盒使用一致的包字节,并避免在多个子作业中重复打包同一个候选版本。
|
||||
`OpenClaw Release Checks` 使用受信任的 workflow ref 将所选 ref 一次性解析为 `release-package-under-test` tarball,然后把该产物传给 live/E2E 发布路径 Docker workflow 和包验收分片。这样可以让各个发布环境使用一致的包字节,并避免在多个子任务中重新打包同一个候选版本。
|
||||
|
||||
对于 `ref=main` 和 `rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总控流程。父级监控器会在父级被取消时取消它已经派发的任何子工作流,因此较新的 main 验证不会被陈旧的两小时 release-check 运行阻塞。发布分支/标签验证和聚焦重跑分组保持 `cancel-in-progress: false`。
|
||||
对于 `ref=main` 和 `rerun_group=all` 的重复 `Full Release Validation` 运行会取代较旧的总括运行。父级监视器会在父级被取消时,取消它已经派发的任何子 workflow,因此较新的 main 验证不会排在陈旧的两小时 release-check 运行之后。发布分支/标签验证和聚焦重跑分组会保持 `cancel-in-progress: false`。
|
||||
|
||||
## Live 和 E2E 分片
|
||||
|
||||
发布 live/E2E 子项保留广泛的原生 `pnpm test:live` 覆盖,但它通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是一个串行作业:
|
||||
发布 live/E2E 子项保留宽泛的原生 `pnpm test:live` 覆盖范围,但它会通过 `scripts/test-live-shard.mjs` 以命名分片运行,而不是作为一个串行任务运行:
|
||||
|
||||
- `native-live-src-agents`
|
||||
- `native-live-src-gateway-core`
|
||||
- provider 过滤的 `native-live-src-gateway-profiles` 作业
|
||||
- 按提供商过滤的 `native-live-src-gateway-profiles` 任务
|
||||
- `native-live-src-gateway-backends`
|
||||
- `native-live-test`
|
||||
- `native-live-extensions-a-k`
|
||||
@ -206,59 +206,59 @@ GitHub 工作流调度 ref 必须是分支或标签,不能是原始提交 SHA
|
||||
- `native-live-extensions-openai`
|
||||
- `native-live-extensions-o-z-other`
|
||||
- `native-live-extensions-xai`
|
||||
- 拆分后的媒体音频/视频分片和 provider 过滤的音乐分片
|
||||
- 拆分后的媒体音频/视频分片,以及按提供商过滤的音乐分片
|
||||
|
||||
这样在保持相同文件覆盖的同时,更容易重跑和诊断缓慢的 live provider 失败。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍然可用于手动一次性重跑。
|
||||
这样会保持相同的文件覆盖范围,同时让缓慢的 live 提供商失败更容易重跑和诊断。聚合的 `native-live-extensions-o-z`、`native-live-extensions-media` 和 `native-live-extensions-media-music` 分片名称仍可用于手动一次性重跑。
|
||||
|
||||
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` 工作流构建。该镜像预装 `ffmpeg` 和 `ffprobe`;媒体作业只在设置前验证这些二进制文件。把 Docker 支持的 live 套件保留在普通 Blacksmith runner 上运行:容器作业不适合启动嵌套 Docker 测试。
|
||||
原生 live 媒体分片在 `ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04` 中运行,该镜像由 `Live Media Runner Image` workflow 构建。该镜像预装了 `ffmpeg` 和 `ffprobe`;媒体任务只会在设置前验证这些二进制文件。让 Docker 支撑的 live 套件继续在普通 Blacksmith runner 上运行,容器任务不是启动嵌套 Docker 测试的合适位置。
|
||||
|
||||
Docker 支持的 live 模型/后端分片针对每个选定提交使用单独共享的 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布工作流会构建并推送该镜像一次,然后 Docker live 模型、按 provider 分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带有显式的脚本级 `timeout` 上限,低于工作流作业超时时间,因此卡住的容器或清理路径会快速失败,而不是消耗整个 release-check 预算。如果这些分片独立重建完整的源 Docker 目标,说明该发布运行配置错误,并会把时间浪费在重复镜像构建上。
|
||||
Docker 支撑的 live 模型/后端分片会为每个所选提交使用单独的共享 `ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像。live 发布 workflow 构建并推送该镜像一次,然后 Docker live 模型、按提供商分片的 Gateway 网关、CLI 后端、ACP bind 和 Codex harness 分片会以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行。Gateway 网关 Docker 分片带有显式的脚本级 `timeout` 上限,低于 workflow 任务超时,因此卡住的容器或清理路径会快速失败,而不是耗尽整个 release-check 预算。如果这些分片独立重建完整源码 Docker 目标,说明发布运行配置错误,并会把挂钟时间浪费在重复镜像构建上。
|
||||
|
||||
## 包验收
|
||||
|
||||
当问题是“这个可安装的 OpenClaw 包作为产品能否工作?”时,使用 `Package Acceptance`。它不同于常规 CI:常规 CI 验证源代码树,而包验收通过用户在安装或更新后使用的同一个 Docker E2E harness 验证单个 tarball。
|
||||
当问题是“这个可安装的 OpenClaw 包是否能作为产品正常工作?”时,使用 `Package Acceptance`。它不同于普通 CI:普通 CI 验证源码树,而包验收会通过用户在安装或更新后使用的同一 Docker E2E harness 来验证单个 tarball。
|
||||
|
||||
### 作业
|
||||
### 任务
|
||||
|
||||
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 构件上传,并在 GitHub 步骤摘要中打印来源、工作流引用、包引用、版本、SHA-256 和 profile。
|
||||
2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用工作流会下载该构件,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行选定的 Docker lanes,而不是打包工作流检出内容。当某个 profile 选择多个定向 `docker_lanes` 时,可复用工作流会准备包和共享镜像一次,然后把这些 lanes 扇出为带有唯一构件的并行定向 Docker 作业。
|
||||
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时运行;如果包验收解析出了一个包,它会安装同一个 `package-under-test` 构件;独立的 Telegram 派发仍然可以安装已发布的 npm spec。
|
||||
4. `summary` 会在包解析、Docker 验收或可选 Telegram lane 失败时使工作流失败。
|
||||
1. `resolve_package` 检出 `workflow_ref`,解析一个包候选项,写入 `.artifacts/docker-e2e-package/openclaw-current.tgz`,写入 `.artifacts/docker-e2e-package/package-candidate.json`,将两者作为 `package-under-test` 产物上传,并在 GitHub 步骤摘要中打印来源、workflow ref、package ref、版本、SHA-256 和 profile。
|
||||
2. `docker_acceptance` 使用 `ref=workflow_ref` 和 `package_artifact_name=package-under-test` 调用 `openclaw-live-and-e2e-checks-reusable.yml`。可复用 workflow 会下载该产物,验证 tarball 清单,在需要时准备 package-digest Docker 镜像,并针对该包运行所选 Docker lanes,而不是打包 workflow 检出内容。当某个 profile 选择多个目标 `docker_lanes` 时,可复用 workflow 会先准备一次包和共享镜像,然后将这些 lanes 扇出为带有唯一产物的并行目标 Docker 任务。
|
||||
3. `package_telegram` 可选调用 `NPM Telegram Beta E2E`。当 `telegram_mode` 不是 `none` 时它会运行,并在包验收解析出包后安装同一个 `package-under-test` 产物;独立 Telegram 派发仍然可以安装已发布的 npm spec。
|
||||
4. `summary` 会在包解析、Docker 验收或可选 Telegram lane 失败时让 workflow 失败。
|
||||
|
||||
### 候选来源
|
||||
|
||||
- `source=npm` 只接受 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。用它验证已发布的预发布版/稳定版。
|
||||
- `source=ref` 打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证选定提交可从仓库分支历史或发布标签到达,在分离的 worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包。
|
||||
- `source=npm` 只接受 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本,例如 `openclaw@2026.4.27-beta.2`。将它用于已发布预发布版/稳定版验收。
|
||||
- `source=ref` 会打包受信任的 `package_ref` 分支、标签或完整提交 SHA。解析器会获取 OpenClaw 分支/标签,验证所选提交可从仓库分支历史或发布标签到达,在 detached worktree 中安装依赖,并用 `scripts/package-openclaw-for-docker.mjs` 打包它。
|
||||
- `source=url` 下载 HTTPS `.tgz`;必须提供 `package_sha256`。
|
||||
- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但对于外部共享的构件应提供。
|
||||
- `source=artifact` 从 `artifact_run_id` 和 `artifact_name` 下载一个 `.tgz`;`package_sha256` 可选,但应为外部共享的产物提供它。
|
||||
|
||||
保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任工作流/harness 代码。`package_ref` 是 `source=ref` 时被打包的源提交。这样当前测试 harness 可以验证较旧的受信任源提交,而不运行旧的工作流逻辑。
|
||||
保持 `workflow_ref` 和 `package_ref` 分离。`workflow_ref` 是运行测试的受信任 workflow/harness 代码。`package_ref` 是在 `source=ref` 时被打包的源提交。这样当前测试 harness 可以验证较旧的受信任源提交,而无需运行旧的 workflow 逻辑。
|
||||
|
||||
### 套件 profile
|
||||
|
||||
- `smoke` — `npm-onboard-channel-agent`、`gateway-network`、`config-reload`
|
||||
- `package` — `npm-onboard-channel-agent`、`doctor-switch`、`update-channel-switch`、`upgrade-survivor`、`published-upgrade-survivor`、`plugins-offline`、`plugin-update`
|
||||
- `product` — `package` 加上 `mcp-channels`、`cron-mcp-cleanup`、`openai-web-search-minimal`、`openwebui`
|
||||
- `full` — 带 OpenWebUI 的完整 Docker 发布路径分块
|
||||
- `full` — 带 OpenWebUI 的完整 Docker 发布路径块
|
||||
- `custom` — 精确的 `docker_lanes`;当 `suite_profile=custom` 时必需
|
||||
|
||||
`package` profile 使用离线插件覆盖,因此已发布包验证不会受 live ClawHub 可用性限制。可选 Telegram lane 在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 构件,同时为独立派发保留已发布 npm spec 路径。
|
||||
`package` profile 使用离线插件覆盖范围,因此已发布包验证不会受 live ClawHub 可用性限制。可选 Telegram lane 会在 `NPM Telegram Beta E2E` 中复用 `package-under-test` 产物,同时保留已发布 npm spec 路径用于独立派发。
|
||||
|
||||
关于专门的更新和插件测试策略,包括本地命令、Docker lanes、包验收输入、发布默认值和失败分诊,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
有关专门的更新和插件测试策略,包括本地命令、Docker lanes、包验收输入、发布默认值和失败分诊,请参阅 [更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
|
||||
发布检查会用 `source=artifact`、准备好的发布包构件、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 调用包验收。这样可以让包迁移、更新、陈旧插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram proof 都使用同一个已解析的包 tarball。跨 OS 发布检查仍然覆盖 OS 特定的新手引导、安装器和平台行为;包/更新产品验证应从包验收开始。`published-upgrade-survivor` Docker lane 每次运行验证一个已发布包基线。在包验收中,解析出的 `package-under-test` tarball 始终是候选包,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败 lane 的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=release-history` 可将 lane 扩展到去重后的历史矩阵:最新六个稳定版、`2026.4.23`,以及 `2026-03-15` 之前的最新稳定版。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将同一组基线扩展到按 issue 形状构造的 fixture,覆盖 Feishu 配置、保留的 bootstrap/persona 文件、已配置的 OpenClaw 插件安装、波浪号日志路径,以及陈旧的旧版插件依赖根目录。单独的 `Update Migration` 工作流在问题是彻底的已发布更新清理,而不是常规完整发布 CI 覆盖时,会使用带 `all-since-2026.4.23` 和 `plugin-deps-cleanup` 的 `update-migration` Docker lane。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包 spec,通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保留单个 lane,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 以使用场景矩阵。已发布 lane 使用内置的 `openclaw config set` 命令配方配置基线,在 `summary.json` 中记录配方步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC status。Windows 打包版和安装器全新安装 lane 还会验证已安装包可以从原始绝对 Windows 路径导入浏览器控制 override。OpenAI 跨 OS agent-turn smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因此安装和 Gateway 网关 proof 会保持在 GPT-5 测试模型上,同时避免 GPT-4.x 默认值。
|
||||
发布检查会使用 `source=artifact`、准备好的发布包产物、`suite_profile=custom`、`docker_lanes='doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update'`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 调用包验收。这样可以把包迁移、更新、陈旧插件依赖清理、已配置插件安装修复、离线插件、插件更新和 Telegram 证明放在同一个已解析包 tarball 上。在 Full Release Validation 或 OpenClaw Release Checks 上设置 `package_acceptance_package_spec`,可针对已发布 npm 包而不是基于 SHA 构建的产物运行同一矩阵。跨 OS 发布检查仍然覆盖 OS 特定的新手引导、安装器和平台行为;包/更新产品验证应从包验收开始。`published-upgrade-survivor` Docker lane 每次运行会验证一个已发布包基线。在包验收中,解析出的 `package-under-test` tarball 始终是候选项,而 `published_upgrade_survivor_baseline` 选择回退的已发布基线,默认是 `openclaw@latest`;失败 lane 的重跑命令会保留该基线。设置 `published_upgrade_survivor_baselines=all-since-2026.4.23` 可将 Full Release CI 扩展到从 `2026.4.23` 到 `latest` 的每个稳定 npm 发布版;`release-history` 仍可用于以较旧的日期前锚点进行手动更宽采样。设置 `published_upgrade_survivor_scenarios=reported-issues` 可将相同基线扩展到问题形态的 fixtures,覆盖 Feishu 配置、保留的 bootstrap/persona 文件、已配置的 OpenClaw 插件安装、波浪号日志路径和陈旧旧版插件依赖根。单独的 `Update Migration` workflow 会在问题是穷尽式已发布更新清理,而不是普通 Full Release CI 广度时,使用带 `all-since-2026.4.23` 和 `plugin-deps-cleanup` 的 `update-migration` Docker lane。本地聚合运行可以通过 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 传入精确包 spec,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 保持单个 lane,例如 `openclaw@2026.4.15`,或设置 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 以运行场景矩阵。已发布 lane 使用内置的 `openclaw config set` 命令 recipe 配置基线,在 `summary.json` 中记录 recipe 步骤,并在 Gateway 网关启动后探测 `/healthz`、`/readyz` 以及 RPC 状态。Windows 打包和安装器全新 lane 还会验证已安装包能否从原始绝对 Windows 路径导入 browser-control override。OpenAI 跨 OS agent-turn smoke 在设置时默认使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因此安装和 Gateway 网关证明会保持在 GPT-5 测试模型上,同时避免 GPT-4.x 默认值。
|
||||
|
||||
### 旧版兼容窗口
|
||||
|
||||
包验收对已经发布的包有有限的旧版兼容窗口。截至 `2026.4.25` 的包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
|
||||
包验收对已经发布的包有有界的旧版兼容窗口。到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以使用兼容路径:
|
||||
|
||||
- `dist/postinstall-inventory.json` 中已知的私有 QA 条目可能指向 tarball 中省略的文件;
|
||||
- 当包没有暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过持久化子用例;
|
||||
- `update-channel-switch` 可以从 tarball 派生的伪 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,并且可以记录缺失的持久化 `update.channel`;
|
||||
- 插件 smoke 可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;
|
||||
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和不重新安装行为保持不变。
|
||||
- `dist/postinstall-inventory.json` 中的已知私有 QA 条目可以指向 tarball 省略的文件;
|
||||
- 当包未暴露 `gateway install --wrapper` 标志时,`doctor-switch` 可以跳过持久化子用例;
|
||||
- `update-channel-switch` 可以从 tarball 派生的假 git fixture 中剪除缺失的 `pnpm.patchedDependencies`,并可以记录缺失的持久化 `update.channel`;
|
||||
- 插件 smokes 可以读取旧版安装记录位置,或接受缺失的 marketplace 安装记录持久化;
|
||||
- `plugin-update` 可以允许配置元数据迁移,同时仍要求安装记录和无重装行为保持不变。
|
||||
|
||||
已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳文件发出警告。后续包必须满足现代契约;同样条件会失败,而不是警告或跳过。
|
||||
已发布的 `2026.4.26` 包也可以对已经发布的本地构建元数据戳记文件发出警告。后续包必须满足现代契约;相同条件会失败,而不是警告或跳过。
|
||||
|
||||
### 示例
|
||||
|
||||
@ -301,111 +301,111 @@ gh workflow run package-acceptance.yml \
|
||||
-f docker_lanes='install-e2e plugin-update'
|
||||
```
|
||||
|
||||
调试失败的包验收运行时,先查看 `resolve_package` 摘要,确认包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 制品:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段耗时和重新运行命令。优先重新运行失败的包配置档或精确的 Docker 通道,而不是重新运行完整发布验证。
|
||||
调试失败的软件包验收运行时,先查看 `resolve_package` 摘要,确认软件包来源、版本和 SHA-256。然后检查 `docker_acceptance` 子运行及其 Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志、阶段计时和重新运行命令。优先重新运行失败的软件包配置文件或精确的 Docker 通道,而不是重新运行完整发布验证。
|
||||
|
||||
## 安装 smoke
|
||||
## 安装冒烟测试
|
||||
|
||||
独立的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将 smoke 覆盖范围拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
单独的 `Install Smoke` 工作流通过自己的 `preflight` 作业复用同一个范围脚本。它将冒烟覆盖拆分为 `run_fast_install_smoke` 和 `run_full_install_smoke`。
|
||||
|
||||
- **快速路径**会在拉取请求触及 Docker/包表面、内置插件包/manifest 变更,或 Docker smoke 作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面时运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行智能体删除共享工作区 CLI smoke,运行容器 Gateway 网关网络 e2e,验证内置插件构建参数,并在 240 秒聚合命令超时内运行有界的内置插件 Docker 配置档(每个场景的 Docker 运行会单独设置上限)。
|
||||
- **完整路径**保留 QR 包安装以及安装器 Docker/更新覆盖范围,用于夜间定时运行、手动分发、workflow-call 发布检查,以及真正触及安装器/包/Docker 表面的拉取请求。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile smoke 镜像,然后将 QR 包安装、根 Dockerfile/Gateway 网关 smoke、安装器/更新 smoke,以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作就不会排在根镜像 smoke 后面等待。
|
||||
- **快速路径**会针对触及 Docker/软件包表面、内置插件软件包/清单变更,或 Docker 冒烟作业会覆盖的核心插件/渠道/Gateway 网关/插件 SDK 表面的拉取请求运行。仅源码的内置插件变更、仅测试编辑和仅文档编辑不会预留 Docker worker。快速路径会构建一次根 Dockerfile 镜像,检查 CLI,运行智能体删除共享工作区 CLI 冒烟测试,运行容器 gateway-network e2e,验证内置插件构建参数,并在 240 秒聚合命令超时内运行有界内置插件 Docker 配置文件(每个场景的 Docker 运行会单独设定上限)。
|
||||
- **完整路径**保留 QR 软件包安装以及安装器 Docker/更新覆盖,用于每夜定时运行、手动分发、workflow-call 发布检查,以及确实触及安装器/软件包/Docker 表面的拉取请求。在完整模式下,install-smoke 会准备或复用一个目标 SHA 的 GHCR 根 Dockerfile 冒烟镜像,然后将 QR 软件包安装、根 Dockerfile/Gateway 网关冒烟、安装器/更新冒烟,以及快速内置插件 Docker E2E 作为独立作业运行,这样安装器工作不会排在根镜像冒烟之后等待。
|
||||
|
||||
`main` 推送(包括合并提交)不会强制走完整路径;当变更范围逻辑会在推送上请求完整覆盖范围时,工作流会保留快速 Docker smoke,并把完整安装 smoke 留给夜间运行或发布验证。
|
||||
`main` 推送(包括合并提交)不会强制使用完整路径;当变更范围逻辑会在推送上请求完整覆盖时,工作流会保留快速 Docker 冒烟,并将完整安装冒烟留给每夜运行或发布验证。
|
||||
|
||||
较慢的 Bun 全局安装 image-provider smoke 由 `run_bun_global_install_smoke` 单独控制。它会在夜间计划任务和发布检查工作流中运行,手动 `Install Smoke` 分发也可以选择加入它,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。
|
||||
较慢的 Bun 全局安装 image-provider 冒烟测试由 `run_bun_global_install_smoke` 单独控制。它会在每夜计划任务和发布检查工作流中运行,手动 `Install Smoke` 分发可以选择启用它,但拉取请求和 `main` 推送不会运行它。QR 和安装器 Docker 测试保留各自面向安装的 Dockerfile。
|
||||
|
||||
## 本地 Docker E2E
|
||||
|
||||
`pnpm test:docker:all` 会预构建一个共享的实时测试镜像,将 OpenClaw 打包一次为 npm tarball,并构建两个共享的 `scripts/e2e/Dockerfile` 镜像:
|
||||
|
||||
- 用于安装器/更新/插件依赖通道的裸 Node/Git 运行器;
|
||||
- 将同一个 tarball 安装到 `/app` 的功能镜像,用于常规功能通道。
|
||||
- 一个用于安装器/更新/插件依赖通道的裸 Node/Git runner;
|
||||
- 一个功能镜像,会将同一个 tarball 安装到 `/app`,用于普通功能通道。
|
||||
|
||||
Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,运行器只执行选中的计划。调度器用 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个通道选择镜像,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行通道。
|
||||
Docker 通道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`,规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`,runner 只执行选中的计划。调度器通过 `OPENCLAW_DOCKER_E2E_BARE_IMAGE` 和 `OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE` 为每个通道选择镜像,然后使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行通道。
|
||||
|
||||
### 可调参数
|
||||
|
||||
| 变量 | 默认值 | 用途 |
|
||||
| -------------------------------------- | ------- | --------------------------------------------------------------------------------------------- |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 常规通道的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | 提供商敏感尾池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时通道上限,避免提供商限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 通道启动之间的错峰时间,用于避免 Docker daemon 创建风暴;设为 `0` 表示不做错峰。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每通道兜底超时(120 分钟);选定的实时/尾部通道使用更严格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | 未设置 | `1` 会打印调度器计划而不运行通道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | 未设置 | 逗号分隔的精确通道列表;跳过清理 smoke,以便智能体复现一个失败通道。 |
|
||||
| 变量 | 默认值 | 用途 |
|
||||
| -------------------------------------- | ------ | --------------------------------------------------------------------------------------------- |
|
||||
| `OPENCLAW_DOCKER_ALL_PARALLELISM` | 10 | 普通通道的主池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM` | 10 | provider 敏感尾部池槽位数。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LIVE_LIMIT` | 9 | 并发实时通道上限,避免 provider 限流。 |
|
||||
| `OPENCLAW_DOCKER_ALL_NPM_LIMIT` | 10 | 并发 npm 安装通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT` | 7 | 并发多服务通道上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_START_STAGGER_MS` | 2000 | 通道启动之间的错峰时间,用于避免 Docker daemon 创建风暴;设为 `0` 表示不做错峰。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` | 7200000 | 每个通道的兜底超时(120 分钟);选定的实时/尾部通道会使用更严格的上限。 |
|
||||
| `OPENCLAW_DOCKER_ALL_DRY_RUN` | unset | `1` 会打印调度器计划而不运行通道。 |
|
||||
| `OPENCLAW_DOCKER_ALL_LANES` | unset | 逗号分隔的精确通道列表;跳过清理冒烟,便于智能体复现一个失败通道。 |
|
||||
|
||||
比其有效上限更重的通道仍可从空池启动,然后会独占运行直到释放容量。本地聚合流程会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活动通道 Status,持久化通道耗时以便按最长优先排序,并默认在第一次失败后停止调度新的池化通道。
|
||||
超过有效上限的较重通道仍可从空池启动,然后会单独运行,直到释放容量。本地聚合流程会预检 Docker,移除陈旧的 OpenClaw E2E 容器,输出活动通道 Status,持久化通道计时以便最长优先排序,并默认在第一次失败后停止调度新的池化通道。
|
||||
|
||||
### 可复用实时/E2E 工作流
|
||||
|
||||
可复用实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些包、镜像类型、实时镜像、通道和凭证覆盖范围。随后 `scripts/docker-e2e.mjs` 会把该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的包制品,或从 `package_artifact_run_id` 下载包制品;验证 tarball 清单;在计划需要已安装包的通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用传入的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有包摘要镜像,而不是重新构建。Docker 镜像拉取会以每次尝试 180 秒的有界超时重试,这样卡住的注册表/缓存流会快速重试,而不是消耗大部分 CI 关键路径。
|
||||
可复用的实时/E2E 工作流会询问 `scripts/test-docker-all.mjs --plan-json` 需要哪些软件包、镜像类型、实时镜像、通道和凭据覆盖。随后 `scripts/docker-e2e.mjs` 会将该计划转换为 GitHub 输出和摘要。它会通过 `scripts/package-openclaw-for-docker.mjs` 打包 OpenClaw、下载当前运行的软件包工件,或从 `package_artifact_run_id` 下载软件包工件;验证 tarball 清单;在计划需要已安装软件包的通道时,通过 Blacksmith 的 Docker 层缓存构建并推送带有软件包摘要标签的裸/功能 GHCR Docker E2E 镜像;并复用提供的 `docker_e2e_bare_image`/`docker_e2e_functional_image` 输入或现有的软件包摘要镜像,而不是重新构建。Docker 镜像拉取会以每次尝试 180 秒的有界超时重试,因此卡住的 registry/cache 流会快速重试,而不会消耗 CI 关键路径的大部分时间。
|
||||
|
||||
### 发布路径分块
|
||||
|
||||
发布 Docker 覆盖范围会运行更小的分块作业,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取它需要的镜像类型,并通过同一个加权调度器执行多个通道:
|
||||
发布 Docker 覆盖会以更小的分块作业运行,并设置 `OPENCLAW_SKIP_DOCKER_BUILD=1`,因此每个分块只拉取自己需要的镜像类型,并通过同一个加权调度器执行多个通道:
|
||||
|
||||
- `OPENCLAW_DOCKER_ALL_PROFILE=release-path`
|
||||
- `OPENCLAW_DOCKER_ALL_CHUNK=core | package-update-openai | package-update-anthropic | package-update-core | plugins-runtime-plugins | plugins-runtime-services | plugins-runtime-install-a..h`
|
||||
|
||||
当前发布 Docker 分块包括 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍然是聚合插件/运行时别名。`install-e2e` 通道别名仍然是两个提供商安装器通道的聚合手动重新运行别名。
|
||||
当前发布 Docker 分块为 `core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`,以及从 `plugins-runtime-install-a` 到 `plugins-runtime-install-h`。`plugins-runtime-core`、`plugins-runtime` 和 `plugins-integrations` 仍然是聚合插件/运行时别名。`install-e2e` 通道别名仍然是两个 provider 安装器通道的聚合手动重新运行别名。
|
||||
|
||||
当完整 release-path 覆盖范围请求 OpenWebUI 时,OpenWebUI 会合并到 `plugins-runtime-services`;只有在 OpenWebUI 专用分发时,才保留独立的 `openwebui` 分块。内置渠道更新通道会针对临时 npm 网络失败重试一次。
|
||||
当完整 release-path 覆盖请求 OpenWebUI 时,OpenWebUI 会并入 `plugins-runtime-services`,并且只在仅 OpenWebUI 的分发中保留独立的 `openwebui` 分块。内置渠道更新通道会针对临时 npm 网络失败重试一次。
|
||||
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、耗时、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON、慢通道表,以及每通道重新运行命令。工作流的 `docker_lanes` 输入会针对已准备好的镜像运行选定通道,而不是运行分块作业,这会将失败通道调试限制在一个有目标的 Docker 作业内,并为该运行准备、下载或复用包制品;如果选定通道是实时 Docker 通道,目标作业会为该次重新运行在本地构建实时测试镜像。生成的每通道 GitHub 重新运行命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备镜像输入,因此失败通道可以复用失败运行中的精确包和镜像。
|
||||
每个分块都会上传 `.artifacts/docker-tests/`,其中包含通道日志、计时、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON、慢通道表和每通道重新运行命令。工作流的 `docker_lanes` 输入会针对已准备好的镜像运行选定通道,而不是运行分块作业,这使失败通道调试被限制在一个有针对性的 Docker 作业内,并会为该运行准备、下载或复用软件包工件;如果选中的通道是实时 Docker 通道,定向作业会为这次重新运行在本地构建实时测试镜像。生成的每通道 GitHub 重新运行命令会在这些值存在时包含 `package_artifact_run_id`、`package_artifact_name` 和已准备好的镜像输入,因此失败通道可以复用失败运行中的精确软件包和镜像。
|
||||
|
||||
```bash
|
||||
pnpm test:docker:rerun <run-id> # download Docker artifacts and print combined/per-lane targeted rerun commands
|
||||
pnpm test:docker:timings <summary> # slow-lane and phase critical-path summaries
|
||||
```
|
||||
|
||||
定时实时/E2E 工作流每天运行完整的 release-path Docker 套件。
|
||||
定时实时/E2E 工作流每天运行完整 release-path Docker 套件。
|
||||
|
||||
## 插件预发布
|
||||
|
||||
`Plugin Prerelease` 是成本更高的产品/包覆盖范围,因此它是由 `Full Release Validation` 或显式操作员分发的独立工作流。常规拉取请求、`main` 推送和独立手动 CI 分发都会关闭该套件。它会把内置插件测试均衡分配到八个插件 worker;这些插件分片作业每次最多运行两个插件配置组,每组一个 Vitest worker,并使用更大的 Node 堆,这样导入量大的插件批次不会创建额外 CI 作业。仅发布的 Docker 预发布路径会把目标 Docker 通道按小组批处理,避免为一到三分钟的作业预留数十个运行器。
|
||||
`Plugin Prerelease` 是成本更高的产品/软件包覆盖,因此它是一个由 `Full Release Validation` 或显式操作员分发的独立工作流。普通拉取请求、`main` 推送和独立的手动 CI 分发都会关闭该套件。它会在八个插件 worker 之间平衡内置插件测试;这些插件分片作业一次最多运行两个插件配置组,每组使用一个 Vitest worker 和更大的 Node 堆,这样导入较重的插件批次不会创建额外的 CI 作业。仅发布使用的 Docker 预发布路径会将定向 Docker 通道按小组批处理,避免为一到三分钟的作业预留数十个 runner。
|
||||
|
||||
## QA Lab
|
||||
|
||||
QA Lab 在主智能范围工作流之外有专用 CI 通道。
|
||||
|
||||
- `Parity gate` 工作流会在匹配的 PR 变更和手动分发时运行;它会构建私有 QA 运行时,并比较 mock GPT-5.5 和 Opus 4.6 智能体包。
|
||||
- `QA-Lab - All Lanes` 工作流会在 `main` 上夜间运行并支持手动分发;它会将 mock parity gate、实时 Matrix 通道、实时 Telegram 和 Discord 通道作为并行作业展开。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。
|
||||
- `QA-Lab - All Lanes` 工作流每夜在 `main` 上运行,也可手动分发;它会将 mock parity gate、实时 Matrix 通道,以及实时 Telegram 和 Discord 通道作为并行作业扇出。实时作业使用 `qa-live-shared` 环境,Telegram/Discord 使用 Convex 租约。
|
||||
|
||||
发布检查会使用确定性的 mock 提供商和 mock 限定模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和常规提供商插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;提供商连接性由独立的实时模型、原生提供商和 Docker 提供商套件覆盖。
|
||||
发布检查会使用确定性 mock provider 和符合 mock 要求的模型(`mock-openai/gpt-5.5` 和 `mock-openai/gpt-5.5-alt`)运行 Matrix 和 Telegram 实时传输通道,因此渠道契约会与实时模型延迟和普通 provider 插件启动隔离。实时传输 Gateway 网关会禁用记忆搜索,因为 QA parity 会单独覆盖记忆行为;provider 连接性由单独的实时模型、原生 provider 和 Docker provider 套件覆盖。
|
||||
|
||||
Matrix 会对定时和发布门禁使用 `--profile fast`,并且只有当检出的 CLI 支持时才添加 `--fail-fast`。CLI 默认值和手动工作流输入保持为 `all`;手动 `matrix_profile=all` 分发始终将完整 Matrix 覆盖范围分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
|
||||
Matrix 对定时和发布门禁使用 `--profile fast`,并且只在检出的 CLI 支持时添加 `--fail-fast`。CLI 默认值和手动工作流输入仍为 `all`;手动 `matrix_profile=all` 分发始终会将完整 Matrix 覆盖分片为 `transport`、`media`、`e2ee-smoke`、`e2ee-deep` 和 `e2ee-cli` 作业。
|
||||
|
||||
`OpenClaw Release Checks` 也会在发布批准前运行发布关键 QA Lab 通道;它的 QA parity gate 会将候选包和基线包作为并行通道作业运行,然后把两个制品下载到一个小报告作业中,用于最终 parity 比较。
|
||||
`OpenClaw Release Checks` 也会在发布批准前运行发布关键的 QA Lab 通道;其 QA parity gate 会将候选包和基线包作为并行通道作业运行,然后将两个工件下载到一个小型报告作业中,用于最终 parity 比较。
|
||||
|
||||
除非变更确实触及 QA 运行时、模型包 parity,或 parity 工作流拥有的表面,否则不要把 PR 落地路径放在 `Parity gate` 后面。对于常规渠道、配置、文档或单元测试修复,把它视为可选信号,并遵循有范围的 CI/检查证据。
|
||||
不要把 PR 落地路径置于 `Parity gate` 之后,除非变更确实触及 QA 运行时、模型包一致性,或一致性工作流负责的表面。对于常规渠道、配置、文档或单元测试修复,应将其视为可选信号,并改为遵循限定范围内的 CI/检查证据。
|
||||
|
||||
## CodeQL
|
||||
|
||||
`CodeQL` 工作流有意作为窄范围的第一道安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求守卫运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用筛选为高/严重 `security-severity` 的高置信度安全查询。
|
||||
`CodeQL` 工作流有意作为窄范围的一轮安全扫描器,而不是完整仓库扫描。每日、手动和非草稿拉取请求保护运行会扫描 Actions 工作流代码,以及最高风险的 JavaScript/TypeScript 表面,并使用高置信度安全查询,过滤到高/严重 `security-severity`。
|
||||
|
||||
拉取请求守卫保持轻量:它只会在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更触发,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不在 PR 默认范围内。
|
||||
拉取请求保护保持轻量:它只会在 `.github/actions`、`.github/codeql`、`.github/workflows`、`packages` 或 `src` 下的变更中启动,并运行与定时工作流相同的高置信度安全矩阵。Android 和 macOS CodeQL 不包含在 PR 默认项中。
|
||||
|
||||
### 安全类别
|
||||
|
||||
| 类别 | 范围 |
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-security-high/core-auth-secrets` | 认证、密钥、沙箱、cron 和 Gateway 网关基线 |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计接触点 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、web-fetch,以及插件 SDK SSRF 策略范围 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站交付,以及智能体工具执行门控 |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、注册表、包管理器安装、源加载,以及插件 SDK 包契约信任范围 |
|
||||
| `/codeql-security-high/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关基线 |
|
||||
| `/codeql-security-high/channel-runtime-boundary` | 核心渠道实现契约,以及渠道插件运行时、Gateway 网关、插件 SDK、密钥、审计触点 |
|
||||
| `/codeql-security-high/network-ssrf-boundary` | 核心 SSRF、IP 解析、网络防护、Web 获取和插件 SDK SSRF 策略表面 |
|
||||
| `/codeql-security-high/mcp-process-tool-boundary` | MCP 服务器、进程执行辅助工具、出站交付,以及智能体工具执行门禁 |
|
||||
| `/codeql-security-high/plugin-trust-boundary` | 插件安装、加载器、清单、注册表、包管理器安装、源码加载,以及插件 SDK 包契约信任表面 |
|
||||
|
||||
### 平台特定安全分片
|
||||
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。为 CodeQL 手动构建 Android 应用,运行在工作流完整性检查接受的最小 Blacksmith Linux 运行器上。上传到 `/codeql-critical-security/android`。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos`。它不在每日默认项中,因为即使结果干净,macOS 构建也会主导运行时间。
|
||||
- `CodeQL Android Critical Security` — 定时 Android 安全分片。在工作流健全性接受的最小 Blacksmith Linux runner 上为 CodeQL 手动构建 Android 应用。上传到 `/codeql-critical-security/android` 下。
|
||||
- `CodeQL macOS Critical Security` — 每周/手动 macOS 安全分片。在 Blacksmith macOS 上为 CodeQL 手动构建 macOS 应用,从上传的 SARIF 中过滤掉依赖构建结果,并上传到 `/codeql-critical-security/macos` 下。它被保留在每日默认项之外,因为即使结果干净,macOS 构建也会主导运行时间。
|
||||
|
||||
### 关键质量类别
|
||||
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux 运行器上,对狭窄的高价值范围运行错误严重性、非安全的 JavaScript/TypeScript 质量查询。它的拉取请求防护刻意小于定时配置:非草稿 PR 只会为智能体命令/模型/工具执行和回复分发代码、配置 schema/迁移/IO 代码、认证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、内存运行时/SDK 粘合代码、MCP/进程/出站交付、提供商运行时/模型目录、会话诊断/交付队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行匹配的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
`CodeQL Critical Quality` 是对应的非安全分片。它只在较小的 Blacksmith Linux runner 上,对窄范围高价值表面运行错误严重级别、非安全的 JavaScript/TypeScript 质量查询。它的拉取请求保护有意小于定时配置文件:非草稿 PR 只会为智能体命令/模型/工具执行和回复分发代码、配置架构/迁移/IO 代码、凭证/密钥/沙箱/安全代码、核心渠道和内置渠道插件运行时、Gateway 网关协议/服务器方法、记忆运行时/SDK 胶水代码、MCP/进程/出站交付、提供商运行时/模型目录、会话诊断/交付队列、插件加载器、插件 SDK/包契约,或插件 SDK 回复运行时变更,运行对应的 `agent-runtime-boundary`、`config-boundary`、`core-auth-secrets`、`channel-runtime-boundary`、`gateway-runtime-boundary`、`memory-runtime-boundary`、`mcp-process-runtime-boundary`、`provider-runtime-boundary`、`session-diagnostics-boundary`、`plugin-boundary`、`plugin-sdk-package-contract` 和 `plugin-sdk-reply-runtime` 分片。CodeQL 配置和质量工作流变更会运行全部十二个 PR 质量分片。
|
||||
|
||||
手动分发接受:
|
||||
|
||||
@ -413,40 +413,40 @@ Matrix 会对定时和发布门禁使用 `--profile fast`,并且只有当检
|
||||
profile=all|agent-runtime-boundary|config-boundary|core-auth-secrets|channel-runtime-boundary|gateway-runtime-boundary|memory-runtime-boundary|mcp-process-runtime-boundary|plugin-boundary|plugin-sdk-package-contract|plugin-sdk-reply-runtime|provider-runtime-boundary|session-diagnostics-boundary
|
||||
```
|
||||
|
||||
这些窄配置是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
窄范围配置文件是用于单独运行一个质量分片的教学/迭代钩子。
|
||||
|
||||
| 类别 | 范围 |
|
||||
| 类别 | 表面 |
|
||||
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 认证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置 schema、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议 schema 和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站交付契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | 内存主机 SDK、内存运行时门面、内存插件 SDK 别名、内存运行时激活粘合代码,以及内存 Doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部机制、会话交付队列、出站会话绑定/交付辅助工具、诊断事件/日志包范围,以及会话 Doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载荷/分块/运行时辅助工具、渠道回复选项、交付队列,以及会话/线程绑定辅助工具 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商认证和设备发现、提供商运行时注册、提供商默认值/目录,以及 web/搜索/抓取/embedding 注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 启动、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 web 抓取/搜索、媒体 IO、媒体理解、图像生成和媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共范围和插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
|
||||
| `/codeql-critical-quality/core-auth-secrets` | 凭证、密钥、沙箱、cron 和 Gateway 网关安全边界代码 |
|
||||
| `/codeql-critical-quality/config-boundary` | 配置架构、迁移、规范化和 IO 契约 |
|
||||
| `/codeql-critical-quality/gateway-runtime-boundary` | Gateway 网关协议架构和服务器方法契约 |
|
||||
| `/codeql-critical-quality/channel-runtime-boundary` | 核心渠道和内置渠道插件实现契约 |
|
||||
| `/codeql-critical-quality/agent-runtime-boundary` | 命令执行、模型/提供商分发、自动回复分发和队列,以及 ACP 控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/mcp-process-runtime-boundary` | MCP 服务器和工具桥接、进程监督辅助工具,以及出站交付契约 |
|
||||
| `/codeql-critical-quality/memory-runtime-boundary` | 记忆宿主 SDK、记忆运行时门面、记忆插件 SDK 别名、记忆运行时激活胶水代码,以及记忆 Doctor 命令 |
|
||||
| `/codeql-critical-quality/session-diagnostics-boundary` | 回复队列内部、会话交付队列、出站会话绑定/交付辅助工具、诊断事件/日志包表面,以及会话 Doctor CLI 契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-reply-runtime` | 插件 SDK 入站回复分发、回复载荷/分块/运行时辅助工具、渠道回复选项、交付队列,以及会话/线程绑定辅助工具 |
|
||||
| `/codeql-critical-quality/provider-runtime-boundary` | 模型目录规范化、提供商凭证和设备发现、提供商运行时注册、提供商默认值/目录,以及 Web/搜索/获取/嵌入注册表 |
|
||||
| `/codeql-critical-quality/ui-control-plane` | 控制 UI 引导、本地持久化、Gateway 网关控制流,以及任务控制平面运行时契约 |
|
||||
| `/codeql-critical-quality/web-media-runtime-boundary` | 核心 Web 获取/搜索、媒体 IO、媒体理解、图像生成,以及媒体生成运行时契约 |
|
||||
| `/codeql-critical-quality/plugin-boundary` | 加载器、注册表、公共表面,以及插件 SDK 入口点契约 |
|
||||
| `/codeql-critical-quality/plugin-sdk-package-contract` | 已发布包侧插件 SDK 源码和插件包契约辅助工具 |
|
||||
|
||||
质量与安全保持分离,因此质量发现可以被定时、度量、禁用或扩展,而不会掩盖安全信号。只有在窄配置具备稳定运行时间和信号之后,Swift、Python 和内置插件 CodeQL 扩展才应作为有范围或分片的后续工作加回。
|
||||
质量与安全保持分离,这样质量发现就可以被定时运行、度量、禁用或扩展,而不会遮蔽安全信号。Swift、Python 和内置插件的 CodeQL 扩展,只有在窄范围配置文件具备稳定运行时间和信号之后,才应作为限定范围或分片的后续工作重新加入。
|
||||
|
||||
## 维护工作流
|
||||
|
||||
### Docs Agent
|
||||
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已向前移动,或过去一小时内已经创建过另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一次未跳过的 Docs Agent 源 SHA 到当前 `main` 的提交范围,因此每小时一次运行可以覆盖自上次文档检查以来积累的所有 main 变更。
|
||||
`Docs Agent` 工作流是一个事件驱动的 Codex 维护通道,用于让现有文档与最近落地的变更保持一致。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,手动分发也可以直接运行它。当 `main` 已经前进,或过去一小时内已经创建另一个未跳过的 Docs Agent 运行时,workflow-run 调用会跳过。运行时,它会审查从上一个未跳过的 Docs Agent 来源 SHA 到当前 `main` 的提交范围,因此一次每小时运行可以覆盖自上次文档巡检以来累积的所有 main 变更。
|
||||
|
||||
### Test Performance Agent
|
||||
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于处理慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果该 UTC 日已有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门控。该通道会构建全套分组 Vitest 性能报告,让 Codex 只做小型、保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行全套报告,并拒绝降低通过基线测试数量的变更。如果基线存在失败测试,Codex 只能修复明显失败项,并且智能体之后的全套报告必须通过,才会提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会 rebase 已验证的补丁,重新运行 `pnpm check:changed`,并重试 push;有冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与文档智能体相同的 drop-sudo 安全姿态。
|
||||
`Test Performance Agent` 工作流是一个事件驱动的 Codex 维护通道,用于慢测试。它没有纯定时计划:`main` 上一次成功的非机器人 push CI 运行可以触发它,但如果当天 UTC 已经有另一个 workflow-run 调用运行过或正在运行,它会跳过。手动分发会绕过这个每日活动门禁。该通道会构建完整套件分组 Vitest 性能报告,让 Codex 只进行小型且保持覆盖率的测试性能修复,而不是大范围重构,然后重新运行完整套件报告,并拒绝会降低通过基线测试数量的变更。如果基线中存在失败测试,Codex 只能修复明显失败项,且 agent 后的完整套件报告必须通过,之后才能提交任何内容。当 `main` 在机器人 push 落地前前进时,该通道会对已验证补丁执行 rebase,重新运行 `pnpm check:changed`,并重试 push;存在冲突的过期补丁会被跳过。它使用 GitHub 托管的 Ubuntu,因此 Codex action 可以保持与 docs agent 相同的 drop-sudo 安全姿态。
|
||||
|
||||
### 合并后的重复 PR
|
||||
|
||||
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复项清理。它默认 dry-run,只有在 `apply=true` 时才会关闭显式列出的 PR。在修改 GitHub 之前,它会验证已落地 PR 已合并,并且每个重复项都有共享的引用 issue 或重叠的变更 hunk。
|
||||
`Duplicate PRs After Merge` 工作流是一个手动维护者工作流,用于落地后的重复清理。它默认 dry-run,并且只有在 `apply=true` 时才会关闭明确列出的 PR。在修改 GitHub 前,它会验证已落地的 PR 已合并,并验证每个重复项要么有共享的引用 issue,要么有重叠的变更 hunk。
|
||||
|
||||
```bash
|
||||
gh workflow run duplicate-after-merge.yml \
|
||||
@ -455,29 +455,29 @@ gh workflow run duplicate-after-merge.yml \
|
||||
-f apply=true
|
||||
```
|
||||
|
||||
## 本地检查门控和变更路由
|
||||
## 本地检查门禁和变更路由
|
||||
|
||||
本地变更通道路由逻辑位于 `scripts/changed-lanes.mjs`,由 `scripts/check-changed.mjs` 执行。该本地检查门控比广泛的 CI 平台范围更严格地关注架构边界:
|
||||
本地变更通道逻辑位于 `scripts/changed-lanes.mjs`,并由 `scripts/check-changed.mjs` 执行。相比宽泛的 CI 平台范围,该本地检查门禁对架构边界更严格:
|
||||
|
||||
- 核心生产变更会运行核心生产和核心测试 typecheck,以及核心 lint/guard;
|
||||
- 仅核心测试变更只运行核心测试 typecheck 和核心 lint;
|
||||
- 插件生产变更会运行插件生产和插件测试 typecheck,以及插件 lint;
|
||||
- 仅插件测试变更会运行插件测试 typecheck 和插件 lint;
|
||||
- 公共插件 SDK 或插件契约变更会扩展到插件 typecheck,因为插件依赖这些核心契约(Vitest 插件扫查仍然是显式测试工作);
|
||||
- 仅发布元数据版本号提升会运行定向版本/配置/根依赖检查;
|
||||
- 未知根目录/配置变更会保守失败到所有检查通道。
|
||||
- 核心生产变更会运行核心生产和核心测试类型检查,以及核心 lint/防护;
|
||||
- 仅核心测试变更只会运行核心测试类型检查,以及核心 lint;
|
||||
- 插件生产变更会运行插件生产和插件测试类型检查,以及插件 lint;
|
||||
- 仅插件测试变更会运行插件测试类型检查,以及插件 lint;
|
||||
- 公共插件 SDK 或插件契约变更会扩展到插件类型检查,因为插件依赖这些核心契约(Vitest 插件扫描仍然是显式测试工作);
|
||||
- 仅发布元数据的版本号提升会运行定向版本/配置/根依赖检查;
|
||||
- 未知根目录/配置变更会故障保护到所有检查通道。
|
||||
|
||||
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且刻意比 `check:changed` 更便宜:直接测试编辑会运行自身,源码编辑优先使用显式映射,然后使用同级测试和导入图依赖项。共享群组房间交付配置是显式映射之一:对群组可见回复配置、源回复交付模式,或消息工具系统提示词的变更,会通过核心回复测试以及 Discord 和 Slack 交付回归测试,这样共享默认值变更会在第一次 PR push 前失败。只有当变更范围大到整个 harness,使便宜映射集合不再是可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
本地变更测试路由位于 `scripts/test-projects.test-support.mjs`,并且有意比 `check:changed` 更轻量:直接修改测试会运行这些测试本身,源代码修改会优先使用显式映射,然后是同级测试和导入图依赖项。共享群组房间投递配置是显式映射之一:对群组可见回复配置、源回复投递模式或 message-tool 系统提示词的更改,会路由到核心回复测试以及 Discord 和 Slack 投递回归测试,这样共享默认值变更会在第一次 PR 推送前失败。仅当变更的范围大到覆盖整个 harness,以至于这个轻量映射集合不能作为可信代理时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
|
||||
## Testbox 验证
|
||||
|
||||
从仓库根目录运行 Testbox,并且对广泛证明优先使用新预热的盒子。在把慢门控花到一个复用过、已过期,或刚报告了异常大同步的盒子上之前,先在盒子内运行 `pnpm testbox:sanity`。
|
||||
从仓库根目录运行 Testbox,并且在进行广泛证明时优先使用一个新预热的 box。在把一个慢速 gate 花在被复用、已过期或刚刚报告异常大同步量的 box 上之前,先在该 box 内运行 `pnpm testbox:sanity`。
|
||||
|
||||
当 `pnpm-lock.yaml` 等必需根文件消失,或 `git status --short` 显示至少 200 个已跟踪删除时,完整性检查会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;应停止该盒子并预热一个新的,而不是调试产品测试失败。对于有意的大规模删除 PR,请为该次完整性检查设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
当 `pnpm-lock.yaml` 等必需的根文件消失,或 `git status --short` 显示至少 200 个已跟踪删除项时,sanity check 会快速失败。这通常意味着远程同步状态不是 PR 的可信副本;应停止该 box 并预热一个新的,而不是调试产品测试失败。对于有意的大量删除 PR,请为该次 sanity 运行设置 `OPENCLAW_TESTBOX_ALLOW_MASS_DELETIONS=1`。
|
||||
|
||||
`pnpm testbox:run` 还会终止本地 Blacksmith CLI 调用:如果它停留在同步阶段超过五分钟且没有同步后输出。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或为异常大的本地差异使用更大的毫秒值。
|
||||
如果本地 Blacksmith CLI 调用停留在同步阶段超过五分钟且没有同步后输出,`pnpm testbox:run` 也会终止它。设置 `OPENCLAW_TESTBOX_SYNC_TIMEOUT_MS=0` 可禁用该保护,或为异常大的本地差异使用更大的毫秒值。
|
||||
|
||||
当 Blacksmith 不可用,或更适合使用自有云容量时,Crabbox 是仓库自有的第二条 Linux 远程盒验证路径。先预热一个盒子,通过项目工作流初始化它,然后通过 Crabbox CLI 运行命令:
|
||||
当 Blacksmith 不可用,或更适合使用自有云容量时,Crabbox 是仓库自有的第二条远程 box Linux 验证路径。预热一个 box,通过项目工作流为其 hydration,然后通过 Crabbox CLI 运行命令:
|
||||
|
||||
```bash
|
||||
pnpm crabbox:warmup -- --idle-timeout 90m
|
||||
@ -486,9 +486,9 @@ pnpm crabbox:run -- --id <cbx_id> --shell "OPENCLAW_TESTBOX=1 pnpm check:changed
|
||||
pnpm crabbox:stop -- <cbx_id>
|
||||
```
|
||||
|
||||
`.crabbox.yaml` 负责提供商、同步和 GitHub Actions 初始化默认值。它会排除本地 `.git`,这样初始化后的 Actions 检出会保留自己的远程 Git 元数据,而不是同步维护者本地的远程仓库配置和对象存储;它还会排除绝不应传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责检出、Node/pnpm 设置、`origin/main` 获取,以及后续 `crabbox run --id <cbx_id>` 命令会 source 的非机密环境交接。
|
||||
`.crabbox.yaml` 负责 provider、同步和 GitHub Actions hydration 默认值。它会排除本地 `.git`,这样 hydration 后的 Actions checkout 会保留自己的远程 Git 元数据,而不是同步维护者本地的 remotes 和 object stores;它还会排除不应被传输的本地运行时/构建产物。`.github/workflows/crabbox-hydrate.yml` 负责 checkout、Node/pnpm 设置、`origin/main` 获取,以及后续 `crabbox run --id <cbx_id>` 命令会 source 的非 secret 环境交接。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [安装概览](/zh-CN/install)
|
||||
- [开发渠道](/zh-CN/install/development-channels)
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
---
|
||||
read_when:
|
||||
- 你遇到连接/身份验证问题,并想要引导式修复
|
||||
- 你遇到连接或凭证问题,并想获得引导式修复
|
||||
- 你已更新并想做一次基本检查
|
||||
summary: '`openclaw doctor` 的 CLI 参考(健康检查 + 引导式修复)'
|
||||
title: Doctor
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T15:57:27Z"
|
||||
generated_at: "2026-05-02T18:56:23Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 90da8ffd705cd517fb90367164cc6af3e551befcec15c91746aa1e1e39454f09
|
||||
source_hash: c64cefee8f36b38657b72912271e3734411870376d2bd5a374d23a77a080035d
|
||||
source_path: cli/doctor.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# `openclaw doctor`
|
||||
|
||||
用于 Gateway 网关和渠道的健康检查 + 快速修复。
|
||||
Gateway 网关和渠道的健康检查 + 快速修复。
|
||||
|
||||
相关内容:
|
||||
相关:
|
||||
|
||||
- 故障排除:[故障排除](/zh-CN/gateway/troubleshooting)
|
||||
- 安全审计:[安全](/zh-CN/gateway/security)
|
||||
@ -36,41 +36,42 @@ openclaw doctor --generate-gateway-token
|
||||
|
||||
- `--no-workspace-suggestions`:禁用工作区记忆/搜索建议
|
||||
- `--yes`:不提示,接受默认值
|
||||
- `--repair`:不提示,应用推荐的非服务修复;Gateway 网关服务安装和重写仍需要交互式确认或显式 Gateway 网关命令
|
||||
- `--repair`:不提示,应用建议的非服务修复;Gateway 网关服务安装和重写仍需要交互式确认或显式 Gateway 网关命令
|
||||
- `--fix`:`--repair` 的别名
|
||||
- `--force`:应用激进修复,包括在需要时覆盖自定义服务配置
|
||||
- `--non-interactive`:无提示运行;仅执行安全迁移和非服务修复
|
||||
- `--generate-gateway-token`:生成并配置 Gateway 网关令牌
|
||||
- `--deep`:扫描系统服务中额外安装的 Gateway 网关
|
||||
- `--deep`:扫描系统服务,查找额外的 Gateway 网关安装
|
||||
|
||||
注意事项:
|
||||
|
||||
- 交互式提示(例如 keychain/OAuth 修复)仅在 stdin 是 TTY 且**未**设置 `--non-interactive` 时运行。无头运行(cron、Telegram、无终端)会跳过提示。
|
||||
- 性能:非交互式 `doctor` 运行会跳过预先加载插件,因此无头健康检查能保持快速。交互式会话在检查需要插件参与时仍会完整加载插件。
|
||||
- `--fix`(`--repair` 的别名)会将备份写入 `~/.openclaw/openclaw.json.bak`,并删除未知配置键名,同时列出每项删除。
|
||||
- `doctor --fix --non-interactive` 会报告缺失或过期的 Gateway 网关服务定义,但在更新修复模式之外不会安装或重写它们。对于缺失的服务,运行 `openclaw gateway install`;如果你明确想替换启动器,运行 `openclaw gateway install --force`。
|
||||
- 状态完整性检查现在会检测会话目录中的孤立转录文件。将它们归档为 `.deleted.<timestamp>` 需要交互式确认;`--fix`、`--yes` 和无头运行会将它们保留在原处。
|
||||
- Doctor 还会扫描 `~/.openclaw/cron/jobs.json`(或 `cron.store`)中的旧版 cron 任务形态,并可在调度器必须在运行时自动规范化它们之前就地重写它们。
|
||||
- 在 Linux 上,当用户的 crontab 仍运行旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 会发出警告;该脚本已不再维护,并且当 cron 缺少 systemd 用户总线环境时,可能记录虚假的 WhatsApp Gateway 网关中断。
|
||||
- Doctor 会清理由旧版 OpenClaw 创建的旧版插件依赖暂存状态。当注册表可以解析缺失的已配置可下载插件时,它也会修复这些插件;2026.5.2 的 Doctor 执行还会在将配置标记为该版本已触碰之前,自动安装旧配置已在使用的可下载插件。
|
||||
- Doctor 通过从 `plugins.allow`/`plugins.entries` 中删除缺失的插件 ID 来修复过期插件配置,并在插件发现健康时同时删除匹配的悬空渠道配置、Heartbeat 目标和渠道模型覆盖。
|
||||
- Doctor 通过禁用受影响的 `plugins.entries.<id>` 条目并移除其无效的 `config` 载荷来隔离无效插件配置。Gateway 网关启动时本来就只会跳过该坏插件,因此其他插件和渠道可以继续运行。
|
||||
- 当另一个监督进程拥有 Gateway 网关生命周期时,设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。Doctor 仍会报告 Gateway 网关/服务健康状态并应用非服务修复,但会跳过服务安装/启动/重启/bootstrap 以及旧版服务清理。
|
||||
- 在 Linux 上,Doctor 会忽略处于非活动状态的额外 Gateway 网关式 systemd 单元,并且在修复期间不会为正在运行的 systemd Gateway 网关服务重写命令/入口点元数据。如果你明确想替换活动启动器,请先停止服务,或使用 `openclaw gateway install --force`。
|
||||
- Doctor 会将旧版扁平 Talk 配置(`talk.voiceId`、`talk.modelId` 及相关配置)自动迁移到 `talk.provider` + `talk.providers.<provider>`。
|
||||
- 交互式提示(如 keychain/OAuth 修复)仅在 stdin 是 TTY 且**未**设置 `--non-interactive` 时运行。无头运行(cron、Telegram、无终端)会跳过提示。
|
||||
- 性能:非交互式 `doctor` 运行会跳过预先加载插件,让无头健康检查保持快速。交互式会话在检查需要插件贡献时仍会完整加载插件。
|
||||
- `--fix`(`--repair` 的别名)会将备份写入 `~/.openclaw/openclaw.json.bak`,并丢弃未知配置键,列出每一项移除。
|
||||
- `doctor --fix --non-interactive` 会报告缺失或过期的 Gateway 网关服务定义,但在更新修复模式之外不会安装或重写它们。对于缺失的服务,运行 `openclaw gateway install`;当你明确想替换启动器时,运行 `openclaw gateway install --force`。
|
||||
- 状态完整性检查现在会检测会话目录中的孤立 transcript 文件。将它们归档为 `.deleted.<timestamp>` 需要交互式确认;`--fix`、`--yes` 和无头运行会让它们保留在原处。
|
||||
- Doctor 也会扫描 `~/.openclaw/cron/jobs.json`(或 `cron.store`)以查找旧版 cron job 结构,并可在调度器必须在运行时自动规范化它们之前就地重写。
|
||||
- 在 Linux 上,当用户的 crontab 仍运行旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 会发出警告;该脚本不再维护,并且当 cron 缺少 systemd user-bus 环境时,可能会记录虚假的 WhatsApp Gateway 网关故障。
|
||||
- Doctor 会清理旧版 OpenClaw 创建的旧版插件依赖暂存状态。当 registry 能解析缺失的已配置可下载插件时,它也会修复它们,并且 2026.5.2 的 Doctor 检查会在将配置标记为该版本已触碰之前,自动安装旧配置已经使用的可下载插件。
|
||||
- 当插件发现正常时,Doctor 会通过从 `plugins.allow`/`plugins.entries` 移除缺失的插件 id,以及匹配的悬空渠道配置、Heartbeat 目标和渠道模型覆盖,来修复过期插件配置。
|
||||
- Doctor 会隔离无效插件配置,方法是禁用受影响的 `plugins.entries.<id>` 条目,并移除其无效的 `config` payload。Gateway 网关启动本来就只会跳过这个异常插件,因此其他插件和渠道可以继续运行。
|
||||
- 当另一个 supervisor 拥有 Gateway 网关生命周期时,设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。Doctor 仍会报告 Gateway 网关/服务健康状况并应用非服务修复,但会跳过服务安装/启动/重启/bootstrap 和旧版服务清理。
|
||||
- 在 Linux 上,Doctor 会忽略未激活的额外 Gateway 网关类似 systemd unit,并且在修复期间不会重写正在运行的 systemd Gateway 网关服务的命令/入口点元数据。当你明确想替换活动启动器时,先停止服务,或使用 `openclaw gateway install --force`。
|
||||
- Doctor 会将旧版扁平 Talk 配置(`talk.voiceId`、`talk.modelId` 及相关项)自动迁移到 `talk.provider` + `talk.providers.<provider>`。
|
||||
- 当唯一差异是对象键顺序时,重复运行 `doctor --fix` 不再报告/应用 Talk 规范化。
|
||||
- Doctor 包含记忆搜索就绪检查,并可在缺少嵌入凭证时推荐 `openclaw configure --section model`。
|
||||
- 当未配置命令所有者时,Doctor 会发出警告。命令所有者是被允许运行仅所有者命令并批准危险操作的人类操作员账号。私信配对只允许某人与 bot 对话;如果你在首个所有者 bootstrap 存在之前批准过发送者,请显式设置 `commands.ownerAllowFrom`。
|
||||
- 当已配置 Codex 模式智能体且操作员的 Codex 主目录中存在个人 Codex CLI 资产时,Doctor 会发出警告。本地 Codex app-server 启动会使用隔离的按智能体划分的主目录,因此请使用 `openclaw migrate codex --dry-run` 盘点应有意提升的资产。
|
||||
- 如果启用了沙箱模式但 Docker 不可用,Doctor 会报告一个高信号警告并附带补救方式(`install Docker` 或 `openclaw config set agents.defaults.sandbox.mode off`)。
|
||||
- 如果 `gateway.auth.token`/`gateway.auth.password` 由 SecretRef 管理且在当前命令路径中不可用,Doctor 会报告只读警告,并且不会写入明文回退凭证。
|
||||
- 如果在修复路径中检查渠道 SecretRef 失败,Doctor 会继续执行并报告警告,而不是提前退出。
|
||||
- 状态目录迁移后,当已启用的默认 Telegram 或 Discord 账号依赖环境回退,而 `TELEGRAM_BOT_TOKEN` 或 `DISCORD_BOT_TOKEN` 对 Doctor 进程不可用时,Doctor 会发出警告。
|
||||
- Telegram `allowFrom` 用户名自动解析(`doctor --fix`)需要当前命令路径中有可解析的 Telegram 令牌。如果令牌检查不可用,Doctor 会报告警告并跳过该轮自动解析。
|
||||
- Doctor 包含记忆搜索就绪检查,并且在缺少 embedding 凭证时可建议运行 `openclaw configure --section model`。
|
||||
- 当未配置命令所有者时,Doctor 会发出警告。命令所有者是允许运行仅所有者命令并批准危险操作的人类操作员账号。私信配对只允许某人与 bot 对话;如果你在首个所有者 bootstrap 存在之前批准过某个发送者,请显式设置 `commands.ownerAllowFrom`。
|
||||
- 当配置了 Codex 模式智能体,且操作员的 Codex home 中存在个人 Codex CLI 资产时,Doctor 会发出警告。本地 Codex app-server 启动使用按智能体隔离的 home,因此请使用 `openclaw migrate codex --dry-run` 清点应有意提升的资产。
|
||||
- 当默认智能体允许的 Skills 因缺少 bins、环境变量、配置或 OS 要求而在当前运行时环境中不可用时,Doctor 会发出警告。`doctor --fix` 可以通过 `skills.entries.<skill>.enabled=false` 禁用这些不可用 Skills;当你想保持该 skill 启用时,请改为安装/配置缺失要求。
|
||||
- 如果启用了沙箱模式但 Docker 不可用,Doctor 会报告高信号警告并附带修复方式(`install Docker` 或 `openclaw config set agents.defaults.sandbox.mode off`)。
|
||||
- 如果 `gateway.auth.token`/`gateway.auth.password` 由 SecretRef 管理且在当前命令路径中不可用,Doctor 会报告只读警告,并且不会写入明文 fallback 凭证。
|
||||
- 如果渠道 SecretRef 检查在修复路径中失败,Doctor 会继续并报告警告,而不是提前退出。
|
||||
- 状态目录迁移后,当已启用的默认 Telegram 或 Discord 账号依赖环境 fallback,且 Doctor 进程无法使用 `TELEGRAM_BOT_TOKEN` 或 `DISCORD_BOT_TOKEN` 时,Doctor 会发出警告。
|
||||
- Telegram `allowFrom` 用户名自动解析(`doctor --fix`)需要当前命令路径中存在可解析的 Telegram token。如果 token 检查不可用,Doctor 会报告警告,并跳过该次自动解析。
|
||||
|
||||
## macOS:`launchctl` 环境覆盖
|
||||
|
||||
如果你之前运行过 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(或 `...PASSWORD`),该值会覆盖你的配置文件,并可能导致持续的“unauthorized”错误。
|
||||
如果你之前运行过 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(或 `...PASSWORD`),该值会覆盖你的配置文件,并可能导致持续的 “unauthorized” 错误。
|
||||
|
||||
```bash
|
||||
launchctl getenv OPENCLAW_GATEWAY_TOKEN
|
||||
@ -80,7 +81,7 @@ launchctl unsetenv OPENCLAW_GATEWAY_TOKEN
|
||||
launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD
|
||||
```
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [CLI 参考](/zh-CN/cli)
|
||||
- [Gateway 网关 Doctor](/zh-CN/gateway/doctor)
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想查看哪些 Skills 可用并且已准备好运行
|
||||
- 你想查看哪些 Skills 可用并已准备好运行
|
||||
- 你想从 ClawHub 搜索、安装或更新 Skills
|
||||
- 你想调试 Skills 缺失的二进制文件、环境变量或配置
|
||||
summary: '`openclaw skills` 的 CLI 参考(search/install/update/list/info/check)'
|
||||
- 你想要调试 Skills 缺失的二进制文件/环境变量/配置
|
||||
summary: 用于 `openclaw skills` 的 CLI 参考(search/install/update/list/info/check)
|
||||
title: Skills
|
||||
x-i18n:
|
||||
generated_at: "2026-04-28T00:10:31Z"
|
||||
model: gpt-5.4
|
||||
generated_at: "2026-05-02T18:56:32Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 5059bf04c68dabe289d2c376407a52989c970e3d16e7637a2c83f4e24ad6564c
|
||||
source_hash: d819cdc421151a0093423f57a9e974489e9cc02de644358bd5700ee75181192e
|
||||
source_path: cli/skills.md
|
||||
workflow: 15
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
# `openclaw skills`
|
||||
@ -45,25 +45,26 @@ openclaw skills info <name>
|
||||
openclaw skills info <name> --json
|
||||
openclaw skills info <name> --agent <id>
|
||||
openclaw skills check
|
||||
openclaw skills check --json
|
||||
openclaw skills check --agent <id>
|
||||
openclaw skills check --json
|
||||
```
|
||||
|
||||
`search`/`install`/`update` 直接使用 ClawHub,并安装到当前工作区的 `skills/` 目录中。`list`/`info`/`check` 仍会检查当前工作区和配置可见的本地 Skills。基于工作区的命令会按以下顺序解析目标工作区:先看 `--agent <id>`,然后看当前工作目录是否位于已配置的 Agent 工作区内,最后回退到默认智能体。
|
||||
`search`/`install`/`update` 直接使用 ClawHub,并安装到当前工作区的 `skills/` 目录。`list`/`info`/`check` 仍会检查当前工作区和配置可见的本地 Skills。基于工作区的命令会先从 `--agent <id>` 解析目标工作区,然后在当前工作目录位于已配置的 agent 工作区内时使用当前工作目录,最后使用默认 agent。
|
||||
|
||||
这个 CLI `install` 命令会从 ClawHub 下载 skill 文件夹。由新手引导或 Skills 设置触发、基于 Gateway 网关的 skill 依赖安装,则会改用独立的 `skills.install` 请求路径。
|
||||
此 CLI `install` 命令会从 ClawHub 下载 Skills 文件夹。从新手引导或 Skills 设置触发的、由 Gateway 网关支持的 Skills 依赖安装,则使用单独的 `skills.install` 请求路径。
|
||||
|
||||
说明:
|
||||
注意:
|
||||
|
||||
- `search [query...]` 接受可选查询;省略时会浏览默认的 ClawHub 搜索流。
|
||||
- `search --limit <n>` 用于限制返回结果数量。
|
||||
- `install --force` 会覆盖工作区中相同 slug 的现有 skill 文件夹。
|
||||
- `--agent <id>` 会指定一个已配置的智能体工作区,并覆盖当前工作目录推断。
|
||||
- `update --all` 只会更新当前工作区中已跟踪的 ClawHub 安装项。
|
||||
- `search [query...]` 接受可选查询;省略它可浏览默认的 ClawHub 搜索信息流。
|
||||
- `search --limit <n>` 会限制返回结果数量。
|
||||
- `install --force` 会覆盖同一 slug 的现有工作区 Skills 文件夹。
|
||||
- `--agent <id>` 会定向到一个已配置的 agent 工作区,并覆盖当前工作目录推断。
|
||||
- `update --all` 只会更新当前工作区中已跟踪的 ClawHub 安装。
|
||||
- `check --agent <id>` 会检查所选 agent 的工作区,并报告哪些已就绪的 Skills 实际对该 agent 的提示词或命令界面可见。
|
||||
- 未提供子命令时,`list` 是默认操作。
|
||||
- `list`、`info` 和 `check` 会将渲染后的输出写入 stdout。使用 `--json` 时,这意味着机器可读的负载会保留在 stdout 中,便于管道和脚本使用。
|
||||
- `list`、`info` 和 `check` 会将渲染后的输出写入 stdout。使用 `--json` 时,这意味着机器可读的载荷会保留在 stdout,供管道和脚本使用。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [CLI 参考](/zh-CN/cli)
|
||||
- [Skills](/zh-CN/tools/skills)
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
---
|
||||
read_when:
|
||||
- 添加或修改 Doctor 迁移
|
||||
- 引入破坏性配置变更
|
||||
- 引入破坏兼容性的配置变更
|
||||
sidebarTitle: Doctor
|
||||
summary: Doctor 命令:健康检查、配置迁移和修复步骤
|
||||
title: Doctor
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T15:57:25Z"
|
||||
generated_at: "2026-05-02T18:56:13Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 1e8150c43662402a4dfe6eb89a804d1de3a73ad8a78f783fd0506e5976c2761f
|
||||
source_hash: 504cf06e8457315eb1df4970a877b88fdc2e32f34974ce789875373e9e030234
|
||||
source_path: gateway/doctor.md
|
||||
workflow: 16
|
||||
---
|
||||
@ -22,7 +22,7 @@ x-i18n:
|
||||
openclaw doctor
|
||||
```
|
||||
|
||||
### 无头和自动化模式
|
||||
### 无界面和自动化模式
|
||||
|
||||
<Tabs>
|
||||
<Tab title="--yes">
|
||||
@ -30,7 +30,7 @@ openclaw doctor
|
||||
openclaw doctor --yes
|
||||
```
|
||||
|
||||
不提示直接接受默认值(包括适用时的重启/服务/沙箱修复步骤)。
|
||||
不提示直接接受默认值(包括适用时的重启、服务、沙箱修复步骤)。
|
||||
|
||||
</Tab>
|
||||
<Tab title="--repair">
|
||||
@ -38,7 +38,7 @@ openclaw doctor
|
||||
openclaw doctor --repair
|
||||
```
|
||||
|
||||
不提示直接应用推荐的修复(在安全时执行修复 + 重启)。
|
||||
不提示直接应用推荐修复(在安全时执行修复 + 重启)。
|
||||
|
||||
</Tab>
|
||||
<Tab title="--repair --force">
|
||||
@ -46,7 +46,7 @@ openclaw doctor
|
||||
openclaw doctor --repair --force
|
||||
```
|
||||
|
||||
同时应用激进修复(会覆盖自定义 supervisor 配置)。
|
||||
同时应用激进修复(覆盖自定义 supervisor 配置)。
|
||||
|
||||
</Tab>
|
||||
<Tab title="--non-interactive">
|
||||
@ -54,7 +54,7 @@ openclaw doctor
|
||||
openclaw doctor --non-interactive
|
||||
```
|
||||
|
||||
不提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启/服务/沙箱操作。检测到旧版状态迁移时会自动运行。
|
||||
无提示运行,并且只应用安全迁移(配置规范化 + 磁盘状态移动)。跳过需要人工确认的重启、服务、沙箱操作。检测到旧版状态迁移时会自动运行。
|
||||
|
||||
</Tab>
|
||||
<Tab title="--deep">
|
||||
@ -67,7 +67,7 @@ openclaw doctor
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
如果你想在写入前查看更改,请先打开配置文件:
|
||||
如果你想在写入前查看变更,请先打开配置文件:
|
||||
|
||||
```bash
|
||||
cat ~/.openclaw/openclaw.json
|
||||
@ -77,34 +77,34 @@ cat ~/.openclaw/openclaw.json
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="健康、UI 和更新">
|
||||
- 对 git 安装执行可选的预检更新(仅交互模式)。
|
||||
- git 安装可选预检更新(仅交互模式)。
|
||||
- UI 协议新鲜度检查(当协议 schema 更新时重建 Control UI)。
|
||||
- 健康检查 + 重启提示。
|
||||
- Skills 状态摘要(符合条件/缺失/被阻止)和插件状态。
|
||||
- Skills Status 摘要(符合条件/缺失/被阻止)和插件 Status。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="配置和迁移">
|
||||
- 旧版值的配置规范化。
|
||||
- 将旧版扁平 `talk.*` 字段中的 Talk 配置迁移到 `talk.provider` + `talk.providers.<provider>`。
|
||||
- 针对旧版 Chrome 扩展配置和 Chrome MCP 就绪状态的浏览器迁移检查。
|
||||
- OpenCode provider 覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。
|
||||
- 将旧版扁平 `talk.*` 字段迁移到 `talk.provider` + `talk.providers.<provider>`。
|
||||
- 检查旧版 Chrome 扩展配置的浏览器迁移和 Chrome MCP 就绪状态。
|
||||
- OpenCode 提供商覆盖警告(`models.providers.opencode` / `models.providers.opencode-go`)。
|
||||
- Codex OAuth 遮蔽警告(`models.providers.openai-codex`)。
|
||||
- OpenAI Codex OAuth profile 的 OAuth TLS 前置条件检查。
|
||||
- 当 `plugins.allow` 具有限制性但工具策略仍请求通配符或插件拥有的工具时,发出插件/工具 allowlist 警告。
|
||||
- 旧版磁盘状态迁移(会话/agent 目录/WhatsApp 认证)。
|
||||
- 旧版插件 manifest 合约键迁移(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders` → `contracts`)。
|
||||
- 旧版 cron 存储迁移(`jobId`, `schedule.cron`, 顶层 delivery/payload 字段、payload `provider`、简单 `notify: true` webhook fallback jobs)。
|
||||
- 旧版 agent 运行时策略迁移到 `agents.defaults.agentRuntime` 和 `agents.list[].agentRuntime`。
|
||||
- 启用插件时清理过期插件配置;当 `plugins.enabled=false` 时,过期插件引用会被视为惰性的 containment 配置并保留。
|
||||
- 当 `plugins.allow` 具有限制性,但工具策略仍请求通配符或插件拥有的工具时,显示插件/工具 allowlist 警告。
|
||||
- 旧版磁盘状态迁移(会话/智能体目录/WhatsApp 凭证)。
|
||||
- 旧版插件 manifest 合约键迁移(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders` → `contracts`)。
|
||||
- 旧版 cron 存储迁移(`jobId`、`schedule.cron`、顶层 delivery/payload 字段、payload `provider`、简单的 `notify: true` webhook 兜底任务)。
|
||||
- 旧版智能体运行时策略迁移到 `agents.defaults.agentRuntime` 和 `agents.list[].agentRuntime`。
|
||||
- 插件启用时清理过期插件配置;当 `plugins.enabled=false` 时,过期插件引用会被视为惰性的隔离配置并保留。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="状态和完整性">
|
||||
- 会话锁文件检查和过期锁清理。
|
||||
- 修复受影响的 2026.4.24 构建创建的重复 prompt-rewrite 分支的会话 transcript。
|
||||
- 检测卡住的 subagent 重启恢复 tombstone,并支持使用 `--fix` 清除过期的 aborted recovery 标志,避免启动时继续将 child 视为 restart-aborted。
|
||||
- 状态完整性和权限检查(会话、transcripts、状态目录)。
|
||||
- 卡住的子智能体重启恢复 tombstone 检测,并通过 `--fix` 支持清除过期的已中止恢复标志,避免启动时持续将子项视为重启已中止。
|
||||
- 状态完整性和权限检查(会话、transcript、状态目录)。
|
||||
- 本地运行时检查配置文件权限(chmod 600)。
|
||||
- 模型认证健康状况:检查 OAuth 过期时间、可刷新即将过期的 token,并报告 auth-profile 冷却/禁用状态。
|
||||
- 模型凭证健康:检查 OAuth 过期时间,可刷新即将过期的 token,并报告 auth-profile 冷却/禁用状态。
|
||||
- 额外工作区目录检测(`~/openclaw`)。
|
||||
|
||||
</Accordion>
|
||||
@ -113,25 +113,26 @@ cat ~/.openclaw/openclaw.json
|
||||
- 旧版服务迁移和额外 Gateway 网关检测。
|
||||
- Matrix 渠道旧版状态迁移(在 `--fix` / `--repair` 模式中)。
|
||||
- Gateway 网关运行时检查(服务已安装但未运行;缓存的 launchd label)。
|
||||
- 渠道状态警告(从正在运行的 Gateway 网关探测)。
|
||||
- Supervisor 配置审计(launchd/systemd/schtasks),支持可选修复。
|
||||
- 清理 Gateway 网关服务中在安装或更新期间捕获的 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值所产生的嵌入式代理环境。
|
||||
- Gateway 网关运行时最佳实践检查(Node vs Bun、version-manager 路径)。
|
||||
- 渠道 Status 警告(从正在运行的 Gateway 网关探测)。
|
||||
- supervisor 配置审计(launchd/systemd/schtasks),可选择修复。
|
||||
- 清理 Gateway 网关服务在安装或更新期间捕获的 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 值的嵌入式代理环境。
|
||||
- Gateway 网关运行时最佳实践检查(Node 与 Bun、版本管理器路径)。
|
||||
- Gateway 网关端口冲突诊断(默认 `18789`)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="认证、安全和配对">
|
||||
<Accordion title="凭证、安全和配对">
|
||||
- 开放私信策略的安全警告。
|
||||
- 针对本地 token 模式的 Gateway 网关认证检查(没有 token 来源时提供 token 生成;不会覆盖 token SecretRef 配置)。
|
||||
- 设备配对问题检测(待处理的首次配对请求、待处理的角色/范围升级、过期的本地 device-token 缓存漂移,以及 paired-record 认证漂移)。
|
||||
- local token 模式的 Gateway 网关凭证检查(当不存在 token 来源时提供 token 生成;不会覆盖 token SecretRef 配置)。
|
||||
- 设备配对问题检测(待处理的首次配对请求、待处理的角色/范围升级、过期的本地 device-token 缓存漂移,以及 paired-record 凭证漂移)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="工作区和 shell">
|
||||
- Linux 上的 systemd linger 检查。
|
||||
- 工作区 bootstrap 文件大小检查(针对上下文文件的截断/接近限制警告)。
|
||||
- Shell 补全状态检查和自动安装/升级。
|
||||
- Memory 搜索 embedding 提供商就绪检查(本地模型、远程 API key 或 QMD binary)。
|
||||
- 源码安装检查(pnpm workspace 不匹配、缺少 UI assets、缺少 tsx binary)。
|
||||
- 工作区 bootstrap 文件大小检查(上下文文件的截断/接近上限警告)。
|
||||
- 默认智能体的 Skills 就绪状态检查;报告缺少 bin、env、配置或 OS 要求的已允许 skills,并且 `--fix` 可在 `skills.entries` 中禁用不可用的 skills。
|
||||
- shell completion Status 检查和自动安装/升级。
|
||||
- 记忆搜索 embedding 提供商就绪状态检查(本地模型、远程 API key 或 QMD binary)。
|
||||
- 源码安装检查(pnpm 工作区不匹配、缺少 UI assets、缺少 tsx binary)。
|
||||
- 写入更新后的配置 + 向导元数据。
|
||||
|
||||
</Accordion>
|
||||
@ -139,19 +140,19 @@ cat ~/.openclaw/openclaw.json
|
||||
|
||||
## Dreams UI 回填和重置
|
||||
|
||||
Control UI Dreams 场景包含 **Backfill**、**Reset** 和 **Clear Grounded** 操作,用于 grounded dreaming 工作流。这些操作使用 Gateway 网关 doctor 风格的 RPC 方法,但它们**不是** `openclaw doctor` CLI 修复/迁移的一部分。
|
||||
Control UI 的 Dreams 场景包含用于 grounded Dreaming 工作流的**回填**、**重置**和**清除 Grounded**操作。这些操作使用 Gateway 网关 doctor 风格的 RPC 方法,但它们**不是** `openclaw doctor` CLI 修复/迁移的一部分。
|
||||
|
||||
它们会做什么:
|
||||
|
||||
- **Backfill** 会扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM diary pass,并将可逆的回填条目写入 `DREAMS.md`。
|
||||
- **Reset** 只会从 `DREAMS.md` 中移除那些带标记的回填 diary 条目。
|
||||
- **Clear Grounded** 只会移除来自历史重放、且尚未积累实时召回或日常支持的 staged grounded-only 短期条目。
|
||||
- **回填**会扫描活动工作区中的历史 `memory/YYYY-MM-DD.md` 文件,运行 grounded REM diary pass,并将可逆的回填条目写入 `DREAMS.md`。
|
||||
- **重置**只会从 `DREAMS.md` 中移除这些已标记的回填 diary 条目。
|
||||
- **清除 Grounded**只会移除来自历史重放、且尚未积累 live recall 或 daily support 的暂存 grounded-only 短期条目。
|
||||
|
||||
它们本身**不会**做什么:
|
||||
|
||||
- 它们不会编辑 `MEMORY.md`
|
||||
- 它们不会运行完整的 doctor 迁移
|
||||
- 除非你先显式运行 staged CLI 路径,否则它们不会自动将 grounded candidates stage 到 live short-term promotion store
|
||||
- 它们不会运行完整 doctor 迁移
|
||||
- 除非你先显式运行暂存 CLI 路径,否则它们不会自动将 grounded 候选项暂存到 live 短期 promotion store
|
||||
|
||||
如果你想让 grounded 历史重放影响正常的 deep promotion lane,请改用 CLI 流程:
|
||||
|
||||
@ -159,32 +160,32 @@ Control UI Dreams 场景包含 **Backfill**、**Reset** 和 **Clear Grounded**
|
||||
openclaw memory rem-backfill --path ./memory --stage-short-term
|
||||
```
|
||||
|
||||
这会将 grounded durable candidates stage 到 short-term dreaming store,同时将 `DREAMS.md` 保留为 review surface。
|
||||
这会将 grounded durable 候选项暂存到短期 Dreaming 存储中,同时保持 `DREAMS.md` 作为审查界面。
|
||||
|
||||
## 详细行为和原理
|
||||
## 详细行为和原因
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="0. 可选更新(git 安装)">
|
||||
如果这是一个 git checkout 且 doctor 正在交互式运行,它会在运行 doctor 前提供更新选项(fetch/rebase/build)。
|
||||
如果这是一个 git checkout 且 doctor 正以交互方式运行,它会在运行 doctor 之前提供更新(fetch/rebase/build)选项。
|
||||
</Accordion>
|
||||
<Accordion title="1. 配置规范化">
|
||||
如果配置包含旧版值形状(例如没有特定渠道覆盖的 `messages.ackReaction`),doctor 会将其规范化为当前 schema。
|
||||
如果配置包含旧版值形态(例如没有渠道特定覆盖的 `messages.ackReaction`),doctor 会将它们规范化为当前 schema。
|
||||
|
||||
这包括旧版 Talk 扁平字段。当前公开的 Talk 配置是 `talk.provider` + `talk.providers.<provider>`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形状重写到提供商映射中。
|
||||
这包括旧版 Talk 扁平字段。当前公开 Talk 配置是 `talk.provider` + `talk.providers.<provider>`。Doctor 会将旧的 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 形态重写为提供商映射。
|
||||
|
||||
当 `plugins.allow` 非空且工具策略使用通配符或插件拥有的工具条目时,Doctor 也会发出警告。`tools.allow: ["*"]` 只匹配来自实际加载插件的工具;它不会绕过独占的插件 allowlist。
|
||||
当 `plugins.allow` 非空且工具策略使用通配符或插件拥有的工具条目时,Doctor 也会警告。`tools.allow: ["*"]` 只匹配实际加载的插件中的工具;它不会绕过独占插件 allowlist。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2. 旧版配置键迁移">
|
||||
当配置包含已弃用键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`。
|
||||
当配置包含已弃用的键时,其他命令会拒绝运行,并要求你运行 `openclaw doctor`。
|
||||
|
||||
Doctor 将会:
|
||||
Doctor 会:
|
||||
|
||||
- 说明发现了哪些旧版键。
|
||||
- 解释发现了哪些旧版键。
|
||||
- 显示它应用的迁移。
|
||||
- 使用更新后的 schema 重写 `~/.openclaw/openclaw.json`。
|
||||
|
||||
Gateway 网关在启动时检测到旧版配置格式时,也会自动运行 doctor 迁移,因此过期配置无需人工介入即可修复。Cron job store 迁移由 `openclaw doctor --fix` 处理。
|
||||
Gateway 网关在启动时检测到旧版配置格式,也会自动运行 doctor 迁移,因此过期配置无需人工介入即可修复。Cron 任务存储迁移由 `openclaw doctor --fix` 处理。
|
||||
|
||||
当前迁移:
|
||||
|
||||
@ -198,300 +199,300 @@ openclaw memory rem-backfill --path ./memory --stage-short-term
|
||||
- 旧版 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.<provider>`
|
||||
- `routing.agentToAgent` → `tools.agentToAgent`
|
||||
- `routing.transcribeAudio` → `tools.media.audio.models`
|
||||
- `messages.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `messages.tts.providers.<provider>`
|
||||
- `messages.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.<provider>`
|
||||
- `messages.tts.provider: "edge"` 和 `messages.tts.providers.edge` → `messages.tts.provider: "microsoft"` 和 `messages.tts.providers.microsoft`
|
||||
- `channels.discord.voice.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.voice.tts.providers.<provider>`
|
||||
- `channels.discord.accounts.<id>.voice.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`)→ `plugins.entries.voice-call.config.tts.providers.<provider>`
|
||||
- `channels.discord.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.voice.tts.providers.<provider>`
|
||||
- `channels.discord.accounts.<id>.voice.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `channels.discord.accounts.<id>.voice.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `plugins.entries.voice-call.config.tts.providers.<provider>`
|
||||
- `plugins.entries.voice-call.config.tts.provider: "edge"` 和 `plugins.entries.voice-call.config.tts.providers.edge` → `provider: "microsoft"` 和 `providers.microsoft`
|
||||
- `plugins.entries.voice-call.config.provider: "log"` → `"mock"`
|
||||
- `plugins.entries.voice-call.config.twilio.from` → `plugins.entries.voice-call.config.fromNumber`
|
||||
- `plugins.entries.voice-call.config.streaming.sttProvider` → `plugins.entries.voice-call.config.streaming.provider`
|
||||
- `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold` → `plugins.entries.voice-call.config.streaming.providers.openai.*`
|
||||
- `bindings[].match.accountID` → `bindings[].match.accountId`
|
||||
- 对于带有命名 `accounts` 但仍残留单账号顶层渠道值的渠道,将这些账号范围的值移动到该渠道选定提升的账号中(大多数渠道为 `accounts.default`;Matrix 可以保留现有匹配的命名/默认目标)
|
||||
- 对于配置了具名 `accounts` 但仍残留单账号顶层渠道值的渠道,将这些账号作用域值移入为该渠道选定的已提升账号(多数渠道使用 `accounts.default`;Matrix 可以保留现有的匹配具名/默认目标)
|
||||
- `identity` → `agents.list[].identity`
|
||||
- `agent.*` → `agents.defaults` + `tools.*`(工具/提升权限/执行/沙箱/子智能体)
|
||||
- `agent.*` → `agents.defaults` + `tools.*`(tools/elevated/exec/sandbox/subagents)
|
||||
- `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` → `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks`
|
||||
- 移除 `agents.defaults.llm`;对慢速提供商/模型超时使用 `models.providers.<id>.timeoutSeconds`
|
||||
- 移除 `agents.defaults.llm`;为较慢的提供商/模型超时使用 `models.providers.<id>.timeoutSeconds`
|
||||
- `browser.ssrfPolicy.allowPrivateNetwork` → `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`
|
||||
- `browser.profiles.*.driver: "extension"` → `"existing-session"`
|
||||
- 移除 `browser.relayBindHost`(旧版扩展中继设置)
|
||||
- 旧版 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是封闭失败)
|
||||
- 旧版 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 网关启动时也会跳过 `api` 设置为未来或未知枚举值的提供商,而不是以失败关闭方式退出)
|
||||
|
||||
Doctor 警告还会包含多账号渠道的账号默认值指导:
|
||||
Doctor 警告还包含多账号渠道的账号默认值指导:
|
||||
|
||||
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但没有配置 `channels.<channel>.defaultAccount` 或 `accounts.default`,Doctor 会警告回退路由可能选择意外账号。
|
||||
- 如果配置了两个或更多 `channels.<channel>.accounts` 条目,但未配置 `channels.<channel>.defaultAccount` 或 `accounts.default`,Doctor 会警告后备路由可能选择意外账号。
|
||||
- 如果 `channels.<channel>.defaultAccount` 设置为未知账号 ID,Doctor 会警告并列出已配置的账号 ID。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2b. OpenCode 提供商覆盖">
|
||||
如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型走错误的 API,或将费用清零。Doctor 会发出警告,这样你就可以移除覆盖并恢复按模型分配的 API 路由 + 费用。
|
||||
<Accordion title="2b. OpenCode 提供商覆盖项">
|
||||
如果你手动添加了 `models.providers.opencode`、`opencode-zen` 或 `opencode-go`,它会覆盖来自 `@mariozechner/pi-ai` 的内置 OpenCode 目录。这可能会强制模型使用错误 API,或将费用清零。Doctor 会发出警告,以便你移除覆盖项并恢复按模型划分的 API 路由与费用。
|
||||
</Accordion>
|
||||
<Accordion title="2c. 浏览器迁移和 Chrome MCP 就绪状态">
|
||||
如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,Doctor 会将其规范化为当前主机本地的 Chrome MCP 附加模型:
|
||||
如果你的浏览器配置仍指向已移除的 Chrome 扩展路径,Doctor 会将其规范化为当前的主机本地 Chrome MCP 附加模型:
|
||||
|
||||
- `browser.profiles.*.driver: "extension"` 变为 `"existing-session"`
|
||||
- `browser.relayBindHost` 会被移除
|
||||
|
||||
当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时,Doctor 还会审计主机本地的 Chrome MCP 路径:
|
||||
当你使用 `defaultProfile: "user"` 或已配置的 `existing-session` 配置文件时,Doctor 还会审计主机本地 Chrome MCP 路径:
|
||||
|
||||
- 检查默认自动连接配置文件所在的同一主机上是否安装了 Google Chrome
|
||||
- 检查同一主机上是否为默认自动连接配置文件安装了 Google Chrome
|
||||
- 检查检测到的 Chrome 版本,并在低于 Chrome 144 时发出警告
|
||||
- 提醒你在浏览器检查页面中启用远程调试(例如 `chrome://inspect/#remote-debugging`、`brave://inspect/#remote-debugging` 或 `edge://inspect/#remote-debugging`)
|
||||
|
||||
Doctor 无法替你启用 Chrome 端设置。主机本地 Chrome MCP 仍然要求:
|
||||
Doctor 无法替你启用 Chrome 端设置。主机本地 Chrome MCP 仍然需要:
|
||||
|
||||
- Gateway 网关/节点主机上有基于 Chromium 的浏览器 144+
|
||||
- Gateway 网关/节点主机上有 Chromium 系浏览器 144+
|
||||
- 浏览器在本地运行
|
||||
- 该浏览器中已启用远程调试
|
||||
- 批准浏览器中的首次附加同意提示
|
||||
- 在浏览器中批准首次附加同意提示
|
||||
|
||||
这里的就绪状态只涉及本地附加前提条件。Existing-session 会保留当前 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。
|
||||
这里的就绪状态只涉及本地附加前置条件。Existing-session 会保留当前 Chrome MCP 路由限制;`responsebody`、PDF 导出、下载拦截和批量操作等高级路由仍需要托管浏览器或原始 CDP 配置文件。
|
||||
|
||||
此检查**不**适用于 Docker、沙箱、远程浏览器或其他无头流程。它们会继续使用原始 CDP。
|
||||
此检查**不**适用于 Docker、沙箱、远程浏览器或其他 headless 流程。它们会继续使用原始 CDP。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2d. OAuth TLS 前提条件">
|
||||
配置 OpenAI Codex OAuth 配置文件时,Doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈是否可以验证证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、过期证书或自签名证书),Doctor 会打印平台特定的修复指导。在使用 Homebrew Node 的 macOS 上,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,探测也会运行。
|
||||
<Accordion title="2d. OAuth TLS 前置条件">
|
||||
配置 OpenAI Codex OAuth 配置文件时,Doctor 会探测 OpenAI 授权端点,以验证本地 Node/OpenSSL TLS 栈能否验证证书链。如果探测因证书错误失败(例如 `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`、证书过期或自签名证书),Doctor 会打印特定平台的修复指导。在使用 Homebrew Node 的 macOS 上,修复通常是 `brew postinstall ca-certificates`。使用 `--deep` 时,即使 Gateway 网关健康,探测也会运行。
|
||||
</Accordion>
|
||||
<Accordion title="2e. Codex OAuth 提供商覆盖">
|
||||
如果你之前在 `models.providers.openai-codex` 下添加过旧版 OpenAI 传输设置,它们可能会遮蔽新版会自动使用的内置 Codex OAuth 提供商路径。Doctor 在发现这些旧传输设置与 Codex OAuth 并存时会发出警告,这样你就可以移除或重写过期的传输覆盖,并恢复内置路由/回退行为。仍然支持自定义代理和仅标头覆盖,且不会触发此警告。
|
||||
<Accordion title="2e. Codex OAuth 提供商覆盖项">
|
||||
如果你之前在 `models.providers.openai-codex` 下添加了旧版 OpenAI 传输设置,它们可能会遮蔽新版发布中自动使用的内置 Codex OAuth 提供商路径。Doctor 在看到这些旧传输设置与 Codex OAuth 同时存在时会发出警告,以便你移除或重写过时的传输覆盖项,并恢复内置路由/后备行为。自定义代理和仅标头覆盖项仍受支持,且不会触发此警告。
|
||||
</Accordion>
|
||||
<Accordion title="2f. Codex 插件路由警告">
|
||||
启用内置 Codex 插件时,Doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI 运行器解析。当你希望通过 PI 使用 Codex OAuth/订阅凭证时,这种组合是有效的,但它很容易与原生 Codex app-server harness 混淆。Doctor 会发出警告,并指向明确的 app-server 形态:`openai/*` 加 `agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。
|
||||
启用内置 Codex 插件后,Doctor 还会检查 `openai-codex/*` 主模型引用是否仍通过默认 PI runner 解析。当你希望通过 PI 使用 Codex OAuth/订阅凭证时,这种组合是有效的,但它很容易与原生 Codex app-server harness 混淆。Doctor 会发出警告并指向明确的 app-server 形态:`openai/*` 加 `agentRuntime.id: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。
|
||||
|
||||
Doctor 不会自动修复这一点,因为两种路由都是有效的:
|
||||
Doctor 不会自动修复此项,因为两条路由都有效:
|
||||
|
||||
- `openai-codex/*` + PI 表示“通过普通 OpenClaw 运行器使用 Codex OAuth/订阅凭证”。
|
||||
- `openai/*` + `agentRuntime.id: "codex"` 表示“通过原生 Codex app-server 运行嵌入式轮次”。
|
||||
- `/codex ...` 表示“从聊天中控制或绑定原生 Codex 对话”。
|
||||
- `/acp ...` 或 `runtime: "acp"` 表示“使用外部 ACP/acpx 适配器”。
|
||||
- `openai-codex/*` + PI 表示“通过正常 OpenClaw runner 使用 Codex OAuth/订阅凭证。”
|
||||
- `openai/*` + `agentRuntime.id: "codex"` 表示“通过原生 Codex app-server 运行嵌入式回合。”
|
||||
- `/codex ...` 表示“从聊天控制或绑定原生 Codex 对话。”
|
||||
- `/acp ...` 或 `runtime: "acp"` 表示“使用外部 ACP/acpx 适配器。”
|
||||
|
||||
如果出现警告,请选择你原本想要的路由并手动编辑配置。当 PI Codex OAuth 是有意配置时,请保持警告原样。
|
||||
如果出现警告,请选择你预期的路由并手动编辑配置。当 PI Codex OAuth 是有意设置时,请保持该警告不变。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3. 旧版状态迁移(磁盘布局)">
|
||||
Doctor 可以将较旧的磁盘布局迁移到当前结构:
|
||||
|
||||
- 会话存储 + 转录:
|
||||
- 会话存储 + transcripts:
|
||||
- 从 `~/.openclaw/sessions/` 到 `~/.openclaw/agents/<agentId>/sessions/`
|
||||
- 智能体目录:
|
||||
- Agent 目录:
|
||||
- 从 `~/.openclaw/agent/` 到 `~/.openclaw/agents/<agentId>/agent/`
|
||||
- WhatsApp 凭证状态(Baileys):
|
||||
- 从旧版 `~/.openclaw/credentials/*.json`(`oauth.json` 除外)
|
||||
- 到 `~/.openclaw/credentials/whatsapp/<accountId>/...`(默认账号 ID:`default`)
|
||||
|
||||
这些迁移是尽力而为且幂等的;当 Doctor 将任何旧版文件夹保留为备份时,会发出警告。Gateway 网关/CLI 在启动时也会自动迁移旧版会话 + 智能体目录,因此历史记录/凭证/模型会落到按智能体划分的路径中,而不需要手动运行 Doctor。WhatsApp 凭证特意只通过 `openclaw doctor` 迁移。Talk 提供商/提供商映射规范化现在会按结构相等进行比较,因此仅键顺序不同的差异不再触发重复的无操作 `doctor --fix` 更改。
|
||||
这些迁移是尽力而为且幂等的;当 Doctor 留下任何旧版文件夹作为备份时,会发出警告。Gateway 网关/CLI 也会在启动时自动迁移旧版会话 + agent 目录,使历史记录/凭证/模型进入按 agent 划分的路径,而无需手动运行 Doctor。WhatsApp 凭证有意只通过 `openclaw doctor` 迁移。Talk 提供商/provider-map 规范化现在会按结构相等进行比较,因此仅键顺序不同的 diff 不再触发重复的无操作 `doctor --fix` 变更。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3a. 旧版插件清单迁移">
|
||||
Doctor 会扫描所有已安装插件清单,查找已弃用的顶层能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。发现后,它会提供将它们移动到 `contracts` 对象并就地重写清单文件的操作。此迁移是幂等的;如果 `contracts` 键已经具有相同的值,旧版键会被移除,而不会重复数据。
|
||||
Doctor 会扫描所有已安装的插件清单,查找已弃用的顶层能力键(`speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders`、`webSearchProviders`)。找到后,它会提议将它们移入 `contracts` 对象,并就地重写清单文件。此迁移是幂等的;如果 `contracts` 键已经有相同的值,则会移除旧版键而不复制数据。
|
||||
</Accordion>
|
||||
<Accordion title="3b. 旧版 cron 存储迁移">
|
||||
Doctor 还会检查 cron 作业存储(默认是 `~/.openclaw/cron/jobs.json`,覆盖时为 `cron.store`)中是否存在调度器为兼容性仍接受的旧作业形态。
|
||||
Doctor 还会检查 cron 作业存储(默认是 `~/.openclaw/cron/jobs.json`,或在覆盖时为 `cron.store`),查找调度器为兼容性仍接受的旧作业形态。
|
||||
|
||||
当前 cron 清理包括:
|
||||
|
||||
- `jobId` → `id`
|
||||
- `schedule.cron` → `schedule.expr`
|
||||
- 顶层 payload 字段(`message`、`model`、`thinking` 等)→ `payload`
|
||||
- 顶层 delivery 字段(`deliver`、`channel`、`to`、`provider` 等)→ `delivery`
|
||||
- payload `provider` 投递别名 → 显式 `delivery.channel`
|
||||
- 简单旧版 `notify: true` webhook 回退作业 → 显式 `delivery.mode="webhook"` 并设置 `delivery.to=cron.webhook`
|
||||
- 顶层 payload 字段(`message`、`model`、`thinking`、...)→ `payload`
|
||||
- 顶层 delivery 字段(`deliver`、`channel`、`to`、`provider`、...)→ `delivery`
|
||||
- payload `provider` 交付别名 → 显式 `delivery.channel`
|
||||
- 简单旧版 `notify: true` webhook 后备作业 → 显式 `delivery.mode="webhook"` 且 `delivery.to=cron.webhook`
|
||||
|
||||
Doctor 只会在不改变行为的情况下自动迁移 `notify: true` 作业。如果某个作业将旧版通知回退与现有的非 webhook 投递模式组合使用,Doctor 会发出警告,并将该作业留给人工审查。
|
||||
Doctor 只会在不改变行为的情况下自动迁移 `notify: true` 作业。如果某个作业将旧版通知后备与现有非 webhook 交付模式组合使用,Doctor 会警告并将该作业留待人工审查。
|
||||
|
||||
在 Linux 上,如果用户的 crontab 仍调用旧版 `~/.openclaw/bin/ensure-whatsapp.sh`,Doctor 也会发出警告。当前 OpenClaw 不维护这个主机本地脚本,并且当 cron 无法访问 systemd 用户总线时,它可能会向 `~/.openclaw/logs/whatsapp-health.log` 写入错误的 `Gateway inactive` 消息。使用 `crontab -e` 移除过期的 crontab 条目;使用 `openclaw channels status --probe`、`openclaw doctor` 和 `openclaw gateway status` 进行当前健康检查。
|
||||
在 Linux 上,当用户的 crontab 仍调用旧版 `~/.openclaw/bin/ensure-whatsapp.sh` 时,Doctor 也会发出警告。该主机本地脚本不再由当前 OpenClaw 维护,并且当 cron 无法访问 systemd 用户总线时,可能会向 `~/.openclaw/logs/whatsapp-health.log` 写入错误的 `Gateway inactive` 消息。使用 `crontab -e` 移除过时的 crontab 条目;当前健康检查请使用 `openclaw channels status --probe`、`openclaw doctor` 和 `openclaw gateway status`。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3c. 会话锁清理">
|
||||
Doctor 会扫描每个智能体会话目录,查找过期的写入锁文件,即会话异常退出后遗留下来的文件。对于找到的每个锁文件,它会报告:路径、PID、PID 是否仍然存活、锁的存在时长,以及是否被视为过期(PID 已死亡或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动移除过期锁文件;否则会打印说明,并指示你使用 `--fix` 重新运行。
|
||||
Doctor 会扫描每个智能体会话目录,查找过期的写入锁文件,即会话异常退出时留下的文件。对于找到的每个锁文件,它会报告:路径、PID、PID 是否仍然存活、锁的存在时长,以及它是否被视为过期(PID 已死或超过 30 分钟)。在 `--fix` / `--repair` 模式下,它会自动删除过期锁文件;否则会打印一条说明,并指示你使用 `--fix` 重新运行。
|
||||
</Accordion>
|
||||
<Accordion title="3d. 会话转录分支修复">
|
||||
Doctor 会扫描智能体会话 JSONL 文件,查找由 2026.4.24 提示词转录重写 bug 创建的重复分支形态:一个带有 OpenClaw 内部运行时上下文的废弃用户轮次,加上一个包含相同可见用户提示词的活跃同级分支。在 `--fix` / `--repair` 模式下,Doctor 会在原文件旁备份每个受影响文件,并将转录重写为活跃分支,这样 Gateway 网关历史记录和记忆读取器就不会再看到重复轮次。
|
||||
Doctor 会扫描智能体会话 JSONL 文件,查找由 2026.4.24 prompt 转录重写 bug 创建的重复分支形态:一个带有 OpenClaw 内部运行时上下文的废弃用户轮次,以及一个包含相同可见用户 prompt 的活动同级分支。在 `--fix` / `--repair` 模式下,Doctor 会将每个受影响文件备份到原文件旁边,并将转录重写为活动分支,这样 Gateway 网关历史记录和记忆读取器就不会再看到重复轮次。
|
||||
</Accordion>
|
||||
<Accordion title="4. 状态完整性检查(会话持久化、路由和安全)">
|
||||
状态目录是运行中的中枢。如果它消失,你会丢失会话、凭证、日志和配置(除非你在其他地方有备份)。
|
||||
状态目录是运行中的核心中枢。如果它消失,你会丢失会话、凭证、日志和配置(除非你在其他位置有备份)。
|
||||
|
||||
Doctor 会检查:
|
||||
|
||||
- **状态目录缺失**:警告灾难性状态丢失,提示重新创建目录,并提醒你它无法恢复缺失的数据。
|
||||
- **状态目录权限**:验证是否可写;提供修复权限的选项(检测到所有者/组不匹配时会发出 `chown` 提示)。
|
||||
- **macOS 云同步状态目录**:当状态解析到 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为由同步支持的路径可能导致更慢的 I/O 以及锁/同步竞态。
|
||||
- **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为基于 SD 或 eMMC 的随机 I/O 在会话和凭证写入下可能更慢且磨损更快。
|
||||
- **状态目录缺失**:警告灾难性状态丢失,提示重新创建目录,并提醒你它无法恢复丢失的数据。
|
||||
- **状态目录权限**:验证可写性;提供修复权限的选项(并在检测到所有者/组不匹配时输出 `chown` 提示)。
|
||||
- **macOS 云同步状态目录**:当状态解析到 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`)或 `~/Library/CloudStorage/...` 下时发出警告,因为同步支持的路径可能导致更慢的 I/O 以及锁/同步竞态。
|
||||
- **Linux SD 或 eMMC 状态目录**:当状态解析到 `mmcblk*` 挂载源时发出警告,因为 SD 或 eMMC 支持的随机 I/O 在会话和凭证写入期间可能更慢且磨损更快。
|
||||
- **会话目录缺失**:`sessions/` 和会话存储目录是持久化历史记录并避免 `ENOENT` 崩溃所必需的。
|
||||
- **转录不匹配**:当最近的会话条目缺少转录文件时发出警告。
|
||||
- **主会话“1 行 JSONL”**:当主转录只有一行时标记(历史记录未在累积)。
|
||||
- **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能在不同安装之间分裂)。
|
||||
- **远程模式提醒**:如果 `gateway.mode=remote`,Doctor 会提醒你在远程主机上运行它(状态存放在那里)。
|
||||
- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被组/所有人读取,则发出警告,并提供收紧到 `600` 的选项。
|
||||
- **转录不匹配**:当近期会话条目缺少转录文件时发出警告。
|
||||
- **主会话“1 行 JSONL”**:当主转录只有一行时标记(历史记录没有累积)。
|
||||
- **多个状态目录**:当多个主目录中存在多个 `~/.openclaw` 文件夹,或 `OPENCLAW_STATE_DIR` 指向其他位置时发出警告(历史记录可能会在安装之间拆分)。
|
||||
- **远程模式提醒**:如果 `gateway.mode=remote`,Doctor 会提醒你在远程主机上运行它(状态存储在那里)。
|
||||
- **配置文件权限**:如果 `~/.openclaw/openclaw.json` 可被组/全局读取,则发出警告并提供收紧到 `600` 的选项。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="5. 模型认证健康状况(OAuth 过期)">
|
||||
Doctor 会检查认证存储中的 OAuth 配置文件,在令牌即将过期或已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件已过期,它会建议使用 Anthropic API key 或 Anthropic 设置令牌路径。刷新提示只会在交互式运行(TTY)时出现;`--non-interactive` 会跳过刷新尝试。
|
||||
<Accordion title="5. 模型凭证健康状态(OAuth 过期)">
|
||||
Doctor 会检查凭证存储中的 OAuth 配置文件,在令牌即将过期/已过期时发出警告,并在安全时刷新它们。如果 Anthropic OAuth/令牌配置文件过期,它会建议使用 Anthropic API key 或 Anthropic 设置令牌路径。刷新提示仅在交互式运行(TTY)时出现;`--non-interactive` 会跳过刷新尝试。
|
||||
|
||||
当 OAuth 刷新永久失败时(例如 `refresh_token_reused`、`invalid_grant`,或提供商要求你重新登录),Doctor 会报告需要重新认证,并打印要运行的确切 `openclaw models auth login --provider ...` 命令。
|
||||
当 OAuth 刷新永久失败时(例如 `refresh_token_reused`、`invalid_grant`,或提供商告知你需要重新登录),Doctor 会报告需要重新认证,并打印要运行的精确 `openclaw models auth login --provider ...` 命令。
|
||||
|
||||
Doctor 还会报告因以下原因暂时不可用的认证配置文件:
|
||||
Doctor 还会报告因以下原因暂时不可用的凭证配置文件:
|
||||
|
||||
- 短暂冷却(速率限制/超时/认证失败)
|
||||
- 较长时间禁用(账单/额度失败)
|
||||
- 较长时间禁用(计费/额度失败)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="6. Hooks 模型验证">
|
||||
如果设置了 `hooks.gmail.model`,Doctor 会根据目录和允许列表验证模型引用,并在它无法解析或被禁止时发出警告。
|
||||
<Accordion title="6. 钩子模型验证">
|
||||
如果设置了 `hooks.gmail.model`,Doctor 会根据目录和允许列表验证模型引用,并在它无法解析或不被允许时发出警告。
|
||||
</Accordion>
|
||||
<Accordion title="7. 沙箱镜像修复">
|
||||
启用沙箱隔离时,Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧版名称的选项。
|
||||
启用沙箱隔离时,Doctor 会检查 Docker 镜像,并在当前镜像缺失时提供构建或切换到旧名称的选项。
|
||||
</Accordion>
|
||||
<Accordion title="7b. 插件安装清理">
|
||||
Doctor 会在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下移除旧版 OpenClaw 生成的插件依赖暂存状态。这包括过期的生成依赖根目录、旧安装阶段目录,以及早期内置插件依赖修复代码留下的包本地残留。
|
||||
Doctor 会在 `openclaw doctor --fix` / `openclaw doctor --repair` 模式下移除旧版 OpenClaw 生成的插件依赖暂存状态。这涵盖过期的生成依赖根目录、旧安装阶段目录,以及早期内置插件依赖修复代码留下的包本地残留物。
|
||||
|
||||
当配置引用了可下载插件,但本地插件注册表找不到它们时,Doctor 也可以重新安装已配置的可下载插件。对于 2026.5.2 内置插件外部化,Doctor 会自动安装现有配置已经使用的可下载插件,然后依赖 `meta.lastTouchedVersion` 使该发布处理只运行一次。Gateway 网关启动和配置重新加载不会运行包管理器;插件安装仍然是显式的 Doctor/安装/更新工作。
|
||||
当配置引用了可下载插件但本地插件注册表找不到它们时,Doctor 也可以重新安装已配置的可下载插件。对于 2026.5.2 内置插件外部化,Doctor 会自动安装现有配置已经使用的可下载插件,然后依赖 `meta.lastTouchedVersion` 让该发布处理只运行一次。Gateway 网关启动和配置重载不会运行包管理器;插件安装仍然是显式的 Doctor/install/update 工作。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="8. Gateway 网关服务迁移和清理提示">
|
||||
Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),并提供移除它们以及使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类似 Gateway 网关的服务并打印清理提示。以配置文件命名的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。
|
||||
Doctor 会检测旧版 Gateway 网关服务(launchd/systemd/schtasks),并提供移除它们、使用当前 Gateway 网关端口安装 OpenClaw 服务的选项。它还可以扫描额外的类似 Gateway 网关的服务并打印清理提示。带配置文件名称的 OpenClaw Gateway 网关服务被视为一等服务,不会被标记为“额外”。
|
||||
|
||||
在 Linux 上,如果缺少用户级 Gateway 网关服务,但存在系统级 OpenClaw Gateway 网关服务,Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep` 或 `openclaw doctor --deep` 检查,然后移除重复项;如果 Gateway 网关生命周期由系统监督器管理,则设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。
|
||||
在 Linux 上,如果用户级 Gateway 网关服务缺失但存在系统级 OpenClaw Gateway 网关服务,Doctor 不会自动安装第二个用户级服务。使用 `openclaw gateway status --deep` 或 `openclaw doctor --deep` 检查,然后移除重复服务;如果 Gateway 网关生命周期由系统 supervisor 管理,则设置 `OPENCLAW_SERVICE_REPAIR_POLICY=external`。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="8b. 启动时 Matrix 迁移">
|
||||
当 Matrix 渠道账户存在待处理或可操作的旧版状态迁移时,Doctor(在 `--fix` / `--repair` 模式下)会创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都是非致命的;错误会被记录,启动会继续。在只读模式(不带 `--fix` 的 `openclaw doctor`)下,此检查会被完全跳过。
|
||||
当 Matrix 渠道账户有待处理或可执行的旧版状态迁移时,Doctor 会在 `--fix` / `--repair` 模式下创建迁移前快照,然后运行尽力而为的迁移步骤:旧版 Matrix 状态迁移和旧版加密状态准备。这两个步骤都是非致命的;错误会被记录,启动会继续。在只读模式(不带 `--fix` 的 `openclaw doctor`)下,此检查会被完全跳过。
|
||||
</Accordion>
|
||||
<Accordion title="8c. 设备配对和认证漂移">
|
||||
Doctor 现在会将设备配对状态作为正常健康检查的一部分进行检查。
|
||||
<Accordion title="8c. 设备配对和凭证漂移">
|
||||
Doctor 现在会把设备配对状态作为正常健康检查的一部分进行检查。
|
||||
|
||||
它会报告:
|
||||
|
||||
- 待处理的首次配对请求
|
||||
- 已配对设备待处理的角色升级
|
||||
- 已配对设备待处理的范围升级
|
||||
- 设备 ID 仍然匹配但设备身份不再匹配已批准记录的公钥不匹配修复
|
||||
- 已配对设备的待处理角色升级
|
||||
- 已配对设备的待处理范围升级
|
||||
- 设备 ID 仍匹配但设备身份不再匹配已批准记录时的公钥不匹配修复
|
||||
- 已配对记录缺少已批准角色的有效令牌
|
||||
- 已配对令牌的范围偏离已批准的配对基线
|
||||
- 当前机器上的本地缓存设备令牌条目早于 Gateway 网关侧令牌轮换,或带有过时的范围元数据
|
||||
- 作用域偏离已批准配对基线的已配对令牌
|
||||
- 当前机器上的本地缓存设备令牌条目早于 Gateway 网关端令牌轮换,或带有过期的作用域元数据
|
||||
|
||||
Doctor 不会自动批准配对请求或自动轮换设备令牌。它会改为打印确切的后续步骤:
|
||||
Doctor 不会自动批准配对请求,也不会自动轮换设备令牌。它会改为打印精确的后续步骤:
|
||||
|
||||
- 使用 `openclaw devices list` 检查待处理请求
|
||||
- 使用 `openclaw devices approve <requestId>` 批准确切请求
|
||||
- 使用 `openclaw devices rotate --device <deviceId> --role <role>` 轮换新令牌
|
||||
- 使用 `openclaw devices remove <deviceId>` 移除并重新批准过时记录
|
||||
- 使用 `openclaw devices approve <requestId>` 批准指定请求
|
||||
- 使用 `openclaw devices rotate --device <deviceId> --role <role>` 轮换一个新令牌
|
||||
- 使用 `openclaw devices remove <deviceId>` 移除并重新批准过期记录
|
||||
|
||||
这填补了常见的“已配对但仍提示需要配对”漏洞:Doctor 现在会区分首次配对、待处理的角色/范围升级,以及过时令牌/设备身份漂移。
|
||||
这堵住了常见的“已经配对但仍提示需要配对”漏洞:doctor 现在会区分首次配对、待处理的角色/作用域升级,以及过期的令牌/设备身份漂移。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="9. 安全警告">
|
||||
当提供商在没有允许列表的情况下向私信开放,或策略以危险方式配置时,Doctor 会发出警告。
|
||||
当 provider 在没有 allowlist 的情况下向私信开放,或策略以危险方式配置时,Doctor 会发出警告。
|
||||
</Accordion>
|
||||
<Accordion title="10. systemd linger(Linux)">
|
||||
如果作为 systemd 用户服务运行,Doctor 会确保已启用 linger,这样 Gateway 网关在登出后仍保持运行。
|
||||
如果以 systemd 用户服务运行,doctor 会确保已启用 lingering,让 Gateway 网关在注销后仍保持运行。
|
||||
</Accordion>
|
||||
<Accordion title="11. 工作区状态(Skills、插件和旧版目录)">
|
||||
<Accordion title="11. 工作区状态(Skills、插件和旧目录)">
|
||||
Doctor 会打印默认智能体的工作区状态摘要:
|
||||
|
||||
- **Skills 状态**:统计符合条件、缺少要求以及被允许列表阻止的 Skills。
|
||||
- **旧版工作区目录**:当 `~/openclaw` 或其他旧版工作区目录与当前工作区并存时发出警告。
|
||||
- **Skills 状态**:统计符合条件、缺少要求以及被 allowlist 阻止的 Skills。
|
||||
- **旧工作区目录**:当 `~/openclaw` 或其他旧工作区目录与当前工作区并存时发出警告。
|
||||
- **插件状态**:统计已启用/已禁用/出错的插件;列出任何错误对应的插件 ID;报告捆绑插件能力。
|
||||
- **插件兼容性警告**:标记与当前运行时存在兼容性问题的插件。
|
||||
- **插件诊断**:显示插件注册表在加载时发出的任何警告或错误。
|
||||
- **插件诊断**:暴露插件注册表在加载时发出的任何警告或错误。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="11b. Bootstrap 文件大小">
|
||||
Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近限制时,Doctor 会打印用于调整 `agents.defaults.bootstrapMaxChars` 和 `agents.defaults.bootstrapTotalMaxChars` 的提示。
|
||||
Doctor 会检查工作区 bootstrap 文件(例如 `AGENTS.md`、`CLAUDE.md` 或其他注入的上下文文件)是否接近或超过配置的字符预算。它会报告每个文件的原始字符数与注入字符数、截断百分比、截断原因(`max/file` 或 `max/total`),以及总注入字符数占总预算的比例。当文件被截断或接近限制时,doctor 会打印用于调优 `agents.defaults.bootstrapMaxChars` 和 `agents.defaults.bootstrapTotalMaxChars` 的提示。
|
||||
</Accordion>
|
||||
<Accordion title="11d. 清理过时渠道插件">
|
||||
当 `openclaw doctor --fix` 移除缺失的渠道插件时,它也会移除引用该插件的悬空渠道作用域配置:`channels.<id>` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["<channel>/*"]` 覆盖项。这可以防止渠道运行时已不存在但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。
|
||||
<Accordion title="11d. 清理过期渠道插件">
|
||||
当 `openclaw doctor --fix` 移除缺失的渠道插件时,它还会移除引用该插件的悬空渠道范围配置:`channels.<id>` 条目、命名该渠道的 Heartbeat 目标,以及 `agents.*.models["<channel>/*"]` 覆盖项。这可以防止渠道运行时已消失但配置仍要求 Gateway 网关绑定到它而导致的 Gateway 网关启动循环。
|
||||
</Accordion>
|
||||
<Accordion title="11c. Shell 补全">
|
||||
Doctor 会检查当前 shell(zsh、bash、fish 或 PowerShell)是否已安装 Tab 补全:
|
||||
|
||||
- 如果 shell 配置文件使用慢速动态补全模式(`source <(openclaw completion ...)`),Doctor 会将其升级为更快的缓存文件变体。
|
||||
- 如果补全已在配置文件中配置但缓存文件缺失,Doctor 会自动重新生成缓存。
|
||||
- 如果完全未配置补全,Doctor 会提示安装它(仅交互模式;使用 `--non-interactive` 时跳过)。
|
||||
- 如果 shell 配置文件使用较慢的动态补全模式(`source <(openclaw completion ...)`),doctor 会将其升级为更快的缓存文件变体。
|
||||
- 如果补全已在配置文件中配置但缓存文件缺失,doctor 会自动重新生成缓存。
|
||||
- 如果完全没有配置补全,doctor 会提示安装它(仅交互模式;使用 `--non-interactive` 时跳过)。
|
||||
|
||||
运行 `openclaw completion --write-state` 可手动重新生成缓存。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="12. Gateway 网关身份验证检查(本地令牌)">
|
||||
Doctor 会检查本地 Gateway 网关令牌身份验证就绪状态。
|
||||
<Accordion title="12. Gateway 网关认证检查(本地令牌)">
|
||||
Doctor 会检查本地 Gateway 网关令牌认证就绪状态。
|
||||
|
||||
- 如果令牌模式需要令牌且没有令牌来源,Doctor 会提议生成一个。
|
||||
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,Doctor 会发出警告,并且不会用明文覆盖它。
|
||||
- `openclaw doctor --generate-gateway-token` 只会在未配置令牌 SecretRef 时强制生成。
|
||||
- 如果令牌模式需要令牌但不存在令牌来源,doctor 会提示生成一个。
|
||||
- 如果 `gateway.auth.token` 由 SecretRef 管理但不可用,doctor 会发出警告,并且不会用明文覆盖它。
|
||||
- `openclaw doctor --generate-gateway-token` 只有在未配置令牌 SecretRef 时才会强制生成。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="12b. 支持只读 SecretRef 的修复">
|
||||
某些修复流程需要检查已配置凭证,同时不削弱运行时快速失败行为。
|
||||
<Accordion title="12b. 感知只读 SecretRef 的修复">
|
||||
某些修复流程需要在不削弱运行时快速失败行为的情况下检查已配置的凭证。
|
||||
|
||||
- `openclaw doctor --fix` 现在针对定向配置修复,使用与 Status 系列命令相同的只读 SecretRef 摘要模型。
|
||||
- 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的机器人凭证。
|
||||
- 如果 Telegram 机器人令牌通过 SecretRef 配置,但在当前命令路径中不可用,Doctor 会报告该凭证已配置但不可用,并跳过自动解析,而不是崩溃或误报令牌缺失。
|
||||
- `openclaw doctor --fix` 现在会使用与 status 系列命令相同的只读 SecretRef 摘要模型来执行有针对性的配置修复。
|
||||
- 示例:Telegram `allowFrom` / `groupAllowFrom` `@username` 修复会在可用时尝试使用已配置的 bot 凭证。
|
||||
- 如果 Telegram bot 令牌通过 SecretRef 配置,但在当前命令路径中不可用,doctor 会报告该凭证已配置但不可用,并跳过自动解析,而不是崩溃或错误报告令牌缺失。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="13. Gateway 网关健康检查 + 重启">
|
||||
Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提出重启建议。
|
||||
Doctor 会运行健康检查,并在 Gateway 网关看起来不健康时提供重启选项。
|
||||
</Accordion>
|
||||
<Accordion title="13b. 记忆搜索就绪状态">
|
||||
Doctor 会检查已配置的记忆搜索嵌入提供商是否已为默认智能体就绪。其行为取决于已配置的后端和提供商:
|
||||
Doctor 会检查配置的记忆搜索嵌入提供商是否已为默认智能体就绪。行为取决于配置的后端和提供商:
|
||||
|
||||
- **QMD 后端**:探测 `qmd` 二进制文件是否可用且可启动。如果不可用,则打印修复指导,包括 npm 包和手动二进制路径选项。
|
||||
- **显式本地提供商**:检查本地模型文件或可识别的远程/可下载模型 URL。如果缺失,则建议切换到远程提供商。
|
||||
- **显式远程提供商**(`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失,则打印可操作的修复提示。
|
||||
- **自动提供商**:先检查本地模型可用性,然后按自动选择顺序逐一尝试各个远程提供商。
|
||||
- **显式远程提供商**(`openai`、`voyage` 等):验证环境或认证存储中是否存在 API key。如果缺失,则打印可执行的修复提示。
|
||||
- **自动提供商**:先检查本地模型可用性,然后按自动选择顺序尝试每个远程提供商。
|
||||
|
||||
当缓存的 Gateway 网关探测结果可用时(Gateway 网关在检查时是健康的),Doctor 会将其结果与 CLI 可见的配置交叉比对,并指出任何差异。Doctor 不会在默认路径上启动新的嵌入 ping;如果你想要实时提供商检查,请使用深度记忆 Status 命令。
|
||||
当存在缓存的 Gateway 网关探测结果(检查时 Gateway 网关处于健康状态)时,Doctor 会将其结果与 CLI 可见配置交叉比对,并指出任何不一致。Doctor 不会在默认路径上启动新的嵌入 ping;如果你想进行实时提供商检查,请使用深度记忆 Status 命令。
|
||||
|
||||
使用 `openclaw memory status --deep` 在运行时验证嵌入就绪状态。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="14. 渠道 Status 警告">
|
||||
如果 Gateway 网关健康,Doctor 会运行渠道 Status 探测,并报告警告及建议的修复方法。
|
||||
如果 Gateway 网关健康,Doctor 会运行渠道 Status 探测,并报告带有建议修复方案的警告。
|
||||
</Accordion>
|
||||
<Accordion title="15. 监督器配置审计 + 修复">
|
||||
Doctor 会检查已安装的监督器配置(launchd/systemd/schtasks)是否缺失默认值或默认值已过时(例如 systemd network-online 依赖和重启延迟)。当发现不匹配时,它会建议更新,并且可以将服务文件/任务重写为当前默认值。
|
||||
<Accordion title="15. Supervisor 配置审计 + 修复">
|
||||
Doctor 会检查已安装的 supervisor 配置(launchd/systemd/schtasks)是否缺少默认值或使用了过期默认值(例如 systemd network-online 依赖和重启延迟)。发现不匹配时,它会建议更新,并可将服务文件/任务重写为当前默认值。
|
||||
|
||||
注意:
|
||||
|
||||
- `openclaw doctor` 会在重写监督器配置前提示。
|
||||
- `openclaw doctor --yes` 会接受默认修复提示。
|
||||
- `openclaw doctor --repair` 会在不提示的情况下应用推荐修复。
|
||||
- `openclaw doctor --repair --force` 会覆盖自定义监督器配置。
|
||||
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` 会让 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/引导、监督器配置重写以及旧版服务清理,因为外部监督器拥有该生命周期。
|
||||
- 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时,Doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外 Gateway 网关类单元,这样配套服务文件不会产生清理噪音。
|
||||
- 如果令牌认证需要令牌,且 `gateway.auth.token` 由 SecretRef 管理,Doctor 服务安装/修复会验证 SecretRef,但不会将解析后的明文令牌值持久化到监督器服务环境元数据中。
|
||||
- Doctor 会检测旧版 LaunchAgent、systemd 或 Windows Scheduled Task 安装曾内联嵌入的托管 `.env`/SecretRef 支持的服务环境值,并重写服务元数据,使这些值从运行时源加载,而不是从监督器定义加载。
|
||||
- Doctor 会检测服务命令是否在 `gateway.port` 变更后仍固定旧的 `--port`,并将服务元数据重写为当前端口。
|
||||
- 如果令牌认证需要令牌,且已配置的令牌 SecretRef 未解析,Doctor 会阻止安装/修复路径,并给出可操作的指导。
|
||||
- `openclaw doctor` 在重写 supervisor 配置之前会提示。
|
||||
- `openclaw doctor --yes` 接受默认修复提示。
|
||||
- `openclaw doctor --repair` 无提示应用建议修复。
|
||||
- `openclaw doctor --repair --force` 覆盖自定义 supervisor 配置。
|
||||
- `OPENCLAW_SERVICE_REPAIR_POLICY=external` 让 Doctor 对 Gateway 网关服务生命周期保持只读。它仍会报告服务健康状态并运行非服务修复,但会跳过服务安装/启动/重启/引导、supervisor 配置重写,以及旧版服务清理,因为该生命周期由外部 supervisor 拥有。
|
||||
- 在 Linux 上,当匹配的 systemd Gateway 网关单元处于活动状态时,Doctor 不会重写命令/入口点元数据。它还会在重复服务扫描期间忽略非活动的非旧版额外 Gateway 网关类单元,因此配套服务文件不会产生清理噪音。
|
||||
- 如果令牌认证需要令牌且 `gateway.auth.token` 由 SecretRef 管理,Doctor 服务安装/修复会验证 SecretRef,但不会将解析后的明文令牌值持久化到 supervisor 服务环境元数据中。
|
||||
- Doctor 会检测旧版 LaunchAgent、systemd 或 Windows Scheduled Task 安装内联嵌入的托管 `.env`/SecretRef 支持的服务环境值,并重写服务元数据,让这些值从运行时来源加载,而不是从 supervisor 定义加载。
|
||||
- Doctor 会检测服务命令是否在 `gateway.port` 更改后仍固定旧的 `--port`,并将服务元数据重写为当前端口。
|
||||
- 如果令牌认证需要令牌且配置的令牌 SecretRef 无法解析,Doctor 会通过可执行的指导阻止安装/修复路径。
|
||||
- 如果同时配置了 `gateway.auth.token` 和 `gateway.auth.password`,且 `gateway.auth.mode` 未设置,Doctor 会阻止安装/修复,直到显式设置模式。
|
||||
- 对于 Linux 用户 systemd 单元,Doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=` 和 `EnvironmentFile=` 源。
|
||||
- 对于 Linux user-systemd 单元,Doctor 令牌漂移检查现在会在比较服务认证元数据时同时包含 `Environment=` 和 `EnvironmentFile=` 来源。
|
||||
- 当配置最后由较新版本写入时,Doctor 服务修复会拒绝从旧版 OpenClaw 二进制文件重写、停止或重启 Gateway 网关服务。请参阅 [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)。
|
||||
- 你始终可以通过 `openclaw gateway install --force` 强制完整重写。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="16. Gateway 网关运行时 + 端口诊断">
|
||||
Doctor 会检查服务运行时(PID、上次退出 Status),并在服务已安装但实际未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。
|
||||
Doctor 会检查服务运行时(PID、上次退出 Status),并在服务已安装但实际上未运行时发出警告。它还会检查 Gateway 网关端口(默认 `18789`)上的端口冲突,并报告可能原因(Gateway 网关已在运行、SSH 隧道)。
|
||||
</Accordion>
|
||||
<Accordion title="17. Gateway 网关运行时最佳实践">
|
||||
当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等)上时,Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,而版本管理器路径在升级后可能会失效,因为服务不会加载你的 shell 初始化脚本。当系统 Node 安装可用时(Homebrew/apt/choco),Doctor 会提出迁移到系统 Node 安装。
|
||||
当 Gateway 网关服务运行在 Bun 或版本管理的 Node 路径(`nvm`、`fnm`、`volta`、`asdf` 等)上时,Doctor 会发出警告。WhatsApp + Telegram 渠道需要 Node,且版本管理器路径可能在升级后失效,因为服务不会加载你的 shell init。Doctor 会在可用时提供迁移到系统 Node 安装的选项(Homebrew/apt/choco)。
|
||||
|
||||
新安装或已修复的 macOS LaunchAgent 会使用规范的系统 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`),而不是复制交互式 shell PATH,因此 Volta、asdf、fnm、pnpm 和其他版本管理器目录不会改变 Node 子进程解析到的内容。Linux 服务仍会保留显式环境根(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)以及稳定的用户 bin 目录,但猜测得到的版本管理器回退目录只有在这些目录实际存在于磁盘上时,才会写入服务 PATH。
|
||||
新安装或修复的 macOS LaunchAgent 使用规范的系统 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`),而不是复制交互式 shell PATH,因此 Volta、asdf、fnm、pnpm 和其他版本管理器目录不会改变 Node 子进程解析到的路径。Linux 服务仍保留显式环境根目录(`NVM_DIR`、`FNM_DIR`、`VOLTA_HOME`、`ASDF_DATA_DIR`、`BUN_INSTALL`、`PNPM_HOME`)和稳定的用户 bin 目录,但猜测的版本管理器回退目录只有在磁盘上存在时才会写入服务 PATH。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="18. 配置写入 + 向导元数据">
|
||||
Doctor 会持久化任何配置变更,并标记向导元数据以记录 Doctor 运行。
|
||||
Doctor 会持久化所有配置更改,并标记向导元数据以记录本次 Doctor 运行。
|
||||
</Accordion>
|
||||
<Accordion title="19. 工作区提示(备份 + 记忆系统)">
|
||||
当缺少工作区记忆系统时,Doctor 会提出建议;如果工作区尚未纳入 git,则会打印备份提示。
|
||||
当缺少工作区记忆系统时,Doctor 会建议添加;如果工作区尚未纳入 git,则会打印备份提示。
|
||||
|
||||
请参阅 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),获取工作区结构和 git 备份的完整指南(推荐使用私有 GitHub 或 GitLab)。
|
||||
请参阅 [/concepts/agent-workspace](/zh-CN/concepts/agent-workspace),获取关于工作区结构和 git 备份(推荐私有 GitHub 或 GitLab)的完整指南。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [Gateway 网关运行手册](/zh-CN/gateway)
|
||||
- [Gateway 网关故障排除](/zh-CN/gateway/troubleshooting)
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
---
|
||||
read_when:
|
||||
- 更改 OpenClaw 更新、Doctor、包验收或插件安装行为
|
||||
- 准备或批准发布候选版
|
||||
- 排查软件包更新、插件依赖清理或插件安装回归问题
|
||||
- 更改 OpenClaw 更新、Doctor、软件包验收或插件安装行为
|
||||
- 准备或批准发布候选版本
|
||||
- 调试包更新、插件依赖清理或插件安装回归问题
|
||||
sidebarTitle: Update and plugin tests
|
||||
summary: OpenClaw 如何验证更新路径、包迁移以及插件安装/更新行为
|
||||
summary: OpenClaw 如何验证更新路径、包迁移和插件安装/更新行为
|
||||
title: 更新和插件测试
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T15:57:40Z"
|
||||
generated_at: "2026-05-02T18:56:28Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 7843767a4acca25ceea62633faa5f4bec954bebf7cc4eeb9f3b0b990313ff946
|
||||
source_hash: 1a56e249f565cc23a439142b3332c0a57fd4afe9021b79f644d353946d6d2ffc
|
||||
source_path: help/testing-updates-plugins.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
这是更新和插件验证的专用清单。目标很简单:证明可安装的软件包可以更新真实用户状态,通过 `doctor` 修复过时的旧版状态,并且仍然可以从受支持的来源安装、加载、更新和卸载插件。
|
||||
这是更新和插件验证的专用清单。目标很简单:证明可安装包能够更新真实用户状态,通过 `doctor` 修复过时的旧版状态,并且仍然可以从受支持的来源安装、加载、更新和卸载插件。
|
||||
|
||||
更完整的测试运行器地图见 [测试](/zh-CN/help/testing)。实时提供商密钥和会接触网络的测试套件见 [实时测试](/zh-CN/help/testing-live)。
|
||||
关于更广泛的测试运行器地图,请参阅 [测试](/zh-CN/help/testing)。关于实时提供商密钥和会触达网络的套件,请参阅 [实时测试](/zh-CN/help/testing-live)。
|
||||
|
||||
## 我们保护的内容
|
||||
|
||||
更新和插件测试保护这些契约:
|
||||
|
||||
- 软件包 tarball 是完整的,包含有效的 `dist/postinstall-inventory.json`,并且不依赖未打包的仓库文件。
|
||||
- 用户可以从较旧的已发布软件包迁移到候选软件包,而不会丢失配置、智能体、会话、工作区、插件允许列表或渠道配置。
|
||||
- `openclaw doctor --fix --non-interactive` 负责旧版清理和修复路径。启动过程不应为过时的插件状态增加隐藏的兼容迁移。
|
||||
- 插件可以从本地目录、git 仓库、npm 软件包和 ClawHub 注册表路径安装。
|
||||
- 插件 npm 依赖安装在托管 npm root 中,在信任前会被扫描,并且卸载时通过 npm 移除,以免提升安装的依赖残留。
|
||||
- 当没有任何变化时,插件更新保持稳定:安装记录、解析后的来源、已安装依赖布局和启用状态都保持不变。
|
||||
- 包 tarball 是完整的,具有有效的 `dist/postinstall-inventory.json`,并且不依赖未打包的仓库文件。
|
||||
- 用户可以从较旧的已发布包迁移到候选包,而不会丢失配置、智能体、会话、工作区、插件允许列表或渠道配置。
|
||||
- `openclaw doctor --fix --non-interactive` 负责旧版清理和修复路径。启动时不应为过时的插件状态增加隐藏的兼容性迁移。
|
||||
- 插件安装可从本地目录、git 仓库、npm 包和 ClawHub 注册表路径运行。
|
||||
- 插件 npm 依赖安装在托管 npm 根目录中,在信任之前会被扫描,并在卸载期间通过 npm 移除,因此提升安装的依赖不会残留。
|
||||
- 插件更新在没有变化时保持稳定:安装记录、解析后的来源、已安装依赖布局和启用状态都保持不变。
|
||||
|
||||
## 开发期间的本地证明
|
||||
|
||||
@ -40,25 +40,25 @@ pnpm check:changed
|
||||
pnpm test:changed
|
||||
```
|
||||
|
||||
对于插件安装、卸载、依赖或软件包清单变更,还要运行覆盖已编辑接缝的聚焦测试:
|
||||
对于插件安装、卸载、依赖或包清单变更,还要运行覆盖已编辑接缝的聚焦测试:
|
||||
|
||||
```bash
|
||||
pnpm test src/plugins/uninstall.test.ts src/infra/package-dist-inventory.test.ts test/scripts/package-acceptance-workflow.test.ts
|
||||
```
|
||||
|
||||
在任何软件包 Docker lane 使用 tarball 之前,先证明软件包工件:
|
||||
在任何包 Docker 通道消费 tarball 之前,先证明包产物:
|
||||
|
||||
```bash
|
||||
pnpm release:check
|
||||
```
|
||||
|
||||
`release:check` 会运行配置/文档/API 漂移检查,写入软件包 dist 清单,运行 `npm pack --dry-run`,拒绝禁止打包的文件,将 tarball 安装到临时前缀中,运行 postinstall,并对内置渠道入口点做冒烟测试。
|
||||
`release:check` 会运行配置/文档/API 漂移检查,写入包 dist 清单,运行 `npm pack --dry-run`,拒绝被禁止打包的文件,将 tarball 安装到临时前缀,运行 postinstall,并对内置渠道入口点做冒烟测试。
|
||||
|
||||
## Docker lanes
|
||||
## Docker 通道
|
||||
|
||||
Docker lanes 是产品级证明。它们会在 Linux 容器内安装或更新真实软件包,并通过 CLI 命令、Gateway 网关启动、HTTP 探针、RPC 状态和文件系统状态断言行为。
|
||||
Docker 通道是产品级证明。它们会在 Linux 容器内安装或更新真实包,并通过 CLI 命令、Gateway 网关启动、HTTP 探测、RPC 状态和文件系统状态断言行为。
|
||||
|
||||
迭代时使用聚焦 lanes:
|
||||
迭代时使用聚焦通道:
|
||||
|
||||
```bash
|
||||
pnpm test:docker:plugins
|
||||
@ -68,13 +68,13 @@ pnpm test:docker:published-upgrade-survivor
|
||||
pnpm test:docker:update-migration
|
||||
```
|
||||
|
||||
重要 lanes:
|
||||
重要通道:
|
||||
|
||||
- `test:docker:plugins` 验证插件安装冒烟、本地文件夹安装、本地文件夹更新跳过行为、带预安装依赖的本地文件夹、`file:` 软件包安装、带 CLI 执行的 git 安装、git 移动引用更新、带提升安装的传递依赖的 npm 注册表安装、npm 更新空操作、本地 ClawHub fixture 安装和更新空操作、marketplace 更新行为,以及 Claude-bundle 启用/检查。设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可让 ClawHub 代码块保持 hermetic/离线。
|
||||
- `test:docker:plugin-update` 验证未变化的已安装插件在 `openclaw plugins update` 期间不会重新安装,也不会丢失安装元数据。
|
||||
- `test:docker:upgrade-survivor` 将候选 tarball 安装到脏的旧用户 fixture 上,运行软件包更新和非交互式 doctor,然后启动 loopback Gateway 网关并检查状态保留。
|
||||
- `test:docker:published-upgrade-survivor` 会先安装一个已发布基线,通过内置的 `openclaw config set` 配方配置它,将其更新到候选 tarball,运行 doctor,检查旧版清理,启动 Gateway 网关,并探测 `/healthz`、`/readyz` 和 RPC 状态。
|
||||
- `test:docker:update-migration` 是清理密集型的已发布更新 lane。它从已配置的 Discord/Telegram 风格用户状态开始,运行基线 doctor,让已配置插件依赖有机会实体化,为已配置的打包插件播种旧版插件依赖残留,更新到候选 tarball,并要求更新后的 doctor 移除旧版依赖 root。
|
||||
- `test:docker:plugins` 验证插件安装冒烟、本地文件夹安装、本地文件夹更新跳过行为、带预安装依赖的本地文件夹、`file:` 包安装、带 CLI 执行的 git 安装、git 移动引用更新、带提升安装传递依赖的 npm 注册表安装、npm 更新空操作、本地 ClawHub fixture 安装和更新空操作、市场更新行为,以及 Claude 捆绑包启用/检查。设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可让 ClawHub 块保持 hermetic/离线。
|
||||
- `test:docker:plugin-update` 验证未更改的已安装插件在 `openclaw plugins update` 期间不会重新安装或丢失安装元数据。
|
||||
- `test:docker:upgrade-survivor` 将候选 tarball 安装到脏的旧用户 fixture 之上,运行包更新和非交互式 doctor,然后启动 local loopback Gateway 网关并检查状态保留。
|
||||
- `test:docker:published-upgrade-survivor` 会先安装已发布的基线,通过烘焙好的 `openclaw config set` 配方配置它,将其更新到候选 tarball,运行 doctor,检查旧版清理,启动 Gateway 网关,并探测 `/healthz`、`/readyz` 和 RPC 状态。
|
||||
- `test:docker:update-migration` 是清理较重的已发布更新通道。它从已配置的 Discord/Telegram 风格用户状态开始,运行基线 doctor,让已配置插件依赖有机会具现化,为已配置的打包插件种入旧版插件依赖残留,更新到候选 tarball,并要求更新后的 doctor 移除旧版依赖根目录。
|
||||
|
||||
有用的已发布升级幸存者变体:
|
||||
|
||||
@ -88,9 +88,9 @@ OPENCLAW_UPGRADE_SURVIVOR_SCENARIO=bootstrap-persona \
|
||||
pnpm test:docker:published-upgrade-survivor
|
||||
```
|
||||
|
||||
可用场景包括 `base`、`feishu-channel`、`bootstrap-persona`、`plugin-deps-cleanup`、`configured-plugin-installs`、`tilde-log-path` 和 `versioned-runtime-deps`。在聚合运行中,`OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues` 会展开为所有已报告问题形状的场景,包括已配置插件安装迁移。
|
||||
可用场景包括 `base`、`feishu-channel`、`bootstrap-persona`、`plugin-deps-cleanup`、`configured-plugin-installs`、`tilde-log-path` 和 `versioned-runtime-deps`。在聚合运行中,`OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues` 会扩展为所有已报告问题形态的场景,包括已配置插件安装迁移。
|
||||
|
||||
完整更新迁移有意与 Full Release CI 分开。当发布问题是“从 2026.4.23 开始的每个已发布稳定版本是否都能更新到此候选版本并清理插件依赖残留?”时,使用手动 `Update Migration` workflow:
|
||||
完整更新迁移有意与完整发布 CI 分离。当发布问题是“从 `2026.4.23` 开始的每个已发布稳定版都能否更新到此候选版本并清理插件依赖残留?”时,使用手动 `Update Migration` 工作流:
|
||||
|
||||
```bash
|
||||
gh workflow run update-migration.yml \
|
||||
@ -101,18 +101,20 @@ gh workflow run update-migration.yml \
|
||||
-f scenarios=plugin-deps-cleanup
|
||||
```
|
||||
|
||||
## Package Acceptance
|
||||
## 包验收
|
||||
|
||||
Package Acceptance 是 GitHub 原生的软件包关卡。它会将一个候选软件包解析为 `package-under-test` tarball,记录版本和 SHA-256,然后针对该精确 tarball 运行可复用的 Docker E2E lanes。workflow harness 引用与软件包来源引用分离,因此当前测试逻辑可以验证较旧的受信任发布版本。
|
||||
包验收是 GitHub 原生的包门禁。它会将一个候选包解析为 `package-under-test` tarball,记录版本和 SHA-256,然后针对该精确 tarball 运行可复用 Docker E2E 通道。工作流 harness ref 与包源 ref 分离,因此当前测试逻辑可以验证较旧的可信发布。
|
||||
|
||||
候选来源:
|
||||
|
||||
- `source=npm`:验证 `openclaw@beta`、`openclaw@latest` 或精确的已发布版本。
|
||||
- `source=ref`:用选定的当前 harness 打包受信任分支、标签或提交。
|
||||
- `source=url`:验证 HTTPS tarball,并要求提供 `package_sha256`。
|
||||
- `source=ref`:使用选定的当前 harness 打包可信分支、标签或提交。
|
||||
- `source=url`:验证带必需 `package_sha256` 的 HTTPS tarball。
|
||||
- `source=artifact`:复用另一个 Actions 运行上传的 tarball。
|
||||
|
||||
发布检查会使用软件包/更新/插件集合调用 Package Acceptance:
|
||||
完整发布验证默认使用 `source=artifact`,由解析后的发布 SHA 构建。对于发布后证明,传入 `package_acceptance_package_spec=openclaw@YYYY.M.D`,使同一个升级矩阵目标指向已发布的 npm 包。
|
||||
|
||||
发布检查会使用包/更新/插件集合调用包验收:
|
||||
|
||||
```text
|
||||
doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update
|
||||
@ -121,16 +123,16 @@ doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor
|
||||
它们还会传入:
|
||||
|
||||
```text
|
||||
published_upgrade_survivor_baselines=release-history
|
||||
published_upgrade_survivor_baselines=all-since-2026.4.23
|
||||
published_upgrade_survivor_scenarios=reported-issues
|
||||
telegram_mode=mock-openai
|
||||
```
|
||||
|
||||
这会让软件包迁移、更新渠道切换、过时插件依赖清理、离线插件覆盖、插件更新行为和 Telegram 软件包 QA 都基于同一个已解析工件运行。
|
||||
这会让包迁移、更新渠道切换、过时插件依赖清理、离线插件覆盖、插件更新行为和 Telegram 包 QA 都针对同一个解析产物运行。
|
||||
|
||||
`release-history` 是一个有界发布检查样本:最新六个稳定版本、`2026.4.23`,以及一个更早的日期前锚点。对于穷尽式已发布更新迁移覆盖,请在单独的 Update Migration workflow 中使用 `all-since-2026.4.23`,而不是 Full Release CI。
|
||||
`all-since-2026.4.23` 是完整发布 CI 的升级样本:从 `2026.4.23` 到 `latest` 的每个 npm 已发布稳定版本。若要获得详尽的已发布更新迁移覆盖,请在单独的更新迁移工作流中使用 `all-since-2026.4.23`,而不是完整发布 CI。`release-history` 仍可用于手动更广泛采样,适合同时需要旧版日期前锚点的情况。
|
||||
|
||||
在发布前验证候选版本时,手动运行软件包配置:
|
||||
在发布前验证候选版本时,手动运行包配置档:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml \
|
||||
@ -139,54 +141,54 @@ gh workflow run package-acceptance.yml \
|
||||
-f source=npm \
|
||||
-f package_spec=openclaw@beta \
|
||||
-f suite_profile=package \
|
||||
-f published_upgrade_survivor_baselines=release-history \
|
||||
-f published_upgrade_survivor_baselines=all-since-2026.4.23 \
|
||||
-f published_upgrade_survivor_scenarios=reported-issues \
|
||||
-f telegram_mode=mock-openai
|
||||
```
|
||||
|
||||
当发布问题包含 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索或 OpenWebUI 时,使用 `suite_profile=product`。只有在需要完整 Docker 发布路径覆盖时才使用 `suite_profile=full`。
|
||||
当发布问题包含 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索或 OpenWebUI 时,使用 `suite_profile=product`。只有在需要完整 Docker 发布路径覆盖时,才使用 `suite_profile=full`。
|
||||
|
||||
## 发布默认值
|
||||
|
||||
对于候选发布版本,默认证明栈是:
|
||||
对于发布候选版本,默认证明栈是:
|
||||
|
||||
1. `pnpm check:changed` 和 `pnpm test:changed`,用于源代码级回归。
|
||||
2. `pnpm release:check`,用于软件包工件完整性。
|
||||
3. Package Acceptance `package` 配置,或发布检查自定义软件包 lanes,用于安装/更新/插件契约。
|
||||
4. 跨 OS 发布检查,用于特定 OS 的安装器、新手引导和平台行为。
|
||||
5. 只有当变更表面触及提供商或托管服务行为时,才运行实时测试套件。
|
||||
1. 使用 `pnpm check:changed` 和 `pnpm test:changed` 检查源码级回归。
|
||||
2. 使用 `pnpm release:check` 检查包产物完整性。
|
||||
3. 使用包验收 `package` 配置档或发布检查自定义包通道检查安装/更新/插件契约。
|
||||
4. 使用跨 OS 发布检查验证 OS 特定安装器、新手引导和平台行为。
|
||||
5. 只有在变更表面触及提供商或托管服务行为时,才运行实时套件。
|
||||
|
||||
在维护者机器上,宽范围关卡和 Docker/软件包产品证明应在 Testbox 中运行,除非明确是在做本地证明。
|
||||
在维护者机器上,宽范围门禁和 Docker/包产品证明应在 Testbox 中运行,除非明确要做本地证明。
|
||||
|
||||
## 旧版兼容性
|
||||
|
||||
兼容性宽容是窄范围且有时间限制的:
|
||||
兼容性宽容范围很窄且有时间限制:
|
||||
|
||||
- 直到 `2026.4.25` 的软件包,包括 `2026.4.25-beta.*`,可以在 Package Acceptance 中容忍已经发布的软件包元数据缺口。
|
||||
- 已发布的 `2026.4.26` 软件包可以对已经发布的本地构建元数据戳记文件发出警告。
|
||||
- 之后的软件包必须满足现代契约。同样的缺口会失败,而不是警告或跳过。
|
||||
- 到 `2026.4.25` 为止的包,包括 `2026.4.25-beta.*`,可以在包验收中容忍已经发布的包元数据缺口。
|
||||
- 已发布的 `2026.4.26` 包可以对已经发布的本地构建元数据戳文件发出警告。
|
||||
- 后续包必须满足现代契约。同样的缺口会失败,而不是警告或跳过。
|
||||
|
||||
不要为这些旧形状添加新的启动迁移。添加或扩展 doctor 修复,然后用 `upgrade-survivor` 或 `published-upgrade-survivor` 证明它。
|
||||
不要为这些旧形态添加新的启动迁移。添加或扩展 doctor 修复,然后用 `upgrade-survivor` 或 `published-upgrade-survivor` 证明。
|
||||
|
||||
## 添加覆盖
|
||||
|
||||
更改更新或插件行为时,在能够因正确原因失败的最低层添加覆盖:
|
||||
|
||||
- 纯路径或元数据逻辑:源代码旁边的单元测试。
|
||||
- 软件包清单或已打包文件行为:`package-dist-inventory` 或 tarball 检查器测试。
|
||||
- CLI 安装/更新行为:Docker lane 断言或 fixture。
|
||||
- 纯路径或元数据逻辑:在源码旁边添加单元测试。
|
||||
- 包清单或已打包文件行为:`package-dist-inventory` 或 tarball 检查器测试。
|
||||
- CLI 安装/更新行为:Docker 通道断言或 fixture。
|
||||
- 已发布版本迁移行为:`published-upgrade-survivor` 场景。
|
||||
- 注册表/软件包来源行为:`test:docker:plugins` fixture 或 ClawHub fixture 服务器。
|
||||
- 依赖布局或清理行为:同时断言运行时执行和文件系统边界。npm 依赖可能提升安装到托管 npm root 下,因此测试应证明该 root 被扫描/清理,而不是假设存在软件包本地 `node_modules` 树。
|
||||
- 注册表/包来源行为:`test:docker:plugins` fixture 或 ClawHub fixture 服务器。
|
||||
- 依赖布局或清理行为:同时断言运行时执行和文件系统边界。npm 依赖可能会提升安装到托管 npm 根目录下,因此测试应证明根目录会被扫描/清理,而不是假设存在包本地 `node_modules` 树。
|
||||
|
||||
新的 Docker fixtures 默认保持 hermetic。除非测试重点就是实时注册表行为,否则使用本地 fixture 注册表和假软件包。
|
||||
新 Docker fixture 默认保持 hermetic。除非测试重点是实时注册表行为,否则使用本地 fixture 注册表和假包。
|
||||
|
||||
## 失败分诊
|
||||
|
||||
从工件身份开始:
|
||||
从产物身份开始:
|
||||
|
||||
- Package Acceptance `resolve_package` 摘要:来源、版本、SHA-256 和工件名称。
|
||||
- Docker 工件:`.artifacts/docker-tests/**/summary.json`、`failures.json`、lane 日志和重跑命令。
|
||||
- 包验收 `resolve_package` 摘要:来源、版本、SHA-256 和产物名称。
|
||||
- Docker 产物:`.artifacts/docker-tests/**/summary.json`、`failures.json`、通道日志和重跑命令。
|
||||
- 升级幸存者摘要:`.artifacts/upgrade-survivor/summary.json`,包括基线版本、候选版本、场景、阶段耗时和配方步骤。
|
||||
|
||||
优先使用相同的软件包工件重跑失败的精确 lane,而不是重跑整个发布总括。
|
||||
优先使用同一个包产物重跑失败的精确通道,而不是重跑整个发布总括流程。
|
||||
|
||||
@ -3,21 +3,21 @@ read_when:
|
||||
- 在本地或 CI 中运行测试
|
||||
- 为模型/提供商 bug 添加回归测试
|
||||
- 调试 Gateway 网关 + 智能体行为
|
||||
summary: 测试工具包:unit/e2e/live 套件、Docker 运行器,以及每项测试覆盖的内容
|
||||
summary: 测试工具包:unit/e2e/live 套件、Docker 运行器,以及每项测试涵盖的内容
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T16:50:25Z"
|
||||
generated_at: "2026-05-02T18:56:28Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 99e7db2ab0069aaa129bed303419b76bb9276f3f53a4ac6bb292120c3a327b7b
|
||||
source_hash: 723d4769d13a83482bd4afcd1878579ba2b245c8e49cefc2794e865da1ab7dc7
|
||||
source_path: help/testing.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)以及少量 Docker 运行器。本文档是“我们如何测试”的指南:
|
||||
OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)和一小组 Docker 运行器。这份文档是“我们如何测试”的指南:
|
||||
|
||||
- 每个套件覆盖什么(以及有意 _不_ 覆盖什么)。
|
||||
- 常见工作流(本地、推送前、调试)应运行哪些命令。
|
||||
- 每个套件覆盖什么(以及刻意_不_覆盖什么)。
|
||||
- 常见工作流(本地、推送前、调试)应该运行哪些命令。
|
||||
- live 测试如何发现凭据并选择模型/提供商。
|
||||
- 如何为真实世界中的模型/提供商问题添加回归测试。
|
||||
|
||||
@ -26,132 +26,135 @@ OpenClaw 有三个 Vitest 套件(单元/集成、e2e、live)以及少量 Doc
|
||||
|
||||
- [QA overview](/zh-CN/concepts/qa-e2e-automation) — 架构、命令界面、场景编写。
|
||||
- [Matrix QA](/zh-CN/concepts/qa-matrix) — `pnpm openclaw qa matrix` 的参考。
|
||||
- [QA channel](/zh-CN/channels/qa-channel) — repo 支撑场景使用的合成传输插件。
|
||||
- [QA channel](/zh-CN/channels/qa-channel) — repo 支持的场景所使用的合成传输插件。
|
||||
|
||||
本页面介绍如何运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考文档。
|
||||
本页介绍如何运行常规测试套件和 Docker/Parallels 运行器。下面的 QA 专用运行器部分([QA 专用运行器](#qa-specific-runners))列出了具体的 `qa` 调用,并指回上面的参考资料。
|
||||
</Note>
|
||||
|
||||
## 快速开始
|
||||
|
||||
多数日常情况下:
|
||||
大多数时候:
|
||||
|
||||
- 完整门禁(推送前预期运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test`
|
||||
- 在空间充足的机器上更快运行本地完整套件:`pnpm test:max`
|
||||
- 在空间充足的机器上更快地运行本地完整套件:`pnpm test:max`
|
||||
- 直接的 Vitest 监听循环:`pnpm test:watch`
|
||||
- 直接指定文件现在也会路由扩展/渠道路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
|
||||
- 当你正在迭代单个失败时,优先运行有针对性的测试。
|
||||
- Docker 支撑的 QA 站点:`pnpm qa:lab:up`
|
||||
- Linux VM 支撑的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
|
||||
- 现在直接定位文件也会路由 extension/channel 路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts`
|
||||
- 当你在迭代单个失败时,优先使用定向运行。
|
||||
- Docker 支持的 QA 站点:`pnpm qa:lab:up`
|
||||
- Linux VM 支持的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
|
||||
|
||||
当你改动测试或想获得额外信心时:
|
||||
当你修改测试或想要额外信心时:
|
||||
|
||||
- 覆盖率门禁:`pnpm test:coverage`
|
||||
- E2E 套件:`pnpm test:e2e`
|
||||
|
||||
调试真实提供商/模型时(需要真实凭据):
|
||||
|
||||
- live 套件(模型 + Gateway 网关工具/图片探测):`pnpm test:live`
|
||||
- live 套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live`
|
||||
- 静默定位一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts`
|
||||
- 运行时性能报告:派发 `OpenClaw Performance`,使用
|
||||
- 运行时性能报告:分派 `OpenClaw Performance`,使用
|
||||
`live_gpt54=true` 进行一次真实的 `openai/gpt-5.4` 智能体回合,或使用
|
||||
`deep_profile=true` 生成 Kova CPU/堆/跟踪工件。配置 `CLAWGRIT_REPORTS_TOKEN` 后,每日定时运行会将 mock-provider、deep-profile 和 GPT 5.4 通道工件发布到
|
||||
`openclaw/clawgrit-reports`。mock-provider 报告还包含源码级 Gateway 网关启动、内存、
|
||||
插件压力、重复 fake-model hello-loop 以及 CLI 启动数据。
|
||||
`deep_profile=true` 生成 Kova CPU/堆/跟踪工件。每日定时运行会在配置了
|
||||
`CLAWGRIT_REPORTS_TOKEN` 时,将 mock-provider、deep-profile 和 GPT 5.4 通道工件发布到
|
||||
`openclaw/clawgrit-reports`。mock-provider 报告还包括源码级 Gateway 网关启动、内存、
|
||||
插件压力、重复 fake-model hello-loop 和 CLI 启动指标。
|
||||
- Docker live 模型扫描:`pnpm test:docker:live-models`
|
||||
- 每个选中的模型现在都会运行一次文本回合以及一个小型的文件读取式探测。
|
||||
元数据声明支持 `image` 输入的模型还会运行一次微型图片回合。
|
||||
在隔离提供商失败时,可用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或
|
||||
- 每个被选择的模型现在会运行一个文本回合,以及一个小型文件读取风格探测。
|
||||
元数据标示支持 `image` 输入的模型还会运行一个小型图像回合。
|
||||
在隔离提供商失败时,可以用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或
|
||||
`OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用额外探测。
|
||||
- CI 覆盖范围:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动
|
||||
`OpenClaw Release Checks` 都会调用可复用 live/E2E 工作流,并设置
|
||||
`include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型矩阵作业。
|
||||
- 对于聚焦的 CI 重跑,派发 `OpenClaw Live And E2E Checks (Reusable)`,
|
||||
并设置 `include_live_suites: true` 和 `live_models_only: true`。
|
||||
- 将新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`,
|
||||
以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和它的
|
||||
scheduled/release 调用方。
|
||||
- CI 覆盖:每日 `OpenClaw Scheduled Live And E2E Checks` 和手动
|
||||
`OpenClaw Release Checks` 都会调用可复用的 live/E2E 工作流,并设置
|
||||
`include_live_suites: true`,其中包括按提供商分片的独立 Docker live 模型矩阵作业。
|
||||
- 对于聚焦的 CI 重跑,分派 `OpenClaw Live And E2E Checks (Reusable)`,并设置
|
||||
`include_live_suites: true` 和 `live_models_only: true`。
|
||||
- 将新的高信号提供商 secret 添加到 `scripts/ci-hydrate-live-auth.sh`、
|
||||
`.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 及其
|
||||
定时/发布调用方。
|
||||
- 原生 Codex 绑定聊天冒烟测试:`pnpm test:docker:live-codex-bind`
|
||||
- 针对 Codex app-server 路径运行 Docker live 通道,使用 `/codex bind` 绑定一个合成
|
||||
- 针对 Codex app-server 路径运行 Docker live 通道,绑定一个带 `/codex bind` 的合成
|
||||
Slack 私信,执行 `/codex fast` 和
|
||||
`/codex permissions`,然后验证普通回复和图片附件通过原生插件绑定而不是 ACP 路由。
|
||||
`/codex permissions`,然后验证普通回复和图像附件通过原生插件绑定而不是 ACP 路由。
|
||||
- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`
|
||||
- 通过插件拥有的 Codex app-server harness 运行 Gateway 网关智能体回合,
|
||||
验证 `/codex status` 和 `/codex models`,并默认执行图片、
|
||||
验证 `/codex status` 和 `/codex models`,并默认执行图像、
|
||||
cron MCP、子智能体和 Guardian 探测。在隔离其他 Codex
|
||||
app-server 失败时,可用
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子智能体探测。要进行聚焦的子智能体检查,请禁用其他探测:
|
||||
app-server 失败时,用
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 禁用子智能体探测。对于聚焦的子智能体检查,禁用其他探测:
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。
|
||||
除非设置了 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则它会在子智能体探测后退出。
|
||||
这会在子智能体探测后退出,除非设置了
|
||||
`OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`。
|
||||
- Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel`
|
||||
- 对消息渠道救援命令界面的可选双保险检查。
|
||||
它会执行 `/crestodian status`,排队一个持久模型变更,回复 `/crestodian yes`,
|
||||
并验证审计/配置写入路径。
|
||||
- Crestodian 规划器 Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在无配置容器中运行 Crestodian,并在 `PATH` 上放置一个假的 Claude CLI,
|
||||
验证模糊规划器回退会转换为带审计的类型化配置写入。
|
||||
- 针对消息渠道救援命令界面的可选双重保障检查。
|
||||
它会执行 `/crestodian status`,排队一个持久模型变更,
|
||||
回复 `/crestodian yes`,并验证审计/配置写入路径。
|
||||
- Crestodian planner Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在无配置容器中运行 Crestodian,并在 `PATH` 上提供一个假 Claude CLI,
|
||||
然后验证模糊 planner 回退会转换为已审计的类型化配置写入。
|
||||
- Crestodian 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run`
|
||||
- 从空的 OpenClaw 状态目录开始,将裸 `openclaw` 路由到
|
||||
- 从空 OpenClaw 状态目录开始,将裸 `openclaw` 路由到
|
||||
Crestodian,应用设置/模型/智能体/Discord 插件 + SecretRef 写入,
|
||||
验证配置,并验证审计条目。同一个 Ring 0 设置路径也在 QA Lab 中由
|
||||
验证配置,并验证审计条目。同一个 Ring 0 设置路径也由 QA Lab 中的
|
||||
`pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。
|
||||
- Moonshot/Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行
|
||||
`openclaw models list --provider moonshot --json`,然后运行一个隔离的
|
||||
`openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`
|
||||
针对 `moonshot/kimi-k2.6`。验证 JSON 报告 Moonshot/K2.6,且助手转录记录存储规范化后的 `usage.cost`。
|
||||
`openclaw models list --provider moonshot --json`,然后针对
|
||||
`moonshot/kimi-k2.6` 运行一个隔离的
|
||||
`openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`。
|
||||
验证 JSON 报告 Moonshot/K2.6,并且助手 transcript 存储了标准化的 `usage.cost`。
|
||||
|
||||
<Tip>
|
||||
当你只需要一个失败用例时,优先通过下面介绍的 allowlist 环境变量收窄 live 测试。
|
||||
当你只需要一个失败用例时,优先通过下面描述的 allowlist 环境变量缩小 live 测试范围。
|
||||
</Tip>
|
||||
|
||||
## QA 专用运行器
|
||||
|
||||
当你需要 QA-lab 真实感时,这些命令位于主测试套件旁边:
|
||||
当你需要 QA-lab 真实度时,这些命令与主测试套件并列使用:
|
||||
|
||||
CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也会通过手动派发并使用 mock 提供商运行。`QA-Lab - All Lanes` 每晚在
|
||||
`main` 上运行,也会通过手动派发运行,将 mock parity gate、live Matrix 通道、
|
||||
Convex 管理的 live Telegram 通道和 Convex 管理的 live Discord 通道作为并行作业。定时 QA 和发布检查会显式传入 Matrix `--profile fast`,
|
||||
CI 在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可以通过使用 mock 提供商的手动分派运行。`QA-Lab - All Lanes` 每晚在
|
||||
`main` 上运行,也可以通过手动分派运行,并将 mock parity gate、live Matrix 通道、
|
||||
Convex 管理的 live Telegram 通道和 Convex 管理的 live Discord 通道作为并行作业运行。定时 QA 和发布检查会显式传递 Matrix `--profile fast`,
|
||||
而 Matrix CLI 和手动工作流输入的默认值仍为
|
||||
`all`;手动派发可以将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、
|
||||
`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 会在发布批准前运行 parity 以及快速 Matrix 和 Telegram 通道,并为发布传输检查使用
|
||||
`mock-openai/gpt-5.5`,这样它们保持确定性,并避开常规提供商插件启动。这些 live 传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA parity 套件覆盖。
|
||||
`all`;手动分派可以将 `all` 分片为 `transport`、`media`、`e2ee-smoke`、
|
||||
`e2ee-deep` 和 `e2ee-cli` 作业。`OpenClaw Release Checks` 会在发布批准前运行 parity 以及 fast Matrix 和 Telegram 通道,发布传输检查使用
|
||||
`mock-openai/gpt-5.5`,以便保持确定性并避免正常的提供商插件启动。这些 live 传输 Gateway 网关会禁用记忆搜索;记忆行为仍由 QA parity 套件覆盖。
|
||||
|
||||
完整发布的 live 媒体分片使用
|
||||
完整发布 live 媒体分片使用
|
||||
`ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04`,其中已经包含
|
||||
`ffmpeg` 和 `ffprobe`。Docker live 模型/后端分片使用共享的
|
||||
`ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像,该镜像会针对选中的
|
||||
commit 构建一次,然后用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片内重新构建。
|
||||
`ghcr.io/openclaw/openclaw-live-test:<sha>` 镜像,该镜像会为每个被选择的提交构建一次,然后使用
|
||||
`OPENCLAW_SKIP_DOCKER_BUILD=1` 拉取它,而不是在每个分片内部重新构建。
|
||||
|
||||
- `pnpm openclaw qa suite`
|
||||
- 直接在主机上运行由仓库支持的 QA 场景。
|
||||
- 默认使用隔离的 Gateway 网关工作进程并行运行多个选定场景。`qa-channel` 默认并发数为 4(受选定场景数量限制)。使用 `--concurrency <count>` 调整工作进程数量,或使用 `--concurrency 1` 进入旧版串行通道。
|
||||
- 当任一场景失败时以非零状态退出。当你想要产物但不想要失败退出码时,使用 `--allow-failures`。
|
||||
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个本地 AIMock 支持的提供商服务器,用于实验性夹具和协议模拟覆盖,而不会替换具备场景感知能力的 `mock-openai` 通道。
|
||||
- 直接在主机上运行由仓库支撑的 QA 场景。
|
||||
- 默认使用隔离的 Gateway 网关工作进程并行运行多个选定场景。`qa-channel` 默认并发数为 4(受选定场景数量限制)。使用 `--concurrency <count>` 调整工作进程数量,或使用 `--concurrency 1` 运行较旧的串行通道。
|
||||
- 任何场景失败时以非零状态退出。如果你想获取工件但不希望退出码失败,请使用 `--allow-failures`。
|
||||
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个由本地 AIMock 支撑的提供商服务器,用于实验性的 fixture 和协议模拟覆盖,同时不会替换具备场景感知能力的 `mock-openai` 通道。
|
||||
- `pnpm test:gateway:cpu-scenarios`
|
||||
- 运行 Gateway 网关启动基准测试以及一个小型模拟 QA Lab 场景包(`channel-chat-baseline`、`memory-failure-fallback`、`gateway-restart-inflight-run`),并将合并后的 CPU 观测摘要写入 `.artifacts/gateway-cpu-scenarios/`。
|
||||
- 默认只标记持续的高 CPU 观测(`--cpu-core-warn` 加 `--hot-wall-warn-ms`),因此短暂的启动突增会被记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满回归。
|
||||
- 使用已构建的 `dist` 产物;当检出目录尚无新的运行时输出时,先运行构建。
|
||||
- 运行 Gateway 网关启动基准测试以及一个小型 mock QA Lab 场景包(`channel-chat-baseline`、`memory-failure-fallback`、`gateway-restart-inflight-run`),并在 `.artifacts/gateway-cpu-scenarios/` 下写入合并后的 CPU 观测摘要。
|
||||
- 默认只标记持续的高 CPU 观测(`--cpu-core-warn` 加 `--hot-wall-warn-ms`),因此短暂的启动突增会被记录为指标,而不会看起来像持续数分钟的 Gateway 网关占满 CPU 回归。
|
||||
- 使用已构建的 `dist` 工件;如果当前检出尚无新的运行时输出,请先运行构建。
|
||||
- `pnpm openclaw qa suite --runner multipass`
|
||||
- 在一次性 Multipass Linux VM 中运行相同的 QA 套件。
|
||||
- 在一次性 Multipass Linux VM 内运行同一套 QA 套件。
|
||||
- 保持与主机上 `qa suite` 相同的场景选择行为。
|
||||
- 复用与 `qa suite` 相同的提供商/模型选择标志。
|
||||
- 实时运行会转发对访客实用的受支持 QA 凭证输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。
|
||||
- 输出目录必须保留在仓库根目录下,以便访客可通过挂载的工作区写回。
|
||||
- 将常规 QA 报告和摘要以及 Multipass 日志写入 `.artifacts/qa-e2e/...`。
|
||||
- 实时运行会转发对 guest 可用且实际可行的受支持 QA 鉴权输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。
|
||||
- 输出目录必须保留在仓库根目录下,以便 guest 可以通过挂载的工作区写回。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告和摘要,以及 Multipass 日志。
|
||||
- `pnpm qa:lab:up`
|
||||
- 启动由 Docker 支持的 QA 站点,用于操作员式 QA 工作。
|
||||
- 启动由 Docker 支撑的 QA 站点,用于操作员式 QA 工作。
|
||||
- `pnpm test:docker:npm-onboard-channel-agent`
|
||||
- 从当前检出构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram,验证打包的插件运行时无需启动依赖修复即可加载,运行 Doctor,并针对模拟的 OpenAI 端点运行一次本地智能体回合。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 以 Discord 运行相同的打包安装通道。
|
||||
- 从当前检出构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API key 新手引导,默认配置 Telegram,验证打包后的插件运行时可在无需启动依赖修复的情况下加载,运行 Doctor,并针对 mock 的 OpenAI 端点运行一次本地智能体回合。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同一条打包安装通道。
|
||||
- `pnpm test:docker:session-runtime-context`
|
||||
- 为嵌入式运行时上下文转录运行确定性的已构建应用 Docker 冒烟测试。它验证隐藏的 OpenClaw 运行时上下文会作为非显示自定义消息持久化,而不是泄露到可见用户回合中,然后播种一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前分支并创建备份。
|
||||
- 针对嵌入式运行时上下文 transcript 运行确定性的已构建应用 Docker smoke。它会验证隐藏的 OpenClaw 运行时上下文作为非显示自定义消息持久化,而不会泄漏到可见的用户回合中;随后播种一个受影响的损坏会话 JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前分支并创建备份。
|
||||
- `pnpm test:docker:npm-telegram-live`
|
||||
- 在 Docker 中安装 OpenClaw 包候选版本,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用实时 Telegram QA 通道,并将该已安装包作为被测系统 Gateway 网关。
|
||||
- 默认值为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 `OPENCLAW_CURRENT_PACKAGE_TGZ`,以测试已解析的本地 tarball,而不是从注册表安装。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证来源。对于 CI/发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥,Docker 包装器会自动选择 Convex。
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅对该通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。
|
||||
- GitHub Actions 将该通道公开为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。
|
||||
- GitHub Actions 还公开了 `Package Acceptance`,用于针对一个候选包进行旁路运行的产品证明。它接受受信任的 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,或来自另一次运行的 tarball 产物,将规范化的 `openclaw-current.tgz` 上传为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 通道配置运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,即可针对同一个 `package-under-test` 产物运行 Telegram QA 工作流。
|
||||
- 最新 beta 产品证明:
|
||||
- 在 Docker 中安装一个 OpenClaw 包候选版本,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用实时 Telegram QA 通道,并将该已安装包作为 SUT Gateway 网关。
|
||||
- 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`;设置 `OPENCLAW_NPM_TELEGRAM_PACKAGE_TGZ=/path/to/openclaw-current.tgz` 或 `OPENCLAW_CURRENT_PACKAGE_TGZ`,可测试已解析的本地 tarball,而不是从 registry 安装。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证来源。对于 CI/发布自动化,请设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色 secret。如果 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色 secret,Docker wrapper 会自动选择 Convex。
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 仅为此通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。
|
||||
- GitHub Actions 将此通道公开为手动 maintainer 工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。
|
||||
- GitHub Actions 还提供 `Package Acceptance`,用于针对一个候选包进行旁路产品验证。它接受可信 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,或另一次运行中的 tarball 工件;上传规范化的 `openclaw-current.tgz` 作为 `package-under-test`,然后使用 smoke、package、product、full 或 custom 通道配置文件运行现有 Docker E2E 调度器。设置 `telegram_mode=mock-openai` 或 `live-frontier`,可让 Telegram QA 工作流针对同一个 `package-under-test` 工件运行。
|
||||
- 最新 beta 产品验证:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml --ref main \
|
||||
@ -161,7 +164,7 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
-f telegram_mode=mock-openai
|
||||
```
|
||||
|
||||
- 精确 tarball URL 证明需要摘要:
|
||||
- 精确 tarball URL 验证需要摘要:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml --ref main \
|
||||
@ -171,7 +174,7 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
-f suite_profile=package
|
||||
```
|
||||
|
||||
- 产物证明会从另一次 Actions 运行下载 tarball 产物:
|
||||
- 工件验证会从另一次 Actions 运行中下载 tarball 工件:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml --ref main \
|
||||
@ -183,43 +186,43 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
|
||||
- `pnpm test:docker:plugins`
|
||||
- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置渠道/插件。
|
||||
- 验证设置发现会让未配置的可下载插件保持缺失,首次配置后的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏依赖修复。
|
||||
- 还会安装一个已知的旧版 npm 基线,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧版插件依赖残留,而无需 harness 侧 postinstall 修复。
|
||||
- 验证设置发现会让未配置的可下载插件保持缺席,第一次配置后的 Doctor 修复会显式安装每个缺失的可下载插件,并且第二次重启不会运行隐藏的依赖修复。
|
||||
- 还会安装一个已知的较旧 npm 基线版本,在运行 `openclaw update --tag <candidate>` 前启用 Telegram,并验证候选版本的更新后 Doctor 会清理旧版插件依赖残留,而无需 harness 侧 postinstall 修复。
|
||||
- `pnpm test:parallels:npm-update`
|
||||
- 跨 Parallels 访客运行原生打包安装更新冒烟测试。每个选定平台会先安装请求的基线包,然后在同一个访客中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、Gateway 网关就绪状态,以及一次本地智能体回合。
|
||||
- 在迭代单个访客时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要产物路径和每个通道的状态。
|
||||
- OpenAI 通道默认使用 `openai/gpt-5.5` 进行实时智能体回合证明。当有意验证另一个 OpenAI 模型时,传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。
|
||||
- 用主机超时包装长时间本地运行,防止 Parallels 传输停滞耗尽剩余测试窗口:
|
||||
- 跨 Parallels guest 运行原生打包安装更新 smoke。每个选定平台会先安装请求的基线包,然后在同一个 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、Gateway 网关就绪状态,以及一次本地智能体回合。
|
||||
- 迭代单个 guest 时使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要工件路径和每通道状态。
|
||||
- OpenAI 通道默认使用 `openai/gpt-5.5` 进行实时智能体回合验证。若有意验证另一个 OpenAI 模型,请传入 `--model <provider/model>` 或设置 `OPENCLAW_PARALLELS_OPENAI_MODEL`。
|
||||
- 用主机 timeout 包裹长时间本地运行,避免 Parallels 传输卡顿耗尽剩余测试窗口:
|
||||
|
||||
```bash
|
||||
timeout --foreground 150m pnpm test:parallels:npm-update -- --json
|
||||
timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json
|
||||
```
|
||||
|
||||
- 该脚本会将嵌套通道日志写入 `/tmp/openclaw-parallels-npm-update.*`。在假定外层包装器挂起之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。
|
||||
- 在冷访客上,Windows 更新可能会在更新后 Doctor 和包更新工作中花费 10 到 15 分钟;只要嵌套 npm 调试日志仍在推进,这仍然是正常的。
|
||||
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟通道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或访客 Gateway 网关状态上发生冲突。
|
||||
- 更新后证明会运行常规内置插件表面,因为语音、图像生成和媒体理解等能力门面会通过内置运行时 API 加载,即使智能体回合本身只检查简单文本响应。
|
||||
- 该脚本会在 `/tmp/openclaw-parallels-npm-update.*` 下写入嵌套通道日志。在假定外层 wrapper 卡住之前,请先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。
|
||||
- 在冷 guest 上,Windows 更新可能会在更新后 Doctor 和包更新工作中花费 10 到 15 分钟;只要嵌套 npm debug 日志仍在推进,这仍属正常。
|
||||
- 不要将此聚合 wrapper 与单独的 Parallels macOS、Windows 或 Linux smoke 通道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或 guest Gateway 网关状态上发生冲突。
|
||||
- 更新后验证会运行常规内置插件表面,因为 speech、image generation 和 media understanding 等能力 facade 会通过内置运行时 API 加载,即使智能体回合本身只检查简单文本响应。
|
||||
|
||||
- `pnpm openclaw qa aimock`
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接协议 smoke 测试。
|
||||
- `pnpm openclaw qa matrix`
|
||||
- 针对一次性 Docker 支持的 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅限源检出,打包安装不随附 `qa-lab`。
|
||||
- 完整 CLI、配置文件/场景目录、环境变量和产物布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。
|
||||
- 针对一次性的 Docker 支撑 Tuwunel homeserver 运行 Matrix 实时 QA 通道。仅限源码检出,打包安装不会随附 `qa-lab`。
|
||||
- 完整 CLI、profile/场景目录、环境变量和工件布局:[Matrix QA](/zh-CN/concepts/qa-matrix)。
|
||||
- `pnpm openclaw qa telegram`
|
||||
- 使用来自环境变量的驱动器和被测系统机器人令牌,针对真实私有群组运行 Telegram 实时 QA 通道。
|
||||
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 ID 必须是数字 Telegram chat id。
|
||||
- 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 选择加入池化租约。
|
||||
- 当任一场景失败时以非零状态退出。当你想要产物但不想要失败退出码时,使用 `--allow-failures`。
|
||||
- 需要同一个私有群组中的两个不同机器人,且被测系统机器人需要公开 Telegram username。
|
||||
- 为了稳定进行机器人对机器人观测,请在 `@BotFather` 中为两个机器人启用 Bot-to-Bot Communication Mode,并确保驱动器机器人可以观测群组机器人流量。
|
||||
- 将 Telegram QA 报告、摘要和 observed-messages 产物写入 `.artifacts/qa-e2e/...`。回复场景包含从驱动器发送请求到观测到被测系统回复的 RTT。
|
||||
- 使用来自环境变量的 driver 和 SUT bot token,针对真实私有群组运行 Telegram 实时 QA 通道。
|
||||
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 id 必须是数字 Telegram chat id。
|
||||
- 支持 `--credential-source convex` 以使用共享池化凭证。默认使用环境变量模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 选择池化租约。
|
||||
- 任何场景失败时以非零状态退出。如果你想获取工件但不希望退出码失败,请使用 `--allow-failures`。
|
||||
- 需要同一私有群组中的两个不同 bot,且 SUT bot 需公开 Telegram username。
|
||||
- 为了获得稳定的 bot 对 bot 观测,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观测群组 bot 流量。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要和 observed-messages 工件。回复场景包含从 driver 发送请求到观测到 SUT 回复的 RTT。
|
||||
|
||||
实时传输通道共享一个标准契约,因此新的传输不会漂移;各通道覆盖矩阵位于 [QA overview → 实时传输覆盖](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是广泛的合成套件,不属于该矩阵。
|
||||
实时传输通道共享一个标准契约,确保新传输不会漂移;每通道覆盖矩阵位于 [QA overview → 实时传输覆盖](/zh-CN/concepts/qa-e2e-automation#live-transport-coverage)。`qa-channel` 是广泛的合成套件,不属于该矩阵。
|
||||
|
||||
### 通过 Convex 共享 Telegram 凭证(v1)
|
||||
|
||||
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支持的池中获取独占租约,在通道运行期间对该租约发送 Heartbeat,并在关闭时释放租约。
|
||||
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支撑的池中获取一个独占租约,在通道运行期间对该租约发送 Heartbeat,并在关闭时释放租约。
|
||||
|
||||
参考 Convex 项目脚手架:
|
||||
|
||||
@ -228,7 +231,7 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
必需环境变量:
|
||||
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`)
|
||||
- 所选角色的一个密钥:
|
||||
- 所选角色的一个 secret:
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer`
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci`
|
||||
- 凭证角色选择:
|
||||
@ -242,14 +245,14 @@ gh workflow run package-acceptance.yml --ref main \
|
||||
- `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS`(默认 `90000`)
|
||||
- `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`)
|
||||
- `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`)
|
||||
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选跟踪 ID)
|
||||
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅本地开发使用的 loopback `http://` Convex URL。
|
||||
- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选 trace id)
|
||||
- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅用于本地开发的 loopback `http://` Convex URL。
|
||||
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 在正常运行中应使用 `https://`。
|
||||
`OPENCLAW_QA_CONVEX_SITE_URL` 在正常操作中应使用 `https://`。
|
||||
|
||||
维护者管理命令(池添加/移除/列出)明确要求 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。
|
||||
Maintainer 管理命令(池 add/remove/list)特别需要 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。
|
||||
|
||||
维护者 CLI 辅助命令:
|
||||
供 maintainer 使用的 CLI helper:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa credentials doctor
|
||||
@ -258,49 +261,49 @@ pnpm openclaw qa credentials list --kind telegram
|
||||
pnpm openclaw qa credentials remove --credential-id <credential-id>
|
||||
```
|
||||
|
||||
在实时运行之前使用 `doctor` 检查 Convex 站点 URL、broker 密钥、端点前缀、HTTP 超时和 admin/list 可达性,而不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。
|
||||
在实时运行前使用 `doctor` 检查 Convex 站点 URL、broker secret、端点前缀、HTTP timeout,以及 admin/list 可达性,并且不会打印 secret 值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。
|
||||
|
||||
默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`):
|
||||
|
||||
- `POST /acquire`
|
||||
- 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }`
|
||||
- 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }`
|
||||
- 耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }`
|
||||
- 已耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }`
|
||||
- `POST /heartbeat`
|
||||
- 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }`
|
||||
- 成功:`{ status: "ok" }`(或空 `2xx`)
|
||||
- `POST /release`
|
||||
- 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }`
|
||||
- 成功:`{ status: "ok" }`(或空 `2xx`)
|
||||
- `POST /admin/add`(仅限维护者密钥)
|
||||
- `POST /admin/add`(仅维护者密钥)
|
||||
- 请求:`{ kind, actorId, payload, note?, status? }`
|
||||
- 成功:`{ status: "ok", credential }`
|
||||
- `POST /admin/remove`(仅限维护者密钥)
|
||||
- `POST /admin/remove`(仅维护者密钥)
|
||||
- 请求:`{ credentialId, actorId }`
|
||||
- 成功:`{ status: "ok", changed, credential }`
|
||||
- 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }`
|
||||
- `POST /admin/list`(仅限维护者密钥)
|
||||
- 活动租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }`
|
||||
- `POST /admin/list`(仅维护者密钥)
|
||||
- 请求:`{ kind?, status?, includePayload?, limit? }`
|
||||
- 成功:`{ status: "ok", credentials, count }`
|
||||
|
||||
Telegram kind 的 payload 形状:
|
||||
Telegram 类型的载荷结构:
|
||||
|
||||
- `{ groupId: string, driverToken: string, sutToken: string }`
|
||||
- `groupId` 必须是数字形式的 Telegram 聊天 ID 字符串。
|
||||
- `admin/add` 会针对 `kind: "telegram"` 验证此形状,并拒绝格式错误的 payload。
|
||||
- `admin/add` 会为 `kind: "telegram"` 验证此结构,并拒绝格式错误的载荷。
|
||||
|
||||
### 向 QA 添加渠道
|
||||
### 将渠道添加到 QA
|
||||
|
||||
新渠道适配器的架构和场景辅助程序名称见 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` 主机 seam 上实现传输运行器,在插件清单中声明 `qaRunners`,挂载为 `openclaw qa <runner>`,并在 `qa/scenarios/` 下编写场景。
|
||||
新渠道适配器的架构和场景辅助工具名称位于 [QA overview → 添加渠道](/zh-CN/concepts/qa-e2e-automation#adding-a-channel)。最低要求:在共享的 `qa-lab` 主机衔接层上实现传输运行器,在插件清单中声明 `qaRunners`,挂载为 `openclaw qa <runner>`,并在 `qa/scenarios/` 下编写场景。
|
||||
|
||||
## 测试套件(在哪里运行什么)
|
||||
## 测试套件(在哪运行什么)
|
||||
|
||||
可以把这些套件理解为“真实度递增”(同时不稳定性/成本也递增):
|
||||
可以把这些套件理解为“真实度逐步提高”(不稳定性/成本也逐步提高):
|
||||
|
||||
### 单元 / 集成(默认)
|
||||
|
||||
- 命令:`pnpm test`
|
||||
- 配置:非定向运行使用 `vitest.full-*.config.ts` 分片集,并可能把多项目分片展开为按项目划分的配置,以便并行调度
|
||||
- 配置:非定向运行使用 `vitest.full-*.config.ts` 分片集,并且可能会将多项目分片展开成按项目配置,以便并行调度
|
||||
- 文件:`src/**/*.test.ts`、`packages/**/*.test.ts` 和 `test/**/*.test.ts` 下的核心/单元清单;UI 单元测试在专用的 `unit-ui` 分片中运行
|
||||
- 范围:
|
||||
- 纯单元测试
|
||||
@ -309,104 +312,102 @@ Telegram kind 的 payload 形状:
|
||||
- 预期:
|
||||
- 在 CI 中运行
|
||||
- 不需要真实密钥
|
||||
- 应该快速且稳定
|
||||
- 解析器和公共 surface 加载器测试必须使用生成的微型插件 fixture 证明宽泛 `api.js` 和
|
||||
`runtime-api.js` 回退行为,而不是使用真实内置插件源 API。真实插件 API 加载应放在
|
||||
插件自有的契约/集成套件中。
|
||||
- 应当快速且稳定
|
||||
- 解析器和公开表面加载器测试必须用生成的极小插件测试夹具证明宽泛 `api.js` 和
|
||||
`runtime-api.js` 的回退行为,而不是使用真实内置插件源码 API。真实插件 API 加载应放在
|
||||
插件拥有的契约/集成套件中。
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="项目、分片和限定范围的 lane">
|
||||
<Accordion title="项目、分片和作用域通道">
|
||||
|
||||
- 非定向 `pnpm test` 会运行十二个较小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低高负载机器上的峰值 RSS,并避免 auto-reply/extension 工作让无关套件饥饿。
|
||||
- `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch loop 并不实用。
|
||||
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过限定范围的 lane 路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免支付完整根项目启动成本。
|
||||
- `pnpm test:changed` 默认会把已变更的 git 路径展开为低成本的限定范围 lane:直接测试编辑、相邻 `*.test.ts` 文件、显式源映射,以及本地 import-graph 依赖项。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm check:changed` 是窄范围工作的常规智能本地检查 gate。它会把 diff 分类为核心、核心测试、extensions、extension 测试、应用、文档、发布元数据、实时 Docker 工具和工具链,然后运行匹配的类型检查、lint 和 guard 命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式 `pnpm test <target>`。仅发布元数据的版本 bump 会运行定向版本/配置/根依赖检查,并带有一个 guard,用于拒绝顶层版本字段之外的 package 变更。
|
||||
- 实时 Docker ACP harness 编辑会运行聚焦检查:实时 Docker 认证脚本的 shell 语法检查,以及实时 Docker 调度器 dry-run。只有当 diff 限定在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、export、版本和其他 package surface 编辑仍使用更宽泛的 guard。
|
||||
- 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 和类似纯工具区域的轻 import 单元测试会通过 `unit-fast` lane 路由,该 lane 会跳过 `test/setup-openclaw-runtime.ts`;有状态/Runtime 较重的文件仍留在现有 lane 上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 辅助源文件还会把变更模式运行映射到这些轻量 lane 中的显式相邻测试,因此辅助程序编辑可以避免为该目录重新运行完整重型套件。
|
||||
- `auto-reply` 为顶层核心辅助程序、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树设置了专用 bucket。CI 进一步把 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,避免一个 import 较重的 bucket 独占完整 Node 尾段。
|
||||
- 普通 PR/main CI 会有意跳过 extension 批量 sweep 和仅发布使用的 `agentic-plugins` 分片。完整发布验证会为发布候选版本分发单独的 `Plugin Prerelease` 子 workflow,用于这些插件/extension 较重的套件。
|
||||
- 非定向 `pnpm test` 会运行十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这会降低负载较高机器上的 RSS 峰值,并避免 auto-reply/插件工作挤占无关套件。
|
||||
- `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环不实用。
|
||||
- `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式文件/目录目标通过作用域通道路由,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可避免承担完整根项目启动开销。
|
||||
- `pnpm test:changed` 默认会将变更的 git 路径展开成低成本作用域通道:直接的测试编辑、同级 `*.test.ts` 文件、显式源映射,以及本地导入图依赖方。配置/设置/package 编辑不会广泛运行测试,除非你显式使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm check:changed` 是窄范围工作的常规智能本地检查门禁。它会将 diff 分类为核心、核心测试、插件、插件测试、应用、文档、发布元数据、live Docker 工具和工具链,然后运行匹配的类型检查、lint 和保护命令。它不会运行 Vitest 测试;如需测试证明,请调用 `pnpm test:changed` 或显式的 `pnpm test <target>`。仅涉及发布元数据的版本提升会运行定向版本/配置/根依赖检查,并带有一个保护检查,拒绝顶层 version 字段之外的 package 变更。
|
||||
- Live Docker ACP harness 编辑会运行聚焦检查:live Docker 认证脚本的 shell 语法和 live Docker 调度器演练。只有当 diff 限于 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本以及其他 package 表面编辑仍然使用更广泛的保护检查。
|
||||
- 来自智能体、命令、插件、auto-reply 辅助工具、`plugin-sdk` 和类似纯工具区域的导入较轻单元测试会通过 `unit-fast` 通道路由,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件保留在现有通道上。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 辅助源文件也会把变更模式运行映射到这些轻量通道中的显式同级测试,因此辅助工具编辑不必为该目录重新运行完整的重型套件。
|
||||
- `auto-reply` 为顶层核心辅助工具、顶层 `reply.*` 集成测试和 `src/auto-reply/reply/**` 子树设置了专用桶。CI 还会把 reply 子树进一步拆分为 agent-runner、dispatch 和 commands/state-routing 分片,因此一个导入较重的桶不会独占完整 Node 尾部开销。
|
||||
- 常规 PR/main CI 会有意跳过插件批量扫测和仅发布时运行的 `agentic-plugins` 分片。完整发布验证会为发布候选版本上的这些插件较重套件调度单独的插件预发布子工作流。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="嵌入式运行器覆盖率">
|
||||
<Accordion title="嵌入式运行器覆盖">
|
||||
|
||||
- 当你更改消息工具发现输入或压缩 Runtime
|
||||
上下文时,请保留两个层级的覆盖率。
|
||||
- 当你更改消息工具发现输入或压缩运行时
|
||||
上下文时,请保留两层覆盖。
|
||||
- 为纯路由和规范化
|
||||
边界添加聚焦辅助回归测试。
|
||||
边界添加聚焦的辅助函数回归测试。
|
||||
- 保持嵌入式运行器集成套件健康:
|
||||
`src/agents/pi-embedded-runner/compact.hooks.test.ts`、
|
||||
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和
|
||||
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。
|
||||
- 这些套件会验证限定范围的 ID 和压缩行为仍然流经
|
||||
真实的 `run.ts` / `compact.ts` 路径;仅辅助程序测试
|
||||
不能充分替代这些集成路径。
|
||||
- 这些套件会验证作用域 ID 和压缩行为仍然流经
|
||||
真实 `run.ts` / `compact.ts` 路径;仅辅助函数测试
|
||||
不足以替代这些集成路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Vitest 池和隔离默认值">
|
||||
|
||||
- 基础 Vitest 配置默认使用 `threads`。
|
||||
- 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用
|
||||
- 共享 Vitest 配置固定 `isolate: false`,并在根项目、E2E 和 live 配置中使用
|
||||
非隔离运行器。
|
||||
- 根 UI lane 保留其 `jsdom` 设置和优化器,但也运行在
|
||||
- 根 UI 通道保留其 `jsdom` 设置和优化器,但也运行在
|
||||
共享的非隔离运行器上。
|
||||
- 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false`
|
||||
- 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false`
|
||||
默认值。
|
||||
- `scripts/run-vitest.mjs` 默认为 Vitest 子 Node
|
||||
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node
|
||||
进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。
|
||||
设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与标准 V8
|
||||
设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与原生 V8
|
||||
行为进行比较。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="快速本地迭代">
|
||||
|
||||
- `pnpm changed:lanes` 会显示一个 diff 触发了哪些架构 lane。
|
||||
- pre-commit hook 仅负责格式化。它会重新 stage 格式化后的文件,
|
||||
不会运行 lint、类型检查或测试。
|
||||
- 当你需要智能本地检查 gate 时,请在交接或 push 前显式运行 `pnpm check:changed`。
|
||||
- `pnpm test:changed` 默认通过低成本的限定范围 lane 路由。仅当智能体
|
||||
判定 harness、配置、package 或契约编辑确实需要更宽泛的
|
||||
Vitest 覆盖率时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm changed:lanes` 会显示一个 diff 触发哪些架构通道。
|
||||
- pre-commit 钩子仅处理格式化。它会重新暂存格式化后的文件,
|
||||
不运行 lint、类型检查或测试。
|
||||
- 在交接或 push 前需要智能本地检查门禁时,请显式运行 `pnpm check:changed`。
|
||||
- `pnpm test:changed` 默认会通过低成本作用域通道路由。仅当智能体
|
||||
判断 harness、配置、package 或契约编辑确实需要更广泛的
|
||||
Vitest 覆盖时,才使用 `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`。
|
||||
- `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由
|
||||
行为,只是使用更高的 worker 上限。
|
||||
- 本地 worker 自动缩放有意保持保守,并会在主机负载平均值已经很高时
|
||||
退让,因此多个并发
|
||||
Vitest 运行默认会造成更少影响。
|
||||
- 基础 Vitest 配置会把项目/配置文件标记为
|
||||
`forceRerunTriggers`,因此当测试
|
||||
wiring 变化时,变更模式重跑仍然正确。
|
||||
- 配置会在受支持的
|
||||
主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;如果你希望
|
||||
为直接性能分析使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。
|
||||
- 本地 worker 自动扩缩有意保持保守,并会在主机负载均值已经较高时
|
||||
回退,因此多个并发 Vitest 运行默认造成的影响更小。
|
||||
- 基础 Vitest 配置会将项目/配置文件标记为
|
||||
`forceRerunTriggers`,因此当测试布线发生变化时,变更模式重新运行仍然正确。
|
||||
- 配置会在受支持的主机上保持启用 `OPENCLAW_VITEST_FS_MODULE_CACHE`;
|
||||
如果你想为直接剖析使用一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="性能调试">
|
||||
|
||||
- `pnpm test:perf:imports` 会启用 Vitest import 时长报告,以及
|
||||
import-breakdown 输出。
|
||||
- `pnpm test:perf:imports:changed` 会把同一个性能分析视图限定到
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及
|
||||
导入分解输出。
|
||||
- `pnpm test:perf:imports:changed` 会将同一剖析视图限定到
|
||||
自 `origin/main` 以来变更的文件。
|
||||
- 分片计时数据会写入 `.artifacts/vitest-shard-timings.json`。
|
||||
整个配置运行使用配置路径作为键;include-pattern CI
|
||||
整配置运行使用配置路径作为键;include-pattern CI
|
||||
分片会追加分片名称,以便单独跟踪过滤后的分片。
|
||||
- 当某个热点测试仍然把大部分时间花在启动 import 上时,
|
||||
请把重型依赖放在狭窄的本地 `*.runtime.ts` seam 后面,并
|
||||
直接 mock 该 seam,而不是为了把 Runtime 辅助程序传给 `vi.mock(...)`
|
||||
而进行深层 import。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会比较路由后的
|
||||
`test:changed` 与该已提交 diff 的原生根项目路径,并打印 wall time 和 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过把变更文件列表路由到
|
||||
`scripts/test-projects.mjs` 和根 Vitest 配置来对当前
|
||||
脏工作树做基准测试。
|
||||
- `pnpm test:perf:profile:main` 会为
|
||||
Vitest/Vite 启动和 transform 开销写入主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下为
|
||||
单元套件写入运行器 CPU+heap profile。
|
||||
- 当某个热点测试仍然把大部分时间花在启动导入上时,
|
||||
请把重依赖放在狭窄本地 `*.runtime.ts` 衔接层后面,并
|
||||
直接 mock 该衔接层,而不是仅为传给 `vi.mock(...)`
|
||||
而深度导入运行时辅助函数。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会对该已提交
|
||||
diff 比较路由后的 `test:changed` 与原生根项目路径,
|
||||
并打印墙钟时间以及 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过
|
||||
`scripts/test-projects.mjs` 和根 Vitest 配置路由变更文件列表,
|
||||
对当前脏工作树进行基准测试。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销
|
||||
写入主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为
|
||||
单元套件写入 runner CPU+heap profile。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -416,135 +417,140 @@ Telegram kind 的 payload 形状:
|
||||
- 命令:`pnpm test:stability:gateway`
|
||||
- 配置:`vitest.gateway.config.ts`,强制使用一个 worker
|
||||
- 范围:
|
||||
- 启动一个真实的 loopback Gateway 网关,默认启用诊断
|
||||
- 通过诊断事件路径驱动合成 Gateway 网关消息、记忆和大 payload 抖动
|
||||
- 启动一个默认启用诊断的真实回环 Gateway 网关
|
||||
- 通过诊断事件路径驱动合成 Gateway 网关消息、内存和大载荷变动
|
||||
- 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability`
|
||||
- 覆盖诊断稳定性 bundle 持久化辅助程序
|
||||
- 断言记录器保持有界,合成 RSS 样本保持在压力预算以下,并且每个会话的队列深度会重新降为零
|
||||
- 覆盖诊断稳定性 bundle 持久化辅助函数
|
||||
- 断言记录器保持有界、合成 RSS 样本保持在压力预算以下,并且每会话队列深度回落到零
|
||||
- 预期:
|
||||
- CI 安全且不需要密钥
|
||||
- 用于稳定性回归跟进的窄 lane,不能替代完整 Gateway 网关套件
|
||||
- 可在 CI 安全运行且无需密钥
|
||||
- 用于稳定性回归跟进的窄通道,不能替代完整 Gateway 网关套件
|
||||
|
||||
### E2E(Gateway 网关 smoke)
|
||||
### E2E(Gateway 网关烟雾测试)
|
||||
|
||||
- 命令:`pnpm test:e2e`
|
||||
- 配置:`vitest.e2e.config.ts`
|
||||
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试
|
||||
- Runtime 默认值:
|
||||
- 使用 Vitest `threads` 和 `isolate: false`,与仓库其余部分一致。
|
||||
- 运行时默认值:
|
||||
- 使用 Vitest `threads` 且 `isolate: false`,与仓库其他部分一致。
|
||||
- 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。
|
||||
- 默认以静默模式运行,以减少控制台 I/O 开销。
|
||||
- 有用的覆盖项:
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 强制指定 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 重新启用详细控制台输出。
|
||||
- 默认以 silent 模式运行,以减少控制台 I/O 开销。
|
||||
- 常用覆盖项:
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 用于强制 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细控制台输出。
|
||||
- 范围:
|
||||
- 多实例 Gateway 网关端到端行为
|
||||
- WebSocket/HTTP surface、节点配对,以及更重的网络
|
||||
- WebSocket/HTTP 表面、节点配对和更重的网络场景
|
||||
- 预期:
|
||||
- 在 CI 中运行(当流水线启用时)
|
||||
- 不需要真实密钥
|
||||
- 比单元测试包含更多移动部件(可能更慢)
|
||||
- 比单元测试有更多移动部件(可能更慢)
|
||||
|
||||
### E2E:OpenShell 后端 smoke
|
||||
### E2E:OpenShell 后端烟雾测试
|
||||
|
||||
- 命令:`pnpm test:e2e:openshell`
|
||||
- 文件:`extensions/openshell/src/backend.e2e.test.ts`
|
||||
- 范围:
|
||||
- 通过 Docker 在主机上启动一个隔离的 OpenShell 网关
|
||||
- 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关
|
||||
- 从临时本地 Dockerfile 创建一个沙箱
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 测试 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 fs bridge 验证远程规范文件系统行为
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 fs 桥接验证远程规范化文件系统行为
|
||||
- 预期:
|
||||
- 仅按需启用;不属于默认 `pnpm test:e2e` 运行
|
||||
- 需要本地 `openshell` CLI 和可工作的 Docker 守护进程
|
||||
- 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试网关和沙箱
|
||||
- 实用覆盖项:
|
||||
- `OPENCLAW_E2E_OPENSHELL=1` 用于在手动运行更广泛的 e2e 套件时启用该测试
|
||||
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell` 用于指向非默认的 CLI 二进制文件或包装脚本
|
||||
- 仅限主动启用;不是默认 `pnpm test:e2e` 运行的一部分
|
||||
- 需要本地 `openshell` CLI 以及可用的 Docker 守护进程
|
||||
- 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱
|
||||
- 有用的覆盖项:
|
||||
- `OPENCLAW_E2E_OPENSHELL=1`,在手动运行更广泛的 e2e 套件时启用该测试
|
||||
- `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`,指向非默认 CLI 二进制文件或包装脚本
|
||||
|
||||
### 实时(真实提供商 + 真实模型)
|
||||
### 现场测试(真实提供商 + 真实模型)
|
||||
|
||||
- 命令:`pnpm test:live`
|
||||
- 配置:`vitest.live.config.ts`
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件实时测试
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件现场测试
|
||||
- 默认值:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 范围:
|
||||
- “这个提供商/模型在 _今天_ 用真实凭证真的能工作吗?”
|
||||
- 捕获提供商格式变更、工具调用差异、鉴权问题和速率限制行为
|
||||
- “这个提供商/模型在 _今天_ 使用真实凭证是否真的可用?”
|
||||
- 捕获提供商格式变化、工具调用差异、认证问题和速率限制行为
|
||||
- 预期:
|
||||
- 按设计并非 CI 稳定(真实网络、真实提供商策略、配额、中断)
|
||||
- 按设计并非 CI 稳定(真实网络、真实提供商策略、配额、故障)
|
||||
- 会产生成本 / 使用速率限制
|
||||
- 优先运行缩小后的子集,而不是“一切”
|
||||
- 实时运行会读取 `~/.profile`,以获取缺失的 API key。
|
||||
- 默认情况下,实时运行仍会隔离 `HOME`,并把配置/鉴权材料复制到临时测试 home 中,这样单元测试夹具就不能修改你真实的 `~/.openclaw`。
|
||||
- 只有在你有意让实时测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。
|
||||
- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志/Bonjour 杂音。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。
|
||||
- API key 轮换(特定于提供商):用逗号/分号格式设置 `*_API_KEYS`,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可通过 `OPENCLAW_LIVE_*_KEY` 设置每个实时运行的覆盖项;测试会在速率限制响应时重试。
|
||||
- 优先运行缩小范围的子集,而不是“全部”
|
||||
- 现场运行会 source `~/.profile` 以获取缺失的 API key。
|
||||
- 默认情况下,现场运行仍会隔离 `HOME`,并将配置/认证材料复制到临时测试 home 中,以免单元测试夹具修改你真实的 `~/.openclaw`。
|
||||
- 仅在你有意需要现场测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。
|
||||
- `pnpm test:live` 现在默认使用更安静的模式:它保留 `[live] ...` 进度输出,但抑制额外的 `~/.profile` 提示,并静默 Gateway 网关引导日志/Bonjour 噪声。如果你希望恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。
|
||||
- API key 轮换(按提供商):设置带逗号/分号格式的 `*_API_KEYS`,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可以通过 `OPENCLAW_LIVE_*_KEY` 为单次现场运行覆盖;测试会在速率限制响应时重试。
|
||||
- 进度/Heartbeat 输出:
|
||||
- 实时套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获很安静,长时间的提供商调用也会显示为仍在活动。
|
||||
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,因此提供商/Gateway 网关进度行会在实时运行期间立即流式输出。
|
||||
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型 Heartbeat。
|
||||
- 现场套件现在会向 stderr 发出进度行,因此即使 Vitest 控制台捕获较安静,长时间的提供商调用也能显示为活跃状态。
|
||||
- `vitest.live.config.ts` 禁用 Vitest 控制台拦截,因此在现场运行期间,提供商/Gateway 网关进度行会立即流式输出。
|
||||
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直连模型 Heartbeat。
|
||||
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测 Heartbeat。
|
||||
|
||||
## 我应该运行哪个套件?
|
||||
|
||||
使用这个决策表:
|
||||
使用这张决策表:
|
||||
|
||||
- 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`)
|
||||
- 触及 Gateway 网关网络 / WS 协议 / 配对:加上 `pnpm test:e2e`
|
||||
- 调试“我的机器人宕了” / 特定提供商失败 / 工具调用:运行缩小后的 `pnpm test:live`
|
||||
- 触及 Gateway 网关网络 / WS 协议 / 配对:添加 `pnpm test:e2e`
|
||||
- 调试“我的 bot 挂了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live`
|
||||
|
||||
## 实时(触及网络)测试
|
||||
## 现场(触网)测试
|
||||
|
||||
关于实时模型矩阵、CLI 后端冒烟、ACP 冒烟、Codex app-server harness,以及所有媒体提供商实时测试(Deepgram、BytePlus、ComfyUI、图片、音乐、视频、media harness),再加上实时运行的凭证处理,请参阅[测试实时套件](/zh-CN/help/testing-live)。关于专用的更新和插件验证检查清单,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
关于现场模型矩阵、CLI 后端 smoke、ACP smoke、Codex app-server
|
||||
harness,以及所有媒体提供商现场测试(Deepgram、BytePlus、ComfyUI、image、
|
||||
music、video、media harness),以及现场运行的凭证处理,请参阅
|
||||
[现场套件测试](/zh-CN/help/testing-live)。关于专用更新和
|
||||
插件验证清单,请参阅
|
||||
[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
|
||||
## Docker 运行器(可选的“在 Linux 中可工作”检查)
|
||||
## Docker 运行器(可选的“在 Linux 中可用”检查)
|
||||
|
||||
这些 Docker 运行器分为两类:
|
||||
|
||||
- 实时模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像内运行它们匹配 profile-key 的实时文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),并挂载你的本地配置目录和工作区(如果已挂载,也会读取 `~/.profile`)。匹配的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。
|
||||
- Docker 实时运行器默认使用较小的冒烟上限,以便完整 Docker 扫描保持实用:
|
||||
- 现场模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只在仓库 Docker 镜像内运行它们匹配 profile-key 的现场文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),挂载你的本地配置目录和工作区(如果已挂载,也会 source `~/.profile`)。匹配的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。
|
||||
- Docker 现场运行器默认使用较小的 smoke 上限,以便完整 Docker 扫描保持实用:
|
||||
`test:docker:live-models` 默认使用 `OPENCLAW_LIVE_MAX_MODELS=12`,并且
|
||||
`test:docker:live-gateway` 默认使用 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、
|
||||
`OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、
|
||||
`OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和
|
||||
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你明确想要更大的穷尽扫描时,覆盖这些环境变量。
|
||||
- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次实时 Docker 镜像,再通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖 lane 的 Node/Git 运行器;这些 lane 会挂载预构建的 tarball。功能镜像会把同一个 tarball 安装到 `/app`,用于已构建应用功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会避免繁重的实时、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比活动上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印状态,把成功 lane 的耗时存储到 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 打印加权 lane 清单而不构建或运行 Docker,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、package/镜像需求和凭证的 CI 计划。
|
||||
- `Package Acceptance` 是 GitHub 原生的软件包门禁,用于检查“这个可安装的 tarball 作为产品能工作吗?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 中解析一个候选 package,将其上传为 `package-under-test`,然后针对该精确 tarball 运行可复用 Docker E2E lane,而不是重新打包所选 ref。配置文件按广度排序:`smoke`、`package`、`product` 和 `full`。关于 package/更新/插件契约、已发布升级幸存者矩阵、发布默认值和失败分诊,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,并在命令分派前的启动导入中出现 Commander、prompt UI、undici 或日志等 package 依赖时失败;它还会确保内置 Gateway 网关运行 chunk 低于预算,并拒绝已知冷 Gateway 网关路径的静态导入。打包后的 CLI 冒烟还覆盖根帮助、新手引导帮助、Doctor 帮助、Status、配置 schema 和模型列表命令。
|
||||
- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包括 `2026.4.25-beta.*`)。在该截止点之前,harness 只容忍已发布 package 的元数据缺口:省略的私有 QA inventory 条目、缺失的 `gateway install --wrapper`、tarball 派生 git 夹具中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的 package,这些路径会严格失败。
|
||||
- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层的集成路径。
|
||||
`OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。只有在你明确希望进行更大的穷尽扫描时,才覆盖这些环境变量。
|
||||
- `test:docker:all` 通过 `test:docker:live-build` 构建一次现场 Docker 镜像,通过 `scripts/package-openclaw-for-docker.mjs` 将 OpenClaw 打包一次为 npm tarball,然后构建/复用两个 `scripts/e2e/Dockerfile` 镜像。裸镜像只是用于安装/更新/插件依赖 lane 的 Node/Git 运行器;这些 lane 会挂载预构建的 tarball。功能镜像会将同一个 tarball 安装到 `/app`,用于已构建应用功能 lane。Docker lane 定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。聚合运行使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限防止繁重的现场、npm-install 和多服务 lane 同时全部启动。如果单个 lane 比活动上限更重,调度器仍可在池为空时启动它,然后让它单独运行,直到容量再次可用。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功 lane 的耗时存储在 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中使用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 打印加权 lane 清单而不构建或运行 Docker,或使用 `node scripts/test-docker-all.mjs --plan-json` 打印所选 lane、package/image 需求和凭证的 CI 计划。
|
||||
- `Package Acceptance` 是 GitHub 原生的 package 门禁,用来验证“这个可安装 tarball 是否能作为产品工作?”它会从 `source=npm`、`source=ref`、`source=url` 或 `source=artifact` 解析一个候选 package,将其上传为 `package-under-test`,然后针对这个精确 tarball 运行可复用 Docker E2E lane,而不是重新打包所选 ref。Profile 按覆盖范围排序:`smoke`、`package`、`product` 和 `full`。关于 package/update/plugin 合约、已发布升级存活矩阵、发布默认值和故障分流,请参阅[更新和插件测试](/zh-CN/help/testing-updates-plugins)。
|
||||
- 构建和发布检查会在 tsdown 之后运行 `scripts/check-cli-bootstrap-imports.mjs`。该守卫会从 `dist/entry.js` 和 `dist/cli/run-main.js` 遍历静态构建图,如果命令分派前的启动阶段导入了 Commander、prompt UI、undici 或 logging 等 package 依赖,就会失败;它还会让内置 Gateway 网关运行 chunk 保持在预算内,并拒绝已知冷 Gateway 网关路径的静态导入。打包后的 CLI smoke 还覆盖根帮助、onboard 帮助、doctor 帮助、status、配置 schema 和一个模型列表命令。
|
||||
- Package Acceptance 旧版兼容性上限为 `2026.4.25`(包含 `2026.4.25-beta.*`)。在该截止点之前,harness 只容忍已发布 package 的元数据缺口:省略的私有 QA inventory 条目、缺失的 `gateway install --wrapper`、tarball 派生 git 夹具中缺失的 patch 文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。对于 `2026.4.25` 之后的 package,这些路径都是严格失败。
|
||||
- 容器 smoke 运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:update-channel-switch`、`test:docker:upgrade-survivor`、`test:docker:published-upgrade-survivor`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`test:docker:gateway-network`、`test:docker:browser-cdp-snapshot`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。
|
||||
|
||||
实时模型 Docker 运行器还只会绑定挂载所需的 CLI 鉴权 home(或在运行未缩小时挂载所有受支持的鉴权 home),然后在运行前把它们复制到容器 home 中,使外部 CLI OAuth 可以刷新令牌而不会修改主机鉴权存储:
|
||||
现场模型 Docker 运行器还只会 bind-mount 所需的 CLI 认证 home(或在运行未缩小时挂载所有受支持的 home),然后在运行前将它们复制到容器 home 中,使外部 CLI OAuth 可以刷新 token,而不修改主机认证存储:
|
||||
|
||||
- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`)
|
||||
- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,并通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 严格覆盖 Droid/OpenCode)
|
||||
- CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`)
|
||||
- Codex 应用服务器 harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`)
|
||||
- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`)
|
||||
- Gateway 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`)
|
||||
- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是一个私有 QA 源码检出通道。它有意不属于包 Docker 发布通道,因为 npm tarball 会省略 QA Lab。
|
||||
- 可观测性冒烟测试:`pnpm qa:otel:smoke` 是私有 QA 源码检出通道。它有意不属于包 Docker 发布通道,因为 npm tarball 会省略 QA Lab。
|
||||
- Open WebUI 实时冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`)
|
||||
- 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`)
|
||||
- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包好的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,运行 Doctor,并运行一次模拟的 OpenAI 智能体回合。可用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包好的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后的工作情况,然后切回包 `stable` 并检查更新状态。
|
||||
- 升级幸存者冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包好的 OpenClaw tarball 安装到一个脏的旧用户 fixture 上,该 fixture 包含智能体、渠道配置、插件 allowlist、陈旧的插件依赖状态,以及现有工作区/会话文件。它会在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 Doctor,然后启动一个 local loopback Gateway 网关,并检查配置/状态保留情况以及启动/Status 预算。
|
||||
- 已发布升级幸存者冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,播种真实的现有用户文件,用烘焙好的命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个 local loopback Gateway 网关,并检查已配置意图、状态保留、启动、`/healthz`、`/readyz` 和 RPC Status 预算。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖单个基线,用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 要求聚合调度器展开精确基线,并用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开 issue 形态的 fixture,例如 `reported-issues`;reported-issues 集合包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些暴露为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。
|
||||
- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文 transcript 持久化,以及 Doctor 对受影响的重复 prompt-rewrite 分支的修复。
|
||||
- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。可用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建 Docker 镜像复制 `dist/`。
|
||||
- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为升级到候选 tarball 之前的稳定基线。本地可用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke 工作流的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留一个隔离的 npm 缓存,这样 root 拥有的缓存条目不会掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。
|
||||
- Install Smoke CI 使用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,在本地运行该脚本且不要设置该环境变量。
|
||||
- Npm tarball 新手引导/渠道/智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包好的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,运行 doctor,然后运行一次模拟的 OpenAI 智能体轮次。可用 `OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机重新构建,或用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- 更新渠道切换冒烟测试:`pnpm test:docker:update-channel-switch` 会在 Docker 中全局安装打包好的 OpenClaw tarball,从包 `stable` 切换到 git `dev`,验证持久化的渠道和插件更新后工作正常,然后切回包 `stable` 并检查更新状态。
|
||||
- 升级存活冒烟测试:`pnpm test:docker:upgrade-survivor` 会把打包好的 OpenClaw tarball 安装到一个带有智能体、渠道配置、插件 allowlist、陈旧插件依赖状态以及既有工作区/会话文件的脏旧用户夹具上。它会在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 doctor,然后启动一个 loopback Gateway 网关,并检查配置/状态保留以及启动/状态预算。
|
||||
- 已发布版本升级存活冒烟测试:`pnpm test:docker:published-upgrade-survivor` 默认安装 `openclaw@latest`,播种真实的既有用户文件,用内置命令配方配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互式 doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个 loopback Gateway 网关,并检查已配置意图、状态保留、启动、`/healthz`、`/readyz` 和 RPC 状态预算。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖单个基线,让聚合调度器用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 展开精确基线,例如 `all-since-2026.4.23`,并用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS` 展开问题形态的夹具,例如 `reported-issues`;reported-issues 集包含 `configured-plugin-installs`,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将它们公开为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。
|
||||
- 会话运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文转录持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。
|
||||
- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 返回内置图像提供商而不是挂起。可用 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,用 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或用 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。
|
||||
- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在它的 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟测试默认使用 npm `latest` 作为稳定基线,然后升级到候选 tarball。在本地用 `OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22` 覆盖,或在 GitHub 上用 Install Smoke workflow 的 `update_baseline_version` 输入覆盖。非 root 安装器检查会保留隔离的 npm 缓存,确保 root 拥有的缓存条目不会掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。
|
||||
- Install Smoke CI 会用 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;需要覆盖直接 `npm install -g` 时,请在本地不带该环境变量运行脚本。
|
||||
- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离的容器 home 中播种两个智能体和一个工作区,运行 `agents delete --json`,并验证有效 JSON 以及保留工作区行为。可用 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
|
||||
- Gateway 网关联网(两个容器,WS 认证 + 健康检查):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`)
|
||||
- 浏览器 CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像和一个 Chromium 层,使用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。
|
||||
- OpenAI Responses web_search 最小 reasoning 回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)通过 Gateway 网关运行一个模拟的 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始详情出现在 Gateway 网关日志中。
|
||||
- MCP 渠道桥接(已播种 Gateway 网关 + stdio 桥接 + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`)
|
||||
- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`)
|
||||
- Gateway 网关联网(两个容器,WS 认证 + health):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`)
|
||||
- Browser CDP 快照冒烟测试:`pnpm test:docker:browser-cdp-snapshot`(脚本:`scripts/e2e/browser-cdp-snapshot-docker.sh`)会构建源码 E2E 镜像和一个 Chromium 层,用原始 CDP 启动 Chromium,运行 `browser doctor --deep`,并验证 CDP 角色快照覆盖链接 URL、游标提升的可点击项、iframe refs 和 frame 元数据。
|
||||
- OpenAI Responses web_search 最小推理回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行模拟的 OpenAI 服务器,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始详情出现在 Gateway 网关日志中。
|
||||
- MCP 渠道桥接(播种的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`)
|
||||
- Pi bundle MCP 工具(真实 stdio MCP server + 嵌入式 Pi profile allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`)
|
||||
- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后拆除 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`)
|
||||
- 插件(本地路径、`file:`、带 hoisted 依赖的 npm registry、git moving refs、ClawHub kitchen-sink、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`)
|
||||
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认 kitchen-sink 包/运行时对。没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL` 时,该测试使用 hermetic 本地 ClawHub fixture 服务器。
|
||||
- 插件更新未变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`)
|
||||
- 插件(local path、`file:`、带提升依赖的 npm registry、git moving refs、ClawHub kitchen-sink、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`)
|
||||
设置 `OPENCLAW_PLUGINS_E2E_CLAWHUB=0` 可跳过 ClawHub 块,或用 `OPENCLAW_PLUGINS_E2E_CLAWHUB_SPEC` 和 `OPENCLAW_PLUGINS_E2E_CLAWHUB_ID` 覆盖默认的 kitchen-sink 包/运行时对。如果没有 `OPENCLAW_CLAWHUB_URL`/`CLAWHUB_URL`,测试会使用 hermetic 本地 ClawHub 夹具服务器。
|
||||
- 插件更新无变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`)
|
||||
- 配置重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`)
|
||||
- 插件:`pnpm test:docker:plugins` 覆盖本地路径、`file:`、带 hoisted 依赖的 npm registry、git moving refs、ClawHub fixtures、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的未变化更新行为。
|
||||
- 插件:`pnpm test:docker:plugins` 覆盖 local path、`file:`、带提升依赖的 npm registry、git moving refs、ClawHub 夹具、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新冒烟测试。`pnpm test:docker:plugin-update` 覆盖已安装插件的无变化更新行为。
|
||||
|
||||
要手动预构建并复用共享功能镜像:
|
||||
|
||||
@ -553,63 +559,60 @@ OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local pnpm test:docker:
|
||||
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e-functional:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels
|
||||
```
|
||||
|
||||
设置后,诸如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 之类的套件特定镜像覆盖仍然优先。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地尚不存在,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。
|
||||
设置后,像 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这样的套件专用镜像覆盖项仍然优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地尚不存在,脚本会拉取它。QR 和安装器 Docker 测试保留自己的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。
|
||||
|
||||
实时模型 Docker runner 还会以只读方式 bind-mount 当前 checkout,并
|
||||
将其暂存到容器内的临时 workdir。这会保持运行时
|
||||
镜像精简,同时仍针对你的精确本地源码/配置运行 Vitest。
|
||||
暂存步骤会跳过大型本地专用缓存和应用构建产物,例如
|
||||
实时模型 Docker runner 还会以只读方式 bind-mount 当前检出,
|
||||
并在容器内将其暂存到临时工作目录。这样可让运行时
|
||||
镜像保持精简,同时仍能针对你的精确本地源码/配置运行 Vitest。
|
||||
暂存步骤会跳过大型本地专用缓存和应用构建输出,例如
|
||||
`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或
|
||||
Gradle 输出目录,这样 Docker 实时运行不会花费数分钟复制
|
||||
机器特定产物。
|
||||
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,因此 Gateway 网关实时探测不会在容器内启动
|
||||
Gradle 输出目录,因此 Docker 实时运行不会花数分钟复制
|
||||
机器专用工件。
|
||||
它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,使 Gateway 网关实时探测不会在容器内启动
|
||||
真实的 Telegram/Discord 等渠道 worker。
|
||||
`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要从该 Docker 通道收窄或排除 Gateway 网关
|
||||
实时覆盖时,也要透传
|
||||
`OPENCLAW_LIVE_GATEWAY_*`。
|
||||
`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它启动一个
|
||||
启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,
|
||||
再启动一个固定版本的 Open WebUI 容器连接到该 Gateway 网关,通过
|
||||
`test:docker:live-models` 仍会运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 通道中的 Gateway 网关实时覆盖范围时,
|
||||
也要传入 `OPENCLAW_LIVE_GATEWAY_*`。
|
||||
`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它会启动一个
|
||||
启用 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器,
|
||||
再启动一个固定版本的 Open WebUI 容器连接该 Gateway 网关,通过
|
||||
Open WebUI 登录,验证 `/api/models` 暴露 `openclaw/default`,然后通过
|
||||
Open WebUI 的 `/api/chat/completions` 代理发送一个
|
||||
真实聊天请求。
|
||||
Open WebUI 的 `/api/chat/completions` 代理发送一个真实聊天请求。
|
||||
首次运行可能明显更慢,因为 Docker 可能需要拉取
|
||||
Open WebUI 镜像,且 Open WebUI 可能需要完成自己的冷启动设置。
|
||||
Open WebUI 镜像,而 Open WebUI 可能也需要完成自己的冷启动设置。
|
||||
该通道需要可用的实时模型密钥,`OPENCLAW_PROFILE_FILE`
|
||||
(默认 `~/.profile`)是在 Docker 化运行中提供它的主要方式。
|
||||
成功运行会打印一个小型 JSON payload,例如 `{ "ok": true, "model":
|
||||
"openclaw/default", ... }`。
|
||||
`test:docker:mcp-channels` 有意保持确定性,不需要
|
||||
真实 Telegram、Discord 或 iMessage 账号。它会启动一个已播种的 Gateway 网关
|
||||
容器,启动第二个容器来 spawn `openclaw mcp serve`,然后
|
||||
验证路由后的会话发现、transcript 读取、附件元数据、
|
||||
实时事件队列行为、出站发送路由,以及通过真实 stdio MCP 桥接发出的 Claude 风格渠道 +
|
||||
权限通知。通知检查会直接
|
||||
检查原始 stdio MCP frames,因此冒烟测试验证的是
|
||||
桥接实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。
|
||||
真实 Telegram、Discord 或 iMessage 账号。它会启动一个播种的 Gateway 网关
|
||||
容器,启动第二个容器来生成 `openclaw mcp serve`,然后
|
||||
验证路由会话发现、转录读取、附件元数据、
|
||||
实时事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 +
|
||||
权限通知。通知检查会直接检查原始 stdio MCP frame,因此该冒烟测试验证的是
|
||||
bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露的内容。
|
||||
`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要实时
|
||||
模型密钥。它构建 repo Docker 镜像,在容器内启动一个真实 stdio MCP 探测服务器,
|
||||
模型密钥。它会构建 repo Docker 镜像,在容器内启动真实 stdio MCP 探测服务器,
|
||||
通过嵌入式 Pi bundle
|
||||
MCP 运行时物化该服务器,执行工具,然后验证 `coding` 和 `messaging` 保留
|
||||
MCP 运行时物化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 保留
|
||||
`bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会过滤它们。
|
||||
`test:docker:cron-mcp-cleanup` 是确定性的,不需要实时模型
|
||||
密钥。它启动一个带真实 stdio MCP 探测服务器的已播种 Gateway 网关,运行一个
|
||||
隔离的 cron 回合和一个 `/subagents spawn` 一次性子回合,然后验证
|
||||
每次运行后 MCP 子进程都会退出。
|
||||
密钥。它会启动带真实 stdio MCP 探测服务器的播种 Gateway 网关,运行一个
|
||||
隔离 cron 轮次和一次 `/subagents spawn` 一次性子轮次,然后验证
|
||||
MCP 子进程在每次运行后退出。
|
||||
|
||||
手动 ACP 自然语言线程冒烟测试(非 CI):
|
||||
手动 ACP 自然语言 thread 冒烟测试(不在 CI 中):
|
||||
|
||||
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...`
|
||||
- 保留此脚本用于回归/调试工作流。ACP 线程路由验证可能还会再次需要它,因此不要删除它。
|
||||
- 保留此脚本用于回归/调试工作流。ACP thread 路由验证将来可能还会需要它,因此不要删除。
|
||||
|
||||
有用的环境变量:
|
||||
|
||||
- `OPENCLAW_CONFIG_DIR=...`(默认值:`~/.openclaw`)挂载到 `/home/node/.openclaw`
|
||||
- `OPENCLAW_WORKSPACE_DIR=...`(默认值:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace`
|
||||
- `OPENCLAW_PROFILE_FILE=...`(默认值:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前加载
|
||||
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` 加载的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI 凭证
|
||||
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认值:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内部缓存 CLI 安装
|
||||
- `$HOME` 下的外部 CLI 凭证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...`
|
||||
- `OPENCLAW_PROFILE_FILE=...`(默认值:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前 source
|
||||
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 仅验证从 `OPENCLAW_PROFILE_FILE` source 得到的环境变量,使用临时配置/工作区目录,且不挂载外部 CLI 认证
|
||||
- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认值:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存的 CLI 安装
|
||||
- `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...`
|
||||
- 默认目录:`.minimax`
|
||||
- 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json`
|
||||
- 缩小范围的提供商运行只会挂载从 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件
|
||||
@ -617,9 +620,9 @@ MCP 运行时物化该服务器,执行工具,然后验证 `coding` 和 `mess
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围
|
||||
- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内筛选提供商
|
||||
- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在不需要重新构建的重复运行中复用已有的 `openclaw:local-live` 镜像
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是环境变量)
|
||||
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI 冒烟测试暴露的模型
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭据来自 profile 存储(而不是环境变量)
|
||||
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关为 Open WebUI smoke 暴露的模型
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI smoke 使用的 nonce 检查提示词
|
||||
- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签
|
||||
|
||||
## 文档完整性检查
|
||||
@ -632,7 +635,7 @@ MCP 运行时物化该服务器,执行工具,然后验证 `coding` 和 `mess
|
||||
这些是不使用真实提供商的“真实流水线”回归:
|
||||
|
||||
- Gateway 网关工具调用(模拟 OpenAI,真实 Gateway 网关 + Agent loop):`src/gateway/gateway.test.ts`(用例:"runs a mock OpenAI tool call end-to-end via gateway agent loop")
|
||||
- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制凭证):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config")
|
||||
- Gateway 网关向导(WS `wizard.start`/`wizard.next`,写入配置 + 强制认证):`src/gateway/gateway.test.ts`(用例:"runs wizard over ws and writes auth token config")
|
||||
|
||||
## 智能体可靠性评估(Skills)
|
||||
|
||||
@ -643,19 +646,19 @@ MCP 运行时物化该服务器,执行工具,然后验证 `coding` 和 `mess
|
||||
|
||||
Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)):
|
||||
|
||||
- **决策:**当提示词中列出 Skills 时,智能体是否选择正确的 Skill(或避开不相关的 Skill)?
|
||||
- **合规性:**智能体是否在使用前读取 `SKILL.md` 并遵循必需的步骤/参数?
|
||||
- **工作流契约:**断言工具顺序、会话历史延续和沙箱边界的多轮场景。
|
||||
- **决策:** 当提示词中列出 Skills 时,智能体是否会选择正确的 Skills(或避开无关 Skills)?
|
||||
- **合规:** 智能体是否会在使用前读取 `SKILL.md`,并遵循所需步骤/参数?
|
||||
- **工作流契约:** 断言工具顺序、会话历史延续和沙箱边界的多轮场景。
|
||||
|
||||
未来评估应首先保持确定性:
|
||||
未来评估应优先保持确定性:
|
||||
|
||||
- 使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skill 文件读取和会话接线。
|
||||
- 一组小型、聚焦 Skills 的场景(使用与避开、门控、提示注入)。
|
||||
- 可选的实时评估(选择加入、由环境变量门控)仅在 CI 安全套件就位后添加。
|
||||
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、Skills 文件读取和会话接线。
|
||||
- 一小组聚焦 Skills 的场景(使用与避开、门控、提示注入)。
|
||||
- 可选的实时评估(选择加入、由环境变量门控)仅在 CI 安全套件就位后再添加。
|
||||
|
||||
## 契约测试(插件和渠道形状)
|
||||
## 契约测试(插件和渠道形态)
|
||||
|
||||
契约测试验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有发现的插件,并运行一组形状和行为断言。默认的 `pnpm test` 单元测试通道会有意跳过这些共享边界和冒烟文件;当你触及共享渠道或提供商表面时,请显式运行契约命令。
|
||||
契约测试会验证每个已注册的插件和渠道是否符合其接口契约。它们会遍历所有发现的插件,并运行一套形态和行为断言。默认的 `pnpm test` 单元测试通道有意跳过这些共享边界和 smoke 文件;当你触及共享渠道或提供商表面时,请显式运行契约命令。
|
||||
|
||||
### 命令
|
||||
|
||||
@ -667,14 +670,14 @@ Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)):
|
||||
|
||||
位于 `src/channels/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **plugin** - 基本插件形状(ID、名称、能力)
|
||||
- **plugin** - 基础插件形态(id、名称、能力)
|
||||
- **setup** - 设置向导契约
|
||||
- **session-binding** - 会话绑定行为
|
||||
- **outbound-payload** - 消息载荷结构
|
||||
- **inbound** - 入站消息处理
|
||||
- **actions** - 渠道操作处理器
|
||||
- **threading** - 线程 ID 处理
|
||||
- **directory** - 目录/成员名册 API
|
||||
- **directory** - 目录/名册 API
|
||||
- **group-policy** - 群组策略强制执行
|
||||
|
||||
### 提供商 Status 契约
|
||||
@ -682,41 +685,41 @@ Skills 仍缺少的内容(见 [Skills](/zh-CN/tools/skills)):
|
||||
位于 `src/plugins/contracts/*.contract.test.ts`。
|
||||
|
||||
- **status** - 渠道 Status 探测
|
||||
- **registry** - 插件注册表形状
|
||||
- **registry** - 插件注册表形态
|
||||
|
||||
### 提供商契约
|
||||
|
||||
位于 `src/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **auth** - 凭证流程契约
|
||||
- **auth-choice** - 凭证选择/选取
|
||||
- **auth** - 认证流程契约
|
||||
- **auth-choice** - 认证选择/选定
|
||||
- **catalog** - 模型目录 API
|
||||
- **discovery** - 插件设备发现
|
||||
- **discovery** - 插件发现
|
||||
- **loader** - 插件加载
|
||||
- **runtime** - 提供商运行时
|
||||
- **shape** - 插件形状/接口
|
||||
- **shape** - 插件形态/接口
|
||||
- **wizard** - 设置向导
|
||||
|
||||
### 何时运行
|
||||
|
||||
- 更改 plugin-sdk 导出或子路径之后
|
||||
- 添加或修改渠道或提供商插件之后
|
||||
- 重构插件注册或设备发现之后
|
||||
- 更改插件 SDK 导出或子路径后
|
||||
- 添加或修改渠道或提供商插件后
|
||||
- 重构插件注册或发现后
|
||||
|
||||
契约测试在 CI 中运行,不需要真实 API key。
|
||||
|
||||
## 添加回归(指南)
|
||||
|
||||
当你修复在实时运行中发现的提供商/模型问题时:
|
||||
当你修复实时环境中发现的提供商/模型问题时:
|
||||
|
||||
- 尽可能添加 CI 安全回归(模拟/桩提供商,或捕获精确的请求形状转换)
|
||||
- 如果它本质上只能实时验证(速率限制、凭证策略),保持实时测试范围狭窄,并通过环境变量选择加入
|
||||
- 优先针对能捕获该错误的最小层级:
|
||||
- 提供商请求转换/重放错误 → 直接的模型测试
|
||||
- Gateway 网关会话/历史/工具流水线错误 → Gateway 网关实时冒烟测试或 CI 安全的 Gateway 网关模拟测试
|
||||
- 尽可能添加 CI 安全回归(模拟/桩提供商,或捕获精确的请求形态转换)
|
||||
- 如果它本质上只能实时测试(速率限制、认证策略),请保持实时测试范围狭窄,并通过环境变量选择加入
|
||||
- 优先定位能捕获该 bug 的最小层级:
|
||||
- 提供商请求转换/回放 bug → 直接的模型测试
|
||||
- Gateway 网关会话/历史/工具流水线 bug → Gateway 网关实时 smoke 或 CI 安全的 Gateway 网关模拟测试
|
||||
- SecretRef 遍历护栏:
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言包含遍历片段的 exec id 会被拒绝。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会故意在未分类目标 id 上失败,确保新类别不能被静默跳过。
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)为每个 SecretRef 类派生一个采样目标,然后断言包含遍历片段的 exec id 会被拒绝。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标族,请更新该测试中的 `classifyTargetClass`。该测试会有意在未分类的目标 id 上失败,确保新类别不能被静默跳过。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -2,157 +2,151 @@
|
||||
read_when:
|
||||
- 正在查找公开发布渠道定义
|
||||
- 运行发布验证或包验收
|
||||
- 正在查找版本命名和发布节奏
|
||||
summary: 发布通道、操作员检查清单、验证环境、版本命名和发布节奏
|
||||
- 查找版本命名和发布节奏
|
||||
summary: 发布轨道、操作员检查清单、验证环境、版本命名和节奏
|
||||
title: 发布策略
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T17:33:37Z"
|
||||
generated_at: "2026-05-02T18:56:27Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: d58ea2416a3c1e129e5167c20b1c8c55eca581c9f811efee5722b5dfd336a85d
|
||||
source_hash: 18cee58dcad91e24c0d76622a9ed1568f93e4e2c51deae9ad06ccc7feb831d3a
|
||||
source_path: reference/RELEASING.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 有四个公开发布通道:
|
||||
OpenClaw 有四条公开发布线:
|
||||
|
||||
- 稳定版:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest`
|
||||
- Alpha:发布到 npm `alpha` 的预发布标签
|
||||
- Beta:发布到 npm `beta` 的预发布标签
|
||||
- 开发版:`main` 的移动头部
|
||||
- stable:带标签的发布版本,默认发布到 npm `beta`,或在明确请求时发布到 npm `latest`
|
||||
- alpha:发布到 npm `alpha` 的预发布标签
|
||||
- beta:发布到 npm `beta` 的预发布标签
|
||||
- dev:`main` 的移动最新提交
|
||||
|
||||
## 版本命名
|
||||
|
||||
- 稳定版发布版本:`YYYY.M.D`
|
||||
- 稳定发布版本:`YYYY.M.D`
|
||||
- Git 标签:`vYYYY.M.D`
|
||||
- 稳定版修正发布版本:`YYYY.M.D-N`
|
||||
- 稳定修正发布版本:`YYYY.M.D-N`
|
||||
- Git 标签:`vYYYY.M.D-N`
|
||||
- Alpha 预发布版本:`YYYY.M.D-alpha.N`
|
||||
- Git 标签:`vYYYY.M.D-alpha.N`
|
||||
- Beta 预发布版本:`YYYY.M.D-beta.N`
|
||||
- Git 标签:`vYYYY.M.D-beta.N`
|
||||
- 月份或日期不要补零
|
||||
- `latest` 表示当前已提升的稳定版 npm 发布版本
|
||||
- `alpha` 表示当前 Alpha 安装目标
|
||||
- `beta` 表示当前 Beta 安装目标
|
||||
- 稳定版和稳定版修正发布默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,也可以稍后提升一个已审核的 Beta 构建
|
||||
- `latest` 表示当前已提升的稳定 npm 发布版本
|
||||
- `alpha` 表示当前 alpha 安装目标
|
||||
- `beta` 表示当前 beta 安装目标
|
||||
- 稳定和稳定修正发布默认发布到 npm `beta`;发布操作员可以明确指定 `latest`,或稍后提升经过审查的 beta 构建
|
||||
- 每个稳定版 OpenClaw 发布都会同时交付 npm 包和 macOS 应用;
|
||||
Beta 发布通常会先验证并发布 npm/包路径,
|
||||
mac 应用构建/签名/公证默认保留给稳定版,除非明确请求
|
||||
beta 发布通常先验证并发布 npm/包路径,除非明确请求,否则
|
||||
mac 应用的构建/签名/公证会保留给稳定版
|
||||
|
||||
## 发布节奏
|
||||
|
||||
- 发布按 Beta 优先推进
|
||||
- 只有在最新 Beta 验证通过后,稳定版才会跟进
|
||||
- 维护者通常从基于当前 `main` 创建的 `release/YYYY.M.D` 分支切出发布,
|
||||
- 发布按 beta 优先推进
|
||||
- 只有在最新 beta 完成验证后才会进入稳定版
|
||||
- 维护者通常从基于当前 `main` 创建的 `release/YYYY.M.D` 分支发布,
|
||||
因此发布验证和修复不会阻塞 `main` 上的新开发
|
||||
- 如果一个 Beta 标签已经被推送或发布并且需要修复,维护者会切出下一个
|
||||
`-beta.N` 标签,而不是删除或重新创建旧的 Beta 标签
|
||||
- 详细的发布流程、审批、凭证和恢复说明仅限维护者查看
|
||||
- 如果 beta 标签已经推送或发布且需要修复,维护者会发布下一个
|
||||
`-beta.N` 标签,而不是删除或重新创建旧的 beta 标签
|
||||
- 详细发布流程、审批、凭证和恢复说明仅限维护者查看
|
||||
|
||||
## 发布操作员清单
|
||||
## 发布操作员检查清单
|
||||
|
||||
此清单是发布流程的公开形态。私有凭证、
|
||||
签名、公证、dist-tag 恢复和紧急回滚详情保留在
|
||||
仅限维护者的发布运行手册中。
|
||||
此检查清单是发布流程的公开形态。私有凭证、签名、公证、dist-tag 恢复和紧急回滚细节保留在仅限维护者查看的发布运行手册中。
|
||||
|
||||
1. 从当前 `main` 开始:拉取最新内容,确认目标提交已推送,
|
||||
并确认当前 `main` CI 的状态足够绿色,可以从它创建分支。
|
||||
2. 使用 `/changelog` 基于真实提交历史重写顶部的 `CHANGELOG.md` 区段,
|
||||
保持条目面向用户,提交并推送,然后在创建分支前再 rebase/pull 一次。
|
||||
并确认当前 `main` 的 CI 状态足够健康,可以从它创建分支。
|
||||
2. 使用 `/changelog` 根据真实提交历史重写顶部 `CHANGELOG.md` 章节,
|
||||
保持条目面向用户,提交它,推送它,并在创建分支前再次 rebase/pull。
|
||||
3. 审查
|
||||
`src/plugins/compat/registry.ts` 和
|
||||
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。仅在升级路径仍被覆盖时移除已过期的
|
||||
兼容性;否则记录为什么有意继续保留。
|
||||
`src/commands/doctor/shared/deprecation-compat.ts` 中的发布兼容性记录。只有在升级路径仍被覆盖时才移除过期兼容性,
|
||||
或记录为什么有意继续保留。
|
||||
4. 从当前 `main` 创建 `release/YYYY.M.D`;不要直接在 `main` 上执行常规发布工作。
|
||||
5. 为目标标签更新所有必需的版本位置,运行
|
||||
`pnpm plugins:sync`,使可发布插件包共享该发布版本和兼容性元数据,然后运行本地确定性预检:
|
||||
5. 为目标标签更新每个必需的版本位置,运行
|
||||
`pnpm plugins:sync`,使可发布的插件包共享发布版本和兼容性元数据,然后运行本地确定性预检:
|
||||
`pnpm check:test-types`、`pnpm check:architecture`、
|
||||
`pnpm build && pnpm ui:build`、`pnpm plugins:sync:check` 和
|
||||
`pnpm release:check`。
|
||||
6. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`。在标签存在之前,
|
||||
允许使用完整的 40 字符发布分支 SHA 进行仅验证预检。保存成功的 `preflight_run_id`。
|
||||
7. 针对发布分支、标签或完整提交 SHA,用 `Full Release Validation` 启动所有预发布测试。这是四个大型发布测试盒的唯一手动入口点:Vitest、Docker、QA Lab 和 Package。
|
||||
8. 如果验证失败,在发布分支上修复,并重新运行能证明修复的最小失败文件、通道、工作流作业、包配置、提供商或模型允许列表。只有当变更面使之前的证据失效时,才重新运行完整总控流程。
|
||||
9. 对于 Alpha 或 Beta,标记 `vYYYY.M.D-alpha.N` 或 `vYYYY.M.D-beta.N`,然后从匹配的 `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 `pnpm plugins:sync:check`,
|
||||
先将所有可发布插件包发布到 npm,其次将同一批发布到 ClawHub,然后使用匹配的 dist-tag 提升已准备好的 OpenClaw npm 预检产物。发布后,针对已发布的 `openclaw@YYYY.M.D-alpha.N`、`openclaw@alpha`、
|
||||
`openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的预发布需要修复,切出下一个匹配的预发布编号;
|
||||
不要删除或重写旧的预发布。
|
||||
10. 对于稳定版,只有在已审核的 Beta 或发布候选具备所需验证证据后才继续。稳定版 npm 发布也通过
|
||||
`OpenClaw Release Publish` 完成,通过
|
||||
`preflight_run_id` 复用成功的预检产物;稳定版 macOS 发布就绪还要求 `main` 上存在打包后的
|
||||
`.zip`、`.dmg`、`.dSYM.zip` 以及更新后的 `appcast.xml`。
|
||||
允许使用完整 40 字符的发布分支 SHA 进行仅验证预检。保存成功的 `preflight_run_id`。
|
||||
7. 针对发布分支、标签或完整提交 SHA,使用 `Full Release Validation` 启动所有预发布测试。这是四个大型发布测试箱的唯一手动入口点:Vitest、Docker、QA Lab 和 Package。
|
||||
8. 如果验证失败,在发布分支上修复,并重新运行最小的失败文件、发布线、工作流作业、包配置、提供商或模型允许列表,以证明修复有效。只有当变更表面让先前证据过期时,才重新运行完整总括验证。
|
||||
9. 对于 alpha 或 beta,标记 `vYYYY.M.D-alpha.N` 或 `vYYYY.M.D-beta.N`,然后从匹配的 `release/YYYY.M.D` 分支运行 `OpenClaw Release Publish`。它会验证 `pnpm plugins:sync:check`,先将所有可发布的插件包发布到 npm,再将同一组包发布到 ClawHub,然后使用匹配的 dist-tag 提升已准备好的 OpenClaw npm 预检产物。发布后,针对已发布的 `openclaw@YYYY.M.D-alpha.N`、`openclaw@alpha`、`openclaw@YYYY.M.D-beta.N` 或 `openclaw@beta` 包运行发布后包验收。如果已推送或已发布的预发布需要修复,请发布下一个匹配的预发布编号;
|
||||
不要删除或重写旧预发布。
|
||||
10. 对于稳定版,只有在经过审查的 beta 或发布候选版本具备所需验证证据后才继续。稳定版 npm 发布也通过
|
||||
`OpenClaw Release Publish` 进行,并通过
|
||||
`preflight_run_id` 复用成功的预检产物;稳定版 macOS 发布就绪还要求
|
||||
`main` 上存在打包好的 `.zip`、`.dmg`、`.dSYM.zip` 和更新后的 `appcast.xml`。
|
||||
11. 发布后,运行 npm 发布后验证器;在需要发布后渠道证明时,可选运行独立的已发布 npm Telegram E2E;
|
||||
在需要时进行 dist-tag 提升;基于完整匹配的 `CHANGELOG.md` 区段生成 GitHub 发布/预发布说明;并完成发布公告步骤。
|
||||
在需要时执行 dist-tag 提升;根据完整匹配的 `CHANGELOG.md` 章节生成 GitHub 发布/预发布说明;并执行发布公告步骤。
|
||||
|
||||
## 发布预检
|
||||
|
||||
- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 也能在更快的本地 `pnpm check` 门禁之外得到覆盖
|
||||
- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外保持绿色
|
||||
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保打包验证步骤所需的 `dist/*` 发布产物和 Control UI 包存在
|
||||
- 在根版本号提升之后、打标签之前运行 `pnpm plugins:sync`。它会更新可发布插件包版本、OpenClaw 对等/API 兼容性元数据、构建元数据和插件变更日志占位内容,以匹配核心发布版本。`pnpm plugins:sync:check` 是非修改型发布守卫;如果忘记此步骤,发布工作流会在任何注册表变更之前失败。
|
||||
- 在发布审批前运行手动 `Full Release Validation` 工作流,以便从单一入口点启动所有预发布测试箱。它接受分支、标签或完整提交 SHA,分派手动 `CI`,并为安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab parity、Matrix 和 Telegram 通道分派 `OpenClaw Release Checks`。当 `release_profile=full` 且 `rerun_group=all` 时,它还会针对来自发布检查的 `release-package-under-test` 产物运行包 Telegram E2E。发布后,如果同一个 Telegram E2E 也应验证已发布的 npm 包,请提供 `npm_telegram_package_spec`。当私有证据报告应证明验证与已发布的 npm 包匹配、但不强制运行 Telegram E2E 时,请提供 `evidence_package_spec`。示例:
|
||||
`gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D`
|
||||
- 当你希望在发布工作继续推进的同时为包候选版本提供旁路证明时,运行手动 `Package Acceptance` 工作流。对 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 以当前 `workflow_ref` harness 打包可信的 `package_ref` 分支/标签/SHA;对带有必需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对另一个 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选版本解析为 `package-under-test`,复用针对该 tarball 的 Docker E2E 发布调度器,并可通过 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 对同一 tarball 运行 Telegram QA。当所选 Docker 通道包含 `published-upgrade-survivor` 时,包产物就是候选版本,而 `published_upgrade_survivor_baseline` 会选择已发布基线。
|
||||
- 在发布预检前运行 `pnpm check:test-types`,确保测试 TypeScript 在更快的本地 `pnpm check` 门禁之外也保持覆盖
|
||||
- 在发布预检前运行 `pnpm check:architecture`,确保更广泛的导入循环和架构边界检查在更快的本地门禁之外也保持绿色
|
||||
- 在 `pnpm release:check` 前运行 `pnpm build && pnpm ui:build`,确保预期的 `dist/*` 发布产物和 Control UI 包已存在,供打包校验步骤使用
|
||||
- 在根版本号提升之后、打标签之前运行 `pnpm plugins:sync`。它会更新可发布插件包版本、OpenClaw peer/API 兼容性元数据、构建元数据和插件变更日志桩,使其匹配核心发布版本。`pnpm plugins:sync:check` 是非变更型发布防护;如果忘记此步骤,发布工作流会在任何 registry 变更前失败。
|
||||
- 在发布批准前运行手动 `Full Release Validation` 工作流,从一个入口启动所有预发布测试盒。它接受分支、标签或完整提交 SHA,分发手动 `CI`,并分发 `OpenClaw Release Checks`,覆盖安装冒烟、包验收、Docker 发布路径套件、live/E2E、OpenWebUI、QA Lab 对等性、Matrix 和 Telegram 通道。使用 `release_profile=full` 和 `rerun_group=all` 时,它还会针对发布检查中的 `release-package-under-test` 产物运行包 Telegram E2E。发布后,如果同一个 Telegram E2E 也需要证明已发布的 npm 包,请提供 `npm_telegram_package_spec`。发布后,如果 Package Acceptance 应针对已发货的 npm 包而不是 SHA 构建产物运行其包/更新矩阵,请提供 `package_acceptance_package_spec`。如果私有证据报告应证明验证匹配已发布的 npm 包,但不强制运行 Telegram E2E,请提供 `evidence_package_spec`。示例:`gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D`
|
||||
- 当你希望在发布工作继续推进时,为包候选项获取旁路证明,请运行手动 `Package Acceptance` 工作流。对 `openclaw@alpha`、`openclaw@beta`、`openclaw@latest` 或精确发布版本使用 `source=npm`;使用 `source=ref` 以当前 `workflow_ref` harness 打包受信任的 `package_ref` 分支/标签/SHA;对带必需 SHA-256 的 HTTPS tarball 使用 `source=url`;或对另一个 GitHub Actions 运行上传的 tarball 使用 `source=artifact`。该工作流会将候选项解析为 `package-under-test`,针对该 tarball 复用 Docker E2E 发布调度器,并可使用 `telegram_mode=mock-openai` 或 `telegram_mode=live-frontier` 针对同一个 tarball 运行 Telegram QA。当所选 Docker 通道包含 `published-upgrade-survivor` 时,包产物就是候选项,而 `published_upgrade_survivor_baseline` 选择已发布的基线。
|
||||
示例:`gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai`
|
||||
常见配置档:
|
||||
常用配置:
|
||||
- `smoke`:安装/渠道/智能体、Gateway 网关网络和配置重载通道
|
||||
- `package`:产物原生的包/更新/插件通道,不包含 OpenWebUI 或 live ClawHub
|
||||
- `product`:包配置档,加上 MCP 渠道、cron/子智能体清理、OpenAI web 搜索和 OpenWebUI
|
||||
- `package`:产物原生包/更新/插件通道,不包含 OpenWebUI 或 live ClawHub
|
||||
- `product`:包配置加上 MCP 渠道、cron/子智能体清理、OpenAI Web 搜索和 OpenWebUI
|
||||
- `full`:带 OpenWebUI 的 Docker 发布路径分块
|
||||
- `custom`:用于聚焦重跑的精确 `docker_lanes` 选择
|
||||
- 当你只需要发布候选版本的完整常规 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 分派会绕过 changed 作用域,并强制运行 Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n 通道。
|
||||
- 当你只需要发布候选版本的完整普通 CI 覆盖时,直接运行手动 `CI` 工作流。手动 CI 分发会绕过变更范围限定,并强制运行 Linux Node 分片、内置插件分片、渠道合约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python skills、Windows、macOS、Android 和 Control UI i18n 通道。
|
||||
示例:`gh workflow run ci.yml --ref release/YYYY.M.D`
|
||||
- 验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP 接收器执行 QA-lab,并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,不需要 Opik、Langfuse 或其他外部采集器。
|
||||
- 验证发布遥测时运行 `pnpm qa:otel:smoke`。它通过本地 OTLP/HTTP 接收器执行 QA-lab,并验证导出的 trace span 名称、有界属性以及内容/标识符脱敏,无需 Opik、Langfuse 或其他外部收集器。
|
||||
- 每次打标签发布前运行 `pnpm release:check`
|
||||
- 标签存在后,为会产生变更的发布序列运行 `OpenClaw Release Publish`。从 `release/YYYY.M.D` 分派它(或在发布 main 可达标签时从 `main` 分派),传入发布标签和成功的 OpenClaw npm `preflight_run_id`,并保持默认插件发布范围 `all-publishable`,除非你正在有意执行聚焦修复。该工作流会串行化插件 npm 发布、插件 ClawHub 发布和 OpenClaw npm 发布,确保核心包不会先于其外置插件发布。
|
||||
- 发布检查现在在单独的手动工作流中运行:
|
||||
`OpenClaw Release Checks`
|
||||
- `OpenClaw Release Checks` 还会在发布审批前运行 QA Lab mock parity 门禁,以及快速 live Matrix 配置档和 Telegram QA 通道。live 通道使用 `qa-live-shared` 环境;Telegram 还使用 Convex CI 凭据租约。当你希望并行获得完整 Matrix 传输、媒体和 E2EE 清单时,请运行手动 `QA-Lab - All Lanes` 工作流,并设置 `matrix_profile=all` 和 `matrix_shards=true`。
|
||||
- 跨操作系统安装和升级运行时验证是公开 `OpenClaw Release Checks` 与 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
|
||||
- 这种拆分是有意的:保持真实 npm 发布路径简短、确定且聚焦产物,同时让较慢的 live 检查保留在自己的通道中,避免拖慢或阻塞发布
|
||||
- 携带密钥的发布检查应通过 `Full Release Validation` 分派,或从 `main`/发布工作流引用分派,以便工作流逻辑和密钥保持受控
|
||||
- 只要解析出的提交可从 OpenClaw 分支或发布标签到达,`OpenClaw Release Checks` 就接受分支、标签或完整提交 SHA
|
||||
- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符的工作流分支提交 SHA,不要求已推送标签
|
||||
- 标签存在后,运行 `OpenClaw Release Publish` 执行会变更状态的发布序列。从 `release/YYYY.M.D`(或发布 main 可达标签时从 `main`)分发它,传入发布标签和成功的 OpenClaw npm `preflight_run_id`,并保持默认插件发布范围 `all-publishable`,除非你有意执行聚焦修复。该工作流会串行执行插件 npm 发布、插件 ClawHub 发布和 OpenClaw npm 发布,确保核心包不会早于其外置插件发布。
|
||||
- 发布检查现在运行在单独的手动工作流中:`OpenClaw Release Checks`
|
||||
- `OpenClaw Release Checks` 还会在发布批准前运行 QA Lab 模拟对等性门禁、快速 live Matrix 配置和 Telegram QA 通道。live 通道使用 `qa-live-shared` 环境;Telegram 还使用 Convex CI 凭据租约。当你需要并行获取完整 Matrix 传输、媒体和 E2EE 清单时,使用 `matrix_profile=all` 和 `matrix_shards=true` 运行手动 `QA-Lab - All Lanes` 工作流。
|
||||
- 跨操作系统安装和升级运行时验证是公开 `OpenClaw Release Checks` 和 `Full Release Validation` 的一部分,它们会直接调用可复用工作流 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`
|
||||
- 这种拆分是有意的:保持真实 npm 发布路径短、确定且以产物为中心,同时较慢的 live 检查保留在自己的通道中,避免拖慢或阻塞发布
|
||||
- 携带 secret 的发布检查应通过 `Full Release Validation` 分发,或从 `main`/发布工作流 ref 分发,以确保工作流逻辑和 secret 保持受控
|
||||
- `OpenClaw Release Checks` 接受分支、标签或完整提交 SHA,只要解析出的提交可从 OpenClaw 分支或发布标签到达
|
||||
- `OpenClaw NPM Release` 仅验证预检也接受当前完整 40 字符工作流分支提交 SHA,不要求已推送标签
|
||||
- 该 SHA 路径仅用于验证,不能提升为真实发布
|
||||
- 在 SHA 模式下,工作流只会为包元数据检查合成 `v<package.json version>`;真实发布仍需要真实发布标签
|
||||
- 两个工作流都将真实发布和提升路径保持在 GitHub 托管 runner 上,而非修改型验证路径可以使用更大的 Blacksmith Linux runner
|
||||
- 该工作流会使用 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache` 运行,并同时使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 工作流密钥
|
||||
- 在 SHA 模式下,工作流仅为包元数据检查合成 `v<package.json version>`;真实发布仍需要真实发布标签
|
||||
- 两个工作流都将真实发布和提升路径保留在 GitHub 托管 runner 上,而非变更型验证路径可以使用更大的 Blacksmith Linux runner
|
||||
- 该工作流运行 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`,并使用 `OPENAI_API_KEY` 和 `ANTHROPIC_API_KEY` 两个工作流 secret
|
||||
- npm 发布预检不再等待单独的发布检查通道
|
||||
- 在审批前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正标签)
|
||||
- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版本),以在全新的临时前缀中验证已发布注册表安装路径
|
||||
- beta 发布后,运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共享租约 Telegram 凭据池,针对已发布 npm 包验证已安装包新手引导、Telegram 设置和真实 Telegram E2E。本地维护者的一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭据。
|
||||
- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流,从 GitHub Actions 运行同一项发布后检查。它有意只允许手动运行,不会在每次合并时运行。
|
||||
- 维护者发布自动化现在使用预检后提升:
|
||||
- 批准前运行 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`(或匹配的 beta/修正标签)
|
||||
- npm 发布后,运行 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`(或匹配的 beta/修正版本),在全新的临时前缀中验证已发布 registry 的安装路径
|
||||
- beta 发布后,运行 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`,使用共享租约 Telegram 凭据池,针对已发布的 npm 包验证已安装包的新手引导、Telegram 设置和真实 Telegram E2E。本地维护者一次性运行可以省略 Convex 变量,并直接传入三个 `OPENCLAW_QA_TELEGRAM_*` 环境变量凭据。
|
||||
- 维护者可以通过手动 `NPM Telegram Beta E2E` 工作流,从 GitHub Actions 运行同一个发布后检查。它有意仅支持手动运行,不会在每次合并时运行。
|
||||
- 维护者发布自动化现在使用先预检再提升:
|
||||
- 真实 npm 发布必须通过成功的 npm `preflight_run_id`
|
||||
- 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `release/YYYY.M.D` 分支分派
|
||||
- 真实 npm 发布必须从与成功预检运行相同的 `main` 或 `release/YYYY.M.D` 分支分发
|
||||
- 稳定 npm 发布默认使用 `beta`
|
||||
- 稳定 npm 发布可以通过工作流输入显式指定目标为 `latest`
|
||||
- 基于 token 的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,出于安全考虑,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开仓库保持仅 OIDC 发布
|
||||
- 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支上但工作流从 `main` 分派时,请设置 `public_release_branch=release/YYYY.M.D`
|
||||
- 稳定 npm 发布可以通过工作流输入显式目标为 `latest`
|
||||
- 基于令牌的 npm dist-tag 变更现在位于 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`,出于安全原因,因为 `npm dist-tag add` 仍需要 `NPM_TOKEN`,而公开 repo 保持仅 OIDC 发布
|
||||
- 公开 `macOS Release` 仅用于验证;当标签只存在于发布分支上,但工作流从 `main` 分发时,设置 `public_release_branch=release/YYYY.M.D`
|
||||
- 真实私有 mac 发布必须通过成功的私有 mac `preflight_run_id` 和 `validate_run_id`
|
||||
- 真实发布路径会提升已准备好的产物,而不是再次重新构建它们
|
||||
- 对于 `YYYY.M.D-N` 这样的稳定修正发布,发布后验证器还会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的同一临时前缀升级路径,确保发布修正不会静默地让旧的全局安装停留在基础稳定载荷上
|
||||
- npm 发布预检默认失败,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` 载荷,这样我们就不会再次发布空浏览器仪表板
|
||||
- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装注册表布局中。发布如果缺少插件运行时载荷,就会使发布后验证器失败,且不能提升到 `latest`。
|
||||
- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 会在发布发布路径之前捕获意外的打包膨胀
|
||||
- 如果发布工作触及 CI 规划、插件计时清单或插件测试矩阵,请在审批前重新生成并审查由规划器拥有的 `.github/workflows/plugin-prerelease.yml` 中的 `plugin-prerelease-extension-shard` 矩阵输出,确保发布说明不会描述过期的 CI 布局
|
||||
- 稳定 macOS 发布就绪性还包括更新器界面:
|
||||
- GitHub 发布最终必须包含打包后的 `.zip`、`.dmg` 和 `.dSYM.zip`
|
||||
- 对于 `YYYY.M.D-N` 这类稳定修正发布,发布后验证器还会检查从 `YYYY.M.D` 到 `YYYY.M.D-N` 的同一临时前缀升级路径,确保发布修正不会静默地让较旧的全局安装停留在基础稳定 payload 上
|
||||
- npm 发布预检默认失败,除非 tarball 同时包含 `dist/control-ui/index.html` 和非空的 `dist/control-ui/assets/` payload,避免再次发布空的浏览器仪表板
|
||||
- 发布后验证还会检查已发布插件入口点和包元数据是否存在于已安装 registry 布局中。若某次发布缺少插件运行时 payload,发布后验证器会失败,并且该版本不能提升为 `latest`。
|
||||
- `pnpm test:install:smoke` 还会对候选更新 tarball 强制执行 npm pack `unpackedSize` 预算,因此安装器 e2e 能在发布路径发布前捕获意外的打包膨胀
|
||||
- 如果发布工作触及 CI 规划、插件计时 manifest 或插件测试矩阵,请在批准前重新生成并审查规划器拥有的 `plugin-prerelease-extension-shard` 矩阵输出(来自 `.github/workflows/plugin-prerelease.yml`),确保发布说明不会描述过期的 CI 布局
|
||||
- 稳定 macOS 发布就绪性还包括更新器表面:
|
||||
- GitHub 发布最终必须包含已打包的 `.zip`、`.dmg` 和 `.dSYM.zip`
|
||||
- 发布后,`main` 上的 `appcast.xml` 必须指向新的稳定 zip
|
||||
- 打包应用必须保持非调试 bundle id、非空 Sparkle feed URL,以及大于等于该发布版本的规范 Sparkle 构建下限的 `CFBundleVersion`
|
||||
- 已打包应用必须保持非调试 bundle id、非空 Sparkle feed URL,以及等于或高于该发布版本规范 Sparkle 构建下限的 `CFBundleVersion`
|
||||
|
||||
## 发布测试箱
|
||||
## 发布测试盒
|
||||
|
||||
`Full Release Validation` 是操作员从单一入口点启动所有预发布测试的方式。对于快速移动分支上的固定提交证明,请使用该 helper,确保每个子工作流都从固定在目标 SHA 的临时分支运行:
|
||||
`Full Release Validation` 是操作员从一个入口启动所有预发布测试的方式。对于快速移动分支上的固定提交证明,使用该辅助工具,确保每个子工作流都从固定在目标 SHA 的临时分支运行:
|
||||
|
||||
```bash
|
||||
pnpm ci:full-release --sha <full-sha>
|
||||
```
|
||||
|
||||
该 helper 会推送 `release-ci/<sha>-...`,从该分支分派 `Full Release Validation` 并传入 `ref=<sha>`,验证每个子工作流 `headSha` 都匹配目标,然后删除临时分支。这样可以避免意外证明较新的 `main` 子运行。
|
||||
该辅助工具会推送 `release-ci/<sha>-...`,从该分支分发 `Full Release Validation` 并传入 `ref=<sha>`,验证每个子工作流的 `headSha` 都匹配目标,然后删除临时分支。这避免了意外证明较新的 `main` 子运行。
|
||||
|
||||
对于发布分支或标签验证,请从可信的 `main` 工作流引用运行,并将发布分支或标签作为 `ref` 传入:
|
||||
对于发布分支或标签验证,请从受信任的 `main` 工作流 ref 运行它,并将发布分支或标签作为 `ref` 传入:
|
||||
|
||||
```bash
|
||||
gh workflow run full-release-validation.yml \
|
||||
@ -164,18 +158,19 @@ gh workflow run full-release-validation.yml \
|
||||
-f evidence_package_spec=openclaw@YYYY.M.D-beta.N
|
||||
```
|
||||
|
||||
该工作流会解析目标 ref,派发带有 `target_ref=<release-ref>` 的手动 `CI`,派发 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 时或设置了 `npm_telegram_package_spec` 时派发独立软件包 Telegram E2E。随后,`OpenClaw Release Checks` 会扇出安装冒烟测试、跨 OS 发布检查、live/E2E Docker 发布路径覆盖、包含 Telegram 软件包 QA 的 Package Acceptance、QA Lab 对等性、live Matrix,以及 live Telegram。只有当 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 均成功时,完整运行才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则会跳过它。最终验证器摘要会包含每个子运行的最慢任务表,因此发布管理员无需下载日志即可看到当前关键路径。
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、确切的工作流任务名称、stable 与 full 配置文件差异、制品,以及聚焦重跑句柄。
|
||||
子工作流会从运行 `Full Release Validation` 的受信任 ref 派发,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签也是如此。没有单独的 Full Release Validation workflow-ref 输入;通过选择工作流运行 ref 来选择受信任的 harness。不要在移动中的 `main` 上使用 `--ref main -f ref=<sha>` 来证明精确提交;原始提交 SHA 不能作为工作流派发 ref,因此请使用 `pnpm ci:full-release --sha <sha>` 创建固定的临时分支。
|
||||
该工作流会解析目标 ref,使用 `target_ref=<release-ref>` 触发手动 `CI`,触发 `OpenClaw Release Checks`,并在 `release_profile=full` 且 `rerun_group=all` 时,或设置了 `npm_telegram_package_spec` 时,触发独立的 Telegram 包 E2E。随后 `OpenClaw Release Checks` 会扩展运行安装冒烟、跨 OS 发布检查、live/E2E Docker 发布路径覆盖、带 Telegram 包 QA 的 Package Acceptance、QA Lab parity、live Matrix 和 live Telegram。完整运行只有在 `Full Release Validation` 摘要显示 `normal_ci` 和 `release_checks` 成功时才可接受。在 full/all 模式下,`npm_telegram` 子项也必须成功;在 full/all 之外,除非提供了已发布的 `npm_telegram_package_spec`,否则会跳过它。最终验证器摘要会包含每个子运行的最慢作业表,因此发布经理无需下载日志即可看到当前关键路径。
|
||||
请参阅[完整发布验证](/zh-CN/reference/full-release-validation),了解完整阶段矩阵、精确工作流作业名称、stable 与 full 配置差异、产物以及聚焦重跑句柄。
|
||||
子工作流从运行 `Full Release Validation` 的受信任 ref 触发,通常是 `--ref main`,即使目标 `ref` 指向较旧的发布分支或标签也是如此。没有单独的完整发布验证 workflow-ref 输入;通过选择工作流运行 ref 来选择受信任的 harness。
|
||||
不要在移动的 `main` 上使用 `--ref main -f ref=<sha>` 来证明精确提交;原始提交 SHA 不能作为工作流 dispatch ref,因此请使用 `pnpm ci:full-release --sha <sha>` 创建固定的临时分支。
|
||||
|
||||
使用 `release_profile` 选择 live/提供商广度:
|
||||
使用 `release_profile` 选择 live/provider 覆盖范围:
|
||||
|
||||
- `minimum`:最快的发布关键 OpenAI/core live 和 Docker 路径
|
||||
- `stable`:minimum 加上用于发布批准的稳定提供商/后端覆盖
|
||||
- `full`:stable 加上广泛的 advisory 提供商/媒体覆盖
|
||||
|
||||
`OpenClaw Release Checks` 使用受信任工作流 ref 将目标 ref 一次性解析为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该制品。这样可以让所有面向软件包的环境都使用相同字节,并避免重复构建软件包。
|
||||
当设置了 repo/org 变量时,跨 OS OpenAI 安装冒烟测试使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为该 lane 证明的是软件包安装、新手引导、Gateway 网关启动,以及一次 live 智能体轮次,而不是对最慢默认模型进行基准测试。更广泛的 live 提供商矩阵仍然是模型特定覆盖的地方。
|
||||
`OpenClaw Release Checks` 使用受信任的工作流 ref 将目标 ref 解析一次为 `release-package-under-test`,并在发布路径 Docker 检查和 Package Acceptance 中复用该产物。这会让所有面向包的 box 使用相同字节,并避免重复构建包。
|
||||
当设置了 repo/org 变量时,跨 OS OpenAI 安装冒烟使用 `OPENCLAW_CROSS_OS_OPENAI_MODEL`,否则使用 `openai/gpt-5.4`,因为该 lane 证明的是包安装、新手引导、Gateway 网关启动,以及一次 live 智能体轮次,而不是基准测试最慢的默认模型。更广泛的 live 提供商矩阵仍然是模型特定覆盖的位置。
|
||||
|
||||
根据发布阶段使用这些变体:
|
||||
|
||||
@ -207,22 +202,23 @@ gh workflow run full-release-validation.yml \
|
||||
-f npm_telegram_provider_mode=mock-openai
|
||||
```
|
||||
|
||||
不要在聚焦修复后的第一次重跑中使用完整 umbrella。如果某个 box 失败,请使用失败的子工作流、任务、Docker lane、软件包配置文件、模型提供商或 QA lane 作为下一次证明。只有当修复更改了共享发布编排,或使较早的全部 box 证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查已记录的子工作流运行 ID,因此在子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父任务。
|
||||
不要把完整 umbrella 用作聚焦修复后的第一次重跑。如果一个 box 失败,请使用失败的子工作流、作业、Docker lane、包配置、模型提供商或 QA lane 作为下一次证明。只有当修复更改了共享发布编排,或让先前的全 box 证据过期时,才再次运行完整 umbrella。umbrella 的最终验证器会重新检查记录的子工作流运行 id,因此在子工作流成功重跑后,只需重跑失败的 `Verify full validation` 父作业。
|
||||
|
||||
对于有界恢复,请将 `rerun_group` 传给 umbrella。`all` 是真正的候选发布运行,`ci` 仅运行普通 CI 子项,`plugin-prerelease` 仅运行仅发布插件子项,`release-checks` 运行每个发布 box,较窄的发布组包括 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。聚焦 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;带有 `release_profile=full` 的 full/all 运行使用 release-checks 软件包制品。
|
||||
对于有界恢复,将 `rerun_group` 传给 umbrella。`all` 是真正的发布候选运行,`ci` 仅运行正常 CI 子项,`plugin-prerelease` 仅运行仅发布插件子项,`release-checks` 运行每个发布 box,更窄的发布组是 `install-smoke`、`cross-os`、`live-e2e`、`package`、`qa`、`qa-parity`、`qa-live` 和 `npm-telegram`。
|
||||
聚焦的 `npm-telegram` 重跑需要 `npm_telegram_package_spec`;带 `release_profile=full` 的 full/all 运行使用 release-checks 包产物。
|
||||
|
||||
### Vitest
|
||||
|
||||
Vitest box 是手动 `CI` 子工作流。手动 CI 会有意绕过变更范围限定,并强制对候选发布运行普通测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟测试、文档检查、Python Skills、Windows、macOS、Android,以及 Control UI i18n。
|
||||
Vitest box 是手动 `CI` 子工作流。手动 CI 会有意绕过 changed 作用域,并为发布候选强制运行正常测试图:Linux Node 分片、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Android 和 Control UI i18n。
|
||||
|
||||
使用这个 box 回答“源代码树是否通过了完整的普通测试套件?”它不同于发布路径产品验证。需要保留的证据:
|
||||
用这个 box 回答“源代码树是否通过了完整的正常测试套件?”它不同于发布路径产品验证。需要保留的证据:
|
||||
|
||||
- 显示已派发 `CI` 运行 URL 的 `Full Release Validation` 摘要
|
||||
- 精确目标 SHA 上绿色的 `CI` 运行
|
||||
- 调查回归时来自 CI 任务的失败或缓慢分片名称
|
||||
- 当运行需要性能分析时,保留 Vitest 计时制品,例如 `.artifacts/vitest-shard-timings.json`
|
||||
- `Full Release Validation` 摘要,显示触发的 `CI` 运行 URL
|
||||
- `CI` 在精确目标 SHA 上为绿色
|
||||
- 调查回归时来自 CI 作业的失败或慢速分片名称
|
||||
- 当运行需要性能分析时,Vitest 时间产物,例如 `.artifacts/vitest-shard-timings.json`
|
||||
|
||||
仅当发布需要确定性的普通 CI,但不需要 Docker、QA Lab、live、跨 OS 或软件包 box 时,才直接运行手动 CI:
|
||||
只有当发布需要确定性的正常 CI,但不需要 Docker、QA Lab、live、跨 OS 或包 box 时,才直接运行手动 CI:
|
||||
|
||||
```bash
|
||||
gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
|
||||
@ -230,51 +226,52 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D
|
||||
|
||||
### Docker
|
||||
|
||||
Docker box 位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml` 以及发布模式 `install-smoke` 工作流运行。它通过打包的 Docker 环境验证候选发布,而不只是源代码级测试。
|
||||
Docker box 位于 `OpenClaw Release Checks` 中,通过 `openclaw-live-and-e2e-checks-reusable.yml`,再加上发布模式的 `install-smoke` 工作流。它通过打包的 Docker 环境验证发布候选,而不是仅验证源码级测试。
|
||||
|
||||
发布 Docker 覆盖包括:
|
||||
|
||||
- 启用慢速 Bun 全局安装冒烟测试的完整安装冒烟测试
|
||||
- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,其中 QR、root/gateway 和 installer/Bun 冒烟任务作为单独 install-smoke 分片运行
|
||||
- 仓库 E2E lane
|
||||
- 发布路径 Docker 分块:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g` 和 `plugins-runtime-install-h`
|
||||
- 请求时,`plugins-runtime-services` 分块中的 OpenWebUI 覆盖
|
||||
- 拆分的内置插件安装/卸载 lane:从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23`
|
||||
- 当发布检查包含 live 套件时,包含 live/E2E 提供商套件和 Docker live 模型覆盖
|
||||
- 启用慢速 Bun 全局安装冒烟的完整安装冒烟
|
||||
- 按目标 SHA 准备/复用根 Dockerfile 冒烟镜像,QR、root/gateway 和 installer/Bun 冒烟作业作为单独的 install-smoke 分片运行
|
||||
- 仓库 E2E lanes
|
||||
- 发布路径 Docker chunks:`core`、`package-update-openai`、`package-update-anthropic`、`package-update-core`、`plugins-runtime-plugins`、`plugins-runtime-services`、`plugins-runtime-install-a`、`plugins-runtime-install-b`、`plugins-runtime-install-c`、`plugins-runtime-install-d`、`plugins-runtime-install-e`、`plugins-runtime-install-f`、`plugins-runtime-install-g` 和 `plugins-runtime-install-h`
|
||||
- 请求时在 `plugins-runtime-services` chunk 内的 OpenWebUI 覆盖
|
||||
- 拆分的内置插件安装/卸载 lanes,从 `bundled-plugin-install-uninstall-0` 到 `bundled-plugin-install-uninstall-23`
|
||||
- 当发布检查包含 live 套件时,live/E2E 提供商套件和 Docker live 模型覆盖
|
||||
|
||||
重跑前先使用 Docker 制品。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段计时、调度器计划 JSON,以及重跑命令。对于聚焦恢复,请在可复用 live/E2E 工作流上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布分块。生成的重跑命令会在可用时包含先前的 `package_artifact_run_id` 和已准备 Docker 镜像输入,因此失败的 lane 可以复用同一 tarball 和 GHCR 镜像。
|
||||
重跑前先使用 Docker 产物。发布路径调度器会上传 `.artifacts/docker-tests/`,其中包含 lane 日志、`summary.json`、`failures.json`、阶段耗时、调度器计划 JSON 和重跑命令。对于聚焦恢复,在可复用 live/E2E 工作流上使用 `docker_lanes=<lane[,lane]>`,而不是重跑所有发布 chunks。生成的重跑命令会在可用时包含先前的 `package_artifact_run_id` 和已准备的 Docker 镜像输入,因此失败的 lane 可以复用同一个 tarball 和 GHCR 镜像。
|
||||
|
||||
### QA Lab
|
||||
|
||||
QA Lab box 也是 `OpenClaw Release Checks` 的一部分。它是 agentic 行为和渠道级发布门禁,独立于 Vitest 和 Docker 软件包机制。
|
||||
QA Lab box 也是 `OpenClaw Release Checks` 的一部分。它是智能体行为和渠道级发布门禁,独立于 Vitest 和 Docker 包机制。
|
||||
|
||||
发布 QA Lab 覆盖包括:
|
||||
|
||||
- 使用 agentic 对等性包,将 OpenAI 候选 lane 与 Opus 4.6 基线进行比较的模拟对等性门禁
|
||||
- 使用 `qa-live-shared` 环境的快速 live Matrix QA 配置文件
|
||||
- 使用 Convex CI 凭据租约的 live Telegram QA lane
|
||||
- 当发布遥测需要明确本地证明时运行 `pnpm qa:otel:smoke`
|
||||
- 使用 agentic parity pack 将 OpenAI 候选 lane 与 Opus 4.6 baseline 对比的 mock parity gate
|
||||
- 使用 `qa-live-shared` 环境的快速 live Matrix QA 配置
|
||||
- 使用 Convex CI 凭证租约的 live Telegram QA lane
|
||||
- 当发布 telemetry 需要明确本地证明时运行 `pnpm qa:otel:smoke`
|
||||
|
||||
使用这个 box 回答“发布在 QA 场景和 live 渠道流程中的行为是否正确?”批准发布时,请保留对等性、Matrix 和 Telegram lane 的制品 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行使用,而不是默认的发布关键 lane。
|
||||
用这个 box 回答“该发布在 QA 场景和 live 渠道流程中行为是否正确?”批准发布时请保留 parity、Matrix 和 Telegram lanes 的产物 URL。完整 Matrix 覆盖仍可作为手动分片 QA-Lab 运行,而不是默认发布关键 lane。
|
||||
|
||||
### Package
|
||||
|
||||
Package box 是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支持。该解析器会将候选项规范化为供 Docker E2E 使用的 `package-under-test` tarball,验证软件包清单,记录软件包版本和 SHA-256,并将工作流 harness ref 与软件包源 ref 分离。
|
||||
Package box 是可安装产品门禁。它由 `Package Acceptance` 和解析器 `scripts/resolve-openclaw-package-candidate.mjs` 支撑。解析器会将候选规范化为 Docker E2E 使用的 `package-under-test` tarball,验证包清单,记录包版本和 SHA-256,并让工作流 harness ref 与包源码 ref 分离。
|
||||
|
||||
支持的候选来源:
|
||||
|
||||
- `source=npm`:`openclaw@beta`、`openclaw@latest`,或精确的 OpenClaw 发布版本
|
||||
- `source=ref`:使用所选 `workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA
|
||||
- `source=npm`:`openclaw@beta`、`openclaw@latest` 或精确的 OpenClaw 发布版本
|
||||
- `source=ref`:使用选定的 `workflow_ref` harness 打包受信任的 `package_ref` 分支、标签或完整提交 SHA
|
||||
- `source=url`:下载需要 `package_sha256` 的 HTTPS `.tgz`
|
||||
- `source=artifact`:复用另一个 GitHub Actions 运行上传的 `.tgz`
|
||||
|
||||
`OpenClaw Release Checks` 会使用 `source=artifact`、已准备的发布软件包制品、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=release-history`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会针对同一已解析 tarball 保持迁移、更新、过期插件依赖清理、离线插件 fixtures、插件更新,以及 Telegram 软件包 QA。它是大多数先前需要 Parallels 的软件包/更新覆盖的 GitHub 原生替代方案。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但软件包/更新产品验证应优先使用 Package Acceptance。
|
||||
`OpenClaw Release Checks` 使用 `source=artifact`、已准备的发布包产物、`suite_profile=custom`、`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor plugins-offline plugin-update`、`published_upgrade_survivor_baselines=all-since-2026.4.23`、`published_upgrade_survivor_scenarios=reported-issues` 和 `telegram_mode=mock-openai` 运行 Package Acceptance。Package Acceptance 会针对同一个已解析的 tarball 保持迁移、更新、陈旧插件依赖清理、离线插件 fixtures、插件更新和 Telegram 包 QA。升级矩阵覆盖从 `2026.4.23` 到 `latest` 的每个已由 npm 发布的稳定 baseline;对于已发货的候选,请使用带 `source=npm` 的 Package Acceptance;对于发布前有 SHA 支撑的本地 npm tarball,请使用 `source=ref`/`source=artifact`。它是大多数过去需要 Parallels 的包/更新覆盖的 GitHub 原生替代方案。跨 OS 发布检查对于 OS 特定的新手引导、安装器和平台行为仍然重要,但包/更新产品验证应优先使用 Package Acceptance。
|
||||
|
||||
更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。当决定哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布软件包迁移变更时,请使用它。从每个稳定 `2026.4.23+` 软件包进行的穷尽式已发布更新迁移是单独的手动 `Update Migration` 工作流,不属于 Full Release CI。
|
||||
更新和插件验证的规范清单是[更新和插件测试](/zh-CN/help/testing-updates-plugins)。在判断哪个本地、Docker、Package Acceptance 或 release-check lane 能证明插件安装/更新、Doctor 清理或已发布包迁移变更时,请使用它。
|
||||
从每个稳定 `2026.4.23+` 包进行穷尽的已发布更新迁移,是单独的手动 `Update Migration` 工作流,不属于完整发布 CI。
|
||||
|
||||
旧版 package-acceptance 宽容性会有意设置时间边界。直到 `2026.4.25` 的软件包可以对已发布到 npm 的元数据缺口使用兼容路径:tarball 中缺少私有 QA 清单条目,缺少 `gateway install --wrapper`,tarball 派生 git fixture 中缺少补丁文件,缺少持久化的 `update.channel`,旧版插件安装记录位置,缺少 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 软件包可能会对已随包发布的本地构建元数据戳文件发出警告。后续软件包必须满足现代软件包契约;这些相同缺口会导致发布验证失败。
|
||||
旧版 package-acceptance 宽容性是有意限时的。直到 `2026.4.25` 的包可以对已经发布到 npm 的元数据缺口使用兼容路径:tarball 中缺失的私有 QA 清单条目、缺失的 `gateway install --wrapper`、tarball 派生 git fixture 中缺失的补丁文件、缺失的持久化 `update.channel`、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及 `plugins update` 期间的配置元数据迁移。已发布的 `2026.4.26` 包可以对已经发货的本地构建元数据 stamp 文件发出警告。后续包必须满足现代包契约;这些相同缺口会导致发布验证失败。
|
||||
|
||||
当发布问题与实际可安装软件包有关时,请使用更广泛的 Package Acceptance 配置文件:
|
||||
当发布问题涉及实际可安装包时,使用更广的 Package Acceptance 配置:
|
||||
|
||||
```bash
|
||||
gh workflow run package-acceptance.yml \
|
||||
@ -286,29 +283,31 @@ gh workflow run package-acceptance.yml \
|
||||
-f published_upgrade_survivor_baseline=openclaw@2026.4.26
|
||||
```
|
||||
|
||||
常见软件包配置文件:
|
||||
常用包配置:
|
||||
|
||||
- `smoke`:快速软件包安装/渠道/智能体、Gateway 网关网络和配置热重载 lane
|
||||
- `package`:不含 live ClawHub 的安装/更新/插件软件包契约;这是 release-check 默认值
|
||||
- `product`:`package` 加上 MCP 渠道、cron/subagent 清理、OpenAI web 搜索和 OpenWebUI
|
||||
- `full`:包含 OpenWebUI 的 Docker 发布路径分块
|
||||
- `smoke`:快速包安装/渠道/智能体、Gateway 网关网络和配置重载 lanes
|
||||
- `package`:不带 live ClawHub 的安装/更新/插件包契约;这是 release-check 默认值
|
||||
- `product`:`package` 加上 MCP 渠道、cron/subagent 清理、OpenAI Web 搜索和 OpenWebUI
|
||||
- `full`:带 OpenWebUI 的 Docker 发布路径 chunks
|
||||
- `custom`:用于聚焦重跑的精确 `docker_lanes` 列表
|
||||
|
||||
对于 package-candidate Telegram 验证,请在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或
|
||||
对于候选包的 Telegram 验证,请在 Package Acceptance 上启用 `telegram_mode=mock-openai` 或
|
||||
`telegram_mode=live-frontier`。该工作流会将解析后的
|
||||
`package-under-test` tarball 传入 Telegram 通道;独立的
|
||||
Telegram 工作流仍接受已发布的 npm spec,用于发布后检查。
|
||||
Telegram 工作流仍接受已发布的 npm 规范,用于发布后检查。
|
||||
|
||||
## 发布自动化
|
||||
## 发布发布自动化
|
||||
|
||||
`OpenClaw Release Publish` 是常规的变更型发布入口点。它会按照发布所需顺序编排 trusted-publisher 工作流:
|
||||
`OpenClaw Release Publish` 是常规的变更型发布入口点。它会按发布所需的顺序编排可信发布者工作流:
|
||||
|
||||
1. 签出发布标签并解析其提交 SHA。
|
||||
1. 检出发布标签并解析其提交 SHA。
|
||||
2. 验证该标签可从 `main` 或 `release/*` 访问。
|
||||
3. 运行 `pnpm plugins:sync:check`。
|
||||
4. 使用 `publish_scope=all-publishable` 和 `ref=<release-sha>` 调度 `Plugin NPM Release`。
|
||||
4. 调度 `Plugin NPM Release`,并使用 `publish_scope=all-publishable` 和
|
||||
`ref=<release-sha>`。
|
||||
5. 使用相同的范围和 SHA 调度 `Plugin ClawHub Release`。
|
||||
6. 使用发布标签、npm dist-tag 和已保存的 `preflight_run_id` 调度 `OpenClaw NPM Release`。
|
||||
6. 使用发布标签、npm dist-tag 和已保存的 `preflight_run_id` 调度
|
||||
`OpenClaw NPM Release`。
|
||||
|
||||
Beta 发布示例:
|
||||
|
||||
@ -330,7 +329,7 @@ gh workflow run openclaw-release-publish.yml \
|
||||
-f npm_dist_tag=alpha
|
||||
```
|
||||
|
||||
稳定版发布到默认 beta dist-tag:
|
||||
将稳定版发布到默认的 beta dist-tag:
|
||||
|
||||
```bash
|
||||
gh workflow run openclaw-release-publish.yml \
|
||||
@ -340,7 +339,7 @@ gh workflow run openclaw-release-publish.yml \
|
||||
-f npm_dist_tag=beta
|
||||
```
|
||||
|
||||
直接将稳定版提升到 `latest` 需要显式指定:
|
||||
直接将稳定版提升到 `latest` 是显式操作:
|
||||
|
||||
```bash
|
||||
gh workflow run openclaw-release-publish.yml \
|
||||
@ -350,64 +349,66 @@ gh workflow run openclaw-release-publish.yml \
|
||||
-f npm_dist_tag=latest
|
||||
```
|
||||
|
||||
只有在进行聚焦修复或重新发布工作时,才使用较低层级的 `Plugin NPM Release` 和 `Plugin ClawHub Release` 工作流。对于选定的插件修复,请将
|
||||
`plugin_publish_scope=selected` 和 `plugins=@openclaw/name` 传给
|
||||
`OpenClaw Release Publish`,或者在 OpenClaw 包不得发布时直接调度子工作流。
|
||||
仅在聚焦修复或重新发布工作中使用较低层级的 `Plugin NPM Release` 和 `Plugin ClawHub Release` 工作流。对于选定的插件修复,请向
|
||||
`OpenClaw Release Publish` 传入 `plugin_publish_scope=selected` 和
|
||||
`plugins=@openclaw/name`;或者在不得发布 OpenClaw 包时,直接调度子工作流。
|
||||
|
||||
## NPM 工作流输入
|
||||
|
||||
`OpenClaw NPM Release` 接受以下由操作员控制的输入:
|
||||
`OpenClaw NPM Release` 接受这些由操作员控制的输入:
|
||||
|
||||
- `tag`:必填的发布标签,例如 `v2026.4.2`、`v2026.4.2-1`,或
|
||||
`v2026.4.2-alpha.1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,也可以是当前完整的 40 字符工作流分支提交 SHA,用于仅验证的预检
|
||||
- `tag`:必需的发布标签,例如 `v2026.4.2`、`v2026.4.2-1`,或
|
||||
`v2026.4.2-alpha.1` 或 `v2026.4.2-beta.1`;当 `preflight_only=true` 时,它也可以是当前完整的 40 字符工作流分支提交 SHA,用于仅验证的预检
|
||||
- `preflight_only`:`true` 表示仅验证/构建/打包,`false` 表示真实发布路径
|
||||
- `preflight_run_id`:真实发布路径必填,这样工作流会复用成功预检运行中准备好的 tarball
|
||||
- `npm_dist_tag`:发布路径的 npm 目标标签;默认值为 `beta`
|
||||
- `preflight_run_id`:真实发布路径必需,这样工作流会复用成功预检运行准备好的 tarball
|
||||
- `npm_dist_tag`:发布路径的 npm 目标标签;默认为 `beta`
|
||||
|
||||
`OpenClaw Release Publish` 接受以下由操作员控制的输入:
|
||||
`OpenClaw Release Publish` 接受这些由操作员控制的输入:
|
||||
|
||||
- `tag`:必填的发布标签;必须已经存在
|
||||
- `preflight_run_id`:成功的 `OpenClaw NPM Release` 预检运行 ID;
|
||||
当 `publish_openclaw_npm=true` 时必填
|
||||
- `tag`:必需的发布标签;必须已存在
|
||||
- `preflight_run_id`:成功的 `OpenClaw NPM Release` 预检运行 id;
|
||||
当 `publish_openclaw_npm=true` 时必需
|
||||
- `npm_dist_tag`:OpenClaw 包的 npm 目标标签
|
||||
- `plugin_publish_scope`:默认值为 `all-publishable`;仅在聚焦修复工作中使用 `selected`
|
||||
- `plugins`:当 `plugin_publish_scope=selected` 时,为逗号分隔的 `@openclaw/*` 包名
|
||||
- `publish_openclaw_npm`:默认值为 `true`;仅在将该工作流用作仅插件修复编排器时设为 `false`
|
||||
- `plugin_publish_scope`:默认为 `all-publishable`;仅在聚焦修复工作中使用 `selected`
|
||||
- `plugins`:当 `plugin_publish_scope=selected` 时,以逗号分隔的 `@openclaw/*` 包名
|
||||
- `publish_openclaw_npm`:默认为 `true`;仅在将该工作流用作仅插件修复编排器时设置为 `false`
|
||||
|
||||
`OpenClaw Release Checks` 接受以下由操作员控制的输入:
|
||||
`OpenClaw Release Checks` 接受这些由操作员控制的输入:
|
||||
|
||||
- `ref`:要验证的分支、标签或完整提交 SHA。带有 secret 的检查要求解析后的提交可从 OpenClaw 分支或发布标签访问。
|
||||
- `ref`:要验证的分支、标签或完整提交 SHA。带密钥的检查要求解析后的提交可从 OpenClaw 分支或发布标签访问。
|
||||
|
||||
规则:
|
||||
|
||||
- 稳定版和修正版标签可以发布到 `beta` 或 `latest`
|
||||
- Alpha 预发布标签只能发布到 `alpha`
|
||||
- Beta 预发布标签只能发布到 `beta`
|
||||
- 对于 `OpenClaw NPM Release`,只有当 `preflight_only=true` 时才允许输入完整提交 SHA
|
||||
- 对于 `OpenClaw NPM Release`,仅当 `preflight_only=true` 时才允许完整提交 SHA 输入
|
||||
- `OpenClaw Release Checks` 和 `Full Release Validation` 始终仅用于验证
|
||||
- 真实发布路径必须使用与预检期间相同的 `npm_dist_tag`;工作流会在发布继续前验证该元数据
|
||||
- 真实发布路径必须使用预检期间使用的同一个 `npm_dist_tag`;
|
||||
工作流会在发布继续前验证该元数据
|
||||
|
||||
## 稳定版 npm 发布流程
|
||||
## 稳定 npm 发布序列
|
||||
|
||||
切稳定版 npm 发布时:
|
||||
切稳定 npm 发布时:
|
||||
|
||||
1. 运行带有 `preflight_only=true` 的 `OpenClaw NPM Release`
|
||||
- 在标签存在之前,你可以使用当前完整的工作流分支提交 SHA,对预检工作流执行仅验证的 dry run
|
||||
2. 为常规 beta 优先流程选择 `npm_dist_tag=beta`,或者仅在你有意直接发布稳定版时选择 `latest`
|
||||
3. 当你希望通过一个手动工作流获得常规 CI 加上实时 prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation`
|
||||
1. 使用 `preflight_only=true` 运行 `OpenClaw NPM Release`
|
||||
- 在标签存在之前,你可以使用当前完整的工作流分支提交 SHA,对预检工作流执行仅验证的演练
|
||||
2. 对于常规的 beta 优先流程,选择 `npm_dist_tag=beta`;仅当你有意直接发布稳定版时才选择 `latest`
|
||||
3. 当你希望通过一个手动工作流获得常规 CI 以及实时 prompt cache、Docker、QA Lab、Matrix 和 Telegram 覆盖时,在发布分支、发布标签或完整提交 SHA 上运行 `Full Release Validation`
|
||||
4. 如果你有意只需要确定性的常规测试图,请改为在发布 ref 上运行手动 `CI` 工作流
|
||||
5. 保存成功的 `preflight_run_id`
|
||||
6. 使用相同的 `tag`、相同的 `npm_dist_tag` 和已保存的 `preflight_run_id` 运行 `OpenClaw Release Publish`;它会先将外部化插件发布到 npm 和 ClawHub,再提升 OpenClaw npm 包
|
||||
7. 如果发布落在 `beta`,请使用私有的
|
||||
7. 如果发布落在 `beta` 上,请使用私有
|
||||
`openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`
|
||||
工作流,将该稳定版本从 `beta` 提升到 `latest`
|
||||
8. 如果发布有意直接发布到 `latest`,并且 `beta` 应立即跟随同一个稳定构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或者让其定时自愈同步稍后移动 `beta`
|
||||
工作流将该稳定版本从 `beta` 提升到 `latest`
|
||||
8. 如果发布有意直接发布到 `latest`,并且 `beta`
|
||||
应立即跟随同一个稳定构建,请使用同一个私有工作流将两个 dist-tag 都指向该稳定版本,或让其定时自愈同步稍后移动 `beta`
|
||||
|
||||
出于安全原因,dist-tag 变更位于私有仓库中,因为它仍然需要 `NPM_TOKEN`,而公共仓库保持仅使用 OIDC 发布。
|
||||
出于安全考虑,dist-tag 变更位于私有仓库中,因为它仍需要 `NPM_TOKEN`,而公共仓库保持仅使用 OIDC 发布。
|
||||
|
||||
这样可以让直接发布路径和 beta 优先提升路径都被记录,并对操作员可见。
|
||||
这让直接发布路径和 beta 优先提升路径都保持有文档记录,并且对操作员可见。
|
||||
|
||||
如果维护者必须回退到本地 npm 身份验证,请仅在专用 tmux 会话中运行任何 1Password CLI(`op`)命令。不要从主智能体 shell 直接调用 `op`;将其保留在 tmux 中,可以让提示、警报和 OTP 处理可观察,并防止重复的主机警报。
|
||||
如果维护者必须回退到本地 npm 身份验证,请仅在专用 tmux 会话内运行任何 1Password CLI(`op`)命令。不要直接从主 agent shell 调用 `op`;将其限制在 tmux 内可以让提示、警报和 OTP 处理可观察,并防止反复触发主机警报。
|
||||
|
||||
## 公共参考
|
||||
|
||||
@ -423,7 +424,7 @@ gh workflow run openclaw-release-publish.yml \
|
||||
|
||||
维护者使用
|
||||
[`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)
|
||||
中的私有发布文档作为实际 runbook。
|
||||
中的私有发布文档作为实际运行手册。
|
||||
|
||||
## 相关
|
||||
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行或重新运行完整发布验证
|
||||
- 比较稳定版和完整版发布验证配置文件
|
||||
- 比较稳定版和完整发布验证配置
|
||||
- 调试发布验证阶段失败
|
||||
summary: 完整发布验证的阶段、子工作流、发布配置文件、重新运行句柄和证据
|
||||
summary: 完整发布验证阶段、子工作流、发布配置、重新运行句柄和证据
|
||||
title: 完整发布验证
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T23:10:04Z"
|
||||
generated_at: "2026-05-02T18:56:29Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: feb4edec850fb97405575c869547b4851bc773507321690670553e6faafc8b0b
|
||||
source_hash: 3ce1e5a72227ca202335fe68b537491a0b68a0bb2af431aa56c41cf20989e88c
|
||||
source_path: reference/full-release-validation.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
`Full Release Validation` 是发布验证总控。它是预发布证明的单一手动入口点,但大部分工作发生在子工作流中,因此失败的执行环境可以重新运行,而不必重启整个发布流程。
|
||||
`Full Release Validation` 是发布总控流程。它是预发布验证的唯一手动入口点,但大多数工作都在子工作流中完成,因此失败的运行单元可以重跑,而无需重新启动整个发布流程。
|
||||
|
||||
从受信任的工作流 ref 运行它,通常是 `main`,并将发布分支、标签或完整提交 SHA 作为 `ref` 传入:
|
||||
|
||||
@ -27,102 +27,107 @@ gh workflow run full-release-validation.yml \
|
||||
-f release_profile=stable
|
||||
```
|
||||
|
||||
子工作流使用受信任的工作流 ref 作为 harness,并使用输入
|
||||
`ref` 作为被测候选版本。这样在验证较旧的发布分支或标签时,也能使用新的验证逻辑。
|
||||
子工作流使用受信任的工作流 ref 作为 harness,并使用输入 `ref` 作为待测候选版本。这样,在验证较旧的发布分支或标签时,新的验证逻辑仍然可用。
|
||||
|
||||
Package Acceptance 通常会从解析后的 `ref` 构建候选 tarball,包括通过 `pnpm ci:full-release` 分发的完整 SHA 运行。发布后,传入 `package_acceptance_package_spec=openclaw@YYYY.M.D`(或 `openclaw@beta`/`openclaw@latest`),改为针对已发布的 npm 包运行相同的包/更新矩阵。
|
||||
|
||||
## 顶层阶段
|
||||
|
||||
| 阶段 | 详情 |
|
||||
| 阶段 | 详情 |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 目标解析 | **作业:** `Resolve target ref`<br />**子工作流:** 无<br />**验证:** 解析发布分支、标签或完整提交 SHA,并记录选定的输入。<br />**重新运行:** 如果这里失败,重新运行总控工作流。 |
|
||||
| Vitest 和普通 CI | **作业:** `Run normal full CI`<br />**子工作流:** `CI`<br />**验证:** 针对目标 ref 的手动完整 CI 图,包括 Linux Node 通道、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Control UI i18n,以及通过总控工作流运行的 Android。<br />**重新运行:** `rerun_group=ci`。 |
|
||||
| 插件预发布 | **作业:** `Run plugin prerelease validation`<br />**子工作流:** `Plugin Prerelease`<br />**验证:** 仅发布使用的插件静态检查、智能体式插件覆盖、完整插件批次分片,以及插件预发布 Docker 通道。<br />**重新运行:** `rerun_group=plugin-prerelease`。 |
|
||||
| 发布检查 | **作业:** `Run release/live/Docker/QA validation`<br />**子工作流:** `OpenClaw Release Checks`<br />**验证:** 安装冒烟、跨 OS 包检查、live/E2E 套件、Docker 发布路径分块、Package Acceptance、QA Lab 对等性、live Matrix 和 live Telegram。<br />**重新运行:** `rerun_group=release-checks` 或更窄的 release-checks 句柄。 |
|
||||
| Telegram 包 | **作业:** `Run package Telegram E2E`<br />**子工作流:** `NPM Telegram Beta E2E`<br />**验证:** 当 `rerun_group=all` 且 `release_profile=full` 时,进行基于构件的 Telegram 包证明;或当设置了 `npm_telegram_package_spec` 时,进行已发布包的 Telegram 证明。<br />**重新运行:** 使用 `npm_telegram_package_spec` 的 `rerun_group=npm-telegram`。 |
|
||||
| 总控验证器 | **作业:** `Verify full validation`<br />**子工作流:** 无<br />**验证:** 重新检查已记录的子运行结论,并从子工作流附加最慢作业表。<br />**重新运行:** 在重新运行失败的子工作流并变绿后,只重新运行此作业。 |
|
||||
| 目标解析 | **Job:** `Resolve target ref`<br />**子工作流:** 无<br />**证明内容:** 解析发布分支、标签或完整提交 SHA,并记录选定输入。<br />**重跑:** 如果此项失败,重跑总控流程。 |
|
||||
| Vitest 和常规 CI | **Job:** `Run normal full CI`<br />**子工作流:** `CI`<br />**证明内容:** 针对目标 ref 的手动完整 CI 图,包括 Linux Node lanes、内置插件分片、渠道契约、Node 22 兼容性、`check`、`check-additional`、构建冒烟、文档检查、Python Skills、Windows、macOS、Control UI i18n,以及通过总控流程运行的 Android。<br />**重跑:** `rerun_group=ci`。 |
|
||||
| 插件预发布 | **Job:** `Run plugin prerelease validation`<br />**子工作流:** `Plugin Prerelease`<br />**证明内容:** 仅发布时运行的插件静态检查、agentic 插件覆盖率、完整插件批量分片,以及插件预发布 Docker lanes。<br />**重跑:** `rerun_group=plugin-prerelease`。 |
|
||||
| 发布检查 | **Job:** `Run release/live/Docker/QA validation`<br />**子工作流:** `OpenClaw Release Checks`<br />**证明内容:** 安装冒烟、跨操作系统包检查、live/E2E 套件、Docker 发布路径分块、Package Acceptance、QA Lab parity、live Matrix,以及 live Telegram。<br />**重跑:** `rerun_group=release-checks` 或更窄的 release-checks 句柄。 |
|
||||
| Package Telegram | **Job:** `Run package Telegram E2E`<br />**子工作流:** `NPM Telegram Beta E2E`<br />**证明内容:** 在 `rerun_group=all` 且 `release_profile=full` 时提供基于工件的 Telegram 包验证;或在设置 `npm_telegram_package_spec` 时提供已发布包的 Telegram 验证。<br />**重跑:** 使用 `npm_telegram_package_spec` 的 `rerun_group=npm-telegram`。 |
|
||||
| 总控验证器 | **Job:** `Verify full validation`<br />**子工作流:** 无<br />**证明内容:** 重新检查已记录的子运行结论,并附加来自子工作流的最慢 Job 表格。<br />**重跑:** 在重跑失败子项并转绿后,仅重跑此 Job。 |
|
||||
|
||||
对于 `ref=main` 和 `rerun_group=all`,较新的总控工作流会取代较旧的总控工作流。当父工作流被取消时,它的监视器会取消已分派的所有子工作流。发布分支和标签验证运行默认不会相互取消。
|
||||
对于 `ref=main` 和 `rerun_group=all`,较新的总控流程会取代较旧的总控流程。当父级被取消时,它的监控器会取消任何已经分发的子工作流。默认情况下,发布分支和标签验证运行不会互相取消。
|
||||
|
||||
## 发布检查阶段
|
||||
|
||||
`OpenClaw Release Checks` 是最大的子工作流。它会解析一次目标,并在面向包或 Docker 的阶段需要时,准备共享的 `release-package-under-test` 构件。
|
||||
`OpenClaw Release Checks` 是最大的子工作流。它只解析一次目标,并在面向包或 Docker 的阶段需要时准备共享的 `release-package-under-test` 工件。
|
||||
|
||||
| 阶段 | 详情 |
|
||||
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 发布目标 | **作业:** `Resolve target ref`<br />**支撑工作流:** 无<br />**测试:** 选定 ref、可选的预期 SHA、profile、rerun group,以及聚焦的 live 套件过滤器。<br />**重新运行:** `rerun_group=release-checks`。 |
|
||||
| 包构件 | **作业:** `Prepare release package artifact`<br />**支撑工作流:** 无<br />**测试:** 打包或解析一个候选 tarball,并上传 `release-package-under-test`,供下游面向包的检查使用。<br />**重新运行:** 受影响的包、跨 OS 或 live/E2E 组。 |
|
||||
| 安装冒烟 | **作业:** `Run install smoke`<br />**支撑工作流:** `Install Smoke`<br />**测试:** 完整安装路径,包括根 Dockerfile 冒烟镜像复用、QR 包安装、根和 Gateway 网关 Docker 冒烟、安装器 Docker 测试、Bun 全局安装 image-provider 冒烟,以及快速内置插件安装/卸载 E2E。<br />**重新运行:** `rerun_group=install-smoke`。 |
|
||||
| 跨 OS | **作业:** `cross_os_release_checks`<br />**支撑工作流:** `OpenClaw Cross-OS Release Checks (Reusable)`<br />**测试:** 在 Linux、Windows 和 macOS 上针对选定提供商和模式运行全新安装与升级通道,使用候选 tarball 加基线包。<br />**重新运行:** `rerun_group=cross-os`。 |
|
||||
| 仓库和 live E2E | **作业:** `Run repo/live E2E validation`<br />**支撑工作流:** `OpenClaw Live And E2E Checks (Reusable)`<br />**测试:** 仓库 E2E、live 缓存、OpenAI websocket 流式传输、原生 live 提供商和插件分片,以及由 `release_profile` 选择的 Docker 支撑 live 模型/后端/Gateway 网关 harness。<br />**重新运行:** `rerun_group=live-e2e`,可选搭配 `live_suite_filter`。 |
|
||||
| Docker 发布路径 | **作业:** `Run Docker release-path validation`<br />**支撑工作流:** `OpenClaw Live And E2E Checks (Reusable)`<br />**测试:** 针对共享包构件的发布路径 Docker 分块。<br />**重新运行:** `rerun_group=live-e2e`。 |
|
||||
| Package Acceptance | **作业:** `Run package acceptance`<br />**支撑工作流:** `Package Acceptance`<br />**测试:** 离线插件包夹具、插件更新,以及针对同一 tarball 的模拟 OpenAI Telegram 包验收。<br />**重新运行:** `rerun_group=package`。 |
|
||||
| QA 对等性 | **作业:** `Run QA Lab parity lane` 和 `Run QA Lab parity report`<br />**支撑工作流:** 直接作业<br />**测试:** 候选版本和基线的智能体式对等包,然后生成对等性报告。<br />**重新运行:** `rerun_group=qa-parity` 或 `rerun_group=qa`。 |
|
||||
| QA live Matrix | **作业:** `Run QA Lab live Matrix lane`<br />**支撑工作流:** 直接作业<br />**测试:** `qa-live-shared` 环境中的快速 live Matrix QA profile。<br />**重新运行:** `rerun_group=qa-live` 或 `rerun_group=qa`。 |
|
||||
| QA live Telegram | **作业:** `Run QA Lab live Telegram lane`<br />**支撑工作流:** 直接作业<br />**测试:** 使用 Convex CI 凭证租约的 live Telegram QA。<br />**重新运行:** `rerun_group=qa-live` 或 `rerun_group=qa`。 |
|
||||
| 发布验证器 | **作业:** `Verify release checks`<br />**支撑工作流:** 无<br />**测试:** 选定 rerun group 所需的 release-check 作业。<br />**重新运行:** 在聚焦的子作业通过后重新运行。 |
|
||||
| 阶段 | 详情 |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 发布目标 | **Job:** `Resolve target ref`<br />**底层工作流:** 无<br />**测试内容:** 选定的 ref、可选的预期 SHA、profile、重跑组,以及聚焦的 live 套件过滤器。<br />**重跑:** `rerun_group=release-checks`。 |
|
||||
| 包工件 | **Job:** `Prepare release package artifact`<br />**底层工作流:** 无<br />**测试内容:** 打包或解析一个候选 tarball,并上传 `release-package-under-test`,供下游面向包的检查使用。<br />**重跑:** 受影响的包、跨操作系统或 live/E2E 组。 |
|
||||
| 安装冒烟 | **Job:** `Run install smoke`<br />**底层工作流:** `Install Smoke`<br />**测试内容:** 完整安装路径,复用根 Dockerfile 冒烟镜像、QR 包安装、根和 Gateway 网关 Docker 冒烟、安装器 Docker 测试、Bun 全局安装 image-provider 冒烟,以及快速内置插件安装/卸载 E2E。<br />**重跑:** `rerun_group=install-smoke`。 |
|
||||
| 跨操作系统 | **Job:** `cross_os_release_checks`<br />**底层工作流:** `OpenClaw Cross-OS Release Checks (Reusable)`<br />**测试内容:** 针对选定提供商和模式,在 Linux、Windows 和 macOS 上运行全新安装与升级 lanes,使用候选 tarball 加基线包。<br />**重跑:** `rerun_group=cross-os`。 |
|
||||
| 仓库和 live E2E | **Job:** `Run repo/live E2E validation`<br />**底层工作流:** `OpenClaw Live And E2E Checks (Reusable)`<br />**测试内容:** 仓库 E2E、live cache、OpenAI websocket streaming、原生 live 提供商和插件分片,以及由 `release_profile` 选择的 Docker 支持的 live 模型/backend/gateway harnesses。<br />**重跑:** `rerun_group=live-e2e`,可选附带 `live_suite_filter`。 |
|
||||
| Docker 发布路径 | **Job:** `Run Docker release-path validation`<br />**底层工作流:** `OpenClaw Live And E2E Checks (Reusable)`<br />**测试内容:** 针对共享包工件运行 release-path Docker 分块。<br />**重跑:** `rerun_group=live-e2e`。 |
|
||||
| Package Acceptance | **Job:** `Run package acceptance`<br />**底层工作流:** `Package Acceptance`<br />**测试内容:** 离线插件包 fixtures、插件更新、mock-OpenAI Telegram 包验收,以及从 `2026.4.23` 或之后的每个稳定 npm 发布版本到同一 tarball 的已发布升级幸存检查。<br />**重跑:** `rerun_group=package`。 |
|
||||
| QA parity | **Job:** `Run QA Lab parity lane` 和 `Run QA Lab parity report`<br />**底层工作流:** 直接 Job<br />**测试内容:** 候选版本和基线的 agentic parity packs,然后生成 parity report。<br />**重跑:** `rerun_group=qa-parity` 或 `rerun_group=qa`。 |
|
||||
| QA live Matrix | **Job:** `Run QA Lab live Matrix lane`<br />**底层工作流:** 直接 Job<br />**测试内容:** 在 `qa-live-shared` 环境中运行快速 live Matrix QA profile。<br />**重跑:** `rerun_group=qa-live` 或 `rerun_group=qa`。 |
|
||||
| QA live Telegram | **Job:** `Run QA Lab live Telegram lane`<br />**底层工作流:** 直接 Job<br />**测试内容:** 使用 Convex CI 凭证租约的 live Telegram QA。<br />**重跑:** `rerun_group=qa-live` 或 `rerun_group=qa`。 |
|
||||
| 发布验证器 | **Job:** `Verify release checks`<br />**底层工作流:** 无<br />**测试内容:** 选定重跑组所需的 release-check Job。<br />**重跑:** 聚焦的子 Job 通过后重跑。 |
|
||||
|
||||
## Docker 发布路径分块
|
||||
|
||||
当 `live_suite_filter` 为空时,Docker 发布路径阶段会运行这些分块:
|
||||
|
||||
| 分块 | 覆盖范围 |
|
||||
| 分块 | 覆盖范围 |
|
||||
| --------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `core` | 核心 Docker 发布路径冒烟通道。 |
|
||||
| `package-update-openai` | OpenAI 包安装和更新行为。 |
|
||||
| `package-update-anthropic` | Anthropic 包安装和更新行为。 |
|
||||
| `package-update-core` | 与提供商无关的包和更新行为。 |
|
||||
| `plugins-runtime-plugins` | 运行插件行为的插件运行时通道。 |
|
||||
| `plugins-runtime-services` | 服务支撑的插件运行时通道;按请求包含 OpenWebUI。 |
|
||||
| `plugins-runtime-install-a` through `plugins-runtime-install-h` | 为并行发布验证而拆分的插件安装/运行时批次。 |
|
||||
| `core` | Core Docker 发布路径冒烟 lanes。 |
|
||||
| `package-update-openai` | OpenAI 包安装和更新行为。 |
|
||||
| `package-update-anthropic` | Anthropic 包安装和更新行为。 |
|
||||
| `package-update-core` | 提供商中立的包和更新行为。 |
|
||||
| `plugins-runtime-plugins` | 运行插件行为的插件运行时 lanes。 |
|
||||
| `plugins-runtime-services` | 服务支持的插件运行时 lanes;在请求时包含 OpenWebUI。 |
|
||||
| `plugins-runtime-install-a` through `plugins-runtime-install-h` | 为并行发布验证拆分的插件安装/运行时批次。 |
|
||||
|
||||
当只有一个 Docker 通道失败时,在可复用 live/E2E 工作流上使用定向的 `docker_lanes=<lane[,lane]>`。发布构件包含每个通道的重新运行命令,并在可用时带有包构件和镜像复用输入。
|
||||
当只有一个 Docker lane 失败时,在可复用 live/E2E 工作流上使用定向的 `docker_lanes=<lane[,lane]>`。发布工件包含按 lane 划分的重跑命令,并在可用时包含包工件和镜像复用输入。
|
||||
|
||||
## 发布 profile
|
||||
## 发布 profiles
|
||||
|
||||
`release_profile` 主要控制发布检查中的 live/提供商覆盖广度。它不会移除普通完整 CI、Plugin Prerelease、安装冒烟、包验收、QA Lab 或 Docker 发布路径分块。`full` 还会让总控工作流在 `rerun_group=all` 时针对发布包构件运行 Telegram 包 E2E,因此完整的发布前候选版本不会默默跳过该 Telegram 包通道。
|
||||
`release_profile` 主要控制发布检查中的实时/提供商覆盖广度。
|
||||
它不会移除正常的完整 CI、插件预发布、安装冒烟测试、包
|
||||
验收、QA Lab 或 Docker 发布路径分块。`full` 还会让
|
||||
总控运行在 `rerun_group=all` 时针对发布包产物执行 Telegram 包 E2E,因此完整的预发布候选版本不会静默跳过该
|
||||
Telegram 包通道。
|
||||
|
||||
| 配置档案 | 预期用途 | 包含的实时/提供商覆盖范围 |
|
||||
| Profile | 预期用途 | 包含的实时/提供商覆盖范围 |
|
||||
| --------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `minimum` | 最快的发布关键冒烟测试。 | OpenAI/核心实时路径、OpenAI 的 Docker 实时模型、原生 Gateway 网关核心、原生 OpenAI Gateway 网关配置档案、原生 OpenAI 插件,以及 Docker 实时 Gateway 网关 OpenAI。 |
|
||||
| `stable` | 默认发布批准配置档案。 | `minimum` 加上 Anthropic、Google、MiniMax、后端、原生实时测试工具、Docker 实时 CLI 后端、Docker ACP 绑定、Docker Codex harness,以及一个 OpenCode Go 冒烟分片。 |
|
||||
| `full` | 广泛的建议性扫描。 | `stable` 加上建议性提供商、插件实时分片和媒体实时分片。 |
|
||||
| `minimum` | 最快的发布关键冒烟测试。 | OpenAI/核心实时路径、用于 OpenAI 的 Docker 实时模型、原生 Gateway 网关核心、原生 OpenAI Gateway 网关配置文件、原生 OpenAI 插件,以及 Docker 实时 Gateway 网关 OpenAI。 |
|
||||
| `stable` | 默认发布批准配置文件。 | `minimum` 加上 Anthropic、Google、MiniMax、后端、原生实时测试 harness、Docker 实时 CLI 后端、Docker ACP 绑定、Docker Codex harness,以及一个 OpenCode Go 冒烟分片。 |
|
||||
| `full` | 广泛的建议性扫描。 | `stable` 加上建议性提供商、插件实时分片和媒体实时分片。 |
|
||||
|
||||
## 仅 Full 的新增项
|
||||
## 仅 full 增加项
|
||||
|
||||
这些套件会被 `stable` 跳过,并由 `full` 包含:
|
||||
|
||||
| 区域 | 仅 Full 的覆盖范围 |
|
||||
| 区域 | 仅 full 覆盖范围 |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| Docker 实时模型 | OpenCode Go、OpenRouter、xAI、Z.ai 和 Fireworks。 |
|
||||
| Docker 实时 Gateway 网关 | DeepSeek、Fireworks、OpenCode Go、OpenRouter、xAI 和 Z.ai 的建议性分片。 |
|
||||
| 原生 Gateway 网关提供商配置档案 | Fireworks、DeepSeek、完整 OpenCode Go 模型分片、OpenRouter、xAI 和 Z.ai。 |
|
||||
| 原生插件实时分片 | 插件 A-K、L-N、O-Z 其他、Moonshot 和 xAI。 |
|
||||
| 原生媒体实时分片 | 音频、Google 音乐、MiniMax 音乐,以及视频组 A-D。 |
|
||||
| Docker 实时模型 | OpenCode Go、OpenRouter、xAI、Z.ai 和 Fireworks。 |
|
||||
| Docker 实时 Gateway 网关 | 用于 DeepSeek、Fireworks、OpenCode Go、OpenRouter、xAI 和 Z.ai 的建议性分片。 |
|
||||
| 原生 Gateway 网关提供商配置文件 | Fireworks、DeepSeek、完整 OpenCode Go 模型分片、OpenRouter、xAI 和 Z.ai。 |
|
||||
| 原生插件实时分片 | 插件 A-K、L-N、O-Z 其他、Moonshot 和 xAI。 |
|
||||
| 原生媒体实时分片 | 音频、Google 音乐、MiniMax 音乐和视频组 A-D。 |
|
||||
|
||||
`stable` 包含 `native-live-src-gateway-profiles-opencode-go-smoke`;`full`
|
||||
改用范围更广的 OpenCode Go 模型分片。
|
||||
则使用更广泛的 OpenCode Go 模型分片。
|
||||
|
||||
## 聚焦重跑
|
||||
|
||||
使用 `rerun_group` 避免重复运行无关的发布盒:
|
||||
使用 `rerun_group` 以避免重复运行无关的发布盒子:
|
||||
|
||||
| 句柄 | 范围 |
|
||||
| 句柄 | 范围 |
|
||||
| ------------------- | --------------------------------------------------------------------- |
|
||||
| `all` | 所有 Full Release Validation 阶段。 |
|
||||
| `ci` | 仅手动完整 CI 子项。 |
|
||||
| `plugin-prerelease` | 仅插件预发布子项。 |
|
||||
| `release-checks` | 所有 OpenClaw Release Checks 阶段。 |
|
||||
| `install-smoke` | 安装冒烟到发布检查。 |
|
||||
| `cross-os` | 跨操作系统发布检查。 |
|
||||
| `live-e2e` | 仓库/实时 E2E 和 Docker 发布路径验证。 |
|
||||
| `package` | Package Acceptance。 |
|
||||
| `qa` | QA 对等性加 QA 实时通道。 |
|
||||
| `qa-parity` | 仅 QA 对等性通道和报告。 |
|
||||
| `qa-live` | 仅 QA 实时 Matrix 和 Telegram。 |
|
||||
| `npm-telegram` | 已发布包的 Telegram E2E;需要 `npm_telegram_package_spec`。 |
|
||||
| `all` | 所有完整发布验证阶段。 |
|
||||
| `ci` | 仅手动完整 CI 子项。 |
|
||||
| `plugin-prerelease` | 仅插件预发布子项。 |
|
||||
| `release-checks` | 所有 OpenClaw 发布检查阶段。 |
|
||||
| `install-smoke` | 通过发布检查执行安装冒烟测试。 |
|
||||
| `cross-os` | 跨 OS 发布检查。 |
|
||||
| `live-e2e` | 仓库/实时 E2E 和 Docker 发布路径验证。 |
|
||||
| `package` | 包验收。 |
|
||||
| `qa` | QA 奇偶校验加 QA 实时通道。 |
|
||||
| `qa-parity` | 仅 QA 奇偶校验通道和报告。 |
|
||||
| `qa-live` | 仅 QA 实时 Matrix 和 Telegram。 |
|
||||
| `npm-telegram` | 已发布包 Telegram E2E;需要 `npm_telegram_package_spec`。 |
|
||||
|
||||
当某个实时套件失败时,将 `live_suite_filter` 与 `rerun_group=live-e2e` 一起使用。
|
||||
有效的过滤器 ID 在可复用实时/E2E 工作流中定义,包括
|
||||
有效的过滤器 ID 定义在可复用实时/E2E 工作流中,包括
|
||||
`docker-live-models`、`live-gateway-docker`、
|
||||
`live-gateway-anthropic-docker`、`live-gateway-google-docker`、
|
||||
`live-gateway-minimax-docker`、`live-gateway-advisory-docker`、
|
||||
@ -132,16 +137,16 @@ gh workflow run full-release-validation.yml \
|
||||
## 需要保留的证据
|
||||
|
||||
保留 `Full Release Validation` 摘要作为发布级索引。它会链接
|
||||
子运行 ID,并包含最慢作业表。对于失败,先检查子
|
||||
工作流,然后重跑上方匹配范围最小的句柄。
|
||||
子运行 ID,并包含最慢任务表。对于失败,先检查子
|
||||
工作流,然后重跑上面匹配的最小句柄。
|
||||
|
||||
有用的工件:
|
||||
有用的产物:
|
||||
|
||||
- 来自 `OpenClaw Release Checks` 的 `release-package-under-test`
|
||||
- `.artifacts/docker-tests/` 下的 Docker 发布路径工件
|
||||
- Package Acceptance 的 `package-under-test` 和 Docker 验收工件
|
||||
- 每个操作系统和套件的跨操作系统发布检查工件
|
||||
- QA 对等性、Matrix 和 Telegram 工件
|
||||
- `.artifacts/docker-tests/` 下的 Docker 发布路径产物
|
||||
- 包验收 `package-under-test` 和 Docker 验收产物
|
||||
- 每个 OS 和套件的跨 OS 发布检查产物
|
||||
- QA 奇偶校验、Matrix 和 Telegram 产物
|
||||
|
||||
## 工作流文件
|
||||
|
||||
|
||||
@ -1,63 +1,63 @@
|
||||
---
|
||||
read_when:
|
||||
- 运行或修复测试
|
||||
summary: 如何在本地运行测试(vitest)以及何时使用 force/coverage 模式
|
||||
summary: 如何在本地运行测试(vitest),以及何时使用强制/覆盖率模式
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-05-02T15:57:31Z"
|
||||
generated_at: "2026-05-02T18:56:59Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: c1e4aec3c056619467bbf51549699cd0387ebb16576e88f91587aab3f382c6c1
|
||||
source_hash: 8a88599d079e1ca42d73d354b582d67dd85be40fc92eed5abe6dcef37dc21f4f
|
||||
source_path: reference/test.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
- 完整测试工具包(套件、live、Docker):[测试](/zh-CN/help/testing)
|
||||
- 完整测试工具包(套件、实时、Docker):[测试](/zh-CN/help/testing)
|
||||
- 更新和插件包验证:[更新和插件测试](/zh-CN/help/testing-updates-plugins)
|
||||
|
||||
- `pnpm test:force`: 终止任何仍占用默认控制端口的 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整 Vitest 套件,避免服务器测试与正在运行的实例冲突。当此前一次 Gateway 网关运行占用了端口 18789 时使用此命令。
|
||||
- `pnpm test:coverage`: 使用 V8 覆盖率运行单元套件(通过 `vitest.unit.config.ts`)。这是已加载文件的单元覆盖率门禁,不是整个仓库的全文件覆盖率。阈值为 70% 行数/函数/语句和 55% 分支。由于 `coverage.all` 为 false,该门禁会衡量单元覆盖率套件加载的文件,而不是把每个拆分车道的源文件都视为未覆盖。
|
||||
- `pnpm test:coverage:changed`: 仅对自 `origin/main` 以来变更的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`: 低成本的智能变更测试运行。它会根据直接测试编辑、同级 `*.test.ts` 文件、显式源码映射和本地导入图运行精确目标。宽泛的配置/包变更会被跳过,除非它们映射到精确测试。
|
||||
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`: 显式的宽泛变更测试运行。当测试 harness/配置/包编辑应回退到 Vitest 更宽泛的变更测试行为时使用它。
|
||||
- `pnpm changed:lanes`: 显示相对 `origin/main` 的 diff 触发的架构车道。
|
||||
- `pnpm check:changed`: 为相对 `origin/main` 的 diff 运行智能变更检查门禁。它会为受影响的架构车道运行类型检查、lint 和 guard 命令,但不会运行 Vitest 测试。测试证明请使用 `pnpm test:changed` 或显式的 `pnpm test <target>`。
|
||||
- `pnpm test`: 将显式文件/目录目标路由到有作用域的 Vitest 车道。未指定目标的运行会使用固定分片组,并展开为叶级配置以便本地并行执行;插件组始终展开为按插件划分的分片配置,而不是一个巨大的根项目进程。
|
||||
- 测试包装器运行结束时会有一条简短的 `[test] passed|failed|skipped ... in ...` 摘要。Vitest 自己的耗时行保留为按分片的细节。
|
||||
- 共享 OpenClaw 测试状态:当测试需要隔离的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、配置 fixture、工作区、智能体目录或 auth-profile 存储时,在 Vitest 中使用 `src/test-utils/openclaw-test-state.ts`。
|
||||
- 进程 E2E helper:当 Vitest 进程级 E2E 测试需要在一处处理运行中的 Gateway 网关、CLI 环境、日志捕获和清理时,使用 `test/helpers/openclaw-test-instance.ts`。
|
||||
- Docker/Bash E2E helper:source `scripts/lib/docker-e2e-image.sh` 的车道可以把 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每条流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 获取容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 获取可 source 的主机环境文件。`create` 前的 `--` 可避免较新的 Node 运行时把 `--env-file` 当作 Node 标志。启动 Gateway 网关的 Docker/Bash 车道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探针、状态环境导出、日志转储和进程清理。
|
||||
- 完整、插件和 include-pattern 分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;后续 whole-config 运行会使用这些计时来平衡慢分片和快分片。Include-pattern CI 分片会把分片名称追加到计时键中,这样既能保留筛选后分片的计时可见性,又不会替换 whole-config 计时数据。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时工件。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会路由到专用轻量车道,这些车道只保留 `test/setup.ts`,而运行时较重的用例仍留在现有车道上。
|
||||
- 带有同级测试的源文件会先映射到该同级测试,然后再回退到更宽的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的 helper 编辑会使用本地导入图运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
|
||||
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),这样 reply harness 不会主导更轻量的顶层状态/token/helper 测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在仓库配置中启用共享的非隔离 runner。
|
||||
- `pnpm test:force`:终止任何占用默认控制端口的残留 Gateway 网关进程,然后使用隔离的 Gateway 网关端口运行完整 Vitest 套件,避免服务器测试与正在运行的实例冲突。当先前的 Gateway 网关运行遗留端口 18789 被占用时使用此命令。
|
||||
- `pnpm test:coverage`:使用 V8 覆盖率运行单元套件(通过 `vitest.unit.config.ts`)。这是已加载文件的单元覆盖率门禁,不是全仓库所有文件覆盖率。阈值为 70% 行/函数/语句和 55% 分支。由于 `coverage.all` 为 false,该门禁测量单元覆盖率套件加载的文件,而不是把每个拆分车道源文件都视为未覆盖。
|
||||
- `pnpm test:coverage:changed`:仅对自 `origin/main` 以来变更的文件运行单元覆盖率。
|
||||
- `pnpm test:changed`:廉价的智能变更测试运行。它会从直接测试编辑、同级 `*.test.ts` 文件、显式源映射和本地导入图运行精确目标。宽泛/配置/包变更会被跳过,除非它们映射到精确测试。
|
||||
- `OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed`:显式的宽泛变更测试运行。当测试 harness/配置/包编辑应回退到 Vitest 更宽泛的变更测试行为时使用。
|
||||
- `pnpm changed:lanes`:显示相对于 `origin/main` 的差异触发的架构车道。
|
||||
- `pnpm check:changed`:针对相对于 `origin/main` 的差异运行智能变更检查门禁。它会为受影响的架构车道运行类型检查、lint 和保护命令,但不会运行 Vitest 测试。使用 `pnpm test:changed` 或显式 `pnpm test <target>` 获取测试证明。
|
||||
- `pnpm test`:通过有作用域的 Vitest 车道路由显式文件/目录目标。未指定目标的运行使用固定分片组,并展开为叶子配置以便本地并行执行;扩展组始终展开为按扩展划分的分片配置,而不是一个巨大的根项目进程。
|
||||
- 测试包装器运行结束时会带有简短的 `[test] passed|failed|skipped ... in ...` 摘要。Vitest 自身的耗时行保留为每个分片的详情。
|
||||
- 共享 OpenClaw 测试状态:当测试需要隔离的 `HOME`、`OPENCLAW_STATE_DIR`、`OPENCLAW_CONFIG_PATH`、配置夹具、工作区、智能体目录或认证配置存储时,在 Vitest 中使用 `src/test-utils/openclaw-test-state.ts`。
|
||||
- 进程 E2E 辅助工具:当 Vitest 进程级 E2E 测试需要把运行中的 Gateway 网关、CLI 环境、日志捕获和清理集中到一处时,使用 `test/helpers/openclaw-test-instance.ts`。
|
||||
- Docker/Bash E2E 辅助工具:source `scripts/lib/docker-e2e-image.sh` 的车道可以将 `docker_e2e_test_state_shell_b64 <label> <scenario>` 传入容器,并用 `scripts/lib/openclaw-e2e-instance.sh` 解码;多 home 脚本可以传入 `docker_e2e_test_state_function_b64`,并在每个流程中调用 `openclaw_test_state_create <label> <scenario>`。更底层的调用方可以使用 `scripts/lib/openclaw-test-state.mjs shell --label <name> --scenario <name>` 获取容器内 shell 片段,或使用 `node scripts/lib/openclaw-test-state.mjs -- create --label <name> --scenario <name> --env-file <path> --json` 获取可 source 的宿主机环境文件。`create` 前的 `--` 会防止较新的 Node 运行时把 `--env-file` 当作 Node 标志。启动 Gateway 网关的 Docker/Bash 车道可以在容器内 source `scripts/lib/openclaw-e2e-instance.sh`,用于入口点解析、模拟 OpenAI 启动、Gateway 网关前台/后台启动、就绪探针、状态环境导出、日志转储和进程清理。
|
||||
- 完整、扩展和包含模式分片运行会更新 `.artifacts/vitest-shard-timings.json` 中的本地计时数据;后续整配置运行会使用这些计时来平衡慢分片和快分片。包含模式 CI 分片会把分片名称追加到计时键,这样可以让过滤后的分片计时可见,而不会替换整配置计时数据。设置 `OPENCLAW_TEST_PROJECTS_TIMINGS=0` 可忽略本地计时工件。
|
||||
- 选定的 `plugin-sdk` 和 `commands` 测试文件现在会路由到专用轻量车道,这些车道只保留 `test/setup.ts`,同时让运行时较重的用例留在其现有车道上。
|
||||
- 带有同级测试的源文件会先映射到该同级测试,再回退到更宽泛的目录 glob。`src/channels/plugins/contracts/test-helpers`、`src/plugin-sdk/test-helpers` 和 `src/plugins/contracts` 下的辅助工具编辑会使用本地导入图运行导入它们的测试,而不是在依赖路径精确时宽泛运行每个分片。
|
||||
- `auto-reply` 现在也拆分为三个专用配置(`core`、`top-level`、`reply`),因此回复 harness 不会主导较轻量的顶层 Status/token/辅助工具测试。
|
||||
- 基础 Vitest 配置现在默认使用 `pool: "threads"` 和 `isolate: false`,并在全仓库配置中启用共享的非隔离运行器。
|
||||
- `pnpm test:channels` 运行 `vitest.channels.config.ts`。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有扩展/插件分片。重型渠道插件、浏览器插件和 OpenAI 会作为专用分片运行;其他插件组保持批处理。对单个内置插件车道使用 `pnpm test extensions/<id>`。
|
||||
- `pnpm test:perf:imports`: 启用 Vitest 导入耗时 + 导入细分报告,同时仍对显式文件/目录目标使用有作用域的车道路由。
|
||||
- `pnpm test:perf:imports:changed`: 相同的导入分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会针对同一已提交 git diff,将已路由的 changed-mode 路径与原生根项目运行进行基准比较。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会在无需先提交的情况下,对当前工作区变更集进行基准测试。
|
||||
- `pnpm test:perf:profile:main`: 为 Vitest 主线程写入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`: 为单元 runner 写入 CPU + heap profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`: 串行运行每个 full-suite Vitest 叶级配置,并写入分组耗时数据以及按配置的 JSON/日志工件。Test Performance Agent 会在尝试修复慢测试前将其用作基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`: 在面向性能的变更后比较分组报告。
|
||||
- `pnpm test:extensions` 和 `pnpm test extensions` 运行所有扩展/插件分片。重型渠道插件、浏览器插件和 OpenAI 会作为专用分片运行;其他插件组保持批处理。使用 `pnpm test extensions/<id>` 运行一个内置插件车道。
|
||||
- `pnpm test:perf:imports`:启用 Vitest 导入耗时 + 导入分解报告,同时仍然对显式文件/目录目标使用有作用域车道路由。
|
||||
- `pnpm test:perf:imports:changed`:相同的导入分析,但仅针对自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>`:针对同一个已提交的 Git 差异,对路由后的变更模式路径和原生根项目运行进行基准测试。
|
||||
- `pnpm test:perf:changed:bench -- --worktree`:对当前工作树变更集进行基准测试,无需先提交。
|
||||
- `pnpm test:perf:profile:main`:为 Vitest 主线程写入 CPU profile(`.artifacts/vitest-main-profile`)。
|
||||
- `pnpm test:perf:profile:runner`:为单元运行器写入 CPU + heap profile(`.artifacts/vitest-runner-profile`)。
|
||||
- `pnpm test:perf:groups --full-suite --allow-failures --output .artifacts/test-perf/baseline-before.json`:串行运行每个完整套件 Vitest 叶子配置,并写入分组耗时数据以及每配置 JSON/日志工件。Test Performance Agent 在尝试修复慢测试前使用它作为基线。
|
||||
- `pnpm test:perf:groups:compare .artifacts/test-perf/baseline-before.json .artifacts/test-perf/after-agent.json`:在性能导向变更后比较分组报告。
|
||||
- Gateway 网关集成:通过 `OPENCLAW_TEST_INCLUDE_GATEWAY=1 pnpm test` 或 `pnpm test:gateway` 选择启用。
|
||||
- `pnpm test:e2e`: 运行 Gateway 网关端到端 smoke 测试(多实例 WS/HTTP/node 配对)。默认使用 `threads` + `isolate: false`,并在 `vitest.e2e.config.ts` 中使用自适应 worker;用 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 以输出详细日志。
|
||||
- `pnpm test:live`: 运行提供商 live 测试(minimax/zai)。需要 API key 和 `LIVE=1`(或提供商特定的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:all`: 构建共享 live-test 镜像,将 OpenClaw 作为 npm tarball 打包一次,构建/复用一个裸 Node/Git runner 镜像以及一个把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器以 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker smoke 车道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于安装器/更新/插件依赖车道;这些车道会挂载预构建 tarball,而不是使用复制的仓库源码。功能镜像(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于普通的已构建应用功能车道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI 包打包器,会在 Docker 使用前验证 tarball 和 `dist/postinstall-inventory.json`。Docker 车道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会输出由调度器拥有的 CI 计划,其中包含选定车道、镜像种类、包/live-image 需求、状态场景和凭据检查,而不会构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认值为 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制对提供商敏感的尾部池,默认值为 10。重型车道上限默认是 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 为每个提供商设置一个重型车道。更大的主机可使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个车道在低并行度主机上超过有效权重或资源上限,它仍可从空池启动,并会独占运行直到释放容量。车道启动默认错开 2 秒,以避免本地 Docker daemon 出现创建风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。runner 默认会预检 Docker、清理陈旧的 OpenClaw E2E 容器、每 30 秒输出活跃车道状态、在兼容车道之间共享提供商 CLI 工具缓存、默认对瞬时 live-provider 故障重试一次(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并把车道计时存储到 `.artifacts/docker-tests/lane-timings.json`,供后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可打印车道清单而不运行 Docker,使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 可调整状态输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 仅运行确定性/本地车道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 仅运行 live-provider 车道;包别名为 `pnpm test:docker:local:all` 和 `pnpm test:docker:live:all`。Live-only 模式会把主 live 车道和尾部 live 车道合并为一个最长优先池,让提供商桶可以把 Claude、Codex 和 Gemini 工作一起打包。除非设置 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,runner 会在第一次失败后停止调度新的池化车道;每个车道都有 120 分钟的兜底超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/tail 车道使用更严格的按车道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS` 配置(默认 180)。按车道的日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 查看慢车道,并使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印低成本的定向重跑命令。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`: 构建基于 Chromium 的源码 E2E 容器,启动原始 CDP 和隔离的 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP role 快照包含链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。
|
||||
- `pnpm test:e2e`:运行 Gateway 网关端到端冒烟测试(多实例 WS/HTTP/node 配对)。默认在 `vitest.e2e.config.ts` 中使用 `threads` + `isolate: false` 和自适应 worker;用 `OPENCLAW_E2E_WORKERS=<n>` 调整,并设置 `OPENCLAW_E2E_VERBOSE=1` 获取详细日志。
|
||||
- `pnpm test:live`:运行提供商 live 测试(minimax/zai)。需要 API key 和 `LIVE=1`(或提供商特定的 `*_LIVE_TEST=1`)才能取消跳过。
|
||||
- `pnpm test:docker:all`:构建共享 live-test 镜像,将 OpenClaw 一次性打包为 npm tarball,构建/复用裸 Node/Git 运行器镜像以及把该 tarball 安装到 `/app` 的功能镜像,然后通过加权调度器使用 `OPENCLAW_SKIP_DOCKER_BUILD=1` 运行 Docker 冒烟车道。裸镜像(`OPENCLAW_DOCKER_E2E_BARE_IMAGE`)用于安装器/更新/插件依赖车道;这些车道挂载预构建的 tarball,而不是使用复制的仓库源代码。功能镜像(`OPENCLAW_DOCKER_E2E_FUNCTIONAL_IMAGE`)用于正常的已构建应用功能车道。`scripts/package-openclaw-for-docker.mjs` 是唯一的本地/CI 包打包器,并在 Docker 使用前验证 tarball 和 `dist/postinstall-inventory.json`。Docker 车道定义位于 `scripts/lib/docker-e2e-scenarios.mjs`;规划器逻辑位于 `scripts/lib/docker-e2e-plan.mjs`;`scripts/test-docker-all.mjs` 执行选定计划。`node scripts/test-docker-all.mjs --plan-json` 会输出由调度器拥有的 CI 计划,包含选定车道、镜像种类、包/live-image 需求、状态场景和凭据检查,而不构建或运行 Docker。`OPENCLAW_DOCKER_ALL_PARALLELISM=<n>` 控制进程槽位,默认为 10;`OPENCLAW_DOCKER_ALL_TAIL_PARALLELISM=<n>` 控制提供商敏感的尾部池,默认为 10。重型车道上限默认值为 `OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=10` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;提供商上限默认通过 `OPENCLAW_DOCKER_ALL_LIVE_CLAUDE_LIMIT=4`、`OPENCLAW_DOCKER_ALL_LIVE_CODEX_LIMIT=4` 和 `OPENCLAW_DOCKER_ALL_LIVE_GEMINI_LIMIT=4` 为每个提供商设置一个重型车道。对更大的宿主机使用 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。如果某个车道在低并行度宿主机上超过有效权重或资源上限,它仍可以从空池启动,并会独自运行直到释放容量。车道启动默认错开 2 秒,以避免本地 Docker daemon 出现 create 风暴;可用 `OPENCLAW_DOCKER_ALL_START_STAGGER_MS=<ms>` 覆盖。运行器默认预检 Docker、清理过期的 OpenClaw E2E 容器、每 30 秒输出活动车道 Status、在兼容车道之间共享提供商 CLI 工具缓存、默认重试一次瞬时 live 提供商失败(`OPENCLAW_DOCKER_ALL_LIVE_RETRIES=<n>`),并把车道计时存储在 `.artifacts/docker-tests/lane-timings.json` 中,以便后续运行按最长优先排序。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 打印车道清单而不运行 Docker,使用 `OPENCLAW_DOCKER_ALL_STATUS_INTERVAL_MS=<ms>` 调整 Status 输出,或使用 `OPENCLAW_DOCKER_ALL_TIMINGS=0` 禁用计时复用。使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=skip` 仅运行确定性/本地车道,或使用 `OPENCLAW_DOCKER_ALL_LIVE_MODE=only` 仅运行 live 提供商车道;包别名为 `pnpm test:docker:local:all` 和 `pnpm test:docker:live:all`。仅 live 模式会把主 live 车道和尾部 live 车道合并到一个最长优先池中,让提供商桶可以将 Claude、Codex 和 Gemini 工作一起打包。除非设置 `OPENCLAW_DOCKER_ALL_FAIL_FAST=0`,否则运行器会在第一次失败后停止调度新的池化车道;每个车道都有 120 分钟的后备超时,可用 `OPENCLAW_DOCKER_ALL_LANE_TIMEOUT_MS` 覆盖;选定的 live/尾部车道使用更严格的每车道上限。CLI 后端 Docker 设置命令有自己的超时,通过 `OPENCLAW_LIVE_CLI_BACKEND_SETUP_TIMEOUT_SECONDS`(默认 180)配置。每车道日志、`summary.json`、`failures.json` 和阶段计时会写入 `.artifacts/docker-tests/<run-id>/` 下;使用 `pnpm test:docker:timings <summary.json>` 检查慢车道,使用 `pnpm test:docker:rerun <run-id|summary.json|failures.json>` 打印廉价的定向重跑命令。
|
||||
- `pnpm test:docker:browser-cdp-snapshot`:构建基于 Chromium 的源 E2E 容器,启动原始 CDP 和隔离的 Gateway 网关,运行 `browser doctor --deep`,并验证 CDP 角色快照包含链接 URL、光标提升的可点击项、iframe 引用和 frame 元数据。
|
||||
- CLI 后端 live Docker 探针可以作为聚焦车道运行,例如 `pnpm test:docker:live-cli-backend:codex`、`pnpm test:docker:live-cli-backend:codex:resume` 或 `pnpm test:docker:live-cli-backend:codex:mcp`。Claude 和 Gemini 有对应的 `:resume` 和 `:mcp` 别名。
|
||||
- `pnpm test:docker:openwebui`: 启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行一次真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,并且不预期像普通 unit/e2e 套件那样具有 CI 稳定性。
|
||||
- `pnpm test:docker:mcp-channels`: 启动一个已注入种子的 Gateway 网关容器和第二个会生成 `openclaw mcp serve` 的客户端容器,然后验证路由式会话发现、transcript 读取、附件元数据、live event queue 行为、出站发送路由,以及通过真实 stdio bridge 传递的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frame,因此该 smoke 反映 bridge 实际发出的内容。
|
||||
- `pnpm test:docker:upgrade-survivor`:将打包的 OpenClaw tar 包安装到带有脏状态的老用户 fixture 上,在没有实时提供商或渠道密钥的情况下运行包更新和非交互式 Doctor,然后启动回环 Gateway 网关,并检查智能体、渠道配置、插件允许列表、工作区/会话文件、过时的旧版插件依赖状态、启动和 RPC 状态是否保留。
|
||||
- `pnpm test:docker:published-upgrade-survivor`:默认安装 `openclaw@latest`,在没有实时提供商或渠道密钥的情况下写入真实的既有用户文件,使用内置的 `openclaw config set` 命令配方配置该基线,将这个已发布安装更新到打包的 OpenClaw tar 包,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动回环 Gateway 网关,并检查已配置的意图、工作区/会话文件、过时的插件配置和旧版依赖状态、启动、`/healthz`、`/readyz` 以及 RPC 状态是否保留或干净修复。使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖一个基线,使用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 扩展精确矩阵,或使用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues` 添加场景 fixture;reported-issues 集包含 `configured-plugin-installs`,用于验证已配置的外部 OpenClaw 插件会在升级期间自动安装。Package Acceptance 将这些公开为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。
|
||||
- `pnpm test:docker:update-migration`:在清理工作较重的 `plugin-deps-cleanup` 场景中运行已发布升级 survivor harness,默认从 `openclaw@2026.4.23` 开始。单独的 `Update Migration` 工作流使用 `baselines=all-since-2026.4.23` 扩展此通道,使 `.23` 以来的每个稳定已发布包都更新到候选版本,并在 Full Release CI 之外证明已配置插件的依赖清理。
|
||||
- `pnpm test:docker:plugins`:对本地路径、`file:`、带提升依赖的 npm registry 包、git 移动 ref、ClawHub fixture、marketplace 更新,以及 Claude-bundle 启用/检查运行安装/更新 smoke。
|
||||
- `pnpm test:docker:openwebui`:启动 Docker 化的 OpenClaw + Open WebUI,通过 Open WebUI 登录,检查 `/api/models`,然后通过 `/api/chat/completions` 运行真实的代理聊天。需要可用的 live 模型 key(例如 `~/.profile` 中的 OpenAI),会拉取外部 Open WebUI 镜像,并且不像正常单元/e2e 套件那样预期能在 CI 中稳定运行。
|
||||
- `pnpm test:docker:mcp-channels`:启动一个已播种的 Gateway 网关容器和第二个客户端容器,后者会生成 `openclaw mcp serve`,然后验证路由后的对话发现、转录读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio bridge 发送的 Claude 风格渠道 + 权限通知。Claude 通知断言会直接读取原始 stdio MCP frames,因此该冒烟测试反映 bridge 实际发出的内容。
|
||||
- `pnpm test:docker:upgrade-survivor`:将打包的 OpenClaw tarball 安装到一个脏的旧用户 fixture 之上,在没有实时提供商或渠道密钥的情况下运行软件包更新和非交互式 Doctor,然后启动一个回环 Gateway 网关,并检查智能体、渠道配置、插件 allowlist、工作区/会话文件、陈旧的旧版插件依赖状态、启动过程和 RPC 状态是否能保留下来。
|
||||
- `pnpm test:docker:published-upgrade-survivor`:默认安装 `openclaw@latest`,在没有实时提供商或渠道密钥的情况下播种真实的既有用户文件,用内置的 `openclaw config set` 命令配方配置该基线,将该已发布安装更新到打包的 OpenClaw tarball,运行非交互式 Doctor,写入 `.artifacts/upgrade-survivor/summary.json`,然后启动一个回环 Gateway 网关,并检查已配置的意图、工作区/会话文件、陈旧的插件配置和旧版依赖状态、启动过程、`/healthz`、`/readyz` 以及 RPC 状态是否能保留或干净修复。可用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC` 覆盖一个基线,用 `OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS` 展开精确矩阵,例如 `all-since-2026.4.23`,或用 `OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS=reported-issues` 添加场景 fixture;reported-issues 集合包含 `configured-plugin-installs`,用于验证已配置的外部 OpenClaw 插件会在升级期间自动安装。软件包验收会将这些公开为 `published_upgrade_survivor_baseline`、`published_upgrade_survivor_baselines` 和 `published_upgrade_survivor_scenarios`。
|
||||
- `pnpm test:docker:update-migration`:在清理较重的 `plugin-deps-cleanup` 场景中运行已发布升级存活 harness,默认从 `openclaw@2026.4.23` 开始。单独的 `Update Migration` 工作流会用 `baselines=all-since-2026.4.23` 扩展此 lane,因此从 `.23` 起的每个稳定已发布软件包都会更新到候选版本,并在 Full Release CI 之外证明已配置插件的依赖清理。
|
||||
- `pnpm test:docker:plugins`:为本地路径、`file:`、带提升依赖的 npm registry 软件包、git 移动引用、ClawHub fixture、市场更新以及 Claude-bundle 启用/检查运行安装/更新冒烟测试。
|
||||
|
||||
## 本地 PR 门禁
|
||||
|
||||
对于本地 PR 合入/门禁检查,运行:
|
||||
对于本地 PR 合并/门禁检查,运行:
|
||||
|
||||
- `pnpm check:changed`
|
||||
- `pnpm check`
|
||||
@ -66,7 +66,7 @@ x-i18n:
|
||||
- `pnpm test`
|
||||
- `pnpm check:docs`
|
||||
|
||||
如果 `pnpm test` 在负载较高的主机上出现不稳定失败,先重跑一次再将其视为回归,然后用 `pnpm test <path/to/test>` 隔离问题。对于内存受限的主机,使用:
|
||||
如果 `pnpm test` 在负载较高的主机上出现不稳定失败,先重新运行一次,再将其视为回归;然后用 `pnpm test <path/to/test>` 隔离问题。对于内存受限的主机,使用:
|
||||
|
||||
- `OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test`
|
||||
- `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-cache pnpm test:changed`
|
||||
@ -79,7 +79,7 @@ x-i18n:
|
||||
|
||||
- `source ~/.profile && pnpm tsx scripts/bench-model.ts --runs 10`
|
||||
- 可选环境变量:`MINIMAX_API_KEY`、`MINIMAX_BASE_URL`、`MINIMAX_MODEL`、`ANTHROPIC_API_KEY`
|
||||
- 默认 prompt:“只回复一个单词:ok。不要标点或额外文本。”
|
||||
- 默认提示词:“只回复一个单词:ok。不要标点或额外文本。”
|
||||
|
||||
上次运行(2025-12-31,20 次运行):
|
||||
|
||||
@ -114,13 +114,13 @@ x-i18n:
|
||||
- `real`:`health`、`status`、`status --json`、`sessions`、`sessions --json`、`tasks --json`、`tasks list --json`、`tasks audit --json`、`agents list --json`、`gateway status`、`gateway status --json`、`gateway health --json`、`config get gateway.port`
|
||||
- `all`:两个预设
|
||||
|
||||
输出包含每个命令的 `sampleCount`、平均值、p50、p95、最小/最大值、退出码/信号分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 配置文件,因此计时和配置文件采集使用同一套 harness。
|
||||
输出包括每条命令的 `sampleCount`、平均值、p50、p95、最小值/最大值、退出代码/信号分布,以及最大 RSS 摘要。可选的 `--cpu-prof-dir` / `--heap-prof-dir` 会为每次运行写入 V8 配置文件,因此计时和配置文件采集使用同一个 harness。
|
||||
|
||||
已保存输出约定:
|
||||
|
||||
- `pnpm test:startup:bench:smoke` 将目标 smoke 工件写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 使用 `runs=5` 和 `warmup=1` 将完整套件工件写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 使用 `runs=5` 和 `warmup=1` 刷新签入的基线 fixture:`test/fixtures/cli-startup-bench.json`
|
||||
- `pnpm test:startup:bench:smoke` 会将目标冒烟测试产物写入 `.artifacts/cli-startup-bench-smoke.json`
|
||||
- `pnpm test:startup:bench:save` 会使用 `runs=5` 和 `warmup=1` 将全套件产物写入 `.artifacts/cli-startup-bench-all.json`
|
||||
- `pnpm test:startup:bench:update` 会使用 `runs=5` 和 `warmup=1` 刷新签入的基线 fixture:`test/fixtures/cli-startup-bench.json`
|
||||
|
||||
签入的 fixture:
|
||||
|
||||
@ -130,9 +130,9 @@ x-i18n:
|
||||
|
||||
## 新手引导 E2E(Docker)
|
||||
|
||||
Docker 是可选的;仅容器化新手引导 smoke 测试需要它。
|
||||
Docker 是可选的;只有容器化新手引导冒烟测试需要它。
|
||||
|
||||
在干净 Linux 容器中的完整冷启动流程:
|
||||
在干净的 Linux 容器中执行完整冷启动流程:
|
||||
|
||||
```bash
|
||||
scripts/e2e/onboard-docker.sh
|
||||
@ -140,9 +140,9 @@ scripts/e2e/onboard-docker.sh
|
||||
|
||||
此脚本通过伪 tty 驱动交互式向导,验证配置/工作区/会话文件,然后启动 Gateway 网关并运行 `openclaw health`。
|
||||
|
||||
## QR 导入 smoke(Docker)
|
||||
## QR 导入冒烟测试(Docker)
|
||||
|
||||
确保维护中的 QR 运行时 helper 可在支持的 Docker Node 运行时下加载(默认 Node 24,兼容 Node 22):
|
||||
确保维护中的 QR 运行时辅助工具能在受支持的 Docker Node 运行时下加载(默认 Node 24,兼容 Node 22):
|
||||
|
||||
```bash
|
||||
pnpm test:docker:qr
|
||||
|
||||
@ -2,55 +2,55 @@
|
||||
read_when:
|
||||
- 添加或修改 Skills
|
||||
- 更改 Skills 门控、允许列表或加载规则
|
||||
- 了解技能优先级和快照行为
|
||||
- 理解 Skills 优先级和快照行为
|
||||
sidebarTitle: Skills
|
||||
summary: Skills:托管式与工作区、门控规则、智能体允许列表和配置接线
|
||||
title: Skills
|
||||
x-i18n:
|
||||
generated_at: "2026-04-30T19:53:28Z"
|
||||
generated_at: "2026-05-02T18:57:19Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: b58d690786756bd3539940aae9f2abcb8a497798ed7b6afeb5e6d6e255fcf257
|
||||
source_hash: 85d9a5305216abd277721a9cf46404505ac6bedcad78417e10862bf7f54591ea
|
||||
source_path: tools/skills.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
OpenClaw 使用 **[AgentSkills](https://agentskills.io)-compatible** 的技能文件夹来教智能体如何使用工具。每个技能都是一个目录,其中包含带有 YAML frontmatter 和说明的 `SKILL.md`。OpenClaw 会加载内置技能以及可选的本地覆盖,并在加载时根据环境、配置和二进制文件是否存在进行过滤。
|
||||
OpenClaw 使用与 **[AgentSkills](https://agentskills.io) 兼容**的技能文件夹来教智能体如何使用工具。每个技能都是一个目录,其中包含带有 YAML frontmatter 和说明的 `SKILL.md`。OpenClaw 会加载内置技能以及可选的本地覆盖,并在加载时根据环境、配置和二进制文件是否存在进行过滤。
|
||||
|
||||
## 位置和优先级
|
||||
|
||||
OpenClaw 从以下来源加载技能,**优先级从高到低**:
|
||||
OpenClaw 会从这些来源加载技能,**优先级从高到低**:
|
||||
|
||||
| # | 来源 | 路径 |
|
||||
| --- | --------------------- | -------------------------------- |
|
||||
| 1 | 工作区 Skills | `<workspace>/skills` |
|
||||
| 2 | 项目智能体 Skills | `<workspace>/.agents/skills` |
|
||||
| 3 | 个人智能体 Skills | `~/.agents/skills` |
|
||||
| 4 | 托管/本地 Skills | `~/.openclaw/skills` |
|
||||
| 5 | 内置 Skills | 随安装一起提供 |
|
||||
| 1 | 工作区技能 | `<workspace>/skills` |
|
||||
| 2 | 项目智能体技能 | `<workspace>/.agents/skills` |
|
||||
| 3 | 个人智能体技能 | `~/.agents/skills` |
|
||||
| 4 | 托管/本地技能 | `~/.openclaw/skills` |
|
||||
| 5 | 内置技能 | 随安装包提供 |
|
||||
| 6 | 额外技能文件夹 | `skills.load.extraDirs`(配置) |
|
||||
|
||||
如果技能名称冲突,优先级最高的来源胜出。
|
||||
如果技能名称冲突,优先级最高的来源生效。
|
||||
|
||||
Codex CLI 原生的 `$CODEX_HOME/skills` 目录不属于这些 OpenClaw 技能根目录。在 Codex harness 模式下,本地应用服务器启动会使用每个智能体隔离的 Codex home,因此个人 Codex CLI 技能不会被隐式加载。使用 `openclaw migrate codex --dry-run` 对它们进行盘点,并使用 `openclaw migrate codex` 在复制到当前 OpenClaw 智能体工作区之前,通过交互式复选框提示选择技能目录。对于非交互式运行,请重复使用 `--skill <name>` 指定要复制的确切技能。
|
||||
Codex CLI 原生的 `$CODEX_HOME/skills` 目录不属于这些 OpenClaw 技能根目录。在 Codex harness 模式下,本地应用服务器启动会使用按智能体隔离的 Codex 主目录,因此个人 Codex CLI 技能不会被隐式加载。使用 `openclaw migrate codex --dry-run` 清点它们,并使用 `openclaw migrate codex` 通过交互式复选框提示选择技能目录,然后将它们复制到当前 OpenClaw 智能体工作区。对于非交互式运行,请重复使用 `--skill <name>` 来指定要复制的确切技能。
|
||||
|
||||
## 每智能体与共享 Skills
|
||||
## 按智能体技能与共享技能
|
||||
|
||||
在**多智能体**设置中,每个智能体都有自己的工作区:
|
||||
|
||||
| 范围 | 路径 | 可见对象 |
|
||||
| -------------------- | ------------------------------------------- | --------------------------- |
|
||||
| 每智能体 | `<workspace>/skills` | 仅该智能体 |
|
||||
| 按智能体 | `<workspace>/skills` | 仅该智能体 |
|
||||
| 项目智能体 | `<workspace>/.agents/skills` | 仅该工作区的智能体 |
|
||||
| 个人智能体 | `~/.agents/skills` | 该机器上的所有智能体 |
|
||||
| 共享托管/本地 | `~/.openclaw/skills` | 该机器上的所有智能体 |
|
||||
| 共享额外目录 | `skills.load.extraDirs`(最低优先级) | 该机器上的所有智能体 |
|
||||
|
||||
多个位置存在相同名称 → 优先级最高的来源胜出。工作区优先于项目智能体,项目智能体优先于个人智能体,个人智能体优先于托管/本地,托管/本地优先于内置,内置优先于额外目录。
|
||||
同名技能出现在多个位置 → 优先级最高的来源生效。工作区优先于项目智能体,项目智能体优先于个人智能体,个人智能体优先于托管/本地,托管/本地优先于内置,内置优先于额外目录。
|
||||
|
||||
## 智能体技能允许列表
|
||||
|
||||
技能**位置**和技能**可见性**是彼此独立的控制项。位置/优先级决定同名技能的哪个副本胜出;智能体允许列表决定智能体实际可以使用哪些技能。
|
||||
技能**位置**和技能**可见性**是独立的控制项。位置/优先级决定同名技能的哪个副本生效;智能体允许列表决定智能体实际可以使用哪些技能。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -59,9 +59,9 @@ Codex CLI 原生的 `$CODEX_HOME/skills` 目录不属于这些 OpenClaw 技能
|
||||
skills: ["github", "weather"],
|
||||
},
|
||||
list: [
|
||||
{ id: "writer" }, // inherits github, weather
|
||||
{ id: "docs", skills: ["docs-search"] }, // replaces defaults
|
||||
{ id: "locked-down", skills: [] }, // no skills
|
||||
{ id: "writer" }, // 继承 github、weather
|
||||
{ id: "docs", skills: ["docs-search"] }, // 替换默认值
|
||||
{ id: "locked-down", skills: [] }, // 没有技能
|
||||
],
|
||||
},
|
||||
}
|
||||
@ -69,61 +69,61 @@ Codex CLI 原生的 `$CODEX_HOME/skills` 目录不属于这些 OpenClaw 技能
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="允许列表规则">
|
||||
- 默认情况下,省略 `agents.defaults.skills` 表示不限制 Skills。
|
||||
- 省略 `agents.defaults.skills` 表示默认不限制技能。
|
||||
- 省略 `agents.list[].skills` 表示继承 `agents.defaults.skills`。
|
||||
- 设置 `agents.list[].skills: []` 表示没有 Skills。
|
||||
- 非空的 `agents.list[].skills` 列表是该智能体的**最终**集合,它不会与默认值合并。
|
||||
- 有效允许列表会应用于提示构建、技能 slash 命令发现、沙箱同步和技能快照。
|
||||
|
||||
- 设置 `agents.list[].skills: []` 表示没有技能。
|
||||
- 非空的 `agents.list[].skills` 列表是该智能体的**最终**集合,不会与默认值合并。
|
||||
- 有效允许列表会应用于提示构建、技能斜杠命令发现、沙箱同步和技能快照。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 插件和 Skills
|
||||
## 插件和技能
|
||||
|
||||
插件可以通过在 `openclaw.plugin.json` 中列出 `skills` 目录来附带自己的技能(路径相对于插件根目录)。插件启用后会加载插件技能。这适合放置特定工具的操作指南:这些指南太长,不适合放进工具说明,但在插件安装后应始终可用。例如,浏览器插件附带一个 `browser-automation` 技能,用于多步骤浏览器控制。
|
||||
插件可以通过在 `openclaw.plugin.json` 中列出 `skills` 目录来携带自己的技能(路径相对于插件根目录)。插件启用时会加载插件技能。对于工具专用的操作指南,这是合适的位置:这些指南太长,不适合放在工具描述中,但只要插件已安装就应该可用。例如,浏览器插件会提供一个 `browser-automation` 技能,用于多步骤浏览器控制。
|
||||
|
||||
插件技能目录会合并到与 `skills.load.extraDirs` 相同的低优先级路径中,因此同名的内置、托管、智能体或工作区技能会覆盖它们。你可以通过插件配置项上的 `metadata.openclaw.requires.config` 对它们加门控。
|
||||
插件技能目录会合并到与 `skills.load.extraDirs` 相同的低优先级路径中,因此同名的内置、托管、智能体或工作区技能会覆盖它们。你可以通过插件配置项上的 `metadata.openclaw.requires.config` 对它们进行门控。
|
||||
|
||||
请参阅 [插件](/zh-CN/tools/plugin) 了解发现/配置,并参阅 [工具](/zh-CN/tools) 了解这些技能所教授的工具表面。
|
||||
参见 [插件](/zh-CN/tools/plugin) 了解发现/配置,参见 [工具](/zh-CN/tools) 了解这些技能所教授的工具表面。
|
||||
|
||||
## Skill Workshop
|
||||
|
||||
可选的实验性 **Skill Workshop** 插件可以根据智能体工作期间观察到的可复用流程,创建或更新工作区技能。它默认禁用,必须通过 `plugins.entries.skill-workshop` 显式启用。
|
||||
可选的实验性 **Skill Workshop** 插件可以根据智能体工作期间观察到的可复用流程创建或更新工作区技能。它默认禁用,必须通过 `plugins.entries.skill-workshop` 显式启用。
|
||||
|
||||
Skill Workshop 只写入 `<workspace>/skills`,会扫描生成的内容,支持待批准或自动安全写入,隔离不安全提案,并在成功写入后刷新技能快照,使新技能无需重启 Gateway 网关即可可用。
|
||||
Skill Workshop 只会写入 `<workspace>/skills`,会扫描生成的内容,支持待批准或自动安全写入,会隔离不安全的提案,并在成功写入后刷新技能快照,使新技能无需重启 Gateway 网关即可可用。
|
||||
|
||||
可将它用于纠正事项,例如 _“下次验证 GIF 署名”_,或来之不易的工作流,例如媒体 QA 检查清单。先从待批准开始;只有在可信工作区中审阅其提案后,才使用自动写入。完整指南:[Skill Workshop 插件](/zh-CN/plugins/skill-workshop)。
|
||||
可将它用于诸如 _“下次验证 GIF 归属”_ 之类的修正,或媒体 QA 清单这类来之不易的工作流。请从待批准开始;只有在可信工作区中审查其提案后,才使用自动写入。完整指南:[Skill Workshop 插件](/zh-CN/plugins/skill-workshop)。
|
||||
|
||||
## ClawHub(安装和同步)
|
||||
|
||||
[ClawHub](https://clawhub.ai) 是 OpenClaw 的公共技能注册表。使用原生 `openclaw skills` 命令进行发现/安装/更新,或使用独立的 `clawhub` CLI 进行发布/同步工作流。完整指南:[ClawHub](/zh-CN/tools/clawhub)。
|
||||
[ClawHub](https://clawhub.ai) 是 OpenClaw 的公共技能注册表。使用原生 `openclaw skills` 命令进行发现/安装/更新,或使用单独的 `clawhub` CLI 进行发布/同步工作流。完整指南:[ClawHub](/zh-CN/tools/clawhub)。
|
||||
|
||||
| 操作 | 命令 |
|
||||
| ---------------------------------- | -------------------------------------- |
|
||||
| 将技能安装到工作区 | `openclaw skills install <skill-slug>` |
|
||||
| 更新所有已安装技能 | `openclaw skills update --all` |
|
||||
| 更新所有已安装的技能 | `openclaw skills update --all` |
|
||||
| 同步(扫描 + 发布更新) | `clawhub sync --all` |
|
||||
|
||||
原生 `openclaw skills install` 会安装到活动工作区的 `skills/` 目录。独立的 `clawhub` CLI 也会安装到当前工作目录下的 `./skills`(或回退到已配置的 OpenClaw 工作区)。OpenClaw 会在下一个会话中将其作为 `<workspace>/skills` 读取。已配置的技能根目录也支持一级分组,例如 `skills/<group>/<skill>/SKILL.md`,因此相关第三方技能可以放在共享文件夹下,而不需要进行广泛的递归扫描。
|
||||
原生 `openclaw skills install` 会安装到活动工作区的 `skills/` 目录。单独的 `clawhub` CLI 也会安装到当前工作目录下的 `./skills`(或回退到已配置的 OpenClaw 工作区)。OpenClaw 会在下一个会话中将其识别为 `<workspace>/skills`。
|
||||
已配置的技能根目录也支持一级分组,例如 `skills/<group>/<skill>/SKILL.md`,因此相关的第三方技能可以保存在共享文件夹下,而无需进行广泛的递归扫描。
|
||||
|
||||
ClawHub 技能页面会在安装前展示最新的安全扫描状态,并提供 VirusTotal、ClawScan 和静态分析的扫描器详情页。`openclaw skills install <slug>` 仍然只是安装路径;发布者可通过 ClawHub 仪表盘或 `clawhub skill rescan <slug>` 处理误报。
|
||||
ClawHub 技能页面会在安装前公开最新安全扫描状态,并提供 VirusTotal、ClawScan 和静态分析的扫描器详情页。`openclaw skills install <slug>` 仍然只是安装路径;发布者可以通过 ClawHub 仪表板或 `clawhub skill rescan <slug>` 处理误报。
|
||||
|
||||
## 安全
|
||||
|
||||
<Warning>
|
||||
将第三方技能视为**不受信任的代码**。启用前先阅读它们。对于不受信任的输入和高风险工具,优先使用沙箱隔离运行。请参阅[沙箱隔离](/zh-CN/gateway/sandboxing)了解智能体侧控制项。
|
||||
将第三方技能视为**不受信任的代码**。启用前请先阅读。对于不受信任的输入和高风险工具,优先使用沙箱隔离运行。参见[沙箱隔离](/zh-CN/gateway/sandboxing)了解智能体侧控制项。
|
||||
</Warning>
|
||||
|
||||
- 工作区和额外目录的技能发现只接受解析后的真实路径仍位于已配置根目录内的技能根目录和 `SKILL.md` 文件。
|
||||
- 由 Gateway 网关支持的技能依赖安装(`skills.install`、新手引导和 Skills 设置 UI)会在执行安装器元数据之前运行内置的危险代码扫描器。默认情况下,`critical` 发现会阻止执行,除非调用方显式设置危险覆盖;可疑发现仍然只会警告。
|
||||
- `openclaw skills install <slug>` 不同,它会将 ClawHub 技能文件夹下载到工作区,不使用上面的安装器元数据路径。
|
||||
- `skills.entries.*.env` 和 `skills.entries.*.apiKey` 会把密钥注入该智能体回合的**主机**进程(不是沙箱)。不要把密钥放进提示和日志。
|
||||
- 工作区和额外目录技能发现只接受解析后的真实路径仍位于已配置根目录内的技能根目录和 `SKILL.md` 文件。
|
||||
- Gateway 网关支持的技能依赖安装(`skills.install`、新手引导和 Skills 设置 UI)会在执行安装器元数据之前运行内置危险代码扫描器。默认情况下,`critical` 发现项会阻止执行,除非调用方显式设置危险覆盖;可疑发现项仍只会发出警告。
|
||||
- `openclaw skills install <slug>` 不同,它会将 ClawHub 技能文件夹下载到工作区,并且不会使用上面的安装器元数据路径。
|
||||
- `skills.entries.*.env` 和 `skills.entries.*.apiKey` 会将密钥注入该智能体回合的**宿主**进程(不是沙箱)。请避免将密钥放入提示和日志。
|
||||
|
||||
如需更广泛的威胁模型和检查清单,请参阅[安全](/zh-CN/gateway/security)。
|
||||
有关更广泛的威胁模型和检查清单,请参见[安全](/zh-CN/gateway/security)。
|
||||
|
||||
## SKILL.md 格式
|
||||
|
||||
`SKILL.md` 必须至少包含:
|
||||
`SKILL.md` 至少必须包含:
|
||||
|
||||
```markdown
|
||||
---
|
||||
@ -132,32 +132,32 @@ description: Generate or edit images via a provider-backed image workflow
|
||||
---
|
||||
```
|
||||
|
||||
OpenClaw 遵循 AgentSkills 规范来处理布局/意图。嵌入式智能体使用的解析器仅支持**单行** frontmatter 键;`metadata` 应为**单行 JSON 对象**。在说明中使用 `{baseDir}` 引用技能文件夹路径。
|
||||
OpenClaw 遵循 AgentSkills 规范来处理布局/意图。嵌入式智能体使用的解析器仅支持**单行** frontmatter 键;`metadata` 应该是**单行 JSON 对象**。在说明中使用 `{baseDir}` 引用技能文件夹路径。
|
||||
|
||||
### 可选 frontmatter 键
|
||||
|
||||
<ParamField path="homepage" type="string">
|
||||
URL 会在 macOS Skills UI 中显示为 “网站”。也支持通过 `metadata.openclaw.homepage` 提供。
|
||||
在 macOS Skills UI 中显示为“网站”的 URL。也支持通过 `metadata.openclaw.homepage` 提供。
|
||||
</ParamField>
|
||||
<ParamField path="user-invocable" type="boolean" default="true">
|
||||
当为 `true` 时,该技能会公开为用户 slash 命令。
|
||||
当为 `true` 时,该技能会作为用户斜杠命令公开。
|
||||
</ParamField>
|
||||
<ParamField path="disable-model-invocation" type="boolean" default="false">
|
||||
当为 `true` 时,该技能会从模型提示中排除(仍可通过用户调用使用)。
|
||||
当为 `true` 时,OpenClaw 会将该技能的说明排除在智能体的常规提示之外。该技能仍会被安装,并且在 `user-invocable` 也为 `true` 时,仍可作为斜杠命令显式运行。
|
||||
</ParamField>
|
||||
<ParamField path="command-dispatch" type='"tool"'>
|
||||
当设置为 `tool` 时,slash 命令会绕过模型并直接分派到工具。
|
||||
设置为 `tool` 时,斜杠命令会绕过模型,并直接分派到工具。
|
||||
</ParamField>
|
||||
<ParamField path="command-tool" type="string">
|
||||
设置 `command-dispatch: tool` 时要调用的工具名称。
|
||||
</ParamField>
|
||||
<ParamField path="command-arg-mode" type='"raw"' default="raw">
|
||||
对于工具分派,会将原始 args 字符串转发给工具(不进行核心解析)。工具会以 `{ command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }` 调用。
|
||||
对于工具分派,将原始参数字符串转发给工具(无核心解析)。工具会以 `{ command: "<raw args>", commandName: "<slash command>", skillName: "<skill name>" }` 调用。
|
||||
</ParamField>
|
||||
|
||||
## 门控(加载时过滤器)
|
||||
|
||||
OpenClaw 使用 `metadata`(单行 JSON)在加载时过滤技能:
|
||||
OpenClaw 会在加载时使用 `metadata`(单行 JSON)过滤技能:
|
||||
|
||||
```markdown
|
||||
---
|
||||
@ -180,10 +180,10 @@ metadata:
|
||||
当为 `true` 时,始终包含该技能(跳过其他门控)。
|
||||
</ParamField>
|
||||
<ParamField path="emoji" type="string">
|
||||
macOS Skills UI 使用的可选表情符号。
|
||||
macOS Skills UI 使用的可选 emoji。
|
||||
</ParamField>
|
||||
<ParamField path="homepage" type="string">
|
||||
在 macOS Skills UI 中显示为 “网站” 的可选 URL。
|
||||
在 macOS Skills UI 中显示为“网站”的可选 URL。
|
||||
</ParamField>
|
||||
<ParamField path="os" type='"darwin" | "linux" | "win32"' >
|
||||
可选平台列表。如果设置,该技能仅在这些操作系统上符合条件。
|
||||
@ -204,20 +204,20 @@ metadata:
|
||||
与 `skills.entries.<name>.apiKey` 关联的环境变量名称。
|
||||
</ParamField>
|
||||
<ParamField path="install" type="object[]">
|
||||
macOS Skills UI 使用的可选安装器规格(brew/node/go/uv/download)。
|
||||
macOS Skills UI 使用的可选安装器规范(brew/node/go/uv/download)。
|
||||
</ParamField>
|
||||
|
||||
如果不存在 `metadata.openclaw`,则该技能始终符合条件(除非在配置中禁用,或对于内置技能被 `skills.allowBundled` 阻止)。
|
||||
如果不存在 `metadata.openclaw`,该技能始终符合条件(除非在配置中禁用,或作为内置技能被 `skills.allowBundled` 阻止)。
|
||||
|
||||
<Note>
|
||||
当 `metadata.openclaw` 不存在时,旧版 `metadata.clawdbot` 块仍会被接受,因此较旧的已安装技能会保留它们的依赖门控和安装器提示。新的和更新后的技能应使用 `metadata.openclaw`。
|
||||
当 `metadata.openclaw` 不存在时,仍接受旧版 `metadata.clawdbot` 块,因此较早安装的技能会保留其依赖门控和安装器提示。新的和更新后的技能应使用 `metadata.openclaw`。
|
||||
</Note>
|
||||
|
||||
### 沙箱隔离注意事项
|
||||
|
||||
- `requires.bins` 会在技能加载时于**主机**上检查。
|
||||
- 如果智能体处于沙箱隔离状态,则二进制文件也必须存在于**容器内部**。通过 `agents.defaults.sandbox.docker.setupCommand`(或自定义镜像)安装它。`setupCommand` 会在容器创建后运行一次。包安装还需要网络出站、可写根文件系统,以及沙箱中的 root 用户。
|
||||
- 示例:`summarize` 技能(`skills/summarize/SKILL.md`)需要沙箱容器中存在 `summarize` CLI,才能在那里运行。
|
||||
- `requires.bins` 会在技能加载时在**宿主**上检查。
|
||||
- 如果智能体已沙箱隔离,二进制文件也必须存在于**容器内部**。通过 `agents.defaults.sandbox.docker.setupCommand`(或自定义镜像)安装它。`setupCommand` 会在容器创建后运行一次。包安装还需要网络出口、可写根文件系统,以及沙箱中的 root 用户。
|
||||
- 示例:`summarize` 技能(`skills/summarize/SKILL.md`)需要沙箱容器中有 `summarize` CLI,才能在那里运行。
|
||||
|
||||
### 安装器规格
|
||||
|
||||
@ -249,11 +249,11 @@ metadata:
|
||||
<AccordionGroup>
|
||||
<Accordion title="安装器选择规则">
|
||||
- 如果列出了多个安装器,Gateway 网关会选择一个首选项(可用时选择 brew,否则选择 node)。
|
||||
- 如果所有安装器都是 `download`,OpenClaw 会列出每个条目,这样你就能看到可用构件。
|
||||
- 如果所有安装器都是 `download`,OpenClaw 会列出每个条目,方便你查看可用构件。
|
||||
- 安装器规格可以包含 `os: ["darwin"|"linux"|"win32"]`,用于按平台筛选选项。
|
||||
- Node 安装会遵循 `openclaw.json` 中的 `skills.install.nodeManager`(默认:npm;选项:npm/pnpm/yarn/bun)。这只影响 Skills 安装;Gateway 网关运行时仍应使用 Node,WhatsApp/Telegram 不建议使用 Bun。
|
||||
- Gateway 网关支持的安装器选择由偏好驱动:当安装规格混合多种类型时,如果启用了 `skills.install.preferBrew` 且 `brew` 存在,OpenClaw 会优先选择 Homebrew,然后是 `uv`,然后是已配置的 node 管理器,再然后是 `go` 或 `download` 等其他回退项。
|
||||
- 如果每个安装规格都是 `download`,OpenClaw 会显示所有下载选项,而不是折叠成一个首选安装器。
|
||||
- Node 安装会遵循 `openclaw.json` 中的 `skills.install.nodeManager`(默认:npm;选项:npm/pnpm/yarn/bun)。这只影响 Skill 安装;Gateway 网关运行时仍应使用 Node,WhatsApp/Telegram 不建议使用 Bun。
|
||||
- Gateway 网关支持的安装器选择由偏好驱动:当安装规格混合多种类型时,如果启用了 `skills.install.preferBrew` 且存在 `brew`,OpenClaw 会优先选择 Homebrew,然后是 `uv`,然后是已配置的 node 管理器,最后是 `go` 或 `download` 等其他回退项。
|
||||
- 如果每个安装规格都是 `download`,OpenClaw 会展示所有下载选项,而不是折叠为一个首选安装器。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="各安装器详情">
|
||||
@ -265,7 +265,7 @@ metadata:
|
||||
|
||||
## 配置覆盖
|
||||
|
||||
内置和托管的 Skills 可以在 `~/.openclaw/openclaw.json` 的 `skills.entries` 下切换并提供环境值:
|
||||
内置和受管 Skills 可以在 `~/.openclaw/openclaw.json` 的 `skills.entries` 下切换开关并提供环境值:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -291,36 +291,32 @@ metadata:
|
||||
|
||||
<ParamField path="enabled" type="boolean">
|
||||
`false` 会禁用该 Skill,即使它是内置或已安装的。
|
||||
内置的 `coding-agent` Skill 需要主动启用:在将其暴露给智能体之前,先设置
|
||||
内置 `coding-agent` Skill 是选择启用的:在向智能体暴露它之前,先设置
|
||||
`skills.entries.coding-agent.enabled: true`,
|
||||
然后确保已安装 `claude`、`codex`、`opencode` 或 `pi` 中的一个,
|
||||
并已为其自己的 CLI 完成认证。
|
||||
然后确保 `claude`、`codex`、`opencode` 或 `pi` 之一已安装,并已为它自己的 CLI
|
||||
完成认证。
|
||||
</ParamField>
|
||||
<ParamField path="apiKey" type='string | { source, provider, id }'>
|
||||
为声明 `metadata.openclaw.primaryEnv` 的 Skills 提供便利。支持明文或 SecretRef。
|
||||
供声明 `metadata.openclaw.primaryEnv` 的 Skills 使用的便捷配置。支持明文或 SecretRef。
|
||||
</ParamField>
|
||||
<ParamField path="env" type="Record<string, string>">
|
||||
仅当进程中尚未设置该变量时才会注入。
|
||||
仅在进程中尚未设置该变量时注入。
|
||||
</ParamField>
|
||||
<ParamField path="config" type="object">
|
||||
用于自定义每个 Skill 字段的可选容器。自定义键必须放在这里。
|
||||
</ParamField>
|
||||
<ParamField path="allowBundled" type="string[]">
|
||||
仅适用于**内置** Skills 的可选允许列表。如果设置,只有列表中的内置 Skills 才符合条件(托管/工作区 Skills 不受影响)。
|
||||
仅用于**内置** Skills 的可选允许列表。如果已设置,只有列表中的内置 Skills 符合条件(受管/工作区 Skills 不受影响)。
|
||||
</ParamField>
|
||||
|
||||
如果 Skill 名称包含连字符,请给键加引号(JSON5 允许带引号的键)。
|
||||
配置键默认匹配 **Skill 名称**。如果某个 Skill 定义了
|
||||
`metadata.openclaw.skillKey`,请在 `skills.entries` 下使用该键。
|
||||
如果 Skill 名称包含连字符,请给键加引号(JSON5 允许带引号的键)。配置键默认匹配 **Skill 名称**,如果某个 Skill 定义了 `metadata.openclaw.skillKey`,请在 `skills.entries` 下使用该键。
|
||||
|
||||
<Note>
|
||||
在 OpenClaw 内部进行原生图像生成/编辑时,请使用核心
|
||||
`image_generate` 工具搭配 `agents.defaults.imageGenerationModel`,
|
||||
而不是使用内置 Skill。这里的 Skill 示例适用于自定义或第三方
|
||||
工作流。对于原生图像分析,请使用 `image` 工具搭配
|
||||
`agents.defaults.imageModel`。如果你选择 `openai/*`、`google/*`、
|
||||
`fal/*` 或其他特定提供商的图像模型,也要添加该提供商的
|
||||
auth/API key。
|
||||
对于 OpenClaw 内部的常规图像生成/编辑,请使用核心
|
||||
`image_generate` 工具和 `agents.defaults.imageGenerationModel`,
|
||||
而不是内置 Skill。这里的 Skill 示例适用于自定义或第三方工作流。对于原生图像分析,请使用
|
||||
`image` 工具和 `agents.defaults.imageModel`。如果你选择 `openai/*`、`google/*`、
|
||||
`fal/*` 或其他特定提供商的图像模型,也要添加该提供商的认证/API key。
|
||||
</Note>
|
||||
|
||||
## 环境注入
|
||||
@ -328,32 +324,32 @@ auth/API key。
|
||||
当智能体运行开始时,OpenClaw 会:
|
||||
|
||||
1. 读取 Skill 元数据。
|
||||
2. 将 `skills.entries.<key>.env` 和 `skills.entries.<key>.apiKey` 应用到 `process.env`。
|
||||
3. 使用**符合条件**的 Skills 构建系统提示词。
|
||||
2. 将 `skills.entries.<key>.env` 和 `skills.entries.<key>.apiKey` 应用于 `process.env`。
|
||||
3. 使用**符合条件的** Skills 构建系统提示词。
|
||||
4. 在运行结束后恢复原始环境。
|
||||
|
||||
环境注入的作用域是**智能体运行**,不是全局 shell 环境。
|
||||
环境注入**限定在智能体运行范围内**,不是全局 shell 环境。
|
||||
|
||||
对于内置的 `claude-cli` 后端,OpenClaw 还会将同一个符合条件的快照实体化为临时 Claude Code 插件,并通过
|
||||
`--plugin-dir` 传入。随后 Claude Code 可以使用其原生 Skill 解析器,而
|
||||
OpenClaw 仍然负责优先级、按智能体允许列表、门控,以及
|
||||
对于内置 `claude-cli` 后端,OpenClaw 还会将同一个符合条件的快照物化为临时 Claude Code 插件,并通过
|
||||
`--plugin-dir` 传递。随后 Claude Code 可以使用其原生 Skill 解析器,同时
|
||||
OpenClaw 仍然负责优先级、每个智能体的允许列表、门控,以及
|
||||
`skills.entries.*` 环境/API key 注入。其他 CLI 后端只使用提示词目录。
|
||||
|
||||
## 快照与刷新
|
||||
## 快照和刷新
|
||||
|
||||
OpenClaw 会在**会话开始时**快照符合条件的 Skills,并在同一会话的后续轮次中复用该列表。对
|
||||
Skills 或配置的更改会在下一个新会话生效。
|
||||
Skills 或配置的更改会在下一个新会话中生效。
|
||||
|
||||
Skills 可以在两种情况下于会话中途刷新:
|
||||
Skills 可以在会话中途在两种情况下刷新:
|
||||
|
||||
- Skills 监视器已启用。
|
||||
- 出现新的符合条件的远程节点。
|
||||
|
||||
可以把它理解为**热重载**:刷新后的列表会在下一次智能体轮次中被采用。如果该会话的有效智能体 Skill 允许列表发生变化,OpenClaw 会刷新快照,让可见 Skills 与当前智能体保持一致。
|
||||
可以把它看作一次**热重载**:刷新的列表会在下一次智能体轮次中被使用。如果该会话的有效智能体 Skill 允许列表发生变化,OpenClaw 会刷新快照,使可见 Skills 与当前智能体保持一致。
|
||||
|
||||
### Skills 监视器
|
||||
|
||||
默认情况下,OpenClaw 会监视 Skill 文件夹,并在 `SKILL.md` 文件变化时更新 Skills 快照。请在 `skills.load` 下配置:
|
||||
默认情况下,OpenClaw 会监视 Skill 文件夹,并在 `SKILL.md` 文件变化时提升 Skills 快照版本。在 `skills.load` 下配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -369,36 +365,36 @@ Skills 可以在两种情况下于会话中途刷新:
|
||||
### 远程 macOS 节点(Linux Gateway 网关)
|
||||
|
||||
如果 Gateway 网关运行在 Linux 上,但连接了一个允许
|
||||
`system.run` 的 **macOS 节点**(Exec approvals 安全设置未设为 `deny`),
|
||||
当所需二进制文件存在于该节点上时,OpenClaw 可以将仅限 macOS 的 Skills 视为符合条件。智能体应通过 `exec` 工具并使用 `host=node` 来执行这些 Skills。
|
||||
`system.run` 的 **macOS 节点**(Exec approvals security 未设置为 `deny`),
|
||||
那么当所需二进制文件存在于该节点上时,OpenClaw 可以将仅限 macOS 的 Skills 视为符合条件。智能体应通过
|
||||
`exec` 工具并使用 `host=node` 执行这些 Skills。
|
||||
|
||||
这依赖于节点报告其命令支持,并通过 `system.which` 或 `system.run` 进行二进制探测。离线节点**不会**让仅远程可用的 Skills 可见。如果某个已连接节点停止响应二进制探测,OpenClaw 会清除其缓存的二进制匹配结果,这样智能体就不再看到当前无法在该处运行的 Skills。
|
||||
这依赖于节点上报其命令支持情况,并通过 `system.which` 或 `system.run` 进行二进制探测。离线节点**不会**让仅远程可用的 Skills 可见。如果已连接节点不再响应二进制探测,OpenClaw 会清除其缓存的二进制匹配结果,使智能体不再看到当前无法在那里运行的 Skills。
|
||||
|
||||
## Token 影响
|
||||
|
||||
当 Skills 符合条件时,OpenClaw 会将可用 Skills 的紧凑 XML 列表注入系统提示词(通过 `pi-coding-agent` 中的 `formatSkillsForPrompt`)。成本是确定性的:
|
||||
当 Skills 符合条件时,OpenClaw 会向系统提示词注入一个紧凑的可用
|
||||
Skills XML 列表(通过 `pi-coding-agent` 中的 `formatSkillsForPrompt`)。成本是确定性的:
|
||||
|
||||
- **基础开销**(仅当 ≥1 个 Skill 时):195 个字符。
|
||||
- **每个 Skill:**97 个字符 + XML 转义后的 `<name>`、`<description>` 和 `<location>` 值长度。
|
||||
- **每个 Skill:**97 个字符 + XML 转义后的 `<name>`、`<description>` 和 `<location>` 值的长度。
|
||||
|
||||
公式(字符):
|
||||
公式(字符数):
|
||||
|
||||
```text
|
||||
total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))
|
||||
```
|
||||
|
||||
XML 转义会将 `& < > " '` 扩展为实体(`&`、`<` 等),
|
||||
从而增加长度。Token 数会随模型分词器而变化。按粗略的
|
||||
OpenAI 风格估算约为 4 字符/token,因此每个 Skill 的 **97 字符 ≈ 24 tokens**,再加上实际字段长度。
|
||||
XML 转义会将 `& < > " '` 扩展为实体(`&`、`<` 等),从而增加长度。Token 数会因模型分词器而异。粗略的
|
||||
OpenAI 风格估算是约 4 字符/token,因此**每个 Skill 97 字符 ≈ 24 tokens**,再加上你的实际字段长度。
|
||||
|
||||
## 托管 Skills 生命周期
|
||||
## 受管 Skills 生命周期
|
||||
|
||||
OpenClaw 会随安装(npm 包或 OpenClaw.app)提供一组基线 Skills 作为**内置 Skills**。`~/.openclaw/skills` 用于本地覆盖,例如在不更改内置副本的情况下固定或修补某个 Skill。工作区 Skills 由用户拥有,并会在名称冲突时覆盖前两者。
|
||||
OpenClaw 会随安装(npm 包或 OpenClaw.app)提供一组基线 Skills,作为**内置 Skills**。`~/.openclaw/skills` 用于本地覆盖,例如在不更改内置副本的情况下固定或修补某个 Skill。工作区 Skills 归用户所有,并会在名称冲突时覆盖前两者。
|
||||
|
||||
## 想找更多 Skills?
|
||||
|
||||
浏览 [https://clawhub.ai](https://clawhub.ai)。完整配置
|
||||
schema:[Skills 配置](/zh-CN/tools/skills-config)。
|
||||
浏览 [https://clawhub.ai](https://clawhub.ai)。完整配置架构:[Skills 配置](/zh-CN/tools/skills-config)。
|
||||
|
||||
## 相关
|
||||
|
||||
@ -407,4 +403,4 @@ schema:[Skills 配置](/zh-CN/tools/skills-config)。
|
||||
- [插件](/zh-CN/tools/plugin) — 插件系统概览
|
||||
- [Skill Workshop 插件](/zh-CN/plugins/skill-workshop) — 从智能体工作生成 Skills
|
||||
- [Skills 配置](/zh-CN/tools/skills-config) — Skill 配置参考
|
||||
- [Slash commands](/zh-CN/tools/slash-commands) — 所有可用的 slash commands
|
||||
- [斜杠命令](/zh-CN/tools/slash-commands) — 所有可用斜杠命令
|
||||
|
||||
Loading…
Reference in New Issue
Block a user