Summary
I installed opencode-pty following the README verbatim, with the $schema and plugin fields set exactly as documented:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-pty"]
}
The plugin silently fails to load. The async PTYPlugin factory is never invoked, so:
- the
config hook that registers pty-open-background-spy / pty-show-server-url never runs,
- the
tool block (pty_spawn, pty_read, pty_write, pty_list, pty_kill) is never registered,
- the
command.execute.before interceptor is never installed.
opencode still lists the plugin under its loaded-plugins set, but no error is shown in the TUI — the failure is completely invisible to the user.
How I diagnosed it
I narrowed the failure to the plugin module by checking the command palette: typing /pty-open in the prompt shows no /pty-open-background-spy (or /pty-show-server-url) entry in the candidate list. Since the only path that adds these commands is the plugin's config hook, their absence proves the PTYPlugin function was never called. Same for the agent tools — the AI has no pty_spawn etc. available.
Tracing further:
-
package.json main: dist/index.js
-
dist/index.js → dist/src/plugin.js
-
dist/src/plugin.js → import { initManager, manager } from "./plugin/pty/manager.js"
-
dist/src/plugin/pty/manager.js opens with:
import { semver } from 'bun'; // ← throws on Node
import { Terminal } from 'bun-pty'; // ← needs bun:ffi
import { version as bunPtyVersion } from 'bun-pty/package.json';
Under Node.js, import { semver } from 'bun' throws ERR_MODULE_NOT_FOUND immediately at module load time. The exception propagates out of the top-level import, the entire plugin module never finishes loading, and PTYPlugin is never reached.
Verified directly:
$ node -e "require('bun')"
Error: Cannot find module 'bun'
code: 'MODULE_NOT_FOUND'
Environment
| Item |
Value |
| OS |
Windows 11 (win32) |
| opencode |
1.17.7 (opencode-ai npm package) |
| Plugin |
opencode-pty@0.3.4 |
| Bun |
1.3.14 installed on the system, but not used to launch opencode (see below) |
| Config |
~/.config/opencode/opencode.json with $schema and plugin fields set per README |
Why "use Bun" is not a real workaround for the documented install
opencode-ai@1.17.7 is a standard Node application. bun add -g opencode-ai only installs the same Node binary under Bun's global modules; running opencode (or ~/.bun/bin/opencode.exe) still spawns a Node process. To get the plugin to actually load, a user has to know to launch with bun --bun x opencode-ai (or bunx opencode-ai) — which is not mentioned anywhere in the README, and is not flagged by package.json engines (it only specifies "opencode": ">=1.3.13").
Following the documented install produces a broken setup for the majority of users on every OS.
Suggested fixes (any one of these)
-
Lazy / dynamic import the Bun-specific bits. Replace the top-level import { semver } from 'bun' with a await import('bun') that only runs when actually needed, and guard the Terminal.prototype._startReadLoop monkey-patch. The plugin would still load under Node; the tools would fail at runtime with a clear error, but the config hook would still register the slash commands.
-
Polyfill semver. The Bun.semver import is only used to compare bun-pty versions (semver.order(bunPtyVersion, '0.4.8')). A simple split+Number comparison or the semver npm package would do.
-
Detect-and-warn at load time. Wrap the Bun-specific imports in a try/catch, log a clear warning (something like [opencode-pty] ⚠ Plugin loaded but the PTY backend is NOT available), and skip the tool registration. The config hook should still run so the slash commands at least show up and the user gets a clear message instead of a silent no-op.
-
Document the runtime requirement prominently. The README installation snippet should make it explicit that the user must run opencode via bunx opencode-ai (or bun --bun opencode), not just opencode.
Option (1) is the smallest change with the biggest user-visible win. Option (3) is the most defensive.
Reference: relevant files
src/plugin.ts — exports PTYPlugin, registers the config hook
src/plugin/pty/manager.ts — source that compiles to the file with the offending import { semver } from 'bun'
package.json — engines.opencode: ">=1.3.13" does not advertise the Bun runtime requirement
Summary
I installed
opencode-ptyfollowing the README verbatim, with the$schemaandpluginfields set exactly as documented:{ "$schema": "https://opencode.ai/config.json", "plugin": ["opencode-pty"] }The plugin silently fails to load. The async
PTYPluginfactory is never invoked, so:confighook that registerspty-open-background-spy/pty-show-server-urlnever runs,toolblock (pty_spawn,pty_read,pty_write,pty_list,pty_kill) is never registered,command.execute.beforeinterceptor is never installed.opencode still lists the plugin under its loaded-plugins set, but no error is shown in the TUI — the failure is completely invisible to the user.
How I diagnosed it
I narrowed the failure to the plugin module by checking the command palette: typing
/pty-openin the prompt shows no/pty-open-background-spy(or/pty-show-server-url) entry in the candidate list. Since the only path that adds these commands is the plugin'sconfighook, their absence proves thePTYPluginfunction was never called. Same for the agent tools — the AI has nopty_spawnetc. available.Tracing further:
package.jsonmain: dist/index.jsdist/index.js→dist/src/plugin.jsdist/src/plugin.js→import { initManager, manager } from "./plugin/pty/manager.js"dist/src/plugin/pty/manager.jsopens with:Under Node.js,
import { semver } from 'bun'throwsERR_MODULE_NOT_FOUNDimmediately at module load time. The exception propagates out of the top-levelimport, the entire plugin module never finishes loading, andPTYPluginis never reached.Verified directly:
Environment
opencode-ainpm package)opencode-pty@0.3.4~/.config/opencode/opencode.jsonwith$schemaandpluginfields set per READMEWhy "use Bun" is not a real workaround for the documented install
opencode-ai@1.17.7is a standard Node application.bun add -g opencode-aionly installs the same Node binary under Bun's global modules; runningopencode(or~/.bun/bin/opencode.exe) still spawns a Node process. To get the plugin to actually load, a user has to know to launch withbun --bun x opencode-ai(orbunx opencode-ai) — which is not mentioned anywhere in the README, and is not flagged bypackage.jsonengines(it only specifies"opencode": ">=1.3.13").Following the documented install produces a broken setup for the majority of users on every OS.
Suggested fixes (any one of these)
Lazy / dynamic import the Bun-specific bits. Replace the top-level
import { semver } from 'bun'with aawait import('bun')that only runs when actually needed, and guard theTerminal.prototype._startReadLoopmonkey-patch. The plugin would still load under Node; the tools would fail at runtime with a clear error, but theconfighook would still register the slash commands.Polyfill
semver. TheBun.semverimport is only used to comparebun-ptyversions (semver.order(bunPtyVersion, '0.4.8')). A simplesplit+Numbercomparison or thesemvernpm package would do.Detect-and-warn at load time. Wrap the Bun-specific imports in a try/catch, log a clear warning (something like
[opencode-pty] ⚠ Plugin loaded but the PTY backend is NOT available), and skip the tool registration. Theconfighook should still run so the slash commands at least show up and the user gets a clear message instead of a silent no-op.Document the runtime requirement prominently. The README installation snippet should make it explicit that the user must run opencode via
bunx opencode-ai(orbun --bun opencode), not justopencode.Option (1) is the smallest change with the biggest user-visible win. Option (3) is the most defensive.
Reference: relevant files
src/plugin.ts— exportsPTYPlugin, registers theconfighooksrc/plugin/pty/manager.ts— source that compiles to the file with the offendingimport { semver } from 'bun'package.json—engines.opencode: ">=1.3.13"does not advertise the Bun runtime requirement