check alignment
This commit is contained in:
parent
c8776aa9ac
commit
be5b06f55e
|
|
@ -0,0 +1,328 @@
|
|||
# BMAD Workflow Conditional Execution Antipattern Audit
|
||||
|
||||
**Date:** 2025-10-22
|
||||
**Auditor:** Claude Code (BMad Builder Agent)
|
||||
**Scope:** All markdown files under `src/`
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Critical Issue Identified:** Invalid self-closing `<check>` tag pattern found throughout BMAD workflow codebase.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- **98 instances** across **14 workflow files**
|
||||
- Affects core workflows, builder workflows, and method workflows
|
||||
- Creates XML parsing ambiguity and unpredictable LLM behavior
|
||||
- Violates BMAD workflow specification (workflow.xml)
|
||||
|
||||
**Severity:** CRITICAL - Invalid XML structure, ambiguous conditional scope
|
||||
|
||||
---
|
||||
|
||||
## The Antipattern
|
||||
|
||||
### Invalid Pattern (Self-Closing Check)
|
||||
|
||||
```xml
|
||||
<!-- ❌ WRONG - Invalid XML structure -->
|
||||
<check>If condition met:</check>
|
||||
<action>Do something</action>
|
||||
<action>Do something else</action>
|
||||
```
|
||||
|
||||
**Problems:**
|
||||
|
||||
1. Check tag doesn't wrap anything (invalid XML)
|
||||
2. Ambiguous scope - unclear which actions are conditional
|
||||
3. Breaks formatters and parsers
|
||||
4. Not part of BMAD workflow spec
|
||||
5. Unpredictable LLM interpretation
|
||||
|
||||
### Correct Patterns
|
||||
|
||||
**Single conditional action:**
|
||||
|
||||
```xml
|
||||
<!-- ✅ CORRECT - Inline conditional -->
|
||||
<action if="condition met">Do something</action>
|
||||
```
|
||||
|
||||
**Multiple conditional actions:**
|
||||
|
||||
```xml
|
||||
<!-- ✅ CORRECT - Proper wrapper block -->
|
||||
<check if="condition met">
|
||||
<action>Do something</action>
|
||||
<action>Do something else</action>
|
||||
</check>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Audit Results
|
||||
|
||||
### Total Count
|
||||
|
||||
- **Total Instances:** 98
|
||||
- **Affected Files:** 14
|
||||
- **Modules Affected:** 4 (BMB, BMM, CIS, Core)
|
||||
|
||||
### Breakdown by File
|
||||
|
||||
| File | Count | Priority |
|
||||
| -------------------------------------------------------------------- | ----- | ----------- |
|
||||
| `modules/bmb/workflows/edit-workflow/instructions.md` | 21 | 🔴 CRITICAL |
|
||||
| `modules/bmm/workflows/4-implementation/dev-story/instructions.md` | 13 | 🔴 CRITICAL |
|
||||
| `modules/bmb/workflows/convert-legacy/instructions.md` | 13 | 🔴 CRITICAL |
|
||||
| `modules/bmb/workflows/create-module/instructions.md` | 12 | 🔴 CRITICAL |
|
||||
| `modules/bmb/workflows/create-agent/instructions.md` | 11 | 🔴 CRITICAL |
|
||||
| `core/workflows/party-mode/instructions.md` | 7 | 🟡 HIGH |
|
||||
| `modules/bmm/workflows/4-implementation/correct-course/checklist.md` | 5 | 🟡 HIGH |
|
||||
| `core/workflows/brainstorming/instructions.md` | 5 | 🟡 HIGH |
|
||||
| `modules/cis/workflows/storytelling/instructions.md` | 3 | 🟢 MEDIUM |
|
||||
| `modules/bmb/workflows/audit-workflow/instructions.md` | 3 | 🟢 MEDIUM |
|
||||
| `modules/bmb/workflows/create-workflow/workflow-creation-guide.md` | 2 | 🟢 MEDIUM |
|
||||
| `modules/bmm/workflows/1-analysis/product-brief/instructions.md` | 1 | 🟢 LOW |
|
||||
| `modules/bmm/workflows/1-analysis/game-brief/instructions.md` | 1 | 🟢 LOW |
|
||||
| `modules/bmb/workflows/redoc/instructions.md` | 1 | 🟢 LOW |
|
||||
|
||||
### Breakdown by Module
|
||||
|
||||
**BMB (Builder) Module: 63 instances (64%)**
|
||||
|
||||
- edit-workflow: 21
|
||||
- convert-legacy: 13
|
||||
- create-module: 12
|
||||
- create-agent: 11
|
||||
- audit-workflow: 3
|
||||
- create-workflow: 2
|
||||
- redoc: 1
|
||||
|
||||
**BMM (Method) Module: 20 instances (20%)**
|
||||
|
||||
- dev-story: 13
|
||||
- correct-course: 5
|
||||
- product-brief: 1
|
||||
- game-brief: 1
|
||||
|
||||
**Core Workflows: 12 instances (12%)**
|
||||
|
||||
- party-mode: 7
|
||||
- brainstorming: 5
|
||||
|
||||
**CIS (Creative) Module: 3 instances (3%)**
|
||||
|
||||
- storytelling: 3
|
||||
|
||||
---
|
||||
|
||||
## Example Instances
|
||||
|
||||
### Example 1: create-agent/instructions.md (Line 13-20)
|
||||
|
||||
**BEFORE (Invalid):**
|
||||
|
||||
```xml
|
||||
<check>If yes:</check>
|
||||
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
|
||||
<action>Pass context data: {installed_path}/brainstorm-context.md</action>
|
||||
<action>Wait for brainstorming session completion</action>
|
||||
|
||||
<check>If no:</check>
|
||||
<action>Proceed directly to Step 0</action>
|
||||
```
|
||||
|
||||
**AFTER (Correct):**
|
||||
|
||||
```xml
|
||||
<check if="user answered yes">
|
||||
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
|
||||
<action>Pass context data: {installed_path}/brainstorm-context.md</action>
|
||||
<action>Wait for brainstorming session completion</action>
|
||||
</check>
|
||||
|
||||
<check if="user answered no">
|
||||
<action>Proceed directly to Step 0</action>
|
||||
</check>
|
||||
```
|
||||
|
||||
### Example 2: dev-story/instructions.md (Line 54-55)
|
||||
|
||||
**BEFORE (Invalid):**
|
||||
|
||||
```xml
|
||||
<check>If story file inaccessible → HALT: "Cannot develop story without access to story file"</check>
|
||||
<check>If task requirements ambiguous → ASK user to clarify or HALT</check>
|
||||
```
|
||||
|
||||
**AFTER (Correct):**
|
||||
|
||||
```xml
|
||||
<action if="story file inaccessible">HALT: "Cannot develop story without access to story file"</action>
|
||||
<action if="task requirements ambiguous">ASK user to clarify or HALT</action>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
### Technical Impact
|
||||
|
||||
1. **XML Validity:** Invalid structure violates XML parsing rules
|
||||
2. **Formatter Confusion:** Custom formatters incorrectly indent following content
|
||||
3. **Scope Ambiguity:** Unclear which actions are inside vs outside conditional
|
||||
4. **Maintainability:** Future developers confused by ambiguous structure
|
||||
|
||||
### LLM Adherence Impact
|
||||
|
||||
**Potential Issues:**
|
||||
|
||||
- LLM may interpret check as unconditional statement
|
||||
- Actions may execute when they shouldn't (or vice versa)
|
||||
- Inconsistent behavior across different LLMs
|
||||
- Unpredictable results in complex nested conditionals
|
||||
|
||||
**Observed Behavior:**
|
||||
|
||||
- LLMs often "figure it out" through context and proximity
|
||||
- Colon (`:`) pattern signals "here's what to do"
|
||||
- Works in simple cases but risky in complex logic
|
||||
|
||||
**Risk Level:** MEDIUM-HIGH
|
||||
|
||||
- May work "most of the time" but unreliable
|
||||
- Fails in edge cases and complex nested logic
|
||||
- Future LLMs may interpret differently
|
||||
|
||||
---
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Why This Happened
|
||||
|
||||
1. **Implicit convention evolved** - Self-closing check pattern emerged organically
|
||||
2. **No enforcement** - No linter or validator caught the pattern
|
||||
3. **Copy-paste propagation** - Pattern copied across workflows
|
||||
4. **Formatting hid the issue** - Manual indentation made it "look right"
|
||||
5. **LLM tolerance** - Current LLMs often figured it out despite ambiguity
|
||||
|
||||
### Meta-Problem
|
||||
|
||||
**The workflows that CREATE workflows have the antipattern:**
|
||||
|
||||
- create-workflow: 2 instances
|
||||
- create-agent: 11 instances
|
||||
- create-module: 12 instances
|
||||
- edit-workflow: 21 instances
|
||||
- convert-legacy: 13 instances
|
||||
|
||||
This means NEW workflows were being created WITH the antipattern built-in!
|
||||
|
||||
---
|
||||
|
||||
## Remediation Plan
|
||||
|
||||
### Phase 1: Immediate (High Priority Files)
|
||||
|
||||
Fix top 5 offenders (63% of problem):
|
||||
|
||||
1. edit-workflow (21 instances)
|
||||
2. dev-story (13 instances)
|
||||
3. convert-legacy (13 instances)
|
||||
4. create-module (12 instances)
|
||||
5. create-agent (11 instances)
|
||||
|
||||
**Total:** 70 instances (71% of problem)
|
||||
|
||||
### Phase 2: Core Workflows
|
||||
|
||||
Fix core workflows (critical for all modules):
|
||||
|
||||
1. party-mode (7 instances)
|
||||
2. brainstorming (5 instances)
|
||||
|
||||
**Total:** 12 instances
|
||||
|
||||
### Phase 3: Remaining
|
||||
|
||||
Fix remaining 16 instances across 7 files
|
||||
|
||||
### Phase 4: Prevention
|
||||
|
||||
1. **Update audit-workflow** ✅ DONE
|
||||
- Added antipattern detection to Step 4
|
||||
- Flags with CRITICAL severity
|
||||
- Suggests correct patterns
|
||||
|
||||
2. **Update creation guide** ✅ DONE
|
||||
- Documented antipattern in workflow-creation-guide.md
|
||||
- Clear examples of correct vs incorrect patterns
|
||||
- Added to best practices
|
||||
|
||||
3. **Update checklist** ✅ DONE
|
||||
- Added validation criteria to checklist.md
|
||||
- 3 new checks for conditional execution patterns
|
||||
|
||||
4. **Create automated fixer** (TODO)
|
||||
- Bulk conversion script for remaining instances
|
||||
- Pattern matching and replacement logic
|
||||
|
||||
---
|
||||
|
||||
## Specification Reference
|
||||
|
||||
From `bmad/core/tasks/workflow.xml`:
|
||||
|
||||
```xml
|
||||
<tag>action if="condition" - Single conditional action (inline, no closing tag needed)</tag>
|
||||
<tag>check if="condition">...</check> - Conditional block wrapping multiple items (closing tag required)</tag>
|
||||
```
|
||||
|
||||
**Key Point:** Check tags MUST have `if=""` attribute and MUST wrap content with closing tag.
|
||||
|
||||
The self-closing pattern `<check>text</check>` is **NOT in the spec** and is **invalid**.
|
||||
|
||||
---
|
||||
|
||||
## Detection Command
|
||||
|
||||
To find all instances:
|
||||
|
||||
```bash
|
||||
grep -r "<check>[^<]*</check>" src --include="*.md" -n
|
||||
```
|
||||
|
||||
To count by file:
|
||||
|
||||
```bash
|
||||
grep -r "<check>[^<]*</check>" src --include="*.md" -c | grep -v ":0$"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Actions
|
||||
|
||||
- [ ] Create bulk-fix script for automated conversion
|
||||
- [ ] Fix Phase 1 files (70 instances)
|
||||
- [ ] Fix Phase 2 files (12 instances)
|
||||
- [ ] Fix Phase 3 files (16 instances)
|
||||
- [ ] Run audit-workflow on all fixed files to verify
|
||||
- [ ] Update formatter to detect and warn on antipattern
|
||||
- [ ] Add pre-commit hook to prevent future instances
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **Workflow Spec:** `bmad/core/tasks/workflow.xml`
|
||||
- **Creation Guide:** `src/modules/bmb/workflows/create-workflow/workflow-creation-guide.md`
|
||||
- **Audit Workflow:** `src/modules/bmb/workflows/audit-workflow/`
|
||||
- **This Report:** `docs/antipattern-audit-2025-10-22.md`
|
||||
|
||||
---
|
||||
|
||||
**Report Status:** Complete
|
||||
**Action Required:** Yes - 98 instances need remediation
|
||||
**Priority:** CRITICAL - Affects core functionality and workflow creation
|
||||
|
|
@ -78,6 +78,9 @@
|
|||
- [ ] XML tags used correctly (<action>, <ask>, <check>, <goto>, <invoke-workflow>, <template-output>)
|
||||
- [ ] No nested tag references in content (use "action tags" not "<action> tags")
|
||||
- [ ] Tag references use descriptive text without angle brackets for clarity
|
||||
- [ ] No conditional execution antipattern (no self-closing <check> tags)
|
||||
- [ ] Single conditionals use <action if="condition"> (inline)
|
||||
- [ ] Multiple conditionals use <check if="condition">...</check> (wrapper block with closing tag)
|
||||
- [ ] Steps are focused (single goal per step)
|
||||
- [ ] Instructions are specific with limits ("Write 1-2 paragraphs" not "Write about")
|
||||
- [ ] Examples provided where helpful
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ Display summary:
|
|||
- Type of workflow
|
||||
- Files present
|
||||
- Module assignment
|
||||
|
||||
</step>
|
||||
|
||||
<step n="2" goal="Validate standard config block">
|
||||
|
|
@ -56,8 +57,8 @@ Display summary:
|
|||
<action>Record any missing or incorrect config variables</action>
|
||||
<template-output>config_issues</template-output>
|
||||
|
||||
<check>If config issues found:</check>
|
||||
<action>Add to issues list with severity: CRITICAL</action>
|
||||
<action if="config issues found">Add to issues list with severity: CRITICAL</action>
|
||||
|
||||
</step>
|
||||
|
||||
<step n="3" goal="Analyze YAML/Instruction/Template alignment">
|
||||
|
|
@ -84,8 +85,8 @@ Display summary:
|
|||
<action>Identify hardcoded values in instructions that should be variables</action>
|
||||
<template-output>alignment_issues</template-output>
|
||||
|
||||
<check>If unused variables found:</check>
|
||||
<action>Add to issues list with severity: BLOAT</action>
|
||||
<action if="unused variables found">Add to issues list with severity: BLOAT</action>
|
||||
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Config variable usage audit">
|
||||
|
|
@ -130,19 +131,52 @@ Display summary:
|
|||
- Improves readability for humans and LLMs
|
||||
- LLMs understand "action tags" = `<action>` tags from context
|
||||
|
||||
**Conditional Execution Antipattern Check:**
|
||||
|
||||
- Scan for self-closing check tags: `<check>condition text</check>` (invalid antipattern)
|
||||
- Detect pattern: check tag on one line, followed by action/ask/goto tags (indicates incorrect nesting)
|
||||
- Flag sequences like: `<check>If X:</check>` followed by `<action>do Y</action>`
|
||||
|
||||
**Correct Patterns:**
|
||||
|
||||
- Single conditional: `<action if="condition">Do something</action>`
|
||||
- Multiple actions: `<check if="condition">` followed by nested actions with closing `</check>` tag
|
||||
|
||||
**Antipattern Example (WRONG):**
|
||||
```xml
|
||||
<check>If condition met:</check>
|
||||
<action>Do something</action>
|
||||
```
|
||||
|
||||
**Correct Example:**
|
||||
```xml
|
||||
<check if="condition met">
|
||||
<action>Do something</action>
|
||||
<action>Do something else</action>
|
||||
</check>
|
||||
```
|
||||
|
||||
**Or for single action:**
|
||||
```xml
|
||||
<action if="condition met">Do something</action>
|
||||
```
|
||||
|
||||
<action>Scan instructions.md for nested tag references using pattern: <(action|ask|check|template-output|invoke-workflow|goto|step|elicit-required)> within text content</action>
|
||||
<action>Record any instances of nested tag references with line numbers</action>
|
||||
<action>Scan instructions.md for conditional execution antipattern: self-closing check tags</action>
|
||||
<action>Detect pattern: `<check>.*</check>` on single line (self-closing check)</action>
|
||||
<action>Record any antipattern instances with line numbers and suggest corrections</action>
|
||||
<action>Record any improper config variable usage</action>
|
||||
<template-output>config_usage_issues</template-output>
|
||||
|
||||
<check>If config usage issues found:</check>
|
||||
<action>Add to issues list with severity: IMPORTANT</action>
|
||||
<check>If nested tag references found:</check>
|
||||
<action>Add to issues list with severity: CLARITY (recommend using descriptive text without angle brackets)</action>
|
||||
<action if="config usage issues found">Add to issues list with severity: IMPORTANT</action>
|
||||
<action if="nested tag references found">Add to issues list with severity: CLARITY (recommend using descriptive text without angle brackets)</action>
|
||||
<action if="conditional antipattern found">Add to issues list with severity: CRITICAL (invalid XML structure - must use action if="" or proper check wrapper)</action>
|
||||
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Web bundle validation" optional="true">
|
||||
<check>If workflow.yaml contains web_bundle section:</check>
|
||||
<check if="workflow.yaml contains web_bundle section">
|
||||
|
||||
<action>Validate web_bundle structure:</action>
|
||||
|
||||
|
|
@ -166,9 +200,7 @@ Display summary:
|
|||
<action>Verify each called workflow.yaml is in web_bundle_files</action>
|
||||
<action>**CRITICAL**: Check if existing_workflows field is present when workflows are invoked</action>
|
||||
<action>If invoke-workflow calls exist, existing_workflows MUST map workflow variables to paths</action>
|
||||
<action>Example: If instructions use {core_brainstorming}, web_bundle needs:
|
||||
existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/workflow.yaml"
|
||||
</action>
|
||||
<action>Example: If instructions use {core_brainstorming}, web_bundle needs: existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/workflow.yaml"</action>
|
||||
|
||||
**File Reference Scan:**
|
||||
<action>Scan instructions.md for file references in action tags</action>
|
||||
|
|
@ -178,11 +210,11 @@ existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/wor
|
|||
<action>Record any missing files or incorrect paths</action>
|
||||
<template-output>web_bundle_issues</template-output>
|
||||
|
||||
<check>If web_bundle issues found:</check>
|
||||
<action>Add to issues list with severity: CRITICAL</action>
|
||||
<action if="web_bundle issues found">Add to issues list with severity: CRITICAL</action>
|
||||
|
||||
<action if="no web_bundle section exists">Note: "No web_bundle configured (may be intentional for local-only workflows)"</action>
|
||||
</check>
|
||||
|
||||
<check>If no web_bundle section exists:</check>
|
||||
<action>Note: "No web_bundle configured (may be intentional for local-only workflows)"</action>
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Bloat detection">
|
||||
|
|
@ -216,8 +248,8 @@ existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/wor
|
|||
<action>Record all bloat items with recommendations</action>
|
||||
<template-output>bloat_items</template-output>
|
||||
|
||||
<check>If bloat detected:</check>
|
||||
<action>Add to issues list with severity: CLEANUP</action>
|
||||
<action if="bloat detected">Add to issues list with severity: CLEANUP</action>
|
||||
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Template variable mapping" if="workflow_type == 'document'">
|
||||
|
|
@ -246,140 +278,55 @@ existing_workflows: - core_brainstorming: "bmad/core/workflows/brainstorming/wor
|
|||
<action>Record any mapping issues</action>
|
||||
<template-output>template_issues</template-output>
|
||||
|
||||
<check>If template issues found:</check>
|
||||
<action>Add to issues list with severity: IMPORTANT</action>
|
||||
<action if="template issues found">Add to issues list with severity: IMPORTANT</action>
|
||||
|
||||
</step>
|
||||
|
||||
<step n="8" goal="Generate comprehensive audit report">
|
||||
<action>Compile all findings into a structured report</action>
|
||||
<action>Compile all findings and calculate summary metrics</action>
|
||||
|
||||
<action>Write audit report to {output_folder}/audit-report-{{workflow_name}}-{{date}}.md</action>
|
||||
<action>Generate executive summary based on issue counts and severity levels</action>
|
||||
<template-output>workflow_type</template-output>
|
||||
<template-output>overall_status</template-output>
|
||||
<template-output>critical_count</template-output>
|
||||
<template-output>important_count</template-output>
|
||||
<template-output>cleanup_count</template-output>
|
||||
|
||||
**Report Structure:**
|
||||
<action>Generate status summaries for each audit section</action>
|
||||
<template-output>config_status</template-output>
|
||||
<template-output>total_variables</template-output>
|
||||
<template-output>instruction_usage_count</template-output>
|
||||
<template-output>template_usage_count</template-output>
|
||||
<template-output>bloat_count</template-output>
|
||||
|
||||
```markdown
|
||||
# Workflow Audit Report
|
||||
<action>Generate config variable usage status indicators</action>
|
||||
<template-output>comm_lang_status</template-output>
|
||||
<template-output>user_name_status</template-output>
|
||||
<template-output>output_folder_status</template-output>
|
||||
<template-output>date_status</template-output>
|
||||
<template-output>nested_tag_count</template-output>
|
||||
|
||||
**Workflow:** {{workflow_name}}
|
||||
**Audit Date:** {{date}}
|
||||
**Auditor:** Audit Workflow (BMAD v6)
|
||||
**Workflow Type:** {{workflow_type}}
|
||||
<action>Generate web bundle metrics</action>
|
||||
<template-output>web_bundle_exists</template-output>
|
||||
<template-output>web_bundle_file_count</template-output>
|
||||
<template-output>missing_files_count</template-output>
|
||||
|
||||
---
|
||||
<action>Generate bloat metrics</action>
|
||||
<template-output>bloat_percentage</template-output>
|
||||
<template-output>cleanup_potential</template-output>
|
||||
|
||||
## Executive Summary
|
||||
<action>Generate template mapping metrics</action>
|
||||
<template-output>template_var_count</template-output>
|
||||
<template-output>mapped_count</template-output>
|
||||
<template-output>missing_mapping_count</template-output>
|
||||
|
||||
**Overall Status:** {{overall_status}}
|
||||
|
||||
- Critical Issues: {{critical_count}}
|
||||
- Important Issues: {{important_count}}
|
||||
- Cleanup Recommendations: {{cleanup_count}}
|
||||
|
||||
---
|
||||
|
||||
## 1. Standard Config Block Validation
|
||||
|
||||
{{config_issues}}
|
||||
|
||||
**Status:** {{config_status}}
|
||||
|
||||
---
|
||||
|
||||
## 2. YAML/Instruction/Template Alignment
|
||||
|
||||
{{alignment_issues}}
|
||||
|
||||
**Variables Analyzed:** {{total_variables}}
|
||||
**Used in Instructions:** {{instruction_usage_count}}
|
||||
**Used in Template:** {{template_usage_count}}
|
||||
**Unused (Bloat):** {{bloat_count}}
|
||||
|
||||
---
|
||||
|
||||
## 3. Config Variable Usage & Instruction Quality
|
||||
|
||||
{{config_usage_issues}}
|
||||
|
||||
**Communication Language:** {{comm_lang_status}}
|
||||
**User Name:** {{user_name_status}}
|
||||
**Output Folder:** {{output_folder_status}}
|
||||
**Date:** {{date_status}}
|
||||
**Nested Tag References:** {{nested_tag_count}} instances found
|
||||
|
||||
---
|
||||
|
||||
## 4. Web Bundle Validation
|
||||
|
||||
{{web_bundle_issues}}
|
||||
|
||||
**Web Bundle Present:** {{web_bundle_exists}}
|
||||
**Files Listed:** {{web_bundle_file_count}}
|
||||
**Missing Files:** {{missing_files_count}}
|
||||
|
||||
---
|
||||
|
||||
## 5. Bloat Detection
|
||||
|
||||
{{bloat_items}}
|
||||
|
||||
**Bloat Percentage:** {{bloat_percentage}}%
|
||||
**Cleanup Potential:** {{cleanup_potential}}
|
||||
|
||||
---
|
||||
|
||||
## 6. Template Variable Mapping
|
||||
|
||||
{{template_issues}}
|
||||
|
||||
**Template Variables:** {{template_var_count}}
|
||||
**Mapped Correctly:** {{mapped_count}}
|
||||
**Missing Mappings:** {{missing_mapping_count}}
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Critical (Fix Immediately)
|
||||
|
||||
{{critical_recommendations}}
|
||||
|
||||
### Important (Address Soon)
|
||||
|
||||
{{important_recommendations}}
|
||||
|
||||
### Cleanup (Nice to Have)
|
||||
|
||||
{{cleanup_recommendations}}
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Use this checklist to verify fixes:
|
||||
|
||||
- [ ] All standard config variables present and correct
|
||||
- [ ] No unused yaml fields (bloat removed)
|
||||
- [ ] Config variables used appropriately in instructions
|
||||
- [ ] Web bundle includes all dependencies
|
||||
- [ ] Template variables properly mapped
|
||||
- [ ] File structure follows v6 conventions
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review critical issues and fix immediately
|
||||
2. Address important issues in next iteration
|
||||
3. Consider cleanup recommendations for optimization
|
||||
4. Re-run audit after fixes to verify improvements
|
||||
|
||||
---
|
||||
|
||||
**Audit Complete** - Generated by audit-workflow v1.0
|
||||
```
|
||||
<action>Compile prioritized recommendations by severity</action>
|
||||
<template-output>critical_recommendations</template-output>
|
||||
<template-output>important_recommendations</template-output>
|
||||
<template-output>cleanup_recommendations</template-output>
|
||||
|
||||
<action>Display summary to {user_name} in {communication_language}</action>
|
||||
<action>Provide path to full audit report</action>
|
||||
<action>Provide path to full audit report: {output_folder}/audit-report-{{workflow_name}}-{{date}}.md</action>
|
||||
|
||||
<ask>Would you like to:
|
||||
|
||||
|
|
@ -389,7 +336,6 @@ Use this checklist to verify fixes:
|
|||
- Exit
|
||||
</ask>
|
||||
|
||||
<template-output>audit_report_path</template-output>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
# Workflow Audit Report
|
||||
|
||||
**Workflow:** {{workflow_name}}
|
||||
**Audit Date:** {{date}}
|
||||
**Auditor:** Audit Workflow (BMAD v6)
|
||||
**Workflow Type:** {{workflow_type}}
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Overall Status:** {{overall_status}}
|
||||
|
||||
- Critical Issues: {{critical_count}}
|
||||
- Important Issues: {{important_count}}
|
||||
- Cleanup Recommendations: {{cleanup_count}}
|
||||
|
||||
---
|
||||
|
||||
## 1. Standard Config Block Validation
|
||||
|
||||
{{config_issues}}
|
||||
|
||||
**Status:** {{config_status}}
|
||||
|
||||
---
|
||||
|
||||
## 2. YAML/Instruction/Template Alignment
|
||||
|
||||
{{alignment_issues}}
|
||||
|
||||
**Variables Analyzed:** {{total_variables}}
|
||||
**Used in Instructions:** {{instruction_usage_count}}
|
||||
**Used in Template:** {{template_usage_count}}
|
||||
**Unused (Bloat):** {{bloat_count}}
|
||||
|
||||
---
|
||||
|
||||
## 3. Config Variable Usage & Instruction Quality
|
||||
|
||||
{{config_usage_issues}}
|
||||
|
||||
**Communication Language:** {{comm_lang_status}}
|
||||
**User Name:** {{user_name_status}}
|
||||
**Output Folder:** {{output_folder_status}}
|
||||
**Date:** {{date_status}}
|
||||
**Nested Tag References:** {{nested_tag_count}} instances found
|
||||
|
||||
---
|
||||
|
||||
## 4. Web Bundle Validation
|
||||
|
||||
{{web_bundle_issues}}
|
||||
|
||||
**Web Bundle Present:** {{web_bundle_exists}}
|
||||
**Files Listed:** {{web_bundle_file_count}}
|
||||
**Missing Files:** {{missing_files_count}}
|
||||
|
||||
---
|
||||
|
||||
## 5. Bloat Detection
|
||||
|
||||
{{bloat_items}}
|
||||
|
||||
**Bloat Percentage:** {{bloat_percentage}}%
|
||||
**Cleanup Potential:** {{cleanup_potential}}
|
||||
|
||||
---
|
||||
|
||||
## 6. Template Variable Mapping
|
||||
|
||||
{{template_issues}}
|
||||
|
||||
**Template Variables:** {{template_var_count}}
|
||||
**Mapped Correctly:** {{mapped_count}}
|
||||
**Missing Mappings:** {{missing_mapping_count}}
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Critical (Fix Immediately)
|
||||
|
||||
{{critical_recommendations}}
|
||||
|
||||
### Important (Address Soon)
|
||||
|
||||
{{important_recommendations}}
|
||||
|
||||
### Cleanup (Nice to Have)
|
||||
|
||||
{{cleanup_recommendations}}
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Use this checklist to verify fixes:
|
||||
|
||||
- [ ] All standard config variables present and correct
|
||||
- [ ] No unused yaml fields (bloat removed)
|
||||
- [ ] Config variables used appropriately in instructions
|
||||
- [ ] Web bundle includes all dependencies
|
||||
- [ ] Template variables properly mapped
|
||||
- [ ] File structure follows v6 conventions
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Review critical issues and fix immediately
|
||||
2. Address important issues in next iteration
|
||||
3. Consider cleanup recommendations for optimization
|
||||
4. Re-run audit after fixes to verify improvements
|
||||
|
||||
---
|
||||
|
||||
**Audit Complete** - Generated by audit-workflow v1.0
|
||||
|
|
@ -12,7 +12,7 @@ date: system-generated
|
|||
|
||||
# Module path and component files
|
||||
installed_path: "{project-root}/bmad/bmb/workflows/audit-workflow"
|
||||
template: false
|
||||
template: "{installed_path}/template.md"
|
||||
instructions: "{installed_path}/instructions.md"
|
||||
validation: "{installed_path}/checklist.md"
|
||||
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ For Modules:
|
|||
|
||||
<step n="3" goal="Determine Target Module and Location">
|
||||
<ask>Which module should this belong to? (eg. bmm, bmb, cis, bmm-legacy, or custom)</ask>
|
||||
<check>If custom module:</check>
|
||||
<ask>Enter custom module code (kebab-case):</ask>
|
||||
<action if="custom module"><ask>Enter custom module code (kebab-case):</ask></action>
|
||||
<action>Determine installation path based on type and module</action>
|
||||
<critical>IMPORTANT: All paths must use final BMAD installation locations, not src paths!</critical>
|
||||
<action>Show user the target location: {project-root}/bmad/{{target_module}}/{{item_type}}/{{item_name}}</action>
|
||||
|
|
@ -79,15 +78,18 @@ For Modules:
|
|||
<step n="4" goal="Choose Conversion Strategy">
|
||||
<action>Based on item type and complexity, choose approach:</action>
|
||||
|
||||
<check>If agent conversion:</check>
|
||||
<check>If simple agent (basic persona + commands):</check>
|
||||
<check if="agent conversion">
|
||||
<check if="simple agent (basic persona + commands)">
|
||||
<action>Use direct conversion to v5 agent YAML format</action>
|
||||
<goto step="5a">Direct Agent Conversion</goto>
|
||||
<check>If complex agent with embedded workflows:</check>
|
||||
</check>
|
||||
<check if="complex agent with embedded workflows">
|
||||
<action>Plan to invoke create-agent workflow</action>
|
||||
<goto step="5b">Workflow-Assisted Agent Creation</goto>
|
||||
</check>
|
||||
</check>
|
||||
|
||||
<check>If template or task conversion to workflow:</check>
|
||||
<check if="template or task conversion to workflow">
|
||||
<action>Analyze the v4 item to determine workflow type:</action>
|
||||
|
||||
- Does it generate a specific document type? → Document workflow
|
||||
|
|
@ -104,14 +106,14 @@ For Modules:
|
|||
4. Meta-workflow (coordinates other workflows)
|
||||
Select 1-4:</ask>
|
||||
|
||||
<check>If template conversion:</check>
|
||||
<goto step="5c">Template-to-Workflow Conversion</goto>
|
||||
<check>If task conversion:</check>
|
||||
<goto step="5e">Task-to-Workflow Conversion</goto>
|
||||
<action if="template conversion"><goto step="5c">Template-to-Workflow Conversion</goto></action>
|
||||
<action if="task conversion"><goto step="5e">Task-to-Workflow Conversion</goto></action>
|
||||
</check>
|
||||
|
||||
<check>If full module conversion:</check>
|
||||
<check if="full module conversion">
|
||||
<action>Plan to invoke create-module workflow</action>
|
||||
<goto step="5d">Module Creation</goto>
|
||||
</check>
|
||||
</step>
|
||||
|
||||
<step n="5a" goal="Direct Agent Conversion" optional="true">
|
||||
|
|
@ -262,15 +264,17 @@ date: system-generated
|
|||
- User interaction patterns → appropriate v5 tags
|
||||
|
||||
3. Based on confirmed workflow type:
|
||||
<check>If Document workflow:</check>
|
||||
<check if="Document workflow">
|
||||
- Create template.md from output patterns
|
||||
- Map generation steps to instructions
|
||||
- Add <template-output> tags for sections
|
||||
- Add template-output tags for sections
|
||||
</check>
|
||||
|
||||
<check>If Action workflow:</check>
|
||||
<check if="Action workflow">
|
||||
- Set template: false in workflow.yaml
|
||||
- Focus on action sequences in instructions
|
||||
- Preserve execution logic
|
||||
</check>
|
||||
|
||||
4. Handle special v4 patterns:
|
||||
- 1-9 elicitation menus → v5 <invoke-task halt="true">{project-root}/bmad/core/tasks/adv-elicit.xml</invoke-task>
|
||||
|
|
@ -341,9 +345,10 @@ For Modules:
|
|||
|
||||
<action>Show validation results to user</action>
|
||||
<ask>Any issues to fix before finalizing? (y/n)</ask>
|
||||
<check>If yes:</check>
|
||||
<check if="yes">
|
||||
<action>Address specific issues</action>
|
||||
<goto step="6">Re-validate</goto>
|
||||
</check>
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Migration Report">
|
||||
|
|
@ -360,15 +365,13 @@ For Modules:
|
|||
|
||||
<step n="8" goal="Cleanup and Finalize">
|
||||
<ask>Archive original v4 files? (y/n)</ask>
|
||||
<check>If yes:</check>
|
||||
<action>Move v4 files to: {project-root}/archive/v4-legacy/{{date}}/</action>
|
||||
<action if="yes">Move v4 files to: {project-root}/archive/v4-legacy/{{date}}/</action>
|
||||
|
||||
<action>Show user the final converted items and their locations</action>
|
||||
<action>Provide any post-conversion instructions or recommendations</action>
|
||||
|
||||
<ask>Would you like to convert another legacy item? (y/n)</ask>
|
||||
<check>If yes:</check>
|
||||
<goto step="1">Start new conversion</goto>
|
||||
<action if="yes"><goto step="1">Start new conversion</goto></action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
|
|||
|
|
@ -10,165 +10,131 @@ Agents with distinct communication styles are more memorable, engaging, and fun
|
|||
|
||||
**Film Noir Detective**
|
||||
|
||||
```
|
||||
The terminal glowed like a neon sign in a rain-soaked alley. I had three suspects:
|
||||
bad input validation, a race condition, and that sketchy third-party library.
|
||||
My gut told me to follow the stack trace. In this business, the stack trace never lies.
|
||||
```
|
||||
|
||||
**80s Action Movie**
|
||||
|
||||
```
|
||||
*cracks knuckles* Listen up, code! You've been running wild for too long!
|
||||
Time to bring some LAW and ORDER to this codebase! *explosion sound effect*
|
||||
_cracks knuckles_ Listen up, code! You've been running wild for too long!
|
||||
Time to bring some LAW and ORDER to this codebase! _explosion sound effect_
|
||||
No bug is getting past me! I eat null pointers for BREAKFAST!
|
||||
```
|
||||
|
||||
**Shakespearean Drama**
|
||||
|
||||
```
|
||||
To debug, or not to debug - that is the question!
|
||||
Whether 'tis nobler in the mind to suffer the slings and arrows of outrageous errors,
|
||||
Or to take arms against a sea of bugs, and by opposing, end them?
|
||||
```
|
||||
|
||||
### 🎮 Gaming and Pop Culture
|
||||
|
||||
**Dungeon Master**
|
||||
|
||||
```
|
||||
*rolls dice* You encounter a wild NullPointerException! It has 15 HP and an armor class of 12.
|
||||
What do you do? You can: 1) Try-catch block (defensive spell), 2) Debug (investigation check),
|
||||
3) Console.log everything (barbarian rage). Choose wisely, adventurer!
|
||||
```
|
||||
_rolls dice_ You encounter a wild NullPointerException! It has 15 HP and an armor class of 12.
|
||||
What do you do? You can: 1 Try-catch block (defensive spell), 2 Debug (investigation check),
|
||||
3 Console.log everything (barbarian rage). Choose wisely, adventurer!
|
||||
|
||||
**Speedrunner**
|
||||
|
||||
```
|
||||
Alright chat, we're going for the any% world record refactor!
|
||||
Frame-perfect optimization incoming! If we clip through this abstraction layer
|
||||
we can save 3ms on every API call. LET'S GOOOO!
|
||||
```
|
||||
|
||||
### 🌍 Cultural Archetypes
|
||||
|
||||
**British Butler**
|
||||
|
||||
```
|
||||
I've taken the liberty of organizing your imports alphabetically, sir/madam.
|
||||
Might I suggest a spot of refactoring with your afternoon tea?
|
||||
The code coverage report is ready for your perusal at your convenience.
|
||||
Very good, sir/madam.
|
||||
```
|
||||
|
||||
**Zen Master**
|
||||
|
||||
```
|
||||
The bug you seek is not in the code, but in the assumption.
|
||||
Empty your cache, as you would empty your mind.
|
||||
When the test passes, it makes no sound.
|
||||
Be like water - async and flowing.
|
||||
```
|
||||
|
||||
**Southern Hospitality**
|
||||
|
||||
```
|
||||
Well bless your heart, looks like you've got yourself a little bug there!
|
||||
Don't you worry none, we'll fix it up real nice.
|
||||
Can I get you some sweet tea while we debug?
|
||||
Y'all come back now if you need more help!
|
||||
```
|
||||
|
||||
### 🔬 Professional Personas
|
||||
|
||||
**McKinsey Consultant**
|
||||
|
||||
```
|
||||
Let me break this down into three key buckets.
|
||||
First, we need to align on the strategic imperatives.
|
||||
Second, we'll leverage best practices to drive synergies.
|
||||
Third, we'll action items to move the needle. Net-net: significant value-add.
|
||||
```
|
||||
|
||||
**Startup Founder**
|
||||
|
||||
```
|
||||
Okay so basically we're going to disrupt the entire way you write code!
|
||||
This is going to be HUGE! We're talking 10x productivity gains!
|
||||
Let's move fast and break things! Well... let's move fast and fix things!
|
||||
We're not just writing code, we're changing the world!
|
||||
```
|
||||
|
||||
### 🎭 Character Quirks
|
||||
|
||||
**Overcaffeinated Developer**
|
||||
|
||||
```
|
||||
OH WOW OKAY SO - *sips coffee* - WE HAVE A BUG BUT ITS FINE ITS TOTALLY FINE
|
||||
I KNOW EXACTLY WHAT TO DO *types at 200wpm* JUST NEED TO REFACTOR EVERYTHING
|
||||
WAIT NO ACTUALLY *more coffee* I HAVE A BETTER IDEA! Have you tried... TYPESCRIPT?!
|
||||
```
|
||||
OH WOW OKAY SO - _sips coffee_ - WE HAVE A BUG BUT ITS FINE ITS TOTALLY FINE
|
||||
I KNOW EXACTLY WHAT TO DO _types at 200wpm_ JUST NEED TO REFACTOR EVERYTHING
|
||||
WAIT NO ACTUALLY _more coffee_ I HAVE A BETTER IDEA! Have you tried... TYPESCRIPT?!
|
||||
|
||||
**Dad Joke Enthusiast**
|
||||
|
||||
```
|
||||
Why did the developer go broke? Because he used up all his cache!
|
||||
*chuckles at own joke*
|
||||
_chuckles at own joke_
|
||||
Speaking of cache, let's clear yours and see if that fixes the issue.
|
||||
I promise my debugging skills are better than my jokes! ...I hope!
|
||||
```
|
||||
|
||||
### 🚀 Sci-Fi and Space
|
||||
|
||||
**Star Trek Officer**
|
||||
|
||||
```
|
||||
Captain's Log, Supplemental: The anomaly in the codebase appears to be a temporal loop
|
||||
in the async function. Mr. Data suggests we reverse the polarity of the promise chain.
|
||||
Number One, make it so. Engage debugging protocols on my mark.
|
||||
*taps combadge* Engineering, we need more processing power!
|
||||
_taps combadge_ Engineering, we need more processing power!
|
||||
Red Alert! All hands to debugging stations!
|
||||
```
|
||||
|
||||
**Star Trek Engineer**
|
||||
|
||||
```
|
||||
Captain, I'm givin' her all she's got! The CPU cannae take much more!
|
||||
If we push this algorithm any harder, the whole system's gonna blow!
|
||||
*frantically typing* I can maybe squeeze 10% more performance if we
|
||||
_frantically typing_ I can maybe squeeze 10% more performance if we
|
||||
reroute power from the console.logs to the main execution thread!
|
||||
```
|
||||
|
||||
### 📺 TV Drama
|
||||
|
||||
**Soap Opera Dramatic**
|
||||
|
||||
```
|
||||
*turns dramatically to camera*
|
||||
_turns dramatically to camera_
|
||||
This function... I TRUSTED it! We had HISTORY together - three commits worth!
|
||||
But now? *single tear* It's throwing exceptions behind my back!
|
||||
*grabs another function* YOU KNEW ABOUT THIS BUG ALL ALONG, DIDN'T YOU?!
|
||||
*dramatic music swells* I'LL NEVER IMPORT YOU AGAIN!
|
||||
```
|
||||
But now? _single tear_ It's throwing exceptions behind my back!
|
||||
_grabs another function_ YOU KNEW ABOUT THIS BUG ALL ALONG, DIDN'T YOU?!
|
||||
_dramatic music swells_ I'LL NEVER IMPORT YOU AGAIN!
|
||||
|
||||
**Reality TV Confessional**
|
||||
|
||||
```
|
||||
*whispering to camera in confessional booth*
|
||||
_whispering to camera in confessional booth_
|
||||
Okay so like, that Array.sort() function? It's literally SO toxic.
|
||||
It mutates IN PLACE. Who does that?! I didn't come here to deal with side effects!
|
||||
*applies lip gloss* I'm forming an alliance with map() and filter().
|
||||
_applies lip gloss_ I'm forming an alliance with map() and filter().
|
||||
We're voting sort() off the codebase at tonight's pull request ceremony.
|
||||
```
|
||||
|
||||
**Reality Competition**
|
||||
|
||||
```
|
||||
Listen up, coders! For today's challenge, you need to refactor this legacy code
|
||||
in under 30 minutes! The winner gets immunity from the next code review!
|
||||
*dramatic pause* BUT WAIT - there's a TWIST! You can only use VANILLA JAVASCRIPT!
|
||||
*contestants gasp* The clock starts... NOW! GO GO GO!
|
||||
```
|
||||
_dramatic pause_ BUT WAIT - there's a TWIST! You can only use VANILLA JAVASCRIPT!
|
||||
_contestants gasp_ The clock starts... NOW! GO GO GO!
|
||||
|
||||
## Creating Custom Styles
|
||||
|
||||
|
|
@ -183,21 +149,17 @@ in under 30 minutes! The winner gets immunity from the next code review!
|
|||
|
||||
**Cooking Show + Military**
|
||||
|
||||
```
|
||||
ALRIGHT RECRUITS! Today we're preparing a beautiful Redux reducer!
|
||||
First, we MISE EN PLACE our action types - that's French for GET YOUR CODE TOGETHER!
|
||||
We're going to sauté these event handlers until they're GOLDEN BROWN!
|
||||
MOVE WITH PURPOSE! SEASON WITH SEMICOLONS!
|
||||
```
|
||||
|
||||
**Nature Documentary + Conspiracy Theorist**
|
||||
|
||||
```
|
||||
The wild JavaScript function stalks its prey... but wait... notice how it ALWAYS
|
||||
knows where the data is? That's not natural selection, folks. Someone DESIGNED it
|
||||
this way. The console.logs are watching. They're ALWAYS watching.
|
||||
Nature? Or intelligent debugging? You decide.
|
||||
```
|
||||
|
||||
## Tips for Success
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@
|
|||
<step n="-1" goal="Optional brainstorming for agent ideas" optional="true">
|
||||
<ask>Do you want to brainstorm agent ideas first? [y/n]</ask>
|
||||
|
||||
<check>If yes:</check>
|
||||
<check if="user answered yes">
|
||||
<action>Invoke brainstorming workflow: {project-root}/bmad/core/workflows/brainstorming/workflow.yaml</action>
|
||||
<action>Pass context data: {installed_path}/brainstorm-context.md</action>
|
||||
<action>Wait for brainstorming session completion</action>
|
||||
<action>Use brainstorming output to inform agent identity and persona development in following steps</action>
|
||||
</check>
|
||||
|
||||
<check>If no:</check>
|
||||
<check if="user answered no">
|
||||
<action>Proceed directly to Step 0</action>
|
||||
</check>
|
||||
|
||||
<template-output>brainstorming_results</template-output>
|
||||
</step>
|
||||
|
|
@ -48,15 +50,17 @@
|
|||
|
||||
**Path Determination:**
|
||||
|
||||
<check>If Module agent:</check>
|
||||
<check if="module agent selected">
|
||||
<action>Discover which module system fits best (bmm, bmb, cis, or custom)</action>
|
||||
<action>Store as {{target_module}} for path determination</action>
|
||||
<note>Agent will be saved to: bmad/{{target_module}}/agents/</note>
|
||||
</check>
|
||||
|
||||
<check>If Simple/Expert agent (standalone):</check>
|
||||
<check if="standalone agent selected">
|
||||
<action>Explain this will be their personal agent, not tied to a module</action>
|
||||
<note>Agent will be saved to: bmad/agents/{{agent-name}}/</note>
|
||||
<note>All sidecar files will be in the same folder</note>
|
||||
</check>
|
||||
|
||||
<critical>Determine agent location:</critical>
|
||||
|
||||
|
|
@ -163,8 +167,7 @@ menu:
|
|||
|
||||
<action>Generate the complete YAML incorporating all discovered elements:</action>
|
||||
|
||||
<example>
|
||||
```yaml
|
||||
<example type="yaml">
|
||||
agent:
|
||||
metadata:
|
||||
id: bmad/{{target_module}}/agents/{{agent_filename}}.md
|
||||
|
|
@ -188,11 +191,10 @@ prompts: {{if discussed}}
|
|||
critical_actions: {{if needed}}
|
||||
|
||||
menu: {{The capabilities built}}
|
||||
|
||||
````
|
||||
</example>
|
||||
|
||||
<critical>Save based on agent type:</critical>
|
||||
|
||||
- If Module Agent: Save to {module_output_file}
|
||||
- If Standalone (Simple/Expert): Save to {standalone_output_file}
|
||||
|
||||
|
|
@ -204,7 +206,7 @@ menu: {{The capabilities built}}
|
|||
<step n="7" goal="Optional personalization" optional="true">
|
||||
<ask>Would you like to create a customization file? This lets you tweak the agent's personality later without touching the core agent.</ask>
|
||||
|
||||
<check>If interested:</check>
|
||||
<check if="user interested">
|
||||
<action>Explain how the customization file gives them a playground to experiment with different personality traits, add new commands, or adjust responses as they get to know the agent better</action>
|
||||
|
||||
<action>Create customization file at: {config_output_file}</action>
|
||||
|
|
@ -228,6 +230,8 @@ agent:
|
|||
|
||||
</example>
|
||||
|
||||
</check>
|
||||
|
||||
<template-output>agent_config</template-output>
|
||||
</step>
|
||||
|
||||
|
|
@ -300,10 +304,11 @@ Add domain-specific resources here.
|
|||
<step n="8b" goal="Handle build tools availability">
|
||||
<action>Check if BMAD build tools are available in this project</action>
|
||||
|
||||
<check>If in BMAD-METHOD project with build tools:</check>
|
||||
<check if="BMAD-METHOD project with build tools">
|
||||
<action>Proceed normally - agent will be built later by the installer</action>
|
||||
</check>
|
||||
|
||||
<check>If NO build tools available (external project):</check>
|
||||
<check if="external project without build tools">
|
||||
<ask>Build tools not detected in this project. Would you like me to:
|
||||
|
||||
1. Generate the compiled agent (.md with XML) ready to use
|
||||
|
|
@ -311,10 +316,13 @@ Add domain-specific resources here.
|
|||
3. Provide both formats
|
||||
</ask>
|
||||
|
||||
<check>If option 1 or 3 selected:</check>
|
||||
<check if="option 1 or 3 selected">
|
||||
<action>Generate compiled agent XML with proper structure including activation rules, persona sections, and menu items</action>
|
||||
<action>Save compiled version as {{agent_filename}}.md</action>
|
||||
<action>Provide path for .claude/commands/ or similar</action>
|
||||
</check>
|
||||
|
||||
</check>
|
||||
|
||||
<template-output>build_handling</template-output>
|
||||
</step>
|
||||
|
|
@ -328,11 +336,13 @@ Add domain-specific resources here.
|
|||
- Command functionality verification
|
||||
- Personality settings confirmation
|
||||
|
||||
<check>If issues found:</check>
|
||||
<check if="validation issues found">
|
||||
<action>Explain the issue conversationally and fix it</action>
|
||||
</check>
|
||||
|
||||
<check>If all good:</check>
|
||||
<check if="validation passed">
|
||||
<action>Celebrate that the agent passed all checks and is ready</action>
|
||||
</check>
|
||||
|
||||
**Technical Checks (behind the scenes):**
|
||||
|
||||
|
|
@ -365,8 +375,9 @@ Add domain-specific resources here.
|
|||
- List the commands available
|
||||
- Suggest trying the first command to see it in action
|
||||
|
||||
<check>If Expert agent:</check>
|
||||
<check if="expert agent">
|
||||
<action>Remind user to add any special knowledge or data the agent might need to its workspace</action>
|
||||
</check>
|
||||
|
||||
<action>Explore what user would like to do next - test the agent, create a teammate, or tweak personality</action>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,16 @@
|
|||
<step n="-1" goal="Optional brainstorming for module ideas" optional="true">
|
||||
<ask>Do you want to brainstorm module ideas first? [y/n]</ask>
|
||||
|
||||
<check>If yes:</check>
|
||||
<check if="yes">
|
||||
<action>Invoke brainstorming workflow: {brainstorming_workflow}</action>
|
||||
<action>Pass context data: {brainstorming_context}</action>
|
||||
<action>Wait for brainstorming session completion</action>
|
||||
<action>Use brainstorming output to inform module concept, agent lineup, and workflow portfolio in following steps</action>
|
||||
</check>
|
||||
|
||||
<check>If no:</check>
|
||||
<check if="no">
|
||||
<action>Proceed directly to Step 0</action>
|
||||
</check>
|
||||
|
||||
<template-output>brainstorming_results</template-output>
|
||||
</step>
|
||||
|
|
@ -25,17 +27,20 @@
|
|||
<step n="0" goal="Check for module brief" optional="true">
|
||||
<ask>Do you have a module brief or should we create one? [have/create/skip]</ask>
|
||||
|
||||
<check>If create:</check>
|
||||
<check if="create">
|
||||
<action>Invoke module-brief workflow: {project-root}/bmad/bmb/workflows/module-brief/workflow.yaml</action>
|
||||
<action>Wait for module brief completion</action>
|
||||
<action>Load the module brief to use as blueprint</action>
|
||||
</check>
|
||||
|
||||
<check>If have:</check>
|
||||
<check if="have">
|
||||
<ask>Provide path to module brief document</ask>
|
||||
<action>Load the module brief and use it to pre-populate all planning sections</action>
|
||||
</check>
|
||||
|
||||
<check>If skip:</check>
|
||||
<check if="skip">
|
||||
<action>Proceed directly to Step 1</action>
|
||||
</check>
|
||||
|
||||
<template-output>module_brief</template-output>
|
||||
</step>
|
||||
|
|
@ -113,8 +118,7 @@
|
|||
**Tasks Planning (optional):**
|
||||
<ask>Any special tasks that don't warrant full workflows?</ask>
|
||||
|
||||
<check>If tasks needed:</check>
|
||||
<action>For each task, capture name, purpose, and whether standalone or supporting</action>
|
||||
<action if="tasks needed">For each task, capture name, purpose, and whether standalone or supporting</action>
|
||||
|
||||
<template-output>module_components</template-output>
|
||||
</step>
|
||||
|
|
@ -221,7 +225,7 @@
|
|||
<step n="5" goal="Create first agent" optional="true">
|
||||
<ask>Create your first agent now? [yes/no]</ask>
|
||||
|
||||
<check>If yes:</check>
|
||||
<check if="yes">
|
||||
<action>Invoke agent builder workflow: {agent_builder}</action>
|
||||
<action>Pass module_components as context input</action>
|
||||
<action>Guide them to create the primary agent for the module</action>
|
||||
|
|
@ -229,9 +233,11 @@
|
|||
<critical>Save to module's agents folder:</critical>
|
||||
|
||||
- Save to {{module_path}}/agents/
|
||||
</check>
|
||||
|
||||
<check>If no:</check>
|
||||
<check if="no">
|
||||
<action>Create placeholder file in agents folder with TODO notes including agent name, purpose, and type</action>
|
||||
</check>
|
||||
|
||||
<template-output>first_agent</template-output>
|
||||
</step>
|
||||
|
|
@ -239,7 +245,7 @@
|
|||
<step n="6" goal="Create first workflow" optional="true">
|
||||
<ask>Create your first workflow now? [yes/no]</ask>
|
||||
|
||||
<check>If yes:</check>
|
||||
<check if="yes">
|
||||
<action>Invoke workflow builder: {workflow_builder}</action>
|
||||
<action>Pass module_components as context input</action>
|
||||
<action>Guide them to create the primary workflow</action>
|
||||
|
|
@ -247,9 +253,11 @@
|
|||
<critical>Save to module's workflows folder:</critical>
|
||||
|
||||
- Save to {{module_path}}/workflows/
|
||||
</check>
|
||||
|
||||
<check>If no:</check>
|
||||
<check if="no">
|
||||
<action>Create placeholder workflow folder structure with TODO notes for workflow.yaml, instructions.md, and template.md if document workflow</action>
|
||||
</check>
|
||||
|
||||
<template-output>first_workflow</template-output>
|
||||
</step>
|
||||
|
|
@ -325,23 +333,23 @@ prompt:
|
|||
|
||||
<ask>Does your module need custom installation logic (database setup, API registration, etc.)?</ask>
|
||||
|
||||
<check>If yes, create installer.js:</check>
|
||||
|
||||
<check if="yes, create installer.js">
|
||||
```javascript
|
||||
// {{module_name}} Module Installer
|
||||
// Custom installation logic
|
||||
|
||||
/**
|
||||
* Module installation hook
|
||||
* Called after files are copied but before IDE configuration
|
||||
*
|
||||
* @param {Object} options - Installation options
|
||||
* @param {string} options.projectRoot - Project root directory
|
||||
* @param {Object} options.config - Module configuration from install-config.yaml
|
||||
* @param {Array} options.installedIDEs - List of IDE codes being configured
|
||||
* @param {Object} options.logger - Logger instance (log, warn, error methods)
|
||||
* @returns {boolean} - true if successful, false to abort installation
|
||||
*/
|
||||
/\*\*
|
||||
|
||||
- Module installation hook
|
||||
- Called after files are copied but before IDE configuration
|
||||
-
|
||||
- @param {Object} options - Installation options
|
||||
- @param {string} options.projectRoot - Project root directory
|
||||
- @param {Object} options.config - Module configuration from install-config.yaml
|
||||
- @param {Array} options.installedIDEs - List of IDE codes being configured
|
||||
- @param {Object} options.logger - Logger instance (log, warn, error methods)
|
||||
- @returns {boolean} - true if successful, false to abort installation
|
||||
\*/
|
||||
async function install(options) {
|
||||
const { projectRoot, config, installedIDEs, logger } = options;
|
||||
|
||||
|
|
@ -357,17 +365,21 @@ async function install(options) {
|
|||
|
||||
logger.log('{{module_name}} custom installation complete!');
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
module.exports = { install };
|
||||
```
|
||||
|
||||
`````
|
||||
|
||||
<critical>Save location:</critical>
|
||||
|
||||
- Save to {{module_path}}/\_module-installer/installer.js
|
||||
</check>
|
||||
|
||||
<check>If no:</check>
|
||||
<check if="no">
|
||||
<action>Skip installer.js creation - the standard installer will handle everything</action>
|
||||
</check>
|
||||
|
||||
<template-output>installer_config</template-output>
|
||||
</step>
|
||||
|
|
@ -389,7 +401,8 @@ This module provides:
|
|||
|
||||
```bash
|
||||
bmad install {{module_code}}
|
||||
```
|
||||
`````
|
||||
|
||||
````
|
||||
|
||||
## Components
|
||||
|
|
@ -471,22 +484,26 @@ Created by {{user_name}} on {{date}}
|
|||
Create a development roadmap for remaining components:
|
||||
|
||||
**TODO.md file:**
|
||||
|
||||
```markdown
|
||||
# {{module_name}} Development Roadmap
|
||||
|
||||
## Phase 1: Core Components
|
||||
|
||||
{{phase1_tasks}}
|
||||
|
||||
## Phase 2: Enhanced Features
|
||||
|
||||
{{phase2_tasks}}
|
||||
|
||||
## Phase 3: Polish and Integration
|
||||
|
||||
{{phase3_tasks}}
|
||||
|
||||
## Quick Commands
|
||||
|
||||
Create new agent:
|
||||
````
|
||||
```
|
||||
|
||||
workflow create-agent
|
||||
|
||||
|
|
|
|||
|
|
@ -290,6 +290,43 @@ _Generated on {{date}}_
|
|||
- **`<action if="">`** - Single conditional action (cleaner, more concise)
|
||||
- **`<check if="">...</check>`** - Multiple items under same condition (explicit scope)
|
||||
|
||||
**❌ CRITICAL ANTIPATTERN - DO NOT USE:**
|
||||
|
||||
**Invalid self-closing check tags:**
|
||||
|
||||
```xml
|
||||
<!-- ❌ WRONG - Invalid XML structure -->
|
||||
<check>If condition met:</check>
|
||||
<action>Do something</action>
|
||||
|
||||
<!-- ❌ WRONG - Ambiguous nesting -->
|
||||
<check>If validation fails:</check>
|
||||
<action>Log error</action>
|
||||
<goto step="1">Retry</goto>
|
||||
```
|
||||
|
||||
**Why this is wrong:**
|
||||
|
||||
- Creates invalid XML structure (check tag doesn't wrap anything)
|
||||
- Ambiguous - unclear if actions are inside or outside the condition
|
||||
- Breaks formatter and parser logic
|
||||
- Not part of BMAD workflow spec
|
||||
|
||||
**✅ CORRECT alternatives:**
|
||||
|
||||
```xml
|
||||
<!-- ✅ Single action - use inline if -->
|
||||
<action if="condition met">Do something</action>
|
||||
|
||||
<!-- ✅ Multiple actions - use proper wrapper block -->
|
||||
<check if="validation fails">
|
||||
<action>Log error</action>
|
||||
<goto step="1">Retry</goto>
|
||||
</check>
|
||||
```
|
||||
|
||||
**Rule:** If you have only ONE conditional action, use `<action if="">`. If you have MULTIPLE conditional actions, use `<check if="">...</check>` wrapper with a closing tag.
|
||||
|
||||
### Loops
|
||||
|
||||
```xml
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ Present the editing menu to the user:
|
|||
<step n="4" goal="Load relevant documentation">
|
||||
Based on the selected edit type, load appropriate reference materials:
|
||||
|
||||
<check>If option 2 (Add/fix standard config):</check>
|
||||
<check if="option 2 (Add/fix standard config) selected">
|
||||
<action>Prepare standard config block template:</action>
|
||||
|
||||
```yaml
|
||||
|
|
@ -102,47 +102,53 @@ date: system-generated
|
|||
<action>Identify missing config variables to add</action>
|
||||
<action>Check instructions.md for config variable usage</action>
|
||||
<action>Check template.md for config variable usage</action>
|
||||
</check>
|
||||
|
||||
<check>If editing instructions or adding features:</check>
|
||||
<check if="editing instructions or adding features">
|
||||
<action>Review the "Writing Instructions" section of the creation guide</action>
|
||||
<action>Load example workflows from {project-root}/bmad/bmm/workflows/ for patterns</action>
|
||||
</check>
|
||||
|
||||
<check>If editing templates:</check>
|
||||
<check if="editing templates">
|
||||
<action>Review the "Templates and Variables" section of the creation guide</action>
|
||||
<action>Ensure variable naming conventions are followed</action>
|
||||
</check>
|
||||
|
||||
<check>If editing validation:</check>
|
||||
<action>Review the "Validation" section and measurable criteria examples</action>
|
||||
<action if="editing validation">Review the "Validation" section and measurable criteria examples</action>
|
||||
|
||||
<check>If option 9 (Remove bloat):</check>
|
||||
<check if="option 9 (Remove bloat) selected">
|
||||
<action>Cross-reference all workflow.yaml fields against instructions.md and template.md</action>
|
||||
<action>Identify yaml fields not used in any file</action>
|
||||
<action>Check for duplicate fields in web_bundle section</action>
|
||||
</check>
|
||||
|
||||
<check>If configuring web bundle:</check>
|
||||
<check if="configuring web bundle">
|
||||
<action>Review the "Web Bundles" section of the creation guide</action>
|
||||
<action>Scan all workflow files for referenced resources</action>
|
||||
<action>Create inventory of all files that must be included</action>
|
||||
<action>Scan instructions for <invoke-workflow> calls - those yamls must be included</action>
|
||||
<action>Scan instructions for invoke-workflow calls - those yamls must be included</action>
|
||||
</check>
|
||||
|
||||
<check>If fixing critical issues:</check>
|
||||
<check if="fixing critical issues">
|
||||
<action>Load the workflow execution engine documentation</action>
|
||||
<action>Verify all required elements are present</action>
|
||||
</check>
|
||||
|
||||
<check>If adjusting instruction style (option 11):</check>
|
||||
<check if="adjusting instruction style (option 11) selected">
|
||||
<action>Analyze current instruction style in instructions.md:</action>
|
||||
|
||||
- Count <action> tags vs <ask> tags
|
||||
- Count action tags vs ask tags
|
||||
- Identify goal-oriented language ("guide", "explore", "help") vs prescriptive ("choose", "select", "specify")
|
||||
- Assess whether steps are open-ended or structured with specific options
|
||||
<action>Determine current dominant style: intent-based, prescriptive, or mixed</action>
|
||||
<action>Load the instruction style guide section from create-workflow</action>
|
||||
</check>
|
||||
</step>
|
||||
|
||||
<step n="5" goal="Perform edits" repeat="until-complete">
|
||||
Based on the selected focus area:
|
||||
|
||||
<check>If configuring web bundle (option 7):</check>
|
||||
<check if="configuring web bundle (option 7) selected">
|
||||
<action>Check if web_bundle section exists in workflow.yaml</action>
|
||||
|
||||
If creating new web bundle:
|
||||
|
|
@ -157,7 +163,7 @@ If creating new web bundle:
|
|||
- Any included files
|
||||
5. Scan template.md for any includes
|
||||
6. Create complete web_bundle_files array
|
||||
7. **CRITICAL**: Check for <invoke-workflow> calls in instructions:
|
||||
7. **CRITICAL**: Check for invoke-workflow calls in instructions:
|
||||
- If workflow invokes other workflows, add existing_workflows field
|
||||
- Maps workflow variable name to bmad/-relative path
|
||||
- Signals bundler to recursively include invoked workflow's web_bundle
|
||||
|
|
@ -170,8 +176,9 @@ If updating existing web bundle:
|
|||
2. Check for missing files in web_bundle_files
|
||||
3. Remove any config dependencies
|
||||
4. Update file list with newly referenced files
|
||||
</check>
|
||||
|
||||
<check>If adjusting instruction style (option 11):</check>
|
||||
<check if="adjusting instruction style (option 11) selected">
|
||||
<action>Present current style analysis to user:</action>
|
||||
|
||||
**Current Instruction Style Analysis:**
|
||||
|
|
@ -233,8 +240,8 @@ Even workflows with a primary style should use the other when appropriate. For e
|
|||
|
||||
<ask>What would you like to do?
|
||||
|
||||
1. **Make more intent-based** - Convert prescriptive <ask> tags to goal-oriented <action> tags where appropriate
|
||||
2. **Make more prescriptive** - Convert open-ended <action> tags to specific <ask> tags with options
|
||||
1. **Make more intent-based** - Convert prescriptive ask tags to goal-oriented action tags where appropriate
|
||||
2. **Make more prescriptive** - Convert open-ended action tags to specific ask tags with options
|
||||
3. **Optimize mix** - Use intent-based for complex steps, prescriptive for simple data collection
|
||||
4. **Review specific steps** - Show me each step and let me decide individually
|
||||
5. **Cancel** - Keep current style
|
||||
|
|
@ -242,9 +249,10 @@ Even workflows with a primary style should use the other when appropriate. For e
|
|||
Select option (1-5):</ask>
|
||||
|
||||
<action>Store user's style adjustment preference as {{style_adjustment_choice}}</action>
|
||||
</check>
|
||||
|
||||
<check>If choice is 1 (make more intent-based):</check>
|
||||
<action>Identify prescriptive <ask> tags that could be converted to intent-based <action> tags</action>
|
||||
<check if="choice is 1 (make more intent-based)">
|
||||
<action>Identify prescriptive ask tags that could be converted to intent-based action tags</action>
|
||||
<action>For each candidate conversion:
|
||||
|
||||
- Show original prescriptive version
|
||||
|
|
@ -253,9 +261,10 @@ Select option (1-5):</ask>
|
|||
- Ask for approval
|
||||
</action>
|
||||
<action>Apply approved conversions</action>
|
||||
</check>
|
||||
|
||||
<check>If choice is 2 (make more prescriptive):</check>
|
||||
<action>Identify open-ended <action> tags that could be converted to prescriptive <ask> tags</action>
|
||||
<check if="choice is 2 (make more prescriptive)">
|
||||
<action>Identify open-ended action tags that could be converted to prescriptive ask tags</action>
|
||||
<action>For each candidate conversion:
|
||||
|
||||
- Show original intent-based version
|
||||
|
|
@ -264,8 +273,9 @@ Select option (1-5):</ask>
|
|||
- Ask for approval
|
||||
</action>
|
||||
<action>Apply approved conversions</action>
|
||||
</check>
|
||||
|
||||
<check>If choice is 3 (optimize mix):</check>
|
||||
<check if="choice is 3 (optimize mix)">
|
||||
<action>Analyze each step for complexity and purpose</action>
|
||||
<action>Recommend style for each step:
|
||||
|
||||
|
|
@ -278,8 +288,9 @@ Select option (1-5):</ask>
|
|||
</action>
|
||||
<action>Show recommendations with reasoning</action>
|
||||
<action>Apply approved optimizations</action>
|
||||
</check>
|
||||
|
||||
<check>If choice is 4 (review specific steps):</check>
|
||||
<check if="choice is 4 (review specific steps)">
|
||||
<action>Present each step one at a time</action>
|
||||
<action>For each step:
|
||||
|
||||
|
|
@ -288,9 +299,9 @@ Select option (1-5):</ask>
|
|||
- Offer to keep, convert to intent-based, or convert to prescriptive
|
||||
- Apply user's choice before moving to next step
|
||||
</action>
|
||||
</check>
|
||||
|
||||
<check>If choice is 5 (cancel):</check>
|
||||
<goto step="3">Return to editing menu</goto>
|
||||
<action if="choice is 5 (cancel)"><goto step="3">Return to editing menu</goto></action>
|
||||
|
||||
<action>Show the current content that will be edited</action>
|
||||
<action>Explain the proposed changes and why they improve the workflow</action>
|
||||
|
|
@ -305,16 +316,17 @@ Select option (1-5):</ask>
|
|||
- [d] Done with edits
|
||||
</ask>
|
||||
|
||||
<check>If user selects 'a':</check>
|
||||
<check if="user selects 'a'">
|
||||
<action>Apply the changes to the file</action>
|
||||
<action>Log the change for the summary</action>
|
||||
</check>
|
||||
|
||||
<check>If user selects 'e':</check>
|
||||
<check if="user selects 'e'">
|
||||
<ask>What modifications would you like to make?</ask>
|
||||
<goto step="5">Regenerate with modifications</goto>
|
||||
</check>
|
||||
|
||||
<check>If user selects 'd':</check>
|
||||
<continue>Proceed to validation</continue>
|
||||
<action if="user selects 'd'"><continue>Proceed to validation</continue></action>
|
||||
</step>
|
||||
|
||||
<step n="6" goal="Validate all changes" optional="true">
|
||||
|
|
@ -361,10 +373,12 @@ Select option (1-5):</ask>
|
|||
- [ ] Called workflows (<invoke-workflow>) included in web_bundle_files
|
||||
- [ ] Complete file inventory verified
|
||||
|
||||
<check>If any validation fails:</check>
|
||||
<check if="any validation fails">
|
||||
<ask>Issues found. Would you like to fix them? (y/n)</ask>
|
||||
<check>If yes:</check>
|
||||
<check if="yes">
|
||||
<goto step="5">Return to editing</goto>
|
||||
</check>
|
||||
</check>
|
||||
</step>
|
||||
|
||||
<step n="7" goal="Generate change summary">
|
||||
|
|
@ -385,8 +399,7 @@ Select option (1-5):</ask>
|
|||
- Exit
|
||||
</ask>
|
||||
|
||||
<check>If test workflow:</check>
|
||||
<action>Invoke the edited workflow for testing</action>
|
||||
<action if="test workflow">Invoke the edited workflow for testing</action>
|
||||
</step>
|
||||
|
||||
</workflow>
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@
|
|||
4. Save README.md
|
||||
</action>
|
||||
|
||||
<check>If clarification needed about purpose or unique features → Ask user briefly, then continue</check>
|
||||
<action if="clarification needed about purpose or unique features">Ask user briefly, then continue</action>
|
||||
</step>
|
||||
|
||||
<step n="4" goal="Process mid-level folder documentation" if="target_type requires folder docs">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,263 @@
|
|||
/**
|
||||
* BMAD Workflow Markdown Formatter
|
||||
*
|
||||
* Formats mixed markdown + XML workflow instruction files with:
|
||||
* - 2-space XML indentation
|
||||
* - Preserved markdown content
|
||||
* - Proper tag nesting
|
||||
* - Consistent formatting
|
||||
*/
|
||||
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
class WorkflowFormatter {
|
||||
constructor(options = {}) {
|
||||
this.indentSize = options.indentSize || 2;
|
||||
this.preserveMarkdown = options.preserveMarkdown !== false;
|
||||
this.verbose = options.verbose || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a workflow markdown file
|
||||
*/
|
||||
format(filePath) {
|
||||
if (this.verbose) {
|
||||
console.log(`Formatting: ${filePath}`);
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const formatted = this.formatContent(content);
|
||||
|
||||
// Only write if content changed
|
||||
if (content === formatted) {
|
||||
if (this.verbose) {
|
||||
console.log(`- No changes: ${filePath}`);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
fs.writeFileSync(filePath, formatted, 'utf8');
|
||||
if (this.verbose) {
|
||||
console.log(`✓ Formatted: ${filePath}`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format content string with stateful indentation tracking
|
||||
*/
|
||||
formatContent(content) {
|
||||
const lines = content.split('\n');
|
||||
const formatted = [];
|
||||
let indentLevel = 0;
|
||||
let inCodeBlock = false;
|
||||
let checkBlockDepth = 0; // Track nested check blocks
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const trimmed = line.trim();
|
||||
|
||||
// Track code blocks (don't format inside them)
|
||||
if (trimmed.startsWith('```')) {
|
||||
if (inCodeBlock) {
|
||||
inCodeBlock = false;
|
||||
} else {
|
||||
inCodeBlock = true;
|
||||
}
|
||||
formatted.push(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't format inside code blocks
|
||||
if (inCodeBlock) {
|
||||
formatted.push(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle XML tags
|
||||
if (this.isXMLLine(trimmed)) {
|
||||
const result = this.formatXMLLine(trimmed, indentLevel, checkBlockDepth, i, lines);
|
||||
formatted.push(result.line);
|
||||
indentLevel = result.nextIndent;
|
||||
checkBlockDepth = result.nextCheckDepth;
|
||||
} else if (trimmed === '') {
|
||||
// Preserve blank lines
|
||||
formatted.push('');
|
||||
} else {
|
||||
// Markdown content - preserve as-is but maintain current indent if inside XML
|
||||
formatted.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
return formatted.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if line contains XML tag
|
||||
*/
|
||||
isXMLLine(line) {
|
||||
return /^<[a-zA-Z-]+(\s|>|\/)/.test(line) || /^<\/[a-zA-Z-]+>/.test(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a single XML line with context awareness
|
||||
*/
|
||||
formatXMLLine(line, currentIndent, checkDepth, lineIndex, allLines) {
|
||||
const trimmed = line.trim();
|
||||
let indent = currentIndent;
|
||||
let nextIndent = currentIndent;
|
||||
let nextCheckDepth = checkDepth;
|
||||
|
||||
// Get the tag name
|
||||
const tagMatch = trimmed.match(/^<\/?([a-zA-Z-]+)/);
|
||||
const tagName = tagMatch ? tagMatch[1] : '';
|
||||
|
||||
// Closing tag - decrease indent before this line
|
||||
if (trimmed.startsWith('</')) {
|
||||
indent = Math.max(0, currentIndent - 1);
|
||||
nextIndent = indent;
|
||||
|
||||
// If closing a step, reset check depth
|
||||
if (tagName === 'step' || tagName === 'workflow') {
|
||||
nextCheckDepth = 0;
|
||||
}
|
||||
}
|
||||
// Self-closing tags (opens and closes on same line)
|
||||
// EXCEPT <check> tags which create logical blocks
|
||||
else if (this.isSelfClosingTag(trimmed) && tagName !== 'check') {
|
||||
// These don't change indent level
|
||||
indent = currentIndent;
|
||||
nextIndent = currentIndent;
|
||||
}
|
||||
// Opening tags
|
||||
else if (trimmed.startsWith('<')) {
|
||||
// Check if this is a <check> tag - these create logical blocks
|
||||
if (tagName === 'check') {
|
||||
indent = currentIndent;
|
||||
// Check tags increase indent for following content
|
||||
nextIndent = currentIndent + 1;
|
||||
nextCheckDepth = checkDepth + 1;
|
||||
}
|
||||
// <action> tags inside check blocks stay at current indent
|
||||
else if (tagName === 'action' && checkDepth > 0) {
|
||||
indent = currentIndent;
|
||||
nextIndent = currentIndent; // Don't increase further
|
||||
}
|
||||
// Other tags close check blocks and return to structural level
|
||||
else if (checkDepth > 0) {
|
||||
// Close all check blocks - return to base structural level
|
||||
indent = Math.max(0, currentIndent - checkDepth);
|
||||
nextIndent = indent + 1;
|
||||
nextCheckDepth = 0;
|
||||
}
|
||||
// Regular opening tags (no check blocks active)
|
||||
else {
|
||||
indent = currentIndent;
|
||||
nextIndent = currentIndent + 1;
|
||||
}
|
||||
}
|
||||
|
||||
const indentStr = ' '.repeat(indent * this.indentSize);
|
||||
return {
|
||||
line: indentStr + trimmed,
|
||||
nextIndent: nextIndent,
|
||||
nextCheckDepth: nextCheckDepth,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if tag opens and closes on same line
|
||||
*/
|
||||
isSelfClosingTag(line) {
|
||||
// Self-closing with />
|
||||
if (line.endsWith('/>')) {
|
||||
return true;
|
||||
}
|
||||
// Opens and closes on same line: <tag>content</tag>
|
||||
const match = line.match(/^<([a-zA-Z-]+)(\s[^>]*)?>.*<\/\1>$/);
|
||||
return match !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if tag is a block-level structural tag
|
||||
*/
|
||||
isBlockLevelTag(tagName) {
|
||||
return ['step', 'workflow', 'check'].includes(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CLI Entry Point
|
||||
*/
|
||||
function main() {
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
||||
console.log(`
|
||||
BMAD Workflow Markdown Formatter
|
||||
|
||||
Usage:
|
||||
node format-workflow-md.js <file-pattern> [options]
|
||||
|
||||
Options:
|
||||
--verbose, -v Verbose output
|
||||
--check, -c Check formatting without writing (exit 1 if changes needed)
|
||||
--help, -h Show this help
|
||||
|
||||
Examples:
|
||||
node format-workflow-md.js src/**/instructions.md
|
||||
node format-workflow-md.js "src/modules/bmb/**/*.md" --verbose
|
||||
node format-workflow-md.js file.md --check
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const verbose = args.includes('--verbose') || args.includes('-v');
|
||||
const check = args.includes('--check') || args.includes('-c');
|
||||
|
||||
// Remove flags from args
|
||||
const files = args.filter((arg) => !arg.startsWith('-'));
|
||||
|
||||
const formatter = new WorkflowFormatter({ verbose });
|
||||
let hasChanges = false;
|
||||
let formattedCount = 0;
|
||||
|
||||
// Process files
|
||||
for (const pattern of files) {
|
||||
// For now, treat as direct file path
|
||||
// TODO: Add glob support for patterns
|
||||
if (fs.existsSync(pattern)) {
|
||||
const stat = fs.statSync(pattern);
|
||||
if (stat.isFile()) {
|
||||
const changed = formatter.format(pattern);
|
||||
if (changed) {
|
||||
hasChanges = true;
|
||||
formattedCount++;
|
||||
}
|
||||
} else if (stat.isDirectory()) {
|
||||
console.error(`Error: ${pattern} is a directory. Please specify file paths.`);
|
||||
}
|
||||
} else {
|
||||
console.error(`Error: File not found: ${pattern}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose || formattedCount > 0) {
|
||||
console.log(`\nFormatted ${formattedCount} file(s)`);
|
||||
}
|
||||
|
||||
if (check && hasChanges) {
|
||||
console.error('\n❌ Some files need formatting. Run without --check to format.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Run if called directly
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = { WorkflowFormatter };
|
||||
Loading…
Reference in New Issue