DiffSight

A desktop client for GitHub & GitLab code review

Code review for the humans who still look.

DiffSight is a fast, local-first desktop app for reviewing pull requests on GitHub and GitLab. Built for engineers who refuse to rubber-stamp AI-generated diffs.

Read the manifesto

Pre-1.0. We'll email you the moment there's something to install.

evilcorp/atlas·#482·verify session signatures before lookup
⌘K
src/auth/session.ts+3−2
S
41 export async function getSession(req: Request) {
42 const token = readCookie(req, 'sid');
43 if (!token) return null;
44 return store.lookup(token);
45 }
58 function readCookie(req: Request, name: string) {
59 const raw = req.headers.get('cookie') ?? '';
41 export async function getSession(req: Request) {
42 const token = readCookie(req, 'sid');
43+ if (!token) return null;
44+ const session = await store.lookup(token);
45+ return verifySignature(session) ? session : null;
46 }
59 function readCookie(req: Request, name: string) {
MS
m.shawon line 45 resolveR

Should we fail closed if verifySignature throws? Right now we'd return null and pretend the user is logged out.

3 of 9 tracks reviewed
indexed · 12,438 symbols
Works withGitHubGitLabBYO AIAnthropicOpenAIClaude CodeCodex

Manifesto

The craft of reading code is dying.

Every day, more code is written by machines. And reviewed by no one. Pull requests pile up. Diffs scroll past. We click Approve because we trust the model. Or because we've stopped trying.

DiffSight is built for the engineers who still believe code review is a discipline. Not a chore. Not a formality. A craft.

AI-assisted, not AI-replaced.

You write with AI. You ship with AI. Fine. But somebody still has to look. That somebody is you. We just make it bearable. Fast, dense, keyboard-driven, local.

What it is

A code review client. Nothing more, nothing less.

Local-first, by design

Everything lives on your machine: SQLite database, encrypted tokens, indexed repos, review history. No DiffSight server. No account. No sync. Telemetry is opt-in and off by default. The app talks directly to GitHub and GitLab from your machine, and to nothing else unless you ask it to.

Bring your own AI

Drop in your Anthropic or OpenAI API key, or hook up your existing Claude Code or Codex subscription. Your prompts go from your machine to your provider. No DiffSight gateway, no relay, no aggregation.

Deep AI analysis

Target a single file and ask DiffSight to read every change line by line, walk the call graph, and surface what matters: behavior shifts, security risks, missing tests, places where the diff and the rest of the codebase no longer agree.

Multi-provider Git

GitHub and GitLab in one place. Same UI for both providers. Switch repos without leaving the keyboard or the window.

Flagship · Track-based review

Stop reviewing PRs as walls of diff.

DiffSight slices a pull request into themed tracks: each one groups the hunks that belong together, and walks you through them with a short narrative.

BeforeWhat GitHub gives you for a 145-change PR
Filesevilcorp/atlas · #482
Files (47)21 / 47
Filter by path…P
  • config
  • tenants.go+331 0
  • tenants_test.go+628 0
  • config.go+12 16
  • config_test.go+12 12
  • internal/keystore
  • store.go+46 38
  • store_test.go+92 12
  • errors.go+14 0
  • internal/storage
  • bucket.go+18 5
  • bucket_test.go+41 8
  • migration.go+167 0
  • internal/server
  • router.go+28 11
  • middleware.go+33 4
  • tenant_resolver.go+78 0
  • internal/billing
  • ledger.go+22 17
  • invoice.go+9 9
  • ledger_test.go+71 12
  • internal/metrics
  • tenant_metrics.go+19 0
  • dashboards.json+138 12
  • cmd/atlas
  • main.go+6 4
  • boot.go+17 9
+ 22 more files
AfterWhat DiffSight does with the same PR
Tracksevilcorp/atlas · #482
Review complete0 / 6
  • 1
    Modeling tenants as first-class config0 / 5

    v1 baked one billing account and tenant id into env vars, so a single instance could only serve one tenant. The author starts by giving the server a registry of tenants so the rest of the change has something to look up.

    • tenants.go
      /config
      +331 0
    • tenants_test.go
      /config
      +628 0
    • config.go
      /config
      +12 16
    • config_test.go
      /config
      +12 12
    • types.go
      /internal/types
      +1 0
    • All files read — chapter complete
  • 2
    Per-tenant key resolution0 / 5

    Each tenant now carries its own KeyConfig, so the keystore can no longer read keys from a single global env.

  • 3
    Re-pathing storage under {tenantId}0 / 8

    With keys scoped per tenant, the storage layout itself must isolate them.

  • 4
    Routing the tenant id through the request0 / 18

    Storage and keys are tenant-scoped. The request layer must extract the id and propagate it down to handlers.

  • 5
    Migrating v1 buckets in place0 / 6

    An existing v1 install upgrading to this build would silently lose every previously published asset without a migration.

  • 6
    Per-tenant metrics and dashboards0 / 4

    Multiple tenants publishing through the same Prometheus instance would have collided on metric names.

Group by intent, not by file. Every hunk lands on a track automatically, with a short narrative of why it's there.
Time-box the noise. Lockfiles, snapshots, and generated code collapse into a single track you can acknowledge or skip.
Resume mid-track. Close the app, come back tomorrow. DiffSight remembers what you've already read.

Features

Dense by default. Quiet by design.

A small set of primitives, each one earning its keep. No carousel of icons, no feature flags pretending to be products.

AI

Deep analysis on the file you choose

Point DiffSight at a single file and ask for a deep read. It walks every change line by line, follows the call graph, and reports back: behavior shifts, security risks, missing tests, places where the diff and the rest of the codebase no longer agree.

src/auth/verify.ts
Claude · 32s · 4 findings
  • High
    Bypass via empty signature.
    verifySignature · line 42 · equality on raw bytes
  • Security
    Token rotation not awaited.
    rotate() · line 88 · async without await
  • Behavior
    Returns null for revoked tokens.
    getSession · line 44 · was previously a thrown error
  • Refactor
    Duplicated error path.
    lines 30-37, 51-58 · extract to a single guard

Inline comments & threads

Reply, resolve, and navigate threads inline. No context switch to a web view.

MS

Should we fail closed here?

AK

Yes. Pushed in fixup.

resolved2 replies

Side-by-side & unified diffs

Toggle layout per file. Sync'd scroll, soft-wrapping, syntax-aware coloring. State persists across sessions so you pick up where you left off.

function getUser(id) {
return db.users.find(id);
}
function getUser(id) {
+ return cache.get(id) ??
+ db.users.find(id);
}

Whole-file context

Expand the full file inline without leaving the diff view.

… 38 lines hidden
41if (token) {
42+ verify(token)
43}
… 12 lines hidden
Powered by Symlink

Local repo indexing

Symlink, our local indexer, parses your repo into typed symbols and call-graphs. Definition jumps, reference lookups, and AI grounding all run in-process. No source code uploaded anywhere, ever.

Supported languages
TypeScriptPythonGoRustJavaKotlinC#PHPSwiftSvelteBash+ more shipping
Indexed · 12,438 symbolslive
  • getSessionsrc/auth/session.ts:41
  • verifySignaturesrc/auth/verify.ts:12
  • SESSION_SECRETsrc/config.ts:8
  • store.lookupsrc/db/store.ts:60
  • rotateKeysrc/auth/keys.ts:24
12,438
symbols
847
files
1.2s
initial scan

Security & privacy

Your code never leaves your control.

DiffSight is built for people who read security threat models. Here's the actual one.

Want the full threat model? Read the security doc.

  • No DiffSight server.

    There is no backend. The desktop app talks directly to GitHub, GitLab, and your chosen LLM provider. Nothing in between.

  • Telemetry is opt-in, off by default.

    Today there's none at all. Anything we ever add will ship off by default, be disclosed in the changelog, and be a one-toggle decision in settings.

  • OS-native secret storage.

    OAuth tokens, PATs, and LLM API keys are encrypted at rest using the OS keystore (Keychain on macOS, DPAPI on Windows, libsecret on Linux) via Electron safeStorage. Never plaintext, never logged.

  • Local SQLite, local index.

    Review history, comments-in-flight, repo index, and cached diffs live in a single SQLite file in your user data directory. Delete the file → DiffSight forgets everything.

  • Renderer is sandboxed.

    Strict process isolation: contextIsolation: true, no nodeIntegration. Every privileged operation goes through a typed IPC contract. The UI cannot touch your tokens.

  • BYOK LLM, no proxy.

    AI requests go from your machine straight to Anthropic / OpenAI / your local Claude Code or Codex CLI. DiffSight never sees, logs, or routes your prompts.

  • Open about what's sent.

    Every outbound network call is documented. For AI reviews, you see exactly which files and hunks get included in the prompt before sending.

  • Read-only agent surface.

    The review agent runs against a fixed set of tools: read_file, list_files, grep, read_pr_diff, list_pr_files, get_dep_graph. No shell. No write. No git push, no git commit, no arbitrary network. The agent can look, never act.

  • Scoped to the PR you opened.

    Every tool call is bound to the current repository and pull request. The agent can't read another repo, jump to another branch, or pull data outside the PR's scope.

  • Bounded by design.

    Per-review token and cost ceilings, configurable. Hard stop on tool-call count to prevent runaway loops. Streamed status with a visible kill switch. Interrupt mid-run, always.

  • Every step is on the record.

    Every tool call (which file, which range, which query) is shown in the UI, in order, with inputs and outputs. Nothing happens off-screen. Save the trace, share it, audit it.

  • Locked-down renderer.

    Strict Content-Security-Policy, no eval, no remote scripts. Even a compromised dependency cannot reach your tokens or open a back-channel to the network.

For the humans who still look

I used to trust the diff. Then I trusted the model. Now I just trust the silence. The click of j k j through every hunk, until I actually understand what I'm shipping.

A senior engineer who still reads code

Pre-1.0 · Closed beta

Get an invite when DiffSight is ready.

We're shipping the first installable build to the waitlist. No public download yet, no marketing emails, no drip campaign. One email when there is something to install.

macOS, Windows, Linux when ready. Free during beta.