Skip to content
 
 

Repository files navigation

Diff Dad

Diff Dad

GitHub PRs as narrated stories.
dad 139 turns a file-by-file diff into a semantic walkthrough with AI-generated chapters, reviewer concerns, a recap tab, inline comments, and live sync.

Install

Homebrew

brew install nicknisi/formulae/dad

Or, equivalently:

brew tap nicknisi/formulae
brew install dad

From source

git clone https://github.com/nicknisi/diffdad && cd diffdad
bun install && bun run build
bun link

Requires Bun when building from source. The Homebrew install is a standalone binary — no runtime needed.

Usage

dad <pr>                     # Open a PR as a narrated review
dad review <pr>              # Same as above (explicit subcommand)
dad config                   # Print a link to the in-app settings page (opens it if the daemon is up)
dad cache clear              # Clear cached narratives
dad daemon                   # Start the per-machine review command center
dad --version                # Print version

Flags (can go in any position):

--with=claude|codex|pi       # Force a specific local AI CLI
--no-cache                   # Regenerate narrative even if cached
--no-open                    # Don't auto-open the browser
--port=3000                  # Use a specific port

PR argument formats:

https://github.com/owner/repo/pull/123
owner/repo#123
139                          # bare number — infers repo from git remote

The CLI fetches the PR diff, generates a semantic narrative, and opens a local web UI in your browser. The review view starts with verdict, reading plan, and concerns; the Recap tab lazily generates an orientation brief for in-flight work.

Command Center (daemon)

