Add your description here
Project description
Revyu
AI-powered local code reviews for your feature branches. Revyu is a CLI tool that analyzes your git branch diff and provides structured, actionable feedback using a locally hosted LLM via Ollama — no code ever leaves your machine.
Features
- Local-first — All analysis happens on your machine using Ollama. Your code stays private.
- Auto-detection — Automatically detects the base branch (
main,master,develop, etc.) so you can just runrevyuand go. - Structured feedback — Issues are categorized by severity (CRITICAL, HIGH, MEDIUM, LOW, NIT) across security, correctness, code quality, and performance.
- Rich terminal output — Feedback is rendered as styled Markdown panels in your terminal.
- Configurable — Control the model, diff size limits, commit count, and more via environment variables or a
.envfile.
Tech Stack
| Component | Technology |
|---|---|
| Language | Python 3.13+ |
| Package manager | uv |
| Build backend | Hatchling |
| CLI framework | Typer |
| Terminal rendering | Rich |
| HTTP client | httpx |
| Configuration | Pydantic Settings |
| LLM backend | Ollama |
| Containerization | Docker + Docker Compose |
Prerequisites
- Python 3.13+
- Git
- Ollama — running locally or via Docker (the included
docker-compose.ymlhandles this for you)
Install from PyPI
# With uv (recommended)
uv tool install revyu
# Or with pip
pip install revyu
Then run it from any git repository on a feature branch:
revyu
Usage with Docker (no Python required)
If you don't have Python installed, you can run Revyu entirely via Docker. There are two approaches depending on whether you already have Ollama running.
Option A: You already have Ollama running
If Ollama is running on your host machine (e.g. via brew install ollama or the Ollama desktop app), you can run Revyu directly from your project's root directory:
docker run --rm \
-v "$(pwd):/repo:ro" \
-e REVYU_OLLAMA_URL=http://host.docker.internal:11434 \
ghcr.io/<your-org>/revyu:latest
host.docker.internal allows the container to reach Ollama on your host machine. Pass any CLI flags after the image name:
docker run --rm \
-v "$(pwd):/repo:ro" \
-e REVYU_OLLAMA_URL=http://host.docker.internal:11434 \
ghcr.io/<your-org>/revyu:latest \
--base-branch develop --model codellama
To simplify repeated use, add a shell alias to your profile (~/.bashrc, ~/.zshrc, etc.):
alias revyu='docker run --rm -v "$(pwd):/repo:ro" -e REVYU_OLLAMA_URL=http://host.docker.internal:11434 ghcr.io/<your-org>/revyu:latest'
Then just run:
cd ~/projects/myapp
revyu
revyu --base-branch develop
revyu --model codellama --no-diff
Option B: Run everything with Docker Compose
If you don't have Ollama installed at all, the included docker-compose.yml runs both Ollama and Revyu together:
# Clone revyu (only needed once, for the docker-compose.yml)
git clone https://github.com/<your-org>/revyu.git ~/revyu
# Start the Ollama service
docker compose -f ~/revyu/docker-compose.yml up -d
# Run revyu against your project
GEN_FEEDBACK_REPO_PATH=/path/to/your/repo \
docker compose -f ~/revyu/docker-compose.yml run --rm revyu
The revyu service is under the tools profile, so it only runs on demand via docker compose run — it won't start with a bare docker compose up.
You can also override configuration:
REVYU_OLLAMA_MODEL=codellama GEN_FEEDBACK_REPO_PATH=~/projects/myapp \
docker compose -f ~/revyu/docker-compose.yml run --rm revyu --base-branch develop
CLI Usage
revyu [OPTIONS]
| Option | Short | Description |
|---|---|---|
--base-branch |
-b |
Branch to diff against. Auto-detected if omitted. |
--model |
-m |
Ollama model to use (default: llama3.2). |
--no-diff |
Skip the full diff — use only commits and file list. | |
--repo |
Path to the git repo (defaults to current directory). | |
--help |
Show help and exit. |
Examples
# Review the current branch (auto-detects base branch)
revyu
# Review against a specific base branch
revyu --base-branch develop
# Use a different model
revyu --model codellama
# Review a repo in another directory
revyu --repo ~/projects/myapp
# Skip the full diff for very large branches
revyu --no-diff
Configuration
Revyu is configured via environment variables (prefixed with REVYU_) or a .env file in the working directory.
| Variable | Default | Description |
|---|---|---|
REVYU_OLLAMA_URL |
http://localhost:11434 |
Ollama server URL. |
REVYU_OLLAMA_MODEL |
llama3.2 |
Default Ollama model. |
REVYU_OLLAMA_TIMEOUT |
120.0 |
Request timeout in seconds. |
REVYU_MAX_COMMITS |
20 |
Maximum number of commits to include in the review. |
REVYU_MAX_DIFF_CHARS |
8000 |
Maximum diff size in characters. Fails if exceeded. |
Example .env file:
REVYU_OLLAMA_URL=http://localhost:11434
REVYU_OLLAMA_MODEL=codellama
REVYU_OLLAMA_TIMEOUT=180
REVYU_MAX_COMMITS=30
REVYU_MAX_DIFF_CHARS=12000
Development Setup
Clone and install
git clone https://github.com/<your-org>/revyu.git
cd revyu
# Install dependencies (creates a virtual environment automatically)
uv sync
# Run revyu locally
uv run revyu
Running tests
uv run pytest
Project structure
src/revyu/
cli.py # CLI entrypoint (Typer app)
git.py # Git operations — branch detection, diff collection
llm.py # Ollama integration — prompt building, API calls
settings.py # Configuration via Pydantic Settings
Contributing
- Create a feature branch from
main. - Make your changes.
- Run tests:
uv run pytest - Open a pull request.
Publishing to PyPI
Manual publish
# Build source and wheel distributions
uv build
# Publish (requires a PyPI API token)
uv publish --token $PYPI_TOKEN
Automated publish with GitHub Actions
Create .github/workflows/publish.yml:
name: Publish to PyPI
on:
push:
tags:
- "v*"
jobs:
publish:
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv python install 3.13
- run: uv build
- run: uv publish
To use this workflow:
- Create a
pypienvironment in your GitHub repo settings (Settings > Environments). - Add a trusted publisher to your PyPI project matching the repository and workflow name.
- Create and push a release tag:
Typical workflow:
Tags should be created on the main branch after merging your feature branch. Here's the recommended process:
# 1. Merge your feature branch via pull request on GitHub
# 2. Switch to main and pull the latest changes
git checkout main
git pull origin main
# 3. Bump the version in pyproject.toml (e.g., from 0.0.9 to 0.1.0)
# Edit pyproject.toml manually or use a tool
# 4. Commit the version bump
git add pyproject.toml
git commit -m "Bump version to 0.1.0"
git push origin main
# 5. Create and push the tag (use the same version as in pyproject.toml)
git tag v0.1.0
git push origin v0.1.0
The tag push triggers the GitHub Actions workflow, which builds and publishes to PyPI automatically.
Publishing Docker to GitHub Container Registry
Manual publish
# Build the image
docker build -t revyu .
# Tag for GHCR
docker tag revyu ghcr.io/<your-org>/revyu:latest
docker tag revyu ghcr.io/<your-org>/revyu:0.1.0
# Authenticate with GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u <your-username> --password-stdin
# Push
docker push ghcr.io/<your-org>/revyu:latest
docker push ghcr.io/<your-org>/revyu:0.1.0
Automated publish with GitHub Actions
Create .github/workflows/docker.yml:
name: Publish Docker to GHCR
on:
push:
tags:
- "v*"
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
This workflow triggers on version tags, builds the Docker image, and pushes it to ghcr.io/<your-org>/revyu with semantic version tags.
License
TBD
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 revyu-0.1.0.tar.gz.
File metadata
- Download URL: revyu-0.1.0.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b4b045b030984cf8aa490cf1000186d007777d4e4bb9e561779622eb58fcbe1
|
|
| MD5 |
70e2b0ed7747039a2d90e19bf459aa94
|
|
| BLAKE2b-256 |
94b6904d923cf025d956f1bee0592afe5ec6f902a29ee0f4b0000ff5846e73a9
|
File details
Details for the file revyu-0.1.0-py3-none-any.whl.
File metadata
- Download URL: revyu-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c002ed7c78378989a6224afd39cc3a5943c66df9a24aafe3372a8c5bc27ef34
|
|
| MD5 |
e40be45195c90f9a3de7557cdff75426
|
|
| BLAKE2b-256 |
c33e69fc3b217425d30f0c2fb86ea8e52775ec36b9f3638746f4d607d979de74
|