@deeplake/hivemind 0.7.32 → 0.7.34

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 (34) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +332 -189
  4. package/codex/bundle/capture.js +365 -332
  5. package/codex/bundle/commands/auth-login.js +163 -30
  6. package/codex/bundle/pre-tool-use.js +334 -301
  7. package/codex/bundle/session-start-setup.js +193 -60
  8. package/codex/bundle/session-start.js +229 -87
  9. package/codex/bundle/shell/deeplake-shell.js +328 -295
  10. package/codex/bundle/skillify-worker.js +26 -18
  11. package/codex/bundle/stop.js +450 -394
  12. package/codex/bundle/wiki-worker.js +174 -292
  13. package/cursor/bundle/capture.js +448 -392
  14. package/cursor/bundle/commands/auth-login.js +163 -30
  15. package/cursor/bundle/pre-tool-use.js +324 -291
  16. package/cursor/bundle/session-end.js +43 -20
  17. package/cursor/bundle/session-start.js +272 -130
  18. package/cursor/bundle/shell/deeplake-shell.js +328 -295
  19. package/cursor/bundle/skillify-worker.js +26 -18
  20. package/cursor/bundle/wiki-worker.js +174 -292
  21. package/hermes/bundle/capture.js +448 -392
  22. package/hermes/bundle/commands/auth-login.js +163 -30
  23. package/hermes/bundle/pre-tool-use.js +324 -291
  24. package/hermes/bundle/session-end.js +43 -20
  25. package/hermes/bundle/session-start.js +269 -127
  26. package/hermes/bundle/shell/deeplake-shell.js +328 -295
  27. package/hermes/bundle/skillify-worker.js +26 -18
  28. package/hermes/bundle/wiki-worker.js +174 -292
  29. package/mcp/bundle/server.js +190 -57
  30. package/openclaw/dist/index.js +160 -32
  31. package/openclaw/dist/skillify-worker.js +26 -18
  32. package/openclaw/openclaw.plugin.json +1 -1
  33. package/openclaw/package.json +1 -1
  34. package/package.json +1 -1
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 existsSync14, mkdirSync as mkdirSync4, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
21
- import { join as join17 } 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 ?? join17(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 join17(getIndexMarkerDir(), `${markerKey}.json`);
28
+ return join18(getIndexMarkerDir(), `${markerKey}.json`);
29
29
  }
