Skip to content

Commit 7e2ac20

Browse files
Paul Preibischclaude
andcommitted
Release v2.14.19 - BMAD TTS Injection Improvements
Improve TTS injection feature for BMAD agents with better backups and summary: - Organized backups: All backups now saved in .agentvibes/backups/agents/ with timestamps - Better summary: See exactly which files were modified and how to restore them - Improved reliability: Better file handling to ensure agent files are always preserved - Shell compatibility: Works on more systems including older bash versions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 59dd26a commit 7e2ac20

File tree

3 files changed

+205
-10
lines changed

3 files changed

+205
-10
lines changed

.claude/hooks/bmad-tts-injector.sh

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,20 @@ inject_tts() {
210210
return 0
211211
fi
212212

213-
# Create backup
213+
# Create backup directory for centralized timestamped backups
214+
local backup_dir=".agentvibes/backups/agents"
215+
mkdir -p "$backup_dir"
216+
217+
# Create timestamped backup in central location (for permanent archive)
218+
local timestamp=$(date +%Y%m%d_%H%M%S)
219+
local backup_name="$(basename "$agent_file" .md)_${timestamp}.md"
220+
cp "$agent_file" "$backup_dir/$backup_name"
221+
222+
# Also create quick-restore backup next to original file
214223
cp "$agent_file" "$agent_file.backup-pre-tts"
215224

225+
echo -e "${GRAY} 📦 Backup saved: $backup_dir/$backup_name${NC}"
226+
216227
# Detect v4 vs v6 structure
217228
local is_v6=false
218229
if grep -q "<activation" "$agent_file"; then
@@ -249,6 +260,15 @@ inject_tts() {
249260
{ print }
250261
' "$agent_file" > "$agent_file.tmp"
251262

263+
# SAFETY CHECK: Verify the tmp file is not empty before comparing
264+
local tmp_size=$(stat -c%s "$agent_file.tmp" 2>/dev/null || stat -f%z "$agent_file.tmp" 2>/dev/null || echo "0")
265+
if [[ "$tmp_size" -eq 0 ]]; then
266+
echo -e "${RED}❌ SAFETY: Refusing to overwrite - tmp file is empty: $(basename "$agent_file")${NC}" >&2
267+
rm -f "$agent_file.tmp"
268+
mv "$agent_file.backup-pre-tts" "$agent_file"
269+
return 1
270+
fi
271+
252272
# If no change (step 4 didn't match), restore backup and report
253273
if ! diff -q "$agent_file.backup-pre-tts" "$agent_file.tmp" > /dev/null 2>&1; then
254274
: # Changes were made, continue
@@ -284,6 +304,29 @@ inject_tts() {
284304
}
285305
{ print }
286306
' "$agent_file" > "$agent_file.tmp"
307+
308+
# SAFETY CHECK: Verify the tmp file is not empty and has similar size to original
309+
# This prevents data loss if awk fails or produces empty output
310+
local original_size=$(stat -c%s "$agent_file" 2>/dev/null || stat -f%z "$agent_file" 2>/dev/null || echo "0")
311+
local tmp_size=$(stat -c%s "$agent_file.tmp" 2>/dev/null || stat -f%z "$agent_file.tmp" 2>/dev/null || echo "0")
312+
313+
if [[ "$tmp_size" -eq 0 ]]; then
314+
echo -e "${RED}❌ SAFETY: Refusing to overwrite - tmp file is empty: $(basename "$agent_file")${NC}" >&2
315+
rm -f "$agent_file.tmp"
316+
mv "$agent_file.backup-pre-tts" "$agent_file"
317+
return 1
318+
fi
319+
320+
# Tmp file should be at least 80% of original size (protects against truncation)
321+
# No upper limit since injection adds substantial content (typically 300-500 bytes)
322+
local min_size=$((original_size * 80 / 100))
323+
324+
if [[ "$tmp_size" -lt "$min_size" ]]; then
325+
echo -e "${RED}❌ SAFETY: Refusing to overwrite - file would shrink too much (orig: ${original_size}B, tmp: ${tmp_size}B): $(basename "$agent_file")${NC}" >&2
326+
rm -f "$agent_file.tmp"
327+
mv "$agent_file.backup-pre-tts" "$agent_file"
328+
return 1
329+
fi
287330
fi
288331

289332
mv "$agent_file.tmp" "$agent_file"
@@ -336,10 +379,10 @@ show_status() {
336379
if has_tts_injection "$agent_file"; then
337380
local voice=$(get_agent_voice "$agent_id")
338381
echo -e " ${GREEN}${NC} $agent_name (${agent_id}) → Voice: ${voice:-default}"
339-
((enabled_count++))
382+
enabled_count=$((enabled_count + 1))
340383
else
341384
echo -e " ${GRAY}$agent_name (${agent_id})${NC}"
342-
((disabled_count++))
385+
disabled_count=$((disabled_count + 1))
343386
fi
344387
done <<< "$agents"
345388

@@ -360,21 +403,62 @@ enable_all() {
360403
local agents=$(find_agents "$bmad_core")
361404
local success_count=0
362405
local skip_count=0
406+
local fail_count=0
407+
408+
# Track modified files and backups for summary
409+
local modified_files=()
410+
local backup_files=()
363411

364412
while IFS= read -r agent_file; do
365413
if has_tts_injection "$agent_file"; then
366-
((skip_count++))
414+
skip_count=$((skip_count + 1))
367415
continue
368416
fi
369417

370418
if inject_tts "$agent_file"; then
371-
((success_count++))
419+
success_count=$((success_count + 1))
420+
modified_files+=("$agent_file")
421+
# Track the backup file that was created
422+
local timestamp=$(date +%Y%m%d_%H%M%S)
423+
local backup_name="$(basename "$agent_file" .md)_${timestamp}.md"
424+
backup_files+=(".agentvibes/backups/agents/$backup_name")
425+
else
426+
fail_count=$((fail_count + 1))
372427
fi
373428
done <<< "$agents"
374429

375430
echo ""
376-
echo -e "${GREEN}🎉 TTS enabled for $success_count agents${NC}"
377-
[[ $skip_count -gt 0 ]] && echo -e "${YELLOW} Skipped $skip_count agents (already enabled)${NC}"
431+
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
432+
echo -e "${CYAN} TTS INJECTION SUMMARY ${NC}"
433+
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
434+
echo ""
435+
436+
# Show results
437+
echo -e "${GREEN}✅ Successfully modified: $success_count agents${NC}"
438+
[[ $skip_count -gt 0 ]] && echo -e "${YELLOW}⏭️ Skipped (already enabled): $skip_count agents${NC}"
439+
[[ $fail_count -gt 0 ]] && echo -e "${RED}❌ Failed: $fail_count agents${NC}"
440+
echo ""
441+
442+
# List modified files
443+
if [[ ${#modified_files[@]} -gt 0 ]]; then
444+
echo -e "${CYAN}📝 Modified Files:${NC}"
445+
for file in "${modified_files[@]}"; do
446+
echo -e "$file"
447+
done
448+
echo ""
449+
fi
450+
451+
# Show backup location
452+
if [[ ${#modified_files[@]} -gt 0 ]]; then
453+
echo -e "${CYAN}📦 Backups saved to:${NC}"
454+
echo -e " .agentvibes/backups/agents/"
455+
echo ""
456+
echo -e "${CYAN}🔄 To restore original files, run:${NC}"
457+
echo -e " ${GREEN}.claude/hooks/bmad-tts-injector.sh restore${NC}"
458+
echo ""
459+
fi
460+
461+
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
378462
echo ""
379463
echo -e "${CYAN}💡 BMAD agents will now speak when activated!${NC}"
380464
}
@@ -394,7 +478,7 @@ disable_all() {
394478

395479
while IFS= read -r agent_file; do
396480
if remove_tts "$agent_file"; then
397-
((success_count++))
481+
success_count=$((success_count + 1))
398482
fi
399483
done <<< "$agents"
400484

@@ -430,7 +514,7 @@ restore_backup() {
430514
local original_file="${backup_file%.backup-pre-tts}"
431515
cp "$backup_file" "$original_file"
432516
echo -e "${GREEN}✅ Restored: $(basename "$original_file")${NC}"
433-
((backup_count++))
517+
backup_count=$((backup_count + 1))
434518
fi
435519
done
436520

RELEASE_NOTES.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,114 @@
1+
# Release v2.14.19 - BMAD TTS Injection Improvements
2+
3+
**Release Date:** 2025-12-05
4+
**Type:** Patch Release
5+
6+
## AI Summary
7+
8+
AgentVibes v2.14.19 improves the BMAD TTS injection feature with better file handling, organized backups, and a more informative summary when enabling voice support for your BMAD agents.
9+
10+
**Key Highlights:**
11+
- 📦 **Organized Backups** - All backups now saved in `.agentvibes/backups/agents/` with timestamps
12+
- 📋 **Better Summary** - See exactly which files were modified and how to restore them
13+
- 🔧 **Improved Reliability** - Better file handling to ensure agent files are always preserved
14+
- 🐚 **Shell Compatibility** - Works on more systems including older bash versions
15+
16+
---
17+
18+
## What is TTS Injection?
19+
20+
**TTS (Text-to-Speech) Injection** is a feature that makes your BMAD agents talk! When you install BMAD with AgentVibes, it adds voice instructions to each agent file so they can speak their responses aloud.
21+
22+
### How it works:
23+
24+
1. **Before TTS Injection** - Your BMAD agents (PM, Architect, UX Designer, etc.) only display text responses
25+
2. **After TTS Injection** - Each agent can speak their responses using your chosen voice
26+
27+
### Example:
28+
29+
When you activate the PM agent, instead of just seeing text, you'll hear:
30+
> "Hey! I'm Marcus, your Project Manager. What can I help you with today?"
31+
32+
The injection adds a small instruction to each agent file that tells it to use AgentVibes for voice output. Your original agent files are always backed up before any changes.
33+
34+
---
35+
36+
## What's New in This Release
37+
38+
### Organized Backup System
39+
40+
When TTS is enabled on your agents, backups are now saved in one central location:
41+
42+
```
43+
.agentvibes/backups/agents/
44+
├── pm_20251205_143022.md
45+
├── architect_20251205_143022.md
46+
├── ux-designer_20251205_143022.md
47+
└── ...
48+
```
49+
50+
Each backup includes a timestamp so you can see exactly when it was created.
51+
52+
### Informative Summary
53+
54+
After enabling TTS, you'll see a clear summary:
55+
56+
```
57+
═══════════════════════════════════════════════════════════════
58+
TTS INJECTION SUMMARY
59+
═══════════════════════════════════════════════════════════════
60+
61+
✅ Successfully modified: 11 agents
62+
63+
📝 Modified Files:
64+
• .bmad/bmm/agents/pm.md
65+
• .bmad/bmm/agents/architect.md
66+
• .bmad/bmm/agents/ux-designer.md
67+
• ...
68+
69+
📦 Backups saved to:
70+
.agentvibes/backups/agents/
71+
72+
🔄 To restore original files, run:
73+
.claude/hooks/bmad-tts-injector.sh restore
74+
75+
💡 BMAD agents will now speak when activated!
76+
```
77+
78+
### Improved Reliability
79+
80+
The script now includes extra checks to make sure your agent files are always safe:
81+
- Creates a backup before making any changes
82+
- Verifies changes were successful before saving
83+
- Automatically restores from backup if anything goes wrong
84+
85+
---
86+
87+
## Files Modified
88+
89+
| File | Changes |
90+
|------|---------|
91+
| `.claude/hooks/bmad-tts-injector.sh` | Backup organization, summary output, reliability improvements |
92+
93+
---
94+
95+
## Testing
96+
97+
- ✅ All 132 BATS tests pass
98+
- ✅ All 12 Node.js tests pass
99+
100+
---
101+
102+
## Upgrade
103+
104+
```bash
105+
npx agentvibes update
106+
```
107+
108+
---
109+
110+
---
111+
1112
# Release v2.14.18 - Mute/Unmute TTS Control
2113

3114
**Release Date:** 2025-12-03

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://json.schemastore.org/package.json",
33
"name": "agentvibes",
4-
"version": "2.14.18",
4+
"version": "2.14.19",
55
"description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code and Claude Desktop (via MCP) with multi-provider support.",
66
"homepage": "https://agentvibes.org",
77
"keywords": [

0 commit comments

Comments
 (0)