feat: add OpenCode v2 plugin support (dual V1/V2 entrypoint) - #124
Conversation
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")
|
Follow-up: resolve the active V2 |
|
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. |
|
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. |
|
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. |
|
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. |
Summary
OpenCode 2.x (the
nextchannel, e.g. build0.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: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 byoh-my-opencode-slim.server(the existing async factory, unchanged).setup(new, insrc/plugin-v2.ts).V2 mapping
provider/configregistrationctx.catalog.transform(provider.update+model.update)authloader + api methodctx.integration.transform(key method)toolhookctx.tool.transform(tools.add, JSON schema preserved)chat.params+experimental.chat.system.transformctx.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 exportsrc/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 buildpassesbun test --isolate tests/unit— 689 pass, 4 pre-existing failures (verified identical onmainbefore these changes)dist/plugin-entry.jsdefault export hasid,serverandsetup~/.config/opencode/plugins/Note: the V2 plugin API is beta and may change; the V1 path is untouched so 1.x users are unaffected.