web_bundle info added to workflow yamls

This commit is contained in:
Brian Madison
2025-09-29 21:18:10 -05:00
parent 9934224230
commit ae136ceb03
17 changed files with 175 additions and 7 deletions

View File

@@ -25,6 +25,7 @@ web_bundle:
name: "brainstorm-game"
description: "Facilitate game brainstorming sessions by orchestrating the CIS brainstorming workflow with game-specific context, guidance, and additional game design techniques."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/1-analysis/brainstorm-game/instructions.md"
- "bmad/bmm/workflows/1-analysis/brainstorm-game/game-context.md"

View File

@@ -24,6 +24,7 @@ web_bundle:
name: "brainstorm-project"
description: "Facilitate project brainstorming sessions by orchestrating the CIS brainstorming workflow with project-specific context and guidance."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md"
- "bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md"

View File

@@ -34,6 +34,7 @@ web_bundle:
name: "game-brief"
description: "Interactive game brief creation workflow that guides users through defining their game vision with multiple input sources and conversational collaboration"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/1-analysis/game-brief/template.md"
- "bmad/bmm/workflows/1-analysis/game-brief/instructions.md"

View File

@@ -33,6 +33,7 @@ web_bundle:
name: "product-brief"
description: "Interactive product brief creation workflow that guides users through defining their product vision with multiple input sources and conversational collaboration"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/1-analysis/product-brief/template.md"
- "bmad/bmm/workflows/1-analysis/product-brief/instructions.md"

View File

@@ -152,6 +152,7 @@ web_bundle:
name: "research"
description: "Adaptive research workflow supporting multiple research types: market research, deep research prompt generation, technical/architecture evaluation, competitive intelligence, user research, and domain analysis"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/1-analysis/research/instructions-router.md"
- "bmad/bmm/workflows/1-analysis/research/instructions-market.md"

View File

@@ -63,6 +63,7 @@ web_bundle:
name: "plan-project"
description: "Scale-adaptive project planning workflow for all project levels (0-4). Automatically adjusts outputs based on project scope - from single atomic changes (Level 0: tech-spec only) to enterprise platforms (Level 4: full PRD + epics). Level 2-4 route to 3-solutioning workflow for architecture and tech specs. Generates appropriate planning artifacts for each level."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/2-plan/instructions-router.md"
- "bmad/bmm/workflows/2-plan/tech-spec/instructions-sm.md"

View File

@@ -75,6 +75,7 @@ web_bundle:
name: "create-story"
description: "Create the next user story markdown from epics/PRD and architecture, using a standard template and saving to the stories folder"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/create-story/template.md"
- "bmad/bmm/workflows/create-story/instructions.md"

View File

@@ -56,6 +56,7 @@ web_bundle:
name: "dev-story"
description: "Execute a story by implementing tasks/subtasks, writing tests, validating, and updating the story file per acceptance criteria"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/dev-story/instructions.md"
- "bmad/bmm/workflows/dev-story/checklist.md"

View File

@@ -44,5 +44,6 @@ web_bundle:
name: "retrospective"
description: "Run after epic completion to review overall success, extract lessons learned, and explore if new information emerged that might impact the next epic"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/4-implementation/retrospective/instructions.md"

View File

@@ -102,6 +102,7 @@ web_bundle:
name: "review-story"
description: "Perform a Senior Developer Review on a completed story flagged Ready for Review, leveraging story-context, epic tech-spec, repo docs, MCP servers for latest best-practices, and web search as fallback. Appends structured review notes to the story."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/review-story/instructions.md"
- "bmad/bmm/workflows/review-story/checklist.md"

View File

@@ -59,6 +59,7 @@ web_bundle:
name: "story-context"
description: "Assemble a dynamic Story Context XML by pulling latest documentation and existing code/library artifacts relevant to a drafted story"
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/bmm/workflows/story-context/context-template.xml"
- "bmad/bmm/workflows/story-context/instructions.md"

View File

@@ -31,6 +31,7 @@ web_bundle:
name: "brainstorming"
description: "Facilitate interactive brainstorming sessions using diverse creative techniques. This workflow facilitates interactive brainstorming sessions using diverse creative techniques. The session is highly interactive, with the AI acting as a facilitator to guide the user through various ideation methods to generate and refine creative solutions."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/cis/workflows/brainstorming/instructions.md"
- "bmad/cis/workflows/brainstorming/checklist.md"

View File

