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