#!/bin/sh # aft.page CLI installer — https://aft.page/install # Usage: curl -fsSL https://aft.page/install | sh # # Installs the native aft binary for this platform. No Node.js required. set -eu BASE="${AFT_CLI_BASE:-https://aft.page/cli}" BIN_DIR="${AFT_BIN_DIR:-$HOME/.local/bin}" # Colors when stdout is a TTY (aft update inherits the terminal; curl | sh often does not). if [ -t 1 ] || [ "${AFT_INSTALL_COLOR:-}" = "1" ]; then BOLD=$(printf '\033[1m') DIM=$(printf '\033[2m') GREEN=$(printf '\033[32m') CYAN=$(printf '\033[36m') RESET=$(printf '\033[0m') else BOLD='' DIM='' GREEN='' CYAN='' RESET='' fi say() { printf '%s\n' "$*"; } die() { printf '%saft install:%s %s\n' "$BOLD" "$RESET" "$*" >&2; exit 1; } command -v curl >/dev/null 2>&1 || die "curl is required" case "$(uname -s)" in Darwin) OS=darwin ;; Linux) OS=linux ;; *) die "unsupported OS: $(uname -s)" ;; esac case "$(uname -m)" in arm64 | aarch64) ARCH=arm64 ;; x86_64 | amd64) ARCH=x64 ;; *) die "unsupported architecture: $(uname -m)" ;; esac TRIPLE="$OS-$ARCH" mkdir -p "$BIN_DIR" TMP="$BIN_DIR/.aft.tmp.$$" printf '%s→%s installing aft CLI…\n' "$CYAN" "$RESET" curl -fsSL "$BASE/aft-$TRIPLE" -o "$TMP" || die "no aft build for $TRIPLE ($BASE/aft-$TRIPLE)" chmod +x "$TMP" if ! "$TMP" --no-banner version >/dev/null 2>&1; then rm -f "$TMP" die "the downloaded binary for $TRIPLE failed to run" fi mv -f "$TMP" "$BIN_DIR/aft" VER="$("$BIN_DIR/aft" --no-banner version 2>/dev/null || echo '?')" say "" printf '%s✓%s %saft%s %sv%s%s ready\n' "$GREEN" "$RESET" "$BOLD" "$RESET" "$DIM" "$VER" "$RESET" printf '%s %s → %s%s\n' "$DIM" "$BIN_DIR/aft" "live URL" "$RESET" say "" printf ' %saft deploy%s ship (no login)\n' "$CYAN" "$RESET" printf ' %saft update%s latest CLI\n' "$CYAN" "$RESET" printf ' %saft --help%s\n' "$CYAN" "$RESET" case ":$PATH:" in *":$BIN_DIR:"*) ;; *) say "" printf '%s PATH tip — add this, then open a new terminal:%s\n' "$DIM" "$RESET" printf ' export PATH="%s:$PATH"\n' "$BIN_DIR" ;; esac say ""