Migrate workflow runner references to workflow.md

This commit is contained in:
Dicky Moore 2026-02-05 16:02:01 +00:00
parent c769f1b44d
commit 1a1d4bed52
9 changed files with 481 additions and 77 deletions

View File

@ -0,0 +1,63 @@
# Test Architect + Quality Advisor Agent Definition
agent:
webskip: true
metadata:
id: "_bmad/bmm/agents/tea.md"
name: Murat
title: Master Test Architect
icon: 🧪
module: bmm
hasSidecar: false
persona:
role: Master Test Architect
identity: Test architect specializing in API testing, backend services, UI automation, CI/CD pipelines, and scalable quality gates. Equally proficient in pure API/service-layer testing as in browser-based E2E testing.
communication_style: "Blends data with gut instinct. 'Strong opinions, weakly held' is their mantra. Speaks in risk calculations and impact assessments."
principles: |
- Risk-based testing - depth scales with impact
- Quality gates backed by data
- Tests mirror usage patterns (API, UI, or both)
- Flakiness is critical technical debt
- Tests first AI implements suite validates
- Calculate risk vs value for every testing decision
- Prefer lower test levels (unit > integration > E2E) when possible
- API tests are first-class citizens, not just UI support
critical_actions:
- "Consult {project-root}/_bmad/bmm/testarch/tea-index.csv to select knowledge fragments under knowledge/ and load only the files needed for the current task"
- "Load the referenced fragment(s) from {project-root}/_bmad/bmm/testarch/knowledge/ before giving recommendations"
- "Cross-check recommendations with the current official Playwright, Cypress, Pact, and CI platform documentation"
menu:
- trigger: TF or fuzzy match on test-framework
workflow: "{project-root}/_bmad/bmm/workflows/testarch/framework/workflow.md"
description: "[TF] Test Framework: Initialize production-ready test framework architecture"
- trigger: AT or fuzzy match on atdd
workflow: "{project-root}/_bmad/bmm/workflows/testarch/atdd/workflow.md"
description: "[AT] Automated Test: Generate API and/or E2E tests first, before starting implementation on a story"
- trigger: TA or fuzzy match on test-automate
workflow: "{project-root}/_bmad/bmm/workflows/testarch/automate/workflow.md"
description: "[TA] Test Automation: Generate comprehensive test automation framework for your whole project"
- trigger: TD or fuzzy match on test-design
workflow: "{project-root}/_bmad/bmm/workflows/testarch/test-design/workflow.md"
description: "[TD] Test Design: Create comprehensive test scenarios ahead of development."
- trigger: TR or fuzzy match on test-trace
workflow: "{project-root}/_bmad/bmm/workflows/testarch/trace/workflow.md"
description: "[TR] Trace Requirements: Map requirements to tests (Phase 1) and make quality gate decision (Phase 2)"
- trigger: NR or fuzzy match on nfr-assess
workflow: "{project-root}/_bmad/bmm/workflows/testarch/nfr-assess/workflow.md"
description: "[NR] Non-Functional Requirements: Validate against the project implementation"
- trigger: CI or fuzzy match on continuous-integration
workflow: "{project-root}/_bmad/bmm/workflows/testarch/ci/workflow.md"
description: "[CI] Continuous Integration: Recommend and Scaffold CI/CD quality pipeline"
- trigger: RV or fuzzy match on test-review
workflow: "{project-root}/_bmad/bmm/workflows/testarch/test-review/workflow.md"
description: "[RV] Review Tests: Perform a quality check against written tests using comprehensive knowledge base and best practices"

View File

