Compare commits

...

6 Commits

47 changed files with 432 additions and 209 deletions

View File

@ -0,0 +1,79 @@
---
title: "Set Up Monorepo Support"
description: Manage multiple projects in a single repository with isolated artifacts
sidebar:
order: 8
---
BMad Method supports working in monorepo environments where multiple projects share a single repository. This allows you to centralize methodology files while keeping project artifacts isolated and organized.
:::note[Prerequisites]
- BMad Method v6.0.1+
- A repository containing multiple projects
:::
## Why Use Monorepo Support?
In a standard setup, BMad expects one project per repository. In a monorepo, you might have `apps/frontend`, `apps/backend`, and `packages/shared`. Without monorepo support, BMad's artifacts (plans, architecture, stories) would be mixed or require installing BMad in every sub-directory.
Monorepo support allows you to:
- **Centralize Methodology**: Install BMad once at the root based on your team's process.
- **Isolate Artifacts**: Automatically route outputs to project-specific folders (e.g., `_bmad-output/frontend/`).
- **Context Switch Easily**: Switch between projects without reinstalling or reconfiguring.
## Project Structure
When monorepo support is active, the structure changes slightly to accommodate multiple projects:
```
monorepo-root/
├── _bmad/ # Methodology (installed core & modules)
│ └── .current_project # Context marker (e.g., "app-alpha")
├── _bmad-output/ # Unified output directory
│ ├── app-alpha/ # Sub-project artifacts
│ │ ├── planning-artifacts/
│ │ └── implementation-artifacts/
│ └── app-beta/ # Sub-project artifacts
│ └── planning-artifacts/
├── apps/ # Actual source code
│ ├── app-alpha/
│ └── app-beta/
└── package.json
```
## How It Works
### Context Injection
Core and BMM workflows automatically check for the existence of `_bmad/.current_project`.
- **If found**: It reads the content (e.g., "app-alpha") and overrides the `output_folder` to `_bmad-output/app-alpha`.
- **If not found**: It behaves like a standard single-project installation, outputting to `_bmad-output` root.
### The /set-project Command
You can easily manage the active project context using the `/set-project` workflow.
**To set a context:**
1. Run `/set-project` in your chat.
2. Select "Set Project Context".
3. Enter the name of your project (e.g., `frontend`, `backend`, `mobile-app`).
**To clear context (return to single-project mode):**
1. Run `/set-project`.
2. Select "Clear Project Context".
### Inline Override
You can temporarily override the project context for a specific command without changing the global `.current_project` state. This is useful for one-off tasks in a different project.
Use the `#project:` syntax (or `#p:` for short) anywhere in your prompt:
```bash
# Full syntax
/create-prd #project:myproject_name
# Short alias
/create-story #p:frontend
```
**Note:** The inline override takes precedence over the `.current_project` file. If no project is specified via `#` or `.current_project`, BMad defaults to the root `_bmad-output` folder.

View File

@ -18,6 +18,12 @@ The fastest way to understand BMad is to try it.
Install BMad and run `/bmad-help` — it will guide you through everything based on your project and installed modules. Install BMad and run `/bmad-help` — it will guide you through everything based on your project and installed modules.
::: :::
## Advanced Setup
- **[Monorepo Support](./how-to/monorepo-setup.md)** — Manage multiple projects in a single repository.
- **[Non-Interactive Installation](./how-to/non-interactive-installation.md)** — Automate BMad installation for CI/CD.
## How to Use These Docs ## How to Use These Docs
These docs are organized into four sections based on what you're trying to do: These docs are organized into four sections based on what you're trying to do:

View File

@ -34,3 +34,16 @@ Load and read full config from {main_config} and resolve basic variables.
### 3. Verification ### 3. Verification
- Display the full resolved output path for confirmation. - Display the full resolved output path for confirmation.
## Inline Project Overrides
You can also temporarily run a command against a different project without changing the global context file. Use the `#project:NAME` or `#p:NAME` syntax in your command invocation.
**Examples:**
- `/create-prd #project:my-app`
- `/sprint-planning #p:admin-portal`
**Precedence:**
1. **Inline Override** (`#p:NAME`)
2. **Global Context File** (`_bmad/.current_project`)
3. **Default Config** (if neither is present)

View File

@ -51,11 +51,6 @@ This uses **step-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language`, `user_skill_level` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language`, `user_skill_level`
### 2. First Step EXECUTION ### 2. First Step EXECUTION

View File

