@levnikolaevich/hex-line-mcp 1.8.0 → 1.8.1
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/dist/server.mjs +59 -5
- package/package.json +1 -1
package/dist/server.mjs
CHANGED
|
@@ -281,7 +281,8 @@ function validateWritePath(filePath) {
|
|
|
281
281
|
import { existsSync as existsSync2 } from "node:fs";
|
|
282
282
|
import { join as join3, dirname as dirname2, relative } from "node:path";
|
|
283
283
|
import { createRequire } from "node:module";
|
|
284
|
-
var
|
|
284
|
+
var HEX_LINE_CONTRACT_VERSION_MIN = 1;
|
|
285
|
+
var HEX_LINE_CONTRACT_VERSION_MAX = 2;
|
|
285
286
|
var _dbs = /* @__PURE__ */ new Map();
|
|
286
287
|
var _driverUnavailable = false;
|
|
287
288
|
function getGraphDB(filePath) {
|
|
@@ -306,12 +307,24 @@ function getGraphDB(filePath) {
|
|
|
306
307
|
return null;
|
|
307
308
|
}
|
|
308
309
|
}
|
|
310
|
+
var _cloneViewAvailable = /* @__PURE__ */ new WeakMap();
|
|
311
|
+
function _hasCloneView(db) {
|
|
312
|
+
if (_cloneViewAvailable.has(db)) return _cloneViewAvailable.get(db);
|
|
313
|
+
try {
|
|
314
|
+
db.prepare("SELECT node_id, norm_hash, file, line_start, display_name FROM hex_line_clone_siblings LIMIT 0").run();
|
|
315
|
+
_cloneViewAvailable.set(db, true);
|
|
316
|
+
return true;
|
|
317
|
+
} catch {
|
|
318
|
+
_cloneViewAvailable.set(db, false);
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
309
322
|
function validateHexLineContract(db) {
|
|
310
323
|
try {
|
|
311
324
|
const contract = db.prepare("SELECT contract_version FROM hex_line_contract LIMIT 1").get();
|
|
312
|
-
if (!contract || contract.contract_version
|
|
325
|
+
if (!contract || contract.contract_version < HEX_LINE_CONTRACT_VERSION_MIN || contract.contract_version > HEX_LINE_CONTRACT_VERSION_MAX) return false;
|
|
313
326
|
db.prepare("SELECT node_id, file, line_start, line_end, display_name, kind, callees, callers FROM hex_line_symbol_annotations LIMIT 1").all();
|
|
314
|
-
db.prepare("SELECT source_id, target_id, source_file, source_line, source_display_name, target_file, target_line, target_display_name FROM hex_line_call_edges LIMIT 1").all();
|
|
327
|
+
db.prepare("SELECT source_id, target_id, source_file, source_line, source_display_name, target_file, target_line, target_display_name, confidence FROM hex_line_call_edges LIMIT 1").all();
|
|
315
328
|
return true;
|
|
316
329
|
} catch {
|
|
317
330
|
return false;
|
|
@@ -363,7 +376,8 @@ function callImpact(db, file, startLine, endLine) {
|
|
|
363
376
|
const dependents = db.prepare(
|
|
364
377
|
`SELECT source_display_name AS name, source_file AS file, source_line AS line
|
|
365
378
|
FROM hex_line_call_edges
|
|
366
|
-
WHERE target_id =
|
|
379
|
+
WHERE target_id = ?
|
|
380
|
+
AND confidence IN ('exact', 'precise')`
|
|
367
381
|
).all(node.node_id);
|
|
368
382
|
for (const dep of dependents) {
|
|
369
383
|
const key = `${dep.file}:${dep.name}`;
|
|
@@ -378,6 +392,39 @@ function callImpact(db, file, startLine, endLine) {
|
|
|
378
392
|
return [];
|
|
379
393
|
}
|
|
380
394
|
}
|
|
395
|
+
function cloneWarning(db, file, startLine, endLine) {
|
|
396
|
+
try {
|
|
397
|
+
if (!_hasCloneView(db)) return [];
|
|
398
|
+
const modified = db.prepare(
|
|
399
|
+
`SELECT node_id
|
|
400
|
+
FROM hex_line_symbol_annotations
|
|
401
|
+
WHERE file = ?
|
|
402
|
+
AND line_start <= ?
|
|
403
|
+
AND line_end >= ?`
|
|
404
|
+
).all(file, endLine, startLine);
|
|
405
|
+
if (modified.length === 0) return [];
|
|
406
|
+
const clones = [];
|
|
407
|
+
const seen = /* @__PURE__ */ new Set();
|
|
408
|
+
for (const node of modified) {
|
|
409
|
+
const siblings = db.prepare(
|
|
410
|
+
`SELECT s2.file, s2.line_start, s2.display_name
|
|
411
|
+
FROM hex_line_clone_siblings s1
|
|
412
|
+
JOIN hex_line_clone_siblings s2 ON s2.norm_hash = s1.norm_hash AND s2.node_id != s1.node_id
|
|
413
|
+
WHERE s1.node_id = ?`
|
|
414
|
+
).all(node.node_id);
|
|
415
|
+
for (const sib of siblings) {
|
|
416
|
+
const key = `${sib.file}:${sib.display_name}`;
|
|
417
|
+
if (!seen.has(key)) {
|
|
418
|
+
seen.add(key);
|
|
419
|
+
clones.push({ name: sib.display_name, file: sib.file, line: sib.line_start });
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return clones.slice(0, 10);
|
|
424
|
+
} catch {
|
|
425
|
+
return [];
|
|
426
|
+
}
|
|
427
|
+
}
|
|
381
428
|
function matchAnnotation(db, file, line) {
|
|
382
429
|
try {
|
|
383
430
|
const node = db.prepare(
|
|
@@ -1569,6 +1616,13 @@ ${serializeReadBlock(block)}`;
|
|
|
1569
1616
|
\u26A0 Call impact: ${affected.length} callers in other files
|
|
1570
1617
|
${list}`;
|
|
1571
1618
|
}
|
|
1619
|
+
const clones = cloneWarning(db, relFile, minLine, maxLine);
|
|
1620
|
+
if (clones.length > 0) {
|
|
1621
|
+
const list = clones.map((c) => `${c.file}:${c.line}`).join(", ");
|
|
1622
|
+
msg += `
|
|
1623
|
+
|
|
1624
|
+
\u26A0 ${clones.length} clone(s): ${list}`;
|
|
1625
|
+
}
|
|
1572
1626
|
}
|
|
1573
1627
|
} catch {
|
|
1574
1628
|
}
|
|
@@ -2786,7 +2840,7 @@ OUTPUT_CAPPED: Output exceeded ${MAX_BULK_OUTPUT_CHARS} chars.`;
|
|
|
2786
2840
|
}
|
|
2787
2841
|
|
|
2788
2842
|
// server.mjs
|
|
2789
|
-
var version = true ? "1.8.
|
|
2843
|
+
var version = true ? "1.8.1" : (await null).createRequire(import.meta.url)("./package.json").version;
|
|
2790
2844
|
var { server, StdioServerTransport } = await createServerRuntime({
|
|
2791
2845
|
name: "hex-line-mcp",
|
|
2792
2846
|
version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@levnikolaevich/hex-line-mcp",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.1",
|
|
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. 10 tools: read, edit, write, grep, outline, verify, directory_tree, file_info, changes, bulk_replace.",
|