From 29eb5660595135d3e38c7e56845a1c9331424d5d Mon Sep 17 00:00:00 2001 From: Rick Ye Date: Mon, 7 Sep 2026 12:02:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B5=8F=E8=A7=88=E5=99=A8=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=99=A8=E6=8E=A8=E8=BF=9F=E5=88=B0=20app=20ready=20?= =?UTF-8?q?=E5=90=8E=E6=9E=84=E9=80=A0=EF=BC=9Bpnpm=20=E6=94=BE=E8=A1=8C?= =?UTF-8?q?=20electron=20postinstall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/pnpm-workspace.yaml | 6 +++++ apps/desktop/src/main/ipc.ts | 38 +++++++++++++++++--------------- 2 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 apps/desktop/pnpm-workspace.yaml diff --git a/apps/desktop/pnpm-workspace.yaml b/apps/desktop/pnpm-workspace.yaml new file mode 100644 index 0000000..9d41469 --- /dev/null +++ b/apps/desktop/pnpm-workspace.yaml @@ -0,0 +1,6 @@ +onlyBuiltDependencies: + - '@google/genai' + - electron + - electron-winstaller + - esbuild + - protobufjs diff --git a/apps/desktop/src/main/ipc.ts b/apps/desktop/src/main/ipc.ts index 466dc39..5cebabc 100644 --- a/apps/desktop/src/main/ipc.ts +++ b/apps/desktop/src/main/ipc.ts @@ -1,4 +1,4 @@ -import { BrowserWindow, dialog, ipcMain, shell } from 'electron' +import { app, BrowserWindow, dialog, ipcMain, shell } from 'electron' import { mkdirSync } from 'node:fs' import { userInfo } from 'node:os' import { AgentService } from './pi/agent-service' @@ -260,12 +260,14 @@ export function registerIpc(): AgentService { }) // ---- 内置受管浏览器 ---- - const browser = getBrowserController() - // 面板状态广播(与 agent:event 同样转发到所有窗口) - browser.onState((state) => { - for (const win of BrowserWindow.getAllWindows()) { - if (!win.isDestroyed()) win.webContents.send('browser:event', { type: 'state', state }) - } + // 控制器构造会调 session.fromPartition,必须等 app ready; + // IPC 处理器在渲染层就绪后才可能被调用,惰性取用是安全的 + void app.whenReady().then(() => { + getBrowserController().onState((state) => { + for (const win of BrowserWindow.getAllWindows()) { + if (!win.isDestroyed()) win.webContents.send('browser:event', { type: 'state', state }) + } + }) }) const browserPass = (fn: () => T): T => { @@ -276,24 +278,24 @@ export function registerIpc(): AgentService { } } - ipcMain.handle('browser:getState', () => browser.getState()) + ipcMain.handle('browser:getState', () => browserPass(() => getBrowserController().getState())) ipcMain.handle('browser:navigate', (_e, input: unknown) => - browserPass(() => browser.navigateDisplay(typeof input === 'string' ? input : '')) + browserPass(() => getBrowserController().navigateDisplay(typeof input === 'string' ? input : '')) ) - ipcMain.handle('browser:goBack', () => browserPass(() => browser.goBack())) - ipcMain.handle('browser:goForward', () => browserPass(() => browser.goForward())) - ipcMain.handle('browser:reload', () => browserPass(() => browser.reload())) + ipcMain.handle('browser:goBack', () => browserPass(() => getBrowserController().goBack())) + ipcMain.handle('browser:goForward', () => browserPass(() => getBrowserController().goForward())) + ipcMain.handle('browser:reload', () => browserPass(() => getBrowserController().reload())) ipcMain.handle('browser:newTab', (_e, url: unknown) => - browserPass(() => browser.newTab(typeof url === 'string' && url ? url : undefined, false)) + browserPass(() => getBrowserController().newTab(typeof url === 'string' && url ? url : undefined, false)) ) ipcMain.handle('browser:selectTab', (_e, tabId: unknown) => - browserPass(() => browser.selectTab(typeof tabId === 'string' ? tabId : '')) + browserPass(() => getBrowserController().selectTab(typeof tabId === 'string' ? tabId : '')) ) ipcMain.handle('browser:closeTab', (_e, tabId: unknown) => - browserPass(() => browser.closeTab(typeof tabId === 'string' ? tabId : undefined)) + browserPass(() => getBrowserController().closeTab(typeof tabId === 'string' ? tabId : undefined)) ) - ipcMain.handle('browser:close', () => browserPass(() => browser.close())) - ipcMain.handle('browser:acknowledgeRisk', () => browserPass(() => browser.acknowledgeRisk())) + ipcMain.handle('browser:close', () => browserPass(() => getBrowserController().close())) + ipcMain.handle('browser:acknowledgeRisk', () => browserPass(() => getBrowserController().acknowledgeRisk())) // 渲染层 BrowserSlot 量出的占位矩形(原生 WebContentsView 对齐到 DOM 布局) ipcMain.handle('browser:layout', (_e, layout: unknown) => { const l = layout as { tabId?: unknown; visible?: unknown; revision?: unknown; bounds?: unknown } @@ -314,7 +316,7 @@ export function registerIpc(): AgentService { ) { throw new Error('invalid browser layout') } - return browserPass(() => browser.applyLayout({ tabId, visible, revision, bounds: { x, y, width, height } })) + return browserPass(() => getBrowserController().applyLayout({ tabId, visible, revision, bounds: { x, y, width, height } })) }) // ---- 本地浏览器配置导入 ----