@soleri/forge 4.2.0 → 4.2.1

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.
@@ -42,6 +42,8 @@ describe('Facades', () => {
42
42
  let openaiKeyPool: KeyPool;
43
43
  let anthropicKeyPool: KeyPool;
44
44
  let llmClient: LLMClient;
45
+ const makeCoreFacade = () =>
46
+ createCoreFacade(vault, planner, brain, undefined, llmClient, openaiKeyPool, anthropicKeyPool);
45
47
 
46
48
  beforeEach(() => {
47
49
  vault = new Vault(':memory:');
@@ -63,7 +65,7 @@ ${domainDescribes}
63
65
 
64
66
  describe('${config.id}_core', () => {
65
67
  it('should create core facade with expected ops', () => {
66
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
68
+ const facade = makeCoreFacade();
67
69
  expect(facade.name).toBe('${config.id}_core');
68
70
  const opNames = facade.ops.map((o) => o.name);
69
71
  expect(opNames).toContain('search');
@@ -84,7 +86,7 @@ ${domainDescribes}
84
86
  makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
85
87
  ]);
86
88
  brain = new Brain(vault);
87
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
89
+ const facade = makeCoreFacade();
88
90
  const searchOp = facade.ops.find((o) => o.name === 'search')!;
89
91
  const results = (await searchOp.handler({ query: 'pattern' })) as Array<{ entry: unknown; score: number; breakdown: unknown }>;
90
92
  expect(Array.isArray(results)).toBe(true);
@@ -98,21 +100,21 @@ ${domainDescribes}
98
100
  makeEntry({ id: 'vs1', domain: 'd1', tags: ['x'] }),
99
101
  makeEntry({ id: 'vs2', domain: 'd2', tags: ['y'] }),
100
102
  ]);
101
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
103
+ const facade = makeCoreFacade();
102
104
  const statsOp = facade.ops.find((o) => o.name === 'vault_stats')!;
103
105
  const stats = (await statsOp.handler({})) as { totalEntries: number };
104
106
  expect(stats.totalEntries).toBe(2);
105
107
  });
106
108
 
107
109
  it('health should return ok status', async () => {
108
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
110
+ const facade = makeCoreFacade();
109
111
  const healthOp = facade.ops.find((o) => o.name === 'health')!;
110
112
  const health = (await healthOp.handler({})) as { status: string };
111
113
  expect(health.status).toBe('ok');
112
114
  });
113
115
 
114
116
  it('identity should return persona', async () => {
115
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
117
+ const facade = makeCoreFacade();
116
118
  const identityOp = facade.ops.find((o) => o.name === 'identity')!;
117
119
  const persona = (await identityOp.handler({})) as { name: string; role: string };
118
120
  expect(persona.name).toBe('${escapeQuotes(config.name)}');
@@ -124,14 +126,14 @@ ${domainDescribes}
124
126
  makeEntry({ id: 'la1', domain: 'alpha', tags: ['a'] }),
125
127
  makeEntry({ id: 'la2', domain: 'beta', tags: ['b'] }),
126
128
  ]);
127
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
129
+ const facade = makeCoreFacade();
128
130
  const listOp = facade.ops.find((o) => o.name === 'list_all')!;
129
131
  const filtered = (await listOp.handler({ domain: 'alpha' })) as unknown[];
130
132
  expect(filtered).toHaveLength(1);
131
133
  });
132
134
 
133
135
  it('activate should return persona and setup status', async () => {
134
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
136
+ const facade = makeCoreFacade();
135
137
  const activateOp = facade.ops.find((o) => o.name === 'activate')!;
136
138
  const result = (await activateOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
137
139
  activated: boolean;
@@ -150,7 +152,7 @@ ${domainDescribes}
150
152
  });
151
153
 
152
154
  it('activate with deactivate flag should return deactivation', async () => {
153
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
155
+ const facade = makeCoreFacade();
154
156
  const activateOp = facade.ops.find((o) => o.name === 'activate')!;
155
157
  const result = (await activateOp.handler({ deactivate: true })) as { deactivated: boolean; message: string };
156
158
  expect(result.deactivated).toBe(true);
@@ -161,7 +163,7 @@ ${domainDescribes}
161
163
  const tempDir = join(tmpdir(), 'forge-inject-test-' + Date.now());
162
164
  mkdirSync(tempDir, { recursive: true });
163
165
  try {
164
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
166
+ const facade = makeCoreFacade();
165
167
  const injectOp = facade.ops.find((o) => o.name === 'inject_claude_md')!;
166
168
  const result = (await injectOp.handler({ projectPath: tempDir })) as {
167
169
  injected: boolean;
@@ -181,7 +183,7 @@ ${domainDescribes}
181
183
  it('inject_claude_md with global flag should target ~/.claude/CLAUDE.md', async () => {
182
184
  // We test the global path resolution by checking the returned path
183
185
  // contains .claude/CLAUDE.md (actual write may or may not happen depending on env)
184
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
186
+ const facade = makeCoreFacade();
185
187
  const injectOp = facade.ops.find((o) => o.name === 'inject_claude_md')!;
186
188
  const result = (await injectOp.handler({ global: true })) as {
187
189
  injected: boolean;
@@ -194,7 +196,7 @@ ${domainDescribes}
194
196
  });
195
197
 
196
198
  it('setup should return project and global CLAUDE.md status', async () => {
197
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
199
+ const facade = makeCoreFacade();
198
200
  const setupOp = facade.ops.find((o) => o.name === 'setup')!;
199
201
  const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
200
202
  agent: { name: string };
@@ -213,7 +215,7 @@ ${domainDescribes}
213
215
  });
214
216
 
215
217
  it('register should track new project', async () => {
216
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
218
+ const facade = makeCoreFacade();
217
219
  const registerOp = facade.ops.find((o) => o.name === 'register')!;
218
220
  const result = (await registerOp.handler({ projectPath: '/tmp/reg-test-project', name: 'reg-test' })) as {
219
221
  project: { path: string; name: string; sessionCount: number };
@@ -228,7 +230,7 @@ ${domainDescribes}
228
230
  });
229
231
 
230
232
  it('register should increment session count for returning project', async () => {
231
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
233
+ const facade = makeCoreFacade();
232
234
  const registerOp = facade.ops.find((o) => o.name === 'register')!;
233
235
  await registerOp.handler({ projectPath: '/tmp/reg-test-returning', name: 'returning' });
234
236
  const result = (await registerOp.handler({ projectPath: '/tmp/reg-test-returning', name: 'returning' })) as {
@@ -242,7 +244,7 @@ ${domainDescribes}
242
244
  });
243
245
 
244
246
  it('memory_capture should store a memory', async () => {
245
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
247
+ const facade = makeCoreFacade();
246
248
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
247
249
  const result = (await captureOp.handler({
248
250
  projectPath: '/test',
@@ -259,7 +261,7 @@ ${domainDescribes}
259
261
  });
260
262
 
261
263
  it('memory_search should find captured memories', async () => {
262
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
264
+ const facade = makeCoreFacade();
263
265
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
264
266
  await captureOp.handler({
265
267
  projectPath: '/test',
@@ -277,7 +279,7 @@ ${domainDescribes}
277
279
  });
278
280
 
279
281
  it('memory_list should return all memories with stats', async () => {
280
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
282
+ const facade = makeCoreFacade();
281
283
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
282
284
  await captureOp.handler({
283
285
  projectPath: '/test',
@@ -298,7 +300,7 @@ ${domainDescribes}
298
300
  });
299
301
 
300
302
  it('session_capture should store a session memory', async () => {
301
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
303
+ const facade = makeCoreFacade();
302
304
  const sessionOp = facade.ops.find((o) => o.name === 'session_capture')!;
303
305
  const result = (await sessionOp.handler({
304
306
  projectPath: '/tmp/test-session',
@@ -319,7 +321,7 @@ ${domainDescribes}
319
321
  makeEntry({ id: 'exp2', domain: 'security', tags: ['xss'] }),
320
322
  makeEntry({ id: 'exp3', domain: 'api-design', tags: ['rest'] }),
321
323
  ]);
322
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
324
+ const facade = makeCoreFacade();
323
325
  const exportOp = facade.ops.find((o) => o.name === 'export')!;
324
326
  const result = (await exportOp.handler({})) as {
325
327
  exported: boolean;
@@ -339,7 +341,7 @@ ${domainDescribes}
339
341
  makeEntry({ id: 'exp-d1', domain: 'security', tags: ['auth'] }),
340
342
  makeEntry({ id: 'exp-d2', domain: 'api-design', tags: ['rest'] }),
341
343
  ]);
342
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
344
+ const facade = makeCoreFacade();
343
345
  const exportOp = facade.ops.find((o) => o.name === 'export')!;
344
346
  const result = (await exportOp.handler({ domain: 'security' })) as {
345
347
  bundles: Array<{ domain: string; entries: unknown[] }>;
@@ -351,7 +353,7 @@ ${domainDescribes}
351
353
  });
352
354
 
353
355
  it('create_plan should create a draft plan', async () => {
354
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
356
+ const facade = makeCoreFacade();
355
357
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
356
358
  const result = (await createOp.handler({
357
359
  objective: 'Add caching',
@@ -364,7 +366,7 @@ ${domainDescribes}
364
366
  });
365
367
 
366
368
  it('get_plan should return a plan by id', async () => {
367
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
369
+ const facade = makeCoreFacade();
368
370
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
369
371
  const created = (await createOp.handler({ objective: 'Test', scope: 'test' })) as { plan: { id: string } };
370
372
  const getOp = facade.ops.find((o) => o.name === 'get_plan')!;
@@ -374,7 +376,7 @@ ${domainDescribes}
374
376
  });
375
377
 
376
378
  it('get_plan without id should return active plans', async () => {
377
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
379
+ const facade = makeCoreFacade();
378
380
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
379
381
  await createOp.handler({ objective: 'Plan A', scope: 'a' });
380
382
  const getOp = facade.ops.find((o) => o.name === 'get_plan')!;
@@ -384,7 +386,7 @@ ${domainDescribes}
384
386
  });
385
387
 
386
388
  it('approve_plan should approve and optionally start execution', async () => {
387
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
389
+ const facade = makeCoreFacade();
388
390
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
389
391
  const created = (await createOp.handler({ objective: 'Approve', scope: 'test' })) as { plan: { id: string } };
390
392
  const approveOp = facade.ops.find((o) => o.name === 'approve_plan')!;
@@ -399,7 +401,7 @@ ${domainDescribes}
399
401
  });
400
402
 
401
403
  it('update_task should update task status', async () => {
402
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
404
+ const facade = makeCoreFacade();
403
405
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
404
406
  const created = (await createOp.handler({
405
407
  objective: 'Task update',
@@ -419,7 +421,7 @@ ${domainDescribes}
419
421
  });
420
422
 
421
423
  it('complete_plan should complete with task summary', async () => {
422
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
424
+ const facade = makeCoreFacade();
423
425
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
424
426
  const created = (await createOp.handler({
425
427
  objective: 'Complete me',
@@ -446,7 +448,7 @@ ${domainDescribes}
446
448
  });
447
449
 
448
450
  it('should have brain ops in core facade', () => {
449
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
451
+ const facade = makeCoreFacade();
450
452
  const opNames = facade.ops.map((o) => o.name);
451
453
  expect(opNames).toContain('record_feedback');
452
454
  expect(opNames).toContain('rebuild_vocabulary');
@@ -454,7 +456,7 @@ ${domainDescribes}
454
456
  });
455
457
 
456
458
  it('record_feedback should record search feedback', async () => {
457
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
459
+ const facade = makeCoreFacade();
458
460
  const feedbackOp = facade.ops.find((o) => o.name === 'record_feedback')!;
459
461
  const result = (await feedbackOp.handler({
460
462
  query: 'test query',
@@ -471,7 +473,7 @@ ${domainDescribes}
471
473
  makeEntry({ id: 'rv1', title: 'Rebuild vocab test', description: 'Testing vocabulary rebuild.', tags: ['rebuild'] }),
472
474
  ]);
473
475
  brain = new Brain(vault);
474
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
476
+ const facade = makeCoreFacade();
475
477
  const rebuildOp = facade.ops.find((o) => o.name === 'rebuild_vocabulary')!;
476
478
  const result = (await rebuildOp.handler({})) as { rebuilt: boolean; vocabularySize: number };
477
479
  expect(result.rebuilt).toBe(true);
@@ -479,7 +481,7 @@ ${domainDescribes}
479
481
  });
480
482
 
481
483
  it('brain_stats should return intelligence stats', async () => {
482
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
484
+ const facade = makeCoreFacade();
483
485
  const statsOp = facade.ops.find((o) => o.name === 'brain_stats')!;
484
486
  const result = (await statsOp.handler({})) as {
485
487
  vocabularySize: number;
@@ -493,7 +495,7 @@ ${domainDescribes}
493
495
  });
494
496
 
495
497
  it('brain_stats should reflect feedback count after recording', async () => {
496
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
498
+ const facade = makeCoreFacade();
497
499
  const feedbackOp = facade.ops.find((o) => o.name === 'record_feedback')!;
498
500
  await feedbackOp.handler({ query: 'q1', entryId: 'e1', action: 'accepted' });
499
501
  await feedbackOp.handler({ query: 'q2', entryId: 'e2', action: 'dismissed' });
@@ -503,7 +505,7 @@ ${domainDescribes}
503
505
  });
504
506
 
505
507
  it('llm_status should return provider availability', async () => {
506
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
508
+ const facade = makeCoreFacade();
507
509
  const llmStatusOp = facade.ops.find((o) => o.name === 'llm_status')!;
508
510
  const result = (await llmStatusOp.handler({})) as {
509
511
  providers: {
@@ -522,7 +524,7 @@ ${domainDescribes}
522
524
  const oPool = new KeyPool({ keys: ['sk-test'] });
523
525
  const aPool = new KeyPool({ keys: ['sk-ant-test'] });
524
526
  const client = new LLMClient(oPool, aPool);
525
- const facade = createCoreFacade(vault, planner, brain, client, oPool, aPool);
527
+ const facade = createCoreFacade(vault, planner, brain, undefined, client, oPool, aPool);
526
528
  const llmStatusOp = facade.ops.find((o) => o.name === 'llm_status')!;
527
529
  const result = (await llmStatusOp.handler({})) as {
528
530
  providers: {
@@ -541,7 +543,7 @@ ${domainDescribes}
541
543
  makeEntry({ id: 'bs-1', domain: 'security', title: 'Authentication token handling', severity: 'critical', description: 'Always validate JWT tokens.', tags: ['auth', 'jwt'] }),
542
544
  ]);
543
545
  brain = new Brain(vault);
544
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
546
+ const facade = makeCoreFacade();
545
547
  const searchOp = facade.ops.find((o) => o.name === 'search')!;
546
548
  const results = (await searchOp.handler({ query: 'authentication token' })) as Array<{ entry: { id: string }; score: number; breakdown: { semantic: number; total: number } }>;
547
549
  expect(results.length).toBeGreaterThan(0);
@@ -1 +1 @@
1
- {"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleri/forge",
3
- "version": "4.2.0",
3
+ "version": "4.2.1",
4
4
  "description": "Scaffold AI agents that learn, remember, and grow with you.",
5
5
  "keywords": [
6
6
  "agent",
@@ -46,6 +46,8 @@ describe('Facades', () => {
46
46
  let openaiKeyPool: KeyPool;
47
47
  let anthropicKeyPool: KeyPool;
48
48
  let llmClient: LLMClient;
49
+ const makeCoreFacade = () =>
50
+ createCoreFacade(vault, planner, brain, undefined, llmClient, openaiKeyPool, anthropicKeyPool);
49
51
 
50
52
  beforeEach(() => {
51
53
  vault = new Vault(':memory:');
@@ -67,7 +69,7 @@ ${domainDescribes}
67
69
 
68
70
  describe('${config.id}_core', () => {
69
71
  it('should create core facade with expected ops', () => {
70
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
72
+ const facade = makeCoreFacade();
71
73
  expect(facade.name).toBe('${config.id}_core');
72
74
  const opNames = facade.ops.map((o) => o.name);
73
75
  expect(opNames).toContain('search');
@@ -88,7 +90,7 @@ ${domainDescribes}
88
90
  makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
89
91
  ]);
90
92
  brain = new Brain(vault);
91
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
93
+ const facade = makeCoreFacade();
92
94
  const searchOp = facade.ops.find((o) => o.name === 'search')!;
93
95
  const results = (await searchOp.handler({ query: 'pattern' })) as Array<{ entry: unknown; score: number; breakdown: unknown }>;
94
96
  expect(Array.isArray(results)).toBe(true);
@@ -102,21 +104,21 @@ ${domainDescribes}
102
104
  makeEntry({ id: 'vs1', domain: 'd1', tags: ['x'] }),
103
105
  makeEntry({ id: 'vs2', domain: 'd2', tags: ['y'] }),
104
106
  ]);
105
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
107
+ const facade = makeCoreFacade();
106
108
  const statsOp = facade.ops.find((o) => o.name === 'vault_stats')!;
107
109
  const stats = (await statsOp.handler({})) as { totalEntries: number };
108
110
  expect(stats.totalEntries).toBe(2);
109
111
  });
110
112
 
111
113
  it('health should return ok status', async () => {
112
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
114
+ const facade = makeCoreFacade();
113
115
  const healthOp = facade.ops.find((o) => o.name === 'health')!;
114
116
  const health = (await healthOp.handler({})) as { status: string };
115
117
  expect(health.status).toBe('ok');
116
118
  });
117
119
 
118
120
  it('identity should return persona', async () => {
119
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
121
+ const facade = makeCoreFacade();
120
122
  const identityOp = facade.ops.find((o) => o.name === 'identity')!;
121
123
  const persona = (await identityOp.handler({})) as { name: string; role: string };
122
124
  expect(persona.name).toBe('${escapeQuotes(config.name)}');
@@ -128,14 +130,14 @@ ${domainDescribes}
128
130
  makeEntry({ id: 'la1', domain: 'alpha', tags: ['a'] }),
129
131
  makeEntry({ id: 'la2', domain: 'beta', tags: ['b'] }),
130
132
  ]);
131
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
133
+ const facade = makeCoreFacade();
132
134
  const listOp = facade.ops.find((o) => o.name === 'list_all')!;
133
135
  const filtered = (await listOp.handler({ domain: 'alpha' })) as unknown[];
134
136
  expect(filtered).toHaveLength(1);
135
137
  });
136
138
 
137
139
  it('activate should return persona and setup status', async () => {
138
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
140
+ const facade = makeCoreFacade();
139
141
  const activateOp = facade.ops.find((o) => o.name === 'activate')!;
140
142
  const result = (await activateOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
141
143
  activated: boolean;
@@ -154,7 +156,7 @@ ${domainDescribes}
154
156
  });
155
157
 
156
158
  it('activate with deactivate flag should return deactivation', async () => {
157
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
159
+ const facade = makeCoreFacade();
158
160
  const activateOp = facade.ops.find((o) => o.name === 'activate')!;
159
161
  const result = (await activateOp.handler({ deactivate: true })) as { deactivated: boolean; message: string };
160
162
  expect(result.deactivated).toBe(true);
@@ -165,7 +167,7 @@ ${domainDescribes}
165
167
  const tempDir = join(tmpdir(), 'forge-inject-test-' + Date.now());
166
168
  mkdirSync(tempDir, { recursive: true });
167
169
  try {
168
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
170
+ const facade = makeCoreFacade();
169
171
  const injectOp = facade.ops.find((o) => o.name === 'inject_claude_md')!;
170
172
  const result = (await injectOp.handler({ projectPath: tempDir })) as {
171
173
  injected: boolean;
@@ -185,7 +187,7 @@ ${domainDescribes}
185
187
  it('inject_claude_md with global flag should target ~/.claude/CLAUDE.md', async () => {
186
188
  // We test the global path resolution by checking the returned path
187
189
  // contains .claude/CLAUDE.md (actual write may or may not happen depending on env)
188
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
190
+ const facade = makeCoreFacade();
189
191
  const injectOp = facade.ops.find((o) => o.name === 'inject_claude_md')!;
190
192
  const result = (await injectOp.handler({ global: true })) as {
191
193
  injected: boolean;
@@ -198,7 +200,7 @@ ${domainDescribes}
198
200
  });
199
201
 
200
202
  it('setup should return project and global CLAUDE.md status', async () => {
201
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
203
+ const facade = makeCoreFacade();
202
204
  const setupOp = facade.ops.find((o) => o.name === 'setup')!;
203
205
  const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
204
206
  agent: { name: string };
@@ -217,7 +219,7 @@ ${domainDescribes}
217
219
  });
218
220
 
219
221
  it('register should track new project', async () => {
220
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
222
+ const facade = makeCoreFacade();
221
223
  const registerOp = facade.ops.find((o) => o.name === 'register')!;
222
224
  const result = (await registerOp.handler({ projectPath: '/tmp/reg-test-project', name: 'reg-test' })) as {
223
225
  project: { path: string; name: string; sessionCount: number };
@@ -232,7 +234,7 @@ ${domainDescribes}
232
234
  });
233
235
 
234
236
  it('register should increment session count for returning project', async () => {
235
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
237
+ const facade = makeCoreFacade();
236
238
  const registerOp = facade.ops.find((o) => o.name === 'register')!;
237
239
  await registerOp.handler({ projectPath: '/tmp/reg-test-returning', name: 'returning' });
238
240
  const result = (await registerOp.handler({ projectPath: '/tmp/reg-test-returning', name: 'returning' })) as {
@@ -246,7 +248,7 @@ ${domainDescribes}
246
248
  });
247
249
 
248
250
  it('memory_capture should store a memory', async () => {
249
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
251
+ const facade = makeCoreFacade();
250
252
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
251
253
  const result = (await captureOp.handler({
252
254
  projectPath: '/test',
@@ -263,7 +265,7 @@ ${domainDescribes}
263
265
  });
264
266
 
265
267
  it('memory_search should find captured memories', async () => {
266
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
268
+ const facade = makeCoreFacade();
267
269
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
268
270
  await captureOp.handler({
269
271
  projectPath: '/test',
@@ -281,7 +283,7 @@ ${domainDescribes}
281
283
  });
282
284
 
283
285
  it('memory_list should return all memories with stats', async () => {
284
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
286
+ const facade = makeCoreFacade();
285
287
  const captureOp = facade.ops.find((o) => o.name === 'memory_capture')!;
286
288
  await captureOp.handler({
287
289
  projectPath: '/test',
@@ -302,7 +304,7 @@ ${domainDescribes}
302
304
  });
303
305
 
304
306
  it('session_capture should store a session memory', async () => {
305
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
307
+ const facade = makeCoreFacade();
306
308
  const sessionOp = facade.ops.find((o) => o.name === 'session_capture')!;
307
309
  const result = (await sessionOp.handler({
308
310
  projectPath: '/tmp/test-session',
@@ -323,7 +325,7 @@ ${domainDescribes}
323
325
  makeEntry({ id: 'exp2', domain: 'security', tags: ['xss'] }),
324
326
  makeEntry({ id: 'exp3', domain: 'api-design', tags: ['rest'] }),
325
327
  ]);
326
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
328
+ const facade = makeCoreFacade();
327
329
  const exportOp = facade.ops.find((o) => o.name === 'export')!;
328
330
  const result = (await exportOp.handler({})) as {
329
331
  exported: boolean;
@@ -343,7 +345,7 @@ ${domainDescribes}
343
345
  makeEntry({ id: 'exp-d1', domain: 'security', tags: ['auth'] }),
344
346
  makeEntry({ id: 'exp-d2', domain: 'api-design', tags: ['rest'] }),
345
347
  ]);
346
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
348
+ const facade = makeCoreFacade();
347
349
  const exportOp = facade.ops.find((o) => o.name === 'export')!;
348
350
  const result = (await exportOp.handler({ domain: 'security' })) as {
349
351
  bundles: Array<{ domain: string; entries: unknown[] }>;
@@ -355,7 +357,7 @@ ${domainDescribes}
355
357
  });
356
358
 
357
359
  it('create_plan should create a draft plan', async () => {
358
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
360
+ const facade = makeCoreFacade();
359
361
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
360
362
  const result = (await createOp.handler({
361
363
  objective: 'Add caching',
@@ -368,7 +370,7 @@ ${domainDescribes}
368
370
  });
369
371
 
370
372
  it('get_plan should return a plan by id', async () => {
371
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
373
+ const facade = makeCoreFacade();
372
374
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
373
375
  const created = (await createOp.handler({ objective: 'Test', scope: 'test' })) as { plan: { id: string } };
374
376
  const getOp = facade.ops.find((o) => o.name === 'get_plan')!;
@@ -378,7 +380,7 @@ ${domainDescribes}
378
380
  });
379
381
 
380
382
  it('get_plan without id should return active plans', async () => {
381
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
383
+ const facade = makeCoreFacade();
382
384
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
383
385
  await createOp.handler({ objective: 'Plan A', scope: 'a' });
384
386
  const getOp = facade.ops.find((o) => o.name === 'get_plan')!;
@@ -388,7 +390,7 @@ ${domainDescribes}
388
390
  });
389
391
 
390
392
  it('approve_plan should approve and optionally start execution', async () => {
391
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
393
+ const facade = makeCoreFacade();
392
394
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
393
395
  const created = (await createOp.handler({ objective: 'Approve', scope: 'test' })) as { plan: { id: string } };
394
396
  const approveOp = facade.ops.find((o) => o.name === 'approve_plan')!;
@@ -403,7 +405,7 @@ ${domainDescribes}
403
405
  });
404
406
 
405
407
  it('update_task should update task status', async () => {
406
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
408
+ const facade = makeCoreFacade();
407
409
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
408
410
  const created = (await createOp.handler({
409
411
  objective: 'Task update',
@@ -423,7 +425,7 @@ ${domainDescribes}
423
425
  });
424
426
 
425
427
  it('complete_plan should complete with task summary', async () => {
426
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
428
+ const facade = makeCoreFacade();
427
429
  const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
428
430
  const created = (await createOp.handler({
429
431
  objective: 'Complete me',
@@ -450,7 +452,7 @@ ${domainDescribes}
450
452
  });
451
453
 
452
454
  it('should have brain ops in core facade', () => {
453
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
455
+ const facade = makeCoreFacade();
454
456
  const opNames = facade.ops.map((o) => o.name);
455
457
  expect(opNames).toContain('record_feedback');
456
458
  expect(opNames).toContain('rebuild_vocabulary');
@@ -458,7 +460,7 @@ ${domainDescribes}
458
460
  });
459
461
 
460
462
  it('record_feedback should record search feedback', async () => {
461
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
463
+ const facade = makeCoreFacade();
462
464
  const feedbackOp = facade.ops.find((o) => o.name === 'record_feedback')!;
463
465
  const result = (await feedbackOp.handler({
464
466
  query: 'test query',
@@ -475,7 +477,7 @@ ${domainDescribes}
475
477
  makeEntry({ id: 'rv1', title: 'Rebuild vocab test', description: 'Testing vocabulary rebuild.', tags: ['rebuild'] }),
476
478
  ]);
477
479
  brain = new Brain(vault);
478
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
480
+ const facade = makeCoreFacade();
479
481
  const rebuildOp = facade.ops.find((o) => o.name === 'rebuild_vocabulary')!;
480
482
  const result = (await rebuildOp.handler({})) as { rebuilt: boolean; vocabularySize: number };
481
483
  expect(result.rebuilt).toBe(true);
@@ -483,7 +485,7 @@ ${domainDescribes}
483
485
  });
484
486
 
485
487
  it('brain_stats should return intelligence stats', async () => {
486
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
488
+ const facade = makeCoreFacade();
487
489
  const statsOp = facade.ops.find((o) => o.name === 'brain_stats')!;
488
490
  const result = (await statsOp.handler({})) as {
489
491
  vocabularySize: number;
@@ -497,7 +499,7 @@ ${domainDescribes}
497
499
  });
498
500
 
499
501
  it('brain_stats should reflect feedback count after recording', async () => {
500
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
502
+ const facade = makeCoreFacade();
501
503
  const feedbackOp = facade.ops.find((o) => o.name === 'record_feedback')!;
502
504
  await feedbackOp.handler({ query: 'q1', entryId: 'e1', action: 'accepted' });
503
505
  await feedbackOp.handler({ query: 'q2', entryId: 'e2', action: 'dismissed' });
@@ -507,7 +509,7 @@ ${domainDescribes}
507
509
  });
508
510
 
509
511
  it('llm_status should return provider availability', async () => {
510
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
512
+ const facade = makeCoreFacade();
511
513
  const llmStatusOp = facade.ops.find((o) => o.name === 'llm_status')!;
512
514
  const result = (await llmStatusOp.handler({})) as {
513
515
  providers: {
@@ -526,7 +528,7 @@ ${domainDescribes}
526
528
  const oPool = new KeyPool({ keys: ['sk-test'] });
527
529
  const aPool = new KeyPool({ keys: ['sk-ant-test'] });
528
530
  const client = new LLMClient(oPool, aPool);
529
- const facade = createCoreFacade(vault, planner, brain, client, oPool, aPool);
531
+ const facade = createCoreFacade(vault, planner, brain, undefined, client, oPool, aPool);
530
532
  const llmStatusOp = facade.ops.find((o) => o.name === 'llm_status')!;
531
533
  const result = (await llmStatusOp.handler({})) as {
532
534
  providers: {
@@ -545,7 +547,7 @@ ${domainDescribes}
545
547
  makeEntry({ id: 'bs-1', domain: 'security', title: 'Authentication token handling', severity: 'critical', description: 'Always validate JWT tokens.', tags: ['auth', 'jwt'] }),
546
548
  ]);
547
549
  brain = new Brain(vault);
548
- const facade = createCoreFacade(vault, planner, brain, llmClient, openaiKeyPool, anthropicKeyPool);
550
+ const facade = makeCoreFacade();
549
551
  const searchOp = facade.ops.find((o) => o.name === 'search')!;
550
552
  const results = (await searchOp.handler({ query: 'authentication token' })) as Array<{ entry: { id: string }; score: number; breakdown: { semantic: number; total: number } }>;
551
553
  expect(results.length).toBeGreaterThan(0);