Metadata-Version: 2.4
Name: scrutin
Version: 0.1.0
Summary: Local pre-commit review briefs from your git diff — scrutinize changes, stage, and commit with confidence
Author: Scrutin contributors
License-Expression: MIT
Project-URL: Documentation, https://pypi.org/project/scrutin/
Project-URL: Source Code, https://github.com/scrutin/scrutin
Keywords: git,code-review,pull-request,pre-commit,developer-tools,diff
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.115.0
Requires-Dist: uvicorn[standard]>=0.32.0
Requires-Dist: pydantic>=2.9.0
Requires-Dist: pydantic-settings>=2.6.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: python-dotenv>=1.0.0
Dynamic: license-file

# 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](#what-you-need)
2. [Install Scrutin](#install-scrutin) (includes [Docker](#docker-no-python-on-host))
3. [Choose browser or IDE](#choose-browser-or-ide)
4. [First run](#first-run)
5. [Browser guide (step by step)](#browser-guide-step-by-step)
6. [VS Code / Cursor extension guide](#vs-code--cursor-extension-guide)
7. [Compare modes](#compare-modes)
8. [Review, stage, and commit](#review-stage-and-commit)
9. [Optional: LLM polish](#optional-llm-polish)
10. [Optional: ignore noisy paths](#optional-ignore-noisy-paths)
11. [CLI reference](#cli-reference)
12. [Troubleshooting](#troubleshooting)

---

## What you need

| Requirement | Notes |
|-------------|--------|
| **Python 3.11+** *or* **Docker** | Server runs via `pip install` or a container (see [Docker](#docker-no-python-on-host)) |
| **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)
- **`gh` CLI** — PR title/body when reviewing a branch with an open PR

---

## Install Scrutin

### From PyPI (recommended)

```bash
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](PYPI.md#installing-from-test-pypi-maintainers--beta-testers) or:

```bash
bash scripts/install-from-testpypi.sh 0.1.0
```

### From source (contributors)

```bash
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:

```bash
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](https://www.docker.com/products/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):

```bash
docker compose pull
docker compose up
```

```powershell
# 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:

```text
/workspace
```

Use the host path only when setting `SCRUTIN_REPO` for the mount (if needed), not in the UI field.

One-liner without Compose:

```bash
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](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](#troubleshooting)).

---

## First run

1. Open a terminal and go to your project:

   ```bash
   cd ~/your-project
   ```

2. Make sure you have **something to review** (edit files, or stage them):

   ```bash
   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):

```bash
cd ~/your-project
scrutin serve
```

Your browser should open **http://127.0.0.1:8787**. To start without opening a tab:

```bash
scrutin serve --no-open
```

Then open that URL manually. To pin a specific repo:

```bash
scrutin serve --repo ~/your-project
```

Alternative — brief in terminal, then open UI:

```bash
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](#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:**

```bash
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:

```bash
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 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:

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:

   ```bash
   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:

   ```json
   {
     "scrutin.server.command": "/path/to/scrutin/.venv/bin/python",
     "scrutin.server.args": ["-m", "scrutin.cli"]
   }
   ```

4. **Developer: Reload Window**.

More detail: [extension/README.md](../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:

```text
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](../.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):

```gitignore
.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):

```bash
cd ~/your-project
scrutin brief
scrutin brief --json
```

Modes:

```bash
scrutin brief --mode working
scrutin brief --mode staged
scrutin brief --mode unstaged
scrutin brief --mode branch --base main --head HEAD
```

Server:

```bash
scrutin serve
scrutin serve --port 8788 --no-open
scrutin serve --repo /path/to/repo
```

From a saved diff file:

```bash
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](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](docs/DOCKER.md) |
| Old “reviewpack” naming in text | Harmless in cached briefs — **Refresh brief** after upgrade |

---

## Quick command cheat sheet

```bash
# 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](LICENSE)
