diff --git a/packages/cli/src/services/updater.ts b/packages/cli/src/services/updater.ts index d4a1711f67f..b1372dfa31a 100644 --- a/packages/cli/src/services/updater.ts +++ b/packages/cli/src/services/updater.ts @@ -125,7 +125,6 @@ const make = Effect.gen(function* () { fetch( `https://update.opencode.ai/api/${encodeURIComponent(channel)}/${encodeURIComponent(OPENCODE_ARTIFACT)}/npm?current=${encodeURIComponent(OPENCODE_VERSION)}`, { - headers: { "User-Agent": `opencode/${OPENCODE_VERSION}` }, signal: AbortSignal.any([signal, AbortSignal.timeout(10_000)]), }, ), diff --git a/packages/updates/README.md b/packages/updates/README.md index 39d55c6aaec..79ac65a5cd0 100644 --- a/packages/updates/README.md +++ b/packages/updates/README.md @@ -14,8 +14,10 @@ Each channel/name/distribution can mark one retained artifact as `minimum`, inde of its `active` artifact. Set or clear it from the admin page. Publishing a new active release preserves the minimum marker. -Clients send their running version as `?current=`. Existing clients fall back -to `User-Agent: opencode/`. A caller below the minimum receives that exact +Clients send their running version as `?current=` and use the CLI's default +`User-Agent: opencode///cli`. When `current` is absent, the service +parses that User-Agent or the older `opencode/` format. +A caller below the minimum receives that exact artifact; callers at or above it receive the active artifact. An unparseable caller version receives the minimum. Requests with neither version source receive the active artifact. All three public API paths apply the same selection and use `Cache-Control: diff --git a/packages/updates/src/index.ts b/packages/updates/src/index.ts index e87591c18e9..3395c3e0922 100644 --- a/packages/updates/src/index.ts +++ b/packages/updates/src/index.ts @@ -70,7 +70,8 @@ export default { } const resolved = resolveChannel(path[0]) - const current = url.searchParams.get("current") ?? request.headers.get("User-Agent")?.match(/^opencode\/(.*)$/)?.[1] + const agent = request.headers.get("User-Agent")?.match(/^opencode\/(?:[^/]+\/([^/]+)\/cli|(.*))$/) + const current = url.searchParams.get("current") ?? agent?.[1] ?? agent?.[2] if (path.length === 1) return channel(env.DB, resolved, current) if (path.length === 2) return artifactName(env.DB, resolved, path[1], current) return artifactDistribution(env.DB, resolved, path[1], path[2], current)