Skip to main content

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

  1. What you need
  2. Install Scrutin (includes Docker)
  3. Choose browser or IDE
  4. First run
  5. Browser guide (step by step)
  6. VS Code / Cursor extension guide
  7. Compare modes
  8. Review, stage, and commit
  9. Optional: LLM polish
  10. Optional: ignore noisy paths
  11. CLI reference
  12. 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 initfirst 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)
  • gh CLI — 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

  1. Open a terminal and go to your project:

    cd ~/your-project
    
  2. Make sure you have something to review (edit files, or stage them):

    git status
    
  3. Start the UI (browser) or open the extension (IDE) — see the sections below.

  4. 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:

  1. Repository — path to your git root (e.g. /Users/you/your-project).
  2. Click ◎ Detect repo if the field is empty or wrong. Scrutin runs git rev-parse from the path you provide.
  3. 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):

  1. Click View diff — side-by-side Original / Modified panes.
  2. 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).
  3. 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:

  1. Choose Provider (or none — Sharpen heuristics only).
  2. Set Model and API key (leave key blank to keep an existing one).
  3. Click Save LLM settings — writes to .env in the repo (path shown under the form).
  4. 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 -A or git 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):

  1. Complete Mark reviewed on all Files to scrutinize (if any).
  2. Ensure something is staged (git diff --cached non-empty).
  3. Write a Commit message, or click Suggest message (uses your diff + brief; no filename spam).
  4. Click Commit staged — runs git commit in 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

  1. Click the Scrutin icon in the activity bar (left).
  2. 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 Brief
  • Scrutin: Refresh Brief
  • Scrutin: Detect Repository
  • Scrutin: Start Server / Stop Server
  • Scrutin: Open in Browser — same UI as scrutin serve in your browser

4. Compare and refresh

At the top of the brief:

  1. Compare — same modes as the browser (working / staged / unstaged / branch).
  2. For branch, set Base and Head.
  3. 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 scrutinizeView 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 settingsrefresh.

7. Commit (extension)

Scroll to the Commit section at the bottom of the sidebar:

  1. Mark all scrutinize files reviewed.
  2. Stage all or stage per file.
  3. Suggest message → edit if needed.
  4. Commit staged.

8. If the server does not start

  1. View → Output → choose Scrutin — read spawn errors.

  2. Test manually:

    cd ~/your-project
    scrutin serve --no-open --port 8787
    curl http://127.0.0.1:8787/health
    
  3. In settings, point at your venv Python:

    {
      "scrutin.server.command": "/path/to/scrutin/.venv/bin/python",
      "scrutin.server.args": ["-m", "scrutin.cli"]
    }
    
  4. 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:

  1. Every file in Files to scrutinize is Mark reviewed (or the list is empty), and
  2. Git has staged changes (git diff --cached not 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):

  1. SCRUTIN_ENV if set
  2. .env in the repo
  3. ~/.scrutin/.env (legacy: ~/.reviewpack/.env still 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 repoRefresh 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:latestdocs/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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scrutin-0.1.0.tar.gz (60.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scrutin-0.1.0-py3-none-any.whl (55.6 kB view details)

Uploaded Python 3

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

Hashes for scrutin-0.1.0.tar.gz
Algorithm Hash digest
SHA256 ffcf358059a7491b9b633df66318dd6988558add2017e24841533c276c259073
MD5 de549c6e38dbf910e8abe79dcc609019
BLAKE2b-256 9ccb314f0e7c7bee2245beef256c1387c0bbf4204599ca83d508651efa1d854e

See more details on using hashes here.

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

Hashes for scrutin-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5cb31ad5d2118425945dc2124493cd10b3f3def9ad178b1d44ae21754cc54da3
MD5 3eccf1fec7e3a80b8f0d0aef7e16a9e8
BLAKE2b-256 f18225642a512c71164e6db3447bde5fe075c977c4f9a0fed3a3d24bdd0ee8a2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page