Skip to main content

gh-prs

A simple CLI that lists the GitHub pull requests you need to act on — and merges the ones that are ready — powered by the gh CLI. No TUI — just readable, colored, grouped output.

By default it shows only the PRs that need your attention:

  • Needs your review — PRs where your review is requested and still needed: once the PR is approved (mergeable without you) it is hidden unless you are personally on the requested-reviewers list (not just through a team), and it is also hidden while changes are requested (the author is reworking it). Drafts are excluded (not ready for review), as are conflicting PRs (a review would be staled by the rebase). A PR also resurfaces here when your previous review was dismissed.
  • New commits since your review — PRs you already reviewed (approved, requested changes, left a review comment, or had your review dismissed by a push) whose head commit is no longer the one you reviewed — new commits or a rebase the author forgot to re-request review for; the case that is otherwise easy to miss. Hidden while the PR is conflicting (more commits are coming anyway). A PR never appears both here and in Needs your review: whenever it qualifies there (e.g. a re-request after a comment-only review), that section wins; a re-request after your still-standing approval keeps it here.
  • Ready to ship — PRs you created that are approved, with CI green (or no checks) and no conflicts. A stacked PR — one whose base branch is itself the head of another open PR — is held back: merging it now would fold it into the parent PR instead of shipping it. It appears here once the parent merges and GitHub retargets it to the default branch; in the meantime the explicit views (-c/-a) still list it.
  • CI failed — PRs you created where a check is failing.
  • Conflicts to resolve — PRs you created that have merge conflicts, drafts included (the base moved underneath your draft; resolving early is cheaper than later).
  • Unresolved comments — reply or resolve — PRs you created with an unresolved review thread where someone else has the last word: feedback waiting on your answer. Threads you replied to last don't count — the ball is back in the reviewer's court — so the PR drops out as soon as you've answered (or resolved) everything, and resurfaces if a reviewer follows up.
  • Waiting on review — time to nudge — PRs you created that are still awaiting review and have gone quiet longer than the staleness threshold (3 days by default). There's nothing for you to do — the code is fine, CI is green, no conflicts — but it has been sitting long enough that pinging the reviewers is warranted. Any new activity (a comment, a commit) resets the clock, so it won't nag while there's discussion. A PR GitHub still labels "changes requested" shows up here too, once you've pushed past every outstanding review and a reviewer is on the hook again — GitHub leaves that label in place until someone reviews afresh, so without this the PR would stay invisible no matter how long it waited. Change the threshold with --stale-after 5d or the stale_after config setting; set it to null in the config to turn the nudge off entirely, or set skip_weekends to count only working days.
  • Drafts gone quiet — finish or mark ready — draft PRs you created that have sat untouched longer than the same staleness threshold. A fresh draft is deliberately parked work-in-progress and stays out of the way (failing CI included — red checks are expected while iterating), but one that has gone quiet is probably forgotten: finish it, mark it ready, or close it. Shares the Waiting on review threshold and off switch.

Prerequisites

  • GitHub CLI (gh) installed and authenticated (gh auth login)
  • Python 3.14+
  • uv

Install

With Homebrew:

brew install denrou/gh-prs/gh-prs

Or from PyPI:

uv tool install gh-prs

Or straight from the repository:

uv tool install gh-prs --from git+https://github.com/denrou/gh-prs.git

As a gh alias

gh alias set --shell prs 'gh-prs'

Then simply run:

gh prs

Usage

gh prs              # PRs that need your attention (default)
gh prs -c/--created # every open PR you created (alias: --me)
gh prs -r/--review  # every PR awaiting your review
gh prs -a/--all     # every PR you are involved with
gh prs --json       # raw JSON (for scripting)
gh prs --count      # print only the PR count for the selected view
                    # (attention count by default; handy for status bars)
gh prs --no-color   # disable colored output

gh prs snooze 123           # hide a PR (of the current repo) until tomorrow morning
gh prs snooze 123 -R o/r    # …of another repo (owner/repo)
gh prs snooze 12 34 --for 3d  # …several at once, for a custom window (12h, 3d, 1w)
gh prs unsnooze 123         # remove a PR's snooze
gh prs snooze               # with no arguments: list snoozed PRs

gh prs merge 123            # approve (if it isn't yours) and squash-merge a PR
gh prs merge 12 34 -R o/r   # …several, in order, in another repo
gh prs merge 123 --auto     # …or enable auto-merge and let GitHub finish
gh prs merge 123 --admin    # …or bypass branch protection (as gh pr merge --admin)

gh prs --stale-after 5d  # flag your PRs (review-waiting or draft) quiet this long

--count exits non-zero when fetching fails, so status-bar scripts can tell "no PRs" apart from "the lookup broke". With -c or -r it uses a fast count-only query (well under a second) — ideal for frequent polling.

Snoozing

Sometimes a PR legitimately needs someone's attention but not yours — say a dependency bump routed to you through a team when a teammate is the natural reviewer. gh prs snooze <pr>... hides one or more PRs from the default attention view; gh prs snooze with no arguments lists what's currently snoozed, and gh prs unsnooze <pr>... brings a PR back early. Reference a PR the way gh does: a bare number, scoped by -R/--repo owner/repo (or the repository of the current directory when omitted), or a full URL. Bare numbers are resolved through gh, so Enterprise hosts work too.

A snooze lasts until tomorrow morning by default (--for 12h/3d/1w to change). Days and weeks are counted on the calendar and end at local midnight: --for 1d at noon, or at 7 a.m., brings the PR back on your first look tomorrow, and --for 3d on the morning three days from now. Hours stay an exact span — --for 4h means four hours. A snooze is also tied to the PR's state at snooze time: its head commit and the reasons it needs your attention. Whichever comes first — the window elapsing, new commits landing, or those reasons changing (say a review lands and a PR that was waiting is now yours to merge) — resurfaces the PR with a warning and drops the snooze, so you acknowledge a specific state for a bounded time, never future work. The attention view prints how many snoozed PRs it withheld on stderr — hiding is visible, never silent. Explicit views (-c/-r/-a), --count for those views, and --json ignore snoozes entirely, so scripts and exact counts are unaffected.

Snoozes are stored locally in ~/.config/gh-prs/snooze.json (honors $XDG_CONFIG_HOME); they never touch the PR on GitHub.

Merging

gh prs merge <pr>... closes the loop the attention view opens: it squash-merges each PR and deletes its branch, approving it first when you are allowed to (you didn't author it) and haven't already. PRs are referenced the same way as for snoozing — a bare number scoped by -R/--repo or the current directory, or a full URL — and are handled in the order given.

Because a merge can't be undone, every PR is checked before anything is merged, and a single problem aborts the whole batch with nothing done: the PR must be open, not a draft, free of conflicts (and GitHub must have finished computing that — a PR pushed seconds ago is refused, retry shortly), have a known head commit, and not be stacked on another open PR (merging would fold it into the parent instead of shipping it). Checks must be green or absent, and the review decision must not stand in the way: approved, not required, or required on a PR your own approval is about to satisfy. Once the batch is under way, the first merge that fails stops it, and the PRs left untouched are listed so you can rerun with just those. Each merge is pinned to the head commit that was checked, so a push landing in between makes GitHub refuse it rather than merging something you didn't look at.

Two flags relax the checks the way gh pr merge itself does. --auto enables auto-merge instead of merging now, so running or failing checks and a pending review requirement are left to GitHub to wait on; a standing "changes requested" review still blocks. --admin uses administrator privileges to bypass branch protection, so checks and the review decision are not preflighted at all. Neither lifts the unconditional checks above, and they can't be combined.

This is the one subcommand that writes to GitHub — it runs gh pr review --approve and gh pr merge --squash --delete-branch on your behalf, nothing else.

Configuration

Settings live in ~/.config/gh-prs/config.json (honors $XDG_CONFIG_HOME), separate from the snooze store. It's optional — every setting has a default. Two keys tune the Waiting on review and Drafts gone quiet nudges, and a third silences review requests you never intend to answer:

{
  "stale_after": "5d",
  "skip_weekends": true,
  "mute": [{ "author": "centreon-renovate", "unless_labels": ["S-Python"] }]
}

stale_after is the silence threshold. It accepts the same duration syntax as --for/--stale-after (12h, 3d, 1w), or null to disable both nudges. The --stale-after flag overrides the file for a single run. As with snoozes, days are counted on the calendar: with 3d, a PR last touched on Monday is flagged from Thursday morning, whatever the hour on Monday, so the day's nudges are all there when you start instead of trickling in through the afternoon. A threshold in hours (72h) stays an exact span.

skip_weekends (default false) leaves Saturdays and Sundays out, in your machine's timezone, so a PR pushed on Friday isn't flagged on Monday for a weekend nobody spent reviewing. It applies to snoozes too: --for 1d on a Friday brings the PR back on Monday morning. It also makes 1w five days rather than seven, which keeps it a same-weekday anniversary: a Thursday PR is nudged the following Thursday, not the Monday after.

mute is a list of rules, each naming a PR author and, optionally, the unless_labels that exempt a PR from it. The example reads "hide centreon-renovate's PRs unless they carry S-Python" — the shape of a bot whose dependency bumps land on your whole team while only one stack is yours. Where a snooze silences one PR for a while, a mute rule silences a kind of PR for good. Muted PRs drop out of the default view and --count; a dim line on stderr says how many were withheld, and gh prs -r (like -a and --json) still lists them, so nothing disappears without a trace. Logins and labels match case-insensitively. Use the author login as GitHub's API reports it — a GitHub App is its slug without the [bot] suffix; gh prs -r --json prints the author and labels the tool sees. Your own PRs are never muted, whatever the rules say.

An unreadable or invalid config only warns and falls back to the defaults (3-day calendar threshold, no mute rules), so a typo never breaks the tool — and a broken mute list hides nothing rather than guessing which rules you meant.

For status bars, prefer the uv tool install binary (~/.local/bin/gh-prs) over uv run inside the repo — it skips ~250 ms of project resolution per invocation.

Release files for gh-prs 0.15.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gh-prs 0.15.0
File Size Uploaded
gh_prs-0.15.0.tar.gz 87.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gh-prs 0.15.0
File Interpreter ABI Platform
gh_prs-0.15.0-py3-none-any.whl Python 3 none any Details

Total release size: 132.1 kB

Release files / gh_prs-0.15.0.tar.gz

Download URL gh_prs-0.15.0.tar.gz
Size 87.8 kB
Tags Source
SHA-256 checksum
How to use checksums
53256b379bf6b9d77e507b3ed04fbf6c95d99ed4f89240fa22b9ed91405d3ad5
BLAKE2b-256 checksum
How to use checksums
e455f66d74411739b342d9e0173d12df0d18c90f1aa5b5b85257f11cbf6ff261
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / gh_prs-0.15.0-py3-none-any.whl

Download URL gh_prs-0.15.0-py3-none-any.whl
Size 44.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
df1342ef065b4f0774edc4bb0c484ba2e6dc08627017a940b00eb0f640183206
BLAKE2b-256 checksum
How to use checksums
3f4ee699f746b58593047e0dbfeed79da6c1706ba37934674c0133e99c76ae4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.15.0 This release

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page