@soleri/forge 0.0.1 → 3.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 (143) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +199 -0
  3. package/dist/facades/forge.facade.d.ts +9 -0
  4. package/dist/facades/forge.facade.js +134 -0
  5. package/dist/facades/forge.facade.js.map +1 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +81 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/knowledge-installer.d.ts +30 -0
  10. package/dist/knowledge-installer.js +437 -0
  11. package/dist/knowledge-installer.js.map +1 -0
  12. package/dist/scaffolder.d.ts +13 -0
  13. package/dist/scaffolder.js +420 -0
  14. package/dist/scaffolder.js.map +1 -0
  15. package/dist/templates/activate.d.ts +9 -0
  16. package/dist/templates/activate.js +140 -0
  17. package/dist/templates/activate.js.map +1 -0
  18. package/dist/templates/brain.d.ts +6 -0
  19. package/dist/templates/brain.js +478 -0
  20. package/dist/templates/brain.js.map +1 -0
  21. package/dist/templates/claude-md-template.d.ts +11 -0
  22. package/dist/templates/claude-md-template.js +73 -0
  23. package/dist/templates/claude-md-template.js.map +1 -0
  24. package/dist/templates/core-facade.d.ts +6 -0
  25. package/dist/templates/core-facade.js +461 -0
  26. package/dist/templates/core-facade.js.map +1 -0
  27. package/dist/templates/domain-facade.d.ts +7 -0
  28. package/dist/templates/domain-facade.js +121 -0
  29. package/dist/templates/domain-facade.js.map +1 -0
  30. package/dist/templates/entry-point.d.ts +5 -0
  31. package/dist/templates/entry-point.js +121 -0
  32. package/dist/templates/entry-point.js.map +1 -0
  33. package/dist/templates/facade-factory.d.ts +1 -0
  34. package/dist/templates/facade-factory.js +63 -0
  35. package/dist/templates/facade-factory.js.map +1 -0
  36. package/dist/templates/facade-types.d.ts +1 -0
  37. package/dist/templates/facade-types.js +46 -0
  38. package/dist/templates/facade-types.js.map +1 -0
  39. package/dist/templates/inject-claude-md.d.ts +11 -0
  40. package/dist/templates/inject-claude-md.js +92 -0
  41. package/dist/templates/inject-claude-md.js.map +1 -0
  42. package/dist/templates/intelligence-loader.d.ts +1 -0
  43. package/dist/templates/intelligence-loader.js +43 -0
  44. package/dist/templates/intelligence-loader.js.map +1 -0
  45. package/dist/templates/intelligence-types.d.ts +1 -0
  46. package/dist/templates/intelligence-types.js +24 -0
  47. package/dist/templates/intelligence-types.js.map +1 -0
  48. package/dist/templates/llm-client.d.ts +7 -0
  49. package/dist/templates/llm-client.js +301 -0
  50. package/dist/templates/llm-client.js.map +1 -0
  51. package/dist/templates/llm-key-pool.d.ts +7 -0
  52. package/dist/templates/llm-key-pool.js +211 -0
  53. package/dist/templates/llm-key-pool.js.map +1 -0
  54. package/dist/templates/llm-types.d.ts +5 -0
  55. package/dist/templates/llm-types.js +161 -0
  56. package/dist/templates/llm-types.js.map +1 -0
  57. package/dist/templates/llm-utils.d.ts +5 -0
  58. package/dist/templates/llm-utils.js +260 -0
  59. package/dist/templates/llm-utils.js.map +1 -0
  60. package/dist/templates/package-json.d.ts +2 -0
  61. package/dist/templates/package-json.js +38 -0
  62. package/dist/templates/package-json.js.map +1 -0
  63. package/dist/templates/persona.d.ts +2 -0
  64. package/dist/templates/persona.js +42 -0
  65. package/dist/templates/persona.js.map +1 -0
  66. package/dist/templates/planner.d.ts +5 -0
  67. package/dist/templates/planner.js +150 -0
  68. package/dist/templates/planner.js.map +1 -0
  69. package/dist/templates/readme.d.ts +5 -0
  70. package/dist/templates/readme.js +316 -0
  71. package/dist/templates/readme.js.map +1 -0
  72. package/dist/templates/setup-script.d.ts +6 -0
  73. package/dist/templates/setup-script.js +112 -0
  74. package/dist/templates/setup-script.js.map +1 -0
  75. package/dist/templates/test-brain.d.ts +6 -0
  76. package/dist/templates/test-brain.js +474 -0
  77. package/dist/templates/test-brain.js.map +1 -0
  78. package/dist/templates/test-facades.d.ts +6 -0
  79. package/dist/templates/test-facades.js +652 -0
  80. package/dist/templates/test-facades.js.map +1 -0
  81. package/dist/templates/test-llm.d.ts +7 -0
  82. package/dist/templates/test-llm.js +574 -0
  83. package/dist/templates/test-llm.js.map +1 -0
  84. package/dist/templates/test-loader.d.ts +5 -0
  85. package/dist/templates/test-loader.js +146 -0
  86. package/dist/templates/test-loader.js.map +1 -0
  87. package/dist/templates/test-planner.d.ts +5 -0
  88. package/dist/templates/test-planner.js +271 -0
  89. package/dist/templates/test-planner.js.map +1 -0
  90. package/dist/templates/test-vault.d.ts +5 -0
  91. package/dist/templates/test-vault.js +380 -0
  92. package/dist/templates/test-vault.js.map +1 -0
  93. package/dist/templates/tsconfig.d.ts +1 -0
  94. package/dist/templates/tsconfig.js +25 -0
  95. package/dist/templates/tsconfig.js.map +1 -0
  96. package/dist/templates/vault.d.ts +5 -0
  97. package/dist/templates/vault.js +263 -0
  98. package/dist/templates/vault.js.map +1 -0
  99. package/dist/templates/vitest-config.d.ts +1 -0
  100. package/dist/templates/vitest-config.js +27 -0
  101. package/dist/templates/vitest-config.js.map +1 -0
  102. package/dist/types.d.ts +89 -0
  103. package/dist/types.js +21 -0
  104. package/dist/types.js.map +1 -0
  105. package/package.json +42 -4
  106. package/src/__tests__/knowledge-installer.test.ts +805 -0
  107. package/src/__tests__/scaffolder.test.ts +335 -0
  108. package/src/facades/forge.facade.ts +150 -0
  109. package/src/index.ts +101 -0
  110. package/src/knowledge-installer.ts +532 -0
  111. package/src/scaffolder.ts +482 -0
  112. package/src/templates/activate.ts +146 -0
  113. package/src/templates/brain.ts +478 -0
  114. package/src/templates/claude-md-template.ts +137 -0
  115. package/src/templates/core-facade.ts +462 -0
  116. package/src/templates/domain-facade.ts +123 -0
  117. package/src/templates/entry-point.ts +125 -0
  118. package/src/templates/facade-factory.ts +62 -0
  119. package/src/templates/facade-types.ts +45 -0
  120. package/src/templates/inject-claude-md.ts +94 -0
  121. package/src/templates/intelligence-loader.ts +42 -0
  122. package/src/templates/intelligence-types.ts +23 -0
  123. package/src/templates/llm-client.ts +302 -0
  124. package/src/templates/llm-key-pool.ts +212 -0
  125. package/src/templates/llm-types.ts +160 -0
  126. package/src/templates/llm-utils.ts +259 -0
  127. package/src/templates/package-json.ts +40 -0
  128. package/src/templates/persona.ts +45 -0
  129. package/src/templates/planner.ts +150 -0
  130. package/src/templates/readme.ts +319 -0
  131. package/src/templates/setup-script.ts +113 -0
  132. package/src/templates/test-brain.ts +474 -0
  133. package/src/templates/test-facades.ts +659 -0
  134. package/src/templates/test-llm.ts +575 -0
  135. package/src/templates/test-loader.ts +146 -0
  136. package/src/templates/test-planner.ts +271 -0
  137. package/src/templates/test-vault.ts +380 -0
  138. package/src/templates/tsconfig.ts +25 -0
  139. package/src/templates/vault.ts +263 -0
  140. package/src/templates/vitest-config.ts +26 -0
  141. package/src/types.ts +68 -0
  142. package/tsconfig.json +21 -0
  143. package/vitest.config.ts +15 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,98 @@
