#!/bin/sh # Effective Intelligence : one line installer. # # curl -fsSL https://effective-intelligence-app.netlify.app/install.sh | bash # # POSIX sh compatible, safe to pipe into sh or bash. It clones (or updates) the # repo into $EI_HOME, installs dependencies with Bun, then runs the hardware # detection so the operator immediately sees what this machine is worth. # # Environment overrides: # EI_HOME install directory (default: $HOME/.effective-intelligence) # EI_REPO git remote to clone from (default: the X-Ventures GitHub repo) # EI_NO_RUN set to 1 to skip the post-install `detect` step # # Nothing is installed on your system without consent: if Bun is missing, the # script prints the official Bun command and only runs it after you say yes. set -eu EI_REPO="${EI_REPO:-https://github.com/X-Ventures/effective-intelligence.git}" EI_HOME="${EI_HOME:-$HOME/.effective-intelligence}" EI_NO_RUN="${EI_NO_RUN:-0}" DOCS_URL="https://effective-intelligence-app.netlify.app/docs/install.html" # Official Bun installer, verbatim from https://bun.com/docs/installation # (canonical URL, https://bun.sh/docs/installation redirects there). BUN_INSTALL_CMD='curl -fsSL https://bun.com/install | bash' # ---------------------------------------------------------------- output ---- if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then C_RESET=$(printf '\033[0m') C_BOLD=$(printf '\033[1m') C_ORANGE=$(printf '\033[38;5;208m') C_RED=$(printf '\033[31m') C_DIM=$(printf '\033[2m') else C_RESET=''; C_BOLD=''; C_ORANGE=''; C_RED=''; C_DIM='' fi say() { printf '%s\n' "$*"; } step() { printf '%s==>%s %s\n' "$C_ORANGE$C_BOLD" "$C_RESET" "$*"; } info() { printf '%s %s%s\n' "$C_DIM" "$*" "$C_RESET"; } die() { printf '%serror:%s %s\n' "$C_RED$C_BOLD" "$C_RESET" "$*" >&2 exit 1 } usage() { cat </dev/null || echo unknown) ARCH_RAW=$(uname -m 2>/dev/null || echo unknown) case "$OS_RAW" in Darwin) OS=darwin ;; Linux) OS=linux ;; MINGW*|MSYS*|CYGWIN*|Windows_NT) printf '%serror:%s Windows is not supported natively.\n' "$C_RED$C_BOLD" "$C_RESET" >&2 say "" >&2 say " Effective Intelligence reads hardware through macOS sysctl and Linux /proc." >&2 say " Install WSL2 (Ubuntu), then run this same command inside the WSL shell:" >&2 say "" >&2 say " wsl --install -d Ubuntu" >&2 say " # then, inside Ubuntu:" >&2 say " curl -fsSL https://effective-intelligence-app.netlify.app/install.sh | bash" >&2 say "" >&2 say " Note: GPU detection inside WSL2 requires the Windows NVIDIA driver with" >&2 say " WSL CUDA support, so nvidia-smi is reachable from Linux." >&2 exit 1 ;; *) die "unsupported operating system '$OS_RAW'. Supported: macOS (Darwin) and Linux." ;; esac case "$ARCH_RAW" in x86_64|amd64) ARCH=x64 ;; arm64|aarch64) ARCH=arm64 ;; *) die "unsupported architecture '$ARCH_RAW'. Bun ships binaries for x86_64 and arm64 only (https://bun.com/docs/installation)." ;; esac step "Effective Intelligence installer" info "platform : $OS/$ARCH" info "target : $EI_HOME" # ----------------------------------------------------------------- git ------ command -v git >/dev/null 2>&1 || die "git is required but was not found in PATH. Install git, then re-run this script." # ----------------------------------------------------------------- bun ------ # Bun installs to ~/.bun/bin, which a piped shell may not have on PATH yet. if [ -x "${BUN_INSTALL:-$HOME/.bun}/bin/bun" ]; then PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH" export PATH fi # Ask a yes/no question. Uses /dev/tty so it still works under `curl | bash`, # where stdin is the script itself. Returns 1 when no terminal is available. ask_yes_no() { question="$1" # A device node can exist yet be unopenable (daemons, CI): probe it for real. if { true < /dev/tty; } 2>/dev/null; then printf '%s [y/N] ' "$question" > /dev/tty 2>/dev/null || return 1 read -r answer < /dev/tty 2>/dev/null || return 1 elif [ -t 0 ]; then printf '%s [y/N] ' "$question" read -r answer || return 1 else return 1 fi case "$answer" in y|Y|yes|Yes|YES) return 0 ;; *) return 1 ;; esac } if ! command -v bun >/dev/null 2>&1; then say "" say "Bun was not found. Effective Intelligence runs entirely on Bun, no build step." say "The official install command (https://bun.com/docs/installation) is:" say "" say " $BUN_INSTALL_CMD" say "" if ask_yes_no "Run that command now?"; then step "Installing Bun" # Runs the official upstream installer, only after explicit consent. sh -c "$BUN_INSTALL_CMD" || die "the Bun installer failed. Install Bun manually, then re-run this script." PATH="${BUN_INSTALL:-$HOME/.bun}/bin:$PATH" export PATH command -v bun >/dev/null 2>&1 || die "Bun installed but is not on PATH. Add \"\$HOME/.bun/bin\" to PATH, then re-run this script." else say "" die "Bun is required. Install it with the command above, then re-run this script." fi fi info "bun : $(bun --version 2>/dev/null || echo unknown)" # --------------------------------------------------------------- clone ------ clone_failed() { say "" >&2 printf '%serror:%s could not clone %s\n' "$C_RED$C_BOLD" "$C_RESET" "$EI_REPO" >&2 say "" >&2 say " The Effective Intelligence repository is currently PRIVATE, so an" >&2 say " anonymous clone will always fail. You need repository access:" >&2 say "" >&2 say " 1. Ask for access to $EI_REPO" >&2 say " 2. Authenticate git, for example: gh auth login" >&2 say " (or add an SSH key and use EI_REPO=git@github.com:X-Ventures/effective-intelligence.git)" >&2 say " 3. Re-run this installer." >&2 say "" >&2 say " Any git remote works, override it with EI_REPO:" >&2 say "" >&2 say " EI_REPO=git@github.com:X-Ventures/effective-intelligence.git \\" >&2 say " sh -c \"\$(curl -fsSL https://effective-intelligence-app.netlify.app/install.sh)\"" >&2 say "" >&2 say " Docs: $DOCS_URL" >&2 exit 1 } if [ -d "$EI_HOME/.git" ]; then step "Updating existing clone" if ! git -C "$EI_HOME" pull --ff-only; then say "" >&2 printf '%serror:%s git pull failed in %s\n' "$C_RED$C_BOLD" "$C_RESET" "$EI_HOME" >&2 say " Fix or delete that directory (it may have local changes, or you may have" >&2 say " lost access to the private remote), then re-run this installer." >&2 exit 1 fi elif [ -e "$EI_HOME" ]; then # Present but not a git clone: move it aside rather than deleting user data. BACKUP="$EI_HOME.bak.$(date +%Y%m%d%H%M%S)" step "Existing non-git directory found, moving it to $BACKUP" mv "$EI_HOME" "$BACKUP" step "Cloning $EI_REPO" git clone --depth 1 "$EI_REPO" "$EI_HOME" || clone_failed else step "Cloning $EI_REPO" mkdir -p "$(dirname "$EI_HOME")" git clone --depth 1 "$EI_REPO" "$EI_HOME" || clone_failed fi # ------------------------------------------------------------- install ------ step "Installing dependencies (bun install)" cd "$EI_HOME" bun install || die "'bun install' failed in $EI_HOME." # -------------------------------------------------------------- detect ------ if [ "$EI_NO_RUN" = "1" ]; then info "EI_NO_RUN=1, skipping hardware detection." else step "Detecting your hardware" # Read-only: prints CPU, RAM, GPUs and the matched profile. No network writes, # no workload started. The agent stays in dry-run until data/agent.json says # otherwise. bun run src/agent-cli.ts detect || die "hardware detection failed. Run it manually: cd $EI_HOME && bun run src/agent-cli.ts detect" fi # ---------------------------------------------------------------- next ------ say "" step "Installed in $EI_HOME" say "" say " Next:" say " cd $EI_HOME" say " bun run src/agent-cli.ts plan # what this machine should run today" say " bun run src/agent-cli.ts run 15 # re-plan loop, dry-run by default" say " bun run src/mcp-server.ts # MCP server, for agent clients" say "" say " Config: $EI_HOME/data/agent.json (set kwhUsd to your real electricity price)." say " Nothing executes for real until dryRun is false AND a binary or key is set." say "" say " Docs: $DOCS_URL" say ""