@raviolelabs/engram-mcp 0.5.3 → 0.5.5

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 (180) hide show
  1. package/dist/cloud/bridge-client.d.ts.map +1 -1
  2. package/dist/cloud/bridge-client.js +14 -1
  3. package/dist/cloud/bridge-client.js.map +1 -1
  4. package/dist/cloud/pairing.d.ts.map +1 -1
  5. package/dist/cloud/pairing.js +45 -4
  6. package/dist/cloud/pairing.js.map +1 -1
  7. package/dist/core/db/index.d.ts.map +1 -1
  8. package/dist/core/db/index.js +31 -15
  9. package/dist/core/db/index.js.map +1 -1
  10. package/dist/core/logger.d.ts.map +1 -1
  11. package/dist/core/logger.js +22 -4
  12. package/dist/core/logger.js.map +1 -1
  13. package/dist/core/server/http.d.ts.map +1 -1
  14. package/dist/core/server/http.js +14 -3
  15. package/dist/core/server/http.js.map +1 -1
  16. package/package.json +1 -2
  17. package/dist/mcp-server/tests/mcp-e2e.test.d.ts +0 -2
  18. package/dist/mcp-server/tests/mcp-e2e.test.d.ts.map +0 -1
  19. package/dist/mcp-server/tests/mcp-e2e.test.js +0 -157
  20. package/dist/mcp-server/tests/mcp-e2e.test.js.map +0 -1
  21. package/dist/memory/modules/_custom/tests/custom-types.test.d.ts +0 -2
  22. package/dist/memory/modules/_custom/tests/custom-types.test.d.ts.map +0 -1
  23. package/dist/memory/modules/_custom/tests/custom-types.test.js +0 -96
  24. package/dist/memory/modules/_custom/tests/custom-types.test.js.map +0 -1
  25. package/dist/memory/modules/audio/tests/audio.test.d.ts +0 -2
  26. package/dist/memory/modules/audio/tests/audio.test.d.ts.map +0 -1
  27. package/dist/memory/modules/audio/tests/audio.test.js +0 -66
  28. package/dist/memory/modules/audio/tests/audio.test.js.map +0 -1
  29. package/dist/memory/modules/audio/tests/transcriber.test.d.ts +0 -2
  30. package/dist/memory/modules/audio/tests/transcriber.test.d.ts.map +0 -1
  31. package/dist/memory/modules/audio/tests/transcriber.test.js +0 -27
  32. package/dist/memory/modules/audio/tests/transcriber.test.js.map +0 -1
  33. package/dist/memory/modules/conversations/tests/conversations.test.d.ts +0 -2
  34. package/dist/memory/modules/conversations/tests/conversations.test.d.ts.map +0 -1
  35. package/dist/memory/modules/conversations/tests/conversations.test.js +0 -75
  36. package/dist/memory/modules/conversations/tests/conversations.test.js.map +0 -1
  37. package/dist/memory/modules/drive/tests/drive.test.d.ts +0 -2
  38. package/dist/memory/modules/drive/tests/drive.test.d.ts.map +0 -1
  39. package/dist/memory/modules/drive/tests/drive.test.js +0 -66
  40. package/dist/memory/modules/drive/tests/drive.test.js.map +0 -1
  41. package/dist/memory/modules/notes/tests/notes.test.d.ts +0 -2
  42. package/dist/memory/modules/notes/tests/notes.test.d.ts.map +0 -1
  43. package/dist/memory/modules/notes/tests/notes.test.js +0 -64
  44. package/dist/memory/modules/notes/tests/notes.test.js.map +0 -1
  45. package/dist/memory/modules/notion/tests/notion.test.d.ts +0 -2
  46. package/dist/memory/modules/notion/tests/notion.test.d.ts.map +0 -1
  47. package/dist/memory/modules/notion/tests/notion.test.js +0 -53
  48. package/dist/memory/modules/notion/tests/notion.test.js.map +0 -1
  49. package/dist/memory/modules/obsidian/tests/obsidian.test.d.ts +0 -2
  50. package/dist/memory/modules/obsidian/tests/obsidian.test.d.ts.map +0 -1
  51. package/dist/memory/modules/obsidian/tests/obsidian.test.js +0 -72
  52. package/dist/memory/modules/obsidian/tests/obsidian.test.js.map +0 -1
  53. package/dist/memory/modules/obsidian/tests/vault-reader.test.d.ts +0 -2
  54. package/dist/memory/modules/obsidian/tests/vault-reader.test.d.ts.map +0 -1
  55. package/dist/memory/modules/obsidian/tests/vault-reader.test.js +0 -37
  56. package/dist/memory/modules/obsidian/tests/vault-reader.test.js.map +0 -1
  57. package/dist/memory/modules/youtube/tests/channel.test.d.ts +0 -2
  58. package/dist/memory/modules/youtube/tests/channel.test.d.ts.map +0 -1
  59. package/dist/memory/modules/youtube/tests/channel.test.js +0 -61
  60. package/dist/memory/modules/youtube/tests/channel.test.js.map +0 -1
  61. package/dist/memory/modules/youtube/tests/transcript-fetcher.test.d.ts +0 -2
  62. package/dist/memory/modules/youtube/tests/transcript-fetcher.test.d.ts.map +0 -1
  63. package/dist/memory/modules/youtube/tests/transcript-fetcher.test.js +0 -23
  64. package/dist/memory/modules/youtube/tests/transcript-fetcher.test.js.map +0 -1
  65. package/dist/memory/modules/youtube/tests/youtube.test.d.ts +0 -2
  66. package/dist/memory/modules/youtube/tests/youtube.test.d.ts.map +0 -1
  67. package/dist/memory/modules/youtube/tests/youtube.test.js +0 -61
  68. package/dist/memory/modules/youtube/tests/youtube.test.js.map +0 -1
  69. package/dist/sync/tests/apply.test.d.ts +0 -4
  70. package/dist/sync/tests/apply.test.d.ts.map +0 -1
  71. package/dist/sync/tests/apply.test.js +0 -117
  72. package/dist/sync/tests/apply.test.js.map +0 -1
  73. package/dist/sync/tests/ops-log.test.d.ts +0 -2
  74. package/dist/sync/tests/ops-log.test.d.ts.map +0 -1
  75. package/dist/sync/tests/ops-log.test.js +0 -105
  76. package/dist/sync/tests/ops-log.test.js.map +0 -1
  77. package/dist/sync/tests/two-device-sync.test.d.ts +0 -2
  78. package/dist/sync/tests/two-device-sync.test.d.ts.map +0 -1
  79. package/dist/sync/tests/two-device-sync.test.js +0 -250
  80. package/dist/sync/tests/two-device-sync.test.js.map +0 -1
  81. package/dist/tests/chunker.test.d.ts +0 -2
  82. package/dist/tests/chunker.test.d.ts.map +0 -1
  83. package/dist/tests/chunker.test.js +0 -24
  84. package/dist/tests/chunker.test.js.map +0 -1
  85. package/dist/tests/cloud-auth.test.d.ts +0 -2
  86. package/dist/tests/cloud-auth.test.d.ts.map +0 -1
  87. package/dist/tests/cloud-auth.test.js +0 -75
  88. package/dist/tests/cloud-auth.test.js.map +0 -1
  89. package/dist/tests/cloud-crypto.test.d.ts +0 -2
  90. package/dist/tests/cloud-crypto.test.d.ts.map +0 -1
  91. package/dist/tests/cloud-crypto.test.js +0 -58
  92. package/dist/tests/cloud-crypto.test.js.map +0 -1
  93. package/dist/tests/cloud-integration.test.d.ts +0 -2
  94. package/dist/tests/cloud-integration.test.d.ts.map +0 -1
  95. package/dist/tests/cloud-integration.test.js +0 -193
  96. package/dist/tests/cloud-integration.test.js.map +0 -1
  97. package/dist/tests/cloud-pairing.test.d.ts +0 -2
  98. package/dist/tests/cloud-pairing.test.d.ts.map +0 -1
  99. package/dist/tests/cloud-pairing.test.js +0 -86
  100. package/dist/tests/cloud-pairing.test.js.map +0 -1
  101. package/dist/tests/cloud-saves-integration.test.d.ts +0 -2
  102. package/dist/tests/cloud-saves-integration.test.d.ts.map +0 -1
  103. package/dist/tests/cloud-saves-integration.test.js +0 -92
  104. package/dist/tests/cloud-saves-integration.test.js.map +0 -1
  105. package/dist/tests/cloud-transit.test.d.ts +0 -2
  106. package/dist/tests/cloud-transit.test.d.ts.map +0 -1
  107. package/dist/tests/cloud-transit.test.js +0 -263
  108. package/dist/tests/cloud-transit.test.js.map +0 -1
  109. package/dist/tests/config.test.d.ts +0 -2
  110. package/dist/tests/config.test.d.ts.map +0 -1
  111. package/dist/tests/config.test.js +0 -25
  112. package/dist/tests/config.test.js.map +0 -1
  113. package/dist/tests/db.test.d.ts +0 -2
  114. package/dist/tests/db.test.d.ts.map +0 -1
  115. package/dist/tests/db.test.js +0 -73
  116. package/dist/tests/db.test.js.map +0 -1
  117. package/dist/tests/embeddings-providers.test.d.ts +0 -2
  118. package/dist/tests/embeddings-providers.test.d.ts.map +0 -1
  119. package/dist/tests/embeddings-providers.test.js +0 -62
  120. package/dist/tests/embeddings-providers.test.js.map +0 -1
  121. package/dist/tests/embeddings.test.d.ts +0 -2
  122. package/dist/tests/embeddings.test.d.ts.map +0 -1
  123. package/dist/tests/embeddings.test.js +0 -22
  124. package/dist/tests/embeddings.test.js.map +0 -1
  125. package/dist/tests/integrations-api.test.d.ts +0 -2
  126. package/dist/tests/integrations-api.test.d.ts.map +0 -1
  127. package/dist/tests/integrations-api.test.js +0 -129
  128. package/dist/tests/integrations-api.test.js.map +0 -1
  129. package/dist/tests/memory-store.test.d.ts +0 -2
  130. package/dist/tests/memory-store.test.d.ts.map +0 -1
  131. package/dist/tests/memory-store.test.js +0 -129
  132. package/dist/tests/memory-store.test.js.map +0 -1
  133. package/dist/tests/module-registry.test.d.ts +0 -2
  134. package/dist/tests/module-registry.test.d.ts.map +0 -1
  135. package/dist/tests/module-registry.test.js +0 -44
  136. package/dist/tests/module-registry.test.js.map +0 -1
  137. package/dist/tests/property-extractor.test.d.ts +0 -2
  138. package/dist/tests/property-extractor.test.d.ts.map +0 -1
  139. package/dist/tests/property-extractor.test.js +0 -24
  140. package/dist/tests/property-extractor.test.js.map +0 -1
  141. package/dist/tests/public-tools.test.d.ts +0 -2
  142. package/dist/tests/public-tools.test.d.ts.map +0 -1
  143. package/dist/tests/public-tools.test.js +0 -286
  144. package/dist/tests/public-tools.test.js.map +0 -1
  145. package/dist/tests/reindex.test.d.ts +0 -2
  146. package/dist/tests/reindex.test.d.ts.map +0 -1
  147. package/dist/tests/reindex.test.js +0 -58
  148. package/dist/tests/reindex.test.js.map +0 -1
  149. package/dist/tests/scope-encryption.test.d.ts +0 -2
  150. package/dist/tests/scope-encryption.test.d.ts.map +0 -1
  151. package/dist/tests/scope-encryption.test.js +0 -71
  152. package/dist/tests/scope-encryption.test.js.map +0 -1
  153. package/dist/tests/shamir.test.d.ts +0 -2
  154. package/dist/tests/shamir.test.d.ts.map +0 -1
  155. package/dist/tests/shamir.test.js +0 -57
  156. package/dist/tests/shamir.test.js.map +0 -1
  157. package/dist/tests/source-registry.test.d.ts +0 -2
  158. package/dist/tests/source-registry.test.d.ts.map +0 -1
  159. package/dist/tests/source-registry.test.js +0 -58
  160. package/dist/tests/source-registry.test.js.map +0 -1
  161. package/dist/tests/types.test.d.ts +0 -2
  162. package/dist/tests/types.test.d.ts.map +0 -1
  163. package/dist/tests/types.test.js +0 -26
  164. package/dist/tests/types.test.js.map +0 -1
  165. package/dist/tests/vector.test.d.ts +0 -2
  166. package/dist/tests/vector.test.d.ts.map +0 -1
  167. package/dist/tests/vector.test.js +0 -61
  168. package/dist/tests/vector.test.js.map +0 -1
  169. package/dist/tests/wikilinks.test.d.ts +0 -2
  170. package/dist/tests/wikilinks.test.d.ts.map +0 -1
  171. package/dist/tests/wikilinks.test.js +0 -20
  172. package/dist/tests/wikilinks.test.js.map +0 -1
  173. package/dist/webapp/tests/api.test.d.ts +0 -2
  174. package/dist/webapp/tests/api.test.d.ts.map +0 -1
  175. package/dist/webapp/tests/api.test.js +0 -125
  176. package/dist/webapp/tests/api.test.js.map +0 -1
  177. package/dist/webapp/tests/mcp-http.test.d.ts +0 -2
  178. package/dist/webapp/tests/mcp-http.test.d.ts.map +0 -1
  179. package/dist/webapp/tests/mcp-http.test.js +0 -47
  180. package/dist/webapp/tests/mcp-http.test.js.map +0 -1
