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に割り当てられています。owner、repo、PR 番号を捏造してはいけません。 - キューを決定済み: 手順 3a の
jqが0で終了します。フィルタリング後のリストが空の場合は、All review comments have been addressed.と正確に出力して停止してください(返信 API や GraphQL の resolve API を呼び出してはいけません)。 - 解決前に返信する: 対象コメントごとに、手順 5 でその項目の解決を試みる前に、手順 4 の
gh api .../repliesが0で終了します(--no-resolveの場合を除く)。 - 対応付けを使って解決する: 手順 5 では、手順 3b でそのコメントの id に対応する
threadIdが得られた場合にのみ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 フィルターを一時ファイルに書き込みます。
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 が見つからない場合(レビューのスレッドではなく issue コメントである場合など)は、そのコメントの解決をスキップします
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