// what the model knows about `user`
const user = fetchUser(id);
// model has to guess: optional? throwing?
if (user.email) {
send(user.email);
}Reviews any language.
Speaks compiler on TypeScript.
Every codebase gets the full multi-pass review with the why-on-every-finding contract. On TypeScript, Revund pipes the code through tsc and ts-morph first — so findings cite real types, not guesses about what a variable named user probably holds.
Same diff. Different evidence.
// from ts-worker / ts-morph:
// fetchUser(id: string): Promise<User | null>
const user = fetchUser(id);
// ↑ Promise not awaited (tsc TS2339)
if (user.email) { /* runtime: undefined.email */
send(user.email);
}The bundle that reaches each pass.
On every TypeScript review, Revund spawns ts-worker as a sidecar. It runs tsc --noEmit against the changed files, resolves external symbols via ts-morph, and bundles everything alongside the diff before any pass runs. If ts-worker can't start, the review falls back to diff + files — degraded, but never blocked.
Source + diff
Changed files, full content. The PR's patch as ground truth.
ts-worker (sidecar)
tsc for diagnostics. ts-morph for imported symbol declarations. gRPC over a Unix socket; spawn on demand, drop on exit.
Enriched bundle
Diff + files + symbol table + diagnostics. Pruned to the token budget; same shape every pass receives.
The enriched bundle is deterministic: same inputs yield the same bundle yield the same finding fingerprints. That's what makes dismissals stable across re-runs.
What ships today, what ships next.
multi-pass review · why on every finding
+ tsc · ts-morph · full type context
+ pyright · ruff diagnostics
+ gopls · staticcheck
+ rust-analyzer · clippy