@@ -32,6 +32,7 @@ web_bundle:
name: "design-thinking"
description: "Guide human-centered design processes using empathy-driven methodologies. This workflow walks through the design thinking phases - Empathize, Define, Ideate, Prototype, and Test - to create solutions deeply rooted in user needs."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/cis/workflows/design-thinking/instructions.md"
- "bmad/cis/workflows/design-thinking/template.md"

View File

@@ -32,6 +32,7 @@ web_bundle:
name: "innovation-strategy"
description: "Identify disruption opportunities and architect business model innovation. This workflow guides strategic analysis of markets, competitive dynamics, and business model innovation to uncover sustainable competitive advantages and breakthrough opportunities."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/cis/workflows/innovation-strategy/instructions.md"
- "bmad/cis/workflows/innovation-strategy/template.md"

View File

@@ -32,6 +32,7 @@ web_bundle:
name: "problem-solving"
description: "Apply systematic problem-solving methodologies to crack complex challenges. This workflow guides through problem diagnosis, root cause analysis, creative solution generation, evaluation, and implementation planning using proven frameworks."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/cis/workflows/problem-solving/instructions.md"
- "bmad/cis/workflows/problem-solving/template.md"

View File

@@ -32,6 +32,7 @@ web_bundle:
name: "storytelling"
description: "Craft compelling narratives using proven story frameworks and techniques. This workflow guides users through structured narrative development, applying appropriate story frameworks to create emotionally resonant and engaging stories for any purpose."
author: "BMad"
use_advanced_elicitation: true
web_bundle_files:
- "bmad/cis/workflows/storytelling/instructions.md"
- "bmad/cis/workflows/storytelling/template.md"

View File

