@soleri/core 2.0.2 → 2.1.0

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 (58) hide show
  1. package/dist/brain/brain.d.ts +12 -50
  2. package/dist/brain/brain.d.ts.map +1 -1
  3. package/dist/brain/brain.js +147 -12
  4. package/dist/brain/brain.js.map +1 -1
  5. package/dist/brain/intelligence.d.ts +51 -0
  6. package/dist/brain/intelligence.d.ts.map +1 -0
  7. package/dist/brain/intelligence.js +666 -0
  8. package/dist/brain/intelligence.js.map +1 -0
  9. package/dist/brain/types.d.ts +165 -0
  10. package/dist/brain/types.d.ts.map +1 -0
  11. package/dist/brain/types.js +2 -0
  12. package/dist/brain/types.js.map +1 -0
  13. package/dist/cognee/client.d.ts +35 -0
  14. package/dist/cognee/client.d.ts.map +1 -0
  15. package/dist/cognee/client.js +291 -0
  16. package/dist/cognee/client.js.map +1 -0
  17. package/dist/cognee/types.d.ts +46 -0
  18. package/dist/cognee/types.d.ts.map +1 -0
  19. package/dist/cognee/types.js +3 -0
  20. package/dist/cognee/types.js.map +1 -0
  21. package/dist/curator/curator.d.ts.map +1 -1
  22. package/dist/curator/curator.js +7 -5
  23. package/dist/curator/curator.js.map +1 -1
  24. package/dist/index.d.ts +4 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +3 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/llm/llm-client.d.ts.map +1 -1
  29. package/dist/llm/llm-client.js +9 -2
  30. package/dist/llm/llm-client.js.map +1 -1
  31. package/dist/runtime/core-ops.d.ts +3 -3
  32. package/dist/runtime/core-ops.d.ts.map +1 -1
  33. package/dist/runtime/core-ops.js +180 -15
  34. package/dist/runtime/core-ops.js.map +1 -1
  35. package/dist/runtime/runtime.d.ts.map +1 -1
  36. package/dist/runtime/runtime.js +4 -0
  37. package/dist/runtime/runtime.js.map +1 -1
  38. package/dist/runtime/types.d.ts +2 -0
  39. package/dist/runtime/types.d.ts.map +1 -1
  40. package/package.json +1 -1
  41. package/src/__tests__/brain-intelligence.test.ts +623 -0
  42. package/src/__tests__/brain.test.ts +265 -27
  43. package/src/__tests__/cognee-client.test.ts +524 -0
  44. package/src/__tests__/core-ops.test.ts +77 -49
  45. package/src/__tests__/curator.test.ts +126 -31
  46. package/src/__tests__/domain-ops.test.ts +45 -9
  47. package/src/__tests__/runtime.test.ts +13 -11
  48. package/src/brain/brain.ts +194 -65
  49. package/src/brain/intelligence.ts +1061 -0
  50. package/src/brain/types.ts +176 -0
  51. package/src/cognee/client.ts +352 -0
  52. package/src/cognee/types.ts +62 -0
  53. package/src/curator/curator.ts +52 -15
  54. package/src/index.ts +26 -1
  55. package/src/llm/llm-client.ts +18 -24
  56. package/src/runtime/core-ops.ts +219 -26
  57. package/src/runtime/runtime.ts +5 -0
  58. package/src/runtime/types.ts +2 -0
