@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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +140 -94
- package/codex/bundle/capture.js +232 -72
- package/codex/bundle/commands/auth-login.js +14 -10
- package/codex/bundle/embeddings/embed-daemon.js +9 -5
- package/codex/bundle/graph-on-stop.js +32 -28
- package/codex/bundle/graph-pull-worker.js +27 -23
- package/codex/bundle/pre-tool-use.js +366 -123
- package/codex/bundle/session-start-setup.js +18 -14
- package/codex/bundle/session-start.js +26 -22
- package/codex/bundle/shell/deeplake-shell.js +30 -26
- package/codex/bundle/skillify-worker.js +14 -10
- package/codex/bundle/skillopt-worker.js +2061 -0
- package/codex/bundle/stop.js +50 -45
- package/codex/bundle/wiki-worker.js +18 -14
- package/cursor/bundle/capture.js +71 -44
- package/cursor/bundle/commands/auth-login.js +14 -10
- package/cursor/bundle/embeddings/embed-daemon.js +9 -5
- package/cursor/bundle/graph-on-stop.js +32 -28
- package/cursor/bundle/graph-pull-worker.js +27 -23
- package/cursor/bundle/pre-tool-use.js +28 -24
- package/cursor/bundle/session-end.js +40 -36
- package/cursor/bundle/session-start.js +39 -35
- package/cursor/bundle/shell/deeplake-shell.js +30 -26
- package/cursor/bundle/skillify-worker.js +14 -10
- package/cursor/bundle/wiki-worker.js +18 -14
- package/hermes/bundle/capture.js +235 -85
- package/hermes/bundle/commands/auth-login.js +14 -10
- package/hermes/bundle/embeddings/embed-daemon.js +9 -5
- package/hermes/bundle/graph-on-stop.js +32 -28
- package/hermes/bundle/graph-pull-worker.js +27 -23
- package/hermes/bundle/pre-tool-use.js +298 -74
- package/hermes/bundle/session-end.js +40 -36
- package/hermes/bundle/session-start.js +39 -35
- package/hermes/bundle/shell/deeplake-shell.js +30 -26
- package/hermes/bundle/skillify-worker.js +14 -10
- package/hermes/bundle/skillopt-worker.js +2061 -0
- package/hermes/bundle/wiki-worker.js +18 -14
- package/mcp/bundle/server.js +15 -11
- package/openclaw/dist/index.js +11 -7
- package/openclaw/dist/skillify-worker.js +14 -10
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
- package/pi/extension-source/hivemind.ts +93 -0
package/codex/bundle/capture.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
371
|
-
const r = resolve(
|
|
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
|
|
380
|
+
const path2 = queuePath();
|
|
377
381
|
const home = resolve(homedir3());
|
|
378
|
-
if (!_isQueuePathInsideHome(
|
|
379
|
-
throw new Error(`notifications-queue write blocked: ${
|
|
382
|
+
if (!_isQueuePathInsideHome(path2, home)) {
|
|
383
|
+
throw new Error(`notifications-queue write blocked: ${path2} is outside ${home}`);
|
|
380
384
|
}
|
|
381
|
-
|
|
382
|
-
const 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,
|
|
388
|
+
renameSync(tmp, path2);
|
|
385
389
|
}
|
|
386
390
|
async function withQueueLock(fn) {
|
|
387
|
-
const
|
|
388
|
-
|
|
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(
|
|
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(
|
|
403
|
+
const age = Date.now() - statSync(path2).mtimeMs;
|
|
400
404
|
if (age > LOCK_STALE_MS) {
|
|
401
|
-
unlinkSync(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
1407
|
-
if (!existsSync4(
|
|
1410
|
+
const path2 = _configPath();
|
|
1411
|
+
if (!existsSync4(path2)) {
|
|
1408
1412
|
_cache = {};
|
|
1409
1413
|
return _cache;
|
|
1410
1414
|
}
|
|
1411
1415
|
try {
|
|
1412
|
-
const raw = readFileSync6(
|
|
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
|
|
1424
|
-
const dir =
|
|
1427
|
+
const path2 = _configPath();
|
|
1428
|
+
const dir = dirname2(path2);
|
|
1425
1429
|
if (!existsSync4(dir))
|
|
1426
|
-
|
|
1427
|
-
const tmp = `${
|
|
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,
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
1561
|
+
const parent = dirname3(link);
|
|
1558
1562
|
if (!existsSync5(parent))
|
|
1559
|
-
|
|
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
|
|
1575
|
-
import { dirname as
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1715
|
-
import { writeFileSync as writeFileSync6, mkdirSync as
|
|
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
|
|
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
|
|
1726
|
+
const path2 = join11(hooksDir, filename);
|
|
1723
1727
|
return {
|
|
1724
|
-
path,
|
|
1728
|
+
path: path2,
|
|
1725
1729
|
log(msg) {
|
|
1726
1730
|
try {
|
|
1727
|
-
|
|
1728
|
-
appendFileSync2(
|
|
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
|
|
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 =
|
|
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
|
|
1785
|
+
const spawn3 = deps.spawn ?? nodeSpawn;
|
|
1782
1786
|
const execPath = deps.execPath ?? process.execPath;
|
|
1783
1787
|
try {
|
|
1784
|
-
const child =
|
|
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
|
-
|
|
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
|
|
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
|
|
2051
|
+
var log6 = (msg) => log("codex-capture", msg);
|
|
1897
2052
|
function resolveEmbedDaemonPath() {
|
|
1898
|
-
return
|
|
2053
|
+
return join18(dirname8(fileURLToPath3(import.meta.url)), "embeddings", "embed-daemon.js");
|
|
1899
2054
|
}
|
|
1900
|
-
var __bundleDir =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2159
|
+
log6(`periodic spawn failed: ${e.message}`);
|
|
2000
2160
|
try {
|
|
2001
2161
|
releaseLock(sessionId);
|
|
2002
2162
|
} catch (releaseErr) {
|
|
2003
|
-
|
|
2163
|
+
log6(`releaseLock after periodic spawn failure also failed: ${releaseErr.message}`);
|
|
2004
2164
|
}
|
|
2005
2165
|
throw e;
|
|
2006
2166
|
}
|
|
2007
2167
|
} catch (e) {
|
|
2008
|
-
|
|
2168
|
+
log6(`periodic trigger error: ${e.message}`);
|
|
2009
2169
|
}
|
|
2010
2170
|
}
|
|
2011
2171
|
main().catch((e) => {
|
|
2012
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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";
|