#!/bin/sh # Siphrix installer - macOS / Linux # # What this does, in order, and nothing else: # 1. Finds Python 3.11+ (tells you where to get it if missing). # 2. Installs the siphrix package from PyPI into your user site. # 3. Runs `siphrix set-up` - which senses what is on this machine # (Claude Code, Codex, VS Code, browsers, local models) and offers # to connect each one. Nothing is connected without asking you. # # Served as plain text so you can read every line first: # curl -fsSL https://siphrix.com/install.sh | sh # is convenient; opening the URL in a browser first is wiser. set -e say() { printf ' %s\n' "$1"; } fail() { printf '\n x %s\n\n' "$1" >&2; exit 1; } printf '\n SIPHRIX - AI Action Audit & Risk Monitor\n' printf ' Records what your AI does. Blocks nothing.\n\n' # --- 1. Python ------------------------------------------------------------ PY="" for candidate in python3 python; do if command -v "$candidate" >/dev/null 2>&1; then if "$candidate" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)' 2>/dev/null; then PY="$candidate"; break fi fi done if [ -z "$PY" ]; then # macOS gets an offer; Linux gets the command and nothing else. A # package manager on Linux is the administrator's territory, and an # installer that reaches for sudo is an installer IT blocks. printf '\n Python 3.11+ is required and was not found.\n\n' if [ "$(uname -s)" = "Darwin" ] && command -v brew >/dev/null 2>&1; then printf ' [1] Install it now (brew install python@3.12)\n' printf ' [2] I will install it myself - stop here\n\n' printf ' Choose [1]: ' read -r choice /dev/null || choice=2 [ "$choice" = "2" ] && fail "Install Python, then run this again." brew install python@3.12 || fail "brew could not install Python." for candidate in python3 python; do if command -v "$candidate" >/dev/null 2>&1 && \ "$candidate" -c 'import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)' 2>/dev/null; then PY="$candidate"; break fi done fi [ -n "$PY" ] || fail "Install Python 3.11+ with your package manager (e.g. apt install python3), then run this again." fi say "OK Python $("$PY" -c 'import sys;print(sys.version.split()[0])') found" # --- 2. The package ------------------------------------------------------- say "... installing siphrix from PyPI" "$PY" -m pip install --upgrade --user --quiet siphrix \ || fail "pip could not install siphrix. Check your network and try again." say "OK siphrix $("$PY" -c 'import siphrix;print(siphrix.__version__)') installed" # --- 3. Company or personal ------------------------------------------------ # Asked outright rather than inferred. A wrong guess either sends records # to a console nobody chose, or leaves a company laptop invisible to the # people answerable for it - and the person answering cannot undo either. printf '\n ---------------------------------------------------------\n' printf ' Is this machine part of a company account?\n\n' printf ' [1] Yes - I have a connection code\n' printf ' [2] No - personal use, nothing leaves this machine\n\n' printf ' Choose [2]: ' read -r mode /dev/null || mode=2 printf ' ---------------------------------------------------------\n\n' CODE="" SERVER="https://siphrix.com" if [ "$mode" = "1" ]; then printf ' Paste your connection code: ' read -r CODE /dev/null || CODE="" printf ' Console [https://siphrix.com]: ' read -r entered /dev/null || entered="" [ -n "$entered" ] && SERVER="$entered" fi if [ -n "$CODE" ]; then "$PY" -m siphrix set-up --code "$CODE" --server "$SERVER" || true else "$PY" -m siphrix set-up --personal || true fi # --- 4. Say the commands that actually work on THIS machine --------------- # `pip install --user` puts the entry point in a per-user bin directory # that is frequently not on PATH - ~/.local/bin on Linux, a versioned # Python directory on macOS. Printing "siphrix coverage" regardless would # hand somebody three commands that answer "command not found" a minute # after installing an audit tool. printf '\n Done. Useful next steps:\n' if command -v siphrix >/dev/null 2>&1; then say "siphrix coverage what is recorded here, and what is not" say "siphrix console open the local console" say "siphrix doctor check the install end to end" else say "$PY -m siphrix coverage what is recorded here, and what is not" say "$PY -m siphrix console open the local console" say "$PY -m siphrix doctor check the install end to end" BIN="$("$PY" -c "import sysconfig;print(sysconfig.get_path('scripts', scheme='posix_user'))" 2>/dev/null)" [ -n "$BIN" ] && printf '\n (the bare "siphrix" command needs %s on your PATH)\n' "$BIN" fi printf '\n'