Skip to content

Commit c348e1c

Browse files
cpcloudclaude
andcommitted
chore(agents): add GraphQL scripts for PR review thread operations
Avoids recurring $ escaping issues when running GraphQL queries/mutations inline in shell commands. The /rev skill now references these files via `-F query=@.claude/graphql/...` instead of inline query strings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7759aca commit c348e1c

3 files changed

Lines changed: 63 additions & 42 deletions

File tree

.claude/commands/rev.md

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<!-- Copyright 2026 Phillip Cloud -->
22
<!-- Licensed under the Apache License, Version 2.0 -->
33

4-
Rebase onto the latest main, address PR review feedback, and fix failing CI.
4+
Rebase onto the latest main, then iterate until all review feedback is
5+
addressed and CI is green.
56

67
## 1. Rebase onto main
78

@@ -10,62 +11,53 @@ Rebase onto the latest main, address PR review feedback, and fix failing CI.
1011
3. If there are conflicts, resolve them, `git add` the resolved files, and
1112
`git rebase --continue`. Repeat until the rebase completes.
1213

13-
## 2. Address PR review feedback and fix CI (parallel)
14+
## 2. Review-fix loop
1415

15-
These two steps are independent -- start both in parallel.
16+
Repeat until there are **zero unresolved threads** and CI is green.
17+
Squash fixes into the relevant commit (fixup + autosquash) to keep
18+
history clean.
1619

17-
### 2a. PR review feedback
20+
### 2a. Address unresolved review feedback
1821

19-
1. Fetch unresolved review threads (use the GraphQL API for threaded context):
22+
1. Fetch unresolved review threads:
2023
```
21-
gh api graphql -f query='
22-
query($owner:String!, $repo:String!, $pr:Int!) {
23-
repository(owner:$owner, name:$repo) {
24-
pullRequest(number:$pr) {
25-
reviewThreads(first:100) {
26-
nodes {
27-
id
28-
isResolved
29-
comments(first:50) {
30-
nodes { id databaseId author{login} body path line }
31-
}
32-
}
33-
}
34-
}
35-
}
36-
}' -f owner=cpcloud -f repo=micasa \
37-
-F pr="$(gh pr view --json number --jq '.number')"
24+
gh api graphql \
25+
-F query=@.claude/graphql/review-threads.graphql \
26+
-f owner=cpcloud -f repo=micasa \
27+
-F pr="$(gh pr view --json number --jq '.number')"
3828
```
29+
Filter to `isResolved == false`.
3930
2. For each **unresolved** thread:
40-
- Read the referenced file and line to understand the context
41-
- Make the requested change (or explain in a reply why not)
42-
- After pushing the fix, reply to the review comment using its
43-
`databaseId` from the query:
31+
- Read the referenced file and line to understand the context.
32+
- Make the requested change (or explain in a reply why not).
33+
- Reply to the review comment using its `databaseId`:
4434
`gh api repos/cpcloud/micasa/pulls/<pr>/comments/<databaseId>/replies -f body='...'`
4535
Explain how it was addressed (commit hash, what changed).
46-
- **Resolve the thread** if you are extremely confident the feedback
47-
has been fully addressed. Use the GraphQL mutation:
36+
- **Resolve the thread**:
4837
```
49-
gh api graphql -f query='
50-
mutation($id:ID!) { resolveReviewThread(input:{threadId:$id}) {
51-
thread { isResolved }
52-
}}' -f id=<thread_node_id>
38+
gh api graphql \
39+
-F query=@.claude/graphql/resolve-thread.graphql \
40+
-f id=<thread_node_id>
5341
```
54-
If there is any doubt the comment hasn't been fully addressed, leave
55-
the thread open for the reviewer.
56-
3. Skip resolved threads -- they need no action.
42+
Only leave a thread open if there is genuine doubt it was fully
43+
addressed.
44+
3. If there are no unresolved threads, skip to 2c.
5745
5846
### 2b. Fix failing CI
5947
6048
Use `/fix-ci` to diagnose and fix each failing job.
6149
62-
## 3. Push and verify
50+
### 2c. Push and wait
6351
64-
1. `git push --force-with-lease` (safe force push since we rebased)
65-
2. Wait for CI to start: `gh pr checks --watch --fail-fast`
66-
3. If new failures appear, loop back to step 2b.
52+
1. `git push --force-with-lease`
53+
2. Wait for CI: `gh pr checks --watch --fail-fast`
54+
3. **Wait for Copilot's review.** Copilot typically takes 5-12 minutes
55+
after a push. Poll unresolved threads every 90s (up to 25 min). The
56+
first poll that returns results means Copilot has posted -- loop
57+
back to 2a. If 25 min pass with zero unresolved threads, Copilot
58+
either found nothing or didn't run -- exit the loop.
6759
68-
## 4. Update PR description
60+
## 3. Update PR description
6961
70-
After all changes are pushed, re-read the PR title and body
71-
(`gh pr view`) and update them if they no longer match the actual changes.
62+
After the loop exits, re-read the PR title and body (`gh pr view`) and
63+
update them if they no longer match the actual changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mutation($id: ID!) {
2+
resolveReviewThread(input: { threadId: $id }) {
3+
thread {
4+
isResolved
5+
}
6+
}
7+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
query($owner: String!, $repo: String!, $pr: Int!) {
2+
repository(owner: $owner, name: $repo) {
3+
pullRequest(number: $pr) {
4+
reviewThreads(first: 100) {
5+
nodes {
6+
id
7+
isResolved
8+
comments(first: 50) {
9+
nodes {
10+
id
11+
databaseId
12+
author { login }
13+
body
14+
path
15+
line
16+
}
17+
}
18+
}
19+
}
20+
}
21+
}
22+
}

0 commit comments

Comments
 (0)