PrimoDev/ apps

PR Widget

Your GitHub pull requests in the Mac menu bar

  • macOS
  • Free
  • Open source
  • v1.1.0

What is PR Widget?

PR Widget is a native macOS menu bar app that watches your GitHub pull requests and notifies you when they change. It shows what needs your review, your open PRs with CI status and new PRs on your repos, and has a window to read the diff and review without opening the browser.

It is free and the code is on GitHub (the repo does not declare a license yet). To install, download the DMG from Releases and drag it to Applications; it is ad-hoc signed but not notarized, so macOS asks you to approve it on first launch.

What it does

  1. 01Three lists: needs my review, my open PRs and new PRs on my repos
  2. 02CI status and review decision on every PR
  3. 03Polls GitHub every 60 seconds and sends a notification when something changes
  4. 04Window with the per-file diff, color-coded with line numbers
  5. 05Inline comments, suggestions, replies and resolving threads
  6. 06Submit a review as comment, approve or request changes (⌘↩)
  7. 07Dismiss a PR; it comes back by itself on new activity
  8. 08Token stored in the macOS Keychain, plus launch at login

FAQ

Is PR Widget free?
Yes. The app is free and the code is on GitHub. The repo does not have a license file yet.
Which macOS version does it need?
macOS 13 or later.
How do I install it and get past Gatekeeper?
Download the DMG from Releases, open it and drag PR Widget to Applications. On macOS 15 Sequoia or later, try to open it once, then go to System Settings > Privacy & Security and click Open Anyway. On macOS 14 or earlier, right-click the app and choose Open. If it still won't open, run xattr -dr com.apple.quarantine "/Applications/PR Widget.app".
What access does it need?
A GitHub Personal Access Token. For a classic token, the repo and read:org scopes; for a fine-grained token, read access to Pull requests, Contents and Metadata. The token is stored in the macOS Keychain, not in a file. It also asks for notification permission.
Does reviewing from the app change the real PR?
Yes. Submitting a review, posting a comment or resolving a thread happens immediately on the real GitHub PR.
Are there any limits?
Search returns up to 50 PRs per list, the GitHub API limit per page. The new PRs list covers only repos you own, not a whole organization.

Documentation

README from the lucianodiisouza/pr-widget repository, refreshed on every deploy.

A tiny native macOS menu bar app that watches your GitHub pull requests so you stop alt-tabbing to github.com. It shows, in a dropdown from the menu bar:

  • Needs my review: PRs where you were requested as a reviewer.
  • My open PRs: your PRs across any org, with CI status (✅ / ❌ / 🟡) and review decision (👍 approved / ✋ changes requested).
  • New on my repos: PRs opened by other people on repos you own.

It polls GitHub every 60 seconds and fires a desktop notification when something changes on a PR you care about:

  • a new PR lands on one of your repos,
  • someone reviews or comments on your PR,
  • CI passes / fails / starts running,
  • a review decision flips (approved / changes requested).

Clicking a PR in the menu (or clicking a notification) opens it in your browser.

Install

Grab the latest PR Widget <version>.dmg from the Releases page, open it, and drag PR Widget into Applications.

Every pushed v* tag builds a fresh DMG in CI and attaches it to the release.

Opening an unsigned app on macOS

PR Widget is ad-hoc signed but not notarized by Apple, so macOS Gatekeeper blocks it on first launch with a message like "PR Widget can't be opened because Apple cannot check it for malicious software." This is expected — here's how to run it anyway.

macOS Sequoia (15) and later — right-click → Open no longer works for un-notarized apps; you have to approve it in Settings:

  1. Try to open PR Widget once (double-click). You'll get the blocked dialog — click Done.
  2. Open → System Settings → Privacy & Security.
  3. Scroll to the Security section. You'll see "PR Widget was blocked to protect your Mac." Click Open Anyway.
  4. Confirm with Open Anyway and authenticate with Touch ID / your password. The app launches and macOS remembers the choice.

