agentvibes 4.2.0 → 4.4.1
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 +208 -84
- 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 +5895 -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 +143 -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,171 +1,171 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/piper-multispeaker-registry.sh
|
|
4
|
-
#
|
|
5
|
-
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
-
# Website: https://agentvibes.org
|
|
7
|
-
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
-
#
|
|
9
|
-
# Co-created by Paul Preibisch with Claude AI
|
|
10
|
-
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
-
#
|
|
12
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
-
# you may not use this file except in compliance with the License.
|
|
14
|
-
# You may obtain a copy of the License at
|
|
15
|
-
#
|
|
16
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
-
#
|
|
18
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
19
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
-
# See the License for the specific language governing permissions and
|
|
22
|
-
# limitations under the License.
|
|
23
|
-
#
|
|
24
|
-
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
-
# express or implied, including but not limited to the warranties of
|
|
26
|
-
# merchantability, fitness for a particular purpose and noninfringement.
|
|
27
|
-
# In no event shall the authors or copyright holders be liable for any claim,
|
|
28
|
-
# damages or other liability, whether in an action of contract, tort or
|
|
29
|
-
# otherwise, arising from, out of or in connection with the software or the
|
|
30
|
-
# use or other dealings in the software.
|
|
31
|
-
#
|
|
32
|
-
# ---
|
|
33
|
-
#
|
|
34
|
-
# @fileoverview Multi-Speaker Voice Registry - Maps speaker names to ONNX models and speaker IDs
|
|
35
|
-
# @context Enables individual speaker selection from multi-speaker Piper models (e.g., 16Speakers)
|
|
36
|
-
# @architecture Static registry mapping speaker names to model files and numeric speaker IDs
|
|
37
|
-
# @dependencies piper-voice-manager.sh (voice storage), play-tts-piper.sh (TTS with speaker ID)
|
|
38
|
-
# @entrypoints Sourced by voice-manager.sh for multi-speaker voice switching
|
|
39
|
-
# @patterns Registry pattern, speaker ID mapping, model-to-speaker association
|
|
40
|
-
# @related voice-manager.sh, play-tts-piper.sh, 16Speakers.onnx.json (speaker_id_map)
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
# Bash 3.2 compatible lowercase function (macOS ships with bash 3.2)
|
|
44
|
-
# ${var,,} syntax requires bash 4.0+
|
|
45
|
-
_to_lower() {
|
|
46
|
-
echo "$1" | tr '[:upper:]' '[:lower:]'
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
# Registry of multi-speaker models and their speaker names
|
|
50
|
-
# Format: "SpeakerName:model_file:speaker_id:description"
|
|
51
|
-
#
|
|
52
|
-
# 16Speakers Model (12 US + 4 UK voices):
|
|
53
|
-
# Source: LibriVox Public Domain recordings
|
|
54
|
-
# Model: 16Speakers.onnx (77MB)
|
|
55
|
-
#
|
|
56
|
-
MULTISPEAKER_VOICES=(
|
|
57
|
-
# US English Speakers (0-11)
|
|
58
|
-
"Cori_Samuel:16Speakers:0:US English Female"
|
|
59
|
-
"Kara_Shallenberg:16Speakers:1:US English Female"
|
|
60
|
-
"Kristin_Hughes:16Speakers:2:US English Female"
|
|
61
|
-
"Maria_Kasper:16Speakers:3:US English Female"
|
|
62
|
-
"Mike_Pelton:16Speakers:4:US English Male"
|
|
63
|
-
"Mark_Nelson:16Speakers:5:US English Male"
|
|
64
|
-
"Michael_Scherer:16Speakers:6:US English Male"
|
|
65
|
-
"James_K_White:16Speakers:7:US English Male"
|
|
66
|
-
"Rose_Ibex:16Speakers:8:US English Female"
|
|
67
|
-
"progressingamerica:16Speakers:9:US English Male"
|
|
68
|
-
"Steve_C:16Speakers:10:US English Male"
|
|
69
|
-
"Owlivia:16Speakers:11:US English Female"
|
|
70
|
-
|
|
71
|
-
# UK English Speakers (12-15)
|
|
72
|
-
"Paul_Hampton:16Speakers:12:UK English Male"
|
|
73
|
-
"Jennifer_Dorr:16Speakers:13:UK English Female"
|
|
74
|
-
"Emily_Cripps:16Speakers:14:UK English Female"
|
|
75
|
-
"Martin_Clifton:16Speakers:15:UK English Male"
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
# @function get_multispeaker_info
|
|
79
|
-
# @intent Get model and speaker ID for a speaker name
|
|
80
|
-
# @why Enables users to select individual speakers from multi-speaker models by name
|
|
81
|
-
# @param $1 {string} speaker_name - Speaker name (e.g., "Cori_Samuel", "Rose_Ibex")
|
|
82
|
-
# @returns Echoes "model:speaker_id" (e.g., "16Speakers:0") to stdout
|
|
83
|
-
# @exitcode 0=speaker found, 1=speaker not found
|
|
84
|
-
# @sideeffects None (read-only lookup)
|
|
85
|
-
# @edgecases Case-insensitive matching
|
|
86
|
-
# @calledby voice-manager.sh switch command
|
|
87
|
-
# @calls None (pure bash array iteration)
|
|
88
|
-
get_multispeaker_info() {
|
|
89
|
-
local speaker_name="$1"
|
|
90
|
-
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
91
|
-
name="${entry%%:*}"
|
|
92
|
-
rest="${entry#*:}"
|
|
93
|
-
model="${rest%%:*}"
|
|
94
|
-
rest="${rest#*:}"
|
|
95
|
-
speaker_id="${rest%%:*}"
|
|
96
|
-
|
|
97
|
-
if [[ "$(_to_lower "$name")" == "$(_to_lower "$speaker_name")" ]]; then
|
|
98
|
-
echo "$model:$speaker_id"
|
|
99
|
-
return 0
|
|
100
|
-
fi
|
|
101
|
-
done
|
|
102
|
-
return 1
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
# @function list_multispeaker_voices
|
|
106
|
-
# @intent Display all available multi-speaker voices with descriptions
|
|
107
|
-
# @why Help users discover individual speakers within multi-speaker models
|
|
108
|
-
# @param None
|
|
109
|
-
# @returns None
|
|
110
|
-
# @exitcode Always 0
|
|
111
|
-
# @sideeffects Writes formatted list to stdout
|
|
112
|
-
# @edgecases None
|
|
113
|
-
# @calledby voice-manager.sh list command, /agent-vibes:list
|
|
114
|
-
# @calls None (pure bash array iteration)
|
|
115
|
-
list_multispeaker_voices() {
|
|
116
|
-
echo "🎭 Multi-Speaker Voices (16Speakers Model):"
|
|
117
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
118
|
-
|
|
119
|
-
local current_model=""
|
|
120
|
-
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
121
|
-
name="${entry%%:*}"
|
|
122
|
-
rest="${entry#*:}"
|
|
123
|
-
model="${rest%%:*}"
|
|
124
|
-
rest="${rest#*:}"
|
|
125
|
-
speaker_id="${rest%%:*}"
|
|
126
|
-
description="${rest#*:}"
|
|
127
|
-
|
|
128
|
-
# Print section header when model changes
|
|
129
|
-
if [[ "$model" != "$current_model" ]]; then
|
|
130
|
-
if [[ -n "$current_model" ]]; then
|
|
131
|
-
echo ""
|
|
132
|
-
fi
|
|
133
|
-
echo " Model: $model.onnx"
|
|
134
|
-
current_model="$model"
|
|
135
|
-
fi
|
|
136
|
-
|
|
137
|
-
echo " • $name (ID: $speaker_id) - $description"
|
|
138
|
-
done
|
|
139
|
-
|
|
140
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
141
|
-
echo ""
|
|
142
|
-
echo "Usage: /agent-vibes:switch Cori_Samuel"
|
|
143
|
-
echo " /agent-vibes:switch Rose_Ibex"
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
# @function get_multispeaker_description
|
|
147
|
-
# @intent Get description for a speaker name
|
|
148
|
-
# @why Provide user-friendly info about speaker characteristics
|
|
149
|
-
# @param $1 {string} speaker_name - Speaker name
|
|
150
|
-
# @returns Echoes description (e.g., "US English Female") to stdout
|
|
151
|
-
# @exitcode 0=speaker found, 1=speaker not found
|
|
152
|
-
# @sideeffects None (read-only lookup)
|
|
153
|
-
# @edgecases Case-insensitive matching
|
|
154
|
-
# @calledby voice-manager.sh switch command (for confirmation message)
|
|
155
|
-
# @calls None (pure bash array iteration)
|
|
156
|
-
get_multispeaker_description() {
|
|
157
|
-
local speaker_name="$1"
|
|
158
|
-
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
159
|
-
name="${entry%%:*}"
|
|
160
|
-
rest="${entry#*:}"
|
|
161
|
-
rest="${rest#*:}"
|
|
162
|
-
rest="${rest#*:}"
|
|
163
|
-
description="${rest}"
|
|
164
|
-
|
|
165
|
-
if [[ "$(_to_lower "$name")" == "$(_to_lower "$speaker_name")" ]]; then
|
|
166
|
-
echo "$description"
|
|
167
|
-
return 0
|
|
168
|
-
fi
|
|
169
|
-
done
|
|
170
|
-
return 1
|
|
171
|
-
}
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/piper-multispeaker-registry.sh
|
|
4
|
+
#
|
|
5
|
+
# AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
|
|
6
|
+
# Website: https://agentvibes.org
|
|
7
|
+
# Repository: https://github.com/paulpreibisch/AgentVibes
|
|
8
|
+
#
|
|
9
|
+
# Co-created by Paul Preibisch with Claude AI
|
|
10
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
+
#
|
|
12
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
# you may not use this file except in compliance with the License.
|
|
14
|
+
# You may obtain a copy of the License at
|
|
15
|
+
#
|
|
16
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
#
|
|
18
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
# See the License for the specific language governing permissions and
|
|
22
|
+
# limitations under the License.
|
|
23
|
+
#
|
|
24
|
+
# DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
25
|
+
# express or implied, including but not limited to the warranties of
|
|
26
|
+
# merchantability, fitness for a particular purpose and noninfringement.
|
|
27
|
+
# In no event shall the authors or copyright holders be liable for any claim,
|
|
28
|
+
# damages or other liability, whether in an action of contract, tort or
|
|
29
|
+
# otherwise, arising from, out of or in connection with the software or the
|
|
30
|
+
# use or other dealings in the software.
|
|
31
|
+
#
|
|
32
|
+
# ---
|
|
33
|
+
#
|
|
34
|
+
# @fileoverview Multi-Speaker Voice Registry - Maps speaker names to ONNX models and speaker IDs
|
|
35
|
+
# @context Enables individual speaker selection from multi-speaker Piper models (e.g., 16Speakers)
|
|
36
|
+
# @architecture Static registry mapping speaker names to model files and numeric speaker IDs
|
|
37
|
+
# @dependencies piper-voice-manager.sh (voice storage), play-tts-piper.sh (TTS with speaker ID)
|
|
38
|
+
# @entrypoints Sourced by voice-manager.sh for multi-speaker voice switching
|
|
39
|
+
# @patterns Registry pattern, speaker ID mapping, model-to-speaker association
|
|
40
|
+
# @related voice-manager.sh, play-tts-piper.sh, 16Speakers.onnx.json (speaker_id_map)
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
# Bash 3.2 compatible lowercase function (macOS ships with bash 3.2)
|
|
44
|
+
# ${var,,} syntax requires bash 4.0+
|
|
45
|
+
_to_lower() {
|
|
46
|
+
echo "$1" | tr '[:upper:]' '[:lower:]'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Registry of multi-speaker models and their speaker names
|
|
50
|
+
# Format: "SpeakerName:model_file:speaker_id:description"
|
|
51
|
+
#
|
|
52
|
+
# 16Speakers Model (12 US + 4 UK voices):
|
|
53
|
+
# Source: LibriVox Public Domain recordings
|
|
54
|
+
# Model: 16Speakers.onnx (77MB)
|
|
55
|
+
#
|
|
56
|
+
MULTISPEAKER_VOICES=(
|
|
57
|
+
# US English Speakers (0-11)
|
|
58
|
+
"Cori_Samuel:16Speakers:0:US English Female"
|
|
59
|
+
"Kara_Shallenberg:16Speakers:1:US English Female"
|
|
60
|
+
"Kristin_Hughes:16Speakers:2:US English Female"
|
|
61
|
+
"Maria_Kasper:16Speakers:3:US English Female"
|
|
62
|
+
"Mike_Pelton:16Speakers:4:US English Male"
|
|
63
|
+
"Mark_Nelson:16Speakers:5:US English Male"
|
|
64
|
+
"Michael_Scherer:16Speakers:6:US English Male"
|
|
65
|
+
"James_K_White:16Speakers:7:US English Male"
|
|
66
|
+
"Rose_Ibex:16Speakers:8:US English Female"
|
|
67
|
+
"progressingamerica:16Speakers:9:US English Male"
|
|
68
|
+
"Steve_C:16Speakers:10:US English Male"
|
|
69
|
+
"Owlivia:16Speakers:11:US English Female"
|
|
70
|
+
|
|
71
|
+
# UK English Speakers (12-15)
|
|
72
|
+
"Paul_Hampton:16Speakers:12:UK English Male"
|
|
73
|
+
"Jennifer_Dorr:16Speakers:13:UK English Female"
|
|
74
|
+
"Emily_Cripps:16Speakers:14:UK English Female"
|
|
75
|
+
"Martin_Clifton:16Speakers:15:UK English Male"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
# @function get_multispeaker_info
|
|
79
|
+
# @intent Get model and speaker ID for a speaker name
|
|
80
|
+
# @why Enables users to select individual speakers from multi-speaker models by name
|
|
81
|
+
# @param $1 {string} speaker_name - Speaker name (e.g., "Cori_Samuel", "Rose_Ibex")
|
|
82
|
+
# @returns Echoes "model:speaker_id" (e.g., "16Speakers:0") to stdout
|
|
83
|
+
# @exitcode 0=speaker found, 1=speaker not found
|
|
84
|
+
# @sideeffects None (read-only lookup)
|
|
85
|
+
# @edgecases Case-insensitive matching
|
|
86
|
+
# @calledby voice-manager.sh switch command
|
|
87
|
+
# @calls None (pure bash array iteration)
|
|
88
|
+
get_multispeaker_info() {
|
|
89
|
+
local speaker_name="$1"
|
|
90
|
+
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
91
|
+
name="${entry%%:*}"
|
|
92
|
+
rest="${entry#*:}"
|
|
93
|
+
model="${rest%%:*}"
|
|
94
|
+
rest="${rest#*:}"
|
|
95
|
+
speaker_id="${rest%%:*}"
|
|
96
|
+
|
|
97
|
+
if [[ "$(_to_lower "$name")" == "$(_to_lower "$speaker_name")" ]]; then
|
|
98
|
+
echo "$model:$speaker_id"
|
|
99
|
+
return 0
|
|
100
|
+
fi
|
|
101
|
+
done
|
|
102
|
+
return 1
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# @function list_multispeaker_voices
|
|
106
|
+
# @intent Display all available multi-speaker voices with descriptions
|
|
107
|
+
# @why Help users discover individual speakers within multi-speaker models
|
|
108
|
+
# @param None
|
|
109
|
+
# @returns None
|
|
110
|
+
# @exitcode Always 0
|
|
111
|
+
# @sideeffects Writes formatted list to stdout
|
|
112
|
+
# @edgecases None
|
|
113
|
+
# @calledby voice-manager.sh list command, /agent-vibes:list
|
|
114
|
+
# @calls None (pure bash array iteration)
|
|
115
|
+
list_multispeaker_voices() {
|
|
116
|
+
echo "🎭 Multi-Speaker Voices (16Speakers Model):"
|
|
117
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
118
|
+
|
|
119
|
+
local current_model=""
|
|
120
|
+
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
121
|
+
name="${entry%%:*}"
|
|
122
|
+
rest="${entry#*:}"
|
|
123
|
+
model="${rest%%:*}"
|
|
124
|
+
rest="${rest#*:}"
|
|
125
|
+
speaker_id="${rest%%:*}"
|
|
126
|
+
description="${rest#*:}"
|
|
127
|
+
|
|
128
|
+
# Print section header when model changes
|
|
129
|
+
if [[ "$model" != "$current_model" ]]; then
|
|
130
|
+
if [[ -n "$current_model" ]]; then
|
|
131
|
+
echo ""
|
|
132
|
+
fi
|
|
133
|
+
echo " Model: $model.onnx"
|
|
134
|
+
current_model="$model"
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
echo " • $name (ID: $speaker_id) - $description"
|
|
138
|
+
done
|
|
139
|
+
|
|
140
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
141
|
+
echo ""
|
|
142
|
+
echo "Usage: /agent-vibes:switch Cori_Samuel"
|
|
143
|
+
echo " /agent-vibes:switch Rose_Ibex"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# @function get_multispeaker_description
|
|
147
|
+
# @intent Get description for a speaker name
|
|
148
|
+
# @why Provide user-friendly info about speaker characteristics
|
|
149
|
+
# @param $1 {string} speaker_name - Speaker name
|
|
150
|
+
# @returns Echoes description (e.g., "US English Female") to stdout
|
|
151
|
+
# @exitcode 0=speaker found, 1=speaker not found
|
|
152
|
+
# @sideeffects None (read-only lookup)
|
|
153
|
+
# @edgecases Case-insensitive matching
|
|
154
|
+
# @calledby voice-manager.sh switch command (for confirmation message)
|
|
155
|
+
# @calls None (pure bash array iteration)
|
|
156
|
+
get_multispeaker_description() {
|
|
157
|
+
local speaker_name="$1"
|
|
158
|
+
for entry in "${MULTISPEAKER_VOICES[@]}"; do
|
|
159
|
+
name="${entry%%:*}"
|
|
160
|
+
rest="${entry#*:}"
|
|
161
|
+
rest="${rest#*:}"
|
|
162
|
+
rest="${rest#*:}"
|
|
163
|
+
description="${rest}"
|
|
164
|
+
|
|
165
|
+
if [[ "$(_to_lower "$name")" == "$(_to_lower "$speaker_name")" ]]; then
|
|
166
|
+
echo "$description"
|
|
167
|
+
return 0
|
|
168
|
+
fi
|
|
169
|
+
done
|
|
170
|
+
return 1
|
|
171
|
+
}
|
|
@@ -84,8 +84,10 @@ get_voice_storage_dir() {
|
|
|
84
84
|
done
|
|
85
85
|
|
|
86
86
|
# Check global config
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
# Prefer $USERPROFILE on Windows where $HOME may be a MINGW-internal path
|
|
88
|
+
local _home="${USERPROFILE:-$HOME}"
|
|
89
|
+
if [[ -z "$config_file" ]] && [[ -f "$_home/.claude/piper-voices-dir.txt" ]]; then
|
|
90
|
+
config_file="$_home/.claude/piper-voices-dir.txt"
|
|
89
91
|
fi
|
|
90
92
|
fi
|
|
91
93
|
|
|
@@ -94,9 +96,22 @@ get_voice_storage_dir() {
|
|
|
94
96
|
fi
|
|
95
97
|
fi
|
|
96
98
|
|
|
99
|
+
# Validate the path is reachable — on Windows/MINGW, stale config files may
|
|
100
|
+
# contain bogus paths like /home/user that map to C:/Program Files/Git/home/
|
|
101
|
+
if [[ -n "$voice_dir" ]]; then
|
|
102
|
+
local parent_dir
|
|
103
|
+
parent_dir=$(dirname "$voice_dir")
|
|
104
|
+
if ! mkdir -p "$parent_dir" 2>/dev/null; then
|
|
105
|
+
voice_dir=""
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
97
109
|
# Fallback to default global storage
|
|
110
|
+
# On Windows (MINGW/Git Bash), $HOME may resolve to a bogus Git-internal path;
|
|
111
|
+
# prefer $USERPROFILE which always points to the real Windows home directory.
|
|
98
112
|
if [[ -z "$voice_dir" ]]; then
|
|
99
|
-
|
|
113
|
+
local home_dir="${USERPROFILE:-$HOME}"
|
|
114
|
+
voice_dir="$home_dir/.claude/piper-voices"
|
|
100
115
|
fi
|
|
101
116
|
|
|
102
117
|
mkdir -p "$voice_dir"
|
|
@@ -198,6 +213,12 @@ download_voice() {
|
|
|
198
213
|
local voice_name="$1"
|
|
199
214
|
local lang_code="${2:-}"
|
|
200
215
|
|
|
216
|
+
# Security: validate voice name to prevent path traversal
|
|
217
|
+
if [[ ! "$voice_name" =~ ^[a-zA-Z0-9_.-]+$ ]]; then
|
|
218
|
+
echo "❌ Invalid voice name: $voice_name" >&2
|
|
219
|
+
return 1
|
|
220
|
+
fi
|
|
221
|
+
|
|
201
222
|
local voice_dir
|
|
202
223
|
voice_dir=$(get_voice_storage_dir)
|
|
203
224
|
|
|
@@ -1,90 +1,90 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh
|
|
4
|
-
#
|
|
5
|
-
# AgentVibes - AgentVibes Receiver Provider (for voiceless connections)
|
|
6
|
-
# Sends text to a remote device via SSH for local AgentVibes playback.
|
|
7
|
-
# Use this when the AI agent runs on a server/headless machine that has no
|
|
8
|
-
# audio output — the remote device (laptop, phone, etc.) plays the audio.
|
|
9
|
-
#
|
|
10
|
-
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
-
# Licensed under the Apache License, Version 2.0
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
set -euo pipefail
|
|
15
|
-
|
|
16
|
-
TEXT="${1:-}"
|
|
17
|
-
VOICE="${2:-en_US-lessac-medium}"
|
|
18
|
-
AGENT_NAME="${3:-default}"
|
|
19
|
-
|
|
20
|
-
# Validate required input
|
|
21
|
-
if [[ -z "$TEXT" ]]; then
|
|
22
|
-
echo "❌ No text provided" >&2
|
|
23
|
-
echo "Usage: $0 <text> [voice] [agent_name]" >&2
|
|
24
|
-
exit 1
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
# Get script directory
|
|
28
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
-
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
30
|
-
|
|
31
|
-
# Get SSH host from config
|
|
32
|
-
SSH_HOST=$(cat "$PROJECT_ROOT/.claude/agentvibes-receiver-host.txt" 2>/dev/null || \
|
|
33
|
-
cat "$HOME/.claude/agentvibes-receiver-host.txt" 2>/dev/null || echo "")
|
|
34
|
-
|
|
35
|
-
if [[ -z "$SSH_HOST" ]]; then
|
|
36
|
-
echo "❌ AgentVibes Receiver host not configured" >&2
|
|
37
|
-
echo "💡 Set host: echo 'your-device' > ~/.claude/agentvibes-receiver-host.txt" >&2
|
|
38
|
-
exit 1
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# SECURITY: Validate SSH_HOST to prevent option injection
|
|
42
|
-
# Must be a valid hostname, IP address, or SSH config alias (alphanumeric, dots, hyphens, underscores)
|
|
43
|
-
if [[ ! "$SSH_HOST" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
|
44
|
-
echo "❌ Invalid SSH host format: $SSH_HOST" >&2
|
|
45
|
-
echo "💡 Host must be alphanumeric (may contain dots, hyphens, underscores)" >&2
|
|
46
|
-
exit 1
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
# SECURITY: Reject hosts starting with hyphen (SSH option injection)
|
|
50
|
-
if [[ "$SSH_HOST" == -* ]]; then
|
|
51
|
-
echo "❌ Invalid SSH host: cannot start with hyphen" >&2
|
|
52
|
-
exit 1
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
# SECURITY: Validate VOICE to prevent injection (alphanumeric, hyphens, underscores only)
|
|
56
|
-
if [[ ! "$VOICE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
57
|
-
echo "❌ Invalid voice format: $VOICE" >&2
|
|
58
|
-
exit 1
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
# SECURITY: Validate AGENT_NAME to prevent injection (alphanumeric, hyphens, underscores, spaces only)
|
|
62
|
-
if [[ ! "$AGENT_NAME" =~ ^[a-zA-Z0-9_\ -]+$ ]]; then
|
|
63
|
-
echo "❌ Invalid agent name format: $AGENT_NAME" >&2
|
|
64
|
-
exit 1
|
|
65
|
-
fi
|
|
66
|
-
|
|
67
|
-
# SECURITY: Encode text and agent name as base64 to prevent command injection
|
|
68
|
-
# The receiver will decode these safely
|
|
69
|
-
ENCODED_TEXT=$(printf '%s' "$TEXT" | base64 -w 0)
|
|
70
|
-
ENCODED_AGENT=$(printf '%s' "$AGENT_NAME" | base64 -w 0)
|
|
71
|
-
|
|
72
|
-
# Send text to remote for local AgentVibes playback
|
|
73
|
-
echo "📱 Sending to $SSH_HOST for local playback..." >&2
|
|
74
|
-
|
|
75
|
-
# Try receiver scripts in order — single SSH call, no separate probe
|
|
76
|
-
# SECURITY: Base64-encoded values are safe to pass as arguments (no shell metacharacters)
|
|
77
|
-
ssh "$SSH_HOST" "
|
|
78
|
-
if [ -f ~/.agentvibes/play-remote.sh ]; then
|
|
79
|
-
bash ~/.agentvibes/play-remote.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'
|
|
80
|
-
elif [ -f ~/.termux/agentvibes-play.sh ]; then
|
|
81
|
-
bash ~/.termux/agentvibes-play.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'
|
|
82
|
-
else
|
|
83
|
-
echo 'Error: Receiver script not found' >&2
|
|
84
|
-
exit 1
|
|
85
|
-
fi
|
|
86
|
-
" &
|
|
87
|
-
SSH_PID=$!
|
|
88
|
-
|
|
89
|
-
echo "Sent to $SSH_HOST (PID: $SSH_PID)" >&2
|
|
90
|
-
exit 0
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh
|
|
4
|
+
#
|
|
5
|
+
# AgentVibes - AgentVibes Receiver Provider (for voiceless connections)
|
|
6
|
+
# Sends text to a remote device via SSH for local AgentVibes playback.
|
|
7
|
+
# Use this when the AI agent runs on a server/headless machine that has no
|
|
8
|
+
# audio output — the remote device (laptop, phone, etc.) plays the audio.
|
|
9
|
+
#
|
|
10
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
11
|
+
# Licensed under the Apache License, Version 2.0
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
TEXT="${1:-}"
|
|
17
|
+
VOICE="${2:-en_US-lessac-medium}"
|
|
18
|
+
AGENT_NAME="${3:-default}"
|
|
19
|
+
|
|
20
|
+
# Validate required input
|
|
21
|
+
if [[ -z "$TEXT" ]]; then
|
|
22
|
+
echo "❌ No text provided" >&2
|
|
23
|
+
echo "Usage: $0 <text> [voice] [agent_name]" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Get script directory
|
|
28
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
30
|
+
|
|
31
|
+
# Get SSH host from config
|
|
32
|
+
SSH_HOST=$(cat "$PROJECT_ROOT/.claude/agentvibes-receiver-host.txt" 2>/dev/null || \
|
|
33
|
+
cat "$HOME/.claude/agentvibes-receiver-host.txt" 2>/dev/null || echo "")
|
|
34
|
+
|
|
35
|
+
if [[ -z "$SSH_HOST" ]]; then
|
|
36
|
+
echo "❌ AgentVibes Receiver host not configured" >&2
|
|
37
|
+
echo "💡 Set host: echo 'your-device' > ~/.claude/agentvibes-receiver-host.txt" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# SECURITY: Validate SSH_HOST to prevent option injection
|
|
42
|
+
# Must be a valid hostname, IP address, or SSH config alias (alphanumeric, dots, hyphens, underscores)
|
|
43
|
+
if [[ ! "$SSH_HOST" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
|
44
|
+
echo "❌ Invalid SSH host format: $SSH_HOST" >&2
|
|
45
|
+
echo "💡 Host must be alphanumeric (may contain dots, hyphens, underscores)" >&2
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# SECURITY: Reject hosts starting with hyphen (SSH option injection)
|
|
50
|
+
if [[ "$SSH_HOST" == -* ]]; then
|
|
51
|
+
echo "❌ Invalid SSH host: cannot start with hyphen" >&2
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# SECURITY: Validate VOICE to prevent injection (alphanumeric, hyphens, underscores only)
|
|
56
|
+
if [[ ! "$VOICE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
57
|
+
echo "❌ Invalid voice format: $VOICE" >&2
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# SECURITY: Validate AGENT_NAME to prevent injection (alphanumeric, hyphens, underscores, spaces only)
|
|
62
|
+
if [[ ! "$AGENT_NAME" =~ ^[a-zA-Z0-9_\ -]+$ ]]; then
|
|
63
|
+
echo "❌ Invalid agent name format: $AGENT_NAME" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# SECURITY: Encode text and agent name as base64 to prevent command injection
|
|
68
|
+
# The receiver will decode these safely
|
|
69
|
+
ENCODED_TEXT=$(printf '%s' "$TEXT" | base64 -w 0)
|
|
70
|
+
ENCODED_AGENT=$(printf '%s' "$AGENT_NAME" | base64 -w 0)
|
|
71
|
+
|
|
72
|
+
# Send text to remote for local AgentVibes playback
|
|
73
|
+
echo "📱 Sending to $SSH_HOST for local playback..." >&2
|
|
74
|
+
|
|
75
|
+
# Try receiver scripts in order — single SSH call, no separate probe
|
|
76
|
+
# SECURITY: Base64-encoded values are safe to pass as arguments (no shell metacharacters)
|
|
77
|
+
ssh "$SSH_HOST" "
|
|
78
|
+
if [ -f ~/.agentvibes/play-remote.sh ]; then
|
|
79
|
+
bash ~/.agentvibes/play-remote.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'
|
|
80
|
+
elif [ -f ~/.termux/agentvibes-play.sh ]; then
|
|
81
|
+
bash ~/.termux/agentvibes-play.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'
|
|
82
|
+
else
|
|
83
|
+
echo 'Error: Receiver script not found' >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
" &
|
|
87
|
+
SSH_PID=$!
|
|
88
|
+
|
|
89
|
+
echo "Sent to $SSH_HOST (PID: $SSH_PID)" >&2
|
|
90
|
+
exit 0
|