@deeplake/hivemind 0.7.25 → 0.7.27

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.
@@ -52,8 +52,8 @@ var init_index_marker_store = __esm({
52
52
  });
53
53
 
54
54
  // dist/src/hooks/hermes/session-start.js
55
- import { fileURLToPath } from "node:url";
56
- import { dirname as dirname4 } from "node:path";
55
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
56
+ import { dirname as dirname6 } from "node:path";
57
57
 
58
58
  // dist/src/commands/auth.js
59
59
  import { execSync } from "node:child_process";
@@ -560,6 +560,162 @@ var DeeplakeApi = class {
560
560
  }
561
561
  };
562
562
 
563
+ // dist/src/cli/skillify-spec.js
564
+ var SKILLIFY_COMMANDS = [
565
+ { cmd: "hivemind skillify", desc: "show scope, team, install, per-project state" },
566
+ { cmd: "hivemind skillify pull", desc: "sync project skills from the org table to local FS" },
567
+ { cmd: "hivemind skillify pull --user <email>", desc: "only skills authored by that user" },
568
+ { cmd: "hivemind skillify pull --users <a,b,c>", desc: "only skills from those authors" },
569
+ { cmd: "hivemind skillify pull --all-users", desc: 'explicit "no author filter" (default)' },
570
+ { cmd: "hivemind skillify pull --to <project|global>", desc: "install location (project=cwd/.claude/skills, global=~/.claude/skills)" },
571
+ { cmd: "hivemind skillify pull --dry-run", desc: "preview without touching disk" },
572
+ { cmd: "hivemind skillify pull --force", desc: "overwrite local files even if up-to-date (creates .bak)" },
573
+ { cmd: "hivemind skillify pull <skill-name>", desc: "pull only that one skill (combines with --user)" },
574
+ { cmd: "hivemind skillify unpull", desc: "remove every skill previously installed by pull" },
575
+ { cmd: "hivemind skillify unpull --user <email>", desc: "remove only that author's pulls" },
576
+ { cmd: "hivemind skillify unpull --not-mine", desc: "remove all pulls except your own" },
577
+ { cmd: "hivemind skillify unpull --dry-run", desc: "preview without touching disk" },
578
+ { cmd: "hivemind skillify scope <me|team|org>", desc: "sharing scope for newly mined skills" },
579
+ { cmd: "hivemind skillify install <project|global>", desc: "default install location for new skills" },
580
+ { cmd: "hivemind skillify promote <skill-name>", desc: "move a project skill to the global location" },
581
+ { cmd: "hivemind skillify team add|remove|list <name>", desc: "manage team member list" },
582
+ { cmd: "hivemind skillify mine-local", desc: "one-shot: mine skills from local sessions (no auth needed)" },
583
+ { cmd: "hivemind skillify mine-local --n <num|all>", desc: "how many sessions to mine (default: 8)" },
584
+ { cmd: "hivemind skillify mine-local --force", desc: "re-run even if the manifest sentinel exists" },
585
+ { cmd: "hivemind skillify mine-local --dry-run", desc: "stop before calling the LLM gate" }
586
+ ];
587
+ function renderSkillifyCommands() {
588
+ const maxLen = Math.max(...SKILLIFY_COMMANDS.map((c) => c.cmd.length));
589
+ return SKILLIFY_COMMANDS.map((c) => `- ${c.cmd.padEnd(maxLen + 2)} \u2014 ${c.desc}`).join("\n");
590
+ }
591
+
592
+ // dist/src/skillify/local-manifest.js
593
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
594
+ import { homedir as homedir4 } from "node:os";
595
+ import { dirname, join as join5 } from "node:path";
596
+ var LOCAL_MANIFEST_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.json");
597
+ var LOCAL_MINE_LOCK_PATH = join5(homedir4(), ".claude", "hivemind", "local-mined.lock");
598
+ function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
599
+ if (!existsSync3(path))
600
+ return null;
601
+ try {
602
+ return JSON.parse(readFileSync4(path, "utf-8"));
603
+ } catch {
604
+ return null;
605
+ }
606
+ }
607
+ function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
608
+ const m = readLocalManifest(path);
609
+ return Array.isArray(m?.entries) ? m.entries.length : 0;
610
+ }
611
+
612
+ // dist/src/skillify/spawn-mine-local-worker.js
613
+ import { execFileSync, spawn } from "node:child_process";
614
+ import { closeSync, existsSync as existsSync4, mkdirSync as mkdirSync4, openSync, readdirSync, statSync, unlinkSync as unlinkSync2 } from "node:fs";
615
+ import { homedir as homedir5 } from "node:os";
616
+ import { dirname as dirname2, join as join6 } from "node:path";
617
+ import { fileURLToPath } from "node:url";
618
+ var HOME = homedir5();
619
+ var HIVEMIND_DIR = join6(HOME, ".claude", "hivemind");
620
+ var LOG_PATH = join6(HOME, ".claude", "hooks", "mine-local.log");
621
+ var CLAUDE_PROJECTS_DIR = join6(HOME, ".claude", "projects");
622
+ var LOCK_STALE_MS = 15 * 60 * 1e3;
623
+ function findBundledCliPath() {
624
+ try {
625
+ const thisDir = dirname2(fileURLToPath(import.meta.url));
626
+ const cliPath = join6(thisDir, "..", "..", "bundle", "cli.js");
627
+ return existsSync4(cliPath) ? cliPath : null;
628
+ } catch {
629
+ return null;
630
+ }
631
+ }
632
+ function findHivemindLauncher() {
633
+ const bundled = findBundledCliPath();
634
+ if (bundled)
635
+ return { kind: "node-script", path: bundled };
636
+ try {
637
+ const out = execFileSync("which", ["hivemind"], {
638
+ encoding: "utf-8",
639
+ stdio: ["ignore", "pipe", "ignore"]
640
+ });
641
+ const bin = out.trim();
642
+ return bin ? { kind: "bin", path: bin } : null;
643
+ } catch {
644
+ return null;
645
+ }
646
+ }
647
+ function hasLocalClaudeSessions() {
648
+ if (!existsSync4(CLAUDE_PROJECTS_DIR))
649
+ return false;
650
+ let subdirs;
651
+ try {
652
+ subdirs = readdirSync(CLAUDE_PROJECTS_DIR);
653
+ } catch {
654
+ return false;
655
+ }
656
+ for (const sub of subdirs) {
657
+ let files;
658
+ try {
659
+ files = readdirSync(join6(CLAUDE_PROJECTS_DIR, sub));
660
+ } catch {
661
+ continue;
662
+ }
663
+ if (files.some((f) => f.endsWith(".jsonl")))
664
+ return true;
665
+ }
666
+ return false;
667
+ }
668
+ function maybeAutoMineLocal() {
669
+ if (existsSync4(LOCAL_MANIFEST_PATH))
670
+ return { triggered: false, reason: "manifest-exists" };
671
+ if (existsSync4(LOCAL_MINE_LOCK_PATH)) {
672
+ let stale = false;
673
+ try {
674
+ const stats = statSync(LOCAL_MINE_LOCK_PATH);
675
+ stale = Date.now() - stats.mtimeMs > LOCK_STALE_MS;
676
+ } catch {
677
+ }
678
+ if (!stale)
679
+ return { triggered: false, reason: "lock-exists" };
680
+ try {
681
+ unlinkSync2(LOCAL_MINE_LOCK_PATH);
682
+ } catch {
683
+ return { triggered: false, reason: "lock-exists" };
684
+ }
685
+ }
686
+ if (!hasLocalClaudeSessions())
687
+ return { triggered: false, reason: "no-claude-sessions" };
688
+ const launcher = findHivemindLauncher();
689
+ if (!launcher)
690
+ return { triggered: false, reason: "no-hivemind-bin" };
691
+ try {
692
+ mkdirSync4(HIVEMIND_DIR, { recursive: true });
693
+ const fd = openSync(LOCAL_MINE_LOCK_PATH, "wx");
694
+ closeSync(fd);
695
+ } catch {
696
+ return { triggered: false, reason: "lock-acquire-failed" };
697
+ }
698
+ try {
699
+ mkdirSync4(join6(HOME, ".claude", "hooks"), { recursive: true });
700
+ const out = openSync(LOG_PATH, "a");
701
+ const [cmd, args] = launcher.kind === "node-script" ? [process.execPath, [launcher.path, "skillify", "mine-local"]] : [launcher.path, ["skillify", "mine-local"]];
702
+ const child = spawn(cmd, args, {
703
+ detached: true,
704
+ stdio: ["ignore", out, out],
705
+ env: process.env
706
+ });
707
+ closeSync(out);
708
+ child.unref();
709
+ return { triggered: true };
710
+ } catch {
711
+ try {
712
+ unlinkSync2(LOCAL_MINE_LOCK_PATH);
713
+ } catch {
714
+ }
715
+ return { triggered: false, reason: "spawn-failed" };
716
+ }
717
+ }
718
+
563
719
  // dist/src/utils/stdin.js
