fix: OpenCode 2.0.29 GA RPC compatibility and Windows support
AH
3d ago+209+209+012345678901234567890123456789-31-31-01234567890123456789
Summary
Makes the GA (OpenCode 2.x) adapter work on the current 2.0.29 host and on Windows, and fixes the standalone CLI login. Verified end-to-end against OpenCode 2.0.29 on Windows.
Root causes fixed
- GA RPC never answered on 2.0.29. OpenCode 2 serializes an RPC method's answer through the registered schema. The adapter registered its strict Standard Schemas as each method's wire
output(and thechangedevent payload), which the newer host cannot encode, so everystate/applycall failed withInvalidRequestError: Expected JSON value at ["output"](and laterrpc.invalid_output: Expected JSON value at ["accounts"]), leaving the/antigravitymenu and sidebar without a snapshot. - Windows build.
verifyPrerequisitescompared realpaths against a hardcoded/node_modules/separator, and the library build calledchmod. - Windows CLI login. The browser opener passed the consent URL unquoted to
cmd /c start, andcmd.exesplits it at the first&, droppingresponse_type; the CLI also wrote the retired pool file instead of the account store, and never printed the URL under--no-browser. - Windows store write.
writeTransferfsynced a directory handle, which Windows rejects withEPERM: operation not permitted, fsync.
Changes
- RPC wire contract —
ga/rpc/protocol.ts,ga/server/index.ts: register a JSON Schema for each method's wireoutputand thechangedevent payload (inputs keep the strict Standard Schema), and stripundefined-valued keys from every answer. The strict contract still runs inside the handler and in the client's own parse. - Windows build —
packages/opencode/scripts/build-tui.ts,tools/common-auth-build/build.mjs: use the platform separator for containment checks; skipchmodon Windows. - CLI login —
packages/opencode/src/cli.ts,plugin/oauth-login.ts: quote the consent URL and passwindowsVerbatimArguments; print the authorization URL when the browser is not opened; persist through the account store withcommitLogins. - Core —
packages/core/src/account-repository.ts: skip directory fsync on Windows (the file is still flushed). - Docs —
README.md(requiredproviders.googleentry) andCHANGELOG.md.
Testing
bun test --isolate src/ga→ 156 pass, 0 fail, including the newrpc-json.test.ts.- Biome clean on all changed files.
- End-to-end on Windows + OpenCode 2.0.29:
POST /api/rpc/antigravity-auth/state→200 { output: … }for both session and sessionless scopes./antigravitycommand registered.opencode run -m google/antigravity-gemini-3.8-flash "Reply with exactly: OK"→OK.
Notes
- The full package suite has pre-existing Windows environment failures unrelated to this change: tests create directories under
%TEMP%, which the private-files policy rejects as writable-by-others, plus POSIX-mode and native-prebuilt checks. - The GA adapter attaches its catalog to the host's
googleprovider, so a host that does not expose one now needs the documentedproviders.googleentry. core.autocrlfmust befalseso the embedded-manifest hash check passes; that is a checkout setting, not part of this change.
Summary by cubic
Makes the OpenCode 2.x GA adapter work with OpenCode 2.0.29 and on Windows, and fixes the standalone CLI login.
Bug Fixes
- The adapter's strict Standard Schema wire
outputandchangedevent payload could not be serialized by OpenCode 2; they now use a permissive JSON Schema while inputs keep the strict validator, and every answer is stripped ofundefined-valued keys.state/applycalls previously failed withInvalidRequestError/rpc.invalid_output, leaving the/antigravitymenu and sidebar without a snapshot. - The Windows build used POSIX path separators and
chmod; both now respect the platform. - The Windows CLI login passed the consent URL unquoted to
cmd /c start, losingresponse_type; the URL is now quoted. Logins also persist through the account store instead of the retired pool file, and the URL is printed when the browser isn't opened. - The account store no longer fsyncs directory handles, which Windows rejects with
EPERM.
Migration
- The adapter attaches its catalog to the host's
googleprovider, so hosts without one must configure it; the README documents the requiredproviders.googleentry.