diff --git a/packages/opencode/package.json b/packages/opencode/package.json index b143141f465a..b9a6feddded4 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.2.1", + "version": "1.2.2", "name": "opencode", "displayName": "iris-agent-cli", "type": "module", diff --git a/packages/opencode/src/cli/cmd/upgrade.ts b/packages/opencode/src/cli/cmd/upgrade.ts index 7365a652127d..ab3eb2b1181b 100644 --- a/packages/opencode/src/cli/cmd/upgrade.ts +++ b/packages/opencode/src/cli/cmd/upgrade.ts @@ -68,8 +68,18 @@ export const UpgradeCommand = { spinner.stop(Installation.isIris() ? "IRIS CLI updated" : "Upgrade complete") if (Installation.isIris()) { - // Also update SDK and bridge if present + // Verify the update actually took effect const { $ } = await import("bun") + const verifyResult = await $`${process.execPath} --version`.nothrow().quiet().text() + const installedVersion = verifyResult.trim() + if (installedVersion && installedVersion !== target) { + prompts.log.warn(`Expected v${target} but binary reports v${installedVersion}`) + prompts.log.info(`Try: curl -fsSL https://heyiris.io/install-iris.sh | bash`) + } else { + prompts.log.success(`Verified: v${installedVersion}`) + } + + // Also update SDK and bridge if present const home = process.env.HOME || "" const sdkDir = `${home}/.iris/sdk` diff --git a/packages/opencode/src/installation/index.ts b/packages/opencode/src/installation/index.ts index 37aa2a6fa278..b0fca3bb8b8e 100644 --- a/packages/opencode/src/installation/index.ts +++ b/packages/opencode/src/installation/index.ts @@ -137,21 +137,36 @@ export namespace Installation { const ext = platform === "linux" ? "tar.gz" : "zip" const assetName = `iris-${platform}-${arch}.${ext}` const releaseUrl = `https://github.com/FREELABEL/iris-opencode/releases/download/v${target}/${assetName}` - const binDir = path.dirname(process.execPath) + // Resolve symlinks to get the real binary path + const realExecPath = await import("fs").then(fs => fs.realpathSync(process.execPath)) + const binDir = path.dirname(realExecPath) const tmpDir = path.join(binDir, ".iris-update-tmp") - cmd = $`set -e -mkdir -p ${tmpDir} -cd ${tmpDir} -curl -fsSL -o ${assetName} ${releaseUrl} + // Use a script file to avoid Bun template literal interpolation issues + const script = `#!/bin/bash +set -e +mkdir -p "${tmpDir}" +cd "${tmpDir}" +curl -fsSL -o "${assetName}" "${releaseUrl}" if [ "${ext}" = "tar.gz" ]; then - tar -xzf ${assetName} + tar -xzf "${assetName}" else - unzip -o ${assetName} + unzip -o "${assetName}" fi -cp -f iris ${binDir}/iris -rm -rf ${tmpDir} -echo "Updated to v${target}"`.env({ ...process.env }) +chmod +x iris +# Remove old binary first (avoids overwriting a running executable) +rm -f "${binDir}/iris" +mv iris "${binDir}/iris" +rm -rf "${tmpDir}" +# Verify the new binary works +"${binDir}/iris" --version +` + const scriptPath = path.join(tmpDir + "-script.sh") + await import("fs").then(fs => { + fs.mkdirSync(path.dirname(scriptPath), { recursive: true }) + fs.writeFileSync(scriptPath, script, { mode: 0o755 }) + }) + cmd = $`bash ${scriptPath} && rm -f ${scriptPath}`.env({ ...process.env }) } else { switch (method) { case "curl":