grepmax 0.26.59 → 0.26.61

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.
@@ -3,18 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildResourceSnapshot = buildResourceSnapshot;
4
4
  function buildResourceSnapshot(counters, memory = process.memoryUsage(), at = Date.now()) {
5
5
  const mb = (bytes) => Math.round(bytes / 1024 / 1024);
6
- return {
7
- at,
8
- reason: counters.reason,
9
- footprintMb: counters.footprintMb,
10
- rssMb: mb(memory.rss),
11
- heapUsedMb: mb(memory.heapUsed),
12
- externalMb: mb(memory.external),
13
- arrayBuffersMb: mb(memory.arrayBuffers),
14
- lanceCacheMb: counters.lanceCacheBytes === null ? null : mb(counters.lanceCacheBytes),
15
- workers: counters.workers,
16
- pendingFiles: counters.pendingFiles,
17
- operations: counters.operations,
18
- maintenance: counters.maintenance,
19
- };
6
+ return Object.assign({ at, reason: counters.reason, footprintMb: counters.footprintMb, rssMb: mb(memory.rss), heapUsedMb: mb(memory.heapUsed), externalMb: mb(memory.external), arrayBuffersMb: mb(memory.arrayBuffers), lanceCacheMb: counters.lanceCacheBytes === null ? null : mb(counters.lanceCacheBytes), workers: counters.workers, pendingFiles: counters.pendingFiles, operations: counters.operations, maintenance: counters.maintenance }, (counters.host ? { host: counters.host } : {}));
20
7
  }
@@ -58,8 +58,10 @@ const config_1 = require("../../config");
58
58
  const embedding_generation_1 = require("../index/embedding-generation");
59
59
  const index_config_1 = require("../index/index-config");
60
60
  const autostart_1 = require("../utils/autostart");
61
+ const host_guard_policy_1 = require("../utils/host-guard-policy");
61
62
  const kernel_zone_1 = require("../utils/kernel-zone");
62
63
  const logger_1 = require("../utils/logger");
64
+ const resource_budget_1 = require("../utils/resource-budget");
63
65
  const safety_latch_1 = require("../utils/safety-latch");
