agentvibes 5.6.7 → 5.6.9

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.
Files changed (142) hide show
  1. package/.agentvibes/LITE-MODE.md +236 -0
  2. package/.agentvibes/README.md +136 -0
  3. package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +141 -0
  4. package/.agentvibes/backups/agents/analyst_20260204_144958.md +78 -0
  5. package/.agentvibes/backups/agents/architect_20260204_144958.md +72 -0
  6. package/.agentvibes/backups/agents/dev_20260204_144958.md +74 -0
  7. package/.agentvibes/backups/agents/pm_20260204_144958.md +72 -0
  8. package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +64 -0
  9. package/.agentvibes/backups/agents/sm_20260204_144958.md +87 -0
  10. package/.agentvibes/backups/agents/tea_20260204_144958.md +79 -0
  11. package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +82 -0
  12. package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +80 -0
  13. package/.agentvibes/config/README-personality-defaults.md +162 -0
  14. package/.agentvibes/config/agentvibes.json +1 -0
  15. package/.agentvibes/config/mode.txt +1 -0
  16. package/.agentvibes/config/personality-voice-defaults.default.json +21 -0
  17. package/.agentvibes/config/save-audio.txt +1 -0
  18. package/.agentvibes/config/voice-metadata.json +160 -0
  19. package/.agentvibes/config.json +38 -1
  20. package/.agentvibes/hooks/help.sh +191 -0
  21. package/.agentvibes/hooks/post-tool-use-lite.sh +111 -0
  22. package/.agentvibes/hooks/save-audio-manager.sh +162 -0
  23. package/.agentvibes/hooks/session-start-full-optimized.sh +102 -0
  24. package/.agentvibes/hooks/session-start-full.sh +142 -0
  25. package/.agentvibes/hooks/session-start-lite-v2.sh +34 -0
  26. package/.agentvibes/hooks/session-start-lite.sh +29 -0
  27. package/.agentvibes/hooks/stop-lite.sh +115 -0
  28. package/.agentvibes/hooks/switch-mode.sh +215 -0
  29. package/.agentvibes/output-styles/audio-summary.md +30 -0
  30. package/.claude/audio/voice-samples/piper/alan.wav +0 -0
  31. package/.claude/audio/voice-samples/piper/amy.wav +0 -0
  32. package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
  33. package/.claude/audio/voice-samples/piper/joe.wav +0 -0
  34. package/.claude/audio/voice-samples/piper/john.wav +0 -0
  35. package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
  36. package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
  37. package/.claude/audio/voice-samples/piper/linda.wav +0 -0
  38. package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
  39. package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
  40. package/.claude/commands/agent-vibes/provider.md +0 -0
  41. package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
  42. package/.claude/commands/agent-vibes-rdp.md +24 -24
  43. package/.claude/config/audio-effects.cfg +6 -1
  44. package/.claude/config/background-music-position.txt +8 -6
  45. package/.claude/config/reverb-level.txt +0 -0
  46. package/.claude/docs/TERMUX_SETUP.md +408 -408
  47. package/.claude/github-star-reminder.txt +1 -1
  48. package/.claude/hooks/audio-cache-utils.sh +0 -0
  49. package/.claude/hooks/audio-processor.sh +0 -0
  50. package/.claude/hooks/background-music-manager.sh +0 -0
  51. package/.claude/hooks/bmad-party-manager.sh +225 -0
  52. package/.claude/hooks/bmad-party-speak.sh +0 -0
  53. package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
  54. package/.claude/hooks/bmad-speak.sh +0 -0
  55. package/.claude/hooks/bmad-tts-injector.sh +0 -0
  56. package/.claude/hooks/bmad-voice-manager.sh +0 -0
  57. package/.claude/hooks/clawdbot-receiver-SECURE.sh +0 -0
  58. package/.claude/hooks/clawdbot-receiver.sh +0 -0
  59. package/.claude/hooks/clean-audio-cache.sh +0 -0
  60. package/.claude/hooks/cleanup-cache.sh +0 -0
  61. package/.claude/hooks/configure-rdp-mode.sh +0 -0
  62. package/.claude/hooks/download-extra-voices.sh +0 -0
  63. package/.claude/hooks/effects-manager.sh +0 -0
  64. package/.claude/hooks/github-star-reminder.sh +0 -0
  65. package/.claude/hooks/language-manager.sh +0 -0
  66. package/.claude/hooks/learn-manager.sh +0 -0
  67. package/.claude/hooks/macos-voice-manager.sh +0 -0
  68. package/.claude/hooks/migrate-background-music.sh +0 -0
  69. package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
  70. package/.claude/hooks/optimize-background-music.sh +0 -0
  71. package/.claude/hooks/path-resolver.sh +0 -0
  72. package/.claude/hooks/personality-manager.sh +0 -0
  73. package/.claude/hooks/piper-download-voices.sh +0 -0
  74. package/.claude/hooks/piper-installer.sh +0 -0
  75. package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
  76. package/.claude/hooks/piper-voice-manager.sh +0 -0
  77. package/.claude/hooks/play-tts-agentvibes-receiver-for-voiceless-connections.sh +0 -0
  78. package/.claude/hooks/play-tts-enhanced.sh +0 -0
  79. package/.claude/hooks/play-tts-macos.sh +0 -0
  80. package/.claude/hooks/play-tts-piper.sh +40 -2
  81. package/.claude/hooks/play-tts-soprano.sh +0 -0
  82. package/.claude/hooks/play-tts-ssh-remote.sh +0 -0
  83. package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
  84. package/.claude/hooks/play-tts-windows-receiver.sh +0 -0
  85. package/.claude/hooks/play-tts.sh +13 -0
  86. package/.claude/hooks/post-response.sh +41 -0
  87. package/.claude/hooks/prepare-release.sh +0 -0
  88. package/.claude/hooks/provider-commands.sh +0 -0
  89. package/.claude/hooks/provider-manager.sh +0 -0
  90. package/.claude/hooks/replay-target-audio.sh +0 -0
  91. package/.claude/hooks/sentiment-manager.sh +0 -0
  92. package/.claude/hooks/session-start-tts.sh +48 -13
  93. package/.claude/hooks/soprano-gradio-synth.py +0 -0
  94. package/.claude/hooks/speed-manager.sh +0 -0
  95. package/.claude/hooks/stop-tts.sh +0 -0
  96. package/.claude/hooks/stop.sh +63 -0
  97. package/.claude/hooks/termux-installer.sh +0 -0
  98. package/.claude/hooks/translate-manager.sh +0 -0
  99. package/.claude/hooks/translator.py +0 -0
  100. package/.claude/hooks/tts-queue-worker.sh +0 -0
  101. package/.claude/hooks/tts-queue.sh +0 -0
  102. package/.claude/hooks/verbosity-manager.sh +0 -0
  103. package/.claude/hooks/voice-manager.sh +0 -0
  104. package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
  105. package/.claude/hooks-windows/play-tts-piper.ps1 +26 -1
  106. package/.claude/hooks-windows/play-tts.ps1 +25 -1
  107. package/.claude/hooks-windows/session-start-tts.ps1 +28 -9
  108. package/.claude/piper-voices-dir.txt +1 -0
  109. package/.claude/settings.json +2 -2
  110. package/.clawdbot/README.md +105 -105
  111. package/.mcp.json +32 -3
  112. package/CLAUDE.md +9 -0
  113. package/README.md +21 -3
  114. package/RELEASE_NOTES.md +61 -0
  115. package/WINDOWS-SETUP.md +208 -208
  116. package/bin/agent-vibes +0 -0
  117. package/bin/agentvibes-voice-browser.js +59 -4
  118. package/bin/agentvibes.js +0 -0
  119. package/bin/ensure-soprano-running.sh +43 -0
  120. package/bin/mcp-server.js +121 -121
  121. package/bin/mcp-server.sh +0 -0
  122. package/bin/test-bmad-pr +78 -78
  123. package/mcp-server/QUICK_START.md +203 -203
  124. package/mcp-server/README.md +345 -345
  125. package/mcp-server/WINDOWS_SETUP.md +260 -260
  126. package/mcp-server/docs/troubleshooting-audio.md +313 -313
  127. package/mcp-server/examples/claude_desktop_config.json +11 -11
  128. package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
  129. package/mcp-server/examples/custom_instructions.md +169 -169
  130. package/mcp-server/install-deps.js +177 -130
  131. package/mcp-server/server.py +1797 -1787
  132. package/mcp-server/test_server.py +0 -0
  133. package/package.json +1 -1
  134. package/src/console/app.js +6 -0
  135. package/src/console/tabs/music-tab.js +18 -2
  136. package/src/console/widgets/format-utils.js +11 -2
  137. package/src/installer.js +38 -37
  138. package/src/services/llm-provider-service.js +28 -9
  139. package/src/utils/voice-names.js +2 -0
  140. package/templates/agentvibes-receiver.sh +0 -0
  141. package/templates/audio/welcome-music.mp3 +0 -0
  142. package/.claude/hooks/play-tts-agentvibes-receiver.sh +0 -1
