Skip to content

fix(desktop): recover failed beta servers and clean unused CLI stages - #57321

Open
kitlangton wants to merge 1 commit into
betafrom
beta-adopt-server
Open

kitlangton wants to merge 1 commit into
betafrom
beta-adopt-server

Conversation

@kitlangton

@kitlangton kitlangton commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Why

Follow-up to #57309 based on review findings:

  1. With version: undefined on beta, decide() in @opencode/client/service never replaced a failed (500) or timed-out (503) server from an older beta build.
  2. Skipping cleanStages when adopting an existing server left older ~200 MB staged CLI directories accumulating under userData/cli/<version>-<arch>.

What Changes

  • Retry Service.ensure once with version: cli.version when an unpinned beta ensure fails with "Background service failed to start" or "Timed out waiting for the background service to start", while keeping 404 protocol incompatibility as a startup error.
  • Always run cleanStages on initial launch when the running server's version is known from file ?? client.fallback(), passing keep: keptStages(cli.version, runningVersion) so both the bundled stage and the running server's stage stay on disk while older stages are removed. If reading the registry fails (runningVersion undefined), skip stage cleanup so an adopted server's stage is never deleted.
  • Keep reconnect using serviceVersion(...) (undefined) so auto-reconnects (for example after sleep/wake or SSE drop) never replace a healthy adopted server. Follow-up: add an explicit in-app restart button and an API revision handshake on /api/info to detect protocol skew directly.
  • Simplify sidecar-probe.ts to const version = CHANNEL === "beta" ? undefined : bundledVersion(); if (version === "") return. Note for rebasing with feat(desktop): preserve Drive-managed development state #57112: background-service.ts should use drive ? undefined : serviceVersion(...) when those lines meet.
  • Trim cli-version.test.ts to 33 lines (serviceVersion, keptStages, and shouldRetryEnsure tables).

Decision Table

Channel Registered service state (/api/info) Version vs bundled CLI Outcome
beta Healthy (200, { version, pid }) Older, matching, or newer Adopt (reuse), keep bundled + running stages, clean older stages
beta Starting (503, { version, pid }) Older, matching, or newer Wait (wait), then adopt; if startup times out, retry with cli.version (replace)
beta Failed (500, { version, pid }) Older or newer Initial fail retries once with cli.version → replace (clear)
beta Missing, unreachable, wrong PID, or 3x timeout Any Start bundled CLI (replace / spawn) and clean unused stages
beta Incompatible protocol (404 on /api/info) Any Preserve running server and show in-app startup error (localServerStartup)
prod (stable) Healthy (200, { version, pid }) Matching Adopt (reuse)
prod (stable) Healthy, starting, failed, or 404 Older or newer Replace with bundled CLI (replace)

Scope

  • packages/client/src/promise/service.ts
  • packages/desktop/src/main/service/cli-version.ts
  • packages/desktop/src/main/service/cli-version.test.ts
  • packages/desktop/src/main/service/cli-stages.ts
  • packages/desktop/src/main/service/cli-stages.test.ts
  • packages/desktop/src/main/service/desktop-cli.ts
  • packages/desktop/src/main/service/sidecar-probe.ts
  • packages/desktop/src/main/service/background-service.ts

Verification

  • bun test src/main/service/cli-version.test.ts src/main/service/cli-stages.test.ts src/main/service/background-service-state.test.ts in packages/desktop
  • bun run typecheck in packages/desktop and packages/client
  • bun run lint:changed origin/beta

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant