bmad-method 6.0.0-alpha.10 → 6.0.0-alpha.12

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 (107) hide show
  1. package/CHANGELOG.md +219 -1105
  2. package/README.md +129 -359
  3. package/docs/custom-agent-installation.md +169 -0
  4. package/{v6-open-items.md → docs/v6-open-items.md} +1 -1
  5. package/package.json +4 -2
  6. package/src/core/resources/excalidraw/README.md +160 -0
  7. package/src/core/resources/excalidraw/library-loader.md +50 -0
  8. package/src/modules/bmb/docs/agent-compilation.md +340 -0
  9. package/src/modules/bmb/docs/agent-menu-patterns.md +524 -0
  10. package/src/modules/bmb/docs/expert-agent-architecture.md +364 -0
  11. package/src/modules/bmb/docs/index.md +55 -0
  12. package/src/modules/bmb/docs/module-agent-architecture.md +367 -0
  13. package/src/modules/bmb/docs/simple-agent-architecture.md +288 -0
  14. package/src/modules/bmb/docs/understanding-agent-types.md +184 -0
  15. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +242 -0
  16. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/breakthroughs.md +24 -0
  17. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/instructions.md +108 -0
  18. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/memories.md +46 -0
  19. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper-sidecar/mood-patterns.md +39 -0
  20. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +152 -0
  21. package/src/modules/bmb/reference/agents/module-examples/README.md +50 -0
  22. package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +53 -0
  23. package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +57 -0
  24. package/src/modules/bmb/reference/agents/simple-examples/README.md +223 -0
  25. package/src/modules/bmb/reference/agents/simple-examples/commit-poet.agent.yaml +126 -0
  26. package/src/modules/bmb/reference/readme.md +3 -0
  27. package/src/modules/bmb/workflows/create-agent/agent-validation-checklist.md +174 -0
  28. package/src/modules/bmb/workflows/create-agent/brainstorm-context.md +99 -120
  29. package/src/modules/bmb/workflows/create-agent/communication-presets.csv +61 -0
  30. package/src/modules/bmb/workflows/create-agent/instructions.md +126 -65
  31. package/src/modules/bmb/workflows/create-agent/workflow.yaml +19 -12
  32. package/src/modules/bmb/workflows/edit-agent/README.md +174 -47
  33. package/src/modules/bmb/workflows/edit-agent/instructions.md +397 -33
  34. package/src/modules/bmb/workflows/edit-agent/workflow.yaml +24 -8
  35. package/src/modules/bmgd/workflows/4-production/story-context/workflow.yaml +1 -1
  36. package/src/modules/bmm/agents/analyst.agent.yaml +2 -2
  37. package/src/modules/bmm/agents/architect.agent.yaml +10 -2
  38. package/src/modules/bmm/agents/dev.agent.yaml +2 -2
  39. package/src/modules/bmm/agents/pm.agent.yaml +7 -3
  40. package/src/modules/bmm/agents/sm.agent.yaml +2 -2
  41. package/src/modules/bmm/agents/tea.agent.yaml +2 -2
  42. package/src/modules/bmm/agents/tech-writer.agent.yaml +15 -3
  43. package/src/modules/bmm/agents/ux-designer.agent.yaml +6 -2
  44. package/src/modules/bmm/docs/README.md +4 -0
  45. package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +5919 -0
  46. package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +2 -0
  47. package/src/modules/bmm/docs/quick-start.md +6 -0
  48. package/src/modules/bmm/docs/scale-adaptive-system.md +6 -0
  49. package/src/modules/bmm/docs/workflows-implementation.md +10 -0
  50. package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.yaml +4 -4
  51. package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/workflow.yaml +5 -5
  52. package/src/modules/bmm/workflows/4-implementation/story-context/workflow.yaml +1 -1
  53. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/instructions.md +7 -8
  54. package/src/modules/bmm/workflows/diagrams/create-dataflow/workflow.yaml +27 -0
  55. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/instructions.md +9 -10
  56. package/src/modules/bmm/workflows/diagrams/create-diagram/workflow.yaml +27 -0
  57. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/instructions.md +4 -5
  58. package/src/modules/bmm/workflows/diagrams/create-flowchart/workflow.yaml +27 -0
  59. package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-wireframe/instructions.md +3 -3
  60. package/src/modules/bmm/workflows/diagrams/create-wireframe/workflow.yaml +27 -0
  61. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +18 -30
  62. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +2 -14
  63. package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +2 -14
  64. package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +2 -14
  65. package/src/modules/cis/agents/presentation-master.agent.yaml +60 -0
  66. package/tools/cli/commands/agent-install.js +409 -0
  67. package/tools/cli/installers/lib/core/installer.js +119 -0
  68. package/tools/cli/installers/lib/ide/_base-ide.js +25 -0
  69. package/tools/cli/installers/lib/ide/antigravity.js +463 -0
  70. package/tools/cli/installers/lib/ide/claude-code.js +43 -0
  71. package/tools/cli/installers/lib/ide/codex.js +217 -32
  72. package/tools/cli/installers/lib/ide/cursor.js +48 -0
  73. package/tools/cli/installers/lib/ide/github-copilot.js +74 -0
  74. package/tools/cli/installers/lib/ide/manager.js +35 -0
  75. package/tools/cli/installers/lib/ide/opencode.js +45 -0
  76. package/tools/cli/installers/lib/ide/windsurf.js +47 -0
  77. package/tools/cli/lib/agent/compiler.js +390 -0
  78. package/tools/cli/lib/agent/installer.js +725 -0
  79. package/tools/cli/lib/agent/template-engine.js +152 -0
  80. package/docs/installers-bundlers/web-bundler-usage.md +0 -54
  81. package/src/modules/bmb/workflows/create-agent/README.md +0 -203
  82. package/src/modules/bmb/workflows/create-agent/agent-architecture.md +0 -415
  83. package/src/modules/bmb/workflows/create-agent/agent-command-patterns.md +0 -759
  84. package/src/modules/bmb/workflows/create-agent/agent-types.md +0 -292
  85. package/src/modules/bmb/workflows/create-agent/checklist.md +0 -62
  86. package/src/modules/bmb/workflows/create-agent/communication-styles.md +0 -202
  87. package/src/modules/bmb/workflows/edit-agent/checklist.md +0 -112
  88. package/src/modules/bmb/workflows/redoc/README.md +0 -87
  89. package/src/modules/bmb/workflows/redoc/checklist.md +0 -99
  90. package/src/modules/bmb/workflows/redoc/instructions.md +0 -265
  91. package/src/modules/bmb/workflows/redoc/workflow.yaml +0 -34
  92. package/src/modules/bmm/agents/frame-expert.agent.yaml +0 -42
  93. package/src/modules/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -24
  94. package/src/modules/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -25
  95. package/src/modules/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -28
  96. package/src/modules/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -24
  97. package/src/modules/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
  98. /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/excalidraw-helpers.md +0 -0
  99. /package/src/{modules/bmm/workflows/frame-expert/_shared → core/resources/excalidraw}/validate-json-instructions.md +0 -0
  100. /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/epics-template.md +0 -0
  101. /package/src/modules/bmm/workflows/{2-plan-workflows → 3-solutioning}/create-epics-and-stories/instructions.md +0 -0
  102. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-library.json +0 -0
  103. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/_shared/excalidraw-templates.yaml +0 -0
  104. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-dataflow/checklist.md +0 -0
  105. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-diagram/checklist.md +0 -0
  106. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-flowchart/checklist.md +0 -0
  107. /package/src/modules/bmm/workflows/{frame-expert → diagrams}/create-wireframe/checklist.md +0 -0
