@deeplake/hivemind 0.7.32 → 0.7.34

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.
Files changed (34) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +332 -189
  4. package/codex/bundle/capture.js +365 -332
  5. package/codex/bundle/commands/auth-login.js +163 -30
  6. package/codex/bundle/pre-tool-use.js +334 -301
  7. package/codex/bundle/session-start-setup.js +193 -60
  8. package/codex/bundle/session-start.js +229 -87
  9. package/codex/bundle/shell/deeplake-shell.js +328 -295
  10. package/codex/bundle/skillify-worker.js +26 -18
  11. package/codex/bundle/stop.js +450 -394
  12. package/codex/bundle/wiki-worker.js +174 -292
  13. package/cursor/bundle/capture.js +448 -392
  14. package/cursor/bundle/commands/auth-login.js +163 -30
  15. package/cursor/bundle/pre-tool-use.js +324 -291
  16. package/cursor/bundle/session-end.js +43 -20
  17. package/cursor/bundle/session-start.js +272 -130
  18. package/cursor/bundle/shell/deeplake-shell.js +328 -295
  19. package/cursor/bundle/skillify-worker.js +26 -18
  20. package/cursor/bundle/wiki-worker.js +174 -292
  21. package/hermes/bundle/capture.js +448 -392
  22. package/hermes/bundle/commands/auth-login.js +163 -30
  23. package/hermes/bundle/pre-tool-use.js +324 -291
  24. package/hermes/bundle/session-end.js +43 -20
  25. package/hermes/bundle/session-start.js +269 -127
  26. package/hermes/bundle/shell/deeplake-shell.js +328 -295
  27. package/hermes/bundle/skillify-worker.js +26 -18
  28. package/hermes/bundle/wiki-worker.js +174 -292
  29. package/mcp/bundle/server.js +190 -57
  30. package/openclaw/dist/index.js +160 -32
  31. package/openclaw/dist/skillify-worker.js +26 -18
  32. package/openclaw/openclaw.plugin.json +1 -1
  33. package/openclaw/package.json +1 -1
  34. package/package.json +1 -1
@@ -17,21 +17,21 @@ __export(index_marker_store_exports, {
17
17
  hasFreshIndexMarker: () => hasFreshIndexMarker,
18
18
  writeIndexMarker: () => writeIndexMarker
19
19
  });
20
- import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
21
- import { join as join3 } from "node:path";
20
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
21
+ import { join as join5 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
24
- return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join3(tmpdir(), "hivemind-deeplake-indexes");
24
+ return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join5(tmpdir(), "hivemind-deeplake-indexes");
25
25
  }
26
26
  function buildIndexMarkerPath(workspaceId, orgId, table, suffix) {
27
27
  const markerKey = [workspaceId, orgId, table, suffix].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
28
- return join3(getIndexMarkerDir(), `${markerKey}.json`);
28
+ return join5(getIndexMarkerDir(), `${markerKey}.json`);
29
29
  }
