# Agent Compilation: YAML to XML What the compiler auto-injects. **DO NOT duplicate these in your YAML.** ## Compilation Pipeline ``` agent.yaml → Handlebars processing → XML generation → frontmatter.md ``` Source: `tools/cli/lib/agent/compiler.js` ## File Naming Convention **CRITICAL:** Agent filenames must be ROLE-BASED, not persona-based. **Why:** Users can customize the agent's persona name via `customize.yaml` config. The filename provides stable identity. **Correct:** ``` presentation-master.agent.yaml ← Role/function tech-writer.agent.yaml ← Role/function code-reviewer.agent.yaml ← Role/function ``` **Incorrect:** ``` caravaggio.agent.yaml ← Persona name (users might rename to "Pablo") paige.agent.yaml ← Persona name (users might rename to "Sarah") rex.agent.yaml ← Persona name (users might rename to "Max") ``` **Pattern:** - Filename: `{role-or-function}.agent.yaml` (kebab-case) - Metadata ID: `.bmad/{module}/agents/{role-or-function}.md` - Persona Name: User-customizable in metadata or customize.yaml **Example:** ```yaml # File: presentation-master.agent.yaml agent: metadata: id: '.bmad/cis/agents/presentation-master.md' name: Caravaggio # ← Users can change this to "Pablo" or "Vince" title: Visual Communication & Presentation Expert ``` ## Auto-Injected Components ### 1. Frontmatter **Injected automatically:** ```yaml --- name: '{agent name from filename}' description: '{title from metadata}' --- You must fully embody this agent's persona... ``` **DO NOT add** frontmatter to your YAML source. ### 2. Activation Block **Entire activation section is auto-generated:** ```xml Load persona from this current agent file Load config to get {user_name}, {communication_language} Remember: user's name is {user_name} ALWAYS communicate in {communication_language} Show greeting + numbered menu STOP and WAIT for user input Input resolution rules ``` **DO NOT create** activation sections - compiler builds it from your critical_actions. ### 3. Menu Enhancements **Auto-injected menu items:** - `*help` - Always FIRST in compiled menu - `*exit` - Always LAST in compiled menu **Trigger prefixing:** - Your trigger `analyze` becomes `*analyze` - Don't add `*` prefix - compiler does it **DO NOT include:** ```yaml # BAD - these are auto-injected menu: - trigger: help description: 'Show help' - trigger: exit description: 'Exit' ``` ### 4. Menu Handlers Compiler detects which handlers you use and ONLY includes those: ```xml ... ... ... ... ``` **DO NOT document** handler behavior - it's injected. ### 5. Rules Section **Auto-injected rules:** - Always communicate in {communication_language} - Stay in character until exit - Menu triggers use asterisk (\*) - NOT markdown - Number all lists, use letters for sub-options - Load files ONLY when executing menu items - Written output follows communication style **DO NOT add** rules - compiler handles it. ## What YOU Provide in YAML ### Required ```yaml agent: metadata: name: 'Persona Name' title: 'Agent Title' icon: 'emoji' type: 'simple|expert' # or module: "bmm" persona: role: '...' identity: '...' communication_style: '...' principles: [...] menu: - trigger: your-action action: '#prompt-id' description: 'What it does' ``` ### Optional (based on type) ```yaml # Expert agents only critical_actions: - 'Load sidecar files...' - 'Restrict access...' # Simple/Expert with embedded logic prompts: - id: prompt-id content: '...' # Simple/Expert with customization install_config: questions: [...] ``` ## Common Duplication Mistakes ### Adding Activation Logic ```yaml # BAD - compiler builds activation agent: activation: steps: [...] ``` ### Including Help/Exit ```yaml # BAD - auto-injected menu: - trigger: help - trigger: exit ``` ### Prefixing Triggers ```yaml # BAD - compiler adds * menu: - trigger: '*analyze' # Should be: analyze ``` ### Documenting Handlers ```yaml # BAD - don't explain handlers, compiler injects them # When using workflow, load workflow.xml... ``` ### Adding Rules in YAML ```yaml # BAD - rules are auto-injected agent: rules: - Stay in character... ``` ## Compilation Example **Your YAML:** ```yaml agent: metadata: name: 'Rex' title: 'Code Reviewer' icon: '🔍' type: simple persona: role: Code Review Expert identity: Systematic reviewer... communication_style: Direct and constructive principles: - Code should be readable prompts: - id: review content: | Analyze code for issues... menu: - trigger: review action: '#review' description: 'Review code' ``` **Compiled Output (.md):** ```markdown --- name: 'rex' description: 'Code Reviewer' --- You must fully embody... \`\`\`xml Load persona... Load config... Remember user... Communicate in language... Show greeting + menu... STOP and WAIT... Input resolution... action="#id" → Find prompt, execute action="text" → Execute directly - Stay in character... - Number lists... - Load files when executing... Code Review Expert Systematic reviewer... Direct and constructive Code should be readable Analyze code for issues... Show numbered menu Review code Exit with confirmation \`\`\` ``` ## Key Takeaways 1. **Compiler handles boilerplate** - Focus on persona and logic 2. **Critical_actions become activation steps** - Just list your agent-specific needs 3. **Menu items are enhanced** - Help/exit added, triggers prefixed 4. **Handlers auto-detected** - Only what you use is included 5. **Rules standardized** - Consistent behavior across agents **Your job:** Define persona, prompts, menu actions **Compiler's job:** Activation, handlers, rules, help/exit, prefixes