From 78052fe43791ae73b7770e8ea2b88832a1bdff17 Mon Sep 17 00:00:00 2001 From: brooklyn! Date: Wed, 9 Sep 2026 21:34:56 -0700 Subject: [PATCH] fix(desktop): keep notification IPC types independent of the renderer The Electron composite project imported src/global.d.ts and followed its renderer-only dependencies. Share the notification payload from a dependency-free Electron module instead; all desktop typechecks and lint now pass. --- .../desktop/electron/notification-ipc.test.ts | 2 +- apps/desktop/electron/notification-ipc.ts | 4 ++-- apps/desktop/electron/notification-types.ts | 19 ++++++++++++++++++ apps/desktop/src/global.d.ts | 20 +------------------ 4 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 apps/desktop/electron/notification-types.ts diff --git a/apps/desktop/electron/notification-ipc.test.ts b/apps/desktop/electron/notification-ipc.test.ts index 9cdd110d7c..011ff7c15a 100644 --- a/apps/desktop/electron/notification-ipc.test.ts +++ b/apps/desktop/electron/notification-ipc.test.ts @@ -3,7 +3,7 @@ import { EventEmitter } from 'node:events' import type { BrowserWindow, IpcMainInvokeEvent } from 'electron' import { beforeEach, expect, it, vi } from 'vitest' -import type { HermesNotification } from '../src/global' +import type { HermesNotification } from './notification-types' const host = vi.hoisted(() => ({ handle: vi.fn(), diff --git a/apps/desktop/electron/notification-ipc.ts b/apps/desktop/electron/notification-ipc.ts index cafdd88452..1567989acd 100644 --- a/apps/desktop/electron/notification-ipc.ts +++ b/apps/desktop/electron/notification-ipc.ts @@ -1,10 +1,9 @@ import { BrowserWindow, ipcMain, Notification } from 'electron' -import type { HermesNotification } from '../src/global' - import { createEventDeduper } from './event-dedupe' import { resolveNotificationAction } from './notification-actions' import { createNotificationRegistry } from './notification-registry' +import type { HermesNotification } from './notification-types' interface NotificationHost { getMainWindow: () => BrowserWindow | null @@ -31,6 +30,7 @@ export function registerNativeNotifications({ getMainWindow, focusWindow }: Noti const actions = Array.isArray(payload?.actions) ? payload.actions : [] const icon = typeof payload?.icon === 'string' && payload.icon.trim() ? payload.icon.trim() : undefined + const notification = new Notification({ title: payload?.title || 'Hermes', body: payload?.body || '', diff --git a/apps/desktop/electron/notification-types.ts b/apps/desktop/electron/notification-types.ts new file mode 100644 index 0000000000..e54d52ea3e --- /dev/null +++ b/apps/desktop/electron/notification-types.ts @@ -0,0 +1,19 @@ +export interface HermesNotification { + title?: string + body?: string + silent?: boolean + kind?: string + sessionId?: string + /** Durable click target captured before runtime bindings can be recycled. */ + focusSessionId?: string + /** Dedupe discriminator for session-less notifications (e.g. plugin id). */ + tag?: string + /** Absolute icon path for Electron `Notification`. */ + icon?: string + /** Resolved hash-router path opened on body click (plugin / deeplink-compatible). */ + activate?: string + /** Renderer handle for onActivate / onAction callbacks. */ + notifyId?: string + actions?: { id: string; text: string; activate?: string }[] +} + diff --git a/apps/desktop/src/global.d.ts b/apps/desktop/src/global.d.ts index d7705d6ede..08f516fd6e 100644 --- a/apps/desktop/src/global.d.ts +++ b/apps/desktop/src/global.d.ts @@ -1,6 +1,7 @@ import type { GatewayWsUrlResult } from '@hermes/shared' import type { TranslucencyState } from '@hermes/shared/translucency' +import type { HermesNotification } from '../electron/notification-types' import type { PoolLimits } from '../electron/pool-limits' import type { WakeIndicatorState } from './lib/wake-indicator' @@ -1238,25 +1239,6 @@ export interface HermesApiRequest { connectionId?: string | null } -export interface HermesNotification { - title?: string - body?: string - silent?: boolean - kind?: string - sessionId?: string - /** Durable click target captured before runtime bindings can be recycled. */ - focusSessionId?: string - /** Dedupe discriminator for session-less notifications (e.g. plugin id). */ - tag?: string - /** Absolute icon path for Electron `Notification`. */ - icon?: string - /** Resolved hash-router path opened on body click (plugin / deeplink-compatible). */ - activate?: string - /** Renderer handle for onActivate / onAction callbacks. */ - notifyId?: string - actions?: { id: string; text: string; activate?: string }[] -} - export interface HermesPreviewTarget { binary?: boolean byteSize?: number