dad daemon runs a long-lived, per-machine review hub: one cross-repo queue of everything waiting on you, served at a stable local URL (http://localhost:4319) and grouped by status — needs you, in flight, cleared.

dad daemon                       # Start the command center
dad daemon status                # Is it running?
dad daemon install               # Run it under launchd — survives terminal close, restarts at login
dad daemon uninstall             # Remove the launchd agent

With a GitHub token configured (see GitHub Token), the daemon polls every 60 seconds for open PRs where you're a requested reviewer or assignee and mints a queue unit for each. Open a review request on GitHub and it shows up here.

  • Lazy narration — a unit's walkthrough is generated the first time you open it, not on poll, so PRs you never click cost nothing.
  • Review from the drill-in — a queue row only opens the PR; you approve or request changes from inside the review, which posts a real GitHub review. There is no queue-level verdict. A PR you've reviewed stays out of the queue until its author pushes past the commit you reviewed.
  • Re-read (⟳) — from a PR's review, re-fetch its live head SHA and regenerate the walkthrough from scratch, bypassing the cache — for when the author has pushed since you last looked.
  • Refresh (↻) — the header button runs a poll on demand instead of waiting for the next tick; a "checked … ago" caption shows how fresh the queue is, and a toast reports what changed.
  • Self-cleaning queue — every poll reconciles against GitHub: closed or merged PRs drop immediately; PRs no longer requested of you drop after two consecutive polls without them.
  • Repo filter — a sidebar facets the queue by repo with per-repo "needs you" counts (a native dropdown on narrow screens), so a busy inbox stays scannable.
  • Errors, not spinners — if narration fails, the review shows an explicit panel with a Retry button (and the raw diff below) instead of spinning forever.

How It Works

Instead of reviewing files one by one, Diff Dad groups code changes into chapters by semantic behavior. An AI reads the entire diff and produces a reading order — setup first, then core changes, then wiring, then edge cases — with prose explaining what each group does and why.

AI Provider

Diff Dad picks a provider in this order:

  1. --with=<cli> flag (forces a local CLI)
  2. Provider configured on the settings page
  3. API key env varsANTHROPIC_API_KEY, then OPENAI_API_KEY, auto-route through the matching API when no provider is configured
  4. claude -p (Claude Code CLI), codex, then pi — uses your existing subscriptions, no API key needed, but significantly slower due to harness overhead

Open the settings page (/settings in the command center, or the Settings view in a PR review) to choose between:

  • Anthropic API — requires ANTHROPIC_API_KEY (recommended)
  • OpenAI — requires OpenAI API key
  • Ollama — local models, no key needed
  • Claude CLI / Codex CLI / pi CLI — uses your existing subscription, no API key
dad --with=claude owner/repo#123    # force the Claude CLI even if a key is set

GitHub Token

Diff Dad needs a GitHub token to fetch PR data and post comments. It checks, in order:

  1. DIFFDAD_GITHUB_TOKEN environment variable
  2. gh auth token (GitHub CLI)
  3. Token saved on the settings page

Caching

Narratives and recaps are cached at ~/.cache/diffdad/, keyed by the PR and its head commit — same commit = instant reload. Use --no-cache to regenerate, or dad cache clear to wipe the cache.

The daemon's review queue is durable state, not a cache, so it lives in the app-data dir instead: ~/Library/Application Support/diffdad on macOS, else $XDG_DATA_HOME/diffdad or ~/.local/share/diffdad. dad cache clear never touches it.

Features

Reviewer Surface

Before the chapters, Diff Dad surfaces what a reviewer needs first:

  • TL;DR + verdict — one-line summary plus a safe / caution / risky call
  • Reading plan — an ordered list of where to start and what to look at next, with one-click jumps to the relevant chapter
  • Concerns — Socratic questions about likely defect classes (logic, state, timing, validation, security, test gaps, API contracts, error handling) with citations to the diff

Per-file risk is computed from churn, criticality keywords (auth, migration, payment, …), inbound import refs, and test-gap heuristics, then fed to the LLM as hints so the reading plan is risk-ordered. Concerns can be dismissed, restored, jumped to in the diff, or turned directly into a GitHub comment / draft review comment.

Recap Tab

For drive-by help or returning to a stale PR, the Recap tab answers “what is going on here?” instead of “what might be wrong?” It gathers PR body text, linked issues, commits, force-push events, review threads, CI status, and latest reviews, then summarizes:

  • Goal — the PR’s intended outcome
  • State of play — done, WIP, and not started
  • Decisions & alternatives — cited choices and direction changes
  • Blockers — failing checks, unanswered review questions, TODOs, or thrash
  • Mental model — core files, touchpoints, and a small ASCII sketch
  • How to help — concrete ways a teammate can unblock the work

Recaps are generated on demand and cached separately from review narratives.

Semantic Chapters

The AI groups hunks across files by behavior, not by filename. Each chapter has a title, a why-it-matters block, and narrative prose explaining the change. Chapters can reference the same hunk when it's relevant to multiple behaviors.

Inline Comments

Review comments from GitHub appear inline next to the relevant code lines, including existing multi-line ranges. Comments you post from Diff Dad sync back to GitHub as real review comments, with support for added lines, removed lines, replies, and shift-click multi-line selections. Bot comments (Greptile, CodeRabbit, etc.) are clustered into collapsible groups with replies.

Live Sync

An SSE connection streams narrative generation progress, partial narratives from API providers, recap completion, and GitHub updates. New comments, CI status changes, and check runs appear in real time. Comments you post are broadcast instantly via the server — no waiting for the next poll.

Story Controls

  • Density — toggle narration between terse (1 sentence), normal, and verbose per chapter
  • Re-narrate — rewrite a chapter's narration through a different lens (security, performance, API consumer)
  • Ask AI — ask a question about a specific chapter's code changes
  • Mark reviewed — track your progress through the PR, persisted across page reloads

Review Submission

Submit reviews directly from the UI — Comment, Approve, or Request Changes. Inline comments are posted to GitHub along with your summary, and the submit dialog can draft or polish that summary with AI using reviewed chapters, draft comments, and raised concerns as context.

Keyboard Shortcuts

Key Action
j / k Next / previous chapter
r Toggle reviewed on current chapter
c Open comment composer on hovered line
s Open / close submit review dialog
? Show shortcuts help
Esc Close open panels

Display Options

Configurable on the settings page:

  • Story structure — chapters (cards), linear (continuous flow), outline (collapsed)
  • Layout — TOC sidebar or full-width linear
  • Density — comfortable or compact
  • Narration density — terse, normal, or verbose default

Architecture

Monorepo with three packages:

packages/cli/    Bun CLI + Hono server
packages/web/    React + Vite reviewer UI
packages/site/   Astro marketing site

The CLI fetches the PR, generates the narrative, starts a local Hono server, and opens the browser. The frontend is a static Vite build served by the Hono server. All GitHub API calls go through the CLI server — the frontend never talks to GitHub directly.

Tech Stack

  • Runtime: Bun
  • Server: Hono
  • Frontend: React 19, Vite, Zustand, Tailwind CSS v4
  • Site: Astro
  • AI: Vercel AI SDK (multi-provider) or local CLIs (claude, codex, pi)
  • Syntax highlighting: Shiki (github-light/dark themes)
  • Markdown: Custom renderer with DOMPurify sanitization

Development

bun install
bun run dev              # Start Vite dev server (frontend only)
bun run build            # Build frontend
bun run build:bin        # Build standalone binary
bun run test             # Run tests
bun run typecheck        # Type-check CLI, web, and site
bun run eval             # Run narrative eval fixtures

To test end-to-end, build the frontend first, then run the CLI:

bun run build
cd packages/cli && bun run src/cli.ts review owner/repo#123

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages