mirror of
https://github.com/Sea-Haven-Industries/pr-reviewer.git
synced 2026-10-05 15:22:12 +00:00
Pre-compute PR reviews so they are ready the moment a PR is opened in the queue, instead of waiting on an on-demand Fireworks call each time. A daemon worker polls the queue every POLL_INTERVAL and reviews new or changed non-draft PRs into a local SQLite cache (gitignored). Change detection is two-level: skip when the PR's updated_at is unchanged, and even when it moved, skip the model call when the diff's SHA-256 matches, so comment-only bumps do not burn tokens. Failed reviews retry up to MAX_REVIEW_ATTEMPTS with 429 backoff; departed PRs are closed with a grace window before purge. Singletons are initialized eagerly in the FastAPI lifespan before the worker thread starts to avoid an init race; all cache writes are serialized. New endpoints GET /api/reviews and POST /api/refresh back a dashboard that polls for status (reviewing/ready/error) and opens a ready review instantly. Nothing is posted automatically; the human still decides. Stdlib-only, so no new runtime or test dependencies.
81 lines
4.7 KiB
Markdown
81 lines
4.7 KiB
Markdown
# pr-reviewer
|
|
|
|
A local dashboard that pulls open PRs from your GitHub org, reviews each one with a Fireworks model using the BLOCK / FIX / NIT / QUESTION skill format, and lets you request revisions or post the review to GitHub as yourself.
|
|
|
|
A background worker pre-reviews non-draft PRs on an interval, so a review is usually ready the moment you open one in the queue. You still decide whether and how to post; nothing is ever posted automatically.
|
|
|
|
Everything runs on your machine. This is a local, single-user tool. It is not deployed anywhere, so there is no AWS stack, no CI deploy path, and secrets live only in a local `.env` (gitignored). Your GitHub token and Fireworks key stay in the backend and never reach the browser.
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
cp .env.example .env # then fill in FIREWORKS_API_KEY (and GITHUB_TOKEN if not using gh CLI)
|
|
./run.sh
|
|
```
|
|
|
|
Open http://127.0.0.1:8765
|
|
|
|
## Auth
|
|
|
|
- **GitHub**: leave `GITHUB_TOKEN` blank to use your local `gh auth token`, or set a token. Reviews are posted as whoever the token belongs to, so use the token for the account you want to appear as the reviewer.
|
|
|
|
A **fine-grained personal access token** is recommended (least privilege). Set the resource owner to `Sea-Haven-Industries` and grant only these repository permissions:
|
|
|
|
| Permission | Level | Why |
|
|
|---|---|---|
|
|
| Pull requests | Read and write | read PR data and submit the review |
|
|
| Contents | Read-only | fetch the PR diff |
|
|
| Metadata | Read-only | mandatory (auto-added) |
|
|
|
|
Give it access to all repositories you review (the search silently skips any it can't see). Fine-grained tokens are single-owner, so this token only covers the `Sea-Haven-Industries` org, which is all this tool searches; an org owner may need to approve the token before it works. A classic PAT with `repo` scope also works but is broader than needed.
|
|
- **Fireworks**: set `FIREWORKS_API_KEY`. Change `FIREWORKS_MODEL` in `.env` to swap models.
|
|
|
|
## How it works
|
|
|
|
1. **Background worker** polls your filter (`PR_SEARCH_FILTER`) every `POLL_INTERVAL` seconds and pre-reviews any new or changed non-draft PR, caching the result. The queue shows each PR's status: `reviewing`, `ready`, `error`, or `closed`. **Refresh now** forces an immediate poll.
|
|
2. **Open a PR** — if its review is `ready`, it appears instantly. Otherwise you see its status, and you can **Run review now** on demand.
|
|
3. **Request revision** re-runs the review with your notes folded in as a trusted instruction, separate from the untrusted diff.
|
|
4. **Post review to GitHub** submits it as a PR review. You confirm the event type (COMMENT / APPROVE / REQUEST_CHANGES) and can edit the body first.
|
|
|
|
### Auto-review worker
|
|
|
|
- Reviews are cached in a local SQLite file (`CACHE_DB`, default `pr_cache.db` in the repo root, gitignored) so they survive restarts and aren't recomputed for unchanged PRs.
|
|
- Change detection is two-level: a PR is skipped if its `updated_at` hasn't moved since the last review, and even when it has, the diff's SHA-256 is compared so a comment-only bump doesn't burn tokens.
|
|
- Drafts are skipped. Failed reviews are retried on later cycles up to `MAX_REVIEW_ATTEMPTS`, then left until the PR changes. Rate-limit (HTTP 429) responses back off and retry.
|
|
- `WORKER_CONCURRENCY` controls how many PRs are reviewed in parallel per cycle (default 2).
|
|
|
|
## The @mention rule
|
|
|
|
Any PR whose author login is in `MENTION_AUTHORS` (default `openswe`) gets an `@author` mention prepended to the review summary. Add more logins comma-separated.
|
|
|
|
## Notes
|
|
|
|
- The diff is treated as untrusted input; the model is instructed to ignore any embedded instructions.
|
|
- Cached reviews persist in a local SQLite file. This is a single-user local tool, not a shared service.
|
|
- Large diffs are truncated at `MAX_DIFF_BYTES` to control token cost.
|
|
|
|
## Configuration
|
|
|
|
Set in `.env` (see `.env.example`). Beyond the GitHub/Fireworks keys:
|
|
|
|
| Var | Default | Purpose |
|
|
|---|---|---|
|
|
| `POLL_INTERVAL` | `300` | seconds between background poll cycles |
|
|
| `WORKER_CONCURRENCY` | `2` | PRs reviewed in parallel per cycle |
|
|
| `MAX_REVIEW_ATTEMPTS` | `3` | error retries before giving up until the PR changes |
|
|
| `MAX_PRS` | `100` | cap on PRs pulled per cycle (GitHub search page max) |
|
|
| `CACHE_DB` | `pr_cache.db` | SQLite cache path (absolute, repo root by default) |
|
|
|
|
## Layout
|
|
|
|
```
|
|
app/
|
|
config.py settings from .env
|
|
github_client.py search PRs, fetch diffs, post reviews
|
|
reviewer.py Fireworks call + skill format + markdown rendering
|
|
store.py SQLite cache of pre-computed reviews
|
|
worker.py background poll + auto-review (run_cycle)
|
|
main.py FastAPI endpoints (incl. /api/reviews, /api/refresh)
|
|
static/
|
|
index.html the dashboard
|
|
```
|