grepmax 0.26.43 → 0.26.44
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/.claude-plugin/marketplace.json +1 -1
- package/NOTICE +6 -0
- package/README.md +3 -1
- package/dist/bin.js +4 -0
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/mcp.js +142 -67
- package/dist/commands/project.js +0 -1
- package/dist/commands/similar.js +0 -1
- package/dist/commands/skeleton.js +0 -1
- package/dist/commands/status.js +32 -18
- package/dist/commands/surprises.js +0 -1
- package/dist/commands/symbols.js +0 -1
- package/dist/commands/watch.js +2 -1
- package/dist/eval-like-limit-probe.js +60 -41
- package/dist/lib/analysis/surprising-connections.js +4 -3
- package/dist/lib/daemon/daemon.js +14 -2
- package/dist/lib/daemon/graph-handler.js +33 -33
- package/dist/lib/daemon/rows-handler.js +13 -51
- package/dist/lib/daemon/vector-handler.js +18 -17
- package/dist/lib/graph/graph-builder.js +33 -16
- package/dist/lib/graph/impact.js +9 -8
- package/dist/lib/index/index-config.js +2 -2
- package/dist/lib/llm/config.js +9 -3
- package/dist/lib/llm/tools.js +5 -4
- package/dist/lib/search/pagerank.js +2 -1
- package/dist/lib/search/searcher.js +5 -4
- package/dist/lib/skeleton/retriever.js +2 -1
- package/dist/lib/store/lance-sdk.js +46 -0
- package/dist/lib/store/vector-db.js +57 -16
- package/dist/lib/utils/cross-project.js +2 -2
- package/dist/lib/utils/project-registry.js +8 -8
- package/dist/lib/utils/query-timeout.js +53 -13
- package/dist/lib/utils/store-access.js +6 -5
- package/dist/lib/utils/store-context.js +102 -0
- package/dist/lib/utils/stores.js +1 -1
- package/dist/vendor/lancedb/LICENSE +202 -0
- package/dist/vendor/lancedb/NODEJS_THIRD_PARTY_LICENSES.md +668 -0
- package/dist/vendor/lancedb/RUST_THIRD_PARTY_LICENSES.html +14607 -0
- package/dist/vendor/lancedb/arrow.d.ts +296 -0
- package/dist/vendor/lancedb/arrow.js +1145 -0
- package/dist/vendor/lancedb/arrow_type.d.ts +9 -0
- package/dist/vendor/lancedb/arrow_type.js +29 -0
- package/dist/vendor/lancedb/connection.d.ts +508 -0
- package/dist/vendor/lancedb/connection.js +298 -0
- package/dist/vendor/lancedb/embedding/embedding_function.d.ts +103 -0
- package/dist/vendor/lancedb/embedding/embedding_function.js +192 -0
- package/dist/vendor/lancedb/embedding/index.d.ts +37 -0
- package/dist/vendor/lancedb/embedding/index.js +108 -0
- package/dist/vendor/lancedb/embedding/openai.d.ts +16 -0
- package/dist/vendor/lancedb/embedding/openai.js +81 -0
- package/dist/vendor/lancedb/embedding/registry.d.ts +94 -0
- package/dist/vendor/lancedb/embedding/registry.js +221 -0
- package/dist/vendor/lancedb/embedding/transformers.d.ts +36 -0
- package/dist/vendor/lancedb/embedding/transformers.js +110 -0
- package/dist/vendor/lancedb/header.d.ts +162 -0
- package/dist/vendor/lancedb/header.js +217 -0
- package/dist/vendor/lancedb/index.d.ts +246 -0
- package/dist/vendor/lancedb/index.js +176 -0
- package/dist/vendor/lancedb/indices.d.ts +721 -0
- package/dist/vendor/lancedb/indices.js +166 -0
- package/dist/vendor/lancedb/license_header.txt +2 -0
- package/dist/vendor/lancedb/materialized_view.d.ts +69 -0
- package/dist/vendor/lancedb/materialized_view.js +112 -0
- package/dist/vendor/lancedb/merge.d.ts +104 -0
- package/dist/vendor/lancedb/merge.js +120 -0
- package/dist/vendor/lancedb/native.d.ts +1193 -0
- package/dist/vendor/lancedb/native.js +688 -0
- package/dist/vendor/lancedb/oauth.d.ts +66 -0
- package/dist/vendor/lancedb/oauth.js +15 -0
- package/dist/vendor/lancedb/otel.d.ts +26 -0
- package/dist/vendor/lancedb/otel.js +114 -0
- package/dist/vendor/lancedb/permutation.d.ts +143 -0
- package/dist/vendor/lancedb/permutation.js +184 -0
- package/dist/vendor/lancedb/provenance.json +6 -0
- package/dist/vendor/lancedb/query.d.ts +663 -0
- package/dist/vendor/lancedb/query.js +966 -0
- package/dist/vendor/lancedb/rerankers/index.d.ts +5 -0
- package/dist/vendor/lancedb/rerankers/index.js +19 -0
- package/dist/vendor/lancedb/rerankers/rrf.d.ts +14 -0
- package/dist/vendor/lancedb/rerankers/rrf.js +28 -0
- package/dist/vendor/lancedb/sanitize.d.ts +32 -0
- package/dist/vendor/lancedb/sanitize.js +544 -0
- package/dist/vendor/lancedb/scannable.d.ts +92 -0
- package/dist/vendor/lancedb/scannable.js +200 -0
- package/dist/vendor/lancedb/schema.d.ts +16 -0
- package/dist/vendor/lancedb/schema.js +387 -0
- package/dist/vendor/lancedb/table.d.ts +1069 -0
- package/dist/vendor/lancedb/table.js +498 -0
- package/dist/vendor/lancedb/util.d.ts +14 -0
- package/dist/vendor/lancedb/util.js +77 -0
- package/package.json +19 -7
- package/plugins/grepmax/.claude-plugin/plugin.json +1 -1
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "grepmax",
|
|
11
11
|
"source": "./plugins/grepmax",
|
|
12
12
|
"description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
|
|
13
|
-
"version": "0.26.
|
|
13
|
+
"version": "0.26.44",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
package/NOTICE
CHANGED
|
@@ -31,3 +31,9 @@ THIRD-PARTY DEPENDENCIES
|
|
|
31
31
|
|
|
32
32
|
This software depends on various open-source libraries. See package.json for
|
|
33
33
|
a complete list of dependencies and their respective licenses.
|
|
34
|
+
|
|
35
|
+
The distribution includes the unmodified JavaScript runtime from
|
|
36
|
+
@lancedb/lancedb 0.38.0 (https://github.com/lancedb/lancedb), licensed under
|
|
37
|
+
Apache-2.0. Its license and build provenance are included in dist/vendor/lancedb/.
|
|
38
|
+
Its optional provider dependency manifest is not distributed. Platform native
|
|
39
|
+
binaries are installed as separately pinned @lancedb packages.
|
package/README.md
CHANGED
|
@@ -126,7 +126,9 @@ Plugins auto-update when you run `npm install -g grepmax@latest` — no need to
|
|
|
126
126
|
|
|
127
127
|
### MCP Server
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
MCP is local-only: the client spawns it and communicates through stdin/stdout pipes. It has no HTTP, SSE, or TCP listener and cannot be reached over the network. The daemon socket is restricted to your user account.
|
|
130
|
+
|
|
131
|
+
`gmax mcp` starts a stdio-based MCP server for clients that support MCP but can't run shell commands (Cursor, Windsurf, custom agents). Search-backed tools use the singleton daemon when available, avoiding a separate embedding worker per MCP session, and use an in-process worker for supported offline/secondary-store access. An unsupported daemon command requires `gmax watch restart`.
|
|
130
132
|
|
|
131
133
|
| Tool | Description |
|
|
132
134
|
| --- | --- |
|
package/dist/bin.js
CHANGED
|
@@ -75,6 +75,10 @@ function selectHome() {
|
|
|
75
75
|
if (process.env.GMAX_HOME)
|
|
76
76
|
return;
|
|
77
77
|
const argv = process.argv.slice(2);
|
|
78
|
+
// These enumerate/route stores per request rather than pinning the process
|
|
79
|
+
// to its launch cwd's store. In particular an MCP session can serve both.
|
|
80
|
+
if (argv[0] === "mcp" || argv[0] === "status")
|
|
81
|
+
return;
|
|
78
82
|
const match = (0, stores_1.matchStore)(commandTarget(argv, process.cwd()));
|
|
79
83
|
if (match.kind === "primary")
|
|
80
84
|
return;
|
package/dist/commands/doctor.js
CHANGED
|
@@ -58,6 +58,7 @@ const lock_1 = require("../lib/utils/lock");
|
|
|
58
58
|
const mlx_hf_cache_1 = require("../lib/utils/mlx-hf-cache");
|
|
59
59
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
60
60
|
const project_root_1 = require("../lib/utils/project-root");
|
|
61
|
+
const query_timeout_1 = require("../lib/utils/query-timeout");
|
|
61
62
|
const root_availability_1 = require("../lib/utils/root-availability");
|
|
62
63
|
const store_access_1 = require("../lib/utils/store-access");
|
|
63
64
|
function formatSize(bytes) {
|
|
@@ -489,7 +490,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
489
490
|
.query()
|
|
490
491
|
.where("length(summary) > 5")
|
|
491
492
|
.select(["id"])
|
|
492
|
-
.toArray()).length;
|
|
493
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS)).length;
|
|
493
494
|
const coverage = (0, doctor_status_1.summaryCoverageStatus)(withSummary, totalChunks);
|
|
494
495
|
console.log(`${coverage.symbol} ${coverage.message}`);
|
|
495
496
|
}
|
package/dist/commands/mcp.js
CHANGED
|
@@ -79,6 +79,7 @@ const graph_handler_1 = require("../lib/daemon/graph-handler");
|
|
|
79
79
|
const rows_handler_1 = require("../lib/daemon/rows-handler");
|
|
80
80
|
const vector_handler_1 = require("../lib/daemon/vector-handler");
|
|
81
81
|
const test_hits_1 = require("../lib/graph/test-hits");
|
|
82
|
+
const embedding_generation_1 = require("../lib/index/embedding-generation");
|
|
82
83
|
const embedding_status_1 = require("../lib/index/embedding-status");
|
|
83
84
|
const index_config_1 = require("../lib/index/index-config");
|
|
84
85
|
const syncer_1 = require("../lib/index/syncer");
|
|
@@ -100,8 +101,11 @@ const project_registry_1 = require("../lib/utils/project-registry");
|
|
|
100
101
|
const project_root_1 = require("../lib/utils/project-root");
|
|
101
102
|
const scope_filter_1 = require("../lib/utils/scope-filter");
|
|
102
103
|
const store_access_1 = require("../lib/utils/store-access");
|
|
104
|
+
const store_context_1 = require("../lib/utils/store-context");
|
|
105
|
+
const stores_1 = require("../lib/utils/stores");
|
|
103
106
|
const watcher_launcher_1 = require("../lib/utils/watcher-launcher");
|
|
104
107
|
const watcher_store_1 = require("../lib/utils/watcher-store");
|
|
108
|
+
const pool_1 = require("../lib/workers/pool");
|
|
105
109
|
// ---------------------------------------------------------------------------
|
|
106
110
|
// Helpers
|
|
107
111
|
// ---------------------------------------------------------------------------
|
|
@@ -143,9 +147,6 @@ function isMcpSessionFallback(error) {
|
|
|
143
147
|
/**
|
|
144
148
|
* MCP's read-tool fallback policy, in one object so every tool shares it.
|
|
145
149
|
*
|
|
146
|
-
* - `fallbackOnUnknownVerb` — a daemon older than this build does not know the
|
|
147
|
-
* read verbs (the live 0.26.27 daemon does not); answer from the store rather
|
|
148
|
-
* than failing the tool call. Removed one release after the verbs ship.
|
|
149
150
|
* - `fallbackOnOversize` — the daemon's 2 MB response cap. See
|
|
150
151
|
* `isOversizeError` for why MCP opts in and the CLI does not.
|
|
151
152
|
* - `extraFallback` — the two session-readiness answers above.
|
|
@@ -161,7 +162,6 @@ function isMcpSessionFallback(error) {
|
|
|
161
162
|
const MCP_WATCH_LEASE_RENEW_MS = 5 * 60 * 1000;
|
|
162
163
|
const MCP_WATCH_LEASE_TTL_MS = 3 * MCP_WATCH_LEASE_RENEW_MS;
|
|
163
164
|
const MCP_STORE_FALLBACK = {
|
|
164
|
-
fallbackOnUnknownVerb: true,
|
|
165
165
|
fallbackOnOversize: true,
|
|
166
166
|
extraFallback: isMcpSessionFallback,
|
|
167
167
|
};
|
|
@@ -172,7 +172,6 @@ const MCP_STORE_FALLBACK = {
|
|
|
172
172
|
*/
|
|
173
173
|
function shouldFallbackMcpDaemonSearch(error) {
|
|
174
174
|
return ((0, store_access_1.classifyDaemonError)(error) === "no-daemon" ||
|
|
175
|
-
(0, store_access_1.isUnknownCommandError)(error) ||
|
|
176
175
|
(0, store_access_1.isOversizeError)(error) ||
|
|
177
176
|
isMcpSessionFallback(error));
|
|
178
177
|
}
|
|
@@ -192,14 +191,30 @@ function resolveMcpProject(requested, currentRoot, projects = (0, project_regist
|
|
|
192
191
|
if (byName.length > 1)
|
|
193
192
|
return undefined;
|
|
194
193
|
const resolved = path.resolve(value);
|
|
195
|
-
|
|
194
|
+
const physical = (value) => {
|
|
195
|
+
try {
|
|
196
|
+
return fs.realpathSync(value);
|
|
197
|
+
}
|
|
198
|
+
catch (_a) {
|
|
199
|
+
return path.resolve(value);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
return projects.find((project) => physical(project.root) === physical(resolved));
|
|
196
203
|
}
|
|
197
204
|
const resolvedCurrent = path.resolve(currentRoot);
|
|
198
|
-
const
|
|
205
|
+
const physical = (value) => {
|
|
206
|
+
try {
|
|
207
|
+
return fs.realpathSync(value);
|
|
208
|
+
}
|
|
209
|
+
catch (_a) {
|
|
210
|
+
return path.resolve(value);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const exact = projects.find((project) => physical(project.root) === physical(resolvedCurrent));
|
|
199
214
|
if (exact)
|
|
200
215
|
return exact;
|
|
201
216
|
return projects
|
|
202
|
-
.filter((project) => (0, path_containment_1.isPathWithin)(project.root, resolvedCurrent))
|
|
217
|
+
.filter((project) => (0, path_containment_1.isPathWithin)(physical(project.root), physical(resolvedCurrent)))
|
|
203
218
|
.sort((a, b) => b.root.length - a.root.length)[0];
|
|
204
219
|
}
|
|
205
220
|
function containMcpTarget(root, target) {
|
|
@@ -380,6 +395,11 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
380
395
|
// --- Project context ---
|
|
381
396
|
const projectRoot = (0, project_root_1.findProjectRoot)(process.cwd());
|
|
382
397
|
const paths = (0, project_root_1.ensureProjectPaths)(projectRoot);
|
|
398
|
+
const currentRoot = () => { var _a; var _b; return (_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.root) !== null && _b !== void 0 ? _b : projectRoot; };
|
|
399
|
+
const storeProjects = () => { var _a; var _b; return (_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.projects) !== null && _b !== void 0 ? _b : (0, project_registry_1.listProjects)(); };
|
|
400
|
+
const storeConfig = () => { var _a; var _b; return (_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.config) !== null && _b !== void 0 ? _b : (0, index_config_1.readGlobalConfig)(); };
|
|
401
|
+
const secondary = () => { var _a; var _b; return (_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.secondary) !== null && _b !== void 0 ? _b : false; };
|
|
402
|
+
const storeDir = () => { var _a; var _b; return (_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.lancedbDir) !== null && _b !== void 0 ? _b : paths.lancedbDir; };
|
|
383
403
|
// Propagate project root to worker processes
|
|
384
404
|
process.env.GMAX_PROJECT_ROOT = paths.root;
|
|
385
405
|
// --- Store access ---
|
|
@@ -388,15 +408,15 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
388
408
|
* `inProcess` branch is entered only when no daemon serves the verb.
|
|
389
409
|
*/
|
|
390
410
|
function readStore(name, opts) {
|
|
391
|
-
return (0, store_access_1.withStoreRead)(name, Object.assign(Object.assign({}, opts), MCP_STORE_FALLBACK));
|
|
411
|
+
return (0, store_access_1.withStoreRead)(name, Object.assign(Object.assign(Object.assign({}, opts), MCP_STORE_FALLBACK), { skipDaemon: secondary() }));
|
|
392
412
|
}
|
|
393
413
|
/** Open the shared store for the duration of one fallback, then close it. */
|
|
394
414
|
function localStore(fn) {
|
|
395
|
-
return (0, rows_handler_1.withLocalStore)(
|
|
415
|
+
return (0, rows_handler_1.withLocalStore)(storeDir(), fn, storeConfig().vectorDim);
|
|
396
416
|
}
|
|
397
417
|
/** A graph verb with MCP's fallback allowances. */
|
|
398
418
|
function graphVerb(verb, call) {
|
|
399
|
-
return (0, graph_handler_1.callGraphVerb)(verb, Object.assign(Object.assign({}, call), { fallback: MCP_STORE_FALLBACK }));
|
|
419
|
+
return (0, graph_handler_1.callGraphVerb)(verb, Object.assign(Object.assign({}, call), { fallback: Object.assign(Object.assign({}, MCP_STORE_FALLBACK), (secondary() ? { skipDaemon: true } : {})) }));
|
|
400
420
|
}
|
|
401
421
|
/**
|
|
402
422
|
* MCP tools take no `--in`/`--exclude`, so a tool's scope is always the
|
|
@@ -440,8 +460,16 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
440
460
|
};
|
|
441
461
|
},
|
|
442
462
|
inProcess: () => localStore((deps) => __awaiter(this, void 0, void 0, function* () {
|
|
443
|
-
const
|
|
444
|
-
|
|
463
|
+
const pool = secondary()
|
|
464
|
+
? new pool_1.WorkerPool((0, embedding_generation_1.resolveEmbeddingGeneration)(storeConfig()), storeConfig().embedMode)
|
|
465
|
+
: undefined;
|
|
466
|
+
try {
|
|
467
|
+
const searcher = new searcher_1.Searcher(deps.vectorDb, pool);
|
|
468
|
+
return yield searcher.search(args.query, args.limit, { rerank: args.rerank, seeds: args.seeds }, args.filters, args.pathPrefix);
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
yield pool === null || pool === void 0 ? void 0 : pool.destroy();
|
|
472
|
+
}
|
|
445
473
|
})),
|
|
446
474
|
daemonErrorMessage: (resp) => [resp.error, resp.hint]
|
|
447
475
|
.filter((value) => typeof value === "string" && value)
|
|
@@ -509,7 +537,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
509
537
|
* order. Batched so a per-symbol loop costs one round trip, not hundreds.
|
|
510
538
|
*/
|
|
511
539
|
function locateRows(root, req) {
|
|
512
|
-
return (0, rows_handler_1.readRows)(Object.assign({ name: "locate", projectRoot: root, lancedbDir:
|
|
540
|
+
return (0, rows_handler_1.readRows)(Object.assign({ name: "locate", projectRoot: root, lancedbDir: storeDir(), vectorDim: storeConfig().vectorDim, scope: projectScope(root), fallback: Object.assign(Object.assign({}, MCP_STORE_FALLBACK), { skipDaemon: secondary() }) }, req));
|
|
513
541
|
}
|
|
514
542
|
/**
|
|
515
543
|
* Chunk and file totals for `index_status`, summed per registered project.
|
|
@@ -574,8 +602,8 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
574
602
|
return __awaiter(this, void 0, void 0, function* () {
|
|
575
603
|
if (_indexReady)
|
|
576
604
|
return;
|
|
577
|
-
const projects = (
|
|
578
|
-
const isRegistered = projects.some((p) => p.root ===
|
|
605
|
+
const projects = storeProjects();
|
|
606
|
+
const isRegistered = projects.some((p) => p.root === currentRoot());
|
|
579
607
|
if (isRegistered) {
|
|
580
608
|
_indexReady = true;
|
|
581
609
|
}
|
|
@@ -593,8 +621,10 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
593
621
|
return __awaiter(this, void 0, void 0, function* () {
|
|
594
622
|
var _a;
|
|
595
623
|
try {
|
|
596
|
-
const watchRoot = root !== null && root !== void 0 ? root : (_a = resolveMcpProject(undefined,
|
|
597
|
-
if (!watchRoot
|
|
624
|
+
const watchRoot = root !== null && root !== void 0 ? root : (_a = resolveMcpProject(undefined, currentRoot(), storeProjects())) === null || _a === void 0 ? void 0 : _a.root;
|
|
625
|
+
if (!watchRoot ||
|
|
626
|
+
secondary() ||
|
|
627
|
+
(0, stores_1.matchStore)(watchRoot).kind !== "primary")
|
|
598
628
|
return;
|
|
599
629
|
const result = yield (0, watcher_launcher_1.launchWatcher)(watchRoot, WATCH_LEASE);
|
|
600
630
|
if (result.ok && !result.reused) {
|
|
@@ -614,10 +644,10 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
614
644
|
// covers the cwd, and scope to it instead of silently widening to the whole
|
|
615
645
|
// index. `root` is the registered project root to scope to.
|
|
616
646
|
function resolveRegisteredProject(requested) {
|
|
617
|
-
const project = resolveMcpProject(requested,
|
|
647
|
+
const project = resolveMcpProject(requested, currentRoot(), storeProjects());
|
|
618
648
|
if (project)
|
|
619
649
|
return { proj: project, root: project.root };
|
|
620
|
-
return { proj: undefined, root:
|
|
650
|
+
return { proj: undefined, root: currentRoot() };
|
|
621
651
|
}
|
|
622
652
|
// --- Tool handlers ---
|
|
623
653
|
function handleSemanticSearch(args_1) {
|
|
@@ -648,7 +678,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
648
678
|
if (typeof args.root === "string") {
|
|
649
679
|
return err("Project not added to gmax yet. Run `gmax add` to index it first.");
|
|
650
680
|
}
|
|
651
|
-
const indexed = (
|
|
681
|
+
const indexed = storeProjects().filter((p) => { var _a; return p.status !== "pending" && ((_a = p.chunkCount) !== null && _a !== void 0 ? _a : 0) > 0; });
|
|
652
682
|
if (indexed.length === 0) {
|
|
653
683
|
return err("No indexed projects yet. cd into a repo and run `gmax add` to index it first.");
|
|
654
684
|
}
|
|
@@ -692,7 +722,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
692
722
|
excludeProjects: typeof args.exclude_projects === "string"
|
|
693
723
|
? args.exclude_projects
|
|
694
724
|
: undefined,
|
|
695
|
-
});
|
|
725
|
+
}, storeProjects());
|
|
696
726
|
if (crossScope.projectRoots.length === 0) {
|
|
697
727
|
return err("No matching indexed projects.");
|
|
698
728
|
}
|
|
@@ -709,7 +739,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
709
739
|
const selectedRoots = searchAll
|
|
710
740
|
? new Set((_a = filters.projectRoots) !== null && _a !== void 0 ? _a : [])
|
|
711
741
|
: new Set([resolvedRoot]);
|
|
712
|
-
(0, embedding_status_1.assertEmbeddingSearchCompatible)((
|
|
742
|
+
(0, embedding_status_1.assertEmbeddingSearchCompatible)(storeProjects().filter((project) => selectedRoots.has(project.root)), storeConfig());
|
|
713
743
|
// Aider-style seeding: the agent passes its open files / discussed
|
|
714
744
|
// symbols; the searcher biases candidate generation toward them.
|
|
715
745
|
const parseSeedList = (v) => {
|
|
@@ -1711,26 +1741,38 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1711
1741
|
});
|
|
1712
1742
|
}
|
|
1713
1743
|
function handleListProjects() {
|
|
1714
|
-
return __awaiter(this,
|
|
1744
|
+
return __awaiter(this, arguments, void 0, function* (args = {}) {
|
|
1715
1745
|
var _a;
|
|
1716
1746
|
try {
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1747
|
+
const inventory = args.root === undefined ? (0, store_context_1.storeInventory)() : [];
|
|
1748
|
+
const projects = [
|
|
1749
|
+
...storeProjects(),
|
|
1750
|
+
...inventory
|
|
1751
|
+
.filter((store) => { var _a; var _b; return store.home !==
|
|
1752
|
+
((_b = (_a = (0, store_context_1.currentStoreContext)()) === null || _a === void 0 ? void 0 : _a.home) !== null && _b !== void 0 ? _b : config_1.PATHS.globalRoot); })
|
|
1753
|
+
.flatMap((store) => store.projects),
|
|
1754
|
+
];
|
|
1755
|
+
if (projects.length === 0 && inventory.length === 0) {
|
|
1719
1756
|
return ok("No projects indexed yet. cd into a repo and run `gmax add` to index it.");
|
|
1720
1757
|
}
|
|
1721
|
-
const currentName = (_a = resolveMcpProject(undefined,
|
|
1722
|
-
const globalConfig = (
|
|
1758
|
+
const currentName = (_a = resolveMcpProject(undefined, currentRoot(), storeProjects())) === null || _a === void 0 ? void 0 : _a.name;
|
|
1759
|
+
const globalConfig = storeConfig();
|
|
1723
1760
|
const lines = projects.map((p) => {
|
|
1724
1761
|
const here = p.name === currentName ? " (current)" : "";
|
|
1725
1762
|
const chunks = typeof p.chunkCount === "number"
|
|
1726
1763
|
? `\t(${p.chunkCount} chunks)`
|
|
1727
1764
|
: "";
|
|
1728
|
-
const
|
|
1765
|
+
const matching = inventory.find((store) => store.projects.some((project) => project.root === p.root));
|
|
1766
|
+
const identity = (0, embedding_status_1.projectEmbeddingStatus)(p, matching ? (0, index_config_1.readGlobalConfig)(matching.home) : globalConfig);
|
|
1729
1767
|
return `${p.name}${here}\t${p.root}\t${p.status}\tembedding=${identity.state}${chunks}`;
|
|
1730
1768
|
});
|
|
1731
1769
|
return ok(`${projects.length} indexed project(s). ` +
|
|
1732
1770
|
`Pass a name to semantic_search via projects:"name", or use scope:"all".\n\n` +
|
|
1733
|
-
lines.join("\n")
|
|
1771
|
+
lines.join("\n") +
|
|
1772
|
+
inventory
|
|
1773
|
+
.filter((store) => store.state !== "mounted")
|
|
1774
|
+
.map((store) => `\nStore ${store.home}: ${store.state}${store.error ? ` — ${store.error}` : ""}`)
|
|
1775
|
+
.join(""));
|
|
1734
1776
|
}
|
|
1735
1777
|
catch (e) {
|
|
1736
1778
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -1742,18 +1784,20 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1742
1784
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1743
1785
|
var _a, _b;
|
|
1744
1786
|
try {
|
|
1745
|
-
const globalConfig = (
|
|
1746
|
-
const projects = (
|
|
1747
|
-
const currentProject = resolveMcpProject(undefined,
|
|
1787
|
+
const globalConfig = storeConfig();
|
|
1788
|
+
const projects = storeProjects();
|
|
1789
|
+
const currentProject = resolveMcpProject(undefined, currentRoot(), storeProjects());
|
|
1748
1790
|
const identity = (0, embedding_status_1.projectEmbeddingStatus)(currentProject, globalConfig);
|
|
1749
1791
|
const { chunks, files } = yield indexTotals(projects);
|
|
1750
|
-
const daemonStatus =
|
|
1792
|
+
const daemonStatus = secondary()
|
|
1793
|
+
? { ok: true, projects: [] }
|
|
1794
|
+
: yield (0, daemon_client_1.sendDaemonCommand)({ cmd: "status" });
|
|
1751
1795
|
const watched = (Array.isArray(daemonStatus.projects) ? daemonStatus.projects : []);
|
|
1752
1796
|
const daemonProject = watched.find((p) => p.root === (currentProject === null || currentProject === void 0 ? void 0 : currentProject.root));
|
|
1753
1797
|
// Only use the registry when no daemon answered; sandboxed reads stay IPC-only.
|
|
1754
1798
|
const watcher = daemonStatus.ok
|
|
1755
1799
|
? undefined
|
|
1756
|
-
: (0, watcher_store_1.getWatcherCoveringPath)(
|
|
1800
|
+
: (0, watcher_store_1.getWatcherCoveringPath)(currentRoot());
|
|
1757
1801
|
let watcherLine = "Watcher: not running";
|
|
1758
1802
|
if (watcher) {
|
|
1759
1803
|
const status = (_a = watcher.status) !== null && _a !== void 0 ? _a : "unknown";
|
|
@@ -1778,7 +1822,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
1778
1822
|
// per-project chunk counts) lives in `list_projects` — keep this tool
|
|
1779
1823
|
// focused on index health and avoid the N-project LanceDB scans.
|
|
1780
1824
|
const lines = [
|
|
1781
|
-
`Index:
|
|
1825
|
+
`Index: ${storeDir()} (${chunks} chunks, ${files} files)`,
|
|
1782
1826
|
`Configured embedding: ${identity.configured.tier} ${identity.configured.vectorDim}d [${(0, embedding_status_1.embeddingFingerprintLabel)(identity.configured.fingerprint)}] (${globalConfig.embedMode})`,
|
|
1783
1827
|
identity.built
|
|
1784
1828
|
? `Built embedding: ${identity.built.tier} ${identity.built.vectorDim}d [${(0, embedding_status_1.embeddingFingerprintLabel)(identity.built.fingerprint)}] (${identity.state})`
|
|
@@ -2001,6 +2045,8 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2001
2045
|
function handleRecentChanges(args) {
|
|
2002
2046
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2003
2047
|
var _a, e_1, _b, _c;
|
|
2048
|
+
var _d;
|
|
2049
|
+
var _e;
|
|
2004
2050
|
ensureWatcher();
|
|
2005
2051
|
const limit = Math.min(Math.max(Number(args.limit) || 20, 1), 50);
|
|
2006
2052
|
const { proj, root } = resolveRegisteredProject(args.root);
|
|
@@ -2008,13 +2054,13 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2008
2054
|
return err("Project not added to gmax yet.");
|
|
2009
2055
|
const prefix = root.endsWith("/") ? root : `${root}/`;
|
|
2010
2056
|
try {
|
|
2011
|
-
const metaCache = new meta_cache_1.MetaCache(config_1.PATHS.lmdbPath);
|
|
2057
|
+
const metaCache = new meta_cache_1.MetaCache((_e = (_d = (0, store_context_1.currentStoreContext)()) === null || _d === void 0 ? void 0 : _d.lmdbPath) !== null && _e !== void 0 ? _e : config_1.PATHS.lmdbPath);
|
|
2012
2058
|
try {
|
|
2013
2059
|
const files = [];
|
|
2014
2060
|
try {
|
|
2015
|
-
for (var
|
|
2016
|
-
_c =
|
|
2017
|
-
|
|
2061
|
+
for (var _f = true, _g = __asyncValues(metaCache.entries()), _h; _h = yield _g.next(), _a = _h.done, !_a; _f = true) {
|
|
2062
|
+
_c = _h.value;
|
|
2063
|
+
_f = false;
|
|
2018
2064
|
const { path: p, entry } = _c;
|
|
2019
2065
|
if (p.startsWith(prefix)) {
|
|
2020
2066
|
files.push({ path: p, mtimeMs: entry.mtimeMs });
|
|
@@ -2024,7 +2070,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2024
2070
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2025
2071
|
finally {
|
|
2026
2072
|
try {
|
|
2027
|
-
if (!
|
|
2073
|
+
if (!_f && !_a && (_b = _g.return)) yield _b.call(_g);
|
|
2028
2074
|
}
|
|
2029
2075
|
finally { if (e_1) throw e_1.error; }
|
|
2030
2076
|
}
|
|
@@ -2069,7 +2115,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2069
2115
|
const { proj, root } = resolveRegisteredProject();
|
|
2070
2116
|
if (!proj)
|
|
2071
2117
|
return err("Project not added to gmax yet.");
|
|
2072
|
-
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], (
|
|
2118
|
+
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], storeConfig());
|
|
2073
2119
|
const changedFiles = getChangedFiles(ref, root);
|
|
2074
2120
|
if (changedFiles.length === 0) {
|
|
2075
2121
|
return ok(ref
|
|
@@ -2269,7 +2315,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2269
2315
|
const { proj, root } = resolveRegisteredProject();
|
|
2270
2316
|
if (!proj)
|
|
2271
2317
|
return err("Project not added to gmax yet.");
|
|
2272
|
-
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], (
|
|
2318
|
+
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], storeConfig());
|
|
2273
2319
|
const isFile = target.includes("/") ||
|
|
2274
2320
|
(target.includes(".") && !target.includes(" "));
|
|
2275
2321
|
// Resolved here: containment is this process's filesystem question.
|
|
@@ -2335,7 +2381,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2335
2381
|
const { proj, root } = resolveRegisteredProject();
|
|
2336
2382
|
if (!proj)
|
|
2337
2383
|
return err("Project not added to gmax yet.");
|
|
2338
|
-
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], (
|
|
2384
|
+
(0, embedding_status_1.assertEmbeddingSearchCompatible)([proj], storeConfig());
|
|
2339
2385
|
const searchOptions = { rerank: process.env.GMAX_RERANK === "1" };
|
|
2340
2386
|
const response = yield searchStore(Object.assign({ projectRoot: root, query: topic, limit, filters: {}, pathPrefix: root }, searchOptions));
|
|
2341
2387
|
if (response.data.length === 0)
|
|
@@ -2405,7 +2451,11 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2405
2451
|
return err("LLM server not available. Run `gmax llm on && gmax llm start`.");
|
|
2406
2452
|
}
|
|
2407
2453
|
const { investigate } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/investigate")));
|
|
2408
|
-
const inv = yield investigate({
|
|
2454
|
+
const inv = yield investigate({
|
|
2455
|
+
question,
|
|
2456
|
+
projectRoot: currentRoot(),
|
|
2457
|
+
maxRounds,
|
|
2458
|
+
});
|
|
2409
2459
|
return ok(inv.answer);
|
|
2410
2460
|
}
|
|
2411
2461
|
catch (e) {
|
|
@@ -2429,12 +2479,15 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2429
2479
|
return err("LLM server not available. Run `gmax llm on && gmax llm start`.");
|
|
2430
2480
|
}
|
|
2431
2481
|
const { reviewCommit } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/review")));
|
|
2432
|
-
const rev = yield reviewCommit({
|
|
2482
|
+
const rev = yield reviewCommit({
|
|
2483
|
+
commitRef,
|
|
2484
|
+
projectRoot: currentRoot(),
|
|
2485
|
+
});
|
|
2433
2486
|
if (rev.clean) {
|
|
2434
2487
|
return ok(`Clean commit (${rev.commit}) — no issues found in ${rev.duration}s.`);
|
|
2435
2488
|
}
|
|
2436
2489
|
const { readReport } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/report")));
|
|
2437
|
-
const report = readReport(
|
|
2490
|
+
const report = readReport(currentRoot());
|
|
2438
2491
|
const entry = report === null || report === void 0 ? void 0 : report.reviews.find((r) => r.commit === rev.commit);
|
|
2439
2492
|
return ok(JSON.stringify({
|
|
2440
2493
|
commit: rev.commit,
|
|
@@ -2459,26 +2512,26 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2459
2512
|
// returns the location.
|
|
2460
2513
|
const { extractDiff, extractSymbols, fileChurn } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/diff")));
|
|
2461
2514
|
const { computeRiskTable, formatRiskTable } = yield Promise.resolve().then(() => __importStar(require("../lib/review/risk")));
|
|
2462
|
-
const diff = extractDiff(commitRef,
|
|
2515
|
+
const diff = extractDiff(commitRef, currentRoot());
|
|
2463
2516
|
const symbols = diff ? extractSymbols(diff) : [];
|
|
2464
2517
|
if (symbols.length === 0) {
|
|
2465
2518
|
return ok("(no changed symbols in this diff)");
|
|
2466
2519
|
}
|
|
2467
|
-
const scope = projectScope(
|
|
2520
|
+
const scope = projectScope(currentRoot());
|
|
2468
2521
|
const facts = yield graphVerb("graph.risk", {
|
|
2469
|
-
projectRoot,
|
|
2522
|
+
projectRoot: currentRoot(),
|
|
2470
2523
|
scope,
|
|
2471
2524
|
payload: { symbols },
|
|
2472
2525
|
render: (resp) => { var _a; return (_a = resp.facts) !== null && _a !== void 0 ? _a : []; },
|
|
2473
2526
|
inProcess: () => localStore((deps) => (0, graph_handler_1.runGraphRisk)(deps.vectorDb, {
|
|
2474
2527
|
symbols,
|
|
2475
|
-
queryRoot:
|
|
2528
|
+
queryRoot: currentRoot(),
|
|
2476
2529
|
scope,
|
|
2477
2530
|
})),
|
|
2478
2531
|
});
|
|
2479
|
-
const prefix =
|
|
2480
|
-
?
|
|
2481
|
-
: `${
|
|
2532
|
+
const prefix = currentRoot().endsWith("/")
|
|
2533
|
+
? currentRoot()
|
|
2534
|
+
: `${currentRoot()}/`;
|
|
2482
2535
|
const rows = computeRiskTable(facts.map((fact) => ({
|
|
2483
2536
|
symbol: fact.symbol,
|
|
2484
2537
|
file: fact.file
|
|
@@ -2489,7 +2542,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2489
2542
|
line: fact.line,
|
|
2490
2543
|
callerCount: fact.callerCount,
|
|
2491
2544
|
hasTests: fact.hasTests,
|
|
2492
|
-
churn: fileChurn(fact.file,
|
|
2545
|
+
churn: fileChurn(fact.file, currentRoot()),
|
|
2493
2546
|
})));
|
|
2494
2547
|
return rows.length === 0
|
|
2495
2548
|
? ok("(no changed symbols in this diff)")
|
|
@@ -2504,7 +2557,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2504
2557
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2505
2558
|
try {
|
|
2506
2559
|
const { readReport, formatReportText } = yield Promise.resolve().then(() => __importStar(require("../lib/llm/report")));
|
|
2507
|
-
const report = readReport(
|
|
2560
|
+
const report = readReport(currentRoot());
|
|
2508
2561
|
if (!report || report.reviews.length === 0) {
|
|
2509
2562
|
return ok("No review findings yet.");
|
|
2510
2563
|
}
|
|
@@ -2519,6 +2572,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2519
2572
|
});
|
|
2520
2573
|
}
|
|
2521
2574
|
// --- MCP server setup ---
|
|
2575
|
+
// Local-only MCP: client-owned pipes, no HTTP/SSE/TCP listener or host option.
|
|
2522
2576
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
2523
2577
|
const server = new mcp_js_1.McpServer({
|
|
2524
2578
|
name: "gmax",
|
|
@@ -2554,7 +2608,7 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2554
2608
|
source: "mcp",
|
|
2555
2609
|
tool: name,
|
|
2556
2610
|
query: mcpLogQuery(name, toolArgs),
|
|
2557
|
-
project:
|
|
2611
|
+
project: currentRoot(),
|
|
2558
2612
|
results: resultLines,
|
|
2559
2613
|
ms: Date.now() - startMs,
|
|
2560
2614
|
error: result.isError ? text.slice(0, 200) : undefined,
|
|
@@ -2566,21 +2620,42 @@ exports.mcp = new commander_1.Command("mcp")
|
|
|
2566
2620
|
// shapes give us free input validation (the SDK rejects calls that violate
|
|
2567
2621
|
// the schema before the handler runs); handlers stay defensively coded.
|
|
2568
2622
|
function tool(name, config, handler) {
|
|
2569
|
-
server.registerTool(name, config, (rawArgs) => __awaiter(this, void 0, void 0, function* () {
|
|
2623
|
+
server.registerTool(name, Object.assign(Object.assign({}, config), { inputSchema: Object.assign({ root: zod_1.z.string().optional() }, config.inputSchema) }), (rawArgs) => __awaiter(this, void 0, void 0, function* () {
|
|
2570
2624
|
let args = (rawArgs !== null && rawArgs !== void 0 ? rawArgs : {});
|
|
2571
2625
|
const startMs = Date.now();
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
if (
|
|
2575
|
-
const
|
|
2626
|
+
let target = projectRoot;
|
|
2627
|
+
try {
|
|
2628
|
+
if (typeof args.root === "string" && args.root.trim()) {
|
|
2629
|
+
const raw = args.root.trim();
|
|
2630
|
+
if (path.isAbsolute(raw) || raw.includes(path.sep))
|
|
2631
|
+
target = path.resolve(raw);
|
|
2632
|
+
else {
|
|
2633
|
+
const projects = [
|
|
2634
|
+
...(0, project_registry_1.listProjects)(),
|
|
2635
|
+
...(0, store_context_1.storeInventory)().flatMap((store) => store.projects),
|
|
2636
|
+
].filter((project, i, all) => all.findIndex((p) => p.root === project.root) === i);
|
|
2637
|
+
const selected = resolveMcpProject(raw, projectRoot, projects);
|
|
2638
|
+
if (!selected)
|
|
2639
|
+
return err(`Unknown or ambiguous registered project: ${raw}. Use list_projects or an exact root.`);
|
|
2640
|
+
target = selected.root;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
return yield (0, store_context_1.withStoreContext)(target, () => __awaiter(this, void 0, void 0, function* () {
|
|
2644
|
+
if (args.root !== undefined) {
|
|
2645
|
+
const selected = resolveMcpProject(args.root, currentRoot(), storeProjects());
|
|
2646
|
+
if (!selected)
|
|
2647
|
+
return err(`Unknown registered project: ${args.root}. Use list_projects to select a project name or exact root.`);
|
|
2648
|
+
args = Object.assign(Object.assign({}, args), { root: selected.root });
|
|
2649
|
+
(0, store_context_1.currentStoreContext)().root = selected.root;
|
|
2650
|
+
}
|
|
2651
|
+
const result = yield handler(args);
|
|
2576
2652
|
yield logToolCall(name, args, startMs, result);
|
|
2577
2653
|
return result;
|
|
2578
|
-
}
|
|
2579
|
-
|
|
2654
|
+
}));
|
|
2655
|
+
}
|
|
2656
|
+
catch (error) {
|
|
2657
|
+
return toolError("Tool failed", error);
|
|
2580
2658
|
}
|
|
2581
|
-
const result = yield handler(args);
|
|
2582
|
-
yield logToolCall(name, args, startMs, result);
|
|
2583
|
-
return result;
|
|
2584
2659
|
}));
|
|
2585
2660
|
}
|
|
2586
2661
|
tool("semantic_search", {
|
package/dist/commands/project.js
CHANGED
|
@@ -71,7 +71,6 @@ exports.project = new commander_1.Command("project")
|
|
|
71
71
|
daemon: () => (0, daemon_client_1.sendDaemonCommand)({ cmd: "rows.project", projectRoot: root }, { timeoutMs: 120000 }),
|
|
72
72
|
render: (resp) => resp.overview,
|
|
73
73
|
inProcess: () => (0, rows_handler_1.withLocalStore)(paths.lancedbDir, (deps) => (0, rows_handler_1.runProject)(deps, root)),
|
|
74
|
-
fallbackOnUnknownVerb: true,
|
|
75
74
|
});
|
|
76
75
|
if (overview.chunks === 0) {
|
|
77
76
|
console.log(`No indexed data found for ${root}. Run: gmax index --path ${root}`);
|
package/dist/commands/similar.js
CHANGED
|
@@ -158,7 +158,6 @@ function lookupSkeleton(projectRoot, lancedbDir, req) {
|
|
|
158
158
|
skeleton: ((_b = resp.skeleton) !== null && _b !== void 0 ? _b : null),
|
|
159
159
|
}); },
|
|
160
160
|
inProcess: () => (0, rows_handler_1.withLocalStore)(lancedbDir, (deps) => (0, rows_handler_1.runSkeleton)(deps, Object.assign({ projectRoot }, req))),
|
|
161
|
-
fallbackOnUnknownVerb: true,
|
|
162
161
|
});
|
|
163
162
|
});
|
|
164
163
|
}
|