diff --git a/README.md b/README.md index 0a13298..96825b9 100644 --- a/README.md +++ b/README.md @@ -146,15 +146,7 @@ curl -fsSL https://git.lohmar.co.uk/cclohmar/NewOpenAgents/raw/branch/main/insta Even though the script arrives over a pipe, it is **interactive**: it reads your answers from the terminal (`/dev/tty`). In a non-terminal context (CI), it runs with safe defaults instead of prompting. -> **If OpenCode's `latest` build won't install** — e.g. `Version 2.0.28 is not available for linux-x64` (upstream publishes the version metadata before the platform binary) — pin the newest published build: -> -> ```bash -> curl -fsSL https://git.lohmar.co.uk/cclohmar/NewOpenAgents/raw/branch/main/install.sh \ -> | bash -s -- --opencode-version 2.0.27 -> ``` -> -> Find what's actually published with -> `curl -s https://registry.npmjs.org/-/package/@opencode/cli-linux-x64/dist-tags`. +> **OpenCode version resolution.** During an upstream release there's a short window where the advertised `latest` has no binary for your platform yet (`Version X is not available for linux-x64`). The installer doesn't trust that metadata — it resolves the newest build **actually published** for your platform. To force a specific version, pass `--opencode-version V` (see what's published: `curl -s https://registry.npmjs.org/-/package/@opencode/cli-linux-x64/dist-tags`). ### Or clone, then install (recommended for updates) diff --git a/install.sh b/install.sh index 9475cf2..1568c25 100755 --- a/install.sh +++ b/install.sh @@ -221,6 +221,42 @@ opencode_path() { fi } +# OpenCode's `latest` metadata can advertise a version whose platform binary is +# not published yet (e.g. "Version 2.0.28 is not available for linux-x64"). +# Resolve the newest version that IS published for this platform, so the default +# install works without the user knowing a version. +resolve_latest_published() { + local os arch target scope url ver + case "$(uname -s)" in + Darwin) os=darwin ;; + Linux) os=linux ;; + MINGW*|MSYS*|CYGWIN*) os=windows ;; + *) return 0 ;; + esac + arch="$(uname -m)" + case "$arch" in + x86_64|amd64) arch=x64 ;; + aarch64|arm64) arch=arm64 ;; + esac + target="${os}-${arch}" + if [ "$arch" = "x64" ] && [ "$os" = "linux" ]; then + grep -qwi avx2 /proc/cpuinfo 2>/dev/null || target="${target}-baseline" + if [ -f /etc/alpine-release ] || { command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; }; then + target="${target}-musl" + fi + fi + command -v curl >/dev/null 2>&1 || return 0 + for scope in "@opencode" "@opencode-ai"; do + url="https://registry.npmjs.org/-/package/${scope}/cli-${target}/dist-tags" + ver="$(curl -fsSL --max-time 15 "$url" 2>/dev/null | sed -n 's/.*"latest":"\([^"]*\)".*/\1/p')" + if [ -n "$ver" ]; then + printf '%s' "$ver" + return 0 + fi + done + return 0 +} + opencode_on_path() { command -v opencode >/dev/null 2>&1; } # The official installer writes the PATH line to the shell rc but never activates @@ -308,10 +344,15 @@ ensure_opencode() { fi local ok=0 - if [ -n "$OPENCODE_VERSION" ] && [ "$OPENCODE_NO_PATH" = 1 ]; then - bash "$tmp" --no-modify-path --version "$OPENCODE_VERSION" && ok=1 - elif [ -n "$OPENCODE_VERSION" ]; then - bash "$tmp" --version "$OPENCODE_VERSION" && ok=1 + local ver="$OPENCODE_VERSION" + if [ -z "$ver" ]; then + ver="$(resolve_latest_published)" + [ -n "$ver" ] && info "Using the newest build published for this platform: ${ver}" + fi + if [ -n "$ver" ] && [ "$OPENCODE_NO_PATH" = 1 ]; then + bash "$tmp" --no-modify-path --version "$ver" && ok=1 + elif [ -n "$ver" ]; then + bash "$tmp" --version "$ver" && ok=1 elif [ "$OPENCODE_NO_PATH" = 1 ]; then bash "$tmp" --no-modify-path && ok=1 else