Local code review, powered by your machine. By default Stet talks to Ollama on your computer: no cloud API keys required for that path, and prompts stay on your machine. Uses the hardware you already have—no extra cost.
- Free: Default setup runs locally; no per-seat or per-request fees to the vendor for typical Ollama use.
- Private (default path): With Ollama on localhost, code and prompts are not sent to a remote SaaS.
- Review-only: Focused on review, not auto-fix; you decide what to change.
- Sustainable: Default setup uses your local hardware instead of datacenter APIs.
Measured October 2026 on a Mac Studio (Apple M1 Ultra, 64 GB) with qwen/qwen3.8-27b served by LM Studio:
| Throughput | ~21 tokens/s end to end (stet benchmark --warmup) |
| API cost per review | $0 on a local model (the same tokens cost ~$0.10–$0.20 per review at Claude Sonnet 5.5 / Opus 5.5 list prices) |
| Seeded-bug test | 10 of 12 planted bugs caught in all 3 runs, including SQL injection and path traversal |
| Test coverage | 83.9%, enforced in CI (77% project, 72% per file) |
Speed depends on your hardware and model; run stet benchmark to measure yours.
Stet is a Latin word from proofreading meaning "let it stand"—an instruction to keep existing text unchanged. Stet is review-only: it helps you approve or flag code, not rewrite it.
- Git
- Default LLM — Ollama: Install Ollama, run
ollama serve, and pull a model (e.g.ollama pull qwen3-coder:30b). Override the model in.review/config.tomlor withSTET_MODEL(e.g.qwen2.5-coder:32b). - Optional — OpenAI-compatible HTTP API: See OpenAI-compatible API (optional) below; no Ollama install required for that mode.
- Set up your LLM (Ollama by default; see Prerequisites).
- Install stet (see Installation).
- From your repo root:
stet doctorthenstet start.
stet doctor checks Git and reachability of your configured LLM (Ollama or OpenAI-compat base URL). On success it may still print Ollama OK even when provider = "openai"; use exit code 0 and the Model: line as the signal.
A typical review cycle on a branch with new commits:
- Check environment — Run
stet doctorto verify Git and the configured LLM endpoint (optional but recommended once). - Start the review — Run
stet startorstet start HEAD~3to review the last 3 commits; wait for the run to complete. - Inspect findings — Use
stet statusorstet listto see findings and IDs. In the Cursor extension, use the findings panel and “Copy for chat.” - Triage — Run
stet dismiss <id>orstet dismiss <id> <reason>for findings you want to ignore (reasons:false_positive,already_correct,wrong_suggestion,out_of_scope); fix code as needed. For when to use each reason, see Choosing a dismissal reason. - Re-review — Run
stet runto re-review only changed hunks. Findings that the model no longer reports (e.g. because you fixed the code) are automatically dismissed, so the active list shrinks as issues are fixed—no need to manually dismiss each one. - Finish — When done, run
stet finishto persist state and remove the review worktree.
You can also run start, run, and finish from the Cursor extension.
Gating CI or agent scripts: Use stet list --min-severity warning --min-confidence 0.8 to fail a pipeline only on actionable findings—the command prints nothing and exits 0 when nothing meets the threshold, and exits 1 on invalid values. Findings hidden by the thresholds stay active, so stet status still counts them. This repo's spine contract step (scripts/spine-stet-contract-run.sh) gates on exactly this policy; set SPINE_STET_MIN_SEVERITY or SPINE_STET_MIN_CONFIDENCE to override its defaults.
Install Ollama, then start the server and pull the suggested model:
ollama serve
ollama pull qwen3-coder:30b # or qwen2.5-coder:32b for a lighter optionOption 1 — Install script (Mac/Linux, recommended)
The script downloads the binary for your OS and architecture from GitHub Releases, verifies it against the release's checksums.txt, and installs it. If no release binary can be downloaded, it builds from source when run from the repo or when STET_REPO_URL is set.
curl -fsSL https://raw.githubusercontent.com/beettlle/stet/main/install.sh | bashTo install a specific version instead of the latest:
curl -fsSL https://raw.githubusercontent.com/beettlle/stet/main/install.sh | STET_RELEASE_TAG=v1.0.0 bashOption 2 — Windows (PowerShell)
You may need -ExecutionPolicy Bypass for the one-liner. Set $env:STET_RELEASE_TAG = "v1.0.0" first to pin a version.
irm https://raw.githubusercontent.com/beettlle/stet/main/install.ps1 | iexOption 3 — Manual download
Download stet-<os>-<arch> and checksums.txt from the Releases page, check the hash (shasum -a 256 -c checksums.txt --ignore-missing), rename the file to stet, chmod +x it, and move it into a directory in your PATH. On macOS, a binary downloaded through a browser is quarantined by Gatekeeper; clear it with xattr -d com.apple.quarantine stet. (The install script uses curl, which does not set the quarantine flag.)
Option 4 — From source
Clone the repo and run the install script (which will build and install), or build manually:
git clone https://github.com/beettlle/stet.git
cd stet
./install.shOr build manually and copy the binary to a directory in your PATH:
make build
cp bin/stet ~/.local/bin/PATH
The default install directory is ~/.local/bin (Mac/Linux) or %USERPROFILE%\.local\bin (Windows). Ensure it is in your PATH. For example, add to ~/.bashrc or ~/.zshrc: export PATH="$HOME/.local/bin:$PATH".
Stet can use any server that exposes an OpenAI-compatible chat/completions HTTP API (for example LM Studio’s local server, or other gateways). Configure it in .review/config.toml (or your global Stet config) or with environment variables:
| Setting | TOML key | Environment variable | Notes |
|---|---|---|---|
| Provider | provider = "openai" |
STET_PROVIDER=openai |
Default is ollama. |
| Base URL | openai_base_url = "http://127.0.0.1:1234/v1" |
STET_OPENAI_BASE_URL |
Include the /v1 prefix if your server uses it (LM Studio default is often port 1234). |
| Completion cap | max_completion_tokens = 4096 |
STET_MAX_COMPLETION_TOKENS |
Sent as OpenAI max_tokens (how many tokens the model may generate). Default 4096. This is separate from the context window (num_ctx, --context, STET_NUM_CTX), which sizes the prompt; large --context does not automatically raise the completion cap. |
Privacy and keys: Pointing at localhost keeps traffic on your machine (subject to that server’s behavior). Pointing at a remote vendor URL means prompts may leave your machine and you may need API keys as required by that server—Stet does not change those rules.
Full precedence and every key are documented in the CLI–Extension Contract.
| Command | Description |
|---|---|
stet doctor |
Verify Git and configured LLM reachability (Ollama or OpenAI-compat) |
stet skill |
Print Agent Skill Markdown for LLM integration (e.g. save as SKILL.md in .claude/skills/stet-integration/) |
stet benchmark |
Measure model throughput (tokens/s) for the configured model |
stet commitmsg |
Generate a conventional git commit message from uncommitted changes (local LLM); --commit to commit with it, --commit-and-review to commit then run review |
stet start [ref] |
Start review from baseline |
stet run |
Re-run incremental review |
stet rerun |
Re-run full review (all hunks) with same or overridden parameters; use --replace to overwrite previous findings; requires an active session |
stet finish |
Persist state, clean up; writes session note to refs/notes/stet for impact analytics |
stet status |
Show session status |
stet list |
List active findings with IDs (for use with dismiss); --min-severity <error|warning|info|nitpick> and --min-confidence <0..1> hide findings below a threshold |
stet dismiss <id> [reason] |
Mark a finding as dismissed; optional reason: false_positive, already_correct, wrong_suggestion, out_of_scope |
stet cleanup |
Remove orphan stet worktrees |
stet optimize |
Run optional DSPy optimizer (history → optimized prompt) |
stet stats [volume|quality|energy] |
Aggregate impact metrics from notes and history |
stet --version |
Print installed version |
--nitpicky— Report style, typos, and grammar (config:nitpicky = trueorSTET_NITPICKY=1).--verify— Run the critic (second-pass verification) on each finding and drop the ones it rejects; add--critic-backend systemoneto use a System One decision server (one ~100 ms request per hunk) instead of a second LLM pass. Critic keys (including env-onlySTET_SYSTEMONE_API_KEY) are documented in the CLI–Extension Contract.--trace— Print internal steps to stderr for debugging (stet start --traceorstet run --trace).--rules-max-tokens— Token budget for Cursor rule review digests in the prompt (config:rules_max_tokensorSTET_RULES_MAX_TOKENS; default0= 15% ofcontext_limit, clamped to 1000–8192). See Cursor rules in the review prompt.--timeout— Per-request timeout for long or large-context reviews (e.g.stet start --timeout 45m). See CLI–Extension Contract.stet benchmark --model MODEL— Benchmark a specific model instead of the configured one.stet benchmark --warmup— Run a warmup call before measuring (load model, discard metrics).stet benchmarkconfiguration — Like every command,stet benchmarkreads the repo.review/config.toml(provider, base URL, model) when run inside a git repository, on top of your global config, environment, and flags; outside a repository only the global config, environment, and flags apply.stet benchmarkestimate — TheTypical stet hunk … estimatedline is approximate: for OpenAI-compatible providers the measured rate is end-to-end (prefill plus generation), and the estimate scales that measured request time to a typical hunk's prompt and output size.
Use Stet inside Cursor (or VSCode) to view findings in a panel, jump to locations, copy to chat, and run "Finish review." The extension runs the CLI and displays results. Load the extension folder as an extension development workspace or install from a VSIX.
By default, Start review runs a production review (stet start or incremental stet run when a session is active) with JSON streaming. Set stet.dryRun to true in workspace or user settings to use --dry-run instead (no LLM; useful for development or CI).
Filter what appears in the findings panel with stet.minConfidence (0–1; findings below the threshold are hidden) and stet.categories (optional allowlist; empty shows all). Filtering is display-only and does not change the CLI session.
- On
stet finish, Stet records session metadata in a Git note (refs/notes/stet) for impact analytics and integration with tools like git-ai. - Product Requirements Document
- Implementation Plan
- CLI–Extension Contract — Configuration and tuning (including RAG and strictness).
- Review Process Internals — For contributors modifying the CLI.
- Review Quality — Actionable findings and prompt guidance.
MIT. See LICENSE.