v0.6.0: beautifului 整合 + 会话/工作区/队列/权限/命令/附件全链路

- beautifului.dev 组件直连:Sidebar Nav、Tool Chips、Approval Card(抽屉化)、Streaming/Thinking、Code Block、Selection Actions、Prompt Bar、Search
This commit is contained in:
Rick Ye
2026-09-06 09:57:14 +08:00
parent 3c2e9e96c5
commit a5951849c8
96 changed files with 11828 additions and 4649 deletions
+78 -4
View File
@@ -1,4 +1,5 @@
import { BrowserWindow, ipcMain } from 'electron'
import { BrowserWindow, dialog, ipcMain } from 'electron'
import { userInfo } from 'node:os'
import { AgentService } from './pi/agent-service'
/**
@@ -16,11 +17,20 @@ export function registerIpc(): AgentService {
}
})
ipcMain.handle('agent:send', (_event, text: unknown) => {
ipcMain.handle('agent:send', (_event, text: unknown, images: unknown) => {
if (typeof text !== 'string' || !text.trim()) {
throw new Error('empty prompt')
}
return service.send(text)
const sendImages = Array.isArray(images)
? images.filter(
(img): img is { mimeType: string; data: string } =>
typeof img === 'object' &&
img !== null &&
typeof (img as { mimeType?: unknown }).mimeType === 'string' &&
typeof (img as { data?: unknown }).data === 'string'
)
: undefined
return service.send(text, sendImages)
})
ipcMain.handle('agent:steer', (_event, text: unknown) => {
@@ -105,6 +115,39 @@ export function registerIpc(): AgentService {
return pass(() => service.setSystemPrompt(text))
})
// ---- 工作区 ----
ipcMain.handle('workspaces:list', () =>
service.listWorkspaces().catch((err: unknown) => {
throw new Error(err instanceof Error ? err.message : String(err))
})
)
ipcMain.handle('workspaces:create', (_event, name: unknown) => {
if (typeof name !== 'string' || !name.trim()) throw new Error('invalid workspace name')
return service.createWorkspace(name).catch((err: unknown) => {
throw new Error(err instanceof Error ? err.message : String(err))
})
})
ipcMain.handle('workspaces:open', (_event, path: unknown) => {
if (typeof path !== 'string' || !path.trim()) throw new Error('invalid workspace path')
return service.openWorkspace(path).catch((err: unknown) => {
throw new Error(err instanceof Error ? err.message : String(err))
})
})
// 调起系统目录选择器;取消返回 null
ipcMain.handle('workspaces:browse', async () => {
const win = BrowserWindow.getFocusedWindow() ?? BrowserWindow.getAllWindows()[0]
const result = await dialog.showOpenDialog(win, {
title: '选择工作区目录',
defaultPath: service.workspacesRoot,
properties: ['openDirectory', 'createDirectory']
})
if (result.canceled || result.filePaths.length === 0) return null
return result.filePaths[0]
})
// ---- 工具审批 ----
ipcMain.handle('approval:resolve', (_event, id: unknown, approved: unknown) => {
if (typeof id !== 'string' || typeof approved !== 'boolean') throw new Error('invalid approval')
@@ -117,8 +160,39 @@ export function registerIpc(): AgentService {
app: process.env.npm_package_version ?? '0.0.0',
electron: process.versions.electron,
node: process.versions.node,
chrome: process.versions.chrome
chrome: process.versions.chrome,
user: userInfo().username
}))
// ---- Chatbox 资源(/ 命令 + 技能、@ 工作区文件、+ 附件)----
ipcMain.handle('chat:resources', () =>
service.listChatResources().catch((err: unknown) => {
throw new Error(err instanceof Error ? err.message : String(err))
})
)
ipcMain.handle('queue:set', (_event, steering: unknown, followUp: unknown) => {
const norm = (value: unknown): string[] =>
Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []
return service.setQueue(norm(steering), norm(followUp))
})
ipcMain.handle('permissions:set', (_event, mode: unknown) => {
const valid: ReadonlySet<string> = new Set(['confirm', 'autoEdit', 'plan', 'full'])
if (typeof mode !== 'string' || !valid.has(mode)) throw new Error('invalid permission mode')
service.setPermissionMode(mode as never)
})
ipcMain.handle('files:list', () =>
service.listWorkspaceFiles().catch((err: unknown) => {
throw new Error(err instanceof Error ? err.message : String(err))
})
)
ipcMain.handle('attachments:pick', async (event) => {
const win = BrowserWindow.fromWebContents(event.sender) ?? BrowserWindow.getAllWindows()[0]
return service.pickAttachments(win ?? undefined)
})
return service
}