- 每个套件覆盖什么内容(以及它刻意不覆盖什么)。
- 常见工作流(本地、pre-push、调试)该运行哪些命令。
- live 测试如何发现凭证并选择模型/提供方。
- 如何为真实世界的模型/提供方问题添加回归测试。
快速开始
大多数时候:- 完整门禁(推送前预期运行):
pnpm build && pnpm check && pnpm check:test-types && pnpm test - 在资源充足的机器上更快的本地全套运行:
pnpm test:max - 直接的 Vitest watch 循环:
pnpm test:watch - 直接指定文件现在也会路由 extension/channel 路径:
pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts - 在迭代单个失败时,优先先做定向运行。
- Docker 版 QA site:
pnpm qa:lab:up - Linux VM 版 QA lane:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
- 覆盖率门禁:
pnpm test:coverage - E2E 套件:
pnpm test:e2e
- Live 套件(模型 + gateway 工具/图像探针):
pnpm test:live - Quiet 地定位单个 live 文件:
pnpm test:live -- src/agents/models.profiles.live.test.ts - 运行时性能报告:带上
live_openai_candidate=true触发OpenClaw Performance,用于一次真实的openai/gpt-5.5agent 回合,或带上deep_profile=true获取 Kova 的 CPU/heap/trace 产物。每日定时运行会在 配置了CLAWGRIT_REPORTS_TOKEN时,将 mock-provider、deep-profile 和 GPT 5.5 lane 产物发布到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或OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0禁用额外探针。 - CI 覆盖:每日的
OpenClaw Scheduled Live And E2E Checks和手动的OpenClaw Release Checks都会调用可复用的 live/E2E workflow,并设置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 调用方中。
- 每个被选中的模型现在都会运行一次文本回合,以及一个小型文件读取探针。
元数据声明
- 原生 Codex 绑定聊天冒烟:
pnpm test:docker:live-codex-bind- 在 Docker live lane 中针对 Codex app-server 路径运行,绑定一个合成的 Slack DM 与
/codex bind,执行/codex fast和/codex permissions,然后验证普通回复和图像附件是否通过原生插件绑定而不是 ACP 路由。
- 在 Docker live lane 中针对 Codex app-server 路径运行,绑定一个合成的 Slack DM 与
- Codex app-server harness 冒烟:
pnpm test:docker:live-codex-harness- 通过插件拥有的 Codex app-server harness 运行 gateway agent 回合,验证
/codex status和/codex models,并且默认会探测图像、cron MCP、sub-agent 和 Guardian。为隔离其他 Codex app-server 故障时,可通过OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0禁用 sub-agent 探针。若要做聚焦的 sub-agent 检查,可关闭其他探针: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,否则它会在 sub-agent 探针后退出。
- 通过插件拥有的 Codex app-server harness 运行 gateway agent 回合,验证
- Codex 按需安装冒烟:
pnpm test:docker:codex-on-demand- 在 Docker 中安装打包后的 OpenClaw tarball,运行 OpenAI API key onboarding,并验证 Codex 插件和
@openai/codex依赖已按需下载到受管的 npm project root。
- 在 Docker 中安装打包后的 OpenClaw tarball,运行 OpenAI API key onboarding,并验证 Codex 插件和
- Live 插件工具依赖冒烟:
pnpm test:docker:live-plugin-tool- 打包一个带有真实
slugify依赖的 fixture 插件,通过npm-pack:安装,验证受管 npm project root 下的依赖,然后让一个 live OpenAI 模型调用该插件工具并返回隐藏的 slug。
- 打包一个带有真实
- Crestodian rescue 命令冒烟:
pnpm test:live:crestodian-rescue-channel- 面向消息通道 rescue 命令 surface 的可选“保险带+保险绳”检查。它会执行
/crestodian status、排队一个持久化的模型变更、回复/crestodian yes,并验证审计/config 写入路径。
- 面向消息通道 rescue 命令 surface 的可选“保险带+保险绳”检查。它会执行
- Crestodian planner Docker 冒烟:
pnpm test:docker:crestodian-planner- 在一个无配置容器中运行 Crestodian,
PATH上带一个假的 Claude CLI,并验证模糊 planner fallback 能转换为一次经过审计的 typed config 写入。
- 在一个无配置容器中运行 Crestodian,
- Crestodian 首次运行 Docker 冒烟:
pnpm test:docker:crestodian-first-run- 从一个空的 OpenClaw state dir 开始,验证现代化的 onboard Crestodian 入口点,应用 setup/model/agent/Discord plugin + SecretRef 写入,校验 config,并验证审计记录。同一条 Ring 0 setup 路径也在 QA Lab 中通过
pnpm openclaw qa suite --scenario crestodian-ring-zero-setup覆盖。
- 从一个空的 OpenClaw state dir 开始,验证现代化的 onboard Crestodian 入口点,应用 setup/model/agent/Discord plugin + SecretRef 写入,校验 config,并验证审计记录。同一条 Ring 0 setup 路径也在 QA Lab 中通过
- 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。验证 JSON 报告 Moonshot/K2.6,并且 assistant transcript 存储了归一化的usage.cost。
QA 专用运行器
当你需要更接近 QA-lab 真实环境时,这些命令可与主测试套件并列使用: CI 会在专门的工作流中运行 QA Lab。Agentic parity 嵌套在QA-Lab - All Lanes 和 release validation 之下,而不是一个独立的 PR 工作流。
广泛验证应使用 Full Release Validation 并设置
rerun_group=qa-parity,或使用 release-checks QA group。稳定/默认 release
checks 会通过 run_release_soak=true 保留完整的 live/Docker soak;
full profile 会强制开启 soak。QA-Lab - All Lanes
在 main 分支上每晚运行,并可通过手动触发运行 mock parity lane、live
Matrix lane、Convex 托管的 live Telegram lane,以及 Convex 托管的 live Discord
lane,作为并行作业。Scheduled QA 和 release checks 会显式传入 Matrix
--profile fast,而 Matrix CLI 与手动 workflow 输入的默认值仍然是 all;手动触发可以把 all 分片成 transport、
media、e2ee-smoke、e2ee-deep 和 e2ee-cli 作业。OpenClaw Release Checks 在发布批准前会先运行 parity、fast Matrix 和 Telegram lanes,并使用
mock-openai/gpt-5.5 执行 release transport checks,使其保持确定性并避免正常的提供方插件启动。这些 live transport
gateway 会禁用 memory search;memory 行为仍由 QA parity 套件覆盖。
完整的发布 live media 分片使用
ghcr.io/openclaw/openclaw-live-media-runner:ubuntu-24.04,其中已包含
ffmpeg 和 ffprobe。Docker live 模型/backend 分片使用共享的
ghcr.io/openclaw/openclaw-live-test:<sha> 镜像,该镜像针对所选提交只构建一次,
然后通过 OPENCLAW_SKIP_DOCKER_BUILD=1 拉取,而不是在每个分片内重新构建。
pnpm openclaw qa suite- 直接在主机上运行仓库支持的 QA 场景。
- 默认使用隔离的 gateway worker 并行运行多个已选场景。
qa-channel默认并发为 4(受所选场景数量限制)。使用--concurrency <count>调整 worker 数量,或使用--concurrency 1进入旧的串行 lane。 - 当任一场景失败时以非零退出。若想保留产物但不以失败码退出,可使用
--allow-failures。 - 支持提供方模式
live-frontier、mock-openai和aimock。aimock会启动一个本地、基于 AIMock 的提供方服务器,用于实验性 fixture 和协议 mock 覆盖,而不会替代具备场景感知的mock-openailane。
pnpm openclaw qa coverage --match <query>- 搜索场景 ID、标题、surface、coverage ID、文档引用、代码引用、插件和提供方要求,然后打印匹配的 suite 目标。
- 当你知道受影响的行为或文件路径,但不知道最小场景时,在运行 QA Lab 之前先用它。它仅供参考;仍然应根据被修改的行为选择 mock、live、Multipass、Matrix 或 transport proof。
pnpm test:plugins:kitchen-sink-live- 通过 QA Lab 运行 live OpenAI Kitchen Sink plugin gauntlet。它会安装外部 Kitchen Sink 包,验证插件 SDK surface inventory,探测
/healthz和/readyz,记录 gateway CPU/RSS 证据,运行一次 live OpenAI 轮次,并检查 adversarial diagnostics。 需要 live OpenAI 认证,例如OPENAI_API_KEY。在已注入凭证的 Testbox 会话中,当存在openclaw-testbox-envhelper 时,它会自动加载 Testbox live-auth profile。
- 通过 QA Lab 运行 live OpenAI Kitchen Sink plugin gauntlet。它会安装外部 Kitchen Sink 包,验证插件 SDK surface inventory,探测
pnpm test:gateway:cpu-scenarios- 运行 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 占满回归。 - 使用已构建的
dist产物;如果 checkout 中还没有新的运行时输出,请先执行 build。
- 运行 gateway 启动基准测试以及一小组 mock QA Lab 场景包
(
pnpm openclaw qa suite --runner multipass- 在一个可丢弃的 Multipass Linux VM 中运行相同的 QA suite。
- 保持与主机上的
qa suite相同的场景选择行为。 - 复用与
qa suite相同的 provider/model 选择标志。 - live 运行会转发对 guest 实用的受支持 QA auth 输入:
基于环境变量的提供方密钥、QA live provider 配置路径,以及存在时的
CODEX_HOME。 - 输出目录必须保留在仓库根目录下,以便 guest 能通过挂载的工作区回写。
- 在
.artifacts/qa-e2e/...下写入常规 QA 报告 + 摘要以及 Multipass 日志。
pnpm qa:lab:up- 启动 Docker 版 QA site,用于操作员式 QA 工作。
pnpm test:docker:npm-onboard-channel-agent- 从当前 checkout 打包并安装一个 npm tarball 到 Docker 中,全局安装,运行非交互式 OpenAI API key onboarding,默认配置 Telegram,验证打包后的插件运行时能在无需启动时依赖修复的情况下加载,运行 doctor,并针对一个 mocked OpenAI 端点执行一次本地 agent 轮次。
- 使用
OPENCLAW_NPM_ONBOARD_CHANNEL=discord可用 Discord 运行相同的已打包安装 lane。
pnpm test:docker:session-runtime-context- 为嵌入式 runtime context transcript 运行一个确定性的 built-app Docker 冒烟。
它验证隐藏的 OpenClaw runtime context 会以不可显示的自定义消息形式持久化,而不会泄露到可见的用户轮次中,
然后构造一个受影响的损坏 session JSONL,并验证
openclaw doctor --fix会将其重写到当前分支并带有备份。
- 为嵌入式 runtime context transcript 运行一个确定性的 built-app Docker 冒烟。
它验证隐藏的 OpenClaw runtime context 会以不可显示的自定义消息形式持久化,而不会泄露到可见的用户轮次中,
然后构造一个受影响的损坏 session JSONL,并验证
pnpm test:docker:npm-telegram-live- 在 Docker 中安装一个 OpenClaw package 候选版本,运行已安装包的 onboarding,通过已安装的 CLI 配置 Telegram,然后复用 live Telegram QA lane,将该已安装包作为 SUT Gateway。
- 包装器只从 checkout 挂载
qa-labharness 源码;已安装包拥有dist、openclaw/plugin-sdk和 bundled plugin runtime,因此该 lane 不会把当前 checkout 的插件混入被测包中。 - 默认值为
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/release 自动化时,设置OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex,再加上OPENCLAW_QA_CONVEX_SITE_URL和角色密钥。如果OPENCLAW_QA_CONVEX_SITE_URL和一个 Convex 角色密钥在 CI 中可用, Docker 包装器会自动选择 Convex。 - 包装器会在 Docker build/install 之前先在主机上验证 Telegram 或 Convex 凭证环境。仅在你明确调试凭证前置步骤时才设置
OPENCLAW_NPM_TELEGRAM_SKIP_CREDENTIAL_PREFLIGHT=1。 OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer仅为此 lane 覆盖共享的OPENCLAW_QA_CREDENTIAL_ROLE。- GitHub Actions 将此 lane 作为手动维护者工作流
NPM Telegram Beta E2E暴露。它不会在合并时运行。该 workflow 使用qa-live-shared环境和 Convex CI 凭证租约。
- GitHub Actions 还提供
Package Acceptance,用于针对单个候选包做旁路产品证明。它接受受信任的 ref、已发布的 npm spec、HTTPS tarball URL 加 SHA-256,或来自其他 run 的 tarball artifact,上传规范化后的openclaw-current.tgz作为package-under-test,然后运行现有的 Docker E2E 调度器,使用 smoke、package、product、full 或 custom lane profiles。设置telegram_mode=mock-openai或live-frontier可针对同一package-under-testartifact 运行 Telegram QA workflow。- 最新 beta 产品证明:
- 精确 tarball URL 证明需要摘要值,并使用公共 URL 安全策略:
- 企业/私有 tarball 镜像使用显式的受信任源策略:
source=trusted-url 会从受信任的 workflow ref 读取 .github/package-trusted-sources.json,且不接受 URL 凭证或 workflow 输入的私有网络绕过。如果命名策略声明了 bearer auth,请配置固定的 OPENCLAW_TRUSTED_PACKAGE_TOKEN 密钥。
- Artifact 证明会从另一个 Actions run 下载 tarball artifact:
-
pnpm test:docker:plugins- 在 Docker 中打包并安装当前 OpenClaw 构建,使用已配置 OpenAI 启动 Gateway,然后通过配置编辑启用随包附带的 channel/plugins。
- 验证 setup discovery 不会显示未配置的可下载插件,第一次配置后的 doctor 修复会显式安装每个缺失的可下载插件,第二次重启不会运行隐藏的依赖修复。
- 还会安装一个已知的旧 npm 基线,在运行
openclaw update --tag <candidate>之前启用 Telegram,并验证候选版本更新后的 doctor 会清理旧版插件依赖残留,而不会在 harness 侧进行 postinstall 修复。
-
pnpm test:parallels:npm-update-
在 Parallels guest 上运行原生打包安装更新冒烟。每个被选中的平台会先安装所请求的基线包,然后在同一个 guest 中运行已安装的
openclaw update命令,并验证已安装版本、更新状态、gateway 就绪状态以及一次本地 agent 轮次。 -
在只迭代一个 guest 时,使用
--platform macos、--platform windows或--platform linux。使用--json获取摘要 artifact 路径和每个 lane 的状态。 -
默认情况下,OpenAI lane 会使用
openai/gpt-5.5作为 live agent-turn 验证。若要刻意验证其他 OpenAI 模型,请传入--model <provider/model>或设置OPENCLAW_PARALLELS_OPENAI_MODEL。 -
将较长的本地运行包裹在 host timeout 中,以免 Parallels 传输卡住而耗尽剩余测试窗口:
-
该脚本会在
/tmp/openclaw-parallels-npm-update.*下写入嵌套的 lane 日志。 在假定外层包装器卡住之前,请检查windows-update.log、macos-update.log或linux-update.log。 - Windows 更新在冷 guest 上的 post-update doctor 和 package update 工作中可能会花费 10 到 15 分钟;只要嵌套的 npm debug log 还在前进,这仍然是正常的。
- 不要将此聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟 lanes 并行运行。它们共享 VM 状态,可能在 snapshot restore、package serving 或 guest gateway state 上发生冲突。
- post-update 证明会运行正常的 bundled plugin surface,因为像 speech、image generation 和 media understanding 这样的 capability facades 即使在 agent 轮次本身只检查简单文本回复时,也会通过 bundled runtime APIs 加载。
-
在 Parallels guest 上运行原生打包安装更新冒烟。每个被选中的平台会先安装所请求的基线包,然后在同一个 guest 中运行已安装的
-
pnpm openclaw qa aimock- 仅启动本地 AIMock 提供方服务器,用于直接的协议冒烟测试。
-
pnpm openclaw qa matrix- 在一个可丢弃的、由 Docker 支持的 Tuwunel homeserver 上运行 Matrix live QA lane。仅限源码 checkout——已打包安装不包含
qa-lab。 - 完整 CLI、profile/scenario 目录、环境变量和产物布局: Matrix QA。
- 在一个可丢弃的、由 Docker 支持的 Tuwunel homeserver 上运行 Matrix live QA lane。仅限源码 checkout——已打包安装不包含
-
pnpm openclaw qa telegram- 使用来自环境变量的 driver 和 SUT bot tokens,在真实私有群组上运行 Telegram live QA lane。
- 需要
OPENCLAW_QA_TELEGRAM_GROUP_ID、OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN和OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN。group id 必须是数字形式的 Telegram chat id。 - 支持
--credential-source convex以使用共享的池化凭证。默认使用 env 模式,或设置OPENCLAW_QA_CREDENTIAL_SOURCE=convex以启用池化租约。 - 默认覆盖 canary、mention gating、command addressing、
/status、bot-to-bot mentioned replies,以及核心 native command replies。mock-openai默认值还覆盖确定性的 reply-chain 和 Telegram final-message streaming 回归。使用--list-scenarios查看可选探针,例如session_status。 - 当任一场景失败时退出非零。想保留产物但不以失败码退出时使用
--allow-failures。 - 需要同一个私有群组中的两个不同机器人,并且 SUT bot 必须暴露 Telegram username。
- 为了稳定地观察 bot-to-bot 行为,请在两个机器人上都于
@BotFather启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观察群组机器人流量。 - 在
.artifacts/qa-e2e/...下写入 Telegram QA 报告、摘要以及 observed-messages 产物。回复类场景会包含从 driver 发送请求到观察到 SUT 回复的 RTT。
Mantis Telegram Live 是此 lane 的 PR 证据包装器。它会使用 Convex 租用的 Telegram 凭证运行候选 ref,在 Crabbox 桌面浏览器中渲染脱敏后的 observed-message 转录,录制 MP4 证据,生成 motion-trim GIF,上传产物包,并在设置了 pr_number 时通过 Mantis GitHub App 以内联方式发布 PR 证据。维护者可以通过 Actions UI 中的 Mantis Scenario(scenario_id: telegram-live)启动它,或直接在 pull request 评论中触发:
Mantis Telegram Desktop Proof 是用于 PR 可视化证据的 agentic 原生 Telegram Desktop before/after 包装器。可以通过 Actions UI 传入自由格式的 instructions 启动,或通过 Mantis Scenario(scenario_id: telegram-desktop-proof)启动,或者通过 PR 评论启动:
motionPreview 清单,并在设置了 pr_number 时通过 Mantis GitHub App 发布同样的双栏 GIF 表格。
pnpm openclaw qa mantis telegram-desktop-builder- 租用或复用一个 Crabbox Linux 桌面,安装原生 Telegram Desktop,使用租用的 Telegram SUT bot token 配置 OpenClaw,启动 gateway,并从可见的 VNC 桌面录制截图/MP4 证据。
- 默认使用
--credential-source convex,因此工作流只需要 Convex broker secret。配合pnpm openclaw qa telegram相同的OPENCLAW_QA_TELEGRAM_*变量时,使用--credential-source env。 - Telegram Desktop 仍需要用户登录/配置文件。bot token 只用于配置 OpenClaw。使用
--telegram-profile-archive-env <name>传入 base64 的.tgz配置文件归档,或使用--keep-lease并通过 VNC 手动登录一次。 - 在输出目录下写入
mantis-telegram-desktop-builder-report.md、mantis-telegram-desktop-builder-summary.json、telegram-desktop-builder.png和telegram-desktop-builder.mp4。
qa-channel 是更广泛的合成套件,不属于该矩阵。
通过 Convex 共享 Telegram 凭证(v1)
当--credential-source convex(或 OPENCLAW_QA_CREDENTIAL_SOURCE=convex)为 live transport QA 启用时,QA lab 会从一个由 Convex 支持的池中获取独占租约,在 lane 运行期间对该租约发送心跳,并在关闭时释放租约。该节名称早于 Discord、Slack 和 WhatsApp 支持;租约契约在各类之间是共享的。
参考 Convex 项目骨架:
qa/convex-credential-broker/
OPENCLAW_QA_CONVEX_SITE_URL(例如https://your-deployment.convex.site)- 针对所选角色的一个密钥:
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER对应maintainerOPENCLAW_QA_CONVEX_SECRET_CI对应ci
- 凭证角色选择:
- CLI:
--credential-role maintainer|ci - 环境默认值:
OPENCLAW_QA_CREDENTIAL_ROLE(CI 中默认为ci,否则默认为maintainer)
- CLI:
OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS(默认1200000)OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS(默认30000)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(可选 trace id)OPENCLAW_QA_ALLOW_INSECURE_HTTP=1允许仅用于本地开发的 loopbackhttp://Convex URL。
OPENCLAW_QA_CONVEX_SITE_URL 在正常运行中应使用 https://。
维护者管理命令(pool add/remove/list)需要
OPENCLAW_QA_CONVEX_SECRET_MAINTAINER。
面向维护者的 CLI 辅助命令:
doctor 检查 Convex site URL、broker 密钥、
endpoint prefix、HTTP timeout 以及 admin/list 可达性,而不会打印
密钥值。脚本和 CI 工具中可使用 --json 以获得机器可读输出。
默认 endpoint 契约(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", ... }
- 请求:
POST /payload-chunk- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken, index } - 成功:
{ status: "ok", index, data }
- 请求:
POST /heartbeat- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs } - 成功:
{ status: "ok" }(或空的2xx)
- 请求:
POST /release- 请求:
{ kind, ownerId, actorRole, credentialId, leaseToken } - 成功:
{ status: "ok" }(或空的2xx)
- 请求:
POST /admin/add(仅 maintainer 密钥)- 请求:
{ kind, actorId, payload, note?, status? } - 成功:
{ status: "ok", credential }
- 请求:
POST /admin/remove(仅 maintainer 密钥)- 请求:
{ credentialId, actorId } - 成功:
{ status: "ok", changed, credential } - 活跃租约保护:
{ status: "error", code: "LEASE_ACTIVE", ... }
- 请求:
POST /admin/list(仅 maintainer 密钥)- 请求:
{ kind?, status?, includePayload?, limit? } - 成功:
{ status: "ok", credentials, count }
- 请求:
{ groupId: string, driverToken: string, sutToken: string }groupId必须是数字形式的 Telegram chat id 字符串。admin/add会校验kind: "telegram"的该结构,并拒绝格式错误的 payload。
{ groupId: string, sutToken: string, testerUserId: string, testerUsername: string, telegramApiId: string, telegramApiHash: string, tdlibDatabaseEncryptionKey: string, tdlibArchiveBase64: string, tdlibArchiveSha256: string, desktopTdataArchiveBase64: string, desktopTdataArchiveSha256: string }groupId、testerUserId和telegramApiId必须是数字字符串。tdlibArchiveSha256和desktopTdataArchiveSha256必须是 SHA-256 十六进制字符串。kind: "telegram-user"为 Mantis Telegram Desktop proof 工作流保留。通用 QA Lab lanes 不得获取它。
- Discord:
{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string, voiceChannelId?: string } - WhatsApp:
{ driverPhoneE164: string, sutPhoneE164: string, driverAuthArchiveBase64: string, sutAuthArchiveBase64: string, groupJid?: string }
{ channelId: string, driverBotToken: string, sutBotToken: string, sutAppToken: string }。
向 QA 添加一个 channel
新 channel adapter 的架构和 scenario-helper 名称位于 QA 概览 → 添加一个 channel。最低要求:在共享的qa-lab host seam 上实现传输运行器,在插件清单中声明 qaRunners,通过 openclaw qa <runner> 挂载,并在 qa/scenarios/ 下编写场景。
测试套件(在哪运行什么)
将这些套件看作“越来越接近真实环境”(同时也越来越不稳定/昂贵):单元 / 集成(默认)
- 命令:
pnpm test - 配置:未定向运行会使用
vitest.full-*.config.ts分片集合,并可能将多项目分片展开为按项目配置,以便并行调度 - 文件:
src/**/*.test.ts、packages/**/*.test.ts和test/**/*.test.ts下的核心/单元清单;UI 单元测试在专用的unit-ui分片中运行 - 范围:
- 纯单元测试
- 进程内集成测试(网关认证、路由、工具、解析、配置)
- 已知缺陷的确定性回归测试
- 预期:
- 在 CI 中运行
- 不需要真实密钥
- 应该快速且稳定
- 解析器和公共表面加载器测试必须通过生成的微型插件夹具,证明广泛的
api.js和runtime-api.js回退行为,而不是依赖真实打包后的插件源码 API。真实插件 API 加载应归入 由插件拥有的契约/集成套件。
- 默认测试安装会跳过可选的原生 Discord opus 构建。Discord 语音使用捆绑的
libopus-wasm,而@discordjs/opus会在allowBuilds中保持禁用,因此本地测试和 Testbox 通道不会编译原生插件。 - 请在
libopus-wasm基准仓库中比较原生 opus 性能,不要在默认的 OpenClaw 安装/测试循环中比较。不要在默认的allowBuilds中将@discordjs/opus设为true;那样会让无关的安装/测试循环编译原生代码。
项目、分片与受限通道
项目、分片与受限通道
- 未定向的
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文件、显式源码映射,以及本地导入图依赖项。除非你显式使用OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed,否则配置/设置/包的编辑不会广泛运行测试。pnpm check:changed是窄范围工作的常规智能本地检查门禁。它会将差异分类为核心、核心测试、扩展、扩展测试、应用、文档、发布元数据、实时 Docker 工具以及工具,然后运行匹配的类型检查、lint 和守卫命令。它不会运行 Vitest 测试;如需测试证明,请调用pnpm test:changed或显式pnpm test <target>。仅发布元数据的版本提升会运行定向的版本/配置/根依赖检查,并带有一个守卫,用于拒绝除顶层 version 字段之外的 package 变更。- 实时 Docker ACP 运行器编辑会运行聚焦检查:实时 Docker 认证脚本的 shell 语法,以及实时 Docker 调度器的 dry-run。只有当差异仅限于
scripts["test:docker:live-*"]时才包含package.json变更;依赖、导出、版本以及其他包表面编辑仍然使用更宽的守卫。 - 来自 agents、commands、plugins、auto-reply helpers、
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分片。完整发布验证会在发布候选版本上为这些偏插件/扩展的套件单独触发Plugin Prerelease子工作流。
嵌入式运行器覆盖
嵌入式运行器覆盖
- 当你更改 message-tool 发现输入或 compaction 运行时上下文时,请保留两层覆盖。
- 为纯路由和归一化边界添加聚焦的辅助回归测试。
- 保持嵌入式运行器集成套件健康:
src/agents/embedded-agent-runner/compact.hooks.test.ts,src/agents/embedded-agent-runner/run.overflow-compaction.test.ts, 和src/agents/embedded-agent-runner/run.overflow-compaction.loop.test.ts。 - 这些套件验证作用域 id 和 compaction 行为仍然通过真实的
run.ts/compact.ts路径流动;仅辅助程序测试不足以替代这些集成路径。
Vitest 池和隔离默认值
Vitest 池和隔离默认值
- 基础 Vitest 配置默认使用
threads。 - 共享 Vitest 配置固定
isolate: false,并在根项目、e2e 和 live 配置中使用 非隔离运行器。 - 根 UI 通道保留其
jsdom设置和优化器,但也运行在 共享的非隔离运行器上。 - 每个
pnpm test分片都会从共享 Vitest 配置继承相同的threads+isolate: false默认值。 scripts/run-vitest.mjs默认会为 Vitest 子 Node 进程添加--no-maglev,以减少大型本地运行期间的 V8 编译抖动。 设置OPENCLAW_VITEST_ENABLE_MAGLEV=1可与原生 V8 行为进行对比。scripts/run-vitest.mjs会在显式的非 watch Vitest 运行中,如果 5 分钟内没有 stdout 或 stderr 输出,就终止进程。设置OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=0可为有意静默的调查禁用此看门狗。
快速本地迭代
快速本地迭代
pnpm changed:lanes会显示某个差异触发了哪些架构通道。- pre-commit 钩子只做格式化。它会重新暂存已格式化的文件, 不会运行 lint、类型检查或测试。
- 在交接或推送前,如果需要智能本地检查门禁,请显式运行
pnpm check:changed。 pnpm test:changed默认会通过廉价的受限通道路由。仅当代理 判断某个运行器、配置、包或契约编辑确实需要更广泛的 Vitest 覆盖时,才使用OPENCLAW_TEST_CHANGED_BROAD=1 pnpm test:changed。pnpm test:max和pnpm test:changed:max保持相同的路由 行为,只是提高了 worker 上限。- 本地 worker 自动缩放是有意保守的,并且在主机负载平均值已经较高时会退让, 因此默认情况下多个并发 Vitest 运行造成的影响更小。
- 基础 Vitest 配置将项目/配置文件标记为
forceRerunTriggers,这样当测试 连接方式变化时,变更模式的重新运行仍然正确。 - 该配置在受支持的主机上保持启用
OPENCLAW_VITEST_FS_MODULE_CACHE;如果你想要 一个用于直接分析的显式缓存位置,可设置OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path。
性能调试
性能调试
pnpm test:perf:imports会启用 Vitest 导入耗时报告以及 导入分解输出。pnpm test:perf:imports:changed会将相同的分析视图限定到 自origin/main以来发生变化的文件。- 分片计时数据会写入
.artifacts/vitest-shard-timings.json。 整体配置运行会使用配置路径作为键;包含模式的 CI 分片会附加分片名称,以便可以分别跟踪过滤后的分片。 - 当某个热点测试仍然把大部分时间花在启动导入上时,
请把重依赖放在一个窄的本地
*.runtime.ts边界之后,并直接 mock 该边界, 而不是深度导入运行时辅助程序只是为了通过vi.mock(...)传递它们。 pnpm test:perf:changed:bench -- --ref <git-ref>会把路由后的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会为禁用文件并行性的单元套件写入运行器 CPU+heap profile。
稳定性(网关)
- 命令:
pnpm test:stability:gateway - 配置:
vitest.gateway.config.ts,强制单 worker - 范围:
- 默认启用诊断并启动一个真实的回环 Gateway
- 通过诊断事件路径驱动合成的网关消息、内存和大负载 churn
- 通过 Gateway WS RPC 查询
diagnostics.stability - 覆盖诊断稳定性 bundle 持久化辅助程序
- 断言记录器保持有界、合成 RSS 样本保持在压力预算之下,并且每个会话的队列深度回落到零
- 预期:
- 对 CI 安全且无需密钥
- 这是用于稳定性回归跟进的窄通道,不是完整 Gateway 套件的替代品
E2E(仓库聚合)
- 命令:
pnpm test:e2e - 范围:
- 运行 gateway smoke E2E 通道
- 运行模拟的 Control UI 浏览器 E2E 通道
- 预期:
- CI 安全且无需密钥
- 需要安装 Playwright Chromium
E2E(gateway smoke)
- 命令:
pnpm test:e2e:gateway - 配置:
vitest.e2e.config.ts - 文件:
src/**/*.e2e.test.ts、test/**/*.e2e.test.ts,以及extensions/下打包插件的 E2E 测试 - 运行时默认值:
- 使用 Vitest
threads且isolate: false,与仓库其余部分一致。 - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。
- 默认以静默模式运行,以降低控制台 I/O 开销。
- 使用 Vitest
- 有用的覆盖项:
OPENCLAW_E2E_WORKERS=<n>用于强制 worker 数量(上限 16)。OPENCLAW_E2E_VERBOSE=1用于重新启用详细控制台输出。
- 范围:
- 多实例 gateway 端到端行为
- WebSocket/HTTP 表面、节点配对,以及更重的网络行为
- 预期:
- 在 CI 中运行(当流水线启用时)
- 不需要真实密钥
- 比单元测试有更多活动部件(可能更慢)
E2E(Control UI 模拟浏览器)
- 命令:
pnpm test:ui:e2e - 配置:
test/vitest/vitest.ui-e2e.config.ts - 文件:
ui/src/**/*.e2e.test.ts - 范围:
- 启动 Vite Control UI
- 通过 Playwright 驱动真实的 Chromium 页面
- 用确定性的浏览器内 mock 替换 Gateway WebSocket
- 预期:
- 作为
pnpm test:e2e的一部分在 CI 中运行 - 不需要真实的 Gateway、agents 或 provider 密钥
- 必须存在浏览器依赖(
pnpm --dir ui exec playwright install chromium)
- 作为
E2E:OpenShell 后端 smoke
- 命令:
pnpm test:e2e:openshell - 文件:
extensions/openshell/src/backend.e2e.test.ts - 范围:
- 通过 Docker 在主机上启动一个隔离的 OpenShell 网关
- 从临时本地 Dockerfile 创建一个沙箱
- 通过真实的
sandbox ssh-config+ SSH exec 测试 OpenClaw 的 OpenShell 后端 - 通过 sandbox fs 桥验证远端规范化的文件系统行为
- 预期:
- 仅可选择启用;不属于默认的
pnpm test:e2e运行 - 需要本地
openshellCLI 以及可用的 Docker 守护进程 - 使用隔离的
HOME/XDG_CONFIG_HOME,然后销毁测试网关和沙箱
- 仅可选择启用;不属于默认的
- 有用的覆盖项:
OPENCLAW_E2E_OPENSHELL=1用于在手动运行更广泛的 e2e 套件时启用该测试OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell用于指向非默认的 CLI 二进制文件或包装脚本
Live(真实提供方 + 真实模型)
- 命令:
pnpm test:live - 配置:
vitest.live.config.ts - 文件:
src/**/*.live.test.ts、test/**/*.live.test.ts,以及extensions/下打包插件的 live 测试 - 默认:由
pnpm test:live启用(会设置OPENCLAW_LIVE_TEST=1) - 范围:
- “这个提供方/模型今天用真实凭据真的能工作吗?”
- 捕获提供方格式变更、工具调用怪癖、认证问题和速率限制行为
- 预期:
- 设计上不稳定于 CI(真实网络、真实提供方策略、配额、故障)
- 会花钱 / 消耗速率限制
- 优先运行缩小后的子集,而不是“全部”
- live 运行使用已导出的 API 密钥和预先配置的认证配置文件。
- 默认情况下,live 运行仍会隔离
HOME,并将配置/认证材料复制到临时测试 home,因此单元夹具不会修改你真实的~/.openclaw。 - 只有当你有意需要 live 测试使用真实 home 目录时,才设置
OPENCLAW_LIVE_USE_REAL_HOME=1。 pnpm test:live默认采用更安静的模式:保留[live] ...进度输出,并静音网关启动日志/Bonjour 交谈。如果你想恢复完整启动日志,可设置OPENCLAW_LIVE_TEST_QUIET=0。- API 密钥轮换(按提供方区分):将
*_API_KEYS设为逗号/分号格式,或使用*_API_KEY_1、*_API_KEY_2(例如OPENAI_API_KEYS、ANTHROPIC_API_KEYS、GEMINI_API_KEYS),也可通过OPENCLAW_LIVE_*_KEY覆盖到单个 live 测试;测试会在速率限制响应后重试。 - 进度/心跳输出:
- live 套件现在会向 stderr 输出进度行,因此即使 Vitest 控制台捕获很安静,较长的提供方调用也会明显处于活跃状态。
vitest.live.config.ts会禁用 Vitest 控制台拦截,因此在 live 运行期间提供方/网关进度行会立即流式输出。- 使用
OPENCLAW_LIVE_HEARTBEAT_MS调整直接模型心跳。 - 使用
OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS调整网关/探针心跳。
我应该运行哪个测试套件?
使用这个决策表:- 编辑逻辑/测试:运行
pnpm test(如果你改动很多,再加上pnpm test:coverage) - 触碰 gateway 网络 / WS 协议 / 配对:再加上
pnpm test:e2e - 调试“我的机器人挂了”/特定提供方失败/工具调用:运行缩小范围的
pnpm test:live
Live(涉及网络)的测试
对于 live 模型矩阵、CLI 后端 smoke、ACP smoke、Codex app-server harness,以及所有媒体提供方 live 测试(Deepgram、BytePlus、ComfyUI、image、music、video、media harness)——外加 live 运行的凭据处理——请参见 Testing live suites。关于专门的更新与 插件验证清单,请参见 Testing updates and plugins。Docker 运行器(可选的“在 Linux 上可用”检查)
这些 Docker 运行器分成两类:- Live-model runners:
test:docker:live-modelsandtest:docker:live-gatewayrun only their matching profile-key live file inside the repo Docker image (src/agents/models.profiles.live.test.tsandsrc/gateway/gateway-models.profiles.live.test.ts), mounting your local config dir, workspace, and optional profile env file. The matching local entrypoints aretest:live:models-profilesandtest:live:gateway-profiles. - Docker live runners keep their own practical caps where needed:
test:docker:live-modelsdefaults to the curated supported high-signal set, andtest:docker:live-gatewaydefaults toOPENCLAW_LIVE_GATEWAY_SMOKE=1,OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8,OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000, andOPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000. SetOPENCLAW_LIVE_MAX_MODELSor the gateway env vars when you explicitly want a smaller cap or larger scan. test:docker:allbuilds the live Docker image once viatest:docker:live-build, packs OpenClaw once as an npm tarball throughscripts/package-openclaw-for-docker.mjs, then builds/reuses twoscripts/e2e/Dockerfileimages. The bare image is only the Node/Git runner for install/update/plugin-dependency lanes; those lanes mount the prebuilt tarball. The functional image installs the same tarball into/appfor built-app functionality lanes. Docker lane definitions live inscripts/lib/docker-e2e-scenarios.mjs; planner logic lives inscripts/lib/docker-e2e-plan.mjs;scripts/test-docker-all.mjsexecutes the selected plan. The aggregate uses a weighted local scheduler:OPENCLAW_DOCKER_ALL_PARALLELISMcontrols process slots, while resource caps keep heavy live, npm-install, and multi-service lanes from all starting at once. If a single lane is heavier than the active caps, the scheduler can still start it when the pool is empty and then keeps it running alone until capacity is available again. Defaults are 10 slots,OPENCLAW_DOCKER_ALL_LIVE_LIMIT=9,OPENCLAW_DOCKER_ALL_NPM_LIMIT=5, andOPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7; tuneOPENCLAW_DOCKER_ALL_WEIGHT_LIMITorOPENCLAW_DOCKER_ALL_DOCKER_LIMITonly when the Docker host has more headroom. The runner performs a Docker preflight by default, removes stale OpenClaw E2E containers, prints status every 30 seconds, stores successful lane timings in.artifacts/docker-tests/lane-timings.json, and uses those timings to start longer lanes first on later runs. UseOPENCLAW_DOCKER_ALL_DRY_RUN=1to print the weighted lane manifest without building or running Docker, ornode scripts/test-docker-all.mjs --plan-jsonto print the CI plan for selected lanes, package/image needs, and credentials.Package Acceptanceis the GitHub-native package gate for “does this installable tarball work as a product?” It resolves one candidate package fromsource=npm,source=ref,source=url, orsource=artifact, uploads it aspackage-under-test, then runs the reusable Docker E2E lanes against that exact tarball instead of repacking the selected ref. Profiles are ordered by breadth:smoke,package,product, andfull. See Testing updates and plugins for the package/update/plugin contract, published-upgrade survivor matrix, release defaults, and failure triage.- Build and release checks run
scripts/check-cli-bootstrap-imports.mjsafter tsdown. The guard walks the static built graph fromdist/entry.jsanddist/cli/run-main.jsand fails if pre-dispatch startup imports package dependencies such as Commander, prompt UI, undici, or logging before command dispatch; it also keeps the bundled gateway run chunk under budget and rejects static imports of known cold gateway paths. Packaged CLI smoke also covers root help, onboard help, doctor help, status, config schema, and a model-list command. - Package Acceptance legacy compatibility is capped at
2026.4.25(2026.4.25-beta.*included). Through that cutoff, the harness tolerates only shipped-package metadata gaps: omitted private QA inventory entries, missinggateway install --wrapper, missing patch files in the tarball-derived git fixture, missing persistedupdate.channel, legacy plugin install-record locations, missing marketplace install-record persistence, and config metadata migration duringplugins update. For packages after2026.4.25, those paths are strict failures. - Container smoke runners:
test:docker:openwebui,test:docker:onboard,test:docker:npm-onboard-channel-agent,test:docker:release-user-journey,test:docker:release-typed-onboarding,test:docker:release-media-memory,test:docker:release-upgrade-user-journey,test:docker:release-plugin-marketplace,test:docker:skill-install,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:agent-bundle-mcp-tools,test:docker:cron-mcp-cleanup,test:docker:plugins,test:docker:plugin-update,test:docker:plugin-lifecycle-matrix, andtest:docker:config-reloadboot one or more real containers and verify higher-level integration paths. - Docker/Bash E2E lanes that install the packed OpenClaw tarball through
scripts/lib/openclaw-e2e-instance.shcapnpm installatOPENCLAW_E2E_NPM_INSTALL_TIMEOUT(default600s; set0to disable the wrapper for debugging).
-
直接模型:
pnpm test:docker:live-models和pnpm test:docker:live-gateway只在仓库 Docker 镜像中运行与其匹配的 profile-key live 文件(src/agents/models.profiles.live.test.ts和src/gateway/gateway-models.profiles.live.test.ts),并挂载你的本地配置目录、工作区和可选的 profile env 文件。对应的本地入口点是test:live:models-profiles和test:live:gateway-profiles。 -
Docker live 运行器默认使用更小的 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。只有当你 明确需要更大的穷举扫描时,才覆盖这些 env 变量。 -
test:docker:all先通过test:docker:live-build构建一次 live Docker 镜像,再通过scripts/package-openclaw-for-docker.mjs将 OpenClaw 打包成一个 npm tarball,然后构建/复用两个scripts/e2e/Dockerfile镜像。裸镜像只是用于 install/update/plugin-dependency 通道的 Node/Git 运行器;这些通道会挂载预构建 tarball。功能镜像会将同一个 tarball 安装到/app,用于已构建应用功能通道。Docker 通道定义位于scripts/lib/docker-e2e-scenarios.mjs;规划逻辑位于scripts/lib/docker-e2e-plan.mjs;scripts/test-docker-all.mjs负责执行所选计划。聚合流程使用加权本地调度器:OPENCLAW_DOCKER_ALL_PARALLELISM控制进程槽位,而资源上限会阻止过重的 live、npm-install 和多服务通道同时启动。如果单个通道比当前上限更重,调度器仍然可以在池为空时启动它,然后让它单独运行,直到再次有容量。默认值为 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 秒打印状态,将成功的通道计时存储在.artifacts/docker-tests/lane-timings.json,并利用这些计时在后续运行中优先启动更长的通道。使用OPENCLAW_DOCKER_ALL_DRY_RUN=1可在不构建或运行 Docker 的情况下打印加权通道清单,或使用node scripts/test-docker-all.mjs --plan-json打印所选通道、包/镜像需求和凭据的 CI 计划。 -
Package Acceptance是 GitHub 原生的包门禁,用于判断“这个可安装 tarball 是否能作为产品工作?”它会从source=npm、source=ref、source=url或source=artifact中解析一个候选包,将其作为package-under-test上传,然后针对这个精确 tarball 运行可复用的 Docker E2E 通道,而不是重新打包所选 ref。Profile 按广度排序:smoke、package、product和full。有关包/更新/插件契约、已发布升级幸存者矩阵、发布默认值和失败分流,请参见 Testing updates and plugins。 -
构建和发布检查会在 tsdown 之后运行
scripts/check-cli-bootstrap-imports.mjs。该守卫从dist/entry.js和dist/cli/run-main.js追踪静态构建图,如果在命令分发之前的预分发启动导入了 Commander、prompt UI、undici 或日志记录等包依赖,就会失败;它还会将打包后的 gateway 运行 chunk 控制在预算内,并拒绝对已知冷门 gateway 路径的静态导入。打包后的 CLI smoke 还覆盖 root help、onboard help、doctor help、status、config schema 和 model-list 命令。 -
Package Acceptance 的旧版兼容性上限为
2026.4.25(包含2026.4.25-beta.*)。在该截止点之前,harness 只容忍已发布包的元数据缺口:省略的 private QA 清单项、缺失的gateway install --wrapper、tarball 派生的 git fixture 中缺失的 patch 文件、缺失的持久化update.channel、旧版插件安装记录位置、缺失的 marketplace 安装记录持久化,以及plugins update期间的配置元数据迁移。对于2026.4.25之后的包,这些路径都属于严格失败。 -
容器 smoke 运行器:
test:docker:openwebui、test:docker:onboard、test:docker:npm-onboard-channel-agent、test:docker:release-user-journey、test:docker:release-typed-onboarding、test:docker:release-media-memory、test:docker:release-upgrade-user-journey、test:docker:release-plugin-marketplace、test:docker:skill-install、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:plugin-lifecycle-matrix和test:docker:config-reload会启动一个或多个真实容器,并验证更高层级的集成路径。 -
直接模型:
pnpm test:docker:live-models(脚本:scripts/test-live-models-docker.sh) -
ACP 绑定 smoke:
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 后端 smoke:
pnpm test:docker:live-cli-backend(脚本:scripts/test-live-cli-backend-docker.sh) -
Codex app-server harness smoke:
pnpm test:docker:live-codex-harness(脚本:scripts/test-live-codex-harness-docker.sh) -
Gateway + 开发 agent:
pnpm test:docker:live-gateway(脚本:scripts/test-live-gateway-models-docker.sh) -
可观测性 smoke:
pnpm qa:otel:smoke、pnpm qa:prometheus:smoke和pnpm qa:observability:smoke是私有 QA 源码检出通道。它们故意不属于 package Docker 发布通道,因为 npm tarball 不包含 QA Lab。 -
Open WebUI live smoke:
pnpm test:docker:openwebui(脚本:scripts/e2e/openwebui-docker.sh) -
上手向导(TTY,完整脚手架):
pnpm test:docker:onboard(脚本:scripts/e2e/onboard-docker.sh) -
npm tarball 上手/通道/agent smoke:
pnpm test:docker:npm-onboard-channel-agent会在 Docker 中全局安装打包好的 OpenClaw tarball,默认通过 env-ref 上手并配置 OpenAI + Telegram,运行 doctor,然后运行一次模拟的 OpenAI agent 回合。可用OPENCLAW_CURRENT_PACKAGE_TGZ=/path/to/openclaw-*.tgz复用预构建 tarball,用OPENCLAW_NPM_ONBOARD_HOST_BUILD=0跳过宿主机重建,或通过OPENCLAW_NPM_ONBOARD_CHANNEL=discord或OPENCLAW_NPM_ONBOARD_CHANNEL=slack切换通道。 -
发布用户旅程 smoke:
pnpm test:docker:release-user-journey会在干净的 Docker home 中全局安装打包好的 OpenClaw tarball,运行 onboarding,配置一个模拟的 OpenAI provider,运行一次 agent 回合,安装/卸载外部插件,针对本地 fixture 配置 ClickClack,验证出站/入站消息,重启 Gateway,并运行 doctor。 -
发布类型化 onboarding smoke:
pnpm test:docker:release-typed-onboarding安装打包好的 tarball,通过真实 TTY 驱动openclaw onboard,将 OpenAI 配置为 env-ref provider,验证不会持久化原始密钥,并运行一次模拟的 agent 回合。 -
发布媒体/记忆 smoke:
pnpm test:docker:release-media-memory安装打包好的 tarball,验证从 PNG 附件中理解图像、OpenAI 兼容的图像生成输出、记忆搜索召回,以及在 Gateway 重启后的召回保留。 -
发布升级用户旅程 smoke:
pnpm test:docker:release-upgrade-user-journey默认安装openclaw@latest,在已发布包上配置 provider/plugin/ClickClack 状态,升级到候选 tarball,然后重新运行核心 agent/plugin/channel 旅程。可通过OPENCLAW_RELEASE_UPGRADE_BASELINE_SPEC=openclaw@<version>覆盖基线。 -
发布插件市场 smoke:
pnpm test:docker:release-plugin-marketplace从本地 fixture marketplace 安装,更新已安装插件,卸载它,并验证插件 CLI 随安装元数据被清理而消失。 -
技能安装 smoke:
pnpm test:docker:skill-install会在 Docker 中全局安装打包好的 OpenClaw tarball,禁用配置中的上传归档安装,从搜索中解析当前 live ClawHub 技能 slug,用openclaw skills install安装它,并验证已安装技能以及.clawhub来源/锁定元数据。 -
更新通道切换 smoke:
pnpm test:docker:update-channel-switch会在 Docker 中全局安装打包好的 OpenClaw tarball,从 packagestable切换到 gitdev,验证持久化通道和更新后插件工作,然后切回 packagestable并检查更新状态。 -
升级幸存者 smoke:
pnpm test:docker:upgrade-survivor会在一个带有 agents、通道配置、插件 allowlist、陈旧插件依赖状态以及现有 workspace/session 文件的脏旧用户 fixture 上安装打包好的 OpenClaw tarball。在没有 live provider 或通道密钥的情况下执行 package update 和非交互 doctor,然后启动回环 Gateway,并检查配置/状态保留以及启动/状态预算。 -
已发布升级幸存者 smoke:
pnpm test:docker:published-upgrade-survivor默认安装openclaw@latest,播种真实感较强的现有用户文件,用 baked command recipe 配置该基线,验证生成的配置,将该已发布安装更新到候选 tarball,运行非交互 doctor,写入.artifacts/upgrade-survivor/summary.json,然后启动回环 Gateway 并检查已配置意图、状态保留、启动、/healthz、/readyz和 RPC 状态预算。可使用OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC覆盖一个基线,要求聚合调度器用OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPECS展开精确本地基线,例如[email protected] [email protected] [email protected],并用OPENCLAW_UPGRADE_SURVIVOR_SCENARIOS展开问题形状的 fixture,例如reported-issues;reported-issues集合包括configured-plugin-installs,用于自动修复外部 OpenClaw 插件安装。Package Acceptance 将这些暴露为published_upgrade_survivor_baseline、published_upgrade_survivor_baselines和published_upgrade_survivor_scenarios,解析诸如last-stable-4或all-since-2026.4.23之类的元基线标记,而 Full Release Validation 会将 release-soak package gate 展开为last-stable-4 2026.4.23 2026.5.2 2026.4.15加上reported-issues。 -
会话运行时上下文 smoke:
pnpm test:docker:session-runtime-context验证隐藏运行时上下文转录持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。 -
Bun 全局安装 smoke:
bash scripts/e2e/bun-global-install-smoke.sh会打包当前树,在隔离 home 中使用bun install -g安装,并验证openclaw infer image providers --json返回的是内置 image providers,而不是挂起。可用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 smoke:
bash scripts/test-install-sh-docker.sh在其 root、update 和 direct-npm 容器之间共享一个 npm cache。Update smoke 默认以 npmlatest作为稳定基线,然后升级到候选 tarball。可在本地通过OPENCLAW_INSTALL_SMOKE_UPDATE_BASELINE=2026.4.22覆盖,或在 GitHub 的 Install Smoke workflow 中通过update_baseline_version输入覆盖。非 root 安装器检查会保持隔离的 npm cache,以免 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 全局更新;当你需要 directnpm install -g覆盖时,请在本地不加该环境变量运行脚本。 -
agents delete shared workspace CLI smoke:
pnpm test:docker:agents-delete-shared-workspace(脚本:scripts/e2e/agents-delete-shared-workspace-docker.sh)默认构建根 Dockerfile 镜像,在隔离的容器 home 中播种两个 agents 和一个 workspace,运行agents delete --json,并验证有效 JSON 以及保留 workspace 的行为。可用OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1复用 install-smoke 镜像。 -
Gateway 网络(两个容器,WS auth + health):
pnpm test:docker:gateway-network(脚本:scripts/e2e/gateway-network-docker.sh) -
浏览器 CDP 快照 smoke:
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,然后强制 provider schema 拒绝并检查原始细节是否出现在 Gateway 日志中。 -
MCP 通道桥(带种子的 Gateway + stdio bridge + 原始 Claude 通知帧 smoke):
pnpm test:docker:mcp-channels(脚本:scripts/e2e/mcp-channels-docker.sh) -
Pi bundle MCP 工具(真实 stdio MCP 服务器 + 内嵌 Pi profile allow/deny smoke):
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、损坏的 npm 包元数据、git 移动 refs、ClawHub 大杂烩、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新 smoke):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 package/runtime 配对。若没有OPENCLAW_CLAWHUB_URL/CLAWHUB_URL,测试将使用一个 hermetic 的本地 ClawHub fixture server。 -
插件更新未变更 smoke:
pnpm test:docker:plugin-update(脚本:scripts/e2e/plugin-update-unchanged-docker.sh) -
插件生命周期矩阵 smoke:
pnpm test:docker:plugin-lifecycle-matrix会在裸容器中安装打包好的 OpenClaw tarball,安装一个 npm 插件,切换启用/禁用,通过本地 npm registry 升级和降级它,删除已安装代码,然后验证卸载仍会移除陈旧状态,同时为每个生命周期阶段记录 RSS/CPU 指标。 -
配置重载元数据 smoke:
pnpm test:docker:config-reload(脚本:scripts/e2e/config-reload-source-docker.sh) -
插件:
pnpm test:docker:plugins覆盖本地路径、file:、带 hoisted 依赖的 npm registry、git 移动 refs、ClawHub fixture、marketplace 更新,以及 Claude-bundle 启用/检查的安装/更新 smoke。pnpm test:docker:plugin-update覆盖已安装插件的未变更新行为。pnpm test:docker:plugin-lifecycle-matrix覆盖资源跟踪的 npm 插件安装、启用、禁用、升级、降级以及缺失代码卸载。
OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE 这样的套件专用镜像覆盖在设置时仍然优先。当 OPENCLAW_SKIP_DOCKER_BUILD=1 指向远程共享镜像时,如果该镜像本地尚不存在,脚本会拉取它。QR 和安装器 Docker 测试保留各自的 Dockerfile,因为它们验证的是包/安装行为,而不是共享的已构建应用运行时。
The live-model Docker runners also bind-mount the current checkout read-only and
stage it into a temporary workdir inside the container. This keeps the runtime
image slim while still running Vitest against your exact local source/config.
The staging step skips large local-only caches and app build outputs such as
.pnpm-store, .worktrees, __openclaw_vitest__, and app-local .build or
Gradle output directories so Docker live runs do not spend minutes copying
machine-specific artifacts.
They also set OPENCLAW_SKIP_CHANNELS=1 so gateway live probes do not start
real Telegram/Discord/etc. channel workers inside the container.
test:docker:live-models still runs pnpm test:live, so pass through
OPENCLAW_LIVE_GATEWAY_* as well when you need to narrow or exclude gateway
live coverage from that Docker lane.
test:docker:openwebui is a higher-level compatibility smoke: it starts an
OpenClaw gateway container with the OpenAI-compatible HTTP endpoints enabled,
starts a pinned Open WebUI container against that gateway, signs in through
Open WebUI, verifies /api/models exposes openclaw/default, then sends a
real chat request through Open WebUI’s /api/chat/completions proxy.
Set OPENWEBUI_SMOKE_MODE=models for release-path CI checks that should stop
after Open WebUI sign-in and model discovery, without waiting on a live model
completion.
The first run can be noticeably slower because Docker may need to pull the
Open WebUI image and Open WebUI may need to finish its own cold-start setup.
This lane expects a usable live model key. Provide it through the process
environment, staged auth profiles, or an explicit OPENCLAW_PROFILE_FILE.
Successful runs print a small JSON payload like { "ok": true, "model": "openclaw/default", ... }.
test:docker:mcp-channels is intentionally deterministic and does not need a
real Telegram, Discord, or iMessage account. It boots a seeded Gateway
container, starts a second container that spawns openclaw mcp serve, then
verifies routed conversation discovery, transcript reads, attachment metadata,
live event queue behavior, outbound send routing, and Claude-style channel +
permission notifications over the real stdio MCP bridge. The notification check
inspects the raw stdio MCP frames directly so the smoke validates what the
bridge actually emits, not just what a specific client SDK happens to surface.
test:docker:agent-bundle-mcp-tools is deterministic and does not need a live
model key. It builds the repo Docker image, starts a real stdio MCP probe server
inside the container, materializes that server through the embedded OpenClaw bundle
MCP runtime, executes the tool, then verifies coding and messaging keep
bundle-mcp tools while minimal and tools.deny: ["bundle-mcp"] filter them.
test:docker:cron-mcp-cleanup is deterministic and does not need a live model
key. It starts a seeded Gateway with a real stdio MCP probe server, runs an
isolated cron turn and a sessions_spawn one-shot child turn, then verifies
the MCP child process exits after each run.
手动 ACP 纯语言线程 smoke(非 CI):
bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...- 保留这个脚本用于回归/调试工作流。它将来可能还需要用于 ACP 线程路由验证,所以不要删除它。
OPENCLAW_CONFIG_DIR=...(默认:~/.openclaw)挂载到/home/node/.openclawOPENCLAW_WORKSPACE_DIR=...(默认:~/.openclaw/workspace)挂载到/home/node/.openclaw/workspaceOPENCLAW_PROFILE_FILE=...会在运行测试前挂载并 sourceOPENCLAW_DOCKER_PROFILE_ENV_ONLY=1用于仅验证来自OPENCLAW_PROFILE_FILE的 env 变量,使用临时 config/workspace 目录且不挂载外部 CLI authOPENCLAW_DOCKER_CLI_TOOLS_DIR=...(默认:~/.cache/openclaw/docker-cli-tools)挂载到/home/node/.npm-global,用于在 Docker 内缓存 CLI 安装$HOME下的外部 CLI auth 目录/文件以只读方式挂载到/host-auth...,然后在测试开始前复制到/home/node/...- 默认目录:
.minimax - 默认文件:
~/.codex/auth.json、~/.codex/config.toml、.claude.json、~/.claude/.credentials.json、~/.claude/settings.json、~/.claude/settings.local.json - 缩小范围的 provider 运行只挂载从
OPENCLAW_LIVE_PROVIDERS/OPENCLAW_LIVE_GATEWAY_PROVIDERS推断出的所需目录/文件 - 可手动用
OPENCLAW_DOCKER_AUTH_DIRS=all、OPENCLAW_DOCKER_AUTH_DIRS=none,或像OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex这样的逗号列表覆盖
- 默认目录:
OPENCLAW_LIVE_GATEWAY_MODELS=.../OPENCLAW_LIVE_MODELS=...用于缩小运行范围OPENCLAW_LIVE_GATEWAY_PROVIDERS=.../OPENCLAW_LIVE_PROVIDERS=...用于过滤容器内 providerOPENCLAW_SKIP_DOCKER_BUILD=1用于在不需要重建的重跑中复用现有的openclaw:local-live镜像OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1用于确保凭据来自 profile store(而不是 env)OPENCLAW_OPENWEBUI_MODEL=...用于选择 gateway 为 Open WebUI smoke 暴露的模型OPENCLAW_OPENWEBUI_PROMPT=...用于覆盖 Open WebUI smoke 使用的 nonce-check promptOPENWEBUI_IMAGE=...用于覆盖固定的 Open WebUI 镜像 tag
文档检查
在修改文档后运行文档检查:pnpm check:docs。
当你还需要页面内标题检查时,运行完整的 Mintlify 锚点验证:pnpm docs:check-links:anchors。
离线回归(CI 安全)
这些是没有真实提供方的“真实流水线”回归:- 网关工具调用(模拟 OpenAI,真实网关 + agent 循环):
src/gateway/gateway.test.ts(用例:“通过网关 agent 循环端到端运行模拟 OpenAI 工具调用”) - 网关向导(WebSocket
wizard.start/wizard.next,写入配置 + 强制认证):src/gateway/gateway.test.ts(用例:“通过 WebSocket 运行向导并写入 auth token 配置”)
Agent 可靠性评估(技能)
我们已经有一些 CI 安全的测试,它们的行为类似于“agent 可靠性评估”:- 通过真实网关 + agent 循环的模拟工具调用(
src/gateway/gateway.test.ts)。 - 端到端向导流程,用于验证会话接线和配置效果(
src/gateway/gateway.test.ts)。
- 决策能力: 当提示中列出技能时,agent 是否会选择正确的技能(或避开不相关的技能)?
- 合规性: agent 在使用前是否会阅读
SKILL.md并遵循所需步骤/参数? - 工作流契约: 多轮场景,断言工具调用顺序、会话历史延续以及沙箱边界。
- 使用带 mock 提供方的场景运行器,用于断言工具调用 + 顺序、技能文件读取以及会话接线。
- 一小套聚焦技能的场景(使用 vs 避免、门控、提示注入)。
- 可选的在线评估(按需启用,受环境变量控制)仅在 CI 安全套件就位后再启用。
契约测试(插件和通道形状)
契约测试会验证每个已注册的插件和通道是否符合其 接口契约。它们会遍历所有已发现的插件,并运行一组 形状与行为断言。默认的pnpm test 单测通道会有意
跳过这些共享接缝和冒烟文件;当你修改共享通道或提供方
表面时,请显式运行契约命令。
命令
- 所有契约:
pnpm test:contracts - 仅通道契约:
pnpm test:contracts:channels - 仅提供方契约:
pnpm test:contracts:plugins
通道契约
位于src/channels/plugins/contracts/*.contract.test.ts 中:
- plugin - 基本插件形态(id、name、capabilities)
- setup - 设置向导契约
- session-binding - 会话绑定行为
- outbound-payload - 消息负载结构
- inbound - 入站消息处理
- actions - 通道动作处理器
- threading - 线程 ID 处理
- directory - 目录/名册 API
- group-policy - 群组策略执行
提供方状态契约
位于src/plugins/contracts/*.contract.test.ts。
- status - 通道状态探针
- registry - 插件注册表形状
提供方契约
位于src/plugins/contracts/*.contract.test.ts 中:
- auth - 认证流程契约
- auth-choice - 认证选择/挑选
- catalog - 模型目录 API
- discovery - 插件发现
- loader - 插件加载
- runtime - 提供方运行时
- shape - 插件形态/接口
- wizard - 设置向导
何时运行
- 在更改 plugin-sdk 导出或子路径之后
- 在添加或修改通道或提供方插件之后
- 在重构插件注册或发现逻辑之后
添加回归测试(指南)
当你修复了线上发现的 provider/model 问题时:- 如果可能,添加一个 CI 安全的回归测试(mock/stub 提供方,或捕获精确的请求形态转换)
- 如果它本质上只能在线运行(速率限制、认证策略),请保持线上测试范围窄,并通过环境变量设为可选
- 优先针对能够捕获 bug 的最小层级:
- 提供方请求转换/回放 bug → 直接的 models 测试
- gateway 会话/历史/工具流水线 bug → gateway live smoke 或 CI 安全的 gateway mock 测试
- SecretRef 遍历防护:
src/secrets/exec-secret-ref-id-parity.test.ts会从注册表元数据(listSecretTargetRegistryEntries())中为每个 SecretRef 类派生一个采样目标,然后断言会拒绝 traversal-segment exec id。- 如果你在
src/secrets/target-registry-data.ts中添加了新的includeInPlanSecretRef 目标族,请更新该测试中的classifyTargetClass。该测试会故意在未分类的目标 id 上失败,因此新的类别不会被悄悄跳过。