Claude-skill-registry github-graphql

Use when querying GitHub via GraphQL. Provides patterns for PR threads, comments, and mutations.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/github-graphql" ~/.claude/skills/majiayu000-claude-skill-registry-github-graphql && rm -rf "$T"
manifest: skills/data/github-graphql/SKILL.md
source content

GitHub GraphQL Patterns

<!-- markdownlint-disable-file MD013 -->

Standardized GraphQL patterns for GitHub PR and review thread operations. All commands that interact with GitHub's GraphQL API should reference this skill instead of duplicating queries.

Critical Requirements

1. Single-Line Format Required

ALWAYS use single-line GraphQL queries with

--raw-field
in Claude Code.

Multi-line GraphQL queries cause encoding issues. Use this pattern:

# CORRECT: Single-line with --raw-field
gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { reviewThreads(last: 100) { nodes { id isResolved } } } } }'

Shell Quoting Notes:

  • Single quotes (as above) prevent shell variable expansion - use when query contains literal placeholders like
    {OWNER}
  • Double quotes needed only for shell variable substitution (e.g.,
    $OWNER
    ) - must escape inner quotes with
    \"
  • Single-line refers to the GraphQL query itself (no newlines), not shell quoting style
  • Placeholders like
    {OWNER}
    ,
    {REPO}
    ,
    {NUMBER}
    are documentation notation - replace with actual values before running

2. Always Use
last: 100
Not
first: ##

NEVER use

first: ##
in GraphQL queries. Always use
last: 100
to ensure you get ALL recent items and don't miss threads/comments due to pagination cutoff.

3. No For Loops

NEVER use for loops or while loops - they require permission prompts and break automation. Instead:

  • Run single
    gh api graphql
    commands against single thread IDs
  • Process threads one at a time with individual approved commands
  • If possible, include multiple thread IDs as separate parameters in a single call

4. Commits Must Be Signed

When making direct commits for PR changes, ALL commits MUST be signed.

Core Query Patterns

1. Get Review Threads

Purpose: Fetch all review threads for a PR with resolution status and comments.

gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { reviewThreads(last: 100) { nodes { id isResolved path line startLine comments(last: 100) { nodes { id databaseId body author { login } createdAt } } } } } } }'

Key Fields:

FieldDescription
id
Thread ID for resolution (format:
PRRT_xxx
)
isResolved
Boolean resolution status
path
File path the comment is on
line
/
startLine
Line numbers in the file
comments.nodes[].body
Comment text
comments.nodes[].databaseId
Numeric ID for REST API operations

2. Resolve Review Thread

Purpose: Mark a review thread as resolved.

gh api graphql --raw-field 'query=mutation { resolveReviewThread(input: {threadId: "{THREAD_ID}"}) { thread { id isResolved } } }'

Requirements:

  • Thread ID must be a valid GraphQL node ID starting with
    PRRT_
  • You must have write access to the repository

3. Verify All Threads Resolved

Purpose: Check if any unresolved threads remain on a PR.

gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { reviewThreads(last: 100) { nodes { isResolved } } } } }' | jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'

Success Criteria: Returns

0
(no unresolved threads).

4. Get PR Mergeable Status

Purpose: Check if a PR can be merged.

gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { mergeable statusCheckRollup { state } reviewDecision } } }'

Mergeable Values:

  • MERGEABLE
    - Can be merged
  • CONFLICTING
    - Has merge conflicts
  • UNKNOWN
    - Status still being calculated

Thread Resolution Workflow

Step 1: Get Unresolved Thread IDs

Run the query to get all threads, then use jq to extract unresolved thread IDs:

gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { reviewThreads(last: 100) { nodes { id isResolved } } } } }' | jq -r '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .id'

Step 2: Resolve Each Thread Individually

For each thread ID from Step 1, run the resolve mutation as a separate command:

gh api graphql --raw-field 'query=mutation { resolveReviewThread(input: {threadId: "PRRT_kwDOxxxxx"}) { thread { id isResolved } } }'

Important: Do NOT use loops. Run each resolve command individually.

Step 3: Verify Resolution

After resolving all threads, verify none remain unresolved:

gh api graphql --raw-field 'query=query { repository(owner: "{OWNER}", name: "{REPO}") { pullRequest(number: {NUMBER}) { reviewThreads(last: 100) { nodes { isResolved } } } } }' | jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'

