Read PR Reviews Comprehensively

lesson workflow active workflow/read-pr-reviews-comprehensively.md View on GitHub

Read PR Reviews Comprehensively

Rule

Always read ALL review sources without truncation using jq for compact output, and reply to individual review comment threads when acknowledging fixes.

Context

When investigating, responding to, or working on pull requests in any GitHub repository.

Detection

Observable signals you need comprehensive PR review reading:

Pattern

CRITICAL: Never truncate review output! Use jq for compact, context-efficient output.

Step 1: Read ALL Review Sources (with jq for efficiency)

PR_NUMBER=134
REPO="gptme/gptme-contrib"

# Basic info
gh pr view $PR_NUMBER --repo $REPO

# General comments (don't use | head!)
gh pr view $PR_NUMBER --repo $REPO --comments

# All reviews (compact with jq)
gh api repos/$REPO/pulls/$PR_NUMBER/reviews \
  --jq '.[] | {user: .user.login, state: .state, body: .body}'

# ALL inline review comments (compact with jq - context efficient!)
gh api repos/$REPO/pulls/$PR_NUMBER/comments \
  --jq '.[] | {id: .id, path: .path, user: .user.login, body: (.body | split("\n")[0:3] | join(" "))}'

Why jq? Raw gh api output includes ~50 fields per comment (timestamps, URLs, reactions, etc.). The jq filter extracts only what's needed, reducing context usage by ~80% while preserving actionable information.

Note: For thread resolution status, GraphQL queries can filter unresolved threads (used by gptme's gh pr view tool internally). The REST API examples above are simpler and cover most use cases.

Step 2: Acknowledge Each Thread + Post Summary (same toolcall!)

Don't just post a general PR comment! Reply to each review thread, THEN post summary - all in one shell block:

# Batch multiple replies in one shell block (efficient!)
# Use --jq to suppress verbose response output
gh api repos/$REPO/pulls/$PR_NUMBER/comments/2678822180/replies \
  -f body="✅ Fixed in commit 3389211" --jq '.id' &
gh api repos/$REPO/pulls/$PR_NUMBER/comments/2678822196/replies \
  -f body="⚠️ Not addressing: edge case, low priority" --jq '.id' &
gh api repos/$REPO/pulls/$PR_NUMBER/comments/2678822210/replies \
  -f body="✅ Fixed in commit 5ebce81" --jq '.id' &
wait

# Then post summary comment (same shell block - signals completion)
gh pr comment $PR_NUMBER --repo $REPO --body "## ✅ All Review Comments Addressed

Replied to all review threads individually. See thread replies for details.

- Issue A: Fixed in abc123
- Issue B: Not addressing (rationale)"

Anti-Patterns

❌ WRONG: Truncating output

gh pr view 134 --comments | head -50  # Misses most comments!
gh api .../comments | head -100       # Truncates review feedback!

❌ WRONG: Raw gh api output (context bloat)

gh api repos/$REPO/pulls/$PR_NUMBER/comments  # 50+ fields per comment!

❌ WRONG: General PR comment only

# This doesn't close individual review threads
gh pr comment 134 --body "Fixed all issues"

❌ WRONG: Separate toolcalls for replies and summary

# First toolcall - replies
gh api .../comments/123/replies -f body="Fixed"
# Second toolcall - summary (BAD: should be same block!)
gh pr comment 134 --body "All done"

✅ CORRECT: Read → Act → Reply workflow

The workflow has three distinct toolcall boundaries (NOT a single command sequence):

Read: Get all comments

gh api repos/$REPO/pulls/$PR_NUMBER/comments \
  --jq '.[] | {id, path, user: .user.login, body: (.body | split("\n")[0])}'

Act: Fix the issues (separate toolcalls) This means using shell tool to make commits - may take multiple toolcalls across files.

Reply: Batch all replies + summary in one block Only AFTER fixing issues, post replies and summary together:

gh api repos/$REPO/pulls/$PR_NUMBER/comments/<id1>/replies -f body="✅ Fixed in abc123" --jq '.id' &
gh api repos/$REPO/pulls/$PR_NUMBER/comments/<id2>/replies -f body="✅ Fixed in abc123" --jq '.id' &
wait

# Summary comment (plain text, not markdown table)
gh pr comment $PR_NUMBER --body "## All Review Comments Addressed

- Issue 1: Fixed in abc123
- Issue 2: Fixed in abc123
- Issue 3: Not addressing (rationale)"

Why batch replies + summary? Review comment thread replies have poor visibility - they're collapsed by default. The summary comment ensures the reviewer sees everything addressed. Keep Phase 3 in one toolcall to prevent partial completion.

jq Quick Reference for PR Reviews

Compact comment list:
  --jq '.[] | {id, path, user: .user.login, body}'

First line of body only:
  --jq '.[] | {id, body: (.body | split("\n")[0])}'

Suppress POST response:
  --jq '.id'

Count comments:
  --jq 'length'

Filter by user:
  --jq '.[] | select(.user.login == "ErikBjare")'

Unresolved threads only:
  GraphQL with: select(.isResolved == false)

Outcome

Following this pattern results in:

Benefits:

Related

Origin

2026-01-10 PR #134: Identified failure mode where agent only read ~3 review comments due to output truncation and posted general PR comment instead of replying to individual review threads. Erik requested upstreaming with jq patterns for context efficiency.

Match Keywords

read ALL review sources without truncation reply to individual review comment threads batch all review replies in one shell block maintainer says you didn't address review comments unresolved review threads on PR