#!/usr/bin/env bash # gentity CLI installer — https://github.com/gentityapp/cli # # Usage: # curl -fsSL https://gentity.ai/install.sh | bash # # Env overrides: # GENTITY_VERSION Tag to install (default: latest) # GENTITY_INSTALL_DIR Destination dir (default: /usr/local/bin) # GENTITY_SKIP_SHA Set to 1 to skip checksum verification (not recommended) set -euo pipefail REPO="gentityapp/cli" VERSION="${GENTITY_VERSION:-latest}" INSTALL_DIR="${GENTITY_INSTALL_DIR:-/usr/local/bin}" BIN_NAME="gentity" # ─── helpers ───────────────────────────────────────────────────────────── say() { printf '\033[36m::\033[0m %s\n' "$*"; } ok() { printf '\033[32m✓\033[0m %s\n' "$*"; } warn() { printf '\033[33m!\033[0m %s\n' "$*" >&2; } die() { printf '\033[31m✗\033[0m %s\n' "$*" >&2; exit 1; } # ─── detect platform ───────────────────────────────────────────────────── uname_s="$(uname -s)" uname_m="$(uname -m)" case "$uname_s" in Darwin) os="darwin" ;; Linux) os="linux" ;; *) die "Unsupported OS: $uname_s. gentity supports macOS and Linux. For Windows, use WSL." ;; esac case "$uname_m" in x86_64|amd64) arch="x64" ;; arm64|aarch64) arch="arm64" ;; *) die "Unsupported architecture: $uname_m. Builds available: darwin-arm64, darwin-x64, linux-x64, linux-arm64." ;; esac target="${os}-${arch}" say "Installing gentity ${VERSION} (${target}) to ${INSTALL_DIR}" # ─── download ──────────────────────────────────────────────────────────── if [ "$VERSION" = "latest" ]; then base="https://github.com/${REPO}/releases/latest/download" else base="https://github.com/${REPO}/releases/download/${VERSION}" fi asset_url="${base}/${BIN_NAME}-${target}" sha_url="${base}/${BIN_NAME}-${target}.sha256" tmp="$(mktemp -d -t gentity-install.XXXXXX)" trap 'rm -rf "$tmp"' EXIT if command -v curl >/dev/null 2>&1; then curl -fsSL "$asset_url" -o "$tmp/$BIN_NAME" curl -fsSL "$sha_url" -o "$tmp/$BIN_NAME.sha256" || warn "Couldn't fetch checksum file." elif command -v wget >/dev/null 2>&1; then wget -q "$asset_url" -O "$tmp/$BIN_NAME" wget -q "$sha_url" -O "$tmp/$BIN_NAME.sha256" || warn "Couldn't fetch checksum file." else die "Neither curl nor wget is installed." fi if [ ! -s "$tmp/$BIN_NAME" ]; then die "Downloaded binary is empty. Check that ${VERSION} exists at https://github.com/${REPO}/releases." fi # ─── verify checksum ───────────────────────────────────────────────────── if [ "${GENTITY_SKIP_SHA:-0}" != "1" ] && [ -s "$tmp/$BIN_NAME.sha256" ]; then # The .sha256 file format is " \n". We only need the hex. expected="$(awk '{print $1}' "$tmp/$BIN_NAME.sha256")" if command -v sha256sum >/dev/null 2>&1; then actual="$(sha256sum "$tmp/$BIN_NAME" | awk '{print $1}')" elif command -v shasum >/dev/null 2>&1; then actual="$(shasum -a 256 "$tmp/$BIN_NAME" | awk '{print $1}')" else warn "No sha256sum/shasum found — skipping verification." actual="" fi if [ -n "$actual" ] && [ "$actual" != "$expected" ]; then die "Checksum mismatch for ${BIN_NAME}-${target}. Expected ${expected}, got ${actual}." fi [ -n "$actual" ] && ok "Checksum verified" fi chmod +x "$tmp/$BIN_NAME" # ─── install ───────────────────────────────────────────────────────────── dest="${INSTALL_DIR}/${BIN_NAME}" if [ -w "$INSTALL_DIR" ] || ([ ! -e "$INSTALL_DIR" ] && mkdir -p "$INSTALL_DIR" 2>/dev/null); then mv "$tmp/$BIN_NAME" "$dest" else warn "$INSTALL_DIR is not writable; using sudo." sudo mv "$tmp/$BIN_NAME" "$dest" sudo chmod +x "$dest" fi ok "Installed $("$dest" --version) to $dest" # ─── PATH check ────────────────────────────────────────────────────────── case ":$PATH:" in *":$INSTALL_DIR:"*) ;; *) warn "$INSTALL_DIR is not on your \$PATH." warn "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):" warn " export PATH=\"$INSTALL_DIR:\$PATH\"" ;; esac cat <<'EOM' Next steps: 1. Mint a token: https://gentity.ai/dashboard/settings/tokens 2. gentity login --token gn_live_... 3. gentity compute create --agent claude-code --model claude-sonnet-4-5 Docs: https://github.com/gentityapp/cli EOM