Skip to content

Support OpenCode V1 and V2 from one plugin export - #9016

Open
SwarmStorm wants to merge 2 commits into
code-yeongyu:devfrom
SwarmStorm:feat/opencode-v1-v2-plugin
Open

SwarmStorm wants to merge 2 commits into
code-yeongyu:devfrom
SwarmStorm:feat/opencode-v1-v2-plugin

Conversation

@SwarmStorm

@SwarmStorm SwarmStorm commented Sep 27, 2026 •

Copy link
Copy Markdown

Summary

  • OpenCode V2 loads a plugin only when the default export has setup from Plugin.define in @opencode/plugin. This package still exported the V1 { id, server } shape, so V2 hosts rejected it with Missing key at ["default"]["setup"].
  • The same default export now has both. V2 calls setup(). OpenCode 1.18.29 and newer keep calling server(), and the TUI entry keeps tui().
  • setup runs the existing V1 pipeline, then projects that config onto V2 tools, commands, MCP, skills, and providers. Agents are written as markdown, because the V2 agent editor can update and remove agents but cannot add one.

Changes

  • Server entry: spread Plugin.define({ id, setup }) and keep server on the same object. TUI entry does the same and keeps tui.
  • packages/omo-opencode/src/v2/ is the host. A context facade feeds the V1 startup path. A hook bridge forwards V2 events into the existing handlers. A projection step registers tools, commands, MCP, skills, and providers, and writes agent markdown under the OpenCode agents directory.
  • Root index.js re-exports the built plugin so a configured plugin directory loads on OpenCode 2.0.16. That release drops a configured path that points at a file.
  • @opencode/plugin 2.0.16 is a dependency of the root package and packages/omo-opencode. The index and TUI bundles treat it as external.

QA & Evidence

  • What was tested: bun test on the export-shape test, the V2 host tests, and the TUI tests, then bun run --cwd packages/omo-opencode typecheck. Separately, OpenCode 2.0.16 run --standalone --format json in a temporary HOME and XDG_* sandbox, with this package configured as a local plugin directory. The session used agent oh-my-openagent/Sisyphus - ultraworker and was asked to call session_list once.
    Observed result: 10 pass, 0 fail, 35 expect() calls. Typecheck exited 0. The server log recorded loading plugin with entrypoint index.js and did not record a missing-setup error. MCP servers connected: lsp (9 tools), context7 (2), websearch (1), grep_app (1). The tool result contained No sessions found. Agent markdown was written for the oh-my-openagent agents, including Sisyphus and oracle.
    Artifact: .omo/evidence/20260927-opencode-v2-load/unit.txt and load.txt (local only, not in the diff).
    Why sufficient: The unit tests pin the dual export, and the OpenCode 2.0.16 process shows the package loading, an OMO agent being selected, and session_list running.
6bd953b47e49a4f267d6e4667d6d5e24193656eff897cbf0ddefdfb91cc5600f  unit.txt
48dbb85bc0d58d9a0924817579b43a3b42e4f83716e5cb9d9e01ced43ba7744a  load.txt

Risks & Residuals

  • V2 has no toast API. Calls that used to show a toast are logged.
  • experimental.compaction.autocontinue has no V2 hook. It stays off, and startup logs that.
  • Codex, Senpi, and the desktop crates are unchanged.
  • The full root bun test and bun run test:codex were not re-run. Those trees are outside this diff. Accepted.

Automated Checks

bun run --cwd packages/omo-opencode typecheck
bun test packages/omo-opencode/src/index.export-shape.test.ts packages/omo-opencode/src/v2/host.test.ts packages/omo-opencode/src/tui.test.ts

Related Issues

Fixes #8485


Summary by cubic

