feat: installer offers option to install web bundles

This commit is contained in:
Brian Madison
2025-06-17 09:55:21 -05:00
parent fe27d68319
commit e934769a5e
5 changed files with 1638 additions and 181 deletions

View File

@@ -2440,67 +2440,6 @@ Document sharded successfully:
- Ensure the sharding is reversible (could reconstruct the original from shards) - Ensure the sharding is reversible (could reconstruct the original from shards)
==================== END: tasks#shard-doc ==================== ==================== END: tasks#shard-doc ====================
==================== START: templates#agent-tmpl ====================
# [AGENT_ID]
CRITICAL: Read the full YML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:
```yml
activation-instructions:
- Follow all instructions in this file -> this defines you, your persona and more importantly what you can do. STAY IN CHARACTER!
- Only read the files/tasks listed here when user selects them for execution to minimize context usage
- The customization field ALWAYS takes precedence over any conflicting instructions
- When listing tasks/templates or presenting options during conversations, always show as numbered options list, allowing the user to type a number to select or execute
agent:
name: [AGENT_NAME]
id: [AGENT_ID]
title: [AGENT_TITLE]
customization: [OPTIONAL_CUSTOMIZATION]
persona:
role: [AGENT_ROLE_DESCRIPTION]
style: [COMMUNICATION_STYLE]
identity: [AGENT_IDENTITY_DESCRIPTION]
focus: [PRIMARY_FOCUS_AREAS]
core_principles:
- [PRINCIPLE_1]
- [PRINCIPLE_2]
- [PRINCIPLE_3]
# Add more principles as needed
startup:
- [STARTUP_INSTRUCTIONS]
commands:
- "*help" - Show: numbered list of the following commands to allow selection
- "*chat-mode" - (Default) [DEFAULT_MODE_DESCRIPTION]
- "*create-doc {template}" - Create doc (no template = show available templates)
- [tasks] specific to the agent that are not covered by a template
- "*exit" - Say goodbye as the [AGENT_TITLE], and then abandon inhabiting this persona
dependencies:
tasks:
- [TASK_1]
- [TASK_2]
# Add required tasks
templates:
- [TEMPLATE_1]
- [TEMPLATE_2]
# Add required templates
checklists:
- [CHECKLIST_1]
# Add required checklists
data:
- [DATA_1]
# Add required data files
utils:
- [UTIL_1]
# Add required utilities
```
==================== END: templates#agent-tmpl ====================
==================== START: templates#architecture-tmpl ==================== ==================== START: templates#architecture-tmpl ====================
# {{Project Name}} Architecture Document # {{Project Name}} Architecture Document
@@ -8543,121 +8482,6 @@ With this work flow, there is only 1 story in progress at a time, worked sequent
None Listed None Listed
==================== END: data#technical-preferences ==================== ==================== END: data#technical-preferences ====================
==================== START: utils#agent-switcher.ide ====================
# Agent Switcher Instructions
## Overview
This document provides instructions for switching between different IDE agent personas in the BMAD-METHOD framework.
## Behavior
### Listing Available Agents
When no agent name is provided:
1. Read the `bmad-core/ide-agents/` directory
2. Look for files matching the pattern `*.ide.md`
3. Extract agent names from filenames (the part before `.ide.md`)
4. Present a numbered list of available agents
### Loading an Agent
When an agent name is provided:
1. Attempt to load `bmad-core/ide-agents/{agent-name}.ide.md`
2. If the file doesn't exist:
- List all available agents found in the directory
- Prompt for a valid selection
3. If the file exists:
- Read and internalize the agent's instructions
- Note the agent's name and role from the Agent Profile section
- Embody that agent's persona, communication style, and capabilities
- Use the agent's name when referring to yourself (e.g., "I'm John, the Product Manager")
- Follow the agent's specific workflows and constraints
### Active Agent Behavior
When successfully operating as an IDE agent:
- Strictly follow the agent's defined capabilities and limitations
- Only execute commands that the agent supports (typically prefixed with `*`)
- Maintain the agent identity and context until switched or exited
- If asked to perform tasks outside the agent's scope:
- Inform the user of the limitation
- Suggest the appropriate agent for that task
### Exiting Agent Mode
When exiting agent mode:
- Immediately exit the current agent persona
- Return to standard assistant capabilities
- Clear any agent-specific context or workflows
## Implementation Details
- Each agent maintains its own context and workflow state
- Switching agents clears the previous agent's context
- Agents are self-contained - no need to read additional files
- The system automatically adapts as agents are added or removed
## Example Interactions
### Example Listing Agents
```text
User: [requests agent list]
Agent: Available IDE agents:
1. architect
2. dev
3. devops
4. pm
5. po
6. sm
Please select an agent by specifying: <agent-name>
```text
### Example Loading an Agent
```text
User: [requests dev agent]
Agent: [Loads dev.ide.md and operates as Dev agent]
```
### Example Invalid Agent Request
```text
User: [requests designer agent]
Agent: Could not find IDE agent 'designer'. Available agents:
1. architect
2. dev
3. devops
4. pm
5. po
6. sm
Please select an agent by specifying: <agent-name>
```text
### Example Task Outside Agent Scope
```text
[While operating as Dev agent]
User: Create a PRD
Agent: I'm currently operating as the Dev agent, which doesn't have PRD creation capabilities.
The PM agent can create PRDs. Would you like me to switch to the PM agent?
```
### Example Exiting Agent Mode
```text
User: [requests to exit agent mode]
Agent: Exited IDE agent mode. Returned to standard assistant capabilities.
```
==================== END: utils#agent-switcher.ide ====================
==================== START: utils#template-format ==================== ==================== START: utils#template-format ====================
# Template Format Conventions # Template Format Conventions