@@ -1 +1 @@
1
- 20260508
1
+ 20260509
File without changes
File without changes
File without changes
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # File: .claude/hooks/bmad-party-manager.sh
4
+ #
5
+ # AgentVibes - Finally, your AI Agents can Talk Back! Text-to-Speech WITH personality for AI Assistants!
6
+ # Website: https://agentvibes.org
7
+ # Repository: https://github.com/paulpreibisch/AgentVibes
8
+ #
9
+ # Co-created by Paul Preibisch with Claude AI
10
+ # Copyright (c) 2025 Paul Preibisch
11
+ #
12
+ # Licensed under the Apache License, Version 2.0 (the "License");
13
+ # you may not use this file except in compliance with the License.
14
+ # You may obtain a copy of the License at
15
+ #
16
+ # http://www.apache.org/licenses/LICENSE-2.0
17
+ #
18
+ # Unless required by applicable law or agreed to in writing, software
19
+ # distributed under the License is distributed on an "AS IS" BASIS,
20
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
+ # See the License for the specific language governing permissions and
22
+ # limitations under the License.
23
+ #
24
+ # DISCLAIMER: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
+ # express or implied, including but not limited to the warranties of
26
+ # merchantability, fitness for a particular purpose and noninfringement.
27
+ # In no event shall the authors or copyright holders be liable for any claim,
28
+ # damages or other liability, whether in an action of contract, tort or
29
+ # otherwise, arising from, out of or in connection with the software or the
30
+ # use or other dealings in the software.
31
+ #
32
+ # ---
33
+ #
34
+ # @fileoverview BMAD Party Mode Voice Integration Manager
35
+ # @context Controls auto-enable/disable of multi-agent voice switching during BMAD party mode
36
+ # @architecture Opt-out flag management, auto-detection, status reporting
37
+ # @dependencies .bmad/_cfg/agent-manifest.csv, bmad-voices-enabled.flag, user-prompt-output.sh
38
+ # @entrypoints /agent-vibes:bmad-party slash command
39
+ # @patterns Auto-enable with opt-out, graceful degradation, feature detection
40
+ # @related user-prompt-output.sh, bmad-voice-manager.sh, Issue #33
41
+
42
+ # Fix locale warnings
43
+ export LC_ALL=C
44
+
45
+ PLUGIN_DIR=".claude/plugins"
46
+ DISABLE_FLAG="$PLUGIN_DIR/bmad-party-mode-disabled.flag"
47
+ BMAD_VOICES_FLAG="$PLUGIN_DIR/bmad-voices-enabled.flag"
48
+ BMAD_MANIFEST=".bmad/_cfg/agent-manifest.csv"
49
+
50
+ # Colors
51
+ GREEN='\033[0;32m'
52
+ YELLOW='\033[1;33m'
53
+ RED='\033[0;31m'
54
+ CYAN='\033[0;36m'
55
+ GRAY='\033[0;90m'
56
+ NC='\033[0m' # No Color
57
+
58
+ #
59
+ # @function is_bmad_installed
60
+ # @context Check if BMAD v6 is installed
61
+ # @returns 0=installed, 1=not installed
62
+ #
63
+ is_bmad_installed() {
64
+ [[ -f "$BMAD_MANIFEST" ]]
65
+ }
66
+
67
+ #
68
+ # @function is_bmad_voices_enabled
69
+ # @context Check if BMAD voice plugin is enabled
70
+ # @returns 0=enabled, 1=disabled
71
+ #
72
+ is_bmad_voices_enabled() {
73
+ [[ -f "$BMAD_VOICES_FLAG" ]]
74
+ }
75
+
76
+ #
77
+ # @function is_party_mode_enabled
78
+ # @context Check if party mode voice integration is enabled
79
+ # @returns 0=enabled, 1=disabled
80
+ #
81
+ is_party_mode_enabled() {
82
+ # Disabled if opt-out flag exists
83
+ [[ -f "$DISABLE_FLAG" ]] && return 1
84
+
85
+ # Enabled if BMAD + voice plugin active
86
+ is_bmad_installed && is_bmad_voices_enabled
87
+ }
88
+
89
+ #
90
+ # @function show_status
91
+ # @context Display current party mode voice integration status
92
+ #
93
+ show_status() {
94
+ echo -e "${CYAN}🎭 BMAD Party Mode Voice Integration${NC}"
95
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
96
+ echo ""
97
+
98
+ # Check BMAD installation
99
+ if ! is_bmad_installed; then
100
+ echo -e "${RED}❌ BMAD not installed${NC}"
101
+ echo -e "${GRAY} Party mode voice integration requires BMAD v6${NC}"
102
+ echo -e "${GRAY} Install: https://github.com/bmad-method/bmad${NC}"
103
+ echo ""
104
+ return 1
105
+ fi
106
+
107
+ echo -e "${GREEN}✅ BMAD v6 detected${NC}"
108
+
109
+ # Check voice plugin
110
+ if ! is_bmad_voices_enabled; then
111
+ echo -e "${RED}❌ BMAD voice plugin disabled${NC}"
112
+ echo -e "${GRAY} Enable: /agent-vibes:bmad enable${NC}"
113
+ echo ""
114
+ return 1
115
+ fi
116
+
117
+ echo -e "${GREEN}✅ BMAD voice plugin enabled${NC}"
118
+
119
+ # Check party mode status
120
+ if is_party_mode_enabled; then
121
+ echo -e "${GREEN}✅ Party mode voices: ENABLED${NC}"
122
+ echo ""
123
+ echo -e "${CYAN}How it works:${NC}"
124
+ echo " When you run /bmad:core:workflows:party-mode,"
125
+ echo " each agent speaks with their unique voice:"
126
+ echo ""
127
+ echo " 🏗️ Winston (Architect) → Michael"
128
+ echo " 📋 John (PM) → Jessica Anne Bogart"
129
+ echo " 💻 Amelia (Dev) → Matthew Schmitz"
130
+ echo " 📊 Mary (Analyst) → kristin"
131
+ echo " ... and more!"
132
+ echo ""
133
+ echo -e "${GRAY}Disable with: /agent-vibes:bmad-party disable${NC}"
134
+ else
135
+ echo -e "${YELLOW}⚠️ Party mode voices: DISABLED (opt-out active)${NC}"
136
+ echo ""
137
+ echo -e "${GRAY}Enable with: /agent-vibes:bmad-party enable${NC}"
138
+ fi
139
+
140
+ echo ""
141
+ }
142
+
143
+ #
144
+ # @function enable_party_mode
145
+ # @context Enable party mode voice integration (remove opt-out flag)
146
+ #
147
+ enable_party_mode() {
148
+ # Verify prerequisites
149
+ if ! is_bmad_installed; then
150
+ echo -e "${RED}❌ Cannot enable: BMAD not installed${NC}"
151
+ echo -e "${GRAY} Install BMAD v6 first${NC}"
152
+ return 1
153
+ fi
154
+
155
+ if ! is_bmad_voices_enabled; then
156
+ echo -e "${RED}❌ Cannot enable: BMAD voice plugin disabled${NC}"
157
+ echo -e "${GRAY} Enable with: /agent-vibes:bmad enable${NC}"
158
+ return 1
159
+ fi
160
+
161
+ # Remove opt-out flag if it exists
162
+ if [[ -f "$DISABLE_FLAG" ]]; then
163
+ rm -f "$DISABLE_FLAG"
164
+ echo -e "${GREEN}✅ Party mode voices enabled${NC}"
165
+ echo ""
166
+ echo -e "${CYAN}🎭 Multi-agent voice switching activated!${NC}"
167
+ echo " Run /bmad:core:workflows:party-mode to hear agents speak"
168
+ else
169
+ echo -e "${GREEN}✅ Party mode voices already enabled${NC}"
170
+ echo ""
171
+ echo -e "${GRAY}(Auto-enabled when BMAD detected)${NC}"
172
+ fi
173
+
174
+ echo ""
175
+ }
176
+
177
+ #
178
+ # @function disable_party_mode
179
+ # @context Disable party mode voice integration (create opt-out flag)
180
+ #
181
+ disable_party_mode() {
182
+ mkdir -p "$PLUGIN_DIR"
183
+
184
+ if [[ -f "$DISABLE_FLAG" ]]; then
185
+ echo -e "${YELLOW}⚠️ Party mode voices already disabled${NC}"
186
+ return 0
187
+ fi
188
+
189
+ # Create opt-out flag
190
+ touch "$DISABLE_FLAG"
191
+
192
+ echo -e "${GREEN}✅ Party mode voices disabled${NC}"
193
+ echo ""
194
+ echo -e "${GRAY}Party mode will continue to work, but agents won't speak${NC}"
195
+ echo -e "${GRAY}Enable again with: /agent-vibes:bmad-party enable${NC}"
196
+ echo ""
197
+ }
198
+
199
+ # Main command dispatcher
200
+ case "${1:-status}" in
201
+ enable)
202
+ enable_party_mode
203
+ ;;
204
+ disable)
205
+ disable_party_mode
206
+ ;;
207
+ status)
208
+ show_status
209
+ ;;
210
+ *)
211
+ echo -e "${CYAN}AgentVibes BMAD Party Mode Manager${NC}"
212
+ echo ""
213
+ echo "Usage: bmad-party-manager.sh {enable|disable|status}"
214
+ echo ""
215
+ echo "Commands:"
216
+ echo " enable Enable party mode voice integration"
217
+ echo " disable Disable party mode voice integration (opt-out)"
218
+ echo " status Show current status and configuration"
219
+ echo ""
220
+ echo "Party Mode Voice Integration:"
221
+ echo " • Auto-enabled when BMAD v6 detected"
222
+ echo " • Each agent speaks with unique voice during party mode"
223
+ echo " • Opt-out available via disable command"
224
+ ;;
225
+ esac
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -91,6 +91,7 @@ DEFAULT_VOICE="en_US-lessac-medium"
91
91
  # @returns Sets $VOICE_MODEL global variable
