@soleri/forge 0.0.1 → 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.
- package/CHANGELOG.md +98 -0
- package/README.md +199 -0
- package/dist/facades/forge.facade.d.ts +9 -0
- package/dist/facades/forge.facade.js +134 -0
- package/dist/facades/forge.facade.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge-installer.d.ts +31 -0
- package/dist/knowledge-installer.js +437 -0
- package/dist/knowledge-installer.js.map +1 -0
- package/dist/scaffolder.d.ts +13 -0
- package/dist/scaffolder.js +330 -0
- package/dist/scaffolder.js.map +1 -0
- package/dist/templates/activate.d.ts +9 -0
- package/dist/templates/activate.js +139 -0
- package/dist/templates/activate.js.map +1 -0
- package/dist/templates/brain.d.ts +6 -0
- package/dist/templates/brain.js +478 -0
- package/dist/templates/brain.js.map +1 -0
- package/dist/templates/claude-md-template.d.ts +11 -0
- package/dist/templates/claude-md-template.js +73 -0
- package/dist/templates/claude-md-template.js.map +1 -0
- package/dist/templates/core-facade.d.ts +6 -0
- package/dist/templates/core-facade.js +456 -0
- package/dist/templates/core-facade.js.map +1 -0
- package/dist/templates/domain-facade.d.ts +7 -0
- package/dist/templates/domain-facade.js +119 -0
- package/dist/templates/domain-facade.js.map +1 -0
- package/dist/templates/entry-point.d.ts +5 -0
- package/dist/templates/entry-point.js +116 -0
- package/dist/templates/entry-point.js.map +1 -0
- package/dist/templates/facade-factory.d.ts +1 -0
- package/dist/templates/facade-factory.js +63 -0
- package/dist/templates/facade-factory.js.map +1 -0
- package/dist/templates/facade-types.d.ts +1 -0
- package/dist/templates/facade-types.js +46 -0
- package/dist/templates/facade-types.js.map +1 -0
- package/dist/templates/inject-claude-md.d.ts +11 -0
- package/dist/templates/inject-claude-md.js +92 -0
- package/dist/templates/inject-claude-md.js.map +1 -0
- package/dist/templates/intelligence-loader.d.ts +1 -0
- package/dist/templates/intelligence-loader.js +43 -0
- package/dist/templates/intelligence-loader.js.map +1 -0
- package/dist/templates/intelligence-types.d.ts +1 -0
- package/dist/templates/intelligence-types.js +24 -0
- package/dist/templates/intelligence-types.js.map +1 -0
- package/dist/templates/llm-client.d.ts +7 -0
- package/dist/templates/llm-client.js +300 -0
- package/dist/templates/llm-client.js.map +1 -0
- package/dist/templates/llm-key-pool.d.ts +7 -0
- package/dist/templates/llm-key-pool.js +211 -0
- package/dist/templates/llm-key-pool.js.map +1 -0
- package/dist/templates/llm-types.d.ts +5 -0
- package/dist/templates/llm-types.js +161 -0
- package/dist/templates/llm-types.js.map +1 -0
- package/dist/templates/llm-utils.d.ts +5 -0
- package/dist/templates/llm-utils.js +260 -0
- package/dist/templates/llm-utils.js.map +1 -0
- package/dist/templates/package-json.d.ts +2 -0
- package/dist/templates/package-json.js +37 -0
- package/dist/templates/package-json.js.map +1 -0
- package/dist/templates/persona.d.ts +2 -0
- package/dist/templates/persona.js +42 -0
- package/dist/templates/persona.js.map +1 -0
- package/dist/templates/planner.d.ts +5 -0
- package/dist/templates/planner.js +150 -0
- package/dist/templates/planner.js.map +1 -0
- package/dist/templates/readme.d.ts +5 -0
- package/dist/templates/readme.js +316 -0
- package/dist/templates/readme.js.map +1 -0
- package/dist/templates/setup-script.d.ts +6 -0
- package/dist/templates/setup-script.js +112 -0
- package/dist/templates/setup-script.js.map +1 -0
- package/dist/templates/test-brain.d.ts +6 -0
- package/dist/templates/test-brain.js +474 -0
- package/dist/templates/test-brain.js.map +1 -0
- package/dist/templates/test-facades.d.ts +6 -0
- package/dist/templates/test-facades.js +649 -0
- package/dist/templates/test-facades.js.map +1 -0
- package/dist/templates/test-llm.d.ts +7 -0
- package/dist/templates/test-llm.js +574 -0
- package/dist/templates/test-llm.js.map +1 -0
- package/dist/templates/test-loader.d.ts +5 -0
- package/dist/templates/test-loader.js +146 -0
- package/dist/templates/test-loader.js.map +1 -0
- package/dist/templates/test-planner.d.ts +5 -0
- package/dist/templates/test-planner.js +271 -0
- package/dist/templates/test-planner.js.map +1 -0
- package/dist/templates/test-vault.d.ts +5 -0
- package/dist/templates/test-vault.js +380 -0
- package/dist/templates/test-vault.js.map +1 -0
- package/dist/templates/tsconfig.d.ts +1 -0
- package/dist/templates/tsconfig.js +25 -0
- package/dist/templates/tsconfig.js.map +1 -0
- package/dist/templates/vault.d.ts +5 -0
- package/dist/templates/vault.js +263 -0
- package/dist/templates/vault.js.map +1 -0
- package/dist/templates/vitest-config.d.ts +1 -0
- package/dist/templates/vitest-config.js +27 -0
- package/dist/templates/vitest-config.js.map +1 -0
- package/dist/types.d.ts +89 -0
- package/dist/types.js +21 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -4
- package/src/__tests__/knowledge-installer.test.ts +805 -0
- package/src/__tests__/scaffolder.test.ts +323 -0
- package/src/facades/forge.facade.ts +150 -0
- package/src/index.ts +101 -0
- package/src/knowledge-installer.ts +532 -0
- package/src/scaffolder.ts +386 -0
- package/src/templates/activate.ts +145 -0
- package/src/templates/claude-md-template.ts +137 -0
- package/src/templates/core-facade.ts +457 -0
- package/src/templates/domain-facade.ts +121 -0
- package/src/templates/entry-point.ts +120 -0
- package/src/templates/inject-claude-md.ts +94 -0
- package/src/templates/llm-client.ts +301 -0
- package/src/templates/package-json.ts +39 -0
- package/src/templates/persona.ts +45 -0
- package/src/templates/readme.ts +319 -0
- package/src/templates/setup-script.ts +113 -0
- package/src/templates/test-facades.ts +656 -0
- package/src/templates/tsconfig.ts +25 -0
- package/src/templates/vitest-config.ts +26 -0
- package/src/types.ts +68 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import type { AgentConfig } from '../types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a README.md for the scaffolded agent.
|
|
5
|
+
*/
|
|
6
|
+
export function generateReadme(config: AgentConfig): string {
|
|
7
|
+
const domainRows = config.domains
|
|
8
|
+
.map((d) => `| ${d} | *Ready for knowledge capture* |`)
|
|
9
|
+
.join('\n');
|
|
10
|
+
|
|
11
|
+
const principleLines = config.principles.map((p) => `- ${p}`).join('\n');
|
|
12
|
+
|
|
13
|
+
return `# ${config.name} — ${config.role}
|
|
14
|
+
|
|
15
|
+
${config.description}
|
|
16
|
+
|
|
17
|
+
## Why ${config.name}
|
|
18
|
+
|
|
19
|
+
Every team accumulates knowledge — patterns that work, mistakes to avoid, architectural decisions and their reasoning. Without a system, this knowledge lives in people's heads, scattered docs, or buried in Slack threads. When someone leaves or context shifts, it's gone.
|
|
20
|
+
|
|
21
|
+
${config.name} is your team's persistent knowledge layer. It:
|
|
22
|
+
- **Remembers** patterns, decisions, and lessons across sessions and projects
|
|
23
|
+
- **Retrieves** the right knowledge at the right time using intelligent search
|
|
24
|
+
- **Learns** from your feedback — accepted suggestions boost similar patterns, dismissed ones fade
|
|
25
|
+
- **Plans** multi-step tasks and tracks execution
|
|
26
|
+
- **Grows** with every interaction — the more you use it, the smarter it gets
|
|
27
|
+
|
|
28
|
+
The agent starts empty. That's intentional. Your expertise is the content; ${config.name} is the infrastructure that makes it searchable, persistent, and always available.
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
\`\`\`bash
|
|
33
|
+
# 1. Install and build
|
|
34
|
+
cd ${config.id}
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
|
|
38
|
+
# 2. Add to Claude Code
|
|
39
|
+
./scripts/setup.sh
|
|
40
|
+
|
|
41
|
+
# 3. Start a new Claude Code session, then say:
|
|
42
|
+
# "Hello, ${config.name}!"
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
That's it. ${config.name} will activate, check your setup, and offer to configure itself.
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- **Node.js 18+** — \`node --version\` to check
|
|
50
|
+
- **Claude Code** — Anthropic's CLI for Claude (\`claude\` command)
|
|
51
|
+
|
|
52
|
+
## What Happens When You Say "Hello, ${config.name}!"
|
|
53
|
+
|
|
54
|
+
1. ${config.name} returns its persona, principles, and tool recommendations
|
|
55
|
+
2. Claude adopts the ${config.name} persona for the rest of the session
|
|
56
|
+
3. ${config.name} checks if your project has CLAUDE.md integration
|
|
57
|
+
4. If not, it offers to inject its configuration (facades table, intent detection, knowledge protocol)
|
|
58
|
+
|
|
59
|
+
## Manual Setup (if setup.sh doesn't work)
|
|
60
|
+
|
|
61
|
+
Add this to \`~/.claude/settings.json\` under \`mcpServers\`:
|
|
62
|
+
|
|
63
|
+
\`\`\`json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"${config.id}": {
|
|
67
|
+
"command": "node",
|
|
68
|
+
"args": ["dist/index.js"],
|
|
69
|
+
"cwd": "/absolute/path/to/${config.id}"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
Then restart Claude Code.
|
|
76
|
+
|
|
77
|
+
## Domains
|
|
78
|
+
|
|
79
|
+
| Domain | What it covers |
|
|
80
|
+
|--------|---------------|
|
|
81
|
+
${domainRows}
|
|
82
|
+
|
|
83
|
+
## Core Principles
|
|
84
|
+
|
|
85
|
+
${principleLines}
|
|
86
|
+
|
|
87
|
+
## Features
|
|
88
|
+
|
|
89
|
+
### Knowledge Vault
|
|
90
|
+
SQLite-backed knowledge storage with FTS5 full-text search. Domains start empty and grow as you capture patterns.
|
|
91
|
+
|
|
92
|
+
### Intelligence Layer (Brain)
|
|
93
|
+
A local, zero-dependency intelligence layer that sits between facades and vault:
|
|
94
|
+
- **TF-IDF + Hybrid Scoring** — Re-ranks search results across 5 dimensions: semantic similarity (40%), severity (15%), recency (15%), tag overlap (15%), domain match (15%)
|
|
95
|
+
- **Auto-Tagging** — Extracts tags from title + description using TF-IDF scoring on capture
|
|
96
|
+
- **Duplicate Detection** — Checks similarity before capture: blocks at >= 0.8, warns at >= 0.6
|
|
97
|
+
- **Adaptive Weights** — Tracks accepted/dismissed results; after 30+ feedback entries, scoring weights auto-tune
|
|
98
|
+
- **Graceful Degradation** — Works immediately on empty vaults; falls back to severity + recency when vocabulary is empty
|
|
99
|
+
|
|
100
|
+
### Memory System
|
|
101
|
+
Captures session summaries, lessons learned, and user preferences. Memories persist across sessions and are searchable.
|
|
102
|
+
|
|
103
|
+
### Session Capture
|
|
104
|
+
A PreCompact hook automatically captures session summaries before context compaction, preserving context across sessions.
|
|
105
|
+
|
|
106
|
+
### Planning
|
|
107
|
+
Multi-step task planning with state machine: draft → approved → executing → completed. Plans are surfaced on activation.
|
|
108
|
+
|
|
109
|
+
### Export
|
|
110
|
+
Export vault knowledge as JSON bundles for version control and sharing.
|
|
111
|
+
|
|
112
|
+
### LLM Client (Optional)
|
|
113
|
+
Unified OpenAI/Anthropic client with multi-key rotation, circuit breakers, and model routing. Works without configuration — capabilities unlock when API keys are provided.
|
|
114
|
+
|
|
115
|
+
**Setup:**
|
|
116
|
+
Create \`~/.${config.id}/keys.json\`:
|
|
117
|
+
\`\`\`json
|
|
118
|
+
{
|
|
119
|
+
"openai": ["sk-..."],
|
|
120
|
+
"anthropic": ["sk-ant-..."]
|
|
121
|
+
}
|
|
122
|
+
\`\`\`
|
|
123
|
+
|
|
124
|
+
Or set environment variables: \`OPENAI_API_KEY\`, \`ANTHROPIC_API_KEY\`.
|
|
125
|
+
|
|
126
|
+
**Model routing** (optional) — \`~/.${config.id}/model-routing.json\`:
|
|
127
|
+
\`\`\`json
|
|
128
|
+
{
|
|
129
|
+
"routes": [],
|
|
130
|
+
"defaultOpenAIModel": "gpt-4o-mini",
|
|
131
|
+
"defaultAnthropicModel": "claude-sonnet-4-20250514"
|
|
132
|
+
}
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
Use \`llm_status\` to check provider availability and key pool health.
|
|
136
|
+
|
|
137
|
+
## How to Use
|
|
138
|
+
|
|
139
|
+
### Activating and Deactivating
|
|
140
|
+
|
|
141
|
+
- **"Hello, ${config.name}!"** — Activate the persona. Claude adopts ${config.name}'s identity, principles, and tool access for the session.
|
|
142
|
+
- **"Goodbye, ${config.name}!"** — Deactivate. Claude returns to its default behavior.
|
|
143
|
+
|
|
144
|
+
### Daily Workflow
|
|
145
|
+
|
|
146
|
+
Once active, ${config.name} works as your domain advisor. Here's how a typical session looks:
|
|
147
|
+
|
|
148
|
+
**Ask for guidance** — ${config.name} searches its vault and responds with relevant patterns:
|
|
149
|
+
\\\`\\\`\\\`
|
|
150
|
+
You: How should we handle rate limiting?
|
|
151
|
+
${config.name}: [searches vault] Based on my patterns, here's what I recommend...
|
|
152
|
+
\\\`\\\`\\\`
|
|
153
|
+
|
|
154
|
+
**Capture knowledge** — When you discover something worth remembering, tell ${config.name} to capture it:
|
|
155
|
+
\\\`\\\`\\\`
|
|
156
|
+
You: We decided to use token bucket for rate limiting. Capture this as a pattern.
|
|
157
|
+
${config.name}: [captures to vault with auto-tags: rate-limiting, token-bucket, api-design]
|
|
158
|
+
\\\`\\\`\\\`
|
|
159
|
+
|
|
160
|
+
**Plan multi-step work** — For larger tasks, ${config.name} creates trackable plans:
|
|
161
|
+
\\\`\\\`\\\`
|
|
162
|
+
You: Plan out the caching implementation.
|
|
163
|
+
${config.name}: Created plan "Add Caching Layer" with 4 tasks:
|
|
164
|
+
1. Define cache invalidation strategy
|
|
165
|
+
2. Add Redis client configuration
|
|
166
|
+
3. Implement cache middleware
|
|
167
|
+
4. Add cache-related tests
|
|
168
|
+
Approve to start execution?
|
|
169
|
+
\\\`\\\`\\\`
|
|
170
|
+
|
|
171
|
+
**Give feedback** — When ${config.name} suggests something, your response teaches it:
|
|
172
|
+
\\\`\\\`\\\`
|
|
173
|
+
You: That pattern doesn't apply here — we're using GraphQL, not REST.
|
|
174
|
+
${config.name}: [records feedback] Got it. I'll adjust future recommendations.
|
|
175
|
+
\\\`\\\`\\\`
|
|
176
|
+
|
|
177
|
+
**Search across sessions** — Knowledge persists. Next week, next month, different project:
|
|
178
|
+
\\\`\\\`\\\`
|
|
179
|
+
You: What did we decide about rate limiting last month?
|
|
180
|
+
${config.name}: [searches vault + memory] You chose token bucket with...
|
|
181
|
+
\\\`\\\`\\\`
|
|
182
|
+
|
|
183
|
+
### Key Operations
|
|
184
|
+
|
|
185
|
+
| What you want | What to say |
|
|
186
|
+
|---------------|-------------|
|
|
187
|
+
| Search knowledge | Ask any domain question |
|
|
188
|
+
| Capture a pattern | "Capture this as a pattern" / "Remember this" |
|
|
189
|
+
| Create a plan | "Plan out [task]" |
|
|
190
|
+
| Check vault health | "What's in your vault?" / "Vault stats" |
|
|
191
|
+
| Export knowledge | "Export your knowledge as JSON" |
|
|
192
|
+
| Check LLM status | "LLM status" (if API keys configured) |
|
|
193
|
+
|
|
194
|
+
## Populating Your Agent
|
|
195
|
+
|
|
196
|
+
${config.name} starts with an empty vault. Here's how to fill it with knowledge.
|
|
197
|
+
|
|
198
|
+
### One at a Time (conversational capture)
|
|
199
|
+
|
|
200
|
+
The simplest way — tell ${config.name} what you've learned and ask it to capture:
|
|
201
|
+
|
|
202
|
+
\\\`\\\`\\\`
|
|
203
|
+
You: We decided to use token bucket for rate limiting with a 100 req/min limit.
|
|
204
|
+
Capture this as a pattern in api-design.
|
|
205
|
+
|
|
206
|
+
${config.name}: [captures to vault]
|
|
207
|
+
Captured: api-rate-limiting (pattern, warning)
|
|
208
|
+
Auto-tags: rate-limiting, token-bucket, api-design
|
|
209
|
+
\\\`\\\`\\\`
|
|
210
|
+
|
|
211
|
+
### Bulk Ingestion (document feed)
|
|
212
|
+
|
|
213
|
+
To populate the vault from existing documents (architecture docs, coding standards, RFCs, post-mortems), paste or reference the document and ask ${config.name} to extract patterns:
|
|
214
|
+
|
|
215
|
+
\\\`\\\`\\\`
|
|
216
|
+
You: Here's our API design guide: [paste content or file path]
|
|
217
|
+
Read through it and capture every pattern, anti-pattern, and rule
|
|
218
|
+
into the api-design domain.
|
|
219
|
+
|
|
220
|
+
${config.name}: [reads document, extracts and captures each pattern]
|
|
221
|
+
Captured 12 entries:
|
|
222
|
+
- api-auth-jwt (pattern, critical) — Always use short-lived JWTs
|
|
223
|
+
- api-no-sql-in-controllers (anti-pattern, warning) — Keep SQL in data layer
|
|
224
|
+
- api-pagination-required (rule, warning) — All list endpoints must paginate
|
|
225
|
+
...
|
|
226
|
+
\\\`\\\`\\\`
|
|
227
|
+
|
|
228
|
+
This works with any text: wiki pages, Slack threads, PR review comments, meeting notes. Claude acts as the intake pipeline — it reads, classifies, and calls \\\`capture\\\` for each extracted entry.
|
|
229
|
+
|
|
230
|
+
### JSON Bundles (manual or scripted)
|
|
231
|
+
|
|
232
|
+
For programmatic loading, edit the JSON files directly:
|
|
233
|
+
|
|
234
|
+
\\\`\\\`\\\`json
|
|
235
|
+
// src/intelligence/data/api-design.json
|
|
236
|
+
{
|
|
237
|
+
"domain": "api-design",
|
|
238
|
+
"version": "1.0.0",
|
|
239
|
+
"entries": [
|
|
240
|
+
{
|
|
241
|
+
"id": "api-auth-jwt",
|
|
242
|
+
"type": "pattern",
|
|
243
|
+
"domain": "api-design",
|
|
244
|
+
"title": "Use short-lived JWTs for authentication",
|
|
245
|
+
"severity": "critical",
|
|
246
|
+
"description": "Issue JWTs with 15-minute expiry...",
|
|
247
|
+
"tags": ["auth", "jwt", "security"]
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
\\\`\\\`\\\`
|
|
252
|
+
|
|
253
|
+
Then rebuild (\\\`npm run build\\\`) to pick up the changes. Entries from JSON bundles load on startup.
|
|
254
|
+
|
|
255
|
+
### Tips for Building a Useful Vault
|
|
256
|
+
|
|
257
|
+
- **Start with your team's top 10 decisions** — the ones people keep asking about
|
|
258
|
+
- **Capture anti-patterns from real incidents** — what went wrong and why
|
|
259
|
+
- **Use severity wisely** — \\\`critical\\\` for must-follow rules, \\\`warning\\\` for strong recommendations, \\\`suggestion\\\` for nice-to-haves
|
|
260
|
+
- **Let auto-tagging work** — the Brain extracts tags from titles and descriptions automatically. You can add manual tags too, but you don't have to
|
|
261
|
+
- **Export regularly** — \\\`export\\\` dumps your vault to JSON for version control and sharing with teammates
|
|
262
|
+
|
|
263
|
+
## Growing Your Agent
|
|
264
|
+
|
|
265
|
+
${config.name} gets smarter through use — no code changes needed:
|
|
266
|
+
|
|
267
|
+
1. **Capture patterns** — Every time you capture a decision, pattern, or lesson, the vault grows. The Brain auto-tags entries and detects duplicates.
|
|
268
|
+
2. **Give feedback** — Accept or dismiss suggestions. After 30+ feedback entries, the Brain auto-tunes its scoring weights to match your preferences.
|
|
269
|
+
3. **Use memory** — Session summaries are captured automatically before context compaction. Lessons and preferences persist across sessions.
|
|
270
|
+
4. **Register projects** — Register ${config.name} with multiple projects. It builds context about each one and surfaces relevant knowledge on activation.
|
|
271
|
+
5. **Export and share** — Export vault knowledge as JSON. Share bundles with teammates or back them up in version control.
|
|
272
|
+
|
|
273
|
+
The more you interact, the more valuable ${config.name} becomes. A fresh agent with 50+ captured patterns and a month of feedback is significantly more useful than one on day one.
|
|
274
|
+
|
|
275
|
+
## Roadmap
|
|
276
|
+
|
|
277
|
+
${config.name} ships with a solid foundation. Below are optional improvements you can add yourself, ordered by impact.
|
|
278
|
+
|
|
279
|
+
### 1. Curator Pipeline
|
|
280
|
+
**What:** Background vault maintenance — tag normalization, duplicate merging, quality scoring, stale entry detection.
|
|
281
|
+
**Why:** Without grooming, vault quality degrades over time. Tags drift, duplicates accumulate, outdated entries linger.
|
|
282
|
+
**How:** Add a \`src/curator/\` module with: a job queue (SQLite-backed), a groom pipeline that scans entries on a schedule, a tag normalizer that consolidates synonyms, and a duplicate detector that merges near-identical entries. Wire it as a \`curator\` facade with ops like \`groom\`, \`scan\`, \`normalize_tags\`, \`merge_duplicates\`. Can optionally use the LLM client for GPT-powered classification.
|
|
283
|
+
|
|
284
|
+
### 2. Document Intake
|
|
285
|
+
**What:** Ingest documents (PDF, markdown, text) into the vault automatically — extract content, classify it, deduplicate, and write entries.
|
|
286
|
+
**Why:** Manual knowledge entry is the biggest friction point. An intake pipeline lets you point at reference material and populate the vault.
|
|
287
|
+
**How:** Add a \`src/intake/\` module with: a content extractor (start with markdown/text, add PDF via \`pdf-parse\`), a chunker that splits long documents into entry-sized pieces, a classifier that assigns domain/type/severity (can use LLM or heuristics), and a dedup gate that checks against existing entries before writing. Expose as an \`intake\` facade op.
|
|
288
|
+
|
|
289
|
+
### 3. Learning Loop
|
|
290
|
+
**What:** Turn accumulated feedback into measurable improvement — track which suggestions get accepted vs dismissed, extract user preferences, adjust scoring.
|
|
291
|
+
**Why:** The Brain already records feedback and tunes weights after 30+ entries. A full learning loop goes further: it builds a preference profile, identifies which patterns resonate, and deprioritizes ones that get consistently dismissed.
|
|
292
|
+
**How:** Add a \`src/learning/\` module with: a feedback analyzer that aggregates accept/dismiss rates per tag and per domain, a preference extractor that builds a user profile from feedback patterns, and a scoring adjuster that feeds insights back into the Brain's weight tuner. Run periodically or trigger after N new feedback entries.
|
|
293
|
+
|
|
294
|
+
### 4. Embeddings & Vector Search
|
|
295
|
+
**What:** Supplement TF-IDF with embedding-based semantic search using OpenAI's embedding API.
|
|
296
|
+
**Why:** TF-IDF is keyword-based — it misses semantic similarity (e.g., "auth" vs "authentication"). Embeddings capture meaning, not just words.
|
|
297
|
+
**How:** Add an embedding service that calls OpenAI's \`text-embedding-3-small\` via the LLM client, stores vectors in a \`vault_embeddings\` table, and adds a vector similarity search path to the Brain. Use cosine similarity to rank. Falls back to TF-IDF when no API key is configured.
|
|
298
|
+
|
|
299
|
+
### 5. Cross-Project Memory
|
|
300
|
+
**What:** Share knowledge and memories across projects — a global pattern pool, project linking, and unified search.
|
|
301
|
+
**Why:** Lessons learned in one project often apply to others. Without cross-project memory, each project starts from zero.
|
|
302
|
+
**How:** Extend the memory system with: a global pool table that stores entries visible to all projects, project link records that connect related projects, and a cross-project search op that queries across all registered projects. Add \`scope\` (project/global) to memory entries.
|
|
303
|
+
|
|
304
|
+
### 6. Context Engine
|
|
305
|
+
**What:** Semantic analysis of user messages — intent classification, entity extraction, and context-aware knowledge retrieval.
|
|
306
|
+
**Why:** Currently the agent responds to explicit ops. A context engine lets it understand *what the user means* and proactively retrieve relevant knowledge.
|
|
307
|
+
**How:** Add a \`src/context/\` module with: an intent classifier (rule-based patterns like "how do I" → PLAN, "this is broken" → FIX), an entity extractor that pulls domain-specific terms from messages, and a knowledge retriever that combines intent + entities to query the vault. Can start rule-based and upgrade to LLM-powered later.
|
|
308
|
+
|
|
309
|
+
### 7. Proactive Agency
|
|
310
|
+
**What:** The agent doesn't just answer — it anticipates, warns, and suggests without being asked.
|
|
311
|
+
**Why:** Moves the agent from reactive (Q&A) to proactive (advisor). Catches issues before they become problems.
|
|
312
|
+
**How:** Add a \`src/agency/\` module with: a suggestion generator that surfaces relevant patterns based on context, a warning detector that flags potential issues (e.g., anti-patterns in captured code), and a notification system that delivers insights at the right moment. Wire into Claude Code hooks for file-change triggers.
|
|
313
|
+
|
|
314
|
+
### 8. Plugin System
|
|
315
|
+
**What:** Runtime-extensible architecture — load, validate, and hot-reload plugins that add new facades, ops, or intelligence.
|
|
316
|
+
**Why:** Lets users extend the agent without modifying core code. Third parties can publish domain-specific plugins.
|
|
317
|
+
**How:** Add a \`src/plugins/\` module with: a plugin loader that scans a directory for plugin packages, a validator that checks plugin manifests against a schema, a registry that tracks active plugins and their facades, and a hot-reload watcher. Each plugin exports a \`register()\` function that receives the vault and brain instances.
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { AgentConfig } from '../types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate a scripts/setup.sh for the scaffolded agent.
|
|
5
|
+
* Handles: Node.js check, build, Claude Code MCP server registration.
|
|
6
|
+
*/
|
|
7
|
+
export function generateSetupScript(config: AgentConfig): string {
|
|
8
|
+
return `#!/usr/bin/env bash
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
AGENT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
12
|
+
AGENT_NAME="${config.id}"
|
|
13
|
+
|
|
14
|
+
echo "=== ${config.name} Setup ==="
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
# Check Node.js
|
|
18
|
+
if ! command -v node &>/dev/null; then
|
|
19
|
+
echo "Error: Node.js is not installed. Install Node.js 18+ first."
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
NODE_VERSION=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
24
|
+
if [ "$NODE_VERSION" -lt 18 ]; then
|
|
25
|
+
echo "Error: Node.js 18+ required (found v$(node -v))."
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
echo "[ok] Node.js $(node -v)"
|
|
29
|
+
|
|
30
|
+
# Check if built
|
|
31
|
+
if [ ! -f "$AGENT_DIR/dist/index.js" ]; then
|
|
32
|
+
echo ""
|
|
33
|
+
echo "Building ${config.name}..."
|
|
34
|
+
cd "$AGENT_DIR"
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
echo "[ok] Built successfully"
|
|
38
|
+
else
|
|
39
|
+
echo "[ok] Already built"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# Check Claude Code
|
|
43
|
+
if ! command -v claude &>/dev/null; then
|
|
44
|
+
echo ""
|
|
45
|
+
echo "Warning: 'claude' command not found."
|
|
46
|
+
echo "Install Claude Code first: https://docs.anthropic.com/en/docs/claude-code"
|
|
47
|
+
echo ""
|
|
48
|
+
echo "After installing, add ${config.name} manually to ~/.claude/settings.json"
|
|
49
|
+
echo "(see README.md for the JSON config)"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
echo "[ok] Claude Code found"
|
|
53
|
+
|
|
54
|
+
# Register MCP server with Claude Code
|
|
55
|
+
echo ""
|
|
56
|
+
echo "Registering ${config.name} with Claude Code..."
|
|
57
|
+
|
|
58
|
+
claude mcp add --scope user "$AGENT_NAME" -- node "$AGENT_DIR/dist/index.js"
|
|
59
|
+
echo "[ok] Registered ${config.name} as MCP server"
|
|
60
|
+
|
|
61
|
+
# Configure PreCompact hook for session capture
|
|
62
|
+
SETTINGS_FILE="$HOME/.claude/settings.json"
|
|
63
|
+
echo ""
|
|
64
|
+
echo "Configuring session capture hook..."
|
|
65
|
+
|
|
66
|
+
if [ ! -d "$HOME/.claude" ]; then
|
|
67
|
+
mkdir -p "$HOME/.claude"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [ ! -f "$SETTINGS_FILE" ]; then
|
|
71
|
+
cat > "$SETTINGS_FILE" << SETTINGS
|
|
72
|
+
{
|
|
73
|
+
"hooks": {
|
|
74
|
+
"PreCompact": [
|
|
75
|
+
{
|
|
76
|
+
"type": "prompt",
|
|
77
|
+
"prompt": "Before context is compacted, capture a session summary by calling ${config.id.replace(/-/g, '_')}_core op:session_capture with a brief summary of what was accomplished, the topics covered, files modified, and tools used."
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
SETTINGS
|
|
83
|
+
echo "[ok] Created $SETTINGS_FILE with PreCompact hook"
|
|
84
|
+
else
|
|
85
|
+
if grep -q "PreCompact" "$SETTINGS_FILE" 2>/dev/null; then
|
|
86
|
+
echo "[ok] PreCompact hook already configured — skipping"
|
|
87
|
+
else
|
|
88
|
+
# Use node to safely merge hook into existing settings
|
|
89
|
+
node -e "
|
|
90
|
+
const fs = require('fs');
|
|
91
|
+
const settings = JSON.parse(fs.readFileSync('$SETTINGS_FILE', 'utf-8'));
|
|
92
|
+
if (!settings.hooks) settings.hooks = {};
|
|
93
|
+
if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];
|
|
94
|
+
settings.hooks.PreCompact.push({
|
|
95
|
+
type: 'prompt',
|
|
96
|
+
prompt: 'Before context is compacted, capture a session summary by calling ${config.id.replace(/-/g, '_')}_core op:session_capture with a brief summary of what was accomplished, the topics covered, files modified, and tools used.'
|
|
97
|
+
});
|
|
98
|
+
fs.writeFileSync('$SETTINGS_FILE', JSON.stringify(settings, null, 2) + '\\n');
|
|
99
|
+
"
|
|
100
|
+
echo "[ok] Added PreCompact hook to $SETTINGS_FILE"
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
echo ""
|
|
105
|
+
echo "=== Setup Complete ==="
|
|
106
|
+
echo ""
|
|
107
|
+
echo "Next:"
|
|
108
|
+
echo " 1. Start a new Claude Code session (or restart if one is open)"
|
|
109
|
+
echo " 2. Say: \\"Hello, ${config.name}!\\""
|
|
110
|
+
echo ""
|
|
111
|
+
echo "${config.name} will activate and guide you from there."
|
|
112
|
+
`;
|
|
113
|
+
}
|