refactor: 命令执行走工作空间终端,AI 不再直接执行

流程改为:AI 提出命令 → 用户确认 → 工作空间终端执行(实时显示)→ 结果反馈 AI → AI 回复

- handleRunCommand 直接 spawn 子进程,stdout/stderr 实时通过 cmd:output 推送
- 进程结束后通过 cmd:done 通知渲染进程
- 停止按钮通过 cmd:kill 终止进程
- 清理 workspace.ts 中不再需要的 execWorkspaceCommand 工具集成代码
- 去掉 workspace:execTool/killTool,改为 cmd:output/cmd:done/cmd:kill
This commit is contained in:
thzxx
2026-04-08 13:12:18 +08:00
parent d5e5f5f58a
commit 0431ed56c0
7 changed files with 107 additions and 84 deletions
+11 -11
View File
@@ -59,17 +59,17 @@ contextBridge.exposeInMainWorld('metonaDesktop', {
onExit: (callback: (data: { id: string; code: number | null }) => void) => {
ipcRenderer.on('workspace:exit', (_: unknown, data: { id: string; code: number | null }) => callback(data));
},
/** 无超时命令执行,用于 AI Tool Calling */
execTool: (command: string, cwd?: string) => ipcRenderer.invoke('workspace:execTool', command, cwd),
/** 终止当前 AI 工具命令 */
killTool: () => ipcRenderer.invoke('workspace:killTool'),
/** AI Tool Calling 实时输出推送到工作空间终端 */
onToolOutput: (callback: (data: { command: string; type: 'stdout' | 'stderr'; data: string }) => void) => {
ipcRenderer.on('workspace:toolOutput', (_: unknown, data: { command: string; type: 'stdout' | 'stderr'; data: string }) => callback(data));
/** 无超时工具命令执行,用于 AI Tool Calling */
execTool: (command: string, cwd?: string) => ipcRenderer.invoke('tool:execute', 'run_command', { command, cwd }),
/** AI 命令实时输出推送到工作空间终端 */
onCmdOutput: (callback: (data: { command: string; type: 'stdout' | 'stderr'; data: string }) => void) => {
ipcRenderer.on('cmd:output', (_: unknown, data: { command: string; type: 'stdout' | 'stderr'; data: string }) => callback(data));
},
/** AI Tool Calling 命令执行完毕 */
onToolDone: (callback: (data: { command: string; exitCode: number | null }) => void) => {
ipcRenderer.on('workspace:toolDone', (_: unknown, data: { command: string; exitCode: number | null }) => callback(data));
}
/** AI 命令执行完毕 */
onCmdDone: (callback: (data: { command: string; exitCode: number | null }) => void) => {
ipcRenderer.on('cmd:done', (_: unknown, data: { command: string; exitCode: number | null }) => callback(data));
},
/** 终止当前 AI 命令 */
cmdKill: () => ipcRenderer.invoke('cmd:kill')
}
});