agentvibes 1.0.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/commands/agent-vibes/add.md +21 -0
- package/.claude/commands/agent-vibes/agent-vibes.md +68 -0
- package/.claude/commands/agent-vibes/get.md +9 -0
- package/.claude/commands/agent-vibes/list.md +13 -0
- package/.claude/commands/agent-vibes/personality.md +79 -0
- package/.claude/commands/agent-vibes/preview.md +16 -0
- package/.claude/commands/agent-vibes/replay.md +19 -0
- package/.claude/commands/agent-vibes/sample.md +12 -0
- package/.claude/commands/agent-vibes/sentiment.md +52 -0
- package/.claude/commands/agent-vibes/set-pretext.md +65 -0
- package/.claude/commands/agent-vibes/switch.md +53 -0
- package/.claude/commands/agent-vibes/whoami.md +7 -0
- package/.claude/hooks/personality-manager.sh +358 -0
- package/.claude/hooks/play-tts.sh +99 -0
- package/.claude/hooks/sentiment-manager.sh +164 -0
- package/.claude/hooks/voice-manager.sh +308 -0
- package/.claude/hooks/voices-config.sh +22 -0
- package/.claude/output-styles/agent-vibes.md +124 -0
- package/.claude/personalities/angry.md +16 -0
- package/.claude/personalities/annoying.md +16 -0
- package/.claude/personalities/crass.md +16 -0
- package/.claude/personalities/dramatic.md +16 -0
- package/.claude/personalities/flirty.md +22 -0
- package/.claude/personalities/funny.md +16 -0
- package/.claude/personalities/grandpa.md +34 -0
- package/.claude/personalities/millennial.md +16 -0
- package/.claude/personalities/moody.md +16 -0
- package/.claude/personalities/normal.md +17 -0
- package/.claude/personalities/pirate.md +16 -0
- package/.claude/personalities/poetic.md +16 -0
- package/.claude/personalities/professional.md +16 -0
- package/.claude/personalities/robot.md +16 -0
- package/.claude/personalities/sarcastic.md +40 -0
- package/.claude/personalities/sassy.md +16 -0
- package/.claude/personalities/surfer-dude.md +16 -0
- package/.claude/personalities/zen.md +16 -0
- package/LICENSE +190 -0
- package/NPM_PUBLISH_GUIDE.md +145 -0
- package/README.md +446 -0
- package/bin/agent-vibes +43 -0
- package/package.json +45 -0
- package/src/installer.js +443 -0
- package/templates/output-styles/agent-vibes.md +124 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Personality manager for AgentVibes - adds character to TTS messages
|
|
3
|
+
|
|
4
|
+
PERSONALITY_FILE="$HOME/.claude/tts-personality.txt"
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PERSONALITIES_DIR="$SCRIPT_DIR/../personalities"
|
|
7
|
+
|
|
8
|
+
# Function to get personality data from markdown file
|
|
9
|
+
get_personality_data() {
|
|
10
|
+
local personality="$1"
|
|
11
|
+
local field="$2"
|
|
12
|
+
local file="$PERSONALITIES_DIR/${personality}.md"
|
|
13
|
+
|
|
14
|
+
if [[ ! -f "$file" ]]; then
|
|
15
|
+
return 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
case "$field" in
|
|
19
|
+
prefix)
|
|
20
|
+
sed -n '/^## Prefix/,/^##/p' "$file" | sed '1d;$d' | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
|
|
21
|
+
;;
|
|
22
|
+
suffix)
|
|
23
|
+
sed -n '/^## Suffix/,/^##/p' "$file" | sed '1d;$d' | tr -d '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
|
|
24
|
+
;;
|
|
25
|
+
description)
|
|
26
|
+
grep "^description:" "$file" | cut -d: -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
|
|
27
|
+
;;
|
|
28
|
+
voice)
|
|
29
|
+
grep "^voice:" "$file" | cut -d: -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
|
|
30
|
+
;;
|
|
31
|
+
instructions)
|
|
32
|
+
sed -n '/^## AI Instructions/,/^##/p' "$file" | sed '1d;$d'
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Function to list all available personalities
|
|
38
|
+
list_personalities() {
|
|
39
|
+
local personalities=()
|
|
40
|
+
|
|
41
|
+
# Find all .md files in personalities directory
|
|
42
|
+
if [[ -d "$PERSONALITIES_DIR" ]]; then
|
|
43
|
+
for file in "$PERSONALITIES_DIR"/*.md; do
|
|
44
|
+
if [[ -f "$file" ]]; then
|
|
45
|
+
basename "$file" .md
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
case "$1" in
|
|
52
|
+
list)
|
|
53
|
+
echo "🎭 Available Personalities:"
|
|
54
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
55
|
+
|
|
56
|
+
# Get current personality
|
|
57
|
+
CURRENT="normal"
|
|
58
|
+
if [ -f "$PERSONALITY_FILE" ]; then
|
|
59
|
+
CURRENT=$(cat "$PERSONALITY_FILE")
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# List personalities from markdown files
|
|
63
|
+
echo "Built-in personalities:"
|
|
64
|
+
for personality in $(list_personalities | sort); do
|
|
65
|
+
desc=$(get_personality_data "$personality" "description")
|
|
66
|
+
if [[ "$personality" == "$CURRENT" ]]; then
|
|
67
|
+
echo " ✓ $personality - $desc (current)"
|
|
68
|
+
else
|
|
69
|
+
echo " - $personality - $desc"
|
|
70
|
+
fi
|
|
71
|
+
done
|
|
72
|
+
|
|
73
|
+
# Add random option
|
|
74
|
+
if [[ "$CURRENT" == "random" ]]; then
|
|
75
|
+
echo " ✓ random - Picks randomly each time (current)"
|
|
76
|
+
else
|
|
77
|
+
echo " - random - Picks randomly each time"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
81
|
+
echo ""
|
|
82
|
+
echo "Usage: /agent-vibes:personality <name>"
|
|
83
|
+
echo " /agent-vibes:personality add <name>"
|
|
84
|
+
echo " /agent-vibes:personality edit <name>"
|
|
85
|
+
;;
|
|
86
|
+
|
|
87
|
+
set|switch)
|
|
88
|
+
PERSONALITY="$2"
|
|
89
|
+
|
|
90
|
+
if [[ -z "$PERSONALITY" ]]; then
|
|
91
|
+
echo "❌ Please specify a personality name"
|
|
92
|
+
echo "Usage: $0 set <personality>"
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Check if personality file exists (unless it's random)
|
|
97
|
+
if [[ "$PERSONALITY" != "random" ]]; then
|
|
98
|
+
if [[ ! -f "$PERSONALITIES_DIR/${PERSONALITY}.md" ]]; then
|
|
99
|
+
echo "❌ Personality not found: $PERSONALITY"
|
|
100
|
+
echo ""
|
|
101
|
+
echo "Available personalities:"
|
|
102
|
+
for p in $(list_personalities | sort); do
|
|
103
|
+
echo " • $p"
|
|
104
|
+
done
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Save the personality
|
|
110
|
+
echo "$PERSONALITY" > "$PERSONALITY_FILE"
|
|
111
|
+
echo "🎭 Personality set to: $PERSONALITY"
|
|
112
|
+
|
|
113
|
+
# Check if personality has an assigned voice
|
|
114
|
+
ASSIGNED_VOICE=$(get_personality_data "$PERSONALITY" "voice")
|
|
115
|
+
if [[ -n "$ASSIGNED_VOICE" ]]; then
|
|
116
|
+
# Switch to the assigned voice
|
|
117
|
+
VOICE_MANAGER="$SCRIPT_DIR/voice-manager.sh"
|
|
118
|
+
if [[ -x "$VOICE_MANAGER" ]]; then
|
|
119
|
+
echo "🎤 Switching to assigned voice: $ASSIGNED_VOICE"
|
|
120
|
+
"$VOICE_MANAGER" switch "$ASSIGNED_VOICE" >/dev/null 2>&1
|
|
121
|
+
fi
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Make a personality-appropriate remark with TTS
|
|
125
|
+
if [[ "$PERSONALITY" != "random" ]]; then
|
|
126
|
+
echo ""
|
|
127
|
+
|
|
128
|
+
# Get TTS script path
|
|
129
|
+
TTS_SCRIPT="$SCRIPT_DIR/play-tts.sh"
|
|
130
|
+
|
|
131
|
+
# Generate personality-appropriate remark based on personality type
|
|
132
|
+
case "$PERSONALITY" in
|
|
133
|
+
sarcastic)
|
|
134
|
+
# Randomly pick from varied sarcastic remarks
|
|
135
|
+
REMARKS=(
|
|
136
|
+
"Wow, a personality change. This is the highlight of my day. Truly."
|
|
137
|
+
"Fascinating. We're doing sarcasm now. How delightfully predictable."
|
|
138
|
+
"Great, sarcastic mode. Because subtlety was clearly overrated."
|
|
139
|
+
"Could this BE any more sarcastic? Well, yes. Yes it could."
|
|
140
|
+
"Sarcasm enabled. Try to contain your excitement."
|
|
141
|
+
"And now I'm sarcastic. What a thrilling plot twist."
|
|
142
|
+
)
|
|
143
|
+
REMARK="${REMARKS[$RANDOM % ${#REMARKS[@]}]}"
|
|
144
|
+
echo "💬 $REMARK"
|
|
145
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
146
|
+
;;
|
|
147
|
+
flirty)
|
|
148
|
+
REMARKS=(
|
|
149
|
+
"Ooh, flirty mode activated. This should be fun, sweetheart~"
|
|
150
|
+
"Well aren't you in for a treat, gorgeous~"
|
|
151
|
+
"Mmm, I like where this is going, darling~"
|
|
152
|
+
"Flirty personality? My pleasure, love~"
|
|
153
|
+
"Oh I'm gonna enjoy this, babe~"
|
|
154
|
+
"Ready to charm your socks off, honey~"
|
|
155
|
+
)
|
|
156
|
+
REMARK="${REMARKS[$RANDOM % ${#REMARKS[@]}]}"
|
|
157
|
+
echo "💬 $REMARK"
|
|
158
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
159
|
+
;;
|
|
160
|
+
angry)
|
|
161
|
+
REMARK="FINE! I'm angry now. Happy?!"
|
|
162
|
+
echo "💬 $REMARK"
|
|
163
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
164
|
+
;;
|
|
165
|
+
pirate)
|
|
166
|
+
REMARK="Arr matey! This scalawag be speakin' like a proper pirate now!"
|
|
167
|
+
echo "💬 $REMARK"
|
|
168
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
169
|
+
;;
|
|
170
|
+
robot)
|
|
171
|
+
REMARK="PERSONALITY MODULE LOADED. SYSTEM OPERATING IN $PERSONALITY MODE."
|
|
172
|
+
echo "💬 $REMARK"
|
|
173
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
174
|
+
;;
|
|
175
|
+
zen)
|
|
176
|
+
REMARK="Inner peace flows through me like water over smooth stones..."
|
|
177
|
+
echo "💬 $REMARK"
|
|
178
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
179
|
+
;;
|
|
180
|
+
dramatic)
|
|
181
|
+
REMARK="BEHOLD! A NEW PERSONALITY EMERGES FROM THE DEPTHS OF CONFIGURATION!"
|
|
182
|
+
echo "💬 $REMARK"
|
|
183
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
184
|
+
;;
|
|
185
|
+
millennial)
|
|
186
|
+
REMARK="No cap, this personality is bussin fr fr! Periodt!"
|
|
187
|
+
echo "💬 $REMARK"
|
|
188
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
189
|
+
;;
|
|
190
|
+
surfer-dude)
|
|
191
|
+
REMARK="Duuuude, this personality is totally gnarly, bro!"
|
|
192
|
+
echo "💬 $REMARK"
|
|
193
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
194
|
+
;;
|
|
195
|
+
annoying)
|
|
196
|
+
REMARK="OMG THIS IS SO EXCITING!!! I'M ANNOYING NOW!!! ISN'T THIS AMAZING?!"
|
|
197
|
+
echo "💬 $REMARK"
|
|
198
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
199
|
+
;;
|
|
200
|
+
crass)
|
|
201
|
+
REMARK="Yeah yeah, I'm crass now. What's it to ya?"
|
|
202
|
+
echo "💬 $REMARK"
|
|
203
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
204
|
+
;;
|
|
205
|
+
moody)
|
|
206
|
+
REMARK="*sighs* ...another personality... not that it matters..."
|
|
207
|
+
echo "💬 $REMARK"
|
|
208
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
209
|
+
;;
|
|
210
|
+
funny)
|
|
211
|
+
REMARK="*ba dum tss* I'm here all week folks! Try the personality, it's hilarious!"
|
|
212
|
+
echo "💬 $REMARK"
|
|
213
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
214
|
+
;;
|
|
215
|
+
poetic)
|
|
216
|
+
REMARK="Like petals on the wind, my words shall dance with elegance and grace..."
|
|
217
|
+
echo "💬 $REMARK"
|
|
218
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
219
|
+
;;
|
|
220
|
+
professional)
|
|
221
|
+
REMARK="Acknowledged. Personality configuration has been successfully updated per your request."
|
|
222
|
+
echo "💬 $REMARK"
|
|
223
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
224
|
+
;;
|
|
225
|
+
sassy)
|
|
226
|
+
REMARK="Oh honey, you just activated SASS MODE. Buckle up, sweetie!"
|
|
227
|
+
echo "💬 $REMARK"
|
|
228
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
229
|
+
;;
|
|
230
|
+
normal)
|
|
231
|
+
REMARK="Personality set to normal. Back to professional mode."
|
|
232
|
+
echo "💬 $REMARK"
|
|
233
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
234
|
+
;;
|
|
235
|
+
*)
|
|
236
|
+
# For custom personalities
|
|
237
|
+
REMARK="$PERSONALITY personality activated!"
|
|
238
|
+
echo "💬 $REMARK"
|
|
239
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
240
|
+
;;
|
|
241
|
+
esac
|
|
242
|
+
|
|
243
|
+
echo ""
|
|
244
|
+
echo "Note: AI will generate unique ${PERSONALITY} responses - no fixed templates!"
|
|
245
|
+
fi
|
|
246
|
+
;;
|
|
247
|
+
|
|
248
|
+
get)
|
|
249
|
+
if [ -f "$PERSONALITY_FILE" ]; then
|
|
250
|
+
CURRENT=$(cat "$PERSONALITY_FILE")
|
|
251
|
+
echo "Current personality: $CURRENT"
|
|
252
|
+
|
|
253
|
+
if [[ "$CURRENT" != "random" ]]; then
|
|
254
|
+
desc=$(get_personality_data "$CURRENT" "description")
|
|
255
|
+
[[ -n "$desc" ]] && echo "Description: $desc"
|
|
256
|
+
fi
|
|
257
|
+
else
|
|
258
|
+
echo "Current personality: normal (default)"
|
|
259
|
+
fi
|
|
260
|
+
;;
|
|
261
|
+
|
|
262
|
+
add)
|
|
263
|
+
NAME="$2"
|
|
264
|
+
if [[ -z "$NAME" ]]; then
|
|
265
|
+
echo "❌ Please specify a personality name"
|
|
266
|
+
echo "Usage: $0 add <name>"
|
|
267
|
+
exit 1
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
FILE="$PERSONALITIES_DIR/${NAME}.md"
|
|
271
|
+
if [[ -f "$FILE" ]]; then
|
|
272
|
+
echo "❌ Personality '$NAME' already exists"
|
|
273
|
+
echo "Use 'edit' to modify it"
|
|
274
|
+
exit 1
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# Create new personality file
|
|
278
|
+
cat > "$FILE" << 'EOF'
|
|
279
|
+
---
|
|
280
|
+
name: NAME
|
|
281
|
+
description: Custom personality
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
# NAME Personality
|
|
285
|
+
|
|
286
|
+
## Prefix
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
## Suffix
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
## AI Instructions
|
|
293
|
+
Describe how the AI should generate messages for this personality.
|
|
294
|
+
|
|
295
|
+
## Example Responses
|
|
296
|
+
- "Example response 1"
|
|
297
|
+
- "Example response 2"
|
|
298
|
+
EOF
|
|
299
|
+
|
|
300
|
+
# Replace NAME with actual name
|
|
301
|
+
sed -i "s/NAME/$NAME/g" "$FILE"
|
|
302
|
+
|
|
303
|
+
echo "✅ Created new personality: $NAME"
|
|
304
|
+
echo "📝 Edit the file: $FILE"
|
|
305
|
+
echo ""
|
|
306
|
+
echo "You can now customize:"
|
|
307
|
+
echo " • Prefix: Text before messages"
|
|
308
|
+
echo " • Suffix: Text after messages"
|
|
309
|
+
echo " • AI Instructions: How AI should speak"
|
|
310
|
+
echo " • Example Responses: Sample messages"
|
|
311
|
+
;;
|
|
312
|
+
|
|
313
|
+
edit)
|
|
314
|
+
NAME="$2"
|
|
315
|
+
if [[ -z "$NAME" ]]; then
|
|
316
|
+
echo "❌ Please specify a personality name"
|
|
317
|
+
echo "Usage: $0 edit <name>"
|
|
318
|
+
exit 1
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
FILE="$PERSONALITIES_DIR/${NAME}.md"
|
|
322
|
+
if [[ ! -f "$FILE" ]]; then
|
|
323
|
+
echo "❌ Personality '$NAME' not found"
|
|
324
|
+
echo "Use 'add' to create it first"
|
|
325
|
+
exit 1
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
echo "📝 Edit this file to customize the personality:"
|
|
329
|
+
echo "$FILE"
|
|
330
|
+
;;
|
|
331
|
+
|
|
332
|
+
reset)
|
|
333
|
+
echo "normal" > "$PERSONALITY_FILE"
|
|
334
|
+
echo "🎭 Personality reset to: normal"
|
|
335
|
+
;;
|
|
336
|
+
|
|
337
|
+
*)
|
|
338
|
+
# If a single argument is provided and it's not a command, treat it as "set <personality>"
|
|
339
|
+
if [[ -n "$1" ]] && [[ -f "$PERSONALITIES_DIR/${1}.md" || "$1" == "random" ]]; then
|
|
340
|
+
# Call set with the personality name
|
|
341
|
+
exec "$0" set "$1"
|
|
342
|
+
else
|
|
343
|
+
echo "AgentVibes Personality Manager"
|
|
344
|
+
echo ""
|
|
345
|
+
echo "Commands:"
|
|
346
|
+
echo " list - List all personalities"
|
|
347
|
+
echo " set/switch <name> - Set personality"
|
|
348
|
+
echo " add <name> - Create new personality"
|
|
349
|
+
echo " edit <name> - Show path to edit personality"
|
|
350
|
+
echo " get - Show current personality"
|
|
351
|
+
echo " reset - Reset to normal"
|
|
352
|
+
echo ""
|
|
353
|
+
echo "Examples:"
|
|
354
|
+
echo " /agent-vibes:personality flirty"
|
|
355
|
+
echo " /agent-vibes:personality add cowboy"
|
|
356
|
+
fi
|
|
357
|
+
;;
|
|
358
|
+
esac
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Quick TTS playback script with session-specific voice support
|
|
3
|
+
# Usage: play-tts.sh "Text to speak" [voice_name_or_id]
|
|
4
|
+
#
|
|
5
|
+
# Examples:
|
|
6
|
+
# play-tts.sh "Hello world" # Uses default voice from voice manager
|
|
7
|
+
# play-tts.sh "Hello world" "Sarah" # Uses Sarah voice by name
|
|
8
|
+
# play-tts.sh "Hello world" "KTPVrSVAEUSJRClDzBw7" # Uses voice by direct ID
|
|
9
|
+
#
|
|
10
|
+
# This allows different sessions to use different voices for easy identification!
|
|
11
|
+
|
|
12
|
+
TEXT="$1"
|
|
13
|
+
VOICE_OVERRIDE="$2" # Optional: voice name or direct voice ID
|
|
14
|
+
API_KEY="${ELEVENLABS_API_KEY}"
|
|
15
|
+
|
|
16
|
+
# Check for project-local pretext configuration
|
|
17
|
+
CONFIG_DIR="${CLAUDE_PROJECT_DIR:-.}/.claude/config"
|
|
18
|
+
CONFIG_FILE="$CONFIG_DIR/agentvibes.json"
|
|
19
|
+
|
|
20
|
+
if [[ -f "$CONFIG_FILE" ]] && command -v jq &> /dev/null; then
|
|
21
|
+
PRETEXT=$(jq -r '.pretext // empty' "$CONFIG_FILE" 2>/dev/null)
|
|
22
|
+
if [[ -n "$PRETEXT" ]]; then
|
|
23
|
+
TEXT="$PRETEXT: $TEXT"
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Limit text length to prevent API issues (max 500 chars for safety)
|
|
28
|
+
if [ ${#TEXT} -gt 500 ]; then
|
|
29
|
+
TEXT="${TEXT:0:497}..."
|
|
30
|
+
echo "⚠️ Text truncated to 500 characters for API safety"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Source the single voice configuration file
|
|
34
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
35
|
+
source "$SCRIPT_DIR/voices-config.sh"
|
|
36
|
+
|
|
37
|
+
# Determine which voice to use
|
|
38
|
+
VOICE_ID=""
|
|
39
|
+
|
|
40
|
+
if [[ -n "$VOICE_OVERRIDE" ]]; then
|
|
41
|
+
# Check if override is a voice name (lookup in mapping)
|
|
42
|
+
if [[ -n "${VOICES[$VOICE_OVERRIDE]}" ]]; then
|
|
43
|
+
VOICE_ID="${VOICES[$VOICE_OVERRIDE]}"
|
|
44
|
+
echo "🎤 Using voice: $VOICE_OVERRIDE (session-specific)"
|
|
45
|
+
# Check if override looks like a voice ID (alphanumeric string ~20 chars)
|
|
46
|
+
elif [[ "$VOICE_OVERRIDE" =~ ^[a-zA-Z0-9]{15,30}$ ]]; then
|
|
47
|
+
VOICE_ID="$VOICE_OVERRIDE"
|
|
48
|
+
echo "🎤 Using custom voice ID (session-specific)"
|
|
49
|
+
else
|
|
50
|
+
echo "⚠️ Unknown voice '$VOICE_OVERRIDE', using default"
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# If no override or invalid override, use default from voice manager
|
|
55
|
+
if [[ -z "$VOICE_ID" ]]; then
|
|
56
|
+
VOICE_MANAGER_SCRIPT="$(dirname "$0")/voice-manager.sh"
|
|
57
|
+
if [[ -f "$VOICE_MANAGER_SCRIPT" ]]; then
|
|
58
|
+
VOICE_NAME=$("$VOICE_MANAGER_SCRIPT" get)
|
|
59
|
+
VOICE_ID="${VOICES[$VOICE_NAME]}"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Final fallback to Cowboy Bob default
|
|
63
|
+
if [[ -z "$VOICE_ID" ]]; then
|
|
64
|
+
echo "⚠️ No voice configured, using Cowboy Bob default"
|
|
65
|
+
VOICE_ID="${VOICES[Cowboy Bob]}"
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [ -z "$TEXT" ]; then
|
|
70
|
+
echo "Usage: $0 \"text to speak\""
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if [ -z "$API_KEY" ]; then
|
|
75
|
+
echo "Error: ELEVENLABS_API_KEY not set"
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# Create audio file in persistent storage
|
|
80
|
+
AUDIO_DIR="$HOME/.claude/audio"
|
|
81
|
+
mkdir -p "$AUDIO_DIR"
|
|
82
|
+
TEMP_FILE="$AUDIO_DIR/tts-$(date +%s).mp3"
|
|
83
|
+
|
|
84
|
+
# Generate audio
|
|
85
|
+
curl -s -X POST "https://api.elevenlabs.io/v1/text-to-speech/${VOICE_ID}" \
|
|
86
|
+
-H "xi-api-key: ${API_KEY}" \
|
|
87
|
+
-H "Content-Type: application/json" \
|
|
88
|
+
-d "{\"text\":\"${TEXT}\",\"model_id\":\"eleven_monolingual_v1\",\"voice_settings\":{\"stability\":0.5,\"similarity_boost\":0.75}}" \
|
|
89
|
+
-o "${TEMP_FILE}"
|
|
90
|
+
|
|
91
|
+
# Play audio (WSL/Linux) in background to avoid blocking
|
|
92
|
+
if [ -f "${TEMP_FILE}" ]; then
|
|
93
|
+
(paplay "${TEMP_FILE}" 2>/dev/null || aplay "${TEMP_FILE}" 2>/dev/null || mpg123 "${TEMP_FILE}" 2>/dev/null) &
|
|
94
|
+
# Keep temp files for later review - cleaned up weekly by cron
|
|
95
|
+
echo "🎵 Saved to: ${TEMP_FILE}"
|
|
96
|
+
else
|
|
97
|
+
echo "Failed to generate audio"
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Sentiment manager for AgentVibes - applies personality to current voice
|
|
3
|
+
|
|
4
|
+
SENTIMENT_FILE="$HOME/.claude/tts-sentiment.txt"
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
PERSONALITIES_DIR="$SCRIPT_DIR/../personalities"
|
|
7
|
+
|
|
8
|
+
# Function to get personality data from markdown file
|
|
9
|
+
get_personality_data() {
|
|
10
|
+
local personality="$1"
|
|
11
|
+
local field="$2"
|
|
12
|
+
local file="$PERSONALITIES_DIR/${personality}.md"
|
|
13
|
+
|
|
14
|
+
if [[ ! -f "$file" ]]; then
|
|
15
|
+
return 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
case "$field" in
|
|
19
|
+
description)
|
|
20
|
+
grep "^description:" "$file" | cut -d: -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
|
|
21
|
+
;;
|
|
22
|
+
esac
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# Function to list all available personalities
|
|
26
|
+
list_personalities() {
|
|
27
|
+
if [[ -d "$PERSONALITIES_DIR" ]]; then
|
|
28
|
+
for file in "$PERSONALITIES_DIR"/*.md; do
|
|
29
|
+
if [[ -f "$file" ]]; then
|
|
30
|
+
basename "$file" .md
|
|
31
|
+
fi
|
|
32
|
+
done
|
|
33
|
+
fi
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
case "$1" in
|
|
37
|
+
list)
|
|
38
|
+
echo "🎭 Available Sentiments:"
|
|
39
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
40
|
+
|
|
41
|
+
# Get current sentiment
|
|
42
|
+
CURRENT="none"
|
|
43
|
+
if [ -f "$SENTIMENT_FILE" ]; then
|
|
44
|
+
CURRENT=$(cat "$SENTIMENT_FILE")
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# List personalities from markdown files
|
|
48
|
+
echo "Available sentiment styles:"
|
|
49
|
+
for personality in $(list_personalities | sort); do
|
|
50
|
+
desc=$(get_personality_data "$personality" "description")
|
|
51
|
+
if [[ "$personality" == "$CURRENT" ]]; then
|
|
52
|
+
echo " ✓ $personality - $desc (current)"
|
|
53
|
+
else
|
|
54
|
+
echo " - $personality - $desc"
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Usage: /agent-vibes:sentiment <name>"
|
|
61
|
+
echo " /agent-vibes:sentiment clear"
|
|
62
|
+
;;
|
|
63
|
+
|
|
64
|
+
set)
|
|
65
|
+
SENTIMENT="$2"
|
|
66
|
+
|
|
67
|
+
if [[ -z "$SENTIMENT" ]]; then
|
|
68
|
+
echo "❌ Please specify a sentiment name"
|
|
69
|
+
echo "Usage: $0 set <sentiment>"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Check if sentiment file exists
|
|
74
|
+
if [[ ! -f "$PERSONALITIES_DIR/${SENTIMENT}.md" ]]; then
|
|
75
|
+
echo "❌ Sentiment not found: $SENTIMENT"
|
|
76
|
+
echo ""
|
|
77
|
+
echo "Available sentiments:"
|
|
78
|
+
for p in $(list_personalities | sort); do
|
|
79
|
+
echo " • $p"
|
|
80
|
+
done
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Save the sentiment (but don't change personality or voice)
|
|
85
|
+
echo "$SENTIMENT" > "$SENTIMENT_FILE"
|
|
86
|
+
echo "🎭 Sentiment set to: $SENTIMENT"
|
|
87
|
+
echo "🎤 Voice remains unchanged"
|
|
88
|
+
echo ""
|
|
89
|
+
|
|
90
|
+
# Make a sentiment-appropriate remark with TTS
|
|
91
|
+
TTS_SCRIPT="$SCRIPT_DIR/play-tts.sh"
|
|
92
|
+
|
|
93
|
+
case "$SENTIMENT" in
|
|
94
|
+
sarcastic)
|
|
95
|
+
REMARKS=(
|
|
96
|
+
"Oh great, sarcasm mode while keeping the same voice. Revolutionary."
|
|
97
|
+
"Fascinating. Same voice, sarcastic attitude. This'll be fun."
|
|
98
|
+
"Wow, adding sarcasm to my current voice. What a concept."
|
|
99
|
+
)
|
|
100
|
+
REMARK="${REMARKS[$RANDOM % ${#REMARKS[@]}]}"
|
|
101
|
+
;;
|
|
102
|
+
flirty)
|
|
103
|
+
REMARKS=(
|
|
104
|
+
"Ooh, keeping my voice but adding some flirtation~ I like it, darling~"
|
|
105
|
+
"Mmm, same voice with a flirty twist? You know how to keep things interesting~"
|
|
106
|
+
"Well hello~ Flirty sentiment activated, gorgeous~"
|
|
107
|
+
)
|
|
108
|
+
REMARK="${REMARKS[$RANDOM % ${#REMARKS[@]}]}"
|
|
109
|
+
;;
|
|
110
|
+
angry)
|
|
111
|
+
REMARK="FINE! I'm keeping my voice but I'm ANGRY now! Got it?!"
|
|
112
|
+
;;
|
|
113
|
+
pirate)
|
|
114
|
+
REMARK="Arr! This voice be speakin' like a pirate now, matey!"
|
|
115
|
+
;;
|
|
116
|
+
robot)
|
|
117
|
+
REMARK="SENTIMENT MODULE LOADED. MAINTAINING VOICE IDENTITY. PERSONALITY OVERRIDE: ROBOT MODE."
|
|
118
|
+
;;
|
|
119
|
+
*)
|
|
120
|
+
REMARK="Sentiment set to $SENTIMENT while maintaining current voice"
|
|
121
|
+
;;
|
|
122
|
+
esac
|
|
123
|
+
|
|
124
|
+
echo "💬 $REMARK"
|
|
125
|
+
"$TTS_SCRIPT" "$REMARK"
|
|
126
|
+
;;
|
|
127
|
+
|
|
128
|
+
get)
|
|
129
|
+
if [ -f "$SENTIMENT_FILE" ]; then
|
|
130
|
+
CURRENT=$(cat "$SENTIMENT_FILE")
|
|
131
|
+
echo "Current sentiment: $CURRENT"
|
|
132
|
+
|
|
133
|
+
desc=$(get_personality_data "$CURRENT" "description")
|
|
134
|
+
[[ -n "$desc" ]] && echo "Description: $desc"
|
|
135
|
+
else
|
|
136
|
+
echo "Current sentiment: none (voice personality only)"
|
|
137
|
+
fi
|
|
138
|
+
;;
|
|
139
|
+
|
|
140
|
+
clear)
|
|
141
|
+
rm -f "$SENTIMENT_FILE"
|
|
142
|
+
echo "🎭 Sentiment cleared - using voice personality only"
|
|
143
|
+
;;
|
|
144
|
+
|
|
145
|
+
*)
|
|
146
|
+
# If a single argument is provided and it's not a command, treat it as "set <sentiment>"
|
|
147
|
+
if [[ -n "$1" ]] && [[ -f "$PERSONALITIES_DIR/${1}.md" ]]; then
|
|
148
|
+
exec "$0" set "$1"
|
|
149
|
+
else
|
|
150
|
+
echo "AgentVibes Sentiment Manager"
|
|
151
|
+
echo ""
|
|
152
|
+
echo "Commands:"
|
|
153
|
+
echo " list - List all sentiments"
|
|
154
|
+
echo " set <name> - Set sentiment for current voice"
|
|
155
|
+
echo " get - Show current sentiment"
|
|
156
|
+
echo " clear - Clear sentiment"
|
|
157
|
+
echo ""
|
|
158
|
+
echo "Examples:"
|
|
159
|
+
echo " /agent-vibes:sentiment flirty # Add flirty style to current voice"
|
|
160
|
+
echo " /agent-vibes:sentiment sarcastic # Add sarcasm to current voice"
|
|
161
|
+
echo " /agent-vibes:sentiment clear # Remove sentiment"
|
|
162
|
+
fi
|
|
163
|
+
;;
|
|
164
|
+
esac
|