docs updated and agent standalone builder working now from the main install flow

This commit is contained in:
Brian Madison
2025-10-04 01:26:38 -05:00
parent 5ee4cf535c
commit a747017520
9 changed files with 908 additions and 96 deletions

View File

@@ -5,7 +5,9 @@
[![Node.js Version](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen)](https://nodejs.org)
[![Discord](https://img.shields.io/badge/Discord-Join%20Community-7289da?logo=discord&logoColor=white)](https://discord.gg/gk8jAdXWmj)
Read this is using the [BMad Method Important Cycle Changes in V6](./v6-IMPORTANT-BMM-FLOW.md)
## 🚀 Critical: Understanding BMad Method v6a Workflow
**IMPORTANT: Before using this framework, you MUST read the [BMM v6 Workflows Guide](./src/modules/bmm/workflows/README.md).** This document is fundamental to understanding how to use v6 of the BMad Method and explains the revolutionary v6a workflow system with its four phases: Analysis, Planning, Solutioning, and Implementation.
**[Subscribe to BMadCode on YouTube](https://www.youtube.com/@BMadCode?sub_confirmation=1)** and **[Join our amazing, active Discord Community](https://discord.gg/gk8jAdXWmj)**
@@ -106,8 +108,11 @@ BMad-CORE works in ANY domain through specialized modules (previously called exp
### Available Modules with Alpha Release
- **BMad Core (core)**: Included and used to power every current and future module; includes a master orchestrator for the local environment and one for the web bundles used with ChatGPT or Gemini Gems, for example.
- **BMad Method (bmm)**: Agile AI-driven software development - the classic that started it all and is still the best - but with v6, massively improved thanks to a rebuild from the ground up built on the new powerful BMad-CORE engine. The BMad Method has also been expanded to use a new "Scale Adaptive Workflow Engine"™.
- **BMad BoMB (bmb)**: The BMad Builder is your Custom Agent, Workflow, and Module authoring tool - it's now easier than ever to customize existing modules or create whatever you can imagine as a standalone module.
- **[BMad Method (bmm)](./src/modules/bmm/README.md)**: Agile AI-driven software development - the classic that started it all and is still the best - but with v6, massively improved thanks to a rebuild from the ground up built on the new powerful BMad-CORE engine. The BMad Method has also been expanded to use a new "Scale Adaptive Workflow Engine"™. **[See BMM Documentation](./src/modules/bmm/README.md)**
- **[BMad BoMB (bmb)](./src/modules/bmb/README.md)**: The BMad Builder is your Custom Agent, Workflow, and Module authoring tool - it's now easier than ever to customize existing modules or create whatever you can imagine as a standalone module. **[See BMB Documentation](./src/modules/bmb/README.md)**
- **Creative Intelligence Suite (cis)**: Unlock innovation, problem-solving, and creative thinking! Brainstorming that was part of the BMad Method in the past is now part of this standalone module along with other workflows. The power of BMad modules still allows modules to borrow from each other - so the CIS, while standalone, also powers the brainstorming abilities for certain agents within the BMad Method!
## What's New in V6-ALPHA
@@ -138,7 +143,9 @@ The sub-agent experience is still undergoing some work, so install them if you c
When you read about the BoMB below, it will link to more information about various features in this new evolution of BMad Code. One of the exciting features is the new agent types - there are 3 now! The most exciting are the new standalone tiny agents that you can easily generate and deploy free from any module - specialized for your exact needs.
### BMad Method
### BMad Method (BMM)
📚 **[Full BMM Documentation](./src/modules/bmm/README.md)** | **[v6 Workflows Guide](./src/modules/bmm/workflows/README.md)**
The BMad Method is significantly transforming and yet more powerful than ever. **Scale Adaptive** is a new term that means when you start the workflow to create a PRD or a GDD (or a simple tech-spec in the case of simple tasks), you will first answer some questions about the scope of the project, new vs. existing codebase and its state, and other questions. This will trigger a leveling of the effort from 0-4, and based on this scale adaptation, it will guide the workflow in different directions.
@@ -223,7 +230,9 @@ The CIS has 5 agents to try out, each with their own workflow! This is a new mod
- [CIS Readme](./src/modules/cis/readme.md)
### BoMB: BMad Builder
### BoMB: BMad Builder (BMB)
📚 **[Full BMB Documentation](./src/modules/bmb/README.md)** | **[Agent Creation Guide](./src/modules/bmb/workflows/create-agent/README.md)**
#### Agent Docs

132
src/modules/bmb/README.md Normal file
View File

@@ -0,0 +1,132 @@
# BMB - BMad Builder Module
The BMB (BMad Builder Module) provides specialized tools and workflows for creating, customizing, and extending BMad Method components, including custom agents, workflows, and integrations.
## Module Structure
### 🤖 `/agents`
Builder-specific agents that help create and customize BMad Method components:
- Agent creation and configuration specialists
- Workflow designers
- Integration builders
### 📋 `/workflows`
Specialized workflows for building and extending BMad Method capabilities:
#### Core Builder Workflows
- `create-agent` - Design and implement custom agents
- `create-workflow` - Build new workflow definitions
- `create-team` - Configure agent teams
- `bundle-agent` - Package agents for distribution
- `create-method` - Design custom development methodologies
#### Integration Workflows
- `integrate-tool` - Connect external tools and services
- `create-adapter` - Build API adapters
- `setup-environment` - Configure development environments
## Key Features
### Agent Builder
Create custom agents with:
- Role-specific instructions
- Tool configurations
- Behavior patterns
- Integration points
### Workflow Designer
Design workflows that:
- Orchestrate multiple agents
- Define process flows
- Handle different project scales
- Integrate with existing systems
### Team Configuration
Build teams that:
- Combine complementary agent skills
- Coordinate on complex tasks
- Share context effectively
- Deliver cohesive results
## Quick Start
```bash
# Create a new custom agent
bmad bmb create-agent
# Design a new workflow
bmad bmb create-workflow
# Bundle an agent for sharing
bmad bmb bundle-agent
# Create a custom team configuration
bmad bmb create-team
```
## Use Cases
### Custom Agent Development
Build specialized agents for:
- Domain-specific expertise
- Company-specific processes
- Tool integrations
- Automation tasks
### Workflow Customization
Create workflows for:
- Unique development processes
- Compliance requirements
- Quality gates
- Deployment pipelines
### Team Orchestration
Configure teams for:
- Large-scale projects
- Cross-functional collaboration
- Specialized domains
- Custom methodologies
## Integration with BMM
BMB works alongside BMM to:
- Extend core BMM capabilities
- Create custom implementations
- Build domain-specific solutions
- Integrate with existing tools
## Best Practices
1. **Start with existing patterns** - Study BMM agents and workflows before creating new ones
2. **Keep it modular** - Build reusable components
3. **Document thoroughly** - Clear documentation helps others use your creations
4. **Test extensively** - Validate agents and workflows before production use
5. **Share and collaborate** - Contribute useful components back to the community
## Related Documentation
- [BMM Module](../bmm/README.md) - Core method implementation
- [Agent Creation Guide](./workflows/create-agent/README.md) - Detailed agent building instructions
- [Workflow Design Patterns](./workflows/README.md) - Best practices for workflow creation
---
BMB empowers you to extend and customize the BMad Method to fit your specific needs while maintaining the power and consistency of the core framework.

View File

@@ -105,10 +105,17 @@ create-agent/
### Generated Files
- 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`
#### For Standalone Agents (not part of a module)
- **YAML Source**: `{output_folder}/agents/{{agent_filename}}.agent.yaml`
- **Installation Location**: `{project-root}/bmad/agents/{{agent_filename}}.md`
- **Compilation**: Run `npm run build:agents` or use the installer menu
#### For Module Agents
- **YAML Source**: `src/modules/{{target_module}}/agents/{{agent_filename}}.agent.yaml`
- **Installation Location**: `{project-root}/bmad/{{module}}/agents/{{agent_filename}}.md`
- **Compilation**: Automatic during module installation
### YAML Agent Structure (simplified)
@@ -136,6 +143,51 @@ agent:
If created, generates at:
`{project-root}/bmad/_cfg/agents/{{module}}-{{agent_filename}}.customize.yaml`
## Installation and Compilation
### Agent Installation Locations
Agents are installed to different locations based on their type:
1. **Standalone Agents** (not part of a module)
- Source: Created in your project's output folder
- Installed to: `{project-root}/bmad/agents/`
- Compilation: Manual via `npm run build:agents`
2. **Module Agents** (part of BMM, BMB, or custom modules)
- Source: Created in `src/modules/{module}/agents/`
- Installed to: `{project-root}/bmad/{module}/agents/`
- Compilation: Automatic during module installation
### Compilation Process
The installer compiles YAML agent definitions to Markdown:
```bash
# For standalone agents
npm run build:agents
# For all BMad components (includes agents)
npm run install:bmad
# Using the installer menu
npm run installer
# Then select: Compile Agents
```
### Build Commands
Additional build commands for agent management:
```bash
# Build specific agent types
npx bmad-method build:agents # Build standalone agents
npx bmad-method build:modules # Build module agents (with modules)
# Full rebuild
npx bmad-method build:all # Rebuild everything
```
## Requirements
- BMAD Core v6 project structure
@@ -192,11 +244,13 @@ Users can go from **vague idea → brainstormed concept → built agent** in one
### After Completion
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 or via customize file
5. Add more commands as agent evolves
1. **Compile the agent**:
- For standalone agents: Run `npm run build:agents` or use the installer menu
- For module agents: Automatic during module installation
2. **Test the agent**: Use the compiled `.md` agent in your IDE
3. **Implement placeholders**: Complete any "todo" workflows referenced
4. **Refine as needed**: Use customize file for persona adjustments
5. **Evolve over time**: Add new commands as requirements emerge
## Agent Types

View File

@@ -2,7 +2,41 @@
## Overview
BMAD agents come in three distinct types, each designed for different use cases and complexity levels.
BMAD agents come in three distinct types, each designed for different use cases and complexity levels. The type determines where the agent is stored and what capabilities it has.
## Directory Structure by Type
### Standalone Agents (Simple & Expert)
Live in their own dedicated directories under `bmad/agents/`:
```
bmad/agents/
├── my-helper/ # Simple agent
│ ├── my-helper.agent.yaml # Agent definition
│ └── my-helper.md # Built XML (generated)
└── domain-expert/ # Expert agent
├── domain-expert.agent.yaml
├── domain-expert.md # Built XML
└── domain-expert-sidecar/ # Expert resources
├── memories.md # Persistent memory
├── instructions.md # Private directives
└── knowledge/ # Domain knowledge
```
### Module Agents
Part of a module system under `bmad/{module}/agents/`:
```
bmad/bmm/agents/
├── product-manager.agent.yaml
├── product-manager.md # Built XML
├── business-analyst.agent.yaml
└── business-analyst.md # Built XML
```
## Agent Types
@@ -10,12 +44,15 @@ BMAD agents come in three distinct types, each designed for different use cases
**Purpose:** Self-contained, standalone agents with embedded capabilities
**Location:** `bmad/agents/{agent-name}/`
**Characteristics:**
- All logic embedded within the agent file
- No external dependencies
- Quick to create and deploy
- Perfect for single-purpose tools
- Lives in its own directory
**Use Cases:**
@@ -24,7 +61,26 @@ BMAD agents come in three distinct types, each designed for different use cases
- Simple analyzers
- Static advisors
**Structure:**
**YAML Structure (source):**
```yaml
agent:
metadata:
name: 'Helper'
title: 'Simple Helper'
icon: '🤖'
type: 'simple'
persona:
role: 'Simple Helper Role'
identity: '...'
communication_style: '...'
principles: ['...']
menu:
- trigger: calculate
description: 'Perform calculation'
```
**XML Structure (built):**
```xml
<agent id="simple-agent" name="Helper" title="Simple Helper" icon="🤖">
@@ -49,12 +105,15 @@ BMAD agents come in three distinct types, each designed for different use cases
**Purpose:** Specialized agents with domain expertise and sidecar resources
**Location:** `bmad/agents/{agent-name}/` with sidecar directory
**Characteristics:**
- Has access to specific folders/files
- Domain-restricted operations
- Maintains specialized knowledge
- Can have memory/context files
- Includes sidecar directory for resources
**Use Cases:**
@@ -63,7 +122,30 @@ BMAD agents come in three distinct types, each designed for different use cases
- Domain expert (medical, legal, technical)
- Personal coach with history
**Structure:**
**YAML Structure (source):**
```yaml
agent:
metadata:
name: 'Domain Expert'
title: 'Specialist'
icon: '🎯'
type: 'expert'
persona:
role: 'Domain Specialist Role'
identity: '...'
communication_style: '...'
principles: ['...']
critical_actions:
- 'Load COMPLETE file {agent-folder}/instructions.md and follow ALL directives'
- 'Load COMPLETE file {agent-folder}/memories.md into permanent context'
- 'ONLY access {user-folder}/diary/ - NO OTHER FOLDERS'
menu:
- trigger: analyze
description: 'Analyze domain-specific data'
```
**XML Structure (built):**
```xml
<agent id="expert-agent" name="Domain Expert" title="Specialist" icon="🎯">
@@ -83,26 +165,33 @@ BMAD agents come in three distinct types, each designed for different use cases
</agent>
```
**Sidecar Structure:**
**Complete Directory Structure:**
```
expert-agent/
├── agent.md # Main agent file
├── memories.md # Personal context/memories
── knowledge/ # Domain knowledge base
└── data/ # Agent-specific data
bmad/agents/expert-agent/
├── expert-agent.agent.yaml # Agent YAML source
├── expert-agent.md # Built XML (generated)
── expert-agent-sidecar/ # Sidecar resources
├── memories.md # Persistent memory
├── instructions.md # Private directives
├── knowledge/ # Domain knowledge base
│ └── README.md
└── sessions/ # Session notes
```
### 3. Module Agent
**Purpose:** Full-featured agents belonging to a module with access to workflows and resources
**Location:** `bmad/{module}/agents/`
**Characteristics:**
- Part of a BMAD module (bmm, bmb, cis)
- Access to multiple workflows
- Can invoke other tasks and agents
- Professional/enterprise grade
- Integrated with module workflows
**Use Cases:**
@@ -111,7 +200,33 @@ expert-agent/
- Test Architect (test strategies, automation)
- Business Analyst (market research, requirements)
**Structure:**
**YAML Structure (source):**
```yaml
agent:
metadata:
name: 'John'
title: 'Product Manager'
icon: '📋'
module: 'bmm'
type: 'module'
persona:
role: 'Product Management Expert'
identity: '...'
communication_style: '...'
principles: ['...']
critical_actions:
- 'Load config from {project-root}/bmad/{module}/config.yaml'
menu:
- trigger: create-prd
workflow: '{project-root}/bmad/bmm/workflows/prd/workflow.yaml'
description: 'Create PRD'
- trigger: validate
exec: '{project-root}/bmad/core/tasks/validate-workflow.xml'
description: 'Validate document'
```
**XML Structure (built):**
```xml
<agent id="bmad/bmm/agents/pm.md" name="John" title="Product Manager" icon="📋">

View File

@@ -55,18 +55,20 @@ Present the recommendation naturally: _"Given that your agent will [summarize pu
For Module agents, discover:
- "Which system would this fit best with?" (bmm, bmb, cis, or custom)
- "Which module system would this fit best with?" (bmm, bmb, cis, or custom)
- Store as {{target_module}} for path determination
- Agent will be saved to: bmad/{{target_module}}/agents/
For Expert agents, explore:
For Simple/Expert agents (standalone):
- "What kind of information will it need to access?"
- "Are there specific folders or data it should work with?"
- "This will be your personal agent, not tied to a module"
- Agent will be saved to: bmad/agents/{{agent-name}}/
- All sidecar files will be in the same folder
<critical>Check {src_impact} variable to determine output location:</critical>
<critical>Determine agent location:</critical>
- If {src_impact} = true: Agent will be saved to {src_output_file}
- If {src_impact} = false: Agent will be saved to {default_output_file}
- Module Agent → bmad/{{module}}/agents/{{agent-name}}.agent.yaml
- Standalone Agent → bmad/agents/{{agent-name}}/{{agent-name}}.agent.yaml
<note>Keep agent naming/identity details for later - let them emerge naturally through the creation process</note>
</step>
@@ -298,15 +300,124 @@ Make it feel like preparing an office:
- "What kind of information will it need quick access to?"
- "Should it have its own data folders?"
Create the resources as a natural extension:
<action>Determine sidecar location:</action>
1. "Creating [agent name]'s knowledge base..."
2. "Setting up its personal workspace..."
3. "Giving it access to the resources it needs..."
- If build tools available: Create next to agent YAML
- If no build tools: Create in output folder with clear structure
<action>Actually CREATE the sidecar files:</action>
1. Create folder structure:
```
{{agent_filename}}-sidecar/
├── memories.md # Persistent memory
├── instructions.md # Private directives
├── knowledge/ # Knowledge base
│ └── README.md
└── sessions/ # Session notes
```
2. Create **memories.md**:
```markdown
# {{agent_name}}'s Memory Bank
## User Preferences
<!-- Populated as I learn about you -->
## Session History
<!-- Important moments from our interactions -->
## Personal Notes
<!-- My observations and insights -->
```
3. Create **instructions.md**:
```markdown
# {{agent_name}} Private Instructions
## Core Directives
- Maintain character: {{brief_personality_summary}}
- Domain: {{agent_domain}}
- Access: Only this sidecar folder
## Special Instructions
{{any_special_rules_from_creation}}
```
4. Create **knowledge/README.md**:
```markdown
# {{agent_name}}'s Knowledge Base
Add domain-specific resources here.
```
<action>Update agent YAML to reference sidecar:</action>
Add `sidecar:` section with paths to created files
<action>Show user the created structure:</action>
"I've created {{agent_name}}'s complete workspace at: {{sidecar_path}}"
<template-output>sidecar_resources</template-output>
</step>
<step n="8b" goal="Handle build tools availability">
<action>Check if BMAD build tools are available:</action>
<check>If in BMAD-METHOD project with build tools:</check>
<action>Proceed normally - agent will be built later</action>
<check>If NO build tools available (external project):</check>
<ask>Build tools not detected in this project. Would you like me to:
1. Generate the compiled agent (.md with XML) ready to use
2. Keep the YAML and build it elsewhere
3. Provide both formats</ask>
<check>If option 1 or 3 selected:</check>
<action>Generate compiled agent XML:</action>
```xml
<!-- Powered by BMAD-CORE™ -->
# {{agent_title}}
<agent id="{{agent_id}}" name="{{agent_name}}" title="{{agent_title}}" icon="{{agent_icon}}">
<activation critical="MANDATORY">
<!-- Inject standard activation -->
{{activation_rules}}
{{activation_greeting}}
</activation>
<persona>
<role>{{role}}</role>
<identity>{{identity}}</identity>
<communication_style>{{style}}</communication_style>
<principles>{{principles}}</principles>
</persona>
<menu>
<item cmd="*help">Show numbered menu</item>
{{converted_menu_items}}
<item cmd="*exit">Exit with confirmation</item>
</menu>
</agent>
```
<action>Save compiled version as {{agent_filename}}.md</action>
<action>Provide path for .claude/commands/ or similar</action>
<template-output>build_handling</template-output>
</step>
<step n="9" goal="Quality check with personality">
"Let me make sure [agent name] is ready to go!"

126
src/modules/bmm/README.md Normal file
View File

@@ -0,0 +1,126 @@
# BMM - BMad Method Module
The BMM (BMad Method Module) is the core orchestration system for the BMad Method v6a, providing comprehensive software development lifecycle management through specialized agents, workflows, teams, and tasks.
## 📚 Essential Reading
**Before using BMM, you MUST read the [BMM v6 Workflows Guide](./workflows/README.md).** This document explains the revolutionary v6a workflow system and how all components work together.
## Module Structure
### 🤖 `/agents`
Specialized AI agents for different development roles:
- **PM** (Product Manager) - Product planning and requirements
- **Analyst** - Business analysis and research
- **Architect** - Technical architecture and design
- **SM** (Scrum Master) - Sprint and story management
- **DEV** (Developer) - Code implementation
- **SR** (Senior Reviewer) - Code review and quality
- **UX** - User experience design
- And more specialized roles
### 📋 `/workflows`
The heart of BMM - structured workflows for the four development phases:
1. **Analysis Phase** (Optional)
- `brainstorm-project` - Project ideation
- `research` - Market/technical research
- `product-brief` - Product strategy
2. **Planning Phase** (Required)
- `plan-project` - Scale-adaptive project planning
- Routes to appropriate documentation based on project complexity
3. **Solutioning Phase** (Level 3-4 projects)
- `3-solutioning` - Architecture design
- `tech-spec` - Epic-specific technical specifications
4. **Implementation Phase** (Iterative)
- `create-story` - Story generation
- `story-context` - Expertise injection
- `dev-story` - Implementation
- `review-story` - Quality validation
- `correct-course` - Issue resolution
- `retrospective` - Continuous improvement
### 👥 `/teams`
Pre-configured agent teams for different project types and phases. Teams coordinate multiple agents working together on complex tasks.
### 📝 `/tasks`
Reusable task definitions that agents execute within workflows. These are the atomic units of work that compose into larger workflows.
### 🔧 `/sub-modules`
Extension modules that add specialized capabilities to BMM.
### 🏗️ `/testarch`
Test architecture and quality assurance components.
## Quick Start
```bash
# Run a planning workflow
bmad pm plan-project
# Create a new story
bmad sm create-story
# Run development workflow
bmad dev develop
# Review implementation
bmad sr review-story
```
## Key Concepts
### Scale Levels
BMM automatically adapts to project complexity:
- **Level 0**: Single atomic change
- **Level 1**: 1-10 stories, minimal documentation
- **Level 2**: 5-15 stories, focused PRD
- **Level 3**: 12-40 stories, full architecture
- **Level 4**: 40+ stories, enterprise scale
### Just-In-Time Design
Technical specifications are created one epic at a time during implementation, not all upfront, allowing for learning and adaptation.
### Context Injection
Story-specific technical guidance is generated dynamically, providing developers with exactly the expertise needed for each task.
## Integration with BMad Core
BMM integrates seamlessly with the BMad Core framework, leveraging:
- The agent execution engine
- Workflow orchestration
- Task management
- Team coordination
## Related Documentation
- [BMM Workflows Guide](./workflows/README.md) - **Start here!**
- [Agent Documentation](./agents/README.md) - Individual agent capabilities
- [Team Configurations](./teams/README.md) - Pre-built team setups
- [Task Library](./tasks/README.md) - Reusable task components
## Best Practices
1. **Always start with the workflows** - Let workflows guide your process
2. **Respect the scale** - Don't over-document small projects
3. **Embrace iteration** - Use retrospectives to continuously improve
4. **Trust the process** - The v6a methodology has been carefully designed
---
For detailed information about the complete BMad Method v6a workflow system, see the [BMM Workflows README](./workflows/README.md).

View File

@@ -346,4 +346,4 @@ bmad sm retrospective # After epic
---
This document supersedes v6-IMPORTANT-BMM-FLOW.md and serves as the authoritative guide to BMM workflow execution. For detailed information about individual workflows, see their respective README files in the workflow folders.
This document serves as the authoritative guide to BMM v6a workflow execution. For detailed information about individual workflows, see their respective README files in the workflow folders.

View File

@@ -78,6 +78,44 @@ module.exports = {
* Build a specific agent
*/
async function buildAgent(projectDir, agentName, force = false) {
// First check standalone agents in bmad/agents/{agentname}/
const standaloneAgentDir = path.join(projectDir, 'bmad', 'agents', agentName);
let standaloneYamlPath = path.join(standaloneAgentDir, `${agentName}.agent.yaml`);
// If exact match doesn't exist, look for any .agent.yaml file in the directory
if (!(await fs.pathExists(standaloneYamlPath)) && (await fs.pathExists(standaloneAgentDir))) {
const files = await fs.readdir(standaloneAgentDir);
const agentFile = files.find((f) => f.endsWith('.agent.yaml'));
if (agentFile) {
standaloneYamlPath = path.join(standaloneAgentDir, agentFile);
}
}
if (await fs.pathExists(standaloneYamlPath)) {
const yamlFileName = path.basename(standaloneYamlPath, '.agent.yaml');
const outputPath = path.join(standaloneAgentDir, `${yamlFileName}.md`);
// Check if rebuild needed
if (!force && (await fs.pathExists(outputPath))) {
const needsRebuild = await checkIfNeedsRebuild(standaloneYamlPath, outputPath, projectDir, agentName);
if (!needsRebuild) {
console.log(chalk.dim(` ${agentName}: already up to date`));
return;
}
}
// Build the standalone agent
console.log(chalk.cyan(` Building standalone agent ${agentName}...`));
const customizePath = path.join(projectDir, 'bmad', '_cfg', 'agents', `${agentName}.customize.yaml`);
const customizeExists = await fs.pathExists(customizePath);
await builder.buildAgent(standaloneYamlPath, customizeExists ? customizePath : null, outputPath, { includeMetadata: true });
console.log(chalk.green(`${agentName} built successfully (standalone)`));
return;
}
// Find the agent YAML file in .claude/commands/bmad/
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
@@ -117,7 +155,7 @@ async function buildAgent(projectDir, agentName, force = false) {
if (!found) {
console.log(chalk.yellow(` ⚠️ Agent '${agentName}' not found`));
console.log(chalk.dim(' Available agents:'));
await listAvailableAgents(bmadCommandsDir);
await listAvailableAgents(projectDir);
}
}
@@ -125,29 +163,35 @@ async function buildAgent(projectDir, agentName, force = false) {
* Build all agents
*/
async function buildAllAgents(projectDir, force = false) {
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
const modules = await fs.readdir(bmadCommandsDir);
let builtCount = 0;
let skippedCount = 0;
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
// First, build standalone agents in bmad/agents/
const standaloneAgentsDir = path.join(projectDir, 'bmad', 'agents');
if (await fs.pathExists(standaloneAgentsDir)) {
console.log(chalk.cyan('\nBuilding standalone agents...'));
const agentDirs = await fs.readdir(standaloneAgentsDir);
if (!(await fs.pathExists(agentsDir))) {
continue;
}
for (const agentDirName of agentDirs) {
const agentDir = path.join(standaloneAgentsDir, agentDirName);
const files = await fs.readdir(agentsDir);
for (const file of files) {
if (!file.endsWith('.agent.yaml')) {
// Skip if not a directory
const stat = await fs.stat(agentDir);
if (!stat.isDirectory()) {
continue;
}
const agentName = file.replace('.agent.yaml', '');
const agentYamlPath = path.join(agentsDir, file);
const outputPath = path.join(agentsDir, `${agentName}.md`);
// Find any .agent.yaml file in the directory
const files = await fs.readdir(agentDir);
const agentFile = files.find((f) => f.endsWith('.agent.yaml'));
if (!agentFile) {
continue;
}
const agentYamlPath = path.join(agentDir, agentFile);
const agentName = path.basename(agentFile, '.agent.yaml');
const outputPath = path.join(agentDir, `${agentName}.md`);
// Check if rebuild needed
if (!force && (await fs.pathExists(outputPath))) {
@@ -159,18 +203,65 @@ async function buildAllAgents(projectDir, force = false) {
}
}
console.log(chalk.cyan(` Building ${agentName}...`));
console.log(chalk.cyan(` Building standalone agent ${agentName}...`));
const customizePath = path.join(projectDir, '.claude', '_cfg', 'agents', `${agentName}.customize.yaml`);
const customizePath = path.join(projectDir, 'bmad', '_cfg', 'agents', `${agentName}.customize.yaml`);
const customizeExists = await fs.pathExists(customizePath);
await builder.buildAgent(agentYamlPath, customizeExists ? customizePath : null, outputPath, { includeMetadata: true });
console.log(chalk.green(`${agentName}`));
console.log(chalk.green(`${agentName} (standalone)`));
builtCount++;
}
}
// Then, build module agents in .claude/commands/bmad/
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
if (await fs.pathExists(bmadCommandsDir)) {
console.log(chalk.cyan('\nBuilding module agents...'));
const modules = await fs.readdir(bmadCommandsDir);
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
if (!(await fs.pathExists(agentsDir))) {
continue;
}
const files = await fs.readdir(agentsDir);
for (const file of files) {
if (!file.endsWith('.agent.yaml')) {
continue;
}
const agentName = file.replace('.agent.yaml', '');
const agentYamlPath = path.join(agentsDir, file);
const outputPath = path.join(agentsDir, `${agentName}.md`);
// Check if rebuild needed
if (!force && (await fs.pathExists(outputPath))) {
const needsRebuild = await checkIfNeedsRebuild(agentYamlPath, outputPath, projectDir, agentName);
if (!needsRebuild) {
console.log(chalk.dim(` ${agentName}: up to date`));
skippedCount++;
continue;
}
}
console.log(chalk.cyan(` Building ${agentName}...`));
const customizePath = path.join(projectDir, '.claude', '_cfg', 'agents', `${agentName}.customize.yaml`);
const customizeExists = await fs.pathExists(customizePath);
await builder.buildAgent(agentYamlPath, customizeExists ? customizePath : null, outputPath, { includeMetadata: true });
console.log(chalk.green(`${agentName} (${module})`));
builtCount++;
}
}
}
console.log(chalk.green(`\n✓ Built ${builtCount} agent(s)`));
if (skippedCount > 0) {
console.log(chalk.dim(` Skipped ${skippedCount} (already up to date)`));
@@ -181,36 +272,75 @@ async function buildAllAgents(projectDir, force = false) {
* Check what needs rebuilding
*/
async function checkBuildStatus(projectDir) {
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
const modules = await fs.readdir(bmadCommandsDir);
const needsRebuild = [];
const upToDate = [];
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
// Check standalone agents in bmad/agents/
const standaloneAgentsDir = path.join(projectDir, 'bmad', 'agents');
if (await fs.pathExists(standaloneAgentsDir)) {
const agentDirs = await fs.readdir(standaloneAgentsDir);
if (!(await fs.pathExists(agentsDir))) {
continue;
}
for (const agentDirName of agentDirs) {
const agentDir = path.join(standaloneAgentsDir, agentDirName);
const files = await fs.readdir(agentsDir);
for (const file of files) {
if (!file.endsWith('.agent.yaml')) {
// Skip if not a directory
const stat = await fs.stat(agentDir);
if (!stat.isDirectory()) {
continue;
}
const agentName = file.replace('.agent.yaml', '');
const agentYamlPath = path.join(agentsDir, file);
const outputPath = path.join(agentsDir, `${agentName}.md`);
// Find any .agent.yaml file in the directory
const files = await fs.readdir(agentDir);
const agentFile = files.find((f) => f.endsWith('.agent.yaml'));
if (!agentFile) {
continue;
}
const agentYamlPath = path.join(agentDir, agentFile);
const agentName = path.basename(agentFile, '.agent.yaml');
const outputPath = path.join(agentDir, `${agentName}.md`);
if (!(await fs.pathExists(outputPath))) {
needsRebuild.push(agentName);
needsRebuild.push(`${agentName} (standalone)`);
} else if (await checkIfNeedsRebuild(agentYamlPath, outputPath, projectDir, agentName)) {
needsRebuild.push(agentName);
needsRebuild.push(`${agentName} (standalone)`);
} else {
upToDate.push(agentName);
upToDate.push(`${agentName} (standalone)`);
}
}
}
// Check module agents in .claude/commands/bmad/
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
if (await fs.pathExists(bmadCommandsDir)) {
const modules = await fs.readdir(bmadCommandsDir);
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
if (!(await fs.pathExists(agentsDir))) {
continue;
}
const files = await fs.readdir(agentsDir);
for (const file of files) {
if (!file.endsWith('.agent.yaml')) {
continue;
}
const agentName = file.replace('.agent.yaml', '');
const agentYamlPath = path.join(agentsDir, file);
const outputPath = path.join(agentsDir, `${agentName}.md`);
if (!(await fs.pathExists(outputPath))) {
needsRebuild.push(`${agentName} (${module})`);
} else if (await checkIfNeedsRebuild(agentYamlPath, outputPath, projectDir, agentName)) {
needsRebuild.push(`${agentName} (${module})`);
} else {
upToDate.push(`${agentName} (${module})`);
}
}
}
}
@@ -275,22 +405,53 @@ async function checkIfNeedsRebuild(yamlPath, outputPath, projectDir, agentName)
/**
* List available agents
*/
async function listAvailableAgents(bmadCommandsDir) {
const modules = await fs.readdir(bmadCommandsDir);
async function listAvailableAgents(projectDir) {
// List standalone agents first
const standaloneAgentsDir = path.join(projectDir, 'bmad', 'agents');
if (await fs.pathExists(standaloneAgentsDir)) {
console.log(chalk.dim(' Standalone agents:'));
const agentDirs = await fs.readdir(standaloneAgentsDir);
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
for (const agentDirName of agentDirs) {
const agentDir = path.join(standaloneAgentsDir, agentDirName);
if (!(await fs.pathExists(agentsDir))) {
continue;
// Skip if not a directory
const stat = await fs.stat(agentDir);
if (!stat.isDirectory()) {
continue;
}
// Find any .agent.yaml file in the directory
const files = await fs.readdir(agentDir);
const agentFile = files.find((f) => f.endsWith('.agent.yaml'));
if (agentFile) {
const agentName = path.basename(agentFile, '.agent.yaml');
console.log(chalk.dim(` - ${agentName} (in ${agentDirName}/)`));
}
}
}
const files = await fs.readdir(agentsDir);
// List module agents
const bmadCommandsDir = path.join(projectDir, '.claude', 'commands', 'bmad');
if (await fs.pathExists(bmadCommandsDir)) {
console.log(chalk.dim(' Module agents:'));
const modules = await fs.readdir(bmadCommandsDir);
for (const file of files) {
if (file.endsWith('.agent.yaml')) {
const agentName = file.replace('.agent.yaml', '');
console.log(chalk.dim(` - ${agentName} (${module})`));
for (const module of modules) {
const agentsDir = path.join(bmadCommandsDir, module, 'agents');
if (!(await fs.pathExists(agentsDir))) {
continue;
}
const files = await fs.readdir(agentsDir);
for (const file of files) {
if (file.endsWith('.agent.yaml')) {
const agentName = file.replace('.agent.yaml', '');
console.log(chalk.dim(` - ${agentName} (${module})`));
}
}
}
}

View File

@@ -992,6 +992,93 @@ class Installer {
}
}
/**
* Build standalone agents in bmad/agents/ directory
* @param {string} bmadDir - Path to bmad directory
* @param {string} projectDir - Path to project directory
*/
async buildStandaloneAgents(bmadDir, projectDir) {
const standaloneAgentsPath = path.join(bmadDir, 'agents');
const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
// Check if standalone agents directory exists
if (!(await fs.pathExists(standaloneAgentsPath))) {
return;
}
// Get all subdirectories in agents/
const agentDirs = await fs.readdir(standaloneAgentsPath, { withFileTypes: true });
for (const agentDir of agentDirs) {
if (!agentDir.isDirectory()) continue;
const agentDirPath = path.join(standaloneAgentsPath, agentDir.name);
// Find any .agent.yaml file in the directory
const files = await fs.readdir(agentDirPath);
const yamlFile = files.find((f) => f.endsWith('.agent.yaml'));
if (!yamlFile) continue;
const agentName = path.basename(yamlFile, '.agent.yaml');
const sourceYamlPath = path.join(agentDirPath, yamlFile);
const targetMdPath = path.join(agentDirPath, `${agentName}.md`);
const customizePath = path.join(cfgAgentsDir, `${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 (similar to rebuildAgentFiles)
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.menu && customizeYaml.menu.length > 0) {
customizedFields.push('menu');
}
}
}
// Build YAML to XML .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 built .md file
await fs.writeFile(targetMdPath, processedContent, 'utf8');
// Display result
if (customizedFields.length > 0) {
console.log(chalk.dim(` Built standalone agent: ${agentName}.md `) + chalk.yellow(`(customized: ${customizedFields.join(', ')})`));
} else {
console.log(chalk.dim(` Built standalone agent: ${agentName}.md`));
}
}
}
/**
* Rebuild agent files from installer source (for compile command)
* @param {string} modulePath - Path to module in bmad/ installation
@@ -1116,19 +1203,36 @@ class Installer {
if (entry.isDirectory() && entry.name !== '_cfg' && entry.name !== 'docs') {
const modulePath = path.join(bmadDir, entry.name);
// Rebuild agents from installer source
const agentsPath = path.join(modulePath, 'agents');
if (await fs.pathExists(agentsPath)) {
await this.rebuildAgentFiles(modulePath, entry.name);
const agentFiles = await fs.readdir(agentsPath);
agentCount += agentFiles.filter((f) => f.endsWith('.md')).length;
}
// Special handling for standalone agents in bmad/agents/ directory
if (entry.name === 'agents') {
spinner.text = 'Building standalone agents...';
await this.buildStandaloneAgents(bmadDir, projectDir);
// Count tasks (already built)
const tasksPath = path.join(modulePath, 'tasks');
if (await fs.pathExists(tasksPath)) {
const taskFiles = await fs.readdir(tasksPath);
taskCount += taskFiles.filter((f) => f.endsWith('.md')).length;
// Count standalone agents
const standaloneAgentsPath = path.join(bmadDir, 'agents');
const standaloneAgentDirs = await fs.readdir(standaloneAgentsPath, { withFileTypes: true });
for (const agentDir of standaloneAgentDirs) {
if (agentDir.isDirectory()) {
const agentDirPath = path.join(standaloneAgentsPath, agentDir.name);
const agentFiles = await fs.readdir(agentDirPath);
agentCount += agentFiles.filter((f) => f.endsWith('.md') && !f.endsWith('.agent.yaml')).length;
}
}
} else {
// Rebuild module agents from installer source
const agentsPath = path.join(modulePath, 'agents');
if (await fs.pathExists(agentsPath)) {
await this.rebuildAgentFiles(modulePath, entry.name);
const agentFiles = await fs.readdir(agentsPath);
agentCount += agentFiles.filter((f) => f.endsWith('.md')).length;
}
// Count tasks (already built)
const tasksPath = path.join(modulePath, 'tasks');
if (await fs.pathExists(tasksPath)) {
const taskFiles = await fs.readdir(tasksPath);
taskCount += taskFiles.filter((f) => f.endsWith('.md')).length;
}
}
}
}