@deeplake/hivemind 0.7.79 → 0.7.81

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 (46) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/bundle/cli.js +140 -94
  4. package/codex/bundle/capture.js +232 -72
  5. package/codex/bundle/commands/auth-login.js +14 -10
  6. package/codex/bundle/embeddings/embed-daemon.js +9 -5
  7. package/codex/bundle/graph-on-stop.js +32 -28
  8. package/codex/bundle/graph-pull-worker.js +27 -23
  9. package/codex/bundle/pre-tool-use.js +366 -123
  10. package/codex/bundle/session-start-setup.js +18 -14
  11. package/codex/bundle/session-start.js +26 -22
  12. package/codex/bundle/shell/deeplake-shell.js +30 -26
  13. package/codex/bundle/skillify-worker.js +14 -10
  14. package/codex/bundle/skillopt-worker.js +2061 -0
  15. package/codex/bundle/stop.js +50 -45
  16. package/codex/bundle/wiki-worker.js +18 -14
  17. package/cursor/bundle/capture.js +71 -44
  18. package/cursor/bundle/commands/auth-login.js +14 -10
  19. package/cursor/bundle/embeddings/embed-daemon.js +9 -5
  20. package/cursor/bundle/graph-on-stop.js +32 -28
  21. package/cursor/bundle/graph-pull-worker.js +27 -23
  22. package/cursor/bundle/pre-tool-use.js +28 -24
  23. package/cursor/bundle/session-end.js +40 -36
  24. package/cursor/bundle/session-start.js +39 -35
  25. package/cursor/bundle/shell/deeplake-shell.js +30 -26
  26. package/cursor/bundle/skillify-worker.js +14 -10
  27. package/cursor/bundle/wiki-worker.js +18 -14
  28. package/hermes/bundle/capture.js +235 -85
  29. package/hermes/bundle/commands/auth-login.js +14 -10
  30. package/hermes/bundle/embeddings/embed-daemon.js +9 -5
  31. package/hermes/bundle/graph-on-stop.js +32 -28
  32. package/hermes/bundle/graph-pull-worker.js +27 -23
  33. package/hermes/bundle/pre-tool-use.js +298 -74
  34. package/hermes/bundle/session-end.js +40 -36
  35. package/hermes/bundle/session-start.js +39 -35
  36. package/hermes/bundle/shell/deeplake-shell.js +30 -26
  37. package/hermes/bundle/skillify-worker.js +14 -10
  38. package/hermes/bundle/skillopt-worker.js +2061 -0
  39. package/hermes/bundle/wiki-worker.js +18 -14
  40. package/mcp/bundle/server.js +15 -11
  41. package/openclaw/dist/index.js +11 -7
  42. package/openclaw/dist/skillify-worker.js +14 -10
  43. package/openclaw/openclaw.plugin.json +1 -1
  44. package/openclaw/package.json +1 -1
  45. package/package.json +1 -1
  46. package/pi/extension-source/hivemind.ts +93 -0
@@ -17,7 +17,7 @@ __export(index_marker_store_exports, {
17
17
  hasFreshIndexMarker: () => hasFreshIndexMarker,
18
18
  writeIndexMarker: () => writeIndexMarker
19
19
  });
20
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
20
+ import { existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
21
21
  import { join as join5 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
@@ -41,7 +41,7 @@ function hasFreshIndexMarker(markerPath) {
41
41
  }
42
42
  }
43
43
  function writeIndexMarker(markerPath) {
44
- mkdirSync3(getIndexMarkerDir(), { recursive: true });
44
+ mkdirSync4(getIndexMarkerDir(), { recursive: true });
45
45
  writeFileSync3(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
46
46
  }
47
47
  var INDEX_MARKER_TTL_MS;
@@ -120,8 +120,8 @@ function loadConfig() {
120
120
  import { randomUUID } from "node:crypto";
121
121
 
122
122
  // dist/src/utils/debug.js
123
- import { appendFileSync } from "node:fs";
124
- import { join as join2 } from "node:path";
123
+ import { appendFileSync, mkdirSync } from "node:fs";
124
+ import { dirname, join as join2 } from "node:path";
125
125
  import { homedir as homedir2 } from "node:os";
126
126
  var LOG = join2(homedir2(), ".deeplake", "hook-debug.log");
127
127
  function isDebug() {
@@ -133,8 +133,12 @@ function utcTimestamp(d = /* @__PURE__ */ new Date()) {
133
133
  function log(tag, msg) {
134
134
  if (!isDebug())
135
135
  return;
136
- appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
136
+ try {
137
+ mkdirSync(dirname(LOG), { recursive: true });
138
+ appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
137
139
  `);
140
+ } catch {
141
+ }
138
142
  }
139
143
 
140
144
  // dist/src/utils/sql.js
@@ -340,7 +344,7 @@ async function healMissingColumns(args) {
340
344
  }
341
345
 
342
346
  // dist/src/notifications/queue.js
343
- import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync, openSync, closeSync, unlinkSync, statSync } from "node:fs";
347
+ import { readFileSync as readFileSync2, writeFileSync, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync, statSync } from "node:fs";
344
348
  import { join as join3, resolve } from "node:path";
345
349
  import { homedir as homedir3 } from "node:os";
346
350
  import { setTimeout as sleep } from "node:timers/promises";
@@ -367,38 +371,38 @@ function readQueue() {
367
371
  return { queue: [] };
368
372
  }
369
373
  }
370
- function _isQueuePathInsideHome(path, home) {
371
- const r = resolve(path);
374
+ function _isQueuePathInsideHome(path2, home) {
375
+ const r = resolve(path2);
372
376
  const h = resolve(home);
373
377
  return r.startsWith(h + "/") || r === h;
374
378
  }
375
379
  function writeQueue(q) {
376
- const path = queuePath();
380
+ const path2 = queuePath();
377
381
  const home = resolve(homedir3());
378
- if (!_isQueuePathInsideHome(path, home)) {
379
- throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
382
+ if (!_isQueuePathInsideHome(path2, home)) {
383
+ throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
380
384
  }
381
- mkdirSync(join3(home, ".deeplake"), { recursive: true, mode: 448 });
382
- const tmp = `${path}.${process.pid}.tmp`;
385
+ mkdirSync2(join3(home, ".deeplake"), { recursive: true, mode: 448 });
386
+ const tmp = `${path2}.${process.pid}.tmp`;
383
387
  writeFileSync(tmp, JSON.stringify(q, null, 2), { mode: 384 });
384
- renameSync(tmp, path);
388
+ renameSync(tmp, path2);
385
389
  }
386
390
  async function withQueueLock(fn) {
387
- const path = lockPath();
388
- mkdirSync(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
391
+ const path2 = lockPath();
392
+ mkdirSync2(join3(homedir3(), ".deeplake"), { recursive: true, mode: 448 });
389
393
  let fd = null;
390
394
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
391
395
  try {
392
- fd = openSync(path, "wx", 384);
396
+ fd = openSync(path2, "wx", 384);
393
397
  break;
394
398
  } catch (e) {
395
399
  const code = e.code;
396
400
  if (code !== "EEXIST")
397
401
  throw e;
398
402
  try {
399
- const age = Date.now() - statSync(path).mtimeMs;
403
+ const age = Date.now() - statSync(path2).mtimeMs;
400
404
  if (age > LOCK_STALE_MS) {
401
- unlinkSync(path);
405
+ unlinkSync(path2);
402
406
  continue;
403
407
  }
404
408
  } catch {
@@ -419,7 +423,7 @@ async function withQueueLock(fn) {
419
423
  } catch {
420
424
  }
421
425
  try {
422
- unlinkSync(path);
426
+ unlinkSync(path2);
423
427
  } catch {
424
428
  }
425
429
  }
@@ -441,7 +445,7 @@ async function enqueueNotification(n) {
441
445
  }
442
446
 
443
447
  // dist/src/commands/auth-creds.js
444
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "node:fs";
448
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, unlinkSync as unlinkSync2 } from "node:fs";
445
449
  import { join as join4 } from "node:path";
446
450
  import { homedir as homedir4 } from "node:os";
447
451
  function configDir() {
@@ -695,9 +699,9 @@ var DeeplakeApi = class {
695
699
  }
696
700
  }
697
701
  /** Update specific columns on a row by path. */
698
- async updateColumns(path, columns) {
702
+ async updateColumns(path2, columns) {
699
703
  const setClauses = Object.entries(columns).map(([col, val]) => typeof val === "number" ? `${col} = ${val}` : `${col} = '${sqlStr(String(val))}'`).join(", ");
700
- await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path)}'`);
704
+ await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(path2)}'`);
701
705
  }
702
706
  // ── Convenience ─────────────────────────────────────────────────────────────
703
707
  /** Create a BM25 search index on a column. */
@@ -1394,22 +1398,22 @@ import { join as join8 } from "node:path";
1394
1398
  import { pathToFileURL } from "node:url";
1395
1399
 
1396
1400
  // dist/src/user-config.js
1397
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
1401
+ import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
1398
1402
  import { homedir as homedir6 } from "node:os";
1399
- import { dirname, join as join7 } from "node:path";
1403
+ import { dirname as dirname2, join as join7 } from "node:path";
1400
1404
  var _configPath = () => process.env.HIVEMIND_CONFIG_PATH ?? join7(homedir6(), ".deeplake", "config.json");
1401
1405
  var _cache = null;
1402
1406
  var _migrated = false;
1403
1407
  function readUserConfig() {
1404
1408
  if (_cache !== null)
1405
1409
  return _cache;
1406
- const path = _configPath();
1407
- if (!existsSync4(path)) {
1410
+ const path2 = _configPath();
1411
+ if (!existsSync4(path2)) {
1408
1412
  _cache = {};
1409
1413
  return _cache;
1410
1414
  }
1411
1415
  try {
1412
- const raw = readFileSync6(path, "utf-8");
1416
+ const raw = readFileSync6(path2, "utf-8");
1413
1417
  const parsed = JSON.parse(raw);
1414
1418
  _cache = isPlainObject(parsed) ? parsed : {};
1415
1419
  } catch {
@@ -1420,13 +1424,13 @@ function readUserConfig() {
1420
1424
  function writeUserConfig(patch) {
1421
1425
  const current = readUserConfig();
1422
1426
  const merged = deepMerge(current, patch);
1423
- const path = _configPath();
1424
- const dir = dirname(path);
1427
+ const path2 = _configPath();
1428
+ const dir = dirname2(path2);
1425
1429
  if (!existsSync4(dir))
1426
- mkdirSync4(dir, { recursive: true });
1427
- const tmp = `${path}.tmp.${process.pid}`;
1430
+ mkdirSync5(dir, { recursive: true });
1431
+ const tmp = `${path2}.tmp.${process.pid}`;
1428
1432
  writeFileSync4(tmp, JSON.stringify(merged, null, 2) + "\n", "utf-8");
1429
- renameSync2(tmp, path);
1433
+ renameSync2(tmp, path2);
1430
1434
  _cache = merged;
1431
1435
  return merged;
1432
1436
  }
@@ -1506,15 +1510,15 @@ function embeddingsDisabled() {
1506
1510
  }
1507
1511
 
1508
1512
  // dist/src/embeddings/self-heal.js
1509
- import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
1513
+ import { existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync6, readlinkSync, renameSync as renameSync3, rmSync, symlinkSync, statSync as statSync2 } from "node:fs";
1510
1514
  import { homedir as homedir8 } from "node:os";
1511
- import { basename as basename2, dirname as dirname2, join as join9 } from "node:path";
1515
+ import { basename as basename2, dirname as dirname3, join as join9 } from "node:path";
1512
1516
  function ensurePluginNodeModulesLink(opts) {
1513
1517
  if (basename2(opts.bundleDir) !== "bundle") {
1514
1518
  return { kind: "not-bundle-layout", bundleDir: opts.bundleDir };
1515
1519
  }
1516
1520
  const target = opts.sharedNodeModules ?? join9(homedir8(), ".hivemind", "embed-deps", "node_modules");
1517
- const pluginDir = dirname2(opts.bundleDir);
1521
+ const pluginDir = dirname3(opts.bundleDir);
1518
1522
  const link = join9(pluginDir, "node_modules");
1519
1523
  if (!existsSync5(target)) {
1520
1524
  return { kind: "shared-deps-missing", target };
@@ -1554,9 +1558,9 @@ function ensurePluginNodeModulesLink(opts) {
1554
1558
  }
1555
1559
  function createSymlinkAtomic(target, link) {
1556
1560
  try {
1557
- const parent = dirname2(link);
1561
+ const parent = dirname3(link);
1558
1562
  if (!existsSync5(parent))
1559
- mkdirSync5(parent, { recursive: true });
1563
+ mkdirSync6(parent, { recursive: true });
1560
1564
  const tmp = `${link}.tmp.${process.pid}`;
1561
1565
  try {
1562
1566
  rmSync(tmp, { force: true });
@@ -1571,11 +1575,11 @@ function createSymlinkAtomic(target, link) {
1571
1575
  }
1572
1576
 
1573
1577
  // dist/src/hooks/codex/capture.js
1574
- import { fileURLToPath as fileURLToPath2 } from "node:url";
1575
- import { dirname as dirname5, join as join14 } from "node:path";
1578
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
1579
+ import { dirname as dirname8, join as join18 } from "node:path";
1576
1580
 
1577
1581
  // dist/src/hooks/summary-state.js
1578
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync6, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
1582
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, writeSync as writeSync2, mkdirSync as mkdirSync7, renameSync as renameSync4, existsSync as existsSync6, unlinkSync as unlinkSync4, openSync as openSync3, closeSync as closeSync3, statSync as statSync3 } from "node:fs";
1579
1583
  import { homedir as homedir9 } from "node:os";
1580
1584
  import { join as join10 } from "node:path";
1581
1585
  var dlog = (msg) => log("summary-state", msg);
@@ -1598,14 +1602,14 @@ function readState(sessionId) {
1598
1602
  }
1599
1603
  }
1600
1604
  function writeState(sessionId, state) {
1601
- mkdirSync6(STATE_DIR, { recursive: true });
1605
+ mkdirSync7(STATE_DIR, { recursive: true });
1602
1606
  const p = statePath(sessionId);
1603
1607
  const tmp = `${p}.${process.pid}.${Date.now()}.tmp`;
1604
1608
  writeFileSync5(tmp, JSON.stringify(state));
1605
1609
  renameSync4(tmp, p);
1606
1610
  }
1607
1611
  function withRmwLock(sessionId, fn) {
1608
- mkdirSync6(STATE_DIR, { recursive: true });
1612
+ mkdirSync7(STATE_DIR, { recursive: true });
1609
1613
  const rmwLock = statePath(sessionId) + ".rmw";
1610
1614
  const deadline = Date.now() + 2e3;
1611
1615
  let fd = null;
@@ -1667,7 +1671,7 @@ function shouldTrigger(state, cfg, now = Date.now()) {
1667
1671
  return false;
1668
1672
  }
1669
1673
  function tryAcquireLock(sessionId, maxAgeMs = 10 * 60 * 1e3) {
1670
- mkdirSync6(STATE_DIR, { recursive: true });
1674
+ mkdirSync7(STATE_DIR, { recursive: true });
1671
1675
  const p = lockPath2(sessionId);
1672
1676
  if (existsSync6(p)) {
1673
1677
  try {
@@ -1711,21 +1715,21 @@ function releaseLock(sessionId) {
1711
1715
  // dist/src/hooks/codex/spawn-wiki-worker.js
1712
1716
  import { execSync } from "node:child_process";
1713
1717
  import { fileURLToPath } from "node:url";
1714
- import { dirname as dirname4, join as join13 } from "node:path";
1715
- import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "node:fs";
1718
+ import { dirname as dirname5, join as join13 } from "node:path";
1719
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync9 } from "node:fs";
1716
1720
  import { homedir as homedir10, tmpdir as tmpdir2 } from "node:os";
1717
1721
 
1718
1722
  // dist/src/utils/wiki-log.js
1719
- import { mkdirSync as mkdirSync7, appendFileSync as appendFileSync2 } from "node:fs";
1723
+ import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync2 } from "node:fs";
1720
1724
  import { join as join11 } from "node:path";
1721
1725
  function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1722
- const path = join11(hooksDir, filename);
1726
+ const path2 = join11(hooksDir, filename);
1723
1727
  return {
1724
- path,
1728
+ path: path2,
1725
1729
  log(msg) {
1726
1730
  try {
1727
- mkdirSync7(hooksDir, { recursive: true });
1728
- appendFileSync2(path, `[${utcTimestamp()}] ${msg}
1731
+ mkdirSync8(hooksDir, { recursive: true });
1732
+ appendFileSync2(path2, `[${utcTimestamp()}] ${msg}
1729
1733
  `);
1730
1734
  } catch {
1731
1735
  }
@@ -1735,7 +1739,7 @@ function makeWikiLogger(hooksDir, filename = "deeplake-wiki.log") {
1735
1739
 
1736
1740
  // dist/src/utils/version-check.js
1737
1741
  import { readFileSync as readFileSync8 } from "node:fs";
1738
- import { dirname as dirname3, join as join12 } from "node:path";
1742
+ import { dirname as dirname4, join as join12 } from "node:path";
1739
1743
  function getInstalledVersion(bundleDir, pluginManifestDir) {
1740
1744
  try {
1741
1745
  const pluginJson = join12(bundleDir, "..", pluginManifestDir, "plugin.json");
@@ -1767,7 +1771,7 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
1767
1771
  return pkg.version;
1768
1772
  } catch {
1769
1773
  }
1770
- const parent = dirname3(dir);
1774
+ const parent = dirname4(dir);
1771
1775
  if (parent === dir)
1772
1776
  break;
1773
1777
  dir = parent;
@@ -1778,10 +1782,10 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
1778
1782
  // dist/src/utils/spawn-detached.js
1779
1783
  import { spawn as nodeSpawn } from "node:child_process";
1780
1784
  function spawnDetachedNodeWorker(workerPath, args = [], deps = {}) {
1781
- const spawn2 = deps.spawn ?? nodeSpawn;
1785
+ const spawn3 = deps.spawn ?? nodeSpawn;
1782
1786
  const execPath = deps.execPath ?? process.execPath;
1783
1787
  try {
1784
- const child = spawn2(execPath, [workerPath, ...args], {
1788
+ const child = spawn3(execPath, [workerPath, ...args], {
1785
1789
  detached: true,
1786
1790
  stdio: ["ignore", "ignore", "ignore"],
1787
1791
  // Suppress the transient console window Windows would otherwise pop for
@@ -1863,7 +1867,7 @@ function spawnCodexWikiWorker(opts) {
1863
1867
  const { config, sessionId, cwd, bundleDir, reason } = opts;
1864
1868
  const projectName = projectNameFromCwd(cwd);
1865
1869
  const tmpDir = join13(tmpdir2(), `deeplake-wiki-${sessionId}-${Date.now()}`);
1866
- mkdirSync8(tmpDir, { recursive: true });
1870
+ mkdirSync9(tmpDir, { recursive: true });
1867
1871
  const pluginVersion = getInstalledVersion(bundleDir, ".codex-plugin") ?? "";
1868
1872
  const configFile = join13(tmpDir, "config.json");
1869
1873
  writeFileSync6(configFile, JSON.stringify({
@@ -1889,15 +1893,166 @@ function spawnCodexWikiWorker(opts) {
1889
1893
  wikiLog(`${reason}: spawned summary worker for ${sessionId}`);
1890
1894
  }
1891
1895
  function bundleDirFromImportMeta(importMetaUrl) {
1892
- return dirname4(fileURLToPath(importMetaUrl));
1896
+ return dirname5(fileURLToPath(importMetaUrl));
1897
+ }
1898
+
1899
+ // dist/src/utils/plugin-state.js
1900
+ import { readFileSync as readFileSync9 } from "node:fs";
1901
+ import { join as join14 } from "node:path";
1902
+ import { homedir as homedir11 } from "node:os";
1903
+ var PLUGIN_ID = "hivemind@hivemind";
1904
+ function isHivemindPluginEnabled() {
1905
+ try {
1906
+ const settingsPath = join14(homedir11(), ".claude", "settings.json");
1907
+ const settings = JSON.parse(readFileSync9(settingsPath, "utf-8"));
1908
+ const enabledPlugins = settings?.enabledPlugins;
1909
+ if (enabledPlugins && typeof enabledPlugins === "object" && PLUGIN_ID in enabledPlugins) {
1910
+ return enabledPlugins[PLUGIN_ID] !== false;
1911
+ }
1912
+ return true;
1913
+ } catch {
1914
+ return true;
1915
+ }
1916
+ }
1917
+
1918
+ // dist/src/skillify/skillopt-trigger.js
1919
+ import { spawn as spawn2 } from "node:child_process";
1920
+ import fs from "node:fs";
1921
+ import path from "node:path";
1922
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
1923
+
1924
+ // dist/src/skillify/state-dir.js
1925
+ import { homedir as homedir12 } from "node:os";
1926
+ import { join as join15 } from "node:path";
1927
+ function getStateDir() {
1928
+ const override = process.env.HIVEMIND_STATE_DIR?.trim();
1929
+ return override && override.length > 0 ? override : join15(homedir12(), ".deeplake", "state", "skillify");
1930
+ }
1931
+
1932
+ // dist/src/skillify/manifest.js
1933
+ import { existsSync as existsSync8, lstatSync as lstatSync2, mkdirSync as mkdirSync10, readFileSync as readFileSync10, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync7 } from "node:fs";
1934
+ import { dirname as dirname7, join as join17 } from "node:path";
1935
+
1936
+ // dist/src/skillify/legacy-migration.js
1937
+ import { existsSync as existsSync7, renameSync as renameSync5 } from "node:fs";
1938
+ import { dirname as dirname6, join as join16 } from "node:path";
1939
+
1940
+ // dist/src/skillify/skillopt-env.js
1941
+ var SKILLOPT_ENV = {
1942
+ /** User-set kill switch: "1" disables the whole trigger. */
1943
+ DISABLED: "HIVEMIND_SKILLOPT_DISABLED",
1944
+ /** Recursion guard the trigger sets on the spawned worker so the worker can't re-arm. */
1945
+ WORKER: "HIVEMIND_SKILLOPT_WORKER",
1946
+ /** Worker inputs, handed trigger → worker via the child env. */
1947
+ SESSION: "HIVEMIND_SKILLOPT_SESSION",
1948
+ SKILL: "HIVEMIND_SKILLOPT_SKILL",
1949
+ REACTION: "HIVEMIND_SKILLOPT_REACTION",
1950
+ TOOL_USE_ID: "HIVEMIND_SKILLOPT_TOOL_USE_ID",
1951
+ /** Which agent's CLI runs the judge/proposer (claude_code/codex/hermes/cursor/pi). */
1952
+ AGENT: "HIVEMIND_SKILLOPT_AGENT",
1953
+ /** K-message judgment-window size override. */
1954
+ JUDGE_WINDOW: "HIVEMIND_SKILLOPT_JUDGE_WINDOW"
1955
+ };
1956
+
1957
+ // dist/src/skillify/skillopt-trigger.js
1958
+ var log5 = (m) => log("skillopt-trigger", m);
1959
+ function defaultHasCreds() {
1960
+ try {
1961
+ return Boolean(loadConfig()?.token);
1962
+ } catch {
1963
+ return false;
1964
+ }
1965
+ }
1966
+ var MAX_REACTION = 8e3;
1967
+ function pendingFile(sessionId) {
1968
+ const safe = sessionId.replace(/[^A-Za-z0-9_-]/g, "_").slice(0, 200);
1969
+ return path.join(getStateDir(), "skillopt", "pending", `${safe}.json`);
1970
+ }
1971
+ var fileStore = {
1972
+ load(sessionId) {
1973
+ try {
1974
+ return JSON.parse(fs.readFileSync(pendingFile(sessionId), "utf8"));
1975
+ } catch {
1976
+ return null;
1977
+ }
1978
+ },
1979
+ save(sessionId, p) {
1980
+ try {
1981
+ const f = pendingFile(sessionId);
1982
+ if (p === null) {
1983
+ try {
1984
+ fs.unlinkSync(f);
1985
+ } catch {
1986
+ }
1987
+ return;
1988
+ }
1989
+ fs.mkdirSync(path.dirname(f), { recursive: true });
1990
+ const tmp = `${f}.${process.pid}.tmp`;
1991
+ fs.writeFileSync(tmp, JSON.stringify(p));
1992
+ fs.renameSync(tmp, f);
1993
+ } catch {
1994
+ }
1995
+ }
1996
+ };
1997
+ function runEventTrigger(sessionId, reaction, opts = {}) {
1998
+ const deps = opts.deps ?? {};
1999
+ const env = deps.env ?? process.env;
2000
+ if (env[SKILLOPT_ENV.DISABLED] === "1")
2001
+ return { fired: false, reason: "disabled" };
2002
+ if (env[SKILLOPT_ENV.WORKER] === "1")
2003
+ return { fired: false, reason: "in-worker" };
2004
+ if (!sessionId)
2005
+ return { fired: false, reason: "no-skill" };
2006
+ const store = deps.store ?? fileStore;
2007
+ const p = store.load(sessionId);
2008
+ if (!p)
2009
+ return { fired: false, reason: "no-skill" };
2010
+ if (!(deps.canFire ?? defaultHasCreds)())
2011
+ return { fired: false, reason: "no-creds" };
2012
+ store.save(sessionId, p.budget - 1 <= 0 ? null : { ...p, budget: p.budget - 1 });
2013
+ (deps.spawnWorker ?? spawnWorker)(sessionId, p.skill, reaction ?? "", p.toolUseId, opts.agent);
2014
+ return { fired: true, reason: "spawned" };
2015
+ }
2016
+ function spawnWorker(sessionId, skill, reaction, toolUseId, agent) {
2017
+ try {
2018
+ const here = path.dirname(fileURLToPath2(import.meta.url));
2019
+ const entry = path.join(here, "skillopt-worker.js");
2020
+ const child = spawn2(process.execPath, [entry], {
2021
+ detached: true,
2022
+ stdio: "ignore",
2023
+ env: {
2024
+ ...process.env,
2025
+ [SKILLOPT_ENV.WORKER]: "1",
2026
+ [SKILLOPT_ENV.SESSION]: sessionId,
2027
+ [SKILLOPT_ENV.SKILL]: skill,
2028
+ [SKILLOPT_ENV.REACTION]: (reaction ?? "").slice(0, MAX_REACTION),
2029
+ ...toolUseId ? { [SKILLOPT_ENV.TOOL_USE_ID]: toolUseId } : {},
2030
+ ...agent ? { [SKILLOPT_ENV.AGENT]: agent } : {}
2031
+ }
2032
+ });
2033
+ child.unref();
2034
+ log5(`spawned skillopt worker for ${skill} in ${sessionId}${agent ? ` (agent=${agent})` : ""}`);
2035
+ } catch (e) {
2036
+ log5(`spawn failed (swallowed): ${e?.message ?? e}`);
2037
+ }
2038
+ }
2039
+
2040
+ // dist/src/hooks/shared/skillopt-hook.js
2041
+ function reactSkillOpt(sessionId, prompt, agent) {
2042
+ try {
2043
+ if (prompt === void 0 || prompt.trim() === "" || process.env.HIVEMIND_WIKI_WORKER === "1")
2044
+ return;
2045
+ runEventTrigger(sessionId, prompt, { agent });
2046
+ } catch {
2047
+ }
1893
2048
  }
1894
2049
 
1895
2050
  // dist/src/hooks/codex/capture.js
1896
- var log5 = (msg) => log("codex-capture", msg);
2051
+ var log6 = (msg) => log("codex-capture", msg);
1897
2052
  function resolveEmbedDaemonPath() {
1898
- return join14(dirname5(fileURLToPath2(import.meta.url)), "embeddings", "embed-daemon.js");
2053
+ return join18(dirname8(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
1899
2054
  }
1900
- var __bundleDir = dirname5(fileURLToPath2(import.meta.url));
2055
+ var __bundleDir = dirname8(fileURLToPath3(import.meta.url));
1901
2056
  var PLUGIN_VERSION = getInstalledVersion(__bundleDir, ".codex-plugin") ?? "";
1902
2057
  if (!embeddingsDisabled()) {
1903
2058
  try {
@@ -1909,10 +2064,14 @@ var CAPTURE = process.env.HIVEMIND_CAPTURE !== "false";
1909
2064
  async function main() {
1910
2065
  if (!CAPTURE)
1911
2066
  return;
2067
+ if (!isHivemindPluginEnabled()) {
2068
+ log6("plugin disabled, skipping capture");
2069
+ return;
2070
+ }
1912
2071
  const input = await readStdin();
1913
2072
  const config = loadConfig();
1914
2073
  if (!config) {
1915
- log5("no config");
2074
+ log6("no config");
1916
2075
  return;
1917
2076
  }
1918
2077
  const sessionsTable = config.sessionsTableName;
@@ -1929,7 +2088,7 @@ async function main() {
1929
2088
  };
1930
2089
  let entry;
1931
2090
  if (input.hook_event_name === "UserPromptSubmit" && input.prompt !== void 0) {
1932
- log5(`user session=${input.session_id}`);
2091
+ log6(`user session=${input.session_id}`);
1933
2092
  entry = {
1934
2093
  id: crypto.randomUUID(),
1935
2094
  ...meta,
@@ -1937,7 +2096,7 @@ async function main() {
1937
2096
  content: input.prompt
1938
2097
  };
1939
2098
  } else if (input.hook_event_name === "PostToolUse" && input.tool_name !== void 0) {
1940
- log5(`tool=${input.tool_name} session=${input.session_id}`);
2099
+ log6(`tool=${input.tool_name} session=${input.session_id}`);
1941
2100
  entry = {
1942
2101
  id: crypto.randomUUID(),
1943
2102
  ...meta,
@@ -1948,12 +2107,12 @@ async function main() {
1948
2107
  tool_response: JSON.stringify(input.tool_response)
1949
2108
  };
1950
2109
  } else {
1951
- log5(`unknown event: ${input.hook_event_name}, skipping`);
2110
+ log6(`unknown event: ${input.hook_event_name}, skipping`);
1952
2111
  return;
1953
2112
  }
1954
2113
  const sessionPath = buildSessionPath(config, input.session_id);
1955
2114
  const line = JSON.stringify(entry);
1956
- log5(`writing to ${sessionPath}`);
2115
+ log6(`writing to ${sessionPath}`);
1957
2116
  const projectName = projectNameFromCwd(input.cwd);
1958
2117
  const filename = sessionPath.split("/").pop() ?? "";
1959
2118
  const jsonForSql = line.replace(/'/g, "''");
@@ -1964,14 +2123,15 @@ async function main() {
1964
2123
  await api.query(insertSql);
1965
2124
  } catch (e) {
1966
2125
  if (e.message?.includes("permission denied") || e.message?.includes("does not exist")) {
1967
- log5("table missing, creating and retrying");
2126
+ log6("table missing, creating and retrying");
1968
2127
  await api.ensureSessionsTable(sessionsTable);
1969
2128
  await api.query(insertSql);
1970
2129
  } else {
1971
2130
  throw e;
1972
2131
  }
1973
2132
  }
1974
- log5("capture ok");
2133
+ log6("capture ok");
2134
+ reactSkillOpt(input.session_id, input.prompt, "codex");
1975
2135
  maybeTriggerPeriodicSummary(input.session_id, input.cwd ?? "", config);
1976
2136
  }
1977
2137
  function maybeTriggerPeriodicSummary(sessionId, cwd, config) {
@@ -1983,7 +2143,7 @@ function maybeTriggerPeriodicSummary(sessionId, cwd, config) {
1983
2143
  if (!shouldTrigger(state, cfg))
1984
2144
  return;
1985
2145
  if (!tryAcquireLock(sessionId)) {
1986
- log5(`periodic trigger suppressed (lock held) session=${sessionId}`);
2146
+ log6(`periodic trigger suppressed (lock held) session=${sessionId}`);
1987
2147
  return;
1988
2148
  }
1989
2149
  wikiLog(`Periodic: threshold hit (total=${state.totalCount}, since=${state.totalCount - state.lastSummaryCount}, N=${cfg.everyNMessages}, hours=${cfg.everyHours})`);
@@ -1996,19 +2156,19 @@ function maybeTriggerPeriodicSummary(sessionId, cwd, config) {
1996
2156
  reason: "Periodic"
1997
2157
  });
1998
2158
  } catch (e) {
1999
- log5(`periodic spawn failed: ${e.message}`);
2159
+ log6(`periodic spawn failed: ${e.message}`);
2000
2160
  try {
2001
2161
  releaseLock(sessionId);
2002
2162
  } catch (releaseErr) {
2003
- log5(`releaseLock after periodic spawn failure also failed: ${releaseErr.message}`);
2163
+ log6(`releaseLock after periodic spawn failure also failed: ${releaseErr.message}`);
2004
2164
  }
2005
2165
  throw e;
2006
2166
  }
2007
2167
  } catch (e) {
2008
- log5(`periodic trigger error: ${e.message}`);
2168
+ log6(`periodic trigger error: ${e.message}`);
2009
2169
  }
2010
2170
  }
2011
2171
  main().catch((e) => {
2012
- log5(`fatal: ${e.message}`);
2172
+ log6(`fatal: ${e.message}`);
2013
2173
  process.exit(0);
2014
2174
  });
@@ -17,7 +17,7 @@ __export(index_marker_store_exports, {
17
17
  hasFreshIndexMarker: () => hasFreshIndexMarker,
18
18
  writeIndexMarker: () => writeIndexMarker
19
19
  });
20
- import { existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
20
+ import { existsSync as existsSync2, mkdirSync as mkdirSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
21
21
  import { join as join6 } from "node:path";
22
22
  import { tmpdir } from "node:os";
23
23
  function getIndexMarkerDir() {
@@ -41,7 +41,7 @@ function hasFreshIndexMarker(markerPath) {
41
41
  }
42
42
  }
43
43
  function writeIndexMarker(markerPath) {
44
- mkdirSync4(getIndexMarkerDir(), { recursive: true });
44
+ mkdirSync5(getIndexMarkerDir(), { recursive: true });
45
45
  writeFileSync4(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
46
46
  }
47
47
  var INDEX_MARKER_TTL_MS;
@@ -413,8 +413,8 @@ function loadConfig() {
413
413
  import { randomUUID as randomUUID2 } from "node:crypto";
414
414
 
415
415
  // dist/src/utils/debug.js
416
- import { appendFileSync } from "node:fs";
417
- import { join as join4 } from "node:path";
416
+ import { appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
417
+ import { dirname, join as join4 } from "node:path";
418
418
  import { homedir as homedir4 } from "node:os";
419
419
  var LOG = join4(homedir4(), ".deeplake", "hook-debug.log");
420
420
  function isDebug() {
@@ -423,8 +423,12 @@ function isDebug() {
423
423
  function log(tag, msg) {
424
424
  if (!isDebug())
425
425
  return;
426
- appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
426
+ try {
427
+ mkdirSync3(dirname(LOG), { recursive: true });
428
+ appendFileSync(LOG, `${(/* @__PURE__ */ new Date()).toISOString()} [${tag}] ${msg}
427
429
  `);
430
+ } catch {
431
+ }
428
432
  }
429
433
 
430
434
  // dist/src/utils/sql.js
@@ -621,7 +625,7 @@ async function healMissingColumns(args) {
621
625
  }
622
626
 
623
627
  // dist/src/notifications/queue.js
624
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync3, openSync, closeSync, unlinkSync as unlinkSync2, statSync } from "node:fs";
628
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync4, openSync, closeSync, unlinkSync as unlinkSync2, statSync } from "node:fs";
625
629
  import { join as join5, resolve } from "node:path";
626
630
  import { homedir as homedir5 } from "node:os";
627
631
  import { setTimeout as sleep } from "node:timers/promises";
@@ -659,14 +663,14 @@ function writeQueue(q) {
659
663
  if (!_isQueuePathInsideHome(path, home)) {
660
664
  throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
661
665
  }
662
- mkdirSync3(join5(home, ".deeplake"), { recursive: true, mode: 448 });
666
+ mkdirSync4(join5(home, ".deeplake"), { recursive: true, mode: 448 });
663
667
  const tmp = `${path}.${process.pid}.tmp`;
664
668
  writeFileSync3(tmp, JSON.stringify(q, null, 2), { mode: 384 });
665
669
  renameSync(tmp, path);
666
670
  }
667
671
  async function withQueueLock(fn) {
668
672
  const path = lockPath();
669
- mkdirSync3(join5(homedir5(), ".deeplake"), { recursive: true, mode: 448 });
673
+ mkdirSync4(join5(homedir5(), ".deeplake"), { recursive: true, mode: 448 });
670
674
  let fd = null;
671
675
  for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
672
676
  try {
@@ -1241,8 +1245,8 @@ var DeeplakeApi = class {
1241
1245
  };
1242
1246
 
1243
1247
  // dist/src/cli/util.js
1244
- import { existsSync as existsSync3, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, cpSync, symlinkSync, unlinkSync as unlinkSync3, lstatSync } from "node:fs";
1245
- import { join as join7, dirname } from "node:path";
1248
+ import { existsSync as existsSync3, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync5, cpSync, symlinkSync, unlinkSync as unlinkSync3, lstatSync } from "node:fs";
1249
+ import { join as join7, dirname as dirname2 } from "node:path";
1246
1250
  import { homedir as homedir6 } from "node:os";
1247
1251
  import { fileURLToPath } from "node:url";
1248
1252
  import { createInterface } from "node:readline";