| title | opencode 2 | ||
|---|---|---|---|
| description | The same package on opencode 2.x: config spellings, a local checkout, and what differs from 1.x. | ||
| sidebar |
|
The same package runs on opencode 1.x and 2.x, and nothing changes for 1.x. The same config works too: opencode 2's native key is plugins, but it still reads the 1.x plugin key shown above, so an existing install needs no edit. A config used only by opencode 2 can spell it natively:
{
"plugins": ["@khalilgharbaoui/opencode-claude-code-plugin"]
}opencode plugin add @khalilgharbaoui/opencode-claude-code-plugin writes that entry and installs the package for you. With no accounts the provider is named Claude Code, id claude-code, so a model's full id is claude-code/claude-haiku-5-5. On opencode 2.1.4, opencode plugin list prints No plugins found even while the plugin is loaded, and opencode plugin check and opencode plugin update do not see it; /claude-code-doctor or opencode models | grep claude-code is the check, and the package cache to clear after a release is ~/.cache/opencode/npm/@khalilgharbaoui/opencode-claude-code-plugin@latest (see Longer cases).
Your existing provider.claude-code.options block keeps working, because opencode 2 still reads 1.x config files. opencode 2's own spelling is providers.claude-code.settings (note the plural providers). All four places the plugin reads its settings from, lowest precedence first: provider.claude-code.options, provider.claude-code.settings, providers.claude-code.settings, and the plugin entry's own options, which wins over all of them. Plugin-level settings such as accounts usually go in that last one: {"package": "@khalilgharbaoui/opencode-claude-code-plugin", "options": {"accounts": ["work"]}}.
For a local checkout, point opencode 2 at the dist directory, not the repository root. It loads <dir>/server or <dir>/index from a directory and never reads package.json#main:
{
"plugins": ["/absolute/path/to/opencode-claude-code-plugin/dist"]
}/connect and the retry opt-out were measured on opencode 2.2.5 (2026-10-31) with Claude Code 2.1.314. Last checked on opencode 2.1.3 (2026-10-23): a chat turn, a proxied shell call, one of Claude's own tools, a session opened in a subdirectory of a project, and a second prompt reusing the same claude process. First verified live on opencode 2.0.11 with Claude Code 2.1.280: chat turns, proxied tools running through opencode 2's own shell, edit, write, webfetch and subagent tools and their permission rules, Claude's own tools rendered in the transcript, subagent dispatch with the agent list, reasoning variants, compaction, account providers, /claude-code-doctor, /btw, and the bundled configuration skill.
opencode 2 gives a plugin no way to ask whether a session is busy and no toast of its own, so the plugin reads opencode 2's event stream for the first and uses the channel opencode 2 gives a plugin between its two halves for the second. With those, these work as they do on 1.x (measured on 2.0.22 and 2.0.31):
/btwis answered inside the running turn. opencode 2 runs the command the moment you type it, so the aside goes to Claude at once and the answer lands in the reply you are watching. Only when the turn has nothing open to write into does a/btwmessage follow, queued, once the turn ends. See/btw.- A permission prompt does not count against a proxied call's deadline. While opencode is still running the turn, because it is waiting on you or the tool is still working, a proxied call that passes its deadline is kept.
- Stopping a turn releases the proxied calls it was waiting on, and interrupts Claude's own turn, instead of leaving them until your next message.
- The plugin's warnings appear as toasts titled
claude-code, raised by the sidebar half. See Logging.
opencode 2 also has two things 1.x has no counterpart for:
/connectchecks the Claude Code login. Each provider (Claude Code, or one per account) is listed under its own name with one method, Claude Code login. Connecting stores nothing, not even a token: the plugin runsclaude auth statusthe way a turn would runclaude, and a toast says how Claude Code is logged in (a Claude subscription, an API key, Amazon Bedrock, Google Vertex AI, ...) or gives the one command that fixes it,claude auth login, orCLAUDE_CONFIG_DIR=~/.claude-work claude auth loginfor an account namedwork. A missing or logged-out CLI also marks the connection Sign in required; log in in a terminal, then connect again. Connecting is optional, the models work without it, and every connect adds one entry to that provider's list of connections, which you can delete from the same dialog. A connection made earlier is checked again when opencode starts.- A failed turn is not retried. opencode 2 runs a turn that failed again, up to ten more times. For this provider each retry started a new
claude, resumed the conversation and sent your message again: one CLI killed mid-turn cost eleven API requests and left the message in the conversation twelve times. The plugin declines those retries, so the error shows once and you resend when you are ready. The Claude CLI already retries API errors (overloaded, server errors, rate limits) itself, and a usage limit was never retried.
Differences from 1.x:
- A subagent can be given its own model in the conversation. opencode 2's
subagenttool takes amodel, so "run the reviewer on Sonnet" reaches it, and the plugin keeps that choice over an agent'sforceModel, itsreasoningEffort(for a named variant) and the dispatch form. opencode 1'stasktool has no such field. See A model you name in the conversation. - No todo panel. opencode 2 has no
todowritetool, so Claude's task list is not mirrored into one, and the sidebar's progress bar is always the time estimate, never a share of todos done. bridgeMcpOauthTokensfinds nothing. opencode 2 keeps MCP OAuth tokens in its database, and the plugin API can activate a stored credential but not read one, so a server you signed into through opencode still reportsneeds-authto the Claude CLI. See MCP bridge.- Claude's
EnterPlanMode,ExitPlanModeandNotebookEditcalls get no tool row. opencode 2 has no tools of those names and rejects an unknown one, so the plugin leaves the row out. The call itself still runs. - Forms are opencode 2's own
Formsurface rather than a question tool, which changes nothing you do: pick an option as usual. The account-switch form and the plan-mode approval were measured live on 2.0.22 (2026-10-07), and the subagent dispatch form on 2026-10-08. - An account switch, by hand or through the form, carries the conversation on opencode 2 exactly as on 1.x, and
accountGroupsblocks it exactly as on 1.x. Both measured live on 2.0.22 (2026-10-08). - A session opened below the project root spawns
claudein that directory. Before 0.55.0 the plugin appended opencode 2's project-relativesubpathto the session's own directory and spawned in a path that does not exist, so every turn of such a session failed withENOENT ... posix_spawnwhile a session at the root worked (issue #113). Acwdset only to work around that can go.