hunkdiff 0.1.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/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/npm/highlights-eq9cgrbb.scm +604 -0
- package/dist/npm/highlights-ghv9g403.scm +205 -0
- package/dist/npm/highlights-hk7bwhj4.scm +284 -0
- package/dist/npm/highlights-r812a2qc.scm +150 -0
- package/dist/npm/highlights-x6tmsnaa.scm +115 -0
- package/dist/npm/injections-73j83es3.scm +27 -0
- package/dist/npm/main.js +88048 -0
- package/dist/npm/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/npm/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/npm/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/npm/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/npm/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Ben Vinegar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# hunk
|
|
2
|
+
|
|
3
|
+
Hunk is a desktop-inspired terminal diff viewer for understanding AI-authored changesets in Bun + TypeScript with OpenTUI.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Bun
|
|
8
|
+
- Zig
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Run
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
bun run src/main.tsx -- diff
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Standalone binary
|
|
23
|
+
|
|
24
|
+
Build a local executable:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bun run build:bin
|
|
28
|
+
./dist/hunk diff
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Install it into `~/.local/bin`:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun run install:bin
|
|
35
|
+
hunk
|
|
36
|
+
hunk diff
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you want a different install location, set `HUNK_INSTALL_DIR` before running the install script.
|
|
40
|
+
|
|
41
|
+
## Workflows
|
|
42
|
+
|
|
43
|
+
- `hunk` — print standard CLI help with the most common commands
|
|
44
|
+
- `hunk diff` — review local working tree changes in the full Hunk UI
|
|
45
|
+
- `hunk diff --staged` / `hunk diff --cached` — review staged changes in the full Hunk UI
|
|
46
|
+
- `hunk diff <ref>` — review changes versus a branch, tag, or commit-ish
|
|
47
|
+
- `hunk diff <ref1>..<ref2>` / `hunk diff <ref1>...<ref2>` — review common Git ranges
|
|
48
|
+
- `hunk diff -- <pathspec...>` — review only selected paths
|
|
49
|
+
- `hunk show [ref]` — review the last commit or a given ref in the full Hunk UI
|
|
50
|
+
- `hunk stash show [ref]` — review a stash entry in the full Hunk UI
|
|
51
|
+
- `hunk diff <left> <right>` — compare two concrete files directly
|
|
52
|
+
- `hunk patch [file|-]` — review a patch file or stdin, including pager mode
|
|
53
|
+
- `hunk pager` — act as a general Git pager wrapper, opening Hunk for diff-like stdin and falling back to normal text paging otherwise
|
|
54
|
+
- `hunk difftool <left> <right> [path]` — integrate with Git difftool
|
|
55
|
+
- `hunk git [range]` — legacy alias for the original Git-style diff entrypoint
|
|
56
|
+
|
|
57
|
+
## Interaction
|
|
58
|
+
|
|
59
|
+
- `1` split view
|
|
60
|
+
- `2` stacked view
|
|
61
|
+
- `0` auto layout
|
|
62
|
+
- `t` cycle themes
|
|
63
|
+
- `a` toggle the agent panel
|
|
64
|
+
- `l` toggle line numbers
|
|
65
|
+
- `w` toggle line wrapping
|
|
66
|
+
- `m` toggle hunk metadata
|
|
67
|
+
- `[` / `]` move between hunks
|
|
68
|
+
- `space` / `b` page forward and backward
|
|
69
|
+
- `/` focus the file filter
|
|
70
|
+
- `tab` cycle focus regions
|
|
71
|
+
- `q` or `Esc` quit
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
Hunk reads layered TOML config with this precedence:
|
|
76
|
+
|
|
77
|
+
1. built-in defaults
|
|
78
|
+
2. global config: `$XDG_CONFIG_HOME/hunk/config.toml` or `~/.config/hunk/config.toml`
|
|
79
|
+
3. repo-local config: `.hunk/config.toml`
|
|
80
|
+
4. command-specific sections like `[git]`, `[diff]`, `[show]`, `[stash-show]`, `[patch]`, `[difftool]`
|
|
81
|
+
5. `[pager]` when Hunk is running in pager mode
|
|
82
|
+
6. explicit CLI flags
|
|
83
|
+
|
|
84
|
+
When you change persistent view settings inside Hunk, it writes them back to `.hunk/config.toml` in the current repo when possible, or to the global config file outside a repo.
|
|
85
|
+
|
|
86
|
+
Example:
|
|
87
|
+
|
|
88
|
+
```toml
|
|
89
|
+
theme = "midnight"
|
|
90
|
+
mode = "auto"
|
|
91
|
+
line_numbers = true
|
|
92
|
+
wrap_lines = false
|
|
93
|
+
hunk_headers = true
|
|
94
|
+
agent_notes = false
|
|
95
|
+
|
|
96
|
+
[pager]
|
|
97
|
+
mode = "stack"
|
|
98
|
+
line_numbers = false
|
|
99
|
+
|
|
100
|
+
[diff]
|
|
101
|
+
mode = "split"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
CLI overrides are available when you want one-off or pager-specific behavior:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
hunk diff --mode split --line-numbers
|
|
108
|
+
hunk show HEAD~1 --theme paper
|
|
109
|
+
hunk patch - --mode stack --no-line-numbers
|
|
110
|
+
hunk diff before.ts after.ts --theme paper --wrap
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Supported persistent CLI overrides:
|
|
114
|
+
|
|
115
|
+
- `--mode <auto|split|stack>`
|
|
116
|
+
- `--theme <theme>`
|
|
117
|
+
- `--line-numbers` / `--no-line-numbers`
|
|
118
|
+
- `--wrap` / `--no-wrap`
|
|
119
|
+
- `--hunk-headers` / `--no-hunk-headers`
|
|
120
|
+
- `--agent-notes` / `--no-agent-notes`
|
|
121
|
+
|
|
122
|
+
## Agent sidecar format
|
|
123
|
+
|
|
124
|
+
Use `--agent-context <file>` to load a JSON sidecar and show agent rationale next to the diff.
|
|
125
|
+
|
|
126
|
+
The order of `files` in the sidecar is significant. Hunk uses that order for the sidebar and main review stream so an agent can tell a story instead of relying on raw patch order.
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"version": 1,
|
|
131
|
+
"summary": "High-level change summary from the agent.",
|
|
132
|
+
"files": [
|
|
133
|
+
{
|
|
134
|
+
"path": "src/core/loaders.ts",
|
|
135
|
+
"summary": "Normalizes git and patch inputs into one changeset model.",
|
|
136
|
+
"annotations": [
|
|
137
|
+
{
|
|
138
|
+
"newRange": [120, 156],
|
|
139
|
+
"summary": "Adds the patch loader entrypoint.",
|
|
140
|
+
"rationale": "Keeps all diff sources flowing through one normalized shape.",
|
|
141
|
+
"tags": ["parser", "architecture"],
|
|
142
|
+
"confidence": "high"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"path": "src/ui/App.tsx",
|
|
148
|
+
"summary": "Presents the new workflow after the loader changes.",
|
|
149
|
+
"annotations": [
|
|
150
|
+
{
|
|
151
|
+
"newRange": [90, 136],
|
|
152
|
+
"summary": "Uses the normalized model in the review shell.",
|
|
153
|
+
"rationale": "The reader should inspect this after understanding the loader changes.",
|
|
154
|
+
"tags": ["ui"],
|
|
155
|
+
"confidence": "medium"
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Files omitted from the sidecar keep their original diff order and appear after the explicitly ordered files.
|
|
164
|
+
|
|
165
|
+
## Codex workflow
|
|
166
|
+
|
|
167
|
+
For Codex-driven changes, keep a transient sidecar at `.hunk/latest.json` and load it during review:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
hunk diff --agent-context .hunk/latest.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Suggested pattern:
|
|
174
|
+
|
|
175
|
+
- Codex makes code changes.
|
|
176
|
+
- Codex refreshes `.hunk/latest.json` with a concise changeset summary, file summaries, and hunk-level rationale.
|
|
177
|
+
- You open `hunk diff`, `hunk diff --staged`, or `hunk show <ref>` with that sidecar.
|
|
178
|
+
|
|
179
|
+
Keep the sidecar concise. It should explain why a hunk exists, what risk to review, and how the files fit together. It should not narrate obvious syntax edits line by line.
|
|
180
|
+
|
|
181
|
+
## Comparison
|
|
182
|
+
|
|
183
|
+
### Feature comparison
|
|
184
|
+
|
|
185
|
+
| Capability | hunk | difftastic | delta | diff |
|
|
186
|
+
| --- | --- | --- | --- | --- |
|
|
187
|
+
| Dedicated interactive review UI | ✅ | ❌ | ❌ | ❌ |
|
|
188
|
+
| Multi-file review stream with navigation sidebar | ✅ | ❌ | ❌ | ❌ |
|
|
189
|
+
| Agent / AI rationale sidecar | ✅ | ❌ | ❌ | ❌ |
|
|
190
|
+
| Split diffs | ✅ | ✅ | ✅ | ✅ |
|
|
191
|
+
| Stacked diffs | ✅ | ✅ | ✅ | ✅ |
|
|
192
|
+
| Auto responsive layouts | ✅ | ❌ | ❌ | ❌ |
|
|
193
|
+
| Themes | ✅ | ❌ | ✅ | ❌ |
|
|
194
|
+
| Syntax highlighting | ✅ | ✅ | ✅ | ❌ |
|
|
195
|
+
| Syntax-aware / structural diffing | ❌ | ✅ | ❌ | ❌ |
|
|
196
|
+
| Mouse support inside the diff viewer | ✅ | ❌ | ❌ | ❌ |
|
|
197
|
+
| Runtime toggles for wrapping / line numbers / hunk metadata | ✅ | ❌ | ❌ | ❌ |
|
|
198
|
+
| Pager-compatible mode | ✅ | ✅ | ✅ | ✅ |
|
|
199
|
+
|
|
200
|
+
### Local timing snapshot
|
|
201
|
+
|
|
202
|
+
These numbers are **not a universal benchmark**. They are a quick local comparison from one Linux machine using tmux panes, measuring **time until a changed marker first became visible** on the same 120-line TypeScript file pair.
|
|
203
|
+
|
|
204
|
+
Commands used:
|
|
205
|
+
|
|
206
|
+
- `hunk diff before.ts after.ts`
|
|
207
|
+
- `difft --display side-by-side before.ts after.ts`
|
|
208
|
+
- `delta --paging=never before.ts after.ts`
|
|
209
|
+
- `diff -u before.ts after.ts`
|
|
210
|
+
|
|
211
|
+
| Tool | Avg first-visible changed output |
|
|
212
|
+
| --- | ---: |
|
|
213
|
+
| `diff` | ~37 ms |
|
|
214
|
+
| `delta --paging=never` | ~35 ms |
|
|
215
|
+
| `hunk diff` | ~219 ms |
|
|
216
|
+
| `difft --display side-by-side` | ~266 ms |
|
|
217
|
+
|
|
218
|
+
Interpretation:
|
|
219
|
+
|
|
220
|
+
- `diff` and `delta` are fastest here because they emit plain diff text and exit.
|
|
221
|
+
- `hunk` pays extra startup cost for an interactive terminal UI, syntax highlighting, navigation state, and optional agent context.
|
|
222
|
+
- `difftastic` pays extra cost for syntax-aware / structural diffing.
|
|
223
|
+
- For larger review sessions, Hunk is optimized for **navigating and understanding** a changeset, not just dumping the quickest possible patch text.
|
|
224
|
+
|
|
225
|
+
## Git integration
|
|
226
|
+
|
|
227
|
+
For full-screen review, you can invoke Hunk directly with Git-shaped commands:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
hunk diff
|
|
231
|
+
hunk diff --staged
|
|
232
|
+
hunk diff main...feature
|
|
233
|
+
hunk show
|
|
234
|
+
hunk show HEAD~1
|
|
235
|
+
hunk stash show
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Use Hunk as the default Git pager when you want it to behave like a normal pager under `git diff` / `git show`:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
git config --global core.pager 'hunk patch -'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Or scope it just to `git diff` and `git show`:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
git config --global pager.diff 'hunk patch -'
|
|
248
|
+
git config --global pager.show 'hunk patch -'
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
When Hunk reads a patch from stdin, it automatically switches to pager-style chrome, strips Git's color escape sequences before parsing, and binds keyboard input to the controlling terminal so it works correctly as a Git pager.
|
|
252
|
+
|
|
253
|
+
Then:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
git diff
|
|
257
|
+
git show HEAD
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
If you want Git to launch Hunk as a difftool for file-to-file comparisons:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
git config --global diff.tool hunk
|
|
264
|
+
git config --global difftool.hunk.cmd 'hunk difftool "$LOCAL" "$REMOTE" "$MERGED"'
|
|
265
|
+
```
|
|
266
|
+
e comparisons:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
git config --global diff.tool hunk
|
|
270
|
+
git config --global difftool.hunk.cmd 'hunk difftool "$LOCAL" "$REMOTE" "$MERGED"'
|
|
271
|
+
```
|