diff --git a/packages/core/src/installation/version.ts b/packages/core/src/installation/version.ts index 25d9cd99aa6c..7412b0b5516b 100644 --- a/packages/core/src/installation/version.ts +++ b/packages/core/src/installation/version.ts @@ -1,8 +1,13 @@ declare global { const OPENCODE_VERSION: string const OPENCODE_CHANNEL: string + const OPENCODE_PLUGIN_VERSION: string } export const InstallationVersion = typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "local" export const InstallationChannel = typeof OPENCODE_CHANNEL === "string" ? OPENCODE_CHANNEL : "local" export const InstallationLocal = InstallationChannel === "local" +// Version of @opencode-ai/plugin installed into config directories. Builds whose own version is not +// published to npm (forks, custom builds) can pin a published one; otherwise it follows the binary. +export const InstallationPluginVersion = + typeof OPENCODE_PLUGIN_VERSION === "string" ? OPENCODE_PLUGIN_VERSION : InstallationVersion diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts index 60a674a4f869..803a945e0e19 100755 --- a/packages/opencode/script/build.ts +++ b/packages/opencode/script/build.ts @@ -197,6 +197,9 @@ for (const item of targets) { OTUI_TREE_SITTER_WORKER_PATH: bunfsRoot + treeSitterWorkerPath, OPENCODE_WORKER_PATH: workerPath, OPENCODE_CHANNEL: `'${Script.channel}'`, + ...(process.env.OPENCODE_PLUGIN_VERSION + ? { OPENCODE_PLUGIN_VERSION: `'${process.env.OPENCODE_PLUGIN_VERSION}'` } + : {}), OPENCODE_LIBC: item.os === "linux" ? `'${item.abi ?? "glibc"}'` : "", ...(item.os === "linux" ? { "process.env.OPENTUI_LIBC": JSON.stringify(item.abi ?? "glibc") } : {}), }, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index d24ca22d80e4..3a60e9781fe2 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -11,7 +11,7 @@ import { Flag } from "@opencode-ai/core/flag/flag" import { Auth } from "../auth" import { Env } from "../env" import { applyEdits, modify } from "jsonc-parser" -import { InstallationLocal, InstallationVersion } from "@opencode-ai/core/installation/version" +import { InstallationLocal, InstallationPluginVersion } from "@opencode-ai/core/installation/version" import { existsSync } from "fs" import { Account } from "@/account/account" import { isRecord } from "@/util/record" @@ -454,7 +454,7 @@ const layer = Layer.effect( add: [ { name: "@opencode-ai/plugin", - version: InstallationLocal ? undefined : InstallationVersion, + version: InstallationLocal ? undefined : InstallationPluginVersion, }, ], }) diff --git a/packages/opencode/src/config/tui.ts b/packages/opencode/src/config/tui.ts index 8f503751f379..8190be7c42f9 100644 --- a/packages/opencode/src/config/tui.ts +++ b/packages/opencode/src/config/tui.ts @@ -16,7 +16,7 @@ import { FSUtil } from "@opencode-ai/core/fs-util" import { CurrentWorkingDirectory } from "./tui-cwd" import { ConfigPlugin } from "@/config/plugin" import { TuiKeybind } from "@opencode-ai/tui/config/keybind" -import { InstallationLocal, InstallationVersion } from "@opencode-ai/core/installation/version" +import { InstallationLocal, InstallationPluginVersion } from "@opencode-ai/core/installation/version" import { makeRuntime } from "@opencode-ai/core/effect/runtime" import { Filesystem } from "@/util/filesystem" import { ConfigVariable } from "@/config/variable" @@ -239,7 +239,7 @@ const layer = Layer.effect( add: [ { name: "@opencode-ai/plugin", - version: InstallationLocal ? undefined : InstallationVersion, + version: InstallationLocal ? undefined : InstallationPluginVersion, }, ], }) diff --git a/packages/opencode/test/installation/installation.test.ts b/packages/opencode/test/installation/installation.test.ts index 6154d364fa63..37d4c1228b8e 100644 --- a/packages/opencode/test/installation/installation.test.ts +++ b/packages/opencode/test/installation/installation.test.ts @@ -7,7 +7,7 @@ import * as TestClock from "effect/testing/TestClock" import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http" import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process" import { Installation } from "../../src/installation" -import { InstallationVersion } from "@opencode-ai/core/installation/version" +import { InstallationPluginVersion, InstallationVersion } from "@opencode-ai/core/installation/version" import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner" import { testEffect } from "../lib/effect" @@ -94,6 +94,12 @@ describe("installation", () => { }) }) + describe("plugin version", () => { + test("follows the binary version when no plugin version is pinned at build time", () => { + expect(InstallationPluginVersion).toBe(InstallationVersion) + }) + }) + describe("latest", () => { const npm = "https://registry.npmjs.org/opencode-ai/latest" const choco = "https://community.chocolatey.org/api/v2/Packages"