Qwen Code 内置 CUA Driver 0.20.0 上游同步:交付边界、同步流程与 Qwen 不变量解析
2026/9/14 15:57:27 网站建设 项目流程

Qwen Code 内置 CUA Driver 0.20.0 上游同步:交付边界、同步流程与 Qwen 不变量解析

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

CUA Driver 是 Qwen Code 以 vendored(内嵌镜像)方式分发的一套跨平台桌面与浏览器自动化运行时。本文基于 docs/plans/2026-08-20-cua-driver-0.20.0-upstream-sync.md 及其配套设计文档,完整讲解一次"纯前置"上游同步的技术方案:如何把内嵌的 CUA Driver 从已发布的 0.17.0 快照推进到 0.20.0,同时保住 Qwen 自己的身份、遥测、坐标与负载过滤契约。读完本文,你将掌握该仓库的 vendored 同步机制、同步脚本的工作原理、哪些变更会被视为越界,以及如何分层验证一次大版本同步是否真正安全落地。

背景:为什么需要一次"纯前置"的上游同步

Qwen Code 仓库把trycua/cualibs/cua-driver以 vendored 方式收纳进自己的packages/cua-driver目录,并在其上叠加 Qwen 特有的运行时与分发契约(详见 packages/cua-driver/README.md 的说明)。这意味着上游每一次大版本演进,Qwen Code 都需要走一次"拉取上游 delta → 解决冲突 → 重挂 Qwen 补丁 → 分层验证"的同步流程。

计划文档为这次同步给出了明确的交付边界:

Deliver one pure prerequisite change before Issue #9334: move the vendored CUA Driver from the released 0.17.0 snapshot to released 0.20.0 while preserving the documented Qwen distribution and compatibility patches. Do not change the built-in Computer Use adapter or downloader pin.

也就是说:

  • 这是一次"纯前置变更",服务于后续的 Issue #9334(模型可见的 Computer Use 能力),但本次不实现 #9334 的任何模型侧 API;
  • 只升级内嵌驱动本身:从已发布快照 0.17.0 迁到已发布版本 0.20.0;
  • 内置 Computer Use adapter 与下载器 pin 保持不变,它们是独立评审的后续工作。

同步的"事实源":tag、commit 与 npm dist-tag

设计文档 docs/design/cua-driver-0.20.0-upstream-sync.md 明确了这次同步的权威依据(source of truth):

同步目标上游稳定版cua-driver-rs-v0.20.0trycua/cua
目标 commitbb8c86049cad1bf0853c6d25c03c14875d0d047f
npmlatestdist-tag@trycua/cua-driver亦解析到0.20.0
排除项0.20.1属于 nightly 预发布,不作为发布基线
当前快照cua-driver-rs-v0.17.0@ commit10279552e2bbe479e367a082f78b1b98ee85a697
合并策略以 0.17.0 为共同祖先做三路合并,校验packages/cua-driver/scripts/sync-from-upstream.sh生成的 delta

这里有两个容易被忽略的细节:一是"发布 tag 是唯一事实源",本地旧 checkout、旧设计笔记和已生成产物只作为比较输入;二是 npm 的latestdist-tag 与 Git tag 必须指向同一版本,避免"Git 同步到 0.20.0、npm 侧却漂到别的版本"的错位。

同步流程:从 delta 应用到全量复核的 8 个步骤

计划文档把整个同步拆成 8 个顺序步骤,覆盖"验证 → 应用 → 裁决 → 对齐 → 验证 → 冒烟 → 全量复核"的完整闭环:

  1. 验证官方元数据:核对 Git tag、commit、npm dist-tag 与发布元数据,确认 0.20.0 是稳定发布而非预发布;
  2. 应用 0.17.0 → 0.20.0 delta:用仓库自带的同步脚本 packages/cua-driver/scripts/sync-from-upstream.sh 拉取libs/cua-driver的增量;
  3. 三路合并裁决 reject:对每个冲突(.rej文件)以上游 0.17.0 为共同祖先做三路合并,逐一裁决;
  4. 采用上游 0.20 行为并保留 Qwen 补丁:采纳新的生命周期、target、授权、SDK 与浏览器 token 行为;保留 Qwen 身份、遥测、坐标适配、payload 过滤与 Windows 空标题窗口补丁;
  5. 恢复锁文件并对齐示例:恢复干净的npm ci构建所需的 lockfile;把独立 SDK 示例对齐到已发布的 0.20.0 包;推进 Qwen 发布元数据到 0.20.0;
  6. 全面验证:校验源码来源、版本一致性、生成契约、语言 SDK、Rust 包、安装器行为、发布接线以及外围 Qwen workspace;
  7. 调试运行时冒烟测试:平台相关或签名发布相关的缺口单独记录,与源码失败区分开;
  8. 两轮连续干净通过:以开放式通读方式检查全部已跟踪与未跟踪 diff,最终修复后必须连续两轮干净通过才能收尾。