564
720
  function readStdin() {
565
721
  return new Promise((resolve, reject) => {
@@ -578,18 +734,18 @@ function readStdin() {
578
734
  }
579
735
 
580
736
  // dist/src/utils/version-check.js
581
- import { readFileSync as readFileSync4 } from "node:fs";
582
- import { dirname, join as join5 } from "node:path";
737
+ import { readFileSync as readFileSync5 } from "node:fs";
738
+ import { dirname as dirname3, join as join7 } from "node:path";
583
739
  function getInstalledVersion(bundleDir, pluginManifestDir) {
584
740
  try {
585
- const pluginJson = join5(bundleDir, "..", pluginManifestDir, "plugin.json");
586
- const plugin = JSON.parse(readFileSync4(pluginJson, "utf-8"));
741
+ const pluginJson = join7(bundleDir, "..", pluginManifestDir, "plugin.json");
742
+ const plugin = JSON.parse(readFileSync5(pluginJson, "utf-8"));
587
743
  if (plugin.version)
588
744
  return plugin.version;
589
745
  } catch {
590
746
  }
591
747
  try {
592
- const stamp = readFileSync4(join5(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
748
+ const stamp = readFileSync5(join7(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
593
749
  if (stamp)
594
750
  return stamp;
595
751
  } catch {
@@ -604,14 +760,14 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
604
760
  ]);
605
761
  let dir = bundleDir;
606
762
  for (let i = 0; i < 5; i++) {
607
- const candidate = join5(dir, "package.json");
763
+ const candidate = join7(dir, "package.json");
608
764
  try {
609
- const pkg = JSON.parse(readFileSync4(candidate, "utf-8"));
765
+ const pkg = JSON.parse(readFileSync5(candidate, "utf-8"));
610
766
  if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
611
767
  return pkg.version;
612
768
  } catch {
613
769
  }
614
- const parent = dirname(dir);
770
+ const parent = dirname3(dir);
615
771
  if (parent === dir)
616
772
  break;
617
773
  dir = parent;
@@ -620,12 +776,12 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
620
776
  }
621
777
 
622
778
  // dist/src/hooks/shared/autoupdate.js
623
- import { spawn } from "node:child_process";
624
- import { existsSync as existsSync3 } from "node:fs";
625
- import { join as join6 } from "node:path";
779
+ import { spawn as spawn2 } from "node:child_process";
780
+ import { existsSync as existsSync5 } from "node:fs";
781
+ import { join as join8 } from "node:path";
626
782
  var log3 = (msg) => log("autoupdate", msg);
627
783
  var defaultSpawn = (cmd, args) => {
628
- const child = spawn(cmd, args, {
784
+ const child = spawn2(cmd, args, {
629
785
  detached: true,
630
786
  stdio: "ignore"
631
787
  });
@@ -638,8 +794,8 @@ function findHivemindOnPath() {
638
794
  const PATH = process.env.PATH ?? "";
639
795
  const dirs = PATH.split(":").filter(Boolean);
640
796
  for (const dir of dirs) {
641
- const candidate = join6(dir, "hivemind");
642
- if (existsSync3(candidate))
797
+ const candidate = join8(dir, "hivemind");
798
+ if (existsSync5(candidate))
643
799
  return candidate;
644
800
  }
645
801
  return null;
@@ -673,14 +829,14 @@ async function autoUpdate(creds, opts) {
673
829
  }
674
830
 
675
831
  // dist/src/skillify/pull.js
676
- 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";
677
- import { homedir as homedir8 } from "node:os";
678
- import { dirname as dirname3, join as join11 } from "node:path";
832
+ 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";
833
+ import { homedir as homedir10 } from "node:os";
834
+ import { dirname as dirname5, join as join13 } from "node:path";
679
835
 
680
836
  // dist/src/skillify/skill-writer.js
681
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
682
- import { homedir as homedir4 } from "node:os";
683
- import { join as join7 } from "node:path";
837
+ import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
838
+ import { homedir as homedir6 } from "node:os";
839
+ import { join as join9 } from "node:path";
684
840
  function assertValidSkillName(name) {
685
841
  if (typeof name !== "string" || name.length === 0) {
686
842
  throw new Error(`invalid skill name: empty or non-string`);
@@ -746,26 +902,26 @@ function parseFrontmatter(text) {
746
902
  }
747
903
 
748
904
  // dist/src/skillify/manifest.js
749
- import { existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
750
- import { homedir as homedir6 } from "node:os";
751
- import { dirname as dirname2, join as join9 } from "node:path";
905
+ import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "node:fs";
906
+ import { homedir as homedir8 } from "node:os";
907
+ import { dirname as dirname4, join as join11 } from "node:path";
752
908
 
753
909
  // dist/src/skillify/legacy-migration.js
754
- import { existsSync as existsSync5, renameSync } from "node:fs";
755
- import { homedir as homedir5 } from "node:os";
756
- import { join as join8 } from "node:path";
910
+ import { existsSync as existsSync7, renameSync } from "node:fs";
911
+ import { homedir as homedir7 } from "node:os";
912
+ import { join as join10 } from "node:path";
757
913
  var dlog = (msg) => log("skillify-migrate", msg);
758
914
  var attempted = false;
759
915
  function migrateLegacyStateDir() {
760
916
  if (attempted)
761
917
  return;
762
918
  attempted = true;
763
- const root = join8(homedir5(), ".deeplake", "state");
764
- const legacy = join8(root, "skilify");
765
- const current = join8(root, "skillify");
766
- if (!existsSync5(legacy))
919
+ const root = join10(homedir7(), ".deeplake", "state");
920
+ const legacy = join10(root, "skilify");
921
+ const current = join10(root, "skillify");
922
+ if (!existsSync7(legacy))
767
923
  return;
768
- if (existsSync5(current))
924
+ if (existsSync7(current))
769
925
  return;
770
926
  try {
771
927
  renameSync(legacy, current);
@@ -785,15 +941,15 @@ function emptyManifest() {
785
941
  return { version: 1, entries: [] };
786
942
  }
787
943
  function manifestPath() {
788
- return join9(homedir6(), ".deeplake", "state", "skillify", "pulled.json");
944
+ return join11(homedir8(), ".deeplake", "state", "skillify", "pulled.json");
789
945
  }
790
946
  function loadManifest(path = manifestPath()) {
791
947
  migrateLegacyStateDir();
792
- if (!existsSync6(path))
948
+ if (!existsSync8(path))
793
949
  return emptyManifest();
794
950
  let raw;
795
951
  try {
796
- raw = readFileSync6(path, "utf-8");
952
+ raw = readFileSync7(path, "utf-8");
797
953
  } catch {
798
954
  return emptyManifest();
799
955
  }
@@ -840,9 +996,9 @@ function loadManifest(path = manifestPath()) {
840
996
  }
841
997
  function saveManifest(m, path = manifestPath()) {
842
998
  migrateLegacyStateDir();
843
- mkdirSync4(dirname2(path), { recursive: true });
999
+ mkdirSync6(dirname4(path), { recursive: true });
844
1000
  const tmp = `${path}.tmp`;
845
- writeFileSync4(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
1001
+ writeFileSync5(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
846
1002
  renameSync2(tmp, path);
847
1003
  }
848
1004
  function recordPull(entry, path = manifestPath()) {
@@ -868,7 +1024,7 @@ function unlinkSymlinks(paths) {
868
1024
  if (!st.isSymbolicLink())
869
1025
  continue;
870
1026
  try {
871
- unlinkSync2(path);
1027
+ unlinkSync3(path);
872
1028
  } catch {
873
1029
  }
874
1030
  }
@@ -878,7 +1034,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
878
1034
  const live = [];
879
1035
  let pruned = 0;
880
1036
  for (const e of m.entries) {
881
- if (existsSync6(join9(e.installRoot, e.dirName))) {
1037
+ if (existsSync8(join11(e.installRoot, e.dirName))) {
882
1038
  live.push(e);
883
1039
  continue;
884
1040
  }
@@ -891,26 +1047,26 @@ function pruneOrphanedEntries(path = manifestPath()) {
891
1047
  }
892
1048
 
893
1049
  // dist/src/skillify/agent-roots.js
894
- import { existsSync as existsSync7 } from "node:fs";
895
- import { homedir as homedir7 } from "node:os";
896
- import { join as join10 } from "node:path";
1050
+ import { existsSync as existsSync9 } from "node:fs";
1051
+ import { homedir as homedir9 } from "node:os";
1052
+ import { join as join12 } from "node:path";
897
1053
  function resolveDetected(home) {
898
1054
  const out = [];
899
- const codexInstalled = existsSync7(join10(home, ".codex"));
900
- const piInstalled = existsSync7(join10(home, ".pi", "agent"));
901
- const hermesInstalled = existsSync7(join10(home, ".hermes"));
1055
+ const codexInstalled = existsSync9(join12(home, ".codex"));
1056
+ const piInstalled = existsSync9(join12(home, ".pi", "agent"));
1057
+ const hermesInstalled = existsSync9(join12(home, ".hermes"));
902
1058
  if (codexInstalled || piInstalled) {
903
- out.push(join10(home, ".agents", "skills"));
1059
+ out.push(join12(home, ".agents", "skills"));
904
1060
  }
905
1061
  if (hermesInstalled) {
906
- out.push(join10(home, ".hermes", "skills"));
1062
+ out.push(join12(home, ".hermes", "skills"));
907
1063
  }
908
1064
  if (piInstalled) {
909
- out.push(join10(home, ".pi", "agent", "skills"));
1065
+ out.push(join12(home, ".pi", "agent", "skills"));
910
1066
  }
911
1067
  return out;
912
1068
  }
913
- function detectAgentSkillsRoots(canonicalRoot, home = homedir7()) {
1069
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir9()) {
914
1070
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
915
1071
  }
916
1072
 
@@ -954,15 +1110,15 @@ function isMissingTableError(message) {
954
1110
  }
955
1111
  function resolvePullDestination(install, cwd) {
956
1112
  if (install === "global")
957
- return join11(homedir8(), ".claude", "skills");
1113
+ return join13(homedir10(), ".claude", "skills");
958
1114
  if (!cwd)
959
1115
  throw new Error("install=project requires a cwd");
960
- return join11(cwd, ".claude", "skills");
1116
+ return join13(cwd, ".claude", "skills");
961
1117
  }
962
1118
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
963
1119
  const out = [];
964
1120
  for (const root of agentRoots) {
965
- const link = join11(root, dirName);
1121
+ const link = join13(root, dirName);
966
1122
  let existing;
967
1123
  try {
968
1124
  existing = lstatSync2(link);
@@ -984,13 +1140,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
984
1140
  continue;
985
1141
  }
986
1142
  try {
987
- unlinkSync3(link);
1143
+ unlinkSync4(link);
988
1144
  } catch {
989
1145
  continue;
990
1146
  }
991
1147
  }
992
1148
  try {
993
- mkdirSync5(dirname3(link), { recursive: true });
1149
+ mkdirSync7(dirname5(link), { recursive: true });
994
1150
  symlinkSync(canonicalDir, link, "dir");
995
1151
  out.push(link);
996
1152
  } catch {
@@ -1005,8 +1161,8 @@ function backfillSymlinks(installRoot) {
1005
1161
  return;
1006
1162
  const detected = detectAgentSkillsRoots(installRoot);
1007
1163
  for (const entry of entries) {
1008
- const canonical = join11(entry.installRoot, entry.dirName);
1009
- if (!existsSync8(canonical))
1164
+ const canonical = join13(entry.installRoot, entry.dirName);
1165
+ if (!existsSync10(canonical))
1010
1166
  continue;
1011
1167
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
1012
1168
  if (sameSorted(fresh, entry.symlinks))
@@ -1116,10 +1272,10 @@ function renderFrontmatter(fm) {
1116
1272
  return lines.join("\n");
1117
1273
  }
1118
1274
  function readLocalVersion(path) {
1119
- if (!existsSync8(path))
1275
+ if (!existsSync10(path))
1120
1276
  return null;
1121
1277
  try {
1122
- const text = readFileSync7(path, "utf-8");
1278
+ const text = readFileSync8(path, "utf-8");
1123
1279
  const parsed = parseFrontmatter(text);
1124
1280
  if (!parsed)
1125
1281
  return null;
@@ -1214,8 +1370,8 @@ async function runPull(opts) {
1214
1370
  summary.skipped++;
1215
1371
  continue;
1216
1372
  }
1217
- const skillDir = join11(root, dirName);
1218
- const skillFile = join11(skillDir, "SKILL.md");
1373
+ const skillDir = join13(root, dirName);
1374
+ const skillFile = join13(skillDir, "SKILL.md");
1219
1375
  const remoteVersion = Number(row.version ?? 1);
1220
1376
  const localVersion = readLocalVersion(skillFile);
1221
1377
  const action = decideAction({
@@ -1226,14 +1382,14 @@ async function runPull(opts) {
1226
1382
  });
1227
1383
  let manifestError;
1228
1384
  if (action === "wrote") {
1229
- mkdirSync5(skillDir, { recursive: true });
1230
- if (existsSync8(skillFile)) {
1385
+ mkdirSync7(skillDir, { recursive: true });
1386
+ if (existsSync10(skillFile)) {
1231
1387
  try {
1232
1388
  renameSync3(skillFile, `${skillFile}.bak`);
1233
1389
  } catch {
1234
1390
  }
1235
1391
  }
1236
- writeFileSync5(skillFile, renderSkillFile(row));
1392
+ writeFileSync6(skillFile, renderSkillFile(row));
1237
1393
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
1238
1394
  try {
1239
1395
  recordPull({
@@ -1329,7 +1485,7 @@ async function autoPullSkills(deps = {}) {
1329
1485
 
1330
1486
  // dist/src/hooks/hermes/session-start.js
1331
1487
  var log5 = (msg) => log("hermes-session-start", msg);
1332
- var __bundleDir = dirname4(fileURLToPath(import.meta.url));
1488
+ var __bundleDir = dirname6(fileURLToPath2(import.meta.url));
1333
1489
  var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
1334
1490
 
1335
1491
  Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
@@ -1350,22 +1506,7 @@ Organization management \u2014 each argument is SEPARATE (do NOT quote subcomman
1350
1506
  - hivemind remove <user-id> \u2014 remove member
1351
1507
 
1352
1508
  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`;
1509
+ ${renderSkillifyCommands()}`;
1369
1510
  async function createPlaceholder(api, table, sessionId, cwd, userName, orgName, workspaceId, pluginVersion) {
1370
1511
  const summaryPath = `/summaries/${userName}/${sessionId}.md`;
1371
1512
  const existing = await api.query(`SELECT path FROM "${table}" WHERE path = '${sqlStr(summaryPath)}' LIMIT 1`);
@@ -1393,6 +1534,9 @@ async function main() {
1393
1534
  const cwd = input.cwd ?? process.cwd();
1394
1535
  const creds = loadCredentials();
1395
1536
  const captureEnabled = process.env.HIVEMIND_CAPTURE !== "false";
1537
+ if (!creds?.token) {
1538
+ maybeAutoMineLocal();
1539
+ }
1396
1540
  await autoUpdate(creds, { agent: "hermes" });
1397
1541
  const current = getInstalledVersion(__bundleDir, ".claude-plugin");
1398
1542
  const pluginVersion = current ?? "";
@@ -1416,9 +1560,12 @@ async function main() {
1416
1560
  if (current)
1417
1561
  versionNotice = `
1418
1562
  Hivemind v${current}`;
1563
+ const localMined = countLocalManifestEntries();
1564
+ const localMinedNote = localMined > 0 ? `
1565
+ ${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.` : "";
1419
1566
  const additional = creds?.token ? `${context}
1420
1567
  Logged in to Deeplake as org: ${creds.orgName ?? creds.orgId} (workspace: ${creds.workspaceId ?? "default"})${versionNotice}` : `${context}
1421
- Not logged in to Deeplake. Run: hivemind login${versionNotice}`;
1568
+ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`;
1422
1569
  console.log(JSON.stringify({ context: additional }));
1423
1570
  }
1424
1571
  main().catch((e) => {
@@ -1073,7 +1073,7 @@ function extractLatestVersion(body) {
1073
1073
  return typeof v === "string" && v.length > 0 ? v : null;
1074
1074
  }
1075
1075
  function getInstalledVersion() {
1076
- return "0.7.25".length > 0 ? "0.7.25" : null;
1076
+ return "0.7.27".length > 0 ? "0.7.27" : null;
1077
1077
  }
1078
1078
  function isNewer(latest, current) {
1079
1079
  const parse = (v) => v.replace(/-.*$/, "").split(".").map(Number);
@@ -52,5 +52,5 @@
52
52
  }
53
53
  }
54
54
  },
55
- "version": "0.7.25"
55
+ "version": "0.7.27"
56
56
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hivemind",
3
- "version": "0.7.25",
3
+ "version": "0.7.27",
4
4
  "type": "module",
5
5
  "description": "Hivemind — cloud-backed persistent shared memory for AI agents, powered by DeepLake",
6
6
  "license": "Apache-2.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeplake/hivemind",
3
- "version": "0.7.25",
3
+ "version": "0.7.27",
4
4
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
5
5
  "type": "module",
6
6
  "repository": {