#!/usr/bin/env bash # ============================================================ # Lyrie — One-line installer # Usage: curl -sSL https://lyrie.ai/install.sh | bash # Or: wget -qO- https://lyrie.ai/install.sh | bash # # Installs the Lyrie agent + ATP CLI on macOS and Linux. # © 2026 OTT Cybersecurity LLC — https://lyrie.ai # ============================================================ set -euo pipefail LYRIE_VERSION="3.0.0" REPO="https://github.com/OTT-Cybersecurity-LLC/lyrie-ai" BOLD="\033[1m" CYAN="\033[36m" GREEN="\033[32m" RED="\033[31m" YELLOW="\033[33m" RESET="\033[0m" banner() { echo "" echo -e "${CYAN}${BOLD}" echo " ██╗ ██╗ ██╗██████╗ ██╗███████╗" echo " ██║ ╚██╗ ██╔╝██╔══██╗██║██╔════╝" echo " ██║ ╚████╔╝ ██████╔╝██║█████╗ " echo " ██║ ╚██╔╝ ██╔══██╗██║██╔══╝ " echo " ███████╗██║ ██║ ██║██║███████╗" echo " ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝" echo -e "${RESET}" echo -e " ${BOLD}Agent Trust Protocol + Lyrie Security Agent${RESET}" echo -e " ${CYAN}v${LYRIE_VERSION} — OTT Cybersecurity LLC${RESET}" echo "" } info() { echo -e " ${CYAN}→${RESET} $1"; } success() { echo -e " ${GREEN}✓${RESET} $1"; } warn() { echo -e " ${YELLOW}⚠${RESET} $1"; } error() { echo -e " ${RED}✗${RESET} $1"; exit 1; } step() { echo -e "\n${BOLD}[$1]${RESET} $2"; } # ── OS detection ───────────────────────────────────────────── detect_os() { OS="unknown" ARCH="$(uname -m)" if [[ "$OSTYPE" == "darwin"* ]]; then OS="macos" elif [[ -f /etc/debian_version ]]; then OS="debian" elif [[ -f /etc/redhat-release ]]; then OS="rhel" elif [[ -f /etc/arch-release ]]; then OS="arch" elif [[ "$OSTYPE" == "linux-gnu"* ]]; then OS="linux" fi info "Detected: ${OS} (${ARCH})" } # ── Dependency checks ───────────────────────────────────────── check_deps() { step "1/5" "Checking dependencies" local missing=() command -v curl >/dev/null 2>&1 || missing+=("curl") command -v git >/dev/null 2>&1 || missing+=("git") if [[ ${#missing[@]} -gt 0 ]]; then warn "Missing: ${missing[*]}" info "Attempting to install missing dependencies..." if [[ "$OS" == "debian" ]]; then sudo apt-get update -qq && sudo apt-get install -y -qq "${missing[@]}" elif [[ "$OS" == "rhel" ]]; then sudo yum install -y -q "${missing[@]}" elif [[ "$OS" == "macos" ]]; then command -v brew >/dev/null 2>&1 && brew install "${missing[@]}" || \ error "Please install: ${missing[*]}" fi fi success "Dependencies satisfied" } # ── Node.js ─────────────────────────────────────────────────── check_node() { step "2/5" "Checking Node.js (>=20 required)" if command -v node >/dev/null 2>&1; then NODE_VER=$(node --version | sed 's/v//') NODE_MAJOR=$(echo "$NODE_VER" | cut -d. -f1) if [[ "$NODE_MAJOR" -ge 20 ]]; then success "Node.js $NODE_VER found" return else warn "Node.js $NODE_VER is too old — need v20+" fi fi info "Installing Node.js v22 via nvm..." curl -sSo- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash export NVM_DIR="$HOME/.nvm" # shellcheck source=/dev/null [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm install 22 --lts >/dev/null 2>&1 nvm use 22 >/dev/null 2>&1 success "Node.js $(node --version) ready" } # ── Python (for lyrie-omega) ────────────────────────────────── check_python() { step "3/5" "Checking Python (>=3.10 required for lyrie-omega)" if command -v python3 >/dev/null 2>&1; then PY_VER=$(python3 --version | awk '{print $2}') PY_MINOR=$(echo "$PY_VER" | cut -d. -f2) if [[ "$PY_MINOR" -ge 10 ]]; then success "Python $PY_VER found" return fi fi warn "Python 3.10+ not found — lyrie-omega will be skipped" SKIP_PYTHON=1 } # ── Install packages ────────────────────────────────────────── install_packages() { step "4/5" "Installing Lyrie packages" # @lyrie/atp info "Installing @lyrie/atp (Agent Trust Protocol)..." if npm install -g @lyrie/atp >/dev/null 2>&1; then success "@lyrie/atp@${LYRIE_VERSION} installed" else warn "@lyrie/atp install failed — try: npm install @lyrie/atp" fi # lyrie-omega (Python) if [[ -z "${SKIP_PYTHON:-}" ]]; then info "Installing lyrie-omega (binary analysis engine)..." if python3 -m pip install lyrie-omega --quiet 2>/dev/null; then success "lyrie-omega@${LYRIE_VERSION} installed" else warn "lyrie-omega install failed — try: pip install lyrie-omega" fi fi } # ── Verify installation ─────────────────────────────────────── verify() { step "5/5" "Verifying installation" local ok=1 if npm list -g @lyrie/atp >/dev/null 2>&1; then success "npm: @lyrie/atp ✓" else warn "npm: @lyrie/atp not detected globally (may still work as local dep)" ok=0 fi if command -v python3 >/dev/null 2>&1 && python3 -c "import omega" >/dev/null 2>&1; then success "python: lyrie-omega ✓" else info "python: lyrie-omega available via 'pip install lyrie-omega'" fi echo "" echo -e "${GREEN}${BOLD}══════════════════════════════════════════${RESET}" echo -e "${GREEN}${BOLD} Lyrie v${LYRIE_VERSION} installation complete!${RESET}" echo -e "${GREEN}${BOLD}══════════════════════════════════════════${RESET}" echo "" echo -e " ${BOLD}Quick start:${RESET}" echo -e " npm install @lyrie/atp # ATP SDK" echo -e " pip install lyrie-omega # Binary analysis" echo "" echo -e " ${BOLD}Resources:${RESET}" echo -e " 🌐 Platform: https://lyrie.ai" echo -e " 📄 ATP Spec: https://atp.lyrie.ai" echo -e " 📦 GitHub: ${REPO}" echo -e " 📡 Research: https://research.lyrie.ai" echo "" } # ── Main ────────────────────────────────────────────────────── main() { banner detect_os check_deps check_node check_python install_packages verify } main "$@"