grepmax 0.12.7 → 0.12.9

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/dist/index.js CHANGED
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
+ process.title = "gmax";
37
38
  const fs = __importStar(require("node:fs"));
38
39
  const path = __importStar(require("node:path"));
39
40
  const commander_1 = require("commander");
@@ -74,6 +74,7 @@ class Daemon {
74
74
  }
75
75
  start() {
76
76
  return __awaiter(this, void 0, void 0, function* () {
77
+ process.title = "gmax-daemon";
77
78
  // 1. Kill existing per-project watchers
78
79
  const existing = (0, watcher_store_1.listWatchers)();
79
80
  for (const w of existing) {
@@ -80,12 +80,19 @@ class ProjectBatchProcessor {
80
80
  this.ftsInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () {
81
81
  if (this.closed || this.processing)
82
82
  return;
83
+ this.processing = true;
83
84
  try {
84
85
  yield this.vectorDb.runMaintenance();
85
86
  }
86
87
  catch (err) {
87
88
  console.error(`[${this.wtag}] Maintenance failed:`, err);
88
89
  }
90
+ finally {
91
+ this.processing = false;
92
+ // Process any events that queued during maintenance
93
+ if (this.pending.size > 0)
94
+ this.scheduleBatch();
95
+ }
89
96
  }), FTS_REBUILD_INTERVAL_MS);
90
97
  this.ftsInterval.unref();
91
98
  }
@@ -93,12 +100,10 @@ class ProjectBatchProcessor {
93
100
  var _a;
94
101
  if (this.closed)
95
102
  return;
96
- if (event !== "unlink") {
97
- const ext = path.extname(absPath).toLowerCase();
98
- const bn = path.basename(absPath).toLowerCase();
99
- if (!config_1.INDEXABLE_EXTENSIONS.has(ext) && !config_1.INDEXABLE_EXTENSIONS.has(bn))
100
- return;
101
- }
103
+ const ext = path.extname(absPath).toLowerCase();
104
+ const bn = path.basename(absPath).toLowerCase();
105
+ if (!config_1.INDEXABLE_EXTENSIONS.has(ext) && !config_1.INDEXABLE_EXTENSIONS.has(bn))
106
+ return;
102
107
  this.pending.set(absPath, event);
103
108
  (_a = this.onActivity) === null || _a === void 0 ? void 0 : _a.call(this);
104
109
  this.scheduleBatch();
@@ -62,6 +62,8 @@ exports.WATCHER_IGNORE_GLOBS = [
62
62
  ".next",
63
63
  "lancedb",
64
64
  ".*", // dotfiles
65
+ "**/*.tmp.*", // editor atomic save artifacts
66
+ "**/*.sb-*", // Xcode swap files
65
67
  ];
66
68
  function startWatcher(opts) {
67
69
  return __awaiter(this, void 0, void 0, function* () {
@@ -405,7 +405,17 @@ class VectorDB {
405
405
  for (let i = 0; i < unique.length; i += batchSize) {
406
406
  const slice = unique.slice(i, i + batchSize);
407
407
  const values = slice.map((p) => `'${(0, filter_builder_1.escapeSqlString)(p)}'`).join(",");
408
- yield table.delete(`path IN (${values})`);
408
+ const where = `path IN (${values})`;
409
+ // Skip no-op deletes to avoid creating empty LanceDB versions
410
+ const existing = yield table
411
+ .query()
412
+ .select(["id"])
413
+ .where(where)
414
+ .limit(1)
415
+ .toArray();
416
+ if (existing.length > 0) {
417
+ yield table.delete(where);
418
+ }
409
419
  }
410
420
  });
411
421
  }
@@ -439,7 +449,16 @@ class VectorDB {
439
449
  const values = slice
440
450
  .map((p) => `'${(0, filter_builder_1.escapeSqlString)(p)}'`)
441
451
  .join(",");
442
- yield table.delete(`path IN (${values})${idExclusion}`);
452
+ const where = `path IN (${values})${idExclusion}`;
453
+ const existing = yield table
454
+ .query()
455
+ .select(["id"])
456
+ .where(where)
457
+ .limit(1)
458
+ .toArray();
459
+ if (existing.length > 0) {
460
+ yield table.delete(where);
461
+ }
443
462
  }
444
463
  });
445
464
  }
@@ -8,6 +8,7 @@ dependencies = [
8
8
  "uvicorn>=0.34.0",
9
9
  "mlx-embeddings @ git+https://github.com/Blaizzy/mlx-embeddings.git",
10
10
  "mlx-lm>=0.22.0",
11
+ "setproctitle>=1.3.0",
11
12
  ]
12
13
 
13
14
  [project.scripts]
@@ -148,6 +148,14 @@ async def health():
148
148
 
149
149
 
150
150
  def main():
151
+ # Set process name for Activity Monitor
152
+ proc_name = os.environ.get("GMAX_PROCESS_NAME", "gmax-embed")
153
+ try:
154
+ from setproctitle import setproctitle
155
+ setproctitle(proc_name)
156
+ except ImportError:
157
+ pass
158
+
151
159
  # Bail early if port is already taken
152
160
  if is_port_in_use(PORT):
153
161
  print(f"[mlx-embed] Port {PORT} already in use — server is already running.")
@@ -148,6 +148,7 @@ async def summarize(request: SummarizeRequest) -> SummarizeResponse:
148
148
  summaries.append(summary)
149
149
  except Exception as e:
150
150
  summaries.append(f"(summary failed: {e})")
151
+ mx.metal.clear_cache()
151
152
 
152
153
  return SummarizeResponse(summaries=summaries)
153
154
 
@@ -162,6 +163,14 @@ async def health():
162
163
 
163
164
 
164
165
  def main():
166
+ # Set process name for Activity Monitor
167
+ proc_name = os.environ.get("GMAX_PROCESS_NAME", "gmax-summarizer")
168
+ try:
169
+ from setproctitle import setproctitle
170
+ setproctitle(proc_name)
171
+ except ImportError:
172
+ pass
173
+
165
174
  if is_port_in_use(PORT):
166
175
  print(f"[summarizer] Port {PORT} already in use — server is already running.")
167
176
  return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.12.7",
3
+ "version": "0.12.9",
4
4
  "author": "Robert Owens <robowens@me.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.12.7",
3
+ "version": "0.12.9",
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",
@@ -42,7 +42,7 @@ function findMlxServerDir() {
42
42
  return null;
43
43
  }
44
44
 
45
- function startPythonServer(serverDir, scriptName, logName) {
45
+ function startPythonServer(serverDir, scriptName, logName, processName) {
46
46
  if (!serverDir) return;
47
47
 
48
48
  const logDir = _path.join(require("node:os").homedir(), ".gmax", "logs");
@@ -63,7 +63,12 @@ function startPythonServer(serverDir, scriptName, logName) {
63
63
  cwd: serverDir,
64
64
  detached: true,
65
65
  stdio: ["ignore", out, out],
66
- env: { ...process.env, VIRTUAL_ENV: "", CONDA_DEFAULT_ENV: "" },
66
+ env: {
67
+ ...process.env,
68
+ VIRTUAL_ENV: "",
69
+ CONDA_DEFAULT_ENV: "",
70
+ GMAX_PROCESS_NAME: processName || logName,
71
+ },
67
72
  });
68
73
  child.unref();
69
74
  }
@@ -105,12 +110,12 @@ async function main() {
105
110
 
106
111
  // Start MLX embed server (port 8100)
107
112
  if (serverDir && !(await isServerRunning(8100))) {
108
- startPythonServer(serverDir, "server.py", "mlx-embed-server");
113
+ startPythonServer(serverDir, "server.py", "mlx-embed-server", "gmax-embed");
109
114
  }
110
115
 
111
- // Start LLM summarizer server (port 8101)
112
- if (serverDir && !(await isServerRunning(8101))) {
113
- startPythonServer(serverDir, "summarizer.py", "mlx-summarizer");
116
+ // Start LLM summarizer server (port 8101) — opt-in only
117
+ if (process.env.GMAX_SUMMARIZER === "1" && serverDir && !(await isServerRunning(8101))) {
118
+ startPythonServer(serverDir, "summarizer.py", "mlx-summarizer", "gmax-summarizer");
114
119
  }
115
120
  }
116
121