Makes the oh-my-openagent plugin load in both OpenCode V1 and V2 from a single export. OpenCode V2 hosts rejected the previous { id, server } export shape with a missing setup error; the default export now also carries Plugin.define({ id, setup }) so V2 calls setup() while V1 keeps calling server() and tui().

  • Adds a packages/omo-opencode/src/v2/ host that runs the existing V1 pipeline through a context facade, translates V2 messages and events into V1 shapes, and projects tools, commands, MCP, skills, and providers into V2.
  • Fills the V2 client facade for live sessions: sessions are read from the OpenCode database, and the CLI run command can drive V2 through its client API.
  • Keeps todos, parents, toasts, compaction, and the sidebar working under V2, and writes agents as markdown because V2's agent editor can update and remove agents but not add them.
  • Adds @opencode/plugin 2.0.16 as a dependency of the root package.json and packages/omo-opencode, a root index.js that re-exports the built plugin, and an openchamber/ host with v2 SDK native-skills support.
  • V2 has no toast API and no experimental.compaction.autocontinue hook; those calls are logged and the setting stays off.

Fixes #8485.

Written for commit 502a4f0. Summary will update on new commits.

Review in cubic

V2 calls setup() from Plugin.define. V1 (1.18.29+) keeps calling server() and the TUI tui() function. The existing V1 pipeline stays in place and is projected onto V2 domains.
@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA. Thank you! ✅
Posted by the CLA Assistant Lite bot.

@SwarmStorm

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@github-actions github-actions Bot added the opencode OpenCode edition: packages/omo-opencode label Sep 27, 2026
github-actions Bot added a commit that referenced this pull request Sep 27, 2026
@SwarmStorm

Copy link
Copy Markdown
Author

Proof of life of the feature working:
image

The dual export loaded, but V2 messages, events, and session calls did not match the V1 pipeline. Translate those shapes, fill the client facade, and keep todos, parents, toasts, compaction, the sidebar, and the CLI working on V2.
@SwarmStorm

Copy link
Copy Markdown
Author

Follow-up on this branch: the first patch made one export load on OpenCode 1 and 2. Using it against OpenCode 2.0.16 showed the V1 pipeline still receiving V2 shapes.

This commit translates chat messages and events into the V1 info/parts and properties shapes, and fills the client methods the tools call: agents, providers, models, skills, config, and session create, prompt, list, status, children, and todos. Parent links are stored by the adapter because V2 create has no parentID. Todos and toasts are stored by the adapter because OpenCode 2 has no todo API and the server context has no toast. Manual compaction asks to continue once on the next idle; automatic compaction does not send a second prompt. The TUI claims the sidebar slot, the CLI uses the V2 session API when the server is V2, and an OpenChamber extension publishes toasts and incomplete todos.

On an isolated OpenCode 2.0.16 server, the plugin loaded, a prompt completed, and session_list returned a session that existed before the plugin loaded. The log had none of the previous failures: v2 hook failed, app.agents is not a function, or client has no equivalent.

@atheerium

Copy link
Copy Markdown

Proof of life of the feature working: image

what is this IDE / GUI you are using? which seems to detect OMO agents

@TomLucidor

Copy link
Copy Markdown

What is the set of things to do, for making v1 tools to become v2 compatible? Cus a lot of other OpenCode context management tools need migration

rubimpassos added a commit to rubimpassos/oh-my-openagent that referenced this pull request Sep 28, 2026
rubimpassos added a commit to rubimpassos/oh-my-openagent that referenced this pull request Sep 28, 2026
@maurerle

maurerle commented Oct 1, 2026

Copy link
Copy Markdown

I update this to latest dev here:
dev...maurerle:oh-my-openagent:feat/opencode-v1-v2-plugin

It works well with opencode v2.

@code-yeongyu

Copy link
Copy Markdown
Owner

Thanks for this work @SwarmStorm. A heads-up on direction: we're consolidating OpenCode V2 support on one additive dual-host shape (a separate src/v2/ entry exporting { id, setup, server } next to the V1 code, V1 behaviour untouched), landing as small reviewable slices with a runtime parity matrix as automated tests. The plan is in #9389, where @fazulfi offered a complete, production-tested port.