Node ID Handling

GitHub uses two ID systems. Understanding when to use each is critical.

GraphQL Node IDs (base64 encoded)

Used for GraphQL operations:

  • Review thread:
    PRRT_kwDOO1m-OM5gtgeQ
  • PR comment:
    PRRC_kwDOO1m-OM5gtgeR
  • Pull request:
    PR_kwDOO1m-OM4...

Get via GraphQL query

nodes[].id
fields.

REST API Numeric IDs

Used for REST API operations:

  • Get via:
    gh api repos/{OWNER}/{REPO}/pulls/{NUMBER}/comments | jq '.[].id'
  • Or via GraphQL:
    comments.nodes[].databaseId

ID Usage Table

OperationID TypeHow to Get
Resolve threadGraphQL node ID (
PRRT_xxx
)
From
reviewThreads.nodes[].id
Reply to commentNumeric IDFrom REST API or
databaseId
React to commentNumeric IDFrom REST API or
databaseId
Get thread statusGraphQL node IDFrom
reviewThreads.nodes[].id

Making Changes to PRs

When resolving review threads requires code changes:

Option 1: Use Worktree (Preferred)

  1. Create or switch to the PR's worktree:

    BRANCH="{BRANCH}"
    SANITIZED_BRANCH="$(printf '%s' "$BRANCH" | tr -c 'A-Za-z0-9._-' '_')"
    git worktree add "$HOME/git/{REPO}/$SANITIZED_BRANCH" "$BRANCH"
    cd "$HOME/git/{REPO}/$SANITIZED_BRANCH"
    
  2. Make changes normally

  3. Commit with signature:

    git commit -S -m "message"

  4. Push:

    git push origin {BRANCH}

Option 2: Direct Signed Commit (Small Changes Only)

For small single-file fixes, you can commit directly if and only if commits are signed:

# Ensure GPG signing is configured
git config --global commit.gpgsign true
git config --global user.signingkey {YOUR_KEY_ID}

# Make the change and commit with signature
git commit -S -m "fix: address review feedback"
git push origin {BRANCH}

Never:

  • Create branches in /tmp folders
  • Output temporary scripts
  • Make unsigned commits

Placeholder Reference

NOTE: Placeholders below use

{CURLY_BRACES}
notation for documentation clarity. These are NOT bash variables and will NOT be expanded by the shell. You must manually replace them with actual values before running commands.

PlaceholderDescriptionExample
{OWNER}
Repository owner (replace with actual value)
JacobPEvans
{REPO}
Repository name (replace with actual value)
ai-assistant-instructions
{NUMBER}
PR number integer (replace with actual value)
123
{THREAD_ID}
Thread ID from GraphQL query (replace with actual value)
PRRT_kwDOO1m-OM5gtgeQ
{BRANCH}
Branch name (replace with actual value)
fix/my-feature

Common Errors and Solutions

ErrorCauseSolution
"Field 'reviewThreads' doesn't exist"Wrong API versionUse GraphQL v4 (default)
"Resource not accessible by integration"Missing permissionsCheck
gh auth status
, ensure repo access
"Invalid node ID"Wrong ID formatVerify ID starts with correct prefix (
PRRT_
, etc.)
Encoding/parsing issuesMulti-line queryUse single-line format with
--raw-field
"Could not resolve to a PullRequest"Wrong PR numberVerify PR exists and number is correct

Commands Using This Skill

  • /resolve-pr-review-thread [all]
    - Primary consumer for thread resolution
  • /manage-pr
    - Thread resolution during PR management
  • /review-pr
    - Creating and reading review threads
  • /pr-review-feedback
    - Reference documentation for GraphQL patterns

Best Practices

  1. Always use
    last: 100
    : Never use
    first: ##
    to avoid missing threads
  2. No loops: Run individual commands, don't batch with loops
  3. Verify resolution: After resolving, query again to confirm
    isResolved: true
  4. Sign all commits: Use
    git commit -S
    for all direct commits
  5. Use worktrees: Prefer worktrees over /tmp folders for code changes
  6. Check permissions first: Run
    gh auth status
    before GraphQL operations
  7. Use jq for parsing: Extract specific fields with
    jq
    rather than parsing raw JSON