Compare commits
5 Commits
2d134314c9
...
d4b4bdfa12
| Author | SHA1 | Date |
|---|---|---|
|
|
d4b4bdfa12 | |
|
|
d6cc8b060a | |
|
|
ccaa88bb2d | |
|
|
382ab8ed45 | |
|
|
1937552da3 |
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: bmad-os-diataxis-style-fix
|
||||
description: Fixes documentation to comply with Diataxis framework and BMad Method style guide rules
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Read `prompts/instructions.md` and execute.
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
# Diataxis Style Fixer
|
||||
|
||||
Automatically fixes documentation to comply with the Diataxis framework and BMad Method style guide.
|
||||
|
||||
## CRITICAL RULES
|
||||
|
||||
- **NEVER commit or push changes** — let the user review first
|
||||
- **NEVER make destructive edits** — preserve all content, only fix formatting
|
||||
- **Use Edit tool** — make targeted fixes, not full file rewrites
|
||||
- **Show summary** — after fixing, list all changes made
|
||||
|
||||
## Input
|
||||
|
||||
Documentation file path or directory to fix. Defaults to `docs/` if not specified.
|
||||
|
||||
## Step 1: Understand Diataxis Framework
|
||||
|
||||
**Diataxis** is a documentation framework that categorizes content into four types based on two axes:
|
||||
|
||||
| | **Learning** (oriented toward future) | **Doing** (oriented toward present) |
|
||||
| -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| **Practical** | **Tutorials** — lessons that guide learners through achieving a specific goal | **How-to guides** — step-by-step instructions for solving a specific problem |
|
||||
| **Conceptual** | **Explanation** — content that clarifies and describes underlying concepts | **Reference** — technical descriptions, organized for lookup |
|
||||
|
||||
**Key principles:**
|
||||
- Each document type serves a distinct user need
|
||||
- Don't mix types — a tutorial shouldn't explain concepts deeply
|
||||
- Focus on the user's goal, not exhaustive coverage
|
||||
- Structure follows purpose (tutorials are linear, reference is scannable)
|
||||
|
||||
## Step 2: Read the Style Guide
|
||||
|
||||
Read the project's style guide at `docs/_STYLE_GUIDE.md` to understand all project-specific conventions.
|
||||
|
||||
## Step 3: Detect Document Type
|
||||
|
||||
Based on file location, determine the document type:
|
||||
|
||||
| Location | Diataxis Type |
|
||||
| -------------------- | -------------------- |
|
||||
| `/docs/tutorials/` | Tutorial |
|
||||
| `/docs/how-to/` | How-to guide |
|
||||
| `/docs/explanation/` | Explanation |
|
||||
| `/docs/reference/` | Reference |
|
||||
| `/docs/glossary/` | Reference (glossary) |
|
||||
|
||||
## Step 4: Find and Fix Issues
|
||||
|
||||
For each markdown file, scan for issues and fix them:
|
||||
|
||||
### Universal Fixes (All Doc Types)
|
||||
|
||||
**Horizontal Rules (`---`)**
|
||||
- Remove any `---` outside of YAML frontmatter
|
||||
- Replace with `##` section headers or admonitions as appropriate
|
||||
|
||||
**`####` Headers**
|
||||
- Replace with bold text: `#### Header` → `**Header**`
|
||||
- Or convert to admonition if it's a warning/notice
|
||||
|
||||
**"Related" or "Next:" Sections**
|
||||
- Remove entire section including links
|
||||
- The sidebar handles navigation
|
||||
|
||||
**Deeply Nested Lists**
|
||||
- Break into sections with `##` headers
|
||||
- Flatten to max 3 levels
|
||||
|
||||
**Code Blocks for Dialogue/Examples**
|
||||
- Convert to admonitions:
|
||||
```
|
||||
:::note[Example]
|
||||
[content]
|
||||
:::
|
||||
```
|
||||
|
||||
**Bold Paragraph Callouts**
|
||||
- Convert to admonitions with appropriate type
|
||||
|
||||
**Too Many Admonitions**
|
||||
- Limit to 1-2 per section (tutorials allow 3-4 per major section)
|
||||
- Consolidate related admonitions
|
||||
- Remove less critical ones if over limit
|
||||
|
||||
**Table Cells / List Items > 2 Sentences**
|
||||
- Break into multiple rows/cells
|
||||
- Or shorten to 1-2 sentences
|
||||
|
||||
**Header Budget Exceeded**
|
||||
- Merge related sections
|
||||
- Convert some `##` to `###` subsections
|
||||
- Goal: 8-12 `##` per doc; 2-3 `###` per section
|
||||
|
||||
### Type-Specific Fixes
|
||||
|
||||
**Tutorials** (`/docs/tutorials/`)
|
||||
- Ensure hook describes outcome in 1-2 sentences
|
||||
- Add "What You'll Learn" bullet section if missing
|
||||
- Add `:::note[Prerequisites]` if missing
|
||||
- Add `:::tip[Quick Path]` TL;DR at top if missing
|
||||
- Use tables for phases, commands, agents
|
||||
- Add "What You've Accomplished" section if missing
|
||||
- Add Quick Reference table if missing
|
||||
- Add Common Questions section if missing
|
||||
- Add Getting Help section if missing
|
||||
- Add `:::tip[Key Takeaways]` at end if missing
|
||||
|
||||
**How-To** (`/docs/how-to/`)
|
||||
- Ensure hook starts with "Use the `X` workflow to..."
|
||||
- Add "When to Use This" with 3-5 bullets if missing
|
||||
- Add `:::note[Prerequisites]` if missing
|
||||
- Ensure steps are numbered `###` with action verbs
|
||||
- Add "What You Get" describing outputs if missing
|
||||
|
||||
**Explanation** (`/docs/explanation/`)
|
||||
- Ensure hook states what document explains
|
||||
- Organize content into scannable `##` sections
|
||||
- Add comparison tables for 3+ options
|
||||
- Link to how-to guides for procedural questions
|
||||
- Limit to 2-3 admonitions per document
|
||||
|
||||
**Reference** (`/docs/reference/`)
|
||||
- Ensure hook states what document references
|
||||
- Ensure structure matches reference type
|
||||
- Use consistent item structure throughout
|
||||
- Use tables for structured/comparative data
|
||||
- Link to explanation docs for conceptual depth
|
||||
- Limit to 1-2 admonitions per document
|
||||
|
||||
**Glossary** (`/docs/glossary/` or glossary files)
|
||||
- Ensure categories as `##` headers
|
||||
- Ensure terms in tables (not individual headers)
|
||||
- Definitions 1-2 sentences max
|
||||
- Bold term names in cells
|
||||
|
||||
## Step 5: Apply Fixes
|
||||
|
||||
For each file with issues:
|
||||
1. Read the file
|
||||
2. Use Edit tool for each fix
|
||||
3. Track what was changed
|
||||
|
||||
## Step 6: Summary
|
||||
|
||||
After processing all files, output a summary:
|
||||
|
||||
```markdown
|
||||
# Style Fixes Applied
|
||||
|
||||
**Files processed:** N
|
||||
**Files modified:** N
|
||||
|
||||
## Changes Made
|
||||
|
||||
### `path/to/file.md`
|
||||
- Removed horizontal rule at line 45
|
||||
- Converted `####` headers to bold text
|
||||
- Added `:::tip[Quick Path]` admonition
|
||||
- Consolidated 3 admonitions into 2
|
||||
|
||||
### `path/to/other.md`
|
||||
- Removed "Related:" section
|
||||
- Fixed table cell length (broke into 2 rows)
|
||||
|
||||
## Review Required
|
||||
|
||||
Please review the changes. When satisfied, commit and push as needed.
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
**Converting `####` to bold:**
|
||||
```markdown
|
||||
#### Important Note
|
||||
Some text here.
|
||||
```
|
||||
→
|
||||
```markdown
|
||||
**Important Note**
|
||||
|
||||
Some text here.
|
||||
```
|
||||
|
||||
**Removing horizontal rule:**
|
||||
```markdown
|
||||
Some content above.
|
||||
|
||||
---
|
||||
|
||||
Some content below.
|
||||
```
|
||||
→
|
||||
```markdown
|
||||
Some content above.
|
||||
|
||||
## [Descriptive Section Header]
|
||||
|
||||
Some content below.
|
||||
```
|
||||
|
||||
**Converting code block to admonition:**
|
||||
```markdown
|
||||
```
|
||||
User: What should I do?
|
||||
|
||||
Agent: Run the workflow.
|
||||
```
|
||||
```
|
||||
→
|
||||
```markdown
|
||||
:::note[Example]
|
||||
|
||||
**User:** What should I do?
|
||||
|
||||
**Agent:** Run the workflow.
|
||||
|
||||
:::
|
||||
```
|
||||
|
||||
**Converting bold paragraph to admonition:**
|
||||
```markdown
|
||||
**IMPORTANT:** This is critical that you read this before proceeding.
|
||||
```
|
||||
→
|
||||
```markdown
|
||||
:::caution[Important]
|
||||
This is critical that you read this before proceeding.
|
||||
:::
|
||||
```
|
||||
|
|
@ -77,7 +77,10 @@ Show in "What You've Accomplished" sections:
|
|||
your-project/
|
||||
├── _bmad/ # BMad configuration
|
||||
├── _bmad-output/
|
||||
│ ├── PRD.md # Your requirements document
|
||||
│ ├── planning-artifacts/
|
||||
│ │ └── PRD.md # Your requirements document
|
||||
│ ├── implementation-artifacts/
|
||||
│ └── project-context.md # Implementation rules (optional)
|
||||
└── ...
|
||||
```
|
||||
````
|
||||
|
|
|
|||
|
|
@ -0,0 +1,157 @@
|
|||
---
|
||||
title: "Project Context"
|
||||
description: How project-context.md guides AI agents with your project's rules and preferences
|
||||
sidebar:
|
||||
order: 7
|
||||
---
|
||||
|
||||
The `project-context.md` file is your project's implementation guide for AI agents. Similar to a "constitution" in other development systems, it captures the rules, patterns, and preferences that ensure consistent code generation across all workflows.
|
||||
|
||||
## What It Does
|
||||
|
||||
AI agents make implementation decisions constantly — which patterns to follow, how to structure code, what conventions to use. Without clear guidance, they may:
|
||||
- Follow generic best practices that don't match your codebase
|
||||
- Make inconsistent decisions across different stories
|
||||
- Miss project-specific requirements or constraints
|
||||
|
||||
The `project-context.md` file solves this by documenting what agents need to know in a concise, LLM-optimized format.
|
||||
|
||||
## How It Works
|
||||
|
||||
Every implementation workflow automatically loads `project-context.md` if it exists. The architect workflow also loads it to respect your technical preferences when designing the architecture.
|
||||
|
||||
**Loaded by these workflows:**
|
||||
- `create-architecture` — respects technical preferences during solutioning
|
||||
- `create-story` — informs story creation with project patterns
|
||||
- `dev-story` — guides implementation decisions
|
||||
- `code-review` — validates against project standards
|
||||
- `quick-dev` — applies patterns when implementing tech-specs
|
||||
- `sprint-planning`, `retrospective`, `correct-course` — provides project-wide context
|
||||
|
||||
## When to Create It
|
||||
|
||||
The `project-context.md` file is useful at any stage of a project:
|
||||
|
||||
| Scenario | When to Create | Purpose |
|
||||
|----------|----------------|---------|
|
||||
| **New project, before architecture** | Manually, before `create-architecture` | Document your technical preferences so the architect respects them |
|
||||
| **New project, after architecture** | Via `generate-project-context` or manually | Capture architecture decisions for implementation agents |
|
||||
| **Existing project** | Via `generate-project-context` | Discover existing patterns so agents follow established conventions |
|
||||
| **Quick Flow project** | Before or during `quick-dev` | Ensure quick implementation respects your patterns |
|
||||
|
||||
:::tip[Recommended]
|
||||
For new projects, create it manually before architecture if you have strong technical preferences. Otherwise, generate it after architecture to capture those decisions.
|
||||
:::
|
||||
|
||||
## What Goes In It
|
||||
|
||||
The file has two main sections:
|
||||
|
||||
### Technology Stack & Versions
|
||||
|
||||
Documents the frameworks, languages, and tools your project uses with specific versions:
|
||||
|
||||
```markdown
|
||||
## Technology Stack & Versions
|
||||
|
||||
- Node.js 20.x, TypeScript 5.3, React 18.2
|
||||
- State: Zustand (not Redux)
|
||||
- Testing: Vitest, Playwright, MSW
|
||||
- Styling: Tailwind CSS with custom design tokens
|
||||
```
|
||||
|
||||
### Critical Implementation Rules
|
||||
|
||||
Documents patterns and conventions that agents might otherwise miss:
|
||||
|
||||
```markdown
|
||||
## Critical Implementation Rules
|
||||
|
||||
**TypeScript Configuration:**
|
||||
- Strict mode enabled — no `any` types without explicit approval
|
||||
- Use `interface` for public APIs, `type` for unions/intersections
|
||||
|
||||
**Code Organization:**
|
||||
- Components in `/src/components/` with co-located `.test.tsx`
|
||||
- Utilities in `/src/lib/` for reusable pure functions
|
||||
- API calls use the `apiClient` singleton — never fetch directly
|
||||
|
||||
**Testing Patterns:**
|
||||
- Unit tests focus on business logic, not implementation details
|
||||
- Integration tests use MSW to mock API responses
|
||||
- E2E tests cover critical user journeys only
|
||||
|
||||
**Framework-Specific:**
|
||||
- All async operations use the `handleError` wrapper for consistent error handling
|
||||
- Feature flags accessed via `featureFlag()` from `@/lib/flags`
|
||||
- New routes follow the file-based routing pattern in `/src/app/`
|
||||
```
|
||||
|
||||
Focus on what's **unobvious** — things agents might not infer from reading code snippets. Don't document standard practices that apply universally.
|
||||
|
||||
## Creating the File
|
||||
|
||||
You have three options:
|
||||
|
||||
### Manual Creation
|
||||
|
||||
Create the file at `_bmad-output/project-context.md` and add your rules:
|
||||
|
||||
```bash
|
||||
# In your project root
|
||||
mkdir -p _bmad-output
|
||||
touch _bmad-output/project-context.md
|
||||
```
|
||||
|
||||
Edit it with your technology stack and implementation rules. The architect and implementation workflows will automatically find and load it.
|
||||
|
||||
### Generate After Architecture
|
||||
|
||||
Run the `generate-project-context` workflow after completing your architecture:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
```
|
||||
|
||||
This scans your architecture document and project files to generate a context file capturing the decisions made.
|
||||
|
||||
### Generate for Existing Projects
|
||||
|
||||
For existing projects, run `generate-project-context` to discover existing patterns:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
```
|
||||
|
||||
The workflow analyzes your codebase to identify conventions, then generates a context file you can review and refine.
|
||||
|
||||
## Why It Matters
|
||||
|
||||
Without `project-context.md`, agents make assumptions that may not match your project:
|
||||
|
||||
| Without Context | With Context |
|
||||
|----------------|--------------|
|
||||
| Uses generic patterns | Follows your established conventions |
|
||||
| Inconsistent style across stories | Consistent implementation |
|
||||
| May miss project-specific constraints | Respects all technical requirements |
|
||||
| Each agent decides independently | All agents align with same rules |
|
||||
|
||||
This is especially important for:
|
||||
- **Quick Flow** — skips PRD and architecture, so context file fills the gap
|
||||
- **Team projects** — ensures all agents follow the same standards
|
||||
- **Existing projects** — prevents breaking established patterns
|
||||
|
||||
## Editing and Updating
|
||||
|
||||
The `project-context.md` file is a living document. Update it when:
|
||||
|
||||
- Architecture decisions change
|
||||
- New conventions are established
|
||||
- Patterns evolve during implementation
|
||||
- You identify gaps from agent behavior
|
||||
|
||||
You can edit it manually at any time, or re-run `generate-project-context` to update it after significant changes.
|
||||
|
||||
:::note[File Location]
|
||||
The default location is `_bmad-output/project-context.md`. Workflows search for it there, and also check `**/project-context.md` anywhere in your project.
|
||||
:::
|
||||
|
|
@ -5,7 +5,7 @@ sidebar:
|
|||
order: 6
|
||||
---
|
||||
|
||||
Use BMad Method effectively when working on existing projects and legacy codebases, sometimes also referred to as brownfield projects.
|
||||
Use BMad Method effectively when working on existing projects and legacy codebases.
|
||||
|
||||
This guide covers the essential workflow for onboarding to existing projects with BMad Method.
|
||||
|
||||
|
|
@ -23,7 +23,30 @@ If you have completed all PRD epics and stories through the BMad process, clean
|
|||
- `_bmad-output/planning-artifacts/`
|
||||
- `_bmad-output/implementation-artifacts/`
|
||||
|
||||
## Step 2: Maintain Quality Project Documentation
|
||||
## Step 2: Create Project Context
|
||||
|
||||
:::tip[Recommended for Existing Projects]
|
||||
Generate `project-context.md` to capture your existing codebase patterns and conventions. This ensures AI agents follow your established practices when implementing changes.
|
||||
:::
|
||||
|
||||
Run the generate project context workflow:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
```
|
||||
|
||||
This scans your codebase to identify:
|
||||
- Technology stack and versions
|
||||
- Code organization patterns
|
||||
- Naming conventions
|
||||
- Testing approaches
|
||||
- Framework-specific patterns
|
||||
|
||||
You can review and refine the generated file, or create it manually at `_bmad-output/project-context.md` if you prefer.
|
||||
|
||||
[Learn more about project context](../explanation/project-context.md)
|
||||
|
||||
## Step 3: Maintain Quality Project Documentation
|
||||
|
||||
Your `docs/` folder should contain succinct, well-organized documentation that accurately represents your project:
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
title: "Manage Project Context"
|
||||
description: Create and maintain project-context.md to guide AI agents
|
||||
sidebar:
|
||||
order: 7
|
||||
---
|
||||
|
||||
Use the `project-context.md` file to ensure AI agents follow your project's technical preferences and implementation rules throughout all workflows.
|
||||
|
||||
:::note[Prerequisites]
|
||||
- BMad Method installed
|
||||
- Understanding of your project's technology stack and conventions
|
||||
:::
|
||||
|
||||
## When to Use This
|
||||
|
||||
- You have strong technical preferences before starting architecture
|
||||
- You've completed architecture and want to capture decisions for implementation
|
||||
- You're working on an existing codebase with established patterns
|
||||
- You notice agents making inconsistent decisions across stories
|
||||
|
||||
## Step 1: Choose Your Approach
|
||||
|
||||
**Manual creation** — Best when you know exactly what rules you want to document
|
||||
|
||||
**Generate after architecture** — Best for capturing decisions made during solutioning
|
||||
|
||||
**Generate for existing projects** — Best for discovering patterns in existing codebases
|
||||
|
||||
## Step 2: Create the File
|
||||
|
||||
### Option A: Manual Creation
|
||||
|
||||
Create the file at `_bmad-output/project-context.md`:
|
||||
|
||||
```bash
|
||||
mkdir -p _bmad-output
|
||||
touch _bmad-output/project-context.md
|
||||
```
|
||||
|
||||
Add your technology stack and implementation rules:
|
||||
|
||||
```markdown
|
||||
---
|
||||
project_name: 'MyProject'
|
||||
user_name: 'YourName'
|
||||
date: '2026-02-15'
|
||||
sections_completed: ['technology_stack', 'critical_rules']
|
||||
---
|
||||
|
||||
# Project Context for AI Agents
|
||||
|
||||
## Technology Stack & Versions
|
||||
|
||||
- Node.js 20.x, TypeScript 5.3, React 18.2
|
||||
- State: Zustand
|
||||
- Testing: Vitest, Playwright
|
||||
- Styling: Tailwind CSS
|
||||
|
||||
## Critical Implementation Rules
|
||||
|
||||
**TypeScript:**
|
||||
- Strict mode enabled, no `any` types
|
||||
- Use `interface` for public APIs, `type` for unions
|
||||
|
||||
**Code Organization:**
|
||||
- Components in `/src/components/` with co-located tests
|
||||
- API calls use `apiClient` singleton — never fetch directly
|
||||
|
||||
**Testing:**
|
||||
- Unit tests focus on business logic
|
||||
- Integration tests use MSW for API mocking
|
||||
```
|
||||
|
||||
### Option B: Generate After Architecture
|
||||
|
||||
Run the workflow in a fresh chat:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
```
|
||||
|
||||
The workflow scans your architecture document and project files to generate a context file capturing the decisions made.
|
||||
|
||||
### Option C: Generate for Existing Projects
|
||||
|
||||
For existing projects, run:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
```
|
||||
|
||||
The workflow analyzes your codebase to identify conventions, then generates a context file you can review and refine.
|
||||
|
||||
## Step 3: Verify Content
|
||||
|
||||
Review the generated file and ensure it captures:
|
||||
|
||||
- Correct technology versions
|
||||
- Your actual conventions (not generic best practices)
|
||||
- Rules that prevent common mistakes
|
||||
- Framework-specific patterns
|
||||
|
||||
Edit manually to add anything missing or remove inaccuracies.
|
||||
|
||||
## What You Get
|
||||
|
||||
A `project-context.md` file that:
|
||||
|
||||
- Ensures all agents follow the same conventions
|
||||
- Prevents inconsistent decisions across stories
|
||||
- Captures architecture decisions for implementation
|
||||
- Serves as a reference for your project's patterns and rules
|
||||
|
||||
## Tips
|
||||
|
||||
:::tip[Focus on the Unobvious]
|
||||
Document patterns agents might miss such as "Use JSDoc style comments on every public class, function and variable", not universal practices like "use meaningful variable names" which LLMs know at this point.
|
||||
:::
|
||||
|
||||
:::tip[Keep It Lean]
|
||||
This file is loaded by every implementation workflow. Long files waste context. Do not include content that only applies to narrow scope or specific stories or features.
|
||||
:::
|
||||
|
||||
:::tip[Update as Needed]
|
||||
Edit manually when patterns change, or re-generate after significant architecture changes.
|
||||
:::
|
||||
|
||||
:::tip[Works for All Project Types]
|
||||
Just as useful for Quick Flow as for full BMad Method projects.
|
||||
:::
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [**Project Context Explanation**](../explanation/project-context.md) — Learn more about how it works
|
||||
- [**Workflow Map**](../reference/workflow-map.md) — See which workflows load project context
|
||||
|
|
@ -23,11 +23,11 @@ Document sharding splits large markdown files into smaller, organized files base
|
|||
|
||||
```text
|
||||
Before Sharding:
|
||||
docs/
|
||||
_bmad-output/planning-artifacts/
|
||||
└── PRD.md (large 50k token file)
|
||||
|
||||
After Sharding:
|
||||
docs/
|
||||
_bmad-output/planning-artifacts/
|
||||
└── prd/
|
||||
├── index.md # Table of contents with descriptions
|
||||
├── overview.md # Section 1
|
||||
|
|
|
|||
|
|
@ -77,12 +77,44 @@ Skip phases 1-3 for small, well-understood work.
|
|||
|
||||
Each document becomes context for the next phase. The PRD tells the architect what constraints matter. The architecture tells the dev agent which patterns to follow. Story files give focused, complete context for implementation. Without this structure, agents make inconsistent decisions.
|
||||
|
||||
For established projects, `document-project` creates or updates `project-context.md` - what exists in the codebase and the rules all implementation workflows must observe. Run it just before Phase 4, and again when something significant changes - structure, architecture, or those rules. You can also edit `project-context.md` by hand.
|
||||
### Project Context
|
||||
|
||||
All implementation workflows load `project-context.md` if it exists. Additional context per workflow:
|
||||
:::tip[Recommended]
|
||||
Create `project-context.md` to ensure AI agents follow your project's rules and preferences. This file works like a constitution for your project — it guides implementation decisions across all workflows.
|
||||
:::
|
||||
|
||||
**When to create it:**
|
||||
|
||||
| Scenario | Approach |
|
||||
|----------|----------|
|
||||
| Before architecture (manual) | Document technical preferences you want the architect to respect |
|
||||
| After architecture | Generate it to capture decisions made during solutioning |
|
||||
| Existing projects | Run `generate-project-context` to discover established patterns |
|
||||
| Quick Flow | Create before `quick-dev` to ensure consistent implementation |
|
||||
|
||||
**How to create it:**
|
||||
|
||||
- **Manually** — Create `_bmad-output/project-context.md` with your technology stack and implementation rules
|
||||
- **Generate it** — Run `/bmad-bmm-generate-project-context` to auto-generate from your architecture or codebase
|
||||
|
||||
**What workflows load it:**
|
||||
|
||||
| Workflow | Purpose |
|
||||
|----------|---------|
|
||||
| `create-architecture` | Respects technical preferences when designing |
|
||||
| `create-story` | Informs story creation with project patterns |
|
||||
| `dev-story` | Guides implementation decisions |
|
||||
| `code-review` | Validates against project standards |
|
||||
| `quick-dev` | Applies patterns when implementing |
|
||||
|
||||
[**Learn more about project-context.md**](../explanation/project-context.md)
|
||||
|
||||
### Additional Context by Workflow
|
||||
|
||||
Beyond `project-context.md`, each workflow loads specific documents:
|
||||
|
||||
| Workflow | Also Loads |
|
||||
| -------------- | ---------------------------- |
|
||||
|----------|------------|
|
||||
| `create-story` | epics, PRD, architecture, UX |
|
||||
| `dev-story` | story file |
|
||||
| `code-review` | architecture, story file |
|
||||
|
|
|
|||
|
|
@ -79,6 +79,12 @@ Always start a fresh chat for each workflow. This prevents context limitations f
|
|||
|
||||
Work through phases 1-3. **Use fresh chats for each workflow.**
|
||||
|
||||
:::tip[Project Context (Optional)]
|
||||
Before starting, consider creating `project-context.md` to document your technical preferences and implementation rules. This ensures all AI agents follow your conventions throughout the project.
|
||||
|
||||
Create it manually at `_bmad-output/project-context.md` or generate it after architecture using `/bmad-bmm-generate-project-context`. [Learn more](../explanation/project-context.md).
|
||||
:::
|
||||
|
||||
### Phase 1: Analysis (Optional)
|
||||
|
||||
All workflows in this phase are optional:
|
||||
|
|
@ -157,10 +163,13 @@ Your project now has:
|
|||
your-project/
|
||||
├── _bmad/ # BMad configuration
|
||||
├── _bmad-output/
|
||||
│ ├── PRD.md # Your requirements document
|
||||
│ ├── architecture.md # Technical decisions
|
||||
│ ├── epics/ # Epic and story files
|
||||
│ └── sprint-status.yaml # Sprint tracking
|
||||
│ ├── planning-artifacts/
|
||||
│ │ ├── PRD.md # Your requirements document
|
||||
│ │ ├── architecture.md # Technical decisions
|
||||
│ │ └── epics/ # Epic and story files
|
||||
│ ├── implementation-artifacts/
|
||||
│ │ └── sprint-status.yaml # Sprint tracking
|
||||
│ └── project-context.md # Implementation rules (optional)
|
||||
└── ...
|
||||
```
|
||||
|
||||
|
|
@ -171,6 +180,7 @@ your-project/
|
|||
| `help` | `/bmad-help` | Any | Get guidance on what to do next |
|
||||
| `prd` | `/bmad-bmm-create-prd` | PM | Create Product Requirements Document |
|
||||
| `create-architecture` | `/bmad-bmm-create-architecture` | Architect | Create architecture document |
|
||||
| `generate-project-context` | `/bmad-bmm-generate-project-context` | Analyst | Create project context file |
|
||||
| `create-epics-and-stories` | `/bmad-bmm-create-epics-and-stories` | PM | Break down PRD into epics |
|
||||
| `check-implementation-readiness` | `/bmad-bmm-check-implementation-readiness` | Architect | Validate planning cohesion |
|
||||
| `sprint-planning` | `/bmad-bmm-sprint-planning` | SM | Initialize sprint tracking |
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ class ConfigCollector {
|
|||
|
||||
const configSpinner = await prompts.spinner();
|
||||
configSpinner.start('Configuring modules...');
|
||||
try {
|
||||
for (const moduleName of defaultModules) {
|
||||
const displayName = displayNameMap.get(moduleName) || moduleName.toUpperCase();
|
||||
configSpinner.message(`Configuring ${displayName}...`);
|
||||
|
|
@ -312,13 +313,19 @@ class ConfigCollector {
|
|||
this._silentConfig = false;
|
||||
}
|
||||
}
|
||||
configSpinner.stop('Module configuration complete');
|
||||
} finally {
|
||||
configSpinner.stop(customizeModules.length > 0 ? 'Module defaults applied' : 'Module configuration complete');
|
||||
}
|
||||
}
|
||||
|
||||
// Run customized modules individually (may show interactive prompts)
|
||||
for (const moduleName of customizeModules) {
|
||||
await this.collectModuleConfig(moduleName, projectDir);
|
||||
}
|
||||
|
||||
if (customizeModules.length > 0) {
|
||||
await prompts.log.step('Module configuration complete');
|
||||
}
|
||||
}
|
||||
|
||||
// Add metadata
|
||||
|
|
@ -1239,7 +1246,6 @@ class ConfigCollector {
|
|||
hasOutput = true;
|
||||
|
||||
const message = valueMessages[selectedValue];
|
||||
await prompts.log.message('');
|
||||
for (const line of message.trim().split('\n')) {
|
||||
const trimmedLine = line.trim();
|
||||
if (trimmedLine.endsWith(':') && !trimmedLine.startsWith(' ')) {
|
||||
|
|
|
|||
|
|
@ -527,8 +527,13 @@ class Installer {
|
|||
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
||||
|
||||
for (const cachedModule of cachedModules) {
|
||||
if (cachedModule.isDirectory()) {
|
||||
const moduleId = cachedModule.name;
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Skip if path doesn't exist (broken symlink, deleted dir) - avoids lstat ENOENT
|
||||
if (!(await fs.pathExists(cachedPath)) || !cachedModule.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if we already have this module from manifest
|
||||
if (customModulePaths.has(moduleId)) {
|
||||
|
|
@ -542,15 +547,12 @@ class Installer {
|
|||
continue;
|
||||
}
|
||||
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Check if this is actually a custom module (has module.yaml)
|
||||
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
||||
if (await fs.pathExists(moduleYamlPath)) {
|
||||
customModulePaths.set(moduleId, cachedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update module manager with the new custom module paths from cache
|
||||
this.moduleManager.setCustomModulePaths(customModulePaths);
|
||||
|
|
@ -609,8 +611,13 @@ class Installer {
|
|||
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
||||
|
||||
for (const cachedModule of cachedModules) {
|
||||
if (cachedModule.isDirectory()) {
|
||||
const moduleId = cachedModule.name;
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Skip if path doesn't exist (broken symlink, deleted dir) - avoids lstat ENOENT
|
||||
if (!(await fs.pathExists(cachedPath)) || !cachedModule.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if we already have this module from manifest
|
||||
if (customModulePaths.has(moduleId)) {
|
||||
|
|
@ -624,15 +631,12 @@ class Installer {
|
|||
continue;
|
||||
}
|
||||
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Check if this is actually a custom module (has module.yaml)
|
||||
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
||||
if (await fs.pathExists(moduleYamlPath)) {
|
||||
customModulePaths.set(moduleId, cachedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update module manager with the new custom module paths from cache
|
||||
this.moduleManager.setCustomModulePaths(customModulePaths);
|
||||
|
|
@ -949,12 +953,11 @@ class Installer {
|
|||
if (!isCustomModule && config._customModuleSources && config._customModuleSources.has(moduleName)) {
|
||||
customInfo = config._customModuleSources.get(moduleName);
|
||||
isCustomModule = true;
|
||||
if (
|
||||
customInfo.sourcePath &&
|
||||
(customInfo.sourcePath.startsWith('_config') || customInfo.sourcePath.includes('_config/custom')) &&
|
||||
!customInfo.path
|
||||
)
|
||||
customInfo.path = customInfo.sourcePath;
|
||||
if (customInfo.sourcePath && !customInfo.path) {
|
||||
customInfo.path = path.isAbsolute(customInfo.sourcePath)
|
||||
? customInfo.sourcePath
|
||||
: path.join(bmadDir, customInfo.sourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally check regular custom content
|
||||
|
|
@ -2373,15 +2376,35 @@ class Installer {
|
|||
const configuredIdes = existingInstall.ides || [];
|
||||
const projectRoot = path.dirname(bmadDir);
|
||||
|
||||
// Get custom module sources from cache
|
||||
// Get custom module sources: first from --custom-content (re-cache from source), then from cache
|
||||
const customModuleSources = new Map();
|
||||
if (config.customContent?.sources?.length > 0) {
|
||||
for (const source of config.customContent.sources) {
|
||||
if (source.id && source.path && (await fs.pathExists(source.path))) {
|
||||
customModuleSources.set(source.id, {
|
||||
id: source.id,
|
||||
name: source.name || source.id,
|
||||
sourcePath: source.path,
|
||||
cached: false, // From CLI, will be re-cached
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const cacheDir = path.join(bmadDir, '_config', 'custom');
|
||||
if (await fs.pathExists(cacheDir)) {
|
||||
const cachedModules = await fs.readdir(cacheDir, { withFileTypes: true });
|
||||
|
||||
for (const cachedModule of cachedModules) {
|
||||
if (cachedModule.isDirectory()) {
|
||||
const moduleId = cachedModule.name;
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Skip if path doesn't exist (broken symlink, deleted dir) - avoids lstat ENOENT
|
||||
if (!(await fs.pathExists(cachedPath))) {
|
||||
continue;
|
||||
}
|
||||
if (!cachedModule.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if we already have this module from manifest
|
||||
if (customModuleSources.has(moduleId)) {
|
||||
|
|
@ -2395,8 +2418,6 @@ class Installer {
|
|||
continue;
|
||||
}
|
||||
|
||||
const cachedPath = path.join(cacheDir, moduleId);
|
||||
|
||||
// Check if this is actually a custom module (has module.yaml)
|
||||
const moduleYamlPath = path.join(cachedPath, 'module.yaml');
|
||||
if (await fs.pathExists(moduleYamlPath)) {
|
||||
|
|
@ -2410,7 +2431,6 @@ class Installer {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load saved IDE configurations
|
||||
const savedIdeConfigs = await this.ideConfigManager.loadAllIdeConfigs(bmadDir);
|
||||
|
|
@ -2544,6 +2564,7 @@ class Installer {
|
|||
_savedIdeConfigs: savedIdeConfigs, // Pass saved IDE configs to installer
|
||||
_customModuleSources: customModuleSources, // Pass custom module sources for updates
|
||||
_existingModules: installedModules, // Pass all installed modules for manifest generation
|
||||
customContent: config.customContent, // Pass through for re-caching from source
|
||||
};
|
||||
|
||||
// Call the standard install method
|
||||
|
|
|
|||
|
|
@ -734,8 +734,10 @@ class ModuleManager {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Skip config.yaml templates - we'll generate clean ones with actual values
|
||||
if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
|
||||
// Skip module root config.yaml only - generated by config collector with actual values
|
||||
// Workflow-level config.yaml (e.g. workflows/orchestrate-story/config.yaml) must be copied
|
||||
// for custom modules that use workflow-specific configuration
|
||||
if (file === 'config.yaml') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,11 +245,48 @@ class UI {
|
|||
|
||||
// Handle quick update separately
|
||||
if (actionType === 'quick-update') {
|
||||
// Quick update doesn't install custom content - just updates existing modules
|
||||
// Pass --custom-content through so installer can re-cache if cache is missing
|
||||
let customContentForQuickUpdate = { hasCustomContent: false };
|
||||
if (options.customContent) {
|
||||
const paths = options.customContent
|
||||
.split(',')
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
if (paths.length > 0) {
|
||||
const customPaths = [];
|
||||
const selectedModuleIds = [];
|
||||
const sources = [];
|
||||
for (const customPath of paths) {
|
||||
const expandedPath = this.expandUserPath(customPath);
|
||||
const validation = this.validateCustomContentPathSync(expandedPath);
|
||||
if (validation) continue;
|
||||
let moduleMeta;
|
||||
try {
|
||||
const moduleYamlPath = path.join(expandedPath, 'module.yaml');
|
||||
moduleMeta = require('yaml').parse(await fs.readFile(moduleYamlPath, 'utf-8'));
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
if (!moduleMeta?.code) continue;
|
||||
customPaths.push(expandedPath);
|
||||
selectedModuleIds.push(moduleMeta.code);
|
||||
sources.push({ path: expandedPath, id: moduleMeta.code, name: moduleMeta.name || moduleMeta.code });
|
||||
}
|
||||
if (customPaths.length > 0) {
|
||||
customContentForQuickUpdate = {
|
||||
hasCustomContent: true,
|
||||
selected: true,
|
||||
sources,
|
||||
selectedFiles: customPaths.map((p) => path.join(p, 'module.yaml')),
|
||||
selectedModuleIds,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
actionType: 'quick-update',
|
||||
directory: confirmedDirectory,
|
||||
customContent: { hasCustomContent: false },
|
||||
customContent: customContentForQuickUpdate,
|
||||
skipPrompts: options.yes || false,
|
||||
};
|
||||
}
|
||||
|
|
@ -305,6 +342,7 @@ class UI {
|
|||
// Build custom content config similar to promptCustomContentSource
|
||||
const customPaths = [];
|
||||
const selectedModuleIds = [];
|
||||
const sources = [];
|
||||
|
||||
for (const customPath of paths) {
|
||||
const expandedPath = this.expandUserPath(customPath);
|
||||
|
|
@ -326,6 +364,11 @@ class UI {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!moduleMeta) {
|
||||
await prompts.log.warn(`Skipping custom content path: ${customPath} - module.yaml is empty`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!moduleMeta.code) {
|
||||
await prompts.log.warn(`Skipping custom content path: ${customPath} - module.yaml missing 'code' field`);
|
||||
continue;
|
||||
|
|
@ -333,6 +376,11 @@ class UI {
|
|||
|
||||
customPaths.push(expandedPath);
|
||||
selectedModuleIds.push(moduleMeta.code);
|
||||
sources.push({
|
||||
path: expandedPath,
|
||||
id: moduleMeta.code,
|
||||
name: moduleMeta.name || moduleMeta.code,
|
||||
});
|
||||
}
|
||||
|
||||
if (customPaths.length > 0) {
|
||||
|
|
@ -340,7 +388,9 @@ class UI {
|
|||
selectedCustomModules: selectedModuleIds,
|
||||
customContentConfig: {
|
||||
hasCustomContent: true,
|
||||
paths: customPaths,
|
||||
selected: true,
|
||||
sources,
|
||||
selectedFiles: customPaths.map((p) => path.join(p, 'module.yaml')),
|
||||
selectedModuleIds: selectedModuleIds,
|
||||
},
|
||||
};
|
||||
|
|
@ -446,6 +496,7 @@ class UI {
|
|||
// Build custom content config similar to promptCustomContentSource
|
||||
const customPaths = [];
|
||||
const selectedModuleIds = [];
|
||||
const sources = [];
|
||||
|
||||
for (const customPath of paths) {
|
||||
const expandedPath = this.expandUserPath(customPath);
|
||||
|
|
@ -467,6 +518,11 @@ class UI {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!moduleMeta) {
|
||||
await prompts.log.warn(`Skipping custom content path: ${customPath} - module.yaml is empty`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!moduleMeta.code) {
|
||||
await prompts.log.warn(`Skipping custom content path: ${customPath} - module.yaml missing 'code' field`);
|
||||
continue;
|
||||
|
|
@ -474,12 +530,19 @@ class UI {
|
|||
|
||||
customPaths.push(expandedPath);
|
||||
selectedModuleIds.push(moduleMeta.code);
|
||||
sources.push({
|
||||
path: expandedPath,
|
||||
id: moduleMeta.code,
|
||||
name: moduleMeta.name || moduleMeta.code,
|
||||
});
|
||||
}
|
||||
|
||||
if (customPaths.length > 0) {
|
||||
customContentConfig = {
|
||||
hasCustomContent: true,
|
||||
paths: customPaths,
|
||||
selected: true,
|
||||
sources,
|
||||
selectedFiles: customPaths.map((p) => path.join(p, 'module.yaml')),
|
||||
selectedModuleIds: selectedModuleIds,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue