#!/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 "$@"