Repository navigation
Conversation
OpenCode 2 rejects V1 plugin factories ("must export a default
definition with an id and a setup function"). Ship a dual-shape
default export: { id, server, setup }.
- OpenCode 1 (>= 1.3.4) keeps loading the existing plugin through
the "server" field (AutoResumePlugin unchanged, named export too)
- OpenCode 2 calls the new "setup" entrypoint (src/v2.ts), which
instantiates the V1 plugin with a synthesized OpenCodeClient and
bridges the returned V1 hooks onto V2 APIs:
tool.execute.before/after -> ctx.tool.hook,
event + chat.message -> ctx.event.subscribe(),
tool.task_complete -> ctx.tool.transform
- V1-only hooks (config, command.execute.before) are skipped, as
OpenCode 2 has no equivalent
- add @opencode/client dependency (used by the V2 setup to
synthesize the client the V1 plugin expects)
- update the exports-guard test for the new default-export shape
The V2 setup is a port of a shim that has been verified live on
OpenCode 2.1.2: plugin loads without errors and registers the
task_complete tool.
|
Thanks for considering this PR! A quick note on how it relates to the other v2 PRs in the tracker (#20, #37, #41, #44) — I see #37 is the chosen direction, and we're happy to close this one if that stands. The one thing #47 adds to the discussion is an adapter variant that avoids the "silently stubbed surfaces" concern raised about #44:
That said, we fully understand if the full port in #37 is the preferred long-term answer (it covers things a bridge can't express as cleanly, like v2's tool-lifecycle events, plus todo state from the session log). If #37 is landing soon, we're glad to close this — just say the word. Until then, leaving it up in case the thinner single-engine option is useful as a comparison point. |
|
there is already #37 so anything that is wrong in that PR needs to be documented in that PR otherwise following everything for me that I still don't use opencode v2 is crazy. |
Summary
Adds support for the OpenCode 2 plugin API while keeping OpenCode 1 compatibility, via a dual-shape default export — the same pattern used by other plugins that migrated (e.g. type-inject).
The problem: OpenCode 2 rejects V1 plugin factories with
Plugin must export a default definition with an id and an effect or setup function, so the plugin fails to load with aLoadErroron OpenCode 2.The fix:
export default { id, server, setup }serverfield —AutoResumePluginitself is unchanged (the named export stays too, so nothing changes for direct imports).setupentrypoint (src/v2.ts), which:OpenCodeClient(the V2 context has noclientfield, so one is created lazily via@opencode/clientwith a graceful fallback),tool.execute.before/tool.execute.after→ctx.tool.hook(...)event+chat.message→ctx.event.subscribe()pumptool.task_complete→ctx.tool.transform(...)(registers thetask_completetool)config,command.execute.before) since OpenCode 2 has no equivalent for them.Verification
The V2
setupis a port of a shim that has been running live on OpenCode 2.1.2: the plugin loads without errors and registers thetask_completetool in real sessions.bun run buildOKbun test: 599 pass / 0 fail across 37 filessrc/index.exports-guard.test.tsupdated for the new default-export shape (still guards against non-Plugin exports crashing the V1 host)Notes
@opencode/client(used by the V2 setup to synthesize the client the V1 plugin expects). Existing V1 users get it transitively but the V1 code path is untouched.server).