@soleri/forge 5.14.10 → 7.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/dist/agent-schema.d.ts +323 -0
- package/dist/agent-schema.js +151 -0
- package/dist/agent-schema.js.map +1 -0
- package/dist/compose-claude-md.d.ts +24 -0
- package/dist/compose-claude-md.js +197 -0
- package/dist/compose-claude-md.js.map +1 -0
- package/dist/index.js +0 -0
- package/dist/lib.d.ts +12 -1
- package/dist/lib.js +10 -1
- package/dist/lib.js.map +1 -1
- package/dist/scaffold-filetree.d.ts +22 -0
- package/dist/scaffold-filetree.js +349 -0
- package/dist/scaffold-filetree.js.map +1 -0
- package/dist/scaffolder.js +261 -11
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/activate.js +39 -1
- package/dist/templates/activate.js.map +1 -1
- package/dist/templates/agents-md.d.ts +10 -1
- package/dist/templates/agents-md.js +76 -16
- package/dist/templates/agents-md.js.map +1 -1
- package/dist/templates/claude-md-template.js +9 -1
- package/dist/templates/claude-md-template.js.map +1 -1
- package/dist/templates/entry-point.js +83 -6
- package/dist/templates/entry-point.js.map +1 -1
- package/dist/templates/inject-claude-md.js +53 -0
- package/dist/templates/inject-claude-md.js.map +1 -1
- package/dist/templates/package-json.js +4 -1
- package/dist/templates/package-json.js.map +1 -1
- package/dist/templates/readme.js +4 -3
- package/dist/templates/readme.js.map +1 -1
- package/dist/templates/setup-script.js +109 -3
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/shared-rules.js +54 -17
- package/dist/templates/shared-rules.js.map +1 -1
- package/dist/templates/test-facades.js +151 -6
- package/dist/templates/test-facades.js.map +1 -1
- package/dist/types.d.ts +75 -10
- package/dist/types.js +40 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/detect-domain-packs.d.ts +25 -0
- package/dist/utils/detect-domain-packs.js +104 -0
- package/dist/utils/detect-domain-packs.js.map +1 -0
- package/package.json +2 -1
- package/src/__tests__/detect-domain-packs.test.ts +178 -0
- package/src/__tests__/scaffold-filetree.test.ts +243 -0
- package/src/__tests__/scaffolder.test.ts +5 -3
- package/src/agent-schema.ts +184 -0
- package/src/compose-claude-md.ts +252 -0
- package/src/lib.ts +14 -1
- package/src/scaffold-filetree.ts +409 -0
- package/src/scaffolder.ts +299 -15
- package/src/templates/activate.ts +39 -0
- package/src/templates/agents-md.ts +78 -16
- package/src/templates/claude-md-template.ts +12 -1
- package/src/templates/entry-point.ts +90 -6
- package/src/templates/inject-claude-md.ts +53 -0
- package/src/templates/package-json.ts +4 -1
- package/src/templates/readme.ts +4 -3
- package/src/templates/setup-script.ts +110 -4
- package/src/templates/shared-rules.ts +55 -17
- package/src/templates/test-facades.ts +156 -6
- package/src/types.ts +45 -2
- package/src/utils/detect-domain-packs.ts +129 -0
- package/tsconfig.json +0 -1
- package/vitest.config.ts +1 -2
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soleri v7 — CLAUDE.md Composer
|
|
3
|
+
*
|
|
4
|
+
* Auto-generates CLAUDE.md from agent.yaml + instructions/ + workflows/ + skills/.
|
|
5
|
+
* This file is never manually edited. `soleri dev` watches and regenerates on change.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { parse as parseYaml } from 'yaml';
|
|
10
|
+
// ─── Main Composer ────────────────────────────────────────────────────
|
|
11
|
+
/**
|
|
12
|
+
* Compose CLAUDE.md from an agent folder.
|
|
13
|
+
*
|
|
14
|
+
* @param agentDir - Path to the agent folder (containing agent.yaml)
|
|
15
|
+
* @param tools - Registered MCP tools (from engine introspection). Optional —
|
|
16
|
+
* if not provided, generates a placeholder table.
|
|
17
|
+
*/
|
|
18
|
+
export function composeClaudeMd(agentDir, tools) {
|
|
19
|
+
const sources = [];
|
|
20
|
+
// 1. Read agent.yaml
|
|
21
|
+
const agentYamlPath = join(agentDir, 'agent.yaml');
|
|
22
|
+
const agentYaml = parseYaml(readFileSync(agentYamlPath, 'utf-8'));
|
|
23
|
+
sources.push(agentYamlPath);
|
|
24
|
+
const sections = [];
|
|
25
|
+
// 2. Agent identity block
|
|
26
|
+
sections.push(composeIdentityBlock(agentYaml));
|
|
27
|
+
// 3. Activation commands
|
|
28
|
+
sections.push(composeActivation(agentYaml));
|
|
29
|
+
// 4. Session start
|
|
30
|
+
sections.push(composeSessionStart(agentYaml));
|
|
31
|
+
// 5. Essential tools table
|
|
32
|
+
sections.push(composeToolsTable(agentYaml, tools));
|
|
33
|
+
// 6. Engine rules (from instructions/_engine.md)
|
|
34
|
+
const enginePath = join(agentDir, 'instructions', '_engine.md');
|
|
35
|
+
if (existsSync(enginePath)) {
|
|
36
|
+
sections.push(readFileSync(enginePath, 'utf-8').trim());
|
|
37
|
+
sources.push(enginePath);
|
|
38
|
+
}
|
|
39
|
+
// 7. User instructions (instructions/*.md, excluding _engine.md)
|
|
40
|
+
const instructionsDir = join(agentDir, 'instructions');
|
|
41
|
+
if (existsSync(instructionsDir)) {
|
|
42
|
+
const files = readdirSync(instructionsDir)
|
|
43
|
+
.filter((f) => f.endsWith('.md') && f !== '_engine.md')
|
|
44
|
+
.sort();
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
const filePath = join(instructionsDir, file);
|
|
47
|
+
sections.push(readFileSync(filePath, 'utf-8').trim());
|
|
48
|
+
sources.push(filePath);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 8. Workflow index
|
|
52
|
+
const workflowsDir = join(agentDir, 'workflows');
|
|
53
|
+
if (existsSync(workflowsDir)) {
|
|
54
|
+
const workflowSection = composeWorkflowIndex(workflowsDir);
|
|
55
|
+
if (workflowSection) {
|
|
56
|
+
sections.push(workflowSection);
|
|
57
|
+
// Add workflow prompt files to sources
|
|
58
|
+
const dirs = readdirSync(workflowsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
59
|
+
for (const dir of dirs) {
|
|
60
|
+
const promptPath = join(workflowsDir, dir.name, 'prompt.md');
|
|
61
|
+
if (existsSync(promptPath))
|
|
62
|
+
sources.push(promptPath);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 9. Skills index
|
|
67
|
+
const skillsDir = join(agentDir, 'skills');
|
|
68
|
+
if (existsSync(skillsDir)) {
|
|
69
|
+
const skillsSection = composeSkillsIndex(skillsDir);
|
|
70
|
+
if (skillsSection)
|
|
71
|
+
sections.push(skillsSection);
|
|
72
|
+
}
|
|
73
|
+
const content = sections.join('\n\n') + '\n';
|
|
74
|
+
return { content, sources };
|
|
75
|
+
}
|
|
76
|
+
// ─── Section Composers ────────────────────────────────────────────────
|
|
77
|
+
function composeIdentityBlock(agent) {
|
|
78
|
+
const lines = [
|
|
79
|
+
`# ${agent.name} Mode`,
|
|
80
|
+
'',
|
|
81
|
+
`## ${agent.name}`,
|
|
82
|
+
'',
|
|
83
|
+
`**Role:** ${agent.role}`,
|
|
84
|
+
`**Domains:** ${agent.domains.join(', ')}`,
|
|
85
|
+
`**Tone:** ${agent.tone}`,
|
|
86
|
+
'',
|
|
87
|
+
agent.description,
|
|
88
|
+
'',
|
|
89
|
+
'**Principles:**',
|
|
90
|
+
...agent.principles.map((p) => `- ${p}`),
|
|
91
|
+
];
|
|
92
|
+
return lines.join('\n');
|
|
93
|
+
}
|
|
94
|
+
function composeActivation(agent) {
|
|
95
|
+
return [
|
|
96
|
+
'## Activation',
|
|
97
|
+
'',
|
|
98
|
+
`**Activate:** "Hello, ${agent.name}!" → \`${agent.id}_core op:activate params:{ projectPath: "." }\``,
|
|
99
|
+
`**Deactivate:** "Goodbye, ${agent.name}!" → \`${agent.id}_core op:activate params:{ deactivate: true }\``,
|
|
100
|
+
'',
|
|
101
|
+
`On activation, adopt the returned persona. Stay in character until deactivated.`,
|
|
102
|
+
].join('\n');
|
|
103
|
+
}
|
|
104
|
+
function composeSessionStart(agent) {
|
|
105
|
+
return [
|
|
106
|
+
'## Session Start',
|
|
107
|
+
'',
|
|
108
|
+
`On every new session: \`${agent.id}_core op:register params:{ projectPath: "." }\``,
|
|
109
|
+
].join('\n');
|
|
110
|
+
}
|
|
111
|
+
function composeToolsTable(agent, tools) {
|
|
112
|
+
const lines = [
|
|
113
|
+
'## Essential Tools',
|
|
114
|
+
'',
|
|
115
|
+
'| Facade | Key Ops |',
|
|
116
|
+
'|--------|---------|',
|
|
117
|
+
];
|
|
118
|
+
if (tools && tools.length > 0) {
|
|
119
|
+
for (const tool of tools) {
|
|
120
|
+
const opsStr = tool.ops
|
|
121
|
+
.slice(0, 6)
|
|
122
|
+
.map((o) => `\`${o}\``)
|
|
123
|
+
.join(', ');
|
|
124
|
+
const suffix = tool.ops.length > 6 ? ', ...' : '';
|
|
125
|
+
lines.push(`| \`${tool.facade}\` | ${opsStr}${suffix} |`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// Placeholder — will be filled by engine introspection at dev time
|
|
130
|
+
lines.push(`| \`${agent.id}_core\` | \`health\`, \`identity\`, \`register\`, \`activate\` |`);
|
|
131
|
+
lines.push(`| \`${agent.id}_vault\` | \`search_intelligent\`, \`capture_knowledge\`, \`capture_quick\` |`);
|
|
132
|
+
lines.push(`| \`${agent.id}_brain\` | \`recommend\`, \`strengths\`, \`feedback\` |`);
|
|
133
|
+
lines.push(`| \`${agent.id}_planner\` | \`create_plan\`, \`approve_plan\`, \`plan_split\`, \`plan_reconcile\` |`);
|
|
134
|
+
lines.push(`| \`${agent.id}_memory\` | \`memory_search\`, \`memory_capture\`, \`session_capture\` |`);
|
|
135
|
+
lines.push(`| \`${agent.id}_curator\` | \`curator_groom\`, \`curator_status\`, \`curator_health\` |`);
|
|
136
|
+
lines.push(`| \`${agent.id}_admin\` | \`admin_health\`, \`admin_tool_list\`, \`admin_diagnostic\` |`);
|
|
137
|
+
// Domain facades from packs
|
|
138
|
+
if (agent.packs) {
|
|
139
|
+
for (const pack of agent.packs) {
|
|
140
|
+
lines.push(`| \`${agent.id}_${pack.name}\` | \`get_patterns\`, \`search\`, \`capture\` |`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Domain facades from domains
|
|
144
|
+
for (const domain of agent.domains) {
|
|
145
|
+
lines.push(`| \`${agent.id}_${domain}\` | \`get_patterns\`, \`search\`, \`capture\` |`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
lines.push('');
|
|
149
|
+
lines.push(`> Full list: \`${agent.id}_admin op:admin_tool_list\``);
|
|
150
|
+
return lines.join('\n');
|
|
151
|
+
}
|
|
152
|
+
function composeWorkflowIndex(workflowsDir) {
|
|
153
|
+
const dirs = readdirSync(workflowsDir, { withFileTypes: true })
|
|
154
|
+
.filter((d) => d.isDirectory())
|
|
155
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
156
|
+
if (dirs.length === 0)
|
|
157
|
+
return null;
|
|
158
|
+
const lines = [
|
|
159
|
+
'## Available Workflows',
|
|
160
|
+
'',
|
|
161
|
+
'| Workflow | Description |',
|
|
162
|
+
'|----------|-------------|',
|
|
163
|
+
];
|
|
164
|
+
for (const dir of dirs) {
|
|
165
|
+
const promptPath = join(workflowsDir, dir.name, 'prompt.md');
|
|
166
|
+
let description = dir.name;
|
|
167
|
+
if (existsSync(promptPath)) {
|
|
168
|
+
const content = readFileSync(promptPath, 'utf-8');
|
|
169
|
+
// Extract first non-heading, non-empty line as description
|
|
170
|
+
const descLine = content.split('\n').find((line) => line.trim() && !line.startsWith('#'));
|
|
171
|
+
if (descLine)
|
|
172
|
+
description = descLine.trim().slice(0, 80);
|
|
173
|
+
}
|
|
174
|
+
lines.push(`| \`${dir.name}\` | ${description} |`);
|
|
175
|
+
}
|
|
176
|
+
return lines.join('\n');
|
|
177
|
+
}
|
|
178
|
+
function composeSkillsIndex(skillsDir) {
|
|
179
|
+
const dirs = readdirSync(skillsDir, { withFileTypes: true })
|
|
180
|
+
.filter((d) => d.isDirectory())
|
|
181
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
182
|
+
if (dirs.length === 0)
|
|
183
|
+
return null;
|
|
184
|
+
const lines = ['## Available Skills', ''];
|
|
185
|
+
for (const dir of dirs) {
|
|
186
|
+
const skillPath = join(skillsDir, dir.name, 'SKILL.md');
|
|
187
|
+
if (existsSync(skillPath)) {
|
|
188
|
+
const content = readFileSync(skillPath, 'utf-8');
|
|
189
|
+
// Extract description from frontmatter if present
|
|
190
|
+
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
191
|
+
const desc = descMatch ? descMatch[1].trim() : dir.name;
|
|
192
|
+
lines.push(`- **${dir.name}**: ${desc}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return lines.join('\n');
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=compose-claude-md.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose-claude-md.js","sourceRoot":"","sources":["../src/compose-claude-md.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/lib.d.ts
CHANGED
|
@@ -9,9 +9,20 @@ export { installKnowledge, generateVaultOnlyDomainFacade } from './knowledge-ins
|
|
|
9
9
|
export { addDomain } from './domain-manager.js';
|
|
10
10
|
export { patchIndexTs, patchClaudeMdContent } from './patching.js';
|
|
11
11
|
export type { AgentConfig, AgentConfigInput, SetupTarget, ScaffoldResult, ScaffoldPreview, AgentInfo, InstallKnowledgeResult, AddDomainResult, } from './types.js';
|
|
12
|
-
export { AgentConfigSchema, SETUP_TARGETS } from './types.js';
|
|
12
|
+
export { AgentConfigSchema, SETUP_TARGETS, MODEL_PRESETS } from './types.js';
|
|
13
|
+
export { scaffoldFileTree } from './scaffold-filetree.js';
|
|
14
|
+
export type { FileTreeScaffoldResult } from './scaffold-filetree.js';
|
|
15
|
+
export { AgentYamlSchema, TONES } from './agent-schema.js';
|
|
16
|
+
export type { AgentYaml, AgentYamlInput } from './agent-schema.js';
|
|
17
|
+
export { composeClaudeMd } from './compose-claude-md.js';
|
|
18
|
+
export type { ComposedClaudeMd, ToolEntry } from './compose-claude-md.js';
|
|
13
19
|
export { generateExtensionsIndex, generateExampleOp } from './templates/extensions.js';
|
|
14
20
|
export { generateClaudeMdTemplate } from './templates/claude-md-template.js';
|
|
15
21
|
export { getEngineRulesContent, getEngineMarker } from './templates/shared-rules.js';
|
|
16
22
|
export { generateInjectClaudeMd } from './templates/inject-claude-md.js';
|
|
17
23
|
export { generateSkills } from './templates/skills.js';
|
|
24
|
+
export { generateTelegramBot } from './templates/telegram-bot.js';
|
|
25
|
+
export { generateTelegramAgent } from './templates/telegram-agent.js';
|
|
26
|
+
export { generateTelegramConfig } from './templates/telegram-config.js';
|
|
27
|
+
export { generateTelegramSupervisor } from './templates/telegram-supervisor.js';
|
|
28
|
+
export { generateEntryPoint } from './templates/entry-point.js';
|
package/dist/lib.js
CHANGED
|
@@ -8,10 +8,19 @@ export { scaffold, previewScaffold, listAgents } from './scaffolder.js';
|
|
|
8
8
|
export { installKnowledge, generateVaultOnlyDomainFacade } from './knowledge-installer.js';
|
|
9
9
|
export { addDomain } from './domain-manager.js';
|
|
10
10
|
export { patchIndexTs, patchClaudeMdContent } from './patching.js';
|
|
11
|
-
export { AgentConfigSchema, SETUP_TARGETS } from './types.js';
|
|
11
|
+
export { AgentConfigSchema, SETUP_TARGETS, MODEL_PRESETS } from './types.js';
|
|
12
|
+
// ─── v7 File-Tree Agent ──────────────────────────────────────────────
|
|
13
|
+
export { scaffoldFileTree } from './scaffold-filetree.js';
|
|
14
|
+
export { AgentYamlSchema, TONES } from './agent-schema.js';
|
|
15
|
+
export { composeClaudeMd } from './compose-claude-md.js';
|
|
12
16
|
export { generateExtensionsIndex, generateExampleOp } from './templates/extensions.js';
|
|
13
17
|
export { generateClaudeMdTemplate } from './templates/claude-md-template.js';
|
|
14
18
|
export { getEngineRulesContent, getEngineMarker } from './templates/shared-rules.js';
|
|
15
19
|
export { generateInjectClaudeMd } from './templates/inject-claude-md.js';
|
|
16
20
|
export { generateSkills } from './templates/skills.js';
|
|
21
|
+
export { generateTelegramBot } from './templates/telegram-bot.js';
|
|
22
|
+
export { generateTelegramAgent } from './templates/telegram-agent.js';
|
|
23
|
+
export { generateTelegramConfig } from './templates/telegram-config.js';
|
|
24
|
+
export { generateTelegramSupervisor } from './templates/telegram-supervisor.js';
|
|
25
|
+
export { generateEntryPoint } from './templates/entry-point.js';
|
|
17
26
|
//# sourceMappingURL=lib.js.map
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAWnE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAWnE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soleri v7 — File-Tree Agent Scaffolder
|
|
3
|
+
*
|
|
4
|
+
* Generates a folder tree with plain files (YAML, Markdown, JSON).
|
|
5
|
+
* No TypeScript, no package.json, no build step.
|
|
6
|
+
*
|
|
7
|
+
* Replaces the old scaffold() that generated TypeScript projects.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgentYamlInput } from './agent-schema.js';
|
|
10
|
+
export interface FileTreeScaffoldResult {
|
|
11
|
+
success: boolean;
|
|
12
|
+
agentDir: string;
|
|
13
|
+
filesCreated: string[];
|
|
14
|
+
summary: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Scaffold a file-tree agent.
|
|
18
|
+
*
|
|
19
|
+
* Creates a folder with agent.yaml, .mcp.json, instructions/, workflows/,
|
|
20
|
+
* and auto-generates CLAUDE.md. No TypeScript, no build step.
|
|
21
|
+
*/
|
|
22
|
+
export declare function scaffoldFileTree(input: AgentYamlInput, outputDir: string): FileTreeScaffoldResult;
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soleri v7 — File-Tree Agent Scaffolder
|
|
3
|
+
*
|
|
4
|
+
* Generates a folder tree with plain files (YAML, Markdown, JSON).
|
|
5
|
+
* No TypeScript, no package.json, no build step.
|
|
6
|
+
*
|
|
7
|
+
* Replaces the old scaffold() that generated TypeScript projects.
|
|
8
|
+
*/
|
|
9
|
+
import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { stringify as yamlStringify } from 'yaml';
|
|
12
|
+
import { AgentYamlSchema } from './agent-schema.js';
|
|
13
|
+
import { getEngineRulesContent } from './templates/shared-rules.js';
|
|
14
|
+
import { composeClaudeMd } from './compose-claude-md.js';
|
|
15
|
+
const BUILTIN_WORKFLOWS = [
|
|
16
|
+
{
|
|
17
|
+
name: 'feature-dev',
|
|
18
|
+
prompt: `# Feature Development
|
|
19
|
+
|
|
20
|
+
## When to Use
|
|
21
|
+
When building a new feature, adding functionality, or creating components.
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
### 1. Understand
|
|
26
|
+
- Search vault for existing patterns: \`op:search_intelligent\`
|
|
27
|
+
- Read relevant source code
|
|
28
|
+
- Clarify requirements with user if ambiguous
|
|
29
|
+
|
|
30
|
+
### 2. Plan
|
|
31
|
+
- Create structured plan: \`op:orchestrate_plan\`
|
|
32
|
+
- Present plan to user, wait for approval
|
|
33
|
+
- Do NOT write code before approval
|
|
34
|
+
|
|
35
|
+
### 3. Test First
|
|
36
|
+
- Write failing tests that define expected behavior
|
|
37
|
+
- Run tests to confirm they fail (RED)
|
|
38
|
+
|
|
39
|
+
### 4. Implement
|
|
40
|
+
- Write minimum code to pass tests (GREEN)
|
|
41
|
+
- Follow vault patterns, avoid known anti-patterns
|
|
42
|
+
- Use semantic tokens, not hardcoded values
|
|
43
|
+
|
|
44
|
+
### 5. Refactor
|
|
45
|
+
- Clean up without changing behavior
|
|
46
|
+
- Extract reusable patterns
|
|
47
|
+
- Ensure all tests still pass
|
|
48
|
+
|
|
49
|
+
### 6. Capture & Ship
|
|
50
|
+
- Capture learned patterns: \`op:capture_knowledge\`
|
|
51
|
+
- Link new entries to related knowledge: \`op:link_entries\`
|
|
52
|
+
- Complete orchestration: \`op:orchestrate_complete\`
|
|
53
|
+
`,
|
|
54
|
+
gates: `gates:
|
|
55
|
+
- phase: brainstorming
|
|
56
|
+
requirement: Requirements are clear and user has approved the approach
|
|
57
|
+
check: user-approval
|
|
58
|
+
|
|
59
|
+
- phase: pre-execution
|
|
60
|
+
requirement: Plan created via orchestrator and approved by user
|
|
61
|
+
check: plan-approved
|
|
62
|
+
|
|
63
|
+
- phase: post-task
|
|
64
|
+
requirement: All tests pass and code compiles
|
|
65
|
+
check: tests-pass
|
|
66
|
+
|
|
67
|
+
- phase: completion
|
|
68
|
+
requirement: Knowledge captured to vault with links
|
|
69
|
+
check: knowledge-captured
|
|
70
|
+
`,
|
|
71
|
+
tools: `tools:
|
|
72
|
+
- soleri_vault op:search_intelligent
|
|
73
|
+
- soleri_vault op:capture_knowledge
|
|
74
|
+
- soleri_vault op:link_entries
|
|
75
|
+
- soleri_planner op:create_plan
|
|
76
|
+
- soleri_planner op:approve_plan
|
|
77
|
+
- soleri_brain op:recommend
|
|
78
|
+
`,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'bug-fix',
|
|
82
|
+
prompt: `# Bug Fix
|
|
83
|
+
|
|
84
|
+
## When to Use
|
|
85
|
+
When fixing bugs, resolving errors, or addressing regressions.
|
|
86
|
+
|
|
87
|
+
## Steps
|
|
88
|
+
|
|
89
|
+
### 1. Reproduce
|
|
90
|
+
- Understand the reported issue
|
|
91
|
+
- Search vault for similar past bugs: \`op:search_intelligent\`
|
|
92
|
+
- Identify the root cause, not just the symptom
|
|
93
|
+
|
|
94
|
+
### 2. Plan Fix
|
|
95
|
+
- Create a plan: \`op:orchestrate_plan\`
|
|
96
|
+
- Identify affected files and potential side effects
|
|
97
|
+
- Wait for user approval
|
|
98
|
+
|
|
99
|
+
### 3. Write Regression Test
|
|
100
|
+
- Write a test that reproduces the bug (RED)
|
|
101
|
+
- Confirm it fails for the right reason
|
|
102
|
+
|
|
103
|
+
### 4. Fix
|
|
104
|
+
- Apply the minimal fix
|
|
105
|
+
- Run the regression test — must pass (GREEN)
|
|
106
|
+
- Run full test suite — no new failures
|
|
107
|
+
|
|
108
|
+
### 5. Capture
|
|
109
|
+
- If the bug reveals a pattern or anti-pattern, capture it: \`op:capture_knowledge\`
|
|
110
|
+
- Complete orchestration: \`op:orchestrate_complete\`
|
|
111
|
+
`,
|
|
112
|
+
gates: `gates:
|
|
113
|
+
- phase: pre-execution
|
|
114
|
+
requirement: Root cause identified and fix plan approved
|
|
115
|
+
check: plan-approved
|
|
116
|
+
|
|
117
|
+
- phase: post-task
|
|
118
|
+
requirement: Regression test passes and no new failures
|
|
119
|
+
check: tests-pass
|
|
120
|
+
|
|
121
|
+
- phase: completion
|
|
122
|
+
requirement: Anti-pattern captured if applicable
|
|
123
|
+
check: knowledge-captured
|
|
124
|
+
`,
|
|
125
|
+
tools: `tools:
|
|
126
|
+
- soleri_vault op:search_intelligent
|
|
127
|
+
- soleri_vault op:capture_knowledge
|
|
128
|
+
- soleri_planner op:create_plan
|
|
129
|
+
- soleri_brain op:recommend
|
|
130
|
+
`,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'code-review',
|
|
134
|
+
prompt: `# Code Review
|
|
135
|
+
|
|
136
|
+
## When to Use
|
|
137
|
+
When reviewing code, auditing quality, or checking for issues.
|
|
138
|
+
|
|
139
|
+
## Steps
|
|
140
|
+
|
|
141
|
+
### 1. Context
|
|
142
|
+
- Search vault for relevant patterns and anti-patterns: \`op:search_intelligent\`
|
|
143
|
+
- Understand the intent of the changes
|
|
144
|
+
|
|
145
|
+
### 2. Review
|
|
146
|
+
- Check for correctness, readability, and maintainability
|
|
147
|
+
- Verify test coverage
|
|
148
|
+
- Check for security issues
|
|
149
|
+
- Validate accessibility if applicable
|
|
150
|
+
|
|
151
|
+
### 3. Feedback
|
|
152
|
+
- Provide actionable, specific feedback
|
|
153
|
+
- Reference vault patterns where applicable
|
|
154
|
+
- Distinguish blocking issues from suggestions
|
|
155
|
+
|
|
156
|
+
### 4. Capture
|
|
157
|
+
- If review reveals new patterns or anti-patterns, capture them: \`op:capture_knowledge\`
|
|
158
|
+
`,
|
|
159
|
+
gates: `gates:
|
|
160
|
+
- phase: completion
|
|
161
|
+
requirement: All blocking issues addressed
|
|
162
|
+
check: issues-resolved
|
|
163
|
+
`,
|
|
164
|
+
tools: `tools:
|
|
165
|
+
- soleri_vault op:search_intelligent
|
|
166
|
+
- soleri_vault op:capture_knowledge
|
|
167
|
+
- soleri_brain op:recommend
|
|
168
|
+
`,
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
// ─── Main Scaffolder ──────────────────────────────────────────────────
|
|
172
|
+
/**
|
|
173
|
+
* Scaffold a file-tree agent.
|
|
174
|
+
*
|
|
175
|
+
* Creates a folder with agent.yaml, .mcp.json, instructions/, workflows/,
|
|
176
|
+
* and auto-generates CLAUDE.md. No TypeScript, no build step.
|
|
177
|
+
*/
|
|
178
|
+
export function scaffoldFileTree(input, outputDir) {
|
|
179
|
+
// Validate config
|
|
180
|
+
const parseResult = AgentYamlSchema.safeParse(input);
|
|
181
|
+
if (!parseResult.success) {
|
|
182
|
+
return {
|
|
183
|
+
success: false,
|
|
184
|
+
agentDir: join(outputDir, input.id ?? 'unknown'),
|
|
185
|
+
filesCreated: [],
|
|
186
|
+
summary: `Invalid config: ${parseResult.error.message}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const config = parseResult.data;
|
|
190
|
+
const agentDir = join(outputDir, config.id);
|
|
191
|
+
const filesCreated = [];
|
|
192
|
+
// Check for existing directory
|
|
193
|
+
if (existsSync(agentDir)) {
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
agentDir,
|
|
197
|
+
filesCreated: [],
|
|
198
|
+
summary: `Directory already exists: ${agentDir}. Choose a different ID or remove it.`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// ─── 1. Create directory structure ──────────────────────────
|
|
202
|
+
const dirs = ['', 'instructions', 'workflows', 'knowledge', 'skills', 'hooks', 'data'];
|
|
203
|
+
// Add workflow subdirectories
|
|
204
|
+
for (const wf of BUILTIN_WORKFLOWS) {
|
|
205
|
+
dirs.push(`workflows/${wf.name}`);
|
|
206
|
+
}
|
|
207
|
+
for (const dir of dirs) {
|
|
208
|
+
mkdirSync(join(agentDir, dir), { recursive: true });
|
|
209
|
+
}
|
|
210
|
+
// ─── 2. Write agent.yaml ────────────────────────────────────
|
|
211
|
+
const agentYamlContent = yamlStringify(buildAgentYaml(config), {
|
|
212
|
+
lineWidth: 100,
|
|
213
|
+
singleQuote: true,
|
|
214
|
+
});
|
|
215
|
+
writeFile(agentDir, 'agent.yaml', agentYamlContent, filesCreated);
|
|
216
|
+
// ─── 3. Write .mcp.json ─────────────────────────────────────
|
|
217
|
+
const mcpJson = {
|
|
218
|
+
mcpServers: {
|
|
219
|
+
'soleri-engine': {
|
|
220
|
+
command: 'npx',
|
|
221
|
+
args: ['@soleri/engine', '--agent', './agent.yaml'],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
writeFile(agentDir, '.mcp.json', JSON.stringify(mcpJson, null, 2) + '\n', filesCreated);
|
|
226
|
+
// ─── 4. Write .gitignore ────────────────────────────────────
|
|
227
|
+
writeFile(agentDir, '.gitignore', [
|
|
228
|
+
'# Auto-generated — do not commit',
|
|
229
|
+
'CLAUDE.md',
|
|
230
|
+
'AGENTS.md',
|
|
231
|
+
'instructions/_engine.md',
|
|
232
|
+
'',
|
|
233
|
+
].join('\n'), filesCreated);
|
|
234
|
+
// ─── 5. Write engine rules ──────────────────────────────────
|
|
235
|
+
writeFile(agentDir, 'instructions/_engine.md', getEngineRulesContent(), filesCreated);
|
|
236
|
+
// ─── 6. Write user instruction files ────────────────────────
|
|
237
|
+
// Generate domain-specific instruction file if agent has specialized domains
|
|
238
|
+
if (config.domains.length > 0) {
|
|
239
|
+
const domainLines = [
|
|
240
|
+
'# Domain Knowledge',
|
|
241
|
+
'',
|
|
242
|
+
`This agent specializes in: ${config.domains.join(', ')}.`,
|
|
243
|
+
'',
|
|
244
|
+
'## Principles',
|
|
245
|
+
'',
|
|
246
|
+
...config.principles.map((p) => `- ${p}`),
|
|
247
|
+
'',
|
|
248
|
+
];
|
|
249
|
+
writeFile(agentDir, 'instructions/domain.md', domainLines.join('\n'), filesCreated);
|
|
250
|
+
}
|
|
251
|
+
// ─── 7. Write workflows ─────────────────────────────────────
|
|
252
|
+
for (const wf of BUILTIN_WORKFLOWS) {
|
|
253
|
+
writeFile(agentDir, `workflows/${wf.name}/prompt.md`, wf.prompt, filesCreated);
|
|
254
|
+
writeFile(agentDir, `workflows/${wf.name}/gates.yaml`, wf.gates, filesCreated);
|
|
255
|
+
writeFile(agentDir, `workflows/${wf.name}/tools.yaml`, wf.tools, filesCreated);
|
|
256
|
+
}
|
|
257
|
+
// ─── 8. Write empty knowledge bundle ────────────────────────
|
|
258
|
+
for (const domain of config.domains) {
|
|
259
|
+
const bundle = {
|
|
260
|
+
domain,
|
|
261
|
+
version: '1.0.0',
|
|
262
|
+
entries: [],
|
|
263
|
+
};
|
|
264
|
+
writeFile(agentDir, `knowledge/${domain}.json`, JSON.stringify(bundle, null, 2) + '\n', filesCreated);
|
|
265
|
+
}
|
|
266
|
+
// ─── 9. Generate CLAUDE.md ──────────────────────────────────
|
|
267
|
+
const { content: claudeMd } = composeClaudeMd(agentDir);
|
|
268
|
+
writeFile(agentDir, 'CLAUDE.md', claudeMd, filesCreated);
|
|
269
|
+
// ─── 10. Summary ────────────────────────────────────────────
|
|
270
|
+
const summary = [
|
|
271
|
+
`Agent "${config.name}" scaffolded at ${agentDir}`,
|
|
272
|
+
'',
|
|
273
|
+
` Files: ${filesCreated.length}`,
|
|
274
|
+
` Domains: ${config.domains.join(', ')}`,
|
|
275
|
+
` Workflows: ${BUILTIN_WORKFLOWS.map((w) => w.name).join(', ')}`,
|
|
276
|
+
'',
|
|
277
|
+
'Next steps:',
|
|
278
|
+
` 1. cd ${config.id}`,
|
|
279
|
+
' 2. Review agent.yaml and customize instructions/',
|
|
280
|
+
' 3. Run: soleri install (registers MCP server)',
|
|
281
|
+
' 4. Run: soleri dev (watches files, auto-regenerates CLAUDE.md)',
|
|
282
|
+
'',
|
|
283
|
+
'No build step needed — this agent is ready to use.',
|
|
284
|
+
].join('\n');
|
|
285
|
+
return {
|
|
286
|
+
success: true,
|
|
287
|
+
agentDir,
|
|
288
|
+
filesCreated,
|
|
289
|
+
summary,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
// ─── Helpers ──────────────────────────────────────────────────────────
|
|
293
|
+
function writeFile(agentDir, relativePath, content, filesCreated) {
|
|
294
|
+
const fullPath = join(agentDir, relativePath);
|
|
295
|
+
const dir = join(agentDir, relativePath.includes('/') ? relativePath.split('/').slice(0, -1).join('/') : '');
|
|
296
|
+
if (!existsSync(dir)) {
|
|
297
|
+
mkdirSync(dir, { recursive: true });
|
|
298
|
+
}
|
|
299
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
300
|
+
filesCreated.push(relativePath);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Build a clean agent.yaml object for serialization.
|
|
304
|
+
* Strips defaults and empty optionals for cleaner output.
|
|
305
|
+
*/
|
|
306
|
+
function buildAgentYaml(config) {
|
|
307
|
+
const yaml = {
|
|
308
|
+
id: config.id,
|
|
309
|
+
name: config.name,
|
|
310
|
+
role: config.role,
|
|
311
|
+
description: config.description,
|
|
312
|
+
domains: config.domains,
|
|
313
|
+
principles: config.principles,
|
|
314
|
+
};
|
|
315
|
+
if (config.tone && config.tone !== 'pragmatic') {
|
|
316
|
+
yaml.tone = config.tone;
|
|
317
|
+
}
|
|
318
|
+
if (config.greeting) {
|
|
319
|
+
yaml.greeting = config.greeting;
|
|
320
|
+
}
|
|
321
|
+
// Engine config — only include non-defaults
|
|
322
|
+
const engine = {};
|
|
323
|
+
if (config.engine?.vault)
|
|
324
|
+
engine.vault = config.engine.vault;
|
|
325
|
+
if (config.engine?.learning === false)
|
|
326
|
+
engine.learning = false;
|
|
327
|
+
if (config.engine?.cognee === true)
|
|
328
|
+
engine.cognee = true;
|
|
329
|
+
if (Object.keys(engine).length > 0)
|
|
330
|
+
yaml.engine = engine;
|
|
331
|
+
// Vaults
|
|
332
|
+
if (config.vaults && config.vaults.length > 0) {
|
|
333
|
+
yaml.vaults = config.vaults;
|
|
334
|
+
}
|
|
335
|
+
// Setup — only include non-defaults
|
|
336
|
+
const setup = {};
|
|
337
|
+
if (config.setup?.target && config.setup.target !== 'opencode')
|
|
338
|
+
setup.target = config.setup.target;
|
|
339
|
+
if (config.setup?.model && config.setup.model !== 'claude-code-sonnet-4')
|
|
340
|
+
setup.model = config.setup.model;
|
|
341
|
+
if (Object.keys(setup).length > 0)
|
|
342
|
+
yaml.setup = setup;
|
|
343
|
+
// Packs
|
|
344
|
+
if (config.packs && config.packs.length > 0) {
|
|
345
|
+
yaml.packs = config.packs;
|
|
346
|
+
}
|
|
347
|
+
return yaml;
|
|
348
|
+
}
|
|
349
|
+
//# sourceMappingURL=scaffold-filetree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-filetree.js","sourceRoot":"","sources":["../src/scaffold-filetree.ts"],"names":[],"mappings":"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"}
|