agentvibes 4.0.1 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +3 -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 -389
- 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 -112
- 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 -70
- package/.claude/hooks/play-tts-macos.sh +368 -345
- package/.claude/hooks/play-tts-piper.sh +679 -578
- package/.claude/hooks/play-tts-soprano.sh +356 -320
- package/.claude/hooks/play-tts-ssh-remote.sh +167 -88
- package/.claude/hooks/play-tts-termux-ssh.sh +169 -169
- package/.claude/hooks/play-tts.sh +301 -298
- 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 -71
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +291 -291
- package/.claude/hooks/stop-tts.sh +84 -0
- 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 -114
- package/.claude/hooks/tts-queue.sh +165 -136
- package/.claude/hooks/verbosity-manager.sh +178 -178
- package/.claude/hooks/voice-manager.sh +548 -544
- 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 -181
- package/README.md +2029 -1909
- package/RELEASE_NOTES.md +1310 -66
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +39 -39
- package/bin/agentvibes-voice-browser.js +1840 -1826
- 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 -1417
- package/mcp-server/test_server.py +395 -395
- package/mcp-server/test_windows_script_parity.py +336 -0
- package/package.json +110 -112
- 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 -806
- package/src/console/audio-env.js +20 -1
- package/src/console/brand-colors.js +13 -13
- package/src/console/constants/personalities.js +44 -0
- package/src/console/footer-config.js +50 -46
- package/src/console/modals/modal-overlay.js +247 -247
- package/src/console/navigation.js +62 -61
- package/src/console/tabs/agents-tab.js +1684 -369
- 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 -46
- package/src/console/tabs/readme-tab.js +267 -267
- package/src/console/tabs/receiver-tab.js +1472 -0
- package/src/console/tabs/settings-tab.js +185 -402
- package/src/console/tabs/voices-tab.js +100 -21
- package/src/console/widgets/destroy-list.js +25 -0
- package/src/console/widgets/format-utils.js +89 -0
- package/src/console/widgets/notice.js +55 -0
- package/src/console/widgets/personality-picker.js +185 -0
- package/src/console/widgets/reverb-picker.js +94 -0
- package/src/console/widgets/track-picker.js +285 -0
- package/src/installer/music-file-input.js +304 -304
- package/src/installer.js +5882 -5777
- package/src/services/agent-voice-store.js +423 -163
- package/src/services/config-service.js +264 -264
- package/src/services/navigation-service.js +123 -123
- package/src/services/provider-service.js +132 -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 -275
- 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 -162
- package/templates/audio/welcome-music.mp3 +0 -0
- package/voice-assignments.json +8244 -8244
- package/.claude/config/background-music-position.txt +0 -1
|
@@ -1,114 +1,145 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/tts-queue-worker.sh
|
|
4
|
-
#
|
|
5
|
-
# TTS Queue Worker - Background process that plays queued TTS sequentially
|
|
6
|
-
# Automatically exits when queue is empty for 5 seconds
|
|
7
|
-
|
|
8
|
-
set -euo pipefail
|
|
9
|
-
|
|
10
|
-
# Security: Use secure temp directory with restrictive permissions
|
|
11
|
-
# Must match the logic in tts-queue.sh exactly
|
|
12
|
-
if [[ -n "${XDG_RUNTIME_DIR:-}" ]] && [[ -d "$XDG_RUNTIME_DIR" ]]; then
|
|
13
|
-
QUEUE_DIR="$XDG_RUNTIME_DIR/agentvibes-tts-queue"
|
|
14
|
-
else
|
|
15
|
-
# Fallback to user-specific temp directory
|
|
16
|
-
QUEUE_DIR="/tmp/agentvibes-tts-queue-$
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
# Security: Validate queue directory exists and has correct ownership
|
|
20
|
-
if [[ ! -d "$QUEUE_DIR" ]]; then
|
|
21
|
-
echo "Error: Queue directory does not exist: $QUEUE_DIR" >&2
|
|
22
|
-
exit 1
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
# Security: Verify we own the queue directory (prevent symlink attacks)
|
|
26
|
-
if [[ "$(stat -c '%u' "$QUEUE_DIR" 2>/dev/null || stat -f '%u' "$QUEUE_DIR" 2>/dev/null)" != "$(id -u)" ]]; then
|
|
27
|
-
echo "Error: Queue directory not owned by current user" >&2
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
WORKER_PID_FILE="$QUEUE_DIR/worker.pid"
|
|
32
|
-
IDLE_TIMEOUT=5 # Exit after 5 seconds of no new requests
|
|
33
|
-
|
|
34
|
-
# Get script directory
|
|
35
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
36
|
-
|
|
37
|
-
# Configurable delay between speakers (seconds)
|
|
38
|
-
# Can be overridden by .claude/tts-speaker-delay.txt or ~/.claude/tts-speaker-delay.txt
|
|
39
|
-
SPEAKER_DELAY=4 # Default: 4 seconds between speakers
|
|
40
|
-
|
|
41
|
-
# Check for custom delay configuration
|
|
42
|
-
if [[ -f ".claude/tts-speaker-delay.txt" ]]; then
|
|
43
|
-
CUSTOM_DELAY=$(cat .claude/tts-speaker-delay.txt 2>/dev/null | tr -d '[:space:]')
|
|
44
|
-
if [[ "$CUSTOM_DELAY" =~ ^[0-9]+$ ]]; then
|
|
45
|
-
SPEAKER_DELAY=$CUSTOM_DELAY
|
|
46
|
-
fi
|
|
47
|
-
elif [[ -f "$HOME/.claude/tts-speaker-delay.txt" ]]; then
|
|
48
|
-
CUSTOM_DELAY=$(cat "$HOME/.claude/tts-speaker-delay.txt" 2>/dev/null | tr -d '[:space:]')
|
|
49
|
-
if [[ "$CUSTOM_DELAY" =~ ^[0-9]+$ ]]; then
|
|
50
|
-
SPEAKER_DELAY=$CUSTOM_DELAY
|
|
51
|
-
fi
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
# Trap to clean up on exit
|
|
55
|
-
trap 'rm -f "$WORKER_PID_FILE"' EXIT
|
|
56
|
-
|
|
57
|
-
# Process queue items
|
|
58
|
-
process_queue() {
|
|
59
|
-
local idle_count=0
|
|
60
|
-
|
|
61
|
-
while true; do
|
|
62
|
-
# Find oldest queue item
|
|
63
|
-
local queue_item=$(ls -1 "$QUEUE_DIR"/*.queue 2>/dev/null | sort | head -1)
|
|
64
|
-
|
|
65
|
-
if [[ -z "$queue_item" ]]; then
|
|
66
|
-
# Queue is empty, increment idle counter
|
|
67
|
-
idle_count=$((idle_count + 1))
|
|
68
|
-
|
|
69
|
-
if [[ $idle_count -ge $IDLE_TIMEOUT ]]; then
|
|
70
|
-
# No new items for timeout period, exit worker
|
|
71
|
-
exit 0
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# Wait
|
|
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
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/tts-queue-worker.sh
|
|
4
|
+
#
|
|
5
|
+
# TTS Queue Worker - Background process that plays queued TTS sequentially
|
|
6
|
+
# Automatically exits when queue is empty for 5 seconds
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Security: Use secure temp directory with restrictive permissions
|
|
11
|
+
# Must match the logic in tts-queue.sh exactly
|
|
12
|
+
if [[ -n "${XDG_RUNTIME_DIR:-}" ]] && [[ -d "$XDG_RUNTIME_DIR" ]]; then
|
|
13
|
+
QUEUE_DIR="$XDG_RUNTIME_DIR/agentvibes-tts-queue"
|
|
14
|
+
else
|
|
15
|
+
# Fallback to user-specific temp directory
|
|
16
|
+
QUEUE_DIR="/tmp/agentvibes-tts-queue-$(id -u)"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Security: Validate queue directory exists and has correct ownership
|
|
20
|
+
if [[ ! -d "$QUEUE_DIR" ]]; then
|
|
21
|
+
echo "Error: Queue directory does not exist: $QUEUE_DIR" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Security: Verify we own the queue directory (prevent symlink attacks)
|
|
26
|
+
if [[ "$(stat -c '%u' "$QUEUE_DIR" 2>/dev/null || stat -f '%u' "$QUEUE_DIR" 2>/dev/null)" != "$(id -u)" ]]; then
|
|
27
|
+
echo "Error: Queue directory not owned by current user" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
WORKER_PID_FILE="$QUEUE_DIR/worker.pid"
|
|
32
|
+
IDLE_TIMEOUT=5 # Exit after 5 seconds of no new requests
|
|
33
|
+
|
|
34
|
+
# Get script directory
|
|
35
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
36
|
+
|
|
37
|
+
# Configurable delay between speakers (seconds)
|
|
38
|
+
# Can be overridden by .claude/tts-speaker-delay.txt or ~/.claude/tts-speaker-delay.txt
|
|
39
|
+
SPEAKER_DELAY=4 # Default: 4 seconds between speakers
|
|
40
|
+
|
|
41
|
+
# Check for custom delay configuration
|
|
42
|
+
if [[ -f ".claude/tts-speaker-delay.txt" ]]; then
|
|
43
|
+
CUSTOM_DELAY=$(cat .claude/tts-speaker-delay.txt 2>/dev/null | tr -d '[:space:]')
|
|
44
|
+
if [[ "$CUSTOM_DELAY" =~ ^[0-9]+$ ]]; then
|
|
45
|
+
SPEAKER_DELAY=$CUSTOM_DELAY
|
|
46
|
+
fi
|
|
47
|
+
elif [[ -f "$HOME/.claude/tts-speaker-delay.txt" ]]; then
|
|
48
|
+
CUSTOM_DELAY=$(cat "$HOME/.claude/tts-speaker-delay.txt" 2>/dev/null | tr -d '[:space:]')
|
|
49
|
+
if [[ "$CUSTOM_DELAY" =~ ^[0-9]+$ ]]; then
|
|
50
|
+
SPEAKER_DELAY=$CUSTOM_DELAY
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Trap to clean up on exit
|
|
55
|
+
trap 'rm -f "$WORKER_PID_FILE"' EXIT
|
|
56
|
+
|
|
57
|
+
# Process queue items
|
|
58
|
+
process_queue() {
|
|
59
|
+
local idle_count=0
|
|
60
|
+
|
|
61
|
+
while true; do
|
|
62
|
+
# Find oldest queue item
|
|
63
|
+
local queue_item=$(ls -1 "$QUEUE_DIR"/*.queue 2>/dev/null | sort | head -1)
|
|
64
|
+
|
|
65
|
+
if [[ -z "$queue_item" ]]; then
|
|
66
|
+
# Queue is empty, increment idle counter
|
|
67
|
+
idle_count=$((idle_count + 1))
|
|
68
|
+
|
|
69
|
+
if [[ $idle_count -ge $IDLE_TIMEOUT ]]; then
|
|
70
|
+
# No new items for timeout period, exit worker
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Wait for a new queue item — use inotifywait if available to avoid polling
|
|
75
|
+
# Use a 1-second timeout (-t 1) so the idle counter still advances correctly
|
|
76
|
+
if command -v inotifywait &>/dev/null; then
|
|
77
|
+
inotifywait -q -e create -t 1 "$QUEUE_DIR" 2>/dev/null || true
|
|
78
|
+
else
|
|
79
|
+
sleep 1
|
|
80
|
+
fi
|
|
81
|
+
continue
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Reset idle counter - we have work
|
|
85
|
+
idle_count=0
|
|
86
|
+
|
|
87
|
+
# Load queue item — explicit key=value parsing (SECURITY: never source untrusted files)
|
|
88
|
+
TEXT_FILE=""
|
|
89
|
+
VOICE=""
|
|
90
|
+
AGENT=""
|
|
91
|
+
PROFILE_PATH=""
|
|
92
|
+
PLAY_WAV=""
|
|
93
|
+
while IFS='=' read -r _key _val; do
|
|
94
|
+
case "$_key" in
|
|
95
|
+
TEXT_FILE) TEXT_FILE="$_val" ;;
|
|
96
|
+
VOICE) VOICE="$_val" ;;
|
|
97
|
+
AGENT) AGENT="$_val" ;;
|
|
98
|
+
PROFILE_PATH) PROFILE_PATH="$_val" ;;
|
|
99
|
+
PLAY_WAV) PLAY_WAV="$_val" ;;
|
|
100
|
+
esac
|
|
101
|
+
done < "$queue_item"
|
|
102
|
+
|
|
103
|
+
# Check if this is a pre-generated WAV playback item
|
|
104
|
+
if [[ -n "${PLAY_WAV:-}" ]] && [[ -f "$PLAY_WAV" ]]; then
|
|
105
|
+
# Play the pre-generated WAV directly (synthesis already done by bmad-speak)
|
|
106
|
+
if command -v paplay &>/dev/null; then
|
|
107
|
+
paplay "$PLAY_WAV" 2>/dev/null || true
|
|
108
|
+
elif command -v aplay &>/dev/null; then
|
|
109
|
+
aplay -q "$PLAY_WAV" 2>/dev/null || true
|
|
110
|
+
elif command -v ffplay &>/dev/null; then
|
|
111
|
+
ffplay -nodisp -autoexit -loglevel quiet "$PLAY_WAV" 2>/dev/null || true
|
|
112
|
+
fi
|
|
113
|
+
else
|
|
114
|
+
# Full TTS request — read text from companion file, use voice/agent directly
|
|
115
|
+
TEXT=""
|
|
116
|
+
if [[ -n "${TEXT_FILE:-}" ]] && [[ -f "$TEXT_FILE" ]]; then
|
|
117
|
+
TEXT=$(cat "$TEXT_FILE")
|
|
118
|
+
rm -f "$TEXT_FILE"
|
|
119
|
+
fi
|
|
120
|
+
AGENT_PROFILE="${PROFILE_PATH:-}"
|
|
121
|
+
|
|
122
|
+
export AGENTVIBES_AGENT_PROFILE="$AGENT_PROFILE"
|
|
123
|
+
|
|
124
|
+
if [[ -n "${VOICE:-}" ]]; then
|
|
125
|
+
bash "$SCRIPT_DIR/play-tts.sh" "$TEXT" "${VOICE}" || true
|
|
126
|
+
else
|
|
127
|
+
bash "$SCRIPT_DIR/play-tts.sh" "$TEXT" || true
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
if [[ -n "$AGENT_PROFILE" ]] && [[ -f "$AGENT_PROFILE" ]]; then
|
|
131
|
+
rm -f "$AGENT_PROFILE"
|
|
132
|
+
fi
|
|
133
|
+
unset AGENTVIBES_AGENT_PROFILE
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# Add configurable pause between speakers for natural conversation flow
|
|
137
|
+
sleep $SPEAKER_DELAY
|
|
138
|
+
|
|
139
|
+
# Remove processed item and any companion text file
|
|
140
|
+
rm -f "$queue_item" "${queue_item%.queue}.txt"
|
|
141
|
+
done
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# Start processing
|
|
145
|
+
process_queue
|
|
@@ -1,136 +1,165 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# File: .claude/hooks/tts-queue.sh
|
|
4
|
-
#
|
|
5
|
-
# TTS Queue Manager for Party Mode
|
|
6
|
-
# Queues TTS requests and plays them sequentially in the background
|
|
7
|
-
# This allows Claude to continue generating responses while audio plays in order
|
|
8
|
-
|
|
9
|
-
set -euo pipefail
|
|
10
|
-
|
|
11
|
-
# Security: Use secure temp directory with restrictive permissions
|
|
12
|
-
# Check if XDG_RUNTIME_DIR is available (more secure than /tmp)
|
|
13
|
-
if [[ -n "${XDG_RUNTIME_DIR:-}" ]] && [[ -d "$XDG_RUNTIME_DIR" ]]; then
|
|
14
|
-
QUEUE_DIR="$XDG_RUNTIME_DIR/agentvibes-tts-queue"
|
|
15
|
-
else
|
|
16
|
-
# Fallback to user-specific temp directory
|
|
17
|
-
QUEUE_DIR="/tmp/agentvibes-tts-queue-$
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
QUEUE_LOCK="$QUEUE_DIR/queue.lock"
|
|
21
|
-
WORKER_PID_FILE="$QUEUE_DIR/worker.pid"
|
|
22
|
-
|
|
23
|
-
# Get script directory
|
|
24
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
25
|
-
|
|
26
|
-
# Initialize queue directory with restrictive permissions
|
|
27
|
-
if [[ ! -d "$QUEUE_DIR" ]]; then
|
|
28
|
-
mkdir -p "$QUEUE_DIR"
|
|
29
|
-
chmod 700 "$QUEUE_DIR" # Only owner can read/write/execute
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# @function add_to_queue
|
|
33
|
-
# @intent Add a TTS request to the queue for sequential playback
|
|
34
|
-
# @param $1 dialogue text
|
|
35
|
-
# @param $2 voice name (optional)
|
|
36
|
-
# @param $3 agent name (optional, for background music in party mode)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
local
|
|
40
|
-
local
|
|
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
|
-
if
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/tts-queue.sh
|
|
4
|
+
#
|
|
5
|
+
# TTS Queue Manager for Party Mode
|
|
6
|
+
# Queues TTS requests and plays them sequentially in the background
|
|
7
|
+
# This allows Claude to continue generating responses while audio plays in order
|
|
8
|
+
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
# Security: Use secure temp directory with restrictive permissions
|
|
12
|
+
# Check if XDG_RUNTIME_DIR is available (more secure than /tmp)
|
|
13
|
+
if [[ -n "${XDG_RUNTIME_DIR:-}" ]] && [[ -d "$XDG_RUNTIME_DIR" ]]; then
|
|
14
|
+
QUEUE_DIR="$XDG_RUNTIME_DIR/agentvibes-tts-queue"
|
|
15
|
+
else
|
|
16
|
+
# Fallback to user-specific temp directory
|
|
17
|
+
QUEUE_DIR="/tmp/agentvibes-tts-queue-$(id -u)"
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
QUEUE_LOCK="$QUEUE_DIR/queue.lock"
|
|
21
|
+
WORKER_PID_FILE="$QUEUE_DIR/worker.pid"
|
|
22
|
+
|
|
23
|
+
# Get script directory
|
|
24
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
25
|
+
|
|
26
|
+
# Initialize queue directory with restrictive permissions
|
|
27
|
+
if [[ ! -d "$QUEUE_DIR" ]]; then
|
|
28
|
+
mkdir -p "$QUEUE_DIR"
|
|
29
|
+
chmod 700 "$QUEUE_DIR" # Only owner can read/write/execute
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# @function add_to_queue
|
|
33
|
+
# @intent Add a TTS request to the queue for sequential playback
|
|
34
|
+
# @param $1 dialogue text
|
|
35
|
+
# @param $2 voice name (optional)
|
|
36
|
+
# @param $3 agent name (optional, for background music in party mode)
|
|
37
|
+
# @param $4 agent profile path (optional, PID-scoped temp JSON with reverb/personality/music overrides)
|
|
38
|
+
add_to_queue() {
|
|
39
|
+
local text="$1"
|
|
40
|
+
local voice="${2:-}"
|
|
41
|
+
local agent="${3:-default}"
|
|
42
|
+
local profile_path="${4:-}"
|
|
43
|
+
|
|
44
|
+
# Create unique queue item with timestamp
|
|
45
|
+
local timestamp=$(date +%s%N)
|
|
46
|
+
local queue_file="$QUEUE_DIR/$timestamp.queue"
|
|
47
|
+
|
|
48
|
+
# Write request to queue file using direct storage
|
|
49
|
+
# Text is stored in a separate .txt file (handles newlines and special chars safely)
|
|
50
|
+
# Voice and agent are simple identifiers with no special chars
|
|
51
|
+
printf '%s' "$text" > "${queue_file%.queue}.txt"
|
|
52
|
+
cat > "$queue_file" <<EOF
|
|
53
|
+
TEXT_FILE=${queue_file%.queue}.txt
|
|
54
|
+
VOICE=$voice
|
|
55
|
+
AGENT=$agent
|
|
56
|
+
PROFILE_PATH=$profile_path
|
|
57
|
+
EOF
|
|
58
|
+
|
|
59
|
+
# Start queue worker if not already running
|
|
60
|
+
start_worker_if_needed
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# @function start_worker_if_needed
|
|
64
|
+
# @intent Start the queue worker process if it's not already running
|
|
65
|
+
start_worker_if_needed() {
|
|
66
|
+
# Security: Use file locking to prevent race condition
|
|
67
|
+
# Open file descriptor 200 for locking
|
|
68
|
+
exec 200>"$QUEUE_LOCK"
|
|
69
|
+
|
|
70
|
+
# Acquire exclusive lock (flock -x) with timeout
|
|
71
|
+
if ! flock -x -w 5 200; then
|
|
72
|
+
echo "Warning: Could not acquire queue lock" >&2
|
|
73
|
+
return 1
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Check if worker is already running (within lock)
|
|
77
|
+
if [[ -f "$WORKER_PID_FILE" ]]; then
|
|
78
|
+
local pid=$(cat "$WORKER_PID_FILE")
|
|
79
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
80
|
+
# Worker is running, release lock and return
|
|
81
|
+
flock -u 200
|
|
82
|
+
exec 200>&-
|
|
83
|
+
return 0
|
|
84
|
+
fi
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Start worker in background
|
|
88
|
+
"$SCRIPT_DIR/tts-queue-worker.sh" &
|
|
89
|
+
local worker_pid=$!
|
|
90
|
+
echo $worker_pid > "$WORKER_PID_FILE"
|
|
91
|
+
|
|
92
|
+
# Release lock
|
|
93
|
+
flock -u 200
|
|
94
|
+
exec 200>&-
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# @function clear_queue
|
|
98
|
+
# @intent Clear all pending TTS requests (emergency stop)
|
|
99
|
+
clear_queue() {
|
|
100
|
+
rm -f "$QUEUE_DIR"/*.queue
|
|
101
|
+
echo "✅ Queue cleared"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# @function show_queue
|
|
105
|
+
# @intent Display current queue status
|
|
106
|
+
show_queue() {
|
|
107
|
+
local count=$(ls -1 "$QUEUE_DIR"/*.queue 2>/dev/null | wc -l)
|
|
108
|
+
echo "📊 Queue status: $count items pending"
|
|
109
|
+
|
|
110
|
+
if [[ -f "$WORKER_PID_FILE" ]]; then
|
|
111
|
+
local pid=$(cat "$WORKER_PID_FILE")
|
|
112
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
113
|
+
echo "✅ Worker process running (PID: $pid)"
|
|
114
|
+
else
|
|
115
|
+
echo "❌ Worker process not running"
|
|
116
|
+
fi
|
|
117
|
+
else
|
|
118
|
+
echo "❌ Worker process not running"
|
|
119
|
+
fi
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# @function play_wav
|
|
123
|
+
# @intent Queue a pre-generated WAV file for sequential playback
|
|
124
|
+
# @param $1 path to WAV file
|
|
125
|
+
play_wav() {
|
|
126
|
+
local wav_file="$1"
|
|
127
|
+
[[ -z "$wav_file" ]] && return 1
|
|
128
|
+
[[ ! -f "$wav_file" ]] && return 1
|
|
129
|
+
|
|
130
|
+
local timestamp=$(date +%s%N)
|
|
131
|
+
local queue_file="$QUEUE_DIR/$timestamp.queue"
|
|
132
|
+
|
|
133
|
+
# Write a playback-only queue item (no synthesis needed)
|
|
134
|
+
cat > "$queue_file" <<EOF
|
|
135
|
+
PLAY_WAV=$wav_file
|
|
136
|
+
EOF
|
|
137
|
+
|
|
138
|
+
start_worker_if_needed
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
# Main command dispatcher
|
|
142
|
+
case "${1:-help}" in
|
|
143
|
+
add)
|
|
144
|
+
add_to_queue "${2:-}" "${3:-}" "${4:-default}" "${5:-}"
|
|
145
|
+
;;
|
|
146
|
+
play)
|
|
147
|
+
play_wav "${2:-}"
|
|
148
|
+
;;
|
|
149
|
+
clear)
|
|
150
|
+
clear_queue
|
|
151
|
+
;;
|
|
152
|
+
status)
|
|
153
|
+
show_queue
|
|
154
|
+
;;
|
|
155
|
+
*)
|
|
156
|
+
echo "Usage: tts-queue.sh {add|play|clear|status}"
|
|
157
|
+
echo ""
|
|
158
|
+
echo "Commands:"
|
|
159
|
+
echo " add <text> [voice] [agent] Add TTS request to queue"
|
|
160
|
+
echo " play <wav_file> Queue a pre-generated WAV for playback"
|
|
161
|
+
echo " clear Clear all pending requests"
|
|
162
|
+
echo " status Show queue status"
|
|
163
|
+
exit 1
|
|
164
|
+
;;
|
|
165
|
+
esac
|