summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2025-11-13 10:22:07 -0800
committerGitHub <[email protected]>2025-11-13 12:22:07 -0600
commitff462dfd7a7319c59e6600aae9c553a59762e739 (patch)
treeea368831fb93dfa472187a8c66279f985dae0137
parent73443585e5e939522d306c601056dcdf609d67c3 (diff)
downloadopencode-ff462dfd7a7319c59e6600aae9c553a59762e739.tar.gz
opencode-ff462dfd7a7319c59e6600aae9c553a59762e739.zip
fix: windows install (#4293)
Co-authored-by: GitHub Action <[email protected]>
-rw-r--r--.github/workflows/snapshot.yml2
-rwxr-xr-xpackages/opencode/bin/opencode145
-rw-r--r--packages/opencode/bin/opencode.cmd58
-rw-r--r--packages/opencode/script/preinstall.mjs44
-rwxr-xr-xpackages/opencode/script/publish.ts19
5 files changed, 86 insertions, 182 deletions
diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml
index 402c014fd..ab2f9c0f2 100644
--- a/.github/workflows/snapshot.yml
+++ b/.github/workflows/snapshot.yml
@@ -4,7 +4,7 @@ on:
push:
branches:
- dev
- - opentui
+ - windows
- v0
concurrency: ${{ github.workflow }}-${{ github.ref }}
diff --git a/packages/opencode/bin/opencode b/packages/opencode/bin/opencode
index 8f75eb189..e35cc0094 100755
--- a/packages/opencode/bin/opencode
+++ b/packages/opencode/bin/opencode
@@ -1,61 +1,84 @@
-#!/bin/sh
-set -e
-
-if [ -n "$OPENCODE_BIN_PATH" ]; then
- resolved="$OPENCODE_BIN_PATH"
-else
- # Get the real path of this script, resolving any symlinks
- script_path="$0"
- while [ -L "$script_path" ]; do
- link_target="$(readlink "$script_path")"
- case "$link_target" in
- /*) script_path="$link_target" ;;
- *) script_path="$(dirname "$script_path")/$link_target" ;;
- esac
- done
- script_dir="$(dirname "$script_path")"
- script_dir="$(cd "$script_dir" && pwd)"
-
- # Map platform names
- case "$(uname -s)" in
- Darwin) platform="darwin" ;;
- Linux) platform="linux" ;;
- MINGW*|CYGWIN*|MSYS*) platform="win32" ;;
- *) platform="$(uname -s | tr '[:upper:]' '[:lower:]')" ;;
- esac
-
- # Map architecture names
- case "$(uname -m)" in
- x86_64|amd64) arch="x64" ;;
- aarch64) arch="arm64" ;;
- armv7l) arch="arm" ;;
- *) arch="$(uname -m)" ;;
- esac
-
- name="opencode-${platform}-${arch}"
- binary="opencode"
- [ "$platform" = "win32" ] && binary="opencode.exe"
-
- # Search for the binary starting from real script location
- resolved=""
- current_dir="$script_dir"
- while [ "$current_dir" != "/" ]; do
- candidate="$current_dir/node_modules/$name/bin/$binary"
- if [ -f "$candidate" ]; then
- resolved="$candidate"
- break
- fi
- current_dir="$(dirname "$current_dir")"
- done
-
- if [ -z "$resolved" ]; then
- printf "It seems that your package manager failed to install the right version of the opencode CLI for your platform. You can try manually installing the \"%s\" package\n" "$name" >&2
- exit 1
- fi
-fi
-
-# Handle SIGINT gracefully
-trap '' INT
-
-# Execute the binary with all arguments
-exec "$resolved" "$@"
+#!/usr/bin/env node
+
+const childProcess = require("child_process")
+const fs = require("fs")
+const path = require("path")
+const os = require("os")
+
+function run(target) {
+ const result = childProcess.spawnSync(target, process.argv.slice(2), {
+ stdio: "inherit",
+ })
+ if (result.error) {
+ console.error(result.error.message)
+ process.exit(1)
+ }
+ const code = typeof result.status === "number" ? result.status : 0
+ process.exit(code)
+}
+
+const envPath = process.env.OPENCODE_BIN_PATH
+if (envPath) {
+ run(envPath)
+}
+
+const scriptPath = fs.realpathSync(__filename)
+const scriptDir = path.dirname(scriptPath)
+
+const platformMap = {
+ darwin: "darwin",
+ linux: "linux",
+ win32: "windows",
+}
+const archMap = {
+ x64: "x64",
+ arm64: "arm64",
+ arm: "arm",
+}
+
+let platform = platformMap[os.platform()]
+if (!platform) {
+ platform = os.platform()
+}
+let arch = archMap[os.arch()]
+if (!arch) {
+ arch = os.arch()
+}
+const base = "opencode-" + platform + "-" + arch
+const binary = platform === "windows" ? "opencode.exe" : "opencode"
+
+function findBinary(startDir) {
+ let current = startDir
+ for (;;) {
+ const modules = path.join(current, "node_modules")
+ if (fs.existsSync(modules)) {
+ const entries = fs.readdirSync(modules)
+ for (const entry of entries) {
+ if (!entry.startsWith(base)) {
+ continue
+ }
+ const candidate = path.join(modules, entry, "bin", binary)
+ if (fs.existsSync(candidate)) {
+ return candidate
+ }
+ }
+ }
+ const parent = path.dirname(current)
+ if (parent === current) {
+ return
+ }
+ current = parent
+ }
+}
+
+const resolved = findBinary(scriptDir)
+if (!resolved) {
+ console.error(
+ 'It seems that your package manager failed to install the right version of the opencode CLI for your platform. You can try manually installing the "' +
+ base +
+ '" package',
+ )
+ process.exit(1)
+}
+
+run(resolved)
diff --git a/packages/opencode/bin/opencode.cmd b/packages/opencode/bin/opencode.cmd
deleted file mode 100644
index 775bfe688..000000000
--- a/packages/opencode/bin/opencode.cmd
+++ /dev/null
@@ -1,58 +0,0 @@
-@echo off
-setlocal enabledelayedexpansion
-
-if defined OPENCODE_BIN_PATH (
- set "resolved=%OPENCODE_BIN_PATH%"
- goto :execute
-)
-
-rem Get the directory of this script
-set "script_dir=%~dp0"
-set "script_dir=%script_dir:~0,-1%"
-
-rem Detect platform and architecture
-set "platform=windows"
-
-rem Detect architecture
-if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
- set "arch=x64"
-) else if "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
- set "arch=arm64"
-) else if "%PROCESSOR_ARCHITECTURE%"=="x86" (
- set "arch=x86"
-) else (
- set "arch=x64"
-)
-
-set "name=opencode-!platform!-!arch!"
-set "binary=opencode.exe"
-
-rem Search for the binary starting from script location
-set "resolved="
-set "current_dir=%script_dir%"
-
-:search_loop
-set "candidate=%current_dir%\node_modules\%name%\bin\%binary%"
-if exist "%candidate%" (
- set "resolved=%candidate%"
- goto :execute
-)
-
-rem Move up one directory
-for %%i in ("%current_dir%") do set "parent_dir=%%~dpi"
-set "parent_dir=%parent_dir:~0,-1%"
-
-rem Check if we've reached the root
-if "%current_dir%"=="%parent_dir%" goto :not_found
-set "current_dir=%parent_dir%"
-goto :search_loop
-
-:not_found
-echo It seems that your package manager failed to install the right version of the opencode CLI for your platform. You can try manually installing the "%name%" package >&2
-exit /b 1
-
-:execute
-rem Execute the binary with all arguments in the same console window
-rem Use start /b /wait to ensure it runs in the current shell context for all shells
-start /b /wait "" "%resolved%" %*
-exit /b %ERRORLEVEL%
diff --git a/packages/opencode/script/preinstall.mjs b/packages/opencode/script/preinstall.mjs
deleted file mode 100644
index dfe46d9e7..000000000
--- a/packages/opencode/script/preinstall.mjs
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env node
-
-import fs from "fs"
-import path from "path"
-import os from "os"
-import { fileURLToPath } from "url"
-
-const __dirname = path.dirname(fileURLToPath(import.meta.url))
-
-function main() {
- if (os.platform() !== "win32") {
- console.log("Non-Windows platform detected, skipping preinstall")
- return
- }
-
- console.log("Windows detected: Modifying package.json bin entry")
-
- // Read package.json
- const packageJsonPath = path.join(__dirname, "package.json")
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))
-
- // Modify bin to point to .cmd file on Windows
- packageJson.bin = {
- opencode: "./bin/opencode.cmd",
- }
-
- // Write it back
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
- console.log("Updated package.json bin to use opencode.cmd")
-
- // Now you can also remove the Unix script if you want
- const unixScript = path.join(__dirname, "bin", "opencode")
- if (fs.existsSync(unixScript)) {
- console.log("Removing Unix shell script")
- fs.unlinkSync(unixScript)
- }
-}
-
-try {
- main()
-} catch (error) {
- console.error("Preinstall script error:", error.message)
- process.exit(0)
-}
diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts
index ac2fce56b..d5afe56fb 100755
--- a/packages/opencode/script/publish.ts
+++ b/packages/opencode/script/publish.ts
@@ -3,7 +3,6 @@ import { $ } from "bun"
import pkg from "../package.json"
import { Script } from "@opencode-ai/script"
import { fileURLToPath } from "url"
-import fs from "fs"
const dir = fileURLToPath(new URL("..", import.meta.url))
process.chdir(dir)
@@ -17,21 +16,6 @@ const { binaries } = await import("./build.ts")
await $`mkdir -p ./dist/${pkg.name}`
await $`cp -r ./bin ./dist/${pkg.name}/bin`
-
-// Copy Windows .exe if any Windows binaries were built
-let hasWindowsBinary = false
-for (const binaryName of Object.keys(binaries)) {
- if (binaryName.includes("win32")) {
- const winBinaryPath = `./dist/${binaryName}/bin/opencode.exe`
- if (fs.existsSync(winBinaryPath)) {
- await $`cp ${winBinaryPath} ./dist/${pkg.name}/bin/opencode.exe`
- hasWindowsBinary = true
- break
- }
- }
-}
-
-await $`cp ./script/preinstall.mjs ./dist/${pkg.name}/preinstall.mjs`
await $`cp ./script/postinstall.mjs ./dist/${pkg.name}/postinstall.mjs`
await Bun.file(`./dist/${pkg.name}/package.json`).write(
@@ -39,10 +23,9 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write(
{
name: pkg.name + "-ai",
bin: {
- [pkg.name]: hasWindowsBinary ? `./bin/${pkg.name}.exe` : `./bin/${pkg.name}`,
+ [pkg.name]: `./bin/${pkg.name}`,
},
scripts: {
- preinstall: "bun ./preinstall.mjs || node ./preinstall.mjs",
postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
},
version: Script.version,