第 2 步是唯一由脚本自动完成的环节,其余步骤都要求人工判断,这正是"vendored 同步"与普通依赖升级的本质区别——Qwen 的补丁必须在新基线上重新定位。

同步脚本源码剖析:reject-based apply 与三路合并

packages/cua-driver/scripts/sync-from-upstream.sh 是整个同步机制的核心。脚本头部注释解释了为什么不使用git subtreegit subtree split会在 trycua/cua 历史深处的某个 commit 上挂起,导致 subtree pull 流程无法使用,因此仓库选择"只 diff 两个 ref、不做全历史遍历"的 reject-based apply 方案。

关键流程(对应脚本源码 sync-from-upstream.sh):

  1. 读取旧基线:从packages/cua-driver/.vendored-from读取当前 vendored 来源 ref(OLD_REF),并校验新旧两个 ref 都能在本地 trycua/cua clone 中解析;
  2. 生成上游 deltagit diff --binary --no-renames "$OLD_REF" "$NEW_REF" -- libs/cua-driver只取驱动目录的增量,--no-renames让重命名变成 delete + add,从而让三路应用更可预测;
  3. 路径重写git apply --reject --directory=packages/cua-driver -p3剥掉a/libs/cua-driver/三个路径组件,再前置到packages/cua-driver/
  4. 冲突留痕:能应用的 hunk 全部应用,应用不上的写成同级.rej文件。之所以不用--3way,是因为补丁的 base blob 在上游仓库而不在本地,本地无法做三路查找,而普通 apply 又是全有或全无的;
  5. 更新基线记录:无论成功与否,.vendored-from都会更新为NEW_REF,保证下次同步的起点正确;
  6. 提示补丁表:脚本末尾提示检查 packages/cua-driver/.vendored-patches.md,如果新 ref 已经包含某个 cherry-pick PR 的合并点,就预期会在对应文件上产生.rej,并在解决后把该行从"活跃补丁"表移除。

.vendored-patches.md的当前内容印证了计划第 4 步"保留 Windows 补丁、退役 EAGAIN 补丁"的要求:

上游 PR修复内容状态
trycua/cua#2021list_windows包含空/空标题顶层窗口仍 open,由 Qwen 本地携带(platform-windows
trycua/cua#2036daemon socket 写遇EAGAIN/EWOULDBLOCK时重试而非致命失败已并入 0.17.0 基线,退役本地补丁
trycua/cua#2025 / #2035X11 合成点击误报成功 /start_session复活空闲回收会话0.7.0 基线已包含,退役

需要"重新决策"的停止条件

计划文档明确列出 5 种触发"需要新决策"的停止条件。换句话说,只要同步过程触碰了以下任何一条,就不能继续机械执行,而必须停下来重新讨论方案:

  1. 改变 Qwen 内置 Computer Use 下载器或 bootstrap 行为
  2. 用上游值替换 Qwen 的身份、安装路径、签名归属或遥测默认值
  3. 照搬上游独有的发布基础设施,或引入新的发布密钥
  4. 在 Windows 本地补丁被上游合并之前擅自丢弃它
  5. 把 Issue #9334 的模型侧 API 塞进本次同步变更

这 5 条是"边界红线":前三条保护 Qwen 的分发与信任边界,第四条保护尚未上游化的本地修复,第五条保证变更范围单一、可独立评审。任何一条越界都意味着本次变更不再是"纯前置同步",需要回到决策层面重新规划。

采用的上游 0.20.0 行为

