fix: OpenCode 2.0.29 GA RPC compatibility and Windows support

AH
3d ago
+209-31

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

  1. 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 the changed event payload), which the newer host cannot encode, so every state/apply call failed with InvalidRequestError: Expected JSON value at ["output"] (and later rpc.invalid_output: Expected JSON value at ["accounts"]), leaving the /antigravity menu and sidebar without a snapshot.
  2. Windows build. verifyPrerequisites compared realpaths against a hardcoded /node_modules/ separator, and the library build called chmod.
  3. Windows CLI login. The browser opener passed the consent URL unquoted to cmd /c start, and cmd.exe splits it at the first &, dropping response_type; the CLI also wrote the retired pool file instead of the account store, and never printed the URL under --no-browser.
  4. Windows store write. writeTransfer fsynced a directory handle, which Windows rejects with EPERM: operation not permitted, fsync.

Changes

  • RPC wire contract — ga/rpc/protocol.ts, ga/server/index.ts: register a JSON Schema for each method's wire output and the changed event payload (inputs keep the strict Standard Schema), and strip undefined-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; skip chmod on Windows.
  • CLI login — packages/opencode/src/cli.ts, plugin/oauth-login.ts: quote the consent URL and pass windowsVerbatimArguments; print the authorization URL when the browser is not opened; persist through the account store with commitLogins.
  • Core — packages/core/src/account-repository.ts: skip directory fsync on Windows (the file is still flushed).
  • Docs — README.md (required providers.google entry) and CHANGELOG.md.

Testing

  • bun test --isolate src/ga → 156 pass, 0 fail, including the new rpc-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.
    • /antigravity command 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 google provider, so a host that does not expose one now needs the documented providers.google entry.
  • core.autocrlf must be false so 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 output and changed event 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 of undefined-valued keys. state/apply calls previously failed with InvalidRequestError / rpc.invalid_output, leaving the /antigravity menu 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, losing response_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 google provider, so hosts without one must configure it; the README documents the required providers.google entry.