remove dead and unused functionality - the web bundler will be replaced

This commit is contained in:
Brian Madison 2025-12-13 14:06:35 +08:00
parent ed0defbe08
commit e6f911d791
13 changed files with 12 additions and 2498 deletions

View File

@ -2,31 +2,26 @@ header: "BMAD™ Core Configuration"
subheader: "Configure the core settings for your BMAD™ installation.\nThese settings will be used across all modules and agents." subheader: "Configure the core settings for your BMAD™ installation.\nThese settings will be used across all modules and agents."
user_name: user_name:
prompt: "What shall the agents call you?" prompt: "What shall the agents call you (TIP: Use a team name if using with a group)?"
default: "BMad" default: "BMad"
result: "{value}" result: "{value}"
communication_language: communication_language:
prompt: "Preferred Chat Language/Style? (English, Mandarin, English Pirate, etc...)" prompt: "Preferred chat language/style? (English, Mandarin, English Pirate, etc...)"
default: "English" default: "English"
result: "{value}" result: "{value}"
document_output_language: document_output_language:
prompt: "Preferred Document Output Language?" prompt: "Preferred document output language?"
default: "{communication_language}" default: "{communication_language}"
result: "{value}" result: "{value}"
output_folder:
prompt: "Where should AI generated artifacts be saved across all modules?"
default: "docs"
result: "{project-root}/{value}"
agent_sidecar_folder: agent_sidecar_folder:
prompt: "Where should users agent sidecar memory folders be stored?" prompt: "Where should users agent sidecar memory folders be stored?"
default: ".bmad-user-memory" default: ".bmad-user-memory"
result: "{project-root}/{value}" result: "{project-root}/{value}"
output_folder:
prompt: "Where should AI Generated Artifacts be saved across all modules?"
default: "docs"
result: "{project-root}/{value}"
install_user_docs:
prompt: "Install user documentation and optimized agent intelligence to each selected modules docs folder?"
default: true
result: "{value}"

View File

@ -11,8 +11,6 @@ subheader: "Configure the settings for the BoMB Factory!\nThe agent, workflow an
## user_name ## user_name
## communication_language ## communication_language
## output_folder ## output_folder
## install_user_docs
## kb_install
custom_stand_alone_location: custom_stand_alone_location:
prompt: "Where do custom agents and workflows get stored?" prompt: "Where do custom agents and workflows get stored?"

View File

@ -11,8 +11,6 @@ subheader: "Agent and Workflow Configuration for this module"
## user_name ## user_name
## communication_language ## communication_language
## output_folder ## output_folder
## install_user_docs
## kb_install
project_name: project_name:
prompt: "What is the title of your project you will be working on?" prompt: "What is the title of your project you will be working on?"
@ -21,9 +19,8 @@ project_name:
user_skill_level: user_skill_level:
prompt: prompt:
- "What is your technical experience level?" - "What is your development experience level?"
- "This affects how agents explain concepts to you (NOT document content)." - "This affects how agents explain concepts in chat."
- "Documents are always concise for LLM efficiency."
default: "intermediate" default: "intermediate"
result: "{value}" result: "{value}"
single-select: single-select:
@ -35,7 +32,7 @@ user_skill_level:
label: "Expert - Deep technical knowledge, be direct and technical" label: "Expert - Deep technical knowledge, be direct and technical"
sprint_artifacts: sprint_artifacts:
prompt: "Where should Sprint Artifacts be stored (sprint status, stories, story context, temp context, etc...)?" prompt: "Where should sprint artifacts be stored (sprint status, stories, retrospectives)?"
default: "{output_folder}/sprint-artifacts" default: "{output_folder}/sprint-artifacts"
result: "{project-root}/{value}" result: "{project-root}/{value}"

View File

