@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.
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +24 -0
- package/dist/capture/index.js.map +1 -1
- package/dist/client/connector.d.ts.map +1 -1
- package/dist/client/connector.js +33 -5
- package/dist/client/connector.js.map +1 -1
- package/dist/client/hub.d.ts.map +1 -1
- package/dist/client/hub.js +4 -0
- package/dist/client/hub.js.map +1 -1
- package/dist/hub/server.d.ts +2 -0
- package/dist/hub/server.d.ts.map +1 -1
- package/dist/hub/server.js +116 -54
- package/dist/hub/server.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +4 -0
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +32 -86
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +29 -13
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/recall/engine.d.ts.map +1 -1
- package/dist/recall/engine.js +33 -32
- package/dist/recall/engine.js.map +1 -1
- package/dist/storage/sqlite.d.ts +43 -7
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +179 -58
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/tools/memory-get.d.ts.map +1 -1
- package/dist/tools/memory-get.js +4 -1
- package/dist/tools/memory-get.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +71 -21
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +24 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +398 -144
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +86 -34
- package/package.json +1 -1
- package/scripts/postinstall.cjs +21 -5
- package/src/capture/index.ts +36 -0
- package/src/client/connector.ts +32 -5
- package/src/client/hub.ts +4 -0
- package/src/hub/server.ts +110 -50
- package/src/ingest/providers/index.ts +37 -92
- package/src/ingest/providers/openai.ts +31 -13
- package/src/recall/engine.ts +32 -30
- package/src/storage/sqlite.ts +196 -63
- package/src/tools/memory-get.ts +4 -1
- package/src/types.ts +2 -0
- package/src/viewer/html.ts +71 -21
- package/src/viewer/server.ts +387 -139
- package/prebuilds/darwin-arm64/better_sqlite3.node +0 -0
- package/prebuilds/darwin-x64/better_sqlite3.node +0 -0
- package/prebuilds/linux-x64/better_sqlite3.node +0 -0
- package/prebuilds/win32-x64/better_sqlite3.node +0 -0
- package/telemetry.credentials.json +0 -5
package/dist/storage/sqlite.js
CHANGED
|
@@ -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
|
|
748
|
-
hub_task_id
|
|
749
|
-
visibility
|
|
750
|
-
group_id
|
|
751
|
-
synced_chunks
|
|
752
|
-
|
|
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
|
|
764
|
-
hub_memory_id
|
|
765
|
-
visibility
|
|
766
|
-
group_id
|
|
767
|
-
|
|
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
|
|
930
|
-
vector
|
|
931
|
-
dimensions
|
|
932
|
-
updated_at
|
|
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
|
-
|
|
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.
|
|
1796
|
-
this.
|
|
1797
|
-
this.
|
|
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
|
|
2239
|
-
|
|
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
|
|
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) {
|