@@ -1,6 +1,7 @@
const path = require('node:path');
const fs = require('fs-extra');
const chalk = require('chalk');
const yaml = require('js-yaml');
const { DependencyResolver } = require('../installers/lib/core/dependency-resolver');
const { XmlHandler } = require('../lib/xml-handler');
const { AgentPartyGenerator } = require('../lib/agent-party-generator');
@@ -267,13 +268,18 @@ class WebBundler {
const processed = new Set();
// Extract file references from agent XML
const fileRefs = this.extractFileReferences(agentXml);
const { refs, workflowRefs } = this.extractFileReferences(agentXml);
// Process each file reference
for (const ref of fileRefs) {
// Process regular file references
for (const ref of refs) {
await this.processFileDependency(ref, dependencies, processed, moduleName, warnings);
}
// Process workflow references with special handling
for (const workflowRef of workflowRefs) {
await this.processWorkflowDependency(workflowRef, dependencies, processed, moduleName, warnings);
}
return dependencies;
}
@@ -282,6 +288,7 @@ class WebBundler {
*/
extractFileReferences(xml) {
const refs = new Set();
const workflowRefs = new Set();
// Match various file reference patterns
const patterns = [
@@ -309,7 +316,18 @@ class WebBundler {
}
}
return [...refs];
// Extract run-workflow references (special handling for workflows)
const workflowPattern = /run-workflow="([^"]+)"/g;
let workflowMatch;
while ((workflowMatch = workflowPattern.exec(xml)) !== null) {
let workflowPath = workflowMatch[1];
workflowPath = workflowPath.replace(/^{project-root}\//, '');
if (workflowPath) {
workflowRefs.add(workflowPath);
}
}
return { refs: [...refs], workflowRefs: [...workflowRefs] };
}
/**
@@ -474,12 +492,143 @@ class WebBundler {
dependencies.set(filePath, processedContent);
// Recursively scan for more dependencies
const nestedRefs = this.extractFileReferences(processedContent);
const { refs: nestedRefs } = this.extractFileReferences(processedContent);
for (const ref of nestedRefs) {
await this.processFileDependency(ref, dependencies, processed, moduleName, warnings);
}
}
/**
* Process a workflow YAML file and its bundle files
*/
async processWorkflowDependency(workflowPath, dependencies, processed, moduleName, warnings = []) {
// Skip if already processed
if (processed.has(workflowPath)) {
return;
}
processed.add(workflowPath);
// Resolve actual file path
const actualPath = this.resolveFilePath(workflowPath, moduleName);
if (!actualPath || !(await fs.pathExists(actualPath))) {
warnings.push(workflowPath);
return;
}
// Read and parse YAML file
const yamlContent = await fs.readFile(actualPath, 'utf8');
let workflowConfig;
try {
workflowConfig = yaml.load(yamlContent);
} catch (error) {
warnings.push(`${workflowPath} (invalid YAML: ${error.message})`);
return;
}
// Include the YAML file itself, wrapped in XML
const yamlId = workflowPath.replace(/^{project-root}\//, '');
const wrappedYaml = this.wrapContentInXml(yamlContent, yamlId, 'yaml');
dependencies.set(yamlId, wrappedYaml);
// Always include core workflow task when processing workflows
await this.includeCoreWorkflowFiles(dependencies, processed, moduleName, warnings);
// Check if advanced elicitation is enabled
if (workflowConfig.web_bundle && workflowConfig.web_bundle.use_advanced_elicitation) {
await this.includeAdvancedElicitationFiles(dependencies, processed, moduleName, warnings);
}
// Process web_bundle_files if they exist
if (workflowConfig.web_bundle && workflowConfig.web_bundle.web_bundle_files) {
const bundleFiles = workflowConfig.web_bundle.web_bundle_files;
for (const bundleFilePath of bundleFiles) {
if (processed.has(bundleFilePath)) {
continue;
}
processed.add(bundleFilePath);
const bundleActualPath = this.resolveFilePath(bundleFilePath, moduleName);
if (!bundleActualPath || !(await fs.pathExists(bundleActualPath))) {
warnings.push(bundleFilePath);
continue;
}
// Read the file content
const fileContent = await fs.readFile(bundleActualPath, 'utf8');
const fileExt = path.extname(bundleActualPath).toLowerCase().replace('.', '');
// Wrap in XML with proper escaping
const wrappedContent = this.wrapContentInXml(fileContent, bundleFilePath, fileExt);
dependencies.set(bundleFilePath, wrappedContent);
}
}
}
/**
* Include core workflow task files
*/
async includeCoreWorkflowFiles(dependencies, processed, moduleName, warnings = []) {
const coreWorkflowPath = 'bmad/core/tasks/workflow.md';
if (processed.has(coreWorkflowPath)) {
return;
}
processed.add(coreWorkflowPath);
const actualPath = this.resolveFilePath(coreWorkflowPath, moduleName);
if (!actualPath || !(await fs.pathExists(actualPath))) {
warnings.push(coreWorkflowPath);
return;
}
const fileContent = await fs.readFile(actualPath, 'utf8');
const wrappedContent = this.wrapContentInXml(fileContent, coreWorkflowPath, 'md');
dependencies.set(coreWorkflowPath, wrappedContent);
}
/**
* Include advanced elicitation files
*/
async includeAdvancedElicitationFiles(dependencies, processed, moduleName, warnings = []) {
const elicitationFiles = ['bmad/core/tasks/adv-elicit.md', 'bmad/core/tasks/adv-elicit-methods.csv'];
for (const filePath of elicitationFiles) {
if (processed.has(filePath)) {
continue;
}
processed.add(filePath);
const actualPath = this.resolveFilePath(filePath, moduleName);
if (!actualPath || !(await fs.pathExists(actualPath))) {
warnings.push(filePath);
continue;
}
const fileContent = await fs.readFile(actualPath, 'utf8');
const fileExt = path.extname(actualPath).toLowerCase().replace('.', '');
const wrappedContent = this.wrapContentInXml(fileContent, filePath, fileExt);
dependencies.set(filePath, wrappedContent);
}
}
/**
* Wrap file content in XML with proper escaping
*/
wrapContentInXml(content, id, type = 'text') {
// Escape any ]]> sequences in the content by splitting CDATA sections
// Replace ]]> with ]]]]><![CDATA[> to properly escape it within CDATA
const escapedContent = content.replaceAll(']]>', ']]]]><![CDATA[>');
// Use CDATA to preserve content exactly as-is, including special characters
return `<file id="${id}" type="${type}"><![CDATA[${escapedContent}]]></file>`;
}
/**
* Process wildcard dependency patterns
*/
@@ -680,8 +829,11 @@ class WebBundler {
if (dependencies && dependencies.size > 0) {
parts.push('\n <!-- Dependencies -->');
for (const [id, content] of dependencies) {
// Escape XML content while preserving tags
const escapedContent = this.escapeXmlContent(content);
// Check if content is already wrapped in a <file> tag (from workflow processing)
// If so, don't escape it - it's already in CDATA
const isWrappedFile = content.trim().startsWith('<file ') && content.trim().endsWith('</file>');
const escapedContent = isWrappedFile ? content : this.escapeXmlContent(content);
// Indent properly
const indentedContent = escapedContent
.split('\n')