Compare commits

...

3 Commits

Author SHA1 Message Date
Paul Preibisch eadea94ff8
Merge 6d5d32a633 into 355ccebca2 2025-11-27 21:29:34 +00:00
Paul Preibisch 6d5d32a633 fix: Always run AgentVibes installer when enabled
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 <noreply@anthropic.com>
2025-11-27 14:28:32 -07:00
Paul Preibisch e3f87e07c1 feat: Add voice map generation with agent intros for party mode
- 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 <noreply@anthropic.com>
2025-11-27 11:00:01 -07:00
3 changed files with 104 additions and 7 deletions

View File

@ -7,7 +7,7 @@
<workflow> <workflow>
<step n="1" goal="Load Agent Manifest and Configurations"> <step n="1" goal="Load Agent Manifest and Voice Map">
<action>Load the agent manifest CSV from {{agent_manifest}}</action> <action>Load the agent manifest CSV from {{agent_manifest}}</action>
<action>Parse CSV to extract all agent entries with their condensed information:</action> <action>Parse CSV to extract all agent entries with their condensed information:</action>
- name (agent identifier) - name (agent identifier)
@ -21,7 +21,10 @@
- module (source module) - module (source module)
- path (file location) - path (file location)
<action>Build complete agent roster with merged personalities</action> <action>Load the agent voice map CSV from {project-root}/{bmad_folder}/\_cfg/agent-voice-map.csv</action>
<action>Parse voice map to get each agent's voice and intro message:</action> - agent (agent identifier, matches name from manifest) - voice (Piper TTS voice name) - intro (introduction message for greetings)
<action>Build complete agent roster with merged personalities and voice data</action>
<action>Store agent data for use in conversation orchestration</action> <action>Store agent data for use in conversation orchestration</action>
</step> </step>
@ -34,12 +37,31 @@
Participating agents: Participating agents:
[For each agent in roster:] [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! [Total count] agents ready to collaborate!
What would you like to discuss with the team? </format>
<action>Have 3-4 agents introduce themselves using their intro from the voice map:</action>
<procedure>
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]"`
</procedure>
<example>
🧙 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."]
</example>
<action>After intros, ask what the team can help with:</action>
<format>
What would you like to discuss with the team?
</format> </format>
<action>Wait for user to provide initial topic or question</action> <action>Wait for user to provide initial topic or question</action>
</step> </step>

View File

@ -1041,7 +1041,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
path: bmadDir, path: bmadDir,
modules: config.modules, modules: config.modules,
ides: config.ides, ides: config.ides,
needsAgentVibes: this.enableAgentVibes && !config.agentVibesInstalled, needsAgentVibes: this.enableAgentVibes, // Always run installer if enabled - handles updates too
projectDir: projectDir, projectDir: projectDir,
}; };
} catch (error) { } catch (error) {

View File

@ -74,6 +74,7 @@ class ManifestGenerator {
await this.writeMainManifest(cfgDir), await this.writeMainManifest(cfgDir),
await this.writeWorkflowManifest(cfgDir), await this.writeWorkflowManifest(cfgDir),
await this.writeAgentManifest(cfgDir), await this.writeAgentManifest(cfgDir),
await this.writeVoiceMap(cfgDir),
await this.writeTaskManifest(cfgDir), await this.writeTaskManifest(cfgDir),
await this.writeToolManifest(cfgDir), await this.writeToolManifest(cfgDir),
await this.writeFilesManifest(cfgDir), await this.writeFilesManifest(cfgDir),
@ -576,6 +577,80 @@ class ManifestGenerator {
return csvPath; 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 * Write task manifest CSV
* @returns {string} Path to the manifest file * @returns {string} Path to the manifest file