A fast, keyboard-first macOS app for reviewing and merging GitHub pull requests. It shows a PR's description, diff and checks, and lets you merge, with nothing else in the way.
Dummy data. Regenerate with bun run screenshot (--theme=catppuccin-mocha, --width=, --height=, --out=).
- Queue: review requested, involved, and created by me, with counts.
- Smart filters: Ready (green, mergeable, no changes requested), Small (≤150 lines), Recent (48h). The Smart sort ranks by readiness.
- Jev readiness (optional): with
OPENROUTER_API_KEYset, each PR gets a 0–100 readiness score. GitHub facts carry most of it (approval, required checks, mergeability, open threads); Jev adds what GitHub can't see, reading the description and a dated timeline of reviews and comments for review quality, real testing and concerns nothing later resolved. Conflicts, failing required checks, drafts and change requests cap the score. High-risk areas get an outlined badge instead of a lower score. Without a key, it falls back to the built-in rules. - Diffs:
@pierre/diffs, virtualized and syntax-highlighted in web workers. Collapsible files and sticky headers. - Preview:
Popens the preview deployment found in bot comments or the body (for examplepr-123.preview.example.com, Vercel, Netlify, Cloudflare Pages); the header button is disabled when there is none. - Devin:
Dopens the Devin session linked in the PR body or comments; the header button is disabled when there is none.⇧Dmessages that session directly over thedevin acp --cloudprotocol, using your existingdevin auth login.⌘↵sends; the toast confirms only after Devin echoes the message back. - Paste an order: copy any text that mentions PRs (a ranked report, a Slack message, a list of
#123or/pull/123links) and press⌘Vanywhere outside a text box. The list re-sorts to your order, grouped under the headings from your text, with everything else after. A Pasted chip shows how many matched;⌥⌫or its × goes back to normal. - Merge conflicts and failing checks: a red Merge conflicts or Required checks failing badge sits next to the branch, and a conflicted PR stays red even in the merge queue. Fix with Devin (
⇧F) sends the PR's Devin session “Fix merge conflicts”, “Fix CI”, or both. - Fix everything with Devin: in the
⇧Xdialog, Send to Devin (⌘↵) finds each picked PR's Devin session and sends it your message from the box above the buttons (empty means “Fix CI and merge conflicts if any”); the toast counts sent, skipped (no session) and failed. - Required checks only: a PR only counts as failing when a check GitHub marks required has failed. Optional failures (preview deploys, cancelled side jobs) keep the green check; its tooltip lists what failed.
- Review threads: every PR row shows its unresolved thread count; the Threads chip (
⌥6) lists PRs that still have any. Inside a PR, Open threads sits above the conversation with the file and line, the full back-and-forth, Reply, Resolve and Reply & resolve (⌘↵/⌘⇧↵), and a jump to the line in the diff.⇧C(or the threads button in the top bar, which shows the open count) jumps to the first open thread. - Comments: long comments are capped with a Show more toggle, so scrolling never gets stuck inside one.
Copens a comment box on the current PR (drafts are kept per PR);⌘↵posts it throughgh. - Layout: description on the left, diff on the right. Panes resize and hide, and
1–3apply preset proportions. - Smart search (Jev): typing a topic like
frontendorbillingalso finds PRs that don't contain the word, tagged Jev in the list. Literal matches still appear instantly. - Smart groups (Jev):
Tgroups related PRs into efforts, such as a run of lib extractions or UI refactors. Groups are ordered by average readiness and each can be collapsed or selected as a whole for bulk merge. - Conversation: PR comments and reviews appear under the description, humans and bots alike (Devin, Perry, GitHub Actions…), with review verdicts highlighted.
⇧Bhides bot comments. - Merge queue: PRs already in a queue show a yellow marker with their position, and queued merges skip the confirmation.
- Themes: press
Tfor a live-preview picker with 57 themes grouped into Dark (35) and Light (22), or follow macOS. Includes Catppuccin, Tokyo Night, Dracula, One Dark/Light, GitHub (dark, dimmed, light, high contrast), VS Code Dark+/Light+, Nord, Gruvbox, Rosé Pine (main, Moon, Dawn), Solarized, Ayu, Everforest, Kanagawa, Material, Night Owl, Monokai, Poimandres, Synthwave '84, Vitesse, Min, Vesper, and T3 Code's palettes (T3 Code, T3 Chat, Grove, Ocean, Ember, Iris; dark and light, regenerate withbun scripts/import-t3-themes.ts <t3code>/packages/shared/src/themePalettes.ts). Diff syntax colours use the matching editor theme. - Close:
⇧W(or the ⊗ button in the top bar, or Close in the bulk bar) closes the current PR, or every checked one, after a confirmation that lists them. An optional comment is posted first; the branch is kept. - Bulk actions: select with
E/⇧J/⇧R, then approve, merge or close in sequence with per-PR error reporting. - Keyboard: Linear-style single keys, VS Code chords, and vim motions.
?lists every shortcut.
All GitHub access goes through your existing GitHub CLI login (gh auth login). The app never sees or stores a token. The Rust backend exposes a small set of commands that run gh with validated arguments.
gh repo clone sunwrobert/pr-review /tmp/pr-review-src -- -q && bash /tmp/pr-review-src/scripts/install.shThis downloads the latest signed release into /Applications. From then on the app updates itself: it checks GitHub Releases at launch, when focused and every 30 minutes, downloads and installs in the background, and shows an Update pill (or ⌘⇧U) to restart into the new version. Use --from-source to build locally instead.
Every push to main runs .github/workflows/release.yml on macOS: typecheck and tests, bump the patch version from the latest v* tag (scripts/release-version.ts), build a universal (Apple Silicon + Intel) app, sign the update with the updater key, and publish a GitHub Release with latest.json. Bump the major or minor in src-tauri/tauri.conf.json to start a new line.
One-time setup: add the updater private key as repo secrets TAURI_SIGNING_PRIVATE_KEY (contents of ~/.tauri/pr-review.key) and TAURI_SIGNING_PRIVATE_KEY_PASSWORD (empty). The matching public key is in tauri.conf.json, so the app only installs updates signed with it. The app is not Apple-notarized; the installer strips the quarantine flag.
One step: builds from source and installs to /Applications (re-run to update):
gh repo clone sunwrobert/pr-review /tmp/pr-review-src -- -q && bash /tmp/pr-review-src/scripts/install.shFrom a checkout, bun run install:app does the same.
- macOS, Bun, Rust (stable), and Xcode Command Line Tools.
ghauthenticated.- Optional:
OPENROUTER_API_KEYin your environment or login shell for AI readiness scoring, grouping and the Tested filter.
bun install
bun run tauri devbun run app
open "src-tauri/target/release/bundle/macos/PR Review.app"bun run screenshot # docs/screenshot.png, dark theme, 2x
bun run screenshot --theme=github-light --out=docs/light.pngIt builds the frontend against the offline fixture layer in bench/, loads a curated demo queue (bench/demo.ts), opens the featured PR and captures the window in headless Chromium. No GitHub or Jev calls.
bun run test
bun run typecheckVim motions work the same in every pane; the modifier picks the pane.
| Motion | List ⌃ |
Middle pane ⌥ |
Right pane ⌘ |
|---|---|---|---|
| Half page down / up | ⌃D / ⌃U |
⌥D / ⌥U |
⌘D / ⌘U |
| Page down / up | ⌃F / ⌃B |
⌥F / ⌥B |
— (use ⌘D / ⌘U) |
| Line down / up | ⌃E / ⌃Y (or ⌃N / ⌃P) |
⌥E / ⌥Y (or ⌥J / ⌥K) |
⌘E / ⌘Y |
| Top / bottom | ⌃G / ⌃⇧G |
⌥G / ⌥⇧G |
⌘G / ⌘⇧G |
⌘J / ⌘K scroll the diff; / focuses the filter. The middle pane is the description and the right pane is the diff.
| Area | Keys |
|---|---|
| Queue | J/K next/prev · gg/G first/last · Space/⇧Space page the middle pane |
| Files | N or ]c/[c next/prev file · X collapse · S split/unified |
| Filters | ⇧T group related work · ⌥1 Ready · ⌥4 Unready · ⌥0 All (Small ⌥2, Recent ⌥3, Tested ⌥5) · ⇧S sort · ⇧X fix with agent · ⇧U select unready · ⇧R select ready |
| Select | ⇧V visual mode (then J/K) · E toggle · ⇧J/⇧K extend · ⇧R all ready · ⇧U all unready · ⌘A all · ⌫ or Esc clear |
| Act | ⇧X copy an agent prompt to fix every PR with conflicts or failing checks (or just the selected ones) · O open on GitHub (in Chrome) · A approve · ⌘↵ merge (all selected when several are checked) · ⇧W close (same) · ⇧A bulk approve · ⌘↵ bulk merge |
| Layout | T theme picker · ⌘B PR list · 1 review · 2 diff focus · 3 read description · ⌘. focus |
| Lightbox | I open first media · H/L or J/K or ←/→ cycle · gg/G first/last · ⌃D/⌃U skip half · Z zoom · O open · Q/Esc close |
| General | / filter PRs · ⌘F find in this PR (↵/⇧↵ next/prev) · ? shortcuts · R refresh |
UI icons are Lucide (ISC), vendored in src/icons.ts so nothing is fetched at runtime. The Devin mark is traced from its GitHub app avatar.
MIT