mirror of
https://github.com/jnMetaCode/superpowers-zh.git
synced 2026-09-02 22:54:06 +08:00
fix: 同步上游 D 块 —— worktree 清理静默空转 + Gemini 子智能体支持勘误(#19)
## 1) finishing-a-development-branch:worktree 清理静默空转(上游 0b47219)
真 bug,我们这边与上游同样存在。步骤 6 在步骤 5 已经 cd 到主仓库根之后才用
`git rev-parse --show-toplevel` 重算 WORKTREE_PATH,于是拿到主根路径 ——
`.worktrees/` 溯源判断永远匹配不上,清理静默空转,随后分支删除还会因为
worktree 仍挂着而失败。上游记录说测试对象不得不偏离 skill 原文才能跑通。
修法(4 处):
- 步骤 2 趁还在工作区内就捕获 WORKTREE_PATH
- 步骤 6 改为消费步骤 2 的值,并加显式警告说明为什么不能在此重算
- 步骤 6 去掉冗余的 MAIN_ROOT 推导与 cd(两个调用方都已切好目录)
- 选项 2 补上菜单已声称的分离 HEAD 推送变体
已实际复现验证(临时仓库 + .worktrees/feature):
- 旧逻辑:WORKTREE_PATH 算得 "main" -> 溯源未命中 -> 清理空转
- 新逻辑:捕获到 "main/.worktrees/feature" -> 命中 -> worktree remove 成功、
branch -D 成功(旧逻辑下会因 worktree 仍挂着而失败)
上游第 4 处改动(rationalization 表里"测试早先通过"那行的措辞)本次不适用 ——
我们还是「红线」清单,那张表属 C 块。
## 2) gemini-tools.md:我们错写成「不支持子 Agent」
我们的版本称 Gemini CLI 没有 Task 等价物、依赖子智能体的 skill「退化为
executing-plans 单会话执行」。实际上 Gemini CLI 通过 `invoke_agent`
(`agent_name: "generalist"`,也可用 `@generalist` 聊天语法)支持子智能体,
并且支持在同一响应里发多个调用做并行分派。
这个错误会让 Gemini CLI 用户的 subagent-driven-development /
dispatching-parallel-agents / requesting-code-review 全部瘸腿。
按上游新版重写(33 行 -> 62 行),补齐:动作导向的映射表、指令文件
(GEMINI.md 层级加载)、个人 skills 目录(~/.gemini/skills 与 ~/.agents/skills
的优先级)、子智能体支持与模板填写、并行分派,以及 tracker_* / complete_task /
update_topic / read_mcp_resource 等此前缺失的 20 个工具名。
已全仓扫描,确认没有别处重复这个错误说法。
## 3) audit.sh 结构漂移度量修正(顺带发现的假阳性来源)
3c/3d 用 `grep -cE '^#{1,4} '` 数标题,但这会把 ``` 围栏内的 shell 注释
(`# 运行测试`)当成 markdown 标题 —— 一个 skill 里多几行 bash 注释就能
凭空造出「结构漂移」。
用正确口径(排除围栏)重算 14 个 skill,3 条告警里 2 条是假阳性:
- executing-plans 9/16 WARN -> 9/11 pass
- finishing-a-development-branch 21/31 WARN -> 14/17 pass
- using-git-worktrees 21/28 WARN -> 14/21 WARN(真漂移,保留)
这点很要紧:#19 里引用的上游欠账数字此前是被虚高的。
改为 awk 逐行跟踪围栏状态。双向验证:给 brainstorming 加 5 个真标题会触发
告警(7 vs 13),加 5 行围栏内 shell 注释不触发。
回归:audit.sh 152 pass / 1 warn / 0 fail(原 150 pass / 3 warn)
verify-release.sh 82 pass / 0 fail
This commit is contained in:
@@ -153,6 +153,14 @@ else
|
||||
done
|
||||
|
||||
# 3c. 14 翻译 skill 结构层级(H1-H4 标题数)
|
||||
#
|
||||
# 必须排除 ``` 围栏内的行:shell 注释(`# 运行测试`)同样匹配 ^#{1,4} ,
|
||||
# 会被当成 markdown 标题数进去。用 grep 直接数的话,一个 skill 里多几行
|
||||
# bash 注释就能凭空造出「结构漂移」—— executing-plans 与
|
||||
# finishing-a-development-branch 两条告警此前就是这么来的假阳性。
|
||||
count_headings() { # 读 stdin,只数围栏之外的 H1-H4
|
||||
awk '/^```/{fence = !fence; next} !fence && /^#{1,4} /{n++} END{print n+0}'
|
||||
}
|
||||
declare -a SKILLS=(brainstorming dispatching-parallel-agents executing-plans \
|
||||
finishing-a-development-branch receiving-code-review requesting-code-review \
|
||||
subagent-driven-development systematic-debugging test-driven-development \
|
||||
@@ -160,8 +168,8 @@ else
|
||||
writing-plans writing-skills)
|
||||
|
||||
for s in "${SKILLS[@]}"; do
|
||||
up=$(git show upstream/main:skills/$s/SKILL.md 2>/dev/null | grep -cE '^#{1,4} ' || echo 0)
|
||||
our=$(grep -cE '^#{1,4} ' "skills/$s/SKILL.md" 2>/dev/null || echo 0)
|
||||
up=$(git show upstream/main:skills/$s/SKILL.md 2>/dev/null | count_headings || echo 0)
|
||||
our=$(count_headings < "skills/$s/SKILL.md" 2>/dev/null || echo 0)
|
||||
diff=$((up - our))
|
||||
abs=${diff#-}
|
||||
# 允许 3 个 header 差异(翻译造成的合并/拆分小幅波动)
|
||||
@@ -173,8 +181,8 @@ else
|
||||
done
|
||||
|
||||
# 3d. requesting-code-review/code-reviewer.md 结构(v5.1.0 self-contained)
|
||||
up=$(git show upstream/main:skills/requesting-code-review/code-reviewer.md 2>/dev/null | grep -cE '^#{1,3} ' || echo 0)
|
||||
our=$(grep -cE '^#{1,3} ' skills/requesting-code-review/code-reviewer.md)
|
||||
up=$(git show upstream/main:skills/requesting-code-review/code-reviewer.md 2>/dev/null | count_headings || echo 0)
|
||||
our=$(count_headings < skills/requesting-code-review/code-reviewer.md)
|
||||
diff=$((up - our))
|
||||
abs=${diff#-}
|
||||
if [ "$abs" -le "2" ]; then
|
||||
|
||||
@@ -50,6 +50,9 @@ npm test / cargo test / pytest / go test ./...
|
||||
```bash
|
||||
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)
|
||||
# 现在就捕获 —— 此刻还在工作区里面。步骤 5 会切换目录,
|
||||
# 而清理(步骤 6)需要这个值
|
||||
WORKTREE_PATH=$(git rev-parse --show-toplevel)
|
||||
```
|
||||
|
||||
这决定了展示哪种菜单、以及清理方式:
|
||||
@@ -129,6 +132,8 @@ git branch -d <feature-branch>
|
||||
```bash
|
||||
# 推送分支
|
||||
git push -u origin <feature-branch>
|
||||
# 从分离 HEAD 出发时,在远端指定新分支名:
|
||||
# git push origin HEAD:refs/heads/<new-branch>
|
||||
|
||||
# 创建 PR
|
||||
gh pr create --title "<title>" --body "$(cat <<'EOF'
|
||||
@@ -179,21 +184,15 @@ git branch -D <feature-branch>
|
||||
|
||||
### 步骤 6:清理工作区
|
||||
|
||||
**只对选项 1 和 4 执行。** 选项 2 和 3 始终保留 worktree。
|
||||
**只对选项 1 和 4 执行。** 选项 2 和 3 始终保留 worktree。两个调用方都已经切到主仓库根目录了 —— 移除 worktree 必须从 worktree 外面执行 —— 因此这里使用**步骤 2 里捕获的** `GIT_DIR` / `GIT_COMMON` / `WORKTREE_PATH`,也就是那次目录切换之前的值。
|
||||
|
||||
```bash
|
||||
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)
|
||||
WORKTREE_PATH=$(git rev-parse --show-toplevel)
|
||||
```
|
||||
> ⚠️ **不要在这里重新计算这些值。** 此刻 `git rev-parse --show-toplevel` 返回的是主仓库根目录,不是 worktree 路径 —— 溯源判断会永远匹配不上,清理会静默空转,随后分支删除还会因为 worktree 仍挂着而失败。
|
||||
|
||||
**如果 `GIT_DIR == GIT_COMMON`:** 普通仓库,无 worktree 可清理。结束。
|
||||
|
||||
**如果 worktree 路径在 `.worktrees/` 或 `worktrees/` 之下:** 这是 Superpowers 创建的 worktree —— 我们负责清理。
|
||||
**如果 `WORKTREE_PATH` 在 `.worktrees/` 或 `worktrees/` 之下:** 这是 Superpowers 创建的 worktree —— 我们负责清理。
|
||||
|
||||
```bash
|
||||
MAIN_ROOT=$(git -C "$(git rev-parse --git-common-dir)/.." rev-parse --show-toplevel)
|
||||
cd "$MAIN_ROOT"
|
||||
git worktree remove "$WORKTREE_PATH"
|
||||
git worktree prune # 自愈:清理任何过期的注册记录
|
||||
```
|
||||
|
||||
@@ -1,33 +1,63 @@
|
||||
# Gemini CLI 工具映射
|
||||
|
||||
Skills 使用 Claude Code 的工具名称。在 Gemini CLI 中遇到这些名称时,请使用对应的平台等价工具:
|
||||
Skills 说的是动作("分派一个子智能体"、"建一条待办"、"读一个文件")。在 Gemini CLI 上,这些动作对应下面这些工具。
|
||||
|
||||
| Skill 中的引用 | Gemini CLI 等价工具 |
|
||||
|---------------|-------------------|
|
||||
| `Read`(读取文件) | `read_file` |
|
||||
| `Write`(创建文件) | `write_file` |
|
||||
| `Edit`(编辑文件) | `replace` |
|
||||
| `Bash`(执行命令) | `run_shell_command` |
|
||||
| `Grep`(搜索文件内容) | `grep_search` |
|
||||
| `Glob`(按名称搜索文件) | `glob` |
|
||||
| `TodoWrite`(任务跟踪) | `write_todos` |
|
||||
| `Skill` 工具(调用 skill) | `activate_skill` |
|
||||
| `WebSearch` | `google_web_search` |
|
||||
| `WebFetch` | `web_fetch` |
|
||||
| `Task` 工具(派遣子 agent) | 无等价工具——Gemini CLI 不支持子 agent |
|
||||
| Skill 请求的动作 | Gemini CLI 等价工具 |
|
||||
|----------------|-------------------|
|
||||
| 读取一个文件 | `read_file` |
|
||||
| 一次读取多个文件 | `read_many_files` |
|
||||
| 创建新文件 | `write_file` |
|
||||
| 编辑文件 | `replace` |
|
||||
| 执行 shell 命令 | `run_shell_command` |
|
||||
| 搜索文件内容 | `grep_search` |
|
||||
| 按名称查找文件 | `glob` |
|
||||
| 列出文件和子目录 | `list_directory` |
|
||||
| 抓取 URL | `web_fetch` |
|
||||
| 搜索网页 | `google_web_search` |
|
||||
| 调用一个 skill | `activate_skill` |
|
||||
| 分派子智能体(`Subagent (general-purpose):` 模板) | `invoke_agent`,`agent_name: "generalist"`(也可用 `@generalist` 聊天语法调用——见[子智能体支持](#子智能体支持)) |
|
||||
| 多个并行分派 | 同一条响应里发多个 `invoke_agent` 调用 |
|
||||
| 任务跟踪("建一条待办"、"标记完成") | `write_todos`(状态:pending、in_progress、completed、cancelled、blocked) |
|
||||
|
||||
## 不支持子 Agent
|
||||
## 指令文件
|
||||
|
||||
Gemini CLI 没有 Claude Code `Task` 工具的等价物。依赖子 agent 派遣的 skills(`subagent-driven-development`、`dispatching-parallel-agents`)将退化为通过 `executing-plans` 进行单会话执行。
|
||||
当某个 skill 提到"你的指令文件"时,在 Gemini CLI 上指的是 **`GEMINI.md`**。Gemini CLI 按层级加载 `GEMINI.md`:全局的在 `~/.gemini/GEMINI.md`,项目级的在工作区目录及其各级父目录里,另外当某个工具访问子目录中的文件时,该子目录下的 `GEMINI.md` 也会被加载。
|
||||
|
||||
## 个人 skills 目录
|
||||
|
||||
用户级 skills 放在 **`~/.gemini/skills/`**,**`~/.agents/skills/`** 是跨运行时的别名目录(与 Codex、Copilot CLI 共用)。当同一层级下两个目录都存在时,`.agents/skills/` 优先。每个 skill 是一个子目录,里面有一份带 `name` 和 `description` frontmatter 的 `SKILL.md`。
|
||||
|
||||
## 子智能体支持
|
||||
|
||||
Gemini CLI 通过 `invoke_agent` 工具分派子智能体,该工具接收 `agent_name` 和 `prompt` 两个参数。同一个分派动作也有聊天语法快捷方式:输入 `@generalist <prompt>` 等价于以 `agent_name: "generalist"` 调用 `invoke_agent`。内置的 agent 名包括 `generalist`、`cli_help`、`codebase_investigator`,以及(启用浏览器工具后的)`browser_agent`。
|
||||
|
||||
Skills 用 `Subagent (general-purpose):` 来分派,并且要么引用一个提示词模板文件(例如 `superpowers:subagent-driven-development` 的 `./implementer-prompt.md`),要么直接给出内联提示词。在 Gemini CLI 上:
|
||||
|
||||
| Skill 里的分派形式 | Gemini CLI 等价做法 |
|
||||
|------------------|-------------------|
|
||||
| 引用某个 `*-prompt.md` 模板(implementer、task-reviewer、code-reviewer 等) | 把模板填好,然后以 `agent_name: "generalist"` 和填好的提示词调用 `invoke_agent` |
|
||||
| 引用 `superpowers:requesting-code-review` 的 `./code-reviewer.md` | 以 `agent_name: "generalist"` 和填好的审查模板调用 `invoke_agent` |
|
||||
| 内联提示词(没有引用模板) | 以 `agent_name: "generalist"` 和你的内联提示词调用 `invoke_agent` |
|
||||
|
||||
### 填写提示词
|
||||
|
||||
Skills 提供的提示词模板里有 `{WHAT_WAS_IMPLEMENTED}` 或 `[FULL TEXT of task]` 这类占位符。把所有占位符都填好,再把完整提示词交给 `invoke_agent`。模板本身就包含了该 agent 的角色、审查标准和期望的输出格式——子智能体会照着它执行。
|
||||
|
||||
### 并行分派
|
||||
|
||||
Gemini CLI 支持并行分派子智能体。在同一条响应里发出多个 `invoke_agent` 调用(或在一个提示词里写多个 `@generalist` 调用),即可让相互独立的子智能体工作并行跑。有依赖关系的任务保持串行,但**不要**为了让历史记录简单一点就把相互独立的子智能体任务串起来。
|
||||
|
||||
## Gemini CLI 额外工具
|
||||
|
||||
以下工具在 Gemini CLI 中可用,但 Claude Code 中没有对应工具:
|
||||
以下工具是 Gemini CLI 独有的:
|
||||
|
||||
| 工具 | 用途 |
|
||||
|------|------|
|
||||
| `list_directory` | 列出文件和子目录 |
|
||||
| `save_memory` | 将信息持久化到 GEMINI.md,跨会话保留 |
|
||||
| `ask_user` | 向用户请求结构化输入 |
|
||||
| `tracker_create_task` | 丰富的任务管理(创建、更新、列表、可视化) |
|
||||
| `enter_plan_mode` / `exit_plan_mode` | 切换到只读研究模式,在修改前先调研 |
|
||||
| `save_memory`(旧版) | 当 `experimental.memoryV2 = false` 时,跨会话持久化事实 |
|
||||
| `get_internal_docs` | 查阅 Gemini CLI 自带的文档 |
|
||||
| `ask_user` | 向用户提出结构化问题(文本 / 单选 / 多选) |
|
||||
| `enter_plan_mode` / `exit_plan_mode` | 进入和退出只读的计划模式 |
|
||||
| `update_topic` | 更新当前会话的主题 / 战略意图元数据 |
|
||||
| `complete_task` | 表示某个 Gemini 子智能体已完成,并把结果返回给父 agent |
|
||||
| `tracker_create_task`、`tracker_update_task`、`tracker_get_task`、`tracker_list_tasks`、`tracker_add_dependency`、`tracker_visualize` | 功能完整的任务跟踪器,支持依赖关系与可视化 |
|
||||
| `read_mcp_resource`、`list_mcp_resources` | 访问 MCP 资源 |
|
||||
|
||||
Reference in New Issue
Block a user