关于 respond-pr-feedback
respond-pr-feedback 是用于回复 PR 审查评论的技能,要求先评估反馈并完成修复或确定回应方式。默认在回复后解决可匹配的审查讨论串,也可用 `--no-resolve` 保留未解决状态。
主要功能
- 01指定 PR 或使用当前分支 PR
- 02筛选尚未回复的审查评论
- 03先回复,再解决讨论串
- 04将评论映射到审查讨论串 ID
- 05可选择跳过解决讨论串
适用场景
- 01修复代码后回复审查意见
- 02向审查者说明设计选择
- 03保留讨论串以便后续跟进
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ existential-birds/ beagle --skill respond-pr-feedback安装后在 Claude Code 中输入/respond-pr-feedback确认已加载。
详细介绍
回复 PR 反馈
评估反馈并完成修复后,回复评审评论。默认情况下会解决对话线程。
用法
调用 respond-pr-feedback 技能,可选择传入以下标志:
respond-pr-feedback [--pr <number>] [--no-resolve]
标志:
--pr <number>- 指定目标 PR 编号(默认为当前分支对应的 PR)--no-resolve- 发布回复后跳过解决线程(默认:全部解决)
前提条件
先运行 fetch-pr-feedback 技能,以评估反馈并进行任何必要的修复。
硬性门槛(按顺序执行)
只有在满足每项通过条件后才能继续(基于客观检查,不可假定已完成)。
- 已满足前提条件: 你已运行 fetch-pr-feedback 技能,评估了每个线程,并针对每个线程应用了修复或选择了明确的回复策略(不得盲目发布回复)。
- 已加载上下文: 第 2 步的命令以
0退出;从gh pr view、gh repo view和gh api user解析出的值均非空,并已赋给$PR_NUMBER、$PR_AUTHOR、$OWNER、$REPO、$CURRENT_USER——绝不可臆造所有者、仓库或 PR 编号。 - 已确定队列: 第 3a 步的
jq以0退出。如果筛选后的列表为空,则准确输出All review comments have been addressed.并停止(不要调用回复或 GraphQL 解决 API)。 - 先回复,再解决: 对每条目标评论,第 4 步的
gh api .../replies必须先以0退出,然后第 5 步才能尝试解决该评论对应的线程(除非传入了--no-resolve)。 - 根据映射解决: 只有当第 3b 步为相应评论的 ID 提供了
threadId时,第 5 步才调用resolveReviewThread;如果没有映射,则跳过该项的解决操作,不视为失败。
指令
1. 解析参数
从 $ARGUMENTS 中提取标志:
--pr <number>,或从当前分支检测--no-resolve标志(布尔值,默认为 false)
2. 获取 PR 上下文
# Get PR info (if --pr not specified, uses current branch)
gh pr view --json number,author --jq '{number, author: .author.login}'
# Get repo owner/name
gh repo view --json owner,name --jq '{owner: .owner.login, name: .name}'
# Get current authenticated user
gh api user --jq '.login'
保存为 $PR_NUMBER、$PR_AUTHOR、$OWNER、$REPO、$CURRENT_USER。
注意: $OWNER、$REPO 等是占位符。请替换为前序步骤获取的实际值。
3. 获取尚未回复的评论和线程数据
3a. 尚未回复的评审评论
获取评审评论,排除 PR 作者和当前用户的评论,并筛选出尚未收到回复的根评论。
使用带单引号分隔符的 heredoc 将 jq 筛选条件写入临时文件(避免 !=、正则表达式模式和尖括号的 shell 转义问题):
cat > /tmp/unreplied_comments.jq << 'JQEOF'
add // [] |
# Root comments from reviewers (not replies, not PR author, not current user)
[.[] | select(
.in_reply_to_id == null and
.user.login != $pr_author and
.user.login != $current_user
)] as $roots |
# IDs that current user has already replied to
[.[] | select(.user.login == $current_user) | .in_reply_to_id] as $replied |
# Filter to unreplied only
$roots | map(select(. as $c | $replied | index($c.id) == null)) |
# Dedup: group by path + line + reviewer, pick newest per group
group_by({
p: .path,
l: (.line // .original_line),
u: .user.login
}) |
map(sort_by(.created_at) | last) |
# Output needed fields
map({
id,
user: .user.login,
path,
line_display: (
.line as $end | .start_line as $start |
if $start and $start != $end then "\($start)-\($end)"
else "\($end // .original_line)" end
),
body
})
JQEOF
gh api --paginate "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments" | \
jq -s --arg pr_author "$PR_AUTHOR" --arg current_user "$CURRENT_USER" \
-f /tmp/unreplied_comments.jq
如果没有找到尚未回复的评论,则输出:"All review comments have been addressed." 并停止。
3b. 预先获取线程数据
获取评审线程 ID,以便在发布回复后解决线程:
gh api graphql -f query="
query {
repository(owner: \"$OWNER\", name: \"$REPO\") {
pullRequest(number: $PR_NUMBER) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 1) {
nodes { databaseId }
}
}
}
}
}
}
"
构建查找映射:评论 databaseId → 线程 id(仅限未解决的线程)。这样便可在发布每条回复后立即解决对应线程。
4. 生成并发布回复
对于每条尚未回复的评论,根据你的评估确定合适的回复:
| 评估结果 | 回复 |
|---|---|
| 反馈不正确或无事实依据 | 解释当前代码为何正确 |
| 反馈缺少上下文 | 解释设计决策 |
| 反馈有效且已修复 | "已在 $COMMIT_SHA 中修复",或简要描述所做的更改 |
| 反馈有效但不会修复 | 解释权衡或决策 |
标记指南: 对机器人评审者使用 @ 标记(例如 @coderabbitai),以触发其处理。不要使用 @ 标记人工评审者。
对每条评论发布回复:
gh api "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments/$COMMENT_ID/replies" \
-X POST --raw-field body="$RESPONSE"
5. 解决线程
默认执行此步骤。 只有传入 --no-resolve 时才跳过。
发布每条回复后,使用该评论的 $COMMENT_ID,从第 3b 步的映射中查找 $THREAD_ID:
gh api graphql -f query="
mutation {
resolveReviewThread(input: {threadId: \"$THREAD_ID\"}) {
thread { isResolved }
}
}
"
- 如果评论的
$COMMENT_ID有对应的线程 ID,则解决该线程 - 如果找不到线程 ID(例如,该评论是问题评论,而非评审线程),则跳过对该评论的线程解决操作
6. 输出摘要
按评审者分组:
### Reviewer: coderabbitai[bot]
| File:Line | Response Type | Thread |
|-----------|---------------|--------|
| `src/foo.ts:42` | Fixed in `abc1234` | Resolved |
| `src/bar.ts:15` | Explained design | Resolved |
### Reviewer: octocat
| File:Line | Response Type | Thread |
|-----------|---------------|--------|
| `src/baz.ts:7` | Won't fix | Resolved |
页脚:
**Threads resolved: 3/3**
回复指南
- 使用
@标记机器人审查者以触发重新处理;不要标记人工审查者 - 回复应简洁且专业
- 不要敷衍附和(“说得太好了!”,“你说得对!”)
- 解释决策时,引用具体代码或设计
- 如果问题已修复:说明改动内容,不要致谢
示例
# Respond to all reviewers on current PR (resolves threads)
respond-pr-feedback
# Respond on a specific PR
respond-pr-feedback --pr 123
# Respond without resolving threads
respond-pr-feedback --no-resolve