Repository navigation
Support OpenCode V1 and V2 from one package - #6
Merged
Merged
Conversation
shanebishop1
force-pushed
the
feat/opencode-v2
branch
from
September 1, 2026 19:58
53d8310 to
bb5f066
Compare
OpenCode V2 resolves a package's `./server` export before its root, so installing `opencode-command-hooks` by name loaded the V1 descriptor and V2 rejected it. The repository E2E loaded the plugin from a directory path, which skips package exports and hid the failure. `./server` now exports one plain definition carrying both the V1 `server` and V2 `setup` adapters, which every current host accepts. The package root stays a callable plugin for V1 releases before 1.3.4, which call each root export as a plugin function. Root `server.js` and `index.js` mirror the exports for directory installs.
The `engines.opencode` range made every V1 release before 1.18.29 skip the plugin as incompatible, although the V1 adapter still runs on them. Package-name installs on OpenCode 1.0 through 1.18 now load as they did with 0.6.x.
Publishes the packed plugin to a throwaway local registry and configures it as `"plugin": ["opencode-command-hooks"]` in V1 1.3.3 (package root), V1 1.3.4 (first `./server` release), the latest V1, and the latest V2. Each host runs a real deterministic shell tool call and must execute the before, after, and (where the host waits for it) idle hooks. Directory-path installs bypass package exports, so this is the only coverage of the entrypoint each host actually selects. Against the previous layout it fails on V1 1.3.3, V1 1.3.4, and V2.
Every OpenCode 1.x release and OpenCode 2 load the same package name without configuration changes. Document how each host selects its entrypoint, the plugin ID, and the package-name host matrix.
The V1 suite picked a hosted free model, which now answers with "Unexpected server error", so the check failed on any commit. It now uses the local OpenAI-compatible fixture by default, like the V2 suite; `OPENCODE_E2E_MODEL` still selects a hosted model. The fixture issues V1 `write` and `task` tool calls in addition to V2 `shell`/`subagent`. With the fast local model, injection and subagent evidence come from the model's request log instead of host log lines that are not flushed before `opencode run` exits. The sandbox path is canonical so macOS temp symlinks do not turn writes into external directory requests.
On macOS the temp directory is a symlink, so the V2 server (started with PWD) and the CLI (process cwd) saw two project locations. Session lookups then missed, and the subagent and reload tests failed locally while passing on Linux CI.
With a fast local model, a one-shot `opencode run` exits as soon as the session is idle, cutting off the idle hook it should observe. Attaching runs to `opencode serve` keeps the host alive like the TUI does.
The V2 adapter declares its own types and the shared entry no longer calls `Plugin.define`, so nothing imports the package. Removing it keeps it and its dependency tree out of every user's install.
It recorded beta-era research and is not referenced by the package or docs. The PR description covers the final design.
It only served the removed `@opencode-ai/plugin/v2` path alias.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
One
opencode-command-hookspackage now supports OpenCode V1 and V2 automatically. Users keep"plugin": ["opencode-command-hooks"]on any host, with no configuration change.@opencode/plugin@2.0.12) alongside the V1 adapter, sharing config, matching, execution, and templating.engines.opencoderange, which made every V1 release before 1.18.29 skip the plugin.@opencode/pluginis not installed for users.Unexpected server error.How each host picks its entrypoint
./server(resolved before.)setup./serverserver./server(src/server.ts) is one plain{ id, server, setup }object. V2's loader validates the default export with an object schema and rejects functions.src/entry.ts) is a callable V1 plugin carrying the same fields. V1 releases before 1.3.4 call every root export as a plugin function.server.jsandindex.jsmirror the two exports for directory-path installs.opencode-command-hookson both hosts (V2 previously usedopencode-command-hooks.v2).The previous layout (
.= V2,./server= V1) passed the existing E2E only because those suites load the plugin from a directory path, which bypasses package exports. Installed by name, V2 loaded the V1 entry and rejected it (Plugin must export a default definition with an id and an effect or setup function), so no hooks ran on any V2 host.Tests
npm run test:hosts:e2e(new): publishes the packed plugin to a throwaway local Verdaccio registry and installs it by name in V1 1.3.3, V1 1.3.4, latest V1, and latest V2. A deterministic model makes a real shell tool call, and the before/after hooks must run (plus idle on hosts that keep running long enough for it). Against the previous layout it fails on V1 1.3.3, V1 1.3.4, and V2. It runs in PR CI and gates the release workflow.npm run test:v1:e2e: now uses the local OpenAI-compatible fixture (OPENCODE_E2E_MODELstill selects a hosted model). Runs attach to a long-livedopencode serve, because a one-shotopencode runexits on idle and cuts off the idle hook. Injection and subagent evidence come from the model request log. The fixture now also issues V1bash/write/taskcalls.npm run test:v2:e2e: temp paths are canonicalized. On macOS the symlinked tmpdir made the server and CLI see two project locations and fail locally; Linux CI was unaffected.Verification
Manual matrix, installed by package name from a local registry:
opencode run, the same as 0.6.1pluginskey, also work.Release
After merge, release from
mainas0.8.0(npmlatestis already0.7.1). The release workflow runs the host matrix before publishing.