IPC architecture
Feature-scoped IPC channels connect the preload bridge to main-process services using shared, typed channel names.
Every renderer-to-main call goes through a named IPC channel, defined once in src/shared/ipc-channels.ts and used by both sides — the main process registers a handler for it, and the preload bridge invokes it.
Organization
Channels are grouped by feature area, not registered ad hoc — for example workspace:open, workspace:list, workspace:rename, and workspace:delete all belong to workspace handling, while codex:modelCatalog:get and claude:modelCatalog:get belong to their respective agent's model-catalogue lookup. One handler module per feature area keeps a channel's registration next to the service logic it calls.
Request/response and events
Most channels follow a simple invoke/response pattern (ipcRenderer.invoke on one side, an ipcMain.handle on the other). Long-running or streaming data — agent conversation events, terminal output — instead uses event subscriptions the renderer can start and stop, rather than forcing a single request/response round-trip to carry a live stream.
No shortcuts from the renderer
The renderer never gets a generic ipcRenderer, filesystem, or Node global — only the specific, typed methods the preload bridge exposes, each mapping to exactly one main-process capability.