@soleri/forge 5.4.0 → 5.6.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/scaffolder.js +98 -6
- package/dist/scaffolder.js.map +1 -1
- package/dist/skills/brain-debrief.md +186 -0
- package/dist/skills/brainstorming.md +170 -0
- package/dist/skills/code-patrol.md +176 -0
- package/dist/skills/context-resume.md +143 -0
- package/dist/skills/executing-plans.md +201 -0
- package/dist/skills/fix-and-learn.md +164 -0
- package/dist/skills/health-check.md +225 -0
- package/dist/skills/knowledge-harvest.md +178 -0
- package/dist/skills/onboard-me.md +197 -0
- package/dist/skills/retrospective.md +189 -0
- package/dist/skills/second-opinion.md +142 -0
- package/dist/skills/skills/brain-debrief.md +214 -0
- package/dist/skills/skills/brainstorming.md +180 -0
- package/dist/skills/skills/code-patrol.md +178 -0
- package/dist/skills/skills/context-resume.md +146 -0
- package/dist/skills/skills/executing-plans.md +216 -0
- package/dist/skills/skills/fix-and-learn.md +167 -0
- package/dist/skills/skills/health-check.md +231 -0
- package/dist/skills/skills/knowledge-harvest.md +185 -0
- package/dist/skills/skills/onboard-me.md +198 -0
- package/dist/skills/skills/retrospective.md +205 -0
- package/dist/skills/skills/second-opinion.md +149 -0
- package/dist/skills/skills/systematic-debugging.md +241 -0
- package/dist/skills/skills/test-driven-development.md +281 -0
- package/dist/skills/skills/vault-capture.md +170 -0
- package/dist/skills/skills/vault-navigator.md +140 -0
- package/dist/skills/skills/verification-before-completion.md +182 -0
- package/dist/skills/skills/writing-plans.md +215 -0
- package/dist/skills/systematic-debugging.md +230 -0
- package/dist/skills/test-driven-development.md +266 -0
- package/dist/skills/vault-capture.md +154 -0
- package/dist/skills/vault-navigator.md +129 -0
- package/dist/skills/verification-before-completion.md +170 -0
- package/dist/skills/writing-plans.md +207 -0
- package/dist/templates/entry-point.js +8 -0
- package/dist/templates/entry-point.js.map +1 -1
- package/dist/templates/readme.js +38 -0
- package/dist/templates/readme.js.map +1 -1
- package/dist/templates/setup-script.js +26 -0
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/skills.d.ts +16 -0
- package/dist/templates/skills.js +73 -0
- package/dist/templates/skills.js.map +1 -0
- package/dist/templates/test-facades.js +35 -6
- package/dist/templates/test-facades.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/scaffolder.test.ts +115 -2
- package/src/scaffolder.ts +100 -6
- package/src/skills/brain-debrief.md +214 -0
- package/src/skills/brainstorming.md +180 -0
- package/src/skills/code-patrol.md +178 -0
- package/src/skills/context-resume.md +146 -0
- package/src/skills/executing-plans.md +216 -0
- package/src/skills/fix-and-learn.md +167 -0
- package/src/skills/health-check.md +231 -0
- package/src/skills/knowledge-harvest.md +185 -0
- package/src/skills/onboard-me.md +198 -0
- package/src/skills/retrospective.md +205 -0
- package/src/skills/second-opinion.md +149 -0
- package/src/skills/systematic-debugging.md +241 -0
- package/src/skills/test-driven-development.md +281 -0
- package/src/skills/vault-capture.md +170 -0
- package/src/skills/vault-navigator.md +140 -0
- package/src/skills/verification-before-completion.md +182 -0
- package/src/skills/writing-plans.md +215 -0
- package/src/templates/entry-point.ts +8 -0
- package/src/templates/readme.ts +38 -0
- package/src/templates/setup-script.ts +26 -0
- package/src/templates/skills.ts +82 -0
- package/src/templates/test-facades.ts +35 -6
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const SKILLS_DIR = join(__dirname, '..', 'skills');
|
|
6
|
+
/** Skills that use YOUR_AGENT_core placeholder and need agent-specific substitution. */
|
|
7
|
+
const AGENT_SPECIFIC_SKILLS = new Set([
|
|
8
|
+
'brain-debrief',
|
|
9
|
+
'brainstorming',
|
|
10
|
+
'code-patrol',
|
|
11
|
+
'context-resume',
|
|
12
|
+
'executing-plans',
|
|
13
|
+
'fix-and-learn',
|
|
14
|
+
'health-check',
|
|
15
|
+
'knowledge-harvest',
|
|
16
|
+
'onboard-me',
|
|
17
|
+
'retrospective',
|
|
18
|
+
'second-opinion',
|
|
19
|
+
'systematic-debugging',
|
|
20
|
+
'test-driven-development',
|
|
21
|
+
'vault-capture',
|
|
22
|
+
'vault-navigator',
|
|
23
|
+
'verification-before-completion',
|
|
24
|
+
'writing-plans',
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Generate skill files for the scaffolded agent.
|
|
28
|
+
* Returns [relativePath, content] tuples for each skill.
|
|
29
|
+
*
|
|
30
|
+
* - Superpowers-adapted skills (MIT): copied as-is
|
|
31
|
+
* - Engine-adapted skills: YOUR_AGENT_core → {config.id}_core
|
|
32
|
+
*/
|
|
33
|
+
export function generateSkills(config) {
|
|
34
|
+
const files = [];
|
|
35
|
+
let skillFiles;
|
|
36
|
+
try {
|
|
37
|
+
skillFiles = readdirSync(SKILLS_DIR).filter((f) => f.endsWith('.md'));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return files;
|
|
41
|
+
}
|
|
42
|
+
for (const file of skillFiles) {
|
|
43
|
+
const skillName = file.replace('.md', '');
|
|
44
|
+
let content = readFileSync(join(SKILLS_DIR, file), 'utf-8');
|
|
45
|
+
if (AGENT_SPECIFIC_SKILLS.has(skillName)) {
|
|
46
|
+
content = content.replace(/YOUR_AGENT_core/g, `${config.id}_core`);
|
|
47
|
+
}
|
|
48
|
+
files.push([`skills/${skillName}/SKILL.md`, content]);
|
|
49
|
+
}
|
|
50
|
+
return files;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* List all bundled skill names with their descriptions (from YAML frontmatter).
|
|
54
|
+
*/
|
|
55
|
+
export function listSkillDescriptions() {
|
|
56
|
+
let skillFiles;
|
|
57
|
+
try {
|
|
58
|
+
skillFiles = readdirSync(SKILLS_DIR).filter((f) => f.endsWith('.md'));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
return skillFiles.map((file) => {
|
|
64
|
+
const content = readFileSync(join(SKILLS_DIR, file), 'utf-8');
|
|
65
|
+
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
66
|
+
const descMatch = content.match(/^description:\s*"?(.+?)"?\s*$/m);
|
|
67
|
+
return {
|
|
68
|
+
name: nameMatch?.[1]?.trim() ?? file.replace('.md', ''),
|
|
69
|
+
description: descMatch?.[1]?.trim() ?? '',
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/templates/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAEnD,wFAAwF;AACxF,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,eAAe;IACf,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,mBAAmB;IACnB,YAAY;IACZ,eAAe;IACf,gBAAgB;IAChB,sBAAsB;IACtB,yBAAyB;IACzB,eAAe;IACf,iBAAiB;IACjB,gCAAgC;IAChC,eAAe;CAChB,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAmB;IAChD,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,IAAI,UAAoB,CAAC;IAEzB,IAAI,CAAC;QACH,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,SAAS,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,UAAoB,CAAC;IAEzB,IAAI,CAAC;QACH,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACnD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAClE,OAAO;YACL,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YACvD,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE;SAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -197,6 +197,8 @@ ${domainDescribes}
|
|
|
197
197
|
expect(opNames).toContain('brain_feedback');
|
|
198
198
|
expect(opNames).toContain('brain_feedback_stats');
|
|
199
199
|
expect(opNames).toContain('brain_reset_extracted');
|
|
200
|
+
// Brain decay report (#89)
|
|
201
|
+
expect(opNames).toContain('brain_decay_report');
|
|
200
202
|
// Agent-specific ops (5)
|
|
201
203
|
expect(opNames).toContain('health');
|
|
202
204
|
expect(opNames).toContain('identity');
|
|
@@ -227,7 +229,7 @@ ${domainDescribes}
|
|
|
227
229
|
expect(opNames).toContain('governance_stats');
|
|
228
230
|
expect(opNames).toContain('governance_expire');
|
|
229
231
|
expect(opNames).toContain('governance_dashboard');
|
|
230
|
-
// Planning Extra ops (
|
|
232
|
+
// Planning Extra ops (13)
|
|
231
233
|
expect(opNames).toContain('plan_iterate');
|
|
232
234
|
expect(opNames).toContain('plan_split');
|
|
233
235
|
expect(opNames).toContain('plan_reconcile');
|
|
@@ -237,6 +239,10 @@ ${domainDescribes}
|
|
|
237
239
|
expect(opNames).toContain('plan_archive');
|
|
238
240
|
expect(opNames).toContain('plan_list_tasks');
|
|
239
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');
|
|
240
246
|
// Memory Extra ops (8)
|
|
241
247
|
expect(opNames).toContain('memory_delete');
|
|
242
248
|
expect(opNames).toContain('memory_stats');
|
|
@@ -259,6 +265,10 @@ ${domainDescribes}
|
|
|
259
265
|
expect(opNames).toContain('vault_seed');
|
|
260
266
|
expect(opNames).toContain('vault_backup');
|
|
261
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');
|
|
262
272
|
// Admin ops (8)
|
|
263
273
|
expect(opNames).toContain('admin_health');
|
|
264
274
|
expect(opNames).toContain('admin_tool_list');
|
|
@@ -268,7 +278,7 @@ ${domainDescribes}
|
|
|
268
278
|
expect(opNames).toContain('admin_version');
|
|
269
279
|
expect(opNames).toContain('admin_reset_cache');
|
|
270
280
|
expect(opNames).toContain('admin_diagnostic');
|
|
271
|
-
// Loop ops (
|
|
281
|
+
// Loop ops (8)
|
|
272
282
|
expect(opNames).toContain('loop_start');
|
|
273
283
|
expect(opNames).toContain('loop_iterate');
|
|
274
284
|
expect(opNames).toContain('loop_status');
|
|
@@ -276,6 +286,7 @@ ${domainDescribes}
|
|
|
276
286
|
expect(opNames).toContain('loop_history');
|
|
277
287
|
expect(opNames).toContain('loop_is_active');
|
|
278
288
|
expect(opNames).toContain('loop_complete');
|
|
289
|
+
expect(opNames).toContain('loop_anomaly_check');
|
|
279
290
|
// Orchestrate ops (5)
|
|
280
291
|
expect(opNames).toContain('orchestrate_plan');
|
|
281
292
|
expect(opNames).toContain('orchestrate_execute');
|
|
@@ -293,7 +304,7 @@ ${domainDescribes}
|
|
|
293
304
|
expect(opNames).toContain('plan_latest_check');
|
|
294
305
|
expect(opNames).toContain('plan_meets_grade');
|
|
295
306
|
expect(opNames).toContain('plan_auto_improve');
|
|
296
|
-
// Admin Extra ops (
|
|
307
|
+
// Admin Extra ops (11)
|
|
297
308
|
expect(opNames).toContain('admin_telemetry');
|
|
298
309
|
expect(opNames).toContain('admin_telemetry_recent');
|
|
299
310
|
expect(opNames).toContain('admin_telemetry_reset');
|
|
@@ -304,11 +315,14 @@ ${domainDescribes}
|
|
|
304
315
|
expect(opNames).toContain('admin_env');
|
|
305
316
|
expect(opNames).toContain('admin_gc');
|
|
306
317
|
expect(opNames).toContain('admin_export_config');
|
|
307
|
-
|
|
318
|
+
expect(opNames).toContain('admin_hot_reload');
|
|
319
|
+
// Curator Extra ops (4 + 1 hybrid)
|
|
308
320
|
expect(opNames).toContain('curator_entry_history');
|
|
309
321
|
expect(opNames).toContain('curator_record_snapshot');
|
|
310
322
|
expect(opNames).toContain('curator_queue_stats');
|
|
311
323
|
expect(opNames).toContain('curator_enrich');
|
|
324
|
+
// #36: Hybrid contradiction detection
|
|
325
|
+
expect(opNames).toContain('curator_hybrid_contradictions');
|
|
312
326
|
// Project ops (12)
|
|
313
327
|
expect(opNames).toContain('project_get');
|
|
314
328
|
expect(opNames).toContain('project_list');
|
|
@@ -326,8 +340,23 @@ ${domainDescribes}
|
|
|
326
340
|
expect(opNames).toContain('memory_promote_to_global');
|
|
327
341
|
expect(opNames).toContain('memory_configure');
|
|
328
342
|
expect(opNames).toContain('memory_cross_project_search');
|
|
329
|
-
//
|
|
330
|
-
expect(
|
|
343
|
+
// Playbook ops (5)
|
|
344
|
+
expect(opNames).toContain('playbook_list');
|
|
345
|
+
expect(opNames).toContain('playbook_get');
|
|
346
|
+
expect(opNames).toContain('playbook_create');
|
|
347
|
+
expect(opNames).toContain('playbook_match');
|
|
348
|
+
expect(opNames).toContain('playbook_seed');
|
|
349
|
+
// Cognee Sync ops (3)
|
|
350
|
+
expect(opNames).toContain('cognee_sync_status');
|
|
351
|
+
expect(opNames).toContain('cognee_sync_drain');
|
|
352
|
+
expect(opNames).toContain('cognee_sync_reconcile');
|
|
353
|
+
// Intake ops (4)
|
|
354
|
+
expect(opNames).toContain('intake_ingest_book');
|
|
355
|
+
expect(opNames).toContain('intake_process');
|
|
356
|
+
expect(opNames).toContain('intake_status');
|
|
357
|
+
expect(opNames).toContain('intake_preview');
|
|
358
|
+
// Total: 208 (203 core + 5 agent-specific)
|
|
359
|
+
expect(facade.ops.length).toBe(208);
|
|
331
360
|
});
|
|
332
361
|
|
|
333
362
|
it('search should query across all domains with ranked results', async () => {
|
|
@@ -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;;cAEH,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA6Fe,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;iBAgBhC,MAAM,CAAC,EAAE;;;;;;;;kCAQQ,MAAM,CAAC,EAAE
|
|
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;;cAEH,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sCA6Fe,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;iBAgBhC,MAAM,CAAC,EAAE;;;;;;;;kCAQQ,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAiMM,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAmCvB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;mCACzB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;0CAWlB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;qCA0B9B,MAAM,CAAC,EAAE;;;;;;;;;;;;;;;;wCAgBN,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EhE,CAAC;AACF,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe,EAAE,MAAc;IAC7D,MAAM,UAAU,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;IAE7D,OAAO,eAAe,UAAU;;4CAEU,OAAO,OAAO,MAAM;;;;;kCAK9B,UAAU;;;;;;;;;iDASK,MAAM;;2BAE5B,MAAM,mBAAmB,MAAM;;;;;;kDAMR,MAAM;;;iCAGvB,MAAM;;2BAEZ,MAAM,kBAAkB,MAAM;;;;;;;wDAOD,MAAM;;;wCAGtB,MAAM;;;;eAI/B,MAAM;;;;;;;;yCAQoB,MAAM;;oCAEX,MAAM;;;;6CAIG,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;gCACtB,MAAM;;;;6CAIO,MAAM,mBAAmB,MAAM;;;gDAG5B,MAAM;;kCAEpB,MAAM;;MAElC,CAAC;AACP,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soleri/forge",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"description": "Scaffold AI agents that learn, remember, and grow with you.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"dev": "tsx src/index.ts",
|
|
41
|
-
"build": "tsc",
|
|
41
|
+
"build": "tsc && cp -r src/skills dist/skills",
|
|
42
42
|
"start": "node dist/index.js",
|
|
43
43
|
"typecheck": "tsc --noEmit",
|
|
44
44
|
"test": "vitest run",
|
|
@@ -59,9 +59,9 @@ describe('Scaffolder', () => {
|
|
|
59
59
|
expect(preview.facades).toHaveLength(4); // 3 domains + core
|
|
60
60
|
expect(preview.facades[0].name).toBe('atlas_data_pipelines');
|
|
61
61
|
|
|
62
|
-
// Core facade should list all
|
|
62
|
+
// Core facade should list all 208 ops (203 core + 5 agent-specific)
|
|
63
63
|
const coreFacade = preview.facades.find((f) => f.name === 'atlas_core')!;
|
|
64
|
-
expect(coreFacade.ops.length).toBe(
|
|
64
|
+
expect(coreFacade.ops.length).toBe(208);
|
|
65
65
|
expect(coreFacade.ops).toContain('curator_status');
|
|
66
66
|
expect(coreFacade.ops).toContain('health');
|
|
67
67
|
|
|
@@ -248,6 +248,119 @@ describe('Scaffolder', () => {
|
|
|
248
248
|
});
|
|
249
249
|
});
|
|
250
250
|
|
|
251
|
+
describe('skills', () => {
|
|
252
|
+
it('should create skills directory with 10 SKILL.md files', () => {
|
|
253
|
+
scaffold(testConfig);
|
|
254
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
255
|
+
|
|
256
|
+
expect(existsSync(skillsDir)).toBe(true);
|
|
257
|
+
|
|
258
|
+
const skillDirs = readdirSync(skillsDir, { withFileTypes: true })
|
|
259
|
+
.filter((e) => e.isDirectory())
|
|
260
|
+
.map((e) => e.name);
|
|
261
|
+
|
|
262
|
+
expect(skillDirs).toHaveLength(17);
|
|
263
|
+
|
|
264
|
+
// Verify each skill dir has a SKILL.md
|
|
265
|
+
for (const dir of skillDirs) {
|
|
266
|
+
expect(existsSync(join(skillsDir, dir, 'SKILL.md'))).toBe(true);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should include all expected skill names', () => {
|
|
271
|
+
scaffold(testConfig);
|
|
272
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
273
|
+
const skillDirs = readdirSync(skillsDir).sort();
|
|
274
|
+
|
|
275
|
+
expect(skillDirs).toEqual([
|
|
276
|
+
'brain-debrief',
|
|
277
|
+
'brainstorming',
|
|
278
|
+
'code-patrol',
|
|
279
|
+
'context-resume',
|
|
280
|
+
'executing-plans',
|
|
281
|
+
'fix-and-learn',
|
|
282
|
+
'health-check',
|
|
283
|
+
'knowledge-harvest',
|
|
284
|
+
'onboard-me',
|
|
285
|
+
'retrospective',
|
|
286
|
+
'second-opinion',
|
|
287
|
+
'systematic-debugging',
|
|
288
|
+
'test-driven-development',
|
|
289
|
+
'vault-capture',
|
|
290
|
+
'vault-navigator',
|
|
291
|
+
'verification-before-completion',
|
|
292
|
+
'writing-plans',
|
|
293
|
+
]);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should have YAML frontmatter in all skills', () => {
|
|
297
|
+
scaffold(testConfig);
|
|
298
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
299
|
+
const skillDirs = readdirSync(skillsDir);
|
|
300
|
+
|
|
301
|
+
for (const dir of skillDirs) {
|
|
302
|
+
const content = readFileSync(join(skillsDir, dir, 'SKILL.md'), 'utf-8');
|
|
303
|
+
expect(content).toMatch(/^---\nname: /);
|
|
304
|
+
expect(content).toContain('description:');
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('should substitute YOUR_AGENT_core with agent ID in all skills', () => {
|
|
309
|
+
scaffold(testConfig);
|
|
310
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
311
|
+
const allSkills = readdirSync(skillsDir);
|
|
312
|
+
|
|
313
|
+
for (const name of allSkills) {
|
|
314
|
+
const content = readFileSync(join(skillsDir, name, 'SKILL.md'), 'utf-8');
|
|
315
|
+
expect(content).not.toContain('YOUR_AGENT_core');
|
|
316
|
+
// All skills that reference agent ops should have atlas_core
|
|
317
|
+
if (content.includes('_core')) {
|
|
318
|
+
expect(content).toContain('atlas_core');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
it('should include MIT attribution in superpowers-adapted skills', () => {
|
|
324
|
+
scaffold(testConfig);
|
|
325
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
326
|
+
const superpowersSkills = [
|
|
327
|
+
'test-driven-development',
|
|
328
|
+
'systematic-debugging',
|
|
329
|
+
'verification-before-completion',
|
|
330
|
+
'brainstorming',
|
|
331
|
+
'writing-plans',
|
|
332
|
+
'executing-plans',
|
|
333
|
+
];
|
|
334
|
+
|
|
335
|
+
for (const name of superpowersSkills) {
|
|
336
|
+
const content = readFileSync(join(skillsDir, name, 'SKILL.md'), 'utf-8');
|
|
337
|
+
expect(content).toContain('MIT License');
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('should have no YOUR_AGENT_core placeholder remaining in any skill', () => {
|
|
342
|
+
scaffold(testConfig);
|
|
343
|
+
const skillsDir = join(tempDir, 'atlas', 'skills');
|
|
344
|
+
const allSkills = readdirSync(skillsDir);
|
|
345
|
+
|
|
346
|
+
for (const name of allSkills) {
|
|
347
|
+
const content = readFileSync(join(skillsDir, name, 'SKILL.md'), 'utf-8');
|
|
348
|
+
expect(content).not.toContain('YOUR_AGENT_core');
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it('should include skills in preview', () => {
|
|
353
|
+
const preview = previewScaffold(testConfig);
|
|
354
|
+
const paths = preview.files.map((f) => f.path);
|
|
355
|
+
expect(paths).toContain('skills/');
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('should mention skills in scaffold summary', () => {
|
|
359
|
+
const result = scaffold(testConfig);
|
|
360
|
+
expect(result.summary).toContain('built-in skills');
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
|
|
251
364
|
describe('listAgents', () => {
|
|
252
365
|
it('should list scaffolded agents', () => {
|
|
253
366
|
scaffold(testConfig);
|
package/src/scaffolder.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
readdirSync,
|
|
7
7
|
readFileSync,
|
|
8
8
|
} from 'node:fs';
|
|
9
|
-
import { join } from 'node:path';
|
|
9
|
+
import { join, dirname } from 'node:path';
|
|
10
10
|
import { homedir } from 'node:os';
|
|
11
11
|
import type { AgentConfig, ScaffoldResult, ScaffoldPreview, AgentInfo } from './types.js';
|
|
12
12
|
|
|
@@ -21,6 +21,7 @@ import { generateInjectClaudeMd } from './templates/inject-claude-md.js';
|
|
|
21
21
|
import { generateActivate } from './templates/activate.js';
|
|
22
22
|
import { generateReadme } from './templates/readme.js';
|
|
23
23
|
import { generateSetupScript } from './templates/setup-script.js';
|
|
24
|
+
import { generateSkills } from './templates/skills.js';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* Preview what scaffold will create without writing anything.
|
|
@@ -75,6 +76,11 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
75
76
|
path: 'scripts/setup.sh',
|
|
76
77
|
description: 'Automated setup — Node.js check, build, Claude Code MCP registration',
|
|
77
78
|
},
|
|
79
|
+
{
|
|
80
|
+
path: 'skills/',
|
|
81
|
+
description:
|
|
82
|
+
'17 built-in skills — TDD, debugging, planning, vault, brain, code patrol, retrospective, onboarding',
|
|
83
|
+
},
|
|
78
84
|
];
|
|
79
85
|
|
|
80
86
|
if (config.hookPacks?.length) {
|
|
@@ -92,7 +98,7 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
92
98
|
{
|
|
93
99
|
name: `${config.id}_core`,
|
|
94
100
|
ops: [
|
|
95
|
-
// From createCoreOps() —
|
|
101
|
+
// From createCoreOps() — 150 generic ops
|
|
96
102
|
'search',
|
|
97
103
|
'vault_stats',
|
|
98
104
|
'list_all',
|
|
@@ -125,6 +131,8 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
125
131
|
'brain_promote_proposals',
|
|
126
132
|
'brain_lifecycle',
|
|
127
133
|
'brain_reset_extracted',
|
|
134
|
+
// Brain decay report (#89) — 1
|
|
135
|
+
'brain_decay_report',
|
|
128
136
|
// Cognee ops — 5
|
|
129
137
|
'cognee_status',
|
|
130
138
|
'cognee_search',
|
|
@@ -134,6 +142,9 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
134
142
|
// LLM ops — 2
|
|
135
143
|
'llm_rotate',
|
|
136
144
|
'llm_call',
|
|
145
|
+
// Prompt ops — 2
|
|
146
|
+
'render_prompt',
|
|
147
|
+
'list_templates',
|
|
137
148
|
'curator_status',
|
|
138
149
|
'curator_detect_duplicates',
|
|
139
150
|
'curator_contradictions',
|
|
@@ -156,7 +167,7 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
156
167
|
'governance_stats',
|
|
157
168
|
'governance_expire',
|
|
158
169
|
'governance_dashboard',
|
|
159
|
-
// Planning Extra ops —
|
|
170
|
+
// Planning Extra ops — 22
|
|
160
171
|
'plan_iterate',
|
|
161
172
|
'plan_split',
|
|
162
173
|
'plan_reconcile',
|
|
@@ -166,6 +177,25 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
166
177
|
'plan_archive',
|
|
167
178
|
'plan_list_tasks',
|
|
168
179
|
'plan_stats',
|
|
180
|
+
// Planning evidence (#148)
|
|
181
|
+
'plan_submit_evidence',
|
|
182
|
+
'plan_verify_task',
|
|
183
|
+
'plan_verify_plan',
|
|
184
|
+
// Subagent dispatch (#149)
|
|
185
|
+
'plan_review_spec',
|
|
186
|
+
'plan_review_quality',
|
|
187
|
+
'plan_review_outcome',
|
|
188
|
+
// Brainstorm (#150)
|
|
189
|
+
'plan_brainstorm',
|
|
190
|
+
// Auto-reconcile (#151)
|
|
191
|
+
'plan_auto_reconcile',
|
|
192
|
+
// Validate plan (#152)
|
|
193
|
+
'plan_validate',
|
|
194
|
+
// Execution metrics + deliverables (#80, #83)
|
|
195
|
+
'plan_execution_metrics',
|
|
196
|
+
'plan_record_task_metrics',
|
|
197
|
+
'plan_submit_deliverable',
|
|
198
|
+
'plan_verify_deliverables',
|
|
169
199
|
// Memory Extra ops — 8
|
|
170
200
|
'memory_delete',
|
|
171
201
|
'memory_stats',
|
|
@@ -188,6 +218,16 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
188
218
|
'vault_seed',
|
|
189
219
|
'vault_backup',
|
|
190
220
|
'vault_age_report',
|
|
221
|
+
// Vault extra — seed canonical + knowledge lifecycle (5)
|
|
222
|
+
'vault_seed_canonical',
|
|
223
|
+
'knowledge_audit',
|
|
224
|
+
'knowledge_health',
|
|
225
|
+
'knowledge_merge',
|
|
226
|
+
'knowledge_reorganize',
|
|
227
|
+
// Bi-temporal vault ops (#89) — 3
|
|
228
|
+
'vault_set_temporal',
|
|
229
|
+
'vault_find_expiring',
|
|
230
|
+
'vault_find_expired',
|
|
191
231
|
// Admin ops — 8
|
|
192
232
|
'admin_health',
|
|
193
233
|
'admin_tool_list',
|
|
@@ -197,14 +237,16 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
197
237
|
'admin_version',
|
|
198
238
|
'admin_reset_cache',
|
|
199
239
|
'admin_diagnostic',
|
|
200
|
-
// Loop ops —
|
|
240
|
+
// Loop ops — 9
|
|
201
241
|
'loop_start',
|
|
202
242
|
'loop_iterate',
|
|
243
|
+
'loop_iterate_gate',
|
|
203
244
|
'loop_status',
|
|
204
245
|
'loop_cancel',
|
|
205
246
|
'loop_history',
|
|
206
247
|
'loop_is_active',
|
|
207
248
|
'loop_complete',
|
|
249
|
+
'loop_anomaly_check',
|
|
208
250
|
// Orchestrate ops — 5
|
|
209
251
|
'orchestrate_plan',
|
|
210
252
|
'orchestrate_execute',
|
|
@@ -222,7 +264,22 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
222
264
|
'capture_quick',
|
|
223
265
|
'search_intelligent',
|
|
224
266
|
'search_feedback',
|
|
225
|
-
//
|
|
267
|
+
// Enriched capture (#154) — 1
|
|
268
|
+
'capture_enriched',
|
|
269
|
+
// Cognee graph (#156) — 3
|
|
270
|
+
'cognee_get_node',
|
|
271
|
+
'cognee_graph_stats',
|
|
272
|
+
'cognee_export_status',
|
|
273
|
+
// Cognee Sync ops — 3
|
|
274
|
+
'cognee_sync_status',
|
|
275
|
+
'cognee_sync_drain',
|
|
276
|
+
'cognee_sync_reconcile',
|
|
277
|
+
// Intake ops — 4
|
|
278
|
+
'intake_ingest_book',
|
|
279
|
+
'intake_process',
|
|
280
|
+
'intake_status',
|
|
281
|
+
'intake_preview',
|
|
282
|
+
// Admin Extra ops — 23
|
|
226
283
|
'admin_telemetry',
|
|
227
284
|
'admin_telemetry_recent',
|
|
228
285
|
'admin_telemetry_reset',
|
|
@@ -233,11 +290,31 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
233
290
|
'admin_env',
|
|
234
291
|
'admin_gc',
|
|
235
292
|
'admin_export_config',
|
|
236
|
-
//
|
|
293
|
+
// Admin key pool (#157)
|
|
294
|
+
'admin_key_pool_status',
|
|
295
|
+
'admin_create_token',
|
|
296
|
+
'admin_revoke_token',
|
|
297
|
+
'admin_list_tokens',
|
|
298
|
+
// Admin accounts (#158)
|
|
299
|
+
'admin_add_account',
|
|
300
|
+
'admin_remove_account',
|
|
301
|
+
'admin_rotate_account',
|
|
302
|
+
'admin_list_accounts',
|
|
303
|
+
'admin_account_status',
|
|
304
|
+
// Admin plugins (#159)
|
|
305
|
+
'admin_list_plugins',
|
|
306
|
+
'admin_plugin_status',
|
|
307
|
+
// Admin instruction validation (#160)
|
|
308
|
+
'admin_validate_instructions',
|
|
309
|
+
// Hot reload (#63)
|
|
310
|
+
'admin_hot_reload',
|
|
311
|
+
// Curator Extra ops — 5
|
|
237
312
|
'curator_entry_history',
|
|
238
313
|
'curator_record_snapshot',
|
|
239
314
|
'curator_queue_stats',
|
|
240
315
|
'curator_enrich',
|
|
316
|
+
// Hybrid contradiction detection (#36) — 1
|
|
317
|
+
'curator_hybrid_contradictions',
|
|
241
318
|
// Project ops — 12
|
|
242
319
|
'project_get',
|
|
243
320
|
'project_list',
|
|
@@ -255,6 +332,12 @@ export function previewScaffold(config: AgentConfig): ScaffoldPreview {
|
|
|
255
332
|
'memory_promote_to_global',
|
|
256
333
|
'memory_configure',
|
|
257
334
|
'memory_cross_project_search',
|
|
335
|
+
// Playbook ops — 5
|
|
336
|
+
'playbook_list',
|
|
337
|
+
'playbook_get',
|
|
338
|
+
'playbook_create',
|
|
339
|
+
'playbook_match',
|
|
340
|
+
'playbook_seed',
|
|
258
341
|
// Agent-specific ops — 5
|
|
259
342
|
'health',
|
|
260
343
|
'identity',
|
|
@@ -295,6 +378,7 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
|
|
|
295
378
|
const dirs = [
|
|
296
379
|
'',
|
|
297
380
|
'scripts',
|
|
381
|
+
'skills',
|
|
298
382
|
'src',
|
|
299
383
|
'src/intelligence',
|
|
300
384
|
'src/intelligence/data',
|
|
@@ -358,6 +442,15 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
|
|
|
358
442
|
filesCreated.push(path);
|
|
359
443
|
}
|
|
360
444
|
|
|
445
|
+
// Generate skill files
|
|
446
|
+
const skillFiles = generateSkills(config);
|
|
447
|
+
for (const [path, content] of skillFiles) {
|
|
448
|
+
const skillDir = join(agentDir, dirname(path));
|
|
449
|
+
mkdirSync(skillDir, { recursive: true });
|
|
450
|
+
writeFileSync(join(agentDir, path), content, 'utf-8');
|
|
451
|
+
filesCreated.push(path);
|
|
452
|
+
}
|
|
453
|
+
|
|
361
454
|
const totalOps = config.domains.length * 5 + 61; // 5 per domain + 56 core (from createCoreOps) + 5 agent-specific
|
|
362
455
|
|
|
363
456
|
// Register the agent as an MCP server in ~/.claude.json
|
|
@@ -370,6 +463,7 @@ export function scaffold(config: AgentConfig): ScaffoldResult {
|
|
|
370
463
|
`Intelligence layer (Brain) — TF-IDF scoring, auto-tagging, duplicate detection`,
|
|
371
464
|
`Activation system included — say "Hello, ${config.name}!" to activate`,
|
|
372
465
|
`1 test suite — facades (vault, brain, planner, llm tests provided by @soleri/core)`,
|
|
466
|
+
`${skillFiles.length} built-in skills (TDD, debugging, planning, vault, brain debrief)`,
|
|
373
467
|
];
|
|
374
468
|
|
|
375
469
|
if (config.hookPacks?.length) {
|