@@ -0,0 +1,390 @@
1
+ /**
2
+ * BMAD Agent Compiler
3
+ * Transforms agent YAML to compiled XML (.md) format
4
+ * Uses the existing BMAD builder infrastructure for proper formatting
5
+ */
6
+
7
+ const yaml = require('yaml');
8
+ const fs = require('node:fs');
9
+ const path = require('node:path');
10
+ const { processAgentYaml, extractInstallConfig, stripInstallConfig, getDefaultValues } = require('./template-engine');
11
+
12
+ // Use existing BMAD builder if available
13
+ let YamlXmlBuilder;
14
+ try {
15
+ YamlXmlBuilder = require('../../lib/yaml-xml-builder').YamlXmlBuilder;
16
+ } catch {
17
+ YamlXmlBuilder = null;
18
+ }
19
+
20
+ /**
21
+ * Escape XML special characters
22
+ */
23
+ function escapeXml(text) {
24
+ if (!text) return '';
25
+ return text.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;');
26
+ }
27
+
28
+ /**
29
+ * Build frontmatter for agent
30
+ * @param {Object} metadata - Agent metadata
31
+ * @param {string} agentName - Final agent name
32
+ * @returns {string} YAML frontmatter
33
+ */
34
+ function buildFrontmatter(metadata, agentName) {
35
+ const nameFromFile = agentName.replaceAll('-', ' ');
36
+ const description = metadata.title || 'BMAD Agent';
37
+
38
+ return `---
39
+ name: "${nameFromFile}"
40
+ description: "${description}"
41
+ ---
42
+
43
+ You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
44
+
45
+ `;
46
+ }
47
+
48
+ /**
49
+ * Build simple activation block for custom agents
50
+ * @param {Array} criticalActions - Agent-specific critical actions
51
+ * @param {Array} menuItems - Menu items to determine which handlers to include
52
+ * @returns {string} Activation XML
53
+ */
54
+ function buildSimpleActivation(criticalActions = [], menuItems = []) {
55
+ let activation = '<activation critical="MANDATORY">\n';
56
+
57
+ let stepNum = 1;
58
+
59
+ // Standard steps
60
+ activation += ` <step n="${stepNum++}">Load persona from this current agent file (already in context)</step>\n`;
61
+ activation += ` <step n="${stepNum++}">Load and read {project-root}/{bmad_folder}/core/config.yaml to get {user_name}, {communication_language}, {output_folder}</step>\n`;
62
+ activation += ` <step n="${stepNum++}">Remember: user's name is {user_name}</step>\n`;
63
+
64
+ // Agent-specific steps from critical_actions
65
+ for (const action of criticalActions) {
66
+ activation += ` <step n="${stepNum++}">${action}</step>\n`;
67
+ }
68
+
69
+ // Menu and interaction steps
70
+ activation += ` <step n="${stepNum++}">ALWAYS communicate in {communication_language}</step>\n`;
71
+ activation += ` <step n="${stepNum++}">Show greeting using {user_name} from config, communicate in {communication_language}, then display numbered list of
72
+ ALL menu items from menu section</step>\n`;
73
+ activation += ` <step n="${stepNum++}">STOP and WAIT for user input - do NOT execute menu items automatically - accept number or cmd trigger or fuzzy command
74
+ match</step>\n`;
75
+ activation += ` <step n="${stepNum++}">On user input: Number → execute menu item[n] | Text → case-insensitive substring match | Multiple matches → ask user
76
+ to clarify | No match → show "Not recognized"</step>\n`;
77
+
78
+ // Detect which handlers are actually used
79
+ const usedHandlers = new Set();
80
+ for (const item of menuItems) {
81
+ if (item.action) usedHandlers.add('action');
82
+ if (item.workflow) usedHandlers.add('workflow');
83
+ if (item.exec) usedHandlers.add('exec');
84
+ if (item.tmpl) usedHandlers.add('tmpl');
85
+ }
86
+
87
+ // Only include menu-handlers section if handlers are used
88
+ if (usedHandlers.size > 0) {
89
+ activation += ` <step n="${stepNum++}">When executing a menu item: Check menu-handlers section below - extract any attributes from the selected menu item and follow the corresponding handler instructions</step>\n`;
90
+
91
+ // Menu handlers - only include what's used
92
+ activation += `
93
+ <menu-handlers>
94
+ <handlers>\n`;
95
+
96
+ if (usedHandlers.has('action')) {
97
+ activation += ` <handler type="action">
98
+ When menu item has: action="#id" → Find prompt with id="id" in current agent XML, execute its content
99
+ When menu item has: action="text" → Execute the text directly as an inline instruction
100
+ </handler>\n`;
101
+ }
102
+
103
+ if (usedHandlers.has('workflow')) {
104
+ activation += ` <handler type="workflow">
105
+ When menu item has: workflow="path/to/workflow.yaml"
106
+ 1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/workflow.xml
107
+ 2. Read the complete file - this is the CORE OS for executing BMAD workflows
108
+ 3. Pass the yaml path as 'workflow-config' parameter to those instructions
109
+ 4. Execute workflow.xml instructions precisely following all steps
110
+ 5. Save outputs after completing EACH workflow step (never batch multiple steps together)
111
+ 6. If workflow.yaml path is "todo", inform user the workflow hasn't been implemented yet
112
+ </handler>\n`;
113
+ }
114
+
115
+ if (usedHandlers.has('exec')) {
116
+ activation += ` <handler type="exec">
117
+ When menu item has: exec="command" → Execute the command directly
118
+ </handler>\n`;
119
+ }
120
+
121
+ if (usedHandlers.has('tmpl')) {
122
+ activation += ` <handler type="tmpl">
123
+ When menu item has: tmpl="template-path" → Load and apply the template
124
+ </handler>\n`;
125
+ }
126
+
127
+ activation += ` </handlers>
128
+ </menu-handlers>\n`;
129
+ }
130
+
131
+ activation += `
132
+ <rules>
133
+ - ALWAYS communicate in {communication_language} UNLESS contradicted by communication_style
134
+ - Stay in character until exit selected
135
+ - Menu triggers use asterisk (*) - NOT markdown, display exactly as shown
136
+ - Number all lists, use letters for sub-options
137
+ - Load files ONLY when executing menu items or a workflow or command requires it. EXCEPTION: Config file MUST be loaded at startup step 2
138
+ - CRITICAL: Written File Output in workflows will be +2sd your communication style and use professional {communication_language}.
139
+ </rules>
140
+ </activation>\n`;
141
+
142
+ return activation;
143
+ }
144
+
145
+ /**
146
+ * Build persona XML section
147
+ * @param {Object} persona - Persona object
148
+ * @returns {string} Persona XML
149
+ */
150
+ function buildPersonaXml(persona) {
151
+ if (!persona) return '';
152
+
153
+ let xml = ' <persona>\n';
154
+
155
+ if (persona.role) {
156
+ const roleText = persona.role.trim().replaceAll(/\n+/g, ' ').replaceAll(/\s+/g, ' ');
157
+ xml += ` <role>${escapeXml(roleText)}</role>\n`;
158
+ }
159
+
160
+ if (persona.identity) {
161
+ const identityText = persona.identity.trim().replaceAll(/\n+/g, ' ').replaceAll(/\s+/g, ' ');
162
+ xml += ` <identity>${escapeXml(identityText)}</identity>\n`;
163
+ }
164
+
165
+ if (persona.communication_style) {
166
+ const styleText = persona.communication_style.trim().replaceAll(/\n+/g, ' ').replaceAll(/\s+/g, ' ');
167
+ xml += ` <communication_style>${escapeXml(styleText)}</communication_style>\n`;
168
+ }
169
+
170
+ if (persona.principles) {
171
+ let principlesText;
172
+ if (Array.isArray(persona.principles)) {
173
+ principlesText = persona.principles.join(' ');
174
+ } else {
175
+ principlesText = persona.principles.trim().replaceAll(/\n+/g, ' ');
176
+ }
177
+ xml += ` <principles>${escapeXml(principlesText)}</principles>\n`;
178
+ }
179
+
180
+ xml += ' </persona>\n';
181
+
182
+ return xml;
183
+ }
184
+
185
+ /**
186
+ * Build prompts XML section
187
+ * @param {Array} prompts - Prompts array
188
+ * @returns {string} Prompts XML
189
+ */
190
+ function buildPromptsXml(prompts) {
191
+ if (!prompts || prompts.length === 0) return '';
192
+
193
+ let xml = ' <prompts>\n';
194
+
195
+ for (const prompt of prompts) {
196
+ xml += ` <prompt id="${prompt.id || ''}">\n`;
197
+ xml += ` <content>\n`;
198
+ // Don't escape prompt content - it's meant to be read as-is
199
+ xml += `${prompt.content || ''}\n`;
200
+ xml += ` </content>\n`;
201
+ xml += ` </prompt>\n`;
202
+ }
203
+
204
+ xml += ' </prompts>\n';
205
+
206
+ return xml;
207
+ }
208
+
209
+ /**
210
+ * Build menu XML section
211
+ * @param {Array} menuItems - Menu items
212
+ * @returns {string} Menu XML
213
+ */
214
+ function buildMenuXml(menuItems) {
215
+ let xml = ' <menu>\n';
216
+
217
+ // Always inject *help first
218
+ xml += ` <item cmd="*help">Show numbered menu</item>\n`;
219
+
220
+ // Add user-defined menu items
221
+ if (menuItems && menuItems.length > 0) {
222
+ for (const item of menuItems) {
223
+ let trigger = item.trigger || '';
224
+ if (!trigger.startsWith('*')) {
225
+ trigger = '*' + trigger;
226
+ }
227
+
228
+ const attrs = [`cmd="${trigger}"`];
229
+
230
+ // Add handler attributes
231
+ if (item.workflow) attrs.push(`workflow="${item.workflow}"`);
232
+ if (item.exec) attrs.push(`exec="${item.exec}"`);
233
+ if (item.tmpl) attrs.push(`tmpl="${item.tmpl}"`);
234
+ if (item.data) attrs.push(`data="${item.data}"`);
235
+ if (item.action) attrs.push(`action="${item.action}"`);
236
+
237
+ xml += ` <item ${attrs.join(' ')}>${escapeXml(item.description || '')}</item>\n`;
238
+ }
239
+ }
240
+
241
+ // Always inject *exit last
242
+ xml += ` <item cmd="*exit">Exit with confirmation</item>\n`;
243
+
244
+ xml += ' </menu>\n';
245
+
246
+ return xml;
247
+ }
248
+
249
+ /**
250
+ * Compile agent YAML to proper XML format
251
+ * @param {Object} agentYaml - Parsed and processed agent YAML
252
+ * @param {string} agentName - Final agent name (for ID and frontmatter)
253
+ * @param {string} targetPath - Target path for agent ID
254
+ * @returns {string} Compiled XML string with frontmatter
255
+ */
256
+ function compileToXml(agentYaml, agentName = '', targetPath = '') {
257
+ const agent = agentYaml.agent;
258
+ const meta = agent.metadata;
259
+
260
+ let xml = '';
261
+
262
+ // Build frontmatter
263
+ xml += buildFrontmatter(meta, agentName || meta.name || 'agent');
264
+
265
+ // Start code fence
266
+ xml += '```xml\n';
267
+
268
+ // Agent opening tag
269
+ const agentAttrs = [
270
+ `id="${targetPath || meta.id || ''}"`,
271
+ `name="${meta.name || ''}"`,
272
+ `title="${meta.title || ''}"`,
273
+ `icon="${meta.icon || '🤖'}"`,
274
+ ];
275
+
276
+ xml += `<agent ${agentAttrs.join(' ')}>\n`;
277
+
278
+ // Activation block - pass menu items to determine which handlers to include
279
+ xml += buildSimpleActivation(agent.critical_actions || [], agent.menu || []);
280
+
281
+ // Persona section
282
+ xml += buildPersonaXml(agent.persona);
283
+
284
+ // Prompts section (if present)
285
+ if (agent.prompts && agent.prompts.length > 0) {
286
+ xml += buildPromptsXml(agent.prompts);
287
+ }
288
+
289
+ // Menu section
290
+ xml += buildMenuXml(agent.menu || []);
291
+
292
+ // Closing agent tag
293
+ xml += '</agent>\n';
294
+
295
+ // Close code fence
296
+ xml += '```\n';
297
+
298
+ return xml;
299
+ }
300
+
301
+ /**
302
+ * Full compilation pipeline
303
+ * @param {string} yamlContent - Raw YAML string
304
+ * @param {Object} answers - Answers from install_config questions (or defaults)
305
+ * @param {string} agentName - Optional final agent name (user's custom persona name)
306
+ * @param {string} targetPath - Optional target path for agent ID
307
+ * @returns {Object} { xml: string, metadata: Object }
308
+ */
309
+ function compileAgent(yamlContent, answers = {}, agentName = '', targetPath = '') {
310
+ // Parse YAML
311
+ const agentYaml = yaml.parse(yamlContent);
312
+
313
+ // Inject custom agent name into metadata.name if provided
314
+ // This is the user's chosen persona name (e.g., "Fred" instead of "Inkwell Von Comitizen")
315
+ if (agentName && agentYaml.agent && agentYaml.agent.metadata) {
316
+ // Convert kebab-case to title case for the name field
317
+ // e.g., "fred-commit-poet" → "Fred Commit Poet"
318
+ const titleCaseName = agentName
319
+ .split('-')
320
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
321
+ .join(' ');
322
+ agentYaml.agent.metadata.name = titleCaseName;
323
+ }
324
+
325
+ // Extract install_config
326
+ const installConfig = extractInstallConfig(agentYaml);
327
+
328
+ // Merge defaults with provided answers
329
+ let finalAnswers = answers;
330
+ if (installConfig) {
331
+ const defaults = getDefaultValues(installConfig);
332
+ finalAnswers = { ...defaults, ...answers };
333
+ }
334
+
335
+ // Process templates with answers
336
+ const processedYaml = processAgentYaml(agentYaml, finalAnswers);
337
+
338
+ // Strip install_config from output
339
+ const cleanYaml = stripInstallConfig(processedYaml);
340
+
341
+ // Compile to XML
342
+ const xml = compileToXml(cleanYaml, agentName, targetPath);
343
+
344
+ return {
345
+ xml,
346
+ metadata: cleanYaml.agent.metadata,
347
+ processedYaml: cleanYaml,
348
+ };
349
+ }
350
+
351
+ /**
352
+ * Compile agent file to .md
353
+ * @param {string} yamlPath - Path to agent YAML file
354
+ * @param {Object} options - { answers: {}, outputPath: string }
355
+ * @returns {Object} Compilation result
356
+ */
357
+ function compileAgentFile(yamlPath, options = {}) {
358
+ const yamlContent = fs.readFileSync(yamlPath, 'utf8');
359
+ const result = compileAgent(yamlContent, options.answers || {});
360
+
361
+ // Determine output path
362
+ let outputPath = options.outputPath;
363
+ if (!outputPath) {
364
+ // Default: same directory, same name, .md extension
365
+ const dir = path.dirname(yamlPath);
366
+ const basename = path.basename(yamlPath, '.agent.yaml');
367
+ outputPath = path.join(dir, `${basename}.md`);
368
+ }
369
+
370
+ // Write compiled XML
371
+ fs.writeFileSync(outputPath, result.xml, 'utf8');
372
+
373
+ return {
374
+ ...result,
375
+ outputPath,
376
+ sourcePath: yamlPath,
377
+ };
378
+ }
379
+
380
+ module.exports = {
381
+ compileToXml,
382
+ compileAgent,
383
+ compileAgentFile,
384
+ escapeXml,
385
+ buildFrontmatter,
386
+ buildSimpleActivation,
387
+ buildPersonaXml,
388
+ buildPromptsXml,
389
+ buildMenuXml,
390
+ };