Skip to content

fix(opencode): support the OpenCode 2 CLI and plugin API - #2397

Open
aryasaatvik wants to merge 4 commits into
entireio:mainfrom
aryasaatvik:fix/opencode-v2-support
Open

fix(opencode): support the OpenCode 2 CLI and plugin API#2397
aryasaatvik wants to merge 4 commits into
entireio:mainfrom
aryasaatvik:fix/opencode-v2-support

Conversation

@aryasaatvik

@aryasaatvik aryasaatvik commented Sep 12, 2026

Copy link
Copy Markdown

Summary

OpenCode 2 is GA and incompatible with Entire's OpenCode integration in two places, so no transcript was ever captured: the generated plugin used the OpenCode 1 server-hook export (rejected with PluginModule.LoadError), and the CLI ran opencode export, which OpenCode 2 answers with a help page and exit 0. This makes the integration target OpenCode 2 end to end.

Changes

  • Plugin — emit an OpenCode 2 plugin definition (id + setup): session hooks replace experimental.chat.system.transform, the event subscription replaces the event map, and session-end moves to plugin unload. The SDK types are imported type-only from the public @opencode/plugin entry, so the loader never resolves project node_modules. Drops OpenCode 1 plugin support.
  • Commands — try opencode session export / session import (OpenCode 2), validate the export before accepting it, and fall back to opencode export / import (OpenCode 1). A classified failure from the OpenCode 2 attempt (e.g. "Session not found") is preserved rather than overwritten by the fallback's invalid output.
  • Schema — normalize both export shapes (info/parts vs type/content plus a message-level text) to the v1 model for reads, and keep chunking/reassembly byte-preserving so the stored raw transcript stays importable by opencode session import.
  • e2e — accept OpenCode 2's opencode v2.0.2 version output, and skip the OpenCode 1 plugin-dependency seeding on major ≥ 2, where the V2 API is provided by the binary.

Flow

turn-end hook
  -> opencode session export <id>   (fallback: opencode export <id>)
  -> validate JSON (rejects exit-0 help; keeps a classified failure)
  -> .entire/tmp/<id>.json          (native, importable)
  -> ParseExportSession             (normalized v1 view for prompts/tokens/files)

Review notes

  • The v1 command exits 0 with a help page on OpenCode 2, so the result is validated rather than trusted, and the OpenCode 2 attempt's classified error survives the fallback.
  • OpenCode 1 plugin support is intentionally dropped; the CLI keeps the v1 export/import command fallback and the e2e harness degrades to config-only seeding on OpenCode 2.
  • Verified against a real opencode session export (messages, prompts, modified files, tokens) and an end-to-end hook run in a scratch repo that wrote a 2 MB .entire/tmp/<id>.json.

OpenCode 2 moved session export/import under `session` and changed the export schema (messages carry a type plus typed content instead of info/parts). Entire only ran `opencode export`, which OpenCode 2 answers with a help page and exit 0, so no transcript was ever cached.

Try the OpenCode 2 command first and validate the output before accepting it, falling back to the v1 command. Normalize both export shapes to the v1 model the readers use, and keep chunking/reassembly byte-preserving so the stored raw transcript stays importable. Teach the condensed transcript path the v2 shape.
The generated plugin used OpenCode 1's server-hook export, which OpenCode 2 rejects with PluginModule.LoadError. Emit a V2 plugin definition (id + setup) instead: session hooks replace the system-transform hook, the event subscription replaces the event map, and session-end moves to plugin unload. The SDK import is type-only so the loader does not resolve project node_modules. Drops OpenCode 1 plugin support.
Extract the repeated "text"/"tool" content-part literals into constants so golangci-lint's goconst passes.

Entire-Checkpoint: 01M2B6RF3CPRJFRGH3081SQ0PW
Preserve a classified export error through the v1 fallback so a missing session still reports "was not found" instead of the generic invalid-output message. Accept OpenCode 2's "opencode v2.0.2" version output and skip the OpenCode 1 plugin-dep seeding on major 2, where the V2 plugin API comes from the binary. Import the SDK types from the public @opencode/plugin entry rather than the internal promise/plugin subpath.

Entire-Checkpoint: 01M2B7PXTQDXJNCP96Z1Q9YTEB
@aryasaatvik
aryasaatvik marked this pull request as ready for review September 12, 2026 16:43
@aryasaatvik
aryasaatvik requested a review from a team as a code owner September 12, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant