import { ipcRenderer, contextBridge } from 'electron' // ============================================================================ // Type definitions for IPC API // ============================================================================ export interface HubStatus { hubId: string status: string agentCount: number gatewayConnected: boolean gatewayUrl?: string defaultAgent?: { agentId: string status: string } | null } export interface AgentInfo { agentId: string status: string } export interface ToolInfo { name: string group: string enabled: boolean } export interface SkillInfo { id: string name: string description: string version: string enabled: boolean source: 'bundled' | 'global' | 'profile' triggers: string[] } export interface ProfileData { profileId: string | undefined name: string | undefined style: string | undefined userContent: string | undefined } // Available style options export const AGENT_STYLES = ['concise', 'warm', 'playful', 'professional'] as const export type AgentStyle = (typeof AGENT_STYLES)[number] // ============================================================================ // Expose typed API to Renderer process // ============================================================================ const electronAPI = { // Hub management hub: { init: () => ipcRenderer.invoke('hub:init'), getStatus: (): Promise => ipcRenderer.invoke('hub:getStatus'), getAgentInfo: (): Promise => ipcRenderer.invoke('hub:getAgentInfo'), info: () => ipcRenderer.invoke('hub:info'), reconnect: (url: string) => ipcRenderer.invoke('hub:reconnect', url), listAgents: () => ipcRenderer.invoke('hub:listAgents'), createAgent: (id?: string) => ipcRenderer.invoke('hub:createAgent', id), getAgent: (id: string) => ipcRenderer.invoke('hub:getAgent', id), closeAgent: (id: string) => ipcRenderer.invoke('hub:closeAgent', id), sendMessage: (agentId: string, content: string) => ipcRenderer.invoke('hub:sendMessage', agentId, content), registerToken: (token: string, agentId: string, expiresAt: number) => ipcRenderer.invoke('hub:registerToken', token, agentId, expiresAt), onDeviceConfirmRequest: (callback: (deviceId: string, meta?: { userAgent?: string; platform?: string; language?: string }) => void) => { ipcRenderer.on('hub:device-confirm-request', (_event, deviceId: string, meta?: { userAgent?: string; platform?: string; language?: string }) => callback(deviceId, meta)) }, offDeviceConfirmRequest: () => { ipcRenderer.removeAllListeners('hub:device-confirm-request') }, deviceConfirmResponse: (deviceId: string, allowed: boolean) => { ipcRenderer.send('hub:device-confirm-response', deviceId, allowed) }, listDevices: () => ipcRenderer.invoke('hub:listDevices'), revokeDevice: (deviceId: string) => ipcRenderer.invoke('hub:revokeDevice', deviceId), }, // Tools management tools: { list: (): Promise => ipcRenderer.invoke('tools:list'), toggle: (name: string) => ipcRenderer.invoke('tools:toggle', name), setStatus: (name: string, enabled: boolean) => ipcRenderer.invoke('tools:setStatus', name, enabled), active: () => ipcRenderer.invoke('tools:active'), reload: () => ipcRenderer.invoke('tools:reload'), }, // Skills management skills: { list: (): Promise => ipcRenderer.invoke('skills:list'), get: (id: string) => ipcRenderer.invoke('skills:get', id), toggle: (id: string) => ipcRenderer.invoke('skills:toggle', id), setStatus: (id: string, enabled: boolean) => ipcRenderer.invoke('skills:setStatus', id, enabled), reload: () => ipcRenderer.invoke('skills:reload'), add: (source: string, options?: { name?: string; force?: boolean }) => ipcRenderer.invoke('skills:add', source, options), remove: (name: string) => ipcRenderer.invoke('skills:remove', name), }, // Agent management agent: { status: () => ipcRenderer.invoke('agent:status'), }, // Profile management profile: { get: (): Promise => ipcRenderer.invoke('profile:get'), updateName: (name: string) => ipcRenderer.invoke('profile:updateName', name), updateStyle: (style: string) => ipcRenderer.invoke('profile:updateStyle', style), updateUser: (content: string) => ipcRenderer.invoke('profile:updateUser', content), }, } // Expose to renderer contextBridge.exposeInMainWorld('electronAPI', electronAPI) // Also expose ipcRenderer for backward compatibility contextBridge.exposeInMainWorld('ipcRenderer', { on(...args: Parameters) { const [channel, listener] = args return ipcRenderer.on(channel, (event, ...args) => listener(event, ...args)) }, off(...args: Parameters) { const [channel, ...omit] = args return ipcRenderer.off(channel, ...omit) }, send(...args: Parameters) { const [channel, ...omit] = args return ipcRenderer.send(channel, ...omit) }, invoke(...args: Parameters) { const [channel, ...omit] = args return ipcRenderer.invoke(channel, ...omit) }, }) // Type declaration for window object export type ElectronAPI = typeof electronAPI