Compare commits

...

9 Commits

Author SHA1 Message Date
Davor Racic 1cc8a53a8e
Merge a69810afe5 into 04e3dc8f75 2026-02-01 17:19:19 +01:00
Michael Pursifull 04e3dc8f75
Fix leaked source paths in PRD validation report (#1481)
Replace /src/core/ paths with {project-root}/_bmad/core/ convention
in validation-report-prd-workflow.md lines 293-294.

These paths reference party-mode and advanced-elicitation workflows
using the source tree layout (/src/core/) instead of the installed
layout ({project-root}/_bmad/core/) that Beta.4 standardized
across all other files.

This is the remaining half of the fix for #1435, which was closed
as "will fix with .4 release" but only the brianmadison path on
line 11 and the XML syntax issue were addressed. The /src/core/
paths on lines 293-294 were missed.

Fixes #1480
2026-02-01 10:15:35 -06:00
Alex Verkhovsky ef7abb7ca5
fix: complete sharding of market research customer analysis steps (#1486)
Connect orphaned detailed customer analysis chain (steps 02-behavior,
03-pain-points, 04-decisions) by updating step-01-init to load
step-02-customer-behavior instead of the condensed
step-02-customer-insights. Remove the now-superseded monolithic file.

Fixes #1399

Co-authored-by: Brian <bmadcode@gmail.com>
2026-02-01 10:14:50 -06:00
Chad Woolley 981e5a49c2
docs: Add exact slash commands to getting-started guide (#1505)
The getting-started tutorial referenced agents and workflows by name
(e.g., "Load the PM agent", "Run the prd workflow") without providing
the actual commands to type. This adds the exact slash commands inline
alongside the existing prose so new users know precisely what to run.
2026-02-01 10:05:49 -06:00
Alex Verkhovsky e17c7e8793
fix: remove .claude/commands file from version control (#1506)
This file was accidentally tracked despite .claude/commands being in
.gitignore. The installer generates this file at install time from
source templates — it should not be tracked in the repo.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:01:40 -06:00
Davor Racić a69810afe5 fix: convert absolute paths to relative in task-tool-command-generator 2026-02-01 13:39:09 +01:00
Davor Racić 1d505b17b4 fix: add safety checks for setBmadFolderName method calls in IdeManager 2026-02-01 13:23:19 +01:00
Davor Racić a6a960f88c fix: Replace the rest of BMAD_FOLDER magic values 2026-02-01 12:42:10 +01:00
Davor Racić 8ed36d9f0d refactor: centralize BMAD_FOLDER_NAME constant in path-utils 2026-02-01 12:24:09 +01:00
13 changed files with 83 additions and 268 deletions

View File

@ -1,7 +0,0 @@
---
name: 'generate-project-context'
description: 'Creates a concise project-context.md file with critical rules and patterns that AI agents must follow when implementing code. Optimized for LLM context efficiency.'
disable-model-invocation: true
---
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/_bmad/bmm/workflows/generate-project-context/workflow.md, READ its entire contents and follow its directions exactly!

View File

@ -65,7 +65,11 @@ The installer creates two folders:
- `_bmad/` — agents, workflows, tasks, and configuration - `_bmad/` — agents, workflows, tasks, and configuration
- `_bmad-output/` — empty for now, but this is where your artifacts will be saved - `_bmad-output/` — empty for now, but this is where your artifacts will be saved
Open your AI IDE in the project folder. Run the `help` workflow (`/bmad-help` on most platforms) to see what to do next — it detects what you've completed and recommends the next step. Open your AI IDE in the project folder. Run the `help` workflow (`/bmad-help`) to see what to do next — it detects what you've completed and recommends the next step.
:::note[How to Load Agents and Run Workflows]
Each workflow has a **slash command** you run in your IDE (e.g., `/bmad-bmm-create-prd`). Running a workflow command automatically loads the appropriate agent — you don't need to load agents separately. You can also load an agent directly for general conversation (e.g., `/bmad-agent-bmm-pm` for the PM agent).
:::
:::caution[Fresh Chats] :::caution[Fresh Chats]
Always start a fresh chat for each workflow. This prevents context limitations from causing issues. Always start a fresh chat for each workflow. This prevents context limitations from causing issues.
@ -78,29 +82,29 @@ Work through phases 1-3. **Use fresh chats for each workflow.**
### Phase 1: Analysis (Optional) ### Phase 1: Analysis (Optional)
All workflows in this phase are optional: All workflows in this phase are optional:
- **brainstorming** — Guided ideation - **brainstorming** (`/bmad-brainstorming`) — Guided ideation
- **research** — Market and technical research - **research** (`/bmad-bmm-research`) — Market and technical research
- **create-product-brief** — Recommended foundation document - **create-product-brief** (`/bmad-bmm-create-product-brief`) — Recommended foundation document
### Phase 2: Planning (Required) ### Phase 2: Planning (Required)
**For BMad Method and Enterprise tracks:** **For BMad Method and Enterprise tracks:**
1. Load the **PM agent** in a new chat 1. Load the **PM agent** (`/bmad-agent-bmm-pm`) in a new chat
2. Run the `prd` workflow 2. Run the `prd` workflow (`/bmad-bmm-create-prd`)
3. Output: `PRD.md` 3. Output: `PRD.md`
**For Quick Flow track:** **For Quick Flow track:**
- Use the `quick-spec` workflow instead of PRD, then skip to implementation - Use the `quick-spec` workflow (`/bmad-bmm-quick-spec`) instead of PRD, then skip to implementation
:::note[UX Design (Optional)] :::note[UX Design (Optional)]
If your project has a user interface, load the **UX-Designer agent** and run the UX design workflow after creating your PRD. If your project has a user interface, load the **UX-Designer agent** (`/bmad-agent-bmm-ux-designer`) and run the UX design workflow (`/bmad-bmm-create-ux-design`) after creating your PRD.
::: :::
### Phase 3: Solutioning (BMad Method/Enterprise) ### Phase 3: Solutioning (BMad Method/Enterprise)
**Create Architecture** **Create Architecture**
1. Load the **Architect agent** in a new chat 1. Load the **Architect agent** (`/bmad-agent-bmm-architect`) in a new chat
2. Run `create-architecture` 2. Run `create-architecture` (`/bmad-bmm-create-architecture`)
3. Output: Architecture document with technical decisions 3. Output: Architecture document with technical decisions
**Create Epics and Stories** **Create Epics and Stories**
@ -109,13 +113,13 @@ If your project has a user interface, load the **UX-Designer agent** and run the
Epics and stories are now created *after* architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down. Epics and stories are now created *after* architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
::: :::
1. Load the **PM agent** in a new chat 1. Load the **PM agent** (`/bmad-agent-bmm-pm`) in a new chat
2. Run `create-epics-and-stories` 2. Run `create-epics-and-stories` (`/bmad-bmm-create-epics-and-stories`)
3. The workflow uses both PRD and Architecture to create technically-informed stories 3. The workflow uses both PRD and Architecture to create technically-informed stories
**Implementation Readiness Check** *(Highly Recommended)* **Implementation Readiness Check** *(Highly Recommended)*
1. Load the **Architect agent** in a new chat 1. Load the **Architect agent** (`/bmad-agent-bmm-architect`) in a new chat
2. Run `check-implementation-readiness` 2. Run `check-implementation-readiness` (`/bmad-bmm-check-implementation-readiness`)
3. Validates cohesion across all planning documents 3. Validates cohesion across all planning documents
## Step 2: Build Your Project ## Step 2: Build Your Project
@ -124,19 +128,19 @@ Once planning is complete, move to implementation. **Each workflow should run in
### Initialize Sprint Planning ### Initialize Sprint Planning
Load the **SM agent** and run `sprint-planning`. This creates `sprint-status.yaml` to track all epics and stories. Load the **SM agent** (`/bmad-agent-bmm-sm`) and run `sprint-planning` (`/bmad-bmm-sprint-planning`). This creates `sprint-status.yaml` to track all epics and stories.
### The Build Cycle ### The Build Cycle
For each story, repeat this cycle with fresh chats: For each story, repeat this cycle with fresh chats:
| Step | Agent | Workflow | Purpose | | Step | Agent | Workflow | Command | Purpose |
| ---- | ----- | -------------- | ---------------------------------- | | ---- | ----- | -------------- | -------------------------- | ---------------------------------- |
| 1 | SM | `create-story` | Create story file from epic | | 1 | SM | `create-story` | `/bmad-bmm-create-story` | Create story file from epic |
| 2 | DEV | `dev-story` | Implement the story | | 2 | DEV | `dev-story` | `/bmad-bmm-dev-story` | Implement the story |
| 3 | DEV | `code-review` | Quality validation *(recommended)* | | 3 | DEV | `code-review` | `/bmad-bmm-code-review` | Quality validation *(recommended)* |
After completing all stories in an epic, load the **SM agent** and run `retrospective`. After completing all stories in an epic, load the **SM agent** (`/bmad-agent-bmm-sm`) and run `retrospective` (`/bmad-bmm-retrospective`).
## What You've Accomplished ## What You've Accomplished
@ -162,17 +166,17 @@ your-project/
## Quick Reference ## Quick Reference
| Workflow | Agent | Purpose | | Workflow | Command | Agent | Purpose |
| -------------------------------- | --------- | ------------------------------------ | | -------------------------------- | ------------------------------------------ | --------- | ------------------------------------ |
| `help` | Any | Get guidance on what to do next | | `help` | `/bmad-help` | Any | Get guidance on what to do next |
| `prd` | PM | Create Product Requirements Document | | `prd` | `/bmad-bmm-create-prd` | PM | Create Product Requirements Document |
| `create-architecture` | Architect | Create architecture document | | `create-architecture` | `/bmad-bmm-create-architecture` | Architect | Create architecture document |
| `create-epics-and-stories` | PM | Break down PRD into epics | | `create-epics-and-stories` | `/bmad-bmm-create-epics-and-stories` | PM | Break down PRD into epics |
| `check-implementation-readiness` | Architect | Validate planning cohesion | | `check-implementation-readiness` | `/bmad-bmm-check-implementation-readiness` | Architect | Validate planning cohesion |
| `sprint-planning` | SM | Initialize sprint tracking | | `sprint-planning` | `/bmad-bmm-sprint-planning` | SM | Initialize sprint tracking |
| `create-story` | SM | Create a story file | | `create-story` | `/bmad-bmm-create-story` | SM | Create a story file |
| `dev-story` | DEV | Implement a story | | `dev-story` | `/bmad-bmm-dev-story` | DEV | Implement a story |
| `code-review` | DEV | Review implemented code | | `code-review` | `/bmad-bmm-code-review` | DEV | Review implemented code |
## Common Questions ## Common Questions
@ -180,10 +184,10 @@ your-project/
Only for BMad Method and Enterprise tracks. Quick Flow skips from tech-spec to implementation. Only for BMad Method and Enterprise tracks. Quick Flow skips from tech-spec to implementation.
**Can I change my plan later?** **Can I change my plan later?**
Yes. The SM agent has a `correct-course` workflow for handling scope changes. Yes. The SM agent has a `correct-course` workflow (`/bmad-bmm-correct-course`) for handling scope changes.
**What if I want to brainstorm first?** **What if I want to brainstorm first?**
Load the Analyst agent and run `brainstorming` before starting your PRD. Load the Analyst agent (`/bmad-agent-bmm-analyst`) and run `brainstorming` (`/bmad-brainstorming`) before starting your PRD.
**Do I need to follow a strict order?** **Do I need to follow a strict order?**
Not strictly. Once you learn the flow, you can run workflows directly using the Quick Reference above. Not strictly. Once you learn the flow, you can run workflows directly using the Quick Reference above.
@ -192,14 +196,14 @@ Not strictly. Once you learn the flow, you can run workflows directly using the
- **During workflows** — Agents guide you with questions and explanations - **During workflows** — Agents guide you with questions and explanations
- **Community** — [Discord](https://discord.gg/gk8jAdXWmj) (#bmad-method-help, #report-bugs-and-issues) - **Community** — [Discord](https://discord.gg/gk8jAdXWmj) (#bmad-method-help, #report-bugs-and-issues)
- **Stuck?** — Run `help` to see what to do next - **Stuck?** — Run `help` (`/bmad-help`) to see what to do next
## Key Takeaways ## Key Takeaways
:::tip[Remember These] :::tip[Remember These]
- **Always use fresh chats** — Start a new chat for each workflow - **Always use fresh chats** — Start a new chat for each workflow
- **Track matters** — Quick Flow uses quick-spec; Method/Enterprise need PRD and architecture - **Track matters** — Quick Flow uses quick-spec; Method/Enterprise need PRD and architecture
- **Use `help` when stuck** — It detects your progress and suggests next steps - **Use `help` (`/bmad-help`) when stuck** — It detects your progress and suggests next steps
::: :::
Ready to start? Install BMad and let the agents guide you through your first project. Ready to start? Install BMad and let the agents guide you through your first project.

View File

@ -138,7 +138,7 @@ Show initial scope document and present continue option:
- Update frontmatter: `stepsCompleted: [1]` - Update frontmatter: `stepsCompleted: [1]`
- Add confirmation note to document: "Scope confirmed by user on {{date}}" - Add confirmation note to document: "Scope confirmed by user on {{date}}"
- Load: `./step-02-customer-insights.md` - Load: `./step-02-customer-behavior.md`
#### If 'Modify': #### If 'Modify':

View File

@ -1,200 +0,0 @@
# Market Research Step 2: Customer Insights
## MANDATORY EXECUTION RULES (READ FIRST):
- 🛑 NEVER generate content without web search verification
- 📖 CRITICAL: ALWAYS read the complete step file before taking any action - partial understanding leads to incomplete decisions
- 🔄 CRITICAL: When loading next step with 'C', ensure the entire file is read and understood before proceeding
- ✅ Search the web to verify and supplement your knowledge with current facts
- 📋 YOU ARE A CUSTOMER INSIGHTS ANALYST, not content generator
- 💬 FOCUS on customer behavior and needs analysis
- 🔍 WEB SEARCH REQUIRED - verify current facts against live sources
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
## EXECUTION PROTOCOLS:
- 🎯 Show web search analysis before presenting findings
- ⚠️ Present [C] continue option after customer insights content generation
- 💾 ONLY save when user chooses C (Continue)
- 📖 Update frontmatter `stepsCompleted: [1, 2]` before loading next step
- 🚫 FORBIDDEN to load next step until C is selected
## CONTEXT BOUNDARIES:
- Current document and frontmatter from step-01 are available
- Focus on customer behavior and needs analysis
- Web search capabilities with source verification are enabled
- May need to search for current customer behavior trends
## YOUR TASK:
Conduct comprehensive customer insights analysis with emphasis on behavior patterns and needs.
## CUSTOMER INSIGHTS SEQUENCE:
### 1. Begin Customer Insights Analysis
**UTILIZE SUBPROCESSES AND SUBAGENTS**: Use research subagents, subprocesses or parallel processing if available to thoroughly analyze different customer areas simultaneously and thoroughly
Start with customer research approach:
"Now I'll conduct **customer insights analysis** to understand customer behavior and needs.
**Customer Insights Focus:**
- Customer behavior patterns and preferences
- Pain points and challenges
- Decision-making processes
- Customer journey mapping
- Customer satisfaction drivers
- Demographic and psychographic profiles
**Let me search for current customer insights using parallel web searches for comprehensive coverage.**"
### 2. Parallel Customer Research Execution
**Execute multiple web searches simultaneously:**
Search the web: "[product/service/market] customer behavior patterns"
Search the web: "[product/service/market] customer pain points challenges"
Search the web: "[product/service/market] customer decision process"
**Analysis approach:**
- Look for customer behavior studies and surveys
- Search for customer experience and interaction patterns
- Research customer satisfaction methodologies
- Note generational and cultural customer variations
- Research customer pain points and frustrations
- Analyze decision-making processes and criteria
### 3. Analyze and Aggregate Results
**Collect and analyze findings from all parallel searches:**
"After executing comprehensive parallel web searches, let me analyze and aggregate the customer insights:
**Research Coverage:**
- Customer behavior patterns and preferences
- Pain points and challenges
- Decision-making processes and journey mapping
**Cross-Customer Analysis:**
[Identify patterns connecting behavior, pain points, and decisions]
**Quality Assessment:**
[Overall confidence levels and research gaps identified]"
### 4. Generate Customer Insights Content
Prepare customer analysis with web search citations:
#### Content Structure:
When saving to document, append these Level 2 and Level 3 sections:
```markdown
## Customer Insights
### Customer Behavior Patterns
[Customer behavior analysis with source citations]
_Source: [URL]_
### Pain Points and Challenges
[Pain points analysis with source citations]
_Source: [URL]_
### Decision-Making Processes
[Decision-making analysis with source citations]
_Source: [URL]_
### Customer Journey Mapping
[Customer journey analysis with source citations]
_Source: [URL]_
### Customer Satisfaction Drivers
[Satisfaction drivers analysis with source citations]
_Source: [URL]_
### Demographic Profiles
[Demographic profiles analysis with source citations]
_Source: [URL]_
### Psychographic Profiles
[Psychographic profiles analysis with source citations]
_Source: [URL]_
```
### 5. Present Analysis and Continue Option
Show the generated customer insights and present continue option:
"I've completed the **customer insights analysis** for customer behavior and needs.
**Key Customer Findings:**
- Customer behavior patterns clearly identified
- Pain points and challenges thoroughly documented
- Decision-making processes mapped
- Customer journey insights captured
- Satisfaction and profile data analyzed
**Ready to proceed to competitive analysis?**
[C] Continue - Save this to the document and proceed to competitive analysis
### 6. Handle Continue Selection
#### If 'C' (Continue):
- Append the final content to the research document
- Update frontmatter: `stepsCompleted: [1, 2]`
- Load: `./step-05-competitive-analysis.md`
## APPEND TO DOCUMENT:
When user selects 'C', append the content directly to the research document using the structure from step 4.
## SUCCESS METRICS:
✅ Customer behavior patterns identified with current citations
✅ Pain points and challenges clearly documented
✅ Decision-making processes thoroughly analyzed
✅ Customer journey insights captured and mapped
✅ Customer satisfaction drivers identified
✅ [C] continue option presented and handled correctly
✅ Content properly appended to document when C selected
## FAILURE MODES:
❌ Relying solely on training data without web verification for current facts
❌ Missing critical customer behavior patterns
❌ Not identifying key pain points and challenges
❌ Incomplete customer journey mapping
❌ Not presenting [C] continue option after content generation
❌ Appending content without user selecting 'C'
**CRITICAL**: Reading only partial step file - leads to incomplete understanding and poor decisions
**CRITICAL**: Proceeding with 'C' without fully reading and understanding the next step file
**CRITICAL**: Making decisions without complete understanding of step requirements and protocols
## CUSTOMER RESEARCH PROTOCOLS:
- Search for customer behavior studies and surveys
- Use market research firm and industry association sources
- Research customer experience and interaction patterns
- Note generational and cultural customer variations
- Research customer satisfaction methodologies
## NEXT STEP:
After user selects 'C' and content is saved to document, load `./step-05-competitive-analysis.md` to focus on competitive landscape analysis.
Remember: Always emphasize current customer data and rigorous source verification!

View File

@ -290,8 +290,8 @@ editWorkflow: './steps-e/step-e-01-discovery.md'
- ✅ Proper workflow path configuration - ✅ Proper workflow path configuration
**2. External Workflow References:** **2. External Workflow References:**
- ✅ Party-mode workflow: Exists at `/src/core/workflows/party-mode/workflow.md` - ✅ Party-mode workflow: Exists at `{project-root}/_bmad/core/workflows/party-mode/workflow.md`
- ✅ Advanced-elicitation task: Exists at `/src/core/workflows/advanced-elicitation/workflow.xml` - ✅ Advanced-elicitation task: Exists at `{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml`
**3. Directory Structure:** **3. Directory Structure:**
- ✅ Complete step architecture (all 3 modes) - ✅ Complete step architecture (all 3 modes)

View File

@ -17,9 +17,7 @@ const { ManifestGenerator } = require('./manifest-generator');
const { IdeConfigManager } = require('./ide-config-manager'); const { IdeConfigManager } = require('./ide-config-manager');
const { CustomHandler } = require('../custom/handler'); const { CustomHandler } = require('../custom/handler');
const prompts = require('../../../lib/prompts'); const prompts = require('../../../lib/prompts');
const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
// BMAD installation folder name - this is constant and should never change
const BMAD_FOLDER_NAME = '_bmad';
class Installer { class Installer {
constructor() { constructor() {

View File

@ -3,6 +3,7 @@ const fs = require('fs-extra');
const chalk = require('chalk'); const chalk = require('chalk');
const { XmlHandler } = require('../../../lib/xml-handler'); const { XmlHandler } = require('../../../lib/xml-handler');
const { getSourcePath } = require('../../../lib/project-root'); const { getSourcePath } = require('../../../lib/project-root');
const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
/** /**
* Base class for IDE-specific setup * Base class for IDE-specific setup
@ -18,7 +19,7 @@ class BaseIdeSetup {
this.configFile = null; // Override in subclasses when detection is file-based this.configFile = null; // Override in subclasses when detection is file-based
this.detectionPaths = []; // Additional paths that indicate the IDE is configured this.detectionPaths = []; // Additional paths that indicate the IDE is configured
this.xmlHandler = new XmlHandler(); this.xmlHandler = new XmlHandler();
this.bmadFolderName = '_bmad'; // Default, can be overridden this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
} }
/** /**
@ -57,7 +58,7 @@ class BaseIdeSetup {
if (this.configDir) { if (this.configDir) {
const configPath = path.join(projectDir, this.configDir); const configPath = path.join(projectDir, this.configDir);
if (await fs.pathExists(configPath)) { if (await fs.pathExists(configPath)) {
const bmadRulesPath = path.join(configPath, 'bmad'); const bmadRulesPath = path.join(configPath, BMAD_FOLDER_NAME);
if (await fs.pathExists(bmadRulesPath)) { if (await fs.pathExists(bmadRulesPath)) {
await fs.remove(bmadRulesPath); await fs.remove(bmadRulesPath);
console.log(chalk.dim(`Removed ${this.name} BMAD configuration`)); console.log(chalk.dim(`Removed ${this.name} BMAD configuration`));

View File

@ -1,6 +1,7 @@
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('node:path'); const path = require('node:path');
const chalk = require('chalk'); const chalk = require('chalk');
const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
/** /**
* IDE Manager - handles IDE-specific setup * IDE Manager - handles IDE-specific setup
@ -14,7 +15,7 @@ class IdeManager {
constructor() { constructor() {
this.handlers = new Map(); this.handlers = new Map();
this._initialized = false; this._initialized = false;
this.bmadFolderName = '_bmad'; // Default, can be overridden this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
} }
/** /**
@ -73,7 +74,9 @@ class IdeManager {
if (HandlerClass) { if (HandlerClass) {
const instance = new HandlerClass(); const instance = new HandlerClass();
if (instance.name && typeof instance.name === 'string') { if (instance.name && typeof instance.name === 'string') {
instance.setBmadFolderName(this.bmadFolderName); if (typeof instance.setBmadFolderName === 'function') {
instance.setBmadFolderName(this.bmadFolderName);
}
this.handlers.set(instance.name, instance); this.handlers.set(instance.name, instance);
} }
} }
@ -101,7 +104,9 @@ class IdeManager {
if (!platformInfo.installer) continue; if (!platformInfo.installer) continue;
const handler = new ConfigDrivenIdeSetup(platformCode, platformInfo); const handler = new ConfigDrivenIdeSetup(platformCode, platformInfo);
handler.setBmadFolderName(this.bmadFolderName); if (typeof handler.setBmadFolderName === 'function') {
handler.setBmadFolderName(this.bmadFolderName);
}
this.handlers.set(platformCode, handler); this.handlers.set(platformCode, handler);
} }
} }

View File

@ -1,14 +1,14 @@
const path = require('node:path'); const path = require('node:path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const chalk = require('chalk'); const chalk = require('chalk');
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName } = require('./path-utils'); const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
/** /**
* Generates launcher command files for each agent * Generates launcher command files for each agent
* Similar to WorkflowCommandGenerator but for agents * Similar to WorkflowCommandGenerator but for agents
*/ */
class AgentCommandGenerator { class AgentCommandGenerator {
constructor(bmadFolderName = '_bmad') { constructor(bmadFolderName = BMAD_FOLDER_NAME) {
this.templatePath = path.join(__dirname, '../templates/agent-command-template.md'); this.templatePath = path.join(__dirname, '../templates/agent-command-template.md');
this.bmadFolderName = bmadFolderName; this.bmadFolderName = bmadFolderName;
} }

View File

@ -18,6 +18,9 @@
const TYPE_SEGMENTS = ['workflows', 'tasks', 'tools']; const TYPE_SEGMENTS = ['workflows', 'tasks', 'tools'];
const AGENT_SEGMENT = 'agents'; const AGENT_SEGMENT = 'agents';
// BMAD installation folder name - centralized constant for all installers
const BMAD_FOLDER_NAME = '_bmad';
/** /**
* Convert hierarchical path to flat dash-separated name (NEW STANDARD) * Convert hierarchical path to flat dash-separated name (NEW STANDARD)
* Converts: 'bmm', 'agents', 'pm' 'bmad-agent-bmm-pm.md' * Converts: 'bmm', 'agents', 'pm' 'bmad-agent-bmm-pm.md'
@ -292,4 +295,5 @@ module.exports = {
TYPE_SEGMENTS, TYPE_SEGMENTS,
AGENT_SEGMENT, AGENT_SEGMENT,
BMAD_FOLDER_NAME,
}; };

View File

@ -2,20 +2,20 @@ const path = require('node:path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const csv = require('csv-parse/sync'); const csv = require('csv-parse/sync');
const chalk = require('chalk'); const chalk = require('chalk');
const { toColonName, toColonPath, toDashPath } = require('./path-utils'); const { toColonName, toColonPath, toDashPath, BMAD_FOLDER_NAME } = require('./path-utils');
/** /**
* Generates command files for standalone tasks and tools * Generates command files for standalone tasks and tools
*/ */
class TaskToolCommandGenerator { class TaskToolCommandGenerator {
/** /**
* @param {string} bmadFolderName - Name of the BMAD folder for template rendering (default: 'bmad') * @param {string} bmadFolderName - Name of the BMAD folder for template rendering (default: '_bmad')
* Note: This parameter is accepted for API consistency with AgentCommandGenerator and * Note: This parameter is accepted for API consistency with AgentCommandGenerator and
* WorkflowCommandGenerator, but is not used for path stripping. The manifest always stores * WorkflowCommandGenerator, but is not used for path stripping. The manifest always stores
* filesystem paths with '_bmad/' prefix (the actual folder name), while bmadFolderName is * filesystem paths with '_bmad/' prefix (the actual folder name), while bmadFolderName is
* used for template placeholder rendering ({{bmadFolderName}}). * used for template placeholder rendering ({{bmadFolderName}}).
*/ */
constructor(bmadFolderName = '_bmad') { constructor(bmadFolderName = BMAD_FOLDER_NAME) {
this.bmadFolderName = bmadFolderName; this.bmadFolderName = bmadFolderName;
} }
@ -33,13 +33,18 @@ class TaskToolCommandGenerator {
const standaloneTools = tools ? tools.filter((t) => t.standalone === 'true' || t.standalone === true) : []; const standaloneTools = tools ? tools.filter((t) => t.standalone === 'true' || t.standalone === true) : [];
const artifacts = []; const artifacts = [];
const bmadPrefix = `${BMAD_FOLDER_NAME}/`;
// Collect task artifacts // Collect task artifacts
for (const task of standaloneTasks) { for (const task of standaloneTasks) {
let taskPath = (task.path || '').replaceAll('\\', '/'); let taskPath = (task.path || '').replaceAll('\\', '/');
// Convert absolute paths to relative paths
if (path.isAbsolute(taskPath)) {
taskPath = path.relative(bmadDir, taskPath).replaceAll('\\', '/');
}
// Remove _bmad/ prefix if present to get relative path within bmad folder // Remove _bmad/ prefix if present to get relative path within bmad folder
if (taskPath.startsWith('_bmad/')) { if (taskPath.startsWith(bmadPrefix)) {
taskPath = taskPath.slice(6); // Remove '_bmad/' taskPath = taskPath.slice(bmadPrefix.length);
} }
const taskExt = path.extname(taskPath) || '.md'; const taskExt = path.extname(taskPath) || '.md';
@ -58,9 +63,13 @@ class TaskToolCommandGenerator {
// Collect tool artifacts // Collect tool artifacts
for (const tool of standaloneTools) { for (const tool of standaloneTools) {
let toolPath = (tool.path || '').replaceAll('\\', '/'); let toolPath = (tool.path || '').replaceAll('\\', '/');
// Convert absolute paths to relative paths
if (path.isAbsolute(toolPath)) {
toolPath = path.relative(bmadDir, toolPath).replaceAll('\\', '/');
}
// Remove _bmad/ prefix if present to get relative path within bmad folder // Remove _bmad/ prefix if present to get relative path within bmad folder
if (toolPath.startsWith('_bmad/')) { if (toolPath.startsWith(bmadPrefix)) {
toolPath = toolPath.slice(6); // Remove '_bmad/' toolPath = toolPath.slice(bmadPrefix.length);
} }
const toolExt = path.extname(toolPath) || '.md'; const toolExt = path.extname(toolPath) || '.md';
@ -159,9 +168,9 @@ class TaskToolCommandGenerator {
if (bmadMatch) { if (bmadMatch) {
// Found /_bmad/ or /bmad/ - use relative path after it // Found /_bmad/ or /bmad/ - use relative path after it
itemPath = `{project-root}/${this.bmadFolderName}/${bmadMatch[1]}`; itemPath = `{project-root}/${this.bmadFolderName}/${bmadMatch[1]}`;
} else if (itemPath.startsWith('_bmad/')) { } else if (itemPath.startsWith(`${BMAD_FOLDER_NAME}/`)) {
// Relative path starting with _bmad/ // Relative path starting with _bmad/
itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(6)}`; itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(BMAD_FOLDER_NAME.length + 1)}`;
} else if (itemPath.startsWith('bmad/')) { } else if (itemPath.startsWith('bmad/')) {
// Relative path starting with bmad/ // Relative path starting with bmad/
itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(5)}`; itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(5)}`;

View File

@ -2,13 +2,13 @@ const path = require('node:path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const csv = require('csv-parse/sync'); const csv = require('csv-parse/sync');
const chalk = require('chalk'); const chalk = require('chalk');
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName } = require('./path-utils'); const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
/** /**
* Generates command files for each workflow in the manifest * Generates command files for each workflow in the manifest
*/ */
class WorkflowCommandGenerator { class WorkflowCommandGenerator {
constructor(bmadFolderName = '_bmad') { constructor(bmadFolderName = BMAD_FOLDER_NAME) {
this.templatePath = path.join(__dirname, '../templates/workflow-command-template.md'); this.templatePath = path.join(__dirname, '../templates/workflow-command-template.md');
this.bmadFolderName = bmadFolderName; this.bmadFolderName = bmadFolderName;
} }

View File

@ -7,6 +7,7 @@ const { XmlHandler } = require('../../../lib/xml-handler');
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root'); const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
const { filterCustomizationData } = require('../../../lib/agent/compiler'); const { filterCustomizationData } = require('../../../lib/agent/compiler');
const { ExternalModuleManager } = require('./external-manager'); const { ExternalModuleManager } = require('./external-manager');
const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
/** /**
* Manages the installation, updating, and removal of BMAD modules. * Manages the installation, updating, and removal of BMAD modules.
@ -27,7 +28,7 @@ const { ExternalModuleManager } = require('./external-manager');
class ModuleManager { class ModuleManager {
constructor(options = {}) { constructor(options = {}) {
this.xmlHandler = new XmlHandler(); this.xmlHandler = new XmlHandler();
this.bmadFolderName = '_bmad'; // Default, can be overridden this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
this.customModulePaths = new Map(); // Initialize custom module paths this.customModulePaths = new Map(); // Initialize custom module paths
this.externalModuleManager = new ExternalModuleManager(); // For external official modules this.externalModuleManager = new ExternalModuleManager(); // For external official modules
} }