--- name: resolve-pr-comments description: Resolve all unresolved PR comments interactively. Makes local edits only—NEVER commits or pushes. Use when asked to resolve PR comments, address review feedback, handle CodeRabbit comments, or fix PR review issues. Invoked with /resolve-pr-comments or /resolve-pr-comments . allowed-tools: Read, Grep, Glob, Bash, Edit, Write, WebFetch, Task, AskUserQuestion, TodoWrite --- # Resolve PR Comments An interactive workflow to systematically address all unresolved PR review comments. ## Usage ``` /resolve-pr-comments /resolve-pr-comments ``` If no repo is specified, uses the current git repository's remote origin. **Before starting the workflow** - if the flow is in Plan Model - ask if the user wants to move to default mode to solve the comments one by one. Mention that each PR resolve has planning attached to it. ## Workflow Overview 1. **Detect repository** - Get owner/repo from git remote or user input 2. **Fetch unresolved comments** - Use GitHub GraphQL API (REST doesn't expose resolved status). Paginate through `reviewThreads` (cursor-based) so all pages are checked when a PR has more than 100 threads. 3. **Create tracking file** - Maintain state across the session 4. **For each comment**: - Get full details and any existing replies - Show the diff view of existing code in a proper diff view - Before suggesting the fix - do the research via documentations. And present all that docs research and relevant links to the user with the fix. Use context 7. **MAKE SURE YOU DO THIS ALWAYS** - Present to user with options (FIX, REPLY, SKIP) - Wait for user decision - Execute the action - Update tracking 5. **Verify resolution** - Check remaining unresolved count 6. **Repeat until done** - Continue until all comments resolved ## Step 1: Detect Repository If repository not provided, detect from git remote: ```bash git remote get-url origin | sed -E 's|.*github.com[:/]([^/]+/[^/.]+)(\.git)?|\1|' ``` ## Step 2: Fetch Unresolved Comments (GraphQL) The REST API does NOT expose resolved/unresolved status. Use GraphQL. **Important:** `reviewThreads` returns at most 100 threads per request. PRs with many review threads (e.g. large CodeRabbit reviews) need **pagination** or you will only see the first 100 threads and miss unresolved ones on later pages. Always paginate until `pageInfo.hasNextPage` is false so the count and list are complete. ### Single-page query (first 100 threads only) ```bash gh api graphql -f query=' { repository(owner: "OWNER", name: "REPO") { pullRequest(number: PR_NUMBER) { reviewThreads(first: 100) { pageInfo { hasNextPage endCursor } nodes { isResolved comments(first: 1) { nodes { databaseId path body author { login } } } } } } } }' ``` Extract unresolved (single page): ```bash ... | jq -r '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | "\(.comments.nodes[0].databaseId)|\(.comments.nodes[0].path)|\(.comments.nodes[0].author.login)"' ``` Avoid parsing `body` in the same jq pass if you paginate—comment bodies can contain control characters and break jq. Fetch full body per comment via REST when presenting (see Step 4). ### Paginate to collect all unresolved threads Use cursor-based pagination so every thread is considered: 1. First request: `reviewThreads(first: 100)` (no `after`). 2. From the response: read `pageInfo.hasNextPage` and `pageInfo.endCursor`. 3. Next request: `reviewThreads(first: 100, after: $endCursor)`. 4. Append unresolved from this page to your list (id, path, author only). 5. Repeat from step 2 until `hasNextPage` is false. Example loop (collects id|path|author for all unresolved; write to a file or variable): ```bash CURSOR="" while true; do if [ -z "$CURSOR" ]; then RESP=$(gh api graphql -f query=' query { repository(owner: "OWNER", name: "REPO") { pullRequest(number: PR_NUMBER) { reviewThreads(first: 100) { pageInfo { hasNextPage endCursor } nodes { isResolved comments(first: 1) { nodes { databaseId path author { login } } } } } } } }') else RESP=$(gh api graphql -f query=' query($after: String) { repository(owner: "OWNER", name: "REPO") { pullRequest(number: PR_NUMBER) { reviewThreads(first: 100, after: $after) { pageInfo { hasNextPage endCursor } nodes { isResolved comments(first: 1) { nodes { databaseId path author { login } } } } } } } }' -f after="$CURSOR") fi # Append unresolved from this page (id|path|author only; no body to avoid control chars) echo "$RESP" | jq -r '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .comments.nodes[0] | "\(.databaseId)|\(.path)|\(.author.login)"' HAS_NEXT=$(echo "$RESP" | jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage') CURSOR=$(echo "$RESP" | jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.endCursor // ""') [ "$HAS_NEXT" != "true" ] || [ -z "$CURSOR" ] && break done ``` Total unresolved count = number of lines output. Use the comment `databaseId` values to fetch full body via REST when presenting each comment (Step 4). ## Step 3: Create Tracking File Create at `/tmp/pr-review/pr--comments.md`: ```markdown # PR # Comment Review (/) ## Summary - Total unresolved: - Fixed: 0 - Replied: 0 - Skipped: 0 ## Comments to Address | # | ID | File | Issue | Status | |---|-----|------|-------|--------| | 1 | 12345 | src/foo.ts | Missing validation | pending | ## Actions Taken | ID | Action | Details | |----|--------|---------| ``` ## Step 4: Present Each Comment For each unresolved comment, present in this format: ``` **Comment #/: ID - ** **What it says:** **Current code state:** **Documentations referred** For anything related to LLM calls (in /core module) - make sure you refer to the documentation. You have access to web_search and context7. and show that too **Options:** 1. **FIX** - 2. **REPLY** - 3. **SKIP** - Move on without action **My recommendation:**