agentvibes 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/.agentvibes/bmad/bmad-voices.md +69 -69
  2. package/.agentvibes/config.json +12 -0
  3. package/.claude/activation-instructions +54 -54
  4. package/.claude/audio/tracks/README.md +52 -52
  5. package/.claude/commands/agent-vibes/add.md +21 -21
  6. package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
  7. package/.claude/commands/agent-vibes/agent.md +79 -79
  8. package/.claude/commands/agent-vibes/background-music.md +111 -111
  9. package/.claude/commands/agent-vibes/bmad.md +198 -198
  10. package/.claude/commands/agent-vibes/clean.md +18 -18
  11. package/.claude/commands/agent-vibes/cleanup.md +18 -18
  12. package/.claude/commands/agent-vibes/commands.json +145 -145
  13. package/.claude/commands/agent-vibes/effects.md +97 -97
  14. package/.claude/commands/agent-vibes/get.md +9 -9
  15. package/.claude/commands/agent-vibes/hide.md +91 -91
  16. package/.claude/commands/agent-vibes/language.md +23 -23
  17. package/.claude/commands/agent-vibes/learn.md +67 -67
  18. package/.claude/commands/agent-vibes/list.md +13 -13
  19. package/.claude/commands/agent-vibes/mute.md +37 -37
  20. package/.claude/commands/agent-vibes/preview.md +17 -17
  21. package/.claude/commands/agent-vibes/provider.md +68 -68
  22. package/.claude/commands/agent-vibes/replay-target.md +14 -14
  23. package/.claude/commands/agent-vibes/sample.md +12 -12
  24. package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
  25. package/.claude/commands/agent-vibes/set-pretext.md +65 -65
  26. package/.claude/commands/agent-vibes/set-speed.md +41 -41
  27. package/.claude/commands/agent-vibes/show.md +84 -84
  28. package/.claude/commands/agent-vibes/switch.md +87 -87
  29. package/.claude/commands/agent-vibes/target-voice.md +26 -26
  30. package/.claude/commands/agent-vibes/target.md +30 -30
  31. package/.claude/commands/agent-vibes/translate.md +68 -68
  32. package/.claude/commands/agent-vibes/unmute.md +45 -45
  33. package/.claude/commands/agent-vibes/verbosity.md +89 -89
  34. package/.claude/commands/agent-vibes/whoami.md +7 -7
  35. package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
  36. package/.claude/commands/agent-vibes-rdp.md +24 -24
  37. package/.claude/config/agentvibes.json +1 -0
  38. package/.claude/config/audio-effects.cfg +2 -2
  39. package/.claude/config/audio-effects.cfg.sample +52 -52
  40. package/.claude/config/background-music-volume.txt +1 -0
  41. package/.claude/config/intro-text.txt +1 -0
  42. package/.claude/config/piper-speech-rate.txt +4 -0
  43. package/.claude/config/piper-target-speech-rate.txt +1 -0
  44. package/.claude/config/reverb-level.txt +1 -0
  45. package/.claude/config/tts-speech-rate.txt +4 -0
  46. package/.claude/config/tts-target-speech-rate.txt +1 -0
  47. package/.claude/docs/TERMUX_SETUP.md +408 -408
  48. package/.claude/github-star-reminder.txt +1 -1
  49. package/.claude/hooks/README-TTS-QUEUE.md +135 -135
  50. package/.claude/hooks/audio-cache-utils.sh +246 -246
  51. package/.claude/hooks/audio-processor.sh +433 -433
  52. package/.claude/hooks/background-music-manager.sh +404 -404
  53. package/.claude/hooks/bmad-speak-enhanced.sh +165 -165
  54. package/.claude/hooks/bmad-speak.sh +269 -269
  55. package/.claude/hooks/bmad-tts-injector.sh +568 -568
  56. package/.claude/hooks/bmad-voice-manager.sh +928 -928
  57. package/.claude/hooks/clawdbot-receiver-SECURE.sh +129 -129
  58. package/.claude/hooks/clawdbot-receiver.sh +107 -107
  59. package/.claude/hooks/clean-audio-cache.sh +22 -22
  60. package/.claude/hooks/cleanup-cache.sh +106 -106
  61. package/.claude/hooks/configure-rdp-mode.sh +137 -137
  62. package/.claude/hooks/download-extra-voices.sh +244 -244
  63. package/.claude/hooks/effects-manager.sh +268 -268
  64. package/.claude/hooks/github-star-reminder.sh +154 -154
  65. package/.claude/hooks/language-manager.sh +362 -362
  66. package/.claude/hooks/learn-manager.sh +492 -492
  67. package/.claude/hooks/macos-voice-manager.sh +205 -205
  68. package/.claude/hooks/migrate-background-music.sh +125 -125
  69. package/.claude/hooks/migrate-to-agentvibes.sh +161 -161
  70. package/.claude/hooks/optimize-background-music.sh +87 -87
  71. package/.claude/hooks/path-resolver.sh +60 -60
  72. package/.claude/hooks/personality-manager.sh +448 -448
  73. package/.claude/hooks/piper-download-voices.sh +225 -225
  74. package/.claude/hooks/piper-installer.sh +292 -292
  75. package/.claude/hooks/piper-multispeaker-registry.sh +171 -171
  76. package/.claude/hooks/piper-voice-manager.sh +24 -3
  77. package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +90 -90
  78. package/.claude/hooks/play-tts-enhanced.sh +105 -105
  79. package/.claude/hooks/play-tts-macos.sh +368 -368
  80. package/.claude/hooks/play-tts-piper.sh +679 -679
  81. package/.claude/hooks/play-tts-soprano.sh +356 -356
  82. package/.claude/hooks/play-tts-ssh-remote.sh +167 -167
  83. package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
  84. package/.claude/hooks/play-tts.sh +301 -301
  85. package/.claude/hooks/prepare-release.sh +54 -54
  86. package/.claude/hooks/provider-commands.sh +617 -617
  87. package/.claude/hooks/provider-manager.sh +399 -399
  88. package/.claude/hooks/replay-target-audio.sh +95 -95
  89. package/.claude/hooks/requirements.txt +6 -6
  90. package/.claude/hooks/sentiment-manager.sh +201 -201
  91. package/.claude/hooks/session-start-tts.sh +81 -81
  92. package/.claude/hooks/soprano-gradio-synth.py +139 -139
  93. package/.claude/hooks/speed-manager.sh +291 -291
  94. package/.claude/hooks/stop-tts.sh +84 -84
  95. package/.claude/hooks/termux-installer.sh +261 -261
  96. package/.claude/hooks/translate-manager.sh +341 -341
  97. package/.claude/hooks/translator.py +237 -237
  98. package/.claude/hooks/tts-queue-worker.sh +145 -145
  99. package/.claude/hooks/tts-queue.sh +165 -165
  100. package/.claude/hooks/verbosity-manager.sh +178 -178
  101. package/.claude/hooks/voice-manager.sh +548 -548
  102. package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
  103. package/.claude/hooks-windows/background-music-manager.ps1 +348 -0
  104. package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -0
  105. package/.claude/hooks-windows/download-extra-voices.ps1 +185 -0
  106. package/.claude/hooks-windows/effects-manager.ps1 +294 -0
  107. package/.claude/hooks-windows/language-manager.ps1 +193 -0
  108. package/.claude/hooks-windows/learn-manager.ps1 +241 -0
  109. package/.claude/hooks-windows/personality-manager.ps1 +266 -0
  110. package/.claude/hooks-windows/play-tts-piper.ps1 +209 -0
  111. package/.claude/hooks-windows/play-tts-sapi.ps1 +108 -0
  112. package/.claude/hooks-windows/play-tts-soprano.ps1 +159 -158
  113. package/.claude/hooks-windows/play-tts-windows-piper.ps1 +50 -5
  114. package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -108
  115. package/.claude/hooks-windows/play-tts.ps1 +344 -266
  116. package/.claude/hooks-windows/provider-manager.ps1 +29 -10
  117. package/.claude/hooks-windows/session-start-tts.ps1 +124 -124
  118. package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
  119. package/.claude/hooks-windows/speed-manager.ps1 +166 -0
  120. package/.claude/hooks-windows/verbosity-manager.ps1 +119 -0
  121. package/.claude/hooks-windows/voice-manager-windows.ps1 +92 -8
  122. package/.claude/output-styles/agent-vibes.md +202 -202
  123. package/.claude/personalities/angry.md +14 -14
  124. package/.claude/personalities/annoying.md +14 -14
  125. package/.claude/personalities/crass.md +14 -14
  126. package/.claude/personalities/dramatic.md +14 -14
  127. package/.claude/personalities/dry-humor.md +50 -50
  128. package/.claude/personalities/flirty.md +20 -20
  129. package/.claude/personalities/funny.md +14 -14
  130. package/.claude/personalities/grandpa.md +32 -32
  131. package/.claude/personalities/millennial.md +14 -14
  132. package/.claude/personalities/moody.md +14 -14
  133. package/.claude/personalities/normal.md +16 -16
  134. package/.claude/personalities/pirate.md +14 -14
  135. package/.claude/personalities/poetic.md +14 -14
  136. package/.claude/personalities/professional.md +14 -14
  137. package/.claude/personalities/rapper.md +55 -55
  138. package/.claude/personalities/robot.md +14 -14
  139. package/.claude/personalities/sarcastic.md +38 -38
  140. package/.claude/personalities/sassy.md +14 -14
  141. package/.claude/personalities/surfer-dude.md +14 -14
  142. package/.claude/personalities/zen.md +14 -14
  143. package/.claude/settings.json +15 -15
  144. package/.claude/verbosity.txt +1 -1
  145. package/.clawdbot/README.md +105 -105
  146. package/.clawdbot/skill/SKILL.md +241 -241
  147. package/.mcp.json +12 -0
  148. package/CLAUDE.md +170 -170
  149. package/README.md +2029 -2007
  150. package/RELEASE_NOTES.md +1310 -1203
  151. package/WINDOWS-SETUP.md +208 -208
  152. package/bin/agent-vibes +39 -39
  153. package/bin/agentvibes-voice-browser.js +1840 -1840
  154. package/bin/agentvibes.js +48 -2
  155. package/bin/mcp-server.js +121 -121
  156. package/bin/mcp-server.sh +206 -206
  157. package/bin/test-bmad-pr +78 -78
  158. package/mcp-server/QUICK_START.md +203 -203
  159. package/mcp-server/README.md +345 -345
  160. package/mcp-server/WINDOWS_SETUP.md +260 -260
  161. package/mcp-server/docs/troubleshooting-audio.md +313 -313
  162. package/mcp-server/examples/claude_desktop_config.json +11 -11
  163. package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
  164. package/mcp-server/examples/custom_instructions.md +169 -169
  165. package/mcp-server/install-deps.js +130 -130
  166. package/mcp-server/pyproject.toml +52 -52
  167. package/mcp-server/requirements.txt +2 -2
  168. package/mcp-server/server.py +1465 -1453
  169. package/mcp-server/test_server.py +395 -395
  170. package/mcp-server/test_windows_script_parity.py +336 -0
  171. package/package.json +110 -110
  172. package/setup-windows.ps1 +815 -815
  173. package/src/bmad-detector.js +71 -71
  174. package/src/cli/list-personalities.js +110 -110
  175. package/src/cli/list-voices.js +114 -114
  176. package/src/commands/bmad-voices.js +394 -394
  177. package/src/commands/install-mcp.js +476 -476
  178. package/src/console/app.js +824 -824
  179. package/src/console/audio-env.js +20 -1
  180. package/src/console/brand-colors.js +13 -13
  181. package/src/console/constants/personalities.js +44 -44
  182. package/src/console/footer-config.js +50 -50
  183. package/src/console/modals/modal-overlay.js +247 -247
  184. package/src/console/navigation.js +62 -62
  185. package/src/console/tabs/agents-tab.js +1684 -1516
  186. package/src/console/tabs/help-tab.js +261 -261
  187. package/src/console/tabs/install-tab.js +1007 -991
  188. package/src/console/tabs/music-tab.js +22 -8
  189. package/src/console/tabs/placeholder-tab.js +53 -53
  190. package/src/console/tabs/readme-tab.js +267 -267
  191. package/src/console/tabs/receiver-tab.js +1472 -1212
  192. package/src/console/tabs/settings-tab.js +152 -79
  193. package/src/console/tabs/voices-tab.js +100 -21
  194. package/src/console/widgets/destroy-list.js +25 -25
  195. package/src/console/widgets/format-utils.js +89 -89
  196. package/src/console/widgets/notice.js +55 -55
  197. package/src/console/widgets/personality-picker.js +185 -185
  198. package/src/console/widgets/reverb-picker.js +94 -94
  199. package/src/console/widgets/track-picker.js +285 -285
  200. package/src/installer/music-file-input.js +304 -304
  201. package/src/installer.js +5882 -5829
  202. package/src/services/agent-voice-store.js +423 -423
  203. package/src/services/config-service.js +264 -264
  204. package/src/services/navigation-service.js +123 -123
  205. package/src/services/provider-service.js +132 -132
  206. package/src/services/verbosity-service.js +157 -157
  207. package/src/utils/audio-duration-validator.js +298 -298
  208. package/src/utils/audio-format-validator.js +277 -277
  209. package/src/utils/dependency-checker.js +469 -466
  210. package/src/utils/file-ownership-verifier.js +358 -358
  211. package/src/utils/list-formatter.js +194 -194
  212. package/src/utils/music-file-validator.js +285 -285
  213. package/src/utils/preview-list-prompt.js +136 -136
  214. package/src/utils/provider-validator.js +96 -12
  215. package/src/utils/secure-music-storage.js +412 -412
  216. package/templates/agentvibes-receiver.sh +482 -482
  217. package/templates/audio/welcome-music.mp3 +0 -0
  218. package/voice-assignments.json +8244 -8244
  219. package/.claude/config/background-music-position.txt +0 -1
@@ -1,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()