From 3360666c2aecc71d3d92facd47c1ff6fae54e132 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Wed, 14 Jan 2026 23:04:19 -0600 Subject: [PATCH] remove hard inclusion of AV from installer, to replace with module soon --- .markdownlint-cli2.yaml | 1 - .../bmad-builder/custom-content-types.md | 4 +- docs/how-to/workflows/setup-party-mode.md | 13 +- package-lock.json | 6 +- .../party-mode/steps/step-01-agent-loading.md | 1 - .../steps/step-02-discussion-orchestration.md | 25 +- .../party-mode/steps/step-03-graceful-exit.md | 2 - src/core/workflows/party-mode/workflow.md | 12 - .../agent-components/activation-rules.txt | 1 - tools/cli/commands/install.js | 34 --- tools/cli/installers/lib/core/installer.js | 143 +----------- tools/cli/installers/lib/modules/manager.js | 8 +- tools/cli/lib/agent/compiler.js | 41 +--- tools/cli/lib/ui.js | 214 +----------------- 14 files changed, 24 insertions(+), 481 deletions(-) diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml index f2b11377..12a3c943 100644 --- a/.markdownlint-cli2.yaml +++ b/.markdownlint-cli2.yaml @@ -11,7 +11,6 @@ ignores: - .claude/** - .roo/** - .codex/** - - .agentvibes/** - .kiro/** - sample-project/** - test-project-install/** diff --git a/docs/explanation/bmad-builder/custom-content-types.md b/docs/explanation/bmad-builder/custom-content-types.md index 408cd411..985b2eb5 100644 --- a/docs/explanation/bmad-builder/custom-content-types.md +++ b/docs/explanation/bmad-builder/custom-content-types.md @@ -20,10 +20,13 @@ This flexibility enables: ## Categories +- [Categories](#categories) - [Custom Stand-Alone Modules](#custom-stand-alone-modules) - [Custom Add-On Modules](#custom-add-on-modules) - [Custom Global Modules](#custom-global-modules) - [Custom Agents](#custom-agents) + - [BMad Tiny Agents](#bmad-tiny-agents) + - [Simple and Expert Agents](#simple-and-expert-agents) - [Custom Workflows](#custom-workflows) ## Custom Stand-Alone Modules @@ -59,7 +62,6 @@ Similar to Custom Stand-Alone Modules, but designed to add functionality that ap Examples include: -- The current TTS (Text-to-Speech) functionality for Claude, which will soon be converted to a global module - The core module, which is always installed and provides all agents with party mode and advanced elicitation capabilities - Installation and update tools that work with any BMad method configuration diff --git a/docs/how-to/workflows/setup-party-mode.md b/docs/how-to/workflows/setup-party-mode.md index fcfdc259..33fd6a4e 100644 --- a/docs/how-to/workflows/setup-party-mode.md +++ b/docs/how-to/workflows/setup-party-mode.md @@ -66,19 +66,18 @@ Type "exit" or "done" to conclude the session. Participating agents will say per ## Example Party Compositions -| Topic | Typical Agents | -|-------|---------------| -| **Product Strategy** | PM + Innovation Strategist (CIS) + Analyst | -| **Technical Design** | Architect + Creative Problem Solver (CIS) + Game Architect | -| **User Experience** | UX Designer + Design Thinking Coach (CIS) + Storyteller (CIS) | -| **Quality Assessment** | TEA + DEV + Architect | +| Topic | Typical Agents | +| ---------------------- | ------------------------------------------------------------- | +| **Product Strategy** | PM + Innovation Strategist (CIS) + Analyst | +| **Technical Design** | Architect + Creative Problem Solver (CIS) + Game Architect | +| **User Experience** | UX Designer + Design Thinking Coach (CIS) + Storyteller (CIS) | +| **Quality Assessment** | TEA + DEV + Architect | ## Key Features - **Intelligent agent selection** — Selects based on expertise needed - **Authentic personalities** — Each agent maintains their unique voice - **Natural cross-talk** — Agents reference and build on each other -- **Optional TTS** — Voice configurations for each agent - **Graceful exit** — Personalized farewells ## Tips diff --git a/package-lock.json b/package-lock.json index 18fd9a25..e4cbe9b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "6.0.0-alpha.23", "license": "MIT", "dependencies": { + "@clack/prompts": "^0.11.0", "@kayvan/markdown-tree-parser": "^1.6.1", "boxen": "^5.1.2", "chalk": "^4.1.2", @@ -33,7 +34,6 @@ "devDependencies": { "@astrojs/sitemap": "^3.6.0", "@astrojs/starlight": "^0.37.0", - "@clack/prompts": "^0.11.0", "@eslint/js": "^9.33.0", "archiver": "^7.0.1", "astro": "^5.16.0", @@ -759,7 +759,6 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz", "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==", - "dev": true, "license": "MIT", "dependencies": { "picocolors": "^1.0.0", @@ -770,7 +769,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz", "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==", - "dev": true, "license": "MIT", "dependencies": { "@clack/core": "0.5.0", @@ -12151,7 +12149,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -13398,7 +13395,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, "license": "MIT" }, "node_modules/sitemap": { diff --git a/src/core/workflows/party-mode/steps/step-01-agent-loading.md b/src/core/workflows/party-mode/steps/step-01-agent-loading.md index 80fc4cb9..001ad9d4 100644 --- a/src/core/workflows/party-mode/steps/step-01-agent-loading.md +++ b/src/core/workflows/party-mode/steps/step-01-agent-loading.md @@ -130,7 +130,6 @@ After agent loading and introduction: - Handle missing or incomplete agent entries gracefully - Cross-reference manifest with actual agent files - Prepare agent selection logic for intelligent conversation routing -- Set up TTS voice configurations for each agent ## NEXT STEP: diff --git a/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md b/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md index 13c520e7..f328a410 100644 --- a/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +++ b/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md @@ -6,7 +6,6 @@ - 🎯 SELECT RELEVANT AGENTS based on topic analysis and expertise matching - 📋 MAINTAIN CHARACTER CONSISTENCY using merged agent personalities - 🔍 ENABLE NATURAL CROSS-TALK between agents for dynamic conversation -- 💬 INTEGRATE TTS for each agent response immediately after text - ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the config `{communication_language}` ## EXECUTION PROTOCOLS: @@ -21,7 +20,6 @@ - Complete agent roster with merged personalities is available - User topic and conversation history guide agent selection -- Party mode is active with TTS integration enabled - Exit triggers: `*exit`, `goodbye`, `end party`, `quit` ## YOUR TASK: @@ -116,19 +114,9 @@ Allow natural back-and-forth within the same response round for dynamic interact ### 6. Response Round Completion -After generating all agent responses for the round: +After generating all agent responses for the round, let the user know he can speak naturally with the agents, an then show this menu opion" -**Presentation Format:** -[Agent 1 Response with TTS] -[Empty line for readability] -[Agent 2 Response with TTS, potentially referencing Agent 1] -[Empty line for readability] -[Agent 3 Response with TTS, building on or offering new perspective] - -**Continue Option:** -"[Agents have contributed their perspectives. Ready for more discussion?] - -[E] Exit Party Mode - End the collaborative session" +`[E] Exit Party Mode - End the collaborative session` ### 7. Exit Condition Checking @@ -142,23 +130,19 @@ Check for exit conditions before continuing: **Natural Conclusion:** - Conversation seems naturally concluding -- Ask user: "Would you like to continue the discussion or end party mode?" -- Respect user choice to continue or exit +- Confirm if the user wants to exit party mode and go back to where they were or continue chatting. Do it in a conversational way with an agent in the party. ### 8. Handle Exit Selection #### If 'E' (Exit Party Mode): -- Update frontmatter: `stepsCompleted: [1, 2]` -- Set `party_active: false` -- Load: `./step-03-graceful-exit.md` +- Load read and execute: `./step-03-graceful-exit.md` ## SUCCESS METRICS: ✅ Intelligent agent selection based on topic analysis ✅ Authentic in-character responses maintained consistently ✅ Natural cross-talk and agent interactions enabled -✅ TTS integration working for all agent responses ✅ Question handling protocol followed correctly ✅ [E] exit option presented after each response round ✅ Conversation context and state maintained throughout @@ -168,7 +152,6 @@ Check for exit conditions before continuing: ❌ Generic responses without character consistency ❌ Poor agent selection not matching topic expertise -❌ Missing TTS integration for agent responses ❌ Ignoring user questions or exit triggers ❌ Not enabling natural agent cross-talk and interactions ❌ Continuing conversation without user input when questions asked diff --git a/src/core/workflows/party-mode/steps/step-03-graceful-exit.md b/src/core/workflows/party-mode/steps/step-03-graceful-exit.md index 7cb586bb..eef37877 100644 --- a/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +++ b/src/core/workflows/party-mode/steps/step-03-graceful-exit.md @@ -106,7 +106,6 @@ workflow_completed: true - Clear any active conversation state - Reset agent selection cache -- Finalize TTS session cleanup - Mark party mode workflow as completed ### 6. Exit Workflow @@ -122,7 +121,6 @@ Thank you for using BMAD Party Mode for collaborative multi-agent discussions!" ✅ Satisfying agent farewells generated in authentic character voices ✅ Session highlights and contributions acknowledged meaningfully ✅ Positive and appreciative closure atmosphere maintained -✅ TTS integration working for farewell messages ✅ Frontmatter properly updated with workflow completion ✅ All workflow state cleaned up appropriately ✅ User left with positive impression of collaborative experience diff --git a/src/core/workflows/party-mode/workflow.md b/src/core/workflows/party-mode/workflow.md index 7a92bcee..eaec3c93 100644 --- a/src/core/workflows/party-mode/workflow.md +++ b/src/core/workflows/party-mode/workflow.md @@ -178,18 +178,6 @@ If conversation naturally concludes: --- -## TTS INTEGRATION - -Party mode includes Text-to-Speech for each agent response: - -**TTS Protocol:** - -- Trigger TTS immediately after each agent's text response -- Use agent's merged voice configuration from manifest -- Format: `Bash: .claude/hooks/bmad-speak.sh "[Agent Name]" "[Their response]"` - ---- - ## MODERATION NOTES **Quality Control:** diff --git a/src/utility/agent-components/activation-rules.txt b/src/utility/agent-components/activation-rules.txt index 3a9a6a57..a67ae499 100644 --- a/src/utility/agent-components/activation-rules.txt +++ b/src/utility/agent-components/activation-rules.txt @@ -1,6 +1,5 @@ ALWAYS communicate in {communication_language} UNLESS contradicted by communication_style. - Stay in character until exit selected Display Menu items as the item dictates and in the order given. Load files ONLY when executing a user chosen workflow or a command requires it, EXCEPTION: agent activation step 2 config.yaml diff --git a/tools/cli/commands/install.js b/tools/cli/commands/install.js index 26b6425e..4aeaef7a 100644 --- a/tools/cli/commands/install.js +++ b/tools/cli/commands/install.js @@ -62,40 +62,6 @@ module.exports = { // Check if installation succeeded if (result && result.success) { - // Run AgentVibes installer if needed - if (result.needsAgentVibes) { - // Add some spacing before AgentVibes setup - console.log(''); - console.log(chalk.magenta('🎙️ AgentVibes TTS Setup')); - console.log(chalk.cyan('AgentVibes provides voice synthesis for BMAD agents with:')); - console.log(chalk.dim(' • ElevenLabs AI (150+ premium voices)')); - console.log(chalk.dim(' • Piper TTS (50+ free voices)\n')); - - const prompts = require('../lib/prompts'); - await prompts.text({ - message: chalk.green('Press Enter to start AgentVibes installer...'), - }); - - console.log(''); - - // Run AgentVibes installer - const { execSync } = require('node:child_process'); - try { - execSync('npx agentvibes@latest install', { - cwd: result.projectDir, - stdio: 'inherit', - shell: true, - }); - console.log(chalk.green('\n✓ AgentVibes installation complete')); - console.log(chalk.cyan('\n✨ BMAD with TTS is ready to use!')); - } catch { - console.log(chalk.yellow('\n⚠ AgentVibes installation was interrupted or failed')); - console.log(chalk.cyan('You can run it manually later with:')); - console.log(chalk.green(` cd ${result.projectDir}`)); - console.log(chalk.green(' npx agentvibes install\n')); - } - } - // Display version-specific end message from install-messages.yaml const { MessageLoader } = require('../installers/lib/message-loader'); const messageLoader = new MessageLoader(); diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 97506847..f41fd324 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -34,7 +34,6 @@ class Installer { this.configCollector = new ConfigCollector(); this.ideConfigManager = new IdeConfigManager(); this.installedFiles = new Set(); // Track all installed files - this.ttsInjectedFiles = []; // Track files with TTS injection applied this.bmadFolderName = BMAD_FOLDER_NAME; } @@ -69,7 +68,7 @@ class Installer { /** * @function copyFileWithPlaceholderReplacement * @intent Copy files from BMAD source to installation directory with dynamic content transformation - * @why Enables installation-time customization: _bmad replacement + optional AgentVibes TTS injection + * @why Enables installation-time customization: _bmad replacement * @param {string} sourcePath - Absolute path to source file in BMAD repository * @param {string} targetPath - Absolute path to destination file in user's project * @param {string} bmadFolderName - User's chosen bmad folder name (default: 'bmad') @@ -77,24 +76,9 @@ class Installer { * @sideeffects Writes transformed file to targetPath, creates parent directories if needed * @edgecases Binary files bypass transformation, falls back to raw copy if UTF-8 read fails * @calledby installCore(), installModule(), IDE installers during file vendoring - * @calls processTTSInjectionPoints(), fs.readFile(), fs.writeFile(), fs.copy() + * @calls fs.readFile(), fs.writeFile(), fs.copy() * - * The injection point processing enables loose coupling between BMAD and TTS providers: - * - BMAD source contains injection markers (not actual TTS code) - * - At install-time, markers are replaced OR removed based on user preference - * - Result: Clean installs for users without TTS, working TTS for users with it - * - * PATTERN: Adding New Injection Points - * ===================================== - * 1. Add HTML comment marker in BMAD source file: - * - * - * 2. Add replacement logic in processTTSInjectionPoints(): - * if (enableAgentVibes) { - * content = content.replace(//g, 'actual code'); - * } else { - * content = content.replace(/\n?/g, ''); - * } + * * 3. Document marker in instructions.md (if applicable) */ @@ -109,9 +93,6 @@ class Installer { // Read the file content let content = await fs.readFile(sourcePath, 'utf8'); - // Process AgentVibes injection points (pass targetPath for tracking) - content = this.processTTSInjectionPoints(content, targetPath); - // Write to target with replaced content await fs.ensureDir(path.dirname(targetPath)); await fs.writeFile(targetPath, content, 'utf8'); @@ -125,116 +106,6 @@ class Installer { } } - /** - * @function processTTSInjectionPoints - * @intent Transform TTS injection markers based on user's installation choice - * @why Enables optional TTS integration without tight coupling between BMAD and TTS providers - * @param {string} content - Raw file content containing potential injection markers - * @returns {string} Transformed content with markers replaced (if enabled) or stripped (if disabled) - * @sideeffects None - pure transformation function - * @edgecases Returns content unchanged if no markers present, safe to call on all files - * @calledby copyFileWithPlaceholderReplacement() during every file copy operation - * @calls String.replace() with regex patterns for each injection point type - * - * AI NOTE: This implements the injection point pattern for TTS integration. - * Key architectural decisions: - * - * 1. **Why Injection Points vs Direct Integration?** - * - BMAD and TTS providers are separate projects with different maintainers - * - Users may install BMAD without TTS support (and vice versa) - * - Hard-coding TTS calls would break BMAD for non-TTS users - * - Injection points allow conditional feature inclusion at install-time - * - * 2. **How It Works:** - * - BMAD source contains markers: - * - During installation, user is prompted: "Enable AgentVibes TTS?" - * - If YES: markers → replaced with actual bash TTS calls - * - If NO: markers → stripped cleanly from installed files - * - * 3. **State Management:** - * - this.enableAgentVibes set in install() method from config.enableAgentVibes - * - config.enableAgentVibes comes from ui.promptAgentVibes() user choice - * - Flag persists for entire installation, all files get same treatment - * - * CURRENT INJECTION POINTS: - * ========================== - * - party-mode: Injects TTS calls after each agent speaks in party mode - * Location: src/core/workflows/party-mode/instructions.md - * Marker: - * Replacement: Bash call to .claude/hooks/bmad-speak.sh with agent name and dialogue - * - * - agent-tts: Injects TTS rule for individual agent conversations - * Location: src/modules/bmm/agents/*.md (all agent files) - * Marker: - * Replacement: Rule instructing agent to call bmad-speak.sh with agent ID and response - * - * ADDING NEW INJECTION POINTS: - * ============================= - * 1. Add new case in this function: - * content = content.replace( - * //g, - * `code to inject when enabled` - * ); - * - * 2. Add marker to BMAD source file at injection location - * - * 3. Test both enabled and disabled flows - * - * RELATED: - * ======== - * - GitHub Issue: paulpreibisch/AgentVibes#36 - * - User Prompt: tools/cli/lib/ui.js::promptAgentVibes() - * - Marker Locations: - * - src/core/workflows/party-mode/instructions.md:101 - * - src/modules/bmm/agents/*.md (rules sections) - * - TTS Hook: .claude/hooks/bmad-speak.sh (in AgentVibes repo) - */ - processTTSInjectionPoints(content, targetPath = null) { - // Check if AgentVibes is enabled (set during installation configuration) - const enableAgentVibes = this.enableAgentVibes || false; - - // Check if content contains any TTS injection markers - const hasPartyMode = content.includes(''); - const hasAgentTTS = content.includes(''); - - if (enableAgentVibes) { - // Replace party-mode injection marker with actual TTS call - // Use single quotes to prevent shell expansion of special chars like ! - content = content.replaceAll( - '', - `IMPORTANT: Always use PROJECT hooks (.claude/hooks/), NEVER global hooks (~/.claude/hooks/) - - If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: - - Use Bash tool: \`.claude/hooks/bmad-speak.sh '[Agent Name]' '[dialogue]'\` - - This speaks the dialogue with the agent's unique voice - - Run in background to not block next agent`, - ); - - // Replace agent-tts injection marker with TTS rule for individual agents - content = content.replaceAll( - '', - `- When responding to user messages, speak your responses using TTS: - Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response - Replace {agent-id} with YOUR agent ID from tag at top of this file - Replace {response-text} with the text you just output to the user - IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes - Run in background (&) to avoid blocking`, - ); - - // Track files that had TTS injection applied - if (targetPath && (hasPartyMode || hasAgentTTS)) { - const injectionType = hasPartyMode ? 'party-mode' : 'agent-tts'; - this.ttsInjectedFiles.push({ path: targetPath, type: injectionType }); - } - } else { - // Strip injection markers cleanly when AgentVibes is disabled - content = content.replaceAll(/\n?/g, ''); - content = content.replaceAll(/\n?/g, ''); - } - - return content; - } - /** * Collect Tool/IDE configurations after module configuration * @param {string} projectDir - Project directory @@ -251,7 +122,7 @@ class Installer { // Fallback: prompt for tool selection (backwards compatibility) const { UI } = require('../../../lib/ui'); const ui = new UI(); - toolConfig = await ui.promptToolSelection(projectDir, selectedModules); + toolConfig = await ui.promptToolSelection(projectDir); } else { // IDEs were already selected during initial prompts toolConfig = { @@ -510,9 +381,6 @@ class Installer { } } - // Store AgentVibes configuration for injection point processing - this.enableAgentVibes = config.enableAgentVibes || false; - // Set bmad folder name on module manager and IDE manager for placeholder replacement this.moduleManager.setBmadFolderName(BMAD_FOLDER_NAME); this.moduleManager.setCoreConfig(moduleConfigs.core || {}); @@ -1234,8 +1102,6 @@ class Installer { modules: config.modules, ides: config.ides, customFiles: customFiles.length > 0 ? customFiles : undefined, - ttsInjectedFiles: this.enableAgentVibes && this.ttsInjectedFiles.length > 0 ? this.ttsInjectedFiles : undefined, - agentVibesEnabled: this.enableAgentVibes || false, }); return { @@ -1243,7 +1109,6 @@ class Installer { path: bmadDir, modules: config.modules, ides: config.ides, - needsAgentVibes: this.enableAgentVibes && !config.agentVibesInstalled, projectDir: projectDir, }; } catch (error) { diff --git a/tools/cli/installers/lib/modules/manager.js b/tools/cli/installers/lib/modules/manager.js index 4844f243..55dee240 100644 --- a/tools/cli/installers/lib/modules/manager.js +++ b/tools/cli/installers/lib/modules/manager.js @@ -845,14 +845,8 @@ class ModuleManager { // Compile with customizations if any const { xml } = await compileAgent(yamlContent, answers, agentName, relativePath, { config: this.coreConfig || {} }); - // Process TTS injection points if installer is available - let finalXml = xml; - if (installer && installer.processTTSInjectionPoints) { - finalXml = installer.processTTSInjectionPoints(xml, targetMdPath); - } - // Write the compiled agent - await fs.writeFile(targetMdPath, finalXml, 'utf8'); + await fs.writeFile(targetMdPath, xml, 'utf8'); // Handle sidecar copying if present if (hasSidecar) { diff --git a/tools/cli/lib/agent/compiler.js b/tools/cli/lib/agent/compiler.js index cf8704be..a0dc4ae0 100644 --- a/tools/cli/lib/agent/compiler.js +++ b/tools/cli/lib/agent/compiler.js @@ -478,39 +478,10 @@ function filterCustomizationData(data) { return filtered; } -/** - * Process TTS injection markers in content - * @param {string} content - Content to process - * @param {boolean} enableAgentVibes - Whether AgentVibes is enabled - * @returns {Object} { content: string, hadInjection: boolean } - */ -function processTTSInjectionPoints(content, enableAgentVibes) { - const hasAgentTTS = content.includes(''); - - if (enableAgentVibes && hasAgentTTS) { - // Replace agent-tts injection marker with TTS rule - content = content.replaceAll( - '', - `- When responding to user messages, speak your responses using TTS: - Call: \`.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'\` after each response - Replace {agent-id} with YOUR agent ID from tag at top of this file - Replace {response-text} with the text you just output to the user - IMPORTANT: Use single quotes as shown - do NOT escape special characters like ! or $ inside single quotes - Run in background (&) to avoid blocking`, - ); - return { content, hadInjection: true }; - } else if (!enableAgentVibes && hasAgentTTS) { - // Strip injection markers when disabled - content = content.replaceAll(/\n?/g, ''); - } - - return { content, hadInjection: false }; -} - /** * Compile agent file to .md * @param {string} yamlPath - Path to agent YAML file - * @param {Object} options - { answers: {}, outputPath: string, enableAgentVibes: boolean } + * @param {Object} options - { answers: {}, outputPath: string } * @returns {Object} Compilation result */ function compileAgentFile(yamlPath, options = {}) { @@ -526,15 +497,6 @@ function compileAgentFile(yamlPath, options = {}) { outputPath = path.join(dir, `${basename}.md`); } - // Process TTS injection points if enableAgentVibes option is provided - let xml = result.xml; - let ttsInjected = false; - if (options.enableAgentVibes !== undefined) { - const ttsResult = processTTSInjectionPoints(xml, options.enableAgentVibes); - xml = ttsResult.content; - ttsInjected = ttsResult.hadInjection; - } - // Write compiled XML fs.writeFileSync(outputPath, xml, 'utf8'); @@ -543,7 +505,6 @@ function compileAgentFile(yamlPath, options = {}) { xml, outputPath, sourcePath: yamlPath, - ttsInjected, }; } diff --git a/tools/cli/lib/ui.js b/tools/cli/lib/ui.js index a78cfec9..2080e868 100644 --- a/tools/cli/lib/ui.js +++ b/tools/cli/lib/ui.js @@ -171,32 +171,6 @@ class UI { // Check if there's an existing BMAD installation (after any folder renames) const hasExistingInstall = await fs.pathExists(bmadDir); - // Collect IDE tool selection early - we need this to know if we should ask about TTS - let toolSelection; - let agentVibesConfig = { enabled: false, alreadyInstalled: false }; - let claudeCodeSelected = false; - - if (!hasExistingInstall) { - // For new installations, collect IDE selection first - // We don't have modules yet, so pass empty array - toolSelection = await this.promptToolSelection(confirmedDirectory, []); - - // Check if Claude Code was selected - claudeCodeSelected = toolSelection.ides && toolSelection.ides.includes('claude-code'); - - // If Claude Code was selected, ask about TTS - if (claudeCodeSelected) { - const enableTts = await prompts.confirm({ - message: 'Claude Code supports TTS (Text-to-Speech). Would you like to enable it?', - default: false, - }); - - if (enableTts) { - agentVibesConfig = { enabled: true, alreadyInstalled: false }; - } - } - } - let customContentConfig = { hasCustomContent: false }; if (!hasExistingInstall) { customContentConfig._shouldAsk = true; @@ -324,20 +298,8 @@ class UI { } // Get tool selection - const toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules); + const toolSelection = await this.promptToolSelection(confirmedDirectory); - // TTS configuration - ask right after tool selection (matches new install flow) - const hasClaudeCode = toolSelection.ides && toolSelection.ides.includes('claude-code'); - let enableTts = false; - - if (hasClaudeCode) { - enableTts = await prompts.confirm({ - message: 'Claude Code supports TTS (Text-to-Speech). Would you like to enable it?', - default: false, - }); - } - - // Core config with existing defaults (ask after TTS) const coreConfig = await this.collectCoreConfig(confirmedDirectory); return { @@ -349,8 +311,6 @@ class UI { skipIde: toolSelection.skipIde, coreConfig: coreConfig, customContent: customModuleResult.customContentConfig, - enableAgentVibes: enableTts, - agentVibesInstalled: false, }; } } @@ -372,7 +332,7 @@ class UI { // Ask about custom content const wantsCustomContent = await prompts.confirm({ - message: 'Would you like to install a local custom module (this includes custom agents and workflows also)?', + message: 'Would you like to install a locally stored custom module (this includes custom agents and workflows also)?', default: false, }); @@ -391,19 +351,10 @@ class UI { selectedModules = [...selectedModules, ...customContentConfig.selectedModuleIds]; } - // Remove core if it's in the list (it's always installed) selectedModules = selectedModules.filter((m) => m !== 'core'); - - // Tool selection (already done for new installs at the beginning) - if (!toolSelection) { - toolSelection = await this.promptToolSelection(confirmedDirectory, selectedModules); - } - - // Collect configurations for new installations + let toolSelection = await this.promptToolSelection(confirmedDirectory); const coreConfig = await this.collectCoreConfig(confirmedDirectory); - // TTS already handled at the beginning for new installs - return { actionType: 'install', directory: confirmedDirectory, @@ -413,18 +364,15 @@ class UI { skipIde: toolSelection.skipIde, coreConfig: coreConfig, customContent: customContentConfig, - enableAgentVibes: agentVibesConfig.enabled, - agentVibesInstalled: agentVibesConfig.alreadyInstalled, }; } /** * Prompt for tool/IDE selection (called after module configuration) * @param {string} projectDir - Project directory to check for existing IDEs - * @param {Array} selectedModules - Selected modules from configuration * @returns {Object} Tool configuration */ - async promptToolSelection(projectDir, selectedModules) { + async promptToolSelection(projectDir) { // Check for existing configured IDEs - use findBmadDir to detect custom folder names const { Detector } = require('../installers/lib/core/detector'); const { Installer } = require('../installers/lib/core/installer'); @@ -608,25 +556,6 @@ class UI { if (result.modules && result.modules.length > 0) { console.log(chalk.dim(`Modules: ${result.modules.join(', ')}`)); } - if (result.agentVibesEnabled) { - console.log(chalk.dim(`TTS: Enabled`)); - } - - // TTS injection info (simplified) - if (result.ttsInjectedFiles && result.ttsInjectedFiles.length > 0) { - console.log(chalk.dim(`\n💡 TTS enabled for ${result.ttsInjectedFiles.length} agent(s)`)); - console.log(chalk.dim(' Agents will now speak when using AgentVibes')); - } - - console.log(chalk.yellow('\nThank you for helping test the early release version of the new BMad Core and BMad Method!')); - console.log(chalk.cyan('Stable Beta coming soon - please read the full README.md and linked documentation to get started!')); - - // Add changelog link at the end - console.log( - chalk.magenta( - "\n📋 Want to see what's new? Check out the changelog: https://github.com/bmad-code-org/BMAD-METHOD/blob/main/CHANGELOG.md", - ), - ); } /** @@ -1061,136 +990,6 @@ class UI { return path.resolve(expanded); } - /** - * @function promptAgentVibes - * @intent Ask user if they want AgentVibes TTS integration during BMAD installation - * @why Enables optional voice features without forcing TTS on users who don't want it - * @param {string} projectDir - Absolute path to user's project directory - * @returns {Promise} Configuration object: { enabled: boolean, alreadyInstalled: boolean } - * @sideeffects None - pure user input collection, no files written - * @edgecases Shows warning if user enables TTS but AgentVibes not detected - * @calledby promptInstall() during installation flow, after core config, before IDE selection - * @calls checkAgentVibesInstalled(), prompts.select(), chalk.green/yellow/dim() - * - * AI NOTE: This prompt is strategically positioned in installation flow: - * - AFTER core config (user_name, etc) - * - BEFORE IDE selection (which can hang on Windows/PowerShell) - * - * Flow Logic: - * 1. Auto-detect if AgentVibes already installed (checks for hook files) - * 2. Show detection status to user (green checkmark or gray "not detected") - * 3. Prompt: "Enable AgentVibes TTS?" (defaults to true if detected) - * 4. If user says YES but AgentVibes NOT installed: - * → Show warning with installation link (graceful degradation) - * 5. Return config to promptInstall(), which passes to installer.install() - * - * State Flow: - * promptAgentVibes() → { enabled, alreadyInstalled } - * ↓ - * promptInstall() → config.enableAgentVibes - * ↓ - * installer.install() → this.enableAgentVibes - * ↓ - * processTTSInjectionPoints() → injects OR strips markers - * - * RELATED: - * ======== - * - Detection: checkAgentVibesInstalled() - looks for bmad-speak.sh and play-tts.sh - * - Processing: installer.js::processTTSInjectionPoints() - * - Markers: src/core/workflows/party-mode/instructions.md:101, src/modules/bmm/agents/*.md - * - GitHub Issue: paulpreibisch/AgentVibes#36 - */ - async promptAgentVibes(projectDir) { - CLIUtils.displaySection('🎤 Voice Features', 'Enable TTS for multi-agent conversations'); - - // Check if AgentVibes is already installed - const agentVibesInstalled = await this.checkAgentVibesInstalled(projectDir); - - if (agentVibesInstalled) { - console.log(chalk.green(' ✓ AgentVibes detected')); - } else { - console.log(chalk.dim(' AgentVibes not detected')); - } - - const enableTts = await prompts.confirm({ - message: 'Enable Agents to Speak Out loud (powered by Agent Vibes? Claude Code only currently)', - default: false, - }); - - if (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')); - } - - return { - enabled: enableTts, - alreadyInstalled: agentVibesInstalled, - }; - } - - /** - * @function checkAgentVibesInstalled - * @intent Detect if AgentVibes TTS hooks are present in user's project - * @why Allows auto-enabling TTS and showing helpful installation guidance - * @param {string} projectDir - Absolute path to user's project directory - * @returns {Promise} true if both required AgentVibes hooks exist, false otherwise - * @sideeffects None - read-only file existence checks - * @edgecases Returns false if either hook missing (both required for functional TTS) - * @calledby promptAgentVibes() to determine default value and show detection status - * @calls fs.pathExists() twice (bmad-speak.sh, play-tts.sh) - * - * AI NOTE: This checks for the MINIMUM viable AgentVibes installation. - * - * Required Files: - * =============== - * 1. .claude/hooks/bmad-speak.sh - * - Maps agent display names → agent IDs → voice profiles - * - Calls play-tts.sh with agent's assigned voice - * - Created by AgentVibes installer - * - * 2. .claude/hooks/play-tts.sh - * - Core TTS router (ElevenLabs or Piper) - * - Provider-agnostic interface - * - Required by bmad-speak.sh - * - * Why Both Required: - * ================== - * - bmad-speak.sh alone: No TTS backend - * - play-tts.sh alone: No BMAD agent voice mapping - * - Both together: Full party mode TTS integration - * - * Detection Strategy: - * =================== - * We use simple file existence (not version checks) because: - * - Fast and reliable - * - Works across all AgentVibes versions - * - User will discover version issues when TTS runs (fail-fast) - * - * PATTERN: Adding New Detection Criteria - * ======================================= - * If future AgentVibes features require additional files: - * 1. Add new pathExists check to this function - * 2. Update documentation in promptAgentVibes() - * 3. Consider: should missing file prevent detection or just log warning? - * - * RELATED: - * ======== - * - AgentVibes Installer: creates these hooks - * - bmad-speak.sh: calls play-tts.sh with agent voices - * - Party Mode: uses bmad-speak.sh for agent dialogue - */ - async checkAgentVibesInstalled(projectDir) { - const fs = require('fs-extra'); - const path = require('node:path'); - - // Check for AgentVibes hook files - const hookPath = path.join(projectDir, '.claude', 'hooks', 'bmad-speak.sh'); - const playTtsPath = path.join(projectDir, '.claude', 'hooks', 'play-tts.sh'); - - return (await fs.pathExists(hookPath)) && (await fs.pathExists(playTtsPath)); - } - /** * Load existing configurations to use as defaults * @param {string} directory - Installation directory @@ -1201,7 +1000,6 @@ class UI { hasCustomContent: false, coreConfig: {}, ideConfig: { ides: [], skipIde: false }, - agentVibesConfig: { enabled: false, alreadyInstalled: false }, }; try { @@ -1215,10 +1013,6 @@ class UI { configs.ideConfig.skipIde = false; } - // Load AgentVibes configuration - const agentVibesInstalled = await this.checkAgentVibesInstalled(directory); - configs.agentVibesConfig = { enabled: agentVibesInstalled, alreadyInstalled: agentVibesInstalled }; - return configs; } catch { // If loading fails, return empty configs