@memtensor/memos-local-openclaw-plugin 1.0.4-beta.4 → 1.0.4-beta.6

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 (152) hide show
  1. package/README.md +22 -39
  2. package/dist/capture/index.d.ts.map +1 -1
  3. package/dist/capture/index.js +6 -0
  4. package/dist/capture/index.js.map +1 -1
  5. package/dist/config.d.ts +1 -2
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +3 -72
  8. package/dist/config.js.map +1 -1
  9. package/dist/embedding/index.d.ts +2 -4
  10. package/dist/embedding/index.d.ts.map +1 -1
  11. package/dist/embedding/index.js +1 -17
  12. package/dist/embedding/index.js.map +1 -1
  13. package/dist/index.d.ts +0 -2
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/ingest/providers/index.d.ts +2 -10
  18. package/dist/ingest/providers/index.d.ts.map +1 -1
  19. package/dist/ingest/providers/index.js +43 -209
  20. package/dist/ingest/providers/index.js.map +1 -1
  21. package/dist/ingest/providers/openai.d.ts +0 -1
  22. package/dist/ingest/providers/openai.d.ts.map +1 -1
  23. package/dist/ingest/providers/openai.js +0 -1
  24. package/dist/ingest/providers/openai.js.map +1 -1
  25. package/dist/ingest/task-processor.js +1 -1
  26. package/dist/ingest/task-processor.js.map +1 -1
  27. package/dist/recall/engine.js +1 -1
  28. package/dist/recall/engine.js.map +1 -1
  29. package/dist/shared/llm-call.d.ts +2 -4
  30. package/dist/shared/llm-call.d.ts.map +1 -1
  31. package/dist/shared/llm-call.js +81 -20
  32. package/dist/shared/llm-call.js.map +1 -1
  33. package/dist/skill/evaluator.d.ts.map +1 -1
  34. package/dist/skill/evaluator.js +2 -2
  35. package/dist/skill/evaluator.js.map +1 -1
  36. package/dist/skill/evolver.d.ts +2 -0
  37. package/dist/skill/evolver.d.ts.map +1 -1
  38. package/dist/skill/evolver.js +3 -0
  39. package/dist/skill/evolver.js.map +1 -1
  40. package/dist/skill/generator.d.ts.map +1 -1
  41. package/dist/skill/generator.js +4 -4
  42. package/dist/skill/generator.js.map +1 -1
  43. package/dist/skill/upgrader.js +1 -1
  44. package/dist/skill/upgrader.js.map +1 -1
  45. package/dist/skill/validator.js +1 -1
  46. package/dist/skill/validator.js.map +1 -1
  47. package/dist/storage/ensure-binding.d.ts.map +1 -1
  48. package/dist/storage/ensure-binding.js +1 -3
  49. package/dist/storage/ensure-binding.js.map +1 -1
  50. package/dist/storage/sqlite.d.ts +0 -294
  51. package/dist/storage/sqlite.d.ts.map +1 -1
  52. package/dist/storage/sqlite.js +0 -821
  53. package/dist/storage/sqlite.js.map +1 -1
  54. package/dist/telemetry.d.ts +12 -5
  55. package/dist/telemetry.d.ts.map +1 -1
  56. package/dist/telemetry.js +135 -38
  57. package/dist/telemetry.js.map +1 -1
  58. package/dist/tools/index.d.ts +0 -1
  59. package/dist/tools/index.d.ts.map +1 -1
  60. package/dist/tools/index.js +1 -3
  61. package/dist/tools/index.js.map +1 -1
  62. package/dist/tools/memory-search.d.ts +2 -3
  63. package/dist/tools/memory-search.d.ts.map +1 -1
  64. package/dist/tools/memory-search.js +7 -48
  65. package/dist/tools/memory-search.js.map +1 -1
  66. package/dist/types.d.ts +2 -49
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/types.js.map +1 -1
  69. package/dist/viewer/html.d.ts.map +1 -1
  70. package/dist/viewer/html.js +471 -2974
  71. package/dist/viewer/html.js.map +1 -1
  72. package/dist/viewer/server.d.ts +0 -45
  73. package/dist/viewer/server.d.ts.map +1 -1
  74. package/dist/viewer/server.js +18 -1155
  75. package/dist/viewer/server.js.map +1 -1
  76. package/index.ts +42 -430
  77. package/openclaw.plugin.json +1 -2
  78. package/package.json +3 -4
  79. package/scripts/postinstall.cjs +46 -283
  80. package/skill/memos-memory-guide/SKILL.md +2 -26
  81. package/src/capture/index.ts +8 -0
  82. package/src/config.ts +3 -94
  83. package/src/embedding/index.ts +1 -21
  84. package/src/index.ts +4 -7
  85. package/src/ingest/providers/index.ts +46 -246
  86. package/src/ingest/providers/openai.ts +1 -1
  87. package/src/ingest/task-processor.ts +1 -1
  88. package/src/recall/engine.ts +1 -1
  89. package/src/shared/llm-call.ts +95 -23
  90. package/src/skill/evaluator.ts +2 -3
  91. package/src/skill/evolver.ts +5 -0
  92. package/src/skill/generator.ts +4 -6
  93. package/src/skill/upgrader.ts +1 -1
  94. package/src/skill/validator.ts +1 -1
  95. package/src/storage/ensure-binding.ts +1 -3
  96. package/src/storage/sqlite.ts +0 -1085
  97. package/src/telemetry.ts +152 -39
  98. package/src/tools/index.ts +0 -1
  99. package/src/tools/memory-search.ts +8 -57
  100. package/src/types.ts +2 -44
  101. package/src/viewer/html.ts +471 -2974
  102. package/src/viewer/server.ts +21 -1070
  103. package/dist/client/connector.d.ts +0 -30
  104. package/dist/client/connector.d.ts.map +0 -1
  105. package/dist/client/connector.js +0 -219
  106. package/dist/client/connector.js.map +0 -1
  107. package/dist/client/hub.d.ts +0 -61
  108. package/dist/client/hub.d.ts.map +0 -1
  109. package/dist/client/hub.js +0 -148
  110. package/dist/client/hub.js.map +0 -1
  111. package/dist/client/skill-sync.d.ts +0 -29
  112. package/dist/client/skill-sync.d.ts.map +0 -1
  113. package/dist/client/skill-sync.js +0 -216
  114. package/dist/client/skill-sync.js.map +0 -1
  115. package/dist/hub/auth.d.ts +0 -19
  116. package/dist/hub/auth.d.ts.map +0 -1
  117. package/dist/hub/auth.js +0 -70
  118. package/dist/hub/auth.js.map +0 -1
  119. package/dist/hub/server.d.ts +0 -41
  120. package/dist/hub/server.d.ts.map +0 -1
  121. package/dist/hub/server.js +0 -747
  122. package/dist/hub/server.js.map +0 -1
  123. package/dist/hub/user-manager.d.ts +0 -29
  124. package/dist/hub/user-manager.d.ts.map +0 -1
  125. package/dist/hub/user-manager.js +0 -125
  126. package/dist/hub/user-manager.js.map +0 -1
  127. package/dist/openclaw-api.d.ts +0 -53
  128. package/dist/openclaw-api.d.ts.map +0 -1
  129. package/dist/openclaw-api.js +0 -189
  130. package/dist/openclaw-api.js.map +0 -1
  131. package/dist/sharing/types.contract.d.ts +0 -2
  132. package/dist/sharing/types.contract.d.ts.map +0 -1
  133. package/dist/sharing/types.contract.js +0 -3
  134. package/dist/sharing/types.contract.js.map +0 -1
  135. package/dist/sharing/types.d.ts +0 -80
  136. package/dist/sharing/types.d.ts.map +0 -1
  137. package/dist/sharing/types.js +0 -3
  138. package/dist/sharing/types.js.map +0 -1
  139. package/dist/tools/network-memory-detail.d.ts +0 -4
  140. package/dist/tools/network-memory-detail.d.ts.map +0 -1
  141. package/dist/tools/network-memory-detail.js +0 -34
  142. package/dist/tools/network-memory-detail.js.map +0 -1
  143. package/src/client/connector.ts +0 -218
  144. package/src/client/hub.ts +0 -189
  145. package/src/client/skill-sync.ts +0 -202
  146. package/src/hub/auth.ts +0 -78
  147. package/src/hub/server.ts +0 -740
  148. package/src/hub/user-manager.ts +0 -139
  149. package/src/openclaw-api.ts +0 -287
  150. package/src/sharing/types.contract.ts +0 -40
  151. package/src/sharing/types.ts +0 -102
  152. package/src/tools/network-memory-detail.ts +0 -34