同步完成后,0.20.0 运行时成为新的 vendored 基线,设计文档列出的"被采纳的上游行为"包括:

  • 传输层拥有的隐式生命周期会话与显式 per-action target:会话生命周期由传输层管理,动作目标逐动作显式指定;
  • 跨权限 profile 生效的 capability manifest:能力清单不再只属于单一 profile;
  • typed SDK、contract 与生成绑定更新:Python / TypeScript UniFFI 绑定随版本同步演进;
  • 前台聚焦验证与后台输入加固:即 README 中提到的verify_state、foreground-focus verification;
  • 策略过滤的工具发现与命名 CLI 会话行为
  • stable / nightly 发布通道支持
  • 移除旧版浏览器 approval tokenbrowser approval tokens are retired,已有 profile 的访问只能通过受信任的启动授权(launch grant)、受限 manifest 或嵌入宿主(embedding host)的授权回调继续。

其中最后一条是行为级破坏性变更,设计文档特别强调:被移除的浏览器 token 路径不作为 Qwen 兼容 fork 保留。也就是说,Qwen 不与上游"反向兼容",而是接受 0.20 的新授权模型。

从 packages/cua-driver/README.md 可以看到这一模型在用户侧的落地:qwen-cua-driver mcp --grant existing-profile显式授予已有 Chromium profile 的访问权,嵌入应用则可以提供DriverAuthorizationHost自己掌管权限提示与授权生命周期。权限模式分三档——standard(默认,无提示)、bounded(仅放行已评审工具与资源)、unrestricted(需--dangerously-bypass-approvals)。

Qwen 不变量:同步必须保住的下游边界

"采用上游行为"与"保住 Qwen 契约"是一体两面。设计文档把必须保留的 Qwen 不变量归纳为 6 条,计划第 4 步的"保留"清单与之完全对应:

  1. 身份归属:可执行文件、app、bundle、服务、安装、更新与发布身份全部保持 Qwen 所有。README 给出了具体形态:可执行文件qwen-cua-driver/qwen-cua-driver.exe、macOS app/Applications/QwenCuaDriver.app、bundle identifiercom.qwencode.cua-driver、状态目录~/.cua-driver、Windows 计划任务qwen-cua-driver-serve;源码本地构建则使用独立的qwen-cua-driver-local身份;
  2. 遥测默认关闭:Qwen 发行版默认禁用遥测,显式启用后也只走文档规定的上游端点(qwen-cua-driver telemetry enable/status/disable,详见 README),不引入 Qwen 遥测服务或代理;
  3. MCP_MODEL_PAYLOAD_FILTER=1:继续作为面向 Qwen 的 payload 过滤器,作用于文本与结构化 MCP 内容,不改动二进制媒体,且不改变直接 SDK 契约;
  4. CUA_DRIVER_RS_COORDINATE_SPACE=1:继续作为可选的归一化坐标适配器,绝对像素仍是默认;CUA_DRIVER_RS_COORDINATE_SCALE可选(默认 1000)。坐标换算发生在 MCP、CLI、daemon、private worker、replay 与直接 SDK 共享的规范工具注册边界,窗口内动作用最近快照尺寸、屏幕空间动作用逻辑屏幕尺寸,缺失或过期坐标基失败关闭而非猜测;
  5. 安装兼容路径:发布安装继续使用~/.cua-driver保持升级兼容,源码构建保留独立的 Qwen 身份(~/.qwen-cua-driver-local);
  6. Windows 空标题补丁:尚未上游合并的 trycua/cua#2021(空/空标题顶层窗口)继续携带并适配到新的窗口模型。

这 6 条中的身份与坐标契约,正是 0.17.0 同步时(docs/design/cua-driver-0.17.0-upstream-sync.md)确立的,0.20.0 同步的职责是"把同样的 Qwen delta 重新挂到新基线的规范边界上",而不是推翻它们。

发布与打包边界

Qwen 的发布流程保留在 .github/workflows/cd-cua-driver.yml,同步时只做维持新驱动构建与发布契约所需的最小改动:

  • 保持既有签名、公证(notarization)、产物命名与发布归属;手工触发(workflow_dispatch)的默认版本推进到 0.20.0(当前仓库该 workflow 的默认值已进一步演进为0.20.5,说明发布线在持续前进);
  • 恢复上游 TypeScript lockfile——npm ci需要它才能干净构建;
  • 上游 0.20.0 tag 把独立 Agent SDK 示例钉在 0.19.2,尽管 npm 与 PyPI 都发布 0.20.0;因此 vendored 示例及其 npm lockfile 要对齐到 0.20.0,确保示例实际执行的是同步后的契约;
  • macOS bundle 版本在存在预发布后缀时仍需保持合法。

