@soleri/forge 5.1.3 → 5.4.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 (77) hide show
  1. package/dist/index.js +0 -0
  2. package/dist/scaffolder.js +150 -2
  3. package/dist/scaffolder.js.map +1 -1
  4. package/dist/templates/brain.d.ts +6 -0
  5. package/dist/templates/brain.js +478 -0
  6. package/dist/templates/brain.js.map +1 -0
  7. package/dist/templates/claude-md-template.js +90 -1
  8. package/dist/templates/claude-md-template.js.map +1 -1
  9. package/dist/templates/core-facade.d.ts +6 -0
  10. package/dist/templates/core-facade.js +564 -0
  11. package/dist/templates/core-facade.js.map +1 -0
  12. package/dist/templates/domain-facade.d.ts +4 -0
  13. package/dist/templates/domain-facade.js +4 -0
  14. package/dist/templates/domain-facade.js.map +1 -1
  15. package/dist/templates/entry-point.js +32 -0
  16. package/dist/templates/entry-point.js.map +1 -1
  17. package/dist/templates/facade-factory.d.ts +1 -0
  18. package/dist/templates/facade-factory.js +63 -0
  19. package/dist/templates/facade-factory.js.map +1 -0
  20. package/dist/templates/facade-types.d.ts +1 -0
  21. package/dist/templates/facade-types.js +46 -0
  22. package/dist/templates/facade-types.js.map +1 -0
  23. package/dist/templates/intelligence-loader.d.ts +1 -0
  24. package/dist/templates/intelligence-loader.js +43 -0
  25. package/dist/templates/intelligence-loader.js.map +1 -0
  26. package/dist/templates/intelligence-types.d.ts +1 -0
  27. package/dist/templates/intelligence-types.js +24 -0
  28. package/dist/templates/intelligence-types.js.map +1 -0
  29. package/dist/templates/llm-client.d.ts +7 -0
  30. package/dist/templates/llm-client.js +300 -0
  31. package/dist/templates/llm-client.js.map +1 -0
  32. package/dist/templates/llm-key-pool.d.ts +7 -0
  33. package/dist/templates/llm-key-pool.js +211 -0
  34. package/dist/templates/llm-key-pool.js.map +1 -0
  35. package/dist/templates/llm-types.d.ts +5 -0
  36. package/dist/templates/llm-types.js +161 -0
  37. package/dist/templates/llm-types.js.map +1 -0
  38. package/dist/templates/llm-utils.d.ts +5 -0
  39. package/dist/templates/llm-utils.js +260 -0
  40. package/dist/templates/llm-utils.js.map +1 -0
  41. package/dist/templates/planner.d.ts +5 -0
  42. package/dist/templates/planner.js +150 -0
  43. package/dist/templates/planner.js.map +1 -0
  44. package/dist/templates/setup-script.js +26 -1
  45. package/dist/templates/setup-script.js.map +1 -1
  46. package/dist/templates/test-brain.d.ts +6 -0
  47. package/dist/templates/test-brain.js +474 -0
  48. package/dist/templates/test-brain.js.map +1 -0
  49. package/dist/templates/test-facades.js +173 -3
  50. package/dist/templates/test-facades.js.map +1 -1
  51. package/dist/templates/test-llm.d.ts +7 -0
  52. package/dist/templates/test-llm.js +574 -0
  53. package/dist/templates/test-llm.js.map +1 -0
  54. package/dist/templates/test-loader.d.ts +5 -0
  55. package/dist/templates/test-loader.js +146 -0
  56. package/dist/templates/test-loader.js.map +1 -0
  57. package/dist/templates/test-planner.d.ts +5 -0
  58. package/dist/templates/test-planner.js +271 -0
  59. package/dist/templates/test-planner.js.map +1 -0
  60. package/dist/templates/test-vault.d.ts +5 -0
  61. package/dist/templates/test-vault.js +380 -0
  62. package/dist/templates/test-vault.js.map +1 -0
  63. package/dist/templates/vault.d.ts +5 -0
  64. package/dist/templates/vault.js +263 -0
  65. package/dist/templates/vault.js.map +1 -0
  66. package/dist/types.d.ts +4 -0
  67. package/dist/types.js +2 -0
  68. package/dist/types.js.map +1 -1
  69. package/package.json +1 -1
  70. package/src/__tests__/scaffolder.test.ts +2 -2
  71. package/src/scaffolder.ts +153 -2
  72. package/src/templates/claude-md-template.ts +181 -0
  73. package/src/templates/domain-facade.ts +4 -0
  74. package/src/templates/entry-point.ts +32 -0
  75. package/src/templates/setup-script.ts +28 -1
  76. package/src/templates/test-facades.ts +173 -3
  77. package/src/types.ts +2 -0
@@ -123,6 +123,29 @@ ${domainDescribes}
123
123
  if (stats.totalEntries === 0) {
124
124
  recommendations.push('Vault is empty');
125
125
  }
126
+ // Check hook status
127
+ const { readdirSync } = await import('node:fs');
128
+ const agentClaudeDir = joinPath(__dirname, '..', '.claude');
129
+ const globalClaudeDir = joinPath(homedir(), '.claude');
130
+ const hookStatus = { agent: [] as string[], global: [] as string[], missing: [] as string[] };
131
+ if (exists(agentClaudeDir)) {
132
+ try {
133
+ const agentHooks = readdirSync(agentClaudeDir)
134
+ .filter((f: string) => f.startsWith('hookify.') && f.endsWith('.local.md'))
135
+ .map((f: string) => f.replace('hookify.', '').replace('.local.md', ''));
136
+ hookStatus.agent = agentHooks;
137
+ for (const hook of agentHooks) {
138
+ if (exists(joinPath(globalClaudeDir, \`hookify.\${hook}.local.md\`))) {
139
+ hookStatus.global.push(hook);
140
+ } else {
141
+ hookStatus.missing.push(hook);
142
+ }
143
+ }
144
+ } catch { /* ignore */ }
145
+ }
146
+ if (hookStatus.missing.length > 0) {
147
+ recommendations.push(\`\${hookStatus.missing.length} hook(s) not installed globally — run scripts/setup.sh\`);
148
+ }
126
149
  if (recommendations.length === 0) {
127
150
  recommendations.push('${config.name} is fully set up and ready!');
128
151
  }
@@ -133,6 +156,7 @@ ${domainDescribes}
133
156
  global: { exists: exists(globalClaudeMd), has_agent_section: hasAgentMarker(globalClaudeMd) },
134
157
  },
135
158
  vault: { entries: stats.totalEntries, domains: Object.keys(stats.byDomain) },
159
+ hooks: hookStatus,
136
160
  recommendations,
137
161
  };
138
162
  },
@@ -169,6 +193,10 @@ ${domainDescribes}
169
193
  expect(opNames).toContain('brain_archive_sessions');
170
194
  expect(opNames).toContain('brain_promote_proposals');
171
195
  expect(opNames).toContain('brain_lifecycle');
196
+ // Enhanced brain ops (3)
197
+ expect(opNames).toContain('brain_feedback');
198
+ expect(opNames).toContain('brain_feedback_stats');
199
+ expect(opNames).toContain('brain_reset_extracted');
172
200
  // Agent-specific ops (5)
173
201
  expect(opNames).toContain('health');
174
202
  expect(opNames).toContain('identity');
@@ -184,8 +212,122 @@ ${domainDescribes}
184
212
  expect(opNames).toContain('route_intent');
185
213
  expect(opNames).toContain('morph');
186
214
  expect(opNames).toContain('get_behavior_rules');
187
- // Total: 50
188
- expect(facade.ops.length).toBe(50);
215
+ // Cognee ops (5)
216
+ expect(opNames).toContain('cognee_status');
217
+ expect(opNames).toContain('cognee_search');
218
+ expect(opNames).toContain('cognee_add');
219
+ expect(opNames).toContain('cognee_cognify');
220
+ expect(opNames).toContain('cognee_config');
221
+ // LLM ops (2)
222
+ expect(opNames).toContain('llm_rotate');
223
+ expect(opNames).toContain('llm_call');
224
+ // Governance ops (5)
225
+ expect(opNames).toContain('governance_policy');
226
+ expect(opNames).toContain('governance_proposals');
227
+ expect(opNames).toContain('governance_stats');
228
+ expect(opNames).toContain('governance_expire');
229
+ expect(opNames).toContain('governance_dashboard');
230
+ // Planning Extra ops (9)
231
+ expect(opNames).toContain('plan_iterate');
232
+ expect(opNames).toContain('plan_split');
233
+ expect(opNames).toContain('plan_reconcile');
234
+ expect(opNames).toContain('plan_complete_lifecycle');
235
+ expect(opNames).toContain('plan_dispatch');
236
+ expect(opNames).toContain('plan_review');
237
+ expect(opNames).toContain('plan_archive');
238
+ expect(opNames).toContain('plan_list_tasks');
239
+ expect(opNames).toContain('plan_stats');
240
+ // Memory Extra ops (8)
241
+ expect(opNames).toContain('memory_delete');
242
+ expect(opNames).toContain('memory_stats');
243
+ expect(opNames).toContain('memory_export');
244
+ expect(opNames).toContain('memory_import');
245
+ expect(opNames).toContain('memory_prune');
246
+ expect(opNames).toContain('memory_deduplicate');
247
+ expect(opNames).toContain('memory_topics');
248
+ expect(opNames).toContain('memory_by_project');
249
+ // Vault Extra ops (12)
250
+ expect(opNames).toContain('vault_get');
251
+ expect(opNames).toContain('vault_update');
252
+ expect(opNames).toContain('vault_remove');
253
+ expect(opNames).toContain('vault_bulk_add');
254
+ expect(opNames).toContain('vault_bulk_remove');
255
+ expect(opNames).toContain('vault_tags');
256
+ expect(opNames).toContain('vault_domains');
257
+ expect(opNames).toContain('vault_recent');
258
+ expect(opNames).toContain('vault_import');
259
+ expect(opNames).toContain('vault_seed');
260
+ expect(opNames).toContain('vault_backup');
261
+ expect(opNames).toContain('vault_age_report');
262
+ // Admin ops (8)
263
+ expect(opNames).toContain('admin_health');
264
+ expect(opNames).toContain('admin_tool_list');
265
+ expect(opNames).toContain('admin_config');
266
+ expect(opNames).toContain('admin_vault_size');
267
+ expect(opNames).toContain('admin_uptime');
268
+ expect(opNames).toContain('admin_version');
269
+ expect(opNames).toContain('admin_reset_cache');
270
+ expect(opNames).toContain('admin_diagnostic');
271
+ // Loop ops (7)
272
+ expect(opNames).toContain('loop_start');
273
+ expect(opNames).toContain('loop_iterate');
274
+ expect(opNames).toContain('loop_status');
275
+ expect(opNames).toContain('loop_cancel');
276
+ expect(opNames).toContain('loop_history');
277
+ expect(opNames).toContain('loop_is_active');
278
+ expect(opNames).toContain('loop_complete');
279
+ // Orchestrate ops (5)
280
+ expect(opNames).toContain('orchestrate_plan');
281
+ expect(opNames).toContain('orchestrate_execute');
282
+ expect(opNames).toContain('orchestrate_complete');
283
+ expect(opNames).toContain('orchestrate_status');
284
+ expect(opNames).toContain('orchestrate_quick_capture');
285
+ // Capture ops (4)
286
+ expect(opNames).toContain('capture_knowledge');
287
+ expect(opNames).toContain('capture_quick');
288
+ expect(opNames).toContain('search_intelligent');
289
+ expect(opNames).toContain('search_feedback');
290
+ // Grading ops (5)
291
+ expect(opNames).toContain('plan_grade');
292
+ expect(opNames).toContain('plan_check_history');
293
+ expect(opNames).toContain('plan_latest_check');
294
+ expect(opNames).toContain('plan_meets_grade');
295
+ expect(opNames).toContain('plan_auto_improve');
296
+ // Admin Extra ops (10)
297
+ expect(opNames).toContain('admin_telemetry');
298
+ expect(opNames).toContain('admin_telemetry_recent');
299
+ expect(opNames).toContain('admin_telemetry_reset');
300
+ expect(opNames).toContain('admin_permissions');
301
+ expect(opNames).toContain('admin_vault_analytics');
302
+ expect(opNames).toContain('admin_search_insights');
303
+ expect(opNames).toContain('admin_module_status');
304
+ expect(opNames).toContain('admin_env');
305
+ expect(opNames).toContain('admin_gc');
306
+ expect(opNames).toContain('admin_export_config');
307
+ // Curator Extra ops (4)
308
+ expect(opNames).toContain('curator_entry_history');
309
+ expect(opNames).toContain('curator_record_snapshot');
310
+ expect(opNames).toContain('curator_queue_stats');
311
+ expect(opNames).toContain('curator_enrich');
312
+ // Project ops (12)
313
+ expect(opNames).toContain('project_get');
314
+ expect(opNames).toContain('project_list');
315
+ expect(opNames).toContain('project_unregister');
316
+ expect(opNames).toContain('project_get_rules');
317
+ expect(opNames).toContain('project_list_rules');
318
+ expect(opNames).toContain('project_add_rule');
319
+ expect(opNames).toContain('project_remove_rule');
320
+ expect(opNames).toContain('project_link');
321
+ expect(opNames).toContain('project_unlink');
322
+ expect(opNames).toContain('project_get_links');
323
+ expect(opNames).toContain('project_linked_projects');
324
+ expect(opNames).toContain('project_touch');
325
+ // Cross-project memory ops (3)
326
+ expect(opNames).toContain('memory_promote_to_global');
327
+ expect(opNames).toContain('memory_configure');
328
+ expect(opNames).toContain('memory_cross_project_search');
329
+ // Total: 152 (147 core + 5 agent-specific)
330
+ expect(facade.ops.length).toBe(152);
189
331
  });
190
332
 
191
333
  it('search should query across all domains with ranked results', async () => {
@@ -277,7 +419,9 @@ ${domainDescribes}
277
419
  const setupOp = facade.ops.find((o) => o.name === 'setup')!;
278
420
  const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
279
421
  agent: { name: string };
422
+ claude_md: { project: { exists: boolean; has_agent_section: boolean }; global: { exists: boolean; has_agent_section: boolean } };
280
423
  vault: { entries: number };
424
+ hooks: { agent: string[]; global: string[]; missing: string[] };
281
425
  recommendations: string[];
282
426
  };
283
427
  expect(result.agent.name).toBe('${escapeQuotes(config.name)}');
@@ -327,6 +471,32 @@ ${domainDescribes}
327
471
  const result = (await healthOp.handler({})) as { score: number };
328
472
  expect(result.score).toBeGreaterThan(0);
329
473
  });
474
+
475
+ it('governance_policy get should return default policy', async () => {
476
+ const facade = buildCoreFacade();
477
+ const policyOp = facade.ops.find((o) => o.name === 'governance_policy')!;
478
+ const result = (await policyOp.handler({ action: 'get', projectPath: '/test' })) as {
479
+ projectPath: string;
480
+ quotas: { maxEntriesTotal: number };
481
+ autoCapture: { enabled: boolean };
482
+ };
483
+ expect(result.projectPath).toBe('/test');
484
+ expect(result.quotas.maxEntriesTotal).toBe(500);
485
+ expect(result.autoCapture.enabled).toBe(true);
486
+ });
487
+
488
+ it('governance_dashboard should return combined view', async () => {
489
+ const facade = buildCoreFacade();
490
+ const dashOp = facade.ops.find((o) => o.name === 'governance_dashboard')!;
491
+ const result = (await dashOp.handler({ projectPath: '/test' })) as {
492
+ vaultSize: number;
493
+ quotaPercent: number;
494
+ pendingProposals: number;
495
+ };
496
+ expect(typeof result.vaultSize).toBe('number');
497
+ expect(typeof result.quotaPercent).toBe('number');
498
+ expect(result.pendingProposals).toBe(0);
499
+ });
330
500
  });
331
501
  });
332
502
  `;
@@ -382,7 +552,7 @@ function generateDomainDescribe(agentId, domain) {
382
552
  severity: 'warning',
383
553
  description: 'A captured pattern.',
384
554
  tags: ['captured'],
385
- })) as { captured: boolean };
555
+ })) as { captured: boolean; governance?: { action: string } };
386
556
  expect(result.captured).toBe(true);
387
557
  const entry = runtime.vault.get('${domain}-cap1');
388
558
  expect(entry).not.toBeNull();
@@ -1 +1 @@
1
- {"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmCS,MAAM,CAAC,EAAE;;;;;;;;;;;EAWzB,eAAe;;cAEH,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCAsEe,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;iBAehC,MAAM,CAAC,EAAE;;;;;;;;kCAQQ,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDA8CM,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmCvB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;mCACzB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;0CAWlB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0B9B,MAAM,CAAC,EAAE;;;;;;;;;;;;;;wCAcN,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDhE,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,MAAc;IAC7D,MAAM,UAAU,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;IAE7D,OAAO,eAAe,UAAU;;4CAEU,OAAO,OAAO,MAAM;;;;;kCAK9B,UAAU;;;;;;;;;iDASK,MAAM;;2BAE5B,MAAM,mBAAmB,MAAM;;;;;;kDAMR,MAAM;;;iCAGvB,MAAM;;2BAEZ,MAAM,kBAAkB,MAAM;;;;;;;wDAOD,MAAM;;;wCAGtB,MAAM;;;;eAI/B,MAAM;;;;;;;;yCAQoB,MAAM;;oCAEX,MAAM;;;;6CAIG,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;gCACtB,MAAM;;;;6CAIO,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;;kCAEpB,MAAM;;MAElC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmCS,MAAM,CAAC,EAAE;;;;;;;;;;;EAWzB,eAAe;;cAEH,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA6Fe,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;iBAgBhC,MAAM,CAAC,EAAE;;;;;;;;kCAQQ,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAoKM,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmCvB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;mCACzB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;0CAWlB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0B9B,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;wCAgBN,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EhE,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,MAAc;IAC7D,MAAM,UAAU,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;IAE7D,OAAO,eAAe,UAAU;;4CAEU,OAAO,OAAO,MAAM;;;;;kCAK9B,UAAU;;;;;;;;;iDASK,MAAM;;2BAE5B,MAAM,mBAAmB,MAAM;;;;;;kDAMR,MAAM;;;iCAGvB,MAAM;;2BAEZ,MAAM,kBAAkB,MAAM;;;;;;;wDAOD,MAAM;;;wCAGtB,MAAM;;;;eAI/B,MAAM;;;;;;;;yCAQoB,MAAM;;oCAEX,MAAM;;;;6CAIG,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;gCACtB,MAAM;;;;6CAIO,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;;kCAEpB,MAAM;;MAElC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AgentConfig } from '../types.js';
2
+ /**
3
+ * Generate the LLM test suite for a new agent.
4
+ * Tests: SecretString, CircuitBreaker, retry, rate-limit parsing,
5
+ * KeyPool rotation, ModelRouter resolution, LLMClient availability.
6
+ */
7
+ export declare function generateLLMTest(_config: AgentConfig): string;