Review code from Claude Code, Codex or Cursor in a native Mac app. Open the diff, follow callers, and ask AI Reader about a change. Click its source references to read the surrounding code.
export function cupsFor(waterMl: number) { return Math.floor(waterMl / 200);}// Fictional teaching input: 550 ml.const cups = cupsFor(550);// cups is 2.
TypeScriptUTF-8 · Source preview
✳ AI Reader +
How many cups does this amount make?
ANSWER
Only complete cups count.
For this fictional recipe, each cup uses 200 ml. With 550 ml, dividing gives 2.75 and Math.floor returns 2.
recipe.ts:1–3
What happens with less than 200 ml?↗
ts label.ts×
src / label.ts /teaLabel
1234567
import { cupsFor } from './recipe';export function teaLabel(waterMl: number) { return cupsFor(waterMl) + ' cups';}// teaLabel(550) returns '2 cups'.
TypeScriptUTF-8 · Source preview
✳ AI Reader +
Where does the count in this label come from?
ANSWER
The label calls the recipe helper.
teaLabel passes waterMl to cupsFor, then puts the returned integer into a label. Read recipe.ts to check how that number is calculated.
label.ts:1–5
Which input would produce zero cups?↗
ts recipe.ts×
src / recipe.ts /cupsFor
123456
export function cupsFor(waterMl: number) { return Math.round(waterMl / 200);}// Proposed change in this teaching example.// cupsFor(550) now returns 3.
TypeScriptUTF-8 · Source preview
✳ AI Reader +
Would rounding preserve the result?
ANSWER
550 ml would become three cups.
Math.round(2.75) returns 3, but three cups need 600 ml in this fictional recipe. The input 550 distinguishes the proposed change from the original.
recipe.ts:1–3
Compare both functions with the same input.↗
Files, questions, and source referencesFictional code and answers, written for this illustration
Works on local repositories
Answers link to source lines
Local changes, commits, branches
01 /WHAT YOU CAN DO
Let the AI write, then see what it changed.
Diffs, the editor, search, and the AI Reader share one window. Local Changes shows everything that changed since your last commit, and when an answer mentions a line, you can open it right there.
Open the repo your AI works in
Open the DMG, drag Yenpo into Applications, and launch it. Choose the root of the repository your agent is working in. Local Changes shows what changed since your last commit, and you can read and search before setting up AI.
Pick one changed function and jump to its definition, its callers, and the tests that use it. Ask the AI Reader what the change does, then open the lines it cites and check the answer yourself.
Look at one commit, or compare two branches, such as the agent’s branch and main. Read the inline diff and ask the AI Reader to look for regressions. The comparison stays on the commits you picked, and it is read-only.
No. Local Changes, commit and branch diffs, search, Markdown, and language-server navigation all work without one. Connect your own provider when you want to ask the AI Reader. Your provider controls model access and any usage charges.
Swift, Rust, C, C++, Objective-C, Python, JavaScript, TypeScript, and Go, each through its language server. Yenpo can install rust-analyzer for you; the other servers come from Xcode or your PATH. What works depends on the server and on how your project is set up.
Does my code stay on my Mac?
Browsing and search stay on your Mac. When you ask the AI Reader something, your question and the relevant code go to the model endpoint you set up, so check that provider’s terms before using restricted code. The AI Reader only reads unless you allow edits for a run.
What should I know about the preview?
It runs on Apple silicon and Intel Macs with macOS 14 or later. Each build expires on the date shown next to the download button, and reinstalling it doesn’t reset that date, so update before then.
Your vibe-coded feature works, but can you explain it? Learn with a runnable filter: predict three results, change one rule by hand, and check what changed.
A shallow copy creates new outer objects but keeps their nested labels shared. Follow the caller, compare references, and test an explanation that misses the mutation.