In short
- Klaub is a free, open-source terminal tool for the person who has to review what AI coding agents wrote.
- It shows each change by function, ranks the changes by risk and says why, and traces who calls them.
- It runs offline, uses no LLM, and never approves, rejects or fixes anything. You decide.
Klaub helps you review code written by AI coding agents such as Claude Code, Codex CLI and Aider, or any change in a Git repository. It reads the code the way the language does, so you review functions and classes instead of hunks. The queue puts the riskiest change first and shows the evidence for that order. Comments you write go back to the agent as one short instruction, and you press Enter.
Quickstart | Install | Skills | Shortcuts | FAQ | Docs
Three steps take you from nothing to a review. Each one is a single command.
brew install myrk-kale/tap/klaubThis works on macOS and on Linux. Without Homebrew, the Install section has a script, Cargo and plain archives.
npx skills add myrk-kale/klaubThe skills CLI asks which skills and which agents to install them for, such as Claude Code and Codex. The skills explains what each one does. Klaub works without them, so you can add them later.
cd my-project
klaub reviewKlaub opens the reviewer on what changed since HEAD. The riskiest change is first.
To work with the agent and the reviewer side by side, start the agent through Klaub:
klaub wrap codex # or: klaub wrap -- claude --model <model>Klaub runs the agent in a session of its own with a reviewer window next to it. Press Shift+→ to go to the reviewer and Shift+← to go back to the agent. Ctrl+B then d leaves the session running in the background, and klaub session attach brings it back. Ctrl+B then Q ends the session and the agent.
- Open the queue with
klaub review. The riskiest change is first, and the code of the selected one is beside it. - Press
wto see why it has that priority. - Press
Enterto focus the code,vto flip between the old and the new version and[and]to jump between the changed regions. - Press
ifor the contract andKfor the symbol panel: its signature with the types, its documentation and its priority. - Press
rto mark a unit as reviewed, and2or3to read the same change as a tree or as a list of files.
Press ? at any time for the key list.
Klaub runs on macOS (Apple silicon and Intel) and on Linux (x86_64 and aarch64), and it needs Git on your PATH. Windows is not supported yet. Pick one of the ways below.
On macOS and on Linux with Homebrew:
brew install myrk-kale/tap/klaubUpdate with brew upgrade klaub and remove with brew uninstall klaub.
Without Homebrew, the install script picks the release archive for your system, checks its SHA-256 and puts the binary in ~/.local/bin:
curl -fsSL https://raw.githubusercontent.com/myrk-kale/klaub/main/scripts/install.sh | shSet KLAUB_VERSION to install a specific version and KLAUB_INSTALL_DIR to put the binary somewhere else. The variables go on the sh side of the pipe:
curl -fsSL https://raw.githubusercontent.com/myrk-kale/klaub/main/scripts/install.sh \
| KLAUB_VERSION=0.4.0 KLAUB_INSTALL_DIR=/usr/local/bin shThe script tells you when the install directory is not on your PATH.
With a Rust toolchain (1.90 or newer), from crates.io:
cargo install klaub --lockedOr straight from the repository:
cargo install --git https://github.com/myrk-kale/klaub klaub --lockedA build from source does not include the session runtime that klaub wrap uses. It looks for one on your PATH, and klaub doctor says which one it found. klaub review does not need it. The development guide has the details.
Or download the archive for your system from the releases page, check it against its .sha256 file and unpack it:
| System | Archive |
|---|---|
| macOS, Apple silicon | klaub-<version>-aarch64-apple-darwin.tar.gz |
| macOS, Intel | klaub-<version>-x86_64-apple-darwin.tar.gz |
| Linux, x86_64 | klaub-<version>-x86_64-unknown-linux-gnu.tar.gz |
| Linux, aarch64 | klaub-<version>-aarch64-unknown-linux-gnu.tar.gz |
shasum -a 256 -c klaub-0.4.0-aarch64-apple-darwin.tar.gz.sha256 # sha256sum -c on Linux
tar -xzf klaub-0.4.0-aarch64-apple-darwin.tar.gz
install -m 0755 klaub-0.4.0-aarch64-apple-darwin/klaub ~/.local/bin/klaubThe archive holds the klaub binary, the license, the changelog and the notices of the third-party components that ship inside it. The Linux archives are built against glibc, so on a distribution that uses musl, such as Alpine, install with Cargo instead.
Each archive also has a build provenance attestation. With the GitHub CLI you can check that it was built from this repository:
gh attestation verify klaub-0.4.0-aarch64-apple-darwin.tar.gz --repo myrk-kale/klaubklaub --version
klaub doctorklaub --version prints the version. klaub doctor checks Git, your terminal, the grammars, the cache and the directories Klaub uses, and says what to fix.
The skills need Node.js, because the skills CLI runs through npx.
npx skills add myrk-kale/klaub # choose the skills and the agents
npx skills add myrk-kale/klaub --list # only list what the repository offers
npx skills add myrk-kale/klaub --skill klaub-feedback --agent claude-code codexUpdate with brew upgrade klaub, by running the install script again, or with cargo install klaub --locked --force. To uninstall, run brew uninstall klaub, delete ~/.local/bin/klaub, or run cargo uninstall klaub. If you want, also remove the .klaub/ folders in your repositories and Klaub's own state and cache directories, which klaub doctor prints. The skills are removed with the skills CLI (npx skills --help lists its commands).
Klaub exists because reading agent output is now a large part of a developer's day, and the tools for it were built for something else. Its answer is a better lens for the person, not another model to judge the first one.
The numbers point at the gap. In Sonar's 2026 State of Code survey of more than 1,100 developers, 96% said they do not fully trust AI-generated code, and only 48% said they always verify it before committing. 38% said reviewing AI code takes more effort than reviewing a colleague's. Developers reported that 42% of the code they commit is AI-generated or assisted. Sonar sells code verification and The Register noted the possible bias, and the figures are self-reported, so read them as a signal and not as a measurement.
A common answer today is to ask a second model to review the first one's diff, as in this write-up of Codex reviewing every Claude diff. It can catch real problems. The same write-up treats the result as advisory, because a reviewing model can be wrong too. You still have to read the code to know which finding to believe.
Klaub takes the other route. It does not try to understand your code better than you do. It makes the code quicker to read and says where to look first, with the evidence on screen: a changed public contract, an entrypoint that reaches the function, a sensitive area, a missing test. The analysis is deterministic, so the same change gives the same queue, and every score can be taken apart. Nothing in Klaub acts for you. It does not approve, reject, submit or fix.
Klaub shows functions, classes and methods, because that is the unit an agent changes and the unit you reason about. A new file is shown whole. A rewritten function appears in full with the old and the new version in the same place. A function that moved to another file is followed there instead of showing up as one deletion and one addition.
Each symbol is classified as added, removed, modified, moved, renamed, signature changed, rewritten or format only, with a confidence and the evidence for it. When Klaub is not sure two functions are the same one, it says so and keeps them apart instead of guessing.
Files in other languages are listed, shown whole and compared as text, and Klaub tells you that no semantic analysis was done for them.
Every changed function, class and file is a unit in the queue, ordered P0 to P3. Press w on a unit to see the points that put it there: a changed contract, an entrypoint that reaches it, a sensitive area such as auth, a risk finding, a missing test. A sensitive word alone never produces a P0.
Findings are marked introduced, pre-existing, removed or unknown, so you can tell a new problem from one that was already there. The risks Klaub looks for are swallowed errors, queries built from dynamic text, secrets written in code, I/O inside loops, dynamic code execution, shell execution, unsafe blocks and disabled certificate checks. It also checks architecture rules you define, such as forbidden dependencies and new import cycles.
If a finding is a false positive, press w, then the finding's number, and Klaub silences that rule for the review. The priority is a heuristic that orders your reading. It is not a verdict on severity, and a P3 can still matter.
The current version fills the screen. Press v to swap it for the previous version in the same viewport, and [ and ] to jump between changed regions. Press o to open the unit inside its whole file. In a terminal that reports key releases, [ui] hold_to_peek lets you hold B to look at the old version and release it to come back.
Press i to see the contract: what a caller would notice. That means parameters and return type, decorators and annotations, the routes the symbol serves, the exceptions it raises or declares, its observable effects, and the public members of a type, each shown as added and removed lines. The same key works on migrations (SQL, Alembic, Django, Rails), dependency manifests and settings files, and it never shows secret values.
Press 4 to see the impact: the callers of the changed function, the functions it calls and the entrypoints that can reach it, with the path and the confidence of each hop. Every edge is labeled resolved, heuristic or unresolved, because a missing path is never evidence that nothing depends on the code. You can open any hop and pivot the view on it.
Comments are anchored to a symbol and a version, and they follow the symbol when lines move. If the commented code disappears, the comment is marked stale instead of landing on the wrong function. They are saved in the repository as versioned JSON.
When you finish, Klaub freezes the comments into a feedback file and offers to put one short instruction in the agent's input, to copy it, or to show the file. It shows the destination and the exact text first, and it sends one line as a bracketed paste, so it can never be read as a submission. You press Enter yourself.
In the next round the previous comments come back, and you decide for each one whether it was resolved, partly resolved, unresolved or a regression. The agent does not get to decide that.
For automation, klaub review --wait lets a script open the reviewer and wait for you. It exits with 0 when you finish the review and 3 when you close it as a draft, and with --format json it prints the review and nothing else. klaub reviews export writes a review as JSON, Markdown or SARIF 2.1.0, so comments can go to code scanning tools.
Klaub ships two skills for your coding agent. They exist so that the agent cooperates with a review you run, not to hand the review to the agent. They install with the skills CLI, as shown in the quickstart, and work with Claude Code, Codex and the other agents that CLI supports.
| Skill | What it makes your agent do | Where it ends |
|---|---|---|
klaub-feedback |
Address the comments of a finished review one comment_id at a time, change the code each comment points at, and not merge, drop or invent comments. |
You decide whether each comment was resolved. |
klaub-flow |
Write a flow diagram of the change under review as JSON, check it with klaub flow validate, and not edit application code. |
Klaub validates it against the snapshot and you navigate it down to the real code. |
Without the skills, the agent still receives your comments as text. With them it knows the format, the order of work and the limits of its role.
The flow diagram is the visible one. Press p in the Flow view to ask your agent for it, then L to reload it. A diagram that is stale, malformed or points outside the repository is refused, and what the agent claims is treated as a hypothesis: where the index disagrees (a step whose symbol does not exist) the difference is shown.
Klaub links changed symbols to the tests that probably exercise them and says how it knows (a reference, a name, a file). It reads JUnit and Coverage.py reports and tells you when they are older than the change. X runs your configured test command after showing it and asking, and it never runs anything on its own.
A coverage view tracks which units you have not reviewed yet, and n jumps to the next one. You can import a brief with --brief FILE and tick its acceptance criteria yourself. Opening a file, running tests or having no alerts never counts as reviewed.
| Language | Extensions | What Klaub understands |
|---|---|---|
| Python | .py, .pyi |
Symbols, signatures, decorators, calls, imports, routes (FastAPI and Flask style), test functions, risk findings |
| JavaScript | .js, .jsx, .mjs, .cjs |
Symbols, signatures, calls, imports and re-exports, Express style routes, risk findings |
| TypeScript | .ts, .tsx, .mts, .cts |
The same as JavaScript, plus interfaces, types and enums |
| Rust | .rs |
Functions, impls, traits, structs, enums, use paths, Result errors, unsafe, #[test] |
| Go | .go |
Functions, methods, structs, interfaces, packages, error returns, routes, main |
| Java | .java |
Classes, interfaces, enums, records, methods, annotations, throws, Spring and JAX-RS routes, JUnit tests |
Adding a language is a documented, step by step change: see adding a language.
Every key below can be changed in .klaub.toml under [keys] (configuration). Press ? in the reader for the same list, : or Ctrl+P for the command palette, and q twice to close.
| Key | Mode |
|---|---|
1 or F2 |
The queue on the left, ranked by risk |
2 or F3 |
The structure tree on the left: modules, files and symbols |
3 |
The flat list of changed files on the left |
F4 |
The code focused (Enter on a list gets there too) |
4 |
The Decisions window, one technical decision to a screen |
5 |
The Flow window: a form that asks the agent for a diagram, and the diagram |
Tab, Shift+Tab |
Next and previous mode |
Esc |
Go back (from the code, to the list you came from) |
The screen is a list on the left and the code of the selected unit on the right. The queue, the tree and the file list are three ways to fill the left side, and the code follows the cursor as you move in any of them. K shows or hides the panel beside the code: the symbol's signature with its types, the documentation comment it carries and the reasons for its priority.
| Key | Action |
|---|---|
j, k or arrows |
Move |
h, l |
Scroll sideways in code |
Enter |
Open the selected unit |
v |
Toggle old and new |
B (hold) |
Show the previous version while held, in supported terminals |
[, ] |
Previous and next changed region |
o |
Open the unit in its whole file |
S |
Switch between the symbol and the whole file |
i |
Inspect the contract |
K |
Show or hide the symbol panel |
<, > |
Back and forward through the units you visited |
/ |
Search |
+, - |
Show more or less in the structure tree |
| Key | Action |
|---|---|
w |
Why this priority, and silence a false positive |
r |
Mark reviewed or unmark |
m, , |
Bookmark a unit, jump to the next bookmark |
n, P |
Next and previous unreviewed unit |
N |
Next unreviewed P0 or P1 unit |
R |
Take a new snapshot after the worktree changed |
| Key | Action |
|---|---|
H |
P0 and P1 only |
u |
Unreviewed only |
I |
Introduced by this change |
T |
Units without tests |
W |
New files |
s |
Minimum reach: local, module or global |
M |
Next module |
x |
Clear filters |
Inside klaub wrap, t on any screen puts a description of what is on it into the agent's input and takes you to the agent, so you only type the question after My question: and press Enter yourself. Shift+→ brings you back.
| On the screen | What the agent receives |
|---|---|
| The queue, the tree, the file list, the code | The unit (symbol and file), how it changed, its priority and findings, the version and lines on screen, the line your cursor is on, and the git diff and git show that show the change and the previous file |
| A decision | The whole card (context, what was decided, why, alternatives, consequences, the question, where in the code) and what you have answered so far. On the summary, every decision with its answer |
| The Flow window | The diagram's steps in reading order with the selected one marked, and the relations. In the form, the choices made so far |
The text tells the agent not to change or run anything before your question. It is one line, cut in the middle if it is long so the end (the question and your answer) always arrives. It is the one text Klaub puts in the agent without asking first, because it is meant to be one key; set [integration] ask_agent_confirms = true to be asked each time, with the destination and the text.
These work after klaub wrap. Press the prefix (Ctrl+B by default), release it, then the key.
| Key | Action |
|---|---|
Shift+→ |
Open the reviewer, with no prefix |
Shift+← |
Back to the agent, with no prefix |
R or r |
Open the reviewer |
A or a |
Back to the agent |
d |
Detach and leave the session running (klaub session attach brings it back) |
Q |
End the session and its agent, after a y/n confirmation |
? |
Print these chords |
An optional mouse mode ([ui] mouse = true) adds wheel scrolling and clicks on rows and code lines.
The Flow window draws how the change runs as a diagram: a box for each step and connectors between them, the steps the change touched outlined, the certainty of each step and relation marked. Without a diagram the window is a form, and what you choose there shapes the request:
| Choice | Options |
|---|---|
| Focus | Free text: what the diagram should concentrate on. Empty covers the whole change |
| Type | Code flow, abstract (components and responsibilities), data flow, sequence of interactions |
| Level of detail | High level, medium, low level (functions and the branches that decide the path) |
| Reach | Only what changed, changes and neighbours, end to end (user, frontend, API, storage, outside systems, even other repositories) |
| Size | About 8, 15 or 30 steps at most |
| Starts at | Automatic, a user action, an HTTP request, a job or event |
| Error paths, Outside systems, Mark what changed | Yes or no each |
↑/↓ move between the choices, ←/→ change one, Enter on Focus types the focus. g puts the request in the agent's input after you confirm; it carries everything the agent needs (the change, your choices, the shape of the file), so nothing has to be installed, and Enter is never pressed for you. When the agent saves .klaub/flows/<snapshot-id>.json the diagram appears by itself. In the diagram the arrows follow the connectors, Enter opens the code of a changed step, e brings the form back to ask for another diagram and L reads the file again. klaub flow prompt prints the same request with the choices as flags (--focus, --kind, --detail, --reach, --size, --start, --errors, --no-externals, --no-mark-changes).
The Decisions window asks the agent for the technical decisions of the change, told so that you can decide without knowing the code or what the product does there. If the file does not exist, g offers to put the request in the agent's input. The request carries everything the agent needs (the change, what to list, the shape of the file and how to write each field), so nothing has to be installed; you read it there and press Enter yourself. when the agent saves .klaub/decisions/<snapshot-id>.json, the window fills in by itself. Klaub does not write the decisions: it validates the file against the snapshot and shows nothing that fails or belongs to another state of the code.
One decision fills the screen, with its question always visible at the bottom.
| Key | What it does |
|---|---|
→ or Enter, ← or Backspace |
Next decision, back |
a, d |
Approve, reject (the same key again takes it back) |
c |
Comment, with or without a verdict (Enter saves, Ctrl+J starts a new line) |
j/k, PgDn/PgUp |
Scroll a long card |
End |
Jump to the summary |
f |
From the summary: hand the rejected and commented decisions back to the agent, after you confirm |
g |
Ask the agent for the decisions |
After the last card the summary lists every decision with its answer. Rejected decisions and comments can be put in the agent's input (inside klaub wrap) or printed with klaub decisions feedback to paste anywhere. Your answers are stored in the review file.
| Command | What it does |
|---|---|
klaub review |
Open the reviewer. Options: --base REV, --scope worktree|staged|unstaged|branch, --brief FILE, --wait, --format json |
klaub wrap <agent> |
Run an agent with a reviewer next to it. --detach starts it in the background |
klaub session list|attach|kill |
Manage wrapped sessions |
klaub reviews list|show|export |
List stored reviews, print one, export as JSON, Markdown or SARIF |
klaub feedback ID |
Print the feedback of a finished review |
klaub tests list|run |
List test associations, or run the configured command after confirming |
klaub flow status|context|validate|prompt |
Work with flow diagrams. prompt takes the same choices as the Flow window as flags |
klaub decisions status|context|validate|prompt|feedback |
Work with the technical decisions: check a file, print the request for the agent, print your answers for the agent |
klaub doctor |
Check Git, the terminal, grammars, the cache, directories and SSH |
klaub crashes list|show |
Read crash reports saved on this machine. Nothing is ever sent |
klaub completions SHELL |
Print a shell completion script |
Klaub does not replace the other ways. It covers the part they leave to your eyes.
| Approach | What you read | Who judges | Where it falls short |
|---|---|---|---|
| The diff in the agent's own output | A line diff, in the order the agent made the edits | You, or the agent grading itself | No ranking, no callers, and a long session scrolls away |
| A pull request on a hosting site | A line diff, after you push | You and your teammates, with the bots you configured | The code leaves your machine before the first read, and the loop with the agent is slow |
| A second AI model as reviewer | The model's findings on the diff | A model, with you confirming each finding | Findings are probabilistic and can be wrong, so you still read the code |
| Klaub | Functions and classes, ranked, with callers and contracts | You, with the evidence on screen | It applies fixed rules, so it finds what the rules and the call graph can show, not every bug |
You can combine them. A second model's findings and Klaub's queue answer different questions, and tests answer a third.
Klaub is a terminal application that helps a person review code changes by function and class, ranked by risk. It was built for reading what AI coding agents write, and it reviews any Git change.
It is for the developer, tech lead or reviewer who has to read and sign off what an agent produced. It is not built for agents. The two skills let an agent cooperate with your review, and every decision stays with you.
Run klaub wrap claude or klaub wrap codex in your repository, let the agent work, then press Ctrl+B and R. You can also run klaub review in a second terminal at any time. When you finish, Klaub can prepare your comments in the agent's input so the agent can address them.
A reviewer you cannot explain is hard to trust, and a second model is one more thing to check. Klaub parses your code, matches symbols across versions, builds a call graph and applies fixed rules, so the same change gives the same queue and every score has a reason. The trade is honest: it cannot find a bug that needs understanding what the code is for. The one place a model is involved is the Decisions window, and there it is your agent that writes the file, not Klaub: Klaub only validates it and records what you answer.
No. Klaub makes no network requests, has no telemetry and needs no account. Comments and reviews are files under .klaub/ in your repository, and crash reports stay on your machine.
Never. Putting a request or your answers in the agent's input shows you the destination and the exact text first, and everything is sent as one line in a bracketed paste, so it cannot be read as a submission. The t shortcut that adds what you are looking at as context skips that question unless you turn it on, and it works the same way: one line, no Enter. You press Enter yourself.
Run npx skills add myrk-kale/klaub, choose the skills and the agents, and confirm. Add --skill klaub-feedback --agent claude-code codex to skip the questions. See Install the skills.
Codex CLI, Claude Code and Aider are the targets, and any interactive terminal program runs through klaub wrap. You can also use klaub review with no agent at all.
Python, JavaScript, TypeScript (including TSX), Rust, Go and Java get full semantic analysis. Other files are shown whole and compared as text. See supported languages.
Klaub adds points for evidence: a changed public contract, an entrypoint that reaches the symbol, a sensitive area, a risk finding, growing complexity, missing tests. Press w to see every term. The weights live in [priority] and are described in configuration.
Open "Why this priority" with w, press the finding's number and confirm. The rule is silenced for that review and the queue is recomputed. "Bring back silenced rules" in the palette undoes it.
In .klaub/reviews/ at the root of the repository, as versioned JSON. Klaub does not edit .gitignore and does not commit anything. The first review of a repository tells you this once.
Yes. Every action, and every key that only works in one mode, can be moved to another single character under [keys]. The footer and the help show the keys you chose.
Run klaub reviews export ID --format sarif. Each comment becomes a result in a SARIF 2.1.0 log, with its priority in the properties.
Yes, as a terminal program. The clipboard of your own machine is out of reach from a remote session, so use "Show file" or klaub feedback there. klaub doctor tells you when it detects SSH. See using Klaub over SSH.
Not yet. Linux and macOS (Intel and Apple Silicon) are supported, and Windows is a possible future extension.
On a Django checkout with 7,000 files, opening a review of a 266 file change takes about 2 seconds the first time and 1 second with a warm cache. Projects of a few hundred files open in 0.3 to 1.1 seconds. A key press in a list takes well under 100 ms. Benchmarks has the method and the limits of these numbers.
Run brew uninstall klaub, delete ~/.local/bin/klaub, or run cargo uninstall klaub, depending on how you installed it. Update and uninstall also covers the files Klaub leaves in your repositories and the skills.
| Configuration | Every .klaub.toml section, and how to move keys |
| Languages | English, Portuguese and Spanish: how one is chosen, what is translated, how to add a sentence or a language |
| Architecture | How Klaub is built: layers, ports, data flow, the terminal layer |
| Security model | Threats, controls and explicit limits |
| Using Klaub over SSH | What works and what the clipboard cannot do |
| Benchmarks | Latency on synthetic and real repositories |
| Adding a language | Every place a new grammar touches |
| Development guide | Building from source, tooling and conventions |
| Changelog | What changed in each release |
| Releasing | How a release is cut |
Contributions are welcome. Start with CONTRIBUTING.md and read the Code of Conduct. Report security issues as described in SECURITY.md, and ask questions through SUPPORT.md.
MIT. The third-party components that ship inside releases keep their own licenses, listed in THIRD-PARTY-NOTICES.md in every release archive. Maintained by myrk-kale.
