agentvibes 2.0.17-beta.3 β†’ 2.0.17-beta.5

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.
@@ -48,6 +48,30 @@
48
48
  {
49
49
  "name": "get",
50
50
  "description": "Get personality details"
51
+ },
52
+ {
53
+ "name": "language",
54
+ "description": "Set main/native language"
55
+ },
56
+ {
57
+ "name": "learn",
58
+ "description": "Enable/disable language learning mode"
59
+ },
60
+ {
61
+ "name": "target",
62
+ "description": "Set target language to learn"
63
+ },
64
+ {
65
+ "name": "target-voice",
66
+ "description": "Set voice for target language"
67
+ },
68
+ {
69
+ "name": "set-speed",
70
+ "description": "Set speech speed for Piper TTS voices"
71
+ },
72
+ {
73
+ "name": "provider",
74
+ "description": "Manage TTS providers (ElevenLabs, Piper)"
51
75
  }
52
76
  ]
53
77
  }
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: Set TTS speech speed for Piper voices
3
+ argument-hint: [target] <speed>
4
+ ---
5
+
6
+ # Set Speech Speed
7
+
8
+ Control the speech rate for Piper TTS voices (ElevenLabs doesn't support speed control).
9
+
10
+ ## Usage
11
+
12
+ ```bash
13
+ /agent-vibes:set-speed 2x # Set main voice to 2x slower
14
+ /agent-vibes:set-speed target 2x # Set target language to 2x slower
15
+ /agent-vibes:set-speed 0.5x # Set main voice to 2x faster
16
+ /agent-vibes:set-speed target 3x # Set target language to 3x slower
17
+ /agent-vibes:set-speed normal # Reset to normal speed (1.0)
18
+ /agent-vibes:set-speed target normal # Reset target to normal speed
19
+ ```
20
+
21
+ ## Speed Values
22
+
23
+ - `0.5x` or `-2x` = 2x faster (half duration)
24
+ - `1x` or `normal` = Normal speed
25
+ - `2x` or `+2x` = 2x slower (double duration, great for learning)
26
+ - `3x` or `+3x` = 3x slower (triple duration, very slow)
27
+
28
+ ## Examples
29
+
30
+ ```bash
31
+ # Make Spanish 2x slower for learning
32
+ /agent-vibes:set-speed target 2x
33
+
34
+ # Make main voice faster
35
+ /agent-vibes:set-speed 0.5x
36
+
37
+ # Reset target language to normal speed
38
+ /agent-vibes:set-speed target normal
39
+ ```
40
+
41
+ !bash .claude/hooks/speed-manager.sh $ARGUMENTS
@@ -144,15 +144,60 @@ fi
144
144
  mkdir -p "$AUDIO_DIR"
145
145
  TEMP_FILE="$AUDIO_DIR/tts-$(date +%s).wav"
146
146
 
147
+ # @function get_speech_rate
148
+ # @intent Determine speech rate for Piper synthesis
149
+ # @why Allow slower speech for language learning (default 2.0 for non-English)
150
+ # @returns Speech rate value (default 1.0 for English, 2.0 for others)
151
+ get_speech_rate() {
152
+ local target_config=""
153
+ local main_config=""
154
+
155
+ # Check for target-specific config first (used for learning mode target language)
156
+ if [[ -f "$SCRIPT_DIR/../config/piper-target-speech-rate.txt" ]]; then
157
+ target_config="$SCRIPT_DIR/../config/piper-target-speech-rate.txt"
158
+ elif [[ -f "$HOME/.claude/config/piper-target-speech-rate.txt" ]]; then
159
+ target_config="$HOME/.claude/config/piper-target-speech-rate.txt"
160
+ fi
161
+
162
+ # Check for main config
163
+ if [[ -f "$SCRIPT_DIR/../config/piper-speech-rate.txt" ]]; then
164
+ main_config="$SCRIPT_DIR/../config/piper-speech-rate.txt"
165
+ elif [[ -f "$HOME/.claude/config/piper-speech-rate.txt" ]]; then
166
+ main_config="$HOME/.claude/config/piper-speech-rate.txt"
167
+ fi
168
+
169
+ # If this is a non-English voice and target config exists, use it
170
+ if [[ "$CURRENT_LANGUAGE" != "english" ]] && [[ -n "$target_config" ]]; then
171
+ cat "$target_config" 2>/dev/null
172
+ return
173
+ fi
174
+
175
+ # Otherwise use main config if available
176
+ if [[ -n "$main_config" ]]; then
177
+ # Read only the last non-comment line (the actual number)
178
+ grep -v '^#' "$main_config" 2>/dev/null | grep -v '^$' | tail -1
179
+ return
180
+ fi
181
+
182
+ # Default: 2x slower for non-English (better for language learning)
183
+ if [[ "$CURRENT_LANGUAGE" != "english" ]]; then
184
+ echo "2.0"
185
+ else
186
+ echo "1.0"
187
+ fi
188
+ }
189
+
190
+ SPEECH_RATE=$(get_speech_rate)
191
+
147
192
  # @function synthesize_with_piper
148
193
  # @intent Generate speech using Piper TTS
149
194
  # @why Provides free, offline TTS alternative
150
- # @param Uses globals: $TEXT, $VOICE_PATH
195
+ # @param Uses globals: $TEXT, $VOICE_PATH, $SPEECH_RATE
151
196
  # @returns Creates WAV file at $TEMP_FILE
152
197
  # @exitcode 0=success, 4=synthesis error
153
198
  # @sideeffects Creates audio file
154
199
  # @edgecases Handles piper errors, invalid models
155
- echo "$TEXT" | piper --model "$VOICE_PATH" --output_file "$TEMP_FILE" 2>/dev/null
200
+ echo "$TEXT" | piper --model "$VOICE_PATH" --length-scale "$SPEECH_RATE" --output_file "$TEMP_FILE" 2>/dev/null
156
201
 
157
202
  if [[ ! -f "$TEMP_FILE" ]] || [[ ! -s "$TEMP_FILE" ]]; then
158
203
  echo "❌ Failed to synthesize speech with Piper"
@@ -27,6 +27,29 @@ ACTIVE_PROVIDER=$(get_active_provider)
27
27
  # Show GitHub star reminder (once per day)
28
28
  "$SCRIPT_DIR/github-star-reminder.sh" 2>/dev/null || true
29
29
 
30
+ # @function detect_voice_provider
31
+ # @intent Auto-detect provider from voice name (for mixed-provider support)
32
+ # @why Allow ElevenLabs for main language + Piper for target language
33
+ # @param $1 voice name/ID
34
+ # @returns Provider name (elevenlabs or piper)
35
+ detect_voice_provider() {
36
+ local voice="$1"
37
+ # Piper voice names contain underscore and dash (e.g., es_ES-davefx-medium)
38
+ if [[ "$voice" == *"_"*"-"* ]]; then
39
+ echo "piper"
40
+ else
41
+ echo "$ACTIVE_PROVIDER"
42
+ fi
43
+ }
44
+
45
+ # Override provider if voice indicates different provider (mixed-provider mode)
46
+ if [[ -n "$VOICE_OVERRIDE" ]]; then
47
+ DETECTED_PROVIDER=$(detect_voice_provider "$VOICE_OVERRIDE")
48
+ if [[ "$DETECTED_PROVIDER" != "$ACTIVE_PROVIDER" ]]; then
49
+ ACTIVE_PROVIDER="$DETECTED_PROVIDER"
50
+ fi
51
+ fi
52
+
30
53
  # Normal single-language mode - route to appropriate provider implementation
31
54
  # Note: For learning mode, the output style will call this script TWICE:
32
55
  # 1. First call with main language text and current voice
@@ -209,6 +209,47 @@ provider_switch() {
209
209
  # Perform switch
210
210
  set_active_provider "$new_provider"
211
211
 
212
+ # Update target voice if language learning mode is active
213
+ local target_lang_file=""
214
+ local target_voice_file=""
215
+
216
+ # Check project-local first, then global
217
+ if [[ -d "$SCRIPT_DIR/../.." ]]; then
218
+ local project_dir="$SCRIPT_DIR/../.."
219
+ if [[ -f "$project_dir/.claude/tts-target-language.txt" ]]; then
220
+ target_lang_file="$project_dir/.claude/tts-target-language.txt"
221
+ target_voice_file="$project_dir/.claude/tts-target-voice.txt"
222
+ fi
223
+ fi
224
+
225
+ # Fallback to global
226
+ if [[ -z "$target_lang_file" ]]; then
227
+ if [[ -f "$HOME/.claude/tts-target-language.txt" ]]; then
228
+ target_lang_file="$HOME/.claude/tts-target-language.txt"
229
+ target_voice_file="$HOME/.claude/tts-target-voice.txt"
230
+ fi
231
+ fi
232
+
233
+ # If target language is set, update voice for new provider
234
+ if [[ -n "$target_lang_file" ]] && [[ -f "$target_lang_file" ]]; then
235
+ local target_lang
236
+ target_lang=$(cat "$target_lang_file")
237
+
238
+ if [[ -n "$target_lang" ]]; then
239
+ # Get the recommended voice for this language with new provider
240
+ local new_target_voice
241
+ new_target_voice=$(get_voice_for_language "$target_lang" "$new_provider")
242
+
243
+ if [[ -n "$new_target_voice" ]]; then
244
+ echo "$new_target_voice" > "$target_voice_file"
245
+ echo ""
246
+ echo "πŸ”„ Updated target language voice:"
247
+ echo " Language: $target_lang"
248
+ echo " Voice: $new_target_voice (for $new_provider)"
249
+ fi
250
+ fi
251
+ fi
252
+
212
253
  # Test new provider
213
254
  echo ""
214
255
  echo "πŸ”Š Testing provider..."
@@ -0,0 +1,226 @@
1
+ #!/bin/bash
2
+ #
3
+ # @fileoverview Speech Speed Manager for Piper TTS
4
+ # @context Manage speech rate for main and target language voices
5
+ # @architecture Simple config file manager for Piper length-scale parameter
6
+ #
7
+
8
+ # Get script directory
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+
11
+ # Determine config directory (project-local first, then global)
12
+ if [[ -n "$CLAUDE_PROJECT_DIR" ]] && [[ -d "$CLAUDE_PROJECT_DIR/.claude" ]]; then
13
+ CONFIG_DIR="$CLAUDE_PROJECT_DIR/.claude/config"
14
+ else
15
+ # Try to find .claude in current path
16
+ CURRENT_DIR="$PWD"
17
+ while [[ "$CURRENT_DIR" != "/" ]]; do
18
+ if [[ -d "$CURRENT_DIR/.claude" ]]; then
19
+ CONFIG_DIR="$CURRENT_DIR/.claude/config"
20
+ break
21
+ fi
22
+ CURRENT_DIR=$(dirname "$CURRENT_DIR")
23
+ done
24
+ # Fallback to global
25
+ if [[ -z "$CONFIG_DIR" ]]; then
26
+ CONFIG_DIR="$HOME/.claude/config"
27
+ fi
28
+ fi
29
+
30
+ mkdir -p "$CONFIG_DIR"
31
+
32
+ MAIN_SPEED_FILE="$CONFIG_DIR/piper-speech-rate.txt"
33
+ TARGET_SPEED_FILE="$CONFIG_DIR/piper-target-speech-rate.txt"
34
+
35
+ # @function parse_speed_value
36
+ # @intent Convert user-friendly speed notation to Piper length-scale value
37
+ # @param $1 Speed string (e.g., "2x", "+2x", "-2x", "0.5x", "normal")
38
+ # @returns Numeric length-scale value
39
+ parse_speed_value() {
40
+ local input="$1"
41
+
42
+ # Handle special cases
43
+ case "$input" in
44
+ normal|1x|1.0)
45
+ echo "1.0"
46
+ return
47
+ ;;
48
+ fast|-2x|0.5x)
49
+ echo "0.5"
50
+ return
51
+ ;;
52
+ slow|+2x|2x|2.0)
53
+ echo "2.0"
54
+ return
55
+ ;;
56
+ slower|+3x|3x|3.0)
57
+ echo "3.0"
58
+ return
59
+ ;;
60
+ esac
61
+
62
+ # Strip leading '+' if present
63
+ input="${input#+}"
64
+
65
+ # Strip trailing 'x' if present
66
+ input="${input%x}"
67
+
68
+ # Validate it's a number
69
+ if [[ "$input" =~ ^[0-9]+\.?[0-9]*$ ]]; then
70
+ echo "$input"
71
+ else
72
+ echo "ERROR"
73
+ fi
74
+ }
75
+
76
+ # @function set_speed
77
+ # @intent Set speech speed for main or target voice
78
+ # @param $1 Target ("target" or empty for main)
79
+ # @param $2 Speed value
80
+ set_speed() {
81
+ local is_target=false
82
+ local speed_input=""
83
+
84
+ # Parse arguments
85
+ if [[ "$1" == "target" ]]; then
86
+ is_target=true
87
+ speed_input="$2"
88
+ else
89
+ speed_input="$1"
90
+ fi
91
+
92
+ if [[ -z "$speed_input" ]]; then
93
+ echo "❌ Error: Speed value required"
94
+ echo "Usage: /agent-vibes:set-speed [target] <speed>"
95
+ echo "Examples: 2x, 0.5x, normal, +3x"
96
+ return 1
97
+ fi
98
+
99
+ # Parse speed value
100
+ local speed_value
101
+ speed_value=$(parse_speed_value "$speed_input")
102
+
103
+ if [[ "$speed_value" == "ERROR" ]]; then
104
+ echo "❌ Invalid speed value: $speed_input"
105
+ echo "Valid values: normal, 0.5x, 1x, 2x, 3x, +2x, -2x"
106
+ return 1
107
+ fi
108
+
109
+ # Determine which file to write to
110
+ local config_file
111
+ local voice_type
112
+ if [[ "$is_target" == true ]]; then
113
+ config_file="$TARGET_SPEED_FILE"
114
+ voice_type="target language"
115
+ else
116
+ config_file="$MAIN_SPEED_FILE"
117
+ voice_type="main voice"
118
+ fi
119
+
120
+ # Write speed value
121
+ echo "$speed_value" > "$config_file"
122
+
123
+ # Show confirmation
124
+ echo "βœ“ Speech speed set for $voice_type"
125
+ echo ""
126
+ echo "Speed: ${speed_value}x"
127
+
128
+ case "$speed_value" in
129
+ 0.5)
130
+ echo "Effect: 2x faster (half duration)"
131
+ ;;
132
+ 1.0)
133
+ echo "Effect: Normal speed"
134
+ ;;
135
+ 2.0)
136
+ echo "Effect: 2x slower (great for language learning)"
137
+ ;;
138
+ 3.0)
139
+ echo "Effect: 3x slower (very slow, detailed learning)"
140
+ ;;
141
+ *)
142
+ if (( $(echo "$speed_value > 1.0" | bc -l) )); then
143
+ echo "Effect: Slower speech"
144
+ else
145
+ echo "Effect: Faster speech"
146
+ fi
147
+ ;;
148
+ esac
149
+
150
+ echo ""
151
+ echo "Note: Speed control only works with Piper TTS voices"
152
+
153
+ # Test the new speed
154
+ if command -v bc &> /dev/null; then
155
+ local test_msg
156
+ if [[ "$is_target" == true ]]; then
157
+ test_msg="Velocidad de voz ajustada para aprender mejor"
158
+ else
159
+ test_msg="Speech speed adjusted successfully"
160
+ fi
161
+
162
+ echo ""
163
+ echo "πŸ”Š Testing new speed..."
164
+ "$SCRIPT_DIR/play-tts.sh" "$test_msg" &
165
+ fi
166
+ }
167
+
168
+ # @function get_speed
169
+ # @intent Display current speech speed settings
170
+ get_speed() {
171
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
172
+ echo " Current Speech Speed Settings"
173
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
174
+ echo ""
175
+
176
+ # Main voice speed
177
+ if [[ -f "$MAIN_SPEED_FILE" ]]; then
178
+ local main_speed=$(grep -v '^#' "$MAIN_SPEED_FILE" 2>/dev/null | grep -v '^$' | tail -1)
179
+ echo "Main voice: ${main_speed}x"
180
+ else
181
+ echo "Main voice: 1.0x (default, normal speed)"
182
+ fi
183
+
184
+ # Target voice speed
185
+ if [[ -f "$TARGET_SPEED_FILE" ]]; then
186
+ local target_speed=$(cat "$TARGET_SPEED_FILE" 2>/dev/null)
187
+ echo "Target language: ${target_speed}x"
188
+ else
189
+ echo "Target language: 2.0x (default, 2x slower for learning)"
190
+ fi
191
+
192
+ echo ""
193
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
194
+ }
195
+
196
+ # Main command handler
197
+ case "${1:-}" in
198
+ target)
199
+ set_speed "target" "$2"
200
+ ;;
201
+ get|status)
202
+ get_speed
203
+ ;;
204
+ normal|fast|slow|slower|*x|*.*|+*|-*)
205
+ set_speed "$1"
206
+ ;;
207
+ *)
208
+ echo "Speech Speed Manager"
209
+ echo ""
210
+ echo "Usage:"
211
+ echo " /agent-vibes:set-speed <speed> Set main voice speed"
212
+ echo " /agent-vibes:set-speed target <speed> Set target language speed"
213
+ echo " /agent-vibes:set-speed get Show current speeds"
214
+ echo ""
215
+ echo "Speed values:"
216
+ echo " 0.5x or -2x = 2x faster"
217
+ echo " 1x or normal = Normal speed"
218
+ echo " 2x or +2x = 2x slower (great for learning)"
219
+ echo " 3x or +3x = 3x slower"
220
+ echo ""
221
+ echo "Examples:"
222
+ echo " /agent-vibes:set-speed target 2x"
223
+ echo " /agent-vibes:set-speed 0.5x"
224
+ echo " /agent-vibes:set-speed normal"
225
+ ;;
226
+ esac
@@ -96,11 +96,44 @@ For 'random' personality: Pick a different personality each time from available
96
96
 
