| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
npm-spec TUI plugins are installed into an isolated cache tree under node_modules, so they resolve their own copy of @opentui/solid and end up with a separate RendererContext singleton. As of OpenTUI 0.4.2 (dual bun/node entry files), that copy no longer matches the host's, so the plugin's slots and commands silently fail to attach to the host renderer. Enable nodeModulesBareSpecifiers rewriting so bare @opentui/* imports inside node_modules are bridged onto the host's registered runtime instances, the same behavior file:// plugins already get.
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
Sorry, something went wrong.
|
Closing this — it's both ineffective and redundant. Redundant: dev already reverted the OpenTUI 0.4.2 bump in #33842 (merged), so @opentui/solid is back to 0.3.4 (single-entry) where npm-spec TUI plugins load fine. The regression no longer exists on dev. Ineffective: I verified the nodeModulesBareSpecifiers: true change in this PR does not actually fix the bug against the real 0.4.2 packaging. With the flag on, importing the plugin's dist/tui.tsx from node_modules still throws Export named 'jsxDEV' not found ... jsx-runtime.d.ts, and host RendererContext === plugin RendererContext is still false. Root cause of why the flag is insufficient (for whoever re-attempts the 0.4.2 bump): the proximate failure is OpenTUI's Solid babel transform (@opentui/solid/scripts/solid-plugin.js), whose file filter hardcodes a node_modules exclusion: const sourceFilter = input.resolvePath
? /^(?!.*[/\\]node_modules[/\\]).*\.[cm]?[jt]sx?(?:[?#].*)?$/
: /^(?!.*[/\\]node_modules[/\\]).*\.[cm]?[jt]sx(?:[?#].*)?$/;npm-spec plugins live under ~/.cache/opencode/.../node_modules/, so the Solid transform never runs on them, Bun falls back to native JSX, and @jsxImportSource @opentui/solid resolves @opentui/solid/jsx-runtime to the plugin's bundled stub. That exclusion is in a different Bun plugin and is not gated by nodeModulesBareSpecifiers. There's also a version-skew dimension (plugin bundles its own older @opentui/solid, distinct instance from the host). Details in #33884. So: the revert is the correct fix for now. If 0.4.2 is re-attempted, the durable fix is to make npm-spec plugins resolve the host's @opentui/* (dedup/override at install) and/or relax the Solid transform's node_modules exclusion for the plugin cache tree — not this flag. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
What this fixes
Fixes #33884.
Since v1.17.10, TUI plugins referenced by their npm package spec in tui.json (e.g. {"plugin": ["@slkiser/opencode-quota"]}) silently stop loading — no sidebar panel, no slash commands, no visible error. Server plugins and file:// TUI plugins are unaffected.
In plain terms
opencode installs an npm TUI plugin into its own isolated folder under ~/.cache/opencode/packages/<spec>/node_modules/<name>/. Because that folder has its own node_modules, the plugin loads its own copy of @opentui/solid instead of the one the opencode app is already running. OpenTUI's Solid renderer keeps a module-level RendererContext singleton, so "the app's renderer" and "the plugin's renderer" end up being two different objects. The plugin then tries to register its panel/commands against a renderer the app isn't using, so nothing shows up — and the failure happens deep in module resolution, so no error reaches the user.
A file:// plugin doesn't have this problem because it lives outside any node_modules directory, so OpenTUI's loader already rewrites its @opentui/* imports onto the app's instance. The npm-spec path is the only one that broke, and it broke when OpenTUI 0.4.2 (#33610) introduced dual bun/node entry files for @opentui/solid, which made the isolated copy diverge from the host copy.
Technical detail
OpenTUI's runtime plugin bridges bare @opentui/* imports onto the host's registered runtime modules, but for paths inside node_modules that bridging is gated behind rewrite options that default to nodeModulesBareSpecifiers: false. Non-node_modules (i.e. file://) plugins are bridged unconditionally.
The fix enables nodeModulesBareSpecifiers when opencode installs the OpenTUI Solid runtime support, so bare @opentui/* imports inside the plugin cache tree are rewritten onto the host's registered instances — giving npm-spec plugins the same renderer instance the host uses, exactly like file:// plugins already get.
One line of behavior change in packages/opencode/src/plugin/tui/runtime.ts, plus an explanatory comment.
Verification
Reproduced on macOS, opencode 1.17.10 (Homebrew), Bun 1.3.14, using @slkiser/opencode-quota:
See #33884 for the full investigation and evidence.
Notes for reviewers