@levnikolaevich/hex-line-mcp 1.25.0 → 1.26.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 +4 -4
- package/dist/hook.mjs +23 -6
- package/dist/server.mjs +2 -2
- package/output-style.md +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ Advanced / occasional:
|
|
|
46
46
|
|
|
47
47
|
| Event | Trigger | Action |
|
|
48
48
|
|-------|---------|--------|
|
|
49
|
-
| **PreToolUse** | Read/Edit/Write/Grep/Glob on project text scope |
|
|
49
|
+
| **PreToolUse** | Read/Edit/Write/Grep/Glob on project text scope | Advises hex-line by default for project-scoped text files and file discovery; explicit `hooks.mode: "blocking"` hard redirects. Built-in tools stay available for binary/media, plan files in Plan Mode, and text paths outside the current project root |
|
|
50
50
|
| **PreToolUse** | Bash with dangerous commands | Blocks `rm -rf /`, `git push --force`, etc. Agent must confirm with user |
|
|
51
51
|
| **PostToolUse** | Bash with 50+ lines output | RTK: deduplicates, truncates, shows filtered summary to Claude as feedback |
|
|
52
52
|
| **SessionStart** | Session begins | Injects a short bootstrap hint; defers to the active output style when `hex-line` style is enabled |
|
|
@@ -54,7 +54,7 @@ Advanced / occasional:
|
|
|
54
54
|
|
|
55
55
|
### Bash Redirects
|
|
56
56
|
|
|
57
|
-
PreToolUse also intercepts project-scoped file inspection Bash commands: `cat`, `type`, `Get-Content`, `head`, `tail`, `ls`, `dir`, `tree`, `find`, `Get-ChildItem`, `stat`, `wc`, `Get-Item`, `grep`, `rg`, `findstr`, `Select-String`, `sed -i`. Targeted inspection pipelines are redirected
|
|
57
|
+
PreToolUse also intercepts project-scoped file inspection Bash commands: `cat`, `type`, `Get-Content`, `head`, `tail`, `ls`, `dir`, `tree`, `find`, `Get-ChildItem`, `stat`, `wc`, `Get-Item`, `grep`, `rg`, `findstr`, `Select-String`, `sed -i`. Targeted inspection pipelines receive advisory hints by default and are hard redirected only in explicit blocking mode; Git/build/test/docker/network and stdin-filter pipelines remain allowed.
|
|
58
58
|
## Install
|
|
59
59
|
|
|
60
60
|
### MCP Server
|
|
@@ -360,11 +360,11 @@ The unified hook (`hook.mjs`) handles five Claude hook events:
|
|
|
360
360
|
|
|
361
361
|
### PreToolUse: Tool Redirect
|
|
362
362
|
|
|
363
|
-
|
|
363
|
+
Advises built-in `Read`, `Edit`, `Write`, `Grep`, and `Glob` on project-scoped text workflows to use hex-line. Missing or malformed hook state defaults to advisory mode; set `.hex-skills/environment_state.json` to `hooks.mode: "blocking"` to hard-route covered calls. Binary/media files (images, PDFs, notebooks, archives, executables, fonts, media), plan markdown files in Plan Mode, and text paths outside the current project root stay on built-in tools.
|
|
364
364
|
|
|
365
365
|
### PreToolUse: Bash Redirect + Dangerous Blocker
|
|
366
366
|
|
|
367
|
-
Intercepts project-scoped Bash file inspection commands (`cat`, `type`, `Get-Content`, `head`, `tail`, `ls`, `dir`, `tree`, `find`, `Get-ChildItem`, `stat`, `wc`, `Get-Item`, `grep`, `rg`, `findstr`, `Select-String`, `sed -i`, etc.) and
|
|
367
|
+
Intercepts project-scoped Bash file inspection commands (`cat`, `type`, `Get-Content`, `head`, `tail`, `ls`, `dir`, `tree`, `find`, `Get-ChildItem`, `stat`, `wc`, `Get-Item`, `grep`, `rg`, `findstr`, `Select-String`, `sed -i`, etc.) and advises hex-line tools by default. Explicit blocking mode hard redirects covered cases. Dangerous commands (`rm -rf /`, `git push --force`, `git reset --hard`, `DROP TABLE`, `chmod 777`, `mkfs`, `dd`) are always blocked.
|
|
368
368
|
|
|
369
369
|
### PostToolUse: RTK Output Filter
|
|
370
370
|
|
package/dist/hook.mjs
CHANGED
|
@@ -207,6 +207,15 @@ function extOf(filePath) {
|
|
|
207
207
|
function getFilePath(toolInput) {
|
|
208
208
|
return toolInput.file_path || toolInput.path || "";
|
|
209
209
|
}
|
|
210
|
+
function getMutatingTargetPath(toolInput) {
|
|
211
|
+
return toolInput.file_path || toolInput.path || "";
|
|
212
|
+
}
|
|
213
|
+
function isPlanMarkdownFile(filePath) {
|
|
214
|
+
if (!filePath) return false;
|
|
215
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
216
|
+
const name = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
217
|
+
return /^plan_.*\.md$/i.test(name);
|
|
218
|
+
}
|
|
210
219
|
function getGlobScopePath(toolInput) {
|
|
211
220
|
if (toolInput.path) return toolInput.path;
|
|
212
221
|
const pattern = typeof toolInput.pattern === "string" ? toolInput.pattern : "";
|
|
@@ -390,11 +399,11 @@ function _resetHexLineDisabledCache() {
|
|
|
390
399
|
var _hookMode;
|
|
391
400
|
function getHookMode() {
|
|
392
401
|
if (_hookMode !== void 0) return _hookMode;
|
|
393
|
-
_hookMode = "
|
|
402
|
+
_hookMode = "advisory";
|
|
394
403
|
try {
|
|
395
404
|
const stateFile = resolve(process.cwd(), ".hex-skills/environment_state.json");
|
|
396
405
|
const data = JSON.parse(readFileSync(stateFile, "utf-8"));
|
|
397
|
-
if (data.hooks?.mode === "
|
|
406
|
+
if (data.hooks?.mode === "blocking") _hookMode = "blocking";
|
|
398
407
|
} catch {
|
|
399
408
|
}
|
|
400
409
|
return _hookMode;
|
|
@@ -443,7 +452,7 @@ function handlePreToolUse(data) {
|
|
|
443
452
|
const toolName = data.tool_name || "";
|
|
444
453
|
const toolInput = data.tool_input || {};
|
|
445
454
|
if (data.permission_mode === "plan" && HEX_LINE_MUTATING.has(toolName)) {
|
|
446
|
-
const targetPath = (toolInput
|
|
455
|
+
const targetPath = getMutatingTargetPath(toolInput).replace(/\\/g, "/");
|
|
447
456
|
const isPlanSafe = PLAN_SAFE_FOLDERS.some((folder) => targetPath.includes(folder));
|
|
448
457
|
if (!isPlanSafe) {
|
|
449
458
|
block(
|
|
@@ -467,14 +476,22 @@ function handlePreToolUse(data) {
|
|
|
467
476
|
}
|
|
468
477
|
if (toolName === "Read") {
|
|
469
478
|
const ext = filePath ? extOf(filePath) : "";
|
|
479
|
+
if (data.permission_mode === "plan" && isPlanMarkdownFile(filePath)) {
|
|
480
|
+
process.exit(0);
|
|
481
|
+
}
|
|
470
482
|
const rangeHint = isPartialRead(toolInput) ? " Preserve the same offset/limit or ranges." : "";
|
|
471
483
|
const outlineTip = filePath && OUTLINEABLE_EXT.has(ext) ? ` For structure-first discovery: mcp__hex-line__outline then mcp__hex-line__read_file with ranges.` : "";
|
|
472
|
-
const
|
|
484
|
+
const editReadyTip = ' If preparing an edit, call mcp__hex-line__read_file with edit_ready=true and verbosity="full" to get anchors and checksums.';
|
|
485
|
+
const target = filePath ? `Use mcp__hex-line__read_file(file_path="${filePath}").${rangeHint}${outlineTip}${editReadyTip}` : "Use mcp__hex-line__read_file or mcp__hex-line__inspect_path.";
|
|
473
486
|
redirect(target, DEFERRED_HINT);
|
|
474
487
|
}
|
|
475
488
|
if (toolName === "Edit") {
|
|
476
|
-
|
|
477
|
-
|
|
489
|
+
if (data.permission_mode === "plan" && isPlanMarkdownFile(filePath)) {
|
|
490
|
+
process.exit(0);
|
|
491
|
+
}
|
|
492
|
+
const editShape = 'edits=[{"set_line":{"anchor":"ab.12","new_text":"replacement"}}]';
|
|
493
|
+
const target = filePath ? `Use mcp__hex-line__edit_file(file_path="${filePath}", ${editShape}). If you need anchors first: mcp__hex-line__read_file(file_path="${filePath}", edit_ready=true, verbosity="full") or mcp__hex-line__grep_search(output_mode="content", edit_ready=true).` : `Use mcp__hex-line__edit_file(${editShape}). If you need anchors first: mcp__hex-line__grep_search(output_mode="content", edit_ready=true).`;
|
|
494
|
+
redirect(target, "Hash-verified edits for project text files. In default advisory mode, built-in Edit remains available as fallback.\n" + DEFERRED_HINT);
|
|
478
495
|
}
|
|
479
496
|
if (toolName === "Write") {
|
|
480
497
|
const pathNote = filePath ? ` with file_path="${filePath}"` : "";
|
package/dist/server.mjs
CHANGED
|
@@ -4757,7 +4757,7 @@ function walkFiles(dir, rootDir, ig) {
|
|
|
4757
4757
|
return results;
|
|
4758
4758
|
}
|
|
4759
4759
|
function globMatch(filename, pattern) {
|
|
4760
|
-
const re = pattern.replace(/\./g, "\\.").replace(/\{([^}]+)\}/g, (_, alts) => "
|
|
4760
|
+
const re = pattern.replace(/\./g, "\\.").replace(/\{([^}]+)\}/g, (_, alts) => "" + alts.split(",").join("") + "").replace(/\*\*\//g, "").replace(/\*\*/g, "\0").replace(/\*/g, "").replace(/\?/g, ".").replace(/\u0000/g, ".*").replace(/\u0001/g, "(?:.*/)?").replace(/\u0002/g, "(").replace(/\u0003/g, "|").replace(/\u0004/g, ")").replace(/\u0005/g, "[^/]*");
|
|
4761
4761
|
return new RegExp("^" + re + "$").test(filename);
|
|
4762
4762
|
}
|
|
4763
4763
|
function loadGitignore2(rootDir) {
|
|
@@ -4870,7 +4870,7 @@ function errorResult(code, message, recovery, { large = false, extra = null } =
|
|
|
4870
4870
|
}
|
|
4871
4871
|
|
|
4872
4872
|
// server.mjs
|
|
4873
|
-
var version = true ? "1.
|
|
4873
|
+
var version = true ? "1.26.0" : (await null).createRequire(import.meta.url)("./package.json").version;
|
|
4874
4874
|
var STATUS_ENUM = z2.enum(["OK", "ERROR", "AUTO_REBASED", "CONFLICT", "STALE", "INVALID", "NO_CHANGES", "CHANGED", "UNSUPPORTED"]);
|
|
4875
4875
|
var ERROR_SHAPE = z2.object({ code: z2.string(), message: z2.string(), recovery: z2.string() }).optional();
|
|
4876
4876
|
var LINE_REPORT_KEYS = /* @__PURE__ */ new Set([
|
package/output-style.md
CHANGED
|
@@ -58,8 +58,8 @@ Prefer `hex-line` for text files you may inspect or modify. Hash-annotated reads
|
|
|
58
58
|
|
|
59
59
|
## Exceptions
|
|
60
60
|
|
|
61
|
-
- Built-in `Read`/`Edit`/`Write`/`Grep`/`Glob` are fallback only. With the hook active, project-scoped text calls and file discovery
|
|
62
|
-
- Bash is still fine for npm, node, git, docker, curl, non-inspection pipelines, and other runtime workflows. Project file inspection commands
|
|
61
|
+
- Built-in `Read`/`Edit`/`Write`/`Grep`/`Glob` are fallback only by preference. With the hook active, project-scoped text calls and file discovery receive hex-line guidance by default and hard-route only when `hooks.mode` is `blocking`. Built-in OK for images, PDFs, notebooks, plan files in Plan Mode, and text paths outside the current project root.
|
|
62
|
+
- Bash is still fine for npm, node, git, docker, curl, non-inspection pipelines, and other runtime workflows. Project file inspection commands receive hex-line guidance, including Windows-native readers/searchers/listing commands.
|
|
63
63
|
|
|
64
64
|
## hex-graph
|
|
65
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@levnikolaevich/hex-line-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.26.0",
|
|
4
4
|
"mcpName": "io.github.levnikolaevich/hex-line-mcp",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Hash-verified file editing MCP + token efficiency hook for AI coding agents. 9 tools: inspect_path, read, edit, write, grep, outline, verify, changes, bulk_replace.",
|