
github-graphql
by JacobPEvans
A comprehensive, vendor-agnostic framework for consistent AI-assisted development workflows - standardized instructions and commands that work seamlessly across Claude, Gemini, Copilot, and local AI models. See also: https://github.com/JacobPEvans/claude-code-plugins
SKILL.md
name: github-graphql description: Use when querying GitHub via GraphQL. Provides patterns for PR threads, comments, and mutations. version: "1.0.0" author: "JacobPEvans"
GitHub GraphQL Patterns
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 graphqlcommands 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:
| Field | Description |
|---|---|
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 mergedCONFLICTING- Has merge conflictsUNKNOWN- 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
| Operation | ID Type | How to Get |
|---|---|---|
| Resolve thread | GraphQL node ID (PRRT_xxx) | From reviewThreads.nodes[].id |
| Reply to comment | Numeric ID | From REST API or databaseId |
| React to comment | Numeric ID | From REST API or databaseId |
| Get thread status | GraphQL node ID | From reviewThreads.nodes[].id |
Making Changes to PRs
When resolving review threads requires code changes:
Option 1: Use Worktree (Preferred)
-
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" -
Make changes normally
-
Commit with signature:
git commit -S -m "message" -
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.
| Placeholder | Description | Example |
|---|---|---|
{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
| Error | Cause | Solution |
|---|---|---|
| "Field 'reviewThreads' doesn't exist" | Wrong API version | Use GraphQL v4 (default) |
| "Resource not accessible by integration" | Missing permissions | Check gh auth status, ensure repo access |
| "Invalid node ID" | Wrong ID format | Verify ID starts with correct prefix (PRRT_, etc.) |
| Encoding/parsing issues | Multi-line query | Use single-line format with --raw-field |
| "Could not resolve to a PullRequest" | Wrong PR number | Verify 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
- Always use
last: 100: Never usefirst: ##to avoid missing threads - No loops: Run individual commands, don't batch with loops
- Verify resolution: After resolving, query again to confirm
isResolved: true - Sign all commits: Use
git commit -Sfor all direct commits - Use worktrees: Prefer worktrees over /tmp folders for code changes
- Check permissions first: Run
gh auth statusbefore GraphQL operations - Use jq for parsing: Extract specific fields with
jqrather than parsing raw JSON
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon


