Created
January 6, 2026 06:11
-
-
Save lamngockhuong/900630e7dd403e07644664f09283c37e to your computer and use it in GitHub Desktop.
Play sound for claude hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env node | |
| const { execSync, spawn } = require("child_process"); | |
| const os = require("os"); | |
| const fs = require("fs"); | |
| const soundType = process.argv[2] || "default"; | |
| // Check if command exists | |
| function commandExists(cmd) { | |
| try { | |
| execSync(`which ${cmd}`, { stdio: "ignore" }); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| // Get Linux sound player | |
| function getLinuxPlayer() { | |
| const players = ["paplay", "aplay", "play", "mpv", "ffplay"]; | |
| for (const player of players) { | |
| if (commandExists(player)) return player; | |
| } | |
| return null; | |
| } | |
| // Get platform-specific sound config | |
| function getSoundConfig(type = "default") { | |
| const platform = os.platform(); | |
| switch (platform) { | |
| case "darwin": | |
| const macSounds = { | |
| default: "/System/Library/Sounds/Funk.aiff", | |
| notification: "/System/Library/Sounds/Blow.aiff", | |
| done: "/System/Library/Sounds/Frog.aiff", | |
| }; | |
| return { | |
| command: "afplay", | |
| args: [macSounds[type] || macSounds.default], | |
| }; | |
| case "linux": | |
| const linuxSounds = { | |
| default: "/usr/share/sounds/freedesktop/stereo/complete.oga", | |
| notification: "/usr/share/sounds/freedesktop/stereo/message.oga", | |
| done: "/usr/share/sounds/freedesktop/stereo/bell.oga", | |
| }; | |
| const soundFile = linuxSounds[type] || linuxSounds.default; | |
| const player = getLinuxPlayer(); | |
| if (!player || !fs.existsSync(soundFile)) { | |
| return null; | |
| } | |
| // Player-specific args | |
| const playerArgs = { | |
| paplay: [soundFile], | |
| aplay: [soundFile], | |
| play: [soundFile], | |
| mpv: ["--no-video", "--really-quiet", soundFile], | |
| ffplay: ["-nodisp", "-autoexit", "-loglevel", "quiet", soundFile], | |
| }; | |
| return { | |
| command: player, | |
| args: playerArgs[player] || [soundFile], | |
| }; | |
| case "win32": | |
| const winSounds = { | |
| default: "C:\\Windows\\Media\\tada.wav", | |
| notification: "C:\\Windows\\Media\\Windows Notify.wav", | |
| done: "C:\\Windows\\Media\\Windows Ding.wav", | |
| }; | |
| const winFile = winSounds[type] || winSounds.default; | |
| return { | |
| command: "powershell", | |
| args: ["-c", `(New-Object Media.SoundPlayer "${winFile}").PlaySync()`], | |
| }; | |
| default: | |
| return null; | |
| } | |
| } | |
| // Play sound and exit | |
| function playSound() { | |
| const config = getSoundConfig(soundType); | |
| if (!config) { | |
| process.exit(0); | |
| } | |
| const child = spawn(config.command, config.args, { | |
| detached: true, | |
| stdio: "ignore", | |
| }); | |
| child.unref(); | |
| process.exit(0); | |
| } | |
| playSound(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hook config: