Summary
The OpenCode desktop app (1.18.15) loads plugins inside an Electron utilityProcess (Node runtime). The CLI is a Bun binary. The Node plugin host has a Bun-compatible shim for the $ shell but no bun:sqlite module — so any plugin with a runtime bun: import fails to load, and the failure is completely silent.
Repro
~/.opencode/opencode.json:
{ "plugin": [".opencode/plugins/worktree.ts"] }
worktree.ts imports ./worktree/state, and worktree/state.ts:11 does import { Database } from "bun:sqlite" (value import).
Restart the desktop app. The plugin entry appears in the plugins list (the count increments), but its tools never register and no error is visible.
Evidence
- Every successfully imported plugin emits a
MODULE_TYPELESS_PACKAGE_JSON warning to server.log. worktree.ts does not — its module graph is never evaluated (verified in ~/.config/ai.opencode.desktop/logs/<ts>/server.log).
- No plugin error in
server.log, renderer.log, main.log, or opencode.log.
- Root cause of the silence: load failures call
publishPluginError in packages/opencode/src/plugin/index.ts, which only emits a Session.Event.Error. The desktop renderer does not consume that event, so nothing is shown or logged.
- The same plugin works under the CLI (
~/.opencode/bin/opencode, Bun) where bun:sqlite is native.
- Loaded-plugin comparison:
rtk.ts (type-only import, loads), graphify.js (Node builtins only, loads), worktree.ts (bun:sqlite value import, does not).
Impact
Any bun:sqlite-based plugin — e.g. the kdco/worktree OCX plugin — cannot run in the desktop app. Node 20 (Electron 30) has no node:sqlite either.
Suggested fixes
- Surface load failures (bug): log the error (stderr / server log) and/or surface it in the desktop UI so users see why a plugin did not load. Today it is invisible.
- Provide
bun:sqlite in the Node host: a shim implementing the API subset plugins use (new Database(path), exec, prepare().get/all/run, close, PRAGMA) backed by sql.js/WASM, or run plugins under a bundled Bun runtime.
Summary
The OpenCode desktop app (1.18.15) loads plugins inside an Electron
utilityProcess(Node runtime). The CLI is a Bun binary. The Node plugin host has a Bun-compatible shim for the$shell but nobun:sqlitemodule — so any plugin with a runtimebun:import fails to load, and the failure is completely silent.Repro
~/.opencode/opencode.json:{ "plugin": [".opencode/plugins/worktree.ts"] }worktree.tsimports./worktree/state, andworktree/state.ts:11doesimport { Database } from "bun:sqlite"(value import).Restart the desktop app. The plugin entry appears in the plugins list (the count increments), but its tools never register and no error is visible.
Evidence
MODULE_TYPELESS_PACKAGE_JSONwarning toserver.log.worktree.tsdoes not — its module graph is never evaluated (verified in~/.config/ai.opencode.desktop/logs/<ts>/server.log).server.log,renderer.log,main.log, oropencode.log.publishPluginErrorinpackages/opencode/src/plugin/index.ts, which only emits aSession.Event.Error. The desktop renderer does not consume that event, so nothing is shown or logged.~/.opencode/bin/opencode, Bun) wherebun:sqliteis native.rtk.ts(type-only import, loads),graphify.js(Node builtins only, loads),worktree.ts(bun:sqlitevalue import, does not).Impact
Any
bun:sqlite-based plugin — e.g. the kdco/worktree OCX plugin — cannot run in the desktop app. Node 20 (Electron 30) has nonode:sqliteeither.Suggested fixes
bun:sqlitein the Node host: a shim implementing the API subset plugins use (new Database(path),exec,prepare().get/all/run,close, PRAGMA) backed by sql.js/WASM, or run plugins under a bundled Bun runtime.