From 7e285d34d82847a92985b9e360f119a17426cb56 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 09:46:16 -0700 Subject: [PATCH 1/5] fix: Clear all npm config env vars before calling AgentVibes installer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When BMAD is invoked with --prefix flag, npm sets many npm_config_* and npm_package_* environment variables. These caused npx agentvibes to look for files in the wrong directory (/prefix/lib instead of cwd). Changes: - tools/cli/commands/install.js: Filter out ALL npm_config_* and npm_package_* env vars before calling npx agentvibes - tools/cli/installers/lib/core/installer.js: Add AgentVibes prompt to Quick Update flow so existing installations can enable TTS - tools/cli/installers/lib/core/manifest-generator.js: Track agentVibes configuration in manifest.yaml This ensures AgentVibes runs in a clean environment regardless of how BMAD was invoked (with or without --prefix flag). šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tools/cli/commands/install.js | 8 +++++ tools/cli/installers/lib/core/installer.js | 33 +++++++++++++++++++ .../installers/lib/core/manifest-generator.js | 4 +++ 3 files changed, 45 insertions(+) diff --git a/tools/cli/commands/install.js b/tools/cli/commands/install.js index e7725338..3a603fd9 100644 --- a/tools/cli/commands/install.js +++ b/tools/cli/commands/install.js @@ -90,10 +90,18 @@ module.exports = { // Run AgentVibes installer const { execSync } = require('node:child_process'); try { + // Clear ALL npm config env vars to prevent inheritance issues + // when BMAD is invoked with --prefix flag + // npm sets many npm_config_* and npm_package_* vars that can interfere + const cleanEnv = Object.fromEntries( + Object.entries(process.env).filter(([key]) => !key.startsWith('npm_config_') && !key.startsWith('npm_package_')), + ); + execSync('npx agentvibes@latest install', { cwd: result.projectDir, stdio: 'inherit', shell: true, + env: cleanEnv, }); console.log(chalk.green('\nāœ“ AgentVibes installation complete')); } catch { diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 6e6fbab9..2273f45a 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -808,6 +808,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: const manifestStats = await manifestGen.generateManifests(bmadDir, config.modules || [], this.installedFiles, { ides: config.ides || [], preservedModules: config._preserveModules || [], // Scan these from installed bmad/ dir + agentVibes: { enabled: this.enableAgentVibes || false }, // Track AgentVibes TTS configuration }); spinner.succeed( @@ -1939,6 +1940,37 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: } } + // Check for AgentVibes TTS - prompt if not previously configured + // Read existing manifest to check if AgentVibes was previously set + const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml'); + let agentVibesEnabled = false; + let agentVibesPreviouslyConfigured = false; + + try { + const manifestContent = await fs.readFile(manifestPath, 'utf8'); + const yaml = require('js-yaml'); + const manifest = yaml.load(manifestContent); + // Check if AgentVibes was previously configured (exists in manifest) + if (manifest.agentVibes !== undefined) { + agentVibesPreviouslyConfigured = true; + agentVibesEnabled = manifest.agentVibes?.enabled || false; + } + } catch { + // Manifest doesn't exist or can't be read - treat as not configured + } + + // If AgentVibes wasn't previously configured, prompt the user + if (!agentVibesPreviouslyConfigured) { + const { UI } = require('../../../lib/ui'); + const ui = new UI(); + const agentVibesConfig = await ui.promptAgentVibes(projectDir); + + if (agentVibesConfig.enableTts) { + agentVibesEnabled = true; + promptedForNewFields = true; + } + } + if (!promptedForNewFields) { console.log(chalk.green('āœ“ All configuration is up to date, no new options to configure')); } @@ -1976,6 +2008,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: _quickUpdate: true, // Flag to skip certain prompts _preserveModules: skippedModules, // Preserve these in manifest even though we didn't update them _savedIdeConfigs: savedIdeConfigs, // Pass saved IDE configs to installer + enableAgentVibes: agentVibesEnabled, // AgentVibes TTS configuration }; // Call the standard install method diff --git a/tools/cli/installers/lib/core/manifest-generator.js b/tools/cli/installers/lib/core/manifest-generator.js index 1dbb8ea6..0458c188 100644 --- a/tools/cli/installers/lib/core/manifest-generator.js +++ b/tools/cli/installers/lib/core/manifest-generator.js @@ -54,6 +54,9 @@ class ManifestGenerator { // Filter out any undefined/null values from IDE list this.selectedIdes = resolvedIdes.filter((ide) => ide && typeof ide === 'string'); + // Store AgentVibes configuration for manifest + this.agentVibes = options.agentVibes || null; + // Collect workflow data await this.collectWorkflows(selectedModules); @@ -437,6 +440,7 @@ class ManifestGenerator { }, modules: this.modules, ides: this.selectedIdes, + agentVibes: this.agentVibes, // Track AgentVibes TTS configuration }; const yamlStr = yaml.dump(manifest, { From 9755d6df9031b7b698bb2534fb3068d137bd36e2 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 09:54:17 -0700 Subject: [PATCH 2/5] feat: Swap bmad-master and pm voice assignments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - bmad-master: en_US-ryan-high → en_US-lessac-medium - pm (john): en_US-lessac-medium → en_US-ryan-high šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .bmad/_cfg/agent-voice-map.csv | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .bmad/_cfg/agent-voice-map.csv diff --git a/.bmad/_cfg/agent-voice-map.csv b/.bmad/_cfg/agent-voice-map.csv new file mode 100644 index 00000000..18a20fe4 --- /dev/null +++ b/.bmad/_cfg/agent-voice-map.csv @@ -0,0 +1,11 @@ +agent,voice +bmad-master,en_US-lessac-medium +analyst,en_US-kristin-medium +architect,en_GB-alan-medium +dev,en_US-joe-medium +pm,en_US-ryan-high +sm,en_US-amy-medium +tea,en_US-kusal-medium +tech-writer,jenny +ux-designer,kristin +frame-expert,en_GB-alan-medium From 1f826b7891c4b8ace16c237d9921b4db7e07041f Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 10:04:00 -0700 Subject: [PATCH 3/5] feat: Move AgentVibes prompt after tool selection with smart defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Move AgentVibes TTS prompt to after IDE/tool selection - Default to Y if Claude Code is selected (since AgentVibes only works with Claude Code) - Default to N if Claude Code is not selected - Remove mid-install warning about AgentVibes not being installed (handled at end) - Pass configured IDEs to quick update flow for consistent behavior šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tools/cli/installers/lib/core/installer.js | 3 ++- tools/cli/lib/ui.js | 24 ++++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 2273f45a..4438d9f2 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -1960,10 +1960,11 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: } // If AgentVibes wasn't previously configured, prompt the user + // Use configuredIdes from line 1904 for smart default (Y if Claude Code is selected) if (!agentVibesPreviouslyConfigured) { const { UI } = require('../../../lib/ui'); const ui = new UI(); - const agentVibesConfig = await ui.promptAgentVibes(projectDir); + const agentVibesConfig = await ui.promptAgentVibes(projectDir, configuredIdes); if (agentVibesConfig.enableTts) { agentVibesEnabled = true; diff --git a/tools/cli/lib/ui.js b/tools/cli/lib/ui.js index 32e8dfc0..34ee9bbf 100644 --- a/tools/cli/lib/ui.js +++ b/tools/cli/lib/ui.js @@ -119,13 +119,14 @@ class UI { const moduleChoices = await this.getModuleChoices(installedModuleIds); const selectedModules = await this.selectModules(moduleChoices); - // Prompt for AgentVibes TTS integration - const agentVibesConfig = await this.promptAgentVibes(confirmedDirectory); - // Collect IDE tool selection AFTER configuration prompts (fixes Windows/PowerShell hang) // This allows text-based prompts to complete before the checkbox prompt const toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules); + // Prompt for AgentVibes TTS integration AFTER tool selection + // Default to Y if Claude Code is selected (since AgentVibes only works with Claude Code) + const agentVibesConfig = await this.promptAgentVibes(confirmedDirectory, toolSelection.ides); + // No more screen clearing - keep output flowing return { @@ -704,7 +705,7 @@ class UI { * - Markers: src/core/workflows/party-mode/instructions.md:101, src/modules/bmm/agents/*.md * - GitHub Issue: paulpreibisch/AgentVibes#36 */ - async promptAgentVibes(projectDir) { + async promptAgentVibes(projectDir, selectedIdes = []) { CLIUtils.displaySection('šŸŽ¤ Voice Features', 'Enable TTS for multi-agent conversations'); // Check if AgentVibes is already installed @@ -716,20 +717,21 @@ class UI { console.log(chalk.dim(' AgentVibes not detected')); } + // Default to Y if Claude Code is selected (AgentVibes only works with Claude Code) + const claudeCodeSelected = selectedIdes.includes('claude-code'); + const defaultValue = claudeCodeSelected; + const answers = await inquirer.prompt([ { type: 'confirm', name: 'enableTts', - message: 'Enable Agents to Speak Out loud (powered by Agent Vibes? Claude Code only currently)', - default: false, // Default to yes - recommended for best experience + message: 'Enable Agents to Speak Out loud (powered by AgentVibes, Claude Code only)', + default: defaultValue, }, ]); - if (answers.enableTts && !agentVibesInstalled) { - console.log(chalk.yellow('\n āš ļø AgentVibes not installed')); - console.log(chalk.dim(' Install AgentVibes separately to enable TTS:')); - console.log(chalk.dim(' https://github.com/paulpreibisch/AgentVibes\n')); - } + // Note: AgentVibes installer runs at end of BMAD install if enabled and not already installed + // No need to show warning here - the installer will handle it return { enabled: answers.enableTts, From e3f87e07c1b356bfd44c1c556c19c0c95fec6c33 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 11:00:01 -0700 Subject: [PATCH 4/5] feat: Add voice map generation with agent intros for party mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Generate _cfg/agent-voice-map.csv during BMAD install with voice and intro columns - Update party mode instructions to have 3-4 agents introduce themselves on activation - Each agent speaks their personalized intro message via TTS šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/core/workflows/party-mode/instructions.md | 34 +++++++-- .../installers/lib/core/manifest-generator.js | 75 +++++++++++++++++++ 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/core/workflows/party-mode/instructions.md b/src/core/workflows/party-mode/instructions.md index 3289f0a7..959f5632 100644 --- a/src/core/workflows/party-mode/instructions.md +++ b/src/core/workflows/party-mode/instructions.md @@ -7,7 +7,7 @@ - + Load the agent manifest CSV from {{agent_manifest}} Parse CSV to extract all agent entries with their condensed information: - name (agent identifier) @@ -21,7 +21,10 @@ - module (source module) - path (file location) -Build complete agent roster with merged personalities +Load the agent voice map CSV from {project-root}/{bmad_folder}/\_cfg/agent-voice-map.csv +Parse voice map to get each agent's voice and intro message: - agent (agent identifier, matches name from manifest) - voice (Piper TTS voice name) - intro (introduction message for greetings) + +Build complete agent roster with merged personalities and voice data Store agent data for use in conversation orchestration @@ -34,14 +37,33 @@ Participating agents: [For each agent in roster:] - - [Agent Name] ([Title]): [Role from merged data] + - [Icon] [Agent Display Name] ([Title]): [Role from merged data] [Total count] agents ready to collaborate! - What would you like to discuss with the team? - - Wait for user to provide initial topic or question + +Have 3-4 agents introduce themselves using their intro from the voice map: + +For each selected agent: 1. Output: [Icon Emoji] [Agent Display Name]: [intro from voice map] 2. Trigger TTS: `.claude/hooks/bmad-speak.sh "[Display Name]" "[intro]"` + + +šŸ§™ BMad Master: Greetings! The BMad Master is here to orchestrate and guide you through any workflow. +[Bash: .claude/hooks/bmad-speak.sh "BMad Master" "Greetings! The BMad Master is here to orchestrate and guide you through any workflow."] + + šŸ“‹ John: Hey team! John here, your Product Manager. Let's make sure we're building the right thing. + [Bash: .claude/hooks/bmad-speak.sh "John" "Hey team! John here, your Product Manager. Let's make sure we're building the right thing."] + + šŸ—ļø Winston: Hello! Winston here, your Architect. I'll ensure we build something scalable and pragmatic. + [Bash: .claude/hooks/bmad-speak.sh "Winston" "Hello! Winston here, your Architect. I'll ensure we build something scalable and pragmatic."] + + + +After intros, ask what the team can help with: + +What would you like to discuss with the team? + +Wait for user to provide initial topic or question diff --git a/tools/cli/installers/lib/core/manifest-generator.js b/tools/cli/installers/lib/core/manifest-generator.js index 0458c188..1b3be9ad 100644 --- a/tools/cli/installers/lib/core/manifest-generator.js +++ b/tools/cli/installers/lib/core/manifest-generator.js @@ -74,6 +74,7 @@ class ManifestGenerator { await this.writeMainManifest(cfgDir), await this.writeWorkflowManifest(cfgDir), await this.writeAgentManifest(cfgDir), + await this.writeVoiceMap(cfgDir), await this.writeTaskManifest(cfgDir), await this.writeToolManifest(cfgDir), await this.writeFilesManifest(cfgDir), @@ -576,6 +577,80 @@ class ManifestGenerator { return csvPath; } + /** + * Write agent voice map CSV for AgentVibes TTS integration + * Maps agent IDs to default Piper TTS voices and intro messages + * AgentVibes will use this if present, otherwise falls back to its own defaults + * @returns {string} Path to the voice map file + */ + async writeVoiceMap(cfgDir) { + const csvPath = path.join(cfgDir, 'agent-voice-map.csv'); + + // Default voice assignments and intros for BMAD agents + // These can be customized by editing the generated CSV + const agentDefaults = { + 'bmad-master': { + voice: 'en_US-lessac-medium', + intro: 'Greetings! The BMad Master is here to orchestrate and guide you through any workflow.', + }, + analyst: { + voice: 'en_US-kristin-medium', + intro: "Hi there! I'm Mary, your Business Analyst. I'll help uncover the real requirements.", + }, + architect: { + voice: 'en_GB-alan-medium', + intro: "Hello! Winston here, your Architect. I'll ensure we build something scalable and pragmatic.", + }, + dev: { + voice: 'en_US-joe-medium', + intro: 'Hey! Amelia here, your Developer. Ready to turn specs into working code.', + }, + pm: { + voice: 'en_US-ryan-high', + intro: "Hey team! John here, your Product Manager. Let's make sure we're building the right thing.", + }, + sm: { + voice: 'en_US-amy-medium', + intro: "Hi everyone! Bob here, your Scrum Master. I'll keep us focused and moving forward.", + }, + tea: { + voice: 'en_US-kusal-medium', + intro: 'Hello! Murat here, your Test Architect. Quality is my obsession.', + }, + 'tech-writer': { + voice: 'jenny', + intro: "Hi! I'm Paige, your Technical Writer. I'll make sure everything is documented clearly.", + }, + 'ux-designer': { + voice: 'kristin', + intro: 'Hey! Sally here, your UX Designer. The user experience is my top priority.', + }, + 'frame-expert': { + voice: 'en_GB-alan-medium', + intro: "Hello! Saif here, your Visual Design Expert. I'll help visualize your ideas.", + }, + }; + + // Fallback values for agents not in the default map + const fallbackVoice = 'en_US-lessac-medium'; + const fallbackIntro = 'Hello! Ready to help with the discussion.'; + + let csv = 'agent,voice,intro\n'; + + // Add voice mapping and intro for each discovered agent + for (const agent of this.agents) { + const defaults = agentDefaults[agent.name] || {}; + const voice = defaults.voice || fallbackVoice; + const intro = defaults.intro || fallbackIntro; + // Escape quotes in intro for CSV + const escapedIntro = intro.replaceAll('"', '""'); + csv += `${agent.name},${voice},"${escapedIntro}"\n`; + } + + await fs.writeFile(csvPath, csv); + return csvPath; + } + /** * Write task manifest CSV * @returns {string} Path to the manifest file From 6d5d32a633371838343bc8f415edce89269fc614 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 14:28:32 -0700 Subject: [PATCH 5/5] fix: Always run AgentVibes installer when enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, BMAD would skip the AgentVibes installer if it detected existing hook files (.claude/hooks/bmad-speak.sh and play-tts.sh). This prevented users from getting AgentVibes updates. Now when user says "Yes" to AgentVibes, it always runs the installer, ensuring users get the latest version with new features and fixes. šŸ¤– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- tools/cli/installers/lib/core/installer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 4438d9f2..99e3497f 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -1041,7 +1041,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: path: bmadDir, modules: config.modules, ides: config.ides, - needsAgentVibes: this.enableAgentVibes && !config.agentVibesInstalled, + needsAgentVibes: this.enableAgentVibes, // Always run installer if enabled - handles updates too projectDir: projectDir, }; } catch (error) {