From e3f87e07c1b356bfd44c1c556c19c0c95fec6c33 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Thu, 27 Nov 2025 11:00:01 -0700 Subject: [PATCH] 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