97
97
  Make each response unique, creative, and naturally incorporate the personality's style!
98
98
 
99
+ ## Language Learning Mode
100
+
101
+ **Check if learning mode is enabled:**
102
+ ```bash
103
+ LEARN_ENABLED=$(cat .claude/tts-learn-enabled.txt 2>/dev/null || cat ~/.claude/tts-learn-enabled.txt 2>/dev/null || echo "false")
104
+ ```
105
+
106
+ **If learning mode is ENABLED ("true"):**
107
+ 1. Get target language and voice:
108
+ ```bash
109
+ TARGET_LANG=$(cat .claude/tts-target-language.txt 2>/dev/null || cat ~/.claude/tts-target-language.txt 2>/dev/null)
110
+ TARGET_VOICE=$(cat .claude/tts-target-voice.txt 2>/dev/null || cat ~/.claude/tts-target-voice.txt 2>/dev/null)
111
+ ```
112
+
113
+ 2. **Make TWO TTS calls** for each acknowledgment/completion:
114
+ - **First**: Play in main language (English) with current voice
115
+ - **Second**: Translate to target language and play with target voice
116
+
117
+ 3. **Translation**: Use AI to translate the English message to the target language naturally
118
+
119
+ **Example with learning mode enabled (Spanish):**
120
+ ```
121
+ User: "hello"
122
+ # Acknowledgment in English
123
+ .claude/hooks/play-tts.sh "Hey there! Great to hear from you!"
124
+ # Acknowledgment in Spanish
125
+ .claude/hooks/play-tts.sh "Β‘Hola! Β‘QuΓ© bueno saber de ti!" "Antoni"
126
+ ```
127
+
128
+ **If learning mode is DISABLED:**
129
+ - Make normal single TTS call as usual
130
+
99
131
  ## Voice Selection
100
132
 
101
133
  - If user specifies a voice (e.g., "use Aria voice"), pass it as second parameter
102
134
  - Otherwise, omit second parameter to use default voice from `.claude/tts-voice.txt`
103
135
  - Use same voice for both acknowledgment and completion
136
+ - For learning mode, use target voice for second TTS call
104
137
 
105
138
  ## Example Usage
106
139
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "2.0.17-beta.3",
4
+ "version": "2.0.17-beta.5",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code and Claude Desktop (via MCP) with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [