这两个技能通过 GIT_DIR != GIT_COMMON 检测实现“检测-延迟”架构,强制 AI 代理先判断是否已处于隔离环境,再决定是使用原生工具创建工作树、回退到 git 命令,还是直接复用。分支收尾时则以测试通过为硬门禁,并基于工作树来源决定是否清理,确保开发闭环安全可靠。

using-git-worktrees 与 finishing-a-development-branch:SuperPowers 如何隔离开发并安全收尾

Superpowers 的 AI 编码代理工作流中,功能开发始于设计(头脑风暴),终于代码集成。using-git-worktreesfinishing-a-development-branch 两个技能共同守护着这个过程的起点与终点,确保开发在隔离中进行,在验证后收尾。v5.1.0 对这两个技能进行了基于 TDD 的重写,引入了“检测-延迟”(detect-and-defer)架构,使其能智能适配不同 AI 编码平台的原生工作树管理。

为什么 AI 代理需要隔离工作区与规范收尾

当 AI 代理在主分支上直接工作,或同时处理多个功能时,极易导致提交混乱或破坏主分支稳定性。git worktree 允许在同一个仓库下创建多个工作目录,每个检出不同分支,互不干扰。然而,现代 AI 编码平台(如 Claude Code、Codex App)自身可能就提供了工作树管理。Superpowers 的 using-git-worktrees 技能不再强制创建,而是优先检测并尊重现有隔离。当功能完成后,简单地删除分支或推送代码存在风险。finishing-a-development-branch 技能则通过强制测试验证和提供结构化选项,确保每一次分支结束都是安全、可审计的决策。

using-git-worktrees:创建隔离工作区的智能流程

该技能的核心原则是:首先检测现有隔离,然后优先使用原生工具,最后才回退到 git 命令。整个过程分为几个关键步骤。

Step 0:检测现有隔离

在尝试创建任何工作树之前,代理必须运行一组只读 Git 命令来判断当前环境:

GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
BRANCH=$(git branch --show-current)

这里有一个关键的子模块防护GIT_DIR != GIT_COMMON 在 git 子模块中也为真。因此,在得出“已处于工作树”的结论前,必须排除子模块:

git rev-parse --show-superproject-working-tree 2>/dev/null
  • 如果 GIT_DIR != GIT_COMMON(且非子模块):表明代理已处于由平台管理(如 Codex App)或之前技能创建的工作树中。代理将跳过创建工作树,直接运行项目设置(如 npm install)和基线测试,并根据分支状态报告“已位于隔离工作区”。这是防止重复创建的核心检测
  • 如果 GIT_DIR == GIT_COMMON(或在子模块中):代理处于普通仓库检出中,需要决定是否创建工作树。

Step 0.5:同意确认(Opt-in)

在普通仓库中,如果用户指令中没有预先声明偏好,代理会请求明确同意:

“您是否希望我设置一个隔离的工作树?这可以保护您当前的分支不受改动影响。”

用户同意后,才进入创建工作流。若用户拒绝,则在当前位置工作,跳过工作树创建。这一步将创建工作树从“默认行为”变为“需要授权”,避免了意外干扰。

Step 1:创建隔离工作区

此步骤遵循严格的优先级顺序,首选原生平台工具,其次才是 git 回退。

1a. 原生工作树工具(首选) 代理会检查其工具集中是否包含类似 EnterWorktreeWorktreeCreate/worktree 命令或 --worktree 标志的原生工具。如果存在,必须使用它,并跳过后续的 git 回退步骤。原生工具能无缝处理目录创建、分支设置和后续清理,使用它们可避免“幽灵状态”——即技能创建的工作树对平台不可见,或平台创建的工作树对技能不可见。

1b. Git 工作树回退 仅当没有原生工具时使用。此路径包含三个关键子环节:

  1. 目录选择优先级:代理按顺序查找:

    • 项目根目录下的 .worktrees/(首选)或 worktrees/ 目录。
    • 旧版全局目录 ~/.config/superpowers/worktrees/<项目名>/(向后兼容)。
    • 项目代理指令文件(如 CLAUDE.mdAGENTS.md)中指定的目录。
    • 默认使用 .worktrees/。 此优先级确保了一致性和对项目约定的尊重。
  2. 安全验证:对于项目本地目录,必须在创建前验证其已被 Git 忽略:

    git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null

    如果未被忽略,代理会立即将其加入 .gitignore 并提交。这是防止工作树中产生的临时文件污染主分支历史的关键安全措施

  3. 创建与配置

    git worktree add "$path" -b "$BRANCH_NAME"
    cd "$path"

    创建后,技能会自动将主仓库的 hooks 目录符号链接到新工作树,确保预提交检查等钩子在新环境中持续生效。 如果 git worktree add 因权限错误(沙箱拒绝)失败,代理会触发沙箱回退:停止创建工作树,转而在当前目录运行设置和测试,并将当前环境视为隔离工作区。这确保了在 Codex App 等受限环境中技能的优雅降级。

finishing-a-development-branch:安全收尾分支的规范流程

当开发完成(通常由 subagent-driven-developmentexecuting-plans 技能触发),此技能引导代理以安全、结构化的方式结束分支。核心原则是:先验证,再检测,后选择,最后清理

Step 1:验证测试(硬门禁)

在提供任何选项前,代理必须运行项目的测试套件。只有所有测试通过,流程才继续。如果测试失败,流程立即停止并报告错误。这是防止将有缺陷代码引入主分支的第一道,也是最重要的质量门禁

Step 2:检测环境

代理再次运行环境检测命令,以确定可用的选项和清理行为:

GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)

此检测结果决定三个路径:

  • 路径 A(GIT_DIR != GIT_COMMONBRANCH 为空):在外部管理的工作树中且处于“分离头指针”状态(典型如 Codex App 沙箱)。代理不会呈现标准菜单,而是确保所有工作已提交,然后输出一个交接载荷,包含当前提交哈希、数据丢失警告、建议的分支名和提交信息,指引用户使用宿主应用(如 Codex App 的“创建分支”按钮)完成后续操作。
  • 路径 B(GIT_DIR != GIT_COMMON 且有命名分支):在外部管理的工作树中但有分支。呈现标准的四个选项菜单。
  • 路径 C(GIT_DIR == GIT_COMMON:普通环境。呈现标准的四个选项菜单。

Step 3 与 Step 4:确定基准分支与呈现选项

在路径 B 和 C 中,代理会确定基准分支(如 main),然后清晰地列出四个选项供选择:

  1. 本地合并回基准分支
  2. 推送并创建 Pull Request (PR)
  3. 保留分支现状(不进行任何操作)
  4. 丢弃此工作

对于选项 4,代理会要求用户输入 discard 进行二次确认,并列出即将被删除的分支和提交,防止误操作。

Step 5:执行选择与清理

根据用户选择执行操作,并在需要时清理工作树。清理逻辑基于来源判断(Provenance-based):

  • 仅在选项 1(合并)和 4(丢弃)后执行清理。选项 2 和 3 始终保留工作树。
  • 清理前,代理会再次检测 GIT_DIRGIT_COMMON。如果当前处于外部管理的工作树中(GIT_DIR != GIT_COMMON),则跳过 git worktree remove,因为宿主环境应负责其生命周期。
  • 只有当工作树位于 .worktrees/~/.config/superpowers/worktrees/ 下时,才认为该工作树由 Superpowers 创建,代理拥有清理权限。此时,代理会 cd 到主仓库根目录后执行 git worktree remove,并随后运行 git worktree prune 清理可能残留的陈旧记录。
  • 对于选项 1(合并),操作顺序至关重要:必须先合并成功并验证测试,然后才能清理工作树并删除分支。这解决了旧版本中“先删分支导致清理失败”的 bug。

在 Superpowers 工作流中的协同作用

这两个技能并非孤立存在,而是深度嵌入 Superpowers 的 完整工作流闭环 中:

  1. 头脑风暴 (brainstorming) 产出设计方案后,如需实现,将调用 using-git-worktrees 创建隔离工作区。
  2. 编写计划 (writing-plans) 产出可执行计划后,subagent-driven-developmentexecuting-plans 在执行每个任务前,会先确保工作空间就绪。
  3. 所有任务执行完毕并通过 测试驱动开发 (test-driven-development)完成前验证 (verification-before-completion) 后,finishing-a-development-branch 被调用,引导代理安全地整合或处置分支。
  4. 清理工作树,整个开发循环结束。

这种设计使得从构思到代码合并的每一步都处于受控状态,既保证了开发效率,又维护了代码库的健康。

FAQ

Q: Step 0.5 的同意确认(opt-in)是否会影响自动化流程的效率? A: 不会。该步骤是智能的:如果用户指令中已声明偏好(例如在配置文件中设置),代理会直接遵从,不会再次询问。只有在没有预先偏好时才会请求同意,这平衡了自动化与用户控制。

Q: 当 AI 代理处于“分离头指针”状态(如 Codex App 沙箱)时,如何创建 PR? A: 代理无法直接在该环境中创建分支或推送。此时,finishing-a-development-branch 技能会输出一份详细的“交接载荷”,包含建议的分支名、提交信息和当前提交哈希,引导用户使用宿主应用(如 Codex App 的“创建分支”或“移交到本地”控件)来完成后续的创建分支、推送和创建 PR 操作。

Q: 为什么有时会跳过清理工作树? A: 清理逻辑基于“来源判断”。如果当前工作树由 AI 编码平台(如 Claude Code、Codex App)的原生工具创建和管理(路径不在 .worktrees/~/.config/superpowers/worktrees/ 下),则 Superpowers 的技能不会触碰它,由平台负责其生命周期。这防止了“幽灵状态”和权限错误。只有 Superpowers 通过 git 回退创建的工作树,技能才会在适当时机清理。