@@ -1,286 +0,0 @@
1
- // src/tests/public-tools.test.ts
2
- // Tests for the 10-tool public surface (v0.2).
3
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
4
- import fs from 'fs';
5
- import os from 'os';
6
- import path from 'path';
7
- import { ulid } from 'ulid';
8
- import { initDb, closeDb } from '../db/index.js';
9
- import { initVectorStore } from '../vector/store.js';
10
- import { MemoryStore } from '../memory/core/store.js';
11
- import { buildPublicTools } from '../memory/public/tools.js';
12
- const embeddingsConfig = {
13
- provider: 'ollama',
14
- baseUrl: 'http://localhost:11434',
15
- model: 'nomic-embed-text',
16
- dimensions: 768,
17
- };
18
- const mockConfig = {
19
- embeddings: embeddingsConfig,
20
- dataDir: '',
21
- mcp: { stdio: true, httpPort: 7777 },
22
- propertyExtraction: { enabled: false },
23
- whisper: { model: 'base', language: 'auto' },
24
- youtube: {},
25
- };
26
- describe('public tools — full 24-tool surface', () => {
27
- let tmpDir;
28
- let store;
29
- beforeEach(async () => {
30
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-public-'));
31
- initDb(tmpDir);
32
- initVectorStore(tmpDir);
33
- store = new MemoryStore({ embeddings: embeddingsConfig });
34
- const now = new Date().toISOString();
35
- await store.insert({
36
- id: ulid(),
37
- type: 'notes',
38
- source_id: 'manual:1',
39
- content: 'TypeScript is great for type-safe code',
40
- content_hash: 'h1',
41
- properties: { created_at: now, ingested_at: now, title: 'TS basics', tags: ['typescript'] },
42
- wikilinks: [],
43
- related_ids: [],
44
- embedding_model: 'nomic-embed-text:v1.5',
45
- });
46
- });
47
- afterEach(() => {
48
- closeDb();
49
- fs.rmSync(tmpDir, { recursive: true, force: true });
50
- });
51
- // Verify the surface has exactly 24 tools (all public — no admin flag)
52
- it('exposes exactly 24 public tools', () => {
53
- const tools = buildPublicTools(store, mockConfig);
54
- const names = tools.map((t) => t.name);
55
- expect(names).toHaveLength(24);
56
- // Core memory tools
57
- expect(names).toContain('remember');
58
- expect(names).toContain('recall');
59
- expect(names).toContain('get');
60
- expect(names).toContain('update');
61
- expect(names).toContain('forget');
62
- expect(names).toContain('relate');
63
- expect(names).toContain('list_types');
64
- expect(names).toContain('recent');
65
- expect(names).toContain('ingest');
66
- expect(names).toContain('suggest_properties');
67
- expect(names).toContain('get_ingest_status');
68
- // Watch/source tools
69
- expect(names).toContain('watch');
70
- expect(names).toContain('unwatch');
71
- expect(names).toContain('list_sources');
72
- // Type tools
73
- expect(names).toContain('create_type');
74
- expect(names).toContain('delete_type');
75
- // Previously-admin tools (now public)
76
- expect(names).toContain('connect_drive');
77
- expect(names).toContain('list_drive_files');
78
- expect(names).toContain('connect_notion');
79
- expect(names).toContain('list_notion_pages');
80
- expect(names).toContain('import_watch_later');
81
- // Cross-memory inference tools
82
- expect(names).toContain('analyze_patterns');
83
- expect(names).toContain('summarize_recent');
84
- expect(names).toContain('find_gaps');
85
- });
86
- it('list_types returns active types', async () => {
87
- const tools = buildPublicTools(store, mockConfig);
88
- const result = (await tools.find((t) => t.name === 'list_types').handler({}));
89
- expect(result.types).toContain('notes');
90
- });
91
- it('remember writes a memory and returns id + wikilinks_extracted', async () => {
92
- const tools = buildPublicTools(store, mockConfig);
93
- const result = (await tools
94
- .find((t) => t.name === 'remember')
95
- .handler({
96
- content: 'Discussed [[Atlas]] project with [[Alice]]',
97
- title: 'Atlas kickoff',
98
- tags: ['atlas', 'alice'],
99
- type: 'notes',
100
- }));
101
- expect(result.id).toBeTruthy();
102
- expect(result.wikilinks_extracted).toEqual(expect.arrayContaining(['Atlas', 'Alice']));
103
- const stored = store.getById(result.id);
104
- expect(stored?.properties.title).toBe('Atlas kickoff');
105
- expect(stored?.properties.tags).toContain('atlas');
106
- });
107
- it('recall returns semantic hits', async () => {
108
- const tools = buildPublicTools(store, mockConfig);
109
- const results = (await tools
110
- .find((t) => t.name === 'recall')
111
- .handler({
112
- query: 'coding typescript',
113
- limit: 5,
114
- }));
115
- expect(results.length).toBeGreaterThan(0);
116
- expect(results[0].type).toBe('notes');
117
- });
118
- it('get retrieves full memory by id', async () => {
119
- const tools = buildPublicTools(store, mockConfig);
120
- // First insert a known memory
121
- const now = new Date().toISOString();
122
- const id = ulid();
123
- await store.insert({
124
- id,
125
- type: 'notes',
126
- source_id: 'get-test',
127
- content: 'get me',
128
- content_hash: 'gm',
129
- properties: { created_at: now, ingested_at: now, title: 'get-test-title' },
130
- wikilinks: [],
131
- related_ids: [],
132
- embedding_model: 'm',
133
- });
134
- const result = (await tools.find((t) => t.name === 'get').handler({ id }));
135
- expect(result.id).toBe(id);
136
- expect(result.content).toBe('get me');
137
- });
138
- it('get returns not_found for unknown id', async () => {
139
- const tools = buildPublicTools(store, mockConfig);
140
- const result = (await tools.find((t) => t.name === 'get').handler({ id: 'nope' }));
141
- expect(result.error).toBe('not_found');
142
- });
143
- it('update mutates title and tags', async () => {
144
- const tools = buildPublicTools(store, mockConfig);
145
- const now = new Date().toISOString();
146
- const id = ulid();
147
- await store.insert({
148
- id,
149
- type: 'notes',
150
- source_id: 'upd',
151
- content: 'edit me',
152
- content_hash: 'e',
153
- properties: { created_at: now, ingested_at: now },
154
- wikilinks: [],
155
- related_ids: [],
156
- embedding_model: 'm',
157
- });
158
- const result = (await tools
159
- .find((t) => t.name === 'update')
160
- .handler({
161
- id,
162
- title: 'Renamed',
163
- tags: ['important'],
164
- }));
165
- expect(result.updated).toBe(true);
166
- expect(store.getById(id)?.properties.title).toBe('Renamed');
167
- expect(store.getById(id)?.properties.tags).toContain('important');
168
- });
169
- it('forget removes item from store', async () => {
170
- const tools = buildPublicTools(store, mockConfig);
171
- const now = new Date().toISOString();
172
- const id = ulid();
173
- await store.insert({
174
- id,
175
- type: 'notes',
176
- source_id: 'del',
177
- content: 'delete me',
178
- content_hash: 'd',
179
- properties: { created_at: now, ingested_at: now },
180
- wikilinks: [],
181
- related_ids: [],
182
- embedding_model: 'm',
183
- });
184
- await tools.find((t) => t.name === 'forget').handler({ id });
185
- expect(store.getById(id)).toBeUndefined();
186
- });
187
- it('relate returns memories sharing wikilinks', async () => {
188
- const tools = buildPublicTools(store, mockConfig);
189
- const now = new Date().toISOString();
190
- const aId = ulid();
191
- const bId = ulid();
192
- await store.insert({
193
- id: aId,
194
- type: 'notes',
195
- source_id: 'a',
196
- content: 'Working on [[ProjectAlpha]]',
197
- content_hash: 'a',
198
- properties: { created_at: now, ingested_at: now, title: 'note-a' },
199
- wikilinks: ['ProjectAlpha'],
200
- related_ids: [],
201
- embedding_model: 'm',
202
- });
203
- await store.insert({
204
- id: bId,
205
- type: 'notes',
206
- source_id: 'b',
207
- content: 'Alpha project notes',
208
- content_hash: 'b',
209
- properties: { created_at: now, ingested_at: now, title: 'ProjectAlpha' },
210
- wikilinks: [],
211
- related_ids: [],
212
- embedding_model: 'm',
213
- });
214
- const result = (await tools
215
- .find((t) => t.name === 'relate')
216
- .handler({
217
- id: bId,
218
- }));
219
- expect(result.some((r) => r.id === aId)).toBe(true);
220
- });
221
- it('recent returns latest memories sorted by date', async () => {
222
- const tools = buildPublicTools(store, mockConfig);
223
- const result = (await tools
224
- .find((t) => t.name === 'recent')
225
- .handler({
226
- limit: 5,
227
- }));
228
- expect(result.length).toBeGreaterThan(0);
229
- expect(result[0].type).toBeTruthy();
230
- });
231
- it('ingest routes .md file correctly', async () => {
232
- const tools = buildPublicTools(store, mockConfig);
233
- // Write a temp md file
234
- const mdPath = path.join(os.tmpdir(), `test-${ulid()}.md`);
235
- fs.writeFileSync(mdPath, '# Test Note\n\nThis is content for ingest test.');
236
- try {
237
- const result = (await tools
238
- .find((t) => t.name === 'ingest')
239
- .handler({
240
- uri: mdPath,
241
- tags: ['test'],
242
- }));
243
- expect(result.id).toBeTruthy();
244
- expect(result.type).toBe('notes');
245
- }
246
- finally {
247
- fs.unlinkSync(mdPath);
248
- }
249
- });
250
- it('suggest_properties returns content + instruction', async () => {
251
- const tools = buildPublicTools(store, mockConfig);
252
- const now = new Date().toISOString();
253
- const id = ulid();
254
- await store.insert({
255
- id,
256
- type: 'notes',
257
- source_id: 'sp:1',
258
- content: 'Plan a quarterly all-hands. Action: confirm venue by Friday.',
259
- content_hash: 'sp1',
260
- properties: { created_at: now, ingested_at: now },
261
- wikilinks: [],
262
- related_ids: [],
263
- embedding_model: 'm',
264
- });
265
- const result = (await tools
266
- .find((t) => t.name === 'suggest_properties')
267
- .handler({
268
- id,
269
- }));
270
- expect(result.memory_id).toBe(id);
271
- expect(result.content).toContain('quarterly all-hands');
272
- expect(result.current_properties.title).toBeNull();
273
- expect(result.instruction).toContain('update');
274
- expect(result.instruction).toContain('title');
275
- });
276
- it('suggest_properties returns error for unknown id', async () => {
277
- const tools = buildPublicTools(store, mockConfig);
278
- const result = (await tools
279
- .find((t) => t.name === 'suggest_properties')
280
- .handler({
281
- id: 'nonexistent',
282
- }));
283
- expect(result.error).toBe('not_found');
284
- });
285
- });
286
- //# sourceMappingURL=public-tools.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"public-tools.test.js","sourceRoot":"","sources":["../../src/tests/public-tools.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=reindex.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reindex.test.d.ts","sourceRoot":"","sources":["../../src/tests/reindex.test.ts"],"names":[],"mappings":""}
@@ -1,58 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
- import { ulid } from 'ulid';
6
- import { initDb, closeDb } from '../db/index.js';
7
- import { initVectorStore } from '../vector/store.js';
8
- import { MemoryStore } from '../memory/core/store.js';
9
- import { reindexAll } from '../memory/core/reindex.js';
10
- const embeddingsConfig = {
11
- provider: 'ollama',
12
- baseUrl: 'http://localhost:11434',
13
- model: 'nomic-embed-text',
14
- dimensions: 768,
15
- };
16
- describe('reindexAll', () => {
17
- let tmpDir;
18
- let store;
19
- beforeEach(async () => {
20
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-reindex-'));
21
- initDb(tmpDir);
22
- initVectorStore(tmpDir);
23
- store = new MemoryStore({ embeddings: embeddingsConfig });
24
- const now = new Date().toISOString();
25
- for (let i = 0; i < 3; i++) {
26
- await store.insert({
27
- id: ulid(),
28
- type: 'notes',
29
- source_id: `s${i}`,
30
- content: `Note number ${i} about TypeScript and memory`,
31
- content_hash: `h${i}`,
32
- properties: { created_at: now, ingested_at: now },
33
- wikilinks: [],
34
- related_ids: [],
35
- embedding_model: 'nomic-embed-text:v1',
36
- });
37
- }
38
- });
39
- afterEach(() => {
40
- closeDb();
41
- fs.rmSync(tmpDir, { recursive: true, force: true });
42
- });
43
- it('reindexes all memories under a new embedding config', async () => {
44
- const result = await reindexAll({ ...embeddingsConfig, model: 'nomic-embed-text' });
45
- expect(result.total).toBe(3);
46
- expect(result.types).toContain('notes');
47
- // Search still works after reindex
48
- const hits = await store.search('notes', 'TypeScript memory', 5);
49
- expect(hits.length).toBeGreaterThan(0);
50
- }, 60_000);
51
- it('emits progress callbacks per memory', async () => {
52
- const progress = [];
53
- await reindexAll({ ...embeddingsConfig }, (p) => progress.push({ ...p }));
54
- expect(progress.length).toBe(3);
55
- expect(progress[2].processed).toBe(3);
56
- }, 60_000);
57
- });
58
- //# sourceMappingURL=reindex.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reindex.test.js","sourceRoot":"","sources":["../../src/tests/reindex.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,MAAM,gBAAgB,GAAG;IACvB,QAAQ,EAAE,QAAiB;IAC3B,OAAO,EAAE,wBAAwB;IACjC,KAAK,EAAE,kBAAkB;IACzB,UAAU,EAAE,GAAG;CAChB,CAAC;AAEF,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,MAAc,CAAC;IACnB,IAAI,KAAkB,CAAC;IAEvB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,CAAC;QACf,eAAe,CAAC,MAAM,CAAC,CAAC;QACxB,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAE1D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAC,MAAM,CAAC;gBACjB,EAAE,EAAE,IAAI,EAAE;gBACV,IAAI,EAAE,OAAO;gBACb,SAAS,EAAE,IAAI,CAAC,EAAE;gBAClB,OAAO,EAAE,eAAe,CAAC,8BAA8B;gBACvD,YAAY,EAAE,IAAI,CAAC,EAAE;gBACrB,UAAU,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE;gBACjD,SAAS,EAAE,EAAE;gBACb,WAAW,EAAE,EAAE;gBACf,eAAe,EAAE,qBAAqB;aACvC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;QACV,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAExC,mCAAmC;QACnC,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,EAAE,MAAM,CAAC,CAAC;IAEX,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,QAAQ,GAA8D,EAAE,CAAC;QAC/E,MAAM,UAAU,CAAC,EAAE,GAAG,gBAAgB,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=scope-encryption.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scope-encryption.test.d.ts","sourceRoot":"","sources":["../../src/tests/scope-encryption.test.ts"],"names":[],"mappings":""}
@@ -1,71 +0,0 @@
1
- // src/tests/scope-encryption.test.ts
2
- // Verifies that workspace-scoped memories use a different encryption key
3
- // (team master key) from personal memories (personal master key).
4
- // Uses real libsodium — no mocks.
5
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
6
- import sodium from 'libsodium-wrappers';
7
- import fs from 'fs/promises';
8
- import path from 'path';
9
- import os from 'os';
10
- import { generateWorkspaceKey, wrapKeyForRecipient, unwrapAndStoreWorkspaceKey, loadWorkspaceKey, getOrCreateX25519Keypair, } from '../memory/modules/team/keystore.js';
11
- let tmpDir;
12
- beforeAll(async () => {
13
- await sodium.ready;
14
- tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'engram-scope-test-'));
15
- });
16
- afterAll(async () => {
17
- await fs.rm(tmpDir, { recursive: true, force: true });
18
- });
19
- describe('scope encryption', () => {
20
- it('generates a 32-byte workspace key', async () => {
21
- const key = await generateWorkspaceKey();
22
- expect(key).toBeInstanceOf(Uint8Array);
23
- expect(key.length).toBe(32);
24
- });
25
- it('generates X25519 keypair and persists it', async () => {
26
- const masterKey = sodium.randombytes_buf(32);
27
- const kp = await getOrCreateX25519Keypair(tmpDir, masterKey);
28
- expect(kp.publicKey.length).toBe(32);
29
- expect(kp.privateKey.length).toBe(32);
30
- // Second call returns the same keypair (loaded from disk)
31
- const kp2 = await getOrCreateX25519Keypair(tmpDir, masterKey);
32
- expect(sodium.to_hex(kp2.publicKey)).toBe(sodium.to_hex(kp.publicKey));
33
- });
34
- it('wraps team key for recipient and unwraps correctly', async () => {
35
- // Use a fresh tmpDir so the prior test's persisted keypair doesn't interfere
36
- const wrapDir = await fs.mkdtemp(path.join(os.tmpdir(), 'engram-wrap-test-'));
37
- const masterKey = sodium.randombytes_buf(32);
38
- const keypair = await getOrCreateX25519Keypair(wrapDir, masterKey);
39
- const teamKey = await generateWorkspaceKey();
40
- const pubkeyHex = sodium.to_hex(keypair.publicKey);
41
- // Owner wraps team key for recipient
42
- const wrappedHex = await wrapKeyForRecipient(teamKey, pubkeyHex);
43
- expect(wrappedHex).toMatch(/^[0-9a-f]+$/);
44
- // Recipient unwraps
45
- const workspaceId = 'TEST01WORKSPACEID01';
46
- const unwrapped = await unwrapAndStoreWorkspaceKey(wrapDir, workspaceId, wrappedHex, keypair);
47
- expect(sodium.to_hex(unwrapped)).toBe(sodium.to_hex(teamKey));
48
- // Persisted key matches
49
- const loaded = await loadWorkspaceKey(wrapDir, workspaceId);
50
- await fs.rm(wrapDir, { recursive: true, force: true });
51
- expect(loaded).not.toBeNull();
52
- expect(sodium.to_hex(loaded)).toBe(sodium.to_hex(teamKey));
53
- });
54
- it('team key is different from personal master key', async () => {
55
- const masterKey = sodium.randombytes_buf(32);
56
- const teamKey = await generateWorkspaceKey();
57
- // Very high probability that two 32-byte random values differ
58
- expect(sodium.to_hex(masterKey)).not.toBe(sodium.to_hex(teamKey));
59
- });
60
- it('wrapped keys for different recipients cannot be decrypted by wrong key', async () => {
61
- const masterKey = sodium.randombytes_buf(32);
62
- const keypairAlice = await getOrCreateX25519Keypair(tmpDir + '-alice', masterKey);
63
- // Bob has a different key directory
64
- const keypairBob = await getOrCreateX25519Keypair(tmpDir + '-bob', masterKey);
65
- const teamKey = await generateWorkspaceKey();
66
- const wrappedForAlice = await wrapKeyForRecipient(teamKey, sodium.to_hex(keypairAlice.publicKey));
67
- // Bob tries to unwrap a key sealed for Alice — should throw
68
- await expect(unwrapAndStoreWorkspaceKey(tmpDir + '-bob', 'WRONG_WORKSPACE_ID', wrappedForAlice, keypairBob)).rejects.toThrow();
69
- });
70
- });
71
- //# sourceMappingURL=scope-encryption.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scope-encryption.test.js","sourceRoot":"","sources":["../../src/tests/scope-encryption.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=shamir.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shamir.test.d.ts","sourceRoot":"","sources":["../../src/tests/shamir.test.ts"],"names":[],"mappings":""}
@@ -1,57 +0,0 @@
1
- // src/tests/shamir.test.ts
2
- import { describe, it, expect } from 'vitest';
3
- import { randomBytes } from 'crypto';
4
- import { shamirSplit, shamirCombine } from '../sync/shamir.js';
5
- describe('Shamir Secret Sharing', () => {
6
- it('round-trips a 32-byte KWK with 3-of-5', () => {
7
- const kwk = randomBytes(32);
8
- const shares = shamirSplit(kwk, 3, 5);
9
- expect(shares).toHaveLength(5);
10
- expect(shares[0].index).toBe(1);
11
- expect(shares[4].index).toBe(5);
12
- // All codes should be base32 (uppercase alpha + digits 2-7)
13
- for (const share of shares) {
14
- expect(share.code).toMatch(/^[A-Z2-7]+$/);
15
- }
16
- // Reconstruct from any 3 shares
17
- const reconstructed = shamirCombine([shares[0], shares[2], shares[4]]);
18
- expect(reconstructed).toStrictEqual(kwk);
19
- });
20
- it('round-trips with a different 3 shares', () => {
21
- const kwk = randomBytes(32);
22
- const shares = shamirSplit(kwk, 3, 5);
23
- const reconstructed = shamirCombine([shares[1], shares[3], shares[0]]);
24
- expect(reconstructed).toStrictEqual(kwk);
25
- });
26
- it('fails with only 2 shares (below threshold of 3)', () => {
27
- const kwk = randomBytes(32);
28
- const shares = shamirSplit(kwk, 3, 5);
29
- // 2 shares will produce garbage, not an error, due to SSS math —
30
- // but the length check on the result will catch it.
31
- // secrets.js-grempe returns a wrong value, not the original.
32
- const bad = shamirCombine([shares[0], shares[1]]);
33
- expect(bad).not.toStrictEqual(kwk);
34
- });
35
- it('rejects kwk not 32 bytes', () => {
36
- expect(() => shamirSplit(Buffer.from('short'), 3, 5)).toThrow(/32 bytes/);
37
- });
38
- it('rejects threshold < 2', () => {
39
- expect(() => shamirSplit(randomBytes(32), 1, 5)).toThrow(/threshold/);
40
- });
41
- it('rejects total < threshold', () => {
42
- expect(() => shamirSplit(randomBytes(32), 5, 3)).toThrow(/total/);
43
- });
44
- it('codes survive lowercasing + whitespace in recovery form entry', () => {
45
- const kwk = randomBytes(32);
46
- const shares = shamirSplit(kwk, 3, 5);
47
- // Simulate user copy-pasting with a lowercase letter or extra space
48
- const noisyShares = [
49
- { ...shares[0], code: shares[0].code.toLowerCase() },
50
- { ...shares[2], code: ' ' + shares[2].code + ' ' },
51
- { ...shares[4], code: shares[4].code },
52
- ];
53
- const reconstructed = shamirCombine(noisyShares);
54
- expect(reconstructed).toStrictEqual(kwk);
55
- });
56
- });
57
- //# sourceMappingURL=shamir.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shamir.test.js","sourceRoot":"","sources":["../../src/tests/shamir.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=source-registry.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source-registry.test.d.ts","sourceRoot":"","sources":["../../src/tests/source-registry.test.ts"],"names":[],"mappings":""}
@@ -1,58 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
- import { initDb, closeDb } from '../db/index.js';
6
- import { sourceRegistry } from '../memory/core/source-registry.js';
7
- describe('SourceRegistry', () => {
8
- let tmpDir;
9
- beforeEach(() => {
10
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'engram-sr-'));
11
- initDb(tmpDir);
12
- });
13
- afterEach(() => {
14
- closeDb();
15
- fs.rmSync(tmpDir, { recursive: true, force: true });
16
- });
17
- it('adds and lists a watched source', () => {
18
- const id = sourceRegistry.add({
19
- module_id: 'drive',
20
- external_id: 'doc-123',
21
- display_name: 'Q1 Roadmap',
22
- });
23
- const sources = sourceRegistry.list('drive');
24
- expect(sources).toHaveLength(1);
25
- expect(sources[0].id).toBe(id);
26
- expect(sources[0].display_name).toBe('Q1 Roadmap');
27
- });
28
- it('records sync timestamp and last_modified_remote', () => {
29
- const id = sourceRegistry.add({
30
- module_id: 'notion',
31
- external_id: 'page-456',
32
- display_name: 'Engineering',
33
- });
34
- sourceRegistry.recordSync(id, '2026-05-15T10:00:00Z');
35
- const s = sourceRegistry.get(id);
36
- expect(s?.last_synced_at).toBeGreaterThan(0);
37
- expect(s?.last_modified_remote).toBe('2026-05-15T10:00:00Z');
38
- });
39
- it('add() is idempotent on (module_id, external_id) — returns existing id instead of throwing', () => {
40
- const id1 = sourceRegistry.add({ module_id: 'drive', external_id: 'd1', display_name: 'A' });
41
- const id2 = sourceRegistry.add({ module_id: 'drive', external_id: 'd1', display_name: 'A2' });
42
- // Should return the existing id, not throw
43
- expect(id2).toBe(id1);
44
- // Only one row should exist
45
- const sources = sourceRegistry.list('drive');
46
- expect(sources.filter((s) => s.external_id === 'd1')).toHaveLength(1);
47
- });
48
- it('removes a watched source', () => {
49
- const id = sourceRegistry.add({
50
- module_id: 'drive',
51
- external_id: 'd2',
52
- display_name: 'Z',
53
- });
54
- sourceRegistry.remove(id);
55
- expect(sourceRegistry.get(id)).toBeUndefined();
56
- });
57
- });
58
- //# sourceMappingURL=source-registry.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source-registry.test.js","sourceRoot":"","sources":["../../src/tests/source-registry.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/tests/types.test.ts"],"names":[],"mappings":""}