92
92
  # @sideeffects None
93
93
  VOICE_MODEL=""
94
+ FILE_VOICE=""
94
95
 
95
96
  # Get current language setting
96
97
  CURRENT_LANGUAGE=$(get_language_code)
@@ -206,6 +207,15 @@ else
206
207
  fi
207
208
  fi
208
209
 
210
+ # Preserve full display name (with ::SpeakerName) before any stripping for logging
211
+ if [[ -n "$VOICE_OVERRIDE" ]]; then
212
+ DISPLAY_VOICE_NAME="$VOICE_OVERRIDE"
213
+ elif [[ -n "$FILE_VOICE" ]]; then
214
+ DISPLAY_VOICE_NAME="$FILE_VOICE"
215
+ else
216
+ DISPLAY_VOICE_NAME="$VOICE_MODEL"
217
+ fi
218
+
209
219
  # @function validate_inputs
210
220
  # @intent Check required parameters
211
221
  # @why Fail fast with clear errors if inputs missing
@@ -215,6 +225,10 @@ if [[ -z "$TEXT" ]]; then
215
225
  exit 1
216
226
  fi
217
227
 
228
+ # Augment PATH for non-interactive shells (pipx installs to ~/.local/bin which
229
+ # interactive shells get via .bashrc/.zshrc, but Bash tool calls skip profile)
230
+ export PATH="$HOME/.local/bin:$HOME/.local/share/pipx/venvs/piper-tts/bin:$PATH"
231
+
218
232
  # Check if Piper is installed
