export const createNotificationEmitterRuntime = (dependencies) => { const { process, getDesktopNotifyEnabled, desktopNotifyPrefix, getUiNotificationClients, getBroadcastGlobalUiEvent, // Optional: in-process desktop shells (Electron main) inject a callback so // notifications are delivered as a direct function call instead of a stdout // stringly-typed IPC. onDesktopNotification: initialOnDesktopNotification, } = dependencies; // Late-bindable: main() in server/index.js may call setOnDesktopNotification // after runtime construction so the in-process shell can subscribe without // restructuring the module-level wiring. let onDesktopNotification = typeof initialOnDesktopNotification === 'function' ? initialOnDesktopNotification : null; const setOnDesktopNotification = (cb) => { onDesktopNotification = typeof cb === 'function' ? cb : null; }; const writeSseEvent = (res, payload) => { res.write(`data: ${JSON.stringify(payload)}\n\n`); }; const emitDesktopNotification = (payload) => { const desktopNotifyEnabled = getDesktopNotifyEnabled(); if (!desktopNotifyEnabled) { return false; } if (!payload || typeof payload !== 'object') { return false; } if (onDesktopNotification) { try { onDesktopNotification(payload); return true; } catch { // ignore host-side throw } return false; } try { // stdout fallback for runtimes that parse the one-line `${prefix}{json}` protocol. process.stdout.write(`${desktopNotifyPrefix}${JSON.stringify(payload)}\n`); return true; } catch { // ignore } return false; }; const broadcastUiNotification = (payload, options = {}) => { const desktopNotifyEnabled = getDesktopNotifyEnabled(); if (!payload || typeof payload !== 'object') { return; } const desktopNotificationDelivered = options.desktopNotificationDelivered === true; const syntheticPayload = { type: 'openchamber:notification', properties: { ...payload, // Tell local desktop UI whether a native channel already accepted this // notification. If so, the SSE/WS event is informational only and must // not create a second OS notification. desktopNotificationDelivered, // Legacy marker retained for older clients that only know about stdout. desktopStdoutActive: desktopNotifyEnabled, }, }; const broadcastGlobalUiEvent = typeof getBroadcastGlobalUiEvent === 'function' ? getBroadcastGlobalUiEvent() : null; if (broadcastGlobalUiEvent) { broadcastGlobalUiEvent(syntheticPayload); return; } const clients = getUiNotificationClients(); if (clients.size === 0) { return; } for (const res of clients) { try { writeSseEvent(res, syntheticPayload); } catch { // ignore } } }; return { writeSseEvent, emitDesktopNotification, broadcastUiNotification, setOnDesktopNotification, }; };