agentvibes 2.0.20 → 2.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/health-coach.md +154 -0
- package/.claude/agents/motivator.md +171 -0
- package/.claude/agents/negotiator.md +97 -0
- package/.claude/commands/agent-vibes/agent-health-coach.md +15 -0
- package/.claude/commands/agent-vibes/agent-motivator.md +15 -0
- package/.claude/commands/agent-vibes/agent-negotiator.md +15 -0
- package/.claude/commands/agent-vibes/agent.md +79 -0
- package/.claude/commands/agent-vibes/commands.json +4 -0
- package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -0
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/download-extra-voices.sh +244 -0
- package/.claude/hooks/personality-manager.sh +81 -0
- package/.claude/hooks/piper-download-voices.sh +3 -93
- package/.claude/hooks/piper-multispeaker-registry.sh +165 -0
- package/.claude/hooks/play-tts-elevenlabs.sh +5 -3
- package/.claude/hooks/play-tts-piper.sh +27 -44
- package/.claude/hooks/provider-manager.sh +24 -5
- package/.claude/hooks/speed-manager.sh +10 -12
- package/.claude/hooks/voice-manager.sh +94 -56
- package/README.md +0 -3
- package/RELEASE_NOTES.md +40 -247
- package/docs/agents.md +485 -0
- package/docs/commands.md +1 -21
- package/docs/extra-voices-implementation-summary.md +235 -0
- package/docs/voice-registration-fix.md +254 -0
- package/fix-vscode-colors.sh +88 -0
- package/fixcolors +88 -0
- package/generate-all-agent-voices.sh +174 -0
- package/generate-missing-elevenlabs-complete.sh +236 -0
- package/generate-missing-elevenlabs.sh +110 -0
- package/generate-new-voices.sh +108 -0
- package/generate-piper-agent-intros.sh +85 -0
- package/generate-provider-and-agent-intros.sh +136 -0
- package/logo/fav_icon_128x128.png +0 -0
- package/logo/fav_icon_128x128.png:Zone.Identifier +4 -0
- package/logo/logo1.webp +0 -0
- package/logo/logo1.webp:Zone.Identifier +4 -0
- package/logo/social.png +0 -0
- package/logo/social.png:Zone.Identifier +4 -0
- package/mcp-server/agentvibes.db +0 -0
- package/mcp-server/server.py +47 -14
- package/package.json +3 -3
- package/regenerate-agent-voices.sh +79 -0
- package/test/unit/provider-manager.bats +8 -5
- package/test/unit/speed-manager.bats +4 -4
- package/agentvibes.org/.claude/audio/tts-padded-1760744118.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760748535.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760748676.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760750748.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760750947.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760752718.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760752907.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753017.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753045.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753241.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753315.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753382.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753408.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753426.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753446.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753541.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753553.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753577.mp3 +0 -0
- package/agentvibes.org/.claude/commands/agent-vibes/add.md +0 -21
- package/agentvibes.org/.claude/commands/agent-vibes/agent-vibes.md +0 -68
- package/agentvibes.org/.claude/commands/agent-vibes/bmad.md +0 -196
- package/agentvibes.org/.claude/commands/agent-vibes/commands.json +0 -77
- package/agentvibes.org/.claude/commands/agent-vibes/get.md +0 -9
- package/agentvibes.org/.claude/commands/agent-vibes/language.md +0 -23
- package/agentvibes.org/.claude/commands/agent-vibes/learn.md +0 -67
- package/agentvibes.org/.claude/commands/agent-vibes/list.md +0 -13
- package/agentvibes.org/.claude/commands/agent-vibes/personality.md +0 -79
- package/agentvibes.org/.claude/commands/agent-vibes/preview.md +0 -17
- package/agentvibes.org/.claude/commands/agent-vibes/provider.md +0 -54
- package/agentvibes.org/.claude/commands/agent-vibes/replay-target.md +0 -14
- package/agentvibes.org/.claude/commands/agent-vibes/replay.md +0 -19
- package/agentvibes.org/.claude/commands/agent-vibes/sample.md +0 -12
- package/agentvibes.org/.claude/commands/agent-vibes/sentiment.md +0 -52
- package/agentvibes.org/.claude/commands/agent-vibes/set-language.md +0 -47
- package/agentvibes.org/.claude/commands/agent-vibes/set-pretext.md +0 -65
- package/agentvibes.org/.claude/commands/agent-vibes/set-speed.md +0 -41
- package/agentvibes.org/.claude/commands/agent-vibes/switch.md +0 -53
- package/agentvibes.org/.claude/commands/agent-vibes/target-voice.md +0 -26
- package/agentvibes.org/.claude/commands/agent-vibes/target.md +0 -30
- package/agentvibes.org/.claude/commands/agent-vibes/update.md +0 -20
- package/agentvibes.org/.claude/commands/agent-vibes/version.md +0 -10
- package/agentvibes.org/.claude/commands/agent-vibes/whoami.md +0 -7
- package/agentvibes.org/.claude/hooks/bmad-tts-injector.sh +0 -386
- package/agentvibes.org/.claude/hooks/bmad-voice-manager.sh +0 -375
- package/agentvibes.org/.claude/hooks/check-output-style.sh +0 -60
- package/agentvibes.org/.claude/hooks/github-star-reminder.sh +0 -94
- package/agentvibes.org/.claude/hooks/language-manager.sh +0 -360
- package/agentvibes.org/.claude/hooks/learn-manager.sh +0 -443
- package/agentvibes.org/.claude/hooks/personality-manager.sh +0 -324
- package/agentvibes.org/.claude/hooks/piper-download-voices.sh +0 -133
- package/agentvibes.org/.claude/hooks/piper-installer.sh +0 -144
- package/agentvibes.org/.claude/hooks/piper-voice-manager.sh +0 -227
- package/agentvibes.org/.claude/hooks/play-tts-elevenlabs.sh +0 -376
- package/agentvibes.org/.claude/hooks/play-tts-piper.sh +0 -281
- package/agentvibes.org/.claude/hooks/play-tts.sh +0 -69
- package/agentvibes.org/.claude/hooks/provider-commands.sh +0 -505
- package/agentvibes.org/.claude/hooks/provider-manager.sh +0 -248
- package/agentvibes.org/.claude/hooks/replay-target-audio.sh +0 -64
- package/agentvibes.org/.claude/hooks/sentiment-manager.sh +0 -163
- package/agentvibes.org/.claude/hooks/speed-manager.sh +0 -259
- package/agentvibes.org/.claude/hooks/voice-manager.sh +0 -477
- package/agentvibes.org/.claude/hooks/voices-config.sh +0 -33
- package/agentvibes.org/.claude/journal/2025-10-07.html +0 -373
- package/agentvibes.org/.claude/journal/index.html +0 -91
- package/agentvibes.org/.claude/output-styles/agent-vibes.md +0 -203
- package/agentvibes.org/.claude/personalities/angry.md +0 -17
- package/agentvibes.org/.claude/personalities/annoying.md +0 -17
- package/agentvibes.org/.claude/personalities/crass.md +0 -17
- package/agentvibes.org/.claude/personalities/dramatic.md +0 -17
- package/agentvibes.org/.claude/personalities/dry-humor.md +0 -53
- package/agentvibes.org/.claude/personalities/flirty.md +0 -23
- package/agentvibes.org/.claude/personalities/funny.md +0 -17
- package/agentvibes.org/.claude/personalities/grandpa.md +0 -35
- package/agentvibes.org/.claude/personalities/millennial.md +0 -17
- package/agentvibes.org/.claude/personalities/moody.md +0 -17
- package/agentvibes.org/.claude/personalities/normal.md +0 -19
- package/agentvibes.org/.claude/personalities/pirate.md +0 -17
- package/agentvibes.org/.claude/personalities/poetic.md +0 -17
- package/agentvibes.org/.claude/personalities/professional.md +0 -17
- package/agentvibes.org/.claude/personalities/robot.md +0 -17
- package/agentvibes.org/.claude/personalities/sarcastic.md +0 -41
- package/agentvibes.org/.claude/personalities/sassy.md +0 -17
- package/agentvibes.org/.claude/personalities/surfer-dude.md +0 -17
- package/agentvibes.org/.claude/personalities/zen.md +0 -17
- package/agentvibes.org/.claude/piper-voices-dir.txt +0 -1
- package/agentvibes.org/.claude/plugins/bmad-voices.md +0 -42
- package/agentvibes.org/.claude/tts-provider.txt +0 -1
- package/agentvibes.org/.mcp-minimal.json +0 -60
- package/agentvibes.org/CHANGELOG.md +0 -56
- package/agentvibes.org/README.md +0 -93
- package/agentvibes.org/app/(auth)/layout.tsx +0 -15
- package/agentvibes.org/app/(auth)/reset-password/page.tsx +0 -45
- package/agentvibes.org/app/(auth)/signin/page.tsx +0 -82
- package/agentvibes.org/app/(auth)/signup/page.tsx +0 -104
- package/agentvibes.org/app/(default)/blog/[slug]/page.tsx +0 -128
- package/agentvibes.org/app/(default)/blog/page.tsx +0 -95
- package/agentvibes.org/app/(default)/layout.tsx +0 -31
- package/agentvibes.org/app/(default)/page.tsx +0 -20
- package/agentvibes.org/app/api/hello/route.ts +0 -3
- package/agentvibes.org/app/css/additional-styles/theme.css +0 -82
- package/agentvibes.org/app/css/additional-styles/utility-patterns.css +0 -55
- package/agentvibes.org/app/css/style.css +0 -100
- package/agentvibes.org/app/layout.tsx +0 -63
- package/agentvibes.org/components/code-block.tsx +0 -27
- package/agentvibes.org/components/cta.tsx +0 -58
- package/agentvibes.org/components/features.tsx +0 -256
- package/agentvibes.org/components/hero-home.tsx +0 -133
- package/agentvibes.org/components/mdx-components.tsx +0 -128
- package/agentvibes.org/components/modal-video.tsx +0 -137
- package/agentvibes.org/components/page-illustration.tsx +0 -55
- package/agentvibes.org/components/spotlight.tsx +0 -77
- package/agentvibes.org/components/testimonials.tsx +0 -282
- package/agentvibes.org/components/ui/footer.tsx +0 -82
- package/agentvibes.org/components/ui/header.tsx +0 -68
- package/agentvibes.org/components/ui/logo.tsx +0 -10
- package/agentvibes.org/components/workflows.tsx +0 -176
- package/agentvibes.org/content/blog/discovering-new-piper-voices.mdx +0 -253
- package/agentvibes.org/content/blog/getting-started-agentvibes.mdx +0 -228
- package/agentvibes.org/content/blog/introducing-agentvibes-v2.mdx +0 -250
- package/agentvibes.org/content/blog/language-learning-with-agentvibes.mdx +0 -142
- package/agentvibes.org/content/blog/voice-personalities-guide.mdx +0 -119
- package/agentvibes.org/lib/blog.ts +0 -73
- package/agentvibes.org/next.config.js +0 -6
- package/agentvibes.org/package-lock.json +0 -4285
- package/agentvibes.org/package.json +0 -40
- package/agentvibes.org/pnpm-lock.yaml +0 -1141
- package/agentvibes.org/postcss.config.js +0 -5
- package/agentvibes.org/public/audio/02-sarcastic.mp3 +0 -0
- package/agentvibes.org/public/audio/03-angry.mp3 +0 -0
- package/agentvibes.org/public/audio/04-grandpa.mp3 +0 -0
- package/agentvibes.org/public/audio/05-sarcastic-example2.mp3 +0 -0
- package/agentvibes.org/public/audio/french-rachel.mp3 +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_0_Cori_Samuel.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_10_Steve_C.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_11_Owlivia.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_12_Paul_Hampton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_13_Jennifer_Dorr.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_14_Emily_Cripps.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_15_Martin_Clifton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_1_Kara_Shallenberg.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_2_Kristin_Hughes.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_3_Maria_Kasper.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_4_Mike_Pelton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_5_Mark_Nelson.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_6_Michael_Scherer.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_7_James_K_White.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_8_Rose_Ibex.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_9_progressingamerica.wav +0 -0
- package/agentvibes.org/public/audio/spanish-antoni.mp3 +0 -0
- package/agentvibes.org/public/favicon.ico +0 -0
- package/agentvibes.org/public/fonts/nacelle-italic.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-regular.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibold.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibolditalic.woff2 +0 -0
- package/agentvibes.org/public/images/blurred-shape-gray.svg +0 -1
- package/agentvibes.org/public/images/blurred-shape.svg +0 -1
- package/agentvibes.org/public/images/client-logo-01.svg +0 -1
- package/agentvibes.org/public/images/client-logo-02.svg +0 -1
- package/agentvibes.org/public/images/client-logo-03.svg +0 -1
- package/agentvibes.org/public/images/client-logo-04.svg +0 -1
- package/agentvibes.org/public/images/client-logo-05.svg +0 -1
- package/agentvibes.org/public/images/client-logo-06.svg +0 -1
- package/agentvibes.org/public/images/client-logo-07.svg +0 -1
- package/agentvibes.org/public/images/client-logo-08.svg +0 -1
- package/agentvibes.org/public/images/client-logo-09.svg +0 -1
- package/agentvibes.org/public/images/features.png +0 -0
- package/agentvibes.org/public/images/footer-illustration.svg +0 -1
- package/agentvibes.org/public/images/hero-image-01.jpg +0 -0
- package/agentvibes.org/public/images/logo.svg +0 -1
- package/agentvibes.org/public/images/page-illustration.svg +0 -1
- package/agentvibes.org/public/images/secondary-illustration.svg +0 -1
- package/agentvibes.org/public/images/testimonial-01.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-02.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-03.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-04.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-05.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-06.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-07.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-08.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-09.jpg +0 -0
- package/agentvibes.org/public/images/workflow-01.png +0 -0
- package/agentvibes.org/public/images/workflow-02.png +0 -0
- package/agentvibes.org/public/images/workflow-03.png +0 -0
- package/agentvibes.org/public/videos/video.mp4 +0 -0
- package/agentvibes.org/tsconfig.json +0 -28
- package/agentvibes.org/utils/useMasonry.tsx +0 -67
- package/agentvibes.org/utils/useMousePosition.tsx +0 -27
- package/docs/bryce-beattie-voice-licensing.md +0 -131
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# @fileoverview Piper TTS Provider Implementation
|
|
4
|
-
# @context Free, offline neural TTS for WSL/Linux
|
|
5
|
-
# @architecture Implements provider contract for Piper binary
|
|
6
|
-
# @dependencies piper (pipx), piper-voice-manager.sh, mpv/aplay
|
|
7
|
-
# @entrypoints Called by play-tts.sh router
|
|
8
|
-
# @patterns Provider contract: text/voice → audio file path
|
|
9
|
-
# @related play-tts.sh, piper-voice-manager.sh, GitHub Issue #25
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
# Fix locale warnings
|
|
13
|
-
export LC_ALL=C
|
|
14
|
-
|
|
15
|
-
TEXT="$1"
|
|
16
|
-
VOICE_OVERRIDE="$2" # Optional: voice model name
|
|
17
|
-
|
|
18
|
-
# Source voice manager and language manager
|
|
19
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
-
source "$SCRIPT_DIR/piper-voice-manager.sh"
|
|
21
|
-
source "$SCRIPT_DIR/language-manager.sh"
|
|
22
|
-
|
|
23
|
-
# Default voice for Piper
|
|
24
|
-
DEFAULT_VOICE="en_US-lessac-medium"
|
|
25
|
-
|
|
26
|
-
# @function determine_voice_model
|
|
27
|
-
# @intent Resolve voice name to Piper model name with language support
|
|
28
|
-
# @why Support voice override, language-specific voices, and default fallback
|
|
29
|
-
# @param Uses global: $VOICE_OVERRIDE
|
|
30
|
-
# @returns Sets $VOICE_MODEL global variable
|
|
31
|
-
# @sideeffects None
|
|
32
|
-
VOICE_MODEL=""
|
|
33
|
-
|
|
34
|
-
# Get current language setting
|
|
35
|
-
CURRENT_LANGUAGE=$(get_language_code)
|
|
36
|
-
|
|
37
|
-
if [[ -n "$VOICE_OVERRIDE" ]]; then
|
|
38
|
-
# Use override if provided
|
|
39
|
-
VOICE_MODEL="$VOICE_OVERRIDE"
|
|
40
|
-
echo "🎤 Using voice: $VOICE_OVERRIDE (session-specific)"
|
|
41
|
-
else
|
|
42
|
-
# Try to get voice from voice file (project-local first, then global)
|
|
43
|
-
VOICE_FILE=""
|
|
44
|
-
if [[ -f "$SCRIPT_DIR/../tts-voice.txt" ]]; then
|
|
45
|
-
VOICE_FILE="$SCRIPT_DIR/../tts-voice.txt"
|
|
46
|
-
elif [[ -f "$HOME/.claude/tts-voice.txt" ]]; then
|
|
47
|
-
VOICE_FILE="$HOME/.claude/tts-voice.txt"
|
|
48
|
-
fi
|
|
49
|
-
|
|
50
|
-
if [[ -n "$VOICE_FILE" ]]; then
|
|
51
|
-
FILE_VOICE=$(cat "$VOICE_FILE" 2>/dev/null)
|
|
52
|
-
# Check if it's a Piper model name (contains underscore and dash)
|
|
53
|
-
if [[ "$FILE_VOICE" == *"_"*"-"* ]]; then
|
|
54
|
-
VOICE_MODEL="$FILE_VOICE"
|
|
55
|
-
fi
|
|
56
|
-
fi
|
|
57
|
-
|
|
58
|
-
# If no Piper voice from file, try language-specific voice
|
|
59
|
-
if [[ -z "$VOICE_MODEL" ]]; then
|
|
60
|
-
LANG_VOICE=$(get_voice_for_language "$CURRENT_LANGUAGE" "piper" 2>/dev/null)
|
|
61
|
-
|
|
62
|
-
if [[ -n "$LANG_VOICE" ]]; then
|
|
63
|
-
VOICE_MODEL="$LANG_VOICE"
|
|
64
|
-
echo "🌍 Using $CURRENT_LANGUAGE voice: $LANG_VOICE (Piper)"
|
|
65
|
-
else
|
|
66
|
-
# Use default voice
|
|
67
|
-
VOICE_MODEL="$DEFAULT_VOICE"
|
|
68
|
-
fi
|
|
69
|
-
fi
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# @function validate_inputs
|
|
73
|
-
# @intent Check required parameters
|
|
74
|
-
# @why Fail fast with clear errors if inputs missing
|
|
75
|
-
# @exitcode 1=missing text, 2=missing piper binary
|
|
76
|
-
if [[ -z "$TEXT" ]]; then
|
|
77
|
-
echo "Usage: $0 \"text to speak\" [voice_model_name]"
|
|
78
|
-
exit 1
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# Check if Piper is installed
|
|
82
|
-
if ! command -v piper &> /dev/null; then
|
|
83
|
-
echo "❌ Error: Piper TTS not installed"
|
|
84
|
-
echo "Install with: pipx install piper-tts"
|
|
85
|
-
echo "Or run: .claude/hooks/piper-installer.sh"
|
|
86
|
-
exit 2
|
|
87
|
-
fi
|
|
88
|
-
|
|
89
|
-
# @function ensure_voice_downloaded
|
|
90
|
-
# @intent Download voice model if not cached
|
|
91
|
-
# @why Provide seamless experience with automatic downloads
|
|
92
|
-
# @param Uses global: $VOICE_MODEL
|
|
93
|
-
# @sideeffects Downloads voice model files
|
|
94
|
-
# @edgecases Prompts user for consent before downloading
|
|
95
|
-
if ! verify_voice "$VOICE_MODEL"; then
|
|
96
|
-
echo "📥 Voice model not found: $VOICE_MODEL"
|
|
97
|
-
echo " File size: ~25MB"
|
|
98
|
-
echo " Preview: https://huggingface.co/rhasspy/piper-voices"
|
|
99
|
-
echo ""
|
|
100
|
-
read -p " Download this voice model? [y/N]: " -n 1 -r
|
|
101
|
-
echo
|
|
102
|
-
|
|
103
|
-
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
104
|
-
if ! download_voice "$VOICE_MODEL"; then
|
|
105
|
-
echo "❌ Failed to download voice model"
|
|
106
|
-
echo "Fix: Download manually or choose different voice"
|
|
107
|
-
exit 3
|
|
108
|
-
fi
|
|
109
|
-
else
|
|
110
|
-
echo "❌ Voice download cancelled"
|
|
111
|
-
exit 3
|
|
112
|
-
fi
|
|
113
|
-
fi
|
|
114
|
-
|
|
115
|
-
# Get voice model path
|
|
116
|
-
VOICE_PATH=$(get_voice_path "$VOICE_MODEL")
|
|
117
|
-
if [[ $? -ne 0 ]]; then
|
|
118
|
-
echo "❌ Voice model path not found: $VOICE_MODEL"
|
|
119
|
-
exit 3
|
|
120
|
-
fi
|
|
121
|
-
|
|
122
|
-
# @function determine_audio_directory
|
|
123
|
-
# @intent Find appropriate directory for audio file storage
|
|
124
|
-
# @why Supports project-local and global storage
|
|
125
|
-
# @returns Sets $AUDIO_DIR global variable
|
|
126
|
-
if [[ -n "$CLAUDE_PROJECT_DIR" ]]; then
|
|
127
|
-
AUDIO_DIR="$CLAUDE_PROJECT_DIR/.claude/audio"
|
|
128
|
-
else
|
|
129
|
-
# Fallback: try to find .claude directory in current path
|
|
130
|
-
CURRENT_DIR="$PWD"
|
|
131
|
-
while [[ "$CURRENT_DIR" != "/" ]]; do
|
|
132
|
-
if [[ -d "$CURRENT_DIR/.claude" ]]; then
|
|
133
|
-
AUDIO_DIR="$CURRENT_DIR/.claude/audio"
|
|
134
|
-
break
|
|
135
|
-
fi
|
|
136
|
-
CURRENT_DIR=$(dirname "$CURRENT_DIR")
|
|
137
|
-
done
|
|
138
|
-
# Final fallback to global if no project .claude found
|
|
139
|
-
if [[ -z "$AUDIO_DIR" ]]; then
|
|
140
|
-
AUDIO_DIR="$HOME/.claude/audio"
|
|
141
|
-
fi
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
|
-
mkdir -p "$AUDIO_DIR"
|
|
145
|
-
TEMP_FILE="$AUDIO_DIR/tts-$(date +%s).wav"
|
|
146
|
-
|
|
147
|
-
# @function get_speech_rate
|
|
148
|
-
# @intent Determine speech rate for Piper synthesis
|
|
149
|
-
# @why Convert user-facing speed (0.5=slower, 2.0=faster) to Piper length-scale (inverted)
|
|
150
|
-
# @returns Piper length-scale value (inverted from user scale)
|
|
151
|
-
# @note Piper uses length-scale where higher=slower, opposite of user expectation
|
|
152
|
-
get_speech_rate() {
|
|
153
|
-
local target_config=""
|
|
154
|
-
local main_config=""
|
|
155
|
-
|
|
156
|
-
# Check for target-specific config first (new and legacy paths)
|
|
157
|
-
if [[ -f "$SCRIPT_DIR/../config/tts-target-speech-rate.txt" ]]; then
|
|
158
|
-
target_config="$SCRIPT_DIR/../config/tts-target-speech-rate.txt"
|
|
159
|
-
elif [[ -f "$HOME/.claude/config/tts-target-speech-rate.txt" ]]; then
|
|
160
|
-
target_config="$HOME/.claude/config/tts-target-speech-rate.txt"
|
|
161
|
-
elif [[ -f "$SCRIPT_DIR/../config/piper-target-speech-rate.txt" ]]; then
|
|
162
|
-
target_config="$SCRIPT_DIR/../config/piper-target-speech-rate.txt"
|
|
163
|
-
elif [[ -f "$HOME/.claude/config/piper-target-speech-rate.txt" ]]; then
|
|
164
|
-
target_config="$HOME/.claude/config/piper-target-speech-rate.txt"
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
# Check for main config (new and legacy paths)
|
|
168
|
-
if [[ -f "$SCRIPT_DIR/../config/tts-speech-rate.txt" ]]; then
|
|
169
|
-
main_config="$SCRIPT_DIR/../config/tts-speech-rate.txt"
|
|
170
|
-
elif [[ -f "$HOME/.claude/config/tts-speech-rate.txt" ]]; then
|
|
171
|
-
main_config="$HOME/.claude/config/tts-speech-rate.txt"
|
|
172
|
-
elif [[ -f "$SCRIPT_DIR/../config/piper-speech-rate.txt" ]]; then
|
|
173
|
-
main_config="$SCRIPT_DIR/../config/piper-speech-rate.txt"
|
|
174
|
-
elif [[ -f "$HOME/.claude/config/piper-speech-rate.txt" ]]; then
|
|
175
|
-
main_config="$HOME/.claude/config/piper-speech-rate.txt"
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
# If this is a non-English voice and target config exists, use it
|
|
179
|
-
if [[ "$CURRENT_LANGUAGE" != "english" ]] && [[ -n "$target_config" ]]; then
|
|
180
|
-
local user_speed=$(cat "$target_config" 2>/dev/null)
|
|
181
|
-
# Convert user speed to Piper length-scale (invert)
|
|
182
|
-
# User: 0.5=slower, 1.0=normal, 2.0=faster
|
|
183
|
-
# Piper: 2.0=slower, 1.0=normal, 0.5=faster
|
|
184
|
-
# Formula: piper_length_scale = 1.0 / user_speed
|
|
185
|
-
echo "scale=2; 1.0 / $user_speed" | bc -l 2>/dev/null || echo "1.0"
|
|
186
|
-
return
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
# Otherwise use main config if available
|
|
190
|
-
if [[ -n "$main_config" ]]; then
|
|
191
|
-
local user_speed=$(grep -v '^#' "$main_config" 2>/dev/null | grep -v '^$' | tail -1)
|
|
192
|
-
echo "scale=2; 1.0 / $user_speed" | bc -l 2>/dev/null || echo "1.0"
|
|
193
|
-
return
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
# Default: 1.0 (normal) for English, 2.0 (slower) for learning
|
|
197
|
-
if [[ "$CURRENT_LANGUAGE" != "english" ]]; then
|
|
198
|
-
echo "2.0"
|
|
199
|
-
else
|
|
200
|
-
echo "1.0"
|
|
201
|
-
fi
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
SPEECH_RATE=$(get_speech_rate)
|
|
205
|
-
|
|
206
|
-
# @function synthesize_with_piper
|
|
207
|
-
# @intent Generate speech using Piper TTS
|
|
208
|
-
# @why Provides free, offline TTS alternative
|
|
209
|
-
# @param Uses globals: $TEXT, $VOICE_PATH, $SPEECH_RATE
|
|
210
|
-
# @returns Creates WAV file at $TEMP_FILE
|
|
211
|
-
# @exitcode 0=success, 4=synthesis error
|
|
212
|
-
# @sideeffects Creates audio file
|
|
213
|
-
# @edgecases Handles piper errors, invalid models
|
|
214
|
-
echo "$TEXT" | piper --model "$VOICE_PATH" --length-scale "$SPEECH_RATE" --output_file "$TEMP_FILE" 2>/dev/null
|
|
215
|
-
|
|
216
|
-
if [[ ! -f "$TEMP_FILE" ]] || [[ ! -s "$TEMP_FILE" ]]; then
|
|
217
|
-
echo "❌ Failed to synthesize speech with Piper"
|
|
218
|
-
echo "Voice model: $VOICE_MODEL"
|
|
219
|
-
echo "Check that voice model is valid"
|
|
220
|
-
exit 4
|
|
221
|
-
fi
|
|
222
|
-
|
|
223
|
-
# @function add_silence_padding
|
|
224
|
-
# @intent Add silence to prevent WSL audio static
|
|
225
|
-
# @why WSL audio subsystem cuts off first ~200ms
|
|
226
|
-
# @param Uses global: $TEMP_FILE
|
|
227
|
-
# @returns Updates $TEMP_FILE to padded version
|
|
228
|
-
# @sideeffects Modifies audio file
|
|
229
|
-
# AI NOTE: Use ffmpeg if available, otherwise skip padding (degraded experience)
|
|
230
|
-
if command -v ffmpeg &> /dev/null; then
|
|
231
|
-
PADDED_FILE="$AUDIO_DIR/tts-padded-$(date +%s).wav"
|
|
232
|
-
# Add 200ms of silence at the beginning
|
|
233
|
-
ffmpeg -f lavfi -i anullsrc=r=44100:cl=stereo:d=0.2 -i "$TEMP_FILE" \
|
|
234
|
-
-filter_complex "[0:a][1:a]concat=n=2:v=0:a=1[out]" \
|
|
235
|
-
-map "[out]" -y "$PADDED_FILE" 2>/dev/null
|
|
236
|
-
|
|
237
|
-
if [[ -f "$PADDED_FILE" ]]; then
|
|
238
|
-
rm -f "$TEMP_FILE"
|
|
239
|
-
TEMP_FILE="$PADDED_FILE"
|
|
240
|
-
fi
|
|
241
|
-
fi
|
|
242
|
-
|
|
243
|
-
# @function play_audio
|
|
244
|
-
# @intent Play generated audio using available player with sequential playback
|
|
245
|
-
# @why Support multiple audio players and prevent overlapping audio in learning mode
|
|
246
|
-
# @param Uses global: $TEMP_FILE, $CURRENT_LANGUAGE
|
|
247
|
-
# @sideeffects Plays audio with lock mechanism for sequential playback
|
|
248
|
-
LOCK_FILE="/tmp/agentvibes-audio.lock"
|
|
249
|
-
|
|
250
|
-
# Wait for previous audio to finish (max 30 seconds)
|
|
251
|
-
for i in {1..60}; do
|
|
252
|
-
if [ ! -f "$LOCK_FILE" ]; then
|
|
253
|
-
break
|
|
254
|
-
fi
|
|
255
|
-
sleep 0.5
|
|
256
|
-
done
|
|
257
|
-
|
|
258
|
-
# Track last target language audio for replay command
|
|
259
|
-
if [[ "$CURRENT_LANGUAGE" != "english" ]]; then
|
|
260
|
-
TARGET_AUDIO_FILE="${CLAUDE_PROJECT_DIR:-.}/.claude/last-target-audio.txt"
|
|
261
|
-
echo "$TEMP_FILE" > "$TARGET_AUDIO_FILE"
|
|
262
|
-
fi
|
|
263
|
-
|
|
264
|
-
# Create lock and play audio
|
|
265
|
-
touch "$LOCK_FILE"
|
|
266
|
-
|
|
267
|
-
# Get audio duration for proper lock timing
|
|
268
|
-
DURATION=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$TEMP_FILE" 2>/dev/null)
|
|
269
|
-
DURATION=${DURATION%.*} # Round to integer
|
|
270
|
-
DURATION=${DURATION:-1} # Default to 1 second if detection fails
|
|
271
|
-
|
|
272
|
-
# Play audio in background
|
|
273
|
-
(mpv "$TEMP_FILE" || aplay "$TEMP_FILE" || paplay "$TEMP_FILE") >/dev/null 2>&1 &
|
|
274
|
-
PLAYER_PID=$!
|
|
275
|
-
|
|
276
|
-
# Wait for audio to finish, then release lock
|
|
277
|
-
(sleep $DURATION; rm -f "$LOCK_FILE") &
|
|
278
|
-
disown
|
|
279
|
-
|
|
280
|
-
echo "🎵 Saved to: $TEMP_FILE"
|
|
281
|
-
echo "🎤 Voice used: $VOICE_MODEL (Piper TTS)"
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
# @fileoverview TTS Provider Router with Language Learning Support
|
|
4
|
-
# @context Routes TTS requests to active provider (ElevenLabs or Piper)
|
|
5
|
-
# @architecture Provider abstraction layer - single entry point for all TTS
|
|
6
|
-
# @dependencies provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh
|
|
7
|
-
# @entrypoints Called by hooks, slash commands, and personality-manager.sh
|
|
8
|
-
# @patterns Provider pattern - delegates to provider-specific implementations
|
|
9
|
-
# @related provider-manager.sh, play-tts-elevenlabs.sh, play-tts-piper.sh, learn-manager.sh
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
# Fix locale warnings
|
|
13
|
-
export LC_ALL=C
|
|
14
|
-
|
|
15
|
-
TEXT="$1"
|
|
16
|
-
VOICE_OVERRIDE="$2" # Optional: voice name or ID
|
|
17
|
-
|
|
18
|
-
# Get script directory
|
|
19
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
-
|
|
21
|
-
# Source provider manager to get active provider
|
|
22
|
-
source "$SCRIPT_DIR/provider-manager.sh"
|
|
23
|
-
|
|
24
|
-
# Get active provider
|
|
25
|
-
ACTIVE_PROVIDER=$(get_active_provider)
|
|
26
|
-
|
|
27
|
-
# Show GitHub star reminder (once per day)
|
|
28
|
-
"$SCRIPT_DIR/github-star-reminder.sh" 2>/dev/null || true
|
|
29
|
-
|
|
30
|
-
# @function detect_voice_provider
|
|
31
|
-
# @intent Auto-detect provider from voice name (for mixed-provider support)
|
|
32
|
-
# @why Allow ElevenLabs for main language + Piper for target language
|
|
33
|
-
# @param $1 voice name/ID
|
|
34
|
-
# @returns Provider name (elevenlabs or piper)
|
|
35
|
-
detect_voice_provider() {
|
|
36
|
-
local voice="$1"
|
|
37
|
-
# Piper voice names contain underscore and dash (e.g., es_ES-davefx-medium)
|
|
38
|
-
if [[ "$voice" == *"_"*"-"* ]]; then
|
|
39
|
-
echo "piper"
|
|
40
|
-
else
|
|
41
|
-
echo "$ACTIVE_PROVIDER"
|
|
42
|
-
fi
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
# Override provider if voice indicates different provider (mixed-provider mode)
|
|
46
|
-
if [[ -n "$VOICE_OVERRIDE" ]]; then
|
|
47
|
-
DETECTED_PROVIDER=$(detect_voice_provider "$VOICE_OVERRIDE")
|
|
48
|
-
if [[ "$DETECTED_PROVIDER" != "$ACTIVE_PROVIDER" ]]; then
|
|
49
|
-
ACTIVE_PROVIDER="$DETECTED_PROVIDER"
|
|
50
|
-
fi
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
# Normal single-language mode - route to appropriate provider implementation
|
|
54
|
-
# Note: For learning mode, the output style will call this script TWICE:
|
|
55
|
-
# 1. First call with main language text and current voice
|
|
56
|
-
# 2. Second call with translated text and target voice
|
|
57
|
-
case "$ACTIVE_PROVIDER" in
|
|
58
|
-
elevenlabs)
|
|
59
|
-
exec "$SCRIPT_DIR/play-tts-elevenlabs.sh" "$TEXT" "$VOICE_OVERRIDE"
|
|
60
|
-
;;
|
|
61
|
-
piper)
|
|
62
|
-
exec "$SCRIPT_DIR/play-tts-piper.sh" "$TEXT" "$VOICE_OVERRIDE"
|
|
63
|
-
;;
|
|
64
|
-
*)
|
|
65
|
-
echo "❌ Unknown provider: $ACTIVE_PROVIDER"
|
|
66
|
-
echo " Run: /agent-vibes:provider list"
|
|
67
|
-
exit 1
|
|
68
|
-
;;
|
|
69
|
-
esac
|