@levnikolaevich/hex-line-mcp 1.10.0 → 1.11.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 +26 -35
- package/dist/artifacts/tree-sitter/manifest.json +57 -0
- package/dist/artifacts/tree-sitter/tree-sitter-c_sharp.wasm +0 -0
- package/dist/artifacts/tree-sitter/tree-sitter-javascript.wasm +0 -0
- package/dist/artifacts/tree-sitter/tree-sitter-php.wasm +0 -0
- package/dist/artifacts/tree-sitter/tree-sitter-python.wasm +0 -0
- package/dist/artifacts/tree-sitter/tree-sitter-tsx.wasm +0 -0
- package/dist/artifacts/tree-sitter/tree-sitter-typescript.wasm +0 -0
- package/dist/hook.mjs +5 -17
- package/dist/server.mjs +567 -265
- package/output-style.md +6 -6
- package/package.json +11 -13
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Every line carries an FNV-1a content hash. Every edit must present those hashes
|
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
|
-
###
|
|
14
|
+
### 9 MCP Tools
|
|
15
15
|
|
|
16
16
|
Core day-to-day tools:
|
|
17
17
|
|
|
@@ -25,20 +25,18 @@ Core day-to-day tools:
|
|
|
25
25
|
Advanced / occasional:
|
|
26
26
|
|
|
27
27
|
- `write_file`
|
|
28
|
-
- `
|
|
29
|
-
- `get_file_info`
|
|
28
|
+
- `inspect_path`
|
|
30
29
|
- `changes`
|
|
31
30
|
|
|
32
31
|
| Tool | Description | Key Feature |
|
|
33
32
|
|------|-------------|-------------|
|
|
34
|
-
| `read_file` | Read file with hash-annotated lines, checksums, and
|
|
33
|
+
| `read_file` | Read file with hash-annotated lines, checksums, revision, and automatic graph hints when available | Partial reads via `offset`/`limit` or `ranges`, compact output by default |
|
|
35
34
|
| `edit_file` | Revision-aware anchor edits (`set_line`, `replace_lines`, `insert_after`, `replace_between`) | Batched same-file edits + conservative auto-rebase |
|
|
36
35
|
| `write_file` | Create new file or overwrite, auto-creates parent dirs | Path validation, no hash overhead |
|
|
37
36
|
| `grep_search` | Search with ripgrep, 3 output modes, per-group checksums | Plain `files`/`count`, compact edit-ready `content` |
|
|
38
|
-
| `outline` | AST-based structural overview with hash anchors via tree-sitter WASM. Supports
|
|
37
|
+
| `outline` | AST-based structural overview with hash anchors via tree-sitter WASM. Supports JavaScript/TypeScript, Python, C#, PHP, and fence-aware markdown headings | 95% token reduction, direct edit anchors |
|
|
39
38
|
| `verify` | Check if held checksums / revision are still current | Staleness check without full re-read |
|
|
40
|
-
| `
|
|
41
|
-
| `get_file_info` | File metadata without reading content | Size, lines, mtime, type, binary detection |
|
|
39
|
+
| `inspect_path` | Unified file-or-directory inspection | File metadata for files, tree or pattern search for directories |
|
|
42
40
|
| `changes` | Compare file against git ref, shows added/removed/modified symbols | AST-level semantic diff |
|
|
43
41
|
| `bulk_replace` | Search-and-replace across multiple files by glob | Compact summary (default) or capped diffs via `format`, dry_run, max_files |
|
|
44
42
|
|
|
@@ -93,11 +91,12 @@ Comparative built-in vs hex-line benchmarks are maintained outside this package.
|
|
|
93
91
|
|
|
94
92
|
### Optional Graph Enrichment
|
|
95
93
|
|
|
96
|
-
If a project already has `.hex-skills/codegraph/index.db`, `hex-line`
|
|
94
|
+
If a project already has `.hex-skills/codegraph/index.db`, `hex-line` automatically adds lightweight graph hints to `read_file`, `outline`, `grep_search`, `edit_file`, and `changes`.
|
|
97
95
|
|
|
98
|
-
- Graph enrichment is optional. If `.hex-skills/codegraph/index.db` is missing, `hex-line` falls back to standard behavior silently.
|
|
96
|
+
- Graph enrichment is optional. If `.hex-skills/codegraph/index.db` is missing, stale, or unreadable, `hex-line` falls back to standard behavior silently.
|
|
99
97
|
- `better-sqlite3` is optional. If it is unavailable, `hex-line` still works without graph hints.
|
|
100
|
-
- `
|
|
98
|
+
- `read_file`, `outline`, and `grep_search` stay compact: they only surface high-signal local facts such as `api`, framework entrypoints, callers, flow, and clone hints.
|
|
99
|
+
- `edit_file` and `changes` surface the deeper review layer: external callers, downstream return/property flow, clone peers, public API risk, framework entrypoint risk, and same-name sibling warnings when present.
|
|
101
100
|
|
|
102
101
|
`hex-line` does not read `hex-graph` internals directly anymore. The integration uses a small read-only contract exposed by `hex-graph-mcp`:
|
|
103
102
|
|
|
@@ -133,16 +132,15 @@ Use `bulk_replace` for text rename patterns across one or more files. Returns co
|
|
|
133
132
|
|
|
134
133
|
### read_file
|
|
135
134
|
|
|
136
|
-
Read a file as canonical edit-ready blocks. Each valid range becomes a `read_range` block with absolute span, line entries, and a checksum covering exactly the emitted lines. Invalid ranges become explicit diagnostic blocks. Supports batch reads
|
|
135
|
+
Read a file as canonical edit-ready blocks. Each valid range becomes a `read_range` block with absolute span, line entries, and a checksum covering exactly the emitted lines. Invalid ranges become explicit diagnostic blocks. Supports batch reads and multi-range reads. Directories go through `inspect_path`.
|
|
137
136
|
|
|
138
137
|
| Parameter | Type | Required | Description |
|
|
139
138
|
|-----------|------|----------|-------------|
|
|
140
|
-
| `path` | string | yes | File
|
|
139
|
+
| `path` | string | yes | File path |
|
|
141
140
|
| `paths` | string[] | no | Array of file paths to read (batch mode) |
|
|
142
141
|
| `offset` | number | no | Start line, 1-indexed (default: 1) |
|
|
143
142
|
| `limit` | number | no | Max lines to return (default: 2000, 0 = all) |
|
|
144
143
|
| `ranges` | array | no | Explicit line ranges, e.g. `[{ "start": 10, "end": 30 }]` |
|
|
145
|
-
| `include_graph` | boolean | no | Opt in to graph annotations when the graph index exists |
|
|
146
144
|
| `plain` | boolean | no | Omit hashes, output `lineNum\|content` instead |
|
|
147
145
|
|
|
148
146
|
Default output is compact but block-structured:
|
|
@@ -229,13 +227,13 @@ Search file contents using ripgrep. Three output modes: `content` (canonical `se
|
|
|
229
227
|
|
|
230
228
|
### outline
|
|
231
229
|
|
|
232
|
-
AST-based structural outline with hash anchors for direct `edit_file` usage. Supports
|
|
230
|
+
AST-based structural outline with hash anchors for direct `edit_file` usage. Supports JavaScript/TypeScript, Python, C#, PHP, and fence-aware markdown heading navigation (`.md`/`.mdx`). Each entry includes a hash tag for immediate anchor use without intermediate `read_file`.
|
|
233
231
|
|
|
234
232
|
| Parameter | Type | Required | Description |
|
|
235
233
|
|-----------|------|----------|-------------|
|
|
236
234
|
| `path` | string | yes | Source file path |
|
|
237
235
|
|
|
238
|
-
Supported languages: JavaScript, TypeScript (
|
|
236
|
+
Supported languages: JavaScript (`.js`, `.mjs`, `.cjs`, `.jsx`), TypeScript (`.ts`, `.tsx`), Python (`.py`), C# (`.cs`), and PHP (`.php`) via tree-sitter WASM.
|
|
239
237
|
|
|
240
238
|
Not for `.json`, `.yaml`, `.txt` -- use `read_file` directly for those.
|
|
241
239
|
|
|
@@ -262,30 +260,22 @@ changed_ranges: 10-12(replace)
|
|
|
262
260
|
STALE 10-12 checksum: 10-12:oldc0de0 current=10-12:newc0de0
|
|
263
261
|
```
|
|
264
262
|
|
|
265
|
-
###
|
|
263
|
+
### inspect_path
|
|
266
264
|
|
|
267
|
-
|
|
265
|
+
Inspect a file or directory path without guessing which low-level tool to call first.
|
|
268
266
|
|
|
269
267
|
| Parameter | Type | Required | Description |
|
|
270
268
|
|-----------|------|----------|-------------|
|
|
271
|
-
| `path` | string | yes |
|
|
269
|
+
| `path` | string | yes | File or directory path |
|
|
272
270
|
| `pattern` | string | no | Glob filter on names (e.g. `"*-mcp"`, `"*.mjs"`). Returns flat match list instead of tree |
|
|
273
271
|
| `type` | string | no | `"file"`, `"dir"`, or `"all"` (default). Like `find -type f/d` |
|
|
274
272
|
| `max_depth` | number | no | Max recursion depth (default: 3, or 20 in pattern mode) |
|
|
275
273
|
| `gitignore` | boolean | no | Respect root .gitignore patterns (default: true). Nested .gitignore not supported |
|
|
276
|
-
| `format` | string | no | `"compact"` =
|
|
277
|
-
|
|
278
|
-
Skips `node_modules`, `.git`, `dist`, `build`, `__pycache__`, `.next`, `coverage` by default.
|
|
279
|
-
|
|
280
|
-
### get_file_info
|
|
281
|
-
|
|
282
|
-
File metadata without reading content.
|
|
283
|
-
|
|
284
|
-
| Parameter | Type | Required | Description |
|
|
285
|
-
|-----------|------|----------|-------------|
|
|
286
|
-
| `path` | string | yes | File path |
|
|
274
|
+
| `format` | string | no | `"compact"` = shorter path view. `"full"` = include sizes / metadata where available |
|
|
287
275
|
|
|
288
|
-
|
|
276
|
+
- For regular files it returns compact metadata: size, line count when cheap, modification time, type, and binary flag.
|
|
277
|
+
- For directories it returns a gitignore-aware tree.
|
|
278
|
+
- With `pattern`, it switches to flat match mode and works as the preferred replacement for `find` / recursive `ls`.
|
|
289
279
|
|
|
290
280
|
## Hook
|
|
291
281
|
|
|
@@ -324,11 +314,10 @@ Injects a short operational workflow into agent context at session start: no `To
|
|
|
324
314
|
|
|
325
315
|
```
|
|
326
316
|
hex-line-mcp/
|
|
327
|
-
server.mjs MCP server (stdio transport,
|
|
317
|
+
server.mjs MCP server (stdio transport, 9 tools)
|
|
328
318
|
hook.mjs Unified hook (PreToolUse + PostToolUse + SessionStart)
|
|
329
319
|
package.json
|
|
330
320
|
lib/
|
|
331
|
-
hash.mjs FNV-1a hashing, 2-char tags, range checksums
|
|
332
321
|
read.mjs File reading with hash annotation
|
|
333
322
|
edit.mjs Anchor-based edits, diff output
|
|
334
323
|
search.mjs ripgrep wrapper with hash-annotated results
|
|
@@ -336,13 +325,15 @@ hex-line-mcp/
|
|
|
336
325
|
verify.mjs Range checksum verification
|
|
337
326
|
info.mjs File metadata (size, lines, mtime, type)
|
|
338
327
|
tree.mjs Directory tree with .gitignore support
|
|
328
|
+
inspect-path.mjs Unified file/directory inspection
|
|
339
329
|
changes.mjs Semantic git diff via AST
|
|
340
330
|
bulk-replace.mjs Multi-file search-and-replace
|
|
341
331
|
setup.mjs Claude hook installation + output style setup
|
|
342
332
|
format.mjs Output formatting utilities
|
|
343
|
-
coerce.mjs Parameter pass-through (identity)
|
|
344
333
|
security.mjs Path validation, binary detection, size limits
|
|
345
|
-
|
|
334
|
+
@levnikolaevich/hex-common/
|
|
335
|
+
text-protocol/hash.mjs Shared FNV-1a hashing and checksum protocol
|
|
336
|
+
output/normalize.mjs Shared output normalization helpers
|
|
346
337
|
```
|
|
347
338
|
|
|
348
339
|
### Hash Format
|
|
@@ -392,7 +383,7 @@ The edit is rejected with an error showing which lines changed since the last re
|
|
|
392
383
|
<details>
|
|
393
384
|
<summary><b>Is outline available for all file types?</b></summary>
|
|
394
385
|
|
|
395
|
-
Outline works on
|
|
386
|
+
Outline works on JavaScript/TypeScript, Python, C#, PHP, and markdown heading navigation (`.md`/`.mdx`, fenced code blocks ignored). For JSON, YAML, and text files use `read_file` directly. Each outline entry includes a hash anchor (`tag.line-range: symbol`) for direct use in `edit_file`.
|
|
396
387
|
|
|
397
388
|
</details>
|
|
398
389
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generated_from": {
|
|
3
|
+
"source": "tree-sitter-cli-build",
|
|
4
|
+
"tree_sitter_cli_version": "0.26.8",
|
|
5
|
+
"note": "Repo-owned grammar WASM artifacts built from pinned npm grammar packages with the current tree-sitter CLI."
|
|
6
|
+
},
|
|
7
|
+
"grammars": [
|
|
8
|
+
{
|
|
9
|
+
"grammar": "javascript",
|
|
10
|
+
"file": "tree-sitter-javascript.wasm",
|
|
11
|
+
"package": "tree-sitter-javascript",
|
|
12
|
+
"version": "0.25.0",
|
|
13
|
+
"source_subdir": null,
|
|
14
|
+
"sha256": "29d37c59b7797fa1c56419816d1730d5ff5e2ed2077bc44c5d6f50082be09136"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"grammar": "typescript",
|
|
18
|
+
"file": "tree-sitter-typescript.wasm",
|
|
19
|
+
"package": "tree-sitter-typescript",
|
|
20
|
+
"version": "0.23.2",
|
|
21
|
+
"source_subdir": "typescript",
|
|
22
|
+
"sha256": "f7c442260d8bf63b89762af2663655d153f84d169b4b8fedd15a5ba9b29ed3a4"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"grammar": "tsx",
|
|
26
|
+
"file": "tree-sitter-tsx.wasm",
|
|
27
|
+
"package": "tree-sitter-typescript",
|
|
28
|
+
"version": "0.23.2",
|
|
29
|
+
"source_subdir": "tsx",
|
|
30
|
+
"sha256": "4f795eb1fd00d14b7d284add59df8796d3c4b30e49d27979cba70c02298d5f67"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"grammar": "python",
|
|
34
|
+
"file": "tree-sitter-python.wasm",
|
|
35
|
+
"package": "tree-sitter-python",
|
|
36
|
+
"version": "0.25.0",
|
|
37
|
+
"source_subdir": null,
|
|
38
|
+
"sha256": "6183aa51eecace847badb487766e33a0f7725c257b479a0b89c9ff1bcec9c610"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"grammar": "c_sharp",
|
|
42
|
+
"file": "tree-sitter-c_sharp.wasm",
|
|
43
|
+
"package": "tree-sitter-c-sharp",
|
|
44
|
+
"version": "0.23.1",
|
|
45
|
+
"source_subdir": null,
|
|
46
|
+
"sha256": "974cb3e3302c04a5b5e6734494af2ed2fd0c284c38693316ef013922639aecf2"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"grammar": "php",
|
|
50
|
+
"file": "tree-sitter-php.wasm",
|
|
51
|
+
"package": "tree-sitter-php",
|
|
52
|
+
"version": "0.24.2",
|
|
53
|
+
"source_subdir": "php",
|
|
54
|
+
"sha256": "393e65be27e256ed2f1a43e0e70e43de05f77b5563d7dd877bdb44760d5560a6"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/hook.mjs
CHANGED
|
@@ -97,27 +97,15 @@ var OUTLINEABLE_EXT = /* @__PURE__ */ new Set([
|
|
|
97
97
|
".ts",
|
|
98
98
|
".tsx",
|
|
99
99
|
".py",
|
|
100
|
-
".go",
|
|
101
|
-
".rs",
|
|
102
|
-
".java",
|
|
103
|
-
".c",
|
|
104
|
-
".h",
|
|
105
|
-
".cpp",
|
|
106
100
|
".cs",
|
|
107
|
-
".
|
|
108
|
-
".php",
|
|
109
|
-
".kt",
|
|
110
|
-
".swift",
|
|
111
|
-
".sh",
|
|
112
|
-
".bash"
|
|
101
|
+
".php"
|
|
113
102
|
]);
|
|
114
103
|
var REVERSE_TOOL_HINTS = {
|
|
115
104
|
"mcp__hex-line__read_file": "Read (file_path, offset, limit)",
|
|
116
105
|
"mcp__hex-line__edit_file": "Edit (old_string, new_string, replace_all)",
|
|
117
106
|
"mcp__hex-line__write_file": "Write (file_path, content)",
|
|
118
107
|
"mcp__hex-line__grep_search": "Grep (pattern, path)",
|
|
119
|
-
"mcp__hex-
|
|
120
|
-
"mcp__hex-line__get_file_info": "Bash(stat/wc)",
|
|
108
|
+
"mcp__hex-line__inspect_path": "Path info / tree / Bash(ls,stat)",
|
|
121
109
|
"mcp__hex-line__outline": "Read with offset/limit",
|
|
122
110
|
"mcp__hex-line__verify": "Read (re-read file to check freshness)",
|
|
123
111
|
"mcp__hex-line__changes": "Bash(git diff)",
|
|
@@ -131,8 +119,8 @@ var TOOL_HINTS = {
|
|
|
131
119
|
cat: "mcp__hex-line__read_file (not cat/head/tail/less/more)",
|
|
132
120
|
head: "mcp__hex-line__read_file with limit param (not head)",
|
|
133
121
|
tail: "mcp__hex-line__read_file with offset param (not tail)",
|
|
134
|
-
ls: "mcp__hex-
|
|
135
|
-
stat: "mcp__hex-
|
|
122
|
+
ls: "mcp__hex-line__inspect_path for tree or pattern search (not ls/find/tree). E.g. pattern='*-mcp' type='dir'",
|
|
123
|
+
stat: "mcp__hex-line__inspect_path for compact file metadata (not stat/wc/file)",
|
|
136
124
|
grep: "mcp__hex-line__grep_search (not grep/rg). Params: output, literal, context_before, context_after, multiline",
|
|
137
125
|
sed: "mcp__hex-line__edit_file for hash edits, or mcp__hex-line__bulk_replace for text rename (not sed -i)",
|
|
138
126
|
diff: "mcp__hex-line__changes (not diff). Git diff with change symbols",
|
|
@@ -358,7 +346,7 @@ function handlePreToolUse(data) {
|
|
|
358
346
|
advise(hint, DEFERRED_HINT);
|
|
359
347
|
}
|
|
360
348
|
const ext = filePath ? extOf(filePath) : "";
|
|
361
|
-
const outlineHint = filePath && OUTLINEABLE_EXT.has(ext) ? `Use mcp__hex-line__outline(path="${filePath}") for structure, then mcp__hex-line__read_file(path="${filePath}") with ranges to read only what you need.` : filePath ? `Use mcp__hex-line__read_file(path="${filePath}") with ranges or offset/limit` : "Use mcp__hex-
|
|
349
|
+
const outlineHint = filePath && OUTLINEABLE_EXT.has(ext) ? `Use mcp__hex-line__outline(path="${filePath}") for structure, then mcp__hex-line__read_file(path="${filePath}") with ranges to read only what you need.` : filePath ? `Use mcp__hex-line__read_file(path="${filePath}") with ranges or offset/limit` : "Use mcp__hex-line__inspect_path or mcp__hex-line__read_file";
|
|
362
350
|
redirect(outlineHint, "Do not use built-in Read for full reads of large files.\n" + DEFERRED_HINT);
|
|
363
351
|
}
|
|
364
352
|
if (toolName === "Edit") {
|