agentvibes 5.2.0 → 5.3.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.
- package/.claude/config/audio-effects.cfg +1 -1
- package/.claude/hooks/audio-cache-utils.sh +246 -246
- package/.claude/hooks/background-music-manager.sh +404 -404
- package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
- package/.claude/hooks/bmad-speak.sh +290 -290
- package/.claude/hooks/bmad-tts-injector.sh +568 -568
- package/.claude/hooks/bmad-voice-manager.sh +928 -928
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +129 -129
- package/.claude/hooks/clawdbot-receiver.sh +107 -107
- package/.claude/hooks/clean-audio-cache.sh +22 -22
- package/.claude/hooks/cleanup-cache.sh +106 -106
- package/.claude/hooks/configure-rdp-mode.sh +137 -137
- package/.claude/hooks/download-extra-voices.sh +244 -244
- package/.claude/hooks/effects-manager.sh +268 -268
- package/.claude/hooks/github-star-reminder.sh +154 -154
- package/.claude/hooks/language-manager.sh +362 -362
- package/.claude/hooks/learn-manager.sh +492 -492
- package/.claude/hooks/macos-voice-manager.sh +205 -205
- package/.claude/hooks/migrate-background-music.sh +125 -125
- package/.claude/hooks/migrate-to-agentvibes.sh +161 -161
- package/.claude/hooks/optimize-background-music.sh +87 -87
- package/.claude/hooks/path-resolver.sh +60 -60
- package/.claude/hooks/personality-manager.sh +448 -448
- package/.claude/hooks/piper-installer.sh +292 -292
- package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
- package/.claude/hooks/play-tts-enhanced.sh +105 -105
- package/.claude/hooks/play-tts-ssh-remote.sh +104 -10
- package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
- package/.claude/hooks/play-tts.sh +31 -11
- package/.claude/hooks/prepare-release.sh +54 -54
- package/.claude/hooks/provider-commands.sh +617 -617
- package/.claude/hooks/provider-manager.sh +399 -399
- package/.claude/hooks/replay-target-audio.sh +95 -95
- package/.claude/hooks/sentiment-manager.sh +201 -201
- package/.claude/hooks/speed-manager.sh +291 -291
- package/.claude/hooks/stop-tts.sh +84 -84
- package/.claude/hooks/termux-installer.sh +261 -261
- package/.claude/hooks/translate-manager.sh +341 -341
- package/.claude/hooks/tts-queue-worker.sh +145 -145
- package/.claude/hooks/tts-queue.sh +165 -165
- package/.claude/hooks/voice-manager.sh +552 -548
- package/.claude/hooks-windows/bmad-party-speak.ps1 +5 -1
- package/.claude/hooks-windows/play-tts.ps1 +91 -59
- package/README.md +21 -2
- package/RELEASE_NOTES.md +130 -0
- package/bin/mcp-server.sh +206 -206
- package/mcp-server/server.py +35 -6
- package/package.json +1 -1
- package/src/console/tabs/setup-tab.js +68 -29
- package/src/console/tabs/voices-tab.js +9 -3
- package/src/installer.js +79 -213
- package/src/services/llm-provider-service.js +139 -75
|
@@ -1,205 +1,205 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/macos-voice-manager.sh
|
|
4
|
-
#
|
|
5
|
-
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
-
# Website: https://agentvibes.org
|
|
7
|
-
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
-
#
|
|
9
|
-
# Co-created by Paul Preibisch with Claude AI
|
|
10
|
-
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
-
#
|
|
12
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
-
# you may not use this file except in compliance with the License.
|
|
14
|
-
# You may obtain a copy of the License at
|
|
15
|
-
#
|
|
16
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
-
#
|
|
18
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
19
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
-
# See the License for the specific language governing permissions and
|
|
22
|
-
# limitations under the License.
|
|
23
|
-
#
|
|
24
|
-
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
-
# express or implied. Use at your own risk. See the Apache License for details.
|
|
26
|
-
#
|
|
27
|
-
# ---
|
|
28
|
-
#
|
|
29
|
-
# @fileoverview macOS Voice Manager - Voice discovery and management for macOS 'say' command
|
|
30
|
-
# @context Provides voice listing, validation, and info for macOS native TTS
|
|
31
|
-
# @architecture Helper functions for play-tts-macos.sh provider
|
|
32
|
-
# @dependencies macOS only (Darwin), say command (built-in)
|
|
33
|
-
# @entrypoints Called by voice-manager.sh for provider-aware voice operations
|
|
34
|
-
# @patterns Voice enumeration via 'say -v ?', language filtering, quality tiers
|
|
35
|
-
# @related play-tts-macos.sh, voice-manager.sh, provider-manager.sh
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
# Platform guard
|
|
39
|
-
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
40
|
-
echo "❌ Error: macOS voice manager only works on macOS"
|
|
41
|
-
exit 1
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
# @function list_macos_voices
|
|
45
|
-
# @intent List all available macOS voices
|
|
46
|
-
# @returns Echoes voice names one per line
|
|
47
|
-
list_macos_voices() {
|
|
48
|
-
say -v ? 2>/dev/null | awk '{print $1}'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
# @function list_macos_voices_detailed
|
|
52
|
-
# @intent List all voices with language info
|
|
53
|
-
# @returns Echoes "voice_name language_code" per line
|
|
54
|
-
list_macos_voices_detailed() {
|
|
55
|
-
say -v ? 2>/dev/null | while read -r line; do
|
|
56
|
-
local voice=$(echo "$line" | awk '{print $1}')
|
|
57
|
-
local lang=$(echo "$line" | awk '{print $2}')
|
|
58
|
-
echo "$voice $lang"
|
|
59
|
-
done
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# @function list_english_voices
|
|
63
|
-
# @intent List only English voices
|
|
64
|
-
# @returns Echoes English voice names
|
|
65
|
-
list_english_voices() {
|
|
66
|
-
say -v ? 2>/dev/null | grep -i "en_" | awk '{print $1}'
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
# @function get_voice_language
|
|
70
|
-
# @intent Get the language code for a voice
|
|
71
|
-
# @param $1 Voice name
|
|
72
|
-
# @returns Echoes language code (e.g., "en_US")
|
|
73
|
-
get_voice_language() {
|
|
74
|
-
local voice="$1"
|
|
75
|
-
say -v ? 2>/dev/null | grep -i "^${voice} " | awk '{print $2}'
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
# @function validate_voice
|
|
79
|
-
# @intent Check if a voice exists on this system
|
|
80
|
-
# @param $1 Voice name
|
|
81
|
-
# @returns 0 if valid, 1 if not found
|
|
82
|
-
validate_voice() {
|
|
83
|
-
local voice="$1"
|
|
84
|
-
say -v ? 2>/dev/null | grep -qi "^${voice} "
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
# @function get_recommended_voices
|
|
88
|
-
# @intent Get list of recommended high-quality voices
|
|
89
|
-
# @returns Echoes recommended voice names
|
|
90
|
-
get_recommended_voices() {
|
|
91
|
-
# These are typically the highest quality voices on macOS
|
|
92
|
-
local recommended=("Samantha" "Alex" "Daniel" "Karen" "Moira" "Tessa" "Fiona" "Veena" "Victoria")
|
|
93
|
-
|
|
94
|
-
for voice in "${recommended[@]}"; do
|
|
95
|
-
if validate_voice "$voice"; then
|
|
96
|
-
echo "$voice"
|
|
97
|
-
fi
|
|
98
|
-
done
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# @function get_voice_info
|
|
102
|
-
# @intent Get detailed info about a specific voice
|
|
103
|
-
# @param $1 Voice name
|
|
104
|
-
# @returns Echoes voice details
|
|
105
|
-
get_voice_info() {
|
|
106
|
-
local voice="$1"
|
|
107
|
-
|
|
108
|
-
if ! validate_voice "$voice"; then
|
|
109
|
-
echo "❌ Voice not found: $voice"
|
|
110
|
-
return 1
|
|
111
|
-
fi
|
|
112
|
-
|
|
113
|
-
local full_info=$(say -v ? 2>/dev/null | grep -i "^${voice} ")
|
|
114
|
-
local lang=$(echo "$full_info" | awk '{print $2}')
|
|
115
|
-
|
|
116
|
-
echo "Voice: $voice"
|
|
117
|
-
echo "Language: $lang"
|
|
118
|
-
echo "Provider: macOS Say (built-in)"
|
|
119
|
-
|
|
120
|
-
# Add description for known voices
|
|
121
|
-
case "$voice" in
|
|
122
|
-
Alex) echo "Description: American English male (enhanced)" ;;
|
|
123
|
-
Samantha) echo "Description: American English female (enhanced)" ;;
|
|
124
|
-
Victoria) echo "Description: American English female" ;;
|
|
125
|
-
Daniel) echo "Description: British English male (enhanced)" ;;
|
|
126
|
-
Karen) echo "Description: Australian English female (enhanced)" ;;
|
|
127
|
-
Moira) echo "Description: Irish English female (enhanced)" ;;
|
|
128
|
-
Tessa) echo "Description: South African English female (enhanced)" ;;
|
|
129
|
-
Fiona) echo "Description: Scottish English female (enhanced)" ;;
|
|
130
|
-
Veena) echo "Description: Indian English female (enhanced)" ;;
|
|
131
|
-
esac
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
# @function count_voices
|
|
135
|
-
# @intent Count total available voices
|
|
136
|
-
# @returns Echoes count
|
|
137
|
-
count_voices() {
|
|
138
|
-
say -v ? 2>/dev/null | wc -l | tr -d ' '
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
# @function count_english_voices
|
|
142
|
-
# @intent Count English voices
|
|
143
|
-
# @returns Echoes count
|
|
144
|
-
count_english_voices() {
|
|
145
|
-
say -v ? 2>/dev/null | grep -i "en_" | wc -l | tr -d ' '
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
# Command-line interface
|
|
149
|
-
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
150
|
-
case "${1:-}" in
|
|
151
|
-
list)
|
|
152
|
-
echo "🎤 Available macOS Voices:"
|
|
153
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
154
|
-
list_macos_voices_detailed | while read -r voice lang; do
|
|
155
|
-
printf " %-15s %s\n" "$voice" "$lang"
|
|
156
|
-
done
|
|
157
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
158
|
-
echo "Total: $(count_voices) voices"
|
|
159
|
-
;;
|
|
160
|
-
list-english)
|
|
161
|
-
echo "🎤 English macOS Voices:"
|
|
162
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
163
|
-
list_english_voices
|
|
164
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
165
|
-
echo "Total: $(count_english_voices) English voices"
|
|
166
|
-
;;
|
|
167
|
-
recommended)
|
|
168
|
-
echo "🌟 Recommended macOS Voices:"
|
|
169
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
170
|
-
get_recommended_voices
|
|
171
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
172
|
-
;;
|
|
173
|
-
info)
|
|
174
|
-
if [[ -z "$2" ]]; then
|
|
175
|
-
echo "Usage: $0 info <voice_name>"
|
|
176
|
-
exit 1
|
|
177
|
-
fi
|
|
178
|
-
get_voice_info "$2"
|
|
179
|
-
;;
|
|
180
|
-
validate)
|
|
181
|
-
if [[ -z "$2" ]]; then
|
|
182
|
-
echo "Usage: $0 validate <voice_name>"
|
|
183
|
-
exit 1
|
|
184
|
-
fi
|
|
185
|
-
if validate_voice "$2"; then
|
|
186
|
-
echo "✅ Voice '$2' is available"
|
|
187
|
-
exit 0
|
|
188
|
-
else
|
|
189
|
-
echo "❌ Voice '$2' is not available"
|
|
190
|
-
exit 1
|
|
191
|
-
fi
|
|
192
|
-
;;
|
|
193
|
-
*)
|
|
194
|
-
echo "Usage: $0 {list|list-english|recommended|info|validate} [voice_name]"
|
|
195
|
-
echo ""
|
|
196
|
-
echo "Commands:"
|
|
197
|
-
echo " list - List all available voices"
|
|
198
|
-
echo " list-english - List English voices only"
|
|
199
|
-
echo " recommended - List recommended high-quality voices"
|
|
200
|
-
echo " info <voice> - Get details about a voice"
|
|
201
|
-
echo " validate <voice> - Check if voice exists"
|
|
202
|
-
exit 1
|
|
203
|
-
;;
|
|
204
|
-
esac
|
|
205
|
-
fi
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/macos-voice-manager.sh
|
|
4
|
+
#
|
|
5
|
+
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
+
# Website: https://agentvibes.org
|
|
7
|
+
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
+
#
|
|
9
|
+
# Co-created by Paul Preibisch with Claude AI
|
|
10
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
+
#
|
|
12
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
# you may not use this file except in compliance with the License.
|
|
14
|
+
# You may obtain a copy of the License at
|
|
15
|
+
#
|
|
16
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
#
|
|
18
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
# See the License for the specific language governing permissions and
|
|
22
|
+
# limitations under the License.
|
|
23
|
+
#
|
|
24
|
+
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
+
# express or implied. Use at your own risk. See the Apache License for details.
|
|
26
|
+
#
|
|
27
|
+
# ---
|
|
28
|
+
#
|
|
29
|
+
# @fileoverview macOS Voice Manager - Voice discovery and management for macOS 'say' command
|
|
30
|
+
# @context Provides voice listing, validation, and info for macOS native TTS
|
|
31
|
+
# @architecture Helper functions for play-tts-macos.sh provider
|
|
32
|
+
# @dependencies macOS only (Darwin), say command (built-in)
|
|
33
|
+
# @entrypoints Called by voice-manager.sh for provider-aware voice operations
|
|
34
|
+
# @patterns Voice enumeration via 'say -v ?', language filtering, quality tiers
|
|
35
|
+
# @related play-tts-macos.sh, voice-manager.sh, provider-manager.sh
|
|
36
|
+
#
|
|
37
|
+
|
|
38
|
+
# Platform guard
|
|
39
|
+
if [[ "$(uname -s)" != "Darwin" ]]; then
|
|
40
|
+
echo "❌ Error: macOS voice manager only works on macOS"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# @function list_macos_voices
|
|
45
|
+
# @intent List all available macOS voices
|
|
46
|
+
# @returns Echoes voice names one per line
|
|
47
|
+
list_macos_voices() {
|
|
48
|
+
say -v ? 2>/dev/null | awk '{print $1}'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# @function list_macos_voices_detailed
|
|
52
|
+
# @intent List all voices with language info
|
|
53
|
+
# @returns Echoes "voice_name language_code" per line
|
|
54
|
+
list_macos_voices_detailed() {
|
|
55
|
+
say -v ? 2>/dev/null | while read -r line; do
|
|
56
|
+
local voice=$(echo "$line" | awk '{print $1}')
|
|
57
|
+
local lang=$(echo "$line" | awk '{print $2}')
|
|
58
|
+
echo "$voice $lang"
|
|
59
|
+
done
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# @function list_english_voices
|
|
63
|
+
# @intent List only English voices
|
|
64
|
+
# @returns Echoes English voice names
|
|
65
|
+
list_english_voices() {
|
|
66
|
+
say -v ? 2>/dev/null | grep -i "en_" | awk '{print $1}'
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# @function get_voice_language
|
|
70
|
+
# @intent Get the language code for a voice
|
|
71
|
+
# @param $1 Voice name
|
|
72
|
+
# @returns Echoes language code (e.g., "en_US")
|
|
73
|
+
get_voice_language() {
|
|
74
|
+
local voice="$1"
|
|
75
|
+
say -v ? 2>/dev/null | grep -i "^${voice} " | awk '{print $2}'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# @function validate_voice
|
|
79
|
+
# @intent Check if a voice exists on this system
|
|
80
|
+
# @param $1 Voice name
|
|
81
|
+
# @returns 0 if valid, 1 if not found
|
|
82
|
+
validate_voice() {
|
|
83
|
+
local voice="$1"
|
|
84
|
+
say -v ? 2>/dev/null | grep -qi "^${voice} "
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# @function get_recommended_voices
|
|
88
|
+
# @intent Get list of recommended high-quality voices
|
|
89
|
+
# @returns Echoes recommended voice names
|
|
90
|
+
get_recommended_voices() {
|
|
91
|
+
# These are typically the highest quality voices on macOS
|
|
92
|
+
local recommended=("Samantha" "Alex" "Daniel" "Karen" "Moira" "Tessa" "Fiona" "Veena" "Victoria")
|
|
93
|
+
|
|
94
|
+
for voice in "${recommended[@]}"; do
|
|
95
|
+
if validate_voice "$voice"; then
|
|
96
|
+
echo "$voice"
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
# @function get_voice_info
|
|
102
|
+
# @intent Get detailed info about a specific voice
|
|
103
|
+
# @param $1 Voice name
|
|
104
|
+
# @returns Echoes voice details
|
|
105
|
+
get_voice_info() {
|
|
106
|
+
local voice="$1"
|
|
107
|
+
|
|
108
|
+
if ! validate_voice "$voice"; then
|
|
109
|
+
echo "❌ Voice not found: $voice"
|
|
110
|
+
return 1
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
local full_info=$(say -v ? 2>/dev/null | grep -i "^${voice} ")
|
|
114
|
+
local lang=$(echo "$full_info" | awk '{print $2}')
|
|
115
|
+
|
|
116
|
+
echo "Voice: $voice"
|
|
117
|
+
echo "Language: $lang"
|
|
118
|
+
echo "Provider: macOS Say (built-in)"
|
|
119
|
+
|
|
120
|
+
# Add description for known voices
|
|
121
|
+
case "$voice" in
|
|
122
|
+
Alex) echo "Description: American English male (enhanced)" ;;
|
|
123
|
+
Samantha) echo "Description: American English female (enhanced)" ;;
|
|
124
|
+
Victoria) echo "Description: American English female" ;;
|
|
125
|
+
Daniel) echo "Description: British English male (enhanced)" ;;
|
|
126
|
+
Karen) echo "Description: Australian English female (enhanced)" ;;
|
|
127
|
+
Moira) echo "Description: Irish English female (enhanced)" ;;
|
|
128
|
+
Tessa) echo "Description: South African English female (enhanced)" ;;
|
|
129
|
+
Fiona) echo "Description: Scottish English female (enhanced)" ;;
|
|
130
|
+
Veena) echo "Description: Indian English female (enhanced)" ;;
|
|
131
|
+
esac
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# @function count_voices
|
|
135
|
+
# @intent Count total available voices
|
|
136
|
+
# @returns Echoes count
|
|
137
|
+
count_voices() {
|
|
138
|
+
say -v ? 2>/dev/null | wc -l | tr -d ' '
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# @function count_english_voices
|
|
142
|
+
# @intent Count English voices
|
|
143
|
+
# @returns Echoes count
|
|
144
|
+
count_english_voices() {
|
|
145
|
+
say -v ? 2>/dev/null | grep -i "en_" | wc -l | tr -d ' '
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Command-line interface
|
|
149
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
150
|
+
case "${1:-}" in
|
|
151
|
+
list)
|
|
152
|
+
echo "🎤 Available macOS Voices:"
|
|
153
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
154
|
+
list_macos_voices_detailed | while read -r voice lang; do
|
|
155
|
+
printf " %-15s %s\n" "$voice" "$lang"
|
|
156
|
+
done
|
|
157
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
158
|
+
echo "Total: $(count_voices) voices"
|
|
159
|
+
;;
|
|
160
|
+
list-english)
|
|
161
|
+
echo "🎤 English macOS Voices:"
|
|
162
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
163
|
+
list_english_voices
|
|
164
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
165
|
+
echo "Total: $(count_english_voices) English voices"
|
|
166
|
+
;;
|
|
167
|
+
recommended)
|
|
168
|
+
echo "🌟 Recommended macOS Voices:"
|
|
169
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
170
|
+
get_recommended_voices
|
|
171
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
172
|
+
;;
|
|
173
|
+
info)
|
|
174
|
+
if [[ -z "$2" ]]; then
|
|
175
|
+
echo "Usage: $0 info <voice_name>"
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
get_voice_info "$2"
|
|
179
|
+
;;
|
|
180
|
+
validate)
|
|
181
|
+
if [[ -z "$2" ]]; then
|
|
182
|
+
echo "Usage: $0 validate <voice_name>"
|
|
183
|
+
exit 1
|
|
184
|
+
fi
|
|
185
|
+
if validate_voice "$2"; then
|
|
186
|
+
echo "✅ Voice '$2' is available"
|
|
187
|
+
exit 0
|
|
188
|
+
else
|
|
189
|
+
echo "❌ Voice '$2' is not available"
|
|
190
|
+
exit 1
|
|
191
|
+
fi
|
|
192
|
+
;;
|
|
193
|
+
*)
|
|
194
|
+
echo "Usage: $0 {list|list-english|recommended|info|validate} [voice_name]"
|
|
195
|
+
echo ""
|
|
196
|
+
echo "Commands:"
|
|
197
|
+
echo " list - List all available voices"
|
|
198
|
+
echo " list-english - List English voices only"
|
|
199
|
+
echo " recommended - List recommended high-quality voices"
|
|
200
|
+
echo " info <voice> - Get details about a voice"
|
|
201
|
+
echo " validate <voice> - Check if voice exists"
|
|
202
|
+
exit 1
|
|
203
|
+
;;
|
|
204
|
+
esac
|
|
205
|
+
fi
|
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/migrate-background-music.sh
|
|
4
|
-
#
|
|
5
|
-
# AgentVibes - Background Music Migration Script
|
|
6
|
-
# Cleans up old background music structure from previous versions
|
|
7
|
-
#
|
|
8
|
-
# This script removes:
|
|
9
|
-
# - Old optimized/ subdirectory
|
|
10
|
-
# - Old PascalCase/space-formatted filenames
|
|
11
|
-
# - Outdated config entries with optimized/ prefix
|
|
12
|
-
#
|
|
13
|
-
# Called automatically during installation to ensure clean state
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
set -euo pipefail
|
|
17
|
-
export LC_ALL=C
|
|
18
|
-
|
|
19
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
21
|
-
|
|
22
|
-
BG_DIR="$SCRIPT_DIR/../audio/tracks"
|
|
23
|
-
CONFIG_FILE="$SCRIPT_DIR/../config/audio-effects.cfg"
|
|
24
|
-
|
|
25
|
-
# Flag to track if any changes were made
|
|
26
|
-
CHANGES_MADE=false
|
|
27
|
-
|
|
28
|
-
echo "🔄 Checking for old background music structure..."
|
|
29
|
-
|
|
30
|
-
# 1. Remove old optimized/ subdirectory if it exists
|
|
31
|
-
if [[ -d "$BG_DIR/optimized" ]]; then
|
|
32
|
-
echo " → Removing old optimized/ subdirectory..."
|
|
33
|
-
|
|
34
|
-
# Check if there are any files in optimized/ that aren't in the parent
|
|
35
|
-
if [[ -n "$(find "$BG_DIR/optimized" -type f -name "*.mp3" 2>/dev/null)" ]]; then
|
|
36
|
-
# Move any unique files up before deleting
|
|
37
|
-
find "$BG_DIR/optimized" -type f -name "*.mp3" 2>/dev/null | while IFS= read -r file; do
|
|
38
|
-
basename_file=$(basename "$file")
|
|
39
|
-
# Convert to snake_case if needed
|
|
40
|
-
snake_case_file=$(echo "$basename_file" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
41
|
-
|
|
42
|
-
# Only move if file doesn't exist in parent with snake_case name
|
|
43
|
-
if [[ ! -f "$BG_DIR/$snake_case_file" ]]; then
|
|
44
|
-
echo " • Migrating: $basename_file → $snake_case_file"
|
|
45
|
-
mv "$file" "$BG_DIR/$snake_case_file"
|
|
46
|
-
CHANGES_MADE=true
|
|
47
|
-
fi
|
|
48
|
-
done
|
|
49
|
-
fi
|
|
50
|
-
|
|
51
|
-
# Remove the optimized directory
|
|
52
|
-
rm -rf "$BG_DIR/optimized"
|
|
53
|
-
echo " ✓ Removed optimized/ subdirectory"
|
|
54
|
-
CHANGES_MADE=true
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
# 2. Remove old PascalCase/space-formatted files if snake_case versions exist
|
|
58
|
-
if [[ -d "$BG_DIR" ]]; then
|
|
59
|
-
find "$BG_DIR" -maxdepth 1 -type f -name "*.mp3" 2>/dev/null | while IFS= read -r file; do
|
|
60
|
-
basename_file=$(basename "$file")
|
|
61
|
-
|
|
62
|
-
# Check if this file has spaces or uppercase letters (old format)
|
|
63
|
-
if [[ "$basename_file" =~ [[:space:]] ]] || [[ "$basename_file" =~ [A-Z] ]]; then
|
|
64
|
-
# Generate snake_case equivalent
|
|
65
|
-
snake_case_file=$(echo "$basename_file" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
66
|
-
|
|
67
|
-
# If snake_case version exists, remove the old format
|
|
68
|
-
if [[ -f "$BG_DIR/$snake_case_file" ]] && [[ "$basename_file" != "$snake_case_file" ]]; then
|
|
69
|
-
echo " → Removing old format: $basename_file (replaced by $snake_case_file)"
|
|
70
|
-
rm -f "$file"
|
|
71
|
-
CHANGES_MADE=true
|
|
72
|
-
fi
|
|
73
|
-
fi
|
|
74
|
-
done
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# 3. Update audio-effects.cfg to remove optimized/ prefixes
|
|
78
|
-
if [[ -f "$CONFIG_FILE" ]]; then
|
|
79
|
-
if grep -q "optimized/" "$CONFIG_FILE" 2>/dev/null; then
|
|
80
|
-
echo " → Updating config to remove optimized/ prefixes..."
|
|
81
|
-
|
|
82
|
-
# Create backup
|
|
83
|
-
cp "$CONFIG_FILE" "${CONFIG_FILE}.backup-migration"
|
|
84
|
-
|
|
85
|
-
# Remove optimized/ prefix from all entries
|
|
86
|
-
sed -i.bak 's|optimized/||g' "$CONFIG_FILE"
|
|
87
|
-
rm -f "${CONFIG_FILE}.bak"
|
|
88
|
-
|
|
89
|
-
echo " ✓ Updated audio-effects.cfg"
|
|
90
|
-
CHANGES_MADE=true
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# Also convert any remaining PascalCase/space filenames to snake_case in config
|
|
94
|
-
if grep -E '\|[^|]*[A-Z ][^|]*\.mp3\|' "$CONFIG_FILE" 2>/dev/null | grep -v '^#' > /dev/null; then
|
|
95
|
-
echo " → Converting config entries to snake_case..."
|
|
96
|
-
|
|
97
|
-
# This is complex - we need to convert field 3 (background file) to snake_case
|
|
98
|
-
temp_file=$(mktemp)
|
|
99
|
-
while IFS='|' read -r field1 field2 field3 field4 rest; do
|
|
100
|
-
# Skip comments and empty lines
|
|
101
|
-
if [[ "$field1" =~ ^#.* ]] || [[ -z "$field1" ]]; then
|
|
102
|
-
echo "$field1|$field2|$field3|$field4$rest"
|
|
103
|
-
continue
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
# Convert field3 (background file) to snake_case if it contains spaces or uppercase
|
|
107
|
-
if [[ -n "$field3" ]] && ([[ "$field3" =~ [[:space:]] ]] || [[ "$field3" =~ [A-Z] ]]); then
|
|
108
|
-
new_field3=$(echo "$field3" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
109
|
-
echo "$field1|$field2|$new_field3|$field4$rest"
|
|
110
|
-
else
|
|
111
|
-
echo "$field1|$field2|$field3|$field4$rest"
|
|
112
|
-
fi
|
|
113
|
-
done < "$CONFIG_FILE" > "$temp_file"
|
|
114
|
-
|
|
115
|
-
mv "$temp_file" "$CONFIG_FILE"
|
|
116
|
-
echo " ✓ Converted config entries to snake_case"
|
|
117
|
-
CHANGES_MADE=true
|
|
118
|
-
fi
|
|
119
|
-
fi
|
|
120
|
-
|
|
121
|
-
if [[ "$CHANGES_MADE" == "true" ]]; then
|
|
122
|
-
echo "✅ Migration complete! Old background music structure cleaned up."
|
|
123
|
-
else
|
|
124
|
-
echo "✅ No migration needed - structure is already up to date."
|
|
125
|
-
fi
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/migrate-background-music.sh
|
|
4
|
+
#
|
|
5
|
+
# AgentVibes - Background Music Migration Script
|
|
6
|
+
# Cleans up old background music structure from previous versions
|
|
7
|
+
#
|
|
8
|
+
# This script removes:
|
|
9
|
+
# - Old optimized/ subdirectory
|
|
10
|
+
# - Old PascalCase/space-formatted filenames
|
|
11
|
+
# - Outdated config entries with optimized/ prefix
|
|
12
|
+
#
|
|
13
|
+
# Called automatically during installation to ensure clean state
|
|
14
|
+
#
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
export LC_ALL=C
|
|
18
|
+
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
21
|
+
|
|
22
|
+
BG_DIR="$SCRIPT_DIR/../audio/tracks"
|
|
23
|
+
CONFIG_FILE="$SCRIPT_DIR/../config/audio-effects.cfg"
|
|
24
|
+
|
|
25
|
+
# Flag to track if any changes were made
|
|
26
|
+
CHANGES_MADE=false
|
|
27
|
+
|
|
28
|
+
echo "🔄 Checking for old background music structure..."
|
|
29
|
+
|
|
30
|
+
# 1. Remove old optimized/ subdirectory if it exists
|
|
31
|
+
if [[ -d "$BG_DIR/optimized" ]]; then
|
|
32
|
+
echo " → Removing old optimized/ subdirectory..."
|
|
33
|
+
|
|
34
|
+
# Check if there are any files in optimized/ that aren't in the parent
|
|
35
|
+
if [[ -n "$(find "$BG_DIR/optimized" -type f -name "*.mp3" 2>/dev/null)" ]]; then
|
|
36
|
+
# Move any unique files up before deleting
|
|
37
|
+
find "$BG_DIR/optimized" -type f -name "*.mp3" 2>/dev/null | while IFS= read -r file; do
|
|
38
|
+
basename_file=$(basename "$file")
|
|
39
|
+
# Convert to snake_case if needed
|
|
40
|
+
snake_case_file=$(echo "$basename_file" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
41
|
+
|
|
42
|
+
# Only move if file doesn't exist in parent with snake_case name
|
|
43
|
+
if [[ ! -f "$BG_DIR/$snake_case_file" ]]; then
|
|
44
|
+
echo " • Migrating: $basename_file → $snake_case_file"
|
|
45
|
+
mv "$file" "$BG_DIR/$snake_case_file"
|
|
46
|
+
CHANGES_MADE=true
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Remove the optimized directory
|
|
52
|
+
rm -rf "$BG_DIR/optimized"
|
|
53
|
+
echo " ✓ Removed optimized/ subdirectory"
|
|
54
|
+
CHANGES_MADE=true
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# 2. Remove old PascalCase/space-formatted files if snake_case versions exist
|
|
58
|
+
if [[ -d "$BG_DIR" ]]; then
|
|
59
|
+
find "$BG_DIR" -maxdepth 1 -type f -name "*.mp3" 2>/dev/null | while IFS= read -r file; do
|
|
60
|
+
basename_file=$(basename "$file")
|
|
61
|
+
|
|
62
|
+
# Check if this file has spaces or uppercase letters (old format)
|
|
63
|
+
if [[ "$basename_file" =~ [[:space:]] ]] || [[ "$basename_file" =~ [A-Z] ]]; then
|
|
64
|
+
# Generate snake_case equivalent
|
|
65
|
+
snake_case_file=$(echo "$basename_file" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
66
|
+
|
|
67
|
+
# If snake_case version exists, remove the old format
|
|
68
|
+
if [[ -f "$BG_DIR/$snake_case_file" ]] && [[ "$basename_file" != "$snake_case_file" ]]; then
|
|
69
|
+
echo " → Removing old format: $basename_file (replaced by $snake_case_file)"
|
|
70
|
+
rm -f "$file"
|
|
71
|
+
CHANGES_MADE=true
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# 3. Update audio-effects.cfg to remove optimized/ prefixes
|
|
78
|
+
if [[ -f "$CONFIG_FILE" ]]; then
|
|
79
|
+
if grep -q "optimized/" "$CONFIG_FILE" 2>/dev/null; then
|
|
80
|
+
echo " → Updating config to remove optimized/ prefixes..."
|
|
81
|
+
|
|
82
|
+
# Create backup
|
|
83
|
+
cp "$CONFIG_FILE" "${CONFIG_FILE}.backup-migration"
|
|
84
|
+
|
|
85
|
+
# Remove optimized/ prefix from all entries
|
|
86
|
+
sed -i.bak 's|optimized/||g' "$CONFIG_FILE"
|
|
87
|
+
rm -f "${CONFIG_FILE}.bak"
|
|
88
|
+
|
|
89
|
+
echo " ✓ Updated audio-effects.cfg"
|
|
90
|
+
CHANGES_MADE=true
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Also convert any remaining PascalCase/space filenames to snake_case in config
|
|
94
|
+
if grep -E '\|[^|]*[A-Z ][^|]*\.mp3\|' "$CONFIG_FILE" 2>/dev/null | grep -v '^#' > /dev/null; then
|
|
95
|
+
echo " → Converting config entries to snake_case..."
|
|
96
|
+
|
|
97
|
+
# This is complex - we need to convert field 3 (background file) to snake_case
|
|
98
|
+
temp_file=$(mktemp)
|
|
99
|
+
while IFS='|' read -r field1 field2 field3 field4 rest; do
|
|
100
|
+
# Skip comments and empty lines
|
|
101
|
+
if [[ "$field1" =~ ^#.* ]] || [[ -z "$field1" ]]; then
|
|
102
|
+
echo "$field1|$field2|$field3|$field4$rest"
|
|
103
|
+
continue
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Convert field3 (background file) to snake_case if it contains spaces or uppercase
|
|
107
|
+
if [[ -n "$field3" ]] && ([[ "$field3" =~ [[:space:]] ]] || [[ "$field3" =~ [A-Z] ]]); then
|
|
108
|
+
new_field3=$(echo "$field3" | tr '[:upper:]' '[:lower:]' | tr ' ' '_' | tr '-' '_')
|
|
109
|
+
echo "$field1|$field2|$new_field3|$field4$rest"
|
|
110
|
+
else
|
|
111
|
+
echo "$field1|$field2|$field3|$field4$rest"
|
|
112
|
+
fi
|
|
113
|
+
done < "$CONFIG_FILE" > "$temp_file"
|
|
114
|
+
|
|
115
|
+
mv "$temp_file" "$CONFIG_FILE"
|
|
116
|
+
echo " ✓ Converted config entries to snake_case"
|
|
117
|
+
CHANGES_MADE=true
|
|
118
|
+
fi
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
if [[ "$CHANGES_MADE" == "true" ]]; then
|
|
122
|
+
echo "✅ Migration complete! Old background music structure cleaned up."
|
|
123
|
+
else
|
|
124
|
+
echo "✅ No migration needed - structure is already up to date."
|
|
125
|
+
fi
|