@ -1,85 +0,0 @@
<task id="bmad/bmm/tasks/daily-standup.xml" name="Daily Standup">
<llm critical="true">
<i>MANDATORY: Execute ALL steps in the flow section IN EXACT ORDER</i>
<i>DO NOT skip steps or change the sequence</i>
<i>HALT immediately when halt-conditions are met</i>
<i>Each action tag within a step tag is a REQUIRED action to complete that step</i>
<i>Sections outside flow (validation, output, critical-context) provide essential context - review and apply throughout execution</i>
</llm>
<flow>
<step n="1" title="Project Context Discovery">
<action>Check for stories folder at {project-root}{output_folder}/stories/</action>
<action>Find current story by identifying highest numbered story file</action>
<action>Read story status (In Progress, Ready for Review, etc.)</action>
<action>Extract agent notes from Dev Agent Record, TEA Results, PO Notes sections</action>
<action>Check for next story references from epics</action>
<action>Identify blockers from story sections</action>
</step>
<step n="2" title="Initialize Standup with Context">
<output>
🏃 DAILY STANDUP - Story-{{number}}: {{title}}
Current Sprint Status:
- Active Story: story-{{number}} ({{status}} - {{percentage}}% complete)
- Next in Queue: story-{{next-number}}: {{next-title}}
- Blockers: {{blockers-from-story}}
Team assembled based on story participants:
{{ List Agents from {project-root}/bmad/_cfg/agent-manifest.csv }}
</output>
</step>
<step n="3" title="Structured Standup Discussion">
<action>Each agent provides three items referencing real story data</action>
<action>What I see: Their perspective on current work, citing story sections (1-2 sentences)</action>
<action>What concerns me: Issues from their domain or story blockers (1-2 sentences)</action>
<action>What I suggest: Actionable recommendations for progress (1-2 sentences)</action>
</step>
<step n="4" title="Create Standup Summary">
<output>
📋 STANDUP SUMMARY:
Key Items from Story File:
- {{completion-percentage}}% complete ({{tasks-complete}}/{{total-tasks}} tasks)
- Blocker: {{main-blocker}}
- Next: {{next-story-reference}}
Action Items:
- {{agent}}: {{action-item}}
- {{agent}}: {{action-item}}
- {{agent}}: {{action-item}}
Need extended discussion? Use *party-mode for detailed breakout.
</output>
</step>
</flow>
<agent-selection>
<context type="prd-review">
<i>Primary: Sarah (PO), Mary (Analyst), Winston (Architect)</i>
<i>Secondary: Murat (TEA), James (Dev)</i>
</context>
<context type="story-planning">
<i>Primary: Sarah (PO), Bob (SM), James (Dev)</i>
<i>Secondary: Murat (TEA)</i>
</context>
<context type="validate-architecture">
<i>Primary: Winston (Architect), James (Dev), Murat (TEA)</i>
<i>Secondary: Sarah (PO)</i>
</context>
<context type="implementation">
<i>Primary: James (Dev), Murat (TEA), Winston (Architect)</i>
<i>Secondary: Sarah (PO)</i>
</context>
</agent-selection>
<llm critical="true">
<i>This task extends party-mode with agile-specific structure</i>
<i>Time-box responses (standup = brief)</i>
<i>Focus on actionable items from real story data when available</i>
<i>End with clear next steps</i>
<i>No deep dives (suggest breakout if needed)</i>
<i>If no stories folder detected, run general standup format</i>
</llm>
</task>

View File

@ -10,6 +10,3 @@ subheader: "No Configuration needed - uses Core Config only."
## user_name ## user_name
## communication_language ## communication_language
## output_folder ## output_folder
## install_user_docs
## kb_install

View File

@ -1,179 +0,0 @@
const { WebBundler } = require('./web-bundler');
const chalk = require('chalk');
const { program } = require('commander');
const path = require('node:path');
const fs = require('fs-extra');
program.name('bundle-web').description('Generate web bundles for BMAD agents and teams').version('1.0.0');
program
.command('all')
.description('Bundle all modules')
.option('-o, --output <path>', 'Output directory', 'web-bundles')
.action(async (options) => {
try {
const bundler = new WebBundler(null, options.output);
await bundler.bundleAll();
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('rebundle')
.description('Clean and rebundle all modules')
.option('-o, --output <path>', 'Output directory', 'web-bundles')
.action(async (options) => {
try {
// Clean output directory first
const outputDir = path.isAbsolute(options.output) ? options.output : path.join(process.cwd(), options.output);
if (await fs.pathExists(outputDir)) {
console.log(chalk.cyan(`🧹 Cleaning ${options.output}...`));
await fs.emptyDir(outputDir);
}
// Bundle all
const bundler = new WebBundler(null, options.output);
await bundler.bundleAll();
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('module <name>')
.description('Bundle a specific module')
.option('-o, --output <path>', 'Output directory', 'web-bundles')
.action(async (moduleName, options) => {
try {
const bundler = new WebBundler(null, options.output);
const result = await bundler.bundleModule(moduleName);
if (result.agents.length === 0 && result.teams.length === 0) {
console.log(chalk.yellow(`No agents or teams found in module: ${moduleName}`));
} else {
console.log(chalk.green(`\n✨ Successfully bundled ${result.agents.length} agents and ${result.teams.length} teams`));
}
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('agent <module> <agent>')
.description('Bundle a specific agent')
.option('-o, --output <path>', 'Output directory', 'web-bundles')
.action(async (moduleName, agentFile, options) => {
try {
const bundler = new WebBundler(null, options.output);
// Ensure .md extension
if (!agentFile.endsWith('.md')) {
agentFile += '.md';
}
// Pre-discover module for complete manifests
await bundler.preDiscoverModule(moduleName);
await bundler.bundleAgent(moduleName, agentFile, false);
console.log(chalk.green(`\n✨ Successfully bundled agent: ${agentFile}`));
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('team <module> <team>')
.description('Bundle a specific team')
.option('-o, --output <path>', 'Output directory', 'web-bundles')
.action(async (moduleName, teamFile, options) => {
try {
const bundler = new WebBundler(null, options.output);
// Ensure .yaml or .yml extension
if (!teamFile.endsWith('.yaml') && !teamFile.endsWith('.yml')) {
teamFile += '.yaml';
}
// Pre-discover module for complete manifests
await bundler.preDiscoverModule(moduleName);
await bundler.bundleTeam(moduleName, teamFile);
console.log(chalk.green(`\n✨ Successfully bundled team: ${teamFile}`));
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('list')
.description('List available modules and agents')
.action(async () => {
try {
const bundler = new WebBundler();
const modules = await bundler.discoverModules();
console.log(chalk.cyan.bold('\n📦 Available Modules:\n'));
for (const module of modules) {
console.log(chalk.bold(` ${module}/`));
const modulePath = path.join(bundler.modulesPath, module);
const agents = await bundler.discoverAgents(modulePath);
const teams = await bundler.discoverTeams(modulePath);
if (agents.length > 0) {
console.log(chalk.gray(' agents/'));
for (const agent of agents) {
console.log(chalk.gray(` - ${agent}`));
}
}
if (teams.length > 0) {
console.log(chalk.gray(' teams/'));
for (const team of teams) {
console.log(chalk.gray(` - ${team}`));
}
}
}
console.log('');
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('clean')
.description('Remove all web bundles')
.action(async () => {
try {
const fs = require('fs-extra');
const outputDir = path.join(process.cwd(), 'web-bundles');
if (await fs.pathExists(outputDir)) {
await fs.remove(outputDir);
console.log(chalk.green('✓ Web bundles directory cleaned'));
} else {
console.log(chalk.yellow('Web bundles directory does not exist'));
}
} catch (error) {
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
// Parse command line arguments
program.parse(process.argv);
// Show help if no command provided
if (process.argv.slice(2).length === 0) {
program.outputHelp();
}

View File

@ -1,28 +0,0 @@
const { WebBundler } = require('./web-bundler');
const chalk = require('chalk');
const path = require('node:path');
async function testAnalystBundle() {
console.log(chalk.cyan.bold('\n🧪 Testing Analyst Agent Bundle\n'));
try {
const bundler = new WebBundler();
// Load web activation first
await bundler.loadWebActivation();
// Bundle just the analyst agent from bmm module
// Only bundle the analyst for testing
const agentPath = path.join(bundler.modulesPath, 'bmm', 'agents', 'analyst.md');
await bundler.bundleAgent('bmm', 'analyst.md');
console.log(chalk.green.bold('\n✅ Test completed successfully!\n'));
} catch (error) {
console.error(chalk.red('\n❌ Test failed:'), error.message);
console.error(error.stack);
process.exit(1);
}
}
// Run test
testAnalystBundle();

View File

@ -1,118 +0,0 @@
const { WebBundler } = require('./web-bundler');
const chalk = require('chalk');
const fs = require('fs-extra');
const path = require('node:path');
async function testWebBundler() {
console.log(chalk.cyan.bold('\n🧪 Testing Web Bundler\n'));
const bundler = new WebBundler();
let passedTests = 0;
let failedTests = 0;
// Test 1: Load web activation
try {
await bundler.loadWebActivation();
console.log(chalk.green('✓ Web activation loaded successfully'));
passedTests++;
} catch (error) {
console.error(chalk.red('✗ Failed to load web activation:'), error.message);
failedTests++;
}
// Test 2: Discover modules
try {
const modules = await bundler.discoverModules();
console.log(chalk.green(`✓ Discovered ${modules.length} modules:`, modules.join(', ')));
passedTests++;
} catch (error) {
console.error(chalk.red('✗ Failed to discover modules:'), error.message);
failedTests++;
}
// Test 3: Bundle analyst agent
try {
const result = await bundler.bundleAgent('bmm', 'analyst.md');
// Check if bundle was created
const bundlePath = path.join(bundler.outputDir, 'bmm', 'agents', 'analyst.xml');
if (await fs.pathExists(bundlePath)) {
const content = await fs.readFile(bundlePath, 'utf8');
// Validate bundle structure
const hasAgent = content.includes('<agent');
const hasActivation = content.includes('<activation');
const hasPersona = content.includes('<persona>');
const activationBeforePersona = content.indexOf('<activation') < content.indexOf('<persona>');
const hasManifests =
content.includes('<agent-party id="bmad/_cfg/agent-manifest.csv">') && content.includes('<manifest id="bmad/web-manifest.xml">');
const hasDependencies = content.includes('<dependencies>');
console.log(chalk.green('✓ Analyst bundle created successfully'));
console.log(chalk.gray(` - Has agent tag: ${hasAgent ? '✓' : '✗'}`));
console.log(chalk.gray(` - Has activation: ${hasActivation ? '✓' : '✗'}`));
console.log(chalk.gray(` - Has persona: ${hasPersona ? '✓' : '✗'}`));
console.log(chalk.gray(` - Activation before persona: ${activationBeforePersona ? '✓' : '✗'}`));
console.log(chalk.gray(` - Has manifests: ${hasManifests ? '✓' : '✗'}`));
console.log(chalk.gray(` - Has dependencies: ${hasDependencies ? '✓' : '✗'}`));
if (hasAgent && hasActivation && hasPersona && activationBeforePersona && hasManifests && hasDependencies) {
passedTests++;
} else {
console.error(chalk.red('✗ Bundle structure validation failed'));
failedTests++;
}
} else {
console.error(chalk.red('✗ Bundle file not created'));
failedTests++;
}
} catch (error) {
console.error(chalk.red('✗ Failed to bundle analyst agent:'), error.message);
failedTests++;
}
// Test 4: Bundle a different agent (architect which exists)
try {
const result = await bundler.bundleAgent('bmm', 'architect.md');
const bundlePath = path.join(bundler.outputDir, 'bmm', 'agents', 'architect.xml');
if (await fs.pathExists(bundlePath)) {
console.log(chalk.green('✓ Architect bundle created successfully'));
passedTests++;
} else {
console.error(chalk.red('✗ Architect bundle file not created'));
failedTests++;
}
} catch (error) {
console.error(chalk.red('✗ Failed to bundle architect agent:'), error.message);
failedTests++;
}
// Test 5: Bundle all agents in a module
try {
const results = await bundler.bundleModule('bmm');
console.log(chalk.green(`✓ Bundled ${results.agents.length} agents from bmm module`));
passedTests++;
} catch (error) {
console.error(chalk.red('✗ Failed to bundle bmm module:'), error.message);
failedTests++;
}
// Summary
console.log(chalk.bold('\n📊 Test Results:'));
console.log(chalk.green(` Passed: ${passedTests}`));
console.log(chalk.red(` Failed: ${failedTests}`));
if (failedTests === 0) {
console.log(chalk.green.bold('\n✅ All tests passed!\n'));
} else {
console.log(chalk.red.bold(`\n${failedTests} test(s) failed\n`));
process.exit(1);
}
}
// Run tests
testWebBundler().catch((error) => {
console.error(chalk.red('Fatal error:'), error);
process.exit(1);
});

File diff suppressed because it is too large Load Diff

View File

@ -1,239 +0,0 @@
/**
* Utility function to replace {project-root} placeholders with actual installation target
* Used during BMAD installation to set correct paths in agent and task files
*/
const fs = require('node:fs');
const path = require('node:path');
/**
* Replace {project-root} and {output_folder}/ placeholders in a single file
* @param {string} filePath - Path to the file to process
* @param {string} projectRoot - The actual project root path to substitute (must include trailing slash)
* @param {string} docOut - The document output path (with leading slash)
* @param {boolean} removeCompletely - If true, removes placeholders entirely instead of replacing
* @returns {boolean} - True if replacements were made, false otherwise
*/
function replacePlaceholdersInFile(filePath, projectRoot, docOut = '/docs', removeCompletely = false) {
try {
let content = fs.readFileSync(filePath, 'utf8');
const originalContent = content;
if (removeCompletely) {
// Remove placeholders entirely (for bundling)
content = content.replaceAll('{project-root}', '');
content = content.replaceAll('{output_folder}/', '');
} else {
// Handle the combined pattern first to avoid double slashes
if (projectRoot && docOut) {
// Replace {project-root}{output_folder}/ combinations first
// Remove leading slash from docOut since projectRoot has trailing slash
// Add trailing slash to docOut
const docOutNoLeadingSlash = docOut.replace(/^\//, '');
const docOutWithTrailingSlash = docOutNoLeadingSlash.endsWith('/') ? docOutNoLeadingSlash : docOutNoLeadingSlash + '/';
content = content.replaceAll('{project-root}{output_folder}/', projectRoot + docOutWithTrailingSlash);
}
// Then replace remaining individual placeholders
if (projectRoot) {
content = content.replaceAll('{project-root}', projectRoot);
}
if (docOut) {
// For standalone {output_folder}/, keep the leading slash and add trailing slash
const docOutWithTrailingSlash = docOut.endsWith('/') ? docOut : docOut + '/';
content = content.replaceAll('{output_folder}/', docOutWithTrailingSlash);
}
}
if (content !== originalContent) {
fs.writeFileSync(filePath, content, 'utf8');
return true;
}
return false;
} catch (error) {
console.error(`Error processing file ${filePath}:`, error.message);
return false;
}
}
/**
* Legacy function name for backward compatibility
*/
function replaceProjectRootInFile(filePath, projectRoot, removeCompletely = false) {
return replacePlaceholdersInFile(filePath, projectRoot, '/docs', removeCompletely);
}
/**
* Recursively replace {project-root} and {output_folder}/ in all files in a directory
* @param {string} dirPath - Directory to process
* @param {string} projectRoot - The actual project root path to substitute (or null to remove)
* @param {string} docOut - The document output path (with leading slash)
* @param {Array<string>} extensions - File extensions to process (default: ['.md', '.xml', '.yaml'])
* @param {boolean} removeCompletely - If true, removes placeholders entirely instead of replacing
* @param {boolean} verbose - If true, show detailed output for each file
* @returns {Object} - Stats object with counts of files processed and modified
*/
function replacePlaceholdersInDirectory(
dirPath,
projectRoot,
docOut = '/docs',
extensions = ['.md', '.xml', '.yaml'],
removeCompletely = false,
verbose = false,
) {
const stats = {
processed: 0,
modified: 0,
errors: 0,
};
function processDirectory(currentPath) {
try {
const items = fs.readdirSync(currentPath, { withFileTypes: true });
for (const item of items) {
const fullPath = path.join(currentPath, item.name);
if (item.isDirectory()) {
// Skip node_modules and .git directories
if (item.name !== 'node_modules' && item.name !== '.git') {
processDirectory(fullPath);
}
} else if (item.isFile()) {
// Check if file has one of the target extensions
const ext = path.extname(item.name).toLowerCase();
if (extensions.includes(ext)) {
stats.processed++;
if (replacePlaceholdersInFile(fullPath, projectRoot, docOut, removeCompletely)) {
stats.modified++;
if (verbose) {
console.log(`✓ Updated: ${fullPath}`);
}
}
}
}
}
} catch (error) {
console.error(`Error processing directory ${currentPath}:`, error.message);
stats.errors++;
}
}
processDirectory(dirPath);
return stats;
}
/**
* Legacy function for backward compatibility
*/
function replaceProjectRootInDirectory(dirPath, projectRoot, extensions = ['.md', '.xml'], removeCompletely = false) {
return replacePlaceholdersInDirectory(dirPath, projectRoot, '/docs', extensions, removeCompletely);
}
/**
* Replace placeholders in a list of specific files
* @param {Array<string>} filePaths - Array of file paths to process
* @param {string} projectRoot - The actual project root path to substitute (or null to remove)
* @param {string} docOut - The document output path (with leading slash)
* @param {boolean} removeCompletely - If true, removes placeholders entirely instead of replacing
* @returns {Object} - Stats object with counts of files processed and modified
*/
function replacePlaceholdersInFiles(filePaths, projectRoot, docOut = '/docs', removeCompletely = false) {
const stats = {
processed: 0,
modified: 0,
errors: 0,
};
for (const filePath of filePaths) {
stats.processed++;
try {
if (replacePlaceholdersInFile(filePath, projectRoot, docOut, removeCompletely)) {
stats.modified++;
console.log(`✓ Updated: ${filePath}`);
}
} catch (error) {
console.error(`Error processing file ${filePath}:`, error.message);
stats.errors++;
}
}
return stats;
}
/**
* Legacy function for backward compatibility
*/
function replaceProjectRootInFiles(filePaths, projectRoot, removeCompletely = false) {
return replacePlaceholdersInFiles(filePaths, projectRoot, '/docs', removeCompletely);
}
/**
* Main installation helper - replaces {project-root} and {output_folder}/ during BMAD installation
* @param {string} installPath - Path where BMAD is being installed
* @param {string} targetProjectRoot - The project root to set in the files (slash will be added)
* @param {string} docsOutputPath - The documentation output path (relative to project root)
* @param {boolean} verbose - If true, show detailed output
* @returns {Object} - Installation stats
*/
function processInstallation(installPath, targetProjectRoot, docsOutputPath = 'docs', verbose = false) {
// Ensure project root has trailing slash since usage is like {project-root}/bmad
const projectRootWithSlash = targetProjectRoot.endsWith('/') ? targetProjectRoot : targetProjectRoot + '/';
// Ensure docs path has leading slash (for internal use) but will add trailing slash during replacement
const normalizedDocsPath = docsOutputPath.replaceAll(/^\/+|\/+$/g, '');
const docOutPath = normalizedDocsPath ? `/${normalizedDocsPath}` : '/docs';
if (verbose) {
console.log(`\nReplacing {project-root} with: ${projectRootWithSlash}`);
console.log(`Replacing {output_folder}/ with: ${docOutPath}/`);
console.log(`Processing files in: ${installPath}\n`);
}
const stats = replacePlaceholdersInDirectory(installPath, projectRootWithSlash, docOutPath, ['.md', '.xml', '.yaml'], false, verbose);
if (verbose) {
console.log('\n--- Installation Processing Complete ---');
}
console.log(`Files processed: ${stats.processed}`);
console.log(`Files modified: ${stats.modified}`);
if (stats.errors > 0) {
console.log(`Errors encountered: ${stats.errors}`);
}
return stats;
}
/**
* Bundle helper - removes {project-root}/ references for web bundling
* @param {string} bundlePath - Path where files are being bundled
* @returns {Object} - Bundle stats
*/
function processBundleRemoval(bundlePath) {
console.log(`\nRemoving {project-root}/ references for bundling`);
console.log(`Processing files in: ${bundlePath}\n`);
const stats = replaceProjectRootInDirectory(bundlePath, null, ['.md', '.xml'], true);
console.log('\n--- Bundle Processing Complete ---');
console.log(`Files processed: ${stats.processed}`);
console.log(`Files modified: ${stats.modified}`);
if (stats.errors > 0) {
console.log(`Errors encountered: ${stats.errors}`);
}
return stats;
}
module.exports = {
replacePlaceholdersInFile,
replacePlaceholdersInDirectory,
replacePlaceholdersInFiles,
replaceProjectRootInFile,
replaceProjectRootInDirectory,
replaceProjectRootInFiles,
processInstallation,
processBundleRemoval,
};

View File

@ -1,27 +0,0 @@
const path = require('node:path');
const { ManifestGenerator } = require('./installers/lib/core/manifest-generator');
async function regenerateManifests() {
const generator = new ManifestGenerator();
const targetDir = process.argv[2];
// List of modules to include in manifests
const selectedModules = ['bmb', 'bmm', 'cis'];
console.log('Regenerating manifests with relative paths...');
console.log('Target directory: .bmad');
try {
const result = await generator.generateManifests('.bmad', selectedModules, [], { ides: [] });
console.log('✓ Manifests generated successfully:');
console.log(` - ${result.workflows} workflows`);
console.log(` - ${result.agents} agents`);
console.log(` - ${result.tasks} tasks`);
console.log(` - ${result.files} files in files-manifest.csv`);
} catch (error) {
console.error('Error generating manifests:', error);
process.exit(1);
}
}
regenerateManifests();

View File

@ -1,43 +0,0 @@
/**
* Test script for YAML XML agent builder
* Usage: node tools/cli/test-yaml-builder.js
*/
const path = require('node:path');
const { YamlXmlBuilder } = require('./lib/yaml-xml-builder');
const { getProjectRoot } = require('./lib/project-root');
async function test() {
console.log('Testing YAML → XML Agent Builder\n');
const builder = new YamlXmlBuilder();
const projectRoot = getProjectRoot();
// Paths
const agentYamlPath = path.join(projectRoot, 'src/modules/bmm/agents/pm.agent.yaml');
const outputPath = path.join(projectRoot, 'test-output-pm.md');
console.log(`Source: ${agentYamlPath}`);
console.log(`Output: ${outputPath}\n`);
try {
const result = await builder.buildAgent(
agentYamlPath,
null, // No customize file for this test
outputPath,
{ includeMetadata: true },
);
console.log('✓ Build successful!');
console.log(` Output: ${result.outputPath}`);
console.log(` Source hash: ${result.sourceHash}`);
console.log('\nGenerated XML file at:', outputPath);
console.log('Review the output to verify correctness.\n');
} catch (error) {
console.error('✗ Build failed:', error.message);
console.error(error.stack);
process.exit(1);
}
}
test();

View File

@ -6,7 +6,7 @@ const ignore = require('ignore');
// These complement .gitignore and are applied regardless of VCS presence. // These complement .gitignore and are applied regardless of VCS presence.
const DEFAULT_PATTERNS = [ const DEFAULT_PATTERNS = [
// Project/VCS // Project/VCS
'**/.bmad-method/**', '**/_bmad/**',
'**/.git/**', '**/.git/**',
'**/.svn/**', '**/.svn/**',
'**/.hg/**', '**/.hg/**',