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
@@ -1,404 +1,404 @@
1
- #!/usr/bin/env bash
2
- #
3
- # File: .claude/hooks/background-music-manager.sh
4
- #
5
- # AgentVibes - Background Music Manager
6
- # Manages background music settings for TTS
7
- #
8
- # Usage:
9
- # background-music-manager.sh status - Show current status
10
- # background-music-manager.sh on - Enable background music
11
- # background-music-manager.sh off - Disable background music
12
- # background-music-manager.sh volume X - Set volume (0.0-1.0)
13
- # background-music-manager.sh list - List all pre-packaged background music
14
- # background-music-manager.sh set-default TRACK - Set default background music
15
- # background-music-manager.sh get-enabled - Returns "true" or "false"
16
- # background-music-manager.sh get-volume - Returns current volume
17
- #
18
-
19
- set -euo pipefail
20
- export LC_ALL=C
21
-
22
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
24
-
25
- # Config file location
26
- CONFIG_DIR="$SCRIPT_DIR/../config"
27
- ENABLED_FILE="$CONFIG_DIR/background-music-enabled.txt"
28
- VOLUME_FILE="$CONFIG_DIR/background-music-volume.txt"
29
-
30
- # Defaults
31
- DEFAULT_VOLUME="0.34"
32
-
33
- # Ensure config directory exists
34
- mkdir -p "$CONFIG_DIR"
35
-
36
- # @function is_enabled
37
- # @intent Check if background music is enabled
38
- # @returns 0 if enabled, 1 if disabled
39
- is_enabled() {
40
- if [[ -f "$ENABLED_FILE" ]]; then
41
- local status
42
- status=$(cat "$ENABLED_FILE" 2>/dev/null | tr -d '[:space:]')
43
- [[ "$status" == "true" || "$status" == "on" || "$status" == "1" ]]
44
- else
45
- # Default: disabled
46
- return 1
47
- fi
48
- }
49
-
50
- # @function get_volume
51
- # @intent Get current volume setting
52
- # @returns Volume value (0.0-1.0)
53
- get_volume() {
54
- if [[ -f "$VOLUME_FILE" ]]; then
55
- cat "$VOLUME_FILE" 2>/dev/null | tr -d '[:space:]'
56
- else
57
- echo "$DEFAULT_VOLUME"
58
- fi
59
- }
60
-
61
- # @function set_enabled
62
- # @intent Enable or disable background music
63
- # @param $1 "true" or "false"
64
- set_enabled() {
65
- local value="$1"
66
- echo "$value" > "$ENABLED_FILE"
67
- }
68
-
69
- # @function set_volume
70
- # @intent Set background music volume
71
- # @param $1 Volume value (0.0-1.0)
72
- set_volume() {
73
- local value="$1"
74
-
75
- # Validate it's a number between 0 and 1
76
- if ! [[ "$value" =~ ^[0-9]*\.?[0-9]+$ ]]; then
77
- echo "Error: Volume must be a number between 0.0 and 1.0" >&2
78
- return 1
79
- fi
80
-
81
- # Check range using bc
82
- if command -v bc &> /dev/null; then
83
- if (( $(echo "$value < 0" | bc -l) )) || (( $(echo "$value > 1" | bc -l) )); then
84
- echo "Error: Volume must be between 0.0 and 1.0" >&2
85
- return 1
86
- fi
87
- fi
88
-
89
- echo "$value" > "$VOLUME_FILE"
90
- }
91
-
92
- # @function list_tracks
93
- # @intent List all pre-packaged background music files
94
- list_tracks() {
95
- local bg_dir="$SCRIPT_DIR/../audio/tracks"
96
-
97
- if [[ ! -d "$bg_dir" ]]; then
98
- echo "❌ No tracks folder found at $bg_dir"
99
- return 1
100
- fi
101
-
102
- echo "🎵 Available Background Music Tracks"
103
- echo "===================================="
104
- echo ""
105
-
106
- local count=0
107
- while IFS= read -r -d '' file; do
108
- local basename
109
- basename=$(basename "$file")
110
- count=$((count + 1))
111
- printf "%2d. %s\n" "$count" "$basename"
112
- done < <(find "$bg_dir" -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.ogg" \) -print0 2>/dev/null | sort -z)
113
-
114
- if [[ $count -eq 0 ]]; then
115
- echo "No audio files found in tracks folder"
116
- else
117
- echo ""
118
- echo "Total: $count track(s)"
119
- fi
120
- }
121
-
122
- # @function get_default_track
123
- # @intent Get the current default background music track
124
- get_default_track() {
125
- local audio_effects_cfg="$SCRIPT_DIR/../config/audio-effects.cfg"
126
-
127
- if [[ ! -f "$audio_effects_cfg" ]]; then
128
- echo ""
129
- return
130
- fi
131
-
132
- # Extract the background file from the default entry
133
- grep "^default|" "$audio_effects_cfg" 2>/dev/null | cut -d'|' -f3 || echo ""
134
- }
135
-
136
- # @function set_default_track
137
- # @intent Set the default background music track
138
- # @param $1 Track filename
139
- set_default_track() {
140
- local track="$1"
141
- local audio_effects_cfg="$SCRIPT_DIR/../config/audio-effects.cfg"
142
- local bg_dir="$SCRIPT_DIR/../audio/tracks"
143
-
144
- if [[ -z "$track" ]]; then
145
- echo "❌ Error: No track name provided"
146
- echo "Usage: $0 set-default TRACK_NAME"
147
- return 1
148
- fi
149
-
150
- # Check if track exists
151
- if [[ ! -f "$bg_dir/$track" ]]; then
152
- echo "❌ Error: Track '$track' not found in tracks folder"
153
- echo "Run '$0 list' to see available tracks"
154
- return 1
155
- fi
156
-
157
- # Check if audio-effects.cfg exists
158
- if [[ ! -f "$audio_effects_cfg" ]]; then
159
- echo "❌ Error: audio-effects.cfg not found at $audio_effects_cfg"
160
- return 1
161
- fi
162
-
163
- # Update the default entry in audio-effects.cfg
164
- # Preserve the sox effects and volume, just update the background file
165
- local temp_file
166
- temp_file=$(mktemp)
167
-
168
- if grep -q "^default|" "$audio_effects_cfg"; then
169
- # Replace existing default entry - preserve effects and volume
170
- awk -F'|' -v track="$track" '
171
- /^default\|/ {
172
- print $1 "|" $2 "|" track "|" $4
173
- next
174
- }
175
- { print }
176
- ' "$audio_effects_cfg" > "$temp_file"
177
-
178
- mv "$temp_file" "$audio_effects_cfg"
179
-
180
- # Auto-enable background music if it was disabled
181
- if ! is_enabled; then
182
- set_enabled "true"
183
- echo "✅ Default background music set to: $track"
184
- echo "🎵 Background music enabled automatically"
185
- else
186
- echo "✅ Default background music set to: $track"
187
- fi
188
- else
189
- echo "❌ Error: No default entry found in audio-effects.cfg"
190
- return 1
191
- fi
192
- }
193
-
194
- # @function show_status
195
- # @intent Display current background music status
196
- show_status() {
197
- echo "🎵 Background Music Status"
198
- echo "=========================="
199
-
200
- if is_enabled; then
201
- echo "Status: ✅ ENABLED"
202
- else
203
- echo "Status: 🔇 DISABLED"
204
- fi
205
-
206
- echo "Volume: $(get_volume) ($(echo "scale=0; $(get_volume) * 100 / 1" | bc -l 2>/dev/null || echo "?")%)"
207
-
208
- # Show default track
209
- local default_track
210
- default_track=$(get_default_track)
211
- if [[ -n "$default_track" ]]; then
212
- echo "Default Track: $default_track"
213
- else
214
- echo "Default Track: (none)"
215
- fi
216
-
217
- # Check for background files
218
- local bg_dir="$SCRIPT_DIR/../audio/tracks"
219
- if [[ -d "$bg_dir" ]]; then
220
- local count
221
- count=$(find "$bg_dir" -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.ogg" \) 2>/dev/null | wc -l)
222
- echo "Tracks: $count audio file(s) in tracks folder"
223
- else
224
- echo "Tracks: No tracks folder found"
225
- fi
226
-
227
- # Check dependencies
228
- echo ""
229
- echo "Dependencies:"
230
- if command -v sox &> /dev/null; then
231
- echo " sox: ✅ installed"
232
- else
233
- echo " sox: ❌ not installed (needed for effects)"
234
- fi
235
- if command -v ffmpeg &> /dev/null; then
236
- echo " ffmpeg: ✅ installed"
237
- else
238
- echo " ffmpeg: ❌ not installed (needed for mixing)"
239
- fi
240
- }
241
-
242
- # Set background music for a specific agent
243
- set_agent_track() {
244
- local agent="$1"
245
- local track="$2"
246
- local config_file="$SCRIPT_DIR/../config/audio-effects.cfg"
247
-
248
- if [[ -z "$agent" ]] || [[ -z "$track" ]]; then
249
- echo "❌ Error: Agent name and track required"
250
- echo "Usage: $0 set-agent AGENT_NAME TRACK_NAME"
251
- exit 1
252
- fi
253
-
254
- # Verify track exists
255
- local bg_dir="$SCRIPT_DIR/../audio/tracks"
256
- if [[ ! -f "$bg_dir/$track" ]]; then
257
- echo "❌ Error: Track not found: $track"
258
- echo "Run '$0 list' to see available tracks"
259
- exit 1
260
- fi
261
-
262
- # Update or add agent config line
263
- if grep -q "^${agent}|" "$config_file" 2>/dev/null; then
264
- # Agent exists - update track (preserve effects and volume)
265
- local temp_file
266
- temp_file=$(mktemp)
267
- awk -F'|' -v agent="$agent" -v track="$track" '
268
- $1 == agent {
269
- print $1 "|" $2 "|" track "|" $4
270
- next
271
- }
272
- { print }
273
- ' "$config_file" > "$temp_file"
274
- mv "$temp_file" "$config_file"
275
- echo "✅ Updated background music for $agent: $track"
276
- else
277
- # Agent doesn't exist - add new line with track
278
- echo "${agent}||${track}|0.30" >> "$config_file"
279
- echo "✅ Added background music for $agent: $track"
280
- fi
281
-
282
- # Auto-enable background music if it was disabled
283
- if ! is_enabled; then
284
- set_enabled "true"
285
- echo "🎵 Background music enabled automatically"
286
- fi
287
- }
288
-
289
- # Set background music for all agents
290
- set_all_agents_track() {
291
- local track="$1"
292
- local config_file="$SCRIPT_DIR/../config/audio-effects.cfg"
293
-
294
- if [[ -z "$track" ]]; then
295
- echo "❌ Error: Track name required"
296
- echo "Usage: $0 set-all TRACK_NAME"
297
- exit 1
298
- fi
299
-
300
- # Verify track exists
301
- local bg_dir="$SCRIPT_DIR/../audio/tracks"
302
- if [[ ! -f "$bg_dir/$track" ]]; then
303
- echo "❌ Error: Track not found: $track"
304
- echo "Run '$0 list' to see available tracks"
305
- exit 1
306
- fi
307
-
308
- # Update all non-comment, non-empty, non-default lines
309
- local temp_file
310
- temp_file=$(mktemp)
311
- local count=0
312
-
313
- awk -F'|' -v track="$track" '
314
- # Skip comments and empty lines
315
- /^#/ || /^[[:space:]]*$/ { print; next }
316
-
317
- # Skip only _party_mode (but UPDATE default!)
318
- $1 == "_party_mode" { print; next }
319
-
320
- # Update all agent lines including default
321
- {
322
- print $1 "|" $2 "|" track "|" $4
323
- }
324
- ' "$config_file" > "$temp_file"
325
-
326
- # Count updated agents (including default)
327
- count=$(grep -v '^#' "$config_file" | grep -v '^[[:space:]]*$' | grep -v '^_party_mode|' | wc -l)
328
-
329
- mv "$temp_file" "$config_file"
330
- echo "✅ Updated background music for $count agents: $track"
331
-
332
- # Auto-enable background music if it was disabled
333
- if ! is_enabled; then
334
- set_enabled "true"
335
- echo "🎵 Background music enabled automatically"
336
- fi
337
- }
338
-
339
- # Main command handler
340
- case "${1:-status}" in
341
- status|"")
342
- show_status
343
- ;;
344
- on|enable|true)
345
- set_enabled "true"
346
- echo "🎵 Background music ENABLED at $(get_volume) volume"
347
- ;;
348
- off|disable|false)
349
- set_enabled "false"
350
- echo "🔇 Background music DISABLED"
351
- ;;
352
- volume)
353
- if [[ -z "${2:-}" ]]; then
354
- echo "Current volume: $(get_volume)"
355
- else
356
- set_volume "$2"
357
- echo "🎵 Background music volume set to $2"
358
- fi
359
- ;;
360
- list)
361
- list_tracks
362
- ;;
363
- set-default)
364
- if [[ -z "${2:-}" ]]; then
365
- echo "❌ Error: No track name provided"
366
- echo "Usage: $0 set-default TRACK_NAME"
367
- echo "Run '$0 list' to see available tracks"
368
- exit 1
369
- fi
370
- set_default_track "$2"
371
- ;;
372
- set-agent)
373
- if [[ -z "${2:-}" ]] || [[ -z "${3:-}" ]]; then
374
- echo "❌ Error: Agent name and track required"
375
- echo "Usage: $0 set-agent AGENT_NAME TRACK_NAME"
376
- echo "Run '$0 list' to see available tracks"
377
- exit 1
378
- fi
379
- set_agent_track "$2" "$3"
380
- ;;
381
- set-all)
382
- if [[ -z "${2:-}" ]]; then
383
- echo "❌ Error: Track name required"
384
- echo "Usage: $0 set-all TRACK_NAME"
385
- echo "Run '$0 list' to see available tracks"
386
- exit 1
387
- fi
388
- set_all_agents_track "$2"
389
- ;;
390
- get-enabled)
391
- if is_enabled; then
392
- echo "true"
393
- else
394
- echo "false"
395
- fi
396
- ;;
397
- get-volume)
398
- get_volume
399
- ;;
400
- *)
401
- echo "Usage: $0 {status|on|off|volume [X]|list|set-default TRACK|set-agent AGENT TRACK|set-all TRACK|get-enabled|get-volume}"
402
- exit 1
403
- ;;
404
- esac
1
+ #!/usr/bin/env bash
2
+ #
3
+ # File: .claude/hooks/background-music-manager.sh
4
+ #
5
+ # AgentVibes - Background Music Manager
6
+ # Manages background music settings for TTS
7
+ #
8
+ # Usage:
9
+ # background-music-manager.sh status - Show current status
10
+ # background-music-manager.sh on - Enable background music
11
+ # background-music-manager.sh off - Disable background music
12
+ # background-music-manager.sh volume X - Set volume (0.0-1.0)
13
+ # background-music-manager.sh list - List all pre-packaged background music
14
+ # background-music-manager.sh set-default TRACK - Set default background music
15
+ # background-music-manager.sh get-enabled - Returns "true" or "false"
16
+ # background-music-manager.sh get-volume - Returns current volume
17
+ #
18
+
19
+ set -euo pipefail
20
+ export LC_ALL=C
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
24
+
25
+ # Config file location
26
+ CONFIG_DIR="$SCRIPT_DIR/../config"
27
+ ENABLED_FILE="$CONFIG_DIR/background-music-enabled.txt"
28
+ VOLUME_FILE="$CONFIG_DIR/background-music-volume.txt"
29
+
30
+ # Defaults
31
+ DEFAULT_VOLUME="0.34"
32
+
33
+ # Ensure config directory exists
34
+ mkdir -p "$CONFIG_DIR"
35
+
36
+ # @function is_enabled
37
+ # @intent Check if background music is enabled
38
+ # @returns 0 if enabled, 1 if disabled
39
+ is_enabled() {
40
+ if [[ -f "$ENABLED_FILE" ]]; then
41
+ local status
42
+ status=$(cat "$ENABLED_FILE" 2>/dev/null | tr -d '[:space:]')
43
+ [[ "$status" == "true" || "$status" == "on" || "$status" == "1" ]]
44
+ else
45
+ # Default: disabled
46
+ return 1
47
+ fi
48
+ }
49
+
50
+ # @function get_volume
51
+ # @intent Get current volume setting
52
+ # @returns Volume value (0.0-1.0)
53
+ get_volume() {
54
+ if [[ -f "$VOLUME_FILE" ]]; then
55
+ cat "$VOLUME_FILE" 2>/dev/null | tr -d '[:space:]'
56
+ else
57
+ echo "$DEFAULT_VOLUME"
58
+ fi
59
+ }
60
+
61
+ # @function set_enabled
62
+ # @intent Enable or disable background music
63
+ # @param $1 "true" or "false"
64
+ set_enabled() {
65
+ local value="$1"
66
+ echo "$value" > "$ENABLED_FILE"
67
+ }
68
+
69
+ # @function set_volume
70
+ # @intent Set background music volume
71
+ # @param $1 Volume value (0.0-1.0)
72
+ set_volume() {
73
+ local value="$1"
74
+
75
+ # Validate it's a number between 0 and 1
76
+ if ! [[ "$value" =~ ^[0-9]*\.?[0-9]+$ ]]; then
77
+ echo "Error: Volume must be a number between 0.0 and 1.0" >&2
78
+ return 1
79
+ fi
80
+
81
+ # Check range using bc
82
+ if command -v bc &> /dev/null; then
83
+ if (( $(echo "$value < 0" | bc -l) )) || (( $(echo "$value > 1" | bc -l) )); then
84
+ echo "Error: Volume must be between 0.0 and 1.0" >&2
85
+ return 1
86
+ fi
87
+ fi
88
+
89
+ echo "$value" > "$VOLUME_FILE"
90
+ }
91
+
92
+ # @function list_tracks
93
+ # @intent List all pre-packaged background music files
94
+ list_tracks() {
95
+ local bg_dir="$SCRIPT_DIR/../audio/tracks"
96
+
97
+ if [[ ! -d "$bg_dir" ]]; then
98
+ echo "❌ No tracks folder found at $bg_dir"
99
+ return 1
100
+ fi
101
+
102
+ echo "🎵 Available Background Music Tracks"
103
+ echo "===================================="
104
+ echo ""
105
+
106
+ local count=0
107
+ while IFS= read -r -d '' file; do
108
+ local basename
109
+ basename=$(basename "$file")
110
+ count=$((count + 1))
111
+ printf "%2d. %s\n" "$count" "$basename"
112
+ done < <(find "$bg_dir" -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.ogg" \) -print0 2>/dev/null | sort -z)
113
+
114
+ if [[ $count -eq 0 ]]; then
115
+ echo "No audio files found in tracks folder"
116
+ else
117
+ echo ""
118
+ echo "Total: $count track(s)"
119
+ fi
120
+ }
121
+
122
+ # @function get_default_track
123
+ # @intent Get the current default background music track
124
+ get_default_track() {
125
+ local audio_effects_cfg="$SCRIPT_DIR/../config/audio-effects.cfg"
126
+
127
+ if [[ ! -f "$audio_effects_cfg" ]]; then
128
+ echo ""
129
+ return
130
+ fi
131
+
132
+ # Extract the background file from the default entry
133
+ grep "^default|" "$audio_effects_cfg" 2>/dev/null | cut -d'|' -f3 || echo ""
134
+ }
135
+
136
+ # @function set_default_track
137
+ # @intent Set the default background music track
138
+ # @param $1 Track filename
139
+ set_default_track() {
140
+ local track="$1"
141
+ local audio_effects_cfg="$SCRIPT_DIR/../config/audio-effects.cfg"
142
+ local bg_dir="$SCRIPT_DIR/../audio/tracks"
143
+
144
+ if [[ -z "$track" ]]; then
145
+ echo "❌ Error: No track name provided"
146
+ echo "Usage: $0 set-default TRACK_NAME"
147
+ return 1
148
+ fi
149
+
150
+ # Check if track exists
151
+ if [[ ! -f "$bg_dir/$track" ]]; then
152
+ echo "❌ Error: Track '$track' not found in tracks folder"
153
+ echo "Run '$0 list' to see available tracks"
154
+ return 1
155
+ fi
156
+
157
+ # Check if audio-effects.cfg exists
158
+ if [[ ! -f "$audio_effects_cfg" ]]; then
159
+ echo "❌ Error: audio-effects.cfg not found at $audio_effects_cfg"
160
+ return 1
161
+ fi
162
+
163
+ # Update the default entry in audio-effects.cfg
164
+ # Preserve the sox effects and volume, just update the background file
165
+ local temp_file
166
+ temp_file=$(mktemp)
167
+
168
+ if grep -q "^default|" "$audio_effects_cfg"; then
169
+ # Replace existing default entry - preserve effects and volume
170
+ awk -F'|' -v track="$track" '
171
+ /^default\|/ {
172
+ print $1 "|" $2 "|" track "|" $4
173
+ next
174
+ }
175
+ { print }
176
+ ' "$audio_effects_cfg" > "$temp_file"
177
+
178
+ mv "$temp_file" "$audio_effects_cfg"
179
+
180
+ # Auto-enable background music if it was disabled
181
+ if ! is_enabled; then
182
+ set_enabled "true"
183
+ echo "✅ Default background music set to: $track"
184
+ echo "🎵 Background music enabled automatically"
185
+ else
186
+ echo "✅ Default background music set to: $track"
187
+ fi
188
+ else
189
+ echo "❌ Error: No default entry found in audio-effects.cfg"
190
+ return 1
191
+ fi
192
+ }
193
+
194
+ # @function show_status
195
+ # @intent Display current background music status
196
+ show_status() {
197
+ echo "🎵 Background Music Status"
198
+ echo "=========================="
199
+
200
+ if is_enabled; then
201
+ echo "Status: ✅ ENABLED"
202
+ else
203
+ echo "Status: 🔇 DISABLED"
204
+ fi
205
+
206
+ echo "Volume: $(get_volume) ($(echo "scale=0; $(get_volume) * 100 / 1" | bc -l 2>/dev/null || echo "?")%)"
207
+
208
+ # Show default track
209
+ local default_track
210
+ default_track=$(get_default_track)
211
+ if [[ -n "$default_track" ]]; then
212
+ echo "Default Track: $default_track"
213
+ else
214
+ echo "Default Track: (none)"
215
+ fi
216
+
217
+ # Check for background files
218
+ local bg_dir="$SCRIPT_DIR/../audio/tracks"
219
+ if [[ -d "$bg_dir" ]]; then
220
+ local count
221
+ count=$(find "$bg_dir" -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.ogg" \) 2>/dev/null | wc -l)
222
+ echo "Tracks: $count audio file(s) in tracks folder"
223
+ else
224
+ echo "Tracks: No tracks folder found"
225
+ fi
226
+
227
+ # Check dependencies
228
+ echo ""
229
+ echo "Dependencies:"
230
+ if command -v sox &> /dev/null; then
231
+ echo " sox: ✅ installed"
232
+ else
233
+ echo " sox: ❌ not installed (needed for effects)"
234
+ fi
235
+ if command -v ffmpeg &> /dev/null; then
236
+ echo " ffmpeg: ✅ installed"
237
+ else
238
+ echo " ffmpeg: ❌ not installed (needed for mixing)"
239
+ fi
240
+ }
241
+
242
+ # Set background music for a specific agent
243
+ set_agent_track() {
244
+ local agent="$1"
245
+ local track="$2"
246
+ local config_file="$SCRIPT_DIR/../config/audio-effects.cfg"
247
+
248
+ if [[ -z "$agent" ]] || [[ -z "$track" ]]; then
249
+ echo "❌ Error: Agent name and track required"
250
+ echo "Usage: $0 set-agent AGENT_NAME TRACK_NAME"
251
+ exit 1
252
+ fi
253
+
254
+ # Verify track exists
255
+ local bg_dir="$SCRIPT_DIR/../audio/tracks"
256
+ if [[ ! -f "$bg_dir/$track" ]]; then
257
+ echo "❌ Error: Track not found: $track"
258
+ echo "Run '$0 list' to see available tracks"
259
+ exit 1
260
+ fi
261
+
262
+ # Update or add agent config line
263
+ if grep -q "^${agent}|" "$config_file" 2>/dev/null; then
264
+ # Agent exists - update track (preserve effects and volume)
265
+ local temp_file
266
+ temp_file=$(mktemp)
267
+ awk -F'|' -v agent="$agent" -v track="$track" '
268
+ $1 == agent {
269
+ print $1 "|" $2 "|" track "|" $4
270
+ next
271
+ }
272
+ { print }
273
+ ' "$config_file" > "$temp_file"
274
+ mv "$temp_file" "$config_file"
275
+ echo "✅ Updated background music for $agent: $track"
276
+ else
277
+ # Agent doesn't exist - add new line with track
278
+ echo "${agent}||${track}|0.30" >> "$config_file"
279
+ echo "✅ Added background music for $agent: $track"
280
+ fi
281
+
282
+ # Auto-enable background music if it was disabled
283
+ if ! is_enabled; then
284
+ set_enabled "true"
285
+ echo "🎵 Background music enabled automatically"
286
+ fi
287
+ }
288
+
289
+ # Set background music for all agents
290
+ set_all_agents_track() {
291
+ local track="$1"
292
+ local config_file="$SCRIPT_DIR/../config/audio-effects.cfg"
293
+
294
+ if [[ -z "$track" ]]; then
295
+ echo "❌ Error: Track name required"
296
+ echo "Usage: $0 set-all TRACK_NAME"
297
+ exit 1
298
+ fi
299
+
300
+ # Verify track exists
301
+ local bg_dir="$SCRIPT_DIR/../audio/tracks"
302
+ if [[ ! -f "$bg_dir/$track" ]]; then
303
+ echo "❌ Error: Track not found: $track"
304
+ echo "Run '$0 list' to see available tracks"
305
+ exit 1
306
+ fi
307
+
308
+ # Update all non-comment, non-empty, non-default lines
309
+ local temp_file
310
+ temp_file=$(mktemp)
311
+ local count=0
312
+
313
+ awk -F'|' -v track="$track" '
314
+ # Skip comments and empty lines
315
+ /^#/ || /^[[:space:]]*$/ { print; next }
316
+
317
+ # Skip only _party_mode (but UPDATE default!)
318
+ $1 == "_party_mode" { print; next }
319
+
320
+ # Update all agent lines including default
321
+ {
322
+ print $1 "|" $2 "|" track "|" $4
323
+ }
324
+ ' "$config_file" > "$temp_file"
325
+
326
+ # Count updated agents (including default)
327
+ count=$(grep -v '^#' "$config_file" | grep -v '^[[:space:]]*$' | grep -v '^_party_mode|' | wc -l)
328
+
329
+ mv "$temp_file" "$config_file"
330
+ echo "✅ Updated background music for $count agents: $track"
331
+
332
+ # Auto-enable background music if it was disabled
333
+ if ! is_enabled; then
334
+ set_enabled "true"
335
+ echo "🎵 Background music enabled automatically"
336
+ fi
337
+ }
338
+
339
+ # Main command handler
340
+ case "${1:-status}" in
341
+ status|"")
342
+ show_status
343
+ ;;
344
+ on|enable|true)
345
+ set_enabled "true"
346
+ echo "🎵 Background music ENABLED at $(get_volume) volume"
347
+ ;;
348
+ off|disable|false)
349
+ set_enabled "false"
350
+ echo "🔇 Background music DISABLED"
351
+ ;;
352
+ volume)
353
+ if [[ -z "${2:-}" ]]; then
354
+ echo "Current volume: $(get_volume)"
355
+ else
356
+ set_volume "$2"
357
+ echo "🎵 Background music volume set to $2"
358
+ fi
359
+ ;;
360
+ list)
361
+ list_tracks
362
+ ;;
363
+ set-default)
364
+ if [[ -z "${2:-}" ]]; then
365
+ echo "❌ Error: No track name provided"
366
+ echo "Usage: $0 set-default TRACK_NAME"
367
+ echo "Run '$0 list' to see available tracks"
368
+ exit 1
369
+ fi
370
+ set_default_track "$2"
371
+ ;;
372
+ set-agent)
373
+ if [[ -z "${2:-}" ]] || [[ -z "${3:-}" ]]; then
374
+ echo "❌ Error: Agent name and track required"
375
+ echo "Usage: $0 set-agent AGENT_NAME TRACK_NAME"
376
+ echo "Run '$0 list' to see available tracks"
377
+ exit 1
378
+ fi
379
+ set_agent_track "$2" "$3"
380
+ ;;
381
+ set-all)
382
+ if [[ -z "${2:-}" ]]; then
383
+ echo "❌ Error: Track name required"
384
+ echo "Usage: $0 set-all TRACK_NAME"
385
+ echo "Run '$0 list' to see available tracks"
386
+ exit 1
387
+ fi
388
+ set_all_agents_track "$2"
389
+ ;;
390
+ get-enabled)
391
+ if is_enabled; then
392
+ echo "true"
393
+ else
394
+ echo "false"
395
+ fi
396
+ ;;
397
+ get-volume)
398
+ get_volume
399
+ ;;
400
+ *)
401
+ echo "Usage: $0 {status|on|off|volume [X]|list|set-default TRACK|set-agent AGENT TRACK|set-all TRACK|get-enabled|get-volume}"
402
+ exit 1
403
+ ;;
404
+ esac