OpenCode is the AI coding agent that executes tasks. It runs directly on the host machine, managed by the local sidecar (apps/sidecar) — no containers, no isolation overhead.
The OpenCode binary is bundled with the desktop app alongside the sidecar binary. When the sidecar starts, it spawns the OpenCode server process and communicates with it via the @opencode-ai/sdk client. The cloud API (apps/api) has no involvement in OpenCode management.
The sidecar resolves the OpenCode binary using this priority:
OPENCODE_BINenvironment variable (explicit override)- Bundled sibling binary next to
process.execPathwith Tauri target-triple naming (e.g.,opencode-x86_64-unknown-linux-gnu) - Fallback to
opencodein system PATH (dev mode)
On sidecar startup:
- Resolve the OpenCode binary path
- Spawn the OpenCode server process
- Wait for the server to become healthy
- Create an SDK client connected to the server
On sidecar shutdown, the OpenCode process is gracefully terminated.
OpenLinear uses @opencode-ai/sdk which provides:
createOpencodeClient()-- creates a client for a running OpenCode serverOpencodeClient-- type for session management, event subscription, provider configuration
Note: The SDK's createOpencodeServer() is not used because it hardcodes spawn("opencode", ...) which can't find the bundled sidecar binary. OpenLinear uses a custom spawnOpencodeServer() that accepts a resolved binary path.
For each task execution:
client.session.create({ title, directory })-- creates a new agent sessionclient.session.prompt({ parts: [{ type: 'text', text }] })-- sends the task as a promptclient.session.abort()-- cancels the session on user cancel or timeout
client.event.subscribe() returns an async iterable stream. Events handled:
| Event | Action |
|---|---|
session.completed / session.idle |
Agent finished -- commit and PR |
session.error |
Execution failed |
session.status (busy) |
Mark agent as thinking |
session.status (retry) |
Log retry reason |
message.part.updated (text) |
Accumulate agent text deltas |
message.part.updated (tool) |
Log tool start/complete/error |
message.part.updated (reasoning) |
Accumulate reasoning deltas |
tool.execute.before |
Log tool starting |
tool.execute.after |
Log tool finished, increment counter |
file.edited |
Log file edit, increment counter |
server.heartbeat |
Ignored |
Text and reasoning arrive as small character-by-character deltas. The delta buffer accumulates them and flushes complete messages to the log at sentence boundaries or after a timeout.
Users configure which LLM provider OpenCode uses through the provider auth API. Two methods are supported:
API Key: Set a provider's API key directly via POST /api/opencode/auth (sidecar route).
OAuth: Start an OAuth flow via POST /api/opencode/auth/oauth/authorize, then complete it with POST /api/opencode/auth/oauth/callback. Both are sidecar routes.
Provider credentials are stored in the OpenCode config directory on the host machine.
All /api/opencode/* endpoints are served by the local sidecar (apps/sidecar), not the cloud API. All endpoints except /status require authentication.
Returns the overall OpenCode system state (whether the sidecar is running and healthy).
Auth: required. List available LLM providers from the OpenCode instance.
Auth: required. Get the authentication status for each provider (which providers have credentials configured).
Auth: required. Set an API key for a provider.
Body: { "providerId": "anthropic", "apiKey": "sk-..." }
Response: { success: true, providerId: "anthropic" }
Auth: required. Start an OAuth authorization flow for a provider.
Body: { "providerId": "...", "method": 0 }
Returns the authorization URL and flow data.
Auth: required. Complete an OAuth authorization flow.
Body: { "providerId": "...", "code": "...", "method": 0 }
Returns the result of the OAuth token exchange.
OpenLinear does not configure which model OpenCode uses. That comes from OpenCode's own config files (stored in the host's OpenCode config directory, typically ~/.config/opencode).
| Variable | Description | Default |
|---|---|---|
OPENCODE_BIN |
Path to the OpenCode binary (overrides bundled sidecar) | -- |
OPENCODE_PORT |
OpenCode server port | 4096 |
OPENCODE_HOST |
OpenCode server host | 127.0.0.1 |