babysit-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBabysit PR
PR自动看护(Babysit PR)
Autonomously monitor a PR (or an entire Graphite stack), fix CI failures, respond to review comments, and push verified fixes. Runs as a long-running session — loops internally with intelligent sleep intervals until all PRs are ready or the user stops the session.
自主监控单个PR(或完整的Graphite PR堆栈)、修复CI失败、回复评审评论并推送已验证的修复。它以长时会话模式运行——内部会循环执行,且带有智能休眠间隔,直到所有PR准备就绪或用户终止会话。
Invocation
调用方式
/babysit-pr/babysit-prSession Loop
会话循环
The skill runs in a continuous loop:
- Detect if the current branch is part of a Graphite stack
- Check PR status (CI + reviews) across all PRs in the stack
- Fix issues starting from the lowest affected branch
- If all PRs are ready → print success and exit
- Otherwise → sleep for an intelligent interval, then repeat
dot
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"];
}该工具以持续循环的方式运行:
- 检测当前分支是否属于某个Graphite堆栈
- 检查堆栈中所有PR的状态(CI + 评审情况)
- 从受影响的最底层分支开始修复问题
- 若所有PR准备就绪→打印成功信息并退出
- 否则→进入智能休眠间隔,之后重复循环
dot
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. Detect Graphite Stack
1. 检测Graphite堆栈
Determine if the current branch is part of a stack:
bash
gt lsThis shows the full stack structure. Parse the output to get the ordered list of branches from bottom (closest to trunk) to top.
If the branch is standalone (not part of a stack), treat it as a single-branch stack — the rest of the flow works the same way.
判断当前分支是否属于某个堆栈:
bash
gt ls该命令会显示完整的堆栈结构。解析输出结果,获取从最底层(接近主干)到最顶层的分支有序列表。
如果分支是独立的(不属于任何堆栈),则将其视为单分支堆栈——后续流程保持不变。
2. Collect PRs Across the Stack
2. 收集堆栈中的所有PR
For each branch in the stack (bottom to top), find its PR:
bash
gh pr view <branch> --json number,url,headRefOidBuild a list of tuples. Skip branches that don't have PRs yet.
(branch, pr_number, headRefOid)If no PRs exist for any branch, print an error and exit.
对于堆栈中的每个分支(从底层到顶层),找到对应的PR:
bash
gh pr view <branch> --json number,url,headRefOid构建元组列表。跳过尚未创建PR的分支。
(分支, PR编号, headRefOid)如果所有分支都没有对应的PR,则打印错误信息并退出。
3. Check CI and Reviews Across All PRs
3. 检查所有PR的CI和评审情况
For each PR in the stack (processing bottom-up), run the CI and review checks described in steps 4a–4c below.
Collect all issues into a list tagged by branch, so you know which branch to fix first. Then fix bottom-up per step 4.
针对堆栈中的每个PR(从底层到顶层处理),执行以下步骤4a–4c中描述的CI和评审检查。
将所有问题收集到按分支标记的列表中,这样你就能知道需要优先修复哪个分支。然后按照步骤4从底层到顶层依次修复。
3a. Check Required CI
3a. 检查必填CI任务
bash
gh pr checks <pr_number> --json name,state,bucket,link,required- Only act on checks for the HEAD commit — verify via .
headRefOid - Fix failures immediately — don't wait for all checks to finish. If some checks have already failed while others are still pending, fix the failed ones right away. The push will trigger a fresh CI run for everything anyway.
- For each failing check (required and optional):
- Get logs:
gh run view <run-id> --log-failed - Investigate the root cause
- Fix the code
- Get logs:
- If checks are or
pending, note how long they've been running (usein_progress) to inform sleep interval.gh run view <run-id> --json createdAt - Optional check failures are best-effort — fix them if possible, but they do not block the exit condition.
bash
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. Inline Review Threads
3b. 内联评审线程
bash
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 }
}
}
}
}
}
}
'bash
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. General Review Comments
3c. 通用评审评论
These are top-level review comments — the body text of a review submission, not tied to any specific file or line. They often contain important high-level feedback, architectural concerns, or summary requests.
bash
gh api repos/{owner}/{repo}/pulls/{pr}/reviews --jq '.[] | select(.body != "" and .body != null) | {id, body, state, user: .user.login}'Also fetch standalone PR comments (conversation tab, not part of a review):
bash
gh api repos/{owner}/{repo}/issues/{pr}/comments --jq '.[] | {id, body, user: .user.login}'这些是顶层评审评论——评审提交的正文内容,不绑定到任何特定文件或行。它们通常包含重要的高层次反馈、架构问题或总结性要求。
bash
gh api repos/{owner}/{repo}/pulls/{pr}/reviews --jq '.[] | select(.body != "" and .body != null) | {id, body, state, user: .user.login}'同时获取独立的PR评论(对话标签页,不属于评审的一部分):
bash
gh api repos/{owner}/{repo}/issues/{pr}/comments --jq '.[] | {id, body, user: .user.login}'Processing Rules
处理规则
Skip any thread/comment that:
- Is resolved (for threads)
- Has already been addressed by the babysitter (last reply is from the bot / starts with 🤖)
Classify and act on each remaining thread or comment.
All replies MUST start with 🤖 to identify as AI-assisted.
| Type | Signals | Action |
|---|---|---|
| Real issue | Bug, correctness problem, missing edge case, security concern | Fix code. Reply: "🤖 Fixed — [description of change]". Resolve thread (if applicable). |
| Scope change | Feature request, style preference, behavioral change | Reply: "🤖 This is outside the scope of this PR. [brief explanation]". Leave open. |
| Non-issue | Misunderstanding, already handled, factually incorrect | Reply: "🤖 [explanation of why this isn't an issue]". Leave open. |
For general review comments, reply using the appropriate API:
- Review comments: or reply to the review
gh api repos/{owner}/{repo}/pulls/{pr}/reviews/{review_id}/comments - Issue comments:
gh api repos/{owner}/{repo}/issues/{pr}/comments -f body="..."
跳过以下任何线程/评论:
- 已解决的线程
- 最后一条回复已来自该工具(以🤖开头)的评论
对剩余的每个线程或评论进行分类并处理。
所有回复必须以🤖开头,标识为AI辅助回复。
| 类型 | 特征 | 操作 |
|---|---|---|
| 真实问题 | 漏洞、正确性问题、缺失的边缘情况、安全隐患 | 修复代码。回复:"🤖 已修复——[变更描述]"。(若适用)标记线程为已解决。 |
| 范围变更 | 功能请求、风格偏好、行为变更 | 回复:"🤖 这超出了本次PR的范围。[简要说明]"。保持线程为未解决状态。 |
| 非问题 | 误解、已处理内容、事实错误 | 回复:"🤖 [解释为何这不是问题]"。保持线程为未解决状态。 |
对于通用评审评论,使用对应的API进行回复:
- 评审评论:或直接回复评审
gh api repos/{owner}/{repo}/pulls/{pr}/reviews/{review_id}/comments - 议题评论:
gh api repos/{owner}/{repo}/issues/{pr}/comments -f body="..."
4. Fix Issues Bottom-Up
4. 从底层到顶层修复问题
When issues are found across multiple PRs in the stack, always fix the lowest branch first. A fix in a lower branch may resolve issues in higher branches after restacking.
Important: only push once per loop iteration. Apply all fixes locally, then push the entire stack at the end.
For each branch with issues (bottom to top):
- Checkout the branch:
gt checkout <branch> - Fix all CI failures and review comments for that branch (per step 3 rules)
- Run targeted local verification — lint and typecheck the changed files, and run only the tests that exercise the changed code (not the full suite). Use the project's CLAUDE.md/AGENTS.md to determine how to run scoped tests (e.g., passing specific test files, directories, or filter patterns). If verification fails, fix the issue and re-verify until it passes.
- Commit locally:
gt modify --commit - Restack so higher branches pick up the changes:
gt restack - Continue to the next branch with issues
After all branches have been fixed:
- Push the entire stack once:
bash
gt submit --stack
当堆栈中的多个PR存在问题时,始终优先修复最底层的分支。底层分支的修复内容在重新堆叠后可能会解决顶层分支的问题。
**重要提示:每次循环迭代仅推送一次。**先在本地应用所有修复,最后再推送整个堆栈。
对于每个存在问题的分支(从底层到顶层):
- 切换到目标分支:
gt checkout <branch> - 修复该分支的所有CI失败和评审评论问题(遵循步骤3的规则)
- 执行针对性本地验证——对修改的文件进行代码检查和类型校验,仅运行与修改代码相关的测试(而非全量测试)。参考项目的CLAUDE.md/AGENTS.md文档确定如何运行范围化测试(例如,指定测试文件、目录或过滤规则)。若验证失败,则修复问题并重新验证,直到通过。
- 本地提交:
gt modify --commit - 重新堆叠,使顶层分支获取变更:
gt restack - 继续处理下一个存在问题的分支
所有分支修复完成后:
- 一次性推送整个堆栈:
bash
gt submit --stack
5. Sleep Interval Logic
5. 休眠间隔逻辑
After each iteration, choose a sleep duration based on current state:
| Situation | Sleep Duration | Rationale |
|---|---|---|
| Just pushed new code, CI not started yet | 2 minutes | CI needs time to pick up the new commit |
| Some checks failed (already fixed & pushed), others still running | 3 minutes | Fresh push will re-run everything, check back soon |
| All checks still running, started < 5 min ago | 3 minutes | Checks are fresh, check back soon |
| All checks still running, started 5-15 min ago | 5 minutes | Give checks time to complete |
| All checks still running, started > 15 min ago | 5 minutes | Long-running checks, keep polling steadily |
| All CI green, waiting on reviewer | 10 minutes | Human response times are slower |
| No actionable items but PR not fully ready | 5 minutes | Default polling interval |
When babysitting a stack, base the interval on the most urgent situation across all PRs (i.e., use the shortest applicable sleep).
Print the chosen interval and reason before sleeping:
"Sleeping {N} minutes — {reason}"Use shell for the wait (e.g., for 5 minutes).
sleepsleep 300每次迭代后,根据当前状态选择休眠时长:
| 场景 | 休眠时长 | 理由 |
|---|---|---|
| 刚推送新代码,CI尚未启动 | 2分钟 | CI需要时间识别新提交 |
| 部分检查失败(已修复并推送),其他检查仍在运行 | 3分钟 | 新推送会重新触发所有检查,很快就能查看结果 |
| 所有检查仍在运行,启动时间不足5分钟 | 3分钟 | 检查刚启动,很快就能查看结果 |
| 所有检查仍在运行,启动时间为5-15分钟 | 5分钟 | 给检查足够的时间完成 |
| 所有检查仍在运行,启动时间超过15分钟 | 5分钟 | 长时间运行的检查,保持稳定轮询 |
| 所有CI检查通过,等待评审人员回复 | 10分钟 | 人工回复速度较慢 |
| 无可执行操作但PR未完全就绪 | 5分钟 | 默认轮询间隔 |
当看护整个PR堆栈时,根据所有PR中最紧急的情况确定间隔(即使用最短的适用休眠时长)。
休眠前打印所选的间隔时长及理由:
"将休眠{N}分钟——{理由}"使用shell的命令实现等待(例如,代表休眠5分钟)。
sleepsleep 3006. Exit Condition
6. 退出条件
All PRs in the stack are ready when:
- All required CI checks are passing on HEAD for every PR
- All review threads across all PRs are either resolved OR have a babysitter reply as the last comment
- All general review comments across all PRs have been addressed (babysitter reply exists)
Optional check failures do not block this exit condition. If optional checks are still failing when the exit condition is met, note them in the output but still declare the stack ready.
Print: "All required checks passing and all review comments addressed across the stack. PRs are ready."
当堆栈中的所有PR满足以下条件时,即视为准备就绪:
- 每个PR的HEAD提交对应的所有必填CI检查均已通过
- 所有PR的所有评审线程要么已解决,要么最后一条回复来自该工具
- 所有PR的所有通用评审评论均已得到处理(存在该工具的回复)
可选检查任务的失败不会阻止退出流程。如果退出条件满足时可选检查仍失败,会在输出中注明,但仍会宣布堆栈已准备就绪。
打印:"堆栈中所有必填检查已通过,所有评审评论均已处理。PR已准备就绪。"
Common Mistakes
常见错误
- Acting on stale CI results — Always verify checks are for the HEAD commit before investigating failures. If checks are pending, wait.
- Replying to the same comment twice — Check if the last reply in a thread is already from the babysitter before responding.
- Pushing without local verification — Always run the project's verification commands before .
gt modify --commit - Resolving threads you shouldn't — Only resolve threads where you fixed a real issue. Leave scope-change and non-issue threads open for the reviewer.
- Missing general review comments — Don't only check inline threads. Always also fetch top-level review bodies and issue comments — reviewers often put their most important feedback there.
- Sleeping too long after pushing — After pushing a fix, use a short interval so you catch CI results quickly.
- Fixing the wrong branch in a stack — Always fix the lowest branch that has the issue. Fixing higher up can cause merge conflicts or get overwritten by a restack.
- Pushing multiple times per loop — Fix all branches locally first (+
gt modify --commitfor each), then push once withgt restack. Multiple pushes waste CI cycles and create race conditions.gt submit --stack - Forgetting to restack after fixing — After modifying a branch in the middle of a stack, always before moving to the next branch so higher branches pick up the changes.
gt restack - Assuming higher branches are unaffected — After fixing and restacking, re-check all PRs from scratch. The restack may introduce new CI failures in higher branches.
- 处理过时的CI结果——在调查失败原因前,务必验证检查任务对应的是HEAD提交。如果检查仍在进行中,请等待。
- 重复回复同一评论——在回复前检查线程的最后一条回复是否已来自该工具。
- 未做本地验证就推送——在执行前,务必运行项目的验证命令。
gt modify --commit - 错误地标记线程为已解决——仅在修复真实问题后才标记线程为已解决。对于范围变更和非问题类线程,保持未解决状态留给评审人员处理。
- 遗漏通用评审评论——不要只检查内联线程。务必同时获取顶层评审正文和议题评论——评审人员通常会将最重要的反馈放在这些位置。
- 推送修复后休眠过久——推送修复内容后使用较短的间隔,以便快速获取CI结果。
- 修复堆栈中错误的分支——始终修复存在问题的最底层分支。在顶层分支修复可能会导致合并冲突,或在重新堆叠时被覆盖。
- 每次循环多次推送——先在本地修复所有分支(每个分支执行+
gt modify --commit),然后通过gt restack一次性推送。多次推送会浪费CI资源并引发竞争条件。gt submit --stack - 修复后忘记重新堆叠——在修改堆栈中间的分支后,务必在处理下一个分支前执行,使顶层分支获取变更。
gt restack - 假设顶层分支不受影响——修复并重新堆叠后,从头重新检查所有PR。重新堆叠可能会在顶层分支引入新的CI失败。