grepmax 0.26.1 → 0.26.2

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.1",
13
+ "version": "0.26.2",
14
14
  "author": {
15
15
  "name": "Robert Owens",
16
16
  "email": "robowens@me.com"
@@ -1472,8 +1472,11 @@ class Daemon {
1472
1472
  return;
1473
1473
  }
1474
1474
  const stopHeartbeat = (0, ipc_handler_1.startHeartbeat)(conn);
1475
+ const wasWatching = this.processors.has(root);
1476
+ let unwatched = false;
1475
1477
  try {
1476
1478
  yield this.unwatchProjectWithinOperation(root);
1479
+ unwatched = true;
1477
1480
  const rootPrefix = root.endsWith("/") ? root : `${root}/`;
1478
1481
  yield this.vectorDb.deletePathsWithPrefix(rootPrefix);
1479
1482
  const keys = yield this.metaCache.getKeysWithPrefix(rootPrefix);
@@ -1482,7 +1485,18 @@ class Daemon {
1482
1485
  (0, ipc_handler_1.writeDone)(conn, { ok: true });
1483
1486
  }
1484
1487
  catch (err) {
1485
- const msg = err instanceof Error ? err.message : String(err);
1488
+ let reportedError = err;
1489
+ if (unwatched && wasWatching && !this.shuttingDown) {
1490
+ try {
1491
+ yield this.watchProjectWithinOperation(root);
1492
+ }
1493
+ catch (watchError) {
1494
+ reportedError = new Error(`Project removal failed: ${String(err)}; watcher restoration failed: ${String(watchError)}`);
1495
+ }
1496
+ }
1497
+ const msg = reportedError instanceof Error
1498
+ ? reportedError.message
1499
+ : String(reportedError);
1486
1500
  console.error(`[daemon] removeProject failed for ${path.basename(root)}:`, msg);
1487
1501
  (0, ipc_handler_1.writeDone)(conn, { ok: false, error: msg });
1488
1502
  }
@@ -193,18 +193,9 @@ class ProjectBatchProcessor {
193
193
  var _a, _b, _c, _d, _e;
194
194
  if (this.closed || this.processing || this.pending.size === 0)
195
195
  return;
196
- // Circuit breaker: don't attempt writes when disk is critically low
197
- if (this.vectorDb.diskPressure === "critical") {
198
- (0, logger_1.log)(this.wtag, "Disk critically low — deferring batch processing");
199
- if (this.debounceTimer)
200
- clearTimeout(this.debounceTimer);
201
- this.debounceDueMs = Date.now() + 60000;
202
- this.debounceTimer = setTimeout(() => {
203
- this.debounceTimer = null;
204
- this.debounceDueMs = 0;
205
- this.startBatch();
206
- }, 60000);
207
- return;
196
+ const diskPressure = this.vectorDb.checkDiskPressure();
197
+ if (diskPressure === "critical") {
198
+ (0, logger_1.log)(this.wtag, "Disk critically low — applying deletions and deferring indexing");
208
199
  }
209
200
  const batch = new Map();
210
201
  const batchForceGenerations = new Map();
@@ -304,6 +295,9 @@ class ProjectBatchProcessor {
304
295
  continue;
305
296
  }
306
297
  const stats = classification.stat;
298
+ if (diskPressure === "critical") {
299
+ continue;
300
+ }
307
301
  const cached = this.metaCache.get(absPath);
308
302
  const forceReprocess = batchForceGenerations.has(absPath);
309
303
  if (!forceReprocess &&
@@ -423,6 +417,9 @@ class ProjectBatchProcessor {
423
417
  requeuePath(absPath, event, retryFailures.has(absPath));
424
418
  }
425
419
  }
420
+ if (diskPressure === "critical" && this.pending.size > 0) {
421
+ backoffOverrideMs = 60000;
422
+ }
426
423
  // Flush to VectorDB: insert first, then delete old (preserving new)
427
424
  const newIds = vectors.map((v) => v.id);
428
425
  if (vectors.length > 0) {
@@ -473,7 +470,7 @@ class ProjectBatchProcessor {
473
470
  (_c = this.onPathSuccess) === null || _c === void 0 ? void 0 : _c.call(this, absPath);
474
471
  }
475
472
  // Trigger compaction if fragments are accumulating
476
- if (reindexed > 0) {
473
+ if (reindexed > 0 && diskPressure !== "critical") {
477
474
  try {
478
475
  yield this.vectorDb.compactIfNeeded();
479
476
  }
@@ -484,7 +481,9 @@ class ProjectBatchProcessor {
484
481
  }
485
482
  catch (err) {
486
483
  // Disk pressure: requeue without counting as retries (not the file's fault)
487
- if (err instanceof vector_db_1.DiskPressureError) {
484
+ const code = err === null || err === void 0 ? void 0 : err.code;
485
+ if (err instanceof vector_db_1.DiskPressureError ||
486
+ (diskPressure === "critical" && code === "ENOSPC")) {
488
487
  for (const [absPath, event] of batch) {
489
488
  if (this.terminalFailures.has(absPath))
490
489
  continue;
@@ -589,6 +589,19 @@ class VectorDB {
589
589
  return table;
590
590
  });
591
591
  }
592
+ openExistingTableUnsafe() {
593
+ return __awaiter(this, void 0, void 0, function* () {
594
+ const db = yield this.getDb();
595
+ try {
596
+ return yield db.openTable(TABLE_NAME);
597
+ }
598
+ catch (err) {
599
+ if (isMissingTableError(err))
600
+ return null;
601
+ throw err;
602
+ }
603
+ });
604
+ }
592
605
  insertBatch(records) {
593
606
  return __awaiter(this, void 0, void 0, function* () {
594
607
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
@@ -982,11 +995,12 @@ class VectorDB {
982
995
  return __awaiter(this, void 0, void 0, function* () {
983
996
  if (!paths.length)
984
997
  return;
985
- this.ensureDiskOk();
986
998
  const unique = Array.from(new Set(paths));
987
999
  const batchSize = 500;
988
1000
  yield this.withWriteGate(() => __awaiter(this, void 0, void 0, function* () {
989
- const table = yield this.ensureTableUnsafe();
1001
+ const table = yield this.openExistingTableUnsafe();
1002
+ if (!table)
1003
+ return;
990
1004
  for (let i = 0; i < unique.length; i += batchSize) {
991
1005
  const slice = unique.slice(i, i + batchSize);
992
1006
  const values = slice.map((p) => `'${(0, filter_builder_1.escapeSqlString)(p)}'`).join(",");
@@ -1026,14 +1040,15 @@ class VectorDB {
1026
1040
  return __awaiter(this, void 0, void 0, function* () {
1027
1041
  if (!paths.length)
1028
1042
  return;
1029
- this.ensureDiskOk();
1030
1043
  const unique = Array.from(new Set(paths));
1031
1044
  const batchSize = 500;
1032
1045
  const idExclusion = excludeIds.length > 0
1033
1046
  ? ` AND id NOT IN (${excludeIds.map((id) => `'${(0, filter_builder_1.escapeSqlString)(id)}'`).join(",")})`
1034
1047
  : "";
1035
1048
  yield this.withWriteGate(() => __awaiter(this, void 0, void 0, function* () {
1036
- const table = yield this.ensureTableUnsafe();
1049
+ const table = yield this.openExistingTableUnsafe();
1050
+ if (!table)
1051
+ return;
1037
1052
  for (let i = 0; i < unique.length; i += batchSize) {
1038
1053
  const slice = unique.slice(i, i + batchSize);
1039
1054
  const values = slice.map((p) => `'${(0, filter_builder_1.escapeSqlString)(p)}'`).join(",");
@@ -1053,14 +1068,15 @@ class VectorDB {
1053
1068
  }
1054
1069
  deletePathsWithPrefix(prefix) {
1055
1070
  return __awaiter(this, void 0, void 0, function* () {
1056
- this.ensureDiskOk();
1057
1071
  // Slash-terminate so a project root can't bleed into a sibling
1058
1072
  // (`/repo/app` must not delete `/repo/app2`), and use starts_with so `_`/`%`
1059
1073
  // in the path are literal, not LIKE wildcards. Destructive path — keep this
1060
1074
  // self-protective even if a caller forgets to normalize.
1061
1075
  const dirPrefix = prefix.endsWith("/") ? prefix : `${prefix}/`;
1062
1076
  yield this.withWriteGate(() => __awaiter(this, void 0, void 0, function* () {
1063
- const table = yield this.ensureTableUnsafe();
1077
+ const table = yield this.openExistingTableUnsafe();
1078
+ if (!table)
1079
+ return;
1064
1080
  yield table.delete((0, filter_builder_1.pathStartsWith)(dirPrefix));
1065
1081
  }));
1066
1082
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "author": "Robert Owens <78518764+reowens@users.noreply.github.com>",
5
5
  "homepage": "https://github.com/reowens/grepmax",
6
6
  "bugs": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
5
5
  "author": {
6
6
  "name": "Robert Owens",