agentvibes 5.13.1 → 5.15.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 (84) hide show
  1. package/.claude/audio/ui/CREDITS.txt +16 -16
  2. package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
  3. package/.claude/commands/agent-vibes-rdp.md +24 -24
  4. package/.claude/config/audio-effects.cfg.sample +52 -52
  5. package/.claude/docs/TERMUX_SETUP.md +408 -408
  6. package/.claude/github-star-reminder.txt +1 -1
  7. package/.claude/hooks/kokoro-server.py +219 -219
  8. package/.claude/hooks/kokoro-tts.py +141 -141
  9. package/.claude/hooks/party-stage-roster.py +328 -328
  10. package/.claude/hooks/play-tts-kokoro.sh +7 -2
  11. package/.claude/hooks/play-tts-ssh-remote.sh +38 -3
  12. package/.claude/hooks/requirements.txt +6 -6
  13. package/.claude/hooks/soprano-gradio-synth.py +139 -139
  14. package/.claude/hooks/translator.py +237 -237
  15. package/.claude/hooks-windows/agentvibes-session-id.ps1 +83 -0
  16. package/.claude/hooks-windows/kokoro-server.py +219 -219
  17. package/.claude/hooks-windows/kokoro-tts.py +107 -107
  18. package/.claude/hooks-windows/play-tts.ps1 +112 -1
  19. package/.claude/hooks-windows/session-start-tts.ps1 +36 -0
  20. package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
  21. package/.claude/verbosity.txt +1 -1
  22. package/.clawdbot/README.md +105 -105
  23. package/CLAUDE.md +84 -176
  24. package/README.md +35 -2
  25. package/RELEASE_NOTES.md +139 -0
  26. package/WINDOWS-SETUP.md +208 -208
  27. package/bin/agent-vibes +39 -39
  28. package/bin/mcp-server.js +121 -121
  29. package/bin/test-bmad-pr +78 -78
  30. package/mcp-server/QUICK_START.md +203 -203
  31. package/mcp-server/README.md +345 -345
  32. package/mcp-server/examples/claude_desktop_config.json +11 -11
  33. package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
  34. package/mcp-server/examples/custom_instructions.md +169 -169
  35. package/mcp-server/install-deps.js +12 -2
  36. package/mcp-server/server.py +2111 -2085
  37. package/mcp-server/test_mcp_correctness.py +504 -504
  38. package/mcp-server/test_windows_script_parity.py +339 -339
  39. package/package.json +6 -3
  40. package/setup-ssh-receiver.ps1 +259 -0
  41. package/setup-windows.ps1 +39 -29
  42. package/src/cli/list-personalities.js +110 -110
  43. package/src/commands/bmad-voices.js +394 -394
  44. package/src/console/brand-colors.js +13 -13
  45. package/src/console/constants/personalities.js +44 -44
  46. package/src/console/tabs/agents-tab.js +14 -4
  47. package/src/console/tabs/help-tab.js +314 -314
  48. package/src/console/tabs/readme-tab.js +272 -272
  49. package/src/console/tabs/settings-tab.js +31 -6
  50. package/src/console/tabs/setup-tab.js +154 -32
  51. package/src/console/tabs/voices-tab.js +48 -6
  52. package/src/console/widgets/destroy-list.js +25 -25
  53. package/src/console/widgets/notice.js +55 -55
  54. package/src/installer/language-screen.js +31 -31
  55. package/src/installer/music-file-input.js +304 -304
  56. package/src/installer.js +98 -37
  57. package/src/services/language-service.js +47 -47
  58. package/src/services/llm-provider-service.js +4 -1
  59. package/src/services/provider-voice-catalog.js +9 -5
  60. package/src/utils/audio-format-validator.js +277 -277
  61. package/src/utils/dependency-checker.js +469 -469
  62. package/src/utils/file-ownership-verifier.js +358 -358
  63. package/src/utils/music-file-validator.js +285 -285
  64. package/src/utils/preview-list-prompt.js +144 -144
  65. package/src/utils/secure-music-storage.js +412 -412
  66. package/templates/agentvibes-receiver.ps1 +311 -0
  67. package/templates/agentvibes-receiver.sh +297 -297
  68. package/voice-assignments.json +8244 -8244
  69. package/.agentvibes/config.json +0 -17
  70. package/.agentvibes/install-manifest.json +0 -362
  71. package/.claude/config/audio-effects.cfg +0 -7
  72. package/.claude/config/audio-effects.cfg.bak-kokoro +0 -7
  73. package/.claude/config/background-music-enabled.txt +0 -1
  74. package/.claude/config/background-music-position.txt +0 -27
  75. package/.claude/config/background-music-volume.txt +0 -1
  76. package/.claude/config/background-music.cfg +0 -1
  77. package/.claude/config/background-music.txt +0 -1
  78. package/.claude/config/language.txt +0 -1
  79. package/.claude/config/personality.txt +0 -1
  80. package/.claude/config/reverb-level.txt +0 -1
  81. package/.claude/config/tts-speech-rate.txt +0 -1
  82. package/.claude/config/tts-verbosity.txt +0 -1
  83. package/.claude/hooks-windows/audio-cache-utils.ps1.user.bak +0 -119
  84. package/.claude/hooks-windows/soprano-gradio-synth.py.user.bak +0 -153
