Skip to content

Conversation

@aryasaatvik
Copy link
Contributor

@aryasaatvik aryasaatvik commented Jan 10, 2026

Summary

  • Migrates plugin system to use SDK v2 types and client exclusively
  • Removes v1 SDK compatibility layer - this is now a full breaking change
  • Key context: Many hooks already had type drift between v1 contract and v2 runtime, so this breaking change is less severe than it appears

Why This Breaking Change Is Acceptable

Hook Types Were Already Broken

Analysis revealed significant type drift between what the plugin package defined and what the OpenCode core actually passed at runtime:

Hook Plugin Expected Core Passed Impact
permission.ask Permission with title Permission.Info with message Field name mismatch - input.title returns undefined
chat.params Provider Promise<Provider.Info> Promise wrapper not in type
chat.message UserMessage MessageV2.Info Different type structure

The core was already using @ts-expect-error workarounds to suppress these mismatches. Plugins accessing input.title in permission.ask were already getting undefined at runtime.

This Change Fixes the Type Mismatch

Instead of maintaining broken v1 types, we:

  1. Update the plugin contract to match the actual v2 runtime behavior
  2. Provide clean, consistent types that match what OpenCode core actually passes
  3. Remove the UnifiedClient complexity (no more .v2 accessor needed)

Changes

Plugin Package (packages/plugin)

  • Updated all imports from @opencode-ai/sdk@opencode-ai/sdk/v2
  • Changed hook types to use v2 SDK types (PermissionRequest instead of Permission, etc.)
  • Simplified PluginInput.client to be v2 OpencodeClient only
  • Added ToolContext.metadata() and ToolResult types

Plugin Loader (packages/opencode)

  • Removed v1 SDK client creation
  • Removed unified client proxy (.v2 accessor)
  • Now creates and passes v2 SDK client only

Breaking Changes

What Before After
SDK client input.client (v1) + input.client.v2 (v2) input.client (v2 only)
Permission type Permission with title PermissionRequest with permission
Permission reply status: ask/deny/allow reply: once/always/reject
SDK calls Nested { path, body, query } Flattened parameters

Migration for Plugin Authors

  1. Change imports: @opencode-ai/plugin (no /v2)
  2. Update permission hook:
    // Before
    (input: Permission, output: { status: "ask" | "deny" | "allow" }) => { ... }
    
    // After
    (input: PermissionRequest, output: { reply: "once" | "always" | "reject" }) => { ... }
  3. Update SDK calls to use flattened parameters

Why Not Maintain v1 Compatibility?

  • The SDK client had massive breaking changes (every method call changed from nested to flat)
  • Hook types already had significant drift (not just style changes, but actual field mismatches)
  • Maintaining both v1 and v2 code paths added complexity
  • Clean break forces plugin authors to update, resulting in better type safety

Closes #7641

…v2 plugin subpath exports (@opencode-ai/plugin/v2)\n- Import types from @opencode-ai/sdk/v2 with flattened API params\n- Update permission hook to use PermissionRequest with reply format\n- Add v2/tool.ts importing FilePart from SDK v2
@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

No duplicate PRs found

…e separate client instances for v1 and v2 SDKs to maintain backward compatibility.\n- Update plugin input handling to accommodate both versions.\n- Implement version detection for plugins to ensure correct initialization based on SDK version.
- Replace separate v1/v2 inputs with unified PluginInput
- Create UnifiedClient with .v2 accessor for backward compatibility
- Remove plugin version detection logic
- Simplify plugin loading to use single unified input
- Remove packages/plugin/src/v2/index.ts and v2/tool.ts
- No longer needed after unifying plugin API with single input
- Remove unified client proxy, use v2 SDK client directly
- Update CodexAuthPlugin to use v2 auth.set() API format
- Update plugin types to use v2 SDK types (OpencodeClient, PermissionRequest)
- Add 'reject' status option to permission.ask hook
- Remove v1 client imports and creation
@aryasaatvik aryasaatvik changed the title feat(plugin): add v2 subpath exports with flattened SDK API BREAKING CHANGE: Migrate plugin system to SDK v2 types only (removes v1 compatibility) Jan 11, 2026
@github-actions
Copy link
Contributor

Hey! Your PR title BREAKING CHANGE: Migrate plugin system to SDK v2 types only (removes v1 compatibility) doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@aryasaatvik aryasaatvik changed the title BREAKING CHANGE: Migrate plugin system to SDK v2 types only (removes v1 compatibility) feat(plugin)!: migrate plugin system to SDK v2 Jan 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plugin hook types not aligned with runtime triggers and missing v2 sdk

1 participant