Development
Set up the Coodeen dev environment and contribute.
Prerequisites
- Bun — primary package manager and runtime for scripts
- Node.js 18+ — used by the build scripts
- Git
Setup
git clone https://github.com/zahinafsar/coodeen.git
cd coodeen
# Install + rebuild native modules for Electron
bun run setupThe first desktop build also downloads the matching opencode binary into apps/desktop/resources/bin/ via scripts/fetch-opencode.js (hooked up as the prebuild script in apps/desktop/package.json).
Running Locally
# Electron dev mode (hot reload for renderer)
bun run devOn startup the app spawns opencode serve --hostname=127.0.0.1 --port=0 as a child and wires the renderer to it.
Type Check
bun run --cwd apps/desktop typecheckBuilding
# Unpacked build
bun run build
# Build + package installers for the current platform
bun run --cwd apps/desktop build:prodbuild:prod runs electron-vite build, copies production deps (scripts/copy-modules.js), then invokes electron-builder with apps/desktop/electron-builder.yml. The opencode binary ships as extraResources so the packaged app can spawn it from process.resourcesPath/bin.
Pinning opencode
OPENCODE_VERSION=0.x.y bun run --cwd apps/desktop fetch-opencodeThe downloaded version is tracked in apps/desktop/resources/bin/.opencode-version.
Docs Site
bun run dev:docsRuns Next.js + Fumadocs from apps/docs/.
Project Structure
| Directory | Purpose |
|---|---|
apps/desktop | Electron app — main, preload, IPC handlers, React renderer |
apps/docs | Documentation site (Next.js + Fumadocs) |
scripts/ | fetch-opencode.js, copy-modules.js, rebuild-native.js |
Main-Process Handlers
Registered in apps/desktop/src/main.ts:
| File | What it does |
|---|---|
opencode.ts | Spawn + supervise sidecar, event bus, auto-reconnect |
sessions.ts | CRUD over opencode sessions + local session-prefs.json |
chat.ts | session.prompt / session.abort forwarding |
providers.ts | List providers, set / delete API keys, cache invalidation |
fs.ts | Directory listing, file read/write, create/delete entries |
git.ts | Status, branches, diff, commit, push, pull, merge, conflicts |
pty.ts | node-pty terminal sessions |
config.ts | Active provider + cwd |
actions.ts | coodeen.json discovery + script runner |
Screen Capture IPC
capture:area runs directly in main.ts: it calls mainWindow.webContents.capturePage({x, y, width, height}) and returns a PNG data-URL. The preview's element picker uses this to crop the iframe's on-screen rect.