219
233
  if ! command -v piper &> /dev/null; then
220
234
  echo "❌ Error: Piper TTS not installed"
@@ -454,7 +468,7 @@ if [[ -f "$SCRIPT_DIR/audio-processor.sh" ]]; then
454
468
  # audio-processor.sh returns: FILE_PATH|BACKGROUND_FILE
455
469
  # Lookup order: LLM key (from --llm) → default
456
470
  _AGENT_KEY="${AGENTVIBES_LLM_KEY:-default}"
457
- PROCESSOR_OUTPUT=$("$SCRIPT_DIR/audio-processor.sh" "$TEMP_FILE" "$_AGENT_KEY" "$PROCESSED_FILE" "$AGENT_PROFILE_FILE" 2>/dev/null) || {
471
+ PROCESSOR_OUTPUT=$(bash "$SCRIPT_DIR/audio-processor.sh" "$TEMP_FILE" "$_AGENT_KEY" "$PROCESSED_FILE" "$AGENT_PROFILE_FILE" 2>/dev/null) || {
458
472
  echo "Warning: Audio processing failed, using unprocessed audio" >&2
459
473
  PROCESSED_FILE="$TEMP_FILE"
460
474
  PROCESSOR_OUTPUT="$TEMP_FILE|"
@@ -614,7 +628,31 @@ if [[ -n "$BACKGROUND_MUSIC" ]]; then
614
628
  MUSIC_FILENAME=$(basename "$BACKGROUND_MUSIC")
615
629
  echo -e "${WHITE}🎵 Background music:${NC} ${PURPLE}$MUSIC_FILENAME${NC}"
616
630
  fi
617
- echo -e "${WHITE}🎤 Voice used:${NC} ${BLUE}$VOICE_MODEL${NC} ${WHITE}(Piper TTS)${NC}"
631
+ # Build friendly label: "model::Mike-13 [Mike Nash]"
632
+ _SURNAME_POOL=("Bell" "Carter" "Davis" "Ellis" "Foster" "Gray" "Hayes" "Irving" "Jones" "Knox" "Lane" "Mason" "Nash" "Owens" "Pierce" "Quinn")
633
+ _VOICE_DISPLAY_LABEL="$DISPLAY_VOICE_NAME"
634
+ if [[ "$DISPLAY_VOICE_NAME" == *"::"* ]]; then
635
+ _SP="${DISPLAY_VOICE_NAME#*::}"
636
+ # Skip 16Speakers names (underscore = already first_last format)
637
+ if [[ "$_SP" != *"_"* ]]; then
638
+ _FRIENDLY=""
639
+ if [[ "$_SP" =~ ^(.+)-([0-9]+)$ ]]; then
640
+ if [[ ${BASH_REMATCH[2]} -ge 2 ]]; then
641
+ _IDX=$(( (${BASH_REMATCH[2]} - 1) % 16 ))
642
+ _FRIENDLY="${BASH_REMATCH[1]} ${_SURNAME_POOL[$_IDX]}"
643
+ else
644
+ # n=1: strip suffix, use Bell — matches uniquifyVoiceName JS behaviour
645
+ _FRIENDLY="${BASH_REMATCH[1]} ${_SURNAME_POOL[0]}"
646
+ fi
647
+ elif [[ "$_SP" =~ [[:space:]] ]]; then
648
+ _FRIENDLY="$_SP"
649
+ else
650
+ _FRIENDLY="$_SP ${_SURNAME_POOL[0]}"
651
+ fi
652
+ [[ "$_FRIENDLY" != "$_SP" ]] && _VOICE_DISPLAY_LABEL="$DISPLAY_VOICE_NAME [$_FRIENDLY]"
653
+ fi
654
+ fi
655
+ echo -e "${WHITE}🎤 Voice used:${NC} ${BLUE}$_VOICE_DISPLAY_LABEL${NC} ${WHITE}(Piper TTS)${NC}"
618
656
 
619
657
  # Show personality if configured
620
658
  PERSONALITY=$(cat "$PROJECT_ROOT/.claude/tts-personality.txt" 2>/dev/null || cat "$HOME/.claude/tts-personality.txt" 2>/dev/null || echo "")
File without changes
File without changes
File without changes
File without changes
@@ -115,6 +115,15 @@ while [[ $# -gt 0 ]]; do
115
115
  LLM_PROVIDER="${2:-}"
116
116
  shift 2
117
117
  ;;
118
+ --project-dir)
119
+ # Always prefer the explicitly-injected project dir over any stale
120
+ # CLAUDE_PROJECT_DIR in the environment (fixes silent override by env).
121
+ # Validate the path exists before trusting it.
122
+ if [[ -n "${2:-}" && -d "${2}" ]]; then
123
+ export CLAUDE_PROJECT_DIR="${2}"
124
+ fi
125
+ shift 2
126
+ ;;
118
127
  *)
119
128
  _POSITIONAL_ARGS+=("$1")
120
129
  shift
@@ -194,6 +203,10 @@ if [[ -n "$LLM_PROVIDER" ]]; then
194
203
  fi
195
204
  # Export LLM key for child scripts (process-local, not system-wide)
196
205
  export AGENTVIBES_LLM_KEY="llm:${LLM_PROVIDER}"
206
+ # Emit routing info when verbose debugging is enabled (used by tests and diagnostics)
207
+ if [[ "${AGENTVIBES_VERBOSE:-0}" == "1" ]]; then
208
+ echo "llm=${LLM_PROVIDER}" >&2
209
+ fi
197
210
  fi
198
211
 
199
212
  # Prepend intro text (pretext) if configured
@@ -0,0 +1,41 @@
1
+ #!/bin/bash
2
+ # AgentVibes TTS Hook - Triggers on assistant responses
3
+ # This hook is called after Claude generates a response
4
+
5
+ set -euo pipefail
6
+
7
+ # Get the hooks directory
8
+ HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ PROJECT_ROOT="$(dirname "$(dirname "$HOOKS_DIR")")"
10
+
11
+ # Check if AgentVibes is muted for this project
12
+ if [[ -f "$PROJECT_ROOT/.claude/agentvibes-muted" ]]; then
13
+ exit 0 # Silently skip TTS
14
+ fi
15
+
16
+ # Check if unmuted flag exists (overrides global mute)
17
+ if [[ ! -f "$PROJECT_ROOT/.claude/agentvibes-unmuted" ]]; then
18
+ # Check global mute
19
+ if [[ -f "$HOME/.agentvibes-muted" ]]; then
20
+ exit 0 # Silently skip TTS
21
+ fi
22
+ fi
23
+
24
+ # Get the assistant's response text from stdin or arguments
25
+ RESPONSE_TEXT="${1:-}"
26
+ if [[ -z "$RESPONSE_TEXT" ]]; then
27
+ # Try reading from stdin if available
28
+ if [[ -p /dev/stdin ]]; then
29
+ RESPONSE_TEXT=$(cat)
30
+ fi
31
+ fi
32
+
33
+ # Skip if no text
34
+ if [[ -z "$RESPONSE_TEXT" ]]; then
35
+ exit 0
36
+ fi
37
+
38
+ # Play TTS using the main play-tts script
39
+ "$HOOKS_DIR/play-tts.sh" "$RESPONSE_TEXT" &
40
+
41
+ exit 0
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -10,18 +10,49 @@ set -euo pipefail
10
10
  # Fix locale warnings
11
11
  export LC_ALL=C
12
12
 
13
- # Get script directory
13
+ # Get script directory (resolve symlinks so $SCRIPT_DIR is the real hooks dir)
14
14
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
15
 
16
+ # Resolve absolute path to play-tts.sh from this script's own location.
17
+ # Using an absolute path in the injected protocol ensures the correct
18
+ # play-tts.sh is called regardless of the working directory when Claude
19
+ # runs the command — fixes "wrong voice in fresh folder" regression.
20
+ PLAY_TTS_PATH="$SCRIPT_DIR/play-tts.sh"
21
+
16
22
  # Check if AgentVibes is installed
17
- if [[ ! -f "$SCRIPT_DIR/play-tts.sh" ]]; then
23
+ if [[ ! -f "$PLAY_TTS_PATH" ]]; then
18
24
  # AgentVibes not installed, don't inject anything
19
25
  exit 0
20
26
  fi
21
27
 
28
+ # Capture project dir NOW while Claude Code has set CLAUDE_PROJECT_DIR.
29
+ # Bash tool calls (how Claude actually runs play-tts.sh) do not automatically
30
+ # receive CLAUDE_PROJECT_DIR, so we bake it into the injected protocol command
31
+ # via --project-dir so the correct per-project config is always found.
32
+ CAPTURED_PROJECT_DIR=""
33
+ if [[ -n "${CLAUDE_PROJECT_DIR:-}" && -d "$CLAUDE_PROJECT_DIR/.claude" ]]; then
34
+ CAPTURED_PROJECT_DIR="$CLAUDE_PROJECT_DIR"
35
+ _PROJECT_CLAUDE_DIR="$CLAUDE_PROJECT_DIR/.claude"
36
+ else
37
+ # Fallback: script lives inside .claude/hooks/, so parent IS .claude/
38
+ _PROJECT_CLAUDE_DIR="$(dirname "$SCRIPT_DIR")"
39
+ fi
40
+
41
+ # Build --project-dir flag to embed in TTS commands.
42
+ # Sanitize: strip any embedded quotes that would break shell quoting.
43
+ PROJECT_DIR_FLAG=""
44
+ if [[ -n "$CAPTURED_PROJECT_DIR" ]]; then
45
+ _SAFE_PROJECT_DIR="${CAPTURED_PROJECT_DIR//\"/}"
46
+ PROJECT_DIR_FLAG=" --project-dir \"$_SAFE_PROJECT_DIR\""
47
+ fi
48
+
22
49
  # Check for sentiment (priority) or personality (fallback)
23
- SENTIMENT=$(cat .claude/tts-sentiment.txt 2>/dev/null || cat ~/.claude/tts-sentiment.txt 2>/dev/null || echo "")
24
- PERSONALITY=$(cat .claude/tts-personality.txt 2>/dev/null || cat ~/.claude/tts-personality.txt 2>/dev/null || echo "normal")
50
+ SENTIMENT=$(cat "$_PROJECT_CLAUDE_DIR/tts-sentiment.txt" 2>/dev/null \
51
+ || cat "$HOME/.claude/tts-sentiment.txt" 2>/dev/null \
52
+ || echo "")
53
+ PERSONALITY=$(cat "$_PROJECT_CLAUDE_DIR/tts-personality.txt" 2>/dev/null \
54
+ || cat "$HOME/.claude/tts-personality.txt" 2>/dev/null \
55
+ || echo "normal")
25
56
 
26
57
  # Determine style
27
58
  if [[ -n "$SENTIMENT" ]]; then
@@ -31,26 +62,30 @@ else
31
62
  fi
32
63
 
33
64
  # Get verbosity level (Issue #32)
34
- VERBOSITY=$(cat .claude/tts-verbosity.txt 2>/dev/null || cat ~/.claude/tts-verbosity.txt 2>/dev/null || echo "low")
65
+ VERBOSITY=$(cat "$_PROJECT_CLAUDE_DIR/tts-verbosity.txt" 2>/dev/null \
66
+ || cat "$HOME/.claude/tts-verbosity.txt" 2>/dev/null \
67
+ || echo "low")
35
68
 
36
- # Output optimized TTS protocol
37
- cat <<'EOF'
69
+ # Output optimized TTS protocol.
70
+ # Note: heredoc uses double-quotes (<<EOF not <<'EOF') so $PLAY_TTS_PATH expands.
71
+ # Backticks must be escaped (\`) to avoid command substitution.
72
+ cat << EOF
38
73
 
39
74
  # AgentVibes TTS Protocol
40
75
 
41
76
  **CRITICAL: You MUST execute TTS at TWO points for EVERY user interaction:**
42
77
 
43
- 1. **Acknowledgment** - Start of task: `Bash: .claude/hooks/play-tts.sh "[action]"`
44
- 2. **Completion** - End of task: `Bash: .claude/hooks/play-tts.sh "[result + key details]"`
78
+ 1. **Acknowledgment** - Start of task: \`Bash: $PLAY_TTS_PATH "[action]" --llm claude-code$PROJECT_DIR_FLAG\`
79
+ 2. **Completion** - End of task: \`Bash: $PLAY_TTS_PATH "[result + key details]" --llm claude-code$PROJECT_DIR_FLAG\`
45
80
 
46
81
  **IMPORTANT: Run TTS commands inline (NOT in background). Wait for each TTS call to complete before continuing.**
47
82
 
48
83
  **Example:**
49
- ```
50
- [Bash: .claude/hooks/play-tts.sh "Checking git status"]
84
+ \`\`\`
85
+ [Bash: $PLAY_TTS_PATH "Checking git status" --llm claude-code$PROJECT_DIR_FLAG]
51
86
  [work...]
52
- [Bash: .claude/hooks/play-tts.sh "Repository is clean, no changes"]
53
- ```
87
+ [Bash: $PLAY_TTS_PATH "Repository is clean, no changes" --llm claude-code$PROJECT_DIR_FLAG]
88
+ \`\`\`
54
89
 
55
90
  EOF
56
91
 
File without changes
File without changes
File without changes
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # File: .claude/hooks/stop.sh
4
+ #
5
+ # AgentVibes Stop Hook - Wrapper that delegates to .agentvibes/
6
+ # This hook runs in LITE mode to extract and speak "Audio Summary:" markers
7
+ #
8
+
9
+ # Fix locale warnings
10
+ export LC_ALL=C
11
+
12
+ # Get script directory
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
15
+
16
+ # Path to mode configuration
17
+ MODE_FILE="$PROJECT_ROOT/.agentvibes/config/mode.txt"
18
+
19
+ # Check if AgentVibes is installed
20
+ AGENTVIBES_HOOKS="$PROJECT_ROOT/.agentvibes/hooks"
21
+ if [[ ! -d "$AGENTVIBES_HOOKS" ]]; then
22
+ # AgentVibes not installed, exit silently
23
+ exit 0
24
+ fi
25
+
26
+ # Read current mode (default to full if not set)
27
+ CURRENT_MODE="full"
28
+ if [[ -f "$MODE_FILE" ]]; then
29
+ CURRENT_MODE=$(cat "$MODE_FILE" 2>/dev/null | tr -d '[:space:]')
30
+ fi
31
+
32
+ # Only run stop hook in LITE mode
33
+ # (Full mode uses tool calls for TTS, not stop hooks)
34
+ if [[ "$CURRENT_MODE" == "lite" ]]; then
35
+ # Claude Code sends JSON on stdin: {"transcript_path": "..."}
36
+ HOOK_INPUT=$(cat)
37
+ TRANSCRIPT_PATH=$(echo "$HOOK_INPUT" | jq -r '.transcript_path // empty' 2>/dev/null || true)
38
+
39
+ [[ -z "$TRANSCRIPT_PATH" ]] && exit 0
40
+ [[ ! -f "$TRANSCRIPT_PATH" ]] && exit 0
41
+
42
+ # Extract Audio Summary ONLY from the most recent assistant response.
43
+ # Key insight: we must NOT search earlier responses — if the latest response
44
+ # has no Audio Summary: marker, we stay silent (no stale replay).
45
+ SUMMARY=$(jq --slurp -r '
46
+ [.[] | try select(.message.role == "assistant")] | last // null
47
+ | if . == null then "" else
48
+ [.message.content[]? | select(.type == "text") | .text] | join("\n")
49
+ end
50
+ | if test("[Aa]udio [Ss]ummary:") then . else "" end
51
+ ' "$TRANSCRIPT_PATH" 2>/dev/null \
52
+ | sed -n 's/.*[Aa]udio [Ss]ummary:[[:space:]]*\(.*\)/\1/p' \
53
+ | head -1 \
54
+ | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
55
+
56
+ [[ -z "$SUMMARY" ]] && exit 0
57
+
58
+ # Speak via AgentVibes play-tts.sh
59
+ if [[ -f "$PROJECT_ROOT/.claude/hooks/play-tts.sh" ]]; then
60
+ AGENTVIBES_MIN_TOKENS=3 AGENTVIBES_SHORT_TOKENS=50 \
61
+ bash "$PROJECT_ROOT/.claude/hooks/play-tts.sh" "$SUMMARY" >/dev/null 2>&1 &
62
+ fi
63
+ fi
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes