grepmax 0.26.11 → 0.26.12
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.
|
@@ -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.12",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
package/dist/commands/doctor.js
CHANGED
|
@@ -88,7 +88,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
88
88
|
.option("--fix", "Auto-fix detected issues (compact, prune, remove stale locks)", false)
|
|
89
89
|
.option("--agent", "Compact output for AI agents", false)
|
|
90
90
|
.action((opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
91
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
91
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
92
92
|
if (!opts.agent)
|
|
93
93
|
console.log("gmax Doctor\n");
|
|
94
94
|
const root = config_1.PATHS.globalRoot;
|
|
@@ -281,7 +281,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
281
281
|
? "LOW"
|
|
282
282
|
: "ok";
|
|
283
283
|
}
|
|
284
|
-
catch (
|
|
284
|
+
catch (_p) { }
|
|
285
285
|
const staleChunkerProjects = projects.filter((p) => {
|
|
286
286
|
var _a;
|
|
287
287
|
return p.status === "indexed" &&
|
|
@@ -486,7 +486,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
486
486
|
yield mc.close();
|
|
487
487
|
}
|
|
488
488
|
}
|
|
489
|
-
catch (
|
|
489
|
+
catch (_q) { }
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
492
|
// --fix auto-remediation
|
|
@@ -503,9 +503,39 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
503
503
|
if (needsOptimize) {
|
|
504
504
|
if (!opts.agent)
|
|
505
505
|
console.log("... Running optimize (compact + prune)...");
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
506
|
+
// Prefer the daemon. Lance's optimize deletes unverified files, which
|
|
507
|
+
// is only safe with a single writer on the store — optimizing here
|
|
508
|
+
// while the daemon compacts made this command a second writer. With a
|
|
509
|
+
// daemon up it owns compaction; without one we are the sole process
|
|
510
|
+
// and can do it in-process safely.
|
|
511
|
+
const { sendDaemonCommand } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/daemon-client")));
|
|
512
|
+
const resp = yield sendDaemonCommand({ cmd: "optimize" }, { timeoutMs: 10 * 60 * 1000 });
|
|
513
|
+
let via = "daemon";
|
|
514
|
+
if (!resp.ok) {
|
|
515
|
+
// Only fall back when the daemon could not take it. A daemon that
|
|
516
|
+
// answered with a real failure should surface, not be retried here
|
|
517
|
+
// as a competing writer.
|
|
518
|
+
const reason = String((_k = resp.error) !== null && _k !== void 0 ? _k : "");
|
|
519
|
+
// Fall back ONLY when nothing is listening. A daemon that is merely
|
|
520
|
+
// too old ("unknown command") or busy ("timeout") is still a live
|
|
521
|
+
// writer on the store, so optimizing here would recreate the
|
|
522
|
+
// two-writer case this routing exists to prevent.
|
|
523
|
+
const daemonAbsent = reason.includes("ECONNREFUSED") || reason.includes("ENOENT");
|
|
524
|
+
if (daemonAbsent) {
|
|
525
|
+
yield db.optimize(3, 0);
|
|
526
|
+
via = "in-process (no daemon)";
|
|
527
|
+
}
|
|
528
|
+
else if (reason.includes("unknown command")) {
|
|
529
|
+
via = "";
|
|
530
|
+
console.log("WARN Optimize skipped: the running daemon predates the optimize command. Restart it (gmax watch --daemon -b) and re-run.");
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
via = "";
|
|
534
|
+
console.log(`WARN Optimize failed via daemon: ${reason}`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (via && !opts.agent)
|
|
538
|
+
console.log(`ok Optimize complete (${via})`);
|
|
509
539
|
fixed++;
|
|
510
540
|
}
|
|
511
541
|
if (orphanedProjects.length > 0) {
|
|
@@ -533,7 +563,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
533
563
|
const done = yield sendStreamingCommand({ cmd: "index", root: p.root, reset: true }, () => { }).catch((e) => ({ ok: false, error: String(e) }));
|
|
534
564
|
if (done.ok &&
|
|
535
565
|
(!("degraded" in done) || done.degraded !== true)) {
|
|
536
|
-
const chunks = (
|
|
566
|
+
const chunks = (_l = done.indexed) !== null && _l !== void 0 ? _l : 0;
|
|
537
567
|
if (opts.agent) {
|
|
538
568
|
console.log(`stale_chunker_reindexed\tname=${name}\tchunks=${chunks}`);
|
|
539
569
|
}
|
|
@@ -545,7 +575,7 @@ exports.doctor = new commander_1.Command("doctor")
|
|
|
545
575
|
else if (!opts.agent) {
|
|
546
576
|
const degraded = "degraded" in done && done.degraded === true;
|
|
547
577
|
const reason = degraded
|
|
548
|
-
? `${(
|
|
578
|
+
? `${(_m = ("scanErrors" in done ? done.scanErrors : 0)) !== null && _m !== void 0 ? _m : 0} scan errors, ${(_o = ("failedFiles" in done ? done.failedFiles : 0)) !== null && _o !== void 0 ? _o : 0} file failures`
|
|
549
579
|
: done.error;
|
|
550
580
|
console.log(`FAIL ${name}: reindex failed (${reason})`);
|
|
551
581
|
}
|
|
@@ -486,6 +486,28 @@ class Daemon {
|
|
|
486
486
|
runSharedOperation(name, signal, fn) {
|
|
487
487
|
return this.operations.runShared(name, signal, fn);
|
|
488
488
|
}
|
|
489
|
+
/**
|
|
490
|
+
* Compact + prune on behalf of a CLI caller.
|
|
491
|
+
*
|
|
492
|
+
* Lance's optimize runs with `deleteUnverified: true`, which its own docs say
|
|
493
|
+
* is only safe when no other process is working on the dataset. That held by
|
|
494
|
+
* accident, not by design: the daemon serializes its own maintenance, but
|
|
495
|
+
* `gmax doctor --fix` optimized in-process, so a user running it during a
|
|
496
|
+
* compaction was a second writer on a store that assumes one. Routing the
|
|
497
|
+
* request here makes it structural — with a daemon up, the daemon is the only
|
|
498
|
+
* optimizer, sharing the same serialization as the maintenance loop. Callers
|
|
499
|
+
* fall back to in-process only when no daemon answers, and are then the sole
|
|
500
|
+
* writer themselves.
|
|
501
|
+
*/
|
|
502
|
+
runOptimize() {
|
|
503
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
504
|
+
const db = this.vectorDb;
|
|
505
|
+
if (!db)
|
|
506
|
+
throw new Error("daemon resources not ready");
|
|
507
|
+
yield this.runSharedOperation("store-maintenance", undefined, () => db.runMaintenance({ force: true }));
|
|
508
|
+
return { ok: true };
|
|
509
|
+
});
|
|
510
|
+
}
|
|
489
511
|
operationStatus() {
|
|
490
512
|
return this.operations.status;
|
|
491
513
|
}
|
|
@@ -173,6 +173,9 @@ function handleCommand(daemon, cmd, conn) {
|
|
|
173
173
|
diskPressure: daemon.getDiskPressure(),
|
|
174
174
|
mlx: daemon.getMlxStatus(),
|
|
175
175
|
};
|
|
176
|
+
case "optimize":
|
|
177
|
+
// Keeps compaction single-writer: see Daemon.runOptimize.
|
|
178
|
+
return yield daemon.runOptimize();
|
|
176
179
|
case "project-stats": {
|
|
177
180
|
const root = String(cmd.root || "");
|
|
178
181
|
if (!root)
|
|
@@ -956,6 +956,15 @@ class VectorDB {
|
|
|
956
956
|
yield this.drainWrites();
|
|
957
957
|
try {
|
|
958
958
|
const done = (0, logger_1.timer)("vectordb", "optimize");
|
|
959
|
+
// deleteUnverified deletes files Lance cannot prove are unreferenced.
|
|
960
|
+
// LanceDB's own docs: only safe "if you can guarantee that no other
|
|
961
|
+
// process is currently working on this dataset. Otherwise the dataset
|
|
962
|
+
// could be put into a corrupted state." gmax is multi-process, so that
|
|
963
|
+
// guarantee comes from routing compaction to a single writer — the
|
|
964
|
+
// daemon serializes it (Daemon.runOptimize + the maintenance loop),
|
|
965
|
+
// and CLI callers go through it rather than optimizing alongside it.
|
|
966
|
+
// Anything new that calls optimize() must preserve that: either be the
|
|
967
|
+
// daemon, or be the only process on the store.
|
|
959
968
|
const stats = yield table.optimize({
|
|
960
969
|
cleanupOlderThan: cutoff,
|
|
961
970
|
deleteUnverified: true,
|
package/package.json
CHANGED