@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 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({
|
|
@@ -54,7 +54,7 @@ var init_index_marker_store = __esm({
|
|
|
54
54
|
|
|
55
55
|
// dist/src/hooks/cursor/session-start.js
|
|
56
56
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
57
|
-
import { dirname as
|
|
57
|
+
import { dirname as dirname7 } from "node:path";
|
|
58
58
|
|
|
59
59
|
// dist/src/commands/auth.js
|
|
60
60
|
import { execSync } from "node:child_process";
|
|
@@ -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
|
|
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";
|
|
839
972
|
import { homedir as homedir10 } from "node:os";
|
|
840
|
-
import { dirname as
|
|
973
|
+
import { dirname as dirname6, join as join15 } 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,34 +1041,43 @@ function parseFrontmatter(text) {
|
|
|
908
1041
|
}
|
|
909
1042
|
|
|
910
1043
|
// dist/src/skillify/manifest.js
|
|
911
|
-
import { existsSync as existsSync8, lstatSync, mkdirSync 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 { dirname as dirname5, join as join13 } from "node:path";
|
|
1046
|
+
|
|
1047
|
+
// dist/src/skillify/legacy-migration.js
|
|
1048
|
+
import { existsSync as existsSync7, renameSync as renameSync2 } from "node:fs";
|
|
1049
|
+
import { dirname as dirname4, join as join12 } from "node:path";
|
|
1050
|
+
|
|
1051
|
+
// dist/src/skillify/state-dir.js
|
|
912
1052
|
import { homedir as homedir8 } from "node:os";
|
|
913
|
-
import {
|
|
1053
|
+
import { join as join11 } from "node:path";
|
|
1054
|
+
function getStateDir() {
|
|
1055
|
+
const override = process.env.HIVEMIND_STATE_DIR?.trim();
|
|
1056
|
+
return override && override.length > 0 ? override : join11(homedir8(), ".deeplake", "state", "skillify");
|
|
1057
|
+
}
|
|
914
1058
|
|
|
915
1059
|
// dist/src/skillify/legacy-migration.js
|
|
916
|
-
import { existsSync as existsSync7, renameSync } from "node:fs";
|
|
917
|
-
import { homedir as homedir7 } from "node:os";
|
|
918
|
-
import { join as join10 } from "node:path";
|
|
919
1060
|
var dlog = (msg) => log("skillify-migrate", msg);
|
|
920
1061
|
var attempted = false;
|
|
921
1062
|
function migrateLegacyStateDir() {
|
|
1063
|
+
if (process.env.HIVEMIND_STATE_DIR?.trim())
|
|
1064
|
+
return;
|
|
922
1065
|
if (attempted)
|
|
923
1066
|
return;
|
|
924
1067
|
attempted = true;
|
|
925
|
-
const
|
|
926
|
-
const legacy =
|
|
927
|
-
const current = join10(root, "skillify");
|
|
1068
|
+
const current = getStateDir();
|
|
1069
|
+
const legacy = join12(dirname4(current), "skilify");
|
|
928
1070
|
if (!existsSync7(legacy))
|
|
929
1071
|
return;
|
|
930
1072
|
if (existsSync7(current))
|
|
931
1073
|
return;
|
|
932
1074
|
try {
|
|
933
|
-
|
|
1075
|
+
renameSync2(legacy, current);
|
|
934
1076
|
dlog(`migrated ${legacy} -> ${current}`);
|
|
935
1077
|
} catch (err) {
|
|
936
1078
|
const code = err.code;
|
|
937
|
-
if (code === "EXDEV" || code === "EPERM") {
|
|
938
|
-
dlog(`migration
|
|
1079
|
+
if (code === "EXDEV" || code === "EPERM" || code === "ENOENT" || code === "EEXIST" || code === "ENOTEMPTY") {
|
|
1080
|
+
dlog(`migration skipped (${code}); legacy dir left as-is or another process handled it`);
|
|
939
1081
|
return;
|
|
940
1082
|
}
|
|
941
1083
|
throw err;
|
|
@@ -947,7 +1089,7 @@ function emptyManifest() {
|
|
|
947
1089
|
return { version: 1, entries: [] };
|
|
948
1090
|
}
|
|
949
1091
|
function manifestPath() {
|
|
950
|
-
return
|
|
1092
|
+
return join13(getStateDir(), "pulled.json");
|
|
951
1093
|
}
|
|
952
1094
|
function loadManifest(path = manifestPath()) {
|
|
953
1095
|
migrateLegacyStateDir();
|
|
@@ -955,7 +1097,7 @@ function loadManifest(path = manifestPath()) {
|
|
|
955
1097
|
return emptyManifest();
|
|
956
1098
|
let raw;
|
|
957
1099
|
try {
|
|
958
|
-
raw =
|
|
1100
|
+
raw = readFileSync8(path, "utf-8");
|
|
959
1101
|
} catch {
|
|
960
1102
|
return emptyManifest();
|
|
961
1103
|
}
|
|
@@ -1002,10 +1144,10 @@ function loadManifest(path = manifestPath()) {
|
|
|
1002
1144
|
}
|
|
1003
1145
|
function saveManifest(m, path = manifestPath()) {
|
|
1004
1146
|
migrateLegacyStateDir();
|
|
1005
|
-
|
|
1147
|
+
mkdirSync7(dirname5(path), { recursive: true });
|
|
1006
1148
|
const tmp = `${path}.tmp`;
|
|
1007
|
-
|
|
1008
|
-
|
|
1149
|
+
writeFileSync6(tmp, JSON.stringify(m, null, 2) + "\n", { mode: 384 });
|
|
1150
|
+
renameSync3(tmp, path);
|
|
1009
1151
|
}
|
|
1010
1152
|
function recordPull(entry, path = manifestPath()) {
|
|
1011
1153
|
const m = loadManifest(path);
|
|
@@ -1030,7 +1172,7 @@ function unlinkSymlinks(paths) {
|
|
|
1030
1172
|
if (!st.isSymbolicLink())
|
|
1031
1173
|
continue;
|
|
1032
1174
|
try {
|
|
1033
|
-
|
|
1175
|
+
unlinkSync4(path);
|
|
1034
1176
|
} catch {
|
|
1035
1177
|
}
|
|
1036
1178
|
}
|
|
@@ -1040,7 +1182,7 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
1040
1182
|
const live = [];
|
|
1041
1183
|
let pruned = 0;
|
|
1042
1184
|
for (const e of m.entries) {
|
|
1043
|
-
if (existsSync8(
|
|
1185
|
+
if (existsSync8(join13(e.installRoot, e.dirName))) {
|
|
1044
1186
|
live.push(e);
|
|
1045
1187
|
continue;
|
|
1046
1188
|
}
|
|
@@ -1055,20 +1197,20 @@ function pruneOrphanedEntries(path = manifestPath()) {
|
|
|
1055
1197
|
// dist/src/skillify/agent-roots.js
|
|
1056
1198
|
import { existsSync as existsSync9 } from "node:fs";
|
|
1057
1199
|
import { homedir as homedir9 } from "node:os";
|
|
1058
|
-
import { join as
|
|
1200
|
+
import { join as join14 } from "node:path";
|
|
1059
1201
|
function resolveDetected(home) {
|
|
1060
1202
|
const out = [];
|
|
1061
|
-
const codexInstalled = existsSync9(
|
|
1062
|
-
const piInstalled = existsSync9(
|
|
1063
|
-
const hermesInstalled = existsSync9(
|
|
1203
|
+
const codexInstalled = existsSync9(join14(home, ".codex"));
|
|
1204
|
+
const piInstalled = existsSync9(join14(home, ".pi", "agent"));
|
|
1205
|
+
const hermesInstalled = existsSync9(join14(home, ".hermes"));
|
|
1064
1206
|
if (codexInstalled || piInstalled) {
|
|
1065
|
-
out.push(
|
|
1207
|
+
out.push(join14(home, ".agents", "skills"));
|
|
1066
1208
|
}
|
|
1067
1209
|
if (hermesInstalled) {
|
|
1068
|
-
out.push(
|
|
1210
|
+
out.push(join14(home, ".hermes", "skills"));
|
|
1069
1211
|
}
|
|
1070
1212
|
if (piInstalled) {
|
|
1071
|
-
out.push(
|
|
1213
|
+
out.push(join14(home, ".pi", "agent", "skills"));
|
|
1072
1214
|
}
|
|
1073
1215
|
return out;
|
|
1074
1216
|
}
|
|
@@ -1116,15 +1258,15 @@ function isMissingTableError(message) {
|
|
|
1116
1258
|
}
|
|
1117
1259
|
function resolvePullDestination(install, cwd) {
|
|
1118
1260
|
if (install === "global")
|
|
1119
|
-
return
|
|
1261
|
+
return join15(homedir10(), ".claude", "skills");
|
|
1120
1262
|
if (!cwd)
|
|
1121
1263
|
throw new Error("install=project requires a cwd");
|
|
1122
|
-
return
|
|
1264
|
+
return join15(cwd, ".claude", "skills");
|
|
1123
1265
|
}
|
|
1124
1266
|
function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
1125
1267
|
const out = [];
|
|
1126
1268
|
for (const root of agentRoots) {
|
|
1127
|
-
const link =
|
|
1269
|
+
const link = join15(root, dirName);
|
|
1128
1270
|
let existing;
|
|
1129
1271
|
try {
|
|
1130
1272
|
existing = lstatSync2(link);
|
|
@@ -1146,13 +1288,13 @@ function fanOutSymlinks(canonicalDir, dirName, agentRoots) {
|
|
|
1146
1288
|
continue;
|
|
1147
1289
|
}
|
|
1148
1290
|
try {
|
|
1149
|
-
|
|
1291
|
+
unlinkSync5(link);
|
|
1150
1292
|
} catch {
|
|
1151
1293
|
continue;
|
|
1152
1294
|
}
|
|
1153
1295
|
}
|
|
1154
1296
|
try {
|
|
1155
|
-
|
|
1297
|
+
mkdirSync8(dirname6(link), { recursive: true });
|
|
1156
1298
|
symlinkSync(canonicalDir, link, "dir");
|
|
1157
1299
|
out.push(link);
|
|
1158
1300
|
} catch {
|
|
@@ -1167,7 +1309,7 @@ function backfillSymlinks(installRoot) {
|
|
|
1167
1309
|
return;
|
|
1168
1310
|
const detected = detectAgentSkillsRoots(installRoot);
|
|
1169
1311
|
for (const entry of entries) {
|
|
1170
|
-
const canonical =
|
|
1312
|
+
const canonical = join15(entry.installRoot, entry.dirName);
|
|
1171
1313
|
if (!existsSync10(canonical))
|
|
1172
1314
|
continue;
|
|
1173
1315
|
const fresh = fanOutSymlinks(canonical, entry.dirName, detected);
|
|
@@ -1281,7 +1423,7 @@ function readLocalVersion(path) {
|
|
|
1281
1423
|
if (!existsSync10(path))
|
|
1282
1424
|
return null;
|
|
1283
1425
|
try {
|
|
1284
|
-
const text =
|
|
1426
|
+
const text = readFileSync9(path, "utf-8");
|
|
1285
1427
|
const parsed = parseFrontmatter(text);
|
|
1286
1428
|
if (!parsed)
|
|
1287
1429
|
return null;
|
|
@@ -1376,8 +1518,8 @@ async function runPull(opts) {
|
|
|
1376
1518
|
summary.skipped++;
|
|
1377
1519
|
continue;
|
|
1378
1520
|
}
|
|
1379
|
-
const skillDir =
|
|
1380
|
-
const skillFile =
|
|
1521
|
+
const skillDir = join15(root, dirName);
|
|
1522
|
+
const skillFile = join15(skillDir, "SKILL.md");
|
|
1381
1523
|
const remoteVersion = Number(row.version ?? 1);
|
|
1382
1524
|
const localVersion = readLocalVersion(skillFile);
|
|
1383
1525
|
const action = decideAction({
|
|
@@ -1388,14 +1530,14 @@ async function runPull(opts) {
|
|
|
1388
1530
|
});
|
|
1389
1531
|
let manifestError;
|
|
1390
1532
|
if (action === "wrote") {
|
|
1391
|
-
|
|
1533
|
+
mkdirSync8(skillDir, { recursive: true });
|
|
1392
1534
|
if (existsSync10(skillFile)) {
|
|
1393
1535
|
try {
|
|
1394
|
-
|
|
1536
|
+
renameSync4(skillFile, `${skillFile}.bak`);
|
|
1395
1537
|
} catch {
|
|
1396
1538
|
}
|
|
1397
1539
|
}
|
|
1398
|
-
|
|
1540
|
+
writeFileSync7(skillFile, renderSkillFile(row));
|
|
1399
1541
|
const symlinks = opts.install === "global" ? fanOutSymlinks(skillDir, dirName, detectAgentSkillsRoots(root)) : [];
|
|
1400
1542
|
try {
|
|
1401
1543
|
recordPull({
|
|
@@ -1437,7 +1579,7 @@ async function runPull(opts) {
|
|
|
1437
1579
|
}
|
|
1438
1580
|
|
|
1439
1581
|
// dist/src/skillify/auto-pull.js
|
|
1440
|
-
var
|
|
1582
|
+
var log5 = (msg) => log("skillify-autopull", msg);
|
|
1441
1583
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
1442
1584
|
function withTimeout(p, ms) {
|
|
1443
1585
|
let timer = null;
|
|
@@ -1453,13 +1595,13 @@ function withTimeout(p, ms) {
|
|
|
1453
1595
|
}
|
|
1454
1596
|
async function autoPullSkills(deps = {}) {
|
|
1455
1597
|
if (process.env.HIVEMIND_AUTOPULL_DISABLED === "1") {
|
|
1456
|
-
|
|
1598
|
+
log5("disabled via HIVEMIND_AUTOPULL_DISABLED=1");
|
|
1457
1599
|
return { pulled: 0, skipped: true, reason: "disabled" };
|
|
1458
1600
|
}
|
|
1459
1601
|
const loadFn = deps.loadConfigFn ?? loadConfig;
|
|
1460
1602
|
const config = loadFn();
|
|
1461
1603
|
if (!config) {
|
|
1462
|
-
|
|
1604
|
+
log5("skipped: not logged in");
|
|
1463
1605
|
return { pulled: 0, skipped: true, reason: "not-logged-in" };
|
|
1464
1606
|
}
|
|
1465
1607
|
let query;
|
|
@@ -1481,17 +1623,17 @@ async function autoPullSkills(deps = {}) {
|
|
|
1481
1623
|
dryRun: false,
|
|
1482
1624
|
force: false
|
|
1483
1625
|
}), timeoutMs);
|
|
1484
|
-
|
|
1626
|
+
log5(`pulled scanned=${summary.scanned} wrote=${summary.wrote} skipped=${summary.skipped}`);
|
|
1485
1627
|
return { pulled: summary.wrote, skipped: false };
|
|
1486
1628
|
} catch (e) {
|
|
1487
|
-
|
|
1629
|
+
log5(`pull failed (swallowed): ${e?.message ?? e}`);
|
|
1488
1630
|
return { pulled: 0, skipped: true, reason: "error" };
|
|
1489
1631
|
}
|
|
1490
1632
|
}
|
|
1491
1633
|
|
|
1492
1634
|
// dist/src/hooks/cursor/session-start.js
|
|
1493
|
-
var
|
|
1494
|
-
var __bundleDir =
|
|
1635
|
+
var log6 = (msg) => log("cursor-session-start", msg);
|
|
1636
|
+
var __bundleDir = dirname7(fileURLToPath2(import.meta.url));
|
|
1495
1637
|
var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
|
|
1496
1638
|
|
|
1497
1639
|
Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
|
|
@@ -1556,11 +1698,11 @@ async function main() {
|
|
|
1556
1698
|
const cwd = resolveCwd(input);
|
|
1557
1699
|
const creds = loadCredentials();
|
|
1558
1700
|
if (!creds?.token) {
|
|
1559
|
-
|
|
1701
|
+
log6("no credentials found");
|
|
1560
1702
|
const auto = maybeAutoMineLocal();
|
|
1561
|
-
|
|
1703
|
+
log6(`auto-mine: ${auto.triggered ? "triggered (background)" : `skipped (${auto.reason})`}`);
|
|
1562
1704
|
} else {
|
|
1563
|
-
|
|
1705
|
+
log6(`credentials loaded: org=${creds.orgName ?? creds.orgId}`);
|
|
1564
1706
|
}
|
|
1565
1707
|
await autoUpdate(creds, { agent: "cursor" });
|
|
1566
1708
|
const current = getInstalledVersion(__bundleDir, ".claude-plugin");
|
|
@@ -1576,14 +1718,14 @@ async function main() {
|
|
|
1576
1718
|
await api.ensureTable();
|
|
1577
1719
|
await api.ensureSessionsTable(sessionsTable);
|
|
1578
1720
|
await createPlaceholder(api, table, sessionId, cwd, config.userName, config.orgName, config.workspaceId, pluginVersion);
|
|
1579
|
-
|
|
1721
|
+
log6("placeholder created");
|
|
1580
1722
|
}
|
|
1581
1723
|
} catch (e) {
|
|
1582
|
-
|
|
1724
|
+
log6(`placeholder failed: ${e.message}`);
|
|
1583
1725
|
}
|
|
1584
1726
|
}
|
|
1585
1727
|
const pullResult = await autoPullSkills();
|
|
1586
|
-
|
|
1728
|
+
log6(`autopull: pulled=${pullResult.pulled} skipped=${pullResult.skipped}`);
|
|
1587
1729
|
let versionNotice = "";
|
|
1588
1730
|
if (current)
|
|
1589
1731
|
versionNotice = `
|
|
@@ -1597,6 +1739,6 @@ Not logged in to Deeplake. Run: hivemind login${localMinedNote}${versionNotice}`
|
|
|
1597
1739
|
console.log(JSON.stringify({ additional_context: additionalContext }));
|
|
1598
1740
|
}
|
|
1599
1741
|
main().catch((e) => {
|
|
1600
|
-
|
|
1742
|
+
log6(`fatal: ${e.message}`);
|
|
1601
1743
|
process.exit(0);
|
|
1602
1744
|
});
|