From 955b787e6b9fb8666e84abfa6868671859d72f7e Mon Sep 17 00:00:00 2001 From: NikodemNowak <71512463+NikodemNowak@users.noreply.github.com> Date: Mon, 14 Sep 2026 18:15:45 +0200 Subject: [PATCH] fix(server): parse CLI versions with a "v" prefix (#11738) --- .../src/provider/providerSnapshot.test.ts | 24 +++++++++++++++++++ apps/server/src/provider/providerSnapshot.ts | 8 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/server/src/provider/providerSnapshot.test.ts b/apps/server/src/provider/providerSnapshot.test.ts index 399d86f7a133e87248674ea6b7567b301cb30d84..5c45362daa74e101fd2acb4ead1a5aea1accb408 100644 --- a/apps/server/src/provider/providerSnapshot.test.ts +++ b/apps/server/src/provider/providerSnapshot.test.ts @@ -11,6 +11,7 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; import { isCommandMissingCause, + parseGenericCliVersion, providerModelsFromSettings, spawnAndCollect, } from "./providerSnapshot.ts"; @@ -93,6 +94,29 @@ describe("providerModelsFromSettings", () => { }); }); +describe("parseGenericCliVersion", () => { + it("parses a bare version", () => { + expect(parseGenericCliVersion("1.14.19")).toBe("1.14.19"); + }); + + it("parses a v-prefixed version", () => { + expect(parseGenericCliVersion("opencode v2.0.3")).toBe("2.0.3"); + expect(parseGenericCliVersion("v22.19.0")).toBe("22.19.0"); + }); + + it("parses a version embedded in other output", () => { + expect(parseGenericCliVersion("codex-cli 0.53.0 (build abc)")).toBe("0.53.0"); + }); + + it("returns null when no version is present", () => { + expect(parseGenericCliVersion("no version here")).toBeNull(); + }); + + it("ignores versions glued to other word characters", () => { + expect(parseGenericCliVersion("build2.0.3artifact")).toBeNull(); + }); +}); + describe("ProviderCommandNotFoundError", () => { it("classifies normalized platform failures without parsing messages", () => { expect( diff --git a/apps/server/src/provider/providerSnapshot.ts b/apps/server/src/provider/providerSnapshot.ts index 40ae0eeefde028fd138a6bb682fe6676d8e23a57..c5503a175498531c0db635b89c0ed455066c1174 100644 --- a/apps/server/src/provider/providerSnapshot.ts +++ b/apps/server/src/provider/providerSnapshot.ts @@ -107,8 +107,14 @@ export const spawnAndCollect = (binaryPath: string, command: ChildProcess.Comman return result; }).pipe(Effect.scoped); +/** + * Return the first semantic version found in CLI output, or null. Accepts a + * leading "v" (for example `opencode v2.0.3`). + */ export function parseGenericCliVersion(output: string): string | null { - const match = output.match(/\b(\d+\.\d+\.\d+)\b/); + // "opencode v2.0.3"-style output: the optional "v" has to be consumed first, + // since "v2" itself contains no word boundary. + const match = output.match(/\bv?(\d+\.\d+\.\d+)\b/); return match?.[1] ?? null; } -- 2.54.0