grepmax 0.7.1 → 0.7.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.
|
@@ -33,7 +33,8 @@ function installPlugin() {
|
|
|
33
33
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
34
|
try {
|
|
35
35
|
yield runClaudeCommand(["marketplace", "add", "reowens/grepmax"]);
|
|
36
|
-
|
|
36
|
+
yield runClaudeCommand(["marketplace", "update", "grepmax"]);
|
|
37
|
+
console.log("✅ Marketplace updated");
|
|
37
38
|
yield runClaudeCommand(["install", "grepmax"]);
|
|
38
39
|
console.log("✅ Successfully installed the gmax plugin for Claude Code");
|
|
39
40
|
console.log("\nNext steps:");
|
package/dist/commands/mcp.js
CHANGED
|
@@ -246,6 +246,8 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
246
246
|
let _searcher = null;
|
|
247
247
|
let _skeletonizer = null;
|
|
248
248
|
let _indexReady = false;
|
|
249
|
+
let _indexing = false;
|
|
250
|
+
let _indexProgress = "";
|
|
249
251
|
const cleanup = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
250
252
|
if (_vectorDb) {
|
|
251
253
|
try {
|
|
@@ -310,14 +312,33 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
310
312
|
const db = getVectorDb();
|
|
311
313
|
const hasIndex = yield db.hasRowsForPath(projectRoot);
|
|
312
314
|
if (!hasIndex) {
|
|
315
|
+
if (_indexing)
|
|
316
|
+
return; // Already indexing in background
|
|
317
|
+
_indexing = true;
|
|
318
|
+
_indexProgress = "starting...";
|
|
313
319
|
console.log("[MCP] No index found, running initial sync...");
|
|
314
|
-
|
|
315
|
-
|
|
320
|
+
(0, syncer_1.initialSync)({
|
|
321
|
+
projectRoot,
|
|
322
|
+
onProgress: (info) => {
|
|
323
|
+
_indexProgress = `${info.processed}/${info.total || "?"} files`;
|
|
324
|
+
},
|
|
325
|
+
})
|
|
326
|
+
.then(() => {
|
|
327
|
+
_indexReady = true;
|
|
328
|
+
_indexing = false;
|
|
329
|
+
_indexProgress = "";
|
|
330
|
+
console.log("[MCP] Initial sync complete.");
|
|
331
|
+
})
|
|
332
|
+
.catch((e) => {
|
|
333
|
+
_indexing = false;
|
|
334
|
+
_indexProgress = "";
|
|
335
|
+
console.error("[MCP] Index sync failed:", e);
|
|
336
|
+
});
|
|
316
337
|
}
|
|
317
338
|
else {
|
|
318
339
|
console.log("[MCP] Index exists, ready.");
|
|
340
|
+
_indexReady = true;
|
|
319
341
|
}
|
|
320
|
-
_indexReady = true;
|
|
321
342
|
}
|
|
322
343
|
catch (e) {
|
|
323
344
|
console.error("[MCP] Index sync failed:", e);
|
|
@@ -345,6 +366,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
345
366
|
const limit = Math.min(Math.max(Number(args.limit) || 3, 1), 50);
|
|
346
367
|
yield ensureIndexReady();
|
|
347
368
|
ensureWatcher();
|
|
369
|
+
if (_indexing) {
|
|
370
|
+
return ok(`Indexing in progress (${_indexProgress}). Results may be incomplete or empty — try again shortly.`);
|
|
371
|
+
}
|
|
348
372
|
try {
|
|
349
373
|
const searcher = getSearcher();
|
|
350
374
|
// Determine path prefix and display root for relative paths
|
|
@@ -492,6 +516,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
492
516
|
const symbol = String(args.symbol || "");
|
|
493
517
|
if (!symbol)
|
|
494
518
|
return err("Missing required parameter: symbol");
|
|
519
|
+
if (_indexing) {
|
|
520
|
+
return ok(`Indexing in progress (${_indexProgress}). trace_calls requires a complete index — try again shortly.`);
|
|
521
|
+
}
|
|
495
522
|
try {
|
|
496
523
|
const db = getVectorDb();
|
|
497
524
|
const builder = new graph_builder_1.GraphBuilder(db);
|
|
@@ -534,6 +561,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
534
561
|
const pattern = typeof args.pattern === "string" ? args.pattern : undefined;
|
|
535
562
|
const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 100);
|
|
536
563
|
const pathPrefix = typeof args.path === "string" ? args.path : undefined;
|
|
564
|
+
if (_indexing) {
|
|
565
|
+
return ok(`Indexing in progress (${_indexProgress}). list_symbols requires a complete index — try again shortly.`);
|
|
566
|
+
}
|
|
537
567
|
try {
|
|
538
568
|
const db = getVectorDb();
|
|
539
569
|
const table = yield db.ensureTable();
|
|
@@ -621,6 +651,9 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
621
651
|
watcherLine += " — search results may be incomplete";
|
|
622
652
|
}
|
|
623
653
|
}
|
|
654
|
+
const indexingLine = _indexing
|
|
655
|
+
? `Indexing: in progress (${_indexProgress})`
|
|
656
|
+
: "";
|
|
624
657
|
const lines = [
|
|
625
658
|
`Index: ~/.gmax/lancedb (${stats.chunks} chunks, ${fileCount} files)`,
|
|
626
659
|
`Model: ${globalConfig.embedMode === "gpu" ? ((_d = (_c = (_b = config_1.MODEL_TIERS[globalConfig.modelTier]) === null || _b === void 0 ? void 0 : _b.mlxModel) !== null && _c !== void 0 ? _c : config === null || config === void 0 ? void 0 : config.embedModel) !== null && _d !== void 0 ? _d : "unknown") : ((_e = config === null || config === void 0 ? void 0 : config.embedModel) !== null && _e !== void 0 ? _e : "unknown")} (${(_f = config === null || config === void 0 ? void 0 : config.vectorDim) !== null && _f !== void 0 ? _f : "?"}d, ${globalConfig.embedMode})`,
|
|
@@ -628,6 +661,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
628
661
|
? `Last indexed: ${config.indexedAt}`
|
|
629
662
|
: "",
|
|
630
663
|
watcherLine,
|
|
664
|
+
indexingLine,
|
|
631
665
|
"",
|
|
632
666
|
"Indexed directories:",
|
|
633
667
|
...projects.map((p) => { var _a; return ` ${p.name}\t${p.root}\t${(_a = p.lastIndexed) !== null && _a !== void 0 ? _a : "unknown"}`; }),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require("node:fs");
|
|
2
2
|
const _path = require("node:path");
|
|
3
3
|
const http = require("node:http");
|
|
4
|
-
const { spawn } = require("node:child_process");
|
|
4
|
+
const { spawn, execFileSync } = require("node:child_process");
|
|
5
5
|
|
|
6
6
|
function isServerRunning(port) {
|
|
7
7
|
return new Promise((resolve) => {
|
|
@@ -20,12 +20,30 @@ function isServerRunning(port) {
|
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function
|
|
23
|
+
function findMlxServerDir() {
|
|
24
|
+
// Try to find mlx-embed-server relative to the gmax binary (npm install location)
|
|
25
|
+
try {
|
|
26
|
+
const gmaxPath = execFileSync("which gmax", {
|
|
27
|
+
encoding: "utf-8",
|
|
28
|
+
}).trim();
|
|
29
|
+
// gmax binary is a symlink in .bin/ → resolve to package root
|
|
30
|
+
const realPath = fs.realpathSync(gmaxPath);
|
|
31
|
+
const pkgRoot = _path.resolve(_path.dirname(realPath), "..");
|
|
32
|
+
const serverDir = _path.join(pkgRoot, "mlx-embed-server");
|
|
33
|
+
if (fs.existsSync(_path.join(serverDir, "server.py"))) return serverDir;
|
|
34
|
+
} catch {}
|
|
35
|
+
|
|
36
|
+
// Fallback: dev mode — relative to plugin root
|
|
24
37
|
const pluginRoot = __dirname.replace(/\/hooks$/, "");
|
|
25
|
-
const
|
|
26
|
-
const
|
|
38
|
+
const devRoot = _path.resolve(pluginRoot, "../..");
|
|
39
|
+
const devDir = _path.join(devRoot, "mlx-embed-server");
|
|
40
|
+
if (fs.existsSync(_path.join(devDir, "server.py"))) return devDir;
|
|
27
41
|
|
|
28
|
-
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function startPythonServer(serverDir, scriptName, logName) {
|
|
46
|
+
if (!serverDir) return;
|
|
29
47
|
|
|
30
48
|
const logPath = `/tmp/${logName}.log`;
|
|
31
49
|
const out = fs.openSync(logPath, "a");
|
|
@@ -41,7 +59,6 @@ function startPythonServer(scriptName, logName) {
|
|
|
41
59
|
|
|
42
60
|
function startWatcher() {
|
|
43
61
|
try {
|
|
44
|
-
const { execFileSync } = require("node:child_process");
|
|
45
62
|
execFileSync("gmax", ["watch", "-b"], { timeout: 5000, stdio: "ignore" });
|
|
46
63
|
} catch {
|
|
47
64
|
// Watcher may already be running or gmax not in PATH — ignore
|
|
@@ -49,18 +66,19 @@ function startWatcher() {
|
|
|
49
66
|
}
|
|
50
67
|
|
|
51
68
|
async function main() {
|
|
52
|
-
const embedMode =
|
|
53
|
-
process.env.GMAX_EMBED_MODE || process.env.OSGREP_EMBED_MODE || "auto";
|
|
69
|
+
const embedMode = process.env.GMAX_EMBED_MODE || "auto";
|
|
54
70
|
|
|
55
71
|
if (embedMode !== "cpu") {
|
|
72
|
+
const serverDir = findMlxServerDir();
|
|
73
|
+
|
|
56
74
|
// Start MLX embed server (port 8100)
|
|
57
|
-
if (!(await isServerRunning(8100))) {
|
|
58
|
-
startPythonServer("server.py", "mlx-embed-server");
|
|
75
|
+
if (serverDir && !(await isServerRunning(8100))) {
|
|
76
|
+
startPythonServer(serverDir, "server.py", "mlx-embed-server");
|
|
59
77
|
}
|
|
60
78
|
|
|
61
79
|
// Start LLM summarizer server (port 8101)
|
|
62
|
-
if (!(await isServerRunning(8101))) {
|
|
63
|
-
startPythonServer("summarizer.py", "mlx-summarizer");
|
|
80
|
+
if (serverDir && !(await isServerRunning(8101))) {
|
|
81
|
+
startPythonServer(serverDir, "summarizer.py", "mlx-summarizer");
|
|
64
82
|
}
|
|
65
83
|
}
|
|
66
84
|
|
|
@@ -71,7 +89,7 @@ async function main() {
|
|
|
71
89
|
hookSpecificOutput: {
|
|
72
90
|
hookEventName: "SessionStart",
|
|
73
91
|
additionalContext:
|
|
74
|
-
|
|
92
|
+
"gmax MCP ready. Use semantic_search for concept-based code search (5+ words recommended). Use code_skeleton before reading large files. index_status to check health.",
|
|
75
93
|
},
|
|
76
94
|
};
|
|
77
95
|
process.stdout.write(JSON.stringify(response));
|