@memtensor/memos-local-openclaw-plugin 1.0.5 → 1.0.6-beta.2

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 (60) hide show
  1. package/dist/capture/index.d.ts.map +1 -1
  2. package/dist/capture/index.js +24 -0
  3. package/dist/capture/index.js.map +1 -1
  4. package/dist/client/connector.d.ts.map +1 -1
  5. package/dist/client/connector.js +33 -5
  6. package/dist/client/connector.js.map +1 -1
  7. package/dist/client/hub.d.ts.map +1 -1
  8. package/dist/client/hub.js +4 -0
  9. package/dist/client/hub.js.map +1 -1
  10. package/dist/hub/server.d.ts +2 -0
  11. package/dist/hub/server.d.ts.map +1 -1
  12. package/dist/hub/server.js +116 -54
  13. package/dist/hub/server.js.map +1 -1
  14. package/dist/ingest/providers/index.d.ts +4 -0
  15. package/dist/ingest/providers/index.d.ts.map +1 -1
  16. package/dist/ingest/providers/index.js +32 -86
  17. package/dist/ingest/providers/index.js.map +1 -1
  18. package/dist/ingest/providers/openai.d.ts.map +1 -1
  19. package/dist/ingest/providers/openai.js +29 -13
  20. package/dist/ingest/providers/openai.js.map +1 -1
  21. package/dist/recall/engine.d.ts.map +1 -1
  22. package/dist/recall/engine.js +33 -32
  23. package/dist/recall/engine.js.map +1 -1
  24. package/dist/storage/sqlite.d.ts +43 -7
  25. package/dist/storage/sqlite.d.ts.map +1 -1
  26. package/dist/storage/sqlite.js +179 -58
  27. package/dist/storage/sqlite.js.map +1 -1
  28. package/dist/tools/memory-get.d.ts.map +1 -1
  29. package/dist/tools/memory-get.js +4 -1
  30. package/dist/tools/memory-get.js.map +1 -1
  31. package/dist/types.d.ts +1 -1
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js.map +1 -1
  34. package/dist/viewer/html.d.ts.map +1 -1
  35. package/dist/viewer/html.js +71 -21
  36. package/dist/viewer/html.js.map +1 -1
  37. package/dist/viewer/server.d.ts +24 -0
  38. package/dist/viewer/server.d.ts.map +1 -1
  39. package/dist/viewer/server.js +398 -144
  40. package/dist/viewer/server.js.map +1 -1
  41. package/index.ts +86 -34
  42. package/package.json +1 -1
  43. package/scripts/postinstall.cjs +21 -5
  44. package/src/capture/index.ts +36 -0
  45. package/src/client/connector.ts +32 -5
  46. package/src/client/hub.ts +4 -0
  47. package/src/hub/server.ts +110 -50
  48. package/src/ingest/providers/index.ts +37 -92
  49. package/src/ingest/providers/openai.ts +31 -13
  50. package/src/recall/engine.ts +32 -30
  51. package/src/storage/sqlite.ts +196 -63
  52. package/src/tools/memory-get.ts +4 -1
  53. package/src/types.ts +2 -0
  54. package/src/viewer/html.ts +71 -21
  55. package/src/viewer/server.ts +387 -139
  56. package/prebuilds/darwin-arm64/better_sqlite3.node +0 -0
  57. package/prebuilds/darwin-x64/better_sqlite3.node +0 -0
  58. package/prebuilds/linux-x64/better_sqlite3.node +0 -0
  59. package/prebuilds/win32-x64/better_sqlite3.node +0 -0
  60. package/telemetry.credentials.json +0 -5
@@ -150,6 +150,7 @@ class SqliteStore {
150
150
  this.migrateLocalSharedTasksOwner();
151
151
  this.migrateHubUserIdentityFields();
152
152
  this.migrateClientHubConnectionIdentityFields();
153
+ this.migrateTeamSharingInstanceId();
153
154
  this.log.debug("Database schema initialized");
154
155
  }
155
156
  migrateChunksIndexesForRecall() {
@@ -210,6 +211,42 @@ class SqliteStore {
210
211
  }
211
212
  catch { /* table may not exist yet */ }
212
213
  }
