grepmax 0.26.42 → 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 +7 -1
- package/dist/bin.js +4 -0
- package/dist/commands/doctor.js +23 -33
- package/dist/commands/mcp.js +144 -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 +35 -19
- 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 +36 -9
- package/dist/lib/daemon/graph-handler.js +33 -33
- package/dist/lib/daemon/ipc-handler.js +11 -10
- 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/compaction-result.js +35 -0
- package/dist/lib/store/lance-sdk.js +46 -0
- package/dist/lib/store/vector-db.js +118 -31
- package/dist/lib/utils/cross-project.js +2 -2
- package/dist/lib/utils/doctor-optimize.js +81 -0
- 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
package/dist/commands/status.js
CHANGED
|
@@ -57,7 +57,9 @@ const filter_builder_1 = require("../lib/utils/filter-builder");
|
|
|
57
57
|
const lock_1 = require("../lib/utils/lock");
|
|
58
58
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
59
59
|
const project_root_1 = require("../lib/utils/project-root");
|
|
60
|
+
const query_timeout_1 = require("../lib/utils/query-timeout");
|
|
60
61
|
const store_access_1 = require("../lib/utils/store-access");
|
|
62
|
+
const store_context_1 = require("../lib/utils/store-context");
|
|
61
63
|
const watcher_store_1 = require("../lib/utils/watcher-store");
|
|
62
64
|
/**
|
|
63
65
|
* Ask the daemon first. Both verbs already exist, so this works against an
|
|
@@ -96,7 +98,9 @@ function loadStatusView(projects) {
|
|
|
96
98
|
chunkCounts.set(project.root, stats.chunks);
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
|
-
const daemon = Object.assign(Object.assign({}, (resp.
|
|
101
|
+
const daemon = Object.assign(Object.assign(Object.assign({}, (resp.compaction !== undefined
|
|
102
|
+
? { compaction: resp.compaction }
|
|
103
|
+
: {})), (resp.resources !== undefined
|
|
100
104
|
? { resources: resp.resources }
|
|
101
105
|
: {})), { pid: typeof resp.pid === "number" ? resp.pid : null, uptimeSec: typeof resp.uptime === "number" ? resp.uptime : null,
|
|
102
106
|
// Older daemons do not report these.
|
|
@@ -115,9 +119,10 @@ function loadStatusView(projects) {
|
|
|
115
119
|
watchers.set(project.root, { status: watcher.status });
|
|
116
120
|
}
|
|
117
121
|
const chunkCounts = new Map();
|
|
122
|
+
let db;
|
|
118
123
|
try {
|
|
119
124
|
const { VectorDB } = yield Promise.resolve().then(() => __importStar(require("../lib/store/vector-db")));
|
|
120
|
-
|
|
125
|
+
db = new VectorDB(config_1.PATHS.lancedbDir);
|
|
121
126
|
const table = yield db.ensureTable();
|
|
122
127
|
for (const project of projects) {
|
|
123
128
|
const prefix = project.root.endsWith("/")
|
|
@@ -127,10 +132,9 @@ function loadStatusView(projects) {
|
|
|
127
132
|
.query()
|
|
128
133
|
.select(["id"])
|
|
129
134
|
.where((0, filter_builder_1.pathStartsWith)(prefix))
|
|
130
|
-
.toArray();
|
|
135
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
131
136
|
chunkCounts.set(project.root, rows.length);
|
|
132
137
|
}
|
|
133
|
-
yield db.close();
|
|
134
138
|
}
|
|
135
139
|
catch (err) {
|
|
136
140
|
// A sandbox denial is not "the query failed" — let it surface as the
|
|
@@ -139,6 +143,9 @@ function loadStatusView(projects) {
|
|
|
139
143
|
throw err;
|
|
140
144
|
console.warn(`[status] Failed to query LanceDB for live chunk counts, using cached counts`);
|
|
141
145
|
}
|
|
146
|
+
finally {
|
|
147
|
+
yield db === null || db === void 0 ? void 0 : db.close();
|
|
148
|
+
}
|
|
142
149
|
return { watchers, chunkCounts };
|
|
143
150
|
}),
|
|
144
151
|
});
|
|
@@ -199,22 +206,15 @@ function buildStatusJson(input) {
|
|
|
199
206
|
? ((_c = input.countWorkers) !== null && _c !== void 0 ? _c : countWorkerProcesses)(d.pid)
|
|
200
207
|
: null);
|
|
201
208
|
}
|
|
202
|
-
return {
|
|
203
|
-
daemon: Object.assign({ running: d !== undefined, pid: (_d = d === null || d === void 0 ? void 0 : d.pid) !== null && _d !== void 0 ? _d : null, since: (d === null || d === void 0 ? void 0 : d.uptimeSec) != null ? now - d.uptimeSec * 1000 : null, workerThreads: (_e = d === null || d === void 0 ? void 0 : d.workerThreads) !== null && _e !== void 0 ? _e : null }, ((d === null || d === void 0 ? void 0 : d.resources) !== undefined ? { resources: d.resources } : {})),
|
|
204
|
-
settings: {
|
|
209
|
+
return Object.assign(Object.assign({}, (input.stores ? { stores: input.stores } : {})), { daemon: Object.assign(Object.assign({ running: d !== undefined, pid: (_d = d === null || d === void 0 ? void 0 : d.pid) !== null && _d !== void 0 ? _d : null, since: (d === null || d === void 0 ? void 0 : d.uptimeSec) != null ? now - d.uptimeSec * 1000 : null, workerThreads: (_e = d === null || d === void 0 ? void 0 : d.workerThreads) !== null && _e !== void 0 ? _e : null }, ((d === null || d === void 0 ? void 0 : d.resources) !== undefined ? { resources: d.resources } : {})), ((d === null || d === void 0 ? void 0 : d.compaction) !== undefined ? { compaction: d.compaction } : {})), settings: {
|
|
205
210
|
embedMode: globalConfig.embedMode,
|
|
206
211
|
modelTier: globalConfig.modelTier,
|
|
207
212
|
vectorDim: globalConfig.vectorDim,
|
|
208
213
|
queryLog: globalConfig.queryLog === true,
|
|
209
214
|
workerThreads: input.workerThreads,
|
|
210
|
-
},
|
|
211
|
-
workersRunning,
|
|
212
|
-
indexing: input.indexing,
|
|
213
|
-
projects: input.projects.map((project) => { var _a; var _b, _c; return (Object.assign({ name: project.name, root: project.root, chunks: (_c = (_b = view.chunkCounts.get(project.root)) !== null && _b !== void 0 ? _b : project.chunkCount) !== null && _c !== void 0 ? _c : 0, indexedAt: toMs(project.lastIndexed), state: projectState(project, view.watchers.get(project.root)), embedding: (0, embedding_status_1.projectEmbeddingStatus)(project, globalConfig).state }, (((_a = view.health) === null || _a === void 0 ? void 0 : _a.has(project.root))
|
|
215
|
+
}, workersRunning, indexing: input.indexing, projects: input.projects.map((project) => { var _a; var _b, _c; return (Object.assign({ name: project.name, root: project.root, chunks: (_c = (_b = view.chunkCounts.get(project.root)) !== null && _b !== void 0 ? _b : project.chunkCount) !== null && _c !== void 0 ? _c : 0, indexedAt: toMs(project.lastIndexed), state: projectState(project, view.watchers.get(project.root)), embedding: (0, embedding_status_1.projectEmbeddingStatus)(project, globalConfig).state }, (((_a = view.health) === null || _a === void 0 ? void 0 : _a.has(project.root))
|
|
214
216
|
? { health: view.health.get(project.root) }
|
|
215
|
-
: {}))); }),
|
|
216
|
-
at: now,
|
|
217
|
-
};
|
|
217
|
+
: {}))); }), at: now });
|
|
218
218
|
}
|
|
219
219
|
const style = {
|
|
220
220
|
bold: (s) => `\x1b[1m${s}\x1b[22m`,
|
|
@@ -264,11 +264,12 @@ Examples:
|
|
|
264
264
|
`)
|
|
265
265
|
.action((opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
266
266
|
var _a, _b;
|
|
267
|
-
var _c, _d, _e, _f;
|
|
267
|
+
var _c, _d, _e, _f, _g, _h, _j;
|
|
268
268
|
const globalConfig = (0, index_config_1.readGlobalConfig)();
|
|
269
269
|
const projects = (0, project_registry_1.listProjects)();
|
|
270
270
|
const indexing = (0, lock_1.isLocked)(config_1.PATHS.globalRoot);
|
|
271
271
|
const currentRoot = (0, project_root_1.findProjectRoot)(process.cwd());
|
|
272
|
+
const stores = (0, store_context_1.storeInventory)();
|
|
272
273
|
// Resolved before the header so a sandbox refusal prints one clean line.
|
|
273
274
|
let view;
|
|
274
275
|
try {
|
|
@@ -284,6 +285,7 @@ Examples:
|
|
|
284
285
|
const { watchers, chunkCounts } = view;
|
|
285
286
|
if (opts.json) {
|
|
286
287
|
const json = buildStatusJson({
|
|
288
|
+
stores,
|
|
287
289
|
view,
|
|
288
290
|
projects,
|
|
289
291
|
globalConfig,
|
|
@@ -301,6 +303,20 @@ Examples:
|
|
|
301
303
|
// Header
|
|
302
304
|
console.log(`\n${style.bold("gmax")} · ${globalConfig.modelTier} (${globalConfig.vectorDim}d, ${globalConfig.embedMode})${indexing ? style.yellow(" · indexing...") : ""}`);
|
|
303
305
|
}
|
|
306
|
+
for (const store of stores) {
|
|
307
|
+
if (opts.agent) {
|
|
308
|
+
console.log(`store\t${store.home}\t${store.state}\tprefixes=${store.prefixes.join(",")}${store.error ? `\terror=${store.error}` : ""}`);
|
|
309
|
+
for (const project of store.projects)
|
|
310
|
+
console.log(`store_project\t${store.home}\t${project.name}\t${(_c = project.chunkCount) !== null && _c !== void 0 ? _c : 0}\t${(_d = project.status) !== null && _d !== void 0 ? _d : "indexed"}\tcounts=cached`);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
console.log(`\nStore: ${shortenPath(store.home)} — ${store.state}${store.error ? ` (${store.error})` : ""}`);
|
|
314
|
+
if (store.state === "offline")
|
|
315
|
+
console.log(" Connect the drive to list its projects.");
|
|
316
|
+
for (const project of store.projects)
|
|
317
|
+
console.log(` ${project.name} ${formatChunks(project.chunkCount)} chunks (cached) ${(_e = project.status) !== null && _e !== void 0 ? _e : "indexed"}`);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
304
320
|
if (projects.length === 0) {
|
|
305
321
|
if (opts.agent) {
|
|
306
322
|
console.log("(none)");
|
|
@@ -315,9 +331,9 @@ Examples:
|
|
|
315
331
|
for (const project of projects) {
|
|
316
332
|
const st = projectState(project, watchers.get(project.root));
|
|
317
333
|
const isCurrent = project.root === currentRoot;
|
|
318
|
-
const count = (
|
|
334
|
+
const count = (_f = chunkCounts.get(project.root)) !== null && _f !== void 0 ? _f : project.chunkCount;
|
|
319
335
|
const identity = (0, embedding_status_1.projectEmbeddingStatus)(project, globalConfig);
|
|
320
|
-
console.log(`${project.name}\t${formatChunks(count)}\t${formatAge(project.lastIndexed)}\t${st}\tembedding=${identity.state}${isCurrent ? "\tcurrent" : ""}${((_a = view.health) === null || _a === void 0 ? void 0 : _a.get(project.root)) ? `\t${(
|
|
336
|
+
console.log(`${project.name}\t${formatChunks(count)}\t${formatAge(project.lastIndexed)}\t${st}\tembedding=${identity.state}${isCurrent ? "\tcurrent" : ""}${((_a = view.health) === null || _a === void 0 ? void 0 : _a.get(project.root)) ? `\t${(_g = (0, index_state_footer_1.formatIndexStateFooter)(view.health.get(project.root), { agent: true })) !== null && _g !== void 0 ? _g : ""}` : ""}`);
|
|
321
337
|
}
|
|
322
338
|
const legacyNotice = (0, embedding_status_1.formatLegacyEmbeddingNotice)((0, embedding_status_1.countLegacyEmbeddingProjects)(projects, globalConfig), { agent: true });
|
|
323
339
|
if (legacyNotice)
|
|
@@ -333,7 +349,7 @@ Examples:
|
|
|
333
349
|
const watcher = watchers.get(project.root);
|
|
334
350
|
// Status column
|
|
335
351
|
let statusStr;
|
|
336
|
-
const projectStatus = (
|
|
352
|
+
const projectStatus = (_h = project.status) !== null && _h !== void 0 ? _h : "indexed";
|
|
337
353
|
if (projectStatus === "pending") {
|
|
338
354
|
statusStr = style.yellow("pending");
|
|
339
355
|
}
|
|
@@ -353,7 +369,7 @@ Examples:
|
|
|
353
369
|
statusStr = style.dim("idle");
|
|
354
370
|
}
|
|
355
371
|
// Chunks column
|
|
356
|
-
const count = (
|
|
372
|
+
const count = (_j = chunkCounts.get(project.root)) !== null && _j !== void 0 ? _j : project.chunkCount;
|
|
357
373
|
const chunks = `${formatChunks(count)} chunks`;
|
|
358
374
|
// Age column
|
|
359
375
|
const age = formatAge(project.lastIndexed);
|
|
@@ -190,7 +190,6 @@ exports.surprises = new commander_1.Command("surprises")
|
|
|
190
190
|
daemon: () => (0, daemon_client_1.sendDaemonCommand)({ cmd: "vector.surprises", projectRoot, options, top }, { timeoutMs: 300000 }),
|
|
191
191
|
render: (resp) => resp,
|
|
192
192
|
inProcess: () => (0, rows_handler_1.withLocalStore)(paths.lancedbDir, (deps) => (0, vector_handler_1.runSurprises)(deps, { projectRoot, options, top })),
|
|
193
|
-
fallbackOnUnknownVerb: true,
|
|
194
193
|
});
|
|
195
194
|
console.log(opts.agent ? formatAgent(result, top) : formatHuman(result, top));
|
|
196
195
|
}
|
package/dist/commands/symbols.js
CHANGED
package/dist/commands/watch.js
CHANGED
|
@@ -60,6 +60,7 @@ const log_rotate_1 = require("../lib/utils/log-rotate");
|
|
|
60
60
|
const process_1 = require("../lib/utils/process");
|
|
61
61
|
const project_registry_1 = require("../lib/utils/project-registry");
|
|
62
62
|
const project_root_1 = require("../lib/utils/project-root");
|
|
63
|
+
const query_timeout_1 = require("../lib/utils/query-timeout");
|
|
63
64
|
const watcher_store_1 = require("../lib/utils/watcher-store");
|
|
64
65
|
// Hard ceiling on signal-driven shutdown; comfortably above the daemon's own
|
|
65
66
|
// 30s operation-drain grace so the orderly path normally wins.
|
|
@@ -278,7 +279,7 @@ exports.watch = new commander_1.Command("watch")
|
|
|
278
279
|
.select(["id"])
|
|
279
280
|
.where((0, filter_builder_1.pathStartsWith)(prefix))
|
|
280
281
|
.limit(1)
|
|
281
|
-
.toArray();
|
|
282
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
282
283
|
let degraded = false;
|
|
283
284
|
let degradedErrors = 0;
|
|
284
285
|
let initialScanErrors = 0;
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
17
35
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
36
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
37
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -24,39 +42,40 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
24
42
|
});
|
|
25
43
|
};
|
|
26
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
|
|
28
|
-
const
|
|
45
|
+
/** Native LIKE+limit regression probe. Always uses synthetic temporary data. */
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const os = __importStar(require("node:os"));
|
|
48
|
+
const path = __importStar(require("node:path"));
|
|
49
|
+
const lance_sdk_1 = require("./lib/store/lance-sdk");
|
|
29
50
|
const filter_builder_1 = require("./lib/utils/filter-builder");
|
|
30
51
|
const query_timeout_1 = require("./lib/utils/query-timeout");
|
|
31
|
-
const needle = process.argv[2] || "Daemon";
|
|
32
|
-
const TIMEOUT_MS = 10000;
|
|
33
52
|
function main() {
|
|
34
53
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (all.length < 2) {
|
|
41
|
-
console.log("needle too rare to exercise the bug — pick a common one");
|
|
42
|
-
process.exit(0);
|
|
43
|
-
}
|
|
44
|
-
const limit = Math.max(1, Math.floor(all.length / 2));
|
|
45
|
-
const t0 = Date.now();
|
|
54
|
+
const needle = process.argv[2] || "Fixture";
|
|
55
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "gmax-like-probe-"));
|
|
56
|
+
const db = yield (0, lance_sdk_1.connect)(dir, {
|
|
57
|
+
session: new lance_sdk_1.Session(BigInt(8 * Math.pow(1024, 2)), BigInt(8 * Math.pow(1024, 2))),
|
|
58
|
+
});
|
|
46
59
|
try {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
`
|
|
50
|
-
|
|
60
|
+
const table = yield db.createTable("probe", Array.from({ length: 200 }, (_, i) => ({
|
|
61
|
+
path: `/fixture/${i}.ts`,
|
|
62
|
+
content: `import ${needle}`,
|
|
63
|
+
})));
|
|
64
|
+
const where = `content LIKE '%${(0, filter_builder_1.escapeSqlString)(needle)}%'`;
|
|
65
|
+
const options = { timeoutMs: 5000 };
|
|
66
|
+
const rows = yield (0, query_timeout_1.withQueryTimeout)(table.query().select(["path"]).where(where).limit(7).toArray(options), "temporary LIKE+limit probe", 6000);
|
|
67
|
+
if (rows.length !== 7)
|
|
68
|
+
throw new Error(`Expected 7 rows, got ${rows.length}`);
|
|
69
|
+
console.log("Temporary LIKE+limit probe: 7 of 200 matching rows returned");
|
|
70
|
+
table.close();
|
|
51
71
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
process.exit(1);
|
|
72
|
+
finally {
|
|
73
|
+
db.close();
|
|
74
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
56
75
|
}
|
|
57
76
|
});
|
|
58
77
|
}
|
|
59
|
-
main().catch((
|
|
60
|
-
console.error(
|
|
61
|
-
process.
|
|
78
|
+
main().catch((error) => {
|
|
79
|
+
console.error(error);
|
|
80
|
+
process.exitCode = 1;
|
|
62
81
|
});
|
|
@@ -63,6 +63,7 @@ const callsites_1 = require("../graph/callsites");
|
|
|
63
63
|
const ann_config_1 = require("../store/ann-config");
|
|
64
64
|
const arrow_1 = require("../utils/arrow");
|
|
65
65
|
const filter_builder_1 = require("../utils/filter-builder");
|
|
66
|
+
const query_timeout_1 = require("../utils/query-timeout");
|
|
66
67
|
const scope_filter_1 = require("../utils/scope-filter");
|
|
67
68
|
exports.DEFAULT_SURPRISE_OPTIONS = {
|
|
68
69
|
sample: 160,
|
|
@@ -512,7 +513,7 @@ function hydrateRows(table, where, ids, columns) {
|
|
|
512
513
|
.select(["id", ...columns])
|
|
513
514
|
.where(`(${where}) AND id IN (${list})`)
|
|
514
515
|
.limit(batch.length)
|
|
515
|
-
.toArray());
|
|
516
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS));
|
|
516
517
|
for (const row of rows)
|
|
517
518
|
out.set(String(row.id || ""), row);
|
|
518
519
|
}
|
|
@@ -580,7 +581,7 @@ function analyzeSurprisingConnections(table_1, projectRoot_1) {
|
|
|
580
581
|
.select(SCAN_SELECT)
|
|
581
582
|
.where(where)
|
|
582
583
|
.limit(opts.maxRows)
|
|
583
|
-
.toArray());
|
|
584
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS));
|
|
584
585
|
const rows = rawRows.map((row) => toChunkRow(row, prefix));
|
|
585
586
|
const fileEdges = buildFileEdges(rows);
|
|
586
587
|
// Weak-code test: decided from the scan's bounds where possible, otherwise
|
|
@@ -643,7 +644,7 @@ function analyzeSurprisingConnections(table_1, projectRoot_1) {
|
|
|
643
644
|
.select([...exports.SURPRISE_COLUMNS, "_distance"])
|
|
644
645
|
.where(where)
|
|
645
646
|
.limit(opts.neighbors + 8)
|
|
646
|
-
.toArray());
|
|
647
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS));
|
|
647
648
|
for (const rawTarget of neighbors) {
|
|
648
649
|
filters.rawNeighbors++;
|
|
649
650
|
const target = withoutVector(toChunkRow(rawTarget, prefix));
|
|
@@ -252,7 +252,10 @@ class Daemon {
|
|
|
252
252
|
yield this.processManager.killStaleProcesses();
|
|
253
253
|
this.assertStartupActive();
|
|
254
254
|
// 1. Acquire exclusive lock — kernel-enforced, atomic, auto-released on death
|
|
255
|
-
|
|
255
|
+
const ipcHome = path.dirname(config_1.PATHS.daemonLockFile);
|
|
256
|
+
fs.mkdirSync(ipcHome, { recursive: true, mode: 0o700 });
|
|
257
|
+
// IPC is local and private to this account, including an existing home.
|
|
258
|
+
fs.chmodSync(ipcHome, 0o700);
|
|
256
259
|
fs.writeFileSync(config_1.PATHS.daemonLockFile, "", { flag: "a" }); // ensure file exists
|
|
257
260
|
(0, logger_1.debug)("daemon", "acquiring lock...");
|
|
258
261
|
try {
|
|
@@ -338,7 +341,16 @@ class Daemon {
|
|
|
338
341
|
reject(err);
|
|
339
342
|
}
|
|
340
343
|
});
|
|
341
|
-
this.server.listen(config_1.PATHS.daemonSocket, () =>
|
|
344
|
+
this.server.listen(config_1.PATHS.daemonSocket, () => {
|
|
345
|
+
try {
|
|
346
|
+
fs.chmodSync(config_1.PATHS.daemonSocket, 0o600);
|
|
347
|
+
resolve();
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
this.server.close();
|
|
351
|
+
reject(error);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
342
354
|
});
|
|
343
355
|
this.assertStartupActive();
|
|
344
356
|
// 3. Write PID file AFTER socket is listening — ensures any process that
|
|
@@ -609,13 +621,23 @@ class Daemon {
|
|
|
609
621
|
* fall back to in-process only when no daemon answers, and are then the sole
|
|
610
622
|
* writer themselves.
|
|
611
623
|
*/
|
|
624
|
+
compactionStatus() {
|
|
625
|
+
var _a;
|
|
626
|
+
var _b;
|
|
627
|
+
return (_b = (_a = this.vectorDb) === null || _a === void 0 ? void 0 : _a.compactionStatus()) !== null && _b !== void 0 ? _b : null;
|
|
628
|
+
}
|
|
612
629
|
runOptimize() {
|
|
613
630
|
return __awaiter(this, void 0, void 0, function* () {
|
|
631
|
+
var _a;
|
|
614
632
|
const db = this.vectorDb;
|
|
615
633
|
if (!db)
|
|
616
634
|
throw new Error("daemon resources not ready");
|
|
617
|
-
yield this.runSharedOperation("store-maintenance", undefined, () => db.runMaintenance({ force: true }));
|
|
618
|
-
|
|
635
|
+
const compaction = yield this.runSharedOperation("store-maintenance", undefined, () => db.runMaintenance({ force: true }));
|
|
636
|
+
if (!compaction)
|
|
637
|
+
return { ok: false, error: "maintenance produced no compaction outcome" };
|
|
638
|
+
return Object.assign({ ok: compaction.status === "completed", compaction }, (compaction.status === "completed"
|
|
639
|
+
? {}
|
|
640
|
+
: { error: (_a = compaction.reason) !== null && _a !== void 0 ? _a : compaction.status }));
|
|
619
641
|
});
|
|
620
642
|
}
|
|
621
643
|
operationStatus() {
|
|
@@ -1867,13 +1889,18 @@ class Daemon {
|
|
|
1867
1889
|
if (this.recycleDueSinceMs === null &&
|
|
1868
1890
|
!ageExceeded &&
|
|
1869
1891
|
sampleFootprint &&
|
|
1870
|
-
RSS_WATERMARK_MB > 0
|
|
1871
|
-
// A fresh daemon above the watermark would recycle in a loop; give the
|
|
1872
|
-
// caches a chance to settle before judging the footprint.
|
|
1873
|
-
ageMs > FOOTPRINT_RECYCLE_MIN_AGE_MS) {
|
|
1892
|
+
RSS_WATERMARK_MB > 0) {
|
|
1874
1893
|
footprintMb = (0, process_footprint_1.readFootprintMb)();
|
|
1875
1894
|
}
|
|
1876
|
-
|
|
1895
|
+
// The existing five-minute probe also records a baseline for memory soaks;
|
|
1896
|
+
// the intervening heartbeat ticks add no footprint probe or snapshot.
|
|
1897
|
+
if (sampleFootprint)
|
|
1898
|
+
this.logResourceSnapshot("periodic", footprintMb);
|
|
1899
|
+
const footprintExceeded = footprintMb !== null &&
|
|
1900
|
+
footprintMb > RSS_WATERMARK_MB &&
|
|
1901
|
+
// Sampling young daemons is useful; recycling them would loop before
|
|
1902
|
+
// their caches have had a chance to settle.
|
|
1903
|
+
ageMs > FOOTPRINT_RECYCLE_MIN_AGE_MS;
|
|
1877
1904
|
if (this.recycleDueSinceMs === null) {
|
|
1878
1905
|
if (!ageExceeded && !footprintExceeded)
|
|
1879
1906
|
return;
|
|
@@ -1,29 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Daemon-side handlers for the `graph.*` read verbs.
|
|
4
|
-
*
|
|
5
|
-
* The commands that used to open LanceDB themselves (`test`, `impact`, `trace`,
|
|
6
|
-
* `peek`, `dead`, `audit`) now send one IPC line and render the answer. The work
|
|
7
|
-
* they used to do between `ensureTable()` and the first `console.log` lives
|
|
8
|
-
* here, so both paths run the *same* code:
|
|
9
|
-
*
|
|
10
|
-
* - the daemon runs `runGraph*` against its warm `VectorDB`
|
|
11
|
-
* - a CLI with no daemon runs the identical `runGraph*` against a local one
|
|
12
|
-
*
|
|
13
|
-
* That is what makes the two paths byte-identical: the commands hold only
|
|
14
|
-
* argument parsing and rendering, and every clamp lives inside the `runGraph*`
|
|
15
|
-
* function rather than in one of the two callers.
|
|
16
|
-
*
|
|
17
|
-
* Results are finished answers, never raw rows. `graph.audit` reads up to 500k
|
|
18
|
-
* chunks and returns a few dozen ranked lines; `graph.dead` reads the whole
|
|
19
|
-
* caller set and returns a count plus three locations. Nothing here streams.
|
|
20
|
-
*
|
|
21
|
-
* Scope on the wire: the CLI resolves `--in`/`--exclude` locally (that needs its
|
|
22
|
-
* cwd and the filesystem) and sends absolute prefixes. The daemon re-validates
|
|
23
|
-
* every one with `resolveContainedPath` — exactly as the `search` case does —
|
|
24
|
-
* and rebuilds the same `ResolvedScope` with `scopeFromPrefixes`, including the
|
|
25
|
-
* single-`--in`-collapses-into-pathPrefix rule, so the WHERE clauses match.
|
|
26
|
-
*/
|
|
27
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
28
3
|
if (k2 === undefined) k2 = k;
|
|
29
4
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -88,6 +63,32 @@ exports.computeAudit = computeAudit;
|
|
|
88
63
|
exports.runGraphAudit = runGraphAudit;
|
|
89
64
|
exports.createGraphVerbs = createGraphVerbs;
|
|
90
65
|
exports.callGraphVerb = callGraphVerb;
|
|
66
|
+
const query_timeout_1 = require("../utils/query-timeout");
|
|
67
|
+
/**
|
|
68
|
+
* Daemon-side handlers for the `graph.*` read verbs.
|
|
69
|
+
*
|
|
70
|
+
* The commands that used to open LanceDB themselves (`test`, `impact`, `trace`,
|
|
71
|
+
* `peek`, `dead`, `audit`) now send one IPC line and render the answer. The work
|
|
72
|
+
* they used to do between `ensureTable()` and the first `console.log` lives
|
|
73
|
+
* here, so both paths run the *same* code:
|
|
74
|
+
*
|
|
75
|
+
* - the daemon runs `runGraph*` against its warm `VectorDB`
|
|
76
|
+
* - a CLI with no daemon runs the identical `runGraph*` against a local one
|
|
77
|
+
*
|
|
78
|
+
* That is what makes the two paths byte-identical: the commands hold only
|
|
79
|
+
* argument parsing and rendering, and every clamp lives inside the `runGraph*`
|
|
80
|
+
* function rather than in one of the two callers.
|
|
81
|
+
*
|
|
82
|
+
* Results are finished answers, never raw rows. `graph.audit` reads up to 500k
|
|
83
|
+
* chunks and returns a few dozen ranked lines; `graph.dead` reads the whole
|
|
84
|
+
* caller set and returns a count plus three locations. Nothing here streams.
|
|
85
|
+
*
|
|
86
|
+
* Scope on the wire: the CLI resolves `--in`/`--exclude` locally (that needs its
|
|
87
|
+
* cwd and the filesystem) and sends absolute prefixes. The daemon re-validates
|
|
88
|
+
* every one with `resolveContainedPath` — exactly as the `search` case does —
|
|
89
|
+
* and rebuilds the same `ResolvedScope` with `scopeFromPrefixes`, including the
|
|
90
|
+
* single-`--in`-collapses-into-pathPrefix rule, so the WHERE clauses match.
|
|
91
|
+
*/
|
|
91
92
|
const path = __importStar(require("node:path"));
|
|
92
93
|
const languages_1 = require("../core/languages");
|
|
93
94
|
const callsites_1 = require("../graph/callsites");
|
|
@@ -328,7 +329,7 @@ function runGraphPeek(db, args) {
|
|
|
328
329
|
.select(["path", "start_line"])
|
|
329
330
|
.where(definedWhere)
|
|
330
331
|
.limit(20)
|
|
331
|
-
.toArray();
|
|
332
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
332
333
|
const defChunks = defRows.map((row) => ({
|
|
333
334
|
path: String(row.path || ""),
|
|
334
335
|
startLine: Number(row.start_line || 0),
|
|
@@ -340,7 +341,7 @@ function runGraphPeek(db, args) {
|
|
|
340
341
|
.select(["is_exported", "start_line", "end_line"])
|
|
341
342
|
.where(definedWhere)
|
|
342
343
|
.limit(1)
|
|
343
|
-
.toArray();
|
|
344
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
344
345
|
const metaRow = metaRows[0];
|
|
345
346
|
const meta = metaRow
|
|
346
347
|
? {
|
|
@@ -366,7 +367,7 @@ function runGraphDead(db, args) {
|
|
|
366
367
|
.select(["path", "start_line", "is_exported"])
|
|
367
368
|
.where((0, scope_filter_1.buildScopeWhere)(args.scope, `array_contains(defined_symbols, '${(0, filter_builder_1.escapeSqlString)(args.symbol)}')`))
|
|
368
369
|
.limit(1)
|
|
369
|
-
.toArray();
|
|
370
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
370
371
|
if (defRows.length === 0) {
|
|
371
372
|
return {
|
|
372
373
|
found: false,
|
|
@@ -696,7 +697,7 @@ function runGraphAudit(db, args) {
|
|
|
696
697
|
])
|
|
697
698
|
.where((0, scope_filter_1.buildScopeWhere)(args.scope))
|
|
698
699
|
.limit(AUDIT_ROW_LIMIT)
|
|
699
|
-
.toArray();
|
|
700
|
+
.toArray(query_timeout_1.QUERY_EXECUTION_OPTIONS);
|
|
700
701
|
if (rows.length === 0)
|
|
701
702
|
return null;
|
|
702
703
|
return computeAudit(rows.map((r) => {
|
|
@@ -851,10 +852,9 @@ exports.GRAPH_VERB_TIMEOUT_MS = 60000;
|
|
|
851
852
|
/**
|
|
852
853
|
* Send one graph verb through the store-access policy.
|
|
853
854
|
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
* unregistered project skips the daemon outright — see isDaemonReadableProject.
|
|
855
|
+
* An unsupported verb requires restarting the live daemon. An unregistered
|
|
856
|
+
* project skips the daemon outright — see isDaemonReadableProject.
|
|
857
857
|
*/
|
|
858
858
|
function callGraphVerb(verb, call) {
|
|
859
|
-
return (0, store_access_1.withStoreRead)(verb, Object.assign({ skipDaemon: !isDaemonReadableProject(call.projectRoot),
|
|
859
|
+
return (0, store_access_1.withStoreRead)(verb, Object.assign({ skipDaemon: !isDaemonReadableProject(call.projectRoot), daemon: () => (0, daemon_client_1.sendDaemonCommand)(Object.assign(Object.assign({ cmd: verb }, encodeScope(call.projectRoot, call.scope)), call.payload), { timeoutMs: exports.GRAPH_VERB_TIMEOUT_MS }), render: call.render, inProcess: call.inProcess }, call.fallback));
|
|
860
860
|
}
|
|
@@ -122,8 +122,8 @@ function startHeartbeat(conn, intervalMs = HEARTBEAT_INTERVAL_MS) {
|
|
|
122
122
|
*/
|
|
123
123
|
function handleCommand(daemon, cmd, conn) {
|
|
124
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
-
var _a;
|
|
126
|
-
var
|
|
125
|
+
var _a, _b;
|
|
126
|
+
var _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
127
127
|
try {
|
|
128
128
|
(0, logger_1.debug)("daemon", `ipc cmd=${cmd.cmd}${cmd.root ? ` root=${cmd.root}` : ""}`);
|
|
129
129
|
if (cmd.cmd !== "ping" &&
|
|
@@ -186,7 +186,8 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
186
186
|
diskPressure: daemon.getDiskPressure(),
|
|
187
187
|
mlx: daemon.getMlxStatus(),
|
|
188
188
|
workers: daemon.workerCount(),
|
|
189
|
-
resources: (
|
|
189
|
+
resources: (_c = (_a = daemon.resourceSnapshot) === null || _a === void 0 ? void 0 : _a.call(daemon)) !== null && _c !== void 0 ? _c : null,
|
|
190
|
+
compaction: (_d = (_b = daemon.compactionStatus) === null || _b === void 0 ? void 0 : _b.call(daemon)) !== null && _d !== void 0 ? _d : null,
|
|
190
191
|
workerThreads: config_1.WORKER_THREADS_SETTING,
|
|
191
192
|
};
|
|
192
193
|
case "optimize":
|
|
@@ -202,14 +203,14 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
202
203
|
return Object.assign({ ok: true }, (yield daemon.projectStats(root)));
|
|
203
204
|
}
|
|
204
205
|
case "shutdown": {
|
|
205
|
-
const reason = String((
|
|
206
|
-
const fromPid = (
|
|
207
|
-
const fromPpid = (
|
|
208
|
-
const fromVer = (
|
|
206
|
+
const reason = String((_e = cmd.reason) !== null && _e !== void 0 ? _e : "unknown");
|
|
207
|
+
const fromPid = (_f = cmd.from_pid) !== null && _f !== void 0 ? _f : "?";
|
|
208
|
+
const fromPpid = (_g = cmd.from_ppid) !== null && _g !== void 0 ? _g : "?";
|
|
209
|
+
const fromVer = (_h = cmd.from_version) !== null && _h !== void 0 ? _h : "?";
|
|
209
210
|
const fromArgv = Array.isArray(cmd.from_argv)
|
|
210
211
|
? cmd.from_argv.join(" ")
|
|
211
212
|
: "?";
|
|
212
|
-
const fromParentCmd = (
|
|
213
|
+
const fromParentCmd = (_j = cmd.from_parent_cmd) !== null && _j !== void 0 ? _j : "?";
|
|
213
214
|
console.log(`[daemon] shutdown command received via IPC: reason=${reason} from_pid=${fromPid} from_ppid=${fromPpid} from_version=${fromVer} from_argv=[${fromArgv}] from_parent_cmd=[${fromParentCmd}]`);
|
|
214
215
|
setImmediate(() => daemon.shutdown());
|
|
215
216
|
return { ok: true };
|
|
@@ -274,8 +275,8 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
274
275
|
return { ok: false, error: "invalid project_roots" };
|
|
275
276
|
}
|
|
276
277
|
for (const prefix of [
|
|
277
|
-
...((
|
|
278
|
-
...((
|
|
278
|
+
...((_k = filters === null || filters === void 0 ? void 0 : filters.inPrefixes) !== null && _k !== void 0 ? _k : []),
|
|
279
|
+
...((_l = filters === null || filters === void 0 ? void 0 : filters.excludePrefixes) !== null && _l !== void 0 ? _l : []),
|
|
279
280
|
]) {
|
|
280
281
|
(0, path_containment_1.resolveContainedPath)(projectRoot, prefix);
|
|
281
282
|
}
|