Skip to main content

Independent AI peer review of git diffs for Claude Code and other coding agents

Project description

fresh-eyes

Independent AI peer review of git diffs, designed for use alongside Claude Code (or any coding agent). Sends your latest changes to a different model so you get a second opinion with different blind spots from the one that wrote the code.

Install

uv tool install fresh-eyes

Or from a local checkout:

uv tool install --from . fresh-eyes

This installs two equivalent commands: fresh-eyes (canonical) and fe (typeable alias).

Setup

fresh-eyes calls three independent reviewers (Gemini, Mistral, DeepSeek). You need at least one API key; the tool runs whichever reviewers have a key it can resolve.

Reviewer Sign up Cost
Gemini https://aistudio.google.com/apikey free tier
Mistral https://console.mistral.ai free experiment tier / paid
DeepSeek https://platform.deepseek.com paid

Storing keys

Store each key once in ~/.config/fresh-eyes/secrets.toml, written at mode 600 so it isn't group/world-readable:

fresh-eyes --set-key gemini      # prompts for the key (input hidden), writes secrets.toml
fresh-eyes --set-key mistral

The file looks like this. You can hand-edit it instead — but then you must chmod 600 it yourself, or fresh-eyes refuses to read it:

[keys]
gemini  = "AIza..."
mistral = "..."

Environment variables still work and take precedence over the file — handy for CI or one-off experiments:

GEMINI_API_KEY=... fresh-eyes        # env wins over secrets.toml for this run

Migrating from ~/.bashrc? Run fresh-eyes --set-key <reviewer> for each key, then delete the export … lines from your shell profile.

Choosing models and reviewers

Create ~/.config/fresh-eyes/config.toml to override per reviewer — useful for swapping a noisy model or benching one entirely, without touching your keys:

[reviewers.mistral]
enabled = false                  # skip Mistral in the default run
model   = "mistral-large-latest" # used if/when it runs (e.g. via --only mistral)

[reviewers.gemini]
model = "gemini-2.5-flash"
  • A reviewer runs in the default (no-flag) invocation when it's enabled (default true) and a key is resolvable.
  • --only <gemini|mistral|deepseek> runs a single reviewer, overriding enabled (it still needs a key).
  • Model precedence: FRESH_EYES_<NAME>_MODEL env var > config.toml > the built-in default.

Activation

fresh-eyes is opt-in per repo, so it doesn't fire in every git repo you cd into. Enable it once per repo:

fresh-eyes --init      # enables fresh-eyes in this repo (writes .git/fresh_eyes_enabled)
fresh-eyes --disable   # disables it again

Running any other command in a non-activated repo prints a friendly message and exits without making API calls.

Usage

From inside an activated git repository:

fresh-eyes                      # review the last commit (HEAD~1..HEAD)
fresh-eyes --since HEAD~3       # review the last 3 commits
fresh-eyes --since abc1234      # review since a specific commit
fresh-eyes --since main         # review everything on this branch since it diverged from main
fresh-eyes --full               # shortcut: diff entire branch against the default branch
fresh-eyes --all                # one-time baseline: review the entire current codebase
fresh-eyes --staged             # review staged-but-uncommitted changes

fe is the short alias — fe --since HEAD~3 works identically.

--since accepts anything git rev-parse resolves: SHAs, branch names, tags, HEAD~N. This is how Claude Code can scope a review around the actual unit of work rather than a fixed window.

Adding intent and trimming context

By default the reviewer sees the diff hunks and the full post-change content of every changed file, so it can see callers, types, and surrounding code without hallucinating about what's outside the hunk. What it does not know is what the change is supposed to do — pass --context for that.

fresh-eyes --context "Adds rate limiting to the /login endpoint. Should reject >5 req/min per IP."
fresh-eyes --context-file SPEC.md          # read intent from a file (relative to CWD)
fresh-eyes --diff-only                     # send only diff hunks, skip full files (trim tokens)
fresh-eyes --since HEAD~3 --context "Refactors auth to use the new token store"

Use --context to tell the reviewer the author's stated goal — the prompt asks it to use this for grading "does the diff do what the author claims?" while still surfacing out-of-scope issues. Use --diff-only to drop the full-file attachments when you know the diff is self-contained or the changed files are very large (cuts token cost on paid providers).

Claude Code integration

Copy the slash command files from this repo into your Claude Code commands directory:

cp commands/fresh-eyes.md commands/fe.md ~/.claude/commands/

You can now invoke /fresh-eyes or /fe in a Claude Code session. The command tells Claude to run the CLI (forwarding flags like --since HEAD~3 when the request implies a specific baseline), read its output, synthesize the findings against the current task context, and raise genuine concerns before continuing.

How it works

  • Stateless: every invocation is explicit about scope. Default is the last commit; pass --since <commit> for anything else. No review-history markers, no hidden state about previous runs.
  • Independent reviewers in parallel: each enabled reviewer is called concurrently and its output is emitted verbatim under a ## <Model> header. The tool does not synthesize — that's left to the calling agent (Claude Code), which weighs the findings against the live task context. One reviewer failing (bad key, API error) is isolated to its own section; the others still complete.
  • Noise filtering: lockfiles, minified assets, and dist//build/ are excluded from the diff so they don't burn tokens.
  • Size guard: bails out with a message (exit 0) if the assembled prompt (diff + optional intent + optional full files) exceeds ~100k estimated tokens.

Exit codes

Code Meaning
0 Review ran successfully, OR diff was too large to send (the tool reports; it does not gate)
1 --since commit not found, or other git error
2 No resolvable API key for the selected reviewer(s), or secrets.toml has insecure (non-600) permissions

License

MIT

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

fresh_eyes-0.6.0.tar.gz (53.1 kB view details)

Uploaded Source

Built Distribution

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

fresh_eyes-0.6.0-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file fresh_eyes-0.6.0.tar.gz.

File metadata

  • Download URL: fresh_eyes-0.6.0.tar.gz
  • Upload date:
  • Size: 53.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fresh_eyes-0.6.0.tar.gz
Algorithm Hash digest
SHA256 763931afd17e9b4658f6c38bb91b22634c12cad3affb2135f56d0e0f6c14e7bb
MD5 79066a59db80d101bd74e98269d0c8db
BLAKE2b-256 e39d30816add4d01e4f5dbff1bd05a498adf8b6157d481b596e3dc594a84edbf

See more details on using hashes here.

Provenance

The following attestation bundles were made for fresh_eyes-0.6.0.tar.gz:

Publisher: release.yml on lucasgerads/fresh-eyes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fresh_eyes-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: fresh_eyes-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 14.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fresh_eyes-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6e46b934ad9888964c7d4f46c4bea8b35b66c1cae974e5d1077d67cef2860661
MD5 2e3fe74c03f0f06f846bf3ffa0fdf3fb
BLAKE2b-256 71343ccd95c30e9e7057f01ffd212c69495bd2b4c7ed6d439a3a3342759485dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fresh_eyes-0.6.0-py3-none-any.whl:

Publisher: release.yml on lucasgerads/fresh-eyes

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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