同时,上游的 monorepo 级 nightly 编排、release-attribution 服务、Python 发布与文档发布基础设施一律不复制——它们依赖上游独有的脚本、密钥、仓库与发布治理。跨平台签名发布产物仍是 CI 门禁,不会本地代跑。

配套的产物契约(README 与 workflow 注释)如下:macOS 产出cua-driver-rs-<v>-darwin-{arm64,x86_64,universal}.tar.gz(含 Qwen 二进制、SDK 载荷与已签名QwenCuaDriver.app)及*-binary.tar.gz;Linux 产出-linux-{x86_64,arm64}.tar.gz;Windows 产出-windows-{x86_64,arm64}.zip@qwen-code/cua-sdknpm 包通过匹配的*-binary归档下载并校验原生载荷(详见 docs/design/cua-driver-computer-use-sdk.md 的发布契约)。

分层验证:让单测绿无法掩盖分发与信任边界破损

验证设计强调"分层",因为窄而绿的单元测试可能掩盖发行版或信任边界的破坏。0.17.0 同步确立的验证层次(docs/design/cua-driver-0.17.0-upstream-sync.md)在 0.20.0 同步中继续适用,并结合计划第 6~8 步展开:

  • Rust 层cargo fmt --all -- --check、包检查、core/contract/SDK 单元测试、生成契约一致性(对应 packages/cua-driver/rust 工作区);
  • 聚焦专项:坐标归一化、payload 过滤、Windows 窗口枚举、安装器与版本测试;
  • 语言 SDK:Python 与 TypeScript SDK 生成/包检查(在包本地工具链可用时);
  • 发布工作流静态检查:可执行名、app bundle 布局、bundle identifier、资产与烘焙版本(对应 scripts/tests/cua-driver-release-workflow.test.js 与 .github/workflows/cd-cua-driver.yml);
  • 外围仓库npm run build && npm run typecheck
  • 全量审计:完整 diff 与 untracked 文件审计,重复到连续两轮干净为止;
  • 签名/公证生产发布与真实物理机 GUI 认证(Windows UIAccess、Linux X11/Wayland、macOS)属于发布门禁,不在本地验证范围内——这正是计划第 7 步"平台相关或签名发布缺口单独记录"的原因。

计划第 7、8 步在此基础上补充了"调试运行时冒烟测试"和"两轮连续干净通过"的收尾纪律,保证源码层失败与平台/签名层缺口被分开跟踪、分开裁决。

明确的范围边界与后续工作

设计文档的 Out of scope 与计划文档的停止条件互相呼应:本次同步修改 Qwen Code 当前内置的下载器 pin、Computer Use MCP adapter、bootstrap 流程、权限 UX 与模型可见工具 schema,也实现 Issue #9334。这些集成变更都作为"基于已验证 0.20.0 运行时与 TypeScript SDK 的独立可评审后续项"存在。

从仓库现状看,后续方向已经可见:关于 Computer Use 的 SDK 化与 accessibility observation revision 协议的独立阶段设计见 docs/design/cua-driver-computer-use-sdk.md 与 docs/plans/2026-08-20-cua-driver-computer-use-sdk.md,它们与本次同步是"先有稳定 0.20 基线、再在其上做 SDK 能力扩展"的前后置关系。

总结

一次成功的 vendored 上游同步,核心不在于"把新代码搬进来",而在于三件事:以发布 tag 为唯一事实源(0.20.0 而非 nightly 的 0.20.1)、用脚本加三路合并把冲突裁决干净(sync-from-upstream.sh + .vendored-patches.md)、把 Qwen 不变量重新挂到新基线的规范边界上(身份、遥测、payload 过滤、坐标契约、Windows 补丁)。配合 5 条停止条件的硬约束与 6 层验证的门禁,0.17.0 → 0.20.0 的同步才能以"纯前置变更"的姿态,安全地为后续 Issue #9334 与 Computer Use SDK 铺路。

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询