@ -373,6 +373,7 @@ _This comprehensive research document serves as an authoritative reference on {{
#### If 'C' (Complete Research): #### If 'C' (Complete Research):
- **Replace** the template placeholder `[Research overview and methodology will be appended here]` in the `## Research Overview` section near the top of the document with a concise 2-3 paragraph overview summarizing the research scope, key findings, and a pointer to the full executive summary in the Research Synthesis section
- Append the complete document to the research file - Append the complete document to the research file
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5]` - Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5]`
- Complete the domain research workflow - Complete the domain research workflow
@ -380,7 +381,7 @@ _This comprehensive research document serves as an authoritative reference on {{
## APPEND TO DOCUMENT: ## APPEND TO DOCUMENT:
When user selects 'C', append the complete comprehensive research document using the full structure above. When user selects 'C', append the complete comprehensive research document using the full structure above. Also replace the `[Research overview and methodology will be appended here]` placeholder in the Research Overview section at the top of the document.
## SUCCESS METRICS: ## SUCCESS METRICS:

View File

@ -389,13 +389,14 @@ _This comprehensive market research document serves as an authoritative market r
#### If 'C' (Complete Research): #### If 'C' (Complete Research):
- **Replace** the template placeholder `[Research overview and methodology will be appended here]` in the `## Research Overview` section near the top of the document with a concise 2-3 paragraph overview summarizing the research scope, key findings, and a pointer to the full executive summary in the Research Synthesis section
- Append the final content to the research document - Append the final content to the research document
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4]` - Update frontmatter: `stepsCompleted: [1, 2, 3, 4]`
- Complete the market research workflow - Complete the market research workflow
## APPEND TO DOCUMENT: ## APPEND TO DOCUMENT:
When user selects 'C', append the content directly to the research document using the structure from step 4. When user selects 'C', append the content directly to the research document using the structure from step 4. Also replace the `[Research overview and methodology will be appended here]` placeholder in the Research Overview section at the top of the document.
## SUCCESS METRICS: ## SUCCESS METRICS:

View File

@ -416,6 +416,7 @@ _This comprehensive technical research document serves as an authoritative techn
#### If 'C' (Complete Research): #### If 'C' (Complete Research):
- **Replace** the template placeholder `[Research overview and methodology will be appended here]` in the `## Research Overview` section near the top of the document with a concise 2-3 paragraph overview summarizing the research scope, key findings, and a pointer to the full executive summary in the Research Synthesis section
- Append the complete technical document to the research file - Append the complete technical document to the research file
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5, 6]` - Update frontmatter: `stepsCompleted: [1, 2, 3, 4, 5, 6]`
- Complete the technical research workflow - Complete the technical research workflow
@ -423,7 +424,7 @@ _This comprehensive technical research document serves as an authoritative techn
## APPEND TO DOCUMENT: ## APPEND TO DOCUMENT:
When user selects 'C', append the complete comprehensive technical research document using the full structure above. When user selects 'C', append the complete comprehensive technical research document using the full structure above. Also replace the `[Research overview and methodology will be appended here]` placeholder in the Research Overview section at the top of the document.
## SUCCESS METRICS: ## SUCCESS METRICS:

View File

@ -20,10 +20,6 @@ main_config: '{project-root}/_bmad/bmm/config.yaml'
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -20,10 +20,6 @@ main_config: '{project-root}/_bmad/bmm/config.yaml'
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -20,10 +20,6 @@ main_config: '{project-root}/_bmad/bmm/config.yaml'
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -46,15 +46,6 @@ This uses **step-file architecture** for disciplined execution:
## INITIALIZATION SEQUENCE ## INITIALIZATION SEQUENCE
### 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime - `date` as system-generated current datetime

View File

@ -50,10 +50,6 @@ This uses **step-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime - `date` as system-generated current datetime

View File

@ -50,10 +50,6 @@ This uses **step-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -26,10 +26,6 @@ This uses **micro-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -46,11 +46,6 @@ description: 'Critical validation workflow that assesses PRD, Architecture, and
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language`
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}` - ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`

View File

@ -29,11 +29,6 @@ This uses **micro-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `output_folder`, `planning_artifacts`, `user_name` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`

View File

@ -50,10 +50,6 @@ This uses **step-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language` - `project_name`, `output_folder`, `planning_artifacts`, `user_name`, `communication_language`, `document_output_language`
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}` - ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`

View File

@ -40,15 +40,7 @@
- [x] Done - Item completed successfully - [x] Done - Item completed successfully
- [N/A] Skip - Item not applicable to this change - [N/A] Skip - Item not applicable to this change
- [!] Action-needed - Item requires attention or follow-up - [!] Action-needed - Item requires attention or follow-up
### 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
<action>Maintain running notes of findings and impacts discovered</action>
<action>Present checklist progress after each major section</action> <action>Present checklist progress after each major section</action>
<action if="checklist cannot be completed">Identify blocking issues and work with user to resolve before continuing</action> <action if="checklist cannot be completed">Identify blocking issues and work with user to resolve before continuing</action>

View File

@ -18,21 +18,6 @@
<critical>🎯 ZERO USER INTERVENTION: Process should be fully automated except for initial epic/story selection or missing documents</critical> <critical>🎯 ZERO USER INTERVENTION: Process should be fully automated except for initial epic/story selection or missing documents</critical>
<step n="1" goal="Determine target story"> <step n="1" goal="Determine target story">
<check if="{project-root}/_bmad/.current_project exists">
<action>Read content as project_suffix</action>
<!-- Sanitization and Validation -->
<action>Trim whitespace and newlines from project_suffix</action>
<check if="project_suffix contains '..' or starts with '/' or starts with '\'">
<output>🚫 Security Error: Invalid project context path detected.</output>
<action>HALT</action>
</check>
<check if="project_suffix matches regex '[^a-zA-Z0-9._-]|^\s*$'">
<output>🚫 Error: Project context must only contain alphanumeric characters, dots, dashes, or underscores.</output>
<action>HALT</action>
</check>
<action>Override output_folder to {project-root}/_bmad-output/{project_suffix}</action>
<action>Output "Monorepo context detected. Output folder redirected to: {output_folder}"</action>
</check>
<check if="{{story_path}} is provided by user or user provided the epic and story number such as 2-4 or 1.6 or epic 1 story 5"> <check if="{{story_path}} is provided by user or user provided the epic and story number such as 2-4 or 1.6 or epic 1 story 5">
<action>Parse user-provided story path: extract epic_num, story_num, story_title from format like "1-2-user-auth"</action> <action>Parse user-provided story path: extract epic_num, story_num, story_title from format like "1-2-user-auth"</action>

