Skip to content

fix(plugin): slim main entry so OpenCode can load it#16

Merged
stephane-segning merged 2 commits into
mainfrom
claude/tender-brown-7a1b0c
May 26, 2026
Merged

fix(plugin): slim main entry so OpenCode can load it#16
stephane-segning merged 2 commits into
mainfrom
claude/tender-brown-7a1b0c

Conversation

@stephane-segning
Copy link
Copy Markdown
Contributor

Summary

Fixes TypeError: Plugin export is not a function when OpenCode loads @vymalo/opencode-oauth2.

OpenCode's plugin loader (verified against opencode-ai@1.15.10) iterates every named export of the resolved plugin module and requires each value to be either a function or { server: fn }. Our dist/index.js re-exported two number constants — DEFAULT_HTTP_TIMEOUT_MS and DEFAULT_SYNC_INTERVAL_MINUTES — which trip the check. Even without those, every other named function (validateConfig, fetchModels, FileCacheStore, and the createOpencodeOauth2Plugin factory itself) would have been invoked as a plugin with the wrong arguments.

Changes

  • src/index.ts — slimmed to a single export { default } from "./opencode.js". The OpenCode-facing entry now exposes exactly one value: the plugin function.
  • src/lib.ts (new) — holds the former public API (validateConfig, OAuth2ModelSyncPlugin, FileCacheStore, the defaults, types, etc.) for embedders that want to drive the runtime directly.
  • package.json — adds an exports map: . → slim plugin entry, ./lib → library API. main/types are kept for legacy resolvers.
  • docs/troubleshooting.md — updates the embedder snippet to import from @vymalo/opencode-oauth2/lib.

Verification

node -e 'import("./dist/index.js").then(m => console.log(Object.keys(m), Object.values(m).map(v => typeof v)))'
# → [ 'default' ] [ 'function' ]
  • pnpm typecheck passes
  • pnpm build passes
  • pnpm test passes (94/94)

Test plan

  • Install the rebuilt package in an OpenCode workspace and confirm the plugin loads without Plugin export is not a function.
  • Confirm import { OAuth2ModelSyncPlugin } from "@vymalo/opencode-oauth2/lib" resolves for embedders.
  • Confirm CI green on Node >=22.

🤖 Generated with Claude Code

OpenCode's plugin loader iterates every named export of the resolved
plugin module and requires each value to be a function (or
`{ server: fn }`). The package's `dist/index.js` re-exported two number
constants (`DEFAULT_HTTP_TIMEOUT_MS`, `DEFAULT_SYNC_INTERVAL_MINUTES`),
which caused `TypeError: Plugin export is not a function` on load. Every
other named function (validateConfig, fetchModels, FileCacheStore, even
the factory itself) would also have been invoked as a plugin.

Restructure so the OpenCode entry exposes only the plugin function, and
move the library API to a `./lib` subpath via the `exports` map.

- src/index.ts: re-exports only `default` from ./opencode.js
- src/lib.ts (new): holds the former named exports
- package.json: adds `exports` map with `.` (plugin) and `./lib` (API)
- docs/troubleshooting.md: updates embedder example to `/lib` subpath

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request restructures the exports of the @vymalo/opencode-oauth2 package to prevent the host environment from incorrectly invoking non-plugin exports. The main entry point (index.ts) now only exports the default plugin function, while the library API has been moved to a new lib.ts file and exposed via the ./lib subpath in package.json. The documentation has been updated accordingly. The reviewer pointed out a regression where the pre-instantiated OpencodeOauth2Plugin was omitted from the new lib.ts exports, and provided a suggestion to restore it.


export { resolveCacheDir, FileCacheStore } from "./cache.js";

export { createOpencodeOauth2Plugin } from "./opencode.js";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The pre-instantiated plugin instance OpencodeOauth2Plugin is not exported from lib.ts. Since it was previously exported from index.ts (and can no longer be exported there to prevent OpenCode from invoking it with incorrect arguments), it should be exported from lib.ts so that embedders who import named exports can still access it.

Suggested change
export { createOpencodeOauth2Plugin } from "./opencode.js";
export { createOpencodeOauth2Plugin, OpencodeOauth2Plugin } from "./opencode.js";

Patch release for the plugin-entry fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@stephane-segning stephane-segning merged commit 84e064d into main May 26, 2026
3 checks passed
@stephane-segning stephane-segning deleted the claude/tender-brown-7a1b0c branch May 26, 2026 09:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant