@deeplake/hivemind 0.6.48 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +147 -20
  4. package/bundle/cli.js +552 -95
  5. package/codex/bundle/capture.js +509 -89
  6. package/codex/bundle/commands/auth-login.js +209 -66
  7. package/codex/bundle/embeddings/embed-daemon.js +243 -0
  8. package/codex/bundle/pre-tool-use.js +629 -104
  9. package/codex/bundle/session-start-setup.js +194 -57
  10. package/codex/bundle/session-start.js +25 -10
  11. package/codex/bundle/shell/deeplake-shell.js +679 -112
  12. package/codex/bundle/stop.js +476 -58
  13. package/codex/bundle/wiki-worker.js +312 -11
  14. package/cursor/bundle/capture.js +768 -57
  15. package/cursor/bundle/commands/auth-login.js +209 -66
  16. package/cursor/bundle/embeddings/embed-daemon.js +243 -0
  17. package/cursor/bundle/pre-tool-use.js +561 -70
  18. package/cursor/bundle/session-end.js +223 -2
  19. package/cursor/bundle/session-start.js +192 -54
  20. package/cursor/bundle/shell/deeplake-shell.js +679 -112
  21. package/cursor/bundle/wiki-worker.js +571 -0
  22. package/hermes/bundle/capture.js +771 -58
  23. package/hermes/bundle/commands/auth-login.js +209 -66
  24. package/hermes/bundle/embeddings/embed-daemon.js +243 -0
  25. package/hermes/bundle/pre-tool-use.js +560 -69
  26. package/hermes/bundle/session-end.js +224 -1
  27. package/hermes/bundle/session-start.js +195 -54
  28. package/hermes/bundle/shell/deeplake-shell.js +679 -112
  29. package/hermes/bundle/wiki-worker.js +572 -0
  30. package/mcp/bundle/server.js +253 -68
  31. package/openclaw/dist/chunks/auth-creds-AEKS6D3P.js +14 -0
  32. package/openclaw/dist/chunks/chunk-SRCBBT4H.js +37 -0
  33. package/openclaw/dist/chunks/config-G23NI5TV.js +33 -0
  34. package/openclaw/dist/chunks/index-marker-store-PGT5CW6T.js +33 -0
  35. package/openclaw/dist/chunks/setup-config-C35UK4LP.js +114 -0
  36. package/openclaw/dist/index.js +752 -702
  37. package/openclaw/openclaw.plugin.json +1 -1
  38. package/openclaw/package.json +1 -1
  39. package/package.json +2 -1
  40. package/pi/extension-source/hivemind.ts +473 -21
