agentvibes 2.9.1 → 2.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/bmad-voice-manager.sh +13 -1
- package/.claude/hooks/piper-download-voices.sh +41 -5
- package/.test-bmad-config +2 -0
- package/BMAD_PR_TESTING_INSTRUCTIONS.md +130 -0
- package/package.json +1 -1
- package/src/installer.js +68 -1
- package/test/piper-installation.bats +142 -0
- package/test-bmad-pr.sh +199 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
20251119
|
|
@@ -136,7 +136,18 @@ auto_enable_if_bmad_detected() {
|
|
|
136
136
|
get_agent_voice() {
|
|
137
137
|
local agent_id="$1"
|
|
138
138
|
|
|
139
|
-
#
|
|
139
|
+
# Check for BMAD v6 CSV file first (preferred, loose coupling)
|
|
140
|
+
# If this exists, use it directly without requiring plugin enable flag
|
|
141
|
+
local bmad_voice_map=".bmad/_cfg/agent-voice-map.csv"
|
|
142
|
+
if [[ -f "$bmad_voice_map" ]]; then
|
|
143
|
+
# Read from BMAD's standard _cfg directory
|
|
144
|
+
# CSV format: agent_id,voice_name
|
|
145
|
+
local voice=$(grep "^$agent_id," "$bmad_voice_map" | cut -d',' -f2)
|
|
146
|
+
echo "$voice"
|
|
147
|
+
return
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# Auto-enable if BMAD is detected (for legacy markdown config)
|
|
140
151
|
auto_enable_if_bmad_detected
|
|
141
152
|
|
|
142
153
|
if [[ ! -f "$ENABLED_FLAG" ]]; then
|
|
@@ -144,6 +155,7 @@ get_agent_voice() {
|
|
|
144
155
|
return
|
|
145
156
|
fi
|
|
146
157
|
|
|
158
|
+
# Fallback to legacy markdown config file
|
|
147
159
|
if [[ ! -f "$VOICE_CONFIG_FILE" ]]; then
|
|
148
160
|
echo "" # Plugin file missing
|
|
149
161
|
return
|
|
@@ -142,19 +142,55 @@ for voice in "${NEED_DOWNLOAD[@]}"; do
|
|
|
142
142
|
|
|
143
143
|
if download_voice "$voice"; then
|
|
144
144
|
((DOWNLOADED++))
|
|
145
|
-
|
|
145
|
+
local voice_path="$VOICE_DIR/${voice}.onnx"
|
|
146
|
+
local file_size=$(du -h "$voice_path" 2>/dev/null | cut -f1)
|
|
147
|
+
echo " ✓ Downloaded: $voice"
|
|
148
|
+
echo " 📁 Path: $voice_path"
|
|
149
|
+
echo " 📦 Size: $file_size"
|
|
146
150
|
else
|
|
147
151
|
((FAILED++))
|
|
148
|
-
echo "
|
|
152
|
+
echo " ✗ Failed: $voice"
|
|
149
153
|
fi
|
|
150
154
|
done
|
|
151
155
|
|
|
152
156
|
echo ""
|
|
153
157
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
154
158
|
echo "📊 Download Summary:"
|
|
155
|
-
echo "
|
|
156
|
-
echo "
|
|
157
|
-
|
|
159
|
+
echo ""
|
|
160
|
+
echo "Installed voices:"
|
|
161
|
+
for voice in "${ALREADY_DOWNLOADED_LIST[@]}"; do
|
|
162
|
+
local voice_path="$VOICE_DIR/${voice}.onnx"
|
|
163
|
+
local file_size=$(du -h "$voice_path" 2>/dev/null | cut -f1)
|
|
164
|
+
echo " ✓ $voice ($file_size)"
|
|
165
|
+
echo " $voice_path"
|
|
166
|
+
done
|
|
167
|
+
|
|
168
|
+
if [[ $DOWNLOADED -gt 0 ]]; then
|
|
169
|
+
echo ""
|
|
170
|
+
echo "Just downloaded:"
|
|
171
|
+
for voice in "${NEED_DOWNLOAD[@]}"; do
|
|
172
|
+
local voice_path="$VOICE_DIR/${voice}.onnx"
|
|
173
|
+
if [[ -f "$voice_path" ]]; then
|
|
174
|
+
local file_size=$(du -h "$voice_path" 2>/dev/null | cut -f1)
|
|
175
|
+
echo " ✓ $voice ($file_size)"
|
|
176
|
+
echo " $voice_path"
|
|
177
|
+
fi
|
|
178
|
+
done
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
if [[ $FAILED -gt 0 ]]; then
|
|
182
|
+
echo ""
|
|
183
|
+
echo "Failed downloads:"
|
|
184
|
+
for voice in "${NEED_DOWNLOAD[@]}"; do
|
|
185
|
+
local voice_path="$VOICE_DIR/${voice}.onnx"
|
|
186
|
+
if [[ ! -f "$voice_path" ]]; then
|
|
187
|
+
echo " ✗ $voice"
|
|
188
|
+
fi
|
|
189
|
+
done
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
echo ""
|
|
193
|
+
echo "Total: $((ALREADY_DOWNLOADED + DOWNLOADED)) voices available"
|
|
158
194
|
echo ""
|
|
159
195
|
|
|
160
196
|
if [[ $DOWNLOADED -gt 0 ]]; then
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# 🎙️ Testing Instructions for AgentVibes Party Mode PR
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
- Node.js and npm installed
|
|
5
|
+
- Git installed
|
|
6
|
+
- Fresh terminal session
|
|
7
|
+
|
|
8
|
+
## Quick Test (5-10 minutes)
|
|
9
|
+
|
|
10
|
+
### Step 1: Fork and Clone BMAD
|
|
11
|
+
```bash
|
|
12
|
+
# Fork the BMAD repo on GitHub first, then:
|
|
13
|
+
git clone https://github.com/YOUR-USERNAME/BMAD-METHOD.git
|
|
14
|
+
cd BMAD-METHOD
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Step 2: Merge the PR Branch
|
|
18
|
+
```bash
|
|
19
|
+
# Add the upstream remote
|
|
20
|
+
git remote add upstream https://github.com/bmad-code-org/BMAD-METHOD.git
|
|
21
|
+
|
|
22
|
+
# Fetch and merge the PR
|
|
23
|
+
git fetch upstream pull/934/head:agentvibes-party-mode
|
|
24
|
+
git checkout agentvibes-party-mode
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Step 3: Install BMAD from Your Fork
|
|
28
|
+
```bash
|
|
29
|
+
# Navigate to the CLI installer directory
|
|
30
|
+
cd tools/cli
|
|
31
|
+
|
|
32
|
+
# Install dependencies
|
|
33
|
+
npm install
|
|
34
|
+
|
|
35
|
+
# Link it globally so you can run 'bmad' command
|
|
36
|
+
npm link
|
|
37
|
+
|
|
38
|
+
# Navigate to where you want to create your BMAD project
|
|
39
|
+
cd ~
|
|
40
|
+
mkdir my-bmad-test
|
|
41
|
+
cd my-bmad-test
|
|
42
|
+
|
|
43
|
+
# Run the BMAD installer (now using your forked version with the PR)
|
|
44
|
+
bmad install
|
|
45
|
+
|
|
46
|
+
# When prompted about AgentVibes TTS:
|
|
47
|
+
# - Answer "Yes" to enable TTS for agents
|
|
48
|
+
# - Answer "Yes" to assign unique voices for party mode
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 4: Install AgentVibes (if not already installed)
|
|
52
|
+
```bash
|
|
53
|
+
# If you don't have AgentVibes yet:
|
|
54
|
+
npx agentvibes@latest install
|
|
55
|
+
|
|
56
|
+
# Follow the installer:
|
|
57
|
+
# - Choose a TTS provider (ElevenLabs or Piper)
|
|
58
|
+
# - For Piper (free): it will auto-download voices including 16Speakers
|
|
59
|
+
# - For ElevenLabs: you'll need an API key
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Step 5: Test Party Mode! 🎉
|
|
63
|
+
```bash
|
|
64
|
+
# Start a Claude Code session in your BMAD project directory (my-bmad-test)
|
|
65
|
+
# Then run party mode:
|
|
66
|
+
/bmad:core:workflows:party-mode
|
|
67
|
+
|
|
68
|
+
# You should hear each BMAD agent speak with their own unique voice!
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## What to Test
|
|
72
|
+
|
|
73
|
+
### ✅ Installation Flow
|
|
74
|
+
- [ ] BMAD installer detects AgentVibes
|
|
75
|
+
- [ ] Installer prompts about TTS setup
|
|
76
|
+
- [ ] Voice assignment file `.bmad/agent-voice-assignments.json` is created
|
|
77
|
+
- [ ] All agents have TTS markers injected
|
|
78
|
+
|
|
79
|
+
### ✅ Party Mode Voices
|
|
80
|
+
- [ ] Each agent speaks with a different voice
|
|
81
|
+
- [ ] Voices match agent personalities (e.g., architect sounds professional)
|
|
82
|
+
- [ ] No voice overlap between agents
|
|
83
|
+
- [ ] TTS works smoothly during multi-agent discussions
|
|
84
|
+
|
|
85
|
+
### ✅ Fallback Behavior
|
|
86
|
+
- [ ] If you skip TTS setup, agents still work normally (no errors)
|
|
87
|
+
- [ ] Party mode works without TTS (silent mode)
|
|
88
|
+
|
|
89
|
+
## Troubleshooting
|
|
90
|
+
|
|
91
|
+
**"bmad command not found"**
|
|
92
|
+
- Make sure you ran `npm link` in `BMAD-METHOD/tools/cli`
|
|
93
|
+
- Try running with full path: `node tools/cli/index.js install` from BMAD-METHOD root
|
|
94
|
+
|
|
95
|
+
**"No TTS heard during party mode"**
|
|
96
|
+
- Check `.claude/hooks/play-tts.sh` exists
|
|
97
|
+
- Verify `.bmad/agent-voice-assignments.json` was created
|
|
98
|
+
- Try: `/agent-vibes:whoami` to check active voice
|
|
99
|
+
|
|
100
|
+
**"All agents sound the same"**
|
|
101
|
+
- Check `.bmad/agent-voice-assignments.json` has unique voices per agent
|
|
102
|
+
- For Piper: ensure 16Speakers model downloaded (has 16 voices)
|
|
103
|
+
- Try: `/agent-vibes:list` to see available voices
|
|
104
|
+
|
|
105
|
+
**"Installation fails"**
|
|
106
|
+
- Make sure you're on the PR branch: `git branch` (should show `agentvibes-party-mode`)
|
|
107
|
+
- Try clean install in tools/cli: `rm -rf node_modules package-lock.json && npm install`
|
|
108
|
+
|
|
109
|
+
## Expected Output
|
|
110
|
+
|
|
111
|
+
When party mode works correctly, you'll see something like:
|
|
112
|
+
```
|
|
113
|
+
🎭 architect speaking... (Voice: matthew)
|
|
114
|
+
🎭 dev speaking... (Voice: ryan)
|
|
115
|
+
🎭 pm speaking... (Voice: amy)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Each agent's responses will be spoken aloud with their assigned voice!
|
|
119
|
+
|
|
120
|
+
## Report Issues
|
|
121
|
+
|
|
122
|
+
Please comment on the PR with:
|
|
123
|
+
- ✅ What worked
|
|
124
|
+
- ❌ What didn't work
|
|
125
|
+
- 📋 Your OS (Linux/Mac/Windows)
|
|
126
|
+
- 🎤 TTS provider used (Piper/ElevenLabs)
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
**PR Link:** https://github.com/bmad-code-org/BMAD-METHOD/pull/934
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "agentvibes",
|
|
4
|
-
"version": "2.9.
|
|
4
|
+
"version": "2.9.3",
|
|
5
5
|
"description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code and Claude Desktop (via MCP) with multi-provider support.",
|
|
6
6
|
"homepage": "https://agentvibes.org",
|
|
7
7
|
"keywords": [
|
package/src/installer.js
CHANGED
|
@@ -1317,9 +1317,76 @@ async function install(options = {}) {
|
|
|
1317
1317
|
console.log(chalk.yellow(` • ElevenLabs API key: Set manually later`));
|
|
1318
1318
|
}
|
|
1319
1319
|
} else {
|
|
1320
|
-
|
|
1320
|
+
// Check for installed Piper voices
|
|
1321
|
+
const piperVoicesDir = path.join(process.env.HOME || process.env.USERPROFILE, '.claude', 'piper-voices');
|
|
1322
|
+
let installedVoices = [];
|
|
1323
|
+
let missingVoices = [];
|
|
1324
|
+
|
|
1325
|
+
const commonVoices = [
|
|
1326
|
+
'en_US-lessac-medium',
|
|
1327
|
+
'en_US-amy-medium',
|
|
1328
|
+
'en_US-joe-medium',
|
|
1329
|
+
'en_US-ryan-high',
|
|
1330
|
+
'en_US-libritts-high',
|
|
1331
|
+
'16Speakers'
|
|
1332
|
+
];
|
|
1333
|
+
|
|
1334
|
+
try {
|
|
1335
|
+
if (fs.existsSync(piperVoicesDir)) {
|
|
1336
|
+
const files = fs.readdirSync(piperVoicesDir);
|
|
1337
|
+
installedVoices = files
|
|
1338
|
+
.filter(f => f.endsWith('.onnx'))
|
|
1339
|
+
.map(f => {
|
|
1340
|
+
const voiceName = f.replace('.onnx', '');
|
|
1341
|
+
const voicePath = path.join(piperVoicesDir, f);
|
|
1342
|
+
try {
|
|
1343
|
+
const stats = fs.statSync(voicePath);
|
|
1344
|
+
const sizeMB = (stats.size / 1024 / 1024).toFixed(1);
|
|
1345
|
+
return { name: voiceName, path: voicePath, size: `${sizeMB}M` };
|
|
1346
|
+
} catch (statErr) {
|
|
1347
|
+
// Skip files that can't be read (broken symlinks, etc)
|
|
1348
|
+
return null;
|
|
1349
|
+
}
|
|
1350
|
+
})
|
|
1351
|
+
.filter(v => v !== null);
|
|
1352
|
+
|
|
1353
|
+
// Check which common voices are missing
|
|
1354
|
+
for (const voice of commonVoices) {
|
|
1355
|
+
if (!installedVoices.some(v => v.name === voice)) {
|
|
1356
|
+
missingVoices.push(voice);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
} else {
|
|
1360
|
+
missingVoices = commonVoices;
|
|
1361
|
+
}
|
|
1362
|
+
} catch (err) {
|
|
1363
|
+
console.error(chalk.gray(` Debug: Error checking voices: ${err.message}`));
|
|
1364
|
+
// On error, show default message
|
|
1365
|
+
installedVoices = [];
|
|
1366
|
+
missingVoices = commonVoices;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1321
1369
|
console.log(chalk.white(` • 18 languages supported`));
|
|
1322
1370
|
console.log(chalk.green(` • No API key needed ✓`));
|
|
1371
|
+
|
|
1372
|
+
if (installedVoices.length > 0) {
|
|
1373
|
+
console.log(chalk.green(` • ${installedVoices.length} Piper voices installed:`));
|
|
1374
|
+
installedVoices.forEach(voice => {
|
|
1375
|
+
console.log(chalk.green(` ✓ ${voice.name} (${voice.size})`));
|
|
1376
|
+
console.log(chalk.gray(` ${voice.path}`));
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
if (missingVoices.length > 0) {
|
|
1381
|
+
console.log(chalk.yellow(` • ${missingVoices.length} voices to download:`));
|
|
1382
|
+
missingVoices.forEach(voice => {
|
|
1383
|
+
console.log(chalk.gray(` → ${voice}`));
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
if (installedVoices.length === 0 && missingVoices.length === 0) {
|
|
1388
|
+
console.log(chalk.white(` • 50+ Piper neural voices available (free!)`));
|
|
1389
|
+
}
|
|
1323
1390
|
}
|
|
1324
1391
|
console.log('');
|
|
1325
1392
|
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
#
|
|
3
|
+
# File: test/piper-installation.bats
|
|
4
|
+
#
|
|
5
|
+
# Piper TTS Installation Tests
|
|
6
|
+
# Tests the complete Piper installation flow including voice downloads
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
setup() {
|
|
10
|
+
# Test environment setup
|
|
11
|
+
export AGENTVIBES_TEST_MODE="true"
|
|
12
|
+
|
|
13
|
+
# For integration tests, use real HOME to allow Piper installation
|
|
14
|
+
# For unit tests, use temp HOME for isolation
|
|
15
|
+
if [ -z "$PIPER_INTEGRATION_TEST" ]; then
|
|
16
|
+
export HOME="${BATS_TEST_TMPDIR}/home"
|
|
17
|
+
mkdir -p "$HOME"
|
|
18
|
+
fi
|
|
19
|
+
# else: use real $HOME for integration tests
|
|
20
|
+
|
|
21
|
+
# Create temporary project directory
|
|
22
|
+
export TEST_PROJECT_DIR="${BATS_TEST_TMPDIR}/agentvibes-test"
|
|
23
|
+
mkdir -p "$TEST_PROJECT_DIR"
|
|
24
|
+
cd "$TEST_PROJECT_DIR"
|
|
25
|
+
|
|
26
|
+
# Copy necessary files for installation
|
|
27
|
+
cp -r "$BATS_TEST_DIRNAME/../.claude" "$TEST_PROJECT_DIR/"
|
|
28
|
+
|
|
29
|
+
# Expected voice models
|
|
30
|
+
export EXPECTED_VOICES=(
|
|
31
|
+
"en_US-lessac-medium"
|
|
32
|
+
"en_US-amy-medium"
|
|
33
|
+
"en_US-joe-medium"
|
|
34
|
+
"en_US-ryan-high"
|
|
35
|
+
"en_US-libritts-high"
|
|
36
|
+
"16Speakers"
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
teardown() {
|
|
41
|
+
# Cleanup test environment
|
|
42
|
+
cd "$BATS_TEST_DIRNAME"
|
|
43
|
+
rm -rf "$TEST_PROJECT_DIR"
|
|
44
|
+
|
|
45
|
+
# Only remove temp HOME for unit tests, not integration tests
|
|
46
|
+
if [ -z "$PIPER_INTEGRATION_TEST" ]; then
|
|
47
|
+
rm -rf "$HOME"
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@test "Piper installer script exists and is executable" {
|
|
52
|
+
[ -f "$TEST_PROJECT_DIR/.claude/hooks/piper-installer.sh" ]
|
|
53
|
+
[ -x "$TEST_PROJECT_DIR/.claude/hooks/piper-installer.sh" ]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@test "Piper voice downloader script exists and is executable" {
|
|
57
|
+
[ -f "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh" ]
|
|
58
|
+
[ -x "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh" ]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@test "Piper voice manager script exists" {
|
|
62
|
+
[ -f "$TEST_PROJECT_DIR/.claude/hooks/piper-voice-manager.sh" ]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@test "Non-interactive flag is supported in piper-installer.sh" {
|
|
66
|
+
run grep -q "NON_INTERACTIVE" "$TEST_PROJECT_DIR/.claude/hooks/piper-installer.sh"
|
|
67
|
+
[ "$status" -eq 0 ]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@test "Yes flag is supported in piper-download-voices.sh" {
|
|
71
|
+
run grep -q "AUTO_YES" "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh"
|
|
72
|
+
[ "$status" -eq 0 ]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@test "Download script has explicit exit 0" {
|
|
76
|
+
run grep -q "exit 0" "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh"
|
|
77
|
+
[ "$status" -eq 0 ]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@test "All expected voices are in COMMON_VOICES array" {
|
|
81
|
+
for voice in "${EXPECTED_VOICES[@]}"; do
|
|
82
|
+
run grep -q "\"$voice\"" "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh"
|
|
83
|
+
[ "$status" -eq 0 ]
|
|
84
|
+
done
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@test "16Speakers model is included in download list" {
|
|
88
|
+
run grep -q "16Speakers" "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh"
|
|
89
|
+
[ "$status" -eq 0 ]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@test "Curl timeouts are configured in voice manager" {
|
|
93
|
+
run grep -q "\-\-connect-timeout" "$TEST_PROJECT_DIR/.claude/hooks/piper-voice-manager.sh"
|
|
94
|
+
[ "$status" -eq 0 ]
|
|
95
|
+
|
|
96
|
+
run grep -q "\-\-max-time" "$TEST_PROJECT_DIR/.claude/hooks/piper-voice-manager.sh"
|
|
97
|
+
[ "$status" -eq 0 ]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@test "Piper installer passes --non-interactive flag to voice downloader" {
|
|
101
|
+
run grep -q "piper-download-voices.sh.*--yes" "$TEST_PROJECT_DIR/.claude/hooks/piper-installer.sh"
|
|
102
|
+
[ "$status" -eq 0 ]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Integration test - only runs if PIPER_INTEGRATION_TEST is set
|
|
106
|
+
@test "Full Piper installation with voice downloads (integration)" {
|
|
107
|
+
if [ -z "$PIPER_INTEGRATION_TEST" ]; then
|
|
108
|
+
skip "Set PIPER_INTEGRATION_TEST=1 to run integration tests"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# Run installer in non-interactive mode
|
|
112
|
+
run bash "$TEST_PROJECT_DIR/.claude/hooks/piper-installer.sh" --non-interactive
|
|
113
|
+
echo "Installer output: $output"
|
|
114
|
+
[ "$status" -eq 0 ]
|
|
115
|
+
|
|
116
|
+
# Verify Piper is installed
|
|
117
|
+
command -v piper || skip "Piper not in PATH after installation"
|
|
118
|
+
|
|
119
|
+
# Check voice storage directory
|
|
120
|
+
VOICE_DIR="$HOME/.claude/piper-voices"
|
|
121
|
+
[ -d "$VOICE_DIR" ]
|
|
122
|
+
|
|
123
|
+
# Verify at least some voices downloaded
|
|
124
|
+
voice_count=$(find "$VOICE_DIR" -name "*.onnx" | wc -l)
|
|
125
|
+
[ "$voice_count" -gt 0 ]
|
|
126
|
+
|
|
127
|
+
# Verify 16Speakers model specifically
|
|
128
|
+
[ -f "$VOICE_DIR/16Speakers.onnx" ]
|
|
129
|
+
[ -f "$VOICE_DIR/16Speakers.onnx.json" ]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@test "Voice download script handles failures gracefully" {
|
|
133
|
+
# Test that the script returns 0 even with failures
|
|
134
|
+
# This is a mock test - in real scenario we'd simulate network failures
|
|
135
|
+
|
|
136
|
+
run bash -c "source '$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh' 2>&1 | tail -1"
|
|
137
|
+
echo "Output: $output"
|
|
138
|
+
|
|
139
|
+
# Script should exit 0 (checked via exit code or explicit exit statement)
|
|
140
|
+
[ -f "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh" ]
|
|
141
|
+
tail -5 "$TEST_PROJECT_DIR/.claude/hooks/piper-download-voices.sh" | grep -q "exit 0"
|
|
142
|
+
}
|
package/test-bmad-pr.sh
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# BMAD PR Testing Script
|
|
4
|
+
# Interactive script to test BMAD PR #934 with AgentVibes integration
|
|
5
|
+
#
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
+
CONFIG_FILE="$SCRIPT_DIR/.test-bmad-config"
|
|
11
|
+
|
|
12
|
+
echo "🎙️ BMAD PR #934 Testing Script"
|
|
13
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Load saved config if it exists
|
|
17
|
+
SAVED_FORK=""
|
|
18
|
+
SAVED_TEST_DIR=""
|
|
19
|
+
if [[ -f "$CONFIG_FILE" ]]; then
|
|
20
|
+
source "$CONFIG_FILE"
|
|
21
|
+
echo "📋 Loaded saved configuration:"
|
|
22
|
+
echo " Fork: $SAVED_FORK"
|
|
23
|
+
echo " Test directory: $SAVED_TEST_DIR"
|
|
24
|
+
echo ""
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Ask for GitHub fork URL
|
|
28
|
+
echo "Step 1: GitHub Fork"
|
|
29
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
30
|
+
if [[ -n "$SAVED_FORK" ]]; then
|
|
31
|
+
read -p "GitHub fork URL [$SAVED_FORK]: " FORK_URL
|
|
32
|
+
FORK_URL="${FORK_URL:-$SAVED_FORK}"
|
|
33
|
+
else
|
|
34
|
+
read -p "GitHub fork URL (e.g., https://github.com/paulpreibisch/BMAD-METHOD.git): " FORK_URL
|
|
35
|
+
fi
|
|
36
|
+
echo ""
|
|
37
|
+
|
|
38
|
+
# Ask for test directory
|
|
39
|
+
echo "Step 2: Test Directory"
|
|
40
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
41
|
+
if [[ -n "$SAVED_TEST_DIR" ]]; then
|
|
42
|
+
read -p "Test directory [$SAVED_TEST_DIR]: " TEST_DIR
|
|
43
|
+
TEST_DIR="${TEST_DIR:-$SAVED_TEST_DIR}"
|
|
44
|
+
else
|
|
45
|
+
DEFAULT_DIR="$HOME/bmad-pr-test-$(date +%Y%m%d-%H%M%S)"
|
|
46
|
+
read -p "Test directory [$DEFAULT_DIR]: " TEST_DIR
|
|
47
|
+
TEST_DIR="${TEST_DIR:-$DEFAULT_DIR}"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Expand ~ to actual home directory
|
|
51
|
+
TEST_DIR="${TEST_DIR/#\~/$HOME}"
|
|
52
|
+
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
# Save configuration
|
|
56
|
+
echo "SAVED_FORK=\"$FORK_URL\"" > "$CONFIG_FILE"
|
|
57
|
+
echo "SAVED_TEST_DIR=\"$TEST_DIR\"" >> "$CONFIG_FILE"
|
|
58
|
+
echo "✅ Configuration saved to $CONFIG_FILE"
|
|
59
|
+
echo ""
|
|
60
|
+
|
|
61
|
+
# Confirm before starting
|
|
62
|
+
echo "Configuration:"
|
|
63
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
64
|
+
echo " Fork: $FORK_URL"
|
|
65
|
+
echo " Test dir: $TEST_DIR"
|
|
66
|
+
echo ""
|
|
67
|
+
read -p "Proceed with testing? [Y/n]: " -n 1 -r
|
|
68
|
+
echo
|
|
69
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ -n $REPLY ]]; then
|
|
70
|
+
echo "❌ Testing cancelled"
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
echo ""
|
|
74
|
+
|
|
75
|
+
# Clean up old test directory if it exists
|
|
76
|
+
if [[ -d "$TEST_DIR" ]]; then
|
|
77
|
+
echo "⚠️ Test directory already exists: $TEST_DIR"
|
|
78
|
+
read -p "Delete and recreate? [Y/n]: " -n 1 -r
|
|
79
|
+
echo
|
|
80
|
+
if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
|
|
81
|
+
rm -rf "$TEST_DIR"
|
|
82
|
+
echo "✅ Deleted old test directory"
|
|
83
|
+
else
|
|
84
|
+
echo "❌ Using existing directory (may have stale data)"
|
|
85
|
+
fi
|
|
86
|
+
echo ""
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Step 1: Clone fork
|
|
90
|
+
echo "Step 1: Cloning your fork"
|
|
91
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
92
|
+
mkdir -p "$TEST_DIR"
|
|
93
|
+
cd "$TEST_DIR"
|
|
94
|
+
git clone "$FORK_URL" BMAD-METHOD
|
|
95
|
+
cd BMAD-METHOD
|
|
96
|
+
echo "✅ Cloned fork"
|
|
97
|
+
echo ""
|
|
98
|
+
|
|
99
|
+
# Step 2: Fetch PR branch
|
|
100
|
+
echo "Step 2: Fetching PR #934 branch"
|
|
101
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
102
|
+
git remote add upstream https://github.com/bmad-code-org/BMAD-METHOD.git
|
|
103
|
+
git fetch upstream pull/934/head:agentvibes-party-mode
|
|
104
|
+
git checkout agentvibes-party-mode
|
|
105
|
+
echo "✅ On PR branch: agentvibes-party-mode"
|
|
106
|
+
echo ""
|
|
107
|
+
|
|
108
|
+
# Step 3: Install BMAD CLI
|
|
109
|
+
echo "Step 3: Installing BMAD CLI"
|
|
110
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
111
|
+
cd tools/cli
|
|
112
|
+
npm install
|
|
113
|
+
npm link
|
|
114
|
+
echo "✅ BMAD CLI installed and linked"
|
|
115
|
+
echo ""
|
|
116
|
+
|
|
117
|
+
# Step 4: Create test project
|
|
118
|
+
echo "Step 4: Creating test BMAD project"
|
|
119
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
120
|
+
cd "$TEST_DIR"
|
|
121
|
+
mkdir -p bmad-project
|
|
122
|
+
cd bmad-project
|
|
123
|
+
echo "✅ Test project directory created: $TEST_DIR/bmad-project"
|
|
124
|
+
echo ""
|
|
125
|
+
|
|
126
|
+
# Step 5: Run BMAD installer
|
|
127
|
+
echo "Step 5: Running BMAD installer"
|
|
128
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
129
|
+
echo "⚠️ When prompted:"
|
|
130
|
+
echo " - Enable TTS for agents? → Yes"
|
|
131
|
+
echo " - Assign unique voices for party mode? → Yes"
|
|
132
|
+
echo ""
|
|
133
|
+
read -p "Press Enter to start BMAD installer..."
|
|
134
|
+
bmad install
|
|
135
|
+
|
|
136
|
+
echo ""
|
|
137
|
+
echo "✅ BMAD installation complete"
|
|
138
|
+
echo ""
|
|
139
|
+
|
|
140
|
+
# Step 6: Install AgentVibes
|
|
141
|
+
echo "Step 6: Installing AgentVibes"
|
|
142
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
143
|
+
echo "⚠️ When prompted, choose:"
|
|
144
|
+
echo " - Provider: Piper (free) for testing"
|
|
145
|
+
echo " - Download voices: Yes"
|
|
146
|
+
echo ""
|
|
147
|
+
read -p "Press Enter to start AgentVibes installer..."
|
|
148
|
+
npx agentvibes@latest install
|
|
149
|
+
|
|
150
|
+
echo ""
|
|
151
|
+
echo "✅ AgentVibes installation complete"
|
|
152
|
+
echo ""
|
|
153
|
+
|
|
154
|
+
# Verification
|
|
155
|
+
echo "Step 7: Verification"
|
|
156
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
157
|
+
echo ""
|
|
158
|
+
|
|
159
|
+
# Check for voice map file
|
|
160
|
+
if [[ -f ".bmad/_cfg/agent-voice-map.csv" ]]; then
|
|
161
|
+
echo "✅ Voice map file created: .bmad/_cfg/agent-voice-map.csv"
|
|
162
|
+
echo ""
|
|
163
|
+
echo "Voice assignments:"
|
|
164
|
+
cat .bmad/_cfg/agent-voice-map.csv
|
|
165
|
+
echo ""
|
|
166
|
+
else
|
|
167
|
+
echo "❌ Voice map file NOT found: .bmad/_cfg/agent-voice-map.csv"
|
|
168
|
+
echo " This is a problem - agents won't have unique voices!"
|
|
169
|
+
echo ""
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
# Check for AgentVibes hooks
|
|
173
|
+
if [[ -f ".claude/hooks/bmad-speak.sh" ]]; then
|
|
174
|
+
echo "✅ BMAD TTS hooks installed"
|
|
175
|
+
else
|
|
176
|
+
echo "❌ BMAD TTS hooks NOT found"
|
|
177
|
+
echo ""
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
# Check for Piper installation
|
|
181
|
+
if command -v piper &> /dev/null; then
|
|
182
|
+
echo "✅ Piper TTS installed"
|
|
183
|
+
piper --version
|
|
184
|
+
else
|
|
185
|
+
echo "⚠️ Piper not found in PATH (may still work if installed locally)"
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
echo ""
|
|
189
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
190
|
+
echo "🎉 Testing setup complete!"
|
|
191
|
+
echo ""
|
|
192
|
+
echo "Next steps:"
|
|
193
|
+
echo " 1. cd $TEST_DIR/bmad-project"
|
|
194
|
+
echo " 2. Start Claude Code session"
|
|
195
|
+
echo " 3. Run: /bmad:core:workflows:party-mode"
|
|
196
|
+
echo " 4. Verify each agent speaks with a unique voice"
|
|
197
|
+
echo ""
|
|
198
|
+
echo "Test project location: $TEST_DIR/bmad-project"
|
|
199
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|