@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/bundle/cli.js +332 -189
- package/codex/bundle/capture.js +365 -332
- package/codex/bundle/commands/auth-login.js +163 -30
- package/codex/bundle/pre-tool-use.js +334 -301
- package/codex/bundle/session-start-setup.js +193 -60
- package/codex/bundle/session-start.js +229 -87
- package/codex/bundle/shell/deeplake-shell.js +328 -295
- package/codex/bundle/skillify-worker.js +26 -18
- package/codex/bundle/stop.js +450 -394
- package/codex/bundle/wiki-worker.js +174 -292
- package/cursor/bundle/capture.js +448 -392
- package/cursor/bundle/commands/auth-login.js +163 -30
- package/cursor/bundle/pre-tool-use.js +324 -291
- package/cursor/bundle/session-end.js +43 -20
- package/cursor/bundle/session-start.js +272 -130
- package/cursor/bundle/shell/deeplake-shell.js +328 -295
- package/cursor/bundle/skillify-worker.js +26 -18
- package/cursor/bundle/wiki-worker.js +174 -292
- package/hermes/bundle/capture.js +448 -392
- package/hermes/bundle/commands/auth-login.js +163 -30
- package/hermes/bundle/pre-tool-use.js +324 -291
- package/hermes/bundle/session-end.js +43 -20
- package/hermes/bundle/session-start.js +269 -127
- package/hermes/bundle/shell/deeplake-shell.js +328 -295
- package/hermes/bundle/skillify-worker.js +26 -18
- package/hermes/bundle/wiki-worker.js +174 -292
- package/mcp/bundle/server.js +190 -57
- package/openclaw/dist/index.js +160 -32
- package/openclaw/dist/skillify-worker.js +26 -18
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/package.json +1 -1
- package/package.json +1 -1
|
@@ -17,21 +17,21 @@ __export(index_marker_store_exports, {
|
|
|
17
17
|
hasFreshIndexMarker: () => hasFreshIndexMarker,
|
|
18
18
|
writeIndexMarker: () => writeIndexMarker
|
|
19
19
|
});
|
|
20
|
-
import { existsSync as existsSync4, mkdirSync as
|
|
21
|
-
import { join as
|
|
20
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
21
|
+
import { join as join8 } from "node:path";
|
|
22
22
|
import { tmpdir } from "node:os";
|
|
23
23
|
function getIndexMarkerDir() {
|
|
24
|
-
return process.env.HIVEMIND_INDEX_MARKER_DIR ??
|
|
24
|
+
return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join8(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
|
|
28
|
+
return join8(getIndexMarkerDir(), `${markerKey}.json`);
|
|
29
29
|
}
|
|
30
30
|
function hasFreshIndexMarker(markerPath) {
|
|
31
31
|
if (!existsSync4(markerPath))
|
|
32
32
|
return false;
|
|
33
33
|
try {
|
|
34
|
-
const raw = JSON.parse(
|
|
34
|
+
const raw = JSON.parse(readFileSync6(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
|
-
|
|
45
|
-
|
|
44
|
+
mkdirSync5(getIndexMarkerDir(), { recursive: true });
|
|
45
|
+
writeFileSync4(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({
|
|
@@ -55,7 +55,7 @@ var init_index_marker_store = __esm({
|
|
|
55
55
|
// dist/src/hooks/codex/session-start.js
|
|
56
56
|
import { spawn as spawn2 } from "node:child_process";
|
|
57
57
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
58
|
-
import { dirname as
|
|
58
|
+
import { dirname as dirname7, join as join15 } from "node:path";
|
|
59
59
|
|
|
60
60
|
// dist/src/commands/auth.js
|
|
61
61
|
import { execSync } from "node:child_process";
|
|
@@ -89,13 +89,13 @@ function loadCredentials() {
|
|
|
89
89
|
|
|
90
90
|
// dist/src/utils/stdin.js
|
|
91
91
|
function readStdin() {
|
|
92
|
-
return new Promise((
|
|
92
|
+
return new Promise((resolve2, reject) => {
|
|
93
93
|
let data = "";
|
|
94
94
|
process.stdin.setEncoding("utf-8");
|
|
95
95
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
96
96
|
process.stdin.on("end", () => {
|
|
97
97
|
try {
|
|
98
|
-
|
|
98
|
+
resolve2(JSON.parse(data));
|
|
99
99
|
} catch (err) {
|
|
100
100
|
reject(new Error(`Failed to parse hook input: ${err}`));
|
|
101
101
|
}
|
|
@@ -339,6 +339,107 @@ function sqlIdent(name) {
|
|
|
339
339
|
var SUMMARY_EMBEDDING_COL = "summary_embedding";
|
|
340
340
|
var MESSAGE_EMBEDDING_COL = "message_embedding";
|
|
341
341
|
|
|
342
|
+
// dist/src/notifications/queue.js
|
|
343
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync4, openSync as openSync2, closeSync as closeSync2, unlinkSync as unlinkSync3, statSync as statSync2 } from "node:fs";
|
|
344
|
+
import { join as join7, resolve } from "node:path";
|
|
345
|
+
import { homedir as homedir6 } from "node:os";
|
|
346
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
347
|
+
var log2 = (msg) => log("notifications-queue", msg);
|
|
348
|
+
var LOCK_RETRY_MAX = 50;
|
|
349
|
+
var LOCK_RETRY_BASE_MS = 5;
|
|
350
|
+
var LOCK_STALE_MS2 = 5e3;
|
|
351
|
+
function queuePath() {
|
|
352
|
+
return join7(homedir6(), ".deeplake", "notifications-queue.json");
|
|
353
|
+
}
|
|
354
|
+
function lockPath() {
|
|
355
|
+
return `${queuePath()}.lock`;
|
|
356
|
+
}
|
|
357
|
+
function readQueue() {
|
|
358
|
+
try {
|
|
359
|
+
const raw = readFileSync5(queuePath(), "utf-8");
|
|
360
|
+
const parsed = JSON.parse(raw);
|
|
361
|
+
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
362
|
+
log2(`queue malformed \u2192 treating as empty`);
|
|
363
|
+
return { queue: [] };
|
|
364
|
+
}
|
|
365
|
+
return { queue: parsed.queue };
|
|
366
|
+
} catch {
|
|
367
|
+
return { queue: [] };
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function _isQueuePathInsideHome(path, home) {
|
|
371
|
+
const r = resolve(path);
|
|
372
|
+
const h = resolve(home);
|
|
373
|
+
return r.startsWith(h + "/") || r === h;
|
|
374
|
+
}
|
|
375
|
+
function writeQueue(q) {
|
|
376
|
+
const path = queuePath();
|
|
377
|
+
const home = resolve(homedir6());
|
|
378
|
+
if (!_isQueuePathInsideHome(path, home)) {
|
|
379
|
+
throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
|
|
380
|
+
}
|
|
381
|
+
mkdirSync4(join7(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
382
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
383
|
+
writeFileSync3(tmp, JSON.stringify(q, null, 2), { mode: 384 });
|
|
384
|
+
renameSync(tmp, path);
|
|
385
|
+
}
|
|
386
|
+
async function withQueueLock(fn) {
|
|
387
|
+
const path = lockPath();
|
|
388
|
+
mkdirSync4(join7(homedir6(), ".deeplake"), { recursive: true, mode: 448 });
|
|
389
|
+
let fd = null;
|
|
390
|
+
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
391
|
+
try {
|
|
392
|
+
fd = openSync2(path, "wx", 384);
|
|
393
|
+
break;
|
|
394
|
+
} catch (e) {
|
|
395
|
+
const code = e.code;
|
|
396
|
+
if (code !== "EEXIST")
|
|
397
|
+
throw e;
|
|
398
|
+
try {
|
|
399
|
+
const age = Date.now() - statSync2(path).mtimeMs;
|
|
400
|
+
if (age > LOCK_STALE_MS2) {
|
|
401
|
+
unlinkSync3(path);
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
407
|
+
await sleep(delay);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (fd === null) {
|
|
411
|
+
log2(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
412
|
+
return fn();
|
|
413
|
+
}
|
|
414
|
+
try {
|
|
415
|
+
return fn();
|
|
416
|
+
} finally {
|
|
417
|
+
try {
|
|
418
|
+
closeSync2(fd);
|
|
419
|
+
} catch {
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
unlinkSync3(path);
|
|
423
|
+
} catch {
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function sameDedupKey(a, b) {
|
|
428
|
+
if (a.id !== b.id)
|
|
429
|
+
return false;
|
|
430
|
+
return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
|
|
431
|
+
}
|
|
432
|
+
async function enqueueNotification(n) {
|
|
433
|
+
await withQueueLock(() => {
|
|
434
|
+
const q = readQueue();
|
|
435
|
+
if (q.queue.some((existing) => sameDedupKey(existing, n))) {
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
q.queue.push(n);
|
|
439
|
+
writeQueue(q);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
342
443
|
// dist/src/deeplake-api.js
|
|
343
444
|
var indexMarkerStorePromise = null;
|
|
344
445
|
function getIndexMarkerStore() {
|
|
@@ -346,7 +447,7 @@ function getIndexMarkerStore() {
|
|
|
346
447
|
indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
|
|
347
448
|
return indexMarkerStorePromise;
|
|
348
449
|
}
|
|
349
|
-
var
|
|
450
|
+
var log3 = (msg) => log("sdk", msg);
|
|
350
451
|
function summarizeSql(sql, maxLen = 220) {
|
|
351
452
|
const compact = sql.replace(/\s+/g, " ").trim();
|
|
352
453
|
return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
|
|
@@ -358,7 +459,38 @@ function traceSql(msg) {
|
|
|
358
459
|
process.stderr.write(`[deeplake-sql] ${msg}
|
|
359
460
|
`);
|
|
360
461
|
if (process.env.HIVEMIND_DEBUG === "1")
|
|
361
|
-
|
|
462
|
+
log3(msg);
|
|
463
|
+
}
|
|
464
|
+
var _signalledBalanceExhausted = false;
|
|
465
|
+
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
466
|
+
if (status !== 402)
|
|
467
|
+
return;
|
|
468
|
+
if (!bodyText.includes("balance_cents"))
|
|
469
|
+
return;
|
|
470
|
+
if (_signalledBalanceExhausted)
|
|
471
|
+
return;
|
|
472
|
+
_signalledBalanceExhausted = true;
|
|
473
|
+
log3(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
|
|
474
|
+
enqueueNotification({
|
|
475
|
+
id: "balance-exhausted",
|
|
476
|
+
severity: "warn",
|
|
477
|
+
transient: true,
|
|
478
|
+
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
479
|
+
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
480
|
+
dedupKey: { reason: "balance-zero" }
|
|
481
|
+
}).catch((e) => {
|
|
482
|
+
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function billingUrl() {
|
|
486
|
+
try {
|
|
487
|
+
const c = loadCredentials();
|
|
488
|
+
if (c?.orgName && c?.workspaceId) {
|
|
489
|
+
return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
|
|
490
|
+
}
|
|
491
|
+
} catch {
|
|
492
|
+
}
|
|
493
|
+
return "https://deeplake.ai";
|
|
362
494
|
}
|
|
363
495
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
364
496
|
var MAX_RETRIES = 3;
|
|
@@ -367,8 +499,8 @@ var MAX_CONCURRENCY = 5;
|
|
|
367
499
|
function getQueryTimeoutMs() {
|
|
368
500
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
369
501
|
}
|
|
370
|
-
function
|
|
371
|
-
return new Promise((
|
|
502
|
+
function sleep2(ms) {
|
|
503
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
372
504
|
}
|
|
373
505
|
function isTimeoutError(error) {
|
|
374
506
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -398,7 +530,7 @@ var Semaphore = class {
|
|
|
398
530
|
this.active++;
|
|
399
531
|
return;
|
|
400
532
|
}
|
|
401
|
-
await new Promise((
|
|
533
|
+
await new Promise((resolve2) => this.waiting.push(resolve2));
|
|
402
534
|
}
|
|
403
535
|
release() {
|
|
404
536
|
this.active--;
|
|
@@ -469,8 +601,8 @@ var DeeplakeApi = class {
|
|
|
469
601
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
470
602
|
if (attempt < MAX_RETRIES) {
|
|
471
603
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
472
|
-
|
|
473
|
-
await
|
|
604
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
|
|
605
|
+
await sleep2(delay);
|
|
474
606
|
continue;
|
|
475
607
|
}
|
|
476
608
|
throw lastError;
|
|
@@ -486,10 +618,11 @@ var DeeplakeApi = class {
|
|
|
486
618
|
const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
|
|
487
619
|
if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
|
|
488
620
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
489
|
-
|
|
490
|
-
await
|
|
621
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
|
|
622
|
+
await sleep2(delay);
|
|
491
623
|
continue;
|
|
492
624
|
}
|
|
625
|
+
maybeSignalBalanceExhausted(resp.status, text);
|
|
493
626
|
throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
|
|
494
627
|
}
|
|
495
628
|
throw lastError ?? new Error("Query failed: max retries exceeded");
|
|
@@ -510,7 +643,7 @@ var DeeplakeApi = class {
|
|
|
510
643
|
const chunk = rows.slice(i, i + CONCURRENCY);
|
|
511
644
|
await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
|
|
512
645
|
}
|
|
513
|
-
|
|
646
|
+
log3(`commit: ${rows.length} rows`);
|
|
514
647
|
}
|
|
515
648
|
async upsertRowSql(row) {
|
|
516
649
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -566,7 +699,7 @@ var DeeplakeApi = class {
|
|
|
566
699
|
markers.writeIndexMarker(markerPath);
|
|
567
700
|
return;
|
|
568
701
|
}
|
|
569
|
-
|
|
702
|
+
log3(`index "${indexName}" skipped: ${e.message}`);
|
|
570
703
|
}
|
|
571
704
|
}
|
|
572
705
|
/**
|
|
@@ -656,13 +789,13 @@ var DeeplakeApi = class {
|
|
|
656
789
|
};
|
|
657
790
|
}
|
|
658
791
|
if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
|
|
659
|
-
await
|
|
792
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
|
|
660
793
|
continue;
|
|
661
794
|
}
|
|
662
795
|
return { tables: [], cacheable: false };
|
|
663
796
|
} catch {
|
|
664
797
|
if (attempt < MAX_RETRIES) {
|
|
665
|
-
await
|
|
798
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
666
799
|
continue;
|
|
667
800
|
}
|
|
668
801
|
return { tables: [], cacheable: false };
|
|
@@ -690,9 +823,9 @@ var DeeplakeApi = class {
|
|
|
690
823
|
} catch (err) {
|
|
691
824
|
lastErr = err;
|
|
692
825
|
const msg = err instanceof Error ? err.message : String(err);
|
|
693
|
-
|
|
826
|
+
log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
|
|
694
827
|
if (attempt < OUTER_BACKOFFS_MS.length) {
|
|
695
|
-
await
|
|
828
|
+
await sleep2(OUTER_BACKOFFS_MS[attempt]);
|
|
696
829
|
}
|
|
697
830
|
}
|
|
698
831
|
}
|
|
@@ -703,9 +836,9 @@ var DeeplakeApi = class {
|
|
|
703
836
|
const tbl = sqlIdent(name ?? this.tableName);
|
|
704
837
|
const tables = await this.listTables();
|
|
705
838
|
if (!tables.includes(tbl)) {
|
|
706
|
-
|
|
839
|
+
log3(`table "${tbl}" not found, creating`);
|
|
707
840
|
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);
|
|
708
|
-
|
|
841
|
+
log3(`table "${tbl}" created`);
|
|
709
842
|
if (!tables.includes(tbl))
|
|
710
843
|
this._tablesCache = [...tables, tbl];
|
|
711
844
|
}
|
|
@@ -718,9 +851,9 @@ var DeeplakeApi = class {
|
|
|
718
851
|
const safe = sqlIdent(name);
|
|
719
852
|
const tables = await this.listTables();
|
|
720
853
|
if (!tables.includes(safe)) {
|
|
721
|
-
|
|
854
|
+
log3(`table "${safe}" not found, creating`);
|
|
722
855
|
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);
|
|
723
|
-
|
|
856
|
+
log3(`table "${safe}" created`);
|
|
724
857
|
if (!tables.includes(safe))
|
|
725
858
|
this._tablesCache = [...tables, safe];
|
|
726
859
|
}
|
|
@@ -743,9 +876,9 @@ var DeeplakeApi = class {
|
|
|
743
876
|
const safe = sqlIdent(name);
|
|
744
877
|
const tables = await this.listTables();
|
|
745
878
|
if (!tables.includes(safe)) {
|
|
746
|
-
|
|
879
|
+
log3(`table "${safe}" not found, creating`);
|
|
747
880
|
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);
|
|
748
|
-
|
|
881
|
+
log3(`table "${safe}" created`);
|
|
749
882
|
if (!tables.includes(safe))
|
|
750
883
|
this._tablesCache = [...tables, safe];
|
|
751
884
|
}
|
|
@@ -754,14 +887,14 @@ var DeeplakeApi = class {
|
|
|
754
887
|
};
|
|
755
888
|
|
|
756
889
|
// dist/src/skillify/pull.js
|
|
757
|
-
import { existsSync as existsSync9, readFileSync as
|
|
890
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, renameSync as renameSync4, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync5 } from "node:fs";
|
|
758
891
|
import { homedir as homedir10 } from "node:os";
|
|
759
|
-
import { dirname as
|
|
892
|
+
import { dirname as dirname6, join as join14 } from "node:path";
|
|
760
893
|
|
|
761
894
|
// dist/src/skillify/skill-writer.js
|
|
762
|
-
import { existsSync as existsSync5, mkdirSync as
|
|
763
|
-
import { homedir as
|
|
764
|
-
import { join as
|
|
895
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync6, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
896
|
+
import { homedir as homedir7 } from "node:os";
|
|
897
|
+
import { join as join9 } from "node:path";
|
|
765
898
|
function assertValidSkillName(name) {
|
|
766
899
|
if (typeof name !== "string" || name.length === 0) {
|
|
767
900
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -827,34 +960,43 @@ function parseFrontmatter(text) {
|
|
|
827
960
|
}
|
|
828
961
|
|
|
829
962
|
// dist/src/skillify/manifest.js
|
|
830
|
-
import { existsSync as existsSync7, lstatSync, mkdirSync as
|
|
963
|
+
import { existsSync as existsSync7, lstatSync, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
964
|
+
import { dirname as dirname5, join as join12 } from "node:path";
|
|
965
|
+
|
|
966
|
+
// dist/src/skillify/legacy-migration.js
|
|
967
|
+
import { existsSync as existsSync6, renameSync as renameSync2 } from "node:fs";
|
|
968
|
+
import { dirname as dirname4, join as join11 } from "node:path";
|
|
969
|
+
|
|
970
|
+
// dist/src/skillify/state-dir.js
|
|
831
971
|
import { homedir as homedir8 } from "node:os";
|
|
832
|
-
import {
|
|
972
|
+
import { join as join10 } from "node:path";
|
|
973
|
+
function getStateDir() {
|
|
974
|
+
const override = process.env.HIVEMIND_STATE_DIR?.trim();
|
|
975
|
+
return override && override.length > 0 ? override : join10(homedir8(), ".deeplake", "state", "skillify");
|
|
976
|
+
}
|
|
833
977
|
|
|
834
978
|
// dist/src/skillify/legacy-migration.js
|
|
835
|
-
import { existsSync as existsSync6, renameSync } from "node:fs";
|
|
836
|
-
import { homedir as homedir7 } from "node:os";
|
|
837
|
-
import { join as join9 } from "node:path";
|
|
838
979
|
var dlog = (msg) => log("skillify-migrate", msg);
|
|
839
980
|
var attempted = false;
|
|
840
981
|
function migrateLegacyStateDir() {
|
|
982
|
+
if (process.env.HIVEMIND_STATE_DIR?.trim())
|
|
983
|
+
return;
|
|
841
984
|
if (attempted)
|
|
842
985
|
return;
|
|
843
986
|
attempted = true;
|
|
844
|
-
const
|
|
845
|
-
const legacy =
|
|
846
|
-
const current = join9(root, "skillify");
|
|
987
|
+
const current = getStateDir();
|
|
988
|
+
const legacy = join11(dirname4(current), "skilify");
|
|
847
989
|
if (!existsSync6(legacy))
|
|
848
990
|
return;
|
|
849
991
|
if (existsSync6(current))
|
|
850
992
|
return;
|
|
851
993
|
try {
|
|
852
|
-
|
|
994
|
+
renameSync2(legacy, current);
|
|
853
995
|
dlog(`migrated ${legacy} -> ${current}`);
|
|
854
996
|
} catch (err) {
|
|
855
997
|
const code = err.code;
|
|
856
|
-
if (code === "EXDEV" || code === "EPERM") {
|
|
857
|
-
dlog(`migration
|
|
998
|
+
if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
|
|
999
|
+
dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
|
|
858
1000
|
return;
|
|
859
1001
|
}
|
|
860
1002
|
throw err;
|
|
@@ -866,7 +1008,7 @@ function emptyManifest() {
|
|
|
866
1008
|
return { version: 1, entries: [] };
|
|
867
1009
|
}
|
|
868
1010
|
function manifestPath() {
|
|
869
|
-
return
|
|
1011
|
+
return join12(getStateDir(), "pulled.json");
|
|
870
1012
|
}
|
|
871
1013
|
function loadManifest(path = manifestPath()) {
|
|
872
1014
|
migrateLegacyStateDir();
|
|
@@ -874,7 +1016,7 @@ function loadManifest(path = manifestPath()) {
|
|
|
874
1016
|
return emptyManifest();
|
|
875
1017
|
let raw;
|
|
876
1018
|
try {
|
|
877
|
-
raw =
|
|
1019
|
+
raw = readFileSync8(path, "utf-8");
|
|
878
1020
|
} catch {
|
|
879
1021
|
return emptyManifest();
|
|
880
1022
|
}
|
|
@@ -921,10 +1063,10 @@ function loadManifest(path = manifestPath()) {
|
|
|
921
1063
|
}
|
|
922
1064
|
function saveManifest(m, path = manifestPath()) {
|
|
923
1065
|
migrateLegacyStateDir();
|
|
924
|
-
|
|
1066
|
+
mkdirSync7(dirname5(path), { recursive: true });
|
|
925
1067
|
const tmp = `${path}.tmp`;
|
|
926
|
-
|
|
927
|
-
|
|
1068
|
+
writeFileSync6(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
1069
|
+
renameSync3(tmp, path);
|
|
928
1070
|
}
|
|
929
1071
|
function recordPull(entry, path = manifestPath()) {
|
|
930
1072
|
const m = loadManifest(path);
|
|
@@ -949,7 +1091,7 @@ function unlinkSymlinks(paths) {
|
|
|
949
1091
|
if (!st.isSymbolicLink())
|
|
950
1092
|
continue;
|
|
951
1093
|
try {
|
|
952
|
-
|
|
1094
|
+
unlinkSync4(path);
|
|
953
1095
|
} catch {
|
|
954
1096
|
}
|
|
955
1097
|
}
|
|
@@ -959,7 +1101,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
959
1101
|
const live = [];
|
|
960
1102
|
let pruned = 0;
|
|
961
1103
|
for (const e of m.entries) {
|
|
962
|
-
if (existsSync7(
|
|
1104
|
+
if (existsSync7(join12(e.installRoot, e.dirName))) {
|
|
963
1105
|
live.push(e);
|
|
964
1106
|
continue;
|
|
965
1107
|
}
|
|
@@ -974,20 +1116,20 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
974
1116
|
// dist/src/skillify/agent-roots.js
|
|
975
1117
|
import { existsSync as existsSync8 } from "node:fs";
|
|
976
1118
|
import { homedir as homedir9 } from "node:os";
|
|
977
|
-
import { join as
|
|
1119
|
+
import { join as join13 } from "node:path";
|
|
978
1120
|
function resolveDetected(home) {
|
|
979
1121
|
const out = [];
|
|
980
|
-
const codexInstalled = existsSync8(
|
|
981
|
-
const piInstalled = existsSync8(
|
|
982
|
-
const hermesInstalled = existsSync8(
|
|
1122
|
+
const codexInstalled = existsSync8(join13(home, ".codex"));
|
|
1123
|
+
const piInstalled = existsSync8(join13(home, ".pi", "agent"));
|
|
1124
|
+
const hermesInstalled = existsSync8(join13(home, ".hermes"));
|
|
983
1125
|
if (codexInstalled || piInstalled) {
|
|
984
|
-
out.push(
|
|
1126
|
+
out.push(join13(home, ".agents", "skills"));
|
|
985
1127
|
}
|
|
986
1128
|
if (hermesInstalled) {
|
|
987
|
-
out.push(
|
|
1129
|
+
out.push(join13(home, ".hermes", "skills"));
|
|
988
1130
|
}
|
|
989
1131
|
if (piInstalled) {
|
|
990
|
-
out.push(
|
|
1132
|
+
out.push(join13(home, ".pi", "agent", "skills"));
|
|
991
1133
|
}
|
|
992
1134
|
return out;
|
|
993
1135
|
}
|
|
@@ -1035,15 +1177,15 @@ function isMissingTableError(message) {
|
|
|
1035
1177
|
}
|
|
1036
1178
|
function resolvePullDestination(install, cwd) {
|
|
1037
1179
|
if (install === "global")
|
|
1038
|
-
return
|
|
1180
|
+
return join14(homedir10(), ".claude", "skills");
|
|
1039
1181
|
if (!cwd)
|
|
1040
1182
|
throw new Error("install=project requires a cwd");
|
|
1041
|
-
return
|
|
1183
|
+
return join14(cwd, ".claude", "skills");
|
|
1042
1184
|
}
|
|
1043
1185
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
1044
1186
|
const out = [];
|
|
1045
1187
|
for (const root of agentRoots) {
|
|
1046
|
-
const link =
|
|
1188
|
+
const link = join14(root, dirName);
|
|
1047
1189
|
let existing;
|
|
1048
1190
|
try {
|
|
1049
1191
|
existing = lstatSync2(link);
|
|
@@ -1065,13 +1207,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
1065
1207
|
continue;
|
|
1066
1208
|
}
|
|
1067
1209
|
try {
|
|
1068
|
-
|
|
1210
|
+
unlinkSync5(link);
|
|
1069
1211
|
} catch {
|
|
1070
1212
|
continue;
|
|
1071
1213
|
}
|
|
1072
1214
|
}
|
|
1073
1215
|
try {
|
|
1074
|
-
|
|
1216
|
+
mkdirSync8(dirname6(link), { recursive: true });
|
|
1075
1217
|
symlinkSync(canonicalDir, link, "dir");
|
|
1076
1218
|
out.push(link);
|
|
1077
1219
|
} catch {
|
|
@@ -1086,7 +1228,7 @@ function backfillSymlinks(installRoot) {
|
|
|
1086
1228
|
return;
|
|
1087
1229
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
1088
1230
|
for (const entry of entries) {
|
|
1089
|
-
const canonical =
|
|
1231
|
+
const canonical = join14(entry.installRoot, entry.dirName);
|
|
1090
1232
|
if (!existsSync9(canonical))
|
|
1091
1233
|
continue;
|
|
1092
1234
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
@@ -1200,7 +1342,7 @@ function readLocalVersion(path) {
|
|
|
1200
1342
|
if (!existsSync9(path))
|
|
1201
1343
|
return null;
|
|
1202
1344
|
try {
|
|
1203
|
-
const text =
|
|
1345
|
+
const text = readFileSync9(path, "utf-8");
|
|
1204
1346
|
const parsed = parseFrontmatter(text);
|
|
1205
1347
|
if (!parsed)
|
|
1206
1348
|
return null;
|
|
@@ -1295,8 +1437,8 @@ async function runPull(opts) {
|
|
|
1295
1437
|
summary.skipped++;
|
|
1296
1438
|
continue;
|
|
1297
1439
|
}
|
|
1298
|
-
const skillDir =
|
|
1299
|
-
const skillFile =
|
|
1440
|
+
const skillDir = join14(root, dirName);
|
|
1441
|
+
const skillFile = join14(skillDir, "SKILL.md");
|
|
1300
1442
|
const remoteVersion = Number(row.version ?? 1);
|
|
1301
1443
|
const localVersion = readLocalVersion(skillFile);
|
|
1302
1444
|
const action = decideAction({
|
|
@@ -1307,14 +1449,14 @@ async function runPull(opts) {
|
|
|
1307
1449
|
});
|
|
1308
1450
|
let manifestError;
|
|
1309
1451
|
if (action === "wrote") {
|
|
1310
|
-
|
|
1452
|
+
mkdirSync8(skillDir, { recursive: true });
|
|
1311
1453
|
if (existsSync9(skillFile)) {
|
|
1312
1454
|
try {
|
|
1313
|
-
|
|
1455
|
+
renameSync4(skillFile, `${skillFile}.bak`);
|
|
1314
1456
|
} catch {
|
|
1315
1457
|
}
|
|
1316
1458
|
}
|
|
1317
|
-
|
|
1459
|
+
writeFileSync7(skillFile, renderSkillFile(row));
|
|
1318
1460
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
1319
1461
|
try {
|
|
1320
1462
|
recordPull({
|
|
@@ -1356,7 +1498,7 @@ async function runPull(opts) {
|
|
|
1356
1498
|
}
|
|
1357
1499
|
|
|
1358
1500
|
// dist/src/skillify/auto-pull.js
|
|
1359
|
-
var
|
|
1501
|
+
var log4 = (msg) => log("skillify-autopull", msg);
|
|
1360
1502
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1361
1503
|
function withTimeout(p, ms) {
|
|
1362
1504
|
let timer = null;
|
|
@@ -1372,13 +1514,13 @@ function withTimeout(p, ms) {
|
|
|
1372
1514
|
}
|
|
1373
1515
|
async function autoPullSkills(deps = {}) {
|
|
1374
1516
|
if (process.env.HIVEMIND_AUTOPULL_DISABLED === "1") {
|
|
1375
|
-
|
|
1517
|
+
log4("disabled via HIVEMIND_AUTOPULL_DISABLED=1");
|
|
1376
1518
|
return { pulled: 0, skipped: true, reason: "disabled" };
|
|
1377
1519
|
}
|
|
1378
1520
|
const loadFn = deps.loadConfigFn ?? loadConfig;
|
|
1379
1521
|
const config = loadFn();
|
|
1380
1522
|
if (!config) {
|
|
1381
|
-
|
|
1523
|
+
log4("skipped: not logged in");
|
|
1382
1524
|
return { pulled: 0, skipped: true, reason: "not-logged-in" };
|
|
1383
1525
|
}
|
|
1384
1526
|
let query;
|
|
@@ -1400,31 +1542,31 @@ async function autoPullSkills(deps = {}) {
|
|
|
1400
1542
|
dryRun: false,
|
|
1401
1543
|
force: false
|
|
1402
1544
|
}), timeoutMs);
|
|
1403
|
-
|
|
1545
|
+
log4(`pulled scanned=${summary.scanned} wrote=${summary.wrote} skipped=${summary.skipped}`);
|
|
1404
1546
|
return { pulled: summary.wrote, skipped: false };
|
|
1405
1547
|
} catch (e) {
|
|
1406
|
-
|
|
1548
|
+
log4(`pull failed (swallowed): ${e?.message ?? e}`);
|
|
1407
1549
|
return { pulled: 0, skipped: true, reason: "error" };
|
|
1408
1550
|
}
|
|
1409
1551
|
}
|
|
1410
1552
|
|
|
1411
1553
|
// dist/src/hooks/codex/session-start.js
|
|
1412
|
-
var
|
|
1413
|
-
var __bundleDir =
|
|
1554
|
+
var log5 = (msg) => log("codex-session-start", msg);
|
|
1555
|
+
var __bundleDir = dirname7(fileURLToPath2(import.meta.url));
|
|
1414
1556
|
async function main() {
|
|
1415
1557
|
if (process.env.HIVEMIND_WIKI_WORKER === "1")
|
|
1416
1558
|
return;
|
|
1417
1559
|
const input = await readStdin();
|
|
1418
1560
|
const creds = loadCredentials();
|
|
1419
1561
|
if (!creds?.token) {
|
|
1420
|
-
|
|
1562
|
+
log5("no credentials found \u2014 run auth login to authenticate");
|
|
1421
1563
|
const auto = maybeAutoMineLocal();
|
|
1422
|
-
|
|
1564
|
+
log5(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
|
|
1423
1565
|
} else {
|
|
1424
|
-
|
|
1566
|
+
log5(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
|
|
1425
1567
|
}
|
|
1426
1568
|
if (creds?.token) {
|
|
1427
|
-
const setupScript =
|
|
1569
|
+
const setupScript = join15(__bundleDir, "session-start-setup.js");
|
|
1428
1570
|
const child = spawn2("node", [setupScript], {
|
|
1429
1571
|
detached: true,
|
|
1430
1572
|
stdio: ["pipe", "ignore", "ignore"],
|
|
@@ -1433,10 +1575,10 @@ async function main() {
|
|
|
1433
1575
|
child.stdin?.write(JSON.stringify(input));
|
|
1434
1576
|
child.stdin?.end();
|
|
1435
1577
|
child.unref();
|
|
1436
|
-
|
|
1578
|
+
log5("spawned async setup process");
|
|
1437
1579
|
}
|
|
1438
1580
|
const pullResult = await autoPullSkills();
|
|
1439
|
-
|
|
1581
|
+
log5(`autopull: pulled=${pullResult.pulled} skipped=${pullResult.skipped}`);
|
|
1440
1582
|
let versionNotice = "";
|
|
1441
1583
|
const current = getInstalledVersion(__bundleDir, ".codex-plugin");
|
|
1442
1584
|
if (current) {
|
|
@@ -1458,6 +1600,6 @@ Hivemind v${current}`;
|
|
|
1458
1600
|
console.log(JSON.stringify(output));
|
|
1459
1601
|
}
|
|
1460
1602
|
main().catch((e) => {
|
|
1461
|
-
|
|
1603
|
+
log5(`fatal: ${e.message}`);
|
|
1462
1604
|
process.exit(0);
|
|
1463
1605
|
});
|