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
@@ -1,281 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # @fileoverview Piper TTS Provider Implementation
4
- # @context Free, offline neural TTS for WSL/Linux
5
- # @architecture Implements provider contract for Piper binary
6
- # @dependencies piper (pipx), piper-voice-manager.sh, mpv/aplay
7
- # @entrypoints Called by play-tts.sh router
8
- # @patterns Provider contract: text/voice → audio file path
9
- # @related play-tts.sh, piper-voice-manager.sh, GitHub Issue #25
10
- #
11
-
12
- # Fix locale warnings
13
- export LC_ALL=C
14
-
15
- TEXT="$1"
16
- VOICE_OVERRIDE="$2" # Optional: voice model name
17
-
18
- # Source voice manager and language manager
19
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
- source "$SCRIPT_DIR/piper-voice-manager.sh"
21
- source "$SCRIPT_DIR/language-manager.sh"
22
-
23
- # Default voice for Piper
24
- DEFAULT_VOICE="en_US-lessac-medium"
25
-
26
- # @function determine_voice_model
27
- # @intent Resolve voice name to Piper model name with language support
28
- # @why Support voice override, language-specific voices, and default fallback
29
- # @param Uses global: $VOICE_OVERRIDE
30
- # @returns Sets $VOICE_MODEL global variable
31
- # @sideeffects None
32
- VOICE_MODEL=""
33
-
34
- # Get current language setting
35
- CURRENT_LANGUAGE=$(get_language_code)
36
-
37
- if [[ -n "$VOICE_OVERRIDE" ]]; then
38
- # Use override if provided
39
- VOICE_MODEL="$VOICE_OVERRIDE"
40
- echo "🎤 Using voice: $VOICE_OVERRIDE (session-specific)"
41
- else
42
- # Try to get voice from voice file (project-local first, then global)
43
- VOICE_FILE=""
44
- if [[ -f "$SCRIPT_DIR/../tts-voice.txt" ]]; then
45
- VOICE_FILE="$SCRIPT_DIR/../tts-voice.txt"
46
- elif [[ -f "$HOME/.claude/tts-voice.txt" ]]; then
47
- VOICE_FILE="$HOME/.claude/tts-voice.txt"
48
- fi
49
-
50
- if [[ -n "$VOICE_FILE" ]]; then
51
- FILE_VOICE=$(cat "$VOICE_FILE" 2>/dev/null)
52
- # Check if it's a Piper model name (contains underscore and dash)
53
- if [[ "$FILE_VOICE" == *"_"*"-"* ]]; then
54
- VOICE_MODEL="$FILE_VOICE"
55
- fi
56
- fi
57
-
58
- # If no Piper voice from file, try language-specific voice
59
- if [[ -z "$VOICE_MODEL" ]]; then
60
- LANG_VOICE=$(get_voice_for_language "$CURRENT_LANGUAGE" "piper" 2>/dev/null)
61
-
62
- if [[ -n "$LANG_VOICE" ]]; then
63
- VOICE_MODEL="$LANG_VOICE"
64
- echo "🌍 Using $CURRENT_LANGUAGE voice: $LANG_VOICE (Piper)"
65
- else
66
- # Use default voice
67
- VOICE_MODEL="$DEFAULT_VOICE"
68
- fi
69
- fi
70
- fi
71
-
72
- # @function validate_inputs
73
- # @intent Check required parameters
74
- # @why Fail fast with clear errors if inputs missing
75
- # @exitcode 1=missing text, 2=missing piper binary
76
- if [[ -z "$TEXT" ]]; then
77
- echo "Usage: $0 \"text to speak\" [voice_model_name]"
78
- exit 1
79
- fi
80
-
81
- # Check if Piper is installed
82
- if ! command -v piper &> /dev/null; then
83
- echo "❌ Error: Piper TTS not installed"
84
- echo "Install with: pipx install piper-tts"
85
- echo "Or run: .claude/hooks/piper-installer.sh"
86
- exit 2
87
- fi
88
-
89
- # @function ensure_voice_downloaded
90
- # @intent Download voice model if not cached
91
- # @why Provide seamless experience with automatic downloads
92
- # @param Uses global: $VOICE_MODEL
93
- # @sideeffects Downloads voice model files
94
- # @edgecases Prompts user for consent before downloading
95
- if ! verify_voice "$VOICE_MODEL"; then
96
- echo "📥 Voice model not found: $VOICE_MODEL"
97
- echo " File size: ~25MB"
98
- echo " Preview: https://huggingface.co/rhasspy/piper-voices"
99
- echo ""
100
- read -p " Download this voice model? [y/N]: " -n 1 -r
101
- echo
102
-
103
- if [[ $REPLY =~ ^[Yy]$ ]]; then
104
- if ! download_voice "$VOICE_MODEL"; then
105
- echo "❌ Failed to download voice model"
106
- echo "Fix: Download manually or choose different voice"
107
- exit 3
108
- fi
109
- else
110
- echo "❌ Voice download cancelled"
111
- exit 3
112
- fi
113
- fi
114
-
115
- # Get voice model path
116
- VOICE_PATH=$(get_voice_path "$VOICE_MODEL")
117
- if [[ $? -ne 0 ]]; then
118
- echo "❌ Voice model path not found: $VOICE_MODEL"
119
- exit 3
120
- fi
121
-
122
- # @function determine_audio_directory
123
- # @intent Find appropriate directory for audio file storage
124
- # @why Supports project-local and global storage
125
- # @returns Sets $AUDIO_DIR global variable
126
- if [[ -n "$CLAUDE_PROJECT_DIR" ]]; then
127
- AUDIO_DIR="$CLAUDE_PROJECT_DIR/.claude/audio"
128
- else
129
- # Fallback: try to find .claude directory in current path
130
- CURRENT_DIR="$PWD"
131
- while [[ "$CURRENT_DIR" != "/" ]]; do
132
- if [[ -d "$CURRENT_DIR/.claude" ]]; then
133
- AUDIO_DIR="$CURRENT_DIR/.claude/audio"
134
- break
135
- fi
136
- CURRENT_DIR=$(dirname "$CURRENT_DIR")
137
- done
138
- # Final fallback to global if no project .claude found
139
- if [[ -z "$AUDIO_DIR" ]]; then
140
- AUDIO_DIR="$HOME/.claude/audio"
141
- fi
142
- fi
143
-
144
- mkdir -p "$AUDIO_DIR"
145
- TEMP_FILE="$AUDIO_DIR/tts-$(date +%s).wav"
146
-
147
- # @function get_speech_rate
148
- # @intent Determine speech rate for Piper synthesis
149
- # @why Convert user-facing speed (0.5=slower, 2.0=faster) to Piper length-scale (inverted)
150
- # @returns Piper length-scale value (inverted from user scale)
151
- # @note Piper uses length-scale where higher=slower, opposite of user expectation
152
- get_speech_rate() {
153
- local target_config=""
154
- local main_config=""
155
-
156
- # Check for target-specific config first (new and legacy paths)
157
- if [[ -f "$SCRIPT_DIR/../config/tts-target-speech-rate.txt" ]]; then
158
- target_config="$SCRIPT_DIR/../config/tts-target-speech-rate.txt"
159
- elif [[ -f "$HOME/.claude/config/tts-target-speech-rate.txt" ]]; then
160
- target_config="$HOME/.claude/config/tts-target-speech-rate.txt"
161
- elif [[ -f "$SCRIPT_DIR/../config/piper-target-speech-rate.txt" ]]; then
162
- target_config="$SCRIPT_DIR/../config/piper-target-speech-rate.txt"
163
- elif [[ -f "$HOME/.claude/config/piper-target-speech-rate.txt" ]]; then
164
- target_config="$HOME/.claude/config/piper-target-speech-rate.txt"
165
- fi
166
-
167
- # Check for main config (new and legacy paths)
168
- if [[ -f "$SCRIPT_DIR/../config/tts-speech-rate.txt" ]]; then
169
- main_config="$SCRIPT_DIR/../config/tts-speech-rate.txt"
170
- elif [[ -f "$HOME/.claude/config/tts-speech-rate.txt" ]]; then
171
- main_config="$HOME/.claude/config/tts-speech-rate.txt"
172
- elif [[ -f "$SCRIPT_DIR/../config/piper-speech-rate.txt" ]]; then
173
- main_config="$SCRIPT_DIR/../config/piper-speech-rate.txt"
174
- elif [[ -f "$HOME/.claude/config/piper-speech-rate.txt" ]]; then
175
- main_config="$HOME/.claude/config/piper-speech-rate.txt"
176
- fi
177
-
178
- # If this is a non-English voice and target config exists, use it
179
- if [[ "$CURRENT_LANGUAGE" != "english" ]] && [[ -n "$target_config" ]]; then
180
- local user_speed=$(cat "$target_config" 2>/dev/null)
181
- # Convert user speed to Piper length-scale (invert)
182
- # User: 0.5=slower, 1.0=normal, 2.0=faster
183
- # Piper: 2.0=slower, 1.0=normal, 0.5=faster
184
- # Formula: piper_length_scale = 1.0 / user_speed
185
- echo "scale=2; 1.0 / $user_speed" | bc -l 2>/dev/null || echo "1.0"
186
- return
187
- fi
188
-
189
- # Otherwise use main config if available
190
- if [[ -n "$main_config" ]]; then
191
- local user_speed=$(grep -v '^#' "$main_config" 2>/dev/null | grep -v '^$' | tail -1)
192
- echo "scale=2; 1.0 / $user_speed" | bc -l 2>/dev/null || echo "1.0"
193
- return
194
- fi
195
-
196
- # Default: 1.0 (normal) for English, 2.0 (slower) for learning
197
- if [[ "$CURRENT_LANGUAGE" != "english" ]]; then
198
- echo "2.0"
199
- else
200
- echo "1.0"
201
- fi
202
- }
203
-
204
- SPEECH_RATE=$(get_speech_rate)
205
-
206
- # @function synthesize_with_piper
207
- # @intent Generate speech using Piper TTS
208
- # @why Provides free, offline TTS alternative
209
- # @param Uses globals: $TEXT, $VOICE_PATH, $SPEECH_RATE
210
- # @returns Creates WAV file at $TEMP_FILE
211
- # @exitcode 0=success, 4=synthesis error
212
- # @sideeffects Creates audio file
213
- # @edgecases Handles piper errors, invalid models
214
- echo "$TEXT" | piper --model "$VOICE_PATH" --length-scale "$SPEECH_RATE" --output_file "$TEMP_FILE" 2>/dev/null
215
-
216
- if [[ ! -f "$TEMP_FILE" ]] || [[ ! -s "$TEMP_FILE" ]]; then
217
- echo "❌ Failed to synthesize speech with Piper"
218
- echo "Voice model: $VOICE_MODEL"
219
- echo "Check that voice model is valid"
220
- exit 4
221
- fi
222
-
223
- # @function add_silence_padding
224
- # @intent Add silence to prevent WSL audio static
225
- # @why WSL audio subsystem cuts off first ~200ms
226
- # @param Uses global: $TEMP_FILE
227
- # @returns Updates $TEMP_FILE to padded version
228
- # @sideeffects Modifies audio file
229
- # AI NOTE: Use ffmpeg if available, otherwise skip padding (degraded experience)
230
- if command -v ffmpeg &> /dev/null; then
231
- PADDED_FILE="$AUDIO_DIR/tts-padded-$(date +%s).wav"
232
- # Add 200ms of silence at the beginning
233
- ffmpeg -f lavfi -i anullsrc=r=44100:cl=stereo:d=0.2 -i "$TEMP_FILE" \
234
- -filter_complex "[0:a][1:a]concat=n=2:v=0:a=1[out]" \
235
- -map "[out]" -y "$PADDED_FILE" 2>/dev/null
236
-
237
- if [[ -f "$PADDED_FILE" ]]; then
238
- rm -f "$TEMP_FILE"
239
- TEMP_FILE="$PADDED_FILE"
240
- fi
241
- fi
242
-
243
- # @function play_audio
244
- # @intent Play generated audio using available player with sequential playback
245
- # @why Support multiple audio players and prevent overlapping audio in learning mode
246
- # @param Uses global: $TEMP_FILE, $CURRENT_LANGUAGE
247
- # @sideeffects Plays audio with lock mechanism for sequential playback
248
- LOCK_FILE="/tmp/agentvibes-audio.lock"
249
-
250
- # Wait for previous audio to finish (max 30 seconds)
251
- for i in {1..60}; do
252
- if [ ! -f "$LOCK_FILE" ]; then
253
- break
254
- fi
255
- sleep 0.5
256
- done
257
-
258
- # Track last target language audio for replay command
259
- if [[ "$CURRENT_LANGUAGE" != "english" ]]; then
260
- TARGET_AUDIO_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/last-target-audio.txt"
261
- echo "$TEMP_FILE" > "$TARGET_AUDIO_FILE"
262
- fi
263
-
264
- # Create lock and play audio
265
- touch "$LOCK_FILE"
266
-
267
- # Get audio duration for proper lock timing
268
- DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$TEMP_FILE" 2>/dev/null)
269
- DURATION=${DURATION%.*} # Round to integer
270
- DURATION=${DURATION:-1} # Default to 1 second if detection fails
271
-
272
- # Play audio in background
273
- (mpv "$TEMP_FILE" || aplay "$TEMP_FILE" || paplay "$TEMP_FILE") >/dev/null 2>&1 &
274
- PLAYER_PID=$!
275
-
276
- # Wait for audio to finish, then release lock
277
- (sleep $DURATION; rm -f "$LOCK_FILE") &
278
- disown
279
-
280
- echo "🎵 Saved to: $TEMP_FILE"
281
- echo "🎤 Voice used: $VOICE_MODEL (Piper TTS)"
@@ -1,69 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # @fileoverview TTS Provider Router with Language Learning Support
4
- # @context Routes TTS requests to active provider (ElevenLabs or Piper)
5
- # @architecture Provider abstraction layer - single entry point for all TTS
6
- # @dependencies provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh
7
- # @entrypoints Called by hooks, slash commands, and personality-manager.sh
8
- # @patterns Provider pattern - delegates to provider-specific implementations
9
- # @related provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh
10
- #
11
-
12
- # Fix locale warnings
13
- export LC_ALL=C
14
-
15
- TEXT="$1"
16
- VOICE_OVERRIDE="$2" # Optional: voice name or ID
17
-
18
- # Get script directory
19
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
-
21
- # Source provider manager to get active provider
22
- source "$SCRIPT_DIR/provider-manager.sh"
23
-
24
- # Get active provider
25
- ACTIVE_PROVIDER=$(get_active_provider)
26
-
27
- # Show GitHub star reminder (once per day)
28
- "$SCRIPT_DIR/github-star-reminder.sh" 2>/dev/null || true
29
-
30
- # @function detect_voice_provider
31
- # @intent Auto-detect provider from voice name (for mixed-provider support)
32
- # @why Allow ElevenLabs for main language + Piper for target language
33
- # @param $1 voice name/ID
34
- # @returns Provider name (elevenlabs or piper)
35
- detect_voice_provider() {
36
- local voice="$1"
37
- # Piper voice names contain underscore and dash (e.g., es_ES-davefx-medium)
38
- if [[ "$voice" == *"_"*"-"* ]]; then
39
- echo "piper"
40
- else
41
- echo "$ACTIVE_PROVIDER"
42
- fi
43
- }
44
-
45
- # Override provider if voice indicates different provider (mixed-provider mode)
46
- if [[ -n "$VOICE_OVERRIDE" ]]; then
47
- DETECTED_PROVIDER=$(detect_voice_provider "$VOICE_OVERRIDE")
48
- if [[ "$DETECTED_PROVIDER" != "$ACTIVE_PROVIDER" ]]; then
49
- ACTIVE_PROVIDER="$DETECTED_PROVIDER"
50
- fi
51
- fi
52
-
53
- # Normal single-language mode - route to appropriate provider implementation
54
- # Note: For learning mode, the output style will call this script TWICE:
55
- # 1. First call with main language text and current voice
56
- # 2. Second call with translated text and target voice
57
- case "$ACTIVE_PROVIDER" in
58
- elevenlabs)
59
- exec "$SCRIPT_DIR/play-tts-elevenlabs.sh" "$TEXT" "$VOICE_OVERRIDE"
60
- ;;
61
- piper)
62
- exec "$SCRIPT_DIR/play-tts-piper.sh" "$TEXT" "$VOICE_OVERRIDE"
63
- ;;
64
- *)
65
- echo "❌ Unknown provider: $ACTIVE_PROVIDER"
66
- echo " Run: /agent-vibes:provider list"
67
- exit 1
68
- ;;
69
- esac