@@ -1,141 +1,141 @@
1
- #!/usr/bin/env python3
2
- """
3
- AgentVibes — Kokoro TTS synthesizer
4
- Synthesizes text to a WAV file using the kokoro-onnx package.
5
- Prints the output WAV path to stdout.
6
-
7
- Usage: kokoro-tts.py <text> <voice> <output_path> [speed]
8
-
9
- Voices (examples):
10
- af_heart af_nova af_sky af_bella af_sarah af_nicole
11
- am_adam am_michael
12
- bf_emma bf_isabella
13
- bm_george bm_lewis
14
-
15
- Install: pip install kokoro-onnx soundfile numpy
16
- """
17
-
18
- import sys
19
- import os
20
- import re
21
-
22
- # Kokoro/torch auto-selects CUDA whenever a GPU is visible, but many setups
23
- # (notably Windows) fail GPU allocation with "CUDA error: unknown error /
24
- # Memory allocation failure", which crashes synthesis after a long torch load.
25
- # The 82M-param Kokoro model runs fine on CPU in a few seconds, so force CPU by
26
- # default. Opt back into GPU with AGENTVIBES_KOKORO_DEVICE=cuda. This MUST run
27
- # before torch/kokoro are imported so torch.cuda.is_available() sees no device.
28
- _KOKORO_DEVICE = os.environ.get('AGENTVIBES_KOKORO_DEVICE', 'cpu').strip().lower()
29
- if _KOKORO_DEVICE != 'cuda':
30
- os.environ['CUDA_VISIBLE_DEVICES'] = ''
31
-
32
- def main():
33
- # --download-only: fetch voice .pt file from HuggingFace without synthesis
34
- if len(sys.argv) >= 2 and sys.argv[1] == '--download-only':
35
- voice = sys.argv[2] if len(sys.argv) > 2 else 'af_heart'
36
- # Validate before the id flows into a HuggingFace filename — blocks path
37
- # traversal / arbitrary repo paths in voices/<voice>.pt.
38
- if not re.match(r'^[a-z]{2}_[a-z0-9_]+$', voice):
39
- print(f"❌ Invalid voice id: {voice}", file=sys.stderr)
40
- sys.exit(4)
41
- try:
42
- from huggingface_hub import hf_hub_download
43
- local = hf_hub_download(repo_id='hexgrad/Kokoro-82M', filename=f'voices/{voice}.pt')
44
- print(local)
45
- except Exception as e:
46
- print(f"❌ Download failed: {e}", file=sys.stderr)
47
- sys.exit(4)
48
- sys.exit(0)
49
-
50
- if len(sys.argv) < 4:
51
- print("Usage: kokoro-tts.py <text> <voice> <output_path> [speed]", file=sys.stderr)
52
- sys.exit(1)
53
-
54
- text = sys.argv[1]
55
- voice = sys.argv[2]
56
- output_path = sys.argv[3]
57
- try:
58
- speed = float(sys.argv[4]) if len(sys.argv) > 4 else 1.0
59
- except ValueError:
60
- speed = 1.0
61
-
62
- # Determine language code from voice prefix
63
- # af/am = American English ('a'), bf/bm = British English ('b')
64
- # jf/jm = Japanese ('j'), kf/km = Korean ('k'), etc.
65
- prefix = voice[:2].lower() if len(voice) >= 2 else 'af'
66
- lang_map = {
67
- 'af': 'a', 'am': 'a', # American English
68
- 'bf': 'b', 'bm': 'b', # British English
69
- 'jf': 'j', 'jm': 'j', # Japanese
70
- 'kf': 'k', 'km': 'k', # Korean
71
- 'zf': 'z', 'zm': 'z', # Mandarin
72
- 'ff': 'f', 'fm': 'f', # French
73
- 'hf': 'h', 'hm': 'h', # Hindi
74
- 'if': 'i', 'im': 'i', # Italian
75
- 'pf': 'p', 'pm': 'p', # Brazilian Portuguese
76
- 'ef': 'e', 'em': 'e', # Spanish (Spain)
77
- 'nf': 'n', 'nm': 'n', # Spanish (Latin America)
78
- }
79
- lang_code = lang_map.get(prefix, 'a')
80
-
81
- try:
82
- from kokoro import KPipeline
83
- except ImportError:
84
- print("❌ kokoro-onnx not installed. Run: pip install kokoro-onnx soundfile numpy", file=sys.stderr)
85
- sys.exit(2)
86
-
87
- try:
88
- import numpy as np
89
- import soundfile as sf
90
- except ImportError:
91
- print("❌ soundfile/numpy not installed. Run: pip install soundfile numpy", file=sys.stderr)
92
- sys.exit(2)
93
-
94
- try:
95
- # Pass device explicitly when supported; fall back for older kokoro
96
- # versions whose KPipeline has no `device` kwarg (CUDA_VISIBLE_DEVICES
97
- # already forces CPU in that case).
98
- try:
99
- pipeline = KPipeline(lang_code=lang_code, device=_KOKORO_DEVICE if _KOKORO_DEVICE == 'cuda' else 'cpu')
100
- except TypeError:
101
- pipeline = KPipeline(lang_code=lang_code)
102
- generator = pipeline(text, voice=voice, speed=speed)
103
-
104
- all_samples = []
105
- sample_rate = 24000 # kokoro always outputs 24 kHz
106
-
107
- for result in generator:
108
- # kokoro >=0.9 yields a KPipeline.Result whose waveform is the
109
- # `.audio` attribute (a torch.Tensor); older builds yield a
110
- # (graphemes, phonemes, audio) tuple. Prefer `.audio`, then fall
111
- # back to the last tuple element.
112
- audio = getattr(result, "audio", None)
113
- if audio is None:
114
- try:
115
- audio = result[-1]
116
- except (TypeError, IndexError, KeyError):
117
- audio = None
118
- if audio is None:
119
- continue
120
- # Tensor -> numpy, force 1-D so np.concatenate never sees a 0-d array
121
- if hasattr(audio, "detach"):
122
- audio = audio.detach().cpu().numpy()
123
- audio = np.asarray(audio).reshape(-1)
124
- if audio.size > 0:
125
- all_samples.append(audio)
126
-
127
- if not all_samples:
128
- print("❌ Kokoro returned no audio samples", file=sys.stderr)
129
- sys.exit(3)
130
-
131
- combined = np.concatenate(all_samples)
132
- sf.write(output_path, combined, sample_rate)
133
- print(output_path)
134
-
135
- except Exception as e:
136
- print(f"❌ Kokoro synthesis failed: {e}", file=sys.stderr)
137
- sys.exit(3)
138
-
139
-
140
- if __name__ == '__main__':
141
- main()
1
+ #!/usr/bin/env python3
2
+ """
3
+ AgentVibes — Kokoro TTS synthesizer
4
+ Synthesizes text to a WAV file using the kokoro-onnx package.
5
+ Prints the output WAV path to stdout.
6
+
7
+ Usage: kokoro-tts.py <text> <voice> <output_path> [speed]
8
+
9
+ Voices (examples):
10
+ af_heart af_nova af_sky af_bella af_sarah af_nicole
11
+ am_adam am_michael
12
+ bf_emma bf_isabella
13
+ bm_george bm_lewis
14
+
15
+ Install: pip install kokoro-onnx soundfile numpy
16
+ """
17
+
18
+ import sys
19
+ import os
20
+ import re
21
+
22
+ # Kokoro/torch auto-selects CUDA whenever a GPU is visible, but many setups
23
+ # (notably Windows) fail GPU allocation with "CUDA error: unknown error /
24
+ # Memory allocation failure", which crashes synthesis after a long torch load.
25
+ # The 82M-param Kokoro model runs fine on CPU in a few seconds, so force CPU by
26
+ # default. Opt back into GPU with AGENTVIBES_KOKORO_DEVICE=cuda. This MUST run
27
+ # before torch/kokoro are imported so torch.cuda.is_available() sees no device.
28
+ _KOKORO_DEVICE = os.environ.get('AGENTVIBES_KOKORO_DEVICE', 'cpu').strip().lower()
29
+ if _KOKORO_DEVICE != 'cuda':
30
+ os.environ['CUDA_VISIBLE_DEVICES'] = ''
31
+
32
+ def main():
33
+ # --download-only: fetch voice .pt file from HuggingFace without synthesis
34
+ if len(sys.argv) >= 2 and sys.argv[1] == '--download-only':
35
+ voice = sys.argv[2] if len(sys.argv) > 2 else 'af_heart'
36
+ # Validate before the id flows into a HuggingFace filename — blocks path
37
+ # traversal / arbitrary repo paths in voices/<voice>.pt.
38
+ if not re.match(r'^[a-z]{2}_[a-z0-9_]+$', voice):
39
+ print(f"❌ Invalid voice id: {voice}", file=sys.stderr)
40
+ sys.exit(4)
41
+ try:
42
+ from huggingface_hub import hf_hub_download
43
+ local = hf_hub_download(repo_id='hexgrad/Kokoro-82M', filename=f'voices/{voice}.pt')
44
+ print(local)
45
+ except Exception as e:
46
+ print(f"❌ Download failed: {e}", file=sys.stderr)
47
+ sys.exit(4)
48
+ sys.exit(0)
49
+
50
+ if len(sys.argv) < 4:
51
+ print("Usage: kokoro-tts.py <text> <voice> <output_path> [speed]", file=sys.stderr)
52
+ sys.exit(1)
53
+
54
+ text = sys.argv[1]
55
+ voice = sys.argv[2]
56
+ output_path = sys.argv[3]
57
+ try:
58
+ speed = float(sys.argv[4]) if len(sys.argv) > 4 else 1.0
59
+ except ValueError:
60
+ speed = 1.0
61
+
62
+ # Determine language code from voice prefix
63
+ # af/am = American English ('a'), bf/bm = British English ('b')
64
+ # jf/jm = Japanese ('j'), kf/km = Korean ('k'), etc.
65
+ prefix = voice[:2].lower() if len(voice) >= 2 else 'af'
66
+ lang_map = {
67
+ 'af': 'a', 'am': 'a', # American English
68
+ 'bf': 'b', 'bm': 'b', # British English
69
+ 'jf': 'j', 'jm': 'j', # Japanese
70
+ 'kf': 'k', 'km': 'k', # Korean
71
+ 'zf': 'z', 'zm': 'z', # Mandarin
72
+ 'ff': 'f', 'fm': 'f', # French
73
+ 'hf': 'h', 'hm': 'h', # Hindi
74
+ 'if': 'i', 'im': 'i', # Italian
75
+ 'pf': 'p', 'pm': 'p', # Brazilian Portuguese
76
+ 'ef': 'e', 'em': 'e', # Spanish (Spain)
77
+ 'nf': 'n', 'nm': 'n', # Spanish (Latin America)
78
+ }
79
+ lang_code = lang_map.get(prefix, 'a')
80
+
81
+ try:
82
+ from kokoro import KPipeline
83
+ except ImportError:
84
+ print("❌ kokoro-onnx not installed. Run: pip install kokoro-onnx soundfile numpy", file=sys.stderr)
85
+ sys.exit(2)
86
+
87
+ try:
88
+ import numpy as np
89
+ import soundfile as sf
90
+ except ImportError:
91
+ print("❌ soundfile/numpy not installed. Run: pip install soundfile numpy", file=sys.stderr)
92
+ sys.exit(2)
93
+
94
+ try:
95
+ # Pass device explicitly when supported; fall back for older kokoro
96
+ # versions whose KPipeline has no `device` kwarg (CUDA_VISIBLE_DEVICES
97
+ # already forces CPU in that case).
98
+ try:
99
+ pipeline = KPipeline(lang_code=lang_code, device=_KOKORO_DEVICE if _KOKORO_DEVICE == 'cuda' else 'cpu')
100
+ except TypeError:
101
+ pipeline = KPipeline(lang_code=lang_code)
102
+ generator = pipeline(text, voice=voice, speed=speed)
103
+
104
+ all_samples = []
105
+ sample_rate = 24000 # kokoro always outputs 24 kHz
106
+
107
+ for result in generator:
108
+ # kokoro >=0.9 yields a KPipeline.Result whose waveform is the
109
+ # `.audio` attribute (a torch.Tensor); older builds yield a
110
+ # (graphemes, phonemes, audio) tuple. Prefer `.audio`, then fall
111
+ # back to the last tuple element.
112
+ audio = getattr(result, "audio", None)
113
+ if audio is None:
114
+ try:
115
+ audio = result[-1]
116
+ except (TypeError, IndexError, KeyError):
117
+ audio = None
118
+ if audio is None:
119
+ continue
120
+ # Tensor -> numpy, force 1-D so np.concatenate never sees a 0-d array
121
+ if hasattr(audio, "detach"):
122
+ audio = audio.detach().cpu().numpy()
123
+ audio = np.asarray(audio).reshape(-1)
124
+ if audio.size > 0:
125
+ all_samples.append(audio)
126
+
127
+ if not all_samples:
128
+ print("❌ Kokoro returned no audio samples", file=sys.stderr)
129
+ sys.exit(3)
130
+
131
+ combined = np.concatenate(all_samples)
132
+ sf.write(output_path, combined, sample_rate)
133
+ print(output_path)
134
+
135
+ except Exception as e:
136
+ print(f"❌ Kokoro synthesis failed: {e}", file=sys.stderr)
137
+ sys.exit(3)
138
+
139
+
140
+ if __name__ == '__main__':
141
+ main()