diff --git a/install.sh b/install.sh index 47429db5b1564..d6a01447d610b 100644 --- a/install.sh +++ b/install.sh @@ -2,7 +2,7 @@ set -euo pipefail # OpenClaw Installer for macOS and Linux -# Usage: curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash +# Usage: curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash BOLD='\033[1m' ACCENT='\033[38;2;255;77;77m' # coral-bright #ff4d4d @@ -16,6 +16,9 @@ MUTED='\033[38;2;90;100;128m' # text-muted #5a6480 NC='\033[0m' # No Color DEFAULT_TAGLINE="All your chats, one OpenClaw." +DEFAULT_NPM_PACKAGE="openclaw-aimlapi" +DEFAULT_GIT_REPO_URL="https://github.com/aimlapi/openclaw-aimlapi.git" +DEFAULT_GIT_REPO_BRANCH="feature/add-aimlapi-models-provider" ORIGINAL_PATH="${PATH:-}" @@ -258,7 +261,7 @@ detect_os_or_die() { if [[ "$OS" == "unknown" ]]; then ui_error "Unsupported operating system" echo "This installer supports macOS and Linux (including WSL)." - echo "For Windows, use: iwr -useb https://openclaw.ai/install.ps1 | iex" + echo "For Windows, use: iwr -useb https://aimlapi.com/openclaw/install.ps1 | iex" exit 1 fi @@ -477,7 +480,8 @@ cleanup_npm_openclaw_paths() { if [[ -z "$npm_root" || "$npm_root" != *node_modules* ]]; then return 1 fi - rm -rf "$npm_root"/.openclaw-* "$npm_root"/openclaw 2>/dev/null || true + local npm_package="${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" + rm -rf "$npm_root"/.openclaw-* "$npm_root"/openclaw "$npm_root"/"$npm_package" 2>/dev/null || true } extract_openclaw_conflict_path() { @@ -951,7 +955,10 @@ DRY_RUN=${OPENCLAW_DRY_RUN:-0} INSTALL_METHOD=${OPENCLAW_INSTALL_METHOD:-} OPENCLAW_VERSION=${OPENCLAW_VERSION:-latest} USE_BETA=${OPENCLAW_BETA:-0} -GIT_DIR_DEFAULT="${HOME}/openclaw" +OPENCLAW_NPM_PACKAGE=${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE} +OPENCLAW_GIT_REPO_URL=${OPENCLAW_GIT_REPO_URL:-$DEFAULT_GIT_REPO_URL} +OPENCLAW_GIT_REPO_BRANCH=${OPENCLAW_GIT_REPO_BRANCH:-$DEFAULT_GIT_REPO_BRANCH} +GIT_DIR_DEFAULT="${HOME}/openclaw-aimlapi" GIT_DIR=${OPENCLAW_GIT_DIR:-$GIT_DIR_DEFAULT} GIT_UPDATE=${OPENCLAW_GIT_UPDATE:-1} SHARP_IGNORE_GLOBAL_LIBVIPS="${SHARP_IGNORE_GLOBAL_LIBVIPS:-1}" @@ -967,7 +974,7 @@ print_usage() { OpenClaw installer (macOS + Linux) Usage: - curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- [options] + curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash -s -- [options] Options: --install-method, --method npm|git Install via npm (default) or from a git checkout @@ -987,6 +994,9 @@ Environment variables: OPENCLAW_INSTALL_METHOD=git|npm OPENCLAW_VERSION=latest|next| OPENCLAW_BETA=0|1 + OPENCLAW_NPM_PACKAGE=openclaw-aimlapi + OPENCLAW_GIT_REPO_URL=https://github.com/aimlapi/openclaw-aimlapi.git + OPENCLAW_GIT_REPO_BRANCH=feature/add-aimlapi-models-provider OPENCLAW_GIT_DIR=... OPENCLAW_GIT_UPDATE=0|1 OPENCLAW_NO_PROMPT=1 @@ -997,9 +1007,9 @@ Environment variables: SHARP_IGNORE_GLOBAL_LIBVIPS=0|1 Default: 1 (avoid sharp building against global libvips) Examples: - curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash - curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --no-onboard - curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method git --no-onboard + curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash + curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash -s -- --no-onboard + curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash -s -- --install-method git --no-onboard EOF } @@ -1159,7 +1169,7 @@ detect_openclaw_checkout() { if [[ ! -f "$dir/pnpm-workspace.yaml" ]]; then return 1 fi - if ! grep -q '"name"[[:space:]]*:[[:space:]]*"openclaw"' "$dir/package.json" 2>/dev/null; then + if ! grep -Eq '"name"[[:space:]]*:[[:space:]]*"(openclaw|openclaw-aimlapi)"' "$dir/package.json" 2>/dev/null; then return 1 fi echo "$dir" @@ -1187,7 +1197,7 @@ print_homebrew_admin_fix() { echo " 2) Ask an Administrator to grant admin rights, then sign out/in:" echo " sudo dseditgroup -o edit -a ${current_user} -t user admin" echo "Then retry:" - echo " curl -fsSL https://openclaw.ai/install.sh | bash" + echo " curl -fsSL https://aimlapi.com/openclaw/install.sh | bash" } install_homebrew() { @@ -1520,31 +1530,61 @@ fix_npm_permissions() { ui_success "npm configured for user installs" } +openclaw_candidate_bins() { + # CLI command must remain `openclaw` regardless of npm package name. + echo "openclaw" +} + ensure_openclaw_bin_link() { local npm_root="" npm_root="$(npm root -g 2>/dev/null || true)" - if [[ -z "$npm_root" || ! -d "$npm_root/openclaw" ]]; then + local npm_package="${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" + if [[ -z "$npm_root" || ! -d "$npm_root/$npm_package" ]]; then return 1 fi + local npm_bin="" npm_bin="$(npm_global_bin_dir || true)" if [[ -z "$npm_bin" ]]; then return 1 fi + mkdir -p "$npm_bin" - if [[ ! -x "${npm_bin}/openclaw" ]]; then - ln -sf "$npm_root/openclaw/dist/entry.js" "${npm_bin}/openclaw" + if [[ -x "${npm_bin}/openclaw" ]]; then + return 0 + fi + + if [[ -f "$npm_root/$npm_package/openclaw.mjs" ]]; then + ln -sf "$npm_root/$npm_package/openclaw.mjs" "${npm_bin}/openclaw" + chmod +x "$npm_root/$npm_package/openclaw.mjs" >/dev/null 2>&1 || true ui_info "Created openclaw bin link at ${npm_bin}/openclaw" + return 0 fi - return 0 + + if [[ -f "$npm_root/$npm_package/dist/entry.js" ]]; then + local wrapper="${npm_bin}/openclaw" + cat > "$wrapper" </dev/null || true)" ]]; then - ui_info "Existing OpenClaw installation detected, upgrading" - return 0 - fi + local cmd="" + while IFS= read -r cmd; do + if [[ -n "$(type -P "$cmd" 2>/dev/null || true)" ]]; then + ui_info "Existing OpenClaw installation detected, upgrading" + return 0 + fi + done < <(openclaw_candidate_bins) return 1 } @@ -1774,38 +1814,53 @@ warn_openclaw_not_found() { resolve_openclaw_bin() { refresh_shell_command_cache local resolved="" - resolved="$(type -P openclaw 2>/dev/null || true)" - if [[ -n "$resolved" && -x "$resolved" ]]; then - echo "$resolved" - return 0 - fi + local cmd="" + while IFS= read -r cmd; do + resolved="$(type -P "$cmd" 2>/dev/null || true)" + if [[ -n "$resolved" && -x "$resolved" ]]; then + echo "$resolved" + return 0 + fi + done < <(openclaw_candidate_bins) ensure_npm_global_bin_on_path refresh_shell_command_cache - resolved="$(type -P openclaw 2>/dev/null || true)" - if [[ -n "$resolved" && -x "$resolved" ]]; then - echo "$resolved" - return 0 - fi + while IFS= read -r cmd; do + resolved="$(type -P "$cmd" 2>/dev/null || true)" + if [[ -n "$resolved" && -x "$resolved" ]]; then + echo "$resolved" + return 0 + fi + done < <(openclaw_candidate_bins) local npm_bin="" npm_bin="$(npm_global_bin_dir || true)" - if [[ -n "$npm_bin" && -x "${npm_bin}/openclaw" ]]; then - echo "${npm_bin}/openclaw" - return 0 + if [[ -n "$npm_bin" ]]; then + while IFS= read -r cmd; do + if [[ -x "${npm_bin}/${cmd}" ]]; then + echo "${npm_bin}/${cmd}" + return 0 + fi + done < <(openclaw_candidate_bins) fi maybe_nodenv_rehash refresh_shell_command_cache - resolved="$(type -P openclaw 2>/dev/null || true)" - if [[ -n "$resolved" && -x "$resolved" ]]; then - echo "$resolved" - return 0 - fi + while IFS= read -r cmd; do + resolved="$(type -P "$cmd" 2>/dev/null || true)" + if [[ -n "$resolved" && -x "$resolved" ]]; then + echo "$resolved" + return 0 + fi + done < <(openclaw_candidate_bins) - if [[ -n "$npm_bin" && -x "${npm_bin}/openclaw" ]]; then - echo "${npm_bin}/openclaw" - return 0 + if [[ -n "$npm_bin" ]]; then + while IFS= read -r cmd; do + if [[ -x "${npm_bin}/${cmd}" ]]; then + echo "${npm_bin}/${cmd}" + return 0 + fi + done < <(openclaw_candidate_bins) fi echo "" @@ -1814,7 +1869,7 @@ resolve_openclaw_bin() { install_openclaw_from_git() { local repo_dir="$1" - local repo_url="https://github.com/openclaw/openclaw.git" + local repo_url="${OPENCLAW_GIT_REPO_URL:-$DEFAULT_GIT_REPO_URL}" if [[ -d "$repo_dir/.git" ]]; then ui_info "Installing OpenClaw from git checkout: ${repo_dir}" @@ -1833,6 +1888,18 @@ install_openclaw_from_git() { run_quiet_step "Cloning OpenClaw" git clone "$repo_url" "$repo_dir" fi + local repo_branch="${OPENCLAW_GIT_REPO_BRANCH:-$DEFAULT_GIT_REPO_BRANCH}" + if [[ -n "$repo_branch" ]] && [[ -z "$(git -C "$repo_dir" status --porcelain 2>/dev/null || true)" ]]; then + run_quiet_step "Fetching repository" git -C "$repo_dir" fetch --all --prune || true + if git -C "$repo_dir" show-ref --verify --quiet "refs/heads/$repo_branch"; then + run_quiet_step "Checking out branch" git -C "$repo_dir" checkout "$repo_branch" || true + elif git -C "$repo_dir" show-ref --verify --quiet "refs/remotes/origin/$repo_branch"; then + run_quiet_step "Checking out branch" git -C "$repo_dir" checkout -b "$repo_branch" "origin/$repo_branch" || true + else + ui_warn "Branch not found on origin: $repo_branch; continuing on current branch" + fi + fi + if [[ "$GIT_UPDATE" == "1" ]]; then if [[ -z "$(git -C "$repo_dir" status --porcelain 2>/dev/null || true)" ]]; then run_quiet_step "Updating repository" git -C "$repo_dir" pull --rebase || true @@ -1865,22 +1932,32 @@ EOF # Install OpenClaw resolve_beta_version() { local beta="" - beta="$(npm view openclaw dist-tags.beta 2>/dev/null || true)" + beta="$(npm view "${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" dist-tags.beta 2>/dev/null || true)" if [[ -z "$beta" || "$beta" == "undefined" || "$beta" == "null" ]]; then return 1 fi echo "$beta" } +resolve_next_version() { + local package_name="$1" + local next="" + next="$(npm view "$package_name" dist-tags.next 2>/dev/null || true)" + if [[ -z "$next" || "$next" == "undefined" || "$next" == "null" ]]; then + return 1 + fi + echo "$next" +} + install_openclaw() { - local package_name="openclaw" + local package_name="${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" if [[ "$USE_BETA" == "1" ]]; then local beta_version="" beta_version="$(resolve_beta_version || true)" if [[ -n "$beta_version" ]]; then OPENCLAW_VERSION="$beta_version" ui_info "Beta tag detected (${beta_version})" - package_name="openclaw" + package_name="${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" else OPENCLAW_VERSION="latest" ui_info "No beta tag found; using latest" @@ -1911,11 +1988,20 @@ install_openclaw() { install_openclaw_npm "${install_spec}" fi - if [[ "${OPENCLAW_VERSION}" == "latest" && "${package_name}" == "openclaw" ]]; then + if [[ "${OPENCLAW_VERSION}" == "latest" ]]; then if ! resolve_openclaw_bin &> /dev/null; then - ui_warn "npm install openclaw@latest failed; retrying openclaw@next" - cleanup_npm_openclaw_paths - install_openclaw_npm "openclaw@next" + # npm install succeeded but CLI isn't discoverable yet; attempt explicit link before tag fallback. + ensure_openclaw_bin_link || true + fi + if ! resolve_openclaw_bin &> /dev/null; then + local next_version="" + next_version="$(resolve_next_version "$package_name" || true)" + if [[ -n "$next_version" ]]; then + ui_warn "Installed ${package_name}@latest but openclaw is not yet discoverable; retrying ${package_name}@next" + cleanup_npm_openclaw_paths + install_openclaw_npm "${package_name}@next" + ensure_openclaw_bin_link || true + fi fi fi @@ -2015,8 +2101,9 @@ resolve_openclaw_version() { if [[ -z "$version" ]]; then local npm_root="" npm_root=$(npm root -g 2>/dev/null || true) - if [[ -n "$npm_root" && -f "$npm_root/openclaw/package.json" ]]; then - version=$(node -e "console.log(require('${npm_root}/openclaw/package.json').version)" 2>/dev/null || true) + local npm_package="${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" + if [[ -n "$npm_root" && -f "$npm_root/${npm_package}/package.json" ]]; then + version=$(node -e "console.log(require('${npm_root}/${npm_package}/package.json').version)" 2>/dev/null || true) fi fi echo "$version" @@ -2153,9 +2240,9 @@ main() { local final_git_dir="" if [[ "$INSTALL_METHOD" == "git" ]]; then # Clean up npm global install if switching to git - if npm list -g openclaw &>/dev/null; then + if npm list -g "${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" &>/dev/null; then ui_info "Removing npm global install (switching to git)" - npm uninstall -g openclaw 2>/dev/null || true + npm uninstall -g "${OPENCLAW_NPM_PACKAGE:-$DEFAULT_NPM_PACKAGE}" 2>/dev/null || true ui_success "npm global install removed" fi @@ -2275,7 +2362,7 @@ main() { ui_kv "Checkout" "$final_git_dir" ui_kv "Wrapper" "$HOME/.local/bin/openclaw" ui_kv "Update command" "openclaw update --restart" - ui_kv "Switch to npm" "curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash -s -- --install-method npm" + ui_kv "Switch to npm" "curl -fsSL --proto '=https' --tlsv1.2 https://aimlapi.com/openclaw/install.sh | bash -s -- --install-method npm" elif [[ "$is_upgrade" == "true" ]]; then ui_info "Upgrade complete" if [[ -r /dev/tty && -w /dev/tty ]]; then