agentvibes 4.2.0 → 4.4.0

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 (219) hide show
  1. package/.agentvibes/bmad/bmad-voices.md +69 -69
  2. package/.agentvibes/config.json +12 -0
  3. package/.claude/activation-instructions +54 -54
  4. package/.claude/audio/tracks/README.md +52 -52
  5. package/.claude/commands/agent-vibes/add.md +21 -21
  6. package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
  7. package/.claude/commands/agent-vibes/agent.md +79 -79
  8. package/.claude/commands/agent-vibes/background-music.md +111 -111
  9. package/.claude/commands/agent-vibes/bmad.md +198 -198
  10. package/.claude/commands/agent-vibes/clean.md +18 -18
  11. package/.claude/commands/agent-vibes/cleanup.md +18 -18
  12. package/.claude/commands/agent-vibes/commands.json +145 -145
  13. package/.claude/commands/agent-vibes/effects.md +97 -97
  14. package/.claude/commands/agent-vibes/get.md +9 -9
  15. package/.claude/commands/agent-vibes/hide.md +91 -91
  16. package/.claude/commands/agent-vibes/language.md +23 -23
  17. package/.claude/commands/agent-vibes/learn.md +67 -67
  18. package/.claude/commands/agent-vibes/list.md +13 -13
  19. package/.claude/commands/agent-vibes/mute.md +37 -37
  20. package/.claude/commands/agent-vibes/preview.md +17 -17
  21. package/.claude/commands/agent-vibes/provider.md +68 -68
  22. package/.claude/commands/agent-vibes/replay-target.md +14 -14
  23. package/.claude/commands/agent-vibes/sample.md +12 -12
  24. package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
  25. package/.claude/commands/agent-vibes/set-pretext.md +65 -65
  26. package/.claude/commands/agent-vibes/set-speed.md +41 -41
  27. package/.claude/commands/agent-vibes/show.md +84 -84
  28. package/.claude/commands/agent-vibes/switch.md +87 -87
  29. package/.claude/commands/agent-vibes/target-voice.md +26 -26
  30. package/.claude/commands/agent-vibes/target.md +30 -30
  31. package/.claude/commands/agent-vibes/translate.md +68 -68
  32. package/.claude/commands/agent-vibes/unmute.md +45 -45
  33. package/.claude/commands/agent-vibes/verbosity.md +89 -89
  34. package/.claude/commands/agent-vibes/whoami.md +7 -7
  35. package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
  36. package/.claude/commands/agent-vibes-rdp.md +24 -24
  37. package/.claude/config/agentvibes.json +1 -0
  38. package/.claude/config/audio-effects.cfg +2 -2
  39. package/.claude/config/audio-effects.cfg.sample +52 -52
  40. package/.claude/config/background-music-volume.txt +1 -0
  41. package/.claude/config/intro-text.txt +1 -0
  42. package/.claude/config/piper-speech-rate.txt +4 -0
  43. package/.claude/config/piper-target-speech-rate.txt +1 -0
  44. package/.claude/config/reverb-level.txt +1 -0
  45. package/.claude/config/tts-speech-rate.txt +4 -0
  46. package/.claude/config/tts-target-speech-rate.txt +1 -0
  47. package/.claude/docs/TERMUX_SETUP.md +408 -408
  48. package/.claude/github-star-reminder.txt +1 -1
  49. package/.claude/hooks/README-TTS-QUEUE.md +135 -135
  50. package/.claude/hooks/audio-cache-utils.sh +246 -246
  51. package/.claude/hooks/audio-processor.sh +433 -433
  52. package/.claude/hooks/background-music-manager.sh +404 -404
  53. package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
  54. package/.claude/hooks/bmad-speak.sh +269 -269
  55. package/.claude/hooks/bmad-tts-injector.sh +568 -568
  56. package/.claude/hooks/bmad-voice-manager.sh +928 -928
  57. package/.claude/hooks/clawdbot-receiver-SECURE.sh +129 -129
  58. package/.claude/hooks/clawdbot-receiver.sh +107 -107
  59. package/.claude/hooks/clean-audio-cache.sh +22 -22
  60. package/.claude/hooks/cleanup-cache.sh +106 -106
  61. package/.claude/hooks/configure-rdp-mode.sh +137 -137
  62. package/.claude/hooks/download-extra-voices.sh +244 -244
  63. package/.claude/hooks/effects-manager.sh +268 -268
  64. package/.claude/hooks/github-star-reminder.sh +154 -154
  65. package/.claude/hooks/language-manager.sh +362 -362
  66. package/.claude/hooks/learn-manager.sh +492 -492
  67. package/.claude/hooks/macos-voice-manager.sh +205 -205
  68. package/.claude/hooks/migrate-background-music.sh +125 -125
  69. package/.claude/hooks/migrate-to-agentvibes.sh +161 -161
  70. package/.claude/hooks/optimize-background-music.sh +87 -87
  71. package/.claude/hooks/path-resolver.sh +60 -60
  72. package/.claude/hooks/personality-manager.sh +448 -448
  73. package/.claude/hooks/piper-download-voices.sh +225 -225
  74. package/.claude/hooks/piper-installer.sh +292 -292
  75. package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
  76. package/.claude/hooks/piper-voice-manager.sh +24 -3
  77. package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +90 -90
  78. package/.claude/hooks/play-tts-enhanced.sh +105 -105
  79. package/.claude/hooks/play-tts-macos.sh +368 -368
  80. package/.claude/hooks/play-tts-piper.sh +679 -679
  81. package/.claude/hooks/play-tts-soprano.sh +356 -356
  82. package/.claude/hooks/play-tts-ssh-remote.sh +167 -167
  83. package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
  84. package/.claude/hooks/play-tts.sh +301 -301
  85. package/.claude/hooks/prepare-release.sh +54 -54
  86. package/.claude/hooks/provider-commands.sh +617 -617
  87. package/.claude/hooks/provider-manager.sh +399 -399
  88. package/.claude/hooks/replay-target-audio.sh +95 -95
  89. package/.claude/hooks/requirements.txt +6 -6
  90. package/.claude/hooks/sentiment-manager.sh +201 -201
  91. package/.claude/hooks/session-start-tts.sh +81 -81
  92. package/.claude/hooks/soprano-gradio-synth.py +139 -139
  93. package/.claude/hooks/speed-manager.sh +291 -291
  94. package/.claude/hooks/stop-tts.sh +84 -84
  95. package/.claude/hooks/termux-installer.sh +261 -261
  96. package/.claude/hooks/translate-manager.sh +341 -341
  97. package/.claude/hooks/translator.py +237 -237
  98. package/.claude/hooks/tts-queue-worker.sh +145 -145
  99. package/.claude/hooks/tts-queue.sh +165 -165
  100. package/.claude/hooks/verbosity-manager.sh +178 -178
  101. package/.claude/hooks/voice-manager.sh +548 -548
  102. package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
  103. package/.claude/hooks-windows/background-music-manager.ps1 +348 -0
  104. package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -0
  105. package/.claude/hooks-windows/download-extra-voices.ps1 +185 -0
  106. package/.claude/hooks-windows/effects-manager.ps1 +294 -0
  107. package/.claude/hooks-windows/language-manager.ps1 +193 -0
  108. package/.claude/hooks-windows/learn-manager.ps1 +241 -0
  109. package/.claude/hooks-windows/personality-manager.ps1 +266 -0
  110. package/.claude/hooks-windows/play-tts-piper.ps1 +209 -0
  111. package/.claude/hooks-windows/play-tts-sapi.ps1 +108 -0
  112. package/.claude/hooks-windows/play-tts-soprano.ps1 +159 -158
  113. package/.claude/hooks-windows/play-tts-windows-piper.ps1 +50 -5
  114. package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
  115. package/.claude/hooks-windows/play-tts.ps1 +344 -266
  116. package/.claude/hooks-windows/provider-manager.ps1 +29 -10
  117. package/.claude/hooks-windows/session-start-tts.ps1 +124 -124
  118. package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
  119. package/.claude/hooks-windows/speed-manager.ps1 +166 -0
  120. package/.claude/hooks-windows/verbosity-manager.ps1 +119 -0
  121. package/.claude/hooks-windows/voice-manager-windows.ps1 +92 -8
  122. package/.claude/output-styles/agent-vibes.md +202 -202
  123. package/.claude/personalities/angry.md +14 -14
  124. package/.claude/personalities/annoying.md +14 -14
  125. package/.claude/personalities/crass.md +14 -14
  126. package/.claude/personalities/dramatic.md +14 -14
  127. package/.claude/personalities/dry-humor.md +50 -50
  128. package/.claude/personalities/flirty.md +20 -20
  129. package/.claude/personalities/funny.md +14 -14
  130. package/.claude/personalities/grandpa.md +32 -32
  131. package/.claude/personalities/millennial.md +14 -14
  132. package/.claude/personalities/moody.md +14 -14
  133. package/.claude/personalities/normal.md +16 -16
  134. package/.claude/personalities/pirate.md +14 -14
  135. package/.claude/personalities/poetic.md +14 -14
  136. package/.claude/personalities/professional.md +14 -14
  137. package/.claude/personalities/rapper.md +55 -55
  138. package/.claude/personalities/robot.md +14 -14
  139. package/.claude/personalities/sarcastic.md +38 -38
  140. package/.claude/personalities/sassy.md +14 -14
  141. package/.claude/personalities/surfer-dude.md +14 -14
  142. package/.claude/personalities/zen.md +14 -14
  143. package/.claude/settings.json +15 -15
  144. package/.claude/verbosity.txt +1 -1
  145. package/.clawdbot/README.md +105 -105
  146. package/.clawdbot/skill/SKILL.md +241 -241
  147. package/.mcp.json +12 -0
  148. package/CLAUDE.md +170 -170
  149. package/README.md +2029 -2007
  150. package/RELEASE_NOTES.md +1310 -1203
  151. package/WINDOWS-SETUP.md +208 -208
  152. package/bin/agent-vibes +39 -39
  153. package/bin/agentvibes-voice-browser.js +1840 -1840
  154. package/bin/agentvibes.js +48 -2
  155. package/bin/mcp-server.js +121 -121
  156. package/bin/mcp-server.sh +206 -206
  157. package/bin/test-bmad-pr +78 -78
  158. package/mcp-server/QUICK_START.md +203 -203
  159. package/mcp-server/README.md +345 -345
  160. package/mcp-server/WINDOWS_SETUP.md +260 -260
  161. package/mcp-server/docs/troubleshooting-audio.md +313 -313
  162. package/mcp-server/examples/claude_desktop_config.json +11 -11
  163. package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
  164. package/mcp-server/examples/custom_instructions.md +169 -169
  165. package/mcp-server/install-deps.js +130 -130
  166. package/mcp-server/pyproject.toml +52 -52
  167. package/mcp-server/requirements.txt +2 -2
  168. package/mcp-server/server.py +1465 -1453
  169. package/mcp-server/test_server.py +395 -395
  170. package/mcp-server/test_windows_script_parity.py +336 -0
  171. package/package.json +110 -110
  172. package/setup-windows.ps1 +815 -815
  173. package/src/bmad-detector.js +71 -71
  174. package/src/cli/list-personalities.js +110 -110
  175. package/src/cli/list-voices.js +114 -114
  176. package/src/commands/bmad-voices.js +394 -394
  177. package/src/commands/install-mcp.js +476 -476
  178. package/src/console/app.js +824 -824
  179. package/src/console/audio-env.js +20 -1
  180. package/src/console/brand-colors.js +13 -13
  181. package/src/console/constants/personalities.js +44 -44
  182. package/src/console/footer-config.js +50 -50
  183. package/src/console/modals/modal-overlay.js +247 -247
  184. package/src/console/navigation.js +62 -62
  185. package/src/console/tabs/agents-tab.js +1684 -1516
  186. package/src/console/tabs/help-tab.js +261 -261
  187. package/src/console/tabs/install-tab.js +1007 -991
  188. package/src/console/tabs/music-tab.js +22 -8
  189. package/src/console/tabs/placeholder-tab.js +53 -53
  190. package/src/console/tabs/readme-tab.js +267 -267
  191. package/src/console/tabs/receiver-tab.js +1472 -1212
  192. package/src/console/tabs/settings-tab.js +152 -79
  193. package/src/console/tabs/voices-tab.js +100 -21
  194. package/src/console/widgets/destroy-list.js +25 -25
  195. package/src/console/widgets/format-utils.js +89 -89
  196. package/src/console/widgets/notice.js +55 -55
  197. package/src/console/widgets/personality-picker.js +185 -185
  198. package/src/console/widgets/reverb-picker.js +94 -94
  199. package/src/console/widgets/track-picker.js +285 -285
  200. package/src/installer/music-file-input.js +304 -304
  201. package/src/installer.js +5882 -5829
  202. package/src/services/agent-voice-store.js +423 -423
  203. package/src/services/config-service.js +264 -264
  204. package/src/services/navigation-service.js +123 -123
  205. package/src/services/provider-service.js +132 -132
  206. package/src/services/verbosity-service.js +157 -157
  207. package/src/utils/audio-duration-validator.js +298 -298
  208. package/src/utils/audio-format-validator.js +277 -277
  209. package/src/utils/dependency-checker.js +469 -466
  210. package/src/utils/file-ownership-verifier.js +358 -358
  211. package/src/utils/list-formatter.js +194 -194
  212. package/src/utils/music-file-validator.js +285 -285
  213. package/src/utils/preview-list-prompt.js +136 -136
  214. package/src/utils/provider-validator.js +96 -12
  215. package/src/utils/secure-music-storage.js +412 -412
  216. package/templates/agentvibes-receiver.sh +482 -482
  217. package/templates/audio/welcome-music.mp3 +0 -0
  218. package/voice-assignments.json +8244 -8244
  219. package/.claude/config/background-music-position.txt +0 -1
@@ -0,0 +1,185 @@
1
+ #
2
+ # File: .claude/hooks-windows/download-extra-voices.ps1
3
+ #
4
+ # AgentVibes - Download Extra Piper Voice Models (Windows)
5
+ # Downloads custom high-quality voices from HuggingFace
6
+ #
7
+
8
+ param(
9
+ [switch]$yes
10
+ )
11
+
12
+ $AUTO_YES = $yes -or ($args -contains "--yes") -or ($args -contains "-y")
13
+
14
+ # Configuration
15
+ $VoiceDir = "$env:USERPROFILE\.claude\piper-voices"
16
+ $PiperExe = "$env:LOCALAPPDATA\Programs\Piper\piper.exe"
17
+
18
+ # HuggingFace repository for custom voices
19
+ $HuggingFaceRepo = "agentvibes/piper-custom-voices"
20
+ $HuggingFaceBaseUrl = "https://huggingface.co/$HuggingFaceRepo/resolve/main"
21
+
22
+ # Extra custom voices to download
23
+ $ExtraVoices = @(
24
+ @{
25
+ name = "kristin"
26
+ description = "Kristin (US English female, Public Domain, 64MB)"
27
+ sizeMB = 64
28
+ },
29
+ @{
30
+ name = "jenny"
31
+ description = "Jenny (UK English female with Irish accent, CC BY, 64MB)"
32
+ sizeMB = 64
33
+ },
34
+ @{
35
+ name = "16Speakers"
36
+ description = "Tracy/16Speakers (Multi-speaker: 12 US + 4 UK voices, Public Domain, 77MB)"
37
+ sizeMB = 77
38
+ }
39
+ )
40
+
41
+ Write-Host ""
42
+ Write-Host "AgentVibes Extra Voice Downloader" -ForegroundColor Cyan
43
+ Write-Host ("=" * 40) -ForegroundColor Cyan
44
+ Write-Host ""
45
+ Write-Host "This will download high-quality custom Piper voices from HuggingFace."
46
+ Write-Host ""
47
+
48
+ # Check if Piper is installed
49
+ if (-not (Test-Path $PiperExe)) {
50
+ Write-Host "[ERROR] Piper not found at: $PiperExe" -ForegroundColor Red
51
+ Write-Host "Run: .\setup-windows.ps1 to install Piper" -ForegroundColor Yellow
52
+ exit 1
53
+ }
54
+
55
+ # Create voice directory
56
+ if (-not (Test-Path $VoiceDir)) {
57
+ New-Item -ItemType Directory -Path $VoiceDir -Force | Out-Null
58
+ }
59
+
60
+ Write-Host "Voice directory: $VoiceDir" -ForegroundColor Gray
61
+ Write-Host ""
62
+
63
+ # Check status of each voice
64
+ $alreadyDownloaded = @()
65
+ $needDownload = @()
66
+
67
+ foreach ($voice in $ExtraVoices) {
68
+ $modelFile = "$VoiceDir\$($voice.name).onnx"
69
+ $configFile = "$VoiceDir\$($voice.name).onnx.json"
70
+
71
+ if ((Test-Path $modelFile) -and (Test-Path $configFile)) {
72
+ $alreadyDownloaded += $voice
73
+ } else {
74
+ $needDownload += $voice
75
+ }
76
+ }
77
+
78
+ Write-Host "Status:" -ForegroundColor Cyan
79
+ Write-Host " Already downloaded: $($alreadyDownloaded.Count) voice(s)"
80
+ Write-Host " Need to download: $($needDownload.Count) voice(s)"
81
+ Write-Host ""
82
+
83
+ if ($alreadyDownloaded.Count -gt 0) {
84
+ Write-Host "Already downloaded (skipped):" -ForegroundColor Green
85
+ foreach ($voice in $alreadyDownloaded) {
86
+ Write-Host " [OK] $($voice.description)" -ForegroundColor Green
87
+ }
88
+ Write-Host ""
89
+ }
90
+
91
+ if ($needDownload.Count -eq 0) {
92
+ Write-Host "All extra voices already downloaded!" -ForegroundColor Green
93
+ exit 0
94
+ }
95
+
96
+ # Calculate total size
97
+ $totalSizeMB = ($needDownload | Measure-Object -Property sizeMB -Sum).Sum
98
+
99
+ Write-Host "Voices to download:" -ForegroundColor Yellow
100
+ foreach ($voice in $needDownload) {
101
+ Write-Host " - $($voice.description)"
102
+ }
103
+ Write-Host ""
104
+ Write-Host "Total download size: ~${totalSizeMB}MB" -ForegroundColor Yellow
105
+ Write-Host ""
106
+
107
+ # Confirm download
108
+ if (-not $AUTO_YES) {
109
+ $reply = Read-Host "Download $($needDownload.Count) extra voice(s)? [Y/n]"
110
+ if ($reply -and $reply -notmatch '^[Yy]') {
111
+ Write-Host "Download cancelled" -ForegroundColor Red
112
+ exit 0
113
+ }
114
+ } else {
115
+ Write-Host "Auto-downloading $($needDownload.Count) extra voice(s)..." -ForegroundColor Cyan
116
+ Write-Host ""
117
+ }
118
+
119
+ # Download each voice
120
+ $downloaded = 0
121
+ $failed = 0
122
+
123
+ foreach ($voice in $needDownload) {
124
+ $voiceName = $voice.name
125
+ Write-Host ""
126
+ Write-Host "Downloading: $($voice.description)..." -ForegroundColor Cyan
127
+
128
+ $modelUrl = "$HuggingFaceBaseUrl/$voiceName.onnx"
129
+ $jsonUrl = "$HuggingFaceBaseUrl/$voiceName.onnx.json"
130
+ $modelFile = "$VoiceDir\$voiceName.onnx"
131
+ $jsonFile = "$VoiceDir\$voiceName.onnx.json"
132
+
133
+ $success = $true
134
+
135
+ try {
136
+ Write-Host " Downloading model file..." -ForegroundColor Yellow
137
+ Invoke-WebRequest -Uri $modelUrl -OutFile $modelFile -ErrorAction Stop
138
+
139
+ Write-Host " Downloading config file..." -ForegroundColor Yellow
140
+ Invoke-WebRequest -Uri $jsonUrl -OutFile $jsonFile -ErrorAction Stop
141
+
142
+ $modelSize = [math]::Round((Get-Item $modelFile).Length / 1MB, 2)
143
+ Write-Host " [OK] Downloaded ($modelSize MB)" -ForegroundColor Green
144
+ }
145
+ catch {
146
+ Write-Host " [ERROR] Failed to download: $_" -ForegroundColor Red
147
+ $success = $false
148
+ # Clean up partial downloads
149
+ Remove-Item -Path $modelFile -ErrorAction SilentlyContinue
150
+ Remove-Item -Path $jsonFile -ErrorAction SilentlyContinue
151
+ }
152
+
153
+ if ($success) {
154
+ $downloaded++
155
+ Write-Host " Successfully downloaded: $voiceName" -ForegroundColor Green
156
+ } else {
157
+ $failed++
158
+ }
159
+ }
160
+
161
+ Write-Host ""
162
+ Write-Host ("=" * 40) -ForegroundColor Cyan
163
+ Write-Host "Download Summary:" -ForegroundColor Cyan
164
+ Write-Host " Successfully downloaded: $downloaded" -ForegroundColor Green
165
+ if ($failed -gt 0) {
166
+ Write-Host " Failed: $failed" -ForegroundColor Red
167
+ }
168
+ Write-Host " Total extra voices available: $($alreadyDownloaded.Count + $downloaded)"
169
+ Write-Host ""
170
+
171
+ if ($downloaded -gt 0) {
172
+ Write-Host "Extra voices ready to use!" -ForegroundColor Green
173
+ Write-Host ""
174
+ Write-Host "Try them:"
175
+ Write-Host " /agent-vibes:provider switch piper"
176
+ Write-Host " /agent-vibes:switch kristin"
177
+ Write-Host " /agent-vibes:switch jenny"
178
+ Write-Host " /agent-vibes:switch 16Speakers"
179
+ }
180
+
181
+ if ($downloaded -gt 0 -or $alreadyDownloaded.Count -gt 0) {
182
+ exit 0
183
+ } else {
184
+ exit 1
185
+ }
@@ -0,0 +1,294 @@
1
+ #
2
+ # File: .claude/hooks-windows/effects-manager.ps1
3
+ #
4
+ # AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
5
+ # Website: https://agentvibes.org
6
+ # Repository: https://github.com/paulpreibisch/AgentVibes
7
+ #
8
+ # Co-created by Paul Preibisch with Claude AI
9
+ # Copyright (c) 2025 Paul Preibisch
10
+ #
11
+ # Licensed under the Apache License, Version 2.0
12
+
13
+ param(
14
+ [Parameter(Position=0)]
15
+ [string]$Command = "help",
16
+ [Parameter(Position=1)]
17
+ [string]$Arg1 = "",
18
+ [Parameter(Position=2)]
19
+ [string]$Arg2 = "default",
20
+ [Parameter(Position=3)]
21
+ [string]$Arg3 = ""
22
+ )
23
+
24
+ $ErrorActionPreference = "Continue"
25
+
26
+ # Get script directory and config file path
27
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
28
+ $ConfigDir = Join-Path (Split-Path -Parent $ScriptDir) "config"
29
+ $ConfigFile = Join-Path $ConfigDir "audio-effects.cfg"
30
+ $ReverbLevelFile = Join-Path $ConfigDir "reverb-level.txt"
31
+
32
+ # Reverb level mappings (sox format: reverberance HF-damping room-scale)
33
+ $ReverbLevels = @{
34
+ "off" = ""
35
+ "light" = "reverb 20 50 50"
36
+ "medium" = "reverb 40 50 70"
37
+ "heavy" = "reverb 70 50 100"
38
+ "cathedral" = "reverb 90 30 100"
39
+ }
40
+
41
+ function Get-AgentEffects {
42
+ param([string]$AgentName)
43
+
44
+ if (-not (Test-Path $ConfigFile)) {
45
+ Write-Output ""
46
+ return
47
+ }
48
+
49
+ $lines = Get-Content $ConfigFile
50
+ $configLine = $null
51
+
52
+ foreach ($line in $lines) {
53
+ if ($line -match "^$([regex]::Escape($AgentName))\|") {
54
+ $configLine = $line
55
+ break
56
+ }
57
+ }
58
+
59
+ if (-not $configLine) {
60
+ foreach ($line in $lines) {
61
+ if ($line -match "^default\|") {
62
+ $configLine = $line
63
+ break
64
+ }
65
+ }
66
+ }
67
+
68
+ if ($configLine) {
69
+ $parts = $configLine -split '\|'
70
+ if ($parts.Count -ge 2) {
71
+ Write-Output $parts[1]
72
+ } else {
73
+ Write-Output ""
74
+ }
75
+ } else {
76
+ Write-Output ""
77
+ }
78
+ }
79
+
80
+ function Set-Reverb {
81
+ param(
82
+ [string]$Level,
83
+ [string]$AgentName = "default",
84
+ [string]$ApplyAll = ""
85
+ )
86
+
87
+ if (-not $ReverbLevels.ContainsKey($Level)) {
88
+ Write-Output "Invalid reverb level: $Level"
89
+ Write-Output "Valid levels: off, light, medium, heavy, cathedral"
90
+ exit 1
91
+ }
92
+
93
+ $reverbEffect = $ReverbLevels[$Level]
94
+
95
+ # Always update reverb-level.txt for play-tts.ps1 compatibility
96
+ if ($ApplyAll -eq "--all" -or $AgentName -eq "default") {
97
+ Set-Content -Path $ReverbLevelFile -Value $Level -NoNewline
98
+ }
99
+
100
+ if (-not (Test-Path $ConfigFile)) {
101
+ Write-Output "Config file not found: $ConfigFile"
102
+ exit 1
103
+ }
104
+
105
+ $lines = Get-Content $ConfigFile
106
+ $newLines = @()
107
+
108
+ if ($ApplyAll -eq "--all") {
109
+ Write-Host "Setting reverb to '$Level' for all agents..."
110
+
111
+ foreach ($line in $lines) {
112
+ if ($line -match "^#" -or $line.Trim() -eq "" -or $line -match "^\|") {
113
+ $newLines += $line
114
+ continue
115
+ }
116
+
117
+ $parts = $line -split '\|', 4
118
+ if ($parts.Count -ge 4) {
119
+ $agent = $parts[0]
120
+ $soxEffects = $parts[1]
121
+ $bgFile = $parts[2]
122
+ $bgVol = $parts[3]
123
+
124
+ # Remove existing reverb from sox effects
125
+ $newEffects = $soxEffects -replace 'reverb\s+\d+\s+\d+\s+\d+', ''
126
+ $newEffects = ($newEffects -replace '\s+', ' ').Trim()
127
+
128
+ # Add new reverb if not off
129
+ if ($reverbEffect) {
130
+ if ($newEffects) {
131
+ $newEffects = "$reverbEffect $newEffects"
132
+ } else {
133
+ $newEffects = $reverbEffect
134
+ }
135
+ }
136
+
137
+ $newLines += "$agent|$newEffects|$bgFile|$bgVol"
138
+ } else {
139
+ $newLines += $line
140
+ }
141
+ }
142
+
143
+ Set-Content -Path $ConfigFile -Value ($newLines -join "`n") -NoNewline
144
+ Write-Output "Reverb set to '$Level' for all agents"
145
+ } else {
146
+ Write-Host "Setting reverb to '$Level' for '$AgentName'..."
147
+
148
+ # Check if agent exists in config
149
+ $agentExists = $false
150
+ foreach ($line in $lines) {
151
+ if ($line -match "^$([regex]::Escape($AgentName))\|") {
152
+ $agentExists = $true
153
+ break
154
+ }
155
+ }
156
+
157
+ if (-not $agentExists) {
158
+ Add-Content -Path $ConfigFile -Value "${AgentName}|${reverbEffect}|agentvibes_soft_flamenco_loop.mp3|0.30"
159
+ Write-Output "Created new config for '$AgentName' with reverb '$Level'"
160
+ return
161
+ }
162
+
163
+ foreach ($line in $lines) {
164
+ if ($line -match "^#" -or $line.Trim() -eq "" -or $line -match "^\|") {
165
+ $newLines += $line
166
+ continue
167
+ }
168
+
169
+ $parts = $line -split '\|', 4
170
+ if ($parts.Count -ge 4 -and $parts[0] -eq $AgentName) {
171
+ $soxEffects = $parts[1]
172
+ $bgFile = $parts[2]
173
+ $bgVol = $parts[3]
174
+
175
+ # Remove existing reverb
176
+ $newEffects = $soxEffects -replace 'reverb\s+\d+\s+\d+\s+\d+', ''
177
+ $newEffects = ($newEffects -replace '\s+', ' ').Trim()
178
+
179
+ if ($reverbEffect) {
180
+ if ($newEffects) {
181
+ $newEffects = "$reverbEffect $newEffects"
182
+ } else {
183
+ $newEffects = $reverbEffect
184
+ }
185
+ }
186
+
187
+ $newLines += "$($parts[0])|$newEffects|$bgFile|$bgVol"
188
+ } else {
189
+ $newLines += $line
190
+ }
191
+ }
192
+
193
+ Set-Content -Path $ConfigFile -Value ($newLines -join "`n") -NoNewline
194
+ Write-Output "Reverb set to '$Level' for '$AgentName'"
195
+ }
196
+ }
197
+
198
+ function Get-ReverbLevel {
199
+ param([string]$AgentName = "default")
200
+
201
+ $effects = Get-AgentEffects -AgentName $AgentName
202
+
203
+ if (-not $effects -or $effects -notmatch 'reverb') {
204
+ Write-Output "off"
205
+ return
206
+ }
207
+
208
+ if ($effects -match 'reverb\s+(\d+)\s+(\d+)\s+(\d+)') {
209
+ $reverbVal = [int]$Matches[1]
210
+ if ($reverbVal -le 20) {
211
+ Write-Output "light"
212
+ } elseif ($reverbVal -le 40) {
213
+ Write-Output "medium"
214
+ } elseif ($reverbVal -le 70) {
215
+ Write-Output "heavy"
216
+ } else {
217
+ Write-Output "cathedral"
218
+ }
219
+ } else {
220
+ Write-Output "off"
221
+ }
222
+ }
223
+
224
+ function Show-Effects {
225
+ if (-not (Test-Path $ConfigFile)) {
226
+ Write-Output "Config file not found: $ConfigFile"
227
+ exit 1
228
+ }
229
+
230
+ Write-Output "Current Audio Effects Configuration:"
231
+ Write-Output ""
232
+
233
+ $lines = Get-Content $ConfigFile
234
+ foreach ($line in $lines) {
235
+ if ($line -match "^#" -or $line.Trim() -eq "" -or $line -match "^\|") {
236
+ continue
237
+ }
238
+
239
+ $parts = $line -split '\|', 4
240
+ if ($parts.Count -ge 2) {
241
+ $agent = $parts[0]
242
+ $soxEffects = $parts[1]
243
+
244
+ $reverbLevel = "off"
245
+ if ($soxEffects -match 'reverb\s+(\d+)\s+(\d+)\s+(\d+)') {
246
+ $reverbVal = [int]$Matches[1]
247
+ if ($reverbVal -le 20) { $reverbLevel = "light" }
248
+ elseif ($reverbVal -le 40) { $reverbLevel = "medium" }
249
+ elseif ($reverbVal -le 70) { $reverbLevel = "heavy" }
250
+ else { $reverbLevel = "cathedral" }
251
+ }
252
+
253
+ Write-Output " ${agent}: reverb=$reverbLevel"
254
+ if ($soxEffects) {
255
+ Write-Output " Effects: $soxEffects"
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ # Main command dispatcher
262
+ switch ($Command) {
263
+ "set-reverb" {
264
+ if (-not $Arg1) {
265
+ Write-Output "Usage: effects-manager.ps1 set-reverb <level> [agent-name] [--all]"
266
+ Write-Output "Levels: off, light, medium, heavy, cathedral"
267
+ exit 1
268
+ }
269
+ Set-Reverb -Level $Arg1 -AgentName $Arg2 -ApplyAll $Arg3
270
+ }
271
+ "get-reverb" {
272
+ $agent = if ($Arg1) { $Arg1 } else { "default" }
273
+ Get-ReverbLevel -AgentName $agent
274
+ }
275
+ "get-effects" {
276
+ $agent = if ($Arg1) { $Arg1 } else { "default" }
277
+ Get-AgentEffects -AgentName $agent
278
+ }
279
+ "list" {
280
+ Show-Effects
281
+ }
282
+ default {
283
+ Write-Output "Usage: effects-manager.ps1 {set-reverb|get-reverb|get-effects|list}"
284
+ Write-Output ""
285
+ Write-Output "Commands:"
286
+ Write-Output " set-reverb <level> [agent] [--all] Set reverb level"
287
+ Write-Output " get-reverb [agent] Get current reverb level"
288
+ Write-Output " get-effects [agent] Get all effects for agent"
289
+ Write-Output " list List all agent effects"
290
+ Write-Output ""
291
+ Write-Output "Reverb Levels: off, light, medium, heavy, cathedral"
292
+ exit 1
293
+ }
294
+ }
@@ -0,0 +1,193 @@
1
+ #
2
+ # File: .claude/hooks-windows/language-manager.ps1
3
+ #
4
+ # AgentVibes - Finally, your AI Agents can Talk Back!
5
+ # Website: https://agentvibes.org
6
+ # Copyright (c) 2025 Paul Preibisch
7
+ # Licensed under the Apache License, Version 2.0
8
+
9
+ param(
10
+ [Parameter(Position=0)]
11
+ [string]$Command = "help",
12
+ [Parameter(Position=1)]
13
+ [string]$Arg1 = "",
14
+ [Parameter(Position=2)]
15
+ [string]$Arg2 = ""
16
+ )
17
+
18
+ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
19
+ $ClaudeDir = Split-Path -Parent $ScriptDir
20
+
21
+ # Determine config directory
22
+ if ($env:CLAUDE_PROJECT_DIR -and (Test-Path "$env:CLAUDE_PROJECT_DIR\.claude")) {
23
+ $ConfigClaudeDir = Join-Path $env:CLAUDE_PROJECT_DIR ".claude"
24
+ } else {
25
+ $ConfigClaudeDir = $ClaudeDir
26
+ }
27
+
28
+ $LanguageFile = Join-Path $ConfigClaudeDir "tts-language.txt"
29
+ if (-not (Test-Path $ConfigClaudeDir)) { New-Item -ItemType Directory -Path $ConfigClaudeDir -Force | Out-Null }
30
+
31
+ # Language to Piper voice mapping
32
+ $PiperVoices = @{
33
+ "spanish" = "es_ES-davefx-medium"
34
+ "french" = "fr_FR-siwis-medium"
35
+ "german" = "de_DE-thorsten-medium"
36
+ "italian" = "it_IT-riccardo-x_low"
37
+ "portuguese" = "pt_BR-faber-medium"
38
+ "chinese" = "zh_CN-huayan-medium"
39
+ "japanese" = "ja_JP-hikari-medium"
40
+ "korean" = "ko_KR-eunyoung-medium"
41
+ "russian" = "ru_RU-dmitri-medium"
42
+ "polish" = "pl_PL-darkman-medium"
43
+ "dutch" = "nl_NL-rdh-medium"
44
+ "turkish" = "tr_TR-dfki-medium"
45
+ "arabic" = "ar_JO-kareem-medium"
46
+ "hindi" = "hi_IN-amitabh-medium"
47
+ "swedish" = "sv_SE-nst-medium"
48
+ "danish" = "da_DK-talesyntese-medium"
49
+ "norwegian" = "no_NO-talesyntese-medium"
50
+ "finnish" = "fi_FI-harri-medium"
51
+ "czech" = "cs_CZ-jirka-medium"
52
+ "romanian" = "ro_RO-mihai-medium"
53
+ "ukrainian" = "uk_UA-lada-x_low"
54
+ "greek" = "el_GR-rapunzelina-low"
55
+ "bulgarian" = "bg_BG-valentin-medium"
56
+ "croatian" = "hr_HR-gorana-medium"
57
+ "slovak" = "sk_SK-lili-medium"
58
+ }
59
+
60
+ $SupportedLanguages = ($PiperVoices.Keys | Sort-Object) -join ", "
61
+
62
+ function Get-PiperVoiceForLanguage {
63
+ param([string]$Lang)
64
+ $lang = $Lang.ToLower()
65
+ if ($PiperVoices.ContainsKey($lang)) { return $PiperVoices[$lang] }
66
+ return ""
67
+ }
68
+
69
+ function Get-ActiveProvider {
70
+ $provFile = Join-Path $ConfigClaudeDir "tts-provider.txt"
71
+ if (-not (Test-Path $provFile)) {
72
+ $provFile = Join-Path $env:USERPROFILE ".claude\tts-provider.txt"
73
+ }
74
+ if (Test-Path $provFile) { return (Get-Content $provFile -Raw).Trim() }
75
+ return "piper"
76
+ }
77
+
78
+ switch ($Command) {
79
+ "set" {
80
+ if (-not $Arg1) {
81
+ Write-Output "Usage: language-manager.ps1 set <language>"
82
+ exit 1
83
+ }
84
+
85
+ $lang = $Arg1.ToLower()
86
+
87
+ # Handle reset/english
88
+ if ($lang -in @("reset", "english", "en")) {
89
+ if (Test-Path $LanguageFile) {
90
+ Remove-Item $LanguageFile -Force
91
+ Write-Output "Language reset to English (default)"
92
+ } else {
93
+ Write-Output "Already using English (default)"
94
+ }
95
+ exit 0
96
+ }
97
+
98
+ # Validate language
99
+ if (-not $PiperVoices.ContainsKey($lang)) {
100
+ Write-Output "Language '$lang' not supported"
101
+ Write-Output ""
102
+ Write-Output "Supported languages:"
103
+ Write-Output $SupportedLanguages
104
+ exit 1
105
+ }
106
+
107
+ # Save language
108
+ Set-Content -Path $LanguageFile -Value $lang -NoNewline
109
+
110
+ $provider = Get-ActiveProvider
111
+ $recommendedVoice = Get-PiperVoiceForLanguage $lang
112
+
113
+ Write-Output "Language set to: $lang"
114
+ Write-Output "Recommended voice for $provider TTS: $recommendedVoice"
115
+ Write-Output ""
116
+ Write-Output "TTS will now speak in $lang."
117
+ Write-Output "Switch voice with: /agent-vibes:switch `"$recommendedVoice`""
118
+ }
119
+
120
+ "get" {
121
+ if (Test-Path $LanguageFile) {
122
+ $lang = (Get-Content $LanguageFile -Raw).Trim()
123
+ $provider = Get-ActiveProvider
124
+ $recommendedVoice = Get-PiperVoiceForLanguage $lang
125
+
126
+ Write-Output "Current language: $lang"
127
+ if ($recommendedVoice) {
128
+ Write-Output "Recommended voice ($provider): $recommendedVoice"
129
+ }
130
+ } else {
131
+ Write-Output "Current language: english (default)"
132
+ Write-Output "No multilingual voice required"
133
+ }
134
+ }
135
+
136
+ "code" {
137
+ if (Test-Path $LanguageFile) {
138
+ Write-Output (Get-Content $LanguageFile -Raw).Trim()
139
+ } else {
140
+ Write-Output "english"
141
+ }
142
+ }
143
+
144
+ "check-voice" {
145
+ if (-not $Arg1) {
146
+ Write-Output "Usage: language-manager.ps1 check-voice <voice-name>"
147
+ exit 1
148
+ }
149
+ $multilingual = @("Antoni", "Rachel", "Domi", "Bella", "Charlotte", "Matilda")
150
+ if ($Arg1 -in $multilingual) { Write-Output "yes" } else { Write-Output "no" }
151
+ }
152
+
153
+ "best-voice" {
154
+ $lang = "english"
155
+ if (Test-Path $LanguageFile) { $lang = (Get-Content $LanguageFile -Raw).Trim() }
156
+ if ($lang -eq "english") {
157
+ Write-Output ""
158
+ } else {
159
+ Write-Output (Get-PiperVoiceForLanguage $lang)
160
+ }
161
+ }
162
+
163
+ "voice-for-language" {
164
+ if (-not $Arg1) {
165
+ Write-Output "Usage: language-manager.ps1 voice-for-language <language> [provider]"
166
+ exit 1
167
+ }
168
+ Write-Output (Get-PiperVoiceForLanguage $Arg1.ToLower())
169
+ }
170
+
171
+ "list" {
172
+ Write-Output "Supported languages and recommended voices:"
173
+ Write-Output ""
174
+ foreach ($lang in ($PiperVoices.Keys | Sort-Object)) {
175
+ $voice = $PiperVoices[$lang]
176
+ Write-Output ("{0,-15} -> {1}" -f $lang, $voice)
177
+ }
178
+ }
179
+
180
+ default {
181
+ Write-Output "AgentVibes Language Manager"
182
+ Write-Output ""
183
+ Write-Output "Usage:"
184
+ Write-Output " language-manager.ps1 set <language> Set language"
185
+ Write-Output " language-manager.ps1 get Get current language"
186
+ Write-Output " language-manager.ps1 code Get language code only"
187
+ Write-Output " language-manager.ps1 check-voice <name> Check if voice is multilingual"
188
+ Write-Output " language-manager.ps1 best-voice Get best voice for current language"
189
+ Write-Output " language-manager.ps1 voice-for-language <lang> Get voice for language"
190
+ Write-Output " language-manager.ps1 list List all supported languages"
191
+ exit 1
192
+ }
193
+ }