Skill3.1k repo starsupdated today
triage-github
This Claude Code skill triages all open GitHub issues, pull requests, and discussions in a repository by spawning up to 100 parallel subagents to evaluate each item, then generates a single prioritized report recommending which PRs to review first, which issues to address first, and which discussions require maintainer attention. Use it when you need a comprehensive, ranked overview of your repository's open work and want to know where to focus effort next, rather than manually reviewing individual items one at a time.
Install in Claude Code
Copygit clone --depth 1 https://github.com/TanStack/ai /tmp/triage-github && cp -r /tmp/triage-github/.grok/skills/triage-github ~/.claude/skills/triage-githubThen start a new Claude Code session; the skill loads automatically.
Definition
SKILL.md
# Triage GitHub Issues, PRs & Discussions in Parallel
## When to use
The user wants a prioritized view of everything open on the current repo's GitHub: which PRs to merge/review first, which issues to fix first, and which discussions need maintainer engagement. Trigger phrases include "triage the backlog", "what should I look at first", "prioritize open PRs and issues", "sweep open work", "triage discussions".
Do **not** invoke for single-item review (just look at it directly) or when the user wants ongoing automation (use `/schedule` instead).
## Prerequisites
- `gh` CLI is authenticated (`gh auth status`). If not, stop and ask the user to authenticate — do not attempt to fix auth automatically.
- Run from inside a git repo whose `origin` points at the GitHub repo to triage. Confirm with `gh repo view --json nameWithOwner,hasDiscussionsEnabled`.
- If `hasDiscussionsEnabled` is `false`, skip the discussions section entirely (don't fetch, don't include in budget, note in report that discussions are disabled).
## Procedure
### 1. Fetch open work
Run these `gh` calls in parallel. Use JSON so the downstream agent prompts are self-contained. The discussions call is a GraphQL query because `gh` has no built-in `discussion list` command.
```bash
gh pr list --state open --limit 200 --json number,title,url,author,assignees,createdAt,updatedAt,isDraft,mergeable,reviewDecision,labels,additions,deletions,changedFiles,statusCheckRollup
gh issue list --state open --limit 200 --json number,title,url,author,createdAt,updatedAt,labels,comments,reactionGroups
gh api graphql -f query='
query($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
discussions(first: 100, orderBy: {field: UPDATED_AT, direction: DESC}, states: OPEN) {
totalCount
nodes {
number
title
url
createdAt
updatedAt
upvoteCount
isAnswered
locked
category { name }
author { login }
labels(first: 5) { nodes { name } }
comments(first: 0) { totalCount }
reactions { totalCount }
}
}
}
}' -F owner=<OWNER> -F name=<REPO>
```
Substitute `<OWNER>` and `<REPO>` from `gh repo view --json nameWithOwner`.
If the combined total exceeds 100 items, tell the user the counts (PRs / issues / discussions) and ask whether to cap at 100 most-recently-updated or split into batches. The agent cap is 100 total across all three categories.
### 2. Decide the parallel split
- Count `nPRs`, `nIssues`, `nDiscussions`.
- If `nPRs + nIssues + nDiscussions <= 100`: spawn one agent per item.
- Otherwise: prioritize PRs first (they block contributors), then issues by most-recently-updated, then discussions by most-recently-updated, up to the 100 budget. Note in the final report which items were skipped.
### 3. Fan out subagents
Dispatch **all agents in a single message** using multiple `Agent` tool calls (Claude Code parallelizes when they're in one block). Use `subagent_type: "general-purpose"` and `run_in_background: false` — you need the results synchronously to write the report.
Per-PR prompt template (substitute the bracketed values):
```
Triage GitHub PR [URL]. You have read-only access via `gh` and web tools.
Gather:
- `gh pr view [NUMBER] --json title,body,author,assignees,createdAt,updatedAt,isDraft,mergeable,mergeStateStatus,reviewDecision,labels,additions,deletions,changedFiles,statusCheckRollup,comments,closingIssuesReferences`
- `gh pr diff [NUMBER]` (skim — don't dump it)
- Recent review comments if any
`closingIssuesReferences` is GitHub's authoritative "this PR closes #X" linkage (populated by closing keywords like `Closes #123`). Put those issue numbers in `closesIssues`. Also scan the PR body/title for issue references that use closing keywords but weren't auto-linked (cross-repo, typos) and include those too. `assignees` is the array of assigned logins (may be empty).
Return ONLY a JSON object on a single line (no prose, no fences), matching:
{"kind":"pr","number":N,"title":"...","url":"...","author":"...","assignees":["login",...],"closesIssues":[N,...],"ageDays":N,"sizeLOC":N,"ciStatus":"passing|failing|pending|none","mergeable":true|false,"reviewState":"approved|changes_requested|review_required|none","draft":true|false,"priority":"P0|P1|P2|P3","reason":"<=140 chars","blockedBy":"<=80 chars or empty","recommendedAction":"merge|review|request-changes|close|wait"}
Priority rubric:
- P0: ready-to-merge (approved + green CI + mergeable + non-draft), or fixes broken main
- P1: small/focused, passing CI, needs review; or bug fix with clear reproduction
- P2: feature work, larger diff, no blockers
- P3: draft, stale (>30 days no activity), or has unresolved conflicts/failures
Be terse. One JSON object. No commentary.
```
Per-issue prompt template:
```
Triage GitHub issue [URL]. Read-only access via `gh`.
Gather:
- `gh issue view [NUMBER] --json title,body,author,createdAt,updatedAt,labels,comments,reactionGroups,assignees`
- Cross-referenced/linked PRs from the timeline: `gh api "repos/<OWNER>/<REPO>/issues/[NUMBER]/timeline" --jq '[.[] | select(.event=="cross-referenced" and .source.issue.pull_request != null) | .source.issue.html_url] | unique'` (substitute `<OWNER>`/`<REPO>`). Any URL returned is a PR that references this issue — capture it in `linkedPR`.
- Skim comments for repro steps, workarounds, and any "fixed by #NNN" / PR links
Set `linkedPR` to the URL of an open PR that addresses this issue if one exists (from the timeline query or comments), else empty. This is used to dedup: issues with a linked PR are folded under that PR in the report. `assignees` is the array of assigned logins (may be empty).
Return ONLY a JSON object on one line:
{"kind":"issue","number":N,"title":"...","url":"...","author":"...","assignees":["login",...],"ageDays":N,"reactions":N,"comments":N,"hasRepro":true|false,"linkedPR":"<url or empty>","category":"bug|feature|docs|question|chore","pr