@soleri/forge 5.9.0 → 5.11.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/lib.d.ts +1 -0
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/scaffolder.js +79 -239
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/entry-point.d.ts +1 -1
- package/dist/templates/entry-point.js +53 -10
- package/dist/templates/entry-point.js.map +1 -1
- package/dist/templates/extensions.d.ts +10 -0
- package/dist/templates/extensions.js +89 -0
- package/dist/templates/extensions.js.map +1 -0
- package/dist/templates/persona.js +27 -0
- package/dist/templates/persona.js.map +1 -1
- package/dist/templates/skills.d.ts +2 -0
- package/dist/templates/skills.js +8 -0
- package/dist/templates/skills.js.map +1 -1
- package/dist/templates/test-facades.js +228 -304
- package/dist/templates/test-facades.js.map +1 -1
- package/dist/types.d.ts +13 -2
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -1
- package/package.json +5 -1
- package/src/__tests__/extensions-scaffold.test.ts +63 -0
- package/src/__tests__/scaffolder.test.ts +9 -6
- package/src/lib.ts +1 -0
- package/src/scaffolder.ts +79 -240
- package/src/templates/entry-point.ts +53 -10
- package/src/templates/extensions.ts +91 -0
- package/src/templates/persona.ts +27 -0
- package/src/templates/skills.ts +11 -0
- package/src/templates/test-facades.ts +228 -304
- package/src/types.ts +8 -0
|
@@ -9,7 +9,7 @@ export function generateFacadesTest(config) {
|
|
|
9
9
|
return `import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
10
10
|
import {
|
|
11
11
|
createAgentRuntime,
|
|
12
|
-
|
|
12
|
+
createSemanticFacades,
|
|
13
13
|
createDomainFacade,
|
|
14
14
|
} from '@soleri/core';
|
|
15
15
|
import type { AgentRuntime, IntelligenceEntry, OpDefinition, FacadeConfig } from '@soleri/core';
|
|
@@ -54,9 +54,217 @@ describe('Facades', () => {
|
|
|
54
54
|
|
|
55
55
|
${domainDescribes}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
// ─── Semantic Facades ────────────────────────────────────────
|
|
58
|
+
describe('semantic facades', () => {
|
|
59
|
+
function buildSemanticFacades(): FacadeConfig[] {
|
|
60
|
+
return createSemanticFacades(runtime, '${config.id}');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
it('should create 10 semantic facades', () => {
|
|
64
|
+
const facades = buildSemanticFacades();
|
|
65
|
+
expect(facades).toHaveLength(10);
|
|
66
|
+
const names = facades.map(f => f.name);
|
|
67
|
+
expect(names).toContain('${config.id}_vault');
|
|
68
|
+
expect(names).toContain('${config.id}_plan');
|
|
69
|
+
expect(names).toContain('${config.id}_brain');
|
|
70
|
+
expect(names).toContain('${config.id}_memory');
|
|
71
|
+
expect(names).toContain('${config.id}_admin');
|
|
72
|
+
expect(names).toContain('${config.id}_curator');
|
|
73
|
+
expect(names).toContain('${config.id}_loop');
|
|
74
|
+
expect(names).toContain('${config.id}_orchestrate');
|
|
75
|
+
expect(names).toContain('${config.id}_control');
|
|
76
|
+
expect(names).toContain('${config.id}_cognee');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('total ops across all facades should be 209', () => {
|
|
80
|
+
const facades = buildSemanticFacades();
|
|
81
|
+
const totalOps = facades.reduce((sum, f) => sum + f.ops.length, 0);
|
|
82
|
+
expect(totalOps).toBe(209);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe('${config.id}_vault', () => {
|
|
87
|
+
function getFacade(): FacadeConfig {
|
|
88
|
+
return createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_vault')!;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
it('should contain vault ops', () => {
|
|
92
|
+
const opNames = getFacade().ops.map(o => o.name);
|
|
93
|
+
expect(opNames).toContain('search');
|
|
94
|
+
expect(opNames).toContain('vault_stats');
|
|
95
|
+
expect(opNames).toContain('list_all');
|
|
96
|
+
expect(opNames).toContain('export');
|
|
97
|
+
expect(opNames).toContain('vault_get');
|
|
98
|
+
expect(opNames).toContain('vault_import');
|
|
99
|
+
expect(opNames).toContain('capture_knowledge');
|
|
100
|
+
expect(opNames).toContain('intake_ingest_book');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('search should query across all domains', async () => {
|
|
104
|
+
runtime.vault.seed([
|
|
105
|
+
makeEntry({ id: 'c1', domain: 'alpha', title: 'Alpha pattern', tags: ['a'] }),
|
|
106
|
+
makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
|
|
107
|
+
]);
|
|
108
|
+
runtime = createAgentRuntime({ agentId: '${config.id}', vaultPath: ':memory:', plansPath: join(plannerDir, 'plans2.json') });
|
|
109
|
+
runtime.vault.seed([
|
|
110
|
+
makeEntry({ id: 'c1', domain: 'alpha', title: 'Alpha pattern', tags: ['a'] }),
|
|
111
|
+
makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
|
|
112
|
+
]);
|
|
113
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_vault')!;
|
|
114
|
+
const searchOp = facade.ops.find(o => o.name === 'search')!;
|
|
115
|
+
const results = (await searchOp.handler({ query: 'pattern' })) as Array<{ entry: unknown; score: number }>;
|
|
116
|
+
expect(Array.isArray(results)).toBe(true);
|
|
117
|
+
expect(results.length).toBe(2);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('vault_stats should return counts', async () => {
|
|
121
|
+
runtime.vault.seed([
|
|
122
|
+
makeEntry({ id: 'vs1', domain: 'd1', tags: ['x'] }),
|
|
123
|
+
makeEntry({ id: 'vs2', domain: 'd2', tags: ['y'] }),
|
|
124
|
+
]);
|
|
125
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_vault')!;
|
|
126
|
+
const statsOp = facade.ops.find(o => o.name === 'vault_stats')!;
|
|
127
|
+
const stats = (await statsOp.handler({})) as { totalEntries: number };
|
|
128
|
+
expect(stats.totalEntries).toBe(2);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('${config.id}_plan', () => {
|
|
133
|
+
it('should contain planning ops', () => {
|
|
134
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_plan')!;
|
|
135
|
+
const opNames = facade.ops.map(o => o.name);
|
|
136
|
+
expect(opNames).toContain('create_plan');
|
|
137
|
+
expect(opNames).toContain('get_plan');
|
|
138
|
+
expect(opNames).toContain('approve_plan');
|
|
139
|
+
expect(opNames).toContain('plan_iterate');
|
|
140
|
+
expect(opNames).toContain('plan_grade');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('create_plan should create a draft plan', async () => {
|
|
144
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_plan')!;
|
|
145
|
+
const createOp = facade.ops.find(o => o.name === 'create_plan')!;
|
|
146
|
+
const result = (await createOp.handler({
|
|
147
|
+
objective: 'Add caching',
|
|
148
|
+
scope: 'api layer',
|
|
149
|
+
tasks: [{ title: 'Add Redis', description: 'Set up Redis client' }],
|
|
150
|
+
})) as { created: boolean; plan: { status: string } };
|
|
151
|
+
expect(result.created).toBe(true);
|
|
152
|
+
expect(result.plan.status).toBe('draft');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('${config.id}_brain', () => {
|
|
157
|
+
it('should contain brain ops', () => {
|
|
158
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_brain')!;
|
|
159
|
+
const opNames = facade.ops.map(o => o.name);
|
|
160
|
+
expect(opNames).toContain('brain_stats');
|
|
161
|
+
expect(opNames).toContain('brain_strengths');
|
|
162
|
+
expect(opNames).toContain('brain_build_intelligence');
|
|
163
|
+
expect(opNames).toContain('brain_lifecycle');
|
|
164
|
+
expect(opNames).toContain('brain_decay_report');
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('brain_stats should return intelligence stats', async () => {
|
|
168
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_brain')!;
|
|
169
|
+
const statsOp = facade.ops.find(o => o.name === 'brain_stats')!;
|
|
170
|
+
const result = (await statsOp.handler({})) as { vocabularySize: number };
|
|
171
|
+
expect(result.vocabularySize).toBe(0);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('${config.id}_memory', () => {
|
|
176
|
+
it('should contain memory ops', () => {
|
|
177
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_memory')!;
|
|
178
|
+
const opNames = facade.ops.map(o => o.name);
|
|
179
|
+
expect(opNames).toContain('memory_search');
|
|
180
|
+
expect(opNames).toContain('memory_capture');
|
|
181
|
+
expect(opNames).toContain('memory_promote_to_global');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('${config.id}_admin', () => {
|
|
186
|
+
it('should contain admin ops', () => {
|
|
187
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_admin')!;
|
|
188
|
+
const opNames = facade.ops.map(o => o.name);
|
|
189
|
+
expect(opNames).toContain('admin_health');
|
|
190
|
+
expect(opNames).toContain('admin_tool_list');
|
|
191
|
+
expect(opNames).toContain('llm_rotate');
|
|
192
|
+
expect(opNames).toContain('render_prompt');
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
describe('${config.id}_curator', () => {
|
|
197
|
+
it('should contain curator ops', () => {
|
|
198
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_curator')!;
|
|
199
|
+
const opNames = facade.ops.map(o => o.name);
|
|
200
|
+
expect(opNames).toContain('curator_status');
|
|
201
|
+
expect(opNames).toContain('curator_health_audit');
|
|
202
|
+
expect(opNames).toContain('curator_hybrid_contradictions');
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('curator_status should return initialized', async () => {
|
|
206
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_curator')!;
|
|
207
|
+
const statusOp = facade.ops.find(o => o.name === 'curator_status')!;
|
|
208
|
+
const result = (await statusOp.handler({})) as { initialized: boolean };
|
|
209
|
+
expect(result.initialized).toBe(true);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe('${config.id}_loop', () => {
|
|
214
|
+
it('should contain loop ops', () => {
|
|
215
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_loop')!;
|
|
216
|
+
const opNames = facade.ops.map(o => o.name);
|
|
217
|
+
expect(opNames).toContain('loop_start');
|
|
218
|
+
expect(opNames).toContain('loop_iterate');
|
|
219
|
+
expect(opNames).toContain('loop_cancel');
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('${config.id}_orchestrate', () => {
|
|
224
|
+
it('should contain orchestrate ops', () => {
|
|
225
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_orchestrate')!;
|
|
226
|
+
const opNames = facade.ops.map(o => o.name);
|
|
227
|
+
expect(opNames).toContain('register');
|
|
228
|
+
expect(opNames).toContain('orchestrate_plan');
|
|
229
|
+
expect(opNames).toContain('project_get');
|
|
230
|
+
expect(opNames).toContain('playbook_list');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe('${config.id}_control', () => {
|
|
235
|
+
it('should contain control and governance ops', () => {
|
|
236
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_control')!;
|
|
237
|
+
const opNames = facade.ops.map(o => o.name);
|
|
238
|
+
expect(opNames).toContain('get_identity');
|
|
239
|
+
expect(opNames).toContain('route_intent');
|
|
240
|
+
expect(opNames).toContain('governance_policy');
|
|
241
|
+
expect(opNames).toContain('governance_dashboard');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('governance_policy should return default policy', async () => {
|
|
245
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_control')!;
|
|
246
|
+
const policyOp = facade.ops.find(o => o.name === 'governance_policy')!;
|
|
247
|
+
const result = (await policyOp.handler({ action: 'get', projectPath: '/test' })) as {
|
|
248
|
+
projectPath: string;
|
|
249
|
+
quotas: { maxEntriesTotal: number };
|
|
250
|
+
};
|
|
251
|
+
expect(result.projectPath).toBe('/test');
|
|
252
|
+
expect(result.quotas.maxEntriesTotal).toBe(500);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('${config.id}_cognee', () => {
|
|
257
|
+
it('should contain cognee ops', () => {
|
|
258
|
+
const facade = createSemanticFacades(runtime, '${config.id}').find(f => f.name === '${config.id}_cognee')!;
|
|
259
|
+
const opNames = facade.ops.map(o => o.name);
|
|
260
|
+
expect(opNames).toContain('cognee_status');
|
|
261
|
+
expect(opNames).toContain('cognee_search');
|
|
262
|
+
expect(opNames).toContain('cognee_sync_status');
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('${config.id}_core (agent-specific)', () => {
|
|
267
|
+
function buildAgentFacade(): FacadeConfig {
|
|
60
268
|
const agentOps: OpDefinition[] = [
|
|
61
269
|
{
|
|
62
270
|
name: 'health',
|
|
@@ -164,245 +372,30 @@ ${domainDescribes}
|
|
|
164
372
|
];
|
|
165
373
|
return {
|
|
166
374
|
name: '${config.id}_core',
|
|
167
|
-
description: '
|
|
168
|
-
ops:
|
|
375
|
+
description: 'Agent-specific operations',
|
|
376
|
+
ops: agentOps,
|
|
169
377
|
};
|
|
170
378
|
}
|
|
171
379
|
|
|
172
|
-
it('should
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
expect(
|
|
178
|
-
expect(
|
|
179
|
-
expect(
|
|
180
|
-
expect(opNames).toContain('register');
|
|
181
|
-
expect(opNames).toContain('llm_status');
|
|
182
|
-
expect(opNames).toContain('curator_status');
|
|
183
|
-
expect(opNames).toContain('curator_health_audit');
|
|
184
|
-
// Brain Intelligence ops (11)
|
|
185
|
-
expect(opNames).toContain('brain_session_context');
|
|
186
|
-
expect(opNames).toContain('brain_strengths');
|
|
187
|
-
expect(opNames).toContain('brain_global_patterns');
|
|
188
|
-
expect(opNames).toContain('brain_recommend');
|
|
189
|
-
expect(opNames).toContain('brain_build_intelligence');
|
|
190
|
-
expect(opNames).toContain('brain_export');
|
|
191
|
-
expect(opNames).toContain('brain_import');
|
|
192
|
-
expect(opNames).toContain('brain_extract_knowledge');
|
|
193
|
-
expect(opNames).toContain('brain_archive_sessions');
|
|
194
|
-
expect(opNames).toContain('brain_promote_proposals');
|
|
195
|
-
expect(opNames).toContain('brain_lifecycle');
|
|
196
|
-
// Enhanced brain ops (3)
|
|
197
|
-
expect(opNames).toContain('brain_feedback');
|
|
198
|
-
expect(opNames).toContain('brain_feedback_stats');
|
|
199
|
-
expect(opNames).toContain('brain_reset_extracted');
|
|
200
|
-
// Brain decay report (#89)
|
|
201
|
-
expect(opNames).toContain('brain_decay_report');
|
|
202
|
-
// Agent-specific ops (5)
|
|
203
|
-
expect(opNames).toContain('health');
|
|
204
|
-
expect(opNames).toContain('identity');
|
|
205
|
-
expect(opNames).toContain('activate');
|
|
206
|
-
expect(opNames).toContain('inject_claude_md');
|
|
207
|
-
expect(opNames).toContain('setup');
|
|
208
|
-
// Control ops (8)
|
|
209
|
-
expect(opNames).toContain('get_identity');
|
|
210
|
-
expect(opNames).toContain('update_identity');
|
|
211
|
-
expect(opNames).toContain('add_guideline');
|
|
212
|
-
expect(opNames).toContain('remove_guideline');
|
|
213
|
-
expect(opNames).toContain('rollback_identity');
|
|
214
|
-
expect(opNames).toContain('route_intent');
|
|
215
|
-
expect(opNames).toContain('morph');
|
|
216
|
-
expect(opNames).toContain('get_behavior_rules');
|
|
217
|
-
// Cognee ops (5)
|
|
218
|
-
expect(opNames).toContain('cognee_status');
|
|
219
|
-
expect(opNames).toContain('cognee_search');
|
|
220
|
-
expect(opNames).toContain('cognee_add');
|
|
221
|
-
expect(opNames).toContain('cognee_cognify');
|
|
222
|
-
expect(opNames).toContain('cognee_config');
|
|
223
|
-
// LLM ops (2)
|
|
224
|
-
expect(opNames).toContain('llm_rotate');
|
|
225
|
-
expect(opNames).toContain('llm_call');
|
|
226
|
-
// Governance ops (5)
|
|
227
|
-
expect(opNames).toContain('governance_policy');
|
|
228
|
-
expect(opNames).toContain('governance_proposals');
|
|
229
|
-
expect(opNames).toContain('governance_stats');
|
|
230
|
-
expect(opNames).toContain('governance_expire');
|
|
231
|
-
expect(opNames).toContain('governance_dashboard');
|
|
232
|
-
// Planning Extra ops (13)
|
|
233
|
-
expect(opNames).toContain('plan_iterate');
|
|
234
|
-
expect(opNames).toContain('plan_split');
|
|
235
|
-
expect(opNames).toContain('plan_reconcile');
|
|
236
|
-
expect(opNames).toContain('plan_complete_lifecycle');
|
|
237
|
-
expect(opNames).toContain('plan_dispatch');
|
|
238
|
-
expect(opNames).toContain('plan_review');
|
|
239
|
-
expect(opNames).toContain('plan_archive');
|
|
240
|
-
expect(opNames).toContain('plan_list_tasks');
|
|
241
|
-
expect(opNames).toContain('plan_stats');
|
|
242
|
-
expect(opNames).toContain('plan_execution_metrics');
|
|
243
|
-
expect(opNames).toContain('plan_record_task_metrics');
|
|
244
|
-
expect(opNames).toContain('plan_submit_deliverable');
|
|
245
|
-
expect(opNames).toContain('plan_verify_deliverables');
|
|
246
|
-
// Memory Extra ops (8)
|
|
247
|
-
expect(opNames).toContain('memory_delete');
|
|
248
|
-
expect(opNames).toContain('memory_stats');
|
|
249
|
-
expect(opNames).toContain('memory_export');
|
|
250
|
-
expect(opNames).toContain('memory_import');
|
|
251
|
-
expect(opNames).toContain('memory_prune');
|
|
252
|
-
expect(opNames).toContain('memory_deduplicate');
|
|
253
|
-
expect(opNames).toContain('memory_topics');
|
|
254
|
-
expect(opNames).toContain('memory_by_project');
|
|
255
|
-
// Vault Extra ops (12)
|
|
256
|
-
expect(opNames).toContain('vault_get');
|
|
257
|
-
expect(opNames).toContain('vault_update');
|
|
258
|
-
expect(opNames).toContain('vault_remove');
|
|
259
|
-
expect(opNames).toContain('vault_bulk_add');
|
|
260
|
-
expect(opNames).toContain('vault_bulk_remove');
|
|
261
|
-
expect(opNames).toContain('vault_tags');
|
|
262
|
-
expect(opNames).toContain('vault_domains');
|
|
263
|
-
expect(opNames).toContain('vault_recent');
|
|
264
|
-
expect(opNames).toContain('vault_import');
|
|
265
|
-
expect(opNames).toContain('vault_seed');
|
|
266
|
-
expect(opNames).toContain('vault_backup');
|
|
267
|
-
expect(opNames).toContain('vault_age_report');
|
|
268
|
-
// #89: Bi-temporal
|
|
269
|
-
expect(opNames).toContain('vault_set_temporal');
|
|
270
|
-
expect(opNames).toContain('vault_find_expiring');
|
|
271
|
-
expect(opNames).toContain('vault_find_expired');
|
|
272
|
-
// Vault archival (#86)
|
|
273
|
-
expect(opNames).toContain('vault_archive');
|
|
274
|
-
expect(opNames).toContain('vault_restore');
|
|
275
|
-
expect(opNames).toContain('vault_optimize');
|
|
276
|
-
// Admin ops (8)
|
|
277
|
-
expect(opNames).toContain('admin_health');
|
|
278
|
-
expect(opNames).toContain('admin_tool_list');
|
|
279
|
-
expect(opNames).toContain('admin_config');
|
|
280
|
-
expect(opNames).toContain('admin_vault_size');
|
|
281
|
-
expect(opNames).toContain('admin_uptime');
|
|
282
|
-
expect(opNames).toContain('admin_version');
|
|
283
|
-
expect(opNames).toContain('admin_reset_cache');
|
|
284
|
-
expect(opNames).toContain('admin_diagnostic');
|
|
285
|
-
// Loop ops (8)
|
|
286
|
-
expect(opNames).toContain('loop_start');
|
|
287
|
-
expect(opNames).toContain('loop_iterate');
|
|
288
|
-
expect(opNames).toContain('loop_status');
|
|
289
|
-
expect(opNames).toContain('loop_cancel');
|
|
290
|
-
expect(opNames).toContain('loop_history');
|
|
291
|
-
expect(opNames).toContain('loop_is_active');
|
|
292
|
-
expect(opNames).toContain('loop_complete');
|
|
293
|
-
expect(opNames).toContain('loop_anomaly_check');
|
|
294
|
-
// Orchestrate ops (5)
|
|
295
|
-
expect(opNames).toContain('orchestrate_plan');
|
|
296
|
-
expect(opNames).toContain('orchestrate_execute');
|
|
297
|
-
expect(opNames).toContain('orchestrate_complete');
|
|
298
|
-
expect(opNames).toContain('orchestrate_status');
|
|
299
|
-
expect(opNames).toContain('orchestrate_quick_capture');
|
|
300
|
-
// Capture ops (4)
|
|
301
|
-
expect(opNames).toContain('capture_knowledge');
|
|
302
|
-
expect(opNames).toContain('capture_quick');
|
|
303
|
-
expect(opNames).toContain('search_intelligent');
|
|
304
|
-
expect(opNames).toContain('search_feedback');
|
|
305
|
-
// Grading ops (5)
|
|
306
|
-
expect(opNames).toContain('plan_grade');
|
|
307
|
-
expect(opNames).toContain('plan_check_history');
|
|
308
|
-
expect(opNames).toContain('plan_latest_check');
|
|
309
|
-
expect(opNames).toContain('plan_meets_grade');
|
|
310
|
-
expect(opNames).toContain('plan_auto_improve');
|
|
311
|
-
// Admin Extra ops (11)
|
|
312
|
-
expect(opNames).toContain('admin_telemetry');
|
|
313
|
-
expect(opNames).toContain('admin_telemetry_recent');
|
|
314
|
-
expect(opNames).toContain('admin_telemetry_reset');
|
|
315
|
-
expect(opNames).toContain('admin_permissions');
|
|
316
|
-
expect(opNames).toContain('admin_vault_analytics');
|
|
317
|
-
expect(opNames).toContain('admin_search_insights');
|
|
318
|
-
expect(opNames).toContain('admin_module_status');
|
|
319
|
-
expect(opNames).toContain('admin_env');
|
|
320
|
-
expect(opNames).toContain('admin_gc');
|
|
321
|
-
expect(opNames).toContain('admin_export_config');
|
|
322
|
-
expect(opNames).toContain('admin_hot_reload');
|
|
323
|
-
// Admin persistence (#85)
|
|
324
|
-
expect(opNames).toContain('admin_persistence_info');
|
|
325
|
-
// Curator Extra ops (4 + 1 hybrid)
|
|
326
|
-
expect(opNames).toContain('curator_entry_history');
|
|
327
|
-
expect(opNames).toContain('curator_record_snapshot');
|
|
328
|
-
expect(opNames).toContain('curator_queue_stats');
|
|
329
|
-
expect(opNames).toContain('curator_enrich');
|
|
330
|
-
// #36: Hybrid contradiction detection
|
|
331
|
-
expect(opNames).toContain('curator_hybrid_contradictions');
|
|
332
|
-
// Project ops (12)
|
|
333
|
-
expect(opNames).toContain('project_get');
|
|
334
|
-
expect(opNames).toContain('project_list');
|
|
335
|
-
expect(opNames).toContain('project_unregister');
|
|
336
|
-
expect(opNames).toContain('project_get_rules');
|
|
337
|
-
expect(opNames).toContain('project_list_rules');
|
|
338
|
-
expect(opNames).toContain('project_add_rule');
|
|
339
|
-
expect(opNames).toContain('project_remove_rule');
|
|
340
|
-
expect(opNames).toContain('project_link');
|
|
341
|
-
expect(opNames).toContain('project_unlink');
|
|
342
|
-
expect(opNames).toContain('project_get_links');
|
|
343
|
-
expect(opNames).toContain('project_linked_projects');
|
|
344
|
-
expect(opNames).toContain('project_touch');
|
|
345
|
-
// Cross-project memory ops (3)
|
|
346
|
-
expect(opNames).toContain('memory_promote_to_global');
|
|
347
|
-
expect(opNames).toContain('memory_configure');
|
|
348
|
-
expect(opNames).toContain('memory_cross_project_search');
|
|
349
|
-
// Playbook ops (5)
|
|
350
|
-
expect(opNames).toContain('playbook_list');
|
|
351
|
-
expect(opNames).toContain('playbook_get');
|
|
352
|
-
expect(opNames).toContain('playbook_create');
|
|
353
|
-
expect(opNames).toContain('playbook_match');
|
|
354
|
-
expect(opNames).toContain('playbook_seed');
|
|
355
|
-
// Cognee Sync ops (3)
|
|
356
|
-
expect(opNames).toContain('cognee_sync_status');
|
|
357
|
-
expect(opNames).toContain('cognee_sync_drain');
|
|
358
|
-
expect(opNames).toContain('cognee_sync_reconcile');
|
|
359
|
-
// Intake ops (4)
|
|
360
|
-
expect(opNames).toContain('intake_ingest_book');
|
|
361
|
-
expect(opNames).toContain('intake_process');
|
|
362
|
-
expect(opNames).toContain('intake_status');
|
|
363
|
-
expect(opNames).toContain('intake_preview');
|
|
364
|
-
// Total: 212 (207 core + 5 agent-specific)
|
|
365
|
-
expect(facade.ops.length).toBe(212);
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
it('search should query across all domains with ranked results', async () => {
|
|
369
|
-
runtime.vault.seed([
|
|
370
|
-
makeEntry({ id: 'c1', domain: 'alpha', title: 'Alpha pattern', tags: ['a'] }),
|
|
371
|
-
makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
|
|
372
|
-
]);
|
|
373
|
-
runtime = createAgentRuntime({ agentId: '${config.id}', vaultPath: ':memory:', plansPath: join(plannerDir, 'plans2.json') });
|
|
374
|
-
runtime.vault.seed([
|
|
375
|
-
makeEntry({ id: 'c1', domain: 'alpha', title: 'Alpha pattern', tags: ['a'] }),
|
|
376
|
-
makeEntry({ id: 'c2', domain: 'beta', title: 'Beta pattern', tags: ['b'] }),
|
|
377
|
-
]);
|
|
378
|
-
const facade = buildCoreFacade();
|
|
379
|
-
const searchOp = facade.ops.find((o) => o.name === 'search')!;
|
|
380
|
-
const results = (await searchOp.handler({ query: 'pattern' })) as Array<{ entry: unknown; score: number; breakdown: unknown }>;
|
|
381
|
-
expect(Array.isArray(results)).toBe(true);
|
|
382
|
-
expect(results.length).toBe(2);
|
|
383
|
-
expect(results[0].score).toBeGreaterThan(0);
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
it('vault_stats should return counts', async () => {
|
|
387
|
-
runtime.vault.seed([
|
|
388
|
-
makeEntry({ id: 'vs1', domain: 'd1', tags: ['x'] }),
|
|
389
|
-
makeEntry({ id: 'vs2', domain: 'd2', tags: ['y'] }),
|
|
390
|
-
]);
|
|
391
|
-
const facade = buildCoreFacade();
|
|
392
|
-
const statsOp = facade.ops.find((o) => o.name === 'vault_stats')!;
|
|
393
|
-
const stats = (await statsOp.handler({})) as { totalEntries: number };
|
|
394
|
-
expect(stats.totalEntries).toBe(2);
|
|
380
|
+
it('agent ops should not appear in semantic facades', () => {
|
|
381
|
+
const facades = createSemanticFacades(runtime, '${config.id}');
|
|
382
|
+
const allOps = facades.flatMap(f => f.ops.map(o => o.name));
|
|
383
|
+
expect(allOps).not.toContain('health');
|
|
384
|
+
expect(allOps).not.toContain('identity');
|
|
385
|
+
expect(allOps).not.toContain('activate');
|
|
386
|
+
expect(allOps).not.toContain('inject_claude_md');
|
|
387
|
+
expect(allOps).not.toContain('setup');
|
|
395
388
|
});
|
|
396
389
|
|
|
397
390
|
it('health should return ok status', async () => {
|
|
398
|
-
const facade =
|
|
391
|
+
const facade = buildAgentFacade();
|
|
399
392
|
const healthOp = facade.ops.find((o) => o.name === 'health')!;
|
|
400
393
|
const health = (await healthOp.handler({})) as { status: string };
|
|
401
394
|
expect(health.status).toBe('ok');
|
|
402
395
|
});
|
|
403
396
|
|
|
404
397
|
it('identity should return persona', async () => {
|
|
405
|
-
const facade =
|
|
398
|
+
const facade = buildAgentFacade();
|
|
406
399
|
const identityOp = facade.ops.find((o) => o.name === 'identity')!;
|
|
407
400
|
const persona = (await identityOp.handler({})) as { name: string; role: string };
|
|
408
401
|
expect(persona.name).toBe('${escapeQuotes(config.name)}');
|
|
@@ -410,7 +403,7 @@ ${domainDescribes}
|
|
|
410
403
|
});
|
|
411
404
|
|
|
412
405
|
it('activate should return persona and setup status', async () => {
|
|
413
|
-
const facade =
|
|
406
|
+
const facade = buildAgentFacade();
|
|
414
407
|
const activateOp = facade.ops.find((o) => o.name === 'activate')!;
|
|
415
408
|
const result = (await activateOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
|
|
416
409
|
activated: boolean;
|
|
@@ -421,7 +414,7 @@ ${domainDescribes}
|
|
|
421
414
|
});
|
|
422
415
|
|
|
423
416
|
it('activate with deactivate flag should return deactivation', async () => {
|
|
424
|
-
const facade =
|
|
417
|
+
const facade = buildAgentFacade();
|
|
425
418
|
const activateOp = facade.ops.find((o) => o.name === 'activate')!;
|
|
426
419
|
const result = (await activateOp.handler({ deactivate: true })) as { deactivated: boolean; message: string };
|
|
427
420
|
expect(result.deactivated).toBe(true);
|
|
@@ -432,7 +425,7 @@ ${domainDescribes}
|
|
|
432
425
|
const tempDir = join(tmpdir(), 'forge-inject-test-' + Date.now());
|
|
433
426
|
mkdirSync(tempDir, { recursive: true });
|
|
434
427
|
try {
|
|
435
|
-
const facade =
|
|
428
|
+
const facade = buildAgentFacade();
|
|
436
429
|
const injectOp = facade.ops.find((o) => o.name === 'inject_claude_md')!;
|
|
437
430
|
const result = (await injectOp.handler({ projectPath: tempDir })) as {
|
|
438
431
|
injected: boolean;
|
|
@@ -450,7 +443,7 @@ ${domainDescribes}
|
|
|
450
443
|
});
|
|
451
444
|
|
|
452
445
|
it('setup should return project and global CLAUDE.md status', async () => {
|
|
453
|
-
const facade =
|
|
446
|
+
const facade = buildAgentFacade();
|
|
454
447
|
const setupOp = facade.ops.find((o) => o.name === 'setup')!;
|
|
455
448
|
const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
|
|
456
449
|
agent: { name: string };
|
|
@@ -463,75 +456,6 @@ ${domainDescribes}
|
|
|
463
456
|
expect(result.vault.entries).toBe(0);
|
|
464
457
|
expect(result.recommendations.length).toBeGreaterThan(0);
|
|
465
458
|
});
|
|
466
|
-
|
|
467
|
-
it('create_plan should create a draft plan', async () => {
|
|
468
|
-
const facade = buildCoreFacade();
|
|
469
|
-
const createOp = facade.ops.find((o) => o.name === 'create_plan')!;
|
|
470
|
-
const result = (await createOp.handler({
|
|
471
|
-
objective: 'Add caching',
|
|
472
|
-
scope: 'api layer',
|
|
473
|
-
tasks: [{ title: 'Add Redis', description: 'Set up Redis client' }],
|
|
474
|
-
})) as { created: boolean; plan: { id: string; status: string; tasks: unknown[] } };
|
|
475
|
-
expect(result.created).toBe(true);
|
|
476
|
-
expect(result.plan.status).toBe('draft');
|
|
477
|
-
expect(result.plan.tasks).toHaveLength(1);
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it('brain_stats should return intelligence stats', async () => {
|
|
481
|
-
const facade = buildCoreFacade();
|
|
482
|
-
const statsOp = facade.ops.find((o) => o.name === 'brain_stats')!;
|
|
483
|
-
const result = (await statsOp.handler({})) as {
|
|
484
|
-
vocabularySize: number;
|
|
485
|
-
feedbackCount: number;
|
|
486
|
-
};
|
|
487
|
-
expect(result.vocabularySize).toBe(0);
|
|
488
|
-
expect(result.feedbackCount).toBe(0);
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
it('curator_status should return table counts', async () => {
|
|
492
|
-
const facade = buildCoreFacade();
|
|
493
|
-
const statusOp = facade.ops.find((o) => o.name === 'curator_status')!;
|
|
494
|
-
const result = (await statusOp.handler({})) as { initialized: boolean };
|
|
495
|
-
expect(result.initialized).toBe(true);
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
it('curator_health_audit should return score', async () => {
|
|
499
|
-
runtime.vault.seed([
|
|
500
|
-
makeEntry({ id: 'ha1', type: 'pattern', tags: ['a', 'b'] }),
|
|
501
|
-
makeEntry({ id: 'ha2', type: 'anti-pattern', tags: ['c', 'd'] }),
|
|
502
|
-
]);
|
|
503
|
-
runtime.curator.groomAll();
|
|
504
|
-
const facade = buildCoreFacade();
|
|
505
|
-
const healthOp = facade.ops.find((o) => o.name === 'curator_health_audit')!;
|
|
506
|
-
const result = (await healthOp.handler({})) as { score: number };
|
|
507
|
-
expect(result.score).toBeGreaterThan(0);
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
it('governance_policy get should return default policy', async () => {
|
|
511
|
-
const facade = buildCoreFacade();
|
|
512
|
-
const policyOp = facade.ops.find((o) => o.name === 'governance_policy')!;
|
|
513
|
-
const result = (await policyOp.handler({ action: 'get', projectPath: '/test' })) as {
|
|
514
|
-
projectPath: string;
|
|
515
|
-
quotas: { maxEntriesTotal: number };
|
|
516
|
-
autoCapture: { enabled: boolean };
|
|
517
|
-
};
|
|
518
|
-
expect(result.projectPath).toBe('/test');
|
|
519
|
-
expect(result.quotas.maxEntriesTotal).toBe(500);
|
|
520
|
-
expect(result.autoCapture.enabled).toBe(true);
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
it('governance_dashboard should return combined view', async () => {
|
|
524
|
-
const facade = buildCoreFacade();
|
|
525
|
-
const dashOp = facade.ops.find((o) => o.name === 'governance_dashboard')!;
|
|
526
|
-
const result = (await dashOp.handler({ projectPath: '/test' })) as {
|
|
527
|
-
vaultSize: number;
|
|
528
|
-
quotaPercent: number;
|
|
529
|
-
pendingProposals: number;
|
|
530
|
-
};
|
|
531
|
-
expect(typeof result.vaultSize).toBe('number');
|
|
532
|
-
expect(typeof result.quotaPercent).toBe('number');
|
|
533
|
-
expect(result.pendingProposals).toBe(0);
|
|
534
|
-
});
|
|
535
459
|
});
|
|
536
460
|
});
|
|
537
461
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAmB;IACrD,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;SAChD,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmCS,MAAM,CAAC,EAAE;;;;;;;;;;;EAWzB,eAAe;;
|
|
1
|
+
{"version":3,"file":"test-facades.js","sourceRoot":"","sources":["../../src/templates/test-facades.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
/** Communication tone for the agent persona */
|
|
3
|
+
export declare const TONES: readonly ["precise", "mentor", "pragmatic"];
|
|
4
|
+
export type Tone = (typeof TONES)[number];
|
|
2
5
|
/** Agent configuration — everything needed to scaffold */
|
|
3
6
|
export declare const AgentConfigSchema: z.ZodObject<{
|
|
4
7
|
/** Agent identifier (kebab-case, used for directory and package name) */
|
|
@@ -13,32 +16,40 @@ export declare const AgentConfigSchema: z.ZodObject<{
|
|
|
13
16
|
domains: z.ZodArray<z.ZodString, "many">;
|
|
14
17
|
/** Core principles the agent follows (3-7 recommended) */
|
|
15
18
|
principles: z.ZodArray<z.ZodString, "many">;
|
|
19
|
+
/** Communication tone: precise, mentor, or pragmatic */
|
|
20
|
+
tone: z.ZodDefault<z.ZodOptional<z.ZodEnum<["precise", "mentor", "pragmatic"]>>>;
|
|
16
21
|
/** Greeting message when agent introduces itself (auto-generated if omitted) */
|
|
17
22
|
greeting: z.ZodOptional<z.ZodString>;
|
|
18
23
|
/** Output directory (parent — agent dir will be created inside, defaults to cwd) */
|
|
19
24
|
outputDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
20
25
|
/** Hook packs to install after scaffolding (optional) */
|
|
21
26
|
hookPacks: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
27
|
+
/** Skills to include (if omitted, all skills are included for backward compat) */
|
|
28
|
+
skills: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
22
29
|
}, "strip", z.ZodTypeAny, {
|
|
23
|
-
id: string;
|
|
24
30
|
name: string;
|
|
31
|
+
id: string;
|
|
25
32
|
role: string;
|
|
26
33
|
description: string;
|
|
27
34
|
domains: string[];
|
|
28
35
|
principles: string[];
|
|
36
|
+
tone: "precise" | "mentor" | "pragmatic";
|
|
29
37
|
outputDir: string;
|
|
30
38
|
greeting?: string | undefined;
|
|
31
39
|
hookPacks?: string[] | undefined;
|
|
40
|
+
skills?: string[] | undefined;
|
|
32
41
|
}, {
|
|
33
|
-
id: string;
|
|
34
42
|
name: string;
|
|
43
|
+
id: string;
|
|
35
44
|
role: string;
|
|
36
45
|
description: string;
|
|
37
46
|
domains: string[];
|
|
38
47
|
principles: string[];
|
|
48
|
+
tone?: "precise" | "mentor" | "pragmatic" | undefined;
|
|
39
49
|
greeting?: string | undefined;
|
|
40
50
|
outputDir?: string | undefined;
|
|
41
51
|
hookPacks?: string[] | undefined;
|
|
52
|
+
skills?: string[] | undefined;
|
|
42
53
|
}>;
|
|
43
54
|
export type AgentConfig = z.infer<typeof AgentConfigSchema>;
|
|
44
55
|
/** Result of scaffolding */
|