@soleri/forge 3.0.0 → 4.0.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 (44) hide show
  1. package/dist/index.js +0 -0
  2. package/dist/knowledge-installer.d.ts +2 -1
  3. package/dist/scaffolder.js +1 -91
  4. package/dist/scaffolder.js.map +1 -1
  5. package/dist/templates/activate.js +1 -2
  6. package/dist/templates/activate.js.map +1 -1
  7. package/dist/templates/core-facade.js +1 -6
  8. package/dist/templates/core-facade.js.map +1 -1
  9. package/dist/templates/domain-facade.js +1 -3
  10. package/dist/templates/domain-facade.js.map +1 -1
  11. package/dist/templates/entry-point.js +2 -7
  12. package/dist/templates/entry-point.js.map +1 -1
  13. package/dist/templates/llm-client.js +3 -4
  14. package/dist/templates/llm-client.js.map +1 -1
  15. package/dist/templates/package-json.js +1 -2
  16. package/dist/templates/package-json.js.map +1 -1
  17. package/dist/templates/test-facades.js +2 -5
  18. package/dist/templates/test-facades.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/__tests__/scaffolder.test.ts +35 -47
  21. package/src/knowledge-installer.ts +1 -1
  22. package/src/scaffolder.ts +1 -97
  23. package/src/templates/activate.ts +1 -2
  24. package/src/templates/core-facade.ts +1 -6
  25. package/src/templates/domain-facade.ts +1 -3
  26. package/src/templates/entry-point.ts +2 -7
  27. package/src/templates/llm-client.ts +3 -4
  28. package/src/templates/package-json.ts +1 -2
  29. package/src/templates/test-facades.ts +2 -5
  30. package/src/templates/brain.ts +0 -478
  31. package/src/templates/facade-factory.ts +0 -62
  32. package/src/templates/facade-types.ts +0 -45
  33. package/src/templates/intelligence-loader.ts +0 -42
  34. package/src/templates/intelligence-types.ts +0 -23
  35. package/src/templates/llm-key-pool.ts +0 -212
  36. package/src/templates/llm-types.ts +0 -160
  37. package/src/templates/llm-utils.ts +0 -259
  38. package/src/templates/planner.ts +0 -150
  39. package/src/templates/test-brain.ts +0 -474
  40. package/src/templates/test-llm.ts +0 -575
  41. package/src/templates/test-loader.ts +0 -146
  42. package/src/templates/test-planner.ts +0 -271
  43. package/src/templates/test-vault.ts +0 -380
  44. package/src/templates/vault.ts +0 -263
package/src/scaffolder.ts CHANGED
@@ -13,32 +13,17 @@ import type { AgentConfig, ScaffoldResult, ScaffoldPreview, AgentInfo } from './
13
13
  import { generatePackageJson } from './templates/package-json.js';
14
14
  import { generateTsconfig } from './templates/tsconfig.js';
15
15
  import { generateVitestConfig } from './templates/vitest-config.js';
16
- import { generateFacadeTypes } from './templates/facade-types.js';
17
- import { generateFacadeFactory } from './templates/facade-factory.js';
18
- import { generateVault } from './templates/vault.js';
19
- import { generateIntelligenceTypes } from './templates/intelligence-types.js';
20
- import { generateIntelligenceLoader } from './templates/intelligence-loader.js';
21
16
  import { generatePersona } from './templates/persona.js';
22
17
  import { generateDomainFacade } from './templates/domain-facade.js';
23
18
  import { generateCoreFacade } from './templates/core-facade.js';
24
19
  import { generateEntryPoint } from './templates/entry-point.js';
25
- import { generateVaultTest } from './templates/test-vault.js';
26
- import { generateLoaderTest } from './templates/test-loader.js';
27
20
  import { generateFacadesTest } from './templates/test-facades.js';
28
21
  import { generateClaudeMdTemplate } from './templates/claude-md-template.js';
29
22
  import { generateInjectClaudeMd } from './templates/inject-claude-md.js';
30
23
  import { generateActivate } from './templates/activate.js';
31
24
  import { generateReadme } from './templates/readme.js';
32
25
  import { generateSetupScript } from './templates/setup-script.js';
33
- import { generatePlanner } from './templates/planner.js';
34
- import { generatePlannerTest } from './templates/test-planner.js';
35
- import { generateBrain } from './templates/brain.js';
36
- import { generateBrainTest } from './templates/test-brain.js';
37
- import { generateLLMTypes } from './templates/llm-types.js';
38
- import { generateLLMUtils } from './templates/llm-utils.js';
39
- import { generateLLMKeyPool } from './templates/llm-key-pool.js';
40
26
  import { generateLLMClient } from './templates/llm-client.js';
41
- import { generateLLMTest } from './templates/test-llm.js';
42
27
 
43
28
  /**
44
29
  * Preview what scaffold will create without writing anything.
@@ -60,40 +45,11 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
60
45
  description:
61
46
  'Entry point — initializes vault, planner, brain, registers facades, starts stdio',
62
47
  },
63
- {
64
- path: 'src/planning/planner.ts',
65
- description: 'Plan state machine — draft → approved → executing → completed',
66
- },
67
- {
68
- path: 'src/brain/brain.ts',
69
- description:
70
- 'Intelligence layer — TF-IDF scoring, auto-tagging, duplicate detection, adaptive weights',
71
- },
72
- {
73
- path: 'src/llm/types.ts',
74
- description:
75
- 'LLM types — SecretString, LLMError, call options/result, circuit breaker, key pool, routing',
76
- },
77
- {
78
- path: 'src/llm/utils.ts',
79
- description:
80
- 'LLM utilities — CircuitBreaker, retry with backoff+jitter, rate limit header parser',
81
- },
82
- {
83
- path: 'src/llm/key-pool.ts',
84
- description:
85
- 'Key pool — multi-key rotation with per-key circuit breakers, preemptive quota rotation',
86
- },
87
48
  {
88
49
  path: 'src/llm/llm-client.ts',
89
50
  description:
90
51
  'LLM client — unified OpenAI/Anthropic caller with model routing (optional, needs API keys)',
91
52
  },
92
- { path: 'src/facades/types.ts', description: 'Facade type system (OpHandler, FacadeConfig)' },
93
- {
94
- path: 'src/facades/facade-factory.ts',
95
- description: 'Registers facades as MCP tools with op dispatch',
96
- },
97
53
  {
98
54
  path: 'src/facades/core.facade.ts',
99
55
  description: 'Core facade — search, vault stats, health, identity',
@@ -102,18 +58,6 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
102
58
  path: `src/facades/${d}.facade.ts`,
103
59
  description: `${d} facade — search, get_patterns, capture, remove`,
104
60
  })),
105
- {
106
- path: 'src/vault/vault.ts',
107
- description: 'SQLite vault with FTS5 full-text search (BM25 ranking)',
108
- },
109
- {
110
- path: 'src/intelligence/types.ts',
111
- description: 'IntelligenceEntry and IntelligenceBundle types',
112
- },
113
- {
114
- path: 'src/intelligence/loader.ts',
115
- description: 'Loads and validates JSON intelligence data files',
116
- },
117
61
  ...config.domains.map((d) => ({
118
62
  path: `src/intelligence/data/${d}.json`,
119
63
  description: `Empty ${d} intelligence bundle — ready for knowledge capture`,
@@ -134,32 +78,10 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
134
78
  path: 'src/activation/activate.ts',
135
79
  description: `${config.name} activation system — persona adoption, setup status, tool recommendations`,
136
80
  },
137
- {
138
- path: 'src/__tests__/vault.test.ts',
139
- description: 'Vault tests — CRUD, FTS5 search, stats, project registration (32 tests)',
140
- },
141
- {
142
- path: 'src/__tests__/loader.test.ts',
143
- description: 'Intelligence loader tests — valid/invalid JSON, edge cases (9 tests)',
144
- },
145
81
  {
146
82
  path: 'src/__tests__/facades.test.ts',
147
83
  description: `Facade integration tests — all ${config.domains.length + 1} facades`,
148
84
  },
149
- {
150
- path: 'src/__tests__/planner.test.ts',
151
- description: 'Planner tests — state machine, task lifecycle, persistence (~20 tests)',
152
- },
153
- {
154
- path: 'src/__tests__/brain.test.ts',
155
- description:
156
- 'Brain tests — TF-IDF scoring, auto-tagging, duplicate detection, adaptive weights (~38 tests)',
157
- },
158
- {
159
- path: 'src/__tests__/llm.test.ts',
160
- description:
161
- 'LLM tests — SecretString, CircuitBreaker, retry, rate limits, KeyPool, ModelRouter (~30 tests)',
162
- },
163
85
  { path: '.mcp.json', description: 'MCP client config for connecting to this agent' },
164
86
  {
165
87
  path: 'README.md',
@@ -238,13 +160,10 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
238
160
  'scripts',
239
161
  'src',
240
162
  'src/facades',
241
- 'src/vault',
242
163
  'src/intelligence',
243
164
  'src/intelligence/data',
244
165
  'src/identity',
245
166
  'src/activation',
246
- 'src/planning',
247
- 'src/brain',
248
167
  'src/llm',
249
168
  'src/__tests__',
250
169
  ];
@@ -282,29 +201,14 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
282
201
 
283
202
  // Write source files
284
203
  const sourceFiles: Array<[string, string]> = [
285
- ['src/facades/types.ts', generateFacadeTypes()],
286
- ['src/facades/facade-factory.ts', generateFacadeFactory()],
287
204
  ['src/facades/core.facade.ts', generateCoreFacade(config)],
288
- ['src/vault/vault.ts', generateVault()],
289
- ['src/intelligence/types.ts', generateIntelligenceTypes()],
290
- ['src/intelligence/loader.ts', generateIntelligenceLoader()],
291
205
  ['src/identity/persona.ts', generatePersona(config)],
292
206
  ['src/activation/claude-md-content.ts', generateClaudeMdTemplate(config)],
293
207
  ['src/activation/inject-claude-md.ts', generateInjectClaudeMd(config)],
294
208
  ['src/activation/activate.ts', generateActivate(config)],
295
209
  ['src/index.ts', generateEntryPoint(config)],
296
- ['src/planning/planner.ts', generatePlanner()],
297
- ['src/brain/brain.ts', generateBrain()],
298
- ['src/llm/types.ts', generateLLMTypes()],
299
- ['src/llm/utils.ts', generateLLMUtils()],
300
- ['src/llm/key-pool.ts', generateLLMKeyPool(config)],
301
210
  ['src/llm/llm-client.ts', generateLLMClient(config)],
302
- ['src/__tests__/vault.test.ts', generateVaultTest()],
303
- ['src/__tests__/loader.test.ts', generateLoaderTest()],
304
211
  ['src/__tests__/facades.test.ts', generateFacadesTest(config)],
305
- ['src/__tests__/planner.test.ts', generatePlannerTest()],
306
- ['src/__tests__/brain.test.ts', generateBrainTest()],
307
- ['src/__tests__/llm.test.ts', generateLLMTest(config)],
308
212
  ];
309
213
 
310
214
  // Domain facades and empty data files
@@ -329,7 +233,7 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
329
233
  `${config.domains.length} empty knowledge domains ready for capture`,
330
234
  `Intelligence layer (Brain) — TF-IDF scoring, auto-tagging, duplicate detection`,
331
235
  `Activation system included — say "Hello, ${config.name}!" to activate`,
332
- `6 test suites — vault, loader, facades, planner, brain, llm`,
236
+ `1 test suitefacades (vault, brain, planner, llm tests provided by @soleri/core)`,
333
237
  ];
334
238
 
335
239
  if (mcpReg.registered) {
@@ -35,8 +35,7 @@ export function generateActivate(config: AgentConfig): string {
35
35
  "import { homedir } from 'node:os';",
36
36
  "import { PERSONA } from '../identity/persona.js';",
37
37
  "import { hasAgentMarker } from './inject-claude-md.js';",
38
- "import type { Vault } from '../vault/vault.js';",
39
- "import type { Planner, Plan } from '../planning/planner.js';",
38
+ "import type { Vault, Planner, Plan } from '@soleri/core';",
40
39
  '',
41
40
  'export interface ActivationResult {',
42
41
  ' activated: boolean;',
@@ -6,16 +6,11 @@ import type { AgentConfig } from '../types.js';
6
6
  */
7
7
  export function generateCoreFacade(config: AgentConfig): string {
8
8
  return `import { z } from 'zod';
9
- import type { FacadeConfig } from './types.js';
10
- import type { Vault } from '../vault/vault.js';
11
- import type { IntelligenceEntry } from '../intelligence/types.js';
9
+ import type { FacadeConfig, Vault, IntelligenceEntry, Planner, Brain, KeyPool } from '@soleri/core';
12
10
  import { PERSONA } from '../identity/persona.js';
13
11
  import { activateAgent, deactivateAgent } from '../activation/activate.js';
14
12
  import { injectClaudeMd, injectClaudeMdGlobal, hasAgentMarker } from '../activation/inject-claude-md.js';
15
- import type { Planner } from '../planning/planner.js';
16
- import type { Brain } from '../brain/brain.js';
17
13
  import type { LLMClient } from '../llm/llm-client.js';
18
- import type { KeyPool } from '../llm/key-pool.js';
19
14
 
20
15
  export function createCoreFacade(vault: Vault, planner: Planner, brain: Brain, llmClient?: LLMClient, openaiKeyPool?: KeyPool, anthropicKeyPool?: KeyPool): FacadeConfig {
21
16
  return {
@@ -6,9 +6,7 @@ export function generateDomainFacade(agentId: string, domain: string): string {
6
6
  const facadeName = `${agentId}_${domain.replace(/-/g, '_')}`;
7
7
 
8
8
  return `import { z } from 'zod';
9
- import type { FacadeConfig } from './types.js';
10
- import type { Vault } from '../vault/vault.js';
11
- import type { Brain } from '../brain/brain.js';
9
+ import type { FacadeConfig, Vault, Brain } from '@soleri/core';
12
10
 
13
11
  export function create${pascalCase(domain)}Facade(vault: Vault, brain: Brain): FacadeConfig {
14
12
  return {
@@ -24,15 +24,10 @@ import { dirname, join } from 'node:path';
24
24
  import { fileURLToPath } from 'node:url';
25
25
  import { homedir } from 'node:os';
26
26
 
27
- import { registerAllFacades } from './facades/facade-factory.js';
27
+ import { Vault, Brain, Planner, KeyPool, loadKeyPoolConfig, loadIntelligenceData, registerAllFacades } from '@soleri/core';
28
28
  ${facadeImports}
29
29
  import { createCoreFacade } from './facades/core.facade.js';
30
- import { loadIntelligenceData } from './intelligence/loader.js';
31
- import { Vault } from './vault/vault.js';
32
- import { Planner } from './planning/planner.js';
33
- import { Brain } from './brain/brain.js';
34
30
  import { LLMClient } from './llm/llm-client.js';
35
- import { KeyPool, loadKeyPoolConfig } from './llm/key-pool.js';
36
31
  import { PERSONA, getPersonaPrompt } from './identity/persona.js';
37
32
 
38
33
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -63,7 +58,7 @@ async function main(): Promise<void> {
63
58
  console.error(\`[\${PERSONA.name.toLowerCase()}] Brain: vocabulary \${brain.getVocabularySize()} terms\`);
64
59
 
65
60
  // Initialize LLM client (optional — works without API keys)
66
- const keyPoolFiles = loadKeyPoolConfig();
61
+ const keyPoolFiles = loadKeyPoolConfig('${config.id}');
67
62
  const openaiKeyPool = new KeyPool(keyPoolFiles.openai);
68
63
  const anthropicKeyPool = new KeyPool(keyPoolFiles.anthropic);
69
64
  const llmClient = new LLMClient(openaiKeyPool, anthropicKeyPool);
@@ -12,15 +12,14 @@ export function generateLLMClient(config: AgentConfig): string {
12
12
  */
13
13
 
14
14
  import Anthropic from '@anthropic-ai/sdk';
15
- import { SecretString, LLMError } from './types.js';
15
+ import { SecretString, LLMError, CircuitBreaker, retry, parseRateLimitHeaders } from '@soleri/core';
16
16
  import type {
17
17
  LLMCallOptions,
18
18
  LLMCallResult,
19
19
  RouteEntry,
20
20
  RoutingConfig,
21
- } from './types.js';
22
- import { CircuitBreaker, retry, parseRateLimitHeaders } from './utils.js';
23
- import type { KeyPool } from './key-pool.js';
21
+ KeyPool,
22
+ } from '@soleri/core';
24
23
  import * as fs from 'node:fs';
25
24
  import * as path from 'node:path';
26
25
  import { homedir } from 'node:os';
@@ -23,11 +23,10 @@ export function generatePackageJson(config: AgentConfig): string {
23
23
  dependencies: {
24
24
  '@anthropic-ai/sdk': '^0.39.0',
25
25
  '@modelcontextprotocol/sdk': '^1.12.1',
26
- 'better-sqlite3': '^11.8.1',
26
+ '@soleri/core': '^1.0.0',
27
27
  zod: '^3.24.2',
28
28
  },
29
29
  devDependencies: {
30
- '@types/better-sqlite3': '^7.6.12',
31
30
  '@types/node': '^22.13.4',
32
31
  '@vitest/coverage-v8': '^3.0.5',
33
32
  tsx: '^4.19.2',
@@ -17,17 +17,14 @@ export function generateFacadesTest(config: AgentConfig): string {
17
17
  .join('\n\n');
18
18
 
19
19
  return `import { describe, it, expect, beforeEach, afterEach } from 'vitest';
20
- import { Vault } from '../vault/vault.js';
21
- import { Brain } from '../brain/brain.js';
22
- import type { IntelligenceEntry } from '../intelligence/types.js';
20
+ import { Vault, Brain, Planner, KeyPool } from '@soleri/core';
21
+ import type { IntelligenceEntry } from '@soleri/core';
23
22
  import { mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from 'node:fs';
24
23
  import { join } from 'node:path';
25
24
  import { tmpdir } from 'node:os';
26
25
  ${domainImports}
27
26
  import { createCoreFacade } from '../facades/core.facade.js';
28
- import { Planner } from '../planning/planner.js';
29
27
  import { LLMClient } from '../llm/llm-client.js';
30
- import { KeyPool } from '../llm/key-pool.js';
31
28
 
32
29
  function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
33
30
  return {