From e9d7dca604c231f7320ccc49aad6e1c1c59613d8 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 5 May 2026 23:06:01 +0900 Subject: [PATCH] fix(session-notification): tolerate shell promises without nothrow --- src/hooks/session-notification-sender.ts | 29 ++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/hooks/session-notification-sender.ts b/src/hooks/session-notification-sender.ts index 4d33bed77..8849e1af8 100644 --- a/src/hooks/session-notification-sender.ts +++ b/src/hooks/session-notification-sender.ts @@ -33,6 +33,21 @@ export function getDefaultSoundPath(platform: Platform): string { } } +type ShellCommand = Promise & { + quiet?: () => Promise + nothrow?: () => ShellCommand +} + +async function runQuietNothrow(command: ShellCommand): Promise { + const safeCommand = typeof command.nothrow === "function" ? command.nothrow() : command + if (typeof safeCommand.quiet === "function") { + await safeCommand.quiet() + return + } + + await safeCommand +} + export async function sendSessionNotification( ctx: PluginInput, platform: Platform, @@ -72,14 +87,14 @@ export async function sendSessionNotification( const escapedTitle = escapeAppleScriptText(title) const escapedMessage = escapeAppleScriptText(message) - await ctx.$`${osascriptPath} -e ${"display notification \"" + escapedMessage + "\" with title \"" + escapedTitle + "\""}`.nothrow().quiet() + await runQuietNothrow(ctx.$`${osascriptPath} -e ${"display notification \"" + escapedMessage + "\" with title \"" + escapedTitle + "\""}`) break } case "linux": { const notifySendPath = await getNotifySendPath() if (!notifySendPath) return - await ctx.$`${notifySendPath} ${title} ${message} 2>/dev/null`.nothrow().quiet() + await runQuietNothrow(ctx.$`${notifySendPath} ${title} ${message} 2>/dev/null`) break } case "win32": { @@ -87,7 +102,7 @@ export async function sendSessionNotification( if (!powershellPath) return const toastScript = buildWindowsToastScript(title, message) - await ctx.$`${powershellPath} -Command ${toastScript}`.nothrow().quiet() + await runQuietNothrow(ctx.$`${powershellPath} -Command ${toastScript}`) break } } @@ -102,17 +117,17 @@ export async function playSessionNotificationSound( case "darwin": { const afplayPath = await getAfplayPath() if (!afplayPath) return - ctx.$`${afplayPath} ${soundPath}`.nothrow().quiet() + await runQuietNothrow(ctx.$`${afplayPath} ${soundPath}`) break } case "linux": { const paplayPath = await getPaplayPath() if (paplayPath) { - ctx.$`${paplayPath} ${soundPath} 2>/dev/null`.nothrow().quiet() + await runQuietNothrow(ctx.$`${paplayPath} ${soundPath} 2>/dev/null`) } else { const aplayPath = await getAplayPath() if (aplayPath) { - ctx.$`${aplayPath} ${soundPath} 2>/dev/null`.nothrow().quiet() + await runQuietNothrow(ctx.$`${aplayPath} ${soundPath} 2>/dev/null`) } } break @@ -121,7 +136,7 @@ export async function playSessionNotificationSound( const powershellPath = await getPowershellPath() if (!powershellPath) return const escaped = escapePowerShellSingleQuotedText(soundPath) - ctx.$`${powershellPath} -Command ${"(New-Object Media.SoundPlayer '" + escaped + "').PlaySync()"}`.nothrow().quiet() + await runQuietNothrow(ctx.$`${powershellPath} -Command ${"(New-Object Media.SoundPlayer '" + escaped + "').PlaySync()"}`) break } }