hunkdiff 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +110 -218
  2. package/bin/hunk.cjs +3 -1
  3. package/package.json +7 -7
package/README.md CHANGED
@@ -1,295 +1,187 @@
1
- # hunk
1
+ <img width="384" height="384" alt="image" src="https://github.com/user-attachments/assets/85c5ba93-9de1-4757-87ae-4520b8fd659f" />
2
2
 
3
- <p align="center">
4
- <a href="https://github.com/modem-dev/hunk/actions/workflows/ci.yml?branch=main"><img src="https://img.shields.io/github/actions/workflow/status/modem-dev/hunk/ci.yml?branch=main&style=for-the-badge&label=CI" alt="CI status"></a>
5
- <a href="https://github.com/modem-dev/hunk/releases"><img src="https://img.shields.io/github/v/release/modem-dev/hunk?style=for-the-badge" alt="Latest release"></a>
6
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge" alt="MIT License"></a>
7
- </p>
3
+ # hunk - TUI diff tool that's AI-friendly
8
4
 
9
- Hunk is a terminal diff viewer for reviewing agent-authored changesets with a desktop-style UI.
5
+ [![CI status](https://img.shields.io/github/actions/workflow/status/modem-dev/hunk/ci.yml?branch=main&style=for-the-badge&label=CI)](https://github.com/modem-dev/hunk/actions/workflows/ci.yml?branch=main)
6
+ [![Latest release](https://img.shields.io/github/v/release/modem-dev/hunk?style=for-the-badge)](https://github.com/modem-dev/hunk/releases)
7
+ [![MIT License](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](LICENSE)
10
8
 
9
+ Hunk is a desktop-inspired terminal diff viewer for reviewing agent-authored changesets.
10
+
11
+ - AI annotations
11
12
  - full-screen multi-file review stream
13
+ - keyboard & mouse support
12
14
  - split, stacked, and responsive auto layouts
13
- - keyboard and mouse navigation
14
- - optional agent rationale beside annotated hunks
15
15
  - Git pager and difftool integration
16
16
 
17
+ <table>
18
+ <tr>
19
+ <td width="60%" align="center">
20
+ <img width="794" alt="image" src="https://github.com/user-attachments/assets/f6ffd9c4-67f5-483c-88f1-cbe88c19f52f" />
21
+ <br />
22
+ <sub>Split view with sidebar and inline AI notes</sub>
23
+ </td>
24
+ <td width="40%" align="center">
25
+ <img width="508" height="920" alt="image" src="https://github.com/user-attachments/assets/44c542a2-0a09-41cd-b264-fbd942e92f06" />
26
+ <br />
27
+ <sub>Stacked view and mouse-selectable menus
28
+ </td>
29
+ </tr>
30
+ </table>
31
+
17
32
  ## Install
18
33
 
19
34
  ```bash
20
35
  npm i -g hunkdiff
21
36
  ```
22
37
 
23
- ## Requirements
38
+ Requirements:
24
39
 
25
40
  - Node.js 18+
26
- - Git for `hunk diff`, `hunk show`, `hunk stash show`, and pager integration
41
+ - Currently supported on macOS and Linux
42
+ - Git is recommended for most workflows
27
43
 
28
- ## Quick start
44
+ ## Usage
29
45
 
30
- Review your current working tree:
46
+ ### Basics
31
47
 
32
48
  ```bash
33
- hunk diff
49
+ hunk # show help
50
+ hunk --version # get version
34
51
  ```
35
52
 
36
- Review staged changes:
53
+ ### Working with Git
37
54
 
38
55
  ```bash
56
+ hunk diff # review current repo changes
39
57
  hunk diff --staged
58
+ hunk show # review the latest commit
59
+ hunk show HEAD~1 # review an earlier commit
40
60
  ```
41
61
 
42
- Review a commit:
62
+ ### Working with raw files/patches
43
63
 
44
64
  ```bash
45
- hunk show HEAD~1
65
+ hunk diff before.ts after.ts # compare two files directly
66
+ git diff --no-color | hunk patch - # review a patch from stdin
46
67
  ```
47
68
 
48
- Compare two files directly:
49
-
50
- ```bash
51
- hunk diff before.ts after.ts
52
- ```
69
+ ## Feature comparison
53
70
 
54
- Open a patch from stdin:
71
+ | Capability | hunk | difftastic | delta | diff |
72
+ | ----------------------------------------------------------- | ---- | ---------- | ----- | ---- |
73
+ | Dedicated interactive review UI | ✅ | ❌ | ❌ | ❌ |
74
+ | Multi-file review stream with navigation sidebar | ✅ | ❌ | ❌ | ❌ |
75
+ | Agent / AI rationale sidecar | ✅ | ❌ | ❌ | ❌ |
76
+ | Split diffs | ✅ | ✅ | ✅ | ✅ |
77
+ | Stacked diffs | ✅ | ✅ | ✅ | ✅ |
78
+ | Auto responsive layouts | ✅ | ❌ | ❌ | ❌ |
79
+ | Themes | ✅ | ❌ | ✅ | ❌ |
80
+ | Syntax highlighting | ✅ | ✅ | ✅ | ❌ |
81
+ | Syntax-aware / structural diffing | ❌ | ✅ | ❌ | ❌ |
82
+ | Mouse support inside the diff viewer | ✅ | ❌ | ❌ | ❌ |
83
+ | Runtime toggles for wrapping / line numbers / hunk metadata | ✅ | ❌ | ❌ | ❌ |
84
+ | Pager-compatible mode | ✅ | ✅ | ✅ | ✅ |
55
85
 
56
- ```bash
57
- git diff --no-color | hunk patch -
58
- ```
86
+ ## Git integration
59
87
 
60
- ## Feature comparison
88
+ You can set Hunk as your Git pager so `git diff` and `git show` open in Hunk automatically.
61
89
 
62
- | Capability | hunk | difftastic | delta | diff |
63
- | --- | --- | --- | --- | --- |
64
- | Dedicated interactive review UI | ✅ | ❌ | ❌ | ❌ |
65
- | Multi-file review stream with navigation sidebar | ✅ | ❌ | ❌ | ❌ |
66
- | Agent / AI rationale sidecar | ✅ | ❌ | ❌ | ❌ |
67
- | Split diffs | ✅ | ✅ | ✅ | ✅ |
68
- | Stacked diffs | ✅ | ✅ | ✅ | ✅ |
69
- | Auto responsive layouts | ✅ | ❌ | ❌ | ❌ |
70
- | Themes | ✅ | ❌ | ✅ | ❌ |
71
- | Syntax highlighting | ✅ | ✅ | ✅ | ❌ |
72
- | Syntax-aware / structural diffing | ❌ | ✅ | ❌ | ❌ |
73
- | Mouse support inside the diff viewer | ✅ | ❌ | ❌ | ❌ |
74
- | Runtime toggles for wrapping / line numbers / hunk metadata | ✅ | ❌ | ❌ | ❌ |
75
- | Pager-compatible mode | ✅ | ✅ | ✅ | ✅ |
76
-
77
- ## Benchmarks
78
-
79
- Quick local timing snapshot from one Linux machine on the same 120-line TypeScript file pair. Metric: time until a changed marker first became visible.
80
-
81
- | Tool | Avg first-visible changed output |
82
- | --- | ---: |
83
- | `diff` | ~37 ms |
84
- | `delta --paging=never` | ~35 ms |
85
- | `hunk diff` | ~219 ms |
86
- | `difft --display side-by-side` | ~266 ms |
87
-
88
- Takeaway:
89
-
90
- - `diff` and `delta` are fastest here because they print plain diff text and exit.
91
- - `hunk` spends more startup time on an interactive UI, syntax highlighting, navigation state, and optional agent context.
92
- - `difftastic` spends more startup time on structural diffing.
93
-
94
- ## Common workflows
95
-
96
- - `hunk` — print CLI help
97
- - `hunk diff` — review working tree changes
98
- - `hunk diff --staged` / `hunk diff --cached` — review staged changes
99
- - `hunk diff <ref>` — review changes versus a branch, tag, or commit-ish
100
- - `hunk diff <ref1>..<ref2>` / `hunk diff <ref1>...<ref2>` — review Git ranges
101
- - `hunk diff -- <pathspec...>` — limit review to selected paths
102
- - `hunk show [ref]` — review the last commit or a specific ref
103
- - `hunk stash show [ref]` — review a stash entry
104
- - `hunk patch [file|-]` — review a patch file or stdin
105
- - `hunk pager` — act as a Git pager wrapper, opening Hunk for diff-like stdin and falling back to plain text paging otherwise
106
- - `hunk difftool <left> <right> [path]` — integrate with Git difftool
107
- - `hunk mcp serve` — run the local MCP daemon for agent-to-diff communication
108
-
109
- ## MCP daemon (experimental)
110
-
111
- Hunk can run a local MCP daemon that brokers commands to live Hunk TUI sessions.
112
-
113
- Opening a normal Hunk review session now tries to register with the daemon automatically and will auto-start it on loopback when needed. You can still run the daemon explicitly:
90
+ From the terminal:
114
91
 
115
92
  ```bash
116
- hunk mcp serve
93
+ git config --global core.pager "hunk pager"
117
94
  ```
118
95
 
119
- Current v1 scope:
120
-
121
- - local loopback daemon only
122
- - live session discovery via `list_sessions` / `get_session`
123
- - inline diff comments via `comment`
124
- - Linux-first implementation, designed to stay portable to macOS later
96
+ Or in your Git config:
125
97
 
126
- Environment variables:
127
-
128
- - `HUNK_MCP_HOST` bind host for the daemon and session clients, default `127.0.0.1`
129
- - `HUNK_MCP_PORT` — bind port for the daemon and session clients, default `47657`
130
- - `HUNK_MCP_DISABLE=1` — disable background session registration for one Hunk process
131
-
132
- ## Interaction
133
-
134
- - `1` split view
135
- - `2` stacked view
136
- - `0` auto layout
137
- - `t` cycle themes
138
- - `a` toggle the agent panel
139
- - `l` toggle line numbers
140
- - `w` toggle line wrapping
141
- - `m` toggle hunk metadata
142
- - `[` / `]` move between hunks
143
- - `space` / `b` page forward and backward
144
- - `/` focus the file filter
145
- - `tab` cycle focus regions
146
- - `q` or `Esc` quit
147
-
148
- ## Git integration
98
+ ```ini
99
+ [core]
100
+ pager = hunk pager
101
+ ```
149
102
 
150
- Use Hunk directly for full-screen review:
103
+ If you’d rather keep Git’s default `diff` and `show` behavior, you can add optional aliases instead:
151
104
 
152
105
  ```bash
153
- hunk diff
154
- hunk diff --staged
155
- hunk diff main...feature
156
- hunk show
157
- hunk stash show
106
+ git config --global alias.hdiff "-c core.pager=\"hunk pager\" diff"
107
+ git config --global alias.hshow "-c core.pager=\"hunk pager\" show"
158
108
  ```
159
109
 
160
- Use Hunk as a pager for `git diff` and `git show`:
110
+ ## Examples
161
111
 
162
- ```bash
163
- git config --global core.pager 'hunk patch -'
164
- ```
112
+ Ready-to-run demo diffs live in [`examples/`](examples/README.md).
165
113
 
166
- Or scope it just to diff/show:
114
+ Each example includes the exact command to run from the repository root.
167
115
 
168
- ```bash
169
- git config --global pager.diff 'hunk patch -'
170
- git config --global pager.show 'hunk patch -'
171
- ```
116
+ ## Agent skill
172
117
 
173
- Use Hunk as a Git difftool:
118
+ Hunk ships a bundled agent skill named `hunk-review` in `skills/hunk-review/SKILL.md`.
174
119
 
175
- ```bash
176
- git config --global diff.tool hunk
177
- git config --global difftool.hunk.cmd 'hunk difftool "$LOCAL" "$REMOTE" "$MERGED"'
178
- ```
120
+ It is written as a self-contained skill for skill-aware coding agents. The skill teaches an agent to:
179
121
 
180
- ## Configuration
122
+ - briefly explain what Hunk is
123
+ - prefer `hunk session ...` when a live Hunk review window already exists
124
+ - inspect current review focus before navigating blindly
125
+ - use `hunk session reload` to swap what an existing live session is showing
126
+ - leave concise inline review comments tied to real diff lines
181
127
 
182
- Hunk reads layered TOML config with this precedence:
128
+ If your coding agent supports packaged or repo-local skills, point it at this repository or copy the `skills/hunk-review/` directory into that agent's skill search path.
183
129
 
184
- 1. built-in defaults
185
- 2. global config: `$XDG_CONFIG_HOME/hunk/config.toml` or `~/.config/hunk/config.toml`
186
- 3. repo-local config: `.hunk/config.toml`
187
- 4. command-specific sections like `[diff]`, `[show]`, `[stash-show]`, `[patch]`, `[difftool]`
188
- 5. `[pager]` when Hunk is running in pager mode
189
- 6. explicit CLI flags
130
+ ## Config
131
+
132
+ Hunk reads config from:
133
+
134
+ - `~/.config/hunk/config.toml`
135
+ - `.hunk/config.toml`
190
136
 
191
137
  Example:
192
138
 
193
139
  ```toml
194
- theme = "midnight"
195
- mode = "auto"
140
+ theme = "graphite" # graphite, midnight, paper, ember
141
+ mode = "auto" # auto, split, stack
196
142
  line_numbers = true
197
143
  wrap_lines = false
198
- hunk_headers = true
199
144
  agent_notes = false
200
-
201
- [pager]
202
- mode = "stack"
203
- line_numbers = false
204
-
205
- [diff]
206
- mode = "split"
207
145
  ```
208
146
 
209
- Supported one-off CLI overrides:
210
-
211
- - `--mode <auto|split|stack>`
212
- - `--theme <theme>`
213
- - `--line-numbers` / `--no-line-numbers`
214
- - `--wrap` / `--no-wrap`
215
- - `--hunk-headers` / `--no-hunk-headers`
216
- - `--agent-notes` / `--no-agent-notes`
217
-
218
- ## Agent context sidecar
219
-
220
- Use `--agent-context <file>` to load a JSON sidecar and show agent rationale next to the diff.
221
-
222
- The order of `files` in the sidecar is significant. Hunk uses that order for the sidebar and the main review stream so an agent can present a review narrative instead of raw patch order.
223
-
224
- ```json
225
- {
226
- "version": 1,
227
- "summary": "High-level change summary from the agent.",
228
- "files": [
229
- {
230
- "path": "src/core/loaders.ts",
231
- "summary": "Normalizes git and patch inputs into one changeset model.",
232
- "annotations": [
233
- {
234
- "newRange": [120, 156],
235
- "summary": "Adds the patch loader entrypoint.",
236
- "rationale": "Keeps all diff sources flowing through one normalized shape.",
237
- "tags": ["parser", "architecture"],
238
- "confidence": "high"
239
- }
240
- ]
241
- }
242
- ]
243
- }
244
- ```
147
+ ## Advanced workflows
245
148
 
246
- For local agent-driven review, keep a transient sidecar at `.hunk/latest.json` and load it with:
149
+ - `hunk diff --agent-context <file>` loads inline agent rationale from a JSON sidecar
150
+ - `hunk mcp serve` runs the local Hunk session daemon and websocket broker for manual startup or debugging
151
+ - normal Hunk sessions auto-start/register with it by default
152
+ - coding agents should usually interact through `hunk session ...`, not by managing the daemon directly
153
+ - Hunk keeps the daemon loopback-only by default
154
+ - if you intentionally need remote access, set `HUNK_MCP_UNSAFE_ALLOW_REMOTE=1` and choose a non-loopback `HUNK_MCP_HOST`
247
155
 
248
- ```bash
249
- hunk diff --agent-context .hunk/latest.json
250
- ```
156
+ ### Live session control CLI
251
157
 
252
- ## Development
158
+ `hunk session ...` is the user-facing and agent-facing interface to Hunk's local live review session daemon.
253
159
 
254
- Install dependencies:
160
+ Use explicit session targeting with either a live `<session-id>` or `--repo <path>` when exactly one live session matches that repo root.
255
161
 
256
162
  ```bash
257
- bun install
163
+ hunk session list
164
+ hunk session context --repo .
165
+ hunk session navigate --repo . --file README.md --hunk 2
166
+ hunk session reload --repo . -- diff
167
+ hunk session reload --repo . -- show HEAD~1 -- README.md
168
+ hunk session comment add --repo . --file README.md --new-line 103 --summary "Frame this as MCP-first"
169
+ hunk session comment list --repo .
170
+ hunk session comment rm --repo . <comment-id>
171
+ hunk session comment clear --repo . --file README.md --yes
258
172
  ```
259
173
 
260
- Validate a change:
174
+ `hunk session reload ... -- <hunk command>` swaps the live session to a new `diff`, `show`, or other reviewable Hunk input without opening a new TUI window.
261
175
 
262
- ```bash
263
- bun run typecheck
264
- bun test
265
- bun run test:tty-smoke
266
- ```
267
-
268
- Build the npm runtime bundle used for publishing:
269
-
270
- ```bash
271
- bun run build:npm
272
- bun run check:pack
273
- ```
176
+ The session CLI can inspect, navigate, annotate, and reload a live session, but it does not edit `.hunk/latest.json`.
274
177
 
275
- Stage the prebuilt npm packages for the current host and smoke test the install path without Bun on `PATH`:
178
+ ## Performance notes
276
179
 
277
- ```bash
278
- bun run build:prebuilt:npm
279
- bun run check:prebuilt-pack
280
- bun run smoke:prebuilt-install
281
- ```
282
-
283
- Prepare the multi-platform release directories from downloaded build artifacts and dry-run the publish order:
180
+ Hunk spends more startup time than plain diff output tools because it launches an interactive UI with syntax highlighting, navigation state, and optional agent context. In exchange, it is optimized for reviewing a full changeset instead of printing static diff text and exiting.
284
181
 
285
- ```bash
286
- bun run build:prebuilt:artifact
287
- bun run stage:prebuilt:release
288
- bun run check:prebuilt-pack
289
- bun run publish:prebuilt:npm -- --dry-run
290
- ```
182
+ ## Contributing
291
183
 
292
- The automated tag/manual release workflow lives in `.github/workflows/release-prebuilt-npm.yml`.
184
+ For source setup, tests, packaging checks, and repo architecture, see [CONTRIBUTING.md](CONTRIBUTING.md).
293
185
 
294
186
  ## License
295
187
 
package/bin/hunk.cjs CHANGED
@@ -111,7 +111,9 @@ if (bunBinary) {
111
111
  run(bunBinary, [entrypoint, ...process.argv.slice(2)]);
112
112
  }
113
113
 
114
- const printablePackages = hostCandidates().map((candidate) => `"${candidate.packageName}"`).join(" or ");
114
+ const printablePackages = hostCandidates()
115
+ .map((candidate) => `"${candidate.packageName}"`)
116
+ .join(" or ");
115
117
  console.error(
116
118
  printablePackages.length > 0
117
119
  ? `Failed to locate a matching prebuilt Hunk binary. Try reinstalling hunkdiff or manually installing ${printablePackages}.`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hunkdiff",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Desktop-inspired terminal diff viewer for understanding agent-authored changesets.",
5
5
  "bin": {
6
6
  "hunk": "./bin/hunk.cjs"
@@ -11,12 +11,12 @@
11
11
  "LICENSE"
12
12
  ],
13
13
  "keywords": [
14
+ "ai",
15
+ "code-review",
14
16
  "diff",
15
17
  "git",
16
- "tui",
17
18
  "terminal",
18
- "code-review",
19
- "ai"
19
+ "tui"
20
20
  ],
21
21
  "repository": {
22
22
  "type": "git",
@@ -30,9 +30,9 @@
30
30
  "node": ">=18"
31
31
  },
32
32
  "optionalDependencies": {
33
- "hunkdiff-darwin-arm64": "0.4.0",
34
- "hunkdiff-darwin-x64": "0.4.0",
35
- "hunkdiff-linux-x64": "0.4.0"
33
+ "hunkdiff-darwin-arm64": "0.5.1",
34
+ "hunkdiff-darwin-x64": "0.5.1",
35
+ "hunkdiff-linux-x64": "0.5.1"
36
36
  },
37
37
  "license": "MIT",
38
38
  "publishConfig": {