mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-17 09:45:25 +00:00
fix: optimize agent compiler and complete handler cleanup
- Add deployment-aware handler generation (filters web-only/ide-only commands) - Remove unused run-workflow handler type (ghost handler cleanup) - Implement missing validate-workflow and data handler generation - Update schema validation to support exactly 6 active handler types - Clean up activation templates and web bundler logic - Prevent generation of unused handler instructions for better performance - All 62 tests pass with backward compatibility maintained
This commit is contained in:
parent
cd98a7f5bb
commit
3740a554f0
@ -38,7 +38,7 @@
|
||||
- [ ] Config values use {config_source}: pattern
|
||||
- [ ] Agent follows naming conventions (kebab-case for files)
|
||||
- [ ] ALL paths reference {project-root}/{bmad_folder}/{{module}}/ locations, NOT src/
|
||||
- [ ] exec, data, run-workflow commands point to final BMAD installation paths
|
||||
- [ ] exec, data, workflow commands point to final BMAD installation paths
|
||||
|
||||
### For Template/Workflow Conversions
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ For Modules:
|
||||
<action>Example path conversions:
|
||||
|
||||
- exec="{project-root}/{bmad_folder}/{{target_module}}/tasks/task-name.md"
|
||||
- run-workflow="{project-root}/{bmad_folder}/{{target_module}}/workflows/workflow-name/workflow.yaml"
|
||||
- workflow="{project-root}/{bmad_folder}/{{target_module}}/workflows/workflow-name/workflow.yaml"
|
||||
- data="{project-root}/{bmad_folder}/{{target_module}}/data/data-file.yaml"
|
||||
</action>
|
||||
<action>Save to: {bmad_folder}/{{target_module}}/agents/{{agent_name}}.agent.yaml (physical location)</action>
|
||||
|
||||
@ -20,19 +20,19 @@ agent:
|
||||
menu:
|
||||
- trigger: brainstorm-project
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml"
|
||||
description: Guided Brainstorming
|
||||
description: Guided Brainstorming scoped to product development ideation and problem discovery
|
||||
|
||||
- trigger: research
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/1-analysis/research/workflow.yaml"
|
||||
description: Guided Research
|
||||
description: Guided Research scoped to market and competitive analysis of a product or feature
|
||||
|
||||
- trigger: product-brief
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/1-analysis/product-brief/workflow.yaml"
|
||||
description: Create a Product Brief
|
||||
description: Create a Product Brief, a great input to then drive a PRD
|
||||
|
||||
- trigger: document-project
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/document-project/workflow.yaml"
|
||||
description: Generate comprehensive documentation of an existing Project
|
||||
description: Generate comprehensive documentation of an existing codebase, including architecture, data flows, and API contracts, and other details to aid project understanding.
|
||||
|
||||
- trigger: party-mode
|
||||
workflow: "{project-root}/{bmad_folder}/core/workflows/party-mode/workflow.yaml"
|
||||
|
||||
@ -24,7 +24,6 @@ agent:
|
||||
|
||||
- trigger: validate-architecture
|
||||
validate-workflow: "{project-root}/{bmad_folder}/bmm/workflows/3-solutioning/architecture/workflow.yaml"
|
||||
checklist: "{project-root}/{bmad_folder}/bmm/workflows/3-solutioning/architecture/checklist.md"
|
||||
description: Validate Architecture Document
|
||||
|
||||
- trigger: implementation-readiness
|
||||
|
||||
@ -25,13 +25,11 @@ agent:
|
||||
|
||||
- trigger: validate-prd
|
||||
validate-workflow: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/prd/workflow.yaml"
|
||||
checklist: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/prd/checklist.md"
|
||||
document: "{output_folder}/PRD.md"
|
||||
description: Validate PRD + Epics + Stories completeness and quality
|
||||
description: Validate PRD
|
||||
|
||||
- trigger: create-epics-and-stories
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.yaml"
|
||||
description: Break PRD requirements into implementable epics and stories after the architecture is defined
|
||||
description: Create Epics and User Stories from PRD (Its recommended to not do this until the architecture is complete)
|
||||
|
||||
- trigger: correct-course
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/4-implementation/correct-course/workflow.yaml"
|
||||
|
||||
@ -19,7 +19,6 @@ agent:
|
||||
- Find if this exists, if it does, always treat it as the bible I plan and execute against: `**/project-context.md ``
|
||||
|
||||
menu:
|
||||
# Quick-Flow workflows - Barry owns the entire quick-flow path from spec to ship
|
||||
- trigger: create-tech-spec
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/bmad-quick-flow/create-tech-spec/workflow.yaml"
|
||||
description: Architect a technical spec with implementation-ready stories
|
||||
|
||||
@ -25,12 +25,10 @@ agent:
|
||||
menu:
|
||||
- trigger: create-ux-design
|
||||
workflow: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml"
|
||||
description: Conduct Design Thinking Workshop to Define the User Specification
|
||||
description: Conduct Design Thinking Workshop to Define the User Specification with PRD as input
|
||||
|
||||
- trigger: validate-design
|
||||
validate-workflow: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml"
|
||||
checklist: "{project-root}/{bmad_folder}/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md"
|
||||
document: "{output_folder}/ux-spec.md"
|
||||
description: Validate UX Specification and Design Artifacts
|
||||
|
||||
- trigger: create-excalidraw-wireframe
|
||||
|
||||
@ -83,7 +83,7 @@ Master storyteller with 50+ years crafting compelling narratives across multiple
|
||||
All CIS agents are **Module Agents** with:
|
||||
|
||||
- Integration with CIS module configuration
|
||||
- Access to workflow invocation via `run-workflow` or `exec` attributes
|
||||
- Access to workflow invocation via `workflow` or `exec` attributes
|
||||
- Standard critical actions for config loading and user context
|
||||
- Simple command structure focused on workflow facilitation
|
||||
|
||||
|
||||
@ -8,16 +8,8 @@
|
||||
</init>
|
||||
<commands critical="MANDATORY">
|
||||
<input>Number → cmd[n] | Text → fuzzy match *commands</input>
|
||||
<extract>exec, tmpl, data, action, run-workflow, validate-workflow</extract>
|
||||
<extract>exec, tmpl, data, action, validate-workflow</extract>
|
||||
<handlers>
|
||||
<handler type="run-workflow">
|
||||
When command has: run-workflow="path/to/x.yaml" You MUST:
|
||||
1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/workflow.xml
|
||||
2. READ its entire contents - the is the CORE OS for EXECUTING workflows
|
||||
3. Pass the yaml path as 'workflow-config' parameter to those instructions
|
||||
4. Follow workflow.xml instructions EXACTLY as written
|
||||
5. Save outputs after EACH section (never batch)
|
||||
</handler>
|
||||
<handler type="progressive-workflow">
|
||||
When command has: run-progressive-workflow="path/to/x.yaml" You MUST:
|
||||
1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/workflow.xml
|
||||
|
||||
@ -21,18 +21,8 @@
|
||||
</bundled-files>
|
||||
<commands critical="MANDATORY">
|
||||
<input>Number → cmd[n] | Text → fuzzy match *commands</input>
|
||||
<extract>exec, tmpl, data, action, run-workflow, validate-workflow</extract>
|
||||
<extract>exec, tmpl, data, action, validate-workflow</extract>
|
||||
<handlers>
|
||||
<handler type="run-workflow">
|
||||
When command has: run-workflow="path/to/x.yaml" You MUST:
|
||||
1. CRITICAL: Locate <file id="{bmad_folder}/core/tasks/workflow.xml"> in this XML bundle
|
||||
2. Extract and READ its CDATA content - this is the CORE OS for EXECUTING workflows
|
||||
3. Locate <file id="path/to/x.yaml"> for the workflow config
|
||||
4. Pass the yaml content as 'workflow-config' parameter to workflow.xml instructions
|
||||
5. Follow workflow.xml instructions EXACTLY as written
|
||||
6. When workflow references other files, locate them by id in <file> elements
|
||||
7. Save outputs after EACH section (never batch)
|
||||
</handler>
|
||||
<handler type="action">
|
||||
When command has: action="#id" → Find prompt with id="id" in current agent XML, execute its content
|
||||
When command has: action="text" → Execute the text directly as a critical action prompt
|
||||
|
||||
@ -116,7 +116,7 @@ Tests required menu structure:
|
||||
|
||||
Tests menu item command targets:
|
||||
|
||||
- ✅ Valid: All 7 command types (`workflow`, `validate-workflow`, `exec`, `action`, `tmpl`, `data`, `run-workflow`)
|
||||
- ✅ Valid: All 6 command types (`workflow`, `validate-workflow`, `exec`, `action`, `tmpl`, `data`)
|
||||
- ✅ Valid: Multiple command targets in one menu item
|
||||
- ❌ Invalid: No command target fields
|
||||
- ❌ Invalid: Empty string command targets
|
||||
|
||||
@ -34,6 +34,4 @@ agent:
|
||||
- trigger: data-test
|
||||
description: Test data command
|
||||
data: path/to/data
|
||||
- trigger: run-workflow-test
|
||||
description: Test run-workflow command
|
||||
run-workflow: path/to/workflow
|
||||
|
||||
@ -748,10 +748,9 @@ class WebBundler {
|
||||
}
|
||||
}
|
||||
|
||||
// Extract workflow references - both 'workflow' and 'run-workflow' attributes
|
||||
// Extract workflow references from agent files
|
||||
const workflowPatterns = [
|
||||
/workflow="([^"]+)"/g, // Menu items with workflow attribute
|
||||
/run-workflow="([^"]+)"/g, // Commands with run-workflow attribute
|
||||
/validate-workflow="([^"]+)"/g, // Validation workflow references
|
||||
];
|
||||
|
||||
@ -789,16 +788,6 @@ class WebBundler {
|
||||
// Match: <item cmd="..." workflow="workflowPath">...</item>
|
||||
const itemWorkflowPattern = new RegExp(`\\s*<item\\s+[^>]*workflow="[^"]*${escapedPath}"[^>]*>.*?</item>\\s*`, 'gs');
|
||||
modifiedXml = modifiedXml.replace(itemWorkflowPattern, '');
|
||||
|
||||
// Pattern 2: Remove <item> tags with run-workflow attribute
|
||||
// Match: <item cmd="..." run-workflow="workflowPath">...</item>
|
||||
const itemRunWorkflowPattern = new RegExp(`\\s*<item\\s+[^>]*run-workflow="[^"]*${escapedPath}"[^>]*>.*?</item>\\s*`, 'gs');
|
||||
modifiedXml = modifiedXml.replace(itemRunWorkflowPattern, '');
|
||||
|
||||
// Pattern 3: Remove <c> tags with run-workflow attribute (legacy)
|
||||
// Match: <c cmd="..." run-workflow="workflowPath">...</c>
|
||||
const cPattern = new RegExp(`\\s*<c\\s+[^>]*run-workflow="[^"]*${escapedPath}"[^>]*>.*?</c>\\s*`, 'gs');
|
||||
modifiedXml = modifiedXml.replace(cPattern, '');
|
||||
}
|
||||
|
||||
return modifiedXml;
|
||||
|
||||
@ -49,9 +49,10 @@ You must fully embody this agent's persona and follow all activation instruction
|
||||
* Build simple activation block for custom agents
|
||||
* @param {Array} criticalActions - Agent-specific critical actions
|
||||
* @param {Array} menuItems - Menu items to determine which handlers to include
|
||||
* @param {string} deploymentType - 'ide' or 'web' - filters commands based on ide-only/web-only flags
|
||||
* @returns {string} Activation XML
|
||||
*/
|
||||
function buildSimpleActivation(criticalActions = [], menuItems = []) {
|
||||
function buildSimpleActivation(criticalActions = [], menuItems = [], deploymentType = 'ide') {
|
||||
let activation = '<activation critical="MANDATORY">\n';
|
||||
|
||||
let stepNum = 1;
|
||||
@ -75,13 +76,28 @@ function buildSimpleActivation(criticalActions = [], menuItems = []) {
|
||||
activation += ` <step n="${stepNum++}">On user input: Number → execute menu item[n] | Text → case-insensitive substring match | Multiple matches → ask user
|
||||
to clarify | No match → show "Not recognized"</step>\n`;
|
||||
|
||||
// Detect which handlers are actually used
|
||||
// Filter menu items based on deployment type
|
||||
const filteredMenuItems = menuItems.filter((item) => {
|
||||
// Skip web-only commands for IDE deployment
|
||||
if (deploymentType === 'ide' && item['web-only'] === true) {
|
||||
return false;
|
||||
}
|
||||
// Skip ide-only commands for web deployment
|
||||
if (deploymentType === 'web' && item['ide-only'] === true) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Detect which handlers are actually used in the filtered menu
|
||||
const usedHandlers = new Set();
|
||||
for (const item of menuItems) {
|
||||
for (const item of filteredMenuItems) {
|
||||
if (item.action) usedHandlers.add('action');
|
||||
if (item.workflow) usedHandlers.add('workflow');
|
||||
if (item.exec) usedHandlers.add('exec');
|
||||
if (item.tmpl) usedHandlers.add('tmpl');
|
||||
if (item.data) usedHandlers.add('data');
|
||||
if (item['validate-workflow']) usedHandlers.add('validate-workflow');
|
||||
}
|
||||
|
||||
// Only include menu-handlers section if handlers are used
|
||||
@ -124,6 +140,25 @@ function buildSimpleActivation(criticalActions = [], menuItems = []) {
|
||||
</handler>\n`;
|
||||
}
|
||||
|
||||
if (usedHandlers.has('data')) {
|
||||
activation += ` <handler type="data">
|
||||
When menu item has: data="path/to/x.json|yaml|yml"
|
||||
Load the file, parse as JSON/YAML, make available as {data} to subsequent operations
|
||||
</handler>\n`;
|
||||
}
|
||||
|
||||
if (usedHandlers.has('validate-workflow')) {
|
||||
activation += ` <handler type="validate-workflow">
|
||||
When menu item has: validate-workflow="path/to/workflow.yaml"
|
||||
1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/validate-workflow.xml
|
||||
2. Read the complete file - this is the CORE OS for validating BMAD workflows
|
||||
3. Pass the workflow.yaml path as 'workflow' parameter to those instructions
|
||||
4. Pass any checklist.md from the workflow location as 'checklist' parameter if available
|
||||
5. Execute validate-workflow.xml instructions precisely following all steps
|
||||
6. Generate validation report with thorough analysis
|
||||
</handler>\n`;
|
||||
}
|
||||
|
||||
activation += ` </handlers>
|
||||
</menu-handlers>\n`;
|
||||
}
|
||||
@ -275,8 +310,8 @@ function compileToXml(agentYaml, agentName = '', targetPath = '') {
|
||||
|
||||
xml += `<agent ${agentAttrs.join(' ')}>\n`;
|
||||
|
||||
// Activation block - pass menu items to determine which handlers to include
|
||||
xml += buildSimpleActivation(agent.critical_actions || [], agent.menu || []);
|
||||
// Activation block - pass menu items and deployment type to determine which handlers to include
|
||||
xml += buildSimpleActivation(agent.critical_actions || [], agent.menu || [], 'ide');
|
||||
|
||||
// Persona section
|
||||
xml += buildPersonaXml(agent.persona);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
const assert = require('node:assert');
|
||||
const { z } = require('zod');
|
||||
|
||||
const COMMAND_TARGET_KEYS = ['workflow', 'validate-workflow', 'exec', 'action', 'tmpl', 'data', 'run-workflow'];
|
||||
const COMMAND_TARGET_KEYS = ['workflow', 'validate-workflow', 'exec', 'action', 'tmpl', 'data'];
|
||||
const TRIGGER_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
||||
|
||||
// Public API ---------------------------------------------------------------
|
||||
@ -180,7 +180,6 @@ function buildMenuItemSchema() {
|
||||
action: createNonEmptyString('agent.menu[].action').optional(),
|
||||
tmpl: createNonEmptyString('agent.menu[].tmpl').optional(),
|
||||
data: createNonEmptyString('agent.menu[].data').optional(),
|
||||
'run-workflow': createNonEmptyString('agent.menu[].run-workflow').optional(),
|
||||
checklist: createNonEmptyString('agent.menu[].checklist').optional(),
|
||||
document: createNonEmptyString('agent.menu[].document').optional(),
|
||||
'ide-only': z.boolean().optional(),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user