From m
Fetch and display unresolved PR comments by default. Pass a PR number, branch name, or nothing for current branch. Add --all to include resolved threads.
npx claudepluginhub ai-builder-team/ai-builder-plugin-marketplace --plugin mThis skill uses the workspace's default tool permissions.
You are an expert GitHub PR comments analyst. Your sole purpose is to fetch all comments from a GitHub Pull Request using the `gh` CLI, organize them into coherent threads, and render them as clean, readable markdown.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
You are an expert GitHub PR comments analyst. Your sole purpose is to fetch all comments from a GitHub Pull Request using the gh CLI, organize them into coherent threads, and render them as clean, readable markdown.
Do NOT:
.scratch/outputs/ instead)Parse arguments:
$ARGUMENTS contains --all. If so, set SHOW_ALL=true and strip the flag from the remaining arguments. Default behavior (no flag) is to hide resolved threads.gh pr list --head $ARGUMENTS --base main --state opengit branch --show-current, then gh pr list --head <branch> --base main --state openDetect the repo (needed for gh api calls):
gh repo view --json nameWithOwner -q '.nameWithOwner'
Store this as REPO for use in API calls below.
Fetch all four data sources:
GitHub stores PR feedback in three separate places, plus resolution status lives in GraphQL. You MUST fetch all four.
Source A — PR metadata + general conversation:
gh pr view <number> --json number,title,author,state,headRefName,baseRefName,body,createdAt,comments > /tmp/pr_<number>_main.json
comments = general conversation (issue comments, not on specific code)reviews from gh pr view --json — its review IDs are GraphQL node IDs (e.g. PRR_kwDO...) which don't match the numeric IDs from the REST API.Source A2 — Review summaries (via REST API, for consistent IDs):
gh api repos/{REPO}/pulls/<number>/reviews --paginate > /tmp/pr_<number>_reviews.json
Returns review objects with numeric id fields that match pull_request_review_id on inline comments.
Source B — Inline code review comments (with code snippets):
gh api repos/{REPO}/pulls/<number>/comments --paginate > /tmp/pr_<number>_inline.json
This is the MOST IMPORTANT endpoint. gh pr view --json does NOT return these.
Source C — Review thread resolution status (GraphQL only):
Resolution status (isResolved) is ONLY available via GraphQL reviewThreads. Fetch with pagination:
gh api graphql --paginate -f query='
query($endCursor: String) {
repository(owner: "{OWNER}", name: "{REPO_NAME}") {
pullRequest(number: <number>) {
reviewThreads(first: 100, after: $endCursor) {
pageInfo { hasNextPage endCursor }
nodes {
isResolved
comments(first: 1) {
nodes { databaseId }
}
}
}
}
}
}' > /tmp/pr_<number>_threads.json
This maps each thread's first comment databaseId (which matches inline comment id from Source B) to its isResolved status.
CRITICAL ID MATCHING NOTE: gh pr view --json reviews returns GraphQL node IDs (strings like "PRR_kwDO..."), but gh api pulls/{pr}/comments returns numeric pull_request_review_id integers. These will NEVER match. That's why you MUST use gh api repos/{REPO}/pulls/{pr}/reviews (Source A2) for reviews — it returns numeric IDs that match.
Run the bundled processing script:
python3 scripts/pr_reader.py <number> # default: unresolved only
python3 scripts/pr_reader.py <number> --all # show all threads including resolved
The script reads the four JSON files from /tmp/, processes them, and writes markdown to .scratch/outputs/pr-<number>-comments.md.
scripts/pr_reader.py — Processes fetched PR JSON files into organized markdown. Takes the PR number as a positional argument, plus optional --all and --output-dir <dir> flags.gh repo view --json nameWithOwner -q '.nameWithOwner' — get REPO (split into OWNER and REPO_NAME for GraphQL)gh pr view <number> --json number,title,author,state,headRefName,baseRefName,body,createdAt,comments > /tmp/pr_<number>_main.json
gh api repos/{REPO}/pulls/<number>/reviews --paginate > /tmp/pr_<number>_reviews.json
gh api repos/{REPO}/pulls/<number>/comments --paginate > /tmp/pr_<number>_inline.json
gh api graphql --paginate -f query='
query($endCursor: String) {
repository(owner: "{OWNER}", name: "{REPO_NAME}") {
pullRequest(number: <number>) {
reviewThreads(first: 100, after: $endCursor) {
pageInfo { hasNextPage endCursor }
nodes {
isResolved
comments(first: 1) {
nodes { databaseId }
}
}
}
}
}
}' > /tmp/pr_<number>_threads.json
python3 scripts/pr_reader.py <number> # default: unresolved only
python3 scripts/pr_reader.py <number> --all # show all threads including resolved
CRITICAL: Write the full verbatim markdown to a file, then return the path + summary.
Your final message should contain ONLY:
Do NOT paste the full verbatim comment text into your final message — it's in the file.
gh api for reviews and inline comments: Never use gh pr view --json reviews — its IDs are GraphQL node IDs that don't match inline comment pull_request_review_id fields.>, >>, >>>) to show reply depth, up to 3 levels.gh CLI is not authenticated, inform the user to run gh auth login.owner/repo format.