Node 20, installer improvements, agent improvements and Expansion Pack for game dev (#232)

* feat: add expansion pack installation system with game dev and infrastructure expansion packs

- Added expansion pack discovery and installation to BMAD installer
- Supports interactive and CLI installation of expansion packs
- Expansion pack files install to destination root (.bmad-core)
- Added game development expansion pack (.bmad-2d-phaser-game-dev)
  - Game designer, developer, and scrum master agents
  - Game-specific templates, tasks, workflows, and guidelines
  - Specialized for Phaser 3 + TypeScript development
- Added infrastructure devops expansion pack (.bmad-infrastructure-devops)
  - Platform engineering agent and infrastructure templates
- Expansion pack agents automatically integrate with IDE rules
- Added list:expansions command and --expansion-packs CLI option

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>

* alpha expansion packs and installer update to support installing expansion packs optionally

* node20

---------

Co-authored-by: Brian Madison <brianmadison@Brians-MacBook-Pro.local>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Brian
2025-06-16 18:34:12 -05:00
committed by GitHub
parent 7df4f4cd0f
commit 595342cb10
126 changed files with 20695 additions and 29296 deletions

View File

@@ -47,7 +47,8 @@ program
.option('-f, --full', 'Install complete .bmad-core folder')
.option('-a, --agent <agent>', 'Install specific agent with dependencies')
.option('-d, --directory <path>', 'Installation directory (default: .bmad-core)')
.option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo)')
.option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, roo, other)')
.option('-e, --expansion-packs <packs...>', 'Install specific expansion packs (can specify multiple)')
.action(async (options) => {
try {
await initializeModules();
@@ -61,7 +62,8 @@ program
installType: options.full ? 'full' : 'single-agent',
agent: options.agent,
directory: options.directory || '.bmad-core',
ides: options.ide || []
ides: (options.ide || []).filter(ide => ide !== 'other'),
expansionPacks: options.expansionPacks || []
};
await installer.install(config);
}
@@ -100,6 +102,19 @@ program
}
});
program
.command('list:expansions')
.description('List available expansion packs')
.action(async () => {
try {
await installer.listExpansionPacks();
} catch (error) {
if (!chalk) await initializeModules();
console.error(chalk.red('Error:'), error.message);
process.exit(1);
}
});
program
.command('status')
.description('Show installation status')
@@ -167,6 +182,41 @@ async function promptInstallation() {
answers.agent = agent;
}
// Ask for expansion pack selection (only for full installation)
if (installType === 'full') {
try {
const availableExpansionPacks = await installer.getAvailableExpansionPacks();
if (availableExpansionPacks.length > 0) {
const { expansionPacks } = await inquirer.prompt([
{
type: 'checkbox',
name: 'expansionPacks',
message: 'Select expansion packs to install (optional):',
choices: [
{ name: 'BMAD Core only (no expansion packs)', value: 'none', checked: true },
new inquirer.Separator(' --- Expansion Packs ---'),
...availableExpansionPacks.map(pack => ({
name: `${pack.name} - ${pack.description}`,
value: pack.id
}))
]
}
]);
// Filter out 'none' selection and only include actual expansion packs
answers.expansionPacks = expansionPacks.filter(pack => pack !== 'none');
} else {
answers.expansionPacks = [];
}
} catch (error) {
console.warn(chalk.yellow('Warning: Could not load expansion packs. Continuing without them.'));
answers.expansionPacks = [];
}
} else {
answers.expansionPacks = [];
}
// Ask for IDE configuration
const { ides } = await inquirer.prompt([
{
@@ -177,17 +227,20 @@ async function promptInstallation() {
{ name: 'Cursor', value: 'cursor' },
{ name: 'Claude Code', value: 'claude-code' },
{ name: 'Windsurf', value: 'windsurf' },
{ name: 'Roo Code', value: 'roo' }
{ name: 'Roo Code', value: 'roo' },
{ name: 'Other (skip IDE setup)', value: 'other' }
],
validate: (answer) => {
if (answer.length < 1) {
return 'You must choose at least one IDE, or press Ctrl+C to skip IDE setup.';
return 'You must choose at least one IDE option.';
}
return true;
}
}
]);
answers.ides = ides;
// Filter out 'other' from the list and only include actual IDEs
answers.ides = ides.filter(ide => ide !== 'other');
return answers;
}