1
+ # Changelog
2
+
3
+ All notable changes to Soleri Forge (formerly Agent Forge) are documented here.
4
+
5
+ ## [2.1.0] - 2026-02-28
6
+
7
+ Feature release — knowledge pack installer. Agents can now receive pre-built domain knowledge after scaffolding.
8
+
9
+ ### Added
10
+
11
+ - **Knowledge Pack Installer (`forge op:install_knowledge`)** — Install intelligence bundles into existing agents in a single operation. Validates bundles, copies data files, generates domain facades, patches `src/index.ts` and `src/activation/claude-md-content.ts`, and rebuilds the agent
12
+ - **Architecture detection** — Installer detects vault+brain vs vault-only agents and generates appropriately typed facades (`brain.intelligentSearch()` vs `vault.search()`)
13
+ - **Vault-only facade generator** — `generateVaultOnlyDomainFacade()` produces facades matching older agent patterns that use raw vault queries
14
+ - **Source file patching** — Regex-based patching for `index.ts` (imports + facade array) and `claude-md-content.ts` (facade table rows) with fallback anchors for older agent formats
15
+ - **Bundle validation** — Validates domain, version, and all entry fields (id, type, domain, title, severity, description, tags) before installation. Partial success supported — valid bundles install even if others fail
16
+ - **`InstallKnowledgeResult` type** — Structured result with counts, domain lists, patched files, build output, and warnings
17
+ - **Knowledge installer test suite** — 35 tests covering validation, bundle handling, copying, facade generation, source patching, and integration
18
+
19
+ ### Changed
20
+
21
+ - `pascalCase()` and `capitalize()` in `src/templates/domain-facade.ts` are now exported for reuse
22
+ - Agent-forge tests: 56 (was 21)
23
+ - Forge operations: 5 (was 4)
24
+
25
+ ## [2.0.1] - 2026-02-20
26
+
27
+ Patch release — 8 bug fixes found during code audit.
28
+
29
+ ### Fixed
30
+
31
+ - **`listAgents` runtime crash** — Used `require()` in ESM module; replaced with already-imported `readFileSync`
32
+ - **`parseResetDuration` double-counting** — Seconds regex `/(\d+)s/` matched the trailing "s" in "200ms", producing 200,200ms instead of 200ms; reordered to check `ms` first with lookbehind
33
+ - **`process.env.HOME || '~'` fallback** — `path.join('~', ...)` doesn't expand tildes; replaced with `homedir()` from `node:os` in generated key-pool and LLM client
34
+ - **Undefined `$MCP_FILE` in setup script** — Referenced undefined bash variable with `set -u` active; replaced with literal `~/.claude/settings.json`
35
+ - **`rotateOnError` race condition** — Circuit breaker was tripped via fire-and-forget async; added synchronous `recordFailure()` method to `CircuitBreaker`
36
+ - **`rotatePreemptive` misleading log** — Logged `this.activeIndex` after mutation; now captures previous index before rotation
37
+ - **`validateEntry` silently dropping entries** — Required `tags.length > 0` but type allows empty arrays; removed length requirement
38
+ - **Dead code** — Removed unused `personaPath` variable in `listAgents`
39
+
40
+ ### Added
41
+
42
+ - `CircuitBreaker.recordFailure()` — Synchronous failure recording for use by KeyPool
43
+ - Generated agent README: "Populating Your Agent" section (conversational, bulk, JSON methods)
44
+ - Generated agent README: "Why {name}" value proposition, expanded "How to Use" with daily workflow, "Growing Your Agent" section
45
+
46
+ ## [2.0.0] - 2026-02-20
47
+
48
+ Major release. Agents now ship with an intelligence layer (Brain) and optional LLM infrastructure — every generated agent is smarter out of the box.
49
+
50
+ ### Added
51
+
52
+ - **Intelligence Layer (Brain)** — TF-IDF hybrid scoring across 5 dimensions: semantic similarity (40%), severity (15%), recency (15%), tag overlap (15%), domain match (15%). Auto-tags entries on capture. Detects duplicates before writing (blocks at >= 0.8, warns at >= 0.6). Adaptive weight tuning after 30+ feedback entries
53
+ - **LLM Client** — Unified OpenAI/Anthropic caller with multi-key rotation, per-key circuit breakers (threshold 3, reset 30s), shared provider breaker (threshold 5, reset 60s), exponential backoff with jitter, and model routing. Optional — agents work without API keys
54
+ - **Key Pool** — Multi-key management for OpenAI with preemptive quota rotation (threshold 50). Loads from `~/.{agentId}/keys.json` or falls back to env vars
55
+ - **Model Router** — Routes LLM calls by caller/task. Reads `~/.{agentId}/model-routing.json` for custom routing rules
56
+ - **SecretString** — Credential wrapper using ES2022 private fields. Prevents key leakage in JSON.stringify, console.log, template literals, and Node inspect
57
+ - **Circuit Breaker** — 3-state protection (closed/open/half-open) for external service calls. Only counts retryable errors toward threshold
58
+ - **Rate Limit Parser** — Parses OpenAI `x-ratelimit-remaining-requests`, `x-ratelimit-reset-requests`, and `retry-after` headers for quota tracking
59
+ - **Brain ops** — `record_feedback`, `rebuild_vocabulary`, `brain_stats` on core facade
60
+ - **`llm_status` op** — Provider availability, key pool status (per-key circuit breaker states), model routing config
61
+ - **LLM test suite** — ~51 tests covering SecretString, CircuitBreaker states, retry, rate limits, KeyPool rotation, LLMClient availability
62
+ - **Brain test suite** — ~38 tests covering TF-IDF scoring, auto-tagging, duplicate detection, adaptive weights
63
+ - **Roadmap** — Each generated agent README includes an 8-item improvement roadmap: curator, intake, learning, embeddings, cross-project memory, context engine, proactive agency, plugin system
64
+
65
+ ### Changed
66
+
67
+ - Domain facades now use Brain for search (`intelligentSearch`) and capture (`enrichAndCapture` with auto-tags and dedup) instead of raw vault queries
68
+ - Core facade signature expanded: `createCoreFacade(vault, planner, brain, llmClient?, openaiKeyPool?, anthropicKeyPool?)`
69
+ - Generated agents include `@anthropic-ai/sdk` as a dependency
70
+ - Activation triggers normalized: "Hola/Adios" → "Hello/Goodbye"
71
+ - Vault schema adds `brain_vocabulary` and `brain_feedback` tables
72
+ - Total core ops per agent: 24 (was 20)
73
+ - Total generated tests per 3-domain agent: ~220 (was ~120)
74
+ - Agent-forge tests: 21 (was 19)
75
+ - Template generators: 27 (was 22)
76
+ - Generated files per agent: ~37 (was ~30)
77
+
78
+ ## [1.0.0] - 2026-02-19
79
+
80
+ First stable release. Forge is a pure scaffolding tool — knowledge-agnostic, zero opinions on content. It builds the infrastructure; you fill in the expertise.
81
+
82
+ ### Added
83
+
84
+ - **MCP Server** — Agent Forge runs as an MCP server with a single `forge` tool and 4 operations: `guide`, `preview`, `create`, `list_agents`
85
+ - **Scaffolding Engine** — Generates 30 files per agent from 22 TypeScript template generators
86
+ - **Knowledge Vault** — Each agent gets SQLite storage with FTS5 full-text search and BM25 ranking. Domains start empty
87
+ - **Domain Facades** — Each knowledge domain becomes its own MCP tool with `get_patterns`, `search`, `get_entry`, `capture`, and `remove` operations
88
+ - **Core Facade** — 20 shared operations including search, vault stats, health, identity, activation, memory, session capture, export, and planning
89
+ - **Memory System** — Three memory types (session, lesson, preference) with FTS5 search, stored in the vault database
90
+ - **Session Capture** — PreCompact hook auto-captures session summaries before Claude Code compacts context
91
+ - **Planning Engine** — JSON-backed state machine with 4 plan states (draft, approved, executing, completed) and 5 task states (pending, in_progress, completed, skipped, failed)
92
+ - **Export** — Dumps vault entries back to JSON intelligence bundles for version control and sharing
93
+ - **Activation System** — Persona-based activation with automatic CLAUDE.md injection
94
+ - **Project Registration** — Agents track which projects they're advising and surface context on activation
95
+ - **Setup Script** — One-command install, build, and `claude mcp add --scope user` registration
96
+ - **Test Generation** — 4 test suites per agent (vault, loader, facades, planner) totaling 120+ tests
97
+ - **README Generation** — Each agent gets a complete README with quick start, domains, principles, and commands
98
+ - **Zod Validation** — All agent configs validated at creation time with clear error messages
package/README.md ADDED
@@ -0,0 +1,199 @@
1
+ # @soleri/forge
2
+
3
+ Create production-ready MCP agents in seconds.
4
+
5
+ Soleri Forge is an MCP server that scaffolds complete [Model Context Protocol](https://modelcontextprotocol.io/) agents — each with its own knowledge vault, intelligence layer, LLM client, memory system, planning engine, and activation persona. You describe what the agent should do, and Forge generates everything: source code, tests, config, and setup scripts.
6
+
7
+ Forge is knowledge-agnostic. It builds the infrastructure — you fill in the expertise.
8
+
9
+ Part of the [Soleri](https://soleri.dev) framework — building AI assistants that learn, remember, and grow with you.
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Register with Claude Code
14
+
15
+ ```bash
16
+ claude mcp add --scope user soleri -- node /path/to/soleri/packages/forge/dist/index.js
17
+ ```
18
+
19
+ ### 2. Create an agent
20
+
21
+ In any Claude Code session, tell Claude what agent you want:
22
+
23
+ ```
24
+ I need an agent called Gaudi that advises on backend architecture.
25
+ Domains: api-design, database, architecture, security, testing, performance.
26
+ Principles: "Security is not optional", "Simple beats clever", "Test everything that can break".
27
+ ```
28
+
29
+ Claude will use the `forge` tool to scaffold it. Under the hood:
30
+
31
+ ```
32
+ forge op:preview params:{ id: "gaudi", name: "Gaudi", ... } # See what will be created
33
+ forge op:create params:{ id: "gaudi", name: "Gaudi", ... } # Scaffold the agent
34
+ ```
35
+
36
+ You can also run `forge op:guide` to get a step-by-step creation flow.
37
+
38
+ ### 3. Build and activate
39
+
40
+ ```bash
41
+ cd gaudi
42
+ ./scripts/setup.sh # Install, build, register with Claude Code
43
+ ```
44
+
45
+ Then in a new Claude Code session:
46
+
47
+ ```
48
+ Hello, Gaudi!
49
+ ```
50
+
51
+ Your agent is live.
52
+
53
+ ## What Gets Generated
54
+
55
+ Every agent ships with a complete, tested architecture — and zero pre-loaded knowledge:
56
+
57
+ ```
58
+ my-agent/
59
+ src/
60
+ facades/ # MCP tool dispatch (one per domain + core)
61
+ vault/ # SQLite + FTS5 full-text search
62
+ brain/ # TF-IDF intelligence layer
63
+ llm/ # Unified OpenAI/Anthropic client (optional)
64
+ intelligence/ # Domain knowledge (empty JSON bundles)
65
+ identity/ # Agent persona and principles
66
+ activation/ # CLAUDE.md injection + activation flow
67
+ planning/ # Multi-step plan state machine
68
+ __tests__/ # 6 test suites (~220 tests)
69
+ scripts/
70
+ setup.sh # One-command install, build, register
71
+ copy-assets.js # Build script for intelligence data
72
+ ```
73
+
74
+ ### Core Capabilities
75
+
76
+ | Capability | What It Does |
77
+ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
78
+ | **Knowledge Vault** | SQLite-backed storage with FTS5 full-text search and BM25 ranking |
79
+ | **Intelligence Layer (Brain)** | TF-IDF hybrid scoring across 5 dimensions, auto-tagging, duplicate detection, adaptive weight tuning |
80
+ | **LLM Client** | Unified OpenAI/Anthropic caller with multi-key rotation, per-key circuit breakers, model routing (optional — works without API keys) |
81
+ | **Domain Facades** | Each knowledge domain becomes its own MCP tool with search, capture, and pattern ops |
82
+ | **Memory System** | Persists session summaries, lessons learned, and preferences across sessions |
83
+ | **Planning Engine** | State machine for multi-step tasks: draft, approve, execute, complete |
84
+ | **Activation** | Persona-based activation with `Hello!` / `Goodbye!` — injects CLAUDE.md automatically |
85
+
86
+ ### Generated Operations
87
+
88
+ Each agent exposes two types of MCP tools:
89
+
90
+ **Domain tools** (`{agent}_{domain}`) — one per knowledge domain:
91
+
92
+ - `get_patterns` `search` `get_entry` `capture` `remove`
93
+
94
+ **Core tool** (`{agent}_core`) — shared infrastructure:
95
+
96
+ - `search` `vault_stats` `list_all` `health` `identity`
97
+ - `activate` `inject_claude_md` `setup` `register`
98
+ - `memory_search` `memory_capture` `memory_list`
99
+ - `session_capture` `export`
100
+ - `create_plan` `get_plan` `approve_plan` `update_task` `complete_plan`
101
+ - `record_feedback` `rebuild_vocabulary` `brain_stats`
102
+ - `llm_status`
103
+
104
+ Total: `(domains x 5) + 24` operations per agent.
105
+
106
+ ## Forge Operations
107
+
108
+ Soleri Forge exposes one MCP tool (`forge`) with 5 ops:
109
+
110
+ | Op | Purpose |
111
+ | ------------------- | ----------------------------------------------- |
112
+ | `guide` | Step-by-step creation flow for the AI to follow |
113
+ | `preview` | See what files and facades will be created |
114
+ | `create` | Scaffold the complete agent project |
115
+ | `list_agents` | Scan a directory for existing agents |
116
+ | `install_knowledge` | Install knowledge packs into an existing agent |
117
+
118
+ ## Installing Knowledge Packs
119
+
120
+ Agents start empty — but you don't have to populate them one entry at a time. Knowledge packs are pre-built JSON bundles containing patterns, anti-patterns, and rules for specific domains.
121
+
122
+ ```
123
+ forge op:install_knowledge params:{
124
+ agentPath: "/path/to/gaudi",
125
+ bundlePath: "/path/to/knowledge-packs/bundles"
126
+ }
127
+ ```
128
+
129
+ ### Bundle Format
130
+
131
+ ```json
132
+ {
133
+ "domain": "accessibility",
134
+ "version": "1.0.0",
135
+ "entries": [
136
+ {
137
+ "id": "a11y-color-contrast",
138
+ "type": "pattern",
139
+ "domain": "accessibility",
140
+ "title": "Color Contrast Ratios",
141
+ "severity": "critical",
142
+ "description": "Ensure text meets WCAG AA contrast ratio...",
143
+ "tags": ["wcag", "contrast", "color"]
144
+ }
145
+ ]
146
+ }
147
+ ```
148
+
149
+ ## Configuration
150
+
151
+ ```json
152
+ {
153
+ "id": "gaudi",
154
+ "name": "Gaudi",
155
+ "role": "Backend Architecture Advisor",
156
+ "description": "Gaudi provides guidance on API design, database patterns, and system architecture.",
157
+ "domains": ["api-design", "database", "architecture", "security", "testing", "performance"],
158
+ "principles": [
159
+ "Security is not optional",
160
+ "Simple beats clever",
161
+ "Test everything that can break"
162
+ ],
163
+ "greeting": "Gaudi here. Let's build something solid.",
164
+ "outputDir": "/Users/you/projects"
165
+ }
166
+ ```
167
+
168
+ ## Development
169
+
170
+ ```bash
171
+ # From monorepo root
172
+ npm install
173
+ npm run build --workspace=@soleri/forge
174
+ npm run test --workspace=@soleri/forge
175
+
176
+ # Or from packages/forge
177
+ npm run dev # Run with tsx (no build needed)
178
+ npm test # Run tests
179
+ ```
180
+
181
+ ### Architecture
182
+
183
+ Soleri Forge is itself an MCP server built on the same patterns it generates:
184
+
185
+ - **`src/index.ts`** — MCP server entry point, registers the `forge` tool
186
+ - **`src/facades/forge.facade.ts`** — Op dispatch for all forge operations
187
+ - **`src/scaffolder.ts`** — Core scaffolding logic (preview, create, list)
188
+ - **`src/knowledge-installer.ts`** — Knowledge pack installer
189
+ - **`src/types.ts`** — Config schema and result types (Zod-validated)
190
+ - **`src/templates/`** — 27 template generators
191
+
192
+ ## Requirements
193
+
194
+ - Node.js 18+
195
+ - Claude Code (for MCP registration and activation)
196
+
197
+ ## License
198
+
199
+ Apache-2.0
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ interface OpDef {
3
+ name: string;
4
+ description: string;
5
+ schema?: z.ZodType;
6
+ handler: (params: Record<string, unknown>) => Promise<unknown>;
7
+ }
8
+ export declare const forgeOps: OpDef[];
9
+ export {};
@@ -0,0 +1,134 @@
1
+ import { z } from 'zod';
2
+ import { scaffold, previewScaffold, listAgents } from '../scaffolder.js';
3
+ import { AgentConfigSchema } from '../types.js';
4
+ import { installKnowledge } from '../knowledge-installer.js';
5
+ export const forgeOps = [
6
+ {
7
+ name: 'preview',
8
+ description: 'Preview what will be created for an agent BEFORE scaffolding. ' +
9
+ 'Show this to the user so they can confirm the structure looks right. ' +
10
+ 'Always call preview before create.',
11
+ schema: AgentConfigSchema,
12
+ handler: async (params) => {
13
+ const config = AgentConfigSchema.parse(params);
14
+ return previewScaffold(config);
15
+ },
16
+ },
17
+ {
18
+ name: 'create',
19
+ description: 'Scaffold a complete MCP agent project with activation system. ' +
20
+ 'This creates the full directory structure, source files, config, and activation module. ' +
21
+ 'After creation: npm install && npm run build, then say "Hello, {Name}!" to activate.',
22
+ schema: AgentConfigSchema,
23
+ handler: async (params) => {
24
+ const config = AgentConfigSchema.parse(params);
25
+ return scaffold(config);
26
+ },
27
+ },
28
+ {
29
+ name: 'list_agents',
30
+ description: 'List all agents found in a directory. ' +
31
+ 'Useful to see what agents already exist before creating a new one.',
32
+ schema: z.object({
33
+ directory: z.string().describe('Parent directory to scan for agent projects'),
34
+ }),
35
+ handler: async (params) => {
36
+ const agents = listAgents(params.directory);
37
+ return {
38
+ agents,
39
+ count: agents.length,
40
+ note: agents.length === 0 ? 'No agents found. Use create to scaffold one.' : undefined,
41
+ };
42
+ },
43
+ },
44
+ {
45
+ name: 'guide',
46
+ description: 'Get a structured guide for the AI agent to follow when helping a user create an agent. ' +
47
+ 'This provides the recommended conversation flow and questions to ask.',
48
+ handler: async () => {
49
+ return {
50
+ title: 'Agent Creation Guide',
51
+ instructions: 'Follow these steps to help the user create a new MCP agent. Ask questions conversationally — do not dump all questions at once.',
52
+ steps: [
53
+ {
54
+ step: 1,
55
+ action: 'Understand the need',
56
+ ask: 'What role should this agent fill? Who will use it? What kind of guidance should it provide?',
57
+ examples: [
58
+ 'backend architecture advisor',
59
+ 'QA testing patterns',
60
+ 'data engineering best practices',
61
+ ],
62
+ },
63
+ {
64
+ step: 2,
65
+ action: 'Choose name and identity',
66
+ ask: 'What should we name this agent? A good name is memorable and reflects its domain.',
67
+ tips: [
68
+ 'Single word works best (Gaudi, Atlas, Nova)',
69
+ 'The name becomes the persona — it will introduce itself with this name',
70
+ ],
71
+ },
72
+ {
73
+ step: 3,
74
+ action: 'Select domains',
75
+ ask: 'What knowledge domains should this agent cover? Domain names should be kebab-case (e.g., api-design, database, security).',
76
+ tips: [
77
+ '3-6 domains is ideal',
78
+ 'Each domain becomes a facade (MCP tool) and an intelligence data file',
79
+ 'User can always add more later',
80
+ ],
81
+ },
82
+ {
83
+ step: 4,
84
+ action: 'Define principles',
85
+ ask: 'What are 3-5 core principles this agent should follow? These shape its personality and advice style.',
86
+ examples: [
87
+ 'Security first — always validate inputs',
88
+ 'Simplicity over cleverness',
89
+ 'Test everything that can break',
90
+ ],
91
+ },
92
+ {
93
+ step: 5,
94
+ action: 'Preview and confirm',
95
+ ask: 'Call preview with the collected config. Show the user what will be created. Ask for confirmation.',
96
+ },
97
+ {
98
+ step: 6,
99
+ action: 'Create the agent',
100
+ ask: 'Call create with the confirmed config. Then guide the user through npm install and npm run build. The MCP server is automatically registered in ~/.claude.json.',
101
+ },
102
+ {
103
+ step: 7,
104
+ action: 'Next steps',
105
+ suggest: [
106
+ 'Restart Claude Code so the new MCP server is picked up',
107
+ 'Say "Hello, {AgentName}!" to activate the persona in any session',
108
+ 'The agent will check setup status and offer to inject its CLAUDE.md sections',
109
+ 'Add initial knowledge by creating entries in the intelligence data JSON files',
110
+ 'Or use the agent and capture knowledge via the capture ops as you work',
111
+ ],
112
+ },
113
+ ],
114
+ };
115
+ },
116
+ },
117
+ {
118
+ name: 'install_knowledge',
119
+ description: 'Install knowledge packs (intelligence bundles) into an existing MCP agent. ' +
120
+ 'Copies bundle JSON files, generates domain facades for new domains, ' +
121
+ 'patches index.ts and claude-md-content.ts, then rebuilds.',
122
+ schema: z.object({
123
+ agentPath: z.string().describe('Absolute path to the target agent project'),
124
+ bundlePath: z.string().describe('Path to bundles directory or single .json file'),
125
+ generateFacades: z
126
+ .boolean()
127
+ .optional()
128
+ .default(true)
129
+ .describe('Generate domain facades for new domains (default true)'),
130
+ }),
131
+ handler: async (params) => installKnowledge(params),
132
+ },
133
+ ];
134
+ //# sourceMappingURL=forge.facade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge.facade.js","sourceRoot":"","sources":["../../src/facades/forge.facade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { z } from 'zod';
5
+ import { forgeOps } from './facades/forge.facade.js';
6
+ async function main() {
7
+ const server = new McpServer({
8
+ name: 'soleri',
9
+ version: '3.0.0',
10
+ });
11
+ // Register the forge tool with op dispatch
12
+ const opNames = forgeOps.map((o) => o.name);
13
+ server.tool('forge', `Soleri Forge — scaffold AI agents that learn, remember, and grow.\n\nOperations: ${opNames.join(', ')}\n\nStart by calling 'guide' to get the recommended conversation flow for helping a user create an agent.`, {
14
+ op: z.string().describe(`Operation: ${opNames.join(' | ')}`),
15
+ params: z.record(z.unknown()).optional().default({}).describe('Operation parameters'),
16
+ }, async ({ op, params }) => {
17
+ const opDef = forgeOps.find((o) => o.name === op);
18
+ if (!opDef) {
19
+ return {
20
+ content: [
21
+ {
22
+ type: 'text',
23
+ text: JSON.stringify({
24
+ success: false,
25
+ error: `Unknown operation "${op}". Available: ${opNames.join(', ')}`,
26
+ }, null, 2),
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ try {
32
+ let validatedParams = params;
33
+ if (opDef.schema) {
34
+ const result = opDef.schema.safeParse(params);
35
+ if (!result.success) {
36
+ return {
37
+ content: [
38
+ {
39
+ type: 'text',
40
+ text: JSON.stringify({ success: false, error: result.error.message }, null, 2),
41
+ },
42
+ ],
43
+ };
44
+ }
45
+ validatedParams = result.data;
46
+ }
47
+ const data = await opDef.handler(validatedParams);
48
+ return {
49
+ content: [
50
+ {
51
+ type: 'text',
52
+ text: JSON.stringify({ success: true, data }, null, 2),
53
+ },
54
+ ],
55
+ };
56
+ }
57
+ catch (err) {
58
+ return {
59
+ content: [
60
+ {
61
+ type: 'text',
62
+ text: JSON.stringify({
63
+ success: false,
64
+ error: err instanceof Error ? err.message : String(err),
65
+ }, null, 2),
66
+ },
67
+ ],
68
+ };
69
+ }
70
+ });
71
+ console.error('[soleri] Soleri Forge — AI agent scaffolding tool');
72
+ console.error(`[soleri] ${forgeOps.length} operations available`);
73
+ const transport = new StdioServerTransport();
74
+ await server.connect(transport);
75
+ console.error('[soleri] Connected via stdio');
76
+ }
77
+ main().catch((err) => {
78
+ console.error('[soleri] Fatal:', err);
79
+ process.exit(1);
80
+ });
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { InstallKnowledgeResult } from './types.js';
2
+ /**
3
+ * Generate a domain facade for older agents that lack a Brain module.
4
+ * Uses vault.search() instead of brain.intelligentSearch() and
5
+ * vault.add() instead of brain.enrichAndCapture().
6
+ */
7
+ export declare function generateVaultOnlyDomainFacade(agentId: string, domain: string): string;
8
+ export interface InstallKnowledgeParams {
9
+ agentPath: string;
10
+ bundlePath: string;
11
+ generateFacades?: boolean;
12
+ }
13
+ export declare function installKnowledge(params: InstallKnowledgeParams): Promise<InstallKnowledgeResult>;
14
+ /**
15
+ * Patch the agent's src/index.ts to add imports and facade registrations
16
+ * for new domains.
17
+ *
18
+ * Anchor patterns:
19
+ * - Import: insert before `import { createCoreFacade }`
20
+ * - Facade array: insert before `createCoreFacade(`
21
+ */
22
+ export declare function patchIndexTs(source: string, newDomains: string[], hasBrain: boolean): string | null;
23
+ /**
24
+ * Patch the agent's src/activation/claude-md-content.ts to add
25
+ * facade table rows for new domains.
26
+ *
27
+ * Primary anchor: line containing `| Memory search |` (newer agents)
28
+ * Fallback anchor: line containing `## Intent Detection` (older agents without memory/brain rows)
29
+ */
30
+ export declare function patchClaudeMdContent(source: string, agentId: string, newDomains: string[]): string | null;