64
66
  const TASK_TIMEOUT_MS = (() => {
65
67
  var _a;
@@ -135,11 +137,37 @@ class ProcessWorker {
135
137
  // fire for the same crash.
136
138
  this.cleanedUp = false;
137
139
  const memArgs = maxMemoryMb ? [`--max-old-space-size=${maxMemoryMb}`] : [];
138
- this.child = childProcess.fork(modulePath, {
139
- execArgv: [...memArgs, ...execArgv],
140
- env: Object.assign(Object.assign({}, process.env), embeddingEnvironment),
141
- serialization: "advanced",
140
+ this.resourceReservation = resource_budget_1.resourceBudget.reserve(resource_budget_1.WORKER_RESOURCE_RESERVE_MB, "worker");
141
+ try {
142
+ const denied = (0, autostart_1.daemonStartDeniedReason)();
143
+ if (denied)
144
+ throw new Error(denied);
145
+ this.child = childProcess.fork(modulePath, {
146
+ execArgv: [...memArgs, ...execArgv],
147
+ env: Object.assign(Object.assign({}, process.env), embeddingEnvironment),
148
+ serialization: "advanced",
149
+ });
150
+ }
151
+ catch (error) {
152
+ this.resourceReservation.release();
153
+ throw error;
154
+ }
155
+ // Keep the reservation until close, including SIGKILL/timeout paths.
156
+ this.child.once("close", () => {
157
+ try {
158
+ this.resourceReservation.release();
159
+ }
160
+ catch (_a) { }
142
161
  });
162
+ try {
163
+ if (!this.child.pid)
164
+ throw new Error("worker PID unavailable");
165
+ this.resourceReservation.attach(this.child.pid);
166
+ }
167
+ catch (error) {
168
+ this.child.kill("SIGKILL");
169
+ throw error;
170
+ }
143
171
  }
144
172
  }
145
173
  function resolveProcessWorker() {
@@ -365,7 +393,7 @@ class WorkerPool {
365
393
  var _a;
366
394
  return Object.assign(new Error((_a = this.spawnDeniedReason) !== null && _a !== void 0 ? _a : "Worker spawn denied"), { code: "HOST_SAFETY" });
367
395
  }
368
- denySpawn(reason, persist = true) {
396
+ denySpawn(reason, persist = false) {
369
397
  // A pool cannot automatically recover after a failed admission. In
370
398
  // particular, timer/exit callbacks must not retry forks or strand queues.
371
399
  this.spawnDeniedReason = `Worker spawn denied: ${reason}`;
@@ -396,22 +424,31 @@ class WorkerPool {
396
424
  const quarantine = (0, autostart_1.daemonStartDeniedReason)();
397
425
  if (quarantine)
398
426
  return this.denySpawn(quarantine, false);
427
+ const strictHostGuard = (0, host_guard_policy_1.hostGuardPolicy)() === "strict";
399
428
  if (process.platform === "darwin") {
400
429
  const memory = (0, kernel_zone_1.probeMemoryPressure)();
401
- if (memory.status !== "known" || memory.pressure !== "normal") {
402
- return this.denySpawn(`OS memory pressure ${memory.status === "known" ? memory.pressure : memory.status}; ${(0, kernel_zone_1.formatPressureProbe)(memory)}`);
430
+ if ((memory.status === "known" && memory.pressure === "critical") ||
431
+ (strictHostGuard &&
432
+ (memory.status !== "known" || memory.pressure !== "normal"))) {
433
+ return this.denySpawn(`OS memory pressure ${memory.status === "known" ? memory.pressure : memory.status}; ${(0, kernel_zone_1.formatPressureProbe)(memory)}`, memory.status === "known" && memory.pressure === "critical");
403
434
  }
404
435
  const kernel = (0, kernel_zone_1.probeKernelZoneUsage)();
405
- if (kernel.status !== "known" || kernel.usage.pressure !== "ok") {
406
- return this.denySpawn(`kernel pressure ${kernel.status === "known" ? kernel.usage.pressure : kernel.status}; ${(0, kernel_zone_1.formatPressureProbe)(kernel)}`);
436
+ if ((kernel.status === "known" && kernel.usage.pressure === "critical") ||
437
+ (strictHostGuard &&
438
+ (kernel.status !== "known" || kernel.usage.pressure !== "ok"))) {
439
+ return this.denySpawn(`kernel pressure ${kernel.status === "known" ? kernel.usage.pressure : kernel.status}; ${(0, kernel_zone_1.formatPressureProbe)(kernel)}`, kernel.status === "known" && kernel.usage.pressure === "critical");
407
440
  }
408
441
  }
409
442
  if (process.platform === "darwin") {
410
443
  // Refresh the cheap OS sample after the potentially slow kernel probe.
411
444
  const freshMemory = (0, kernel_zone_1.probeMemoryPressure)();
412
- if (freshMemory.status !== "known" ||
413
- freshMemory.pressure !== "normal") {
414
- return this.denySpawn(`OS memory pressure ${freshMemory.status === "known" ? freshMemory.pressure : freshMemory.status}; ${(0, kernel_zone_1.formatPressureProbe)(freshMemory)}`);
445
+ if ((freshMemory.status === "known" &&
446
+ freshMemory.pressure === "critical") ||
447
+ (strictHostGuard &&
448
+ (freshMemory.status !== "known" ||
449
+ freshMemory.pressure !== "normal"))) {
450
+ return this.denySpawn(`OS memory pressure ${freshMemory.status === "known" ? freshMemory.pressure : freshMemory.status}; ${(0, kernel_zone_1.formatPressureProbe)(freshMemory)}`, freshMemory.status === "known" &&
451
+ freshMemory.pressure === "critical");
415
452
  }
416
453
  }
417
454
  // Probes are synchronous but another process can quarantine the host
@@ -421,8 +458,10 @@ class WorkerPool {
421
458
  return this.denySpawn(finalQuarantine, false);
422
459
  worker = new ProcessWorker(this.modulePath, this.execArgv, this.embeddingEnvironment, config_1.MAX_WORKER_MEMORY_MB);
423
460
  }
424
- catch (_a) {
425
- return this.denySpawn("host admission or fork failed");
461
+ catch (error) {
462
+ return this.denySpawn(error instanceof Error
463
+ ? error.message
464
+ : "host admission or fork failed");
426
465
  }
427
466
  (0, logger_1.log)("pool", `spawn PID:${worker.child.pid} (${this.workers.length + 1}/${Math.max(1, config_1.CONFIG.WORKER_THREADS)})`);
428
467
  const onMessage = (msg) => {
@@ -625,6 +664,15 @@ class WorkerPool {
625
664
  this.dispatch();
626
665
  return;
627
666
  }
667
+ try {
668
+ resource_budget_1.resourceBudget.check();
669
+ }
670
+ catch (error) {
671
+ this.denySpawn(error instanceof Error
672
+ ? error.message
673
+ : "aggregate resource admission unavailable");
674
+ return;
675
+ }
628
676
  idle.busy = true;
629
677
  idle.pendingTaskId = task.id;
630
678
  idle.busySince = Date.now();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.59",
3
+ "version": "0.26.61",
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.59",
3
+ "version": "0.26.61",
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",