@deeplake/hivemind 0.7.26 → 0.7.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +1086 -93
  4. package/codex/bundle/capture.js +10 -5
  5. package/codex/bundle/commands/auth-login.js +10 -5
  6. package/codex/bundle/embeddings/embed-daemon.js +4 -2
  7. package/codex/bundle/pre-tool-use.js +10 -5
  8. package/codex/bundle/session-start-setup.js +10 -5
  9. package/codex/bundle/session-start.js +233 -136
  10. package/codex/bundle/shell/deeplake-shell.js +10 -5
  11. package/codex/bundle/skillify-worker.js +60 -21
  12. package/codex/bundle/stop.js +66 -25
  13. package/codex/bundle/wiki-worker.js +4 -2
  14. package/codex/skills/deeplake-memory/SKILL.md +33 -0
  15. package/cursor/bundle/capture.js +63 -22
  16. package/cursor/bundle/commands/auth-login.js +10 -5
  17. package/cursor/bundle/embeddings/embed-daemon.js +4 -2
  18. package/cursor/bundle/pre-tool-use.js +10 -5
  19. package/cursor/bundle/session-end.js +57 -19
  20. package/cursor/bundle/session-start.js +238 -87
  21. package/cursor/bundle/shell/deeplake-shell.js +10 -5
  22. package/cursor/bundle/skillify-worker.js +60 -21
  23. package/cursor/bundle/wiki-worker.js +4 -2
  24. package/hermes/bundle/capture.js +63 -22
  25. package/hermes/bundle/commands/auth-login.js +10 -5
  26. package/hermes/bundle/embeddings/embed-daemon.js +4 -2
  27. package/hermes/bundle/pre-tool-use.js +10 -5
  28. package/hermes/bundle/session-end.js +57 -19
  29. package/hermes/bundle/session-start.js +239 -87
  30. package/hermes/bundle/shell/deeplake-shell.js +10 -5
  31. package/hermes/bundle/skillify-worker.js +60 -21
  32. package/hermes/bundle/wiki-worker.js +4 -2
  33. package/mcp/bundle/server.js +10 -5
  34. package/openclaw/dist/chunks/{auth-creds-AEKS6D3P.js → auth-creds-KKTYIP27.js} +2 -1
  35. package/openclaw/dist/chunks/{chunk-SRCBBT4H.js → chunk-OSD5GJJ5.js} +2 -0
  36. package/openclaw/dist/chunks/{config-ZLH6JFJS.js → config-XEK4MJJS.js} +2 -0
  37. package/openclaw/dist/chunks/{index-marker-store-PGT5CW6T.js → index-marker-store-CPGF2BI7.js} +4 -2
  38. package/openclaw/dist/chunks/{setup-config-C35UK4LP.js → setup-config-VI54GEUM.js} +2 -0
  39. package/openclaw/dist/index.js +68 -19
  40. package/openclaw/dist/skillify-worker.js +67 -27
  41. package/openclaw/openclaw.plugin.json +1 -1
  42. package/openclaw/package.json +1 -1
  43. package/package.json +1 -1
  44. package/pi/extension-source/hivemind.ts +157 -19
@@ -21,13 +21,15 @@ function readStdin() {
21
21
  import { appendFileSync } from "node:fs";
22
22
  import { join } from "node:path";
23
23
  import { homedir } from "node:os";
24
- var DEBUG = process.env.HIVEMIND_DEBUG === "1";
25
24
  var LOG = join(homedir(), ".deeplake", "hook-debug.log");
25
+ function isDebug() {
26
+ return process.env.HIVEMIND_DEBUG === "1";
27
+ }
26
28
  function utcTimestamp(d = /* @__PURE__ */ new Date()) {
27
29
  return d.toISOString().replace("T", " ").slice(0, 19) + " UTC";
28
30
  }
29
31
  function log(tag, msg) {
30
- if (!DEBUG)
32
+ if (!isDebug())
31
33
  return;
32
34
  appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
33
35
  `);
@@ -282,33 +284,69 @@ import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, appendFileSyn
282
284
  import { homedir as homedir6, tmpdir as tmpdir2 } from "node:os";
283
285
 
284
286
  // dist/src/skillify/gate-runner.js
285
- import { execFileSync } from "node:child_process";
286
287
  import { existsSync as existsSync3 } from "node:fs";
288
+ import { createRequire } from "node:module";
287
289
  import { homedir as homedir5 } from "node:os";
288
290
  import { join as join7 } from "node:path";
291
+ var requireForCp = createRequire(import.meta.url);
292
+ var { execFileSync: runChildProcess } = requireForCp("node:child_process");
293
+ var inheritedEnv = process;
294
+ function firstExistingPath(candidates) {
295
+ for (const c of candidates) {
296
+ if (existsSync3(c))
297
+ return c;
298
+ }
299
+ return null;
300
+ }
289
301
  function findAgentBin(agent) {
290
- const which = (name) => {
291
- try {
292
- const out = execFileSync("which", [name], {
293
- encoding: "utf-8",
294
- stdio: ["ignore", "pipe", "ignore"]
295
- });
296
- return out.trim() || null;
297
- } catch {
298
- return null;
299
- }
300
- };
302
+ const home = homedir5();
301
303
  switch (agent) {
304
+ // /usr/bin/<name> is included in every candidate list — that's the
305
+ // common Linux package-manager install path (apt, dnf, pacman). Old
306
+ // code used `which` which always checked it; the static-scan fix
307
+ // dropped `which`, so /usr/bin needs to be explicit. CodeRabbit on
308
+ // #170 caught the gap.
302
309
  case "claude_code":
303
- return which("claude") ?? join7(homedir5(), ".claude", "local", "claude");
310
+ return firstExistingPath([
311
+ join7(home, ".claude", "local", "claude"),
312
+ "/usr/local/bin/claude",
313
+ "/usr/bin/claude",
314
+ join7(home, ".npm-global", "bin", "claude"),
315
+ join7(home, ".local", "bin", "claude"),
316
+ "/opt/homebrew/bin/claude"
317
+ ]) ?? join7(home, ".claude", "local", "claude");
304
318
  case "codex":
305
- return which("codex") ?? "/usr/local/bin/codex";
319
+ return firstExistingPath([
320
+ "/usr/local/bin/codex",
321
+ "/usr/bin/codex",
322
+ join7(home, ".npm-global", "bin", "codex"),
323
+ join7(home, ".local", "bin", "codex"),
324
+ "/opt/homebrew/bin/codex"
325
+ ]) ?? "/usr/local/bin/codex";
306
326
  case "cursor":
307
- return which("cursor-agent") ?? "/usr/local/bin/cursor-agent";
327
+ return firstExistingPath([
328
+ "/usr/local/bin/cursor-agent",
329
+ "/usr/bin/cursor-agent",
330
+ join7(home, ".npm-global", "bin", "cursor-agent"),
331
+ join7(home, ".local", "bin", "cursor-agent"),
332
+ "/opt/homebrew/bin/cursor-agent"
333
+ ]) ?? "/usr/local/bin/cursor-agent";
308
334
  case "hermes":
309
- return which("hermes") ?? join7(homedir5(), ".local", "bin", "hermes");
335
+ return firstExistingPath([
336
+ join7(home, ".local", "bin", "hermes"),
337
+ "/usr/local/bin/hermes",
338
+ "/usr/bin/hermes",
339
+ join7(home, ".npm-global", "bin", "hermes"),
340
+ "/opt/homebrew/bin/hermes"
341
+ ]) ?? join7(home, ".local", "bin", "hermes");
310
342
  case "pi":
311
- return which("pi") ?? join7(homedir5(), ".local", "bin", "pi");
343
+ return firstExistingPath([
344
+ join7(home, ".local", "bin", "pi"),
345
+ "/usr/local/bin/pi",
346
+ "/usr/bin/pi",
347
+ join7(home, ".npm-global", "bin", "pi"),
348
+ "/opt/homebrew/bin/pi"
349
+ ]) ?? join7(home, ".local", "bin", "pi");
312
350
  }
313
351
  }
314
352
 
@@ -53,8 +53,8 @@ var init_index_marker_store = __esm({
53
53
  });
54
54
 
55
55
  // dist/src/hooks/cursor/session-start.js
56
- import { fileURLToPath } from "node:url";
57
- import { dirname as dirname4 } from "node:path";
56
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
57
+ import { dirname as dirname6 } from "node:path";
58
58
 
59
59
  // dist/src/commands/auth.js
60
60
  import { execSync } from "node:child_process";
@@ -126,10 +126,12 @@ import { randomUUID } from "node:crypto";
126
126
  import { appendFileSync } from "node:fs";
127
127
  import { join as join3 } from "node:path";
128
128
  import { homedir as homedir3 } from "node:os";
129
- var DEBUG = process.env.HIVEMIND_DEBUG === "1";
130
129
  var LOG = join3(homedir3(), ".deeplake", "hook-debug.log");
130
+ function isDebug() {
131
+ return process.env.HIVEMIND_DEBUG === "1";
132
+ }
131
133
  function log(tag, msg) {
132
- if (!DEBUG)
134
+ if (!isDebug())
133
135
  return;
134
136
  appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
135
137
  `);
@@ -175,7 +177,9 @@ var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
175
177
  var MAX_RETRIES = 3;
176
178
  var BASE_DELAY_MS = 500;
177
179
  var MAX_CONCURRENCY = 5;
178
- var QUERY_TIMEOUT_MS = Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
180
+ function getQueryTimeoutMs() {
181
+ return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
182
+ }
179
183
  function sleep(ms) {
180
184
  return new Promise((resolve) => setTimeout(resolve, ms));
181
185
  }
@@ -256,8 +260,9 @@ var DeeplakeApi = class {
256
260
  let lastError;
257
261
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
258
262
  let resp;
263
+ const timeoutMs = getQueryTimeoutMs();
259
264
  try {
260
- const signal = AbortSignal.timeout(QUERY_TIMEOUT_MS);
265
+ const signal = AbortSignal.timeout(timeoutMs);
261
266
  resp = await fetch(`${this.apiUrl}/workspaces/${this.workspaceId}/tables/query`, {
262
267
  method: "POST",
263
268
  headers: {
@@ -271,7 +276,7 @@ var DeeplakeApi = class {
271
276
  });
272
277
  } catch (e) {
273
278
  if (isTimeoutError(e)) {
274
- lastError = new Error(`Query timeout after ${QUERY_TIMEOUT_MS}ms`);
279
+ lastError = new Error(`Query timeout after ${timeoutMs}ms`);
275
280
  throw lastError;
276
281
  }
277
282
  lastError = e instanceof Error ? e : new Error(String(e));
@@ -561,6 +566,162 @@ var DeeplakeApi = class {
561
566
  }
562
567
  };
563
568
 
569
+ // dist/src/cli/skillify-spec.js
570
+ var SKILLIFY_COMMANDS = [
571
+ { cmd: "hivemind skillify", desc: "show scope, team, install, per-project state" },
572
+ { cmd: "hivemind skillify pull", desc: "sync project skills from the org table to local FS" },
573
+ { cmd: "hivemind skillify pull --user <email>", desc: "only skills authored by that user" },
574
+ { cmd: "hivemind skillify pull --users <a,b,c>", desc: "only skills from those authors" },
575
+ { cmd: "hivemind skillify pull --all-users", desc: 'explicit "no author filter" (default)' },
576
+ { cmd: "hivemind skillify pull --to <project|global>", desc: "install location (project=cwd/.claude/skills, global=~/.claude/skills)" },
577
+ { cmd: "hivemind skillify pull --dry-run", desc: "preview without touching disk" },
578
+ { cmd: "hivemind skillify pull --force", desc: "overwrite local files even if up-to-date (creates .bak)" },
579
+ { cmd: "hivemind skillify pull <skill-name>", desc: "pull only that one skill (combines with --user)" },
580
+ { cmd: "hivemind skillify unpull", desc: "remove every skill previously installed by pull" },
581
+ { cmd: "hivemind skillify unpull --user <email>", desc: "remove only that author's pulls" },
582
+ { cmd: "hivemind skillify unpull --not-mine", desc: "remove all pulls except your own" },
583
+ { cmd: "hivemind skillify unpull --dry-run", desc: "preview without touching disk" },
584
+ { cmd: "hivemind skillify scope <me|team|org>", desc: "sharing scope for newly mined skills" },
585
+ { cmd: "hivemind skillify install <project|global>", desc: "default install location for new skills" },
586
+ { cmd: "hivemind skillify promote <skill-name>", desc: "move a project skill to the global location" },
587
+ { cmd: "hivemind skillify team add|remove|list <name>", desc: "manage team member list" },
588
+ { cmd: "hivemind skillify mine-local", desc: "one-shot: mine skills from local sessions (no auth needed)" },
589
+ { cmd: "hivemind skillify mine-local --n <num|all>", desc: "how many sessions to mine (default: 8)" },
590
+ { cmd: "hivemind skillify mine-local --force", desc: "re-run even if the manifest sentinel exists" },
591
+ { cmd: "hivemind skillify mine-local --dry-run", desc: "stop before calling the LLM gate" }
592
+ ];
593
+ function renderSkillifyCommands() {
594
+ const maxLen = Math.max(...SKILLIFY_COMMANDS.map((c) => c.cmd.length));
595
+ return SKILLIFY_COMMANDS.map((c) => `- ${c.cmd.padEnd(maxLen + 2)} \u2014 ${c.desc}`).join("\n");
596
+ }
597
+
598
+ // dist/src/skillify/local-manifest.js
599
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
600
+ import { homedir as homedir4 } from "node:os";
601
+ import { dirname, join as join5 } from "node:path";
602
+ var LOCAL_MANIFEST_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.json");
603
+ var LOCAL_MINE_LOCK_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.lock");
604
+ function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
605
+ if (!existsSync3(path))
606
+ return null;
607
+ try {
608
+ return JSON.parse(readFileSync4(path, "utf-8"));
609
+ } catch {
610
+ return null;
611
+ }
612
+ }
613
+ function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
614
+ const m = readLocalManifest(path);
615
+ return Array.isArray(m?.entries) ? m.entries.length : 0;
616
+ }
617
+
618
+ // dist/src/skillify/spawn-mine-local-worker.js
619
+ import { execFileSync, spawn } from "node:child_process";
620
+ import { closeSync, existsSync as existsSync4, mkdirSync as mkdirSync4, openSync, readdirSync, statSync, unlinkSync as unlinkSync2 } from "node:fs";
621
+ import { homedir as homedir5 } from "node:os";
622
+ import { dirname as dirname2, join as join6 } from "node:path";
623
+ import { fileURLToPath } from "node:url";
624
+ var HOME = homedir5();
625
+ var HIVEMIND_DIR = join6(HOME, ".claude", "hivemind");
626
+ var LOG_PATH = join6(HOME, ".claude", "hooks", "mine-local.log");
627
+ var CLAUDE_PROJECTS_DIR = join6(HOME, ".claude", "projects");
628
+ var LOCK_STALE_MS = 15 * 60 * 1e3;
629
+ function findBundledCliPath() {
630
+ try {
631
+ const thisDir = dirname2(fileURLToPath(import.meta.url));
632
+ const cliPath = join6(thisDir, "..", "..", "bundle", "cli.js");
633
+ return existsSync4(cliPath) ? cliPath : null;
634
+ } catch {
635
+ return null;
636
+ }
637
+ }
638
+ function findHivemindLauncher() {
639
+ const bundled = findBundledCliPath();
640
+ if (bundled)
641
+ return { kind: "node-script", path: bundled };
642
+ try {
643
+ const out = execFileSync("which", ["hivemind"], {
644
+ encoding: "utf-8",
645
+ stdio: ["ignore", "pipe", "ignore"]
646
+ });
647
+ const bin = out.trim();
648
+ return bin ? { kind: "bin", path: bin } : null;
649
+ } catch {
650
+ return null;
651
+ }
652
+ }
653
+ function hasLocalClaudeSessions() {
654
+ if (!existsSync4(CLAUDE_PROJECTS_DIR))
655
+ return false;
656
+ let subdirs;
657
+ try {
658
+ subdirs = readdirSync(CLAUDE_PROJECTS_DIR);
659
+ } catch {
660
+ return false;
661
+ }
662
+ for (const sub of subdirs) {
663
+ let files;
664
+ try {
665
+ files = readdirSync(join6(CLAUDE_PROJECTS_DIR, sub));
666
+ } catch {
667
+ continue;
668
+ }
669
+ if (files.some((f) => f.endsWith(".jsonl")))
670
+ return true;
671
+ }
672
+ return false;
673
+ }
674
+ function maybeAutoMineLocal() {
675
+ if (existsSync4(LOCAL_MANIFEST_PATH))
676
+ return { triggered: false, reason: "manifest-exists" };
677
+ if (existsSync4(LOCAL_MINE_LOCK_PATH)) {
678
+ let stale = false;
679
+ try {
680
+ const stats = statSync(LOCAL_MINE_LOCK_PATH);
681
+ stale = Date.now() - stats.mtimeMs > LOCK_STALE_MS;
682
+ } catch {
683
+ }
684
+ if (!stale)
685
+ return { triggered: false, reason: "lock-exists" };
686
+ try {
687
+ unlinkSync2(LOCAL_MINE_LOCK_PATH);
688
+ } catch {
689
+ return { triggered: false, reason: "lock-exists" };
690
+ }
691
+ }
692
+ if (!hasLocalClaudeSessions())
693
+ return { triggered: false, reason: "no-claude-sessions" };
694
+ const launcher = findHivemindLauncher();
695
+ if (!launcher)
696
+ return { triggered: false, reason: "no-hivemind-bin" };
697
+ try {
698
+ mkdirSync4(HIVEMIND_DIR, { recursive: true });
699
+ const fd = openSync(LOCAL_MINE_LOCK_PATH, "wx");
700
+ closeSync(fd);
701
+ } catch {
702
+ return { triggered: false, reason: "lock-acquire-failed" };
703
+ }
704
+ try {
705
+ mkdirSync4(join6(HOME, ".claude", "hooks"), { recursive: true });
706
+ const out = openSync(LOG_PATH, "a");
707
+ const [cmd, args] = launcher.kind === "node-script" ? [process.execPath, [launcher.path, "skillify", "mine-local"]] : [launcher.path, ["skillify", "mine-local"]];
708
+ const child = spawn(cmd, args, {
709
+ detached: true,
710
+ stdio: ["ignore", out, out],
711
+ env: process.env
712
+ });
713
+ closeSync(out);
714
+ child.unref();
715
+ return { triggered: true };
716
+ } catch {
717
+ try {
718
+ unlinkSync2(LOCAL_MINE_LOCK_PATH);
719
+ } catch {
720
+ }
721
+ return { triggered: false, reason: "spawn-failed" };
722
+ }
723
+ }
724
+
564
725
  // dist/src/utils/stdin.js
565
726
  function readStdin() {
566
727
  return new Promise((resolve, reject) => {
@@ -579,18 +740,18 @@ function readStdin() {
579
740
  }
580
741
 
581
742
  // dist/src/utils/version-check.js
582
- import { readFileSync as readFileSync4 } from "node:fs";
583
- import { dirname, join as join5 } from "node:path";
743
+ import { readFileSync as readFileSync5 } from "node:fs";
744
+ import { dirname as dirname3, join as join7 } from "node:path";
584
745
  function getInstalledVersion(bundleDir, pluginManifestDir) {
585
746
  try {
586
- const pluginJson = join5(bundleDir, "..", pluginManifestDir, "plugin.json");
587
- const plugin = JSON.parse(readFileSync4(pluginJson, "utf-8"));
747
+ const pluginJson = join7(bundleDir, "..", pluginManifestDir, "plugin.json");
748
+ const plugin = JSON.parse(readFileSync5(pluginJson, "utf-8"));
588
749
  if (plugin.version)
589
750
  return plugin.version;
590
751
  } catch {
591
752
  }
592
753
  try {
593
- const stamp = readFileSync4(join5(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
754
+ const stamp = readFileSync5(join7(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
594
755
  if (stamp)
595
756
  return stamp;
596
757
  } catch {
@@ -605,14 +766,14 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
605
766
  ]);
606
767
  let dir = bundleDir;
607
768
  for (let i = 0; i < 5; i++) {
608
- const candidate = join5(dir, "package.json");
769
+ const candidate = join7(dir, "package.json");
609
770
  try {
610
- const pkg = JSON.parse(readFileSync4(candidate, "utf-8"));
771
+ const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
611
772
  if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
612
773
  return pkg.version;
613
774
  } catch {
614
775
  }
615
- const parent = dirname(dir);
776
+ const parent = dirname3(dir);
616
777
  if (parent === dir)
617
778
  break;
618
779
  dir = parent;
@@ -621,12 +782,12 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
621
782
  }
622
783
 
623
784
  // dist/src/hooks/shared/autoupdate.js
624
- import { spawn } from "node:child_process";
625
- import { existsSync as existsSync3 } from "node:fs";
626
- import { join as join6 } from "node:path";
785
+ import { spawn as spawn2 } from "node:child_process";
786
+ import { existsSync as existsSync5 } from "node:fs";
787
+ import { join as join8 } from "node:path";
627
788
  var log3 = (msg) => log("autoupdate", msg);
628
789
  var defaultSpawn = (cmd, args) => {
629
- const child = spawn(cmd, args, {
790
+ const child = spawn2(cmd, args, {
630
791
  detached: true,
631
792
  stdio: "ignore"
632
793
  });
@@ -639,8 +800,8 @@ function findHivemindOnPath() {
639
800
  const PATH = process.env.PATH ?? "";
640
801
  const dirs = PATH.split(":").filter(Boolean);
641
802
  for (const dir of dirs) {
642
- const candidate = join6(dir, "hivemind");
643
- if (existsSync3(candidate))
803
+ const candidate = join8(dir, "hivemind");
804
+ if (existsSync5(candidate))
644
805
  return candidate;
645
806
  }
646
807
  return null;
@@ -674,14 +835,14 @@ async function autoUpdate(creds, opts) {
674
835
  }
675
836
 
676
837
  // dist/src/skillify/pull.js
677
- import { existsSync as existsSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync3, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync3 } from "node:fs";
678
- import { homedir as homedir8 } from "node:os";
679
- import { dirname as dirname3, join as join11 } from "node:path";
838
+ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync4 } from "node:fs";
839
+ import { homedir as homedir10 } from "node:os";
840
+ import { dirname as dirname5, join as join13 } from "node:path";
680
841
 
681
842
  // dist/src/skillify/skill-writer.js
682
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
683
- import { homedir as homedir4 } from "node:os";
684
- import { join as join7 } from "node:path";
843
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
844
+ import { homedir as homedir6 } from "node:os";
845
+ import { join as join9 } from "node:path";
685
846
  function assertValidSkillName(name) {
686
847
  if (typeof name !== "string" || name.length === 0) {
687
848
  throw new Error(`invalid skill name: empty or non-string`);
@@ -747,26 +908,26 @@ function parseFrontmatter(text) {
747
908
  }
748
909
 
749
910
  // dist/src/skillify/manifest.js
750
- import { existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
751
- import { homedir as homedir6 } from "node:os";
752
- import { dirname as dirname2, join as join9 } from "node:path";
911
+ import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
912
+ import { homedir as homedir8 } from "node:os";
913
+ import { dirname as dirname4, join as join11 } from "node:path";
753
914
 
754
915
  // dist/src/skillify/legacy-migration.js
755
- import { existsSync as existsSync5, renameSync } from "node:fs";
756
- import { homedir as homedir5 } from "node:os";
757
- import { join as join8 } from "node:path";
916
+ import { existsSync as existsSync7, renameSync } from "node:fs";
917
+ import { homedir as homedir7 } from "node:os";
918
+ import { join as join10 } from "node:path";
758
919
  var dlog = (msg) => log("skillify-migrate", msg);
759
920
  var attempted = false;
760
921
  function migrateLegacyStateDir() {
761
922
  if (attempted)
762
923
  return;
763
924
  attempted = true;
764
- const root = join8(homedir5(), ".deeplake", "state");
765
- const legacy = join8(root, "skilify");
766
- const current = join8(root, "skillify");
767
- if (!existsSync5(legacy))
925
+ const root = join10(homedir7(), ".deeplake", "state");
926
+ const legacy = join10(root, "skilify");
927
+ const current = join10(root, "skillify");
928
+ if (!existsSync7(legacy))
768
929
  return;
769
- if (existsSync5(current))
930
+ if (existsSync7(current))
770
931
  return;
771
932
  try {
772
933
  renameSync(legacy, current);
@@ -786,15 +947,15 @@ function emptyManifest() {
786
947
  return { version: 1, entries: [] };
787
948
  }
788
949
  function manifestPath() {
789
- return join9(homedir6(), ".deeplake", "state", "skillify", "pulled.json");
950
+ return join11(homedir8(), ".deeplake", "state", "skillify", "pulled.json");
790
951
  }
791
952
  function loadManifest(path = manifestPath()) {
792
953
  migrateLegacyStateDir();
793
- if (!existsSync6(path))
954
+ if (!existsSync8(path))
794
955
  return emptyManifest();
795
956
  let raw;
796
957
  try {
797
- raw = readFileSync6(path, "utf-8");
958
+ raw = readFileSync7(path, "utf-8");
798
959
  } catch {
799
960
  return emptyManifest();
800
961
  }
@@ -841,9 +1002,9 @@ function loadManifest(path = manifestPath()) {
841
1002
  }
842
1003
  function saveManifest(m, path = manifestPath()) {
843
1004
  migrateLegacyStateDir();
844
- mkdirSync4(dirname2(path), { recursive: true });
1005
+ mkdirSync6(dirname4(path), { recursive: true });
845
1006
  const tmp = `${path}.tmp`;
846
- writeFileSync4(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
1007
+ writeFileSync5(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
847
1008
  renameSync2(tmp, path);
848
1009
  }
849
1010
  function recordPull(entry, path = manifestPath()) {
@@ -869,7 +1030,7 @@ function unlinkSymlinks(paths) {
869
1030
  if (!st.isSymbolicLink())
870
1031
  continue;
871
1032
  try {
872
- unlinkSync2(path);
1033
+ unlinkSync3(path);
873
1034
  } catch {
874
1035
  }
875
1036
  }
@@ -879,7 +1040,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
879
1040
  const live = [];
880
1041
  let pruned = 0;
881
1042
  for (const e of m.entries) {
882
- if (existsSync6(join9(e.installRoot, e.dirName))) {
1043
+ if (existsSync8(join11(e.installRoot, e.dirName))) {
883
1044
  live.push(e);
884
1045
  continue;
885
1046
  }
@@ -892,26 +1053,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
892
1053
  }
893
1054
 
894
1055
  // dist/src/skillify/agent-roots.js
895
- import { existsSync as existsSync7 } from "node:fs";
896
- import { homedir as homedir7 } from "node:os";
897
- import { join as join10 } from "node:path";
1056
+ import { existsSync as existsSync9 } from "node:fs";
1057
+ import { homedir as homedir9 } from "node:os";
1058
+ import { join as join12 } from "node:path";
898
1059
  function resolveDetected(home) {
899
1060
  const out = [];
900
- const codexInstalled = existsSync7(join10(home, ".codex"));
901
- const piInstalled = existsSync7(join10(home, ".pi", "agent"));
902
- const hermesInstalled = existsSync7(join10(home, ".hermes"));
1061
+ const codexInstalled = existsSync9(join12(home, ".codex"));
1062
+ const piInstalled = existsSync9(join12(home, ".pi", "agent"));
1063
+ const hermesInstalled = existsSync9(join12(home, ".hermes"));
903
1064
  if (codexInstalled || piInstalled) {
904
- out.push(join10(home, ".agents", "skills"));
1065
+ out.push(join12(home, ".agents", "skills"));
905
1066
  }
906
1067
  if (hermesInstalled) {
907
- out.push(join10(home, ".hermes", "skills"));
1068
+ out.push(join12(home, ".hermes", "skills"));
908
1069
  }
909
1070
  if (piInstalled) {
910
- out.push(join10(home, ".pi", "agent", "skills"));
1071
+ out.push(join12(home, ".pi", "agent", "skills"));
911
1072
  }
912
1073
  return out;
913
1074
  }
914
- function detectAgentSkillsRoots(canonicalRoot, home = homedir7()) {
1075
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir9()) {
915
1076
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
916
1077
  }
917
1078
 
@@ -955,15 +1116,15 @@ function isMissingTableError(message) {
955
1116
  }
956
1117
  function resolvePullDestination(install, cwd) {
957
1118
  if (install === "global")
958
- return join11(homedir8(), ".claude", "skills");
1119
+ return join13(homedir10(), ".claude", "skills");
959
1120
  if (!cwd)
960
1121
  throw new Error("install=project requires a cwd");
961
- return join11(cwd, ".claude", "skills");
1122
+ return join13(cwd, ".claude", "skills");
962
1123
  }
963
1124
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
964
1125
  const out = [];
965
1126
  for (const root of agentRoots) {
966
- const link = join11(root, dirName);
1127
+ const link = join13(root, dirName);
967
1128
  let existing;
968
1129
  try {
969
1130
  existing = lstatSync2(link);
@@ -985,13 +1146,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
985
1146
  continue;
986
1147
  }
987
1148
  try {
988
- unlinkSync3(link);
1149
+ unlinkSync4(link);
989
1150
  } catch {
990
1151
  continue;
991
1152
  }
992
1153
  }
993
1154
  try {
994
- mkdirSync5(dirname3(link), { recursive: true });
1155
+ mkdirSync7(dirname5(link), { recursive: true });
995
1156
  symlinkSync(canonicalDir, link, "dir");
996
1157
  out.push(link);
997
1158
  } catch {
@@ -1006,8 +1167,8 @@ function backfillSymlinks(installRoot) {
1006
1167
  return;
1007
1168
  const detected = detectAgentSkillsRoots(installRoot);
1008
1169
  for (const entry of entries) {
1009
- const canonical = join11(entry.installRoot, entry.dirName);
1010
- if (!existsSync8(canonical))
1170
+ const canonical = join13(entry.installRoot, entry.dirName);
1171
+ if (!existsSync10(canonical))
1011
1172
  continue;
1012
1173
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
1013
1174
  if (sameSorted(fresh, entry.symlinks))
@@ -1117,10 +1278,10 @@ function renderFrontmatter(fm) {
1117
1278
  return lines.join("\n");
1118
1279
  }
1119
1280
  function readLocalVersion(path) {
1120
- if (!existsSync8(path))
1281
+ if (!existsSync10(path))
1121
1282
  return null;
1122
1283
  try {
1123
- const text = readFileSync7(path, "utf-8");
1284
+ const text = readFileSync8(path, "utf-8");
1124
1285
  const parsed = parseFrontmatter(text);
1125
1286
  if (!parsed)
1126
1287
  return null;
@@ -1215,8 +1376,8 @@ async function runPull(opts) {
1215
1376
  summary.skipped++;
1216
1377
  continue;
1217
1378
  }
1218
- const skillDir = join11(root, dirName);
1219
- const skillFile = join11(skillDir, "SKILL.md");
1379
+ const skillDir = join13(root, dirName);
1380
+ const skillFile = join13(skillDir, "SKILL.md");
1220
1381
  const remoteVersion = Number(row.version ?? 1);
1221
1382
  const localVersion = readLocalVersion(skillFile);
1222
1383
  const action = decideAction({
@@ -1227,14 +1388,14 @@ async function runPull(opts) {
1227
1388
  });
1228
1389
  let manifestError;
1229
1390
  if (action === "wrote") {
1230
- mkdirSync5(skillDir, { recursive: true });
1231
- if (existsSync8(skillFile)) {
1391
+ mkdirSync7(skillDir, { recursive: true });
1392
+ if (existsSync10(skillFile)) {
1232
1393
  try {
1233
1394
  renameSync3(skillFile, `${skillFile}.bak`);
1234
1395
  } catch {
1235
1396
  }
1236
1397
  }
1237
- writeFileSync5(skillFile, renderSkillFile(row));
1398
+ writeFileSync6(skillFile, renderSkillFile(row));
1238
1399
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
1239
1400
  try {
1240
1401
  recordPull({
@@ -1330,7 +1491,7 @@ async function autoPullSkills(deps = {}) {
1330
1491
 
1331
1492
  // dist/src/hooks/cursor/session-start.js
1332
1493
  var log5 = (msg) => log("cursor-session-start", msg);
1333
- var __bundleDir = dirname4(fileURLToPath(import.meta.url));
1494
+ var __bundleDir = dirname6(fileURLToPath2(import.meta.url));
1334
1495
  var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
1335
1496
 
1336
1497
  Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
@@ -1350,22 +1511,7 @@ Organization management \u2014 each argument is SEPARATE (do NOT quote subcomman
1350
1511
  - hivemind remove <user-id> \u2014 remove member
1351
1512
 
1352
1513
  SKILLS (skillify) \u2014 mine + share reusable skills across the org:
1353
- - hivemind skillify \u2014 show scope/team/install + per-project state
1354
- - hivemind skillify pull \u2014 sync project skills from the org table
1355
- - hivemind skillify pull --user <email> \u2014 only that author's skills
1356
- - hivemind skillify pull --users a,b,c \u2014 multiple authors (CSV)
1357
- - hivemind skillify pull --all-users \u2014 explicit "no author filter"
1358
- - hivemind skillify pull --to project|global \u2014 install location
1359
- - hivemind skillify pull --dry-run \u2014 preview only
1360
- - hivemind skillify pull --force \u2014 overwrite local (creates .bak)
1361
- - hivemind skillify pull <skill-name> \u2014 pull only that skill (combines with --user)
1362
- - hivemind skillify unpull \u2014 remove every skill previously installed by pull
1363
- - hivemind skillify unpull --user <email> \u2014 remove only that author's pulls
1364
- - hivemind skillify unpull --not-mine \u2014 remove all pulls except your own
1365
- - hivemind skillify unpull --dry-run \u2014 preview without touching disk
1366
- - hivemind skillify scope <me|team> \u2014 sharing scope for new skills
1367
- - hivemind skillify install <project|global> \u2014 default install location
1368
- - hivemind skillify team add|remove|list <name> \u2014 manage team list`;
1514
+ ${renderSkillifyCommands()}`;
1369
1515
  function resolveSessionId(input) {
1370
1516
  return input.session_id ?? input.conversation_id ?? `cursor-${Date.now()}`;
1371
1517
  }
@@ -1404,6 +1550,8 @@ async function main() {
1404
1550
  const creds = loadCredentials();
1405
1551
  if (!creds?.token) {
1406
1552
  log5("no credentials found");
1553
+ const auto = maybeAutoMineLocal();
1554
+ log5(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
1407
1555
  } else {
1408
1556
  log5(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
1409
1557
  }
@@ -1433,9 +1581,12 @@ async function main() {
1433
1581
  if (current)
1434
1582
  versionNotice = `
1435
1583
  Hivemind v${current}`;
1584
+ const localMined = countLocalManifestEntries();
1585
+ const localMinedNote = localMined > 0 ? `
1586
+ ${localMined} local skill${localMined === 1 ? "" : "s"} from past 'hivemind skillify mine-local' run(s) live in ~/.claude/skills/. Run 'hivemind login' to start sharing new mining results with your team.` : "";
1436
1587
  const additionalContext = creds?.token ? `${context}
1437
1588
  Logged in to Deeplake as org: ${creds.orgName ?? creds.orgId} (workspace: ${creds.workspaceId ?? "default"})${versionNotice}` : `${context}
1438
- Not logged in to Deeplake. Run: hivemind login${versionNotice}`;
1589
+ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`;
1439
1590
  console.log(JSON.stringify({ additional_context: additionalContext }));
1440
1591
  }
1441
1592
  main().catch((e) => {