@aicoffe/agent-worktree-kit
v0.4.3
Published
`@aicoffe/agent-worktree-kit` 是一个零配置的 git worktree 生命周期 CLI,专为 Agent 编程工作流设计:一条 `wt init feat/foo` 完成「建分支 + 建 worktree + 复制环境文件 + 前台启动 Agent」,一条 `wt cleanup feat/foo` 安全地删除整个任务环境。它只做代码隔离,不维护任何中心状态。
Readme
Agent Worktree Kit (wt)
@aicoffe/agent-worktree-kit 是一个零配置的 git worktree 生命周期 CLI,专为 Agent 编程工作流设计:一条 wt init feat/foo 完成「建分支 + 建 worktree + 复制环境文件 + 前台启动 Agent」,一条 wt cleanup feat/foo 安全地删除整个任务环境。它只做代码隔离,不维护任何中心状态。
一、五分钟上手
# 1. 全局安装
npm install -g @aicoffe/agent-worktree-kit
# 2. 创建分支与 worktree(在任意 git 仓库根执行)
wt init feat/foo
# 3. 创建后直接前台启动你的 Agent
wt init feat/foo --harness claude
# harness 是任意命令字符串(shell 语义),例如带参数启动 cursor
wt init feat/foo --harness "cursor ."wt init 默认自动识别基线分支(读 origin/HEAD,失败则经 git remote set-head origin -a 刷新重读,再回退 origin/main → origin/master → 当前 HEAD),把 .env.example 复制为 worktree 内的 .env.local,并把 .worktrees/ 幂等写入 .git/info/exclude(不碰你的 .gitignore)。
--harness 启动时,wt 会尽力把主仓库的项目级 harness 配置注入环境变量(如 OPENCODE_CONFIG_DIR → 主仓库 .opencode/)——worktree 内启动的 agent 因此能吃到主仓库的 agents/commands/plugins 等项目级配置。零配置即可对 opencode / codex / cursor / aider 生效(仅当主仓库确实存在对应配置时注入;shell 已有的同名变量永不覆盖;--no-harness-env 一键关闭;详见「四、设计哲学」)。
可选:用 wt config init 生成 .worktreerc.json 固化默认值,之后 --harness / --env-* 参数不用每次敲。完全跳过这一步也能用——零配置是设计目标。
二、命令速查表
共 8 个命令,签名与 wt <command> --help 输出一致:
| 命令签名 | 用途 |
|---|---|
| wt init [options] <branch> | 创建新 worktree 与分支并完成环境初始化。选项:--base <ref>(基线引用,缺省自动识别:origin/HEAD → origin/main → origin/master → HEAD)、--harness <cmd>(创建后前台启动)、--no-harness-env(关闭 harness 配置注入)、--env-source <file>(默认 .env.example,相对主仓库根)、--env-target <file>(仅纯文件名,默认 .env.local)、--json(仅输出单一 JSON 结果对象) |
| wt exec [options] <branch> [cmdArgs...] | 在指定分支的 worktree 内执行命令,退出码透传。--harness <cmd> 以 shell 语义执行;否则取 -- 后的参数逐参执行(无 shell),如 wt exec feat/foo -- node -v |
| wt cleanup [options] [branch] | 删除 worktree 与本地分支,含保护拦截与分支名确认。选项:--force(连同未提交/未跟踪与 ignored 文件一并删除)、--delete-remote(同时删远程分支,失败仅警告)、--yes(跳过分支名确认,非交互环境必需)。<branch> 缺省为当前 worktree 分支 |
| wt status [options] | 六列展示全部 worktree 状态(WORKTREE \| BRANCH \| PATH \| HARNESS \| CLEANABLE \| BLOCKER)。--json 输出行对象 JSON 数组 |
| wt list [options] | 列出全部 worktree,与 wt status 同构。--json 输出等价结构化数据 |
| wt doctor [options] | 五项健康检测(孤儿目录、分支已删但 worktree 残留、忽略规则缺失、env-target 缺失、重复路径)。--fix 仅自动补全缺失的 .git/info/exclude 忽略规则(安全操作),其余仅报告 |
| wt config init | 在仓库根生成 .worktreerc.json(已存在则不覆盖) |
| wt config show | 标注来源([default] / [rc])展示有效配置 |
退出码约定:0 成功;1 运行错误(分支已存在、worktree 不存在、配置非法等);2 保护拦截或用户中止;exec / harness 子进程退出码原样透传。
三、.worktreerc.json 配置文件
完全可选。用 wt config init 生成,放在仓库根:
{
"$schema": "https://agent-worktree-kit.dev/schema.json",
"worktreeDir": ".worktrees",
"baseBranch": null,
"envSource": ".env.example",
"envTarget": ".env.local",
"harness": {
"default": null,
"env": {},
"envByCommand": {}
}
}| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| $schema | string | "https://agent-worktree-kit.dev/schema.json" | 占位 URL,仅作编辑器提示;wt 的 zod 校验在本地完成,不会向该地址发起远程请求 |
| worktreeDir | string | ".worktrees" | worktree 存放目录(相对主仓库根) |
| baseBranch | string | null | null | 显式固定 wt init 的基线分支(可被 --base 覆盖);null 表示自动识别:origin/HEAD → git remote set-head origin -a 刷新重读 → origin/main → origin/master → 当前 HEAD |
| envSource | string | ".env.example" | --env-source 默认值(相对主仓库根) |
| envTarget | string | ".env.local" | --env-target 默认值;同时决定写入 .git/info/exclude 的文件名 |
| harness.default | string | null | null | 不传 --harness 时执行的命令;null 表示不启动 |
| harness.env | record<string, string> | 无(缺省不注入) | 启动 harness 时无条件注入的静态键值对(对所有 harness 生效);值支持 ${mainRepoRoot} 字面占位符替换为主仓库根绝对路径(不做任何 shell 展开) |
| harness.envByCommand | record<string, record<string, string>> | 无(缺省不注入) | 按命令首词注入的键值对(如 "opencode": { "OPENCODE_CONFIG_DIR": "${mainRepoRoot}/.opencode" });同 key 覆盖 harness.env 与内置注册表 |
| harness.envHook | string | 无(缺省不执行) | 自定义注入脚本路径(相对主仓库根):以 bash 执行、cwd=主仓库根、5s 超时;wt 注入 WT_MAIN_REPO_ROOT / WT_WORKTREE_PATH / WT_HARNESS_COMMAND 三个变量,脚本 stdout 输出的 KEY=VALUE 行会被注入(# 注释行忽略,其余行忽略并警告,stderr 原样透传);脚本不存在/非零退出/超时 → 警告后跳过脚本注入并继续启动,不回滚 worktree |
注入优先级(同一变量名冲突时,高优先级胜出):用户 shell 已 export 的变量 > envHook 输出 > envByCommand[<首词>] > env > 内置注册表。内置注册表零配置生效:按 --harness 命令首词 basename 匹配(首词为 npx/bunx 取第二词,pnpm dlx 取第三词;大小写敏感),仅当主仓库存在对应配置时注入——opencode → OPENCODE_CONFIG_DIR(.opencode/)+ OPENCODE_CONFIG(opencode.json)、codex → CODEX_HOME(.codex/,注意:共享登录态与会话历史)、cursor → CURSOR_CONFIG_DIR(.cursor/)、aider → AIDER_CONFIG(.aider.conf.yml);claude 与 gemini 刻意不注入(claude 项目级 settings 自 v2.1.246+ 已原生跨 worktree 解析,CLAUDE_CONFIG_DIR 是 user 级重定向;gemini 官方无项目配置重定向环境变量)。--no-harness-env 关闭一切注入(含 rc 配置);rc 层不提供总开关。
规则:所有字段均可省略(省略即用默认值);CLI 选项始终覆盖配置文件;校验由 zod 在本地完成(未知字段/类型错误会指出字段与位置,退出码 1),无任何远程请求。
四、设计哲学
只做代码隔离。 wt 不管理端口、数据库、缓存、容器,不生成环境变量值,不写任何 marker。多环境运行时隔离请交给成熟方案:Dev Container、Docker Compose、direnv。
env 复制是静默的逐字节拷贝。 源文件不存在则静默跳过(不报错、不阻塞、不建空文件);worktree 内目标已存在则不覆盖。不做变量替换、不做模板渲染——源文件是什么样,目标就是什么样。
命令字符串不映射、不校验;环境配置是叠加层。 --harness 的值仍是你自己的命令字符串,wt 原样以 shell 语义在 worktree 内前台阻塞执行,不映射别名、不校验存在性;解析优先级为 CLI 选项 > harness.default > 不启动。wt 只额外做一件事:启动前尽力注入项目级配置环境变量——尽力 = 存在才注入(静默跳过)、shell 已有变量不覆盖、envHook 失败不阻塞(警告 + 继续)、--no-harness-env 一键关闭。注入与启动彼此独立:harness 启动失败不会回滚——worktree 保留,可用 wt exec 重试。
无中心状态。 worktree 清单位置由 git 自己记录(git worktree list),忽略规则只写 .git/info/exclude(不碰 .gitignore),没有 registry、没有锁文件。wt status/wt list 展示的一切都来自 git 与文件系统的实时读取。
五、安全声明
wt cleanup不做合并判断,也不依赖gh。 它不知道也不猜测你的分支是否已合并——这是你的职责。git branch -D是刻意选择。 squash / rebase 方式合并后,git branch -d的合并判断不可靠,因此统一用-D强删。作为补偿,删除前wt cleanup会展示摘要(路径/分支/工作区状态/ignored 文件/远程分支/将执行的命令),要求你输入完整分支名确认,并提醒「请确认该分支对应的 PR 已合并到 main」。- 保护拦截:主 worktree 与
main/master/develop/staging/production/release/*分支一律拒绝清理(退出码 2)。 - 不建议默认使用
--yes。 它跳过分支名确认,为脚本与非交互环境而设;交互场景下保留人工确认这道防线更安全。--force也只越过干净检查、不越过确认。
六、并发约定
不要并发执行 wt init。 多个同时进行的 init 会竞争分支校验、.git/info/exclude 追加与 worktree 创建,产生的冲突不在 wt 的处理范围内。如果环境已出现异常(孤儿目录、忽略规则缺失等),用 wt doctor 检测并修复。
七、平台声明
- 支持 macOS 与 Linux。
- Windows 仅支持经 WSL 使用,原生 Windows 环境未定义、未测试。
- 安全提示:
wt仅执行你自己输入的 harness 命令字符串(以 shell 语义执行)。请勿将来源不明的字符串粘贴为--harness参数——它拥有与你终端相同的一切权限。 - harness 配置注入同样是任意代码执行面:
.worktreerc.json的harness.envHook脚本以bash执行且不做任何沙箱,权限与你的终端相同;脚本来自你自己的 rc 文件,团队仓库中的 rc 文件应视同代码评审对象。另注意CODEX_HOME注入后,codex 在 worktree 内的会话与主仓库共享登录态/会话历史(通常正是想要的;不想要可用--no-harness-env或 rc 反向覆盖)。
License
MIT
