Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

157 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

diffdeck

English | ν•œκ΅­μ–΄ | ζ—₯本θͺž | δΈ­ζ–‡ | EspaΓ±ol

A local diff viewer, built on a vendored fork of Pierre's @pierre/diffs and @pierre/trees.

npm TypeScript Bun License

diffdeck demo β€” scrolling a large diff, jumping to a file from the tree, click-to-fold, in-app search, and split view

What is this?

diffdeck is the local diff viewer originally embedded in cc-statusline, extracted into its own product. Instead of depending on the upstream Pierre packages β€” which move fast (@pierre/diffs churns heavily; @pierre/trees is pre-1.0 beta) and whose internal markup we had already coupled to heavily β€” diffdeck recovers the original TypeScript from the packages' source maps and vendors it, so we own the rendering engine outright.

The result is a Bun-workspace monorepo where a commodity-hard, framework-agnostic diff engine (Pierre's CodeView, the ~29.5k lines of packages/diffs) is kept as-is, while the parts we customize live in our own code.

Features

What the diff-rendering engine provides:

  • Syntax-highlighted diffs via Shiki with TextMate themes (light + dark).
  • Full old/new file diffs, not just patches β€” so unchanged context can be collapsed and expanded on demand.
  • Unified and split layouts.
  • File-tree sidebar with git-status badges, natural sort, and flatten (compacting single-child folder chains).
  • Image diffs β€” changed binary images render inline with old/new panels.
  • Virtualized rendering that stays smooth on large diffs, with sticky file headers.
  • Shadow-DOM encapsulation per file, so the viewer's styles never leak into the page.

The interactive viewer chrome that wraps this engine β€” click-to-fold, copy-path, in-app search, watch/auto-refresh, and working-tree-vs-base modes β€” comes from the cc-statusline viewer and now lives in diffdeck's apps/viewer/.

The diffdeck viewer β€” file tree with git-status badges, an inline image diff, and syntax-highlighted diffs

Grab β€” hand a diff selection to your coding agent

Select code in the diff and a prompt box opens right where you released the drag. Press Enter and diffdeck copies one block to your clipboard β€” the file reference, the exact lines you picked, and your prompt β€” ready to paste into Claude Code, Codex, or any chat.

Grab β€” lines highlighted in the diff with the prompt box open beside them

Two ways in: drag the code text, or use the gutter's line selection and its + button. A text drag copies exactly the characters you highlighted; the gutter path takes whole lines. Either way the highlight shows precisely what will be copied.

What lands on your clipboard:

```
diffdeck selection
File: apps/viewer/browser/main.ts
Lines: 84-85 (new side, working diff)

if (a) return;
const b = 1;
```
why was this needed?

Installation

Run it on demand β€” no install needed:

bunx @say8425/diffdeck

Or install it globally to get the diffdeck command:

bun install -g @say8425/diffdeck

Requires Bun; git (and gh for branch-vs-base detection) on your PATH.

CLI

Run it in any git repository to view its diff:

bunx @say8425/diffdeck        # or `diffdeck` if installed globally

This starts a local server on 127.0.0.1:49573 (override with --port) and opens the viewer in your browser.

Options:

Flag Description
--port <n> Port to serve on (default: $DIFFDECK_PORT or 49573)
--no-open Do not open a browser automatically (prints the URL)
--untracked Start with untracked files included
--watch Start with watch (auto-refresh) on
--no-flatten Start with the file tree un-flattened (flatten is on by default)
--tree-right Start with the file tree on the right
--split Start in split view (unified is the default)
--hide-tree Start with the file tree hidden
--fold-with-tree Start with sidebar directory collapse synced to diff folds
-h, --help Show help
-v, --version Show version

These view flags set the initial state for this launch only β€” they don't change your saved preferences, and the in-app toggles reflect the launched state.

Environment: DIFFDECK_PORT sets the default port. The token is cached under $XDG_CACHE_HOME/diffdeck/, or ~/.cache/diffdeck/ when that is unset.

Skills

diffdeck ships an agent skill (a single skills/diffdeck/SKILL.md) so an AI coding agent can open the diff viewer in your browser when a change is easier to see than to read. Install it into your agent through one of the channels below.

The plugin and npx skills channels fetch from GitHub, so they need the repository to be public and diffdeck published to npm (so the skill's bunx @say8425/diffdeck resolves). The self-contained diffdeck install-skill works from any local install.

Claude Code

Plugin:

/plugin marketplace add say8425/diffdeck
/plugin install diffdeck@diffdeck

Or self-contained (writes ~/.claude/skills/diffdeck/):

diffdeck install-skill        # --project installs into the current repo instead

Codex

Plugin:

codex plugin marketplace add say8425/diffdeck
codex plugin add diffdeck@diffdeck

Or self-contained (writes ~/.claude/skills/diffdeck/ and ~/.agents/skills/diffdeck/):

diffdeck install-skill --codex

skills

Install into any supported agent with the skills CLI:

npx skills add say8425/diffdeck

The codex / npx skills subcommands are young β€” check codex plugin --help / npx skills --help for your version.

Architecture

packages/
  path-store/   @diffdeck/path-store   pure tree logic (flatten, sort, projection, store)
  theming/      @diffdeck/theming      theme system + 10 vendored shiki theme JSONs
  diffs/        @diffdeck/diffs         CodeView diff-rendering engine
  trees/        @diffdeck/trees         FileTree engine (vanilla render)
apps/viewer/    @say8425/diffdeck β€” CLI + diff-server (data API) + browser viewer
skills/         the agent skill (SKILL.md), copied into the package at build time
scripts/        source-map extraction tool, css-inline Bun plugin, render-parity harness
docs/           README translations and screenshots

Dependency graph: path-store (no deps) ← trees; theming (shiki) ← diffs, trees. Runtime externals: shiki + @shikijs/*, diff, hast-util-to-html, lru_map β€” these are the packages' own dependencies; the published CLI bundles everything, so nothing is resolved at install time.

Development

Requires Bun.

bun install
bun run typecheck   # per-package tsc
bun test
bun run lint        # oxlint
bun run format      # oxfmt

Testing

Three lanes:

  • bun test β€” unit/integration tests, fast. *.e2e.ts specs are excluded from collection, so this never launches a browser.
  • bun run test:coverage β€” the same suite with a 100% coverage gate on diffdeck's owned runtime code (apps/viewer/{browser,cli,server}). Intentionally out of the gate: the vendored packages/*, the tooling under scripts/, the browser entry main.ts (integration entry β€” exercised by the e2e suite instead, not in-process), build.ts, and the specs themselves (*.test.ts, e2e/**).
  • bun run test:e2e β€” the Playwright real-browser suite (apps/viewer/e2e/). Drives the system Google Chrome via channel: "chrome" (no Chromium download) and covers main.ts and the vendored render paths end-to-end.

Render-parity harness

Confirms the forked CodeView + FileTree actually render:

bun run scripts/parity/build.ts
cd scripts/parity && python3 -m http.server 8099
# open http://127.0.0.1:8099/index.html

License

Apache-2.0. diffdeck vendors source derived from Pierre's @pierre/* packages (Apache-2.0, Β© The Pierre Computer Company), modified under the @diffdeck/* namespace. See NOTICE and each package's LICENSE for full attribution and the required notice of modification.

About

πŸ–‹οΈ Local diff viewer β€” forked & vendored from @pierre/diffs + @pierre/trees (Apache-2.0). Monorepo foundation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages