doc updates, build folder renamed to tools, readme clarity for v4

This commit is contained in:
Brian Madison
2025-06-08 10:36:23 -05:00
parent 6c4ff90c50
commit aa3d8eba67
25 changed files with 20397 additions and 520 deletions

215
tools/cli.js Executable file
View File

@@ -0,0 +1,215 @@
#!/usr/bin/env node
/**
* BMAD v4 Build CLI
* Command line interface for building agents and bundles
*/
const { program } = require('commander');
const WebBuilder = require('./builders/web-builder');
const DependencyResolver = require('./lib/dependency-resolver');
// Initialize resolver
const resolver = new DependencyResolver();
program
.name('bmad-build')
.description('BMAD v4 Build System')
.version('4.0.0');
// Build all web bundles and agents
program
.command('build')
.alias('build:web')
.description('Build all web bundles and standalone agents')
.option('--sample-update', 'Also output to web-bundles directory')
.action(async (options) => {
try {
const builder = new WebBuilder();
if (options.sampleUpdate) {
builder.enableSampleUpdate();
}
const results = await builder.buildAll();
if (results.errors.length > 0) {
console.log('\n⚠ Build completed with errors:');
results.errors.forEach(error => {
console.log(` ${error.type}: ${error.name} - ${error.error}`);
});
process.exit(1);
} else {
console.log('\n🎉 All builds completed successfully!');
if (options.sampleUpdate) {
console.log(' 📁 Also updated web-bundles directory');
}
}
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
});
// Build specific bundle
program
.command('build:bundle')
.description('Build a specific bundle')
.requiredOption('-n, --name <name>', 'Bundle name')
.action(async (options) => {
try {
const builder = new WebBuilder();
const configs = builder.loadBundleConfigs();
const config = configs.find(c => c.name.toLowerCase().includes(options.name.toLowerCase()));
if (!config) {
console.error(`❌ Bundle not found: ${options.name}`);
process.exit(1);
}
const result = await builder.buildBundle(config);
console.log(`✅ Built bundle: ${result.name}`);
console.log(` Files: ${result.outputs.length}`);
console.log(` Size: ${result.statistics.totalSize} characters`);
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
});
// Build standalone agent
program
.command('build:agent')
.description('Build a standalone agent')
.requiredOption('-a, --agent <id>', 'Agent ID')
.action(async (options) => {
try {
const builder = new WebBuilder();
const result = await builder.buildStandaloneAgent(options.agent);
console.log(`✅ Built agent: ${result.name}`);
console.log(` File: ${result.outputs[0]}`);
console.log(` Size: ${result.statistics.totalSize} characters`);
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
});
// List available agents
program
.command('list:agents')
.description('List all available agents')
.action(() => {
try {
const agents = resolver.getAvailableAgents();
console.log('📋 Available agents:');
agents.forEach(agentId => {
try {
const config = resolver.loadAgentConfig(agentId);
const webCompatible = config.environments.web?.available !== false;
const ideOnly = config.environments.ide?.ide_only === true;
console.log(` ${agentId}: ${config.name}`);
console.log(` ${config.description}`);
console.log(` Environments: ${webCompatible ? 'web' : ''}${webCompatible && !ideOnly ? ', ' : ''}${!ideOnly ? 'ide' : 'ide-only'}`);
console.log('');
} catch (error) {
console.log(` ${agentId}: Error loading config`);
}
});
} catch (error) {
console.error('❌ Failed to list agents:', error.message);
process.exit(1);
}
});
// Analyze dependencies
program
.command('analyze:deps')
.description('Analyze agent dependencies')
.option('-a, --agent <id>', 'Specific agent ID')
.option('-g, --graph', 'Generate dependency graph')
.action((options) => {
try {
if (options.agent) {
const deps = resolver.resolveAgentDependencies(options.agent, 'web');
console.log(`📊 Dependencies for ${deps.config.name}:`);
Object.entries(deps.resources).forEach(([type, resources]) => {
if (resources.length > 0) {
console.log(` ${type}: ${resources.join(', ')}`);
}
});
} else if (options.graph) {
const graph = resolver.generateDependencyGraph();
console.log('📈 Dependency Graph:');
console.log(` Nodes: ${graph.nodes.length}`);
console.log(` Edges: ${graph.edges.length}`);
console.log('\n Agents:');
graph.nodes.filter(n => n.type === 'agent').forEach(n => {
console.log(` ${n.id}: ${n.label}`);
});
} else {
const agents = resolver.getAvailableAgents();
console.log('📊 All Agent Dependencies:');
agents.forEach(agentId => {
try {
const deps = resolver.resolveAgentDependencies(agentId, 'web');
const totalDeps = Object.values(deps.resources).reduce((sum, arr) => sum + arr.length, 0);
console.log(` ${agentId}: ${totalDeps} total dependencies`);
} catch (error) {
console.log(` ${agentId}: Error resolving dependencies`);
}
});
}
} catch (error) {
console.error('❌ Analysis failed:', error.message);
process.exit(1);
}
});
// Validate configuration
program
.command('validate')
.description('Validate all configurations')
.action(() => {
try {
const agents = resolver.getAvailableAgents();
let errors = 0;
console.log('🔍 Validating configurations...');
agents.forEach(agentId => {
try {
const deps = resolver.resolveAgentDependencies(agentId, 'web');
console.log(`${agentId}: Valid`);
} catch (error) {
console.log(`${agentId}: ${error.message}`);
errors++;
}
});
if (errors > 0) {
console.log(`\n❌ Validation failed: ${errors} errors found`);
process.exit(1);
} else {
console.log('\n✅ All configurations valid!');
}
} catch (error) {
console.error('❌ Validation failed:', error.message);
process.exit(1);
}
});
// Handle unknown commands
program.on('command:*', () => {
console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
process.exit(1);
});
// Parse command line arguments
program.parse();
// Show help if no command provided
if (!process.argv.slice(2).length) {
program.outputHelp();
}