Sync address-review command with upstream PR #14#1019
Conversation
…#14 Updates the address-review command with improvements from upstream: - Add $ARGUMENTS placement to Step 2 - Add node_id fields to comment fetches for thread resolution - Add jq -s (slurp) to paginated gh api calls for proper aggregation - Add GraphQL query to fetch review thread metadata and thread_id - Add filtering for already-resolved threads - Document review summary body reply path via general PR comments - Document GraphQL pagination limitation for review threads Co-Authored-By: Claude Haiku 4.5 <[email protected]>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThis PR syncs the Key changes:
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A(["/address-review input"]) --> B["Step 1: Detect repo\ngh repo view"]
B --> C["Step 2: Parse input\nPR number / URL / review ID"]
C --> D{"Input type?"}
D -->|issuecomment-ID| E["GET /issues/comments/ID"]
D -->|pullrequestreview-ID| F["GET /pulls/PR/reviews/ID\nGET /pulls/PR/reviews/ID/comments\n--paginate + jq -s"]
D -->|PR number only| G["GET /pulls/PR/comments\n--paginate + jq -s\nGET /issues/PR/comments\n--paginate + jq -s"]
F --> H
G --> H["GraphQL: fetch reviewThreads\nwith node_id + isResolved\n--paginate + jq -s"]
H --> I["Filter:\n- Skip resolved threads (NEW)\n- Skip in_reply_to_id replies\n- Deduplicate bots"]
I --> J["Step 4: Triage\nMUST-FIX / DISCUSS / SKIPPED"]
J --> K["Step 5: TodoWrite\nMUST-FIX items only"]
K --> L["Step 6: Present triage\nSingle sequential numbering (NEW)\nWait for user selection"]
L --> M{"User selects items"}
M -->|"MUST-FIX or DISCUSS"| N["Address in code/tests/docs"]
M -->|"SKIPPED rationale"| O["Post rationale reply only"]
N --> P{"Comment type?"}
P -->|"Issue comment"| Q["POST /issues/PR/comments"]
P -->|"Review comment"| R["POST /pulls/PR/comments/ID/replies"]
P -->|"Review summary body (NEW)"| S["POST /issues/PR/comments\nas general PR comment"]
Q --> T{"Thread resolvable?"}
R --> T
S --> T
T -->|"Yes + thread_id available"| U["GraphQL: resolveReviewThread"]
T -->|No| V([Done])
U --> V
Last reviewed commit: "Sync address-review ..." |
| Create a task list with TodoWrite containing **only the `MUST-FIX` items**: | ||
|
|
||
| - One todo per must-fix comment or deduplicated issue | ||
| - For file-specific comments: `"{file}:{line} - {comment_summary} (@{username})"` (content) | ||
| - For general comments: Parse the comment body and extract the must-fix action | ||
| - Format activeForm: `"Addressing {brief description}"` | ||
| - All todos should start with status: `"pending"` | ||
| - One task per must-fix comment or deduplicated issue | ||
| - Subject: `"{file}:{line} - {comment_summary} (@{username})"` | ||
| - For general comments: Parse the comment body and extract the must-fix action as the subject | ||
| - Description: Include the full review comment text and any relevant context | ||
| - All tasks should start with status: `"pending"` |
There was a problem hiding this comment.
activeForm field missing from task instructions
The previous version of Step 5 explicitly instructed the LLM to provide activeForm: "Addressing {brief description}" when calling TodoWrite. The TodoWrite tool schema requires three fields: content, activeForm, and status. The new instructions introduce "Subject" and "Description" terminology (neither of which maps directly to the tool's schema) and drop the activeForm guidance entirely.
While Claude may infer activeForm from its knowledge of the tool, omitting explicit guidance increases the chance of a malformed TodoWrite call if the executing model is less familiar with the schema. Consider restoring the activeForm guidance:
| Create a task list with TodoWrite containing **only the `MUST-FIX` items**: | |
| - One todo per must-fix comment or deduplicated issue | |
| - For file-specific comments: `"{file}:{line} - {comment_summary} (@{username})"` (content) | |
| - For general comments: Parse the comment body and extract the must-fix action | |
| - Format activeForm: `"Addressing {brief description}"` | |
| - All todos should start with status: `"pending"` | |
| - One task per must-fix comment or deduplicated issue | |
| - Subject: `"{file}:{line} - {comment_summary} (@{username})"` | |
| - For general comments: Parse the comment body and extract the must-fix action as the subject | |
| - Description: Include the full review comment text and any relevant context | |
| - All tasks should start with status: `"pending"` | |
| Create a task list with TodoWrite containing **only the `MUST-FIX` items**: | |
| - One task per must-fix comment or deduplicated issue | |
| - Subject (`content`): `"{file}:{line} - {comment_summary} (@{username})"` | |
| - For general comments: Parse the comment body and extract the must-fix action as the subject | |
| - Active form (`activeForm`): `"Addressing {brief description}"` | |
| - Description: Include the full review comment text and any relevant context | |
| - All tasks should start with status: `"pending"` |
| ```bash | ||
| OWNER=${REPO%/*} | ||
| NAME=${REPO#*/} | ||
| gh api graphql --paginate -f owner="${OWNER}" -f name="${NAME}" -F pr={PR_NUMBER} -f query='query($owner:String!, $name:String!, $pr:Int!, $endCursor:String) { repository(owner:$owner, name:$name) { pullRequest(number:$pr) { reviewThreads(first:100, after:$endCursor) { nodes { id isResolved comments(first:100) { nodes { id databaseId } } } pageInfo { hasNextPage endCursor } } } } }' | jq -s '[.[].data.repository.pullRequest.reviewThreads.nodes[] | {thread_id: .id, is_resolved: .isResolved, comments: [.comments.nodes[] | {node_id: .id, id: .databaseId}]}]' |
There was a problem hiding this comment.
The GraphQL query is a very long single line that's hard to read and maintain. Consider splitting it across lines for clarity (the shell still treats it as one command):
| gh api graphql --paginate -f owner="${OWNER}" -f name="${NAME}" -F pr={PR_NUMBER} -f query='query($owner:String!, $name:String!, $pr:Int!, $endCursor:String) { repository(owner:$owner, name:$name) { pullRequest(number:$pr) { reviewThreads(first:100, after:$endCursor) { nodes { id isResolved comments(first:100) { nodes { id databaseId } } } pageInfo { hasNextPage endCursor } } } } }' | jq -s '[.[].data.repository.pullRequest.reviewThreads.nodes[] | {thread_id: .id, is_resolved: .isResolved, comments: [.comments.nodes[] | {node_id: .id, id: .databaseId}]}]' | |
| gh api graphql --paginate \ | |
| -f owner="${OWNER}" -f name="${NAME}" -F pr={PR_NUMBER} \ | |
| -f query='query($owner:String!, $name:String!, $pr:Int!, $endCursor:String) { | |
| repository(owner:$owner, name:$name) { | |
| pullRequest(number:$pr) { | |
| reviewThreads(first:100, after:$endCursor) { | |
| nodes { id isResolved comments(first:100) { nodes { id databaseId } } } | |
| pageInfo { hasNextPage endCursor } | |
| } | |
| } | |
| } | |
| }' | jq -s '[.[].data.repository.pullRequest.reviewThreads.nodes[] | | |
| {thread_id: .id, is_resolved: .isResolved, | |
| comments: [.comments.nodes[] | {node_id: .id, id: .databaseId}]}]' |
Also worth noting: gh api graphql --paginate looks for pageInfo.endCursor at the top level of the data response. The current query nests pageInfo inside reviewThreads, which is the correct location for gh's auto-pagination — just flagging it in case someone refactors the query structure later.
|
Overall this is a solid improvement. See follow-up comments for specifics. |
Issue 1: node_id missing from single-comment fetch (Step 3, issuecomment path)The issuecomment fetch path omits node_id, while every other comment-fetching path in Step 3 now includes it. Issue comments do not belong to review threads so this will not break thread resolution in practice, but the inconsistency is confusing. Suggest adding node_id: .node_id here for uniformity. |
Issue 2: Removal of standalone review comment creation pathThe old section for standalone review comments documented how to create a new anchored comment on a line (using commit_id, path, line, side). This is removed in favour of using the /replies endpoint for all existing review comments. Using /replies for existing threads is correct, but if a thread ID is unavailable or a comment has been deleted there is no longer a documented fallback. Worth a short note in Known Limitations suggesting the general PR comment endpoint as a fallback. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 614a78e0af
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| **If only PR number is provided (fetch all PR comments):** | ||
|
|
||
| ```bash | ||
| gh api repos/${REPO}/pulls/{PR_NUMBER}/comments | jq '[.[] | {id: .id, path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login, in_reply_to_id: .in_reply_to_id}]' | ||
| # Inline code review comments | ||
| gh api --paginate repos/${REPO}/pulls/{PR_NUMBER}/comments | jq -s '[.[].[] | {id: .id, node_id: .node_id, type: "review", path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login, in_reply_to_id: .in_reply_to_id}]' | ||
|
|
||
| # General PR discussion comments (not tied to specific lines) | ||
| gh api --paginate repos/${REPO}/issues/{PR_NUMBER}/comments | jq -s '[.[].[] | {id: .id, node_id: .node_id, type: "issue", body: .body, user: .user.login, html_url: .html_url}]' | ||
| ``` |
There was a problem hiding this comment.
Fetch review bodies in the plain-PR path
When the user invokes /address-review 12345 or passes a plain PR URL, this branch only fetches inline review comments and issue comments. Review summary bodies live on /pulls/{PR_NUMBER}/reviews, so any actionable summary-only feedback never makes it into triage or the todo list unless the user supplies a #pullrequestreview-... URL. That makes the new Step 7 handling for review summaries unreachable in the default flow.
Useful? React with 👍 / 👎.
|
Issue 3: GraphQL inner pagination note is slightly incomplete. The Known Limitations note says comments(first:100) is hardcoded and may truncate threads with more than 100 comments. The reviewThreads(first:100) per page is also hardcoded. Very rare in practice, but both limits are worth mentioning. Minor nit: the jq -s slurp pattern for aggregating paginated REST results is a correct fix. A short inline comment explaining why jq -s is needed would help future readers (--paginate emits one JSON array per page; -s slurps them so .[].[] can flatten across pages). Overall: the core logic (GraphQL thread metadata, is_resolved filtering, ARGUMENTS variable wiring) is correct and well thought out. The databaseId/node_id mapping between GraphQL and REST is handled properly. See the separate inline comment for a readability suggestion on the long GraphQL query. |
## Summary Brings over [PR #16](shakacode/claude-code-commands-skills-agents#16) from the shared commands repo so non-Claude assistants (Codex, GPT, etc.) can run the same `/address-review` workflow. - Add `prompts/address-review.md` — shared prompt template that mirrors the Claude `/address-review` triage/reply/resolve flow and falls back cleanly when terminal `gh` access is unavailable. - Add root `AGENTS.md` (adapted for Shakapacker's layout) that points non-Claude tools at `prompts/address-review.md` when asked to address PR review comments. The Claude command at `.claude/commands/address-review.md` already matches upstream HEAD (synced previously in #1019) and is unchanged here. ## Test plan - [ ] Verify `prompts/address-review.md` is byte-identical to the upstream template - [ ] Verify `AGENTS.md` is discoverable by Codex CLI and points at the shared prompt - [ ] Confirm no changes to existing `.claude/commands/address-review.md` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: adds a standalone prompt markdown file only, with no runtime code changes. > > **Overview** > Adds `prompts/address-review.md`, a reusable prompt template that instructs coding assistants how to fetch PR review/issue comments via `gh`, filter unresolved top-level feedback, triage into `MUST-FIX`/`DISCUSS`/`SKIPPED`, then (after user selection) reply and optionally resolve threads. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 6758682. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Syncs the address-review command with improvements from shakacode/claude-code-commands-skills-agents#14.
Key changes:
node_idfields to all comment fetches for thread resolutionjq -s(slurp) to paginatedgh apicalls for proper multi-page aggregationthread_idNote
Low Risk
Low risk documentation-only changes, but they alter the prescribed GitHub API/GraphQL workflows for fetching/replying/resolving review threads and could affect anyone automating this process if followed incorrectly.
Overview
Updates the
address-reviewcommand instructions to fetch richer PR feedback data and better support thread resolution. It addsnode_idand proper--paginateaggregation (jq -s) to comment fetches, introduces a GraphQL lookup to map comments tothread_id/isResolved, and documents skipping already-resolved threads.Clarifies reply behavior by distinguishing inline review comments (reply via
/replies) from review summary bodies (reply via general PR issue comments), tightens triage/task formatting guidance, and notes the GraphQL inner-pagination limitation for threads with >100 comments.Written by Cursor Bugbot for commit 614a78e. This will update automatically on new commits. Configure here.