@soleri/forge 5.1.3 → 5.4.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/index.js +0 -0
- package/dist/scaffolder.js +150 -2
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/brain.d.ts +6 -0
- package/dist/templates/brain.js +478 -0
- package/dist/templates/brain.js.map +1 -0
- package/dist/templates/claude-md-template.js +90 -1
- package/dist/templates/claude-md-template.js.map +1 -1
- package/dist/templates/core-facade.d.ts +6 -0
- package/dist/templates/core-facade.js +564 -0
- package/dist/templates/core-facade.js.map +1 -0
- package/dist/templates/domain-facade.d.ts +4 -0
- package/dist/templates/domain-facade.js +4 -0
- package/dist/templates/domain-facade.js.map +1 -1
- package/dist/templates/entry-point.js +32 -0
- package/dist/templates/entry-point.js.map +1 -1
- package/dist/templates/facade-factory.d.ts +1 -0
- package/dist/templates/facade-factory.js +63 -0
- package/dist/templates/facade-factory.js.map +1 -0
- package/dist/templates/facade-types.d.ts +1 -0
- package/dist/templates/facade-types.js +46 -0
- package/dist/templates/facade-types.js.map +1 -0
- package/dist/templates/intelligence-loader.d.ts +1 -0
- package/dist/templates/intelligence-loader.js +43 -0
- package/dist/templates/intelligence-loader.js.map +1 -0
- package/dist/templates/intelligence-types.d.ts +1 -0
- package/dist/templates/intelligence-types.js +24 -0
- package/dist/templates/intelligence-types.js.map +1 -0
- package/dist/templates/llm-client.d.ts +7 -0
- package/dist/templates/llm-client.js +300 -0
- package/dist/templates/llm-client.js.map +1 -0
- package/dist/templates/llm-key-pool.d.ts +7 -0
- package/dist/templates/llm-key-pool.js +211 -0
- package/dist/templates/llm-key-pool.js.map +1 -0
- package/dist/templates/llm-types.d.ts +5 -0
- package/dist/templates/llm-types.js +161 -0
- package/dist/templates/llm-types.js.map +1 -0
- package/dist/templates/llm-utils.d.ts +5 -0
- package/dist/templates/llm-utils.js +260 -0
- package/dist/templates/llm-utils.js.map +1 -0
- package/dist/templates/planner.d.ts +5 -0
- package/dist/templates/planner.js +150 -0
- package/dist/templates/planner.js.map +1 -0
- package/dist/templates/setup-script.js +26 -1
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/test-brain.d.ts +6 -0
- package/dist/templates/test-brain.js +474 -0
- package/dist/templates/test-brain.js.map +1 -0
- package/dist/templates/test-facades.js +173 -3
- package/dist/templates/test-facades.js.map +1 -1
- package/dist/templates/test-llm.d.ts +7 -0
- package/dist/templates/test-llm.js +574 -0
- package/dist/templates/test-llm.js.map +1 -0
- package/dist/templates/test-loader.d.ts +5 -0
- package/dist/templates/test-loader.js +146 -0
- package/dist/templates/test-loader.js.map +1 -0
- package/dist/templates/test-planner.d.ts +5 -0
- package/dist/templates/test-planner.js +271 -0
- package/dist/templates/test-planner.js.map +1 -0
- package/dist/templates/test-vault.d.ts +5 -0
- package/dist/templates/test-vault.js +380 -0
- package/dist/templates/test-vault.js.map +1 -0
- package/dist/templates/vault.d.ts +5 -0
- package/dist/templates/vault.js +263 -0
- package/dist/templates/vault.js.map +1 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/scaffolder.test.ts +2 -2
- package/src/scaffolder.ts +153 -2
- package/src/templates/claude-md-template.ts +181 -0
- package/src/templates/domain-facade.ts +4 -0
- package/src/templates/entry-point.ts +32 -0
- package/src/templates/setup-script.ts +28 -1
- package/src/templates/test-facades.ts +173 -3
- package/src/types.ts +2 -0
|
@@ -57,6 +57,9 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
|
|
|
57
57
|
`| Session capture | ${bt}${toolPrefix}_core${bt} | ${bt}session_capture${bt} |`,
|
|
58
58
|
`| Export knowledge | ${bt}${toolPrefix}_core${bt} | ${bt}export${bt} |`,
|
|
59
59
|
`| Record feedback | ${bt}${toolPrefix}_core${bt} | ${bt}record_feedback${bt} |`,
|
|
60
|
+
`| Enhanced feedback | ${bt}${toolPrefix}_core${bt} | ${bt}brain_feedback${bt} |`,
|
|
61
|
+
`| Feedback stats | ${bt}${toolPrefix}_core${bt} | ${bt}brain_feedback_stats${bt} |`,
|
|
62
|
+
`| Reset extracted | ${bt}${toolPrefix}_core${bt} | ${bt}brain_reset_extracted${bt} |`,
|
|
60
63
|
`| Rebuild vocabulary | ${bt}${toolPrefix}_core${bt} | ${bt}rebuild_vocabulary${bt} |`,
|
|
61
64
|
`| Brain stats | ${bt}${toolPrefix}_core${bt} | ${bt}brain_stats${bt} |`,
|
|
62
65
|
`| LLM status | ${bt}${toolPrefix}_core${bt} | ${bt}llm_status${bt} |`,
|
|
@@ -73,6 +76,117 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
|
|
|
73
76
|
`| Add guideline | ${bt}${toolPrefix}_core${bt} | ${bt}add_guideline${bt} |`,
|
|
74
77
|
`| Remove guideline | ${bt}${toolPrefix}_core${bt} | ${bt}remove_guideline${bt} |`,
|
|
75
78
|
`| Rollback identity | ${bt}${toolPrefix}_core${bt} | ${bt}rollback_identity${bt} |`,
|
|
79
|
+
`| Cognee status | ${bt}${toolPrefix}_core${bt} | ${bt}cognee_status${bt} |`,
|
|
80
|
+
`| Cognee search | ${bt}${toolPrefix}_core${bt} | ${bt}cognee_search${bt} |`,
|
|
81
|
+
`| Cognee add | ${bt}${toolPrefix}_core${bt} | ${bt}cognee_add${bt} |`,
|
|
82
|
+
`| Cognee cognify | ${bt}${toolPrefix}_core${bt} | ${bt}cognee_cognify${bt} |`,
|
|
83
|
+
`| Cognee config | ${bt}${toolPrefix}_core${bt} | ${bt}cognee_config${bt} |`,
|
|
84
|
+
`| LLM rotate key | ${bt}${toolPrefix}_core${bt} | ${bt}llm_rotate${bt} |`,
|
|
85
|
+
`| LLM call | ${bt}${toolPrefix}_core${bt} | ${bt}llm_call${bt} |`,
|
|
86
|
+
`| Governance policy | ${bt}${toolPrefix}_core${bt} | ${bt}governance_policy${bt} |`,
|
|
87
|
+
`| Governance proposals | ${bt}${toolPrefix}_core${bt} | ${bt}governance_proposals${bt} |`,
|
|
88
|
+
`| Governance stats | ${bt}${toolPrefix}_core${bt} | ${bt}governance_stats${bt} |`,
|
|
89
|
+
`| Expire proposals | ${bt}${toolPrefix}_core${bt} | ${bt}governance_expire${bt} |`,
|
|
90
|
+
`| Governance dashboard | ${bt}${toolPrefix}_core${bt} | ${bt}governance_dashboard${bt} |`,
|
|
91
|
+
// Planning Extra ops
|
|
92
|
+
`| Iterate plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_iterate${bt} |`,
|
|
93
|
+
`| Split plan tasks | ${bt}${toolPrefix}_core${bt} | ${bt}plan_split${bt} |`,
|
|
94
|
+
`| Reconcile plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_reconcile${bt} |`,
|
|
95
|
+
`| Complete lifecycle | ${bt}${toolPrefix}_core${bt} | ${bt}plan_complete_lifecycle${bt} |`,
|
|
96
|
+
`| Dispatch tasks | ${bt}${toolPrefix}_core${bt} | ${bt}plan_dispatch${bt} |`,
|
|
97
|
+
`| Review plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_review${bt} |`,
|
|
98
|
+
`| Archive plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_archive${bt} |`,
|
|
99
|
+
`| List plan tasks | ${bt}${toolPrefix}_core${bt} | ${bt}plan_list_tasks${bt} |`,
|
|
100
|
+
`| Plan stats | ${bt}${toolPrefix}_core${bt} | ${bt}plan_stats${bt} |`,
|
|
101
|
+
// Memory Extra ops
|
|
102
|
+
`| Delete memory | ${bt}${toolPrefix}_core${bt} | ${bt}memory_delete${bt} |`,
|
|
103
|
+
`| Memory stats | ${bt}${toolPrefix}_core${bt} | ${bt}memory_stats${bt} |`,
|
|
104
|
+
`| Export memories | ${bt}${toolPrefix}_core${bt} | ${bt}memory_export${bt} |`,
|
|
105
|
+
`| Import memories | ${bt}${toolPrefix}_core${bt} | ${bt}memory_import${bt} |`,
|
|
106
|
+
`| Prune memories | ${bt}${toolPrefix}_core${bt} | ${bt}memory_prune${bt} |`,
|
|
107
|
+
`| Deduplicate memories | ${bt}${toolPrefix}_core${bt} | ${bt}memory_deduplicate${bt} |`,
|
|
108
|
+
`| Memory topics | ${bt}${toolPrefix}_core${bt} | ${bt}memory_topics${bt} |`,
|
|
109
|
+
`| Memories by project | ${bt}${toolPrefix}_core${bt} | ${bt}memory_by_project${bt} |`,
|
|
110
|
+
// Vault Extra ops
|
|
111
|
+
`| Get vault entry | ${bt}${toolPrefix}_core${bt} | ${bt}vault_get${bt} |`,
|
|
112
|
+
`| Update entry | ${bt}${toolPrefix}_core${bt} | ${bt}vault_update${bt} |`,
|
|
113
|
+
`| Remove entry | ${bt}${toolPrefix}_core${bt} | ${bt}vault_remove${bt} |`,
|
|
114
|
+
`| Bulk add | ${bt}${toolPrefix}_core${bt} | ${bt}vault_bulk_add${bt} |`,
|
|
115
|
+
`| Bulk remove | ${bt}${toolPrefix}_core${bt} | ${bt}vault_bulk_remove${bt} |`,
|
|
116
|
+
`| Vault tags | ${bt}${toolPrefix}_core${bt} | ${bt}vault_tags${bt} |`,
|
|
117
|
+
`| Vault domains | ${bt}${toolPrefix}_core${bt} | ${bt}vault_domains${bt} |`,
|
|
118
|
+
`| Recent entries | ${bt}${toolPrefix}_core${bt} | ${bt}vault_recent${bt} |`,
|
|
119
|
+
`| Import entries | ${bt}${toolPrefix}_core${bt} | ${bt}vault_import${bt} |`,
|
|
120
|
+
`| Seed entries | ${bt}${toolPrefix}_core${bt} | ${bt}vault_seed${bt} |`,
|
|
121
|
+
`| Backup vault | ${bt}${toolPrefix}_core${bt} | ${bt}vault_backup${bt} |`,
|
|
122
|
+
`| Vault age report | ${bt}${toolPrefix}_core${bt} | ${bt}vault_age_report${bt} |`,
|
|
123
|
+
// Admin ops
|
|
124
|
+
`| Admin health | ${bt}${toolPrefix}_core${bt} | ${bt}admin_health${bt} |`,
|
|
125
|
+
`| Tool list | ${bt}${toolPrefix}_core${bt} | ${bt}admin_tool_list${bt} |`,
|
|
126
|
+
`| Config | ${bt}${toolPrefix}_core${bt} | ${bt}admin_config${bt} |`,
|
|
127
|
+
`| Vault size | ${bt}${toolPrefix}_core${bt} | ${bt}admin_vault_size${bt} |`,
|
|
128
|
+
`| Uptime | ${bt}${toolPrefix}_core${bt} | ${bt}admin_uptime${bt} |`,
|
|
129
|
+
`| Version | ${bt}${toolPrefix}_core${bt} | ${bt}admin_version${bt} |`,
|
|
130
|
+
`| Reset cache | ${bt}${toolPrefix}_core${bt} | ${bt}admin_reset_cache${bt} |`,
|
|
131
|
+
`| Diagnostic | ${bt}${toolPrefix}_core${bt} | ${bt}admin_diagnostic${bt} |`,
|
|
132
|
+
// Loop ops
|
|
133
|
+
`| Start loop | ${bt}${toolPrefix}_core${bt} | ${bt}loop_start${bt} |`,
|
|
134
|
+
`| Loop iterate | ${bt}${toolPrefix}_core${bt} | ${bt}loop_iterate${bt} |`,
|
|
135
|
+
`| Loop status | ${bt}${toolPrefix}_core${bt} | ${bt}loop_status${bt} |`,
|
|
136
|
+
`| Cancel loop | ${bt}${toolPrefix}_core${bt} | ${bt}loop_cancel${bt} |`,
|
|
137
|
+
`| Loop history | ${bt}${toolPrefix}_core${bt} | ${bt}loop_history${bt} |`,
|
|
138
|
+
`| Loop active | ${bt}${toolPrefix}_core${bt} | ${bt}loop_is_active${bt} |`,
|
|
139
|
+
`| Complete loop | ${bt}${toolPrefix}_core${bt} | ${bt}loop_complete${bt} |`,
|
|
140
|
+
// Orchestrate ops
|
|
141
|
+
`| Orchestrate plan | ${bt}${toolPrefix}_core${bt} | ${bt}orchestrate_plan${bt} |`,
|
|
142
|
+
`| Orchestrate execute | ${bt}${toolPrefix}_core${bt} | ${bt}orchestrate_execute${bt} |`,
|
|
143
|
+
`| Orchestrate complete | ${bt}${toolPrefix}_core${bt} | ${bt}orchestrate_complete${bt} |`,
|
|
144
|
+
`| Orchestrate status | ${bt}${toolPrefix}_core${bt} | ${bt}orchestrate_status${bt} |`,
|
|
145
|
+
`| Quick capture | ${bt}${toolPrefix}_core${bt} | ${bt}orchestrate_quick_capture${bt} |`,
|
|
146
|
+
// Capture ops
|
|
147
|
+
`| Capture knowledge | ${bt}${toolPrefix}_core${bt} | ${bt}capture_knowledge${bt} |`,
|
|
148
|
+
`| Quick capture entry | ${bt}${toolPrefix}_core${bt} | ${bt}capture_quick${bt} |`,
|
|
149
|
+
`| Intelligent search | ${bt}${toolPrefix}_core${bt} | ${bt}search_intelligent${bt} |`,
|
|
150
|
+
`| Search feedback | ${bt}${toolPrefix}_core${bt} | ${bt}search_feedback${bt} |`,
|
|
151
|
+
// Grading ops
|
|
152
|
+
`| Grade plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_grade${bt} |`,
|
|
153
|
+
`| Check history | ${bt}${toolPrefix}_core${bt} | ${bt}plan_check_history${bt} |`,
|
|
154
|
+
`| Latest check | ${bt}${toolPrefix}_core${bt} | ${bt}plan_latest_check${bt} |`,
|
|
155
|
+
`| Meets grade | ${bt}${toolPrefix}_core${bt} | ${bt}plan_meets_grade${bt} |`,
|
|
156
|
+
`| Auto improve plan | ${bt}${toolPrefix}_core${bt} | ${bt}plan_auto_improve${bt} |`,
|
|
157
|
+
// Admin Extra ops
|
|
158
|
+
`| Telemetry stats | ${bt}${toolPrefix}_core${bt} | ${bt}admin_telemetry${bt} |`,
|
|
159
|
+
`| Recent calls | ${bt}${toolPrefix}_core${bt} | ${bt}admin_telemetry_recent${bt} |`,
|
|
160
|
+
`| Reset telemetry | ${bt}${toolPrefix}_core${bt} | ${bt}admin_telemetry_reset${bt} |`,
|
|
161
|
+
`| Permissions | ${bt}${toolPrefix}_core${bt} | ${bt}admin_permissions${bt} |`,
|
|
162
|
+
`| Vault analytics | ${bt}${toolPrefix}_core${bt} | ${bt}admin_vault_analytics${bt} |`,
|
|
163
|
+
`| Search insights | ${bt}${toolPrefix}_core${bt} | ${bt}admin_search_insights${bt} |`,
|
|
164
|
+
`| Module status | ${bt}${toolPrefix}_core${bt} | ${bt}admin_module_status${bt} |`,
|
|
165
|
+
`| Environment | ${bt}${toolPrefix}_core${bt} | ${bt}admin_env${bt} |`,
|
|
166
|
+
`| Garbage collect | ${bt}${toolPrefix}_core${bt} | ${bt}admin_gc${bt} |`,
|
|
167
|
+
`| Export config | ${bt}${toolPrefix}_core${bt} | ${bt}admin_export_config${bt} |`,
|
|
168
|
+
// Curator Extra ops
|
|
169
|
+
`| Entry history | ${bt}${toolPrefix}_core${bt} | ${bt}curator_entry_history${bt} |`,
|
|
170
|
+
`| Record snapshot | ${bt}${toolPrefix}_core${bt} | ${bt}curator_record_snapshot${bt} |`,
|
|
171
|
+
`| Queue stats | ${bt}${toolPrefix}_core${bt} | ${bt}curator_queue_stats${bt} |`,
|
|
172
|
+
`| Enrich metadata | ${bt}${toolPrefix}_core${bt} | ${bt}curator_enrich${bt} |`,
|
|
173
|
+
// Project ops
|
|
174
|
+
`| Get project | ${bt}${toolPrefix}_core${bt} | ${bt}project_get${bt} |`,
|
|
175
|
+
`| List projects | ${bt}${toolPrefix}_core${bt} | ${bt}project_list${bt} |`,
|
|
176
|
+
`| Unregister project | ${bt}${toolPrefix}_core${bt} | ${bt}project_unregister${bt} |`,
|
|
177
|
+
`| Project rules | ${bt}${toolPrefix}_core${bt} | ${bt}project_get_rules${bt} |`,
|
|
178
|
+
`| All project rules | ${bt}${toolPrefix}_core${bt} | ${bt}project_list_rules${bt} |`,
|
|
179
|
+
`| Add rule | ${bt}${toolPrefix}_core${bt} | ${bt}project_add_rule${bt} |`,
|
|
180
|
+
`| Remove rule | ${bt}${toolPrefix}_core${bt} | ${bt}project_remove_rule${bt} |`,
|
|
181
|
+
`| Link projects | ${bt}${toolPrefix}_core${bt} | ${bt}project_link${bt} |`,
|
|
182
|
+
`| Unlink projects | ${bt}${toolPrefix}_core${bt} | ${bt}project_unlink${bt} |`,
|
|
183
|
+
`| Project links | ${bt}${toolPrefix}_core${bt} | ${bt}project_get_links${bt} |`,
|
|
184
|
+
`| Linked projects | ${bt}${toolPrefix}_core${bt} | ${bt}project_linked_projects${bt} |`,
|
|
185
|
+
`| Touch project | ${bt}${toolPrefix}_core${bt} | ${bt}project_touch${bt} |`,
|
|
186
|
+
// Cross-project memory ops
|
|
187
|
+
`| Promote to global | ${bt}${toolPrefix}_core${bt} | ${bt}memory_promote_to_global${bt} |`,
|
|
188
|
+
`| Configure memory | ${bt}${toolPrefix}_core${bt} | ${bt}memory_configure${bt} |`,
|
|
189
|
+
`| Cross-project search | ${bt}${toolPrefix}_core${bt} | ${bt}memory_cross_project_search${bt} |`,
|
|
76
190
|
);
|
|
77
191
|
|
|
78
192
|
mdLines.push(
|
|
@@ -130,6 +244,73 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
|
|
|
130
244
|
`<!-- /${marker} -->`,
|
|
131
245
|
);
|
|
132
246
|
|
|
247
|
+
// ─── Hook Packs section (when configured) ─────────────────────
|
|
248
|
+
if (config.hookPacks?.length) {
|
|
249
|
+
const PACK_INFO: Record<string, { description: string; hooks: Record<string, string> }> = {
|
|
250
|
+
'typescript-safety': {
|
|
251
|
+
description: 'Block unsafe TypeScript patterns',
|
|
252
|
+
hooks: {
|
|
253
|
+
'no-any-types': '`:any`, `as any`, `<any>`, `Record<string, any>`',
|
|
254
|
+
'no-console-log': '`console.log` in committed code',
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
a11y: {
|
|
258
|
+
description: 'Accessibility enforcement',
|
|
259
|
+
hooks: {
|
|
260
|
+
'semantic-html': 'Generic divs where semantic HTML should be used',
|
|
261
|
+
'focus-ring-required': 'Missing visible focus indicators',
|
|
262
|
+
'ux-touch-targets': 'Touch targets smaller than 44px',
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
'css-discipline': {
|
|
266
|
+
description: 'CSS best practices',
|
|
267
|
+
hooks: {
|
|
268
|
+
'no-important': '`!important` in CSS',
|
|
269
|
+
'no-inline-styles': 'Inline style attributes',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
'clean-commits': {
|
|
273
|
+
description: 'Clean git history',
|
|
274
|
+
hooks: {
|
|
275
|
+
'no-ai-attribution': 'AI attribution in commits',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// Build rows — expand 'full' to constituent packs
|
|
281
|
+
const rows: Array<{ pack: string; hook: string; blocks: string }> = [];
|
|
282
|
+
for (const packName of config.hookPacks) {
|
|
283
|
+
if (packName === 'full') {
|
|
284
|
+
// Composed pack — expand all constituent packs
|
|
285
|
+
for (const [subPack, info] of Object.entries(PACK_INFO)) {
|
|
286
|
+
for (const [hook, blocks] of Object.entries(info.hooks)) {
|
|
287
|
+
rows.push({ pack: subPack, hook, blocks });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
} else if (PACK_INFO[packName]) {
|
|
291
|
+
for (const [hook, blocks] of Object.entries(PACK_INFO[packName].hooks)) {
|
|
292
|
+
rows.push({ pack: packName, hook, blocks });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (rows.length > 0) {
|
|
298
|
+
// Insert before the closing marker
|
|
299
|
+
const closingMarkerIndex = mdLines.length - 1;
|
|
300
|
+
const hookLines = [
|
|
301
|
+
'',
|
|
302
|
+
'## Hook Packs',
|
|
303
|
+
'',
|
|
304
|
+
'Quality gates installed in `.claude/`. Run `scripts/setup.sh` to install globally.',
|
|
305
|
+
'',
|
|
306
|
+
'| Pack | Hook | Blocks |',
|
|
307
|
+
'|------|------|--------|',
|
|
308
|
+
...rows.map((r) => `| ${r.pack} | ${r.hook} | ${r.blocks} |`),
|
|
309
|
+
];
|
|
310
|
+
mdLines.splice(closingMarkerIndex, 0, ...hookLines);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
133
314
|
// Escape each markdown line for use in a single-quoted TS string literal
|
|
134
315
|
const quotedLines = mdLines.map((line) => {
|
|
135
316
|
const escaped = line.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate a domain-specific facade for the agent.
|
|
3
3
|
* Each domain gets a facade with search, get_patterns, and list ops.
|
|
4
|
+
*
|
|
5
|
+
* @deprecated v4 legacy only — v5 agents use createDomainFacade() from
|
|
6
|
+
* @soleri/core which includes governance gating. This template is only
|
|
7
|
+
* used by domain-manager.ts for pre-v5 agents.
|
|
4
8
|
*/
|
|
5
9
|
export function generateDomainFacade(agentId: string, domain: string): string {
|
|
6
10
|
const facadeName = `${agentId}_${domain.replace(/-/g, '_')}`;
|
|
@@ -143,6 +143,37 @@ async function main(): Promise<void> {
|
|
|
143
143
|
if (s.totalEntries === 0) {
|
|
144
144
|
recommendations.push('Vault is empty — add intelligence data or capture knowledge via domain facades');
|
|
145
145
|
}
|
|
146
|
+
|
|
147
|
+
// Check hook status
|
|
148
|
+
const { readdirSync } = await import('node:fs');
|
|
149
|
+
const agentClaudeDir = joinPath(__dirname, '..', '.claude');
|
|
150
|
+
const globalClaudeDir = joinPath(homedir(), '.claude');
|
|
151
|
+
|
|
152
|
+
const hookStatus = { agent: [] as string[], global: [] as string[], missing: [] as string[] };
|
|
153
|
+
|
|
154
|
+
if (existsSync(agentClaudeDir)) {
|
|
155
|
+
try {
|
|
156
|
+
const agentHooks = readdirSync(agentClaudeDir)
|
|
157
|
+
.filter((f: string) => f.startsWith('hookify.') && f.endsWith('.local.md'))
|
|
158
|
+
.map((f: string) => f.replace('hookify.', '').replace('.local.md', ''));
|
|
159
|
+
hookStatus.agent = agentHooks;
|
|
160
|
+
|
|
161
|
+
for (const hook of agentHooks) {
|
|
162
|
+
if (existsSync(joinPath(globalClaudeDir, \`hookify.\${hook}.local.md\`))) {
|
|
163
|
+
hookStatus.global.push(hook);
|
|
164
|
+
} else {
|
|
165
|
+
hookStatus.missing.push(hook);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} catch {
|
|
169
|
+
// ignore read errors
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (hookStatus.missing.length > 0) {
|
|
174
|
+
recommendations.push(\`\${hookStatus.missing.length} hook(s) not installed globally — run scripts/setup.sh\`);
|
|
175
|
+
}
|
|
176
|
+
|
|
146
177
|
if (recommendations.length === 0) {
|
|
147
178
|
recommendations.push('${config.name} is fully set up and ready!');
|
|
148
179
|
}
|
|
@@ -154,6 +185,7 @@ async function main(): Promise<void> {
|
|
|
154
185
|
global: { exists: globalExists, has_agent_section: globalHasAgent },
|
|
155
186
|
},
|
|
156
187
|
vault: { entries: s.totalEntries, domains: Object.keys(s.byDomain) },
|
|
188
|
+
hooks: hookStatus,
|
|
157
189
|
recommendations,
|
|
158
190
|
};
|
|
159
191
|
},
|
|
@@ -101,7 +101,34 @@ else
|
|
|
101
101
|
fi
|
|
102
102
|
fi
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
${
|
|
105
|
+
config.hookPacks?.length
|
|
106
|
+
? `# Install hook packs to global ~/.claude/
|
|
107
|
+
AGENT_CLAUDE_DIR="$AGENT_DIR/.claude"
|
|
108
|
+
GLOBAL_CLAUDE_DIR="$HOME/.claude"
|
|
109
|
+
|
|
110
|
+
if [ -d "$AGENT_CLAUDE_DIR" ]; then
|
|
111
|
+
echo ""
|
|
112
|
+
echo "Installing hook packs..."
|
|
113
|
+
mkdir -p "$GLOBAL_CLAUDE_DIR"
|
|
114
|
+
installed=0
|
|
115
|
+
skipped=0
|
|
116
|
+
for hook_file in "$AGENT_CLAUDE_DIR"/hookify.*.local.md; do
|
|
117
|
+
[ -f "$hook_file" ] || continue
|
|
118
|
+
dest="$GLOBAL_CLAUDE_DIR/$(basename "$hook_file")"
|
|
119
|
+
if [ -f "$dest" ]; then
|
|
120
|
+
skipped=$((skipped + 1))
|
|
121
|
+
else
|
|
122
|
+
cp "$hook_file" "$dest"
|
|
123
|
+
installed=$((installed + 1))
|
|
124
|
+
fi
|
|
125
|
+
done
|
|
126
|
+
echo "[ok] Hooks: $installed installed, $skipped already present"
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
`
|
|
130
|
+
: ''
|
|
131
|
+
}echo ""
|
|
105
132
|
echo "=== Setup Complete ==="
|
|
106
133
|
echo ""
|
|
107
134
|
echo "Next:"
|
|
@@ -126,6 +126,29 @@ ${domainDescribes}
|
|
|
126
126
|
if (stats.totalEntries === 0) {
|
|
127
127
|
recommendations.push('Vault is empty');
|
|
128
128
|
}
|
|
129
|
+
// Check hook status
|
|
130
|
+
const { readdirSync } = await import('node:fs');
|
|
131
|
+
const agentClaudeDir = joinPath(__dirname, '..', '.claude');
|
|
132
|
+
const globalClaudeDir = joinPath(homedir(), '.claude');
|
|
133
|
+
const hookStatus = { agent: [] as string[], global: [] as string[], missing: [] as string[] };
|
|
134
|
+
if (exists(agentClaudeDir)) {
|
|
135
|
+
try {
|
|
136
|
+
const agentHooks = readdirSync(agentClaudeDir)
|
|
137
|
+
.filter((f: string) => f.startsWith('hookify.') && f.endsWith('.local.md'))
|
|
138
|
+
.map((f: string) => f.replace('hookify.', '').replace('.local.md', ''));
|
|
139
|
+
hookStatus.agent = agentHooks;
|
|
140
|
+
for (const hook of agentHooks) {
|
|
141
|
+
if (exists(joinPath(globalClaudeDir, \`hookify.\${hook}.local.md\`))) {
|
|
142
|
+
hookStatus.global.push(hook);
|
|
143
|
+
} else {
|
|
144
|
+
hookStatus.missing.push(hook);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch { /* ignore */ }
|
|
148
|
+
}
|
|
149
|
+
if (hookStatus.missing.length > 0) {
|
|
150
|
+
recommendations.push(\`\${hookStatus.missing.length} hook(s) not installed globally — run scripts/setup.sh\`);
|
|
151
|
+
}
|
|
129
152
|
if (recommendations.length === 0) {
|
|
130
153
|
recommendations.push('${config.name} is fully set up and ready!');
|
|
131
154
|
}
|
|
@@ -136,6 +159,7 @@ ${domainDescribes}
|
|
|
136
159
|
global: { exists: exists(globalClaudeMd), has_agent_section: hasAgentMarker(globalClaudeMd) },
|
|
137
160
|
},
|
|
138
161
|
vault: { entries: stats.totalEntries, domains: Object.keys(stats.byDomain) },
|
|
162
|
+
hooks: hookStatus,
|
|
139
163
|
recommendations,
|
|
140
164
|
};
|
|
141
165
|
},
|
|
@@ -172,6 +196,10 @@ ${domainDescribes}
|
|
|
172
196
|
expect(opNames).toContain('brain_archive_sessions');
|
|
173
197
|
expect(opNames).toContain('brain_promote_proposals');
|
|
174
198
|
expect(opNames).toContain('brain_lifecycle');
|
|
199
|
+
// Enhanced brain ops (3)
|
|
200
|
+
expect(opNames).toContain('brain_feedback');
|
|
201
|
+
expect(opNames).toContain('brain_feedback_stats');
|
|
202
|
+
expect(opNames).toContain('brain_reset_extracted');
|
|
175
203
|
// Agent-specific ops (5)
|
|
176
204
|
expect(opNames).toContain('health');
|
|
177
205
|
expect(opNames).toContain('identity');
|
|
@@ -187,8 +215,122 @@ ${domainDescribes}
|
|
|
187
215
|
expect(opNames).toContain('route_intent');
|
|
188
216
|
expect(opNames).toContain('morph');
|
|
189
217
|
expect(opNames).toContain('get_behavior_rules');
|
|
190
|
-
//
|
|
191
|
-
expect(
|
|
218
|
+
// Cognee ops (5)
|
|
219
|
+
expect(opNames).toContain('cognee_status');
|
|
220
|
+
expect(opNames).toContain('cognee_search');
|
|
221
|
+
expect(opNames).toContain('cognee_add');
|
|
222
|
+
expect(opNames).toContain('cognee_cognify');
|
|
223
|
+
expect(opNames).toContain('cognee_config');
|
|
224
|
+
// LLM ops (2)
|
|
225
|
+
expect(opNames).toContain('llm_rotate');
|
|
226
|
+
expect(opNames).toContain('llm_call');
|
|
227
|
+
// Governance ops (5)
|
|
228
|
+
expect(opNames).toContain('governance_policy');
|
|
229
|
+
expect(opNames).toContain('governance_proposals');
|
|
230
|
+
expect(opNames).toContain('governance_stats');
|
|
231
|
+
expect(opNames).toContain('governance_expire');
|
|
232
|
+
expect(opNames).toContain('governance_dashboard');
|
|
233
|
+
// Planning Extra ops (9)
|
|
234
|
+
expect(opNames).toContain('plan_iterate');
|
|
235
|
+
expect(opNames).toContain('plan_split');
|
|
236
|
+
expect(opNames).toContain('plan_reconcile');
|
|
237
|
+
expect(opNames).toContain('plan_complete_lifecycle');
|
|
238
|
+
expect(opNames).toContain('plan_dispatch');
|
|
239
|
+
expect(opNames).toContain('plan_review');
|
|
240
|
+
expect(opNames).toContain('plan_archive');
|
|
241
|
+
expect(opNames).toContain('plan_list_tasks');
|
|
242
|
+
expect(opNames).toContain('plan_stats');
|
|
243
|
+
// Memory Extra ops (8)
|
|
244
|
+
expect(opNames).toContain('memory_delete');
|
|
245
|
+
expect(opNames).toContain('memory_stats');
|
|
246
|
+
expect(opNames).toContain('memory_export');
|
|
247
|
+
expect(opNames).toContain('memory_import');
|
|
248
|
+
expect(opNames).toContain('memory_prune');
|
|
249
|
+
expect(opNames).toContain('memory_deduplicate');
|
|
250
|
+
expect(opNames).toContain('memory_topics');
|
|
251
|
+
expect(opNames).toContain('memory_by_project');
|
|
252
|
+
// Vault Extra ops (12)
|
|
253
|
+
expect(opNames).toContain('vault_get');
|
|
254
|
+
expect(opNames).toContain('vault_update');
|
|
255
|
+
expect(opNames).toContain('vault_remove');
|
|
256
|
+
expect(opNames).toContain('vault_bulk_add');
|
|
257
|
+
expect(opNames).toContain('vault_bulk_remove');
|
|
258
|
+
expect(opNames).toContain('vault_tags');
|
|
259
|
+
expect(opNames).toContain('vault_domains');
|
|
260
|
+
expect(opNames).toContain('vault_recent');
|
|
261
|
+
expect(opNames).toContain('vault_import');
|
|
262
|
+
expect(opNames).toContain('vault_seed');
|
|
263
|
+
expect(opNames).toContain('vault_backup');
|
|
264
|
+
expect(opNames).toContain('vault_age_report');
|
|
265
|
+
// Admin ops (8)
|
|
266
|
+
expect(opNames).toContain('admin_health');
|
|
267
|
+
expect(opNames).toContain('admin_tool_list');
|
|
268
|
+
expect(opNames).toContain('admin_config');
|
|
269
|
+
expect(opNames).toContain('admin_vault_size');
|
|
270
|
+
expect(opNames).toContain('admin_uptime');
|
|
271
|
+
expect(opNames).toContain('admin_version');
|
|
272
|
+
expect(opNames).toContain('admin_reset_cache');
|
|
273
|
+
expect(opNames).toContain('admin_diagnostic');
|
|
274
|
+
// Loop ops (7)
|
|
275
|
+
expect(opNames).toContain('loop_start');
|
|
276
|
+
expect(opNames).toContain('loop_iterate');
|
|
277
|
+
expect(opNames).toContain('loop_status');
|
|
278
|
+
expect(opNames).toContain('loop_cancel');
|
|
279
|
+
expect(opNames).toContain('loop_history');
|
|
280
|
+
expect(opNames).toContain('loop_is_active');
|
|
281
|
+
expect(opNames).toContain('loop_complete');
|
|
282
|
+
// Orchestrate ops (5)
|
|
283
|
+
expect(opNames).toContain('orchestrate_plan');
|
|
284
|
+
expect(opNames).toContain('orchestrate_execute');
|
|
285
|
+
expect(opNames).toContain('orchestrate_complete');
|
|
286
|
+
expect(opNames).toContain('orchestrate_status');
|
|
287
|
+
expect(opNames).toContain('orchestrate_quick_capture');
|
|
288
|
+
// Capture ops (4)
|
|
289
|
+
expect(opNames).toContain('capture_knowledge');
|
|
290
|
+
expect(opNames).toContain('capture_quick');
|
|
291
|
+
expect(opNames).toContain('search_intelligent');
|
|
292
|
+
expect(opNames).toContain('search_feedback');
|
|
293
|
+
// Grading ops (5)
|
|
294
|
+
expect(opNames).toContain('plan_grade');
|
|
295
|
+
expect(opNames).toContain('plan_check_history');
|
|
296
|
+
expect(opNames).toContain('plan_latest_check');
|
|
297
|
+
expect(opNames).toContain('plan_meets_grade');
|
|
298
|
+
expect(opNames).toContain('plan_auto_improve');
|
|
299
|
+
// Admin Extra ops (10)
|
|
300
|
+
expect(opNames).toContain('admin_telemetry');
|
|
301
|
+
expect(opNames).toContain('admin_telemetry_recent');
|
|
302
|
+
expect(opNames).toContain('admin_telemetry_reset');
|
|
303
|
+
expect(opNames).toContain('admin_permissions');
|
|
304
|
+
expect(opNames).toContain('admin_vault_analytics');
|
|
305
|
+
expect(opNames).toContain('admin_search_insights');
|
|
306
|
+
expect(opNames).toContain('admin_module_status');
|
|
307
|
+
expect(opNames).toContain('admin_env');
|
|
308
|
+
expect(opNames).toContain('admin_gc');
|
|
309
|
+
expect(opNames).toContain('admin_export_config');
|
|
310
|
+
// Curator Extra ops (4)
|
|
311
|
+
expect(opNames).toContain('curator_entry_history');
|
|
312
|
+
expect(opNames).toContain('curator_record_snapshot');
|
|
313
|
+
expect(opNames).toContain('curator_queue_stats');
|
|
314
|
+
expect(opNames).toContain('curator_enrich');
|
|
315
|
+
// Project ops (12)
|
|
316
|
+
expect(opNames).toContain('project_get');
|
|
317
|
+
expect(opNames).toContain('project_list');
|
|
318
|
+
expect(opNames).toContain('project_unregister');
|
|
319
|
+
expect(opNames).toContain('project_get_rules');
|
|
320
|
+
expect(opNames).toContain('project_list_rules');
|
|
321
|
+
expect(opNames).toContain('project_add_rule');
|
|
322
|
+
expect(opNames).toContain('project_remove_rule');
|
|
323
|
+
expect(opNames).toContain('project_link');
|
|
324
|
+
expect(opNames).toContain('project_unlink');
|
|
325
|
+
expect(opNames).toContain('project_get_links');
|
|
326
|
+
expect(opNames).toContain('project_linked_projects');
|
|
327
|
+
expect(opNames).toContain('project_touch');
|
|
328
|
+
// Cross-project memory ops (3)
|
|
329
|
+
expect(opNames).toContain('memory_promote_to_global');
|
|
330
|
+
expect(opNames).toContain('memory_configure');
|
|
331
|
+
expect(opNames).toContain('memory_cross_project_search');
|
|
332
|
+
// Total: 152 (147 core + 5 agent-specific)
|
|
333
|
+
expect(facade.ops.length).toBe(152);
|
|
192
334
|
});
|
|
193
335
|
|
|
194
336
|
it('search should query across all domains with ranked results', async () => {
|
|
@@ -280,7 +422,9 @@ ${domainDescribes}
|
|
|
280
422
|
const setupOp = facade.ops.find((o) => o.name === 'setup')!;
|
|
281
423
|
const result = (await setupOp.handler({ projectPath: '/tmp/nonexistent-test' })) as {
|
|
282
424
|
agent: { name: string };
|
|
425
|
+
claude_md: { project: { exists: boolean; has_agent_section: boolean }; global: { exists: boolean; has_agent_section: boolean } };
|
|
283
426
|
vault: { entries: number };
|
|
427
|
+
hooks: { agent: string[]; global: string[]; missing: string[] };
|
|
284
428
|
recommendations: string[];
|
|
285
429
|
};
|
|
286
430
|
expect(result.agent.name).toBe('${escapeQuotes(config.name)}');
|
|
@@ -330,6 +474,32 @@ ${domainDescribes}
|
|
|
330
474
|
const result = (await healthOp.handler({})) as { score: number };
|
|
331
475
|
expect(result.score).toBeGreaterThan(0);
|
|
332
476
|
});
|
|
477
|
+
|
|
478
|
+
it('governance_policy get should return default policy', async () => {
|
|
479
|
+
const facade = buildCoreFacade();
|
|
480
|
+
const policyOp = facade.ops.find((o) => o.name === 'governance_policy')!;
|
|
481
|
+
const result = (await policyOp.handler({ action: 'get', projectPath: '/test' })) as {
|
|
482
|
+
projectPath: string;
|
|
483
|
+
quotas: { maxEntriesTotal: number };
|
|
484
|
+
autoCapture: { enabled: boolean };
|
|
485
|
+
};
|
|
486
|
+
expect(result.projectPath).toBe('/test');
|
|
487
|
+
expect(result.quotas.maxEntriesTotal).toBe(500);
|
|
488
|
+
expect(result.autoCapture.enabled).toBe(true);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it('governance_dashboard should return combined view', async () => {
|
|
492
|
+
const facade = buildCoreFacade();
|
|
493
|
+
const dashOp = facade.ops.find((o) => o.name === 'governance_dashboard')!;
|
|
494
|
+
const result = (await dashOp.handler({ projectPath: '/test' })) as {
|
|
495
|
+
vaultSize: number;
|
|
496
|
+
quotaPercent: number;
|
|
497
|
+
pendingProposals: number;
|
|
498
|
+
};
|
|
499
|
+
expect(typeof result.vaultSize).toBe('number');
|
|
500
|
+
expect(typeof result.quotaPercent).toBe('number');
|
|
501
|
+
expect(result.pendingProposals).toBe(0);
|
|
502
|
+
});
|
|
333
503
|
});
|
|
334
504
|
});
|
|
335
505
|
`;
|
|
@@ -387,7 +557,7 @@ function generateDomainDescribe(agentId: string, domain: string): string {
|
|
|
387
557
|
severity: 'warning',
|
|
388
558
|
description: 'A captured pattern.',
|
|
389
559
|
tags: ['captured'],
|
|
390
|
-
})) as { captured: boolean };
|
|
560
|
+
})) as { captured: boolean; governance?: { action: string } };
|
|
391
561
|
expect(result.captured).toBe(true);
|
|
392
562
|
const entry = runtime.vault.get('${domain}-cap1');
|
|
393
563
|
expect(entry).not.toBeNull();
|
package/src/types.ts
CHANGED
|
@@ -18,6 +18,8 @@ export const AgentConfigSchema = z.object({
|
|
|
18
18
|
greeting: z.string().min(10).max(300),
|
|
19
19
|
/** Output directory (parent — agent dir will be created inside) */
|
|
20
20
|
outputDir: z.string().min(1),
|
|
21
|
+
/** Hook packs to install after scaffolding (optional) */
|
|
22
|
+
hookPacks: z.array(z.string()).optional(),
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
export type AgentConfig = z.infer<typeof AgentConfigSchema>;
|