Skip to content

feat: add OpenCode v2 plugin support (dual V1/V2 entrypoint) - #124

Merged
Nomadcxx merged 2 commits into
Nomadcxx:mainfrom
Daltonganger:feat/opencode-v2-support
Aug 13, 2026
Merged

feat: add OpenCode v2 plugin support (dual V1/V2 entrypoint)#124
Nomadcxx merged 2 commits into
Nomadcxx:mainfrom
Daltonganger:feat/opencode-v2-support

Conversation

@Daltonganger

Copy link
Copy Markdown
Contributor

Summary

OpenCode 2.x (the next channel, e.g. build 0.0.0-next-17403) changed the plugin API: plugins must now default-export an object ({ id, setup }) instead of an async factory function. On OpenCode 2.x this plugin currently fails to load with:

failed to load plugin target=@rama_nigg/open-cursor cause="Expected object, got async () => ..."

This PR adds OpenCode 2.x support without breaking OpenCode 1.x, by exporting a dual-shaped default from plugin-entry.ts{ id, server, setup } — the same pattern used by oh-my-opencode-slim.

  • OpenCode 1.x loads server (the existing async factory, unchanged).
  • OpenCode 2.x loads setup (new, in src/plugin-v2.ts).

V2 mapping

V1 hook V2 equivalent
provider / config registration ctx.catalog.transform (provider.update + model.update)
auth loader + api method ctx.integration.transform (key method)
tool hook ctx.tool.transform (tools.add, JSON schema preserved)
chat.params + experimental.chat.system.transform ctx.session.hook("context") (system push + tools record)

The V2 setup reuses the existing proxy server, MCP bridge, tool registry, and model sync — no duplication of that logic.

Changes

  • src/plugin-entry.ts — dual { id, server, setup } default export
  • src/plugin-v2.ts — new V2 setup (proxy start, catalog/integration/tool/session registration)
  • src/plugin.ts — export a few internals used by the V2 setup (CURSOR_PROVIDER_ID, TOOL_LOOP_MODE, TOOL_HOOK_EXCLUSIONS, ensureCursorProxyServer, buildToolHookEntries)

Testing

  • bun run build passes
  • bun test --isolate tests/unit — 689 pass, 4 pre-existing failures (verified identical on main before these changes)
  • Verified the built dist/plugin-entry.js default export has id, server and setup
  • Locally smoke-tested as a V2 plugin file in ~/.config/opencode/plugins/

Note: the V2 plugin API is beta and may change; the V1 path is untouched so 1.x users are unaffected.

Ruben Beuker added 2 commits August 13, 2026 13:42
OpenCode 2.x replaced the V1 plugin API (async factory function default
export) with an object export ({ id, setup }). Loading this plugin on
OpenCode 2.x currently fails with "Expected object, got async ()".

Export a dual-shaped default from plugin-entry.ts — { id, server, setup } —
mirroring the pattern used by oh-my-opencode-slim, so the same package
works on both OpenCode 1.x (server) and 2.x (setup).

The V2 setup (src/plugin-v2.ts) reuses the existing proxy, MCP bridge and
tool machinery and maps the V1 hooks to V2 transforms:
- provider registration via ctx.catalog.transform
- auth via ctx.integration.transform (key method)
- tools via ctx.tool.transform (JSON schema preserved)
- chat.params / system transform via ctx.session.hook("context")
@Daltonganger

Copy link
Copy Markdown
Contributor Author

Follow-up: resolve the active V2 cursor-acp key integration immediately before a Cursor turn and feed it into the existing proxy auth path. This completes the V1 auth.loader → V2 credential bridge.

@Nomadcxx

Nomadcxx commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Thanks for the work on V2 support and the credential follow-up. The dual entrypoint gives us the right V1/V2 bridge, and the V1 path checks clean.

I found a few mismatches with the pinned V2 contract around provider settings, tool registration, session tool shape, and cleanup. I will merge this as the foundation and land those corrections in a maintainer follow-up, so you do not need to make further changes here. Thanks again.

@Nomadcxx
Nomadcxx merged commit 70144d7 into Nomadcxx:main Aug 13, 2026
2 checks passed
@Daltonganger

Copy link
Copy Markdown
Contributor Author

Wanna know what you're gonna do, I found out Grok 4.6 wasn't automatically updated in the plugin, so maybe have a look together.

@Nomadcxx

Copy link
Copy Markdown
Owner

Yep, your V2 work is merged. I followed it with #125 to tidy up the provider, tools, credentials, and cleanup paths.

I’m testing it on bare-metal opencode V2 now and found a startup-order routing bug that the isolated tests missed. I’m sorting that out before release.

And yeah, for sure. If you wanna take a look at Grok 4.6 together, that’d be sweet. I’ll trace the refresh path from my side, then we can compare notes. Thanks for catching it.

@Nomadcxx

Copy link
Copy Markdown
Owner

yeah, you were right about auto-update. grok 4.6 works through v2; I tested it on bare-metal.

we still run startup refresh through the old sdk/api-key path, so cursor-agent logins miss new models. I haven’t patched it yet. I’ll switch discovery to cursor-agent first, with sdk fallback. good catch.

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.

2 participants