import Electron, { contextBridge, ipcRenderer, webUtils } from 'electron'; interface RecipeConfig { id: string; name: string; description: string; instructions?: string; activities?: string[]; [key: string]: unknown; } interface NotificationData { title: string; body: string; } interface FileResponse { file: string; filePath: string; error: string | null; found: boolean; } interface SaveDataUrlResponse { id: string; filePath?: string; error?: string; } const config = JSON.parse(process.argv.find((arg) => arg.startsWith('{')) || '{}'); // Define the API types in a single place type ElectronAPI = { platform: string; reactReady: () => void; getConfig: () => Record; hideWindow: () => void; directoryChooser: (replace?: boolean) => Promise; createChatWindow: ( query?: string, dir?: string, version?: string, resumeSessionId?: string, recipeConfig?: RecipeConfig, viewType?: string ) => void; logInfo: (txt: string) => void; showNotification: (data: NotificationData) => void; openInChrome: (url: string) => void; fetchMetadata: (url: string) => Promise; reloadApp: () => void; checkForOllama: () => Promise; selectFileOrDirectory: () => Promise; startPowerSaveBlocker: () => Promise; stopPowerSaveBlocker: () => Promise; getBinaryPath: (binaryName: string) => Promise; readFile: (directory: string) => Promise; writeFile: (directory: string, content: string) => Promise; getAllowedExtensions: () => Promise; getPathForFile: (file: File) => string; setMenuBarIcon: (show: boolean) => Promise; getMenuBarIconState: () => Promise; setDockIcon: (show: boolean) => Promise; getDockIconState: () => Promise; on: ( channel: string, callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void ) => void; off: ( channel: string, callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void ) => void; emit: (channel: string, ...args: unknown[]) => void; // Functions for image pasting saveDataUrlToTemp: (dataUrl: string, uniqueId: string) => Promise; deleteTempFile: (filePath: string) => void; // Function to serve temp images getTempImage: (filePath: string) => Promise; }; type AppConfigAPI = { get: (key: string) => unknown; getAll: () => Record; }; const electronAPI: ElectronAPI = { platform: process.platform, reactReady: () => ipcRenderer.send('react-ready'), getConfig: () => config, hideWindow: () => ipcRenderer.send('hide-window'), directoryChooser: (replace?: boolean) => ipcRenderer.invoke('directory-chooser', replace), createChatWindow: ( query?: string, dir?: string, version?: string, resumeSessionId?: string, recipeConfig?: RecipeConfig, viewType?: string ) => ipcRenderer.send( 'create-chat-window', query, dir, version, resumeSessionId, recipeConfig, viewType ), logInfo: (txt: string) => ipcRenderer.send('logInfo', txt), showNotification: (data: NotificationData) => ipcRenderer.send('notify', data), openInChrome: (url: string) => ipcRenderer.send('open-in-chrome', url), fetchMetadata: (url: string) => ipcRenderer.invoke('fetch-metadata', url), reloadApp: () => ipcRenderer.send('reload-app'), checkForOllama: () => ipcRenderer.invoke('check-ollama'), selectFileOrDirectory: () => ipcRenderer.invoke('select-file-or-directory'), startPowerSaveBlocker: () => ipcRenderer.invoke('start-power-save-blocker'), stopPowerSaveBlocker: () => ipcRenderer.invoke('stop-power-save-blocker'), getBinaryPath: (binaryName: string) => ipcRenderer.invoke('get-binary-path', binaryName), readFile: (filePath: string) => ipcRenderer.invoke('read-file', filePath), writeFile: (filePath: string, content: string) => ipcRenderer.invoke('write-file', filePath, content), getPathForFile: (file: File) => webUtils.getPathForFile(file), getAllowedExtensions: () => ipcRenderer.invoke('get-allowed-extensions'), setMenuBarIcon: (show: boolean) => ipcRenderer.invoke('set-menu-bar-icon', show), getMenuBarIconState: () => ipcRenderer.invoke('get-menu-bar-icon-state'), setDockIcon: (show: boolean) => ipcRenderer.invoke('set-dock-icon', show), getDockIconState: () => ipcRenderer.invoke('get-dock-icon-state'), on: ( channel: string, callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void ) => { ipcRenderer.on(channel, callback); }, off: ( channel: string, callback: (event: Electron.IpcRendererEvent, ...args: unknown[]) => void ) => { ipcRenderer.off(channel, callback); }, emit: (channel: string, ...args: unknown[]) => { ipcRenderer.emit(channel, ...args); }, saveDataUrlToTemp: (dataUrl: string, uniqueId: string): Promise => { return ipcRenderer.invoke('save-data-url-to-temp', dataUrl, uniqueId); }, deleteTempFile: (filePath: string): void => { ipcRenderer.send('delete-temp-file', filePath); }, getTempImage: (filePath: string): Promise => { return ipcRenderer.invoke('get-temp-image', filePath); }, }; const appConfigAPI: AppConfigAPI = { get: (key: string) => config[key], getAll: () => config, }; // Expose the APIs contextBridge.exposeInMainWorld('electron', electronAPI); contextBridge.exposeInMainWorld('appConfig', appConfigAPI); // Type declaration for TypeScript declare global { interface Window { electron: ElectronAPI; appConfig: AppConfigAPI; } }