feat: add structured agent tools and improve workspace chat UX

This commit is contained in:
2026-10-19 11:30:23 +09:00
parent 098af30fa7
commit cc589fd8cf
35 changed files with 2831 additions and 247 deletions
+38
View File
@@ -0,0 +1,38 @@
import { BrowserWindow, clipboard, Menu } from 'electron'
import type { IpcMainInvokeEvent, MenuItemConstructorOptions } from 'electron'
import type { ChatTextMenuAction, ChatTextMenuOptions } from '../shared/chatTextMenu'
export function showChatTextMenu(event: IpcMainInvokeEvent, input: ChatTextMenuOptions): Promise<ChatTextMenuAction> | null {
if (!input || !['message', 'input'].includes(input.kind) || event.sender.isDestroyed() || event.senderFrame !== event.sender.mainFrame) return null
const window = BrowserWindow.fromWebContents(event.sender)
if (!window || window.isDestroyed()) return null
const label = (value: unknown, fallback: string): string => typeof value === 'string' && value.trim() ? value.slice(0, 80) : fallback
return new Promise((resolve) => {
const items: MenuItemConstructorOptions[] = [{
label: label(input.labels?.copy, 'Copy'),
enabled: input.canCopy === true,
click: () => {
if (!event.sender.isDestroyed() && input.canCopy === true) event.sender.copy()
resolve(null)
}
}]
if (input.kind === 'input') {
items.push({
label: label(input.labels?.paste, 'Paste'),
enabled: input.canPaste === true && clipboard.readText().length > 0,
click: () => {
if (!event.sender.isDestroyed() && input.canPaste === true && clipboard.readText().length > 0) event.sender.paste()
resolve(null)
}
})
} else if (input.canClear !== undefined) {
items.push({ type: 'separator' }, {
label: label(input.labels?.clear, 'Delete conversation'),
enabled: input.canClear === true,
click: () => resolve(input.canClear === true ? 'clear' : null)
})
}
Menu.buildFromTemplate(items).popup({ window, callback: () => resolve(null) })
})
}