agentvibes 2.0.20 → 2.0.22

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.
Files changed (233) hide show
  1. package/.claude/agents/health-coach.md +154 -0
  2. package/.claude/agents/motivator.md +171 -0
  3. package/.claude/agents/negotiator.md +97 -0
  4. package/.claude/commands/agent-vibes/agent-health-coach.md +15 -0
  5. package/.claude/commands/agent-vibes/agent-motivator.md +15 -0
  6. package/.claude/commands/agent-vibes/agent-negotiator.md +15 -0
  7. package/.claude/commands/agent-vibes/agent.md +79 -0
  8. package/.claude/commands/agent-vibes/commands.json +4 -0
  9. package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -0
  10. package/.claude/github-star-reminder.txt +1 -1
  11. package/.claude/hooks/download-extra-voices.sh +244 -0
  12. package/.claude/hooks/personality-manager.sh +81 -0
  13. package/.claude/hooks/piper-download-voices.sh +3 -93
  14. package/.claude/hooks/piper-multispeaker-registry.sh +165 -0
  15. package/.claude/hooks/play-tts-elevenlabs.sh +5 -3
  16. package/.claude/hooks/play-tts-piper.sh +27 -44
  17. package/.claude/hooks/provider-manager.sh +24 -5
  18. package/.claude/hooks/speed-manager.sh +10 -12
  19. package/.claude/hooks/voice-manager.sh +94 -56
  20. package/README.md +0 -3
  21. package/RELEASE_NOTES.md +40 -247
  22. package/docs/agents.md +485 -0
  23. package/docs/commands.md +1 -21
  24. package/docs/extra-voices-implementation-summary.md +235 -0
  25. package/docs/voice-registration-fix.md +254 -0
  26. package/fix-vscode-colors.sh +88 -0
  27. package/fixcolors +88 -0
  28. package/generate-all-agent-voices.sh +174 -0
  29. package/generate-missing-elevenlabs-complete.sh +236 -0
  30. package/generate-missing-elevenlabs.sh +110 -0
  31. package/generate-new-voices.sh +108 -0
  32. package/generate-piper-agent-intros.sh +85 -0
  33. package/generate-provider-and-agent-intros.sh +136 -0
  34. package/logo/fav_icon_128x128.png +0 -0
  35. package/logo/fav_icon_128x128.png:Zone.Identifier +4 -0
  36. package/logo/logo1.webp +0 -0
  37. package/logo/logo1.webp:Zone.Identifier +4 -0
  38. package/logo/social.png +0 -0
  39. package/logo/social.png:Zone.Identifier +4 -0
  40. package/mcp-server/agentvibes.db +0 -0
  41. package/mcp-server/server.py +47 -14
  42. package/package.json +3 -3
  43. package/regenerate-agent-voices.sh +79 -0
  44. package/test/unit/provider-manager.bats +8 -5
  45. package/test/unit/speed-manager.bats +4 -4
  46. package/agentvibes.org/.claude/audio/tts-padded-1760744118.mp3 +0 -0
  47. package/agentvibes.org/.claude/audio/tts-padded-1760748535.mp3 +0 -0
  48. package/agentvibes.org/.claude/audio/tts-padded-1760748676.mp3 +0 -0
  49. package/agentvibes.org/.claude/audio/tts-padded-1760750748.mp3 +0 -0
  50. package/agentvibes.org/.claude/audio/tts-padded-1760750947.mp3 +0 -0
  51. package/agentvibes.org/.claude/audio/tts-padded-1760752718.mp3 +0 -0
  52. package/agentvibes.org/.claude/audio/tts-padded-1760752907.mp3 +0 -0
  53. package/agentvibes.org/.claude/audio/tts-padded-1760753017.mp3 +0 -0
  54. package/agentvibes.org/.claude/audio/tts-padded-1760753045.mp3 +0 -0
  55. package/agentvibes.org/.claude/audio/tts-padded-1760753241.mp3 +0 -0
  56. package/agentvibes.org/.claude/audio/tts-padded-1760753315.mp3 +0 -0
  57. package/agentvibes.org/.claude/audio/tts-padded-1760753382.mp3 +0 -0
  58. package/agentvibes.org/.claude/audio/tts-padded-1760753408.mp3 +0 -0
  59. package/agentvibes.org/.claude/audio/tts-padded-1760753426.mp3 +0 -0
  60. package/agentvibes.org/.claude/audio/tts-padded-1760753446.mp3 +0 -0
  61. package/agentvibes.org/.claude/audio/tts-padded-1760753541.mp3 +0 -0
  62. package/agentvibes.org/.claude/audio/tts-padded-1760753553.mp3 +0 -0
  63. package/agentvibes.org/.claude/audio/tts-padded-1760753577.mp3 +0 -0
  64. package/agentvibes.org/.claude/commands/agent-vibes/add.md +0 -21
  65. package/agentvibes.org/.claude/commands/agent-vibes/agent-vibes.md +0 -68
  66. package/agentvibes.org/.claude/commands/agent-vibes/bmad.md +0 -196
  67. package/agentvibes.org/.claude/commands/agent-vibes/commands.json +0 -77
  68. package/agentvibes.org/.claude/commands/agent-vibes/get.md +0 -9
  69. package/agentvibes.org/.claude/commands/agent-vibes/language.md +0 -23
  70. package/agentvibes.org/.claude/commands/agent-vibes/learn.md +0 -67
  71. package/agentvibes.org/.claude/commands/agent-vibes/list.md +0 -13
  72. package/agentvibes.org/.claude/commands/agent-vibes/personality.md +0 -79
  73. package/agentvibes.org/.claude/commands/agent-vibes/preview.md +0 -17
  74. package/agentvibes.org/.claude/commands/agent-vibes/provider.md +0 -54
  75. package/agentvibes.org/.claude/commands/agent-vibes/replay-target.md +0 -14
  76. package/agentvibes.org/.claude/commands/agent-vibes/replay.md +0 -19
  77. package/agentvibes.org/.claude/commands/agent-vibes/sample.md +0 -12
  78. package/agentvibes.org/.claude/commands/agent-vibes/sentiment.md +0 -52
  79. package/agentvibes.org/.claude/commands/agent-vibes/set-language.md +0 -47
  80. package/agentvibes.org/.claude/commands/agent-vibes/set-pretext.md +0 -65
  81. package/agentvibes.org/.claude/commands/agent-vibes/set-speed.md +0 -41
  82. package/agentvibes.org/.claude/commands/agent-vibes/switch.md +0 -53
  83. package/agentvibes.org/.claude/commands/agent-vibes/target-voice.md +0 -26
  84. package/agentvibes.org/.claude/commands/agent-vibes/target.md +0 -30
  85. package/agentvibes.org/.claude/commands/agent-vibes/update.md +0 -20
  86. package/agentvibes.org/.claude/commands/agent-vibes/version.md +0 -10
  87. package/agentvibes.org/.claude/commands/agent-vibes/whoami.md +0 -7
  88. package/agentvibes.org/.claude/hooks/bmad-tts-injector.sh +0 -386
  89. package/agentvibes.org/.claude/hooks/bmad-voice-manager.sh +0 -375
  90. package/agentvibes.org/.claude/hooks/check-output-style.sh +0 -60
  91. package/agentvibes.org/.claude/hooks/github-star-reminder.sh +0 -94
  92. package/agentvibes.org/.claude/hooks/language-manager.sh +0 -360
  93. package/agentvibes.org/.claude/hooks/learn-manager.sh +0 -443
  94. package/agentvibes.org/.claude/hooks/personality-manager.sh +0 -324
  95. package/agentvibes.org/.claude/hooks/piper-download-voices.sh +0 -133
  96. package/agentvibes.org/.claude/hooks/piper-installer.sh +0 -144
  97. package/agentvibes.org/.claude/hooks/piper-voice-manager.sh +0 -227
  98. package/agentvibes.org/.claude/hooks/play-tts-elevenlabs.sh +0 -376
  99. package/agentvibes.org/.claude/hooks/play-tts-piper.sh +0 -281
  100. package/agentvibes.org/.claude/hooks/play-tts.sh +0 -69
  101. package/agentvibes.org/.claude/hooks/provider-commands.sh +0 -505
  102. package/agentvibes.org/.claude/hooks/provider-manager.sh +0 -248
  103. package/agentvibes.org/.claude/hooks/replay-target-audio.sh +0 -64
  104. package/agentvibes.org/.claude/hooks/sentiment-manager.sh +0 -163
  105. package/agentvibes.org/.claude/hooks/speed-manager.sh +0 -259
  106. package/agentvibes.org/.claude/hooks/voice-manager.sh +0 -477
  107. package/agentvibes.org/.claude/hooks/voices-config.sh +0 -33
  108. package/agentvibes.org/.claude/journal/2025-10-07.html +0 -373
  109. package/agentvibes.org/.claude/journal/index.html +0 -91
  110. package/agentvibes.org/.claude/output-styles/agent-vibes.md +0 -203
  111. package/agentvibes.org/.claude/personalities/angry.md +0 -17
  112. package/agentvibes.org/.claude/personalities/annoying.md +0 -17
  113. package/agentvibes.org/.claude/personalities/crass.md +0 -17
  114. package/agentvibes.org/.claude/personalities/dramatic.md +0 -17
  115. package/agentvibes.org/.claude/personalities/dry-humor.md +0 -53
  116. package/agentvibes.org/.claude/personalities/flirty.md +0 -23
  117. package/agentvibes.org/.claude/personalities/funny.md +0 -17
  118. package/agentvibes.org/.claude/personalities/grandpa.md +0 -35
  119. package/agentvibes.org/.claude/personalities/millennial.md +0 -17
  120. package/agentvibes.org/.claude/personalities/moody.md +0 -17
  121. package/agentvibes.org/.claude/personalities/normal.md +0 -19
  122. package/agentvibes.org/.claude/personalities/pirate.md +0 -17
  123. package/agentvibes.org/.claude/personalities/poetic.md +0 -17
  124. package/agentvibes.org/.claude/personalities/professional.md +0 -17
  125. package/agentvibes.org/.claude/personalities/robot.md +0 -17
  126. package/agentvibes.org/.claude/personalities/sarcastic.md +0 -41
  127. package/agentvibes.org/.claude/personalities/sassy.md +0 -17
  128. package/agentvibes.org/.claude/personalities/surfer-dude.md +0 -17
  129. package/agentvibes.org/.claude/personalities/zen.md +0 -17
  130. package/agentvibes.org/.claude/piper-voices-dir.txt +0 -1
  131. package/agentvibes.org/.claude/plugins/bmad-voices.md +0 -42
  132. package/agentvibes.org/.claude/tts-provider.txt +0 -1
  133. package/agentvibes.org/.mcp-minimal.json +0 -60
  134. package/agentvibes.org/CHANGELOG.md +0 -56
  135. package/agentvibes.org/README.md +0 -93
  136. package/agentvibes.org/app/(auth)/layout.tsx +0 -15
  137. package/agentvibes.org/app/(auth)/reset-password/page.tsx +0 -45
  138. package/agentvibes.org/app/(auth)/signin/page.tsx +0 -82
  139. package/agentvibes.org/app/(auth)/signup/page.tsx +0 -104
  140. package/agentvibes.org/app/(default)/blog/[slug]/page.tsx +0 -128
  141. package/agentvibes.org/app/(default)/blog/page.tsx +0 -95
  142. package/agentvibes.org/app/(default)/layout.tsx +0 -31
  143. package/agentvibes.org/app/(default)/page.tsx +0 -20
  144. package/agentvibes.org/app/api/hello/route.ts +0 -3
  145. package/agentvibes.org/app/css/additional-styles/theme.css +0 -82
  146. package/agentvibes.org/app/css/additional-styles/utility-patterns.css +0 -55
  147. package/agentvibes.org/app/css/style.css +0 -100
  148. package/agentvibes.org/app/layout.tsx +0 -63
  149. package/agentvibes.org/components/code-block.tsx +0 -27
  150. package/agentvibes.org/components/cta.tsx +0 -58
  151. package/agentvibes.org/components/features.tsx +0 -256
  152. package/agentvibes.org/components/hero-home.tsx +0 -133
  153. package/agentvibes.org/components/mdx-components.tsx +0 -128
  154. package/agentvibes.org/components/modal-video.tsx +0 -137
  155. package/agentvibes.org/components/page-illustration.tsx +0 -55
  156. package/agentvibes.org/components/spotlight.tsx +0 -77
  157. package/agentvibes.org/components/testimonials.tsx +0 -282
  158. package/agentvibes.org/components/ui/footer.tsx +0 -82
  159. package/agentvibes.org/components/ui/header.tsx +0 -68
  160. package/agentvibes.org/components/ui/logo.tsx +0 -10
  161. package/agentvibes.org/components/workflows.tsx +0 -176
  162. package/agentvibes.org/content/blog/discovering-new-piper-voices.mdx +0 -253
  163. package/agentvibes.org/content/blog/getting-started-agentvibes.mdx +0 -228
  164. package/agentvibes.org/content/blog/introducing-agentvibes-v2.mdx +0 -250
  165. package/agentvibes.org/content/blog/language-learning-with-agentvibes.mdx +0 -142
  166. package/agentvibes.org/content/blog/voice-personalities-guide.mdx +0 -119
  167. package/agentvibes.org/lib/blog.ts +0 -73
  168. package/agentvibes.org/next.config.js +0 -6
  169. package/agentvibes.org/package-lock.json +0 -4285
  170. package/agentvibes.org/package.json +0 -40
  171. package/agentvibes.org/pnpm-lock.yaml +0 -1141
  172. package/agentvibes.org/postcss.config.js +0 -5
  173. package/agentvibes.org/public/audio/02-sarcastic.mp3 +0 -0
  174. package/agentvibes.org/public/audio/03-angry.mp3 +0 -0
  175. package/agentvibes.org/public/audio/04-grandpa.mp3 +0 -0
  176. package/agentvibes.org/public/audio/05-sarcastic-example2.mp3 +0 -0
  177. package/agentvibes.org/public/audio/french-rachel.mp3 +0 -0
  178. package/agentvibes.org/public/audio/piper-voices/speaker_0_Cori_Samuel.wav +0 -0
  179. package/agentvibes.org/public/audio/piper-voices/speaker_10_Steve_C.wav +0 -0
  180. package/agentvibes.org/public/audio/piper-voices/speaker_11_Owlivia.wav +0 -0
  181. package/agentvibes.org/public/audio/piper-voices/speaker_12_Paul_Hampton.wav +0 -0
  182. package/agentvibes.org/public/audio/piper-voices/speaker_13_Jennifer_Dorr.wav +0 -0
  183. package/agentvibes.org/public/audio/piper-voices/speaker_14_Emily_Cripps.wav +0 -0
  184. package/agentvibes.org/public/audio/piper-voices/speaker_15_Martin_Clifton.wav +0 -0
  185. package/agentvibes.org/public/audio/piper-voices/speaker_1_Kara_Shallenberg.wav +0 -0
  186. package/agentvibes.org/public/audio/piper-voices/speaker_2_Kristin_Hughes.wav +0 -0
  187. package/agentvibes.org/public/audio/piper-voices/speaker_3_Maria_Kasper.wav +0 -0
  188. package/agentvibes.org/public/audio/piper-voices/speaker_4_Mike_Pelton.wav +0 -0
  189. package/agentvibes.org/public/audio/piper-voices/speaker_5_Mark_Nelson.wav +0 -0
  190. package/agentvibes.org/public/audio/piper-voices/speaker_6_Michael_Scherer.wav +0 -0
  191. package/agentvibes.org/public/audio/piper-voices/speaker_7_James_K_White.wav +0 -0
  192. package/agentvibes.org/public/audio/piper-voices/speaker_8_Rose_Ibex.wav +0 -0
  193. package/agentvibes.org/public/audio/piper-voices/speaker_9_progressingamerica.wav +0 -0
  194. package/agentvibes.org/public/audio/spanish-antoni.mp3 +0 -0
  195. package/agentvibes.org/public/favicon.ico +0 -0
  196. package/agentvibes.org/public/fonts/nacelle-italic.woff2 +0 -0
  197. package/agentvibes.org/public/fonts/nacelle-regular.woff2 +0 -0
  198. package/agentvibes.org/public/fonts/nacelle-semibold.woff2 +0 -0
  199. package/agentvibes.org/public/fonts/nacelle-semibolditalic.woff2 +0 -0
  200. package/agentvibes.org/public/images/blurred-shape-gray.svg +0 -1
  201. package/agentvibes.org/public/images/blurred-shape.svg +0 -1
  202. package/agentvibes.org/public/images/client-logo-01.svg +0 -1
  203. package/agentvibes.org/public/images/client-logo-02.svg +0 -1
  204. package/agentvibes.org/public/images/client-logo-03.svg +0 -1
  205. package/agentvibes.org/public/images/client-logo-04.svg +0 -1
  206. package/agentvibes.org/public/images/client-logo-05.svg +0 -1
  207. package/agentvibes.org/public/images/client-logo-06.svg +0 -1
  208. package/agentvibes.org/public/images/client-logo-07.svg +0 -1
  209. package/agentvibes.org/public/images/client-logo-08.svg +0 -1
  210. package/agentvibes.org/public/images/client-logo-09.svg +0 -1
  211. package/agentvibes.org/public/images/features.png +0 -0
  212. package/agentvibes.org/public/images/footer-illustration.svg +0 -1
  213. package/agentvibes.org/public/images/hero-image-01.jpg +0 -0
  214. package/agentvibes.org/public/images/logo.svg +0 -1
  215. package/agentvibes.org/public/images/page-illustration.svg +0 -1
  216. package/agentvibes.org/public/images/secondary-illustration.svg +0 -1
  217. package/agentvibes.org/public/images/testimonial-01.jpg +0 -0
  218. package/agentvibes.org/public/images/testimonial-02.jpg +0 -0
  219. package/agentvibes.org/public/images/testimonial-03.jpg +0 -0
  220. package/agentvibes.org/public/images/testimonial-04.jpg +0 -0
  221. package/agentvibes.org/public/images/testimonial-05.jpg +0 -0
  222. package/agentvibes.org/public/images/testimonial-06.jpg +0 -0
  223. package/agentvibes.org/public/images/testimonial-07.jpg +0 -0
  224. package/agentvibes.org/public/images/testimonial-08.jpg +0 -0
  225. package/agentvibes.org/public/images/testimonial-09.jpg +0 -0
  226. package/agentvibes.org/public/images/workflow-01.png +0 -0
  227. package/agentvibes.org/public/images/workflow-02.png +0 -0
  228. package/agentvibes.org/public/images/workflow-03.png +0 -0
  229. package/agentvibes.org/public/videos/video.mp4 +0 -0
  230. package/agentvibes.org/tsconfig.json +0 -28
  231. package/agentvibes.org/utils/useMasonry.tsx +0 -67
  232. package/agentvibes.org/utils/useMousePosition.tsx +0 -27
  233. package/docs/bryce-beattie-voice-licensing.md +0 -131
