qwen-code 多工作区制品归属:/workspaces/:workspace 限定路由与 Web Shell e2e 验证
qwen-code 多工作区制品归属/workspaces/:workspace 限定路由与 Web Shell e2e 验证【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文围绕 qwen-code 仓库中的端到端验证文档 .qwen/e2e-tests/2026-08-04-secondary-artifact-workspace-ownership.md 展开系统梳理次级工作区secondary workspace制品归属这一多工作区能力的设计目标、三组核心验证场景、源码级路由实现以及最终的自动化与生产环境双重验证结果。读完本文你将掌握qwen serve多--workspace注册下/workspaces/:workspace前缀限定路由的工作原理理解制品面板与定时任务如何按工作区隔离归属并了解如何用同路径哨兵文件与隔离定时任务夹具完成一次可复现的多工作区 e2e 验证。一、问题背景多工作区下的制品归属缺失qwen-code 的qwen serve自 0.21.3 起支持重复--workspace注册使单个 daemon 可同时托管多个工作区并通过 Web Shell 对外提供服务基线信息见 .qwen/e2e-tests/2026-08-04-secondary-artifact-workspace-ownership.md#baseline。但在该 e2e 任务开展前组件行为是失败优先failure-first的存在两个明确的归属缺陷制品面板无归属所有者当一个制品标签页无法确定它属于哪个工作区时会退回到根工作区primary workspace的动作与路由导致次级工作区中打开的制品可能被错误地以主工作区身份读写。定时任务详情缺少次级workspaceId调度任务明细没有携带次级工作区标识前端无法把该任务路由到其真正所属的工作区跨工作区管理调度任务不止主工作区而是每个已注册项目的能力不完整。这两点正是本次 e2e 验证要修复并锁定的核心目标让次级会话的制品与次级工作区的定时任务严格走自己的工作区路由任何归属不明或归属丢失的情况都必须失败关闭fail-closed而不是静默降级到主工作区。二、验证方案本地双工作区搭建验证的第一步是构造一个完全隔离、可对照的双工作区环境。文档给出了四个步骤创建相互隔离的主/次临时工作区两个工作区在磁盘上完全独立。在两个工作区放置同名相对路径哨兵文件、但内容不同例如artifact-owner.txt主工作区写入PRIMARY_WORKSPACE_SENTINEL_8494次级工作区写入SECONDARY_WORKSPACE_SENTINEL_8494。用同路径不同内容的方式可以精确检验路由是否把请求送达了正确的工作区——只要返回字节不属于当前工作区就能立刻暴露路由泄漏。为两个运行时创建各自独立的持久化定时任务夹具distinct durable scheduled-task fixtures主/次各有一个独立的 cron 任务用于验证任务 CRUD 是否只影响各自工作区。以两个--workspace标志启动生产构建的dist/cli.js serve监听 loopback并挂载生产 Web Shell 产物node dist/cli.js serve \ --workspace /path/to/primary \ --workspace /path/to/secondary \ --port loopback-port注意本仓库为只读环境以上命令仅用于说明可复现验证的启动方式实际执行需在本地检出中完成。三、场景一次级工作区文件操作操作打开一个次级会话的制品artifact并下载/预览其中的哨兵文件。预期请求必须携带工作区限定前缀即目标是/workspaces/secondary/file...而不是根路由/file。返回的字节必须是次级哨兵内容永远不能是主工作区的哨兵。这一预期的实现落点在 packages/cli/src/serve/routes/workspace-file-read.ts 中。从源码可见registerWorkspaceQualifiedFileReadRoutes注册了一整组工作区限定读路由app.get(/workspaces/:workspace/file, ...); // 读取文件内容 app.get(/workspaces/:workspace/file/bytes, ...); // 读取文件原始字节 app.get(/workspaces/:workspace/stat, ...); // 文件状态 app.get(/workspaces/:workspace/list, ...); // 目录列表 app.get(/workspaces/:workspace/glob, ...); // glob 匹配每个请求首先通过resolveWorkspaceRuntimeFromParam把路径参数:workspace工作区 id 或绝对路径解析为已注册运行时解析失败即短路返回随后通过setWorkspaceRouteContext把运行时绑定到本次请求上下文再进入真正的文件处理逻辑。配套的写路由在 packages/cli/src/serve/routes/workspace-file-write.ts同样以/workspaces/:workspace/file/write、/file/edit、/file/upload的限定前缀形式注册。而路径前缀的解析/保护逻辑集中在 packages/cli/src/serve/acp-http/index.ts其中定义了PLURAL_WS_PREFIX /workspaces/并实现了对/workspaces/selectorsuffix的匹配与选择器提取同时显式拒绝%2e%2e之类的编码穿越如/workspaces/%2e%2e/acp这类会塌缩到/acp、从而静默绑定到主挂载点的路径——这正是次级文件永不落入主工作区的底层保障之一。四、场景二次级工作区定时任务操作打开次级工作区的持久化定时任务依次执行切换启用状态、编辑、删除测试副本。预期每一次请求都必须指向/workspaces/secondary/scheduled-tasks...。主工作区的任务与任务文件必须保持原样不受任何影响。该能力的后端实现在 packages/cli/src/serve/routes/scheduled-tasks.ts 的registerWorkspaceQualifiedScheduledTasksRoutes它以/workspaces/:workspace为前缀复用registerScheduledTaskCrudRoutes并通过resolveWorkspaceRuntimeWithLiveCompatibilityFromParam解析目标运行时随后调用requireTrustedWorkspaceRuntime执行必须为受信任工作区的同一门禁最后把任务目标指向该工作区的 cron 文件与启用会话管理时的bridge从而让多工作区 Web Shell 可以管理每个已注册项目的调度而不只是主工作区。文档注释也明确写着任何读写前都要求该工作区受信任这一门禁与其他限定路由一致。前端侧定时任务的面板与 CRUD 交互位于 packages/web-shell/client/components/dialogs/ScheduledTasksDialog.tsx它通过qwen-code/web-shell/daemon-react-sdk的useWorkspaceActions拿到按工作区隔离的动作集合并基于DaemonWorkspaceCapability等类型感知当前工作区能力从而把次级任务与主任务在 UI 上区分开。五、场景三归属丢失fail-closed操作保持一个制品标签页打开在延迟读取尚未返回时通过能力夹具capability fixture将次级工作区移除或标记为不可用。预期面板显示本地化的工作区不可用workspace-unavailable状态。延迟到达的响应被直接忽略。不会有任何请求被重试到主工作区路由上——即绝不静默降级。这是三条预期中最关键的一条它定义了归属丢失时的失败语义与其把请求错误地落到主工作区造成数据污染不如放弃本次响应并向用户明确展示工作区已不可用。验证文档同时要求生产构建的 Web Shell 产物中必须包含新的 stale-owner陈旧所有者守卫逻辑并且GET /capabilities必须分别广播主/次两个运行时的独立 id见 packages/cli/src/serve/capabilities.ts 中按工作区切分的能力声明结构前端才能依据能力变化判断我打开的这个制品所属工作区是否还在。六、自动化验证结果验证文档记录了 2026-08-04 的完整结果结论为PASS分为三层6.1 Failure-first 预演3 个预期失败在修复前先跑一轮捕获 3 个预期失败与 29 个既有通过用例精确复现了三类缺陷主哨兵泄漏到了无所有者的制品标签页即归属缺失时误用根工作区路由次级限定客户端未被使用qualified client 没有接入次级会话定时任务列表缺少workspaceId字段。6.2 聚焦归属套件413/413 通过修复后的聚焦测试覆盖了六处受影响测试文件解析器、turn 输出、制品面板、嵌套 subagent、应用标签页传播等413 个用例全部通过全量 Web Shell 套件为167 个文件、2,777 个测试全部通过Web Shell lint 与 TypeScript typecheck、包级 Web Shell 构建、仓库根生产构建均通过改动文件通过 Prettier包级格式检查仍报告 5 个未改动的基线文件BranchPickerPopover.module.css、GitModePopover.module.css、GitDialog.module.css、PlanExecutionView.module.css、index.html与本次改动无关。七、生产双工作区验证自动化之外文档还记录了在生产构建上的真实双工作区验证——用构建后的 CLI 以两个受信任工作区加载复制出的生产 bundleGET /capabilities广播了主、次两个不同的运行时 id且产物中的 JS 包含新的 stale-owner 守卫。同路径哨兵对照GET /file?pathartifact-owner.txt返回PRIMARY_WORKSPACE_SENTINEL_8494SHA-256818d5f4f…GET /workspaces/secondary-id/file?pathartifact-owner.txt返回SECONDARY_WORKSPACE_SENTINEL_8494SHA-2560e9fac79…次级字节路由只返回次级哨兵字节。主/次哈希不同直接证明两条路由落到了不同的磁盘目录。持久任务 CRUD 隔离次级任务的 list/update/delete 全部走/workspaces/secondary-id/scheduled-tasks...更新只改变次级任务的名称与启用状态主任务保持存在、启用且未变更删除次级任务后只有次级列表被清空主任务仍在验证完毕后两个测试任务均被清理。daemon 请求日志独立记录了限定的 file、bytes 以及 scheduled-task 的 POST/GET/PATCH/DELETE 路由及成功状态作为第三方证据。八、关于视觉证据的说明按文档记录本次验证中应用内浏览器运行时未报告可用的浏览器实例因此没有截取到 UI 截图也没有用合成截图替代——这是刻意为之的严谨做法宁可缺失也不伪造证据。生产服务器对当前 Web Shell bundle 返回 HTTP 200DOM 行为则由上述聚焦套件与全量套件覆盖。基于此本文亦不额外插入任何与次级工作区制品面板相关的演示图片避免引入无法核实的视觉材料。九、总结Secondary artifact workspace ownership 这次 e2e 验证为 qwen-code 的多工作区 Web Shell 钉住了三项可验证的行为契约次级制品严格走/workspaces/secondary/file...路由同路径哨兵文件 SHA-256 哈希是防止读错工作区的最直观证据次级定时任务 CRUD 严格走/workspaces/secondary/scheduled-tasks...主工作区任务零影响归属丢失必须 fail-closed显示本地化工作区不可用、忽略延迟响应、绝不重试到主路由。对应实现可分别回溯到 packages/cli/src/serve/routes/workspace-file-read.ts、packages/cli/src/serve/routes/workspace-file-write.ts、packages/cli/src/serve/routes/scheduled-tasks.ts 与 packages/cli/src/serve/acp-http/index.ts 中的PLURAL_WS_PREFIX解析保护逻辑。对于希望自行复现或扩展该验证的读者可直接以本文第二节的本地搭建步骤为起点复用双哨兵文件 隔离任务夹具 限定路由日志三件套在qwen serve的多工作区能力上继续加固。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →