Summary
V2 local plugin discovery does not load immediate child directories as packages, even when they provide a string exports entrypoint. This contradicts the documented behavior:
The equivalent global directory is ~/.config/opencode/plugins/. Direct .ts and .js children are loaded. An immediate child directory is also loaded as a package when OpenCode can resolve a string exports, module, or main entrypoint, or an index.ts or index.js file.
https://opencode.ai/v2/docs/build/plugins#local-discovery
Environment
- opencode version:
opencode2 v0.0.0-next-16719
- OS:
Darwin 25.6.0 Darwin Kernel Version 25.6.0: Sat Jul 11 15:27:27 PDT 2026; root:xnu-12377.161.13~4/RELEASE_ARM64_T6041 arm64
- Terminal: Ghostty (
TERM_PROGRAM=ghostty, TERM=xterm-256color, COLORTERM=truecolor)
- Shell:
/bin/zsh
- Install/channel: V2 preview,
next release
- Active plugins: Isolated reproduction loads
repro.direct-file plus built-ins; repro.directory-package is absent. The original user config also contains an explicit packaged plugin and local .ts plugins, but they are not needed to reproduce the issue.
Reproduction
-
Create an isolated config with a direct-file control plugin and a directory package:
root="${TMPDIR:-/tmp}/opencode-plugin-directory-repro"
rm -rf "$root"
mkdir -p "$root/config/plugins/directory-package"
printf '{}\n' > "$root/config/opencode.json"
cat > "$root/config/plugins/direct.ts" <<'PLUGIN'
export default { id: "repro.direct-file", setup() {} }
PLUGIN
cat > "$root/config/plugins/directory-package/package.json" <<'PACKAGE'
{ "type": "module", "exports": "./index.ts" }
PACKAGE
cat > "$root/config/plugins/directory-package/index.ts" <<'PLUGIN'
export default { id: "repro.directory-package", setup() {} }
PLUGIN
-
Start V2 using this config directory:
OPENCODE_CONFIG_DIR="$root/config" OPENCODE_SERVER_PASSWORD=repro \
opencode2 serve --hostname 127.0.0.1 --port 41987
-
In another terminal, list active plugins after startup:
OPENCODE_SERVER_PASSWORD=repro \
opencode2 api --server http://127.0.0.1:41987 get /api/plugin
Expected Behavior
Both repro.direct-file and repro.directory-package are loaded. The documentation says an immediate child directory is loaded when OpenCode can resolve a string exports, module, or main entrypoint, or an index.ts or index.js file.
Actual Behavior
Only the direct-file control plugin is loaded:
repro.directory-package is consistently absent. The same behavior occurs for ~/.config/opencode/plugins/boxedcode, whose package.json has "exports": "./index.ts".
Additional Context
The issue reproduces consistently with no third-party plugins involved. Direct .ts discovery works, so the config directory is being scanned correctly.
The current V2 implementation in packages/core/src/plugin/supervisor.ts discovers only direct files with:
fs.scan("{plugin,plugins}/*.{ts,js}", ...)
No child directories are scanned or resolved as package entrypoints.
Summary
V2 local plugin discovery does not load immediate child directories as packages, even when they provide a string
exportsentrypoint. This contradicts the documented behavior:https://opencode.ai/v2/docs/build/plugins#local-discovery
Environment
opencode2 v0.0.0-next-16719Darwin 25.6.0 Darwin Kernel Version 25.6.0: Sat Jul 11 15:27:27 PDT 2026; root:xnu-12377.161.13~4/RELEASE_ARM64_T6041 arm64TERM_PROGRAM=ghostty,TERM=xterm-256color,COLORTERM=truecolor)/bin/zshnextreleaserepro.direct-fileplus built-ins;repro.directory-packageis absent. The original user config also contains an explicit packaged plugin and local.tsplugins, but they are not needed to reproduce the issue.Reproduction
Create an isolated config with a direct-file control plugin and a directory package:
Start V2 using this config directory:
OPENCODE_CONFIG_DIR="$root/config" OPENCODE_SERVER_PASSWORD=repro \ opencode2 serve --hostname 127.0.0.1 --port 41987In another terminal, list active plugins after startup:
Expected Behavior
Both
repro.direct-fileandrepro.directory-packageare loaded. The documentation says an immediate child directory is loaded when OpenCode can resolve a stringexports,module, ormainentrypoint, or anindex.tsorindex.jsfile.Actual Behavior
Only the direct-file control plugin is loaded:
repro.directory-packageis consistently absent. The same behavior occurs for~/.config/opencode/plugins/boxedcode, whosepackage.jsonhas"exports": "./index.ts".Additional Context
The issue reproduces consistently with no third-party plugins involved. Direct
.tsdiscovery works, so the config directory is being scanned correctly.The current V2 implementation in
packages/core/src/plugin/supervisor.tsdiscovers only direct files with:No child directories are scanned or resolved as package entrypoints.