grepmax 0.26.72 → 0.26.74
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/dist/commands/watch.js +15 -4
- package/dist/lib/daemon/daemon.js +28 -14
- package/dist/lib/daemon/watcher-manager.js +209 -170
- package/dist/lib/index/watcher-recovery.js +91 -0
- package/dist/lib/index/watcher.js +97 -61
- package/dist/lib/output/index-state-footer.js +8 -0
- package/dist/lib/utils/host-guard-policy.js +1 -0
- package/dist/lib/utils/kernel-zone.js +4 -4
- package/dist/lib/utils/pressure-diagnostics.js +176 -0
- package/dist/lib/utils/resource-budget.js +12 -9
- package/dist/lib/utils/safety-latch.js +5 -1
- package/dist/lib/utils/watcher-store.js +3 -2
- package/dist/lib/workers/pool.js +13 -6
- package/package.json +1 -1
- 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.74",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Robert Owens",
|
|
16
16
|
"email": "robowens@me.com"
|
package/dist/commands/watch.js
CHANGED
|
@@ -365,9 +365,10 @@ exports.watch = new commander_1.Command("watch")
|
|
|
365
365
|
},
|
|
366
366
|
});
|
|
367
367
|
console.log(`[watch:${projectName}] File watcher active`);
|
|
368
|
+
(0, watcher_store_1.heartbeat)(process.pid, watcher.health);
|
|
368
369
|
// Heartbeat — update LMDB every 60s so other processes can detect liveliness
|
|
369
370
|
const heartbeatInterval = setInterval(() => {
|
|
370
|
-
(0, watcher_store_1.heartbeat)(process.pid);
|
|
371
|
+
(0, watcher_store_1.heartbeat)(process.pid, watcher.health);
|
|
371
372
|
}, IDLE_CHECK_INTERVAL_MS);
|
|
372
373
|
// Idle timeout
|
|
373
374
|
let lastActivity = Date.now();
|
|
@@ -401,8 +402,8 @@ exports.watch
|
|
|
401
402
|
.command("status")
|
|
402
403
|
.description("Show running watchers")
|
|
403
404
|
.action(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
404
|
-
var _a;
|
|
405
|
-
var
|
|
405
|
+
var _a, _b, _c, _d;
|
|
406
|
+
var _e, _f, _g;
|
|
406
407
|
const { sendDaemonCommand } = yield Promise.resolve().then(() => __importStar(require("../lib/utils/daemon-client")));
|
|
407
408
|
const resp = yield sendDaemonCommand({ cmd: "status" });
|
|
408
409
|
if (resp.ok) {
|
|
@@ -421,7 +422,10 @@ exports.watch
|
|
|
421
422
|
if ((_a = p.indexState) === null || _a === void 0 ? void 0 : _a.queue)
|
|
422
423
|
console.log(` queue: ${(0, index_state_footer_1.formatWatchQueue)(p.indexState.queue)}`);
|
|
423
424
|
if (p.indexState)
|
|
424
|
-
console.log(` watcher=${(
|
|
425
|
+
console.log(` watcher=${(_e = p.indexState.watcherMode) !== null && _e !== void 0 ? _e : "unknown"} overflows=${(_f = p.indexState.overflowCount) !== null && _f !== void 0 ? _f : 0} lastReconciled=${p.indexState.lastReconciledAt ? new Date(p.indexState.lastReconciledAt).toISOString() : "unknown"} catchupMs=${(_g = p.indexState.catchupMs) !== null && _g !== void 0 ? _g : "unknown"}`);
|
|
426
|
+
const recovery = (0, index_state_footer_1.formatWatcherRecovery)((_b = p.indexState) === null || _b === void 0 ? void 0 : _b.watcherRecovery);
|
|
427
|
+
if (recovery)
|
|
428
|
+
console.log(` recovery: ${recovery}`);
|
|
425
429
|
}
|
|
426
430
|
if (projects.length === 0) {
|
|
427
431
|
console.log(" (no projects)");
|
|
@@ -434,6 +438,13 @@ exports.watch
|
|
|
434
438
|
for (const w of watchers) {
|
|
435
439
|
const age = Math.floor((Date.now() - w.startTime) / 60000);
|
|
436
440
|
console.log(` - PID: ${w.pid} | Root: ${w.projectRoot} | Running: ${age}m`);
|
|
441
|
+
const recovery = (0, index_state_footer_1.formatWatcherRecovery)((_c = w.indexState) === null || _c === void 0 ? void 0 : _c.watcherRecovery);
|
|
442
|
+
if (recovery) {
|
|
443
|
+
console.log(` health sample: ${w.indexStateAt ? new Date(w.indexStateAt).toISOString() : "unknown"}`);
|
|
444
|
+
console.log(` recovery: ${recovery}`);
|
|
445
|
+
if ((_d = w.indexState) === null || _d === void 0 ? void 0 : _d.queue)
|
|
446
|
+
console.log(` queue: ${(0, index_state_footer_1.formatWatchQueue)(w.indexState.queue)}`);
|
|
447
|
+
}
|
|
437
448
|
}
|
|
438
449
|
}
|
|
439
450
|
if (!resp.ok && watchers.length === 0) {
|
|
@@ -74,6 +74,7 @@ const keyed_mutex_1 = require("../utils/keyed-mutex");
|
|
|
74
74
|
const log_rotate_1 = require("../utils/log-rotate");
|
|
75
75
|
const logger_1 = require("../utils/logger");
|
|
76
76
|
const operation_coordinator_1 = require("../utils/operation-coordinator");
|
|
77
|
+
const pressure_diagnostics_1 = require("../utils/pressure-diagnostics");
|
|
77
78
|
const process_1 = require("../utils/process");
|
|
78
79
|
const process_footprint_1 = require("../utils/process-footprint");
|
|
79
80
|
const project_registry_1 = require("../utils/project-registry");
|
|
@@ -263,9 +264,9 @@ class Daemon {
|
|
|
263
264
|
if (denied !== null && !options.readOnly)
|
|
264
265
|
throw new Error(`gmax: ${denied}; preserving containment`);
|
|
265
266
|
// Explicit read-only startup preserves every marker and opens no models.
|
|
266
|
-
const pressure = this.hostPressureDeniedReason();
|
|
267
|
+
const pressure = this.hostPressureDeniedReason("startup");
|
|
267
268
|
if (pressure === null || pressure === void 0 ? void 0 : pressure.critical) {
|
|
268
|
-
(0, safety_latch_1.latchSafetyStop)(pressure.reason);
|
|
269
|
+
(0, safety_latch_1.latchSafetyStop)(pressure.reason, undefined, pressure.diagnostics);
|
|
269
270
|
throw new Error(`gmax: ${pressure.reason}; startup safety stop`);
|
|
270
271
|
}
|
|
271
272
|
if (options.readOnly || pressure !== null) {
|
|
@@ -534,7 +535,7 @@ class Daemon {
|
|
|
534
535
|
catch (_a) { }
|
|
535
536
|
(0, log_rotate_1.rotateLogFds)(path.join(config_1.PATHS.logsDir, "daemon.log"));
|
|
536
537
|
this.sweepWatchLeases();
|
|
537
|
-
if (!this.checkKernelZonePressure()) {
|
|
538
|
+
if (!this.checkKernelZonePressure("heartbeat")) {
|
|
538
539
|
this.heartbeatTick++;
|
|
539
540
|
if (this.pausedReason !== null && this.heartbeatTick % 5 === 0)
|
|
540
541
|
this.logResourceSnapshot("paused-heartbeat", null);
|
|
@@ -726,7 +727,7 @@ class Daemon {
|
|
|
726
727
|
yield (0, query_timeout_1.withQueryTimeout)(this.pausePromise, "pause transition", paused_reads_1.PAUSED_QUERY_TIMEOUT_MS);
|
|
727
728
|
if (this.shuttingDown || this.recycling)
|
|
728
729
|
throw new operation_coordinator_1.OperationClosedError();
|
|
729
|
-
this.checkKernelZonePressure();
|
|
730
|
+
this.checkKernelZonePressure("operation");
|
|
730
731
|
if (this.shuttingDown || this.recycling)
|
|
731
732
|
throw new operation_coordinator_1.OperationClosedError();
|
|
732
733
|
return fn(operationSignal);
|
|
@@ -795,7 +796,7 @@ class Daemon {
|
|
|
795
796
|
if (denied !== null)
|
|
796
797
|
throw new Error(`${name} refused: ${denied}`);
|
|
797
798
|
// Probe at operation admission, before setup/cache/worker/model side effects.
|
|
798
|
-
if (!this.checkKernelZonePressure()) {
|
|
799
|
+
if (!this.checkKernelZonePressure("operation")) {
|
|
799
800
|
throw new Error(`${name} refused: host pressure is unsafe or unknown${this.pausedReason ? `: ${this.pausedReason}` : ""}`);
|
|
800
801
|
}
|
|
801
802
|
if (!this.checkAggregateResources())
|
|
@@ -2140,7 +2141,7 @@ class Daemon {
|
|
|
2140
2141
|
}
|
|
2141
2142
|
runHeartbeatMaintenance(sampleFootprint) {
|
|
2142
2143
|
// Both ordinary probes and deferred-recycle ticks check safety first.
|
|
2143
|
-
if (!this.checkKernelZonePressure())
|
|
2144
|
+
if (!this.checkKernelZonePressure("heartbeat"))
|
|
2144
2145
|
return;
|
|
2145
2146
|
if (sampleFootprint && !this.checkAggregateResources())
|
|
2146
2147
|
return;
|
|
@@ -2260,12 +2261,12 @@ class Daemon {
|
|
|
2260
2261
|
* Non-macOS hosts have no such probe. On macOS an unavailable sample is
|
|
2261
2262
|
* explicitly unknown and cannot authorize further mutation.
|
|
2262
2263
|
*/
|
|
2263
|
-
checkKernelZonePressure() {
|
|
2264
|
+
checkKernelZonePressure(action = "pressure-check") {
|
|
2264
2265
|
if (this.shuttingDown || this.recycling)
|
|
2265
2266
|
return false;
|
|
2266
|
-
const pressure = this.hostPressureDeniedReason();
|
|
2267
|
+
const pressure = this.hostPressureDeniedReason(action);
|
|
2267
2268
|
if (pressure === null || pressure === void 0 ? void 0 : pressure.critical) {
|
|
2268
|
-
this.stopForSafety(pressure.reason);
|
|
2269
|
+
this.stopForSafety(pressure.reason, true, pressure.diagnostics);
|
|
2269
2270
|
return false;
|
|
2270
2271
|
}
|
|
2271
2272
|
const denied = (0, autostart_1.daemonStartDeniedReason)();
|
|
@@ -2287,39 +2288,48 @@ class Daemon {
|
|
|
2287
2288
|
? error.message
|
|
2288
2289
|
: "aggregate resource admission unavailable";
|
|
2289
2290
|
if (error instanceof resource_budget_1.ResourceAdmissionError && error.critical)
|
|
2290
|
-
this.stopForSafety(reason);
|
|
2291
|
+
this.stopForSafety(reason, true, error.diagnostics);
|
|
2291
2292
|
else
|
|
2292
2293
|
this.pauseWork(reason);
|
|
2293
2294
|
return false;
|
|
2294
2295
|
}
|
|
2295
2296
|
}
|
|
2296
2297
|
/** Unknown/warning pauses resource expansion; only known critical shuts down. */
|
|
2297
|
-
hostPressureDeniedReason() {
|
|
2298
|
+
hostPressureDeniedReason(action = "pressure-check") {
|
|
2298
2299
|
if (process.platform !== "darwin")
|
|
2299
2300
|
return null;
|
|
2301
|
+
const policy = (0, host_guard_policy_1.hostGuardPolicy)();
|
|
2302
|
+
const probes = {};
|
|
2303
|
+
const diagnostics = () => (0, pressure_diagnostics_1.probeStopDiagnostics)("daemon-pressure", action, policy, probes);
|
|
2300
2304
|
const memory = (0, kernel_zone_1.probeMemoryPressure)();
|
|
2305
|
+
probes.memoryInitial = memory;
|
|
2301
2306
|
if (memory.status === "known" && memory.pressure === "critical")
|
|
2302
2307
|
return {
|
|
2303
2308
|
reason: `critical OS memory pressure (${(0, kernel_zone_1.formatPressureProbe)(memory)})`,
|
|
2304
2309
|
measured: true,
|
|
2305
2310
|
critical: true,
|
|
2311
|
+
diagnostics: diagnostics(),
|
|
2306
2312
|
};
|
|
2307
2313
|
// Paused reads still need the kernel-critical guard, even if OS pressure warns.
|
|
2308
2314
|
const kernel = (0, kernel_zone_1.probeKernelZoneUsage)();
|
|
2315
|
+
probes.kernel = kernel;
|
|
2309
2316
|
if (kernel.status === "known" && kernel.usage.pressure === "critical")
|
|
2310
2317
|
return {
|
|
2311
2318
|
reason: `critical kernel pressure: ${(0, kernel_zone_1.formatZoneUsage)(kernel.usage)} (${(0, kernel_zone_1.formatPressureProbe)(kernel)})`,
|
|
2312
2319
|
measured: true,
|
|
2313
2320
|
critical: true,
|
|
2321
|
+
diagnostics: diagnostics(),
|
|
2314
2322
|
};
|
|
2315
2323
|
const freshMemory = (0, kernel_zone_1.probeMemoryPressure)();
|
|
2324
|
+
probes.memoryFinal = freshMemory;
|
|
2316
2325
|
if (freshMemory.status === "known" && freshMemory.pressure === "critical")
|
|
2317
2326
|
return {
|
|
2318
2327
|
reason: `critical OS memory pressure (${(0, kernel_zone_1.formatPressureProbe)(freshMemory)})`,
|
|
2319
2328
|
measured: true,
|
|
2320
2329
|
critical: true,
|
|
2330
|
+
diagnostics: diagnostics(),
|
|
2321
2331
|
};
|
|
2322
|
-
if (
|
|
2332
|
+
if (policy === "critical-only")
|
|
2323
2333
|
return null;
|
|
2324
2334
|
for (const sample of [memory, freshMemory]) {
|
|
2325
2335
|
if (sample.status !== "known")
|
|
@@ -2327,12 +2337,14 @@ class Daemon {
|
|
|
2327
2337
|
reason: `OS memory pressure unavailable (${(0, kernel_zone_1.formatPressureProbe)(sample)})`,
|
|
2328
2338
|
measured: false,
|
|
2329
2339
|
critical: false,
|
|
2340
|
+
diagnostics: diagnostics(),
|
|
2330
2341
|
};
|
|
2331
2342
|
if (sample.pressure !== "normal")
|
|
2332
2343
|
return {
|
|
2333
2344
|
reason: `warn OS memory pressure (${(0, kernel_zone_1.formatPressureProbe)(sample)})`,
|
|
2334
2345
|
measured: true,
|
|
2335
2346
|
critical: false,
|
|
2347
|
+
diagnostics: diagnostics(),
|
|
2336
2348
|
};
|
|
2337
2349
|
}
|
|
2338
2350
|
if (kernel.status !== "known")
|
|
@@ -2340,21 +2352,23 @@ class Daemon {
|
|
|
2340
2352
|
reason: `kernel pressure unavailable (${(0, kernel_zone_1.formatPressureProbe)(kernel)}); heavy work paused`,
|
|
2341
2353
|
measured: false,
|
|
2342
2354
|
critical: false,
|
|
2355
|
+
diagnostics: diagnostics(),
|
|
2343
2356
|
};
|
|
2344
2357
|
if (kernel.usage.pressure !== "ok")
|
|
2345
2358
|
return {
|
|
2346
2359
|
reason: `warn kernel pressure: ${(0, kernel_zone_1.formatZoneUsage)(kernel.usage)} (${(0, kernel_zone_1.formatPressureProbe)(kernel)})`,
|
|
2347
2360
|
measured: true,
|
|
2348
2361
|
critical: false,
|
|
2362
|
+
diagnostics: diagnostics(),
|
|
2349
2363
|
};
|
|
2350
2364
|
return null;
|
|
2351
2365
|
}
|
|
2352
|
-
stopForSafety(reason, persist = true) {
|
|
2366
|
+
stopForSafety(reason, persist = true, diagnostics) {
|
|
2353
2367
|
// Warning already pauses mutation: a stale index costs less than another
|
|
2354
2368
|
// host crash. Unknown readings are visible stops, never healthy samples.
|
|
2355
2369
|
try {
|
|
2356
2370
|
if (persist)
|
|
2357
|
-
(0, safety_latch_1.latchSafetyStop)(reason);
|
|
2371
|
+
(0, safety_latch_1.latchSafetyStop)(reason, undefined, diagnostics);
|
|
2358
2372
|
}
|
|
2359
2373
|
catch (error) {
|
|
2360
2374
|
console.error("[daemon] Failed to persist safety stop; stopping anyway:", error);
|