<!-- codsh-publication:grok-cli-dsh-rewrite:ticket-42 --> ## Parent https://github.com/Blackman99/codsh/issues/132 **Ticket:** 42 **Status:** ready-for-agent **User Stories:** 29, 44(见父规格) ## What to build 用户分叉或委派到隔离工作树,检查并显式应用结果,失败或取消后能安全保留/清理目录。 ## Acceptance criteria - [ ] 支持参考的本地 worktree 创建/恢复/列举/应用/清理行为,agent 工作目录与界面提示一致。 - [ ] 脏工作区、同名分支、非 Git 目录、冲突和取消不覆盖用户已有修改。 - [ ] 隔离后的权限和会话身份正确;应用结果是可见动作,不因子代理完成自动破坏主工作区。 - [ ] 用临时真实 Git 仓库验证分支、文件和清理效果,公开命令/协议与界面一致。 ## Blocked by - #160 — Ticket 28: 对话分叉与回退 - #172 — Ticket 40: dsh 子代理执行与任务视图 ## Delivery contract 用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。
Activity
feat(rust): run typed dsh subagents with a task view
Blackman99 commentedon Sep 25, 2026
Ticket 42 / #174 已合入
rewrite/grok-dsh-20260920的7b96914。codsh --rust -w [NAME](--worktree=NAME)在$GROK_HOME/worktrees/<repo>/<name>新建 git worktree(分支codsh/<name>),在--cwd之后、读取配置/信任/沙箱之前进入。默认从 HEAD 加上未提交和未跟踪(未忽略)的文件建一个快照提交,原 checkout、索引和分支不变;--worktree-ref/--ref给干净 checkout。重名加-2、-3后缀,已有分支不会被复用或重置。非 git 目录、未初始化仓库、bare 仓库、无效 ref 都被拒绝且不留下任何东西。-w -r <id>/-w -c把会话复制成新 id 放进新 worktree 并续接副本,原会话不动。状态行显示 worktree 和分支。codsh --rust worktree list|show|apply|rm|gc|db和会话内/worktree管理 worktree。apply默认合并:只有 checkout 仍是 worktree 起点内容时才写入,其余列为冲突不动(退出码 5),--overwrite取 worktree 版本,--dry-run只报告;apply 不提交、不暂存,拒绝符号链接和越界路径。rm对有未提交内容的 worktree 需-f,分支有提交时保留分支。gc不给--max-age不过期任何东西,保留有未提交/未跟踪/非缓存忽略文件、未被分支持有的提交或存活所有者的 worktree。detach、salvage、clean-artifacts明确拒绝(没有 Grove 投影)。子代理
isolation: "worktree"在自己的 worktree 中执行:未改动时自动删除,有改动时保留并在工具块和/tasks中给出 worktree 与分支,取消时删除。worktree 中的文件权限同时按 worktree 路径和对应的 checkout 路径评估,取更严格的结果,所以 checkout 上的 deny 规则也覆盖 worktree 副本。验证(全部只在 Linux 上):新增
scripts/rust-worktree.spec.mjs19 项通过,和rust-acp-protocol、rust-subagents、rust-mcp一起 80/80 通过;新增scripts/rust-worktree-pty-test.py通过(会话隔离、/worktree apply、子代理保留、冲突、-w -r分叉、后缀、非 git 拒绝、rm 与 gc),rust-subagent-pty-test.py和rust-queue-pty-test.py在合入后的代码上也通过;pnpm run typecheck通过;pnpm test2350 通过、2 失败(reference-evidence.spec.mjs和rust-launcher.spec.mjs在高负载下 5 秒超时,单独运行分别 11/11、4/4 通过,与本改动无关);Rust 工作区测试 codsh-rust 508 通过、4 失败,其余 crate 982 通过;cargo fmt --check通过。失败的 4 项都在本改动未触及的文件里:filesystem_sandbox.rs两项是已知的 Linux 沙箱环境限制;voice和privacy各一项是本地回环服务器只读一次请求导致的时序抖动(privacy单独重跑 3 次通过 1 次)。strict clippy 只报filesystem_sandbox.rs两个既有问题。未验证:macOS 与 Windows 完全没有运行过——路径解析(macOS
/private符号链接、大小写不敏感文件系统、Windows 盘符与 junction)、符号链接拒绝和所有 PTY 流程都只在 Linux 上验证。rust-fork-pty-test.py只能在 macOS 上运行,本次只改了其中一条提示文字,未运行。本机没有 bubblewrap,文件系统沙箱下的 worktree(写入范围不够时 git 报错、不应用任何东西)没有端到端验证。与参考二进制的逐项对照未做。未实现:Grove / fast / btrfs worktree;新会话和分叉的 worktree 提示(
hints.*_worktree_mode)和自动 gc;x.ai/git/worktree/*ACP 扩展;运行中会话内的/fork --worktree(被拒绝,改用-w -r)。已知限制:快照提交不区分已暂存和未暂存;apply不应用仅权限位(chmod)的变化;du不统计 worktree 池;worktree 是独立的信任与授权工作区,会重新询问;worktree 会话内/new之后登记表里的 sessionId 不更新。main、npm 和默认版本都没有改动。
#191(远程克隆与工作树)和 #208(Ship 完整流程)不再等待本 ticket,但 #191 仍等 #190,#208 仍等 #195、#196。