@deeplake/hivemind 0.7.16 → 0.7.17

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.
@@ -6,13 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Cloud-backed persistent shared memory for AI agents powered by Deeplake",
9
- "version": "0.7.16"
9
+ "version": "0.7.17"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "hivemind",
14
14
  "description": "Persistent shared memory powered by Deeplake — captures all session activity and provides cross-session, cross-agent memory search",
15
- "version": "0.7.16",
15
+ "version": "0.7.17",
16
16
  "source": "./claude-code",
17
17
  "homepage": "https://github.com/activeloopai/hivemind"
18
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hivemind",
3
3
  "description": "Cloud-backed persistent memory powered by Deeplake — read, write, and share memory across Claude Code sessions and agents",
4
- "version": "0.7.16",
4
+ "version": "0.7.17",
5
5
  "author": {
6
6
  "name": "Activeloop",
7
7
  "url": "https://deeplake.ai"
package/bundle/cli.js CHANGED
@@ -3353,6 +3353,7 @@ var VERSION_DIR = join8(PI_AGENT_DIR, ".hivemind");
3353
3353
  var WIKI_WORKER_DIR = join8(PI_AGENT_DIR, "hivemind");
3354
3354
  var WIKI_WORKER_PATH = join8(WIKI_WORKER_DIR, "wiki-worker.js");
3355
3355
  var SKILIFY_WORKER_PATH = join8(WIKI_WORKER_DIR, "skilify-worker.js");
3356
+ var AUTOPULL_WORKER_PATH = join8(WIKI_WORKER_DIR, "autopull-worker.js");
3356
3357
  var HIVEMIND_BLOCK_START = "<!-- BEGIN hivemind-memory -->";
3357
3358
  var HIVEMIND_BLOCK_END = "<!-- END hivemind-memory -->";
3358
3359
  var HIVEMIND_BLOCK_BODY = `${HIVEMIND_BLOCK_START}
@@ -3442,6 +3443,11 @@ function installPi() {
3442
3443
  ensureDir(WIKI_WORKER_DIR);
3443
3444
  copyFileSync2(srcSkilifyWorker, SKILIFY_WORKER_PATH);
3444
3445
  }
3446
+ const srcAutopullWorker = join8(pkgRoot(), "pi", "bundle", "autopull-worker.js");
3447
+ if (existsSync7(srcAutopullWorker)) {
3448
+ ensureDir(WIKI_WORKER_DIR);
3449
+ copyFileSync2(srcAutopullWorker, AUTOPULL_WORKER_PATH);
3450
+ }
3445
3451
  ensureDir(VERSION_DIR);
3446
3452
  writeVersionStamp(VERSION_DIR, getVersion());
3447
3453
  log(` pi AGENTS.md updated -> ${AGENTS_MD}`);
@@ -3452,6 +3458,9 @@ function installPi() {
3452
3458
  if (existsSync7(SKILIFY_WORKER_PATH)) {
3453
3459
  log(` pi skilify-worker installed -> ${SKILIFY_WORKER_PATH}`);
3454
3460
  }
3461
+ if (existsSync7(AUTOPULL_WORKER_PATH)) {
3462
+ log(` pi autopull-worker installed -> ${AUTOPULL_WORKER_PATH}`);
3463
+ }
3455
3464
  }
3456
3465
  function uninstallPi() {
3457
3466
  if (existsSync7(LEGACY_SKILL_DIR)) {
@@ -4710,9 +4719,9 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
4710
4719
  }
4711
4720
 
4712
4721
  // dist/src/commands/skilify.js
4713
- import { readdirSync as readdirSync4, existsSync as existsSync17, readFileSync as readFileSync13, mkdirSync as mkdirSync8, renameSync as renameSync3 } from "node:fs";
4714
- import { homedir as homedir10 } from "node:os";
4715
- import { dirname as dirname3, join as join20 } from "node:path";
4722
+ import { readdirSync as readdirSync4, existsSync as existsSync18, readFileSync as readFileSync13, mkdirSync as mkdirSync8, renameSync as renameSync3 } from "node:fs";
4723
+ import { homedir as homedir11 } from "node:os";
4724
+ import { dirname as dirname4, join as join21 } from "node:path";
4716
4725
 
4717
4726
  // dist/src/skilify/scope-config.js
4718
4727
  import { existsSync as existsSync12, mkdirSync as mkdirSync4, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
@@ -4740,9 +4749,9 @@ function saveScopeConfig(cfg) {
4740
4749
  }
4741
4750
 
4742
4751
  // dist/src/skilify/pull.js
4743
- import { existsSync as existsSync15, readFileSync as readFileSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, renameSync as renameSync2 } from "node:fs";
4744
- import { homedir as homedir8 } from "node:os";
4745
- import { join as join18 } from "node:path";
4752
+ import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync7, renameSync as renameSync2, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync8 } from "node:fs";
4753
+ import { homedir as homedir9 } from "node:os";
4754
+ import { dirname as dirname3, join as join19 } from "node:path";
4746
4755
 
4747
4756
  // dist/src/skilify/skill-writer.js
4748
4757
  import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync10, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync7 } from "node:fs";
@@ -4806,7 +4815,7 @@ function parseFrontmatter(text) {
4806
4815
  }
4807
4816
 
4808
4817
  // dist/src/skilify/manifest.js
4809
- import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync8 } from "node:fs";
4818
+ import { existsSync as existsSync14, lstatSync as lstatSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync11, renameSync, unlinkSync as unlinkSync7, writeFileSync as writeFileSync8 } from "node:fs";
4810
4819
  import { homedir as homedir7 } from "node:os";
4811
4820
  import { dirname as dirname2, join as join17 } from "node:path";
4812
4821
  function emptyManifest() {
@@ -4846,6 +4855,8 @@ function loadManifest(path = manifestPath()) {
4846
4855
  continue;
4847
4856
  if (e.install !== "global" && e.install !== "project")
4848
4857
  continue;
4858
+ const symlinks = Array.isArray(e.symlinks) ? e.symlinks.filter((p) => typeof p === "string" && p.length > 0 && (p.startsWith("/") || /^[A-Za-z]:[\\/]/.test(p)) && // absolute (POSIX or Windows)
4859
+ !p.includes("..")) : [];
4849
4860
  entries.push({
4850
4861
  dirName: e.dirName,
4851
4862
  name: e.name,
@@ -4854,7 +4865,8 @@ function loadManifest(path = manifestPath()) {
4854
4865
  remoteVersion: typeof e.remoteVersion === "number" ? e.remoteVersion : 1,
4855
4866
  install: e.install,
4856
4867
  installRoot: e.installRoot,
4857
- pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString()
4868
+ pulledAt: typeof e.pulledAt === "string" ? e.pulledAt : (/* @__PURE__ */ new Date()).toISOString(),
4869
+ symlinks
4858
4870
  });
4859
4871
  }
4860
4872
  return { version: 1, entries };
@@ -4887,6 +4899,62 @@ function removePullEntry(install, installRoot, dirName, path = manifestPath()) {
4887
4899
  function entriesForRoot(m, install, installRoot) {
4888
4900
  return m.entries.filter((e) => e.install === install && e.installRoot === installRoot);
4889
4901
  }
4902
+ function unlinkSymlinks(paths) {
4903
+ for (const path of paths) {
4904
+ let st;
4905
+ try {
4906
+ st = lstatSync3(path);
4907
+ } catch {
4908
+ continue;
4909
+ }
4910
+ if (!st.isSymbolicLink())
4911
+ continue;
4912
+ try {
4913
+ unlinkSync7(path);
4914
+ } catch {
4915
+ }
4916
+ }
4917
+ }
4918
+ function pruneOrphanedEntries(path = manifestPath()) {
4919
+ const m = loadManifest(path);
4920
+ const live = [];
4921
+ let pruned = 0;
4922
+ for (const e of m.entries) {
4923
+ if (existsSync14(join17(e.installRoot, e.dirName))) {
4924
+ live.push(e);
4925
+ continue;
4926
+ }
4927
+ unlinkSymlinks(e.symlinks);
4928
+ pruned++;
4929
+ }
4930
+ if (pruned > 0)
4931
+ saveManifest({ version: 1, entries: live }, path);
4932
+ return pruned;
4933
+ }
4934
+
4935
+ // dist/src/skilify/agent-roots.js
4936
+ import { existsSync as existsSync15 } from "node:fs";
4937
+ import { homedir as homedir8 } from "node:os";
4938
+ import { join as join18 } from "node:path";
4939
+ function resolveDetected(home) {
4940
+ const out = [];
4941
+ const codexInstalled = existsSync15(join18(home, ".codex"));
4942
+ const piInstalled = existsSync15(join18(home, ".pi", "agent"));
4943
+ const hermesInstalled = existsSync15(join18(home, ".hermes"));
4944
+ if (codexInstalled || piInstalled) {
4945
+ out.push(join18(home, ".agents", "skills"));
4946
+ }
4947
+ if (hermesInstalled) {
4948
+ out.push(join18(home, ".hermes", "skills"));
4949
+ }
4950
+ if (piInstalled) {
4951
+ out.push(join18(home, ".pi", "agent", "skills"));
4952
+ }
4953
+ return out;
4954
+ }
4955
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir8()) {
4956
+ return resolveDetected(home).filter((p) => p !== canonicalRoot);
4957
+ }
4890
4958
 
4891
4959
  // dist/src/skilify/pull.js
4892
4960
  function assertValidAuthor(author) {
@@ -4920,10 +4988,78 @@ function isMissingTableError(message) {
4920
4988
  }
4921
4989
  function resolvePullDestination(install, cwd) {
4922
4990
  if (install === "global")
4923
- return join18(homedir8(), ".claude", "skills");
4991
+ return join19(homedir9(), ".claude", "skills");
4924
4992
  if (!cwd)
4925
4993
  throw new Error("install=project requires a cwd");
4926
- return join18(cwd, ".claude", "skills");
4994
+ return join19(cwd, ".claude", "skills");
4995
+ }
4996
+ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
4997
+ const out = [];
4998
+ for (const root of agentRoots) {
4999
+ const link = join19(root, dirName);
5000
+ let existing;
5001
+ try {
5002
+ existing = lstatSync4(link);
5003
+ } catch {
5004
+ existing = null;
5005
+ }
5006
+ if (existing) {
5007
+ if (!existing.isSymbolicLink()) {
5008
+ continue;
5009
+ }
5010
+ let current;
5011
+ try {
5012
+ current = readlinkSync2(link);
5013
+ } catch {
5014
+ current = null;
5015
+ }
5016
+ if (current === canonicalDir) {
5017
+ out.push(link);
5018
+ continue;
5019
+ }
5020
+ try {
5021
+ unlinkSync8(link);
5022
+ } catch {
5023
+ continue;
5024
+ }
5025
+ }
5026
+ try {
5027
+ mkdirSync7(dirname3(link), { recursive: true });
5028
+ symlinkSync2(canonicalDir, link, "dir");
5029
+ out.push(link);
5030
+ } catch {
5031
+ }
5032
+ }
5033
+ return out;
5034
+ }
5035
+ function backfillSymlinks(installRoot) {
5036
+ const manifest = loadManifest();
5037
+ const entries = entriesForRoot(manifest, "global", installRoot);
5038
+ if (entries.length === 0)
5039
+ return;
5040
+ const detected = detectAgentSkillsRoots(installRoot);
5041
+ for (const entry of entries) {
5042
+ const canonical = join19(entry.installRoot, entry.dirName);
5043
+ if (!existsSync16(canonical))
5044
+ continue;
5045
+ const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
5046
+ if (sameSorted(fresh, entry.symlinks))
5047
+ continue;
5048
+ try {
5049
+ recordPull({ ...entry, symlinks: fresh });
5050
+ } catch {
5051
+ }
5052
+ }
5053
+ }
5054
+ function sameSorted(a, b) {
5055
+ if (a.length !== b.length)
5056
+ return false;
5057
+ const sa = [...a].sort();
5058
+ const sb = [...b].sort();
5059
+ for (let i = 0; i < sa.length; i++)
5060
+ if (sa[i] !== sb[i])
5061
+ return false;
5062
+ return true;
4927
5063
  }
4928
5064
  function selectLatestPerName(rows) {
4929
5065
  const seen = /* @__PURE__ */ new Set();
@@ -4989,7 +5125,7 @@ function renderFrontmatter(fm) {
4989
5125
  return lines.join("\n");
4990
5126
  }
4991
5127
  function readLocalVersion(path) {
4992
- if (!existsSync15(path))
5128
+ if (!existsSync16(path))
4993
5129
  return null;
4994
5130
  try {
4995
5131
  const text = readFileSync12(path, "utf-8");
@@ -5009,6 +5145,8 @@ function decideAction(args) {
5009
5145
  return args.dryRun ? "dryrun" : "wrote";
5010
5146
  }
5011
5147
  async function runPull(opts) {
5148
+ if (!opts.dryRun)
5149
+ pruneOrphanedEntries();
5012
5150
  const sql = buildPullSql({
5013
5151
  tableName: opts.tableName,
5014
5152
  users: opts.users,
@@ -5076,8 +5214,8 @@ async function runPull(opts) {
5076
5214
  summary.skipped++;
5077
5215
  continue;
5078
5216
  }
5079
- const skillDir = join18(root, dirName);
5080
- const skillFile = join18(skillDir, "SKILL.md");
5217
+ const skillDir = join19(root, dirName);
5218
+ const skillFile = join19(skillDir, "SKILL.md");
5081
5219
  const remoteVersion = Number(row.version ?? 1);
5082
5220
  const localVersion = readLocalVersion(skillFile);
5083
5221
  const action = decideAction({
@@ -5089,13 +5227,14 @@ async function runPull(opts) {
5089
5227
  let manifestError;
5090
5228
  if (action === "wrote") {
5091
5229
  mkdirSync7(skillDir, { recursive: true });
5092
- if (existsSync15(skillFile)) {
5230
+ if (existsSync16(skillFile)) {
5093
5231
  try {
5094
5232
  renameSync2(skillFile, `${skillFile}.bak`);
5095
5233
  } catch {
5096
5234
  }
5097
5235
  }
5098
5236
  writeFileSync9(skillFile, renderSkillFile(row));
5237
+ const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
5099
5238
  try {
5100
5239
  recordPull({
5101
5240
  dirName,
@@ -5105,7 +5244,8 @@ async function runPull(opts) {
5105
5244
  remoteVersion,
5106
5245
  install: opts.install,
5107
5246
  installRoot: root,
5108
- pulledAt: (/* @__PURE__ */ new Date()).toISOString()
5247
+ pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
5248
+ symlinks
5109
5249
  });
5110
5250
  } catch (e) {
5111
5251
  manifestError = e?.message ?? String(e);
@@ -5128,19 +5268,22 @@ async function runPull(opts) {
5128
5268
  else
5129
5269
  summary.skipped++;
5130
5270
  }
5271
+ if (!opts.dryRun && opts.install === "global") {
5272
+ backfillSymlinks(root);
5273
+ }
5131
5274
  return summary;
5132
5275
  }
5133
5276
 
5134
5277
  // dist/src/skilify/unpull.js
5135
- import { existsSync as existsSync16, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync3 } from "node:fs";
5136
- import { homedir as homedir9 } from "node:os";
5137
- import { join as join19 } from "node:path";
5278
+ import { existsSync as existsSync17, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync3 } from "node:fs";
5279
+ import { homedir as homedir10 } from "node:os";
5280
+ import { join as join20 } from "node:path";
5138
5281
  function resolveUnpullRoot(install, cwd) {
5139
5282
  if (install === "global")
5140
- return join19(homedir9(), ".claude", "skills");
5283
+ return join20(homedir10(), ".claude", "skills");
5141
5284
  if (!cwd)
5142
5285
  throw new Error("cwd required when install === 'project'");
5143
- return join19(cwd, ".claude", "skills");
5286
+ return join20(cwd, ".claude", "skills");
5144
5287
  }
5145
5288
  function runUnpull(opts) {
5146
5289
  const root = resolveUnpullRoot(opts.install, opts.cwd);
@@ -5163,10 +5306,12 @@ function runUnpull(opts) {
5163
5306
  const entries = entriesForRoot(manifest, opts.install, root);
5164
5307
  for (const entry of entries) {
5165
5308
  summary.scanned++;
5166
- const path = join19(root, entry.dirName);
5167
- if (!existsSync16(path)) {
5168
- if (!opts.dryRun)
5309
+ const path = join20(root, entry.dirName);
5310
+ if (!existsSync17(path)) {
5311
+ if (!opts.dryRun) {
5312
+ unlinkSymlinks(entry.symlinks);
5169
5313
  removePullEntry(opts.install, entry.installRoot, entry.dirName);
5314
+ }
5170
5315
  summary.entries.push({
5171
5316
  dirName: entry.dirName,
5172
5317
  kind: "manifest-orphan",
@@ -5203,6 +5348,7 @@ function runUnpull(opts) {
5203
5348
  } else {
5204
5349
  try {
5205
5350
  rmSync5(path, { recursive: true, force: true });
5351
+ unlinkSymlinks(entry.symlinks);
5206
5352
  removePullEntry(opts.install, entry.installRoot, entry.dirName);
5207
5353
  result.action = "removed";
5208
5354
  summary.removed++;
@@ -5214,12 +5360,12 @@ function runUnpull(opts) {
5214
5360
  }
5215
5361
  summary.entries.push(result);
5216
5362
  }
5217
- if (existsSync16(root) && (opts.all || opts.legacyCleanup)) {
5363
+ if (existsSync17(root) && (opts.all || opts.legacyCleanup)) {
5218
5364
  const manifestDirNames = new Set(entries.map((e) => e.dirName));
5219
5365
  for (const dirName of readdirSync3(root)) {
5220
5366
  if (manifestDirNames.has(dirName))
5221
5367
  continue;
5222
- const path = join19(root, dirName);
5368
+ const path = join20(root, dirName);
5223
5369
  let st;
5224
5370
  try {
5225
5371
  st = statSync3(path);
@@ -5298,7 +5444,7 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
5298
5444
 
5299
5445
  // dist/src/commands/skilify.js
5300
5446
  function stateDir() {
5301
- return join20(homedir10(), ".deeplake", "state", "skilify");
5447
+ return join21(homedir11(), ".deeplake", "state", "skilify");
5302
5448
  }
5303
5449
  function showStatus() {
5304
5450
  const cfg = loadScopeConfig();
@@ -5306,7 +5452,7 @@ function showStatus() {
5306
5452
  console.log(`team: ${cfg.team.length === 0 ? "(empty)" : cfg.team.join(", ")}`);
5307
5453
  console.log(`install: ${cfg.install} (${cfg.install === "global" ? "~/.claude/skills/" : "<project>/.claude/skills/"})`);
5308
5454
  const dir = stateDir();
5309
- if (!existsSync17(dir)) {
5455
+ if (!existsSync18(dir)) {
5310
5456
  console.log(`state: (no projects tracked yet)`);
5311
5457
  return;
5312
5458
  }
@@ -5318,7 +5464,7 @@ function showStatus() {
5318
5464
  console.log(`state: ${files.length} project(s) tracked`);
5319
5465
  for (const f of files) {
5320
5466
  try {
5321
- const s = JSON.parse(readFileSync13(join20(dir, f), "utf-8"));
5467
+ const s = JSON.parse(readFileSync13(join21(dir, f), "utf-8"));
5322
5468
  const skills = s.skillsGenerated.length === 0 ? "none" : s.skillsGenerated.join(", ");
5323
5469
  console.log(` - ${s.project} (counter=${s.counter}, last=${s.lastDate ?? "never"}, skills=${skills})`);
5324
5470
  } catch {
@@ -5344,7 +5490,7 @@ function setInstall(loc) {
5344
5490
  }
5345
5491
  const cfg = loadScopeConfig();
5346
5492
  saveScopeConfig({ ...cfg, install: loc });
5347
- const path = loc === "global" ? join20(homedir10(), ".claude", "skills") : "<cwd>/.claude/skills";
5493
+ const path = loc === "global" ? join21(homedir11(), ".claude", "skills") : "<cwd>/.claude/skills";
5348
5494
  console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
5349
5495
  }
5350
5496
  function promoteSkill(name, cwd) {
@@ -5352,17 +5498,17 @@ function promoteSkill(name, cwd) {
5352
5498
  console.error("Usage: hivemind skilify promote <skill-name>");
5353
5499
  process.exit(1);
5354
5500
  }
5355
- const projectPath = join20(cwd, ".claude", "skills", name);
5356
- const globalPath = join20(homedir10(), ".claude", "skills", name);
5357
- if (!existsSync17(join20(projectPath, "SKILL.md"))) {
5501
+ const projectPath = join21(cwd, ".claude", "skills", name);
5502
+ const globalPath = join21(homedir11(), ".claude", "skills", name);
5503
+ if (!existsSync18(join21(projectPath, "SKILL.md"))) {
5358
5504
  console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
5359
5505
  process.exit(1);
5360
5506
  }
5361
- if (existsSync17(join20(globalPath, "SKILL.md"))) {
5507
+ if (existsSync18(join21(globalPath, "SKILL.md"))) {
5362
5508
  console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
5363
5509
  process.exit(1);
5364
5510
  }
5365
- mkdirSync8(dirname3(globalPath), { recursive: true });
5511
+ mkdirSync8(dirname4(globalPath), { recursive: true });
5366
5512
  renameSync3(projectPath, globalPath);
5367
5513
  console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
5368
5514
  }
@@ -5493,7 +5639,7 @@ async function pullSkills(args) {
5493
5639
  console.error(`pull failed: ${e?.message ?? e}`);
5494
5640
  process.exit(1);
5495
5641
  }
5496
- const dest = toRaw === "global" ? join20(homedir10(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
5642
+ const dest = toRaw === "global" ? join21(homedir11(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
5497
5643
  const filterDesc = users.length === 0 ? "all users" : users.join(", ");
5498
5644
  console.log(`Destination: ${dest}`);
5499
5645
  console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
@@ -5543,7 +5689,7 @@ async function unpullSkills(args) {
5543
5689
  all,
5544
5690
  legacyCleanup
5545
5691
  });
5546
- const dest = toRaw === "global" ? join20(homedir10(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
5692
+ const dest = toRaw === "global" ? join21(homedir11(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
5547
5693
  const filterParts = [];
5548
5694
  if (users.length > 0)
5549
5695
  filterParts.push(`users=${users.join(",")}`);
@@ -5632,13 +5778,13 @@ if (process.argv[1] && process.argv[1].endsWith("skilify.js")) {
5632
5778
 
5633
5779
  // dist/src/cli/update.js
5634
5780
  import { execFileSync as execFileSync4 } from "node:child_process";
5635
- import { existsSync as existsSync18, readFileSync as readFileSync15, realpathSync } from "node:fs";
5636
- import { dirname as dirname5, sep } from "node:path";
5781
+ import { existsSync as existsSync19, readFileSync as readFileSync15, realpathSync } from "node:fs";
5782
+ import { dirname as dirname6, sep } from "node:path";
5637
5783
  import { fileURLToPath as fileURLToPath2 } from "node:url";
5638
5784
 
5639
5785
  // dist/src/utils/version-check.js
5640
5786
  import { readFileSync as readFileSync14 } from "node:fs";
5641
- import { dirname as dirname4, join as join21 } from "node:path";
5787
+ import { dirname as dirname5, join as join22 } from "node:path";
5642
5788
  function isNewer(latest, current) {
5643
5789
  const parse = (v) => v.split(".").map(Number);
5644
5790
  const [la, lb, lc] = parse(latest);
@@ -5657,7 +5803,7 @@ function detectInstallKind(argv1) {
5657
5803
  return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
5658
5804
  }
5659
5805
  })();
5660
- let dir = dirname5(realArgv1);
5806
+ let dir = dirname6(realArgv1);
5661
5807
  let installDir = null;
5662
5808
  for (let i = 0; i < 10; i++) {
5663
5809
  const pkgPath = `${dir}${sep}package.json`;
@@ -5669,12 +5815,12 @@ function detectInstallKind(argv1) {
5669
5815
  }
5670
5816
  } catch {
5671
5817
  }
5672
- const parent = dirname5(dir);
5818
+ const parent = dirname6(dir);
5673
5819
  if (parent === dir)
5674
5820
  break;
5675
5821
  dir = parent;
5676
5822
  }
5677
- installDir ??= dirname5(realArgv1);
5823
+ installDir ??= dirname6(realArgv1);
5678
5824
  if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
5679
5825
  return { kind: "npx", installDir };
5680
5826
  }
@@ -5683,10 +5829,10 @@ function detectInstallKind(argv1) {
5683
5829
  }
5684
5830
  let gitDir = installDir;
5685
5831
  for (let i = 0; i < 6; i++) {
5686
- if (existsSync18(`${gitDir}${sep}.git`)) {
5832
+ if (existsSync19(`${gitDir}${sep}.git`)) {
5687
5833
  return { kind: "local-dev", installDir };
5688
5834
  }
5689
- const parent = dirname5(gitDir);
5835
+ const parent = dirname6(gitDir);
5690
5836
  if (parent === gitDir)
5691
5837
  break;
5692
5838
  gitDir = parent;
@@ -5845,6 +5991,12 @@ Skill management (mine + share reusable Claude skills across the org):
5845
5991
  Options: --user <email>, --users a,b,c,
5846
5992
  --all-users, --to <project|global>,
5847
5993
  --dry-run, --force.
5994
+ Note: every agent's SessionStart hook
5995
+ auto-runs 'pull --all-users --to global'
5996
+ on every session. File writes are
5997
+ idempotent (skipped when local is
5998
+ at-or-newer than remote). Disable via
5999
+ HIVEMIND_AUTOPULL_DISABLED=1.
5848
6000
  hivemind skilify unpull Remove skills previously installed by pull.
5849
6001
  Options: --user, --users, --not-mine,
5850
6002
  --to <project|global>, --dry-run,