Files
Maestro/src/renderer/services/process.ts
Antonio Carlos Carvalho de Oliveira 7ba47d2880 feat(opencode): enable real-time streaming and tool execution events
Enable real-time streaming for OpenCode agent responses instead of
buffering until completion. Also emit tool execution events so the UI
can display what tools the agent is using.

Changes:
- process-manager.ts: Emit 'data' event immediately for partial text
  (was only accumulating in streamedText buffer)
- process-manager.ts: Emit 'tool-execution' event for tool_use events
- index.ts: Forward tool-execution events to renderer via IPC
- preload.ts: Add onToolExecution handler for IPC bridge
- process.ts: Add onToolExecution service method
- global.d.ts: Add type definition for onToolExecution

This provides consistent UX with Claude Code and Codex agents which
already have streaming enabled, and enables future UI components to
display tool execution status.

Fixes #58
2025-12-22 19:37:10 -06:00

102 lines
2.6 KiB
TypeScript

/**
* Process management service
* Wraps IPC calls to main process for process operations
*/
import { createIpcMethod } from './ipcWrapper';
import type { ProcessConfig } from '../types';
export type { ProcessConfig } from '../types';
export interface ProcessDataHandler {
(sessionId: string, data: string): void;
}
export interface ProcessExitHandler {
(sessionId: string, code: number): void;
}
export interface ProcessSessionIdHandler {
(sessionId: string, agentSessionId: string): void;
}
export const processService = {
/**
* Spawn a new process
*/
spawn: (config: ProcessConfig): Promise<{ pid: number; success: boolean }> =>
createIpcMethod({
call: () => window.maestro.process.spawn(config),
errorContext: 'Process spawn',
rethrow: true,
}),
/**
* Write data to process stdin
*/
write: (sessionId: string, data: string): Promise<boolean> =>
createIpcMethod({
call: () => window.maestro.process.write(sessionId, data),
errorContext: 'Process write',
rethrow: true,
}),
/**
* Interrupt a process (send SIGINT/Ctrl+C)
*/
interrupt: (sessionId: string): Promise<boolean> =>
createIpcMethod({
call: () => window.maestro.process.interrupt(sessionId),
errorContext: 'Process interrupt',
rethrow: true,
}),
/**
* Kill a process
*/
kill: (sessionId: string): Promise<boolean> =>
createIpcMethod({
call: () => window.maestro.process.kill(sessionId),
errorContext: 'Process kill',
rethrow: true,
}),
/**
* Resize PTY terminal
*/
resize: (sessionId: string, cols: number, rows: number): Promise<boolean> =>
createIpcMethod({
call: () => window.maestro.process.resize(sessionId, cols, rows),
errorContext: 'Process resize',
rethrow: true,
}),
/**
* Register handler for process data events
*/
onData(handler: ProcessDataHandler): () => void {
return window.maestro.process.onData(handler);
},
/**
* Register handler for process exit events
*/
onExit(handler: ProcessExitHandler): () => void {
return window.maestro.process.onExit(handler);
},
/**
* Register handler for session-id events (batch mode)
*/
onSessionId(handler: ProcessSessionIdHandler): () => void {
return window.maestro.process.onSessionId(handler);
},
/**
* Register handler for tool execution events (OpenCode, Codex)
*/
onToolExecution(handler: (sessionId: string, toolEvent: { toolName: string; state?: unknown; timestamp: number }) => void): () => void {
return window.maestro.process.onToolExecution(handler);
}
};