@@ -0,0 +1,244 @@
1
+ #!/bin/bash
2
+ #
3
+ # File: .claude/hooks/download-extra-voices.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, including but not limited to the warranties of
26
+ # merchantability, fitness for a particular purpose and noninfringement.
27
+ # In no event shall the authors or copyright holders be liable for any claim,
28
+ # damages or other liability, whether in an action of contract, tort or
29
+ # otherwise, arising from, out of or in connection with the software or the
30
+ # use or other dealings in the software.
31
+ #
32
+ # ---
33
+ #
34
+ # @fileoverview Extra Piper Voice Downloader - Downloads custom high-quality voices from HuggingFace
35
+ # @context Post-installation utility to download premium custom voices (Kristin, Jenny, Tracy/16Speakers)
36
+ # @architecture Downloads ONNX voice models from agentvibes/piper-custom-voices HuggingFace repository
37
+ # @dependencies curl (downloads), piper-voice-manager.sh (storage dir logic)
38
+ # @entrypoints Called by MCP server download_extra_voices tool or manually
39
+ # @patterns Batch downloads, skip-existing logic, auto-yes flag for non-interactive use
40
+ # @related piper-voice-manager.sh, mcp-server/server.py, docs/huggingface-setup-guide.md
41
+ #
42
+
43
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
44
+ source "$SCRIPT_DIR/piper-voice-manager.sh"
45
+
46
+ # Parse command line arguments
47
+ AUTO_YES=false
48
+ if [[ "$1" == "--yes" ]] || [[ "$1" == "-y" ]]; then
49
+ AUTO_YES=true
50
+ fi
51
+
52
+ # HuggingFace repository for custom voices
53
+ HUGGINGFACE_REPO="agentvibes/piper-custom-voices"
54
+ HUGGINGFACE_BASE_URL="https://huggingface.co/${HUGGINGFACE_REPO}/resolve/main"
55
+
56
+ # Extra custom voices to download
57
+ EXTRA_VOICES=(
58
+ "kristin:Kristin (US English female, Public Domain, 64MB)"
59
+ "jenny:Jenny (UK English female with Irish accent, CC BY, 64MB)"
60
+ "16Speakers:Tracy/16Speakers (Multi-speaker: 12 US + 4 UK voices, Public Domain, 77MB)"
61
+ )
62
+
63
+ echo "🎙️ AgentVibes Extra Voice Downloader"
64
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
65
+ echo ""
66
+ echo "This will download high-quality custom Piper voices from HuggingFace."
67
+ echo ""
68
+ echo "📦 Voices available:"
69
+ for voice_info in "${EXTRA_VOICES[@]}"; do
70
+ voice_name="${voice_info%%:*}"
71
+ voice_desc="${voice_info#*:}"
72
+ echo " • $voice_desc"
73
+ done
74
+ echo ""
75
+
76
+ # Check if piper is installed
77
+ if ! command -v piper &> /dev/null; then
78
+ echo "❌ Error: Piper TTS not installed"
79
+ echo "Install with: pipx install piper-tts"
80
+ exit 1
81
+ fi
82
+
83
+ # Get storage directory
84
+ VOICE_DIR=$(get_voice_storage_dir)
85
+ echo "📂 Storage location: $VOICE_DIR"
86
+ echo ""
87
+
88
+ # Count already downloaded
89
+ ALREADY_DOWNLOADED=0
90
+ ALREADY_DOWNLOADED_LIST=()
91
+ NEED_DOWNLOAD=()
92
+
93
+ for voice_info in "${EXTRA_VOICES[@]}"; do
94
+ voice_name="${voice_info%%:*}"
95
+ voice_desc="${voice_info#*:}"
96
+
97
+ # Check if both .onnx and .onnx.json exist
98
+ if [[ -f "$VOICE_DIR/${voice_name}.onnx" ]] && [[ -f "$VOICE_DIR/${voice_name}.onnx.json" ]]; then
99
+ ((ALREADY_DOWNLOADED++))
100
+ ALREADY_DOWNLOADED_LIST+=("$voice_desc")
101
+ else
102
+ NEED_DOWNLOAD+=("$voice_info")
103
+ fi
104
+ done
105
+
106
+ echo "📊 Status:"
107
+ echo " Already downloaded: $ALREADY_DOWNLOADED voice(s)"
108
+ echo " Need to download: ${#NEED_DOWNLOAD[@]} voice(s)"
109
+ echo ""
110
+
111
+ # Show already downloaded voices
112
+ if [[ $ALREADY_DOWNLOADED -gt 0 ]]; then
113
+ echo "✅ Already downloaded (skipped):"
114
+ for voice_desc in "${ALREADY_DOWNLOADED_LIST[@]}"; do
115
+ echo " ✓ $voice_desc"
116
+ done
117
+ echo ""
118
+ fi
119
+
120
+ if [[ ${#NEED_DOWNLOAD[@]} -eq 0 ]]; then
121
+ echo "🎉 All extra voices already downloaded!"
122
+ exit 0
123
+ fi
124
+
125
+ echo "Voices to download:"
126
+ for voice_info in "${NEED_DOWNLOAD[@]}"; do
127
+ voice_desc="${voice_info#*:}"
128
+ echo " • $voice_desc"
129
+ done
130
+ echo ""
131
+
132
+ # Calculate total size
133
+ TOTAL_SIZE_MB=0
134
+ for voice_info in "${NEED_DOWNLOAD[@]}"; do
135
+ voice_desc="${voice_info#*:}"
136
+ if [[ "$voice_desc" =~ ([0-9]+)MB ]]; then
137
+ TOTAL_SIZE_MB=$((TOTAL_SIZE_MB + ${BASH_REMATCH[1]}))
138
+ fi
139
+ done
140
+
141
+ echo "💾 Total download size: ~${TOTAL_SIZE_MB}MB"
142
+ echo ""
143
+
144
+ # Ask for confirmation (skip if --yes flag provided)
145
+ if [[ "$AUTO_YES" == "false" ]]; then
146
+ read -p "Download ${#NEED_DOWNLOAD[@]} extra voice(s)? [Y/n]: " -n 1 -r
147
+ echo
148
+
149
+ if [[ ! $REPLY =~ ^[Yy]$ ]] && [[ -n $REPLY ]]; then
150
+ echo "❌ Download cancelled"
151
+ exit 0
152
+ fi
153
+ else
154
+ echo "Auto-downloading ${#NEED_DOWNLOAD[@]} extra voice(s)..."
155
+ echo ""
156
+ fi
157
+
158
+ # Create voice directory if it doesn't exist
159
+ mkdir -p "$VOICE_DIR"
160
+
161
+ # Download function
162
+ download_voice_file() {
163
+ local url="$1"
164
+ local output_path="$2"
165
+ local file_name="$3"
166
+
167
+ echo " 📥 Downloading $file_name..."
168
+
169
+ if curl -L --progress-bar "$url" -o "$output_path" 2>&1; then
170
+ echo " ✅ Downloaded: $file_name"
171
+ return 0
172
+ else
173
+ echo " ❌ Failed to download: $file_name"
174
+ return 1
175
+ fi
176
+ }
177
+
178
+ # Download each voice
179
+ DOWNLOADED=0
180
+ FAILED=0
181
+
182
+ for voice_info in "${NEED_DOWNLOAD[@]}"; do
183
+ voice_name="${voice_info%%:*}"
184
+ voice_desc="${voice_info#*:}"
185
+
186
+ echo ""
187
+ echo "📥 Downloading: ${voice_desc%%,*}..."
188
+ echo ""
189
+
190
+ # Download .onnx file
191
+ onnx_url="${HUGGINGFACE_BASE_URL}/${voice_name}.onnx"
192
+ onnx_path="${VOICE_DIR}/${voice_name}.onnx"
193
+
194
+ # Download .onnx.json file
195
+ json_url="${HUGGINGFACE_BASE_URL}/${voice_name}.onnx.json"
196
+ json_path="${VOICE_DIR}/${voice_name}.onnx.json"
197
+
198
+ success=true
199
+
200
+ if ! download_voice_file "$onnx_url" "$onnx_path" "${voice_name}.onnx"; then
201
+ success=false
202
+ fi
203
+
204
+ if ! download_voice_file "$json_url" "$json_path" "${voice_name}.onnx.json"; then
205
+ success=false
206
+ fi
207
+
208
+ if [[ "$success" == "true" ]]; then
209
+ ((DOWNLOADED++))
210
+ echo ""
211
+ echo "✅ Successfully downloaded: ${voice_desc%%,*}"
212
+ else
213
+ ((FAILED++))
214
+ echo ""
215
+ echo "❌ Failed to download: ${voice_desc%%,*}"
216
+ # Clean up partial downloads
217
+ rm -f "$onnx_path" "$json_path"
218
+ fi
219
+ done
220
+
221
+ echo ""
222
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
223
+ echo "📊 Download Summary:"
224
+ echo " ✅ Successfully downloaded: $DOWNLOADED"
225
+ echo " ❌ Failed: $FAILED"
226
+ echo " 📦 Total extra voices available: $((ALREADY_DOWNLOADED + DOWNLOADED))"
227
+ echo ""
228
+
229
+ if [[ $DOWNLOADED -gt 0 ]]; then
230
+ echo "✨ Extra voices ready to use!"
231
+ echo ""
232
+ echo "Try them:"
233
+ echo " /agent-vibes:provider switch piper"
234
+ echo " /agent-vibes:switch kristin"
235
+ echo " /agent-vibes:switch jenny"
236
+ echo " /agent-vibes:switch 16Speakers"
237
+ fi
238
+
239
+ # Return success if at least one voice was downloaded or all were already present
240
+ if [[ $DOWNLOADED -gt 0 ]] || [[ $ALREADY_DOWNLOADED -gt 0 ]]; then
241
+ exit 0
242
+ else
243
+ exit 1
244
+ fi
@@ -333,6 +333,85 @@ EOF
333
333
  echo "🎭 Personality reset to: normal"
334
334
  ;;
335
335
 
336
+ set-favorite-voice)
337
+ PERSONALITY="$2"
338
+ NEW_VOICE="$3"
339
+
340
+ if [[ -z "$PERSONALITY" ]] || [[ -z "$NEW_VOICE" ]]; then
341
+ echo "❌ Please specify both personality name and voice name"
342
+ echo "Usage: $0 set-favorite-voice <personality> <voice>"
343
+ exit 1
344
+ fi
345
+
346
+ FILE="$PERSONALITIES_DIR/${PERSONALITY}.md"
347
+ if [[ ! -f "$FILE" ]]; then
348
+ echo "❌ Personality '$PERSONALITY' not found"
349
+ exit 1
350
+ fi
351
+
352
+ # Detect active TTS provider
353
+ PROVIDER_FILE=""
354
+ if [[ -f "$CLAUDE_DIR/tts-provider.txt" ]]; then
355
+ PROVIDER_FILE="$CLAUDE_DIR/tts-provider.txt"
356
+ elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
357
+ PROVIDER_FILE="$HOME/.claude/tts-provider.txt"
358
+ fi
359
+
360
+ ACTIVE_PROVIDER="elevenlabs" # default
361
+ if [[ -n "$PROVIDER_FILE" ]]; then
362
+ ACTIVE_PROVIDER=$(cat "$PROVIDER_FILE")
363
+ fi
364
+
365
+ # Determine which field to update based on provider
366
+ if [[ "$ACTIVE_PROVIDER" == "piper" ]]; then
367
+ VOICE_FIELD="piper_voice"
368
+ CURRENT_VOICE=$(get_personality_data "$PERSONALITY" "piper_voice")
369
+ else
370
+ VOICE_FIELD="elevenlabs_voice"
371
+ CURRENT_VOICE=$(get_personality_data "$PERSONALITY" "voice")
372
+ fi
373
+
374
+ # Check if personality already has a favorite voice assigned
375
+ if [[ -n "$CURRENT_VOICE" ]] && [[ "$CURRENT_VOICE" != "$NEW_VOICE" ]]; then
376
+ echo "⚠️ WARNING: Personality '$PERSONALITY' already has a favorite voice assigned!"
377
+ echo ""
378
+ echo " Current favorite ($ACTIVE_PROVIDER): $CURRENT_VOICE"
379
+ echo " New voice: $NEW_VOICE"
380
+ echo ""
381
+ echo "Do you want to replace the favorite voice?"
382
+ echo ""
383
+ read -p "Enter your choice (yes/no): " CHOICE
384
+
385
+ case "$CHOICE" in
386
+ yes|y|YES|Y)
387
+ echo "✅ Replacing favorite voice..."
388
+ ;;
389
+ no|n|NO|N)
390
+ echo "❌ Keeping current favorite voice: $CURRENT_VOICE"
391
+ exit 0
392
+ ;;
393
+ *)
394
+ echo "❌ Invalid choice. Keeping current favorite voice: $CURRENT_VOICE"
395
+ exit 1
396
+ ;;
397
+ esac
398
+ fi
399
+
400
+ # Update the voice in the personality file
401
+ if grep -q "^${VOICE_FIELD}:" "$FILE"; then
402
+ # Field exists, replace it
403
+ sed -i "s/^${VOICE_FIELD}:.*/${VOICE_FIELD}: ${NEW_VOICE}/" "$FILE"
404
+ else
405
+ # Field doesn't exist, add it after the frontmatter
406
+ sed -i "/^---$/,/^---$/ { /^---$/a\\
407
+ ${VOICE_FIELD}: ${NEW_VOICE}
408
+ }" "$FILE"
409
+ fi
410
+
411
+ echo "✅ Favorite voice for '$PERSONALITY' personality set to: $NEW_VOICE ($ACTIVE_PROVIDER)"
412
+ echo "📝 Updated file: $FILE"
413
+ ;;
414
+
336
415
  *)
