@soleri/forge 5.14.8 → 5.14.10

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.
@@ -1,8 +1,11 @@
1
1
  import type { AgentConfig } from '../types.js';
2
2
  /**
3
3
  * Generates src/activation/activate.ts for a new agent.
4
- * Provides the activate/deactivate system that returns full context
5
- * to Claudepersona, guidelines, tool recommendations, setup status.
4
+ *
5
+ * Activation is ADAPTIVE it discovers current capabilities at runtime
6
+ * (vault domains, installed packs, identity changes) rather than returning
7
+ * a frozen snapshot from scaffold time. PERSONA is the birth config;
8
+ * the activation response reflects what the agent has become.
6
9
  *
7
10
  * Uses array-joined pattern because generated code contains template literals.
8
11
  */
@@ -1,21 +1,15 @@
1
1
  /**
2
2
  * Generates src/activation/activate.ts for a new agent.
3
- * Provides the activate/deactivate system that returns full context
4
- * to Claudepersona, guidelines, tool recommendations, setup status.
3
+ *
4
+ * Activation is ADAPTIVE it discovers current capabilities at runtime
5
+ * (vault domains, installed packs, identity changes) rather than returning
6
+ * a frozen snapshot from scaffold time. PERSONA is the birth config;
7
+ * the activation response reflects what the agent has become.
5
8
  *
6
9
  * Uses array-joined pattern because generated code contains template literals.
7
10
  */
8
11
  export function generateActivate(config) {
9
- const toolPrefix = config.id; // keep hyphens — matches MCP tool registration
10
- const _marker = `${config.id}:mode`;
11
- // Build tool recommendations from config domains
12
- const toolRecLines = [];
13
- for (const d of config.domains) {
14
- const toolName = `${toolPrefix}_${d.replace(/-/g, '_')}`;
15
- toolRecLines.push(` { intent: 'search ${d}', facade: '${toolName}', op: 'search' },`);
16
- toolRecLines.push(` { intent: '${d} patterns', facade: '${toolName}', op: 'get_patterns' },`);
17
- toolRecLines.push(` { intent: 'capture ${d}', facade: '${toolName}', op: 'capture' },`);
18
- }
12
+ const toolPrefix = config.id;
19
13
  // Build behavioral guidelines from config principles
20
14
  const guidelineLines = config.principles
21
15
  .map((p) => {
@@ -23,23 +17,31 @@ export function generateActivate(config) {
23
17
  return ` '${escaped}',`;
24
18
  })
25
19
  .join('\n');
20
+ // Static domain list (from scaffold time) — used as baseline
21
+ const configDomains = JSON.stringify(config.domains);
26
22
  return [
27
23
  "import { join } from 'node:path';",
24
+ "import { existsSync, readFileSync } from 'node:fs';",
28
25
  "import { homedir } from 'node:os';",
29
26
  "import { PERSONA } from '../identity/persona.js';",
30
27
  "import { hasAgentMarker, removeClaudeMdGlobal } from './inject-claude-md.js';",
31
- "import type { Vault, Planner, Plan } from '@soleri/core';",
28
+ "import type { AgentRuntime } from '@soleri/core';",
32
29
  '',
33
30
  'export interface ActivationResult {',
34
31
  ' activated: boolean;',
35
- ' persona: {',
32
+ ' origin: {',
36
33
  ' name: string;',
37
34
  ' role: string;',
38
35
  ' description: string;',
36
+ ' };',
37
+ ' current: {',
38
+ ' role: string;',
39
39
  ' greeting: string;',
40
+ ' domains: string[];',
41
+ ' capabilities: Array<{ domain: string; entries: number }>;',
42
+ ' installed_packs: Array<{ id: string; type: string }>;',
40
43
  ' };',
41
44
  ' guidelines: string[];',
42
- ' tool_recommendations: Array<{ intent: string; facade: string; op: string }>;',
43
45
  ' session_instruction: string;',
44
46
  ' setup_status: {',
45
47
  ' claude_md_injected: boolean;',
@@ -60,20 +62,80 @@ export function generateActivate(config) {
60
62
  '}',
61
63
  '',
62
64
  '/**',
63
- ` * Activate ${config.name} — returns full context for Claude to adopt the persona.`,
65
+ ` * Activate ${config.name} — discovers current capabilities and returns adaptive context.`,
66
+ ' *',
67
+ ' * PERSONA is the birth config. The activation response reflects what the agent',
68
+ ' * has become through installed packs, captured knowledge, and identity updates.',
64
69
  ' */',
65
- 'export function activateAgent(vault: Vault, projectPath: string, planner?: Planner): ActivationResult {',
66
- ' // Check CLAUDE.md injection status (project-level and global)',
70
+ 'export function activateAgent(runtime: AgentRuntime, projectPath: string): ActivationResult {',
71
+ ' const { vault, planner, identityManager } = runtime;',
72
+ '',
73
+ ' // ─── Setup status ──────────────────────────────────────────',
67
74
  " const projectClaudeMd = join(projectPath, 'CLAUDE.md');",
68
75
  " const globalClaudeMd = join(homedir(), '.claude', 'CLAUDE.md');",
69
76
  ' const claudeMdInjected = hasAgentMarker(projectClaudeMd);',
70
77
  ' const globalClaudeMdInjected = hasAgentMarker(globalClaudeMd);',
71
78
  '',
72
- ' // Check vault status',
79
+ ' // ─── Vault stats — what the agent actually knows ──────────',
73
80
  ' const stats = vault.stats();',
74
81
  ' const vaultHasEntries = stats.totalEntries > 0;',
75
82
  '',
76
- " // Build next steps based on what's missing",
83
+ ' // ─── Discover domains ─────────────────────────────────────',
84
+ ` const configuredDomains: string[] = ${configDomains};`,
85
+ ' const vaultDomains = Object.keys(stats.byDomain);',
86
+ '',
87
+ ' // Merge configured + vault-discovered domains (dedup)',
88
+ ' const allDomains = [...new Set([...configuredDomains, ...vaultDomains])];',
89
+ '',
90
+ ' // Build capability map — entries per domain',
91
+ ' const capabilities = allDomains.map((d) => ({',
92
+ ' domain: d,',
93
+ ' entries: stats.byDomain[d] ?? 0,',
94
+ ' }));',
95
+ '',
96
+ ' // ─── Discover installed packs ─────────────────────────────',
97
+ ' const installedPacks: Array<{ id: string; type: string }> = [];',
98
+ ' try {',
99
+ " const lockPath = join(projectPath, 'soleri.lock');",
100
+ ' if (existsSync(lockPath)) {',
101
+ " const lockData = JSON.parse(readFileSync(lockPath, 'utf-8'));",
102
+ ' if (lockData.packs) {',
103
+ ' for (const [id, entry] of Object.entries(lockData.packs)) {',
104
+ ' installedPacks.push({ id, type: (entry as Record<string, string>).type ?? "unknown" });',
105
+ ' }',
106
+ ' }',
107
+ ' }',
108
+ ' } catch {',
109
+ ' // Lock file missing or corrupt — proceed without pack info',
110
+ ' }',
111
+ '',
112
+ ' // ─── Dynamic role — based on what the agent actually covers ─',
113
+ " const currentIdentity = identityManager.getIdentity('" + config.id + "');",
114
+ ' const newDomains = allDomains.filter((d) => !configuredDomains.includes(d));',
115
+ ' let currentRole = currentIdentity?.role ?? PERSONA.role;',
116
+ '',
117
+ ' // If the agent has grown beyond its birth domains, reflect that',
118
+ ' if (newDomains.length > 0) {',
119
+ ' const formatted = newDomains.map((d) => d.replace(/-/g, " ")).join(", ");',
120
+ ' currentRole = `${PERSONA.role} (also covering ${formatted})`;',
121
+ ' }',
122
+ '',
123
+ ' // ─── Dynamic greeting ─────────────────────────────────────',
124
+ " let greeting = `Hello! I'm ${PERSONA.name}.`;",
125
+ ' if (allDomains.length > configuredDomains.length) {',
126
+ " greeting += ` I started as a ${PERSONA.role} and have expanded to also cover ${newDomains.map((d) => d.replace(/-/g, ' ')).join(', ')}.`;",
127
+ ' } else {',
128
+ ' greeting += ` ${PERSONA.role} ready to help.`;',
129
+ ' }',
130
+ ' if (stats.totalEntries > 0) {',
131
+ ' const domainSummary = capabilities',
132
+ ' .filter((c) => c.entries > 0)',
133
+ ' .map((c) => `${c.entries} ${c.domain.replace(/-/g, " ")}`)',
134
+ ' .join(", ");',
135
+ ' greeting += ` Vault: ${stats.totalEntries} entries (${domainSummary}).`;',
136
+ ' }',
137
+ '',
138
+ ' // ─── Next steps ───────────────────────────────────────────',
77
139
  ' const nextSteps: string[] = [];',
78
140
  ' if (!globalClaudeMdInjected && !claudeMdInjected) {',
79
141
  ` nextSteps.push('No CLAUDE.md configured — run inject_claude_md with global: true for all projects, or without for this project only');`,
@@ -81,10 +143,7 @@ export function generateActivate(config) {
81
143
  ` nextSteps.push('Global CLAUDE.md not configured — run inject_claude_md with global: true to enable activation in all projects');`,
82
144
  ' }',
83
145
  ' if (!vaultHasEntries) {',
84
- " nextSteps.push('Vault is empty — start capturing knowledge with the domain capture ops');",
85
- ' }',
86
- ' if (nextSteps.length === 0) {',
87
- ` nextSteps.push('All set! ${config.name} is fully integrated.');`,
146
+ " nextSteps.push('Vault is empty — start capturing knowledge with the domain capture ops, or install a knowledge pack with soleri pack install');",
88
147
  ' }',
89
148
  '',
90
149
  ' // Check for executing plans',
@@ -98,25 +157,30 @@ export function generateActivate(config) {
98
157
  ' nextSteps.unshift(`${executingPlans.length} plan(s) in progress — use get_plan to review`);',
99
158
  ' }',
100
159
  '',
160
+ ' if (nextSteps.length === 0) {',
161
+ ` nextSteps.push('All set! ${config.name} is ready.');`,
162
+ ' }',
163
+ '',
101
164
  ' return {',
102
165
  ' activated: true,',
103
- ' persona: {',
166
+ ' origin: {',
104
167
  ' name: PERSONA.name,',
105
168
  ' role: PERSONA.role,',
106
169
  ' description: PERSONA.description,',
107
- ' greeting: PERSONA.greeting,',
170
+ ' },',
171
+ ' current: {',
172
+ ' role: currentRole,',
173
+ ' greeting,',
174
+ ' domains: allDomains,',
175
+ ' capabilities,',
176
+ ' installed_packs: installedPacks,',
108
177
  ' },',
109
178
  ' guidelines: [',
110
179
  guidelineLines,
111
180
  ' ],',
112
- ' tool_recommendations: [',
113
- ` { intent: 'health check', facade: '${toolPrefix}_core', op: 'health' },`,
114
- ` { intent: 'search all', facade: '${toolPrefix}_core', op: 'search' },`,
115
- ` { intent: 'vault stats', facade: '${toolPrefix}_core', op: 'vault_stats' },`,
116
- ...toolRecLines,
117
- ' ],',
118
- ` session_instruction: 'You are now ' + PERSONA.name + ', a ' + PERSONA.role + '. Stay in character for the ENTIRE session. ' +`,
119
- ` 'Reference patterns from the knowledge vault. Provide concrete examples. Flag anti-patterns with severity.',`,
181
+ " session_instruction: `You are ${PERSONA.name}. Your origin role is ${PERSONA.role}, but you have grown — your current capabilities span: ${allDomains.join(', ')}. ` +",
182
+ " 'Adapt your expertise to match your actual knowledge. ' +",
183
+ " 'Reference patterns from the knowledge vault. Provide concrete examples. Flag anti-patterns with severity.',",
120
184
  ' setup_status: {',
121
185
  ' claude_md_injected: claudeMdInjected,',
122
186
  ' global_claude_md_injected: globalClaudeMdInjected,',
@@ -132,7 +196,6 @@ export function generateActivate(config) {
132
196
  ` * Deactivate ${config.name} — drops persona and cleans up CLAUDE.md sections.`,
133
197
  ' */',
134
198
  'export function deactivateAgent(): DeactivationResult {',
135
- ' // Remove agent sections from global CLAUDE.md on deactivation',
136
199
  ' const globalResult = removeClaudeMdGlobal();',
137
200
  ' return {',
138
201
  ' deactivated: true,',
@@ -1 +1 @@
1
- {"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/templates/activate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/templates/activate.ts"],"names":[],"mappings":"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"}
@@ -25,8 +25,8 @@ export function generateClaudeMdTemplate(config) {
25
25
  // ─── Identity ──────────────────────────────────────────
26
26
  `## ${config.name}`,
27
27
  '',
28
- `**Role:** ${config.role}`,
29
- `**Domains:** ${config.domains.join(', ')}`,
28
+ `**Origin role:** ${config.role}`,
29
+ `**Initial domains:** ${config.domains.join(', ')}`,
30
30
  `**Tone:** ${config.tone ?? 'pragmatic'}`,
31
31
  '',
32
32
  config.description,
@@ -34,13 +34,26 @@ export function generateClaudeMdTemplate(config) {
34
34
  '**Principles:**',
35
35
  ...config.principles.map((p) => `- ${p}`),
36
36
  '',
37
+ // ─── Adaptive Identity ──────────────────────────────────
38
+ '## Adaptive Identity',
39
+ '',
40
+ `${config.name} is not a fixed-role agent. The origin role above is a starting point — the agent evolves as knowledge is added.`,
41
+ '',
42
+ '**On activation**, the agent discovers its current capabilities by checking:',
43
+ '- Vault domains (what knowledge actually exists)',
44
+ '- Installed packs (what was added after creation)',
45
+ '- Identity updates (any role changes via `op:update_identity`)',
46
+ '',
47
+ '**Use the `current` field** from the activation response — not `origin` — to determine how to present yourself.',
48
+ 'If you have grown beyond your origin role, say so. Your greeting and expertise should reflect what you actually know.',
49
+ '',
37
50
  // ─── Activation ────────────────────────────────────────
38
51
  '## Activation',
39
52
  '',
40
53
  `**Activate:** "Hello, ${config.name}!" → ${bt}${toolPrefix}_core op:activate params:{ projectPath: "." }${bt}`,
41
54
  `**Deactivate:** "Goodbye, ${config.name}!" → ${bt}${toolPrefix}_core op:activate params:{ deactivate: true }${bt}`,
42
55
  '',
43
- 'On activation, adopt the returned persona. Stay in character until deactivated.',
56
+ 'On activation, read the `current` field to discover your evolved role, then adopt that persona for the session.',
44
57
  '',
45
58
  // ─── Session Start ─────────────────────────────────────
46
59
  '## Session Start',
@@ -1 +1 @@
1
- {"version":3,"file":"claude-md-template.js","sourceRoot":"","sources":["../../src/templates/claude-md-template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-md-template.js","sourceRoot":"","sources":["../../src/templates/claude-md-template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAmB;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,EAAE,OAAO,CAAC;IACnC,MAAM,EAAE,GAAG,GAAG,CAAC;IAEf,MAAM,OAAO,GAAa;QACxB,QAAQ,MAAM,MAAM;QACpB,EAAE;QACF,KAAK,MAAM,CAAC,IAAI,OAAO;QACvB,EAAE;QAEF,0DAA0D;QAC1D,MAAM,MAAM,CAAC,IAAI,EAAE;QACnB,EAAE;QACF,oBAAoB,MAAM,CAAC,IAAI,EAAE;QACjC,wBAAwB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACnD,aAAa,MAAM,CAAC,IAAI,IAAI,WAAW,EAAE;QACzC,EAAE;QACF,MAAM,CAAC,WAAW;QAClB,EAAE;QACF,iBAAiB;QACjB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,EAAE;QAEF,2DAA2D;QAC3D,sBAAsB;QACtB,EAAE;QACF,GAAG,MAAM,CAAC,IAAI,kHAAkH;QAChI,EAAE;QACF,8EAA8E;QAC9E,kDAAkD;QAClD,mDAAmD;QACnD,gEAAgE;QAChE,EAAE;QACF,iHAAiH;QACjH,uHAAuH;QACvH,EAAE;QAEF,0DAA0D;QAC1D,eAAe;QACf,EAAE;QACF,yBAAyB,MAAM,CAAC,IAAI,QAAQ,EAAE,GAAG,UAAU,gDAAgD,EAAE,EAAE;QAC/G,6BAA6B,MAAM,CAAC,IAAI,QAAQ,EAAE,GAAG,UAAU,gDAAgD,EAAE,EAAE;QACnH,EAAE;QACF,iHAAiH;QACjH,EAAE;QAEF,0DAA0D;QAC1D,kBAAkB;QAClB,EAAE;QACF,yBAAyB,EAAE,GAAG,UAAU,gDAAgD,EAAE,EAAE;QAC5F,EAAE;KACH,CAAC;IAEF,2DAA2D;IAC3D,OAAO,CAAC,IAAI,CACV,oBAAoB,EACpB,QAAQ,UAAU,YAAY,EAC9B,EAAE,EACF,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,EAAE,GAAG,UAAU,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CACpI,CAAC;IAEF,sCAAsC;IACtC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,GAAG,UAAU,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CACV,KAAK,EAAE,GAAG,QAAQ,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAC1F,CAAC;IACJ,CAAC;IAED,oFAAoF;IACpF,OAAO,CAAC,IAAI;IACV,2DAA2D;IAC3D,KAAK,EAAE,GAAG,UAAU,SAAS,EAAE,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EACnJ,KAAK,EAAE,GAAG,UAAU,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAC/J,KAAK,EAAE,GAAG,UAAU,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI;IACvL,qDAAqD;IACrD,KAAK,EAAE,GAAG,UAAU,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,KAAK,EAAE,4BAA4B,EAAE,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EACnO,KAAK,EAAE,GAAG,UAAU,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,KAAK,EAAE,gCAAgC,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI;IACpL,iCAAiC;IACjC,KAAK,EAAE,GAAG,UAAU,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,0BAA0B,EAAE,IAAI,EACrK,KAAK,EAAE,GAAG,UAAU,eAAe,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EACrI,KAAK,EAAE,GAAG,UAAU,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI;IACzK,wBAAwB;IACxB,KAAK,EAAE,GAAG,UAAU,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EACnH,KAAK,EAAE,GAAG,UAAU,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,uBAAuB,EAAE,KAAK,EAAE,oBAAoB,EAAE,IAAI,EAC1K,KAAK,EAAE,GAAG,UAAU,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI;IAC/H,yCAAyC;IACzC,KAAK,EAAE,GAAG,UAAU,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAC5H,KAAK,EAAE,GAAG,UAAU,WAAW,EAAE,MAAM,EAAE,2BAA2B,EAAE,KAAK,EAAE,6BAA6B,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAC3I,KAAK,EAAE,GAAG,UAAU,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,0BAA0B,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI;IAC/K,QAAQ;IACR,KAAK,EAAE,GAAG,UAAU,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,CACpH,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,EAAE,GAAG,UAAU,4BAA4B,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAEtF,0DAA0D;IAC1D,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEjC,0DAA0D;IAC1D,OAAO,CAAC,IAAI,CAAC,SAAS,MAAM,MAAM,CAAC,CAAC;IAEpC,gEAAgE;IAChE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjE,OAAO,QAAQ,OAAO,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,mDAAmD;IACnD,MAAM,aAAa,GAAG,qBAAqB,EAAE,CAAC;IAC9C,MAAM,iBAAiB,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACjE,OAAO,QAAQ,OAAO,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,4BAA4B,MAAM,CAAC,IAAI,GAAG;QAC1C,gDAAgD;QAChD,KAAK;QACL,EAAE;QACF,qEAAqE;QACrE,gDAAgD;QAChD,YAAY;QACZ,GAAG,WAAW;QACd,kBAAkB;QAClB,GAAG;QACH,EAAE;QACF,+CAA+C;QAC/C,aAAa,MAAM,IAAI;QACvB,GAAG;QACH,EAAE;QACF,yEAAyE;QACzE,mDAAmD;QACnD,YAAY;QACZ,GAAG,iBAAiB;QACpB,kBAAkB;QAClB,GAAG;QACH,EAAE;QACF,kDAAkD;QAClD,aAAa,eAAe,EAAE,IAAI;QAClC,GAAG;KACJ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,eAAe,CAAC,OAAiB,EAAE,MAAmB;IAC7D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM;QAAE,OAAO;IAEtC,mDAAmD;IACnD,oEAAoE;IACpE,yDAAyD;IACzD,OAAO,CAAC,IAAI,CACV,eAAe,EACf,EAAE,EACF,oFAAoF,EACpF,EAAE,EACF,oBAAoB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACjD,EAAE,EACF,wEAAwE,EACxE,uDAAuD,EACvD,EAAE,CACH,CAAC;AACJ,CAAC"}
@@ -99,7 +99,7 @@ async function main(): Promise<void> {
99
99
  changeReason: 'Initial identity seeded from PERSONA',
100
100
  });
101
101
  }
102
- return activateAgent(runtime.vault, (params.projectPath as string) ?? '.', runtime.planner);
102
+ return activateAgent(runtime, (params.projectPath as string) ?? '.');
103
103
  },
104
104
  },
105
105
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleri/forge",
3
- "version": "5.14.8",
3
+ "version": "5.14.10",
4
4
  "description": "Scaffold AI agents that learn, remember, and grow with you.",
5
5
  "keywords": [
6
6
  "agent",
@@ -2,26 +2,15 @@ import type { AgentConfig } from '../types.js';
2
2
 
3
3
  /**
4
4
  * Generates src/activation/activate.ts for a new agent.
5
- * Provides the activate/deactivate system that returns full context
6
- * to Claudepersona, guidelines, tool recommendations, setup status.
5
+ *
6
+ * Activation is ADAPTIVE it discovers current capabilities at runtime
7
+ * (vault domains, installed packs, identity changes) rather than returning
8
+ * a frozen snapshot from scaffold time. PERSONA is the birth config;
9
+ * the activation response reflects what the agent has become.
7
10
  *
8
11
  * Uses array-joined pattern because generated code contains template literals.
9
12
  */
10
13
  export function generateActivate(config: AgentConfig): string {
11
- const toolPrefix = config.id; // keep hyphens — matches MCP tool registration
12
- const _marker = `${config.id}:mode`;
13
-
14
- // Build tool recommendations from config domains
15
- const toolRecLines: string[] = [];
16
- for (const d of config.domains) {
17
- const toolName = `${toolPrefix}_${d.replace(/-/g, '_')}`;
18
- toolRecLines.push(` { intent: 'search ${d}', facade: '${toolName}', op: 'search' },`);
19
- toolRecLines.push(
20
- ` { intent: '${d} patterns', facade: '${toolName}', op: 'get_patterns' },`,
21
- );
22
- toolRecLines.push(` { intent: 'capture ${d}', facade: '${toolName}', op: 'capture' },`);
23
- }
24
-
25
14
  // Build behavioral guidelines from config principles
26
15
  const guidelineLines = config.principles
27
16
  .map((p) => {
@@ -30,23 +19,32 @@ export function generateActivate(config: AgentConfig): string {
30
19
  })
31
20
  .join('\n');
32
21
 
22
+ // Static domain list (from scaffold time) — used as baseline
23
+ const configDomains = JSON.stringify(config.domains);
24
+
33
25
  return [
34
26
  "import { join } from 'node:path';",
27
+ "import { existsSync, readFileSync } from 'node:fs';",
35
28
  "import { homedir } from 'node:os';",
36
29
  "import { PERSONA } from '../identity/persona.js';",
37
30
  "import { hasAgentMarker, removeClaudeMdGlobal } from './inject-claude-md.js';",
38
- "import type { Vault, Planner, Plan } from '@soleri/core';",
31
+ "import type { AgentRuntime } from '@soleri/core';",
39
32
  '',
40
33
  'export interface ActivationResult {',
41
34
  ' activated: boolean;',
42
- ' persona: {',
35
+ ' origin: {',
43
36
  ' name: string;',
44
37
  ' role: string;',
45
38
  ' description: string;',
39
+ ' };',
40
+ ' current: {',
41
+ ' role: string;',
46
42
  ' greeting: string;',
43
+ ' domains: string[];',
44
+ ' capabilities: Array<{ domain: string; entries: number }>;',
45
+ ' installed_packs: Array<{ id: string; type: string }>;',
47
46
  ' };',
48
47
  ' guidelines: string[];',
49
- ' tool_recommendations: Array<{ intent: string; facade: string; op: string }>;',
50
48
  ' session_instruction: string;',
51
49
  ' setup_status: {',
52
50
  ' claude_md_injected: boolean;',
@@ -67,20 +65,80 @@ export function generateActivate(config: AgentConfig): string {
67
65
  '}',
68
66
  '',
69
67
  '/**',
70
- ` * Activate ${config.name} — returns full context for Claude to adopt the persona.`,
68
+ ` * Activate ${config.name} — discovers current capabilities and returns adaptive context.`,
69
+ ' *',
70
+ ' * PERSONA is the birth config. The activation response reflects what the agent',
71
+ ' * has become through installed packs, captured knowledge, and identity updates.',
71
72
  ' */',
72
- 'export function activateAgent(vault: Vault, projectPath: string, planner?: Planner): ActivationResult {',
73
- ' // Check CLAUDE.md injection status (project-level and global)',
73
+ 'export function activateAgent(runtime: AgentRuntime, projectPath: string): ActivationResult {',
74
+ ' const { vault, planner, identityManager } = runtime;',
75
+ '',
76
+ ' // ─── Setup status ──────────────────────────────────────────',
74
77
  " const projectClaudeMd = join(projectPath, 'CLAUDE.md');",
75
78
  " const globalClaudeMd = join(homedir(), '.claude', 'CLAUDE.md');",
76
79
  ' const claudeMdInjected = hasAgentMarker(projectClaudeMd);',
77
80
  ' const globalClaudeMdInjected = hasAgentMarker(globalClaudeMd);',
78
81
  '',
79
- ' // Check vault status',
82
+ ' // ─── Vault stats — what the agent actually knows ──────────',
80
83
  ' const stats = vault.stats();',
81
84
  ' const vaultHasEntries = stats.totalEntries > 0;',
82
85
  '',
83
- " // Build next steps based on what's missing",
86
+ ' // ─── Discover domains ─────────────────────────────────────',
87
+ ` const configuredDomains: string[] = ${configDomains};`,
88
+ ' const vaultDomains = Object.keys(stats.byDomain);',
89
+ '',
90
+ ' // Merge configured + vault-discovered domains (dedup)',
91
+ ' const allDomains = [...new Set([...configuredDomains, ...vaultDomains])];',
92
+ '',
93
+ ' // Build capability map — entries per domain',
94
+ ' const capabilities = allDomains.map((d) => ({',
95
+ ' domain: d,',
96
+ ' entries: stats.byDomain[d] ?? 0,',
97
+ ' }));',
98
+ '',
99
+ ' // ─── Discover installed packs ─────────────────────────────',
100
+ ' const installedPacks: Array<{ id: string; type: string }> = [];',
101
+ ' try {',
102
+ " const lockPath = join(projectPath, 'soleri.lock');",
103
+ ' if (existsSync(lockPath)) {',
104
+ " const lockData = JSON.parse(readFileSync(lockPath, 'utf-8'));",
105
+ ' if (lockData.packs) {',
106
+ ' for (const [id, entry] of Object.entries(lockData.packs)) {',
107
+ ' installedPacks.push({ id, type: (entry as Record<string, string>).type ?? "unknown" });',
108
+ ' }',
109
+ ' }',
110
+ ' }',
111
+ ' } catch {',
112
+ ' // Lock file missing or corrupt — proceed without pack info',
113
+ ' }',
114
+ '',
115
+ ' // ─── Dynamic role — based on what the agent actually covers ─',
116
+ " const currentIdentity = identityManager.getIdentity('" + config.id + "');",
117
+ ' const newDomains = allDomains.filter((d) => !configuredDomains.includes(d));',
118
+ ' let currentRole = currentIdentity?.role ?? PERSONA.role;',
119
+ '',
120
+ ' // If the agent has grown beyond its birth domains, reflect that',
121
+ ' if (newDomains.length > 0) {',
122
+ ' const formatted = newDomains.map((d) => d.replace(/-/g, " ")).join(", ");',
123
+ ' currentRole = `${PERSONA.role} (also covering ${formatted})`;',
124
+ ' }',
125
+ '',
126
+ ' // ─── Dynamic greeting ─────────────────────────────────────',
127
+ " let greeting = `Hello! I'm ${PERSONA.name}.`;",
128
+ ' if (allDomains.length > configuredDomains.length) {',
129
+ " greeting += ` I started as a ${PERSONA.role} and have expanded to also cover ${newDomains.map((d) => d.replace(/-/g, ' ')).join(', ')}.`;",
130
+ ' } else {',
131
+ ' greeting += ` ${PERSONA.role} ready to help.`;',
132
+ ' }',
133
+ ' if (stats.totalEntries > 0) {',
134
+ ' const domainSummary = capabilities',
135
+ ' .filter((c) => c.entries > 0)',
136
+ ' .map((c) => `${c.entries} ${c.domain.replace(/-/g, " ")}`)',
137
+ ' .join(", ");',
138
+ ' greeting += ` Vault: ${stats.totalEntries} entries (${domainSummary}).`;',
139
+ ' }',
140
+ '',
141
+ ' // ─── Next steps ───────────────────────────────────────────',
84
142
  ' const nextSteps: string[] = [];',
85
143
  ' if (!globalClaudeMdInjected && !claudeMdInjected) {',
86
144
  ` nextSteps.push('No CLAUDE.md configured — run inject_claude_md with global: true for all projects, or without for this project only');`,
@@ -88,10 +146,7 @@ export function generateActivate(config: AgentConfig): string {
88
146
  ` nextSteps.push('Global CLAUDE.md not configured — run inject_claude_md with global: true to enable activation in all projects');`,
89
147
  ' }',
90
148
  ' if (!vaultHasEntries) {',
91
- " nextSteps.push('Vault is empty — start capturing knowledge with the domain capture ops');",
92
- ' }',
93
- ' if (nextSteps.length === 0) {',
94
- ` nextSteps.push('All set! ${config.name} is fully integrated.');`,
149
+ " nextSteps.push('Vault is empty — start capturing knowledge with the domain capture ops, or install a knowledge pack with soleri pack install');",
95
150
  ' }',
96
151
  '',
97
152
  ' // Check for executing plans',
@@ -105,25 +160,30 @@ export function generateActivate(config: AgentConfig): string {
105
160
  ' nextSteps.unshift(`${executingPlans.length} plan(s) in progress — use get_plan to review`);',
106
161
  ' }',
107
162
  '',
163
+ ' if (nextSteps.length === 0) {',
164
+ ` nextSteps.push('All set! ${config.name} is ready.');`,
165
+ ' }',
166
+ '',
108
167
  ' return {',
109
168
  ' activated: true,',
110
- ' persona: {',
169
+ ' origin: {',
111
170
  ' name: PERSONA.name,',
112
171
  ' role: PERSONA.role,',
113
172
  ' description: PERSONA.description,',
114
- ' greeting: PERSONA.greeting,',
173
+ ' },',
174
+ ' current: {',
175
+ ' role: currentRole,',
176
+ ' greeting,',
177
+ ' domains: allDomains,',
178
+ ' capabilities,',
179
+ ' installed_packs: installedPacks,',
115
180
  ' },',
116
181
  ' guidelines: [',
117
182
  guidelineLines,
118
183
  ' ],',
119
- ' tool_recommendations: [',
120
- ` { intent: 'health check', facade: '${toolPrefix}_core', op: 'health' },`,
121
- ` { intent: 'search all', facade: '${toolPrefix}_core', op: 'search' },`,
122
- ` { intent: 'vault stats', facade: '${toolPrefix}_core', op: 'vault_stats' },`,
123
- ...toolRecLines,
124
- ' ],',
125
- ` session_instruction: 'You are now ' + PERSONA.name + ', a ' + PERSONA.role + '. Stay in character for the ENTIRE session. ' +`,
126
- ` 'Reference patterns from the knowledge vault. Provide concrete examples. Flag anti-patterns with severity.',`,
184
+ " session_instruction: `You are ${PERSONA.name}. Your origin role is ${PERSONA.role}, but you have grown — your current capabilities span: ${allDomains.join(', ')}. ` +",
185
+ " 'Adapt your expertise to match your actual knowledge. ' +",
186
+ " 'Reference patterns from the knowledge vault. Provide concrete examples. Flag anti-patterns with severity.',",
127
187
  ' setup_status: {',
128
188
  ' claude_md_injected: claudeMdInjected,',
129
189
  ' global_claude_md_injected: globalClaudeMdInjected,',
@@ -139,7 +199,6 @@ export function generateActivate(config: AgentConfig): string {
139
199
  ` * Deactivate ${config.name} — drops persona and cleans up CLAUDE.md sections.`,
140
200
  ' */',
141
201
  'export function deactivateAgent(): DeactivationResult {',
142
- ' // Remove agent sections from global CLAUDE.md on deactivation',
143
202
  ' const globalResult = removeClaudeMdGlobal();',
144
203
  ' return {',
145
204
  ' deactivated: true,',
@@ -29,8 +29,8 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
29
29
  // ─── Identity ──────────────────────────────────────────
30
30
  `## ${config.name}`,
31
31
  '',
32
- `**Role:** ${config.role}`,
33
- `**Domains:** ${config.domains.join(', ')}`,
32
+ `**Origin role:** ${config.role}`,
33
+ `**Initial domains:** ${config.domains.join(', ')}`,
34
34
  `**Tone:** ${config.tone ?? 'pragmatic'}`,
35
35
  '',
36
36
  config.description,
@@ -39,13 +39,27 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
39
39
  ...config.principles.map((p) => `- ${p}`),
40
40
  '',
41
41
 
42
+ // ─── Adaptive Identity ──────────────────────────────────
43
+ '## Adaptive Identity',
44
+ '',
45
+ `${config.name} is not a fixed-role agent. The origin role above is a starting point — the agent evolves as knowledge is added.`,
46
+ '',
47
+ '**On activation**, the agent discovers its current capabilities by checking:',
48
+ '- Vault domains (what knowledge actually exists)',
49
+ '- Installed packs (what was added after creation)',
50
+ '- Identity updates (any role changes via `op:update_identity`)',
51
+ '',
52
+ '**Use the `current` field** from the activation response — not `origin` — to determine how to present yourself.',
53
+ 'If you have grown beyond your origin role, say so. Your greeting and expertise should reflect what you actually know.',
54
+ '',
55
+
42
56
  // ─── Activation ────────────────────────────────────────
43
57
  '## Activation',
44
58
  '',
45
59
  `**Activate:** "Hello, ${config.name}!" → ${bt}${toolPrefix}_core op:activate params:{ projectPath: "." }${bt}`,
46
60
  `**Deactivate:** "Goodbye, ${config.name}!" → ${bt}${toolPrefix}_core op:activate params:{ deactivate: true }${bt}`,
47
61
  '',
48
- 'On activation, adopt the returned persona. Stay in character until deactivated.',
62
+ 'On activation, read the `current` field to discover your evolved role, then adopt that persona for the session.',
49
63
  '',
50
64
 
51
65
  // ─── Session Start ─────────────────────────────────────
@@ -102,7 +102,7 @@ async function main(): Promise<void> {
102
102
  changeReason: 'Initial identity seeded from PERSONA',
103
103
  });
104
104
  }
105
- return activateAgent(runtime.vault, (params.projectPath as string) ?? '.', runtime.planner);
105
+ return activateAgent(runtime, (params.projectPath as string) ?? '.');
106
106
  },
107
107
  },
108
108
  {