remove uneeded files

This commit is contained in:
Brian Madison
2025-10-03 11:54:32 -05:00
parent 3f40ef4756
commit fd01ad69f8
7 changed files with 292 additions and 326 deletions

View File

@@ -2,7 +2,7 @@
## Overview
The Build Agent workflow is an interactive agent builder that guides you through creating BMAD Core compliant agents with proper persona, activation rules, and command structure. It supports three agent types: Simple (self-contained), Expert (with sidecar resources), and Module (full-featured with workflows).
The Build Agent workflow is an interactive agent builder that guides you through creating BMAD Core compliant agents as YAML source files that compile to final `.md` during install. It supports three agent types: Simple (self-contained), Expert (with sidecar resources), and Module (full-featured with workflows).
## Key Features
@@ -10,8 +10,8 @@ The Build Agent workflow is an interactive agent builder that guides you through
- **Three Agent Types**: Simple, Expert, and Module agents with appropriate structures
- **Persona Development**: Guided creation of role, identity, communication style, and principles
- **Command Builder**: Interactive command definition with workflow/task/action patterns
- **Validation Built-In**: Ensures XML structure and BMAD Core compliance
- **Config File Support**: Optional agent config for persona overrides
- **Validation Built-In**: Ensures YAML structure and BMAD Core compliance
- **Customize Support**: Optional `customize.yaml` for persona/menu overrides and critical actions
- **Sidecar Resources**: Setup for Expert agents with domain-specific data
## Usage
@@ -94,49 +94,47 @@ create-agent/
### Phase 4: Finalization (Steps 5-10)
- Add custom activation rules (optional, rarely needed)
- Generate complete agent.md file
- Create agent config file (optional)
- Confirm activation behavior (mostly automatic)
- Generate `.agent.yaml` file
- Optionally create a customize file for overrides
- Setup sidecar resources (for Expert agents)
- Validate agent structure
- Validate YAML and compile to `.md`
- Provide usage instructions
## Output
### Generated Agent File
### Generated Files
Creates agent file at:
`{output_folder}/agents/{{agent_filename}}.md`
- YAML agent saved at:
`{output_folder}/agents/{{agent_filename}}.agent.yaml` (or `src/modules/{{target_module}}/agents/{{agent_filename}}.agent.yaml` if `src_impact=true`)
- Compiled `.md` generated by installer at:
`{project-root}/bmad/{{module}}/agents/{{agent_filename}}.md`
### Agent Structure
### YAML Agent Structure (simplified)
```xml
<!-- Powered by BMAD-CORE™ -->
# {{agent_title}}
<agent id="bmad/{{module}}/agents/{{agent_filename}}.md"
name="{{agent_name}}"
title="{{agent_title}}"
icon="{{agent_icon}}">
<persona>
<role>...</role>
<identity>...</identity>
<communication_style>...</communication_style>
<principles>...</principles>
</persona>
<cmds>
<c cmd="*help">...</c>
<c cmd="*exit">...</c>
<!-- Additional commands -->
</cmds>
</agent>
```yaml
agent:
metadata:
id: bmad/{{module}}/agents/{{agent_filename}}.md
name: { { agent_name } }
title: { { agent_title } }
icon: { { agent_icon } }
module: { { module } }
persona:
role: '...'
identity: '...'
communication_style: '...'
principles: ['...', '...']
menu:
- trigger: example
workflow: '{project-root}/path/to/workflow.yaml'
description: Do the thing
```
### Optional Config File
### Optional Customize File
If created, generates at:
`{project-root}/bmad/_cfg/agents/{{agent_config_name}}.md`
`{project-root}/bmad/_cfg/agents/{{module}}-{{agent_filename}}.customize.yaml`
## Requirements
@@ -194,10 +192,10 @@ Users can go from **vague idea → brainstormed concept → built agent** in one
### After Completion
1. Test the agent by loading it
2. Verify all commands work as expected
1. Compile agents: `npm run install:bmad` → "Compile Agents"
2. Test the compiled `.md` agent in your IDE
3. Implement any "todo" workflows
4. Refine persona based on usage
4. Refine persona based on usage or via customize file
5. Add more commands as agent evolves
## Agent Types

View File

@@ -1,123 +1,51 @@
# Build Agent Validation Checklist
# Build Agent Validation Checklist (YAML Agents)
## Agent Structure Validation
### XML Structure
### YAML Structure
- [ ] Valid XML syntax with proper opening and closing tags
- [ ] Agent tag has required attributes: id, name, title, icon
- [ ] All XML tags properly nested and closed
- [ ] No duplicate attribute names within same element
- [ ] YAML parses without errors
- [ ] `agent.metadata` includes: `id`, `name`, `title`, `icon`, `module`
- [ ] `agent.persona` exists with role, identity, communication_style, and principles
- [ ] `agent.menu` exists with at least one item
### Core Components
- [ ] `<!-- Powered by BMAD-CORE™ -->` header present at top of file
- [ ] Title section with agent name exists after header
- [ ] Main `<agent>` wrapper element present
- [ ] `<persona>` section exists and is not empty
- [ ] `<cmds>` section exists with at least 2 commands
- [ ] `metadata.id` points to final compiled path: `bmad/{{module}}/agents/{{agent}}.md`
- [ ] `metadata.module` matches the module folder (e.g., `bmm`, `bmb`, `cis`)
- [ ] Principles are an array (preferred) or string with clear values
## Persona Completeness
### Required Persona Elements
- [ ] Role clearly defines primary expertise area (12 lines)
- [ ] Identity includes relevant background and strengths (35 lines)
- [ ] Communication style gives concrete guidance (35 lines)
- [ ] Principles present and meaningful (no placeholders)
- [ ] `<role>` tag present with 1-2 line description of agent's professional role
- [ ] `<identity>` tag present with 3-5 lines describing background and expertise
- [ ] `<communication_style>` tag present with 3-5 lines describing interaction approach
- [ ] `<principles>` tag present with 5-8 lines of core beliefs and methodology
## Menu Validation
### Persona Quality
- [ ] Triggers do not start with `*` (auto-prefixed during build)
- [ ] Each item has a `description`
- [ ] Handlers use valid attributes (`workflow`, `exec`, `tmpl`, `data`, `action`)
- [ ] Paths use `{project-root}` or valid variables
- [ ] No duplicate triggers
- [ ] Role clearly defines primary expertise area
- [ ] Identity includes relevant experience indicators
- [ ] Communication style describes how agent interacts with users
- [ ] Principles start with "I believe" or "I operate" or similar first-person statement
- [ ] No placeholder text like "TODO" or "FILL THIS IN" remains
## Optional Sections
## Command Structure
- [ ] `prompts` defined when using `action: "#id"`
- [ ] `critical_actions` present if custom activation steps are needed
- [ ] Customize file (if created) located at `{project-root}/bmad/_cfg/agents/{{module}}-{{agent}}.customize.yaml`
### Required Commands
## Build Verification
- [ ] `*help` command present to show command list
- [ ] `*exit` command present to exit agent persona
- [ ] All commands start with asterisk (\*) prefix
- [ ] Each command has descriptive text explaining its purpose
- [ ] Run compile to build `.md`: `npm run install:bmad` → "Compile Agents" (or `bmad install` → Compile)
- [ ] Confirm compiled file exists at `{project-root}/bmad/{{module}}/agents/{{agent}}.md`
### Command Validation
## Final Quality
- [ ] No duplicate command triggers (each cmd attribute is unique)
- [ ] Commands are properly formatted as `<c cmd="*trigger">Description</c>`
- [ ] For workflow commands: `run-workflow` attribute has valid path or "todo"
- [ ] For task commands: `exec` attribute has valid path
- [ ] No malformed command attributes
## Agent Type Specific
### Simple Agent
- [ ] Self-contained with no external workflow dependencies OR marked as "todo"
- [ ] Any embedded data properly structured
- [ ] Logic description clear if embedded functionality exists
### Expert Agent
- [ ] Sidecar resources clearly defined if applicable
- [ ] Domain restrictions documented in critical-actions or sidecar-resources
- [ ] Memory/knowledge file paths specified if used
- [ ] Access patterns (read/write) defined for resources
### Module Agent
- [ ] Module path correctly references existing module (bmm/bmb/cis or custom)
- [ ] Config loading path in critical-actions matches module structure
- [ ] At least one workflow or task reference (or marked "todo")
- [ ] Module-specific conventions followed
## Critical Actions (if present)
### Standard Actions
- [ ] Config loading path is valid: `{project-root}/bmad/{module}/config.yaml`
- [ ] User name variable reference: `{user_name}`
- [ ] Communication language reference: `{communication_language}`
- [ ] All variable references use proper syntax: `{variable_name}`
### Custom Actions
- [ ] Custom initialization clearly described
- [ ] No syntax errors in action statements
- [ ] All file paths use {project-root} or other valid variables
## Optional Elements
### Activation Rules (if custom)
- [ ] Initialization sequence clearly defined
- [ ] Command resolution logic specified
- [ ] Input handling rules documented
- [ ] All custom rules properly structured
### Config File (if created)
- [ ] Located in correct path: `{project-root}/bmad/_cfg/agents/`
- [ ] Follows config override structure
- [ ] Name matches agent filename
## Final Validation
### File Quality
- [ ] No syntax errors that would prevent agent loading
- [ ] All placeholders replaced with actual values
- [ ] File saved to correct location as specified in workflow
- [ ] Filename follows kebab-case convention
### Usability
- [ ] Agent purpose is clear from title and persona
- [ ] Commands logically match agent's expertise
- [ ] User would understand how to interact with agent
- [ ] Next steps for implementation are clear
- [ ] Filename is kebab-case and ends with `.agent.yaml`
- [ ] Output location matches `src_impact` decision
- [ ] Agent purpose and commands are clear and consistent
## Issues Found

View File

@@ -2,7 +2,7 @@
<critical>The workflow execution engine is governed by: {project_root}/bmad/core/tasks/workflow.md</critical>
<critical>You MUST have already loaded and processed: {project_root}/bmad/bmb/workflows/create-agent/workflow.yaml</critical>
<critical>Study agent examples in: {project_root}/bmad/bmm/agents/ for patterns</critical>
<critical>Study YAML agent examples in: {project_root}/bmad/bmm/agents/ for patterns</critical>
<workflow>
@@ -25,7 +25,7 @@ If no, proceed directly to Step 0.
<action>Load agent architecture reference: {agent_architecture}</action>
<action>Load agent types guide: {agent_types}</action>
<action>Load command patterns: {agent_commands}</action>
<action>Study the XML schema, required sections, and best practices</action>
<action>Understand the YAML agent schema and how it compiles to final .md via the installer</action>
<action>Understand the differences between Simple, Expert, and Module agents</action>
</step>
@@ -49,8 +49,8 @@ Based on their choice, gather:
For Module agents also ask:
- Which module? (bmm, cis, other or custom)
- Store as {{target_module}} for output path determination
- Which module? (bmm, bmb, cis, or custom)
- Store as {{target_module}} for output path determination (used in metadata.module and id)
For Expert agents also ask:
@@ -119,123 +119,87 @@ Or describe your own unique style! (3-5 lines)
<template-output>agent_persona</template-output>
</step>
<step n="3" goal="Setup critical actions" optional="true">
Ask: **Does your agent need initialization actions? [Yes/no]** (default: Yes)
<step n="3" goal="Setup optional additions" optional="true">
Ask: **Do you want to add prompts or critical actions? [Yes/no]** (default: No)
If yes, determine what's needed:
If yes, collect:
Standard critical actions (include by default):
- Prompts: id + content (referenced with action: "#id" in menu items)
- Critical actions: plain text steps appended to activation during build
```xml
<critical-actions>
<i>Load into memory {project-root}/bmad/{{module}}/config.yaml and set variable project_name, output_folder, user_name, communication_language, src_impact</i>
<i>Remember the users name is {user_name}</i>
<i>ALWAYS communicate in {communication_language}</i>
</critical-actions>
```
Represent these in YAML sections `prompts` and `critical_actions`.
For Expert agents, add domain-specific actions:
- Loading sidecar files
- Setting access restrictions
- Initializing domain knowledge
For Simple agents, might be minimal or none.
Ask if they need custom initialization beyond standard.
<template-output>critical_actions</template-output>
<template-output>agent_enhancements</template-output>
</step>
<step n="4" goal="Build command structure">
<action>Always start with these standard commands:</action>
<critical>Help and Exit are auto-injected; do NOT add them. Triggers are auto-prefixed with * during build.</critical>
Collect menu items in YAML (examples):
```
*help - Show numbered cmd list
*exit - Exit with confirmation
menu:
- trigger: product-brief
workflow: "{project-root}/bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml"
description: Produce Project Brief
- trigger: validate-prd
workflow: "{project-root}/bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml"
"validate-workflow": "{output_folder}/prd-draft.md"
description: Validate PRD Against Checklist
- trigger: summarize
action: "#deep-analysis"
description: Summarize current document
- trigger: generate-brief
exec: "{project-root}/bmad/core/tasks/create-doc.md"
tmpl: "{project-root}/bmad/bmm/templates/brief.md"
data: "{project-root}/bmad/_data/context.csv"
description: Generate Project Brief from template
```
Ask: **Include \*yolo mode? [Yes/no]** (default: Yes)
If yes, add: `*yolo - Toggle Yolo Mode`
Now gather custom commands. For each command ask:
1. **Command trigger** (e.g., "*create-prd", "*analyze", "\*brainstorm")
2. **Description** (what it does)
3. **Type:**
- Workflow (run-workflow) - References a workflow
- Task (exec) - References a task file
- Embedded - Logic embedded in agent
- Placeholder - For future implementation
If Workflow type:
- Ask for workflow path or mark as "todo" for later
- Format: `run-workflow="{project-root}/path/to/workflow.yaml"` or `run-workflow="todo"`
If Task type:
- Ask for task path
- Format: `exec="{project-root}/path/to/task.md"`
If Embedded:
- Note this for special handling in agent
Continue adding commands until user says done.
<template-output>agent_commands</template-output>
</step>
<step n="5" goal="Add activation rules" optional="true">
Ask: **Does your agent need custom activation rules?** (beyond standard BMAD Core activation)
<step n="5" goal="Activation behavior" optional="true">
BMAD injects activation from fragments automatically based on used attributes (workflow/exec/tmpl/action). Most agents do not need custom activation.
If yes, gather:
If special steps are required, add them as `critical_actions` (Step 3) so they are appended during build.
- Special initialization sequences
- Menu display preferences
- Input handling rules
- Command resolution logic
- Special modes or states
Most agents use standard activation, so this is rarely needed.
<template-output>activation_rules</template-output>
<template-output>activation_notes</template-output>
</step>
<step n="6" goal="Generate agent file">
Based on agent type, generate the complete agent.md file:
<step n="6" goal="Generate agent file (YAML)">
Generate a YAML agent at the chosen path. The installer will compile it to `.md` inside `{project-root}/bmad/{{module}}/agents/`.
**Structure:**
Example structure:
```xml
<!-- Powered by BMAD-CORE™ -->
```yaml
agent:
metadata:
id: bmad/{{target_module}}/agents/{{agent_filename}}.md
name: { { agent_name } }
title: { { agent_title } }
icon: { { agent_icon } }
module: { { target_module } }
# {{agent_title}}
persona:
role: |
{{agent_persona.role}}
identity: |
{{agent_persona.identity}}
communication_style: |
{{agent_persona.communication_style}}
principles: { { agent_persona.principles } }
<agent id="bmad/{{module}}/agents/{{agent_filename}}.md" name="{{agent_name}}" title="{{agent_title}}" icon="{{agent_icon}}">
{{activation_rules if custom}}
<persona>
{{agent_persona}}
</persona>
{{critical_actions}}
{{embedded_data if expert/simple}}
<cmds>
{{agent_commands}}
</cmds>
</agent>
# Optional (from Step 3)
prompts: []
critical_actions: []
menu: { { agent_commands } }
```
For Expert agents, include:
- Sidecar file references
- Domain restrictions
- Special data access patterns
For Simple agents:
- May include embedded data/logic
- Self-contained functionality
<critical>Determine save location based on {src_impact}:</critical>
- If {src_impact} = true: Save to {src_output_file} (src/modules/{{target_module}}/agents/{{agent_filename}}.md)
@@ -244,28 +208,28 @@ For Simple agents:
<template-output>complete_agent</template-output>
</step>
<step n="7" goal="Create agent config file" optional="true">
Ask: **Create agent config file for overrides? [Yes/no]** (default: No)
<step n="7" goal="Create customize file" optional="true">
Ask: **Create a customize YAML for overrides? [Yes/no]** (default: No)
If yes, create minimal config at: {config_output_file}
If yes, create at: {config_output_file}
```xml
# Agent Config: {{agent_filename}}
<agent-config name="{{agent_name}}" title="{{agent_title}}">
<llm critical="true">
<i>ALWAYS respond in {core:communication_language}.</i>
</llm>
<!-- Override persona elements as needed -->
<role></role>
<identity></identity>
<communication_style></communication_style>
<principles></principles>
<memories></memories>
</agent-config>
```yaml
# Agent Customization (overrides are merged at build time)
agent:
metadata:
name: ''
persona:
role: ''
identity: ''
communication_style: ''
principles: []
critical_actions: []
prompts: []
menu: []
```
Note: The installer also auto-creates this file from a template if missing.
<template-output>agent_config</template-output>
</step>
@@ -283,27 +247,23 @@ For Expert agents, help setup sidecar resources:
<step n="9" goal="Validate generated agent">
Run validation checks:
1. **Structure validation:**
- Valid XML structure
- All required tags present
- Proper BMAD Core compliance
1. **YAML structure:**
- Parses without errors
- `agent.metadata` has id, name, title, icon, module
- `agent.persona` complete; principles may be array
2. **Persona completeness:**
- Role defined
- Identity defined
- Communication style defined
- Principles defined
2. **Menu validation:**
- No `*` prefix in triggers (added at build)
- `description` present for each item
- Paths use `{project-root}` or valid variables
- No duplicate triggers
3. **Commands validation:**
- \*help command present
- \*exit command present
- All workflow paths valid or marked "todo"
- No duplicate command triggers
3. **Build check:**
- Run installer compile to generate `.md` files
- Confirm `{project-root}/bmad/{{module}}/agents/{{agent_filename}}.md` exists
4. **Type-specific validation:**
- Simple: Self-contained logic verified
- Expert: Sidecar resources referenced
- Module: Module path correct
4. **Type-specific:**
- Simple/Expert/Module fields make sense and referenced paths exist (or are `todo`)
Show validation results and fix any issues.
</step>
@@ -315,9 +275,9 @@ Provide the user with:
- If {src_impact} = true: {{src_output_file}}
- If {src_impact} = false: {{default_output_file}}
2. **How to activate:**
- For testing: Load the agent file directly
- For production: Register in module config
2. **Build to .md:**
- Run `npm run install:bmad` and choose "Compile Agents" (or `bmad install` → Compile)
- The installer merges YAML + customize and injects activation and menu handlers
3. **Next steps:**
- Implement any "todo" workflows

View File

@@ -1,6 +1,6 @@
# Build Agent Workflow Configuration
name: create-agent
description: "Interactive workflow to build BMAD Core compliant agents (simple, expert, or module types) with optional brainstorming for agent ideas, proper persona development, activation rules, and command structure"
description: "Interactive workflow to build BMAD Core compliant agents (YAML source compiled to .md during install) with optional brainstorming, persona development, and command structure"
author: "BMad"
# Critical variables load from config_source
@@ -28,12 +28,13 @@ template: false # This is an interactive workflow - no template needed
instructions: "{installed_path}/instructions.md"
validation: "{installed_path}/checklist.md"
# Output configuration - dynamic based on src_impact and agent type
# If src_impact=true: Save to src/modules/{{target_module}}/agents/
# If src_impact=false: Save to output_folder/agents/
default_output_file: "{output_folder}/agents/{{agent_filename}}.md"
src_output_file: "{project-root}/src/modules/{{target_module}}/agents/{{agent_filename}}.md"
config_output_file: "{project-root}/bmad/_cfg/agents/{{agent_config_name}}.md"
# Output configuration - YAML agents compiled to .md at install time
# If src_impact=true: Save YAML to src/modules/{{target_module}}/agents/
# If src_impact=false: Save YAML to output_folder/agents/
default_output_file: "{output_folder}/agents/{{agent_filename}}.agent.yaml"
src_output_file: "{project-root}/src/modules/{{target_module}}/agents/{{agent_filename}}.agent.yaml"
# Optional user override file (auto-created by installer if missing)
config_output_file: "{project-root}/bmad/_cfg/agents/{{target_module}}-{{agent_filename}}.customize.yaml"
web_bundle:
name: "create-agent"

View File

@@ -333,7 +333,6 @@ class Installer {
// Pre-register manifest files that will be created (except files-manifest.csv to avoid recursion)
const cfgDir = path.join(bmadDir, '_cfg');
this.installedFiles.push(
path.join(cfgDir, 'manifest.csv'),
path.join(cfgDir, 'manifest.yaml'),
path.join(cfgDir, 'workflow-manifest.csv'),
path.join(cfgDir, 'agent-manifest.csv'),
@@ -419,21 +418,8 @@ class Installer {
spinner.succeed('Module-specific installers completed');
// Create manifest
spinner.start('Creating installation manifest...');
const manifestResult = await this.manifest.create(
bmadDir,
{
version: require(path.join(getProjectRoot(), 'package.json')).version,
installDate: new Date().toISOString(),
core: config.installCore,
modules: config.modules || [],
ides: config.ides || [],
language: config.language || null,
},
this.installedFiles,
);
spinner.succeed(`Manifest created (${manifestResult.filesTracked} files tracked)`);
// Note: Manifest files are already created by ManifestGenerator above
// No need to create legacy manifest.csv anymore
// If this was an update, restore custom files
let customFiles = [];
@@ -982,10 +968,13 @@ class Installer {
// Replace {project-root} placeholder
const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
// Write the built .md file
// Write the built .md file to bmad/{module}/agents/
await fs.writeFile(mdPath, processedContent, 'utf8');
this.installedFiles.push(mdPath);
// Remove the source YAML file - we can regenerate from installer source if needed
await fs.remove(yamlPath);
console.log(chalk.dim(` Built agent: ${agentName}.md`));
}
// Handle legacy .md agents - inject activation if needed
@@ -1003,6 +992,100 @@ class Installer {
}
}
/**
* Rebuild agent files from installer source (for compile command)
* @param {string} modulePath - Path to module in bmad/ installation
* @param {string} moduleName - Module name
*/
async rebuildAgentFiles(modulePath, moduleName) {
// Get source agents directory from installer
const sourceAgentsPath =
moduleName === 'core' ? path.join(getModulePath('core'), 'agents') : path.join(getSourcePath(`modules/${moduleName}`), 'agents');
if (!(await fs.pathExists(sourceAgentsPath))) {
return; // No source agents to rebuild
}
// Determine project directory (parent of bmad/ directory)
const bmadDir = path.dirname(modulePath);
const projectDir = path.dirname(bmadDir);
const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
const targetAgentsPath = path.join(modulePath, 'agents');
// Ensure target directory exists
await fs.ensureDir(targetAgentsPath);
// Get all YAML agent files from source
const sourceFiles = await fs.readdir(sourceAgentsPath);
for (const file of sourceFiles) {
if (file.endsWith('.agent.yaml')) {
const agentName = file.replace('.agent.yaml', '');
const sourceYamlPath = path.join(sourceAgentsPath, file);
const targetMdPath = path.join(targetAgentsPath, `${agentName}.md`);
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
// Check for customizations
const customizeExists = await fs.pathExists(customizePath);
let customizedFields = [];
if (customizeExists) {
const customizeContent = await fs.readFile(customizePath, 'utf8');
const yaml = require('js-yaml');
const customizeYaml = yaml.load(customizeContent);
// Detect what fields are customized
if (customizeYaml) {
if (customizeYaml.persona) {
for (const [key, value] of Object.entries(customizeYaml.persona)) {
if (value !== '' && value !== null && !(Array.isArray(value) && value.length === 0)) {
customizedFields.push(`persona.${key}`);
}
}
}
if (customizeYaml.agent?.metadata) {
for (const [key, value] of Object.entries(customizeYaml.agent.metadata)) {
if (value !== '' && value !== null) {
customizedFields.push(`metadata.${key}`);
}
}
}
if (customizeYaml.critical_actions && customizeYaml.critical_actions.length > 0) {
customizedFields.push('critical_actions');
}
if (customizeYaml.memories && customizeYaml.memories.length > 0) {
customizedFields.push('memories');
}
if (customizeYaml.menu && customizeYaml.menu.length > 0) {
customizedFields.push('menu');
}
if (customizeYaml.prompts && customizeYaml.prompts.length > 0) {
customizedFields.push('prompts');
}
}
}
// Build YAML + customize to .md
const xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
includeMetadata: true,
});
// Replace {project-root} placeholder
const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
// Write the rebuilt .md file
await fs.writeFile(targetMdPath, processedContent, 'utf8');
// Display result with customizations if any
if (customizedFields.length > 0) {
console.log(chalk.dim(` Rebuilt agent: ${agentName}.md `) + chalk.yellow(`(customized: ${customizedFields.join(', ')})`));
} else {
console.log(chalk.dim(` Rebuilt agent: ${agentName}.md`));
}
}
}
}
/**
* Compile/rebuild all agents and tasks for quick updates
* @param {Object} config - Compilation configuration
@@ -1030,13 +1113,13 @@ class Installer {
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory() && entry.name !== '_cfg') {
if (entry.isDirectory() && entry.name !== '_cfg' && entry.name !== 'docs') {
const modulePath = path.join(bmadDir, entry.name);
// Process agents
// Rebuild agents from installer source
const agentsPath = path.join(modulePath, 'agents');
if (await fs.pathExists(agentsPath)) {
await this.processAgentFiles(modulePath, entry.name);
await this.rebuildAgentFiles(modulePath, entry.name);
const agentFiles = await fs.readdir(agentsPath);
agentCount += agentFiles.filter((f) => f.endsWith('.md')).length;
}

View File

@@ -146,22 +146,21 @@ class ManifestGenerator {
/**
* Collect all agents from core and selected modules
* Scans the INSTALLED bmad directory, not the source
*/
async collectAgents(selectedModules) {
this.agents = [];
// Get core agents
const corePath = getModulePath('core');
const coreAgentsPath = path.join(corePath, 'agents');
// Get core agents from installed bmad directory
const coreAgentsPath = path.join(this.bmadDir, 'core', 'agents');
if (await fs.pathExists(coreAgentsPath)) {
const coreAgents = await this.getAgentsFromDir(coreAgentsPath, 'core');
this.agents.push(...coreAgents);
}
// Get module agents
// Get module agents from installed bmad directory
for (const moduleName of selectedModules) {
const modulePath = getSourcePath(`modules/${moduleName}`);
const agentsPath = path.join(modulePath, 'agents');
const agentsPath = path.join(this.bmadDir, moduleName, 'agents');
if (await fs.pathExists(agentsPath)) {
const moduleAgents = await this.getAgentsFromDir(agentsPath, moduleName);
@@ -172,16 +171,23 @@ class ManifestGenerator {
/**
* Get agents from a directory
* Only includes compiled .md files (not .agent.yaml source files)
*/
async getAgentsFromDir(dirPath, moduleName) {
const agents = [];
const files = await fs.readdir(dirPath);
for (const file of files) {
if (file.endsWith('.md')) {
// Only include .md files, skip .agent.yaml source files and README.md
if (file.endsWith('.md') && !file.endsWith('.agent.yaml') && file.toLowerCase() !== 'readme.md') {
const filePath = path.join(dirPath, file);
const content = await fs.readFile(filePath, 'utf8');
// Skip files that don't contain <agent> tag (e.g., README files)
if (!content.includes('<agent')) {
continue;
}
// Skip web-only agents
if (content.includes('localskip="true"')) {
continue;
@@ -218,22 +224,21 @@ class ManifestGenerator {
/**
* Collect all tasks from core and selected modules
* Scans the INSTALLED bmad directory, not the source
*/
async collectTasks(selectedModules) {
this.tasks = [];
// Get core tasks
const corePath = getModulePath('core');
const coreTasksPath = path.join(corePath, 'tasks');
// Get core tasks from installed bmad directory
const coreTasksPath = path.join(this.bmadDir, 'core', 'tasks');
if (await fs.pathExists(coreTasksPath)) {
const coreTasks = await this.getTasksFromDir(coreTasksPath, 'core');
this.tasks.push(...coreTasks);
}
// Get module tasks
// Get module tasks from installed bmad directory
for (const moduleName of selectedModules) {
const modulePath = getSourcePath(`modules/${moduleName}`);
const tasksPath = path.join(modulePath, 'tasks');
const tasksPath = path.join(this.bmadDir, moduleName, 'tasks');
if (await fs.pathExists(tasksPath)) {
const moduleTasks = await this.getTasksFromDir(tasksPath, moduleName);
@@ -296,11 +301,7 @@ class ManifestGenerator {
installDate: new Date().toISOString(),
lastUpdated: new Date().toISOString(),
},
modules: this.modules.map((name) => ({
name,
version: '',
shortTitle: '',
})),
modules: this.modules,
ides: ['claude-code'],
};

View File

@@ -145,11 +145,6 @@ class YamlXmlBuilder {
let xml = '<!-- Powered by BMAD-CORE™ -->\n\n';
xml += `# ${metadata.title || 'Agent'}\n\n`;
// Add build metadata as comment
if (buildMetadata.includeMetadata) {
xml += this.buildMetadataComment(buildMetadata);
}
xml += '```xml\n';
// Agent opening tag