#!/usr/bin/env bash # ZoarkBot Linux Installer # Usage: curl -sSL https://get.zoarkai.org | bash # bash install-linux.sh [LICENSE_KEY] set -euo pipefail INSTALL_DIR="${ZOARKBOT_INSTALL_DIR:-$HOME/.zoarkbot}" BIN_DIR="${ZOARKBOT_BIN_DIR:-$HOME/.local/bin}" LICENSE_SERVER="${ZOARKBOT_LICENSE_SERVER:-https://license.zoarkai.org}" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m' info() { echo -e "${CYAN}[zoarkbot]${NC} $*"; } ok() { echo -e "${GREEN}[✓]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } die() { echo -e "${RED}[✗]${NC} $*" >&2; exit 1; } echo -e "\n${BOLD} ZoarkBot Installer${NC} · https://app.zoarkai.org\n" # ── Node.js check + nvm auto-install ──────────────────────────────────────── _ensure_node22() { export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" [[ -s "$NVM_DIR/nvm.sh" ]] && source "$NVM_DIR/nvm.sh" if command -v node >/dev/null 2>&1; then local major; major=$(node -e "process.stdout.write(process.versions.node.split('.')[0])") [[ "$major" -ge 22 ]] && return 0 warn "Node.js v$(node --version) found — need 22+. Installing via nvm..." else warn "Node.js not found. Auto-installing Node.js 22 via nvm..." fi if [[ ! -s "$NVM_DIR/nvm.sh" ]]; then curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source "$NVM_DIR/nvm.sh" fi nvm install 22 --no-progress && nvm use 22 && nvm alias default 22 ok "Node.js $(node --version) ready" } _ensure_node22 # ── License key ──────────────────────────────────────────────────────────────── LICENSE_KEY="${1:-${ZOARKBOT_LICENSE_KEY:-}}" if [[ -z "$LICENSE_KEY" ]]; then echo -n " License key (from app.zoarkai.org): " read -r LICENSE_KEY fi LICENSE_KEY="${LICENSE_KEY^^}" if [[ ! "$LICENSE_KEY" =~ ^ZOARKBOT-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$ ]]; then die "Invalid key format. Expected: ZOARKBOT-XXXX-XXXX-XXXX-XXXX" fi # ── Get signed download URL ──────────────────────────────────────────────────── info "Validating license..." HTTP_RESP=$(curl -sf --max-time 15 \ "${LICENSE_SERVER}/v1/account/download-url?os=linux&license_key=${LICENSE_KEY}") \ || die "Cannot reach license server. Check your connection." DOWNLOAD_URL=$(echo "$HTTP_RESP" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['download_url'])" 2>/dev/null) \ || die "License validation failed. Verify your key at app.zoarkai.org" ok "License valid" # ── Download ────────────────────────────────────────────────────────────────── info "Downloading ZoarkBot for Linux..." TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT curl -fL --progress-bar -o "$TMP/zoarkbot.tar.gz" "$DOWNLOAD_URL" \ || die "Download failed. Please try again." # ── Install ─────────────────────────────────────────────────────────────────── info "Installing to ${INSTALL_DIR}..." rm -rf "${INSTALL_DIR}/dist" "${INSTALL_DIR}/node_modules" # clean old version mkdir -p "$INSTALL_DIR" tar -xzf "$TMP/zoarkbot.tar.gz" -C "$INSTALL_DIR" # ── Wrapper ─────────────────────────────────────────────────────────────────── mkdir -p "$BIN_DIR" cat > "$BIN_DIR/zoarkbot" </dev/null; then printf '\nexport PATH="%s:$PATH"\n' "$BIN_DIR" >> "$RC" break fi done export PATH="${BIN_DIR}:$PATH" # ── Activate ────────────────────────────────────────────────────────────────── info "Activating license on this machine..." node "${INSTALL_DIR}/zoarkbot.mjs" license activate "$LICENSE_KEY" \ || warn "Auto-activation failed. Run: zoarkbot license activate ${LICENSE_KEY}" ok "ZoarkBot installed successfully!" echo "" echo -e " ${BOLD}Next steps:${NC}" echo -e " 1. ${CYAN}zoarkbot gateway${NC} — start the AI agent gateway" echo -e " 2. ${CYAN}https://mc.zoarkai.org${NC} — open Mission Control in browser" echo -e " 3. ${CYAN}zoarkbot setup${NC} — configure your API keys" echo "" echo -e " Docs: ${CYAN}https://app.zoarkai.org${NC} Support: ${CYAN}support@zoarkai.org${NC}" echo "" warn "Reload shell or run: export PATH=\"${BIN_DIR}:\$PATH\""