# diffing — full documentation corpus Version 0.16.1. Generated for AI ingest. Prefer individual pages when possible. --- url: https://ahmedragab20.github.io/diffing/docs/ title: Documentation --- # Documentation **diffing** is a local-first CLI for reviewing git diffs with humans and AI agents. It runs a loopback web UI (or an experimental native TUI), stores review state under `~/.diffing/`, and exposes CLI + MCP tools for agent handoff and plan review. ## If you are an agent 1. Read [Agent handoff](/docs/guides/agent-handoff/) — async park is the default. 2. Install MCP / skills via [Setup & MCP](/docs/guides/setup-and-mcp/). 3. Prefer [MCP tools](/docs/reference/mcp/) when available; otherwise CLI from [CLI reference](/docs/reference/cli/). 4. For design sign-off before coding: [Plan review](/docs/guides/plan-review/). 5. Bulk ingest: [`/llms.txt`](/llms.txt) and [`/llms-full.txt`](/llms-full.txt). | Verdict / signal | Action | |------------------|--------| | Plan `approved` | Implement the reviewed plan | | Plan `changes-requested` | Revise plan, resubmit same id — do not implement | | Plan `rejected` | Stop | | Await `timeout` + `disposition=park` | End turn; resume when human is ready | | Comment severity `blocking` | Must fix before resolve | | Comment severity `question` | Reply; usually leave open | ## If you are a human 1. [Getting started](/docs/getting-started/) — install and first review. 2. [Code review](/docs/guides/code-review/) — web UI workflow. 3. [Keyboard shortcuts](/docs/reference/keyboard/) — vim-style navigation. 4. [Themes](/docs/design/themes/) & [Gridline](/docs/design/gridline/) — visual system. ## Sections | Section | What it covers | |---------|----------------| | **Start** | Install, setup, first review | | **Concepts** | Architecture, sessions, storage | | **Guides** | Review loops, agents, PR, TUI, search | | **Reference** | CLI, MCP, HTTP API, XML, settings, exit codes | | **Design** | Gridline design system, themes | ## Quick commands ```bash npm install -g diffing diffing setup diffing # preferred interactive UI diffing --staged diffing view # read-only native viewer diffing mode tui # make full TUI the default diffing await-review # sync handoff only diffing plan submit PLAN.md --model "your-model" diffing mcp ``` ## Facts agents should not invent | Do not assume | Correct | |---------------|---------| | Fixed default port | Random free port on `127.0.0.1` | | App uses `localStorage` | Server-side under `~/.diffing/` + `~/.config/diffing/` | | `t` cycles themes | `t` = tab size; themes = `g t` | | ~10 MCP tools | **37** tools (see MCP reference) | | ~42 themes | **52** themes; default **rose-pine** | --- url: https://ahmedragab20.github.io/diffing/docs/getting-started/ title: Getting started --- # Getting started **Requirements:** Node.js 20+, `git` on your PATH, and a Git repository when reviewing code. ## Install ```bash npm install -g diffing # or pnpm add -g diffing # try without installing: npx diffing setup --check ``` A short postinstall banner may print in interactive terminals (print-only — nothing is written to your IDE or project). Upgrade later: ```bash diffing update ``` ## First-time setup ### Interactive gate The first time you run `diffing` in a TTY (and setup is not marked complete), you get: ```text [Y] Run setup now [n] Skip [?] Docs ``` - **Y** — runs `diffing setup` (doctor, default mode, optional skills/MCP) - **n** — continues without setup - **?** — prints the getting-started docs URL Skip anytime with `diffing --skip-setup`. CI and non-TTY environments never show the prompt. ### Setup wizard ```bash diffing setup # interactive wizard diffing setup --yes # install skills + print MCP JSON (no IDE writes) diffing setup --check # preflight only diffing setup --reset # clear setupCompletedAt marker ``` Partial steps: ```bash diffing setup skills diffing setup mcp diffing setup mcp --write-mcp # merge into IDE MCP configs diffing setup mcp --write-project-mcp # opt-in project .cursor/mcp.json ``` Aliases: `diffing init`, `diffing onboard`. The wizard: 1. Checks Node ≥20, `git`, and `~/.config/diffing/` 2. Runs `diffing doctor` 3. Lets you choose **web** vs **TUI** as the default interactive mode 4. Optionally prints shell completions (`diffing completion `) 5. Installs agent skills via `npx skills add ahmedragab20/diffing` 6. Prints MCP JSON; writes IDE configs only with `--write-mcp` / `--write-project-mcp` ## Review your changes ```bash cd /path/to/your-repo diffing ``` This starts the preferred interactive UI (web by default) and opens your browser. Useful variants: ```bash diffing --staged diffing HEAD~3 diffing main..feature diffing -- src/ diffing view # read-only native TUI browser diffing --tui # full native review TUI (experimental) diffing mode tui # make TUI the interactive default diffing --no-open # start server without opening browser diffing --port 3433 # fixed port ``` TTY auto-detect: interactive terminals open the UI; pipes/redirects print a unified patch like `git diff`. Force with `--web`, `--terminal`, `--view`, or `--tui`. ## Agent handoff (optional) 1. Run `diffing setup` and paste MCP JSON or use `--write-mcp` 2. Install skills: `npx skills add ahmedragab20/diffing` 3. Start a review: `diffing` 4. Agent waits only when you are reviewing now: `diffing await-review` or MCP `await_review` Default agent behavior is **async**: share the UI URL, end the turn, resume when you say ready. See [Agent handoff](/docs/guides/agent-handoff/). ## Troubleshooting ```bash diffing doctor diffing setup --check ``` | Symptom | What to try | |--------|-------------| | `not inside a git repository` | `cd` into a repo | | First-run prompt every time | Complete `diffing setup`, or use `--skip-setup` | | MCP tools missing in IDE | `diffing setup mcp --write-mcp` or paste JSON from `diffing setup --yes` | | Skills not found | `npx skills add ahmedragab20/diffing` | | Server won't start | `diffing doctor`, try `diffing --port 3433` | ## Next - [Code review](/docs/guides/code-review/) - [CLI reference](/docs/reference/cli/) - [Architecture](/docs/concepts/architecture/) --- url: https://ahmedragab20.github.io/diffing/docs/concepts/overview/ title: Overview --- # Overview ## What it is **diffing** replaces `git diff` when you want a review workspace instead of a patch dump: - **Humans** review changes in a local browser UI (or experimental native TUI), leave inline comments, and send rounds to an agent. - **Agents** discover the server via a per-repo lockfile, fetch comments, reply/resolve, submit plans for approval, and inspect diffs in bounded slices. - **Nothing leaves the machine** by default — bind is `127.0.0.1`, storage is under `~/.diffing/`. ## What it is not - Not a hosted SaaS or cloud review product - Not a replacement for GitHub PR hosting (though it can **mirror** a PR for local review) - Not only a terminal pager — the TUI is opt-in/experimental; web is the supported production path ## Surfaces | Surface | Command | Role | |---------|---------|------| | Web review UI | `diffing` / `--web` | Full review: comments, plans, search, themes | | Native TUI | `diffing --tui` / `mode tui` | Experimental full review in terminal | | Read-only viewer | `diffing view` | Fast interactive diff browser | | Terminal patch | pipe / `--terminal` | Standard unified diff on stdout | | MCP | `diffing mcp` | Tool surface for AI coding agents | | CLI agent cmds | `await-review`, `reply`, `plan …` | Port-agnostic handoff | ## Core loops ### Code review ```text human opens diffing → comments on lines → Send to agent → agent replies / edits / resolves → human continues ``` ### Plan review ```text agent submits markdown plan → human comments + verdict → approved → implement → changes-requested → revise same plan id → rejected → stop ``` ## Design language The product UI uses **Gridline** — a terminal-native design system shared by the web UI and Rust TUI. Flat surfaces, monospaced type, one-pixel rules, color for state not decoration. See [Gridline](/docs/design/gridline/). ## Next - [Architecture](/docs/concepts/architecture/) - [Sessions](/docs/concepts/sessions/) - [Agent handoff](/docs/guides/agent-handoff/) --- url: https://ahmedragab20.github.io/diffing/docs/concepts/architecture/ title: Architecture --- # Architecture ## High level ```text Human ──► Web UI / TUI ──► Local server (127.0.0.1:port) │ Agent ──► CLI / MCP ────────┤ ▼ Git working tree ~/.diffing/-/ ``` The primary process either: 1. Starts a **review session** (web or TUI) with a random free port, or 2. Prints a **unified patch** when stdout is not a TTY (or `--terminal`). ## Output mode auto-detection | Condition | Result | |-----------|--------| | Interactive TTY, preference `web` | Web server + browser | | Interactive TTY, preference `tui` | Native review TUI | | Pipe / redirect / non-TTY | Terminal patch (like `git diff`) | | Explicit `--web` / `--tui` / `--view` / `--terminal` | Forced mode | | Output-format flags (`--stat`, `--raw`, …) | Forces terminal mode | Change preference: `diffing mode web` or `diffing mode tui` → stored in `~/.config/diffing/settings.json` as `defaultMode`. ## Session discovery Every live web, TUI, or GitHub PR review registers under: ```text ~/.diffing/-/ ├── server.json # active-session pointer └── sessions/.json # one record per live session ``` Agent commands (`url`, `comments`, `await-review`, `plan …`, MCP) read the **active** session from `server.json` — no hardcoded ports. Example lock shape: ```json { "port": 3433, "host": "127.0.0.1", "pid": 45192, "repoRoot": "/Users/dev/my-app", "sessionId": "…", "mode": "web" } ``` `mode` is `"web" | "tui" | "gh-pr"`. Stale PIDs are pruned; if the active session dies, the newest live session is elected. See [Sessions](/docs/concepts/sessions/) for multi-session lifecycle. ## Auth on loopback Loopback binds generate a per-session API token stored in the lockfile. The web UI uses an HttpOnly cookie; CLI/MCP send `x-diffing-token`. Browseable URLs never include `?token=`. LAN expose requires deliberate flags: ```bash diffing --host 0.0.0.0 --insecure-no-auth ``` ## Storage | Path | Contents | |------|----------| | `~/.diffing/-/` | comments, plans, sessions, attachments, search DBs | | `~/.config/diffing/settings.json` | theme, defaultMode, editor, UI prefs | The real app does **not** use browser `localStorage` for session state. ## Real-time `GET /api/live` SSE: `heartbeat` (~15s), `change`, `comments`, `plans`, `agent-status`, `plan-review-status`. Filesystem watchers on the repo and storage dir keep UIs live. ## Next - [Sessions](/docs/concepts/sessions/) - [Storage & security](/docs/concepts/storage/) - [HTTP API](/docs/reference/http-api/) --- url: https://ahmedragab20.github.io/diffing/docs/concepts/sessions/ title: Sessions --- # Sessions ## Concurrent sessions Starting `diffing`, `diffing --web`, `diffing --tui`, or a GitHub PR review no longer conflicts with an existing review. Each launch gets its own port and registry record, becomes **active**, and leaves older sessions running. | Flag | Behavior | |------|----------| | (default launch) | New session; becomes active | | `--reuse-session` | Open the active session and exit | | `--replace-session` | Stop active, then start with current args | `--reuse-session` and `--replace-session` are mutually exclusive. MCP `start_review_session` is conservative: it never stops or replaces a user-owned session and reports incompatible scope/mode conflicts. ## Session manager CLI ```bash diffing sessions # table; * = active diffing sessions --json diffing sessions use # retarget agent commands diffing sessions open [|active] diffing sessions stop |active|all diffing sessions kill |active|all # alias for stop ``` The first eight characters of an id are accepted when unique. Stopping the active session elects the newest remaining session. ## Agent tip After `sessions use`, reconnect MCP so the new connection discovers the selected web session. Plan tools require `mode: web`. ## Modes on a session | mode | Meaning | |------|---------| | `web` | Local working-tree (or range) review in browser | | `tui` | Native terminal full review | | `gh-pr` | GitHub PR mirror review | In `gh-pr` mode, prefer `gh_*` and bounded `diff_*` tools; local plan tools need a web session. --- url: https://ahmedragab20.github.io/diffing/docs/concepts/storage/ title: Storage & security --- # Storage & security ## Paths | Location | Purpose | |----------|---------| | `~/.diffing/-<8-char-hash>/` | Per-repository server state | | `~/.config/diffing/settings.json` | User preferences (theme, mode, editor, …) | | `~/.diffing/backups/` | MCP config backups from setup merge | Repo hash is `sha256(absolute-repo-root).slice(0, 8)`. Typical per-repo contents: ```text server.json sessions/ comments.json plans.json plan-sources/ attachments/ fff/ # search frecency + history DBs ``` Inactive projects may be auto-pruned after prolonged inactivity (see product settings/docs for current window). ## Network defaults - **Host:** `127.0.0.1` - **Port:** OS-selected free port, or `--port ` - **LAN:** only with `--host 0.0.0.0` (or `::`) **and** `--insecure-no-auth` ## Path safety - `..` and null bytes rejected - Paths URL-decoded and constrained to the repository root - Escape attempts return **403** - Attachments isolated under the per-repo `attachments/` directory ## Privacy - No account, no telemetry, no required cloud - GitHub features only run when you open a PR session / authorize publish - Agent plans and scratch should live under `~/.diffing/…/plan-sources/`, not in the consumer working tree ## Related - [Settings](/docs/reference/settings/) - [Architecture](/docs/concepts/architecture/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/code-review/ title: Code review --- # Code review ## Human path ```bash cd your-repo diffing # or: diffing --staged, main..feature, … ``` In the UI: 1. Navigate files (sidebar filters: All / Unviewed / Comments / Since last) 2. Toggle split/unified with m 3. Select lines → add comment (optional severity: blocking · nit · question · praise) 4. Optional multi-line ranges and ```` ```suggestion ```` blocks 5. Click **Send review** / **Send to agent** with a verdict and optional note Live updates: agent replies and resolves appear over SSE without refresh. ## Agent path Prefer MCP when available. Portable CLI: ```bash diffing url # share with human # async: end turn until human says ready diffing await-review # only when human is reviewing now diffing comments --open # snapshot open threads as XML diffing reply --body "…" --model "your-model" diffing resolve diffing progress --message "Working…" --pct 40 ``` ### Per-comment policy | Kind | Action | |------|--------| | Change request / blocking | Edit code → reply → resolve | | Nit | Optional; fix or acknowledge | | Question | Reply; leave open unless answered fully | | Praise | No code change | | Ambiguous | Reply asking for clarification; leave open | ## Suggestions Comments may include: ````markdown ```suggestion const fixed = true; ``` ```` Human or agent can apply via UI / MCP `apply_suggestion` / API — applies the fence to the working tree and can auto-resolve. ## Multi-round Each **Send to agent** increments a review round. History is available via UI and `get_review_history` / `GET /api/review/history`. Outdated comments are detected when lines move. ## Related - [Agent handoff](/docs/guides/agent-handoff/) - [Comments XML](/docs/reference/comments-xml/) - [Keyboard](/docs/reference/keyboard/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/plan-review/ title: Plan review --- # Plan review Plan review gates **implementation** on human sign-off. Use it for non-trivial design, risky changes, or any request to comment on a plan before code. ## Flow ```text 1. Write plan markdown (prefer ~/.diffing//plan-sources/ — not the working tree) 2. submit → share plan URL → park (async default) 3. Human reviews at /plan, comments, Submit review 4. Agent reads verdict and acts ``` ### CLI ```bash diffing plan submit PLAN.md --model "your-model" [--title T] [--save-source] # prints URL; do not --wait unless sync diffing plan await [--timeout 570] # sync / resume diffing plan list diffing plan show [] [--version n] diffing plan versions diffing plan reply --body "…" --model "your-model" diffing plan resolve ``` Resubmit revisions with the **same** `--id` so history stays one conversation. ### MCP `submit_plan`, `await_plan_review`, `list_plans`, `get_plan`, `get_plan_versions`, `get_plan_version`, `reply_to_plan_comment`, `resolve_plan_comment`. ## Verdicts | Decision | Agent action | |----------|--------------| | `approved` | Implement the reviewed version; account for open comments | | `changes-requested` | **Do not implement.** Revise plan, resolve addressed threads, resubmit same planId | | `rejected` | **Stop.** Do not implement | | `comment-only` | Reply only; do not edit product files | | `pending` | Park (async) or one sync await if asked | ## Severity on plan comments Same triage as code review: `blocking` | `nit` | `question` | `praise`. Treat blocking as must-fix before resubmit. ## Plan UI (human) | Feature | Behavior | |---------|----------| | Source / Read / Split | m | | Zen Read | z | | Live edit | e — autosave PUT; Save as new version POST | | Outline / comments map | o / c | | Inline comments | Source gutter or Read highlight; multi-line + severity | | Submit review | Verdict that unblocks `plan await` | ## Keep the tree clean Never write plans, notes, or `.diffing/` directories into the consumer project. Use `~/.diffing//plan-sources/` or stdin: ```bash cat PLAN.md | diffing plan submit --model "your-model" ``` --- url: https://ahmedragab20.github.io/diffing/docs/guides/agent-handoff/ title: Agent handoff --- # Agent handoff The handoff protocol is **agent waits, human releases** for sync waits, plus a default **async park/resume** path so agents do not burn tokens holding a turn open. ## Async (default) ```text Agent opens review / submits plan → gets URL + nextAction=park → ends turn (no await loop) Human reviews when ready → says "ready" / agent resumes Agent runs one await OR comments --open / get_plan ``` **Do not** silent-loop on timeout. At most one extra await if the human asked you to keep waiting. ## Sync (human at the keyboard) ```bash diffing await-review [--timeout 570] # or MCP await_review ``` Long-poll until **Send to agent**. Default timeout **570s**. ### Exit codes | Code | Meaning | |------|---------| | `0` | OK — payload received | | `2` | Await timeout (expected park signal) | | `3` | No server for this repo | | `4` | Not found (e.g. comment id) | | `5` | Usage error | On timeout, stderr includes `DIFFING_AWAIT_TIMEOUT` and a park hint. ## Discovery No port configuration: ```bash diffing url diffing sessions --json diffing sessions use ``` MCP binds a repository (`diffing mcp [--repo /abs/path]`) and discovers the active lockfile. ## MCP vs CLI | MCP | CLI | |-----|-----| | `await_review` | `diffing await-review` | | `list_comments` | `diffing comments [--open] [--format xml\|json\|md]` | | `reply_to_comment` | `diffing reply` | | `resolve_comment` / `unresolve_comment` | `diffing resolve` / `unresolve` | | `report_progress` | `diffing progress --message "…"` | | `diff_*` | `diffing inspect …` | | Plan tools | `diffing plan …` | | `gh_*` | `diffing gh …` | Full catalog: [MCP tools](/docs/reference/mcp/). ## Comment-only mode If a released handoff has mode `comment-only`, **reply without editing files**. ## Skills ```bash npx skills add ahmedragab20/diffing ``` Skills: `diffing`, `diffing-start-review`, `diffing-finish-review`, `diffing-review`, `diffing-plan-review`, `diffing-pr-read`, `diffing-pr-address`. ## Related - [Code review](/docs/guides/code-review/) - [Plan review](/docs/guides/plan-review/) - [Exit codes](/docs/reference/exit-codes/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/github-pr/ title: GitHub PR review --- # GitHub PR review diffing can mirror a GitHub PR into a local review session (`mode: gh-pr`) so you get the same UI/TUI ergonomics without leaving the machine for reads. ## Open a PR session ```bash diffing --gh-pr 123 diffing --gh-pr owner/repo#123 diffing --gh-pr https://github.com/owner/repo/pull/123 # equivalent: diffing "gh pr 123" ``` Requires `gh` auth (or token) with access to the repository. ## CLI reads ```bash diffing gh status diffing gh overview diffing gh threads diffing gh reviews diffing inspect summary diffing inspect files ``` ## MCP | Tool | Use | |------|-----| | `gh_overview` | PR metadata + summary | | `gh_list_threads` | Conversation threads | | `gh_list_reviews` | Submitted reviews | | `gh_list_draft_comments` | Local drafts | | `gh_create_draft_comment` | Stage a draft locally | | `gh_refresh` | Re-fetch after force-push / new activity | | `gh_submit_review` | **Publish** — requires explicit user authorization | Prefer bounded `diff_summary` → `diff_files` → `diff_hunks` → `diff_slice` over dumping the full patch. ## Authorization rule **Read** freely in a PR session. **Mutate** GitHub (submit review, publish replies) only when the user explicitly authorizes. Tool descriptions mark remote publication accordingly. ## Local vs remote plan tools Plan review tools need a **web** local session. Do not tear down a PR/TUI session just to submit a plan — start or select a compatible web session (`diffing --web --no-open` or `sessions use`). ## Related - [Sessions](/docs/concepts/sessions/) - [MCP tools](/docs/reference/mcp/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/tui/ title: Terminal UI (TUI) --- # Terminal UI (TUI) > **Experimental.** Interface, keymap, and on-disk `mode: "tui"` details may change in a minor release. The **web UI** is the supported path for production workflows. ## Two surfaces | Command | Role | |---------|------| | `diffing view` / `--view` | Focused **read-only** native diff browser (ergonomic `git diff`) | | `diffing --tui` | Full review: comments, handoff, agent loop in-terminal | | `diffing mode tui` | Make full TUI the interactive default | Native binaries ship via optional platform packages on npm install. Fallbacks: source build under `crates/diffing-tui`, or a `diffing-tui` on `$PATH`. ```bash diffing view diffing --tui diffing mode tui diffing mode web # restore web default ``` ## Behavior notes - Shares sparse diff index ideas with headless inspect tools - Publishes a capability-scoped loopback API through the session registry - Web and TUI can run **concurrently** for the same repo - Read-only viewer does **not** register a full review session - Mouse capture configurable (`tuiMouseEnabled` in settings) ## Build from source ```bash pnpm build:tui # or cargo build --release --manifest-path crates/diffing-tui/Cargo.toml ``` ## Design TUI chrome follows [Gridline](/docs/design/gridline/) — same semantic roles as the web adapter. ## Related - [Keyboard](/docs/reference/keyboard/) (web-first; TUI has its own keymap in CLI deep-dive) - [Getting started](/docs/getting-started/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/search/ title: Search --- # Search Search is powered by `@ff-labs/fff-node` (native Rust). If the binary is unavailable for your platform, search reports unavailable — the server does not crash. ## Scopes | Scope | Behavior | |-------|----------| | **Files** | Fuzzy path matching | | **Text** | Grep; optional regex | | **Symbols** | 27 patterns across JS/TS, Go, Rust, Python, PHP | | **All** | Concurrent unified results | Symbol kinds: functions, classes, interfaces, types, enums, variables, structs, impls, traits, methods. ## UI - / — all-scope search (often changed-only) - s — symbol search - g v — file browser - **Changed only** filter restricts to active diff paths ## Limits - Default limit **60**, max **200** - Frecency/history DBs under `~/.diffing/-/fff/` ## HTTP `POST /api/search` with `{ scope, query, limit, regex, changedPaths? }`. Selections can update frecency via `POST /api/search/track`. ## Related - [HTTP API](/docs/reference/http-api/) - [Keyboard](/docs/reference/keyboard/) --- url: https://ahmedragab20.github.io/diffing/docs/guides/setup-and-mcp/ title: Setup & MCP --- # Setup & MCP ## Setup wizard ```bash diffing setup diffing setup --yes diffing setup --check diffing setup skills diffing setup mcp diffing setup mcp --write-mcp diffing setup mcp --write-project-mcp ``` `--write-mcp` merges **only** the `diffing` key into known IDE MCP configs and backs up under `~/.diffing/backups/`. Other servers are preserved. ## Skills ```bash npx skills add ahmedragab20/diffing ``` | Skill | When | | ------- | ------ | | `diffing` | Route any diffing request | | `diffing-start-review` | Launch UI for human | | `diffing-finish-review` | Process handoff comments | | `diffing-review` | Agent posts inline review | | `diffing-plan-review` | Plan gate before code | | `diffing-pr-read` | Bounded PR inspection | | `diffing-pr-address` | Turn PR feedback into local work | ## pi extension ```bash pi install git:github.com/ahmedragab20/diffing pi install npm:diffing ``` The extension lives at `extensions/pi/index.ts` and registers 18 `diffing_*` tools mirroring the MCP catalog — status, start_review, comments, reply/resolve/unresolve, progress, await_review, plan submit/await/list/show/reply/resolve, url, sessions, gh_overview, and a CLI escape hatch. It also adds a `/diffing` command that opens or reuses the review UI and a footer status widget showing the active review session. > **Note:** When pi runs inside the diffing repo itself, `~/.agents/skills/diffing*` should be symlinks to `.agents/skills/*`. pi dedupes skills by realpath, so symlinked entries merge silently with the repo's project skills; the extension self-heals these links to avoid skill-collision warnings. ## MCP server ```bash diffing mcp diffing mcp --repo /absolute/path/to/repo ``` Client config: ```json { "mcpServers": { "diffing": { "command": "diffing", "args": ["mcp"] } } } ``` No port in the config. Repository is `--repo` or the git root of the MCP process cwd. Invalid selection fails instead of guessing. ## First tool calls 1. `review_session_status` — inspect binding / nextAction 2. `start_review_session` — only when needed (idempotent; never replaces user sessions) 3. Then diff inspect, comments, plan, or `gh_*` as appropriate See [MCP tools](/docs/reference/mcp/) for the full 37-tool catalog. ## Doctor & completions ```bash diffing doctor diffing completion zsh diffing completion bash diffing completion fish ``` --- url: https://ahmedragab20.github.io/diffing/docs/reference/cli/ title: CLI reference --- # CLI reference ## Primary command ```bash diffing [options] [...] [-- ...] ``` Drop-in for `git diff` revisions, options, and pathspecs. On a TTY, opens the preferred interactive UI; otherwise prints a unified patch. ### Server / session options | Flag | Description | |------|-------------| | `--port ` | Fixed port; default is a random free port | | `--host ` | Bind address (default `127.0.0.1`) | | `--insecure-no-auth` | Required with non-loopback binds; disables API auth | | `--no-open` | Do not auto-open browser | | `--reuse-session` | Open active session and exit | | `--replace-session` | Stop active, then start with current args | | `--web` | Force web UI | | `--terminal` | Force stdout patch | | `--view` | Read-only native viewer | | `--tui` | Full native review TUI (experimental) | | `--gh-pr ` | GitHub PR session | | `--skip-setup` | Bypass first-run setup gate | | `--staged` / other git flags | Same semantics as `git diff` | ### Git-compatible flag groups Revisions/range · algorithms · whitespace · context · word-diff · renames/copies · output formats · filtering · output control — 60+ flags across 12 categories. Output-format flags force terminal mode. Examples: ```bash diffing --staged diffing HEAD~3 diffing main..feature diffing -w -- src/ diffing --stat # terminal mode ``` ## Subcommands | Command | Role | |---------|------| | `sessions …` | List / use / open / stop live sessions | | `mode [web\|tui]` | Get/set default interactive mode | | `await-review` | Sync wait for Send to agent | | `comments` | Dump comments (XML/JSON/md) | | `reply` / `resolve` / `unresolve` | Thread lifecycle | | `comment edit` / `comment delete` | Mutate threads | | `progress` | Live agent progress toast | | `url` | Active base URL | | `inspect …` | Bounded diff reads | | `plan …` | Plan review loop | | `gh …` | GitHub PR automation | | `mcp` | Stdio MCP server | | `setup` / `init` / `onboard` | First-time wizard | | `doctor` | Environment self-check | | `completion ` | Shell completions | | `update` | Self-upgrade via npm/pnpm | | `view` | Read-only TUI viewer | ### sessions ```bash diffing sessions diffing sessions --json diffing sessions use diffing sessions open [|active] diffing sessions stop |active|all ``` ### mode ```bash diffing mode diffing mode web diffing mode tui ``` Stored as `defaultMode` in settings. Applies only on interactive TTY without an explicit mode flag. ### await-review ```bash diffing await-review [-t|--timeout ] ``` Default timeout **570**. Exit `0` / `2` / `3` / `5`. Prefer async park when the human is not reviewing now. ### comments ```bash diffing comments [--open] [--json] [--format xml|json|md|markdown] ``` ### reply / resolve / unresolve ```bash diffing reply --body [--model ] diffing resolve diffing unresolve ``` Body may be `-` or stdin for `reply`. ### progress ```bash diffing progress --message "Working…" [--model M] [--pct 40] ``` ### url ```bash diffing url ``` ### inspect ```bash diffing inspect summary diffing inspect files diffing inspect hunks --file diffing inspect slice --file [--start R] … diffing inspect search --query "…" ``` Token-efficient alternative to dumping the full patch. Mirrors MCP `diff_*` tools. ### plan ```bash diffing plan submit [|-] [--title T] [--source S] [--model M] [--id ID] [--wait] [--timeout N] [--save-source|-S] diffing plan await [--timeout N] diffing plan list [--json] diffing plan show [] [--version n] [--json] diffing plan versions diffing plan reply --body [--model M] diffing plan resolve ``` ### gh ```bash diffing gh status diffing gh overview diffing gh threads diffing gh reviews # plus pr-fetch / pr-list-comments / pr-review (see deep CLI in repo docs/cli.md) ``` ### mcp ```bash diffing mcp [--repo /abs/path] ``` ### setup / doctor / update ```bash diffing setup [--yes] [--check] [--reset] diffing doctor diffing update diffing completion zsh ``` ## Exit codes See [Exit codes](/docs/reference/exit-codes/). ## Source Deep historical manual: repository `docs/cli.md` (superseded by this site for public docs; retained for cutover). Verified against CLI sources for v0.13.x. --- url: https://ahmedragab20.github.io/diffing/docs/reference/mcp/ title: MCP tools --- # MCP tools Launch: ```bash diffing mcp diffing mcp --repo /absolute/path/to/repository ``` Client snippet: ```json { "mcpServers": { "diffing": { "command": "diffing", "args": ["mcp"] } } } ``` Successful calls return readable text plus schema-validated `structuredContent`. Count verified against `src/mcp.ts` `registerTool` (**37** tools). ## Session | Tool | Purpose | |------|---------| | `review_session_status` | Inspect repo binding and active session; use `nextAction` first | | `start_review_session` | Idempotently start/reuse loopback web session; never replaces user sessions | ## Diff inspection Prefer bounded tools over `get_diff` for large trees. | Tool | Purpose | |------|---------| | `get_diff` | Full patch (use sparingly) | | `diff_summary` | High-level change summary | | `diff_files` | Paged file list | | `diff_hunks` | Hunks for a file | | `diff_slice` | Exact row window with budgets | | `diff_search` | Search within the diff | ## Comments & handoff | Tool | Purpose | |------|---------| | `create_comment` | Inline finding (path, side, line/range, body, optional severity) | | `await_review` | Sync wait for human Send to agent | | `list_comments` | Snapshot threads | | `reply_to_comment` | Agent reply | | `resolve_comment` / `unresolve_comment` | Lifecycle | | `edit_comment` / `delete_comment` | Mutate thread | | `edit_reply` / `delete_reply` | Mutate reply | | `apply_suggestion` | Apply ```` ```suggestion ```` fence | | `resolve_all_comments` | Bulk resolve | | `report_progress` | Live toast | | `get_review_history` | Multi-round history | ## Plan review | Tool | Purpose | |------|---------| | `submit_plan` | Submit markdown (async park default) | | `await_plan_review` | Sync wait for verdict | | `list_plans` | All plans | | `get_plan` | Current plan + comments as XML/data | | `get_plan_versions` | Version metadata | | `get_plan_version` | Historical body | | `reply_to_plan_comment` | Reply | | `resolve_plan_comment` | Resolve thread | ## GitHub PR | Tool | Purpose | |------|---------| | `gh_overview` | PR overview | | `gh_list_threads` | Threads | | `gh_list_reviews` | Reviews | | `gh_list_draft_comments` | Local drafts | | `gh_create_draft_comment` | Create draft | | `gh_refresh` | Re-fetch remote state | | `gh_submit_review` | Publish review (**explicit user auth**) | ## Await semantics `await_review` / `await_plan_review` return `status: "released" | "timeout"`. Timeout includes `disposition: "park"` and `nextAction` — **end the turn**, do not silent-loop. | Mode | When | Action | |------|------|--------| | Async (default) | Human may take a while | Share URL; park | | Sync | Human reviewing now | One await (~570s); on timeout park | ## Prompts & resource - Prompt `review_local_changes` - Prompt `submit_plan_for_review` - Resource `diffing://agent-guide` ## Related - [Agent handoff](/docs/guides/agent-handoff/) - [Setup & MCP](/docs/guides/setup-and-mcp/) --- url: https://ahmedragab20.github.io/diffing/docs/reference/http-api/ title: HTTP API --- # HTTP API All endpoints are on the session base URL from `diffing url` (loopback). Authenticate with session cookie (browser) or `x-diffing-token` (CLI/MCP) on loopback binds. ## Handoff | Method | Path | Role | |--------|------|------| | `POST` | `/api/review/send` | Human releases waiters; increments round | | `GET` | `/api/review/await` | Long-poll (`sinceRound`, `timeoutMs` ≤ 50000) | | `GET` | `/api/review/status` | Round / waiters snapshot | | `GET` | `/api/review/history` | Multi-round history | ### send body ```json { "generalComment": "Optional markdown summary" } ``` ### await response (released) ```json { "status": "released", "round": 4, "payload": { "commentXml": "", "openCount": 2, "comments": [] } } ``` ## Comments | Method | Path | Role | |--------|------|------| | `GET` | `/api/comments` | List threads | | `POST` | `/api/comments` | Create (filePath, side, lineNumber, body, optional startLineNumber, severity) | | `PUT` | `/api/comments/:id` | Edit body or `{ status }` | | `DELETE` | `/api/comments/:id` | Delete | | `POST` | `/api/comments/resolve-all` | Resolve all open | | `POST` | `/api/comments/:id/replies` | Reply | | `PUT` | `/api/comments/:id/replies/:replyId` | Edit reply | | `DELETE` | `/api/comments/:id/replies/:replyId` | Delete reply | | `POST` | `/api/comments/:id/apply-suggestion` | Apply suggestion fence | ## Agent progress | Method | Path | |--------|------| | `POST` | `/api/agent/progress` | | `GET` | `/api/agent/progress` | ```json { "message": "Working…", "model": "…", "pct": 40 } ``` ## Live SSE `GET /api/live` — events: `heartbeat`, `change`, `comments`, `plans`, `agent-status`, `plan-review-status`. ## Search `POST /api/search` — `{ scope, query, limit, regex, changedPaths? }` `POST /api/search/track` — frecency update ## Attachments `POST /api/attachments` (multipart) · `GET /api/attachments/:filename` Stored under per-repo `attachments/`. ## Plans Plan CRUD and comments live under `/api/plans…` (list, get, versions, submit, comments, review status). Prefer CLI/MCP for agents; use HTTP when embedding or debugging. ## Other | Path | Role | |------|------| | `POST /api/open-file` | Launch editor (vscode/zed/vim/neovim/default) | | Git/IDE helpers | Diff options, settings persistence, etc. | Deep endpoint catalog remains in repository `docs/cli.md` §11 for rare routes. ## Related - [Comments XML](/docs/reference/comments-xml/) - [Architecture](/docs/concepts/architecture/) --- url: https://ahmedragab20.github.io/diffing/docs/reference/comments-xml/ title: Comments XML --- # Comments XML Exported via `diffing comments`, `await-review`, MCP list/await tools, and UI clipboard. ## Elements | Element | Role | |---------|------| | `` | Root | | `` | Self-documenting agent instructions | | `` | Optional round-level markdown (CDATA) | | `` | Groups threads per path | | `` | Thread — attrs below | | `` | Optional line context (`+`/`-` prefixes) | | `` | Markdown (CDATA) | | `` / `` | Thread replies | ### comment attributes | Attr | Values | |------|--------| | `id` | UUID | | `line` | `"15"` · `"10-15"` (inclusive) · `"file"` | | `side` | `additions` \| `deletions` | | `status` | `open` \| `resolved` | | `severity` | optional `blocking` \| `nit` \| `question` \| `praise` | | `created-at` | ISO-8601 | ### reply attributes | Attr | Values | |------|--------| | `id` | UUID | | `role` | `user` \| `agent` | | `model` | set when role is agent | | `created-at` | ISO-8601 | ## Example ```xml ``` ## Severity policy for agents | Severity | Action | |----------|--------| | `blocking` | Must address before resolve | | `nit` | Optional | | `question` | Answer; usually leave open | | `praise` | No code change | | omitted | Treat as normal open request | --- url: https://ahmedragab20.github.io/diffing/docs/reference/keyboard/ title: Keyboard shortcuts --- # Keyboard shortcuts Multi-key sequences use an **800 ms** buffer. A vim-style status bar shows **NORMAL** / **INSERT**; single-key shortcuts are disabled while typing in inputs. ## Scrolling & diffs | Key | Action | |-----|--------| | j / k | Scroll down / up (100px) | | Ctrl+d / Ctrl+u | Half-page down / up | | g g | Jump to top | | G | Jump to bottom | | m | Toggle split / unified | | t | Cycle tab size (2 → 4 → 8) | | w | Toggle line wrap | | n | Toggle line numbers | | i | Cycle diff indicators | | I | Cycle inline diff type | | Cmd+Shift+P | Toggle comment preview | ## Files & UI | Key | Action | |-----|--------| | J / K | Next / previous file | | v | Toggle file viewed | | b | Toggle sidebar | | / | All-scope search | | s | Symbol search | | g v | File browser | | g t | **Theme picker** | | Cmd/Ctrl+K | Command palette | | ? | Shortcuts help | > **Do not confuse:** t is **tab size**, not themes. Themes open with g t. ## Plan page (`/plan`) | Key | Action | |-----|--------| | m | Source → Read → Split | | z | Zen Read | | e | Live plan edit | | ⌘/Ctrl+S | Flush autosave while editing | | o | Outline | | c | Comments map | | J / K | Next / previous plan | | Esc | Discard / exit zen / dismiss composer | ## TUI The experimental TUI has its own keymap (vim-style). See repository `docs/cli.md` §4d for the full TUI table while the site stays web-authoritative. --- url: https://ahmedragab20.github.io/diffing/docs/reference/settings/ title: Settings --- # Settings ## Location ```text ~/.config/diffing/settings.json ``` Per-repo UI session state (panel sizes, drafts, etc.) lives under `~/.diffing/-/` — **not** browser localStorage. ## Common keys Defaults may evolve; inspect your file or product source for the latest schema. Representative fields: | Key | Role | | ----- | ------ | | `defaultMode` | `"web"` \| `"tui"` interactive default | | `theme` | Theme id (default **`rose-pine`**) | | `diffStyle` | `"split"` \| `"unified"` | | `defaultTabSize` | Fallback tab width (editorconfig wins) | | `editorIDE` | `default` \| `vscode` \| `zed` \| `vim` \| `neovim` \| `ghostty` | | `lineDiffType` | `word` \| `word-alt` \| `char` \| `none` | | `lineWrap` | boolean | | `diffIndicators` | `classic` \| `bars` \| `none` | | `showLineNumbers` | boolean | | `tuiMouseEnabled` | boolean | | `fontSize` | base code font size (px) | | `haptics` | sounds / haptics in web UI | | `setupCompletedAt` | first-run wizard marker | | `staged` / `untracked` | default inclusion toggles | ## Theme Change in UI with g t or settings. 52 themes — see [Themes](/docs/design/themes/). ## Mode ```bash diffing mode web diffing mode tui ``` --- url: https://ahmedragab20.github.io/diffing/docs/reference/exit-codes/ title: Exit codes --- # Exit codes | Code | Meaning | Typical commands | |------|---------|------------------| | `0` | Success | Most commands | | `2` | Await **timeout** (park — not a crash) | `await-review`, `plan await` | | `3` | No active server for this repository | Agent cmds needing lockfile | | `4` | Resource not found (comment/plan id) | `reply`, `resolve`, … | | `5` | Usage / invalid arguments | Any | ## Await timeout policy Exit `2` means the wait budget elapsed (default **570s**). Agents should: 1. Treat it as `disposition=park` 2. **End the turn** (async resume later) 3. Re-await only if the human asked to keep waiting — never silent-loop ## Shell example ```bash diffing await-review case $? in 0) echo "review received" ;; 2) echo "park — human not done" ;; 3) echo "start diffing first" ;; *) echo "error $?" ;; esac ``` --- url: https://ahmedragab20.github.io/diffing/docs/design/gridline/ title: Gridline --- # Gridline **Gridline** is diffing's shared visual language. The Rust TUI defines the original semantic contract; the browser adapter lives in `src/ui/styles/gridline.css`. This docs site mirrors the same principles. ## Product character The browser should feel like a **terminal workspace** with richer input — not a dashboard decorated with mono fonts. Hierarchy comes from type, alignment, density, and one-pixel rules. Persistent surfaces stay flat. Color communicates **state**, not ornament. ## Invariants - No glass, blur, glow, gradient, or hover elevation on persistent chrome - Square or shallow corners (2px controls; 4px overlays max) - Accent rails only for active navigation / keyboard focus - Pills only for compact status/count data - UI and code are mono-first (Geist Mono + JetBrains Mono) - Themes supply values; components consume semantic roles (`--gl-*`) ## Semantic roles Surfaces: `canvas`, `surface`, `raised`, `element`, `selected` Text: `text`, `text-subtle`, `muted`, `code`, `gutter` Structure: `rule-subtle`, `rule`, `focus` Feedback: `info`, `positive`, `warning`, `negative` Diff: `added-surface`, `removed-surface` Geometry: 4px unit · 44px app bar · 28px controls · 24px compact. ## Component recipes (summary) - **Toolbar** — solid 44px status strip, rectangular controls - **Sidebar** — flat pane, one rule divider - **Diff file** — edge-defined pane, quiet header - **Comments** — status dots for lifecycle; neutral card border - **Modal** — raised surface + single overlay shadow - **Vim status** — viewport-edge line, not a floating glass pill ## TUI notes Density is deliberate (one cell base unit). Focus is local — not a full panel accent rectangle. Status strip owns key hints; help overlay is the full reference. See repository `docs/tui-design-system.md` for full TUI recipes. ## Related - [Themes](/docs/design/themes/) - Repo: `docs/design-system.md`, `docs/tui-design-system.md` --- url: https://ahmedragab20.github.io/diffing/docs/design/themes/ title: Themes --- # Themes diffing ships **52** themes (counted from `ThemeModal.tsx`). Default: **`rose-pine`**. ## Switch theme - Keyboard: g t - Settings UI / toolbar - Persist: `theme` in `~/.config/diffing/settings.json` > t alone cycles **tab size**, not themes. ## Catalog | Id | Notes | |----|-------| | `nord` | | | `github-dark`, `github-dark-dimmed`, `github-dark-high-contrast` | | | `github-light`, `github-light-high-contrast` | | | `dracula`, `one-dark`, `synthwave-84`, `tokyo-night` | | | `catppuccin-mocha`, `catppuccin-frappe`, `catppuccin-macchiato`, `catppuccin-latte` | | | `solarized-dark`, `solarized-light` | | | `monokai`, `ayu-dark`, `ayu-light` | | | `nightfox`, `nordfox`, `duskfox`, `terafox`, `carbonfox`, `dayfox`, `dawnfox` | Nightfox family | | `andromeeda`, `aurora-x`, `dark-plus`, `light-plus`, `houston`, `laserwave` | | | `material-theme`, `material-theme-darker`, `material-theme-lighter`, `material-theme-ocean`, `material-theme-palenight` | | | `min-dark`, `min-light`, `night-owl`, `one-light`, `plastic`, `poimandres` | | | `rose-pine`, `rose-pine-moon`, `rose-pine-dawn` | Default family | | `slack-dark`, `slack-ochre` | | | `vesper`, `vitesse-black`, `vitesse-dark`, `vitesse-light` | | Syntax highlighting uses Shiki via `@pierre/diffs` with dark/light pairs mapped per theme. ## Gridline requirement Every theme must keep primary text readable and focus color visible. Components consume `--gl-*` roles derived from the theme palette.