Skip to content

Commit 8b2f132

Browse files
justin808claude
andcommitted
Update address-review command with triage system and thread resolution
Added MUST-FIX/DISCUSS/SKIPPED triage classification before creating todos, allowing users to focus on high-impact items. Also added GitHub GraphQL thread resolution to close feedback loops after addressing comments. Improved bot comment handling to deduplicate and filter by actionability rather than blanket-skipping. Added support for standalone review comment replies and better error handling. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 12fd1d6 commit 8b2f132

1 file changed

Lines changed: 83 additions & 46 deletions

File tree

commands/address-review.md

Lines changed: 83 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
---
2-
description: Fetch GitHub PR review comments and create todos to address them
2+
description: Fetch GitHub PR review comments, triage them, create todos for must-fix items, reply to comments, and resolve addressed threads
33
---
44

5-
Fetch review comments from a GitHub PR in this repository and create a todo list to address each comment.
6-
7-
The user's input is: $ARGUMENTS
5+
Fetch review comments from a GitHub PR in this repository, triage them, and create a todo list only for items worth addressing.
86

97
# Instructions
108

@@ -18,7 +16,7 @@ If this command fails, ensure `gh` CLI is installed and authenticated (`gh auth
1816

1917
## Step 2: Parse User Input
2018

21-
Extract the PR number and optional review/comment ID from `$ARGUMENTS`:
19+
Extract the PR number and optional review/comment ID from the user's message:
2220

2321
**Supported formats:**
2422

@@ -43,38 +41,23 @@ gh api repos/${REPO}/issues/comments/{COMMENT_ID} | jq '{body: .body, user: .use
4341

4442
**If a specific review ID is provided (`#pullrequestreview-...`):**
4543

46-
First fetch the review body itself (reviewers often leave overall feedback here):
47-
4844
```bash
49-
gh api repos/${REPO}/pulls/{PR_NUMBER}/reviews/{REVIEW_ID} | jq '{id: .id, body: .body, state: .state, user: .user.login}'
45+
gh api repos/${REPO}/pulls/{PR_NUMBER}/reviews/{REVIEW_ID}/comments | jq '[.[] | {id: .id, path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login}]'
5046
```
5147

52-
Then fetch inline comments attached to that review:
48+
**If only PR number is provided (fetch all PR review comments):**
5349

5450
```bash
55-
gh api --paginate repos/${REPO}/pulls/{PR_NUMBER}/reviews/{REVIEW_ID}/comments | jq '[.[] | {id: .id, path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login}]'
51+
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}]'
5652
```
5753

58-
Include the review body as a todo item if it contains actionable feedback.
59-
60-
**If only PR number is provided (fetch all comments):**
61-
62-
Fetch both inline review comments and general PR discussion comments:
63-
64-
```bash
65-
# Inline code review comments
66-
gh api --paginate repos/${REPO}/pulls/{PR_NUMBER}/comments | jq '[.[] | {id: .id, type: "review", path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login, in_reply_to_id: .in_reply_to_id}]'
67-
68-
# General PR discussion comments (not tied to specific lines)
69-
gh api --paginate repos/${REPO}/issues/{PR_NUMBER}/comments | jq '[.[] | {id: .id, type: "issue", body: .body, user: .user.login, html_url: .html_url}]'
70-
```
71-
72-
Merge and de-duplicate results before creating todos.
73-
7454
**Filtering comments:**
7555

7656
- Skip comments where `in_reply_to_id` is set (these are replies, not top-level comments)
77-
- Skip bot-generated comments (check if `user` ends with `[bot]`)
57+
- Do not skip bot-generated comments by default. Many actionable review comments in this repository come from bots.
58+
- Deduplicate repeated bot comments and skip bot status posts, summaries, and acknowledgments that do not require a code or documentation change
59+
- Treat as actionable by default only: correctness bugs, regressions, missing tests, and clear inconsistencies with adjacent code
60+
- Treat as non-actionable by default: style nits, speculative suggestions, changelog wording, duplicate bot comments, and "could consider" feedback unless the user explicitly asks for polish work
7861
- Focus on actionable feedback, not acknowledgments or thank-you messages
7962

8063
**Error handling:**
@@ -83,45 +66,88 @@ Merge and de-duplicate results before creating todos.
8366
- If the API returns 403, check authentication with `gh auth status`
8467
- If the response is empty, inform the user no review comments were found
8568

86-
## Step 4: Create Todo List
69+
## Step 4: Triage Comments
70+
71+
Before creating any todos, classify every review comment into one of three categories:
72+
73+
- `MUST-FIX`: correctness bugs, regressions, security issues, missing tests that could hide a real bug, and clear inconsistencies with adjacent code that would likely block merge
74+
- `DISCUSS`: reasonable suggestions that expand scope, architectural opinions that are not clearly right or wrong, and comments where the reviewer claim may be correct but needs a user decision
75+
- `SKIPPED`: style preferences, documentation nits, comment requests, test-shape preferences, speculative suggestions, changelog wording, duplicate comments, status posts, summaries, and factually incorrect suggestions
76+
77+
Triage rules:
78+
79+
- Deduplicate overlapping comments before classifying them. Keep one representative item for the underlying issue.
80+
- Verify factual claims locally before classifying a comment as `MUST-FIX`.
81+
- If a claim appears wrong, classify it as `SKIPPED` and note briefly why.
82+
- Preserve the original review comment ID and thread ID when available so the command can reply to the correct place and resolve the correct thread later.
83+
84+
## Step 5: Create Todo List
8785

88-
Parse the response and create a todo list with TodoWrite containing:
86+
Create a todo list with TodoWrite containing **only the `MUST-FIX` items**:
8987

90-
- One todo per actionable review comment/suggestion
88+
- One todo per must-fix comment or deduplicated issue
9189
- For file-specific comments: `"{file}:{line} - {comment_summary} (@{username})"` (content)
92-
- For general comments: Parse the comment body and extract actionable items
90+
- For general comments: Parse the comment body and extract the must-fix action
91+
- Format activeForm: `"Addressing {brief description}"`
9392
- All todos should start with status: `"pending"`
9493

95-
## Step 5: Present to User
94+
## Step 6: Present Triage to User
9695

97-
Present the todos to the user - **DO NOT automatically start addressing them**:
96+
Present the triage to the user - **DO NOT automatically start addressing items**:
9897

99-
- Show a summary of how many actionable items were found
100-
- List the todos clearly
101-
- Wait for the user to tell you which ones to address
98+
- Number all items sequentially across categories so users can reference any item by number
99+
- `MUST-FIX ({count})`: list the todos created
100+
- `DISCUSS ({count})`: list items needing user choice, with a short reason
101+
- `SKIPPED ({count})`: list skipped comments with a short reason, including duplicates and factually incorrect suggestions
102+
- Wait for the user to tell you which items to address
103+
- If useful, suggest replying with a brief rationale on declined items, but do not do so unless the user asks
102104

103-
## Step 6: Address Items and Reply
105+
## Step 7: Address Items, Reply, and Resolve
104106

105-
When addressing items, after completing each todo item, reply to the original review comment explaining how it was addressed.
107+
When addressing items, after completing each selected todo item, reply to the original review comment explaining how it was addressed.
106108

107-
**For general PR discussion comments (issue comments):**
109+
**For issue comments (general PR comments):**
108110

109111
```bash
110112
gh api repos/${REPO}/issues/{PR_NUMBER}/comments -X POST -f body="<response>"
111113
```
112114

113-
**For inline review comments (replying to a thread):**
115+
**For PR review comments (file-specific, replying to a thread):**
114116

115117
```bash
116118
gh api repos/${REPO}/pulls/{PR_NUMBER}/comments/{COMMENT_ID}/replies -X POST -f body="<response>"
117119
```
118120

121+
**For standalone review comments (not in a thread):**
122+
123+
```bash
124+
gh api repos/${REPO}/pulls/{PR_NUMBER}/comments -X POST -f body="<response>" -f commit_id="<COMMIT_SHA>" -f path="<FILE_PATH>" -f line=<LINE_NUMBER> -f side="RIGHT"
125+
```
126+
127+
Note: `side` is required when using `line`. Use `"RIGHT"` for the PR commit side (most common) or `"LEFT"` for the base commit side.
128+
119129
The response should briefly explain:
120130

121131
- What was changed
122132
- Which commit(s) contain the fix
123133
- Any relevant details or decisions made
124134

135+
After posting the reply, resolve the review thread when all of the following are true:
136+
137+
- The comment belongs to a review thread and you have the thread ID
138+
- The concern was actually addressed in code, tests, or documentation, or it was explicitly declined with a clear explanation approved by the user
139+
- The thread is not already resolved
140+
141+
Use GitHub GraphQL to resolve the thread:
142+
143+
```bash
144+
gh api graphql -f query='mutation($threadId:ID!) { resolveReviewThread(input:{threadId:$threadId}) { thread { id isResolved } } }' -f threadId="<THREAD_ID>"
145+
```
146+
147+
Do not resolve a thread if the fix is still pending, if you are unsure whether the reviewer concern is satisfied, or if the user asked to leave the thread open.
148+
149+
If the user explicitly asks to close out a `DISCUSS` or `SKIPPED` item, reply with the rationale and resolve the thread only when the conversation is actually complete.
150+
125151
# Example Usage
126152

127153
```text
@@ -133,16 +159,24 @@ The response should briefly explain:
133159

134160
# Example Output
135161

136-
After fetching comments, present them like this:
162+
After fetching and triaging comments, present them like this:
137163

138164
```text
139-
Found 3 actionable review comments:
165+
Found 5 review comments. Triage:
166+
167+
MUST-FIX (1):
168+
1. ⬜ src/helper.rb:45 - Missing nil guard causes a crash on empty input (@reviewer1)
169+
170+
DISCUSS (1):
171+
2. src/config.rb:12 - Extract this to a shared config constant (@reviewer1)
172+
Reason: reasonable suggestion, but it expands scope
140173
141-
1. ⬜ src/helper.rb:45 - Add error handling for nil case (@reviewer1)
142-
2. ⬜ src/config.rb:12 - Consider using constant instead of magic number (@reviewer1)
143-
3. ⬜ General comment - Update documentation to reflect API changes (@reviewer2)
174+
SKIPPED (3):
175+
3. src/helper.rb:50 - "Consider adding a comment" (@claude[bot]) - documentation nit
176+
4. src/helper.rb:45 - Same nil guard issue (@greptile-apps[bot]) - duplicate of #1
177+
5. spec/helper_spec.rb:20 - "Consolidate assertions" (@claude[bot]) - test style preference
144178
145-
Which items would you like me to address? (e.g., "all", "1,2", or "1")
179+
Which items would you like me to address? (e.g., "1", "1,2", or "all must-fix")
146180
```
147181

148182
# Important Notes
@@ -155,6 +189,9 @@ Which items would you like me to address? (e.g., "all", "1,2", or "1")
155189
- **NEVER automatically address all review comments** - always wait for user direction
156190
- When given a specific review URL, no need to ask for more information
157191
- **ALWAYS reply to comments after addressing them** to close the feedback loop
192+
- Resolve the review thread after replying when the concern is actually addressed and a thread ID is available
193+
- Default to real issues only. Do not spend a review cycle on optional polish unless the user explicitly asks for it
194+
- Triage comments before creating todos. Only `MUST-FIX` items should become todos by default
158195
- For large review comments (like detailed code reviews), parse and extract the actionable items into separate todos
159196

160197
# Known Limitations

0 commit comments

Comments
 (0)