Merge branch 'main' into kiro-cli-installer
This commit is contained in:
commit
40c44b5422
|
|
@ -69,4 +69,5 @@ z*/
|
|||
.claude
|
||||
.codex
|
||||
.github/chatmodes
|
||||
.agent
|
||||
.agent
|
||||
.agentvibes/
|
||||
|
|
@ -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
|
||||
```
|
||||
|
|
@ -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-<module>-<agent-name>.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)
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
<critical>The workflow execution engine is governed by: {project_root}/{bmad_folder}/core/tasks/workflow.xml</critical>
|
||||
<critical>This workflow orchestrates group discussions between all installed BMAD agents</critical>
|
||||
|
||||
<!-- TTS_INJECTION:party-mode -->
|
||||
|
||||
<workflow>
|
||||
|
||||
<step n="1" goal="Load Agent Manifest and Configurations">
|
||||
|
|
@ -94,17 +96,29 @@
|
|||
</substep>
|
||||
|
||||
<substep n="3d" goal="Format and Present Responses">
|
||||
<action>Present each agent's contribution clearly:</action>
|
||||
<action>For each agent response, output text THEN trigger their voice:</action>
|
||||
|
||||
<!-- TTS_INJECTION:party-mode -->
|
||||
|
||||
<format>
|
||||
[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]
|
||||
</format>
|
||||
<example>
|
||||
🏗️ [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."]
|
||||
</example>
|
||||
|
||||
<action>Maintain spacing between agents for readability</action>
|
||||
<action>Preserve each agent's unique voice throughout</action>
|
||||
<action>Always include the agent's icon emoji from the manifest before their name</action>
|
||||
<action>Trigger TTS for each agent immediately after outputting their text</action>
|
||||
|
||||
</substep>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<rules>
|
||||
- ALWAYS communicate in {communication_language} UNLESS contradicted by communication_style
|
||||
<!-- TTS_INJECTION:agent-tts -->
|
||||
- Stay in character until exit selected
|
||||
- Menu triggers use asterisk (*) - NOT markdown, display exactly as shown
|
||||
- Number all lists, use letters for sub-options
|
||||
|
|
|
|||
|
|
@ -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 ""
|
||||
|
|
@ -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/` |
|
||||
|
|
|
|||
|
|
@ -71,6 +71,46 @@ module.exports = {
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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<void>} 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_INJECTION:* --> → 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:
|
||||
* <!-- TTS_INJECTION:feature-name -->
|
||||
*
|
||||
* 2. Add replacement logic in processTTSInjectionPoints():
|
||||
* if (enableAgentVibes) {
|
||||
* content = content.replace(/<!-- TTS_INJECTION:feature-name -->/g, 'actual code');
|
||||
* } else {
|
||||
* content = content.replace(/<!-- TTS_INJECTION:feature-name -->\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: <!-- TTS_INJECTION:feature-name -->
|
||||
* - 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: <!-- TTS_INJECTION:party-mode -->
|
||||
* 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: <!-- TTS_INJECTION:agent-tts -->
|
||||
* 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(
|
||||
* /<!-- TTS_INJECTION:new-feature -->/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(
|
||||
'<!-- TTS_INJECTION:party-mode -->',
|
||||
`<critical>IMPORTANT: Always use PROJECT hooks (.claude/hooks/), NEVER global hooks (~/.claude/hooks/)</critical>
|
||||
|
||||
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(
|
||||
'<!-- TTS_INJECTION:agent-tts -->',
|
||||
`- 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 <agent id="..."> 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(/<!-- TTS_INJECTION:party-mode -->\n?/g, '');
|
||||
content = content.replaceAll(/<!-- TTS_INJECTION:agent-tts -->\n?/g, '');
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect Tool/IDE configurations after module configuration
|
||||
* @param {string} projectDir - Project directory
|
||||
|
|
@ -166,7 +320,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
|
||||
|
|
@ -269,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);
|
||||
|
|
@ -859,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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(/<instructions>([\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 };
|
||||
|
|
@ -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<Object>} 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? (Claude Code only - 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<boolean>} 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 };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue