#!/bin/sh # One-paste cold install / CLI upgrade faucet. # # Public shape (canonical; do not invent cousins): # curl -fsSL https://get.xterminal.app | sh # # Env: # XTERMINAL_INSTALL_BASE_URL default https://get.xterminal.app # XTERMINAL_INSTALL_DIR optional --path for install-cli # # Downloads the latest CLI payload, verifies sha256, execs a liveness check, # then delegates to `xleads install-cli`. # # Body is wrapped in main(); only main "$@" at the bottom so a truncated # curl|sh pipe never half-runs. # shellcheck shell=sh disable=SC2039,SC3043 main() { set -eu umask 022 case "$(uname -s)" in Darwin) ;; *) echo "get-xterminal: Darwin (macOS) only; refusing on $(uname -s)" >&2 exit 1 ;; esac TMP_DIR="" cleanup() { if [ -n "${TMP_DIR:-}" ] && [ -d "$TMP_DIR" ]; then rm -rf "$TMP_DIR" fi } trap cleanup EXIT INT HUP TERM require_cmd() { if ! command -v "$1" >/dev/null 2>&1; then echo "get-xterminal: missing required command: $1" >&2 exit 1 fi } require_cmd curl require_cmd shasum require_cmd mktemp require_cmd mkdir require_cmd chmod require_cmd sed require_cmd awk require_cmd head require_cmd tar require_cmd dd require_cmd od require_cmd tr XTERMINAL_TTY=0 if [ -t 2 ] && [ -n "${TERM:-}" ] && [ "$TERM" != "dumb" ] && [ -z "${NO_COLOR:-}" ]; then XTERMINAL_TTY=1 fi paint_reset="" paint_blue="" paint_muted="" if [ "$XTERMINAL_TTY" -eq 1 ]; then paint_reset="$(printf '\033[0m')" paint_blue="$(printf '\033[38;2;29;155;240m')" paint_muted="$(printf '\033[38;2;113;118;123m')" fi step() { if [ "$XTERMINAL_TTY" -eq 1 ]; then printf '%s %-11s%s %s%s%s\n' "$paint_muted" "$1" "$paint_reset" "$paint_blue" "$2" "$paint_reset" >&2 fi } BASE="${XTERMINAL_INSTALL_BASE_URL:-https://get.xterminal.app}" case "$BASE" in */) BASE="${BASE%/}" ;; esac TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/get-xterminal.XXXXXX")" MANIFEST="$TMP_DIR/latest.json" DOWNLOAD="$TMP_DIR/xleads-macos-universal" step "fetching" "$BASE" if ! curl -fsSL "$BASE/latest.json" -o "$MANIFEST" &2 exit 1 fi extract_string() { _key="$1" _file="$2" sed -n 's/.*"'"$_key"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$_file" | head -n 1 } CLI_URL="$(extract_string url "$MANIFEST")" CLI_SHA="$(extract_string sha256 "$MANIFEST")" if [ -z "$CLI_URL" ] || [ -z "$CLI_SHA" ]; then echo "get-xterminal: latest.json missing cli.url or cli.sha256" >&2 exit 1 fi if [ "${#CLI_SHA}" -ne 64 ]; then echo "get-xterminal: cli.sha256 is not 64 hex chars (got length ${#CLI_SHA})" >&2 exit 1 fi step "downloading" "xleads" if ! curl -fsSL "$CLI_URL" -o "$DOWNLOAD" &2 exit 1 fi GOT_SHA="$(shasum -a 256 "$DOWNLOAD" | awk '{print $1}')" if [ "$GOT_SHA" != "$CLI_SHA" ]; then echo "get-xterminal: sha256 mismatch — refusing install (fail closed)" >&2 echo " expected: $CLI_SHA" >&2 echo " got: $GOT_SHA" >&2 exit 1 fi chmod 755 "$DOWNLOAD" step "verified" "sha256" is_gzip_payload() { _magic="$(dd if="$1" bs=1 count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')" [ "$_magic" = "1f8b" ] } if is_gzip_payload "$DOWNLOAD"; then PAYLOAD_DIR="$TMP_DIR/payload" mkdir -p "$PAYLOAD_DIR" if ! tar -xzf "$DOWNLOAD" -C "$PAYLOAD_DIR"; then echo "get-xterminal: failed to extract CLI payload" >&2 exit 1 fi if [ -x "$PAYLOAD_DIR/xleads-macos-universal" ]; then DOWNLOAD="$PAYLOAD_DIR/xleads-macos-universal" elif [ -x "$PAYLOAD_DIR/xleads" ]; then DOWNLOAD="$PAYLOAD_DIR/xleads" else echo "get-xterminal: archive missing xleads binary" >&2 exit 1 fi chmod 755 "$DOWNLOAD" fi # Leave Documents/Desktop/Downloads before any xleads exec. macOS TCC # attributes getcwd / inherited cwd to the CLI binary. if ! cd "$HOME"; then echo "get-xterminal: failed to cd to HOME before running xleads" >&2 exit 1 fi if ! "$DOWNLOAD" backend hello --json /dev/null; then echo "get-xterminal: downloaded binary failed liveness check: $DOWNLOAD backend hello --json" >&2 exit 1 fi INSTALL_ARGS="install-cli" if [ -n "${XTERMINAL_INSTALL_DIR:-}" ]; then INSTALL_ARGS="install-cli --path $XTERMINAL_INSTALL_DIR" fi step "installing" "xleads" # shellcheck disable=SC2086 exec "$DOWNLOAD" $INSTALL_ARGS } main "$@"