diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 402c014f..ab2f9c0f 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 8f75eb18..e35cc009 100755 --- a/packages/opencode/bin/opencode +++ b/packages/opencode/bin/opencode @@ -1,61 +1,84 @@ -#!/bin/sh -set -e +#!/usr/bin/env node -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 +const childProcess = require("child_process") +const fs = require("fs") +const path = require("path") +const os = require("os") -# Handle SIGINT gracefully -trap '' INT +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) +} -# Execute the binary with all arguments -exec "$resolved" "$@" +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 775bfe68..00000000 --- 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 dfe46d9e..00000000 --- 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 ac2fce56..d5afe56f 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,