@@ -34,8 +34,8 @@ describe('createCoreOps', () => {
34
34
  return op;
35
35
  }
36
36
 
37
- it('should return 26 ops', () => {
38
- expect(ops.length).toBe(26);
37
+ it('should return 37 ops', () => {
38
+ expect(ops.length).toBe(37);
39
39
  });
40
40
 
41
41
  it('should have all expected op names', () => {
@@ -63,6 +63,18 @@ describe('createCoreOps', () => {
63
63
  expect(names).toContain('rebuild_vocabulary');
64
64
  expect(names).toContain('brain_stats');
65
65
  expect(names).toContain('llm_status');
66
+ // Brain Intelligence
67
+ expect(names).toContain('brain_session_context');
68
+ expect(names).toContain('brain_strengths');
69
+ expect(names).toContain('brain_global_patterns');
70
+ expect(names).toContain('brain_recommend');
71
+ expect(names).toContain('brain_build_intelligence');
72
+ expect(names).toContain('brain_export');
73
+ expect(names).toContain('brain_import');
74
+ expect(names).toContain('brain_extract_knowledge');
75
+ expect(names).toContain('brain_archive_sessions');
76
+ expect(names).toContain('brain_promote_proposals');
77
+ expect(names).toContain('brain_lifecycle');
66
78
  // Curator
67
79
  expect(names).toContain('curator_status');
68
80
  expect(names).toContain('curator_detect_duplicates');
@@ -75,58 +87,65 @@ describe('createCoreOps', () => {
75
87
  });
76
88
 
77
89
  it('search should query vault via brain', async () => {
78
- runtime.vault.seed([{
79
- id: 'co-1',
80
- type: 'pattern',
81
- domain: 'testing',
82
- title: 'Test pattern for core ops',
83
- severity: 'warning',
84
- description: 'Core ops test.',
85
- tags: ['test'],
86
- }]);
90
+ runtime.vault.seed([
91
+ {
92
+ id: 'co-1',
93
+ type: 'pattern',
94
+ domain: 'testing',
95
+ title: 'Test pattern for core ops',
96
+ severity: 'warning',
97
+ description: 'Core ops test.',
98
+ tags: ['test'],
99
+ },
100
+ ]);
87
101
  runtime.brain.rebuildVocabulary();
88
102
 
89
103
  // Re-create ops since brain state changed
90
104
  ops = createCoreOps(runtime);
91
- const results = await findOp('search').handler({ query: 'core ops test' }) as unknown[];
105
+ const results = (await findOp('search').handler({ query: 'core ops test' })) as unknown[];
92
106
  expect(results.length).toBeGreaterThan(0);
93
107
  });
94
108
 
95
109
  it('vault_stats should return counts', async () => {
96
- runtime.vault.seed([{
97
- id: 'vs-1',
98
- type: 'pattern',
99
- domain: 'd1',
100
- title: 'T',
101
- severity: 'warning',
102
- description: 'D',
103
- tags: ['t'],
104
- }]);
105
- const stats = await findOp('vault_stats').handler({}) as { totalEntries: number };
110
+ runtime.vault.seed([
111
+ {
112
+ id: 'vs-1',
113
+ type: 'pattern',
114
+ domain: 'd1',
115
+ title: 'T',
116
+ severity: 'warning',
117
+ description: 'D',
118
+ tags: ['t'],
119
+ },
120
+ ]);
121
+ const stats = (await findOp('vault_stats').handler({})) as { totalEntries: number };
106
122
  expect(stats.totalEntries).toBe(1);
107
123
  });
108
124
 
109
125
  it('create_plan + get_plan should work', async () => {
110
- const created = await findOp('create_plan').handler({
126
+ const created = (await findOp('create_plan').handler({
111
127
  objective: 'Test plan',
112
128
  scope: 'core-ops test',
113
129
  tasks: [{ title: 'Task 1', description: 'Do something' }],
114
- }) as { created: boolean; plan: { id: string; status: string } };
130
+ })) as { created: boolean; plan: { id: string; status: string } };
115
131
  expect(created.created).toBe(true);
116
132
  expect(created.plan.status).toBe('draft');
117
133
 
118
- const plan = await findOp('get_plan').handler({ planId: created.plan.id }) as { id: string };
134
+ const plan = (await findOp('get_plan').handler({ planId: created.plan.id })) as { id: string };
119
135
  expect(plan.id).toBe(created.plan.id);
120
136
  });
121
137
 
122
138
  it('brain_stats should return stats', async () => {
123
- const stats = await findOp('brain_stats').handler({}) as { vocabularySize: number; feedbackCount: number };
139
+ const stats = (await findOp('brain_stats').handler({})) as {
140
+ vocabularySize: number;
141
+ feedbackCount: number;
142
+ };
124
143
  expect(stats.vocabularySize).toBe(0);
125
144
  expect(stats.feedbackCount).toBe(0);
126
145
  });
127
146
 
128
147
  it('llm_status should return provider info', async () => {
129
- const status = await findOp('llm_status').handler({}) as {
148
+ const status = (await findOp('llm_status').handler({})) as {
130
149
  providers: {
131
150
  openai: { available: boolean };
132
151
  anthropic: { available: boolean };
@@ -139,22 +158,24 @@ describe('createCoreOps', () => {
139
158
  });
140
159
 
141
160
  it('curator_status should return initialized', async () => {
142
- const status = await findOp('curator_status').handler({}) as { initialized: boolean };
161
+ const status = (await findOp('curator_status').handler({})) as { initialized: boolean };
143
162
  expect(status.initialized).toBe(true);
144
163
  });
145
164
 
146
165
  it('curator_health_audit should return score', async () => {
147
- runtime.vault.seed([{
148
- id: 'ha-1',
149
- type: 'pattern',
150
- domain: 'testing',
151
- title: 'Health pattern',
152
- severity: 'warning',
153
- description: 'Testing health.',
154
- tags: ['health'],
155
- }]);
166
+ runtime.vault.seed([
167
+ {
168
+ id: 'ha-1',
169
+ type: 'pattern',
170
+ domain: 'testing',
171
+ title: 'Health pattern',
172
+ severity: 'warning',
173
+ description: 'Testing health.',
174
+ tags: ['health'],
175
+ },
176
+ ]);
156
177
  runtime.curator.groomAll();
157
- const result = await findOp('curator_health_audit').handler({}) as { score: number };
178
+ const result = (await findOp('curator_health_audit').handler({})) as { score: number };
158
179
  expect(result.score).toBeGreaterThan(0);
159
180
  });
160
181
 
@@ -169,21 +190,28 @@ describe('createCoreOps', () => {
169
190
  toolsUsed: [],
170
191
  });
171
192
 
172
- const results = await findOp('memory_search').handler({ query: 'core ops memory' }) as unknown[];
193
+ const results = (await findOp('memory_search').handler({
194
+ query: 'core ops memory',
195
+ })) as unknown[];
173
196
  expect(results.length).toBeGreaterThan(0);
174
197
  });
175
198
 
176
199
  it('export should return bundles', async () => {
177
- runtime.vault.seed([{
178
- id: 'exp-1',
179
- type: 'pattern',
180
- domain: 'security',
181
- title: 'Export test',
182
- severity: 'warning',
183
- description: 'Testing export.',
184
- tags: ['export'],
185
- }]);
186
- const result = await findOp('export').handler({}) as { exported: boolean; totalEntries: number };
200
+ runtime.vault.seed([
201
+ {
202
+ id: 'exp-1',
203
+ type: 'pattern',
204
+ domain: 'security',
205
+ title: 'Export test',
206
+ severity: 'warning',
207
+ description: 'Testing export.',
208
+ tags: ['export'],
209
+ },
210
+ ]);
211
+ const result = (await findOp('export').handler({})) as {
212
+ exported: boolean;
213
+ totalEntries: number;
214
+ };
187
215
  expect(result.exported).toBe(true);
188
216
  expect(result.totalEntries).toBe(1);
189
217
  });
@@ -121,8 +121,16 @@ describe('Curator', () => {
121
121
  describe('Duplicate Detection', () => {
122
122
  it('should detect duplicates above threshold', () => {
123
123
  vault.seed([
124
- makeEntry({ id: 'dup-1', title: 'Use semantic tokens for colors', description: 'Always use semantic tokens instead of raw hex values for color styling.' }),
125
- makeEntry({ id: 'dup-2', title: 'Use semantic tokens for color values', description: 'Prefer semantic color tokens over raw hex or rgb values in styling.' }),
124
+ makeEntry({
125
+ id: 'dup-1',
126
+ title: 'Use semantic tokens for colors',
127
+ description: 'Always use semantic tokens instead of raw hex values for color styling.',
128
+ }),
129
+ makeEntry({
130
+ id: 'dup-2',
131
+ title: 'Use semantic tokens for color values',
132
+ description: 'Prefer semantic color tokens over raw hex or rgb values in styling.',
133
+ }),
126
134
  ]);
127
135
  const results = curator.detectDuplicates(undefined, 0.3);
128
136
  expect(results.length).toBeGreaterThan(0);
@@ -134,8 +142,16 @@ describe('Curator', () => {
134
142
 
135
143
  it('should not detect duplicates below threshold', () => {
136
144
  vault.seed([
137
- makeEntry({ id: 'uniq-1', title: 'Database indexing strategies', description: 'Create indices on frequently queried columns.' }),
138
- makeEntry({ id: 'uniq-2', title: 'React component lifecycle', description: 'Use useEffect for side effects in functional components.' }),
145
+ makeEntry({
146
+ id: 'uniq-1',
147
+ title: 'Database indexing strategies',
148
+ description: 'Create indices on frequently queried columns.',
149
+ }),
150
+ makeEntry({
151
+ id: 'uniq-2',
152
+ title: 'React component lifecycle',
153
+ description: 'Use useEffect for side effects in functional components.',
154
+ }),
139
155
  ]);
140
156
  const results = curator.detectDuplicates(undefined, 0.8);
141
157
  expect(results.length).toBe(0);
@@ -143,9 +159,21 @@ describe('Curator', () => {
143
159
 
144
160
  it('should detect duplicates for a specific entry', () => {
145
161
  vault.seed([
146
- makeEntry({ id: 'spec-1', title: 'Authentication with JWT tokens', description: 'Use JSON Web Tokens for stateless authentication.' }),
147
- makeEntry({ id: 'spec-2', title: 'JWT token authentication pattern', description: 'Implement JWT-based authentication for API endpoints.' }),
148
- makeEntry({ id: 'spec-3', title: 'Database connection pooling', description: 'Use connection pools for efficient database access.' }),
162
+ makeEntry({
163
+ id: 'spec-1',
164
+ title: 'Authentication with JWT tokens',
165
+ description: 'Use JSON Web Tokens for stateless authentication.',
166
+ }),
167
+ makeEntry({
168
+ id: 'spec-2',
169
+ title: 'JWT token authentication pattern',
170
+ description: 'Implement JWT-based authentication for API endpoints.',
171
+ }),
172
+ makeEntry({
173
+ id: 'spec-3',
174
+ title: 'Database connection pooling',
175
+ description: 'Use connection pools for efficient database access.',
176
+ }),
149
177
  ]);
150
178
  const results = curator.detectDuplicates('spec-1', 0.3);
151
179
  expect(results.length).toBe(1);
@@ -154,8 +182,16 @@ describe('Curator', () => {
154
182
 
155
183
  it('should suggest merge for high similarity', () => {
156
184
  vault.seed([
157
- makeEntry({ id: 'merge-1', title: 'Validate user input', description: 'Always validate and sanitize user input before processing.' }),
158
- makeEntry({ id: 'merge-2', title: 'Validate user input', description: 'Always validate and sanitize user input before processing.' }),
185
+ makeEntry({
186
+ id: 'merge-1',
187
+ title: 'Validate user input',
188
+ description: 'Always validate and sanitize user input before processing.',
189
+ }),
190
+ makeEntry({
191
+ id: 'merge-2',
192
+ title: 'Validate user input',
193
+ description: 'Always validate and sanitize user input before processing.',
194
+ }),
159
195
  ]);
160
196
  const results = curator.detectDuplicates(undefined, 0.3);
161
197
  if (results.length > 0 && results[0].matches.length > 0) {
@@ -185,7 +221,8 @@ describe('Curator', () => {
185
221
  id: 'ap-inline',
186
222
  type: 'anti-pattern',
187
223
  title: 'Avoid inline styles for styling',
188
- description: 'Never use inline styles — prefer CSS classes or Tailwind utilities for styling.',
224
+ description:
225
+ 'Never use inline styles — prefer CSS classes or Tailwind utilities for styling.',
189
226
  tags: ['styling'],
190
227
  }),
191
228
  ]);
@@ -219,8 +256,18 @@ describe('Curator', () => {
219
256
 
220
257
  it('should respect UNIQUE constraint — no duplicate contradictions', () => {
221
258
  vault.seed([
222
- makeEntry({ id: 'p-dup', type: 'pattern', title: 'Use inline styles', description: 'Apply inline styles for dynamic values.' }),
223
- makeEntry({ id: 'ap-dup', type: 'anti-pattern', title: 'Avoid inline styles', description: 'Do not use inline styles.' }),
259
+ makeEntry({
260
+ id: 'p-dup',
261
+ type: 'pattern',
262
+ title: 'Use inline styles',
263
+ description: 'Apply inline styles for dynamic values.',
264
+ }),
265
+ makeEntry({
266
+ id: 'ap-dup',
267
+ type: 'anti-pattern',
268
+ title: 'Avoid inline styles',
269
+ description: 'Do not use inline styles.',
270
+ }),
224
271
  ]);
225
272
  curator.detectContradictions(0.2);
226
273
  const first = curator.getContradictions();
@@ -231,8 +278,18 @@ describe('Curator', () => {
231
278
 
232
279
  it('should resolve a contradiction', () => {
233
280
  vault.seed([
234
- makeEntry({ id: 'p-res', type: 'pattern', title: 'Use inline styles', description: 'Apply inline styles.' }),
235
- makeEntry({ id: 'ap-res', type: 'anti-pattern', title: 'Avoid inline styles', description: 'Do not use inline styles.' }),
281
+ makeEntry({
282
+ id: 'p-res',
283
+ type: 'pattern',
284
+ title: 'Use inline styles',
285
+ description: 'Apply inline styles.',
286
+ }),
287
+ makeEntry({
288
+ id: 'ap-res',
289
+ type: 'anti-pattern',
290
+ title: 'Avoid inline styles',
291
+ description: 'Do not use inline styles.',
292
+ }),
236
293
  ]);
237
294
  curator.detectContradictions(0.2);
238
295
  const all = curator.getContradictions();
@@ -245,8 +302,18 @@ describe('Curator', () => {
245
302
 
246
303
  it('should dismiss a contradiction', () => {
247
304
  vault.seed([
248
- makeEntry({ id: 'p-dis', type: 'pattern', title: 'Use inline styles', description: 'Apply inline styles.' }),
249
- makeEntry({ id: 'ap-dis', type: 'anti-pattern', title: 'Avoid inline styles', description: 'Do not use inline styles.' }),
305
+ makeEntry({
306
+ id: 'p-dis',
307
+ type: 'pattern',
308
+ title: 'Use inline styles',
309
+ description: 'Apply inline styles.',
310
+ }),
311
+ makeEntry({
312
+ id: 'ap-dis',
313
+ type: 'anti-pattern',
314
+ title: 'Avoid inline styles',
315
+ description: 'Do not use inline styles.',
316
+ }),
250
317
  ]);
251
318
  curator.detectContradictions(0.2);
252
319
  const all = curator.getContradictions();
@@ -256,8 +323,18 @@ describe('Curator', () => {
256
323
 
257
324
  it('should list by status', () => {
258
325
  vault.seed([
259
- makeEntry({ id: 'p-ls', type: 'pattern', title: 'Use inline styles', description: 'Apply inline styles.' }),
260
- makeEntry({ id: 'ap-ls', type: 'anti-pattern', title: 'Avoid inline styles', description: 'Do not use inline styles.' }),
326
+ makeEntry({
327
+ id: 'p-ls',
328
+ type: 'pattern',
329
+ title: 'Use inline styles',
330
+ description: 'Apply inline styles.',
331
+ }),
332
+ makeEntry({
333
+ id: 'ap-ls',
334
+ type: 'anti-pattern',
335
+ title: 'Avoid inline styles',
336
+ description: 'Do not use inline styles.',
337
+ }),
261
338
  ]);
262
339
  curator.detectContradictions(0.2);
263
340
  const open = curator.getContradictions('open');
@@ -295,7 +372,9 @@ describe('Curator', () => {
295
372
  curator.groomEntry('groom-state');
296
373
 
297
374
  const db = vault.getDb();
298
- const row = db.prepare('SELECT * FROM curator_entry_state WHERE entry_id = ?').get('groom-state') as Record<string, unknown>;
375
+ const row = db
376
+ .prepare('SELECT * FROM curator_entry_state WHERE entry_id = ?')
377
+ .get('groom-state') as Record<string, unknown>;
299
378
  expect(row).toBeDefined();
300
379
  expect(row.status).toBe('active');
301
380
  expect(row.last_groomed_at).not.toBeNull();
@@ -336,8 +415,16 @@ describe('Curator', () => {
336
415
 
337
416
  it('should find issues in dry-run', () => {
338
417
  vault.seed([
339
- makeEntry({ id: 'con-1', title: 'Validate user input thoroughly', description: 'Always validate and sanitize all user input before processing.' }),
340
- makeEntry({ id: 'con-2', title: 'Validate user input thoroughly', description: 'Always validate and sanitize all user input before processing.' }),
418
+ makeEntry({
419
+ id: 'con-1',
420
+ title: 'Validate user input thoroughly',
421
+ description: 'Always validate and sanitize all user input before processing.',
422
+ }),
423
+ makeEntry({
424
+ id: 'con-2',
425
+ title: 'Validate user input thoroughly',
426
+ description: 'Always validate and sanitize all user input before processing.',
427
+ }),
341
428
  ]);
342
429
  const result = curator.consolidate({ dryRun: true, duplicateThreshold: 0.3 });
343
430
  expect(result.dryRun).toBe(true);
@@ -369,14 +456,24 @@ describe('Curator', () => {
369
456
  expect(result.mutations).toBeGreaterThan(0);
370
457
 
371
458
  // Check that entry state was archived
372
- const row = db.prepare('SELECT status FROM curator_entry_state WHERE entry_id = ?').get('stale-con') as { status: string };
459
+ const row = db
460
+ .prepare('SELECT status FROM curator_entry_state WHERE entry_id = ?')
461
+ .get('stale-con') as { status: string };
373
462
  expect(row.status).toBe('archived');
374
463
  });
375
464
 
376
465
  it('should remove duplicates when not dry-run', () => {
377
466
  vault.seed([
378
- makeEntry({ id: 'rem-1', title: 'Duplicate pattern for removal', description: 'This is a duplicate pattern that should be removed during consolidation.' }),
379
- makeEntry({ id: 'rem-2', title: 'Duplicate pattern for removal', description: 'This is a duplicate pattern that should be removed during consolidation.' }),
467
+ makeEntry({
468
+ id: 'rem-1',
469
+ title: 'Duplicate pattern for removal',
470
+ description: 'This is a duplicate pattern that should be removed during consolidation.',
471
+ }),
472
+ makeEntry({
473
+ id: 'rem-2',
474
+ title: 'Duplicate pattern for removal',
475
+ description: 'This is a duplicate pattern that should be removed during consolidation.',
476
+ }),
380
477
  ]);
381
478
  const result = curator.consolidate({ dryRun: false, duplicateThreshold: 0.3 });
382
479
  expect(result.mutations).toBeGreaterThan(0);
@@ -440,9 +537,7 @@ describe('Curator', () => {
440
537
  });
441
538
 
442
539
  it('should penalize for missing entry types', () => {
443
- vault.seed([
444
- makeEntry({ id: 'h-p1', type: 'pattern', tags: ['x'] }),
445
- ]);
540
+ vault.seed([makeEntry({ id: 'h-p1', type: 'pattern', tags: ['x'] })]);
446
541
  curator.groomAll();
447
542
  const result = curator.healthAudit();
448
543
  expect(result.score).toBeLessThan(100);
@@ -451,9 +546,7 @@ describe('Curator', () => {
451
546
  });
452
547
 
453
548
  it('should recommend actions for issues', () => {
454
- vault.seed([
455
- makeEntry({ id: 'h-rec', type: 'pattern', tags: [] }),
456
- ]);
549
+ vault.seed([makeEntry({ id: 'h-rec', type: 'pattern', tags: [] })]);
457
550
  const result = curator.healthAudit();
458
551
  expect(result.recommendations.length).toBeGreaterThan(0);
459
552
  });
@@ -461,7 +554,9 @@ describe('Curator', () => {
461
554
  it('should handle empty vault gracefully', () => {
462
555
  const result = curator.healthAudit();
463
556
  expect(result.score).toBe(100);
464
- expect(result.recommendations).toContain('Vault is empty — add knowledge entries to get started.');
557
+ expect(result.recommendations).toContain(
558
+ 'Vault is empty — add knowledge entries to get started.',
559
+ );
465
560
  });
466
561
 
467
562
  it('should include tag health metrics', () => {
@@ -41,12 +41,28 @@ describe('createDomainFacade', () => {
41
41
 
42
42
  it('get_patterns should scope to domain', async () => {
43
43
  runtime.vault.seed([
44
- { id: 'sec-1', type: 'pattern', domain: 'security', title: 'Auth', severity: 'warning', description: 'Auth.', tags: ['auth'] },
45
- { id: 'api-1', type: 'pattern', domain: 'api-design', title: 'REST', severity: 'warning', description: 'REST.', tags: ['rest'] },
44
+ {
45
+ id: 'sec-1',
46
+ type: 'pattern',
47
+ domain: 'security',
48
+ title: 'Auth',
49
+ severity: 'warning',
50
+ description: 'Auth.',
51
+ tags: ['auth'],
52
+ },
53
+ {
54
+ id: 'api-1',
55
+ type: 'pattern',
56
+ domain: 'api-design',
57
+ title: 'REST',
58
+ severity: 'warning',
59
+ description: 'REST.',
60
+ tags: ['rest'],
61
+ },
46
62
  ]);
47
63
  const facade = createDomainFacade(runtime, 'test-domain', 'security');
48
64
  const op = facade.ops.find((o) => o.name === 'get_patterns')!;
49
- const results = await op.handler({}) as IntelligenceEntry[];
65
+ const results = (await op.handler({})) as IntelligenceEntry[];
50
66
  expect(results.every((e) => e.domain === 'security')).toBe(true);
51
67
  });
52
68
 
@@ -68,29 +84,45 @@ describe('createDomainFacade', () => {
68
84
 
69
85
  it('remove should delete entry', async () => {
70
86
  runtime.vault.seed([
71
- { id: 'rm-1', type: 'pattern', domain: 'security', title: 'Remove me', severity: 'warning', description: 'Remove.', tags: ['test'] },
87
+ {
88
+ id: 'rm-1',
89
+ type: 'pattern',
90
+ domain: 'security',
91
+ title: 'Remove me',
92
+ severity: 'warning',
93
+ description: 'Remove.',
94
+ tags: ['test'],
95
+ },
72
96
  ]);
73
97
  const facade = createDomainFacade(runtime, 'test-domain', 'security');
74
98
  const removeOp = facade.ops.find((o) => o.name === 'remove')!;
75
- const result = await removeOp.handler({ id: 'rm-1' }) as { removed: boolean };
99
+ const result = (await removeOp.handler({ id: 'rm-1' })) as { removed: boolean };
76
100
  expect(result.removed).toBe(true);
77
101
  expect(runtime.vault.get('rm-1')).toBeNull();
78
102
  });
79
103
 
80
104
  it('get_entry should return specific entry', async () => {
81
105
  runtime.vault.seed([
82
- { id: 'ge-1', type: 'pattern', domain: 'security', title: 'Get me', severity: 'warning', description: 'Get.', tags: ['test'] },
106
+ {
107
+ id: 'ge-1',
108
+ type: 'pattern',
109
+ domain: 'security',
110
+ title: 'Get me',
111
+ severity: 'warning',
112
+ description: 'Get.',
113
+ tags: ['test'],
114
+ },
83
115
  ]);
84
116
  const facade = createDomainFacade(runtime, 'test-domain', 'security');
85
117
  const getOp = facade.ops.find((o) => o.name === 'get_entry')!;
86
- const result = await getOp.handler({ id: 'ge-1' }) as IntelligenceEntry;
118
+ const result = (await getOp.handler({ id: 'ge-1' })) as IntelligenceEntry;
87
119
  expect(result.id).toBe('ge-1');
88
120
  });
89
121
 
90
122
  it('get_entry should return error for missing entry', async () => {
91
123
  const facade = createDomainFacade(runtime, 'test-domain', 'security');
92
124
  const getOp = facade.ops.find((o) => o.name === 'get_entry')!;
93
- const result = await getOp.handler({ id: 'nope' }) as { error: string };
125
+ const result = (await getOp.handler({ id: 'nope' })) as { error: string };
94
126
  expect(result.error).toBeDefined();
95
127
  });
96
128
  });
@@ -110,7 +142,11 @@ describe('createDomainFacades', () => {
110
142
  });
111
143
 
112
144
  it('should create one facade per domain', () => {
113
- const facades = createDomainFacades(runtime, 'test-multi', ['security', 'api-design', 'testing']);
145
+ const facades = createDomainFacades(runtime, 'test-multi', [
146
+ 'security',
147
+ 'api-design',
148
+ 'testing',
149
+ ]);
114
150
  expect(facades.length).toBe(3);
115
151
  expect(facades[0].name).toBe('test-multi_security');
116
152
  expect(facades[1].name).toBe('test-multi_api_design');
@@ -58,26 +58,28 @@ describe('createAgentRuntime', () => {
58
58
  runtime = null; // already closed
59
59
  });
60
60
 
61
- it('brain should be wired to vault', () => {
61
+ it('brain should be wired to vault', async () => {
62
62
  runtime = createAgentRuntime({
63
63
  agentId: 'test-brain-wire',
64
64
  vaultPath: ':memory:',
65
65
  });
66
66
 
67
67
  // Seed some data through vault
68
- runtime.vault.seed([{
69
- id: 'rt-1',
70
- type: 'pattern',
71
- domain: 'testing',
72
- title: 'Runtime test pattern',
73
- severity: 'warning',
74
- description: 'A test.',
75
- tags: ['test'],
76
- }]);
68
+ runtime.vault.seed([
69
+ {
70
+ id: 'rt-1',
71
+ type: 'pattern',
72
+ domain: 'testing',
73
+ title: 'Runtime test pattern',
74
+ severity: 'warning',
75
+ description: 'A test.',
76
+ tags: ['test'],
77
+ },
78
+ ]);
77
79
 
78
80
  // Brain should find it
79
81
  runtime.brain.rebuildVocabulary();
80
- const results = runtime.brain.intelligentSearch('runtime test', { limit: 5 });
82
+ const results = await runtime.brain.intelligentSearch('runtime test', { limit: 5 });
81
83
  expect(results.length).toBeGreaterThan(0);
82
84
  });
83
85