@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.
Files changed (72) hide show
  1. package/dist/scaffolder.js +98 -6
  2. package/dist/scaffolder.js.map +1 -1
  3. package/dist/skills/brain-debrief.md +186 -0
  4. package/dist/skills/brainstorming.md +170 -0
  5. package/dist/skills/code-patrol.md +176 -0
  6. package/dist/skills/context-resume.md +143 -0
  7. package/dist/skills/executing-plans.md +201 -0
  8. package/dist/skills/fix-and-learn.md +164 -0
  9. package/dist/skills/health-check.md +225 -0
  10. package/dist/skills/knowledge-harvest.md +178 -0
  11. package/dist/skills/onboard-me.md +197 -0
  12. package/dist/skills/retrospective.md +189 -0
  13. package/dist/skills/second-opinion.md +142 -0
  14. package/dist/skills/skills/brain-debrief.md +214 -0
  15. package/dist/skills/skills/brainstorming.md +180 -0
  16. package/dist/skills/skills/code-patrol.md +178 -0
  17. package/dist/skills/skills/context-resume.md +146 -0
  18. package/dist/skills/skills/executing-plans.md +216 -0
  19. package/dist/skills/skills/fix-and-learn.md +167 -0
  20. package/dist/skills/skills/health-check.md +231 -0
  21. package/dist/skills/skills/knowledge-harvest.md +185 -0
  22. package/dist/skills/skills/onboard-me.md +198 -0
  23. package/dist/skills/skills/retrospective.md +205 -0
  24. package/dist/skills/skills/second-opinion.md +149 -0
  25. package/dist/skills/skills/systematic-debugging.md +241 -0
  26. package/dist/skills/skills/test-driven-development.md +281 -0
  27. package/dist/skills/skills/vault-capture.md +170 -0
  28. package/dist/skills/skills/vault-navigator.md +140 -0
  29. package/dist/skills/skills/verification-before-completion.md +182 -0
  30. package/dist/skills/skills/writing-plans.md +215 -0
  31. package/dist/skills/systematic-debugging.md +230 -0
  32. package/dist/skills/test-driven-development.md +266 -0
  33. package/dist/skills/vault-capture.md +154 -0
  34. package/dist/skills/vault-navigator.md +129 -0
  35. package/dist/skills/verification-before-completion.md +170 -0
  36. package/dist/skills/writing-plans.md +207 -0
  37. package/dist/templates/entry-point.js +8 -0
  38. package/dist/templates/entry-point.js.map +1 -1
  39. package/dist/templates/readme.js +38 -0
  40. package/dist/templates/readme.js.map +1 -1
  41. package/dist/templates/setup-script.js +26 -0
  42. package/dist/templates/setup-script.js.map +1 -1
  43. package/dist/templates/skills.d.ts +16 -0
  44. package/dist/templates/skills.js +73 -0
  45. package/dist/templates/skills.js.map +1 -0
  46. package/dist/templates/test-facades.js +35 -6
  47. package/dist/templates/test-facades.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/__tests__/scaffolder.test.ts +115 -2
  50. package/src/scaffolder.ts +100 -6
  51. package/src/skills/brain-debrief.md +214 -0
  52. package/src/skills/brainstorming.md +180 -0
  53. package/src/skills/code-patrol.md +178 -0
  54. package/src/skills/context-resume.md +146 -0
  55. package/src/skills/executing-plans.md +216 -0
  56. package/src/skills/fix-and-learn.md +167 -0
  57. package/src/skills/health-check.md +231 -0
  58. package/src/skills/knowledge-harvest.md +185 -0
  59. package/src/skills/onboard-me.md +198 -0
  60. package/src/skills/retrospective.md +205 -0
  61. package/src/skills/second-opinion.md +149 -0
  62. package/src/skills/systematic-debugging.md +241 -0
  63. package/src/skills/test-driven-development.md +281 -0
  64. package/src/skills/vault-capture.md +170 -0
  65. package/src/skills/vault-navigator.md +140 -0
  66. package/src/skills/verification-before-completion.md +182 -0
  67. package/src/skills/writing-plans.md +215 -0
  68. package/src/templates/entry-point.ts +8 -0
  69. package/src/templates/readme.ts +38 -0
  70. package/src/templates/setup-script.ts +26 -0
  71. package/src/templates/skills.ts +82 -0
  72. 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 (9)
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 (7)
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 (10)
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
- // Curator Extra ops (4)
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
- // Total: 152 (147 core + 5 agent-specific)
330
- expect(facade.ops.length).toBe(152);
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAoKM,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"}
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.4.0",
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 152 ops (147 core + 5 agent-specific)
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(152);
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() — 144 generic ops
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 — 9
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 — 7
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
- // Admin Extra ops10
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
- // Curator Extra ops — 4
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) {