IPC Communication
Relevant source files
The following files were used as context for generating this wiki page:
IPC (Inter-Process Communication) in Open Claude Cowork facilitates the secure exchange of data between the Electron Frontend (Renderer Process) and the Backend Server. While traditional Electron IPC typically involves ipcMain and ipcRenderer, this project primarily utilizes a preload.js bridge to manage HTTP requests and Server-Sent Events (SSE) between the UI and a Node.js Express server running on localhost:3001.
The architecture separates the desktop shell from the AI processing logic, ensuring that the heavy lifting of provider SDK management (Claude and Opencode) and tool routing remains in the backend while the frontend handles real-time markdown rendering and user interaction.
Sources: README.md:144-162, preload.js:3
Communication Architecture
The system utilizes a three-tier communication model:
- Renderer Process: Executes the frontend UI logic and handles user input.
- Preload Script: Acts as a security bridge, exposing a restricted
electronAPIto the renderer. - Backend Server: An Express.js instance that processes AI requests, manages sessions, and communicates with external tool providers.
High-Level Data Flow
The following diagram illustrates how a user message moves from the UI through the secure bridge to the backend server.
The application uses HTTP for initial requests and Server-Sent Events (SSE) for real-time, token-by-token response streaming.
Sources: README.md:144-162, preload.js:46-95
The Electron API Bridge
The preload.js script uses contextBridge to expose specific functions to the window.electronAPI object in the renderer process. This setup ensures that the renderer does not have direct access to Node.js primitives or the full ipcRenderer module, adhering to Electron security best practices.
Exposed Methods
| Method | Description | Parameters |
|---|---|---|
sendMessage | Initiates a chat request to the backend. | message, chatId, provider, model |
stopQuery | Signals the backend to abort an active query. | chatId, provider |
abortCurrentRequest | Cancels the client-side fetch request using an AbortController. | None |
getProviders | Retrieves a list of available AI providers from the server. | None |
Sources: preload.js:10-104, renderer/renderer.js:770-798
Streaming and Response Handling
Communication for AI responses is implemented via a streaming fetch. The preload script manages an AbortController to handle request cancellation, while the renderer uses a ReadableStream reader to process incoming data chunks.
Request Sequence
This sequence diagram shows the lifecycle of a chat message, including the initiation of the stream and the handling of Server-Sent Events.
The backend sends normalized chunks with a data: prefix, which the frontend parses to update chat bubbles or trigger tool call visualizations.
Sources: preload.js:46-95, renderer/renderer.js:804-945, server/server.js:85-115
Abort and Termination Logic
Reliable communication includes the ability to terminate long-running AI generations. The system implements a two-stage abort mechanism.
- Client-Side Abort: The
preload.jsscript callsabort()on thecurrentAbortController. This immediately closes the fetch connection in the renderer. - Server-Side Abort: The renderer calls
electronAPI.stopQuery(), which sends a POST request to/api/abort. The backend then identifies the active session and triggers the specific provider's abort method.
// From preload.js: Signal the backend to stop
stopQuery: async (chatId, provider = 'claude') => {
const response = await fetch(`${SERVER_URL}/api/abort`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ chatId, provider })
});
return await response.json();
}
Sources: preload.js:12-32, server/server.js:175-201, server/providers/opencode-provider.js:29-39
Provider-Specific Communication
The backend server acts as a proxy between the IPC bridge and the AI SDKs. For the Opencode Provider, the system handles an internal event loop to translate SDK events into SSE chunks compatible with the IPC bridge.
- Session Management: The backend maintains a mapping of
chatId(from IPC) tosessionId(from AI Provider). - Event Normalization: Events like
message.part.updatedfrom the Opencode SDK are captured and reformatted into the standardized JSON structure expected by therenderer.jsstreaming handler.
Sources: server/providers/opencode-provider.js:120-220, server/server.js:141-165
Summary
The IPC communication in Open Claude Cowork is a robust bridge designed for high-concurrency AI interactions. By utilizing a secure preload layer and SSE streaming, the application ensures real-time UI updates while maintaining a clean separation between the Electron desktop shell and the Node.js AI orchestration backend. This architecture allows the app to support complex features like tool call visualization and extended thinking modes across different AI providers through a unified communication interface.