@@ -1,4 +1,56 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // dist/src/index-marker-store.js
13
+ var index_marker_store_exports = {};
14
+ __export(index_marker_store_exports, {
15
+ buildIndexMarkerPath: () => buildIndexMarkerPath,
16
+ getIndexMarkerDir: () => getIndexMarkerDir,
17
+ hasFreshIndexMarker: () => hasFreshIndexMarker,
18
+ writeIndexMarker: () => writeIndexMarker
19
+ });
20
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
21
+ import { join as join4 } from "node:path";
22
+ import { tmpdir } from "node:os";
23
+ function getIndexMarkerDir() {
24
+ return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join4(tmpdir(), "hivemind-deeplake-indexes");
25
+ }
26
+ function buildIndexMarkerPath(workspaceId, orgId, table, suffix) {
27
+ const markerKey = [workspaceId, orgId, table, suffix].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
28
+ return join4(getIndexMarkerDir(), `${markerKey}.json`);
29
+ }
30
+ function hasFreshIndexMarker(markerPath) {
31
+ if (!existsSync2(markerPath))
32
+ return false;
33
+ try {
34
+ const raw = JSON.parse(readFileSync3(markerPath, "utf-8"));
35
+ const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
36
+ if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
37
+ return false;
38
+ return true;
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ function writeIndexMarker(markerPath) {
44
+ mkdirSync2(getIndexMarkerDir(), { recursive: true });
45
+ writeFileSync2(markerPath, JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
46
+ }
47
+ var INDEX_MARKER_TTL_MS;
48
+ var init_index_marker_store = __esm({
49
+ "dist/src/index-marker-store.js"() {
50
+ "use strict";
51
+ INDEX_MARKER_TTL_MS = Number(process.env.HIVEMIND_INDEX_MARKER_TTL_MS ?? 6 * 60 * 6e4);
52
+ }
53
+ });
2
54
 
3
55
  // dist/src/hooks/codex/session-start-setup.js
4
56
  import { fileURLToPath } from "node:url";
@@ -7,36 +59,48 @@ import { execSync as execSync2 } from "node:child_process";
7
59
  import { homedir as homedir4 } from "node:os";
8
60
 
9
61
  // dist/src/commands/auth.js
10
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
62
+ import { execSync } from "node:child_process";
63
+
64
+ // dist/src/utils/client-header.js
65
+ var DEEPLAKE_CLIENT_HEADER = "X-Deeplake-Client";
66
+ function deeplakeClientValue() {
67
+ return "hivemind";
68
+ }
69
+ function deeplakeClientHeader() {
70
+ return { [DEEPLAKE_CLIENT_HEADER]: deeplakeClientValue() };
71
+ }
72
+
73
+ // dist/src/commands/auth-creds.js
74
+ import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs";
11
75
  import { join } from "node:path";
12
76
  import { homedir } from "node:os";
13
- import { execSync } from "node:child_process";
14
- var CONFIG_DIR = join(homedir(), ".deeplake");
15
- var CREDS_PATH = join(CONFIG_DIR, "credentials.json");
77
+ function configDir() {
78
+ return join(homedir(), ".deeplake");
79
+ }
80
+ function credsPath() {
81
+ return join(configDir(), "credentials.json");
82
+ }
16
83
  function loadCredentials() {
17
- if (!existsSync(CREDS_PATH))
18
- return null;
19
84
  try {
20
- return JSON.parse(readFileSync(CREDS_PATH, "utf-8"));
85
+ return JSON.parse(readFileSync(credsPath(), "utf-8"));
21
86
  } catch {
22
87
  return null;
23
88
  }
24
89
  }
25
90
  function saveCredentials(creds) {
26
- if (!existsSync(CONFIG_DIR))
27
- mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
28
- writeFileSync(CREDS_PATH, JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
91
+ mkdirSync(configDir(), { recursive: true, mode: 448 });
92
+ writeFileSync(credsPath(), JSON.stringify({ ...creds, savedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), { mode: 384 });
29
93
  }
30
94
 
31
95
  // dist/src/config.js
32
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
96
+ import { readFileSync as readFileSync2, existsSync } from "node:fs";
33
97
  import { join as join2 } from "node:path";
34
98
  import { homedir as homedir2, userInfo } from "node:os";
35
99
  function loadConfig() {
36
100
  const home = homedir2();
37
101
  const credPath = join2(home, ".deeplake", "credentials.json");
38
102
  let creds = null;
39
- if (existsSync2(credPath)) {
103
+ if (existsSync(credPath)) {
40
104
  try {
41
105
  creds = JSON.parse(readFileSync2(credPath, "utf-8"));
42
106
  } catch {
@@ -62,9 +126,6 @@ function loadConfig() {
62
126
 
63
127
  // dist/src/deeplake-api.js
64
128
  import { randomUUID } from "node:crypto";
65
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
66
- import { join as join4 } from "node:path";
67
- import { tmpdir } from "node:os";
68
129
 
69
130
  // dist/src/utils/debug.js
70
131
  import { appendFileSync } from "node:fs";
@@ -87,7 +148,17 @@ function sqlStr(value) {
87
148
  return value.replace(/\\/g, "\\\\").replace(/'/g, "''").replace(/\0/g, "").replace(/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
88
149
  }
89
150
 
151
+ // dist/src/embeddings/columns.js
152
+ var SUMMARY_EMBEDDING_COL = "summary_embedding";
153
+ var MESSAGE_EMBEDDING_COL = "message_embedding";
154
+
90
155
  // dist/src/deeplake-api.js
156
+ var indexMarkerStorePromise = null;
157
+ function getIndexMarkerStore() {
158
+ if (!indexMarkerStorePromise)
159
+ indexMarkerStorePromise = Promise.resolve().then(() => (init_index_marker_store(), index_marker_store_exports));
160
+ return indexMarkerStorePromise;
161
+ }
91
162
  var log2 = (msg) => log("sdk", msg);
92
163
  function summarizeSql(sql, maxLen = 220) {
93
164
  const compact = sql.replace(/\s+/g, " ").trim();
@@ -107,7 +178,6 @@ var MAX_RETRIES = 3;
107
178
  var BASE_DELAY_MS = 500;
108
179
  var MAX_CONCURRENCY = 5;
109
180
  var QUERY_TIMEOUT_MS = Number(process.env.HIVEMIND_QUERY_TIMEOUT_MS ?? 1e4);
110
- var INDEX_MARKER_TTL_MS = Number(process.env.HIVEMIND_INDEX_MARKER_TTL_MS ?? 6 * 60 * 6e4);
111
181
  function sleep(ms) {
112
182
  return new Promise((resolve) => setTimeout(resolve, ms));
113
183
  }
@@ -127,9 +197,6 @@ function isTransientHtml403(text) {
127
197
  const body = text.toLowerCase();
128
198
  return body.includes("<html") || body.includes("403 forbidden") || body.includes("cloudflare") || body.includes("nginx");
129
199
  }
130
- function getIndexMarkerDir() {
131
- return process.env.HIVEMIND_INDEX_MARKER_DIR ?? join4(tmpdir(), "hivemind-deeplake-indexes");
132
- }
133
200
  var Semaphore = class {
134
201
  max;
135
202
  waiting = [];
@@ -198,7 +265,8 @@ var DeeplakeApi = class {
198
265
  headers: {
199
266
  Authorization: `Bearer ${this.token}`,
200
267
  "Content-Type": "application/json",
201
- "X-Activeloop-Org-Id": this.orgId
268
+ "X-Activeloop-Org-Id": this.orgId,
269
+ ...deeplakeClientHeader()
202
270
  },
203
271
  signal,
204
272
  body: JSON.stringify({ query: sql })
@@ -225,7 +293,8 @@ var DeeplakeApi = class {
225
293
  }
226
294
  const text = await resp.text().catch(() => "");
227
295
  const retryable403 = isSessionInsertQuery(sql) && (resp.status === 401 || resp.status === 403 && (text.length === 0 || isTransientHtml403(text)));
228
- if (attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
296
+ const alreadyExists = resp.status === 500 && isDuplicateIndexError(text);
297
+ if (!alreadyExists && attempt < MAX_RETRIES && (RETRYABLE_CODES.has(resp.status) || retryable403)) {
229
298
  const delay = BASE_DELAY_MS * Math.pow(2, attempt) + Math.random() * 200;
230
299
  log2(`query retry ${attempt + 1}/${MAX_RETRIES} (${resp.status}) in ${delay.toFixed(0)}ms`);
231
300
  await sleep(delay);
@@ -259,7 +328,7 @@ var DeeplakeApi = class {
259
328
  const lud = row.lastUpdateDate ?? ts;
260
329
  const exists = await this.query(`SELECT path FROM "${this.tableName}" WHERE path = '${sqlStr(row.path)}' LIMIT 1`);
261
330
  if (exists.length > 0) {
262
- let setClauses = `summary = E'${sqlStr(row.contentText)}', mime_type = '${sqlStr(row.mimeType)}', size_bytes = ${row.sizeBytes}, last_update_date = '${lud}'`;
331
+ let setClauses = `summary = E'${sqlStr(row.contentText)}', ${SUMMARY_EMBEDDING_COL} = NULL, mime_type = '${sqlStr(row.mimeType)}', size_bytes = ${row.sizeBytes}, last_update_date = '${lud}'`;
263
332
  if (row.project !== void 0)
264
333
  setClauses += `, project = '${sqlStr(row.project)}'`;
265
334
  if (row.description !== void 0)
@@ -267,8 +336,8 @@ var DeeplakeApi = class {
267
336
  await this.query(`UPDATE "${this.tableName}" SET ${setClauses} WHERE path = '${sqlStr(row.path)}'`);
268
337
  } else {
269
338
  const id = randomUUID();
270
- let cols = "id, path, filename, summary, mime_type, size_bytes, creation_date, last_update_date";
271
- let vals = `'${id}', '${sqlStr(row.path)}', '${sqlStr(row.filename)}', E'${sqlStr(row.contentText)}', '${sqlStr(row.mimeType)}', ${row.sizeBytes}, '${cd}', '${lud}'`;
339
+ let cols = `id, path, filename, summary, ${SUMMARY_EMBEDDING_COL}, mime_type, size_bytes, creation_date, last_update_date`;
340
+ let vals = `'${id}', '${sqlStr(row.path)}', '${sqlStr(row.filename)}', E'${sqlStr(row.contentText)}', NULL, '${sqlStr(row.mimeType)}', ${row.sizeBytes}, '${cd}', '${lud}'`;
272
341
  if (row.project !== void 0) {
273
342
  cols += ", project";
274
343
  vals += `, '${sqlStr(row.project)}'`;
@@ -293,48 +362,83 @@ var DeeplakeApi = class {
293
362
  buildLookupIndexName(table, suffix) {
294
363
  return `idx_${table}_${suffix}`.replace(/[^a-zA-Z0-9_]/g, "_");
295
364
  }
296
- getLookupIndexMarkerPath(table, suffix) {
297
- const markerKey = [
298
- this.workspaceId,
299
- this.orgId,
300
- table,
301
- suffix
302
- ].join("__").replace(/[^a-zA-Z0-9_.-]/g, "_");
303
- return join4(getIndexMarkerDir(), `${markerKey}.json`);
304
- }
305
- hasFreshLookupIndexMarker(table, suffix) {
306
- const markerPath = this.getLookupIndexMarkerPath(table, suffix);
307
- if (!existsSync3(markerPath))
308
- return false;
309
- try {
310
- const raw = JSON.parse(readFileSync3(markerPath, "utf-8"));
311
- const updatedAt = raw.updatedAt ? new Date(raw.updatedAt).getTime() : NaN;
312
- if (!Number.isFinite(updatedAt) || Date.now() - updatedAt > INDEX_MARKER_TTL_MS)
313
- return false;
314
- return true;
315
- } catch {
316
- return false;
317
- }
318
- }
319
- markLookupIndexReady(table, suffix) {
320
- mkdirSync2(getIndexMarkerDir(), { recursive: true });
321
- writeFileSync2(this.getLookupIndexMarkerPath(table, suffix), JSON.stringify({ updatedAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf-8");
322
- }
323
365
  async ensureLookupIndex(table, suffix, columnsSql) {
324
- if (this.hasFreshLookupIndexMarker(table, suffix))
366
+ const markers = await getIndexMarkerStore();
367
+ const markerPath = markers.buildIndexMarkerPath(this.workspaceId, this.orgId, table, suffix);
368
+ if (markers.hasFreshIndexMarker(markerPath))
325
369
  return;
326
370
  const indexName = this.buildLookupIndexName(table, suffix);
327
371
  try {
328
372
  await this.query(`CREATE INDEX IF NOT EXISTS "${indexName}" ON "${table}" ${columnsSql}`);
329
- this.markLookupIndexReady(table, suffix);
373
+ markers.writeIndexMarker(markerPath);
330
374
  } catch (e) {
331
375
  if (isDuplicateIndexError(e)) {
332
- this.markLookupIndexReady(table, suffix);
376
+ markers.writeIndexMarker(markerPath);
333
377
  return;
334
378
  }
335
379
  log2(`index "${indexName}" skipped: ${e.message}`);
336
380
  }
337
381
  }
382
+ /**
383
+ * Ensure a vector column exists on the given table.
384
+ *
385
+ * The previous implementation always issued `ALTER TABLE ADD COLUMN IF NOT
386
+ * EXISTS …` on every SessionStart. On a long-running workspace that's
387
+ * already migrated, every call returns 500 "Column already exists" — noisy
388
+ * in the log and a wasted round-trip. Worse, the very first call after the
389
+ * column is genuinely added triggers Deeplake's post-ALTER `vector::at`
390
+ * window (~30s) during which subsequent INSERTs fail; minimising the
391
+ * number of ALTER calls minimises exposure to that window.
392
+ *
393
+ * New flow:
394
+ * 1. Check the local marker file (mirrors ensureLookupIndex). If fresh,
395
+ * return — zero network calls.
396
+ * 2. SELECT 1 FROM information_schema.columns WHERE table_name = T AND
397
+ * column_name = C. Read-only, idempotent, can't tickle the post-ALTER
398
+ * bug. If the column is present → mark + return.
399
+ * 3. Only if step 2 says the column is missing, fall back to ALTER ADD
400
+ * COLUMN IF NOT EXISTS. Mark on success, also mark if Deeplake reports
401
+ * "already exists" (race: another client added it between our SELECT
402
+ * and ALTER).
403
+ *
404
+ * Marker uses the same dir / TTL as ensureLookupIndex so both schema
405
+ * caches share an opt-out (HIVEMIND_INDEX_MARKER_DIR) and a TTL knob.
406
+ */
407
+ async ensureEmbeddingColumn(table, column) {
408
+ await this.ensureColumn(table, column, "FLOAT4[]");
409
+ }
410
+ /**
411
+ * Generic marker-gated column migration. Same SELECT-then-ALTER flow as
412
+ * ensureEmbeddingColumn, parameterized by SQL type so it can patch up any
413
+ * column that was added to the schema after the table was originally
414
+ * created. Used today for `summary_embedding`, `message_embedding`, and
415
+ * the `agent` column (added 2026-04-11) — the latter has no fallback if
416
+ * a user upgraded over a pre-2026-04-11 table, so every INSERT fails
417
+ * with `column "agent" does not exist`.
418
+ */
419
+ async ensureColumn(table, column, sqlType) {
420
+ const markers = await getIndexMarkerStore();
421
+ const markerPath = markers.buildIndexMarkerPath(this.workspaceId, this.orgId, table, `col_${column}`);
422
+ if (markers.hasFreshIndexMarker(markerPath))
423
+ return;
424
+ const colCheck = `SELECT 1 FROM information_schema.columns WHERE table_name = '${sqlStr(table)}' AND column_name = '${sqlStr(column)}' AND table_schema = '${sqlStr(this.workspaceId)}' LIMIT 1`;
425
+ const rows = await this.query(colCheck);
426
+ if (rows.length > 0) {
427
+ markers.writeIndexMarker(markerPath);
428
+ return;
429
+ }
430
+ try {
431
+ await this.query(`ALTER TABLE "${table}" ADD COLUMN ${column} ${sqlType}`);
432
+ } catch (e) {
433
+ const msg = e instanceof Error ? e.message : String(e);
434
+ if (!/already exists/i.test(msg))
435
+ throw e;
436
+ const recheck = await this.query(colCheck);
437
+ if (recheck.length === 0)
438
+ throw e;
439
+ }
440
+ markers.writeIndexMarker(markerPath);
441
+ }
338
442
  /** List all tables in the workspace (with retry). */
339
443
  async listTables(forceRefresh = false) {
340
444
  if (!forceRefresh && this._tablesCache)
@@ -350,7 +454,8 @@ var DeeplakeApi = class {
350
454
  const resp = await fetch(`${this.apiUrl}/workspaces/${this.workspaceId}/tables`, {
351
455
  headers: {
352
456
  Authorization: `Bearer ${this.token}`,
353
- "X-Activeloop-Org-Id": this.orgId
457
+ "X-Activeloop-Org-Id": this.orgId,
458
+ ...deeplakeClientHeader()
354
459
  }
355
460
  });
356
461
  if (resp.ok) {
@@ -375,28 +480,60 @@ var DeeplakeApi = class {
375
480
  }
376
481
  return { tables: [], cacheable: false };
377
482
  }
483
+ /**
484
+ * Run a `CREATE TABLE` with an extra outer retry budget. The base
485
+ * `query()` already retries 3 times on fetch errors (~3.5s total), but a
486
+ * failed CREATE is permanent corruption — every subsequent SELECT against
487
+ * the missing table fails. Wrapping in an outer loop with longer backoff
488
+ * (2s, 5s, then 10s) gives us ~17s of reach across transient network
489
+ * blips before giving up. Failures still propagate; getApi() resets its
490
+ * cache on init failure (openclaw plugin) so the next call retries the
491
+ * whole init flow.
492
+ */
493
+ async createTableWithRetry(sql, label) {
494
+ const OUTER_BACKOFFS_MS = [2e3, 5e3, 1e4];
495
+ let lastErr = null;
496
+ for (let attempt = 0; attempt <= OUTER_BACKOFFS_MS.length; attempt++) {
497
+ try {
498
+ await this.query(sql);
499
+ return;
500
+ } catch (err) {
501
+ lastErr = err;
502
+ const msg = err instanceof Error ? err.message : String(err);
503
+ log2(`CREATE TABLE "${label}" attempt ${attempt + 1}/${OUTER_BACKOFFS_MS.length + 1} failed: ${msg}`);
504
+ if (attempt < OUTER_BACKOFFS_MS.length) {
505
+ await sleep(OUTER_BACKOFFS_MS[attempt]);
506
+ }
507
+ }
508
+ }
509
+ throw lastErr;
510
+ }
378
511
  /** Create the memory table if it doesn't already exist. Migrate columns on existing tables. */
379
512
  async ensureTable(name) {
380
513
  const tbl = name ?? this.tableName;
381
514
  const tables = await this.listTables();
382
515
  if (!tables.includes(tbl)) {
383
516
  log2(`table "${tbl}" not found, creating`);
384
- await this.query(`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 '', 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 '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`);
517
+ 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 '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, tbl);
385
518
  log2(`table "${tbl}" created`);
386
519
  if (!tables.includes(tbl))
387
520
  this._tablesCache = [...tables, tbl];
388
521
  }
522
+ await this.ensureEmbeddingColumn(tbl, SUMMARY_EMBEDDING_COL);
523
+ await this.ensureColumn(tbl, "agent", "TEXT NOT NULL DEFAULT ''");
389
524
  }
390
525
  /** Create the sessions table (uses JSONB for message since every row is a JSON event). */
391
526
  async ensureSessionsTable(name) {
392
527
  const tables = await this.listTables();
393
528
  if (!tables.includes(name)) {
394
529
  log2(`table "${name}" not found, creating`);
395
- await this.query(`CREATE TABLE IF NOT EXISTS "${name}" (id TEXT NOT NULL DEFAULT '', path TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '', message JSONB, 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 '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`);
530
+ await this.createTableWithRetry(`CREATE TABLE IF NOT EXISTS "${name}" (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 '', creation_date TEXT NOT NULL DEFAULT '', last_update_date TEXT NOT NULL DEFAULT '') USING deeplake`, name);
396
531
  log2(`table "${name}" created`);
397
532
  if (!tables.includes(name))
398
533
  this._tablesCache = [...tables, name];
399
534
  }
535
+ await this.ensureEmbeddingColumn(name, MESSAGE_EMBEDDING_COL);
536
+ await this.ensureColumn(name, "agent", "TEXT NOT NULL DEFAULT ''");
400
537
  await this.ensureLookupIndex(name, "path_creation_date", `("path", "creation_date")`);
401
538
  }
402
539
  };
@@ -6,17 +6,21 @@ import { fileURLToPath } from "node:url";
6
6
  import { dirname as dirname2, join as join4 } from "node:path";
7
7
 
8
8
  // dist/src/commands/auth.js
9
- import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
9
+ import { execSync } from "node:child_process";
10
+
11
+ // dist/src/commands/auth-creds.js
12
+ import { readFileSync, writeFileSync, mkdirSync, unlinkSync } from "node:fs";
10
13
  import { join } from "node:path";
11
14
  import { homedir } from "node:os";
12
- import { execSync } from "node:child_process";
13
- var CONFIG_DIR = join(homedir(), ".deeplake");
14
- var CREDS_PATH = join(CONFIG_DIR, "credentials.json");
15
+ function configDir() {
16
+ return join(homedir(), ".deeplake");
17
+ }
18
+ function credsPath() {
19
+ return join(configDir(), "credentials.json");
20
+ }
15
21
  function loadCredentials() {
16
- if (!existsSync(CREDS_PATH))
17
- return null;
18
22
  try {
19
- return JSON.parse(readFileSync(CREDS_PATH, "utf-8"));
23
+ return JSON.parse(readFileSync(credsPath(), "utf-8"));
20
24
  } catch {
21
25
  return null;
22
26
  }
@@ -100,9 +104,20 @@ var __bundleDir = dirname2(fileURLToPath(import.meta.url));
100
104
  var AUTH_CMD = join4(__bundleDir, "commands", "auth-login.js");
101
105
  var context = `DEEPLAKE MEMORY: Persistent memory at ~/.deeplake/memory/ shared across sessions, users, and agents.
102
106
 
103
- Structure: index.md (start here) \u2192 summaries/*.md \u2192 sessions/*.jsonl (last resort). Do NOT jump straight to JSONL.
104
- Search: grep -r "keyword" ~/.deeplake/memory/
105
- IMPORTANT: Only use bash commands (cat, ls, grep, echo, jq, head, tail, sed, awk, etc.) to interact with ~/.deeplake/memory/. Do NOT use python, python3, node, curl, or other interpreters \u2014 they are not available in the memory filesystem.
107
+ Deeplake memory has THREE tiers \u2014 pick the right one for the question:
108
+ 1. ~/.deeplake/memory/index.md \u2014 auto-generated index, top 50 most-recently-updated entries with Created + Last Updated + Project + Description columns. ~5 KB. **For "what's recent / who did X this week / since <date>" queries, START HERE** and trust the Last Updated column over any "Started:" line in summary bodies.
109
+ 2. ~/.deeplake/memory/summaries/ \u2014 condensed wiki summaries per session (~3 KB each). For keyword/topic recall, search these.
110
+ 3. ~/.deeplake/memory/sessions/ \u2014 raw full-dialogue JSONL (~5 KB each). FALLBACK only \u2014 use when summaries don't contain the exact quote/turn you need.
111
+
112
+ Search workflow:
113
+ - Time-based ("last week", "today", "since X"): cat ~/.deeplake/memory/index.md and read the most-recent rows.
114
+ - Keyword/topic recall: grep -r "keyword" ~/.deeplake/memory/summaries/ (the shell hook routes this through hybrid lexical+semantic search \u2014 synonyms match too). Then cat the top-matching summary.
115
+ - Raw transcript fallback only: grep -r "keyword" ~/.deeplake/memory/sessions/ (use sparingly \u2014 JSONL is verbose).
116
+
117
+ \u2705 grep -r "keyword" ~/.deeplake/memory/summaries/
118
+ \u274C grep without a summaries/ or sessions/ suffix \u2014 too noisy
119
+
120
+ IMPORTANT: Only use bash builtins (cat, ls, grep, echo, jq, head, tail, sed, awk, etc.) on ~/.deeplake/memory/. Do NOT use python, python3, node, curl, or other interpreters \u2014 they are not available in the memory filesystem.
106
121
  Do NOT spawn subagents to read deeplake memory.`;
107
122
  async function main() {
108
123
  if (process.env.HIVEMIND_WIKI_WORKER === "1")