import { notificationToDesktopText, type NotificationInput } from "./notify-protocol.ts"; import type { Runtime } from "./runtime.ts"; export const OSASCRIPT_PATH = "/usr/bin/osascript"; export function escapeAppleScriptLiteral(value: string): string { return value .replaceAll("\\", "\\\\") .replaceAll("\"", "\\\"") .replace(/[\r\n\u2028\u2029]/gu, character => character === "\r" ? "\\r" : "\\n"); } export function resolveMacosNotifier(runtime: Runtime): string | null { try { return runtime.isExecutable(OSASCRIPT_PATH) ? OSASCRIPT_PATH : null; } catch { return null; } } export function buildMacosNotifyCommand(input: NotificationInput, path = OSASCRIPT_PATH): string[] { const { title, body } = notificationToDesktopText(input); const script = `display notification "${escapeAppleScriptLiteral(body)}" with title "${escapeAppleScriptLiteral(title)}"`; return [path, "-e", script]; } export function resolveMacosDesktopCommand(input: NotificationInput, runtime: Runtime): { command: string; args: string[] } | null { const path = resolveMacosNotifier(runtime); if (!path) return null; const argv = buildMacosNotifyCommand(input, path); return { command: argv[0]!, args: argv.slice(1) }; } export function sendMacosDesktopNotification(input: NotificationInput, runtime: Runtime): boolean { const resolved = resolveMacosDesktopCommand(input, runtime); if (!resolved) return false; runtime.spawnDetached(resolved.command, resolved.args); return true; }