30
30
  function hasFreshIndexMarker(markerPath) {
31
31
  if (!existsSync2(markerPath))
32
32
  return false;
33
33
  try {
34
- const raw = JSON.parse(readFileSync2(markerPath, "utf-8"));
34
+ const raw = JSON.parse(readFileSync4(markerPath, "utf-8"));
35
35
  const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
36
36
  if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
37
37
  return false;
@@ -41,8 +41,8 @@ function hasFreshIndexMarker(markerPath) {
41
41
  }
42
42
  }
43
43
  function writeIndexMarker(markerPath) {
44
- mkdirSync(getIndexMarkerDir(), { recursive: true });
45
- writeFileSync(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
44
+ mkdirSync3(getIndexMarkerDir(), { recursive: true });
45
+ writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
46
46
  }
47
47
  var INDEX_MARKER_TTL_MS;
48
48
  var init_index_marker_store = __esm({
@@ -53,9 +53,9 @@ var init_index_marker_store = __esm({
53
53
  });
54
54
 
55
55
  // dist/src/hooks/codex/stop.js
56
- import { readFileSync as readFileSync10, existsSync as existsSync10 } from "node:fs";
56
+ import { readFileSync as readFileSync11, existsSync as existsSync10 } from "node:fs";
57
57
  import { fileURLToPath as fileURLToPath3 } from "node:url";
58
- import { dirname as dirname5, join as join17 } from "node:path";
58
+ import { dirname as dirname6, join as join19 } from "node:path";
59
59
 
60
60
  // dist/src/utils/stdin.js
61
61
  function readStdin() {
@@ -152,6 +152,125 @@ function deeplakeClientHeader() {
152
152
  return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
153
153
  }
154
154
 
155
+ // dist/src/notifications/queue.js
156
+ import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync, openSync, closeSync, unlinkSync, statSync } from "node:fs";
157
+ import { join as join3, resolve } from "node:path";
158
+ import { homedir as homedir3 } from "node:os";
159
+ import { setTimeout as sleep } from "node:timers/promises";
160
+ var log2 = (msg) => log("notifications-queue", msg);
161
+ var LOCK_RETRY_MAX = 50;
162
+ var LOCK_RETRY_BASE_MS = 5;
163
+ var LOCK_STALE_MS = 5e3;
164
+ function queuePath() {
165
+ return join3(homedir3(), ".deeplake", "notifications-queue.json");
166
+ }
167
+ function lockPath() {
168
+ return `${queuePath()}.lock`;
169
+ }
170
+ function readQueue() {
171
+ try {
172
+ const raw = readFileSync2(queuePath(), "utf-8");
173
+ const parsed = JSON.parse(raw);
174
+ if (!parsed || !Array.isArray(parsed.queue)) {
175
+ log2(`queue malformed \u2192 treating as empty`);
176
+ return { queue: [] };
177
+ }
178
+ return { queue: parsed.queue };
179
+ } catch {
180
+ return { queue: [] };
181
+ }
182
+ }
183
+ function _isQueuePathInsideHome(path, home) {
184
+ const r = resolve(path);
185
+ const h = resolve(home);
186
+ return r.startsWith(h + "/") || r === h;
187
+ }
188
+ function writeQueue(q) {
189
+ const path = queuePath();
190
+ const home = resolve(homedir3());
191
+ if (!_isQueuePathInsideHome(path, home)) {
192
+ throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
193
+ }
194
+ mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
195
+ const tmp = `${path}.${process.pid}.tmp`;
196
+ writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
197
+ renameSync(tmp, path);
198
+ }
199
+ async function withQueueLock(fn) {
200
+ const path = lockPath();
201
+ mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
202
+ let fd = null;
203
+ for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
204
+ try {
205
+ fd = openSync(path, "wx", 384);
206
+ break;
207
+ } catch (e) {
208
+ const code = e.code;
209
+ if (code !== "EEXIST")
210
+ throw e;
211
+ try {
212
+ const age = Date.now() - statSync(path).mtimeMs;
213
+ if (age > LOCK_STALE_MS) {
214
+ unlinkSync(path);
215
+ continue;
216
+ }
217
+ } catch {
218
+ }
219
+ const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
220
+ await sleep(delay);
221
+ }
222
+ }
223
+ if (fd === null) {
224
+ log2(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
225
+ return fn();
226
+ }
227
+ try {
228
+ return fn();
229
+ } finally {
230
+ try {
231
+ closeSync(fd);
232
+ } catch {
233
+ }
234
+ try {
235
+ unlinkSync(path);
236
+ } catch {
237
+ }
238
+ }
239
+ }
240
+ function sameDedupKey(a, b) {
241
+ if (a.id !== b.id)
242
+ return false;
243
+ return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
244
+ }
245
+ async function enqueueNotification(n) {
246
+ await withQueueLock(() => {
247
+ const q = readQueue();
248
+ if (q.queue.some((existing) => sameDedupKey(existing, n))) {
249
+ return;
250
+ }
251
+ q.queue.push(n);
252
+ writeQueue(q);
253
+ });
254
+ }
255
+
256
+ // dist/src/commands/auth-creds.js
257
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "node:fs";
258
+ import { join as join4 } from "node:path";
259
+ import { homedir as homedir4 } from "node:os";
260
+ function configDir() {
261
+ return join4(homedir4(), ".deeplake");
262
+ }
263
+ function credsPath() {
264
+ return join4(configDir(), "credentials.json");
265
+ }
266
+ function loadCredentials() {
267
+ try {
268
+ return JSON.parse(readFileSync3(credsPath(), "utf-8"));
269
+ } catch {
270
+ return null;
271
+ }
272
+ }
273
+
155
274
  // dist/src/deeplake-api.js
156
275
  var indexMarkerStorePromise = null;
157
276
  function getIndexMarkerStore() {
@@ -159,7 +278,7 @@ function getIndexMarkerStore() {
159
278
  indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
160
279
  return indexMarkerStorePromise;
161
280
  }
162
- var log2 = (msg) => log("sdk", msg);
281
+ var log3 = (msg) => log("sdk", msg);
163
282
  function summarizeSql(sql, maxLen = 220) {
164
283
  const compact = sql.replace(/\s+/g, " ").trim();
165
284
  return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
@@ -171,7 +290,38 @@ function traceSql(msg) {
171
290
  process.stderr.write(`[deeplake-sql] ${msg}
172
291
  `);
173
292
  if (process.env.HIVEMIND_DEBUG === "1")
174
- log2(msg);
293
+ log3(msg);
294
+ }
295
+ var _signalledBalanceExhausted = false;
296
+ function maybeSignalBalanceExhausted(status, bodyText) {
297
+ if (status !== 402)
298
+ return;
299
+ if (!bodyText.includes("balance_cents"))
300
+ return;
301
+ if (_signalledBalanceExhausted)
302
+ return;
303
+ _signalledBalanceExhausted = true;
304
+ log3(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
305
+ enqueueNotification({
306
+ id: "balance-exhausted",
307
+ severity: "warn",
308
+ transient: true,
309
+ title: "Hivemind credits exhausted \u2014 top up to keep capturing",
310
+ body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
311
+ dedupKey: { reason: "balance-zero" }
312
+ }).catch((e) => {
313
+ log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
314
+ });
315
+ }
316
+ function billingUrl() {
317
+ try {
318
+ const c = loadCredentials();
319
+ if (c?.orgName && c?.workspaceId) {
320
+ return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
321
+ }
322
+ } catch {
323
+ }
324
+ return "https://deeplake.ai";
175
325
  }
176
326
  var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
177
327
  var MAX_RETRIES = 3;
@@ -180,7 +330,7 @@ var MAX_CONCURRENCY = 5;
180
330
  function getQueryTimeoutMs() {
181
331
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
182
332
  }
183
- function sleep(ms) {
333
+ function sleep2(ms) {
184
334
  return new Promise((resolve2) => setTimeout(resolve2, ms));
185
335
  }
186
336
  function isTimeoutError(error) {
@@ -282,8 +432,8 @@ var DeeplakeApi = class {
282
432
  lastError = e instanceof Error ? e : new Error(String(e));
283
433
  if (attempt < MAX_RETRIES) {
284
434
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
285
- log2(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
286
- await sleep(delay);
435
+ log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
436
+ await sleep2(delay);
287
437
  continue;
288
438
  }
289
439
  throw lastError;
@@ -299,10 +449,11 @@ var DeeplakeApi = class {
299
449
  const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
300
450
  if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
301
451
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
302
- log2(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
303
- await sleep(delay);
452
+ log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
453
+ await sleep2(delay);
304
454
  continue;
305
455
  }
456
+ maybeSignalBalanceExhausted(resp.status, text);
306
457
  throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
307
458
  }
308
459
  throw lastError ?? new Error("Query failed: max retries exceeded");
@@ -323,7 +474,7 @@ var DeeplakeApi = class {
323
474
  const chunk = rows.slice(i, i + CONCURRENCY);
324
475
  await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
325
476
  }
326
- log2(`commit: ${rows.length} rows`);
477
+ log3(`commit: ${rows.length} rows`);
327
478
  }
328
479
  async upsertRowSql(row) {
329
480
  const ts = (/* @__PURE__ */ new Date()).toISOString();
@@ -379,7 +530,7 @@ var DeeplakeApi = class {
379
530
  markers.writeIndexMarker(markerPath);
380
531
  return;
381
532
  }
382
- log2(`index "${indexName}" skipped: ${e.message}`);
533
+ log3(`index "${indexName}" skipped: ${e.message}`);
383
534
  }
384
535
  }
385
536
  /**
@@ -469,13 +620,13 @@ var DeeplakeApi = class {
469
620
  };
470
621
  }
471
622
  if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
472
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
623
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
473
624
  continue;
474
625
  }
475
626
  return { tables: [], cacheable: false };
476
627
  } catch {
477
628
  if (attempt < MAX_RETRIES) {
478
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt));
629
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
479
630
  continue;
480
631
  }
481
632
  return { tables: [], cacheable: false };
@@ -503,9 +654,9 @@ var DeeplakeApi = class {
503
654
  } catch (err) {
504
655
  lastErr = err;
505
656
  const msg = err instanceof Error ? err.message : String(err);
506
- log2(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
657
+ log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
507
658
  if (attempt < OUTER_BACKOFFS_MS.length) {
508
- await sleep(OUTER_BACKOFFS_MS[attempt]);
659
+ await sleep2(OUTER_BACKOFFS_MS[attempt]);
509
660
  }
510
661
  }
511
662
  }
@@ -516,9 +667,9 @@ var DeeplakeApi = class {
516
667
  const tbl = sqlIdent(name ?? this.tableName);
517
668
  const tables = await this.listTables();
518
669
  if (!tables.includes(tbl)) {
519
- log2(`table "${tbl}" not found, creating`);
670
+ log3(`table "${tbl}" not found, creating`);
520
671
  await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${tbl}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', summary TEXT NOT NULL DEFAULT '', summary_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'text/plain', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
521
- log2(`table "${tbl}" created`);
672
+ log3(`table "${tbl}" created`);
522
673
  if (!tables.includes(tbl))
523
674
  this._tablesCache = [...tables, tbl];
524
675
  }
@@ -531,9 +682,9 @@ var DeeplakeApi = class {
531
682
  const safe = sqlIdent(name);
532
683
  const tables = await this.listTables();
533
684
  if (!tables.includes(safe)) {
534
- log2(`table "${safe}" not found, creating`);
685
+ log3(`table "${safe}" not found, creating`);
535
686
  await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, message_embedding FLOAT4[], author TEXT NOT NULL DEFAULT '', mime_type TEXT NOT NULL DEFAULT 'application/json', size_bytes BIGINT NOT NULL DEFAULT 0, project TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', agent TEXT NOT NULL DEFAULT '', plugin_version TEXT NOT NULL DEFAULT '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
536
- log2(`table "${safe}" created`);
687
+ log3(`table "${safe}" created`);
537
688
  if (!tables.includes(safe))
538
689
  this._tablesCache = [...tables, safe];
539
690
  }
@@ -556,9 +707,9 @@ var DeeplakeApi = class {
556
707
  const safe = sqlIdent(name);
557
708
  const tables = await this.listTables();
558
709
  if (!tables.includes(safe)) {
559
- log2(`table "${safe}" not found, creating`);
710
+ log3(`table "${safe}" not found, creating`);
560
711
  await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${safe}" (id TEXT NOT NULL DEFAULT '', name TEXT NOT NULL DEFAULT '', project TEXT NOT NULL DEFAULT '', project_key TEXT NOT NULL DEFAULT '', local_path TEXT NOT NULL DEFAULT '', install TEXT NOT NULL DEFAULT 'project', source_sessions TEXT NOT NULL DEFAULT '[]', source_agent TEXT NOT NULL DEFAULT '', scope TEXT NOT NULL DEFAULT 'me', author TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', trigger_text TEXT NOT NULL DEFAULT '', body TEXT NOT NULL DEFAULT '', version BIGINT NOT NULL DEFAULT 1, created_at TEXT NOT NULL DEFAULT '', updated_at TEXT NOT NULL DEFAULT '') USING deeplake`, safe);
561
- log2(`table "${safe}" created`);
712
+ log3(`table "${safe}" created`);
562
713
  if (!tables.includes(safe))
563
714
  this._tablesCache = [...tables, safe];
564
715
  }
@@ -569,20 +720,20 @@ var DeeplakeApi = class {
569
720
  // dist/src/hooks/codex/spawn-wiki-worker.js
570
721
  import { spawn, execSync } from "node:child_process";
571
722
  import { fileURLToPath } from "node:url";
572
- import { dirname as dirname2, join as join6 } from "node:path";
573
- import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "node:fs";
574
- import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
723
+ import { dirname as dirname2, join as join8 } from "node:path";
724
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "node:fs";
725
+ import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
575
726
 
576
727
  // dist/src/utils/wiki-log.js
577
- import { mkdirSync as mkdirSync2, appendFileSync as appendFileSync2 } from "node:fs";
578
- import { join as join4 } from "node:path";
728
+ import { mkdirSync as mkdirSync4, appendFileSync as appendFileSync2 } from "node:fs";
729
+ import { join as join6 } from "node:path";
579
730
  function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
580
- const path = join4(hooksDir, filename);
731
+ const path = join6(hooksDir, filename);
581
732
  return {
582
733
  path,
583
734
  log(msg) {
584
735
  try {
585
- mkdirSync2(hooksDir, { recursive: true });
736
+ mkdirSync4(hooksDir, { recursive: true });
586
737
  appendFileSync2(path, `[${utcTimestamp()}] ${msg}
587
738
  `);
588
739
  } catch {
@@ -592,18 +743,18 @@ function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
592
743
  }
593
744
 
594
745
  // dist/src/utils/version-check.js
595
- import { readFileSync as readFileSync3 } from "node:fs";
596
- import { dirname, join as join5 } from "node:path";
746
+ import { readFileSync as readFileSync5 } from "node:fs";
747
+ import { dirname, join as join7 } from "node:path";
597
748
  function getInstalledVersion(bundleDir, pluginManifestDir) {
598
749
  try {
599
- const pluginJson = join5(bundleDir, "..", pluginManifestDir, "plugin.json");
600
- const plugin = JSON.parse(readFileSync3(pluginJson, "utf-8"));
750
+ const pluginJson = join7(bundleDir, "..", pluginManifestDir, "plugin.json");
751
+ const plugin = JSON.parse(readFileSync5(pluginJson, "utf-8"));
601
752
  if (plugin.version)
602
753
  return plugin.version;
603
754
  } catch {
604
755
  }
605
756
  try {
606
- const stamp = readFileSync3(join5(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
757
+ const stamp = readFileSync5(join7(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
607
758
  if (stamp)
608
759
  return stamp;
609
760
  } catch {
@@ -618,9 +769,9 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
618
769
  ]);
619
770
  let dir = bundleDir;
620
771
  for (let i = 0; i < 5; i++) {
621
- const candidate = join5(dir, "package.json");
772
+ const candidate = join7(dir, "package.json");
622
773
  try {
623
- const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
774
+ const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
624
775
  if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
625
776
  return pkg.version;
626
777
  } catch {
@@ -634,8 +785,8 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
634
785
  }
635
786
 
636
787
  // dist/src/hooks/codex/spawn-wiki-worker.js
637
- var HOME = homedir3();
638
- var wikiLogger = makeWikiLogger(join6(HOME, ".codex", "hooks"));
788
+ var HOME = homedir5();
789
+ var wikiLogger = makeWikiLogger(join8(HOME, ".codex", "hooks"));
639
790
  var WIKI_LOG = wikiLogger.path;
640
791
  var WIKI_PROMPT_TEMPLATE = `You are building a personal wiki from a coding session. Your goal is to extract every piece of knowledge \u2014 entities, decisions, relationships, and facts \u2014 into a structured, searchable wiki entry.
641
792
 
@@ -697,11 +848,11 @@ function findCodexBin() {
697
848
  function spawnCodexWikiWorker(opts) {
698
849
  const { config, sessionId, cwd, bundleDir, reason } = opts;
699
850
  const projectName = cwd.split("/").pop() || "unknown";
700
- const tmpDir = join6(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
701
- mkdirSync3(tmpDir, { recursive: true });
851
+ const tmpDir = join8(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
852
+ mkdirSync5(tmpDir, { recursive: true });
702
853
  const pluginVersion = getInstalledVersion(bundleDir, ".codex-plugin") ?? "";
703
- const configFile = join6(tmpDir, "config.json");
704
- writeFileSync2(configFile, JSON.stringify({
854
+ const configFile = join8(tmpDir, "config.json");
855
+ writeFileSync4(configFile, JSON.stringify({
705
856
  apiUrl: config.apiUrl,
706
857
  token: config.token,
707
858
  orgId: config.orgId,
@@ -715,11 +866,11 @@ function spawnCodexWikiWorker(opts) {
715
866
  tmpDir,
716
867
  codexBin: findCodexBin(),
717
868
  wikiLog: WIKI_LOG,
718
- hooksDir: join6(HOME, ".codex", "hooks"),
869
+ hooksDir: join8(HOME, ".codex", "hooks"),
719
870
  promptTemplate: WIKI_PROMPT_TEMPLATE
720
871
  }));
721
872
  wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
722
- const workerPath = join6(bundleDir, "wiki-worker.js");
873
+ const workerPath = join8(bundleDir, "wiki-worker.js");
723
874
  spawn("nohup", ["node", workerPath, configFile], {
724
875
  detached: true,
725
876
  stdio: ["ignore", "ignore", "ignore"]
@@ -733,15 +884,15 @@ function bundleDirFromImportMeta(importMetaUrl) {
733
884
  // dist/src/skillify/spawn-skillify-worker.js
734
885
  import { spawn as spawn2 } from "node:child_process";
735
886
  import { fileURLToPath as fileURLToPath2 } from "node:url";
736
- import { dirname as dirname3, join as join8 } from "node:path";
737
- import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
738
- import { homedir as homedir5, tmpdir as tmpdir3 } from "node:os";
887
+ import { dirname as dirname3, join as join10 } from "node:path";
888
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
889
+ import { homedir as homedir7, tmpdir as tmpdir3 } from "node:os";
739
890
 
740
891
  // dist/src/skillify/gate-runner.js
741
892
  import { existsSync as existsSync3 } from "node:fs";
742
893
  import { createRequire } from "node:module";
743
- import { homedir as homedir4 } from "node:os";
744
- import { join as join7 } from "node:path";
894
+ import { homedir as homedir6 } from "node:os";
895
+ import { join as join9 } from "node:path";
745
896
  var requireForCp = createRequire(import.meta.url);
746
897
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
747
898
  var inheritedEnv = process;
@@ -753,7 +904,7 @@ function firstExistingPath(candidates) {
753
904
  return null;
754
905
  }
755
906
  function findAgentBin(agent) {
756
- const home = homedir4();
907
+ const home = homedir6();
757
908
  switch (agent) {
758
909
  // /usr/bin/<name> is included in every candidate list — that's the
759
910
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -762,54 +913,54 @@ function findAgentBin(agent) {
762
913
  // #170 caught the gap.
763
914
  case "claude_code":
764
915
  return firstExistingPath([
765
- join7(home, ".claude", "local", "claude"),
916
+ join9(home, ".claude", "local", "claude"),
766
917
  "/usr/local/bin/claude",
767
918
  "/usr/bin/claude",
768
- join7(home, ".npm-global", "bin", "claude"),
769
- join7(home, ".local", "bin", "claude"),
919
+ join9(home, ".npm-global", "bin", "claude"),
920
+ join9(home, ".local", "bin", "claude"),
770
921
  "/opt/homebrew/bin/claude"
771
- ]) ?? join7(home, ".claude", "local", "claude");
922
+ ]) ?? join9(home, ".claude", "local", "claude");
772
923
  case "codex":
773
924
  return firstExistingPath([
774
925
  "/usr/local/bin/codex",
775
926
  "/usr/bin/codex",
776
- join7(home, ".npm-global", "bin", "codex"),
777
- join7(home, ".local", "bin", "codex"),
927
+ join9(home, ".npm-global", "bin", "codex"),
928
+ join9(home, ".local", "bin", "codex"),
778
929
  "/opt/homebrew/bin/codex"
779
930
  ]) ?? "/usr/local/bin/codex";
780
931
  case "cursor":
781
932
  return firstExistingPath([
782
933
  "/usr/local/bin/cursor-agent",
783
934
  "/usr/bin/cursor-agent",
784
- join7(home, ".npm-global", "bin", "cursor-agent"),
785
- join7(home, ".local", "bin", "cursor-agent"),
935
+ join9(home, ".npm-global", "bin", "cursor-agent"),
936
+ join9(home, ".local", "bin", "cursor-agent"),
786
937
  "/opt/homebrew/bin/cursor-agent"
787
938
  ]) ?? "/usr/local/bin/cursor-agent";
788
939
  case "hermes":
789
940
  return firstExistingPath([
790
- join7(home, ".local", "bin", "hermes"),
941
+ join9(home, ".local", "bin", "hermes"),
791
942
  "/usr/local/bin/hermes",
792
943
  "/usr/bin/hermes",
793
- join7(home, ".npm-global", "bin", "hermes"),
944
+ join9(home, ".npm-global", "bin", "hermes"),
794
945
  "/opt/homebrew/bin/hermes"
795
- ]) ?? join7(home, ".local", "bin", "hermes");
946
+ ]) ?? join9(home, ".local", "bin", "hermes");
796
947
  case "pi":
797
948
  return firstExistingPath([
798
- join7(home, ".local", "bin", "pi"),
949
+ join9(home, ".local", "bin", "pi"),
799
950
  "/usr/local/bin/pi",
800
951
  "/usr/bin/pi",
801
- join7(home, ".npm-global", "bin", "pi"),
952
+ join9(home, ".npm-global", "bin", "pi"),
802
953
  "/opt/homebrew/bin/pi"
803
- ]) ?? join7(home, ".local", "bin", "pi");
954
+ ]) ?? join9(home, ".local", "bin", "pi");
804
955
  }
805
956
  }
806
957
 
807
958
  // dist/src/skillify/spawn-skillify-worker.js
808
- var HOME2 = homedir5();
809
- var SKILLIFY_LOG = join8(HOME2, ".claude", "hooks", "skillify.log");
959
+ var HOME2 = homedir7();
960
+ var SKILLIFY_LOG = join10(HOME2, ".claude", "hooks", "skillify.log");
810
961
  function skillifyLog(msg) {
811
962
  try {
812
- mkdirSync4(dirname3(SKILLIFY_LOG), { recursive: true });
963
+ mkdirSync6(dirname3(SKILLIFY_LOG), { recursive: true });
813
964
  appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
814
965
  `);
815
966
  } catch {
@@ -817,11 +968,11 @@ function skillifyLog(msg) {
817
968
  }
818
969
  function spawnSkillifyWorker(opts) {
819
970
  const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
820
- const tmpDir = join8(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
821
- mkdirSync4(tmpDir, { recursive: true, mode: 448 });
971
+ const tmpDir = join10(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
972
+ mkdirSync6(tmpDir, { recursive: true, mode: 448 });
822
973
  const gateBin = findAgentBin(agent);
823
- const configFile = join8(tmpDir, "config.json");
824
- writeFileSync3(configFile, JSON.stringify({
974
+ const configFile = join10(tmpDir, "config.json");
975
+ writeFileSync5(configFile, JSON.stringify({
825
976
  apiUrl: config.apiUrl,
826
977
  token: config.token,
827
978
  orgId: config.orgId,
@@ -851,7 +1002,7 @@ function spawnSkillifyWorker(opts) {
851
1002
  } catch {
852
1003
  }
853
1004
  skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
854
- const workerPath = join8(bundleDir, "skillify-worker.js");
1005
+ const workerPath = join10(bundleDir, "skillify-worker.js");
855
1006
  spawn2("nohup", ["node", workerPath, configFile], {
856
1007
  detached: true,
857
1008
  stdio: ["ignore", "ignore", "ignore"]
@@ -860,36 +1011,45 @@ function spawnSkillifyWorker(opts) {
860
1011
  }
861
1012
 
862
1013
  // dist/src/skillify/state.js
863
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, writeSync, mkdirSync as mkdirSync5, renameSync as renameSync2, existsSync as existsSync5, unlinkSync, openSync, closeSync } from "node:fs";
1014
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, writeSync, mkdirSync as mkdirSync7, renameSync as renameSync3, rmdirSync, existsSync as existsSync5, lstatSync, unlinkSync as unlinkSync3, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
864
1015
  import { execSync as execSync2 } from "node:child_process";
865
- import { homedir as homedir7 } from "node:os";
866
1016
  import { createHash } from "node:crypto";
867
- import { join as join10, basename } from "node:path";
1017
+ import { join as join13, basename } from "node:path";
1018
+
1019
+ // dist/src/skillify/legacy-migration.js
1020
+ import { existsSync as existsSync4, renameSync as renameSync2 } from "node:fs";
1021
+ import { dirname as dirname4, join as join12 } from "node:path";
1022
+
1023
+ // dist/src/skillify/state-dir.js
1024
+ import { homedir as homedir8 } from "node:os";
1025
+ import { join as join11 } from "node:path";
1026
+ function getStateDir() {
1027
+ const override = process.env.HIVEMIND_STATE_DIR?.trim();
1028
+ return override && override.length > 0 ? override : join11(homedir8(), ".deeplake", "state", "skillify");
1029
+ }
868
1030
 
869
1031
  // dist/src/skillify/legacy-migration.js
870
- import { existsSync as existsSync4, renameSync } from "node:fs";
871
- import { homedir as homedir6 } from "node:os";
872
- import { join as join9 } from "node:path";
873
1032
  var dlog = (msg) => log("skillify-migrate", msg);
874
1033
  var attempted = false;
875
1034
  function migrateLegacyStateDir() {
1035
+ if (process.env.HIVEMIND_STATE_DIR?.trim())
1036
+ return;
876
1037
  if (attempted)
877
1038
  return;
878
1039
  attempted = true;
879
- const root = join9(homedir6(), ".deeplake", "state");
880
- const legacy = join9(root, "skilify");
881
- const current = join9(root, "skillify");
1040
+ const current = getStateDir();
1041
+ const legacy = join12(dirname4(current), "skilify");
882
1042
  if (!existsSync4(legacy))
883
1043
  return;
884
1044
  if (existsSync4(current))
885
1045
  return;
886
1046
  try {
887
- renameSync(legacy, current);
1047
+ renameSync2(legacy, current);
888
1048
  dlog(`migrated ${legacy} -> ${current}`);
889
1049
  } catch (err) {
890
1050
  const code = err.code;
891
- if (code === "EXDEV" || code === "EPERM") {
892
- dlog(`migration failed (${code}); leaving legacy dir in place`);
1051
+ if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
1052
+ dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
893
1053
  return;
894
1054
  }
895
1055
  throw err;
@@ -898,17 +1058,16 @@ function migrateLegacyStateDir() {
898
1058
 
899
1059
  // dist/src/skillify/state.js
900
1060
  var dlog2 = (msg) => log("skillify-state", msg);
901
- var STATE_DIR = join10(homedir7(), ".deeplake", "state", "skillify");
902
1061
  var YIELD_BUF = new Int32Array(new SharedArrayBuffer(4));
903
1062
  var TRIGGER_THRESHOLD = (() => {
904
1063
  const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
905
1064
  return Number.isInteger(n) && n > 0 ? n : 20;
906
1065
  })();
907
1066
  function statePath(projectKey) {
908
- return join10(STATE_DIR, `${projectKey}.json`);
1067
+ return join13(getStateDir(), `${projectKey}.json`);
909
1068
  }
910
- function lockPath(projectKey) {
911
- return join10(STATE_DIR, `${projectKey}.lock`);
1069
+ function lockPath2(projectKey) {
1070
+ return join13(getStateDir(), `${projectKey}.lock`);
912
1071
  }
913
1072
  var DEFAULT_PORTS = {
914
1073
  http: "80",
@@ -957,35 +1116,35 @@ function readState(projectKey) {
957
1116
  if (!existsSync5(p))
958
1117
  return null;
959
1118
  try {
960
- return JSON.parse(readFileSync4(p, "utf-8"));
1119
+ return JSON.parse(readFileSync6(p, "utf-8"));
961
1120
  } catch {
962
1121
  return null;
963
1122
  }
964
1123
  }
965
1124
  function writeState(projectKey, state) {
966
1125
  migrateLegacyStateDir();
967
- mkdirSync5(STATE_DIR, { recursive: true });
1126
+ mkdirSync7(getStateDir(), { recursive: true });
968
1127
  const p = statePath(projectKey);
969
1128
  const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
970
- writeFileSync4(tmp, JSON.stringify(state, null, 2));
971
- renameSync2(tmp, p);
1129
+ writeFileSync6(tmp, JSON.stringify(state, null, 2));
1130
+ renameSync3(tmp, p);
972
1131
  }
973
1132
  function withRmwLock(projectKey, fn) {
974
1133
  migrateLegacyStateDir();
975
- mkdirSync5(STATE_DIR, { recursive: true });
976
- const rmw = lockPath(projectKey) + ".rmw";
1134
+ mkdirSync7(getStateDir(), { recursive: true });
1135
+ const rmw = lockPath2(projectKey) + ".rmw";
977
1136
  const deadline = Date.now() + 2e3;
978
1137
  let fd = null;
979
1138
  while (fd === null) {
980
1139
  try {
981
- fd = openSync(rmw, "wx");
1140
+ fd = openSync2(rmw, "wx");
982
1141
  } catch (e) {
983
1142
  if (e.code !== "EEXIST")
984
1143
  throw e;
985
1144
  if (Date.now() > deadline) {
986
1145
  dlog2(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
987
1146
  try {
988
- unlinkSync(rmw);
1147
+ unlinkSync3(rmw);
989
1148
  } catch (unlinkErr) {
990
1149
  dlog2(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
991
1150
  }
@@ -997,9 +1156,9 @@ function withRmwLock(projectKey, fn) {
997
1156
  try {
998
1157
  return fn();
999
1158
  } finally {
1000
- closeSync(fd);
1159
+ closeSync2(fd);
1001
1160
  try {
1002
- unlinkSync(rmw);
1161
+ unlinkSync3(rmw);
1003
1162
  } catch (unlinkErr) {
1004
1163
  dlog2(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
1005
1164
  }
@@ -1015,29 +1174,43 @@ function resetCounter(projectKey) {
1015
1174
  }
1016
1175
  function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
1017
1176
  migrateLegacyStateDir();
1018
- mkdirSync5(STATE_DIR, { recursive: true });
1019
- const p = lockPath(projectKey);
1177
+ mkdirSync7(getStateDir(), { recursive: true });
1178
+ const p = lockPath2(projectKey);
1020
1179
  if (existsSync5(p)) {
1021
1180
  try {
1022
- const ageMs = Date.now() - parseInt(readFileSync4(p, "utf-8"), 10);
1181
+ const ageMs = Date.now() - parseInt(readFileSync6(p, "utf-8"), 10);
1023
1182
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
1024
1183
  return false;
1025
1184
  } catch (readErr) {
1026
1185
  dlog2(`worker lock unreadable for ${projectKey}, treating as stale: ${readErr.message}`);
1027
1186
  }
1028
1187
  try {
1029
- unlinkSync(p);
1188
+ unlinkSync3(p);
1030
1189
  } catch (unlinkErr) {
1031
- dlog2(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
1032
- return false;
1190
+ if (unlinkErr?.code !== "EISDIR" && unlinkErr?.code !== "EPERM" && unlinkErr?.code !== "ENOENT") {
1191
+ dlog2(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
1192
+ return false;
1193
+ }
1194
+ let isDir = false;
1195
+ try {
1196
+ isDir = lstatSync(p).isDirectory();
1197
+ } catch {
1198
+ }
1199
+ if (isDir) {
1200
+ try {
1201
+ rmdirSync(p);
1202
+ } catch (rmErr) {
1203
+ dlog2(`rmdir stale lock skipped for ${projectKey}: ${rmErr.message}`);
1204
+ }
1205
+ }
1033
1206
  }
1034
1207
  }
1035
1208
  try {
1036
- const fd = openSync(p, "wx");
1209
+ const fd = openSync2(p, "wx");
1037
1210
  try {
1038
1211
  writeSync(fd, String(Date.now()));
1039
1212
  } finally {
1040
- closeSync(fd);
1213
+ closeSync2(fd);
1041
1214
  }
1042
1215
  return true;
1043
1216
  } catch {
@@ -1045,26 +1218,27 @@ function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
1045
1218
  }
1046
1219
  }
1047
1220
  function releaseWorkerLock(projectKey) {
1048
- const p = lockPath(projectKey);
1221
+ const p = lockPath2(projectKey);
1049
1222
  try {
1050
- unlinkSync(p);
1223
+ unlinkSync3(p);
1051
1224
  } catch {
1052
1225
  }
1053
1226
  }
1054
1227
 
1055
1228
  // dist/src/skillify/scope-config.js
1056
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "node:fs";
1057
- import { homedir as homedir8 } from "node:os";
1058
- import { join as join11 } from "node:path";
1059
- var STATE_DIR2 = join11(homedir8(), ".deeplake", "state", "skillify");
1060
- var CONFIG_PATH = join11(STATE_DIR2, "config.json");
1229
+ import { existsSync as existsSync6, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
1230
+ import { join as join14 } from "node:path";
1231
+ function configPath() {
1232
+ return join14(getStateDir(), "config.json");
1233
+ }
1061
1234
  var DEFAULT = { scope: "me", team: [], install: "project" };
1062
1235
  function loadScopeConfig() {
1063
1236
  migrateLegacyStateDir();
1237
+ const CONFIG_PATH = configPath();
1064
1238
  if (!existsSync6(CONFIG_PATH))
1065
1239
  return DEFAULT;
1066
1240
  try {
1067
- const raw = JSON.parse(readFileSync5(CONFIG_PATH, "utf-8"));
1241
+ const raw = JSON.parse(readFileSync7(CONFIG_PATH, "utf-8"));
1068
1242
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
1069
1243
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
1070
1244
  const install = raw.install === "global" ? "global" : "project";
@@ -1115,39 +1289,39 @@ function forceSessionEndTrigger(opts) {
1115
1289
  }
1116
1290
 
1117
1291
  // dist/src/hooks/summary-state.js
1118
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, writeSync as writeSync2, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync7, unlinkSync as unlinkSync2, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
1292
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync8, writeSync as writeSync2, mkdirSync as mkdirSync9, renameSync as renameSync4, existsSync as existsSync7, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1119
1293
  import { homedir as homedir9 } from "node:os";
1120
- import { join as join12 } from "node:path";
1294
+ import { join as join15 } from "node:path";
1121
1295
  var dlog3 = (msg) => log("summary-state", msg);
1122
- var STATE_DIR3 = join12(homedir9(), ".claude", "hooks", "summary-state");
1296
+ var STATE_DIR = join15(homedir9(), ".claude", "hooks", "summary-state");
1123
1297
  var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
1124
- function lockPath2(sessionId) {
1125
- return join12(STATE_DIR3, `${sessionId}.lock`);
1298
+ function lockPath3(sessionId) {
1299
+ return join15(STATE_DIR, `${sessionId}.lock`);
1126
1300
  }
1127
1301
  function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1128
- mkdirSync7(STATE_DIR3, { recursive: true });
1129
- const p = lockPath2(sessionId);
1302
+ mkdirSync9(STATE_DIR, { recursive: true });
1303
+ const p = lockPath3(sessionId);
1130
1304
  if (existsSync7(p)) {
1131
1305
  try {
1132
- const ageMs = Date.now() - parseInt(readFileSync6(p, "utf-8"), 10);
1306
+ const ageMs = Date.now() - parseInt(readFileSync8(p, "utf-8"), 10);
1133
1307
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
1134
1308
  return false;
1135
1309
  } catch (readErr) {
1136
1310
  dlog3(`lock file unreadable for ${sessionId}, treating as stale: ${readErr.message}`);
1137
1311
  }
1138
1312
  try {
1139
- unlinkSync2(p);
1313
+ unlinkSync4(p);
1140
1314
  } catch (unlinkErr) {
1141
1315
  dlog3(`could not unlink stale lock for ${sessionId}: ${unlinkErr.message}`);
1142
1316
  return false;
1143
1317
  }
1144
1318
  }
1145
1319
  try {
1146
- const fd = openSync2(p, "wx");
1320
+ const fd = openSync3(p, "wx");
1147
1321
  try {
1148
1322
  writeSync2(fd, String(Date.now()));
1149
1323
  } finally {
1150
- closeSync2(fd);
1324
+ closeSync3(fd);
1151
1325
  }
1152
1326
  return true;
1153
1327
  } catch (e) {
@@ -1158,7 +1332,7 @@ function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1158
1332
  }
1159
1333
  function releaseLock(sessionId) {
1160
1334
  try {
1161
- unlinkSync2(lockPath2(sessionId));
1335
+ unlinkSync4(lockPath3(sessionId));
1162
1336
  } catch (e) {
1163
1337
  if (e?.code !== "ENOENT") {
1164
1338
  dlog3(`releaseLock unlink failed for ${sessionId}: ${e.message}`);
@@ -1175,8 +1349,8 @@ function buildSessionPath(config, sessionId) {
1175
1349
  // dist/src/embeddings/client.js
1176
1350
  import { connect } from "node:net";
1177
1351
  import { spawn as spawn3 } from "node:child_process";
1178
- import { openSync as openSync4, closeSync as closeSync4, writeSync as writeSync3, unlinkSync as unlinkSync4, existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
1179
- import { homedir as homedir13 } from "node:os";
1352
+ import { openSync as openSync4, closeSync as closeSync4, writeSync as writeSync3, unlinkSync as unlinkSync5, existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
1353
+ import { homedir as homedir10 } from "node:os";
1180
1354
  import { join as join16 } from "node:path";
1181
1355
 
1182
1356
  // dist/src/embeddings/protocol.js
@@ -1190,233 +1364,13 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
1190
1364
  return `${dir}/hivemind-embed-${uid}.pid`;
1191
1365
  }
1192
1366
 
1193
- // dist/src/notifications/queue.js
1194
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync7, renameSync as renameSync4, mkdirSync as mkdirSync8, openSync as openSync3, closeSync as closeSync3, unlinkSync as unlinkSync3, statSync } from "node:fs";
1195
- import { join as join13, resolve } from "node:path";
1196
- import { homedir as homedir10 } from "node:os";
1197
- import { setTimeout as sleep2 } from "node:timers/promises";
1198
- var log3 = (msg) => log("notifications-queue", msg);
1199
- var LOCK_RETRY_MAX = 50;
1200
- var LOCK_RETRY_BASE_MS = 5;
1201
- var LOCK_STALE_MS = 5e3;
1202
- function queuePath() {
1203
- return join13(homedir10(), ".deeplake", "notifications-queue.json");
1204
- }
1205
- function lockPath3() {
1206
- return `${queuePath()}.lock`;
1207
- }
1208
- function readQueue() {
1209
- try {
1210
- const raw = readFileSync7(queuePath(), "utf-8");
1211
- const parsed = JSON.parse(raw);
1212
- if (!parsed || !Array.isArray(parsed.queue)) {
1213
- log3(`queue malformed \u2192 treating as empty`);
1214
- return { queue: [] };
1215
- }
1216
- return { queue: parsed.queue };
1217
- } catch {
1218
- return { queue: [] };
1219
- }
1220
- }
1221
- function _isQueuePathInsideHome(path, home) {
1222
- const r = resolve(path);
1223
- const h = resolve(home);
1224
- return r.startsWith(h + "/") || r === h;
1225
- }
1226
- function writeQueue(q) {
1227
- const path = queuePath();
1228
- const home = resolve(homedir10());
1229
- if (!_isQueuePathInsideHome(path, home)) {
1230
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
1231
- }
1232
- mkdirSync8(join13(home, ".deeplake"), { recursive: true, mode: 448 });
1233
- const tmp = `${path}.${process.pid}.tmp`;
1234
- writeFileSync7(tmp, JSON.stringify(q, null, 2), { mode: 384 });
1235
- renameSync4(tmp, path);
1236
- }
1237
- async function withQueueLock(fn) {
1238
- const path = lockPath3();
1239
- mkdirSync8(join13(homedir10(), ".deeplake"), { recursive: true, mode: 448 });
1240
- let fd = null;
1241
- for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
1242
- try {
1243
- fd = openSync3(path, "wx", 384);
1244
- break;
1245
- } catch (e) {
1246
- const code = e.code;
1247
- if (code !== "EEXIST")
1248
- throw e;
1249
- try {
1250
- const age = Date.now() - statSync(path).mtimeMs;
1251
- if (age > LOCK_STALE_MS) {
1252
- unlinkSync3(path);
1253
- continue;
1254
- }
1255
- } catch {
1256
- }
1257
- const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
1258
- await sleep2(delay);
1259
- }
1260
- }
1261
- if (fd === null) {
1262
- log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
1263
- return fn();
1264
- }
1265
- try {
1266
- return fn();
1267
- } finally {
1268
- try {
1269
- closeSync3(fd);
1270
- } catch {
1271
- }
1272
- try {
1273
- unlinkSync3(path);
1274
- } catch {
1275
- }
1276
- }
1277
- }
1278
- function sameDedupKey(a, b) {
1279
- if (a.id !== b.id)
1280
- return false;
1281
- return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
1282
- }
1283
- async function enqueueNotification(n) {
1284
- await withQueueLock(() => {
1285
- const q = readQueue();
1286
- if (q.queue.some((existing) => sameDedupKey(existing, n))) {
1287
- return;
1288
- }
1289
- q.queue.push(n);
1290
- writeQueue(q);
1291
- });
1292
- }
1293
-
1294
- // dist/src/embeddings/disable.js
1295
- import { createRequire as createRequire2 } from "node:module";
1296
- import { homedir as homedir12 } from "node:os";
1297
- import { join as join15 } from "node:path";
1298
- import { pathToFileURL } from "node:url";
1299
-
1300
- // dist/src/user-config.js
1301
- import { existsSync as existsSync8, mkdirSync as mkdirSync9, readFileSync as readFileSync8, renameSync as renameSync5, writeFileSync as writeFileSync8 } from "node:fs";
1302
- import { homedir as homedir11 } from "node:os";
1303
- import { dirname as dirname4, join as join14 } from "node:path";
1304
- var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join14(homedir11(), ".deeplake", "config.json");
1305
- var _cache = null;
1306
- var _migrated = false;
1307
- function readUserConfig() {
1308
- if (_cache !== null)
1309
- return _cache;
1310
- const path = _configPath();
1311
- if (!existsSync8(path)) {
1312
- _cache = {};
1313
- return _cache;
1314
- }
1315
- try {
1316
- const raw = readFileSync8(path, "utf-8");
1317
- const parsed = JSON.parse(raw);
1318
- _cache = isPlainObject(parsed) ? parsed : {};
1319
- } catch {
1320
- _cache = {};
1321
- }
1322
- return _cache;
1323
- }
1324
- function writeUserConfig(patch) {
1325
- const current = readUserConfig();
1326
- const merged = deepMerge(current, patch);
1327
- const path = _configPath();
1328
- const dir = dirname4(path);
1329
- if (!existsSync8(dir))
1330
- mkdirSync9(dir, { recursive: true });
1331
- const tmp = `${path}.tmp.${process.pid}`;
1332
- writeFileSync8(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1333
- renameSync5(tmp, path);
1334
- _cache = merged;
1335
- return merged;
1336
- }
1337
- function getEmbeddingsEnabled() {
1338
- const cfg = readUserConfig();
1339
- if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
1340
- return cfg.embeddings.enabled;
1341
- }
1342
- if (_migrated) {
1343
- return migrationValueFromEnv();
1344
- }
1345
- _migrated = true;
1346
- const enabled = migrationValueFromEnv();
1347
- try {
1348
- writeUserConfig({ embeddings: { enabled } });
1349
- } catch {
1350
- _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
1351
- }
1352
- return enabled;
1353
- }
1354
- function migrationValueFromEnv() {
1355
- const raw = process.env.HIVEMIND_EMBEDDINGS;
1356
- if (raw === void 0)
1357
- return false;
1358
- if (raw === "false")
1359
- return false;
1360
- return true;
1361
- }
1362
- function isPlainObject(value) {
1363
- return typeof value === "object" && value !== null && !Array.isArray(value);
1364
- }
1365
- function deepMerge(base, patch) {
1366
- const out = { ...base };
1367
- for (const key of Object.keys(patch)) {
1368
- const patchVal = patch[key];
1369
- const baseVal = base[key];
1370
- if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
1371
- out[key] = { ...baseVal, ...patchVal };
1372
- } else if (patchVal !== void 0) {
1373
- out[key] = patchVal;
1374
- }
1375
- }
1376
- return out;
1377
- }
1378
-
1379
- // dist/src/embeddings/disable.js
1380
- var cachedStatus = null;
1381
- function defaultResolveTransformers() {
1382
- const sharedDir = join15(homedir12(), ".hivemind", "embed-deps");
1383
- try {
1384
- createRequire2(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
1385
- return;
1386
- } catch {
1387
- }
1388
- createRequire2(import.meta.url).resolve("@huggingface/transformers");
1389
- }
1390
- var _resolve = defaultResolveTransformers;
1391
- var _readEnabled = getEmbeddingsEnabled;
1392
- function detectStatus() {
1393
- if (!_readEnabled())
1394
- return "user-disabled";
1395
- try {
1396
- _resolve();
1397
- return "enabled";
1398
- } catch {
1399
- return "no-transformers";
1400
- }
1401
- }
1402
- function embeddingsStatus() {
1403
- if (cachedStatus !== null)
1404
- return cachedStatus;
1405
- cachedStatus = detectStatus();
1406
- return cachedStatus;
1407
- }
1408
- function embeddingsDisabled() {
1409
- return embeddingsStatus() !== "enabled";
1410
- }
1411
-
1412
1367
  // dist/src/embeddings/client.js
1413
- var SHARED_DAEMON_PATH = join16(homedir13(), ".hivemind", "embed-deps", "embed-daemon.js");
1368
+ var SHARED_DAEMON_PATH = join16(homedir10(), ".hivemind", "embed-deps", "embed-daemon.js");
1414
1369
  var log4 = (m) => log("embed-client", m);
1415
1370
  function getUid() {
1416
1371
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
1417
1372
  return uid !== void 0 ? String(uid) : process.env.USER ?? "default";
1418
1373
  }
1419
- var _signalledMissingDeps = false;
1420
1374
  var _recycledStuckDaemon = false;
1421
1375
  var EmbedClient = class {
1422
1376
  socketPath;
@@ -1433,7 +1387,7 @@ var EmbedClient = class {
1433
1387
  this.socketPath = socketPathFor(uid, dir);
1434
1388
  this.pidPath = pidPathFor(uid, dir);
1435
1389
  this.timeoutMs = opts.timeoutMs ?? DEFAULT_CLIENT_TIMEOUT_MS;
1436
- this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync9(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
1390
+ this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync8(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
1437
1391
  this.autoSpawn = opts.autoSpawn ?? true;
1438
1392
  this.spawnWaitMs = opts.spawnWaitMs ?? 5e3;
1439
1393
  }
@@ -1514,7 +1468,7 @@ var EmbedClient = class {
1514
1468
  async waitForDaemonReady() {
1515
1469
  const deadline = Date.now() + this.spawnWaitMs;
1516
1470
  while (Date.now() < deadline) {
1517
- if (existsSync9(this.socketPath))
1471
+ if (existsSync8(this.socketPath))
1518
1472
  return;
1519
1473
  await new Promise((r) => setTimeout(r, 50));
1520
1474
  }
@@ -1557,7 +1511,7 @@ var EmbedClient = class {
1557
1511
  this.recycleDaemon(hello.pid);
1558
1512
  return true;
1559
1513
  }
1560
- if (hello.daemonPath !== this.daemonEntry && !existsSync9(hello.daemonPath)) {
1514
+ if (hello.daemonPath !== this.daemonEntry && !existsSync8(hello.daemonPath)) {
1561
1515
  _recycledStuckDaemon = true;
1562
1516
  log4(`daemon path no longer on disk \u2014 running=${hello.daemonPath} (gone) expected=${this.daemonEntry}; recycling`);
1563
1517
  this.recycleDaemon(hello.pid);
@@ -1569,37 +1523,21 @@ var EmbedClient = class {
1569
1523
  /**
1570
1524
  * On a transformers-missing error from the daemon, SIGTERM the stuck
1571
1525
  * daemon (the bundle daemon that can't find its deps) and clear
1572
- * sock/pid so the next call spawns fresh. Also enqueue a one-time
1573
- * notification telling the user to run `hivemind embeddings install`
1574
- * but only when the user has opted in. Suppressed when
1575
- * embeddingsStatus() === "user-disabled" so we don't nag users who
1576
- * explicitly chose to turn embeddings off.
1526
+ * sock/pid so the next call spawns fresh.
1527
+ *
1528
+ * Previously this also enqueued a user-visible "Hivemind embeddings
1529
+ * disabled deps missing" notification telling the user to run
1530
+ * `hivemind embeddings install`. The notification was removed because
1531
+ * (a) the recycle alone often fixes the issue silently, and (b) the
1532
+ * warning kept stacking on top of the primary session-start banner
1533
+ * which clashed with the single-slot priority model. The `detail`
1534
+ * argument is retained for future telemetry / debug logging.
1577
1535
  */
1578
- handleTransformersMissing(detail) {
1536
+ handleTransformersMissing(_detail) {
1579
1537
  if (!_recycledStuckDaemon) {
1580
1538
  _recycledStuckDaemon = true;
1581
1539
  this.recycleDaemon(null);
1582
1540
  }
1583
- if (_signalledMissingDeps)
1584
- return;
1585
- _signalledMissingDeps = true;
1586
- let status;
1587
- try {
1588
- status = embeddingsStatus();
1589
- } catch {
1590
- status = "enabled";
1591
- }
1592
- if (status === "user-disabled")
1593
- return;
1594
- enqueueNotification({
1595
- id: "embed-deps-missing",
1596
- severity: "warn",
1597
- title: "Hivemind embeddings disabled \u2014 deps missing",
1598
- body: `Semantic memory search is off because @huggingface/transformers is not installed where the daemon can find it. Run \`hivemind embeddings install\` to enable.`,
1599
- dedupKey: { reason: "transformers-missing", detail: detail.slice(0, 200) }
1600
- }).catch((e) => {
1601
- log4(`enqueue embed-deps-missing failed: ${e instanceof Error ? e.message : String(e)}`);
1602
- });
1603
1541
  }
1604
1542
  /**
1605
1543
  * Best-effort SIGTERM + sock/pid cleanup. Tolerant of every missing-file
@@ -1622,7 +1560,7 @@ var EmbedClient = class {
1622
1560
  } catch {
1623
1561
  }
1624
1562
  }
1625
- if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync9(this.socketPath)) {
1563
+ if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync8(this.socketPath)) {
1626
1564
  try {
1627
1565
  process.kill(pid, "SIGTERM");
1628
1566
  } catch {
@@ -1631,11 +1569,11 @@ var EmbedClient = class {
1631
1569
  log4(`recycle: socket gone, skipping SIGTERM on possibly-stale pid ${pid}`);
1632
1570
  }
1633
1571
  try {
1634
- unlinkSync4(this.socketPath);
1572
+ unlinkSync5(this.socketPath);
1635
1573
  } catch {
1636
1574
  }
1637
1575
  try {
1638
- unlinkSync4(this.pidPath);
1576
+ unlinkSync5(this.pidPath);
1639
1577
  } catch {
1640
1578
  }
1641
1579
  }
@@ -1686,7 +1624,7 @@ var EmbedClient = class {
1686
1624
  } catch (e) {
1687
1625
  if (this.isPidFileStale()) {
1688
1626
  try {
1689
- unlinkSync4(this.pidPath);
1627
+ unlinkSync5(this.pidPath);
1690
1628
  } catch {
1691
1629
  }
1692
1630
  try {
@@ -1699,11 +1637,11 @@ var EmbedClient = class {
1699
1637
  return;
1700
1638
  }
1701
1639
  }
1702
- if (!this.daemonEntry || !existsSync9(this.daemonEntry)) {
1640
+ if (!this.daemonEntry || !existsSync8(this.daemonEntry)) {
1703
1641
  log4(`daemonEntry not configured or missing: ${this.daemonEntry}`);
1704
1642
  try {
1705
1643
  closeSync4(fd);
1706
- unlinkSync4(this.pidPath);
1644
+ unlinkSync5(this.pidPath);
1707
1645
  } catch {
1708
1646
  }
1709
1647
  return;
@@ -1742,7 +1680,7 @@ var EmbedClient = class {
1742
1680
  while (Date.now() < deadline) {
1743
1681
  await sleep3(delay);
1744
1682
  delay = Math.min(delay * 1.5, 300);
1745
- if (!existsSync9(this.socketPath))
1683
+ if (!existsSync8(this.socketPath))
1746
1684
  continue;
1747
1685
  try {
1748
1686
  return await this.connectOnce();
@@ -1806,12 +1744,130 @@ function embeddingSqlLiteral(vec) {
1806
1744
  return `ARRAY[${parts.join(",")}]::float4[]`;
1807
1745
  }
1808
1746
 
1747
+ // dist/src/embeddings/disable.js
1748
+ import { createRequire as createRequire2 } from "node:module";
1749
+ import { homedir as homedir12 } from "node:os";
1750
+ import { join as join18 } from "node:path";
1751
+ import { pathToFileURL } from "node:url";
1752
+
1753
+ // dist/src/user-config.js
1754
+ import { existsSync as existsSync9, mkdirSync as mkdirSync10, readFileSync as readFileSync10, renameSync as renameSync5, writeFileSync as writeFileSync9 } from "node:fs";
1755
+ import { homedir as homedir11 } from "node:os";
1756
+ import { dirname as dirname5, join as join17 } from "node:path";
1757
+ var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join17(homedir11(), ".deeplake", "config.json");
1758
+ var _cache = null;
1759
+ var _migrated = false;
1760
+ function readUserConfig() {
1761
+ if (_cache !== null)
1762
+ return _cache;
1763
+ const path = _configPath();
1764
+ if (!existsSync9(path)) {
1765
+ _cache = {};
1766
+ return _cache;
1767
+ }
1768
+ try {
1769
+ const raw = readFileSync10(path, "utf-8");
1770
+ const parsed = JSON.parse(raw);
1771
+ _cache = isPlainObject(parsed) ? parsed : {};
1772
+ } catch {
1773
+ _cache = {};
1774
+ }
1775
+ return _cache;
1776
+ }
1777
+ function writeUserConfig(patch) {
1778
+ const current = readUserConfig();
1779
+ const merged = deepMerge(current, patch);
1780
+ const path = _configPath();
1781
+ const dir = dirname5(path);
1782
+ if (!existsSync9(dir))
1783
+ mkdirSync10(dir, { recursive: true });
1784
+ const tmp = `${path}.tmp.${process.pid}`;
1785
+ writeFileSync9(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1786
+ renameSync5(tmp, path);
1787
+ _cache = merged;
1788
+ return merged;
1789
+ }
1790
+ function getEmbeddingsEnabled() {
1791
+ const cfg = readUserConfig();
1792
+ if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
1793
+ return cfg.embeddings.enabled;
1794
+ }
1795
+ if (_migrated) {
1796
+ return migrationValueFromEnv();
1797
+ }
1798
+ _migrated = true;
1799
+ const enabled = migrationValueFromEnv();
1800
+ try {
1801
+ writeUserConfig({ embeddings: { enabled } });
1802
+ } catch {
1803
+ _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
1804
+ }
1805
+ return enabled;
1806
+ }
1807
+ function migrationValueFromEnv() {
1808
+ const raw = process.env.HIVEMIND_EMBEDDINGS;
1809
+ if (raw === void 0)
1810
+ return false;
1811
+ if (raw === "false")
1812
+ return false;
1813
+ return true;
1814
+ }
1815
+ function isPlainObject(value) {
1816
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1817
+ }
1818
+ function deepMerge(base, patch) {
1819
+ const out = { ...base };
1820
+ for (const key of Object.keys(patch)) {
1821
+ const patchVal = patch[key];
1822
+ const baseVal = base[key];
1823
+ if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
1824
+ out[key] = { ...baseVal, ...patchVal };
1825
+ } else if (patchVal !== void 0) {
1826
+ out[key] = patchVal;
1827
+ }
1828
+ }
1829
+ return out;
1830
+ }
1831
+
1832
+ // dist/src/embeddings/disable.js
1833
+ var cachedStatus = null;
1834
+ function defaultResolveTransformers() {
1835
+ const sharedDir = join18(homedir12(), ".hivemind", "embed-deps");
1836
+ try {
1837
+ createRequire2(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
1838
+ return;
1839
+ } catch {
1840
+ }
1841
+ createRequire2(import.meta.url).resolve("@huggingface/transformers");
1842
+ }
1843
+ var _resolve = defaultResolveTransformers;
1844
+ var _readEnabled = getEmbeddingsEnabled;
1845
+ function detectStatus() {
1846
+ if (!_readEnabled())
1847
+ return "user-disabled";
1848
+ try {
1849
+ _resolve();
1850
+ return "enabled";
1851
+ } catch {
1852
+ return "no-transformers";
1853
+ }
1854
+ }
1855
+ function embeddingsStatus() {
1856
+ if (cachedStatus !== null)
1857
+ return cachedStatus;
1858
+ cachedStatus = detectStatus();
1859
+ return cachedStatus;
1860
+ }
1861
+ function embeddingsDisabled() {
1862
+ return embeddingsStatus() !== "enabled";
1863
+ }
1864
+
1809
1865
  // dist/src/hooks/codex/stop.js
1810
1866
  var log5 = (msg) => log("codex-stop", msg);
1811
1867
  function resolveEmbedDaemonPath() {
1812
- return join17(dirname5(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1868
+ return join19(dirname6(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1813
1869
  }
1814
- var __bundleDir = dirname5(fileURLToPath3(import.meta.url));
1870
+ var __bundleDir = dirname6(fileURLToPath3(import.meta.url));
1815
1871
  var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".codex-plugin") ?? "";
1816
1872
  var CAPTURE = process.env.HIVEMIND_CAPTURE !== "false";
1817
1873
  async function main() {
@@ -1836,7 +1892,7 @@ async function main() {
1836
1892
  try {
1837
1893
  const transcriptPath = input.transcript_path;
1838
1894
  if (existsSync10(transcriptPath)) {
1839
- const transcript = readFileSync10(transcriptPath, "utf-8");
1895
+ const transcript = readFileSync11(transcriptPath, "utf-8");
1840
1896
  const lines = transcript.trim().split("\n").reverse();
1841
1897
  for (const line2 of lines) {
1842
1898
  try {