View File

@ -13,24 +13,6 @@
<critical>User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.</critical> <critical>User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.</critical>
<step n="1" goal="Find next ready story and load it" tag="sprint-status"> <step n="1" goal="Find next ready story and load it" tag="sprint-status">
<check if="{project-root}/_bmad/.current_project exists">
<action>Read content as project_suffix</action>
<!-- Sanitization and Validation -->
<action>Trim whitespace and newlines from project_suffix</action>
<check if="project_suffix contains '..' or starts with '/' or starts with '\'">
<output>🚫 Security Error: Invalid project context path detected.</output>
<action>HALT</action>
</check>
<check if="project_suffix matches regex '[^a-zA-Z0-9._-]|^\s*$'">
<output>🚫 Error: Project context must only contain alphanumeric characters, dots, dashes, or underscores.</output>
<action>HALT</action>
</check>
<check if="project_suffix.length > 100">
<output>🚫 Error: Project context name is too long (max 100 characters).</output>
<action>HALT</action>
</check>
<action>Override output_folder to {project-root}/_bmad-output/{project_suffix}</action>
</check>
<check if="{{story_path}} is provided"> <check if="{{story_path}} is provided">
<action>Use {{story_path}} directly</action> <action>Use {{story_path}} directly</action>

View File

@ -3,17 +3,6 @@
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical> <critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
<critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical> <critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical>
## 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
3. Re-derive dependent path variables to reflect the new `output_folder`:
- `implementation_artifacts`: `{output_folder}/implementation`
- `planning_artifacts`: `{output_folder}/planning`
<critical>Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}</critical> <critical>Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}</critical>
<critical>Generate all documents in {document_output_language}</critical> <critical>Generate all documents in {document_output_language}</critical>

View File

@ -4,14 +4,6 @@
<critical>You MUST have already loaded and processed: {project-root}/_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml</critical> <critical>You MUST have already loaded and processed: {project-root}/_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml</critical>
## 📚 Document Discovery ## 📚 Document Discovery
### 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- Full Epic Loading - Full Epic Loading

View File

@ -2,14 +2,6 @@
<critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical> <critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
## 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
<critical>You MUST have already loaded and processed: {project-root}/_bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml</critical> <critical>You MUST have already loaded and processed: {project-root}/_bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml</critical>
<critical>Modes: interactive (default), validate, data</critical> <critical>Modes: interactive (default), validate, data</critical>
<critical>⚠️ ABSOLUTELY NO TIME ESTIMATES. Do NOT mention hours, days, weeks, or timelines.</critical> <critical>⚠️ ABSOLUTELY NO TIME ESTIMATES. Do NOT mention hours, days, weeks, or timelines.</critical>

View File

@ -27,11 +27,6 @@ This uses **step-file architecture** for focused execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `user_name`, `communication_language`, `user_skill_level` - `user_name`, `communication_language`, `user_skill_level`

View File

@ -68,11 +68,6 @@ This uses **step-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name` - `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -83,10 +83,6 @@
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
<step n="3" goal="Check for existing documentation and determine workflow mode" if="resume_mode == false"> <step n="3" goal="Check for existing documentation and determine workflow mode" if="resume_mode == false">
<action>Check if {project_knowledge}/index.md exists</action> <action>Check if {project_knowledge}/index.md exists</action>

View File

@ -95,15 +95,7 @@ Your choice [1/2/3]:
- Best for: Quick project overview, initial understanding - Best for: Quick project overview, initial understanding
- File reading: Minimal (configs, README, package.json, etc.) - File reading: Minimal (configs, README, package.json, etc.)
## 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
json, etc.)
**2. Deep Scan** (10-30 minutes) **2. Deep Scan** (10-30 minutes)

View File

@ -29,12 +29,6 @@ This uses **micro-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `output_folder`, `user_name` - `project_name`, `output_folder`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -18,14 +18,6 @@ Check project for existing test framework:
- Search online for current recommended test framework for that stack - Search online for current recommended test framework for that stack
- Suggest the meta framework and use it (or ask user to confirm) - Suggest the meta framework and use it (or ask user to confirm)
### 1. Configuration Loading
Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
### Step 1: Identify Features ### Step 1: Identify Features

View File

@ -18,7 +18,11 @@
<flow> <flow>
<step n="1" title="Load and Initialize Workflow"> <step n="1" title="Load and Initialize Workflow">
<substep n="1a" title="Load Configuration and Resolve Variables"> <substep n="1a" title="Monorepo Context Injection">
{{monorepo_context_logic}}
</substep>
<substep n="1b" title="Load Configuration and Resolve Variables">
<action>Read workflow.yaml from provided path</action> <action>Read workflow.yaml from provided path</action>
<mandate>Load config_source (REQUIRED for all modules)</mandate> <mandate>Load config_source (REQUIRED for all modules)</mandate>
<phase n="1">Load external config from config_source path</phase> <phase n="1">Load external config from config_source path</phase>
@ -27,7 +31,7 @@
<phase n="4">Ask user for input of any variables that are still unknown</phase> <phase n="4">Ask user for input of any variables that are still unknown</phase>
</substep> </substep>
<substep n="1b" title="Load Required Components"> <substep n="1c" title="Load Required Components">
<mandate>Instructions: Read COMPLETE file from path OR embedded list (REQUIRED)</mandate> <mandate>Instructions: Read COMPLETE file from path OR embedded list (REQUIRED)</mandate>
<check>If template path → Read COMPLETE template file</check> <check>If template path → Read COMPLETE template file</check>
<check>If validation path → Note path for later loading when needed</check> <check>If validation path → Note path for later loading when needed</check>
@ -35,7 +39,7 @@
<note>Data files (csv, json) → Store paths only, load on-demand when instructions reference them</note> <note>Data files (csv, json) → Store paths only, load on-demand when instructions reference them</note>
</substep> </substep>
<substep n="1c" title="Initialize Output" if="template-workflow"> <substep n="1d" title="Initialize Output" if="template-workflow">
<action>Resolve default_output_file path with all variables and {{date}}</action> <action>Resolve default_output_file path with all variables and {{date}}</action>
<action>Create output directory if doesn't exist</action> <action>Create output directory if doesn't exist</action>
<action>If template-workflow → Write template to output file with placeholders</action> <action>If template-workflow → Write template to output file with placeholders</action>

View File

@ -20,6 +20,7 @@
<flow> <flow>
<step n="1" title="Method Registry Loading"> <step n="1" title="Method Registry Loading">
<!-- Retained inline check because this workflow may be invoked as a standalone tool mid-conversation, bypassing the OS-level context injection. -->
<check if="{project-root}/_bmad/.current_project exists"> <check if="{project-root}/_bmad/.current_project exists">
<action>Read content as project_suffix</action> <action>Read content as project_suffix</action>
<!-- Sanitization and Validation --> <!-- Sanitization and Validation -->

View File

@ -36,12 +36,6 @@ This uses **micro-file architecture** for disciplined execution:
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
Load config from `{project-root}/_bmad/core/config.yaml` and resolve:
- `project_name`, `output_folder`, `user_name` - `project_name`, `output_folder`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`

View File

@ -29,11 +29,6 @@ This uses **micro-file architecture** with **sequential conversation orchestrati
Load and read full config from {main_config} and resolve basic variables. Load and read full config from {main_config} and resolve basic variables.
**Monorepo Context Check:**
1. Check if `{project-root}/_bmad/.current_project` exists.
2. If it exists, read its content as `{project_suffix}` and override output folder:
- `output_folder`: `{project-root}/_bmad-output/{project_suffix}`
- `project_name`, `output_folder`, `user_name` - `project_name`, `output_folder`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level` - `communication_language`, `document_output_language`, `user_skill_level`
- `date` as a system-generated value - `date` as a system-generated value

View File

