/github-triage
Clear Dependabot and bot noise from your GitHub notification inbox: mark settled merged and closed PRs done, merge green dependency PRs in repos you maintain, dismiss low-value ones, and leave only real human threads behind.
Claude Code
$ npx -y skills add bendrucker/claude --skill github-triage --agent claude-code
Codex
$ npx skills add bendrucker/claude --skill github-triage -a codex -y
Cursor
$ npx skills add bendrucker/claude --skill github-triage -a cursor -y
Gemini CLI
$ npx skills add bendrucker/claude --skill github-triage -a gemini-cli -y
GitHub Copilot
$ npx skills add bendrucker/claude --skill github-triage -a github-copilot -y
OpenCode
$ npx skills add bendrucker/claude --skill github-triage -a opencode -y
Windsurf
$ npx skills add bendrucker/claude --skill github-triage -a windsurf -y
SKILL.md
github-triage.SKILL.mdname: github-triage
disable-model-invocation: true
description: >-
Clear Dependabot and bot noise from your GitHub notification inbox: mark settled merged and closed PRs done, merge green dependency PRs in repos you maintain, dismiss low-value ones, and leave only real human threads behind.
argument-hint: "[--dry-run]"
allowed-tools:
- AskUserQuestion
- Bash(gh api:*)
- Bash(gh pr view:*)
- Bash(gh pr merge:*)
- Bash(gh repo view:*)
GitHub Triage
Clear bot and Dependabot noise from the notification inbox, leave threads from real humans. `--dry-run` classifies and prints the plan without acting.
Inbox
!`gh api "notifications?all=true&per_page=100" --paginate | jq -r '.[] | [.id, .reason, .subject.type, .repository.full_name, (.subject.url | sub(".*/pulls/";"#") | sub(".*/issues/";"issue#")), .subject.title] | @tsv' | column -t -s $'\t'`
Triage against `all=true`. The default call returns only unread; the app Inbox also shows read-but-not-done threads, where most stale noise sits. First column is the thread id, which is also the mark-done key.
Gather
Resolve your own login once: `gh api user --jq .login`. For each open `PullRequest` thread:
- `gh api repos/<r>/pulls/<n> --jq '{author:.user.login, state, merged:(.merged_at!=null)}'`. Any closed/merged PR is settled: mark done, skip the rest.
- `gh pr view <n> --repo <r> --json mergeStateStatus`. Merge gate, per the table below. It computes async, so re-fetch once on `UNKNOWN`.
- `gh api repos/<r> --jq .permissions.push`. `true` means you can merge.
- Latest actor, only for a your-own-PR-in-your-own-repo thread: `gh api <subject.latest_comment_url> --jq '{login:.user.login, type:.user.type}'`.
| `mergeStateStatus` | Meaning | Action | | --- | --- | --- | | `CLEAN` | green, no conflict, current | mergeable | | `BLOCKED` | needs review or a required check | leave, never force | | `BEHIND` | base moved | leave, Dependabot rebases | | `UNSTABLE` / `DIRTY` | check failed or conflict | classify by importance | | `UNKNOWN` | not computed | re-fetch once |
Classify
First match wins.
- **Closed or merged PR** → done, whatever the author or reason. Largest category: every merge and every landed bump leaves a read-but-not-done thread.
- **Bot or self activity on your own PR** → done. PR author is you, repo owner is you, and the latest actor is you or a bot (`type` `Bot`): your own automation (Worktrunk, Greptile, CI) and replies on your own work. Exception: a *different* human as latest actor is real feedback, leave it. Personal namespace only, not shared orgs.
- **Open human thread** (`reason` `mention`/`comment`, or a person authored) → leave.
- **Open non-Dependabot bot** (e.g. `github-actions[bot]` generated content) → leave; the diff is real.
- **Open Dependabot, `CLEAN`, you have push** → merge, then done.
- **Open Dependabot, not mergeable, low-importance** → done, leave PR open. Low-importance: `deps-dev` tooling (eslint, prettier, globals, ncc, `@types/*`) and routine CI-action bumps (`actions/checkout`, `actions/cache`, `goreleaser-action`).
- **Open Dependabot, not mergeable, runtime/prod dep** → leave. Shipped deps, Go modules, security bumps (`golang.org/x/*`, `through2`, `undici`) are a real call.
- **Non-PR**: `Release` → done; `RepositoryAdvisory` → leave (security).
Ambiguous importance (a `deps-dev` bump that ships, a flaky-looking prod failure) → `AskUserQuestion`. Merges and dismissals are the user's call.
Act
Under `--dry-run`, print the plan and stop.
Merge with `gh pr merge <n> --repo <r> --squash`. Failure with `add the --admin flag` means branch protection is blocking it: do **not** pass `--admin`, leave and report as needs-review. Within one repo, same-file bumps go `BEHIND` after the first merge. Leave them for Dependabot to rebase.
Mark done with `gh api --method DELETE notifications/threads/<id>` (`204` = ok). `DELETE` marks done. `PATCH` only marks read. Mark done *after* a merge, not before: the merge event resurfaces the thread once, and a rerun catches it under the closed/merged rule.
Verify
Done has no REST read-back: `all=true` still lists done threads and `GET .../threads/<id>` still returns `200`, so a clean Inbox can't be confirmed by re-listing. Trust the `204`s. Report what you merged, dismissed, and left (one line each), and tell the user to confirm in the app.
Read more
name: github-triage disable-model-invocation: true description: >- Clear Dependabot and bot noise from your GitHub notification inbox: mark settled merged and closed PRs done, merge green dependency PRs in repos you maintain, dismiss low-value ones, and leave only real human threads behind. argument-hint: "[--dry-run]" allowed-tools: - AskUserQuestion - Bash(gh api:*) - Bash(gh pr view:*) - Bash(gh pr merge:*) - Bash(gh repo view:*)
GitHub Triage
Clear bot and Dependabot noise from the notification inbox, leave threads from real humans. `--dry-run` classifies and prints the plan without acting.
Inbox
!`gh api "notifications?all=true&per_page=100" --paginate | jq -r '.[] | [.id, .reason, .subject.type, .repository.full_name, (.subject.url | sub(".*/pulls/";"#") | sub(".*/issues/";"issue#")), .subject.title] | @tsv' | column -t -s $'\t'`
Triage against `all=true`. The default call returns only unread; the app Inbox also shows read-but-not-done threads, where most stale noise sits. First column is the thread id, which is also the mark-done key.
Gather
Resolve your own login once: `gh api user --jq .login`. For each open `PullRequest` thread:
- `gh api repos/<r>/pulls/<n> --jq '{author:.user.login, state, merged:(.merged_at!=null)}'`. Any closed/merged PR is settled: mark done, skip the rest.
- `gh pr view <n> --repo <r> --json mergeStateStatus`. Merge gate, per the table below. It computes async, so re-fetch once on `UNKNOWN`.
- `gh api repos/<r> --jq .permissions.push`. `true` means you can merge.
- Latest actor, only for a your-own-PR-in-your-own-repo thread: `gh api <subject.latest_comment_url> --jq '{login:.user.login, type:.user.type}'`.
| `mergeStateStatus` | Meaning | Action | | --- | --- | --- | | `CLEAN` | green, no conflict, current | mergeable | | `BLOCKED` | needs review or a required check | leave, never force | | `BEHIND` | base moved | leave, Dependabot rebases | | `UNSTABLE` / `DIRTY` | check failed or conflict | classify by importance | | `UNKNOWN` | not computed | re-fetch once |
Classify
First match wins.
- **Closed or merged PR** → done, whatever the author or reason. Largest category: every merge and every landed bump leaves a read-but-not-done thread.
- **Bot or self activity on your own PR** → done. PR author is you, repo owner is you, and the latest actor is you or a bot (`type` `Bot`): your own automation (Worktrunk, Greptile, CI) and replies on your own work. Exception: a *different* human as latest actor is real feedback, leave it. Personal namespace only, not shared orgs.
- **Open human thread** (`reason` `mention`/`comment`, or a person authored) → leave.
- **Open non-Dependabot bot** (e.g. `github-actions[bot]` generated content) → leave; the diff is real.
- **Open Dependabot, `CLEAN`, you have push** → merge, then done.
- **Open Dependabot, not mergeable, low-importance** → done, leave PR open. Low-importance: `deps-dev` tooling (eslint, prettier, globals, ncc, `@types/*`) and routine CI-action bumps (`actions/checkout`, `actions/cache`, `goreleaser-action`).
- **Open Dependabot, not mergeable, runtime/prod dep** → leave. Shipped deps, Go modules, security bumps (`golang.org/x/*`, `through2`, `undici`) are a real call.
- **Non-PR**: `Release` → done; `RepositoryAdvisory` → leave (security).
Ambiguous importance (a `deps-dev` bump that ships, a flaky-looking prod failure) → `AskUserQuestion`. Merges and dismissals are the user's call.
Act
Under `--dry-run`, print the plan and stop.
Merge with `gh pr merge <n> --repo <r> --squash`. Failure with `add the --admin flag` means branch protection is blocking it: do **not** pass `--admin`, leave and report as needs-review. Within one repo, same-file bumps go `BEHIND` after the first merge. Leave them for Dependabot to rebase.
Mark done with `gh api --method DELETE notifications/threads/<id>` (`204` = ok). `DELETE` marks done. `PATCH` only marks read. Mark done *after* a merge, not before: the merge event resurfaces the thread once, and a rerun catches it under the closed/merged rule.
Verify
Done has no REST read-back: `all=true` still lists done threads and `GET .../threads/<id>` still returns `200`, so a clean Inbox can't be confirmed by re-listing. Trust the `204`s. Report what you merged, dismissed, and left (one line each), and tell the user to confirm in the app.
Other skills on claude.
cli
Type-safe CLI argument parsing with commander and @commander-js/extra-typings, the standard parser for this repo's Bun scripts.…
prose-lab
Turn the user's labels on repo prose, or their notes from reviewing a document in Plannotator, into calibrated Vale rules.
activity
Report real device usage from ActivityWatch. Covers per-app time, window titles, and active vs idle spans. Use when asked "what…
agent-team
Orchestrating Claude Code agent teams. Use when creating teams, spawning teammates, assigning tasks, configuring teammate modes,…
handoff
Hand the current conversation off to a fresh background agent that picks up the work immediately, so you can step away and track…
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about github-triage.
- Which coding agents can use github-triage?
- github-triage installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

