agentvibes 2.16.0 → 2.17.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/.claude/config/audio-effects.cfg +1 -1
- package/.claude/config/audio-effects.cfg.sample +52 -0
- package/.claude/hooks/audio-processor.sh +2 -2
- package/.claude/hooks/bmad-voice-manager.sh +152 -5
- package/.claude/hooks/effects-manager.sh +268 -0
- package/.claude/hooks/learn-manager.sh +7 -7
- package/.claude/hooks/personality-manager.sh +35 -24
- package/.claude/hooks/piper-installer.sh +2 -2
- package/.claude/hooks/provider-manager.sh +4 -4
- package/.claude/hooks/replay-target-audio.sh +1 -1
- package/.claude/hooks/speed-manager.sh +4 -4
- package/.claude/hooks/voice-manager.sh +50 -47
- package/.claude/personalities/angry.md +2 -4
- package/.claude/personalities/annoying.md +2 -4
- package/.claude/personalities/crass.md +2 -4
- package/.claude/personalities/dramatic.md +2 -4
- package/.claude/personalities/dry-humor.md +1 -3
- package/.claude/personalities/flirty.md +2 -4
- package/.claude/personalities/funny.md +2 -4
- package/.claude/personalities/grandpa.md +1 -3
- package/.claude/personalities/millennial.md +2 -4
- package/.claude/personalities/moody.md +2 -4
- package/.claude/personalities/normal.md +2 -4
- package/.claude/personalities/pirate.md +2 -4
- package/.claude/personalities/poetic.md +2 -4
- package/.claude/personalities/professional.md +2 -4
- package/.claude/personalities/rapper.md +1 -3
- package/.claude/personalities/robot.md +2 -4
- package/.claude/personalities/sarcastic.md +2 -4
- package/.claude/personalities/sassy.md +1 -3
- package/.claude/personalities/surfer-dude.md +2 -4
- package/.claude/personalities/zen.md +2 -4
- package/README.md +146 -10
- package/mcp-server/server.py +120 -17
- package/package.json +1 -1
- package/src/cli/list-personalities.js +110 -0
- package/src/cli/list-voices.js +114 -0
- package/src/commands/install-mcp.js +50 -34
- package/src/installer.js +1157 -450
- package/src/utils/dependency-checker.js +403 -0
- package/src/utils/list-formatter.js +194 -0
|
@@ -49,4 +49,4 @@ BMad Master|reverb 50 60 100 pitch -100|agentvibes_soft_flamenco_loop.mp3|0.30
|
|
|
49
49
|
_party_mode|compand 0.3,1 6:-70,-60,-20|agent_vibes_dark_chill_step_loop.mp3|0.40
|
|
50
50
|
|
|
51
51
|
# Default (no agent specified) - clean with subtle enhancement and chillwave background
|
|
52
|
-
default|
|
|
52
|
+
default|gain -8|agent_vibes_chillwave_v2_loop.mp3|0.30
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# AgentVibes Audio Effects Configuration
|
|
2
|
+
# Format: AGENT_NAME|SOX_EFFECTS|BACKGROUND_FILE|BACKGROUND_VOLUME
|
|
3
|
+
#
|
|
4
|
+
# SOX_EFFECTS: sox effect chain (leave empty for none)
|
|
5
|
+
# - reverb <reverberance> <HF-damping> <room-scale>
|
|
6
|
+
# - pitch <cents> (100 cents = 1 semitone)
|
|
7
|
+
# - equalizer <freq> <width>q <gain-dB>
|
|
8
|
+
# - gain <dB>
|
|
9
|
+
# - compand <attack,decay> <soft-knee-dB:in-dB,out-dB>
|
|
10
|
+
#
|
|
11
|
+
# BACKGROUND_FILE: path to ambient audio (relative to .claude/audio/tracks/)
|
|
12
|
+
# BACKGROUND_VOLUME: 0.0-1.0 (0.20-0.40 recommended)
|
|
13
|
+
#
|
|
14
|
+
# Example: John|reverb 30 50 80|my-track.mp3|0.25
|
|
15
|
+
|
|
16
|
+
# BMAD Agents - each with unique audio personality
|
|
17
|
+
|
|
18
|
+
# PM John - upbeat, driving energy
|
|
19
|
+
John|gain -1 equalizer 3000 1q +2|agentvibes_soft_flamenco_loop.mp3|0.30
|
|
20
|
+
|
|
21
|
+
# Architect Winston - deep, authoritative
|
|
22
|
+
Winston|reverb 40 50 90 gain -2|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
23
|
+
|
|
24
|
+
# Developer Amelia - clean, precise
|
|
25
|
+
Amelia|compand 0.3,1 6:-70,-60,-20|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
26
|
+
|
|
27
|
+
# Business Analyst Mary - warm, analytical
|
|
28
|
+
Mary|equalizer 200 1q +3 equalizer 2500 1q -2|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
29
|
+
|
|
30
|
+
# Scrum Master Bob - refined, organized
|
|
31
|
+
Bob|reverb 30 40 70 compand 0.2,0.5 6:-70,-60,-20|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
32
|
+
|
|
33
|
+
# Test Architect Murat - crisp, analytical
|
|
34
|
+
Murat|equalizer 4000 1q +3 compand 0.1,0.3 6:-70,-60,-20|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
35
|
+
|
|
36
|
+
# UX Designer Sally - warm, empathetic
|
|
37
|
+
Sally|reverb 25 40 70 equalizer 300 1q +2|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
38
|
+
|
|
39
|
+
# Tech Writer Paige - clear, patient
|
|
40
|
+
Paige|compand 0.2,0.5 6:-70,-60,-20|agentvibes_soft_flamenco_loop.mp3|0.20
|
|
41
|
+
|
|
42
|
+
# Frame Expert Saif - structured, detail-oriented
|
|
43
|
+
Saif|equalizer 2000 1q +2|agentvibes_soft_flamenco_loop.mp3|0.25
|
|
44
|
+
|
|
45
|
+
# BMad Master - wise orchestrator
|
|
46
|
+
BMad Master|reverb 50 60 100 pitch -100|agentvibes_soft_flamenco_loop.mp3|0.30
|
|
47
|
+
|
|
48
|
+
# Party mode room ambiance - used when multiple agents are talking
|
|
49
|
+
_party_mode|compand 0.3,1 6:-70,-60,-20|agent_vibes_dark_chill_step_loop.mp3|0.40
|
|
50
|
+
|
|
51
|
+
# Default (no agent specified) - clean with subtle enhancement and chillwave background
|
|
52
|
+
default|gain -8|agentvibes_soft_flamenco_loop.mp3|0.30
|
|
@@ -83,7 +83,7 @@ get_agent_config() {
|
|
|
83
83
|
local agent="$1"
|
|
84
84
|
|
|
85
85
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
86
|
-
echo "default
|
|
86
|
+
echo "default|gain -8||0.0"
|
|
87
87
|
return
|
|
88
88
|
fi
|
|
89
89
|
|
|
@@ -100,7 +100,7 @@ get_agent_config() {
|
|
|
100
100
|
if [[ -n "$config" ]]; then
|
|
101
101
|
echo "$config"
|
|
102
102
|
else
|
|
103
|
-
echo "default
|
|
103
|
+
echo "default|gain -8||0.0"
|
|
104
104
|
fi
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -159,10 +159,64 @@ get_agent_voice() {
|
|
|
159
159
|
# Read from BMAD's standard _cfg directory
|
|
160
160
|
# CSV format: agent_id,voice_name
|
|
161
161
|
local voice=$(grep "^$agent_id," "$bmad_voice_map" | cut -d',' -f2)
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
|
|
163
|
+
# If voice is empty or generic (same for all), use defaults
|
|
164
|
+
if [[ -n "$voice" ]] && [[ "$voice" != "en_US-lessac-medium" ]]; then
|
|
165
|
+
echo "$voice"
|
|
166
|
+
return
|
|
167
|
+
fi
|
|
168
|
+
# If empty or generic, fall through to defaults below
|
|
164
169
|
fi
|
|
165
170
|
|
|
171
|
+
# Default voice mappings (hardcoded fallback when CSV is missing or has generic values)
|
|
172
|
+
# These match the BMAD-METHOD defaults for consistency
|
|
173
|
+
case "$agent_id" in
|
|
174
|
+
bmad-master)
|
|
175
|
+
echo "en_US-lessac-medium"
|
|
176
|
+
return
|
|
177
|
+
;;
|
|
178
|
+
analyst)
|
|
179
|
+
echo "en_US-kristin-medium"
|
|
180
|
+
return
|
|
181
|
+
;;
|
|
182
|
+
architect)
|
|
183
|
+
echo "en_GB-alan-medium"
|
|
184
|
+
return
|
|
185
|
+
;;
|
|
186
|
+
dev)
|
|
187
|
+
echo "en_US-joe-medium"
|
|
188
|
+
return
|
|
189
|
+
;;
|
|
190
|
+
pm)
|
|
191
|
+
echo "en_US-ryan-high"
|
|
192
|
+
return
|
|
193
|
+
;;
|
|
194
|
+
quick-flow-solo-dev)
|
|
195
|
+
echo "en_US-joe-medium"
|
|
196
|
+
return
|
|
197
|
+
;;
|
|
198
|
+
sm)
|
|
199
|
+
echo "en_US-amy-medium"
|
|
200
|
+
return
|
|
201
|
+
;;
|
|
202
|
+
tea)
|
|
203
|
+
echo "en_US-kusal-medium"
|
|
204
|
+
return
|
|
205
|
+
;;
|
|
206
|
+
tech-writer)
|
|
207
|
+
echo "en_US-kristin-medium"
|
|
208
|
+
return
|
|
209
|
+
;;
|
|
210
|
+
ux-designer)
|
|
211
|
+
echo "en_US-kristin-medium"
|
|
212
|
+
return
|
|
213
|
+
;;
|
|
214
|
+
frame-expert)
|
|
215
|
+
echo "en_GB-alan-medium"
|
|
216
|
+
return
|
|
217
|
+
;;
|
|
218
|
+
esac
|
|
219
|
+
|
|
166
220
|
# Auto-enable if BMAD is detected (for legacy markdown config)
|
|
167
221
|
auto_enable_if_bmad_detected
|
|
168
222
|
|
|
@@ -212,13 +266,106 @@ get_agent_voice() {
|
|
|
212
266
|
# @returns Echoes intro text to stdout, empty string if not configured
|
|
213
267
|
# @exitcode Always 0
|
|
214
268
|
# @sideeffects None
|
|
215
|
-
# @edgecases Returns empty string if plugin file missing, parses column 3 of markdown table
|
|
269
|
+
# @edgecases Returns empty string if plugin file missing, parses column 3 of CSV or markdown table
|
|
216
270
|
# @calledby bmad-speak.sh for agent identification in party mode
|
|
217
|
-
# @calls grep, awk, sed
|
|
218
|
-
# @version 2.
|
|
271
|
+
# @calls grep, awk, sed, cut
|
|
272
|
+
# @version 2.2.0 - Now supports CSV file format, falls back to agent name from manifest if intro missing
|
|
219
273
|
get_agent_intro() {
|
|
220
274
|
local agent_id="$1"
|
|
221
275
|
|
|
276
|
+
# Check for BMAD v6 CSV file first (preferred, loose coupling)
|
|
277
|
+
# If this exists, use it directly without requiring plugin enable flag
|
|
278
|
+
# Support both .bmad (standard) and bmad (alternative) paths
|
|
279
|
+
local bmad_voice_map=""
|
|
280
|
+
if [[ -f ".bmad/_cfg/agent-voice-map.csv" ]]; then
|
|
281
|
+
bmad_voice_map=".bmad/_cfg/agent-voice-map.csv"
|
|
282
|
+
elif [[ -f "bmad/_cfg/agent-voice-map.csv" ]]; then
|
|
283
|
+
bmad_voice_map="bmad/_cfg/agent-voice-map.csv"
|
|
284
|
+
fi
|
|
285
|
+
|
|
286
|
+
if [[ -n "$bmad_voice_map" ]]; then
|
|
287
|
+
# Read from BMAD's standard _cfg directory
|
|
288
|
+
# CSV format: agent,voice,intro
|
|
289
|
+
local intro=$(grep "^$agent_id," "$bmad_voice_map" | cut -d',' -f3 | sed 's/^"//;s/"$//')
|
|
290
|
+
|
|
291
|
+
# If intro is empty or generic, fall back to agent display name from manifest
|
|
292
|
+
if [[ -z "$intro" ]] || [[ "$intro" == "Hello! Ready to help with the discussion." ]]; then
|
|
293
|
+
# Try to get display name from agent-manifest.csv
|
|
294
|
+
local manifest_file=""
|
|
295
|
+
if [[ -f ".bmad/_cfg/agent-manifest.csv" ]]; then
|
|
296
|
+
manifest_file=".bmad/_cfg/agent-manifest.csv"
|
|
297
|
+
elif [[ -f "bmad/_cfg/agent-manifest.csv" ]]; then
|
|
298
|
+
manifest_file="bmad/_cfg/agent-manifest.csv"
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
if [[ -n "$manifest_file" ]]; then
|
|
302
|
+
# Extract displayName (column 2) where name (column 1) matches agent_id
|
|
303
|
+
# CSV format: name,displayName,title,icon,role,...
|
|
304
|
+
local display_name=$(grep "^\"*${agent_id}\"*," "$manifest_file" | cut -d',' -f2 | sed 's/^"//;s/"$//')
|
|
305
|
+
if [[ -n "$display_name" ]]; then
|
|
306
|
+
intro="$display_name here"
|
|
307
|
+
fi
|
|
308
|
+
fi
|
|
309
|
+
fi
|
|
310
|
+
|
|
311
|
+
# If we got an intro, return it
|
|
312
|
+
if [[ -n "$intro" ]]; then
|
|
313
|
+
echo "$intro"
|
|
314
|
+
return
|
|
315
|
+
fi
|
|
316
|
+
# Otherwise fall through to hardcoded defaults below
|
|
317
|
+
fi
|
|
318
|
+
|
|
319
|
+
# Hardcoded default intro mappings (final fallback)
|
|
320
|
+
# These match the BMAD-METHOD agent display names for consistency
|
|
321
|
+
case "$agent_id" in
|
|
322
|
+
bmad-master)
|
|
323
|
+
echo "BMad Master here"
|
|
324
|
+
return
|
|
325
|
+
;;
|
|
326
|
+
analyst)
|
|
327
|
+
echo "Mary here"
|
|
328
|
+
return
|
|
329
|
+
;;
|
|
330
|
+
architect)
|
|
331
|
+
echo "Winston here"
|
|
332
|
+
return
|
|
333
|
+
;;
|
|
334
|
+
dev)
|
|
335
|
+
echo "Amelia here"
|
|
336
|
+
return
|
|
337
|
+
;;
|
|
338
|
+
pm)
|
|
339
|
+
echo "John here"
|
|
340
|
+
return
|
|
341
|
+
;;
|
|
342
|
+
quick-flow-solo-dev)
|
|
343
|
+
echo "Barry here"
|
|
344
|
+
return
|
|
345
|
+
;;
|
|
346
|
+
sm)
|
|
347
|
+
echo "Bob here"
|
|
348
|
+
return
|
|
349
|
+
;;
|
|
350
|
+
tea)
|
|
351
|
+
echo "Murat here"
|
|
352
|
+
return
|
|
353
|
+
;;
|
|
354
|
+
tech-writer)
|
|
355
|
+
echo "Paige here"
|
|
356
|
+
return
|
|
357
|
+
;;
|
|
358
|
+
ux-designer)
|
|
359
|
+
echo "Sally here"
|
|
360
|
+
return
|
|
361
|
+
;;
|
|
362
|
+
frame-expert)
|
|
363
|
+
echo "Frame Expert here"
|
|
364
|
+
return
|
|
365
|
+
;;
|
|
366
|
+
esac
|
|
367
|
+
|
|
368
|
+
# Fallback to legacy markdown config file
|
|
222
369
|
if [[ ! -f "$VOICE_CONFIG_FILE" ]]; then
|
|
223
370
|
echo ""
|
|
224
371
|
return
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# File: .claude/hooks/effects-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
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
# Get script directory and config file path
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
CONFIG_FILE="$SCRIPT_DIR/../config/audio-effects.cfg"
|
|
29
|
+
|
|
30
|
+
# Reverb level mappings (reverberance HF-damping room-scale)
|
|
31
|
+
declare -A REVERB_LEVELS=(
|
|
32
|
+
["off"]=""
|
|
33
|
+
["light"]="reverb 20 50 50"
|
|
34
|
+
["medium"]="reverb 40 50 70"
|
|
35
|
+
["heavy"]="reverb 70 50 100"
|
|
36
|
+
["cathedral"]="reverb 90 30 100"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# @function get_agent_effects
|
|
40
|
+
# @intent Get current effects configuration for an agent
|
|
41
|
+
# @param $1 Agent name (or "default")
|
|
42
|
+
# @returns Echoes the SOX effects string
|
|
43
|
+
get_agent_effects() {
|
|
44
|
+
local agent_name="$1"
|
|
45
|
+
|
|
46
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
47
|
+
echo ""
|
|
48
|
+
return
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Read agent config line, format: AGENT_NAME|SOX_EFFECTS|BACKGROUND_FILE|BACKGROUND_VOLUME
|
|
52
|
+
local config_line=$(grep "^${agent_name}|" "$CONFIG_FILE" 2>/dev/null || echo "")
|
|
53
|
+
|
|
54
|
+
if [[ -z "$config_line" ]]; then
|
|
55
|
+
# Try default
|
|
56
|
+
config_line=$(grep "^default|" "$CONFIG_FILE" 2>/dev/null || echo "")
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [[ -n "$config_line" ]]; then
|
|
60
|
+
echo "$config_line" | cut -d'|' -f2
|
|
61
|
+
else
|
|
62
|
+
echo ""
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# @function set_reverb
|
|
67
|
+
# @intent Set reverb level for an agent or globally
|
|
68
|
+
# @param $1 Reverb level (off, light, medium, heavy, cathedral)
|
|
69
|
+
# @param $2 Agent name (optional, defaults to "default")
|
|
70
|
+
# @param $3 --all flag (optional, applies to all agents)
|
|
71
|
+
set_reverb() {
|
|
72
|
+
local level="$1"
|
|
73
|
+
local agent_name="${2:-default}"
|
|
74
|
+
local apply_all="${3:-}"
|
|
75
|
+
|
|
76
|
+
# Validate level
|
|
77
|
+
if [[ ! -v REVERB_LEVELS[$level] ]]; then
|
|
78
|
+
echo "❌ Invalid reverb level: $level"
|
|
79
|
+
echo "Valid levels: off, light, medium, heavy, cathedral"
|
|
80
|
+
return 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
local reverb_effect="${REVERB_LEVELS[$level]}"
|
|
84
|
+
|
|
85
|
+
if [[ "$apply_all" == "--all" ]]; then
|
|
86
|
+
# Apply to all agents in config
|
|
87
|
+
echo "🎛️ Setting reverb to '$level' for all agents..."
|
|
88
|
+
|
|
89
|
+
# Create temp file
|
|
90
|
+
local temp_file="${CONFIG_FILE}.tmp"
|
|
91
|
+
|
|
92
|
+
# Process each line
|
|
93
|
+
while IFS='|' read -r agent sox_effects bg_file bg_vol || [[ -n "$agent" ]]; do
|
|
94
|
+
# Skip comments and empty lines
|
|
95
|
+
if [[ "$agent" =~ ^# ]] || [[ -z "$agent" ]]; then
|
|
96
|
+
echo "$agent|$sox_effects|$bg_file|$bg_vol" >> "$temp_file"
|
|
97
|
+
continue
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Remove existing reverb from sox effects
|
|
101
|
+
local new_effects=$(echo "$sox_effects" | sed -E 's/reverb [0-9]+ [0-9]+ [0-9]+//g' | sed 's/ */ /g' | sed 's/^ //;s/ $//')
|
|
102
|
+
|
|
103
|
+
# Add new reverb if not off
|
|
104
|
+
if [[ -n "$reverb_effect" ]]; then
|
|
105
|
+
if [[ -n "$new_effects" ]]; then
|
|
106
|
+
new_effects="$reverb_effect $new_effects"
|
|
107
|
+
else
|
|
108
|
+
new_effects="$reverb_effect"
|
|
109
|
+
fi
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
echo "${agent}|${new_effects}|${bg_file}|${bg_vol}" >> "$temp_file"
|
|
113
|
+
done < "$CONFIG_FILE"
|
|
114
|
+
|
|
115
|
+
# Replace original with temp
|
|
116
|
+
mv "$temp_file" "$CONFIG_FILE"
|
|
117
|
+
|
|
118
|
+
echo "✅ Reverb set to '$level' for all agents"
|
|
119
|
+
else
|
|
120
|
+
# Apply to specific agent
|
|
121
|
+
echo "🎛️ Setting reverb to '$level' for '$agent_name'..."
|
|
122
|
+
|
|
123
|
+
# Check if agent exists in config
|
|
124
|
+
if ! grep -q "^${agent_name}|" "$CONFIG_FILE" 2>/dev/null; then
|
|
125
|
+
# Agent doesn't exist, add it with just reverb
|
|
126
|
+
echo "${agent_name}|${reverb_effect}|agentvibes_soft_flamenco_loop.mp3|0.30" >> "$CONFIG_FILE"
|
|
127
|
+
echo "✅ Created new config for '$agent_name' with reverb '$level'"
|
|
128
|
+
return
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Create temp file
|
|
132
|
+
local temp_file="${CONFIG_FILE}.tmp"
|
|
133
|
+
|
|
134
|
+
# Process each line
|
|
135
|
+
while IFS='|' read -r agent sox_effects bg_file bg_vol || [[ -n "$agent" ]]; do
|
|
136
|
+
# Skip comments and empty lines
|
|
137
|
+
if [[ "$agent" =~ ^# ]] || [[ -z "$agent" ]]; then
|
|
138
|
+
echo "$agent|$sox_effects|$bg_file|$bg_vol" >> "$temp_file"
|
|
139
|
+
continue
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
if [[ "$agent" == "$agent_name" ]]; then
|
|
143
|
+
# Remove existing reverb from sox effects
|
|
144
|
+
local new_effects=$(echo "$sox_effects" | sed -E 's/reverb [0-9]+ [0-9]+ [0-9]+//g' | sed 's/ */ /g' | sed 's/^ //;s/ $//')
|
|
145
|
+
|
|
146
|
+
# Add new reverb if not off
|
|
147
|
+
if [[ -n "$reverb_effect" ]]; then
|
|
148
|
+
if [[ -n "$new_effects" ]]; then
|
|
149
|
+
new_effects="$reverb_effect $new_effects"
|
|
150
|
+
else
|
|
151
|
+
new_effects="$reverb_effect"
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
echo "${agent}|${new_effects}|${bg_file}|${bg_vol}" >> "$temp_file"
|
|
156
|
+
else
|
|
157
|
+
echo "${agent}|${sox_effects}|${bg_file}|${bg_vol}" >> "$temp_file"
|
|
158
|
+
fi
|
|
159
|
+
done < "$CONFIG_FILE"
|
|
160
|
+
|
|
161
|
+
# Replace original with temp
|
|
162
|
+
mv "$temp_file" "$CONFIG_FILE"
|
|
163
|
+
|
|
164
|
+
echo "✅ Reverb set to '$level' for '$agent_name'"
|
|
165
|
+
fi
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
# @function list_effects
|
|
169
|
+
# @intent List current effects for all agents
|
|
170
|
+
list_effects() {
|
|
171
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
172
|
+
echo "❌ Config file not found: $CONFIG_FILE"
|
|
173
|
+
return 1
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
echo "📊 Current Audio Effects Configuration:"
|
|
177
|
+
echo ""
|
|
178
|
+
|
|
179
|
+
while IFS='|' read -r agent sox_effects bg_file bg_vol || [[ -n "$agent" ]]; do
|
|
180
|
+
# Skip comments and empty lines
|
|
181
|
+
if [[ "$agent" =~ ^# ]] || [[ -z "$agent" ]]; then
|
|
182
|
+
continue
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
# Extract reverb level if present
|
|
186
|
+
local reverb_level="off"
|
|
187
|
+
if [[ "$sox_effects" =~ reverb\ ([0-9]+)\ ([0-9]+)\ ([0-9]+) ]]; then
|
|
188
|
+
local reverb_val="${BASH_REMATCH[1]}"
|
|
189
|
+
if [[ "$reverb_val" -le 20 ]]; then
|
|
190
|
+
reverb_level="light"
|
|
191
|
+
elif [[ "$reverb_val" -le 40 ]]; then
|
|
192
|
+
reverb_level="medium"
|
|
193
|
+
elif [[ "$reverb_val" -le 70 ]]; then
|
|
194
|
+
reverb_level="heavy"
|
|
195
|
+
else
|
|
196
|
+
reverb_level="cathedral"
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
echo " $agent: reverb=$reverb_level"
|
|
201
|
+
if [[ -n "$sox_effects" ]]; then
|
|
202
|
+
echo " Effects: $sox_effects"
|
|
203
|
+
fi
|
|
204
|
+
done < "$CONFIG_FILE"
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
# @function get_reverb_level
|
|
208
|
+
# @intent Get current reverb level for an agent
|
|
209
|
+
# @param $1 Agent name (or "default")
|
|
210
|
+
# @returns Echoes reverb level name (off, light, medium, heavy, cathedral)
|
|
211
|
+
get_reverb_level() {
|
|
212
|
+
local agent_name="$1"
|
|
213
|
+
local effects=$(get_agent_effects "$agent_name")
|
|
214
|
+
|
|
215
|
+
if [[ -z "$effects" ]] || [[ ! "$effects" =~ reverb ]]; then
|
|
216
|
+
echo "off"
|
|
217
|
+
return
|
|
218
|
+
fi
|
|
219
|
+
|
|
220
|
+
# Extract reverb parameters
|
|
221
|
+
if [[ "$effects" =~ reverb\ ([0-9]+)\ ([0-9]+)\ ([0-9]+) ]]; then
|
|
222
|
+
local reverb_val="${BASH_REMATCH[1]}"
|
|
223
|
+
if [[ "$reverb_val" -le 20 ]]; then
|
|
224
|
+
echo "light"
|
|
225
|
+
elif [[ "$reverb_val" -le 40 ]]; then
|
|
226
|
+
echo "medium"
|
|
227
|
+
elif [[ "$reverb_val" -le 70 ]]; then
|
|
228
|
+
echo "heavy"
|
|
229
|
+
else
|
|
230
|
+
echo "cathedral"
|
|
231
|
+
fi
|
|
232
|
+
else
|
|
233
|
+
echo "off"
|
|
234
|
+
fi
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# Main command dispatcher
|
|
238
|
+
case "${1:-help}" in
|
|
239
|
+
set-reverb)
|
|
240
|
+
if [[ -z "${2:-}" ]]; then
|
|
241
|
+
echo "Usage: effects-manager.sh set-reverb <level> [agent-name] [--all]"
|
|
242
|
+
echo "Levels: off, light, medium, heavy, cathedral"
|
|
243
|
+
exit 1
|
|
244
|
+
fi
|
|
245
|
+
set_reverb "$2" "${3:-default}" "${4:-}"
|
|
246
|
+
;;
|
|
247
|
+
get-reverb)
|
|
248
|
+
get_reverb_level "${2:-default}"
|
|
249
|
+
;;
|
|
250
|
+
get-effects)
|
|
251
|
+
get_agent_effects "${2:-default}"
|
|
252
|
+
;;
|
|
253
|
+
list)
|
|
254
|
+
list_effects
|
|
255
|
+
;;
|
|
256
|
+
*)
|
|
257
|
+
echo "Usage: effects-manager.sh {set-reverb|get-reverb|get-effects|list}"
|
|
258
|
+
echo ""
|
|
259
|
+
echo "Commands:"
|
|
260
|
+
echo " set-reverb <level> [agent] [--all] Set reverb level"
|
|
261
|
+
echo " get-reverb [agent] Get current reverb level"
|
|
262
|
+
echo " get-effects [agent] Get all effects for agent"
|
|
263
|
+
echo " list List all agent effects"
|
|
264
|
+
echo ""
|
|
265
|
+
echo "Reverb Levels: off, light, medium, heavy, cathedral"
|
|
266
|
+
exit 1
|
|
267
|
+
;;
|
|
268
|
+
esac
|
|
@@ -187,7 +187,7 @@ set_target_language() {
|
|
|
187
187
|
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
188
188
|
provider=$(cat "$HOME/.claude/tts-provider.txt")
|
|
189
189
|
else
|
|
190
|
-
provider="
|
|
190
|
+
provider="piper"
|
|
191
191
|
fi
|
|
192
192
|
echo -e " (for ${GREEN}$provider${NC} TTS)"
|
|
193
193
|
echo ""
|
|
@@ -207,7 +207,7 @@ set_target_language() {
|
|
|
207
207
|
echo -e "${YELLOW} (Voice not yet downloaded - greeting will play after first download)${NC}"
|
|
208
208
|
fi
|
|
209
209
|
else
|
|
210
|
-
#
|
|
210
|
+
# macOS or other provider - just play it in background
|
|
211
211
|
nohup "$SCRIPT_DIR/play-tts.sh" "$greeting" "$recommended_voice" >/dev/null 2>&1 &
|
|
212
212
|
fi
|
|
213
213
|
else
|
|
@@ -228,7 +228,7 @@ get_recommended_voice_for_language() {
|
|
|
228
228
|
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
229
229
|
provider=$(cat "$HOME/.claude/tts-provider.txt")
|
|
230
230
|
else
|
|
231
|
-
provider="
|
|
231
|
+
provider="piper" # Default
|
|
232
232
|
fi
|
|
233
233
|
|
|
234
234
|
# Source language manager and get provider-specific voice
|
|
@@ -279,7 +279,7 @@ suggest_voice_for_language() {
|
|
|
279
279
|
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
280
280
|
provider=$(cat "$HOME/.claude/tts-provider.txt")
|
|
281
281
|
else
|
|
282
|
-
provider="
|
|
282
|
+
provider="piper"
|
|
283
283
|
fi
|
|
284
284
|
|
|
285
285
|
echo ""
|
|
@@ -351,7 +351,7 @@ enable_learn_mode() {
|
|
|
351
351
|
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
352
352
|
provider=$(cat "$HOME/.claude/tts-provider.txt")
|
|
353
353
|
else
|
|
354
|
-
provider="
|
|
354
|
+
provider="piper"
|
|
355
355
|
fi
|
|
356
356
|
echo -e " (for ${GREEN}$provider${NC} TTS)"
|
|
357
357
|
echo ""
|
|
@@ -374,7 +374,7 @@ enable_learn_mode() {
|
|
|
374
374
|
elif [[ -f "$HOME/.claude/tts-provider.txt" ]]; then
|
|
375
375
|
provider=$(cat "$HOME/.claude/tts-provider.txt")
|
|
376
376
|
else
|
|
377
|
-
provider="
|
|
377
|
+
provider="piper"
|
|
378
378
|
fi
|
|
379
379
|
|
|
380
380
|
# Check if we're using Piper and if the voice is available
|
|
@@ -388,7 +388,7 @@ enable_learn_mode() {
|
|
|
388
388
|
echo -e "${YELLOW} (Voice not yet downloaded - greeting will play after first download)${NC}"
|
|
389
389
|
fi
|
|
390
390
|
else
|
|
391
|
-
#
|
|
391
|
+
# macOS or other provider - just play it in background
|
|
392
392
|
nohup "$SCRIPT_DIR/play-tts.sh" "$greeting" "$target_voice" >/dev/null 2>&1 &
|
|
393
393
|
fi
|
|
394
394
|
fi
|
|
@@ -110,38 +110,48 @@ list_personalities() {
|
|
|
110
110
|
|
|
111
111
|
case "$1" in
|
|
112
112
|
list)
|
|
113
|
-
echo "🎭 Available Personalities:"
|
|
114
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
115
|
-
|
|
116
113
|
# Get current personality
|
|
117
114
|
CURRENT="normal"
|
|
118
115
|
if [ -f "$PERSONALITY_FILE" ]; then
|
|
119
116
|
CURRENT=$(cat "$PERSONALITY_FILE")
|
|
120
117
|
fi
|
|
121
118
|
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
# Use Node.js formatter for beautiful boxen display
|
|
120
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
121
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
122
|
+
FORMATTER="$PROJECT_ROOT/src/cli/list-personalities.js"
|
|
123
|
+
|
|
124
|
+
# Use Node.js formatter if available
|
|
125
|
+
if [[ -f "$FORMATTER" ]] && command -v node &> /dev/null; then
|
|
126
|
+
node "$FORMATTER" "$PERSONALITIES_DIR" "$CURRENT"
|
|
127
|
+
else
|
|
128
|
+
# Fallback to plain text display
|
|
129
|
+
echo "🎭 Available Personalities:"
|
|
130
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
131
|
+
|
|
132
|
+
echo "Built-in personalities:"
|
|
133
|
+
for personality in $(list_personalities | sort); do
|
|
134
|
+
desc=$(get_personality_data "$personality" "description")
|
|
135
|
+
if [[ "$personality" == "$CURRENT" ]]; then
|
|
136
|
+
echo " ✓ $personality - $desc (current)"
|
|
137
|
+
else
|
|
138
|
+
echo " - $personality - $desc"
|
|
139
|
+
fi
|
|
140
|
+
done
|
|
141
|
+
|
|
142
|
+
# Add random option
|
|
143
|
+
if [[ "$CURRENT" == "random" ]]; then
|
|
144
|
+
echo " ✓ random - Picks randomly each time (current)"
|
|
128
145
|
else
|
|
129
|
-
echo " -
|
|
146
|
+
echo " - random - Picks randomly each time"
|
|
130
147
|
fi
|
|
131
|
-
done
|
|
132
148
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
echo "
|
|
136
|
-
|
|
137
|
-
echo "
|
|
149
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
150
|
+
echo ""
|
|
151
|
+
echo "Usage: /agent-vibes:personality <name>"
|
|
152
|
+
echo " /agent-vibes:personality add <name>"
|
|
153
|
+
echo " /agent-vibes:personality edit <name>"
|
|
138
154
|
fi
|
|
139
|
-
|
|
140
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
141
|
-
echo ""
|
|
142
|
-
echo "Usage: /agent-vibes:personality <name>"
|
|
143
|
-
echo " /agent-vibes:personality add <name>"
|
|
144
|
-
echo " /agent-vibes:personality edit <name>"
|
|
145
155
|
;;
|
|
146
156
|
|
|
147
157
|
set|switch)
|
|
@@ -367,8 +377,9 @@ EOF
|
|
|
367
377
|
VOICE_FIELD="piper_voice"
|
|
368
378
|
CURRENT_VOICE=$(get_personality_data "$PERSONALITY" "piper_voice")
|
|
369
379
|
else
|
|
370
|
-
|
|
371
|
-
|
|
380
|
+
# macOS or other provider
|
|
381
|
+
VOICE_FIELD="macos_voice"
|
|
382
|
+
CURRENT_VOICE=$(get_personality_data "$PERSONALITY" "macos_voice")
|
|
372
383
|
fi
|
|
373
384
|
|
|
374
385
|
# Check if personality already has a favorite voice assigned
|
|
@@ -68,8 +68,8 @@ elif grep -qi microsoft /proc/version 2>/dev/null || [[ "$PLATFORM" == "Linux" ]
|
|
|
68
68
|
else
|
|
69
69
|
echo "❌ Unsupported platform: $PLATFORM"
|
|
70
70
|
echo ""
|
|
71
|
-
echo " For Windows, use
|
|
72
|
-
echo " /agent-vibes:provider switch
|
|
71
|
+
echo " For Windows, use macOS provider instead:"
|
|
72
|
+
echo " /agent-vibes:provider switch macos"
|
|
73
73
|
exit 1
|
|
74
74
|
fi
|
|
75
75
|
|