Help us improve
Share bugs, ideas, or general feedback.
Configures notification sounds, types, volume, devices, and webhooks for claude-notifications plugin via interactive wizard with sound previews.
npx claudepluginhub 777genius/claude-notifications-go --plugin claude-notifications-goHow this command is triggered — by the user, by Claude, or both
Slash command
/claude-notifications-go:settingsThis command is limited to the following tools:
The summary Claude sees in its command listing — used to decide when to auto-load this command
# 🎵 Claude Notifications Settings Welcome! This interactive wizard will help you configure notification sounds for Claude Code. Let's make your Claude experience more delightful with custom audio notifications! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ## 🎯 KEY FEATURE: Interactive Sound Preview **IMPORTANT FOR CLAUDE:** This setup wizard is INTERACTIVE. Users can preview sounds at ANY time by saying: - "play [sound_name]" - "preview [sound_name]" - "прослушать [sound_name]" (Russian) - "проиграть [sound_name]" (Russian) **Your job:** 1. Detect when user wants to preview...
/speakEnables, disables, or configures voice feedback: set voice (e.g., azelma), toggle enabled state, add custom prompts. Manages ~/.claude/voice.local.md YAML config.
/setupConfigures sound effects theme and trigger mode for Claude Code events via interactive prompts. Supports configure (theme/mix/disable), update (refresh/test), and remove actions.
/configView or modify heartbeat daemon settings including enable/disable, interval, prompt, Telegram forwarding, security, Web UI, and cron jobs. Supports subcommands like show, on/off, interval <minutes>.
/settingsView or update Shipyard workflow settings in .shipyard/config.json. Supports list to show all, single key to view/set, or interactive mode for guided changes.
/settingsLaunches interactive editor for .planning/config.json via learnship settings workflow, preserving gates, validations, checkpoints, and routing.
/settingsView and manage global settings including article word limits and companion project defaults for code, document, diagram types. Supports show [type], set, reset subcommands.
Share bugs, ideas, or general feedback.
Welcome! This interactive wizard will help you configure notification sounds for Claude Code.
Let's make your Claude experience more delightful with custom audio notifications!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
IMPORTANT FOR CLAUDE:
This setup wizard is INTERACTIVE. Users can preview sounds at ANY time by saying:
Your job:
${PLUGIN_ROOT}/bin/sound-preview <path> to play itFlow:
Be patient and encouraging - sound selection is personal!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
First, let me verify the notification binary is installed:
# Get plugin root directory
# Priority: 1) CLAUDE_PLUGIN_ROOT env var, 2) installed plugin location, 3) current directory
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
# Try the standard installed plugin location
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
# Fallback to current directory (for development)
PLUGIN_ROOT="$(pwd)"
fi
fi
echo "Plugin root: $PLUGIN_ROOT"
echo ""
# Check if binary exists (platform-agnostic check)
BINARY_EXISTS=false
if [ -f "${PLUGIN_ROOT}/bin/claude-notifications" ] || \
[ -f "${PLUGIN_ROOT}/bin/claude-notifications-darwin-amd64" ] || \
[ -f "${PLUGIN_ROOT}/bin/claude-notifications-darwin-arm64" ] || \
[ -f "${PLUGIN_ROOT}/bin/claude-notifications-linux-amd64" ] || \
[ -f "${PLUGIN_ROOT}/bin/claude-notifications-windows-amd64.exe" ]; then
BINARY_EXISTS=true
fi
if [ "$BINARY_EXISTS" = "false" ]; then
echo "⚠️ Notification binary not found. Installing..."
echo ""
if ! "${PLUGIN_ROOT}/bin/install.sh"; then
echo ""
echo "❌ Error: Failed to install notification binary"
echo "Please run /claude-notifications-go:init or check your internet connection"
exit 1
fi
echo ""
echo "✅ Binary installed successfully!"
echo ""
else
echo "✅ Notification binary is already installed"
echo ""
fi
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Now let me detect what sound options are available on your system!
# Get plugin root (re-declare for this bash session)
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
# Detect Operating System
OS_TYPE=$(uname -s)
case "$OS_TYPE" in
Darwin*)
echo "Operating System: macOS"
HAS_SYSTEM_SOUNDS="true"
SYSTEM_SOUNDS_DIR="/System/Library/Sounds"
;;
Linux*)
echo "Operating System: Linux"
if [ -d "/usr/share/sounds" ]; then
HAS_SYSTEM_SOUNDS="true"
SYSTEM_SOUNDS_DIR="/usr/share/sounds"
else
HAS_SYSTEM_SOUNDS="false"
fi
;;
MINGW*|MSYS*|CYGWIN*)
echo "Operating System: Windows"
HAS_SYSTEM_SOUNDS="false"
;;
*)
echo "Operating System: Unknown"
HAS_SYSTEM_SOUNDS="false"
;;
esac
# Built-in Sounds
echo ""
echo "Built-in sounds (included with plugin):"
if [ -d "${PLUGIN_ROOT}/sounds" ]; then
ls -1 "${PLUGIN_ROOT}/sounds/"*.mp3 2>/dev/null | while read file; do
name=$(basename "$file" .mp3)
echo " ✓ $name.mp3"
done
else
echo " Warning: sounds/ directory not found!"
fi
# System Sounds
if [ "$HAS_SYSTEM_SOUNDS" = "true" ]; then
echo ""
echo "System sounds detected at: $SYSTEM_SOUNDS_DIR"
case "$OS_TYPE" in
Darwin*)
# macOS system sounds
echo "Available macOS system sounds:"
ls -1 /System/Library/Sounds/*.aiff 2>/dev/null | while read file; do
name=$(basename "$file" .aiff)
echo " • $name"
done
;;
Linux*)
# Linux system sounds (varies by distribution)
echo "Available Linux system sounds (sample):"
find /usr/share/sounds -type f \( -name "*.ogg" -o -name "*.wav" \) 2>/dev/null | head -10 | while read file; do
name=$(basename "$file")
echo " • $name"
done
;;
esac
else
echo ""
echo "⚠️ No system sounds detected on this platform."
echo " Don't worry! You can use the built-in MP3 sounds included with the plugin."
echo " They work perfectly on all platforms!"
fi
Always available:
macOS system sounds (if detected):
Linux system sounds (if detected):
/usr/share/sounds/━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CRITICAL INSTRUCTION FOR CLAUDE:
Before asking the user to make final choices, you MUST offer to play sounds for them.
Tell the user:
🎵 Want to hear sounds before choosing? I can play any sound for you! Just say:
"play task-complete"- Built-in task-complete sound"play Glass"- macOS Glass system sound"preview Hero"- Preview any available soundTry as many as you like! When you're ready, I'll ask you to select sounds for each notification type.
How to handle preview requests:
When user says "play [sound_name]", "preview [sound_name]", "прослушать [sound_name]", or "проиграть [sound_name]":
Extract sound name from user message (ignore the command word, keep only the sound name)
Determine the full path to the sound file:
# Get plugin root
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
# For built-in sounds (no extension needed)
if [[ "$sound_name" == "task-complete" ]] || [[ "$sound_name" == "review-complete" ]] || [[ "$sound_name" == "question" ]] || [[ "$sound_name" == "plan-ready" ]]; then
SOUND_PATH="${PLUGIN_ROOT}/sounds/${sound_name}.mp3"
# For macOS system sounds
elif [[ -f "/System/Library/Sounds/${sound_name}.aiff" ]]; then
SOUND_PATH="/System/Library/Sounds/${sound_name}.aiff"
# Try common variations
elif [[ -f "/System/Library/Sounds/${sound_name}.mp3" ]]; then
SOUND_PATH="/System/Library/Sounds/${sound_name}.mp3"
else
echo "❌ Sound '${sound_name}' not found. Available options listed above."
exit 1
fi
Play the sound using the sound-preview utility with reduced volume:
# Get plugin root
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
echo "🔊 Playing: ${sound_name}... (volume: 30%)"
"${PLUGIN_ROOT}/bin/sound-preview" --volume 0.3 "$SOUND_PATH"
echo "✓ Playback complete!"
IMPORTANT: Always use --volume 0.3 (30% volume) when previewing sounds during setup to avoid disturbing the user with loud sounds.
Ask if they want to hear more:
Would you like to:
- Hear another sound? (just type "play [name]")
- Ready to make your selections? (type "ready")
Examples of user interactions:
User: play Glass
Claude: [runs bin/sound-preview --volume 0.3 /System/Library/Sounds/Glass.aiff]
Claude: "🔊 Playing: Glass... (volume: 30%) ✓ Playback complete! Would you like to hear another sound, or ready to choose?"
User: preview task-complete
Claude: [runs bin/sound-preview --volume 0.3 sounds/task-complete.mp3]
Claude: "🔊 Playing: task-complete... (volume: 30%) ✓ Playback complete!"
User: прослушать Hero
Claude: [runs bin/sound-preview --volume 0.3 /System/Library/Sounds/Hero.aiff]
Claude: "🔊 Playing: Hero... (volume: 30%) ✓ Playback complete!"
User: проиграть Ping
Claude: [runs bin/sound-preview --volume 0.3 /System/Library/Sounds/Ping.aiff]
Claude: "🔊 Playing: Ping... (volume: 30%) ✓ Playback complete!"
User: ready
Claude: "Great! Let's configure your notification sounds..."
[proceeds to Questions 1-4]
Edge cases:
User: play unknown-sound
Claude: "❌ Sound 'unknown-sound' not found. Available sounds are:
Built-in: task-complete, review-complete, question, plan-ready
System (macOS): Glass, Hero, Funk, Sosumi, Ping, Purr, Basso, etc.
Try: 'play Glass' or 'preview task-complete'"
User: I want Glass for everything
Claude: "Great choice! Let me confirm - you want Glass for all notification types?
Or would you like to choose different sounds for each type?
(You can still preview other sounds if you'd like)"
IMPORTANT:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Now let's configure your notification sounds! I'll ask you 4 questions - one for each notification type.
IMPORTANT: Build the options list dynamically based on what's available:
# Build options array based on OS and available sounds
OPTIONS=""
# Always include built-in sounds (available on all platforms)
OPTIONS="${OPTIONS}Built-in: task-complete.mp3|Triumphant completion chime (recommended)\n"
OPTIONS="${OPTIONS}Built-in: review-complete.mp3|Gentle notification tone\n"
OPTIONS="${OPTIONS}Built-in: question.mp3|Attention sound\n"
OPTIONS="${OPTIONS}Built-in: plan-ready.mp3|Professional tone\n"
# Add system sounds if available
if [ "$HAS_SYSTEM_SOUNDS" = "true" ] && [ "$OS_TYPE" = "Darwin"* ]; then
# macOS system sounds
OPTIONS="${OPTIONS}System: Glass|Crisp macOS Glass sound\n"
OPTIONS="${OPTIONS}System: Hero|Triumphant fanfare\n"
OPTIONS="${OPTIONS}System: Funk|Distinctive funk groove\n"
OPTIONS="${OPTIONS}System: Sosumi|Pleasant macOS notification\n"
OPTIONS="${OPTIONS}System: Ping|Subtle ping sound\n"
OPTIONS="${OPTIONS}System: Purr|Gentle purr\n"
fi
echo "Available sound options built: $(echo -e "$OPTIONS" | wc -l) options"
Before presenting the question, remind the user:
🎵 Reminder: You can still preview sounds! Just say "play [sound_name]" before making your choice.
When Claude finishes a task, which sound would you like to hear?
Use AskUserQuestion with dynamically generated options:
If macOS with system sounds:
If Linux/Windows (no system sounds):
Note: System sounds are only available on macOS. On other platforms, use the built-in MP3 sounds which work perfectly everywhere!
CRITICAL: If user says "play [sound]" instead of choosing, DO NOT call AskUserQuestion yet. First play the sound, then re-ask the question.
Before presenting the question, remind the user:
🎵 Reminder: You can preview sounds! Just say "play [sound_name]" before choosing.
When Claude completes a code review or analysis, which sound?
Use AskUserQuestion with the same dynamically generated options as Question 1.
Before presenting the question, remind the user:
🎵 Reminder: You can preview sounds! Just say "play [sound_name]" before choosing.
When Claude has a question or needs clarification?
Use AskUserQuestion with the same dynamically generated options as Question 1.
Before presenting the question, remind the user:
🎵 Reminder: You can preview sounds! Just say "play [sound_name]" before choosing.
When Claude finishes planning and is ready for your review?
Use AskUserQuestion with the same dynamically generated options as Question 1.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Now let's choose which notification types you want to receive. You can disable specific types that you find too frequent.
Use AskUserQuestion with:
Note: By default all types are selected (enabled). Unselecting a type will disable notifications for that status.
Mapping user selection to config:
"enabled": true (or omit, as nil = true)"enabled": falseExample: If user only selects "question" and "plan_ready":
{
"statuses": {
"task_complete": { "enabled": false, "title": "...", "sound": "..." },
"review_complete": { "enabled": false, "title": "...", "sound": "..." },
"question": { "enabled": true, "title": "...", "sound": "..." },
"plan_ready": { "enabled": true, "title": "...", "sound": "..." }
}
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Now let's configure the volume for your notification sounds.
Use AskUserQuestion with:
Volume mapping:
1.00.70.50.30.1Important: Parse the user's choice and extract the numeric value (e.g., "70%" → 0.7).
Note: You can offer to preview a sound at the selected volume:
# Get plugin root
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
echo "Let me play a quick test at your selected volume..."
"${PLUGIN_ROOT}/bin/sound-preview" --volume <selected_volume> "${PLUGIN_ROOT}/sounds/task-complete.mp3"
echo "How does that sound? (If you want to adjust, just let me know)"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
You can route notification sounds to a specific audio output device instead of using the system default.
First, list available audio devices:
# Get plugin root
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
echo "Available audio output devices:"
"${PLUGIN_ROOT}/bin/list-devices"
Use AskUserQuestion with:
If user selects "Specific device":
Device name mapping:
"" (empty string in config)Note: Leave audioDevice empty to use the system default. This is recommended unless you have a specific reason to route audio elsewhere.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Do you want to send notifications to a webhook (Slack, Discord, Telegram)?
Use AskUserQuestion with:
If webhook is enabled, I'll create a placeholder configuration that you can edit later.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Based on your answers, I'll create ~/.claude/claude-notifications-go/config.json:
Sound Path Construction (Important!):
Parse the user's choice and construct the correct path:
# Function to convert user choice to file path
get_sound_path() {
local choice="$1"
# Check if it's a built-in sound
if [[ "$choice" == "Built-in:"* ]] || [[ "$choice" == *".mp3" ]]; then
# Extract filename
filename=$(echo "$choice" | sed 's/Built-in: //' | sed 's/^[^:]*: //')
echo "\${CLAUDE_PLUGIN_ROOT}/sounds/${filename}"
# Check if it's a system sound (macOS)
elif [[ "$choice" == "System:"* ]]; then
# Extract sound name (e.g., "Glass" from "System: Glass")
soundname=$(echo "$choice" | sed 's/System: //' | awk '{print $1}')
echo "/System/Library/Sounds/${soundname}.aiff"
# Fallback to built-in if parsing fails
else
echo "\${CLAUDE_PLUGIN_ROOT}/sounds/task-complete.mp3"
fi
}
# Example usage:
TASK_COMPLETE_PATH=$(get_sound_path "$user_answer_1")
REVIEW_COMPLETE_PATH=$(get_sound_path "$user_answer_2")
QUESTION_PATH=$(get_sound_path "$user_answer_3")
PLAN_READY_PATH=$(get_sound_path "$user_answer_4")
Examples:
${CLAUDE_PLUGIN_ROOT}/sounds/task-complete.mp3/System/Library/Sounds/Glass.aiffConfiguration Template:
IMPORTANT - Webhook Configuration Rules:
"enabled": false and "preset": "custom" (DO NOT use "none")"enabled": true and "preset": "slack""enabled": true and "preset": "discord""enabled": true and "preset": "telegram""enabled": true and "preset": "custom"{
"notifications": {
"desktop": {
"enabled": true,
"sound": true,
"volume": <user's selected volume>,
"audioDevice": "<user's selected device or empty string>",
"appIcon": "${CLAUDE_PLUGIN_ROOT}/claude_icon.png"
},
"webhook": {
"enabled": <true if webhook selected, false for "No webhooks">,
"preset": "<slack|discord|telegram|custom - NEVER use 'none', use 'custom' if No webhooks>",
"url": "<placeholder - user must edit>",
"chat_id": "<for telegram only>",
"format": "json",
"headers": {},
"payloadFields": {}
},
"suppressQuestionAfterTaskCompleteSeconds": 7
},
"statuses": {
"task_complete": {
"enabled": <true if selected in Step 4.5, false if not selected>,
"title": "✅ Task Completed",
"sound": "<user's choice>"
},
"review_complete": {
"enabled": <true if selected in Step 4.5, false if not selected>,
"title": "🔍 Review Completed",
"sound": "<user's choice>"
},
"question": {
"enabled": <true if selected in Step 4.5, false if not selected>,
"title": "❓ Claude Has Questions",
"sound": "<user's choice>"
},
"plan_ready": {
"enabled": <true if selected in Step 4.5, false if not selected>,
"title": "📋 Plan Ready for Review",
"sound": "<user's choice>"
}
}
}
Writing the config file:
First, get the stable config directory and create it:
mkdir -p "$HOME/.claude/claude-notifications-go"
echo "$HOME/.claude/claude-notifications-go/config.json"
Write config to the stable path (from echo output above)
Also copy to legacy path for backward compat with older binary versions:
cp "$HOME/.claude/claude-notifications-go/config.json" "${PLUGIN_ROOT}/config/config.json" 2>/dev/null || true
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
After creating the configuration, show the user:
🎉 Configuration Saved Successfully!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📝 Summary:
✅ Task Complete → <chosen sound> <ENABLED/DISABLED>
🔍 Review Complete → <chosen sound> <ENABLED/DISABLED>
❓ Question → <chosen sound> <ENABLED/DISABLED>
📋 Plan Ready → <chosen sound> <ENABLED/DISABLED>
🔊 Desktop notifications: ENABLED
🔊 Volume: <selected volume>%
🔊 Audio device: <selected device or "System default">
🔗 Webhooks: <ENABLED/DISABLED>
Configuration file: ~/.claude/claude-notifications-go/config.json
Ask user: "Would you like to test your task-complete notification now?"
If yes:
# Get plugin root
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"
if [ -z "$PLUGIN_ROOT" ]; then
INSTALLED_PATH="$HOME/.claude/plugins/marketplaces/claude-notifications-go"
if [ -d "$INSTALLED_PATH" ]; then
PLUGIN_ROOT="$INSTALLED_PATH"
else
PLUGIN_ROOT="$(pwd)"
fi
fi
echo "Testing task-complete sound at your configured volume (<selected_volume>%)..."
"${PLUGIN_ROOT}/bin/sound-preview" --volume <selected_volume> "<path-to-chosen-sound>"
echo "✓ Sound test complete!"
Note: This test uses your configured volume level. The actual notifications will use this same volume.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Editing Later:
/claude-notifications-go:settings anytime to reconfigure~/.claude/claude-notifications-go/config.jsonWebhook Configuration:
If you enabled webhooks, you'll need to manually edit ~/.claude/claude-notifications-go/config.json to add:
Sound Formats Supported:
System Sounds:
/System/Library/Sounds/*.aiff/usr/share/sounds/**/*.ogg (varies by distribution)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✨ Sound Selection Tips:
🎯 Recommended Combinations:
Minimal Setup:
Power User Setup:
Built-in Sounds:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Ready to begin? Let's start by choosing your sound source! 🎵