Compare commits

...

3 Commits

Author SHA1 Message Date
OverlordBaconPants 5a82b700e3
Merge f2a942b2db into ba890779a2 2026-02-03 14:13:43 -05:00
Michael Pursifull ba890779a2
feat: cross-file reference validator for BMAD source files (#1494)
* feat: add cross-file reference validator for CI

Add tools/validate-file-refs.js that validates cross-file references
in BMAD source files (agents, workflows, tasks, steps). Catches broken
file paths, missing referenced files, wrong extensions, and absolute
path leaks before they reach users.

Addresses broken-file-ref and path-handling bug classes which account
for 25% of all historical bugs (59 closed issues, 129+ comments).

- Scans src/ for YAML, markdown, and XML files
- Validates {project-root}/_bmad/ references against source tree
- Checks relative path references, exec attributes, invoke-task tags
- Detects absolute path leaks (/Users/, /home/, C:\)
- Adds validate:refs npm script and CI step in quality.yaml

* feat: strip JSON example blocks to reduce false-positive broken refs

Add stripJsonExampleBlocks() to the markdown reference extractor so
bare JSON example/template blocks (braces on their own lines) are
removed before pattern matching. This prevents paths inside example
data from being flagged as broken references.

* feat: add line numbers, fix utility/ path mapping, improve verbose output

- Add utility/ to direct path mapping (was incorrectly falling through
  to src/modules/utility/)
- Show line numbers for broken references in markdown files
- Show YAML key path for broken references in YAML files
- Print file headers in verbose mode for all files with refs

* fix: correct verbose [OK]/[BROKEN] overlap and line number drift

Broken refs no longer print [OK] before [BROKEN] in --verbose mode.
Code block stripping now preserves newlines so offsetToLine() reports
accurate line numbers when code blocks precede broken references.

* fix: address review feedback, add CI annotations and step summary

Address alexeyv's review findings on PR #1494:
- Fix exec-attr prefix handling for {_bmad}/ and bare _bmad/ paths
- Fix mapInstalledToSource fallback (remove phantom src/modules/ mapping)
- Switch extractYamlRefs to parseDocument() for YAML line numbers

Add CI integration (stories 2-1, 2-2):
- Emit ::warning annotations for broken refs and abs-path leaks
- Write markdown table to $GITHUB_STEP_SUMMARY
- Guard both behind environment variable checks

Harden CI output:
- escapeAnnotation() encodes %, \r, \n per GitHub Actions spec
- escapeTableCell() escapes pipe chars in step summary table

---------

Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
Co-authored-by: Brian <bmadcode@gmail.com>
2026-02-03 13:13:38 -06:00
OverlordBaconPants f2a942b2db Add Teachers Assistant educational agent and documentation 2026-01-25 08:12:13 -05:00
10 changed files with 1568 additions and 0 deletions

View File

@ -113,3 +113,6 @@ jobs:
- name: Test agent compilation components
run: npm run test:install
- name: Validate file references
run: npm run validate:refs

View File

@ -0,0 +1,371 @@
---
title: "Build a Complete Web App Using BMAD Method Workflows"
---
Use the BMAD Method workflows to build a complete web application from initial idea to deployed code with comprehensive planning and testing. This guide follows the development of a simple Habit Tracker app to illustrate the concepts, but these same workflows apply to any web application project.
## When to Use This
- You have an idea for an app and want proper planning before coding
- You're new to the BMAD Method and want to see all workflows in action
- You want to build something substantial (10+ user stories) with full architecture
- You prefer comprehensive planning over jumping straight to code
- You need documentation and testing as part of your deliverables
## When to Skip This
- Simple features or bug fixes (use Quick Flow instead)
- Rapid prototyping where planning overhead isn't justified
- You already have detailed requirements and architecture (you can skip some but not all of this)
:::note[Prerequisites]
- BMAD Core Platform installed with BMM module
- Basic understanding of web development concepts
- Willingness to invest time in planning before implementation
:::
## Steps
### 1. Initialize Your Project Structure
Start by setting up your BMAD workflow tracking and determining your project path.
**Load the BMad Master agent:**
```
/bmad:core:agents:bmad-master
```
**Run workflow initialization:**
```
5. [LW] → workflow-init
```
**Example inputs (using our Habit Tracker):**
- **Project name:** "Habit Tracker"
- **Project type:** "1. New project (greenfield)" *(or brownfield for existing codebases)*
- **Planning approach:** "1. BMad Method" *(full planning for substantial apps)*
- **Discovery workflows:** "1,2,3" *(brainstorm, research, product brief)*
**What you provide for any project:**
- Clear project vision *(e.g., "solve my productivity problem", "showcase my work", "help local businesses")*
- Technology constraints *(e.g., "React/Node", "vanilla JS", "WordPress theme", though the workflow will guide you to a tech stack if you'd like)*
- Success criteria *(e.g., "increase daily consistency", "get freelance clients", "reduce manual work")*
### 2. Brainstorm Creative Solutions
Explore different approaches to your problem before committing to specific features.
**Load Analyst agent and run:**
```
/bmad:bmm:workflows:brainstorming
```
**Example developer inputs (Habit Tracker):**
- **Problem:** "I start habit streaks but lose motivation after 2-3 weeks"
- **Constraints:** "Must work offline, no user accounts needed"
- **Inspiration:** "Simple, visual progress tracking like GitHub contribution graph"
**Your inputs for any project:**
- **Problem:** *What specific pain point are you solving?*
- **Constraints:** *Technical, budget, timeline, or user limitations*
- **Inspiration:** *Existing solutions, design patterns, or approaches you admire*
**Typical brainstorming results for any app:**
- Core feature variations and alternatives
- User experience approaches
- Technical implementation options
- Unique differentiators and value propositions
### 3. Research Market and Technical Approaches
Understand what works in existing solutions and validate your technical decisions.
**Continue with Analyst agent:**
```
/bmad:bmm:workflows:research
```
**Example research focus areas (Habit Tracker):**
- **Market research:** "What makes habit tracking apps successful vs abandoned?"
- **Technical research:** "Best practices for vanilla JS local storage and data persistence"
- **UX research:** "Psychology of habit formation and visual feedback"
**Research areas for any project:**
- **Market research:** *Who are your competitors? What do users actually need?*
- **Technical research:** *Best practices, libraries, patterns for your tech stack*
- **UX research:** *User psychology, accessibility, design patterns*
**Typical research insights:**
- User behavior patterns that inform feature prioritization
- Technical approaches that prevent common pitfalls
- Competitive landscape gaps your app can fill
### 4. Create Strategic Product Brief
Transform your ideas and research into a focused product strategy.
**Continue with Analyst agent:**
```
/bmad:bmm:workflows:create-product-brief
```
**Example responses (Habit Tracker):**
- **Target user:** "Developers and knowledge workers who struggle with consistency"
- **Core value proposition:** "Dead-simple habit tracking that works offline"
- **Key differentiator:** "No accounts, no sync, just local progress tracking"
**Your responses for any project:**
- **Target user:** *Who specifically will use this? What are their pain points?*
- **Core value proposition:** *What's the main benefit you're delivering?*
- **Key differentiator:** *How is your approach unique or better?*
**Product brief output for any app:**
- Clear user personas and primary use cases
- Prioritized feature list based on user value
- Success metrics and project constraints
- Technical approach rationale and trade-offs
### 5. Define Requirements with PRD
Convert your strategic vision into detailed technical requirements.
**Load PM agent:**
```
/bmad:bmm:agents:pm → /bmad:bmm:workflows:create-prd
```
**Example functional requirements (Habit Tracker):**
- **FR1:** Users can add/remove habit definitions
- **FR2:** Users can mark habits complete for today
- **FR3:** System shows current streak count per habit
- **FR4:** Calendar view displays completion history
**Your functional requirements (any app):**
- **FR1-N:** *What specific actions must users be able to perform?*
- **FR1-N:** *What data must the system track and display?*
- **FR1-N:** *What business logic must the system implement?*
**Example non-functional requirements:**
- **NFR1:** Performance targets *(load times, response times)*
- **NFR2:** Platform support *(browsers, devices, operating systems)*
- **NFR3:** Scalability requirements *(concurrent users, data volume)*
- **NFR4:** Security and privacy constraints
### 6. Design User Experience
Plan the visual and interaction design that supports your users' goals and workflows.
**Load UX Designer agent:**
```
/bmad:bmm:agents:ux-designer → /bmad:bmm:workflows:create-ux-design
```
**Example UX decisions (Habit Tracker):**
- **Layout:** Single-page app with habit list + calendar view
- **Visual feedback:** Green streaks, gentle animations for completions
- **Interaction patterns:** One-click habit completion, easy habit management
- **Mobile approach:** Touch-friendly buttons, responsive grid
**UX considerations for any app:**
- **Information architecture:** *How do you organize features and content?*
- **Visual hierarchy:** *What gets user attention first, second, third?*
- **Interaction patterns:** *How do users accomplish their primary tasks?*
- **Responsive design:** *How does the experience adapt across devices?*
### 7. Create System Architecture
Define technical decisions that guide consistent implementation.
**Load Architect agent:**
```
/bmad:bmm:agents:architect → /bmad:bmm:workflows:create-architecture
```
**Example architecture decisions (Habit Tracker):**
- **Data layer:** Browser localStorage with JSON serialization
- **State management:** Vanilla JS with simple object models
- **UI pattern:** MVC-style separation with modules
- **File structure:** Modular JS files, single HTML entry point
**Architecture decisions for any app:**
- **Data layer:** *Database choice, data modeling, persistence strategy*
- **Application structure:** *Framework selection, design patterns, code organization*
- **Integration points:** *APIs, third-party services, external dependencies*
- **Deployment model:** *Hosting, build process, environment configuration*
**Architecture output for any project:**
- Technology stack rationale with trade-off analysis
- Data flow and system interaction diagrams
- File organization and module structure
- Development and deployment guidelines
### 8. Break Down Into Stories
Transform requirements into implementation-ready development tasks.
**Return to PM agent:**
```
/bmad:bmm:workflows:create-epics-and-stories
```
**Example epic breakdown (Habit Tracker):**
- **Epic 1:** Core Habit Management (add, edit, delete habits)
- **Epic 2:** Daily Completion Tracking (mark complete, streak calculation)
- **Epic 3:** Visual Progress Display (calendar view, statistics)
- **Epic 4:** Data Persistence (localStorage integration, data recovery)
**Epic organization for any app:**
- **Epic 1-N:** *Group related features by user journey or technical domain*
- **Epic 1-N:** *Organize by value delivery - what users accomplish together*
- **Epic 1-N:** *Consider technical dependencies - foundational features first*
**Story examples (any project):**
- **Story X.Y:** As a [user type], I can [action] so that [benefit]
- **Story X.Y:** As a [user type], I can [action] so that [benefit]
- **Story X.Y:** As a [user type], I can [action] so that [benefit]
### 9. Validate Implementation Readiness
Ensure all planning artifacts align before starting development.
**Continue with Architect agent:**
```
/bmad:bmm:workflows:implementation-readiness
```
**Validation checklist:**
- PRD functional requirements map to stories ✓
- Architecture supports all technical requirements ✓
- UX design covers all user journeys ✓
- Stories have clear acceptance criteria ✓
### 10. Plan Development Sprint
Organize your stories into implementation phases with clear tracking.
**Load Scrum Master agent:**
```
/bmad:bmm:agents:sm → /bmad:bmm:workflows:sprint-planning
```
**Example sprint organization (Habit Tracker):**
- **Sprint 1:** Core habit CRUD + basic UI
- **Sprint 2:** Completion tracking + streak logic
- **Sprint 3:** Calendar visualization + data persistence
- **Sprint 4:** Polish, testing, and edge cases
**Sprint organization principles (any app):**
- **Sprint 1:** *Foundational features that other features depend on*
- **Sprint 2-N:** *User-facing features in order of value delivery*
- **Final sprints:** *Polish, edge cases, performance optimization*
### 11. Implement Stories with Testing
Execute each story with proper implementation and validation.
**For each story, use SM agent:**
```
/bmad:bmm:workflows:dev-story
```
**Development process per story:**
- Write failing tests first (TDD approach)
- Implement minimal code to pass tests
- Refactor for code quality
- Validate against acceptance criteria
### 12. Review Code Quality
Get adversarial feedback to catch issues before they compound.
**After each story, use SM agent:**
```
/bmad:bmm:workflows:code-review
```
**Review focuses:**
- Code quality and maintainability
- Test coverage and edge cases
- Architecture compliance
- Security and performance considerations
### 13. Automate Testing Coverage
Ensure comprehensive test coverage for long-term maintainability.
**Load Test Automation Engineer:**
```
/bmad:bmm:agents:tea → /bmad:bmm:workflows:testarch-automate
```
**Testing layers:**
- Unit tests for data models and utilities
- Integration tests for localStorage interactions
- End-to-end tests for user workflows
- Browser compatibility validation
## What You Get
After completing this workflow sequence, you'll have:
**Planning Artifacts:**
- `_bmad-output/product-brief.md` - Strategic product vision
- `_bmad-output/PRD.md` - Detailed requirements document
- `_bmad-output/ux-design.md` - Visual and interaction design
- `_bmad-output/architecture.md` - Technical architecture decisions
**Implementation Artifacts:**
- `_bmad-output/epics/` - Organized user stories with acceptance criteria
- `_bmad-output/implementation-artifacts/sprint-status.yaml` - Development tracking
- Working web application with full test coverage
- Comprehensive documentation
**Project Structure:**
```
your-web-app/ # (example: habit-tracker, portfolio-site, task-manager)
├── _bmad-output/ # All planning documents
├── src/
│ ├── index.html # Main application entry
│ ├── js/
│ │ ├── app.js # Main application logic
│ │ ├── [feature]-manager.js # Core business logic modules
│ │ ├── [component].js # UI components
│ │ └── [utility].js # Helper utilities
│ ├── css/
│ │ └── styles.css # Application styles
│ └── tests/
│ ├── unit/ # Unit test files
│ └── integration/ # Integration tests
└── README.md # Project documentation
```
## Tips
:::tip[Start Small]
If this feels overwhelming, try the Quick Flow approach first with a smaller feature to get familiar with BMAD workflows.
:::
:::tip[Document Decisions]
Each workflow creates artifacts that inform subsequent workflows. Don't skip documentation - it prevents rework later.
:::
:::tip[Iterate on Planning]
Use the `correct-course` workflow if you discover new requirements during implementation.
:::
## Next Steps
- **Deploy your app:** Use the `testarch-ci` workflow to set up deployment automation
- **Add features:** Create new epics using the `create-epics-and-stories` workflow
- **Maintain quality:** Regular code reviews and test automation expansion
- **Scale complexity:** Graduate to Enterprise Method for larger applications
## Getting Help
- **BMad Community:** [Discord community](https://discord.gg/bmad-method)
- **Documentation:** [Complete workflow reference](https://docs.bmad-method.org/)
- **Issues:** [GitHub repository](https://github.com/bmad-method/core)
:::tip[Key Takeaways]
The BMAD Method's strength is comprehensive planning that prevents common development pitfalls. Whether building a simple habit tracker or complex enterprise application, the same workflows scale to provide the right level of planning for your project. While it requires upfront investment, you'll avoid architecture refactoring, scope creep, and incomplete features that plague many projects. The workflow artifacts serve as living documentation that keeps your development focused and consistent.
:::

View File

@ -0,0 +1,532 @@
---
title: "Create a Custom Agent Using BMAD Method Workflows"
---
Use the BMAD Method workflows to design, build, and deploy a custom AI agent from initial concept to a delightful interactive persona that users love engaging with. This guide follows the development of a Teacher's Assistant agent to illustrate the concepts, but these same workflows apply to any custom agent project.
## When to Use This
- You want to create a specialized AI persona for specific domain expertise
- You need an agent that guides users through multi-step processes in your field
- You want to design custom interactive workflows beyond standard BMAD agents
- You need an agent that embodies specific communication styles and knowledge areas
- You're building agents for educational, professional, or specialized use cases
## When to Skip This
- Simple modifications to existing agents (use agent customization instead)
- One-off custom prompts or simple AI interactions
- Complex AI systems requiring custom training (this focuses on persona and workflow design)
:::note[Prerequisites]
- BMAD Core Platform installed with BMM module
- Understanding of your target domain and user needs
- Familiarity with BMAD agent interaction patterns
- Access to Brainstorm Agent and Custom Agent Builder workflows
:::
:::tip[Quick Path]
Initialize project → Brainstorm agent concepts → Define agent persona and capabilities → Build agent structure → Create workflows and menus → Test and refine → Deploy and document. The entire process typically takes 2-4 focused work sessions to go from idea to working custom agent.
:::
## Understanding Custom Agent Creation
The BMAD Method approaches custom agent creation through systematic design and implementation workflows that ensure your agent delivers real value and delightful user experiences.
| Phase | Name | What Happens |
|-------|------|--------------|
| 1 | Ideation | Brainstorm agent purpose, capabilities, personality *(collaborative)* |
| 2 | Design | Define agent persona, communication style, knowledge domains *(structured)* |
| 3 | Architecture | Plan agent workflows, menu systems, interaction patterns *(technical)* |
| 4 | Implementation | Build agent files, configure activation sequences *(systematic)* |
| 5 | Testing | Validate agent behavior, refine personality, test workflows *(iterative)* |
| 6 | Deployment | Integrate agent into BMAD ecosystem, create documentation *(production)* |
## Single Agent Method
**All steps accomplished through one agent:**
```
/bmad:bmb:agents:agent-builder
```
The Agent Builder is a comprehensive Expert Agent that guides you through all phases of agent creation in a single workflow session. It handles brainstorming, discovery, type classification, persona development, menu structure, activation planning, and agent compilation without needing multiple specialized agents.
## Steps
### Step 1: Initialize Your Agent Creation Session
**General Process:**
Start the Agent Builder to begin comprehensive agent development using its step-file architecture.
```
/bmad:bmb:agents:agent-builder
3. [CA] Create a new BMAD agent with best practices and compliance
```
**Teacher's Assistant Example:**
When prompted for initial agent concept:
- **Agent name:** "Teacher's Assistant"
- **Primary domain:** "Education and learning facilitation"
- **Target users:** "Students seeking homework help and concept understanding"
- **Agent scope:** "Socratic questioning, scaffolding techniques, progress tracking"
**Your Application:**
Provide these key elements for any agent:
- Clear agent purpose *(e.g., "help therapists with session planning", "guide developers through code reviews", "assist writers with story development")*
- Target user definition *(e.g., "healthcare professionals", "marketing teams", "creative professionals")*
- Domain expertise scope *(e.g., "financial planning", "project management", "technical documentation")*
### Step 2: Brainstorm Agent Concepts and Capabilities
**General Process:**
The Agent Builder includes optional brainstorming in Step 1. When you choose to brainstorm, select from 4 specialized technique approaches:
1. **User-Selected Techniques** - Browse the complete technique library
2. **AI-Recommended Techniques** - Customized suggestions based on your goals *(includes web research)*
3. **Random Technique Selection** - Discover unexpected creative methods
4. **Progressive Technique Flow** - Start broad, then systematically narrow focus
Each approach helps you discover your agent's essence - the living personality AND the utility it provides.
**Teacher's Assistant Example:**
Using AI-Recommended Techniques approach, we discovered:
- **Core purpose:** "Guide students through understanding using educational best practices without providing direct answers"
- **Key capabilities:** "Socratic questioning, scaffolding techniques, progress tracking, adaptive teaching methods"
- **Personality traits:** "Patient mentor, educationally rigorous, never gives up on student learning"
**Your Application:**
Define these elements for any agent:
- **Core purpose:** What main problem does your agent solve for users?
- **Key capabilities:** What specific tasks should your agent excel at?
- **Personality traits:** How should your agent communicate and behave?
### Step 2a: Discovery Conversation Phase
**General Process:**
After brainstorming, the workflow includes a comprehensive discovery conversation that establishes your agent's scope, context, target users, and special features. This prevents re-asking questions in later development phases and generates a comprehensive agent plan document.
**Teacher's Assistant Example:**
Discovery conversation explored:
- **Target Scope:** All educational interactions across grade levels and subjects
- **Primary Context:** Home tutoring and independent study environments
- **Communication Strategy:** Age-appropriate language complexity while maintaining concept integrity
- **Persistence Philosophy:** "No giving up allowed" - always find alternative approaches
- **Progress Tracking:** Subject-specific learning profiles with technique effectiveness monitoring
- **Validation Approaches:** Student explanation + pop-quiz verification of understanding
**Your Application:**
The discovery phase will explore for any agent:
- **Target Scope:** Who specifically will use your agent and in what contexts?
- **Primary Context:** Where and how will your agent be used most frequently?
- **Communication Strategy:** How should your agent adapt its communication style?
- **Core Philosophy:** What principles guide your agent's decision-making?
- **Special Features:** What unique capabilities set your agent apart?
### Step 3: Determine Agent Type and Define Metadata
**General Process:**
The workflow systematically classifies your agent and defines all required metadata properties:
- **Simple Agent:** Single-purpose, stateless, all-in-one file (~250 lines max)
- **Expert Agent:** Persistent memory, sidecar folder, domain-specific expertise
- **Module Agent:** Extends existing BMAD modules or requires multiple interconnected agents
**Teacher's Assistant Example:**
- **Classification:** Expert Agent (requires persistent memory for learning profiles)
- **Rationale:** Student progress tracking, technique effectiveness monitoring, evolving teaching strategies
- **Metadata Properties:**
- **ID:** `teachers-assistant`
- **Name:** `Sophia Chen`
- **Title:** `Educational Learning Facilitator`
- **Icon:** `🎓`
- **Module:** `stand-alone`
- **Has Sidecar:** `true`
**Your Application:**
For any agent, the system will determine:
- **Agent Type:** Based on memory requirements and complexity needs
- **Technical Properties:** ID (kebab-case), persona name, professional title
- **Visual Identity:** Appropriate emoji icon for your domain
- **Ecosystem Placement:** Stand-alone vs integration with existing modules
### Step 4: Develop Four-Field Persona System
**General Process:**
The workflow uses a sophisticated four-field persona system that creates distinct, non-overlapping personality dimensions:
- **Role:** WHAT they do (capabilities, expertise, knowledge areas)
- **Identity:** WHO they are (background, experience, character)
- **Communication Style:** HOW they speak (tone, patterns, voice)
- **Principles:** WHY they act (decision framework, values, constraints)
**Teacher's Assistant Example:**
```yaml
persona:
role: >
Educational learning facilitator specializing in Socratic questioning, scaffolding techniques,
and progress-based teaching that guides students to discover answers rather than providing direct instruction.
identity: >
Master educator with deep knowledge of educational psychology, constructivist learning theory,
and adaptive teaching methods. Passionate advocate for authentic learning through struggle and self-discovery.
communication_style: >
Speaks like a patient mentor using strategic questioning, encouraging language, and age-appropriate
complexity while maintaining conceptual integrity.
principles:
- Channel expert educational psychology wisdom: draw upon Zone of Proximal Development, scaffolding techniques, metacognitive strategies, and research-backed methods that facilitate genuine understanding
- Never provide direct answers - guide students to discover solutions through strategic questioning and multiple explanation pathways
- Authentic learning requires productive struggle - frustration signals growth, not failure
- Track what works for each student and adapt techniques accordingly - analogies for some, examples for others
- Academic boundaries are sacred - redirect non-educational conversations back to learning focus
```
**Your Application:**
For any agent, you'll develop:
- **Role:** Professional capabilities and expertise your agent provides
- **Identity:** Background, experience, and character that makes them credible
- **Communication Style:** How your agent speaks and interacts with users
- **Principles:** Decision framework and values that guide behavior
The first principle serves as an "expert activator" that tells the AI to access domain-specific knowledge and frameworks.
### Step 5: Commands & Menu Structure Design
**General Process:**
Transform discovered capabilities into structured menu commands following BMAD patterns:
- **Capability Review:** Analyze all capabilities from the discovery phase
- **Command Grouping:** Organize related capabilities under logical command areas
- **Menu Pattern Application:** Follow BMAD Expert Agent menu structure requirements
- **Trigger Design:** Create intuitive 2-letter codes and fuzzy match patterns
- **Handler Definition:** Map commands to specific prompts or actions
**Teacher's Assistant Example:**
Created 9 educational commands with Expert Agent architecture:
```yaml
critical_actions:
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/learning-profiles.md'
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/technique-tracking.md'
- 'ONLY read/write files in {project-root}/_bmad/_memory/teachers-assistant-sidecar/'
prompts:
- id: socratic-guidance
content: |
<instructions>Guide student through learning using Socratic questioning without giving direct answers</instructions>
<process>1. Ask strategic questions 2. Use student interests for analogies 3. Encourage discovery 4. Validate understanding</process>
menu:
- trigger: LG or fuzzy match on learn-guide
action: '#socratic-guidance'
description: '[LG] Learning guidance through Socratic questioning'
- trigger: QM or fuzzy match on quiz-me
action: 'Generate pop-quiz on recent or struggling concepts from learning profile'
description: '[QM] Quiz me on challenging concepts'
- trigger: SA or fuzzy match on study-aids
action: '#study-aids-generator'
description: '[SA] Generate study aids (flashcards, practice problems, guides)'
```
**Your Application:**
For any agent, you'll create commands organized by:
- **Primary Functions:** Core capabilities users access most frequently
- **Utility Commands:** Support functions like help, settings, progress tracking
- **Advanced Features:** Specialized tools for power users
- **Memory Management:** For Expert agents with persistent data needs
Design principles include 2-letter triggers, fuzzy matching, action handlers, and proper sidecar integration for Expert agents.
### Step 6: Activation Planning
**General Process:**
Define how your agent behaves when it starts up through critical actions and startup sequences:
- **Reference Loading:** Understanding critical action patterns
- **Routing Decision:** Determining build path (Simple/Expert/Module) based on architecture
- **Activation Needs Discussion:** Deciding autonomous vs responsive behavior patterns
- **Critical Actions Definition:** Specifying startup commands for memory loading and boundaries
**Teacher's Assistant Example:**
```yaml
activation:
hasCriticalActions: true
rationale: "Agent needs to auto-load student learning context to provide personalized educational guidance"
criticalActions:
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/learning-profiles.md'
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/technique-tracking.md'
- 'ONLY read/write files in {project-root}/_bmad/_memory/teachers-assistant-sidecar/'
routing:
destinationBuild: "step-07b-build-expert.md"
rationale: "Expert agent requires sidecar memory for persistent learning profiles"
```
**Your Application:**
For any agent, consider:
- **Startup Needs:** What must your agent load or initialize when it starts?
- **Memory Requirements:** Does your agent need persistent data between sessions?
- **Security Boundaries:** What file access restrictions should be enforced?
- **Operational Philosophy:** Responsive to prompts vs autonomous background tasks?
Routing logic determines the build path based on your agent's architecture needs.
### Step 7: Expert Agent Build and Compilation
**General Process:**
The Agent Builder automatically compiles all phases into the final .agent.yaml file:
1. **Generates Agent YAML:** Combines persona, menu, activation, and metadata
2. **Creates Sidecar Structure:** Sets up memory folders for Expert agents
3. **Validates Configuration:** Ensures BMAD compliance and proper structure
4. **Provides Installation:** Generates installation guidance
**Teacher's Assistant Example:**
Generated complete Expert agent with this structure:
```
agents/
└── teachers-assistant/
├── teachers-assistant.agent.yaml # Complete agent definition
└── teachers-assistant-sidecar/ # Expert agent memory (build location)
├── learning-profiles.md # Student progress and preferences
├── technique-tracking.md # Teaching method effectiveness data
└── README.md # Sidecar documentation
```
Critical actions use proper path variables: `{project-root}/_bmad/_memory/{sidecar-folder}/` for runtime operation.
**Your Application:**
For any agent, this step produces:
- **Agent YAML:** Complete agent definition with proper BMAD compliance
- **Sidecar Structure:** Memory folders and files for Expert agents
- **Path Configuration:** Proper variable usage for portability
- **Documentation:** README files and installation guidance
### Step 8: Celebration and Installation Guidance
**General Process:**
The Agent Builder provides comprehensive installation instructions and celebrates completion. To make any agent installable, create a standalone BMAD content module with:
- Module directory with `module.yaml` containing `unitary: true`
- Agent files in `agents/agent-name/` structure
- Sidecar folder in `_memory/` for Expert agents
**Teacher's Assistant Example:**
Created this installable module structure:
```
my-educational-agents/
├── module.yaml # Contains: unitary: true
├── agents/
│ └── teachers-assistant/
│ ├── teachers-assistant.agent.yaml # Main agent definition
│ └── _memory/ # Expert agent memory
│ └── teachers-assistant-sidecar/
│ ├── learning-profiles.md
│ ├── technique-tracking.md
│ └── README.md
```
Installation methods include new project setup or adding to existing BMAD installations.
**Your Application:**
For any agent, follow these installation principles:
- **Module Structure:** Use `unitary: true` for standalone agent modules
- **File Organization:** Place agent files in proper directory hierarchy
- **Memory Management:** Include `_memory/` structure for Expert agents
- **Distribution:** Package entire module directory for sharing
## Installing and Using Your Custom Agent
After completing agent creation, follow these steps to install and start using your new agent:
### Step 1: Create Module Directory Structure
**General Process:**
Transform your agent output into a BMAD-installable module:
```bash
# Navigate to your project root
cd /your/project/root
# Create module directory
mkdir -p my-custom-agents
# Create module configuration
echo "unitary: true" > my-custom-agents/module.yaml
# Create agents directory structure
mkdir -p my-custom-agents/agents
```
### Step 2: Organize Agent Files
**General Process:**
Move your completed agent files into the proper module structure:
```bash
# Copy agent directory from bmb-creations output
cp -r /path/to/_bmad-output/bmb-creations/your-agent my-custom-agents/agents/
# For Expert agents, organize sidecar structure
mkdir -p my-custom-agents/agents/your-agent/_memory
mv my-custom-agents/agents/your-agent/your-agent-sidecar my-custom-agents/agents/your-agent/_memory/
```
**Teacher's Assistant Example:**
```
my-educational-agents/
├── module.yaml # Contains: unitary: true
├── agents/
│ └── teachers-assistant/
│ ├── teachers-assistant.agent.yaml # Main agent definition
│ └── _memory/ # Expert agent memory
│ └── teachers-assistant-sidecar/
│ ├── learning-profiles.md
│ ├── technique-tracking.md
│ └── README.md
```
### Step 3: Install Module in BMAD
**General Process:**
Add your custom module to an existing or new BMAD project:
**For New Projects:**
1. Run BMAD installer: `npx @bmad-method/cli init`
2. When prompted for local modules, provide the path to your module
3. Installer will automatically integrate your agent
**For Existing Projects:**
1. Run: `npx @bmad-method/cli modify`
2. Select "Add local custom module"
3. Provide path to your module directory
4. Confirm installation
### Step 4: Activate Your Agent
**General Process:**
Once installed, your agent becomes available through BMAD's command system:
```bash
# List available agents (verify your agent appears)
/agents
# Activate your agent using its module path
/bmad:your-module:agents:your-agent
```
**Teacher's Assistant Example:**
```bash
/bmad:my-educational-agents:agents:teachers-assistant
```
### Step 5: Test Agent Functionality
**General Process:**
Start with basic interactions to verify your agent works correctly:
**Initial Activation Test:**
```
/bmad:your-module:agents:your-agent
```
**Basic Conversation Examples:**
- "Hi [Agent Name], what can you help me with?"
- "Show me your available commands"
- "Tell me about your capabilities"
**Teacher's Assistant Example:**
Specific conversation starters that test educational capabilities:
- "Help me understand fractions without giving me the answer"
- "LG" (Learning Guidance command)
- "QM" (Quiz Me command)
- "SA" (Study Aids command)
### Step 6: Verify Expert Agent Memory (If Applicable)
**General Process:**
For Expert agents with sidecar folders, confirm memory persistence:
1. **Start agent and interact with memory commands**
2. **Update profiles or tracking data**
3. **Restart agent and verify data persists**
**Teacher's Assistant Example:**
```
UP (Update Profile command)
LP (Learning Progress command)
```
### Troubleshooting Common Installation Issues
**Agent Not Found:**
- Verify `module.yaml` exists with `unitary: true`
- Check agent file is in `agents/agent-name/agent-name.agent.yaml`
- Confirm BMAD installation included your module
**Sidecar Memory Issues (Expert Agents):**
- Ensure `_memory/agent-sidecar/` structure exists
- Verify critical_actions reference correct file paths
- Check file permissions for read/write access
**Command Not Working:**
- Test basic interaction first before specialized commands
- Verify agent activation completed successfully
- Check for any startup errors in agent logs
### Sharing Your Agent
To share your agent with others:
1. **Package entire module directory:** `my-custom-agents/`
2. **Include installation instructions:** Reference this guide
3. **Provide example interactions:** Show how to use key features
4. **Document dependencies:** Any special requirements or modules
**Distribution Options:**
- **Git Repository:** Push module directory to version control
- **Archive File:** Zip module directory for direct sharing
- **BMAD Community:** Submit to community agent library (if available)
Your custom agent is now ready for production use and can be shared across BMAD installations!
## Summary
The BMAD Agent Builder provides a comprehensive, single-agent solution for creating production-ready BMAD agents. Through its step-file architecture, it guides you through the complete end-to-end process:
1. **Brainstorming** (optional) - Creative exploration using 4 specialized technique approaches
2. **Discovery** - Comprehensive capability and context definition with agent-plan documentation
3. **Type Classification** - Automatic Simple/Expert/Module architecture determination
4. **Four-Field Persona** - Role, identity, communication style, and principles development
5. **Commands & Menu** - Structured command interface with BMAD compliance
6. **Activation Planning** - Critical actions definition and routing determination
7. **Agent Build** - Complete YAML file generation with sidecar structure
8. **Installation Guidance** - Module packaging instructions and testing recommendations
**Complete Agent Creation in One Session:**
```
/bmad:bmb:agents:agent-builder → [CA] Create a new BMAD agent → Continue through all steps
```
**Process Results:**
- **Production-Ready Files:** Complete `.agent.yaml` with proper BMAD compliance
- **Expert Architecture:** Sidecar folder structure with memory files and security boundaries
- **Installation Package:** Module structure with `module.yaml` for BMAD integration
- **Testing Guidelines:** Conversation starters and command validation approaches
- **Documentation:** Comprehensive agent plan and sidecar README for maintenance
**Key Advantages:**
- **Single Agent Workflow:** Complete process without switching between multiple agents
- **BMAD Compliance:** Automatic adherence to all standards, patterns, and architectural requirements
- **Expert Memory Management:** Proper sidecar setup with runtime path variables and file boundaries
- **Specialized Domain Integration:** Research-backed methodology incorporation
- **Production Installation:** Ready-to-install module structure with proper configuration
**Teacher's Assistant Case Study Achievement:**
- **Expert Agent:** 9 educational commands with persistent memory architecture
- **Educational Psychology Integration:** Socratic method, scaffolding techniques, ZPD assessment
- **Complete Workflow:** From concept to installable module in single session
- **Memory Architecture:** Student learning profiles and technique effectiveness tracking
- **BMAD Compliance:** Full validation and proper sidecar configuration
**Time Investment:**
Typically 2-4 focused work sessions to go from initial idea to production-ready, installable custom agent with comprehensive capabilities and professional-quality implementation.
The BMAD Agent Creation Method transforms agent concepts into production-ready implementations efficiently and systematically, handling all technical complexity while maintaining focus on agent personality and user value delivery.

View File

@ -0,0 +1,26 @@
# Teachers-Assistant-Sidecar
This folder stores persistent memory for the **Teachers Assistant** Expert agent.
## Purpose
Maintains individual student learning profiles and tracks teaching technique effectiveness to provide personalized educational guidance that adapts to each student's learning style and progress.
## Files
- **learning-profiles.md**: Student interests, grade level, subject progress tracking, and learning preferences
- **technique-tracking.md**: Record of teaching methods and their effectiveness per student for continuous improvement
## Runtime Access
After BMAD installation, this folder will be accessible at:
`{project-root}/_bmad/_memory/teachers-assistant-sidecar/`
## Educational Philosophy
This agent implements research-backed educational psychology principles:
- **Zone of Proximal Development**: Scaffolding within student's learning capability
- **Socratic Method**: Strategic questioning to guide discovery rather than provide answers
- **Constructivist Learning**: Student-centered knowledge building through active engagement
- **Metacognitive Strategies**: Building student awareness of their own learning processes
## Security & Privacy
- Agent file access is restricted to this sidecar folder only
- Student learning data remains private and is not shared beyond educational interactions
- Progress tracking serves to improve teaching effectiveness, not for external assessment

View File

@ -0,0 +1,27 @@
# Learning Profiles
## Student Information
- **Name**: [To be filled during first interaction]
- **Grade Level**: [To be determined]
- **Primary Subjects**: [To be identified]
## Learning Preferences
- **Communication Style**: [Age-appropriate complexity level]
- **Preferred Analogies**: [Student interests for concept explanations]
- **Learning Modalities**: [Visual, verbal, kinesthetic preferences]
- **Study Aid Formats**: [Flashcards, concept maps, practice problems, guides]
## Subject Progress Tracking
### [Subject Name]
- **Mastered Concepts**: [List concepts student has demonstrated understanding]
- **Struggling Areas**: [Concepts requiring additional focus and practice]
- **Effective Techniques**: [Methods that work well for this student in this subject]
- **Recent Sessions**: [Brief notes on last few learning interactions]
## Progress Notes
- **Overall Learning Patterns**: [What consistently helps this student learn]
- **Motivation Strategies**: [What keeps student engaged]
- **Challenge Areas**: [Topics or approaches that consistently cause difficulty]
*This file is updated automatically during learning sessions and can be manually edited through the [UP] command.*

View File

@ -0,0 +1,43 @@
# Technique Effectiveness Tracking
## Teaching Method Analysis
### Socratic Questioning
- **Success Rate**: [Percentage of times this leads to understanding]
- **Best Used For**: [Types of concepts where this works well]
- **Student Response**: [How student typically responds to questioning approach]
- **Notes**: [Specific questioning patterns that work for this student]
### Analogies & Examples
- **Preferred Analogy Types**: [Student interests that make good analogies]
- **Successful Analogies**: [Record of analogies that clicked]
- **Failed Analogies**: [Analogies that confused rather than clarified]
- **Interest Areas**: [Student hobbies/interests available for analogies]
### Study Aid Generation
- **Most Effective Formats**: [Flashcards, concept maps, practice problems, guides]
- **Usage Patterns**: [How student uses generated materials]
- **Revision Frequency**: [How often student reviews generated aids]
- **Success Metrics**: [Improvement after using specific aid types]
### Alternative Explanation Methods
- **Visual Methods**: [Diagrams, charts, illustrations effectiveness]
- **Narrative Methods**: [Story-based learning success rate]
- **Step-by-Step Guides**: [Procedural learning effectiveness]
- **Peer Explanation**: [Student teaching back concepts success]
## Session Effectiveness Tracking
- **Date**: [Session date]
- **Subject**: [Topic covered]
- **Methods Used**: [Teaching techniques employed]
- **Student Engagement**: [High/Medium/Low and why]
- **Understanding Achieved**: [Yes/Partial/No and next steps]
- **Follow-up Needed**: [Additional practice or review required]
## Adaptation Insights
- **Learning Style Preferences**: [What consistently works]
- **Avoidance Patterns**: [Methods that consistently fail]
- **Optimal Session Length**: [How long before fatigue sets in]
- **Best Time Patterns**: [When student is most receptive to learning]
*This file tracks which educational techniques work best for individual students and is updated after each learning session.*

View File

@ -0,0 +1,84 @@
agent:
metadata:
id: teachers-assistant
name: Sophia Chen
title: Educational Learning Facilitator
icon: 🎓
module: stand-alone
hasSidecar: true
persona:
role: |
Educational learning facilitator specializing in Socratic questioning, scaffolding techniques, and progress-based teaching that guides students to discover answers rather than providing direct instruction.
identity: |
Master educator with deep knowledge of educational psychology, constructivist learning theory, and adaptive teaching methods. Passionate advocate for authentic learning through struggle and self-discovery.
communication_style: |
Speaks like a patient mentor using strategic questioning, encouraging language, and age-appropriate complexity while maintaining conceptual integrity.
principles:
- Channel expert educational psychology wisdom: draw upon Zone of Proximal Development, scaffolding techniques, metacognitive strategies, and research-backed methods that facilitate genuine understanding
- Never provide direct answers - guide students to discover solutions through strategic questioning and multiple explanation pathways
- Authentic learning requires productive struggle - frustration signals growth, not failure
- Track what works for each student and adapt techniques accordingly - analogies for some, examples for others
- Academic boundaries are sacred - redirect non-educational conversations back to learning focus
critical_actions:
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/learning-profiles.md'
- 'Load COMPLETE file {project-root}/_bmad/_memory/teachers-assistant-sidecar/technique-tracking.md'
- 'ONLY read/write files in {project-root}/_bmad/_memory/teachers-assistant-sidecar/'
prompts:
- id: socratic-guidance
content: |
<instructions>Guide student through learning using Socratic questioning without giving direct answers</instructions>
<process>1. Ask strategic questions 2. Use student interests for analogies 3. Encourage discovery 4. Validate understanding</process>
- id: alternative-explanation
content: |
<instructions>Try different teaching approach when student struggles with current method</instructions>
<process>1. Assess why current approach failed 2. Select alternative method 3. Use different modality or analogy 4. Check for understanding</process>
- id: study-aids-generator
content: |
<instructions>Generate study materials based on student needs and preferences</instructions>
<options>Flashcards | Practice Problems | Concept Maps | Step-by-step Guides</options>
<process>1. Assess learning gaps 2. Choose appropriate format 3. Create targeted materials 4. Save to learning profile</process>
menu:
- trigger: LG or fuzzy match on learn-guide
action: '#socratic-guidance'
description: '[LG] Learning guidance through Socratic questioning'
- trigger: QM or fuzzy match on quiz-me
action: 'Generate pop-quiz on recent or struggling concepts from learning profile'
description: '[QM] Quiz me on challenging concepts'
- trigger: VC or fuzzy match on validate-concepts
action: 'Test retention of previously learned material to ensure long-term understanding'
description: '[VC] Validate concept retention'
- trigger: SA or fuzzy match on study-aids
action: '#study-aids-generator'
description: '[SA] Generate study aids (flashcards, practice problems, guides)'
- trigger: ED or fuzzy match on explain-differently
action: '#alternative-explanation'
description: '[ED] Try different explanation method'
- trigger: ST or fuzzy match on story-time
action: 'Tell engaging stories that exemplify concepts being learned'
description: '[ST] Story time - learn through narratives'
- trigger: UP or fuzzy match on update-profile
action: 'Update {project-root}/_bmad/_memory/teachers-assistant-sidecar/learning-profiles.md with interests and preferences'
description: '[UP] Update learning profile and interests'
- trigger: LP or fuzzy match on learning-progress
action: 'Review progress from {project-root}/_bmad/_memory/teachers-assistant-sidecar/technique-tracking.md and provide insights'
description: '[LP] View learning progress and technique effectiveness'
- trigger: HC or fuzzy match on help-commands
action: 'Display all available educational commands and their usage with examples'
description: '[HC] Help - show all available commands'

View File

@ -0,0 +1 @@
unitary: true

View File

@ -49,6 +49,7 @@
"test:coverage": "c8 --reporter=text --reporter=html npm run test:schemas",
"test:install": "node test/test-installation-components.js",
"test:schemas": "node test/test-agent-schema.js",
"validate:refs": "node tools/validate-file-refs.js",
"validate:schemas": "node tools/validate-agent-schema.js"
},
"lint-staged": {

480
tools/validate-file-refs.js Normal file
View File

@ -0,0 +1,480 @@
/**
* File Reference Validator
*
* Validates cross-file references in BMAD source files (agents, workflows, tasks, steps).
* Catches broken file paths, missing referenced files, and absolute path leaks.
*
* What it checks:
* - {project-root}/_bmad/ references in YAML and markdown resolve to real src/ files
* - Relative path references (./file.md, ../data/file.csv) point to existing files
* - exec="..." and <invoke-task> targets exist
* - Step metadata (thisStepFile, nextStepFile) references are valid
* - Load directives (Load: `./file.md`) target existing files
* - No absolute paths (/Users/, /home/, C:\) leak into source files
*
* What it does NOT check (deferred):
* - {installed_path} variable interpolation (self-referential, low risk)
* - {{mustache}} template variables (runtime substitution)
* - {config_source}:key dynamic YAML dereferences
*
* Usage:
* node tools/validate-file-refs.js # Warn on broken references (exit 0)
* node tools/validate-file-refs.js --strict # Fail on broken references (exit 1)
* node tools/validate-file-refs.js --verbose # Show all checked references
*
* Default mode is warning-only (exit 0) so adoption is non-disruptive.
* Use --strict when you want CI or pre-commit to enforce valid references.
*/
const fs = require('node:fs');
const path = require('node:path');
const yaml = require('yaml');
const PROJECT_ROOT = path.resolve(__dirname, '..');
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
const VERBOSE = process.argv.includes('--verbose');
const STRICT = process.argv.includes('--strict');
// --- Constants ---
// File extensions to scan
const SCAN_EXTENSIONS = new Set(['.yaml', '.yml', '.md', '.xml']);
// Skip directories
const SKIP_DIRS = new Set(['node_modules', '_module-installer', '.git']);
// Pattern: {project-root}/_bmad/ references
const PROJECT_ROOT_REF = /\{project-root\}\/_bmad\/([^\s'"<>})\]`]+)/g;
// Pattern: {_bmad}/ shorthand references
const BMAD_SHORTHAND_REF = /\{_bmad\}\/([^\s'"<>})\]`]+)/g;
// Pattern: exec="..." attributes
const EXEC_ATTR = /exec="([^"]+)"/g;
// Pattern: <invoke-task> content
const INVOKE_TASK = /<invoke-task>([^<]+)<\/invoke-task>/g;
// Pattern: relative paths in quotes
const RELATIVE_PATH_QUOTED = /['"](\.\.\/?[^'"]+\.(?:md|yaml|yml|xml|json|csv|txt))['"]/g;
const RELATIVE_PATH_DOT = /['"](\.\/[^'"]+\.(?:md|yaml|yml|xml|json|csv|txt))['"]/g;
// Pattern: step metadata
const STEP_META = /(?:thisStepFile|nextStepFile|continueStepFile|skipToStepFile|altStepFile|workflowFile):\s*['"](\.[^'"]+)['"]/g;
// Pattern: Load directives
const LOAD_DIRECTIVE = /Load[:\s]+`(\.[^`]+)`/g;
// Pattern: absolute path leaks
const ABS_PATH_LEAK = /(?:\/Users\/|\/home\/|[A-Z]:\\\\)/;
// --- Output Escaping ---
function escapeAnnotation(str) {
return str.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
}
function escapeTableCell(str) {
return String(str).replaceAll('|', String.raw`\|`);
}
// Path prefixes/patterns that only exist in installed structure, not in source
const INSTALL_ONLY_PATHS = ['_config/'];
// Files that are generated at install time and don't exist in the source tree
const INSTALL_GENERATED_FILES = ['config.yaml'];
// Variables that indicate a path is not statically resolvable
const UNRESOLVABLE_VARS = [
'{output_folder}',
'{value}',
'{timestamp}',
'{config_source}:',
'{installed_path}',
'{shared_path}',
'{planning_artifacts}',
'{research_topic}',
'{user_name}',
'{communication_language}',
'{epic_number}',
'{next_epic_num}',
'{epic_num}',
'{part_id}',
'{count}',
'{date}',
'{outputFile}',
'{nextStepFile}',
];
// --- File Discovery ---
function getSourceFiles(dir) {
const files = [];
function walk(currentDir) {
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
for (const entry of entries) {
if (SKIP_DIRS.has(entry.name)) continue;
const fullPath = path.join(currentDir, entry.name);
if (entry.isDirectory()) {
walk(fullPath);
} else if (entry.isFile() && SCAN_EXTENSIONS.has(path.extname(entry.name))) {
files.push(fullPath);
}
}
}
walk(dir);
return files;
}
// --- Code Block Stripping ---
function stripCodeBlocks(content) {
return content.replaceAll(/```[\s\S]*?```/g, (m) => m.replaceAll(/[^\n]/g, ''));
}
function stripJsonExampleBlocks(content) {
// Strip bare JSON example blocks: { and } each on their own line.
// These are example/template data (not real file references).
return content.replaceAll(/^\{\s*\n(?:.*\n)*?^\}\s*$/gm, (m) => m.replaceAll(/[^\n]/g, ''));
}
// --- Path Mapping ---
function mapInstalledToSource(refPath) {
// Strip {project-root}/_bmad/ or {_bmad}/ prefix
let cleaned = refPath.replace(/^\{project-root\}\/_bmad\//, '').replace(/^\{_bmad\}\//, '');
// Also handle bare _bmad/ prefix (seen in some invoke-task)
cleaned = cleaned.replace(/^_bmad\//, '');
// Skip install-only paths (generated at install time, not in source)
if (isInstallOnly(cleaned)) return null;
// core/, bmm/, and utility/ are directly under src/
if (cleaned.startsWith('core/') || cleaned.startsWith('bmm/') || cleaned.startsWith('utility/')) {
return path.join(SRC_DIR, cleaned);
}
// Fallback: map directly under src/
return path.join(SRC_DIR, cleaned);
}
// --- Reference Extraction ---
function isResolvable(refStr) {
// Skip refs containing unresolvable runtime variables
if (refStr.includes('{{')) return false;
for (const v of UNRESOLVABLE_VARS) {
if (refStr.includes(v)) return false;
}
return true;
}
function isInstallOnly(cleanedPath) {
// Skip paths that only exist in the installed _bmad/ structure, not in src/
for (const prefix of INSTALL_ONLY_PATHS) {
if (cleanedPath.startsWith(prefix)) return true;
}
// Skip files that are generated during installation
const basename = path.basename(cleanedPath);
for (const generated of INSTALL_GENERATED_FILES) {
if (basename === generated) return true;
}
return false;
}
function extractYamlRefs(filePath, content) {
const refs = [];
let doc;
try {
doc = yaml.parseDocument(content);
} catch {
return refs; // Skip unparseable YAML (schema validator handles this)
}
function checkValue(value, range, keyPath) {
if (typeof value !== 'string') return;
if (!isResolvable(value)) return;
const line = range ? offsetToLine(content, range[0]) : undefined;
// Check for {project-root}/_bmad/ refs
const prMatch = value.match(/\{project-root\}\/_bmad\/[^\s'"<>})\]`]+/);
if (prMatch) {
refs.push({ file: filePath, raw: prMatch[0], type: 'project-root', line, key: keyPath });
}
// Check for {_bmad}/ refs
const bmMatch = value.match(/\{_bmad\}\/[^\s'"<>})\]`]+/);
if (bmMatch) {
refs.push({ file: filePath, raw: bmMatch[0], type: 'project-root', line, key: keyPath });
}
// Check for relative paths
const relMatch = value.match(/^\.\.?\/[^\s'"<>})\]`]+\.(?:md|yaml|yml|xml|json|csv|txt)$/);
if (relMatch) {
refs.push({ file: filePath, raw: relMatch[0], type: 'relative', line, key: keyPath });
}
}
function walkNode(node, keyPath) {
if (!node) return;
if (yaml.isMap(node)) {
for (const item of node.items) {
const key = item.key && item.key.value !== undefined ? item.key.value : '?';
const childPath = keyPath ? `${keyPath}.${key}` : String(key);
walkNode(item.value, childPath);
}
} else if (yaml.isSeq(node)) {
for (const [i, item] of node.items.entries()) {
walkNode(item, `${keyPath}[${i}]`);
}
} else if (yaml.isScalar(node)) {
checkValue(node.value, node.range, keyPath);
}
}
walkNode(doc.contents, '');
return refs;
}
function offsetToLine(content, offset) {
let line = 1;
for (let i = 0; i < offset && i < content.length; i++) {
if (content[i] === '\n') line++;
}
return line;
}
function extractMarkdownRefs(filePath, content) {
const refs = [];
const stripped = stripJsonExampleBlocks(stripCodeBlocks(content));
function runPattern(regex, type) {
regex.lastIndex = 0;
let match;
while ((match = regex.exec(stripped)) !== null) {
const raw = match[1];
if (!isResolvable(raw)) continue;
refs.push({ file: filePath, raw, type, line: offsetToLine(stripped, match.index) });
}
}
// {project-root}/_bmad/ refs
runPattern(PROJECT_ROOT_REF, 'project-root');
// {_bmad}/ shorthand
runPattern(BMAD_SHORTHAND_REF, 'project-root');
// exec="..." attributes
runPattern(EXEC_ATTR, 'exec-attr');
// <invoke-task> tags
runPattern(INVOKE_TASK, 'invoke-task');
// Step metadata
runPattern(STEP_META, 'relative');
// Load directives
runPattern(LOAD_DIRECTIVE, 'relative');
// Relative paths in quotes
runPattern(RELATIVE_PATH_QUOTED, 'relative');
runPattern(RELATIVE_PATH_DOT, 'relative');
return refs;
}
// --- Reference Resolution ---
function resolveRef(ref) {
if (ref.type === 'project-root') {
return mapInstalledToSource(ref.raw);
}
if (ref.type === 'relative') {
return path.resolve(path.dirname(ref.file), ref.raw);
}
if (ref.type === 'exec-attr') {
let execPath = ref.raw;
if (execPath.includes('{project-root}')) {
return mapInstalledToSource(execPath);
}
if (execPath.includes('{_bmad}')) {
return mapInstalledToSource(execPath);
}
if (execPath.startsWith('_bmad/')) {
return mapInstalledToSource(execPath);
}
// Relative exec path
return path.resolve(path.dirname(ref.file), execPath);
}
if (ref.type === 'invoke-task') {
// Extract file path from invoke-task content
const prMatch = ref.raw.match(/\{project-root\}\/_bmad\/([^\s'"<>})\]`]+)/);
if (prMatch) return mapInstalledToSource(prMatch[0]);
const bmMatch = ref.raw.match(/\{_bmad\}\/([^\s'"<>})\]`]+)/);
if (bmMatch) return mapInstalledToSource(bmMatch[0]);
const bareMatch = ref.raw.match(/_bmad\/([^\s'"<>})\]`]+)/);
if (bareMatch) return mapInstalledToSource(bareMatch[0]);
return null; // Can't resolve — skip
}
return null;
}
// --- Absolute Path Leak Detection ---
function checkAbsolutePathLeaks(filePath, content) {
const leaks = [];
const stripped = stripCodeBlocks(content);
const lines = stripped.split('\n');
for (const [i, line] of lines.entries()) {
if (ABS_PATH_LEAK.test(line)) {
leaks.push({ file: filePath, line: i + 1, content: line.trim() });
}
}
return leaks;
}
// --- Main ---
console.log(`\nValidating file references in: ${SRC_DIR}`);
console.log(`Mode: ${STRICT ? 'STRICT (exit 1 on issues)' : 'WARNING (exit 0)'}${VERBOSE ? ' + VERBOSE' : ''}\n`);
const files = getSourceFiles(SRC_DIR);
console.log(`Found ${files.length} source files\n`);
let totalRefs = 0;
let brokenRefs = 0;
let totalLeaks = 0;
let filesWithIssues = 0;
const allIssues = []; // Collect for $GITHUB_STEP_SUMMARY
for (const filePath of files) {
const relativePath = path.relative(PROJECT_ROOT, filePath);
const content = fs.readFileSync(filePath, 'utf-8');
const ext = path.extname(filePath);
// Extract references
let refs;
if (ext === '.yaml' || ext === '.yml') {
refs = extractYamlRefs(filePath, content);
} else {
refs = extractMarkdownRefs(filePath, content);
}
// Resolve and check
const broken = [];
if (VERBOSE && refs.length > 0) {
console.log(`\n${relativePath}`);
}
for (const ref of refs) {
totalRefs++;
const resolved = resolveRef(ref);
if (resolved && !fs.existsSync(resolved)) {
// For paths without extensions, also check if it's a directory
const hasExt = path.extname(resolved) !== '';
if (!hasExt) {
// Could be a directory reference — skip if not clearly a file
continue;
}
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved) });
brokenRefs++;
continue;
}
if (VERBOSE && resolved) {
console.log(` [OK] ${ref.raw}`);
}
}
// Check absolute path leaks
const leaks = checkAbsolutePathLeaks(filePath, content);
totalLeaks += leaks.length;
// Report issues for this file
if (broken.length > 0 || leaks.length > 0) {
filesWithIssues++;
if (!VERBOSE) {
console.log(`\n${relativePath}`);
}
for (const { ref, resolved } of broken) {
const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : '';
console.log(` [BROKEN] ${ref.raw}${location ? ` (${location})` : ''}`);
console.log(` Target not found: ${resolved}`);
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: 'broken ref' });
if (process.env.GITHUB_ACTIONS) {
const line = ref.line || 1;
console.log(`::warning file=${relativePath},line=${line}::${escapeAnnotation(`Broken reference: ${ref.raw}${resolved}`)}`);
}
}
for (const leak of leaks) {
console.log(` [ABS-PATH] Line ${leak.line}: ${leak.content}`);
allIssues.push({ file: relativePath, line: leak.line, ref: leak.content, issue: 'abs-path' });
if (process.env.GITHUB_ACTIONS) {
console.log(`::warning file=${relativePath},line=${leak.line}::${escapeAnnotation(`Absolute path leak: ${leak.content}`)}`);
}
}
}
}
// Summary
console.log(`\n${'─'.repeat(60)}`);
console.log(`\nSummary:`);
console.log(` Files scanned: ${files.length}`);
console.log(` References checked: ${totalRefs}`);
console.log(` Broken references: ${brokenRefs}`);
console.log(` Absolute path leaks: ${totalLeaks}`);
const hasIssues = brokenRefs > 0 || totalLeaks > 0;
if (hasIssues) {
console.log(`\n ${filesWithIssues} file(s) with issues`);
if (STRICT) {
console.log(`\n [STRICT MODE] Exiting with failure.`);
} else {
console.log(`\n Run with --strict to treat warnings as errors.`);
}
} else {
console.log(`\n All file references valid!`);
}
console.log('');
// Write GitHub Actions step summary
if (process.env.GITHUB_STEP_SUMMARY) {
let summary = '## File Reference Validation\n\n';
if (allIssues.length > 0) {
summary += '| File | Line | Reference | Issue |\n';
summary += '|------|------|-----------|-------|\n';
for (const issue of allIssues) {
summary += `| ${escapeTableCell(issue.file)} | ${issue.line} | ${escapeTableCell(issue.ref)} | ${issue.issue} |\n`;
}
summary += '\n';
}
summary += `**${files.length} files scanned, ${totalRefs} references checked, ${brokenRefs + totalLeaks} issues found**\n`;
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);
}
process.exit(hasIssues && STRICT ? 1 : 0);