@@ -145,7 +145,6 @@ class SqliteStore {
145
145
  this.migrateSkillVisibility();
146
146
  this.migrateSkillEmbeddingsAndFts();
147
147
  this.migrateFtsToTrigram();
148
- this.migrateHubTables();
149
148
  this.log.debug("Database schema initialized");
150
149
  }
151
150
  migrateChunksIndexesForRecall() {
@@ -623,217 +622,6 @@ class SqliteStore {
623
622
  },
624
623
  };
625
624
  }
626
- migrateHubTables() {
627
- this.db.exec(`
628
- CREATE TABLE IF NOT EXISTS client_hub_connection (
629
- id INTEGER PRIMARY KEY CHECK (id = 1),
630
- hub_url TEXT NOT NULL,
631
- user_id TEXT NOT NULL,
632
- username TEXT NOT NULL,
633
- user_token TEXT NOT NULL,
634
- role TEXT NOT NULL,
635
- connected_at INTEGER NOT NULL
636
- );
637
-
638
- CREATE TABLE IF NOT EXISTS local_shared_tasks (
639
- task_id TEXT PRIMARY KEY,
640
- hub_task_id TEXT NOT NULL,
641
- visibility TEXT NOT NULL DEFAULT 'public',
642
- group_id TEXT,
643
- synced_chunks INTEGER NOT NULL DEFAULT 0,
644
- shared_at INTEGER NOT NULL
645
- );
646
-
647
- CREATE TABLE IF NOT EXISTS hub_users (
648
- id TEXT PRIMARY KEY,
649
- username TEXT NOT NULL UNIQUE,
650
- device_name TEXT NOT NULL DEFAULT '',
651
- role TEXT NOT NULL,
652
- status TEXT NOT NULL,
653
- token_hash TEXT NOT NULL DEFAULT '',
654
- created_at INTEGER NOT NULL,
655
- approved_at INTEGER
656
- );
657
- CREATE INDEX IF NOT EXISTS idx_hub_users_status ON hub_users(status);
658
- CREATE INDEX IF NOT EXISTS idx_hub_users_role ON hub_users(role);
659
-
660
- CREATE TABLE IF NOT EXISTS hub_groups (
661
- id TEXT PRIMARY KEY,
662
- name TEXT NOT NULL UNIQUE,
663
- description TEXT NOT NULL DEFAULT '',
664
- created_at INTEGER NOT NULL
665
- );
666
-
667
- CREATE TABLE IF NOT EXISTS hub_group_members (
668
- group_id TEXT NOT NULL REFERENCES hub_groups(id) ON DELETE CASCADE,
669
- user_id TEXT NOT NULL REFERENCES hub_users(id) ON DELETE CASCADE,
670
- joined_at INTEGER NOT NULL,
671
- PRIMARY KEY (group_id, user_id)
672
- );
673
- CREATE INDEX IF NOT EXISTS idx_hub_group_members_user ON hub_group_members(user_id);
674
-
675
- CREATE TABLE IF NOT EXISTS hub_tasks (
676
- id TEXT PRIMARY KEY,
677
- source_task_id TEXT NOT NULL,
678
- source_user_id TEXT NOT NULL,
679
- title TEXT NOT NULL,
680
- summary TEXT NOT NULL DEFAULT '',
681
- group_id TEXT,
682
- visibility TEXT NOT NULL,
683
- created_at INTEGER NOT NULL,
684
- updated_at INTEGER NOT NULL,
685
- UNIQUE(source_user_id, source_task_id)
686
- );
687
- CREATE INDEX IF NOT EXISTS idx_hub_tasks_visibility ON hub_tasks(visibility);
688
- CREATE INDEX IF NOT EXISTS idx_hub_tasks_group ON hub_tasks(group_id);
689
-
690
- CREATE TABLE IF NOT EXISTS hub_chunks (
691
- id TEXT PRIMARY KEY,
692
- hub_task_id TEXT NOT NULL REFERENCES hub_tasks(id) ON DELETE CASCADE,
693
- source_chunk_id TEXT NOT NULL,
694
- source_user_id TEXT NOT NULL,
695
- role TEXT NOT NULL,
696
- content TEXT NOT NULL,
697
- summary TEXT NOT NULL DEFAULT '',
698
- kind TEXT NOT NULL DEFAULT 'paragraph',
699
- created_at INTEGER NOT NULL,
700
- UNIQUE(source_user_id, source_chunk_id)
701
- );
702
- CREATE INDEX IF NOT EXISTS idx_hub_chunks_task ON hub_chunks(hub_task_id);
703
-
704
- CREATE TABLE IF NOT EXISTS hub_embeddings (
705
- chunk_id TEXT PRIMARY KEY REFERENCES hub_chunks(id) ON DELETE CASCADE,
706
- vector BLOB NOT NULL,
707
- dimensions INTEGER NOT NULL,
708
- updated_at INTEGER NOT NULL
709
- );
710
-
711
- CREATE VIRTUAL TABLE IF NOT EXISTS hub_chunks_fts USING fts5(
712
- summary,
713
- content,
714
- content='hub_chunks',
715
- content_rowid='rowid',
716
- tokenize='porter unicode61'
717
- );
718
-
719
- CREATE TRIGGER IF NOT EXISTS hub_chunks_ai AFTER INSERT ON hub_chunks BEGIN
720
- INSERT INTO hub_chunks_fts(rowid, summary, content)
721
- VALUES (new.rowid, new.summary, new.content);
722
- END;
723
-
724
- CREATE TRIGGER IF NOT EXISTS hub_chunks_ad AFTER DELETE ON hub_chunks BEGIN
725
- INSERT INTO hub_chunks_fts(hub_chunks_fts, rowid, summary, content)
726
- VALUES ('delete', old.rowid, old.summary, old.content);
727
- END;
728
-
729
- CREATE TRIGGER IF NOT EXISTS hub_chunks_au AFTER UPDATE ON hub_chunks BEGIN
730
- INSERT INTO hub_chunks_fts(hub_chunks_fts, rowid, summary, content)
731
- VALUES ('delete', old.rowid, old.summary, old.content);
732
- INSERT INTO hub_chunks_fts(rowid, summary, content)
733
- VALUES (new.rowid, new.summary, new.content);
734
- END;
735
-
736
- CREATE TABLE IF NOT EXISTS hub_skills (
737
- id TEXT PRIMARY KEY,
738
- source_skill_id TEXT NOT NULL,
739
- source_user_id TEXT NOT NULL,
740
- name TEXT NOT NULL,
741
- description TEXT NOT NULL DEFAULT '',
742
- version INTEGER NOT NULL,
743
- group_id TEXT,
744
- visibility TEXT NOT NULL,
745
- bundle TEXT NOT NULL,
746
- quality_score REAL,
747
- created_at INTEGER NOT NULL,
748
- updated_at INTEGER NOT NULL,
749
- UNIQUE(source_user_id, source_skill_id)
750
- );
751
- CREATE INDEX IF NOT EXISTS idx_hub_skills_visibility ON hub_skills(visibility);
752
- CREATE INDEX IF NOT EXISTS idx_hub_skills_group ON hub_skills(group_id);
753
-
754
- CREATE TABLE IF NOT EXISTS hub_skill_embeddings (
755
- skill_id TEXT PRIMARY KEY REFERENCES hub_skills(id) ON DELETE CASCADE,
756
- vector BLOB NOT NULL,
757
- dimensions INTEGER NOT NULL,
758
- updated_at INTEGER NOT NULL
759
- );
760
-
761
- CREATE VIRTUAL TABLE IF NOT EXISTS hub_skills_fts USING fts5(
762
- name,
763
- description,
764
- content='hub_skills',
765
- content_rowid='rowid',
766
- tokenize='porter unicode61'
767
- );
768
-
769
- CREATE TRIGGER IF NOT EXISTS hub_skills_ai AFTER INSERT ON hub_skills BEGIN
770
- INSERT INTO hub_skills_fts(rowid, name, description)
771
- VALUES (new.rowid, new.name, new.description);
772
- END;
773
-
774
- CREATE TRIGGER IF NOT EXISTS hub_skills_ad AFTER DELETE ON hub_skills BEGIN
775
- INSERT INTO hub_skills_fts(hub_skills_fts, rowid, name, description)
776
- VALUES ('delete', old.rowid, old.name, old.description);
777
- END;
778
-
779
- CREATE TRIGGER IF NOT EXISTS hub_skills_au AFTER UPDATE ON hub_skills BEGIN
780
- INSERT INTO hub_skills_fts(hub_skills_fts, rowid, name, description)
781
- VALUES ('delete', old.rowid, old.name, old.description);
782
- INSERT INTO hub_skills_fts(rowid, name, description)
783
- VALUES (new.rowid, new.name, new.description);
784
- END;
785
-
786
- -- Independent shared memories (not tied to a task)
787
- CREATE TABLE IF NOT EXISTS hub_memories (
788
- id TEXT PRIMARY KEY,
789
- source_chunk_id TEXT NOT NULL,
790
- source_user_id TEXT NOT NULL,
791
- role TEXT NOT NULL,
792
- content TEXT NOT NULL,
793
- summary TEXT NOT NULL DEFAULT '',
794
- kind TEXT NOT NULL DEFAULT 'paragraph',
795
- group_id TEXT,
796
- visibility TEXT NOT NULL,
797
- created_at INTEGER NOT NULL,
798
- updated_at INTEGER NOT NULL,
799
- UNIQUE(source_user_id, source_chunk_id)
800
- );
801
- CREATE INDEX IF NOT EXISTS idx_hub_memories_visibility ON hub_memories(visibility);
802
- CREATE INDEX IF NOT EXISTS idx_hub_memories_group ON hub_memories(group_id);
803
-
804
- CREATE TABLE IF NOT EXISTS hub_memory_embeddings (
805
- memory_id TEXT PRIMARY KEY REFERENCES hub_memories(id) ON DELETE CASCADE,
806
- vector BLOB NOT NULL,
807
- dimensions INTEGER NOT NULL,
808
- updated_at INTEGER NOT NULL
809
- );
810
-
811
- CREATE VIRTUAL TABLE IF NOT EXISTS hub_memories_fts USING fts5(
812
- summary,
813
- content,
814
- content='hub_memories',
815
- content_rowid='rowid',
816
- tokenize='porter unicode61'
817
- );
818
-
819
- CREATE TRIGGER IF NOT EXISTS hub_memories_ai AFTER INSERT ON hub_memories BEGIN
820
- INSERT INTO hub_memories_fts(rowid, summary, content)
821
- VALUES (new.rowid, new.summary, new.content);
822
- END;
823
-
824
- CREATE TRIGGER IF NOT EXISTS hub_memories_ad AFTER DELETE ON hub_memories BEGIN
825
- INSERT INTO hub_memories_fts(hub_memories_fts, rowid, summary, content)
826
- VALUES ('delete', old.rowid, old.summary, old.content);
827
- END;
828
-
829
- CREATE TRIGGER IF NOT EXISTS hub_memories_au AFTER UPDATE ON hub_memories BEGIN
830
- INSERT INTO hub_memories_fts(hub_memories_fts, rowid, summary, content)
831
- VALUES ('delete', old.rowid, old.summary, old.content);
832
- INSERT INTO hub_memories_fts(rowid, summary, content)
833
- VALUES (new.rowid, new.summary, new.content);
834
- END;
835
- `);
836
- }
837
625
  // ─── Write ───
838
626
  insertChunk(chunk) {
839
627
  const stmt = this.db.prepare(`
@@ -1472,527 +1260,6 @@ class SqliteStore {
1472
1260
  return this.db.prepare("SELECT DISTINCT session_key FROM chunks ORDER BY session_key").all()
1473
1261
  .map(r => r.session_key);
1474
1262
  }
1475
- // ─── Hub / Client connection ───
1476
- setClientHubConnection(conn) {
1477
- this.db.prepare(`
1478
- INSERT INTO client_hub_connection (id, hub_url, user_id, username, user_token, role, connected_at)
1479
- VALUES (1, ?, ?, ?, ?, ?, ?)
1480
- ON CONFLICT(id) DO UPDATE SET
1481
- hub_url = excluded.hub_url,
1482
- user_id = excluded.user_id,
1483
- username = excluded.username,
1484
- user_token = excluded.user_token,
1485
- role = excluded.role,
1486
- connected_at = excluded.connected_at
1487
- `).run(conn.hubUrl, conn.userId, conn.username, conn.userToken, conn.role, conn.connectedAt);
1488
- }
1489
- getClientHubConnection() {
1490
- const row = this.db.prepare('SELECT * FROM client_hub_connection WHERE id = 1').get();
1491
- return row ? rowToClientHubConnection(row) : null;
1492
- }
1493
- clearClientHubConnection() {
1494
- this.db.prepare('DELETE FROM client_hub_connection WHERE id = 1').run();
1495
- }
1496
- // ─── Local Shared Tasks (client-side tracking) ───
1497
- markTaskShared(taskId, hubTaskId, syncedChunks, visibility, groupId) {
1498
- this.db.prepare(`
1499
- INSERT INTO local_shared_tasks (task_id, hub_task_id, visibility, group_id, synced_chunks, shared_at)
1500
- VALUES (?, ?, ?, ?, ?, ?)
1501
- ON CONFLICT(task_id) DO UPDATE SET
1502
- hub_task_id = excluded.hub_task_id,
1503
- visibility = excluded.visibility,
1504
- group_id = excluded.group_id,
1505
- synced_chunks = excluded.synced_chunks,
1506
- shared_at = excluded.shared_at
1507
- `).run(taskId, hubTaskId, visibility, groupId ?? null, syncedChunks, Date.now());
1508
- }
1509
- unmarkTaskShared(taskId) {
1510
- this.db.prepare('DELETE FROM local_shared_tasks WHERE task_id = ?').run(taskId);
1511
- }
1512
- getLocalSharedTask(taskId) {
1513
- const row = this.db.prepare('SELECT * FROM local_shared_tasks WHERE task_id = ?').get(taskId);
1514
- if (!row)
1515
- return null;
1516
- 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 };
1517
- }
1518
- listLocalSharedTasks() {
1519
- const rows = this.db.prepare('SELECT task_id, hub_task_id, visibility, group_id, synced_chunks FROM local_shared_tasks').all();
1520
- return rows.map(r => ({ taskId: r.task_id, hubTaskId: r.hub_task_id, visibility: r.visibility, groupId: r.group_id, syncedChunks: r.synced_chunks }));
1521
- }
1522
- // ─── Hub Users / Groups ───
1523
- upsertHubUser(user) {
1524
- this.db.prepare(`
1525
- INSERT INTO hub_users (id, username, device_name, role, status, token_hash, created_at, approved_at)
1526
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
1527
- ON CONFLICT(id) DO UPDATE SET
1528
- username = excluded.username,
1529
- device_name = excluded.device_name,
1530
- role = excluded.role,
1531
- status = excluded.status,
1532
- token_hash = excluded.token_hash,
1533
- created_at = excluded.created_at,
1534
- approved_at = excluded.approved_at
1535
- `).run(user.id, user.username, user.deviceName ?? "", user.role, user.status, user.tokenHash, user.createdAt, user.approvedAt);
1536
- }
1537
- getHubUser(userId) {
1538
- const row = this.db.prepare('SELECT * FROM hub_users WHERE id = ?').get(userId);
1539
- if (!row)
1540
- return null;
1541
- return this.attachGroupsToHubUser(rowToHubUser(row));
1542
- }
1543
- listHubUsers(status) {
1544
- const rows = status
1545
- ? this.db.prepare('SELECT * FROM hub_users WHERE status = ? ORDER BY created_at').all(status)
1546
- : this.db.prepare('SELECT * FROM hub_users ORDER BY created_at').all();
1547
- return rows.map((row) => this.attachGroupsToHubUser(rowToHubUser(row)));
1548
- }
1549
- upsertHubGroup(group) {
1550
- this.db.prepare(`
1551
- INSERT INTO hub_groups (id, name, description, created_at)
1552
- VALUES (?, ?, ?, ?)
1553
- ON CONFLICT(id) DO UPDATE SET
1554
- name = excluded.name,
1555
- description = excluded.description,
1556
- created_at = excluded.created_at
1557
- `).run(group.id, group.name, group.description, group.createdAt);
1558
- }
1559
- listHubGroups() {
1560
- const rows = this.db.prepare('SELECT * FROM hub_groups ORDER BY name').all();
1561
- return rows.map(rowToHubGroup);
1562
- }
1563
- addHubGroupMember(groupId, userId, joinedAt = Date.now()) {
1564
- this.db.prepare(`
1565
- INSERT INTO hub_group_members (group_id, user_id, joined_at)
1566
- VALUES (?, ?, ?)
1567
- ON CONFLICT(group_id, user_id) DO UPDATE SET joined_at = excluded.joined_at
1568
- `).run(groupId, userId, joinedAt);
1569
- }
1570
- getHubGroupById(groupId) {
1571
- const row = this.db.prepare('SELECT * FROM hub_groups WHERE id = ?').get(groupId);
1572
- return row ? rowToHubGroup(row) : undefined;
1573
- }
1574
- deleteHubGroup(groupId) {
1575
- const result = this.db.prepare('DELETE FROM hub_groups WHERE id = ?').run(groupId);
1576
- return result.changes > 0;
1577
- }
1578
- listHubGroupMembers(groupId) {
1579
- const rows = this.db.prepare(`
1580
- SELECT gm.user_id, hu.username, gm.joined_at
1581
- FROM hub_group_members gm
1582
- JOIN hub_users hu ON hu.id = gm.user_id
1583
- WHERE gm.group_id = ?
1584
- ORDER BY gm.joined_at
1585
- `).all(groupId);
1586
- return rows.map(r => ({ userId: r.user_id, username: r.username, joinedAt: r.joined_at }));
1587
- }
1588
- removeHubGroupMember(groupId, userId) {
1589
- this.db.prepare('DELETE FROM hub_group_members WHERE group_id = ? AND user_id = ?').run(groupId, userId);
1590
- }
1591
- getGroupsForHubUser(userId) {
1592
- const rows = this.db.prepare(`
1593
- SELECT g.*
1594
- FROM hub_group_members gm
1595
- JOIN hub_groups g ON g.id = gm.group_id
1596
- WHERE gm.user_id = ?
1597
- ORDER BY g.name
1598
- `).all(userId);
1599
- return rows.map((row) => ({ id: row.id, name: row.name, description: row.description || undefined }));
1600
- }
1601
- // ─── Hub Shared Data ───
1602
- upsertHubTask(task) {
1603
- this.db.prepare(`
1604
- INSERT INTO hub_tasks (id, source_task_id, source_user_id, title, summary, group_id, visibility, created_at, updated_at)
1605
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
1606
- ON CONFLICT(source_user_id, source_task_id) DO UPDATE SET
1607
- title = excluded.title,
1608
- summary = excluded.summary,
1609
- group_id = excluded.group_id,
1610
- visibility = excluded.visibility,
1611
- created_at = excluded.created_at,
1612
- updated_at = excluded.updated_at
1613
- `).run(task.id, task.sourceTaskId, task.sourceUserId, task.title, task.summary, task.groupId, task.visibility, task.createdAt, task.updatedAt);
1614
- }
1615
- getHubTaskBySource(sourceUserId, sourceTaskId) {
1616
- const row = this.db.prepare('SELECT * FROM hub_tasks WHERE source_user_id = ? AND source_task_id = ?').get(sourceUserId, sourceTaskId);
1617
- return row ? rowToHubTask(row) : null;
1618
- }
1619
- upsertHubChunk(chunk) {
1620
- if (!chunk.sourceTaskId)
1621
- throw new Error("sourceTaskId is required for hub chunk upserts");
1622
- const taskId = this.resolveCanonicalHubTaskId(chunk.hubTaskId, chunk.sourceUserId, chunk.sourceTaskId);
1623
- this.db.prepare(`
1624
- INSERT INTO hub_chunks (id, hub_task_id, source_chunk_id, source_user_id, role, content, summary, kind, created_at)
1625
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
1626
- ON CONFLICT(source_user_id, source_chunk_id) DO UPDATE SET
1627
- hub_task_id = excluded.hub_task_id,
1628
- role = excluded.role,
1629
- content = excluded.content,
1630
- summary = excluded.summary,
1631
- kind = excluded.kind,
1632
- created_at = excluded.created_at
1633
- `).run(chunk.id, taskId, chunk.sourceChunkId, chunk.sourceUserId, chunk.role, chunk.content, chunk.summary, chunk.kind, chunk.createdAt);
1634
- }
1635
- getHubChunkBySource(sourceUserId, sourceChunkId) {
1636
- const row = this.db.prepare('SELECT * FROM hub_chunks WHERE source_user_id = ? AND source_chunk_id = ?').get(sourceUserId, sourceChunkId);
1637
- return row ? rowToHubChunk(row) : null;
1638
- }
1639
- deleteHubTaskBySource(sourceUserId, sourceTaskId) {
1640
- this.db.prepare('DELETE FROM hub_tasks WHERE source_user_id = ? AND source_task_id = ?').run(sourceUserId, sourceTaskId);
1641
- }
1642
- upsertHubSkill(skill) {
1643
- this.db.prepare(`
1644
- INSERT INTO hub_skills (id, source_skill_id, source_user_id, name, description, version, group_id, visibility, bundle, quality_score, created_at, updated_at)
1645
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1646
- ON CONFLICT(source_user_id, source_skill_id) DO UPDATE SET
1647
- name = excluded.name,
1648
- description = excluded.description,
1649
- version = excluded.version,
1650
- group_id = excluded.group_id,
1651
- visibility = excluded.visibility,
1652
- bundle = excluded.bundle,
1653
- quality_score = excluded.quality_score,
1654
- created_at = excluded.created_at,
1655
- updated_at = excluded.updated_at
1656
- `).run(skill.id, skill.sourceSkillId, skill.sourceUserId, skill.name, skill.description, skill.version, skill.groupId, skill.visibility, skill.bundle, skill.qualityScore, skill.createdAt, skill.updatedAt);
1657
- }
1658
- getHubSkillBySource(sourceUserId, sourceSkillId) {
1659
- const row = this.db.prepare('SELECT * FROM hub_skills WHERE source_user_id = ? AND source_skill_id = ?').get(sourceUserId, sourceSkillId);
1660
- return row ? rowToHubSkill(row) : null;
1661
- }
1662
- getHubSkillById(skillId) {
1663
- const row = this.db.prepare('SELECT * FROM hub_skills WHERE id = ?').get(skillId);
1664
- return row ? rowToHubSkill(row) : null;
1665
- }
1666
- upsertHubSkillEmbedding(skillId, vector, sourceUserId, sourceSkillId) {
1667
- if (!sourceUserId || !sourceSkillId)
1668
- throw new Error("sourceUserId and sourceSkillId are required for hub skill embedding upserts");
1669
- const canonicalSkillId = this.resolveCanonicalHubSkillId(skillId, sourceUserId, sourceSkillId);
1670
- const buf = Buffer.allocUnsafe(vector.length * 4);
1671
- for (let i = 0; i < vector.length; i++)
1672
- buf.writeFloatLE(vector[i], i * 4);
1673
- this.db.prepare(`
1674
- INSERT INTO hub_skill_embeddings (skill_id, vector, dimensions, updated_at)
1675
- VALUES (?, ?, ?, ?)
1676
- ON CONFLICT(skill_id) DO UPDATE SET
1677
- vector = excluded.vector,
1678
- dimensions = excluded.dimensions,
1679
- updated_at = excluded.updated_at
1680
- `).run(canonicalSkillId, buf, vector.length, Date.now());
1681
- }
1682
- getHubSkillEmbedding(skillId) {
1683
- const row = this.db.prepare('SELECT vector, dimensions FROM hub_skill_embeddings WHERE skill_id = ?').get(skillId);
1684
- if (!row)
1685
- return null;
1686
- const out = [];
1687
- for (let i = 0; i < row.dimensions; i++)
1688
- out.push(row.vector.readFloatLE(i * 4));
1689
- return out;
1690
- }
1691
- searchHubChunks(query, options) {
1692
- const limit = options?.maxResults ?? 10;
1693
- const userId = options?.userId ?? "";
1694
- const rows = this.db.prepare(`
1695
- SELECT hc.id, hc.content, hc.summary, hc.role, hc.created_at, ht.title as task_title, ht.visibility, '' as group_name, hu.username as owner_name,
1696
- bm25(hub_chunks_fts) as rank
1697
- FROM hub_chunks_fts f
1698
- JOIN hub_chunks hc ON hc.rowid = f.rowid
1699
- JOIN hub_tasks ht ON ht.id = hc.hub_task_id
1700
- LEFT JOIN hub_users hu ON hu.id = ht.source_user_id
1701
- WHERE hub_chunks_fts MATCH ?
1702
- ORDER BY rank
1703
- LIMIT ?
1704
- `).all(sanitizeFtsQuery(query), limit);
1705
- return rows.map((row, idx) => ({ hit: row, rank: idx + 1 }));
1706
- }
1707
- upsertHubEmbedding(chunkId, vector) {
1708
- const buf = Buffer.from(vector.buffer, vector.byteOffset, vector.byteLength);
1709
- this.db.prepare(`
1710
- INSERT INTO hub_embeddings (chunk_id, vector, dimensions, updated_at)
1711
- VALUES (?, ?, ?, ?)
1712
- ON CONFLICT(chunk_id) DO UPDATE SET vector = excluded.vector, dimensions = excluded.dimensions, updated_at = excluded.updated_at
1713
- `).run(chunkId, buf, vector.length, Date.now());
1714
- }
1715
- getHubEmbedding(chunkId) {
1716
- const row = this.db.prepare('SELECT vector, dimensions FROM hub_embeddings WHERE chunk_id = ?').get(chunkId);
1717
- if (!row)
1718
- return null;
1719
- return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.dimensions);
1720
- }
1721
- getVisibleHubEmbeddings(userId) {
1722
- const rows = this.db.prepare(`
1723
- SELECT he.chunk_id, he.vector, he.dimensions
1724
- FROM hub_embeddings he
1725
- JOIN hub_chunks hc ON hc.id = he.chunk_id
1726
- JOIN hub_tasks ht ON ht.id = hc.hub_task_id
1727
- `).all();
1728
- return rows.map(r => ({
1729
- chunkId: r.chunk_id,
1730
- vector: new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions),
1731
- }));
1732
- }
1733
- getVisibleHubSearchHitByChunkId(chunkId, userId) {
1734
- const row = this.db.prepare(`
1735
- SELECT hc.id, hc.content, hc.summary, hc.role, hc.created_at, ht.title as task_title, ht.visibility, '' as group_name, hu.username as owner_name,
1736
- 0 as rank
1737
- FROM hub_chunks hc
1738
- JOIN hub_tasks ht ON ht.id = hc.hub_task_id
1739
- LEFT JOIN hub_users hu ON hu.id = ht.source_user_id
1740
- WHERE hc.id = ?
1741
- LIMIT 1
1742
- `).get(chunkId);
1743
- return row ?? null;
1744
- }
1745
- getHubChunkById(chunkId) {
1746
- const row = this.db.prepare('SELECT * FROM hub_chunks WHERE id = ?').get(chunkId);
1747
- return row ? rowToHubChunk(row) : null;
1748
- }
1749
- searchHubSkills(query, options) {
1750
- const limit = options?.maxResults ?? 10;
1751
- const userId = options?.userId ?? "";
1752
- const sanitized = sanitizeFtsQuery(query);
1753
- let rows;
1754
- if (sanitized) {
1755
- rows = this.db.prepare(`
1756
- SELECT hs.id, hs.name, hs.description, hs.version, hs.visibility, '' AS group_name, hu.username AS owner_name, hs.quality_score,
1757
- bm25(hub_skills_fts) as rank
1758
- FROM hub_skills_fts f
1759
- JOIN hub_skills hs ON hs.rowid = f.rowid
1760
- LEFT JOIN hub_users hu ON hu.id = hs.source_user_id
1761
- WHERE hub_skills_fts MATCH ?
1762
- ORDER BY rank
1763
- LIMIT ?
1764
- `).all(sanitized, limit);
1765
- }
1766
- else {
1767
- rows = this.db.prepare(`
1768
- SELECT hs.id, hs.name, hs.description, hs.version, hs.visibility, '' AS group_name, hu.username AS owner_name, hs.quality_score,
1769
- 0 as rank
1770
- FROM hub_skills hs
1771
- LEFT JOIN hub_users hu ON hu.id = hs.source_user_id
1772
- ORDER BY hs.updated_at DESC
1773
- LIMIT ?
1774
- `).all(limit);
1775
- }
1776
- return rows.map((row, idx) => ({ hit: row, rank: idx + 1 }));
1777
- }
1778
- deleteHubSkillBySource(sourceUserId, sourceSkillId) {
1779
- this.db.prepare('DELETE FROM hub_skills WHERE source_user_id = ? AND source_skill_id = ?').run(sourceUserId, sourceSkillId);
1780
- }
1781
- listVisibleHubTasks(userId, limit = 40) {
1782
- const rows = this.db.prepare(`
1783
- SELECT t.*, u.username AS owner_name, NULL AS group_name,
1784
- (SELECT COUNT(*) FROM hub_chunks c WHERE c.hub_task_id = t.id) AS chunk_count
1785
- FROM hub_tasks t
1786
- LEFT JOIN hub_users u ON u.id = t.source_user_id
1787
- ORDER BY t.updated_at DESC
1788
- LIMIT ?
1789
- `).all(limit);
1790
- return rows.map(r => ({
1791
- id: r.id, sourceTaskId: r.source_task_id, sourceUserId: r.source_user_id,
1792
- title: r.title, summary: r.summary, groupId: r.group_id, groupName: r.group_name ?? null,
1793
- visibility: r.visibility, ownerName: r.owner_name ?? "unknown", chunkCount: r.chunk_count ?? 0,
1794
- createdAt: r.created_at, updatedAt: r.updated_at,
1795
- }));
1796
- }
1797
- listAllHubTasks() {
1798
- const rows = this.db.prepare(`
1799
- SELECT t.*, u.username AS owner_name, g.name AS group_name,
1800
- (SELECT COUNT(*) FROM hub_chunks c WHERE c.hub_task_id = t.id) AS chunk_count
1801
- FROM hub_tasks t
1802
- LEFT JOIN hub_users u ON u.id = t.source_user_id
1803
- LEFT JOIN hub_groups g ON g.id = t.group_id
1804
- ORDER BY t.updated_at DESC
1805
- `).all();
1806
- return rows.map(r => ({
1807
- id: r.id, sourceTaskId: r.source_task_id, sourceUserId: r.source_user_id,
1808
- title: r.title, summary: r.summary, groupId: r.group_id, groupName: r.group_name ?? null,
1809
- visibility: r.visibility, ownerName: r.owner_name ?? "unknown", chunkCount: r.chunk_count ?? 0,
1810
- createdAt: r.created_at, updatedAt: r.updated_at,
1811
- }));
1812
- }
1813
- deleteHubTaskById(taskId) {
1814
- const info = this.db.prepare('DELETE FROM hub_tasks WHERE id = ?').run(taskId);
1815
- return info.changes > 0;
1816
- }
1817
- listVisibleHubSkills(userId, limit = 40) {
1818
- const rows = this.db.prepare(`
1819
- SELECT s.*, u.username AS owner_name, NULL AS group_name
1820
- FROM hub_skills s
1821
- LEFT JOIN hub_users u ON u.id = s.source_user_id
1822
- ORDER BY s.updated_at DESC
1823
- LIMIT ?
1824
- `).all(limit);
1825
- return rows.map(r => ({
1826
- id: r.id, sourceSkillId: r.source_skill_id, sourceUserId: r.source_user_id,
1827
- name: r.name, description: r.description, version: r.version,
1828
- groupId: r.group_id, groupName: r.group_name ?? null, visibility: r.visibility,
1829
- ownerName: r.owner_name ?? "unknown", qualityScore: r.quality_score,
1830
- createdAt: r.created_at, updatedAt: r.updated_at,
1831
- }));
1832
- }
1833
- listAllHubSkills() {
1834
- const rows = this.db.prepare(`
1835
- SELECT s.*, u.username AS owner_name, g.name AS group_name
1836
- FROM hub_skills s
1837
- LEFT JOIN hub_users u ON u.id = s.source_user_id
1838
- LEFT JOIN hub_groups g ON g.id = s.group_id
1839
- ORDER BY s.updated_at DESC
1840
- `).all();
1841
- return rows.map(r => ({
1842
- id: r.id, sourceSkillId: r.source_skill_id, sourceUserId: r.source_user_id,
1843
- name: r.name, description: r.description, version: r.version,
1844
- groupId: r.group_id, groupName: r.group_name ?? null, visibility: r.visibility,
1845
- ownerName: r.owner_name ?? "unknown", qualityScore: r.quality_score,
1846
- createdAt: r.created_at, updatedAt: r.updated_at,
1847
- }));
1848
- }
1849
- deleteHubSkillById(skillId) {
1850
- const info = this.db.prepare('DELETE FROM hub_skills WHERE id = ?').run(skillId);
1851
- return info.changes > 0;
1852
- }
1853
- // ─── Hub Shared Memories (independent) ───
1854
- upsertHubMemory(memory) {
1855
- this.db.prepare(`
1856
- INSERT INTO hub_memories (id, source_chunk_id, source_user_id, role, content, summary, kind, group_id, visibility, created_at, updated_at)
1857
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1858
- ON CONFLICT(source_user_id, source_chunk_id) DO UPDATE SET
1859
- role = excluded.role,
1860
- content = excluded.content,
1861
- summary = excluded.summary,
1862
- kind = excluded.kind,
1863
- group_id = excluded.group_id,
1864
- visibility = excluded.visibility,
1865
- created_at = excluded.created_at,
1866
- updated_at = excluded.updated_at
1867
- `).run(memory.id, memory.sourceChunkId, memory.sourceUserId, memory.role, memory.content, memory.summary, memory.kind, memory.groupId, memory.visibility, memory.createdAt, memory.updatedAt);
1868
- }
1869
- getHubMemoryBySource(sourceUserId, sourceChunkId) {
1870
- const row = this.db.prepare('SELECT * FROM hub_memories WHERE source_user_id = ? AND source_chunk_id = ?').get(sourceUserId, sourceChunkId);
1871
- return row ? rowToHubMemory(row) : null;
1872
- }
1873
- getHubMemoryById(memoryId) {
1874
- const row = this.db.prepare('SELECT * FROM hub_memories WHERE id = ?').get(memoryId);
1875
- return row ? rowToHubMemory(row) : null;
1876
- }
1877
- deleteHubMemoryBySource(sourceUserId, sourceChunkId) {
1878
- this.db.prepare('DELETE FROM hub_memories WHERE source_user_id = ? AND source_chunk_id = ?').run(sourceUserId, sourceChunkId);
1879
- }
1880
- deleteHubMemoryById(memoryId) {
1881
- const info = this.db.prepare('DELETE FROM hub_memories WHERE id = ?').run(memoryId);
1882
- return info.changes > 0;
1883
- }
1884
- upsertHubMemoryEmbedding(memoryId, vector) {
1885
- const buf = Buffer.from(vector.buffer, vector.byteOffset, vector.byteLength);
1886
- this.db.prepare(`
1887
- INSERT INTO hub_memory_embeddings (memory_id, vector, dimensions, updated_at)
1888
- VALUES (?, ?, ?, ?)
1889
- ON CONFLICT(memory_id) DO UPDATE SET vector = excluded.vector, dimensions = excluded.dimensions, updated_at = excluded.updated_at
1890
- `).run(memoryId, buf, vector.length, Date.now());
1891
- }
1892
- getHubMemoryEmbedding(memoryId) {
1893
- const row = this.db.prepare('SELECT vector, dimensions FROM hub_memory_embeddings WHERE memory_id = ?').get(memoryId);
1894
- if (!row)
1895
- return null;
1896
- return new Float32Array(row.vector.buffer, row.vector.byteOffset, row.dimensions);
1897
- }
1898
- searchHubMemories(query, options) {
1899
- const limit = options?.maxResults ?? 10;
1900
- const userId = options?.userId ?? "";
1901
- const sanitized = sanitizeFtsQuery(query);
1902
- if (!sanitized)
1903
- return [];
1904
- const rows = this.db.prepare(`
1905
- SELECT hm.id, hm.content, hm.summary, hm.role, hm.created_at, hm.visibility, '' as group_name, hu.username as owner_name,
1906
- bm25(hub_memories_fts) as rank
1907
- FROM hub_memories_fts f
1908
- JOIN hub_memories hm ON hm.rowid = f.rowid
1909
- LEFT JOIN hub_users hu ON hu.id = hm.source_user_id
1910
- WHERE hub_memories_fts MATCH ?
1911
- ORDER BY rank
1912
- LIMIT ?
1913
- `).all(sanitized, limit);
1914
- return rows.map((row, idx) => ({ hit: row, rank: idx + 1 }));
1915
- }
1916
- getVisibleHubMemoryEmbeddings(userId) {
1917
- const rows = this.db.prepare(`
1918
- SELECT hme.memory_id, hme.vector, hme.dimensions
1919
- FROM hub_memory_embeddings hme
1920
- JOIN hub_memories hm ON hm.id = hme.memory_id
1921
- `).all();
1922
- return rows.map(r => ({
1923
- memoryId: r.memory_id,
1924
- vector: new Float32Array(r.vector.buffer, r.vector.byteOffset, r.dimensions),
1925
- }));
1926
- }
1927
- getVisibleHubSearchHitByMemoryId(memoryId, userId) {
1928
- const row = this.db.prepare(`
1929
- SELECT hm.id, hm.content, hm.summary, hm.role, hm.created_at, hm.visibility, '' as group_name, hu.username as owner_name,
1930
- 0 as rank
1931
- FROM hub_memories hm
1932
- LEFT JOIN hub_users hu ON hu.id = hm.source_user_id
1933
- WHERE hm.id = ?
1934
- LIMIT 1
1935
- `).get(memoryId);
1936
- return row ?? null;
1937
- }
1938
- listVisibleHubMemories(userId, limit = 40) {
1939
- const rows = this.db.prepare(`
1940
- SELECT m.*, u.username AS owner_name, NULL AS group_name
1941
- FROM hub_memories m
1942
- LEFT JOIN hub_users u ON u.id = m.source_user_id
1943
- ORDER BY m.updated_at DESC
1944
- LIMIT ?
1945
- `).all(limit);
1946
- return rows.map(r => ({
1947
- id: r.id, sourceChunkId: r.source_chunk_id, sourceUserId: r.source_user_id,
1948
- role: r.role, summary: r.summary, kind: r.kind,
1949
- groupId: r.group_id, groupName: r.group_name ?? null, visibility: r.visibility,
1950
- ownerName: r.owner_name ?? "unknown", createdAt: r.created_at, updatedAt: r.updated_at,
1951
- }));
1952
- }
1953
- listAllHubMemories() {
1954
- const rows = this.db.prepare(`
1955
- SELECT m.*, u.username AS owner_name, g.name AS group_name
1956
- FROM hub_memories m
1957
- LEFT JOIN hub_users u ON u.id = m.source_user_id
1958
- LEFT JOIN hub_groups g ON g.id = m.group_id
1959
- ORDER BY m.updated_at DESC
1960
- `).all();
1961
- return rows.map(r => ({
1962
- id: r.id, sourceChunkId: r.source_chunk_id, sourceUserId: r.source_user_id,
1963
- role: r.role, summary: r.summary, kind: r.kind,
1964
- groupId: r.group_id, groupName: r.group_name ?? null, visibility: r.visibility,
1965
- ownerName: r.owner_name ?? "unknown", createdAt: r.created_at, updatedAt: r.updated_at,
1966
- }));
1967
- }
1968
- resolveCanonicalHubTaskId(taskId, sourceUserId, sourceTaskId) {
1969
- if (sourceTaskId) {
1970
- const bySource = this.db.prepare('SELECT id FROM hub_tasks WHERE source_user_id = ? AND source_task_id = ?').get(sourceUserId, sourceTaskId);
1971
- if (!bySource)
1972
- throw new Error(`source task not found for user=${sourceUserId} sourceTaskId=${sourceTaskId}`);
1973
- if (bySource.id != taskId)
1974
- throw new Error(`mismatch between source task and hubTaskId: expected ${bySource.id}, got ${taskId}`);
1975
- return bySource.id;
1976
- }
1977
- throw new Error(`source task not found for user=${sourceUserId} taskId=${taskId}`);
1978
- }
1979
- resolveCanonicalHubSkillId(skillId, sourceUserId, sourceSkillId) {
1980
- if (sourceUserId && sourceSkillId) {
1981
- const bySource = this.db.prepare('SELECT id FROM hub_skills WHERE source_user_id = ? AND source_skill_id = ?').get(sourceUserId, sourceSkillId);
1982
- if (!bySource)
1983
- throw new Error(`source skill not found for user=${sourceUserId} sourceSkillId=${sourceSkillId}`);
1984
- if (bySource.id != skillId)
1985
- throw new Error(`mismatch between source skill and skillId: expected ${bySource.id}, got ${skillId}`);
1986
- return bySource.id;
1987
- }
1988
- throw new Error(`source skill not found for skillId=${skillId}`);
1989
- }
1990
- attachGroupsToHubUser(user) {
1991
- return {
1992
- ...user,
1993
- groups: this.getGroupsForHubUser(user.id),
1994
- };
1995
- }
1996
1263
  getSessionOwnerMap(sessionKeys) {
1997
1264
  const result = new Map();
1998
1265
  if (sessionKeys.length === 0)
@@ -2094,94 +1361,6 @@ function rowToSkillVersion(row) {
2094
1361
  createdAt: row.created_at,
2095
1362
  };
2096
1363
  }
2097
- function rowToClientHubConnection(row) {
2098
- return {
2099
- hubUrl: row.hub_url,
2100
- userId: row.user_id,
2101
- username: row.username,
2102
- userToken: row.user_token,
2103
- role: row.role,
2104
- connectedAt: row.connected_at,
2105
- };
2106
- }
2107
- function rowToHubUser(row) {
2108
- return {
2109
- id: row.id,
2110
- username: row.username,
2111
- deviceName: row.device_name || undefined,
2112
- role: row.role,
2113
- status: row.status,
2114
- groups: [],
2115
- tokenHash: row.token_hash,
2116
- createdAt: row.created_at,
2117
- approvedAt: row.approved_at,
2118
- };
2119
- }
2120
- function rowToHubGroup(row) {
2121
- return {
2122
- id: row.id,
2123
- name: row.name,
2124
- description: row.description,
2125
- createdAt: row.created_at,
2126
- };
2127
- }
2128
- function rowToHubTask(row) {
2129
- return {
2130
- id: row.id,
2131
- sourceTaskId: row.source_task_id,
2132
- sourceUserId: row.source_user_id,
2133
- title: row.title,
2134
- summary: row.summary,
2135
- groupId: row.group_id,
2136
- visibility: row.visibility,
2137
- createdAt: row.created_at,
2138
- updatedAt: row.updated_at,
2139
- };
2140
- }
2141
- function rowToHubChunk(row) {
2142
- return {
2143
- id: row.id,
2144
- hubTaskId: row.hub_task_id,
2145
- sourceChunkId: row.source_chunk_id,
2146
- sourceUserId: row.source_user_id,
2147
- role: row.role,
2148
- content: row.content,
2149
- summary: row.summary,
2150
- kind: row.kind,
2151
- createdAt: row.created_at,
2152
- };
2153
- }
2154
- function rowToHubSkill(row) {
2155
- return {
2156
- id: row.id,
2157
- sourceSkillId: row.source_skill_id,
2158
- sourceUserId: row.source_user_id,
2159
- name: row.name,
2160
- description: row.description,
2161
- version: row.version,
2162
- groupId: row.group_id,
2163
- visibility: row.visibility,
2164
- bundle: row.bundle,
2165
- qualityScore: row.quality_score,
2166
- createdAt: row.created_at,
2167
- updatedAt: row.updated_at,
2168
- };
2169
- }
2170
- function rowToHubMemory(row) {
2171
- return {
2172
- id: row.id,
2173
- sourceChunkId: row.source_chunk_id,
2174
- sourceUserId: row.source_user_id,
2175
- role: row.role,
2176
- content: row.content,
2177
- summary: row.summary,
2178
- kind: row.kind,
2179
- groupId: row.group_id,
2180
- visibility: row.visibility,
2181
- createdAt: row.created_at,
2182
- updatedAt: row.updated_at,
2183
- };
2184
- }
2185
1364
  function contentHash(content) {
2186
1365
  return (0, crypto_1.createHash)("sha256").update(content).digest("hex").slice(0, 16);
2187
1366
  }