Review PR Threads

SkillDev tools

Resolve the currently-unresolved review threads on the current branch's PR in one sweep — assess each, fix it (test-first, verified) or reply-only, then reply and resolve — and return a summary. Use standalone to address PR review feedback, or as the thread-handling step invoked by /watch-pr. Repo is adamayoung/TMDb.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Review PR Threads skill

What this skill tells your AI

The instructions your AI receives, as published by adamayoung/tmdb in .claude/skills/review-pr-threads/SKILL.md and read by ahel’s review.

Handle the open review conversations on a pull request: for each unresolved thread, decide whether it warrants a code change, make and verify the fix (or explain why not), reply, and resolve it. This is a single sweep over the threads that are unresolved right now — it does not wait for new reviews to arrive. The caller (you, or /watch-pr) decides whether to run it again after a push triggers a fresh review.

Repo is adamayoung/TMDb. GitHub reads (find the PR, fetch threads), the reply, and the resolve all use the GitHub MCP (mcp__github__*): get_review_comments exposes each comment's numeric REST id in its html_url (the #discussion_r<id> anchor — verified 2026-08-07), which is exactly the id add_reply_to_pull_request_comment takes. gh is authenticated and kept as the reply fallback (gh api graphql with the thread node id) on a 401/403 or if the anchor is ever absent.

Principles

  1. One sweep, then return. Process every thread that is unresolved at invocation, then stop and report. Do not loop waiting for re-reviews — pushing a fix re-triggers the claude-review bot and CI, and that convergence loop belongs to the caller.
  2. Fix test-first and verify before you reply. A code change in response to a thread follows the project's discipline: reproduce/capture with a test where applicable, then fix, then verify with the delegated skills. Never claim a fix you haven't verified.
  3. Don't change code you disagree with — reply instead. Out-of-scope, incorrect, already-handled, or question-only threads get a reasoned reply and a resolve, not an edit.
  4. Dedup via the run ledger. Keep (or reuse the caller's) ledger of handled thread IDs and a topic signature (path:line + gist) per thread. If a thread repeats a topic you already fixed this run, reply pointing at the earlier commit SHA and resolve — do not re-edit.
  5. The claude-review bot's summary comment is advisory. It posts inline threads only for Critical/High; its Medium/Low summary bullets are not threads and are not work items — don't turn them into code changes.

0. Find the PR

Find the open PR for the current branch with mcp__github__list_pull_requests (owner/repo from the origin remote, head: <owner>:<branch>, state: open), or read a specific one with mcp__github__pull_request_read method get (pullNumber: <n>). Take number/html_url/state/head.ref from the result.

  • An explicit PR number in the skill arguments overrides the current branch.
  • No PR for the current branch → stop and tell the user (suggest /pr).
  • State not open → stop and report.

1. Fetch unresolved threads

Use mcp__github__pull_request_read method get_review_comments (owner/repo from origin, pullNumber: <n>). It returns review threads, each with metadata (isResolved, isOutdated, isCollapsed), the thread node id (PRRT_…, used to resolve in §2), path/line, and the grouped comments — each comment carrying an html_url whose #discussion_r<id> anchor is the numeric comment id §2's reply needs. Paginate with perPage/after (the endCursor from the previous page's pageInfo) if needed.

Process each thread where isResolved is false and whose thread id is not already in the ledger.

2. Handle each thread

For each unresolved thread:

  1. Assess the comment(s) and decide whether a code change is warranted, in scope, and clearly correct.

  2. Needs a fix → edit the code, then verify with the delegated skills — /lint, /build, /test (and /integration-test if it could affect live-API behaviour); those run in Haiku subagents so logs stay out of context. Commit with a gitmoji message and record the commit SHA. Batch the sweep's pushes: commit per fix, but git push once after all threads are handled (§3), so one review/CI cycle is triggered per sweep, not one per thread.

  3. No fix warranted (disagree / out of scope / a question / already done) → make no code change; you'll say why in the reply. When the reason is out of scope and the reviewer's point is sound, file it per .github/ISSUE_FILING.md and reply with the issue number. "Out of scope" with nothing behind it is how a valid review comment gets closed forever; a link is what makes it a deferral rather than a dismissal.

  4. Reply on the thread — what you assessed and whether you fixed it (include the commit SHA when you did). Use mcp__github__add_reply_to_pull_request_comment (owner/repo from origin, pullNumber: <n>, body, and commentId — the number from the thread's first comment's html_url anchor, …#discussion_r<ID>; the number only, never the PRRT_… node id). On a 401/403, or if no comment in the thread carries the anchor, fall back to the GraphQL reply with the thread node id we already have from §1:

    gh api graphql -f query='mutation($id:ID!,$body:String!){
      addPullRequestReviewThreadReply(input:{pullRequestReviewThreadId:$id,body:$body}){ comment{ id } }
    }' -f id=<THREAD_ID> -f body='<your feedback>'
    
  5. Resolve the thread with mcp__github__pull_request_review_write method resolve_thread (threadId: <PRRT_… node id>; owner/repo/pullNumber are ignored for this method). Resolving an already-resolved thread is a no-op.

  6. Record the thread ID and topic signature in the ledger.

Reply and resolve after the single push (§3) for threads you fixed, so the SHA you cite is on the remote. Reply/resolve reply-only threads immediately.

3. Push once, then finish

After every thread is handled, if you committed any fixes, git push once (it re-triggers CI and the claude-review bot — expected). Then post the deferred replies + resolves for the fixed threads.

There is no pre-commit hook (.git/hooks/ holds only *.sample), so nothing lints on your behalf — run /lint before committing.

Guardrails

  • Never edit .github/workflows/* or other CI/config to silence a reviewer, and never force-push, without surfacing to the user first.
  • If a requested change is ambiguous or risky, reply with your assessment and leave it for the user (note it in the summary) rather than guessing.
  • Stay in scope: address the thread, don't opportunistically refactor around it.

Return: sweep summary

Report, concisely:

  • Fixed — thread topic → commit SHA, per fixed thread.
  • Replied-only — thread topic → one-line reason (disagreed / out of scope / already done / question answered).
  • Left for the user — ambiguous/risky threads you replied on but did not act on, and why.
  • Counts — threads handled this sweep, and any that remain unresolved (e.g. a thread you intentionally left open for a human decision).

Whether anything was pushed (and the resulting CI/review re-trigger) so the caller can decide whether to sweep again.

Arguments: $ARGUMENTS

Signals

GitHub stars
176
Forks
47
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
review-pr-threads
Source
github.com/adamayoung/tmdb