@deeplake/hivemind 0.7.32 → 0.7.33

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.
@@ -16,21 +16,21 @@ __export(index_marker_store_exports, {
16
16
  hasFreshIndexMarker: () => hasFreshIndexMarker,
17
17
  writeIndexMarker: () => writeIndexMarker
18
18
  });
19
- import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
20
- import { join as join3 } from "node:path";
19
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
20
+ import { join as join5 } from "node:path";
21
21
  import { tmpdir } from "node:os";
22
22
  function getIndexMarkerDir() {
23
- return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join3(tmpdir(), "hivemind-deeplake-indexes");
23
+ return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join5(tmpdir(), "hivemind-deeplake-indexes");
24
24
  }
25
25
  function buildIndexMarkerPath(workspaceId, orgId, table, suffix) {
26
26
  const markerKey = [workspaceId, orgId, table, suffix].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
27
- return join3(getIndexMarkerDir(), `${markerKey}.json`);
27
+ return join5(getIndexMarkerDir(), `${markerKey}.json`);
28
28
  }
29
29
  function hasFreshIndexMarker(markerPath) {
30
30
  if (!existsSync2(markerPath))
31
31
  return false;
32
32
  try {
33
- const raw = JSON.parse(readFileSync2(markerPath, "utf-8"));
33
+ const raw = JSON.parse(readFileSync4(markerPath, "utf-8"));
34
34
  const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
35
35
  if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
36
36
  return false;
@@ -40,8 +40,8 @@ function hasFreshIndexMarker(markerPath) {
40
40
  }
41
41
  }
42
42
  function writeIndexMarker(markerPath) {
43
- mkdirSync(getIndexMarkerDir(), { recursive: true });
44
- writeFileSync(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
43
+ mkdirSync3(getIndexMarkerDir(), { recursive: true });
44
+ writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
45
45
  }
46
46
  var INDEX_MARKER_TTL_MS;
47
47
  var init_index_marker_store = __esm({
@@ -146,6 +146,125 @@ function deeplakeClientHeader() {
146
146
  return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
147
147
  }
148
148
 
149
+ // dist/src/notifications/queue.js
150
+ import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync, openSync, closeSync, unlinkSync, statSync } from "node:fs";
151
+ import { join as join3, resolve } from "node:path";
152
+ import { homedir as homedir3 } from "node:os";
153
+ import { setTimeout as sleep } from "node:timers/promises";
154
+ var log2 = (msg) => log("notifications-queue", msg);
155
+ var LOCK_RETRY_MAX = 50;
156
+ var LOCK_RETRY_BASE_MS = 5;
157
+ var LOCK_STALE_MS = 5e3;
158
+ function queuePath() {
159
+ return join3(homedir3(), ".deeplake", "notifications-queue.json");
160
+ }
161
+ function lockPath() {
162
+ return `${queuePath()}.lock`;
163
+ }
164
+ function readQueue() {
165
+ try {
166
+ const raw = readFileSync2(queuePath(), "utf-8");
167
+ const parsed = JSON.parse(raw);
168
+ if (!parsed || !Array.isArray(parsed.queue)) {
169
+ log2(`queue malformed \u2192 treating as empty`);
170
+ return { queue: [] };
171
+ }
172
+ return { queue: parsed.queue };
173
+ } catch {
174
+ return { queue: [] };
175
+ }
176
+ }
177
+ function _isQueuePathInsideHome(path, home) {
178
+ const r = resolve(path);
179
+ const h = resolve(home);
180
+ return r.startsWith(h + "/") || r === h;
181
+ }
182
+ function writeQueue(q) {
183
+ const path = queuePath();
184
+ const home = resolve(homedir3());
185
+ if (!_isQueuePathInsideHome(path, home)) {
186
+ throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
187
+ }
188
+ mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
189
+ const tmp = `${path}.${process.pid}.tmp`;
190
+ writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
191
+ renameSync(tmp, path);
192
+ }
193
+ async function withQueueLock(fn) {
194
+ const path = lockPath();
195
+ mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
196
+ let fd = null;
197
+ for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
198
+ try {
199
+ fd = openSync(path, "wx", 384);
200
+ break;
201
+ } catch (e) {
202
+ const code = e.code;
203
+ if (code !== "EEXIST")
204
+ throw e;
205
+ try {
206
+ const age = Date.now() - statSync(path).mtimeMs;
207
+ if (age > LOCK_STALE_MS) {
208
+ unlinkSync(path);
209
+ continue;
210
+ }
211
+ } catch {
212
+ }
213
+ const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
214
+ await sleep(delay);
215
+ }
216
+ }
217
+ if (fd === null) {
218
+ log2(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
219
+ return fn();
220
+ }
221
+ try {
222
+ return fn();
223
+ } finally {
224
+ try {
225
+ closeSync(fd);
226
+ } catch {
227
+ }
228
+ try {
229
+ unlinkSync(path);
230
+ } catch {
231
+ }
232
+ }
233
+ }
234
+ function sameDedupKey(a, b) {
235
+ if (a.id !== b.id)
236
+ return false;
237
+ return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
238
+ }
239
+ async function enqueueNotification(n) {
240
+ await withQueueLock(() => {
241
+ const q = readQueue();
242
+ if (q.queue.some((existing) => sameDedupKey(existing, n))) {
243
+ return;
244
+ }
245
+ q.queue.push(n);
246
+ writeQueue(q);
247
+ });
248
+ }
249
+
250
+ // dist/src/commands/auth-creds.js
251
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "node:fs";
252
+ import { join as join4 } from "node:path";
253
+ import { homedir as homedir4 } from "node:os";
254
+ function configDir() {
255
+ return join4(homedir4(), ".deeplake");
256
+ }
257
+ function credsPath() {
258
+ return join4(configDir(), "credentials.json");
259
+ }
260
+ function loadCredentials() {
261
+ try {
262
+ return JSON.parse(readFileSync3(credsPath(), "utf-8"));
263
+ } catch {
264
+ return null;
265
+ }
266
+ }
267
+
149
268
  // dist/src/deeplake-api.js
150
269
  var indexMarkerStorePromise = null;
151
270
  function getIndexMarkerStore() {
@@ -153,7 +272,7 @@ function getIndexMarkerStore() {
153
272
  indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
154
273
  return indexMarkerStorePromise;
155
274
  }
156
- var log2 = (msg) => log("sdk", msg);
275
+ var log3 = (msg) => log("sdk", msg);
157
276
  function summarizeSql(sql, maxLen = 220) {
158
277
  const compact = sql.replace(/\s+/g, " ").trim();
159
278
  return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
@@ -165,7 +284,38 @@ function traceSql(msg) {
165
284
  process.stderr.write(`[deeplake-sql] ${msg}
166
285
  `);
167
286
  if (process.env.HIVEMIND_DEBUG === "1")
168
- log2(msg);
287
+ log3(msg);
288
+ }
289
+ var _signalledBalanceExhausted = false;
290
+ function maybeSignalBalanceExhausted(status, bodyText) {
291
+ if (status !== 402)
292
+ return;
293
+ if (!bodyText.includes("balance_cents"))
294
+ return;
295
+ if (_signalledBalanceExhausted)
296
+ return;
297
+ _signalledBalanceExhausted = true;
298
+ log3(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
299
+ enqueueNotification({
300
+ id: "balance-exhausted",
301
+ severity: "warn",
302
+ transient: true,
303
+ title: "Hivemind credits exhausted \u2014 top up to keep capturing",
304
+ body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
305
+ dedupKey: { reason: "balance-zero" }
306
+ }).catch((e) => {
307
+ log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
308
+ });
309
+ }
310
+ function billingUrl() {
311
+ try {
312
+ const c = loadCredentials();
313
+ if (c?.orgName && c?.workspaceId) {
314
+ return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
315
+ }
316
+ } catch {
317
+ }
318
+ return "https://deeplake.ai";
169
319
  }
170
320
  var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
171
321
  var MAX_RETRIES = 3;
@@ -174,7 +324,7 @@ var MAX_CONCURRENCY = 5;
174
324
  function getQueryTimeoutMs() {
175
325
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
176
326
  }
177
- function sleep(ms) {
327
+ function sleep2(ms) {
178
328
  return new Promise((resolve2) => setTimeout(resolve2, ms));
179
329
  }
180
330
  function isTimeoutError(error) {
@@ -276,8 +426,8 @@ var DeeplakeApi = class {
276
426
  lastError = e instanceof Error ? e : new Error(String(e));
277
427
  if (attempt < MAX_RETRIES) {
278
428
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
279
- log2(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
280
- await sleep(delay);
429
+ log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
430
+ await sleep2(delay);
281
431
  continue;
282
432
  }
283
433
  throw lastError;
@@ -293,10 +443,11 @@ var DeeplakeApi = class {
293
443
  const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
294
444
  if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
295
445
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
296
- log2(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
297
- await sleep(delay);
446
+ log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
447
+ await sleep2(delay);
298
448
  continue;
299
449
  }
450
+ maybeSignalBalanceExhausted(resp.status, text);
300
451
  throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
301
452
  }
302
453
  throw lastError ?? new Error("Query failed: max retries exceeded");
@@ -317,7 +468,7 @@ var DeeplakeApi = class {
317
468
  const chunk = rows.slice(i, i + CONCURRENCY);
318
469
  await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
319
470
  }
320
- log2(`commit: ${rows.length} rows`);
471
+ log3(`commit: ${rows.length} rows`);
321
472
  }
322
473
  async upsertRowSql(row) {
323
474
  const ts = (/* @__PURE__ */ new Date()).toISOString();
@@ -373,7 +524,7 @@ var DeeplakeApi = class {
373
524
  markers.writeIndexMarker(markerPath);
374
525
  return;
375
526
  }
376
- log2(`index "${indexName}" skipped: ${e.message}`);
527
+ log3(`index "${indexName}" skipped: ${e.message}`);
377
528
  }
378
529
  }
379
530
  /**
@@ -463,13 +614,13 @@ var DeeplakeApi = class {
463
614
  };
464
615
  }
465
616
  if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
466
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
617
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
467
618
  continue;
468
619
  }
469
620
  return { tables: [], cacheable: false };
470
621
  } catch {
471
622
  if (attempt < MAX_RETRIES) {
472
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt));
623
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
473
624
  continue;
474
625
  }
475
626
  return { tables: [], cacheable: false };
@@ -497,9 +648,9 @@ var DeeplakeApi = class {
497
648
  } catch (err) {
498
649
  lastErr = err;
499
650
  const msg = err instanceof Error ? err.message : String(err);
500
- log2(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
651
+ log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
501
652
  if (attempt < OUTER_BACKOFFS_MS.length) {
502
- await sleep(OUTER_BACKOFFS_MS[attempt]);
653
+ await sleep2(OUTER_BACKOFFS_MS[attempt]);
503
654
  }
504
655
  }
505
656
  }
@@ -510,9 +661,9 @@ var DeeplakeApi = class {
510
661
  const tbl = sqlIdent(name ?? this.tableName);
511
662
  const tables = await this.listTables();
512
663
  if (!tables.includes(tbl)) {
513
- log2(`table "${tbl}" not found, creating`);
664
+ log3(`table "${tbl}" not found, creating`);
514
665
  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);
515
- log2(`table "${tbl}" created`);
666
+ log3(`table "${tbl}" created`);
516
667
  if (!tables.includes(tbl))
517
668
  this._tablesCache = [...tables, tbl];
518
669
  }
@@ -525,9 +676,9 @@ var DeeplakeApi = class {
525
676
  const safe = sqlIdent(name);
526
677
  const tables = await this.listTables();
527
678
  if (!tables.includes(safe)) {
528
- log2(`table "${safe}" not found, creating`);
679
+ log3(`table "${safe}" not found, creating`);
529
680
  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);
530
- log2(`table "${safe}" created`);
681
+ log3(`table "${safe}" created`);
531
682
  if (!tables.includes(safe))
532
683
  this._tablesCache = [...tables, safe];
533
684
  }
@@ -550,9 +701,9 @@ var DeeplakeApi = class {
550
701
  const safe = sqlIdent(name);
551
702
  const tables = await this.listTables();
552
703
  if (!tables.includes(safe)) {
553
- log2(`table "${safe}" not found, creating`);
704
+ log3(`table "${safe}" not found, creating`);
554
705
  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);
555
- log2(`table "${safe}" created`);
706
+ log3(`table "${safe}" created`);
556
707
  if (!tables.includes(safe))
557
708
  this._tablesCache = [...tables, safe];
558
709
  }
@@ -569,9 +720,9 @@ function buildSessionPath(config, sessionId) {
569
720
  // dist/src/embeddings/client.js
570
721
  import { connect } from "node:net";
571
722
  import { spawn } from "node:child_process";
572
- import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as unlinkSync2, existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
573
- import { homedir as homedir6 } from "node:os";
574
- import { join as join7 } from "node:path";
723
+ import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as unlinkSync3, existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
724
+ import { homedir as homedir5 } from "node:os";
725
+ import { join as join6 } from "node:path";
575
726
 
576
727
  // dist/src/embeddings/protocol.js
577
728
  var DEFAULT_SOCKET_DIR = "/tmp";
@@ -584,233 +735,13 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
584
735
  return `${dir}/hivemind-embed-${uid}.pid`;
585
736
  }
586
737
 
587
- // dist/src/notifications/queue.js
588
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync } from "node:fs";
589
- import { join as join4, resolve } from "node:path";
590
- import { homedir as homedir3 } from "node:os";
591
- import { setTimeout as sleep2 } from "node:timers/promises";
592
- var log3 = (msg) => log("notifications-queue", msg);
593
- var LOCK_RETRY_MAX = 50;
594
- var LOCK_RETRY_BASE_MS = 5;
595
- var LOCK_STALE_MS = 5e3;
596
- function queuePath() {
597
- return join4(homedir3(), ".deeplake", "notifications-queue.json");
598
- }
599
- function lockPath() {
600
- return `${queuePath()}.lock`;
601
- }
602
- function readQueue() {
603
- try {
604
- const raw = readFileSync3(queuePath(), "utf-8");
605
- const parsed = JSON.parse(raw);
606
- if (!parsed || !Array.isArray(parsed.queue)) {
607
- log3(`queue malformed \u2192 treating as empty`);
608
- return { queue: [] };
609
- }
610
- return { queue: parsed.queue };
611
- } catch {
612
- return { queue: [] };
613
- }
614
- }
615
- function _isQueuePathInsideHome(path, home) {
616
- const r = resolve(path);
617
- const h = resolve(home);
618
- return r.startsWith(h + "/") || r === h;
619
- }
620
- function writeQueue(q) {
621
- const path = queuePath();
622
- const home = resolve(homedir3());
623
- if (!_isQueuePathInsideHome(path, home)) {
624
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
625
- }
626
- mkdirSync2(join4(home, ".deeplake"), { recursive: true, mode: 448 });
627
- const tmp = `${path}.${process.pid}.tmp`;
628
- writeFileSync2(tmp, JSON.stringify(q, null, 2), { mode: 384 });
629
- renameSync(tmp, path);
630
- }
631
- async function withQueueLock(fn) {
632
- const path = lockPath();
633
- mkdirSync2(join4(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
634
- let fd = null;
635
- for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
636
- try {
637
- fd = openSync(path, "wx", 384);
638
- break;
639
- } catch (e) {
640
- const code = e.code;
641
- if (code !== "EEXIST")
642
- throw e;
643
- try {
644
- const age = Date.now() - statSync(path).mtimeMs;
645
- if (age > LOCK_STALE_MS) {
646
- unlinkSync(path);
647
- continue;
648
- }
649
- } catch {
650
- }
651
- const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
652
- await sleep2(delay);
653
- }
654
- }
655
- if (fd === null) {
656
- log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
657
- return fn();
658
- }
659
- try {
660
- return fn();
661
- } finally {
662
- try {
663
- closeSync(fd);
664
- } catch {
665
- }
666
- try {
667
- unlinkSync(path);
668
- } catch {
669
- }
670
- }
671
- }
672
- function sameDedupKey(a, b) {
673
- if (a.id !== b.id)
674
- return false;
675
- return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
676
- }
677
- async function enqueueNotification(n) {
678
- await withQueueLock(() => {
679
- const q = readQueue();
680
- if (q.queue.some((existing) => sameDedupKey(existing, n))) {
681
- return;
682
- }
683
- q.queue.push(n);
684
- writeQueue(q);
685
- });
686
- }
687
-
688
- // dist/src/embeddings/disable.js
689
- import { createRequire } from "node:module";
690
- import { homedir as homedir5 } from "node:os";
691
- import { join as join6 } from "node:path";
692
- import { pathToFileURL } from "node:url";
693
-
694
- // dist/src/user-config.js
695
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
696
- import { homedir as homedir4 } from "node:os";
697
- import { dirname, join as join5 } from "node:path";
698
- var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join5(homedir4(), ".deeplake", "config.json");
699
- var _cache = null;
700
- var _migrated = false;
701
- function readUserConfig() {
702
- if (_cache !== null)
703
- return _cache;
704
- const path = _configPath();
705
- if (!existsSync3(path)) {
706
- _cache = {};
707
- return _cache;
708
- }
709
- try {
710
- const raw = readFileSync4(path, "utf-8");
711
- const parsed = JSON.parse(raw);
712
- _cache = isPlainObject(parsed) ? parsed : {};
713
- } catch {
714
- _cache = {};
715
- }
716
- return _cache;
717
- }
718
- function writeUserConfig(patch) {
719
- const current = readUserConfig();
720
- const merged = deepMerge(current, patch);
721
- const path = _configPath();
722
- const dir = dirname(path);
723
- if (!existsSync3(dir))
724
- mkdirSync3(dir, { recursive: true });
725
- const tmp = `${path}.tmp.${process.pid}`;
726
- writeFileSync3(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
727
- renameSync2(tmp, path);
728
- _cache = merged;
729
- return merged;
730
- }
731
- function getEmbeddingsEnabled() {
732
- const cfg = readUserConfig();
733
- if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
734
- return cfg.embeddings.enabled;
735
- }
736
- if (_migrated) {
737
- return migrationValueFromEnv();
738
- }
739
- _migrated = true;
740
- const enabled = migrationValueFromEnv();
741
- try {
742
- writeUserConfig({ embeddings: { enabled } });
743
- } catch {
744
- _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
745
- }
746
- return enabled;
747
- }
748
- function migrationValueFromEnv() {
749
- const raw = process.env.HIVEMIND_EMBEDDINGS;
750
- if (raw === void 0)
751
- return false;
752
- if (raw === "false")
753
- return false;
754
- return true;
755
- }
756
- function isPlainObject(value) {
757
- return typeof value === "object" && value !== null && !Array.isArray(value);
758
- }
759
- function deepMerge(base, patch) {
760
- const out = { ...base };
761
- for (const key of Object.keys(patch)) {
762
- const patchVal = patch[key];
763
- const baseVal = base[key];
764
- if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
765
- out[key] = { ...baseVal, ...patchVal };
766
- } else if (patchVal !== void 0) {
767
- out[key] = patchVal;
768
- }
769
- }
770
- return out;
771
- }
772
-
773
- // dist/src/embeddings/disable.js
774
- var cachedStatus = null;
775
- function defaultResolveTransformers() {
776
- const sharedDir = join6(homedir5(), ".hivemind", "embed-deps");
777
- try {
778
- createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
779
- return;
780
- } catch {
781
- }
782
- createRequire(import.meta.url).resolve("@huggingface/transformers");
783
- }
784
- var _resolve = defaultResolveTransformers;
785
- var _readEnabled = getEmbeddingsEnabled;
786
- function detectStatus() {
787
- if (!_readEnabled())
788
- return "user-disabled";
789
- try {
790
- _resolve();
791
- return "enabled";
792
- } catch {
793
- return "no-transformers";
794
- }
795
- }
796
- function embeddingsStatus() {
797
- if (cachedStatus !== null)
798
- return cachedStatus;
799
- cachedStatus = detectStatus();
800
- return cachedStatus;
801
- }
802
- function embeddingsDisabled() {
803
- return embeddingsStatus() !== "enabled";
804
- }
805
-
806
738
  // dist/src/embeddings/client.js
807
- var SHARED_DAEMON_PATH = join7(homedir6(), ".hivemind", "embed-deps", "embed-daemon.js");
739
+ var SHARED_DAEMON_PATH = join6(homedir5(), ".hivemind", "embed-deps", "embed-daemon.js");
808
740
  var log4 = (m) => log("embed-client", m);
809
741
  function getUid() {
810
742
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
811
743
  return uid !== void 0 ? String(uid) : process.env.USER ?? "default";
812
744
  }
813
- var _signalledMissingDeps = false;
814
745
  var _recycledStuckDaemon = false;
815
746
  var EmbedClient = class {
816
747
  socketPath;
@@ -827,7 +758,7 @@ var EmbedClient = class {
827
758
  this.socketPath = socketPathFor(uid, dir);
828
759
  this.pidPath = pidPathFor(uid, dir);
829
760
  this.timeoutMs = opts.timeoutMs ?? DEFAULT_CLIENT_TIMEOUT_MS;
830
- this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync4(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
761
+ this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync3(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
831
762
  this.autoSpawn = opts.autoSpawn ?? true;
832
763
  this.spawnWaitMs = opts.spawnWaitMs ?? 5e3;
833
764
  }
@@ -908,7 +839,7 @@ var EmbedClient = class {
908
839
  async waitForDaemonReady() {
909
840
  const deadline = Date.now() + this.spawnWaitMs;
910
841
  while (Date.now() < deadline) {
911
- if (existsSync4(this.socketPath))
842
+ if (existsSync3(this.socketPath))
912
843
  return;
913
844
  await new Promise((r) => setTimeout(r, 50));
914
845
  }
@@ -951,7 +882,7 @@ var EmbedClient = class {
951
882
  this.recycleDaemon(hello.pid);
952
883
  return true;
953
884
  }
954
- if (hello.daemonPath !== this.daemonEntry && !existsSync4(hello.daemonPath)) {
885
+ if (hello.daemonPath !== this.daemonEntry && !existsSync3(hello.daemonPath)) {
955
886
  _recycledStuckDaemon = true;
956
887
  log4(`daemon path no longer on disk \u2014 running=${hello.daemonPath} (gone) expected=${this.daemonEntry}; recycling`);
957
888
  this.recycleDaemon(hello.pid);
@@ -963,37 +894,21 @@ var EmbedClient = class {
963
894
  /**
964
895
  * On a transformers-missing error from the daemon, SIGTERM the stuck
965
896
  * daemon (the bundle daemon that can't find its deps) and clear
966
- * sock/pid so the next call spawns fresh. Also enqueue a one-time
967
- * notification telling the user to run `hivemind embeddings install`
968
- * but only when the user has opted in. Suppressed when
969
- * embeddingsStatus() === "user-disabled" so we don't nag users who
970
- * explicitly chose to turn embeddings off.
897
+ * sock/pid so the next call spawns fresh.
898
+ *
899
+ * Previously this also enqueued a user-visible "Hivemind embeddings
900
+ * disabled deps missing" notification telling the user to run
901
+ * `hivemind embeddings install`. The notification was removed because
902
+ * (a) the recycle alone often fixes the issue silently, and (b) the
903
+ * warning kept stacking on top of the primary session-start banner
904
+ * which clashed with the single-slot priority model. The `detail`
905
+ * argument is retained for future telemetry / debug logging.
971
906
  */
972
- handleTransformersMissing(detail) {
907
+ handleTransformersMissing(_detail) {
973
908
  if (!_recycledStuckDaemon) {
974
909
  _recycledStuckDaemon = true;
975
910
  this.recycleDaemon(null);
976
911
  }
977
- if (_signalledMissingDeps)
978
- return;
979
- _signalledMissingDeps = true;
980
- let status;
981
- try {
982
- status = embeddingsStatus();
983
- } catch {
984
- status = "enabled";
985
- }
986
- if (status === "user-disabled")
987
- return;
988
- enqueueNotification({
989
- id: "embed-deps-missing",
990
- severity: "warn",
991
- title: "Hivemind embeddings disabled \u2014 deps missing",
992
- body: `Semantic memory search is off because @huggingface/transformers is not installed where the daemon can find it. Run \`hivemind embeddings install\` to enable.`,
993
- dedupKey: { reason: "transformers-missing", detail: detail.slice(0, 200) }
994
- }).catch((e) => {
995
- log4(`enqueue embed-deps-missing failed: ${e instanceof Error ? e.message : String(e)}`);
996
- });
997
912
  }
998
913
  /**
999
914
  * Best-effort SIGTERM + sock/pid cleanup. Tolerant of every missing-file
@@ -1016,7 +931,7 @@ var EmbedClient = class {
1016
931
  } catch {
1017
932
  }
1018
933
  }
1019
- if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync4(this.socketPath)) {
934
+ if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync3(this.socketPath)) {
1020
935
  try {
1021
936
  process.kill(pid, "SIGTERM");
1022
937
  } catch {
@@ -1025,11 +940,11 @@ var EmbedClient = class {
1025
940
  log4(`recycle: socket gone, skipping SIGTERM on possibly-stale pid ${pid}`);
1026
941
  }
1027
942
  try {
1028
- unlinkSync2(this.socketPath);
943
+ unlinkSync3(this.socketPath);
1029
944
  } catch {
1030
945
  }
1031
946
  try {
1032
- unlinkSync2(this.pidPath);
947
+ unlinkSync3(this.pidPath);
1033
948
  } catch {
1034
949
  }
1035
950
  }
@@ -1080,7 +995,7 @@ var EmbedClient = class {
1080
995
  } catch (e) {
1081
996
  if (this.isPidFileStale()) {
1082
997
  try {
1083
- unlinkSync2(this.pidPath);
998
+ unlinkSync3(this.pidPath);
1084
999
  } catch {
1085
1000
  }
1086
1001
  try {
@@ -1093,11 +1008,11 @@ var EmbedClient = class {
1093
1008
  return;
1094
1009
  }
1095
1010
  }
1096
- if (!this.daemonEntry || !existsSync4(this.daemonEntry)) {
1011
+ if (!this.daemonEntry || !existsSync3(this.daemonEntry)) {
1097
1012
  log4(`daemonEntry not configured or missing: ${this.daemonEntry}`);
1098
1013
  try {
1099
1014
  closeSync2(fd);
1100
- unlinkSync2(this.pidPath);
1015
+ unlinkSync3(this.pidPath);
1101
1016
  } catch {
1102
1017
  }
1103
1018
  return;
@@ -1136,7 +1051,7 @@ var EmbedClient = class {
1136
1051
  while (Date.now() < deadline) {
1137
1052
  await sleep3(delay);
1138
1053
  delay = Math.min(delay * 1.5, 300);
1139
- if (!existsSync4(this.socketPath))
1054
+ if (!existsSync3(this.socketPath))
1140
1055
  continue;
1141
1056
  try {
1142
1057
  return await this.connectOnce();
@@ -1200,17 +1115,135 @@ function embeddingSqlLiteral(vec) {
1200
1115
  return `ARRAY[${parts.join(",")}]::float4[]`;
1201
1116
  }
1202
1117
 
1203
- // dist/src/embeddings/self-heal.js
1204
- import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync4, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
1118
+ // dist/src/embeddings/disable.js
1119
+ import { createRequire } from "node:module";
1205
1120
  import { homedir as homedir7 } from "node:os";
1206
- import { basename, dirname as dirname2, join as join8 } from "node:path";
1121
+ import { join as join8 } from "node:path";
1122
+ import { pathToFileURL } from "node:url";
1123
+
1124
+ // dist/src/user-config.js
1125
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
1126
+ import { homedir as homedir6 } from "node:os";
1127
+ import { dirname, join as join7 } from "node:path";
1128
+ var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join7(homedir6(), ".deeplake", "config.json");
1129
+ var _cache = null;
1130
+ var _migrated = false;
1131
+ function readUserConfig() {
1132
+ if (_cache !== null)
1133
+ return _cache;
1134
+ const path = _configPath();
1135
+ if (!existsSync4(path)) {
1136
+ _cache = {};
1137
+ return _cache;
1138
+ }
1139
+ try {
1140
+ const raw = readFileSync6(path, "utf-8");
1141
+ const parsed = JSON.parse(raw);
1142
+ _cache = isPlainObject(parsed) ? parsed : {};
1143
+ } catch {
1144
+ _cache = {};
1145
+ }
1146
+ return _cache;
1147
+ }
1148
+ function writeUserConfig(patch) {
1149
+ const current = readUserConfig();
1150
+ const merged = deepMerge(current, patch);
1151
+ const path = _configPath();
1152
+ const dir = dirname(path);
1153
+ if (!existsSync4(dir))
1154
+ mkdirSync4(dir, { recursive: true });
1155
+ const tmp = `${path}.tmp.${process.pid}`;
1156
+ writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1157
+ renameSync2(tmp, path);
1158
+ _cache = merged;
1159
+ return merged;
1160
+ }
1161
+ function getEmbeddingsEnabled() {
1162
+ const cfg = readUserConfig();
1163
+ if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
1164
+ return cfg.embeddings.enabled;
1165
+ }
1166
+ if (_migrated) {
1167
+ return migrationValueFromEnv();
1168
+ }
1169
+ _migrated = true;
1170
+ const enabled = migrationValueFromEnv();
1171
+ try {
1172
+ writeUserConfig({ embeddings: { enabled } });
1173
+ } catch {
1174
+ _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
1175
+ }
1176
+ return enabled;
1177
+ }
1178
+ function migrationValueFromEnv() {
1179
+ const raw = process.env.HIVEMIND_EMBEDDINGS;
1180
+ if (raw === void 0)
1181
+ return false;
1182
+ if (raw === "false")
1183
+ return false;
1184
+ return true;
1185
+ }
1186
+ function isPlainObject(value) {
1187
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1188
+ }
1189
+ function deepMerge(base, patch) {
1190
+ const out = { ...base };
1191
+ for (const key of Object.keys(patch)) {
1192
+ const patchVal = patch[key];
1193
+ const baseVal = base[key];
1194
+ if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
1195
+ out[key] = { ...baseVal, ...patchVal };
1196
+ } else if (patchVal !== void 0) {
1197
+ out[key] = patchVal;
1198
+ }
1199
+ }
1200
+ return out;
1201
+ }
1202
+
1203
+ // dist/src/embeddings/disable.js
1204
+ var cachedStatus = null;
1205
+ function defaultResolveTransformers() {
1206
+ const sharedDir = join8(homedir7(), ".hivemind", "embed-deps");
1207
+ try {
1208
+ createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
1209
+ return;
1210
+ } catch {
1211
+ }
1212
+ createRequire(import.meta.url).resolve("@huggingface/transformers");
1213
+ }
1214
+ var _resolve = defaultResolveTransformers;
1215
+ var _readEnabled = getEmbeddingsEnabled;
1216
+ function detectStatus() {
1217
+ if (!_readEnabled())
1218
+ return "user-disabled";
1219
+ try {
1220
+ _resolve();
1221
+ return "enabled";
1222
+ } catch {
1223
+ return "no-transformers";
1224
+ }
1225
+ }
1226
+ function embeddingsStatus() {
1227
+ if (cachedStatus !== null)
1228
+ return cachedStatus;
1229
+ cachedStatus = detectStatus();
1230
+ return cachedStatus;
1231
+ }
1232
+ function embeddingsDisabled() {
1233
+ return embeddingsStatus() !== "enabled";
1234
+ }
1235
+
1236
+ // dist/src/embeddings/self-heal.js
1237
+ import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
1238
+ import { homedir as homedir8 } from "node:os";
1239
+ import { basename, dirname as dirname2, join as join9 } from "node:path";
1207
1240
  function ensurePluginNodeModulesLink(opts) {
1208
1241
  if (basename(opts.bundleDir) !== "bundle") {
1209
1242
  return { kind: "not-bundle-layout", bundleDir: opts.bundleDir };
1210
1243
  }
1211
- const target = opts.sharedNodeModules ?? join8(homedir7(), ".hivemind", "embed-deps", "node_modules");
1244
+ const target = opts.sharedNodeModules ?? join9(homedir8(), ".hivemind", "embed-deps", "node_modules");
1212
1245
  const pluginDir = dirname2(opts.bundleDir);
1213
- const link = join8(pluginDir, "node_modules");
1246
+ const link = join9(pluginDir, "node_modules");
1214
1247
  if (!existsSync5(target)) {
1215
1248
  return { kind: "shared-deps-missing", target };
1216
1249
  }
@@ -1251,7 +1284,7 @@ function createSymlinkAtomic(target, link) {
1251
1284
  try {
1252
1285
  const parent = dirname2(link);
1253
1286
  if (!existsSync5(parent))
1254
- mkdirSync4(parent, { recursive: true });
1287
+ mkdirSync5(parent, { recursive: true });
1255
1288
  const tmp = `${link}.tmp.${process.pid}`;
1256
1289
  try {
1257
1290
  rmSync(tmp, { force: true });
@@ -1267,40 +1300,40 @@ function createSymlinkAtomic(target, link) {
1267
1300
 
1268
1301
  // dist/src/hooks/hermes/capture.js
1269
1302
  import { fileURLToPath as fileURLToPath3 } from "node:url";
1270
- import { dirname as dirname6, join as join18 } from "node:path";
1303
+ import { dirname as dirname6, join as join19 } from "node:path";
1271
1304
 
1272
1305
  // dist/src/hooks/summary-state.js
1273
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, writeSync as writeSync2, mkdirSync as mkdirSync5, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync3, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1274
- import { homedir as homedir8 } from "node:os";
1275
- import { join as join9 } from "node:path";
1306
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3 } from "node:fs";
1307
+ import { homedir as homedir9 } from "node:os";
1308
+ import { join as join10 } from "node:path";
1276
1309
  var dlog = (msg) => log("summary-state", msg);
1277
- var STATE_DIR = join9(homedir8(), ".claude", "hooks", "summary-state");
1310
+ var STATE_DIR = join10(homedir9(), ".claude", "hooks", "summary-state");
1278
1311
  var YIELD_BUF = new Int32Array(new SharedArrayBuffer(4));
1279
1312
  function statePath(sessionId) {
1280
- return join9(STATE_DIR, `${sessionId}.json`);
1313
+ return join10(STATE_DIR, `${sessionId}.json`);
1281
1314
  }
1282
1315
  function lockPath2(sessionId) {
1283
- return join9(STATE_DIR, `${sessionId}.lock`);
1316
+ return join10(STATE_DIR, `${sessionId}.lock`);
1284
1317
  }
1285
1318
  function readState(sessionId) {
1286
1319
  const p = statePath(sessionId);
1287
1320
  if (!existsSync6(p))
1288
1321
  return null;
1289
1322
  try {
1290
- return JSON.parse(readFileSync6(p, "utf-8"));
1323
+ return JSON.parse(readFileSync7(p, "utf-8"));
1291
1324
  } catch {
1292
1325
  return null;
1293
1326
  }
1294
1327
  }
1295
1328
  function writeState(sessionId, state) {
1296
- mkdirSync5(STATE_DIR, { recursive: true });
1329
+ mkdirSync6(STATE_DIR, { recursive: true });
1297
1330
  const p = statePath(sessionId);
1298
1331
  const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
1299
- writeFileSync4(tmp, JSON.stringify(state));
1332
+ writeFileSync5(tmp, JSON.stringify(state));
1300
1333
  renameSync4(tmp, p);
1301
1334
  }
1302
1335
  function withRmwLock(sessionId, fn) {
1303
- mkdirSync5(STATE_DIR, { recursive: true });
1336
+ mkdirSync6(STATE_DIR, { recursive: true });
1304
1337
  const rmwLock = statePath(sessionId) + ".rmw";
1305
1338
  const deadline = Date.now() + 2e3;
1306
1339
  let fd = null;
@@ -1313,7 +1346,7 @@ function withRmwLock(sessionId, fn) {
1313
1346
  if (Date.now() > deadline) {
1314
1347
  dlog(`rmw lock deadline exceeded for ${sessionId}, reclaiming stale lock`);
1315
1348
  try {
1316
- unlinkSync3(rmwLock);
1349
+ unlinkSync4(rmwLock);
1317
1350
  } catch (unlinkErr) {
1318
1351
  dlog(`stale rmw lock unlink failed for ${sessionId}: ${unlinkErr.message}`);
1319
1352
  }
@@ -1327,7 +1360,7 @@ function withRmwLock(sessionId, fn) {
1327
1360
  } finally {
1328
1361
  closeSync3(fd);
1329
1362
  try {
1330
- unlinkSync3(rmwLock);
1363
+ unlinkSync4(rmwLock);
1331
1364
  } catch (unlinkErr) {
1332
1365
  dlog(`rmw lock cleanup failed for ${sessionId}: ${unlinkErr.message}`);
1333
1366
  }
@@ -1362,18 +1395,18 @@ function shouldTrigger(state, cfg, now = Date.now()) {
1362
1395
  return false;
1363
1396
  }
1364
1397
  function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1365
- mkdirSync5(STATE_DIR, { recursive: true });
1398
+ mkdirSync6(STATE_DIR, { recursive: true });
1366
1399
  const p = lockPath2(sessionId);
1367
1400
  if (existsSync6(p)) {
1368
1401
  try {
1369
- const ageMs = Date.now() - parseInt(readFileSync6(p, "utf-8"), 10);
1402
+ const ageMs = Date.now() - parseInt(readFileSync7(p, "utf-8"), 10);
1370
1403
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
1371
1404
  return false;
1372
1405
  } catch (readErr) {
1373
1406
  dlog(`lock file unreadable for ${sessionId}, treating as stale: ${readErr.message}`);
1374
1407
  }
1375
1408
  try {
1376
- unlinkSync3(p);
1409
+ unlinkSync4(p);
1377
1410
  } catch (unlinkErr) {
1378
1411
  dlog(`could not unlink stale lock for ${sessionId}: ${unlinkErr.message}`);
1379
1412
  return false;
@@ -1395,7 +1428,7 @@ function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1395
1428
  }
1396
1429
  function releaseLock(sessionId) {
1397
1430
  try {
1398
- unlinkSync3(lockPath2(sessionId));
1431
+ unlinkSync4(lockPath2(sessionId));
1399
1432
  } catch (e) {
1400
1433
  if (e?.code !== "ENOENT") {
1401
1434
  dlog(`releaseLock unlink failed for ${sessionId}: ${e.message}`);
@@ -1406,20 +1439,20 @@ function releaseLock(sessionId) {
1406
1439
  // dist/src/hooks/hermes/spawn-wiki-worker.js
1407
1440
  import { spawn as spawn2, execSync } from "node:child_process";
1408
1441
  import { fileURLToPath } from "node:url";
1409
- import { dirname as dirname4, join as join12 } from "node:path";
1410
- import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "node:fs";
1411
- import { homedir as homedir9, tmpdir as tmpdir2 } from "node:os";
1442
+ import { dirname as dirname4, join as join13 } from "node:path";
1443
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "node:fs";
1444
+ import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
1412
1445
 
1413
1446
  // dist/src/utils/wiki-log.js
1414
- import { mkdirSync as mkdirSync6, appendFileSync as appendFileSync2 } from "node:fs";
1415
- import { join as join10 } from "node:path";
1447
+ import { mkdirSync as mkdirSync7, appendFileSync as appendFileSync2 } from "node:fs";
1448
+ import { join as join11 } from "node:path";
1416
1449
  function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1417
- const path = join10(hooksDir, filename);
1450
+ const path = join11(hooksDir, filename);
1418
1451
  return {
1419
1452
  path,
1420
1453
  log(msg) {
1421
1454
  try {
1422
- mkdirSync6(hooksDir, { recursive: true });
1455
+ mkdirSync7(hooksDir, { recursive: true });
1423
1456
  appendFileSync2(path, `[${utcTimestamp()}] ${msg}
1424
1457
  `);
1425
1458
  } catch {
@@ -1429,18 +1462,18 @@ function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1429
1462
  }
1430
1463
 
1431
1464
  // dist/src/utils/version-check.js
1432
- import { readFileSync as readFileSync7 } from "node:fs";
1433
- import { dirname as dirname3, join as join11 } from "node:path";
1465
+ import { readFileSync as readFileSync8 } from "node:fs";
1466
+ import { dirname as dirname3, join as join12 } from "node:path";
1434
1467
  function getInstalledVersion(bundleDir, pluginManifestDir) {
1435
1468
  try {
1436
- const pluginJson = join11(bundleDir, "..", pluginManifestDir, "plugin.json");
1437
- const plugin = JSON.parse(readFileSync7(pluginJson, "utf-8"));
1469
+ const pluginJson = join12(bundleDir, "..", pluginManifestDir, "plugin.json");
1470
+ const plugin = JSON.parse(readFileSync8(pluginJson, "utf-8"));
1438
1471
  if (plugin.version)
1439
1472
  return plugin.version;
1440
1473
  } catch {
1441
1474
  }
1442
1475
  try {
1443
- const stamp = readFileSync7(join11(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
1476
+ const stamp = readFileSync8(join12(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
1444
1477
  if (stamp)
1445
1478
  return stamp;
1446
1479
  } catch {
@@ -1455,9 +1488,9 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
1455
1488
  ]);
1456
1489
  let dir = bundleDir;
1457
1490
  for (let i = 0; i < 5; i++) {
1458
- const candidate = join11(dir, "package.json");
1491
+ const candidate = join12(dir, "package.json");
1459
1492
  try {
1460
- const pkg = JSON.parse(readFileSync7(candidate, "utf-8"));
1493
+ const pkg = JSON.parse(readFileSync8(candidate, "utf-8"));
1461
1494
  if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
1462
1495
  return pkg.version;
1463
1496
  } catch {
@@ -1471,8 +1504,8 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
1471
1504
  }
1472
1505
 
1473
1506
  // dist/src/hooks/hermes/spawn-wiki-worker.js
1474
- var HOME = homedir9();
1475
- var wikiLogger = makeWikiLogger(join12(HOME, ".hermes", "hooks"));
1507
+ var HOME = homedir10();
1508
+ var wikiLogger = makeWikiLogger(join13(HOME, ".hermes", "hooks"));
1476
1509
  var WIKI_LOG = wikiLogger.path;
1477
1510
  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.
1478
1511
 
@@ -1534,11 +1567,11 @@ function findHermesBin() {
1534
1567
  function spawnHermesWikiWorker(opts) {
1535
1568
  const { config, sessionId, cwd, bundleDir, reason } = opts;
1536
1569
  const projectName = cwd.split("/").pop() || "unknown";
1537
- const tmpDir = join12(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
1538
- mkdirSync7(tmpDir, { recursive: true });
1570
+ const tmpDir = join13(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
1571
+ mkdirSync8(tmpDir, { recursive: true });
1539
1572
  const pluginVersion = getInstalledVersion(bundleDir, ".claude-plugin") ?? "";
1540
- const configFile = join12(tmpDir, "config.json");
1541
- writeFileSync5(configFile, JSON.stringify({
1573
+ const configFile = join13(tmpDir, "config.json");
1574
+ writeFileSync6(configFile, JSON.stringify({
1542
1575
  apiUrl: config.apiUrl,
1543
1576
  token: config.token,
1544
1577
  orgId: config.orgId,
@@ -1554,11 +1587,11 @@ function spawnHermesWikiWorker(opts) {
1554
1587
  hermesProvider: process.env.HIVEMIND_HERMES_PROVIDER ?? "openrouter",
1555
1588
  hermesModel: process.env.HIVEMIND_HERMES_MODEL ?? "anthropic/claude-haiku-4-5",
1556
1589
  wikiLog: WIKI_LOG,
1557
- hooksDir: join12(HOME, ".hermes", "hooks"),
1590
+ hooksDir: join13(HOME, ".hermes", "hooks"),
1558
1591
  promptTemplate: WIKI_PROMPT_TEMPLATE
1559
1592
  }));
1560
1593
  wikiLog(`${reason}: spawning summary worker for ${sessionId}`);
1561
- const workerPath = join12(bundleDir, "wiki-worker.js");
1594
+ const workerPath = join13(bundleDir, "wiki-worker.js");
1562
1595
  spawn2("nohup", ["node", workerPath, configFile], {
1563
1596
  detached: true,
1564
1597
  stdio: ["ignore", "ignore", "ignore"]
@@ -1572,15 +1605,15 @@ function bundleDirFromImportMeta(importMetaUrl) {
1572
1605
  // dist/src/skillify/spawn-skillify-worker.js
1573
1606
  import { spawn as spawn3 } from "node:child_process";
1574
1607
  import { fileURLToPath as fileURLToPath2 } from "node:url";
1575
- import { dirname as dirname5, join as join14 } from "node:path";
1576
- import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
1577
- import { homedir as homedir11, tmpdir as tmpdir3 } from "node:os";
1608
+ import { dirname as dirname5, join as join15 } from "node:path";
1609
+ import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, chmodSync } from "node:fs";
1610
+ import { homedir as homedir12, tmpdir as tmpdir3 } from "node:os";
1578
1611
 
1579
1612
  // dist/src/skillify/gate-runner.js
1580
1613
  import { existsSync as existsSync7 } from "node:fs";
1581
1614
  import { createRequire as createRequire2 } from "node:module";
1582
- import { homedir as homedir10 } from "node:os";
1583
- import { join as join13 } from "node:path";
1615
+ import { homedir as homedir11 } from "node:os";
1616
+ import { join as join14 } from "node:path";
1584
1617
  var requireForCp = createRequire2(import.meta.url);
1585
1618
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
1586
1619
  var inheritedEnv = process;
@@ -1592,7 +1625,7 @@ function firstExistingPath(candidates) {
1592
1625
  return null;
1593
1626
  }
1594
1627
  function findAgentBin(agent) {
1595
- const home = homedir10();
1628
+ const home = homedir11();
1596
1629
  switch (agent) {
1597
1630
  // /usr/bin/<name> is included in every candidate list — that's the
1598
1631
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -1601,54 +1634,54 @@ function findAgentBin(agent) {
1601
1634
  // #170 caught the gap.
1602
1635
  case "claude_code":
1603
1636
  return firstExistingPath([
1604
- join13(home, ".claude", "local", "claude"),
1637
+ join14(home, ".claude", "local", "claude"),
1605
1638
  "/usr/local/bin/claude",
1606
1639
  "/usr/bin/claude",
1607
- join13(home, ".npm-global", "bin", "claude"),
1608
- join13(home, ".local", "bin", "claude"),
1640
+ join14(home, ".npm-global", "bin", "claude"),
1641
+ join14(home, ".local", "bin", "claude"),
1609
1642
  "/opt/homebrew/bin/claude"
1610
- ]) ?? join13(home, ".claude", "local", "claude");
1643
+ ]) ?? join14(home, ".claude", "local", "claude");
1611
1644
  case "codex":
1612
1645
  return firstExistingPath([
1613
1646
  "/usr/local/bin/codex",
1614
1647
  "/usr/bin/codex",
1615
- join13(home, ".npm-global", "bin", "codex"),
1616
- join13(home, ".local", "bin", "codex"),
1648
+ join14(home, ".npm-global", "bin", "codex"),
1649
+ join14(home, ".local", "bin", "codex"),
1617
1650
  "/opt/homebrew/bin/codex"
1618
1651
  ]) ?? "/usr/local/bin/codex";
1619
1652
  case "cursor":
1620
1653
  return firstExistingPath([
1621
1654
  "/usr/local/bin/cursor-agent",
1622
1655
  "/usr/bin/cursor-agent",
1623
- join13(home, ".npm-global", "bin", "cursor-agent"),
1624
- join13(home, ".local", "bin", "cursor-agent"),
1656
+ join14(home, ".npm-global", "bin", "cursor-agent"),
1657
+ join14(home, ".local", "bin", "cursor-agent"),
1625
1658
  "/opt/homebrew/bin/cursor-agent"
1626
1659
  ]) ?? "/usr/local/bin/cursor-agent";
1627
1660
  case "hermes":
1628
1661
  return firstExistingPath([
1629
- join13(home, ".local", "bin", "hermes"),
1662
+ join14(home, ".local", "bin", "hermes"),
1630
1663
  "/usr/local/bin/hermes",
1631
1664
  "/usr/bin/hermes",
1632
- join13(home, ".npm-global", "bin", "hermes"),
1665
+ join14(home, ".npm-global", "bin", "hermes"),
1633
1666
  "/opt/homebrew/bin/hermes"
1634
- ]) ?? join13(home, ".local", "bin", "hermes");
1667
+ ]) ?? join14(home, ".local", "bin", "hermes");
1635
1668
  case "pi":
1636
1669
  return firstExistingPath([
1637
- join13(home, ".local", "bin", "pi"),
1670
+ join14(home, ".local", "bin", "pi"),
1638
1671
  "/usr/local/bin/pi",
1639
1672
  "/usr/bin/pi",
1640
- join13(home, ".npm-global", "bin", "pi"),
1673
+ join14(home, ".npm-global", "bin", "pi"),
1641
1674
  "/opt/homebrew/bin/pi"
1642
- ]) ?? join13(home, ".local", "bin", "pi");
1675
+ ]) ?? join14(home, ".local", "bin", "pi");
1643
1676
  }
1644
1677
  }
1645
1678
 
1646
1679
  // dist/src/skillify/spawn-skillify-worker.js
1647
- var HOME2 = homedir11();
1648
- var SKILLIFY_LOG = join14(HOME2, ".claude", "hooks", "skillify.log");
1680
+ var HOME2 = homedir12();
1681
+ var SKILLIFY_LOG = join15(HOME2, ".claude", "hooks", "skillify.log");
1649
1682
  function skillifyLog(msg) {
1650
1683
  try {
1651
- mkdirSync8(dirname5(SKILLIFY_LOG), { recursive: true });
1684
+ mkdirSync9(dirname5(SKILLIFY_LOG), { recursive: true });
1652
1685
  appendFileSync3(SKILLIFY_LOG, `[${utcTimestamp()}] ${msg}
1653
1686
  `);
1654
1687
  } catch {
@@ -1656,11 +1689,11 @@ function skillifyLog(msg) {
1656
1689
  }
1657
1690
  function spawnSkillifyWorker(opts) {
1658
1691
  const { config, cwd, projectKey, project, bundleDir, agent, scopeConfig, currentSessionId, reason } = opts;
1659
- const tmpDir = join14(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
1660
- mkdirSync8(tmpDir, { recursive: true, mode: 448 });
1692
+ const tmpDir = join15(tmpdir3(), `deeplake-skillify-${projectKey}-${Date.now()}`);
1693
+ mkdirSync9(tmpDir, { recursive: true, mode: 448 });
1661
1694
  const gateBin = findAgentBin(agent);
1662
- const configFile = join14(tmpDir, "config.json");
1663
- writeFileSync6(configFile, JSON.stringify({
1695
+ const configFile = join15(tmpDir, "config.json");
1696
+ writeFileSync7(configFile, JSON.stringify({
1664
1697
  apiUrl: config.apiUrl,
1665
1698
  token: config.token,
1666
1699
  orgId: config.orgId,
@@ -1690,7 +1723,7 @@ function spawnSkillifyWorker(opts) {
1690
1723
  } catch {
1691
1724
  }
1692
1725
  skillifyLog(`${reason}: spawning skillify worker for project=${project} key=${projectKey}`);
1693
- const workerPath = join14(bundleDir, "skillify-worker.js");
1726
+ const workerPath = join15(bundleDir, "skillify-worker.js");
1694
1727
  spawn3("nohup", ["node", workerPath, configFile], {
1695
1728
  detached: true,
1696
1729
  stdio: ["ignore", "ignore", "ignore"]
@@ -1699,25 +1732,25 @@ function spawnSkillifyWorker(opts) {
1699
1732
  }
1700
1733
 
1701
1734
  // dist/src/skillify/state.js
1702
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync7, writeSync as writeSync3, mkdirSync as mkdirSync9, renameSync as renameSync6, existsSync as existsSync9, unlinkSync as unlinkSync4, openSync as openSync4, closeSync as closeSync4 } from "node:fs";
1735
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync8, writeSync as writeSync3, mkdirSync as mkdirSync10, renameSync as renameSync6, existsSync as existsSync9, unlinkSync as unlinkSync5, openSync as openSync4, closeSync as closeSync4 } from "node:fs";
1703
1736
  import { execSync as execSync2 } from "node:child_process";
1704
- import { homedir as homedir13 } from "node:os";
1737
+ import { homedir as homedir14 } from "node:os";
1705
1738
  import { createHash } from "node:crypto";
1706
- import { join as join16, basename as basename2 } from "node:path";
1739
+ import { join as join17, basename as basename2 } from "node:path";
1707
1740
 
1708
1741
  // dist/src/skillify/legacy-migration.js
1709
1742
  import { existsSync as existsSync8, renameSync as renameSync5 } from "node:fs";
1710
- import { homedir as homedir12 } from "node:os";
1711
- import { join as join15 } from "node:path";
1743
+ import { homedir as homedir13 } from "node:os";
1744
+ import { join as join16 } from "node:path";
1712
1745
  var dlog2 = (msg) => log("skillify-migrate", msg);
1713
1746
  var attempted = false;
1714
1747
  function migrateLegacyStateDir() {
1715
1748
  if (attempted)
1716
1749
  return;
1717
1750
  attempted = true;
1718
- const root = join15(homedir12(), ".deeplake", "state");
1719
- const legacy = join15(root, "skilify");
1720
- const current = join15(root, "skillify");
1751
+ const root = join16(homedir13(), ".deeplake", "state");
1752
+ const legacy = join16(root, "skilify");
1753
+ const current = join16(root, "skillify");
1721
1754
  if (!existsSync8(legacy))
1722
1755
  return;
1723
1756
  if (existsSync8(current))
@@ -1737,17 +1770,17 @@ function migrateLegacyStateDir() {
1737
1770
 
1738
1771
  // dist/src/skillify/state.js
1739
1772
  var dlog3 = (msg) => log("skillify-state", msg);
1740
- var STATE_DIR2 = join16(homedir13(), ".deeplake", "state", "skillify");
1773
+ var STATE_DIR2 = join17(homedir14(), ".deeplake", "state", "skillify");
1741
1774
  var YIELD_BUF2 = new Int32Array(new SharedArrayBuffer(4));
1742
1775
  var TRIGGER_THRESHOLD = (() => {
1743
1776
  const n = Number(process.env.HIVEMIND_SKILLIFY_EVERY_N_TURNS ?? "");
1744
1777
  return Number.isInteger(n) && n > 0 ? n : 20;
1745
1778
  })();
1746
1779
  function statePath2(projectKey) {
1747
- return join16(STATE_DIR2, `${projectKey}.json`);
1780
+ return join17(STATE_DIR2, `${projectKey}.json`);
1748
1781
  }
1749
1782
  function lockPath3(projectKey) {
1750
- return join16(STATE_DIR2, `${projectKey}.lock`);
1783
+ return join17(STATE_DIR2, `${projectKey}.lock`);
1751
1784
  }
1752
1785
  var DEFAULT_PORTS = {
1753
1786
  http: "80",
@@ -1796,22 +1829,22 @@ function readState2(projectKey) {
1796
1829
  if (!existsSync9(p))
1797
1830
  return null;
1798
1831
  try {
1799
- return JSON.parse(readFileSync8(p, "utf-8"));
1832
+ return JSON.parse(readFileSync9(p, "utf-8"));
1800
1833
  } catch {
1801
1834
  return null;
1802
1835
  }
1803
1836
  }
1804
1837
  function writeState2(projectKey, state) {
1805
1838
  migrateLegacyStateDir();
1806
- mkdirSync9(STATE_DIR2, { recursive: true });
1839
+ mkdirSync10(STATE_DIR2, { recursive: true });
1807
1840
  const p = statePath2(projectKey);
1808
1841
  const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
1809
- writeFileSync7(tmp, JSON.stringify(state, null, 2));
1842
+ writeFileSync8(tmp, JSON.stringify(state, null, 2));
1810
1843
  renameSync6(tmp, p);
1811
1844
  }
1812
1845
  function withRmwLock2(projectKey, fn) {
1813
1846
  migrateLegacyStateDir();
1814
- mkdirSync9(STATE_DIR2, { recursive: true });
1847
+ mkdirSync10(STATE_DIR2, { recursive: true });
1815
1848
  const rmw = lockPath3(projectKey) + ".rmw";
1816
1849
  const deadline = Date.now() + 2e3;
1817
1850
  let fd = null;
@@ -1824,7 +1857,7 @@ function withRmwLock2(projectKey, fn) {
1824
1857
  if (Date.now() > deadline) {
1825
1858
  dlog3(`rmw lock deadline exceeded for ${projectKey}, reclaiming stale lock`);
1826
1859
  try {
1827
- unlinkSync4(rmw);
1860
+ unlinkSync5(rmw);
1828
1861
  } catch (unlinkErr) {
1829
1862
  dlog3(`stale rmw lock unlink failed for ${projectKey}: ${unlinkErr.message}`);
1830
1863
  }
@@ -1838,7 +1871,7 @@ function withRmwLock2(projectKey, fn) {
1838
1871
  } finally {
1839
1872
  closeSync4(fd);
1840
1873
  try {
1841
- unlinkSync4(rmw);
1874
+ unlinkSync5(rmw);
1842
1875
  } catch (unlinkErr) {
1843
1876
  dlog3(`rmw lock cleanup failed for ${projectKey}: ${unlinkErr.message}`);
1844
1877
  }
@@ -1871,18 +1904,18 @@ function resetCounter(projectKey) {
1871
1904
  }
1872
1905
  function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
1873
1906
  migrateLegacyStateDir();
1874
- mkdirSync9(STATE_DIR2, { recursive: true });
1907
+ mkdirSync10(STATE_DIR2, { recursive: true });
1875
1908
  const p = lockPath3(projectKey);
1876
1909
  if (existsSync9(p)) {
1877
1910
  try {
1878
- const ageMs = Date.now() - parseInt(readFileSync8(p, "utf-8"), 10);
1911
+ const ageMs = Date.now() - parseInt(readFileSync9(p, "utf-8"), 10);
1879
1912
  if (Number.isFinite(ageMs) && ageMs < maxAgeMs)
1880
1913
  return false;
1881
1914
  } catch (readErr) {
1882
1915
  dlog3(`worker lock unreadable for ${projectKey}, treating as stale: ${readErr.message}`);
1883
1916
  }
1884
1917
  try {
1885
- unlinkSync4(p);
1918
+ unlinkSync5(p);
1886
1919
  } catch (unlinkErr) {
1887
1920
  dlog3(`could not unlink stale worker lock for ${projectKey}: ${unlinkErr.message}`);
1888
1921
  return false;
@@ -1903,24 +1936,24 @@ function tryAcquireWorkerLock(projectKey, maxAgeMs = 10 * 60 * 1e3) {
1903
1936
  function releaseWorkerLock(projectKey) {
1904
1937
  const p = lockPath3(projectKey);
1905
1938
  try {
1906
- unlinkSync4(p);
1939
+ unlinkSync5(p);
1907
1940
  } catch {
1908
1941
  }
1909
1942
  }
1910
1943
 
1911
1944
  // dist/src/skillify/scope-config.js
1912
- import { existsSync as existsSync10, mkdirSync as mkdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "node:fs";
1913
- import { homedir as homedir14 } from "node:os";
1914
- import { join as join17 } from "node:path";
1915
- var STATE_DIR3 = join17(homedir14(), ".deeplake", "state", "skillify");
1916
- var CONFIG_PATH = join17(STATE_DIR3, "config.json");
1945
+ import { existsSync as existsSync10, mkdirSync as mkdirSync11, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "node:fs";
1946
+ import { homedir as homedir15 } from "node:os";
1947
+ import { join as join18 } from "node:path";
1948
+ var STATE_DIR3 = join18(homedir15(), ".deeplake", "state", "skillify");
1949
+ var CONFIG_PATH = join18(STATE_DIR3, "config.json");
1917
1950
  var DEFAULT = { scope: "me", team: [], install: "project" };
1918
1951
  function loadScopeConfig() {
1919
1952
  migrateLegacyStateDir();
1920
1953
  if (!existsSync10(CONFIG_PATH))
1921
1954
  return DEFAULT;
1922
1955
  try {
1923
- const raw = JSON.parse(readFileSync9(CONFIG_PATH, "utf-8"));
1956
+ const raw = JSON.parse(readFileSync10(CONFIG_PATH, "utf-8"));
1924
1957
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
1925
1958
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
1926
1959
  const install = raw.install === "global" ? "global" : "project";
@@ -1973,7 +2006,7 @@ function tryStopCounterTrigger(opts) {
1973
2006
  // dist/src/hooks/hermes/capture.js
1974
2007
  var log5 = (msg) => log("hermes-capture", msg);
1975
2008
  function resolveEmbedDaemonPath() {
1976
- return join18(dirname6(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
2009
+ return join19(dirname6(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1977
2010
  }
1978
2011
  var __bundleDir = dirname6(fileURLToPath3(import.meta.url));
1979
2012
  var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".claude-plugin") ?? "";