grepmax 0.26.56 → 0.26.57

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.56",
13
+ "version": "0.26.57",
14
14
  "author": {
15
15
  "name": "Robert Owens",
16
16
  "email": "robowens@me.com"
package/README.md CHANGED
@@ -472,6 +472,8 @@ gmax watch restart # Restart daemon
472
472
 
473
473
  `gmax doctor` reports ANN index state. `ANN: vector index not built` is normal with the default exact-search configuration.
474
474
 
475
+ `gmax doctor` and `gmax status` report persistent safety stops and daemon startup quarantine. `doctor` exits with code 2 when startup is blocked; `status --json` includes `daemon.startupBlockedReason`. Installing an update preserves these stops. macOS kernel-zone probes use `zprint -L` to omit the wired-memory report and kernel symbolication while retaining the same zone counters and pressure thresholds.
476
+
475
477
  Full-table compaction and new FTS/ANN index builds are disabled in the containment release, including forced maintenance and doctor repair. Existing indexes remain readable; missing lexical indexes fall back to available retrieval. Retained copies are not recovered by this release. A separate exclusive prune-only path requires validation before deployment. Do not repeatedly force repair, use future cutoffs or manually remove index fragments.
476
478
 
477
479
  `~/.gmax/logs/daemon.log` records containment skips and retained historical compaction outcomes, including duration, logical size, disk size before/after, free space, and bytes reclaimed. `gmax status --json` exposes the last outcome under `daemon.compaction`; its `at` timestamp identifies when it was recorded. Five-minute resource snapshots track footprint, RSS, heap, external/ArrayBuffer memory, Lance cache, workers and pending work for memory investigations. Reading status uses retained snapshots and does not scan the index directory. Logs rotate to `daemon.log.prev`.
@@ -52,6 +52,7 @@ const config_1 = require("../config");
52
52
  const embedding_status_1 = require("../lib/index/embedding-status");
53
53
  const index_config_1 = require("../lib/index/index-config");
54
54
  const maintenance_policy_1 = require("../lib/store/maintenance-policy");
55
+ const autostart_1 = require("../lib/utils/autostart");
55
56
  const doctor_optimize_1 = require("../lib/utils/doctor-optimize");
56
57
  const doctor_status_1 = require("../lib/utils/doctor-status");
57
58
  const exit_1 = require("../lib/utils/exit");
@@ -357,6 +358,16 @@ exports.doctor = new commander_1.Command("doctor")
357
358
  }
358
359
  if (!opts.agent)
359
360
  console.log("gmax Doctor\n");
361
+ const startupBlockedReason = (0, autostart_1.daemonStartDeniedReason)();
362
+ if (startupBlockedReason !== null) {
363
+ const reason = startupBlockedReason.replace(/[\r\n\t]/g, " ");
364
+ console.log(opts.agent
365
+ ? `daemon_startup\tblocked=true\treason=${reason}`
366
+ : `FAIL Daemon startup blocked: ${reason}`);
367
+ // Inspect the retained index, but do not report a healthy installation
368
+ // while the persistent host stop or autostart quarantine prevents use.
369
+ process.exitCode = 2;
370
+ }
360
371
  const root = config_1.PATHS.globalRoot;
361
372
  const models = config_1.PATHS.models;
362
373
  const grammars = config_1.PATHS.grammars;
@@ -51,6 +51,7 @@ const config_1 = require("../config");
51
51
  const embedding_status_1 = require("../lib/index/embedding-status");
52
52
  const index_config_1 = require("../lib/index/index-config");
53
53
  const index_state_footer_1 = require("../lib/output/index-state-footer");
54
+ const autostart_1 = require("../lib/utils/autostart");
54
55
  const daemon_client_1 = require("../lib/utils/daemon-client");
55
56
  const exit_1 = require("../lib/utils/exit");
56
57
  const filter_builder_1 = require("../lib/utils/filter-builder");
@@ -206,7 +207,9 @@ function buildStatusJson(input) {
206
207
  ? ((_c = input.countWorkers) !== null && _c !== void 0 ? _c : countWorkerProcesses)(d.pid)
207
208
  : null);
208
209
  }
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: {
210
+ return Object.assign(Object.assign({}, (input.stores ? { stores: input.stores } : {})), { daemon: Object.assign(Object.assign(Object.assign(Object.assign({ running: d !== undefined }, (input.startupBlockedReason != null
211
+ ? { startupBlockedReason: input.startupBlockedReason }
212
+ : {})), { 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: {
210
213
  embedMode: globalConfig.embedMode,
211
214
  modelTier: globalConfig.modelTier,
212
215
  vectorDim: globalConfig.vectorDim,
@@ -283,6 +286,7 @@ Examples:
283
286
  throw err;
284
287
  }
285
288
  const { watchers, chunkCounts } = view;
289
+ const startupBlockedReason = (0, autostart_1.daemonStartDeniedReason)();
286
290
  if (opts.json) {
287
291
  const json = buildStatusJson({
288
292
  stores,
@@ -290,6 +294,7 @@ Examples:
290
294
  projects,
291
295
  globalConfig,
292
296
  indexing,
297
+ startupBlockedReason,
293
298
  workerThreads: (0, config_1.resolveWorkerThreads)({
294
299
  env: process.env.GMAX_WORKER_THREADS,
295
300
  configValue: globalConfig.workerThreads,
@@ -303,6 +308,12 @@ Examples:
303
308
  // Header
304
309
  console.log(`\n${style.bold("gmax")} · ${globalConfig.modelTier} (${globalConfig.vectorDim}d, ${globalConfig.embedMode})${indexing ? style.yellow(" · indexing...") : ""}`);
305
310
  }
311
+ if (startupBlockedReason !== null) {
312
+ const reason = startupBlockedReason.replace(/[\r\n\t]/g, " ");
313
+ console.log(opts.agent
314
+ ? `daemon_startup\tblocked=true\treason=${reason}`
315
+ : style.red(`Daemon startup blocked: ${reason}`));
316
+ }
306
317
  for (const store of stores) {
307
318
  if (opts.agent) {
308
319
  console.log(`store\t${store.home}\t${store.state}\tprefixes=${store.prefixes.join(",")}${store.error ? `\terror=${store.error}` : ""}`);
@@ -144,7 +144,12 @@ function boundedPressureProbe(command, args, timeout, parse, overrides) {
144
144
  }
145
145
  }
146
146
  function probeKernelZoneUsage(zoneName = ZONE_NAME, overrides = {}) {
147
- const result = boundedPressureProbe("zprint", [zoneName], PROBE_TIMEOUT_MS, (output) => {
147
+ const result = boundedPressureProbe("zprint",
148
+ // A name only filters printed rows; zprint still prepares the wired-memory
149
+ // report (including kernel symbolication) by default. -L skips that work.
150
+ // On the incident host this reduced 6–10 second probes to 23–85 ms without
151
+ // changing the zone counters, timeout, or fail-closed admission policy.
152
+ ["-L", zoneName], PROBE_TIMEOUT_MS, (output) => {
148
153
  const parsed = parseZprintOutput(output, zoneName);
149
154
  if (!parsed)
150
155
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.56",
3
+ "version": "0.26.57",
4
4
  "author": "Robert Owens <78518764+reowens@users.noreply.github.com>",
5
5
  "homepage": "https://github.com/reowens/grepmax",
6
6
  "bugs": {
@@ -108,7 +108,7 @@
108
108
  "@modelcontextprotocol/client": "2.3.0",
109
109
  "@types/node": "^26.6.1",
110
110
  "@types/proper-lockfile": "^4.1.4",
111
- "mcp-sdk-v1-fixture": "npm:@modelcontextprotocol/sdk@1.30.0",
111
+ "mcp-sdk-v1-fixture": "npm:@modelcontextprotocol/sdk@1.31.0",
112
112
  "node-gyp": "^13.0.2",
113
113
  "tsx": "^4.23.13",
114
114
  "typescript": "^7.0.2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.26.56",
3
+ "version": "0.26.57",
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",