fix: 浏览器控制器推迟到 app ready 后构造;pnpm 放行 electron postinstall

This commit is contained in:
Rick Ye
2026-09-07 12:02:23 +08:00
parent eafbe8c15d
commit 29eb566059
2 changed files with 26 additions and 18 deletions
+6
View File
@@ -0,0 +1,6 @@
onlyBuiltDependencies:
- '@google/genai'
- electron
- electron-winstaller
- esbuild
- protobufjs
+20 -18
View File
@@ -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 = <T,>(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 } }))
})
// ---- 本地浏览器配置导入 ----