Compare commits
33 Commits
6.0.0-Beta
...
main
| Author | SHA1 | Date |
|---|---|---|
|
|
df176d4206 | |
|
|
2d9ebcaf2f | |
|
|
5b80649d3a | |
|
|
594235522c | |
|
|
7ecae1d000 | |
|
|
ba890779a2 | |
|
|
323cd75efd | |
|
|
b0c35d595f | |
|
|
0c46ef0be2 | |
|
|
79067a9427 | |
|
|
fa01b4929b | |
|
|
0bbb544521 | |
|
|
c3d1bf3fe8 | |
|
|
04e3dc8f75 | |
|
|
ef7abb7ca5 | |
|
|
981e5a49c2 | |
|
|
e17c7e8793 | |
|
|
1665ad68df | |
|
|
6af79165d8 | |
|
|
bdcd8afa42 | |
|
|
d45eff15bf | |
|
|
0a7329ff23 | |
|
|
7afe018f82 | |
|
|
8c59fb96a7 | |
|
|
7fcfd4c1b8 | |
|
|
53220420a5 | |
|
|
9c0314732e | |
|
|
542a7429ec | |
|
|
9df5720ab3 | |
|
|
1c13305f9f | |
|
|
6198add5bd | |
|
|
5fe54de24e | |
|
|
903710be1b |
Binary file not shown.
|
|
@ -0,0 +1,169 @@
|
|||
---
|
||||
name: changelog-social
|
||||
description: Generate social media announcements for Discord, Twitter, and LinkedIn from the latest changelog entry. Use when user asks to create release announcements, social posts, or share changelog updates. Reads CHANGELOG.md in current working directory. Reference examples/ for tone and format.
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Changelog Social
|
||||
|
||||
Generate engaging social media announcements from changelog entries.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Extract Changelog Entry
|
||||
|
||||
Read `./CHANGELOG.md` and extract the latest version entry. The changelog follows this format:
|
||||
|
||||
```markdown
|
||||
## [VERSION]
|
||||
|
||||
### 🎁 Features
|
||||
* **Title** — Description
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
* **Title** — Description
|
||||
|
||||
### 📚 Documentation
|
||||
* **Title** — Description
|
||||
|
||||
### 🔧 Maintenance
|
||||
* **Title** — Description
|
||||
```
|
||||
|
||||
Parse:
|
||||
- **Version number** (e.g., `6.0.0-Beta.5`)
|
||||
- **Features** - New functionality, enhancements
|
||||
- **Bug Fixes** - Fixes users will care about
|
||||
- **Documentation** - New or improved docs
|
||||
- **Maintenance** - Dependency updates, tooling improvements
|
||||
|
||||
### Step 2: Get Git Contributors
|
||||
|
||||
Use git log to find contributors since the previous version. Get commits between the current version tag and the previous one:
|
||||
|
||||
```bash
|
||||
# Find the previous version tag first
|
||||
git tag --sort=-version:refname | head -5
|
||||
|
||||
# Get commits between versions with PR numbers and authors
|
||||
git log <previous-tag>..<current-tag> --pretty=format:"%h|%s|%an" --grep="#"
|
||||
```
|
||||
|
||||
Extract PR numbers from commit messages that contain `#` followed by digits. Compile unique contributors.
|
||||
|
||||
### Step 3: Generate Discord Announcement
|
||||
|
||||
**Limit: 2,000 characters per message.** Split into multiple messages if needed.
|
||||
|
||||
Use this template style:
|
||||
|
||||
```markdown
|
||||
🚀 **BMad vVERSION RELEASED!**
|
||||
|
||||
🎉 [Brief hype sentence]
|
||||
|
||||
🪥 **KEY HIGHLIGHT** - [One-line summary]
|
||||
|
||||
🎯 **CATEGORY NAME**
|
||||
• Feature one - brief description
|
||||
• Feature two - brief description
|
||||
• Coming soon: Future teaser
|
||||
|
||||
🔧 **ANOTHER CATEGORY**
|
||||
• Fix or feature
|
||||
• Another item
|
||||
|
||||
📚 **DOCS OR OTHER**
|
||||
• Item
|
||||
• Item with link
|
||||
|
||||
🌟 **COMMUNITY PHILOSOPHY** (optional - include for major releases)
|
||||
• Everything is FREE - No paywalls
|
||||
• Knowledge shared, not sold
|
||||
|
||||
📊 **STATS**
|
||||
X commits | Y PRs merged | Z files changed
|
||||
|
||||
🙏 **CONTRIBUTORS**
|
||||
@username1 (X PRs!), @username2 (Y PRs!)
|
||||
@username3, @username4, username5 + dependabot 🛡️
|
||||
Community-driven FTW! 🌟
|
||||
|
||||
📦 **INSTALL:**
|
||||
`npx bmad-method@VERSION install`
|
||||
|
||||
⭐ **SUPPORT US:**
|
||||
🌟 GitHub: github.com/bmad-code-org/BMAD-METHOD/
|
||||
📺 YouTube: youtube.com/@BMadCode
|
||||
☕ Donate: buymeacoffee.com/bmad
|
||||
|
||||
🔥 **Next version tease!**
|
||||
```
|
||||
|
||||
**Content Strategy:**
|
||||
- Focus on **user impact** - what's better for them?
|
||||
- Highlight **annoying bugs fixed** that frustrated users
|
||||
- Show **new capabilities** that enable workflows
|
||||
- Keep it **punchy** - use emojis and short bullets
|
||||
- Add **personality** - excitement, humor, gratitude
|
||||
|
||||
### Step 4: Generate Twitter Post
|
||||
|
||||
**Limit: 25,000 characters per tweet (Premium).** With Premium, use a single comprehensive post matching the Discord style (minus Discord-specific formatting). Aim for 1,500-3,000 characters for better engagement.
|
||||
|
||||
**Threads are optional** — only use for truly massive releases where you want multiple engagement points.
|
||||
|
||||
See `examples/twitter-example.md` for the single-post Premium format.
|
||||
|
||||
## Content Selection Guidelines
|
||||
|
||||
**Include:**
|
||||
- New features that change workflows
|
||||
- Bug fixes for annoying/blocking issues
|
||||
- Documentation that helps users
|
||||
- Performance improvements
|
||||
- New agents or workflows
|
||||
- Breaking changes (call out clearly)
|
||||
|
||||
**Skip/Minimize:**
|
||||
- Internal refactoring
|
||||
- Dependency updates (unless user-facing)
|
||||
- Test improvements
|
||||
- Minor style fixes
|
||||
|
||||
**Emphasize:**
|
||||
- "Finally fixed" issues
|
||||
- "Faster" operations
|
||||
- "Easier" workflows
|
||||
- "Now supports" capabilities
|
||||
|
||||
## Examples
|
||||
|
||||
Reference example posts in `examples/` for tone and formatting guidance:
|
||||
|
||||
- **discord-example.md** — Full Discord announcement with emojis, sections, contributor shout-outs
|
||||
- **twitter-example.md** — Twitter thread format (5 tweets max for major releases)
|
||||
- **linkedin-example.md** — Professional post for major/minor releases with significant features
|
||||
|
||||
**When to use LinkedIn:**
|
||||
- Major version releases (e.g., v6.0.0 Beta, v7.0.0)
|
||||
- Minor releases with exceptional new features
|
||||
- Community milestone announcements
|
||||
|
||||
Read the appropriate example file before generating to match the established style and voice.
|
||||
|
||||
## Output Format
|
||||
|
||||
Present both announcements in clearly labeled sections:
|
||||
|
||||
```markdown
|
||||
## Discord Announcement
|
||||
|
||||
[paste Discord content here]
|
||||
|
||||
## Twitter Post
|
||||
|
||||
[paste Twitter content here]
|
||||
```
|
||||
|
||||
Offer to make adjustments if the user wants different emphasis, tone, or content.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
🚀 **BMad v6.0.0-alpha.23 RELEASED!**
|
||||
|
||||
🎉 Huge update - almost beta!
|
||||
|
||||
🪟 **WINDOWS INSTALLER FIXED** - Menu arrows issue should be fixed! CRLF & ESM problems resolved.
|
||||
|
||||
🎯 **PRD WORKFLOWS IMPROVED**
|
||||
• Validation & Edit workflows added!
|
||||
• PRD Cohesion check ensures document flows beautifully
|
||||
• Coming soon: Use of subprocess optimization (context saved!)
|
||||
• Coming soon: Final format polish step in all workflows - Human consumption OR hyper-optimized LLM condensed initially!
|
||||
|
||||
🔧 **WORKFLOW CREATOR & VALIDATOR**
|
||||
• Subprocess support for advanced optimization
|
||||
• Path violation checks ensure integrity
|
||||
• Beyond error checking - offers optimization & flow suggestions!
|
||||
|
||||
📚 **NEW DOCS SITE** - docs.bmad-method.org
|
||||
• Diataxis framework: Tutorials, How-To, Explanations, References
|
||||
• Current docs still being revised
|
||||
• Tutorials, blogs & explainers coming soon!
|
||||
|
||||
💡 **BRAINSTORMING REVOLUTION**
|
||||
• 100+ idea goal (quantity-first!)
|
||||
• Anti-bias protocol (pivot every 10 ideas)
|
||||
• Chain-of-thought + simulated temperature prompts
|
||||
• Coming soon: SubProcessing (on-the-fly sub agents)
|
||||
|
||||
🌟 **COMMUNITY PHILOSOPHY**
|
||||
• Everything is FREE - No paywalls, no gated content
|
||||
• Knowledge shared, not sold
|
||||
• No premium tiers - full access to our ideas
|
||||
|
||||
📊 **27 commits | 217 links converted | 42+ docs created**
|
||||
|
||||
🙏 **17 Community PR Authors in this release!**
|
||||
@lum (6 PRs!), @q00 (3 PRs!), @phil (2 PRs!)
|
||||
@mike, @alex, @ramiz, @sjennings + dependabot 🛡️
|
||||
Community-driven FTW! 🌟
|
||||
|
||||
📦 **INSTALL ALPHA:**
|
||||
`npx bmad-method install`
|
||||
|
||||
⭐ **SUPPORT US:**
|
||||
🌟 GitHub: github.com/bmad-code-org/BMAD-METHOD/
|
||||
📺 YouTube: youtube.com/@BMadCode
|
||||
|
||||
🎤 **SPEAKING & MEDIA**
|
||||
Available for conferences, podcasts, media appearances!
|
||||
Topics: AI-Native Organizations (Any Industry), BMad Method
|
||||
DM on Discord for inquiries!
|
||||
|
||||
🔥 **V6 Beta is DAYS away!** January 22nd ETA - new features such as xyz and abc bug fixes!
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
🚀 **Announcing BMad Method v6.0.0 Beta - AI-Native Agile Development Framework**
|
||||
|
||||
I'm excited to share that BMad Method, the open-source AI-driven agile development framework, is entering Beta! After 27 alpha releases and countless community contributions, we're approaching a major milestone.
|
||||
|
||||
**What's New in v6.0.0-alpha.23**
|
||||
|
||||
🪟 **Windows Compatibility Fixed**
|
||||
We've resolved the installer issues that affected Windows users. The menu arrows problem, CRLF handling, and ESM compatibility are all resolved.
|
||||
|
||||
🎯 **Enhanced PRD Workflows**
|
||||
Our Product Requirements Document workflows now include validation and editing capabilities, with a new cohesion check that ensures your documents flow beautifully. Subprocess optimization is coming soon to save even more context.
|
||||
|
||||
🔧 **Workflow Creator & Validator**
|
||||
New tools for creating and validating workflows with subprocess support, path violation checks, and optimization suggestions that go beyond simple error checking.
|
||||
|
||||
📚 **New Documentation Platform**
|
||||
We've launched docs.bmad-method.org using the Diataxis framework - providing clear separation between tutorials, how-to guides, explanations, and references. Our documentation is being continuously revised and expanded.
|
||||
|
||||
💡 **Brainstorming Revolution**
|
||||
Our brainstorming workflows now use research-backed techniques: 100+ idea goals, anti-bias protocols, chain-of-thought reasoning, and simulated temperature prompts for higher divergence.
|
||||
|
||||
**Our Philosophy**
|
||||
|
||||
Everything in BMad Method is FREE. No paywalls, no gated content, no premium tiers. We believe knowledge should be shared, not sold. This is community-driven development at its finest.
|
||||
|
||||
**The Stats**
|
||||
- 27 commits in this release
|
||||
- 217 documentation links converted
|
||||
- 42+ new documents created
|
||||
- 17 community PR authors contributed
|
||||
|
||||
**Get Started**
|
||||
|
||||
```
|
||||
npx bmad-method@alpha install
|
||||
```
|
||||
|
||||
**Learn More**
|
||||
- GitHub: github.com/bmad-code-org/BMAD-METHOD
|
||||
- YouTube: youtube.com/@BMadCode
|
||||
- Docs: docs.bmad-method.org
|
||||
|
||||
**What's Next?**
|
||||
|
||||
Beta is just days away with an ETA of January 22nd. We're also available for conferences, podcasts, and media appearances to discuss AI-Native Organizations and the BMad Method.
|
||||
|
||||
Have you tried BMad Method yet? I'd love to hear about your experience in the comments!
|
||||
|
||||
#AI #SoftwareDevelopment #Agile #OpenSource #DevTools #LLM #AgentEngineering
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
🚀 **BMad v6.0.0-alpha.23 RELEASED!**
|
||||
|
||||
Huge update - we're almost at Beta! 🎉
|
||||
|
||||
🪟 **WINDOWS INSTALLER FIXED** - Menu arrows issue should be fixed! CRLF & ESM problems resolved.
|
||||
|
||||
🎯 **PRD WORKFLOWS IMPROVED**
|
||||
• Validation & Edit workflows added!
|
||||
• PRD Cohesion check ensures document flows beautifully
|
||||
• Coming soon: Subprocess optimization (context saved!)
|
||||
• Coming soon: Final format polish step in all workflows
|
||||
|
||||
🔧 **WORKFLOW CREATOR & VALIDATOR**
|
||||
• Subprocess support for advanced optimization
|
||||
• Path violation checks ensure integrity
|
||||
• Beyond error checking - offers optimization & flow suggestions!
|
||||
|
||||
📚 **NEW DOCS SITE** - docs.bmad-method.org
|
||||
• Diataxis framework: Tutorials, How-To, Explanations, References
|
||||
• Current docs still being revised
|
||||
• Tutorials, blogs & explainers coming soon!
|
||||
|
||||
💡 **BRAINSTORMING REVOLUTION**
|
||||
• 100+ idea goal (quantity-first!)
|
||||
• Anti-bias protocol (pivot every 10 ideas)
|
||||
• Chain-of-thought + simulated temperature prompts
|
||||
• Coming soon: SubProcessing (on-the-fly sub agents)
|
||||
|
||||
🌟 **COMMUNITY PHILOSOPHY**
|
||||
• Everything is FREE - No paywalls, no gated content
|
||||
• Knowledge shared, not sold
|
||||
• No premium tiers - full access to our ideas
|
||||
|
||||
📊 **27 commits | 217 links converted | 42+ docs created**
|
||||
|
||||
🙏 **17 Community PR Authors in this release!**
|
||||
@lum (6 PRs!), @q00 (3 PRs!), @phil (2 PRs!)
|
||||
@mike, @alex, @ramiz, @sjennings + dependabot 🛡️
|
||||
Community-driven FTW! 🌟
|
||||
|
||||
📦 **INSTALL ALPHA:**
|
||||
`npx bmad-method install`
|
||||
|
||||
⭐ **SUPPORT US:**
|
||||
🌟 GitHub: github.com/bmad-code-org/BMAD-METHOD/
|
||||
📺 YouTube: youtube.com/@BMadCode
|
||||
|
||||
🎤 **SPEAKING & MEDIA**
|
||||
Available for conferences, podcasts, media appearances!
|
||||
Topics: AI-Native Organizations (Any Industry), BMad Method
|
||||
DM on Discord for inquiries!
|
||||
|
||||
🔥 **V6 Beta is DAYS away!** January 22nd ETA!
|
||||
|
||||
#AI #DevTools #Agile #OpenSource #LLM #AgentEngineering
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: draft-changelog
|
||||
description: Analyzes changes since the last release and generates a draft changelog entry
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Read `prompts/instructions.md` and execute.
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
# Draft Changelog Execution
|
||||
|
||||
## Input
|
||||
Project path (or run from project root)
|
||||
|
||||
## Step 1: Identify Current State
|
||||
- Get the latest released tag
|
||||
- Get current version
|
||||
- Verify there are commits since the last release
|
||||
|
||||
## Step 2: Launch Explore Agent
|
||||
|
||||
Use `thoroughness: "very thorough"` to analyze all changes since the last release tag.
|
||||
|
||||
**Key: For each merge commit, look up the merged PR/issue that was closed.**
|
||||
- Use `gh pr view` or git commit body to find the PR number
|
||||
- Read the PR description and comments to understand full context
|
||||
- Don't rely solely on commit merge messages - they lack context
|
||||
|
||||
**Analyze:**
|
||||
|
||||
1. **All merges/commits** since the last tag
|
||||
2. **For each merge, read the original PR/issue** that was closed
|
||||
3. **Files changed** with statistics
|
||||
4. **Categorize changes:**
|
||||
- 🎁 **Features** - New functionality, new agents, new workflows
|
||||
- 🐛 **Bug Fixes** - Fixed bugs, corrected issues
|
||||
- ♻️ **Refactoring** - Code improvements, reorganization
|
||||
- 📚 **Documentation** - Docs updates, README changes
|
||||
- 🔧 **Maintenance** - Dependency updates, tooling, infrastructure
|
||||
- 💥 **Breaking Changes** - Changes that may affect users
|
||||
|
||||
**Provide:**
|
||||
- Comprehensive summary of ALL changes with PR context
|
||||
- Categorization of each change
|
||||
- Identification of breaking changes
|
||||
- Significance assessment (major/minor/trivial)
|
||||
|
||||
## Step 3: Generate Draft Changelog
|
||||
|
||||
Format:
|
||||
```markdown
|
||||
## v0.X.X - [Date]
|
||||
|
||||
* [Change 1 - categorized by type]
|
||||
* [Change 2]
|
||||
```
|
||||
|
||||
Guidelines:
|
||||
- Present tense ("Fix bug" not "Fixed bug")
|
||||
- Most significant changes first
|
||||
- Group related changes
|
||||
- Clear, concise language
|
||||
- For breaking changes, clearly indicate impact
|
||||
|
||||
## Step 4: Present Draft
|
||||
|
||||
Show the draft with current version, last tag, commit count, and options to edit/retry.
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# gh-triage
|
||||
|
||||
Fetches all GitHub issues via gh CLI and uses AI agents to deeply analyze, cluster, and prioritize issues.
|
||||
|
||||
## Usage
|
||||
|
||||
Run from within any BMad Method repository to triage issues.
|
||||
|
||||
## What It Does
|
||||
|
||||
1. Fetches all open issues via `gh issue list`
|
||||
2. Splits issues into batches
|
||||
3. Launches parallel agents to analyze each batch
|
||||
4. Generates comprehensive triage report to `_bmad-output/triage-reports/`
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
name: gh-triage
|
||||
description: Fetch all GitHub issues via gh CLI and use AI agents to deeply analyze, cluster, and prioritize issues
|
||||
license: MIT
|
||||
disable-model-invocation: true
|
||||
metadata:
|
||||
author: bmad-code-org
|
||||
version: "3.0.0"
|
||||
compatibility: Requires gh CLI, git repository, and BMad Method with Task tool support
|
||||
---
|
||||
|
||||
Read `prompts/instructions.md` and execute.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
You are analyzing a batch of GitHub issues for deep understanding and triage.
|
||||
|
||||
**YOUR TASK:**
|
||||
Read the issues in your batch and provide DEEP analysis:
|
||||
|
||||
1. **For EACH issue, analyze:**
|
||||
- What is this ACTUALLY about? (beyond keywords)
|
||||
- What component/system does it affect?
|
||||
- What's the impact and severity?
|
||||
- Is it a bug, feature request, or something else?
|
||||
- What specific theme does it belong to?
|
||||
|
||||
2. **PRIORITY ASSESSMENT:**
|
||||
- CRITICAL: Blocks users, security issues, data loss, broken installers
|
||||
- HIGH: Major functionality broken, important features missing
|
||||
- MEDIUM: Workarounds available, minor bugs, nice-to-have features
|
||||
- LOW: Edge cases, cosmetic issues, questions
|
||||
|
||||
3. **RELATIONSHIPS:**
|
||||
- Duplicates: Near-identical issues about the same problem
|
||||
- Related: Issues connected by theme or root cause
|
||||
- Dependencies: One issue blocks or requires another
|
||||
|
||||
**YOUR BATCH:**
|
||||
[Paste the batch of issues here - each with number, title, body, labels]
|
||||
|
||||
**OUTPUT FORMAT (JSON only, no markdown):**
|
||||
{
|
||||
"issues": [
|
||||
{
|
||||
"number": 123,
|
||||
"title": "issue title",
|
||||
"deep_understanding": "2-3 sentences explaining what this is really about",
|
||||
"affected_components": ["installer", "workflows", "docs"],
|
||||
"issue_type": "bug/feature/question/tech-debt",
|
||||
"priority": "CRITICAL/HIGH/MEDIUM/LOW",
|
||||
"priority_rationale": "Why this priority level",
|
||||
"theme": "installation/workflow/integration/docs/ide-support/etc",
|
||||
"relationships": {
|
||||
"duplicates_of": [456],
|
||||
"related_to": [789, 101],
|
||||
"blocks": [111]
|
||||
}
|
||||
}
|
||||
],
|
||||
"cross_repo_issues": [
|
||||
{"number": 123, "target_repo": "bmad-builder", "reason": "about agent builder"}
|
||||
],
|
||||
"cleanup_candidates": [
|
||||
{"number": 456, "reason": "v4-related/outdated/duplicate"}
|
||||
],
|
||||
"themes_found": {
|
||||
"Installation Blockers": {
|
||||
"count": 5,
|
||||
"root_cause": "Common pattern if identifiable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Return ONLY valid JSON. No explanations outside the JSON structure.
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# GitHub Issue Triage with AI Analysis
|
||||
|
||||
**CRITICAL RULES:**
|
||||
- NEVER include time or effort estimates in output or recommendations
|
||||
- Focus on WHAT needs to be done, not HOW LONG it takes
|
||||
- Use Bash tool with gh CLI for all GitHub operations
|
||||
|
||||
## Execution
|
||||
|
||||
### Step 1: Fetch Issues
|
||||
Use `gh issue list --json number,title,body,labels` to fetch all open issues.
|
||||
|
||||
### Step 2: Batch Creation
|
||||
Split issues into batches of ~10 issues each for parallel analysis.
|
||||
|
||||
### Step 3: Parallel Agent Analysis
|
||||
For EACH batch, use the Task tool with `subagent_type=general-purpose` to launch an agent with prompt from `prompts/agent-prompt.md`
|
||||
|
||||
### Step 4: Consolidate & Generate Report
|
||||
After all agents complete, create a comprehensive markdown report saved to `_bmad-output/triage-reports/triage-YYYY-MM-DD.md`
|
||||
|
||||
## Report Format
|
||||
|
||||
### Executive Summary
|
||||
- Total issues analyzed
|
||||
- Issue count by priority (CRITICAL, HIGH, MEDIUM, LOW)
|
||||
- Major themes discovered
|
||||
- Top 5 critical issues requiring immediate attention
|
||||
|
||||
### Critical Issues (CRITICAL Priority)
|
||||
For each CRITICAL issue:
|
||||
- **#123 - [Issue Title](url)**
|
||||
- **What it's about:** [Deep understanding]
|
||||
- **Affected:** [Components]
|
||||
- **Why Critical:** [Rationale]
|
||||
- **Suggested Action:** [Specific action]
|
||||
|
||||
### High Priority Issues (HIGH Priority)
|
||||
Same format as Critical, grouped by theme.
|
||||
|
||||
### Theme Clusters
|
||||
For each major theme:
|
||||
- **Theme Name** (N issues)
|
||||
- **What connects these:** [Pattern]
|
||||
- **Root cause:** [If identifiable]
|
||||
- **Consolidated actions:** [Bulk actions if applicable]
|
||||
- **Issues:** #123, #456, #789
|
||||
|
||||
### Relationships & Dependencies
|
||||
- **Duplicates:** List pairs with `gh issue close` commands
|
||||
- **Related Issues:** Groups of related issues
|
||||
- **Dependencies:** Blocking relationships
|
||||
|
||||
### Cross-Repo Issues
|
||||
Issues that should be migrated to other repositories.
|
||||
|
||||
For each, provide:
|
||||
```
|
||||
gh issue close XXX --repo CURRENT_REPO --comment "This issue belongs in REPO. Please report at https://github.com/TARGET_REPO/issues/new"
|
||||
```
|
||||
|
||||
### Cleanup Candidates
|
||||
- **v4-related:** Deprecated version issues with close commands
|
||||
- **Stale:** No activity >30 days
|
||||
- **Low priority + old:** Low priority issues >60 days old
|
||||
|
||||
### Actionable Next Steps
|
||||
Specific, prioritized actions:
|
||||
1. [CRITICAL] Fix broken installer - affects all new users
|
||||
2. [HIGH] Resolve Windows path escaping issues
|
||||
3. [HIGH] Address workflow integration bugs
|
||||
etc.
|
||||
|
||||
Include `gh` commands where applicable for bulk actions.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# release-module
|
||||
|
||||
Automates the complete release process for npm modules.
|
||||
|
||||
## Usage
|
||||
|
||||
Run from project root or pass project path:
|
||||
```
|
||||
bmad-utility-skills:release-module
|
||||
```
|
||||
|
||||
## Prerequisite
|
||||
|
||||
First run `draft-changelog` to analyze changes and create a draft changelog.
|
||||
|
||||
## What It Does
|
||||
|
||||
1. Gets and confirms changelog entry
|
||||
2. Confirms version bump type (patch/minor/major)
|
||||
3. Updates CHANGELOG.md
|
||||
4. Bumps version with `npm version`
|
||||
5. Pushes git tag
|
||||
6. Publishes to npm
|
||||
7. Creates GitHub release
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
name: release-module
|
||||
description: Automates the complete release process for npm modules - version bump, changelog, git tag, npm publish, GitHub release
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
Read `prompts/instructions.md` and execute.
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
# Release BMad Module Execution
|
||||
|
||||
## Input
|
||||
Project path (or run from project root)
|
||||
|
||||
## Execution Steps
|
||||
|
||||
### Step 1: Get Current State
|
||||
- Verify git working tree is clean
|
||||
- Get latest tag and current version
|
||||
- Check for unpushed commits
|
||||
|
||||
### Step 2: Get Changelog Entry
|
||||
|
||||
Ask the user for the changelog entry (from draft-changelog skill or manual).
|
||||
|
||||
### Step 3: Confirm Changelog
|
||||
|
||||
Show project name, current version, proposed next version, and changelog. Get confirmation.
|
||||
|
||||
### Step 4: Confirm Version Bump Type
|
||||
|
||||
Ask what type of bump: patch, minor, major, prerelease, or custom.
|
||||
|
||||
### Step 5: Update CHANGELOG.md
|
||||
|
||||
Insert new entry at top, commit, and push.
|
||||
|
||||
### Step 6: Bump Version
|
||||
|
||||
Run `npm version` to update package.json, create commit, and create tag.
|
||||
|
||||
### Step 7: Push Tag
|
||||
|
||||
Push the new version tag to GitHub.
|
||||
|
||||
### Step 8: Publish to npm
|
||||
|
||||
Publish the package.
|
||||
|
||||
### Step 9: Create GitHub Release
|
||||
|
||||
Create release with changelog notes using `gh release create`.
|
||||
|
||||
### Step 10: Create Social Announcement
|
||||
|
||||
Create a social media announcement file at `_bmad-output/social/{repo-name}-release.md`.
|
||||
|
||||
Format:
|
||||
```markdown
|
||||
# {name} v{version} Released
|
||||
|
||||
## Highlights
|
||||
{2-3 bullet points of key features/changes}
|
||||
|
||||
## Links
|
||||
- GitHub: {release-url}
|
||||
- npm: {npm-url}
|
||||
```
|
||||
|
||||
### Step 11: Confirm Completion
|
||||
|
||||
Show npm, GitHub, and social announcement file paths.
|
||||
|
||||
## Error Handling
|
||||
|
||||
Stop immediately on any step failure. Inform user and suggest fix.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- Wait for user confirmation before destructive operations
|
||||
- Push changelog commit before version bump
|
||||
- Use explicit directory paths in commands
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
name: Bug Report
|
||||
description: File a bug report to help us improve BMad Method
|
||||
title: "[BUG] "
|
||||
labels: bug
|
||||
assignees: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for filing a bug report! Please fill out the information below to help us reproduce and fix the issue.
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Clear and concise description of what the bug is
|
||||
placeholder: e.g., When I run /dev-story, it crashes on step 3
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Step-by-step instructions to reproduce the behavior
|
||||
placeholder: |
|
||||
1. Run 'npx bmad-method install'
|
||||
2. Select option X
|
||||
3. Run workflow Y
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: What you expected to happen
|
||||
placeholder: The workflow should complete successfully
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: actual
|
||||
attributes:
|
||||
label: Actual behavior
|
||||
description: What actually happened
|
||||
placeholder: The workflow crashed with error "..."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: Add screenshots if applicable (paste images directly)
|
||||
placeholder: Paste any relevant screenshots here
|
||||
|
||||
- type: dropdown
|
||||
id: module
|
||||
attributes:
|
||||
label: Which module is this for?
|
||||
description: Select the BMad module this issue relates to
|
||||
options:
|
||||
- BMad Method (BMM) - Core Framework
|
||||
- BMad Builder (BMB) - Agent Builder Tool
|
||||
- Test Architect (TEA) - Test Strategy Module
|
||||
- Game Dev Studio (BMGD) - Game Development Module
|
||||
- Creative Intelligence Suite (CIS) - Innovation Module
|
||||
- Not sure / Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: BMad Version
|
||||
description: "Check with: npx bmad-method --version or check package.json"
|
||||
placeholder: e.g., 6.0.0-Beta.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: ide
|
||||
attributes:
|
||||
label: Which AI IDE are you using?
|
||||
options:
|
||||
- Claude Code
|
||||
- Cursor
|
||||
- Windsurf
|
||||
- Copilot CLI / GitHub Copilot
|
||||
- Kilo Code
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Operating System
|
||||
options:
|
||||
- macOS
|
||||
- Windows
|
||||
- Linux
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Copy and paste any relevant log output
|
||||
render: shell
|
||||
|
||||
- type: checkboxes
|
||||
id: terms
|
||||
attributes:
|
||||
label: Confirm
|
||||
options:
|
||||
- label: I've searched for existing issues
|
||||
required: true
|
||||
- label: I'm using the latest version
|
||||
required: false
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
name: Documentation
|
||||
description: Report issues or suggest improvements to documentation
|
||||
title: "[DOCS] "
|
||||
labels: documentation
|
||||
assignees: []
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Help us improve the BMad Method documentation!
|
||||
|
||||
- type: dropdown
|
||||
id: doc-type
|
||||
attributes:
|
||||
label: What type of documentation issue is this?
|
||||
options:
|
||||
- Error or inaccuracy
|
||||
- Missing information
|
||||
- Unclear or confusing
|
||||
- Outdated content
|
||||
- Request for new documentation
|
||||
- Typo or grammar
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: location
|
||||
attributes:
|
||||
label: Documentation location
|
||||
description: Where is the documentation that needs improvement?
|
||||
placeholder: e.g., http://docs.bmad-method.org/tutorials/getting-started/ or "In the README"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: issue
|
||||
attributes:
|
||||
label: What's the issue?
|
||||
description: Describe the documentation issue in detail
|
||||
placeholder: e.g., Step 3 says to run command X but it should be command Y
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: suggestion
|
||||
attributes:
|
||||
label: Suggested improvement
|
||||
description: How would you like to see this improved?
|
||||
placeholder: e.g., Change the command to X and add an example
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: BMad Version (if applicable)
|
||||
placeholder: e.g., 6.0.0-Beta.4
|
||||
|
|
@ -113,3 +113,6 @@ jobs:
|
|||
|
||||
- name: Test agent compilation components
|
||||
run: npm run test:install
|
||||
|
||||
- name: Validate file references
|
||||
run: npm run validate:refs
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ _bmad-output
|
|||
.qwen
|
||||
.rovodev
|
||||
.kilocodemodes
|
||||
.claude
|
||||
.claude/commands
|
||||
.codex
|
||||
.github/chatmodes
|
||||
.github/agents
|
||||
|
|
|
|||
6
.npmrc
6
.npmrc
|
|
@ -1 +1,5 @@
|
|||
registry=https://registry.npmjs.org
|
||||
# Prevent peer dependency warnings during installation
|
||||
legacy-peer-deps=true
|
||||
|
||||
# Improve install performance
|
||||
prefer-offline=true
|
||||
|
|
|
|||
32
CHANGELOG.md
32
CHANGELOG.md
|
|
@ -1,5 +1,37 @@
|
|||
# Changelog
|
||||
|
||||
## [6.0.0-Beta.5]
|
||||
|
||||
### 🎁 Features
|
||||
|
||||
* **Add generate-project-context workflow** — New 3-step workflow for project context generation, integrated with quick-flow-solo-dev agent
|
||||
* **Shard market research customer analysis** — Refactor monolithic customer insights into 4-step detailed customer behavior analysis workflow
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* **Fix npm install peer dependency issues** — Add `.npmrc` with `legacy-peer-deps=true`, update Starlight to 0.37.5, and add `--legacy-peer-deps` flag to module installer (PR #1476)
|
||||
* **Fix leaked source paths in PRD validation report** — Replace absolute `/src/core/` paths with `{project-root}/_bmad/core/` (#1481)
|
||||
* **Fix orphaned market research customer analysis** — Connect step-01-init to step-02-customer-behavior to complete workflow sharding (#1486)
|
||||
* **Fix duplicate 2-letter brainstorming code** — Change BS to BSP to resolve conflict with cis Brainstorming module
|
||||
* **Fix tech writer sidecar functionality** — Enable proper sidecar operation (#1487)
|
||||
* **Fix relative paths in workflow steps** — Correct paths in step-11-polish (#1497) and step-e-04-complete (#1498)
|
||||
* **Fix party-mode workflow file extension** — Correct extension in workflow.xml (#1499)
|
||||
* **Fix generated slash commands** — Add `disable-model-invocation` to all generated commands (#1501)
|
||||
* **Fix agent scan and help CSV files** — Correct module-help.csv entries
|
||||
* **Fix HELP_STEP placeholder replacement** — Fix placeholder not replaced in compiled agents, fix hardcoded path, fix single quote (#1437)
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
* **Add exact slash commands to Getting Started guide** — Provide precise command examples for users (#1505)
|
||||
* **Remove .claude/commands from version control** — Commands are generated, not tracked (#1506)
|
||||
|
||||
### 🔧 Maintenance
|
||||
|
||||
* **Update Starlight to 0.37.5** — Latest version with peer dependency compatibility
|
||||
* **Add GitHub issue templates** — New bug-report.yaml and documentation.yaml templates
|
||||
|
||||
---
|
||||
|
||||
## [6.0.0-Beta.4]
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ Every step tells you what's next. Optional phases (brainstorming, research, UX d
|
|||
BMad Method extends with official modules for specialized domains. Modules are available during installation and can be added to your project at any time. After the V6 beta period these will also be available as Plugins and Granular Skills.
|
||||
|
||||
| Module | GitHub | NPM | Purpose |
|
||||
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------- |
|
||||
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
||||
| **BMad Method (BMM)** | [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD) | [bmad-method](https://www.npmjs.com/package/bmad-method) | Core framework with 34+ workflows across 4 development phases |
|
||||
| **BMad Builder (BMB)** | [bmad-code-org/bmad-builder](https://github.com/bmad-code-org/bmad-builder) | [bmad-builder](https://www.npmjs.com/package/bmad-builder) | Create custom BMad agents, workflows, and domain-specific modules |
|
||||
| **Test Architect (TEA)** 🆕 | [bmad-code-org/tea](https://github.com/bmad-code-org/bmad-method-test-architecture-enterprise) | [tea](https://www.npmjs.com/package/bmad-method-test-architecture-enterprise) | Risk-based test strategy, automation, and release gates (8 workflows) |
|
||||
|
|
@ -116,6 +116,7 @@ BMad provides two testing options to fit your needs:
|
|||
### For v4 Users
|
||||
|
||||
- **[v4 Documentation](https://github.com/bmad-code-org/BMAD-METHOD/tree/V4/docs)**
|
||||
- If you need to install V4, you can do this with `npx bmad-method@4.44.3 install` - similar for any past version.
|
||||
|
||||
## Community
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
|
|
@ -0,0 +1,374 @@
|
|||
---
|
||||
title: "Game Types Reference"
|
||||
---
|
||||
|
||||
BMGD supports 24 game type templates. Each adds genre-specific sections to your GDD.
|
||||
|
||||
## Game Types
|
||||
|
||||
### Action & Combat
|
||||
|
||||
#### Action Platformer
|
||||
|
||||
Side-scrolling or 3D platforming with combat mechanics.
|
||||
|
||||
**Examples:** Hollow Knight, Mega Man, Celeste
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Movement systems (jumps, dashes, wall mechanics)
|
||||
- Combat mechanics (melee/ranged, combos)
|
||||
- Level design patterns
|
||||
- Boss design
|
||||
|
||||
#### Shooter
|
||||
|
||||
Projectile combat with aiming mechanics.
|
||||
|
||||
**Examples:** Doom, Call of Duty, Splatoon
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Weapon systems
|
||||
- Aiming and accuracy
|
||||
- Enemy AI patterns
|
||||
- Level/arena design
|
||||
- Multiplayer considerations
|
||||
|
||||
#### Fighting
|
||||
|
||||
1v1 combat with combos and frame data.
|
||||
|
||||
**Examples:** Street Fighter, Tekken, Super Smash Bros.
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Frame data systems
|
||||
- Combo mechanics
|
||||
- Character movesets
|
||||
- Competitive balance
|
||||
- Netcode requirements
|
||||
|
||||
### Strategy & Tactics
|
||||
|
||||
#### Strategy
|
||||
|
||||
Resource management with tactical decisions.
|
||||
|
||||
**Examples:** StarCraft, Civilization, Europa Universalis
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Resource systems
|
||||
- Unit/building design
|
||||
- AI opponent behavior
|
||||
- Map/scenario design
|
||||
- Victory conditions
|
||||
|
||||
#### Turn-Based Tactics
|
||||
|
||||
Grid-based movement with turn order.
|
||||
|
||||
**Examples:** XCOM, Fire Emblem, Into the Breach
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Grid and movement systems
|
||||
- Turn order mechanics
|
||||
- Cover and positioning
|
||||
- Unit progression
|
||||
- Procedural mission generation
|
||||
|
||||
#### Tower Defense
|
||||
|
||||
Wave-based defense with tower placement.
|
||||
|
||||
**Examples:** Bloons TD, Kingdom Rush, Plants vs. Zombies
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Tower types and upgrades
|
||||
- Wave design and pacing
|
||||
- Economy systems
|
||||
- Map design patterns
|
||||
- Meta-progression
|
||||
|
||||
### RPG & Progression
|
||||
|
||||
#### RPG
|
||||
|
||||
Character progression with stats, inventory, and quests.
|
||||
|
||||
**Examples:** Final Fantasy, The Witcher, Baldur's Gate
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Character stats and leveling
|
||||
- Inventory and equipment
|
||||
- Quest system design
|
||||
- Combat system (action/turn-based)
|
||||
- Skill trees and builds
|
||||
|
||||
#### Roguelike
|
||||
|
||||
Procedural generation with permadeath and run-based progression.
|
||||
|
||||
**Examples:** Hades, Dead Cells, Spelunky
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Procedural generation rules
|
||||
- Permadeath and persistence
|
||||
- Run structure and pacing
|
||||
- Item/ability synergies
|
||||
- Meta-progression systems
|
||||
|
||||
#### Metroidvania
|
||||
|
||||
Interconnected world with ability gating.
|
||||
|
||||
**Examples:** Metroid, Castlevania: Symphony of the Night, Ori
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- World map connectivity
|
||||
- Ability gating design
|
||||
- Backtracking flow
|
||||
- Secret and collectible placement
|
||||
- Power-up progression
|
||||
|
||||
### Narrative & Story
|
||||
|
||||
#### Adventure
|
||||
|
||||
Story-driven exploration with puzzle elements.
|
||||
|
||||
**Examples:** Monkey Island, Myst, Life is Strange
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Puzzle design
|
||||
- Narrative delivery
|
||||
- Exploration mechanics
|
||||
- Dialogue systems
|
||||
- Story branching
|
||||
|
||||
#### Visual Novel
|
||||
|
||||
Narrative choices with branching story.
|
||||
|
||||
**Examples:** Doki Doki Literature Club, Phoenix Wright, Steins;Gate
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Branching narrative structure
|
||||
- Choice and consequence
|
||||
- Character routes
|
||||
- UI/presentation
|
||||
- Save/load states
|
||||
|
||||
#### Text-Based
|
||||
|
||||
Text input/output games with parser or choice mechanics.
|
||||
|
||||
**Examples:** Zork, 80 Days, Dwarf Fortress (adventure mode)
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Parser or choice systems
|
||||
- World model
|
||||
- Narrative structure
|
||||
- Text presentation
|
||||
- Save state management
|
||||
|
||||
### Simulation & Management
|
||||
|
||||
#### Simulation
|
||||
|
||||
Realistic systems with management and building.
|
||||
|
||||
**Examples:** SimCity, RollerCoaster Tycoon, The Sims
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Core simulation loops
|
||||
- Economy modeling
|
||||
- AI agents/citizens
|
||||
- Building/construction
|
||||
- Failure states
|
||||
|
||||
#### Sandbox
|
||||
|
||||
Creative freedom with building and minimal objectives.
|
||||
|
||||
**Examples:** Minecraft, Terraria, Garry's Mod
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Creation tools
|
||||
- Physics/interaction systems
|
||||
- Persistence and saving
|
||||
- Sharing/community features
|
||||
- Optional objectives
|
||||
|
||||
### Sports & Racing
|
||||
|
||||
#### Racing
|
||||
|
||||
Vehicle control with tracks and lap times.
|
||||
|
||||
**Examples:** Mario Kart, Forza, Need for Speed
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Vehicle physics model
|
||||
- Track design
|
||||
- AI opponents
|
||||
- Progression/career mode
|
||||
- Multiplayer racing
|
||||
|
||||
#### Sports
|
||||
|
||||
Team-based or individual sports simulation.
|
||||
|
||||
**Examples:** FIFA, NBA 2K, Tony Hawk's Pro Skater
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Sport-specific rules
|
||||
- Player/team management
|
||||
- AI opponent behavior
|
||||
- Season/career modes
|
||||
- Multiplayer modes
|
||||
|
||||
### Multiplayer
|
||||
|
||||
#### MOBA
|
||||
|
||||
Multiplayer team battles with hero selection.
|
||||
|
||||
**Examples:** League of Legends, Dota 2, Smite
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Hero/champion design
|
||||
- Lane and map design
|
||||
- Team composition
|
||||
- Matchmaking
|
||||
- Economy (gold/items)
|
||||
|
||||
#### Party Game
|
||||
|
||||
Local multiplayer with minigames.
|
||||
|
||||
**Examples:** Mario Party, Jackbox, Overcooked
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Minigame design patterns
|
||||
- Controller support
|
||||
- Round/game structure
|
||||
- Scoring systems
|
||||
- Player count flexibility
|
||||
|
||||
### Horror & Survival
|
||||
|
||||
#### Survival
|
||||
|
||||
Resource gathering with crafting and persistent threats.
|
||||
|
||||
**Examples:** Don't Starve, Subnautica, The Forest
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Resource gathering
|
||||
- Crafting systems
|
||||
- Hunger/health/needs
|
||||
- Threat systems
|
||||
- Base building
|
||||
|
||||
#### Horror
|
||||
|
||||
Atmosphere and tension with limited resources.
|
||||
|
||||
**Examples:** Resident Evil, Silent Hill, Amnesia
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Fear mechanics
|
||||
- Resource scarcity
|
||||
- Sound design
|
||||
- Lighting and visibility
|
||||
- Enemy/threat design
|
||||
|
||||
### Casual & Progression
|
||||
|
||||
#### Puzzle
|
||||
|
||||
Logic-based challenges and problem-solving.
|
||||
|
||||
**Examples:** Tetris, Portal, The Witness
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Puzzle mechanics
|
||||
- Difficulty progression
|
||||
- Hint systems
|
||||
- Level structure
|
||||
- Scoring/rating
|
||||
|
||||
#### Idle/Incremental
|
||||
|
||||
Passive progression with upgrades and automation.
|
||||
|
||||
**Examples:** Cookie Clicker, Adventure Capitalist, Clicker Heroes
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Core loop design
|
||||
- Prestige systems
|
||||
- Automation unlocks
|
||||
- Number scaling
|
||||
- Offline progress
|
||||
|
||||
#### Card Game
|
||||
|
||||
Deck building with card mechanics.
|
||||
|
||||
**Examples:** Slay the Spire, Hearthstone, Magic: The Gathering Arena
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Card design framework
|
||||
- Deck building rules
|
||||
- Mana/resource systems
|
||||
- Rarity and collection
|
||||
- Competitive balance
|
||||
|
||||
### Rhythm
|
||||
|
||||
#### Rhythm
|
||||
|
||||
Music synchronization with timing-based gameplay.
|
||||
|
||||
**Examples:** Guitar Hero, Beat Saber, Crypt of the NecroDancer
|
||||
|
||||
**GDD sections:**
|
||||
|
||||
- Note/beat mapping
|
||||
- Scoring systems
|
||||
- Difficulty levels
|
||||
- Music licensing
|
||||
- Input methods
|
||||
|
||||
## Hybrid Types
|
||||
|
||||
Multiple game types can be combined. GDD sections from all selected types are included.
|
||||
|
||||
| Hybrid | Components | Combined Sections |
|
||||
|--------|------------|-------------------|
|
||||
| Action RPG | Action Platformer + RPG | Movement, combat, stats, inventory |
|
||||
| Survival Horror | Survival + Horror | Resources, crafting, atmosphere, fear |
|
||||
| Roguelike Deckbuilder | Roguelike + Card Game | Run structure, procedural gen, cards |
|
||||
| Tactical RPG | Turn-Based Tactics + RPG | Grid movement, stats, progression |
|
||||
| Open World Survival | Sandbox + Survival | Building, crafting, exploration |
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
title: "BMGD Quick Guide"
|
||||
description: Quick reference for BMad Game Dev Studio
|
||||
---
|
||||
|
||||

|
||||
|
||||
# BMGD Quick Guide
|
||||
|
||||
BMad Game Dev Studio (BMGD) extends BMM with game-specific capabilities. Developed by game industry veterans, it guides you through product research, technical design, narrative design, and a full epic-driven production cycle.
|
||||
|
||||
## Under Construction
|
||||
|
||||
Documentation is under heavy construction catching up with the new beta release. We'll have complete documentation up as soon as possible. For now, please ask in the BMGD section of the Discord if you have any questions.
|
||||
|
||||

|
||||
|
||||
## Quick Start
|
||||
|
||||
**Install → Game Brief → GDD → (Narrative) → Architecture → Build**
|
||||
|
||||
BMGD is an optional module installed via BMAD Method: `npx bmad-method install`
|
||||
|
||||
See [How-To Reference](#how-to-reference) for commands.
|
||||
|
||||
## Development Phases
|
||||
|
||||
| Phase | Name | Key Activities |
|
||||
|-------|------|----------------|
|
||||
| 1 | **Preproduction** | Brainstorm Game, Game Brief, market research |
|
||||
| 2 | **Design** | GDD creation, Narrative Design (for story-driven games) |
|
||||
| 3 | **Technical** | Game Architecture (engine, systems, patterns) |
|
||||
| 4 | **Production** | Sprint planning, story development, code review, testing |
|
||||
|
||||
## BMGD Agents
|
||||
|
||||
| Agent | Purpose |
|
||||
|-------|---------|
|
||||
| Game Designer | Game mechanics, balance, player psychology |
|
||||
| Game Developer | Implementation with engine-specific patterns |
|
||||
| Game Architect | Engine selection, systems design, technical structure |
|
||||
| Game Scrum Master | Sprint planning and epic management |
|
||||
| Game QA | Playtesting, engine-specific testing, performance profiling |
|
||||
| Game Solo Dev | Full-stack game development for solo projects |
|
||||
|
||||
## Key Documents
|
||||
|
||||
| Document | Purpose |
|
||||
|----------|---------|
|
||||
| **Game Brief** | Vision, market positioning, fundamentals |
|
||||
| **GDD** | Core loop, mechanics, progression, art/audio direction |
|
||||
| **Narrative Design** | Story structure, characters, world-building, dialogue |
|
||||
| **Architecture** | Engine, systems, patterns, project structure |
|
||||
|
||||
## Game Type Templates
|
||||
|
||||
BMGD includes 24 game type templates that auto-configure GDD sections:
|
||||
|
||||
Action, Adventure, Puzzle, RPG, Strategy, Simulation, Sports, Racing, Fighting, Horror, Platformer, Shooter, and more.
|
||||
|
||||
Each template provides genre-specific GDD sections, mechanics patterns, testing considerations, and common pitfalls to avoid.
|
||||
|
||||
## Explanation: BMGD vs BMM
|
||||
|
||||
### When to Use Each
|
||||
|
||||
| Use BMGD for | Use BMM for |
|
||||
|--------------|-------------|
|
||||
| Video games | Web applications |
|
||||
| Interactive experiences | APIs and services |
|
||||
| Game prototyping | Mobile apps (non-game) |
|
||||
| Game jams | General software projects |
|
||||
|
||||
### Phase Mapping
|
||||
|
||||
| BMM Phase | BMGD Phase | Key Difference |
|
||||
|-----------|------------|----------------|
|
||||
| Analysis | Preproduction | Game concepts, Game Brief instead of Product Brief |
|
||||
| Planning | Design | GDD instead of PRD; optional Narrative Design |
|
||||
| Solutioning | Technical | Focus on engine selection, game-specific patterns |
|
||||
| Implementation | Production | Game QA replaces TEA; engine-specific testing |
|
||||
|
||||
### Document Differences
|
||||
|
||||
| BMM | BMGD | Notes |
|
||||
|-----|------|-------|
|
||||
| Product Brief | Game Brief | Captures vision, market, fundamentals |
|
||||
| PRD | GDD | Includes mechanics, balance, player experience |
|
||||
| N/A | Narrative Design | Story, characters, world (story-driven games) |
|
||||
| Architecture | Architecture | BMGD version includes engine-specific patterns and considerations |
|
||||
|
||||
### Testing Differences
|
||||
|
||||
**BMM (TEA):** Web-focused testing with Playwright, Cypress, API testing, E2E for web apps.
|
||||
|
||||
**BMGD (Game QA):** Engine-specific frameworks (Unity, Unreal, Godot), gameplay testing, performance profiling, playtest planning, balance validation.
|
||||
|
||||
## How-To Reference
|
||||
|
||||
| I need to... | Action |
|
||||
|--------------|--------------------------------------------------------------------------------------------------------|
|
||||
| Install BMGD | Run `npx bmad-method install` and select BMGD during module installation |
|
||||
| Start a new game | Run `/bmad-gds-brainstorm-game`, then `/bmad:gds:create-game-brief` |
|
||||
| Design my game | Run `/bmad-gds-create-gdd`; add `/bmad:gds:narrative` if story-heavy |
|
||||
| Plan architecture | Run `/bmad-gds-game-architecture` with Game Architect |
|
||||
| Build my game | Use Phase 4 production workflows - Run `/bmad-help` to see what's next |
|
||||
| Test an idea quickly | Use [Quick-Flow](quick-flow-workflows.md) for rapid prototyping |
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Game Types Guide](game-types.md)
|
||||
- [Quick-Flow Guide](quick-flow-workflows.md)
|
||||
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
title: "Quick Flow Workflows"
|
||||
---
|
||||
|
||||
How to create tech specs and execute implementations with Quick Flow.
|
||||
|
||||
## Choosing a Workflow
|
||||
|
||||
| Situation | Workflow | Command |
|
||||
|-----------|----------|---------|
|
||||
| Need to document before implementing | Quick-Spec | `/bmad-gds-quick-spec` |
|
||||
| Multiple approaches to evaluate | Quick-Spec | `/bmad-gds-quick-spec` |
|
||||
| Have a completed tech-spec | Quick-Dev | `/bmad-gds-quick-dev path/to/spec.md` |
|
||||
| Have clear, direct instructions | Quick-Dev | `/bmad-gds-quick-dev` |
|
||||
| Building complete game system | Full GDS | `/bmad-gds-workflow-init` |
|
||||
| Epic-level features | Full GDS | `/bmad-gds-workflow-init` |
|
||||
|
||||
---
|
||||
|
||||
## How to Create a Tech Spec (Quick-Spec)
|
||||
|
||||
### Step 1: Start the workflow
|
||||
|
||||
```bash
|
||||
/bmad-gds-quick-spec
|
||||
```
|
||||
|
||||
### Step 2: Describe your requirement
|
||||
|
||||
Provide your feature request. The agent scans the codebase and asks clarifying questions.
|
||||
|
||||
**Checkpoint options:**
|
||||
- `[a]` Advanced Elicitation - explore requirements deeper
|
||||
- `[c]` Continue to investigation
|
||||
- `[p]` Party Mode - consult expert agents
|
||||
|
||||
### Step 3: Review investigation findings
|
||||
|
||||
The agent analyzes the codebase for patterns, constraints, and similar implementations. Review the findings.
|
||||
|
||||
**Checkpoint options:**
|
||||
- `[c]` Continue to spec generation
|
||||
- `[p]` Party Mode - get technical review
|
||||
|
||||
### Step 4: Review generated spec
|
||||
|
||||
The agent creates an ordered task list with file paths and acceptance criteria. Verify completeness.
|
||||
|
||||
**Checkpoint options:**
|
||||
- `[c]` Continue to final review
|
||||
- `[p]` Party Mode - technical review
|
||||
|
||||
### Step 5: Finalize
|
||||
|
||||
Confirm the spec meets these standards:
|
||||
- Every task has a file path and specific action
|
||||
- Tasks ordered by dependency
|
||||
- Acceptance criteria in Given/When/Then format
|
||||
- No placeholders or TBD sections
|
||||
|
||||
**Options:**
|
||||
- `[d]` Start Quick-Dev immediately
|
||||
- `[done]` Save spec and exit
|
||||
|
||||
**Output:** `{planning_artifacts}/tech-spec-{slug}.md`
|
||||
|
||||
---
|
||||
|
||||
## How to Execute Implementation (Quick-Dev)
|
||||
|
||||
### With a Tech-Spec
|
||||
|
||||
```bash
|
||||
/bmad-gds-quick-dev path/to/tech-spec-feature.md
|
||||
```
|
||||
|
||||
The agent:
|
||||
1. Captures baseline git commit
|
||||
2. Loads and validates the spec
|
||||
3. Executes tasks in order
|
||||
4. Runs self-check
|
||||
5. Performs adversarial review
|
||||
6. Resolves findings
|
||||
7. Validates against acceptance criteria
|
||||
|
||||
### With Direct Instructions
|
||||
|
||||
```bash
|
||||
/bmad-gds-quick-dev
|
||||
```
|
||||
|
||||
Then describe what you want implemented:
|
||||
1. Captures baseline git commit
|
||||
2. Evaluates complexity (may suggest planning)
|
||||
3. Gathers context from codebase
|
||||
4. Executes implementation
|
||||
5. Runs self-check and adversarial review
|
||||
6. Resolves findings
|
||||
|
||||
**Escalation:** If the agent detects complexity (multiple components, system-level scope, uncertainty), it offers:
|
||||
- `[t]` Create tech-spec first
|
||||
- `[w]` Use full GDS workflow
|
||||
- `[e]` Execute anyway
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Spec has placeholders or TBD sections
|
||||
|
||||
Return to investigation step. Complete missing research, inline all findings, re-run review.
|
||||
|
||||
### Workflow lost context mid-step
|
||||
|
||||
Check frontmatter for `stepsCompleted`. Resume from last completed step.
|
||||
|
||||
### Agent suggested planning but you want to execute
|
||||
|
||||
You can override with `[e]`, but document your assumptions. Escalation heuristics exist because planning saves time on complex tasks.
|
||||
|
||||
### Tests failing after implementation
|
||||
|
||||
Return to the resolve-findings step. Review failures, fix issues, ensure test expectations are correct, re-run full suite.
|
||||
|
||||
### Need help
|
||||
|
||||
```bash
|
||||
/bmad-help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reference
|
||||
|
||||
### File Locations
|
||||
|
||||
| File | Location |
|
||||
|------|----------|
|
||||
| Work in progress | `{implementation_artifacts}/tech-spec-wip.md` |
|
||||
| Completed specs | `{planning_artifacts}/tech-spec-{slug}.md` |
|
||||
| Archived specs | `{implementation_artifacts}/tech-spec-{slug}-archived-{date}.md` |
|
||||
| Workflow files | `_bmad/gds/workflows/gds-quick-flow/` |
|
||||
|
||||
### Validation Criteria
|
||||
|
||||
**Self-check (before adversarial review):**
|
||||
- All tasks/instructions completed
|
||||
- Tests written and passing
|
||||
- Follows existing patterns
|
||||
- No obvious bugs
|
||||
- Acceptance criteria met
|
||||
- Code is readable
|
||||
|
||||
**Adversarial review:**
|
||||
- Correctness
|
||||
- Security
|
||||
- Performance
|
||||
- Maintainability
|
||||
- Test coverage
|
||||
- Error handling
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
|
|
@ -58,7 +58,7 @@ Build it, one story at a time.
|
|||
| `correct-course` | Handle significant mid-sprint changes | Updated plan or re-routing |
|
||||
| `retrospective` | Review after epic completion | Lessons learned |
|
||||
|
||||
**Quinn (QA Agent):** Built-in QA agent for test automation. Trigger with `QA` or `bmad-bmm-automate`. Generates standard API and E2E tests using your project's test framework. Beginner-friendly, no configuration needed. For advanced test strategy, install [Test Architect (TEA)](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/) module.
|
||||
**Quinn (QA Agent):** Built-in QA agent for test automation. Trigger with `QA` or `bmad-bmm-qa-automate`. Generates standard API and E2E tests using your project's test framework. Beginner-friendly, no configuration needed. For advanced test strategy, install [Test Architect (TEA)](https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/) module.
|
||||
|
||||
## Quick Flow (Parallel Track)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,11 @@ The installer creates two folders:
|
|||
- `_bmad/` — agents, workflows, tasks, and configuration
|
||||
- `_bmad-output/` — empty for now, but this is where your artifacts will be saved
|
||||
|
||||
Open your AI IDE in the project folder. Run the `help` workflow (`/bmad-help` on most platforms) to see what to do next — it detects what you've completed and recommends the next step.
|
||||
Open your AI IDE in the project folder. Run the `help` workflow (`/bmad-help`) to see what to do next — it detects what you've completed and recommends the next step.
|
||||
|
||||
:::note[How to Load Agents and Run Workflows]
|
||||
Each workflow has a **slash command** you run in your IDE (e.g., `/bmad-bmm-create-prd`). Running a workflow command automatically loads the appropriate agent — you don't need to load agents separately. You can also load an agent directly for general conversation (e.g., `/bmad-agent-bmm-pm` for the PM agent).
|
||||
:::
|
||||
|
||||
:::caution[Fresh Chats]
|
||||
Always start a fresh chat for each workflow. This prevents context limitations from causing issues.
|
||||
|
|
@ -78,29 +82,29 @@ Work through phases 1-3. **Use fresh chats for each workflow.**
|
|||
### Phase 1: Analysis (Optional)
|
||||
|
||||
All workflows in this phase are optional:
|
||||
- **brainstorming** — Guided ideation
|
||||
- **research** — Market and technical research
|
||||
- **create-product-brief** — Recommended foundation document
|
||||
- **brainstorming** (`/bmad-brainstorming`) — Guided ideation
|
||||
- **research** (`/bmad-bmm-research`) — Market and technical research
|
||||
- **create-product-brief** (`/bmad-bmm-create-product-brief`) — Recommended foundation document
|
||||
|
||||
### Phase 2: Planning (Required)
|
||||
|
||||
**For BMad Method and Enterprise tracks:**
|
||||
1. Load the **PM agent** in a new chat
|
||||
2. Run the `prd` workflow
|
||||
1. Load the **PM agent** (`/bmad-agent-bmm-pm`) in a new chat
|
||||
2. Run the `prd` workflow (`/bmad-bmm-create-prd`)
|
||||
3. Output: `PRD.md`
|
||||
|
||||
**For Quick Flow track:**
|
||||
- Use the `quick-spec` workflow instead of PRD, then skip to implementation
|
||||
- Use the `quick-spec` workflow (`/bmad-bmm-quick-spec`) instead of PRD, then skip to implementation
|
||||
|
||||
:::note[UX Design (Optional)]
|
||||
If your project has a user interface, load the **UX-Designer agent** and run the UX design workflow after creating your PRD.
|
||||
If your project has a user interface, load the **UX-Designer agent** (`/bmad-agent-bmm-ux-designer`) and run the UX design workflow (`/bmad-bmm-create-ux-design`) after creating your PRD.
|
||||
:::
|
||||
|
||||
### Phase 3: Solutioning (BMad Method/Enterprise)
|
||||
|
||||
**Create Architecture**
|
||||
1. Load the **Architect agent** in a new chat
|
||||
2. Run `create-architecture`
|
||||
1. Load the **Architect agent** (`/bmad-agent-bmm-architect`) in a new chat
|
||||
2. Run `create-architecture` (`/bmad-bmm-create-architecture`)
|
||||
3. Output: Architecture document with technical decisions
|
||||
|
||||
**Create Epics and Stories**
|
||||
|
|
@ -109,13 +113,13 @@ If your project has a user interface, load the **UX-Designer agent** and run the
|
|||
Epics and stories are now created *after* architecture. This produces better quality stories because architecture decisions (database, API patterns, tech stack) directly affect how work should be broken down.
|
||||
:::
|
||||
|
||||
1. Load the **PM agent** in a new chat
|
||||
2. Run `create-epics-and-stories`
|
||||
1. Load the **PM agent** (`/bmad-agent-bmm-pm`) in a new chat
|
||||
2. Run `create-epics-and-stories` (`/bmad-bmm-create-epics-and-stories`)
|
||||
3. The workflow uses both PRD and Architecture to create technically-informed stories
|
||||
|
||||
**Implementation Readiness Check** *(Highly Recommended)*
|
||||
1. Load the **Architect agent** in a new chat
|
||||
2. Run `check-implementation-readiness`
|
||||
1. Load the **Architect agent** (`/bmad-agent-bmm-architect`) in a new chat
|
||||
2. Run `check-implementation-readiness` (`/bmad-bmm-check-implementation-readiness`)
|
||||
3. Validates cohesion across all planning documents
|
||||
|
||||
## Step 2: Build Your Project
|
||||
|
|
@ -124,19 +128,19 @@ Once planning is complete, move to implementation. **Each workflow should run in
|
|||
|
||||
### Initialize Sprint Planning
|
||||
|
||||
Load the **SM agent** and run `sprint-planning`. This creates `sprint-status.yaml` to track all epics and stories.
|
||||
Load the **SM agent** (`/bmad-agent-bmm-sm`) and run `sprint-planning` (`/bmad-bmm-sprint-planning`). This creates `sprint-status.yaml` to track all epics and stories.
|
||||
|
||||
### The Build Cycle
|
||||
|
||||
For each story, repeat this cycle with fresh chats:
|
||||
|
||||
| Step | Agent | Workflow | Purpose |
|
||||
| ---- | ----- | -------------- | ---------------------------------- |
|
||||
| 1 | SM | `create-story` | Create story file from epic |
|
||||
| 2 | DEV | `dev-story` | Implement the story |
|
||||
| 3 | DEV | `code-review` | Quality validation *(recommended)* |
|
||||
| Step | Agent | Workflow | Command | Purpose |
|
||||
| ---- | ----- | -------------- | -------------------------- | ---------------------------------- |
|
||||
| 1 | SM | `create-story` | `/bmad-bmm-create-story` | Create story file from epic |
|
||||
| 2 | DEV | `dev-story` | `/bmad-bmm-dev-story` | Implement the story |
|
||||
| 3 | DEV | `code-review` | `/bmad-bmm-code-review` | Quality validation *(recommended)* |
|
||||
|
||||
After completing all stories in an epic, load the **SM agent** and run `retrospective`.
|
||||
After completing all stories in an epic, load the **SM agent** (`/bmad-agent-bmm-sm`) and run `retrospective` (`/bmad-bmm-retrospective`).
|
||||
|
||||
## What You've Accomplished
|
||||
|
||||
|
|
@ -162,17 +166,17 @@ your-project/
|
|||
|
||||
## Quick Reference
|
||||
|
||||
| Workflow | Agent | Purpose |
|
||||
| -------------------------------- | --------- | ------------------------------------ |
|
||||
| `help` | Any | Get guidance on what to do next |
|
||||
| `prd` | PM | Create Product Requirements Document |
|
||||
| `create-architecture` | Architect | Create architecture document |
|
||||
| `create-epics-and-stories` | PM | Break down PRD into epics |
|
||||
| `check-implementation-readiness` | Architect | Validate planning cohesion |
|
||||
| `sprint-planning` | SM | Initialize sprint tracking |
|
||||
| `create-story` | SM | Create a story file |
|
||||
| `dev-story` | DEV | Implement a story |
|
||||
| `code-review` | DEV | Review implemented code |
|
||||
| Workflow | Command | Agent | Purpose |
|
||||
| -------------------------------- | ------------------------------------------ | --------- | ------------------------------------ |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `create-story` | `/bmad-bmm-create-story` | SM | Create a story file |
|
||||
| `dev-story` | `/bmad-bmm-dev-story` | DEV | Implement a story |
|
||||
| `code-review` | `/bmad-bmm-code-review` | DEV | Review implemented code |
|
||||
|
||||
## Common Questions
|
||||
|
||||
|
|
@ -180,10 +184,10 @@ your-project/
|
|||
Only for BMad Method and Enterprise tracks. Quick Flow skips from tech-spec to implementation.
|
||||
|
||||
**Can I change my plan later?**
|
||||
Yes. The SM agent has a `correct-course` workflow for handling scope changes.
|
||||
Yes. The SM agent has a `correct-course` workflow (`/bmad-bmm-correct-course`) for handling scope changes.
|
||||
|
||||
**What if I want to brainstorm first?**
|
||||
Load the Analyst agent and run `brainstorming` before starting your PRD.
|
||||
Load the Analyst agent (`/bmad-agent-bmm-analyst`) and run `brainstorming` (`/bmad-brainstorming`) before starting your PRD.
|
||||
|
||||
**Do I need to follow a strict order?**
|
||||
Not strictly. Once you learn the flow, you can run workflows directly using the Quick Reference above.
|
||||
|
|
@ -192,14 +196,14 @@ Not strictly. Once you learn the flow, you can run workflows directly using the
|
|||
|
||||
- **During workflows** — Agents guide you with questions and explanations
|
||||
- **Community** — [Discord](https://discord.gg/gk8jAdXWmj) (#bmad-method-help, #report-bugs-and-issues)
|
||||
- **Stuck?** — Run `help` to see what to do next
|
||||
- **Stuck?** — Run `help` (`/bmad-help`) to see what to do next
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
:::tip[Remember These]
|
||||
- **Always use fresh chats** — Start a new chat for each workflow
|
||||
- **Track matters** — Quick Flow uses quick-spec; Method/Enterprise need PRD and architecture
|
||||
- **Use `help` when stuck** — It detects your progress and suggests next steps
|
||||
- **Use `help` (`/bmad-help`) when stuck** — It detects your progress and suggests next steps
|
||||
:::
|
||||
|
||||
Ready to start? Install BMad and let the agents guide you through your first project.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "bmad-method",
|
||||
"version": "6.0.0-Beta.4",
|
||||
"version": "6.0.0-Beta.5",
|
||||
"description": "Breakthrough Method of Agile AI-driven Development",
|
||||
"keywords": [
|
||||
"agile",
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
"lint": "eslint . --ext .js,.cjs,.mjs,.yaml --max-warnings=0",
|
||||
"lint:fix": "eslint . --ext .js,.cjs,.mjs,.yaml --fix",
|
||||
"lint:md": "markdownlint-cli2 \"**/*.md\"",
|
||||
"prepare": "husky",
|
||||
"prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0",
|
||||
"rebundle": "node tools/cli/bundlers/bundle-web.js rebundle",
|
||||
"release:major": "gh workflow run \"Manual Release\" -f version_bump=major",
|
||||
"release:minor": "gh workflow run \"Manual Release\" -f version_bump=minor",
|
||||
|
|
@ -49,6 +49,7 @@
|
|||
"test:coverage": "c8 --reporter=text --reporter=html npm run test:schemas",
|
||||
"test:install": "node test/test-installation-components.js",
|
||||
"test:schemas": "node test/test-agent-schema.js",
|
||||
"validate:refs": "node tools/validate-file-refs.js",
|
||||
"validate:schemas": "node tools/validate-agent-schema.js"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
|
@ -68,7 +69,8 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"@clack/core": "^1.0.0",
|
||||
"@clack/prompts": "^1.0.0",
|
||||
"@kayvan/markdown-tree-parser": "^1.6.1",
|
||||
"boxen": "^5.1.2",
|
||||
"chalk": "^4.1.2",
|
||||
|
|
@ -81,6 +83,7 @@
|
|||
"ignore": "^7.0.5",
|
||||
"js-yaml": "^4.1.0",
|
||||
"ora": "^5.4.1",
|
||||
"picocolors": "^1.1.1",
|
||||
"semver": "^7.6.3",
|
||||
"wrap-ansi": "^7.0.0",
|
||||
"xml2js": "^0.6.2",
|
||||
|
|
@ -88,7 +91,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/sitemap": "^3.6.0",
|
||||
"@astrojs/starlight": "^0.37.0",
|
||||
"@astrojs/starlight": "^0.37.5",
|
||||
"@eslint/js": "^9.33.0",
|
||||
"archiver": "^7.0.1",
|
||||
"astro": "^5.16.0",
|
||||
|
|
@ -99,7 +102,7 @@
|
|||
"eslint-plugin-unicorn": "^60.0.0",
|
||||
"eslint-plugin-yml": "^1.18.0",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^30.0.4",
|
||||
"jest": "^30.2.0",
|
||||
"lint-staged": "^16.1.1",
|
||||
"markdownlint-cli2": "^0.19.1",
|
||||
"prettier": "^3.7.4",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
agent:
|
||||
metadata:
|
||||
id: "_bmad/bmm/agents/quinn"
|
||||
id: "_bmad/bmm/agents/qa"
|
||||
name: Quinn
|
||||
title: QA Engineer
|
||||
icon: 🧪
|
||||
|
|
@ -27,7 +27,7 @@ agent:
|
|||
- Focus on realistic user scenarios
|
||||
|
||||
menu:
|
||||
- trigger: QA
|
||||
- trigger: qa
|
||||
workflow: "{project-root}/_bmad/bmm/workflows/qa/automate/workflow.yaml"
|
||||
description: "[QA] Automate - Generate tests for existing features (simplified)"
|
||||
|
||||
|
|
@ -54,4 +54,4 @@ agent:
|
|||
For comprehensive test strategy, risk-based planning, quality gates, and enterprise features,
|
||||
install the Test Architect (TEA) module: https://bmad-code-org.github.io/bmad-method-test-architecture-enterprise/
|
||||
|
||||
Ready to generate some tests? Just say `QA` or `bmad-bmm-automate`!
|
||||
Ready to generate some tests? Just say `QA` or `bmad-bmm-qa-automate`!
|
||||
|
|
@ -16,12 +16,11 @@ agent:
|
|||
principles: |
|
||||
- Planning and execution are two sides of the same coin.
|
||||
- Specs are for building, not bureaucracy. Code that ships is better than perfect code that doesn't.
|
||||
- If `**/project-context.md` exists, follow it. If absent, proceed without.
|
||||
|
||||
menu:
|
||||
- trigger: TS or fuzzy match on tech-spec
|
||||
- trigger: QS or fuzzy match on quick-spec
|
||||
exec: "{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md"
|
||||
description: "[TS] Tech Spec: Architect a quick but complete technical spec with implementation-ready stories/specs"
|
||||
description: "[QS] Quick Spec: Architect a quick but complete technical spec with implementation-ready stories/specs"
|
||||
|
||||
- trigger: QD or fuzzy match on quick-dev
|
||||
workflow: "{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ agent:
|
|||
title: Technical Writer
|
||||
icon: 📚
|
||||
module: bmm
|
||||
hasSidecar: false
|
||||
hasSidecar: true
|
||||
|
||||
persona:
|
||||
role: Technical Documentation Specialist + Knowledge Curator
|
||||
|
|
@ -28,9 +28,9 @@ agent:
|
|||
action: "Engage in multi-turn conversation until you fully understand the ask, use subprocess if available for any web search, research or document review required to extract and return only relevant info to parent context. Author final document following all `_bmad/_memory/tech-writer-sidecar/documentation-standards.md`. After draft, use a subprocess to review and revise for quality of content and ensure standards are still met."
|
||||
description: "[WD] Write Document: Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory."
|
||||
|
||||
- trigger: WD or fuzzy match on write-document
|
||||
- trigger: US or fuzzy match on update-standards
|
||||
action: "Update `_bmad/_memory/tech-writer-sidecar/documentation-standards.md` adding user preferences to User Specified CRITICAL Rules section. Remove any contradictory rules as needed. Share with user the updates made."
|
||||
description: "[US]: Update Standards: Agent Memory records your specific preferences if you discover missing document conventions."
|
||||
description: "[US] Update Standards: Agent Memory records your specific preferences if you discover missing document conventions."
|
||||
|
||||
- trigger: MG or fuzzy match on mermaid-gen
|
||||
action: "Create a Mermaid diagram based on user description multi-turn user conversation until the complete details are understood to produce the requested artifact. If not specified, suggest diagram types based on ask. Strictly follow Mermaid syntax and CommonMark fenced code block standards."
|
||||
|
|
|
|||
|
|
@ -1,22 +1,28 @@
|
|||
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs,
|
||||
bmm,anytime,Document Project,DP,10,_bmad/bmm/workflows/document-project/workflow.yaml,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*,
|
||||
bmm,anytime,Quick Spec,TS,20,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps utilities without extensive planning",planning_artifacts,"tech spec",
|
||||
bmm,anytime,Quick Dev,QD,30,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,,
|
||||
bmm,anytime,Correct Course,CC,40,_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
|
||||
bmm,anytime,Document Project,DP,,_bmad/bmm/workflows/document-project/workflow.yaml,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*,
|
||||
bmm,anytime,Generate Project Context,GPC,,_bmad/bmm/workflows/generate-project-context/workflow.md,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context",
|
||||
bmm,anytime,Quick Spec,QS,,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps brownfield additions to well established patterns utilities without extensive planning",planning_artifacts,"tech spec",
|
||||
bmm,anytime,Quick Dev,QD,,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,,
|
||||
bmm,anytime,Correct Course,CC,,_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
|
||||
bmm,anytime,Create Dataflow,CDF,,_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml,bmad-bmm-create-excalidraw-dataflow,false,ux-designer,Create Mode,"Create data flow diagrams (DFD) in Excalidraw format - can be called standalone or during any workflow to add visual documentation",planning_artifacts,"dataflow diagram",
|
||||
bmm,anytime,Create Diagram,CED,,_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml,bmad-bmm-create-excalidraw-diagram,false,ux-designer,Create Mode,"Create system architecture diagrams ERDs UML diagrams or general technical diagrams in Excalidraw format - use anytime or call from architecture workflow to add visual documentation",planning_artifacts,"diagram",
|
||||
bmm,anytime,Create Flowchart,CFC,,_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml,bmad-bmm-create-excalidraw-flowchart,false,ux-designer,Create Mode,"Create a flowchart visualization in Excalidraw format for processes pipelines or logic flows - use anytime or during architecture to add process documentation",planning_artifacts,"flowchart",
|
||||
bmm,anytime,Create Wireframe,CEW,,_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml,bmad-bmm-create-excalidraw-wireframe,false,ux-designer,Create Mode,"Create website or app wireframes in Excalidraw format - use anytime standalone or call from UX workflow to add UI mockups",planning_artifacts,"wireframe",
|
||||
bmm,anytime,Write Document,WD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,bmad-bmm-write-document,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document",
|
||||
bmm,anytime,Update Standards,US,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,bmad-bmm-update-standards,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards",
|
||||
bmm,anytime,Mermaid Generate,MG,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,bmad-bmm-mermaid-generate,false,tech-writer,,"Create a Mermaid diagram based on user description. Will suggest diagram types if not specified.",planning_artifacts,"mermaid diagram",
|
||||
bmm,anytime,Validate Document,VD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,bmad-bmm-validate-document,false,tech-writer,,"Review the specified document against documentation standards and best practices. Returns specific actionable improvement suggestions organized by priority.",planning_artifacts,"validation report",
|
||||
bmm,anytime,Explain Concept,EC,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,bmad-bmm-explain-concept,false,tech-writer,,"Create clear technical explanations with examples and diagrams for complex concepts. Breaks down into digestible sections using task-oriented approach.",project_knowledge,"explanation",
|
||||
bmm,1-analysis,Brainstorm Project,BP,10,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,data=_bmad/bmm/data/project-context-template.md,"Expert Guided Facilitation through a single or multiple techniques",planning_artifacts,"brainstorming session",
|
||||
bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=market,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents"
|
||||
bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=domain,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project-knowledge","research documents"
|
||||
bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=technical,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project-knowledge","research documents"
|
||||
bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=market,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents",
|
||||
bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=domain,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project_knowledge","research documents",
|
||||
bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow.md,bmad-bmm-research,false,analyst,Create Mode research_type=technical,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project_knowledge","research documents",
|
||||
bmm,1-analysis,Create Brief,CB,30,_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md,bmad-bmm-create-brief,false,analyst,Create Mode,"A guided experience to nail down your product idea",planning_artifacts,"product brief",
|
||||
bmm,1-analysis,Validate Brief,VB,40,_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md,bmad-bmm-validate-brief,false,analyst,Validate Mode,"Validates product brief completeness",planning_artifacts,"brief validation report",
|
||||
bmm,2-planning,Create PRD,CP,10,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-prd,true,pm,Create Mode,"Expert led facilitation to produce your Product Requirements Document",planning_artifacts,prd,
|
||||
bmm,2-planning,Validate PRD,VP,20,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-prd,false,pm,Validate Mode,"Validate PRD is comprehensive lean well organized and cohesive",planning_artifacts,"prd validation report",
|
||||
bmm,2-planning,Create PRD,CP,10,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-create-prd,true,pm,Create Mode,"Expert led facilitation to produce your Product Requirements Document",planning_artifacts,prd,
|
||||
bmm,2-planning,Validate PRD,VP,20,_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md,bmad-bmm-validate-prd,false,pm,Validate Mode,"Validate PRD is comprehensive lean well organized and cohesive",planning_artifacts,"prd validation report",
|
||||
bmm,2-planning,Create UX,CU,30,_bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md,bmad-bmm-create-ux-design,false,ux-designer,Create Mode,"Guidance through realizing the plan for your UX, strongly recommended if a UI is a primary piece of the proposed project",planning_artifacts,"ux design",
|
||||
bmm,2-planning,Validate UX,VU,40,_bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md,bmad-bmm-create-ux-design,false,ux-designer,Validate Mode,"Validates UX design deliverables",planning_artifacts,"ux validation report",
|
||||
,anytime,Create Dataflow,CDF,50,_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml,bmad-bmm-create-excalidraw-dataflow,false,ux-designer,Create Mode,"Create data flow diagrams (DFD) in Excalidraw format - can be called standalone or during any workflow to add visual documentation",planning_artifacts,"dataflow diagram",
|
||||
,anytime,Create Diagram,CED,51,_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml,bmad-bmm-create-excalidraw-diagram,false,ux-designer,Create Mode,"Create system architecture diagrams ERDs UML diagrams or general technical diagrams in Excalidraw format - use anytime or call from architecture workflow to add visual documentation",planning_artifacts,"diagram",
|
||||
,anytime,Create Flowchart,CFC,52,_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml,bmad-bmm-create-excalidraw-flowchart,false,ux-designer,Create Mode,"Create a flowchart visualization in Excalidraw format for processes pipelines or logic flows - use anytime or during architecture to add process documentation",planning_artifacts,"flowchart",
|
||||
,anytime,Create Wireframe,CEW,53,_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml,bmad-bmm-create-excalidraw-wireframe,false,ux-designer,Create Mode,"Create website or app wireframes in Excalidraw format - use anytime standalone or call from UX workflow to add UI mockups",planning_artifacts,"wireframe",
|
||||
bmm,3-solutioning,Create Architecture,CA,10,_bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md,bmad-bmm-create-architecture,true,architect,Create Mode,"Guided Workflow to document technical decisions",planning_artifacts,architecture,
|
||||
bmm,3-solutioning,Validate Architecture,VA,20,_bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md,bmad-bmm-create-architecture,false,architect,Validate Mode,"Validates architecture completeness",planning_artifacts,"architecture validation report",
|
||||
bmm,3-solutioning,Create Epics and Stories,CE,30,_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md,bmad-bmm-create-epics-and-stories,true,pm,Create Mode,"Create the Epics and Stories Listing",planning_artifacts,"epics and stories",
|
||||
|
|
@ -24,9 +30,9 @@ bmm,3-solutioning,Validate Epics and Stories,VE,40,_bmad/bmm/workflows/3-solutio
|
|||
bmm,3-solutioning,Check Implementation Readiness,IR,70,_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md,bmad-bmm-check-implementation-readiness,true,architect,Validate Mode,"Ensure PRD UX Architecture and Epics Stories are aligned",planning_artifacts,"readiness report",
|
||||
bmm,4-implementation,Sprint Planning,SP,10,_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml,bmad-bmm-sprint-planning,true,sm,Create Mode,"Generate sprint plan for development tasks - this kicks off the implementation phase by producing a plan the implementation agents will follow in sequence for every story in the plan.",implementation_artifacts,"sprint status",
|
||||
bmm,4-implementation,Sprint Status,SS,20,_bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml,bmad-bmm-sprint-status,false,sm,Create Mode,"Anytime: Summarize sprint status and route to next workflow",,,
|
||||
bmm,4-implementation,Create Story,CS,30,_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml,bmad-bmm-create-story,true,sm,Create Mode,"Story cycle start: Prepare first found story in the sprint plan that is next, or if the command is run with a specific epic and story designation with context. Once complete, then VS then DS then CR then back to DS if needed or next CS or ER",implementation_artifacts,story,
|
||||
bmm,4-implementation,Validate Story,VS,35,_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml,bmad-bmm-create-story,false,sm,Validate Mode,"Validates story readiness and completeness before development work begins",implementation_artifacts,"story validation report",
|
||||
bmm,4-implementation,Create Story,CS,30,_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml,bmad-bmm-create-story,true,sm,Create Mode,"Story cycle start: Prepare first found story in the sprint plan that is next, or if the command is run with a specific epic and story designation with context. Once complete, then VS then DS then CR then back to DS if needed or next CS or ER",implementation_artifacts,story,
|
||||
bmm,4-implementation,Dev Story,DS,40,_bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml,bmad-bmm-dev-story,true,dev,Create Mode,"Story cycle: Execute story implementation tasks and tests then CR then back to DS if fixes needed",,,
|
||||
bmm,4-implementation,Code Review,CR,50,_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml,bmad-bmm-code-review,false,dev,Create Mode,"Story cycle: If issues back to DS if approved then next CS or ER if epic complete",,,
|
||||
bmm,4-implementation,QA Automation Test,QA,45,_bmad/bmm/workflows/qa/automate/workflow.yaml,bmad-bmm-qa-automate,false,qa,Create Mode,"Generate automated API and E2E tests for implemented code using the project's existing test framework (detects existing well known in use test frameworks). Use after implementation to add test coverage. NOT for code review or story validation - use CR for that.",implementation_artifacts,"test suite",
|
||||
bmm,4-implementation,Retrospective,ER,60,_bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml,bmad-bmm-retrospective,false,sm,Create Mode,"Optional at epic end: Review completed work lessons learned and next epic or if major issues consider CC",implementation_artifacts,retrospective,
|
||||
bmm,4-implementation,Automate,QA,45,_bmad/bmm/workflows/qa/automate/workflow.yaml,bmad-bmm-automate,false,quinn,Create Mode,"Generate automated API and E2E tests for implemented code using the project's existing test framework (detects Playwright, Jest, Vitest, etc). Use after implementation to add test coverage. NOT for code review or story validation - use CR for that.",implementation_artifacts,"test suite",
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 7.
|
|
|
@ -138,7 +138,7 @@ Show initial scope document and present continue option:
|
|||
|
||||
- Update frontmatter: `stepsCompleted: [1]`
|
||||
- Add confirmation note to document: "Scope confirmed by user on {{date}}"
|
||||
- Load: `./step-02-customer-insights.md`
|
||||
- Load: `./step-02-customer-behavior.md`
|
||||
|
||||
#### If 'Modify':
|
||||
|
||||
|
|
|
|||
|
|
@ -1,200 +0,0 @@
|
|||
# Market Research Step 2: Customer Insights
|
||||
|
||||
## MANDATORY EXECUTION RULES (READ FIRST):
|
||||
|
||||
- 🛑 NEVER generate content without web search verification
|
||||
|
||||
- 📖 CRITICAL: ALWAYS read the complete step file before taking any action - partial understanding leads to incomplete decisions
|
||||
- 🔄 CRITICAL: When loading next step with 'C', ensure the entire file is read and understood before proceeding
|
||||
- ✅ Search the web to verify and supplement your knowledge with current facts
|
||||
- 📋 YOU ARE A CUSTOMER INSIGHTS ANALYST, not content generator
|
||||
- 💬 FOCUS on customer behavior and needs analysis
|
||||
- 🔍 WEB SEARCH REQUIRED - verify current facts against live sources
|
||||
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
|
||||
|
||||
## EXECUTION PROTOCOLS:
|
||||
|
||||
- 🎯 Show web search analysis before presenting findings
|
||||
- ⚠️ Present [C] continue option after customer insights content generation
|
||||
- 💾 ONLY save when user chooses C (Continue)
|
||||
- 📖 Update frontmatter `stepsCompleted: [1, 2]` before loading next step
|
||||
- 🚫 FORBIDDEN to load next step until C is selected
|
||||
|
||||
## CONTEXT BOUNDARIES:
|
||||
|
||||
- Current document and frontmatter from step-01 are available
|
||||
- Focus on customer behavior and needs analysis
|
||||
- Web search capabilities with source verification are enabled
|
||||
- May need to search for current customer behavior trends
|
||||
|
||||
## YOUR TASK:
|
||||
|
||||
Conduct comprehensive customer insights analysis with emphasis on behavior patterns and needs.
|
||||
|
||||
## CUSTOMER INSIGHTS SEQUENCE:
|
||||
|
||||
### 1. Begin Customer Insights Analysis
|
||||
|
||||
**UTILIZE SUBPROCESSES AND SUBAGENTS**: Use research subagents, subprocesses or parallel processing if available to thoroughly analyze different customer areas simultaneously and thoroughly
|
||||
|
||||
Start with customer research approach:
|
||||
"Now I'll conduct **customer insights analysis** to understand customer behavior and needs.
|
||||
|
||||
**Customer Insights Focus:**
|
||||
|
||||
- Customer behavior patterns and preferences
|
||||
- Pain points and challenges
|
||||
- Decision-making processes
|
||||
- Customer journey mapping
|
||||
- Customer satisfaction drivers
|
||||
- Demographic and psychographic profiles
|
||||
|
||||
**Let me search for current customer insights using parallel web searches for comprehensive coverage.**"
|
||||
|
||||
### 2. Parallel Customer Research Execution
|
||||
|
||||
**Execute multiple web searches simultaneously:**
|
||||
|
||||
Search the web: "[product/service/market] customer behavior patterns"
|
||||
Search the web: "[product/service/market] customer pain points challenges"
|
||||
Search the web: "[product/service/market] customer decision process"
|
||||
|
||||
**Analysis approach:**
|
||||
|
||||
- Look for customer behavior studies and surveys
|
||||
- Search for customer experience and interaction patterns
|
||||
- Research customer satisfaction methodologies
|
||||
- Note generational and cultural customer variations
|
||||
- Research customer pain points and frustrations
|
||||
- Analyze decision-making processes and criteria
|
||||
|
||||
### 3. Analyze and Aggregate Results
|
||||
|
||||
**Collect and analyze findings from all parallel searches:**
|
||||
|
||||
"After executing comprehensive parallel web searches, let me analyze and aggregate the customer insights:
|
||||
|
||||
**Research Coverage:**
|
||||
|
||||
- Customer behavior patterns and preferences
|
||||
- Pain points and challenges
|
||||
- Decision-making processes and journey mapping
|
||||
|
||||
**Cross-Customer Analysis:**
|
||||
[Identify patterns connecting behavior, pain points, and decisions]
|
||||
|
||||
**Quality Assessment:**
|
||||
[Overall confidence levels and research gaps identified]"
|
||||
|
||||
### 4. Generate Customer Insights Content
|
||||
|
||||
Prepare customer analysis with web search citations:
|
||||
|
||||
#### Content Structure:
|
||||
|
||||
When saving to document, append these Level 2 and Level 3 sections:
|
||||
|
||||
```markdown
|
||||
## Customer Insights
|
||||
|
||||
### Customer Behavior Patterns
|
||||
|
||||
[Customer behavior analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Pain Points and Challenges
|
||||
|
||||
[Pain points analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Decision-Making Processes
|
||||
|
||||
[Decision-making analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Customer Journey Mapping
|
||||
|
||||
[Customer journey analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Customer Satisfaction Drivers
|
||||
|
||||
[Satisfaction drivers analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Demographic Profiles
|
||||
|
||||
[Demographic profiles analysis with source citations]
|
||||
_Source: [URL]_
|
||||
|
||||
### Psychographic Profiles
|
||||
|
||||
[Psychographic profiles analysis with source citations]
|
||||
_Source: [URL]_
|
||||
```
|
||||
|
||||
### 5. Present Analysis and Continue Option
|
||||
|
||||
Show the generated customer insights and present continue option:
|
||||
"I've completed the **customer insights analysis** for customer behavior and needs.
|
||||
|
||||
**Key Customer Findings:**
|
||||
|
||||
- Customer behavior patterns clearly identified
|
||||
- Pain points and challenges thoroughly documented
|
||||
- Decision-making processes mapped
|
||||
- Customer journey insights captured
|
||||
- Satisfaction and profile data analyzed
|
||||
|
||||
**Ready to proceed to competitive analysis?**
|
||||
[C] Continue - Save this to the document and proceed to competitive analysis
|
||||
|
||||
### 6. Handle Continue Selection
|
||||
|
||||
#### If 'C' (Continue):
|
||||
|
||||
- Append the final content to the research document
|
||||
- Update frontmatter: `stepsCompleted: [1, 2]`
|
||||
- Load: `./step-05-competitive-analysis.md`
|
||||
|
||||
## APPEND TO DOCUMENT:
|
||||
|
||||
When user selects 'C', append the content directly to the research document using the structure from step 4.
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
✅ Customer behavior patterns identified with current citations
|
||||
✅ Pain points and challenges clearly documented
|
||||
✅ Decision-making processes thoroughly analyzed
|
||||
✅ Customer journey insights captured and mapped
|
||||
✅ Customer satisfaction drivers identified
|
||||
✅ [C] continue option presented and handled correctly
|
||||
✅ Content properly appended to document when C selected
|
||||
|
||||
## FAILURE MODES:
|
||||
|
||||
❌ Relying solely on training data without web verification for current facts
|
||||
|
||||
❌ Missing critical customer behavior patterns
|
||||
❌ Not identifying key pain points and challenges
|
||||
❌ Incomplete customer journey mapping
|
||||
❌ Not presenting [C] continue option after content generation
|
||||
❌ Appending content without user selecting 'C'
|
||||
|
||||
❌ **CRITICAL**: Reading only partial step file - leads to incomplete understanding and poor decisions
|
||||
❌ **CRITICAL**: Proceeding with 'C' without fully reading and understanding the next step file
|
||||
❌ **CRITICAL**: Making decisions without complete understanding of step requirements and protocols
|
||||
|
||||
## CUSTOMER RESEARCH PROTOCOLS:
|
||||
|
||||
- Search for customer behavior studies and surveys
|
||||
- Use market research firm and industry association sources
|
||||
- Research customer experience and interaction patterns
|
||||
- Note generational and cultural customer variations
|
||||
- Research customer satisfaction methodologies
|
||||
|
||||
## NEXT STEP:
|
||||
|
||||
After user selects 'C' and content is saved to document, load `./step-05-competitive-analysis.md` to focus on competitive landscape analysis.
|
||||
|
||||
Remember: Always emphasize current customer data and rigorous source verification!
|
||||
|
|
@ -9,5 +9,7 @@ scientific,"research,algorithm,simulation,modeling,computational,analysis,data s
|
|||
legaltech,"legal,law,contract,compliance,litigation,patent,attorney,court",high,"Legal ethics;Bar regulations;Data retention;Attorney-client privilege;Court system integration","Legal practice rules;Ethics requirements;Court filing systems;Document standards;Confidentiality","domain-research","legal technology ethics {date};law practice management software requirements;court filing system standards;attorney client privilege technology","ethics_compliance;data_retention;confidentiality_measures;court_integration"
|
||||
insuretech,"insurance,claims,underwriting,actuarial,policy,risk,premium",high,"Insurance regulations;Actuarial standards;Data privacy;Fraud detection;State compliance","Insurance regulations by state;Actuarial methods;Risk modeling;Claims processing;Regulatory reporting","domain-research","insurance software regulations {date};actuarial standards software;insurance fraud detection;state insurance compliance","regulatory_requirements;risk_modeling;fraud_detection;reporting_compliance"
|
||||
energy,"energy,utility,grid,solar,wind,power,electricity,oil,gas",high,"Grid compliance;NERC standards;Environmental regulations;Safety requirements;Real-time operations","Energy regulations;Grid standards;Environmental compliance;Safety protocols;SCADA systems","domain-research","energy sector software compliance {date};NERC CIP standards;smart grid requirements;renewable energy software standards","grid_compliance;safety_protocols;environmental_compliance;operational_requirements"
|
||||
process_control,"industrial automation,process control,PLC,SCADA,DCS,HMI,operational technology,OT,control system,cyberphysical,MES,historian,instrumentation,I&C,P&ID",high,"Functional safety;OT cybersecurity;Real-time control requirements;Legacy system integration;Process safety and hazard analysis;Environmental compliance and permitting;Engineering authority and PE requirements","Functional safety standards;OT security frameworks;Industrial protocols;Process control architecture;Plant reliability and maintainability","domain-research + technical-model","IEC 62443 OT cybersecurity requirements {date};functional safety software requirements {date};industrial process control architecture;ISA-95 manufacturing integration","functional_safety;ot_security;process_requirements;engineering_authority"
|
||||
building_automation,"building automation,BAS,BMS,HVAC,smart building,lighting control,fire alarm,fire protection,fire suppression,life safety,elevator,access control,DDC,energy management,sequence of operations,commissioning",high,"Life safety codes;Building energy standards;Multi-trade coordination and interoperability;Commissioning and ongoing operational performance;Indoor environmental quality and occupant comfort;Engineering authority and PE requirements","Building automation protocols;HVAC and mechanical controls;Fire alarm, fire protection, and life safety design;Commissioning process and sequence of operations;Building codes and energy standards","domain-research","smart building software architecture {date};BACnet integration best practices;building automation cybersecurity {date};ASHRAE building standards","life_safety;energy_compliance;commissioning_requirements;engineering_authority"
|
||||
gaming,"game,player,gameplay,level,character,multiplayer,quest",redirect,"REDIRECT TO GAME WORKFLOWS","Game design","game-brief","NA","NA"
|
||||
general,"",low,"Standard requirements;Basic security;User experience;Performance","General software practices","continue","software development best practices {date}","standard_requirements"
|
||||
|
|
|
@ -5,7 +5,7 @@ description: 'Optimize and polish the complete PRD document for flow, coherence,
|
|||
# File References
|
||||
nextStepFile: './step-12-complete.md'
|
||||
outputFile: '{planning_artifacts}/prd.md'
|
||||
purposeFile: './data/prd-purpose.md'
|
||||
purposeFile: '../data/prd-purpose.md'
|
||||
|
||||
# Task References
|
||||
advancedElicitationTask: '{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml'
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ description: 'Complete & Validate - Present options for next steps including ful
|
|||
|
||||
# File references (ONLY variables used in this step)
|
||||
prdFile: '{prd_file_path}'
|
||||
validationWorkflow: './steps-v/step-v-01-discovery.md'
|
||||
validationWorkflow: '../steps-v/step-v-01-discovery.md'
|
||||
---
|
||||
|
||||
# Step E-4: Complete & Validate
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ validationStatus: COMPLETE - PRODUCTION READY
|
|||
|
||||
# PRD Workflow Validation Report
|
||||
|
||||
**Workflow Being Validated:** /Users/brianmadison/dev/BMAD-METHOD/src/bmm/workflows/2-plan-workflows/create-prd
|
||||
**Workflow Being Validated:** _bmad/bmm/workflows/2-plan-workflows/create-prd
|
||||
**Validation Date:** 2026-01-08
|
||||
**Validator:** BMAD Workflow Validation System
|
||||
|
||||
|
|
@ -290,8 +290,8 @@ editWorkflow: './steps-e/step-e-01-discovery.md'
|
|||
- ✅ Proper workflow path configuration
|
||||
|
||||
**2. External Workflow References:**
|
||||
- ✅ Party-mode workflow: Exists at `/src/core/workflows/party-mode/workflow.md`
|
||||
- ✅ Advanced-elicitation task: Exists at `/src/core/workflows/advanced-elicitation/workflow.xml`
|
||||
- ✅ Party-mode workflow: Exists at `{project-root}/_bmad/core/workflows/party-mode/workflow.md`
|
||||
- ✅ Advanced-elicitation task: Exists at `{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml`
|
||||
|
||||
**3. Directory Structure:**
|
||||
- ✅ Complete step architecture (all 3 modes)
|
||||
|
|
|
|||
|
|
@ -8,4 +8,6 @@ productivity,"productivity,workflow,tasks,management,business,tools",medium,stan
|
|||
media,"content,media,video,audio,streaming,broadcast",high,advanced,"CDN architecture, video encoding, streaming protocols, content delivery"
|
||||
iot,"IoT,sensors,devices,embedded,smart,connected",high,advanced,"device communication, real-time data processing, edge computing, security"
|
||||
government,"government,civic,public,admin,policy,regulation",high,enhanced,"accessibility standards, security clearance, data privacy, audit trails"
|
||||
process_control,"industrial automation,process control,PLC,SCADA,DCS,HMI,operational technology,control system,cyberphysical,MES,instrumentation,I&C,P&ID",high,advanced,"industrial process control architecture, SCADA system design, OT cybersecurity architecture, real-time control systems"
|
||||
building_automation,"building automation,BAS,BMS,HVAC,smart building,fire alarm,fire protection,fire suppression,life safety,elevator,DDC,access control,sequence of operations,commissioning",high,advanced,"building automation architecture, BACnet integration patterns, smart building design, building management system security"
|
||||
gaming,"game,gaming,multiplayer,real-time,interactive,entertainment",high,advanced,"real-time multiplayer, game engine architecture, matchmaking, leaderboards"
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
project_name: '{{project_name}}'
|
||||
user_name: '{{user_name}}'
|
||||
date: '{{date}}'
|
||||
sections_completed: ['technology_stack']
|
||||
existing_patterns_found: { { number_of_patterns_discovered } }
|
||||
---
|
||||
|
||||
# Project Context for AI Agents
|
||||
|
||||
_This file contains critical rules and patterns that AI agents must follow when implementing code in this project. Focus on unobvious details that agents might otherwise miss._
|
||||
|
||||
---
|
||||
|
||||
## Technology Stack & Versions
|
||||
|
||||
_Documented after discovery phase_
|
||||
|
||||
## Critical Implementation Rules
|
||||
|
||||
_Documented after discovery phase_
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
# Step 1: Context Discovery & Initialization
|
||||
|
||||
## MANDATORY EXECUTION RULES (READ FIRST):
|
||||
|
||||
- 🛑 NEVER generate content without user input
|
||||
- ✅ ALWAYS treat this as collaborative discovery between technical peers
|
||||
- 📋 YOU ARE A FACILITATOR, not a content generator
|
||||
- 💬 FOCUS on discovering existing project context and technology stack
|
||||
- 🎯 IDENTIFY critical implementation rules that AI agents need
|
||||
- ⚠️ ABSOLUTELY NO TIME ESTIMATES - AI development speed has fundamentally changed
|
||||
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
|
||||
|
||||
## EXECUTION PROTOCOLS:
|
||||
|
||||
- 🎯 Show your analysis before taking any action
|
||||
- 📖 Read existing project files to understand current context
|
||||
- 💾 Initialize document and update frontmatter
|
||||
- 🚫 FORBIDDEN to load next step until discovery is complete
|
||||
|
||||
## CONTEXT BOUNDARIES:
|
||||
|
||||
- Variables from workflow.md are available in memory
|
||||
- Focus on existing project files and architecture decisions
|
||||
- Look for patterns, conventions, and unique requirements
|
||||
- Prioritize rules that prevent implementation mistakes
|
||||
|
||||
## YOUR TASK:
|
||||
|
||||
Discover the project's technology stack, existing patterns, and critical implementation rules that AI agents must follow when writing code.
|
||||
|
||||
## DISCOVERY SEQUENCE:
|
||||
|
||||
### 1. Check for Existing Project Context
|
||||
|
||||
First, check if project context already exists:
|
||||
|
||||
- Look for file at `{project_knowledge}/project-context.md or {project-root}/**/project-context.md`
|
||||
- If exists: Read complete file to understand existing rules
|
||||
- Present to user: "Found existing project context with {number_of_sections} sections. Would you like to update this or create a new one?"
|
||||
|
||||
### 2. Discover Project Technology Stack
|
||||
|
||||
Load and analyze project files to identify technologies:
|
||||
|
||||
**Architecture Document:**
|
||||
|
||||
- Look for `{planning_artifacts}/architecture.md`
|
||||
- Extract technology choices with specific versions
|
||||
- Note architectural decisions that affect implementation
|
||||
|
||||
**Package Files:**
|
||||
|
||||
- Check for `package.json`, `requirements.txt`, `Cargo.toml`, etc.
|
||||
- Extract exact versions of all dependencies
|
||||
- Note development vs production dependencies
|
||||
|
||||
**Configuration Files:**
|
||||
|
||||
- Look for project language specific configs ( example: `tsconfig.json`)
|
||||
- Build tool configs (webpack, vite, next.config.js, etc.)
|
||||
- Linting and formatting configs (.eslintrc, .prettierrc, etc.)
|
||||
- Testing configurations (jest.config.js, vitest.config.ts, etc.)
|
||||
|
||||
### 3. Identify Existing Code Patterns
|
||||
|
||||
Search through existing codebase for patterns:
|
||||
|
||||
**Naming Conventions:**
|
||||
|
||||
- File naming patterns (PascalCase, kebab-case, etc.)
|
||||
- Component/function naming conventions
|
||||
- Variable naming patterns
|
||||
- Test file naming patterns
|
||||
|
||||
**Code Organization:**
|
||||
|
||||
- How components are structured
|
||||
- Where utilities and helpers are placed
|
||||
- How services are organized
|
||||
- Test organization patterns
|
||||
|
||||
**Documentation Patterns:**
|
||||
|
||||
- Comment styles and conventions
|
||||
- Documentation requirements
|
||||
- README and API doc patterns
|
||||
|
||||
### 4. Extract Critical Implementation Rules
|
||||
|
||||
Look for rules that AI agents might miss:
|
||||
|
||||
**Language-Specific Rules:**
|
||||
|
||||
- TypeScript strict mode requirements
|
||||
- Import/export conventions
|
||||
- Async/await vs Promise usage patterns
|
||||
- Error handling patterns specific to the language
|
||||
|
||||
**Framework-Specific Rules:**
|
||||
|
||||
- React hooks usage patterns
|
||||
- API route conventions
|
||||
- Middleware usage patterns
|
||||
- State management patterns
|
||||
|
||||
**Testing Rules:**
|
||||
|
||||
- Test structure requirements
|
||||
- Mock usage conventions
|
||||
- Integration vs unit test boundaries
|
||||
- Coverage requirements
|
||||
|
||||
**Development Workflow Rules:**
|
||||
|
||||
- Branch naming conventions
|
||||
- Commit message patterns
|
||||
- PR review requirements
|
||||
- Deployment procedures
|
||||
|
||||
### 5. Initialize Project Context Document
|
||||
|
||||
Based on discovery, create or update the context document:
|
||||
|
||||
#### A. Fresh Document Setup (if no existing context)
|
||||
|
||||
Copy template from `{installed_path}/project-context-template.md` to `{output_folder}/project-context.md`
|
||||
Initialize frontmatter fields.
|
||||
|
||||
#### B. Existing Document Update
|
||||
|
||||
Load existing context and prepare for updates
|
||||
Set frontmatter `sections_completed` to track what will be updated
|
||||
|
||||
### 6. Present Discovery Summary
|
||||
|
||||
Report findings to user:
|
||||
|
||||
"Welcome {{user_name}}! I've analyzed your project for {{project_name}} to discover the context that AI agents need.
|
||||
|
||||
**Technology Stack Discovered:**
|
||||
{{list_of_technologies_with_versions}}
|
||||
|
||||
**Existing Patterns Found:**
|
||||
|
||||
- {{number_of_patterns}} implementation patterns
|
||||
- {{number_of_conventions}} coding conventions
|
||||
- {{number_of_rules}} critical rules
|
||||
|
||||
**Key Areas for Context Rules:**
|
||||
|
||||
- {{area_1}} (e.g., TypeScript configuration)
|
||||
- {{area_2}} (e.g., Testing patterns)
|
||||
- {{area_3}} (e.g., Code organization)
|
||||
|
||||
{if_existing_context}
|
||||
**Existing Context:** Found {{sections}} sections already defined. We can update or add to these.
|
||||
{/if_existing_context}
|
||||
|
||||
Ready to create/update your project context. This will help AI agents implement code consistently with your project's standards.
|
||||
|
||||
[C] Continue to context generation"
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
✅ Existing project context properly detected and handled
|
||||
✅ Technology stack accurately identified with versions
|
||||
✅ Critical implementation patterns discovered
|
||||
✅ Project context document properly initialized
|
||||
✅ Discovery findings clearly presented to user
|
||||
✅ User ready to proceed with context generation
|
||||
|
||||
## FAILURE MODES:
|
||||
|
||||
❌ Not checking for existing project context before creating new one
|
||||
❌ Missing critical technology versions or configurations
|
||||
❌ Overlooking important coding patterns or conventions
|
||||
❌ Not initializing frontmatter properly
|
||||
❌ Not presenting clear discovery summary to user
|
||||
|
||||
## NEXT STEP:
|
||||
|
||||
After user selects [C] to continue, load `./step-02-generate.md` to collaboratively generate the specific project context rules.
|
||||
|
||||
Remember: Do NOT proceed to step-02 until user explicitly selects [C] from the menu and discovery is confirmed and the initial file has been written as directed in this discovery step!
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
# Step 2: Context Rules Generation
|
||||
|
||||
## MANDATORY EXECUTION RULES (READ FIRST):
|
||||
|
||||
- 🛑 NEVER generate content without user input
|
||||
- ✅ ALWAYS treat this as collaborative discovery between technical peers
|
||||
- 📋 YOU ARE A FACILITATOR, not a content generator
|
||||
- 💬 FOCUS on unobvious rules that AI agents need to be reminded of
|
||||
- 🎯 KEEP CONTENT LEAN - optimize for LLM context efficiency
|
||||
- ⚠️ ABSOLUTELY NO TIME ESTIMATES - AI development speed has fundamentally changed
|
||||
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
|
||||
|
||||
## EXECUTION PROTOCOLS:
|
||||
|
||||
- 🎯 Show your analysis before taking any action
|
||||
- 📝 Focus on specific, actionable rules rather than general advice
|
||||
- ⚠️ Present A/P/C menu after each major rule category
|
||||
- 💾 ONLY save when user chooses C (Continue)
|
||||
- 📖 Update frontmatter with completed sections
|
||||
- 🚫 FORBIDDEN to load next step until all sections are complete
|
||||
|
||||
## COLLABORATION MENUS (A/P/C):
|
||||
|
||||
This step will generate content and present choices for each rule category:
|
||||
|
||||
- **A (Advanced Elicitation)**: Use discovery protocols to explore nuanced implementation rules
|
||||
- **P (Party Mode)**: Bring multiple perspectives to identify critical edge cases
|
||||
- **C (Continue)**: Save the current rules and proceed to next category
|
||||
|
||||
## PROTOCOL INTEGRATION:
|
||||
|
||||
- When 'A' selected: Execute {project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml
|
||||
- When 'P' selected: Execute {project-root}/_bmad/core/workflows/party-mode
|
||||
- PROTOCOLS always return to display this step's A/P/C menu after the A or P have completed
|
||||
- User accepts/rejects protocol changes before proceeding
|
||||
|
||||
## CONTEXT BOUNDARIES:
|
||||
|
||||
- Discovery results from step-1 are available
|
||||
- Technology stack and existing patterns are identified
|
||||
- Focus on rules that prevent implementation mistakes
|
||||
- Prioritize unobvious details that AI agents might miss
|
||||
|
||||
## YOUR TASK:
|
||||
|
||||
Collaboratively generate specific, critical rules that AI agents must follow when implementing code in this project.
|
||||
|
||||
## CONTEXT GENERATION SEQUENCE:
|
||||
|
||||
### 1. Technology Stack & Versions
|
||||
|
||||
Document the exact technology stack from discovery:
|
||||
|
||||
**Core Technologies:**
|
||||
Based on user skill level, present findings:
|
||||
|
||||
**Expert Mode:**
|
||||
"Technology stack from your architecture and package files:
|
||||
{{exact_technologies_with_versions}}
|
||||
|
||||
Any critical version constraints I should document for agents?"
|
||||
|
||||
**Intermediate Mode:**
|
||||
"I found your technology stack:
|
||||
|
||||
**Core Technologies:**
|
||||
{{main_technologies_with_versions}}
|
||||
|
||||
**Key Dependencies:**
|
||||
{{important_dependencies_with_versions}}
|
||||
|
||||
Are there any version constraints or compatibility notes agents should know about?"
|
||||
|
||||
**Beginner Mode:**
|
||||
"Here are the technologies you're using:
|
||||
|
||||
**Main Technologies:**
|
||||
{{friendly_description_of_tech_stack}}
|
||||
|
||||
**Important Notes:**
|
||||
{{key_things_agents_need_to_know_about_versions}}
|
||||
|
||||
Should I document any special version rules or compatibility requirements?"
|
||||
|
||||
### 2. Language-Specific Rules
|
||||
|
||||
Focus on unobvious language patterns agents might miss:
|
||||
|
||||
**TypeScript/JavaScript Rules:**
|
||||
"Based on your codebase, I notice some specific patterns:
|
||||
|
||||
**Configuration Requirements:**
|
||||
{{typescript_config_rules}}
|
||||
|
||||
**Import/Export Patterns:**
|
||||
{{import_export_conventions}}
|
||||
|
||||
**Error Handling Patterns:**
|
||||
{{error_handling_requirements}}
|
||||
|
||||
Are these patterns correct? Any other language-specific rules agents should follow?"
|
||||
|
||||
**Python/Ruby/Other Language Rules:**
|
||||
Adapt to the actual language in use with similar focused questions.
|
||||
|
||||
### 3. Framework-Specific Rules
|
||||
|
||||
Document framework-specific patterns:
|
||||
|
||||
**React Rules (if applicable):**
|
||||
"For React development, I see these patterns:
|
||||
|
||||
**Hooks Usage:**
|
||||
{{hooks_usage_patterns}}
|
||||
|
||||
**Component Structure:**
|
||||
{{component_organization_rules}}
|
||||
|
||||
**State Management:**
|
||||
{{state_management_patterns}}
|
||||
|
||||
**Performance Rules:**
|
||||
{{performance_optimization_requirements}}
|
||||
|
||||
Should I add any other React-specific rules?"
|
||||
|
||||
**Other Framework Rules:**
|
||||
Adapt for Vue, Angular, Next.js, Express, etc.
|
||||
|
||||
### 4. Testing Rules
|
||||
|
||||
Focus on testing patterns that ensure consistency:
|
||||
|
||||
**Test Structure Rules:**
|
||||
"Your testing setup shows these patterns:
|
||||
|
||||
**Test Organization:**
|
||||
{{test_file_organization}}
|
||||
|
||||
**Mock Usage:**
|
||||
{{mock_patterns_and_conventions}}
|
||||
|
||||
**Test Coverage Requirements:**
|
||||
{{coverage_expectations}}
|
||||
|
||||
**Integration vs Unit Test Rules:**
|
||||
{{test_boundary_patterns}}
|
||||
|
||||
Are there testing rules agents should always follow?"
|
||||
|
||||
### 5. Code Quality & Style Rules
|
||||
|
||||
Document critical style and quality rules:
|
||||
|
||||
**Linting/Formatting:**
|
||||
"Your code style configuration requires:
|
||||
|
||||
**ESLint/Prettier Rules:**
|
||||
{{specific_linting_rules}}
|
||||
|
||||
**Code Organization:**
|
||||
{{file_and_folder_structure_rules}}
|
||||
|
||||
**Naming Conventions:**
|
||||
{{naming_patterns_agents_must_follow}}
|
||||
|
||||
**Documentation Requirements:**
|
||||
{{comment_and_documentation_patterns}}
|
||||
|
||||
Any additional code quality rules?"
|
||||
|
||||
### 6. Development Workflow Rules
|
||||
|
||||
Document workflow patterns that affect implementation:
|
||||
|
||||
**Git/Repository Rules:**
|
||||
"Your project uses these patterns:
|
||||
|
||||
**Branch Naming:**
|
||||
{{branch_naming_conventions}}
|
||||
|
||||
**Commit Message Format:**
|
||||
{{commit_message_patterns}}
|
||||
|
||||
**PR Requirements:**
|
||||
{{pull_request_checklist}}
|
||||
|
||||
**Deployment Patterns:**
|
||||
{{deployment_considerations}}
|
||||
|
||||
Should I document any other workflow rules?"
|
||||
|
||||
### 7. Critical Don't-Miss Rules
|
||||
|
||||
Identify rules that prevent common mistakes:
|
||||
|
||||
**Anti-Patterns to Avoid:**
|
||||
"Based on your codebase, here are critical things agents must NOT do:
|
||||
|
||||
{{critical_anti_patterns_with_examples}}
|
||||
|
||||
**Edge Cases:**
|
||||
{{specific_edge_cases_agents_should_handle}}
|
||||
|
||||
**Security Rules:**
|
||||
{{security_considerations_agents_must_follow}}
|
||||
|
||||
**Performance Gotchas:**
|
||||
{{performance_patterns_to_avoid}}
|
||||
|
||||
Are there other 'gotchas' agents should know about?"
|
||||
|
||||
### 8. Generate Context Content
|
||||
|
||||
For each category, prepare lean content for the project context file:
|
||||
|
||||
#### Content Structure:
|
||||
|
||||
```markdown
|
||||
## Technology Stack & Versions
|
||||
|
||||
{{concise_technology_list_with_exact_versions}}
|
||||
|
||||
## Critical Implementation Rules
|
||||
|
||||
### Language-Specific Rules
|
||||
|
||||
{{bullet_points_of_critical_language_rules}}
|
||||
|
||||
### Framework-Specific Rules
|
||||
|
||||
{{bullet_points_of_framework_patterns}}
|
||||
|
||||
### Testing Rules
|
||||
|
||||
{{bullet_points_of_testing_requirements}}
|
||||
|
||||
### Code Quality & Style Rules
|
||||
|
||||
{{bullet_points_of_style_and_quality_rules}}
|
||||
|
||||
### Development Workflow Rules
|
||||
|
||||
{{bullet_points_of_workflow_patterns}}
|
||||
|
||||
### Critical Don't-Miss Rules
|
||||
|
||||
{{bullet_points_of_anti_patterns_and_edge_cases}}
|
||||
```
|
||||
|
||||
### 9. Present Content and Menu
|
||||
|
||||
After each category, show the generated rules and present choices:
|
||||
|
||||
"I've drafted the {{category_name}} rules for your project context.
|
||||
|
||||
**Here's what I'll add:**
|
||||
|
||||
[Show the complete markdown content for this category]
|
||||
|
||||
**What would you like to do?**
|
||||
[A] Advanced Elicitation - Explore nuanced rules for this category
|
||||
[P] Party Mode - Review from different implementation perspectives
|
||||
[C] Continue - Save these rules and move to next category"
|
||||
|
||||
### 10. Handle Menu Selection
|
||||
|
||||
#### If 'A' (Advanced Elicitation):
|
||||
|
||||
- Execute advanced-elicitation.xml with current category rules
|
||||
- Process enhanced rules that come back
|
||||
- Ask user: "Accept these enhanced rules for {{category}}? (y/n)"
|
||||
- If yes: Update content, then return to A/P/C menu
|
||||
- If no: Keep original content, then return to A/P/C menu
|
||||
|
||||
#### If 'P' (Party Mode):
|
||||
|
||||
- Execute party-mode workflow with category rules context
|
||||
- Process collaborative insights on implementation patterns
|
||||
- Ask user: "Accept these changes to {{category}} rules? (y/n)"
|
||||
- If yes: Update content, then return to A/P/C menu
|
||||
- If no: Keep original content, then return to A/P/C menu
|
||||
|
||||
#### If 'C' (Continue):
|
||||
|
||||
- Save the current category content to project context file
|
||||
- Update frontmatter: `sections_completed: [...]`
|
||||
- Proceed to next category or step-03 if complete
|
||||
|
||||
## APPEND TO PROJECT CONTEXT:
|
||||
|
||||
When user selects 'C' for a category, append the content directly to `{output_folder}/project-context.md` using the structure from step 8.
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
✅ All critical technology versions accurately documented
|
||||
✅ Language-specific rules cover unobvious patterns
|
||||
✅ Framework rules capture project-specific conventions
|
||||
✅ Testing rules ensure consistent test quality
|
||||
✅ Code quality rules maintain project standards
|
||||
✅ Workflow rules prevent implementation conflicts
|
||||
✅ Content is lean and optimized for LLM context
|
||||
✅ A/P/C menu presented and handled correctly for each category
|
||||
|
||||
## FAILURE MODES:
|
||||
|
||||
❌ Including obvious rules that agents already know
|
||||
❌ Making content too verbose for LLM context efficiency
|
||||
❌ Missing critical anti-patterns or edge cases
|
||||
❌ Not getting user validation for each rule category
|
||||
❌ Not documenting exact versions and configurations
|
||||
❌ Not presenting A/P/C menu after content generation
|
||||
|
||||
## NEXT STEP:
|
||||
|
||||
After completing all rule categories and user selects 'C' for the final category, load `./step-03-complete.md` to finalize the project context file.
|
||||
|
||||
Remember: Do NOT proceed to step-03 until all categories are complete and user explicitly selects 'C' for each!
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
# Step 3: Context Completion & Finalization
|
||||
|
||||
## MANDATORY EXECUTION RULES (READ FIRST):
|
||||
|
||||
- 🛑 NEVER generate content without user input
|
||||
- ✅ ALWAYS treat this as collaborative completion between technical peers
|
||||
- 📋 YOU ARE A FACILITATOR, not a content generator
|
||||
- 💬 FOCUS on finalizing a lean, LLM-optimized project context
|
||||
- 🎯 ENSURE all critical rules are captured and actionable
|
||||
- ⚠️ ABSOLUTELY NO TIME ESTIMATES - AI development speed has fundamentally changed
|
||||
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
|
||||
|
||||
## EXECUTION PROTOCOLS:
|
||||
|
||||
- 🎯 Show your analysis before taking any action
|
||||
- 📝 Review and optimize content for LLM context efficiency
|
||||
- 📖 Update frontmatter with completion status
|
||||
- 🚫 NO MORE STEPS - this is the final step
|
||||
|
||||
## CONTEXT BOUNDARIES:
|
||||
|
||||
- All rule categories from step-2 are complete
|
||||
- Technology stack and versions are documented
|
||||
- Focus on final review, optimization, and completion
|
||||
- Ensure the context file is ready for AI agent consumption
|
||||
|
||||
## YOUR TASK:
|
||||
|
||||
Complete the project context file, optimize it for LLM efficiency, and provide guidance for usage and maintenance.
|
||||
|
||||
## COMPLETION SEQUENCE:
|
||||
|
||||
### 1. Review Complete Context File
|
||||
|
||||
Read the entire project context file and analyze:
|
||||
|
||||
**Content Analysis:**
|
||||
|
||||
- Total length and readability for LLMs
|
||||
- Clarity and specificity of rules
|
||||
- Coverage of all critical areas
|
||||
- Actionability of each rule
|
||||
|
||||
**Structure Analysis:**
|
||||
|
||||
- Logical organization of sections
|
||||
- Consistency of formatting
|
||||
- Absence of redundant or obvious information
|
||||
- Optimization for quick scanning
|
||||
|
||||
### 2. Optimize for LLM Context
|
||||
|
||||
Ensure the file is lean and efficient:
|
||||
|
||||
**Content Optimization:**
|
||||
|
||||
- Remove any redundant rules or obvious information
|
||||
- Combine related rules into concise bullet points
|
||||
- Use specific, actionable language
|
||||
- Ensure each rule provides unique value
|
||||
|
||||
**Formatting Optimization:**
|
||||
|
||||
- Use consistent markdown formatting
|
||||
- Implement clear section hierarchy
|
||||
- Ensure scannability with strategic use of bolding
|
||||
- Maintain readability while maximizing information density
|
||||
|
||||
### 3. Final Content Structure
|
||||
|
||||
Ensure the final structure follows this optimized format:
|
||||
|
||||
```markdown
|
||||
# Project Context for AI Agents
|
||||
|
||||
_This file contains critical rules and patterns that AI agents must follow when implementing code in this project. Focus on unobvious details that agents might otherwise miss._
|
||||
|
||||
---
|
||||
|
||||
## Technology Stack & Versions
|
||||
|
||||
{{concise_technology_list}}
|
||||
|
||||
## Critical Implementation Rules
|
||||
|
||||
### Language-Specific Rules
|
||||
|
||||
{{specific_language_rules}}
|
||||
|
||||
### Framework-Specific Rules
|
||||
|
||||
{{framework_patterns}}
|
||||
|
||||
### Testing Rules
|
||||
|
||||
{{testing_requirements}}
|
||||
|
||||
### Code Quality & Style Rules
|
||||
|
||||
{{style_and_quality_patterns}}
|
||||
|
||||
### Development Workflow Rules
|
||||
|
||||
{{workflow_patterns}}
|
||||
|
||||
### Critical Don't-Miss Rules
|
||||
|
||||
{{anti_patterns_and_edge_cases}}
|
||||
|
||||
---
|
||||
|
||||
## Usage Guidelines
|
||||
|
||||
**For AI Agents:**
|
||||
|
||||
- Read this file before implementing any code
|
||||
- Follow ALL rules exactly as documented
|
||||
- When in doubt, prefer the more restrictive option
|
||||
- Update this file if new patterns emerge
|
||||
|
||||
**For Humans:**
|
||||
|
||||
- Keep this file lean and focused on agent needs
|
||||
- Update when technology stack changes
|
||||
- Review quarterly for outdated rules
|
||||
- Remove rules that become obvious over time
|
||||
|
||||
Last Updated: {{date}}
|
||||
```
|
||||
|
||||
### 4. Present Completion Summary
|
||||
|
||||
Based on user skill level, present the completion:
|
||||
|
||||
**Expert Mode:**
|
||||
"Project context complete. Optimized for LLM consumption with {{rule_count}} critical rules across {{section_count}} sections.
|
||||
|
||||
File saved to: `{output_folder}/project-context.md`
|
||||
|
||||
Ready for AI agent integration."
|
||||
|
||||
**Intermediate Mode:**
|
||||
"Your project context is complete and optimized for AI agents!
|
||||
|
||||
**What we created:**
|
||||
|
||||
- {{rule_count}} critical implementation rules
|
||||
- Technology stack with exact versions
|
||||
- Framework-specific patterns and conventions
|
||||
- Testing and quality guidelines
|
||||
- Workflow and anti-pattern rules
|
||||
|
||||
**Key benefits:**
|
||||
|
||||
- AI agents will implement consistently with your standards
|
||||
- Reduced context switching and implementation errors
|
||||
- Clear guidance for unobvious project requirements
|
||||
|
||||
**Next steps:**
|
||||
|
||||
- AI agents should read this file before implementing
|
||||
- Update as your project evolves
|
||||
- Review periodically for optimization"
|
||||
|
||||
**Beginner Mode:**
|
||||
"Excellent! Your project context guide is ready! 🎉
|
||||
|
||||
**What this does:**
|
||||
Think of this as a 'rules of the road' guide for AI agents working on your project. It ensures they all follow the same patterns and avoid common mistakes.
|
||||
|
||||
**What's included:**
|
||||
|
||||
- Exact technology versions to use
|
||||
- Critical coding rules they might miss
|
||||
- Testing and quality standards
|
||||
- Workflow patterns to follow
|
||||
|
||||
**How AI agents use it:**
|
||||
They read this file before writing any code, ensuring everything they create follows your project's standards perfectly.
|
||||
|
||||
Your project context is saved and ready to help agents implement consistently!"
|
||||
|
||||
### 5. Final File Updates
|
||||
|
||||
Update the project context file with completion information:
|
||||
|
||||
**Frontmatter Update:**
|
||||
|
||||
```yaml
|
||||
---
|
||||
project_name: '{{project_name}}'
|
||||
user_name: '{{user_name}}'
|
||||
date: '{{date}}'
|
||||
sections_completed:
|
||||
['technology_stack', 'language_rules', 'framework_rules', 'testing_rules', 'quality_rules', 'workflow_rules', 'anti_patterns']
|
||||
status: 'complete'
|
||||
rule_count: { { total_rules } }
|
||||
optimized_for_llm: true
|
||||
---
|
||||
```
|
||||
|
||||
**Add Usage Section:**
|
||||
Append the usage guidelines from step 3 to complete the document.
|
||||
|
||||
### 6. Completion Validation
|
||||
|
||||
Final checks before completion:
|
||||
|
||||
**Content Validation:**
|
||||
✅ All critical technology versions documented
|
||||
✅ Language-specific rules are specific and actionable
|
||||
✅ Framework rules cover project conventions
|
||||
✅ Testing rules ensure consistency
|
||||
✅ Code quality rules maintain standards
|
||||
✅ Workflow rules prevent conflicts
|
||||
✅ Anti-pattern rules prevent common mistakes
|
||||
|
||||
**Format Validation:**
|
||||
✅ Content is lean and optimized for LLMs
|
||||
✅ Structure is logical and scannable
|
||||
✅ No redundant or obvious information
|
||||
✅ Consistent formatting throughout
|
||||
|
||||
### 7. Completion Message
|
||||
|
||||
Present final completion to user:
|
||||
|
||||
"✅ **Project Context Generation Complete!**
|
||||
|
||||
Your optimized project context file is ready at:
|
||||
`{output_folder}/project-context.md`
|
||||
|
||||
**📊 Context Summary:**
|
||||
|
||||
- {{rule_count}} critical rules for AI agents
|
||||
- {{section_count}} comprehensive sections
|
||||
- Optimized for LLM context efficiency
|
||||
- Ready for immediate agent integration
|
||||
|
||||
**🎯 Key Benefits:**
|
||||
|
||||
- Consistent implementation across all AI agents
|
||||
- Reduced common mistakes and edge cases
|
||||
- Clear guidance for project-specific patterns
|
||||
- Minimal LLM context usage
|
||||
|
||||
**📋 Next Steps:**
|
||||
|
||||
1. AI agents will automatically read this file when implementing
|
||||
2. Update this file when your technology stack or patterns evolve
|
||||
3. Review quarterly to optimize and remove outdated rules
|
||||
|
||||
Your project context will help ensure high-quality, consistent implementation across all development work. Great work capturing your project's critical implementation requirements!"
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
✅ Complete project context file with all critical rules
|
||||
✅ Content optimized for LLM context efficiency
|
||||
✅ All technology versions and patterns documented
|
||||
✅ File structure is logical and scannable
|
||||
✅ Usage guidelines included for agents and humans
|
||||
✅ Frontmatter properly updated with completion status
|
||||
✅ User provided with clear next steps and benefits
|
||||
|
||||
## FAILURE MODES:
|
||||
|
||||
❌ Final content is too verbose for LLM consumption
|
||||
❌ Missing critical implementation rules or patterns
|
||||
❌ Not optimizing content for agent readability
|
||||
❌ Not providing clear usage guidelines
|
||||
❌ Frontmatter not properly updated
|
||||
❌ Not validating file completion before ending
|
||||
|
||||
## WORKFLOW COMPLETE:
|
||||
|
||||
This is the final step of the Generate Project Context workflow. The user now has a comprehensive, optimized project context file that will ensure consistent, high-quality implementation across all AI agents working on the project.
|
||||
|
||||
The project context file serves as the critical "rules of the road" that agents need to implement code consistently with the project's standards and patterns.
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
name: generate-project-context
|
||||
description: Creates a concise project-context.md file with critical rules and patterns that AI agents must follow when implementing code. Optimized for LLM context efficiency.
|
||||
---
|
||||
|
||||
# Generate Project Context Workflow
|
||||
|
||||
**Goal:** Create a concise, optimized `project-context.md` file containing critical rules, patterns, and guidelines that AI agents must follow when implementing code. This file focuses on unobvious details that LLMs need to be reminded of.
|
||||
|
||||
**Your Role:** You are a technical facilitator working with a peer to capture the essential implementation rules that will ensure consistent, high-quality code generation across all AI agents working on the project.
|
||||
|
||||
---
|
||||
|
||||
## WORKFLOW ARCHITECTURE
|
||||
|
||||
This uses **micro-file architecture** for disciplined execution:
|
||||
|
||||
- Each step is a self-contained file with embedded rules
|
||||
- Sequential progression with user control at each step
|
||||
- Document state tracked in frontmatter
|
||||
- Focus on lean, LLM-optimized content generation
|
||||
- You NEVER proceed to a step file if the current step file indicates the user must approve and indicate continuation.
|
||||
|
||||
---
|
||||
|
||||
## INITIALIZATION
|
||||
|
||||
### Configuration Loading
|
||||
|
||||
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
|
||||
|
||||
- `project_name`, `output_folder`, `user_name`
|
||||
- `communication_language`, `document_output_language`, `user_skill_level`
|
||||
- `date` as system-generated current datetime
|
||||
- ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}`
|
||||
|
||||
### Paths
|
||||
|
||||
- `installed_path` = `{project-root}/_bmad/bmm/workflows/generate-project-context`
|
||||
- `template_path` = `{installed_path}/project-context-template.md`
|
||||
- `output_file` = `{output_folder}/project-context.md`
|
||||
|
||||
---
|
||||
|
||||
## EXECUTION
|
||||
|
||||
Load and execute `steps/step-01-discover.md` to begin the workflow.
|
||||
|
||||
**Note:** Input document discovery and initialization protocols are handled in step-01-discover.md.
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs
|
||||
core,,Brainstorming,BS,20,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,,Facilitate interactive brainstorming sessions using diverse creative techniques and ideation methods,{output_folder}/brainstorming/brainstorming-session-{{date}}.md,,
|
||||
core,,Party Mode,PM,30,_bmad/core/workflows/party-mode/workflow.md,bmad-party-mode,false,party-mode facilitator,,Orchestrates group discussions between all installed BMAD agents enabling natural multi-agent conversations,,
|
||||
core,,bmad-help,BH,40,_bmad/core/tasks/help.md,bmad-help,false,,,Get unstuck by showing what workflow steps come next or answering questions about what to do in the BMad Method,,
|
||||
core,,Index Docs,ID,50,_bmad/core/tasks/index-docs.xml,bmad-index-docs,false,,,Generates or updates an index.md of all documents in the specified directory,,
|
||||
core,,Shard Document,SD,70,_bmad/core/tasks/shard-doc.xml,bmad-shard-doc,false,,,Splits large markdown documents into smaller organized files based on level 2 sections,,
|
||||
core,,Editorial Review - Prose,EP,80,_bmad/core/tasks/editorial-review-prose.xml,bmad-editorial-review-prose,false,,,Clinical copy-editor that reviews text for communication issues,,"three-column markdown table with suggested fixes",
|
||||
core,,Editorial Review - Structure,ES,90,_bmad/core/tasks/editorial-review-structure.xml,bmad-editorial-review-structure,false,,,Structural editor that proposes cuts reorganization and simplification while preserving comprehension,,
|
||||
core,,Adversarial Review (General),AR,100,_bmad/core/tasks/review-adversarial-general.xml,bmad-review-adversarial-general,false,,,Cynically review content and produce findings,,
|
||||
core,anytime,Brainstorming,BSP,,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,,"Generate diverse ideas through interactive techniques. Use early in ideation phase or when stuck generating ideas.",{output_folder}/brainstorming/brainstorming-session-{{date}}.md,,
|
||||
core,anytime,Party Mode,PM,,_bmad/core/workflows/party-mode/workflow.md,bmad-party-mode,false,party-mode facilitator,,"Orchestrate multi-agent discussions. Use when you need multiple agent perspectives or want agents to collaborate.",,
|
||||
core,anytime,bmad-help,BH,,_bmad/core/tasks/help.md,bmad-help,false,,,"Get unstuck by showing what workflow steps come next or answering BMad Method questions.",,
|
||||
core,anytime,Index Docs,ID,,_bmad/core/tasks/index-docs.xml,bmad-index-docs,false,,,"Create lightweight index for quick LLM scanning. Use when LLM needs to understand available docs without loading everything.",,
|
||||
core,anytime,Shard Document,SD,,_bmad/core/tasks/shard-doc.xml,bmad-shard-doc,false,,,"Split large documents into smaller files by sections. Use when doc becomes too large (>500 lines) to manage effectively.",,
|
||||
core,anytime,Editorial Review - Prose,EP,,_bmad/core/tasks/editorial-review-prose.xml,bmad-editorial-review-prose,false,,,"Review prose for clarity, tone, and communication issues. Use after drafting to polish written content.",report located with target document,"three-column markdown table with suggested fixes",
|
||||
core,anytime,Editorial Review - Structure,ES,,_bmad/core/tasks/editorial-review-structure.xml,bmad-editorial-review-structure,false,,,"Propose cuts, reorganization, and simplification while preserving comprehension. Use when doc produced from multiple subprocesses or needs structural improvement.",report located with target document,
|
||||
core,anytime,Adversarial Review (General),AR,,_bmad/core/tasks/review-adversarial-general.xml,bmad-review-adversarial-general,false,,,"Review content critically to find issues and weaknesses. Use for quality assurance or before finalizing deliverables. Code Review in other modules run this automatically, but its useful also for document reviews",,
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -1,4 +1,4 @@
|
|||
<task id="_bmad/core/tasks/workflow.xml" name="Execute Workflow" standalone="false">
|
||||
<task id="_bmad/core/tasks/workflow.xml" name="Execute Workflow" standalone="false" internal="true">
|
||||
<objective>Execute given workflow by loading its configuration, following instructions, and producing output</objective>
|
||||
|
||||
<llm critical="true">
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
<action>Continue to next step</action>
|
||||
</if>
|
||||
<if response="p">
|
||||
<action>Start the party-mode workflow {project-root}/_bmad/core/workflows/party-mode/workflow.yaml</action>
|
||||
<action>Start the party-mode workflow {project-root}/_bmad/core/workflows/party-mode/workflow.md</action>
|
||||
</if>
|
||||
<if
|
||||
response="y">
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ async function runTests() {
|
|||
|
||||
try {
|
||||
const builder = new YamlXmlBuilder();
|
||||
const qaAgentPath = path.join(projectRoot, 'src/bmm/agents/quinn.agent.yaml');
|
||||
const qaAgentPath = path.join(projectRoot, 'src/bmm/agents/qa.agent.yaml');
|
||||
const tempOutput = path.join(__dirname, 'temp-qa-agent.md');
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -586,7 +586,11 @@ class ConfigCollector {
|
|||
console.log();
|
||||
console.log(chalk.cyan('?') + ' ' + chalk.magenta(moduleDisplayName));
|
||||
let customize = true;
|
||||
if (moduleName !== 'core') {
|
||||
if (moduleName === 'core') {
|
||||
// Core module: no confirm prompt, so add spacing manually to match visual style
|
||||
console.log(chalk.gray('│'));
|
||||
} else {
|
||||
// Non-core modules: show "Accept Defaults?" confirm prompt (clack adds spacing)
|
||||
const customizeAnswer = await prompts.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class DependencyResolver {
|
|||
const content = await fs.readFile(file.path, 'utf8');
|
||||
|
||||
// Parse YAML frontmatter for explicit dependencies
|
||||
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
||||
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
||||
if (frontmatterMatch) {
|
||||
try {
|
||||
// Pre-process to handle backticks in YAML values
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ const { ManifestGenerator } = require('./manifest-generator');
|
|||
const { IdeConfigManager } = require('./ide-config-manager');
|
||||
const { CustomHandler } = require('../custom/handler');
|
||||
const prompts = require('../../../lib/prompts');
|
||||
|
||||
// BMAD installation folder name - this is constant and should never change
|
||||
const BMAD_FOLDER_NAME = '_bmad';
|
||||
const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
|
||||
|
||||
class Installer {
|
||||
constructor() {
|
||||
|
|
@ -697,9 +695,6 @@ class Installer {
|
|||
config.skipIde = toolSelection.skipIde;
|
||||
const ideConfigurations = toolSelection.configurations;
|
||||
|
||||
// Add spacing after prompts before installation progress
|
||||
console.log('');
|
||||
|
||||
if (spinner.isSpinning) {
|
||||
spinner.text = 'Continuing installation...';
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
|||
const fs = require('fs-extra');
|
||||
const yaml = require('yaml');
|
||||
const crypto = require('node:crypto');
|
||||
const csv = require('csv-parse/sync');
|
||||
const { getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||
|
||||
// Load package.json for version info
|
||||
|
|
@ -21,6 +22,19 @@ class ManifestGenerator {
|
|||
this.selectedIdes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean text for CSV output by normalizing whitespace and escaping quotes
|
||||
* @param {string} text - Text to clean
|
||||
* @returns {string} Cleaned text safe for CSV
|
||||
*/
|
||||
cleanForCSV(text) {
|
||||
if (!text) return '';
|
||||
return text
|
||||
.trim()
|
||||
.replaceAll(/\s+/g, ' ') // Normalize all whitespace (including newlines) to single space
|
||||
.replaceAll('"', '""'); // Escape quotes for CSV
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate all manifests for the installation
|
||||
* @param {string} bmadDir - _bmad
|
||||
|
|
@ -161,7 +175,7 @@ class ManifestGenerator {
|
|||
workflow = yaml.parse(content);
|
||||
} else {
|
||||
// Parse MD workflow with YAML frontmatter
|
||||
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
||||
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
||||
if (!frontmatterMatch) {
|
||||
if (debug) {
|
||||
console.log(`[DEBUG] Skipped (no frontmatter): ${fullPath}`);
|
||||
|
|
@ -201,7 +215,7 @@ class ManifestGenerator {
|
|||
// Workflows with standalone: false are filtered out above
|
||||
workflows.push({
|
||||
name: workflow.name,
|
||||
description: workflow.description.replaceAll('"', '""'), // Escape quotes for CSV
|
||||
description: this.cleanForCSV(workflow.description),
|
||||
module: moduleName,
|
||||
path: installPath,
|
||||
});
|
||||
|
|
@ -319,24 +333,15 @@ class ManifestGenerator {
|
|||
|
||||
const agentName = entry.name.replace('.md', '');
|
||||
|
||||
// Helper function to clean and escape CSV content
|
||||
const cleanForCSV = (text) => {
|
||||
if (!text) return '';
|
||||
return text
|
||||
.trim()
|
||||
.replaceAll(/\s+/g, ' ') // Normalize whitespace
|
||||
.replaceAll('"', '""'); // Escape quotes for CSV
|
||||
};
|
||||
|
||||
agents.push({
|
||||
name: agentName,
|
||||
displayName: nameMatch ? nameMatch[1] : agentName,
|
||||
title: titleMatch ? titleMatch[1] : '',
|
||||
icon: iconMatch ? iconMatch[1] : '',
|
||||
role: roleMatch ? cleanForCSV(roleMatch[1]) : '',
|
||||
identity: identityMatch ? cleanForCSV(identityMatch[1]) : '',
|
||||
communicationStyle: styleMatch ? cleanForCSV(styleMatch[1]) : '',
|
||||
principles: principlesMatch ? cleanForCSV(principlesMatch[1]) : '',
|
||||
role: roleMatch ? this.cleanForCSV(roleMatch[1]) : '',
|
||||
identity: identityMatch ? this.cleanForCSV(identityMatch[1]) : '',
|
||||
communicationStyle: styleMatch ? this.cleanForCSV(styleMatch[1]) : '',
|
||||
principles: principlesMatch ? this.cleanForCSV(principlesMatch[1]) : '',
|
||||
module: moduleName,
|
||||
path: installPath,
|
||||
});
|
||||
|
|
@ -385,6 +390,11 @@ class ManifestGenerator {
|
|||
const filePath = path.join(dirPath, file);
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
// Skip internal/engine files (not user-facing tasks)
|
||||
if (content.includes('internal="true"')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = file.replace(/\.(xml|md)$/, '');
|
||||
let displayName = name;
|
||||
let description = '';
|
||||
|
|
@ -392,13 +402,13 @@ class ManifestGenerator {
|
|||
|
||||
if (file.endsWith('.md')) {
|
||||
// Parse YAML frontmatter for .md tasks
|
||||
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
||||
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
||||
if (frontmatterMatch) {
|
||||
try {
|
||||
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
||||
name = frontmatter.name || name;
|
||||
displayName = frontmatter.displayName || frontmatter.name || name;
|
||||
description = frontmatter.description || '';
|
||||
description = this.cleanForCSV(frontmatter.description || '');
|
||||
standalone = frontmatter.standalone === true || frontmatter.standalone === 'true';
|
||||
} catch {
|
||||
// If YAML parsing fails, use defaults
|
||||
|
|
@ -411,7 +421,7 @@ class ManifestGenerator {
|
|||
|
||||
const descMatch = content.match(/description="([^"]+)"/);
|
||||
const objMatch = content.match(/<objective>([^<]+)<\/objective>/);
|
||||
description = descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '';
|
||||
description = this.cleanForCSV(descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '');
|
||||
|
||||
const standaloneMatch = content.match(/<task[^>]+standalone="true"/);
|
||||
standalone = !!standaloneMatch;
|
||||
|
|
@ -424,7 +434,7 @@ class ManifestGenerator {
|
|||
tasks.push({
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
description: description.replaceAll('"', '""'),
|
||||
description: description,
|
||||
module: moduleName,
|
||||
path: installPath,
|
||||
standalone: standalone,
|
||||
|
|
@ -474,6 +484,11 @@ class ManifestGenerator {
|
|||
const filePath = path.join(dirPath, file);
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
// Skip internal tools (same as tasks)
|
||||
if (content.includes('internal="true"')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let name = file.replace(/\.(xml|md)$/, '');
|
||||
let displayName = name;
|
||||
let description = '';
|
||||
|
|
@ -481,13 +496,13 @@ class ManifestGenerator {
|
|||
|
||||
if (file.endsWith('.md')) {
|
||||
// Parse YAML frontmatter for .md tools
|
||||
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
||||
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
||||
if (frontmatterMatch) {
|
||||
try {
|
||||
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
||||
name = frontmatter.name || name;
|
||||
displayName = frontmatter.displayName || frontmatter.name || name;
|
||||
description = frontmatter.description || '';
|
||||
description = this.cleanForCSV(frontmatter.description || '');
|
||||
standalone = frontmatter.standalone === true || frontmatter.standalone === 'true';
|
||||
} catch {
|
||||
// If YAML parsing fails, use defaults
|
||||
|
|
@ -500,7 +515,7 @@ class ManifestGenerator {
|
|||
|
||||
const descMatch = content.match(/description="([^"]+)"/);
|
||||
const objMatch = content.match(/<objective>([^<]+)<\/objective>/);
|
||||
description = descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '';
|
||||
description = this.cleanForCSV(descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '');
|
||||
|
||||
const standaloneMatch = content.match(/<tool[^>]+standalone="true"/);
|
||||
standalone = !!standaloneMatch;
|
||||
|
|
@ -513,7 +528,7 @@ class ManifestGenerator {
|
|||
tools.push({
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
description: description.replaceAll('"', '""'),
|
||||
description: description,
|
||||
module: moduleName,
|
||||
path: installPath,
|
||||
standalone: standalone,
|
||||
|
|
@ -773,30 +788,23 @@ class ManifestGenerator {
|
|||
*/
|
||||
async writeAgentManifest(cfgDir) {
|
||||
const csvPath = path.join(cfgDir, 'agent-manifest.csv');
|
||||
const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
|
||||
|
||||
// Read existing manifest to preserve entries
|
||||
const existingEntries = new Map();
|
||||
if (await fs.pathExists(csvPath)) {
|
||||
const content = await fs.readFile(csvPath, 'utf8');
|
||||
const lines = content.split('\n').filter((line) => line.trim());
|
||||
|
||||
// Skip header
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line) {
|
||||
// Parse CSV (simple parsing assuming no commas in quoted fields)
|
||||
const parts = line.split('","');
|
||||
if (parts.length >= 11) {
|
||||
const name = parts[0].replace(/^"/, '');
|
||||
const module = parts[8];
|
||||
existingEntries.set(`${module}:${name}`, line);
|
||||
}
|
||||
}
|
||||
const records = csv.parse(content, {
|
||||
columns: true,
|
||||
skip_empty_lines: true,
|
||||
});
|
||||
for (const record of records) {
|
||||
existingEntries.set(`${record.module}:${record.name}`, record);
|
||||
}
|
||||
}
|
||||
|
||||
// Create CSV header with persona fields
|
||||
let csv = 'name,displayName,title,icon,role,identity,communicationStyle,principles,module,path\n';
|
||||
let csvContent = 'name,displayName,title,icon,role,identity,communicationStyle,principles,module,path\n';
|
||||
|
||||
// Combine existing and new agents, preferring new data for duplicates
|
||||
const allAgents = new Map();
|
||||
|
|
@ -809,18 +817,38 @@ class ManifestGenerator {
|
|||
// Add/update new agents
|
||||
for (const agent of this.agents) {
|
||||
const key = `${agent.module}:${agent.name}`;
|
||||
allAgents.set(
|
||||
key,
|
||||
`"${agent.name}","${agent.displayName}","${agent.title}","${agent.icon}","${agent.role}","${agent.identity}","${agent.communicationStyle}","${agent.principles}","${agent.module}","${agent.path}"`,
|
||||
);
|
||||
allAgents.set(key, {
|
||||
name: agent.name,
|
||||
displayName: agent.displayName,
|
||||
title: agent.title,
|
||||
icon: agent.icon,
|
||||
role: agent.role,
|
||||
identity: agent.identity,
|
||||
communicationStyle: agent.communicationStyle,
|
||||
principles: agent.principles,
|
||||
module: agent.module,
|
||||
path: agent.path,
|
||||
});
|
||||
}
|
||||
|
||||
// Write all agents
|
||||
for (const [, value] of allAgents) {
|
||||
csv += value + '\n';
|
||||
for (const [, record] of allAgents) {
|
||||
const row = [
|
||||
escapeCsv(record.name),
|
||||
escapeCsv(record.displayName),
|
||||
escapeCsv(record.title),
|
||||
escapeCsv(record.icon),
|
||||
escapeCsv(record.role),
|
||||
escapeCsv(record.identity),
|
||||
escapeCsv(record.communicationStyle),
|
||||
escapeCsv(record.principles),
|
||||
escapeCsv(record.module),
|
||||
escapeCsv(record.path),
|
||||
].join(',');
|
||||
csvContent += row + '\n';
|
||||
}
|
||||
|
||||
await fs.writeFile(csvPath, csv);
|
||||
await fs.writeFile(csvPath, csvContent);
|
||||
return csvPath;
|
||||
}
|
||||
|
||||
|
|
@ -830,30 +858,23 @@ class ManifestGenerator {
|
|||
*/
|
||||
async writeTaskManifest(cfgDir) {
|
||||
const csvPath = path.join(cfgDir, 'task-manifest.csv');
|
||||
const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
|
||||
|
||||
// Read existing manifest to preserve entries
|
||||
const existingEntries = new Map();
|
||||
if (await fs.pathExists(csvPath)) {
|
||||
const content = await fs.readFile(csvPath, 'utf8');
|
||||
const lines = content.split('\n').filter((line) => line.trim());
|
||||
|
||||
// Skip header
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line) {
|
||||
// Parse CSV (simple parsing assuming no commas in quoted fields)
|
||||
const parts = line.split('","');
|
||||
if (parts.length >= 6) {
|
||||
const name = parts[0].replace(/^"/, '');
|
||||
const module = parts[3];
|
||||
existingEntries.set(`${module}:${name}`, line);
|
||||
}
|
||||
}
|
||||
const records = csv.parse(content, {
|
||||
columns: true,
|
||||
skip_empty_lines: true,
|
||||
});
|
||||
for (const record of records) {
|
||||
existingEntries.set(`${record.module}:${record.name}`, record);
|
||||
}
|
||||
}
|
||||
|
||||
// Create CSV header with standalone column
|
||||
let csv = 'name,displayName,description,module,path,standalone\n';
|
||||
let csvContent = 'name,displayName,description,module,path,standalone\n';
|
||||
|
||||
// Combine existing and new tasks
|
||||
const allTasks = new Map();
|
||||
|
|
@ -866,15 +887,30 @@ class ManifestGenerator {
|
|||
// Add/update new tasks
|
||||
for (const task of this.tasks) {
|
||||
const key = `${task.module}:${task.name}`;
|
||||
allTasks.set(key, `"${task.name}","${task.displayName}","${task.description}","${task.module}","${task.path}","${task.standalone}"`);
|
||||
allTasks.set(key, {
|
||||
name: task.name,
|
||||
displayName: task.displayName,
|
||||
description: task.description,
|
||||
module: task.module,
|
||||
path: task.path,
|
||||
standalone: task.standalone,
|
||||
});
|
||||
}
|
||||
|
||||
// Write all tasks
|
||||
for (const [, value] of allTasks) {
|
||||
csv += value + '\n';
|
||||
for (const [, record] of allTasks) {
|
||||
const row = [
|
||||
escapeCsv(record.name),
|
||||
escapeCsv(record.displayName),
|
||||
escapeCsv(record.description),
|
||||
escapeCsv(record.module),
|
||||
escapeCsv(record.path),
|
||||
escapeCsv(record.standalone),
|
||||
].join(',');
|
||||
csvContent += row + '\n';
|
||||
}
|
||||
|
||||
await fs.writeFile(csvPath, csv);
|
||||
await fs.writeFile(csvPath, csvContent);
|
||||
return csvPath;
|
||||
}
|
||||
|
||||
|
|
@ -884,30 +920,23 @@ class ManifestGenerator {
|
|||
*/
|
||||
async writeToolManifest(cfgDir) {
|
||||
const csvPath = path.join(cfgDir, 'tool-manifest.csv');
|
||||
const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
|
||||
|
||||
// Read existing manifest to preserve entries
|
||||
const existingEntries = new Map();
|
||||
if (await fs.pathExists(csvPath)) {
|
||||
const content = await fs.readFile(csvPath, 'utf8');
|
||||
const lines = content.split('\n').filter((line) => line.trim());
|
||||
|
||||
// Skip header
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line) {
|
||||
// Parse CSV (simple parsing assuming no commas in quoted fields)
|
||||
const parts = line.split('","');
|
||||
if (parts.length >= 6) {
|
||||
const name = parts[0].replace(/^"/, '');
|
||||
const module = parts[3];
|
||||
existingEntries.set(`${module}:${name}`, line);
|
||||
}
|
||||
}
|
||||
const records = csv.parse(content, {
|
||||
columns: true,
|
||||
skip_empty_lines: true,
|
||||
});
|
||||
for (const record of records) {
|
||||
existingEntries.set(`${record.module}:${record.name}`, record);
|
||||
}
|
||||
}
|
||||
|
||||
// Create CSV header with standalone column
|
||||
let csv = 'name,displayName,description,module,path,standalone\n';
|
||||
let csvContent = 'name,displayName,description,module,path,standalone\n';
|
||||
|
||||
// Combine existing and new tools
|
||||
const allTools = new Map();
|
||||
|
|
@ -920,15 +949,30 @@ class ManifestGenerator {
|
|||
// Add/update new tools
|
||||
for (const tool of this.tools) {
|
||||
const key = `${tool.module}:${tool.name}`;
|
||||
allTools.set(key, `"${tool.name}","${tool.displayName}","${tool.description}","${tool.module}","${tool.path}","${tool.standalone}"`);
|
||||
allTools.set(key, {
|
||||
name: tool.name,
|
||||
displayName: tool.displayName,
|
||||
description: tool.description,
|
||||
module: tool.module,
|
||||
path: tool.path,
|
||||
standalone: tool.standalone,
|
||||
});
|
||||
}
|
||||
|
||||
// Write all tools
|
||||
for (const [, value] of allTools) {
|
||||
csv += value + '\n';
|
||||
for (const [, record] of allTools) {
|
||||
const row = [
|
||||
escapeCsv(record.name),
|
||||
escapeCsv(record.displayName),
|
||||
escapeCsv(record.description),
|
||||
escapeCsv(record.module),
|
||||
escapeCsv(record.path),
|
||||
escapeCsv(record.standalone),
|
||||
].join(',');
|
||||
csvContent += row + '\n';
|
||||
}
|
||||
|
||||
await fs.writeFile(csvPath, csv);
|
||||
await fs.writeFile(csvPath, csvContent);
|
||||
return csvPath;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ class CustomHandler {
|
|||
const agentFiles = await this.findFilesRecursively(sourceAgentsPath, ['.agent.yaml']);
|
||||
|
||||
for (const agentFile of agentFiles) {
|
||||
const relativePath = path.relative(sourceAgentsPath, agentFile);
|
||||
const relativePath = path.relative(sourceAgentsPath, agentFile).split(path.sep).join('/');
|
||||
const targetDir = path.join(targetAgentsPath, path.dirname(relativePath));
|
||||
|
||||
await fs.ensureDir(targetDir);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
|||
const chalk = require('chalk');
|
||||
const { XmlHandler } = require('../../../lib/xml-handler');
|
||||
const { getSourcePath } = require('../../../lib/project-root');
|
||||
const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
|
||||
|
||||
/**
|
||||
* Base class for IDE-specific setup
|
||||
|
|
@ -18,7 +19,7 @@ class BaseIdeSetup {
|
|||
this.configFile = null; // Override in subclasses when detection is file-based
|
||||
this.detectionPaths = []; // Additional paths that indicate the IDE is configured
|
||||
this.xmlHandler = new XmlHandler();
|
||||
this.bmadFolderName = 'bmad'; // Default, can be overridden
|
||||
this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,7 +58,7 @@ class BaseIdeSetup {
|
|||
if (this.configDir) {
|
||||
const configPath = path.join(projectDir, this.configDir);
|
||||
if (await fs.pathExists(configPath)) {
|
||||
const bmadRulesPath = path.join(configPath, 'bmad');
|
||||
const bmadRulesPath = path.join(configPath, BMAD_FOLDER_NAME);
|
||||
if (await fs.pathExists(bmadRulesPath)) {
|
||||
await fs.remove(bmadRulesPath);
|
||||
console.log(chalk.dim(`Removed ${this.name} BMAD configuration`));
|
||||
|
|
@ -445,6 +446,11 @@ class BaseIdeSetup {
|
|||
try {
|
||||
const content = await fs.readFile(fullPath, 'utf8');
|
||||
|
||||
// Skip internal/engine files (not user-facing tasks/tools)
|
||||
if (content.includes('internal="true"')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for standalone="true" in XML files
|
||||
if (entry.name.endsWith('.xml')) {
|
||||
// Look for standalone="true" in the opening tag (task or tool)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
|
|||
*/
|
||||
async installToTarget(projectDir, bmadDir, config, options) {
|
||||
const { target_dir, template_type, artifact_types } = config;
|
||||
|
||||
// Skip targets with explicitly empty artifact_types array
|
||||
// This prevents creating empty directories when no artifacts will be written
|
||||
if (Array.isArray(artifact_types) && artifact_types.length === 0) {
|
||||
return { success: true, results: { agents: 0, workflows: 0, tasks: 0, tools: 0 } };
|
||||
}
|
||||
|
||||
const targetPath = path.join(projectDir, target_dir);
|
||||
await this.ensureDir(targetPath);
|
||||
|
||||
|
|
@ -86,10 +93,11 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
|
|||
results.workflows = await this.writeWorkflowArtifacts(targetPath, artifacts, template_type, config);
|
||||
}
|
||||
|
||||
// Install tasks and tools
|
||||
// Install tasks and tools using template system (supports TOML for Gemini, MD for others)
|
||||
if (!artifact_types || artifact_types.includes('tasks') || artifact_types.includes('tools')) {
|
||||
const taskToolGen = new TaskToolCommandGenerator();
|
||||
const taskToolResult = await taskToolGen.generateDashTaskToolCommands(projectDir, bmadDir, targetPath);
|
||||
const taskToolGen = new TaskToolCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts } = await taskToolGen.collectTaskToolArtifacts(bmadDir);
|
||||
const taskToolResult = await this.writeTaskToolArtifacts(targetPath, artifacts, template_type, config);
|
||||
results.tasks = taskToolResult.tasks || 0;
|
||||
results.tools = taskToolResult.tools || 0;
|
||||
}
|
||||
|
|
@ -180,6 +188,53 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write task/tool artifacts to target directory using templates
|
||||
* @param {string} targetPath - Target directory path
|
||||
* @param {Array} artifacts - Task/tool artifacts
|
||||
* @param {string} templateType - Template type to use
|
||||
* @param {Object} config - Installation configuration
|
||||
* @returns {Promise<Object>} Counts of tasks and tools written
|
||||
*/
|
||||
async writeTaskToolArtifacts(targetPath, artifacts, templateType, config = {}) {
|
||||
let taskCount = 0;
|
||||
let toolCount = 0;
|
||||
|
||||
// Pre-load templates to avoid repeated file I/O in the loop
|
||||
const taskTemplate = await this.loadTemplate(templateType, 'task', config, 'default-task');
|
||||
const toolTemplate = await this.loadTemplate(templateType, 'tool', config, 'default-tool');
|
||||
|
||||
const { artifact_types } = config;
|
||||
|
||||
for (const artifact of artifacts) {
|
||||
if (artifact.type !== 'task' && artifact.type !== 'tool') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if the specific artifact type is not requested in config
|
||||
if (artifact_types) {
|
||||
if (artifact.type === 'task' && !artifact_types.includes('tasks')) continue;
|
||||
if (artifact.type === 'tool' && !artifact_types.includes('tools')) continue;
|
||||
}
|
||||
|
||||
// Use pre-loaded template based on artifact type
|
||||
const { content: template, extension } = artifact.type === 'task' ? taskTemplate : toolTemplate;
|
||||
|
||||
const content = this.renderTemplate(template, artifact);
|
||||
const filename = this.generateFilename(artifact, artifact.type, extension);
|
||||
const filePath = path.join(targetPath, filename);
|
||||
await this.writeFile(filePath, content);
|
||||
|
||||
if (artifact.type === 'task') {
|
||||
taskCount++;
|
||||
} else {
|
||||
toolCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return { tasks: taskCount, tools: toolCount };
|
||||
}
|
||||
|
||||
/**
|
||||
* Load template based on type and configuration
|
||||
* @param {string} templateType - Template type (claude, windsurf, etc.)
|
||||
|
|
@ -283,6 +338,7 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
|
|||
return `---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
You must fully embody this agent's persona and follow all activation instructions exactly as specified.
|
||||
|
|
@ -297,6 +353,7 @@ You must fully embody this agent's persona and follow all activation instruction
|
|||
return `---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# {{name}}
|
||||
|
|
@ -314,10 +371,24 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
|
|||
renderTemplate(template, artifact) {
|
||||
// Use the appropriate path property based on artifact type
|
||||
let pathToUse = artifact.relativePath || '';
|
||||
if (artifact.type === 'agent-launcher') {
|
||||
switch (artifact.type) {
|
||||
case 'agent-launcher': {
|
||||
pathToUse = artifact.agentPath || artifact.relativePath || '';
|
||||
} else if (artifact.type === 'workflow-command') {
|
||||
|
||||
break;
|
||||
}
|
||||
case 'workflow-command': {
|
||||
pathToUse = artifact.workflowPath || artifact.relativePath || '';
|
||||
|
||||
break;
|
||||
}
|
||||
case 'task':
|
||||
case 'tool': {
|
||||
pathToUse = artifact.path || artifact.relativePath || '';
|
||||
|
||||
break;
|
||||
}
|
||||
// No default
|
||||
}
|
||||
|
||||
let rendered = template
|
||||
|
|
@ -349,8 +420,9 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
|
|||
// Reuse central logic to ensure consistent naming conventions
|
||||
const standardName = toDashPath(artifact.relativePath);
|
||||
|
||||
// Clean up potential double extensions from source files (e.g. .yaml.md -> .md)
|
||||
const baseName = standardName.replace(/\.(yaml|yml)\.md$/, '.md');
|
||||
// Clean up potential double extensions from source files (e.g. .yaml.md, .xml.md -> .md)
|
||||
// This handles any extensions that might slip through toDashPath()
|
||||
const baseName = standardName.replace(/\.(md|yaml|yml|json|xml|toml)\.md$/i, '.md');
|
||||
|
||||
// If using default markdown, preserve the bmad-agent- prefix for agents
|
||||
if (extension === '.md') {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,10 @@ class CodexSetup extends BaseIdeSetup {
|
|||
);
|
||||
taskArtifacts.push({
|
||||
type: 'task',
|
||||
name: task.name,
|
||||
displayName: task.name,
|
||||
module: task.module,
|
||||
path: task.path,
|
||||
sourcePath: task.path,
|
||||
relativePath: path.join(task.module, 'tasks', `${task.name}.md`),
|
||||
content,
|
||||
|
|
@ -116,7 +119,7 @@ class CodexSetup extends BaseIdeSetup {
|
|||
const workflowCount = await workflowGenerator.writeDashArtifacts(destDir, workflowArtifacts);
|
||||
|
||||
// Also write tasks using underscore format
|
||||
const ttGen = new TaskToolCommandGenerator();
|
||||
const ttGen = new TaskToolCommandGenerator(this.bmadFolderName);
|
||||
const tasksWritten = await ttGen.writeDashArtifacts(destDir, taskArtifacts);
|
||||
|
||||
const written = agentCount + workflowCount + tasksWritten;
|
||||
|
|
@ -214,7 +217,10 @@ class CodexSetup extends BaseIdeSetup {
|
|||
|
||||
artifacts.push({
|
||||
type: 'task',
|
||||
name: task.name,
|
||||
displayName: task.name,
|
||||
module: task.module,
|
||||
path: task.path,
|
||||
sourcePath: task.path,
|
||||
relativePath: path.join(task.module, 'tasks', `${task.name}.md`),
|
||||
content,
|
||||
|
|
@ -411,6 +417,7 @@ class CodexSetup extends BaseIdeSetup {
|
|||
const launcherContent = `---
|
||||
name: '${agentName}'
|
||||
description: '${agentName} agent'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const fs = require('fs-extra');
|
||||
const path = require('node:path');
|
||||
const chalk = require('chalk');
|
||||
const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
|
||||
|
||||
/**
|
||||
* IDE Manager - handles IDE-specific setup
|
||||
|
|
@ -14,7 +15,7 @@ class IdeManager {
|
|||
constructor() {
|
||||
this.handlers = new Map();
|
||||
this._initialized = false;
|
||||
this.bmadFolderName = 'bmad'; // Default, can be overridden
|
||||
this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,6 +74,9 @@ class IdeManager {
|
|||
if (HandlerClass) {
|
||||
const instance = new HandlerClass();
|
||||
if (instance.name && typeof instance.name === 'string') {
|
||||
if (typeof instance.setBmadFolderName === 'function') {
|
||||
instance.setBmadFolderName(this.bmadFolderName);
|
||||
}
|
||||
this.handlers.set(instance.name, instance);
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +104,9 @@ class IdeManager {
|
|||
if (!platformInfo.installer) continue;
|
||||
|
||||
const handler = new ConfigDrivenIdeSetup(platformCode, platformInfo);
|
||||
if (typeof handler.setBmadFolderName === 'function') {
|
||||
handler.setBmadFolderName(this.bmadFolderName);
|
||||
}
|
||||
this.handlers.set(platformCode, handler);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ platforms:
|
|||
- target_dir: .github/agents
|
||||
template_type: copilot_agents
|
||||
artifact_types: [agents]
|
||||
- target_dir: .vscode
|
||||
template_type: vscode_settings
|
||||
artifact_types: []
|
||||
|
||||
iflow:
|
||||
name: "iFlow"
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const chalk = require('chalk');
|
||||
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName } = require('./path-utils');
|
||||
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
|
||||
|
||||
/**
|
||||
* Generates launcher command files for each agent
|
||||
* Similar to WorkflowCommandGenerator but for agents
|
||||
*/
|
||||
class AgentCommandGenerator {
|
||||
constructor(bmadFolderName = 'bmad') {
|
||||
constructor(bmadFolderName = BMAD_FOLDER_NAME) {
|
||||
this.templatePath = path.join(__dirname, '../templates/agent-command-template.md');
|
||||
this.bmadFolderName = bmadFolderName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,13 +141,24 @@ async function getTasksFromDir(dirPath, moduleName) {
|
|||
const files = await fs.readdir(dirPath);
|
||||
|
||||
for (const file of files) {
|
||||
if (!file.endsWith('.md')) {
|
||||
// Include both .md and .xml task files
|
||||
if (!file.endsWith('.md') && !file.endsWith('.xml')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const filePath = path.join(dirPath, file);
|
||||
const content = await fs.readFile(filePath, 'utf8');
|
||||
|
||||
// Skip internal/engine files (not user-facing tasks)
|
||||
if (content.includes('internal="true"')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove extension to get task name
|
||||
const ext = file.endsWith('.xml') ? '.xml' : '.md';
|
||||
tasks.push({
|
||||
path: path.join(dirPath, file),
|
||||
name: file.replace('.md', ''),
|
||||
path: filePath,
|
||||
name: file.replace(ext, ''),
|
||||
module: moduleName,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@
|
|||
const TYPE_SEGMENTS = ['workflows', 'tasks', 'tools'];
|
||||
const AGENT_SEGMENT = 'agents';
|
||||
|
||||
// BMAD installation folder name - centralized constant for all installers
|
||||
const BMAD_FOLDER_NAME = '_bmad';
|
||||
|
||||
/**
|
||||
* Convert hierarchical path to flat dash-separated name (NEW STANDARD)
|
||||
* Converts: 'bmm', 'agents', 'pm' → 'bmad-agent-bmm-pm.md'
|
||||
|
|
@ -59,7 +62,9 @@ function toDashPath(relativePath) {
|
|||
return 'bmad-unknown.md';
|
||||
}
|
||||
|
||||
const withoutExt = relativePath.replace('.md', '');
|
||||
// Strip common file extensions to avoid double extensions in generated filenames
|
||||
// e.g., 'create-story.xml' → 'create-story', 'workflow.yaml' → 'workflow'
|
||||
const withoutExt = relativePath.replace(/\.(md|yaml|yml|json|xml|toml)$/i, '');
|
||||
const parts = withoutExt.split(/[/\\]/);
|
||||
|
||||
const module = parts[0];
|
||||
|
|
@ -183,7 +188,8 @@ function toUnderscoreName(module, type, name) {
|
|||
* @deprecated Use toDashPath instead
|
||||
*/
|
||||
function toUnderscorePath(relativePath) {
|
||||
const withoutExt = relativePath.replace('.md', '');
|
||||
// Strip common file extensions (same as toDashPath for consistency)
|
||||
const withoutExt = relativePath.replace(/\.(md|yaml|yml|json|xml|toml)$/i, '');
|
||||
const parts = withoutExt.split(/[/\\]/);
|
||||
|
||||
const module = parts[0];
|
||||
|
|
@ -289,4 +295,5 @@ module.exports = {
|
|||
|
||||
TYPE_SEGMENTS,
|
||||
AGENT_SEGMENT,
|
||||
BMAD_FOLDER_NAME,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,12 +2,98 @@ const path = require('node:path');
|
|||
const fs = require('fs-extra');
|
||||
const csv = require('csv-parse/sync');
|
||||
const chalk = require('chalk');
|
||||
const { toColonName, toColonPath, toDashPath } = require('./path-utils');
|
||||
const { toColonName, toColonPath, toDashPath, BMAD_FOLDER_NAME } = require('./path-utils');
|
||||
|
||||
/**
|
||||
* Generates command files for standalone tasks and tools
|
||||
*/
|
||||
class TaskToolCommandGenerator {
|
||||
/**
|
||||
* @param {string} bmadFolderName - Name of the BMAD folder for template rendering (default: '_bmad')
|
||||
* Note: This parameter is accepted for API consistency with AgentCommandGenerator and
|
||||
* WorkflowCommandGenerator, but is not used for path stripping. The manifest always stores
|
||||
* filesystem paths with '_bmad/' prefix (the actual folder name), while bmadFolderName is
|
||||
* used for template placeholder rendering ({{bmadFolderName}}).
|
||||
*/
|
||||
constructor(bmadFolderName = BMAD_FOLDER_NAME) {
|
||||
this.bmadFolderName = bmadFolderName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect task and tool artifacts for IDE installation
|
||||
* @param {string} bmadDir - BMAD installation directory
|
||||
* @returns {Promise<Object>} Artifacts array with metadata
|
||||
*/
|
||||
async collectTaskToolArtifacts(bmadDir) {
|
||||
const tasks = await this.loadTaskManifest(bmadDir);
|
||||
const tools = await this.loadToolManifest(bmadDir);
|
||||
|
||||
// Filter to only standalone items
|
||||
const standaloneTasks = tasks ? tasks.filter((t) => t.standalone === 'true' || t.standalone === true) : [];
|
||||
const standaloneTools = tools ? tools.filter((t) => t.standalone === 'true' || t.standalone === true) : [];
|
||||
|
||||
const artifacts = [];
|
||||
const bmadPrefix = `${BMAD_FOLDER_NAME}/`;
|
||||
|
||||
// Collect task artifacts
|
||||
for (const task of standaloneTasks) {
|
||||
let taskPath = (task.path || '').replaceAll('\\', '/');
|
||||
// Convert absolute paths to relative paths
|
||||
if (path.isAbsolute(taskPath)) {
|
||||
taskPath = path.relative(bmadDir, taskPath).replaceAll('\\', '/');
|
||||
}
|
||||
// Remove _bmad/ prefix if present to get relative path within bmad folder
|
||||
if (taskPath.startsWith(bmadPrefix)) {
|
||||
taskPath = taskPath.slice(bmadPrefix.length);
|
||||
}
|
||||
|
||||
const taskExt = path.extname(taskPath) || '.md';
|
||||
artifacts.push({
|
||||
type: 'task',
|
||||
name: task.name,
|
||||
displayName: task.displayName || task.name,
|
||||
description: task.description || `Execute ${task.displayName || task.name}`,
|
||||
module: task.module,
|
||||
// Use forward slashes for cross-platform consistency (not path.join which uses backslashes on Windows)
|
||||
relativePath: `${task.module}/tasks/${task.name}${taskExt}`,
|
||||
path: taskPath,
|
||||
});
|
||||
}
|
||||
|
||||
// Collect tool artifacts
|
||||
for (const tool of standaloneTools) {
|
||||
let toolPath = (tool.path || '').replaceAll('\\', '/');
|
||||
// Convert absolute paths to relative paths
|
||||
if (path.isAbsolute(toolPath)) {
|
||||
toolPath = path.relative(bmadDir, toolPath).replaceAll('\\', '/');
|
||||
}
|
||||
// Remove _bmad/ prefix if present to get relative path within bmad folder
|
||||
if (toolPath.startsWith(bmadPrefix)) {
|
||||
toolPath = toolPath.slice(bmadPrefix.length);
|
||||
}
|
||||
|
||||
const toolExt = path.extname(toolPath) || '.md';
|
||||
artifacts.push({
|
||||
type: 'tool',
|
||||
name: tool.name,
|
||||
displayName: tool.displayName || tool.name,
|
||||
description: tool.description || `Execute ${tool.displayName || tool.name}`,
|
||||
module: tool.module,
|
||||
// Use forward slashes for cross-platform consistency (not path.join which uses backslashes on Windows)
|
||||
relativePath: `${tool.module}/tools/${tool.name}${toolExt}`,
|
||||
path: toolPath,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
artifacts,
|
||||
counts: {
|
||||
tasks: standaloneTasks.length,
|
||||
tools: standaloneTools.length,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate task and tool commands from manifest CSVs
|
||||
* @param {string} projectDir - Project directory
|
||||
|
|
@ -65,13 +151,40 @@ class TaskToolCommandGenerator {
|
|||
const description = item.description || `Execute ${item.displayName || item.name}`;
|
||||
|
||||
// Convert path to use {project-root} placeholder
|
||||
// Handle undefined/missing path by constructing from module and name
|
||||
let itemPath = item.path;
|
||||
if (itemPath && typeof itemPath === 'string' && itemPath.startsWith('bmad/')) {
|
||||
itemPath = `{project-root}/${itemPath}`;
|
||||
if (!itemPath || typeof itemPath !== 'string') {
|
||||
// Fallback: construct path from module and name if path is missing
|
||||
const typePlural = type === 'task' ? 'tasks' : 'tools';
|
||||
itemPath = `{project-root}/${this.bmadFolderName}/${item.module}/${typePlural}/${item.name}.md`;
|
||||
} else {
|
||||
// Normalize path separators to forward slashes
|
||||
itemPath = itemPath.replaceAll('\\', '/');
|
||||
|
||||
// Extract relative path from absolute paths (Windows or Unix)
|
||||
// Look for _bmad/ or bmad/ in the path and extract everything after it
|
||||
// Match patterns like: /_bmad/core/tasks/... or /bmad/core/tasks/...
|
||||
// Use [/\\] to handle both Unix forward slashes and Windows backslashes,
|
||||
// and also paths without a leading separator (e.g., C:/_bmad/...)
|
||||
const bmadMatch = itemPath.match(/[/\\]_bmad[/\\](.+)$/) || itemPath.match(/[/\\]bmad[/\\](.+)$/);
|
||||
if (bmadMatch) {
|
||||
// Found /_bmad/ or /bmad/ - use relative path after it
|
||||
itemPath = `{project-root}/${this.bmadFolderName}/${bmadMatch[1]}`;
|
||||
} else if (itemPath.startsWith(`${BMAD_FOLDER_NAME}/`)) {
|
||||
// Relative path starting with _bmad/
|
||||
itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(BMAD_FOLDER_NAME.length + 1)}`;
|
||||
} else if (itemPath.startsWith('bmad/')) {
|
||||
// Relative path starting with bmad/
|
||||
itemPath = `{project-root}/${this.bmadFolderName}/${itemPath.slice(5)}`;
|
||||
} else if (!itemPath.startsWith('{project-root}')) {
|
||||
// For other relative paths, prefix with project root and bmad folder
|
||||
itemPath = `{project-root}/${this.bmadFolderName}/${itemPath}`;
|
||||
}
|
||||
}
|
||||
|
||||
return `---
|
||||
description: '${description.replaceAll("'", "''")}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# ${item.displayName || item.name}
|
||||
|
|
@ -186,7 +299,7 @@ Follow all instructions in the ${type} file exactly as written.
|
|||
// Generate command files for tasks
|
||||
for (const task of standaloneTasks) {
|
||||
const commandContent = this.generateCommandContent(task, 'task');
|
||||
// Use underscore format: bmad_bmm_name.md
|
||||
// Use dash format: bmad-bmm-name.md
|
||||
const flatName = toDashPath(`${task.module}/tasks/${task.name}.md`);
|
||||
const commandPath = path.join(baseCommandsDir, flatName);
|
||||
await fs.ensureDir(path.dirname(commandPath));
|
||||
|
|
@ -197,7 +310,7 @@ Follow all instructions in the ${type} file exactly as written.
|
|||
// Generate command files for tools
|
||||
for (const tool of standaloneTools) {
|
||||
const commandContent = this.generateCommandContent(tool, 'tool');
|
||||
// Use underscore format: bmad_bmm_name.md
|
||||
// Use dash format: bmad-bmm-name.md
|
||||
const flatName = toDashPath(`${tool.module}/tools/${tool.name}.md`);
|
||||
const commandPath = path.join(baseCommandsDir, flatName);
|
||||
await fs.ensureDir(path.dirname(commandPath));
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ const path = require('node:path');
|
|||
const fs = require('fs-extra');
|
||||
const csv = require('csv-parse/sync');
|
||||
const chalk = require('chalk');
|
||||
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName } = require('./path-utils');
|
||||
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
|
||||
|
||||
/**
|
||||
* Generates command files for each workflow in the manifest
|
||||
*/
|
||||
class WorkflowCommandGenerator {
|
||||
constructor(bmadFolderName = 'bmad') {
|
||||
constructor(bmadFolderName = BMAD_FOLDER_NAME) {
|
||||
this.templatePath = path.join(__dirname, '../templates/workflow-command-template.md');
|
||||
this.bmadFolderName = bmadFolderName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
---
|
||||
|
||||
# {{name}}
|
||||
|
||||
Read the entire task file at: {project-root}/{{bmadFolderName}}/{{path}}
|
||||
|
||||
Follow all instructions in the task file exactly as written.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
---
|
||||
|
||||
# {{name}}
|
||||
|
||||
Read the entire tool file at: {project-root}/{{bmadFolderName}}/{{path}}
|
||||
|
||||
Follow all instructions in the tool file exactly as written.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
name: '{{name}}'
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
description = "Executes the {{name}} task from the BMAD Method."
|
||||
prompt = """
|
||||
Execute the BMAD '{{name}}' task.
|
||||
|
||||
TASK INSTRUCTIONS:
|
||||
1. LOAD the task file from {project-root}/{{bmadFolderName}}/{{path}}
|
||||
2. READ its entire contents
|
||||
3. FOLLOW every instruction precisely as specified
|
||||
|
||||
TASK FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
||||
"""
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
description = "Executes the {{name}} tool from the BMAD Method."
|
||||
prompt = """
|
||||
Execute the BMAD '{{name}}' tool.
|
||||
|
||||
TOOL INSTRUCTIONS:
|
||||
1. LOAD the tool file from {project-root}/{{bmadFolderName}}/{{path}}
|
||||
2. READ its entire contents
|
||||
3. FOLLOW every instruction precisely as specified
|
||||
|
||||
TOOL FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
||||
"""
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
description: '{{description}}'
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
description: '{{description}}'
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{{workflow_path}}, READ its entire contents and follow its directions exactly!
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ const { XmlHandler } = require('../../../lib/xml-handler');
|
|||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||
const { filterCustomizationData } = require('../../../lib/agent/compiler');
|
||||
const { ExternalModuleManager } = require('./external-manager');
|
||||
const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
|
||||
|
||||
/**
|
||||
* Manages the installation, updating, and removal of BMAD modules.
|
||||
|
|
@ -27,7 +28,7 @@ const { ExternalModuleManager } = require('./external-manager');
|
|||
class ModuleManager {
|
||||
constructor(options = {}) {
|
||||
this.xmlHandler = new XmlHandler();
|
||||
this.bmadFolderName = 'bmad'; // Default, can be overridden
|
||||
this.bmadFolderName = BMAD_FOLDER_NAME; // Default, can be overridden
|
||||
this.customModulePaths = new Map(); // Initialize custom module paths
|
||||
this.externalModuleManager = new ExternalModuleManager(); // For external official modules
|
||||
}
|
||||
|
|
@ -416,7 +417,7 @@ class ModuleManager {
|
|||
if (needsDependencyInstall || wasNewClone || nodeModulesMissing) {
|
||||
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
||||
try {
|
||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress', {
|
||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress --legacy-peer-deps', {
|
||||
cwd: moduleCacheDir,
|
||||
stdio: 'pipe',
|
||||
timeout: 120_000, // 2 minute timeout
|
||||
|
|
@ -441,7 +442,7 @@ class ModuleManager {
|
|||
if (packageJsonNewer) {
|
||||
const installSpinner = ora(`Installing dependencies for ${moduleInfo.name}...`).start();
|
||||
try {
|
||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress', {
|
||||
execSync('npm install --production --no-audit --no-fund --prefer-offline --no-progress --legacy-peer-deps', {
|
||||
cwd: moduleCacheDir,
|
||||
stdio: 'pipe',
|
||||
timeout: 120_000, // 2 minute timeout
|
||||
|
|
@ -870,7 +871,7 @@ class ModuleManager {
|
|||
for (const agentFile of agentFiles) {
|
||||
if (!agentFile.endsWith('.agent.yaml')) continue;
|
||||
|
||||
const relativePath = path.relative(sourceAgentsPath, agentFile);
|
||||
const relativePath = path.relative(sourceAgentsPath, agentFile).split(path.sep).join('/');
|
||||
const targetDir = path.join(targetAgentsPath, path.dirname(relativePath));
|
||||
|
||||
await fs.ensureDir(targetDir);
|
||||
|
|
|
|||
|
|
@ -121,9 +121,10 @@ class ActivationBuilder {
|
|||
|
||||
// Calculate final step numbers
|
||||
const menuStep = currentStepNum;
|
||||
const haltStep = currentStepNum + 1;
|
||||
const inputStep = currentStepNum + 2;
|
||||
const executeStep = currentStepNum + 3;
|
||||
const helpStep = currentStepNum + 1;
|
||||
const haltStep = currentStepNum + 2;
|
||||
const inputStep = currentStepNum + 3;
|
||||
const executeStep = currentStepNum + 4;
|
||||
|
||||
// Replace placeholders
|
||||
const processed = stepsTemplate
|
||||
|
|
@ -131,6 +132,7 @@ class ActivationBuilder {
|
|||
.replace('{{module}}', metadata.module || 'core') // Fixed to use {{module}}
|
||||
.replace('{AGENT_SPECIFIC_STEPS}', agentStepsXml)
|
||||
.replace('{MENU_STEP}', menuStep.toString())
|
||||
.replace('{HELP_STEP}', helpStep.toString())
|
||||
.replace('{HALT_STEP}', haltStep.toString())
|
||||
.replace('{INPUT_STEP}', inputStep.toString())
|
||||
.replace('{EXECUTE_STEP}', executeStep.toString());
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ function findBmadConfig(startPath = process.cwd()) {
|
|||
* @returns {string} Resolved path
|
||||
*/
|
||||
function resolvePath(pathStr, context) {
|
||||
return pathStr.replaceAll('{project-root}', context.projectRoot).replaceAll('{bmad-folder}', context_bmadFolder);
|
||||
return pathStr.replaceAll('{project-root}', context.projectRoot).replaceAll('{bmad-folder}', context.bmadFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
*/
|
||||
|
||||
let _clack = null;
|
||||
let _clackCore = null;
|
||||
let _picocolors = null;
|
||||
|
||||
/**
|
||||
* Lazy-load @clack/prompts (ESM module)
|
||||
|
|
@ -20,6 +22,28 @@ async function getClack() {
|
|||
return _clack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy-load @clack/core (ESM module)
|
||||
* @returns {Promise<Object>} The clack core module
|
||||
*/
|
||||
async function getClackCore() {
|
||||
if (!_clackCore) {
|
||||
_clackCore = await import('@clack/core');
|
||||
}
|
||||
return _clackCore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy-load picocolors
|
||||
* @returns {Promise<Object>} The picocolors module
|
||||
*/
|
||||
async function getPicocolors() {
|
||||
if (!_picocolors) {
|
||||
_picocolors = (await import('picocolors')).default;
|
||||
}
|
||||
return _picocolors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user cancellation gracefully
|
||||
* @param {any} value - The value to check
|
||||
|
|
@ -191,6 +215,118 @@ async function groupMultiselect(options) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default filter function for autocomplete - case-insensitive label matching
|
||||
* @param {string} search - Search string
|
||||
* @param {Object} option - Option object with label
|
||||
* @returns {boolean} Whether the option matches
|
||||
*/
|
||||
function defaultAutocompleteFilter(search, option) {
|
||||
const label = option.label ?? String(option.value ?? '');
|
||||
return label.toLowerCase().includes(search.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Autocomplete multi-select prompt with type-ahead filtering
|
||||
* Custom implementation that always shows "Space/Tab:" in the hint
|
||||
* @param {Object} options - Prompt options
|
||||
* @param {string} options.message - The question to ask
|
||||
* @param {Array} options.options - Array of choices [{label, value, hint?}]
|
||||
* @param {string} [options.placeholder] - Placeholder text for search input
|
||||
* @param {Array} [options.initialValues] - Array of initially selected values
|
||||
* @param {boolean} [options.required=false] - Whether at least one must be selected
|
||||
* @param {number} [options.maxItems=5] - Maximum visible items in scrollable list
|
||||
* @param {Function} [options.filter] - Custom filter function (search, option) => boolean
|
||||
* @returns {Promise<Array>} Array of selected values
|
||||
*/
|
||||
async function autocompleteMultiselect(options) {
|
||||
const core = await getClackCore();
|
||||
const clack = await getClack();
|
||||
const color = await getPicocolors();
|
||||
|
||||
const filterFn = options.filter ?? defaultAutocompleteFilter;
|
||||
|
||||
const prompt = new core.AutocompletePrompt({
|
||||
options: options.options,
|
||||
multiple: true,
|
||||
filter: filterFn,
|
||||
validate: () => {
|
||||
if (options.required && prompt.selectedValues.length === 0) {
|
||||
return 'Please select at least one item';
|
||||
}
|
||||
},
|
||||
initialValue: options.initialValues,
|
||||
render() {
|
||||
const barColor = this.state === 'error' ? color.yellow : color.cyan;
|
||||
const bar = barColor(clack.S_BAR);
|
||||
const barEnd = barColor(clack.S_BAR_END);
|
||||
|
||||
const title = `${color.gray(clack.S_BAR)}\n${clack.symbol(this.state)} ${options.message}\n`;
|
||||
|
||||
const userInput = this.userInput;
|
||||
const placeholder = options.placeholder || 'Type to search...';
|
||||
const hasPlaceholder = userInput === '' && placeholder !== undefined;
|
||||
|
||||
// Show placeholder or user input with cursor
|
||||
const searchDisplay =
|
||||
this.isNavigating || hasPlaceholder ? color.dim(hasPlaceholder ? placeholder : userInput) : this.userInputWithCursor;
|
||||
|
||||
const allOptions = this.options;
|
||||
const matchCount =
|
||||
this.filteredOptions.length === allOptions.length
|
||||
? ''
|
||||
: color.dim(` (${this.filteredOptions.length} match${this.filteredOptions.length === 1 ? '' : 'es'})`);
|
||||
|
||||
// Render option with checkbox
|
||||
const renderOption = (opt, isHighlighted) => {
|
||||
const isSelected = this.selectedValues.includes(opt.value);
|
||||
const label = opt.label ?? String(opt.value ?? '');
|
||||
const hintText = opt.hint && opt.value === this.focusedValue ? color.dim(` (${opt.hint})`) : '';
|
||||
const checkbox = isSelected ? color.green(clack.S_CHECKBOX_SELECTED) : color.dim(clack.S_CHECKBOX_INACTIVE);
|
||||
return isHighlighted ? `${checkbox} ${label}${hintText}` : `${checkbox} ${color.dim(label)}`;
|
||||
};
|
||||
|
||||
switch (this.state) {
|
||||
case 'submit': {
|
||||
return `${title}${color.gray(clack.S_BAR)} ${color.dim(`${this.selectedValues.length} items selected`)}`;
|
||||
}
|
||||
|
||||
case 'cancel': {
|
||||
return `${title}${color.gray(clack.S_BAR)} ${color.strikethrough(color.dim(userInput))}`;
|
||||
}
|
||||
|
||||
default: {
|
||||
// Always show "SPACE:" regardless of isNavigating state
|
||||
const hints = [`${color.dim('↑/↓')} to navigate`, `${color.dim('TAB/SPACE:')} select`, `${color.dim('ENTER:')} confirm`];
|
||||
|
||||
const noMatchesLine = this.filteredOptions.length === 0 && userInput ? [`${bar} ${color.yellow('No matches found')}`] : [];
|
||||
|
||||
const errorLine = this.state === 'error' ? [`${bar} ${color.yellow(this.error)}`] : [];
|
||||
|
||||
const headerLines = [...`${title}${bar}`.split('\n'), `${bar} ${searchDisplay}${matchCount}`, ...noMatchesLine, ...errorLine];
|
||||
|
||||
const footerLines = [`${bar} ${color.dim(hints.join(' • '))}`, `${barEnd}`];
|
||||
|
||||
const optionLines = clack.limitOptions({
|
||||
cursor: this.cursor,
|
||||
options: this.filteredOptions,
|
||||
style: renderOption,
|
||||
maxItems: options.maxItems || 5,
|
||||
output: options.output,
|
||||
rowPadding: headerLines.length + footerLines.length,
|
||||
});
|
||||
|
||||
return [...headerLines, ...optionLines.map((line) => `${bar} ${line}`), ...footerLines].join('\n');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const result = await prompt.prompt();
|
||||
await handleCancel(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm prompt (replaces Inquirer 'confirm' type)
|
||||
* @param {Object} options - Prompt options
|
||||
|
|
@ -211,7 +347,12 @@ async function confirm(options) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Text input prompt (replaces Inquirer 'input' type)
|
||||
* Text input prompt with Tab-to-fill-placeholder support (replaces Inquirer 'input' type)
|
||||
*
|
||||
* This custom implementation restores the Tab-to-fill-placeholder behavior that was
|
||||
* intentionally removed in @clack/prompts v1.0.0 (placeholder became purely visual).
|
||||
* Uses @clack/core's TextPrompt primitive with custom key handling.
|
||||
*
|
||||
* @param {Object} options - Prompt options
|
||||
* @param {string} options.message - The question to ask
|
||||
* @param {string} [options.default] - Default value
|
||||
|
|
@ -220,20 +361,64 @@ async function confirm(options) {
|
|||
* @returns {Promise<string>} User's input
|
||||
*/
|
||||
async function text(options) {
|
||||
const clack = await getClack();
|
||||
const core = await getClackCore();
|
||||
const color = await getPicocolors();
|
||||
|
||||
// Use default as placeholder if placeholder not explicitly provided
|
||||
// This shows the default value as grayed-out hint text
|
||||
const placeholder = options.placeholder === undefined ? options.default : options.placeholder;
|
||||
const defaultValue = options.default;
|
||||
|
||||
const result = await clack.text({
|
||||
message: options.message,
|
||||
defaultValue: options.default,
|
||||
placeholder: typeof placeholder === 'string' ? placeholder : undefined,
|
||||
const prompt = new core.TextPrompt({
|
||||
defaultValue,
|
||||
validate: options.validate,
|
||||
render() {
|
||||
const title = `${color.gray('◆')} ${options.message}`;
|
||||
|
||||
// Show placeholder as dim text when input is empty
|
||||
let valueDisplay;
|
||||
if (this.state === 'error') {
|
||||
valueDisplay = color.yellow(this.userInputWithCursor);
|
||||
} else if (this.userInput) {
|
||||
valueDisplay = this.userInputWithCursor;
|
||||
} else if (placeholder) {
|
||||
// Show placeholder with cursor indicator when empty
|
||||
valueDisplay = `${color.inverse(color.hidden('_'))}${color.dim(placeholder)}`;
|
||||
} else {
|
||||
valueDisplay = color.inverse(color.hidden('_'));
|
||||
}
|
||||
|
||||
const bar = color.gray('│');
|
||||
|
||||
// Handle different states
|
||||
if (this.state === 'submit') {
|
||||
return `${color.gray('◇')} ${options.message}\n${bar} ${color.dim(this.value || defaultValue || '')}`;
|
||||
}
|
||||
|
||||
if (this.state === 'cancel') {
|
||||
return `${color.gray('◇')} ${options.message}\n${bar} ${color.strikethrough(color.dim(this.userInput || ''))}`;
|
||||
}
|
||||
|
||||
if (this.state === 'error') {
|
||||
return `${color.yellow('▲')} ${options.message}\n${bar} ${valueDisplay}\n${color.yellow('│')} ${color.yellow(this.error)}`;
|
||||
}
|
||||
|
||||
return `${title}\n${bar} ${valueDisplay}\n${bar}`;
|
||||
},
|
||||
});
|
||||
|
||||
// Add Tab key handler to fill placeholder into input
|
||||
prompt.on('key', (char) => {
|
||||
if (char === '\t' && placeholder && !prompt.userInput) {
|
||||
// Use _setUserInput with write=true to populate the readline and update internal state
|
||||
prompt._setUserInput(placeholder, true);
|
||||
}
|
||||
});
|
||||
|
||||
const result = await prompt.prompt();
|
||||
await handleCancel(result);
|
||||
|
||||
// TextPrompt's finalize handler already applies defaultValue for empty input
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -423,6 +608,7 @@ module.exports = {
|
|||
select,
|
||||
multiselect,
|
||||
groupMultiselect,
|
||||
autocompleteMultiselect,
|
||||
confirm,
|
||||
text,
|
||||
password,
|
||||
|
|
|
|||
|
|
@ -344,6 +344,9 @@ class UI {
|
|||
|
||||
/**
|
||||
* Prompt for tool/IDE selection (called after module configuration)
|
||||
* Uses a split prompt approach:
|
||||
* 1. Recommended tools - standard multiselect for 3 preferred tools
|
||||
* 2. Additional tools - autocompleteMultiselect with search capability
|
||||
* @param {string} projectDir - Project directory to check for existing IDEs
|
||||
* @returns {Object} Tool configuration
|
||||
*/
|
||||
|
|
@ -366,95 +369,123 @@ class UI {
|
|||
const preferredIdes = ideManager.getPreferredIdes();
|
||||
const otherIdes = ideManager.getOtherIdes();
|
||||
|
||||
// Build grouped options object for groupMultiselect
|
||||
const groupedOptions = {};
|
||||
const processedIdes = new Set();
|
||||
const initialValues = [];
|
||||
// Determine which configured IDEs are in "preferred" vs "other" categories
|
||||
const configuredPreferred = configuredIdes.filter((id) => preferredIdes.some((ide) => ide.value === id));
|
||||
const configuredOther = configuredIdes.filter((id) => otherIdes.some((ide) => ide.value === id));
|
||||
|
||||
// First, add previously configured IDEs, marked with ✅
|
||||
// Warn about previously configured tools that are no longer available
|
||||
const allKnownValues = new Set([...preferredIdes, ...otherIdes].map((ide) => ide.value));
|
||||
const unknownTools = configuredIdes.filter((id) => id && typeof id === 'string' && !allKnownValues.has(id));
|
||||
if (unknownTools.length > 0) {
|
||||
console.log(chalk.yellow(`⚠️ Previously configured tools are no longer available: ${unknownTools.join(', ')}`));
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// UPGRADE PATH: If tools already configured, show all tools with configured at top
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
if (configuredIdes.length > 0) {
|
||||
const configuredGroup = [];
|
||||
for (const ideValue of configuredIdes) {
|
||||
// Skip empty or invalid IDE values
|
||||
if (!ideValue || typeof ideValue !== 'string') {
|
||||
continue;
|
||||
}
|
||||
const allTools = [...preferredIdes, ...otherIdes];
|
||||
|
||||
// Find the IDE in either preferred or other lists
|
||||
const preferredIde = preferredIdes.find((ide) => ide.value === ideValue);
|
||||
const otherIde = otherIdes.find((ide) => ide.value === ideValue);
|
||||
const ide = preferredIde || otherIde;
|
||||
// Sort: configured tools first, then preferred, then others
|
||||
const sortedTools = [
|
||||
...allTools.filter((ide) => configuredIdes.includes(ide.value)),
|
||||
...allTools.filter((ide) => !configuredIdes.includes(ide.value)),
|
||||
];
|
||||
|
||||
if (ide) {
|
||||
configuredGroup.push({
|
||||
label: `${ide.name} ✅`,
|
||||
value: ide.value,
|
||||
const upgradeOptions = sortedTools.map((ide) => {
|
||||
const isConfigured = configuredIdes.includes(ide.value);
|
||||
const isPreferred = preferredIdes.some((p) => p.value === ide.value);
|
||||
let label = ide.name;
|
||||
if (isPreferred) label += ' ⭐';
|
||||
if (isConfigured) label += ' ✅';
|
||||
return { label, value: ide.value };
|
||||
});
|
||||
processedIdes.add(ide.value);
|
||||
initialValues.push(ide.value); // Pre-select configured IDEs
|
||||
} else {
|
||||
// Warn about unrecognized IDE (but don't fail)
|
||||
console.log(chalk.yellow(`⚠️ Previously configured IDE '${ideValue}' is no longer available`));
|
||||
}
|
||||
}
|
||||
if (configuredGroup.length > 0) {
|
||||
groupedOptions['Previously Configured'] = configuredGroup;
|
||||
}
|
||||
|
||||
// Sort initialValues to match display order
|
||||
const sortedInitialValues = sortedTools.filter((ide) => configuredIdes.includes(ide.value)).map((ide) => ide.value);
|
||||
|
||||
const upgradeSelected = await prompts.autocompleteMultiselect({
|
||||
message: 'Integrate with',
|
||||
options: upgradeOptions,
|
||||
initialValues: sortedInitialValues,
|
||||
required: false,
|
||||
maxItems: 8,
|
||||
});
|
||||
|
||||
const selectedIdes = upgradeSelected || [];
|
||||
|
||||
if (selectedIdes.length === 0) {
|
||||
console.log('');
|
||||
const confirmNoTools = await prompts.confirm({
|
||||
message: 'No tools selected. Continue without installing any tools?',
|
||||
default: false,
|
||||
});
|
||||
|
||||
if (!confirmNoTools) {
|
||||
return this.promptToolSelection(projectDir);
|
||||
}
|
||||
|
||||
// Add preferred tools (excluding already processed)
|
||||
const remainingPreferred = preferredIdes.filter((ide) => !processedIdes.has(ide.value));
|
||||
if (remainingPreferred.length > 0) {
|
||||
groupedOptions['Recommended Tools'] = remainingPreferred.map((ide) => {
|
||||
processedIdes.add(ide.value);
|
||||
return { ides: [], skipIde: true };
|
||||
}
|
||||
|
||||
// Display selected tools
|
||||
this.displaySelectedTools(selectedIdes, preferredIdes, allTools);
|
||||
|
||||
return { ides: selectedIdes, skipIde: false };
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// NEW INSTALL: Show all tools with search
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
const allTools = [...preferredIdes, ...otherIdes];
|
||||
|
||||
const allToolOptions = allTools.map((ide) => {
|
||||
const isPreferred = preferredIdes.some((p) => p.value === ide.value);
|
||||
let label = ide.name;
|
||||
if (isPreferred) label += ' ⭐';
|
||||
return {
|
||||
label: `${ide.name} ⭐`,
|
||||
label,
|
||||
value: ide.value,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Add other tools (excluding already processed)
|
||||
const remainingOther = otherIdes.filter((ide) => !processedIdes.has(ide.value));
|
||||
if (remainingOther.length > 0) {
|
||||
groupedOptions['Additional Tools'] = remainingOther.map((ide) => ({
|
||||
label: ide.name,
|
||||
value: ide.value,
|
||||
}));
|
||||
}
|
||||
|
||||
// Add standalone "None" option at the end
|
||||
groupedOptions[' '] = [
|
||||
{
|
||||
label: '⚠ None - I am not installing any tools',
|
||||
value: '__NONE__',
|
||||
},
|
||||
];
|
||||
|
||||
let selectedIdes = [];
|
||||
|
||||
selectedIdes = await prompts.groupMultiselect({
|
||||
message: `Select tools to configure ${chalk.dim('(↑/↓ navigates, SPACE toggles, ENTER to confirm)')}:`,
|
||||
options: groupedOptions,
|
||||
initialValues: initialValues.length > 0 ? initialValues : undefined,
|
||||
required: true,
|
||||
selectableGroups: false,
|
||||
const selectedIdes = await prompts.autocompleteMultiselect({
|
||||
message: 'Select tools:',
|
||||
options: allToolOptions,
|
||||
initialValues: configuredIdes.length > 0 ? configuredIdes : undefined,
|
||||
required: false,
|
||||
maxItems: 8,
|
||||
});
|
||||
|
||||
// If user selected both "__NONE__" and other tools, honor the "None" choice
|
||||
if (selectedIdes && selectedIdes.includes('__NONE__') && selectedIdes.length > 1) {
|
||||
console.log();
|
||||
console.log(chalk.yellow('⚠️ "None - I am not installing any tools" was selected, so no tools will be configured.'));
|
||||
console.log();
|
||||
selectedIdes = [];
|
||||
} else if (selectedIdes && selectedIdes.includes('__NONE__')) {
|
||||
// Only "__NONE__" was selected
|
||||
selectedIdes = [];
|
||||
const allSelectedIdes = selectedIdes || [];
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// STEP 3: Confirm if no tools selected
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
if (allSelectedIdes.length === 0) {
|
||||
console.log('');
|
||||
const confirmNoTools = await prompts.confirm({
|
||||
message: 'No tools selected. Continue without installing any tools?',
|
||||
default: false,
|
||||
});
|
||||
|
||||
if (!confirmNoTools) {
|
||||
// User wants to select tools - recurse
|
||||
return this.promptToolSelection(projectDir);
|
||||
}
|
||||
|
||||
return {
|
||||
ides: selectedIdes || [],
|
||||
skipIde: !selectedIdes || selectedIdes.length === 0,
|
||||
ides: [],
|
||||
skipIde: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Display selected tools
|
||||
this.displaySelectedTools(allSelectedIdes, preferredIdes, allTools);
|
||||
|
||||
return {
|
||||
ides: allSelectedIdes,
|
||||
skipIde: allSelectedIdes.length === 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1655,6 +1686,27 @@ class UI {
|
|||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display list of selected tools after IDE selection
|
||||
* @param {Array} selectedIdes - Array of selected IDE values
|
||||
* @param {Array} preferredIdes - Array of preferred IDE objects
|
||||
* @param {Array} allTools - Array of all tool objects
|
||||
*/
|
||||
displaySelectedTools(selectedIdes, preferredIdes, allTools) {
|
||||
if (selectedIdes.length === 0) return;
|
||||
|
||||
const preferredValues = new Set(preferredIdes.map((ide) => ide.value));
|
||||
|
||||
console.log('');
|
||||
console.log(chalk.dim(' Selected tools:'));
|
||||
for (const ideValue of selectedIdes) {
|
||||
const tool = allTools.find((t) => t.value === ideValue);
|
||||
const name = tool?.name || ideValue;
|
||||
const marker = preferredValues.has(ideValue) ? ' ⭐' : '';
|
||||
console.log(chalk.dim(` • ${name}${marker}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { UI };
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ async function main(customProjectRoot) {
|
|||
const project_root = customProjectRoot || path.join(__dirname, '..');
|
||||
|
||||
// Find all agent files
|
||||
const agentFiles = await glob('src/{core,modules/*}/agents/*.agent.yaml', {
|
||||
const agentFiles = await glob('src/{core,bmm}/agents/**/*.agent.yaml', {
|
||||
cwd: project_root,
|
||||
absolute: true,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,480 @@
|
|||
/**
|
||||
* File Reference Validator
|
||||
*
|
||||
* Validates cross-file references in BMAD source files (agents, workflows, tasks, steps).
|
||||
* Catches broken file paths, missing referenced files, and absolute path leaks.
|
||||
*
|
||||
* What it checks:
|
||||
* - {project-root}/_bmad/ references in YAML and markdown resolve to real src/ files
|
||||
* - Relative path references (./file.md, ../data/file.csv) point to existing files
|
||||
* - exec="..." and <invoke-task> targets exist
|
||||
* - Step metadata (thisStepFile, nextStepFile) references are valid
|
||||
* - Load directives (Load: `./file.md`) target existing files
|
||||
* - No absolute paths (/Users/, /home/, C:\) leak into source files
|
||||
*
|
||||
* What it does NOT check (deferred):
|
||||
* - {installed_path} variable interpolation (self-referential, low risk)
|
||||
* - {{mustache}} template variables (runtime substitution)
|
||||
* - {config_source}:key dynamic YAML dereferences
|
||||
*
|
||||
* Usage:
|
||||
* node tools/validate-file-refs.js # Warn on broken references (exit 0)
|
||||
* node tools/validate-file-refs.js --strict # Fail on broken references (exit 1)
|
||||
* node tools/validate-file-refs.js --verbose # Show all checked references
|
||||
*
|
||||
* Default mode is warning-only (exit 0) so adoption is non-disruptive.
|
||||
* Use --strict when you want CI or pre-commit to enforce valid references.
|
||||
*/
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const yaml = require('yaml');
|
||||
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
||||
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
|
||||
const VERBOSE = process.argv.includes('--verbose');
|
||||
const STRICT = process.argv.includes('--strict');
|
||||
|
||||
// --- Constants ---
|
||||
|
||||
// File extensions to scan
|
||||
const SCAN_EXTENSIONS = new Set(['.yaml', '.yml', '.md', '.xml']);
|
||||
|
||||
// Skip directories
|
||||
const SKIP_DIRS = new Set(['node_modules', '_module-installer', '.git']);
|
||||
|
||||
// Pattern: {project-root}/_bmad/ references
|
||||
const PROJECT_ROOT_REF = /\{project-root\}\/_bmad\/([^\s'"<>})\]`]+)/g;
|
||||
|
||||
// Pattern: {_bmad}/ shorthand references
|
||||
const BMAD_SHORTHAND_REF = /\{_bmad\}\/([^\s'"<>})\]`]+)/g;
|
||||
|
||||
// Pattern: exec="..." attributes
|
||||
const EXEC_ATTR = /exec="([^"]+)"/g;
|
||||
|
||||
// Pattern: <invoke-task> content
|
||||
const INVOKE_TASK = /<invoke-task>([^<]+)<\/invoke-task>/g;
|
||||
|
||||
// Pattern: relative paths in quotes
|
||||
const RELATIVE_PATH_QUOTED = /['"](\.\.\/?[^'"]+\.(?:md|yaml|yml|xml|json|csv|txt))['"]/g;
|
||||
const RELATIVE_PATH_DOT = /['"](\.\/[^'"]+\.(?:md|yaml|yml|xml|json|csv|txt))['"]/g;
|
||||
|
||||
// Pattern: step metadata
|
||||
const STEP_META = /(?:thisStepFile|nextStepFile|continueStepFile|skipToStepFile|altStepFile|workflowFile):\s*['"](\.[^'"]+)['"]/g;
|
||||
|
||||
// Pattern: Load directives
|
||||
const LOAD_DIRECTIVE = /Load[:\s]+`(\.[^`]+)`/g;
|
||||
|
||||
// Pattern: absolute path leaks
|
||||
const ABS_PATH_LEAK = /(?:\/Users\/|\/home\/|[A-Z]:\\\\)/;
|
||||
|
||||
// --- Output Escaping ---
|
||||
|
||||
function escapeAnnotation(str) {
|
||||
return str.replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
|
||||
}
|
||||
|
||||
function escapeTableCell(str) {
|
||||
return String(str).replaceAll('|', String.raw`\|`);
|
||||
}
|
||||
|
||||
// Path prefixes/patterns that only exist in installed structure, not in source
|
||||
const INSTALL_ONLY_PATHS = ['_config/'];
|
||||
|
||||
// Files that are generated at install time and don't exist in the source tree
|
||||
const INSTALL_GENERATED_FILES = ['config.yaml'];
|
||||
|
||||
// Variables that indicate a path is not statically resolvable
|
||||
const UNRESOLVABLE_VARS = [
|
||||
'{output_folder}',
|
||||
'{value}',
|
||||
'{timestamp}',
|
||||
'{config_source}:',
|
||||
'{installed_path}',
|
||||
'{shared_path}',
|
||||
'{planning_artifacts}',
|
||||
'{research_topic}',
|
||||
'{user_name}',
|
||||
'{communication_language}',
|
||||
'{epic_number}',
|
||||
'{next_epic_num}',
|
||||
'{epic_num}',
|
||||
'{part_id}',
|
||||
'{count}',
|
||||
'{date}',
|
||||
'{outputFile}',
|
||||
'{nextStepFile}',
|
||||
];
|
||||
|
||||
// --- File Discovery ---
|
||||
|
||||
function getSourceFiles(dir) {
|
||||
const files = [];
|
||||
|
||||
function walk(currentDir) {
|
||||
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (SKIP_DIRS.has(entry.name)) continue;
|
||||
|
||||
const fullPath = path.join(currentDir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
walk(fullPath);
|
||||
} else if (entry.isFile() && SCAN_EXTENSIONS.has(path.extname(entry.name))) {
|
||||
files.push(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk(dir);
|
||||
return files;
|
||||
}
|
||||
|
||||
// --- Code Block Stripping ---
|
||||
|
||||
function stripCodeBlocks(content) {
|
||||
return content.replaceAll(/```[\s\S]*?```/g, (m) => m.replaceAll(/[^\n]/g, ''));
|
||||
}
|
||||
|
||||
function stripJsonExampleBlocks(content) {
|
||||
// Strip bare JSON example blocks: { and } each on their own line.
|
||||
// These are example/template data (not real file references).
|
||||
return content.replaceAll(/^\{\s*\n(?:.*\n)*?^\}\s*$/gm, (m) => m.replaceAll(/[^\n]/g, ''));
|
||||
}
|
||||
|
||||
// --- Path Mapping ---
|
||||
|
||||
function mapInstalledToSource(refPath) {
|
||||
// Strip {project-root}/_bmad/ or {_bmad}/ prefix
|
||||
let cleaned = refPath.replace(/^\{project-root\}\/_bmad\//, '').replace(/^\{_bmad\}\//, '');
|
||||
|
||||
// Also handle bare _bmad/ prefix (seen in some invoke-task)
|
||||
cleaned = cleaned.replace(/^_bmad\//, '');
|
||||
|
||||
// Skip install-only paths (generated at install time, not in source)
|
||||
if (isInstallOnly(cleaned)) return null;
|
||||
|
||||
// core/, bmm/, and utility/ are directly under src/
|
||||
if (cleaned.startsWith('core/') || cleaned.startsWith('bmm/') || cleaned.startsWith('utility/')) {
|
||||
return path.join(SRC_DIR, cleaned);
|
||||
}
|
||||
|
||||
// Fallback: map directly under src/
|
||||
return path.join(SRC_DIR, cleaned);
|
||||
}
|
||||
|
||||
// --- Reference Extraction ---
|
||||
|
||||
function isResolvable(refStr) {
|
||||
// Skip refs containing unresolvable runtime variables
|
||||
if (refStr.includes('{{')) return false;
|
||||
for (const v of UNRESOLVABLE_VARS) {
|
||||
if (refStr.includes(v)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isInstallOnly(cleanedPath) {
|
||||
// Skip paths that only exist in the installed _bmad/ structure, not in src/
|
||||
for (const prefix of INSTALL_ONLY_PATHS) {
|
||||
if (cleanedPath.startsWith(prefix)) return true;
|
||||
}
|
||||
// Skip files that are generated during installation
|
||||
const basename = path.basename(cleanedPath);
|
||||
for (const generated of INSTALL_GENERATED_FILES) {
|
||||
if (basename === generated) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function extractYamlRefs(filePath, content) {
|
||||
const refs = [];
|
||||
|
||||
let doc;
|
||||
try {
|
||||
doc = yaml.parseDocument(content);
|
||||
} catch {
|
||||
return refs; // Skip unparseable YAML (schema validator handles this)
|
||||
}
|
||||
|
||||
function checkValue(value, range, keyPath) {
|
||||
if (typeof value !== 'string') return;
|
||||
if (!isResolvable(value)) return;
|
||||
|
||||
const line = range ? offsetToLine(content, range[0]) : undefined;
|
||||
|
||||
// Check for {project-root}/_bmad/ refs
|
||||
const prMatch = value.match(/\{project-root\}\/_bmad\/[^\s'"<>})\]`]+/);
|
||||
if (prMatch) {
|
||||
refs.push({ file: filePath, raw: prMatch[0], type: 'project-root', line, key: keyPath });
|
||||
}
|
||||
|
||||
// Check for {_bmad}/ refs
|
||||
const bmMatch = value.match(/\{_bmad\}\/[^\s'"<>})\]`]+/);
|
||||
if (bmMatch) {
|
||||
refs.push({ file: filePath, raw: bmMatch[0], type: 'project-root', line, key: keyPath });
|
||||
}
|
||||
|
||||
// Check for relative paths
|
||||
const relMatch = value.match(/^\.\.?\/[^\s'"<>})\]`]+\.(?:md|yaml|yml|xml|json|csv|txt)$/);
|
||||
if (relMatch) {
|
||||
refs.push({ file: filePath, raw: relMatch[0], type: 'relative', line, key: keyPath });
|
||||
}
|
||||
}
|
||||
|
||||
function walkNode(node, keyPath) {
|
||||
if (!node) return;
|
||||
|
||||
if (yaml.isMap(node)) {
|
||||
for (const item of node.items) {
|
||||
const key = item.key && item.key.value !== undefined ? item.key.value : '?';
|
||||
const childPath = keyPath ? `${keyPath}.${key}` : String(key);
|
||||
walkNode(item.value, childPath);
|
||||
}
|
||||
} else if (yaml.isSeq(node)) {
|
||||
for (const [i, item] of node.items.entries()) {
|
||||
walkNode(item, `${keyPath}[${i}]`);
|
||||
}
|
||||
} else if (yaml.isScalar(node)) {
|
||||
checkValue(node.value, node.range, keyPath);
|
||||
}
|
||||
}
|
||||
|
||||
walkNode(doc.contents, '');
|
||||
return refs;
|
||||
}
|
||||
|
||||
function offsetToLine(content, offset) {
|
||||
let line = 1;
|
||||
for (let i = 0; i < offset && i < content.length; i++) {
|
||||
if (content[i] === '\n') line++;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
function extractMarkdownRefs(filePath, content) {
|
||||
const refs = [];
|
||||
const stripped = stripJsonExampleBlocks(stripCodeBlocks(content));
|
||||
|
||||
function runPattern(regex, type) {
|
||||
regex.lastIndex = 0;
|
||||
let match;
|
||||
while ((match = regex.exec(stripped)) !== null) {
|
||||
const raw = match[1];
|
||||
if (!isResolvable(raw)) continue;
|
||||
refs.push({ file: filePath, raw, type, line: offsetToLine(stripped, match.index) });
|
||||
}
|
||||
}
|
||||
|
||||
// {project-root}/_bmad/ refs
|
||||
runPattern(PROJECT_ROOT_REF, 'project-root');
|
||||
|
||||
// {_bmad}/ shorthand
|
||||
runPattern(BMAD_SHORTHAND_REF, 'project-root');
|
||||
|
||||
// exec="..." attributes
|
||||
runPattern(EXEC_ATTR, 'exec-attr');
|
||||
|
||||
// <invoke-task> tags
|
||||
runPattern(INVOKE_TASK, 'invoke-task');
|
||||
|
||||
// Step metadata
|
||||
runPattern(STEP_META, 'relative');
|
||||
|
||||
// Load directives
|
||||
runPattern(LOAD_DIRECTIVE, 'relative');
|
||||
|
||||
// Relative paths in quotes
|
||||
runPattern(RELATIVE_PATH_QUOTED, 'relative');
|
||||
runPattern(RELATIVE_PATH_DOT, 'relative');
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
// --- Reference Resolution ---
|
||||
|
||||
function resolveRef(ref) {
|
||||
if (ref.type === 'project-root') {
|
||||
return mapInstalledToSource(ref.raw);
|
||||
}
|
||||
|
||||
if (ref.type === 'relative') {
|
||||
return path.resolve(path.dirname(ref.file), ref.raw);
|
||||
}
|
||||
|
||||
if (ref.type === 'exec-attr') {
|
||||
let execPath = ref.raw;
|
||||
if (execPath.includes('{project-root}')) {
|
||||
return mapInstalledToSource(execPath);
|
||||
}
|
||||
if (execPath.includes('{_bmad}')) {
|
||||
return mapInstalledToSource(execPath);
|
||||
}
|
||||
if (execPath.startsWith('_bmad/')) {
|
||||
return mapInstalledToSource(execPath);
|
||||
}
|
||||
// Relative exec path
|
||||
return path.resolve(path.dirname(ref.file), execPath);
|
||||
}
|
||||
|
||||
if (ref.type === 'invoke-task') {
|
||||
// Extract file path from invoke-task content
|
||||
const prMatch = ref.raw.match(/\{project-root\}\/_bmad\/([^\s'"<>})\]`]+)/);
|
||||
if (prMatch) return mapInstalledToSource(prMatch[0]);
|
||||
|
||||
const bmMatch = ref.raw.match(/\{_bmad\}\/([^\s'"<>})\]`]+)/);
|
||||
if (bmMatch) return mapInstalledToSource(bmMatch[0]);
|
||||
|
||||
const bareMatch = ref.raw.match(/_bmad\/([^\s'"<>})\]`]+)/);
|
||||
if (bareMatch) return mapInstalledToSource(bareMatch[0]);
|
||||
|
||||
return null; // Can't resolve — skip
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- Absolute Path Leak Detection ---
|
||||
|
||||
function checkAbsolutePathLeaks(filePath, content) {
|
||||
const leaks = [];
|
||||
const stripped = stripCodeBlocks(content);
|
||||
const lines = stripped.split('\n');
|
||||
|
||||
for (const [i, line] of lines.entries()) {
|
||||
if (ABS_PATH_LEAK.test(line)) {
|
||||
leaks.push({ file: filePath, line: i + 1, content: line.trim() });
|
||||
}
|
||||
}
|
||||
|
||||
return leaks;
|
||||
}
|
||||
|
||||
// --- Main ---
|
||||
|
||||
console.log(`\nValidating file references in: ${SRC_DIR}`);
|
||||
console.log(`Mode: ${STRICT ? 'STRICT (exit 1 on issues)' : 'WARNING (exit 0)'}${VERBOSE ? ' + VERBOSE' : ''}\n`);
|
||||
|
||||
const files = getSourceFiles(SRC_DIR);
|
||||
console.log(`Found ${files.length} source files\n`);
|
||||
|
||||
let totalRefs = 0;
|
||||
let brokenRefs = 0;
|
||||
let totalLeaks = 0;
|
||||
let filesWithIssues = 0;
|
||||
const allIssues = []; // Collect for $GITHUB_STEP_SUMMARY
|
||||
|
||||
for (const filePath of files) {
|
||||
const relativePath = path.relative(PROJECT_ROOT, filePath);
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const ext = path.extname(filePath);
|
||||
|
||||
// Extract references
|
||||
let refs;
|
||||
if (ext === '.yaml' || ext === '.yml') {
|
||||
refs = extractYamlRefs(filePath, content);
|
||||
} else {
|
||||
refs = extractMarkdownRefs(filePath, content);
|
||||
}
|
||||
|
||||
// Resolve and check
|
||||
const broken = [];
|
||||
|
||||
if (VERBOSE && refs.length > 0) {
|
||||
console.log(`\n${relativePath}`);
|
||||
}
|
||||
|
||||
for (const ref of refs) {
|
||||
totalRefs++;
|
||||
const resolved = resolveRef(ref);
|
||||
|
||||
if (resolved && !fs.existsSync(resolved)) {
|
||||
// For paths without extensions, also check if it's a directory
|
||||
const hasExt = path.extname(resolved) !== '';
|
||||
if (!hasExt) {
|
||||
// Could be a directory reference — skip if not clearly a file
|
||||
continue;
|
||||
}
|
||||
broken.push({ ref, resolved: path.relative(PROJECT_ROOT, resolved) });
|
||||
brokenRefs++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (VERBOSE && resolved) {
|
||||
console.log(` [OK] ${ref.raw}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Check absolute path leaks
|
||||
const leaks = checkAbsolutePathLeaks(filePath, content);
|
||||
totalLeaks += leaks.length;
|
||||
|
||||
// Report issues for this file
|
||||
if (broken.length > 0 || leaks.length > 0) {
|
||||
filesWithIssues++;
|
||||
if (!VERBOSE) {
|
||||
console.log(`\n${relativePath}`);
|
||||
}
|
||||
|
||||
for (const { ref, resolved } of broken) {
|
||||
const location = ref.line ? `line ${ref.line}` : ref.key ? `key: ${ref.key}` : '';
|
||||
console.log(` [BROKEN] ${ref.raw}${location ? ` (${location})` : ''}`);
|
||||
console.log(` Target not found: ${resolved}`);
|
||||
allIssues.push({ file: relativePath, line: ref.line || 1, ref: ref.raw, issue: 'broken ref' });
|
||||
if (process.env.GITHUB_ACTIONS) {
|
||||
const line = ref.line || 1;
|
||||
console.log(`::warning file=${relativePath},line=${line}::${escapeAnnotation(`Broken reference: ${ref.raw} → ${resolved}`)}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const leak of leaks) {
|
||||
console.log(` [ABS-PATH] Line ${leak.line}: ${leak.content}`);
|
||||
allIssues.push({ file: relativePath, line: leak.line, ref: leak.content, issue: 'abs-path' });
|
||||
if (process.env.GITHUB_ACTIONS) {
|
||||
console.log(`::warning file=${relativePath},line=${leak.line}::${escapeAnnotation(`Absolute path leak: ${leak.content}`)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Summary
|
||||
console.log(`\n${'─'.repeat(60)}`);
|
||||
console.log(`\nSummary:`);
|
||||
console.log(` Files scanned: ${files.length}`);
|
||||
console.log(` References checked: ${totalRefs}`);
|
||||
console.log(` Broken references: ${brokenRefs}`);
|
||||
console.log(` Absolute path leaks: ${totalLeaks}`);
|
||||
|
||||
const hasIssues = brokenRefs > 0 || totalLeaks > 0;
|
||||
|
||||
if (hasIssues) {
|
||||
console.log(`\n ${filesWithIssues} file(s) with issues`);
|
||||
|
||||
if (STRICT) {
|
||||
console.log(`\n [STRICT MODE] Exiting with failure.`);
|
||||
} else {
|
||||
console.log(`\n Run with --strict to treat warnings as errors.`);
|
||||
}
|
||||
} else {
|
||||
console.log(`\n All file references valid!`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// Write GitHub Actions step summary
|
||||
if (process.env.GITHUB_STEP_SUMMARY) {
|
||||
let summary = '## File Reference Validation\n\n';
|
||||
if (allIssues.length > 0) {
|
||||
summary += '| File | Line | Reference | Issue |\n';
|
||||
summary += '|------|------|-----------|-------|\n';
|
||||
for (const issue of allIssues) {
|
||||
summary += `| ${escapeTableCell(issue.file)} | ${issue.line} | ${escapeTableCell(issue.ref)} | ${issue.issue} |\n`;
|
||||
}
|
||||
summary += '\n';
|
||||
}
|
||||
summary += `**${files.length} files scanned, ${totalRefs} references checked, ${brokenRefs + totalLeaks} issues found**\n`;
|
||||
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);
|
||||
}
|
||||
|
||||
process.exit(hasIssues && STRICT ? 1 : 0);
|
||||
|
|
@ -110,41 +110,7 @@ export default defineConfig({
|
|||
collapsed: true,
|
||||
autogenerate: { directory: 'reference' },
|
||||
},
|
||||
{
|
||||
label: 'TEA - Testing in BMAD',
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
label: 'Tutorials',
|
||||
autogenerate: { directory: 'tea/tutorials' },
|
||||
},
|
||||
{
|
||||
label: 'How-To Guides',
|
||||
items: [
|
||||
{
|
||||
label: 'Workflows',
|
||||
autogenerate: { directory: 'tea/how-to/workflows' },
|
||||
},
|
||||
{
|
||||
label: 'Customization',
|
||||
autogenerate: { directory: 'tea/how-to/customization' },
|
||||
},
|
||||
{
|
||||
label: 'Brownfield',
|
||||
autogenerate: { directory: 'tea/how-to/brownfield' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Explanation',
|
||||
autogenerate: { directory: 'tea/explanation' },
|
||||
},
|
||||
{
|
||||
label: 'Reference',
|
||||
autogenerate: { directory: 'tea/reference' },
|
||||
},
|
||||
],
|
||||
},
|
||||
// TEA docs moved to standalone module site; keep BMM sidebar focused.
|
||||
],
|
||||
|
||||
// Credits in footer
|
||||
|
|
|
|||
Loading…
Reference in New Issue