diff --git a/.github/workflows/bundle-latest.yaml b/.github/workflows/bundle-latest.yaml index d8a0da0e..7c49cb24 100644 --- a/.github/workflows/bundle-latest.yaml +++ b/.github/workflows/bundle-latest.yaml @@ -10,6 +10,7 @@ permissions: jobs: bundle-and-publish: + if: ${{ false }} # Temporarily disabled while web bundles are paused. runs-on: ubuntu-latest steps: - name: Checkout BMAD-METHOD diff --git a/tools/cli/bundlers/bundle-web.js b/tools/cli/bundlers/bundle-web.js deleted file mode 100644 index acbdbb24..00000000 --- a/tools/cli/bundlers/bundle-web.js +++ /dev/null @@ -1,67 +0,0 @@ -const { Command } = require('commander'); -const { WebBundler } = require('./web-bundler'); - -const program = new Command(); -const bundler = new WebBundler(); - -program.name('bundle-web').description('Generate BMAD web bundles').version('1.0.0'); - -program - .command('list') - .description('List available modules and agents') - .action(async () => { - await bundler.list(); - }); - -program - .command('clean') - .description('Remove all generated web bundles') - .action(async () => { - await bundler.clean(); - }); - -program - .command('all') - .description('Bundle all modules') - .action(async () => { - await bundler.bundleAll(); - }); - -program - .command('rebundle') - .description('Clean and bundle all modules') - .action(async () => { - await bundler.clean(); - await bundler.bundleAll(); - }); - -program - .command('module') - .description('Bundle a specific module') - .argument('', 'module name') - .action(async (name) => { - await bundler.bundleModule(name); - }); - -program - .command('agent') - .description('Bundle a specific agent') - .argument('', 'module name') - .argument('', 'agent name') - .action(async (moduleName, agentName) => { - await bundler.bundleAgentByName(moduleName, agentName); - }); - -program - .command('team') - .description('Bundle a specific team (not currently implemented)') - .argument('', 'module name') - .argument('', 'team name') - .action(async (moduleName, teamName) => { - throw new Error(`Team bundling is not implemented: ${moduleName}/${teamName}`); - }); - -program.parseAsync(process.argv).catch((error) => { - console.error(error.message || error); - process.exitCode = 1; -}); diff --git a/tools/cli/bundlers/web-bundler.js b/tools/cli/bundlers/web-bundler.js deleted file mode 100644 index eaa122e5..00000000 --- a/tools/cli/bundlers/web-bundler.js +++ /dev/null @@ -1,156 +0,0 @@ -const path = require('node:path'); -const fs = require('fs-extra'); -const chalk = require('chalk'); -const { XmlHandler } = require('../lib/xml-handler'); - -class WebBundler { - constructor(options = {}) { - this.projectRoot = options.projectRoot || path.resolve(__dirname, '../../..'); - this.modulesRoot = options.modulesRoot || path.join(this.projectRoot, 'src', 'modules'); - this.outputRoot = options.outputRoot || path.join(this.projectRoot, 'web-bundles'); - this.logger = options.logger || console; - this.xmlHandler = new XmlHandler(); - } - - async listModules() { - if (!(await fs.pathExists(this.modulesRoot))) { - return []; - } - - const entries = await fs.readdir(this.modulesRoot, { withFileTypes: true }); - return entries - .filter((entry) => entry.isDirectory()) - .map((entry) => entry.name) - .sort(); - } - - async listAgents(moduleName) { - const agentsDir = path.join(this.modulesRoot, moduleName, 'agents'); - if (!(await fs.pathExists(agentsDir))) { - return []; - } - - const files = await this.findAgentFiles(agentsDir); - return files.map((file) => path.basename(file, '.agent.yaml')).sort(); - } - - async list() { - const modules = await this.listModules(); - - if (modules.length === 0) { - this.logger.log('No modules found.'); - return; - } - - this.logger.log(chalk.cyan('Available modules and agents:')); - for (const moduleName of modules) { - const agents = await this.listAgents(moduleName); - this.logger.log(` ${moduleName}: ${agents.length} agent(s)`); - for (const agent of agents) { - this.logger.log(` - ${agent}`); - } - } - } - - async clean() { - if (await fs.pathExists(this.outputRoot)) { - await fs.remove(this.outputRoot); - } - this.logger.log(chalk.green('OK: Cleaned web-bundles output')); - } - - async bundleAll() { - const modules = await this.listModules(); - if (modules.length === 0) { - this.logger.log('No modules found to bundle.'); - return; - } - - await fs.ensureDir(this.outputRoot); - for (const moduleName of modules) { - await this.bundleModule(moduleName); - } - } - - async bundleModule(moduleName) { - const moduleRoot = path.join(this.modulesRoot, moduleName); - if (!(await fs.pathExists(moduleRoot))) { - throw new Error(`Module not found: ${moduleName}`); - } - - const agentsDir = path.join(moduleRoot, 'agents'); - if (!(await fs.pathExists(agentsDir))) { - this.logger.log(chalk.yellow(`Skipping ${moduleName}: no agents directory`)); - return; - } - - const outputModuleDir = path.join(this.outputRoot, moduleName, 'agents'); - await fs.remove(outputModuleDir); - await fs.ensureDir(outputModuleDir); - - const agentFiles = await this.findAgentFiles(agentsDir); - if (agentFiles.length === 0) { - this.logger.log(chalk.yellow(`Skipping ${moduleName}: no agent files found`)); - return; - } - - this.logger.log(chalk.cyan(`Bundling ${moduleName} (${agentFiles.length} agent(s))`)); - for (const agentFile of agentFiles) { - await this.bundleAgentFile(moduleName, agentFile); - } - } - - async bundleAgentByName(moduleName, agentName) { - const agentsDir = path.join(this.modulesRoot, moduleName, 'agents'); - if (!(await fs.pathExists(agentsDir))) { - throw new Error(`Agents directory not found for module: ${moduleName}`); - } - - const agentFiles = await this.findAgentFiles(agentsDir); - const match = agentFiles.find((file) => path.basename(file, '.agent.yaml') === agentName); - if (!match) { - throw new Error(`Agent not found: ${moduleName}/${agentName}`); - } - - const outputModuleDir = path.join(this.outputRoot, moduleName, 'agents'); - await fs.ensureDir(outputModuleDir); - await this.bundleAgentFile(moduleName, match); - } - - async bundleAgentFile(moduleName, agentFile) { - const agentName = path.basename(agentFile, '.agent.yaml'); - const outputFile = path.join(this.outputRoot, moduleName, 'agents', `${agentName}.xml`); - - const bundled = await this.xmlHandler.buildFromYaml(agentFile, null, { forWebBundle: true }); - const xml = this.extractXmlBlock(bundled); - - await fs.writeFile(outputFile, xml, 'utf8'); - this.logger.log(chalk.green(` OK: ${moduleName}/${agentName}`)); - } - - async findAgentFiles(rootDir) { - const entries = await fs.readdir(rootDir, { withFileTypes: true }); - const files = []; - - for (const entry of entries) { - const fullPath = path.join(rootDir, entry.name); - if (entry.isDirectory()) { - files.push(...(await this.findAgentFiles(fullPath))); - } else if (entry.isFile() && entry.name.endsWith('.agent.yaml')) { - files.push(fullPath); - } - } - - return files; - } - - extractXmlBlock(content) { - const match = content.match(/```xml\s*([\s\S]*?)```/); - if (!match) { - return content.trim() + '\n'; - } - return match[1].trim() + '\n'; - } -} - -module.exports = { WebBundler };