Repository navigation
Description
Parent: #10107. Depends on / pairs with: 01 (compile-time Solid JSX).
Problem
At TUI startup OpenCode runs ensureRuntimePluginSupport() (packages/opencode/src/plugin/tui/runtime.ts:44). That code does import { plugin as registerBunPlugin } from "bun" (node_modules/@opentui/solid/scripts/runtime-plugin-support-configure.js:1 and scripts/solid-plugin.js:1) and calls registerBunPlugin(createSolidTransformPlugin()) and registerBunPlugin(createRuntimePlugin(...)) (the @opentui/core/runtime-plugin specifier rewriter for user TUI plugins). Bun's plugin(p) invokes p.setup(build) synchronously; the plugin registers build.onLoad(...) loaders and records state.installed = true on globalThis[Symbol.for("opentui.solid.transform")].
Perry's bun module exposes stringWidth, file, write, stdin, hash, semver, JSONL, deepEquals, stripANSI, wrapAnsi, which, zstdDecompress*, gc, generateHeapSnapshot, Glob, pathToFileURL, fileURLToPath, TOML, YAML, spawn, … (crates/perry-hir/src/lower/expr_member.rs:340-360, crates/perry-runtime/src/bun_compat/) but no plugin; the member falls to js_bun_unsupported and the TUI dies before its first frame.
Scope
- Add
plugin(p)to thebunmodule andBun.plugin: accept{ name, setup }(object) or a function; callsetup(build)synchronously with an inertbuildobject (onLoad,onResolve,onStart,onEnd,config,moduleare accepted and ignored); returnundefined(or a resolved promise ifsetupreturns one), matching Bun's shape. Also acceptBun.plugin.clearAll()as a no-op. - Leave a diagnostic hook: when a later dynamic import would have needed a registered loader (a
.tsx/.jsxuser plugin), the deferred-import error should say the file type needs a runtime transform that the native build does not include (ties to decision DECISION: runtime-loaded JavaScript in the native OpenCode build — plugins, custom tools, non-bundled providers, TUI plugins #10105). - Keep
typeof Bun === "undefined"semantics for bundles that feature-detect Bun (member-position-only lowering, see bun-compat: Bun globals + "bun" module shim pack (Bun.stringWidth, Bun.file/write, Bun.stdin.text, Bun.hash) #6560).
Acceptance
-
import { plugin } from "bun"; plugin({ name: "x", setup(b) { b.onLoad({ filter: /a/ }, () => ({})); } })compiles and returns without throwing;Bun.plugin(fn)likewise. -
ensureRuntimePluginSupport()from@opentui/solid/runtime-plugin-support/configurereturnstrueunder perry and a second call returnsfalse(installed-state bookkeeping works). - The OpenCode TUI proceeds past
src/plugin/tui/runtime.tsmodule init in the native binary. - API manifest / docs drift gate updated (
--print-api-manifest).
Activity
proggeramlug commentedon Sep 12, 2026
Fixed by #10130, landed on
mainvia merge train #10139 at5fbd9e527f.The close keyword does not fire through a train branch, so closing manually.