agentvibes 5.13.1 → 5.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/audio/ui/CREDITS.txt +16 -16
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/kokoro-server.py +219 -219
- package/.claude/hooks/kokoro-tts.py +141 -141
- package/.claude/hooks/party-stage-roster.py +328 -328
- package/.claude/hooks/play-tts-kokoro.sh +7 -2
- package/.claude/hooks/play-tts-ssh-remote.sh +38 -3
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks-windows/kokoro-server.py +219 -219
- package/.claude/hooks-windows/kokoro-tts.py +107 -107
- package/.claude/hooks-windows/play-tts.ps1 +17 -0
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/CLAUDE.md +84 -176
- package/README.md +27 -2
- package/RELEASE_NOTES.md +68 -0
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/mcp-server.js +121 -121
- 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/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 +12 -2
- package/mcp-server/server.py +2111 -2085
- package/mcp-server/test_mcp_correctness.py +504 -504
- package/mcp-server/test_windows_script_parity.py +339 -339
- package/package.json +6 -3
- package/setup-ssh-receiver.ps1 +259 -0
- package/setup-windows.ps1 +39 -29
- package/src/cli/list-personalities.js +110 -110
- package/src/commands/bmad-voices.js +394 -394
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -44
- package/src/console/tabs/agents-tab.js +14 -4
- package/src/console/tabs/help-tab.js +314 -314
- package/src/console/tabs/readme-tab.js +272 -272
- package/src/console/tabs/settings-tab.js +31 -6
- package/src/console/tabs/setup-tab.js +154 -32
- package/src/console/tabs/voices-tab.js +48 -6
- package/src/console/widgets/destroy-list.js +25 -25
- package/src/console/widgets/notice.js +55 -55
- package/src/installer/language-screen.js +31 -31
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +91 -35
- package/src/services/language-service.js +47 -47
- package/src/services/llm-provider-service.js +4 -1
- package/src/services/provider-voice-catalog.js +9 -5
- package/src/utils/audio-format-validator.js +277 -277
- package/src/utils/dependency-checker.js +469 -469
- package/src/utils/file-ownership-verifier.js +358 -358
- package/src/utils/music-file-validator.js +285 -285
- package/src/utils/preview-list-prompt.js +144 -144
- package/src/utils/secure-music-storage.js +412 -412
- package/templates/agentvibes-receiver.ps1 +311 -0
- package/templates/agentvibes-receiver.sh +297 -297
- package/voice-assignments.json +8244 -8244
- package/.agentvibes/config.json +0 -17
- package/.agentvibes/install-manifest.json +0 -362
- package/.claude/config/audio-effects.cfg +0 -7
- package/.claude/config/audio-effects.cfg.bak-kokoro +0 -7
- package/.claude/config/background-music-enabled.txt +0 -1
- package/.claude/config/background-music-position.txt +0 -27
- package/.claude/config/background-music-volume.txt +0 -1
- package/.claude/config/background-music.cfg +0 -1
- package/.claude/config/background-music.txt +0 -1
- package/.claude/config/language.txt +0 -1
- package/.claude/config/personality.txt +0 -1
- package/.claude/config/reverb-level.txt +0 -1
- package/.claude/config/tts-speech-rate.txt +0 -1
- package/.claude/config/tts-verbosity.txt +0 -1
- package/.claude/hooks-windows/audio-cache-utils.ps1.user.bak +0 -119
- 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()
|