Coodeen
Architecture

How Coodeen Works

Processes, data flow, and where state lives.

Overview

Coodeen is an Electron shell around the opencode agent. On launch the main process spawns opencode serve --hostname=127.0.0.1 --port=0 as a child and connects to it with @opencode-ai/sdk. The renderer (React + Tailwind + Radix) drives the split-pane UI.

Processes

  • Electron main — Supervises the opencode sidecar, registers IPC handlers for filesystem, git, terminal (node-pty), and opencode RPC.
  • Electron renderer — React UI: chat on the left; Preview / Files / Git tabs plus togglable terminal on the right.
  • opencode sidecar — Child process. Owns the agent, sessions, messages, tool execution, and provider auth.

Data Flow

  1. Renderer fires an IPC call (chat:prompt, sessions:list, fs:readFile, etc.).
  2. The matching handler in apps/desktop/src/handlers/ either runs locally (fs, git, pty) or forwards through the opencode SDK.
  3. opencode streams events (message.part.updated, tool call lifecycle, status) over /global/event (SSE).
  4. handlers/opencode.ts rebroadcasts each event on the opencode:event IPC channel.
  5. The renderer's chat store reduces events into the view model.

The event bus runs in a reconnect loop with a 15s heartbeat and exponential backoff (0.5s → 5s).

What's Stored Where

WhatLocation
Sessions, messages, tool historyopencode — ~/.local/share/opencode/
Provider API keysopencode — ~/.local/share/opencode/auth.json
Per-session preview URLElectron userData — session-prefs.json
Active provider selectionElectron userData — app-config.json

Electron userData paths:

PlatformLocation
macOS~/Library/Application Support/coodeen/
Windows%APPDATA%/coodeen/
Linux~/.config/coodeen/

Directory Scoping

Every opencode call is pinned to a specific project directory. Coodeen sets both x-opencode-directory (URL-encoded) as a header and directory as a query param, so POSTs and GETs both hit the right instance. Switching sessions switches the scope.

Open Source

Code on GitHub. Contributions welcome.