Problem
notify.sh shells out to \${VENV}/bin/stackvox-say to speak notifications, but that binary does not exist in stackvox 0.3.x. The current stackvox CLI is unified — say is a subcommand (stackvox say ...), not a separate console_script.
The speak_notification() function gates on [[ ! -x "$STACKVOX_SAY" ]] && return, so when the binary is missing it bails silently. Users with STACKNUDGE_VOICE=true get no voice and no error — install looks healthy, daemon is running, models are downloaded, the manual stackvox speak command works, but hooks never speak.
Repro
- Fresh install on macOS with
./install.sh.
- Set in
~/.stack-nudge/config:
STACKNUDGE_VOICE=true
STACKNUDGE_VOICE_NAME=af_river
- Trigger a Claude Code Stop hook (or run
~/.stack-nudge/notify.sh claude-code stop).
- Expected: voice speaks. Actual: silence (banner + sound still fire).
Trace shows the bail:
+ STACKVOX_SAY=/Users/me/.stack-nudge/venv/bin/stackvox-say
+ speak_notification 'stack nudge is ready for you'
+ [[ ! -x /Users/me/.stack-nudge/venv/bin/stackvox-say ]]
And the venv only contains the unified CLI:
$ ls ~/.stack-nudge/venv/bin/ | grep -i stack
stackvox
$ ~/.stack-nudge/venv/bin/stackvox say --help
usage: stackvox say [-h] [--voice VOICE] [--speed SPEED] [--lang LANG] [--file FILE] [--fallback-say] [text]
Suggested fix
In notify.sh (around lines 207–223):
STACKVOX="${VENV}/bin/stackvox"
-STACKVOX_SAY="${VENV}/bin/stackvox-say"
speak_notification() {
[[ "${VOICE_ENABLED}" != "true" ]] && return
- [[ ! -x "$STACKVOX_SAY" ]] && return
+ [[ ! -x "$STACKVOX" ]] && return
local text="$1"
if [[ ! -S "${HOME}/.cache/stackvox/daemon.sock" ]]; then
nohup "$STACKVOX" serve >/dev/null 2>&1 &
fi
local kokoro_lang
kokoro_lang=$(voice_to_kokoro_lang "$VOICE_NAME")
- "$STACKVOX_SAY" --voice "${VOICE_NAME}" --lang "${kokoro_lang}" --speed "${VOICE_SPEED}" "${text}" 2>/dev/null &
+ "$STACKVOX" say --voice "${VOICE_NAME}" --lang "${kokoro_lang}" --speed "${VOICE_SPEED}" "${text}" 2>/dev/null &
}
I patched my local copy this way and voice now fires correctly through the hook path.
Defensive tweak
The silent bail ([[ ! -x "$STACKVOX_SAY" ]] && return) is the reason this hid for who-knows-how-long. Worth logging to a log file (or stderr behind a STACKNUDGE_DEBUG=true flag) when voice is requested but the binary is missing — same logic for the daemon-socket check.
Pin or document the version
install.sh pins stackvox>=0.3.0. Either:
- Pin a known-working range that still ships
stackvox-say, or
- Update
notify.sh to call stackvox say (recommended, since the unified CLI is the going-forward shape).
Environment
- macOS Darwin 25.3.0
- stackvox 0.3.1
- Python 3.13.13 (Homebrew)
- daemon running, models downloaded successfully
Related
Same install session as #11 and #12.
Problem
notify.shshells out to\${VENV}/bin/stackvox-sayto speak notifications, but that binary does not exist in stackvox 0.3.x. The current stackvox CLI is unified —sayis a subcommand (stackvox say ...), not a separate console_script.The
speak_notification()function gates on[[ ! -x "$STACKVOX_SAY" ]] && return, so when the binary is missing it bails silently. Users withSTACKNUDGE_VOICE=trueget no voice and no error — install looks healthy, daemon is running, models are downloaded, the manualstackvox speakcommand works, but hooks never speak.Repro
./install.sh.~/.stack-nudge/config:~/.stack-nudge/notify.sh claude-code stop).Trace shows the bail:
And the venv only contains the unified CLI:
Suggested fix
In
notify.sh(around lines 207–223):STACKVOX="${VENV}/bin/stackvox" -STACKVOX_SAY="${VENV}/bin/stackvox-say" speak_notification() { [[ "${VOICE_ENABLED}" != "true" ]] && return - [[ ! -x "$STACKVOX_SAY" ]] && return + [[ ! -x "$STACKVOX" ]] && return local text="$1" if [[ ! -S "${HOME}/.cache/stackvox/daemon.sock" ]]; then nohup "$STACKVOX" serve >/dev/null 2>&1 & fi local kokoro_lang kokoro_lang=$(voice_to_kokoro_lang "$VOICE_NAME") - "$STACKVOX_SAY" --voice "${VOICE_NAME}" --lang "${kokoro_lang}" --speed "${VOICE_SPEED}" "${text}" 2>/dev/null & + "$STACKVOX" say --voice "${VOICE_NAME}" --lang "${kokoro_lang}" --speed "${VOICE_SPEED}" "${text}" 2>/dev/null & }I patched my local copy this way and voice now fires correctly through the hook path.
Defensive tweak
The silent bail (
[[ ! -x "$STACKVOX_SAY" ]] && return) is the reason this hid for who-knows-how-long. Worth logging to a log file (or stderr behind aSTACKNUDGE_DEBUG=trueflag) when voice is requested but the binary is missing — same logic for the daemon-socket check.Pin or document the version
install.shpinsstackvox>=0.3.0. Either:stackvox-say, ornotify.shto callstackvox say(recommended, since the unified CLI is the going-forward shape).Environment
Related
Same install session as #11 and #12.