#!/bin/sh set -eu Color_Off='' Red='' Green='' Dim='' Bold_White='' if [ -t 1 ]; then Color_Off='\033[0m' Red='\033[0;31m' Green='\033[0;32m' Dim='\033[0;2m' Bold_White='\033[1m' fi error() { printf "${Red}error${Color_Off}: %s\n" "$*" >&2 exit 1 } info() { printf "${Dim}%s${Color_Off}\n" "$*" } info_bold() { printf "${Bold_White}%s${Color_Off}\n" "$*" } success() { printf "${Green}%s${Color_Off}\n" "$*" } usage() { cat <<'USAGE' Usage: install.sh [version] [installer options] Examples: install.sh install.sh 1.0.0-beta.10 install.sh --no-modify-path USAGE } need_cmd() { command -v "$1" >/dev/null 2>&1 || error "$1 is required to install clams." } normalize_version_tag() { case "$1" in latest) printf '%s\n' latest ;; clams-v[0-9]*) printf '%s\n' "$1" ;; v[0-9]*) printf 'clams-%s\n' "$1" ;; [0-9]*) printf 'clams-v%s\n' "$1" ;; *) error "Invalid version format: $1. Expected latest, 1.0.0-beta.10, v1.0.0-beta.10, or clams-v1.0.0-beta.10." ;; esac } install_agent_skills() { echo clams_cmd=$(find_clams_cmd || true) if [ -z "$clams_cmd" ]; then info "Could not find the newly installed clams binary." info "Install agent skills later with:" info_bold " clams skills install --global" return 0 fi if ! clams_supports_skills_install "$clams_cmd"; then info "This clams binary does not support agent skill installation." info "Install agent skills after updating clams with:" info_bold " clams skills install --global" return 0 fi if ! { printf "${Bold_White}Would you like to install Clams Agent Skills? (y/N): ${Color_Off}" >/dev/tty && IFS= read -r install_skills /dev/null; then info "This session isn't interactive, so skipping the agent skills prompt." info "Install them later with:" info_bold " clams skills install --global" return 0 fi case "$install_skills" in y | Y) echo info "Installing agent skills..." if "$clams_cmd" skills install --global /dev/null 2>&1; then command -v clams return 0 fi return 1 } clams_supports_skills_install() { "$1" --no-input skills install --help >/dev/null 2>&1 } run_windows_installer() { powershell -ExecutionPolicy Bypass -Command \ "\$p=(New-TemporaryFile).FullName + '.ps1'; try { iwr -UseBasicParsing https://clams.tech/install.ps1 -OutFile \$p; powershell -ExecutionPolicy Bypass -File \$p; if (\$LASTEXITCODE) { exit \$LASTEXITCODE } } finally { rm \$p -Force -ErrorAction SilentlyContinue }" } if [ "${OS:-}" = Windows_NT ]; then run_windows_installer exit $? fi need_cmd curl need_cmd chmod need_cmd mktemp need_cmd rm need_cmd sh version=latest if [ "$#" -gt 0 ]; then case "$1" in -h | --help) usage exit 0 ;; -*) ;; *) version=$1 shift ;; esac fi tag=$(normalize_version_tag "$version") github_repo="https://github.com/clams-tech/releases" if [ "$tag" = latest ]; then installer_url="$github_repo/releases/latest/download/clams-installer.sh" info "Fetching latest clams installer..." else installer_url="$github_repo/releases/download/$tag/clams-installer.sh" info "Fetching clams installer for ${tag#clams-v}..." fi tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/clams-install.XXXXXX") || error "Failed to create a temporary directory." trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM installer_path="$tmp_dir/clams-installer.sh" curl --proto '=https' --tlsv1.2 -LsSf "$installer_url" -o "$installer_path" || error "Failed to download installer from $installer_url" chmod +x "$installer_path" || error "Failed to mark installer executable." if [ -n "${CLAMS_INSTALL:-}" ] && [ -z "${CLAMS_INSTALL_DIR:-}" ]; then export CLAMS_INSTALL_DIR="$CLAMS_INSTALL/bin" fi sh "$installer_path" "$@" install_agent_skills