@levnikolaevich/hex-line-mcp 1.3.1 → 1.3.3
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 +120 -47
- package/benchmark/atomic.mjs +502 -0
- package/benchmark/graph.mjs +80 -0
- package/benchmark/index.mjs +144 -0
- package/benchmark/workflows.mjs +350 -0
- package/hook.mjs +48 -15
- package/lib/benchmark-helpers.mjs +1 -1
- package/lib/changes.mjs +2 -1
- package/lib/coerce.mjs +1 -42
- package/lib/edit.mjs +258 -248
- package/lib/graph-enrich.mjs +76 -58
- package/lib/hash.mjs +1 -109
- package/lib/info.mjs +1 -1
- package/lib/normalize.mjs +1 -106
- package/lib/outline.mjs +32 -87
- package/lib/read.mjs +8 -5
- package/lib/revisions.mjs +238 -0
- package/lib/search.mjs +6 -7
- package/lib/security.mjs +4 -4
- package/lib/setup.mjs +7 -20
- package/lib/update-check.mjs +1 -56
- package/lib/verify.mjs +32 -16
- package/output-style.md +21 -6
- package/package.json +18 -6
- package/server.mjs +35 -43
- package/benchmark.mjs +0 -1106
package/README.md
CHANGED
|
@@ -13,17 +13,34 @@ Every line carries an FNV-1a content hash. Every edit must present those hashes
|
|
|
13
13
|
|
|
14
14
|
### 11 MCP Tools
|
|
15
15
|
|
|
16
|
+
Core day-to-day tools:
|
|
17
|
+
|
|
18
|
+
- `read_file`
|
|
19
|
+
- `edit_file`
|
|
20
|
+
- `grep_search`
|
|
21
|
+
- `outline`
|
|
22
|
+
- `verify`
|
|
23
|
+
- `bulk_replace`
|
|
24
|
+
|
|
25
|
+
Advanced / occasional:
|
|
26
|
+
|
|
27
|
+
- `write_file`
|
|
28
|
+
- `directory_tree`
|
|
29
|
+
- `get_file_info`
|
|
30
|
+
- `changes`
|
|
31
|
+
- `setup_hooks`
|
|
32
|
+
|
|
16
33
|
| Tool | Description | Key Feature |
|
|
17
34
|
|------|-------------|-------------|
|
|
18
|
-
| `read_file` | Read file with hash-annotated lines and
|
|
19
|
-
| `edit_file` |
|
|
35
|
+
| `read_file` | Read file with hash-annotated lines, checksums, and revision | Partial reads via `offset`/`limit` |
|
|
36
|
+
| `edit_file` | Revision-aware anchor edits (`set_line`, `replace_lines`, `insert_after`, `replace_between`) | Batched same-file edits + conservative auto-rebase |
|
|
20
37
|
| `write_file` | Create new file or overwrite, auto-creates parent dirs | Path validation, no hash overhead |
|
|
21
38
|
| `grep_search` | Search with ripgrep, 3 output modes, per-group checksums | Edit-ready: grep -> edit directly with checksums |
|
|
22
39
|
| `outline` | AST-based structural overview via tree-sitter WASM | 95% token reduction (10 lines instead of 500) |
|
|
23
|
-
| `verify` | Check if held
|
|
40
|
+
| `verify` | Check if held checksums / revision are still current | Staleness check without full re-read |
|
|
24
41
|
| `directory_tree` | Compact directory tree with root .gitignore support | Skips node_modules/.git, shows file sizes |
|
|
25
42
|
| `get_file_info` | File metadata without reading content | Size, lines, mtime, type, binary detection |
|
|
26
|
-
| `setup_hooks` | Configure
|
|
43
|
+
| `setup_hooks` | Configure Claude hooks + install output style | Gemini/Codex get guidance only; no hooks |
|
|
27
44
|
| `changes` | Compare file against git ref, shows added/removed/modified symbols | AST-level semantic diff |
|
|
28
45
|
| `bulk_replace` | Search-and-replace across multiple files by glob | Per-file diffs, dry_run, max_files safety |
|
|
29
46
|
|
|
@@ -33,13 +50,13 @@ Every line carries an FNV-1a content hash. Every edit must present those hashes
|
|
|
33
50
|
|-------|---------|--------|
|
|
34
51
|
| **PreToolUse** | Read/Edit/Write/Grep on text files | Blocks built-in, forces hex-line tools |
|
|
35
52
|
| **PreToolUse** | Bash with dangerous commands | Blocks `rm -rf /`, `git push --force`, etc. Agent must confirm with user |
|
|
36
|
-
| **PostToolUse** | Bash with 50+ lines output | RTK: deduplicates, truncates,
|
|
53
|
+
| **PostToolUse** | Bash with 50+ lines output | RTK: deduplicates, truncates, shows filtered summary to Claude as feedback |
|
|
37
54
|
| **SessionStart** | Session begins | Injects full tool preference list into agent context |
|
|
38
55
|
|
|
39
56
|
|
|
40
57
|
### Bash Redirects
|
|
41
58
|
|
|
42
|
-
PreToolUse also intercepts simple Bash commands: cat, head, tail,
|
|
59
|
+
PreToolUse also intercepts simple Bash commands: cat, head, tail, tree, find, stat, wc -l, grep, rg, sed -i — redirects to hex-line equivalents. `ls`/`dir` only redirected for recursive listing (`ls -R`, `dir /s`); simple `ls path` is allowed. Compound commands with pipes are allowed.
|
|
43
60
|
## Install
|
|
44
61
|
|
|
45
62
|
### MCP Server
|
|
@@ -49,6 +66,8 @@ npm i -g @levnikolaevich/hex-line-mcp
|
|
|
49
66
|
claude mcp add -s user hex-line -- hex-line-mcp
|
|
50
67
|
```
|
|
51
68
|
|
|
69
|
+
ripgrep is bundled via `@vscode/ripgrep` — no manual install needed for `grep_search`.
|
|
70
|
+
|
|
52
71
|
### Hooks
|
|
53
72
|
|
|
54
73
|
Automatic setup (run once after MCP install):
|
|
@@ -69,41 +88,83 @@ mcp__hex-line__setup_hooks(agent="claude")
|
|
|
69
88
|
|
|
70
89
|
The `setup_hooks` tool automatically installs the output style to `~/.claude/output-styles/hex-line.md` and activates it if no other style is set. To activate manually: `/config` > Output style > hex-line.
|
|
71
90
|
|
|
72
|
-
##
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
## Benchmarking
|
|
92
|
+
|
|
93
|
+
`hex-line-mcp` now distinguishes:
|
|
94
|
+
|
|
95
|
+
- `tests` — correctness and regression safety
|
|
96
|
+
- `benchmarks` — comparative workflow efficiency against built-in tools
|
|
97
|
+
- `diagnostics` — modeled tool-level measurements for engineering inspection
|
|
98
|
+
|
|
99
|
+
Public benchmark mode reports only comparative multi-step workflows:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run benchmark -- --repo /path/to/repo
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Optional diagnostics stay available separately:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npm run benchmark:diagnostic -- --repo /path/to/repo
|
|
109
|
+
npm run benchmark:diagnostic:graph -- --repo /path/to/repo
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The diagnostics output includes synthetic tool-level comparisons such as read, grep, verify, and graph-enrichment helpers. Those numbers are useful for inspecting output shape and token behavior, but they are not the public workflow benchmark score.
|
|
113
|
+
|
|
114
|
+
Current sample run on the `hex-line-mcp` repo with session-derived workflows:
|
|
115
|
+
|
|
116
|
+
| ID | Workflow | Built-in | hex-line | Savings | Ops |
|
|
117
|
+
|----|----------|---------:|---------:|--------:|----:|
|
|
118
|
+
| W1 | Debug hook file-listing redirect | 23,143 chars | 882 chars | 96% | 3→2 |
|
|
119
|
+
| W2 | Adjust `setup_hooks` guidance and verify | 24,877 chars | 1,637 chars | 93% | 3→3 |
|
|
120
|
+
| W3 | Repo-wide benchmark wording refresh | 137,796 chars | 38,918 chars | 72% | 15→1 |
|
|
121
|
+
| W4 | Inspect large smoke test before edit | 49,566 chars | 2,104 chars | 96% | 3→3 |
|
|
122
|
+
|
|
123
|
+
Workflow summary: `89%` average token savings, `24→9` tool calls (`63%` fewer).
|
|
124
|
+
|
|
125
|
+
These workflows are derived from recent real Claude sessions, but executed against local reproducible fixtures in the repository. They should be read as workflow-efficiency measurements, not as correctness or semantic-quality claims.
|
|
126
|
+
|
|
127
|
+
### Optional Graph Enrichment
|
|
128
|
+
|
|
129
|
+
If a project already has `.codegraph/index.db`, `hex-line` can add lightweight graph hints to `read_file`, `outline`, `grep_search`, and `edit_file`.
|
|
130
|
+
|
|
131
|
+
- Graph enrichment is optional. If `.codegraph/index.db` is missing, `hex-line` falls back to standard behavior silently.
|
|
132
|
+
- `better-sqlite3` is optional. If it is unavailable, `hex-line` still works without graph hints.
|
|
133
|
+
- `edit_file` reports **Call impact**, not full semantic blast radius. The warning uses call-graph callers only.
|
|
134
|
+
|
|
135
|
+
`hex-line` does not read `hex-graph` internals directly anymore. The integration uses a small read-only contract exposed by `hex-graph-mcp`:
|
|
136
|
+
|
|
137
|
+
- `hex_line_contract`
|
|
138
|
+
- `hex_line_symbol_annotations`
|
|
139
|
+
- `hex_line_call_edges`
|
|
101
140
|
|
|
102
141
|
## Tools Reference
|
|
103
142
|
|
|
143
|
+
## Common Workflows
|
|
144
|
+
|
|
145
|
+
### Local code edit in one file
|
|
146
|
+
|
|
147
|
+
1. `outline` for large code files
|
|
148
|
+
2. `read_file` for the exact range you need
|
|
149
|
+
3. `edit_file` with all known hunks in one call
|
|
150
|
+
|
|
151
|
+
### Follow-up edit on the same file
|
|
152
|
+
|
|
153
|
+
1. Carry `revision` from the earlier `read_file` or `edit_file`
|
|
154
|
+
2. Pass it back as `base_revision`
|
|
155
|
+
3. Use `verify` before rereading the file
|
|
156
|
+
|
|
157
|
+
### Rewrite a long block
|
|
158
|
+
|
|
159
|
+
Use `replace_between` inside `edit_file` when you know stable start/end anchors and want to replace a large function, class, or config block without reciting the old body.
|
|
160
|
+
|
|
161
|
+
### Literal rename / refactor
|
|
162
|
+
|
|
163
|
+
Use `bulk_replace` for text rename patterns across one or more files. Do not use it as a substitute for structured block rewrites.
|
|
164
|
+
|
|
104
165
|
### read_file
|
|
105
166
|
|
|
106
|
-
Read a file with FNV-1a hash-annotated lines
|
|
167
|
+
Read a file with FNV-1a hash-annotated lines, range checksums, file checksum, and revision. Supports directory listing.
|
|
107
168
|
|
|
108
169
|
| Parameter | Type | Required | Description |
|
|
109
170
|
|-----------|------|----------|-------------|
|
|
@@ -120,11 +181,13 @@ ab.1 import { resolve } from "node:path";
|
|
|
120
181
|
cd.2 import { readFileSync } from "node:fs";
|
|
121
182
|
...
|
|
122
183
|
checksum: 1-50:f7e2a1b0
|
|
184
|
+
revision: rev-12-a1b2c3d4
|
|
185
|
+
file: 1-120:beefcafe
|
|
123
186
|
```
|
|
124
187
|
|
|
125
188
|
### edit_file
|
|
126
189
|
|
|
127
|
-
Edit using hash-verified anchors
|
|
190
|
+
Edit using revision-aware hash-verified anchors. Prefer one batched call per file. For text rename use bulk_replace.
|
|
128
191
|
|
|
129
192
|
| Parameter | Type | Required | Description |
|
|
130
193
|
|-----------|------|----------|-------------|
|
|
@@ -132,19 +195,28 @@ Edit using hash-verified anchors or text replacement. Returns diff + post-edit c
|
|
|
132
195
|
| `edits` | string | yes | JSON array of edit operations (see below) |
|
|
133
196
|
| `dry_run` | boolean | no | Preview changes without writing |
|
|
134
197
|
| `restore_indent` | boolean | no | Auto-fix indentation to match anchor context (default: false) |
|
|
198
|
+
| `base_revision` | string | no | Prior revision from `read_file` / `edit_file` for same-file follow-up edits |
|
|
199
|
+
| `conflict_policy` | enum | no | `conservative` or `strict` (default: `conservative`) |
|
|
135
200
|
|
|
136
201
|
Edit operations (JSON array):
|
|
137
202
|
|
|
138
203
|
```json
|
|
139
204
|
[
|
|
140
205
|
{"set_line": {"anchor": "ab.12", "new_text": "replacement line"}},
|
|
141
|
-
{"replace_lines": {"start_anchor": "ab.10", "end_anchor": "cd.15", "new_text": "..."}},
|
|
206
|
+
{"replace_lines": {"start_anchor": "ab.10", "end_anchor": "cd.15", "new_text": "...", "range_checksum": "10-15:a1b2c3d4"}},
|
|
142
207
|
{"insert_after": {"anchor": "ab.20", "text": "inserted line"}},
|
|
143
|
-
{"
|
|
144
|
-
{"replace": {"old_text": "find all", "new_text": "replace all", "all": true}}
|
|
208
|
+
{"replace_between": {"start_anchor": "ab.30", "end_anchor": "cd.80", "new_text": "...", "boundary_mode": "inclusive"}}
|
|
145
209
|
]
|
|
146
210
|
```
|
|
147
211
|
|
|
212
|
+
Result footer includes:
|
|
213
|
+
|
|
214
|
+
- `status: OK | AUTO_REBASED | CONFLICT`
|
|
215
|
+
- `revision: ...`
|
|
216
|
+
- `file: ...`
|
|
217
|
+
- `changed_ranges: ...` when relevant
|
|
218
|
+
- `retry_checksum: ...` on local conflicts
|
|
219
|
+
|
|
148
220
|
### write_file
|
|
149
221
|
|
|
150
222
|
Create a new file or overwrite an existing one. Creates parent directories automatically.
|
|
@@ -192,12 +264,13 @@ Not for `.md`, `.json`, `.yaml`, `.txt` -- use `read_file` directly for those.
|
|
|
192
264
|
|
|
193
265
|
### verify
|
|
194
266
|
|
|
195
|
-
Check if range checksums from a prior read are still valid
|
|
267
|
+
Check if range checksums from a prior read are still valid, optionally relative to a prior `base_revision`.
|
|
196
268
|
|
|
197
269
|
| Parameter | Type | Required | Description |
|
|
198
270
|
|-----------|------|----------|-------------|
|
|
199
271
|
| `path` | string | yes | File path |
|
|
200
272
|
| `checksums` | string | yes | JSON array of checksum strings, e.g. `["1-50:f7e2a1b0"]` |
|
|
273
|
+
| `base_revision` | string | no | Prior revision to compare against latest state |
|
|
201
274
|
|
|
202
275
|
Returns a single-line confirmation or lists changed ranges.
|
|
203
276
|
|
|
@@ -269,7 +342,7 @@ hex-line-mcp/
|
|
|
269
342
|
lib/
|
|
270
343
|
hash.mjs FNV-1a hashing, 2-char tags, range checksums
|
|
271
344
|
read.mjs File reading with hash annotation
|
|
272
|
-
edit.mjs Anchor-based
|
|
345
|
+
edit.mjs Anchor-based edits, diff output
|
|
273
346
|
search.mjs ripgrep wrapper with hash-annotated results
|
|
274
347
|
outline.mjs tree-sitter WASM AST outline
|
|
275
348
|
verify.mjs Range checksum verification
|
|
@@ -277,9 +350,9 @@ hex-line-mcp/
|
|
|
277
350
|
tree.mjs Directory tree with .gitignore support
|
|
278
351
|
changes.mjs Semantic git diff via AST
|
|
279
352
|
bulk-replace.mjs Multi-file search-and-replace
|
|
280
|
-
setup.mjs
|
|
353
|
+
setup.mjs Claude hook installation + output style setup
|
|
281
354
|
format.mjs Output formatting utilities
|
|
282
|
-
coerce.mjs Parameter
|
|
355
|
+
coerce.mjs Parameter pass-through (identity)
|
|
283
356
|
security.mjs Path validation, binary detection, size limits
|
|
284
357
|
normalize.mjs Output normalization, deduplication, truncation
|
|
285
358
|
```
|
|
@@ -317,7 +390,7 @@ FNV-1a accumulator over all line hashes in the range (little-endian byte feed).
|
|
|
317
390
|
<details>
|
|
318
391
|
<summary><b>Does it work without Claude Code?</b></summary>
|
|
319
392
|
|
|
320
|
-
Yes. hex-line-mcp is a standard MCP server (stdio transport). It works with any MCP-compatible client -- Claude Code, Gemini CLI, Codex CLI, or custom integrations.
|
|
393
|
+
Yes. hex-line-mcp is a standard MCP server (stdio transport). It works with any MCP-compatible client -- Claude Code, Gemini CLI, Codex CLI, or custom integrations. Hook installation is Claude-specific; Gemini/Codex use MCP Tool Preferences guidance instead.
|
|
321
394
|
|
|
322
395
|
</details>
|
|
323
396
|
|
|
@@ -336,9 +409,9 @@ Outline works on code files only (15+ languages via tree-sitter WASM). For markd
|
|
|
336
409
|
</details>
|
|
337
410
|
|
|
338
411
|
<details>
|
|
339
|
-
<summary><b>How does the RTK filter
|
|
412
|
+
<summary><b>How does the RTK filter work?</b></summary>
|
|
340
413
|
|
|
341
|
-
The PostToolUse hook normalizes Bash output (replaces UUIDs, timestamps, IPs with placeholders), deduplicates identical lines, and truncates to first 15 + last 15 lines.
|
|
414
|
+
The PostToolUse hook normalizes Bash output (replaces UUIDs, timestamps, IPs with placeholders), deduplicates identical lines, and truncates to first 15 + last 15 lines. The filtered summary is shown to Claude as stderr feedback via exit code 2.
|
|
342
415
|
|
|
343
416
|
</details>
|
|
344
417
|
|