Skip to content

fix(opencode): keep OpenCode 1 updates on 1.x using npm discovery - #54904

Merged
thdxr merged 2 commits into
v1from
v1-update-isolation
Oct 16, 2026
Merged

thdxr merged 2 commits into
v1from
v1-update-isolation

Conversation

@thdxr

@thdxr thdxr commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Issue for this PR

Closes #

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

This keeps OpenCode 1 clients on 1.x once OpenCode 2 is published as GitHub Releases.

This PR no longer uses the update service. Every install method gets its version from the opencode-ai npm package, which only ever contains OpenCode 1; OpenCode 2 ships as @opencode/cli. Nothing in OpenCode 1 reads GitHub's releases/latest any more. #54903 is now only needed to publish 2.0 GitHub Releases. Its v1 update-service channel and the seeding step in docs/release/v1-v2-isolation.md don't apply to OpenCode 1.

Version discovery (Installation.latest()):

  • Fetches ${registry}/opencode-ai/latest using the user's npm registry (registry.npmjs.org by default). Preview builds use their own dist-tag. The lookup times out after 10s.
  • Anything that isn't a newer version in the same major reports the installed version, so the existing OpenCode 2.0 offer shows instead.
  • A failed check stays silent in the background. /update now shows "Couldn't check for updates." and opencode upgrade reports the same instead of crashing.

Installing a 1.x update, per method:

  • npm / pnpm / bun / yarn: install opencode-ai@<version>. Yarn upgrades previously failed with "Unknown installation method"; they now work.
  • curl: runs opencode.ai/install with VERSION=<version>.
  • Homebrew Core: its opencode formula is already 2.x, so brew upgrade opencode would install OpenCode 2.
    • No 1.x update is offered, and no request is made; the OpenCode 2.0 offer shows instead.
    • An explicit upgrade refuses and points to --major or to reinstalling from the tap.
  • Homebrew tap (anomalyco/tap/opencode): this formula is only written by the OpenCode 1 publish; OpenCode 2 uses opencode-v2 and opencode-beta. The tap is updated a few minutes after npm.
    • Before running brew upgrade, it pulls the tap and checks the formula version.
    • If the tap isn't yet at the target version (or isn't 1.x), it asks the user to try again in a few minutes and runs nothing.
  • Chocolatey: choco upgrade --version can only install versions the moderated community feed has published. The npm version is only advertised once the feed lists that exact version.
  • Scoop: scoop install opencode@<version> generates the manifest from the bucket's autoupdate URLs, which point at our GitHub release files. Any published 1.x release can be installed.
    • Limitation: in the first few minutes after npm publishes, before the GitHub release is out, an install fails (the curl upgrade path has the same window).
  • Every method: upgrade refuses 2.x targets and points to opencode upgrade --major.

install script:

  • Gets the default version from registry.npmjs.org/opencode-ai/latest (grep/sed, no jq), and checks the release file for this platform exists.
  • If npm fails or returns something other than 1.x, or the release is still publishing, it falls back to the newest v1.* in GitHub's release list. It never uses releases/latest.
  • Downloads from releases/download/v$version/.
  • Still refuses VERSION/--version 2.x or later.
  • An explicit version is now checked against the release file rather than the tag page, so a release that's still publishing fails with a clear message.

Release tooling:

  • Removed the ported script/update-artifact.ts and the publish-to-service step.
  • Kept --latest on the V1 GitHub release and the v1.* filter in raw-changelog.ts.

The OpenCode 2.0 offer UI and the semver-aware comparisons in cli/upgrade.ts / dialog-update.tsx are unchanged from the first revision.

Note: merging changes opencode.ai/install immediately, because it redirects to the install file on v1. Clients only pick up the CLI changes in the next V1 release.

How did you verify your code works?

  • bun run typecheck (30/30).
  • packages/opencode: bun test test/installation test/cli test/server (708 pass).
  • packages/tui: bun test test/component (12 pass).
  • bun test ./script/install.test.ts ./script/raw-changelog.test.ts (10 pass).
  • Discovery tests cover:
    • npm used for each method (curl, yarn, unknown, npm, bun, pnpm, scoop, choco, brew tap);
    • 2.x ignored for each method;
    • Homebrew Core making no request and offering nothing;
    • Chocolatey not advertising a version its feed lacks;
    • registry 503, missing version and timeout, with no GitHub calls.
  • Upgrade tests cover:
    • opencode-ai@<v> for npm, pnpm, bun and yarn;
    • 2.x refused for every method;
    • Homebrew Core refusing;
    • the tap at the target version, behind it, and at 2.x.
  • Install script tests use a stand-in curl and cover:
    • npm success;
    • falling back to the GitHub v1.* list when npm fails or the release is still publishing;
    • a 2.x npm response being ignored;
    • VERSION 2.x refused;
    • a missing explicit release.
  • Mutation checks confirmed the timeout test and the still-publishing fallback test catch regressions.

Screenshots / recordings

N/A

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

@thdxr
thdxr force-pushed the v1-update-isolation branch from 9e84409 to 13cdadf Compare October 16, 2026 01:17
@thdxr thdxr changed the title feat(opencode): keep OpenCode 1 updates on 1.x via the update service fix(opencode): keep OpenCode 1 updates on 1.x using npm discovery Oct 16, 2026
@thdxr
thdxr merged commit 3be0395 into v1 Oct 16, 2026
10 checks passed
@thdxr
thdxr deleted the v1-update-isolation branch October 16, 2026 01:18
lacymorrow added a commit to lacymorrow/lash that referenced this pull request Oct 19, 2026
Upstream added script/install.test.ts in anomalyco#54904 to cover its OpenCode 1
vs 2 release gating. Merged as-is it asserts behavior lash deliberately
does not have: anomalyco/opencode URLs, $HOME/.opencode/bin, and a
refusal of 2.x versions.

Retargeted at lash's installer and added a guard for the regression this
week's merge introduced, where the non-conflicting half of upstream's
release-discovery rewrite put a hard-coded anomalyco/opencode download
URL back into the installer. The stub curl now refuses every host but
lacymorrow/lash.

Also builds a zip on darwin instead of skipping, so the download and
extract path is exercised outside linux CI. 7/7 pass.
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