关于 babysit-pr
babysit-pr 是面向编码 Agent 的长期运行技能,用于跟进单个 PR 或整个 Graphite 堆栈。它循环检查 CI 与评审意见,按堆栈自底向上修复并验证变更。
主要功能
- 01监控 PR 与 Graphite 堆栈
- 02并行收集 CI 和评审状态
- 03分析失败检查并修复代码
- 04处理评审评论并回复
- 05本地验证、重排堆栈并推送
- 06按状态调整轮询间隔
适用场景
- 01等待 CI 完成并及时修复失败
- 02在多个堆栈 PR 中逐项处理评审意见
- 03确保变更验证后再提交推送
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ neekolas/ claude-skills --skill babysit-pr安装后在 Claude Code 中输入/babysit-pr确认已加载。
详细介绍
Babysit PR
自主监控一个 PR(或整个 Graphite 堆栈),修复 CI 失败、回复评审评论,并推送经过验证的修复。以长时间运行的会话形式运行——在内部循环,并采用智能休眠间隔,直到所有 PR 都准备就绪或用户停止会话。
调用方式
/babysit-pr
会话循环
此技能会持续循环:
- 检测当前分支是否属于 Graphite 堆栈
- 检查堆栈中所有 PR 的状态(CI + 评审)
- 从受影响程度最低的分支开始修复问题
- 如果所有 PR 都已准备就绪 → 输出成功信息并退出
- 否则 → 休眠一段智能设定的时间,然后重复
digraph babysit {
node [shape=box];
"Start session" [shape=doublecircle];
"Detect Graphite stack\n(gt ls)";
"Collect PRs for\nall stack branches";
"Any PRs found?" [shape=diamond];
"Exit: no PRs found" [shape=doubleoctagon];
"For each PR\n(bottom of stack first):\ncheck CI + reviews";
"Any issues found\nacross stack?" [shape=diamond];
"For each branch (bottom-up):\nfix, verify, commit,\nrestack";
"gt submit --stack\n(single push)";
"All PRs: checks green +\ncomments addressed?" [shape=diamond];
"Print: Stack is ready" [shape=doubleoctagon];
"Print remaining issues\n+ sleep interval";
"Sleep with\nintelligent interval";
"Start session" -> "Detect Graphite stack\n(gt ls)";
"Detect Graphite stack\n(gt ls)" -> "Collect PRs for\nall stack branches";
"Collect PRs for\nall stack branches" -> "Any PRs found?";
"Any PRs found?" -> "Exit: no PRs found" [label="no"];
"Any PRs found?" -> "For each PR\n(bottom of stack first):\ncheck CI + reviews" [label="yes"];
"For each PR\n(bottom of stack first):\ncheck CI + reviews" -> "Any issues found\nacross stack?";
"Any issues found\nacross stack?" -> "All PRs: checks green +\ncomments addressed?" [label="no"];
"Any issues found\nacross stack?" -> "For each branch (bottom-up):\nfix, verify, commit,\nrestack" [label="yes"];
"For each branch (bottom-up):\nfix, verify, commit,\nrestack" -> "gt submit --stack\n(single push)";
"gt submit --stack\n(single push)" -> "All PRs: checks green +\ncomments addressed?";
"All PRs: checks green +\ncomments addressed?" -> "Print: Stack is ready" [label="yes"];
"All PRs: checks green +\ncomments addressed?" -> "Print remaining issues\n+ sleep interval" [label="no"];
"Print remaining issues\n+ sleep interval" -> "Sleep with\nintelligent interval";
"Sleep with\nintelligent interval" -> "Detect Graphite stack\n(gt ls)" [label="loop"];
}
1. 检测 Graphite 堆栈
确定当前分支是否属于一个堆栈:
gt ls
这会显示完整的堆栈结构。解析输出,获取按从底部(最接近 trunk)到顶部排列的分支列表。
如果该分支是独立分支(不属于堆栈),则将其视为单分支堆栈——其余流程相同。
2. 收集整个堆栈中的 PR
按从底部到顶部的顺序,为堆栈中的每个分支查找其 PR:
gh pr view <branch> --json number,url,headRefOid
构建一个 (branch, pr_number, headRefOid) 元组列表。跳过尚无 PR 的分支。
如果所有分支都没有 PR,则输出错误并退出。
3. 检查所有 PR 的 CI 和评审
使用子 Agent 并行收集状态。 为每个 PR 派发一个子 Agent,同时获取 CI 状态、评审线程和一般评论。每个子 Agent 会针对分配到的 PR 执行步骤 3a–3c 中的检查,并返回结构化的问题摘要。这样可以保持主上下文整洁,避免跨整个堆栈顺序调用 API。
同样,在调查失败的检查时,为每个失败的运行派发一个子 Agent,以获取日志(gh run view <run-id> --log-failed)并分析根本原因。CI 日志内容冗长——将其隔离在子 Agent 中可避免上下文受到干扰。
将所有问题收集到一个按分支标记的列表中,以便确定优先修复哪个分支。然后按照步骤 4 从底部向上修复。
3a. 检查必需的 CI
gh pr checks <pr_number> --json name,state,bucket,link,required
- 仅处理 HEAD 提交上的检查——通过
headRefOid验证。 - 立即修复失败项——不要等到所有检查都结束。如果部分检查已经失败,而其他检查仍在等待中,立即修复失败项即可。推送会为所有内容触发新一轮 CI 运行。
- 对于每项失败的检查(必需和可选):
- 获取日志:
gh run view <run-id> --log-failed - 调查根本原因
- 修复代码
- 获取日志:
- 如果检查处于
pending或in_progress状态,请记录其已运行的时长(使用gh run view <run-id> --json createdAt),以便设定休眠间隔。 - 对可选检查失败采取尽力而为的处理方式——尽可能修复,但这些失败不会阻止退出。
3b. 行内评审线程
gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 10) {
nodes { body author { login } path line }
}
}
}
}
}
}
'
3c. 一般评审评论
这些是顶层评审评论——评审提交的正文,不针对任何特定文件或行。它们通常包含重要的高层次反馈、架构方面的顾虑或总结请求。
gh api repos/{owner}/{repo}/pulls/{pr}/reviews --jq '.[] | select(.body != "" and .body != null) | {id, body, state, user: .user.login}'
同时获取独立的 PR 评论(对话选项卡中的评论,不属于评审内容):
gh api repos/{owner}/{repo}/issues/{pr}/comments --jq '.[] | {id, body, user: .user.login}'
处理规则
跳过任何满足以下条件的讨论串/评论:
- 已解决(针对讨论串)
- 已由 babysitter 处理(最后一条回复来自机器人 / 以 🤖 开头)
对其余每个讨论串或评论进行分类并采取相应操作。
所有回复都必须以 🤖 开头,以表明由 AI 辅助。
| 类型 | 信号 | 操作 |
|---|---|---|
| 实际问题 | Bug、正确性问题、缺少边界情况、安全问题 | 修复代码。回复:“🤖 已修复 — [变更说明]”。解决讨论串(如适用)。 |
| 范围变更 | 功能请求、风格偏好、行为变更 | 回复:“🤖 这超出了此 PR 的范围。[简要说明]”。保持未解决。 |
| 非问题 | 误解、已处理、事实错误 | 回复:“🤖 [说明为何这不是问题]”。保持未解决。 |
对于常规审查评论,使用相应的 API 回复:
- 审查评论:
gh api repos/{owner}/{repo}/pulls/{pr}/reviews/{review_id}/comments或回复审查 - Issue 评论:
gh api repos/{owner}/{repo}/issues/{pr}/comments -f body="..."
4. 自下而上修复问题
如果在堆栈中的多个 PR 发现问题,务必先修复最底层的分支。较低分支上的修复可能会在重新整理堆栈后解决较高分支中的问题。
重要:每轮迭代只推送一次。 在本地应用所有修复,然后在最后推送整个堆栈。
对于每个存在问题的分支(从底部到顶部):
- 检出分支:
gt checkout <branch> - 修复该分支的所有 CI 失败和审查评论(遵循步骤 3 中的规则)
- 运行有针对性的本地验证 — 对修改的文件运行 lint 和类型检查,并且只运行会测试修改代码的测试(不要运行完整测试套件)。参考项目的 CLAUDE.md/AGENTS.md,确定如何运行指定范围的测试(例如,传入特定测试文件、目录或过滤模式)。如果验证失败,修复问题并重新验证,直到通过。
- 在本地提交:
gt modify --commit - 重新整理堆栈,使较高分支包含这些变更:
gt restack - 继续处理下一个存在问题的分支
所有分支修复完成后:
- 一次性推送整个堆栈:
gt submit --stack
5. 睡眠间隔逻辑
每轮迭代结束后,根据当前状态选择睡眠时长:
| 情况 | 睡眠时长 | 原因 |
|---|---|---|
| 刚推送新代码,CI 尚未启动 | 2 分钟 | CI 需要时间获取新提交 |
| 部分检查失败(已修复并推送),其他检查仍在运行 | 3 分钟 | 新推送会重新运行所有检查,稍后再查看 |
| 所有检查仍在运行,启动时间不到 5 分钟 | 3 分钟 | 检查刚启动,稍后再查看 |
| 所有检查仍在运行,启动时间为 5–15 分钟 | 5 分钟 | 给检查一些时间完成 |
| 所有检查仍在运行,启动时间超过 15 分钟 | 5 分钟 | 检查运行时间较长,继续定期轮询 |
| 所有 CI 检查均通过,正在等待审查者 | 10 分钟 | 人工回复耗时更长 |
| 没有可采取行动的事项,但 PR 尚未完全就绪 | 5 分钟 | 默认轮询间隔 |
照看一组堆栈时,根据所有 PR 中最紧急的情况确定间隔(即采用适用的最短睡眠时长)。
睡眠前打印所选间隔和原因:“Sleeping {N} minutes — {reason}”
使用 shell sleep 等待(例如,5 分钟使用 sleep 300)。
6. 退出条件
堆栈中的所有 PR 满足以下条件后即可就绪:
- 每个 PR 的 HEAD 上所有必需 CI 检查均已通过
- 所有 PR 中的所有评审讨论串均已解决,或最后一条评论是 babysitter 的回复
- 所有 PR 中的所有常规评审评论均已处理(存在 babysitter 的回复)
可选检查失败不会阻止满足此退出条件。如果满足退出条件时可选检查仍未通过,请在输出中注明,但仍要声明堆栈已就绪。
打印:"All required checks passing and all review comments addressed across the stack. PRs are ready."
常见错误
- 依据过时的 CI 结果采取行动 — 调查失败前,务必确认检查针对的是 HEAD 提交。如果检查仍在等待中,请等待。
- 对同一条评论回复两次 — 回复前,检查讨论串中的最后一条回复是否已经来自 babysitter。
- 未经本地验证就推送 — 执行
gt modify --commit前,务必运行项目的验证命令。 - 解决不应解决的讨论串 — 只解决已修复实际问题的讨论串。对于范围变更和非问题讨论串,请保持打开状态,留给评审者处理。
- 遗漏常规评审评论 — 不要只检查行内讨论串。还要始终获取顶层评审正文和 issue 评论;评审者经常会在其中提出最重要的反馈。
- 推送后等待过久 — 推送修复后,使用较短的间隔,以便尽快发现 CI 结果。
- 修复堆栈中的错误分支 — 始终修复存在问题的最低分支。修复更高层的分支可能导致合并冲突,或在重新堆叠时被覆盖。
- 每轮多次推送 — 先在本地修复所有分支(对每个分支执行
gt modify --commit和gt restack),然后使用gt submit --stack推送一次。多次推送会浪费 CI 运行周期并造成竞态条件。 - 修复后忘记重新堆叠 — 修改堆栈中间的分支后,务必先执行
gt restack,再处理下一个分支,这样更高层的分支才能获取这些更改。 - 假设更高层分支不受影响 — 修复并重新堆叠后,从头重新检查所有 PR。重新堆叠可能会导致更高层分支出现新的 CI 失败。
- 在主上下文中按顺序获取 PR 状态和日志 — 使用子 Agent 并行检查每个 PR 的 CI 和评审,并获取详细的 CI 日志。这样可以加快每轮迭代,并让主上下文窗口保持整洁,以便进行决策和修复代码。