agentvibes 2.13.9 → 2.14.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/commands/agent-vibes/translate.md +68 -0
- package/.claude/hooks/learn-manager.sh +14 -3
- package/.claude/hooks/play-tts.sh +131 -8
- package/.claude/hooks/requirements.txt +6 -0
- package/.claude/hooks/translate-manager.sh +341 -0
- package/.claude/hooks/translator.py +237 -0
- package/README.md +9 -8
- package/RELEASE_NOTES.md +114 -408
- package/docs/language-learning-mode.md +47 -2
- package/package.json +1 -1
- package/src/commands/bmad-voices.js +2 -1
- package/src/installer.js +9 -8
- package/test/unit/translator.bats +246 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Configure automatic TTS translation to speak in your preferred language'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# /agent-vibes:translate - Multi-Language TTS Translation
|
|
6
|
+
|
|
7
|
+
Configure AgentVibes to automatically translate English TTS text to your preferred language before speaking.
|
|
8
|
+
|
|
9
|
+
**Usage:**
|
|
10
|
+
- `/agent-vibes:translate` - Show current translation settings
|
|
11
|
+
- `/agent-vibes:translate set <language>` - Set translation language
|
|
12
|
+
- `/agent-vibes:translate auto` - Use BMAD communication_language setting
|
|
13
|
+
- `/agent-vibes:translate off` - Disable translation (speak English)
|
|
14
|
+
- `/agent-vibes:translate status` - Show detailed status
|
|
15
|
+
|
|
16
|
+
**Arguments:** $ARGUMENTS
|
|
17
|
+
|
|
18
|
+
## How It Works
|
|
19
|
+
|
|
20
|
+
When translation is enabled, AgentVibes will:
|
|
21
|
+
1. Take the English TTS text
|
|
22
|
+
2. Translate it to your target language using Google Translate
|
|
23
|
+
3. Speak the translated text using a language-appropriate voice
|
|
24
|
+
|
|
25
|
+
## Priority Order
|
|
26
|
+
|
|
27
|
+
1. **Manual override** (`/agent-vibes:translate set spanish`) - Highest priority
|
|
28
|
+
2. **BMAD config** (`communication_language` in `.bmad/core/config.yaml`) - Auto-detected
|
|
29
|
+
3. **Default** - No translation (English)
|
|
30
|
+
|
|
31
|
+
## Supported Languages
|
|
32
|
+
|
|
33
|
+
Spanish, French, German, Italian, Portuguese, Chinese, Japanese, Korean, Russian, Polish, Dutch, Turkish, Arabic, Hindi, Swedish, Danish, Norwegian, Finnish, Czech, Romanian, Ukrainian, Greek, Bulgarian, Croatian, Slovak
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Translate all TTS to Spanish
|
|
39
|
+
/agent-vibes:translate set spanish
|
|
40
|
+
|
|
41
|
+
# Use BMAD's communication_language setting
|
|
42
|
+
/agent-vibes:translate auto
|
|
43
|
+
|
|
44
|
+
# Disable translation (speak English)
|
|
45
|
+
/agent-vibes:translate off
|
|
46
|
+
|
|
47
|
+
# Check current settings
|
|
48
|
+
/agent-vibes:translate status
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Integration with BMAD
|
|
52
|
+
|
|
53
|
+
If you have BMAD installed with a `communication_language` setting:
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
# .bmad/core/config.yaml
|
|
57
|
+
communication_language: Spanish
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
AgentVibes will automatically detect this and translate TTS to Spanish when you run `/agent-vibes:translate auto`.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
Execute the translate-manager.sh script:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
.claude/hooks/translate-manager.sh $ARGUMENTS
|
|
68
|
+
```
|
|
@@ -34,10 +34,19 @@
|
|
|
34
34
|
# @patterns Dual-voice orchestration, auto-configuration, greeting on activation, provider-aware voice selection
|
|
35
35
|
# @related language-manager.sh, play-tts.sh, .claude/tts-learn-mode.txt, .claude/tts-target-language.txt
|
|
36
36
|
|
|
37
|
-
set
|
|
37
|
+
# Only set strict mode when executed directly, not when sourced
|
|
38
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
39
|
+
set -e
|
|
40
|
+
fi
|
|
38
41
|
|
|
39
42
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
40
|
-
|
|
43
|
+
|
|
44
|
+
# Use PWD for project dir when called from project context, fall back to script-relative
|
|
45
|
+
if [[ -d "$PWD/.claude" ]]; then
|
|
46
|
+
PROJECT_DIR="$PWD"
|
|
47
|
+
else
|
|
48
|
+
PROJECT_DIR="$SCRIPT_DIR/../.."
|
|
49
|
+
fi
|
|
41
50
|
|
|
42
51
|
# Configuration files (project-local first, then global fallback)
|
|
43
52
|
MAIN_LANG_FILE="$PROJECT_DIR/.claude/tts-main-language.txt"
|
|
@@ -430,7 +439,8 @@ show_status() {
|
|
|
430
439
|
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
431
440
|
}
|
|
432
441
|
|
|
433
|
-
# Main command handler
|
|
442
|
+
# Main command handler - only run if script is executed directly, not sourced
|
|
443
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
434
444
|
case "${1:-}" in
|
|
435
445
|
get-main-language)
|
|
436
446
|
get_main_language
|
|
@@ -473,3 +483,4 @@ case "${1:-}" in
|
|
|
473
483
|
exit 1
|
|
474
484
|
;;
|
|
475
485
|
esac
|
|
486
|
+
fi
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
#
|
|
32
32
|
# ---
|
|
33
33
|
#
|
|
34
|
-
# @fileoverview TTS Provider Router with Language Learning Support
|
|
35
|
-
# @context Routes TTS requests to active provider (ElevenLabs or Piper)
|
|
36
|
-
# @architecture Provider abstraction layer - single entry point for all TTS
|
|
37
|
-
# @dependencies provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh,
|
|
34
|
+
# @fileoverview TTS Provider Router with Translation and Language Learning Support
|
|
35
|
+
# @context Routes TTS requests to active provider (ElevenLabs or Piper) with optional translation
|
|
36
|
+
# @architecture Provider abstraction layer - single entry point for all TTS, handles translation and learning mode
|
|
37
|
+
# @dependencies provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, translator.py, translate-manager.sh, learn-manager.sh
|
|
38
38
|
# @entrypoints Called by hooks, slash commands, personality-manager.sh, and all TTS features
|
|
39
39
|
# @patterns Provider pattern - delegates to provider-specific implementations, auto-detects provider from voice name
|
|
40
|
-
# @related provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh
|
|
40
|
+
# @related provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh, translate-manager.sh
|
|
41
41
|
#
|
|
42
42
|
|
|
43
43
|
# Fix locale warnings
|
|
@@ -98,10 +98,133 @@ if [[ -n "$VOICE_OVERRIDE" ]]; then
|
|
|
98
98
|
fi
|
|
99
99
|
fi
|
|
100
100
|
|
|
101
|
+
# @function speak_text
|
|
102
|
+
# @intent Route text to appropriate TTS provider
|
|
103
|
+
# @why Reusable function for speaking, used by both single and learning modes
|
|
104
|
+
# @param $1 text to speak
|
|
105
|
+
# @param $2 voice override (optional)
|
|
106
|
+
# @param $3 provider override (optional)
|
|
107
|
+
speak_text() {
|
|
108
|
+
local text="$1"
|
|
109
|
+
local voice="${2:-}"
|
|
110
|
+
local provider="${3:-$ACTIVE_PROVIDER}"
|
|
111
|
+
|
|
112
|
+
case "$provider" in
|
|
113
|
+
elevenlabs)
|
|
114
|
+
"$SCRIPT_DIR/play-tts-elevenlabs.sh" "$text" "$voice"
|
|
115
|
+
;;
|
|
116
|
+
piper)
|
|
117
|
+
"$SCRIPT_DIR/play-tts-piper.sh" "$text" "$voice"
|
|
118
|
+
;;
|
|
119
|
+
*)
|
|
120
|
+
echo "❌ Unknown provider: $provider" >&2
|
|
121
|
+
return 1
|
|
122
|
+
;;
|
|
123
|
+
esac
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Note: learn-manager.sh and translate-manager.sh are sourced inside their
|
|
127
|
+
# respective handler functions to avoid triggering their main handlers
|
|
128
|
+
|
|
129
|
+
# @function handle_learning_mode
|
|
130
|
+
# @intent Speak in both main language and target language for learning
|
|
131
|
+
# @why Issue #51 - Auto-translate and speak twice for immersive language learning
|
|
132
|
+
# @returns 0 if learning mode handled, 1 if not in learning mode
|
|
133
|
+
handle_learning_mode() {
|
|
134
|
+
# Source learn-manager for learning mode functions
|
|
135
|
+
source "$SCRIPT_DIR/learn-manager.sh" 2>/dev/null || return 1
|
|
136
|
+
|
|
137
|
+
# Check if learning mode is enabled
|
|
138
|
+
if ! is_learn_mode_enabled 2>/dev/null; then
|
|
139
|
+
return 1
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
local target_lang
|
|
143
|
+
target_lang=$(get_target_language 2>/dev/null || echo "")
|
|
144
|
+
local target_voice
|
|
145
|
+
target_voice=$(get_target_voice 2>/dev/null || echo "")
|
|
146
|
+
|
|
147
|
+
# Need both target language and voice for learning mode
|
|
148
|
+
if [[ -z "$target_lang" ]] || [[ -z "$target_voice" ]]; then
|
|
149
|
+
return 1
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# 1. Speak in main language (current voice)
|
|
153
|
+
speak_text "$TEXT" "$VOICE_OVERRIDE" "$ACTIVE_PROVIDER"
|
|
154
|
+
|
|
155
|
+
# 2. Auto-translate to target language
|
|
156
|
+
local translated
|
|
157
|
+
translated=$(python3 "$SCRIPT_DIR/translator.py" "$TEXT" "$target_lang" 2>/dev/null) || translated="$TEXT"
|
|
158
|
+
|
|
159
|
+
# Small pause between languages
|
|
160
|
+
sleep 0.5
|
|
161
|
+
|
|
162
|
+
# 3. Speak translated text with target voice
|
|
163
|
+
local target_provider
|
|
164
|
+
target_provider=$(detect_voice_provider "$target_voice")
|
|
165
|
+
speak_text "$translated" "$target_voice" "$target_provider"
|
|
166
|
+
|
|
167
|
+
return 0
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# @function handle_translation_mode
|
|
171
|
+
# @intent Translate and speak in target language (non-learning mode)
|
|
172
|
+
# @why Issue #50 - BMAD multi-language TTS support
|
|
173
|
+
# @returns 0 if translation handled, 1 if not translating
|
|
174
|
+
handle_translation_mode() {
|
|
175
|
+
# Source translate-manager to get translation settings
|
|
176
|
+
source "$SCRIPT_DIR/translate-manager.sh" 2>/dev/null || return 1
|
|
177
|
+
|
|
178
|
+
# Check if translation is enabled
|
|
179
|
+
if ! is_translation_enabled 2>/dev/null; then
|
|
180
|
+
return 1
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
local translate_to
|
|
184
|
+
translate_to=$(get_translate_to 2>/dev/null || echo "")
|
|
185
|
+
|
|
186
|
+
if [[ -z "$translate_to" ]] || [[ "$translate_to" == "english" ]]; then
|
|
187
|
+
return 1
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# Translate text
|
|
191
|
+
local translated
|
|
192
|
+
translated=$(python3 "$SCRIPT_DIR/translator.py" "$TEXT" "$translate_to" 2>/dev/null) || translated="$TEXT"
|
|
193
|
+
|
|
194
|
+
# Get voice for target language if no override specified
|
|
195
|
+
local voice_to_use="$VOICE_OVERRIDE"
|
|
196
|
+
if [[ -z "$voice_to_use" ]]; then
|
|
197
|
+
source "$SCRIPT_DIR/language-manager.sh" 2>/dev/null || true
|
|
198
|
+
voice_to_use=$(get_voice_for_language "$translate_to" "$ACTIVE_PROVIDER" 2>/dev/null || echo "")
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# Update provider if voice indicates different provider
|
|
202
|
+
local provider_to_use="$ACTIVE_PROVIDER"
|
|
203
|
+
if [[ -n "$voice_to_use" ]]; then
|
|
204
|
+
provider_to_use=$(detect_voice_provider "$voice_to_use")
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
# Speak translated text
|
|
208
|
+
speak_text "$translated" "$voice_to_use" "$provider_to_use"
|
|
209
|
+
return 0
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
# Mode priority:
|
|
213
|
+
# 1. Learning mode (speaks twice: main + translated)
|
|
214
|
+
# 2. Translation mode (speaks translated only)
|
|
215
|
+
# 3. Normal mode (speaks as-is)
|
|
216
|
+
|
|
217
|
+
# Try learning mode first (Issue #51)
|
|
218
|
+
if handle_learning_mode; then
|
|
219
|
+
exit 0
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
# Try translation mode (Issue #50)
|
|
223
|
+
if handle_translation_mode; then
|
|
224
|
+
exit 0
|
|
225
|
+
fi
|
|
226
|
+
|
|
101
227
|
# Normal single-language mode - route to appropriate provider implementation
|
|
102
|
-
# Note: For learning mode, the output style will call this script TWICE:
|
|
103
|
-
# 1. First call with main language text and current voice
|
|
104
|
-
# 2. Second call with translated text and target voice
|
|
105
228
|
case "$ACTIVE_PROVIDER" in
|
|
106
229
|
elevenlabs)
|
|
107
230
|
exec "$SCRIPT_DIR/play-tts-elevenlabs.sh" "$TEXT" "$VOICE_OVERRIDE"
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/translate-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 Translation Manager - Auto-translate TTS to user's preferred language
|
|
30
|
+
# @context Integrates with BMAD communication_language and provides manual override
|
|
31
|
+
# @architecture Manages translation settings, detects BMAD config, translates text via translator.py
|
|
32
|
+
# @dependencies translator.py, language-manager.sh, .bmad/core/config.yaml (optional)
|
|
33
|
+
# @entrypoints Called by /agent-vibes:translate commands and play-tts.sh
|
|
34
|
+
# @patterns Config cascade - manual override > BMAD config > default (no translation)
|
|
35
|
+
# @related translator.py, play-tts.sh, language-manager.sh, learn-manager.sh
|
|
36
|
+
|
|
37
|
+
# Only set strict mode when executed directly, not when sourced
|
|
38
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
39
|
+
set -euo pipefail
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
43
|
+
|
|
44
|
+
# Use PWD for project dir when called from project context, fall back to script-relative
|
|
45
|
+
if [[ -d "$PWD/.claude" ]]; then
|
|
46
|
+
PROJECT_DIR="$PWD"
|
|
47
|
+
else
|
|
48
|
+
PROJECT_DIR="$SCRIPT_DIR/../.."
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Configuration files
|
|
52
|
+
TRANSLATE_FILE="$PROJECT_DIR/.claude/tts-translate-to.txt"
|
|
53
|
+
GLOBAL_TRANSLATE_FILE="$HOME/.claude/tts-translate-to.txt"
|
|
54
|
+
|
|
55
|
+
# Colors
|
|
56
|
+
GREEN='\033[0;32m'
|
|
57
|
+
YELLOW='\033[1;33m'
|
|
58
|
+
BLUE='\033[0;34m'
|
|
59
|
+
RED='\033[0;31m'
|
|
60
|
+
NC='\033[0m'
|
|
61
|
+
|
|
62
|
+
# Supported languages (matching language-manager.sh)
|
|
63
|
+
SUPPORTED_LANGUAGES="spanish french german italian portuguese chinese japanese korean russian polish dutch turkish arabic hindi swedish danish norwegian finnish czech romanian ukrainian greek bulgarian croatian slovak"
|
|
64
|
+
|
|
65
|
+
# @function get_bmad_language
|
|
66
|
+
# @intent Read communication_language from BMAD config
|
|
67
|
+
# @why BMAD users can set their preferred language in .bmad/core/config.yaml
|
|
68
|
+
# @returns Language name (lowercase) or empty if not set
|
|
69
|
+
get_bmad_language() {
|
|
70
|
+
local bmad_config=""
|
|
71
|
+
|
|
72
|
+
# Search for BMAD config in project or parents
|
|
73
|
+
local search_dir="$PWD"
|
|
74
|
+
while [[ "$search_dir" != "/" ]]; do
|
|
75
|
+
if [[ -f "$search_dir/.bmad/core/config.yaml" ]]; then
|
|
76
|
+
bmad_config="$search_dir/.bmad/core/config.yaml"
|
|
77
|
+
break
|
|
78
|
+
fi
|
|
79
|
+
search_dir=$(dirname "$search_dir")
|
|
80
|
+
done
|
|
81
|
+
|
|
82
|
+
if [[ -z "$bmad_config" ]] || [[ ! -f "$bmad_config" ]]; then
|
|
83
|
+
echo ""
|
|
84
|
+
return
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Security: Verify file ownership (should be owned by current user)
|
|
88
|
+
local owner
|
|
89
|
+
owner=$(stat -c '%u' "$bmad_config" 2>/dev/null || stat -f '%u' "$bmad_config" 2>/dev/null || echo "")
|
|
90
|
+
if [[ -n "$owner" ]] && [[ "$owner" != "$(id -u)" ]]; then
|
|
91
|
+
echo "Warning: BMAD config not owned by current user, skipping" >&2
|
|
92
|
+
echo ""
|
|
93
|
+
return
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Extract communication_language from YAML (simple grep approach)
|
|
97
|
+
local lang
|
|
98
|
+
lang=$(grep -E "^communication_language:" "$bmad_config" 2>/dev/null | head -1 | cut -d: -f2 | tr -d ' "'"'" | tr '[:upper:]' '[:lower:]')
|
|
99
|
+
|
|
100
|
+
echo "$lang"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# @function get_translate_to
|
|
104
|
+
# @intent Get the target language for translation
|
|
105
|
+
# @why Implements priority: manual override > BMAD config > no translation
|
|
106
|
+
# @returns Language name or empty if no translation
|
|
107
|
+
get_translate_to() {
|
|
108
|
+
# Priority 1: Manual override
|
|
109
|
+
if [[ -f "$TRANSLATE_FILE" ]]; then
|
|
110
|
+
local manual
|
|
111
|
+
manual=$(cat "$TRANSLATE_FILE")
|
|
112
|
+
if [[ "$manual" != "off" ]] && [[ "$manual" != "auto" ]]; then
|
|
113
|
+
echo "$manual"
|
|
114
|
+
return
|
|
115
|
+
elif [[ "$manual" == "off" ]]; then
|
|
116
|
+
echo ""
|
|
117
|
+
return
|
|
118
|
+
fi
|
|
119
|
+
# If "auto", fall through to BMAD detection
|
|
120
|
+
elif [[ -f "$GLOBAL_TRANSLATE_FILE" ]]; then
|
|
121
|
+
local manual
|
|
122
|
+
manual=$(cat "$GLOBAL_TRANSLATE_FILE")
|
|
123
|
+
if [[ "$manual" != "off" ]] && [[ "$manual" != "auto" ]]; then
|
|
124
|
+
echo "$manual"
|
|
125
|
+
return
|
|
126
|
+
elif [[ "$manual" == "off" ]]; then
|
|
127
|
+
echo ""
|
|
128
|
+
return
|
|
129
|
+
fi
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Priority 2: BMAD config
|
|
133
|
+
local bmad_lang
|
|
134
|
+
bmad_lang=$(get_bmad_language)
|
|
135
|
+
if [[ -n "$bmad_lang" ]] && [[ "$bmad_lang" != "english" ]]; then
|
|
136
|
+
echo "$bmad_lang"
|
|
137
|
+
return
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Default: No translation
|
|
141
|
+
echo ""
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# @function is_translation_enabled
|
|
145
|
+
# @intent Check if translation should occur
|
|
146
|
+
# @why Quick check for play-tts.sh to decide whether to translate
|
|
147
|
+
# @returns 0 if enabled, 1 if disabled
|
|
148
|
+
is_translation_enabled() {
|
|
149
|
+
local translate_to
|
|
150
|
+
translate_to=$(get_translate_to)
|
|
151
|
+
[[ -n "$translate_to" ]] && [[ "$translate_to" != "english" ]]
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# @function translate_text
|
|
155
|
+
# @intent Translate text to target language using translator.py
|
|
156
|
+
# @why Central translation function for all TTS
|
|
157
|
+
# @param $1 text to translate
|
|
158
|
+
# @param $2 target language (optional, auto-detected if not provided)
|
|
159
|
+
# @returns Translated text (or original if translation fails/disabled)
|
|
160
|
+
translate_text() {
|
|
161
|
+
local text="$1"
|
|
162
|
+
local target="${2:-}"
|
|
163
|
+
|
|
164
|
+
if [[ -z "$target" ]]; then
|
|
165
|
+
target=$(get_translate_to)
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Skip if no translation target or target is English
|
|
169
|
+
if [[ -z "$target" ]] || [[ "$target" == "english" ]]; then
|
|
170
|
+
echo "$text"
|
|
171
|
+
return
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Call translator.py
|
|
175
|
+
local translated
|
|
176
|
+
translated=$(python3 "$SCRIPT_DIR/translator.py" "$text" "$target" 2>/dev/null) || translated="$text"
|
|
177
|
+
|
|
178
|
+
echo "$translated"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
# @function set_translate
|
|
182
|
+
# @intent Set manual translation override
|
|
183
|
+
# @why Allows users to override BMAD config or force specific language
|
|
184
|
+
# @param $1 language name, "auto", or "off"
|
|
185
|
+
set_translate() {
|
|
186
|
+
local lang="$1"
|
|
187
|
+
|
|
188
|
+
if [[ -z "$lang" ]]; then
|
|
189
|
+
echo -e "${YELLOW}Usage: translate-manager.sh set <language|auto|off>${NC}"
|
|
190
|
+
exit 1
|
|
191
|
+
fi
|
|
192
|
+
|
|
193
|
+
lang=$(echo "$lang" | tr '[:upper:]' '[:lower:]')
|
|
194
|
+
|
|
195
|
+
mkdir -p "$PROJECT_DIR/.claude"
|
|
196
|
+
|
|
197
|
+
if [[ "$lang" == "off" ]]; then
|
|
198
|
+
echo "off" > "$TRANSLATE_FILE"
|
|
199
|
+
echo -e "${GREEN}✓${NC} Translation: ${YELLOW}DISABLED${NC}"
|
|
200
|
+
echo " TTS will speak in English only"
|
|
201
|
+
return
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
if [[ "$lang" == "auto" ]]; then
|
|
205
|
+
echo "auto" > "$TRANSLATE_FILE"
|
|
206
|
+
echo -e "${GREEN}✓${NC} Translation: ${BLUE}AUTO${NC}"
|
|
207
|
+
echo " Will detect from BMAD config if available"
|
|
208
|
+
|
|
209
|
+
local bmad_lang
|
|
210
|
+
bmad_lang=$(get_bmad_language)
|
|
211
|
+
if [[ -n "$bmad_lang" ]]; then
|
|
212
|
+
echo -e " ${BLUE}ℹ${NC} BMAD config detected: $bmad_lang"
|
|
213
|
+
else
|
|
214
|
+
echo -e " ${YELLOW}⚠${NC} No BMAD config found, will speak English"
|
|
215
|
+
fi
|
|
216
|
+
return
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
# Validate language
|
|
220
|
+
local valid=false
|
|
221
|
+
for supported in $SUPPORTED_LANGUAGES; do
|
|
222
|
+
if [[ "$lang" == "$supported" ]]; then
|
|
223
|
+
valid=true
|
|
224
|
+
break
|
|
225
|
+
fi
|
|
226
|
+
done
|
|
227
|
+
|
|
228
|
+
if [[ "$valid" != "true" ]]; then
|
|
229
|
+
echo -e "${RED}❌${NC} Language '$lang' not supported"
|
|
230
|
+
echo ""
|
|
231
|
+
echo "Supported languages:"
|
|
232
|
+
echo "$SUPPORTED_LANGUAGES" | tr ' ' '\n' | column
|
|
233
|
+
exit 1
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
echo "$lang" > "$TRANSLATE_FILE"
|
|
237
|
+
echo -e "${GREEN}✓${NC} Translation set to: ${BLUE}$lang${NC}"
|
|
238
|
+
echo " All TTS will be translated to $lang before speaking"
|
|
239
|
+
|
|
240
|
+
# Show voice recommendation
|
|
241
|
+
source "$SCRIPT_DIR/language-manager.sh" 2>/dev/null || true
|
|
242
|
+
if command -v get_voice_for_language &>/dev/null; then
|
|
243
|
+
local provider
|
|
244
|
+
provider=$(get_active_provider 2>/dev/null || echo "piper")
|
|
245
|
+
local voice
|
|
246
|
+
voice=$(get_voice_for_language "$lang" "$provider" 2>/dev/null || echo "")
|
|
247
|
+
if [[ -n "$voice" ]]; then
|
|
248
|
+
echo -e " ${BLUE}💡${NC} Recommended voice: ${YELLOW}$voice${NC}"
|
|
249
|
+
echo -e " Switch with: /agent-vibes:switch $voice"
|
|
250
|
+
fi
|
|
251
|
+
fi
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# @function show_status
|
|
255
|
+
# @intent Display current translation settings
|
|
256
|
+
# @why Help users understand what's configured
|
|
257
|
+
show_status() {
|
|
258
|
+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
259
|
+
echo -e "${BLUE} Translation Settings${NC}"
|
|
260
|
+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
261
|
+
echo ""
|
|
262
|
+
|
|
263
|
+
# Check manual setting
|
|
264
|
+
local manual_setting=""
|
|
265
|
+
if [[ -f "$TRANSLATE_FILE" ]]; then
|
|
266
|
+
manual_setting=$(cat "$TRANSLATE_FILE")
|
|
267
|
+
elif [[ -f "$GLOBAL_TRANSLATE_FILE" ]]; then
|
|
268
|
+
manual_setting=$(cat "$GLOBAL_TRANSLATE_FILE")
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Check BMAD config
|
|
272
|
+
local bmad_lang
|
|
273
|
+
bmad_lang=$(get_bmad_language)
|
|
274
|
+
|
|
275
|
+
# Get effective translation
|
|
276
|
+
local effective
|
|
277
|
+
effective=$(get_translate_to)
|
|
278
|
+
|
|
279
|
+
echo -e " ${BLUE}Manual Setting:${NC} ${manual_setting:-"(not set)"}"
|
|
280
|
+
echo -e " ${BLUE}BMAD Language:${NC} ${bmad_lang:-"(not detected)"}"
|
|
281
|
+
echo -e " ${BLUE}Effective:${NC} $(if [[ -n "$effective" ]]; then echo -e "${GREEN}$effective${NC}"; else echo -e "${YELLOW}No translation${NC}"; fi)"
|
|
282
|
+
echo ""
|
|
283
|
+
|
|
284
|
+
if [[ -n "$effective" ]]; then
|
|
285
|
+
echo -e " ${GREEN}✓${NC} TTS will be translated to ${BLUE}$effective${NC}"
|
|
286
|
+
else
|
|
287
|
+
echo -e " ${YELLOW}ℹ${NC} TTS will speak in English"
|
|
288
|
+
fi
|
|
289
|
+
|
|
290
|
+
echo ""
|
|
291
|
+
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
292
|
+
echo ""
|
|
293
|
+
echo -e " ${BLUE}Commands:${NC}"
|
|
294
|
+
echo -e " /agent-vibes:translate set <lang> Set manual translation"
|
|
295
|
+
echo -e " /agent-vibes:translate auto Use BMAD config"
|
|
296
|
+
echo -e " /agent-vibes:translate off Disable translation"
|
|
297
|
+
echo ""
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
# Main command handler - only run if script is executed directly, not sourced
|
|
301
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
302
|
+
case "${1:-}" in
|
|
303
|
+
get-bmad-language)
|
|
304
|
+
get_bmad_language
|
|
305
|
+
;;
|
|
306
|
+
get-translate-to)
|
|
307
|
+
get_translate_to
|
|
308
|
+
;;
|
|
309
|
+
is-enabled)
|
|
310
|
+
if is_translation_enabled; then
|
|
311
|
+
echo "ON"
|
|
312
|
+
exit 0
|
|
313
|
+
else
|
|
314
|
+
echo "OFF"
|
|
315
|
+
exit 1
|
|
316
|
+
fi
|
|
317
|
+
;;
|
|
318
|
+
translate)
|
|
319
|
+
if [[ -z "${2:-}" ]]; then
|
|
320
|
+
echo "Usage: translate-manager.sh translate <text> [target_lang]" >&2
|
|
321
|
+
exit 1
|
|
322
|
+
fi
|
|
323
|
+
translate_text "$2" "${3:-}"
|
|
324
|
+
;;
|
|
325
|
+
set)
|
|
326
|
+
set_translate "${2:-}"
|
|
327
|
+
;;
|
|
328
|
+
auto)
|
|
329
|
+
set_translate "auto"
|
|
330
|
+
;;
|
|
331
|
+
off)
|
|
332
|
+
set_translate "off"
|
|
333
|
+
;;
|
|
334
|
+
status)
|
|
335
|
+
show_status
|
|
336
|
+
;;
|
|
337
|
+
*)
|
|
338
|
+
show_status
|
|
339
|
+
;;
|
|
340
|
+
esac
|
|
341
|
+
fi
|