qwen-code Worktree 通用能力:从设计文档到源码实现的隔离工作环境全解
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
qwen-code 把 git worktree 从 Arena 多模型对比的专属机制,升级为面向普通用户会话与 subagent 的通用能力。本文基于设计文档 worktree 通用能力设计,结合仓库中已落地的工具、服务与 CLI 启动路径源码,完整讲解enter_worktree/exit_worktree两个工具、AgentTool的isolation: 'worktree'参数、--worktree启动标志与 PR 引用解析的实现原理、配置项与安全守卫。读完后,你将掌握 qwen-code 中 worktree 的目录约定、会话持久化机制、脏状态清理策略,以及如何在会话内、subagent 中或启动时开启隔离工作环境。
一、背景:从 Arena 专属到通用能力
qwen-code 此前只有面向 Arena 多模型对比场景的内部 worktree 实现(GitWorktreeService),普通用户无法在会话中使用 worktree 隔离工作,AgentTool 也不支持为 subagent 创建隔离环境。设计文档给出的目标是:将 worktree 做成通用能力,支持用户会话级隔离和 Agent 级隔离,同时保证现有 Arena 功能体验完全不变。
现状能力对比(来自设计文档)如下,可以看到 qwen-code 在 Phase A~D 各阶段已补齐的能力与 claude-code 的对照:
| 功能 | qwen-code | claude-code | 阶段 |
|---|---|---|---|
EnterWorktree工具 | 已有(Phase A) | 已有 | — |
ExitWorktree工具 | 已有(Phase A) | 已有 | — |
AgentToolisolation: 'worktree' | 已有(Phase B) | 已有 | — |
| 过期 worktree 自动清理 | 已有(Phase B) | 已有 | — |
| worktree 会话状态持久化与恢复 | 已实现(Phase C) | 已有 | Phase C |
| Post-creation setup(hooks 配置) | 已实现(Phase C) | 已有 | Phase C |
| StatusLine worktree 状态展示 | 已实现(Phase C) | 已有 | Phase C |
| WorktreeExitDialog(退出提示) | 已实现(Phase C) | 已有 | Phase C |
--worktreeCLI 启动标志 | 已有(Phase D) | 已有 | — |
| 符号链接目录(node_modules 等) | 已有(Phase D) | 已有 | — |
PR 引用(--worktree=#123) | 已有(Phase D) | 已有 | — |
| sparse checkout | 未实现 | 已有 | Future |
| tmux 集成 | 未实现 | 已有 | Future |
| Arena 多模型 worktree 隔离 | qwen 独有 | 无 | — |
| 脏状态覆盖(stash + copy) | 已有 | 已有 | — |
| Baseline commit 追踪 | qwen 独有 | 无 | — |
其中「脏状态覆盖」与「Baseline commit 追踪」两项 qwen-code 独有的能力,在 gitWorktreeService.ts 中可以看到实现痕迹:setupWorktrees()(L1016)在批量创建 Arena worktree 时,用git stash create捕获已跟踪的脏状态、对未跟踪文件做逐文件 copy,并写入一个baseline (dirty state overlay)的 baseline commit(BASELINE_COMMIT_MESSAGE,L559),后续 diff 优先相对该 baseline 计算(L1357 起),没有 baseline 时回退到 merge-base。
二、设计原则:通用层与 Arena 层解耦
设计文档明确了核心原则:worktree 是通用能力,Arena 是其上层应用。
- 通用 worktree 层:
EnterWorktree/ExitWorktree工具、AgentToolisolation参数、会话状态管理、自动清理; - Arena 层:多模型并行调度、
worktreeBaseDir自定义路径、批量创建与 diff 对比,继续使用GitWorktreeService.setupWorktrees()的现有逻辑,不受通用层改动影响。
两条路径在架构上是独立的:AgentTool 的isolation: 'worktree'只走通用路径,Arena 内部不经过这个参数创建 worktree。这一点在配置 schema 中也有明确声明——settingsSchema.ts 中worktree顶层项的 description 写明:该配置只作用于enter_worktree工具、agent isolation: "worktree"参数与启动--worktree标志创建的 worktree,不影响Arena worktree(Arena 用agents.arena.worktreeBaseDir,默认~/.qwen/arena)。
三、路径约定与命名规则
通用 worktree 路径
由EnterWorktree工具或 AgentToolisolation: 'worktree'创建的 worktree 固定存放在:
{git 仓库根}/.qwen/worktrees/{slug}路径不可配置。slug 命名规则:
- 用户会话 worktree:用户指定名称,或自动生成(格式:
{形容词}-{名词}-{4位随机})。工具实现中的注释(enter-worktree.ts)写为{adj}-{noun}-{4hex}; - Agent worktree:
agent-{7位随机 hex},对应源码中的AGENT_WORKTREE_SLUG_PATTERN(gitWorktreeService.ts)。
分支命名沿用worktree-<slug>规则(由worktreeBranchForSlug()生成)。由于 worktree 固定在仓库根下的.qwen/worktrees/,enter-worktree.ts 在执行前会先用一个「probe」服务解析 git 仓库顶层,确保即使从 monorepo 子目录调用工具,worktree 也落在<repoRoot>/.qwen/worktrees/下,而不是散落在各个包目录里。
Arena worktree 路径
Arena 的 worktree 路径由agents.arena.worktreeBaseDir控制,默认~/.qwen/arena,与通用路径完全独立,通用层不做任何改动。
四、Phase A:EnterWorktree 工具
触发条件与输入 Schema
设计文档规定的触发条件在工具描述中得到了忠实落实(enter-worktree.ts):只有用户明确说 "start a worktree"、"use a worktree"、"create a worktree" 等词语时才调用;用户说"修复 bug"、"开发功能"、"创建分支"时不得触发。
输入 schema:
name?: string // 可选,slug 格式:字母/数字/点/下划线/破折号,最大 64 字符工具注册在 tool-names.ts(ENTER_WORKTREE: 'enter_worktree'、EXIT_WORKTREE: 'exit_worktree'),并设置了shouldDefer标志——只有用户明确提及 worktree 时才会被模型调用(见 enter-worktree.ts 构造函数参数)。
执行流程(源码级)
设计文档描述的行为序列,与 EnterWorktreeInvocation.execute() 的实现一一对应:
- 防嵌套校验:若当前
targetDir路径中含.qwen/worktrees/组件,直接拒绝(Already inside a git worktree...)。源码注释解释了原因:嵌套创建会让模型的上下文仍指向外层 worktree,退出时内层 worktree 通常被孤立; - git 可用性检查与仓库根解析:
checkGitAvailable()+isGitRepository(),随后用getRepoTopLevel()解析到仓库顶层; - slug 处理:空字符串按未提供处理(部分模型会对可选参数传
''),未提供时调用GitWorktreeService.generateAutoSlug()(L1596);显式 slug 经validateUserWorktreeSlug()(L2029)校验,该函数还会保留agent-前缀,防止用户命名意外撞上 Agent 临时 worktree 的清理模式; - 锚定基础分支:
getCurrentBranch()捕获调用时的检出分支作为 base(源码注释指出:若省略 base,会回退到主工作区当前分支,而用户可能正站在 feature 分支上启动);同时用getCurrentCommitHash()记录originalHeadCommit,供退出对话框统计本次会话新增提交; - 创建 worktree:调用
service.createUserWorktree(slug, baseBranch, { symlinkDirectories }),symlinkDirectories直接取自config.getWorktreeSymlinkDirectories()(Phase D-2 配置,见下文); - 写会话标记:
writeWorktreeSessionMarker(worktreePath, sessionId)把 worktree 打上所属会话的标签,best-effort(失败不中止创建),使后续跨会话的exit_worktree action='remove'能拒绝删除别人的工作; - 持久化 sidecar:
writeWorktreeSession()写入WorktreeSession记录,包含{ slug, worktreePath, worktreeBranch, originalCwd, originalBranch, originalHeadCommit }(设计文档中为{ slug, worktreePath, worktreeBranch, originalCwd, originalBranch },实现中额外增加了originalHeadCommit字段),服务于--resume恢复、Footer 展示与退出对话框; - 输出:
worktreePath、worktreeBranch、message。message 明确指示模型「从此刻起所有文件操作都走该绝对路径,直到调用exit_worktree」。
设计文档中提到 Phase A 的EnterWorktreeTool不修改Config.targetDir,依赖模型从工具结果里读到绝对路径并继续使用——源码印证了这一点:execute 全程只读config.getTargetDir(),没有调用setTargetDir。
五、Phase A:ExitWorktree 工具与安全守卫
输入 Schema 与触发条件
name: string // 必须与 enter_worktree 使用/返回的 name 一致 action: 'keep' | 'remove' discard_changes?: boolean // 仅 action='remove' 时有效触发条件:用户说 "exit the worktree"、"leave the worktree"、"we're done with the worktree" 等。
三层安全守卫
ExitWorktreeInvocation.execute() 实现了设计文档要求的守卫,并比文档描述更严格:
- 会话所有权守卫:
remove前读取 worktree 的 session marker(readWorktreeSessionMarker),若 owner 是其他活跃会话则拒绝执行,防止提示注入或混乱模型枚举.qwen/worktrees/后误删他人工作;owner 未知(无 marker)时放行但记 warn 日志; - 未提交变更守卫:
countWorktreeChanges()统计 tracked/untracked 变更,discard_changes: false时只要有变更就拒绝;若git status本身失败(counts 为 null),宁可拒绝也不建议 bypass——因为此时安全检查的前提条件未知; - 未合并提交守卫:
hasUnmergedWorktreeCommits()检测分支上是否有其他分支或远程 ref 不可达的提交。设计文档只提到未提交变更守卫,源码还额外拒绝了「删除分支会丢提交」的场景,且没有提供 discard commits 的开关——注释解释了理由:「丢失已提交的工作很少是用户说 remove worktree 时真正的意思」。
此外,权限层面:action='remove'的getDefaultPermission()返回'ask',并覆写getConfirmationDetails()返回type: 'exec'(而非默认'info'),源码注释说明了动机——AUTO_EDIT模式会自动批准info/edit类型确认,必须让删除 worktree 走run_shell_command同级的确认通道,才能防住数据丢失路径。
keep / remove 行为
keep:保留 worktree 目录和分支,模型继续引用绝对路径。注意实现与文档的一处演进:设计文档写的是「清空会话中的 worktree 状态」,而当前源码在keep时保留sidecar(exit-worktree.ts 注释引用了 PR 评审意见),理由是清空绑定会让后续--resume/ Footer / 退出对话框「忘记」用户刚选择保留的 worktree;remove:删除 worktree 目录与分支,随后maybeClearWorktreeSession()仅当 sidecar 中的 slug 与本次退出的 slug 一致时才清除(用户可能在磁盘上有多个 worktree,sidecar 只跟踪一个,避免误伤)。
若git branch -d在安全检查通过后又拒绝删除(并发写入竞态),工具会保留分支并在 message 中告知git branch -D手动恢复,而不是强删。
六、Phase B:Agent 级隔离与过期清理
isolation: 'worktree' 参数
设计:模型可为 subagent 创建临时隔离 worktree,agent 结束后自动清理。在 agent.ts 中,isolation?: 'worktree'参数的说明为:创建临时 worktree 于<projectRoot>/.qwen/worktrees/agent-<7hex>;无变更则自动删除;有变更则保留,将路径和分支返回在结果中——与文档完全一致。工具描述(L901)补充:无变更自动清理,有变更时结果中返回 worktree 路径与分支供审查或合并。
校验规则(agent.ts):isolation只接受'worktree';要求显式subagent_type(不能是 fork,fork 共享父级上下文不需要隔离);命名 teammate 不允许isolation——需要先创建 leader 拥有的 worktree,再通过working_dir参数 pin 进去(对应 worktree-pin.ts 的实现)。
buildWorktreeNotice:隔离环境上下文注入
设计文档要求参考 claude-code 的buildWorktreeNotice:fork subagent 在 worktree 中运行时,向其注入上下文提示——说明其处于隔离 worktree、路径继承自父 agent、编辑前需重新读取文件。实现位于 fork-subagent.ts,并在 agent.ts 的 worktree 模式下被调用注入。
过期 worktree 自动清理(fail-closed)
设计:扫描.qwen/worktrees/,匹配agent-{7hex}模式,超过 30 天且无未推送提交则删除,fail-closed 策略。worktreeCleanup.ts 的cleanupStaleAgentWorktrees()完整落地了这一策略:
EPHEMERAL_WORKTREE_PATTERNS只含AGENT_WORKTREE_SLUG_PATTERN——用户命名 worktree 永不清理,它们由ExitWorktreeTool手动管理(agent-前缀保留机制保证用户 slug 不会误匹配);- 阈值
STALE_WORKTREE_CUTOFF_MS = 30 * 24 * 60 * 60 * 1000(L40),按目录 mtime 判断; - fail-closed 链条:存在未提交 tracked 变更 → 跳过;存在上游不可达提交 → 跳过;
git status检查失败 →假设为 dirty并跳过(hasTrackedChanges 注释特别说明:权限错误、文件系统异常必须留下日志痕迹,且不可与「确实有变更」混淆); - 脏检查用
git status --porcelain --untracked-files=no:既覆盖 staged/modified/conflicted(旧实现曾漏掉 conflicted,导致 merge 进行中的 worktree 被误扫),又跳过大型仓库中最慢的 untracked 遍历; - 删除竞态兜底:目录已删但
git branch -d因新提交失败时,保留分支并 warn 日志,提交仍可恢复。
Arena 兼容保证
Arena 内部不经过isolation参数创建 worktree,此改动不触碰 Arena 代码路径——源码中setupWorktrees()批量接口与createUserWorktree()/createAgentWorktree()单会话接口在同一个 gitWorktreeService.ts 内并存,互不干扰。设计文档还特别澄清了一个「无需改动」点:review skill 使用独立机制(路径.qwen/tmp/review-pr-<n>,通过qwen review fetch-pr命令创建),与通用 worktree 路径和机制完全不同,不存在混淆。
七、Phase C:会话持久化与 UI 安全网
目标:worktree 状态在会话中断后可恢复,用户在界面上始终知道自己在哪个 worktree 里,退出会话时有安全提示。
WorktreeSession sidecar 与 --resume 恢复
会话状态以 JSON sidecar 文件持久化,由 worktreeSessionService.ts 提供writeWorktreeSession/readWorktreeSession/clearWorktreeSession/isSessionRuntimeActive等能力。链路:
enter_worktree调用writeWorktreeSession()写入(见上文第四节第 7 步);exit_worktree在 slug 匹配时调用clearWorktreeSession();--resume/ 启动路径读取该字段恢复上下文:headless 入口 nonInteractiveCli.ts 会在首条 prompt 前注入 worktree 上下文提示(restoreWorktreeContext,发出worktree_started/worktree_restored系统消息),交互式 TUI 同理。
Post-creation setup:hooks 路径对齐
创建 worktree 后自动执行git config core.hooksPath <mainRepo>/.git/hooks,确保 worktree 内的提交与主仓库 hooks 行为一致。实现位于configureHooksPath()(gitWorktreeService.ts),在createUserWorktree()的成功路径中被 best-effort 调用(L2150),失败只记日志不中止创建。
StatusLine 展示与退出对话框
- UIStateContext.tsx 新增
activeWorktree字段(含 WorktreeExitDialog 可见性状态),从 session 状态读取,在会话进入 / 退出 worktree 时更新; - Footer 在
activeWorktree非空时内置展示⎇ <branch> (<slug>)行,无需用户配置 statusline 脚本即可获得基本可见性;配置项ui.hideBuiltinWorktreeIndicator可隐藏该行,留给 custom statusline(StatusLineCommandInputpayload 携带worktree?: { slug, branch }供脚本使用); WorktreeExitDialog:Ctrl+C / Ctrl+D 第二次确认时若activeWorktree非空,拦截退出并展示 keep / remove 选择对话框,keep / remove 操作复用ExitWorktreeTool的路径;originalHeadCommit在此处发挥作用——对话框用rev-list <originalHeadCommit>..HEAD统计本次会话新提交,re-attach 场景下基线重新从 worktree 内部捕获,避免把历史会话的提交都算作「本次工作」。
八、Phase D:--worktree启动标志、符号链接与 PR 引用
设计文档指出,三个功能放在同一阶段落地,因为它们都挂在同一个启动入口上,且 symlink / PR fetch 都必须在 worktree 创建之后立即执行,单独拆分会重复改 bootstrap 序列。
D-1:--worktree [name]CLI 启动标志
yargs 选项(config.ts 的注释明确三种形态):
| 形式 | 行为 |
|---|---|
qwen --worktree | bare flag(yargs 传空字符串),自动生成 slug({形容词}-{名词}-{6hex},工具路径为 4 位 hex,此处为 6 位) |
qwen --worktree my-name | 显式 slug,沿用EnterWorktreeTool的 slug 校验规则 |
qwen --worktree=my-name | 等价于上一种 |
不提供短别名-w(短别名只保留给最高频参数)。核心实现是 worktreeStartup.ts 的setupStartupWorktree()(L110),在 argv 解析后、loadCliConfig()/Config构造前运行,使process.chdir()的结果直接喂给 Config 的targetDir。
与 Phase A 的行为差异(设计文档明确要求在用户文档中说明):Phase A 的EnterWorktreeTool不修改Config.targetDir;而--worktree在启动期生效,直接切换targetDir和process.cwd()——更强的隔离保证。
re-attach 路径:若 worktree 目录已存在(例如之前--worktree foo退出时选了 Keep),跳过git worktree add(PR fetch 也跳过,ref 首次运行已物化),直接 chdir 进已有 worktree 并重新捕获 HEAD 基线。worktreeStartup.ts 的注释解释了为何 re-attach 必须用 worktree 内部 HEAD 而非启动 cwd 的 HEAD 作为originalHeadCommit。同时,从已有 worktree 内部启动新 worktree 会被拒绝(防嵌套,L133-L141),字面量pr-<N>slug 允许 re-attach 到已有 PR worktree,但不会凭空创建(保留前缀在探测失败时重新生效)。
与--resume的优先级:由于 session 存储以projectHash(process.cwd())为 key,而--worktree在 resume picker 之前就 chdir,「在 worktree X 启动的 session 从 worktree Y 内 resume」在架构上不可达。实际行为矩阵:
--resume状态 | --worktree状态 | 结果 |
|---|---|---|
| 无 | 无 | 普通会话,无 worktree |
| 无 | 有(新 slug) | 新建 worktree |
| 无 | 有(已存在的 slug) | re-attach 到已有 worktree |
| 有 | 无 | 恢复旧 worktree(sidecar 命中则注入 reminder) |
| 有(sid 出自同一 worktree) | 有(同一 slug) | re-attach + session 命中:正常 resume |
| 有(sid 出自 main checkout) | 有(任意 slug) | session lookup 失败,exit 1(documented limitation) |
| 有(sid 出自 worktree X) | 有(slug Y, X != Y) | 同上,session 跨 projectHash 不可寻 |
跨 projectHash override 语义(在 worktree / 主 checkout 的 session 之间转移)需要 storage 锚定到 repo root 而非 cwd 派生的 projectHash,属于未来 Config 重构范畴。
D-2:worktree.symlinkDirectories配置项
schema(新增worktree顶层 namespace,在 settingsSchema.ts 中按字母序插在tools与ui之间):
{ "worktree": { "symlinkDirectories": ["node_modules", "dist", ".turbo"], }, }- 类型
string[],默认undefined(opt-in);requiresRestart: false; - 路径相对于主仓库根,绝对路径或含
..的路径被路径遍历守卫拒绝; - 作用范围:
EnterWorktreeTool、AgentToolisolation: 'worktree'、--worktreeCLI flag 创建的所有通用 worktree;Arena worktree 不受影响。
实现:GitWorktreeService.symlinkConfiguredDirectories()(gitWorktreeService.ts)在createUserWorktree()成功后、紧跟configureHooksPath()调用。源码中的守卫比文档更细:除拒绝绝对路径与..段外,还拒绝.git内部路径、.qwen管理树内部路径、realpath 解析后逃逸 repo root 的源、以及目标父目录解析逃逸 worktree root 的符号链接链(防御 committed-symlink 攻击)。
错误处理(fail-open):
| 场景 | 行为 |
|---|---|
| 源目录不存在(ENOENT) | 静默跳过,debug log |
| 目标路径已存在(EEXIST) | 静默跳过,debug log(不覆盖) |
路径遍历(../、绝对路径等) | 拒绝该项,debug log warn |
| 其他 I/O 错误 | debug log warn,继续处理后续项 |
worktree 创建本身不会因 symlink 失败而中止——与configureHooksPath()相同的 best-effort post-creation setup 原则。
D-3:PR 引用解析(--worktree=#<N>/ 全 URL)
支持形式(parsePRReference(),gitWorktreeService.ts):
| 形式 | 解析后的 PR 号 |
|---|---|
--worktree=#123 | 123 |
--worktree '#123' | 123 |
--worktree https://github.com/foo/bar/pull/123 | 123 |
--worktree https://gh.enterprise.com/foo/bar/pull/123?baz=qux | 123(企业版 + 带 query) |
slug 与分支命名:slug 为pr-<N>(特殊保留前缀,与用户 slug 区分);分支为worktree-pr-<N>(沿用worktree-<slug>规则;不采用pr-<N>直接命名,避免与本地pr-<N>分支冲突)。
fetch 策略:git fetch origin pull/<N>/head,用FETCH_HEAD作为新 worktree 的 base。不依赖ghCLI——纯 git fetch,支持任何 GitHub 实例(公网或企业版),只要origin指向 GitHub。选择head而非mergeref 的理由:用户通常想看 PR 的实际改动。
错误路径:
| 场景 | 错误消息 |
|---|---|
origin远程缺失 | --worktree=#<N> requires an "origin" remote that points at GitHub. |
git fetch失败 | Failed to fetch PR #<N>: PR may not exist or origin remote is unreachable. |
| 网络超时(30s) | 同上,加(timeout) |
origin不是 GitHub | 不做主动检查,由git fetch自然失败 |
PR worktree同样应用symlinkDirectories——用户期望在 PR 上立刻能跑测试,依赖目录需要复用。
安全与回滚(fail-open vs fail-close 的边界)
- symlink / hooks 失败不中止 worktree 创建(Phase C 既定模式);PR fetch 失败中止启动(无 base ref 就无法创建 worktree);slug 校验失败中止启动;
- cwd 切换的副作用:切
process.cwd()后相对路径参数(如--prompt-file ./foo.txt)解析会受影响。对策:在setupStartupWorktree()入口处先做一次相对路径 normalize。
九、配置与扩展项总览
| 配置项 | 类型 | 用途 | 阶段 |
|---|---|---|---|
ui.hideBuiltinWorktreeIndicator | boolean | 隐藏 Footer 中内置⎇ worktree-… (…)行,留给 custom statusline | Phase C |
worktree.symlinkDirectories | string[] | 符号链接指定目录(如node_modules)到 worktree,避免磁盘浪费 | Phase D |
worktree.sparsePaths | string[] | git sparse-checkout cone 模式,大型 monorepo 只写入指定路径 | Future(未实现) |
Phase A / B 不新增任何配置项。用户文档见 docs/users/features/worktree.md。
十、用户触发方式汇总
| 方式 | 示例 | 阶段 |
|---|---|---|
| 会话中明确请求 | 用户说「在 worktree 中开始工作」→ 模型调用enter_worktree | Phase A |
| Agent 隔离 | 模型为 subagent 设置isolation: 'worktree' | Phase B |
| CLI 启动标志 | qwen --worktree my-feature/qwen --worktree=#123 | Phase D |
无斜杠命令。会话中 worktree 的触发依赖用户明确提及,isolation: 'worktree'才是模型自主决策的场景。
十一、Future 路线图
以下功能面向更特定的场景,当前不纳入排期,待需求明确后再评估:
| 功能 | 说明 |
|---|---|
| sparse checkout | worktree.sparsePaths配置项,大型 monorepo 只 checkout 指定路径,缩短创建时间和磁盘占用 |
.worktreeinclude文件 | 将 gitignore 的文件(.env、secrets.json等)自动复制进 worktree |
| tmux 集成 | --worktree --tmux在新 tmux 窗口启动 worktree 会话 |
设计文档在 D 阶段还留了三个开放问题:--worktree-keep-on-exitflag(建议先不加,等反馈)、symlinkDirectoriesper-project override(settings 已有 user/workspace/project 三级合并,无需特殊处理)、PR fetch 取head还是mergeref(沿用head)。
十二、延伸阅读:仓库内关键实现索引
- 设计文档:docs/design/worktree.md;用户文档:docs/users/features/worktree.md
- 工具实现:enter-worktree.ts、exit-worktree.ts、工具名常量 tool-names.ts
- 核心服务:gitWorktreeService.ts(
createUserWorktreeL2087、parsePRReferenceL1628、configureHooksPathL2202、symlinkConfiguredDirectoriesL2299、Arena 批量接口setupWorktreesL1016)、worktreeSessionService.ts、worktreeCleanup.ts - Agent 隔离:agent.ts(
isolation参数与校验)、fork-subagent.ts(buildWorktreeNotice)、worktree-pin.ts(caller-owned worktree pin) - CLI 启动路径:worktreeStartup.ts、config.ts(yargs 选项)、settingsSchema.ts(
worktreenamespace)、headless 注入 nonInteractiveCli.ts - UI 状态:UIStateContext.tsx(
activeWorktree) - 测试:enter-worktree.test.ts、exit-worktree.test.ts、worktreeStartup.test.ts、worktreeCleanup.test.ts、gitWorktreeService.symlinks.integ.test.ts(symlink 集成测试)、gitWorktreeService.hooks.integ.test.ts(hooks 集成测试)
整体来看,这套设计的工程取舍很清晰:通用层与 Arena 层物理隔离保证存量功能零回归;命名空间(agent-/pr-保留前缀)+ 会话 marker + sidecar 三层机制解决「谁的 worktree、谁负责清理」的所有权问题;fail-open 与 fail-closed 的边界(setup 尽力而为、删除与 fetch 必须严格)贯穿每一个删除与启动路径,使「隔离工作环境」在 Agent 自主操作的场景下依然是可审计、可恢复、可回滚的。
【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考