agentvibes 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agentvibes/LITE-MODE.md +236 -0
- package/.agentvibes/README.md +136 -0
- package/.agentvibes/backup/session-start-tts.sh.20251210_212814 +141 -0
- package/.agentvibes/backups/agents/analyst_20260204_144958.md +78 -0
- package/.agentvibes/backups/agents/architect_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/dev_20260204_144958.md +74 -0
- package/.agentvibes/backups/agents/pm_20260204_144958.md +72 -0
- package/.agentvibes/backups/agents/quick-flow-solo-dev_20260204_144958.md +64 -0
- package/.agentvibes/backups/agents/sm_20260204_144958.md +87 -0
- package/.agentvibes/backups/agents/tea_20260204_144958.md +79 -0
- package/.agentvibes/backups/agents/tech-writer_20260204_144958.md +82 -0
- package/.agentvibes/backups/agents/ux-designer_20260204_144958.md +80 -0
- package/.agentvibes/bmad/bmad-voices.md +69 -69
- package/.agentvibes/config/README-personality-defaults.md +162 -0
- package/.agentvibes/config/mode.txt +1 -0
- package/.agentvibes/config/personality-voice-defaults.default.json +21 -0
- package/.agentvibes/config/save-audio.txt +1 -0
- package/.agentvibes/config/voice-metadata.json +160 -0
- package/.agentvibes/config.json +24 -15
- package/.agentvibes/hooks/help.sh +191 -0
- package/.agentvibes/hooks/post-tool-use-lite.sh +111 -0
- package/.agentvibes/hooks/save-audio-manager.sh +162 -0
- package/.agentvibes/hooks/session-start-full-optimized.sh +102 -0
- package/.agentvibes/hooks/session-start-full.sh +142 -0
- package/.agentvibes/hooks/session-start-lite-v2.sh +34 -0
- package/.agentvibes/hooks/session-start-lite.sh +29 -0
- package/.agentvibes/hooks/stop-lite.sh +115 -0
- package/.agentvibes/hooks/switch-mode.sh +215 -0
- package/.agentvibes/output-styles/audio-summary.md +30 -0
- package/.claude/activation-instructions +54 -54
- package/.claude/audio/voice-samples/piper/alan.wav +0 -0
- package/.claude/audio/voice-samples/piper/amy.wav +0 -0
- package/.claude/audio/voice-samples/piper/charlotte.wav +0 -0
- package/.claude/audio/voice-samples/piper/joe.wav +0 -0
- package/.claude/audio/voice-samples/piper/john.wav +0 -0
- package/.claude/audio/voice-samples/piper/katherine.wav +0 -0
- package/.claude/audio/voice-samples/piper/kristin.wav +0 -0
- package/.claude/audio/voice-samples/piper/linda.wav +0 -0
- package/.claude/audio/voice-samples/piper/marcus.wav +0 -0
- package/.claude/audio/voice-samples/piper/ryan.wav +0 -0
- package/.claude/commands/agent-vibes/add.md +21 -21
- package/.claude/commands/agent-vibes/agent-vibes.md +101 -101
- package/.claude/commands/agent-vibes/agent.md +79 -79
- package/.claude/commands/agent-vibes/background-music.md +111 -111
- package/.claude/commands/agent-vibes/bmad.md +198 -198
- package/.claude/commands/agent-vibes/clean.md +18 -18
- package/.claude/commands/agent-vibes/cleanup.md +18 -18
- package/.claude/commands/agent-vibes/commands.json +145 -145
- package/.claude/commands/agent-vibes/effects.md +97 -97
- package/.claude/commands/agent-vibes/get.md +9 -9
- package/.claude/commands/agent-vibes/hide.md +91 -91
- package/.claude/commands/agent-vibes/language.md +23 -23
- package/.claude/commands/agent-vibes/learn.md +67 -67
- package/.claude/commands/agent-vibes/list.md +13 -13
- package/.claude/commands/agent-vibes/mute.md +37 -37
- package/.claude/commands/agent-vibes/preview.md +17 -17
- package/.claude/commands/agent-vibes/provider.md +68 -68
- package/.claude/commands/agent-vibes/replay-target.md +14 -14
- package/.claude/commands/agent-vibes/sample.md +12 -12
- package/.claude/commands/agent-vibes/set-favorite-voice.md +84 -84
- package/.claude/commands/agent-vibes/set-pretext.md +65 -65
- package/.claude/commands/agent-vibes/set-speed.md +41 -41
- package/.claude/commands/agent-vibes/show.md +84 -84
- package/.claude/commands/agent-vibes/switch.md +87 -87
- package/.claude/commands/agent-vibes/target-voice.md +26 -26
- package/.claude/commands/agent-vibes/target.md +30 -30
- package/.claude/commands/agent-vibes/translate.md +68 -68
- package/.claude/commands/agent-vibes/unmute.md +45 -45
- package/.claude/commands/agent-vibes/whoami.md +7 -7
- package/.claude/commands/agent-vibes-bmad-voices.md +117 -117
- package/.claude/commands/agent-vibes-rdp.md +24 -24
- package/.claude/config/audio-effects.cfg +4 -11
- package/.claude/config/audio-effects.cfg.sample +52 -52
- package/.claude/config/background-music-position.txt +27 -0
- package/.claude/config/background-music-volume.txt +1 -1
- package/.claude/config/background-music.cfg +1 -0
- package/.claude/config/background-music.txt +1 -0
- package/.claude/config/tts-speech-rate.txt +1 -4
- package/.claude/config/tts-verbosity.txt +1 -0
- package/.claude/docs/TERMUX_SETUP.md +408 -408
- package/.claude/github-star-reminder.txt +1 -1
- package/.claude/hooks/README-TTS-QUEUE.md +135 -135
- package/.claude/hooks/audio-cache-utils.sh +0 -0
- package/.claude/hooks/audio-processor.sh +60 -14
- package/.claude/hooks/background-music-manager.sh +0 -0
- package/.claude/hooks/bmad-party-manager.sh +225 -0
- package/.claude/hooks/bmad-speak-enhanced.sh +0 -0
- package/.claude/hooks/bmad-speak.sh +6 -13
- package/.claude/hooks/bmad-tts-injector.sh +0 -0
- package/.claude/hooks/bmad-voice-manager.sh +0 -0
- package/.claude/hooks/clawdbot-receiver-SECURE.sh +25 -23
- package/.claude/hooks/clawdbot-receiver.sh +4 -28
- package/.claude/hooks/clean-audio-cache.sh +0 -0
- package/.claude/hooks/cleanup-cache.sh +0 -0
- package/.claude/hooks/configure-rdp-mode.sh +0 -0
- package/.claude/hooks/download-extra-voices.sh +0 -0
- package/.claude/hooks/effects-manager.sh +0 -0
- package/.claude/hooks/github-star-reminder.sh +0 -0
- package/.claude/hooks/language-manager.sh +0 -0
- package/.claude/hooks/learn-manager.sh +0 -0
- package/.claude/hooks/macos-voice-manager.sh +0 -0
- package/.claude/hooks/migrate-background-music.sh +0 -0
- package/.claude/hooks/migrate-to-agentvibes.sh +0 -0
- package/.claude/hooks/optimize-background-music.sh +0 -0
- package/.claude/hooks/personality-manager.sh +0 -0
- package/.claude/hooks/piper-download-voices.sh +0 -0
- package/.claude/hooks/piper-installer.sh +1 -1
- package/.claude/hooks/piper-multispeaker-registry.sh +0 -0
- package/.claude/hooks/piper-voice-manager.sh +0 -0
- package/.claude/hooks/play-tts-enhanced.sh +0 -0
- package/.claude/hooks/play-tts-macos.sh +6 -12
- package/.claude/hooks/play-tts-piper.sh +50 -79
- package/.claude/hooks/play-tts-soprano.sh +9 -43
- package/.claude/hooks/play-tts-ssh-remote.sh +43 -215
- package/.claude/hooks/play-tts-termux-ssh.sh +0 -0
- package/.claude/hooks/play-tts.sh +31 -31
- package/.claude/hooks/post-response.sh +41 -0
- package/.claude/hooks/prepare-release.sh +0 -0
- package/.claude/hooks/provider-commands.sh +0 -0
- package/.claude/hooks/provider-manager.sh +0 -0
- package/.claude/hooks/replay-target-audio.sh +0 -0
- package/.claude/hooks/requirements.txt +6 -6
- package/.claude/hooks/sentiment-manager.sh +0 -0
- package/.claude/hooks/session-start-tts.sh +56 -39
- package/.claude/hooks/soprano-gradio-synth.py +139 -139
- package/.claude/hooks/speed-manager.sh +0 -0
- package/.claude/hooks/stop.sh +63 -0
- package/.claude/hooks/termux-installer.sh +0 -0
- package/.claude/hooks/translate-manager.sh +0 -0
- package/.claude/hooks/translator.py +237 -237
- package/.claude/hooks/tts-queue-worker.sh +0 -0
- package/.claude/hooks/tts-queue.sh +0 -0
- package/.claude/hooks/verbosity-manager.sh +0 -0
- package/.claude/hooks/voice-manager.sh +26 -4
- package/.claude/hooks-windows/audio-cache-utils.ps1 +119 -119
- package/.claude/hooks-windows/bmad-party-speak.ps1 +278 -278
- package/.claude/hooks-windows/bmad-speak.ps1 +264 -264
- package/.claude/hooks-windows/clean-audio-cache.ps1 +53 -53
- package/.claude/hooks-windows/effects-manager.ps1 +294 -294
- package/.claude/hooks-windows/language-manager.ps1 +193 -193
- package/.claude/hooks-windows/learn-manager.ps1 +241 -241
- package/.claude/hooks-windows/personality-manager.ps1 +266 -266
- package/.claude/hooks-windows/play-tts-soprano.ps1 +5 -5
- package/.claude/hooks-windows/play-tts-termux-ssh.ps1 +138 -138
- package/.claude/hooks-windows/play-tts-windows-piper.ps1 +164 -0
- package/.claude/hooks-windows/play-tts-windows-sapi.ps1 +108 -0
- package/.claude/hooks-windows/play-tts.ps1 +104 -513
- package/.claude/hooks-windows/provider-manager.ps1 +158 -192
- package/.claude/hooks-windows/session-start-tts.ps1 +55 -46
- package/.claude/hooks-windows/soprano-gradio-synth.py +153 -153
- package/.claude/hooks-windows/speed-manager.ps1 +166 -166
- package/.claude/hooks-windows/voice-manager-windows.ps1 +176 -260
- package/.claude/output-styles/agent-vibes.md +202 -202
- package/.claude/personalities/angry.md +14 -14
- package/.claude/personalities/annoying.md +14 -14
- package/.claude/personalities/crass.md +14 -14
- package/.claude/personalities/dramatic.md +14 -14
- package/.claude/personalities/dry-humor.md +50 -50
- package/.claude/personalities/flirty.md +20 -20
- package/.claude/personalities/funny.md +14 -14
- package/.claude/personalities/grandpa.md +32 -32
- package/.claude/personalities/millennial.md +14 -14
- package/.claude/personalities/moody.md +14 -14
- package/.claude/personalities/normal.md +16 -16
- package/.claude/personalities/pirate.md +14 -14
- package/.claude/personalities/poetic.md +14 -14
- package/.claude/personalities/professional.md +14 -14
- package/.claude/personalities/rapper.md +55 -55
- package/.claude/personalities/robot.md +14 -14
- package/.claude/personalities/sarcastic.md +38 -38
- package/.claude/personalities/sassy.md +14 -14
- package/.claude/personalities/surfer-dude.md +14 -14
- package/.claude/personalities/zen.md +14 -14
- package/.claude/piper-voices-dir.txt +1 -0
- package/.claude/settings.json +25 -15
- package/.claude/verbosity.txt +1 -1
- package/.clawdbot/README.md +105 -105
- package/.clawdbot/skill/SKILL.md +149 -145
- package/.mcp.json +30 -11
- package/CLAUDE.md +170 -215
- package/README.md +206 -525
- package/RELEASE_NOTES.md +1132 -1976
- package/WINDOWS-SETUP.md +208 -208
- package/bin/agent-vibes +0 -0
- package/bin/agentvibes-voice-browser.js +64 -1289
- package/bin/agentvibes.js +0 -0
- package/bin/ensure-soprano-running.sh +43 -0
- package/bin/mcp-server.js +121 -121
- package/bin/mcp-server.sh +0 -0
- package/bin/test-bmad-pr +78 -78
- package/mcp-server/QUICK_START.md +203 -203
- package/mcp-server/README.md +345 -345
- package/mcp-server/WINDOWS_SETUP.md +260 -260
- package/mcp-server/docs/troubleshooting-audio.md +313 -313
- package/mcp-server/examples/claude_desktop_config.json +11 -11
- package/mcp-server/examples/claude_desktop_config_piper.json +9 -9
- package/mcp-server/examples/custom_instructions.md +169 -169
- package/mcp-server/install-deps.js +130 -130
- package/mcp-server/pyproject.toml +52 -52
- package/mcp-server/requirements.txt +2 -2
- package/mcp-server/server.py +1451 -1578
- package/mcp-server/test_server.py +395 -395
- package/package.json +1 -3
- package/setup-windows.ps1 +815 -815
- package/src/installer.js +42 -5
- package/templates/agentvibes-receiver.sh +158 -483
- package/templates/audio/welcome-music.mp3 +0 -0
- package/.agentvibes/bmad-voice-map.json +0 -104
- package/.agentvibes/copilot-sessions.log +0 -4
- package/.claude/config/audio-effects-bmad.cfg +0 -50
- package/.claude/config/background-music-enabled.txt +0 -1
- package/.claude/config/intro-text.txt +0 -1
- package/.claude/config/personality.txt +0 -1
- package/.claude/config/piper-speech-rate.txt +0 -4
- package/.claude/config/piper-target-speech-rate.txt +0 -1
- package/.claude/config/reverb-level.txt +0 -1
- package/.claude/config/tts-target-speech-rate.txt +0 -1
- package/voice-assignments.json +0 -8245
- /package/{.claude → .agentvibes}/config/agentvibes.json +0 -0
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
#
|
|
3
3
|
# File: .claude/hooks/play-tts-ssh-remote.sh
|
|
4
4
|
#
|
|
5
|
-
# AgentVibes - SSH-Remote TTS Provider
|
|
6
|
-
# Sends text
|
|
7
|
-
#
|
|
8
|
-
# The sender reads local audio-effects.cfg and bundles everything into a
|
|
9
|
-
# single base64-encoded JSON payload. The receiver is a thin executor.
|
|
5
|
+
# AgentVibes - SSH-Remote TTS Provider
|
|
6
|
+
# Sends text to remote device via SSH for local AgentVibes playback
|
|
10
7
|
#
|
|
11
8
|
# Copyright (c) 2025 Paul Preibisch
|
|
12
9
|
# Licensed under the Apache License, Version 2.0
|
|
@@ -14,249 +11,80 @@
|
|
|
14
11
|
|
|
15
12
|
set -euo pipefail
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# Positional (legacy):
|
|
21
|
-
# play-tts-ssh-remote.sh "text" [voice] [agent_name]
|
|
22
|
-
#
|
|
23
|
-
# Flag-based (full per-call control):
|
|
24
|
-
# play-tts-ssh-remote.sh --text "hello" --voice "en_US-ryan-high" \
|
|
25
|
-
# --pretext "Winston here" --music "track.mp3" \
|
|
26
|
-
# --volume 0.25 --effects "reverb 40 60 80" \
|
|
27
|
-
# --speed 1.1 --provider piper --agent "winston"
|
|
28
|
-
#
|
|
29
|
-
# Flags override config-file values. Any flag omitted → falls back to config.
|
|
30
|
-
# --pretext "" (empty string) explicitly suppresses pretext (no fallback).
|
|
31
|
-
# ---------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
TEXT=""
|
|
34
|
-
VOICE=""
|
|
35
|
-
AGENT_NAME=""
|
|
36
|
-
PRETEXT_OVERRIDE=""
|
|
37
|
-
PRETEXT_SET=0 # whether --pretext was explicitly provided
|
|
38
|
-
MUSIC_OVERRIDE=""
|
|
39
|
-
VOLUME_OVERRIDE=""
|
|
40
|
-
EFFECTS_OVERRIDE=""
|
|
41
|
-
SPEED_OVERRIDE=""
|
|
42
|
-
PROVIDER_OVERRIDE=""
|
|
43
|
-
|
|
44
|
-
# Detect flag-based vs positional usage: if first arg starts with --, use flags.
|
|
45
|
-
if [[ "${1:-}" == --* ]]; then
|
|
46
|
-
while [[ $# -gt 0 ]]; do
|
|
47
|
-
case "$1" in
|
|
48
|
-
--text) TEXT="${2:-}"; shift 2 ;;
|
|
49
|
-
--voice) VOICE="${2:-}"; shift 2 ;;
|
|
50
|
-
--agent) AGENT_NAME="${2:-}"; shift 2 ;;
|
|
51
|
-
--pretext) PRETEXT_OVERRIDE="${2:-}"; PRETEXT_SET=1; shift 2 ;;
|
|
52
|
-
--music) MUSIC_OVERRIDE="${2:-}"; shift 2 ;;
|
|
53
|
-
--volume) VOLUME_OVERRIDE="${2:-}"; shift 2 ;;
|
|
54
|
-
--effects) EFFECTS_OVERRIDE="${2:-}"; shift 2 ;;
|
|
55
|
-
--speed) SPEED_OVERRIDE="${2:-}"; shift 2 ;;
|
|
56
|
-
--provider) PROVIDER_OVERRIDE="${2:-}"; shift 2 ;;
|
|
57
|
-
*) echo "Unknown flag: $1" >&2; exit 1 ;;
|
|
58
|
-
esac
|
|
59
|
-
done
|
|
60
|
-
else
|
|
61
|
-
TEXT="${1:-}"
|
|
62
|
-
VOICE="${2:-}"
|
|
63
|
-
AGENT_NAME="${3:-}"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# Defaults for still-empty values
|
|
67
|
-
VOICE="${VOICE:-en_US-lessac-medium}"
|
|
68
|
-
AGENT_NAME="${AGENT_NAME:-default}"
|
|
14
|
+
TEXT="${1:-}"
|
|
15
|
+
VOICE="${2:-en_US-lessac-medium}"
|
|
16
|
+
AGENT_NAME="${3:-default}"
|
|
69
17
|
|
|
70
18
|
# Validate required input
|
|
71
19
|
if [[ -z "$TEXT" ]]; then
|
|
72
|
-
echo "
|
|
73
|
-
echo "Usage
|
|
20
|
+
echo "❌ No text provided" >&2
|
|
21
|
+
echo "Usage: $0 <text> [voice] [agent_name]" >&2
|
|
74
22
|
exit 1
|
|
75
23
|
fi
|
|
76
24
|
|
|
77
|
-
# Get script directory
|
|
25
|
+
# Get script directory
|
|
78
26
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
79
27
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
80
28
|
|
|
81
|
-
# Derive project name from directory
|
|
82
|
-
PROJECT_NAME=$(basename "$PROJECT_ROOT")
|
|
83
|
-
|
|
84
|
-
# ---------------------------------------------------------------------------
|
|
85
29
|
# Get SSH host from config
|
|
86
|
-
# ---------------------------------------------------------------------------
|
|
87
|
-
|
|
88
30
|
SSH_HOST=$(cat "$PROJECT_ROOT/.claude/ssh-remote-host.txt" 2>/dev/null || \
|
|
89
31
|
cat "$HOME/.claude/ssh-remote-host.txt" 2>/dev/null || echo "")
|
|
90
32
|
|
|
91
33
|
if [[ -z "$SSH_HOST" ]]; then
|
|
92
|
-
echo "SSH-Remote host not configured" >&2
|
|
93
|
-
echo "Set host: echo '
|
|
34
|
+
echo "❌ SSH-Remote host not configured" >&2
|
|
35
|
+
echo "💡 Set host: echo 'android' > ~/.claude/ssh-remote-host.txt" >&2
|
|
94
36
|
exit 1
|
|
95
37
|
fi
|
|
96
38
|
|
|
97
|
-
# SECURITY: Validate SSH_HOST
|
|
39
|
+
# SECURITY: Validate SSH_HOST to prevent option injection
|
|
40
|
+
# Must be a valid hostname, IP address, or SSH config alias (alphanumeric, dots, hyphens, underscores)
|
|
98
41
|
if [[ ! "$SSH_HOST" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
|
99
|
-
echo "Invalid SSH host format: $SSH_HOST" >&2
|
|
42
|
+
echo "❌ Invalid SSH host format: $SSH_HOST" >&2
|
|
43
|
+
echo "💡 Host must be alphanumeric (may contain dots, hyphens, underscores)" >&2
|
|
100
44
|
exit 1
|
|
101
45
|
fi
|
|
102
46
|
|
|
103
|
-
# SECURITY:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
echo "Invalid voice format: $VOICE" >&2
|
|
47
|
+
# SECURITY: Reject hosts starting with hyphen (SSH option injection)
|
|
48
|
+
if [[ "$SSH_HOST" == -* ]]; then
|
|
49
|
+
echo "❌ Invalid SSH host: cannot start with hyphen" >&2
|
|
107
50
|
exit 1
|
|
108
51
|
fi
|
|
109
52
|
|
|
110
|
-
# SECURITY: Validate
|
|
111
|
-
if [[ ! "$
|
|
112
|
-
echo "Invalid
|
|
53
|
+
# SECURITY: Validate VOICE to prevent injection (alphanumeric, hyphens, underscores only)
|
|
54
|
+
if [[ ! "$VOICE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
55
|
+
echo "❌ Invalid voice format: $VOICE" >&2
|
|
113
56
|
exit 1
|
|
114
57
|
fi
|
|
115
58
|
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
SOX_EFFECTS=""
|
|
121
|
-
BG_FILE=""
|
|
122
|
-
BG_VOLUME="0.10"
|
|
123
|
-
|
|
124
|
-
EFFECTS_CFG="$PROJECT_ROOT/.claude/config/audio-effects.cfg"
|
|
125
|
-
if [[ -f "$EFFECTS_CFG" ]]; then
|
|
126
|
-
CONFIG_LINE=$(grep "^${AGENT_NAME}|" "$EFFECTS_CFG" 2>/dev/null || \
|
|
127
|
-
grep "^default|" "$EFFECTS_CFG" 2>/dev/null || true)
|
|
128
|
-
if [[ -n "$CONFIG_LINE" ]]; then
|
|
129
|
-
IFS='|' read -r _ SOX_EFFECTS BG_FILE BG_VOLUME <<< "$CONFIG_LINE"
|
|
130
|
-
fi
|
|
131
|
-
fi
|
|
132
|
-
|
|
133
|
-
# Read pretext if configured
|
|
134
|
-
PRETEXT=""
|
|
135
|
-
PRETEXT_FILE="$PROJECT_ROOT/.agentvibes/config/pretext.txt"
|
|
136
|
-
if [[ -f "$PRETEXT_FILE" ]]; then
|
|
137
|
-
PRETEXT=$(cat "$PRETEXT_FILE" 2>/dev/null || true)
|
|
138
|
-
fi
|
|
139
|
-
|
|
140
|
-
# Read speed if configured
|
|
141
|
-
SPEED=""
|
|
142
|
-
SPEED_FILE="$PROJECT_ROOT/.agentvibes/config/speed.txt"
|
|
143
|
-
if [[ -f "$SPEED_FILE" ]]; then
|
|
144
|
-
SPEED=$(cat "$SPEED_FILE" 2>/dev/null || true)
|
|
145
|
-
fi
|
|
146
|
-
|
|
147
|
-
# Read the TTS provider the RECEIVER should use to generate audio.
|
|
148
|
-
# This is separate from the sender's own provider (which is "ssh-remote").
|
|
149
|
-
# Check receiver-provider.txt first, then fall back to "piper".
|
|
150
|
-
PROVIDER=""
|
|
151
|
-
RECEIVER_PROVIDER_FILE="$PROJECT_ROOT/.agentvibes/config/receiver-provider.txt"
|
|
152
|
-
if [[ -f "$RECEIVER_PROVIDER_FILE" ]]; then
|
|
153
|
-
PROVIDER=$(cat "$RECEIVER_PROVIDER_FILE" 2>/dev/null || true)
|
|
154
|
-
fi
|
|
155
|
-
# Also check home-level config
|
|
156
|
-
if [[ -z "$PROVIDER" ]]; then
|
|
157
|
-
RECEIVER_PROVIDER_FILE="$HOME/.agentvibes/config/receiver-provider.txt"
|
|
158
|
-
if [[ -f "$RECEIVER_PROVIDER_FILE" ]]; then
|
|
159
|
-
PROVIDER=$(cat "$RECEIVER_PROVIDER_FILE" 2>/dev/null || true)
|
|
160
|
-
fi
|
|
161
|
-
fi
|
|
162
|
-
# Validate — only known TTS providers (not transport providers like ssh-remote)
|
|
163
|
-
case "${PROVIDER:-}" in
|
|
164
|
-
piper|soprano|macos|windows-sapi) ;;
|
|
165
|
-
*) PROVIDER="piper" ;;
|
|
166
|
-
esac
|
|
167
|
-
|
|
168
|
-
# ---------------------------------------------------------------------------
|
|
169
|
-
# Apply CLI flag overrides (flags win over config files)
|
|
170
|
-
# ---------------------------------------------------------------------------
|
|
171
|
-
# Validate effects (prevent injection — only alphanumeric, spaces, dots, hyphens)
|
|
172
|
-
if [[ -n "$EFFECTS_OVERRIDE" ]]; then
|
|
173
|
-
if [[ "$EFFECTS_OVERRIDE" =~ ^[a-zA-Z0-9\ ._-]+$ ]]; then
|
|
174
|
-
SOX_EFFECTS="$EFFECTS_OVERRIDE"
|
|
175
|
-
else
|
|
176
|
-
echo "Invalid effects format: $EFFECTS_OVERRIDE (alphanumeric/space/.-_ only)" >&2
|
|
177
|
-
exit 1
|
|
178
|
-
fi
|
|
179
|
-
fi
|
|
180
|
-
[[ -n "$MUSIC_OVERRIDE" ]] && BG_FILE="$MUSIC_OVERRIDE"
|
|
181
|
-
[[ -n "$VOLUME_OVERRIDE" ]] && BG_VOLUME="$VOLUME_OVERRIDE"
|
|
182
|
-
[[ -n "$SPEED_OVERRIDE" ]] && SPEED="$SPEED_OVERRIDE"
|
|
183
|
-
[[ -n "$PROVIDER_OVERRIDE" ]] && PROVIDER="$PROVIDER_OVERRIDE"
|
|
184
|
-
# Pretext: explicit --pretext wins even when empty string (suppresses pretext)
|
|
185
|
-
if [[ "$PRETEXT_SET" == "1" ]]; then
|
|
186
|
-
PRETEXT="$PRETEXT_OVERRIDE"
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
# Re-validate provider after override (in case user passed bad value)
|
|
190
|
-
case "${PROVIDER:-}" in
|
|
191
|
-
piper|soprano|macos|windows-sapi) ;;
|
|
192
|
-
*) PROVIDER="piper" ;;
|
|
193
|
-
esac
|
|
194
|
-
# Validate music filename (prevent path injection through JSON → receiver)
|
|
195
|
-
# Allows spaces in track names like "Late Night Hip Hop Groove.mp3"
|
|
196
|
-
if [[ -n "$BG_FILE" && ! "$BG_FILE" =~ ^[a-zA-Z0-9_\.\ -]+$ ]]; then
|
|
197
|
-
echo "Invalid music filename format: $BG_FILE (alphanumeric/space/.-_ only)" >&2
|
|
198
|
-
exit 1
|
|
199
|
-
fi
|
|
200
|
-
# Validate volume
|
|
201
|
-
if [[ -n "$BG_VOLUME" && ! "$BG_VOLUME" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
202
|
-
echo "Invalid volume: $BG_VOLUME (numeric only)" >&2
|
|
203
|
-
exit 1
|
|
204
|
-
fi
|
|
205
|
-
# Validate speed
|
|
206
|
-
if [[ -n "$SPEED" && ! "$SPEED" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
|
207
|
-
echo "Invalid speed: $SPEED (numeric only)" >&2
|
|
59
|
+
# SECURITY: Validate AGENT_NAME to prevent injection (alphanumeric, hyphens, underscores, spaces only)
|
|
60
|
+
if [[ ! "$AGENT_NAME" =~ ^[a-zA-Z0-9_\ -]+$ ]]; then
|
|
61
|
+
echo "❌ Invalid agent name format: $AGENT_NAME" >&2
|
|
208
62
|
exit 1
|
|
209
63
|
fi
|
|
210
64
|
|
|
211
|
-
#
|
|
212
|
-
#
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
# SECURITY: Use jq if available for safe JSON construction, else manual escaping
|
|
216
|
-
build_json_payload() {
|
|
217
|
-
if command -v jq &>/dev/null; then
|
|
218
|
-
jq -n \
|
|
219
|
-
--arg text "$TEXT" \
|
|
220
|
-
--arg voice "$VOICE" \
|
|
221
|
-
--arg effects "$SOX_EFFECTS" \
|
|
222
|
-
--arg music "$BG_FILE" \
|
|
223
|
-
--arg volume "$BG_VOLUME" \
|
|
224
|
-
--arg project "$PROJECT_NAME" \
|
|
225
|
-
--arg pretext "$PRETEXT" \
|
|
226
|
-
--arg speed "$SPEED" \
|
|
227
|
-
--arg provider "$PROVIDER" \
|
|
228
|
-
'{text: $text, voice: $voice, effects: $effects, music: $music, volume: $volume, project: $project, pretext: $pretext, speed: $speed, provider: $provider}'
|
|
229
|
-
else
|
|
230
|
-
# Manual JSON — escape all interpolated fields (backslash, double-quote, newline, tab)
|
|
231
|
-
_esc() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g' | tr '\n' ' '; }
|
|
232
|
-
local e_text e_voice e_effects e_music e_vol e_proj e_pre e_spd e_prov
|
|
233
|
-
e_text=$(_esc "$TEXT"); e_voice=$(_esc "$VOICE"); e_effects=$(_esc "$SOX_EFFECTS")
|
|
234
|
-
e_music=$(_esc "$BG_FILE"); e_vol=$(_esc "$BG_VOLUME"); e_proj=$(_esc "$PROJECT_NAME")
|
|
235
|
-
e_pre=$(_esc "$PRETEXT"); e_spd=$(_esc "$SPEED"); e_prov=$(_esc "$PROVIDER")
|
|
236
|
-
printf '{"text":"%s","voice":"%s","effects":"%s","music":"%s","volume":"%s","project":"%s","pretext":"%s","speed":"%s","provider":"%s"}' \
|
|
237
|
-
"$e_text" "$e_voice" "$e_effects" "$e_music" "$e_vol" "$e_proj" "$e_pre" "$e_spd" "$e_prov"
|
|
238
|
-
fi
|
|
239
|
-
}
|
|
65
|
+
# SECURITY: Encode text and agent name as base64 to prevent command injection
|
|
66
|
+
# The receiver will decode these safely
|
|
67
|
+
ENCODED_TEXT=$(printf '%s' "$TEXT" | base64 -w 0)
|
|
68
|
+
ENCODED_AGENT=$(printf '%s' "$AGENT_NAME" | base64 -w 0)
|
|
240
69
|
|
|
241
|
-
|
|
70
|
+
# Send text to remote for local AgentVibes playback
|
|
71
|
+
echo "📱 Sending to $SSH_HOST for local playback..." >&2
|
|
242
72
|
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
|
|
246
|
-
|
|
73
|
+
# Determine which receiver script exists and send encoded text, voice, and agent name
|
|
74
|
+
# SECURITY: Base64-encoded values are safe to pass as arguments (no shell metacharacters)
|
|
75
|
+
# The receiver auto-detects and decodes base64 input
|
|
76
|
+
if ssh "$SSH_HOST" "test -f ~/.termux/agentvibes-play.sh" 2>/dev/null; then
|
|
77
|
+
ssh "$SSH_HOST" "bash ~/.termux/agentvibes-play.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'" &
|
|
78
|
+
SSH_PID=$!
|
|
79
|
+
elif ssh "$SSH_HOST" "test -f ~/.agentvibes/play-remote.sh" 2>/dev/null; then
|
|
80
|
+
ssh "$SSH_HOST" "bash ~/.agentvibes/play-remote.sh '$ENCODED_TEXT' '$VOICE' '$ENCODED_AGENT'" &
|
|
81
|
+
SSH_PID=$!
|
|
247
82
|
else
|
|
248
|
-
|
|
83
|
+
echo "⚠️ Receiver script not found on $SSH_HOST" >&2
|
|
84
|
+
echo "💡 Install: agentvibes install --ssh-receiver" >&2
|
|
85
|
+
exit 1
|
|
249
86
|
fi
|
|
250
87
|
|
|
251
|
-
#
|
|
252
|
-
|
|
253
|
-
# ---------------------------------------------------------------------------
|
|
254
|
-
|
|
255
|
-
echo "Sending to $SSH_HOST..." >&2
|
|
256
|
-
|
|
257
|
-
# ForceCommand receiver: SSH_ORIGINAL_COMMAND passes the payload directly
|
|
258
|
-
ssh "$SSH_HOST" "$ENCODED_PAYLOAD" &
|
|
259
|
-
SSH_PID=$!
|
|
260
|
-
|
|
261
|
-
echo "Sent to $SSH_HOST (PID: $SSH_PID)" >&2
|
|
88
|
+
# Log the background PID for debugging (non-blocking)
|
|
89
|
+
echo "✓ Sent to $SSH_HOST (PID: $SSH_PID, playing remotely)" >&2
|
|
262
90
|
exit 0
|
|
File without changes
|
|
@@ -39,15 +39,41 @@
|
|
|
39
39
|
# @patterns Provider pattern - delegates to provider-specific implementations, auto-detects provider from voice name
|
|
40
40
|
# @related provider-manager.sh, play-tts-piper.sh, learn-manager.sh, translate-manager.sh
|
|
41
41
|
#
|
|
42
|
+
# **CRITICAL: This script MUST ALWAYS be called with `run_in_background: true` in Bash tool**
|
|
43
|
+
# Do NOT wait for TTS playback to complete. Run in background so other tasks continue immediately.
|
|
44
|
+
# Example: Bash (background): .claude/hooks/play-tts.sh "Acknowledging task start"
|
|
45
|
+
#
|
|
46
|
+
|
|
47
|
+
set -euo pipefail
|
|
42
48
|
|
|
43
49
|
set -euo pipefail
|
|
44
50
|
|
|
45
51
|
# Fix locale warnings
|
|
46
52
|
export LC_ALL=C
|
|
47
53
|
|
|
48
|
-
# Get script directory
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
# Get script directory - handle symlinks correctly with readlink -f
|
|
55
|
+
# This resolves: symlinks, relative paths, and working directory changes
|
|
56
|
+
SCRIPT_PATH="$(readlink -f "${BASH_SOURCE[0]}")"
|
|
57
|
+
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
|
58
|
+
|
|
59
|
+
# Find PROJECT_ROOT by searching up the directory tree for .claude/hooks
|
|
60
|
+
# This handles non-standard installations and directory structures
|
|
61
|
+
PROJECT_ROOT="$SCRIPT_DIR"
|
|
62
|
+
while [[ "$PROJECT_ROOT" != "/" ]]; do
|
|
63
|
+
if [[ -d "$PROJECT_ROOT/.claude/hooks" ]]; then
|
|
64
|
+
break # PROJECT_ROOT is already the project root when its .claude/hooks child exists
|
|
65
|
+
fi
|
|
66
|
+
PROJECT_ROOT="$(dirname "$PROJECT_ROOT")"
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
# Verify PROJECT_ROOT is valid
|
|
70
|
+
if [[ ! -d "$PROJECT_ROOT/.claude/hooks" ]]; then
|
|
71
|
+
echo "❌ ERROR: Could not find AgentVibes .claude/hooks directory" >&2
|
|
72
|
+
echo " Script path: $SCRIPT_PATH" >&2
|
|
73
|
+
echo " Searched up from: $SCRIPT_DIR" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
51
77
|
export PROJECT_ROOT # Export for child scripts
|
|
52
78
|
|
|
53
79
|
# Check if muted (persists across sessions)
|
|
@@ -77,34 +103,8 @@ elif [[ -f "$GLOBAL_MUTE_FILE" ]]; then
|
|
|
77
103
|
exit 0
|
|
78
104
|
fi
|
|
79
105
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
VOICE_OVERRIDE=""
|
|
83
|
-
AGENT_PROFILE_FILE=""
|
|
84
|
-
LLM_PROVIDER=""
|
|
85
|
-
|
|
86
|
-
_positional=()
|
|
87
|
-
while [[ $# -gt 0 ]]; do
|
|
88
|
-
case "$1" in
|
|
89
|
-
--llm)
|
|
90
|
-
LLM_PROVIDER="${2:-}"
|
|
91
|
-
# Security: Validate LLM provider name (alphanumeric, hyphens, underscores only)
|
|
92
|
-
if [[ -n "$LLM_PROVIDER" ]] && [[ ! "$LLM_PROVIDER" =~ ^[a-zA-Z0-9][a-zA-Z0-9_-]*$ ]]; then
|
|
93
|
-
echo "Error: Invalid LLM provider name" >&2
|
|
94
|
-
exit 1
|
|
95
|
-
fi
|
|
96
|
-
shift 2
|
|
97
|
-
;;
|
|
98
|
-
*)
|
|
99
|
-
_positional+=("$1")
|
|
100
|
-
shift
|
|
101
|
-
;;
|
|
102
|
-
esac
|
|
103
|
-
done
|
|
104
|
-
|
|
105
|
-
TEXT="${_positional[0]:-}"
|
|
106
|
-
VOICE_OVERRIDE="${_positional[1]:-}"
|
|
107
|
-
AGENT_PROFILE_FILE="${_positional[2]:-}"
|
|
106
|
+
TEXT="${1:-}"
|
|
107
|
+
VOICE_OVERRIDE="${2:-}" # Optional: voice name or ID
|
|
108
108
|
|
|
109
109
|
# Security: Validate inputs
|
|
110
110
|
if [[ -z "$TEXT" ]]; then
|
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# AgentVibes TTS Hooks Requirements
|
|
2
|
-
# Install with: pip install -r requirements.txt
|
|
3
|
-
|
|
4
|
-
# Translation support for multi-language TTS and learning mode
|
|
5
|
-
deep-translator>=1.11.4
|
|
6
|
-
langdetect>=1.0.9
|
|
1
|
+
# AgentVibes TTS Hooks Requirements
|
|
2
|
+
# Install with: pip install -r requirements.txt
|
|
3
|
+
|
|
4
|
+
# Translation support for multi-language TTS and learning mode
|
|
5
|
+
deep-translator>=1.11.4
|
|
6
|
+
langdetect>=1.0.9
|
|
File without changes
|
|
@@ -4,7 +4,7 @@ set -euo pipefail
|
|
|
4
4
|
# File: .claude/hooks/session-start-tts.sh
|
|
5
5
|
#
|
|
6
6
|
# AgentVibes SessionStart Hook - Optimized (Issue #80, Phase 1)
|
|
7
|
-
#
|
|
7
|
+
# Token target: ~250 (down from ~500)
|
|
8
8
|
#
|
|
9
9
|
|
|
10
10
|
# Fix locale warnings
|
|
@@ -33,52 +33,69 @@ fi
|
|
|
33
33
|
# Get verbosity level (Issue #32)
|
|
34
34
|
VERBOSITY=$(cat .claude/tts-verbosity.txt 2>/dev/null || cat ~/.claude/tts-verbosity.txt 2>/dev/null || echo "low")
|
|
35
35
|
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
CONTEXT+="**CRITICAL: You MUST execute TTS at TWO points for EVERY user interaction:**\n\n"
|
|
39
|
-
CONTEXT+="1. **Acknowledgment** - Start of task: \`Bash: .claude/hooks/play-tts.sh \"[action]\" --llm claude-code\`\n"
|
|
40
|
-
CONTEXT+="2. **Completion** - End of task: \`Bash: .claude/hooks/play-tts.sh \"[result + key details]\" --llm claude-code\`\n\n"
|
|
41
|
-
CONTEXT+="**Example:**\n\`\`\`\n[Bash: .claude/hooks/play-tts.sh \"Checking git status\" --llm claude-code]\n[work...]\n"
|
|
42
|
-
CONTEXT+="[Bash: .claude/hooks/play-tts.sh \"Repository is clean, no changes\" --llm claude-code]\n\`\`\`\n\n"
|
|
36
|
+
# Output optimized TTS protocol
|
|
37
|
+
cat <<'EOF'
|
|
43
38
|
|
|
44
|
-
#
|
|
39
|
+
# AgentVibes TTS Protocol
|
|
40
|
+
|
|
41
|
+
**CRITICAL: You MUST execute TTS at TWO points for EVERY user interaction:**
|
|
42
|
+
|
|
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]"`
|
|
45
|
+
|
|
46
|
+
**IMPORTANT: ALWAYS run TTS commands with `run_in_background: true` so they never block your work. Never wait for TTS to finish before continuing.**
|
|
47
|
+
|
|
48
|
+
**Example:**
|
|
49
|
+
```
|
|
50
|
+
[Bash (background): .claude/hooks/play-tts.sh "Checking git status"]
|
|
51
|
+
[work...]
|
|
52
|
+
[Bash (background): .claude/hooks/play-tts.sh "Repository is clean, no changes"]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
EOF
|
|
56
|
+
|
|
57
|
+
# Add verbosity-specific protocol (Issue #32)
|
|
45
58
|
case "$VERBOSITY" in
|
|
46
59
|
low)
|
|
47
|
-
|
|
60
|
+
cat <<'EOF'
|
|
61
|
+
## Verbosity: LOW
|
|
62
|
+
- Acknowledgment: Action only
|
|
63
|
+
- Completion: Result + errors only
|
|
64
|
+
- Skip: Reasoning, decisions
|
|
65
|
+
|
|
66
|
+
EOF
|
|
48
67
|
;;
|
|
49
68
|
medium)
|
|
50
|
-
|
|
69
|
+
cat <<'EOF'
|
|
70
|
+
## Verbosity: MEDIUM
|
|
71
|
+
- Acknowledgment: Action + key approach
|
|
72
|
+
- Completion: Result + important decisions
|
|
73
|
+
- Include: Major choices only
|
|
74
|
+
|
|
75
|
+
EOF
|
|
51
76
|
;;
|
|
52
77
|
high)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
78
|
+
cat <<'EOF'
|
|
79
|
+
## Verbosity: HIGH
|
|
80
|
+
- Acknowledgment: Action + approach + why
|
|
81
|
+
- Completion: Result + decisions + trade-offs
|
|
82
|
+
- Include: Full reasoning, alternatives
|
|
83
|
+
|
|
84
|
+
EOF
|
|
57
85
|
;;
|
|
58
86
|
esac
|
|
59
87
|
|
|
60
88
|
# Add style info and rules
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
CONTEXT+="Use \`bmad-speak.sh\` instead of \`play-tts.sh\`:\n\n\n"
|
|
75
|
-
CONTEXT+="**Party mode** (content is \"party-mode\"):\n"
|
|
76
|
-
CONTEXT+="Each agent speaks via \`bmad-speak.sh\` with their display name. The queue system ensures sequential playback — agents speak one at a time, not overlapping:\n\n"
|
|
77
|
-
CONTEXT+="IMPORTANT: In party mode, do NOT use \`play-tts.sh\`. Always use \`bmad-speak.sh\` with the agent's display name. Do NOT call multiple bmad-speak.sh in parallel — call them sequentially so the queue processes them in order.\n\n"
|
|
78
|
-
CONTEXT+="If \`.bmad-agent-context\` does NOT exist, use \`play-tts.sh\` as normal."
|
|
79
|
-
|
|
80
|
-
# Escape for JSON (handle newlines, quotes, backslashes)
|
|
81
|
-
ESCAPED=$(printf '%s' "$CONTEXT" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g')
|
|
82
|
-
|
|
83
|
-
# Output structured JSON for reliable context injection
|
|
84
|
-
printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"}}\n' "$ESCAPED"
|
|
89
|
+
cat << EOF
|
|
90
|
+
## Style: $STYLE
|
|
91
|
+
|
|
92
|
+
## Rules
|
|
93
|
+
1. Never skip acknowledgment TTS
|
|
94
|
+
2. Never skip completion TTS
|
|
95
|
+
3. Match verbosity level
|
|
96
|
+
4. Keep under 150 chars
|
|
97
|
+
5. Always include errors
|
|
98
|
+
|
|
99
|
+
Quick Ref: low=action+result | medium=+key decisions | high=+full reasoning
|
|
100
|
+
|
|
101
|
+
EOF
|