This PR explores the same single-export, dual-host direction, so you'd be very welcome to review the slices or co-author one. Where your work is reused, it will be credited in the changelog. I'm leaving this PR open for now; once the first slice lands we'll compare what this covers and close it with a pointer if it's fully covered.

@mradwankhalil

Copy link
Copy Markdown
Contributor

Bug report + fix for this branch's V2 hook bridge: SwarmStorm#1.

writeHookMessagesBack (src/v2/message-shape.ts) writes the edited V1 view back to the V2 context messages by index. Any messages.transform hook that inserts a message (team-mode status, monitor status and team mailbox injectors all do) shifts every later message's parts into its neighbour. When the latest user-role message sits between two tool steps (an instruction file pulled in by a read), the assistant's reasoning + tool-call parts land in a tool message, and OpenCode 2.0.28 rejects the request on every provider (… tool messages only support tool-result content for now, logged as Failed to drain Session) until the next user prompt.

The PR maps each view back to the message it came from (WeakMap) and adds tests that fail before the change. Reproduced from a real session's stored history; details in the PR.

gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 15, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 15, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
@mradwankhalil

Copy link
Copy Markdown
Contributor

The adapter as written removes user-registered namespaced MCP tools matching V1 false rules (including grep_app_*) from the shared registry for every agent, so even the librarian's explicit allow cannot recover them: #10237. Fix proposal and regression details: #10237 (comment).

The proposed guard uses native registered.options.namespace metadata to preserve shared namespaced registrations under both exact and wildcard false rules—not a name-spelling exception. Unnamespaced plugin/native removal stays unchanged, and MCP execution remains subject to host permissions; translating V1 defaults into per-agent V2 deny rules is a separate policy decision.

Since the V2 adapter is not on dev yet, I'm happy to open a focused PR against your branch if you'd prefer that to applying the change yourself.

@mradwankhalil

Copy link
Copy Markdown
Contributor

@SwarmStorm I checked your head 502a4f0f against current dev 2e41a503 in an isolated clone. The merge conflicts are only package.json and bun.lock, not adapter source. Upstream moved the old root runtime entries into devDependencies; the resolution retains that layout/current dependency graph and adds the external runtime @opencode/plugin: 2.0.16, then regenerates the lock with lifecycle scripts disabled.

I prepared a rebased copy in my fork, preserving your two commits, authorship and messages. Cherry-picks, in order: 36a21a96, a8d435b6. No extra adapter fixes are folded in; the non-manifest/lock source patch is unchanged. Your branch was not modified; nothing was force-pushed.

Verification: export/V2-host/V2-CLI tests 16 pass, 0 fail, and root typecheck passes. The additional TUI/state/SQLite group has two Windows EBUSY fixture-cleanup failures plus a leaked-temp teardown failure; the SQLite code is unchanged, but I have not rerun the original-head baseline. No build, full-suite or live-runtime validation claimed.

I know the additive dual-host slices in #9389 are the intended direction. Please use the branch/cherry-picks if useful; happy to help adapt the rebase to those slices or keep the #10237 registry follow-up separate.

gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 17, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 17, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 19, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 19, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 23, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 23, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 26, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 26, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 29, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Oct 29, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Nov 3, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Nov 3, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support
gdraganic pushed a commit to gdraganic/oh-my-openagent that referenced this pull request Nov 13, 2026
gdraganic added a commit to gdraganic/oh-my-openagent that referenced this pull request Nov 13, 2026
fork-sync rebuilt main on the head of upstream PR code-yeongyu#9016 while it was open,
which pinned the fork to the upstream commit that PR was based on. It now
rebuilds on upstream dev; the PR's commits carry the Fork-Patch trailer and
travel as patches. The sync also runs the prompt-route and Bun runtime audits.
Upstream workflows added since the previous base are dropped, as the sync
itself does.

Fork-Patch: v2-support

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

opencode OpenCode edition: packages/omo-opencode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: OpenCode V2 plugin API support

6 participants