Skip to content

chore(opencode): qualify and recommend runtime 2.2.1 - #1188

Merged
pascalandr merged 1 commit into
devfrom
chore/qualify-opencode-2.2.1
Oct 29, 2026
Merged

pascalandr merged 1 commit into
devfrom
chore/qualify-opencode-2.2.1

Conversation

@pascalandr

@pascalandr pascalandr commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Qualify OpenCode 2.2.1 (latest stable, 29 October) with the existing locked 2.1.0 client/plugin dependencies, and recommend it.
  • Keep the technical minimum at 2.1.2: no consumed contract changed, so the minimum has no new reason to move.
  • 2.1.2, 2.1.4 and 2.2.0 daemons stay ready and get an optional upgrade offer. 2.2.1 is the tested version. Newer and custom labels keep authenticated contract recognition.
  • The reviewed-contract fast path lists the 2.1.2 minimum and the 2.2.1 target.
  • The recommended version is updated in the help (all ten locales), both READMEs, CONTRIBUTING.md, dev-docs/OPENCODE_COMPATIBILITY.md and the architecture skill.

Contract review (v2.1.4 → v2.2.0 → v2.2.1; 661 + 134 commits)

Reviewed from the exact tags v2.1.4 (68bc26b7da), v2.2.0 (1097e2668b) and v2.2.1 (3ebcf9a32c), the published npm packages, and an authenticated OpenAPI dump from each official CLI running in its own sandbox. The changelog covers 2.2.0. It had no 2.2.1 entry at review time (29 October), so 2.2.1 was reviewed from its commit log.

  • Authenticated OpenAPI: 124 → 130 → 134 paths, 149 → 156 → 162 operations. Each dump matches the tagged packages/protocol/openapi.json.
    • 2.2.0 adds GET /api/plugin/gui; POST /api/experimental/generate/{text,image,decisions}; POST/DELETE /api/experimental/fs/watch; GET /api/experimental/media/{hash}; and GET /api/experimental/usage/limits.
    • 2.2.0 removes POST /api/experimental/voice/session/{sessionID}/instructions.
    • 2.2.1 adds six /api/experimental/schedule operations (list, create, get, delete, pause, resume), gated by experimental.schedules.
    • Changed operations:
      • GET /api/model gains an optional types filter. Without it the route lists chat models only. Image and decision models are new in 2.2.0, so the default listing matches 2.1.4.
      • GET /api/event gains an optional types filter.
      • GET /api/vcs/diff gains an optional untracked parameter.
      • POST /api/experimental/generate becomes the deprecated alias of /generate/text.
      • Nine session, project and saved-permission routes drop LocationNotFoundError from their 404 responses: they no longer boot a Location (#58997).
      • GET /api/agent can now answer 503 while plugins settle (#59082).
      • In 2.2.1, the session log and persistent-PTY operation IDs move under experimental.*. Their paths are unchanged.
    • Schemas: all 103 consumed-family schemas are byte-identical from 2.1.4 to 2.2.1. These are V2EventEncoded, Session.* (messages, parts, inbox, info), Form.*, Permission.*, Prompt*, Event.*, Location.* and PTY/Shell. The session prompt, environment, message, form/permission reply and RPC operations are unchanged too. The only Config.InfoEncoded changes are additive opt-ins: experimental.media_blob, experimental.image_generate, experimental.schedules and timezone. Model type, prompt-cache cache settings, FileDiff.Info.more, Mcp.Server.title and ServerInfo.hostname are additive fields.
    • Admission: every predicate CodeNomad's compatibility/negotiate.ts checks holds on 2.2.0 and 2.2.1. That covers the canonical API, session_environment and the 2.1 replay shape (native without state, compaction metadata without recent).
    • Instance proxy: none of the new routes is on the allowlist. That includes the GUI plugin bundle, generation, file watch, media blobs, usage limits and schedules. The removed voice route was never exposed. The routes CodeNomad does proxy kept their paths.
  • Published declarations (2.1.0 pins → 2.1.4 → 2.2.1):
    • Client: 143 → 147 → 185 methods. 2.2.1 mirrors the experimental methods under client.experimental.*. The only removal is voice.instructions, which CodeNomad doesn't use. 2.2.1 doesn't send the experimental-media-uri capability, so media reads stay inline.
    • Schema: 2.2.0 adds media refs (MediaRef, Session.Message.MediaUser, inbox MediaUserPayload), generate, usage-limits and Model.Type. 2.2.1 adds goal and schedule. The one removal since 2.1.0 is SessionEvent.Source (2.1.4).
    • Plugin: 2.2.0 adds the gui/* SDK (excluded from the host runtime) and Host.packageID. 2.2.1 adds SessionIdle/SessionIdleBackground. The event subscribe domain gains an optional types filter; CodeNomad's plugins don't subscribe through it.
    • Typecheck: the server and UI typecheck with 0 errors against the 2.1.4 and 2.2.1 client/schema/plugin declarations, through scratch paths overrides. The pinned 2.1.0 control is also clean.
    • Host modules: CodeNomad's three daemon-loaded bundles resolve @opencode/plugin (Plugin), /effect (Plugin, Rpc, Location), /promise/adapter (fromPromise), /rpc (Rpc), effect and effect/encoding (Base64Url) from the host. @opencode/schema and @opencode/client are bundled from the 2.1.0 pins, and @opencode/schema/location imports are type-only. A probe plugin loaded in an isolated 2.2.1 daemon resolves every one of these modules and bindings, as on 2.1.4. The host Effect stays 4.0.1, with the same lockfile hash.
  • Private native services: the pending-request reader and Missions recurrence use keyed native services: LocationServiceMap, Form, Permission, Location, Job, Database, Session and Bus. Their keys are unchanged at v2.2.1, and the members CodeNomad calls are unchanged. The changes are additive: Permission.assertNotDenied, Session.*WithRefs, an image Job kind, and LocationServiceMap.canonical normalizing paths.
  • Storage (migrations from 2.1.4 to 2.2.1): blob/blob_ref (always created; written only with experimental.media_blob) and schedule are new. session_pending is dropped; CodeNomad never reads it. A session_v2.allowance column is added and dropped within 2.2.0.
    • The tables CodeNomad reads directly (session_message, session_v2, session_inbox, event, event_sequence, kv) keep their shape.
    • The pruning plugin's media-blob.ts already projects media:<sha256> refs.
    • The pruning fixture enables media_blob explicitly, so the always-present blob table doesn't change its expectation.
    • Missions reads session_inbox only by count and ID in production code.
  • Behavior changes checked:
    • Code Mode: 2.2.1 moves programs onto one job queue (#57976). The run-to-completion regression behind the 2.1.2 minimum passes on 2.1.4, 2.2.0 and 2.2.1: { total: 2000, beforeAwait: 1000, count: 1000 }.
    • Session form polling returns [] without booting a cold Location (#59083). Forms are in memory, so nothing pending is hidden. This matches CodeNomad's existing-only pending reader.
    • Location keys and session.create directories are canonical on POSIX too: trailing slash removed, posix.normalize (#59327). Windows already normalized. This is low risk; it was reviewed in source only, since the location and ownership fixtures run on Windows and the POSIX certification covers migration, Code Mode and Git-degraded.
    • Location keep-alive: the changelog line "keep project services alive … with a 24-hour inactivity cap" (#57274) doesn't match the shipped tree. That commit was superseded before 2.1.4, and no cap exists at v2.2.0 or v2.2.1. From 2.1.4 to 2.2.1, location-activity.ts only canonicalizes paths and generalizes Job kinds. Long-waiting Missions sessions keep their Location as on 2.1.4.
    • Plugin readiness: each runner step and tool call now waits for plugin activation (#51133), and agent/provider lists wait for plugins. Presence leases stay outside the discovery root, so this adds no reload.
    • Service lifecycle: registration and config renames are retried on Windows. The managed service ignores a saved XDG_STATE_HOME (#58815); CodeNomad never sets it. The OPENCODE_SERVER_USERNAME change was added and reverted within 2.2.0. Detached POSIX children are killed when OpenCode exits; service start uses its own spawn path.
    • 2.2.1 opt-ins:
      • schedules, both the API and the agent tool, need experimental.schedules;
      • image_generate needs experimental.image_generate;
      • /goal runs only when invoked;
      • the subagent tool description now invites follow-ups to running subagents, with the same mechanics as 2.1.4.
    • Other changes: compaction sizing from the provider's count, MCP malformed-tool tolerance, OAuth refresh coordination (#54023) and webfetch redirect rules. They touch no consumed contract and were reviewed in source; of these, the native suites exercise compaction only.
    • Upstream #52922 (Bus routing before Location fanout) is still open: keep the discovery and event-relay mitigations.

Verdict: no consumed contract changed from 2.1.4 to 2.2.1.

  • The 2.1.0 client/plugin pins can stay.
  • The 2.1.2 minimum has no reason to move.
  • 2.2.1 is admitted through the existing contract recognition, and nothing found blocks recommending it once the native suites pass on it.
  • No CodeNomad bug was found.

Bumping the pins is optional. It would bring the 2.2 client's discard-tool-result-payload option and its "register running sessions missed while disconnected" fix (#53012). It would also move the replay reducer, so it belongs in its own PR. The UI and server already typecheck against 2.2.1.

Not verified here:

  • the full native suites against 2.2.0/2.2.1 (only the Code Mode regression and the host-module probe ran);
  • the TUI pruning companion under OpenTUI 0.7. It uses only Plugin.define, ctx.data.session and ctx.data.listen, so the 0.7 renderable changes don't apply, but this wasn't run;
  • POSIX canonicalization on a real Linux/macOS runtime;
  • the 2.2.1 release notes, which were unpublished at review time.

Isolated Windows qualification

Base: dev 157766206; Node 25.2.1 (local; CI runs the pinned 24.20.0); exact official CLI 2.2.1; unchanged locked client/plugin 2.1.0.

  • Build and checks: production server and native plugin builds (pruning, automation, Missions), root typecheck.
  • Native runtime: Code Mode job ordering ({ total: 2000, beforeAwait: 1000, count: 1000 } on 2.2.1), plugin runtime, automation; complete pruning, history, proxy, navigation and media; Location, worktree families/management and event relay; permission receipts; Git init/degraded.
  • Missions: contract, family control, native and trajectory; all 11 recurring Mission journeys (ABCDGELFWQN).
  • Sessions: environment, fork, aside, interrupt, lifecycle, blank cleanup (--conditions=browser, as in CI), compaction isolation, prompt skills, provider usage/accounts/selection, service usage, web search, plugin packages, output limit, Promise-tool failure, subagent depth, temporary workspaces.
  • Migrations: history from 2.1.0, 2.1.2, 2.1.4 and 2.2.0 to 2.2.1.
  • Installation: fresh install, native upgrade and legacy replacement fixtures.
  • Units after the recommendation change: compatibility/transport/update 35/35; full server 2,628 passed, 8 skipped, 1 cancelled (index.test.ts shutdown test timed out at 5 s under full-suite load and passes 4/4 alone); ten-locale help checks pass.

In CI, latest resolves to 2.2.1: the compatibility job runs the native suites against the minimum and latest on Windows, and the migration and Git-degraded certification runs them on Ubuntu, Windows and macOS. WSL, packaged desktop, installers/updater end-to-end and real mobile devices keep their separate release gates.

OpenCode 2.2.1 is the latest stable release. Its authenticated OpenAPI, published client/schema/plugin declarations and host plugin modules keep every contract CodeNomad consumes: the 103 consumed schemas are byte-identical from 2.1.4, admission predicates hold, and new routes stay off the proxy allowlist.

The recommendation moves to 2.2.1; the 2.1.2 minimum and the 2.1.0 client/plugin pins stay. 2.1.2, 2.1.4 and 2.2.0 daemons remain ready with an optional upgrade offer, and the reviewed-contract fast path lists 2.1.2 and 2.2.1. Help in all ten locales, both READMEs, CONTRIBUTING.md, OPENCODE_COMPATIBILITY.md and the architecture skill name the new recommendation.

Validation: every native suite against the exact 2.2.1 CLI on Windows (Code Mode, plugins, pruning, Missions and all recurring journeys, sessions, providers, migrations from 2.1.0/2.1.2/2.1.4/2.2.0, install/upgrade/legacy replacement), compatibility units 35/35, full server units, and the ten-locale help checks.
@pascalandr

Copy link
Copy Markdown
Contributor Author

Gatekeeper review

Round 1: no code or documentation defects. Every recommendation reference moved to 2.2.1 consistently across code, tests and all ten help locales; historical references (e.g. session-identity fixtures) are intact, and the scope matches #1126. Compatibility/transport/update units pass 35/35. Admission accepts the saved 2.1.4, 2.2.0 and 2.2.1 runtime schemas, and all 14 new operations stay outside the proxy allowlist.

Two P3s on the PR body, both fixed:

  • POSIX path canonicalization was described as covered by Ubuntu/macOS location fixtures, which run on Windows only; now stated as source-reviewed.
  • OAuth refresh coordination and webfetch redirects were described as covered by the native suites; now stated as source-reviewed, with compaction the only change the suites exercise.

Round 2: both P3s resolved; compaction coverage confirmed (scripts/test-compaction-isolation-native.mjs and the 2.2.1 qualification log).

ZERO FINDINGS

@pascalandr
pascalandr merged commit ca514ed into dev Oct 29, 2026
24 of 39 checks passed
@pascalandr
pascalandr deleted the chore/qualify-opencode-2.2.1 branch October 29, 2026 14:04
shantur added a commit that referenced this pull request Oct 29, 2026
…ixes (#1192)

# CodeNomad 1.0.1 - Steadier Missions, ranked history search and Linux
fixes

CodeNomad 1.0.1 removes the Missions project limit, makes mission states
easier to read, and adds relevance-ranked search across a project's
history. It also fixes transcripts and questions that could stay stale
after a dropped connection, and fixes Linux AppImage display and F11
problems.

## Missions

- A project is no longer limited to 20 missions, and storage limits now
apply to each mission rather than the whole project. Deleted missions
release their storage once their cleanup is done, and the Missions panel
loads closed missions as lightweight summaries, so long mission
histories stay fast (#1170, #1173, #1175, #1176, #1177, #1178, #1180).
- Mission colours now follow the session list: red when an answer is
needed, pulsing yellow for running work, orange for interrupted or
paused missions, green for an unseen completion, and blue for a prepared
mission that hasn't started. The collapsed chevron only signals answers,
running work and unseen completions (#1150, #1155).
- A coordinator can no longer end a one-time mission as failed on its
own. When it can't continue, it asks you; a mission that stalls shows as
**Interrupted** and can be resumed with **Recover interrupted mission**,
including previously failed missions (#1150, #1151).
- The creation form now takes up the whole Missions panel and includes
the project's subagent nesting depth. An unsent draft is kept when you
switch right-panel tabs or projects (#1142, #1155).
- Fixed recurring missions never starting on OpenCode 2.2.0. A failed
first start of a recurring run now shows a warning right away and
retries after 30 seconds (#1158, #1171).
- Fixed missions on OpenCode Zen's free models being refused at the
coordinator's first request because of the mission session identifier
format (#1133).
- Fixed nested subagents stopping at depth 1 when a project config was
left with an empty `experimental` block. **Inherit** now removes that
empty block, and the shown depth matches what OpenCode applies (#1153).
- The help now explains that a running one-time mission keeps going in
OpenCode while CodeNomad is closed, and lists what waits for the backend
(#1137).

## History and search

- In the transcript search window, project-wide search now ranks results
by relevance (rare words weigh more, exact phrases first, one result per
conversation before repeats) and highlights every term. Conversation
search stays chronological (#1161, #1164).
- Project search scans the most recent 16,384 messages first, shows up
to 40 results, and can search further back in older history (#1182).
- Agents can search the project's past sessions themselves with the
`session_search` Code Mode tool, which stays limited to the calling
session's project (#1161, #1182).
- History, cleanup and attachment views now read files stored with
OpenCode 2.2.0's opt-in media blobs correctly. Before, cleanup could
report a false conflict and attachments could look unavailable (#1172).

## Transcript and connection reliability

- Opening a session that is already generating (after a restart, or from
a subagent box) now shows its transcript and keeps streaming, instead of
staying empty or frozen (#1156, #1181).
- Tool rows that stayed "pending" after a missed event now settle on
their own, including when the turn ended during a disconnect. A queued
prompt delivered during a disconnect now appears in the transcript
(#1169, #1184, #1187).
- Missed questions now appear within seconds on unstable connections,
such as a phone going through a tunnel. CodeNomad reconnects a stream
that has gone silent, rechecks when the network comes back or the app
returns to the foreground, and fetches a question the transcript shows
as running when its form never arrived (#1162, #1165).
- New session now shows a spinner while it is being created on a slow
network. Repeated clicks or shortcuts no longer create duplicate
sessions, and a failure shows an alert (#1157).
- Sessions and permission requests of a repository opened as its own
project no longer show up in a parent folder's project (#1174).
- Session alerts, such as a usage-limit error, no longer appear a second
time in the Preferences window (#1163).

## Panels and previews

- When the window narrows, each panel shrinks once and then hides, and
widening restores the same layouts in reverse. A panel that loses its
room closes and comes back when the room returns. On phones and narrow
windows, picking a session from the floating session panel closes the
panel (#1144, #1149).
- The active project tab can grow to 300 px so long project names fit
(#1166).
- Clicking a `localhost` link in a conversation opens it in the
session's web preview; Ctrl+click (⌘-click on macOS) or middle-click
still opens your browser. Apps that use `localStorage`, `sessionStorage`
or cookies now work inside the preview (#1119).
- Paired Remote Control devices can now use web previews, controlled by
a new **Web previews** switch in Remote Control settings (on by
default). SideCar connections now refuse requests from sandboxed pages
(#1131, #1135).

## Desktop and Linux

- Fixed a black window in the Linux AppImage on up-to-date systems: the
AppImage now uses the system's display libraries (#1138).
- Fixed F11 freezing the Linux app under X11/XWayland (#1143).
- The CodeNomad server package now starts when installed with pnpm
(#1186).

## Upgrade

OpenCode 2.2.1 is now the recommended runtime; 2.1.2 remains the
minimum, and 2.1.2, 2.1.4 and 2.2.0 keep working with an optional
upgrade offer (#1188).
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.

1 participant