installer and bundler progress
This commit is contained in:
@@ -25,6 +25,8 @@ 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"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/brainstorm-game/instructions.md"
|
||||
template: false
|
||||
use_advanced_elicitation: true
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/1-analysis/brainstorm-game/instructions.md"
|
||||
|
||||
@@ -24,6 +24,8 @@ web_bundle:
|
||||
name: "brainstorm-project"
|
||||
description: "Facilitate project brainstorming sessions by orchestrating the CIS brainstorming workflow with project-specific context and guidance."
|
||||
author: "BMad"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md"
|
||||
template: false
|
||||
use_advanced_elicitation: true
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md"
|
||||
|
||||
@@ -34,6 +34,9 @@ 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"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/product-brief/instructions.md"
|
||||
validation: "bmad/bmm/workflows/1-analysis/product-brief/checklist.md"
|
||||
template: "bmad/bmm/workflows/1-analysis/game-brief/template.md"
|
||||
use_advanced_elicitation: true
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/1-analysis/game-brief/template.md"
|
||||
|
||||
@@ -33,6 +33,9 @@ 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"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/product-brief/instructions.md"
|
||||
validation: "bmad/bmm/workflows/1-analysis/product-brief/checklist.md"
|
||||
template: "bmad/bmm/workflows/1-analysis/product-brief/template.md"
|
||||
use_advanced_elicitation: true
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/1-analysis/product-brief/template.md"
|
||||
|
||||
@@ -152,6 +152,8 @@ 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"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-router.md" # Router loads specific instruction sets
|
||||
validation: "bmad/bmm/workflows/1-analysis/research/checklist.md"
|
||||
use_advanced_elicitation: true
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/1-analysis/research/instructions-router.md"
|
||||
@@ -162,3 +164,82 @@ web_bundle:
|
||||
- "bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md"
|
||||
- "bmad/bmm/workflows/1-analysis/research/template-technical.md"
|
||||
- "bmad/bmm/workflows/1-analysis/research/checklist.md"
|
||||
# Workflow configuration
|
||||
interactive: true # User checkpoints throughout
|
||||
autonomous: false # Requires user input
|
||||
allow_parallel: true # Can run research tasks in parallel
|
||||
|
||||
# Research frameworks available (context dependent)
|
||||
frameworks:
|
||||
market:
|
||||
- "TAM/SAM/SOM Analysis"
|
||||
- "Porter's Five Forces"
|
||||
- "Jobs-to-be-Done"
|
||||
- "Technology Adoption Lifecycle"
|
||||
- "SWOT Analysis"
|
||||
- "Value Chain Analysis"
|
||||
technical:
|
||||
- "Trade-off Analysis"
|
||||
- "Architecture Decision Records (ADR)"
|
||||
- "Technology Radar"
|
||||
- "Comparison Matrix"
|
||||
- "Cost-Benefit Analysis"
|
||||
deep_prompt:
|
||||
- "ChatGPT Deep Research Best Practices"
|
||||
- "Gemini Deep Research Framework"
|
||||
- "Grok DeepSearch Optimization"
|
||||
- "Claude Projects Methodology"
|
||||
- "Iterative Prompt Refinement"
|
||||
|
||||
# Data sources (for web research)
|
||||
data_sources:
|
||||
- "Industry reports and publications"
|
||||
- "Government statistics and databases"
|
||||
- "Financial reports and SEC filings"
|
||||
- "News articles and press releases"
|
||||
- "Academic research papers"
|
||||
- "Technical documentation and RFCs"
|
||||
- "GitHub repositories and discussions"
|
||||
- "Stack Overflow and developer forums"
|
||||
- "Market research firm reports"
|
||||
- "Social media and communities"
|
||||
- "Patent databases"
|
||||
- "Benchmarking studies"
|
||||
# Research types supported
|
||||
research_types:
|
||||
market:
|
||||
name: "Market Research"
|
||||
description: "Comprehensive market analysis with TAM/SAM/SOM"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-market.md"
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-market.md"
|
||||
output: "{market_output}"
|
||||
deep_prompt:
|
||||
name: "Deep Research Prompt Generator"
|
||||
description: "Generate optimized prompts for AI research platforms"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md"
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md"
|
||||
output: "{deep_prompt_output}"
|
||||
technical:
|
||||
name: "Technical/Architecture Research"
|
||||
description: "Technology evaluation and architecture pattern research"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-technical.md"
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-technical.md"
|
||||
output: "{technical_output}"
|
||||
competitive:
|
||||
name: "Competitive Intelligence"
|
||||
description: "Deep competitor analysis"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-market.md" # Uses market with competitive focus
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-market.md"
|
||||
output: "{output_folder}/competitive-intelligence-{{date}}.md"
|
||||
user:
|
||||
name: "User Research"
|
||||
description: "Customer insights and persona development"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-market.md" # Uses market with user focus
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-market.md"
|
||||
output: "{output_folder}/user-research-{{date}}.md"
|
||||
domain:
|
||||
name: "Domain/Industry Research"
|
||||
description: "Industry and domain deep dives"
|
||||
instructions: "bmad/bmm/workflows/1-analysis/research/instructions-market.md" # Uses market with domain focus
|
||||
template: "bmad/bmm/workflows/1-analysis/research/template-market.md"
|
||||
output: "{output_folder}/domain-research-{{date}}.md"
|
||||
|
||||
@@ -64,6 +64,30 @@ web_bundle:
|
||||
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
|
||||
# Do not load these directly - instructions-router.md will load the proper file based on project type/level when needed
|
||||
instructions_sm: "bmad/bmm/workflows/2-plan/tech-spec/instructions-sm.md"
|
||||
instructions_med: "bmad/bmm/workflows/2-plan/prd/instructions-med.md"
|
||||
instructions_lg: "bmad/bmm/workflows/2-plan/prd/instructions-lg.md"
|
||||
instructions_ux: "bmad/bmm/workflows/2-plan/ux/instructions-ux.md"
|
||||
instructions_gdd: "bmad/bmm/workflows/2-plan/gdd/instructions-gdd.md"
|
||||
instructions_narrative: "bmad/bmm/workflows/2-plan/narrative/instructions-narrative.md"
|
||||
validation: "bmad/bmm/workflows/2-plan/checklist.md"
|
||||
# Templates - Load these only when the instructions request loading them
|
||||
prd_template: "{installed_path}/prd/prd-template.md"
|
||||
analysis_template: "{installed_path}/prd/analysis-template.md"
|
||||
epics_template: "{installed_path}/prd/epics-template.md"
|
||||
tech_spec_template: "{installed_path}/tech-spec/tech-spec-template.md"
|
||||
ux_spec_template: "{installed_path}/ux/ux-spec-template.md"
|
||||
gdd_template: "{installed_path}/gdd/gdd-template.md"
|
||||
game_types_csv: "{installed_path}/gdd/game-types.csv"
|
||||
narrative_template: "{installed_path}/narrative/narrative-template.md"
|
||||
# Scale parameters - adaptive by project level
|
||||
scale_parameters:
|
||||
level_0: "Single atomic change, tech-spec only"
|
||||
level_1: "1-10 stories, 1 epic, minimal PRD + tech-spec"
|
||||
level_2: "5-15 stories, 1-2 epics, focused PRD + tech-spec"
|
||||
level_3: "12-40 stories, 2-5 epics, full PRD + architect handoff"
|
||||
level_4: "40+ stories, 5+ epics, enterprise PRD + architect handoff"
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/2-plan/instructions-router.md"
|
||||
- "bmad/bmm/workflows/2-plan/tech-spec/instructions-sm.md"
|
||||
|
||||
@@ -59,12 +59,18 @@ project_types_questions: "{installed_path}/project-types"
|
||||
default_output_file: "{output_folder}/solution-architecture.md"
|
||||
|
||||
# Additional workflow dependencies
|
||||
tech_spec_workflow: "{project-root}/bmad/bmm/workflows/3-solutioning/tech-spec"
|
||||
tech_spec_workflow: "{project-root}/bmad/bmm/workflows/3-solutioning/tech-spec/workflow.yaml"
|
||||
|
||||
web_bundle:
|
||||
name: "solution-architecture"
|
||||
description: "Scale-adaptive solution architecture generation with dynamic template sections. Replaces legacy HLA workflow with modern BMAD Core compliance."
|
||||
author: "BMad Builder"
|
||||
instructions: "bmad/bmm/workflows/3-solutioning/instructions.md"
|
||||
validation: "bmad/bmm/workflows/3-solutioning/checklist.md"
|
||||
tech_spec_workflow: "bmad/bmm/workflows/3-solutioning/tech-spec/workflow.yaml"
|
||||
# Reference data files
|
||||
architecture_registry: "bmad/bmm/workflows/3-solutioning/templates/registry.csv"
|
||||
project_types_questions: "bmad/bmm/workflows/3-solutioning/project-types"
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/3-solutioning/instructions.md"
|
||||
- "bmad/bmm/workflows/3-solutioning/checklist.md"
|
||||
|
||||
@@ -34,10 +34,4 @@ execution_modes:
|
||||
- incremental: "Recommended - Refine each edit with user collaboration"
|
||||
- batch: "Present all changes at once for review"
|
||||
|
||||
web_bundle:
|
||||
name: "correct-course"
|
||||
description: "Navigate significant changes during sprint execution by analyzing impact, proposing solutions, and routing for implementation"
|
||||
author: "BMad Method"
|
||||
web_bundle_files:
|
||||
- "bmad/bmm/workflows/4-implementation/correct-course/instructions.md"
|
||||
- "bmad/bmm/workflows/4-implementation/correct-course/checklist.md"
|
||||
web_bundle: false
|
||||
|
||||
@@ -71,12 +71,4 @@ execution_hints:
|
||||
autonomous: true
|
||||
iterative: true
|
||||
|
||||
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"
|
||||
- "bmad/bmm/workflows/create-story/checklist.md"
|
||||
web_bundle: false
|
||||
|
||||
@@ -52,11 +52,4 @@ execution_hints:
|
||||
autonomous: true # Proceed without user input unless blocked
|
||||
iterative: true
|
||||
|
||||
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"
|
||||
web_bundle: false
|
||||
|
||||
@@ -40,10 +40,4 @@ validation_required:
|
||||
- technical_health: "Is codebase in stable, maintainable state?"
|
||||
- blocker_resolution: "Any unresolved blockers that will impact next epic?"
|
||||
|
||||
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"
|
||||
web_bundle: false
|
||||
|
||||
@@ -98,11 +98,4 @@ execution_hints:
|
||||
autonomous: true # Proceed without user input unless blocked
|
||||
iterative: true
|
||||
|
||||
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"
|
||||
web_bundle: false
|
||||
|
||||
@@ -55,12 +55,4 @@ execution_hints:
|
||||
autonomous: true
|
||||
iterative: true
|
||||
|
||||
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"
|
||||
- "bmad/bmm/workflows/story-context/checklist.md"
|
||||
web_bundle: false
|
||||
|
||||
@@ -173,12 +173,17 @@ class WebBundler {
|
||||
|
||||
// Resolve dependencies with warning tracking
|
||||
const dependencyWarnings = [];
|
||||
const dependencies = await this.resolveAgentDependencies(agentXml, moduleName, dependencyWarnings);
|
||||
const { dependencies, skippedWorkflows } = await this.resolveAgentDependencies(agentXml, moduleName, dependencyWarnings);
|
||||
|
||||
if (dependencyWarnings.length > 0) {
|
||||
this.stats.warnings.push({ agent: agentName, warnings: dependencyWarnings });
|
||||
}
|
||||
|
||||
// Remove commands for skipped workflows from agent XML
|
||||
if (skippedWorkflows.length > 0) {
|
||||
agentXml = this.removeSkippedWorkflowCommands(agentXml, skippedWorkflows);
|
||||
}
|
||||
|
||||
// Build the bundle (no manifests for individual agents)
|
||||
const bundle = this.buildAgentBundle(agentXml, dependencies);
|
||||
|
||||
@@ -266,6 +271,7 @@ class WebBundler {
|
||||
async resolveAgentDependencies(agentXml, moduleName, warnings = []) {
|
||||
const dependencies = new Map();
|
||||
const processed = new Set();
|
||||
const skippedWorkflows = [];
|
||||
|
||||
// Extract file references from agent XML
|
||||
const { refs, workflowRefs } = this.extractFileReferences(agentXml);
|
||||
@@ -277,10 +283,13 @@ class WebBundler {
|
||||
|
||||
// Process workflow references with special handling
|
||||
for (const workflowRef of workflowRefs) {
|
||||
await this.processWorkflowDependency(workflowRef, dependencies, processed, moduleName, warnings);
|
||||
const result = await this.processWorkflowDependency(workflowRef, dependencies, processed, moduleName, warnings);
|
||||
if (result && result.skipped) {
|
||||
skippedWorkflows.push(workflowRef);
|
||||
}
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
return { dependencies, skippedWorkflows };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,6 +339,27 @@ class WebBundler {
|
||||
return { refs: [...refs], workflowRefs: [...workflowRefs] };
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove commands from agent XML that reference skipped workflows
|
||||
*/
|
||||
removeSkippedWorkflowCommands(agentXml, skippedWorkflows) {
|
||||
let modifiedXml = agentXml;
|
||||
|
||||
// For each skipped workflow, find and remove the corresponding <c> command
|
||||
for (const workflowPath of skippedWorkflows) {
|
||||
// Match: <c cmd="..." run-workflow="workflowPath">...</c>
|
||||
// Need to escape special regex characters in the path
|
||||
const escapedPath = workflowPath.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
||||
|
||||
// Pattern to match the command line with this workflow
|
||||
const pattern = new RegExp(`\\s*<c\\s+cmd="[^"]*"\\s+run-workflow="[^"]*${escapedPath}"[^>]*>.*?</c>\\s*`, 'gs');
|
||||
|
||||
modifiedXml = modifiedXml.replace(pattern, '');
|
||||
}
|
||||
|
||||
return modifiedXml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a file dependency recursively
|
||||
*/
|
||||
@@ -504,7 +534,7 @@ class WebBundler {
|
||||
async processWorkflowDependency(workflowPath, dependencies, processed, moduleName, warnings = []) {
|
||||
// Skip if already processed
|
||||
if (processed.has(workflowPath)) {
|
||||
return;
|
||||
return { skipped: false };
|
||||
}
|
||||
processed.add(workflowPath);
|
||||
|
||||
@@ -513,7 +543,7 @@ class WebBundler {
|
||||
|
||||
if (!actualPath || !(await fs.pathExists(actualPath))) {
|
||||
warnings.push(workflowPath);
|
||||
return;
|
||||
return { skipped: true };
|
||||
}
|
||||
|
||||
// Read and parse YAML file
|
||||
@@ -524,12 +554,28 @@ class WebBundler {
|
||||
workflowConfig = yaml.load(yamlContent);
|
||||
} catch (error) {
|
||||
warnings.push(`${workflowPath} (invalid YAML: ${error.message})`);
|
||||
return;
|
||||
return { skipped: true };
|
||||
}
|
||||
|
||||
// Include the YAML file itself, wrapped in XML
|
||||
// Check if web_bundle is explicitly set to false
|
||||
if (workflowConfig.web_bundle === false) {
|
||||
// Mark this workflow as skipped so we can remove the command from agent
|
||||
return { skipped: true, workflowPath };
|
||||
}
|
||||
|
||||
// Create YAML content with only web_bundle section (flattened)
|
||||
let bundleYamlContent;
|
||||
if (workflowConfig.web_bundle && typeof workflowConfig.web_bundle === 'object') {
|
||||
// Only include the web_bundle content, flattened to root level
|
||||
bundleYamlContent = yaml.dump(workflowConfig.web_bundle);
|
||||
} else {
|
||||
// If no web_bundle section, include full YAML
|
||||
bundleYamlContent = yamlContent;
|
||||
}
|
||||
|
||||
// Include the YAML file with only web_bundle content, wrapped in XML
|
||||
const yamlId = workflowPath.replace(/^{project-root}\//, '');
|
||||
const wrappedYaml = this.wrapContentInXml(yamlContent, yamlId, 'yaml');
|
||||
const wrappedYaml = this.wrapContentInXml(bundleYamlContent, yamlId, 'yaml');
|
||||
dependencies.set(yamlId, wrappedYaml);
|
||||
|
||||
// Always include core workflow task when processing workflows
|
||||
@@ -566,6 +612,8 @@ class WebBundler {
|
||||
dependencies.set(bundleFilePath, wrappedContent);
|
||||
}
|
||||
}
|
||||
|
||||
return { skipped: false };
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -271,9 +271,15 @@ class ModuleManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the file
|
||||
await fs.ensureDir(path.dirname(targetFile));
|
||||
await fs.copy(sourceFile, targetFile, { overwrite: true });
|
||||
// Check if this is a workflow.yaml file
|
||||
if (file.endsWith('workflow.yaml')) {
|
||||
await fs.ensureDir(path.dirname(targetFile));
|
||||
await this.copyWorkflowYamlStripped(sourceFile, targetFile);
|
||||
} else {
|
||||
// Copy the file normally
|
||||
await fs.ensureDir(path.dirname(targetFile));
|
||||
await fs.copy(sourceFile, targetFile, { overwrite: true });
|
||||
}
|
||||
|
||||
// Track the file if callback provided
|
||||
if (fileTrackingCallback) {
|
||||
@@ -282,6 +288,91 @@ class ModuleManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy workflow.yaml file with web_bundle section stripped
|
||||
* Preserves comments, formatting, and line breaks
|
||||
* @param {string} sourceFile - Source workflow.yaml file path
|
||||
* @param {string} targetFile - Target workflow.yaml file path
|
||||
*/
|
||||
async copyWorkflowYamlStripped(sourceFile, targetFile) {
|
||||
// Read the source YAML file
|
||||
let yamlContent = await fs.readFile(sourceFile, 'utf8');
|
||||
|
||||
try {
|
||||
// First check if web_bundle exists by parsing
|
||||
const workflowConfig = yaml.load(yamlContent);
|
||||
|
||||
if (workflowConfig.web_bundle === undefined) {
|
||||
// No web_bundle section, just copy as-is
|
||||
await fs.writeFile(targetFile, yamlContent, 'utf8');
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove web_bundle section using regex to preserve formatting
|
||||
// Match the web_bundle key and all its content (including nested items)
|
||||
// This handles both web_bundle: false and web_bundle: {...}
|
||||
|
||||
// Find the line that starts web_bundle
|
||||
const lines = yamlContent.split('\n');
|
||||
let startIdx = -1;
|
||||
let endIdx = -1;
|
||||
let baseIndent = 0;
|
||||
|
||||
// Find the start of web_bundle section
|
||||
for (const [i, line] of lines.entries()) {
|
||||
const match = line.match(/^(\s*)web_bundle:/);
|
||||
if (match) {
|
||||
startIdx = i;
|
||||
baseIndent = match[1].length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (startIdx === -1) {
|
||||
// web_bundle not found in text (shouldn't happen), copy as-is
|
||||
await fs.writeFile(targetFile, yamlContent, 'utf8');
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the end of web_bundle section
|
||||
// It ends when we find a line with same or less indentation that's not empty/comment
|
||||
endIdx = startIdx;
|
||||
for (let i = startIdx + 1; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
|
||||
// Skip empty lines and comments
|
||||
if (line.trim() === '' || line.trim().startsWith('#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check indentation
|
||||
const indent = line.match(/^(\s*)/)[1].length;
|
||||
if (indent <= baseIndent) {
|
||||
// Found next section at same or lower indentation
|
||||
endIdx = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find an end, it goes to end of file
|
||||
if (endIdx === startIdx) {
|
||||
endIdx = lines.length - 1;
|
||||
}
|
||||
|
||||
// Remove the web_bundle section (including the line before if it's just a blank line)
|
||||
const newLines = [...lines.slice(0, startIdx), ...lines.slice(endIdx + 1)];
|
||||
|
||||
// Clean up any double blank lines that might result
|
||||
const strippedYaml = newLines.join('\n').replaceAll(/\n\n\n+/g, '\n\n');
|
||||
|
||||
await fs.writeFile(targetFile, strippedYaml, 'utf8');
|
||||
} catch {
|
||||
// If anything fails, just copy the file as-is
|
||||
console.warn(chalk.yellow(` Warning: Could not process ${path.basename(sourceFile)}, copying as-is`));
|
||||
await fs.copy(sourceFile, targetFile, { overwrite: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process agent files to inject activation block
|
||||
* @param {string} modulePath - Path to installed module
|
||||
|
||||
Reference in New Issue
Block a user