关于 review-pr
review-pr 是面向编码 Agent 的 Skill,用于获取、核对并处理 GitHub 拉取请求的评审意见。它要求先以当前代码验证意见,并在一轮流程中完成评估、回复和解决讨论串。
主要功能
- 01查找当前分支的拉取请求
- 02获取并分类顶层评审意见
- 03对照当前文件核实意见
- 04回复意见并解决讨论串
- 05汇总已完成的评审
适用场景
- 01整理 GitHub 拉取请求的评审反馈
- 02核查报告的问题是否仍存在
- 03修复已确认的问题并回复评审者
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ richtabor/ agent-skills --skill review-pr安装后在 Claude Code 中输入/review-pr确认已加载。
详细介绍
审查 PR 评论
从 GitHub 获取、评估并处理 PR 审查评论。许多审查者的评论引用了过时的代码,或误解了代码逻辑——采取行动前务必核实实际代码库。
流程
这是一个单次流程。 获取评论、阅读文件、评估、呈现评估结果、回复所有评论、解决所有讨论串并显示最终摘要——全程无需暂停等待用户确认。
1. 查找 PR
如果没有提供 PR 编号,请查找当前分支对应的 PR:
gh pr list --head $(git branch --show-current) --json number,title --jq '.[0]'
2. 获取审查评论
获取评论及其 ID:
gh api repos/{owner}/{repo}/pulls/{number}/comments --jq '.[] | {id: .id, path: .path, line: (.line // .original_line), body: .body, in_reply_to_id: .in_reply_to_id}'
仅筛选顶层评论(即 in_reply_to_id 为 null 的评论)。
3. 阅读引用的文件(关键步骤)
评估任何评论之前,务必先阅读实际的当前代码。 审查者经常会:
- 引用较早提交中的行号
- 误读代码逻辑
- 评论已经修复的代码
对于每个不同的文件路径,阅读文件并核实:
- 行号是否与审查者描述的内容一致?
- 问题是否已经解决?
- 审查者对代码的理解是否正确?
4. 评估所有评论
对每条评论进行分类:
| 类别 | 判断标准 | 回复 |
|---|---|---|
| 已解决 | 问题已在后续提交中修复,或审查者误读了代码 | 说明代码实际的行为 |
| 修复 | 当前代码中存在有效的错误、安全问题或拼写错误 | 实施修复 |
| 不予修复 | 过度设计、风格偏好、功能请求,或会破坏一致性 | 说明理由 |
5. 呈现评估结果、回复并解决
一次性完成所有操作——不要暂停等待用户确认。 呈现评估结果、回复每条评论,并立即解决所有讨论串。
呈现所有评论及其评估结果:
## PR #[number]: [title]
Found [X] review comments. Here's my assessment:
---
### 1. `path/file.ts:42` — **Already addressed**
> [comment body]
**Issue**: Reviewer concerned about X
**Actual code**: Lines 26-34 already handle this — [brief explanation]
---
### 2. `path/other.ts:15` — **Won't fix**
> [comment body]
**Issue**: Reviewer wants X
**Why skip**: [Over-engineering / Matches existing pattern / Feature request / etc]
---
### 3. `path/file.ts:88` — **Fix**
> [comment body]
**Issue**: Typo in user-facing string
**Proposed change**: Change "Jumpope" to "Jump Rope"
---
## Summary
- **Already addressed**: 6 comments
- **Won't fix**: 8 comments
- **Fix**: 2 comments
然后立即回复所有评论并解决所有讨论串(见下方第 6 至 7 步)。不要等待用户输入。
6. 回复评论
对于已解决的评论,回复并说明当前情况:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="This is already handled — lines 26-34 fetch the authenticated user and verify user.id === state before proceeding. If they don't match, it rejects with a CSRF error."
对于不予修复的评论,简明说明理由:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="Won't fix — this matches the exact pattern used for the other integrations in the same file. Changing just this one would be inconsistent."
对于修复类评论,先实施修复,再回复:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body="Fixed in abc1234"
7. 解决所有讨论串
首先,获取所有未解决讨论串的 ID:
cat << 'QUERY' | gh api graphql --input - --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | {threadId: .id, commentId: .comments.nodes[0].databaseId}'
{"query": "query($owner: String!, $repo: String!, $pr: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 1) { nodes { databaseId } } } } } } }", "variables": {"owner": "OWNER", "repo": "REPO", "pr": 123}}
QUERY
然后按 ID 逐一解决讨论串:
cat << 'QUERY' | gh api graphql --input -
{"query": "mutation { resolveReviewThread(input: {threadId: \"THREAD_ID_HERE\"}) { thread { isResolved } } }"}
QUERY
8. 最终摘要
回复并解决后,显示最终摘要:
## Review Complete
All 16 conversations resolved.
### Already addressed (6)
| Comment | Explanation |
|---------|-------------|
| State validation | Already validates user.id === state at lines 26-34 |
| HR zones docs | Comments already say "milliseconds", not "percentage" |
### Won't fix (8)
| Comment | Reason |
|---------|--------|
| Form semantics | Matches existing pattern for other integrations |
| Rate limiting | Self-heals on next cron run, over-engineering |
### Fixed (2)
| Commit | Fix |
|--------|-----|
| `abc123` | Fixed typo "Jumpope" → "Jump Rope" |
重要:整个流程(评估 → 回复 → 解决 → 总结)必须一次完成。不要暂停询问“要继续吗?”——直接执行。
评估指南
已解决 — 说明情况,不要修复
审查者判断有误的常见情况:
- 审查者引用了错误的行号:代码在审查后已发生变更
- 审查者误读了逻辑:例如,认为条件写反了,但实际并没有
- 问题已经修复:后续提交已解决该问题
- 代码位于其他位置:检查或验证是在另一个函数中完成的
回复模板:
“此问题已处理——[具体位置] 执行了[具体操作]。[简要说明代码为何正确]。”
修复 — 实施并提交
仅修复以下问题:
- 当前代码中确实存在
- 属于错误、安全问题或拼写错误
- 可通过阅读文件加以核实
不予修复 — 说明理由
| 理由 | 回复模板 |
|---|---|
| 符合现有模式 | “不予修复——这与同一文件中 X、Y 和 Z 的模式完全一致。只修改这一处会导致不一致。” |
| 过度设计 | “不予修复——[故障模式]会明显失败/重试时会自行恢复/由[现有机制]处理。” |
| 功能请求 | “不予修复——这是功能请求,而不是 Bug。当前流程正常:[它的作用]。不在此 PR 的范围内。” |
| 产品决策 | “不予修复——这是产品决策,而不是 Bug。[当前行为]是有意设计的,因为[原因]。” |
| 会导致问题 | “不予修复——这会破坏[现有行为/与 X 的一致性]。” |
审查者常见误解
条件理解反了
审查者经常误读布尔逻辑。例如:
// "Refresh if expires in less than 5 minutes"
if (expiry.getTime() - Date.now() > 5 * 60 * 1000) {
return integration.access_token!; // Token is fresh, return early
}
// Proceed to refresh...
审查者说:“条件反了,令牌永远不会刷新” 实际情况:条件正确——令牌有效时提前返回,过期时刷新。
验证似乎缺失,实际上已存在
审查者说:“没有验证 state 参数” 实际情况:第 26–34 行已进行了验证。 在表示同意之前,务必先检查是否已有验证。
错误消息中的令牌
审查者说:“错误消息中记录了敏感令牌” 实际情况:错误日志记录的是 API 的错误响应,而不是我们的令牌。 仔细查看错误字符串中的实际内容。
该行不存在的代码
审查者提到第 174 行,但文件只有 161 行。 审查以来,文件已经发生变化。
核心原则
- 单次完成:不要停下来询问“要继续吗?”——在一个流程中完成评估、回复、解决和总结
- 行动前先核实:评估评论前,务必先阅读实际文件
- 相信代码库:如果现有模式有效,新代码就应与其保持一致
- 解释,而非仅仅驳回:跳过的评论应得到清晰解释
- 解决所有问题:无论是已修复还是已解释,所有讨论串都应标记为已解决
- 简洁明了:回复应为 1–2 句话,而不是一大段文字