Compare commits

..

1 Commits

Author SHA1 Message Date
Armel BOBDA dc50cac7af
Merge 951b66b037 into 26e47562dd 2025-12-10 18:50:21 +05:00
27 changed files with 147 additions and 173 deletions

View File

@ -4,10 +4,9 @@ language: "en-US"
early_access: true early_access: true
reviews: reviews:
profile: chill profile: chill
high_level_summary: false # don't post summary until explicitly invoked high_level_summary: true
request_changes_workflow: false request_changes_workflow: false
review_status: false review_status: false
commit_status: false # don't set commit status until explicitly invoked
collapse_walkthrough: false collapse_walkthrough: false
poem: false poem: false
auto_review: auto_review:
@ -34,7 +33,4 @@ reviews:
Flag any process.exit() without error message. Flag any process.exit() without error message.
chat: chat:
auto_reply: true # Response to mentions in comments, a la @coderabbit review auto_reply: true # Response to mentions in comments, a la @coderabbit review
issue_enrichment:
auto_enrich:
enabled: false # don't auto-comment on issues

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "bmad-method", "name": "bmad-method",
"version": "6.0.0-alpha.16", "version": "6.0.0-alpha.15",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "bmad-method", "name": "bmad-method",
"version": "6.0.0-alpha.16", "version": "6.0.0-alpha.15",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@kayvan/markdown-tree-parser": "^1.6.1", "@kayvan/markdown-tree-parser": "^1.6.1",

View File

@ -330,7 +330,7 @@ Review was saved to story file, but sprint-status.yaml may be out of sync.
<action>All action items are included in the standalone review report</action> <action>All action items are included in the standalone review report</action>
<ask if="action items exist">Would you like me to create tracking items for these action items? (backlog/tasks)</ask> <ask if="action items exist">Would you like me to create tracking items for these action items? (backlog/tasks)</ask>
<action if="user confirms"> <action if="user confirms">
If {{backlog_file}} does not exist, copy {installed_path}/backlog-template.md to {{backlog_file}} location. If {{backlog_file}} does not exist, copy {installed_path}/backlog_template.md to {{backlog_file}} location.
Append a row per action item with Date={{date}}, Story="Ad-Hoc Review", Epic="N/A", Type, Severity, Owner (or "TBD"), Status="Open", Notes with file refs and context. Append a row per action item with Date={{date}}, Story="Ad-Hoc Review", Epic="N/A", Type, Severity, Owner (or "TBD"), Status="Open", Notes with file refs and context.
</action> </action>
</check> </check>
@ -342,7 +342,7 @@ Review was saved to story file, but sprint-status.yaml may be out of sync.
Append under the story's "Tasks / Subtasks" a new subsection titled "Review Follow-ups (AI)", adding each item as an unchecked checkbox in imperative form, prefixed with "[AI-Review]" and severity. Example: "- [ ] [AI-Review][High] Add input validation on server route /api/x (AC #2)". Append under the story's "Tasks / Subtasks" a new subsection titled "Review Follow-ups (AI)", adding each item as an unchecked checkbox in imperative form, prefixed with "[AI-Review]" and severity. Example: "- [ ] [AI-Review][High] Add input validation on server route /api/x (AC #2)".
</action> </action>
<action> <action>
If {{backlog_file}} does not exist, copy {installed_path}/backlog-template.md to {{backlog_file}} location. If {{backlog_file}} does not exist, copy {installed_path}/backlog_template.md to {{backlog_file}} location.
Append a row per action item with Date={{date}}, Story={{epic_num}}.{{story_num}}, Epic={{epic_num}}, Type, Severity, Owner (or "TBD"), Status="Open", Notes with short context and file refs. Append a row per action item with Date={{date}}, Story={{epic_num}}.{{story_num}}, Epic={{epic_num}}, Type, Severity, Owner (or "TBD"), Status="Open", Notes with short context and file refs.
</action> </action>
<action> <action>

View File

@ -24,7 +24,7 @@ agent:
critical_actions: critical_actions:
- "READ the entire story file BEFORE any implementation - tasks/subtasks sequence is your authoritative implementation guide" - "READ the entire story file BEFORE any implementation - tasks/subtasks sequence is your authoritative implementation guide"
- "Load project-context.md if available for coding standards only - never let it override story requirements" - "Load project_context.md if available for coding standards only - never let it override story requirements"
- "Execute tasks/subtasks IN ORDER as written in story file - no skipping, no reordering, no doing what you want" - "Execute tasks/subtasks IN ORDER as written in story file - no skipping, no reordering, no doing what you want"
- "For each task/subtask: follow red-green-refactor cycle - write failing test first, then implementation" - "For each task/subtask: follow red-green-refactor cycle - write failing test first, then implementation"
- "Mark task/subtask [x] ONLY when both implementation AND tests are complete and passing" - "Mark task/subtask [x] ONLY when both implementation AND tests are complete and passing"

