@deeplake/hivemind 0.7.31 → 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.
package/bundle/cli.js CHANGED
@@ -17,21 +17,21 @@ __export(index_marker_store_exports, {
17
17
  hasFreshIndexMarker: () => hasFreshIndexMarker,
18
18
  writeIndexMarker: () => writeIndexMarker
19
19
  });
20
- import { existsSync as existsSync13, mkdirSync as mkdirSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "node:fs";
21
- import { join as join16 } from "node:path";
20
+ import { existsSync as existsSync14, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
21
+ import { join as join18 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
24
- return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join16(tmpdir(), "hivemind-deeplake-indexes");
24
+ return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join18(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 join16(getIndexMarkerDir(), `${markerKey}.json`);
28
+ return join18(getIndexMarkerDir(), `${markerKey}.json`);
29
29
  }
30
30
  function hasFreshIndexMarker(markerPath) {
31
- if (!existsSync13(markerPath))
31
+ if (!existsSync14(markerPath))
32
32
  return false;
33
33
  try {
34
- const raw = JSON.parse(readFileSync10(markerPath, "utf-8"));
34
+ const raw = JSON.parse(readFileSync13(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
- mkdirSync3(getIndexMarkerDir(), { recursive: true });
45
- writeFileSync7(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
44
+ mkdirSync5(getIndexMarkerDir(), { recursive: true });
45
+ writeFileSync9(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({
@@ -3681,42 +3681,137 @@ function uninstallPi() {
3681
3681
  }
3682
3682
 
3683
3683
  // dist/src/cli/embeddings.js
3684
- import { copyFileSync as copyFileSync3, chmodSync, existsSync as existsSync10, lstatSync as lstatSync2, readdirSync, readlinkSync, rmSync as rmSync4, statSync, unlinkSync as unlinkSync5 } from "node:fs";
3685
- import { execFileSync as execFileSync3 } from "node:child_process";
3686
- import { join as join11 } from "node:path";
3687
- var SHARED_DIR = join11(HOME, ".hivemind", "embed-deps");
3688
- var SHARED_NODE_MODULES = join11(SHARED_DIR, "node_modules");
3689
- var SHARED_DAEMON_PATH = join11(SHARED_DIR, "embed-daemon.js");
3684
+ import { copyFileSync as copyFileSync3, chmodSync, existsSync as existsSync11, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync9, readlinkSync, rmSync as rmSync4, statSync, unlinkSync as unlinkSync5 } from "node:fs";
3685
+ import { execFileSync as execFileSync3, spawnSync } from "node:child_process";
3686
+ import { userInfo } from "node:os";
3687
+ import { join as join12 } from "node:path";
3688
+
3689
+ // dist/src/embeddings/protocol.js
3690
+ var DEFAULT_SOCKET_DIR = "/tmp";
3691
+ var DEFAULT_IDLE_TIMEOUT_MS = 10 * 60 * 1e3;
3692
+ function socketPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
3693
+ return `${dir}/hivemind-embed-${uid}.sock`;
3694
+ }
3695
+ function pidPathFor(uid, dir = DEFAULT_SOCKET_DIR) {
3696
+ return `${dir}/hivemind-embed-${uid}.pid`;
3697
+ }
3698
+
3699
+ // dist/src/user-config.js
3700
+ import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync6 } from "node:fs";
3701
+ import { homedir as homedir4 } from "node:os";
3702
+ import { dirname as dirname2, join as join11 } from "node:path";
3703
+ var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join11(homedir4(), ".deeplake", "config.json");
3704
+ var _cache = null;
3705
+ var _migrated = false;
3706
+ function readUserConfig() {
3707
+ if (_cache !== null)
3708
+ return _cache;
3709
+ const path = _configPath();
3710
+ if (!existsSync10(path)) {
3711
+ _cache = {};
3712
+ return _cache;
3713
+ }
3714
+ try {
3715
+ const raw = readFileSync8(path, "utf-8");
3716
+ const parsed = JSON.parse(raw);
3717
+ _cache = isPlainObject(parsed) ? parsed : {};
3718
+ } catch {
3719
+ _cache = {};
3720
+ }
3721
+ return _cache;
3722
+ }
3723
+ function writeUserConfig(patch) {
3724
+ const current = readUserConfig();
3725
+ const merged = deepMerge(current, patch);
3726
+ const path = _configPath();
3727
+ const dir = dirname2(path);
3728
+ if (!existsSync10(dir))
3729
+ mkdirSync2(dir, { recursive: true });
3730
+ const tmp = `${path}.tmp.${process.pid}`;
3731
+ writeFileSync6(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
3732
+ renameSync2(tmp, path);
3733
+ _cache = merged;
3734
+ return merged;
3735
+ }
3736
+ function getEmbeddingsEnabled() {
3737
+ const cfg = readUserConfig();
3738
+ if (cfg.embeddings && typeof cfg.embeddings.enabled === "boolean") {
3739
+ return cfg.embeddings.enabled;
3740
+ }
3741
+ if (_migrated) {
3742
+ return migrationValueFromEnv();
3743
+ }
3744
+ _migrated = true;
3745
+ const enabled = migrationValueFromEnv();
3746
+ try {
3747
+ writeUserConfig({ embeddings: { enabled } });
3748
+ } catch {
3749
+ _cache = { ...cfg ?? {}, embeddings: { ...cfg?.embeddings ?? {}, enabled } };
3750
+ }
3751
+ return enabled;
3752
+ }
3753
+ function migrationValueFromEnv() {
3754
+ const raw = process.env.HIVEMIND_EMBEDDINGS;
3755
+ if (raw === void 0)
3756
+ return false;
3757
+ if (raw === "false")
3758
+ return false;
3759
+ return true;
3760
+ }
3761
+ function setEmbeddingsEnabled(enabled) {
3762
+ writeUserConfig({ embeddings: { enabled } });
3763
+ }
3764
+ function isPlainObject(value) {
3765
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3766
+ }
3767
+ function deepMerge(base, patch) {
3768
+ const out = { ...base };
3769
+ for (const key of Object.keys(patch)) {
3770
+ const patchVal = patch[key];
3771
+ const baseVal = base[key];
3772
+ if (isPlainObject(patchVal) && isPlainObject(baseVal)) {
3773
+ out[key] = { ...baseVal, ...patchVal };
3774
+ } else if (patchVal !== void 0) {
3775
+ out[key] = patchVal;
3776
+ }
3777
+ }
3778
+ return out;
3779
+ }
3780
+
3781
+ // dist/src/cli/embeddings.js
3782
+ var SHARED_DIR = join12(HOME, ".hivemind", "embed-deps");
3783
+ var SHARED_NODE_MODULES = join12(SHARED_DIR, "node_modules");
3784
+ var SHARED_DAEMON_PATH = join12(SHARED_DIR, "embed-daemon.js");
3690
3785
  var TRANSFORMERS_PKG = "@huggingface/transformers";
3691
3786
  var TRANSFORMERS_RANGE = "^3.0.0";
3692
3787
  function findHivemindInstalls(home = HOME) {
3693
3788
  const out = [];
3694
3789
  const fixed = [
3695
- { id: "codex", pluginDir: join11(home, ".codex", "hivemind") },
3696
- { id: "cursor", pluginDir: join11(home, ".cursor", "hivemind") },
3697
- { id: "hermes", pluginDir: join11(home, ".hermes", "hivemind") }
3790
+ { id: "codex", pluginDir: join12(home, ".codex", "hivemind") },
3791
+ { id: "cursor", pluginDir: join12(home, ".cursor", "hivemind") },
3792
+ { id: "hermes", pluginDir: join12(home, ".hermes", "hivemind") }
3698
3793
  ];
3699
3794
  for (const inst of fixed) {
3700
- if (existsSync10(join11(inst.pluginDir, "bundle")))
3795
+ if (existsSync11(join12(inst.pluginDir, "bundle")))
3701
3796
  out.push(inst);
3702
3797
  }
3703
- const ccCache = join11(home, ".claude", "plugins", "cache", "hivemind", "hivemind");
3704
- if (existsSync10(ccCache)) {
3798
+ const ccCache = join12(home, ".claude", "plugins", "cache", "hivemind", "hivemind");
3799
+ if (existsSync11(ccCache)) {
3705
3800
  let entries = [];
3706
3801
  try {
3707
3802
  entries = readdirSync(ccCache);
3708
3803
  } catch {
3709
3804
  }
3710
3805
  for (const ver of entries) {
3711
- const dir = join11(ccCache, ver);
3806
+ const dir = join12(ccCache, ver);
3712
3807
  try {
3713
3808
  if (!statSync(dir).isDirectory())
3714
3809
  continue;
3715
3810
  } catch {
3716
3811
  continue;
3717
3812
  }
3718
- const candidates = [join11(dir, "bundle"), join11(dir, "claude-code", "bundle")];
3719
- if (candidates.some((p) => existsSync10(p))) {
3813
+ const candidates = [join12(dir, "bundle"), join12(dir, "claude-code", "bundle")];
3814
+ if (candidates.some((p) => existsSync11(p))) {
3720
3815
  out.push({ id: `claude (${ver})`, pluginDir: dir });
3721
3816
  }
3722
3817
  }
@@ -3724,10 +3819,10 @@ function findHivemindInstalls(home = HOME) {
3724
3819
  return out;
3725
3820
  }
3726
3821
  function isSharedDepsInstalled(sharedNodeModules = SHARED_NODE_MODULES) {
3727
- return existsSync10(join11(sharedNodeModules, TRANSFORMERS_PKG));
3822
+ return existsSync11(join12(sharedNodeModules, TRANSFORMERS_PKG));
3728
3823
  }
3729
3824
  function isSymlinkToSharedDeps(linkPath, sharedNodeModules) {
3730
- if (!existsSync10(linkPath))
3825
+ if (!existsSync11(linkPath))
3731
3826
  return false;
3732
3827
  try {
3733
3828
  if (!lstatSync2(linkPath).isSymbolicLink())
@@ -3738,8 +3833,8 @@ function isSymlinkToSharedDeps(linkPath, sharedNodeModules) {
3738
3833
  }
3739
3834
  }
3740
3835
  function linkStateFor(install, sharedNodeModules = SHARED_NODE_MODULES) {
3741
- const link = join11(install.pluginDir, "node_modules");
3742
- if (!existsSync10(link) && !isSymbolicLink(link))
3836
+ const link = join12(install.pluginDir, "node_modules");
3837
+ if (!existsSync11(link) && !isSymbolicLink(link))
3743
3838
  return { kind: "no-node-modules" };
3744
3839
  try {
3745
3840
  if (lstatSync2(link).isSymbolicLink()) {
@@ -3763,7 +3858,7 @@ function ensureSharedDeps() {
3763
3858
  log(` Embeddings installing ${TRANSFORMERS_PKG}@${TRANSFORMERS_RANGE} into ${SHARED_DIR}`);
3764
3859
  log(` (~600 MB; first install only \u2014 every agent will share this)`);
3765
3860
  ensureDir(SHARED_DIR);
3766
- writeJson(join11(SHARED_DIR, "package.json"), {
3861
+ writeJson(join12(SHARED_DIR, "package.json"), {
3767
3862
  name: "hivemind-embed-deps",
3768
3863
  version: "1.0.0",
3769
3864
  private: true,
@@ -3777,8 +3872,8 @@ function ensureSharedDeps() {
3777
3872
  log(` Embeddings shared deps already present at ${SHARED_DIR}`);
3778
3873
  }
3779
3874
  ensureDir(SHARED_DIR);
3780
- const src = join11(pkgRoot(), "embeddings", "embed-daemon.js");
3781
- if (existsSync10(src)) {
3875
+ const src = join12(pkgRoot(), "embeddings", "embed-daemon.js");
3876
+ if (existsSync11(src)) {
3782
3877
  copyFileSync3(src, SHARED_DAEMON_PATH);
3783
3878
  chmodSync(SHARED_DAEMON_PATH, 493);
3784
3879
  } else {
@@ -3786,40 +3881,115 @@ function ensureSharedDeps() {
3786
3881
  }
3787
3882
  }
3788
3883
  function linkAgent(install) {
3789
- const link = join11(install.pluginDir, "node_modules");
3884
+ const link = join12(install.pluginDir, "node_modules");
3885
+ const state = linkStateFor(install);
3886
+ if (state.kind === "owns-own-node-modules") {
3887
+ warn(` Embeddings ${install.id.padEnd(20)} owns its own node_modules \u2014 skipping symlink (status: owns-own-node-modules)`);
3888
+ return;
3889
+ }
3790
3890
  symlinkForce(SHARED_NODE_MODULES, link);
3791
3891
  log(` Embeddings linked ${install.id.padEnd(20)} -> shared deps`);
3792
3892
  }
3793
- function enableEmbeddings() {
3893
+ function installEmbeddings() {
3794
3894
  ensureSharedDeps();
3795
3895
  const installs = findHivemindInstalls();
3796
3896
  if (installs.length === 0) {
3797
3897
  warn(" Embeddings no hivemind installs detected \u2014 run `hivemind install` first");
3798
3898
  warn(" (the shared deps are in place; subsequent agent installs will pick them up if you re-run `hivemind embeddings install`)");
3799
- return;
3899
+ } else {
3900
+ for (const inst of installs)
3901
+ linkAgent(inst);
3902
+ }
3903
+ setEmbeddingsEnabled(true);
3904
+ log(` Embeddings enabled in ~/.deeplake/config.json`);
3905
+ log(` Embeddings ready. Restart your agents to pick up.`);
3906
+ }
3907
+ function enableEmbeddings() {
3908
+ setEmbeddingsEnabled(true);
3909
+ log(` Embeddings enabled in ~/.deeplake/config.json`);
3910
+ if (!isSharedDepsInstalled()) {
3911
+ warn(` Embeddings shared deps not installed yet \u2014 run \`hivemind embeddings install\` to download them`);
3912
+ } else {
3913
+ log(` Embeddings shared deps present \u2014 sessions will start producing embeddings on next restart`);
3800
3914
  }
3801
- for (const inst of installs)
3802
- linkAgent(inst);
3803
- log(` Embeddings enabled. Restart your agents to pick up.`);
3804
3915
  }
3805
- function disableEmbeddings(opts) {
3916
+ function uninstallEmbeddings(opts) {
3806
3917
  const installs = findHivemindInstalls();
3807
3918
  for (const inst of installs) {
3808
- const link = join11(inst.pluginDir, "node_modules");
3919
+ const link = join12(inst.pluginDir, "node_modules");
3809
3920
  if (isSymlinkToSharedDeps(link, SHARED_NODE_MODULES)) {
3810
3921
  unlinkSync5(link);
3811
3922
  log(` Embeddings unlinked ${inst.id}`);
3812
3923
  }
3813
3924
  }
3814
- if (opts?.prune && existsSync10(SHARED_DIR)) {
3925
+ if (opts?.prune && existsSync11(SHARED_DIR)) {
3815
3926
  rmSync4(SHARED_DIR, { recursive: true, force: true });
3816
3927
  log(` Embeddings pruned ${SHARED_DIR}`);
3817
3928
  }
3929
+ setEmbeddingsEnabled(false);
3930
+ killEmbedDaemon();
3931
+ log(` Embeddings disabled in ~/.deeplake/config.json`);
3932
+ }
3933
+ function disableEmbeddings() {
3934
+ setEmbeddingsEnabled(false);
3935
+ killEmbedDaemon();
3936
+ log(` Embeddings disabled in ~/.deeplake/config.json`);
3937
+ log(` Embeddings daemon terminated; shared deps preserved (run \`hivemind embeddings uninstall\` to remove)`);
3938
+ }
3939
+ function killEmbedDaemon(socketDir) {
3940
+ const uid = typeof process.getuid === "function" ? process.getuid() : userInfo().uid;
3941
+ const pidPath = pidPathFor(String(uid), socketDir);
3942
+ const sockPath = socketPathFor(String(uid), socketDir);
3943
+ let pid = null;
3944
+ try {
3945
+ pid = Number.parseInt(readFileSync9(pidPath, "utf-8").trim(), 10);
3946
+ } catch {
3947
+ }
3948
+ if (pid !== null && Number.isFinite(pid) && _isDaemonAliveOnSocket(sockPath)) {
3949
+ try {
3950
+ process.kill(pid, "SIGTERM");
3951
+ } catch {
3952
+ }
3953
+ } else if (pid !== null) {
3954
+ log(` Embeddings pidfile present but socket dead \u2014 skipping SIGTERM on possibly-stale pid ${pid}`);
3955
+ }
3956
+ try {
3957
+ unlinkSync5(sockPath);
3958
+ } catch {
3959
+ }
3960
+ try {
3961
+ unlinkSync5(pidPath);
3962
+ } catch {
3963
+ }
3964
+ }
3965
+ function _isDaemonAliveOnSocket(sockPath, timeoutMs = 200) {
3966
+ if (!existsSync11(sockPath))
3967
+ return false;
3968
+ try {
3969
+ const child = spawnSync("node", [
3970
+ "-e",
3971
+ `const n=require("node:net");const s=n.connect(${JSON.stringify(sockPath)});s.once("connect",()=>{s.end();process.exit(0)});s.once("error",()=>process.exit(2));setTimeout(()=>process.exit(3),${timeoutMs});`
3972
+ ], { timeout: timeoutMs + 1e3, stdio: "ignore" });
3973
+ return child.status === 0;
3974
+ } catch {
3975
+ return false;
3976
+ }
3818
3977
  }
3819
3978
  function statusEmbeddings() {
3979
+ const enabled = getEmbeddingsEnabled();
3980
+ log(`Config: ~/.deeplake/config.json embeddings.enabled = ${enabled}`);
3820
3981
  log(`Shared deps: ${SHARED_DIR}`);
3821
3982
  log(`Installed: ${isSharedDepsInstalled() ? "yes" : "no"}`);
3822
- log(`Daemon: ${existsSync10(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : "(not present)"}`);
3983
+ log(`Daemon: ${existsSync11(SHARED_DAEMON_PATH) ? SHARED_DAEMON_PATH : "(not present)"}`);
3984
+ if (!enabled) {
3985
+ log("");
3986
+ log(`Embeddings are DISABLED in user config. Run \`hivemind embeddings enable\` to opt in,`);
3987
+ log(`or \`hivemind embeddings install\` if the shared deps are not yet downloaded.`);
3988
+ } else if (!isSharedDepsInstalled()) {
3989
+ log("");
3990
+ warn(`Embeddings are enabled in config but shared deps are missing.`);
3991
+ warn(`Run \`hivemind embeddings install\` to download @huggingface/transformers.`);
3992
+ }
3823
3993
  log("");
3824
3994
  log(`Agent installs:`);
3825
3995
  const installs = findHivemindInstalls();
@@ -3835,7 +4005,7 @@ function statusEmbeddings() {
3835
4005
  label = "\u2713 linked \u2192 shared";
3836
4006
  break;
3837
4007
  case "no-node-modules":
3838
- label = "\u2717 not linked (embeddings disabled)";
4008
+ label = "\u2717 not linked";
3839
4009
  break;
3840
4010
  case "owns-own-node-modules":
3841
4011
  label = "\u25B3 has its own node_modules (not shared)";
@@ -3850,8 +4020,8 @@ function statusEmbeddings() {
3850
4020
  }
3851
4021
 
3852
4022
  // dist/src/cli/auth.js
3853
- import { existsSync as existsSync11 } from "node:fs";
3854
- import { join as join13 } from "node:path";
4023
+ import { existsSync as existsSync12 } from "node:fs";
4024
+ import { join as join14 } from "node:path";
3855
4025
 
3856
4026
  // dist/src/commands/auth.js
3857
4027
  import { execSync } from "node:child_process";
@@ -3866,25 +4036,25 @@ function deeplakeClientHeader() {
3866
4036
  }
3867
4037
 
3868
4038
  // dist/src/commands/auth-creds.js
3869
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync2, unlinkSync as unlinkSync6 } from "node:fs";
3870
- import { join as join12 } from "node:path";
3871
- import { homedir as homedir4 } from "node:os";
4039
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync3, unlinkSync as unlinkSync6 } from "node:fs";
4040
+ import { join as join13 } from "node:path";
4041
+ import { homedir as homedir5 } from "node:os";
3872
4042
  function configDir() {
3873
- return join12(homedir4(), ".deeplake");
4043
+ return join13(homedir5(), ".deeplake");
3874
4044
  }
3875
4045
  function credsPath() {
3876
- return join12(configDir(), "credentials.json");
4046
+ return join13(configDir(), "credentials.json");
3877
4047
  }
3878
4048
  function loadCredentials() {
3879
4049
  try {
3880
- return JSON.parse(readFileSync8(credsPath(), "utf-8"));
4050
+ return JSON.parse(readFileSync10(credsPath(), "utf-8"));
3881
4051
  } catch {
3882
4052
  return null;
3883
4053
  }
3884
4054
  }
3885
4055
  function saveCredentials(creds) {
3886
- mkdirSync2(configDir(), { recursive: true, mode: 448 });
3887
- writeFileSync6(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
4056
+ mkdirSync3(configDir(), { recursive: true, mode: 448 });
4057
+ writeFileSync7(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
3888
4058
  }
3889
4059
  function deleteCredentials() {
3890
4060
  try {
@@ -4073,9 +4243,9 @@ Using: ${orgName}
4073
4243
  }
4074
4244
 
4075
4245
  // dist/src/cli/auth.js
4076
- var CREDS_PATH = join13(HOME, ".deeplake", "credentials.json");
4246
+ var CREDS_PATH = join14(HOME, ".deeplake", "credentials.json");
4077
4247
  function isLoggedIn() {
4078
- return existsSync11(CREDS_PATH) && loadCredentials() !== null;
4248
+ return existsSync12(CREDS_PATH) && loadCredentials() !== null;
4079
4249
  }
4080
4250
  async function ensureLoggedIn() {
4081
4251
  if (isLoggedIn())
@@ -4108,16 +4278,16 @@ async function maybeShowOrgChoice() {
4108
4278
  }
4109
4279
 
4110
4280
  // dist/src/config.js
4111
- import { readFileSync as readFileSync9, existsSync as existsSync12 } from "node:fs";
4112
- import { join as join14 } from "node:path";
4113
- import { homedir as homedir5, userInfo } from "node:os";
4281
+ import { readFileSync as readFileSync11, existsSync as existsSync13 } from "node:fs";
4282
+ import { join as join15 } from "node:path";
4283
+ import { homedir as homedir6, userInfo as userInfo2 } from "node:os";
4114
4284
  function loadConfig() {
4115
- const home = homedir5();
4116
- const credPath = join14(home, ".deeplake", "credentials.json");
4285
+ const home = homedir6();
4286
+ const credPath = join15(home, ".deeplake", "credentials.json");
4117
4287
  let creds = null;
4118
- if (existsSync12(credPath)) {
4288
+ if (existsSync13(credPath)) {
4119
4289
  try {
4120
- creds = JSON.parse(readFileSync9(credPath, "utf-8"));
4290
+ creds = JSON.parse(readFileSync11(credPath, "utf-8"));
4121
4291
  } catch {
4122
4292
  return null;
4123
4293
  }
@@ -4130,13 +4300,13 @@ function loadConfig() {
4130
4300
  token,
4131
4301
  orgId,
4132
4302
  orgName: creds?.orgName ?? orgId,
4133
- userName: creds?.userName || userInfo().username || "unknown",
4303
+ userName: creds?.userName || userInfo2().username || "unknown",
4134
4304
  workspaceId: process.env.HIVEMIND_WORKSPACE_ID ?? creds?.workspaceId ?? "default",
4135
4305
  apiUrl: process.env.HIVEMIND_API_URL ?? creds?.apiUrl ?? "https://api.deeplake.ai",
4136
4306
  tableName: process.env.HIVEMIND_TABLE ?? "memory",
4137
4307
  sessionsTableName: process.env.HIVEMIND_SESSIONS_TABLE ?? "sessions",
4138
4308
  skillsTableName: process.env.HIVEMIND_SKILLS_TABLE ?? "skills",
4139
- memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join14(home, ".deeplake", "memory")
4309
+ memoryPath: process.env.HIVEMIND_MEMORY_PATH ?? join15(home, ".deeplake", "memory")
4140
4310
  };
4141
4311
  }
4142
4312
 
@@ -4145,9 +4315,9 @@ import { randomUUID } from "node:crypto";
4145
4315
 
4146
4316
  // dist/src/utils/debug.js
4147
4317
  import { appendFileSync } from "node:fs";
4148
- import { join as join15 } from "node:path";
4149
- import { homedir as homedir6 } from "node:os";
4150
- var LOG = join15(homedir6(), ".deeplake", "hook-debug.log");
4318
+ import { join as join16 } from "node:path";
4319
+ import { homedir as homedir7 } from "node:os";
4320
+ var LOG = join16(homedir7(), ".deeplake", "hook-debug.log");
4151
4321
  function isDebug() {
4152
4322
  return process.env.HIVEMIND_DEBUG === "1";
4153
4323
  }
@@ -4173,6 +4343,107 @@ function sqlIdent(name) {
4173
4343
  var SUMMARY_EMBEDDING_COL = "summary_embedding";
4174
4344
  var MESSAGE_EMBEDDING_COL = "message_embedding";
4175
4345
 
4346
+ // dist/src/notifications/queue.js
4347
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, renameSync as renameSync3, mkdirSync as mkdirSync4, openSync, closeSync, unlinkSync as unlinkSync7, statSync as statSync2 } from "node:fs";
4348
+ import { join as join17, resolve } from "node:path";
4349
+ import { homedir as homedir8 } from "node:os";
4350
+ import { setTimeout as sleep } from "node:timers/promises";
4351
+ var log3 = (msg) => log2("notifications-queue", msg);
4352
+ var LOCK_RETRY_MAX = 50;
4353
+ var LOCK_RETRY_BASE_MS = 5;
4354
+ var LOCK_STALE_MS = 5e3;
4355
+ function queuePath() {
4356
+ return join17(homedir8(), ".deeplake", "notifications-queue.json");
4357
+ }
4358
+ function lockPath() {
4359
+ return `${queuePath()}.lock`;
4360
+ }
4361
+ function readQueue() {
4362
+ try {
4363
+ const raw = readFileSync12(queuePath(), "utf-8");
4364
+ const parsed = JSON.parse(raw);
4365
+ if (!parsed || !Array.isArray(parsed.queue)) {
4366
+ log3(`queue malformed \u2192 treating as empty`);
4367
+ return { queue: [] };
4368
+ }
4369
+ return { queue: parsed.queue };
4370
+ } catch {
4371
+ return { queue: [] };
4372
+ }
4373
+ }
4374
+ function _isQueuePathInsideHome(path, home) {
4375
+ const r = resolve(path);
4376
+ const h = resolve(home);
4377
+ return r.startsWith(h + "/") || r === h;
4378
+ }
4379
+ function writeQueue(q) {
4380
+ const path = queuePath();
4381
+ const home = resolve(homedir8());
4382
+ if (!_isQueuePathInsideHome(path, home)) {
4383
+ throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
4384
+ }
4385
+ mkdirSync4(join17(home, ".deeplake"), { recursive: true, mode: 448 });
4386
+ const tmp = `${path}.${process.pid}.tmp`;
4387
+ writeFileSync8(tmp, JSON.stringify(q, null, 2), { mode: 384 });
4388
+ renameSync3(tmp, path);
4389
+ }
4390
+ async function withQueueLock(fn) {
4391
+ const path = lockPath();
4392
+ mkdirSync4(join17(homedir8(), ".deeplake"), { recursive: true, mode: 448 });
4393
+ let fd = null;
4394
+ for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
4395
+ try {
4396
+ fd = openSync(path, "wx", 384);
4397
+ break;
4398
+ } catch (e) {
4399
+ const code = e.code;
4400
+ if (code !== "EEXIST")
4401
+ throw e;
4402
+ try {
4403
+ const age = Date.now() - statSync2(path).mtimeMs;
4404
+ if (age > LOCK_STALE_MS) {
4405
+ unlinkSync7(path);
4406
+ continue;
4407
+ }
4408
+ } catch {
4409
+ }
4410
+ const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
4411
+ await sleep(delay);
4412
+ }
4413
+ }
4414
+ if (fd === null) {
4415
+ log3(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
4416
+ return fn();
4417
+ }
4418
+ try {
4419
+ return fn();
4420
+ } finally {
4421
+ try {
4422
+ closeSync(fd);
4423
+ } catch {
4424
+ }
4425
+ try {
4426
+ unlinkSync7(path);
4427
+ } catch {
4428
+ }
4429
+ }
4430
+ }
4431
+ function sameDedupKey(a, b) {
4432
+ if (a.id !== b.id)
4433
+ return false;
4434
+ return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
4435
+ }
4436
+ async function enqueueNotification(n) {
4437
+ await withQueueLock(() => {
4438
+ const q = readQueue();
4439
+ if (q.queue.some((existing) => sameDedupKey(existing, n))) {
4440
+ return;
4441
+ }
4442
+ q.queue.push(n);
4443
+ writeQueue(q);
4444
+ });
4445
+ }
4446
+
4176
4447
  // dist/src/deeplake-api.js
4177
4448
  var indexMarkerStorePromise = null;
4178
4449
  function getIndexMarkerStore() {
@@ -4180,7 +4451,7 @@ function getIndexMarkerStore() {
4180
4451
  indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
4181
4452
  return indexMarkerStorePromise;
4182
4453
  }
4183
- var log3 = (msg) => log2("sdk", msg);
4454
+ var log4 = (msg) => log2("sdk", msg);
4184
4455
  function summarizeSql(sql, maxLen = 220) {
4185
4456
  const compact = sql.replace(/\s+/g, " ").trim();
4186
4457
  return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
@@ -4192,7 +4463,38 @@ function traceSql(msg) {
4192
4463
  process.stderr.write(`[deeplake-sql] ${msg}
4193
4464
  `);
4194
4465
  if (process.env.HIVEMIND_DEBUG === "1")
4195
- log3(msg);
4466
+ log4(msg);
4467
+ }
4468
+ var _signalledBalanceExhausted = false;
4469
+ function maybeSignalBalanceExhausted(status, bodyText) {
4470
+ if (status !== 402)
4471
+ return;
4472
+ if (!bodyText.includes("balance_cents"))
4473
+ return;
4474
+ if (_signalledBalanceExhausted)
4475
+ return;
4476
+ _signalledBalanceExhausted = true;
4477
+ log4(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
4478
+ enqueueNotification({
4479
+ id: "balance-exhausted",
4480
+ severity: "warn",
4481
+ transient: true,
4482
+ title: "Hivemind credits exhausted \u2014 top up to keep capturing",
4483
+ body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
4484
+ dedupKey: { reason: "balance-zero" }
4485
+ }).catch((e) => {
4486
+ log4(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
4487
+ });
4488
+ }
4489
+ function billingUrl() {
4490
+ try {
4491
+ const c = loadCredentials();
4492
+ if (c?.orgName && c?.workspaceId) {
4493
+ return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
4494
+ }
4495
+ } catch {
4496
+ }
4497
+ return "https://deeplake.ai";
4196
4498
  }
4197
4499
  var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
4198
4500
  var MAX_RETRIES = 3;
@@ -4201,8 +4503,8 @@ var MAX_CONCURRENCY = 5;
4201
4503
  function getQueryTimeoutMs() {
4202
4504
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
4203
4505
  }
4204
- function sleep(ms) {
4205
- return new Promise((resolve) => setTimeout(resolve, ms));
4506
+ function sleep2(ms) {
4507
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
4206
4508
  }
4207
4509
  function isTimeoutError(error) {
4208
4510
  const name = error instanceof Error ? error.name.toLowerCase() : "";
@@ -4232,7 +4534,7 @@ var Semaphore = class {
4232
4534
  this.active++;
4233
4535
  return;
4234
4536
  }
4235
- await new Promise((resolve) => this.waiting.push(resolve));
4537
+ await new Promise((resolve2) => this.waiting.push(resolve2));
4236
4538
  }
4237
4539
  release() {
4238
4540
  this.active--;
@@ -4303,8 +4605,8 @@ var DeeplakeApi = class {
4303
4605
  lastError = e instanceof Error ? e : new Error(String(e));
4304
4606
  if (attempt < MAX_RETRIES) {
4305
4607
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
4306
- log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
4307
- await sleep(delay);
4608
+ log4(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
4609
+ await sleep2(delay);
4308
4610
  continue;
4309
4611
  }
4310
4612
  throw lastError;
@@ -4320,10 +4622,11 @@ var DeeplakeApi = class {
4320
4622
  const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
4321
4623
  if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
4322
4624
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
4323
- log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
4324
- await sleep(delay);
4625
+ log4(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
4626
+ await sleep2(delay);
4325
4627
  continue;
4326
4628
  }
4629
+ maybeSignalBalanceExhausted(resp.status, text);
4327
4630
  throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
4328
4631
  }
4329
4632
  throw lastError ?? new Error("Query failed: max retries exceeded");
@@ -4344,7 +4647,7 @@ var DeeplakeApi = class {
4344
4647
  const chunk = rows.slice(i, i + CONCURRENCY);
4345
4648
  await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
4346
4649
  }
4347
- log3(`commit: ${rows.length} rows`);
4650
+ log4(`commit: ${rows.length} rows`);
4348
4651
  }
4349
4652
  async upsertRowSql(row) {
4350
4653
  const ts = (/* @__PURE__ */ new Date()).toISOString();
@@ -4400,7 +4703,7 @@ var DeeplakeApi = class {
4400
4703
  markers.writeIndexMarker(markerPath);
4401
4704
  return;
4402
4705
  }
4403
- log3(`index "${indexName}" skipped: ${e.message}`);
4706
+ log4(`index "${indexName}" skipped: ${e.message}`);
4404
4707
  }
4405
4708
  }
4406
4709
  /**
@@ -4490,13 +4793,13 @@ var DeeplakeApi = class {
4490
4793
  };
4491
4794
  }
4492
4795
  if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
4493
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
4796
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
4494
4797
  continue;
4495
4798
  }
4496
4799
  return { tables: [], cacheable: false };
4497
4800
  } catch {
4498
4801
  if (attempt < MAX_RETRIES) {
4499
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt));
4802
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
4500
4803
  continue;
4501
4804
  }
4502
4805
  return { tables: [], cacheable: false };
@@ -4524,9 +4827,9 @@ var DeeplakeApi = class {
4524
4827
  } catch (err) {
4525
4828
  lastErr = err;
4526
4829
  const msg = err instanceof Error ? err.message : String(err);
4527
- log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
4830
+ log4(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
4528
4831
  if (attempt < OUTER_BACKOFFS_MS.length) {
4529
- await sleep(OUTER_BACKOFFS_MS[attempt]);
4832
+ await sleep2(OUTER_BACKOFFS_MS[attempt]);
4530
4833
  }
4531
4834
  }
4532
4835
  }
@@ -4537,9 +4840,9 @@ var DeeplakeApi = class {
4537
4840
  const tbl = sqlIdent(name ?? this.tableName);
4538
4841
  const tables = await this.listTables();
4539
4842
  if (!tables.includes(tbl)) {
4540
- log3(`table "${tbl}" not found, creating`);
4843
+ log4(`table "${tbl}" not found, creating`);
4541
4844
  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);
4542
- log3(`table "${tbl}" created`);
4845
+ log4(`table "${tbl}" created`);
4543
4846
  if (!tables.includes(tbl))
4544
4847
  this._tablesCache = [...tables, tbl];
4545
4848
  }
@@ -4552,9 +4855,9 @@ var DeeplakeApi = class {
4552
4855
  const safe = sqlIdent(name);
4553
4856
  const tables = await this.listTables();
4554
4857
  if (!tables.includes(safe)) {
4555
- log3(`table "${safe}" not found, creating`);
4858
+ log4(`table "${safe}" not found, creating`);
4556
4859
  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);
4557
- log3(`table "${safe}" created`);
4860
+ log4(`table "${safe}" created`);
4558
4861
  if (!tables.includes(safe))
4559
4862
  this._tablesCache = [...tables, safe];
4560
4863
  }
@@ -4577,9 +4880,9 @@ var DeeplakeApi = class {
4577
4880
  const safe = sqlIdent(name);
4578
4881
  const tables = await this.listTables();
4579
4882
  if (!tables.includes(safe)) {
4580
- log3(`table "${safe}" not found, creating`);
4883
+ log4(`table "${safe}" not found, creating`);
4581
4884
  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);
4582
- log3(`table "${safe}" created`);
4885
+ log4(`table "${safe}" created`);
4583
4886
  if (!tables.includes(safe))
4584
4887
  this._tablesCache = [...tables, safe];
4585
4888
  }
@@ -4610,10 +4913,10 @@ function parseArgs(argv) {
4610
4913
  }
4611
4914
  function confirm(message) {
4612
4915
  const rl = createInterface({ input: process.stdin, output: process.stderr });
4613
- return new Promise((resolve) => {
4916
+ return new Promise((resolve2) => {
4614
4917
  rl.question(`${message} [y/N] `, (answer) => {
4615
4918
  rl.close();
4616
- resolve(answer.trim().toLowerCase() === "y");
4919
+ resolve2(answer.trim().toLowerCase() === "y");
4617
4920
  });
4618
4921
  });
4619
4922
  }
@@ -4915,34 +5218,34 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
4915
5218
  }
4916
5219
 
4917
5220
  // dist/src/commands/skillify.js
4918
- import { readdirSync as readdirSync5, existsSync as existsSync25, readFileSync as readFileSync18, mkdirSync as mkdirSync10, renameSync as renameSync5 } from "node:fs";
4919
- import { homedir as homedir18 } from "node:os";
4920
- import { dirname as dirname6, join as join28 } from "node:path";
5221
+ import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as readFileSync21, mkdirSync as mkdirSync12, renameSync as renameSync7 } from "node:fs";
5222
+ import { homedir as homedir20 } from "node:os";
5223
+ import { dirname as dirname7, join as join30 } from "node:path";
4921
5224
 
4922
5225
  // dist/src/skillify/scope-config.js
4923
- import { existsSync as existsSync15, mkdirSync as mkdirSync4, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
4924
- import { homedir as homedir8 } from "node:os";
4925
- import { join as join18 } from "node:path";
5226
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
5227
+ import { homedir as homedir10 } from "node:os";
5228
+ import { join as join20 } from "node:path";
4926
5229
 
4927
5230
  // dist/src/skillify/legacy-migration.js
4928
- import { existsSync as existsSync14, renameSync as renameSync2 } from "node:fs";
4929
- import { homedir as homedir7 } from "node:os";
4930
- import { join as join17 } from "node:path";
5231
+ import { existsSync as existsSync15, renameSync as renameSync4 } from "node:fs";
5232
+ import { homedir as homedir9 } from "node:os";
5233
+ import { join as join19 } from "node:path";
4931
5234
  var dlog = (msg) => log2("skillify-migrate", msg);
4932
5235
  var attempted = false;
4933
5236
  function migrateLegacyStateDir() {
4934
5237
  if (attempted)
4935
5238
  return;
4936
5239
  attempted = true;
4937
- const root = join17(homedir7(), ".deeplake", "state");
4938
- const legacy = join17(root, "skilify");
4939
- const current = join17(root, "skillify");
4940
- if (!existsSync14(legacy))
5240
+ const root = join19(homedir9(), ".deeplake", "state");
5241
+ const legacy = join19(root, "skilify");
5242
+ const current = join19(root, "skillify");
5243
+ if (!existsSync15(legacy))
4941
5244
  return;
4942
- if (existsSync14(current))
5245
+ if (existsSync15(current))
4943
5246
  return;
4944
5247
  try {
4945
- renameSync2(legacy, current);
5248
+ renameSync4(legacy, current);
4946
5249
  dlog(`migrated ${legacy} -> ${current}`);
4947
5250
  } catch (err) {
4948
5251
  const code = err.code;
@@ -4955,15 +5258,15 @@ function migrateLegacyStateDir() {
4955
5258
  }
4956
5259
 
4957
5260
  // dist/src/skillify/scope-config.js
4958
- var STATE_DIR = join18(homedir8(), ".deeplake", "state", "skillify");
4959
- var CONFIG_PATH2 = join18(STATE_DIR, "config.json");
5261
+ var STATE_DIR = join20(homedir10(), ".deeplake", "state", "skillify");
5262
+ var CONFIG_PATH2 = join20(STATE_DIR, "config.json");
4960
5263
  var DEFAULT = { scope: "me", team: [], install: "project" };
4961
5264
  function loadScopeConfig() {
4962
5265
  migrateLegacyStateDir();
4963
- if (!existsSync15(CONFIG_PATH2))
5266
+ if (!existsSync16(CONFIG_PATH2))
4964
5267
  return DEFAULT;
4965
5268
  try {
4966
- const raw = JSON.parse(readFileSync11(CONFIG_PATH2, "utf-8"));
5269
+ const raw = JSON.parse(readFileSync14(CONFIG_PATH2, "utf-8"));
4967
5270
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
4968
5271
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
4969
5272
  const install = raw.install === "global" ? "global" : "project";
@@ -4974,19 +5277,19 @@ function loadScopeConfig() {
4974
5277
  }
4975
5278
  function saveScopeConfig(cfg) {
4976
5279
  migrateLegacyStateDir();
4977
- mkdirSync4(STATE_DIR, { recursive: true });
4978
- writeFileSync8(CONFIG_PATH2, JSON.stringify(cfg, null, 2));
5280
+ mkdirSync6(STATE_DIR, { recursive: true });
5281
+ writeFileSync10(CONFIG_PATH2, JSON.stringify(cfg, null, 2));
4979
5282
  }
4980
5283
 
4981
5284
  // dist/src/skillify/pull.js
4982
- import { existsSync as existsSync19, readFileSync as readFileSync14, writeFileSync as writeFileSync11, mkdirSync as mkdirSync7, renameSync as renameSync4, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync8 } from "node:fs";
4983
- import { homedir as homedir12 } from "node:os";
4984
- import { dirname as dirname3, join as join22 } from "node:path";
5285
+ import { existsSync as existsSync20, readFileSync as readFileSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9, renameSync as renameSync6, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync9 } from "node:fs";
5286
+ import { homedir as homedir14 } from "node:os";
5287
+ import { dirname as dirname4, join as join24 } from "node:path";
4985
5288
 
4986
5289
  // dist/src/skillify/skill-writer.js
4987
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync12, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync9 } from "node:fs";
4988
- import { homedir as homedir9 } from "node:os";
4989
- import { join as join19 } from "node:path";
5290
+ import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
5291
+ import { homedir as homedir11 } from "node:os";
5292
+ import { join as join21 } from "node:path";
4990
5293
  function assertValidSkillName(name) {
4991
5294
  if (typeof name !== "string" || name.length === 0) {
4992
5295
  throw new Error(`invalid skill name: empty or non-string`);
@@ -5002,10 +5305,10 @@ function assertValidSkillName(name) {
5002
5305
  }
5003
5306
  }
5004
5307
  function skillDir(skillsRoot, name) {
5005
- return join19(skillsRoot, name);
5308
+ return join21(skillsRoot, name);
5006
5309
  }
5007
5310
  function skillPath(skillsRoot, name) {
5008
- return join19(skillDir(skillsRoot, name), "SKILL.md");
5311
+ return join21(skillDir(skillsRoot, name), "SKILL.md");
5009
5312
  }
5010
5313
  function renderFrontmatter(fm) {
5011
5314
  const lines = ["---"];
@@ -5083,10 +5386,10 @@ function writeNewSkill(args) {
5083
5386
  assertValidSkillName(args.name);
5084
5387
  const dir = skillDir(args.skillsRoot, args.name);
5085
5388
  const path = skillPath(args.skillsRoot, args.name);
5086
- if (existsSync16(path)) {
5389
+ if (existsSync17(path)) {
5087
5390
  throw new Error(`skill already exists at ${path}; use mergeSkill`);
5088
5391
  }
5089
- mkdirSync5(dir, { recursive: true });
5392
+ mkdirSync7(dir, { recursive: true });
5090
5393
  const now = (/* @__PURE__ */ new Date()).toISOString();
5091
5394
  const author = args.author && args.author.length > 0 ? args.author : void 0;
5092
5395
  const contributors = author ? [author] : [];
@@ -5106,7 +5409,7 @@ function writeNewSkill(args) {
5106
5409
 
5107
5410
  ${args.body.trim()}
5108
5411
  `;
5109
- writeFileSync9(path, text);
5412
+ writeFileSync11(path, text);
5110
5413
  return {
5111
5414
  path,
5112
5415
  action: "created",
@@ -5118,41 +5421,41 @@ ${args.body.trim()}
5118
5421
  };
5119
5422
  }
5120
5423
  function listSkills(skillsRoot) {
5121
- if (!existsSync16(skillsRoot))
5424
+ if (!existsSync17(skillsRoot))
5122
5425
  return [];
5123
5426
  const out = [];
5124
5427
  for (const name of readdirSync2(skillsRoot)) {
5125
- const skillFile = join19(skillsRoot, name, "SKILL.md");
5126
- if (existsSync16(skillFile) && statSync2(skillFile).isFile()) {
5127
- out.push({ name, body: readFileSync12(skillFile, "utf-8") });
5428
+ const skillFile = join21(skillsRoot, name, "SKILL.md");
5429
+ if (existsSync17(skillFile) && statSync3(skillFile).isFile()) {
5430
+ out.push({ name, body: readFileSync15(skillFile, "utf-8") });
5128
5431
  }
5129
5432
  }
5130
5433
  return out;
5131
5434
  }
5132
5435
  function resolveSkillsRoot(install, cwd) {
5133
5436
  if (install === "global") {
5134
- return join19(homedir9(), ".claude", "skills");
5437
+ return join21(homedir11(), ".claude", "skills");
5135
5438
  }
5136
- return join19(cwd, ".claude", "skills");
5439
+ return join21(cwd, ".claude", "skills");
5137
5440
  }
5138
5441
 
5139
5442
  // dist/src/skillify/manifest.js
5140
- import { existsSync as existsSync17, lstatSync as lstatSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync13, renameSync as renameSync3, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "node:fs";
5141
- import { homedir as homedir10 } from "node:os";
5142
- import { dirname as dirname2, join as join20 } from "node:path";
5443
+ import { existsSync as existsSync18, lstatSync as lstatSync3, mkdirSync as mkdirSync8, readFileSync as readFileSync16, renameSync as renameSync5, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "node:fs";
5444
+ import { homedir as homedir12 } from "node:os";
5445
+ import { dirname as dirname3, join as join22 } from "node:path";
5143
5446
  function emptyManifest() {
5144
5447
  return { version: 1, entries: [] };
5145
5448
  }
5146
5449
  function manifestPath() {
5147
- return join20(homedir10(), ".deeplake", "state", "skillify", "pulled.json");
5450
+ return join22(homedir12(), ".deeplake", "state", "skillify", "pulled.json");
5148
5451
  }
5149
5452
  function loadManifest(path = manifestPath()) {
5150
5453
  migrateLegacyStateDir();
5151
- if (!existsSync17(path))
5454
+ if (!existsSync18(path))
5152
5455
  return emptyManifest();
5153
5456
  let raw;
5154
5457
  try {
5155
- raw = readFileSync13(path, "utf-8");
5458
+ raw = readFileSync16(path, "utf-8");
5156
5459
  } catch {
5157
5460
  return emptyManifest();
5158
5461
  }
@@ -5199,10 +5502,10 @@ function loadManifest(path = manifestPath()) {
5199
5502
  }
5200
5503
  function saveManifest(m, path = manifestPath()) {
5201
5504
  migrateLegacyStateDir();
5202
- mkdirSync6(dirname2(path), { recursive: true });
5505
+ mkdirSync8(dirname3(path), { recursive: true });
5203
5506
  const tmp = `${path}.tmp`;
5204
- writeFileSync10(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5205
- renameSync3(tmp, path);
5507
+ writeFileSync12(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5508
+ renameSync5(tmp, path);
5206
5509
  }
5207
5510
  function recordPull(entry, path = manifestPath()) {
5208
5511
  const m = loadManifest(path);
@@ -5234,7 +5537,7 @@ function unlinkSymlinks(paths) {
5234
5537
  if (!st.isSymbolicLink())
5235
5538
  continue;
5236
5539
  try {
5237
- unlinkSync7(path);
5540
+ unlinkSync8(path);
5238
5541
  } catch {
5239
5542
  }
5240
5543
  }
@@ -5244,7 +5547,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
5244
5547
  const live = [];
5245
5548
  let pruned = 0;
5246
5549
  for (const e of m.entries) {
5247
- if (existsSync17(join20(e.installRoot, e.dirName))) {
5550
+ if (existsSync18(join22(e.installRoot, e.dirName))) {
5248
5551
  live.push(e);
5249
5552
  continue;
5250
5553
  }
@@ -5257,26 +5560,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
5257
5560
  }
5258
5561
 
5259
5562
  // dist/src/skillify/agent-roots.js
5260
- import { existsSync as existsSync18 } from "node:fs";
5261
- import { homedir as homedir11 } from "node:os";
5262
- import { join as join21 } from "node:path";
5563
+ import { existsSync as existsSync19 } from "node:fs";
5564
+ import { homedir as homedir13 } from "node:os";
5565
+ import { join as join23 } from "node:path";
5263
5566
  function resolveDetected(home) {
5264
5567
  const out = [];
5265
- const codexInstalled = existsSync18(join21(home, ".codex"));
5266
- const piInstalled = existsSync18(join21(home, ".pi", "agent"));
5267
- const hermesInstalled = existsSync18(join21(home, ".hermes"));
5568
+ const codexInstalled = existsSync19(join23(home, ".codex"));
5569
+ const piInstalled = existsSync19(join23(home, ".pi", "agent"));
5570
+ const hermesInstalled = existsSync19(join23(home, ".hermes"));
5268
5571
  if (codexInstalled || piInstalled) {
5269
- out.push(join21(home, ".agents", "skills"));
5572
+ out.push(join23(home, ".agents", "skills"));
5270
5573
  }
5271
5574
  if (hermesInstalled) {
5272
- out.push(join21(home, ".hermes", "skills"));
5575
+ out.push(join23(home, ".hermes", "skills"));
5273
5576
  }
5274
5577
  if (piInstalled) {
5275
- out.push(join21(home, ".pi", "agent", "skills"));
5578
+ out.push(join23(home, ".pi", "agent", "skills"));
5276
5579
  }
5277
5580
  return out;
5278
5581
  }
5279
- function detectAgentSkillsRoots(canonicalRoot, home = homedir11()) {
5582
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir13()) {
5280
5583
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
5281
5584
  }
5282
5585
 
@@ -5320,15 +5623,15 @@ function isMissingTableError(message) {
5320
5623
  }
5321
5624
  function resolvePullDestination(install, cwd) {
5322
5625
  if (install === "global")
5323
- return join22(homedir12(), ".claude", "skills");
5626
+ return join24(homedir14(), ".claude", "skills");
5324
5627
  if (!cwd)
5325
5628
  throw new Error("install=project requires a cwd");
5326
- return join22(cwd, ".claude", "skills");
5629
+ return join24(cwd, ".claude", "skills");
5327
5630
  }
5328
5631
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5329
5632
  const out = [];
5330
5633
  for (const root of agentRoots) {
5331
- const link = join22(root, dirName);
5634
+ const link = join24(root, dirName);
5332
5635
  let existing;
5333
5636
  try {
5334
5637
  existing = lstatSync4(link);
@@ -5350,13 +5653,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5350
5653
  continue;
5351
5654
  }
5352
5655
  try {
5353
- unlinkSync8(link);
5656
+ unlinkSync9(link);
5354
5657
  } catch {
5355
5658
  continue;
5356
5659
  }
5357
5660
  }
5358
5661
  try {
5359
- mkdirSync7(dirname3(link), { recursive: true });
5662
+ mkdirSync9(dirname4(link), { recursive: true });
5360
5663
  symlinkSync2(canonicalDir, link, "dir");
5361
5664
  out.push(link);
5362
5665
  } catch {
@@ -5371,8 +5674,8 @@ function backfillSymlinks(installRoot) {
5371
5674
  return;
5372
5675
  const detected = detectAgentSkillsRoots(installRoot);
5373
5676
  for (const entry of entries) {
5374
- const canonical = join22(entry.installRoot, entry.dirName);
5375
- if (!existsSync19(canonical))
5677
+ const canonical = join24(entry.installRoot, entry.dirName);
5678
+ if (!existsSync20(canonical))
5376
5679
  continue;
5377
5680
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
5378
5681
  if (sameSorted(fresh, entry.symlinks))
@@ -5482,10 +5785,10 @@ function renderFrontmatter2(fm) {
5482
5785
  return lines.join("\n");
5483
5786
  }
5484
5787
  function readLocalVersion(path) {
5485
- if (!existsSync19(path))
5788
+ if (!existsSync20(path))
5486
5789
  return null;
5487
5790
  try {
5488
- const text = readFileSync14(path, "utf-8");
5791
+ const text = readFileSync17(path, "utf-8");
5489
5792
  const parsed = parseFrontmatter(text);
5490
5793
  if (!parsed)
5491
5794
  return null;
@@ -5580,8 +5883,8 @@ async function runPull(opts) {
5580
5883
  summary.skipped++;
5581
5884
  continue;
5582
5885
  }
5583
- const skillDir2 = join22(root, dirName);
5584
- const skillFile = join22(skillDir2, "SKILL.md");
5886
+ const skillDir2 = join24(root, dirName);
5887
+ const skillFile = join24(skillDir2, "SKILL.md");
5585
5888
  const remoteVersion = Number(row.version ?? 1);
5586
5889
  const localVersion = readLocalVersion(skillFile);
5587
5890
  const action = decideAction({
@@ -5592,14 +5895,14 @@ async function runPull(opts) {
5592
5895
  });
5593
5896
  let manifestError;
5594
5897
  if (action === "wrote") {
5595
- mkdirSync7(skillDir2, { recursive: true });
5596
- if (existsSync19(skillFile)) {
5898
+ mkdirSync9(skillDir2, { recursive: true });
5899
+ if (existsSync20(skillFile)) {
5597
5900
  try {
5598
- renameSync4(skillFile, `${skillFile}.bak`);
5901
+ renameSync6(skillFile, `${skillFile}.bak`);
5599
5902
  } catch {
5600
5903
  }
5601
5904
  }
5602
- writeFileSync11(skillFile, renderSkillFile(row));
5905
+ writeFileSync13(skillFile, renderSkillFile(row));
5603
5906
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
5604
5907
  try {
5605
5908
  recordPull({
@@ -5641,15 +5944,15 @@ async function runPull(opts) {
5641
5944
  }
5642
5945
 
5643
5946
  // dist/src/skillify/unpull.js
5644
- import { existsSync as existsSync20, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync3 } from "node:fs";
5645
- import { homedir as homedir13 } from "node:os";
5646
- import { join as join23 } from "node:path";
5947
+ import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
5948
+ import { homedir as homedir15 } from "node:os";
5949
+ import { join as join25 } from "node:path";
5647
5950
  function resolveUnpullRoot(install, cwd) {
5648
5951
  if (install === "global")
5649
- return join23(homedir13(), ".claude", "skills");
5952
+ return join25(homedir15(), ".claude", "skills");
5650
5953
  if (!cwd)
5651
5954
  throw new Error("cwd required when install === 'project'");
5652
- return join23(cwd, ".claude", "skills");
5955
+ return join25(cwd, ".claude", "skills");
5653
5956
  }
5654
5957
  function runUnpull(opts) {
5655
5958
  const root = resolveUnpullRoot(opts.install, opts.cwd);
@@ -5672,8 +5975,8 @@ function runUnpull(opts) {
5672
5975
  const entries = entriesForRoot(manifest, opts.install, root);
5673
5976
  for (const entry of entries) {
5674
5977
  summary.scanned++;
5675
- const path = join23(root, entry.dirName);
5676
- if (!existsSync20(path)) {
5978
+ const path = join25(root, entry.dirName);
5979
+ if (!existsSync21(path)) {
5677
5980
  if (!opts.dryRun) {
5678
5981
  unlinkSymlinks(entry.symlinks);
5679
5982
  removePullEntry(opts.install, entry.installRoot, entry.dirName);
@@ -5726,15 +6029,15 @@ function runUnpull(opts) {
5726
6029
  }
5727
6030
  summary.entries.push(result);
5728
6031
  }
5729
- if (existsSync20(root) && (opts.all || opts.legacyCleanup)) {
6032
+ if (existsSync21(root) && (opts.all || opts.legacyCleanup)) {
5730
6033
  const manifestDirNames = new Set(entries.map((e) => e.dirName));
5731
6034
  for (const dirName of readdirSync3(root)) {
5732
6035
  if (manifestDirNames.has(dirName))
5733
6036
  continue;
5734
- const path = join23(root, dirName);
6037
+ const path = join25(root, dirName);
5735
6038
  let st;
5736
6039
  try {
5737
- st = statSync3(path);
6040
+ st = statSync4(path);
5738
6041
  } catch {
5739
6042
  continue;
5740
6043
  }
@@ -5810,30 +6113,30 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
5810
6113
 
5811
6114
  // dist/src/commands/mine-local.js
5812
6115
  import { spawn } from "node:child_process";
5813
- import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
5814
- import { homedir as homedir17 } from "node:os";
5815
- import { basename, dirname as dirname5, join as join27 } from "node:path";
6116
+ import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
6117
+ import { homedir as homedir19 } from "node:os";
6118
+ import { basename, dirname as dirname6, join as join29 } from "node:path";
5816
6119
 
5817
6120
  // dist/src/skillify/local-source.js
5818
- import { readdirSync as readdirSync4, readFileSync as readFileSync15, existsSync as existsSync21, statSync as statSync4 } from "node:fs";
5819
- import { homedir as homedir14 } from "node:os";
5820
- import { join as join24 } from "node:path";
5821
- var HOME2 = homedir14();
6121
+ import { readdirSync as readdirSync4, readFileSync as readFileSync18, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
6122
+ import { homedir as homedir16 } from "node:os";
6123
+ import { join as join26 } from "node:path";
6124
+ var HOME2 = homedir16();
5822
6125
  function encodeCwdClaudeCode(cwd) {
5823
6126
  return cwd.replace(/[/_]/g, "-");
5824
6127
  }
5825
6128
  function detectInstalledAgents() {
5826
6129
  const installs = [];
5827
- const claudeRoot = join24(HOME2, ".claude", "projects");
5828
- if (existsSync21(claudeRoot)) {
6130
+ const claudeRoot = join26(HOME2, ".claude", "projects");
6131
+ if (existsSync22(claudeRoot)) {
5829
6132
  installs.push({
5830
6133
  agent: "claude_code",
5831
6134
  sessionRoot: claudeRoot,
5832
6135
  encodeCwd: encodeCwdClaudeCode
5833
6136
  });
5834
6137
  }
5835
- const codexRoot = join24(HOME2, ".codex", "sessions");
5836
- if (existsSync21(codexRoot)) {
6138
+ const codexRoot = join26(HOME2, ".codex", "sessions");
6139
+ if (existsSync22(codexRoot)) {
5837
6140
  installs.push({
5838
6141
  agent: "codex",
5839
6142
  sessionRoot: codexRoot,
@@ -5860,9 +6163,9 @@ function listLocalSessions(installs, cwd) {
5860
6163
  continue;
5861
6164
  }
5862
6165
  for (const sub of subdirs) {
5863
- const subdirPath = join24(install.sessionRoot, sub);
6166
+ const subdirPath = join26(install.sessionRoot, sub);
5864
6167
  try {
5865
- if (!statSync4(subdirPath).isDirectory())
6168
+ if (!statSync5(subdirPath).isDirectory())
5866
6169
  continue;
5867
6170
  } catch {
5868
6171
  continue;
@@ -5877,10 +6180,10 @@ function listLocalSessions(installs, cwd) {
5877
6180
  for (const f of files) {
5878
6181
  if (!f.endsWith(".jsonl"))
5879
6182
  continue;
5880
- const fullPath = join24(subdirPath, f);
6183
+ const fullPath = join26(subdirPath, f);
5881
6184
  let stats;
5882
6185
  try {
5883
- stats = statSync4(fullPath);
6186
+ stats = statSync5(fullPath);
5884
6187
  } catch {
5885
6188
  continue;
5886
6189
  }
@@ -5938,7 +6241,7 @@ function pickSessions(candidates, opts) {
5938
6241
  function nativeJsonlToRows(filePath, sessionId, agent) {
5939
6242
  let raw;
5940
6243
  try {
5941
- raw = readFileSync15(filePath, "utf-8");
6244
+ raw = readFileSync18(filePath, "utf-8");
5942
6245
  } catch {
5943
6246
  return [];
5944
6247
  }
@@ -6028,22 +6331,22 @@ function extractPairs(rows) {
6028
6331
  }
6029
6332
 
6030
6333
  // dist/src/skillify/gate-runner.js
6031
- import { existsSync as existsSync22 } from "node:fs";
6334
+ import { existsSync as existsSync23 } from "node:fs";
6032
6335
  import { createRequire } from "node:module";
6033
- import { homedir as homedir15 } from "node:os";
6034
- import { join as join25 } from "node:path";
6336
+ import { homedir as homedir17 } from "node:os";
6337
+ import { join as join27 } from "node:path";
6035
6338
  var requireForCp = createRequire(import.meta.url);
6036
6339
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
6037
6340
  var inheritedEnv = process;
6038
6341
  function firstExistingPath(candidates) {
6039
6342
  for (const c of candidates) {
6040
- if (existsSync22(c))
6343
+ if (existsSync23(c))
6041
6344
  return c;
6042
6345
  }
6043
6346
  return null;
6044
6347
  }
6045
6348
  function findAgentBin(agent) {
6046
- const home = homedir15();
6349
+ const home = homedir17();
6047
6350
  switch (agent) {
6048
6351
  // /usr/bin/<name> is included in every candidate list — that's the
6049
6352
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -6052,45 +6355,45 @@ function findAgentBin(agent) {
6052
6355
  // #170 caught the gap.
6053
6356
  case "claude_code":
6054
6357
  return firstExistingPath([
6055
- join25(home, ".claude", "local", "claude"),
6358
+ join27(home, ".claude", "local", "claude"),
6056
6359
  "/usr/local/bin/claude",
6057
6360
  "/usr/bin/claude",
6058
- join25(home, ".npm-global", "bin", "claude"),
6059
- join25(home, ".local", "bin", "claude"),
6361
+ join27(home, ".npm-global", "bin", "claude"),
6362
+ join27(home, ".local", "bin", "claude"),
6060
6363
  "/opt/homebrew/bin/claude"
6061
- ]) ?? join25(home, ".claude", "local", "claude");
6364
+ ]) ?? join27(home, ".claude", "local", "claude");
6062
6365
  case "codex":
6063
6366
  return firstExistingPath([
6064
6367
  "/usr/local/bin/codex",
6065
6368
  "/usr/bin/codex",
6066
- join25(home, ".npm-global", "bin", "codex"),
6067
- join25(home, ".local", "bin", "codex"),
6369
+ join27(home, ".npm-global", "bin", "codex"),
6370
+ join27(home, ".local", "bin", "codex"),
6068
6371
  "/opt/homebrew/bin/codex"
6069
6372
  ]) ?? "/usr/local/bin/codex";
6070
6373
  case "cursor":
6071
6374
  return firstExistingPath([
6072
6375
  "/usr/local/bin/cursor-agent",
6073
6376
  "/usr/bin/cursor-agent",
6074
- join25(home, ".npm-global", "bin", "cursor-agent"),
6075
- join25(home, ".local", "bin", "cursor-agent"),
6377
+ join27(home, ".npm-global", "bin", "cursor-agent"),
6378
+ join27(home, ".local", "bin", "cursor-agent"),
6076
6379
  "/opt/homebrew/bin/cursor-agent"
6077
6380
  ]) ?? "/usr/local/bin/cursor-agent";
6078
6381
  case "hermes":
6079
6382
  return firstExistingPath([
6080
- join25(home, ".local", "bin", "hermes"),
6383
+ join27(home, ".local", "bin", "hermes"),
6081
6384
  "/usr/local/bin/hermes",
6082
6385
  "/usr/bin/hermes",
6083
- join25(home, ".npm-global", "bin", "hermes"),
6386
+ join27(home, ".npm-global", "bin", "hermes"),
6084
6387
  "/opt/homebrew/bin/hermes"
6085
- ]) ?? join25(home, ".local", "bin", "hermes");
6388
+ ]) ?? join27(home, ".local", "bin", "hermes");
6086
6389
  case "pi":
6087
6390
  return firstExistingPath([
6088
- join25(home, ".local", "bin", "pi"),
6391
+ join27(home, ".local", "bin", "pi"),
6089
6392
  "/usr/local/bin/pi",
6090
6393
  "/usr/bin/pi",
6091
- join25(home, ".npm-global", "bin", "pi"),
6394
+ join27(home, ".npm-global", "bin", "pi"),
6092
6395
  "/opt/homebrew/bin/pi"
6093
- ]) ?? join25(home, ".local", "bin", "pi");
6396
+ ]) ?? join27(home, ".local", "bin", "pi");
6094
6397
  }
6095
6398
  }
6096
6399
 
@@ -6120,27 +6423,27 @@ function extractJsonBlock(s) {
6120
6423
  }
6121
6424
 
6122
6425
  // dist/src/skillify/local-manifest.js
6123
- import { existsSync as existsSync23, mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync12 } from "node:fs";
6124
- import { homedir as homedir16 } from "node:os";
6125
- import { dirname as dirname4, join as join26 } from "node:path";
6126
- var LOCAL_MANIFEST_PATH = join26(homedir16(), ".claude", "hivemind", "local-mined.json");
6127
- var LOCAL_MINE_LOCK_PATH = join26(homedir16(), ".claude", "hivemind", "local-mined.lock");
6426
+ import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
6427
+ import { homedir as homedir18 } from "node:os";
6428
+ import { dirname as dirname5, join as join28 } from "node:path";
6429
+ var LOCAL_MANIFEST_PATH = join28(homedir18(), ".claude", "hivemind", "local-mined.json");
6430
+ var LOCAL_MINE_LOCK_PATH = join28(homedir18(), ".claude", "hivemind", "local-mined.lock");
6128
6431
  function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
6129
- if (!existsSync23(path))
6432
+ if (!existsSync24(path))
6130
6433
  return null;
6131
6434
  try {
6132
- return JSON.parse(readFileSync16(path, "utf-8"));
6435
+ return JSON.parse(readFileSync19(path, "utf-8"));
6133
6436
  } catch {
6134
6437
  return null;
6135
6438
  }
6136
6439
  }
6137
6440
  function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
6138
- mkdirSync8(dirname4(path), { recursive: true });
6139
- writeFileSync12(path, JSON.stringify(m, null, 2));
6441
+ mkdirSync10(dirname5(path), { recursive: true });
6442
+ writeFileSync14(path, JSON.stringify(m, null, 2));
6140
6443
  }
6141
6444
 
6142
6445
  // dist/src/commands/mine-local.js
6143
- import { unlinkSync as unlinkSync9 } from "node:fs";
6446
+ import { unlinkSync as unlinkSync10 } from "node:fs";
6144
6447
  var EPSILON = 0.3;
6145
6448
  var DEFAULT_N = 8;
6146
6449
  var PAIR_CHAR_CAP = 4e3;
@@ -6151,9 +6454,9 @@ var IN_FLIGHT_MAX_AGE_MS = 6e4;
6151
6454
  var GATE_TIMEOUT_MS = 24e4;
6152
6455
  var MANIFEST_PATH = LOCAL_MANIFEST_PATH;
6153
6456
  function runGateViaStdin(opts) {
6154
- return new Promise((resolve) => {
6457
+ return new Promise((resolve2) => {
6155
6458
  if (opts.agent !== "claude_code") {
6156
- resolve({
6459
+ resolve2({
6157
6460
  stdout: "",
6158
6461
  stderr: "",
6159
6462
  errored: true,
@@ -6161,8 +6464,8 @@ function runGateViaStdin(opts) {
6161
6464
  });
6162
6465
  return;
6163
6466
  }
6164
- if (!existsSync24(opts.bin)) {
6165
- resolve({
6467
+ if (!existsSync25(opts.bin)) {
6468
+ resolve2({
6166
6469
  stdout: "",
6167
6470
  stderr: "",
6168
6471
  errored: true,
@@ -6189,7 +6492,7 @@ function runGateViaStdin(opts) {
6189
6492
  if (settled)
6190
6493
  return;
6191
6494
  settled = true;
6192
- resolve(r);
6495
+ resolve2(r);
6193
6496
  };
6194
6497
  const timer = setTimeout(() => {
6195
6498
  try {
@@ -6449,7 +6752,7 @@ async function runMineLocal(args) {
6449
6752
  return;
6450
6753
  lockReleased = true;
6451
6754
  try {
6452
- unlinkSync9(LOCAL_MINE_LOCK_PATH);
6755
+ unlinkSync10(LOCAL_MINE_LOCK_PATH);
6453
6756
  } catch {
6454
6757
  }
6455
6758
  };
@@ -6506,8 +6809,8 @@ async function runMineLocalImpl(args) {
6506
6809
  console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
6507
6810
  return;
6508
6811
  }
6509
- const tmpDir = join27(homedir17(), ".claude", "hivemind", `mine-local-${Date.now()}`);
6510
- mkdirSync9(tmpDir, { recursive: true });
6812
+ const tmpDir = join29(homedir19(), ".claude", "hivemind", `mine-local-${Date.now()}`);
6813
+ mkdirSync11(tmpDir, { recursive: true });
6511
6814
  console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
6512
6815
  const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
6513
6816
  const shortId = s.sessionId.slice(0, 8);
@@ -6518,23 +6821,23 @@ async function runMineLocalImpl(args) {
6518
6821
  return { session: s, skills: [], reason: "no pairs", error: null };
6519
6822
  }
6520
6823
  const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
6521
- const sessionTmp = join27(tmpDir, `s-${shortId}`);
6522
- mkdirSync9(sessionTmp, { recursive: true });
6523
- const verdictPath = join27(sessionTmp, "verdict.json");
6824
+ const sessionTmp = join29(tmpDir, `s-${shortId}`);
6825
+ mkdirSync11(sessionTmp, { recursive: true });
6826
+ const verdictPath = join29(sessionTmp, "verdict.json");
6524
6827
  const prompt = buildSessionPrompt(tail, s, verdictPath);
6525
- writeFileSync13(join27(sessionTmp, "prompt.txt"), prompt);
6828
+ writeFileSync15(join29(sessionTmp, "prompt.txt"), prompt);
6526
6829
  const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
6527
6830
  try {
6528
- writeFileSync13(join27(sessionTmp, "gate-stdout.txt"), gate.stdout);
6831
+ writeFileSync15(join29(sessionTmp, "gate-stdout.txt"), gate.stdout);
6529
6832
  if (gate.stderr)
6530
- writeFileSync13(join27(sessionTmp, "gate-stderr.txt"), gate.stderr);
6833
+ writeFileSync15(join29(sessionTmp, "gate-stderr.txt"), gate.stderr);
6531
6834
  } catch {
6532
6835
  }
6533
6836
  if (gate.errored) {
6534
6837
  console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
6535
6838
  return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
6536
6839
  }
6537
- const verdictText = existsSync24(verdictPath) ? readFileSync17(verdictPath, "utf-8") : gate.stdout;
6840
+ const verdictText = existsSync25(verdictPath) ? readFileSync20(verdictPath, "utf-8") : gate.stdout;
6538
6841
  const mv = parseMultiVerdict(verdictText);
6539
6842
  if (!mv) {
6540
6843
  console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
@@ -6586,7 +6889,7 @@ async function runMineLocalImpl(args) {
6586
6889
  sourceSessions: [session.sessionId],
6587
6890
  agent: gateAgent
6588
6891
  });
6589
- const canonicalDir = dirname5(result.path);
6892
+ const canonicalDir = dirname6(result.path);
6590
6893
  const symlinks = fanOutRoots.length > 0 ? fanOutSymlinks(canonicalDir, basename(canonicalDir), fanOutRoots) : [];
6591
6894
  const symlinkSuffix = symlinks.length > 0 ? `, fan-out \u2192 ${symlinks.length} root(s)` : "";
6592
6895
  console.log(` wrote ${skill.name} \u2190 session ${session.sessionId.slice(0, 8)} (${session.agent}${symlinkSuffix})`);
@@ -6750,7 +7053,7 @@ function wrapAt(s, max) {
6750
7053
 
6751
7054
  // dist/src/commands/skillify.js
6752
7055
  function stateDir() {
6753
- return join28(homedir18(), ".deeplake", "state", "skillify");
7056
+ return join30(homedir20(), ".deeplake", "state", "skillify");
6754
7057
  }
6755
7058
  function showStatus() {
6756
7059
  const cfg = loadScopeConfig();
@@ -6758,7 +7061,7 @@ function showStatus() {
6758
7061
  console.log(`team: ${cfg.team.length === 0 ? "(empty)" : cfg.team.join(", ")}`);
6759
7062
  console.log(`install: ${cfg.install} (${cfg.install === "global" ? "~/.claude/skills/" : "<project>/.claude/skills/"})`);
6760
7063
  const dir = stateDir();
6761
- if (!existsSync25(dir)) {
7064
+ if (!existsSync26(dir)) {
6762
7065
  console.log(`state: (no projects tracked yet)`);
6763
7066
  return;
6764
7067
  }
@@ -6770,7 +7073,7 @@ function showStatus() {
6770
7073
  console.log(`state: ${files.length} project(s) tracked`);
6771
7074
  for (const f of files) {
6772
7075
  try {
6773
- const s = JSON.parse(readFileSync18(join28(dir, f), "utf-8"));
7076
+ const s = JSON.parse(readFileSync21(join30(dir, f), "utf-8"));
6774
7077
  const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
6775
7078
  const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
6776
7079
  console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
@@ -6797,7 +7100,7 @@ function setInstall(loc) {
6797
7100
  }
6798
7101
  const cfg = loadScopeConfig();
6799
7102
  saveScopeConfig({ ...cfg, install: loc });
6800
- const path = loc === "global" ? join28(homedir18(), ".claude", "skills") : "<cwd>/.claude/skills";
7103
+ const path = loc === "global" ? join30(homedir20(), ".claude", "skills") : "<cwd>/.claude/skills";
6801
7104
  console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
6802
7105
  }
6803
7106
  function promoteSkill(name, cwd) {
@@ -6805,18 +7108,18 @@ function promoteSkill(name, cwd) {
6805
7108
  console.error("Usage: hivemind skillify promote <skill-name>");
6806
7109
  process.exit(1);
6807
7110
  }
6808
- const projectPath = join28(cwd, ".claude", "skills", name);
6809
- const globalPath = join28(homedir18(), ".claude", "skills", name);
6810
- if (!existsSync25(join28(projectPath, "SKILL.md"))) {
7111
+ const projectPath = join30(cwd, ".claude", "skills", name);
7112
+ const globalPath = join30(homedir20(), ".claude", "skills", name);
7113
+ if (!existsSync26(join30(projectPath, "SKILL.md"))) {
6811
7114
  console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
6812
7115
  process.exit(1);
6813
7116
  }
6814
- if (existsSync25(join28(globalPath, "SKILL.md"))) {
7117
+ if (existsSync26(join30(globalPath, "SKILL.md"))) {
6815
7118
  console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
6816
7119
  process.exit(1);
6817
7120
  }
6818
- mkdirSync10(dirname6(globalPath), { recursive: true });
6819
- renameSync5(projectPath, globalPath);
7121
+ mkdirSync12(dirname7(globalPath), { recursive: true });
7122
+ renameSync7(projectPath, globalPath);
6820
7123
  console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
6821
7124
  }
6822
7125
  function teamAdd(name) {
@@ -6922,7 +7225,7 @@ async function pullSkills(args) {
6922
7225
  console.error(`pull failed: ${e?.message ?? e}`);
6923
7226
  process.exit(1);
6924
7227
  }
6925
- const dest = toRaw === "global" ? join28(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7228
+ const dest = toRaw === "global" ? join30(homedir20(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
6926
7229
  const filterDesc = users.length === 0 ? "all users" : users.join(", ");
6927
7230
  console.log(`Destination: ${dest}`);
6928
7231
  console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
@@ -6972,7 +7275,7 @@ async function unpullSkills(args) {
6972
7275
  all,
6973
7276
  legacyCleanup
6974
7277
  });
6975
- const dest = toRaw === "global" ? join28(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7278
+ const dest = toRaw === "global" ? join30(homedir20(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
6976
7279
  const filterParts = [];
6977
7280
  if (users.length > 0)
6978
7281
  filterParts.push(`users=${users.join(",")}`);
@@ -7068,13 +7371,13 @@ if (process.argv[1] && process.argv[1].endsWith("skillify.js")) {
7068
7371
 
7069
7372
  // dist/src/cli/update.js
7070
7373
  import { execFileSync as execFileSync4 } from "node:child_process";
7071
- import { existsSync as existsSync26, readFileSync as readFileSync20, realpathSync } from "node:fs";
7072
- import { dirname as dirname8, sep } from "node:path";
7374
+ import { existsSync as existsSync27, readFileSync as readFileSync23, realpathSync } from "node:fs";
7375
+ import { dirname as dirname9, sep } from "node:path";
7073
7376
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7074
7377
 
7075
7378
  // dist/src/utils/version-check.js
7076
- import { readFileSync as readFileSync19 } from "node:fs";
7077
- import { dirname as dirname7, join as join29 } from "node:path";
7379
+ import { readFileSync as readFileSync22 } from "node:fs";
7380
+ import { dirname as dirname8, join as join31 } from "node:path";
7078
7381
  function isNewer(latest, current) {
7079
7382
  const parse = (v) => v.split(".").map(Number);
7080
7383
  const [la, lb, lc] = parse(latest);
@@ -7093,24 +7396,24 @@ function detectInstallKind(argv1) {
7093
7396
  return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
7094
7397
  }
7095
7398
  })();
7096
- let dir = dirname8(realArgv1);
7399
+ let dir = dirname9(realArgv1);
7097
7400
  let installDir = null;
7098
7401
  for (let i = 0; i < 10; i++) {
7099
7402
  const pkgPath = `${dir}${sep}package.json`;
7100
7403
  try {
7101
- const pkg = JSON.parse(readFileSync20(pkgPath, "utf-8"));
7404
+ const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
7102
7405
  if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
7103
7406
  installDir = dir;
7104
7407
  break;
7105
7408
  }
7106
7409
  } catch {
7107
7410
  }
7108
- const parent = dirname8(dir);
7411
+ const parent = dirname9(dir);
7109
7412
  if (parent === dir)
7110
7413
  break;
7111
7414
  dir = parent;
7112
7415
  }
7113
- installDir ??= dirname8(realArgv1);
7416
+ installDir ??= dirname9(realArgv1);
7114
7417
  if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
7115
7418
  return { kind: "npx", installDir };
7116
7419
  }
@@ -7119,10 +7422,10 @@ function detectInstallKind(argv1) {
7119
7422
  }
7120
7423
  let gitDir = installDir;
7121
7424
  for (let i = 0; i < 6; i++) {
7122
- if (existsSync26(`${gitDir}${sep}.git`)) {
7425
+ if (existsSync27(`${gitDir}${sep}.git`)) {
7123
7426
  return { kind: "local-dev", installDir };
7124
7427
  }
7125
- const parent = dirname8(gitDir);
7428
+ const parent = dirname9(gitDir);
7126
7429
  if (parent === gitDir)
7127
7430
  break;
7128
7431
  gitDir = parent;
@@ -7265,12 +7568,28 @@ Usage:
7265
7568
 
7266
7569
  Semantic search (embeddings):
7267
7570
  hivemind embeddings install Download @huggingface/transformers
7268
- once (~600 MB) into a shared dir
7269
- and symlink every detected agent
7270
- plugin to it. Idempotent.
7271
- hivemind embeddings uninstall [--prune] Remove the per-agent symlinks.
7272
- --prune also deletes the shared dir.
7273
- hivemind embeddings status Show shared-deps + per-agent state.
7571
+ once (~600 MB) into a shared dir,
7572
+ symlink every detected agent
7573
+ plugin to it, and set
7574
+ embeddings.enabled = true in
7575
+ ~/.deeplake/config.json. Idempotent.
7576
+ hivemind embeddings enable Light opt-in: flip
7577
+ embeddings.enabled = true in
7578
+ ~/.deeplake/config.json. Use this
7579
+ after \`disable\` to turn back on
7580
+ without re-running install.
7581
+ hivemind embeddings disable Light opt-out: flip
7582
+ embeddings.enabled = false and
7583
+ SIGTERM the running daemon. Shared
7584
+ deps stay on disk.
7585
+ hivemind embeddings uninstall [--prune] Full opt-out: remove the per-agent
7586
+ symlinks, flip
7587
+ embeddings.enabled = false, and
7588
+ SIGTERM the daemon. --prune also
7589
+ deletes the shared dir to reclaim
7590
+ ~600 MB.
7591
+ hivemind embeddings status Show config + shared-deps + per-
7592
+ agent state.
7274
7593
 
7275
7594
  Add --with-embeddings to "hivemind install" (or "hivemind <agent> install")
7276
7595
  to run "embeddings install" automatically after installing the agent(s).
@@ -7340,7 +7659,7 @@ async function runInstallAll(args) {
7340
7659
  runSingleInstall(id);
7341
7660
  if (withEmbeddings) {
7342
7661
  log("");
7343
- enableEmbeddings();
7662
+ installEmbeddings();
7344
7663
  }
7345
7664
  await maybeShowOrgChoice();
7346
7665
  log("");
@@ -7433,19 +7752,27 @@ async function main() {
7433
7752
  }
7434
7753
  if (cmd === "embeddings") {
7435
7754
  const sub = args[1];
7436
- if (sub === "install" || sub === "enable") {
7755
+ if (sub === "install") {
7756
+ installEmbeddings();
7757
+ return;
7758
+ }
7759
+ if (sub === "enable") {
7437
7760
  enableEmbeddings();
7438
7761
  return;
7439
7762
  }
7440
- if (sub === "uninstall" || sub === "disable") {
7441
- disableEmbeddings({ prune: hasFlag(args.slice(2), "--prune") });
7763
+ if (sub === "disable") {
7764
+ disableEmbeddings();
7765
+ return;
7766
+ }
7767
+ if (sub === "uninstall") {
7768
+ uninstallEmbeddings({ prune: hasFlag(args.slice(2), "--prune") });
7442
7769
  return;
7443
7770
  }
7444
7771
  if (sub === "status") {
7445
7772
  statusEmbeddings();
7446
7773
  return;
7447
7774
  }
7448
- warn("Usage: hivemind embeddings install | uninstall [--prune] | status");
7775
+ warn("Usage: hivemind embeddings install | enable | disable | uninstall [--prune] | status");
7449
7776
  process.exit(1);
7450
7777
  }
7451
7778
  if (AUTH_SUBCOMMANDS.has(cmd)) {
@@ -7459,7 +7786,7 @@ async function main() {
7459
7786
  runSingleInstall(cmd);
7460
7787
  if (hasFlag(args.slice(2), "--with-embeddings")) {
7461
7788
  log("");
7462
- enableEmbeddings();
7789
+ installEmbeddings();
7463
7790
  }
7464
7791
  } else if (sub === "uninstall")
7465
7792
  runSingleUninstall(cmd);