@deeplake/hivemind 0.7.31 → 0.7.33
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 +594 -267
- package/codex/bundle/capture.js +585 -124
- package/codex/bundle/commands/auth-login.js +163 -30
- package/codex/bundle/embeddings/embed-daemon.js +55 -4
- package/codex/bundle/pre-tool-use.js +475 -85
- package/codex/bundle/session-start-setup.js +193 -60
- package/codex/bundle/session-start.js +221 -88
- package/codex/bundle/shell/deeplake-shell.js +458 -68
- package/codex/bundle/stop.js +565 -175
- package/codex/bundle/wiki-worker.js +258 -19
- package/cursor/bundle/capture.js +660 -199
- package/cursor/bundle/commands/auth-login.js +163 -30
- package/cursor/bundle/embeddings/embed-daemon.js +55 -4
- package/cursor/bundle/pre-tool-use.js +460 -70
- package/cursor/bundle/session-start.js +271 -131
- package/cursor/bundle/shell/deeplake-shell.js +458 -68
- package/cursor/bundle/wiki-worker.js +258 -19
- package/hermes/bundle/capture.js +661 -200
- package/hermes/bundle/commands/auth-login.js +163 -30
- package/hermes/bundle/embeddings/embed-daemon.js +55 -4
- package/hermes/bundle/pre-tool-use.js +459 -69
- package/hermes/bundle/session-start.js +268 -128
- package/hermes/bundle/shell/deeplake-shell.js +458 -68
- package/hermes/bundle/wiki-worker.js +258 -19
- package/mcp/bundle/server.js +190 -57
- package/openclaw/dist/index.js +160 -32
- 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 existsSync2, mkdirSync as
|
|
21
|
-
import { join as
|
|
20
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
21
|
+
import { join as join5 } 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 ?? join5(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 join5(getIndexMarkerDir(), `${markerKey}.json`);
|
|
29
29
|
}
|
|
30
30
|
function hasFreshIndexMarker(markerPath) {
|
|
31
31
|
if (!existsSync2(markerPath))
|
|
32
32
|
return false;
|
|
33
33
|
try {
|
|
34
|
-
const raw = JSON.parse(
|
|
34
|
+
const raw = JSON.parse(readFileSync4(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
|
+
mkdirSync3(getIndexMarkerDir(), { recursive: true });
|
|
45
|
+
writeFileSync3(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({
|
|
@@ -152,6 +152,107 @@ function sqlIdent(name) {
|
|
|
152
152
|
var SUMMARY_EMBEDDING_COL = "summary_embedding";
|
|
153
153
|
var MESSAGE_EMBEDDING_COL = "message_embedding";
|
|
154
154
|
|
|
155
|
+
// dist/src/notifications/queue.js
|
|
156
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, renameSync, mkdirSync as mkdirSync2, openSync, closeSync, unlinkSync as unlinkSync2, statSync } from "node:fs";
|
|
157
|
+
import { join as join4, resolve } from "node:path";
|
|
158
|
+
import { homedir as homedir4 } from "node:os";
|
|
159
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
160
|
+
var log2 = (msg) => log("notifications-queue", msg);
|
|
161
|
+
var LOCK_RETRY_MAX = 50;
|
|
162
|
+
var LOCK_RETRY_BASE_MS = 5;
|
|
163
|
+
var LOCK_STALE_MS = 5e3;
|
|
164
|
+
function queuePath() {
|
|
165
|
+
return join4(homedir4(), ".deeplake", "notifications-queue.json");
|
|
166
|
+
}
|
|
167
|
+
function lockPath() {
|
|
168
|
+
return `${queuePath()}.lock`;
|
|
169
|
+
}
|
|
170
|
+
function readQueue() {
|
|
171
|
+
try {
|
|
172
|
+
const raw = readFileSync3(queuePath(), "utf-8");
|
|
173
|
+
const parsed = JSON.parse(raw);
|
|
174
|
+
if (!parsed || !Array.isArray(parsed.queue)) {
|
|
175
|
+
log2(`queue malformed \u2192 treating as empty`);
|
|
176
|
+
return { queue: [] };
|
|
177
|
+
}
|
|
178
|
+
return { queue: parsed.queue };
|
|
179
|
+
} catch {
|
|
180
|
+
return { queue: [] };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function _isQueuePathInsideHome(path, home) {
|
|
184
|
+
const r = resolve(path);
|
|
185
|
+
const h = resolve(home);
|
|
186
|
+
return r.startsWith(h + "/") || r === h;
|
|
187
|
+
}
|
|
188
|
+
function writeQueue(q) {
|
|
189
|
+
const path = queuePath();
|
|
190
|
+
const home = resolve(homedir4());
|
|
191
|
+
if (!_isQueuePathInsideHome(path, home)) {
|
|
192
|
+
throw new Error(`notifications-queue write blocked: ${path} is outside ${home}`);
|
|
193
|
+
}
|
|
194
|
+
mkdirSync2(join4(home, ".deeplake"), { recursive: true, mode: 448 });
|
|
195
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
196
|
+
writeFileSync2(tmp, JSON.stringify(q, null, 2), { mode: 384 });
|
|
197
|
+
renameSync(tmp, path);
|
|
198
|
+
}
|
|
199
|
+
async function withQueueLock(fn) {
|
|
200
|
+
const path = lockPath();
|
|
201
|
+
mkdirSync2(join4(homedir4(), ".deeplake"), { recursive: true, mode: 448 });
|
|
202
|
+
let fd = null;
|
|
203
|
+
for (let attempt = 0; attempt < LOCK_RETRY_MAX; attempt++) {
|
|
204
|
+
try {
|
|
205
|
+
fd = openSync(path, "wx", 384);
|
|
206
|
+
break;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
const code = e.code;
|
|
209
|
+
if (code !== "EEXIST")
|
|
210
|
+
throw e;
|
|
211
|
+
try {
|
|
212
|
+
const age = Date.now() - statSync(path).mtimeMs;
|
|
213
|
+
if (age > LOCK_STALE_MS) {
|
|
214
|
+
unlinkSync2(path);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
const delay = LOCK_RETRY_BASE_MS * (attempt + 1);
|
|
220
|
+
await sleep(delay);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (fd === null) {
|
|
224
|
+
log2(`lock acquisition gave up after ${LOCK_RETRY_MAX} attempts \u2014 proceeding unlocked (last-writer-wins)`);
|
|
225
|
+
return fn();
|
|
226
|
+
}
|
|
227
|
+
try {
|
|
228
|
+
return fn();
|
|
229
|
+
} finally {
|
|
230
|
+
try {
|
|
231
|
+
closeSync(fd);
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
unlinkSync2(path);
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function sameDedupKey(a, b) {
|
|
241
|
+
if (a.id !== b.id)
|
|
242
|
+
return false;
|
|
243
|
+
return JSON.stringify(a.dedupKey) === JSON.stringify(b.dedupKey);
|
|
244
|
+
}
|
|
245
|
+
async function enqueueNotification(n) {
|
|
246
|
+
await withQueueLock(() => {
|
|
247
|
+
const q = readQueue();
|
|
248
|
+
if (q.queue.some((existing) => sameDedupKey(existing, n))) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
q.queue.push(n);
|
|
252
|
+
writeQueue(q);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
155
256
|
// dist/src/deeplake-api.js
|
|
156
257
|
var indexMarkerStorePromise = null;
|
|
157
258
|
function getIndexMarkerStore() {
|
|
@@ -159,7 +260,7 @@ function getIndexMarkerStore() {
|
|
|
159
260
|
indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
|
|
160
261
|
return indexMarkerStorePromise;
|
|
161
262
|
}
|
|
162
|
-
var
|
|
263
|
+
var log3 = (msg) => log("sdk", msg);
|
|
163
264
|
function summarizeSql(sql, maxLen = 220) {
|
|
164
265
|
const compact = sql.replace(/\s+/g, " ").trim();
|
|
165
266
|
return compact.length > maxLen ? `${compact.slice(0, maxLen)}...` : compact;
|
|
@@ -171,7 +272,38 @@ function traceSql(msg) {
|
|
|
171
272
|
process.stderr.write(`[deeplake-sql] ${msg}
|
|
172
273
|
`);
|
|
173
274
|
if (process.env.HIVEMIND_DEBUG === "1")
|
|
174
|
-
|
|
275
|
+
log3(msg);
|
|
276
|
+
}
|
|
277
|
+
var _signalledBalanceExhausted = false;
|
|
278
|
+
function maybeSignalBalanceExhausted(status, bodyText) {
|
|
279
|
+
if (status !== 402)
|
|
280
|
+
return;
|
|
281
|
+
if (!bodyText.includes("balance_cents"))
|
|
282
|
+
return;
|
|
283
|
+
if (_signalledBalanceExhausted)
|
|
284
|
+
return;
|
|
285
|
+
_signalledBalanceExhausted = true;
|
|
286
|
+
log3(`balance exhausted \u2014 enqueuing session-start banner (body=${bodyText.slice(0, 120)})`);
|
|
287
|
+
enqueueNotification({
|
|
288
|
+
id: "balance-exhausted",
|
|
289
|
+
severity: "warn",
|
|
290
|
+
transient: true,
|
|
291
|
+
title: "Hivemind credits exhausted \u2014 top up to keep capturing",
|
|
292
|
+
body: `Sessions are not being saved and memory recall is returning empty. Top up at ${billingUrl()} to restore capture and recall.`,
|
|
293
|
+
dedupKey: { reason: "balance-zero" }
|
|
294
|
+
}).catch((e) => {
|
|
295
|
+
log3(`enqueue balance-exhausted failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
function billingUrl() {
|
|
299
|
+
try {
|
|
300
|
+
const c = loadCredentials();
|
|
301
|
+
if (c?.orgName && c?.workspaceId) {
|
|
302
|
+
return `https://deeplake.ai/${encodeURIComponent(c.orgName)}/workspace/${encodeURIComponent(c.workspaceId)}/billing`;
|
|
303
|
+
}
|
|
304
|
+
} catch {
|
|
305
|
+
}
|
|
306
|
+
return "https://deeplake.ai";
|
|
175
307
|
}
|
|
176
308
|
var RETRYABLE_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
177
309
|
var MAX_RETRIES = 3;
|
|
@@ -180,8 +312,8 @@ var MAX_CONCURRENCY = 5;
|
|
|
180
312
|
function getQueryTimeoutMs() {
|
|
181
313
|
return Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
|
|
182
314
|
}
|
|
183
|
-
function
|
|
184
|
-
return new Promise((
|
|
315
|
+
function sleep2(ms) {
|
|
316
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
185
317
|
}
|
|
186
318
|
function isTimeoutError(error) {
|
|
187
319
|
const name = error instanceof Error ? error.name.toLowerCase() : "";
|
|
@@ -211,7 +343,7 @@ var Semaphore = class {
|
|
|
211
343
|
this.active++;
|
|
212
344
|
return;
|
|
213
345
|
}
|
|
214
|
-
await new Promise((
|
|
346
|
+
await new Promise((resolve2) => this.waiting.push(resolve2));
|
|
215
347
|
}
|
|
216
348
|
release() {
|
|
217
349
|
this.active--;
|
|
@@ -282,8 +414,8 @@ var DeeplakeApi = class {
|
|
|
282
414
|
lastError = e instanceof Error ? e : new Error(String(e));
|
|
283
415
|
if (attempt < MAX_RETRIES) {
|
|
284
416
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
285
|
-
|
|
286
|
-
await
|
|
417
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (fetch error: ${lastError.message}) in ${delay.toFixed(0)}ms`);
|
|
418
|
+
await sleep2(delay);
|
|
287
419
|
continue;
|
|
288
420
|
}
|
|
289
421
|
throw lastError;
|
|
@@ -299,10 +431,11 @@ var DeeplakeApi = class {
|
|
|
299
431
|
const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
|
|
300
432
|
if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
|
|
301
433
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
|
|
302
|
-
|
|
303
|
-
await
|
|
434
|
+
log3(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
|
|
435
|
+
await sleep2(delay);
|
|
304
436
|
continue;
|
|
305
437
|
}
|
|
438
|
+
maybeSignalBalanceExhausted(resp.status, text);
|
|
306
439
|
throw new Error(`Query failed: ${resp.status}: ${text.slice(0, 200)}`);
|
|
307
440
|
}
|
|
308
441
|
throw lastError ?? new Error("Query failed: max retries exceeded");
|
|
@@ -323,7 +456,7 @@ var DeeplakeApi = class {
|
|
|
323
456
|
const chunk = rows.slice(i, i + CONCURRENCY);
|
|
324
457
|
await Promise.allSettled(chunk.map((r) => this.upsertRowSql(r)));
|
|
325
458
|
}
|
|
326
|
-
|
|
459
|
+
log3(`commit: ${rows.length} rows`);
|
|
327
460
|
}
|
|
328
461
|
async upsertRowSql(row) {
|
|
329
462
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -379,7 +512,7 @@ var DeeplakeApi = class {
|
|
|
379
512
|
markers.writeIndexMarker(markerPath);
|
|
380
513
|
return;
|
|
381
514
|
}
|
|
382
|
-
|
|
515
|
+
log3(`index "${indexName}" skipped: ${e.message}`);
|
|
383
516
|
}
|
|
384
517
|
}
|
|
385
518
|
/**
|
|
@@ -469,13 +602,13 @@ var DeeplakeApi = class {
|
|
|
469
602
|
};
|
|
470
603
|
}
|
|
471
604
|
if (attempt < MAX_RETRIES && RETRYABLE_CODES.has(resp.status)) {
|
|
472
|
-
await
|
|
605
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200);
|
|
473
606
|
continue;
|
|
474
607
|
}
|
|
475
608
|
return { tables: [], cacheable: false };
|
|
476
609
|
} catch {
|
|
477
610
|
if (attempt < MAX_RETRIES) {
|
|
478
|
-
await
|
|
611
|
+
await sleep2(BASE_DELAY_MS * Math.pow(2, attempt));
|
|
479
612
|
continue;
|
|
480
613
|
}
|
|
481
614
|
return { tables: [], cacheable: false };
|
|
@@ -503,9 +636,9 @@ var DeeplakeApi = class {
|
|
|
503
636
|
} catch (err) {
|
|
504
637
|
lastErr = err;
|
|
505
638
|
const msg = err instanceof Error ? err.message : String(err);
|
|
506
|
-
|
|
639
|
+
log3(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
|
|
507
640
|
if (attempt < OUTER_BACKOFFS_MS.length) {
|
|
508
|
-
await
|
|
641
|
+
await sleep2(OUTER_BACKOFFS_MS[attempt]);
|
|
509
642
|
}
|
|
510
643
|
}
|
|
511
644
|
}
|
|
@@ -516,9 +649,9 @@ var DeeplakeApi = class {
|
|
|
516
649
|
const tbl = sqlIdent(name ?? this.tableName);
|
|
517
650
|
const tables = await this.listTables();
|
|
518
651
|
if (!tables.includes(tbl)) {
|
|
519
|
-
|
|
652
|
+
log3(`table "${tbl}" not found, creating`);
|
|
520
653
|
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);
|
|
521
|
-
|
|
654
|
+
log3(`table "${tbl}" created`);
|
|
522
655
|
if (!tables.includes(tbl))
|
|
523
656
|
this._tablesCache = [...tables, tbl];
|
|
524
657
|
}
|
|
@@ -531,9 +664,9 @@ var DeeplakeApi = class {
|
|
|
531
664
|
const safe = sqlIdent(name);
|
|
532
665
|
const tables = await this.listTables();
|
|
533
666
|
if (!tables.includes(safe)) {
|
|
534
|
-
|
|
667
|
+
log3(`table "${safe}" not found, creating`);
|
|
535
668
|
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);
|
|
536
|
-
|
|
669
|
+
log3(`table "${safe}" created`);
|
|
537
670
|
if (!tables.includes(safe))
|
|
538
671
|
this._tablesCache = [...tables, safe];
|
|
539
672
|
}
|
|
@@ -556,9 +689,9 @@ var DeeplakeApi = class {
|
|
|
556
689
|
const safe = sqlIdent(name);
|
|
557
690
|
const tables = await this.listTables();
|
|
558
691
|
if (!tables.includes(safe)) {
|
|
559
|
-
|
|
692
|
+
log3(`table "${safe}" not found, creating`);
|
|
560
693
|
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);
|
|
561
|
-
|
|
694
|
+
log3(`table "${safe}" created`);
|
|
562
695
|
if (!tables.includes(safe))
|
|
563
696
|
this._tablesCache = [...tables, safe];
|
|
564
697
|
}
|
|
@@ -596,16 +729,16 @@ function renderSkillifyCommands() {
|
|
|
596
729
|
}
|
|
597
730
|
|
|
598
731
|
// dist/src/skillify/local-manifest.js
|
|
599
|
-
import { existsSync as existsSync3, mkdirSync as
|
|
600
|
-
import { homedir as
|
|
601
|
-
import { dirname, join as
|
|
602
|
-
var LOCAL_MANIFEST_PATH =
|
|
603
|
-
var LOCAL_MINE_LOCK_PATH =
|
|
732
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
733
|
+
import { homedir as homedir5 } from "node:os";
|
|
734
|
+
import { dirname, join as join6 } from "node:path";
|
|
735
|
+
var LOCAL_MANIFEST_PATH = join6(homedir5(), ".claude", "hivemind", "local-mined.json");
|
|
736
|
+
var LOCAL_MINE_LOCK_PATH = join6(homedir5(), ".claude", "hivemind", "local-mined.lock");
|
|
604
737
|
function readLocalManifest(path = LOCAL_MANIFEST_PATH) {
|
|
605
738
|
if (!existsSync3(path))
|
|
606
739
|
return null;
|
|
607
740
|
try {
|
|
608
|
-
return JSON.parse(
|
|
741
|
+
return JSON.parse(readFileSync5(path, "utf-8"));
|
|
609
742
|
} catch {
|
|
610
743
|
return null;
|
|
611
744
|
}
|
|
@@ -617,19 +750,19 @@ function countLocalManifestEntries(path = LOCAL_MANIFEST_PATH) {
|
|
|
617
750
|
|
|
618
751
|
// dist/src/skillify/spawn-mine-local-worker.js
|
|
619
752
|
import { execFileSync, spawn } from "node:child_process";
|
|
620
|
-
import { closeSync, existsSync as existsSync4, mkdirSync as
|
|
621
|
-
import { homedir as
|
|
622
|
-
import { dirname as dirname2, join as
|
|
753
|
+
import { closeSync as closeSync2, existsSync as existsSync4, mkdirSync as mkdirSync5, openSync as openSync2, readdirSync, statSync as statSync2, unlinkSync as unlinkSync3 } from "node:fs";
|
|
754
|
+
import { homedir as homedir6 } from "node:os";
|
|
755
|
+
import { dirname as dirname2, join as join7 } from "node:path";
|
|
623
756
|
import { fileURLToPath } from "node:url";
|
|
624
|
-
var HOME =
|
|
625
|
-
var HIVEMIND_DIR =
|
|
626
|
-
var LOG_PATH =
|
|
627
|
-
var CLAUDE_PROJECTS_DIR =
|
|
628
|
-
var
|
|
757
|
+
var HOME = homedir6();
|
|
758
|
+
var HIVEMIND_DIR = join7(HOME, ".claude", "hivemind");
|
|
759
|
+
var LOG_PATH = join7(HOME, ".claude", "hooks", "mine-local.log");
|
|
760
|
+
var CLAUDE_PROJECTS_DIR = join7(HOME, ".claude", "projects");
|
|
761
|
+
var LOCK_STALE_MS2 = 15 * 60 * 1e3;
|
|
629
762
|
function findBundledCliPath() {
|
|
630
763
|
try {
|
|
631
764
|
const thisDir = dirname2(fileURLToPath(import.meta.url));
|
|
632
|
-
const cliPath =
|
|
765
|
+
const cliPath = join7(thisDir, "..", "..", "bundle", "cli.js");
|
|
633
766
|
return existsSync4(cliPath) ? cliPath : null;
|
|
634
767
|
} catch {
|
|
635
768
|
return null;
|
|
@@ -662,7 +795,7 @@ function hasLocalClaudeSessions() {
|
|
|
662
795
|
for (const sub of subdirs) {
|
|
663
796
|
let files;
|
|
664
797
|
try {
|
|
665
|
-
files = readdirSync(
|
|
798
|
+
files = readdirSync(join7(CLAUDE_PROJECTS_DIR, sub));
|
|
666
799
|
} catch {
|
|
667
800
|
continue;
|
|
668
801
|
}
|
|
@@ -677,14 +810,14 @@ function maybeAutoMineLocal() {
|
|
|
677
810
|
if (existsSync4(LOCAL_MINE_LOCK_PATH)) {
|
|
678
811
|
let stale = false;
|
|
679
812
|
try {
|
|
680
|
-
const stats =
|
|
681
|
-
stale = Date.now() - stats.mtimeMs >
|
|
813
|
+
const stats = statSync2(LOCAL_MINE_LOCK_PATH);
|
|
814
|
+
stale = Date.now() - stats.mtimeMs > LOCK_STALE_MS2;
|
|
682
815
|
} catch {
|
|
683
816
|
}
|
|
684
817
|
if (!stale)
|
|
685
818
|
return { triggered: false, reason: "lock-exists" };
|
|
686
819
|
try {
|
|
687
|
-
|
|
820
|
+
unlinkSync3(LOCAL_MINE_LOCK_PATH);
|
|
688
821
|
} catch {
|
|
689
822
|
return { triggered: false, reason: "lock-exists" };
|
|
690
823
|
}
|
|
@@ -695,27 +828,27 @@ function maybeAutoMineLocal() {
|
|
|
695
828
|
if (!launcher)
|
|
696
829
|
return { triggered: false, reason: "no-hivemind-bin" };
|
|
697
830
|
try {
|
|
698
|
-
|
|
699
|
-
const fd =
|
|
700
|
-
|
|
831
|
+
mkdirSync5(HIVEMIND_DIR, { recursive: true });
|
|
832
|
+
const fd = openSync2(LOCAL_MINE_LOCK_PATH, "wx");
|
|
833
|
+
closeSync2(fd);
|
|
701
834
|
} catch {
|
|
702
835
|
return { triggered: false, reason: "lock-acquire-failed" };
|
|
703
836
|
}
|
|
704
837
|
try {
|
|
705
|
-
|
|
706
|
-
const out =
|
|
838
|
+
mkdirSync5(join7(HOME, ".claude", "hooks"), { recursive: true });
|
|
839
|
+
const out = openSync2(LOG_PATH, "a");
|
|
707
840
|
const [cmd, args] = launcher.kind === "node-script" ? [process.execPath, [launcher.path, "skillify", "mine-local"]] : [launcher.path, ["skillify", "mine-local"]];
|
|
708
841
|
const child = spawn(cmd, args, {
|
|
709
842
|
detached: true,
|
|
710
843
|
stdio: ["ignore", out, out],
|
|
711
844
|
env: process.env
|
|
712
845
|
});
|
|
713
|
-
|
|
846
|
+
closeSync2(out);
|
|
714
847
|
child.unref();
|
|
715
848
|
return { triggered: true };
|
|
716
849
|
} catch {
|
|
717
850
|
try {
|
|
718
|
-
|
|
851
|
+
unlinkSync3(LOCAL_MINE_LOCK_PATH);
|
|
719
852
|
} catch {
|
|
720
853
|
}
|
|
721
854
|
return { triggered: false, reason: "spawn-failed" };
|
|
@@ -724,13 +857,13 @@ function maybeAutoMineLocal() {
|
|
|
724
857
|
|
|
725
858
|
// dist/src/utils/stdin.js
|
|
726
859
|
function readStdin() {
|
|
727
|
-
return new Promise((
|
|
860
|
+
return new Promise((resolve2, reject) => {
|
|
728
861
|
let data = "";
|
|
729
862
|
process.stdin.setEncoding("utf-8");
|
|
730
863
|
process.stdin.on("data", (chunk) => data += chunk);
|
|
731
864
|
process.stdin.on("end", () => {
|
|
732
865
|
try {
|
|
733
|
-
|
|
866
|
+
resolve2(JSON.parse(data));
|
|
734
867
|
} catch (err) {
|
|
735
868
|
reject(new Error(`Failed to parse hook input: ${err}`));
|
|
736
869
|
}
|
|
@@ -740,18 +873,18 @@ function readStdin() {
|
|
|
740
873
|
}
|
|
741
874
|
|
|
742
875
|
// dist/src/utils/version-check.js
|
|
743
|
-
import { readFileSync as
|
|
744
|
-
import { dirname as dirname3, join as
|
|
876
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
877
|
+
import { dirname as dirname3, join as join8 } from "node:path";
|
|
745
878
|
function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
746
879
|
try {
|
|
747
|
-
const pluginJson =
|
|
748
|
-
const plugin = JSON.parse(
|
|
880
|
+
const pluginJson = join8(bundleDir, "..", pluginManifestDir, "plugin.json");
|
|
881
|
+
const plugin = JSON.parse(readFileSync6(pluginJson, "utf-8"));
|
|
749
882
|
if (plugin.version)
|
|
750
883
|
return plugin.version;
|
|
751
884
|
} catch {
|
|
752
885
|
}
|
|
753
886
|
try {
|
|
754
|
-
const stamp =
|
|
887
|
+
const stamp = readFileSync6(join8(bundleDir, "..", ".hivemind_version"), "utf-8").trim();
|
|
755
888
|
if (stamp)
|
|
756
889
|
return stamp;
|
|
757
890
|
} catch {
|
|
@@ -766,9 +899,9 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
766
899
|
]);
|
|
767
900
|
let dir = bundleDir;
|
|
768
901
|
for (let i = 0; i < 5; i++) {
|
|
769
|
-
const candidate =
|
|
902
|
+
const candidate = join8(dir, "package.json");
|
|
770
903
|
try {
|
|
771
|
-
const pkg = JSON.parse(
|
|
904
|
+
const pkg = JSON.parse(readFileSync6(candidate, "utf-8"));
|
|
772
905
|
if (HIVEMIND_PKG_NAMES.has(pkg.name) && pkg.version)
|
|
773
906
|
return pkg.version;
|
|
774
907
|
} catch {
|
|
@@ -784,8 +917,8 @@ function getInstalledVersion(bundleDir, pluginManifestDir) {
|
|
|
784
917
|
// dist/src/hooks/shared/autoupdate.js
|
|
785
918
|
import { spawn as spawn2 } from "node:child_process";
|
|
786
919
|
import { existsSync as existsSync5 } from "node:fs";
|
|
787
|
-
import { join as
|
|
788
|
-
var
|
|
920
|
+
import { join as join9 } from "node:path";
|
|
921
|
+
var log4 = (msg) => log("autoupdate", msg);
|
|
789
922
|
var defaultSpawn = (cmd, args) => {
|
|
790
923
|
const child = spawn2(cmd, args, {
|
|
791
924
|
detached: true,
|
|
@@ -800,7 +933,7 @@ function findHivemindOnPath() {
|
|
|
800
933
|
const PATH = process.env.PATH ?? "";
|
|
801
934
|
const dirs = PATH.split(":").filter(Boolean);
|
|
802
935
|
for (const dir of dirs) {
|
|
803
|
-
const candidate =
|
|
936
|
+
const candidate = join9(dir, "hivemind");
|
|
804
937
|
if (existsSync5(candidate))
|
|
805
938
|
return candidate;
|
|
806
939
|
}
|
|
@@ -808,41 +941,41 @@ function findHivemindOnPath() {
|
|
|
808
941
|
}
|
|
809
942
|
async function autoUpdate(creds, opts) {
|
|
810
943
|
const t0 = Date.now();
|
|
811
|
-
|
|
944
|
+
log4(`agent=${opts.agent} entered`);
|
|
812
945
|
if (!creds?.token) {
|
|
813
|
-
|
|
946
|
+
log4(`agent=${opts.agent} skip: no creds.token (${Date.now() - t0}ms)`);
|
|
814
947
|
return;
|
|
815
948
|
}
|
|
816
949
|
if (creds.autoupdate === false) {
|
|
817
|
-
|
|
950
|
+
log4(`agent=${opts.agent} skip: autoupdate=false (${Date.now() - t0}ms)`);
|
|
818
951
|
return;
|
|
819
952
|
}
|
|
820
953
|
const binaryPath = opts.hivemindBinaryPath !== void 0 ? opts.hivemindBinaryPath : findHivemindOnPath();
|
|
821
954
|
if (!binaryPath) {
|
|
822
|
-
|
|
955
|
+
log4(`agent=${opts.agent} skip: hivemind binary not on PATH (${Date.now() - t0}ms)`);
|
|
823
956
|
return;
|
|
824
957
|
}
|
|
825
|
-
|
|
958
|
+
log4(`agent=${opts.agent} binary=${binaryPath} \u2192 dispatching detached update`);
|
|
826
959
|
const spawnFn = opts.spawn ?? defaultSpawn;
|
|
827
960
|
let pid;
|
|
828
961
|
try {
|
|
829
962
|
pid = spawnFn(binaryPath, ["update"]).pid;
|
|
830
963
|
} catch (e) {
|
|
831
|
-
|
|
964
|
+
log4(`agent=${opts.agent} dispatch threw: ${e?.message ?? e} (${Date.now() - t0}ms)`);
|
|
832
965
|
return;
|
|
833
966
|
}
|
|
834
|
-
|
|
967
|
+
log4(`agent=${opts.agent} dispatched (pid=${pid ?? "?"}) (${Date.now() - t0}ms total)`);
|
|
835
968
|
}
|
|
836
969
|
|
|
837
970
|
// dist/src/skillify/pull.js
|
|
838
|
-
import { existsSync as existsSync10, readFileSync as
|
|
839
|
-
import { homedir as
|
|
840
|
-
import { dirname as dirname5, join as
|
|
971
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, renameSync as renameSync4, lstatSync as lstatSync2, readlinkSync, symlinkSync, unlinkSync as unlinkSync5 } from "node:fs";
|
|
972
|
+
import { homedir as homedir11 } from "node:os";
|
|
973
|
+
import { dirname as dirname5, join as join14 } from "node:path";
|
|
841
974
|
|
|
842
975
|
// dist/src/skillify/skill-writer.js
|
|
843
|
-
import { existsSync as existsSync6, mkdirSync as
|
|
844
|
-
import { homedir as
|
|
845
|
-
import { join as
|
|
976
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
977
|
+
import { homedir as homedir7 } from "node:os";
|
|
978
|
+
import { join as join10 } from "node:path";
|
|
846
979
|
function assertValidSkillName(name) {
|
|
847
980
|
if (typeof name !== "string" || name.length === 0) {
|
|
848
981
|
throw new Error(`invalid skill name: empty or non-string`);
|
|
@@ -908,29 +1041,29 @@ function parseFrontmatter(text) {
|
|
|
908
1041
|
}
|
|
909
1042
|
|
|
910
1043
|
// dist/src/skillify/manifest.js
|
|
911
|
-
import { existsSync as existsSync8, lstatSync, mkdirSync as
|
|
912
|
-
import { homedir as
|
|
913
|
-
import { dirname as dirname4, join as
|
|
1044
|
+
import { existsSync as existsSync8, lstatSync, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
1045
|
+
import { homedir as homedir9 } from "node:os";
|
|
1046
|
+
import { dirname as dirname4, join as join12 } from "node:path";
|
|
914
1047
|
|
|
915
1048
|
// dist/src/skillify/legacy-migration.js
|
|
916
|
-
import { existsSync as existsSync7, renameSync } from "node:fs";
|
|
917
|
-
import { homedir as
|
|
918
|
-
import { join as
|
|
1049
|
+
import { existsSync as existsSync7, renameSync as renameSync2 } from "node:fs";
|
|
1050
|
+
import { homedir as homedir8 } from "node:os";
|
|
1051
|
+
import { join as join11 } from "node:path";
|
|
919
1052
|
var dlog = (msg) => log("skillify-migrate", msg);
|
|
920
1053
|
var attempted = false;
|
|
921
1054
|
function migrateLegacyStateDir() {
|
|
922
1055
|
if (attempted)
|
|
923
1056
|
return;
|
|
924
1057
|
attempted = true;
|
|
925
|
-
const root =
|
|
926
|
-
const legacy =
|
|
927
|
-
const current =
|
|
1058
|
+
const root = join11(homedir8(), ".deeplake", "state");
|
|
1059
|
+
const legacy = join11(root, "skilify");
|
|
1060
|
+
const current = join11(root, "skillify");
|
|
928
1061
|
if (!existsSync7(legacy))
|
|
929
1062
|
return;
|
|
930
1063
|
if (existsSync7(current))
|
|
931
1064
|
return;
|
|
932
1065
|
try {
|
|
933
|
-
|
|
1066
|
+
renameSync2(legacy, current);
|
|
934
1067
|
dlog(`migrated ${legacy} -> ${current}`);
|
|
935
1068
|
} catch (err) {
|
|
936
1069
|
const code = err.code;
|
|
@@ -947,7 +1080,7 @@ function emptyManifest() {
|
|
|
947
1080
|
return { version: 1, entries: [] };
|
|
948
1081
|
}
|
|
949
1082
|
function manifestPath() {
|
|
950
|
-
return
|
|
1083
|
+
return join12(homedir9(), ".deeplake", "state", "skillify", "pulled.json");
|
|
951
1084
|
}
|
|
952
1085
|
function loadManifest(path = manifestPath()) {
|
|
953
1086
|
migrateLegacyStateDir();
|
|
@@ -955,7 +1088,7 @@ function loadManifest(path = manifestPath()) {
|
|
|
955
1088
|
return emptyManifest();
|
|
956
1089
|
let raw;
|
|
957
1090
|
try {
|
|
958
|
-
raw =
|
|
1091
|
+
raw = readFileSync8(path, "utf-8");
|
|
959
1092
|
} catch {
|
|
960
1093
|
return emptyManifest();
|
|
961
1094
|
}
|
|
@@ -1002,10 +1135,10 @@ function loadManifest(path = manifestPath()) {
|
|
|
1002
1135
|
}
|
|
1003
1136
|
function saveManifest(m, path = manifestPath()) {
|
|
1004
1137
|
migrateLegacyStateDir();
|
|
1005
|
-
|
|
1138
|
+
mkdirSync7(dirname4(path), { recursive: true });
|
|
1006
1139
|
const tmp = `${path}.tmp`;
|
|
1007
|
-
|
|
1008
|
-
|
|
1140
|
+
writeFileSync6(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
1141
|
+
renameSync3(tmp, path);
|
|
1009
1142
|
}
|
|
1010
1143
|
function recordPull(entry, path = manifestPath()) {
|
|
1011
1144
|
const m = loadManifest(path);
|
|
@@ -1030,7 +1163,7 @@ function unlinkSymlinks(paths) {
|
|
|
1030
1163
|
if (!st.isSymbolicLink())
|
|
1031
1164
|
continue;
|
|
1032
1165
|
try {
|
|
1033
|
-
|
|
1166
|
+
unlinkSync4(path);
|
|
1034
1167
|
} catch {
|
|
1035
1168
|
}
|
|
1036
1169
|
}
|
|
@@ -1040,7 +1173,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
1040
1173
|
const live = [];
|
|
1041
1174
|
let pruned = 0;
|
|
1042
1175
|
for (const e of m.entries) {
|
|
1043
|
-
if (existsSync8(
|
|
1176
|
+
if (existsSync8(join12(e.installRoot, e.dirName))) {
|
|
1044
1177
|
live.push(e);
|
|
1045
1178
|
continue;
|
|
1046
1179
|
}
|
|
@@ -1054,25 +1187,25 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
1054
1187
|
|
|
1055
1188
|
// dist/src/skillify/agent-roots.js
|
|
1056
1189
|
import { existsSync as existsSync9 } from "node:fs";
|
|
1057
|
-
import { homedir as
|
|
1058
|
-
import { join as
|
|
1190
|
+
import { homedir as homedir10 } from "node:os";
|
|
1191
|
+
import { join as join13 } from "node:path";
|
|
1059
1192
|
function resolveDetected(home) {
|
|
1060
1193
|
const out = [];
|
|
1061
|
-
const codexInstalled = existsSync9(
|
|
1062
|
-
const piInstalled = existsSync9(
|
|
1063
|
-
const hermesInstalled = existsSync9(
|
|
1194
|
+
const codexInstalled = existsSync9(join13(home, ".codex"));
|
|
1195
|
+
const piInstalled = existsSync9(join13(home, ".pi", "agent"));
|
|
1196
|
+
const hermesInstalled = existsSync9(join13(home, ".hermes"));
|
|
1064
1197
|
if (codexInstalled || piInstalled) {
|
|
1065
|
-
out.push(
|
|
1198
|
+
out.push(join13(home, ".agents", "skills"));
|
|
1066
1199
|
}
|
|
1067
1200
|
if (hermesInstalled) {
|
|
1068
|
-
out.push(
|
|
1201
|
+
out.push(join13(home, ".hermes", "skills"));
|
|
1069
1202
|
}
|
|
1070
1203
|
if (piInstalled) {
|
|
1071
|
-
out.push(
|
|
1204
|
+
out.push(join13(home, ".pi", "agent", "skills"));
|
|
1072
1205
|
}
|
|
1073
1206
|
return out;
|
|
1074
1207
|
}
|
|
1075
|
-
function detectAgentSkillsRoots(canonicalRoot, home =
|
|
1208
|
+
function detectAgentSkillsRoots(canonicalRoot, home = homedir10()) {
|
|
1076
1209
|
return resolveDetected(home).filter((p) => p !== canonicalRoot);
|
|
1077
1210
|
}
|
|
1078
1211
|
|
|
@@ -1116,15 +1249,15 @@ function isMissingTableError(message) {
|
|
|
1116
1249
|
}
|
|
1117
1250
|
function resolvePullDestination(install, cwd) {
|
|
1118
1251
|
if (install === "global")
|
|
1119
|
-
return
|
|
1252
|
+
return join14(homedir11(), ".claude", "skills");
|
|
1120
1253
|
if (!cwd)
|
|
1121
1254
|
throw new Error("install=project requires a cwd");
|
|
1122
|
-
return
|
|
1255
|
+
return join14(cwd, ".claude", "skills");
|
|
1123
1256
|
}
|
|
1124
1257
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
1125
1258
|
const out = [];
|
|
1126
1259
|
for (const root of agentRoots) {
|
|
1127
|
-
const link =
|
|
1260
|
+
const link = join14(root, dirName);
|
|
1128
1261
|
let existing;
|
|
1129
1262
|
try {
|
|
1130
1263
|
existing = lstatSync2(link);
|
|
@@ -1146,13 +1279,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
1146
1279
|
continue;
|
|
1147
1280
|
}
|
|
1148
1281
|
try {
|
|
1149
|
-
|
|
1282
|
+
unlinkSync5(link);
|
|
1150
1283
|
} catch {
|
|
1151
1284
|
continue;
|
|
1152
1285
|
}
|
|
1153
1286
|
}
|
|
1154
1287
|
try {
|
|
1155
|
-
|
|
1288
|
+
mkdirSync8(dirname5(link), { recursive: true });
|
|
1156
1289
|
symlinkSync(canonicalDir, link, "dir");
|
|
1157
1290
|
out.push(link);
|
|
1158
1291
|
} catch {
|
|
@@ -1167,7 +1300,7 @@ function backfillSymlinks(installRoot) {
|
|
|
1167
1300
|
return;
|
|
1168
1301
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
1169
1302
|
for (const entry of entries) {
|
|
1170
|
-
const canonical =
|
|
1303
|
+
const canonical = join14(entry.installRoot, entry.dirName);
|
|
1171
1304
|
if (!existsSync10(canonical))
|
|
1172
1305
|
continue;
|
|
1173
1306
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
@@ -1281,7 +1414,7 @@ function readLocalVersion(path) {
|
|
|
1281
1414
|
if (!existsSync10(path))
|
|
1282
1415
|
return null;
|
|
1283
1416
|
try {
|
|
1284
|
-
const text =
|
|
1417
|
+
const text = readFileSync9(path, "utf-8");
|
|
1285
1418
|
const parsed = parseFrontmatter(text);
|
|
1286
1419
|
if (!parsed)
|
|
1287
1420
|
return null;
|
|
@@ -1376,8 +1509,8 @@ async function runPull(opts) {
|
|
|
1376
1509
|
summary.skipped++;
|
|
1377
1510
|
continue;
|
|
1378
1511
|
}
|
|
1379
|
-
const skillDir =
|
|
1380
|
-
const skillFile =
|
|
1512
|
+
const skillDir = join14(root, dirName);
|
|
1513
|
+
const skillFile = join14(skillDir, "SKILL.md");
|
|
1381
1514
|
const remoteVersion = Number(row.version ?? 1);
|
|
1382
1515
|
const localVersion = readLocalVersion(skillFile);
|
|
1383
1516
|
const action = decideAction({
|
|
@@ -1388,14 +1521,14 @@ async function runPull(opts) {
|
|
|
1388
1521
|
});
|
|
1389
1522
|
let manifestError;
|
|
1390
1523
|
if (action === "wrote") {
|
|
1391
|
-
|
|
1524
|
+
mkdirSync8(skillDir, { recursive: true });
|
|
1392
1525
|
if (existsSync10(skillFile)) {
|
|
1393
1526
|
try {
|
|
1394
|
-
|
|
1527
|
+
renameSync4(skillFile, `${skillFile}.bak`);
|
|
1395
1528
|
} catch {
|
|
1396
1529
|
}
|
|
1397
1530
|
}
|
|
1398
|
-
|
|
1531
|
+
writeFileSync7(skillFile, renderSkillFile(row));
|
|
1399
1532
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
1400
1533
|
try {
|
|
1401
1534
|
recordPull({
|
|
@@ -1437,7 +1570,7 @@ async function runPull(opts) {
|
|
|
1437
1570
|
}
|
|
1438
1571
|
|
|
1439
1572
|
// dist/src/skillify/auto-pull.js
|
|
1440
|
-
var
|
|
1573
|
+
var log5 = (msg) => log("skillify-autopull", msg);
|
|
1441
1574
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1442
1575
|
function withTimeout(p, ms) {
|
|
1443
1576
|
let timer = null;
|
|
@@ -1453,13 +1586,13 @@ function withTimeout(p, ms) {
|
|
|
1453
1586
|
}
|
|
1454
1587
|
async function autoPullSkills(deps = {}) {
|
|
1455
1588
|
if (process.env.HIVEMIND_AUTOPULL_DISABLED === "1") {
|
|
1456
|
-
|
|
1589
|
+
log5("disabled via HIVEMIND_AUTOPULL_DISABLED=1");
|
|
1457
1590
|
return { pulled: 0, skipped: true, reason: "disabled" };
|
|
1458
1591
|
}
|
|
1459
1592
|
const loadFn = deps.loadConfigFn ?? loadConfig;
|
|
1460
1593
|
const config = loadFn();
|
|
1461
1594
|
if (!config) {
|
|
1462
|
-
|
|
1595
|
+
log5("skipped: not logged in");
|
|
1463
1596
|
return { pulled: 0, skipped: true, reason: "not-logged-in" };
|
|
1464
1597
|
}
|
|
1465
1598
|
let query;
|
|
@@ -1481,16 +1614,16 @@ async function autoPullSkills(deps = {}) {
|
|
|
1481
1614
|
dryRun: false,
|
|
1482
1615
|
force: false
|
|
1483
1616
|
}), timeoutMs);
|
|
1484
|
-
|
|
1617
|
+
log5(`pulled scanned=${summary.scanned} wrote=${summary.wrote} skipped=${summary.skipped}`);
|
|
1485
1618
|
return { pulled: summary.wrote, skipped: false };
|
|
1486
1619
|
} catch (e) {
|
|
1487
|
-
|
|
1620
|
+
log5(`pull failed (swallowed): ${e?.message ?? e}`);
|
|
1488
1621
|
return { pulled: 0, skipped: true, reason: "error" };
|
|
1489
1622
|
}
|
|
1490
1623
|
}
|
|
1491
1624
|
|
|
1492
1625
|
// dist/src/hooks/cursor/session-start.js
|
|
1493
|
-
var
|
|
1626
|
+
var log6 = (msg) => log("cursor-session-start", msg);
|
|
1494
1627
|
var __bundleDir = dirname6(fileURLToPath2(import.meta.url));
|
|
1495
1628
|
var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
|
|
1496
1629
|
|
|
@@ -1511,7 +1644,14 @@ Organization management \u2014 each argument is SEPARATE (do NOT quote subcomman
|
|
|
1511
1644
|
- hivemind remove <user-id> \u2014 remove member
|
|
1512
1645
|
|
|
1513
1646
|
SKILLS (skillify) \u2014 mine + share reusable skills across the org:
|
|
1514
|
-
${renderSkillifyCommands()}
|
|
1647
|
+
${renderSkillifyCommands()}
|
|
1648
|
+
|
|
1649
|
+
Embeddings (semantic memory search) \u2014 opt-in, persisted in ~/.deeplake/config.json:
|
|
1650
|
+
- hivemind embeddings install \u2014 download deps (~600MB), symlink agents, set enabled:true
|
|
1651
|
+
- hivemind embeddings enable \u2014 flip enabled:true (run install first if deps missing)
|
|
1652
|
+
- hivemind embeddings disable \u2014 flip enabled:false + SIGTERM daemon (deps stay on disk)
|
|
1653
|
+
- hivemind embeddings uninstall [--prune] \u2014 remove agent symlinks + disable; --prune wipes deps too
|
|
1654
|
+
- hivemind embeddings status \u2014 show config + deps + per-agent link state`;
|
|
1515
1655
|
function resolveSessionId(input) {
|
|
1516
1656
|
return input.session_id ?? input.conversation_id ?? `cursor-${Date.now()}`;
|
|
1517
1657
|
}
|
|
@@ -1549,11 +1689,11 @@ async function main() {
|
|
|
1549
1689
|
const cwd = resolveCwd(input);
|
|
1550
1690
|
const creds = loadCredentials();
|
|
1551
1691
|
if (!creds?.token) {
|
|
1552
|
-
|
|
1692
|
+
log6("no credentials found");
|
|
1553
1693
|
const auto = maybeAutoMineLocal();
|
|
1554
|
-
|
|
1694
|
+
log6(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
|
|
1555
1695
|
} else {
|
|
1556
|
-
|
|
1696
|
+
log6(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
|
|
1557
1697
|
}
|
|
1558
1698
|
await autoUpdate(creds, { agent: "cursor" });
|
|
1559
1699
|
const current = getInstalledVersion(__bundleDir, ".claude-plugin");
|
|
@@ -1569,14 +1709,14 @@ async function main() {
|
|
|
1569
1709
|
await api.ensureTable();
|
|
1570
1710
|
await api.ensureSessionsTable(sessionsTable);
|
|
1571
1711
|
await createPlaceholder(api, table, sessionId, cwd, config.userName, config.orgName, config.workspaceId, pluginVersion);
|
|
1572
|
-
|
|
1712
|
+
log6("placeholder created");
|
|
1573
1713
|
}
|
|
1574
1714
|
} catch (e) {
|
|
1575
|
-
|
|
1715
|
+
log6(`placeholder failed: ${e.message}`);
|
|
1576
1716
|
}
|
|
1577
1717
|
}
|
|
1578
1718
|
const pullResult = await autoPullSkills();
|
|
1579
|
-
|
|
1719
|
+
log6(`autopull: pulled=${pullResult.pulled} skipped=${pullResult.skipped}`);
|
|
1580
1720
|
let versionNotice = "";
|
|
1581
1721
|
if (current)
|
|
1582
1722
|
versionNotice = `
|
|
@@ -1590,6 +1730,6 @@ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`
|
|
|
1590
1730
|
console.log(JSON.stringify({ additional_context: additionalContext }));
|
|
1591
1731
|
}
|
|
1592
1732
|
main().catch((e) => {
|
|
1593
|
-
|
|
1733
|
+
log6(`fatal: ${e.message}`);
|
|
1594
1734
|
process.exit(0);
|
|
1595
1735
|
});
|