agentvibes 5.3.0 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agentvibes/LITE-MODE.md +236 -0
- package/.agentvibes/README.md +136 -0
- package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +141 -0
- package/.agentvibes/backups/agents/analyst_20260204_144958.md +78 -0
- package/.agentvibes/backups/agents/architect_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/dev_20260204_144958.md +74 -0
- package/.agentvibes/backups/agents/pm_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +64 -0
- package/.agentvibes/backups/agents/sm_20260204_144958.md +87 -0
- package/.agentvibes/backups/agents/tea_20260204_144958.md +79 -0
- package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +82 -0
- package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +80 -0
- package/.agentvibes/bmad/bmad-voices.md +69 -69
- package/.agentvibes/config/README-personality-defaults.md +162 -0
- package/.agentvibes/config/mode.txt +1 -0
- package/.agentvibes/config/personality-voice-defaults.default.json +21 -0
- package/.agentvibes/config/save-audio.txt +1 -0
- package/.agentvibes/config/voice-metadata.json +160 -0
- package/.agentvibes/config.json +24 -15
- package/.agentvibes/hooks/help.sh +191 -0
- package/.agentvibes/hooks/post-tool-use-lite.sh +111 -0
- package/.agentvibes/hooks/save-audio-manager.sh +162 -0
- package/.agentvibes/hooks/session-start-full-optimized.sh +102 -0
- package/.agentvibes/hooks/session-start-full.sh +142 -0
- package/.agentvibes/hooks/session-start-lite-v2.sh +34 -0
- package/.agentvibes/hooks/session-start-lite.sh +29 -0
- package/.agentvibes/hooks/stop-lite.sh +115 -0
- package/.agentvibes/hooks/switch-mode.sh +215 -0
- package/.agentvibes/output-styles/audio-summary.md +30 -0
- package/.claude/activation-instructions +54 -54
- package/.claude/audio/voice-samples/piper/alan.wav +0 -0
- package/.claude/audio/voice-samples/piper/amy.wav +0 -0
- package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
- package/.claude/audio/voice-samples/piper/joe.wav +0 -0
- package/.claude/audio/voice-samples/piper/john.wav +0 -0
- package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
- package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
- package/.claude/audio/voice-samples/piper/linda.wav +0 -0
- package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
- package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
- 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/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/audio-effects.cfg +16 -11
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-position.txt +27 -0
- package/.claude/config/background-music-volume.txt +1 -1
- package/.claude/config/background-music.cfg +1 -0
- package/.claude/config/background-music.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +1 -4
- package/.claude/config/tts-verbosity.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 +0 -0
- package/.claude/hooks/audio-processor.sh +60 -14
- package/.claude/hooks/background-music-manager.sh +0 -0
- package/.claude/hooks/bmad-party-manager.sh +225 -0
- package/.claude/hooks/bmad-party-speak.sh +0 -0
- package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
- package/.claude/hooks/bmad-speak.sh +12 -15
- package/.claude/hooks/bmad-tts-injector.sh +0 -0
- package/.claude/hooks/bmad-voice-manager.sh +0 -0
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +25 -23
- package/.claude/hooks/clawdbot-receiver.sh +4 -28
- package/.claude/hooks/clean-audio-cache.sh +0 -0
- package/.claude/hooks/cleanup-cache.sh +0 -0
- package/.claude/hooks/configure-rdp-mode.sh +0 -0
- package/.claude/hooks/download-extra-voices.sh +0 -0
- package/.claude/hooks/effects-manager.sh +0 -0
- package/.claude/hooks/github-star-reminder.sh +0 -0
- package/.claude/hooks/language-manager.sh +0 -0
- package/.claude/hooks/learn-manager.sh +0 -0
- package/.claude/hooks/macos-voice-manager.sh +0 -0
- package/.claude/hooks/migrate-background-music.sh +0 -0
- package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
- package/.claude/hooks/optimize-background-music.sh +0 -0
- package/.claude/hooks/personality-manager.sh +0 -0
- package/.claude/hooks/piper-download-voices.sh +0 -0
- package/.claude/hooks/piper-installer.sh +1 -1
- package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
- package/.claude/hooks/piper-voice-manager.sh +0 -0
- package/.claude/hooks/play-tts-enhanced.sh +0 -0
- package/.claude/hooks/play-tts-macos.sh +6 -12
- package/.claude/hooks/play-tts-piper.sh +52 -81
- package/.claude/hooks/play-tts-soprano.sh +9 -43
- package/.claude/hooks/play-tts-ssh-remote.sh +43 -215
- package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
- package/.claude/hooks/play-tts.sh +41 -20
- package/.claude/hooks/post-response.sh +41 -0
- package/.claude/hooks/prepare-release.sh +0 -0
- package/.claude/hooks/provider-commands.sh +0 -0
- package/.claude/hooks/provider-manager.sh +0 -0
- package/.claude/hooks/replay-target-audio.sh +0 -0
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +0 -0
- package/.claude/hooks/session-start-tts.sh +56 -39
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +0 -0
- package/.claude/hooks/stop.sh +63 -0
- package/.claude/hooks/termux-installer.sh +0 -0
- package/.claude/hooks/translate-manager.sh +0 -0
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +0 -0
- package/.claude/hooks/tts-queue.sh +0 -0
- package/.claude/hooks/verbosity-manager.sh +0 -0
- package/.claude/hooks/voice-manager.sh +26 -4
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/bmad-party-speak.ps1 +278 -278
- package/.claude/hooks-windows/bmad-speak.ps1 +264 -264
- package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -53
- package/.claude/hooks-windows/effects-manager.ps1 +294 -294
- package/.claude/hooks-windows/language-manager.ps1 +193 -193
- package/.claude/hooks-windows/learn-manager.ps1 +241 -241
- package/.claude/hooks-windows/personality-manager.ps1 +266 -266
- package/.claude/hooks-windows/play-tts-soprano.ps1 +5 -5
- package/.claude/hooks-windows/play-tts-termux-ssh.ps1 +138 -138
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +178 -0
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -0
- package/.claude/hooks-windows/play-tts.ps1 +265 -507
- package/.claude/hooks-windows/provider-manager.ps1 +158 -192
- package/.claude/hooks-windows/session-start-tts.ps1 +55 -46
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/speed-manager.ps1 +166 -166
- package/.claude/hooks-windows/voice-manager-windows.ps1 +176 -260
- 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/piper-voices-dir.txt +1 -0
- package/.claude/settings.json +25 -15
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.clawdbot/skill/SKILL.md +149 -145
- package/.mcp.json +30 -11
- package/CLAUDE.md +170 -215
- package/README.md +207 -521
- package/RELEASE_NOTES.md +1172 -1976
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +0 -0
- package/bin/agentvibes-voice-browser.js +64 -1289
- package/bin/agentvibes.js +28 -0
- package/bin/ensure-soprano-running.sh +43 -0
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +0 -0
- 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 +1467 -1578
- package/mcp-server/test_server.py +395 -395
- package/package.json +1 -3
- package/setup-windows.ps1 +815 -815
- package/src/console/tabs/music-tab.js +5 -2
- package/src/console/tabs/voices-tab.js +71 -37
- package/src/installer.js +52 -5
- package/src/services/llm-provider-service.js +1 -1
- package/templates/agentvibes-receiver.sh +158 -483
- package/templates/audio/welcome-music.mp3 +0 -0
- package/.agentvibes/bmad-voice-map.json +0 -104
- package/.agentvibes/copilot-sessions.log +0 -4
- package/.claude/config/audio-effects-bmad.cfg +0 -50
- package/.claude/config/intro-text.txt +0 -1
- package/.claude/config/personality.txt +0 -1
- package/.claude/config/piper-speech-rate.txt +0 -4
- package/.claude/config/piper-target-speech-rate.txt +0 -1
- package/.claude/config/reverb-level.txt +0 -1
- package/.claude/config/tts-target-speech-rate.txt +0 -1
- package/voice-assignments.json +0 -8245
- /package/{.claude → .agentvibes}/config/agentvibes.json +0 -0
|
@@ -1,483 +1,158 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: agentvibes-receiver.sh
|
|
4
|
-
# Location: User installs to ~/.agentvibes/play-remote.sh
|
|
5
|
-
#
|
|
6
|
-
# AgentVibes SSH-TTS Receiver
|
|
7
|
-
# Receives
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
fi
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if [[ -
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
#
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
PRETEXT=""
|
|
160
|
-
SPEED=""
|
|
161
|
-
PROVIDER="piper"
|
|
162
|
-
|
|
163
|
-
# Detect JSON payload (starts with '{')
|
|
164
|
-
if [[ "$DECODED" == "{"* ]]; then
|
|
165
|
-
# JSON v2 payload — extract fields with lightweight parsing
|
|
166
|
-
# SECURITY: Use parameter extraction, not eval
|
|
167
|
-
if command -v jq &>/dev/null; then
|
|
168
|
-
TEXT=$(printf '%s' "$DECODED" | jq -r '.text // empty' 2>/dev/null) || TEXT=""
|
|
169
|
-
VOICE=$(printf '%s' "$DECODED" | jq -r '.voice // "en_US-lessac-medium"' 2>/dev/null) || VOICE="en_US-lessac-medium"
|
|
170
|
-
SOX_EFFECTS=$(printf '%s' "$DECODED" | jq -r '.effects // empty' 2>/dev/null) || SOX_EFFECTS=""
|
|
171
|
-
BG_FILE=$(printf '%s' "$DECODED" | jq -r '.music // empty' 2>/dev/null) || BG_FILE=""
|
|
172
|
-
BG_VOLUME=$(printf '%s' "$DECODED" | jq -r '.volume // "0.10"' 2>/dev/null) || BG_VOLUME="0.10"
|
|
173
|
-
PROJECT=$(printf '%s' "$DECODED" | jq -r '.project // empty' 2>/dev/null) || PROJECT=""
|
|
174
|
-
PRETEXT=$(printf '%s' "$DECODED" | jq -r '.pretext // empty' 2>/dev/null) || PRETEXT=""
|
|
175
|
-
SPEED=$(printf '%s' "$DECODED" | jq -r '.speed // empty' 2>/dev/null) || SPEED=""
|
|
176
|
-
PROVIDER=$(printf '%s' "$DECODED" | jq -r '.provider // "piper"' 2>/dev/null) || PROVIDER="piper"
|
|
177
|
-
else
|
|
178
|
-
# Fallback: extract with grep/sed (no jq available)
|
|
179
|
-
TEXT=$(printf '%s' "$DECODED" | grep -o '"text"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
180
|
-
VOICE=$(printf '%s' "$DECODED" | grep -o '"voice"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
181
|
-
SOX_EFFECTS=$(printf '%s' "$DECODED" | grep -o '"effects"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
182
|
-
BG_FILE=$(printf '%s' "$DECODED" | grep -o '"music"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
183
|
-
BG_VOLUME=$(printf '%s' "$DECODED" | grep -o '"volume"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
184
|
-
PROJECT=$(printf '%s' "$DECODED" | grep -o '"project"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
185
|
-
PRETEXT=$(printf '%s' "$DECODED" | grep -o '"pretext"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
186
|
-
SPEED=$(printf '%s' "$DECODED" | grep -o '"speed"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
187
|
-
PROVIDER=$(printf '%s' "$DECODED" | grep -o '"provider"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//' || true)
|
|
188
|
-
[[ -z "$VOICE" ]] && VOICE="en_US-lessac-medium"
|
|
189
|
-
[[ -z "$BG_VOLUME" ]] && BG_VOLUME="0.10"
|
|
190
|
-
[[ -z "$PROVIDER" ]] && PROVIDER="piper"
|
|
191
|
-
fi
|
|
192
|
-
else
|
|
193
|
-
# Legacy format: plain text, voice from positional arg
|
|
194
|
-
TEXT="$DECODED"
|
|
195
|
-
VOICE="${2:-en_US-lessac-medium}"
|
|
196
|
-
fi
|
|
197
|
-
|
|
198
|
-
# Validate required text
|
|
199
|
-
if [[ -z "$TEXT" ]]; then
|
|
200
|
-
echo "Error: No text in payload" >&2
|
|
201
|
-
exit 1
|
|
202
|
-
fi
|
|
203
|
-
|
|
204
|
-
# SECURITY: Validate voice format (allow :: for multi-speaker, . for locale, space for names)
|
|
205
|
-
_voice_re='^[a-zA-Z0-9_.: -]+$'
|
|
206
|
-
if [[ ! "$VOICE" =~ $_voice_re ]]; then
|
|
207
|
-
echo "Error: Invalid voice format" >&2
|
|
208
|
-
exit 1
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
# SECURITY: Validate volume is a number
|
|
212
|
-
if [[ -n "$BG_VOLUME" ]] && [[ ! "$BG_VOLUME" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
213
|
-
BG_VOLUME="0.10"
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
# SECURITY: Validate speed is a number (prevents awk injection)
|
|
217
|
-
if [[ -n "$SPEED" ]] && [[ ! "$SPEED" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
218
|
-
SPEED=""
|
|
219
|
-
fi
|
|
220
|
-
|
|
221
|
-
# SECURITY: Validate provider format (known providers only)
|
|
222
|
-
case "$PROVIDER" in
|
|
223
|
-
piper|soprano|macos|windows-sapi) ;;
|
|
224
|
-
*) PROVIDER="piper" ;;
|
|
225
|
-
esac
|
|
226
|
-
|
|
227
|
-
# Prepend pretext if provided
|
|
228
|
-
if [[ -n "$PRETEXT" ]]; then
|
|
229
|
-
TEXT="${PRETEXT}. ${TEXT}"
|
|
230
|
-
fi
|
|
231
|
-
|
|
232
|
-
# ---------------------------------------------------------------------------
|
|
233
|
-
# Structured logging (for receiver tab to display)
|
|
234
|
-
# ---------------------------------------------------------------------------
|
|
235
|
-
|
|
236
|
-
LOG_ID=$(printf '%04x' $((RANDOM % 65536)))
|
|
237
|
-
|
|
238
|
-
log_message() {
|
|
239
|
-
local status="$1"
|
|
240
|
-
local detail="${2:-}"
|
|
241
|
-
local timestamp
|
|
242
|
-
timestamp=$(date '+%Y-%m-%dT%H:%M:%S')
|
|
243
|
-
local log_dir
|
|
244
|
-
log_dir=$(dirname "$LOG_FILE")
|
|
245
|
-
mkdir -p "$log_dir" 2>/dev/null || true
|
|
246
|
-
# Extract sender IP from SSH_CLIENT (set by sshd: "IP PORT PORT")
|
|
247
|
-
local sender_ip="${SSH_CLIENT%% *}"
|
|
248
|
-
[[ -z "$sender_ip" ]] && sender_ip="local"
|
|
249
|
-
# Format: TIMESTAMP|STATUS|PROJECT|VOICE|TEXT_PREVIEW|DETAIL|IP|LOG_ID
|
|
250
|
-
local preview="${TEXT:0:200}"
|
|
251
|
-
printf '%s|%s|%s|%s|%s|%s|%s|%s\n' \
|
|
252
|
-
"$timestamp" "$status" "${PROJECT:-unknown}" "$VOICE" "$preview" "$detail" "$sender_ip" "$LOG_ID" \
|
|
253
|
-
>> "$LOG_FILE" 2>/dev/null || true
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
log_message "RECEIVED" "provider=${PROVIDER} effects=${SOX_EFFECTS:-none} music=${BG_FILE:-none}"
|
|
257
|
-
|
|
258
|
-
# ---------------------------------------------------------------------------
|
|
259
|
-
# Temp files with cleanup
|
|
260
|
-
# ---------------------------------------------------------------------------
|
|
261
|
-
|
|
262
|
-
# Use own runtime dir for temp files (not the desktop user's)
|
|
263
|
-
_TEMP_BASE="/run/user/$(id -u)"
|
|
264
|
-
[[ -d "$_TEMP_BASE" ]] && [[ -w "$_TEMP_BASE" ]] || _TEMP_BASE="/tmp"
|
|
265
|
-
RAW_WAV=$(mktemp "$_TEMP_BASE/agentvibes-recv-XXXXXX.wav")
|
|
266
|
-
EFFECTS_WAV=$(mktemp "$_TEMP_BASE/agentvibes-recv-fx-XXXXXX.wav")
|
|
267
|
-
FINAL_WAV=$(mktemp "$_TEMP_BASE/agentvibes-recv-final-XXXXXX.wav")
|
|
268
|
-
trap 'rm -f "$RAW_WAV" "$EFFECTS_WAV" "$FINAL_WAV"' EXIT
|
|
269
|
-
|
|
270
|
-
# ---------------------------------------------------------------------------
|
|
271
|
-
# Step 1: Generate TTS audio (multi-provider dispatch)
|
|
272
|
-
# ---------------------------------------------------------------------------
|
|
273
|
-
|
|
274
|
-
_generate_tts_piper() {
|
|
275
|
-
local model="$VOICES_DIR/${VOICE}.onnx"
|
|
276
|
-
if [[ ! -f "$model" ]]; then
|
|
277
|
-
# Fallback: try any available voice rather than failing
|
|
278
|
-
local fallback
|
|
279
|
-
fallback=$(find "$VOICES_DIR" -maxdepth 1 -name '*.onnx' -type f 2>/dev/null | head -1)
|
|
280
|
-
if [[ -n "$fallback" ]]; then
|
|
281
|
-
local fallback_name
|
|
282
|
-
fallback_name=$(basename "$fallback" .onnx)
|
|
283
|
-
log_message "WARN" "Voice $VOICE not found, falling back to $fallback_name"
|
|
284
|
-
echo "Warning: Voice $VOICE not found, using $fallback_name" >&2
|
|
285
|
-
VOICE="$fallback_name"
|
|
286
|
-
model="$fallback"
|
|
287
|
-
else
|
|
288
|
-
log_message "ERROR" "No voice models found in $VOICES_DIR"
|
|
289
|
-
echo "Error: No voice models found in $VOICES_DIR" >&2
|
|
290
|
-
return 1
|
|
291
|
-
fi
|
|
292
|
-
fi
|
|
293
|
-
|
|
294
|
-
local args=(--model "$model" --output_file "$RAW_WAV")
|
|
295
|
-
if [[ -n "$SPEED" ]] && [[ "$SPEED" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
296
|
-
args+=(--length_scale "$SPEED")
|
|
297
|
-
fi
|
|
298
|
-
|
|
299
|
-
echo "$TEXT" | piper "${args[@]}" 2>/dev/null || {
|
|
300
|
-
log_message "ERROR" "Piper TTS failed"
|
|
301
|
-
echo "Error: Piper TTS generation failed" >&2
|
|
302
|
-
return 1
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
_generate_tts_soprano() {
|
|
307
|
-
local soprano_port="${SOPRANO_PORT:-7860}"
|
|
308
|
-
|
|
309
|
-
# Try API mode first (OpenAI-compatible endpoint)
|
|
310
|
-
if curl -sf -X POST "http://127.0.0.1:${soprano_port}/v1/audio/speech" \
|
|
311
|
-
-H "Content-Type: application/json" \
|
|
312
|
-
-d "{\"input\":$(printf '%s' "$TEXT" | jq -Rs .)}" \
|
|
313
|
-
--output "$RAW_WAV" 2>/dev/null; then
|
|
314
|
-
return 0
|
|
315
|
-
fi
|
|
316
|
-
|
|
317
|
-
# Try CLI mode — options before --, text as final positional arg
|
|
318
|
-
if command -v soprano &>/dev/null; then
|
|
319
|
-
soprano -o "$RAW_WAV" -- "$TEXT" 2>/dev/null && return 0
|
|
320
|
-
fi
|
|
321
|
-
|
|
322
|
-
log_message "ERROR" "Soprano TTS failed — is soprano running on port ${soprano_port}?"
|
|
323
|
-
echo "Error: Soprano TTS unavailable (tried API and CLI)" >&2
|
|
324
|
-
return 1
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
_generate_tts_macos() {
|
|
328
|
-
if ! command -v say &>/dev/null; then
|
|
329
|
-
log_message "ERROR" "macOS say command not found"
|
|
330
|
-
echo "Error: macOS say command not available" >&2
|
|
331
|
-
return 1
|
|
332
|
-
fi
|
|
333
|
-
|
|
334
|
-
local say_args=(-v "$VOICE")
|
|
335
|
-
# Convert speed multiplier to WPM (say uses WPM, default ~200)
|
|
336
|
-
if [[ -n "$SPEED" ]] && [[ "$SPEED" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
337
|
-
local wpm
|
|
338
|
-
wpm=$(awk "BEGIN {printf \"%d\", 200 * $SPEED}")
|
|
339
|
-
say_args+=(-r "$wpm")
|
|
340
|
-
fi
|
|
341
|
-
|
|
342
|
-
# say outputs AIFF — convert to WAV for consistent pipeline
|
|
343
|
-
local aiff_tmp="${RAW_WAV%.wav}.aiff"
|
|
344
|
-
echo "$TEXT" | say "${say_args[@]}" -o "$aiff_tmp" 2>/dev/null || {
|
|
345
|
-
log_message "ERROR" "macOS say failed"
|
|
346
|
-
rm -f "$aiff_tmp"
|
|
347
|
-
return 1
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if command -v ffmpeg &>/dev/null; then
|
|
351
|
-
ffmpeg -y -i "$aiff_tmp" "$RAW_WAV" </dev/null 2>/dev/null
|
|
352
|
-
rm -f "$aiff_tmp"
|
|
353
|
-
else
|
|
354
|
-
# No ffmpeg — rename and hope player handles AIFF
|
|
355
|
-
mv "$aiff_tmp" "$RAW_WAV"
|
|
356
|
-
fi
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
_generate_tts_windows_sapi() {
|
|
360
|
-
# Windows SAPI via PowerShell (works in WSL2 via powershell.exe)
|
|
361
|
-
local ps_cmd=""
|
|
362
|
-
if command -v powershell.exe &>/dev/null; then
|
|
363
|
-
ps_cmd="powershell.exe"
|
|
364
|
-
elif command -v pwsh &>/dev/null; then
|
|
365
|
-
ps_cmd="pwsh"
|
|
366
|
-
else
|
|
367
|
-
log_message "ERROR" "PowerShell not found for Windows SAPI"
|
|
368
|
-
echo "Error: PowerShell required for Windows SAPI" >&2
|
|
369
|
-
return 1
|
|
370
|
-
fi
|
|
371
|
-
|
|
372
|
-
# SECURITY: Escape text for PowerShell single-quoted string
|
|
373
|
-
local escaped_text
|
|
374
|
-
escaped_text=$(printf '%s' "$TEXT" | sed "s/'/''/g")
|
|
375
|
-
|
|
376
|
-
local rate=0
|
|
377
|
-
if [[ -n "$SPEED" ]] && [[ "$SPEED" =~ ^[0-9]+\.?[0-9]*$ ]]; then
|
|
378
|
-
# SAPI rate: -10 to 10, 0 is normal. Speed 1.0=0, 2.0=5, 0.5=-5
|
|
379
|
-
rate=$(awk "BEGIN {r = ($SPEED - 1.0) * 10; if (r > 10) r = 10; if (r < -10) r = -10; printf \"%d\", r}")
|
|
380
|
-
fi
|
|
381
|
-
|
|
382
|
-
$ps_cmd -NoProfile -Command "
|
|
383
|
-
Add-Type -AssemblyName System.Speech
|
|
384
|
-
\$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
|
|
385
|
-
\$synth.Rate = $rate
|
|
386
|
-
\$synth.SetOutputToWaveFile('$(wslpath -w "$RAW_WAV" 2>/dev/null || echo "$RAW_WAV")')
|
|
387
|
-
\$synth.Speak('$escaped_text')
|
|
388
|
-
\$synth.Dispose()
|
|
389
|
-
" 2>/dev/null || {
|
|
390
|
-
log_message "ERROR" "Windows SAPI TTS failed"
|
|
391
|
-
echo "Error: Windows SAPI generation failed" >&2
|
|
392
|
-
return 1
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
# Dispatch to the appropriate TTS provider
|
|
397
|
-
case "$PROVIDER" in
|
|
398
|
-
piper)
|
|
399
|
-
_generate_tts_piper || exit 1
|
|
400
|
-
;;
|
|
401
|
-
soprano)
|
|
402
|
-
_generate_tts_soprano || exit 1
|
|
403
|
-
;;
|
|
404
|
-
macos)
|
|
405
|
-
_generate_tts_macos || exit 1
|
|
406
|
-
;;
|
|
407
|
-
windows-sapi)
|
|
408
|
-
_generate_tts_windows_sapi || exit 1
|
|
409
|
-
;;
|
|
410
|
-
*)
|
|
411
|
-
log_message "ERROR" "Unknown provider: $PROVIDER"
|
|
412
|
-
echo "Error: Unknown TTS provider: $PROVIDER" >&2
|
|
413
|
-
exit 1
|
|
414
|
-
;;
|
|
415
|
-
esac
|
|
416
|
-
|
|
417
|
-
PLAY_FILE="$RAW_WAV"
|
|
418
|
-
|
|
419
|
-
# ---------------------------------------------------------------------------
|
|
420
|
-
# Step 2: Apply sox effects (reverb, EQ, etc.)
|
|
421
|
-
# ---------------------------------------------------------------------------
|
|
422
|
-
|
|
423
|
-
if [[ -n "$SOX_EFFECTS" ]] && command -v sox &>/dev/null; then
|
|
424
|
-
# SECURITY: Validate effects contain only safe characters (alphanumeric, spaces, dots, hyphens, underscores)
|
|
425
|
-
if [[ "$SOX_EFFECTS" =~ ^[a-zA-Z0-9\ ._-]+$ ]]; then
|
|
426
|
-
sox "$RAW_WAV" "$EFFECTS_WAV" $SOX_EFFECTS 2>/dev/null && PLAY_FILE="$EFFECTS_WAV"
|
|
427
|
-
else
|
|
428
|
-
log_message "WARN" "Rejected unsafe sox effects: ${SOX_EFFECTS:0:50}"
|
|
429
|
-
fi
|
|
430
|
-
fi
|
|
431
|
-
|
|
432
|
-
# ---------------------------------------------------------------------------
|
|
433
|
-
# Step 3: Mix background music (if configured)
|
|
434
|
-
# ---------------------------------------------------------------------------
|
|
435
|
-
|
|
436
|
-
if [[ -n "$BG_FILE" ]] && command -v ffmpeg &>/dev/null; then
|
|
437
|
-
BG_PATH="$TRACKS_DIR/$BG_FILE"
|
|
438
|
-
if [[ -f "$BG_PATH" ]]; then
|
|
439
|
-
DURATION=$(ffprobe -v error -show_entries format=duration \
|
|
440
|
-
-of default=noprint_wrappers=1:nokey=1 "$PLAY_FILE" 2>/dev/null || echo "")
|
|
441
|
-
if [[ -n "$DURATION" ]]; then
|
|
442
|
-
TOTAL_DUR=$(awk "BEGIN {printf \"%.2f\", $DURATION + 2}")
|
|
443
|
-
FADE_OUT=$(awk "BEGIN {printf \"%.2f\", $DURATION}")
|
|
444
|
-
timeout 20 ffmpeg -y -i "$PLAY_FILE" -stream_loop -1 -i "$BG_PATH" \
|
|
445
|
-
-filter_complex "[1:a]volume=${BG_VOLUME},afade=t=in:st=0:d=0.3,afade=t=out:st=${FADE_OUT}:d=2[bg];[0:a]adelay=1000|1000,volume=1.5[v];[v][bg]amix=inputs=2:duration=longest:normalize=0[out]" \
|
|
446
|
-
-map "[out]" -t "$TOTAL_DUR" "$FINAL_WAV" </dev/null 2>/dev/null && PLAY_FILE="$FINAL_WAV"
|
|
447
|
-
fi
|
|
448
|
-
fi
|
|
449
|
-
fi
|
|
450
|
-
|
|
451
|
-
# ---------------------------------------------------------------------------
|
|
452
|
-
# Step 4: Play audio in foreground (required for SSH — no backgrounding)
|
|
453
|
-
# ---------------------------------------------------------------------------
|
|
454
|
-
|
|
455
|
-
if [[ -z "$AUDIO_PLAYER" ]]; then
|
|
456
|
-
log_message "ERROR" "No audio player found (pw-play, paplay, aplay)"
|
|
457
|
-
echo "Error: No audio player available" >&2
|
|
458
|
-
exit 1
|
|
459
|
-
fi
|
|
460
|
-
|
|
461
|
-
# Save master volume before playback — flat-volumes in PipeWire/PulseAudio
|
|
462
|
-
# can change master volume when a new stream connects from another user.
|
|
463
|
-
_saved_vol=""
|
|
464
|
-
if command -v pactl &>/dev/null; then
|
|
465
|
-
_saved_vol=$(pactl get-sink-volume @DEFAULT_SINK@ 2>/dev/null | grep -o '[0-9]*%' | head -1)
|
|
466
|
-
fi
|
|
467
|
-
|
|
468
|
-
log_message "PLAYING" "player=$AUDIO_PLAYER sink=${_default_sink:-unknown} vol=${_saved_vol:-?} pulse=${PULSE_SERVER:-unset}"
|
|
469
|
-
|
|
470
|
-
_play_err=$($AUDIO_PLAYER "${AUDIO_PLAYER_ARGS[@]}" "$PLAY_FILE" 2>&1) || {
|
|
471
|
-
log_message "ERROR" "Playback failed with $AUDIO_PLAYER: $_play_err"
|
|
472
|
-
echo "Error: Audio playback failed" >&2
|
|
473
|
-
echo "Detail: $_play_err" >&2
|
|
474
|
-
exit 1
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
# Restore master volume to what it was before playback
|
|
478
|
-
if [[ -n "$_saved_vol" ]] && command -v pactl &>/dev/null; then
|
|
479
|
-
pactl set-sink-volume @DEFAULT_SINK@ "$_saved_vol" 2>/dev/null || true
|
|
480
|
-
fi
|
|
481
|
-
|
|
482
|
-
log_message "DONE" ""
|
|
483
|
-
exit 0
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: agentvibes-receiver.sh
|
|
4
|
+
# Location: User installs to ~/.termux/agentvibes-play.sh or ~/.agentvibes/play-remote.sh
|
|
5
|
+
#
|
|
6
|
+
# AgentVibes SSH-TTS Receiver
|
|
7
|
+
# Receives text from remote server via SSH, plays with local AgentVibes
|
|
8
|
+
#
|
|
9
|
+
# Installation:
|
|
10
|
+
# curl -sSL https://raw.githubusercontent.com/paulpreibisch/AgentVibes/main/scripts/install-ssh-receiver.sh | bash
|
|
11
|
+
# OR
|
|
12
|
+
# agentvibes install --ssh-receiver
|
|
13
|
+
#
|
|
14
|
+
# Copyright (c) 2025 Paul Preibisch
|
|
15
|
+
# Licensed under Apache-2.0
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# Handle -- argument separator (skip it if present)
|
|
21
|
+
if [[ "${1:-}" == "--" ]]; then
|
|
22
|
+
shift
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
TEXT="${1:-}"
|
|
26
|
+
VOICE="${2:-en_US-ryan-high}"
|
|
27
|
+
MUSIC="${3:-}"
|
|
28
|
+
REVERB="${4:-}"
|
|
29
|
+
|
|
30
|
+
if [[ -z "$TEXT" ]]; then
|
|
31
|
+
echo "❌ No text provided" >&2
|
|
32
|
+
echo "Usage: $0 [--] <text> [voice] [music] [reverb]" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# SECURITY: If text is base64-encoded (from secure sender), decode it
|
|
37
|
+
# Base64 text won't contain spaces or special chars, so we detect it heuristically
|
|
38
|
+
if [[ "$TEXT" =~ ^[A-Za-z0-9+/]+=*$ ]] && [[ ${#TEXT} -gt 20 ]]; then
|
|
39
|
+
DECODED=$(printf '%s' "$TEXT" | base64 -d 2>/dev/null) || DECODED=""
|
|
40
|
+
if [[ -n "$DECODED" ]]; then
|
|
41
|
+
TEXT="$DECODED"
|
|
42
|
+
fi
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# SECURITY: Validate voice format (alphanumeric, hyphens, underscores only)
|
|
46
|
+
if [[ ! "$VOICE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
47
|
+
echo "❌ Invalid voice format: $VOICE" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Suppress GitHub star reminders (receiver mode)
|
|
52
|
+
export AGENTVIBES_NO_REMINDERS=1
|
|
53
|
+
|
|
54
|
+
# Find AgentVibes installation
|
|
55
|
+
# SECURITY: Uses controlled paths only, validates existence
|
|
56
|
+
find_agentvibes() {
|
|
57
|
+
# Try command lookup first
|
|
58
|
+
if command -v agentvibes >/dev/null 2>&1; then
|
|
59
|
+
local bin_path
|
|
60
|
+
bin_path=$(which agentvibes)
|
|
61
|
+
# Resolve if it's a symlink
|
|
62
|
+
if [[ -L "$bin_path" ]]; then
|
|
63
|
+
bin_path=$(readlink -f "$bin_path" 2>/dev/null || realpath "$bin_path" 2>/dev/null || echo "$bin_path")
|
|
64
|
+
fi
|
|
65
|
+
# SECURITY: Properly quote nested command substitutions
|
|
66
|
+
local lib_path
|
|
67
|
+
lib_path="$(dirname "$(dirname "$bin_path")")/lib/node_modules/agentvibes"
|
|
68
|
+
if [[ -d "$lib_path" ]]; then
|
|
69
|
+
echo "$lib_path"
|
|
70
|
+
return 0
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Check common npm global locations (controlled paths only)
|
|
75
|
+
local search_paths=(
|
|
76
|
+
"$HOME/.npm-global/lib/node_modules/agentvibes"
|
|
77
|
+
"/usr/local/lib/node_modules/agentvibes"
|
|
78
|
+
"/data/data/com.termux/files/usr/lib/node_modules/agentvibes" # Android Termux
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Handle nvm paths separately to avoid glob issues
|
|
82
|
+
if [[ -d "$HOME/.nvm/versions/node" ]]; then
|
|
83
|
+
local nvm_path
|
|
84
|
+
# SECURITY: Use find instead of unsafe glob expansion
|
|
85
|
+
nvm_path=$(find "$HOME/.nvm/versions/node" -maxdepth 3 -type d -name "agentvibes" -path "*/lib/node_modules/*" 2>/dev/null | head -1)
|
|
86
|
+
if [[ -n "$nvm_path" ]] && [[ -d "$nvm_path" ]]; then
|
|
87
|
+
echo "$nvm_path"
|
|
88
|
+
return 0
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
for path in "${search_paths[@]}"; do
|
|
93
|
+
if [[ -d "$path" ]]; then
|
|
94
|
+
echo "$path"
|
|
95
|
+
return 0
|
|
96
|
+
fi
|
|
97
|
+
done
|
|
98
|
+
|
|
99
|
+
return 1
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
AGENTVIBES_ROOT=$(find_agentvibes)
|
|
103
|
+
|
|
104
|
+
if [[ -z "$AGENTVIBES_ROOT" ]]; then
|
|
105
|
+
echo "❌ AgentVibes not found" >&2
|
|
106
|
+
echo "💡 Install: npm install -g agentvibes" >&2
|
|
107
|
+
exit 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
PLAY_TTS="$AGENTVIBES_ROOT/.claude/hooks/play-tts.sh"
|
|
111
|
+
|
|
112
|
+
if [[ ! -f "$PLAY_TTS" ]]; then
|
|
113
|
+
echo "❌ play-tts.sh not found at $PLAY_TTS" >&2
|
|
114
|
+
exit 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Configure audio effects and background music if provided
|
|
118
|
+
# CRITICAL: Write to AGENTVIBES package config, not HOME config
|
|
119
|
+
# The audio-processor reads from package config, not ~/.claude/config
|
|
120
|
+
if [[ -n "$MUSIC" ]] || [[ -n "$REVERB" ]]; then
|
|
121
|
+
CONFIG_DIR="$AGENTVIBES_ROOT/.claude/config"
|
|
122
|
+
mkdir -p "$CONFIG_DIR"
|
|
123
|
+
|
|
124
|
+
# Enable background music
|
|
125
|
+
echo "true" > "$CONFIG_DIR/background-music-enabled.txt"
|
|
126
|
+
|
|
127
|
+
# Clear position cache for fresh start
|
|
128
|
+
rm -f "$CONFIG_DIR/background-music-position.txt"
|
|
129
|
+
|
|
130
|
+
# Set background music track if provided
|
|
131
|
+
if [[ -n "$MUSIC" ]]; then
|
|
132
|
+
echo "$MUSIC" > "$CONFIG_DIR/background-music.txt"
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Set audio effects config (default agent name is always "default")
|
|
136
|
+
if [[ -n "$MUSIC" ]] && [[ -n "$REVERB" ]]; then
|
|
137
|
+
echo "default|${REVERB}|${MUSIC}|0.10" > "$CONFIG_DIR/audio-effects.cfg"
|
|
138
|
+
elif [[ -n "$REVERB" ]]; then
|
|
139
|
+
echo "default|${REVERB}||0.0" > "$CONFIG_DIR/audio-effects.cfg"
|
|
140
|
+
elif [[ -n "$MUSIC" ]]; then
|
|
141
|
+
echo "default||${MUSIC}|0.10" > "$CONFIG_DIR/audio-effects.cfg"
|
|
142
|
+
fi
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Log for debugging (optional, comment out in production)
|
|
146
|
+
if [[ "${AGENTVIBES_DEBUG:-0}" == "1" ]]; then
|
|
147
|
+
echo "[DEBUG] AgentVibes root: $AGENTVIBES_ROOT" >&2
|
|
148
|
+
echo "[DEBUG] Voice: $VOICE" >&2
|
|
149
|
+
echo "[DEBUG] Music: ${MUSIC:-none}" >&2
|
|
150
|
+
echo "[DEBUG] Reverb: ${REVERB:-none}" >&2
|
|
151
|
+
echo "[DEBUG] Text length: ${#TEXT}" >&2
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Generate and play with full AgentVibes features
|
|
155
|
+
echo "🎵 Playing via AgentVibes: ${TEXT:0:50}..." >&2
|
|
156
|
+
bash "$PLAY_TTS" "$TEXT" "$VOICE"
|
|
157
|
+
|
|
158
|
+
exit 0
|
|
File without changes
|