chore: upgrade Electron to 44.5.1 and adapt clipboard APIs

This commit is contained in:
mesalogo
2026-10-02 17:53:42 +08:00
parent 90ea33ef5c
commit d773f5e961
8 changed files with 62 additions and 19 deletions
@@ -148,7 +148,7 @@ async function main() {
[
'appId: live.digiman.goodbuddy.harness-smoke',
'productName: GoodBuddyHarnessSmoke',
'electronVersion: "43.2.0"',
`electronVersion: "${require('electron/package.json').version}"`,
'asar: true',
'npmRebuild: false',
'files:',
+1 -1
View File
@@ -10,7 +10,7 @@ Debian `loong64` 桌面,不代表 GoodBuddy 已将龙芯纳入正式发布支
均为 LoongArch ELF。
预览版使用社区维护的 Electron 42.3.0 LoongArch 构建。GoodBuddy 正式版本
当前使用 Electron 43.2.0,因此该预览包只用于移植和真机验证,不能作为正式
当前使用 Electron 44.5.1,因此该预览包只用于移植和真机验证,不能作为正式
发布基线。Electron 官方目前也不提供 Linux LoongArch 预编译包。
已完成的实际构建结果:
+4 -4
View File
@@ -84,7 +84,7 @@
"@xterm/addon-search": "0.16.0",
"@xterm/addon-webgl": "0.19.0",
"@xterm/xterm": "6.0.0",
"electron": "^43.2.0",
"electron": "^44.5.1",
"electron-builder": "^26.15.3",
"electron-vite": "^5.0.0",
"esbuild": "0.25.12",
@@ -14755,9 +14755,9 @@
}
},
"node_modules/electron": {
"version": "43.2.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-43.2.0.tgz",
"integrity": "sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==",
"version": "44.5.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-44.5.1.tgz",
"integrity": "sha512-lx7AYoFIiyvEvgvpyWO9kOC60xtNPpiPZAth6Fmg9NutzpCAMLwpUlaBY2EXfZyIgUdzEmLMj9KvK0Vrokl1yQ==",
"dev": true,
"license": "MIT",
"dependencies": {
+1 -1
View File
@@ -385,7 +385,7 @@
"@xterm/addon-search": "0.16.0",
"@xterm/addon-webgl": "0.19.0",
"@xterm/xterm": "6.0.0",
"electron": "^43.2.0",
"electron": "^44.5.1",
"electron-builder": "^26.15.3",
"electron-vite": "^5.0.0",
"esbuild": "0.25.12",
+40 -1
View File
@@ -4,13 +4,16 @@ import { basename, join } from 'node:path'
import { strToU8, zipSync } from 'fflate'
import { afterEach, describe, expect, it, vi } from 'vitest'
const { createFromBuffer, getSources, showOpenDialog } = vi.hoisted(() => ({
const { createFromBuffer, getSources, showOpenDialog, readText, readClipboard } = vi.hoisted(() => ({
readText: vi.fn(),
readClipboard: vi.fn(),
createFromBuffer: vi.fn(),
getSources: vi.fn(),
showOpenDialog: vi.fn()
}))
vi.mock('electron', () => ({
clipboard: { readText, read: readClipboard },
desktopCapturer: {
getSources
},
@@ -31,6 +34,8 @@ import { defaultDocumentParsingSettings } from './document-parsing-settings-stor
const temporaryDirectories: string[] = []
afterEach(async () => {
readText.mockReset()
readClipboard.mockReset()
getSources.mockReset()
showOpenDialog.mockReset()
createFromBuffer.mockReset()
@@ -42,6 +47,40 @@ afterEach(async () => {
})
describe('ContextManager', () => {
it('awaits clipboard text and prefers it over images', async () => {
readText.mockResolvedValue(' clipboard text ')
const manager = new ContextManager()
const attachment = await manager.readClipboard()
expect(attachment.kind).toBe('text')
expect(attachment.preview).toContain('clipboard text')
expect(readClipboard).not.toHaveBeenCalled()
})
it('decodes an asynchronous clipboard PNG when text is empty', async () => {
readText.mockResolvedValue('')
const data = Buffer.from([0x89, 0x50, 0x4e, 0x47])
const getType = vi.fn().mockResolvedValue(new Blob([data]))
readClipboard.mockResolvedValue([{ types: ['image/png'], getType }])
const image = {
isEmpty: () => false,
getSize: () => ({ width: 640, height: 480 }),
resize: vi.fn(),
toJPEG: () => Buffer.from([0xff, 0xd8, 0xff, 0xd9])
}
image.resize.mockReturnValue(image)
createFromBuffer.mockReturnValue(image)
const attachment = await new ContextManager().readClipboard()
expect(getType).toHaveBeenCalledWith('image/png')
expect(createFromBuffer).toHaveBeenCalledWith(data)
expect(attachment.kind).toBe('image')
})
it('rejects a clipboard without text or a supported image', async () => {
readText.mockResolvedValue('')
readClipboard.mockResolvedValue([{ types: ['text/html'] }])
await expect(new ContextManager().readClipboard()).rejects.toThrow('剪贴板中没有可用的文本或图片')
})
it('preserves logical attachment identity and frozen message bytes across a draft reparse', async () => {
const directory = await mkdtemp(join(tmpdir(), 'goodbuddy-reparse-'))
temporaryDirectories.push(directory)
+9 -5
View File
@@ -568,14 +568,18 @@ export class ContextManager {
)
}
readClipboard(): ContextAttachment {
const text = clipboard.readText().trim()
async readClipboard(): Promise<ContextAttachment> {
const text = (await clipboard.readText()).trim()
if (text) {
return this.storeText('剪贴板文本.txt', text)
}
const image = clipboard.readImage()
if (!image.isEmpty()) {
return this.storeImage('剪贴板图片.png', image)
for (const item of await clipboard.read()) {
if (!item.types.includes('image/png')) continue
const blob = await item.getType('image/png')
const image = nativeImage.createFromBuffer(Buffer.from(await blob.arrayBuffer()))
if (!image.isEmpty()) {
return this.storeImage('剪贴板图片.png', image)
}
}
throw new Error('剪贴板中没有可用的文本或图片')
}
+4 -4
View File
@@ -264,9 +264,9 @@ describe('terminal IPC boundary', () => {
snapshot.sessionId
)
expect(
await expect(
electronMocks.handlers.get(ipcChannels.clipboardReadText)?.(event)
).toBe('Get-Location\r')
).resolves.toBe('Get-Location\r')
expect(electronMocks.readClipboardText).toHaveBeenCalledOnce()
electronMocks.handlers.get(ipcChannels.clipboardWriteText)?.(
@@ -353,8 +353,8 @@ const electronMocks = vi.hoisted(() => {
openPath: vi.fn(async () => ''),
showItemInFolder: vi.fn(),
openExternal: vi.fn(async () => undefined),
readClipboardText: vi.fn(() => 'Get-Location\r'),
writeClipboardText: vi.fn()
readClipboardText: vi.fn(async () => 'Get-Location\r'),
writeClipboardText: vi.fn(async () => {})
}
})
+2 -2
View File
@@ -10,12 +10,12 @@ export function registerClipboardIpcHandlers(
): void {
registerHandler(ipcChannels.clipboardReadText, (event) => {
assertTrustedSender(event, window)
return clipboardTextSchema.parse(clipboard.readText())
return clipboard.readText().then((text) => clipboardTextSchema.parse(text))
})
registerHandler(ipcChannels.clipboardWriteText, (event, input) => {
assertTrustedSender(event, window)
clipboard.writeText(clipboardTextSchema.parse(input))
return clipboard.writeText(clipboardTextSchema.parse(input))
})
}