github-workflows/skills/resolve-pr-threads/SKILL.md
Orchestrates resolution of GitHub PR review threads AND reads recent non-thread PR comments (top-level + review bodies) by grouping related feedback, processing each group sequentially inline with superpowers:receiving-code-review, and resolving threads via GraphQL. Use when you need to batch-process review feedback to unblock a PR merge.
npx skillsauth add jacobpevans/claude-code-plugins resolve-pr-threadsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Orchestrates resolution of all unresolved PR review comments by grouping related threads, processing each group sequentially inline to implement fixes or provide explanations, then resolving threads via GitHub's GraphQL API.
State warning: Thread IDs and resolution status change as reviews arrive. Re-fetch all open threads — cached thread lists from earlier are unreliable.
/resolve-pr-threads # Current branch PR
/resolve-pr-threads 142 # Specific PR
/resolve-pr-threads all # All open PRs with unresolved threads (sequential)
gh auth status — then retryContext inference: Infer owner/repo/PR from current git context, then substitute
these values for <OWNER>, <REPO>, <PR_NUMBER> placeholders per gh-cli-patterns:
owner=$(gh repo view --json owner --jq '.owner.login')
repo=$(gh repo view --json name --jq '.name')
number=$(gh pr view --json number --jq '.number')
Run 1a and 1b in parallel.
Run the canonical fetch-threads query from /gh-cli-patterns.
Replace <OWNER>, <REPO>, <PR_NUMBER> before running.
Filter to isResolved == false. Extract: id (PRRT_* node ID), path, line,
comments.nodes[].databaseId (numeric — for REST replies), comments.nodes[].body,
comments.nodes[].author.login.
gh pr view <PR_NUMBER> --json commits --jq '.commits[-1].committedDate'
Then run 1c and 1d in parallel.
Replace <OWNER>, <REPO>, <PR_NUMBER>, <LAST_COMMIT_DATE> (ISO 8601) before running:
gh api "repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments?since=<LAST_COMMIT_DATE>"
Replace <OWNER>, <REPO>, <PR_NUMBER>, <LAST_COMMIT_DATE> (ISO 8601) before running:
gh api "repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/reviews" \
--jq '[.[] | select(.submitted_at > "<LAST_COMMIT_DATE>" and (.body | length > 0))
| {id, body, author: .user.login, submitted_at}]'
First: Invoke superpowers:receiving-code-review via the Skill tool once.
Read and follow its full pattern. This applies to all thread and comment processing below.
Process each thread group sequentially (one group at a time, no sub-agents).
For each thread group:
<OWNER>, <REPO>, <PR_NUMBER>, <DATABASE_ID> before running:gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments/<DATABASE_ID>/replies -f body="your reply"
<DATABASE_ID> is the NUMERIC value from the fetch response, NOT the PRRT_ node ID.
Track results per thread:
PRRT_xxx: handled [commit:abc1234]PRRT_xxx: needs-human [reason]Process each comment group sequentially after all thread groups. Skip if no comments.
For each comment group:
gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments -f body="..."Do not use the Issues comments endpoint as a fallback for review-thread replies; threaded review comments must be handled only via the dedicated thread-resolution flow.
Track results per comment:
COMMENT({author}, {date}): actionable [commit:abc1234]COMMENT({author}, {date}): acknowledged [replied]COMMENT({author}, {date}): needs-human [reason]After all groups are processed, resolve each handled thread one at a time (not in parallel)
to avoid cascade failures. Use the canonical resolve mutation from /gh-cli-patterns.
Replace <THREAD_ID> (PRRT_* node ID) before running.
Skip needs-human threads; flag for manual attention.
Run the canonical count-unresolved query from /gh-cli-patterns.
Replace <OWNER>, <REPO>, <PR_NUMBER> before running.
Must return {"unresolved": 0, "overflow": false}. Then push: git push.
gh pr list --state open --json number,headRefNameThis skill is a single-pass resolver — it processes all threads and comments found at invocation time, then returns. If the caller needs to handle late-arriving reviews, it is responsible for re-invoking this skill.
PR #<PR_NUMBER> - Review Feedback Summary
Threads: {groupCount} groups ({threadCount} total) | Handled: {n} | Needs human: {n}
Resolved via GraphQL: {n} | Verification: {0 unresolved}/{total}
Comments: {n} since last commit | Actionable: {n} | Acknowledged: {n} | Needs human: {n}
Status: COMPLETE | PARTIAL ({n} need attention)
Omit "Threads:" when zero threads; omit "Comments:" when zero comments.
| Error | Cause | Fix |
|-------|-------|-----|
| Could not resolve to a node | Invalid thread ID | Re-fetch threads, IDs may have changed |
| Resource not accessible | Permission issue | Check gh auth status, need repo write access |
| Verification shows >0 | Thread not resolved | Re-run mutation for remaining threads |
| Empty reviewThreads | No reviews yet | Exit cleanly |
| Exactly 100 threads returned | Pagination cap hit | Resolve visible threads first, then re-run |
| REST reply fails | Invalid <DATABASE_ID> or permissions | Verify numeric databaseId (not node ID) and ensure token has required repo permissions (403 = permission issue) |
| since filter returns all comments | Invalid date format | Verify ISO 8601 format |
| Reviews endpoint returns empty | No reviews submitted | Proceed with threads only |
| \! in jq expression | Claude Code Bash escapes ! | Use (.x == y | not) or .x | length > 0 instead of != |
documentation
Use when editing GitHub Actions workflow files (.github/workflows/*.yml) in JacobPEvans repos. Documents when to target self-hosted RunsOn runners vs GitHub-hosted runners, the v3 label catalog used across the org, the required github.run_id segment, and the GitHub App allowlist prereq.
testing
Check PR merge readiness, sync local repo, cleanup stale worktrees; optional cross-repo sweep and stale-branch prune modes
tools
Local rebase-merge workflow for pull requests with signed commits
tools
Canonical reference for all gh CLI command shapes used by skills in this plugin. Defines the placeholder convention, allowed --json fields, GraphQL fallback rules, -f/-F/--raw-field flag semantics, the PR-readiness gate, code-scanning alert query, review-thread fetch/count/resolve mutations, and heredoc bodies. Prevents Unknown JSON field errors and divergent query shapes.