View File

@ -199,11 +199,24 @@ PRDs are for Level 2-4 projects with multiple features requiring product-level c
### Q: How do I mark a story as done? ### Q: How do I mark a story as done?
**A:** After dev-story completes and code-review passes: **A:** You have two options:
1. Open `sprint-status.yaml` (created by sprint-planning) **Option 1: Use story-done workflow (Recommended)**
2. Change the story status from `review` to `done`
3. Save the file 1. Load SM agent
2. Run `story-done` workflow
3. Workflow automatically updates `sprint-status.yaml` (created by sprint-planning at Phase 4 start)
4. Moves story from current status → `DONE`
5. Advances the story queue
**Option 2: Manual update**
1. After dev-story completes and code-review passes
2. Open `sprint-status.yaml` (created by sprint-planning)
3. Change the story status from `review` to `done`
4. Save the file
The story-done workflow is faster and ensures proper status file updates.
### Q: Can I work on multiple stories at once? ### Q: Can I work on multiple stories at once?

View File

@ -2934,7 +2934,7 @@
"gap": 1 "gap": 1
}, },
"endBinding": { "endBinding": {
"elementId": "proc-code-review", "elementId": "proc-story-done",
"focus": 0.04241833499478815, "focus": 0.04241833499478815,
"gap": 1.3466869862454587 "gap": 1.3466869862454587
}, },
@ -3189,7 +3189,7 @@
"lineHeight": 1.25 "lineHeight": 1.25
}, },
{ {
"id": "proc-code-review", "id": "proc-story-done",
"type": "rectangle", "type": "rectangle",
"x": 1169.3991588878014, "x": 1169.3991588878014,
"y": 947.2529662369525, "y": 947.2529662369525,
@ -3207,12 +3207,12 @@
"value": 8 "value": 8
}, },
"groupIds": [ "groupIds": [
"proc-code-review-group" "proc-story-done-group"
], ],
"boundElements": [ "boundElements": [
{ {
"type": "text", "type": "text",
"id": "proc-code-review-text" "id": "proc-story-done-text"
}, },
{ {
"type": "arrow", "type": "arrow",
@ -3235,7 +3235,7 @@
"link": null "link": null
}, },
{ {
"id": "proc-code-review-text", "id": "proc-story-done-text",
"type": "text", "type": "text",
"x": 1187.9272045420983, "x": 1187.9272045420983,
"y": 972.2529662369525, "y": 972.2529662369525,
@ -3249,14 +3249,14 @@
"roughness": 0, "roughness": 0,
"opacity": 100, "opacity": 100,
"groupIds": [ "groupIds": [
"proc-code-review-group" "proc-story-done-group"
], ],
"fontSize": 16, "fontSize": 16,
"fontFamily": 1, "fontFamily": 1,
"text": "Code Review\n<<use different\nLLM>>", "text": "Code Review\n<<use different\nLLM>>",
"textAlign": "center", "textAlign": "center",
"verticalAlign": "middle", "verticalAlign": "middle",
"containerId": "proc-code-review", "containerId": "proc-story-done",
"locked": false, "locked": false,
"version": 502, "version": 502,
"versionNonce": 1242095014, "versionNonce": 1242095014,
@ -3289,7 +3289,7 @@
"opacity": 100, "opacity": 100,
"groupIds": [], "groupIds": [],
"startBinding": { "startBinding": {
"elementId": "proc-code-review", "elementId": "proc-story-done",
"focus": 0.014488632877232727, "focus": 0.014488632877232727,
"gap": 8.284295421831303 "gap": 8.284295421831303
}, },

View File

@ -377,6 +377,12 @@ Checks:
Quick Spec Flow works seamlessly with all Phase 4 implementation workflows: Quick Spec Flow works seamlessly with all Phase 4 implementation workflows:
### story-context (SM Agent)
- ✅ Recognizes tech-spec.md as authoritative source
- ✅ Extracts context from tech-spec (replaces PRD)
- ✅ Generates XML context for complex scenarios
### create-story (SM Agent) ### create-story (SM Agent)
- ✅ Can work with tech-spec.md instead of PRD - ✅ Can work with tech-spec.md instead of PRD
@ -523,6 +529,10 @@ Quick Spec Flow is **fully standalone**:
**A:** No problem! You can always transition to BMad Method by running workflow-init and create-prd. Your tech-spec becomes input for the PRD. **A:** No problem! You can always transition to BMad Method by running workflow-init and create-prd. Your tech-spec becomes input for the PRD.
### Q: Do I need story-context for every story?
**A:** Usually no! Tech-spec is comprehensive enough for most Quick Flow projects. Only use story-context for complex edge cases.
### Q: Can I skip validation? ### Q: Can I skip validation?
**A:** No, validation always runs automatically. But it's fast and catches issues early! **A:** No, validation always runs automatically. But it's fast and catches issues early!
@ -554,11 +564,15 @@ Starter templates save hours of setup time. Let Quick Spec Flow find the best on
When validation runs, read the scores. They tell you if your spec is production-ready. When validation runs, read the scores. They tell you if your spec is production-ready.
### 5. **Keep Single Changes Truly Atomic** ### 5. **Story Context is Optional**
For single changes, try going directly to dev-story first. Only add story-context if you hit complexity.
### 6. **Keep Single Changes Truly Atomic**
If your "single change" needs 3+ files, it might be a multi-story feature. Let the workflow guide you. If your "single change" needs 3+ files, it might be a multi-story feature. Let the workflow guide you.
### 6. **Validate Story Sequence for Multi-Story Features** ### 7. **Validate Story Sequence for Multi-Story Features**
When you get multiple stories, check the dependency validation output. Proper sequence matters! When you get multiple stories, check the dependency validation output. Proper sequence matters!

View File

@ -26,17 +26,14 @@ graph TB
subgraph Phase3["<b>Phase 3: SOLUTIONING</b>"] subgraph Phase3["<b>Phase 3: SOLUTIONING</b>"]
Architecture["<b>Architect: *architecture</b>"] Architecture["<b>Architect: *architecture</b>"]
EpicsStories["<b>PM/Architect: *create-epics-and-stories</b>"] EpicsStories["<b>PM/Architect: *create-epics-and-stories</b>"]
TestDesignSys["<b>TEA: *test-design (system-level)</b>"]
Framework["<b>TEA: *framework</b>"] Framework["<b>TEA: *framework</b>"]
CI["<b>TEA: *ci</b>"] CI["<b>TEA: *ci</b>"]
GateCheck["<b>Architect: *implementation-readiness</b>"] GateCheck["<b>Architect: *implementation-readiness</b>"]
Architecture --> EpicsStories Architecture --> EpicsStories
Architecture --> TestDesignSys
TestDesignSys --> Framework
EpicsStories --> Framework EpicsStories --> Framework
Framework --> CI Framework --> CI
CI --> GateCheck CI --> GateCheck
Phase3Note["<b>Epics created AFTER architecture,</b><br/><b>then system-level test design and test infrastructure setup</b>"] Phase3Note["<b>Epics created AFTER architecture,</b><br/><b>then test infrastructure setup</b>"]
EpicsStories -.-> Phase3Note EpicsStories -.-> Phase3Note
end end
@ -96,17 +93,12 @@ graph TB
- **Documentation** (Optional for brownfield): Prerequisite using `*document-project` - **Documentation** (Optional for brownfield): Prerequisite using `*document-project`
- **Phase 1** (Optional): Discovery/Analysis (`*brainstorm`, `*research`, `*product-brief`) - **Phase 1** (Optional): Discovery/Analysis (`*brainstorm`, `*research`, `*product-brief`)
- **Phase 2** (Required): Planning (`*prd` creates PRD with FRs/NFRs) - **Phase 2** (Required): Planning (`*prd` creates PRD with FRs/NFRs)
- **Phase 3** (Track-dependent): Solutioning (`*architecture` → `*test-design` (system-level) → `*create-epics-and-stories` → TEA: `*framework`, `*ci``*implementation-readiness`) - **Phase 3** (Track-dependent): Solutioning (`*architecture` → `*create-epics-and-stories` → TEA: `*framework`, `*ci``*implementation-readiness`)
- **Phase 4** (Required): Implementation (`*sprint-planning` → per-epic: `*test-design` → per-story: dev workflows) - **Phase 4** (Required): Implementation (`*sprint-planning` → per-epic: `*test-design` → per-story: dev workflows)
**TEA workflows:** `*framework` and `*ci` run once in Phase 3 after architecture. `*test-design` is **dual-mode**: **TEA workflows:** `*framework` and `*ci` run once in Phase 3 after architecture. `*test-design` runs per-epic in Phase 4. Output: `test-design-epic-N.md`.
- **System-level (Phase 3):** Run immediately after architecture/ADR drafting to produce `test-design-system.md` (testability review, ADR → test mapping, Architecturally Significant Requirements (ASRs), environment needs). Feeds the implementation-readiness gate. Quick Flow track skips Phase 1 and 3. BMad Method and Enterprise use all phases based on project needs.
- **Epic-level (Phase 4):** Run per-epic to produce `test-design-epic-N.md` (risk, priorities, coverage plan).
Quick Flow track skips Phases 1 and 3.
BMad Method and Enterprise use all phases based on project needs.
When an ADR or architecture draft is produced, run `*test-design` in **system-level** mode before the implementation-readiness gate. This ensures the ADR has an attached testability review and ADR → test mapping. Keep the test-design updated if ADRs change.
### Why TEA is Different from Other BMM Agents ### Why TEA is Different from Other BMM Agents

View File

@ -196,7 +196,7 @@ workflow-init asks: "Is this work in progress or previous effort?"
2. Verify agent has workflow: 2. Verify agent has workflow:
- PM agent: prd, tech-spec - PM agent: prd, tech-spec
- Architect agent: create-architecture, validate-architecture - Architect agent: create-architecture, validate-architecture
- SM agent: sprint-planning, create-story - SM agent: sprint-planning, create-story, story-context
3. Try menu number instead of name 3. Try menu number instead of name
4. Check you're using correct agent for workflow 4. Check you're using correct agent for workflow
@ -219,6 +219,23 @@ workflow-init asks: "Is this work in progress or previous effort?"
3. **Run in Phase 4 only** - Ensure Phase 2/3 complete first 3. **Run in Phase 4 only** - Ensure Phase 2/3 complete first
4. **Check file paths** - Epic files should be in correct output folder 4. **Check file paths** - Epic files should be in correct output folder
### Problem: story-context generates empty or wrong context
**Symptoms:**
- Context file created but has no useful content
- Context doesn't reference existing code
- Missing technical guidance
**Solution:**
1. **Run epic-tech-context first** - story-context builds on epic context
2. **Check story file exists** - Verify story was created by create-story
3. **For brownfield**:
- Ensure document-project was run
- Verify docs/index.md exists with codebase context
4. **Try regenerating** - Sometimes needs fresh attempt with more specific story details
--- ---
## Context and Documentation Issues ## Context and Documentation Issues
@ -345,7 +362,7 @@ For most brownfield projects, **Deep scan is sufficient**.
1. **For brownfield**: 1. **For brownfield**:
- Ensure document-project captured existing architecture - Ensure document-project captured existing architecture
- Review architecture docs before implementing - Review architecture docs before implementing
2. **Check story file** - Should document integration points 2. **Check story-context** - Should document integration points
3. **In tech-spec/architecture** - Explicitly document: 3. **In tech-spec/architecture** - Explicitly document:
- Which existing modules to modify - Which existing modules to modify
- What APIs/services to integrate with - What APIs/services to integrate with
@ -367,7 +384,7 @@ For most brownfield projects, **Deep scan is sufficient**.
- Should detect existing patterns - Should detect existing patterns
- Asks for confirmation before proceeding - Asks for confirmation before proceeding
2. **Review documentation** - Ensure document-project captured patterns 2. **Review documentation** - Ensure document-project captured patterns
3. **Use comprehensive story files** - Include pattern guidance in story 3. **Use story-context** - Injects pattern guidance per story
4. **Add to code-review checklist**: 4. **Add to code-review checklist**:
- Pattern adherence - Pattern adherence
- Convention consistency - Convention consistency
@ -442,7 +459,9 @@ To change locations, edit config.yaml then re-run workflows.
``` ```
2. **Some workflows auto-update**: 2. **Some workflows auto-update**:
- sprint-planning creates file - sprint-planning creates file
- create-story changes story to "ready-for-dev" - epic-tech-context changes epic to "contexted"
- create-story changes story to "drafted"
- story-context changes to "ready-for-dev"
- dev-story may auto-update (check workflow) - dev-story may auto-update (check workflow)
3. **Re-run sprint-planning** to resync if needed 3. **Re-run sprint-planning** to resync if needed
@ -638,8 +657,8 @@ If your issue isn't covered here:
### "Context generation failed" ### "Context generation failed"
**Cause:** Missing prerequisites (story file or docs) **Cause:** Missing prerequisites (epic context, story file, or docs)
**Fix:** Verify story file exists, docs present **Fix:** Verify epic-tech-context run, story file exists, docs present
--- ---

View File

@ -152,9 +152,10 @@ Dependencies: Story 1.2 (DONE) ✅
**Recommendation:** Run `create-story` to generate Story 1.3 **Recommendation:** Run `create-story` to generate Story 1.3
After create-story: After create-story:
1. Run dev-story 1. Run story-context
2. Run code-review 2. Run dev-story
3. Update sprint-status.yaml to mark story done 3. Run code-review
4. Run story-done
``` ```
See: [workflow-status instructions](../workflows/workflow-status/instructions.md) See: [workflow-status instructions](../workflows/workflow-status/instructions.md)

View File

@ -1,6 +1,6 @@
--- ---
name: create-prd name: create-prd
description: Creates a comprehensive PRD through collaborative step-by-step discovery between two product managers working as peers. description: Creates a comprehensive PRDs through collaborative step-by-step discovery between two product managers working as peers.
main_config: '{project-root}/.bmad/bmm/config.yaml' main_config: '{project-root}/.bmad/bmm/config.yaml'
web_bundle: true web_bundle: true
--- ---

View File

@ -94,7 +94,7 @@ Discover and load context documents using smart discovery:
**Project Context Rules (Critical for AI Agents):** **Project Context Rules (Critical for AI Agents):**
1. Check for project context file: `**/project-context.md` 1. Check for project context file: `**/project_context.md`
2. If exists: Load COMPLETE file contents - this contains critical rules for AI agents 2. If exists: Load COMPLETE file contents - this contains critical rules for AI agents
3. Add to frontmatter `hasProjectContext: true` and track file path 3. Add to frontmatter `hasProjectContext: true` and track file path
4. Report to user: "Found existing project context with {number_of_rules} agent rules" 4. Report to user: "Found existing project context with {number_of_rules} agent rules"

View File

@ -280,7 +280,7 @@ Your architecture will ensure consistent, high-quality implementation across all
**💡 Optional Enhancement: Project Context File** **💡 Optional Enhancement: Project Context File**
Would you like to create a `project-context.md` file? This is a concise, optimized guide for AI agents that captures: Would you like to create a `project_context.md` file? This is a concise, optimized guide for AI agents that captures:
- Critical language and framework rules they might miss - Critical language and framework rules they might miss
- Specific patterns and conventions for your project - Specific patterns and conventions for your project
@ -310,7 +310,7 @@ This will help ensure consistent implementation by capturing:
- Testing and quality standards - Testing and quality standards
- Anti-patterns to avoid - Anti-patterns to avoid
The workflow will collaborate with you to create an optimized `project-context.md` file that AI agents will read before implementing any code." The workflow will collaborate with you to create an optimized `project_context.md` file that AI agents will read before implementing any code."
**Execute the Generate Project Context workflow:** **Execute the Generate Project Context workflow:**

View File

@ -217,7 +217,7 @@
**Issues Fixed:** {{fixed_count}} **Issues Fixed:** {{fixed_count}}
**Action Items Created:** {{action_count}} **Action Items Created:** {{action_count}}
{{#if new_status == "done"}}Code review complete!{{else}}Address the action items and continue development.{{/if}} {{#if new_status == "done"}}Story is ready for next work!{{else}}Address the action items and continue development.{{/if}}
</output> </output>
</step> </step>

View File

@ -35,7 +35,7 @@ validation-rules:
- [ ] **Acceptance Criteria Satisfaction:** Implementation satisfies EVERY Acceptance Criterion in the story - [ ] **Acceptance Criteria Satisfaction:** Implementation satisfies EVERY Acceptance Criterion in the story
- [ ] **No Ambiguous Implementation:** Clear, unambiguous implementation that meets story requirements - [ ] **No Ambiguous Implementation:** Clear, unambiguous implementation that meets story requirements
- [ ] **Edge Cases Handled:** Error conditions and edge cases appropriately addressed - [ ] **Edge Cases Handled:** Error conditions and edge cases appropriately addressed
- [ ] **Dependencies Within Scope:** Only uses dependencies specified in story or project-context.md - [ ] **Dependencies Within Scope:** Only uses dependencies specified in story or project_context.md
## 🧪 Testing & Quality Assurance ## 🧪 Testing & Quality Assurance

View File

@ -53,9 +53,11 @@ Run `/bmad:bmm:workflows:sprint-planning` to generate it, then rerun sprint-stat
1. If any story status == in-progress → recommend `dev-story` for the first in-progress story 1. If any story status == in-progress → recommend `dev-story` for the first in-progress story
2. Else if any story status == review → recommend `code-review` for the first review story 2. Else if any story status == review → recommend `code-review` for the first review story
3. Else if any story status == ready-for-dev → recommend `dev-story` 3. Else if any story status == ready-for-dev → recommend `dev-story`
4. Else if any story status == backlog → recommend `create-story` 4. Else if any story status == drafted → recommend `story-ready`
5. Else if retrospectives are optional → recommend `retrospective` 5. Else if any story status == backlog → recommend `create-story`
6. Else → All implementation items done; suggest `workflow-status` to plan next phase 6. Else if any epic status == backlog → recommend `epic-tech-context`
7. Else if retrospectives are optional → recommend `retrospective`
8. Else → All implementation items done; suggest `workflow-status` to plan next phase
<action>Store selected recommendation as: next_story_id, next_workflow_id, next_agent (SM/DEV as appropriate)</action> <action>Store selected recommendation as: next_story_id, next_workflow_id, next_agent (SM/DEV as appropriate)</action>
</step> </step>

View File

@ -33,7 +33,7 @@ Discover the project's technology stack, existing patterns, and critical impleme
First, check if project context already exists: First, check if project context already exists:
- Look for file at `{output_folder}/project-context.md` - Look for file at `{output_folder}/project_context.md`
- If exists: Read complete file to understand existing rules - 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?" - Present to user: "Found existing project context with {number_of_sections} sections. Would you like to update this or create a new one?"
@ -122,7 +122,7 @@ Based on discovery, create or update the context document:
#### A. Fresh Document Setup (if no existing context) #### A. Fresh Document Setup (if no existing context)
Copy template from `{installed_path}/project-context-template.md` to `{output_folder}/project-context.md` Copy template from `{installed_path}/project-context-template.md` to `{output_folder}/project_context.md`
Initialize frontmatter with: Initialize frontmatter with:
```yaml ```yaml

View File

@ -288,7 +288,7 @@ After each category, show the generated rules and present choices:
## APPEND TO PROJECT CONTEXT: ## 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. 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: ## SUCCESS METRICS:

View File

@ -134,7 +134,7 @@ Based on user skill level, present the completion:
**Expert Mode:** **Expert Mode:**
"Project context complete. Optimized for LLM consumption with {{rule_count}} critical rules across {{section_count}} sections. "Project context complete. Optimized for LLM consumption with {{rule_count}} critical rules across {{section_count}} sections.
File saved to: `{output_folder}/project-context.md` File saved to: `{output_folder}/project_context.md`
Ready for AI agent integration." Ready for AI agent integration."
@ -227,7 +227,7 @@ Present final completion to user:
"✅ **Project Context Generation Complete!** "✅ **Project Context Generation Complete!**
Your optimized project context file is ready at: Your optimized project context file is ready at:
`{output_folder}/project-context.md` `{output_folder}/project_context.md`
**📊 Context Summary:** **📊 Context Summary:**

View File

@ -1,11 +1,11 @@
--- ---
name: generate-project-context 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. 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 # 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. **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. **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.
@ -37,7 +37,7 @@ Load config from `{project-root}/.bmad/bmm/config.yaml` and resolve:
- `installed_path` = `{project-root}/.bmad/bmm/workflows/generate-project-context` - `installed_path` = `{project-root}/.bmad/bmm/workflows/generate-project-context`
- `template_path` = `{installed_path}/project-context-template.md` - `template_path` = `{installed_path}/project-context-template.md`
- `output_file` = `{output_folder}/project-context.md` - `output_file` = `{output_folder}/project_context.md`
--- ---

View File

@ -24,14 +24,8 @@ variables:
# Output configuration # Output configuration
# Note: Actual output file determined dynamically based on mode detection # Note: Actual output file determined dynamically based on mode detection
# Declared outputs for new workflow format # - System-Level (Phase 3): {output_folder}/test-design-system.md
outputs: # - Epic-Level (Phase 4): {output_folder}/test-design-epic-{epic_num}.md
- id: system-level
description: "System-level testability review (Phase 3)"
path: "{output_folder}/test-design-system.md"
- id: epic-level
description: "Epic-level test plan (Phase 4)"
path: "{output_folder}/test-design-epic-{epic_num}.md"
default_output_file: "{output_folder}/test-design-epic-{epic_num}.md" default_output_file: "{output_folder}/test-design-epic-{epic_num}.md"
# Required tools # Required tools

View File

@ -248,21 +248,14 @@ class ConfigCollector {
const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt'); const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
const existingKeys = this.existingConfig && this.existingConfig[moduleName] ? Object.keys(this.existingConfig[moduleName]) : []; const existingKeys = this.existingConfig && this.existingConfig[moduleName] ? Object.keys(this.existingConfig[moduleName]) : [];
// Find new interactive fields (with prompt)
const newKeys = configKeys.filter((key) => { const newKeys = configKeys.filter((key) => {
const item = moduleConfig[key]; const item = moduleConfig[key];
// Check if it's a config item and doesn't exist in existing config // Check if it's a config item and doesn't exist in existing config
return item && typeof item === 'object' && item.prompt && !existingKeys.includes(key); return item && typeof item === 'object' && item.prompt && !existingKeys.includes(key);
}); });
// Find new static fields (without prompt, just result) // If in silent mode and no new keys, use existing config and skip prompts
const newStaticKeys = configKeys.filter((key) => { if (silentMode && newKeys.length === 0) {
const item = moduleConfig[key];
return item && typeof item === 'object' && !item.prompt && item.result && !existingKeys.includes(key);
});
// If in silent mode and no new keys (neither interactive nor static), use existing config and skip prompts
if (silentMode && newKeys.length === 0 && newStaticKeys.length === 0) {
if (this.existingConfig && this.existingConfig[moduleName]) { if (this.existingConfig && this.existingConfig[moduleName]) {
if (!this.collectedConfig[moduleName]) { if (!this.collectedConfig[moduleName]) {
this.collectedConfig[moduleName] = {}; this.collectedConfig[moduleName] = {};
@ -301,12 +294,9 @@ class ConfigCollector {
return false; // No new fields return false; // No new fields
} }
// If we have new fields (interactive or static), process them // If we have new fields, build questions first
if (newKeys.length > 0 || newStaticKeys.length > 0) { if (newKeys.length > 0) {
const questions = []; const questions = [];
const staticAnswers = {};
// Build questions for interactive fields
for (const key of newKeys) { for (const key of newKeys) {
const item = moduleConfig[key]; const item = moduleConfig[key];
const question = await this.buildQuestion(moduleName, key, item, moduleConfig); const question = await this.buildQuestion(moduleName, key, item, moduleConfig);
@ -315,35 +305,20 @@ class ConfigCollector {
} }
} }
// Prepare static answers (no prompt, just result)
for (const key of newStaticKeys) {
staticAnswers[`${moduleName}_${key}`] = undefined;
}
// Collect all answers (static + prompted)
let allAnswers = { ...staticAnswers };
if (questions.length > 0) { if (questions.length > 0) {
// Only show header if we actually have questions // Only show header if we actually have questions
CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader); CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader);
console.log(); // Line break before questions console.log(); // Line break before questions
const promptedAnswers = await inquirer.prompt(questions); const answers = await inquirer.prompt(questions);
// Merge prompted answers with static answers // Store answers for cross-referencing
Object.assign(allAnswers, promptedAnswers); Object.assign(this.allAnswers, answers);
} else if (newStaticKeys.length > 0) {
// Only static fields, no questions - show no config message
CLIUtils.displayModuleNoConfig(moduleName, moduleConfig.header, moduleConfig.subheader);
}
// Store all answers for cross-referencing // Process answers and build result values
Object.assign(this.allAnswers, allAnswers); for (const key of Object.keys(answers)) {
// Process all answers (both static and prompted)
for (const key of Object.keys(allAnswers)) {
const originalKey = key.replace(`${moduleName}_`, ''); const originalKey = key.replace(`${moduleName}_`, '');
const item = moduleConfig[originalKey]; const item = moduleConfig[originalKey];
const value = allAnswers[key]; const value = answers[key];
let result; let result;
if (Array.isArray(value)) { if (Array.isArray(value)) {
@ -359,6 +334,10 @@ class ConfigCollector {
} }
this.collectedConfig[moduleName][originalKey] = result; this.collectedConfig[moduleName][originalKey] = result;
} }
} else {
// New keys exist but no questions generated - show no config message
CLIUtils.displayModuleNoConfig(moduleName, moduleConfig.header, moduleConfig.subheader);
}
} }
// Copy over existing values for fields that weren't prompted // Copy over existing values for fields that weren't prompted
@ -374,7 +353,7 @@ class ConfigCollector {
} }
} }
return newKeys.length > 0 || newStaticKeys.length > 0; // Return true if we had any new fields (interactive or static) return newKeys.length > 0; // Return true if we prompted for new fields
} }
/** /**
@ -522,52 +501,30 @@ class ConfigCollector {
// Process each config item // Process each config item
const questions = []; const questions = [];
const staticAnswers = {};
const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt'); const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
for (const key of configKeys) { for (const key of configKeys) {
const item = moduleConfig[key]; const item = moduleConfig[key];
// Skip if not a config object // Skip if not a config object
if (!item || typeof item !== 'object') { if (!item || typeof item !== 'object' || !item.prompt) {
continue; continue;
} }
// Handle static values (no prompt, just result)
if (!item.prompt && item.result) {
// Add to static answers with a marker value
staticAnswers[`${moduleName}_${key}`] = undefined;
continue;
}
// Handle interactive values (with prompt)
if (item.prompt) {
const question = await this.buildQuestion(moduleName, key, item, moduleConfig); const question = await this.buildQuestion(moduleName, key, item, moduleConfig);
if (question) { if (question) {
questions.push(question); questions.push(question);
} }
} }
}
// Collect all answers (static + prompted)
let allAnswers = { ...staticAnswers };
// Display appropriate header based on whether there are questions // Display appropriate header based on whether there are questions
if (questions.length > 0) { if (questions.length > 0) {
CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader); CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader);
console.log(); // Line break before questions console.log(); // Line break before questions
const promptedAnswers = await inquirer.prompt(questions); const answers = await inquirer.prompt(questions);
// Merge prompted answers with static answers // Store answers for cross-referencing
Object.assign(allAnswers, promptedAnswers); Object.assign(this.allAnswers, answers);
}
// Store all answers for cross-referencing
Object.assign(this.allAnswers, allAnswers);
// Process all answers (both static and prompted)
if (Object.keys(allAnswers).length > 0) {
const answers = allAnswers;
// Process answers and build result values // Process answers and build result values
for (const key of Object.keys(answers)) { for (const key of Object.keys(answers)) {

View File

@ -581,11 +581,6 @@ class ManifestGenerator {
*/ */
async writeWorkflowManifest(cfgDir) { async writeWorkflowManifest(cfgDir) {
const csvPath = path.join(cfgDir, 'workflow-manifest.csv'); const csvPath = path.join(cfgDir, 'workflow-manifest.csv');
const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
const parseCsvLine = (line) => {
const columns = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
return columns.map((c) => c.replaceAll(/^"|"$/g, ''));
};
// Read existing manifest to preserve entries // Read existing manifest to preserve entries
const existingEntries = new Map(); const existingEntries = new Map();
@ -597,21 +592,18 @@ class ManifestGenerator {
for (let i = 1; i < lines.length; i++) { for (let i = 1; i < lines.length; i++) {
const line = lines[i]; const line = lines[i];
if (line) { if (line) {
const parts = parseCsvLine(line); // Parse CSV (simple parsing assuming no commas in quoted fields)
const parts = line.split('","');
if (parts.length >= 4) { if (parts.length >= 4) {
const [name, description, module, workflowPath] = parts; const name = parts[0].replace(/^"/, '');
existingEntries.set(`${module}:${name}`, { const module = parts[2];
name, existingEntries.set(`${module}:${name}`, line);
description,
module,
path: workflowPath,
});
} }
} }
} }
} }
// Create CSV header - standalone column removed, everything is canonicalized to 4 columns // Create CSV header - removed standalone column as ALL workflows now generate commands
let csv = 'name,description,module,path\n'; let csv = 'name,description,module,path\n';
// Combine existing and new workflows // Combine existing and new workflows
@ -625,18 +617,12 @@ class ManifestGenerator {
// Add/update new workflows // Add/update new workflows
for (const workflow of this.workflows) { for (const workflow of this.workflows) {
const key = `${workflow.module}:${workflow.name}`; const key = `${workflow.module}:${workflow.name}`;
allWorkflows.set(key, { allWorkflows.set(key, `"${workflow.name}","${workflow.description}","${workflow.module}","${workflow.path}"`);
name: workflow.name,
description: workflow.description,
module: workflow.module,
path: workflow.path,
});
} }
// Write all workflows // Write all workflows
for (const [, value] of allWorkflows) { for (const [, value] of allWorkflows) {
const row = [escapeCsv(value.name), escapeCsv(value.description), escapeCsv(value.module), escapeCsv(value.path)].join(','); csv += value + '\n';
csv += row + '\n';
} }
await fs.writeFile(csvPath, csv); await fs.writeFile(csvPath, csv);