A local tool for reviewing GitHub pull requests across all your repos and scheduling auto-merges once approval and CI conditions are met.
- Web UI at
http://localhost:3847— browse PRs, view diffs, schedule merges - CLI — all the same actions from the terminal
- Scheduler — runs inside the web server; checks every minute and merges when conditions are met
npm install- Go to https://github.com/settings/developers → New OAuth App
- Fill in:
- Application name: PRR (or anything you like)
- Homepage URL:
http://localhost:3847 - Authorization callback URL:
http://localhost:3847/auth/callback
- Click Register application
- On the next page, scroll down and enable Device Flow
- Copy the Client ID
cp .env.example .envOpen .env and set your Client ID:
GITHUB_CLIENT_ID=your_client_id_here
npm run buildThe first time you run any command, a browser window will open to https://github.com/login/device. Enter the code shown in your terminal and click Authorize.
The token is cached at ~/.config/prr/token.json — you won't be prompted again until it expires.
Org SSO: If your GitHub org uses SAML SSO, go to
https://github.com/settings/connections/applications/<your-client-id>
and click Grant next to your org after authorizing.
node dist/index.js webOpens http://localhost:3847 in your browser. The merge scheduler runs automatically inside the same process — no separate daemon needed.
npm install -g .
prr webAll commands authenticate automatically on first run.
List all open pull requests you authored or are involved in, across all repos.
prr list
Show diff, reviews, CI checks, and comments for a specific PR in the terminal.
prr review timsara331/my-repo#42
Schedule a PR to be automatically merged at a specific time. The merge only fires if all configured conditions are met at that time.
prr schedule timsara331/my-repo#42 2025-06-15T09:00:00
Options:
| Flag | Default | Description |
|---|---|---|
-m, --method <method> |
merge |
Merge method: merge, squash, or rebase |
-a, --approvals <n> |
1 |
Minimum number of approvals required |
--no-checks |
— | Skip the CI checks requirement |
# Squash merge with no approval or CI requirements
prr schedule timsara331/my-repo#42 2025-06-15T09:00:00 --method squash --approvals 0 --no-checksThe datetime must be in ISO 8601 format:
YYYY-MM-DDTHH:MM:SS
Times are interpreted as your local timezone.
Show all scheduled merges and their current status.
prr status
Filter by status:
prr status --filter pending
prr status --filter merged
prr status --filter failed
prr status --filter cancelledCancel a pending scheduled merge. The ID is shown in prr status (first 8 characters are enough if unique).
prr cancel 314bcfe7
Run the merge scheduler as a standalone background process (alternative to prr web if you only want the scheduler without the UI).
prr daemon
The daemon checks every minute for due schedules and merges PRs that meet all conditions. Logs to stdout.
Start the web UI and open it in your browser. The scheduler runs inside this process automatically.
prr web
prr web --port 4000 # custom port
When a scheduled merge fires, the engine re-checks all conditions fresh from the GitHub API before merging:
| Condition | What is checked |
|---|---|
| PR is open | The PR hasn't already been merged or closed |
| Not a draft | Draft PRs are skipped |
| Min approvals | At least N approving reviews with no outstanding change requests |
| All CI checks pass | Every check run is completed with success or skipped conclusion |
| No merge conflicts | GitHub reports the PR as mergeable |
If any condition fails at merge time, the schedule is marked failed with a reason — it will not retry automatically. You can create a new schedule if needed.
src/
├── auth/ GitHub OAuth Device Flow, token cache
├── github/ PR listing, PR detail, merge validation + execution
├── scheduler/ SQLite store, node-cron daemon engine
├── commands/ CLI command handlers
└── web/ Express server, API routes, browser UI (index.html)
data/ SQLite database (created at runtime, gitignored)
dist/ Compiled output (gitignored)
Run without building (uses tsx to run TypeScript directly):
npm run dev -- web
npm run dev -- listRebuild after making changes:
npm run build