pr-reviewer — Sea Haven Industries
Find a file
Adam Moussa 15a52bff40
Add background auto-review worker with SQLite cache
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.
2026-07-01 14:28:11 -04:00
.github Add pr-reviewer local PR review tool 2026-07-01 13:48:10 -04:00
app Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
static Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
tests Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
.env.example Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
.gitignore Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
pyproject.toml Add pr-reviewer local PR review tool 2026-07-01 13:48:10 -04:00
README.md Add background auto-review worker with SQLite cache 2026-07-01 14:28:11 -04:00
requirements-dev.txt Add pr-reviewer local PR review tool 2026-07-01 13:48:10 -04:00
requirements.txt Add pr-reviewer local PR review tool 2026-07-01 13:48:10 -04:00
run.sh Add pr-reviewer local PR review tool 2026-07-01 13:48:10 -04:00

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

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