Skip to content

feat: add opencode v2 support (dual v1/v2 plugin entrypoint) - #127

Merged
justin-carper merged 1 commit into
mainfrom
opencode-v2-support
Sep 29, 2026
Merged

justin-carper merged 1 commit into
mainfrom
opencode-v2-support

Conversation

@justin-carper

Copy link
Copy Markdown
Collaborator

What

Adds opencode v2 support while keeping v1 working. v2 is a separate npm scope (@opencode/cli, first 2.x on 2026-09-11) with its own plugin API, not a 2.x of opencode-ai.

The default export is now { id, setup, server }. v1 (>= 1.18.29) calls server (unchanged CursorPlugin); v2 calls setup (new src/plugin/v2.ts). Each host ignores the other's key.

What v2 gets

  • Cursor provider and model catalog (real per-model cost, settings.cwd pinned to the session directory)
  • Stored-key and CURSOR_API_KEY auth methods
  • Session context hook (sessionID / plan-mode forwarding) and title hook (ephemeral, same race fix as v1's chat.params)
  • cursor_refresh_models
  • Cleanup removes the generated system rule

Not on v2 (documented in README, CHANGELOG, SECURITY.md)

  • cursor_delegate / cursor_cloud_agent are deliberately not registered. v1 gates them fail-closed with context.ask. v2's plugin ToolContext has no approval path a plugin can drive, and nothing else in 2.0.19 enforces one, so registering them would run Cursor agents ungated. Absent beats silently ungated.
  • cursor_update_plugin (clears the v1 cache layout; on v2 use opencode plugin update)
  • provider.cursor.options block (including autoCompaction), live MCP forwarding, skill mirror, plugin-tools bridge, subagent task-part stamping, update toast, app.log bridge

Review notes

  • Min versions change: README said opencode 1.17+. v1 now needs 1.18.29+ because older hosts do not read an object entrypoint for path plugins. This is the one v1-facing behavior change; worth a look before merge.
  • server.js at the repo root is new and is in files. v2's loader probes literal root entrypoints for file:// directory plugins and never reads package.json exports. npm installs by name are unaffected.
  • cursor_refresh_models / cursor_update_plugin bodies moved verbatim into buildMaintenanceTools() in cursor-tools.ts, shared by both entrypoints. v1 description text and behavior are byte-identical. resolveApiKey may now be async.
  • Existing tests switch from the default import to the named CursorPlugin import. Assertion logic is unchanged.
  • package-lock.json is intentionally not part of this PR. package.json gains no dependencies, and the lockfile on main already drifts against the registry.

Verification

  • npm test: 42 files, 641 tests, exit 0. npm run typecheck and npm run build exit 0.
  • Published dist/plugin/index.{js,d.ts} contain no reference to @opencode/plugin; server.js is in the npm pack file list.
  • Live smoke, one Cursor-model chat each (cursor/claude-haiku-4-5, reply with exactly: OK returned OK):
    • v1: opencode 1.18.33
    • v2: @opencode/cli 2.0.19, run with run --standalone from a project dir that is its own git root
  • v2 live tool call: cursor_refresh_models completed. That run used the built-in opencode/big-pickle model because Claude Haiku chose bash over the tool.
  • Not covered by a live run: the v2 shared-background-service mode (only --standalone was exercised), and the cwd setting under that mode.
  • Local v2 testing needs OPENCODE_CURSOR_PROVIDER_NPM=file://<checkout>/dist/provider/index.js; the v2 loader otherwise resolves the npm-published provider copy.
  • scripts/integration-test.sh (CI's real-host smoke) was not run locally; CI will exercise it.

Changelog entry is under [Unreleased].

opencode v2 ships as a separate npm scope (@opencode/cli) with a new
plugin API. The default export is now an object carrying both entrypoints:
v1 (>= 1.18.29) calls `server`, v2 calls `setup`. Each host ignores the
other's key.

v2 `setup` (src/plugin/v2.ts) registers the Cursor provider and model
catalog (real per-model cost, settings.cwd pinned to the session
directory), stored-key/env auth methods, the session context and title
hooks, and cursor_refresh_models. Cleanup removes the generated system
rule.

Not exposed on v2: cursor_delegate / cursor_cloud_agent (v2 has no
plugin-drivable approval path, so they stay absent rather than ungated)
and cursor_update_plugin (v1 cache layout; use `opencode plugin update`).
Remaining gaps are listed in the README.

cursor_refresh_models / cursor_update_plugin bodies move to a shared
builder in cursor-tools.ts; v1 behavior is unchanged. A root server.js
re-export lets v2 load a file:// directory plugin.
@justin-carper
justin-carper merged commit 1230be9 into main Sep 29, 2026
8 checks passed
@justin-carper
justin-carper deleted the opencode-v2-support branch September 29, 2026 15:36
justin-carper added a commit that referenced this pull request Oct 3, 2026
Promotes the 0.10.0 line from @next to latest: opencode v2 support
alongside v1 (#127), the subagent transcript fix (#114), regenerated
model limits/costs, and the repaired weekly model-data drift check.
Consolidates pre-releases 0.9.1-next.0, 0.10.0-next.1, and
0.10.0-next.2 (0.10.0-next.0 was tagged but never published). The
README v2 install example switches back to @latest.
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.

1 participant