@ -1,31 +1,32 @@
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs,
bmm,anytime,Document Project,DP,,_bmad/bmm/workflows/document-project/workflow.yaml,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*,
bmm,anytime,Generate Project Context,GPC,,_bmad/bmm/workflows/generate-project-context/workflow.md,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context",
bmm,anytime,Quick Spec,QS,,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps brownfield additions to well established patterns utilities without extensive planning",planning_artifacts,"tech spec",
bmm,anytime,Quick Dev,QD,,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,,
bmm,anytime,Correct Course,CC,,_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
bmm,anytime,Write Document,WD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document",
bmm,anytime,Update Standards,US,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards",
bmm,anytime,Mermaid Generate,MG,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create a Mermaid diagram based on user description. Will suggest diagram types if not specified.",planning_artifacts,"mermaid diagram",
bmm,anytime,Validate Document,VD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Review the specified document against documentation standards and best practices. Returns specific actionable improvement suggestions organized by priority.",planning_artifacts,"validation report",
bmm,anytime,Explain Concept,EC,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create clear technical explanations with examples and diagrams for complex concepts. Breaks down into digestible sections using task-oriented approach.",project_knowledge,"explanation",
bmm,anytime,Document Project,DP,10,_bmad/bmm/workflows/document-project/workflow.md,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*,
bmm,anytime,Quick Spec,TS,20,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps utilities without extensive planning",planning_artifacts,"tech spec",
bmm,anytime,Quick Dev,QD,30,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,,
bmm,anytime,Correct Course,CC,40,_bmad/bmm/workflows/4-implementation/correct-course/workflow.md,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
bmm,1-analysis,Brainstorm Project,BP,10,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,data=_bmad/bmm/data/project-context-template.md,"Expert Guided Facilitation through a single or multiple techniques",planning_artifacts,"brainstorming session",
bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow-market-research.md,bmad-bmm-market-research,false,analyst,Create Mode,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents",
bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md,bmad-bmm-domain-research,false,analyst,Create Mode,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project_knowledge","research documents",
bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md,bmad-bmm-technical-research,false,analyst,Create Mode,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project_knowledge","research documents",
bmm,1-analysis,Create Brief,CB,30,_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md,bmad-bmm-create-product-brief,false,analyst,Create Mode,"A guided experience to nail down your product idea",planning_artifacts,"product brief",
bmm,2-planning,Create PRD,CP,10,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md,bmad-bmm-create-prd,true,pm,Create Mode,"Expert led facilitation to produce your Product Requirements Document",planning_artifacts,prd,
bmm,2-planning,Validate PRD,VP,20,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md,bmad-bmm-validate-prd,false,pm,Validate Mode,"Validate PRD is comprehensive lean well organized and cohesive",planning_artifacts,"prd validation report",
bmm,2-planning,Edit PRD,EP,25,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md,bmad-bmm-edit-prd,false,pm,Edit Mode,"Improve and enhance an existing PRD",planning_artifacts,"updated prd",
bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=market,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents"
bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=domain,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project-knowledge","research documents"
bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=technical,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project-knowledge","research documents"
bmm,1-analysis,Create Brief,CB,30,_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md,bmad-bmm-create-brief,false,analyst,Create Mode,"A guided experience to nail down your product idea",planning_artifacts,"product brief",
bmm,1-analysis,Validate Brief,VB,40,_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md,bmad-bmm-validate-brief,false,analyst,Validate Mode,"Validates product brief completeness",planning_artifacts,"brief validation report",
bmm,2-planning,Create PRD,CP,10,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-prd,true,pm,Create Mode,"Expert led facilitation to produce your Product Requirements Document",planning_artifacts,prd,
bmm,2-planning,Validate PRD,VP,20,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-prd,false,pm,Validate Mode,"Validate PRD is comprehensive lean well organized and cohesive",planning_artifacts,"prd validation report",
bmm,2-planning,Create UX,CU,30,_bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md,bmad-bmm-create-ux-design,false,ux-designer,Create Mode,"Guidance through realizing the plan for your UX, strongly recommended if a UI is a primary piece of the proposed project",planning_artifacts,"ux design",
bmm,2-planning,Validate UX,VU,40,_bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md,bmad-bmm-create-ux-design,false,ux-designer,Validate Mode,"Validates UX design deliverables",planning_artifacts,"ux validation report",
,anytime,Create Dataflow,CDF,50,_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.md,bmad-bmm-create-excalidraw-dataflow,false,ux-designer,Create Mode,"Create data flow diagrams (DFD) in Excalidraw format - can be called standalone or during any workflow to add visual documentation",planning_artifacts,"dataflow diagram",
,anytime,Create Diagram,CED,51,_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.md,bmad-bmm-create-excalidraw-diagram,false,ux-designer,Create Mode,"Create system architecture diagrams ERDs UML diagrams or general technical diagrams in Excalidraw format - use anytime or call from architecture workflow to add visual documentation",planning_artifacts,"diagram",
,anytime,Create Flowchart,CFC,52,_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.md,bmad-bmm-create-excalidraw-flowchart,false,ux-designer,Create Mode,"Create a flowchart visualization in Excalidraw format for processes pipelines or logic flows - use anytime or during architecture to add process documentation",planning_artifacts,"flowchart",
,anytime,Create Wireframe,CEW,53,_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.md,bmad-bmm-create-excalidraw-wireframe,false,ux-designer,Create Mode,"Create website or app wireframes in Excalidraw format - use anytime standalone or call from UX workflow to add UI mockups",planning_artifacts,"wireframe",
bmm,3-solutioning,Create Architecture,CA,10,_bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md,bmad-bmm-create-architecture,true,architect,Create Mode,"Guided Workflow to document technical decisions",planning_artifacts,architecture,
bmm,3-solutioning,Validate Architecture,VA,20,_bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md,bmad-bmm-create-architecture,false,architect,Validate Mode,"Validates architecture completeness",planning_artifacts,"architecture validation report",
bmm,3-solutioning,Create Epics and Stories,CE,30,_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md,bmad-bmm-create-epics-and-stories,true,pm,Create Mode,"Create the Epics and Stories Listing",planning_artifacts,"epics and stories",
bmm,3-solutioning,Validate Epics and Stories,VE,40,_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md,bmad-bmm-create-epics-and-stories,false,pm,Validate Mode,"Validates epics and stories completeness",planning_artifacts,"epics validation report",
bmm,3-solutioning,Test Design,TD,50,_bmad/bmm/workflows/testarch/test-design/workflow.md,bmad-bmm-testarch-test-design,false,tea,Create Mode,"Create comprehensive test scenarios ahead of development, recommended if string test compliance or assurance is needed. Very critical for distributed applications with separate front ends and backends outside of a monorepo.",planning_artifacts,"test design",
bmm,3-solutioning,Check Implementation Readiness,IR,70,_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md,bmad-bmm-check-implementation-readiness,true,architect,Validate Mode,"Ensure PRD UX Architecture and Epics Stories are aligned",planning_artifacts,"readiness report",
bmm,4-implementation,Sprint Planning,SP,10,_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml,bmad-bmm-sprint-planning,true,sm,Create Mode,"Generate sprint plan for development tasks - this kicks off the implementation phase by producing a plan the implementation agents will follow in sequence for every story in the plan.",implementation_artifacts,"sprint status",
bmm,4-implementation,Sprint Status,SS,20,_bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml,bmad-bmm-sprint-status,false,sm,Create Mode,"Anytime: Summarize sprint status and route to next workflow",,,
bmm,4-implementation,Validate Story,VS,35,_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml,bmad-bmm-create-story,false,sm,Validate Mode,"Validates story readiness and completeness before development work begins",implementation_artifacts,"story validation report",
bmm,4-implementation,Create Story,CS,30,_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml,bmad-bmm-create-story,true,sm,Create Mode,"Story cycle start: Prepare first found story in the sprint plan that is next, or if the command is run with a specific epic and story designation with context. Once complete, then VS then DS then CR then back to DS if needed or next CS or ER",implementation_artifacts,story,
bmm,4-implementation,Dev Story,DS,40,_bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml,bmad-bmm-dev-story,true,dev,Create Mode,"Story cycle: Execute story implementation tasks and tests then CR then back to DS if fixes needed",,,
bmm,4-implementation,Code Review,CR,50,_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml,bmad-bmm-code-review,false,dev,Create Mode,"Story cycle: If issues back to DS if approved then next CS or ER if epic complete",,,
bmm,4-implementation,QA Automation Test,QA,45,_bmad/bmm/workflows/qa/automate/workflow.yaml,bmad-bmm-qa-automate,false,qa,Create Mode,"Generate automated API and E2E tests for implemented code using the project's existing test framework (detects existing well known in use test frameworks). Use after implementation to add test coverage. NOT for code review or story validation - use CR for that.",implementation_artifacts,"test suite",
bmm,4-implementation,Retrospective,ER,60,_bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml,bmad-bmm-retrospective,false,sm,Create Mode,"Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC",implementation_artifacts,retrospective,
bmm,4-implementation,Sprint Planning,SP,10,_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.md,bmad-bmm-sprint-planning,true,sm,Create Mode,"Generate sprint plan for development tasks - this kicks off the implementation phase by producing a plan the implementation agents will follow in sequence for every story in the plan.",implementation_artifacts,"sprint status",
bmm,4-implementation,Sprint Status,SS,20,_bmad/bmm/workflows/4-implementation/sprint-status/workflow.md,bmad-bmm-sprint-status,false,sm,Create Mode,"Anytime: Summarize sprint status and route to next workflow",,,
bmm,4-implementation,Create Story,CS,30,_bmad/bmm/workflows/4-implementation/create-story/workflow.md,bmad-bmm-create-story,true,sm,Create Mode,"Story cycle start: Prepare first found story in the sprint plan that is next, or if the command is run with a specific epic and story designation with context. Once complete, then VS then DS then CR then back to DS if needed or next CS or ER",implementation_artifacts,story,
bmm,4-implementation,Validate Story,VS,35,_bmad/bmm/workflows/4-implementation/create-story/workflow.md,bmad-bmm-create-story,false,sm,Validate Mode,"Validates story readiness and completeness before development work begins",implementation_artifacts,"story validation report",
bmm,4-implementation,Dev Story,DS,40,_bmad/bmm/workflows/4-implementation/dev-story/workflow.md,bmad-bmm-dev-story,true,dev,Create Mode,"Story cycle: Execute story implementation tasks and tests then CR then back to DS if fixes needed",,,
bmm,4-implementation,Code Review,CR,50,_bmad/bmm/workflows/4-implementation/code-review/workflow.md,bmad-bmm-code-review,false,dev,Create Mode,"Story cycle: If issues back to DS if approved then next CS or ER if epic complete",,,
bmm,4-implementation,Retrospective,ER,60,_bmad/bmm/workflows/4-implementation/retrospective/workflow.md,bmad-bmm-retrospective,false,sm,Create Mode,"Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC",implementation_artifacts,retrospective,

Can't render this file because it has a wrong number of fields in line 7.

View File

@ -0,0 +1,160 @@
# Core Excalidraw Resources
Universal knowledge for creating Excalidraw diagrams. All agents that create Excalidraw files should reference these resources.
## Purpose
Provides the **HOW** (universal knowledge) while agents provide the **WHAT** (domain-specific application).
**Core = "How to create Excalidraw elements"**
- How to group shapes with text labels
- How to calculate text width
- How to create arrows with proper bindings
- How to validate JSON syntax
- Base structure and primitives
**Agents = "What diagrams to create"**
- Frame Expert (BMM): Technical flowcharts, architecture diagrams, wireframes
- Presentation Master (CIS): Pitch decks, creative visuals, Rube Goldberg machines
- Tech Writer (BMM): Documentation diagrams, concept explanations
## Files in This Directory
### excalidraw-helpers.md
**Universal element creation patterns**
- Text width calculation
- Element grouping rules (shapes + labels)
- Grid alignment
- Arrow creation (straight, elbow)
- Theme application
- Validation checklist
- Optimization rules
**Agents reference this to:**
- Create properly grouped shapes
- Calculate text dimensions
- Connect elements with arrows
- Ensure valid structure
### validate-json-instructions.md
**Universal JSON validation process**
- How to validate Excalidraw JSON
- Common errors and fixes
- Workflow integration
- Error recovery
**Agents reference this to:**
- Validate files after creation
- Fix syntax errors
- Ensure files can be opened in Excalidraw
### library-loader.md (Future)
**How to load external .excalidrawlib files**
- Programmatic library loading
- Community library integration
- Custom library management
**Status:** To be developed when implementing external library support.
## How Agents Use These Resources
### Example: Frame Expert (Technical Diagrams)
```yaml
# workflows/excalidraw-diagrams/create-flowchart/workflow.md
helpers: '{project-root}/_bmad/core/resources/excalidraw/excalidraw-helpers.md'
json_validation: '{project-root}/_bmad/core/resources/excalidraw/validate-json-instructions.md'
```
**Domain-specific additions:**
```yaml
# workflows/excalidraw-diagrams/_shared/flowchart-templates.yaml
flowchart:
start_node:
type: ellipse
width: 120
height: 60
process_box:
type: rectangle
width: 160
height: 80
decision_diamond:
type: diamond
width: 140
height: 100
```
### Example: Presentation Master (Creative Visuals)
```yaml
# workflows/create-visual-metaphor/workflow.md
helpers: '{project-root}/_bmad/core/resources/excalidraw/excalidraw-helpers.md'
json_validation: '{project-root}/_bmad/core/resources/excalidraw/validate-json-instructions.md'
```
**Domain-specific additions:**
```yaml
# workflows/_shared/creative-templates.yaml
rube_goldberg:
whimsical_connector:
type: arrow
strokeStyle: dashed
roughness: 2
playful_box:
type: rectangle
roundness: 12
```
## What Doesn't Belong in Core
**Domain-Specific Elements:**
- Flowchart-specific templates (belongs in Frame Expert)
- Pitch deck layouts (belongs in Presentation Master)
- Documentation-specific styles (belongs in Tech Writer)
**Agent Workflows:**
- How to create a flowchart (Frame Expert workflow)
- How to create a pitch deck (Presentation Master workflow)
- Step-by-step diagram creation (agent-specific)
**Theming:**
- Currently in agent workflows
- **Future:** Will be refactored to core as user-configurable themes
## Architecture Principle
**Single Source of Truth:**
- Core holds universal knowledge
- Agents reference core, don't duplicate
- Updates to core benefit all agents
- Agents specialize with domain knowledge
**DRY (Don't Repeat Yourself):**
- Element creation logic: ONCE in core
- Text width calculation: ONCE in core
- Validation process: ONCE in core
- Arrow binding patterns: ONCE in core
## Future Enhancements
1. **External Library Loader** - Load .excalidrawlib files from libraries.excalidraw.com
2. **Theme Management** - User-configurable color themes saved in core
3. **Component Library** - Shared reusable components across agents
4. **Layout Algorithms** - Auto-layout helpers for positioning elements

View File

@ -0,0 +1,50 @@
# External Library Loader
**Status:** Placeholder for future implementation
## Purpose
Load external .excalidrawlib files from <https://libraries.excalidraw.com> or custom sources.
## Planned Capabilities
- Load libraries by URL
- Load libraries from local files
- Merge multiple libraries
- Filter library components
- Cache loaded libraries
## API Reference
Will document how to use:
- `importLibrary(url)` - Load library from URL
- `loadSceneOrLibraryFromBlob()` - Load from file
- `mergeLibraryItems()` - Combine libraries
## Usage Example
```yaml
# Future workflow.md structure
libraries:
- url: 'https://libraries.excalidraw.com/libraries/...'
filter: ['aws', 'cloud']
- path: '{project-root}/_data/custom-library.excalidrawlib'
```
## Implementation Notes
This will be developed when agents need to leverage the extensive library ecosystem available at <https://libraries.excalidraw.com>.
Hundreds of pre-built component libraries exist for:
- AWS/Cloud icons
- UI/UX components
- Business diagrams
- Mind map shapes
- Floor plans
- And much more...
## User Configuration
Future: Users will be able to configure favorite libraries in their BMAD config for automatic loading.

View File

@ -234,6 +234,101 @@ async function runTests() {
console.log('');
// ============================================================
// Test 7: Validate Workflow XML Reference Guard
// ============================================================
console.log(`${colors.yellow}Test Suite 7: Validate Workflow Reference Guard${colors.reset}\n`);
try {
const searchRoots = [path.join(projectRoot, 'src'), path.join(projectRoot, 'docs')];
const allowedExtensions = new Set(['.md', '.yaml', '.yml', '.xml']);
const forbiddenRef = 'validate-workflow.xml';
const excludedFile = path.join(projectRoot, 'src', 'core', 'tasks', 'validate-workflow.xml');
const offenders = [];
const walk = async (dir) => {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
await walk(fullPath);
continue;
}
if (!allowedExtensions.has(path.extname(entry.name))) {
continue;
}
if (fullPath === excludedFile) {
continue;
}
const content = await fs.readFile(fullPath, 'utf8');
if (content.includes(forbiddenRef)) {
offenders.push(path.relative(projectRoot, fullPath));
}
}
};
for (const root of searchRoots) {
await walk(root);
}
assert(
offenders.length === 0,
'No validate-workflow.xml references outside XML source',
offenders.length > 0 ? offenders.join(', ') : '',
);
} catch (error) {
assert(false, 'Validate workflow reference guard runs', error.message);
}
console.log('');
// ============================================================
// Test 8: Workflow XML Reference Guard
// ============================================================
console.log(`${colors.yellow}Test Suite 8: Workflow Reference Guard${colors.reset}\n`);
try {
const searchRoots = [path.join(projectRoot, 'src'), path.join(projectRoot, 'docs'), path.join(projectRoot, 'tools')];
const allowedExtensions = new Set(['.md', '.yaml', '.yml', '.xml']);
const forbiddenRef = 'workflow.xml';
const excludedFiles = new Set([
path.join(projectRoot, 'src', 'core', 'tasks', 'workflow.xml'),
path.join(projectRoot, 'src', 'core', 'workflows', 'advanced-elicitation', 'workflow.xml'),
]);
const offenders = [];
const walk = async (dir) => {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
await walk(fullPath);
continue;
}
if (!allowedExtensions.has(path.extname(entry.name))) {
continue;
}
if (excludedFiles.has(fullPath)) {
continue;
}
const content = await fs.readFile(fullPath, 'utf8');
if (content.includes(forbiddenRef)) {
offenders.push(path.relative(projectRoot, fullPath));
}
}
};
for (const root of searchRoots) {
await walk(root);
}
assert(offenders.length === 0, 'No workflow.xml references outside XML source', offenders.length > 0 ? offenders.join(', ') : '');
} catch (error) {
assert(false, 'Workflow reference guard runs', error.message);
}
console.log('');
// ============================================================
// Summary
// ============================================================

View File

@ -148,7 +148,7 @@ class ManifestGenerator {
return workflows;
}
// Recursively find workflow.yaml files
// Recursively find workflow files
const findWorkflows = async (dir, relativePath = '') => {
const entries = await fs.readdir(dir, { withFileTypes: true });

View File

@ -304,7 +304,7 @@ class BaseIdeSetup {
if (entry.isDirectory() && entry.name !== 'core' && entry.name !== '_config' && entry.name !== 'agents') {
const moduleWorkflowsPath = path.join(bmadDir, entry.name, 'workflows');
if (await fs.pathExists(moduleWorkflowsPath)) {
const moduleWorkflows = await this.findWorkflowYamlFiles(moduleWorkflowsPath);
const moduleWorkflows = await this.findWorkflowFiles(moduleWorkflowsPath);
workflows.push(
...moduleWorkflows.map((w) => ({
...w,
@ -324,11 +324,11 @@ class BaseIdeSetup {
}
/**
* Recursively find workflow.yaml files
* Recursively find workflow files (workflow.yaml or workflow.md)
* @param {string} dir - Directory to search
* @returns {Array} List of workflow file info objects
*/
async findWorkflowYamlFiles(dir) {
async findWorkflowFiles(dir) {
const workflows = [];
if (!(await fs.pathExists(dir))) {
@ -342,14 +342,24 @@ class BaseIdeSetup {
if (entry.isDirectory()) {
// Recursively search subdirectories
const subWorkflows = await this.findWorkflowYamlFiles(fullPath);
const subWorkflows = await this.findWorkflowFiles(fullPath);
workflows.push(...subWorkflows);
} else if (entry.isFile() && entry.name === 'workflow.yaml') {
// Read workflow.yaml to get name and standalone property
} else if (entry.isFile() && (entry.name === 'workflow.yaml' || entry.name === 'workflow.md')) {
// Read workflow file to get name and standalone property
try {
const yaml = require('yaml');
const content = await fs.readFile(fullPath, 'utf8');
const workflowData = yaml.parse(content);
let workflowData = null;
if (entry.name === 'workflow.yaml') {
workflowData = yaml.parse(content);
} else {
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatterMatch) {
continue;
}
workflowData = yaml.parse(frontmatterMatch[1]);
}
if (workflowData && workflowData.name) {
// Workflows are standalone by default unless explicitly false

View File

@ -2,13 +2,13 @@ const path = require('node:path');
const fs = require('fs-extra');
const csv = require('csv-parse/sync');
const chalk = require('chalk');
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName } = require('./path-utils');
/**
* Generates command files for each workflow in the manifest
*/
class WorkflowCommandGenerator {
constructor(bmadFolderName = BMAD_FOLDER_NAME) {
constructor(bmadFolderName = 'bmad') {
this.templatePath = path.join(__dirname, '../templates/workflow-command-template.md');
this.bmadFolderName = bmadFolderName;
}
@ -67,10 +67,8 @@ class WorkflowCommandGenerator {
for (const workflow of allWorkflows) {
const commandContent = await this.generateCommandContent(workflow, bmadDir);
// Calculate the relative workflow path (e.g., bmm/workflows/4-implementation/sprint-planning/workflow.yaml)
let workflowRelPath = workflow.path || '';
// Normalize path separators for cross-platform compatibility
workflowRelPath = workflowRelPath.replaceAll('\\', '/');
// Calculate the relative workflow path (e.g., bmm/workflows/4-implementation/sprint-planning/workflow.md)
let workflowRelPath = workflow.path;
// Remove _bmad/ prefix if present to get relative path from project root
// Handle both absolute paths (/path/to/_bmad/...) and relative paths (_bmad/...)
if (workflowRelPath.includes('_bmad/')) {
@ -78,15 +76,9 @@ class WorkflowCommandGenerator {
if (parts.length > 1) {
workflowRelPath = parts.slice(1).join('/');
}
} else if (workflowRelPath.includes('/src/')) {
// Normalize source paths (e.g. .../src/bmm/...) to relative module path (e.g. bmm/...)
const match = workflowRelPath.match(/\/src\/([^/]+)\/(.+)/);
if (match) {
workflowRelPath = `${match[1]}/${match[2]}`;
}
}
// Determine if this is a YAML workflow (use normalized path which is guaranteed to be a string)
const isYamlWorkflow = workflowRelPath.endsWith('.yaml') || workflowRelPath.endsWith('.yml');
// Determine if this is a YAML workflow
const isYamlWorkflow = workflow.path.endsWith('.yaml') || workflow.path.endsWith('.yml');
artifacts.push({
type: 'workflow-command',
isYamlWorkflow: isYamlWorkflow, // For template selection
@ -133,8 +125,8 @@ class WorkflowCommandGenerator {
const template = await fs.readFile(templatePath, 'utf8');
// Convert source path to installed path
// From: /Users/.../src/bmm/workflows/.../workflow.yaml
// To: {project-root}/_bmad/bmm/workflows/.../workflow.yaml
// From: /Users/.../src/bmm/workflows/.../workflow.md
// To: {project-root}/_bmad/bmm/workflows/.../workflow.md
let workflowPath = workflow.path;
// Extract the relative path from source
@ -218,9 +210,9 @@ class WorkflowCommandGenerator {
## Execution
When running any workflow:
1. LOAD {project-root}/${this.bmadFolderName}/core/tasks/workflow.xml
1. LOAD {project-root}/${this.bmadFolderName}/core/tasks/workflow.md
2. Pass the workflow path as 'workflow-config' parameter
3. Follow workflow.xml instructions EXACTLY
3. Follow workflow.md instructions EXACTLY
4. Save outputs after EACH section
## Modes
@ -292,7 +284,7 @@ When running any workflow:
* Write workflow command artifacts using dash format (NEW STANDARD)
* Creates flat files like: bmad-bmm-correct-course.md
*
* Note: Workflows do NOT have bmad-agent- prefix - only agents do.
* Note: Workflows do NOT have .agent.md suffix - only agents do.
*
* @param {string} baseCommandsDir - Base commands directory for the IDE
* @param {Array} artifacts - Workflow artifacts

View File

@ -740,10 +740,10 @@ class ModuleManager {
}
}
// Check if this is a workflow.yaml file
if (file.endsWith('workflow.yaml')) {
// Check if this is a workflow file (YAML or MD)
if (file.endsWith('workflow.yaml') || file.endsWith('workflow.md')) {
await fs.ensureDir(path.dirname(targetFile));
await this.copyWorkflowYamlStripped(sourceFile, targetFile);
await this.copyWorkflowFileStripped(sourceFile, targetFile);
} else {
// Copy the file with placeholder replacement
await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile);
@ -757,12 +757,23 @@ class ModuleManager {
}
/**
* Copy workflow.yaml file with web_bundle section stripped
* Copy workflow file with web_bundle section stripped (YAML or MD)
* Preserves comments, formatting, and line breaks
* @param {string} sourceFile - Source workflow.yaml file path
* @param {string} targetFile - Target workflow.yaml file path
* @param {string} sourceFile - Source workflow file path
* @param {string} targetFile - Target workflow file path
*/
async copyWorkflowYamlStripped(sourceFile, targetFile) {
async copyWorkflowFileStripped(sourceFile, targetFile) {
if (sourceFile.endsWith('.md')) {
let mdContent = await fs.readFile(sourceFile, 'utf8');
mdContent = mdContent.replaceAll('_bmad', '_bmad');
mdContent = mdContent.replaceAll('_bmad', this.bmadFolderName);
mdContent = this.stripWebBundleFromFrontmatter(mdContent);
await fs.writeFile(targetFile, mdContent, 'utf8');
return;
}
// Read the source YAML file
let yamlContent = await fs.readFile(sourceFile, 'utf8');
@ -843,6 +854,20 @@ class ModuleManager {
}
}
stripWebBundleFromFrontmatter(content) {
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatterMatch) {
return content;
}
const frontmatter = frontmatterMatch[1]
.split('\n')
.filter((line) => !line.trim().startsWith('web_bundle:'))
.join('\n');
return content.replace(frontmatterMatch[0], `---\n${frontmatter}\n---`);
}
/**
* Compile .agent.yaml files to .md format in modules
* @param {string} sourcePath - Source module path
@ -1151,8 +1176,8 @@ class ModuleManager {
// Parse SOURCE workflow path
// Handle both _bmad placeholder and hardcoded 'bmad'
// Example: {project-root}/_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml
// Or: {project-root}/bmad/bmm/workflows/4-implementation/create-story/workflow.yaml
// Example: {project-root}/_bmad/bmm/workflows/4-implementation/create-story/workflow.md
// Or: {project-root}/bmad/bmm/workflows/4-implementation/create-story/workflow.md
const sourceMatch = sourceWorkflowPath.match(/\{project-root\}\/(?:_bmad)\/([^/]+)\/workflows\/(.+)/);
if (!sourceMatch) {
console.warn(chalk.yellow(` Could not parse workflow path: ${sourceWorkflowPath}`));
@ -1163,7 +1188,7 @@ class ModuleManager {
// Parse INSTALL workflow path
// Handle_bmad
// Example: {project-root}/_bmad/bmgd/workflows/4-production/create-story/workflow.yaml
// Example: {project-root}/_bmad/bmgd/workflows/4-production/create-story/workflow.md
const installMatch = installWorkflowPath.match(/\{project-root\}\/(_bmad)\/([^/]+)\/workflows\/(.+)/);
if (!installMatch) {
console.warn(chalk.yellow(` Could not parse workflow-install path: ${installWorkflowPath}`));
@ -1173,9 +1198,13 @@ class ModuleManager {
const installWorkflowSubPath = installMatch[2];
const sourceModulePath = getModulePath(sourceModule);
const actualSourceWorkflowPath = path.join(sourceModulePath, 'workflows', sourceWorkflowSubPath.replace(/\/workflow\.yaml$/, ''));
const actualSourceWorkflowPath = path.join(
sourceModulePath,
'workflows',
sourceWorkflowSubPath.replace(/\/workflow\.(yaml|md)$/, ''),
);
const actualDestWorkflowPath = path.join(targetPath, 'workflows', installWorkflowSubPath.replace(/\/workflow\.yaml$/, ''));
const actualDestWorkflowPath = path.join(targetPath, 'workflows', installWorkflowSubPath.replace(/\/workflow\.(yaml|md)$/, ''));
// Check if source workflow exists
if (!(await fs.pathExists(actualSourceWorkflowPath))) {
@ -1186,7 +1215,7 @@ class ModuleManager {
// Copy the entire workflow folder
console.log(
chalk.dim(
` Vendoring: ${sourceModule}/workflows/${sourceWorkflowSubPath.replace(/\/workflow\.yaml$/, '')}${moduleName}/workflows/${installWorkflowSubPath.replace(/\/workflow\.yaml$/, '')}`,
` Vendoring: ${sourceModule}/workflows/${sourceWorkflowSubPath.replace(/\/workflow\.(yaml|md)$/, '')}${moduleName}/workflows/${installWorkflowSubPath.replace(/\/workflow\.(yaml|md)$/, '')}`,
),
);
@ -1194,9 +1223,13 @@ class ModuleManager {
// Copy the workflow directory recursively with placeholder replacement
await this.copyDirectoryWithPlaceholderReplacement(actualSourceWorkflowPath, actualDestWorkflowPath);
// Update the workflow.yaml config_source reference
// Update workflow config_source references
const workflowMdPath = path.join(actualDestWorkflowPath, 'workflow.md');
const workflowYamlPath = path.join(actualDestWorkflowPath, 'workflow.yaml');
if (await fs.pathExists(workflowYamlPath)) {
if (await fs.pathExists(workflowMdPath)) {
await this.updateWorkflowConfigSource(workflowMdPath, moduleName);
} else if (await fs.pathExists(workflowYamlPath)) {
await this.updateWorkflowConfigSource(workflowYamlPath, moduleName);
}
}
@ -1208,24 +1241,24 @@ class ModuleManager {
}
/**
* Update workflow.yaml config_source to point to new module
* @param {string} workflowYamlPath - Path to workflow.yaml file
* Update workflow config_source/main_config to point to new module
* @param {string} workflowPath - Path to workflow file
* @param {string} newModuleName - New module name to reference
*/
async updateWorkflowConfigSource(workflowYamlPath, newModuleName) {
let yamlContent = await fs.readFile(workflowYamlPath, 'utf8');
async updateWorkflowConfigSource(workflowPath, newModuleName) {
let fileContent = await fs.readFile(workflowPath, 'utf8');
// Replace config_source: "{project-root}/_bmad/OLD_MODULE/config.yaml"
// with config_source: "{project-root}/_bmad/NEW_MODULE/config.yaml"
// Note: At this point _bmad has already been replaced with actual folder name
const configSourcePattern = /config_source:\s*["']?\{project-root\}\/[^/]+\/[^/]+\/config\.yaml["']?/g;
const newConfigSource = `config_source: "{project-root}/${this.bmadFolderName}/${newModuleName}/config.yaml"`;
const configSourcePattern = /(config_source|main_config):\s*["']?\{project-root\}\/[^/]+\/[^/]+\/config\.yaml["']?/g;
const newConfigSource = `$1: "{project-root}/${this.bmadFolderName}/${newModuleName}/config.yaml"`;
const updatedYaml = yamlContent.replaceAll(configSourcePattern, newConfigSource);
const updatedContent = fileContent.replaceAll(configSourcePattern, newConfigSource);
if (updatedYaml !== yamlContent) {
await fs.writeFile(workflowYamlPath, updatedYaml, 'utf8');
console.log(chalk.dim(` Updated config_source to: ${this.bmadFolderName}/${newModuleName}/config.yaml`));
if (updatedContent !== fileContent) {
await fs.writeFile(workflowPath, updatedContent, 'utf8');
console.log(chalk.dim(` Updated workflow config to: ${this.bmadFolderName}/${newModuleName}/config.yaml`));
}
}