Skip to content

fix: support OpenCode v2 alongside v1 - #274

Merged
xxchan merged 1 commit into
mainfrom
fix/opencode-v2
Oct 9, 2026
Merged

xxchan merged 1 commit into
mainfrom
fix/opencode-v2

Conversation

@xxchan

@xxchan xxchan commented Oct 9, 2026

Copy link
Copy Markdown
Member

OpenCode v1 and v2 share the same executable name but differ in control, configuration and child-event behavior. Select the adapter from the installed release line: v2 omits steer, queues through the existing helpers, attributes forwarded child frames to their native sessions, and refuses prompt options that cannot be applied safely. v1 retains prompt injection and same-turn steering.

The shared ACP layer keeps immediate steering acceptance and records a later native refusal as input_dropped with runtime_refused. The current turn keeps its own outcome, including when refusal arrives during a later turn; Grok's replacement-prompt semantics remain intact.

v2 model queries use only --standalone. Empty output reports unsupported and links upstream #53724, without creating a native session or persistent service. Native shell, subagent and execute names are retained, with command classification for shell.

Validation: nine real boundary checks each on OpenCode 1.18.35 and 2.0.26 with the free Big Pickle model; real Grok 1.0.50 steering; all five shared behavior backends; recorded v2 child-frame and MCP-through-execute replay, plus native refusal/order regressions. The native observations, source boundaries and model-query limitation are documented in experiments/opencode-v2-2026-10-09.md.

Closes #271.

@xxchan
xxchan merged commit 75afa0f into main Oct 9, 2026
17 checks passed
@xxchan
xxchan deleted the fix/opencode-v2 branch October 9, 2026 13:24
@xxchan xxchan mentioned this pull request Oct 9, 2026
xxchan added a commit that referenced this pull request Oct 9, 2026
Release OAR and CLI 0.48.0. This PR changes only the two package version
fields.

**Added: `Runtime.installPlan()` and `Runtime.install()`** (#275, closes
#268)
- `installPlan(options?)` is read only: the steps `install()` would run
here (the vendor's own documented installer, with its own
non-interactive switch), the source page, `network: true`, `privileges:
false`; or why it would run nothing.
- `install(options?)` runs that installer only when the runtime's probe
finds no installation, and judges the outcome by the probe afterwards,
never by the installer's exit code: `installed { installation, line?,
output }`, `already_installed`, `failed { exitCode, output }`, or
`unsupported { reason, detail }` with `platform`, `requires_privileges`
(never sudo), `requires_gui` (antigravity), `missing_tool`, `bundled`,
`line_required`, `unknown_line`.
- claude, codex, grok and kimi use each vendor's native installer,
chosen so `checkUpdate()`/`upgrade()` recognize the copy. opencode
declares `installLines` (`v1`, `v2`): a host must choose one, and an
install never replaces a copy of the other line.
- The claude and codex probes now also look where their installers put
the launcher (`~/.local/bin`), which a service process's PATH can miss.
- macOS and Linux (x64 verified on a fresh VM, arm64 in a sandbox); on
Windows the plan names the vendor's PowerShell command and runs nothing.

**Fixed: OpenCode v2 alongside v1** (#274, closes #271)
- One runtime `opencode` follows the installed line. On v2: no `steer`
member (v2 refuses a second prompt; `steerOrQueue` and `deliver` queue),
forwarded child-session updates become the child's own records and graph
edge (attribution `nested`), `appendSystemPrompt` and `systemPrompt` are
refused at open with the reason (v2 has no verified session-local
channel), and `listModels` reports `unsupported` while v2's `models
--standalone` returns an empty catalog (anomalyco/opencode#53724).
- Every ACP runtime: a steer the runtime refuses after it was accepted
is now `input_dropped { reason: "runtime_refused" }`, handing the input
back, and no longer ends the running turn as `failed`.

**Fixed: Codex command output previews** (#277, closes #261)
- `tool_call_progress` has a new field `outputDelta`, appended to the
preview; `output` stays a replacement snapshot (pi, ACP, Pi Durable).
Codex reports its command output as `outputDelta`, so SessionView now
shows the whole output instead of the last chunk.
- Codex `turn/started` and pi `agent_start` report `turn_active`, so a
turn the runtime started on its own shows as running before its first
content.

**Behavior changes**
- Codex `tool_call_progress` carries `outputDelta` instead of `output`.
A host that folds tool progress itself must append it.
- `input_dropped.reason` and `ConversationInput.reason` gain
`runtime_refused`.
- OpenCode v2 sessions have no `steer`, and refuse `appendSystemPrompt`
and `systemPrompt` at open (not in the static `refusedSessionOptions`,
which v1 still answers).

Validation: each PR passed all checks on its final head; #274's merged
tree equals its CI tree, and #275 and #277 were each re-verified locally
(typecheck, lint, full tests) on the main they merged into, whose merged
trees equal those verified trees. After this PR passes CI and merges,
tag its exact squash commit as `v0.48.0` to trigger npm trusted
publishing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: exe.dev user <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
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.

opencode v2 (2.0.x) alongside v1: steer refusal, silent appendSystemPrompt, child sessions, listModels

2 participants