@ -0,0 +1,206 @@
/**
* Context Logic Integration Tests
*
* Validates the centralized monorepo context logic deduplication:
* 1. context-logic.js exports a valid XML block
* 2. All workflow templates that need it use the {{monorepo_context_logic}} placeholder
* 3. No stale hardcoded <monorepo-context-check> blocks exist in templates
* 4. src/core/tasks/workflow.xml uses the placeholder (not a hardcoded block)
* 5. All JS consumers correctly import context-logic.js
* 6. MONOREPO_CONTEXT_LOGIC string integrity (key fields are present)
*/
const fs = require('fs-extra');
const path = require('node:path');
// ANSI colors
const c = {
reset: '\u001B[0m',
green: '\u001B[32m',
red: '\u001B[31m',
yellow: '\u001B[33m',
cyan: '\u001B[36m',
dim: '\u001B[2m',
};
let passed = 0;
let failed = 0;
function ok(condition, testName, detail = '') {
if (condition) {
console.log(`${c.green}${c.reset} ${testName}`);
passed++;
} else {
console.log(`${c.red}${c.reset} ${testName}`);
if (detail) console.log(` ${c.dim}${detail}${c.reset}`);
failed++;
}
}
async function readFile(p) {
return fs.readFile(p, 'utf8');
}
async function exists(p) {
return fs.pathExists(p);
}
async function runTests() {
console.log(`${c.cyan}============================================================`);
console.log(' Context Logic Integration Tests');
console.log(`============================================================${c.reset}\n`);
const root = path.join(__dirname, '..');
const sharedDir = path.join(root, 'tools/cli/installers/lib/ide/shared');
const templatesDir = path.join(root, 'tools/cli/installers/lib/ide/templates');
const combinedDir = path.join(templatesDir, 'combined');
// ────────────────────────────────────────────────────────────
// Suite 1: context-logic.js module integrity
// ────────────────────────────────────────────────────────────
console.log(`${c.yellow}Suite 1: context-logic.js module integrity${c.reset}\n`);
const contextLogicPath = path.join(sharedDir, 'context-logic.js');
ok(await exists(contextLogicPath), 'context-logic.js file exists');
let MONOREPO_CONTEXT_LOGIC;
try {
const mod = require(contextLogicPath);
ok(typeof mod.MONOREPO_CONTEXT_LOGIC === 'string', 'exports MONOREPO_CONTEXT_LOGIC as a string');
ok(mod.MONOREPO_CONTEXT_LOGIC.length > 0, 'MONOREPO_CONTEXT_LOGIC is non-empty');
MONOREPO_CONTEXT_LOGIC = mod.MONOREPO_CONTEXT_LOGIC;
} catch (error) {
ok(false, 'context-logic.js is require()-able', error.message);
MONOREPO_CONTEXT_LOGIC = '';
}
// Key content checks
ok(MONOREPO_CONTEXT_LOGIC.includes('<monorepo-context-check'), 'has opening <monorepo-context-check> tag');
ok(MONOREPO_CONTEXT_LOGIC.includes('</monorepo-context-check>'), 'has closing </monorepo-context-check> tag');
ok(MONOREPO_CONTEXT_LOGIC.includes('#project:NAME'), 'documents #project:NAME syntax');
ok(MONOREPO_CONTEXT_LOGIC.includes('#p:NAME'), 'documents #p:NAME short alias');
ok(MONOREPO_CONTEXT_LOGIC.includes('.current_project'), 'includes .current_project fallback logic');
ok(MONOREPO_CONTEXT_LOGIC.includes('path traversal'), 'includes path traversal security check');
ok(MONOREPO_CONTEXT_LOGIC.includes('output_folder'), 'overrides output_folder path variable');
ok(MONOREPO_CONTEXT_LOGIC.includes('planning_artifacts'), 'overrides planning_artifacts path variable');
ok(MONOREPO_CONTEXT_LOGIC.includes('HALT'), 'halts on security violation');
console.log('');
// ────────────────────────────────────────────────────────────
// Suite 2: JS consumers import context-logic.js correctly
// ────────────────────────────────────────────────────────────
console.log(`${c.yellow}Suite 2: JS consumers import context-logic.js${c.reset}\n`);
const consumers = [
{
file: 'tools/cli/installers/lib/core/installer.js',
expectedImport: "require('../ide/shared/context-logic')",
},
{
file: 'tools/cli/installers/lib/ide/_config-driven.js',
expectedImport: "require('./shared/context-logic')",
},
{
file: 'tools/cli/installers/lib/ide/shared/workflow-command-generator.js',
expectedImport: "require('./context-logic')",
},
];
for (const { file, expectedImport } of consumers) {
const fullPath = path.join(root, file);
const content = await readFile(fullPath);
ok(content.includes(expectedImport), `${path.basename(file)} imports context-logic correctly`);
ok(content.includes("replaceAll('{{monorepo_context_logic}}'"), `${path.basename(file)} uses replaceAll for placeholder`);
}
console.log('');
// ────────────────────────────────────────────────────────────
// Suite 3: Templates use placeholder, not hardcoded blocks
// ────────────────────────────────────────────────────────────
console.log(`${c.yellow}Suite 3: Templates use {{monorepo_context_logic}} placeholder${c.reset}\n`);
// These templates MUST have the placeholder (they are rendered directly as IDE workflow commands)
const mustHavePlaceholder = [
path.join(templatesDir, 'workflow-command-template.md'),
path.join(templatesDir, 'workflow-commander.md'),
path.join(combinedDir, 'antigravity.md'),
path.join(combinedDir, 'claude-workflow.md'),
path.join(combinedDir, 'claude-workflow-yaml.md'),
path.join(combinedDir, 'default-workflow.md'),
path.join(combinedDir, 'default-workflow-yaml.md'),
path.join(combinedDir, 'kiro-workflow.md'),
path.join(combinedDir, 'opencode-workflow.md'),
path.join(combinedDir, 'windsurf-workflow.md'),
];
for (const filePath of mustHavePlaceholder) {
const rel = path.relative(root, filePath);
const content = await readFile(filePath);
ok(content.includes('{{monorepo_context_logic}}'), `${path.basename(filePath)} has {{monorepo_context_logic}} placeholder`);
// Must NOT have raw hardcoded block (only the shared module should have it)
ok(!content.includes('<monorepo-context-check'), `${path.basename(filePath)} has NO hardcoded <monorepo-context-check> block`);
}
console.log('');
// ────────────────────────────────────────────────────────────
// Suite 4: No rogue hardcoded blocks anywhere in templates dir
// ────────────────────────────────────────────────────────────
console.log(`${c.yellow}Suite 4: No hardcoded blocks in templates directory${c.reset}\n`);
const walkDir = async (dir) => {
const entries = await fs.readdir(dir, { withFileTypes: true });
const files = [];
for (const e of entries) {
const full = path.join(dir, e.name);
if (e.isDirectory()) files.push(...(await walkDir(full)));
else if (e.isFile()) files.push(full);
}
return files;
};
const allTemplateFiles = await walkDir(templatesDir);
const rogueFiles = [];
for (const f of allTemplateFiles) {
const content = await readFile(f);
if (content.includes('<monorepo-context-check') && !f.includes('context-logic.js')) {
rogueFiles.push(path.relative(root, f));
}
}
ok(
rogueFiles.length === 0,
`No hardcoded <monorepo-context-check> blocks in templates (found ${rogueFiles.length})`,
rogueFiles.length > 0 ? `Rogue files: ${rogueFiles.join(', ')}` : '',
);
console.log('');
// ────────────────────────────────────────────────────────────
// Suite 5: src/core/tasks/workflow.xml uses placeholder
// ────────────────────────────────────────────────────────────
console.log(`${c.yellow}Suite 5: src/core/tasks/workflow.xml uses placeholder${c.reset}\n`);
const srcWorkflowXml = path.join(root, 'src/core/tasks/workflow.xml');
ok(await exists(srcWorkflowXml), 'src/core/tasks/workflow.xml exists');
const srcXmlContent = await readFile(srcWorkflowXml);
ok(srcXmlContent.includes('{{monorepo_context_logic}}'), 'workflow.xml (src) uses {{monorepo_context_logic}} placeholder');
ok(!srcXmlContent.includes('<monorepo-context-check'), 'workflow.xml (src) has NO hardcoded <monorepo-context-check> block');
// ────────────────────────────────────────────────────────────
// Results
// ────────────────────────────────────────────────────────────
console.log(`\n${c.cyan}============================================================`);
console.log(` Results: ${c.green}${passed} passed${c.reset}${c.cyan}, ${c.red}${failed} failed${c.reset}${c.cyan}`);
console.log(`============================================================${c.reset}\n`);
if (failed === 0) {
console.log(`${c.green}✨ All context-logic integration tests passed!${c.reset}\n`);
process.exit(0);
} else {
console.log(`${c.red}${failed} test(s) failed${c.reset}\n`);
process.exit(1);
}
}
runTests().catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -1,9 +1,19 @@
/** /**
* Monorepo Support Validation Tests * Monorepo Support Validation Tests
* *
* Verifies that: * Architecture after deduplication:
* - Monorepo context logic lives ONLY in context-logic.js
* - workflow.xml (src) uses {{monorepo_context_logic}} placeholder injected at install time
* - Individual source workflow files do NOT have inline checks (that's the deduplication!)
* - Only code-review/instructions.xml, dev-story/instructions.xml, create-story/instructions.xml
* and advanced-elicitation/workflow.xml are XML workflows checked; XML workflows that go through
* workflow.xml no longer need inline checks.
*
* Verifies:
* 1. The set-project workflow is correctly registered. * 1. The set-project workflow is correctly registered.
* 2. All core and BMM workflows contain the monorepo context logic. * 2. No source workflow file has a stale inline "Monorepo Context Check" block.
* 3. Only the canonical SINGLE source (context-logic.js) defines the check.
* 4. set-project implementation still manages .current_project.
*/ */
const fs = require('fs-extra'); const fs = require('fs-extra');
@ -55,46 +65,39 @@ async function runTests() {
console.log(''); console.log('');
// 2. Verify context logic in workflows // 2. Verify NO stale inline "Monorepo Context Check" blocks in source workflow files
console.log(`${colors.yellow}Test Suite 2: Workflow Context Logic${colors.reset}\n`); // These are redundant since workflow.xml now handles context injection via context-logic.js
console.log(`${colors.yellow}Test Suite 2: No Stale Inline Monorepo Context Checks${colors.reset}\n`);
console.log(` ${colors.dim}(Inline checks were moved to workflow.xml via context-logic.js)${colors.reset}\n`);
const workflowFiles = glob.sync('src/{core,bmm}/workflows/**/*.{md,xml}', { cwd: projectRoot }); const workflowFiles = glob.sync('src/{core,bmm}/workflows/**/*.{md,xml}', { cwd: projectRoot });
// Workflows that MUST have the check
const requiredWorkflows = [
'brainstorming',
'party-mode',
'create-product-brief',
'create-prd',
'create-architecture',
'code-review',
'create-story',
'dev-story',
'set-project', // Should not have the check itself, but let's exclude it
];
for (const file of workflowFiles) { for (const file of workflowFiles) {
const basename = path.basename(path.dirname(file)); // skip the context-logic source itself (it's the canonical source)
if (basename === 'set-project' || basename === '0-context') continue; if (file.includes('context-logic')) continue;
const content = await fs.readFile(path.join(projectRoot, file), 'utf8'); const content = await fs.readFile(path.join(projectRoot, file), 'utf8');
const isXml = file.endsWith('.xml');
if (isXml) { assert(!content.includes('**Monorepo Context Check:**'), `No stale inline check block in: ${file}`);
assert(content.includes('_bmad/.current_project'), `XML workflow contains context check: ${file}`);
} else {
// Only check Markdown files that look like main workflow/instruction files
const filename = path.basename(file);
if (filename.includes('workflow') || filename.includes('instructions')) {
assert(content.includes('_bmad/.current_project'), `Markdown workflow contains context check: ${file}`);
}
}
} }
console.log(''); console.log('');
// 3. Verify set-project implementation // 3. Verify canonical source is context-logic.js (single source of truth)
console.log(`${colors.yellow}Test Suite 3: set-project Implementation${colors.reset}\n`); console.log(`${colors.yellow}Test Suite 3: Single Source of Truth${colors.reset}\n`);
const contextLogicPath = path.join(projectRoot, 'tools/cli/installers/lib/ide/shared/context-logic.js');
assert(await fs.pathExists(contextLogicPath), 'context-logic.js exists as canonical source');
const srcWorkflowXml = path.join(projectRoot, 'src/core/tasks/workflow.xml');
const xmlContent = await fs.readFile(srcWorkflowXml, 'utf8');
assert(xmlContent.includes('{{monorepo_context_logic}}'), 'workflow.xml uses {{monorepo_context_logic}} placeholder');
assert(!xmlContent.includes('**Monorepo Context Check:**'), 'workflow.xml has no stale inline check');
console.log('');
// 4. Verify set-project implementation
console.log(`${colors.yellow}Test Suite 4: set-project Implementation${colors.reset}\n`);
try { try {
const setProjectPath = path.join(projectRoot, 'src/bmm/workflows/0-context/set-project/workflow.md'); const setProjectPath = path.join(projectRoot, 'src/bmm/workflows/0-context/set-project/workflow.md');
const exists = await fs.pathExists(setProjectPath); const exists = await fs.pathExists(setProjectPath);
@ -102,6 +105,7 @@ async function runTests() {
if (exists) { if (exists) {
const content = await fs.readFile(setProjectPath, 'utf8'); const content = await fs.readFile(setProjectPath, 'utf8');
assert(content.includes('_bmad/.current_project'), 'set-project implementation manages .current_project'); assert(content.includes('_bmad/.current_project'), 'set-project implementation manages .current_project');
assert(content.includes('my-app'), 'set-project examples use generic public-friendly names');
} }
} catch (error) { } catch (error) {
assert(false, 'set-project check failed', error.message); assert(false, 'set-project check failed', error.message);

View File

@ -16,6 +16,7 @@ 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'); const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
const { MONOREPO_CONTEXT_LOGIC } = require('../ide/shared/context-logic');
class Installer { class Installer {
constructor() { constructor() {
@ -89,6 +90,10 @@ class Installer {
// Read the file content // Read the file content
let content = await fs.readFile(sourcePath, 'utf8'); let content = await fs.readFile(sourcePath, 'utf8');
// Apply replacements
content = content.replaceAll('{{monorepo_context_logic}}', MONOREPO_CONTEXT_LOGIC);
content = content.replaceAll('_bmad', this.bmadFolderName);
// Write to target with replaced content // Write to target with replaced content
await fs.ensureDir(path.dirname(targetPath)); await fs.ensureDir(path.dirname(targetPath));
await fs.writeFile(targetPath, content, 'utf8'); await fs.writeFile(targetPath, content, 'utf8');

View File

@ -391,12 +391,15 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
// No default // No default
} }
const { MONOREPO_CONTEXT_LOGIC } = require('./shared/context-logic');
let rendered = template let rendered = template
.replaceAll('{{name}}', artifact.name || '') .replaceAll('{{name}}', artifact.name || '')
.replaceAll('{{module}}', artifact.module || 'core') .replaceAll('{{module}}', artifact.module || 'core')
.replaceAll('{{path}}', pathToUse) .replaceAll('{{path}}', pathToUse)
.replaceAll('{{description}}', artifact.description || `${artifact.name} ${artifact.type || ''}`) .replaceAll('{{description}}', artifact.description || `${artifact.name} ${artifact.type || ''}`)
.replaceAll('{{workflow_path}}', pathToUse); .replaceAll('{{workflow_path}}', pathToUse)
.replaceAll('{{monorepo_context_logic}}', MONOREPO_CONTEXT_LOGIC);
// Replace _bmad placeholder with actual folder name // Replace _bmad placeholder with actual folder name
rendered = rendered.replaceAll('_bmad', this.bmadFolderName); rendered = rendered.replaceAll('_bmad', this.bmadFolderName);

View File

@ -0,0 +1,48 @@
/**
* Monorepo Context Logic XML Block
*
* robust, secure, and centralized logic for handling:
* 1. Inline project overrides (#p:NAME)
* 2. .current_project file fallback
* 3. Path variable overrides
*/
const MONOREPO_CONTEXT_LOGIC = `
<monorepo-context-check CRITICAL="TRUE" priority="before-config">
<!-- Step 1: Check for inline project override in user invocation -->
<!-- Supported syntax: #project:NAME (full) or #p:NAME (short alias) -->
<action>Scan user's invocation message for pattern #project:NAME or #p:NAME (case-insensitive)</action>
<check if="inline override found">
<action>Set project_suffix = extracted NAME</action>
<output>🎯 Inline project override: {project_suffix}</output>
</check>
<!-- Step 2: Fall back to .current_project file -->
<check if="project_suffix not yet set AND {project-root}/_bmad/.current_project exists">
<action>Read {project-root}/_bmad/.current_project as project_suffix</action>
</check>
<!-- Step 3: Validate -->
<check if="project_suffix is set">
<action>Trim whitespace and newlines from project_suffix</action>
<!-- Security: Prevent path traversal and invalid chars -->
<check if="project_suffix contains '..' OR starts with '/' OR starts with '\\'">
<output>🚫 Security Error: Invalid project context path traversal detected.</output>
<action>HALT</action>
</check>
<check if="project_suffix matching regex [^a-zA-Z0-9._-]">
<output>🚫 Error: project_suffix must only contain alphanumeric characters, dots, dashes, or underscores.</output>
<action>HALT</action>
</check>
<!-- Step 4: Override path variables -->
<action>Override output_folder = {project-root}/_bmad-output/{project_suffix}</action>
<action>Override planning_artifacts = {output_folder}/planning-artifacts</action>
<action>Override implementation_artifacts = {output_folder}/implementation-artifacts</action>
<action>Override project_knowledge = {output_folder}/knowledge</action>
<action>Override sprint_status_file = {output_folder}/sprint-status.yaml</action>
<output>🗂 Monorepo context: {project_suffix} outputs to {output_folder}</output>
</check>
</monorepo-context-check>
`;
module.exports = { MONOREPO_CONTEXT_LOGIC };

View File

@ -151,12 +151,15 @@ class WorkflowCommandGenerator {
} }
} }
const { MONOREPO_CONTEXT_LOGIC } = require('./context-logic');
// Replace template variables // Replace template variables
return template return template
.replaceAll('{{name}}', workflow.name) .replaceAll('{{name}}', workflow.name)
.replaceAll('{{module}}', workflow.module) .replaceAll('{{module}}', workflow.module)
.replaceAll('{{description}}', workflow.description) .replaceAll('{{description}}', workflow.description)
.replaceAll('{{workflow_path}}', workflowPath) .replaceAll('{{workflow_path}}', workflowPath)
.replaceAll('{{monorepo_context_logic}}', MONOREPO_CONTEXT_LOGIC)
.replaceAll('_bmad', this.bmadFolderName); .replaceAll('_bmad', this.bmadFolderName);
} }

View File

@ -3,6 +3,8 @@ name: '{{name}}'
description: '{{description}}' description: '{{description}}'
--- ---
{{monorepo_context_logic}}
Read the entire workflow file at: {project-root}/_bmad/{{workflow_path}} Read the entire workflow file at: {project-root}/_bmad/{{workflow_path}}
Follow all instructions in the workflow file exactly as written. Follow all instructions in the workflow file exactly as written.

View File

@ -7,6 +7,8 @@ disable-model-invocation: true
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded: IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
<steps CRITICAL="TRUE"> <steps CRITICAL="TRUE">
0. {{monorepo_context_logic}}
1. Always LOAD the FULL @{project-root}/{{bmadFolderName}}/core/tasks/workflow.xml 1. Always LOAD the FULL @{project-root}/{{bmadFolderName}}/core/tasks/workflow.xml
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{project-root}/{{bmadFolderName}}/{{path}} 2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{project-root}/{{bmadFolderName}}/{{path}}
3. Pass the yaml path @{project-root}/{{bmadFolderName}}/{{path}} as 'workflow-config' parameter to the workflow.xml instructions 3. Pass the yaml path @{project-root}/{{bmadFolderName}}/{{path}} as 'workflow-config' parameter to the workflow.xml instructions

View File

@ -4,4 +4,6 @@ description: '{{description}}'
disable-model-invocation: true disable-model-invocation: true
--- ---
{{monorepo_context_logic}}
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly! IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!

View File

@ -4,4 +4,6 @@ inclusion: manual
# {{name}} # {{name}}
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL #[[file:{{bmadFolderName}}/{{path}}]], READ its entire contents and follow its directions exactly! {{monorepo_context_logic}}
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!

View File

@ -8,6 +8,7 @@ Execute the BMAD '{{name}}' workflow.
CRITICAL: You must load and follow the workflow definition exactly. CRITICAL: You must load and follow the workflow definition exactly.
WORKFLOW INSTRUCTIONS: WORKFLOW INSTRUCTIONS:
{{monorepo_context_logic}}
1. LOAD the workflow file from {project-root}/{{bmadFolderName}}/{{path}} 1. LOAD the workflow file from {project-root}/{{bmadFolderName}}/{{path}}
2. READ its entire contents 2. READ its entire contents

View File

@ -5,6 +5,8 @@ auto_execution_mode: "iterate"
# {{name}} # {{name}}
{{monorepo_context_logic}}
Read the entire workflow file at {project-root}/_bmad/{{workflow_path}} Read the entire workflow file at {project-root}/_bmad/{{workflow_path}}
Follow all instructions in the workflow file exactly as written. Follow all instructions in the workflow file exactly as written.

View File

@ -3,6 +3,8 @@ description: '{{description}}'
disable-model-invocation: true disable-model-invocation: true
--- ---
{{monorepo_context_logic}}
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded: IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
<steps CRITICAL="TRUE"> <steps CRITICAL="TRUE">

View File

@ -3,4 +3,6 @@ description: '{{description}}'
disable-model-invocation: true disable-model-invocation: true
--- ---
{{monorepo_context_logic}}
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{{workflow_path}}, READ its entire contents and follow its directions exactly! IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{{workflow_path}}, READ its entire contents and follow its directions exactly!