diff --git a/packages/electron/main.mjs b/packages/electron/main.mjs index 15b8aaff..d2b85e0e 100644 --- a/packages/electron/main.mjs +++ b/packages/electron/main.mjs @@ -1746,6 +1746,19 @@ const handleInvoke = async (browserWindow, command, args = {}) => { return null; } + case 'desktop_open_external_url': { + const target = typeof args.url === 'string' ? args.url.trim() : ''; + if (!target) throw new Error('URL is required'); + + const parsed = new URL(target); + if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') { + throw new Error('Only HTTP URLs can be opened externally'); + } + + await shell.openExternal(parsed.toString()); + return null; + } + case 'desktop_reveal_path': { const targetPath = typeof args.path === 'string' ? args.path.trim() : ''; if (!targetPath) { diff --git a/packages/electron/preload.mjs b/packages/electron/preload.mjs index 3259ec5f..2de3f085 100644 --- a/packages/electron/preload.mjs +++ b/packages/electron/preload.mjs @@ -137,6 +137,9 @@ contextBridge.exposeInMainWorld('__TAURI__', { dialog: { open: (options) => ipcRenderer.invoke('openchamber:dialog:open', options || {}), }, + shell: { + open: (url) => ipcRenderer.invoke('openchamber:invoke', 'desktop_open_external_url', { url }), + }, event: { listen: async (event, handler) => addListener(event, handler), },