agentvibes 2.2.0-beta.2 → 2.2.0-beta.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
20251102
|
|
@@ -80,10 +80,17 @@ detect_bmad() {
|
|
|
80
80
|
# Find all BMAD agents
|
|
81
81
|
find_agents() {
|
|
82
82
|
local bmad_core="$1"
|
|
83
|
-
local agents_dir="
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
local agents_dir=""
|
|
84
|
+
|
|
85
|
+
# Check for v6-alpha structure (bmad/bmm/agents/)
|
|
86
|
+
if [[ -d "$bmad_core/bmm/agents" ]]; then
|
|
87
|
+
agents_dir="$bmad_core/bmm/agents"
|
|
88
|
+
# Check for v4 structure (.bmad-core/agents/)
|
|
89
|
+
elif [[ -d "$bmad_core/agents" ]]; then
|
|
90
|
+
agents_dir="$bmad_core/agents"
|
|
91
|
+
else
|
|
92
|
+
echo -e "${RED}❌ Agents directory not found in $bmad_core${NC}" >&2
|
|
93
|
+
echo -e "${GRAY} Tried: $bmad_core/bmm/agents/ and $bmad_core/agents/${NC}" >&2
|
|
87
94
|
return 1
|
|
88
95
|
fi
|
|
89
96
|
|
|
@@ -94,9 +101,20 @@ find_agents() {
|
|
|
94
101
|
has_tts_injection() {
|
|
95
102
|
local agent_file="$1"
|
|
96
103
|
|
|
104
|
+
# Check for v4 marker (YAML comment)
|
|
97
105
|
if grep -q "# AGENTVIBES-TTS-INJECTION" "$agent_file" 2>/dev/null; then
|
|
98
106
|
return 0
|
|
99
107
|
fi
|
|
108
|
+
|
|
109
|
+
# Check for v6 marker (XML attribute or text)
|
|
110
|
+
if grep -q "AGENTVIBES TTS INJECTION" "$agent_file" 2>/dev/null; then
|
|
111
|
+
return 0
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
if grep -q 'tts="agentvibes"' "$agent_file" 2>/dev/null; then
|
|
115
|
+
return 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
100
118
|
return 1
|
|
101
119
|
}
|
|
102
120
|
|
|
@@ -190,55 +208,78 @@ inject_tts() {
|
|
|
190
208
|
# Create backup
|
|
191
209
|
cp "$agent_file" "$agent_file.backup-pre-tts"
|
|
192
210
|
|
|
193
|
-
#
|
|
194
|
-
|
|
195
|
-
|
|
211
|
+
# Detect v4 vs v6 structure
|
|
212
|
+
local is_v6=false
|
|
213
|
+
if grep -q "<activation" "$agent_file"; then
|
|
214
|
+
is_v6=true
|
|
215
|
+
elif ! grep -q "activation-instructions:" "$agent_file"; then
|
|
216
|
+
echo -e "${RED}❌ No activation section found in: $(basename "$agent_file")${NC}"
|
|
196
217
|
return 1
|
|
197
218
|
fi
|
|
198
219
|
|
|
199
|
-
# Create TTS injection script
|
|
200
|
-
|
|
201
|
-
|
|
220
|
+
# Create TTS injection script based on version
|
|
221
|
+
if [[ "$is_v6" == "true" ]]; then
|
|
222
|
+
# v6 format: XML-style with <step n="4.5">
|
|
223
|
+
local tts_step=""
|
|
224
|
+
if [[ -n "$agent_voice" ]]; then
|
|
225
|
+
tts_step=" <step n=\"4.5\" tts=\"agentvibes\">🎤 AGENTVIBES TTS INJECTION:
|
|
226
|
+
- Create context: echo \"${agent_id}\" > .bmad-agent-context (Bash tool)
|
|
227
|
+
- Speak greeting: .claude/hooks/play-tts.sh \"Hello! I'm ready to help you.\" \"${agent_voice}\" (Bash tool)
|
|
228
|
+
- CRITICAL: Before EVERY response, scan for questions/prompts and speak them using Bash tool</step>"
|
|
229
|
+
else
|
|
230
|
+
tts_step=" <step n=\"4.5\" tts=\"agentvibes\">🎤 AGENTVIBES TTS INJECTION:
|
|
231
|
+
- Create context: echo \"${agent_id}\" > .bmad-agent-context (Bash tool)
|
|
232
|
+
- Speak greeting: .claude/hooks/play-tts.sh \"Hello! I'm ready to help you.\" (Bash tool)
|
|
233
|
+
- CRITICAL: Before EVERY response, scan for questions/prompts and speak them using Bash tool</step>"
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
# Insert after step 4 (greeting) - only first match
|
|
237
|
+
awk -v tts="$tts_step" '
|
|
238
|
+
!done && /<step n="4">.*[Gg]reet/ {
|
|
239
|
+
print
|
|
240
|
+
print tts
|
|
241
|
+
done=1
|
|
242
|
+
next
|
|
243
|
+
}
|
|
244
|
+
{ print }
|
|
245
|
+
' "$agent_file" > "$agent_file.tmp"
|
|
246
|
+
|
|
247
|
+
# If no change (step 4 didn't match), restore backup and report
|
|
248
|
+
if ! diff -q "$agent_file.backup-pre-tts" "$agent_file.tmp" > /dev/null 2>&1; then
|
|
249
|
+
: # Changes were made, continue
|
|
250
|
+
else
|
|
251
|
+
# No changes - step 4 pattern didn't match
|
|
252
|
+
rm "$agent_file.tmp"
|
|
253
|
+
mv "$agent_file.backup-pre-tts" "$agent_file"
|
|
254
|
+
echo -e "${RED}❌ Could not find step 4 with greeting in: $(basename "$agent_file")${NC}"
|
|
255
|
+
return 1
|
|
256
|
+
fi
|
|
202
257
|
|
|
203
|
-
|
|
204
|
-
|
|
258
|
+
else
|
|
259
|
+
# v4 format: YAML-style with STEP 4:
|
|
260
|
+
local activation_injection=""
|
|
261
|
+
if [[ -n "$agent_voice" ]]; then
|
|
262
|
+
activation_injection=" - # AGENTVIBES-TTS-INJECTION: STEP 3.5 - Announce activation with TTS
|
|
205
263
|
- STEP 3.5a: Use Bash tool to create context file: echo \"${agent_id}\" > .bmad-agent-context
|
|
206
264
|
- STEP 3.5b: Use Bash tool to speak: .claude/hooks/play-tts.sh \"Agent ${agent_id} activated and ready\" \"${agent_voice}\"
|
|
207
|
-
- AGENTVIBES-TTS-INJECTION:
|
|
208
|
-
|
|
209
|
-
- AGENTVIBES-TTS-
|
|
210
|
-
- AGENTVIBES-TTS-STEP 3: If questions found, use Bash tool to speak them: .claude/hooks/play-tts.sh \"question text\" \"${agent_voice}\"
|
|
211
|
-
- AGENTVIBES-TTS-STEP 4: Show the response text to user
|
|
212
|
-
- AGENTVIBES-TTS-INJECTION: On exit command (*exit), use Bash tool FIRST to cleanup: rm -f .bmad-agent-context"
|
|
213
|
-
persona_injection=" - AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
214
|
-
else
|
|
215
|
-
activation_injection=" - # AGENTVIBES-TTS-INJECTION: STEP 3.5 - Announce activation with TTS and set context
|
|
265
|
+
- AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
266
|
+
else
|
|
267
|
+
activation_injection=" - # AGENTVIBES-TTS-INJECTION: STEP 3.5 - Announce activation with TTS
|
|
216
268
|
- STEP 3.5a: Use Bash tool to create context file: echo \"${agent_id}\" > .bmad-agent-context
|
|
217
269
|
- STEP 3.5b: Use Bash tool to speak: .claude/hooks/play-tts.sh \"Agent ${agent_id} activated and ready\"
|
|
218
|
-
- AGENTVIBES-TTS-INJECTION:
|
|
219
|
-
|
|
220
|
-
- AGENTVIBES-TTS-STEP 2: Scan response for questions (lines with ? or numbered lists or phrases like What/Should/Would)
|
|
221
|
-
- AGENTVIBES-TTS-STEP 3: If questions found, use Bash tool to speak them: .claude/hooks/play-tts.sh \"question text\"
|
|
222
|
-
- AGENTVIBES-TTS-STEP 4: Show the response text to user
|
|
223
|
-
- AGENTVIBES-TTS-INJECTION: On exit command (*exit), use Bash tool FIRST to cleanup: rm -f .bmad-agent-context"
|
|
224
|
-
persona_injection=" - AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
225
|
-
fi
|
|
270
|
+
- AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
271
|
+
fi
|
|
226
272
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
print persona
|
|
238
|
-
next
|
|
239
|
-
}
|
|
240
|
-
{ print }
|
|
241
|
-
' "$agent_file" > "$agent_file.tmp"
|
|
273
|
+
# Insert after STEP 4: Greet
|
|
274
|
+
awk -v activation="$activation_injection" '
|
|
275
|
+
/STEP 4:.*[Gg]reet/ {
|
|
276
|
+
print
|
|
277
|
+
print activation
|
|
278
|
+
next
|
|
279
|
+
}
|
|
280
|
+
{ print }
|
|
281
|
+
' "$agent_file" > "$agent_file.tmp"
|
|
282
|
+
fi
|
|
242
283
|
|
|
243
284
|
mv "$agent_file.tmp" "$agent_file"
|
|
244
285
|
|
|
@@ -366,7 +407,17 @@ restore_backup() {
|
|
|
366
407
|
echo -e "${CYAN}🔄 Restoring agents from backup...${NC}"
|
|
367
408
|
echo ""
|
|
368
409
|
|
|
369
|
-
|
|
410
|
+
# Determine agents directory (v6 vs v4)
|
|
411
|
+
local agents_dir=""
|
|
412
|
+
if [[ -d "$bmad_core/bmm/agents" ]]; then
|
|
413
|
+
agents_dir="$bmad_core/bmm/agents"
|
|
414
|
+
elif [[ -d "$bmad_core/agents" ]]; then
|
|
415
|
+
agents_dir="$bmad_core/agents"
|
|
416
|
+
else
|
|
417
|
+
echo -e "${RED}❌ Agents directory not found${NC}"
|
|
418
|
+
return 1
|
|
419
|
+
fi
|
|
420
|
+
|
|
370
421
|
local backup_count=0
|
|
371
422
|
|
|
372
423
|
for backup_file in "$agents_dir"/*.backup-pre-tts; do
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/bmad-tts-injector.sh
|
|
4
|
+
#
|
|
5
|
+
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
+
# Website: https://agentvibes.org
|
|
7
|
+
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
+
#
|
|
9
|
+
# Co-created by Paul Preibisch with Claude AI
|
|
10
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
+
#
|
|
12
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
# you may not use this file except in compliance with the License.
|
|
14
|
+
# You may obtain a copy of the License at
|
|
15
|
+
#
|
|
16
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
#
|
|
18
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
# See the License for the specific language governing permissions and
|
|
22
|
+
# limitations under the License.
|
|
23
|
+
#
|
|
24
|
+
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
+
# express or implied. Use at your own risk. See the Apache License for details.
|
|
26
|
+
#
|
|
27
|
+
# ---
|
|
28
|
+
#
|
|
29
|
+
# @fileoverview BMAD TTS Injection Manager - Patches BMAD agents for TTS integration
|
|
30
|
+
# @context Automatically modifies BMAD agent YAML files to include AgentVibes TTS capabilities
|
|
31
|
+
# @architecture Injects TTS hooks into activation-instructions and core_principles sections
|
|
32
|
+
# @dependencies bmad-core/agents/*.md files, play-tts.sh, bmad-voice-manager.sh
|
|
33
|
+
# @entrypoints Called via bmad-tts-injector.sh {enable|disable|status|restore}
|
|
34
|
+
# @patterns File patching with backup, provider-aware voice mapping, injection markers for idempotency
|
|
35
|
+
# @related play-tts.sh, bmad-voice-manager.sh, .bmad-core/agents/*.md
|
|
36
|
+
#
|
|
37
|
+
|
|
38
|
+
set -e # Exit on error
|
|
39
|
+
|
|
40
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
41
|
+
CLAUDE_DIR="$(dirname "$SCRIPT_DIR")"
|
|
42
|
+
|
|
43
|
+
# Colors for output
|
|
44
|
+
GREEN='\033[0;32m'
|
|
45
|
+
YELLOW='\033[1;33m'
|
|
46
|
+
RED='\033[0;31m'
|
|
47
|
+
CYAN='\033[0;36m'
|
|
48
|
+
GRAY='\033[0;90m'
|
|
49
|
+
NC='\033[0m' # No Color
|
|
50
|
+
|
|
51
|
+
# Detect BMAD installation and version
|
|
52
|
+
# Supports both v4 (.bmad-core/) and v6-alpha (bmad/) installations
|
|
53
|
+
detect_bmad() {
|
|
54
|
+
local bmad_core_dir=""
|
|
55
|
+
|
|
56
|
+
# Check for v6-alpha first (newer version)
|
|
57
|
+
if [[ -d "bmad" ]]; then
|
|
58
|
+
bmad_core_dir="bmad"
|
|
59
|
+
elif [[ -d "../bmad" ]]; then
|
|
60
|
+
bmad_core_dir="../bmad"
|
|
61
|
+
# Check for v4 (legacy)
|
|
62
|
+
elif [[ -d ".bmad-core" ]]; then
|
|
63
|
+
bmad_core_dir=".bmad-core"
|
|
64
|
+
elif [[ -d "../.bmad-core" ]]; then
|
|
65
|
+
bmad_core_dir="../.bmad-core"
|
|
66
|
+
# Check for bmad-core (without dot prefix, legacy variant)
|
|
67
|
+
elif [[ -d "bmad-core" ]]; then
|
|
68
|
+
bmad_core_dir="bmad-core"
|
|
69
|
+
elif [[ -d "../bmad-core" ]]; then
|
|
70
|
+
bmad_core_dir="../bmad-core"
|
|
71
|
+
else
|
|
72
|
+
echo -e "${RED}❌ BMAD installation not found${NC}" >&2
|
|
73
|
+
echo -e "${GRAY} Looked for bmad/, .bmad-core/, or bmad-core/ directory${NC}" >&2
|
|
74
|
+
return 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
echo "$bmad_core_dir"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Find all BMAD agents
|
|
81
|
+
find_agents() {
|
|
82
|
+
local bmad_core="$1"
|
|
83
|
+
local agents_dir=""
|
|
84
|
+
|
|
85
|
+
# Check for v6-alpha structure (bmad/bmm/agents/)
|
|
86
|
+
if [[ -d "$bmad_core/bmm/agents" ]]; then
|
|
87
|
+
agents_dir="$bmad_core/bmm/agents"
|
|
88
|
+
# Check for v4 structure (.bmad-core/agents/)
|
|
89
|
+
elif [[ -d "$bmad_core/agents" ]]; then
|
|
90
|
+
agents_dir="$bmad_core/agents"
|
|
91
|
+
else
|
|
92
|
+
echo -e "${RED}❌ Agents directory not found in $bmad_core${NC}" >&2
|
|
93
|
+
echo -e "${GRAY} Tried: $bmad_core/bmm/agents/ and $bmad_core/agents/${NC}" >&2
|
|
94
|
+
return 1
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
find "$agents_dir" -name "*.md" -type f
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Check if agent has TTS injection
|
|
101
|
+
has_tts_injection() {
|
|
102
|
+
local agent_file="$1"
|
|
103
|
+
|
|
104
|
+
# Check for v4 marker (YAML comment)
|
|
105
|
+
if grep -q "# AGENTVIBES-TTS-INJECTION" "$agent_file" 2>/dev/null; then
|
|
106
|
+
return 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Check for v6 marker (XML attribute or text)
|
|
110
|
+
if grep -q "AGENTVIBES TTS INJECTION" "$agent_file" 2>/dev/null; then
|
|
111
|
+
return 0
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
if grep -q 'tts="agentvibes"' "$agent_file" 2>/dev/null; then
|
|
115
|
+
return 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
return 1
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# Extract agent ID from file
|
|
122
|
+
get_agent_id() {
|
|
123
|
+
local agent_file="$1"
|
|
124
|
+
|
|
125
|
+
# Look for "id: <agent-id>" in YAML block
|
|
126
|
+
local agent_id=$(grep -E "^ id:" "$agent_file" | head -1 | awk '{print $2}' | tr -d '"' | tr -d "'")
|
|
127
|
+
|
|
128
|
+
if [[ -z "$agent_id" ]]; then
|
|
129
|
+
# Fallback: use filename without extension
|
|
130
|
+
agent_id=$(basename "$agent_file" .md)
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
echo "$agent_id"
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Get voice for agent from BMAD voice mapping
|
|
137
|
+
get_agent_voice() {
|
|
138
|
+
local agent_id="$1"
|
|
139
|
+
|
|
140
|
+
# Use bmad-voice-manager.sh to get voice
|
|
141
|
+
if [[ -f "$SCRIPT_DIR/bmad-voice-manager.sh" ]]; then
|
|
142
|
+
local voice=$("$SCRIPT_DIR/bmad-voice-manager.sh" get-voice "$agent_id" 2>/dev/null || echo "")
|
|
143
|
+
echo "$voice"
|
|
144
|
+
fi
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Map ElevenLabs voice to Piper equivalent
|
|
148
|
+
map_voice_to_provider() {
|
|
149
|
+
local elevenlabs_voice="$1"
|
|
150
|
+
local provider="$2"
|
|
151
|
+
|
|
152
|
+
# If provider is elevenlabs or empty, return as-is
|
|
153
|
+
if [[ "$provider" != "piper" ]]; then
|
|
154
|
+
echo "$elevenlabs_voice"
|
|
155
|
+
return
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
# Map ElevenLabs voices to Piper equivalents
|
|
159
|
+
case "$elevenlabs_voice" in
|
|
160
|
+
"Jessica Anne Bogart"|"Aria")
|
|
161
|
+
echo "en_US-lessac-medium"
|
|
162
|
+
;;
|
|
163
|
+
"Matthew Schmitz"|"Archer"|"Michael")
|
|
164
|
+
echo "en_US-danny-low"
|
|
165
|
+
;;
|
|
166
|
+
"Burt Reynolds"|"Cowboy Bob")
|
|
167
|
+
echo "en_US-joe-medium"
|
|
168
|
+
;;
|
|
169
|
+
"Tiffany"|"Ms. Walker")
|
|
170
|
+
echo "en_US-amy-medium"
|
|
171
|
+
;;
|
|
172
|
+
"Ralf Eisend"|"Tom")
|
|
173
|
+
echo "en_US-libritts-high"
|
|
174
|
+
;;
|
|
175
|
+
*)
|
|
176
|
+
# Default to amy for unknown voices
|
|
177
|
+
echo "en_US-amy-medium"
|
|
178
|
+
;;
|
|
179
|
+
esac
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# Get current TTS provider
|
|
183
|
+
get_current_provider() {
|
|
184
|
+
# Check project-local first, then global
|
|
185
|
+
if [[ -f ".claude/tts-provider.txt" ]]; then
|
|
186
|
+
cat ".claude/tts-provider.txt" 2>/dev/null || echo "elevenlabs"
|
|
187
|
+
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
188
|
+
cat "$HOME/.claude/tts-provider.txt" 2>/dev/null || echo "elevenlabs"
|
|
189
|
+
else
|
|
190
|
+
echo "elevenlabs"
|
|
191
|
+
fi
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# Inject TTS hook into agent activation instructions
|
|
195
|
+
inject_tts() {
|
|
196
|
+
local agent_file="$1"
|
|
197
|
+
local agent_id=$(get_agent_id "$agent_file")
|
|
198
|
+
local elevenlabs_voice=$(get_agent_voice "$agent_id")
|
|
199
|
+
local current_provider=$(get_current_provider)
|
|
200
|
+
local agent_voice=$(map_voice_to_provider "$elevenlabs_voice" "$current_provider")
|
|
201
|
+
|
|
202
|
+
# Check if already injected
|
|
203
|
+
if has_tts_injection "$agent_file"; then
|
|
204
|
+
echo -e "${YELLOW}⚠️ TTS already injected in: $(basename "$agent_file")${NC}"
|
|
205
|
+
return 0
|
|
206
|
+
fi
|
|
207
|
+
|
|
208
|
+
# Create backup
|
|
209
|
+
cp "$agent_file" "$agent_file.backup-pre-tts"
|
|
210
|
+
|
|
211
|
+
# Detect v4 vs v6 structure
|
|
212
|
+
local is_v6=false
|
|
213
|
+
if grep -q "<activation" "$agent_file"; then
|
|
214
|
+
is_v6=true
|
|
215
|
+
elif ! grep -q "activation-instructions:" "$agent_file"; then
|
|
216
|
+
echo -e "${RED}❌ No activation section found in: $(basename "$agent_file")${NC}"
|
|
217
|
+
return 1
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Create TTS injection script based on version
|
|
221
|
+
if [[ "$is_v6" == "true" ]]; then
|
|
222
|
+
# v6 format: XML-style with <step n="4.5">
|
|
223
|
+
local tts_step=""
|
|
224
|
+
if [[ -n "$agent_voice" ]]; then
|
|
225
|
+
tts_step=" <step n=\"4.5\" tts=\"agentvibes\">🎤 AGENTVIBES TTS INJECTION:
|
|
226
|
+
- Create context: echo \"${agent_id}\" > .bmad-agent-context (Bash tool)
|
|
227
|
+
- Speak greeting: .claude/hooks/play-tts.sh \"Hello! I'm ready to help you.\" \"${agent_voice}\" (Bash tool)
|
|
228
|
+
- CRITICAL: Before EVERY response, scan for questions/prompts and speak them using Bash tool</step>"
|
|
229
|
+
else
|
|
230
|
+
tts_step=" <step n=\"4.5\" tts=\"agentvibes\">🎤 AGENTVIBES TTS INJECTION:
|
|
231
|
+
- Create context: echo \"${agent_id}\" > .bmad-agent-context (Bash tool)
|
|
232
|
+
- Speak greeting: .claude/hooks/play-tts.sh \"Hello! I'm ready to help you.\" (Bash tool)
|
|
233
|
+
- CRITICAL: Before EVERY response, scan for questions/prompts and speak them using Bash tool</step>"
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
# Insert after step 4 (greeting) - only first match
|
|
237
|
+
awk -v tts="$tts_step" '
|
|
238
|
+
!done && /<step n="4">.*[Gg]reet/ {
|
|
239
|
+
print
|
|
240
|
+
print tts
|
|
241
|
+
done=1
|
|
242
|
+
next
|
|
243
|
+
}
|
|
244
|
+
{ print }
|
|
245
|
+
' "$agent_file" > "$agent_file.tmp"
|
|
246
|
+
|
|
247
|
+
# If no change (step 4 didn't match), restore backup and report
|
|
248
|
+
if ! diff -q "$agent_file.backup-pre-tts" "$agent_file.tmp" > /dev/null 2>&1; then
|
|
249
|
+
: # Changes were made, continue
|
|
250
|
+
else
|
|
251
|
+
# No changes - step 4 pattern didn't match
|
|
252
|
+
rm "$agent_file.tmp"
|
|
253
|
+
mv "$agent_file.backup-pre-tts" "$agent_file"
|
|
254
|
+
echo -e "${RED}❌ Could not find step 4 with greeting in: $(basename "$agent_file")${NC}"
|
|
255
|
+
return 1
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
else
|
|
259
|
+
# v4 format: YAML-style with STEP 4:
|
|
260
|
+
local activation_injection=""
|
|
261
|
+
if [[ -n "$agent_voice" ]]; then
|
|
262
|
+
activation_injection=" - # AGENTVIBES-TTS-INJECTION: STEP 3.5 - Announce activation with TTS
|
|
263
|
+
- STEP 3.5a: Use Bash tool to create context file: echo \"${agent_id}\" > .bmad-agent-context
|
|
264
|
+
- STEP 3.5b: Use Bash tool to speak: .claude/hooks/play-tts.sh \"Agent ${agent_id} activated and ready\" \"${agent_voice}\"
|
|
265
|
+
- AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
266
|
+
else
|
|
267
|
+
activation_injection=" - # AGENTVIBES-TTS-INJECTION: STEP 3.5 - Announce activation with TTS
|
|
268
|
+
- STEP 3.5a: Use Bash tool to create context file: echo \"${agent_id}\" > .bmad-agent-context
|
|
269
|
+
- STEP 3.5b: Use Bash tool to speak: .claude/hooks/play-tts.sh \"Agent ${agent_id} activated and ready\"
|
|
270
|
+
- AGENTVIBES-TTS-INJECTION: Before every response, scan for questions and speak them using Bash tool"
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
# Insert after STEP 4: Greet
|
|
274
|
+
awk -v activation="$activation_injection" '
|
|
275
|
+
/STEP 4:.*[Gg]reet/ {
|
|
276
|
+
print
|
|
277
|
+
print activation
|
|
278
|
+
next
|
|
279
|
+
}
|
|
280
|
+
{ print }
|
|
281
|
+
' "$agent_file" > "$agent_file.tmp"
|
|
282
|
+
fi
|
|
283
|
+
|
|
284
|
+
mv "$agent_file.tmp" "$agent_file"
|
|
285
|
+
|
|
286
|
+
if [[ "$current_provider" == "piper" ]] && [[ -n "$elevenlabs_voice" ]]; then
|
|
287
|
+
echo -e "${GREEN}✅ Injected TTS into: $(basename "$agent_file") → Voice: ${agent_voice:-default} (${current_provider}: ${elevenlabs_voice} → ${agent_voice})${NC}"
|
|
288
|
+
else
|
|
289
|
+
echo -e "${GREEN}✅ Injected TTS into: $(basename "$agent_file") → Voice: ${agent_voice:-default}${NC}"
|
|
290
|
+
fi
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# Remove TTS injection from agent
|
|
294
|
+
remove_tts() {
|
|
295
|
+
local agent_file="$1"
|
|
296
|
+
|
|
297
|
+
# Check if has injection
|
|
298
|
+
if ! has_tts_injection "$agent_file"; then
|
|
299
|
+
echo -e "${GRAY} No TTS in: $(basename "$agent_file")${NC}"
|
|
300
|
+
return 0
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
# Create backup
|
|
304
|
+
cp "$agent_file" "$agent_file.backup-tts-removal"
|
|
305
|
+
|
|
306
|
+
# Remove TTS injection lines
|
|
307
|
+
sed -i.bak '/# AGENTVIBES-TTS-INJECTION/,+1d' "$agent_file"
|
|
308
|
+
rm -f "$agent_file.bak"
|
|
309
|
+
|
|
310
|
+
echo -e "${GREEN}✅ Removed TTS from: $(basename "$agent_file")${NC}"
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
# Show status of TTS injections
|
|
314
|
+
show_status() {
|
|
315
|
+
local bmad_core=$(detect_bmad)
|
|
316
|
+
if [[ -z "$bmad_core" ]]; then
|
|
317
|
+
return 1
|
|
318
|
+
fi
|
|
319
|
+
|
|
320
|
+
echo -e "${CYAN}📊 BMAD TTS Injection Status:${NC}"
|
|
321
|
+
echo ""
|
|
322
|
+
|
|
323
|
+
local agents=$(find_agents "$bmad_core")
|
|
324
|
+
local enabled_count=0
|
|
325
|
+
local disabled_count=0
|
|
326
|
+
|
|
327
|
+
while IFS= read -r agent_file; do
|
|
328
|
+
local agent_id=$(get_agent_id "$agent_file")
|
|
329
|
+
local agent_name=$(basename "$agent_file" .md)
|
|
330
|
+
|
|
331
|
+
if has_tts_injection "$agent_file"; then
|
|
332
|
+
local voice=$(get_agent_voice "$agent_id")
|
|
333
|
+
echo -e " ${GREEN}✅${NC} $agent_name (${agent_id}) → Voice: ${voice:-default}"
|
|
334
|
+
((enabled_count++))
|
|
335
|
+
else
|
|
336
|
+
echo -e " ${GRAY}❌ $agent_name (${agent_id})${NC}"
|
|
337
|
+
((disabled_count++))
|
|
338
|
+
fi
|
|
339
|
+
done <<< "$agents"
|
|
340
|
+
|
|
341
|
+
echo ""
|
|
342
|
+
echo -e "${CYAN}Summary:${NC} $enabled_count enabled, $disabled_count disabled"
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# Enable TTS for all agents
|
|
346
|
+
enable_all() {
|
|
347
|
+
local bmad_core=$(detect_bmad)
|
|
348
|
+
if [[ -z "$bmad_core" ]]; then
|
|
349
|
+
return 1
|
|
350
|
+
fi
|
|
351
|
+
|
|
352
|
+
echo -e "${CYAN}🎤 Enabling TTS for all BMAD agents...${NC}"
|
|
353
|
+
echo ""
|
|
354
|
+
|
|
355
|
+
local agents=$(find_agents "$bmad_core")
|
|
356
|
+
local success_count=0
|
|
357
|
+
local skip_count=0
|
|
358
|
+
|
|
359
|
+
while IFS= read -r agent_file; do
|
|
360
|
+
if has_tts_injection "$agent_file"; then
|
|
361
|
+
((skip_count++))
|
|
362
|
+
continue
|
|
363
|
+
fi
|
|
364
|
+
|
|
365
|
+
if inject_tts "$agent_file"; then
|
|
366
|
+
((success_count++))
|
|
367
|
+
fi
|
|
368
|
+
done <<< "$agents"
|
|
369
|
+
|
|
370
|
+
echo ""
|
|
371
|
+
echo -e "${GREEN}🎉 TTS enabled for $success_count agents${NC}"
|
|
372
|
+
[[ $skip_count -gt 0 ]] && echo -e "${YELLOW} Skipped $skip_count agents (already enabled)${NC}"
|
|
373
|
+
echo ""
|
|
374
|
+
echo -e "${CYAN}💡 BMAD agents will now speak when activated!${NC}"
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
# Disable TTS for all agents
|
|
378
|
+
disable_all() {
|
|
379
|
+
local bmad_core=$(detect_bmad)
|
|
380
|
+
if [[ -z "$bmad_core" ]]; then
|
|
381
|
+
return 1
|
|
382
|
+
fi
|
|
383
|
+
|
|
384
|
+
echo -e "${CYAN}🔇 Disabling TTS for all BMAD agents...${NC}"
|
|
385
|
+
echo ""
|
|
386
|
+
|
|
387
|
+
local agents=$(find_agents "$bmad_core")
|
|
388
|
+
local success_count=0
|
|
389
|
+
|
|
390
|
+
while IFS= read -r agent_file; do
|
|
391
|
+
if remove_tts "$agent_file"; then
|
|
392
|
+
((success_count++))
|
|
393
|
+
fi
|
|
394
|
+
done <<< "$agents"
|
|
395
|
+
|
|
396
|
+
echo ""
|
|
397
|
+
echo -e "${GREEN}✅ TTS disabled for $success_count agents${NC}"
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
# Restore from backup
|
|
401
|
+
restore_backup() {
|
|
402
|
+
local bmad_core=$(detect_bmad)
|
|
403
|
+
if [[ -z "$bmad_core" ]]; then
|
|
404
|
+
return 1
|
|
405
|
+
fi
|
|
406
|
+
|
|
407
|
+
echo -e "${CYAN}🔄 Restoring agents from backup...${NC}"
|
|
408
|
+
echo ""
|
|
409
|
+
|
|
410
|
+
# Determine agents directory (v6 vs v4)
|
|
411
|
+
local agents_dir=""
|
|
412
|
+
if [[ -d "$bmad_core/bmm/agents" ]]; then
|
|
413
|
+
agents_dir="$bmad_core/bmm/agents"
|
|
414
|
+
elif [[ -d "$bmad_core/agents" ]]; then
|
|
415
|
+
agents_dir="$bmad_core/agents"
|
|
416
|
+
else
|
|
417
|
+
echo -e "${RED}❌ Agents directory not found${NC}"
|
|
418
|
+
return 1
|
|
419
|
+
fi
|
|
420
|
+
|
|
421
|
+
local backup_count=0
|
|
422
|
+
|
|
423
|
+
for backup_file in "$agents_dir"/*.backup-pre-tts; do
|
|
424
|
+
if [[ -f "$backup_file" ]]; then
|
|
425
|
+
local original_file="${backup_file%.backup-pre-tts}"
|
|
426
|
+
cp "$backup_file" "$original_file"
|
|
427
|
+
echo -e "${GREEN}✅ Restored: $(basename "$original_file")${NC}"
|
|
428
|
+
((backup_count++))
|
|
429
|
+
fi
|
|
430
|
+
done
|
|
431
|
+
|
|
432
|
+
if [[ $backup_count -eq 0 ]]; then
|
|
433
|
+
echo -e "${YELLOW}⚠️ No backups found${NC}"
|
|
434
|
+
else
|
|
435
|
+
echo ""
|
|
436
|
+
echo -e "${GREEN}✅ Restored $backup_count agents from backup${NC}"
|
|
437
|
+
fi
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
# Main command dispatcher
|
|
441
|
+
case "${1:-help}" in
|
|
442
|
+
enable)
|
|
443
|
+
enable_all
|
|
444
|
+
;;
|
|
445
|
+
disable)
|
|
446
|
+
disable_all
|
|
447
|
+
;;
|
|
448
|
+
status)
|
|
449
|
+
show_status
|
|
450
|
+
;;
|
|
451
|
+
restore)
|
|
452
|
+
restore_backup
|
|
453
|
+
;;
|
|
454
|
+
help|*)
|
|
455
|
+
echo -e "${CYAN}AgentVibes BMAD TTS Injection Manager${NC}"
|
|
456
|
+
echo ""
|
|
457
|
+
echo "Usage: bmad-tts-injector.sh {enable|disable|status|restore}"
|
|
458
|
+
echo ""
|
|
459
|
+
echo "Commands:"
|
|
460
|
+
echo " enable Inject TTS hooks into all BMAD agents"
|
|
461
|
+
echo " disable Remove TTS hooks from all BMAD agents"
|
|
462
|
+
echo " status Show TTS injection status for all agents"
|
|
463
|
+
echo " restore Restore agents from backup (undo changes)"
|
|
464
|
+
echo ""
|
|
465
|
+
echo "What it does:"
|
|
466
|
+
echo " • Automatically patches BMAD agent activation instructions"
|
|
467
|
+
echo " • Adds TTS calls when agents greet users"
|
|
468
|
+
echo " • Uses voice mapping from AgentVibes BMAD plugin"
|
|
469
|
+
echo " • Creates backups before modifying files"
|
|
470
|
+
;;
|
|
471
|
+
esac
|
package/fixcolors
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# fixcolors - Apply vibrant purple color scheme to AgentVibes VS Code workspace
|
|
4
|
+
# Usage: ./fixcolors
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
PURPLE_ACTIVE="#7b2cbf"
|
|
9
|
+
PURPLE_INACTIVE="#5a189a"
|
|
10
|
+
PURPLE_DEBUG="#9d4edd"
|
|
11
|
+
WHITE="#ffffff"
|
|
12
|
+
LIGHT_GRAY="#e0e0e0"
|
|
13
|
+
|
|
14
|
+
echo "🎨 Applying vibrant purple color scheme to AgentVibes workspace..."
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
# Function to update JSON files with purple colors
|
|
18
|
+
update_colors() {
|
|
19
|
+
local file="$1"
|
|
20
|
+
local temp_file="${file}.tmp"
|
|
21
|
+
|
|
22
|
+
if [[ ! -f "$file" ]]; then
|
|
23
|
+
echo "⚠️ File not found: $file"
|
|
24
|
+
return 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
echo "📝 Updating: $file"
|
|
28
|
+
|
|
29
|
+
# Use Python to safely update JSON
|
|
30
|
+
python3 << EOF
|
|
31
|
+
import json
|
|
32
|
+
import sys
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
with open('$file', 'r') as f:
|
|
36
|
+
data = json.load(f)
|
|
37
|
+
|
|
38
|
+
# Ensure settings exists
|
|
39
|
+
if 'settings' in data:
|
|
40
|
+
settings = data['settings']
|
|
41
|
+
else:
|
|
42
|
+
settings = data
|
|
43
|
+
|
|
44
|
+
# Ensure workbench.colorCustomizations exists
|
|
45
|
+
if 'workbench.colorCustomizations' not in settings:
|
|
46
|
+
settings['workbench.colorCustomizations'] = {}
|
|
47
|
+
|
|
48
|
+
colors = settings['workbench.colorCustomizations']
|
|
49
|
+
|
|
50
|
+
# Apply purple theme
|
|
51
|
+
colors['titleBar.activeBackground'] = '$PURPLE_ACTIVE'
|
|
52
|
+
colors['titleBar.activeForeground'] = '$WHITE'
|
|
53
|
+
colors['titleBar.inactiveBackground'] = '$PURPLE_INACTIVE'
|
|
54
|
+
colors['titleBar.inactiveForeground'] = '$LIGHT_GRAY'
|
|
55
|
+
colors['statusBar.background'] = '$PURPLE_ACTIVE'
|
|
56
|
+
colors['statusBar.foreground'] = '$WHITE'
|
|
57
|
+
colors['statusBar.noFolderBackground'] = '$PURPLE_INACTIVE'
|
|
58
|
+
colors['statusBar.debuggingBackground'] = '$PURPLE_DEBUG'
|
|
59
|
+
|
|
60
|
+
# Write back
|
|
61
|
+
with open('$temp_file', 'w') as f:
|
|
62
|
+
json.dump(data, f, indent=2)
|
|
63
|
+
|
|
64
|
+
print(" ✓ Colors updated")
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
print(f" ✗ Error: {e}", file=sys.stderr)
|
|
68
|
+
sys.exit(1)
|
|
69
|
+
EOF
|
|
70
|
+
|
|
71
|
+
if [[ $? -eq 0 ]]; then
|
|
72
|
+
mv "$temp_file" "$file"
|
|
73
|
+
echo " ✓ File saved"
|
|
74
|
+
else
|
|
75
|
+
rm -f "$temp_file"
|
|
76
|
+
echo " ✗ Failed to update"
|
|
77
|
+
return 1
|
|
78
|
+
fi
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Update AgentVibes workspace
|
|
82
|
+
echo "🔧 AgentVibes workspace:"
|
|
83
|
+
update_colors "/home/fire/claude/AgentVibes/AgentVibes.code-workspace"
|
|
84
|
+
echo ""
|
|
85
|
+
|
|
86
|
+
echo "✅ All done! Reload VS Code window to see the purple theme."
|
|
87
|
+
echo ""
|
|
88
|
+
echo "💡 To reload: Press Ctrl+Shift+P → 'Developer: Reload Window'"
|
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.2.0-beta.
|
|
4
|
+
"version": "2.2.0-beta.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
|
@@ -800,6 +800,16 @@ async function install(options = {}) {
|
|
|
800
800
|
}
|
|
801
801
|
console.log('');
|
|
802
802
|
|
|
803
|
+
// Pause to let user review installation summary
|
|
804
|
+
await inquirer.prompt([
|
|
805
|
+
{
|
|
806
|
+
type: 'confirm',
|
|
807
|
+
name: 'continue',
|
|
808
|
+
message: chalk.cyan('📋 Review the installation summary above. Continue?'),
|
|
809
|
+
default: true,
|
|
810
|
+
}
|
|
811
|
+
]);
|
|
812
|
+
|
|
803
813
|
// Show recent changes from git log or RELEASE_NOTES.md
|
|
804
814
|
try {
|
|
805
815
|
const { execSync } = await import('node:child_process');
|
|
@@ -858,6 +868,16 @@ async function install(options = {}) {
|
|
|
858
868
|
}
|
|
859
869
|
}
|
|
860
870
|
|
|
871
|
+
// Pause to let user review recent changes
|
|
872
|
+
await inquirer.prompt([
|
|
873
|
+
{
|
|
874
|
+
type: 'confirm',
|
|
875
|
+
name: 'continue',
|
|
876
|
+
message: chalk.cyan('📝 Review the recent changes above. Continue?'),
|
|
877
|
+
default: true,
|
|
878
|
+
}
|
|
879
|
+
]);
|
|
880
|
+
|
|
861
881
|
// Success message
|
|
862
882
|
console.log(
|
|
863
883
|
boxen(
|
|
@@ -903,19 +923,38 @@ async function install(options = {}) {
|
|
|
903
923
|
console.log(chalk.gray(' • /agent-vibes:switch <name> - Change your voice'));
|
|
904
924
|
console.log(chalk.gray(' • /agent-vibes:personality <style> - Set personality\n'));
|
|
905
925
|
|
|
926
|
+
// Pause to let user review setup instructions
|
|
927
|
+
await inquirer.prompt([
|
|
928
|
+
{
|
|
929
|
+
type: 'confirm',
|
|
930
|
+
name: 'continue',
|
|
931
|
+
message: chalk.yellow('⚠️ Important: Did you note the setup steps above? Continue?'),
|
|
932
|
+
default: true,
|
|
933
|
+
}
|
|
934
|
+
]);
|
|
935
|
+
|
|
906
936
|
// Recommend MCP Server installation
|
|
907
937
|
console.log(
|
|
908
938
|
boxen(
|
|
909
939
|
chalk.cyan.bold('🎙️ Want Natural Language Control?\n\n') +
|
|
910
|
-
chalk.white.bold('AgentVibes MCP Server -
|
|
911
|
-
chalk.gray('Use
|
|
940
|
+
chalk.white.bold('AgentVibes MCP Server - Control TTS with Natural Language!\n\n') +
|
|
941
|
+
chalk.gray('Use natural language instead of slash commands:\n') +
|
|
912
942
|
chalk.gray(' "Switch to Aria voice" instead of /agent-vibes:switch "Aria"\n') +
|
|
913
943
|
chalk.gray(' "Set personality to sarcastic" instead of /agent-vibes:personality sarcastic\n\n') +
|
|
914
|
-
chalk.cyan('
|
|
915
|
-
chalk.cyan
|
|
916
|
-
chalk.gray('
|
|
917
|
-
chalk.
|
|
918
|
-
chalk.
|
|
944
|
+
chalk.cyan('📋 Claude Code MCP Configuration:\n\n') +
|
|
945
|
+
chalk.white('Add this to your ') + chalk.cyan('~/.claude/mcp.json') + chalk.white(':\n\n') +
|
|
946
|
+
chalk.gray('{\n') +
|
|
947
|
+
chalk.gray(' "mcpServers": {\n') +
|
|
948
|
+
chalk.gray(' "agentvibes": {\n') +
|
|
949
|
+
chalk.gray(' "command": "npx",\n') +
|
|
950
|
+
chalk.gray(' "args": ["-y", "agentvibes-mcp-server"]\n') +
|
|
951
|
+
chalk.gray(' }\n') +
|
|
952
|
+
chalk.gray(' }\n') +
|
|
953
|
+
chalk.gray('}\n\n') +
|
|
954
|
+
chalk.cyan('📱 Claude Desktop / Warp Terminal:\n') +
|
|
955
|
+
chalk.white(' npx agentvibes setup-mcp-for-claude-desktop\n\n') +
|
|
956
|
+
chalk.cyan('📖 Full Guide:\n') +
|
|
957
|
+
chalk.cyan.bold('https://github.com/paulpreibisch/AgentVibes#mcp-server'),
|
|
919
958
|
{
|
|
920
959
|
padding: 1,
|
|
921
960
|
margin: 1,
|
|
@@ -925,6 +964,16 @@ async function install(options = {}) {
|
|
|
925
964
|
)
|
|
926
965
|
);
|
|
927
966
|
|
|
967
|
+
// Pause to let user review MCP server info
|
|
968
|
+
await inquirer.prompt([
|
|
969
|
+
{
|
|
970
|
+
type: 'confirm',
|
|
971
|
+
name: 'continue',
|
|
972
|
+
message: chalk.cyan('🎙️ Review MCP Server setup info above. Continue?'),
|
|
973
|
+
default: true,
|
|
974
|
+
}
|
|
975
|
+
]);
|
|
976
|
+
|
|
928
977
|
// Check for BMAD installation (both v4 and v6)
|
|
929
978
|
const bmadDetection = await detectBMAD(targetDir);
|
|
930
979
|
const bmadDetected = bmadDetection.installed;
|