337
416
  # If a single argument is provided and it's not a command, treat it as "set <personality>"
338
417
  if [[ -n "$1" ]] && [[ -f "$PERSONALITIES_DIR/${1}.md" || "$1" == "random" ]]; then
@@ -347,11 +426,13 @@ EOF
347
426
  echo " add <name> - Create new personality"
348
427
  echo " edit <name> - Show path to edit personality"
349
428
  echo " get - Show current personality"
429
+ echo " set-favorite-voice <name> <voice> - Set favorite voice for a personality"
350
430
  echo " reset - Reset to normal"
351
431
  echo ""
352
432
  echo "Examples:"
353
433
  echo " /agent-vibes:personality flirty"
354
434
  echo " /agent-vibes:personality add cowboy"
435
+ echo " /agent-vibes:personality set-favorite-voice flirty \"Aria\""
355
436
  fi
356
437
  ;;
357
438
  esac
@@ -49,7 +49,7 @@ if [[ "$1" == "--yes" ]] || [[ "$1" == "-y" ]]; then
49
49
  AUTO_YES=true
50
50
  fi
51
51
 
52
- # Common voice models to download from HuggingFace (official Piper voices)
52
+ # Common voice models to download
53
53
  COMMON_VOICES=(
54
54
  "en_US-lessac-medium" # Default, clear male
55
55
  "en_US-amy-medium" # Warm female
@@ -58,16 +58,6 @@ COMMON_VOICES=(
58
58
  "en_US-libritts-high" # Premium quality
59
59
  )
60
60
 
61
- # Custom high-quality voices from AgentVibes HuggingFace repository
62
- # Original voices by Bryce Beattie (https://brycebeattie.com/files/tts/)
63
- # Repository: https://huggingface.co/agentvibes/piper-custom-voices
64
- # Licensed: Public Domain (Kristin, 16Speakers) / CC BY attribution (Jenny)
65
- CUSTOM_VOICES=(
66
- "kristin:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/kristin.onnx:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/kristin.onnx.json" # US English female (Public Domain)
67
- "jenny:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/jenny.onnx:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/jenny.onnx.json" # UK English female, Irish (CC BY attribution required)
68
- "16Speakers:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/16Speakers.onnx:https://huggingface.co/agentvibes/piper-custom-voices/resolve/main/16Speakers.onnx.json" # Multi-speaker: 16 voices (Public Domain)
69
- )
70
-
71
61
  echo "🎙️ Piper Voice Model Downloader"
72
62
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
73
63
  echo ""
@@ -160,96 +150,16 @@ done
160
150
 
161
151
  echo ""
162
152
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
163
- echo "📊 Download Summary (Standard Voices):"
153
+ echo "📊 Download Summary:"
164
154
  echo " ✅ Successfully downloaded: $DOWNLOADED"
165
155
  echo " ❌ Failed: $FAILED"
166
156
  echo " 📦 Total voices available: $((ALREADY_DOWNLOADED + DOWNLOADED))"
167
157
  echo ""
168
158
 
169
- # Now offer to download custom high-quality voices from Bryce Beattie
170
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
171
- echo "🎨 Custom High-Quality Voices Available"
172
- echo ""
173
- echo "Additional premium voices from AgentVibes:"
174
- echo " • Kristin - US English female (Public Domain)"
175
- echo " • Jenny - UK English female, Irish accent (CC BY)"
176
- echo " • 16Speakers - Multi-speaker: 16 different voices (Public Domain)"
177
- echo ""
178
- echo "Repository: https://huggingface.co/agentvibes/piper-custom-voices"
179
- echo "Original voices by: Bryce Beattie (https://brycebeattie.com/files/tts/)"
180
- echo ""
181
-
182
- if [[ "$AUTO_YES" == "false" ]]; then
183
- read -p "Download custom voices (Kristin + Jenny + 16Speakers)? [Y/n]: " -n 1 -r
184
- echo
185
-
186
- if [[ $REPLY =~ ^[Yy]$ ]] || [[ -z $REPLY ]]; then
187
- DOWNLOAD_CUSTOM=true
188
- else
189
- DOWNLOAD_CUSTOM=false
190
- fi
191
- else
192
- DOWNLOAD_CUSTOM=true
193
- fi
194
-
195
- if [[ "$DOWNLOAD_CUSTOM" == "true" ]]; then
196
- echo ""
197
- echo "📥 Downloading custom voices..."
198
-
199
- CUSTOM_DOWNLOADED=0
200
- CUSTOM_FAILED=0
201
-
202
- for voice_entry in "${CUSTOM_VOICES[@]}"; do
203
- IFS=':' read -r voice_name onnx_url json_url <<< "$voice_entry"
204
-
205
- echo ""
206
- echo "📥 Downloading: $voice_name..."
207
-
208
- # Create filename from voice name
209
- onnx_file="$VOICE_DIR/${voice_name}.onnx"
210
- json_file="$VOICE_DIR/${voice_name}.onnx.json"
211
-
212
- # Download .onnx file
213
- if curl -L "$onnx_url" -o "$onnx_file" 2>/dev/null; then
214
- # Download .json config file
215
- if curl -L "$json_url" -o "$json_file" 2>/dev/null; then
216
- ((CUSTOM_DOWNLOADED++))
217
- echo "✅ Downloaded: $voice_name"
218
- else
219
- ((CUSTOM_FAILED++))
220
- echo "❌ Failed to download config: $voice_name"
221
- rm -f "$onnx_file" # Clean up partial download
222
- fi
223
- else
224
- ((CUSTOM_FAILED++))
225
- echo "❌ Failed to download model: $voice_name"
226
- fi
227
- done
228
-
229
- echo ""
230
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
231
- echo "📊 Custom Voices Summary:"
232
- echo " ✅ Successfully downloaded: $CUSTOM_DOWNLOADED"
233
- echo " ❌ Failed: $CUSTOM_FAILED"
234
- echo ""
235
- fi
236
-
237
- TOTAL_DOWNLOADED=$((DOWNLOADED + ${CUSTOM_DOWNLOADED:-0}))
238
-
239
- if [[ $TOTAL_DOWNLOADED -gt 0 ]]; then
159
+ if [[ $DOWNLOADED -gt 0 ]]; then
240
160
  echo "✨ Ready to use Piper TTS with downloaded voices!"
241
161
  echo ""
242
162
  echo "Try it:"
243
163
  echo " /agent-vibes:provider switch piper"
244
164
  echo " /agent-vibes:preview"
245
- echo ""
246
- echo "Attribution:"
247
- echo " • Original voices by Bryce Beattie - https://brycebeattie.com/files/tts/"
248
- echo " • Hosted by AgentVibes - https://huggingface.co/agentvibes/piper-custom-voices"
249
- echo " • Jenny voice requires attribution (CC BY license)"
250
- echo ""
251
- echo "Using 16Speakers multi-voice:"
252
- echo " • Switch to specific speaker: /agent-vibes:switch 16Speakers#0"
253
- echo " • Speakers 0-15 available (Cori, Kara, Kristin, Maria, Mike, etc.)"
254
- echo " • View all speakers: /agent-vibes:list"
255
165
  fi
@@ -0,0 +1,165 @@
1
+ #!/bin/bash
2
+ #
3
+ # File: .claude/hooks/piper-multispeaker-registry.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, including but not limited to the warranties of
26
+ # merchantability, fitness for a particular purpose and noninfringement.
27
+ # In no event shall the authors or copyright holders be liable for any claim,
28
+ # damages or other liability, whether in an action of contract, tort or
29
+ # otherwise, arising from, out of or in connection with the software or the
30
+ # use or other dealings in the software.
31
+ #
32
+ # ---
33
+ #
34
+ # @fileoverview Multi-Speaker Voice Registry - Maps speaker names to ONNX models and speaker IDs
35
+ # @context Enables individual speaker selection from multi-speaker Piper models (e.g., 16Speakers)
36
+ # @architecture Static registry mapping speaker names to model files and numeric speaker IDs
37
+ # @dependencies piper-voice-manager.sh (voice storage), play-tts-piper.sh (TTS with speaker ID)
38
+ # @entrypoints Sourced by voice-manager.sh for multi-speaker voice switching
39
+ # @patterns Registry pattern, speaker ID mapping, model-to-speaker association
40
+ # @related voice-manager.sh, play-tts-piper.sh, 16Speakers.onnx.json (speaker_id_map)
41
+ #
42
+
43
+ # Registry of multi-speaker models and their speaker names
44
+ # Format: "SpeakerName:model_file:speaker_id:description"
45
+ #
46
+ # 16Speakers Model (12 US + 4 UK voices):
47
+ # Source: LibriVox Public Domain recordings
48
+ # Model: 16Speakers.onnx (77MB)
49
+ #
50
+ MULTISPEAKER_VOICES=(
51
+ # US English Speakers (0-11)
52
+ "Cori_Samuel:16Speakers:0:US English Female"
53
+ "Kara_Shallenberg:16Speakers:1:US English Female"
54
+ "Kristin_Hughes:16Speakers:2:US English Female"
55
+ "Maria_Kasper:16Speakers:3:US English Female"
56
+ "Mike_Pelton:16Speakers:4:US English Male"
57
+ "Mark_Nelson:16Speakers:5:US English Male"
58
+ "Michael_Scherer:16Speakers:6:US English Male"
59
+ "James_K_White:16Speakers:7:US English Male"
60
+ "Rose_Ibex:16Speakers:8:US English Female"
61
+ "progressingamerica:16Speakers:9:US English Male"
62
+ "Steve_C:16Speakers:10:US English Male"
63
+ "Owlivia:16Speakers:11:US English Female"
64
+
65
+ # UK English Speakers (12-15)
66
+ "Paul_Hampton:16Speakers:12:UK English Male"
67
+ "Jennifer_Dorr:16Speakers:13:UK English Female"
68
+ "Emily_Cripps:16Speakers:14:UK English Female"
69
+ "Martin_Clifton:16Speakers:15:UK English Male"
70
+ )
71
+
72
+ # @function get_multispeaker_info
73
+ # @intent Get model and speaker ID for a speaker name
74
+ # @why Enables users to select individual speakers from multi-speaker models by name
75
+ # @param $1 {string} speaker_name - Speaker name (e.g., "Cori_Samuel", "Rose_Ibex")
76
+ # @returns Echoes "model:speaker_id" (e.g., "16Speakers:0") to stdout
77
+ # @exitcode 0=speaker found, 1=speaker not found
78
+ # @sideeffects None (read-only lookup)
79
+ # @edgecases Case-insensitive matching
80
+ # @calledby voice-manager.sh switch command
81
+ # @calls None (pure bash array iteration)
82
+ get_multispeaker_info() {
83
+ local speaker_name="$1"
84
+ for entry in "${MULTISPEAKER_VOICES[@]}"; do
85
+ name="${entry%%:*}"
86
+ rest="${entry#*:}"
87
+ model="${rest%%:*}"
88
+ rest="${rest#*:}"
89
+ speaker_id="${rest%%:*}"
90
+
91
+ if [[ "${name,,}" == "${speaker_name,,}" ]]; then
92
+ echo "$model:$speaker_id"
93
+ return 0
94
+ fi
95
+ done
96
+ return 1
97
+ }
98
+
99
+ # @function list_multispeaker_voices
100
+ # @intent Display all available multi-speaker voices with descriptions
101
+ # @why Help users discover individual speakers within multi-speaker models
102
+ # @param None
103
+ # @returns None
104
+ # @exitcode Always 0
105
+ # @sideeffects Writes formatted list to stdout
106
+ # @edgecases None
107
+ # @calledby voice-manager.sh list command, /agent-vibes:list
108
+ # @calls None (pure bash array iteration)
109
+ list_multispeaker_voices() {
110
+ echo "🎭 Multi-Speaker Voices (16Speakers Model):"
111
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
112
+
113
+ local current_model=""
114
+ for entry in "${MULTISPEAKER_VOICES[@]}"; do
115
+ name="${entry%%:*}"
116
+ rest="${entry#*:}"
117
+ model="${rest%%:*}"
118
+ rest="${rest#*:}"
119
+ speaker_id="${rest%%:*}"
120
+ description="${rest#*:}"
121
+
122
+ # Print section header when model changes
123
+ if [[ "$model" != "$current_model" ]]; then
124
+ if [[ -n "$current_model" ]]; then
125
+ echo ""
126
+ fi
127
+ echo " Model: $model.onnx"
128
+ current_model="$model"
129
+ fi
130
+
131
+ echo " • $name (ID: $speaker_id) - $description"
132
+ done
133
+
134
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
135
+ echo ""
136
+ echo "Usage: /agent-vibes:switch Cori_Samuel"
137
+ echo " /agent-vibes:switch Rose_Ibex"
138
+ }
139
+
140
+ # @function get_multispeaker_description
141
+ # @intent Get description for a speaker name
142
+ # @why Provide user-friendly info about speaker characteristics
143
+ # @param $1 {string} speaker_name - Speaker name
144
+ # @returns Echoes description (e.g., "US English Female") to stdout
145
+ # @exitcode 0=speaker found, 1=speaker not found
146
+ # @sideeffects None (read-only lookup)
147
+ # @edgecases Case-insensitive matching
148
+ # @calledby voice-manager.sh switch command (for confirmation message)
149
+ # @calls None (pure bash array iteration)
150
+ get_multispeaker_description() {
151
+ local speaker_name="$1"
152
+ for entry in "${MULTISPEAKER_VOICES[@]}"; do
153
+ name="${entry%%:*}"
154
+ rest="${entry#*:}"
155
+ rest="${rest#*:}"
156
+ rest="${rest#*:}"
157
+ description="${rest}"
158
+
159
+ if [[ "${name,,}" == "${speaker_name,,}" ]]; then
160
+ echo "$description"
161
+ return 0
162
+ fi
163
+ done
164
+ return 1
165
+ }
@@ -384,9 +384,11 @@ if [ -f "${TEMP_FILE}" ]; then
384
384
  fi
385
385
  fi
386
386
 
387
- # Play audio (WSL/Linux) in background to avoid blocking, fully detached
388
- (paplay "${TEMP_FILE}" || aplay "${TEMP_FILE}" || mpg123 "${TEMP_FILE}") >/dev/null 2>&1 &
389
- PLAYER_PID=$!
387
+ # Play audio (WSL/Linux) in background to avoid blocking, fully detached (skip if in test mode)
388
+ if [[ "${AGENTVIBES_TEST_MODE:-false}" != "true" ]]; then
389
+ (paplay "${TEMP_FILE}" || aplay "${TEMP_FILE}" || mpg123 "${TEMP_FILE}") >/dev/null 2>&1 &
390
+ PLAYER_PID=$!
391
+ fi
390
392
 
391
393
  # Wait for audio to finish, then release lock
392
394
  (sleep $DURATION; rm -f "$LOCK_FILE") &