30
30
  function hasFreshIndexMarker(markerPath) {
31
31
  if (!existsSync14(markerPath))
32
32
  return false;
33
33
  try {
34
- const raw = JSON.parse(readFileSync12(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
- mkdirSync4(getIndexMarkerDir(), { recursive: true });
45
- writeFileSync8(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({
@@ -519,19 +519,19 @@ function isPluginsAllowMissingHivemind(allow) {
519
519
  return Array.isArray(allow) && allow.length > 0 && !allow.includes("hivemind");
520
520
  }
521
521
  function ensureHivemindAllowlisted() {
522
- const configPath = getOpenclawConfigPath();
523
- if (!existsSync4(configPath)) {
524
- return { status: "error", configPath, error: "openclaw config file not found" };
522
+ const configPath2 = getOpenclawConfigPath();
523
+ if (!existsSync4(configPath2)) {
524
+ return { status: "error", configPath: configPath2, error: "openclaw config file not found" };
525
525
  }
526
526
  let parsed;
527
527
  try {
528
- const raw = readFileSync5(configPath, "utf-8");
528
+ const raw = readFileSync5(configPath2, "utf-8");
529
529
  parsed = JSON.parse(raw);
530
530
  } catch (e) {
531
- return { status: "error", configPath, error: `could not read/parse config: ${e instanceof Error ? e.message : String(e)}` };
531
+ return { status: "error", configPath: configPath2, error: `could not read/parse config: ${e instanceof Error ? e.message : String(e)}` };
532
532
  }
533
533
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
534
- return { status: "error", configPath, error: "openclaw config is not a JSON object" };
534
+ return { status: "error", configPath: configPath2, error: "openclaw config is not a JSON object" };
535
535
  }
536
536
  const plugins = parsed.plugins ?? {};
537
537
  const pluginsAllowRaw = plugins.allow;
@@ -540,7 +540,7 @@ function ensureHivemindAllowlisted() {
540
540
  const pluginsAllowNeedsPatch = isPluginsAllowMissingHivemind(pluginsAllowRaw);
541
541
  const toolsAlsoAllowNeedsPatch = Array.isArray(alsoAllowRaw) && alsoAllowRaw.length > 0 && !isAllowlistCoveringHivemind(alsoAllowRaw);
542
542
  if (!pluginsAllowNeedsPatch && !toolsAlsoAllowNeedsPatch) {
543
- return { status: "already-set", configPath };
543
+ return { status: "already-set", configPath: configPath2 };
544
544
  }
545
545
  const updated = { ...parsed };
546
546
  if (pluginsAllowNeedsPatch) {
@@ -557,18 +557,18 @@ function ensureHivemindAllowlisted() {
557
557
  alsoAllow: [...alsoAllowRaw, "hivemind"]
558
558
  };
559
559
  }
560
- const backupPath = `${configPath}.bak-hivemind-${Date.now()}`;
561
- const tmpPath = `${configPath}.tmp-hivemind-${process.pid}`;
560
+ const backupPath = `${configPath2}.bak-hivemind-${Date.now()}`;
561
+ const tmpPath = `${configPath2}.tmp-hivemind-${process.pid}`;
562
562
  try {
563
- writeFileSync3(backupPath, readFileSync5(configPath, "utf-8"));
563
+ writeFileSync3(backupPath, readFileSync5(configPath2, "utf-8"));
564
564
  writeFileSync3(tmpPath, JSON.stringify(updated, null, 2) + "\n");
565
- renameSync(tmpPath, configPath);
565
+ renameSync(tmpPath, configPath2);
566
566
  } catch (e) {
567
- return { status: "error", configPath, error: `could not write config: ${e instanceof Error ? e.message : String(e)}` };
567
+ return { status: "error", configPath: configPath2, error: `could not write config: ${e instanceof Error ? e.message : String(e)}` };
568
568
  }
569
569
  return {
570
570
  status: "added",
571
- configPath,
571
+ configPath: configPath2,
572
572
  backupPath,
573
573
  delta: {
574
574
  pluginsAllow: pluginsAllowNeedsPatch,
@@ -4343,6 +4343,107 @@ function sqlIdent(name) {
4343
4343
  var SUMMARY_EMBEDDING_COL = "summary_embedding";
4344
4344
  var MESSAGE_EMBEDDING_COL = "message_embedding";
4345
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
+
4346
4447
  // dist/src/deeplake-api.js
4347
4448
  var indexMarkerStorePromise = null;
4348
4449
  function getIndexMarkerStore() {
@@ -4350,7 +4451,7 @@ function getIndexMarkerStore() {
4350
4451
  indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
4351
4452
  return indexMarkerStorePromise;
4352
4453
  }
4353
- var log3 = (msg) => log2("sdk", msg);
4454
+ var log4 = (msg) => log2("sdk", msg);
4354
4455
  function summarizeSql(sql, maxLen = 220) {
4355
4456
  const compact = sql.replace(/\s+/g, " ").trim();
4356
4457
  return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
@@ -4362,7 +4463,38 @@ function traceSql(msg) {
4362
4463
  process.stderr.write(`[deeplake-sql] ${msg}
4363
4464
  `);
4364
4465
  if (process.env.HIVEMIND_DEBUG === "1")
4365
- 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";
4366
4498
  }
4367
4499
  var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
4368
4500
  var MAX_RETRIES = 3;
@@ -4371,8 +4503,8 @@ var MAX_CONCURRENCY = 5;
4371
4503
  function getQueryTimeoutMs() {
4372
4504
  return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
4373
4505
  }
4374
- function sleep(ms) {
4375
- return new Promise((resolve) => setTimeout(resolve, ms));
4506
+ function sleep2(ms) {
4507
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
4376
4508
  }
4377
4509
  function isTimeoutError(error) {
4378
4510
  const name = error instanceof Error ? error.name.toLowerCase() : "";
@@ -4402,7 +4534,7 @@ var Semaphore = class {
4402
4534
  this.active++;
4403
4535
  return;
4404
4536
  }
4405
- await new Promise((resolve) => this.waiting.push(resolve));
4537
+ await new Promise((resolve2) => this.waiting.push(resolve2));
4406
4538
  }
4407
4539
  release() {
4408
4540
  this.active--;
@@ -4473,8 +4605,8 @@ var DeeplakeApi = class {
4473
4605
  lastError = e instanceof Error ? e : new Error(String(e));
4474
4606
  if (attempt < MAX_RETRIES) {
4475
4607
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
4476
- log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
4477
- await sleep(delay);
4608
+ log4(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
4609
+ await sleep2(delay);
4478
4610
  continue;
4479
4611
  }
4480
4612
  throw lastError;
@@ -4490,10 +4622,11 @@ var DeeplakeApi = class {
4490
4622
  const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
4491
4623
  if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
4492
4624
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
4493
- log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
4494
- await sleep(delay);
4625
+ log4(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
4626
+ await sleep2(delay);
4495
4627
  continue;
4496
4628
  }
4629
+ maybeSignalBalanceExhausted(resp.status, text);
4497
4630
  throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
4498
4631
  }
4499
4632
  throw lastError ?? new Error("Query failed: max retries exceeded");
@@ -4514,7 +4647,7 @@ var DeeplakeApi = class {
4514
4647
  const chunk = rows.slice(i, i + CONCURRENCY);
4515
4648
  await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
4516
4649
  }
4517
- log3(`commit: ${rows.length} rows`);
4650
+ log4(`commit: ${rows.length} rows`);
4518
4651
  }
4519
4652
  async upsertRowSql(row) {
4520
4653
  const ts = (/* @__PURE__ */ new Date()).toISOString();
@@ -4570,7 +4703,7 @@ var DeeplakeApi = class {
4570
4703
  markers.writeIndexMarker(markerPath);
4571
4704
  return;
4572
4705
  }
4573
- log3(`index "${indexName}" skipped: ${e.message}`);
4706
+ log4(`index "${indexName}" skipped: ${e.message}`);
4574
4707
  }
4575
4708
  }
4576
4709
  /**
@@ -4660,13 +4793,13 @@ var DeeplakeApi = class {
4660
4793
  };
4661
4794
  }
4662
4795
  if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
4663
- 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);
4664
4797
  continue;
4665
4798
  }
4666
4799
  return { tables: [], cacheable: false };
4667
4800
  } catch {
4668
4801
  if (attempt < MAX_RETRIES) {
4669
- await sleep(BASE_DELAY_MS * Math.pow(2, attempt));
4802
+ await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
4670
4803
  continue;
4671
4804
  }
4672
4805
  return { tables: [], cacheable: false };
@@ -4694,9 +4827,9 @@ var DeeplakeApi = class {
4694
4827
  } catch (err) {
4695
4828
  lastErr = err;
4696
4829
  const msg = err instanceof Error ? err.message : String(err);
4697
- 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}`);
4698
4831
  if (attempt < OUTER_BACKOFFS_MS.length) {
4699
- await sleep(OUTER_BACKOFFS_MS[attempt]);
4832
+ await sleep2(OUTER_BACKOFFS_MS[attempt]);
4700
4833
  }
4701
4834
  }
4702
4835
  }
@@ -4707,9 +4840,9 @@ var DeeplakeApi = class {
4707
4840
  const tbl = sqlIdent(name ?? this.tableName);
4708
4841
  const tables = await this.listTables();
4709
4842
  if (!tables.includes(tbl)) {
4710
- log3(`table "${tbl}" not found, creating`);
4843
+ log4(`table "${tbl}" not found, creating`);
4711
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);
4712
- log3(`table "${tbl}" created`);
4845
+ log4(`table "${tbl}" created`);
4713
4846
  if (!tables.includes(tbl))
4714
4847
  this._tablesCache = [...tables, tbl];
4715
4848
  }
@@ -4722,9 +4855,9 @@ var DeeplakeApi = class {
4722
4855
  const safe = sqlIdent(name);
4723
4856
  const tables = await this.listTables();
4724
4857
  if (!tables.includes(safe)) {
4725
- log3(`table "${safe}" not found, creating`);
4858
+ log4(`table "${safe}" not found, creating`);
4726
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);
4727
- log3(`table "${safe}" created`);
4860
+ log4(`table "${safe}" created`);
4728
4861
  if (!tables.includes(safe))
4729
4862
  this._tablesCache = [...tables, safe];
4730
4863
  }
@@ -4747,9 +4880,9 @@ var DeeplakeApi = class {
4747
4880
  const safe = sqlIdent(name);
4748
4881
  const tables = await this.listTables();
4749
4882
  if (!tables.includes(safe)) {
4750
- log3(`table "${safe}" not found, creating`);
4883
+ log4(`table "${safe}" not found, creating`);
4751
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);
4752
- log3(`table "${safe}" created`);
4885
+ log4(`table "${safe}" created`);
4753
4886
  if (!tables.includes(safe))
4754
4887
  this._tablesCache = [...tables, safe];
4755
4888
  }
@@ -4780,10 +4913,10 @@ function parseArgs(argv) {
4780
4913
  }
4781
4914
  function confirm(message) {
4782
4915
  const rl = createInterface({ input: process.stdin, output: process.stderr });
4783
- return new Promise((resolve) => {
4916
+ return new Promise((resolve2) => {
4784
4917
  rl.question(`${message} [y/N] `, (answer) => {
4785
4918
  rl.close();
4786
- resolve(answer.trim().toLowerCase() === "y");
4919
+ resolve2(answer.trim().toLowerCase() === "y");
4787
4920
  });
4788
4921
  });
4789
4922
  }
@@ -5085,39 +5218,48 @@ if (process.argv[1] && process.argv[1].endsWith("auth-login.js")) {
5085
5218
  }
5086
5219
 
5087
5220
  // dist/src/commands/skillify.js
5088
- import { readdirSync as readdirSync5, existsSync as existsSync26, readFileSync as readFileSync20, mkdirSync as mkdirSync11, renameSync as renameSync6 } from "node:fs";
5089
- import { homedir as homedir19 } from "node:os";
5090
- import { dirname as dirname7, join as join29 } 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 homedir18 } from "node:os";
5223
+ import { dirname as dirname8, join as join31 } from "node:path";
5091
5224
 
5092
5225
  // dist/src/skillify/scope-config.js
5093
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
5226
+ import { existsSync as existsSync16, mkdirSync as mkdirSync6, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "node:fs";
5227
+ import { join as join21 } from "node:path";
5228
+
5229
+ // dist/src/skillify/legacy-migration.js
5230
+ import { existsSync as existsSync15, renameSync as renameSync4 } from "node:fs";
5231
+ import { dirname as dirname3, join as join20 } from "node:path";
5232
+
5233
+ // dist/src/skillify/state-dir.js
5094
5234
  import { homedir as homedir9 } from "node:os";
5095
5235
  import { join as join19 } from "node:path";
5236
+ function getStateDir() {
5237
+ const override = process.env.HIVEMIND_STATE_DIR?.trim();
5238
+ return override && override.length > 0 ? override : join19(homedir9(), ".deeplake", "state", "skillify");
5239
+ }
5096
5240
 
5097
5241
  // dist/src/skillify/legacy-migration.js
5098
- import { existsSync as existsSync15, renameSync as renameSync3 } from "node:fs";
5099
- import { homedir as homedir8 } from "node:os";
5100
- import { join as join18 } from "node:path";
5101
5242
  var dlog = (msg) => log2("skillify-migrate", msg);
5102
5243
  var attempted = false;
5103
5244
  function migrateLegacyStateDir() {
5245
+ if (process.env.HIVEMIND_STATE_DIR?.trim())
5246
+ return;
5104
5247
  if (attempted)
5105
5248
  return;
5106
5249
  attempted = true;
5107
- const root = join18(homedir8(), ".deeplake", "state");
5108
- const legacy = join18(root, "skilify");
5109
- const current = join18(root, "skillify");
5250
+ const current = getStateDir();
5251
+ const legacy = join20(dirname3(current), "skilify");
5110
5252
  if (!existsSync15(legacy))
5111
5253
  return;
5112
5254
  if (existsSync15(current))
5113
5255
  return;
5114
5256
  try {
5115
- renameSync3(legacy, current);
5257
+ renameSync4(legacy, current);
5116
5258
  dlog(`migrated ${legacy} -> ${current}`);
5117
5259
  } catch (err) {
5118
5260
  const code = err.code;
5119
- if (code === "EXDEV" || code === "EPERM") {
5120
- dlog(`migration failed (${code}); leaving legacy dir in place`);
5261
+ if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
5262
+ dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
5121
5263
  return;
5122
5264
  }
5123
5265
  throw err;
@@ -5125,15 +5267,17 @@ function migrateLegacyStateDir() {
5125
5267
  }
5126
5268
 
5127
5269
  // dist/src/skillify/scope-config.js
5128
- var STATE_DIR = join19(homedir9(), ".deeplake", "state", "skillify");
5129
- var CONFIG_PATH2 = join19(STATE_DIR, "config.json");
5270
+ function configPath() {
5271
+ return join21(getStateDir(), "config.json");
5272
+ }
5130
5273
  var DEFAULT = { scope: "me", team: [], install: "project" };
5131
5274
  function loadScopeConfig() {
5132
5275
  migrateLegacyStateDir();
5276
+ const CONFIG_PATH2 = configPath();
5133
5277
  if (!existsSync16(CONFIG_PATH2))
5134
5278
  return DEFAULT;
5135
5279
  try {
5136
- const raw = JSON.parse(readFileSync13(CONFIG_PATH2, "utf-8"));
5280
+ const raw = JSON.parse(readFileSync14(CONFIG_PATH2, "utf-8"));
5137
5281
  const scope = raw.scope === "team" ? "team" : raw.scope === "org" ? "team" : "me";
5138
5282
  const team = Array.isArray(raw.team) ? raw.team.filter((s) => typeof s === "string") : [];
5139
5283
  const install = raw.install === "global" ? "global" : "project";
@@ -5144,19 +5288,19 @@ function loadScopeConfig() {
5144
5288
  }
5145
5289
  function saveScopeConfig(cfg) {
5146
5290
  migrateLegacyStateDir();
5147
- mkdirSync5(STATE_DIR, { recursive: true });
5148
- writeFileSync9(CONFIG_PATH2, JSON.stringify(cfg, null, 2));
5291
+ mkdirSync6(getStateDir(), { recursive: true });
5292
+ writeFileSync10(configPath(), JSON.stringify(cfg, null, 2));
5149
5293
  }
5150
5294
 
5151
5295
  // dist/src/skillify/pull.js
5152
- import { existsSync as existsSync20, readFileSync as readFileSync16, writeFileSync as writeFileSync12, mkdirSync as mkdirSync8, renameSync as renameSync5, lstatSync as lstatSync4, readlinkSync as readlinkSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync8 } from "node:fs";
5153
- import { homedir as homedir13 } from "node:os";
5154
- import { dirname as dirname4, join as join23 } from "node:path";
5296
+ 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";
5297
+ import { homedir as homedir12 } from "node:os";
5298
+ import { dirname as dirname5, join as join25 } from "node:path";
5155
5299
 
5156
5300
  // dist/src/skillify/skill-writer.js
5157
- import { existsSync as existsSync17, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
5301
+ import { existsSync as existsSync17, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
5158
5302
  import { homedir as homedir10 } from "node:os";
5159
- import { join as join20 } from "node:path";
5303
+ import { join as join22 } from "node:path";
5160
5304
  function assertValidSkillName(name) {
5161
5305
  if (typeof name !== "string" || name.length === 0) {
5162
5306
  throw new Error(`invalid skill name: empty or non-string`);
@@ -5172,10 +5316,10 @@ function assertValidSkillName(name) {
5172
5316
  }
5173
5317
  }
5174
5318
  function skillDir(skillsRoot, name) {
5175
- return join20(skillsRoot, name);
5319
+ return join22(skillsRoot, name);
5176
5320
  }
5177
5321
  function skillPath(skillsRoot, name) {
5178
- return join20(skillDir(skillsRoot, name), "SKILL.md");
5322
+ return join22(skillDir(skillsRoot, name), "SKILL.md");
5179
5323
  }
5180
5324
  function renderFrontmatter(fm) {
5181
5325
  const lines = ["---"];
@@ -5256,7 +5400,7 @@ function writeNewSkill(args) {
5256
5400
  if (existsSync17(path)) {
5257
5401
  throw new Error(`skill already exists at ${path}; use mergeSkill`);
5258
5402
  }
5259
- mkdirSync6(dir, { recursive: true });
5403
+ mkdirSync7(dir, { recursive: true });
5260
5404
  const now = (/* @__PURE__ */ new Date()).toISOString();
5261
5405
  const author = args.author && args.author.length > 0 ? args.author : void 0;
5262
5406
  const contributors = author ? [author] : [];
@@ -5276,7 +5420,7 @@ function writeNewSkill(args) {
5276
5420
 
5277
5421
  ${args.body.trim()}
5278
5422
  `;
5279
- writeFileSync10(path, text);
5423
+ writeFileSync11(path, text);
5280
5424
  return {
5281
5425
  path,
5282
5426
  action: "created",
@@ -5292,29 +5436,28 @@ function listSkills(skillsRoot) {
5292
5436
  return [];
5293
5437
  const out = [];
5294
5438
  for (const name of readdirSync2(skillsRoot)) {
5295
- const skillFile = join20(skillsRoot, name, "SKILL.md");
5296
- if (existsSync17(skillFile) && statSync2(skillFile).isFile()) {
5297
- out.push({ name, body: readFileSync14(skillFile, "utf-8") });
5439
+ const skillFile = join22(skillsRoot, name, "SKILL.md");
5440
+ if (existsSync17(skillFile) && statSync3(skillFile).isFile()) {
5441
+ out.push({ name, body: readFileSync15(skillFile, "utf-8") });
5298
5442
  }
5299
5443
  }
5300
5444
  return out;
5301
5445
  }
5302
5446
  function resolveSkillsRoot(install, cwd) {
5303
5447
  if (install === "global") {
5304
- return join20(homedir10(), ".claude", "skills");
5448
+ return join22(homedir10(), ".claude", "skills");
5305
5449
  }
5306
- return join20(cwd, ".claude", "skills");
5450
+ return join22(cwd, ".claude", "skills");
5307
5451
  }
5308
5452
 
5309
5453
  // dist/src/skillify/manifest.js
5310
- import { existsSync as existsSync18, lstatSync as lstatSync3, mkdirSync as mkdirSync7, readFileSync as readFileSync15, renameSync as renameSync4, unlinkSync as unlinkSync7, writeFileSync as writeFileSync11 } from "node:fs";
5311
- import { homedir as homedir11 } from "node:os";
5312
- import { dirname as dirname3, join as join21 } from "node:path";
5454
+ 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";
5455
+ import { dirname as dirname4, join as join23 } from "node:path";
5313
5456
  function emptyManifest() {
5314
5457
  return { version: 1, entries: [] };
5315
5458
  }
5316
5459
  function manifestPath() {
5317
- return join21(homedir11(), ".deeplake", "state", "skillify", "pulled.json");
5460
+ return join23(getStateDir(), "pulled.json");
5318
5461
  }
5319
5462
  function loadManifest(path = manifestPath()) {
5320
5463
  migrateLegacyStateDir();
@@ -5322,7 +5465,7 @@ function loadManifest(path = manifestPath()) {
5322
5465
  return emptyManifest();
5323
5466
  let raw;
5324
5467
  try {
5325
- raw = readFileSync15(path, "utf-8");
5468
+ raw = readFileSync16(path, "utf-8");
5326
5469
  } catch {
5327
5470
  return emptyManifest();
5328
5471
  }
@@ -5369,10 +5512,10 @@ function loadManifest(path = manifestPath()) {
5369
5512
  }
5370
5513
  function saveManifest(m, path = manifestPath()) {
5371
5514
  migrateLegacyStateDir();
5372
- mkdirSync7(dirname3(path), { recursive: true });
5515
+ mkdirSync8(dirname4(path), { recursive: true });
5373
5516
  const tmp = `${path}.tmp`;
5374
- writeFileSync11(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5375
- renameSync4(tmp, path);
5517
+ writeFileSync12(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
5518
+ renameSync5(tmp, path);
5376
5519
  }
5377
5520
  function recordPull(entry, path = manifestPath()) {
5378
5521
  const m = loadManifest(path);
@@ -5404,7 +5547,7 @@ function unlinkSymlinks(paths) {
5404
5547
  if (!st.isSymbolicLink())
5405
5548
  continue;
5406
5549
  try {
5407
- unlinkSync7(path);
5550
+ unlinkSync8(path);
5408
5551
  } catch {
5409
5552
  }
5410
5553
  }
@@ -5414,7 +5557,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
5414
5557
  const live = [];
5415
5558
  let pruned = 0;
5416
5559
  for (const e of m.entries) {
5417
- if (existsSync18(join21(e.installRoot, e.dirName))) {
5560
+ if (existsSync18(join23(e.installRoot, e.dirName))) {
5418
5561
  live.push(e);
5419
5562
  continue;
5420
5563
  }
@@ -5428,25 +5571,25 @@ function pruneOrphanedEntries(path = manifestPath()) {
5428
5571
 
5429
5572
  // dist/src/skillify/agent-roots.js
5430
5573
  import { existsSync as existsSync19 } from "node:fs";
5431
- import { homedir as homedir12 } from "node:os";
5432
- import { join as join22 } from "node:path";
5574
+ import { homedir as homedir11 } from "node:os";
5575
+ import { join as join24 } from "node:path";
5433
5576
  function resolveDetected(home) {
5434
5577
  const out = [];
5435
- const codexInstalled = existsSync19(join22(home, ".codex"));
5436
- const piInstalled = existsSync19(join22(home, ".pi", "agent"));
5437
- const hermesInstalled = existsSync19(join22(home, ".hermes"));
5578
+ const codexInstalled = existsSync19(join24(home, ".codex"));
5579
+ const piInstalled = existsSync19(join24(home, ".pi", "agent"));
5580
+ const hermesInstalled = existsSync19(join24(home, ".hermes"));
5438
5581
  if (codexInstalled || piInstalled) {
5439
- out.push(join22(home, ".agents", "skills"));
5582
+ out.push(join24(home, ".agents", "skills"));
5440
5583
  }
5441
5584
  if (hermesInstalled) {
5442
- out.push(join22(home, ".hermes", "skills"));
5585
+ out.push(join24(home, ".hermes", "skills"));
5443
5586
  }
5444
5587
  if (piInstalled) {
5445
- out.push(join22(home, ".pi", "agent", "skills"));
5588
+ out.push(join24(home, ".pi", "agent", "skills"));
5446
5589
  }
5447
5590
  return out;
5448
5591
  }
5449
- function detectAgentSkillsRoots(canonicalRoot, home = homedir12()) {
5592
+ function detectAgentSkillsRoots(canonicalRoot, home = homedir11()) {
5450
5593
  return resolveDetected(home).filter((p) => p !== canonicalRoot);
5451
5594
  }
5452
5595
 
@@ -5490,15 +5633,15 @@ function isMissingTableError(message) {
5490
5633
  }
5491
5634
  function resolvePullDestination(install, cwd) {
5492
5635
  if (install === "global")
5493
- return join23(homedir13(), ".claude", "skills");
5636
+ return join25(homedir12(), ".claude", "skills");
5494
5637
  if (!cwd)
5495
5638
  throw new Error("install=project requires a cwd");
5496
- return join23(cwd, ".claude", "skills");
5639
+ return join25(cwd, ".claude", "skills");
5497
5640
  }
5498
5641
  function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5499
5642
  const out = [];
5500
5643
  for (const root of agentRoots) {
5501
- const link = join23(root, dirName);
5644
+ const link = join25(root, dirName);
5502
5645
  let existing;
5503
5646
  try {
5504
5647
  existing = lstatSync4(link);
@@ -5520,13 +5663,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
5520
5663
  continue;
5521
5664
  }
5522
5665
  try {
5523
- unlinkSync8(link);
5666
+ unlinkSync9(link);
5524
5667
  } catch {
5525
5668
  continue;
5526
5669
  }
5527
5670
  }
5528
5671
  try {
5529
- mkdirSync8(dirname4(link), { recursive: true });
5672
+ mkdirSync9(dirname5(link), { recursive: true });
5530
5673
  symlinkSync2(canonicalDir, link, "dir");
5531
5674
  out.push(link);
5532
5675
  } catch {
@@ -5541,7 +5684,7 @@ function backfillSymlinks(installRoot) {
5541
5684
  return;
5542
5685
  const detected = detectAgentSkillsRoots(installRoot);
5543
5686
  for (const entry of entries) {
5544
- const canonical = join23(entry.installRoot, entry.dirName);
5687
+ const canonical = join25(entry.installRoot, entry.dirName);
5545
5688
  if (!existsSync20(canonical))
5546
5689
  continue;
5547
5690
  const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
@@ -5655,7 +5798,7 @@ function readLocalVersion(path) {
5655
5798
  if (!existsSync20(path))
5656
5799
  return null;
5657
5800
  try {
5658
- const text = readFileSync16(path, "utf-8");
5801
+ const text = readFileSync17(path, "utf-8");
5659
5802
  const parsed = parseFrontmatter(text);
5660
5803
  if (!parsed)
5661
5804
  return null;
@@ -5750,8 +5893,8 @@ async function runPull(opts) {
5750
5893
  summary.skipped++;
5751
5894
  continue;
5752
5895
  }
5753
- const skillDir2 = join23(root, dirName);
5754
- const skillFile = join23(skillDir2, "SKILL.md");
5896
+ const skillDir2 = join25(root, dirName);
5897
+ const skillFile = join25(skillDir2, "SKILL.md");
5755
5898
  const remoteVersion = Number(row.version ?? 1);
5756
5899
  const localVersion = readLocalVersion(skillFile);
5757
5900
  const action = decideAction({
@@ -5762,14 +5905,14 @@ async function runPull(opts) {
5762
5905
  });
5763
5906
  let manifestError;
5764
5907
  if (action === "wrote") {
5765
- mkdirSync8(skillDir2, { recursive: true });
5908
+ mkdirSync9(skillDir2, { recursive: true });
5766
5909
  if (existsSync20(skillFile)) {
5767
5910
  try {
5768
- renameSync5(skillFile, `${skillFile}.bak`);
5911
+ renameSync6(skillFile, `${skillFile}.bak`);
5769
5912
  } catch {
5770
5913
  }
5771
5914
  }
5772
- writeFileSync12(skillFile, renderSkillFile(row));
5915
+ writeFileSync13(skillFile, renderSkillFile(row));
5773
5916
  const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir2, dirName, detectAgentSkillsRoots(root)) : [];
5774
5917
  try {
5775
5918
  recordPull({
@@ -5811,15 +5954,15 @@ async function runPull(opts) {
5811
5954
  }
5812
5955
 
5813
5956
  // dist/src/skillify/unpull.js
5814
- import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync3 } from "node:fs";
5815
- import { homedir as homedir14 } from "node:os";
5816
- import { join as join24 } from "node:path";
5957
+ import { existsSync as existsSync21, readdirSync as readdirSync3, rmSync as rmSync5, statSync as statSync4 } from "node:fs";
5958
+ import { homedir as homedir13 } from "node:os";
5959
+ import { join as join26 } from "node:path";
5817
5960
  function resolveUnpullRoot(install, cwd) {
5818
5961
  if (install === "global")
5819
- return join24(homedir14(), ".claude", "skills");
5962
+ return join26(homedir13(), ".claude", "skills");
5820
5963
  if (!cwd)
5821
5964
  throw new Error("cwd required when install === 'project'");
5822
- return join24(cwd, ".claude", "skills");
5965
+ return join26(cwd, ".claude", "skills");
5823
5966
  }
5824
5967
  function runUnpull(opts) {
5825
5968
  const root = resolveUnpullRoot(opts.install, opts.cwd);
@@ -5842,7 +5985,7 @@ function runUnpull(opts) {
5842
5985
  const entries = entriesForRoot(manifest, opts.install, root);
5843
5986
  for (const entry of entries) {
5844
5987
  summary.scanned++;
5845
- const path = join24(root, entry.dirName);
5988
+ const path = join26(root, entry.dirName);
5846
5989
  if (!existsSync21(path)) {
5847
5990
  if (!opts.dryRun) {
5848
5991
  unlinkSymlinks(entry.symlinks);
@@ -5901,10 +6044,10 @@ function runUnpull(opts) {
5901
6044
  for (const dirName of readdirSync3(root)) {
5902
6045
  if (manifestDirNames.has(dirName))
5903
6046
  continue;
5904
- const path = join24(root, dirName);
6047
+ const path = join26(root, dirName);
5905
6048
  let st;
5906
6049
  try {
5907
- st = statSync3(path);
6050
+ st = statSync4(path);
5908
6051
  } catch {
5909
6052
  continue;
5910
6053
  }
@@ -5980,21 +6123,21 @@ function decideTargetForManifestEntry(entry, opts, userFilter, haveUserFilter) {
5980
6123
 
5981
6124
  // dist/src/commands/mine-local.js
5982
6125
  import { spawn } from "node:child_process";
5983
- import { existsSync as existsSync25, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
5984
- import { homedir as homedir18 } from "node:os";
5985
- import { basename, dirname as dirname6, join as join28 } from "node:path";
6126
+ import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
6127
+ import { homedir as homedir17 } from "node:os";
6128
+ import { basename, dirname as dirname7, join as join30 } from "node:path";
5986
6129
 
5987
6130
  // dist/src/skillify/local-source.js
5988
- import { readdirSync as readdirSync4, readFileSync as readFileSync17, existsSync as existsSync22, statSync as statSync4 } from "node:fs";
5989
- import { homedir as homedir15 } from "node:os";
5990
- import { join as join25 } from "node:path";
5991
- var HOME2 = homedir15();
6131
+ import { readdirSync as readdirSync4, readFileSync as readFileSync18, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
6132
+ import { homedir as homedir14 } from "node:os";
6133
+ import { join as join27 } from "node:path";
6134
+ var HOME2 = homedir14();
5992
6135
  function encodeCwdClaudeCode(cwd) {
5993
6136
  return cwd.replace(/[/_]/g, "-");
5994
6137
  }
5995
6138
  function detectInstalledAgents() {
5996
6139
  const installs = [];
5997
- const claudeRoot = join25(HOME2, ".claude", "projects");
6140
+ const claudeRoot = join27(HOME2, ".claude", "projects");
5998
6141
  if (existsSync22(claudeRoot)) {
5999
6142
  installs.push({
6000
6143
  agent: "claude_code",
@@ -6002,7 +6145,7 @@ function detectInstalledAgents() {
6002
6145
  encodeCwd: encodeCwdClaudeCode
6003
6146
  });
6004
6147
  }
6005
- const codexRoot = join25(HOME2, ".codex", "sessions");
6148
+ const codexRoot = join27(HOME2, ".codex", "sessions");
6006
6149
  if (existsSync22(codexRoot)) {
6007
6150
  installs.push({
6008
6151
  agent: "codex",
@@ -6030,9 +6173,9 @@ function listLocalSessions(installs, cwd) {
6030
6173
  continue;
6031
6174
  }
6032
6175
  for (const sub of subdirs) {
6033
- const subdirPath = join25(install.sessionRoot, sub);
6176
+ const subdirPath = join27(install.sessionRoot, sub);
6034
6177
  try {
6035
- if (!statSync4(subdirPath).isDirectory())
6178
+ if (!statSync5(subdirPath).isDirectory())
6036
6179
  continue;
6037
6180
  } catch {
6038
6181
  continue;
@@ -6047,10 +6190,10 @@ function listLocalSessions(installs, cwd) {
6047
6190
  for (const f of files) {
6048
6191
  if (!f.endsWith(".jsonl"))
6049
6192
  continue;
6050
- const fullPath = join25(subdirPath, f);
6193
+ const fullPath = join27(subdirPath, f);
6051
6194
  let stats;
6052
6195
  try {
6053
- stats = statSync4(fullPath);
6196
+ stats = statSync5(fullPath);
6054
6197
  } catch {
6055
6198
  continue;
6056
6199
  }
@@ -6108,7 +6251,7 @@ function pickSessions(candidates, opts) {
6108
6251
  function nativeJsonlToRows(filePath, sessionId, agent) {
6109
6252
  let raw;
6110
6253
  try {
6111
- raw = readFileSync17(filePath, "utf-8");
6254
+ raw = readFileSync18(filePath, "utf-8");
6112
6255
  } catch {
6113
6256
  return [];
6114
6257
  }
@@ -6200,8 +6343,8 @@ function extractPairs(rows) {
6200
6343
  // dist/src/skillify/gate-runner.js
6201
6344
  import { existsSync as existsSync23 } from "node:fs";
6202
6345
  import { createRequire } from "node:module";
6203
- import { homedir as homedir16 } from "node:os";
6204
- import { join as join26 } from "node:path";
6346
+ import { homedir as homedir15 } from "node:os";
6347
+ import { join as join28 } from "node:path";
6205
6348
  var requireForCp = createRequire(import.meta.url);
6206
6349
  var { execFileSync: runChildProcess } = requireForCp("node:child_process");
6207
6350
  var inheritedEnv = process;
@@ -6213,7 +6356,7 @@ function firstExistingPath(candidates) {
6213
6356
  return null;
6214
6357
  }
6215
6358
  function findAgentBin(agent) {
6216
- const home = homedir16();
6359
+ const home = homedir15();
6217
6360
  switch (agent) {
6218
6361
  // /usr/bin/<name> is included in every candidate list — that's the
6219
6362
  // common Linux package-manager install path (apt, dnf, pacman). Old
@@ -6222,45 +6365,45 @@ function findAgentBin(agent) {
6222
6365
  // #170 caught the gap.
6223
6366
  case "claude_code":
6224
6367
  return firstExistingPath([
6225
- join26(home, ".claude", "local", "claude"),
6368
+ join28(home, ".claude", "local", "claude"),
6226
6369
  "/usr/local/bin/claude",
6227
6370
  "/usr/bin/claude",
6228
- join26(home, ".npm-global", "bin", "claude"),
6229
- join26(home, ".local", "bin", "claude"),
6371
+ join28(home, ".npm-global", "bin", "claude"),
6372
+ join28(home, ".local", "bin", "claude"),
6230
6373
  "/opt/homebrew/bin/claude"
6231
- ]) ?? join26(home, ".claude", "local", "claude");
6374
+ ]) ?? join28(home, ".claude", "local", "claude");
6232
6375
  case "codex":
6233
6376
  return firstExistingPath([
6234
6377
  "/usr/local/bin/codex",
6235
6378
  "/usr/bin/codex",
6236
- join26(home, ".npm-global", "bin", "codex"),
6237
- join26(home, ".local", "bin", "codex"),
6379
+ join28(home, ".npm-global", "bin", "codex"),
6380
+ join28(home, ".local", "bin", "codex"),
6238
6381
  "/opt/homebrew/bin/codex"
6239
6382
  ]) ?? "/usr/local/bin/codex";
6240
6383
  case "cursor":
6241
6384
  return firstExistingPath([
6242
6385
  "/usr/local/bin/cursor-agent",
6243
6386
  "/usr/bin/cursor-agent",
6244
- join26(home, ".npm-global", "bin", "cursor-agent"),
6245
- join26(home, ".local", "bin", "cursor-agent"),
6387
+ join28(home, ".npm-global", "bin", "cursor-agent"),
6388
+ join28(home, ".local", "bin", "cursor-agent"),
6246
6389
  "/opt/homebrew/bin/cursor-agent"
6247
6390
  ]) ?? "/usr/local/bin/cursor-agent";
6248
6391
  case "hermes":
6249
6392
  return firstExistingPath([
6250
- join26(home, ".local", "bin", "hermes"),
6393
+ join28(home, ".local", "bin", "hermes"),
6251
6394
  "/usr/local/bin/hermes",
6252
6395
  "/usr/bin/hermes",
6253
- join26(home, ".npm-global", "bin", "hermes"),
6396
+ join28(home, ".npm-global", "bin", "hermes"),
6254
6397
  "/opt/homebrew/bin/hermes"
6255
- ]) ?? join26(home, ".local", "bin", "hermes");
6398
+ ]) ?? join28(home, ".local", "bin", "hermes");
6256
6399
  case "pi":
6257
6400
  return firstExistingPath([
6258
- join26(home, ".local", "bin", "pi"),
6401
+ join28(home, ".local", "bin", "pi"),
6259
6402
  "/usr/local/bin/pi",
6260
6403
  "/usr/bin/pi",
6261
- join26(home, ".npm-global", "bin", "pi"),
6404
+ join28(home, ".npm-global", "bin", "pi"),
6262
6405
  "/opt/homebrew/bin/pi"
6263
- ]) ?? join26(home, ".local", "bin", "pi");
6406
+ ]) ?? join28(home, ".local", "bin", "pi");
6264
6407
  }
6265
6408
  }
6266
6409
 
@@ -6290,27 +6433,27 @@ function extractJsonBlock(s) {
6290
6433
  }
6291
6434
 
6292
6435
  // dist/src/skillify/local-manifest.js
6293
- import { existsSync as existsSync24, mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync13 } from "node:fs";
6294
- import { homedir as homedir17 } from "node:os";
6295
- import { dirname as dirname5, join as join27 } from "node:path";
6296
- var LOCAL_MANIFEST_PATH = join27(homedir17(), ".claude", "hivemind", "local-mined.json");
6297
- var LOCAL_MINE_LOCK_PATH = join27(homedir17(), ".claude", "hivemind", "local-mined.lock");
6436
+ import { existsSync as existsSync24, mkdirSync as mkdirSync10, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
6437
+ import { homedir as homedir16 } from "node:os";
6438
+ import { dirname as dirname6, join as join29 } from "node:path";
6439
+ var LOCAL_MANIFEST_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.json");
6440
+ var LOCAL_MINE_LOCK_PATH = join29(homedir16(), ".claude", "hivemind", "local-mined.lock");
6298
6441
  function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
6299
6442
  if (!existsSync24(path))
6300
6443
  return null;
6301
6444
  try {
6302
- return JSON.parse(readFileSync18(path, "utf-8"));
6445
+ return JSON.parse(readFileSync19(path, "utf-8"));
6303
6446
  } catch {
6304
6447
  return null;
6305
6448
  }
6306
6449
  }
6307
6450
  function writeLocalManifest(m, path = LOCAL_MANIFEST_PATH) {
6308
- mkdirSync9(dirname5(path), { recursive: true });
6309
- writeFileSync13(path, JSON.stringify(m, null, 2));
6451
+ mkdirSync10(dirname6(path), { recursive: true });
6452
+ writeFileSync14(path, JSON.stringify(m, null, 2));
6310
6453
  }
6311
6454
 
6312
6455
  // dist/src/commands/mine-local.js
6313
- import { unlinkSync as unlinkSync9 } from "node:fs";
6456
+ import { unlinkSync as unlinkSync10 } from "node:fs";
6314
6457
  var EPSILON = 0.3;
6315
6458
  var DEFAULT_N = 8;
6316
6459
  var PAIR_CHAR_CAP = 4e3;
@@ -6321,9 +6464,9 @@ var IN_FLIGHT_MAX_AGE_MS = 6e4;
6321
6464
  var GATE_TIMEOUT_MS = 24e4;
6322
6465
  var MANIFEST_PATH = LOCAL_MANIFEST_PATH;
6323
6466
  function runGateViaStdin(opts) {
6324
- return new Promise((resolve) => {
6467
+ return new Promise((resolve2) => {
6325
6468
  if (opts.agent !== "claude_code") {
6326
- resolve({
6469
+ resolve2({
6327
6470
  stdout: "",
6328
6471
  stderr: "",
6329
6472
  errored: true,
@@ -6332,7 +6475,7 @@ function runGateViaStdin(opts) {
6332
6475
  return;
6333
6476
  }
6334
6477
  if (!existsSync25(opts.bin)) {
6335
- resolve({
6478
+ resolve2({
6336
6479
  stdout: "",
6337
6480
  stderr: "",
6338
6481
  errored: true,
@@ -6359,7 +6502,7 @@ function runGateViaStdin(opts) {
6359
6502
  if (settled)
6360
6503
  return;
6361
6504
  settled = true;
6362
- resolve(r);
6505
+ resolve2(r);
6363
6506
  };
6364
6507
  const timer = setTimeout(() => {
6365
6508
  try {
@@ -6619,7 +6762,7 @@ async function runMineLocal(args) {
6619
6762
  return;
6620
6763
  lockReleased = true;
6621
6764
  try {
6622
- unlinkSync9(LOCAL_MINE_LOCK_PATH);
6765
+ unlinkSync10(LOCAL_MINE_LOCK_PATH);
6623
6766
  } catch {
6624
6767
  }
6625
6768
  };
@@ -6676,8 +6819,8 @@ async function runMineLocalImpl(args) {
6676
6819
  console.log(`Dry-run: would invoke ${gateAgent} gate on ${picked.length} session(s) in parallel (concurrency=${GATE_CONCURRENCY}).`);
6677
6820
  return;
6678
6821
  }
6679
- const tmpDir = join28(homedir18(), ".claude", "hivemind", `mine-local-${Date.now()}`);
6680
- mkdirSync10(tmpDir, { recursive: true });
6822
+ const tmpDir = join30(homedir17(), ".claude", "hivemind", `mine-local-${Date.now()}`);
6823
+ mkdirSync11(tmpDir, { recursive: true });
6681
6824
  console.log(`Running ${picked.length} gate call(s) in parallel (concurrency=${GATE_CONCURRENCY}, timeout=${GATE_TIMEOUT_MS / 1e3}s each)...`);
6682
6825
  const results = await parallelMap(picked, GATE_CONCURRENCY, async (s) => {
6683
6826
  const shortId = s.sessionId.slice(0, 8);
@@ -6688,23 +6831,23 @@ async function runMineLocalImpl(args) {
6688
6831
  return { session: s, skills: [], reason: "no pairs", error: null };
6689
6832
  }
6690
6833
  const tail = pairs2.slice(-PER_SESSION_PAIR_CAP);
6691
- const sessionTmp = join28(tmpDir, `s-${shortId}`);
6692
- mkdirSync10(sessionTmp, { recursive: true });
6693
- const verdictPath = join28(sessionTmp, "verdict.json");
6834
+ const sessionTmp = join30(tmpDir, `s-${shortId}`);
6835
+ mkdirSync11(sessionTmp, { recursive: true });
6836
+ const verdictPath = join30(sessionTmp, "verdict.json");
6694
6837
  const prompt = buildSessionPrompt(tail, s, verdictPath);
6695
- writeFileSync14(join28(sessionTmp, "prompt.txt"), prompt);
6838
+ writeFileSync15(join30(sessionTmp, "prompt.txt"), prompt);
6696
6839
  const gate = await runGateViaStdin({ agent: gateAgent, bin: gateBin, prompt, timeoutMs: GATE_TIMEOUT_MS });
6697
6840
  try {
6698
- writeFileSync14(join28(sessionTmp, "gate-stdout.txt"), gate.stdout);
6841
+ writeFileSync15(join30(sessionTmp, "gate-stdout.txt"), gate.stdout);
6699
6842
  if (gate.stderr)
6700
- writeFileSync14(join28(sessionTmp, "gate-stderr.txt"), gate.stderr);
6843
+ writeFileSync15(join30(sessionTmp, "gate-stderr.txt"), gate.stderr);
6701
6844
  } catch {
6702
6845
  }
6703
6846
  if (gate.errored) {
6704
6847
  console.log(` [${shortId}] gate failed: ${gate.errorMessage}`);
6705
6848
  return { session: s, skills: [], reason: null, error: gate.errorMessage ?? "gate failed" };
6706
6849
  }
6707
- const verdictText = existsSync25(verdictPath) ? readFileSync19(verdictPath, "utf-8") : gate.stdout;
6850
+ const verdictText = existsSync25(verdictPath) ? readFileSync20(verdictPath, "utf-8") : gate.stdout;
6708
6851
  const mv = parseMultiVerdict(verdictText);
6709
6852
  if (!mv) {
6710
6853
  console.log(` [${shortId}] unparseable verdict (kept at ${sessionTmp})`);
@@ -6756,7 +6899,7 @@ async function runMineLocalImpl(args) {
6756
6899
  sourceSessions: [session.sessionId],
6757
6900
  agent: gateAgent
6758
6901
  });
6759
- const canonicalDir = dirname6(result.path);
6902
+ const canonicalDir = dirname7(result.path);
6760
6903
  const symlinks = fanOutRoots.length > 0 ? fanOutSymlinks(canonicalDir, basename(canonicalDir), fanOutRoots) : [];
6761
6904
  const symlinkSuffix = symlinks.length > 0 ? `, fan-out \u2192 ${symlinks.length} root(s)` : "";
6762
6905
  console.log(` wrote ${skill.name} \u2190 session ${session.sessionId.slice(0, 8)} (${session.agent}${symlinkSuffix})`);
@@ -6920,7 +7063,7 @@ function wrapAt(s, max) {
6920
7063
 
6921
7064
  // dist/src/commands/skillify.js
6922
7065
  function stateDir() {
6923
- return join29(homedir19(), ".deeplake", "state", "skillify");
7066
+ return getStateDir();
6924
7067
  }
6925
7068
  function showStatus() {
6926
7069
  const cfg = loadScopeConfig();
@@ -6940,7 +7083,7 @@ function showStatus() {
6940
7083
  console.log(`state: ${files.length} project(s) tracked`);
6941
7084
  for (const f of files) {
6942
7085
  try {
6943
- const s = JSON.parse(readFileSync20(join29(dir, f), "utf-8"));
7086
+ const s = JSON.parse(readFileSync21(join31(dir, f), "utf-8"));
6944
7087
  const last = typeof s.updatedAt === "number" ? new Date(s.updatedAt).toISOString() : s.lastDate ?? "never";
6945
7088
  const skills = Array.isArray(s.skillsGenerated) && s.skillsGenerated.length > 0 ? s.skillsGenerated.join(", ") : "none";
6946
7089
  console.log(` - ${s.project} (counter=${s.counter}, last=${last}, skills=${skills})`);
@@ -6967,7 +7110,7 @@ function setInstall(loc) {
6967
7110
  }
6968
7111
  const cfg = loadScopeConfig();
6969
7112
  saveScopeConfig({ ...cfg, install: loc });
6970
- const path = loc === "global" ? join29(homedir19(), ".claude", "skills") : "<cwd>/.claude/skills";
7113
+ const path = loc === "global" ? join31(homedir18(), ".claude", "skills") : "<cwd>/.claude/skills";
6971
7114
  console.log(`Install location set to '${loc}'. New skills will be written to ${path}/<name>/SKILL.md.`);
6972
7115
  }
6973
7116
  function promoteSkill(name, cwd) {
@@ -6975,18 +7118,18 @@ function promoteSkill(name, cwd) {
6975
7118
  console.error("Usage: hivemind skillify promote <skill-name>");
6976
7119
  process.exit(1);
6977
7120
  }
6978
- const projectPath = join29(cwd, ".claude", "skills", name);
6979
- const globalPath = join29(homedir19(), ".claude", "skills", name);
6980
- if (!existsSync26(join29(projectPath, "SKILL.md"))) {
7121
+ const projectPath = join31(cwd, ".claude", "skills", name);
7122
+ const globalPath = join31(homedir18(), ".claude", "skills", name);
7123
+ if (!existsSync26(join31(projectPath, "SKILL.md"))) {
6981
7124
  console.error(`Skill '${name}' not found at ${projectPath}/SKILL.md`);
6982
7125
  process.exit(1);
6983
7126
  }
6984
- if (existsSync26(join29(globalPath, "SKILL.md"))) {
7127
+ if (existsSync26(join31(globalPath, "SKILL.md"))) {
6985
7128
  console.error(`Skill '${name}' already exists at ${globalPath}/SKILL.md \u2014 refusing to overwrite. Remove it first or rename the project skill.`);
6986
7129
  process.exit(1);
6987
7130
  }
6988
- mkdirSync11(dirname7(globalPath), { recursive: true });
6989
- renameSync6(projectPath, globalPath);
7131
+ mkdirSync12(dirname8(globalPath), { recursive: true });
7132
+ renameSync7(projectPath, globalPath);
6990
7133
  console.log(`Promoted '${name}' from ${projectPath} \u2192 ${globalPath}.`);
6991
7134
  }
6992
7135
  function teamAdd(name) {
@@ -7092,7 +7235,7 @@ async function pullSkills(args) {
7092
7235
  console.error(`pull failed: ${e?.message ?? e}`);
7093
7236
  process.exit(1);
7094
7237
  }
7095
- const dest = toRaw === "global" ? join29(homedir19(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7238
+ const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7096
7239
  const filterDesc = users.length === 0 ? "all users" : users.join(", ");
7097
7240
  console.log(`Destination: ${dest}`);
7098
7241
  console.log(`Filter: ${filterDesc}${skillName ? ` \xB7 skill='${skillName}'` : ""}${dryRun ? " \xB7 dry-run" : ""}${force ? " \xB7 force" : ""}`);
@@ -7142,7 +7285,7 @@ async function unpullSkills(args) {
7142
7285
  all,
7143
7286
  legacyCleanup
7144
7287
  });
7145
- const dest = toRaw === "global" ? join29(homedir19(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7288
+ const dest = toRaw === "global" ? join31(homedir18(), ".claude", "skills") : `${process.cwd()}/.claude/skills`;
7146
7289
  const filterParts = [];
7147
7290
  if (users.length > 0)
7148
7291
  filterParts.push(`users=${users.join(",")}`);
@@ -7238,13 +7381,13 @@ if (process.argv[1] && process.argv[1].endsWith("skillify.js")) {
7238
7381
 
7239
7382
  // dist/src/cli/update.js
7240
7383
  import { execFileSync as execFileSync4 } from "node:child_process";
7241
- import { existsSync as existsSync27, readFileSync as readFileSync22, realpathSync } from "node:fs";
7242
- import { dirname as dirname9, sep } from "node:path";
7384
+ import { existsSync as existsSync27, readFileSync as readFileSync23, realpathSync } from "node:fs";
7385
+ import { dirname as dirname10, sep } from "node:path";
7243
7386
  import { fileURLToPath as fileURLToPath2 } from "node:url";
7244
7387
 
7245
7388
  // dist/src/utils/version-check.js
7246
- import { readFileSync as readFileSync21 } from "node:fs";
7247
- import { dirname as dirname8, join as join30 } from "node:path";
7389
+ import { readFileSync as readFileSync22 } from "node:fs";
7390
+ import { dirname as dirname9, join as join32 } from "node:path";
7248
7391
  function isNewer(latest, current) {
7249
7392
  const parse = (v) => v.split(".").map(Number);
7250
7393
  const [la, lb, lc] = parse(latest);
@@ -7263,24 +7406,24 @@ function detectInstallKind(argv1) {
7263
7406
  return argv1 ?? process.argv[1] ?? fileURLToPath2(import.meta.url);
7264
7407
  }
7265
7408
  })();
7266
- let dir = dirname9(realArgv1);
7409
+ let dir = dirname10(realArgv1);
7267
7410
  let installDir = null;
7268
7411
  for (let i = 0; i < 10; i++) {
7269
7412
  const pkgPath = `${dir}${sep}package.json`;
7270
7413
  try {
7271
- const pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
7414
+ const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
7272
7415
  if (pkg.name === PKG_NAME || pkg.name === "hivemind") {
7273
7416
  installDir = dir;
7274
7417
  break;
7275
7418
  }
7276
7419
  } catch {
7277
7420
  }
7278
- const parent = dirname9(dir);
7421
+ const parent = dirname10(dir);
7279
7422
  if (parent === dir)
7280
7423
  break;
7281
7424
  dir = parent;
7282
7425
  }
7283
- installDir ??= dirname9(realArgv1);
7426
+ installDir ??= dirname10(realArgv1);
7284
7427
  if (realArgv1.includes(`${sep}_npx${sep}`) || realArgv1.includes(`${sep}.npx${sep}`)) {
7285
7428
  return { kind: "npx", installDir };
7286
7429
  }
@@ -7292,7 +7435,7 @@ function detectInstallKind(argv1) {
7292
7435
  if (existsSync27(`${gitDir}${sep}.git`)) {
7293
7436
  return { kind: "local-dev", installDir };
7294
7437
  }
7295
- const parent = dirname9(gitDir);
7438
+ const parent = dirname10(gitDir);
7296
7439
  if (parent === gitDir)
7297
7440
  break;
7298
7441
  gitDir = parent;