Skip to content

feat(opencode): add v2 plugin support (--opencode-v2) - #3464

Closed
umi008 wants to merge 1 commit into
rtk-ai:developfrom
umi008:feat/opencode-v2-plugin
Closed

umi008 wants to merge 1 commit into
rtk-ai:developfrom
umi008:feat/opencode-v2-plugin

Conversation

@umi008

@umi008 umi008 commented Aug 7, 2026 •

Copy link
Copy Markdown

Summary

  • Add hooks/opencode/rtk-v2.ts — OpenCode v2 plugin using Plugin.define + ctx.tool.hook('execute.before', ...) with child_process.spawn (v2 doesn't provide the bun-shell $ helper)
  • Add --opencode-v2 flag to rtk init, mutually exclusive with --opencode
  • Embed OPENCODE_V2_PLUGIN via include_str!; thread through all sub-functions

Test plan

  • cargo fmt --all && cargo clippy --all-targets && cargo test --all
  • Manual testing: plugin loads and registers hook with bun (opencode2 runtime)
  • Manual testing: rtk rewrite rewrites commands correctly (exit code 3 handled)
  • Manual testing: rtk init -g --opencode-v2 installs the v2 plugin

Important: All PRs must target the develop branch (not master).
See CONTRIBUTING.md for details.

- Add hooks/opencode/rtk-v2.ts — OpenCode v2 plugin using Plugin.define
  API with ctx.tool.hook('execute.before', ...)
- Add --opencode-v2 flag to rtk init CLI
- Embed OPENCODE_V2_PLUGIN via include_str! in installer
- Thread install_opencode_v2 through run(), run_default_mode(),
  run_hook_only_mode(), run_claude_md_mode(), run_opencode_only_mode()
- ensure_opencode_plugin_installed() now accepts content parameter
- Validate --opencode and --opencode-v2 are mutually exclusive
- Update READMEs for hooks/ and hooks/opencode/
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Uli seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@umi008 umi008 changed the title feat: add opencode v2 plugin support (opencode2) feat(opencode): add v2 plugin support (--opencode-v2) Aug 7, 2026
@Sn0wo2

Sn0wo2 commented Aug 16, 2026

Copy link
Copy Markdown

import { Plugin } from "@opencode-ai/plugin" fails to resolve in the v2 plugin runtime (even with the package installed next to the file). Dropping the import and exporting a plain { id, setup } object fixes it.
Plugin.define is just a type wrapper. Everything else works as-is (verified on next-17444):

import { spawn } from "child_process"

// RTK OpenCode v2 plugin — rewrites commands to use rtk for token savings.
// Requires: rtk >= 0.23.0 in PATH.
//
// OpenCode 2.0 uses a new plugin API (Plugin.define + ctx.tool.hook) and does
// not provide the v1 bun-shell `$` helper, so this variant spawns `rtk`
// directly. `rtk rewrite` exits non-zero even on success, so we read stdout
// from the child instead of relying on exit codes.
//
// This is a thin delegating plugin: all rewrite logic lives in `rtk rewrite`,
// which is the single source of truth (src/discover/registry.rs).
// To add or change rewrite rules, edit the Rust registry — not this file.

function rtkRewrite(command: string): Promise<string> {
  return new Promise((resolve) => {
    const proc = spawn("rtk", ["rewrite", command], { windowsHide: true })
    let out = ""
    proc.stdout.on("data", (d) => {
      out += d
    })
    proc.on("error", () => resolve(""))
    proc.on("close", () => resolve(out.trim()))
  })
}

export default {
  id: "rtk.rewrite",
  setup: async (ctx) => {
    await ctx.tool.hook("execute.before", async (event) => {
      const tool = String(event.tool ?? "").toLowerCase()
      if (tool !== "bash" && tool !== "shell") return
      if (!event.input || typeof event.input !== "object") return

      const command = (event.input as Record<string, unknown>).command
      if (typeof command !== "string" || !command) return

      const rewritten = await rtkRewrite(command)
      if (rewritten && rewritten !== command) {
        ;(event.input as Record<string, unknown>).command = rewritten
      }
    })
  },
}

@KuSh

KuSh commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Closing this one in favour of #3899, which adds the same OpenCode 2.0 support inside the existing plugin file so both plugin formats are handled automatically and no separate --opencode-v2 flag is needed. If the separate-file approach still matters for your setup, a comment on #3899 is the best place to raise it.

@KuSh KuSh closed this Sep 6, 2026
@KuSh KuSh added the duplicate This issue or pull request already exists label Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants