Compare commits

...

4 Commits

7 changed files with 75 additions and 14 deletions

View File

@ -234,7 +234,7 @@ your-project/
2. Run `*workflow-init` to set up your project workflow path 2. Run `*workflow-init` to set up your project workflow path
3. Follow the [Quick Start](#-quick-start) guide above to choose your planning track 3. Follow the [Quick Start](#-quick-start) guide above to choose your planning track
**Alternative:** [**Web Bundles**](./docs/USING_WEB_BUNDLES.md) - Use BMAD agents in Claude Projects, ChatGPT, or Gemini without installation **Alternative:** [**Web Bundles**](https://bmad-code-org.github.io/bmad-bundles/) - Download pre-built agent bundles for use in Claude Projects, ChatGPT, or Gemini without installation (automatically updated on every commit to main)
--- ---

View File

@ -36,11 +36,11 @@ Web bundles are standalone XML files containing:
**Option A: Download Pre-Bundled Files (Quickest)** **Option A: Download Pre-Bundled Files (Quickest)**
Download ready-to-use bundles directly from GitHub: Download ready-to-use bundles that are automatically updated whenever commits are merged to main:
**[→ Browse Web Bundles on GitHub](https://github.com/bmad-code-org/BMAD-METHOD/tree/main/web-bundles)** **[→ Download Web Bundles](https://bmad-code-org.github.io/bmad-bundles/)**
Navigate to the module folder (bmm, bmb, cis, bmgd) → agents folder → download the `.xml` file you need. Navigate to the module folder (bmm, bmb, cis, bmgd) → agents folder → download the `.xml` file you need. These bundles are automatically regenerated and deployed with every commit to the main branch, ensuring you always have the latest version.
**Option B: Generate from Local Installation** **Option B: Generate from Local Installation**

View File

@ -105,9 +105,9 @@
<item cmd="*help">Show numbered command list</item> <item cmd="*help">Show numbered command list</item>
<item cmd="*list-agents">List all available agents with their capabilities</item> <item cmd="*list-agents">List all available agents with their capabilities</item>
<item cmd="*agents [agent-name]">Transform into a specific agent</item> <item cmd="*agents [agent-name]">Transform into a specific agent</item>
<item cmd="*party-mode" workflow="bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml">Enter group chat with all agents <item cmd="*party-mode" workflow="{bmad_folder}/core/workflows/party-mode/workflow.yaml">Enter group chat with all agents
simultaneously</item> simultaneously</item>
<item cmd="*advanced-elicitation" task="bmad/core/tasks/advanced-elicitation.xml">Push agent to perform advanced elicitation</item> <item cmd="*advanced-elicitation" task="{bmad_folder}/core/tasks/advanced-elicitation.xml">Push agent to perform advanced elicitation</item>
<item cmd="*exit">Exit current session</item> <item cmd="*exit">Exit current session</item>
</menu> </menu>
</agent> </agent>

View File

@ -36,7 +36,7 @@
<step n="3" title="Execute Sharding"> <step n="3" title="Execute Sharding">
<action>Inform user that sharding is beginning</action> <action>Inform user that sharding is beginning</action>
<action>Execute command: `npx @kayvan/markdown-tree-parser [source-document] [destination-folder]`</action> <action>Execute command: `npx @kayvan/markdown-tree-parser explode [source-document] [destination-folder]`</action>
<action>Capture command output and any errors</action> <action>Capture command output and any errors</action>
<action if="command fails">HALT and display error to user</action> <action if="command fails">HALT and display error to user</action>
</step> </step>
@ -106,4 +106,4 @@ Consider deleting or archiving the original document.</output>
<halt-conditions critical="true"> <halt-conditions critical="true">
<i>HALT if npx command fails or produces no output files</i> <i>HALT if npx command fails or produces no output files</i>
</halt-conditions> </halt-conditions>
</tool> </tool>

View File

@ -21,7 +21,9 @@ web_bundle:
name: "party-mode" name: "party-mode"
description: "Orchestrates group discussions between all installed BMAD agents, enabling natural multi-agent conversations" description: "Orchestrates group discussions between all installed BMAD agents, enabling natural multi-agent conversations"
author: "BMad" author: "BMad"
instructions: "bmad/core/workflows/party-mode/instructions.md" instructions: "{bmad_folder}/core/workflows/party-mode/instructions.md"
agent_manifest: "bmad/_cfg/agent-manifest.csv" agent_manifest: "{bmad_folder}/_cfg/agent-manifest.csv"
web_bundle_files: web_bundle_files:
- "{bmad_folder}/core/workflows/party-mode/workflow.xml" - "{bmad_folder}/core/workflows/party-mode/workflow.xml"
- "{bmad_folder}/core/workflows/party-mode/instructions.md"
- "{bmad_folder}/_cfg/agent-manifest.csv"

View File

@ -48,6 +48,36 @@ class ConfigCollector {
return path.join(projectDir, 'bmad'); return path.join(projectDir, 'bmad');
} }
/**
* Detect the existing BMAD folder name in a project
* @param {string} projectDir - Project directory
* @returns {Promise<string|null>} Folder name (just the name, not full path) or null if not found
*/
async detectExistingBmadFolder(projectDir) {
// Check if project directory exists
if (!(await fs.pathExists(projectDir))) {
return null;
}
// Look for ANY directory with _cfg/manifest.yaml
try {
const entries = await fs.readdir(projectDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const manifestPath = path.join(projectDir, entry.name, '_cfg', 'manifest.yaml');
if (await fs.pathExists(manifestPath)) {
// Found a V6+ installation, return just the folder name
return entry.name;
}
}
}
} catch {
// Ignore errors
}
return null;
}
/** /**
* Load existing config if it exists from module config files * Load existing config if it exists from module config files
* @param {string} projectDir - Target project directory * @param {string} projectDir - Target project directory
@ -565,6 +595,15 @@ class ConfigCollector {
} }
} }
// Special handling for bmad_folder: detect existing folder name
if (moduleName === 'core' && key === 'bmad_folder' && !existingValue && this.currentProjectDir) {
// Try to detect the existing BMAD folder name
const detectedFolder = await this.detectExistingBmadFolder(this.currentProjectDir);
if (detectedFolder) {
existingValue = detectedFolder;
}
}
// Determine question type and default value // Determine question type and default value
let questionType = 'input'; let questionType = 'input';
let defaultValue = item.default; let defaultValue = item.default;

View File

@ -562,7 +562,12 @@ class Installer {
config.skipIde = toolSelection.skipIde; config.skipIde = toolSelection.skipIde;
const ideConfigurations = toolSelection.configurations; const ideConfigurations = toolSelection.configurations;
spinner.start('Continuing installation...'); // Check if spinner is already running (e.g., from folder name change scenario)
if (spinner.isSpinning) {
spinner.text = 'Continuing installation...';
} else {
spinner.start('Continuing installation...');
}
// Create bmad directory structure // Create bmad directory structure
spinner.text = 'Creating directory structure...'; spinner.text = 'Creating directory structure...';
@ -1753,8 +1758,19 @@ class Installer {
lastModified: new Date().toISOString(), lastModified: new Date().toISOString(),
}; };
// Now run the full installation with the collected configs // Check if bmad_folder has changed
spinner.start('Updating BMAD installation...'); const existingBmadFolderName = path.basename(bmadDir);
const newBmadFolderName = this.configCollector.collectedConfig.core?.bmad_folder || existingBmadFolderName;
if (existingBmadFolderName === newBmadFolderName) {
// Normal quick update - start the spinner
spinner.start('Updating BMAD installation...');
} else {
// Folder name has changed - stop spinner and let install() handle it
spinner.stop();
console.log(chalk.yellow(`\n⚠️ Folder name will change: ${existingBmadFolderName}${newBmadFolderName}`));
console.log(chalk.yellow('The installer will handle the folder migration.\n'));
}
// Build the config object for the installer // Build the config object for the installer
const installConfig = { const installConfig = {
@ -1773,7 +1789,11 @@ class Installer {
// Call the standard install method // Call the standard install method
const result = await this.install(installConfig); const result = await this.install(installConfig);
spinner.succeed('Quick update complete!'); // Only succeed the spinner if it's still spinning
// (install method might have stopped it if folder name changed)
if (spinner.isSpinning) {
spinner.succeed('Quick update complete!');
}
return { return {
success: true, success: true,