2025-10-02 21:45:59 -05:00
const yaml = require ( 'js-yaml' ) ;
const fs = require ( 'fs-extra' ) ;
const path = require ( 'node:path' ) ;
const crypto = require ( 'node:crypto' ) ;
const { AgentAnalyzer } = require ( './agent-analyzer' ) ;
const { ActivationBuilder } = require ( './activation-builder' ) ;
2025-12-13 16:22:34 +08:00
const { escapeXml } = require ( '../../lib/xml-utils' ) ;
2025-10-02 21:45:59 -05:00
/ * *
* Converts agent YAML files to XML format with smart activation injection
* /
class YamlXmlBuilder {
constructor ( ) {
this . analyzer = new AgentAnalyzer ( ) ;
this . activationBuilder = new ActivationBuilder ( ) ;
}
/ * *
* Deep merge two objects ( for customize . yaml + agent . yaml )
* @ param { Object } target - Target object
* @ param { Object } source - Source object to merge in
* @ returns { Object } Merged object
* /
deepMerge ( target , source ) {
const output = { ... target } ;
if ( this . isObject ( target ) && this . isObject ( source ) ) {
for ( const key of Object . keys ( source ) ) {
if ( this . isObject ( source [ key ] ) ) {
if ( key in target ) {
output [ key ] = this . deepMerge ( target [ key ] , source [ key ] ) ;
} else {
output [ key ] = source [ key ] ;
}
} else if ( Array . isArray ( source [ key ] ) ) {
// For arrays, append rather than replace (for commands)
if ( Array . isArray ( target [ key ] ) ) {
output [ key ] = [ ... target [ key ] , ... source [ key ] ] ;
} else {
output [ key ] = source [ key ] ;
}
} else {
output [ key ] = source [ key ] ;
}
}
}
return output ;
}
/ * *
* Check if value is an object
* /
isObject ( item ) {
return item && typeof item === 'object' && ! Array . isArray ( item ) ;
}
/ * *
* Load and merge agent YAML with customization
* @ param { string } agentYamlPath - Path to base agent YAML
* @ param { string } customizeYamlPath - Path to customize YAML ( optional )
* @ returns { Object } Merged agent configuration
* /
async loadAndMergeAgent ( agentYamlPath , customizeYamlPath = null ) {
// Load base agent
const agentContent = await fs . readFile ( agentYamlPath , 'utf8' ) ;
const agentYaml = yaml . load ( agentContent ) ;
// Load customization if exists
let merged = agentYaml ;
if ( customizeYamlPath && ( await fs . pathExists ( customizeYamlPath ) ) ) {
const customizeContent = await fs . readFile ( customizeYamlPath , 'utf8' ) ;
const customizeYaml = yaml . load ( customizeContent ) ;
if ( customizeYaml ) {
// Special handling: persona fields are merged, but only non-empty values override
if ( customizeYaml . persona ) {
const basePersona = merged . agent . persona || { } ;
const customPersona = { } ;
// Only copy non-empty customize values
for ( const [ key , value ] of Object . entries ( customizeYaml . persona ) ) {
if ( value !== '' && value !== null && ! ( Array . isArray ( value ) && value . length === 0 ) ) {
customPersona [ key ] = value ;
}
}
// Merge non-empty customize values over base
if ( Object . keys ( customPersona ) . length > 0 ) {
merged . agent . persona = { ... basePersona , ... customPersona } ;
}
}
// Merge metadata (only non-empty values)
if ( customizeYaml . agent && customizeYaml . agent . metadata ) {
const nonEmptyMetadata = { } ;
for ( const [ key , value ] of Object . entries ( customizeYaml . agent . metadata ) ) {
if ( value !== '' && value !== null ) {
nonEmptyMetadata [ key ] = value ;
}
}
merged . agent . metadata = { ... merged . agent . metadata , ... nonEmptyMetadata } ;
}
// Append menu items (support both 'menu' and legacy 'commands')
const customMenuItems = customizeYaml . menu || customizeYaml . commands ;
if ( customMenuItems ) {
// Determine if base uses 'menu' or 'commands'
if ( merged . agent . menu ) {
merged . agent . menu = [ ... merged . agent . menu , ... customMenuItems ] ;
} else if ( merged . agent . commands ) {
merged . agent . commands = [ ... merged . agent . commands , ... customMenuItems ] ;
} else {
// Default to 'menu' for new agents
merged . agent . menu = customMenuItems ;
}
}
// Append critical actions
if ( customizeYaml . critical _actions ) {
merged . agent . critical _actions = [ ... ( merged . agent . critical _actions || [ ] ) , ... customizeYaml . critical _actions ] ;
}
2025-11-16 14:36:32 +08:00
// Append prompts
if ( customizeYaml . prompts ) {
merged . agent . prompts = [ ... ( merged . agent . prompts || [ ] ) , ... customizeYaml . prompts ] ;
}
// Append memories
if ( customizeYaml . memories ) {
merged . agent . memories = [ ... ( merged . agent . memories || [ ] ) , ... customizeYaml . memories ] ;
}
2025-10-02 21:45:59 -05:00
}
}
return merged ;
}
/ * *
* Convert agent YAML to XML
* @ param { Object } agentYaml - Parsed agent YAML object
* @ param { Object } buildMetadata - Metadata about the build ( file paths , hashes , etc . )
* @ returns { string } XML content
* /
async convertToXml ( agentYaml , buildMetadata = { } ) {
const agent = agentYaml . agent ;
const metadata = agent . metadata || { } ;
2025-10-04 21:33:19 -05:00
// Add module from buildMetadata if available
if ( buildMetadata . module ) {
metadata . module = buildMetadata . module ;
}
2025-10-02 21:45:59 -05:00
// Analyze agent to determine needed handlers
const profile = this . analyzer . analyzeAgentObject ( agentYaml ) ;
2025-10-03 19:08:34 -05:00
// Build activation block only if not skipped
let activationBlock = '' ;
if ( ! buildMetadata . skipActivation ) {
2025-10-03 21:46:53 -05:00
activationBlock = await this . activationBuilder . buildActivation (
profile ,
metadata ,
agent . critical _actions || [ ] ,
buildMetadata . forWebBundle || false , // Pass web bundle flag
) ;
2025-10-03 19:08:34 -05:00
}
2025-10-02 21:45:59 -05:00
// Start building XML
2025-10-19 11:59:27 -05:00
let xml = '' ;
if ( buildMetadata . forWebBundle ) {
// Web bundle: keep existing format
xml += '<!-- Powered by BMAD-CORE™ -->\n\n' ;
xml += ` # ${ metadata . title || 'Agent' } \n \n ` ;
} else {
// Installation: use YAML frontmatter + instruction
// Extract name from filename: "cli-chief.yaml" or "pm.agent.yaml" -> "cli chief" or "pm"
const filename = buildMetadata . sourceFile || 'agent.yaml' ;
let nameFromFile = path . basename ( filename , path . extname ( filename ) ) ; // Remove .yaml/.md extension
nameFromFile = nameFromFile . replace ( /\.agent$/ , '' ) ; // Remove .agent suffix if present
nameFromFile = nameFromFile . replaceAll ( '-' , ' ' ) ; // Replace dashes with spaces
xml += '---\n' ;
xml += ` name: " ${ nameFromFile } " \n ` ;
xml += ` description: " ${ metadata . title || 'BMAD Agent' } " \n ` ;
xml += '---\n\n' ;
xml +=
"You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.\n\n" ;
}
2025-10-02 21:45:59 -05:00
xml += '```xml\n' ;
// Agent opening tag
const agentAttrs = [
` id=" ${ metadata . id || '' } " ` ,
` name=" ${ metadata . name || '' } " ` ,
` title=" ${ metadata . title || '' } " ` ,
` icon=" ${ metadata . icon || '🤖' } " ` ,
] ;
// Add localskip attribute if present
if ( metadata . localskip === true ) {
agentAttrs . push ( 'localskip="true"' ) ;
}
xml += ` <agent ${ agentAttrs . join ( ' ' ) } > \n ` ;
2025-10-03 19:08:34 -05:00
// Activation block (only if not skipped)
if ( activationBlock ) {
xml += activationBlock + '\n' ;
}
2025-10-02 21:45:59 -05:00
// Persona section
xml += this . buildPersonaXml ( agent . persona ) ;
2025-11-16 14:36:32 +08:00
// Memories section (if exists)
if ( agent . memories ) {
xml += this . buildMemoriesXml ( agent . memories ) ;
}
2025-10-02 21:45:59 -05:00
// Prompts section (if exists)
if ( agent . prompts ) {
xml += this . buildPromptsXml ( agent . prompts ) ;
}
// Menu section (support both 'menu' and legacy 'commands')
const menuItems = agent . menu || agent . commands || [ ] ;
2025-11-15 19:39:53 -06:00
xml += this . buildCommandsXml ( menuItems , buildMetadata . forWebBundle ) ;
2025-10-02 21:45:59 -05:00
xml += '</agent>\n' ;
xml += '```\n' ;
return xml ;
}
/ * *
* Build persona XML section
* /
buildPersonaXml ( persona ) {
if ( ! persona ) return '' ;
let xml = ' <persona>\n' ;
if ( persona . role ) {
2025-12-13 16:22:34 +08:00
xml += ` <role> ${ escapeXml ( persona . role ) } </role> \n ` ;
2025-10-02 21:45:59 -05:00
}
if ( persona . identity ) {
2025-12-13 16:22:34 +08:00
xml += ` <identity> ${ escapeXml ( persona . identity ) } </identity> \n ` ;
2025-10-02 21:45:59 -05:00
}
if ( persona . communication _style ) {
2025-12-13 16:22:34 +08:00
xml += ` <communication_style> ${ escapeXml ( persona . communication _style ) } </communication_style> \n ` ;
2025-10-02 21:45:59 -05:00
}
if ( persona . principles ) {
// Principles can be array or string
let principlesText ;
if ( Array . isArray ( persona . principles ) ) {
principlesText = persona . principles . join ( ' ' ) ;
} else {
principlesText = persona . principles ;
}
2025-12-13 16:22:34 +08:00
xml += ` <principles> ${ escapeXml ( principlesText ) } </principles> \n ` ;
2025-10-02 21:45:59 -05:00
}
xml += ' </persona>\n' ;
return xml ;
}
2025-11-16 14:36:32 +08:00
/ * *
* Build memories XML section
* /
buildMemoriesXml ( memories ) {
if ( ! memories || memories . length === 0 ) return '' ;
let xml = ' <memories>\n' ;
for ( const memory of memories ) {
2025-12-13 16:22:34 +08:00
xml += ` <memory> ${ escapeXml ( memory ) } </memory> \n ` ;
2025-11-16 14:36:32 +08:00
}
xml += ' </memories>\n' ;
return xml ;
}
2025-10-02 21:45:59 -05:00
/ * *
* Build prompts XML section
2025-11-12 22:40:45 -06:00
* Handles both array format and object / dictionary format
2025-10-02 21:45:59 -05:00
* /
buildPromptsXml ( prompts ) {
2025-11-12 22:40:45 -06:00
if ( ! prompts ) return '' ;
// Handle object/dictionary format: { promptId: 'content', ... }
// Convert to array format for processing
let promptsArray = prompts ;
if ( ! Array . isArray ( prompts ) ) {
// Check if it's an object with no length property (dictionary format)
if ( typeof prompts === 'object' && prompts . length === undefined ) {
promptsArray = Object . entries ( prompts ) . map ( ( [ id , content ] ) => ( {
id : id ,
content : content ,
} ) ) ;
} else {
return '' ; // Not a valid prompts format
}
}
if ( promptsArray . length === 0 ) return '' ;
2025-10-02 21:45:59 -05:00
let xml = ' <prompts>\n' ;
2025-11-12 22:40:45 -06:00
for ( const prompt of promptsArray ) {
2025-10-02 21:45:59 -05:00
xml += ` <prompt id=" ${ prompt . id || '' } "> \n ` ;
2025-11-16 14:36:32 +08:00
xml += ` <content> \n ` ;
2025-12-13 16:22:34 +08:00
xml += ` ${ escapeXml ( prompt . content || '' ) } \n ` ;
2025-11-16 14:36:32 +08:00
xml += ` </content> \n ` ;
2025-10-02 21:45:59 -05:00
xml += ` </prompt> \n ` ;
}
xml += ' </prompts>\n' ;
return xml ;
}
/ * *
* Build menu XML section ( renamed from commands for clarity )
* Auto - injects * help and * exit , adds * prefix to all triggers
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
* Supports both legacy format and new multi format with nested handlers
2025-11-15 19:39:53 -06:00
* @ param { Array } menuItems - Menu items from YAML
* @ param { boolean } forWebBundle - Whether building for web bundle
2025-10-02 21:45:59 -05:00
* /
2025-11-15 19:39:53 -06:00
buildCommandsXml ( menuItems , forWebBundle = false ) {
2025-10-02 21:45:59 -05:00
let xml = ' <menu>\n' ;
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Always inject menu display option first
xml += ` <item cmd="*menu">[M] Redisplay Menu Options</item> \n ` ;
2025-10-02 21:45:59 -05:00
// Add user-defined menu items with * prefix
if ( menuItems && menuItems . length > 0 ) {
for ( const item of menuItems ) {
2025-11-15 19:39:53 -06:00
// Skip ide-only items when building for web bundles
if ( forWebBundle && item [ 'ide-only' ] === true ) {
continue ;
}
// Skip web-only items when NOT building for web bundles (i.e., IDE/local installation)
if ( ! forWebBundle && item [ 'web-only' ] === true ) {
continue ;
}
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Handle multi format menu items with nested handlers
if ( item . multi && item . triggers && Array . isArray ( item . triggers ) ) {
2025-12-13 16:22:34 +08:00
xml += ` <item type="multi"> ${ escapeXml ( item . multi ) } \n ` ;
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
xml += this . buildNestedHandlers ( item . triggers ) ;
xml += ` </item> \n ` ;
2025-10-02 21:45:59 -05:00
}
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Handle legacy format menu items
else if ( item . trigger ) {
// For legacy items, keep using cmd with *<trigger> format
let trigger = item . trigger || '' ;
if ( ! trigger . startsWith ( '*' ) ) {
trigger = '*' + trigger ;
}
2025-10-02 21:45:59 -05:00
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
const attrs = [ ` cmd=" ${ trigger } " ` ] ;
2025-10-02 21:45:59 -05:00
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Add handler attributes
// If workflow-install exists, use its value for workflow attribute (vendoring)
// workflow-install is build-time metadata - tells installer where to copy workflows
// The final XML should only have workflow pointing to the install location
if ( item [ 'workflow-install' ] ) {
attrs . push ( ` workflow=" ${ item [ 'workflow-install' ] } " ` ) ;
} else if ( item . workflow ) {
attrs . push ( ` workflow=" ${ item . workflow } " ` ) ;
}
2025-11-05 20:44:22 -06:00
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
if ( item [ 'validate-workflow' ] ) attrs . push ( ` validate-workflow=" ${ item [ 'validate-workflow' ] } " ` ) ;
if ( item . exec ) attrs . push ( ` exec=" ${ item . exec } " ` ) ;
if ( item . tmpl ) attrs . push ( ` tmpl=" ${ item . tmpl } " ` ) ;
if ( item . data ) attrs . push ( ` data=" ${ item . data } " ` ) ;
if ( item . action ) attrs . push ( ` action=" ${ item . action } " ` ) ;
2025-10-02 21:45:59 -05:00
2025-12-13 16:22:34 +08:00
xml += ` <item ${ attrs . join ( ' ' ) } > ${ escapeXml ( item . description || '' ) } </item> \n ` ;
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
}
2025-10-02 21:45:59 -05:00
}
}
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Always inject dismiss last
xml += ` <item cmd="*dismiss">[D] Dismiss Agent</item> \n ` ;
2025-10-02 21:45:59 -05:00
xml += ' </menu>\n' ;
return xml ;
}
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
/ * *
* Build nested handlers for multi format menu items
* @ param { Array } triggers - Triggers array from multi format
* @ returns { string } Handler XML
* /
buildNestedHandlers ( triggers ) {
let xml = '' ;
for ( const triggerGroup of triggers ) {
for ( const [ triggerName , execArray ] of Object . entries ( triggerGroup ) ) {
// Build trigger with * prefix
let trigger = triggerName . startsWith ( '*' ) ? triggerName : '*' + triggerName ;
// Extract the relevant execution data
const execData = this . processExecArray ( execArray ) ;
// For nested handlers in multi items, we don't need cmd attribute
// The match attribute will handle fuzzy matching
2025-12-13 16:22:34 +08:00
const attrs = [ ` match=" ${ escapeXml ( execData . description || '' ) } " ` ] ;
feat: implement granular step-file workflow architecture with multi-menu support
## Major Features Added
- **Step-file workflow architecture**: Transform monolithic workflows into granular step files for improved LLM adherence and consistency
- **Multi-menu handler system**: New `handler-multi.xml` enables grouped menu items with fuzzy matching
- **Workflow compliance checker**: Added automated compliance validation for all workflows
- **Create/edit agent workflows**: New structured workflows for agent creation and editing
## Workflow Enhancements
- **Create-workflow**: Expanded from 6 to 14 detailed steps covering tools, design, compliance
- **Granular step execution**: Each workflow step now has dedicated files for focused execution
- **New documentation**: Added CSV data standards, intent vs prescriptive spectrum, and common tools reference
## Complete Migration Status
- **4 workflows fully migrated**: `create-agent`, `edit-agent`, `create-workflow`, and `edit-workflow` now use the new granular step-file architecture
- **Legacy transformation**: `edit-workflow` includes built-in capability to transform legacy single-file workflows into the new improved granular format
- **Future cleanup**: Legacy versions will be removed in a future commit after validation
## Schema Updates
- **Multi-menu support**: Updated agent schema to support `triggers` array for grouped menu items
- **Legacy compatibility**: Maintains backward compatibility with single `trigger` field
- **Discussion enhancements**: Added conversational_knowledge recommendation for discussion agents
## File Structure Changes
- Added: `create-agent/`, `edit-agent/`, `edit-workflow/`, `workflow-compliance-check/` workflows
- Added: Documentation standards and CSV reference files
- Refactored: `create-workflow/steps/` with detailed granular step files
## Handler Improvements
- Enhanced `handler-exec.xml` with clearer execution instructions
- Improved data passing context for executed files
- Better error handling and user guidance
This architectural change significantly improves workflow execution consistency across all LLM models by breaking complex processes into manageable, focused steps. The edit-workflow transformation tool ensures smooth migration of existing workflows to the new format.
2025-11-30 15:09:23 -06:00
// Add handler attributes based on exec data
if ( execData . route ) attrs . push ( ` exec=" ${ execData . route } " ` ) ;
if ( execData . workflow ) attrs . push ( ` workflow=" ${ execData . workflow } " ` ) ;
if ( execData [ 'validate-workflow' ] ) attrs . push ( ` validate-workflow=" ${ execData [ 'validate-workflow' ] } " ` ) ;
if ( execData . action ) attrs . push ( ` action=" ${ execData . action } " ` ) ;
if ( execData . data ) attrs . push ( ` data=" ${ execData . data } " ` ) ;
if ( execData . tmpl ) attrs . push ( ` tmpl=" ${ execData . tmpl } " ` ) ;
// Only add type if it's not 'exec' (exec is already implied by the exec attribute)
if ( execData . type && execData . type !== 'exec' ) attrs . push ( ` type=" ${ execData . type } " ` ) ;
xml += ` <handler ${ attrs . join ( ' ' ) } ></handler> \n ` ;
}
}
return xml ;
}
/ * *
* Process the execution array from multi format triggers
* Extracts relevant data for XML attributes
* @ param { Array } execArray - Array of execution objects
* @ returns { Object } Processed execution data
* /
processExecArray ( execArray ) {
const result = {
description : '' ,
route : null ,
workflow : null ,
data : null ,
action : null ,
type : null ,
} ;
if ( ! Array . isArray ( execArray ) ) {
return result ;
}
for ( const exec of execArray ) {
if ( exec . input ) {
// Use input as description if no explicit description is provided
result . description = exec . input ;
}
if ( exec . route ) {
// Determine if it's a workflow or exec based on file extension or context
if ( exec . route . endsWith ( '.yaml' ) || exec . route . endsWith ( '.yml' ) ) {
result . workflow = exec . route ;
} else {
result . route = exec . route ;
}
}
if ( exec . data !== null && exec . data !== undefined ) {
result . data = exec . data ;
}
if ( exec . action ) {
result . action = exec . action ;
}
if ( exec . type ) {
result . type = exec . type ;
}
}
return result ;
}
2025-10-02 21:45:59 -05:00
/ * *
* Calculate file hash for build tracking
* /
async calculateFileHash ( filePath ) {
if ( ! ( await fs . pathExists ( filePath ) ) ) {
return null ;
}
const content = await fs . readFile ( filePath , 'utf8' ) ;
return crypto . createHash ( 'md5' ) . update ( content ) . digest ( 'hex' ) . slice ( 0 , 8 ) ;
}
/ * *
2025-10-03 19:08:34 -05:00
* Build agent XML from YAML files and return as string ( for in - memory use )
2025-10-02 21:45:59 -05:00
* @ param { string } agentYamlPath - Path to agent YAML
* @ param { string } customizeYamlPath - Path to customize YAML ( optional )
* @ param { Object } options - Build options
2025-10-03 19:08:34 -05:00
* @ returns { Promise < string > } XML content as string
2025-10-02 21:45:59 -05:00
* /
2025-10-03 19:08:34 -05:00
async buildFromYaml ( agentYamlPath , customizeYamlPath = null , options = { } ) {
2025-10-02 21:45:59 -05:00
// Load and merge YAML files
const mergedAgent = await this . loadAndMergeAgent ( agentYamlPath , customizeYamlPath ) ;
// Calculate hashes for build tracking
const sourceHash = await this . calculateFileHash ( agentYamlPath ) ;
const customizeHash = customizeYamlPath ? await this . calculateFileHash ( customizeYamlPath ) : null ;
2025-10-04 21:33:19 -05:00
// Extract module from path (e.g., /path/to/modules/bmm/agents/pm.yaml -> bmm)
// or /path/to/bmad/bmm/agents/pm.yaml -> bmm
let module = 'core' ; // default to core
const pathParts = agentYamlPath . split ( path . sep ) ;
// Look for module indicators in the path
const modulesIndex = pathParts . indexOf ( 'modules' ) ;
const bmadIndex = pathParts . indexOf ( 'bmad' ) ;
if ( modulesIndex !== - 1 && pathParts [ modulesIndex + 1 ] ) {
// Path contains /modules/{module}/
module = pathParts [ modulesIndex + 1 ] ;
} else if ( bmadIndex !== - 1 && pathParts [ bmadIndex + 1 ] ) {
// Path contains /bmad/{module}/
const potentialModule = pathParts [ bmadIndex + 1 ] ;
// Check if it's a known module, not 'agents' or '_cfg'
if ( [ 'bmm' , 'bmb' , 'cis' , 'core' ] . includes ( potentialModule ) ) {
module = potentialModule ;
}
}
2025-10-02 21:45:59 -05:00
// Build metadata
const buildMetadata = {
sourceFile : path . basename ( agentYamlPath ) ,
sourceHash ,
customizeFile : customizeYamlPath ? path . basename ( customizeYamlPath ) : null ,
customizeHash ,
builderVersion : '1.0.0' ,
includeMetadata : options . includeMetadata !== false ,
2025-10-03 19:08:34 -05:00
skipActivation : options . skipActivation === true ,
2025-10-03 21:46:53 -05:00
forWebBundle : options . forWebBundle === true ,
2025-10-04 21:33:19 -05:00
module : module , // Add module to buildMetadata
2025-10-02 21:45:59 -05:00
} ;
2025-10-03 19:08:34 -05:00
// Convert to XML and return
return await this . convertToXml ( mergedAgent , buildMetadata ) ;
}
/ * *
* Build agent XML from YAML files
* @ param { string } agentYamlPath - Path to agent YAML
* @ param { string } customizeYamlPath - Path to customize YAML ( optional )
* @ param { string } outputPath - Path to write XML file
* @ param { Object } options - Build options
* /
async buildAgent ( agentYamlPath , customizeYamlPath , outputPath , options = { } ) {
// Use buildFromYaml to get XML content
const xml = await this . buildFromYaml ( agentYamlPath , customizeYamlPath , options ) ;
2025-10-02 21:45:59 -05:00
// Write output file
await fs . ensureDir ( path . dirname ( outputPath ) ) ;
await fs . writeFile ( outputPath , xml , 'utf8' ) ;
2025-10-03 19:08:34 -05:00
// Calculate hashes for return value
const sourceHash = await this . calculateFileHash ( agentYamlPath ) ;
const customizeHash = customizeYamlPath ? await this . calculateFileHash ( customizeYamlPath ) : null ;
2025-10-02 21:45:59 -05:00
return {
success : true ,
outputPath ,
sourceHash ,
customizeHash ,
} ;
}
}
module . exports = { YamlXmlBuilder } ;