214
+ migrateTeamSharingInstanceId() {
215
+ try {
216
+ const tscCols = this.db.prepare("PRAGMA table_info(team_shared_chunks)").all();
217
+ if (tscCols.length > 0 && !tscCols.some(c => c.name === "hub_instance_id")) {
218
+ this.db.exec("ALTER TABLE team_shared_chunks ADD COLUMN hub_instance_id TEXT NOT NULL DEFAULT ''");
219
+ this.log.info("Migrated: added hub_instance_id to team_shared_chunks");
220
+ }
221
+ }
222
+ catch { /* table may not exist yet */ }
223
+ try {
224
+ const lstCols = this.db.prepare("PRAGMA table_info(local_shared_tasks)").all();
225
+ if (lstCols.length > 0 && !lstCols.some(c => c.name === "hub_instance_id")) {
226
+ this.db.exec("ALTER TABLE local_shared_tasks ADD COLUMN hub_instance_id TEXT NOT NULL DEFAULT ''");
227
+ this.log.info("Migrated: added hub_instance_id to local_shared_tasks");
228
+ }
229
+ }
230
+ catch { /* table may not exist yet */ }
231
+ try {
232
+ const connCols = this.db.prepare("PRAGMA table_info(client_hub_connection)").all();
233
+ if (connCols.length > 0 && !connCols.some(c => c.name === "hub_instance_id")) {
234
+ this.db.exec("ALTER TABLE client_hub_connection ADD COLUMN hub_instance_id TEXT NOT NULL DEFAULT ''");
235
+ this.log.info("Migrated: added hub_instance_id to client_hub_connection");
236
+ }
237
+ }
238
+ catch { /* table may not exist yet */ }
239
+ this.db.exec(`
240
+ CREATE TABLE IF NOT EXISTS team_shared_skills (
241
+ skill_id TEXT PRIMARY KEY,
242
+ hub_skill_id TEXT NOT NULL DEFAULT '',
243
+ visibility TEXT NOT NULL DEFAULT 'public',
244
+ group_id TEXT,
245
+ hub_instance_id TEXT NOT NULL DEFAULT '',
246
+ shared_at INTEGER NOT NULL
247
+ )
248
+ `);
249
+ }
213
250
  migrateOwnerFields() {
214
251
  const chunkCols = this.db.prepare("PRAGMA table_info(chunks)").all();
215
252
  if (!chunkCols.some((c) => c.name === "owner")) {
@@ -744,12 +781,13 @@ class SqliteStore {
744
781
  );
745
782
 
746
783
  CREATE TABLE IF NOT EXISTS local_shared_tasks (
747
- task_id TEXT PRIMARY KEY,
748
- hub_task_id TEXT NOT NULL,
749
- visibility TEXT NOT NULL DEFAULT 'public',
750
- group_id TEXT,
751
- synced_chunks INTEGER NOT NULL DEFAULT 0,
752
- shared_at INTEGER NOT NULL
784
+ task_id TEXT PRIMARY KEY,
785
+ hub_task_id TEXT NOT NULL,
786
+ visibility TEXT NOT NULL DEFAULT 'public',
787
+ group_id TEXT,
788
+ synced_chunks INTEGER NOT NULL DEFAULT 0,
789
+ hub_instance_id TEXT NOT NULL DEFAULT '',
790
+ shared_at INTEGER NOT NULL
753
791
  );
754
792
 
755
793
  CREATE TABLE IF NOT EXISTS local_shared_memories (
@@ -760,11 +798,21 @@ class SqliteStore {
760
798
 
761
799
  -- Client: team share UI metadata only (no hub_memories row — avoids local FTS/embed recall duplication)
762
800
  CREATE TABLE IF NOT EXISTS team_shared_chunks (
763
- chunk_id TEXT PRIMARY KEY REFERENCES chunks(id) ON DELETE CASCADE,
764
- hub_memory_id TEXT NOT NULL DEFAULT '',
765
- visibility TEXT NOT NULL DEFAULT 'public',
766
- group_id TEXT,
767
- shared_at INTEGER NOT NULL
801
+ chunk_id TEXT PRIMARY KEY REFERENCES chunks(id) ON DELETE CASCADE,
802
+ hub_memory_id TEXT NOT NULL DEFAULT '',
803
+ visibility TEXT NOT NULL DEFAULT 'public',
804
+ group_id TEXT,
805
+ hub_instance_id TEXT NOT NULL DEFAULT '',
806
+ shared_at INTEGER NOT NULL
807
+ );
808
+
809
+ CREATE TABLE IF NOT EXISTS team_shared_skills (
810
+ skill_id TEXT PRIMARY KEY,
811
+ hub_skill_id TEXT NOT NULL DEFAULT '',
812
+ visibility TEXT NOT NULL DEFAULT 'public',
813
+ group_id TEXT,
814
+ hub_instance_id TEXT NOT NULL DEFAULT '',
815
+ shared_at INTEGER NOT NULL
768
816
  );
769
817
 
770
818
  CREATE TABLE IF NOT EXISTS hub_users (
@@ -926,10 +974,10 @@ class SqliteStore {
926
974
  CREATE INDEX IF NOT EXISTS idx_hub_memories_group ON hub_memories(group_id);
927
975
 
928
976
  CREATE TABLE IF NOT EXISTS hub_memory_embeddings (
929
- memory_id TEXT PRIMARY KEY REFERENCES hub_memories(id) ON DELETE CASCADE,
930
- vector BLOB NOT NULL,
931
- dimensions INTEGER NOT NULL,
932
- updated_at INTEGER NOT NULL
977
+ memory_id TEXT PRIMARY KEY REFERENCES hub_memories(id) ON DELETE CASCADE,
978
+ vector BLOB NOT NULL,
979
+ dimensions INTEGER NOT NULL,
980
+ updated_at INTEGER NOT NULL
933
981
  );
934
982
 
935
983
  CREATE VIRTUAL TABLE IF NOT EXISTS hub_memories_fts USING fts5(
@@ -1132,6 +1180,15 @@ class SqliteStore {
1132
1180
  return [];
1133
1181
  }
1134
1182
  }
1183
+ listHubMemories(opts = {}) {
1184
+ const limit = opts.limit ?? 200;
1185
+ try {
1186
+ return this.db.prepare("SELECT id, summary, content FROM hub_memories ORDER BY created_at DESC LIMIT ?").all(limit);
1187
+ }
1188
+ catch {
1189
+ return [];
1190
+ }
1191
+ }
1135
1192
  // ─── Vector Search ───
1136
1193
  getAllEmbeddings(ownerFilter) {
1137
1194
  let sql = `SELECT e.chunk_id, e.vector, e.dimensions FROM embeddings e
@@ -1272,6 +1329,7 @@ class SqliteStore {
1272
1329
  "skills",
1273
1330
  "local_shared_memories",
1274
1331
  "team_shared_chunks",
1332
+ "team_shared_skills",
1275
1333
  "local_shared_tasks",
1276
1334
  "embeddings",
1277
1335
  "chunks",
@@ -1651,8 +1709,8 @@ class SqliteStore {
1651
1709
  // ─── Hub / Client connection ───
1652
1710
  setClientHubConnection(conn) {
1653
1711
  this.db.prepare(`
1654
- INSERT INTO client_hub_connection (id, hub_url, user_id, username, user_token, role, connected_at, identity_key, last_known_status)
1655
- VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?)
1712
+ INSERT INTO client_hub_connection (id, hub_url, user_id, username, user_token, role, connected_at, identity_key, last_known_status, hub_instance_id)
1713
+ VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1656
1714
  ON CONFLICT(id) DO UPDATE SET
1657
1715
  hub_url = excluded.hub_url,
1658
1716
  user_id = excluded.user_id,
@@ -1661,8 +1719,9 @@ class SqliteStore {
1661
1719
  role = excluded.role,
1662
1720
  connected_at = excluded.connected_at,
1663
1721
  identity_key = excluded.identity_key,
1664
- last_known_status = excluded.last_known_status
1665
- `).run(conn.hubUrl, conn.userId, conn.username, conn.userToken, conn.role, conn.connectedAt, conn.identityKey ?? "", conn.lastKnownStatus ?? "");
1722
+ last_known_status = excluded.last_known_status,
1723
+ hub_instance_id = excluded.hub_instance_id
1724
+ `).run(conn.hubUrl, conn.userId, conn.username, conn.userToken, conn.role, conn.connectedAt, conn.identityKey ?? "", conn.lastKnownStatus ?? "", conn.hubInstanceId ?? "");
1666
1725
  }
1667
1726
  getClientHubConnection() {
1668
1727
  const row = this.db.prepare('SELECT * FROM client_hub_connection WHERE id = 1').get();
@@ -1672,17 +1731,18 @@ class SqliteStore {
1672
1731
  this.db.prepare('DELETE FROM client_hub_connection WHERE id = 1').run();
1673
1732
  }
1674
1733
  // ─── Local Shared Tasks (client-side tracking) ───
1675
- markTaskShared(taskId, hubTaskId, syncedChunks, visibility, groupId) {
1734
+ markTaskShared(taskId, hubTaskId, syncedChunks, visibility, groupId, hubInstanceId) {
1676
1735
  this.db.prepare(`
1677
- INSERT INTO local_shared_tasks (task_id, hub_task_id, visibility, group_id, synced_chunks, shared_at)
1678
- VALUES (?, ?, ?, ?, ?, ?)
1736
+ INSERT INTO local_shared_tasks (task_id, hub_task_id, visibility, group_id, synced_chunks, hub_instance_id, shared_at)
1737
+ VALUES (?, ?, ?, ?, ?, ?, ?)
1679
1738
  ON CONFLICT(task_id) DO UPDATE SET
1680
1739
  hub_task_id = excluded.hub_task_id,
1681
1740
  visibility = excluded.visibility,
1682
1741
  group_id = excluded.group_id,
1683
1742
  synced_chunks = excluded.synced_chunks,
1743
+ hub_instance_id = excluded.hub_instance_id,
1684
1744
  shared_at = excluded.shared_at
1685
- `).run(taskId, hubTaskId, visibility, groupId ?? null, syncedChunks, Date.now());
1745
+ `).run(taskId, hubTaskId, visibility, groupId ?? null, syncedChunks, hubInstanceId ?? "", Date.now());
1686
1746
  }
1687
1747
  unmarkTaskShared(taskId) {
1688
1748
  this.db.prepare('DELETE FROM local_shared_tasks WHERE task_id = ?').run(taskId);
@@ -1691,11 +1751,11 @@ class SqliteStore {
1691
1751
  const row = this.db.prepare('SELECT * FROM local_shared_tasks WHERE task_id = ?').get(taskId);
1692
1752
  if (!row)
1693
1753
  return null;
1694
- return { taskId: row.task_id, hubTaskId: row.hub_task_id, visibility: row.visibility, groupId: row.group_id, syncedChunks: row.synced_chunks, sharedAt: row.shared_at };
1754
+ return { taskId: row.task_id, hubTaskId: row.hub_task_id, visibility: row.visibility, groupId: row.group_id, syncedChunks: row.synced_chunks, sharedAt: row.shared_at, hubInstanceId: row.hub_instance_id || "" };
1695
1755
  }
1696
1756
  listLocalSharedTasks() {
1697
- const rows = this.db.prepare('SELECT task_id, hub_task_id, visibility, group_id, synced_chunks FROM local_shared_tasks').all();
1698
- return rows.map(r => ({ taskId: r.task_id, hubTaskId: r.hub_task_id, visibility: r.visibility, groupId: r.group_id, syncedChunks: r.synced_chunks }));
1757
+ const rows = this.db.prepare('SELECT task_id, hub_task_id, visibility, group_id, synced_chunks, hub_instance_id FROM local_shared_tasks').all();
1758
+ return rows.map(r => ({ taskId: r.task_id, hubTaskId: r.hub_task_id, visibility: r.visibility, groupId: r.group_id, syncedChunks: r.synced_chunks, hubInstanceId: r.hub_instance_id || "" }));
1699
1759
  }
1700
1760
  // ─── Local Shared Memories (client-side tracking) ───
1701
1761
  markMemorySharedLocally(chunkId) {
@@ -1790,11 +1850,20 @@ class SqliteStore {
1790
1850
  return user;
1791
1851
  });
1792
1852
  }
1853
+ deleteHubMemoriesByUser(userId) {
1854
+ this.db.prepare('DELETE FROM hub_memories WHERE source_user_id = ?').run(userId);
1855
+ }
1856
+ deleteHubTasksByUser(userId) {
1857
+ this.db.prepare('DELETE FROM hub_tasks WHERE source_user_id = ?').run(userId);
1858
+ }
1859
+ deleteHubSkillsByUser(userId) {
1860
+ this.db.prepare('DELETE FROM hub_skills WHERE source_user_id = ?').run(userId);
1861
+ }
1793
1862
  deleteHubUser(userId, cleanResources = false) {
1794
1863
  if (cleanResources) {
1795
- this.db.prepare('DELETE FROM hub_tasks WHERE source_user_id = ?').run(userId);
1796
- this.db.prepare('DELETE FROM hub_skills WHERE source_user_id = ?').run(userId);
1797
- this.db.prepare('DELETE FROM hub_memories WHERE source_user_id = ?').run(userId);
1864
+ this.deleteHubTasksByUser(userId);
1865
+ this.deleteHubSkillsByUser(userId);
1866
+ this.deleteHubMemoriesByUser(userId);
1798
1867
  const result = this.db.prepare('DELETE FROM hub_users WHERE id = ?').run(userId);
1799
1868
  return result.changes > 0;
1800
1869
  }
@@ -1965,6 +2034,34 @@ class SqliteStore {
1965
2034
  vector: new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions),
1966
2035
  }));
1967
2036
  }
2037
+ upsertHubMemoryEmbedding(memoryId, vector) {
2038
+ const buf = Buffer.from(vector.buffer, vector.byteOffset, vector.byteLength);
2039
+ this.db.prepare(`
2040
+ INSERT INTO hub_memory_embeddings (memory_id, vector, dimensions, updated_at)
2041
+ VALUES (?, ?, ?, ?)
2042
+ ON CONFLICT(memory_id) DO UPDATE SET vector = excluded.vector, dimensions = excluded.dimensions, updated_at = excluded.updated_at
2043
+ `).run(memoryId, buf, vector.length, Date.now());
2044
+ }
2045
+ getHubMemoryEmbedding(memoryId) {
2046
+ const row = this.db.prepare('SELECT vector, dimensions FROM hub_memory_embeddings WHERE memory_id = ?').get(memoryId);
2047
+ if (!row)
2048
+ return null;
2049
+ return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.dimensions);
2050
+ }
2051
+ getVisibleHubMemoryEmbeddings(userId) {
2052
+ const rows = this.db.prepare(`
2053
+ SELECT hme.memory_id, hme.vector, hme.dimensions
2054
+ FROM hub_memory_embeddings hme
2055
+ JOIN hub_memories hm ON hm.id = hme.memory_id
2056
+ WHERE hm.visibility = 'public'
2057
+ OR hm.source_user_id = ?
2058
+ OR EXISTS (SELECT 1 FROM hub_group_members gm WHERE gm.group_id = hm.group_id AND gm.user_id = ?)
2059
+ `).all(userId, userId);
2060
+ return rows.map(r => ({
2061
+ memoryId: r.memory_id,
2062
+ vector: new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions),
2063
+ }));
2064
+ }
1968
2065
  searchHubChunks(query, options) {
1969
2066
  const limit = options?.maxResults ?? 10;
1970
2067
  const userId = options?.userId ?? "";
@@ -2179,17 +2276,18 @@ class SqliteStore {
2179
2276
  const vis = row.visibility === "group" ? "group" : "public";
2180
2277
  const gid = vis === "group" ? (row.groupId ?? null) : null;
2181
2278
  this.db.prepare(`
2182
- INSERT INTO team_shared_chunks (chunk_id, hub_memory_id, visibility, group_id, shared_at)
2183
- VALUES (?, ?, ?, ?, ?)
2279
+ INSERT INTO team_shared_chunks (chunk_id, hub_memory_id, visibility, group_id, hub_instance_id, shared_at)
2280
+ VALUES (?, ?, ?, ?, ?, ?)
2184
2281
  ON CONFLICT(chunk_id) DO UPDATE SET
2185
2282
  hub_memory_id = excluded.hub_memory_id,
2186
2283
  visibility = excluded.visibility,
2187
2284
  group_id = excluded.group_id,
2285
+ hub_instance_id = excluded.hub_instance_id,
2188
2286
  shared_at = excluded.shared_at
2189
- `).run(chunkId, row.hubMemoryId ?? "", vis, gid, now);
2287
+ `).run(chunkId, row.hubMemoryId ?? "", vis, gid, row.hubInstanceId ?? "", now);
2190
2288
  }
2191
2289
  getTeamSharedChunk(chunkId) {
2192
- const r = this.db.prepare("SELECT chunk_id, hub_memory_id, visibility, group_id, shared_at FROM team_shared_chunks WHERE chunk_id = ?").get(chunkId);
2290
+ const r = this.db.prepare("SELECT chunk_id, hub_memory_id, visibility, group_id, hub_instance_id, shared_at FROM team_shared_chunks WHERE chunk_id = ?").get(chunkId);
2193
2291
  if (!r)
2194
2292
  return null;
2195
2293
  return {
@@ -2197,6 +2295,7 @@ class SqliteStore {
2197
2295
  hubMemoryId: r.hub_memory_id,
2198
2296
  visibility: r.visibility,
2199
2297
  groupId: r.group_id,
2298
+ hubInstanceId: r.hub_instance_id || "",
2200
2299
  sharedAt: r.shared_at,
2201
2300
  };
2202
2301
  }
@@ -2204,6 +2303,49 @@ class SqliteStore {
2204
2303
  const info = this.db.prepare("DELETE FROM team_shared_chunks WHERE chunk_id = ?").run(chunkId);
2205
2304
  return info.changes > 0;
2206
2305
  }
2306
+ // ─── Team Shared Skills (Client role — UI metadata only) ───
2307
+ upsertTeamSharedSkill(skillId, row) {
2308
+ const now = Date.now();
2309
+ const vis = row.visibility === "group" ? "group" : "public";
2310
+ const gid = vis === "group" ? (row.groupId ?? null) : null;
2311
+ this.db.prepare(`
2312
+ INSERT INTO team_shared_skills (skill_id, hub_skill_id, visibility, group_id, hub_instance_id, shared_at)
2313
+ VALUES (?, ?, ?, ?, ?, ?)
2314
+ ON CONFLICT(skill_id) DO UPDATE SET
2315
+ hub_skill_id = excluded.hub_skill_id,
2316
+ visibility = excluded.visibility,
2317
+ group_id = excluded.group_id,
2318
+ hub_instance_id = excluded.hub_instance_id,
2319
+ shared_at = excluded.shared_at
2320
+ `).run(skillId, row.hubSkillId ?? "", vis, gid, row.hubInstanceId ?? "", now);
2321
+ }
2322
+ getTeamSharedSkill(skillId) {
2323
+ const r = this.db.prepare("SELECT * FROM team_shared_skills WHERE skill_id = ?").get(skillId);
2324
+ if (!r)
2325
+ return null;
2326
+ return { skillId: r.skill_id, hubSkillId: r.hub_skill_id, visibility: r.visibility, groupId: r.group_id, hubInstanceId: r.hub_instance_id || "", sharedAt: r.shared_at };
2327
+ }
2328
+ deleteTeamSharedSkill(skillId) {
2329
+ return this.db.prepare("DELETE FROM team_shared_skills WHERE skill_id = ?").run(skillId).changes > 0;
2330
+ }
2331
+ // ─── Team sharing cleanup (role switch / leave) ───
2332
+ clearTeamSharedChunks() {
2333
+ this.db.prepare("DELETE FROM team_shared_chunks").run();
2334
+ }
2335
+ clearTeamSharedSkills() {
2336
+ this.db.prepare("DELETE FROM team_shared_skills").run();
2337
+ }
2338
+ downgradeTeamSharedTasksToLocal() {
2339
+ this.db.prepare("UPDATE local_shared_tasks SET hub_task_id = '', hub_instance_id = '', visibility = 'public', group_id = NULL, synced_chunks = 0").run();
2340
+ }
2341
+ downgradeTeamSharedTaskToLocal(taskId) {
2342
+ this.db.prepare("UPDATE local_shared_tasks SET hub_task_id = '', hub_instance_id = '', visibility = 'public', group_id = NULL, synced_chunks = 0 WHERE task_id = ?").run(taskId);
2343
+ }
2344
+ clearAllTeamSharingState() {
2345
+ this.clearTeamSharedChunks();
2346
+ this.clearTeamSharedSkills();
2347
+ this.downgradeTeamSharedTasksToLocal();
2348
+ }
2207
2349
  // ─── Hub Notifications ───
2208
2350
  insertHubNotification(n) {
2209
2351
  this.db.prepare('INSERT INTO hub_notifications (id, user_id, type, resource, title, message, read, created_at) VALUES (?, ?, ?, ?, ?, ?, 0, ?)').run(n.id, n.userId, n.type, n.resource, n.title, n.message ?? '', Date.now());
@@ -2235,20 +2377,8 @@ class SqliteStore {
2235
2377
  clearHubNotifications(userId) {
2236
2378
  this.db.prepare('DELETE FROM hub_notifications WHERE user_id = ?').run(userId);
2237
2379
  }
2238
- upsertHubMemoryEmbedding(memoryId, vector) {
2239
- const buf = Buffer.from(vector.buffer, vector.byteOffset, vector.byteLength);
2240
- this.db.prepare(`
2241
- INSERT INTO hub_memory_embeddings (memory_id, vector, dimensions, updated_at)
2242
- VALUES (?, ?, ?, ?)
2243
- ON CONFLICT(memory_id) DO UPDATE SET vector = excluded.vector, dimensions = excluded.dimensions, updated_at = excluded.updated_at
2244
- `).run(memoryId, buf, vector.length, Date.now());
2245
- }
2246
- getHubMemoryEmbedding(memoryId) {
2247
- const row = this.db.prepare('SELECT vector, dimensions FROM hub_memory_embeddings WHERE memory_id = ?').get(memoryId);
2248
- if (!row)
2249
- return null;
2250
- return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.dimensions);
2251
- }
2380
+ // upsertHubMemoryEmbedding / getHubMemoryEmbedding removed:
2381
+ // hub memory vectors are now computed on-the-fly at search time.
2252
2382
  searchHubMemories(query, options) {
2253
2383
  const limit = options?.maxResults ?? 10;
2254
2384
  const userId = options?.userId ?? "";
@@ -2267,17 +2397,7 @@ class SqliteStore {
2267
2397
  `).all(sanitized, limit);
2268
2398
  return rows.map((row, idx) => ({ hit: row, rank: idx + 1 }));
2269
2399
  }
2270
- getVisibleHubMemoryEmbeddings(userId) {
2271
- const rows = this.db.prepare(`
2272
- SELECT hme.memory_id, hme.vector, hme.dimensions
2273
- FROM hub_memory_embeddings hme
2274
- JOIN hub_memories hm ON hm.id = hme.memory_id
2275
- `).all();
2276
- return rows.map(r => ({
2277
- memoryId: r.memory_id,
2278
- vector: new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions),
2279
- }));
2280
- }
2400
+ // getVisibleHubMemoryEmbeddings removed: vectors computed on-the-fly at search time.
2281
2401
  getVisibleHubSearchHitByMemoryId(memoryId, userId) {
2282
2402
  const row = this.db.prepare(`
2283
2403
  SELECT hm.id, hm.content, hm.summary, hm.role, hm.created_at, hm.visibility, '' as group_name, hu.username as owner_name,
@@ -2451,6 +2571,7 @@ function rowToClientHubConnection(row) {
2451
2571
  connectedAt: row.connected_at,
2452
2572
  identityKey: row.identity_key || "",
2453
2573
  lastKnownStatus: row.last_known_status || "",
2574
+ hubInstanceId: row.hub_instance_id || "",
2454
2575
  };
2455
2576
  }
2456
2577
  function rowToHubUser(row) {