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.
- package/.agentvibes/bmad/bmad-voices.md +69 -69
- package/.agentvibes/config.json +12 -0
- package/.claude/activation-instructions +54 -54
- package/.claude/audio/tracks/README.md +52 -52
- package/.claude/commands/agent-vibes/add.md +21 -21
- package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
- package/.claude/commands/agent-vibes/agent.md +79 -79
- package/.claude/commands/agent-vibes/background-music.md +111 -111
- package/.claude/commands/agent-vibes/bmad.md +198 -198
- package/.claude/commands/agent-vibes/clean.md +18 -18
- package/.claude/commands/agent-vibes/cleanup.md +18 -18
- package/.claude/commands/agent-vibes/commands.json +145 -145
- package/.claude/commands/agent-vibes/effects.md +97 -97
- package/.claude/commands/agent-vibes/get.md +9 -9
- package/.claude/commands/agent-vibes/hide.md +91 -91
- package/.claude/commands/agent-vibes/language.md +23 -23
- package/.claude/commands/agent-vibes/learn.md +67 -67
- package/.claude/commands/agent-vibes/list.md +13 -13
- package/.claude/commands/agent-vibes/mute.md +37 -37
- package/.claude/commands/agent-vibes/preview.md +17 -17
- package/.claude/commands/agent-vibes/provider.md +68 -68
- package/.claude/commands/agent-vibes/replay-target.md +14 -14
- package/.claude/commands/agent-vibes/sample.md +12 -12
- package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
- package/.claude/commands/agent-vibes/set-pretext.md +65 -65
- package/.claude/commands/agent-vibes/set-speed.md +41 -41
- package/.claude/commands/agent-vibes/show.md +84 -84
- package/.claude/commands/agent-vibes/switch.md +87 -87
- package/.claude/commands/agent-vibes/target-voice.md +26 -26
- package/.claude/commands/agent-vibes/target.md +30 -30
- package/.claude/commands/agent-vibes/translate.md +68 -68
- package/.claude/commands/agent-vibes/unmute.md +45 -45
- package/.claude/commands/agent-vibes/verbosity.md +89 -89
- package/.claude/commands/agent-vibes/whoami.md +7 -7
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/agentvibes.json +1 -0
- package/.claude/config/audio-effects.cfg +2 -2
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-volume.txt +1 -0
- package/.claude/config/intro-text.txt +1 -0
- package/.claude/config/piper-speech-rate.txt +4 -0
- package/.claude/config/piper-target-speech-rate.txt +1 -0
- package/.claude/config/reverb-level.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +4 -0
- package/.claude/config/tts-target-speech-rate.txt +1 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/README-TTS-QUEUE.md +135 -135
- package/.claude/hooks/audio-cache-utils.sh +246 -246
- package/.claude/hooks/audio-processor.sh +433 -433
- package/.claude/hooks/background-music-manager.sh +404 -404
- package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
- package/.claude/hooks/bmad-speak.sh +269 -269
- 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-download-voices.sh +225 -225
- package/.claude/hooks/piper-installer.sh +292 -292
- package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
- package/.claude/hooks/piper-voice-manager.sh +24 -3
- package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +90 -90
- package/.claude/hooks/play-tts-enhanced.sh +105 -105
- package/.claude/hooks/play-tts-macos.sh +368 -368
- package/.claude/hooks/play-tts-piper.sh +679 -679
- package/.claude/hooks/play-tts-soprano.sh +356 -356
- package/.claude/hooks/play-tts-ssh-remote.sh +167 -167
- package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
- package/.claude/hooks/play-tts.sh +301 -301
- 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/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +201 -201
- package/.claude/hooks/session-start-tts.sh +81 -81
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- 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/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +145 -145
- package/.claude/hooks/tts-queue.sh +165 -165
- package/.claude/hooks/verbosity-manager.sh +178 -178
- package/.claude/hooks/voice-manager.sh +548 -548
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/background-music-manager.ps1 +348 -0
- package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -0
- package/.claude/hooks-windows/download-extra-voices.ps1 +185 -0
- package/.claude/hooks-windows/effects-manager.ps1 +294 -0
- package/.claude/hooks-windows/language-manager.ps1 +193 -0
- package/.claude/hooks-windows/learn-manager.ps1 +241 -0
- package/.claude/hooks-windows/personality-manager.ps1 +266 -0
- package/.claude/hooks-windows/play-tts-piper.ps1 +209 -0
- package/.claude/hooks-windows/play-tts-sapi.ps1 +108 -0
- package/.claude/hooks-windows/play-tts-soprano.ps1 +159 -158
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +50 -5
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
- package/.claude/hooks-windows/play-tts.ps1 +344 -266
- package/.claude/hooks-windows/provider-manager.ps1 +29 -10
- package/.claude/hooks-windows/session-start-tts.ps1 +124 -124
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/speed-manager.ps1 +166 -0
- package/.claude/hooks-windows/verbosity-manager.ps1 +119 -0
- package/.claude/hooks-windows/voice-manager-windows.ps1 +92 -8
- package/.claude/output-styles/agent-vibes.md +202 -202
- package/.claude/personalities/angry.md +14 -14
- package/.claude/personalities/annoying.md +14 -14
- package/.claude/personalities/crass.md +14 -14
- package/.claude/personalities/dramatic.md +14 -14
- package/.claude/personalities/dry-humor.md +50 -50
- package/.claude/personalities/flirty.md +20 -20
- package/.claude/personalities/funny.md +14 -14
- package/.claude/personalities/grandpa.md +32 -32
- package/.claude/personalities/millennial.md +14 -14
- package/.claude/personalities/moody.md +14 -14
- package/.claude/personalities/normal.md +16 -16
- package/.claude/personalities/pirate.md +14 -14
- package/.claude/personalities/poetic.md +14 -14
- package/.claude/personalities/professional.md +14 -14
- package/.claude/personalities/rapper.md +55 -55
- package/.claude/personalities/robot.md +14 -14
- package/.claude/personalities/sarcastic.md +38 -38
- package/.claude/personalities/sassy.md +14 -14
- package/.claude/personalities/surfer-dude.md +14 -14
- package/.claude/personalities/zen.md +14 -14
- package/.claude/settings.json +15 -15
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.clawdbot/skill/SKILL.md +241 -241
- package/.mcp.json +12 -0
- package/CLAUDE.md +170 -170
- package/README.md +2029 -2007
- package/RELEASE_NOTES.md +1310 -1203
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/agentvibes-voice-browser.js +1840 -1840
- package/bin/agentvibes.js +48 -2
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +206 -206
- package/bin/test-bmad-pr +78 -78
- package/mcp-server/QUICK_START.md +203 -203
- package/mcp-server/README.md +345 -345
- package/mcp-server/WINDOWS_SETUP.md +260 -260
- package/mcp-server/docs/troubleshooting-audio.md +313 -313
- package/mcp-server/examples/claude_desktop_config.json +11 -11
- package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
- package/mcp-server/examples/custom_instructions.md +169 -169
- package/mcp-server/install-deps.js +130 -130
- package/mcp-server/pyproject.toml +52 -52
- package/mcp-server/requirements.txt +2 -2
- package/mcp-server/server.py +1465 -1453
- package/mcp-server/test_server.py +395 -395
- package/mcp-server/test_windows_script_parity.py +336 -0
- package/package.json +110 -110
- package/setup-windows.ps1 +815 -815
- package/src/bmad-detector.js +71 -71
- package/src/cli/list-personalities.js +110 -110
- package/src/cli/list-voices.js +114 -114
- package/src/commands/bmad-voices.js +394 -394
- package/src/commands/install-mcp.js +476 -476
- package/src/console/app.js +824 -824
- package/src/console/audio-env.js +20 -1
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/footer-config.js +50 -50
- package/src/console/modals/modal-overlay.js +247 -247
- package/src/console/navigation.js +62 -62
- package/src/console/tabs/agents-tab.js +1684 -1516
- package/src/console/tabs/help-tab.js +261 -261
- package/src/console/tabs/install-tab.js +1007 -991
- package/src/console/tabs/music-tab.js +22 -8
- package/src/console/tabs/placeholder-tab.js +53 -53
- package/src/console/tabs/readme-tab.js +267 -267
- package/src/console/tabs/receiver-tab.js +1472 -1212
- package/src/console/tabs/settings-tab.js +152 -79
- package/src/console/tabs/voices-tab.js +100 -21
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/format-utils.js +89 -89
- package/src/console/widgets/notice.js +55 -55
- package/src/console/widgets/personality-picker.js +185 -185
- package/src/console/widgets/reverb-picker.js +94 -94
- package/src/console/widgets/track-picker.js +285 -285
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +5882 -5829
- package/src/services/agent-voice-store.js +423 -423
- package/src/services/config-service.js +264 -264
- package/src/services/navigation-service.js +123 -123
- package/src/services/provider-service.js +132 -132
- package/src/services/verbosity-service.js +157 -157
- package/src/utils/audio-duration-validator.js +298 -298
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -466
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/list-formatter.js +194 -194
- package/src/utils/music-file-validator.js +285 -285
- package/src/utils/preview-list-prompt.js +136 -136
- package/src/utils/provider-validator.js +96 -12
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.sh +482 -482
- package/templates/audio/welcome-music.mp3 +0 -0
- package/voice-assignments.json +8244 -8244
- package/.claude/config/background-music-position.txt +0 -1
|
@@ -1,237 +1,237 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/translator.py
|
|
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 Text translator for multi-language TTS and learning mode
|
|
30
|
-
# @context Provides automatic translation using Google Translate via deep-translator library
|
|
31
|
-
# @architecture Standalone CLI module callable from bash scripts, with library mode for Python imports
|
|
32
|
-
# @dependencies deep-translator, langdetect (pip install deep-translator langdetect)
|
|
33
|
-
# @entrypoints CLI: python3 translator.py <text> <target_lang>, Library: from translator import translate
|
|
34
|
-
# @patterns Command pattern - supports translate, detect, and batch operations
|
|
35
|
-
# @related play-tts.sh, learn-manager.sh, language-manager.sh
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
"""
|
|
39
|
-
Text translation utilities for AgentVibes multi-language TTS.
|
|
40
|
-
|
|
41
|
-
Provides automatic translation of TTS text to the user's preferred language,
|
|
42
|
-
supporting both BMAD communication_language settings and learning mode.
|
|
43
|
-
|
|
44
|
-
Usage:
|
|
45
|
-
CLI: python3 translator.py <text> <target_language>
|
|
46
|
-
Library: from translator import translate, detect_language
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
import sys
|
|
50
|
-
import os
|
|
51
|
-
from typing import Optional, Tuple
|
|
52
|
-
|
|
53
|
-
# Language name to ISO code mapping
|
|
54
|
-
LANG_CODES = {
|
|
55
|
-
'spanish': 'es', 'español': 'es', 'es': 'es',
|
|
56
|
-
'french': 'fr', 'français': 'fr', 'fr': 'fr',
|
|
57
|
-
'german': 'de', 'deutsch': 'de', 'de': 'de',
|
|
58
|
-
'italian': 'it', 'italiano': 'it', 'it': 'it',
|
|
59
|
-
'portuguese': 'pt', 'português': 'pt', 'pt': 'pt',
|
|
60
|
-
'chinese': 'zh-CN', 'mandarin': 'zh-CN', 'zh': 'zh-CN', '中文': 'zh-CN',
|
|
61
|
-
'japanese': 'ja', '日本語': 'ja', 'ja': 'ja',
|
|
62
|
-
'korean': 'ko', '한국어': 'ko', 'ko': 'ko',
|
|
63
|
-
'russian': 'ru', 'русский': 'ru', 'ru': 'ru',
|
|
64
|
-
'polish': 'pl', 'polski': 'pl', 'pl': 'pl',
|
|
65
|
-
'dutch': 'nl', 'nederlands': 'nl', 'nl': 'nl',
|
|
66
|
-
'turkish': 'tr', 'türkçe': 'tr', 'tr': 'tr',
|
|
67
|
-
'arabic': 'ar', 'العربية': 'ar', 'ar': 'ar',
|
|
68
|
-
'hindi': 'hi', 'हिन्दी': 'hi', 'hi': 'hi',
|
|
69
|
-
'swedish': 'sv', 'svenska': 'sv', 'sv': 'sv',
|
|
70
|
-
'danish': 'da', 'dansk': 'da', 'da': 'da',
|
|
71
|
-
'norwegian': 'no', 'norsk': 'no', 'no': 'no',
|
|
72
|
-
'finnish': 'fi', 'suomi': 'fi', 'fi': 'fi',
|
|
73
|
-
'czech': 'cs', 'čeština': 'cs', 'cs': 'cs',
|
|
74
|
-
'romanian': 'ro', 'română': 'ro', 'ro': 'ro',
|
|
75
|
-
'ukrainian': 'uk', 'українська': 'uk', 'uk': 'uk',
|
|
76
|
-
'greek': 'el', 'ελληνικά': 'el', 'el': 'el',
|
|
77
|
-
'bulgarian': 'bg', 'български': 'bg', 'bg': 'bg',
|
|
78
|
-
'croatian': 'hr', 'hrvatski': 'hr', 'hr': 'hr',
|
|
79
|
-
'slovak': 'sk', 'slovenčina': 'sk', 'sk': 'sk',
|
|
80
|
-
'english': 'en', 'en': 'en',
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def get_lang_code(language: str) -> str:
|
|
85
|
-
"""
|
|
86
|
-
Convert language name to ISO code.
|
|
87
|
-
|
|
88
|
-
Args:
|
|
89
|
-
language: Language name or code (e.g., 'spanish', 'es', 'español')
|
|
90
|
-
|
|
91
|
-
Returns:
|
|
92
|
-
ISO language code (e.g., 'es')
|
|
93
|
-
"""
|
|
94
|
-
lang_lower = language.lower().strip()
|
|
95
|
-
return LANG_CODES.get(lang_lower, lang_lower)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def detect_language(text: str) -> Optional[str]:
|
|
99
|
-
"""
|
|
100
|
-
Detect the language of given text.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
text: Text to analyze
|
|
104
|
-
|
|
105
|
-
Returns:
|
|
106
|
-
Language code (e.g., 'es', 'fr', 'en') or None if detection fails
|
|
107
|
-
"""
|
|
108
|
-
if not text or len(text.strip()) < 3:
|
|
109
|
-
return None
|
|
110
|
-
|
|
111
|
-
try:
|
|
112
|
-
from langdetect import detect, LangDetectException
|
|
113
|
-
return detect(text)
|
|
114
|
-
except ImportError:
|
|
115
|
-
print("Warning: langdetect not installed. Run: pip install langdetect", file=sys.stderr)
|
|
116
|
-
return None
|
|
117
|
-
except Exception:
|
|
118
|
-
return None
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def translate(text: str, target_lang: str, source_lang: str = 'en') -> Tuple[str, bool]:
|
|
122
|
-
"""
|
|
123
|
-
Translate text to target language.
|
|
124
|
-
|
|
125
|
-
Args:
|
|
126
|
-
text: Text to translate
|
|
127
|
-
target_lang: Target language (name or code)
|
|
128
|
-
source_lang: Source language (default: 'en')
|
|
129
|
-
|
|
130
|
-
Returns:
|
|
131
|
-
Tuple of (translated_text, success)
|
|
132
|
-
"""
|
|
133
|
-
if not text or not text.strip():
|
|
134
|
-
return text, False
|
|
135
|
-
|
|
136
|
-
# Convert language names to codes
|
|
137
|
-
target_code = get_lang_code(target_lang)
|
|
138
|
-
source_code = get_lang_code(source_lang)
|
|
139
|
-
|
|
140
|
-
# Skip if source and target are the same
|
|
141
|
-
if target_code == source_code:
|
|
142
|
-
return text, False
|
|
143
|
-
|
|
144
|
-
# Skip if target is English and source is also English
|
|
145
|
-
if target_code == 'en' and source_code == 'en':
|
|
146
|
-
return text, False
|
|
147
|
-
|
|
148
|
-
try:
|
|
149
|
-
from deep_translator import GoogleTranslator
|
|
150
|
-
|
|
151
|
-
translator = GoogleTranslator(source=source_code, target=target_code)
|
|
152
|
-
translated = translator.translate(text)
|
|
153
|
-
|
|
154
|
-
if translated:
|
|
155
|
-
return translated, True
|
|
156
|
-
return text, False
|
|
157
|
-
|
|
158
|
-
except ImportError:
|
|
159
|
-
print("Error: deep-translator not installed. Run: pip install deep-translator", file=sys.stderr)
|
|
160
|
-
return text, False
|
|
161
|
-
except Exception as e:
|
|
162
|
-
print(f"Translation error: {e}", file=sys.stderr)
|
|
163
|
-
return text, False
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def translate_auto(text: str, target_lang: str) -> Tuple[str, bool, Optional[str]]:
|
|
167
|
-
"""
|
|
168
|
-
Translate text to target language with auto-detection of source language.
|
|
169
|
-
|
|
170
|
-
Args:
|
|
171
|
-
text: Text to translate
|
|
172
|
-
target_lang: Target language (name or code)
|
|
173
|
-
|
|
174
|
-
Returns:
|
|
175
|
-
Tuple of (translated_text, success, detected_source_lang)
|
|
176
|
-
"""
|
|
177
|
-
if not text or not text.strip():
|
|
178
|
-
return text, False, None
|
|
179
|
-
|
|
180
|
-
# Detect source language
|
|
181
|
-
detected = detect_language(text)
|
|
182
|
-
|
|
183
|
-
# Convert target to code
|
|
184
|
-
target_code = get_lang_code(target_lang)
|
|
185
|
-
|
|
186
|
-
# Skip if detected language matches target
|
|
187
|
-
if detected and detected == target_code:
|
|
188
|
-
return text, False, detected
|
|
189
|
-
|
|
190
|
-
# Translate
|
|
191
|
-
translated, success = translate(text, target_lang, source_lang=detected or 'en')
|
|
192
|
-
return translated, success, detected
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def main():
|
|
196
|
-
"""CLI entry point for translator."""
|
|
197
|
-
if len(sys.argv) < 3:
|
|
198
|
-
print("Usage: translator.py <text> <target_language> [source_language]", file=sys.stderr)
|
|
199
|
-
print(" translator.py detect <text>", file=sys.stderr)
|
|
200
|
-
print("", file=sys.stderr)
|
|
201
|
-
print("Examples:", file=sys.stderr)
|
|
202
|
-
print(" translator.py 'Hello world' spanish", file=sys.stderr)
|
|
203
|
-
print(" translator.py 'Hello world' es en", file=sys.stderr)
|
|
204
|
-
print(" translator.py detect 'Hola mundo'", file=sys.stderr)
|
|
205
|
-
sys.exit(1)
|
|
206
|
-
|
|
207
|
-
command = sys.argv[1]
|
|
208
|
-
|
|
209
|
-
# Detection mode
|
|
210
|
-
if command == 'detect':
|
|
211
|
-
if len(sys.argv) < 3:
|
|
212
|
-
print("Usage: translator.py detect <text>", file=sys.stderr)
|
|
213
|
-
sys.exit(1)
|
|
214
|
-
text = sys.argv[2]
|
|
215
|
-
detected = detect_language(text)
|
|
216
|
-
if detected:
|
|
217
|
-
print(detected)
|
|
218
|
-
else:
|
|
219
|
-
print("unknown")
|
|
220
|
-
sys.exit(0)
|
|
221
|
-
|
|
222
|
-
# Translation mode
|
|
223
|
-
text = sys.argv[1]
|
|
224
|
-
target_lang = sys.argv[2]
|
|
225
|
-
source_lang = sys.argv[3] if len(sys.argv) > 3 else 'en'
|
|
226
|
-
|
|
227
|
-
translated, success = translate(text, target_lang, source_lang)
|
|
228
|
-
|
|
229
|
-
# Output the result (for shell script consumption)
|
|
230
|
-
print(translated)
|
|
231
|
-
|
|
232
|
-
# Exit with appropriate code
|
|
233
|
-
sys.exit(0 if success else 1)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if __name__ == '__main__':
|
|
237
|
-
main()
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/translator.py
|
|
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 Text translator for multi-language TTS and learning mode
|
|
30
|
+
# @context Provides automatic translation using Google Translate via deep-translator library
|
|
31
|
+
# @architecture Standalone CLI module callable from bash scripts, with library mode for Python imports
|
|
32
|
+
# @dependencies deep-translator, langdetect (pip install deep-translator langdetect)
|
|
33
|
+
# @entrypoints CLI: python3 translator.py <text> <target_lang>, Library: from translator import translate
|
|
34
|
+
# @patterns Command pattern - supports translate, detect, and batch operations
|
|
35
|
+
# @related play-tts.sh, learn-manager.sh, language-manager.sh
|
|
36
|
+
#
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
Text translation utilities for AgentVibes multi-language TTS.
|
|
40
|
+
|
|
41
|
+
Provides automatic translation of TTS text to the user's preferred language,
|
|
42
|
+
supporting both BMAD communication_language settings and learning mode.
|
|
43
|
+
|
|
44
|
+
Usage:
|
|
45
|
+
CLI: python3 translator.py <text> <target_language>
|
|
46
|
+
Library: from translator import translate, detect_language
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
import sys
|
|
50
|
+
import os
|
|
51
|
+
from typing import Optional, Tuple
|
|
52
|
+
|
|
53
|
+
# Language name to ISO code mapping
|
|
54
|
+
LANG_CODES = {
|
|
55
|
+
'spanish': 'es', 'español': 'es', 'es': 'es',
|
|
56
|
+
'french': 'fr', 'français': 'fr', 'fr': 'fr',
|
|
57
|
+
'german': 'de', 'deutsch': 'de', 'de': 'de',
|
|
58
|
+
'italian': 'it', 'italiano': 'it', 'it': 'it',
|
|
59
|
+
'portuguese': 'pt', 'português': 'pt', 'pt': 'pt',
|
|
60
|
+
'chinese': 'zh-CN', 'mandarin': 'zh-CN', 'zh': 'zh-CN', '中文': 'zh-CN',
|
|
61
|
+
'japanese': 'ja', '日本語': 'ja', 'ja': 'ja',
|
|
62
|
+
'korean': 'ko', '한국어': 'ko', 'ko': 'ko',
|
|
63
|
+
'russian': 'ru', 'русский': 'ru', 'ru': 'ru',
|
|
64
|
+
'polish': 'pl', 'polski': 'pl', 'pl': 'pl',
|
|
65
|
+
'dutch': 'nl', 'nederlands': 'nl', 'nl': 'nl',
|
|
66
|
+
'turkish': 'tr', 'türkçe': 'tr', 'tr': 'tr',
|
|
67
|
+
'arabic': 'ar', 'العربية': 'ar', 'ar': 'ar',
|
|
68
|
+
'hindi': 'hi', 'हिन्दी': 'hi', 'hi': 'hi',
|
|
69
|
+
'swedish': 'sv', 'svenska': 'sv', 'sv': 'sv',
|
|
70
|
+
'danish': 'da', 'dansk': 'da', 'da': 'da',
|
|
71
|
+
'norwegian': 'no', 'norsk': 'no', 'no': 'no',
|
|
72
|
+
'finnish': 'fi', 'suomi': 'fi', 'fi': 'fi',
|
|
73
|
+
'czech': 'cs', 'čeština': 'cs', 'cs': 'cs',
|
|
74
|
+
'romanian': 'ro', 'română': 'ro', 'ro': 'ro',
|
|
75
|
+
'ukrainian': 'uk', 'українська': 'uk', 'uk': 'uk',
|
|
76
|
+
'greek': 'el', 'ελληνικά': 'el', 'el': 'el',
|
|
77
|
+
'bulgarian': 'bg', 'български': 'bg', 'bg': 'bg',
|
|
78
|
+
'croatian': 'hr', 'hrvatski': 'hr', 'hr': 'hr',
|
|
79
|
+
'slovak': 'sk', 'slovenčina': 'sk', 'sk': 'sk',
|
|
80
|
+
'english': 'en', 'en': 'en',
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_lang_code(language: str) -> str:
|
|
85
|
+
"""
|
|
86
|
+
Convert language name to ISO code.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
language: Language name or code (e.g., 'spanish', 'es', 'español')
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
ISO language code (e.g., 'es')
|
|
93
|
+
"""
|
|
94
|
+
lang_lower = language.lower().strip()
|
|
95
|
+
return LANG_CODES.get(lang_lower, lang_lower)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def detect_language(text: str) -> Optional[str]:
|
|
99
|
+
"""
|
|
100
|
+
Detect the language of given text.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
text: Text to analyze
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Language code (e.g., 'es', 'fr', 'en') or None if detection fails
|
|
107
|
+
"""
|
|
108
|
+
if not text or len(text.strip()) < 3:
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
from langdetect import detect, LangDetectException
|
|
113
|
+
return detect(text)
|
|
114
|
+
except ImportError:
|
|
115
|
+
print("Warning: langdetect not installed. Run: pip install langdetect", file=sys.stderr)
|
|
116
|
+
return None
|
|
117
|
+
except Exception:
|
|
118
|
+
return None
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def translate(text: str, target_lang: str, source_lang: str = 'en') -> Tuple[str, bool]:
|
|
122
|
+
"""
|
|
123
|
+
Translate text to target language.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
text: Text to translate
|
|
127
|
+
target_lang: Target language (name or code)
|
|
128
|
+
source_lang: Source language (default: 'en')
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Tuple of (translated_text, success)
|
|
132
|
+
"""
|
|
133
|
+
if not text or not text.strip():
|
|
134
|
+
return text, False
|
|
135
|
+
|
|
136
|
+
# Convert language names to codes
|
|
137
|
+
target_code = get_lang_code(target_lang)
|
|
138
|
+
source_code = get_lang_code(source_lang)
|
|
139
|
+
|
|
140
|
+
# Skip if source and target are the same
|
|
141
|
+
if target_code == source_code:
|
|
142
|
+
return text, False
|
|
143
|
+
|
|
144
|
+
# Skip if target is English and source is also English
|
|
145
|
+
if target_code == 'en' and source_code == 'en':
|
|
146
|
+
return text, False
|
|
147
|
+
|
|
148
|
+
try:
|
|
149
|
+
from deep_translator import GoogleTranslator
|
|
150
|
+
|
|
151
|
+
translator = GoogleTranslator(source=source_code, target=target_code)
|
|
152
|
+
translated = translator.translate(text)
|
|
153
|
+
|
|
154
|
+
if translated:
|
|
155
|
+
return translated, True
|
|
156
|
+
return text, False
|
|
157
|
+
|
|
158
|
+
except ImportError:
|
|
159
|
+
print("Error: deep-translator not installed. Run: pip install deep-translator", file=sys.stderr)
|
|
160
|
+
return text, False
|
|
161
|
+
except Exception as e:
|
|
162
|
+
print(f"Translation error: {e}", file=sys.stderr)
|
|
163
|
+
return text, False
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def translate_auto(text: str, target_lang: str) -> Tuple[str, bool, Optional[str]]:
|
|
167
|
+
"""
|
|
168
|
+
Translate text to target language with auto-detection of source language.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
text: Text to translate
|
|
172
|
+
target_lang: Target language (name or code)
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Tuple of (translated_text, success, detected_source_lang)
|
|
176
|
+
"""
|
|
177
|
+
if not text or not text.strip():
|
|
178
|
+
return text, False, None
|
|
179
|
+
|
|
180
|
+
# Detect source language
|
|
181
|
+
detected = detect_language(text)
|
|
182
|
+
|
|
183
|
+
# Convert target to code
|
|
184
|
+
target_code = get_lang_code(target_lang)
|
|
185
|
+
|
|
186
|
+
# Skip if detected language matches target
|
|
187
|
+
if detected and detected == target_code:
|
|
188
|
+
return text, False, detected
|
|
189
|
+
|
|
190
|
+
# Translate
|
|
191
|
+
translated, success = translate(text, target_lang, source_lang=detected or 'en')
|
|
192
|
+
return translated, success, detected
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def main():
|
|
196
|
+
"""CLI entry point for translator."""
|
|
197
|
+
if len(sys.argv) < 3:
|
|
198
|
+
print("Usage: translator.py <text> <target_language> [source_language]", file=sys.stderr)
|
|
199
|
+
print(" translator.py detect <text>", file=sys.stderr)
|
|
200
|
+
print("", file=sys.stderr)
|
|
201
|
+
print("Examples:", file=sys.stderr)
|
|
202
|
+
print(" translator.py 'Hello world' spanish", file=sys.stderr)
|
|
203
|
+
print(" translator.py 'Hello world' es en", file=sys.stderr)
|
|
204
|
+
print(" translator.py detect 'Hola mundo'", file=sys.stderr)
|
|
205
|
+
sys.exit(1)
|
|
206
|
+
|
|
207
|
+
command = sys.argv[1]
|
|
208
|
+
|
|
209
|
+
# Detection mode
|
|
210
|
+
if command == 'detect':
|
|
211
|
+
if len(sys.argv) < 3:
|
|
212
|
+
print("Usage: translator.py detect <text>", file=sys.stderr)
|
|
213
|
+
sys.exit(1)
|
|
214
|
+
text = sys.argv[2]
|
|
215
|
+
detected = detect_language(text)
|
|
216
|
+
if detected:
|
|
217
|
+
print(detected)
|
|
218
|
+
else:
|
|
219
|
+
print("unknown")
|
|
220
|
+
sys.exit(0)
|
|
221
|
+
|
|
222
|
+
# Translation mode
|
|
223
|
+
text = sys.argv[1]
|
|
224
|
+
target_lang = sys.argv[2]
|
|
225
|
+
source_lang = sys.argv[3] if len(sys.argv) > 3 else 'en'
|
|
226
|
+
|
|
227
|
+
translated, success = translate(text, target_lang, source_lang)
|
|
228
|
+
|
|
229
|
+
# Output the result (for shell script consumption)
|
|
230
|
+
print(translated)
|
|
231
|
+
|
|
232
|
+
# Exit with appropriate code
|
|
233
|
+
sys.exit(0 if success else 1)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
if __name__ == '__main__':
|
|
237
|
+
main()
|