Local pre-commit review briefs from your git diff — scrutinize changes, stage, and commit with confidence
Project description
Scrutin — User guide
Scrutin helps you review local git changes before you commit. It reads your working tree, highlights risky areas, lists files worth extra attention, and lets you view diffs, stage/unstage, and commit from one place — in the browser or in the VS Code / Cursor sidebar.
Everything runs on your machine — no cloud service required.
Table of contents
- What you need
- Install Scrutin (includes Docker)
- Choose browser or IDE
- First run
- Browser guide (step by step)
- VS Code / Cursor extension guide
- Compare modes
- Review, stage, and commit
- Optional: LLM polish
- Optional: ignore noisy paths
- CLI reference
- Troubleshooting
What you need
| Requirement | Notes |
|---|---|
| Python 3.11+ or Docker | Server runs via pip install or a container (see Docker) |
| git | On your PATH (host); git is also inside the Docker image |
| A git repository | Existing repo or git init — first commit is optional for uncommitted review |
| Browser (for web UI) | Any modern browser |
| VS Code or Cursor (for extension) | Plus the Scrutin extension (see below) |
Optional:
- LLM API key — richer summary and self-checks (otherwise Sharpen heuristics run locally)
ghCLI — PR title/body when reviewing a branch with an open PR
Install Scrutin
From PyPI (recommended)
pip install scrutin
scrutin --help
From Test PyPI (beta only)
Test PyPI is unreliable for installs with dependencies (a fake fastapi==1.0 is treated as newer than real 0.136.x). Use production PyPI for deps, then --no-deps for scrutin — see docs/PYPI.md or:
bash scripts/install-from-testpypi.sh 0.1.0
From source (contributors)
git clone https://github.com/scrutin/scrutin.git
cd scrutin
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
scrutin --help
Verify git is available:
git --version
Docker (no Python on host)
For Windows, Java, or other teams without Python: pull the image from Docker Hub and use the browser UI. No Python, no git clone of Scrutin, no local docker build.
Requirements: Docker Desktop (or Docker Engine) + your project folder (with .git) on disk.
From your project’s repository root (the app you are committing to — not the Scrutin source tree):
docker compose pull
docker compose up
# Windows PowerShell — run inside your Java/project repo
docker compose pull
docker compose up
Open http://127.0.0.1:8787 and set Repository to:
/workspace
Use the host path only when setting SCRUTIN_REPO for the mount (if needed), not in the UI field.
One-liner without Compose:
docker pull scrutin/scrutin:latest
docker run --rm -p 8787:8787 -v "$(pwd):/workspace:rw" scrutin/scrutin:latest
More detail (LLM .env, git identity for commits, extension + Docker): docs/DOCKER.md
Choose browser or IDE
Both interfaces use the same backend (scrutin serve on port 8787 by default). Pick one or use both.
| Browser | VS Code / Cursor extension | |
|---|---|---|
| Best for | Full-screen review, second monitor; Docker users | Review beside your code |
| How to start | scrutin serve or docker compose pull && docker compose up |
Open Scrutin activity bar → Brief (server auto-starts) |
| URL / location | http://127.0.0.1:8787 | Sidebar webview |
| Commit panel | Left sidebar | Bottom of sidebar |
| Open file in editor | Copy path / use your editor | Open file in diff modal |
You only need one running server. If port 8787 is busy, stop the old process or change the port (see Troubleshooting).
First run
-
Open a terminal and go to your project:
cd ~/your-project
-
Make sure you have something to review (edit files, or stage them):
git status -
Start the UI (browser) or open the extension (IDE) — see the sections below.
-
Click Refresh brief (browser) or ↻ refresh (extension) after you change files.
Browser guide (step by step)
1. Start the server
From your project directory (or any path; you can set the repo in the UI):
cd ~/your-project
scrutin serve
Your browser should open http://127.0.0.1:8787. To start without opening a tab:
scrutin serve --no-open
Then open that URL manually. To pin a specific repo:
scrutin serve --repo ~/your-project
Alternative — brief in terminal, then open UI:
scrutin brief --open
2. Set the repository
In the left Workspace panel:
- Repository — path to your git root (e.g.
/Users/you/your-project). - Click ◎ Detect repo if the field is empty or wrong. Scrutin runs
git rev-parsefrom the path you provide. - Check the hint under Compare — it shows how many paths changed (staged / unstaged).
3. Choose what to compare
Use the Compare dropdown:
| Mode | What it shows |
|---|---|
| working | Staged + unstaged vs HEAD (default for pre-commit) |
| staged | Index vs HEAD only |
| unstaged | Working tree vs index only |
| branch | base…head (e.g. main…HEAD) — pick Base and Head when selected |
After changing mode, click ↻ Refresh brief.
4. Read the dashboard
The main panel is your pre-commit brief:
- KPIs — files changed, review progress, lines added/removed, brief engine (Sharpen vs LLM).
- Diff activity / File mix — size and risk breakdown.
- Risk overview — categories (secrets, CI/CD, migrations, etc.).
- Summary / Why — what changed and why it matters.
- Risk areas — tags for the kinds of risk detected.
5. Review flagged files (“Files to scrutinize”)
This section lists paths that deserve extra care (risky or largest changes):
- Click View diff — side-by-side Original / Modified panes.
- In the diff modal:
- Stage / Unstage — update the git index for that file.
- Mark reviewed — track that you have looked at this file (required before commit is enabled).
- On the card you can also Stage / Unstage without opening the diff.
The File review bar shows progress (e.g. 5 / 12 reviewed). The header pill may show “N file(s) left” until all flagged files are marked reviewed.
6. Handle all other changes (“Other changed files”)
If your diff has more paths than the scrutinize list (common on large changesets), scroll to Other changed files:
- Same actions: View diff, Stage, Unstage.
- These files do not require “Mark reviewed” for the commit button — only Files to scrutinize do.
7. Optional: configure LLM
Expand LLM (optional) in the sidebar:
- Choose Provider (or none — Sharpen heuristics only).
- Set Model and API key (leave key blank to keep an existing one).
- Click Save LLM settings — writes to
.envin the repo (path shown under the form). - Click ↻ Refresh brief to regenerate with the LLM.
See Optional: LLM polish.
8. Stage changes
Before committing, git needs staged content:
- Per file: Stage on a card or in the diff modal.
- Bulk: Stage all in the Commit panel (stages every changed file in the current compare scope that is not fully staged).
- Terminal (equivalent):
git add -Aorgit add path/to/file
Unstage all removes paths from the index (not from disk).
The commit hint updates, e.g. “Stage 9 file(s) below (or Stage all) before committing.”
9. Commit
In the Commit panel (sidebar):
- Complete Mark reviewed on all Files to scrutinize (if any).
- Ensure something is staged (
git diff --cachednon-empty). - Write a Commit message, or click Suggest message (uses your diff + brief; no filename spam).
- Click Commit staged — runs
git commitin that repository.
After a successful commit, the brief refreshes from the new tree state.
10. Self-checks and rollback
- Ask yourself — 5 self-checks — prompts before you push (from heuristics or LLM).
- Rollback — quick reference for
git restore,git revert, etc.
VS Code / Cursor extension guide
1. Install the extension
Marketplace (when published): search Scrutin in Extensions.
From source / VSIX:
cd ~/scrutin/extension
npm install
npm run compile
npx vsce package
In VS Code/Cursor: Extensions → … → Install from VSIX → choose the .vsix file.
You still need the Python package:
pip install scrutin
2. Open your project
Open the git repository root as the workspace folder (the folder that contains .git).
3. Open the brief
- Click the Scrutin icon in the activity bar (left).
- Open the Brief view.
The extension starts scrutin serve on 127.0.0.1:8787 when needed (scrutin.server.autoStart, default true).
Command Palette (Cmd+Shift+P / Ctrl+Shift+P):
Scrutin: Open BriefScrutin: Refresh BriefScrutin: Detect RepositoryScrutin: Start Server/Stop ServerScrutin: Open in Browser— same UI asscrutin servein your browser
4. Compare and refresh
At the top of the brief:
- Compare — same modes as the browser (working / staged / unstaged / branch).
- For branch, set Base and Head.
- Click ↻ refresh after edits.
The status line shows idle, building…, N file(s) left, or errors.
5. Review files
Same workflow as the browser:
- Files to scrutinize — View diff, Stage / Unstage, Mark reviewed.
- Other changed files — diff and stage/unstage without the review gate.
Diff modal:
- Original / Modified column headers (section labels).
- Stage badge: Unstaged, Staged, or Staged + unstaged.
- Open file — opens the path in the editor.
- Mark reviewed — only for scrutinize-list files.
6. LLM settings
Expand LLM (optional) → set provider, model, key → Save LLM settings → refresh.
7. Commit (extension)
Scroll to the Commit section at the bottom of the sidebar:
- Mark all scrutinize files reviewed.
- Stage all or stage per file.
- Suggest message → edit if needed.
- Commit staged.
8. If the server does not start
-
View → Output → choose Scrutin — read spawn errors.
-
Test manually:
cd ~/your-project scrutin serve --no-open --port 8787 curl http://127.0.0.1:8787/health
-
In settings, point at your venv Python:
{ "scrutin.server.command": "/path/to/scrutin/.venv/bin/python", "scrutin.server.args": ["-m", "scrutin.cli"] }
-
Developer: Reload Window.
More detail: extension/README.md.
Compare modes
| Mode | Git equivalent | Typical use |
|---|---|---|
| working | git diff HEAD (+ untracked where supported) |
“What am I about to commit?” |
| staged | git diff --cached |
“What’s already in the index?” |
| unstaged | git diff |
“What’s changed but not staged?” |
| branch | git diff base...head |
Feature branch vs main |
Switch mode → Refresh brief (browser) or refresh (extension).
Review, stage, and commit
What “scrutinize” means
Scrutin does not hide other files. It prioritizes a subset:
- Risky paths (secrets, config, migrations, CI/CD, large API surface, etc.).
- If nothing is risky, the largest edits in the current scope.
Everything else appears under Other changed files.
Review gate
Commit staged stays disabled until:
- Every file in Files to scrutinize is Mark reviewed (or the list is empty), and
- Git has staged changes (
git diff --cachednot empty).
What gets committed
The button runs git commit with your message. It commits whatever is staged in that repo — including files you staged from “Other changed files” or from the terminal. Scrutin does not commit unstaged work by itself.
Suggested workflow:
Edit files → Refresh brief → Review scrutinize list → Stage (per file or Stage all)
→ Suggest message → Commit staged
Optional: LLM polish
Without a key, Scrutin uses Sharpen heuristics (local rules, no API calls).
With a key, summary, why, and self-checks can be enhanced. Configure via UI or .env:
| Provider | Environment variables |
|---|---|
| OpenAI | OPENAI_API_KEY, OPENAI_MODEL |
| Anthropic | ANTHROPIC_API_KEY, ANTHROPIC_MODEL |
| Google Gemini | GOOGLE_API_KEY, GOOGLE_MODEL |
| Groq | GROQ_API_KEY, GROQ_MODEL |
| Mistral | MISTRAL_API_KEY, MISTRAL_MODEL |
Active provider: SCRUTIN_LLM_PROVIDER=openai (or none).
Env file locations (first match wins):
SCRUTIN_ENVif set.envin the repo~/.scrutin/.env(legacy:~/.reviewpack/.envstill read)
Copy .env.example to .env as a starting point.
Privacy: LLM calls send metadata (paths, stats, risk tags) — not full diff bodies. Review your provider’s policy if that matters.
Optional: ignore noisy paths
Create .scrutinignore in the repo root (same idea as .gitignore, one pattern per line):
.venv/
node_modules/
dist/
*.egg-info/
Legacy name .reviewpackignore is still honored if .scrutinignore is missing.
Built-in ignores include .venv/, __pycache__/, node_modules/, and common build artifacts.
CLI reference
Terminal-only brief (no UI):
cd ~/your-project
scrutin brief
scrutin brief --json
Modes:
scrutin brief --mode working
scrutin brief --mode staged
scrutin brief --mode unstaged
scrutin brief --mode branch --base main --head HEAD
Server:
scrutin serve
scrutin serve --port 8788 --no-open
scrutin serve --repo /path/to/repo
From a saved diff file:
scrutin brief --diff changes.patch --repo .
Troubleshooting
| Problem | What to do |
|---|---|
scrutin: command not found |
pip install scrutin or activate the venv where you installed it |
Not inside a git repository |
cd to the repo root, or run git init |
No diff to analyze |
Save edits, git add some files, or switch compare mode |
| UI empty / wrong repo | Set Repository path → Detect repo → Refresh brief; or scrutin serve --repo /full/path |
| Port 8787 in use | Stop old server (Ctrl+C), or lsof -i :8787 and kill; extension: change scrutin.server.port |
| Extension “server not ready” | Output panel Scrutin; run scrutin serve --no-open manually; set scrutin.server.command + args |
| Brief only in terminal | Use scrutin serve or scrutin brief --open |
| LLM panel missing / save fails | Upgrade package: pip install -e . or latest scrutin; restart serve |
.env.example stage error |
Update Scrutin — dotfile paths must not be stripped |
| Commit button disabled | Mark all scrutinize files reviewed and stage at least one file |
Docker: pull access denied / not found |
Publish image or set SCRUTIN_IMAGE=youruser/scrutin:latest — docs/DOCKER.md |
| Docker: wrong / empty repo | Set Repository to /workspace, not C:\... or /Users/... |
| Docker: commit fails | Set git user.name / user.email in container — docs/DOCKER.md |
| Old “reviewpack” naming in text | Harmless in cached briefs — Refresh brief after upgrade |
Quick command cheat sheet
# Install (Python)
pip install scrutin
# Browser workflow (Python)
cd ~/your-project
scrutin serve
# → http://127.0.0.1:8787 → Detect repo → Refresh brief → review → Stage all → Commit staged
# Browser workflow (Docker — no Python on host)
docker compose pull && docker compose up
# → http://127.0.0.1:8787 → Repository: /workspace
# Extension workflow
# Install extension + pip install scrutin → Open Brief → refresh → same review/commit flow
# Check server
curl http://127.0.0.1:8787/health
# Terminal brief only
scrutin brief --json
License
MIT — LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file scrutin-0.1.0.tar.gz.
File metadata
- Download URL: scrutin-0.1.0.tar.gz
- Upload date:
- Size: 60.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ffcf358059a7491b9b633df66318dd6988558add2017e24841533c276c259073
|
|
| MD5 |
de549c6e38dbf910e8abe79dcc609019
|
|
| BLAKE2b-256 |
9ccb314f0e7c7bee2245beef256c1387c0bbf4204599ca83d508651efa1d854e
|
File details
Details for the file scrutin-0.1.0-py3-none-any.whl.
File metadata
- Download URL: scrutin-0.1.0-py3-none-any.whl
- Upload date:
- Size: 55.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cb31ad5d2118425945dc2124493cd10b3f3def9ad178b1d44ae21754cc54da3
|
|
| MD5 |
3eccf1fec7e3a80b8f0d0aef7e16a9e8
|
|
| BLAKE2b-256 |
f18225642a512c71164e6db3447bde5fe075c977c4f9a0fed3a3d24bdd0ee8a2
|