@deeplake/hivemind 0.7.31 → 0.7.32

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.
@@ -46081,14 +46081,14 @@ var require_turndown_cjs = __commonJS({
46081
46081
  } else if (node.nodeType === 1) {
46082
46082
  replacement = replacementForNode.call(self2, node);
46083
46083
  }
46084
- return join11(output, replacement);
46084
+ return join13(output, replacement);
46085
46085
  }, "");
46086
46086
  }
46087
46087
  function postProcess(output) {
46088
46088
  var self2 = this;
46089
46089
  this.rules.forEach(function(rule) {
46090
46090
  if (typeof rule.append === "function") {
46091
- output = join11(output, rule.append(self2.options));
46091
+ output = join13(output, rule.append(self2.options));
46092
46092
  }
46093
46093
  });
46094
46094
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -46100,7 +46100,7 @@ var require_turndown_cjs = __commonJS({
46100
46100
  if (whitespace.leading || whitespace.trailing) content = content.trim();
46101
46101
  return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
46102
46102
  }
46103
- function join11(output, replacement) {
46103
+ function join13(output, replacement) {
46104
46104
  var s12 = trimTrailingNewlines(output);
46105
46105
  var s22 = trimLeadingNewlines(replacement);
46106
46106
  var nls = Math.max(output.length - s12.length, replacement.length - s22.length);
@@ -66870,7 +66870,7 @@ function getQueryTimeoutMs() {
66870
66870
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
66871
66871
  }
66872
66872
  function sleep(ms3) {
66873
- return new Promise((resolve5) => setTimeout(resolve5, ms3));
66873
+ return new Promise((resolve6) => setTimeout(resolve6, ms3));
66874
66874
  }
66875
66875
  function isTimeoutError(error) {
66876
66876
  const name = error instanceof Error ? error.name.toLowerCase() : "";
@@ -66900,7 +66900,7 @@ var Semaphore = class {
66900
66900
  this.active++;
66901
66901
  return;
66902
66902
  }
66903
- await new Promise((resolve5) => this.waiting.push(resolve5));
66903
+ await new Promise((resolve6) => this.waiting.push(resolve6));
66904
66904
  }
66905
66905
  release() {
66906
66906
  this.active--;
@@ -67259,7 +67259,7 @@ var DeeplakeApi = class {
67259
67259
  import { basename as basename4, posix } from "node:path";
67260
67260
  import { randomUUID as randomUUID2 } from "node:crypto";
67261
67261
  import { fileURLToPath } from "node:url";
67262
- import { dirname as dirname4, join as join9 } from "node:path";
67262
+ import { dirname as dirname5, join as join11 } from "node:path";
67263
67263
 
67264
67264
  // dist/src/shell/grep-core.js
67265
67265
  var TOOL_INPUT_FIELDS = [
@@ -67689,9 +67689,9 @@ function refineGrepMatches(rows, params, forceMultiFilePrefix) {
67689
67689
  // dist/src/embeddings/client.js
67690
67690
  import { connect } from "node:net";
67691
67691
  import { spawn } from "node:child_process";
67692
- import { openSync, closeSync, writeSync, unlinkSync, existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
67693
- import { homedir as homedir3 } from "node:os";
67694
- import { join as join7 } from "node:path";
67692
+ import { openSync as openSync2, closeSync as closeSync2, writeSync, unlinkSync as unlinkSync2, existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
67693
+ import { homedir as homedir6 } from "node:os";
67694
+ import { join as join10 } from "node:path";
67695
67695
 
67696
67696
  // dist/src/embeddings/protocol.js
67697
67697
  var DEFAULT_SOCKET_DIR = "/tmp";
@@ -67704,13 +67704,234 @@ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
67704
67704
  return `${dir}/hivemind-embed-${uid}.pid`;
67705
67705
  }
67706
67706
 
67707
+ // dist/src/notifications/queue.js
67708
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync as statSync2 } from "node:fs";
67709
+ import { join as join7, resolve as resolve4 } from "node:path";
67710
+ import { homedir as homedir3 } from "node:os";
67711
+ import { setTimeout as sleep2 } from "node:timers/promises";
67712
+ var log3 = (msg) => log("notifications-queue", msg);
67713
+ var LOCK_RETRY_MAX = 50;
67714
+ var LOCK_RETRY_BASE_MS = 5;
67715
+ var LOCK_STALE_MS = 5e3;
67716
+ function queuePath() {
67717
+ return join7(homedir3(), ".deeplake", "notifications-queue.json");
67718
+ }
67719
+ function lockPath() {
67720
+ return `${queuePath()}.lock`;
67721
+ }
67722
+ function readQueue() {
67723
+ try {
67724
+ const raw = readFileSync3(queuePath(), "utf-8");
67725
+ const parsed = JSON.parse(raw);
67726
+ if (!parsed || !Array.isArray(parsed.queue)) {
67727
+ log3(`queue malformed \u2192 treating as empty`);
67728
+ return { queue: [] };
67729
+ }
67730
+ return { queue: parsed.queue };
67731
+ } catch {
67732
+ return { queue: [] };
67733
+ }
67734
+ }
67735
+ function _isQueuePathInsideHome(path2, home) {
67736
+ const r10 = resolve4(path2);
67737
+ const h18 = resolve4(home);
67738
+ return r10.startsWith(h18 + "/") || r10 === h18;
67739
+ }
67740
+ function writeQueue(q17) {
67741
+ const path2 = queuePath();
67742
+ const home = resolve4(homedir3());
67743
+ if (!_isQueuePathInsideHome(path2, home)) {
67744
+ throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
67745
+ }
67746
+ mkdirSync2(join7(home, ".deeplake"), { recursive: true, mode: 448 });
67747
+ const tmp = `${path2}.${process.pid}.tmp`;
67748
+ writeFileSync2(tmp, JSON.stringify(q17, null, 2), { mode: 384 });
67749
+ renameSync(tmp, path2);
67750
+ }
67751
+ async function withQueueLock(fn4) {
67752
+ const path2 = lockPath();
67753
+ mkdirSync2(join7(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
67754
+ let fd = null;
67755
+ for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
67756
+ try {
67757
+ fd = openSync(path2, "wx", 384);
67758
+ break;
67759
+ } catch (e6) {
67760
+ const code = e6.code;
67761
+ if (code !== "EEXIST")
67762
+ throw e6;
67763
+ try {
67764
+ const age = Date.now() - statSync2(path2).mtimeMs;
67765
+ if (age > LOCK_STALE_MS) {
67766
+ unlinkSync(path2);
67767
+ continue;
67768
+ }
67769
+ } catch {
67770
+ }
67771
+ const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
67772
+ await sleep2(delay);
67773
+ }
67774
+ }
67775
+ if (fd === null) {
67776
+ log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
67777
+ return fn4();
67778
+ }
67779
+ try {
67780
+ return fn4();
67781
+ } finally {
67782
+ try {
67783
+ closeSync(fd);
67784
+ } catch {
67785
+ }
67786
+ try {
67787
+ unlinkSync(path2);
67788
+ } catch {
67789
+ }
67790
+ }
67791
+ }
67792
+ function sameDedupKey(a15, b26) {
67793
+ if (a15.id !== b26.id)
67794
+ return false;
67795
+ return JSON.stringify(a15.dedupKey) === JSON.stringify(b26.dedupKey);
67796
+ }
67797
+ async function enqueueNotification(n24) {
67798
+ await withQueueLock(() => {
67799
+ const q17 = readQueue();
67800
+ if (q17.queue.some((existing) => sameDedupKey(existing, n24))) {
67801
+ return;
67802
+ }
67803
+ q17.queue.push(n24);
67804
+ writeQueue(q17);
67805
+ });
67806
+ }
67807
+
67808
+ // dist/src/embeddings/disable.js
67809
+ import { createRequire } from "node:module";
67810
+ import { homedir as homedir5 } from "node:os";
67811
+ import { join as join9 } from "node:path";
67812
+ import { pathToFileURL } from "node:url";
67813
+
67814
+ // dist/src/user-config.js
67815
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
67816
+ import { homedir as homedir4 } from "node:os";
67817
+ import { dirname as dirname4, join as join8 } from "node:path";
67818
+ var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join8(homedir4(), ".deeplake", "config.json");
67819
+ var _cache = null;
67820
+ var _migrated = false;
67821
+ function readUserConfig() {
67822
+ if (_cache !== null)
67823
+ return _cache;
67824
+ const path2 = _configPath();
67825
+ if (!existsSync4(path2)) {
67826
+ _cache = {};
67827
+ return _cache;
67828
+ }
67829
+ try {
67830
+ const raw = readFileSync4(path2, "utf-8");
67831
+ const parsed = JSON.parse(raw);
67832
+ _cache = isPlainObject(parsed) ? parsed : {};
67833
+ } catch {
67834
+ _cache = {};
67835
+ }
67836
+ return _cache;
67837
+ }
67838
+ function writeUserConfig(patch) {
67839
+ const current = readUserConfig();
67840
+ const merged = deepMerge(current, patch);
67841
+ const path2 = _configPath();
67842
+ const dir = dirname4(path2);
67843
+ if (!existsSync4(dir))
67844
+ mkdirSync3(dir, { recursive: true });
67845
+ const tmp = `${path2}.tmp.${process.pid}`;
67846
+ writeFileSync3(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
67847
+ renameSync2(tmp, path2);
67848
+ _cache = merged;
67849
+ return merged;
67850
+ }
67851
+ function getEmbeddingsEnabled() {
67852
+ const cfg = readUserConfig();
67853
+ if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
67854
+ return cfg.embeddings.enabled;
67855
+ }
67856
+ if (_migrated) {
67857
+ return migrationValueFromEnv();
67858
+ }
67859
+ _migrated = true;
67860
+ const enabled = migrationValueFromEnv();
67861
+ try {
67862
+ writeUserConfig({ embeddings: { enabled } });
67863
+ } catch {
67864
+ _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
67865
+ }
67866
+ return enabled;
67867
+ }
67868
+ function migrationValueFromEnv() {
67869
+ const raw = process.env.HIVEMIND_EMBEDDINGS;
67870
+ if (raw === void 0)
67871
+ return false;
67872
+ if (raw === "false")
67873
+ return false;
67874
+ return true;
67875
+ }
67876
+ function isPlainObject(value) {
67877
+ return typeof value === "object" && value !== null && !Array.isArray(value);
67878
+ }
67879
+ function deepMerge(base, patch) {
67880
+ const out = { ...base };
67881
+ for (const key of Object.keys(patch)) {
67882
+ const patchVal = patch[key];
67883
+ const baseVal = base[key];
67884
+ if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
67885
+ out[key] = { ...baseVal, ...patchVal };
67886
+ } else if (patchVal !== void 0) {
67887
+ out[key] = patchVal;
67888
+ }
67889
+ }
67890
+ return out;
67891
+ }
67892
+
67893
+ // dist/src/embeddings/disable.js
67894
+ var cachedStatus = null;
67895
+ function defaultResolveTransformers() {
67896
+ const sharedDir = join9(homedir5(), ".hivemind", "embed-deps");
67897
+ try {
67898
+ createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
67899
+ return;
67900
+ } catch {
67901
+ }
67902
+ createRequire(import.meta.url).resolve("@huggingface/transformers");
67903
+ }
67904
+ var _resolve = defaultResolveTransformers;
67905
+ var _readEnabled = getEmbeddingsEnabled;
67906
+ function detectStatus() {
67907
+ if (!_readEnabled())
67908
+ return "user-disabled";
67909
+ try {
67910
+ _resolve();
67911
+ return "enabled";
67912
+ } catch {
67913
+ return "no-transformers";
67914
+ }
67915
+ }
67916
+ function embeddingsStatus() {
67917
+ if (cachedStatus !== null)
67918
+ return cachedStatus;
67919
+ cachedStatus = detectStatus();
67920
+ return cachedStatus;
67921
+ }
67922
+ function embeddingsDisabled() {
67923
+ return embeddingsStatus() !== "enabled";
67924
+ }
67925
+
67707
67926
  // dist/src/embeddings/client.js
67708
- var SHARED_DAEMON_PATH = join7(homedir3(), ".hivemind", "embed-deps", "embed-daemon.js");
67709
- var log3 = (m26) => log("embed-client", m26);
67927
+ var SHARED_DAEMON_PATH = join10(homedir6(), ".hivemind", "embed-deps", "embed-daemon.js");
67928
+ var log4 = (m26) => log("embed-client", m26);
67710
67929
  function getUid() {
67711
67930
  const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
67712
67931
  return uid !== void 0 ? String(uid) : process.env.USER ?? "default";
67713
67932
  }
67933
+ var _signalledMissingDeps = false;
67934
+ var _recycledStuckDaemon = false;
67714
67935
  var EmbedClient = class {
67715
67936
  socketPath;
67716
67937
  pidPath;
@@ -67719,13 +67940,14 @@ var EmbedClient = class {
67719
67940
  autoSpawn;
67720
67941
  spawnWaitMs;
67721
67942
  nextId = 0;
67943
+ helloVerified = false;
67722
67944
  constructor(opts = {}) {
67723
67945
  const uid = getUid();
67724
67946
  const dir = opts.socketDir ?? "/tmp";
67725
67947
  this.socketPath = socketPathFor(uid, dir);
67726
67948
  this.pidPath = pidPathFor(uid, dir);
67727
67949
  this.timeoutMs = opts.timeoutMs ?? DEFAULT_CLIENT_TIMEOUT_MS;
67728
- this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync4(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
67950
+ this.daemonEntry = opts.daemonEntry ?? process.env.HIVEMIND_EMBED_DAEMON ?? (existsSync5(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : void 0);
67729
67951
  this.autoSpawn = opts.autoSpawn ?? true;
67730
67952
  this.spawnWaitMs = opts.spawnWaitMs ?? 5e3;
67731
67953
  }
@@ -67735,8 +67957,33 @@ var EmbedClient = class {
67735
67957
  *
67736
67958
  * Fire-and-forget spawn on miss: if the daemon isn't up, this call returns
67737
67959
  * null AND kicks off a background spawn. The next call finds a ready daemon.
67960
+ *
67961
+ * Stuck-daemon recycle: if the daemon returns a transformers-missing
67962
+ * error (typical after a marketplace upgrade left an older daemon process
67963
+ * alive but with no node_modules accessible from its bundle path), we
67964
+ * SIGTERM it and clear its sock/pid so the very next call spawns a fresh
67965
+ * daemon from the current bundle. Without this, the stuck daemon would
67966
+ * keep poisoning every session until its 10-minute idle-out fires.
67738
67967
  */
67739
67968
  async embed(text, kind = "document") {
67969
+ const v27 = await this.embedAttempt(text, kind);
67970
+ if (v27 !== "recycled")
67971
+ return v27;
67972
+ if (!this.autoSpawn)
67973
+ return null;
67974
+ this.trySpawnDaemon();
67975
+ await this.waitForDaemonReady();
67976
+ const retry = await this.embedAttempt(text, kind);
67977
+ return retry === "recycled" ? null : retry;
67978
+ }
67979
+ /**
67980
+ * One round-trip: connect → verify → embed. Returns:
67981
+ * - number[] : embedding vector (happy path)
67982
+ * - null : timeout / daemon error / transformers-missing
67983
+ * - "recycled": verifyDaemonOnce killed the daemon mid-call;
67984
+ * caller should respawn and retry once.
67985
+ */
67986
+ async embedAttempt(text, kind) {
67740
67987
  let sock;
67741
67988
  try {
67742
67989
  sock = await this.connectOnce();
@@ -67746,17 +67993,25 @@ var EmbedClient = class {
67746
67993
  return null;
67747
67994
  }
67748
67995
  try {
67996
+ const recycled = await this.verifyDaemonOnce(sock);
67997
+ if (recycled) {
67998
+ return "recycled";
67999
+ }
67749
68000
  const id = String(++this.nextId);
67750
68001
  const req = { op: "embed", id, kind, text };
67751
68002
  const resp = await this.sendAndWait(sock, req);
67752
68003
  if (resp.error || !("embedding" in resp) || !resp.embedding) {
67753
- log3(`embed err: ${resp.error ?? "no embedding"}`);
68004
+ const err = resp.error ?? "no embedding";
68005
+ log4(`embed err: ${err}`);
68006
+ if (isTransformersMissingError(err)) {
68007
+ this.handleTransformersMissing(err);
68008
+ }
67754
68009
  return null;
67755
68010
  }
67756
68011
  return resp.embedding;
67757
68012
  } catch (e6) {
67758
68013
  const err = e6 instanceof Error ? e6.message : String(e6);
67759
- log3(`embed failed: ${err}`);
68014
+ log4(`embed failed: ${err}`);
67760
68015
  return null;
67761
68016
  } finally {
67762
68017
  try {
@@ -67765,6 +68020,139 @@ var EmbedClient = class {
67765
68020
  }
67766
68021
  }
67767
68022
  }
68023
+ /**
68024
+ * Poll for the sock file to come back after `trySpawnDaemon` — used by
68025
+ * the recycle retry path. Best-effort: caps at `spawnWaitMs` and
68026
+ * returns regardless so the retry attempt can run.
68027
+ */
68028
+ async waitForDaemonReady() {
68029
+ const deadline = Date.now() + this.spawnWaitMs;
68030
+ while (Date.now() < deadline) {
68031
+ if (existsSync5(this.socketPath))
68032
+ return;
68033
+ await new Promise((r10) => setTimeout(r10, 50));
68034
+ }
68035
+ }
68036
+ /**
68037
+ * Send a `hello` on first successful connect per EmbedClient instance.
68038
+ * If the daemon answers with a path that doesn't match our configured
68039
+ * daemonEntry — typical after a marketplace upgrade replaced the bundle
68040
+ * — SIGTERM the daemon + clear sock/pid so the next call spawns from the
68041
+ * current bundle.
68042
+ *
68043
+ * `helloVerified` is set ONLY after we've seen a compatible response,
68044
+ * so a transient probe failure or a recycle-triggering mismatch leaves
68045
+ * the flag false; the next reconnect re-runs verification against
68046
+ * whatever daemon is then live (typically the fresh spawn).
68047
+ */
68048
+ async verifyDaemonOnce(sock) {
68049
+ if (this.helloVerified)
68050
+ return false;
68051
+ if (!this.daemonEntry) {
68052
+ this.helloVerified = true;
68053
+ return false;
68054
+ }
68055
+ const id = String(++this.nextId);
68056
+ const req = { op: "hello", id };
68057
+ let resp;
68058
+ try {
68059
+ resp = await this.sendAndWait(sock, req);
68060
+ } catch (e6) {
68061
+ log4(`hello probe failed (inconclusive, will retry next connect): ${e6 instanceof Error ? e6.message : String(e6)}`);
68062
+ return false;
68063
+ }
68064
+ const hello = resp;
68065
+ if (_recycledStuckDaemon) {
68066
+ return false;
68067
+ }
68068
+ if (!hello.daemonPath) {
68069
+ _recycledStuckDaemon = true;
68070
+ log4(`daemon does not implement hello (older protocol); recycling`);
68071
+ this.recycleDaemon(hello.pid);
68072
+ return true;
68073
+ }
68074
+ if (hello.daemonPath !== this.daemonEntry && !existsSync5(hello.daemonPath)) {
68075
+ _recycledStuckDaemon = true;
68076
+ log4(`daemon path no longer on disk \u2014 running=${hello.daemonPath} (gone) expected=${this.daemonEntry}; recycling`);
68077
+ this.recycleDaemon(hello.pid);
68078
+ return true;
68079
+ }
68080
+ this.helloVerified = true;
68081
+ return false;
68082
+ }
68083
+ /**
68084
+ * On a transformers-missing error from the daemon, SIGTERM the stuck
68085
+ * daemon (the bundle daemon that can't find its deps) and clear
68086
+ * sock/pid so the next call spawns fresh. Also enqueue a one-time
68087
+ * notification telling the user to run `hivemind embeddings install`
68088
+ * — but only when the user has opted in. Suppressed when
68089
+ * embeddingsStatus() === "user-disabled" so we don't nag users who
68090
+ * explicitly chose to turn embeddings off.
68091
+ */
68092
+ handleTransformersMissing(detail) {
68093
+ if (!_recycledStuckDaemon) {
68094
+ _recycledStuckDaemon = true;
68095
+ this.recycleDaemon(null);
68096
+ }
68097
+ if (_signalledMissingDeps)
68098
+ return;
68099
+ _signalledMissingDeps = true;
68100
+ let status;
68101
+ try {
68102
+ status = embeddingsStatus();
68103
+ } catch {
68104
+ status = "enabled";
68105
+ }
68106
+ if (status === "user-disabled")
68107
+ return;
68108
+ enqueueNotification({
68109
+ id: "embed-deps-missing",
68110
+ severity: "warn",
68111
+ title: "Hivemind embeddings disabled \u2014 deps missing",
68112
+ body: `Semantic memory search is off because @huggingface/transformers is not installed where the daemon can find it. Run \`hivemind embeddings install\` to enable.`,
68113
+ dedupKey: { reason: "transformers-missing", detail: detail.slice(0, 200) }
68114
+ }).catch((e6) => {
68115
+ log4(`enqueue embed-deps-missing failed: ${e6 instanceof Error ? e6.message : String(e6)}`);
68116
+ });
68117
+ }
68118
+ /**
68119
+ * Best-effort SIGTERM + sock/pid cleanup. Tolerant of every missing-file
68120
+ * combination and dead-PID cases.
68121
+ *
68122
+ * Identity check: gate the SIGTERM on the daemon's socket file still
68123
+ * existing. We know the daemon was alive moments ago (we either just
68124
+ * got a hello response or the caller saw a transformers-missing error
68125
+ * the daemon emitted), but if the socket file is gone by the time we
68126
+ * try to kill, the daemon process is also gone and the PID we
68127
+ * captured may already have been recycled by the OS to an unrelated
68128
+ * user process. Mirrors the gate added to `killEmbedDaemon` in the
68129
+ * CLI — same failure mode, rarer trigger.
68130
+ */
68131
+ recycleDaemon(reportedPid) {
68132
+ let pid = reportedPid;
68133
+ if (pid === null) {
68134
+ try {
68135
+ pid = Number.parseInt(readFileSync5(this.pidPath, "utf-8").trim(), 10);
68136
+ } catch {
68137
+ }
68138
+ }
68139
+ if (Number.isFinite(pid) && pid !== null && pid > 0 && existsSync5(this.socketPath)) {
68140
+ try {
68141
+ process.kill(pid, "SIGTERM");
68142
+ } catch {
68143
+ }
68144
+ } else if (pid !== null) {
68145
+ log4(`recycle: socket gone, skipping SIGTERM on possibly-stale pid ${pid}`);
68146
+ }
68147
+ try {
68148
+ unlinkSync2(this.socketPath);
68149
+ } catch {
68150
+ }
68151
+ try {
68152
+ unlinkSync2(this.pidPath);
68153
+ } catch {
68154
+ }
68155
+ }
67768
68156
  /**
67769
68157
  * Wait up to spawnWaitMs for the daemon to accept connections, spawning if
67770
68158
  * necessary. Meant for SessionStart / long-running batches — not the hot path.
@@ -67788,7 +68176,7 @@ var EmbedClient = class {
67788
68176
  }
67789
68177
  }
67790
68178
  connectOnce() {
67791
- return new Promise((resolve5, reject) => {
68179
+ return new Promise((resolve6, reject) => {
67792
68180
  const sock = connect(this.socketPath);
67793
68181
  const to3 = setTimeout(() => {
67794
68182
  sock.destroy();
@@ -67796,7 +68184,7 @@ var EmbedClient = class {
67796
68184
  }, this.timeoutMs);
67797
68185
  sock.once("connect", () => {
67798
68186
  clearTimeout(to3);
67799
- resolve5(sock);
68187
+ resolve6(sock);
67800
68188
  });
67801
68189
  sock.once("error", (e6) => {
67802
68190
  clearTimeout(to3);
@@ -67807,16 +68195,16 @@ var EmbedClient = class {
67807
68195
  trySpawnDaemon() {
67808
68196
  let fd;
67809
68197
  try {
67810
- fd = openSync(this.pidPath, "wx", 384);
68198
+ fd = openSync2(this.pidPath, "wx", 384);
67811
68199
  writeSync(fd, String(process.pid));
67812
68200
  } catch (e6) {
67813
68201
  if (this.isPidFileStale()) {
67814
68202
  try {
67815
- unlinkSync(this.pidPath);
68203
+ unlinkSync2(this.pidPath);
67816
68204
  } catch {
67817
68205
  }
67818
68206
  try {
67819
- fd = openSync(this.pidPath, "wx", 384);
68207
+ fd = openSync2(this.pidPath, "wx", 384);
67820
68208
  writeSync(fd, String(process.pid));
67821
68209
  } catch {
67822
68210
  return;
@@ -67825,11 +68213,11 @@ var EmbedClient = class {
67825
68213
  return;
67826
68214
  }
67827
68215
  }
67828
- if (!this.daemonEntry || !existsSync4(this.daemonEntry)) {
67829
- log3(`daemonEntry not configured or missing: ${this.daemonEntry}`);
68216
+ if (!this.daemonEntry || !existsSync5(this.daemonEntry)) {
68217
+ log4(`daemonEntry not configured or missing: ${this.daemonEntry}`);
67830
68218
  try {
67831
- closeSync(fd);
67832
- unlinkSync(this.pidPath);
68219
+ closeSync2(fd);
68220
+ unlinkSync2(this.pidPath);
67833
68221
  } catch {
67834
68222
  }
67835
68223
  return;
@@ -67841,14 +68229,14 @@ var EmbedClient = class {
67841
68229
  env: process.env
67842
68230
  });
67843
68231
  child.unref();
67844
- log3(`spawned daemon pid=${child.pid}`);
68232
+ log4(`spawned daemon pid=${child.pid}`);
67845
68233
  } finally {
67846
- closeSync(fd);
68234
+ closeSync2(fd);
67847
68235
  }
67848
68236
  }
67849
68237
  isPidFileStale() {
67850
68238
  try {
67851
- const raw = readFileSync3(this.pidPath, "utf-8").trim();
68239
+ const raw = readFileSync5(this.pidPath, "utf-8").trim();
67852
68240
  const pid = Number(raw);
67853
68241
  if (!pid || Number.isNaN(pid))
67854
68242
  return true;
@@ -67866,9 +68254,9 @@ var EmbedClient = class {
67866
68254
  const deadline = Date.now() + this.spawnWaitMs;
67867
68255
  let delay = 30;
67868
68256
  while (Date.now() < deadline) {
67869
- await sleep2(delay);
68257
+ await sleep3(delay);
67870
68258
  delay = Math.min(delay * 1.5, 300);
67871
- if (!existsSync4(this.socketPath))
68259
+ if (!existsSync5(this.socketPath))
67872
68260
  continue;
67873
68261
  try {
67874
68262
  return await this.connectOnce();
@@ -67878,7 +68266,7 @@ var EmbedClient = class {
67878
68266
  throw new Error("daemon did not become ready within spawnWaitMs");
67879
68267
  }
67880
68268
  sendAndWait(sock, req) {
67881
- return new Promise((resolve5, reject) => {
68269
+ return new Promise((resolve6, reject) => {
67882
68270
  let buf = "";
67883
68271
  const to3 = setTimeout(() => {
67884
68272
  sock.destroy();
@@ -67893,7 +68281,7 @@ var EmbedClient = class {
67893
68281
  const line = buf.slice(0, nl3);
67894
68282
  clearTimeout(to3);
67895
68283
  try {
67896
- resolve5(JSON.parse(line));
68284
+ resolve6(JSON.parse(line));
67897
68285
  } catch (e6) {
67898
68286
  reject(e6);
67899
68287
  }
@@ -67910,9 +68298,14 @@ var EmbedClient = class {
67910
68298
  });
67911
68299
  }
67912
68300
  };
67913
- function sleep2(ms3) {
68301
+ function sleep3(ms3) {
67914
68302
  return new Promise((r10) => setTimeout(r10, ms3));
67915
68303
  }
68304
+ function isTransformersMissingError(err) {
68305
+ if (/hivemind embeddings install/i.test(err))
68306
+ return true;
68307
+ return /@huggingface\/transformers/i.test(err);
68308
+ }
67916
68309
 
67917
68310
  // dist/src/embeddings/sql.js
67918
68311
  function embeddingSqlLiteral(vec) {
@@ -67927,42 +68320,6 @@ function embeddingSqlLiteral(vec) {
67927
68320
  return `ARRAY[${parts.join(",")}]::float4[]`;
67928
68321
  }
67929
68322
 
67930
- // dist/src/embeddings/disable.js
67931
- import { createRequire } from "node:module";
67932
- import { homedir as homedir4 } from "node:os";
67933
- import { join as join8 } from "node:path";
67934
- import { pathToFileURL } from "node:url";
67935
- var cachedStatus = null;
67936
- function defaultResolveTransformers() {
67937
- try {
67938
- createRequire(import.meta.url).resolve("@huggingface/transformers");
67939
- return;
67940
- } catch {
67941
- }
67942
- const sharedDir = join8(homedir4(), ".hivemind", "embed-deps");
67943
- createRequire(pathToFileURL(`${sharedDir}/`).href).resolve("@huggingface/transformers");
67944
- }
67945
- var _resolve = defaultResolveTransformers;
67946
- function detectStatus() {
67947
- if (process.env.HIVEMIND_EMBEDDINGS === "false")
67948
- return "env-disabled";
67949
- try {
67950
- _resolve();
67951
- return "enabled";
67952
- } catch {
67953
- return "no-transformers";
67954
- }
67955
- }
67956
- function embeddingsStatus() {
67957
- if (cachedStatus !== null)
67958
- return cachedStatus;
67959
- cachedStatus = detectStatus();
67960
- return cachedStatus;
67961
- }
67962
- function embeddingsDisabled() {
67963
- return embeddingsStatus() !== "enabled";
67964
- }
67965
-
67966
68323
  // dist/src/hooks/virtual-table-query.js
67967
68324
  var INDEX_LIMIT_PER_SECTION = 50;
67968
68325
  function buildVirtualIndexContent(summaryRows, sessionRows = [], opts = {}) {
@@ -68055,7 +68412,7 @@ function normalizeSessionMessage(path2, message) {
68055
68412
  return normalizeContent(path2, raw);
68056
68413
  }
68057
68414
  function resolveEmbedDaemonPath() {
68058
- return join9(dirname4(fileURLToPath(import.meta.url)), "embeddings", "embed-daemon.js");
68415
+ return join11(dirname5(fileURLToPath(import.meta.url)), "..", "embeddings", "embed-daemon.js");
68059
68416
  }
68060
68417
  function joinSessionMessages(path2, messages) {
68061
68418
  return messages.map((message) => normalizeSessionMessage(path2, message)).join("\n");
@@ -68621,7 +68978,7 @@ var DeeplakeFs = class _DeeplakeFs {
68621
68978
 
68622
68979
  // node_modules/yargs-parser/build/lib/index.js
68623
68980
  import { format } from "util";
68624
- import { normalize, resolve as resolve4 } from "path";
68981
+ import { normalize, resolve as resolve5 } from "path";
68625
68982
 
68626
68983
  // node_modules/yargs-parser/build/lib/string-utils.js
68627
68984
  function camelCase2(str) {
@@ -69559,7 +69916,7 @@ function stripQuotes(val) {
69559
69916
  }
69560
69917
 
69561
69918
  // node_modules/yargs-parser/build/lib/index.js
69562
- import { readFileSync as readFileSync4 } from "fs";
69919
+ import { readFileSync as readFileSync6 } from "fs";
69563
69920
  import { createRequire as createRequire2 } from "node:module";
69564
69921
  var _a3;
69565
69922
  var _b;
@@ -69581,12 +69938,12 @@ var parser = new YargsParser({
69581
69938
  },
69582
69939
  format,
69583
69940
  normalize,
69584
- resolve: resolve4,
69941
+ resolve: resolve5,
69585
69942
  require: (path2) => {
69586
69943
  if (typeof require2 !== "undefined") {
69587
69944
  return require2(path2);
69588
69945
  } else if (path2.match(/\.json$/)) {
69589
- return JSON.parse(readFileSync4(path2, "utf8"));
69946
+ return JSON.parse(readFileSync6(path2, "utf8"));
69590
69947
  } else {
69591
69948
  throw Error("only .json config files are supported in ESM");
69592
69949
  }
@@ -69606,11 +69963,11 @@ var lib_default = yargsParser;
69606
69963
 
69607
69964
  // dist/src/shell/grep-interceptor.js
69608
69965
  import { fileURLToPath as fileURLToPath2 } from "node:url";
69609
- import { dirname as dirname5, join as join10 } from "node:path";
69966
+ import { dirname as dirname6, join as join12 } from "node:path";
69610
69967
  var SEMANTIC_SEARCH_ENABLED = process.env.HIVEMIND_SEMANTIC_SEARCH !== "false" && !embeddingsDisabled();
69611
69968
  var SEMANTIC_EMBED_TIMEOUT_MS = Number(process.env.HIVEMIND_SEMANTIC_EMBED_TIMEOUT_MS ?? "500");
69612
69969
  function resolveGrepEmbedDaemonPath() {
69613
- return join10(dirname5(fileURLToPath2(import.meta.url)), "..", "embeddings", "embed-daemon.js");
69970
+ return join12(dirname6(fileURLToPath2(import.meta.url)), "..", "embeddings", "embed-daemon.js");
69614
69971
  }
69615
69972
  var sharedGrepEmbedClient = null;
69616
69973
  function getGrepEmbedClient() {