From 11a1dbaefcf789a145c13e2883ec073c5b47b2e0 Mon Sep 17 00:00:00 2001 From: mreis-atlassian Date: Thu, 27 Nov 2025 02:05:04 +1100 Subject: [PATCH 1/4] feat: Adding support for Rovo Dev (#975) - Adding support for rovo dev - Adding rovo dev translation wrappers --- docs/ide-info/rovo-dev.md | 388 ++++++++++++++++++ docs/index.md | 1 + .../installers-modules-platforms-reference.md | 2 +- tools/cli/README.md | 1 + tools/cli/installers/lib/core/installer.js | 4 +- tools/cli/installers/lib/ide/rovo-dev.js | 290 +++++++++++++ tools/platform-codes.yaml | 6 + 7 files changed, 690 insertions(+), 2 deletions(-) create mode 100644 docs/ide-info/rovo-dev.md create mode 100644 tools/cli/installers/lib/ide/rovo-dev.js diff --git a/docs/ide-info/rovo-dev.md b/docs/ide-info/rovo-dev.md new file mode 100644 index 00000000..a6445758 --- /dev/null +++ b/docs/ide-info/rovo-dev.md @@ -0,0 +1,388 @@ +# Rovo Dev IDE Integration + +This document describes how BMAD-METHOD integrates with [Atlassian Rovo Dev](https://www.atlassian.com/rovo-dev), an AI-powered software development assistant. + +## Overview + +Rovo Dev is designed to integrate deeply with developer workflows and organizational knowledge bases. When you install BMAD-METHOD in a Rovo Dev project, it automatically installs BMAD agents, workflows, tasks, and tools just like it does for other IDEs (Cursor, VS Code, etc.). + +BMAD-METHOD provides: + +- **Agents**: Specialized subagents for various development tasks +- **Workflows**: Multi-step workflow guides and coordinators +- **Tasks & Tools**: Reference documentation for BMAD tasks and tools + +### What are Rovo Dev Subagents? + +Subagents are specialized agents that Rovo Dev can delegate tasks to. They are defined as Markdown files with YAML frontmatter stored in the `.rovodev/subagents/` directory. Rovo Dev automatically discovers these files and makes them available through the `@subagent-name` syntax. + +## Installation and Setup + +### Automatic Installation + +When you run the BMAD-METHOD installer and select Rovo Dev as your IDE: + +```bash +bmad install +``` + +The installer will: + +1. Create a `.rovodev/subagents/` directory in your project (if it doesn't exist) +2. Convert BMAD agents into Rovo Dev subagent format +3. Write subagent files with the naming pattern: `bmad--.md` + +### File Structure + +After installation, your project will have: + +``` +project-root/ +├── .rovodev/ +│ ├── subagents/ +│ │ ├── bmad-core-code-reviewer.md +│ │ ├── bmad-bmm-pm.md +│ │ ├── bmad-bmm-dev.md +│ │ └── ... (more agents from selected modules) +│ ├── workflows/ +│ │ ├── bmad-brainstorming.md +│ │ ├── bmad-prd-creation.md +│ │ └── ... (workflow guides) +│ ├── references/ +│ │ ├── bmad-task-core-code-review.md +│ │ ├── bmad-tool-core-analysis.md +│ │ └── ... (task/tool references) +│ ├── config.yml (Rovo Dev configuration) +│ ├── prompts.yml (Optional: reusable prompts) +│ └── ... +├── .bmad/ (BMAD installation directory) +└── ... +``` + +**Directory Structure Explanation:** + +- **subagents/**: Agents discovered and used by Rovo Dev with `@agent-name` syntax +- **workflows/**: Multi-step workflow guides and instructions +- **references/**: Documentation for available tasks and tools in BMAD + +## Subagent File Format + +BMAD agents are converted to Rovo Dev subagent format, which uses Markdown with YAML frontmatter: + +### Basic Structure + +```markdown +--- +name: bmad-module-agent-name +description: One sentence description of what this agent does +tools: + - bash + - open_files + - grep + - expand_code_chunks +model: anthropic.claude-3-5-sonnet-20241022-v2:0 # Optional +load_memory: true # Optional +--- + +You are a specialized agent for [specific task]. + +## Your Role + +Describe the agent's role and responsibilities... + +## Key Instructions + +1. First instruction +2. Second instruction +3. Third instruction + +## When to Use This Agent + +Explain when and how to use this agent... +``` + +### YAML Frontmatter Fields + +| Field | Type | Required | Description | +| ------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | string | Yes | Unique identifier for the subagent (kebab-case, no spaces) | +| `description` | string | Yes | One-line description of the subagent's purpose | +| `tools` | array | No | List of tools the subagent can use. If not specified, uses parent agent's tools | +| `model` | string | No | Specific LLM model for this subagent (e.g., `anthropic.claude-3-5-sonnet-20241022-v2:0`). If not specified, uses parent agent's model | +| `load_memory` | boolean | No | Whether to load default memory files (AGENTS.md, AGENTS.local.md). Defaults to `true` | + +### System Prompt + +The content after the closing `---` is the subagent's system prompt. This defines: + +- The agent's persona and role +- Its capabilities and constraints +- Step-by-step instructions for task execution +- Examples of expected behavior + +## Using BMAD Components in Rovo Dev + +### Invoking a Subagent (Agent) + +In Rovo Dev, you can invoke a BMAD agent as a subagent using the `@` syntax: + +``` +@bmad-core-code-reviewer Please review this PR for potential issues +@bmad-bmm-pm Help plan this feature release +@bmad-bmm-dev Implement this feature +``` + +### Accessing Workflows + +Workflow guides are available in `.rovodev/workflows/` directory: + +``` +@bmad-core-code-reviewer Use the brainstorming workflow from .rovodev/workflows/bmad-brainstorming.md +``` + +Workflow files contain step-by-step instructions and can be referenced or copied into Rovo Dev for collaborative workflow execution. + +### Accessing Tasks and Tools + +Task and tool documentation is available in `.rovodev/references/` directory. These provide: + +- Task execution instructions +- Tool capabilities and usage +- Integration examples +- Parameter documentation + +### Example Usage Scenarios + +#### Code Review + +``` +@bmad-core-code-reviewer Review the changes in src/components/Button.tsx +for best practices, performance, and potential bugs +``` + +#### Documentation + +``` +@bmad-core-documentation-writer Generate API documentation for the new +user authentication module +``` + +#### Feature Design + +``` +@bmad-module-feature-designer Design a solution for implementing +dark mode support across the application +``` + +## Customizing BMAD Subagents + +You can customize BMAD subagents after installation by editing their files directly in `.rovodev/subagents/`. + +### Example: Adding Tool Restrictions + +By default, BMAD subagents inherit tools from the parent Rovo Dev agent. You can restrict which tools a specific subagent can use: + +```yaml +--- +name: bmad-core-code-reviewer +description: Reviews code and suggests improvements +tools: + - open_files + - expand_code_chunks + - grep +--- +``` + +### Example: Using a Specific Model + +Some agents might benefit from using a different model. You can specify this: + +```yaml +--- +name: bmad-core-documentation-writer +description: Writes clear and comprehensive documentation +model: anthropic.claude-3-5-sonnet-20241022-v2:0 +--- +``` + +### Example: Enhancing the System Prompt + +You can add additional context to a subagent's system prompt: + +```markdown +--- +name: bmad-core-code-reviewer +description: Reviews code and suggests improvements +--- + +You are a specialized code review agent for our project. + +## Project Context + +Our codebase uses: + +- React 18 for frontend +- Node.js 18+ for backend +- TypeScript for type safety +- Jest for testing + +## Review Checklist + +1. Type safety and TypeScript correctness +2. React best practices and hooks usage +3. Performance considerations +4. Test coverage +5. Documentation and comments + +...rest of original system prompt... +``` + +## Memory and Context + +By default, BMAD subagents have `load_memory: true`, which means they will load memory files from your project: + +- **Project-level**: `.rovodev/AGENTS.md` and `.rovodev/.agent.md` +- **User-level**: `~/.rovodev/AGENTS.md` (global memory across all projects) + +These files can contain: + +- Project guidelines and conventions +- Common patterns and best practices +- Recent decisions and context +- Custom instructions for all agents + +### Creating Project Memory + +Create `.rovodev/AGENTS.md` in your project: + +```markdown +# Project Guidelines + +## Code Style + +- Use 2-space indentation +- Use camelCase for variables +- Use PascalCase for classes + +## Architecture + +- Follow modular component structure +- Use dependency injection for services +- Implement proper error handling + +## Testing Requirements + +- Minimum 80% code coverage +- Write tests before implementation +- Use descriptive test names +``` + +## Troubleshooting + +### Subagents Not Appearing in Rovo Dev + +1. **Verify files exist**: Check that `.rovodev/subagents/bmad-*.md` files are present +2. **Check Rovo Dev is reloaded**: Rovo Dev may cache agent definitions. Restart Rovo Dev or reload the project +3. **Verify file format**: Ensure files have proper YAML frontmatter (between `---` markers) +4. **Check file permissions**: Ensure files are readable by Rovo Dev + +### Agent Name Conflicts + +If you have custom subagents with the same names as BMAD agents, Rovo Dev will load both but may show a warning. Use unique prefixes for custom subagents to avoid conflicts. + +### Tools Not Available + +If a subagent's tools aren't working: + +1. Verify the tool names match Rovo Dev's available tools +2. Check that the parent Rovo Dev agent has access to those tools +3. Ensure tool permissions are properly configured in `.rovodev/config.yml` + +## Advanced: Tool Configuration + +Rovo Dev agents have access to a set of tools for various tasks. Common tools available include: + +- `bash`: Execute shell commands +- `open_files`: View file contents +- `grep`: Search across files +- `expand_code_chunks`: View specific code sections +- `find_and_replace_code`: Modify files +- `create_file`: Create new files +- `delete_file`: Delete files +- `move_file`: Rename or move files + +### MCP Servers + +Rovo Dev can also connect to Model Context Protocol (MCP) servers, which provide additional tools and data sources: + +- **Atlassian Integration**: Access to Jira, Confluence, and Bitbucket +- **Code Analysis**: Custom code analysis and metrics +- **External Services**: APIs and third-party integrations + +Configure MCP servers in `~/.rovodev/mcp.json` or `.rovodev/mcp.json`. + +## Integration with Other IDE Handlers + +BMAD-METHOD supports multiple IDEs simultaneously. You can have both Rovo Dev and other IDE configurations (Cursor, VS Code, etc.) in the same project. Each IDE will have its own artifacts installed in separate directories. + +For example: + +- Rovo Dev agents: `.rovodev/subagents/bmad-*.md` +- Cursor rules: `.cursor/rules/bmad/` +- Claude Code: `.claude/rules/bmad/` + +## Performance Considerations + +- BMAD subagent files are typically small (1-5 KB each) +- Rovo Dev lazy-loads subagents, so having many subagents doesn't impact startup time +- System prompts are cached by Rovo Dev after first load + +## Best Practices + +1. **Keep System Prompts Concise**: Shorter, well-structured prompts are more effective +2. **Use Project Memory**: Leverage `.rovodev/AGENTS.md` for shared context +3. **Customize Tool Restrictions**: Give subagents only the tools they need +4. **Test Subagent Invocations**: Verify each subagent works as expected for your project +5. **Version Control**: Commit `.rovodev/subagents/` to version control for team consistency +6. **Document Custom Subagents**: Add comments explaining the purpose of customized subagents + +## Related Documentation + +- [Rovo Dev Official Documentation](https://www.atlassian.com/rovo-dev) +- [BMAD-METHOD Installation Guide](./installation.md) +- [IDE Handler Architecture](./ide-handlers.md) +- [Rovo Dev Configuration Reference](https://www.atlassian.com/rovo-dev/configuration) + +## Examples + +### Example 1: Code Review Workflow + +``` +User: @bmad-core-code-reviewer Review src/auth/login.ts for security issues +Rovo Dev → Subagent: Opens file, analyzes code, suggests improvements +Subagent output: Security vulnerabilities found, recommendations provided +``` + +### Example 2: Documentation Generation + +``` +User: @bmad-core-documentation-writer Generate API docs for the new payment module +Rovo Dev → Subagent: Analyzes code structure, generates documentation +Subagent output: Markdown documentation with examples and API reference +``` + +### Example 3: Architecture Design + +``` +User: @bmad-module-feature-designer Design a caching strategy for the database layer +Rovo Dev → Subagent: Reviews current architecture, proposes design +Subagent output: Detailed architecture proposal with implementation plan +``` + +## Support + +For issues or questions about: + +- **Rovo Dev**: See [Atlassian Rovo Dev Documentation](https://www.atlassian.com/rovo-dev) +- **BMAD-METHOD**: See [BMAD-METHOD README](../README.md) +- **IDE Integration**: See [IDE Handler Guide](./ide-handlers.md) diff --git a/docs/index.md b/docs/index.md index 0db96b2f..d5e1f83e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -87,6 +87,7 @@ Instructions for loading agents and running workflows in your development enviro - [OpenCode](./ide-info/opencode.md) - [Qwen](./ide-info/qwen.md) - [Roo](./ide-info/roo.md) +- [Rovo Dev](./ide-info/rovo-dev.md) - [Trae](./ide-info/trae.md) **Key concept:** Every reference to "load an agent" or "activate an agent" in the main docs links to the [ide-info](./ide-info/) directory for IDE-specific instructions. diff --git a/docs/installers-bundlers/installers-modules-platforms-reference.md b/docs/installers-bundlers/installers-modules-platforms-reference.md index df54e875..62f1a398 100644 --- a/docs/installers-bundlers/installers-modules-platforms-reference.md +++ b/docs/installers-bundlers/installers-modules-platforms-reference.md @@ -171,7 +171,7 @@ communication_language: "English" - Windsurf **Additional**: -Cline, Roo, Auggie, GitHub Copilot, Codex, Gemini, Qwen, Trae, Kilo, Crush, iFlow +Cline, Roo, Rovo Dev,Auggie, GitHub Copilot, Codex, Gemini, Qwen, Trae, Kilo, Crush, iFlow ### Platform Features diff --git a/tools/cli/README.md b/tools/cli/README.md index 944b2948..5c794f16 100644 --- a/tools/cli/README.md +++ b/tools/cli/README.md @@ -162,6 +162,7 @@ The installer supports **15 IDE environments** through a base-derived architectu | `gemini` | Google Gemini | `.gemini/` | | `qwen` | Qwen | `.qwen/` | | `roo` | Roo | `.roo/` | +| `rovo-dev` | Rovo | `.rovodev/` | | `trae` | Trae | `.trae/` | | `iflow` | iFlow | `.iflow/` | | `kilo` | Kilo | `.kilo/` | diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 3f72cd59..7473a307 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -166,7 +166,9 @@ class Installer { for (const ide of newlySelectedIdes) { // List of IDEs that have interactive prompts - const needsPrompts = ['claude-code', 'github-copilot', 'roo', 'cline', 'auggie', 'codex', 'qwen', 'gemini'].includes(ide); + const needsPrompts = ['claude-code', 'github-copilot', 'roo', 'cline', 'auggie', 'codex', 'qwen', 'gemini', 'rovo-dev'].includes( + ide, + ); if (needsPrompts) { // Get IDE handler and collect configuration diff --git a/tools/cli/installers/lib/ide/rovo-dev.js b/tools/cli/installers/lib/ide/rovo-dev.js new file mode 100644 index 00000000..8f460178 --- /dev/null +++ b/tools/cli/installers/lib/ide/rovo-dev.js @@ -0,0 +1,290 @@ +const path = require('node:path'); +const fs = require('fs-extra'); +const chalk = require('chalk'); +const { BaseIdeSetup } = require('./_base-ide'); +const { AgentCommandGenerator } = require('./shared/agent-command-generator'); +const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator'); +const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator'); + +/** + * Rovo Dev IDE setup handler + * + * Installs BMAD agents as Rovo Dev subagents in .rovodev/subagents/ + * Installs workflows and tasks/tools as reference guides in .rovodev/ + * Rovo Dev automatically discovers agents and integrates with BMAD like other IDEs + */ +class RovoDevSetup extends BaseIdeSetup { + constructor() { + super('rovo-dev', 'Atlassian Rovo Dev', true); // preferred IDE + this.configDir = '.rovodev'; + this.subagentsDir = 'subagents'; + this.workflowsDir = 'workflows'; + this.referencesDir = 'references'; + } + + /** + * Cleanup old BMAD installation before reinstalling + * @param {string} projectDir - Project directory + */ + async cleanup(projectDir) { + const rovoDevDir = path.join(projectDir, this.configDir); + + if (!(await fs.pathExists(rovoDevDir))) { + return; + } + + // Clean BMAD agents from subagents directory + const subagentsDir = path.join(rovoDevDir, this.subagentsDir); + if (await fs.pathExists(subagentsDir)) { + const entries = await fs.readdir(subagentsDir); + const bmadFiles = entries.filter((file) => file.startsWith('bmad-') && file.endsWith('.md')); + + for (const file of bmadFiles) { + await fs.remove(path.join(subagentsDir, file)); + } + } + + // Clean BMAD workflows from workflows directory + const workflowsDir = path.join(rovoDevDir, this.workflowsDir); + if (await fs.pathExists(workflowsDir)) { + const entries = await fs.readdir(workflowsDir); + const bmadFiles = entries.filter((file) => file.startsWith('bmad-') && file.endsWith('.md')); + + for (const file of bmadFiles) { + await fs.remove(path.join(workflowsDir, file)); + } + } + + // Clean BMAD tasks/tools from references directory + const referencesDir = path.join(rovoDevDir, this.referencesDir); + if (await fs.pathExists(referencesDir)) { + const entries = await fs.readdir(referencesDir); + const bmadFiles = entries.filter((file) => file.startsWith('bmad-') && file.endsWith('.md')); + + for (const file of bmadFiles) { + await fs.remove(path.join(referencesDir, file)); + } + } + } + + /** + * Setup Rovo Dev configuration + * @param {string} projectDir - Project directory + * @param {string} bmadDir - BMAD installation directory + * @param {Object} options - Setup options + */ + async setup(projectDir, bmadDir, options = {}) { + console.log(chalk.cyan(`Setting up ${this.name}...`)); + + // Clean up old BMAD installation first + await this.cleanup(projectDir); + + // Create .rovodev directory structure + const rovoDevDir = path.join(projectDir, this.configDir); + const subagentsDir = path.join(rovoDevDir, this.subagentsDir); + const workflowsDir = path.join(rovoDevDir, this.workflowsDir); + const referencesDir = path.join(rovoDevDir, this.referencesDir); + + await this.ensureDir(subagentsDir); + await this.ensureDir(workflowsDir); + await this.ensureDir(referencesDir); + + // Generate and install agents + const agentGen = new AgentCommandGenerator(this.bmadFolderName); + const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []); + + let agentCount = 0; + for (const artifact of agentArtifacts) { + const subagentFilename = `bmad-${artifact.module}-${artifact.name}.md`; + const targetPath = path.join(subagentsDir, subagentFilename); + const subagentContent = this.convertToRovoDevSubagent(artifact.content, artifact.name, artifact.module); + await this.writeFile(targetPath, subagentContent); + agentCount++; + } + + // Generate and install workflows + const workflowGen = new WorkflowCommandGenerator(this.bmadFolderName); + const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGen.collectWorkflowArtifacts(bmadDir); + + let workflowCount = 0; + for (const artifact of workflowArtifacts) { + if (artifact.type === 'workflow-command') { + const workflowFilename = path.basename(artifact.relativePath); + const targetPath = path.join(workflowsDir, workflowFilename); + await this.writeFile(targetPath, artifact.content); + workflowCount++; + } + } + + // Generate and install tasks and tools + const taskToolGen = new TaskToolCommandGenerator(); + const { tasks: taskCount, tools: toolCount } = await this.generateTaskToolReferences(bmadDir, referencesDir, taskToolGen); + + // Summary output + console.log(chalk.green(`✓ ${this.name} configured:`)); + console.log(chalk.dim(` - ${agentCount} agents installed to .rovodev/subagents/`)); + if (workflowCount > 0) { + console.log(chalk.dim(` - ${workflowCount} workflows installed to .rovodev/workflows/`)); + } + if (taskCount + toolCount > 0) { + console.log( + chalk.dim(` - ${taskCount + toolCount} tasks/tools installed to .rovodev/references/ (${taskCount} tasks, ${toolCount} tools)`), + ); + } + console.log(chalk.yellow(`\n Note: Agents are automatically discovered by Rovo Dev`)); + console.log(chalk.dim(` - Access agents by typing @ in Rovo Dev to see available options`)); + console.log(chalk.dim(` - Workflows and references are available in .rovodev/ directory`)); + + return { + success: true, + agents: agentCount, + workflows: workflowCount, + tasks: taskCount, + tools: toolCount, + }; + } + + /** + * Generate task and tool reference guides + * @param {string} bmadDir - BMAD directory + * @param {string} referencesDir - References directory + * @param {TaskToolCommandGenerator} taskToolGen - Generator instance + */ + async generateTaskToolReferences(bmadDir, referencesDir, taskToolGen) { + const tasks = await taskToolGen.loadTaskManifest(bmadDir); + const tools = await taskToolGen.loadToolManifest(bmadDir); + + const standaloneTasks = tasks ? tasks.filter((t) => t.standalone === 'true' || t.standalone === true) : []; + const standaloneTools = tools ? tools.filter((t) => t.standalone === 'true' || t.standalone === true) : []; + + let taskCount = 0; + for (const task of standaloneTasks) { + const commandContent = taskToolGen.generateCommandContent(task, 'task'); + const targetPath = path.join(referencesDir, `bmad-task-${task.module}-${task.name}.md`); + await this.writeFile(targetPath, commandContent); + taskCount++; + } + + let toolCount = 0; + for (const tool of standaloneTools) { + const commandContent = taskToolGen.generateCommandContent(tool, 'tool'); + const targetPath = path.join(referencesDir, `bmad-tool-${tool.module}-${tool.name}.md`); + await this.writeFile(targetPath, commandContent); + toolCount++; + } + + return { tasks: taskCount, tools: toolCount }; + } + + /** + * Convert BMAD agent launcher to Rovo Dev subagent format + * + * Rovo Dev subagents use Markdown files with YAML frontmatter containing: + * - name: Unique identifier for the subagent + * - description: One-line description of the subagent's purpose + * - tools: Array of tools the subagent can use (optional) + * - model: Specific model for this subagent (optional) + * - load_memory: Whether to load memory files (optional, defaults to true) + * + * @param {string} launcherContent - Original agent launcher content + * @param {string} agentName - Name of the agent + * @param {string} moduleName - Name of the module + * @returns {string} Rovo Dev subagent-formatted content + */ + convertToRovoDevSubagent(launcherContent, agentName, moduleName) { + // Extract metadata from the launcher XML + const titleMatch = launcherContent.match(/title="([^"]+)"/); + const title = titleMatch ? titleMatch[1] : this.formatTitle(agentName); + + const descriptionMatch = launcherContent.match(/description="([^"]+)"/); + const description = descriptionMatch ? descriptionMatch[1] : `BMAD agent: ${title}`; + + const roleDefinitionMatch = launcherContent.match(/roleDefinition="([^"]+)"/); + const roleDefinition = roleDefinitionMatch ? roleDefinitionMatch[1] : `You are a specialized agent for ${title.toLowerCase()} tasks.`; + + // Extract the main system prompt from the launcher (content after closing tags) + let systemPrompt = roleDefinition; + + // Try to extract additional instructions from the launcher content + const instructionsMatch = launcherContent.match(/([\s\S]*?)<\/instructions>/); + if (instructionsMatch) { + systemPrompt += '\n\n' + instructionsMatch[1].trim(); + } + + // Build YAML frontmatter for Rovo Dev subagent + const frontmatter = { + name: `bmad-${moduleName}-${agentName}`, + description: description, + // Note: tools and model can be added by users in their .rovodev/subagents/*.md files + // We don't enforce specific tools since BMAD agents are flexible + }; + + // Create YAML frontmatter string with proper quoting for special characters + let yamlContent = '---\n'; + yamlContent += `name: ${frontmatter.name}\n`; + // Quote description to handle colons and other special characters in YAML + yamlContent += `description: "${frontmatter.description.replaceAll('"', String.raw`\"`)}"\n`; + yamlContent += '---\n'; + + // Combine frontmatter with system prompt + const subagentContent = yamlContent + systemPrompt; + + return subagentContent; + } + + /** + * Detect whether Rovo Dev is already configured in the project + * @param {string} projectDir - Project directory + * @returns {boolean} + */ + async detect(projectDir) { + const rovoDevDir = path.join(projectDir, this.configDir); + + if (!(await fs.pathExists(rovoDevDir))) { + return false; + } + + // Check for BMAD agents in subagents directory + const subagentsDir = path.join(rovoDevDir, this.subagentsDir); + if (await fs.pathExists(subagentsDir)) { + try { + const entries = await fs.readdir(subagentsDir); + if (entries.some((entry) => entry.startsWith('bmad-') && entry.endsWith('.md'))) { + return true; + } + } catch { + // Continue checking other directories + } + } + + // Check for BMAD workflows in workflows directory + const workflowsDir = path.join(rovoDevDir, this.workflowsDir); + if (await fs.pathExists(workflowsDir)) { + try { + const entries = await fs.readdir(workflowsDir); + if (entries.some((entry) => entry.startsWith('bmad-') && entry.endsWith('.md'))) { + return true; + } + } catch { + // Continue checking other directories + } + } + + // Check for BMAD tasks/tools in references directory + const referencesDir = path.join(rovoDevDir, this.referencesDir); + if (await fs.pathExists(referencesDir)) { + try { + const entries = await fs.readdir(referencesDir); + if (entries.some((entry) => entry.startsWith('bmad-') && entry.endsWith('.md'))) { + return true; + } + } catch { + // Continue + } + } + + return false; + } +} + +module.exports = { RovoDevSetup }; diff --git a/tools/platform-codes.yaml b/tools/platform-codes.yaml index 99c4b275..a58e2119 100644 --- a/tools/platform-codes.yaml +++ b/tools/platform-codes.yaml @@ -55,6 +55,12 @@ platforms: category: ide description: "Enhanced Cline fork" + rovo: + name: "Rovo Dev" + preferred: false + category: ide + description: "Atlassian's AI coding assistant" + github-copilot: name: "GitHub Copilot" preferred: false From 5702195ef73385b5d2ea474fe6f08f4f8d5c8650 Mon Sep 17 00:00:00 2001 From: Paul Preibisch Date: Wed, 26 Nov 2025 08:51:57 -0700 Subject: [PATCH 2/4] Add Text-to-Speech Integration via TTS_INJECTION System (#934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add provider-agnostic TTS integration via injection point system Implements comprehensive Text-to-Speech integration for BMAD agents using a generic TTS_INJECTION marker system. When AgentVibes (or any compatible TTS provider) is installed, all BMAD agents can speak their responses with unique AI voices. ## Key Features **Provider-Agnostic Architecture** - Uses generic `TTS_INJECTION` markers instead of vendor-specific naming - Future-proof for multiple TTS providers beyond AgentVibes - Clean separation - BMAD stays TTS-agnostic, providers handle injection **Installation Flow** - BMAD → AgentVibes: TTS instructions injected when AgentVibes detects existing BMAD installation - AgentVibes → BMAD: TTS instructions injected during BMAD installation when AgentVibes detected - User must manually create voice assignment file when AgentVibes installs first (documented limitation) **Party Mode Voice Support** - Each agent speaks with unique assigned voice in multi-agent discussions - PM, Architect, Developer, Analyst, UX Designer, etc. - all with distinct voices **Zero Breaking Changes** - Fully backward compatible - works without any TTS provider - `TTS_INJECTION` markers are benign HTML comments if not processed - No changes to existing agent behavior or non-TTS workflows ## Implementation Details **Files Modified:** - `tools/cli/installers/lib/core/installer.js` - TTS injection processing logic - `tools/cli/lib/ui.js` - AgentVibes detection and installation prompts - `tools/cli/commands/install.js` - Post-install guidance for AgentVibes setup - `src/utility/models/fragments/activation-rules.xml` - TTS_INJECTION marker for agents - `src/core/workflows/party-mode/instructions.md` - TTS_INJECTION marker for party mode **Injection Point System:** ```xml - ALWAYS communicate in {communication_language} - Stay in character until exit selected ``` When AgentVibes is detected, the installer replaces this marker with: ``` - When responding to user messages, speak your responses using TTS: Call: `.claude/hooks/bmad-speak.sh '{agent-id}' '{response-text}'` after each response IMPORTANT: Use single quotes - do NOT escape special characters like ! or $ ``` **Special Character Handling:** - Explicit guidance to use single quotes without escaping - Prevents "backslash exclamation" artifacts in speech **User Experience:** ``` User: "How should we architect this feature?" Architect: [Text response] + 🔊 [Professional voice explains architecture] ``` Party Mode: ``` PM (John): "I'll focus on user value..." 🔊 [Male professional voice] UX Designer (Sara): "From a user perspective..." 🔊 [Female voice] Architect (Marcus): "The technical approach..." 🔊 [Male technical voice] ``` ## Testing **Unit Tests:** ✅ 62/62 passing - 49/49 schema validation tests - 13/13 installation component tests **Integration Testing:** - ✅ BMAD → AgentVibes (automatic injection) - ✅ AgentVibes → BMAD (automatic injection) - ✅ No TTS provider (markers remain as comments) ## Documentation Comprehensive testing guide created with: - Both installation scenario walkthroughs - Verification commands and expected outputs - Troubleshooting guidance ## Known Limitations **AgentVibes → BMAD Installation Order:** When AgentVibes installs first, voice assignment file must be created manually: ```bash mkdir -p .bmad/_cfg cat > .bmad/_cfg/agent-voice-map.csv << 'EOF' agent_id,voice_name pm,en_US-ryan-high architect,en_US-danny-low dev,en_US-joe-medium EOF ``` This limitation exists to prevent false legacy v4 detection warnings from BMAD installer. **Recommended:** Install BMAD first, then AgentVibes for automatic voice assignment. ## Related Work **Companion Implementation:** - Repository: paulpreibisch/AgentVibes - Commits: 6 commits implementing injection processing and voice routing - Features: Retroactive injection, file path extraction, escape stripping **GitHub Issues:** - paulpreibisch/AgentVibes#36 - BMAD agent ID support ## Breaking Changes None. Feature is opt-in and requires separate TTS provider installation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: Enforce project hooks over global hooks in party mode before, claude would sometimes favor global agent vibes hooks over project specific * feat: Automate AgentVibes installer invocation after BMAD install Instead of showing manual installation instructions, the installer now: - Prompts "Press Enter to start AgentVibes installer..." - Automatically runs npx agentvibes@latest install - Handles errors gracefully with fallback instructions This provides a seamless installation flow matching the test script's interactive approach. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * docs: Add automated testing script and guide for PR #934 Added comprehensive testing tools for AgentVibes party mode integration: - test-bmad-pr.sh: Fully automated installation and verification script - Interactive mode selection (official PR or custom fork) - Automatic BMAD CLI setup and linking - AgentVibes installation with guided prompts - Built-in verification checks for voice maps and hooks - Saved configuration for quick re-testing - TESTING.md: Complete testing documentation - Quick start with one-line npx command - Manual installation alternative - Troubleshooting guide - Cleanup instructions Testers can now run a single command to test the full AgentVibes integration without needing to understand the complex setup process. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: Add shell: true to npx execSync to prevent permission denied error The execSync call for 'npx agentvibes@latest install' was failing with 'Permission denied' because the shell was trying to execute 'agentvibes@latest' directly instead of passing it as an argument to npx. Adding shell: true ensures the command runs in a proper shell context where npx can correctly interpret the @latest version syntax. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: Remove duplicate AgentVibes installation step from test script The test script was calling AgentVibes installer twice: 1. BMAD installer now automatically runs AgentVibes (new feature) 2. Test script had a separate Step 6 that also ran AgentVibes This caused the installer to run twice, with the second call failing because it was already installed. Changes: - Removed redundant Step 6 (AgentVibes installation) - Updated Step 5 to indicate it includes AgentVibes - Updated step numbers from 7 to 6 throughout - Added guidance that AgentVibes runs automatically Now the flow is cleaner: BMAD installer handles everything! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: Address bmadcode review - preserve variables and move TTS logic to injection Fixes requested changes from PR review: 1. Preserve {bmad_folder} variable placeholder - Changed: {project_root}/.bmad/core/tasks/workflow.xml - To: {project_root}/{bmad_folder}/core/tasks/workflow.xml - Allows users to choose custom BMAD folder names during installation 2. Move TTS-specific hook guidance to injection system - Removed hardcoded hook enforcement from source files - Added hook guidance to processTTSInjectionPoints() in installer.js - Now only appears when AgentVibes is installed (via TTS_INJECTION) 3. Maintain TTS-agnostic source architecture - Source files remain clean of TTS-specific instructions - TTS details injected at install-time only when needed - Preserves provider-agnostic design principle Changes made: - src/core/workflows/party-mode/instructions.md - Reverted .bmad to {bmad_folder} variable - Replaced hardcoded hook guidance with - Removed about play-tts.sh hook location - tools/cli/installers/lib/core/installer.js - Added hook enforcement to party-mode injection replacement - Guidance now injected only when enableAgentVibes is true Addresses review comments from bmadcode: - "needs to remain the variable. it will get set in the file at the install destination." - "items like this we will need to inject if user is using claude and TTS" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude * fix: Change 'claude-code' to 'claude' in test script instructions The correct command to start Claude is 'claude', not 'claude-code'. Updated line 362-363 in test-bmad-pr.sh to show the correct command. * fix: Remove npm link from test script to avoid global namespace pollution - Removed 'npm link' command that was installing BMAD globally - Changed 'bmad install' to direct node execution using local clone - Updated success message to reflect no global installation This keeps testing fully isolated and prevents conflicts with: - Existing BMAD installations - Future official BMAD installs - Orphaned symlinks when test directory is deleted The test script now runs completely self-contained without modifying the user's global npm environment. --------- Co-authored-by: Claude Code Co-authored-by: Claude Co-authored-by: Paul Preibisch Co-authored-by: Brian --- TESTING.md | 115 ++++++ src/core/workflows/party-mode/instructions.md | 28 +- .../models/fragments/activation-rules.xml | 1 + test-bmad-pr.sh | 381 ++++++++++++++++++ tools/cli/commands/install.js | 40 ++ tools/cli/installers/lib/core/installer.js | 174 +++++++- tools/cli/lib/ui.js | 159 ++++++++ 7 files changed, 889 insertions(+), 9 deletions(-) create mode 100644 TESTING.md create mode 100755 test-bmad-pr.sh diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 00000000..37357302 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,115 @@ +# Testing AgentVibes Party Mode (PR #934) + +This guide helps you test the AgentVibes integration that adds multi-agent party mode with unique voices for each BMAD agent. + +## Quick Start + +We've created an automated test script that handles everything for you: + +```bash +curl -fsSL https://raw.githubusercontent.com/paulpreibisch/BMAD-METHOD/feature/agentvibes-tts-integration/test-bmad-pr.sh -o test-bmad-pr.sh +chmod +x test-bmad-pr.sh +./test-bmad-pr.sh +``` + +## What the Script Does + +The automated script will: + +1. Clone the BMAD repository +2. Checkout the PR branch with party mode features +3. Install BMAD CLI tools locally +4. Create a test BMAD project +5. Install AgentVibes TTS system +6. Configure unique voices for each agent +7. Verify the installation + +## Prerequisites + +- Node.js and npm installed +- Git installed +- ~500MB free disk space +- 10-15 minutes for complete setup + +## Manual Testing (Alternative) + +If you prefer manual installation: + +### 1. Clone and Setup BMAD + +```bash +git clone https://github.com/paulpreibisch/BMAD-METHOD.git +cd BMAD-METHOD +git fetch origin pull/934/head:agentvibes-party-mode +git checkout agentvibes-party-mode +cd tools/cli +npm install +npm link +``` + +### 2. Create Test Project + +```bash +mkdir -p ~/bmad-test-project +cd ~/bmad-test-project +bmad install +``` + +When prompted: + +- Enable TTS for agents? → **Yes** +- The installer will automatically prompt you to install AgentVibes + +### 3. Test Party Mode + +```bash +cd ~/bmad-test-project +claude-code +``` + +In Claude Code, run: + +``` +/bmad:core:workflows:party-mode +``` + +Each BMAD agent should speak with a unique voice! + +## Verification + +After installation, verify: + +✅ Voice map file exists: `.bmad/_cfg/agent-voice-map.csv` +✅ BMAD TTS hooks exist: `.claude/hooks/bmad-speak.sh` +✅ Each agent has a unique voice assigned +✅ Party mode works with distinct voices + +## Troubleshooting + +**No audio?** + +- Check: `.claude/hooks/play-tts.sh` exists +- Test current voice: `/agent-vibes:whoami` + +**Same voice for all agents?** + +- Check: `.bmad/_cfg/agent-voice-map.csv` has different voices +- List available voices: `/agent-vibes:list` + +## Report Issues + +Found a bug? Report it on the PR: +https://github.com/bmad-code-org/BMAD-METHOD/pull/934 + +## Cleanup + +To remove the test installation: + +```bash +# Remove test directory +rm -rf ~/bmad-test-project # or your custom test directory + +# Unlink BMAD CLI (optional) +cd ~/BMAD-METHOD/tools/cli +npm unlink +``` diff --git a/src/core/workflows/party-mode/instructions.md b/src/core/workflows/party-mode/instructions.md index 3ca8e052..6afd5ede 100644 --- a/src/core/workflows/party-mode/instructions.md +++ b/src/core/workflows/party-mode/instructions.md @@ -2,6 +2,7 @@ The workflow execution engine is governed by: {project_root}/{bmad_folder}/core/tasks/workflow.xml This workflow orchestrates group discussions between all installed BMAD agents + @@ -94,17 +95,36 @@ - Present each agent's contribution clearly: + For each agent response, output text THEN trigger their voice: + + + 1. Output the agent's text in format: [Icon Emoji] [Agent Name]: [dialogue] + 2. 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 + 3. Repeat for each agent in the response + + - [Agent Name]: [Their response in their voice/style] + [Icon Emoji] [Agent Name]: [Their response in their voice/style] - [Another Agent]: [Their response, potentially referencing the first] + [Icon Emoji] [Another Agent]: [Their response, potentially referencing the first] - [Third Agent if selected]: [Their contribution] + [Icon Emoji] [Third Agent if selected]: [Their contribution] + + 🏗️ [Winston]: I recommend using microservices for better scalability. + [Bash: .claude/hooks/bmad-speak.sh "Winston" "I recommend using microservices for better scalability."] + + 📋 [John]: But a monolith would get us to market faster for MVP. + [Bash: .claude/hooks/bmad-speak.sh "John" "But a monolith would get us to market faster for MVP."] + Maintain spacing between agents for readability Preserve each agent's unique voice throughout + Always include the agent's icon emoji from the manifest before their name + Trigger TTS for each agent immediately after outputting their text diff --git a/src/utility/models/fragments/activation-rules.xml b/src/utility/models/fragments/activation-rules.xml index 8fdd9852..4835e834 100644 --- a/src/utility/models/fragments/activation-rules.xml +++ b/src/utility/models/fragments/activation-rules.xml @@ -1,5 +1,6 @@ - ALWAYS communicate in {communication_language} UNLESS contradicted by communication_style + - Stay in character until exit selected - Menu triggers use asterisk (*) - NOT markdown, display exactly as shown - Number all lists, use letters for sub-options diff --git a/test-bmad-pr.sh b/test-bmad-pr.sh new file mode 100755 index 00000000..54cde458 --- /dev/null +++ b/test-bmad-pr.sh @@ -0,0 +1,381 @@ +#!/usr/bin/env bash +# +# BMAD PR Testing Script +# Interactive script to test BMAD PR #934 with AgentVibes integration +# + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG_FILE="$SCRIPT_DIR/.test-bmad-config" + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +clear + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "🎙️ BMAD AgentVibes Party Mode Testing Script" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo -e "${BLUE}What this script does:${NC}" +echo "" +echo " This script automates the process of testing BMAD's AgentVibes" +echo " integration (PR #934), which adds multi-agent party mode with" +echo " unique voices for each BMAD agent." +echo "" +echo -e "${BLUE}The script will:${NC}" +echo "" +echo " 1. Clone the BMAD repository" +echo " 2. Checkout the PR branch with party mode features" +echo " 3. Install BMAD CLI tools locally" +echo " 4. Create a test BMAD project" +echo " 5. Run BMAD installer (automatically installs AgentVibes)" +echo " 6. Verify the installation" +echo "" +echo -e "${YELLOW}Prerequisites:${NC}" +echo " • Node.js and npm installed" +echo " • Git installed" +echo " • ~500MB free disk space" +echo " • 10-15 minutes for complete setup" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +read -p "Ready to continue? [Y/n]: " -n 1 -r +echo +if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ -n $REPLY ]]; then + echo "❌ Setup cancelled" + exit 0 +fi + +clear + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "🔧 Testing Mode Selection" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo "Choose how you want to test:" +echo "" +echo " 1) Test official BMAD PR #934 (recommended for most users)" +echo " • Uses: github.com/bmad-code-org/BMAD-METHOD" +echo " • Branch: PR #934 (agentvibes-party-mode)" +echo " • Best for: Testing the official PR before it's merged" +echo "" +echo " 2) Test your forked repository" +echo " • Uses: Your GitHub fork" +echo " • Branch: Your custom branch (you choose)" +echo " • Best for: Testing your own changes or modifications" +echo "" + +# Load saved config if it exists +SAVED_MODE="" +SAVED_FORK="" +SAVED_BRANCH="" +SAVED_TEST_DIR="" +if [[ -f "$CONFIG_FILE" ]]; then + source "$CONFIG_FILE" +fi + +if [[ -n "$SAVED_MODE" ]]; then + echo -e "${BLUE}Last used: Mode $SAVED_MODE${NC}" + [[ -n "$SAVED_FORK" ]] && echo " Fork: $SAVED_FORK" + [[ -n "$SAVED_BRANCH" ]] && echo " Branch: $SAVED_BRANCH" + echo "" +fi + +read -p "Select mode [1/2]: " MODE_CHOICE +echo "" + +# Validate mode choice +while [[ ! "$MODE_CHOICE" =~ ^[12]$ ]]; do + echo -e "${RED}Invalid choice. Please enter 1 or 2.${NC}" + read -p "Select mode [1/2]: " MODE_CHOICE + echo "" +done + +# Configure based on mode +if [[ "$MODE_CHOICE" == "1" ]]; then + # Official PR mode + REPO_URL="https://github.com/bmad-code-org/BMAD-METHOD.git" + BRANCH_NAME="agentvibes-party-mode" + FETCH_PR=true + + echo -e "${GREEN}✓ Using official BMAD repository${NC}" + echo " Repository: $REPO_URL" + echo " Will fetch: PR #934 into branch '$BRANCH_NAME'" + echo "" +else + # Fork mode + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "🍴 Fork Configuration" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + + if [[ -n "$SAVED_FORK" ]]; then + read -p "GitHub fork URL [$SAVED_FORK]: " FORK_INPUT + REPO_URL="${FORK_INPUT:-$SAVED_FORK}" + else + echo "Enter your forked repository URL:" + echo "(e.g., https://github.com/yourusername/BMAD-METHOD.git)" + read -p "Fork URL: " REPO_URL + fi + echo "" + + if [[ -n "$SAVED_BRANCH" ]]; then + read -p "Branch name [$SAVED_BRANCH]: " BRANCH_INPUT + BRANCH_NAME="${BRANCH_INPUT:-$SAVED_BRANCH}" + else + echo "Enter the branch name to test:" + echo "(e.g., agentvibes-party-mode, main, feature-xyz)" + read -p "Branch: " BRANCH_NAME + fi + echo "" + + FETCH_PR=false + + echo -e "${GREEN}✓ Using your fork${NC}" + echo " Repository: $REPO_URL" + echo " Branch: $BRANCH_NAME" + echo "" +fi + +# Ask for test directory +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📁 Test Directory" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +if [[ -n "$SAVED_TEST_DIR" ]]; then + read -p "Test directory [$SAVED_TEST_DIR]: " TEST_DIR + TEST_DIR="${TEST_DIR:-$SAVED_TEST_DIR}" +else + DEFAULT_DIR="$HOME/bmad-pr-test-$(date +%Y%m%d-%H%M%S)" + echo "Where should we create the test environment?" + read -p "Test directory [$DEFAULT_DIR]: " TEST_DIR + TEST_DIR="${TEST_DIR:-$DEFAULT_DIR}" +fi + +# Expand ~ to actual home directory +TEST_DIR="${TEST_DIR/#\~/$HOME}" + +echo "" + +# Save configuration +echo "SAVED_MODE=\"$MODE_CHOICE\"" > "$CONFIG_FILE" +[[ "$MODE_CHOICE" == "2" ]] && echo "SAVED_FORK=\"$REPO_URL\"" >> "$CONFIG_FILE" +[[ "$MODE_CHOICE" == "2" ]] && echo "SAVED_BRANCH=\"$BRANCH_NAME\"" >> "$CONFIG_FILE" +echo "SAVED_TEST_DIR=\"$TEST_DIR\"" >> "$CONFIG_FILE" +echo -e "${GREEN}✓ Configuration saved${NC}" +echo "" + +# Confirm before starting +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📋 Summary" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo " Repository: $REPO_URL" +echo " Branch: $BRANCH_NAME" +echo " Test dir: $TEST_DIR" +echo "" +read -p "Proceed with setup? [Y/n]: " -n 1 -r +echo +echo "" +if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ -n $REPLY ]]; then + echo "❌ Setup cancelled" + exit 0 +fi + +# Clean up old test directory if it exists +if [[ -d "$TEST_DIR" ]]; then + echo "⚠️ Test directory already exists: $TEST_DIR" + read -p "Delete and recreate? [Y/n]: " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then + rm -rf "$TEST_DIR" + echo -e "${GREEN}✓ Deleted old test directory${NC}" + else + echo -e "${YELLOW}⚠ Using existing directory (may have stale data)${NC}" + fi + echo "" +fi + +clear + +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "🚀 Starting Installation" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +# Step 1: Clone repository +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📥 Step 1/6: Cloning repository" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +mkdir -p "$TEST_DIR" +cd "$TEST_DIR" +git clone "$REPO_URL" BMAD-METHOD +cd BMAD-METHOD +echo "" +echo -e "${GREEN}✓ Repository cloned${NC}" +echo "" + +# Step 2: Checkout branch (different logic for PR vs fork) +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "🔀 Step 2/6: Checking out branch" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +if [[ "$FETCH_PR" == true ]]; then + # Fetch PR from upstream + echo "Fetching PR #934 from upstream..." + git remote add upstream https://github.com/bmad-code-org/BMAD-METHOD.git + git fetch upstream pull/934/head:$BRANCH_NAME + git checkout $BRANCH_NAME + echo "" + echo -e "${GREEN}✓ Checked out PR branch: $BRANCH_NAME${NC}" +else + # Just checkout the specified branch from fork + git checkout $BRANCH_NAME + echo "" + echo -e "${GREEN}✓ Checked out branch: $BRANCH_NAME${NC}" +fi +echo "" + +# Step 3: Install BMAD CLI +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📦 Step 3/6: Installing BMAD CLI" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +cd tools/cli +npm install +echo "" +echo -e "${GREEN}✓ BMAD CLI dependencies installed${NC}" +echo "" + +# Step 4: Create test project +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "📁 Step 4/6: Creating test project" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +cd "$TEST_DIR" +mkdir -p bmad-project +cd bmad-project +echo -e "${GREEN}✓ Test project directory created${NC}" +echo " Location: $TEST_DIR/bmad-project" +echo "" + +# Step 5: Run BMAD installer (includes AgentVibes setup) +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "⚙️ Step 5/6: Running BMAD installer with AgentVibes" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo -e "${YELLOW}Important: When prompted during installation:${NC}" +echo -e " • Enable TTS for agents? → ${GREEN}Yes${NC}" +echo -e " • Assign unique voices for party mode? → ${GREEN}Yes${NC}" +echo "" +echo -e "${YELLOW}AgentVibes will start automatically after BMAD installation.${NC}" +echo -e "${YELLOW}Recommended TTS settings:${NC}" +echo -e " • Provider: ${GREEN}Piper${NC} (free, local TTS)" +echo -e " • Download voices: ${GREEN}Yes${NC}" +echo "" +read -p "Press Enter to start BMAD installer..." +node "$TEST_DIR/BMAD-METHOD/tools/cli/bin/bmad.js" install + +echo "" +echo -e "${GREEN}✓ BMAD and AgentVibes installation complete${NC}" +echo "" + +# Step 6: Verification +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "✅ Step 6/6: Verifying installation" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +VERIFICATION_PASSED=true + +# Check for voice map file +if [[ -f ".bmad/_cfg/agent-voice-map.csv" ]]; then + echo -e "${GREEN}✓ Voice map file created${NC}" + echo " Location: .bmad/_cfg/agent-voice-map.csv" + echo "" + echo " Voice assignments:" + cat .bmad/_cfg/agent-voice-map.csv | sed 's/^/ /' + echo "" +else + echo -e "${RED}✗ Voice map file NOT found${NC}" + echo " Expected: .bmad/_cfg/agent-voice-map.csv" + echo " ${YELLOW}Warning: Agents may not have unique voices!${NC}" + echo "" + VERIFICATION_PASSED=false +fi + +# Check for AgentVibes hooks +if [[ -f ".claude/hooks/bmad-speak.sh" ]]; then + echo -e "${GREEN}✓ BMAD TTS hooks installed${NC}" + echo " Location: .claude/hooks/bmad-speak.sh" +else + echo -e "${RED}✗ BMAD TTS hooks NOT found${NC}" + echo " Expected: .claude/hooks/bmad-speak.sh" + VERIFICATION_PASSED=false +fi +echo "" + +# Check for Piper installation +if command -v piper &> /dev/null; then + PIPER_VERSION=$(piper --version 2>&1 || echo "unknown") + echo -e "${GREEN}✓ Piper TTS installed${NC}" + echo " Version: $PIPER_VERSION" +elif [[ -f ".agentvibes/providers/piper/piper" ]]; then + echo -e "${GREEN}✓ Piper TTS installed (local)${NC}" + echo " Location: .agentvibes/providers/piper/piper" +else + echo -e "${YELLOW}⚠ Piper not detected${NC}" + echo " (May still work if using ElevenLabs)" +fi +echo "" + +# Final status +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +if [[ "$VERIFICATION_PASSED" == true ]]; then + echo -e "${GREEN}🎉 Setup Complete - All Checks Passed!${NC}" +else + echo -e "${YELLOW}⚠️ Setup Complete - With Warnings${NC}" + echo "" + echo "Some verification checks failed. The installation may still work," + echo "but you might experience issues with party mode voices." +fi +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" +echo -e "${BLUE}Next Steps:${NC}" +echo "" +echo " 1. Navigate to test project:" +echo -e " ${GREEN}cd $TEST_DIR/bmad-project${NC}" +echo "" +echo " 2. Start Claude session:" +echo -e " ${GREEN}claude${NC}" +echo "" +echo " 3. Test party mode:" +echo -e " ${GREEN}/bmad:core:workflows:party-mode${NC}" +echo "" +echo " 4. Verify each agent speaks with a unique voice!" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo -e "${BLUE}Troubleshooting:${NC}" +echo "" +echo " • No audio? Check: .claude/hooks/play-tts.sh exists" +echo " • Same voice for all agents? Check: .bmad/_cfg/agent-voice-map.csv" +echo " • Test current voice: /agent-vibes:whoami" +echo " • List available voices: /agent-vibes:list" +echo "" +echo -e "${BLUE}Report Issues:${NC}" +echo " https://github.com/bmad-code-org/BMAD-METHOD/pull/934" +echo "" +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" diff --git a/tools/cli/commands/install.js b/tools/cli/commands/install.js index d2706ee6..a9d484d5 100644 --- a/tools/cli/commands/install.js +++ b/tools/cli/commands/install.js @@ -59,6 +59,46 @@ module.exports = { console.log(chalk.cyan('BMAD Core and Selected Modules have been installed to:'), chalk.bold(result.path)); 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!')); + + // Run AgentVibes installer if needed + if (result.needsAgentVibes) { + console.log(chalk.magenta('\n🎙️ 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 readline = require('node:readline'); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + await new Promise((resolve) => { + rl.question(chalk.green('Press Enter to start AgentVibes installer...'), () => { + rl.close(); + resolve(); + }); + }); + + 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')); + } 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')); + } + } + process.exit(0); } } catch (error) { diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 7473a307..8539ebbe 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -1,3 +1,23 @@ +/** + * File: tools/cli/installers/lib/core/installer.js + * + * BMAD Method - Business Model Agile Development Method + * Repository: https://github.com/paulpreibisch/BMAD-METHOD + * + * Copyright (c) 2025 Paul Preibisch + * Licensed under the Apache License, Version 2.0 + * + * --- + * + * @fileoverview Core BMAD installation orchestrator with AgentVibes injection point support + * @context Manages complete BMAD installation flow including core agents, modules, IDE configs, and optional TTS integration + * @architecture Orchestrator pattern - coordinates Detector, ModuleManager, IdeManager, and file operations to build complete BMAD installation + * @dependencies fs-extra, ora, chalk, detector.js, module-manager.js, ide-manager.js, config.js + * @entrypoints Called by install.js command via installer.install(config) + * @patterns Injection point processing (AgentVibes), placeholder replacement ({bmad_folder}), module dependency resolution + * @related GitHub AgentVibes#34 (injection points), ui.js (user prompts), copyFileWithPlaceholderReplacement() + */ + const path = require('node:path'); const fs = require('fs-extra'); const chalk = require('chalk'); @@ -69,10 +89,41 @@ class Installer { } /** - * Copy a file and replace {bmad_folder} placeholder with actual folder name - * @param {string} sourcePath - Source file path - * @param {string} targetPath - Target file path - * @param {string} bmadFolderName - The bmad folder name to use for replacement + * @function copyFileWithPlaceholderReplacement + * @intent Copy files from BMAD source to installation directory with dynamic content transformation + * @why Enables installation-time customization: {bmad_folder} replacement + optional AgentVibes TTS injection + * @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') + * @returns {Promise} Resolves when file copy and transformation complete + * @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() + * + * AI NOTE: This is the core transformation pipeline for ALL BMAD installation file copies. + * It performs two transformations in sequence: + * 1. {bmad_folder} → user's custom folder name (e.g., ".bmad" or "bmad") + * 2. → TTS bash calls (if enabled) OR stripped (if disabled) + * + * 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) */ async copyFileWithPlaceholderReplacement(sourcePath, targetPath, bmadFolderName) { // List of text file extensions that should have placeholder replacement @@ -90,6 +141,9 @@ class Installer { content = content.replaceAll('{bmad_folder}', bmadFolderName); } + // Process AgentVibes injection points + content = this.processTTSInjectionPoints(content); + // Write to target with replaced content await fs.ensureDir(path.dirname(targetPath)); await fs.writeFile(targetPath, content, 'utf8'); @@ -103,6 +157,106 @@ 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) { + // Check if AgentVibes is enabled (set during installation configuration) + const enableAgentVibes = this.enableAgentVibes || false; + + 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`, + ); + } 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 @@ -271,6 +425,9 @@ class Installer { const bmadFolderName = moduleConfigs.core && moduleConfigs.core.bmad_folder ? moduleConfigs.core.bmad_folder : 'bmad'; this.bmadFolderName = bmadFolderName; // Store for use in other methods + // 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(bmadFolderName); this.ideManager.setBmadFolderName(bmadFolderName); @@ -861,7 +1018,14 @@ class Installer { customFiles: customFiles.length > 0 ? customFiles : undefined, }); - return { success: true, path: bmadDir, modules: config.modules, ides: config.ides }; + return { + success: true, + path: bmadDir, + modules: config.modules, + ides: config.ides, + needsAgentVibes: this.enableAgentVibes && !config.agentVibesInstalled, + projectDir: projectDir, + }; } catch (error) { spinner.fail('Installation failed'); throw error; diff --git a/tools/cli/lib/ui.js b/tools/cli/lib/ui.js index 8de8825e..730ce4f9 100644 --- a/tools/cli/lib/ui.js +++ b/tools/cli/lib/ui.js @@ -1,3 +1,23 @@ +/** + * File: tools/cli/lib/ui.js + * + * BMAD Method - Business Model Agile Development Method + * Repository: https://github.com/paulpreibisch/BMAD-METHOD + * + * Copyright (c) 2025 Paul Preibisch + * Licensed under the Apache License, Version 2.0 + * + * --- + * + * @fileoverview Interactive installation prompts and user input collection for BMAD CLI + * @context Guides users through installation configuration including core settings, modules, IDEs, and optional AgentVibes TTS + * @architecture Facade pattern - presents unified installation flow, delegates to Detector/ConfigCollector/IdeManager for specifics + * @dependencies inquirer (prompts), chalk (formatting), detector.js (existing installation detection) + * @entrypoints Called by install.js command via ui.promptInstall(), returns complete configuration object + * @patterns Progressive disclosure (prompts in order), early IDE selection (Windows compat), AgentVibes auto-detection + * @related installer.js (consumes config), AgentVibes#34 (TTS integration), promptAgentVibes() + */ + const chalk = require('chalk'); const inquirer = require('inquirer'); const path = require('node:path'); @@ -99,6 +119,9 @@ 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); @@ -114,6 +137,8 @@ class UI { ides: toolSelection.ides, skipIde: toolSelection.skipIde, coreConfig: coreConfig, // Pass collected core config to installer + enableAgentVibes: agentVibesConfig.enabled, // AgentVibes TTS integration + agentVibesInstalled: agentVibesConfig.alreadyInstalled, }; } @@ -639,6 +664,140 @@ class UI { // Resolve to the absolute path relative to the current working directory 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(), inquirer.prompt(), chalk.green/yellow/dim() + * + * AI NOTE: This prompt is strategically positioned in installation flow: + * - AFTER core config (bmad_folder, 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 answers = await inquirer.prompt([ + { + type: 'confirm', + name: 'enableTts', + message: 'Enable AgentVibes TTS? (Agents speak with unique voices in party mode)', + default: true, // Default to yes - recommended for best experience + }, + ]); + + 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')); + } + + return { + enabled: answers.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)); + } } module.exports = { UI }; From 2cac74cfb559ab4d1e73312f7e6b7f1580954ba9 Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Wed, 26 Nov 2025 11:00:46 -0600 Subject: [PATCH 3/4] agent vibes injection and installer update --- .gitignore | 3 ++- src/core/workflows/party-mode/instructions.md | 10 ++-------- tools/cli/lib/ui.js | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 581f725e..cef2ce1a 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,5 @@ z*/ .claude .codex .github/chatmodes -.agent \ No newline at end of file +.agent +.agentvibes/ \ No newline at end of file diff --git a/src/core/workflows/party-mode/instructions.md b/src/core/workflows/party-mode/instructions.md index 6afd5ede..3289f0a7 100644 --- a/src/core/workflows/party-mode/instructions.md +++ b/src/core/workflows/party-mode/instructions.md @@ -2,6 +2,7 @@ The workflow execution engine is governed by: {project_root}/{bmad_folder}/core/tasks/workflow.xml This workflow orchestrates group discussions between all installed BMAD agents + @@ -97,14 +98,7 @@ For each agent response, output text THEN trigger their voice: - - 1. Output the agent's text in format: [Icon Emoji] [Agent Name]: [dialogue] - 2. 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 - 3. Repeat for each agent in the response - + [Icon Emoji] [Agent Name]: [Their response in their voice/style] diff --git a/tools/cli/lib/ui.js b/tools/cli/lib/ui.js index 730ce4f9..788349b5 100644 --- a/tools/cli/lib/ui.js +++ b/tools/cli/lib/ui.js @@ -720,7 +720,7 @@ class UI { { type: 'confirm', name: 'enableTts', - message: 'Enable AgentVibes TTS? (Agents speak with unique voices in party mode)', + message: 'Enable AgentVibes TTS? (Claude Code only - Agents speak with unique voices in party mode)', default: true, // Default to yes - recommended for best experience }, ]); From 9223e2be21a8f55fc31c9e23f5d74e116eb2ddc8 Mon Sep 17 00:00:00 2001 From: fikri-kompanion <101977604+fikri-kompanion@users.noreply.github.com> Date: Thu, 27 Nov 2025 03:48:16 +0800 Subject: [PATCH 4/4] fix: give kilocode tool access to bmad modes (#961) Co-authored-by: Ahmad Fikrizaman Co-authored-by: Brian --- tools/cli/installers/lib/ide/kilo.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/cli/installers/lib/ide/kilo.js b/tools/cli/installers/lib/ide/kilo.js index 601cfc0a..66cb8c37 100644 --- a/tools/cli/installers/lib/ide/kilo.js +++ b/tools/cli/installers/lib/ide/kilo.js @@ -123,6 +123,9 @@ class KiloSetup extends BaseIdeSetup { modeEntry += ` groups:\n`; modeEntry += ` - read\n`; modeEntry += ` - edit\n`; + modeEntry += ` - browser\n`; + modeEntry += ` - command\n`; + modeEntry += ` - mcp\n`; return modeEntry; }