macOS Sonoma (14) and earlier:

  1. In Applications, right-click (or Control-click) PR Widget → Open.
  2. In the dialog, click Open again. macOS remembers the choice from then on.

Terminal fallback (any version). If the app still won't open, strip the quarantine flag it picked up from being downloaded:

xattr -dr com.apple.quarantine "/Applications/PR Widget.app"

Then launch it normally. This is only needed once, right after installing.

Why the warning? The app isn't code-signed with a paid Apple Developer ID or notarized, so Gatekeeper can't verify a known developer. Building from source with ./run.sh sidesteps this entirely.

Build & run

./run.sh

That builds the app, packages it into PR Widget.app, ad-hoc code-signs it (so notifications are allowed), and launches it. Look at the top-right of your menu bar for the pull-request icon.

To rebuild after code changes:

./run.sh --rebuild

First launch: connect GitHub

On first launch it asks for a GitHub Personal Access Token. Create one at:

Paste it into the prompt and hit Save. The token is stored in your macOS Keychain (not in any file). You can change it later from the menu → Set GitHub Token….

Notifications

The first successful sync is silent (it just records a baseline), so you don't get a flood of alerts for every currently-open PR. From then on you'll only be notified about changes.

If macOS asks whether "PR Widget" may send notifications, allow it. If you never granted permission, the app falls back to AppleScript notifications so you still get alerts.

The window

Launching opens a Pull Requests window (also: menu bar → Open PR Window, ⌘O). While it's open the app becomes a normal app: it gets a Dock icon and shows up in ⌘-Tab. Close the window and it drops back to menu-bar-only.

The window is a split view: the PR list on the left, a code-review pane on the right.

Left (list):

  • Filter dropdown (All / Needs review / My PRs / New on my repos) + search.
  • Dismiss a PR: hover a row and click the ✕ (or right-click → Dismiss). It hides from the list, but reappears automatically if it gets new activity (a new comment, review, or CI change), since that's when you'd want another look.
  • Click the ↗︎ on a row (or right-click → Open in Browser) to open it on GitHub.
  • Gear menu (settings): Set GitHub Token, Refresh, Launch at Login, Show dismissed, Restore all dismissed.

Right (review pane): select a PR to load it:

  • PR description and the conversation (reviews + comments).
  • The full diff, per file, color-coded, with line numbers. Big files are capped (open on GitHub for the rest).
  • Review inline: existing review threads appear anchored to their lines, with a Resolve / Unresolve button and a Reply box.
  • Comment on a line: hover a line, click the blue +, type, and post. Use Suggestion to drop a ```suggestion block seeded with the line.
  • Submit a review: write a body, pick Comment / Approve / Request changes, and submit (⌘↩).

These are live actions against GitHub: submitting a review, posting a comment, or resolving a thread happens immediately on the real PR.

Window size/position is remembered between launches.

Run at login

Use the gear menu → Launch at Login in the window (or the menu bar item of the same name). It registers via macOS's modern SMAppService, so it also shows up under System Settings → General → Login Items.

Project layout

File What it does
Sources/PRWidget/main.swift Entry point; runs as a menu-bar accessory app.
AppDelegate.swift Status item, menu, 60s polling loop, token prompt.
GitHubClient.swift One GraphQL request → login + all three PR buckets.
Models.swift PR model + GraphQL decoding.
StateStore.swift Diffs each refresh against the last to produce events.
NotificationManager.swift Desktop notifications (UserNotifications + osascript fallback).
Keychain.swift Stores the token in the macOS Keychain.
build.sh / run.sh Build, bundle, sign, launch.

Notes / limits

  • Search is capped at 50 PRs per bucket (GitHub API limit per page).
  • "New on my repos" covers repos you own. Watching a whole org's repos would need an extra query, easy to add if you want it.
  • Polling interval is 60s; change refreshInterval in AppDelegate.swift.