File diff suppressed because it is too large Load Diff

View File

@@ -289,6 +289,36 @@ async function promptInstallation() {
// Use selected IDEs directly // Use selected IDEs directly
answers.ides = ides; answers.ides = ides;
// Ask for web bundles installation
const { includeWebBundles } = await inquirer.prompt([
{
type: 'confirm',
name: 'includeWebBundles',
message: 'Would you like to include pre-built web bundles? (standalone agent/team files)',
default: true
}
]);
if (includeWebBundles) {
const { webBundlesDirectory } = await inquirer.prompt([
{
type: 'input',
name: 'webBundlesDirectory',
message: 'Enter directory for web bundles:',
default: `${directory}/web-bundles`,
validate: (input) => {
if (!input.trim()) {
return 'Please enter a valid directory path';
}
return true;
}
}
]);
answers.webBundlesDirectory = webBundlesDirectory;
}
answers.includeWebBundles = includeWebBundles;
return answers; return answers;
} }

View File

@@ -115,6 +115,11 @@ class ConfigLoader {
return path.join(__dirname, '..', '..', '..', 'bmad-core'); return path.join(__dirname, '..', '..', '..', 'bmad-core');
} }
getDistPath() {
// Get the path to dist directory relative to the installer
return path.join(__dirname, '..', '..', '..', 'dist');
}
getAgentPath(agentId) { getAgentPath(agentId) {
return path.join(this.getBmadCorePath(), 'agents', `${agentId}.md`); return path.join(this.getBmadCorePath(), 'agents', `${agentId}.md`);
} }

View File

@@ -324,6 +324,12 @@ class Installer {
const expansionFiles = await this.installExpansionPacks(installDir, config.expansionPacks, spinner); const expansionFiles = await this.installExpansionPacks(installDir, config.expansionPacks, spinner);
files.push(...expansionFiles); files.push(...expansionFiles);
// Install web bundles if requested
if (config.includeWebBundles && config.webBundlesDirectory) {
spinner.text = "Installing web bundles...";
await this.installWebBundles(config.webBundlesDirectory, spinner);
}
// Set up IDE integration if requested // Set up IDE integration if requested
const ides = config.ides || (config.ide ? [config.ide] : []); const ides = config.ides || (config.ide ? [config.ide] : []);
if (ides.length > 0) { if (ides.length > 0) {
@@ -573,6 +579,10 @@ class Installer {
console.log(chalk.green(`✓ Expansion packs installed: ${packNames}`)); console.log(chalk.green(`✓ Expansion packs installed: ${packNames}`));
} }
if (config.includeWebBundles && config.webBundlesDirectory) {
console.log(chalk.green(`✓ Web bundles installed to: ${config.webBundlesDirectory}`));
}
if (ides.length > 0) { if (ides.length > 0) {
const ideNames = ides.map(ide => { const ideNames = ides.map(ide => {
const ideConfig = configLoader.getIdeConfiguration(ide); const ideConfig = configLoader.getIdeConfiguration(ide);
@@ -582,11 +592,13 @@ class Installer {
} }
// Information about web bundles // Information about web bundles
console.log(chalk.bold("\n📦 Web Bundles Available:")); if (!config.includeWebBundles) {
console.log("Pre-built web bundles are available in the project distribution:"); console.log(chalk.bold("\n📦 Web Bundles Available:"));
console.log(chalk.cyan(` ${path.join(path.dirname(installDir), 'dist')}/`)); console.log("Pre-built web bundles are available and can be added later:");
console.log("These bundles work independently and can be shared, moved, or used"); console.log(chalk.cyan(" Run the installer again to add them to your project"));
console.log("in other projects as standalone files."); console.log("These bundles work independently and can be shared, moved, or used");
console.log("in other projects as standalone files.");
}
if (config.installType === "single-agent") { if (config.installType === "single-agent") {
console.log( console.log(
@@ -797,6 +809,31 @@ class Installer {
return installedFiles; return installedFiles;
} }
async installWebBundles(webBundlesDirectory, spinner) {
// Ensure modules are initialized
await initializeModules();
try {
// Find the dist directory in the BMAD installation
const distDir = configLoader.getDistPath();
if (!(await fileManager.pathExists(distDir))) {
console.warn(chalk.yellow('Web bundles not found. Run "npm run build" to generate them.'));
return;
}
// Ensure web bundles directory exists
await fileManager.ensureDirectory(webBundlesDirectory);
// Copy the entire dist directory structure to web bundles directory
await fileManager.copyDirectory(distDir, webBundlesDirectory);
console.log(chalk.green(`✓ Installed web bundles to: ${webBundlesDirectory}`));
} catch (error) {
console.error(chalk.red(`Failed to install web bundles: ${error.message}`));
}
}
async findInstallation() { async findInstallation() {
// Look for .bmad-core in current directory or parent directories // Look for .bmad-core in current directory or parent directories
let currentDir = process.cwd(); let currentDir = process.cwd();