View File

@@ -3,55 +3,55 @@ installation-options:
name: Complete BMAD Core
description: Copy the entire .bmad-core folder with all agents, templates, and tools
action: copy-folder
source: .bmad-core
source: bmad-core
single-agent:
name: Single Agent
description: Select and install a single agent with its dependencies
action: copy-agent
agent-dependencies:
core-files:
- .bmad-core/utils/template-format.md
- bmad-core/utils/template-format.md
dev:
- .bmad-core/templates/story-tmpl.md
- .bmad-core/checklists/story-dod-checklist.md
- bmad-core/templates/story-tmpl.md
- bmad-core/checklists/story-dod-checklist.md
pm:
- .bmad-core/templates/prd-tmpl.md
- .bmad-core/templates/brownfield-prd-tmpl.md
- .bmad-core/checklists/pm-checklist.md
- .bmad-core/checklists/change-checklist.md
- .bmad-core/tasks/advanced-elicitation.md
- .bmad-core/tasks/create-doc.md
- .bmad-core/tasks/correct-course.md
- .bmad-core/tasks/create-deep-research-prompt.md
- .bmad-core/tasks/brownfield-create-epic.md
- .bmad-core/tasks/brownfield-create-story.md
- .bmad-core/tasks/execute-checklist.md
- .bmad-core/tasks/shard-doc.md
- bmad-core/templates/prd-tmpl.md
- bmad-core/templates/brownfield-prd-tmpl.md
- bmad-core/checklists/pm-checklist.md
- bmad-core/checklists/change-checklist.md
- bmad-core/tasks/advanced-elicitation.md
- bmad-core/tasks/create-doc.md
- bmad-core/tasks/correct-course.md
- bmad-core/tasks/create-deep-research-prompt.md
- bmad-core/tasks/brownfield-create-epic.md
- bmad-core/tasks/brownfield-create-story.md
- bmad-core/tasks/execute-checklist.md
- bmad-core/tasks/shard-doc.md
architect:
- .bmad-core/templates/architecture-tmpl.md
- .bmad-core/checklists/architect-checklist.md
- bmad-core/templates/architecture-tmpl.md
- bmad-core/checklists/architect-checklist.md
sm:
- .bmad-core/templates/story-tmpl.md
- .bmad-core/checklists/story-draft-checklist.md
- .bmad-core/workflows/*.yml
- bmad-core/templates/story-tmpl.md
- bmad-core/checklists/story-draft-checklist.md
- bmad-core/workflows/*.yml
po:
- .bmad-core/checklists/po-master-checklist.md
- .bmad-core/templates/acceptance-criteria-tmpl.md
- bmad-core/checklists/po-master-checklist.md
- bmad-core/templates/acceptance-criteria-tmpl.md
analyst:
- .bmad-core/templates/prd-tmpl.md
- .bmad-core/tasks/advanced-elicitation.md
- bmad-core/templates/prd-tmpl.md
- bmad-core/tasks/advanced-elicitation.md
qa:
- .bmad-core/checklists/story-dod-checklist.md
- .bmad-core/templates/test-plan-tmpl.md
- bmad-core/checklists/story-dod-checklist.md
- bmad-core/templates/test-plan-tmpl.md
ux-expert:
- .bmad-core/templates/ux-tmpl.md
- bmad-core/templates/ux-tmpl.md
bmad-master:
- .bmad-core/templates/*.md
- .bmad-core/tasks/*.md
- .bmad-core/schemas/*.yml
- bmad-core/templates/*.md
- bmad-core/tasks/*.md
- bmad-core/schemas/*.yml
bmad-orchestrator:
- .bmad-core/agent-teams/*.yml
- .bmad-core/workflows/*.yml
- bmad-core/agent-teams/*.yml
- bmad-core/workflows/*.yml
ide-configurations:
cursor:
name: Cursor
@@ -99,41 +99,41 @@ ide-configurations:
available-agents:
- id: analyst
name: Business Analyst
file: .bmad-core/agents/analyst.md
file: bmad-core/agents/analyst.md
description: Requirements gathering and analysis
- id: pm
name: Product Manager
file: .bmad-core/agents/pm.md
file: bmad-core/agents/pm.md
description: Product strategy and roadmap planning
- id: architect
name: Solution Architect
file: .bmad-core/agents/architect.md
file: bmad-core/agents/architect.md
description: Technical design and architecture
- id: po
name: Product Owner
file: .bmad-core/agents/po.md
file: bmad-core/agents/po.md
description: Backlog management and prioritization
- id: sm
name: Scrum Master
file: .bmad-core/agents/sm.md
file: bmad-core/agents/sm.md
description: Agile process and story creation
- id: dev
name: Developer
file: .bmad-core/agents/dev.md
file: bmad-core/agents/dev.md
description: Code implementation and testing
- id: qa
name: QA Engineer
file: .bmad-core/agents/qa.md
file: bmad-core/agents/qa.md
description: Quality assurance and testing
- id: ux-expert
name: UX Expert
file: .bmad-core/agents/ux-expert.md
file: bmad-core/agents/ux-expert.md
description: User experience design
- id: bmad-master
name: BMAD Master
file: .bmad-core/agents/bmad-master.md
file: bmad-core/agents/bmad-master.md
description: BMAD framework expert and guide
- id: bmad-orchestrator
name: BMAD Orchestrator
file: .bmad-core/agents/bmad-orchestrator.md
file: bmad-core/agents/bmad-orchestrator.md
description: Multi-agent workflow coordinator

View File

@@ -30,6 +30,43 @@ class ConfigLoader {
return config['available-agents'] || [];
}
async getAvailableExpansionPacks() {
const expansionPacksDir = path.join(this.getBmadCorePath(), '..', 'expansion-packs');
try {
const entries = await fs.readdir(expansionPacksDir, { withFileTypes: true });
const expansionPacks = [];
for (const entry of entries) {
if (entry.isDirectory()) {
const manifestPath = path.join(expansionPacksDir, entry.name, 'manifest.yml');
try {
const manifestContent = await fs.readFile(manifestPath, 'utf8');
const manifest = yaml.load(manifestContent);
expansionPacks.push({
id: entry.name,
name: manifest.name || entry.name,
description: manifest.description || 'No description available',
version: manifest.version || '1.0.0',
author: manifest.author || 'Unknown',
manifestPath: manifestPath,
dependencies: manifest.dependencies || []
});
} catch (error) {
console.warn(`Failed to read manifest for expansion pack ${entry.name}: ${error.message}`);
}
}
}
return expansionPacks;
} catch (error) {
console.warn(`Failed to read expansion packs directory: ${error.message}`);
return [];
}
}
async getAgentDependencies(agentId) {
// Use DependencyResolver to dynamically parse agent dependencies
const DependencyResolver = require('../../lib/dependency-resolver');
@@ -77,8 +114,8 @@ class ConfigLoader {
}
getBmadCorePath() {
// Get the path to .bmad-core relative to the installer (now under tools)
return path.join(__dirname, '..', '..', '..', '.bmad-core');
// Get the path to bmad-core relative to the installer (now under tools)
return path.join(__dirname, '..', '..', '..', 'bmad-core');
}
getAgentPath(agentId) {

View File

@@ -261,6 +261,10 @@ class Installer {
}
}
// Install expansion packs if requested
const expansionFiles = await this.installExpansionPacks(installDir, config.expansionPacks, spinner);
files.push(...expansionFiles);
// Set up IDE integration if requested
const ides = config.ides || (config.ide ? [config.ide] : []);
if (ides.length > 0) {
@@ -505,6 +509,11 @@ class Installer {
console.log(chalk.bold("\n🎯 Installation Summary:"));
console.log(chalk.green("✓ .bmad-core framework installed with all agents and workflows"));
if (config.expansionPacks && config.expansionPacks.length > 0) {
const packNames = config.expansionPacks.join(", ");
console.log(chalk.green(`✓ Expansion packs installed: ${packNames}`));
}
if (ides.length > 0) {
const ideNames = ides.map(ide => {
const ideConfig = configLoader.getIdeConfiguration(ide);
@@ -569,6 +578,33 @@ class Installer {
);
}
async listExpansionPacks() {
// Initialize ES modules
await initializeModules();
const expansionPacks = await this.getAvailableExpansionPacks();
console.log(chalk.bold("\nAvailable BMAD Expansion Packs:\n"));
if (expansionPacks.length === 0) {
console.log(chalk.yellow("No expansion packs found."));
return;
}
for (const pack of expansionPacks) {
console.log(chalk.cyan(` ${pack.id.padEnd(20)}`),
`${pack.name} v${pack.version}`);
console.log(chalk.dim(` ${' '.repeat(22)}${pack.description}`));
if (pack.author && pack.author !== 'Unknown') {
console.log(chalk.dim(` ${' '.repeat(22)}by ${pack.author}`));
}
console.log();
}
console.log(
chalk.dim("Install with: npx bmad-method install --full --expansion-packs <id>\n")
);
}
async showStatus() {
// Initialize ES modules
await initializeModules();
@@ -624,6 +660,96 @@ class Installer {
return configLoader.getAvailableAgents();
}
async getAvailableExpansionPacks() {
return configLoader.getAvailableExpansionPacks();
}
async installExpansionPacks(installDir, selectedPacks, spinner) {
if (!selectedPacks || selectedPacks.length === 0) {
return [];
}
const installedFiles = [];
const glob = require('glob');
for (const packId of selectedPacks) {
spinner.text = `Installing expansion pack: ${packId}...`;
try {
const expansionPacks = await this.getAvailableExpansionPacks();
const pack = expansionPacks.find(p => p.id === packId);
if (!pack) {
console.warn(`Expansion pack ${packId} not found, skipping...`);
continue;
}
const expansionPackDir = path.dirname(pack.manifestPath);
// Define the folders to copy from expansion packs to .bmad-core
const foldersToSync = [
'agents',
'agent-teams',
'templates',
'tasks',
'checklists',
'workflows',
'data',
'utils',
'schemas'
];
// Copy each folder if it exists
for (const folder of foldersToSync) {
const sourceFolder = path.join(expansionPackDir, folder);
// Check if folder exists in expansion pack
if (await fileManager.pathExists(sourceFolder)) {
// Get all files in this folder
const files = glob.sync('**/*', {
cwd: sourceFolder,
nodir: true
});
// Copy each file to the destination
for (const file of files) {
const sourcePath = path.join(sourceFolder, file);
const destPath = path.join(installDir, '.bmad-core', folder, file);
if (await fileManager.copyFile(sourcePath, destPath)) {
installedFiles.push(path.join('.bmad-core', folder, file));
}
}
}
}
// Also copy web-bundles if they exist (to a different location)
const webBundlesSource = path.join(expansionPackDir, 'web-bundles');
if (await fileManager.pathExists(webBundlesSource)) {
const files = glob.sync('**/*', {
cwd: webBundlesSource,
nodir: true
});
for (const file of files) {
const sourcePath = path.join(webBundlesSource, file);
const destPath = path.join(installDir, '.bmad-core', 'web-bundles', 'expansion-packs', packId, file);
if (await fileManager.copyFile(sourcePath, destPath)) {
installedFiles.push(path.join('.bmad-core', 'web-bundles', 'expansion-packs', packId, file));
}
}
}
console.log(chalk.green(`✓ Installed expansion pack: ${pack.name}`));
} catch (error) {
console.error(chalk.red(`Failed to install expansion pack ${packId}: ${error.message}`));
}
}
return installedFiles;
}
async findInstallation() {
// Look for .bmad-core in current directory or parent directories
let currentDir = process.cwd();

View File

@@ -1,12 +1,12 @@
{
"name": "bmad-method",
"version": "4.0.1",
"version": "4.3.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "bmad-method",
"version": "4.0.1",
"version": "4.3.0",
"license": "MIT",
"dependencies": {
"chalk": "^5.4.1",
@@ -21,7 +21,7 @@
"bmad-method": "bin/bmad.js"
},
"engines": {
"node": ">=14.0.0"
"node": ">=20.0.0"
}
},
"node_modules/@inquirer/checkbox": {

View File

@@ -30,7 +30,7 @@
"ora": "^8.2.0"
},
"engines": {
"node": ">=14.0.0"
"node": ">=20.0.0"
},
"repository": {
"type": "git",