Skip to content

Install

You need Docker with Compose v2, a GitHub account, and a Claude Pro, Max, Team or Enterprise plan for anyone who will run reviews.

Terminal window
git clone https://github.com/Wimukti/reviewstage && cd reviewstage
cp .env.example .env
docker compose up -d

Open http://localhost:8899. The first visit is the login page.

Before you sign in, run the doctor. It checks Docker, the .env, that the reviewstage service is healthy, and that the container can reach GitHub:

Terminal window
bin/doctor.sh

Only two values are required to start:

KeyWhat
REPOowner/name of the repository to review.
GITHUB_PATA service token used for reads only: listing review requests and cloning the base repo. A fine-grained PAT with Contents: read, Pull requests: read, Metadata: read on that repository is enough. It never posts or approves.

Everything else has a sensible default. DRY_RUN=1 ships on by default: the dashboard works end to end but refuses to write to GitHub until you flip it. See Configuration for every knob.

Terminal window
docker compose --profile team up -d # adds the review-request poller + Slack cards
docker compose up -d demo # seeds sample runs so you can explore the UI

team is what you want for a shared server; see Team mode. demo is for looking around before wiring anything.

  1. Open http://localhost:8899. With GitHub sign-in configured the page shows Continue with GitHub; without it, a token form. For a solo install the token form is fine: Create a fine-grained token opens GitHub’s fine-grained token page — pick the repositories you review and grant Pull requests: Read and write, Contents: Read and Metadata: Read (a classic token with the repo scope also works). Pick an expiry (90 days is a good default). This token acts as you; it is what makes every comment attributable to a person.
  2. Paste the token. It is verified against GitHub, stored encrypted, and used only for the posts and approvals you click.
  3. On the welcome checklist, Connect Claude: a link opens Claude in a new tab, you authorise with your own account and paste the code back. This runs the genuine claude setup-token flow inside the container, so your reviews bill to your plan.

You are ready for your first review.

Optional for a solo Docker install; recommended for a team. With it, nobody creates or pastes a token: the login page’s one visible action is Continue with GitHub, and the token GitHub issues is stored encrypted and used exactly like a pasted PAT — for the comments and approvals that person clicks, under their own name. Teammates can still open Use a personal access token instead.

  1. On github.com go to Settings → Developer settings → OAuth Apps → New OAuth App (or under your organisation’s settings if the app should belong to the org).

  2. Fill in:

    FieldValue
    Application nameReviewStage (or your team’s name for it)
    Homepage URLyour PUBLIC_URL, e.g. https://reviews.example.com
    Authorization callback URL<PUBLIC_URL>/oauth/callback — exact
    Enable Device Flowoff
  3. Register, then Generate a new client secret and copy both the Client ID and the secret (the secret is shown once).

  4. Optional but recommended: in the app’s Optional features, turn on Expire user access tokens. Tokens then last eight hours and ReviewStage refreshes them itself.

  5. In .env:

    Terminal window
    GH_CLIENT_ID=<client id>
    GH_CLIENT_SECRET=<client secret>
    GH_OAUTH_SCOPES=repo

    repo is the smallest classic scope that can comment on and approve a pull request in a private repository; OAuth Apps cannot request fine-grained permissions (see Security). Public repositories only? public_repo is enough.

  6. Restart (docker compose up -d again, or systemctl restart reviewstage). The login page now shows Continue with GitHub.

A GitHub App works with the same two .env keys (leave GH_OAUTH_SCOPES empty) and gives narrower, per-repository permissions in exchange for an org owner installing it. It is the roadmap default; see Configuration.

The dashboard is a progressive web app. Once it is reachable over HTTPS (or on localhost), install it from the browser and it opens standalone, in the app’s own colours, from your home screen or dock:

  • iPhone / iPad (Safari): Share → Add to Home Screen.
  • Android (Chrome): the Install app prompt, or ⋮ → Add to Home screen.
  • Desktop (Chrome / Edge): the install icon in the address bar.

It is the same app as the tab; the sign-in and Claude connection carry over. Offline, it shows a “needs a connection to your server” page rather than stale data, because everything lives on your server. Native store apps and push notifications are the next phase; see Mobile.

Use this when you cannot run Docker, or want the dashboard behind your own web server. The pieces are a Python 3 server, a few bash scripts, the Claude Code CLI and the GitHub CLI. There is no build step for the backend; the dashboard UI is a prebuilt bundle.

Summary of what bin/bootstrap.sh does, so you know what to expect:

  1. Installs gh and claude if missing.
  2. Copies the scripts to ~/.reviewstage/bin/ and creates ~/.reviewstage/.env (chmod 600), adding only missing keys so re-running never overwrites your values.
  3. Makes a blobless base clone of REPO for worktrees.
  4. Installs the built-in review skill and seeds the editable team default.
  5. Writes and starts a systemd unit, reviewstage.service, that binds the dashboard to 127.0.0.1:8899.
  6. Installs the cron entry for the poller (every 3 minutes).

Then:

Terminal window
sudo -iu <service-user> # the user the unit runs as
claude # sign Claude Code in as that user, interactively
~/reviewstage/bin/bootstrap.sh # prompts for REPO and your GitHub login
# paste GITHUB_PAT (and SLACK_WEBHOOK if wanted) into ~/.reviewstage/.env
~/reviewstage/bin/bootstrap.sh # re-run to finish; safe at any point
curl -s localhost:8899/health # -> ok

Put a TLS-terminating reverse proxy in front (Caddy is two lines) and read Security before turning DRY_RUN off. The server reads .env once at startup: restart it after any edit.

MIT licensed · Built on Claude Code