#!/bin/bash # PiSystem install.sh — Deterministisches Setup für alle Maschinen # # Installiert alle Pi-Orchestrator-Infrastrukturkomponenten: # - bin/Sub* → ~/bin/ + /usr/local/bin/ # - extensions/ → ~/.pi/agent/extensions/ # - memory/ → ~/.pi/agent/memory/ # - agent/AGENTS.md → ~/.pi/agent/AGENTS.md # # Idempotent: Kann beliebig oft ausgeführt werden. # Erstellt Backups mit Timestamp vor jedem Überschreiben. # # Voraussetzungen: # - pi (Pi Agent CLI) installiert # - tmux installiert # - intercom (pi-intercom npm package) installiert # # Nutzung: # ./install.sh # Vollinstallation # ./install.sh --dry-run # Zeigt was getan würde ohne Änderungen set -euo pipefail REPO_DIR="$(cd "$(dirname "$0")" && pwd)" DRY_RUN=false [ "${1:-}" = "--dry-run" ] && DRY_RUN=true TS=$(date '+%Y-%m-%d-%H-%M') BACKUP_SUFFIX=".bak-v${TS}" green() { echo -e "\033[0;32m✓ $*\033[0m"; } yellow() { echo -e "\033[0;33m⚠ $*\033[0m"; } red() { echo -e "\033[0;31m✗ $*\033[0m"; } info() { echo -e " $*"; } install_file() { local src="$1" local dst="$2" local executable="${3:-false}" if [ ! -f "$src" ]; then red "Quelldatei fehlt: $src" return 1 fi local dst_dir dst_dir="$(dirname "$dst")" if $DRY_RUN; then info "[DRY-RUN] $src → $dst" return 0 fi mkdir -p "$dst_dir" # Backup falls Ziel existiert und sich unterscheidet if [ -f "$dst" ] && ! diff -q "$src" "$dst" &>/dev/null; then cp "$dst" "${dst}${BACKUP_SUFFIX}" info "Backup: ${dst}${BACKUP_SUFFIX}" fi cp "$src" "$dst" [ "$executable" = "true" ] && chmod +x "$dst" green "$dst" } echo "" echo "═══════════════════════════════════════════════════════" echo " PiSystem Installation — $(date '+%Y-%m-%d %H:%M')" $DRY_RUN && echo " MODUS: DRY-RUN (keine Änderungen)" echo "═══════════════════════════════════════════════════════" echo "" # ─── Voraussetzungen prüfen ───────────────────────────────── echo "── Voraussetzungen ────────────────────────────────────" check_cmd() { if command -v "$1" &>/dev/null; then green "$1 vorhanden ($(command -v "$1"))" else red "$1 FEHLT — Installation erforderlich: $2" MISSING=true fi } MISSING=false check_cmd "tmux" "apt install tmux" check_cmd "pi" "Siehe CrowdBrain neue-maschine.md für Pi-Installation" check_cmd "zenity" "apt install zenity (für Desktop-Notifications von SubConfirm)" $MISSING && { echo ""; red "Fehlende Voraussetzungen — Abbruch."; exit 1; } # pi-intercom als Pi-Package prüfen (kein Shell-Binary, daher separat) if pi list-packages 2>/dev/null | grep -q "pi-intercom"; then green "pi-intercom installiert" else yellow "pi-intercom nicht gefunden — in Pi ausführen: pi install npm:pi-intercom" fi echo "" # ─── bin/ → ~/bin/ ────────────────────────────────────────── echo "── bin/ → ~/bin/ ──────────────────────────────────────" mkdir -p "$HOME/bin" for f in "$REPO_DIR"/bin/*; do [ -f "$f" ] || continue install_file "$f" "$HOME/bin/$(basename "$f")" true done echo "" # ─── bin/ → /usr/local/bin/ (nur Sub* Skripte) ────────────── echo "── bin/Sub* → /usr/local/bin/ ─────────────────────────" for f in "$REPO_DIR"/bin/Sub*; do [ -f "$f" ] || continue DST="/usr/local/bin/$(basename "$f")" if $DRY_RUN; then info "[DRY-RUN] $f → $DST (sudo)" elif sudo -n true 2>/dev/null; then sudo cp "$f" "$DST" && sudo chmod +x "$DST" green "$DST" else yellow "/usr/local/bin: sudo nötig — übersprungen (~/bin reicht)" break fi done echo "" # ─── Extensions ───────────────────────────────────────────── echo "── extensions/ → ~/.pi/agent/extensions/ ──────────────" mkdir -p "$HOME/.pi/agent/extensions" for f in "$REPO_DIR"/extensions/*; do [ -f "$f" ] || continue install_file "$f" "$HOME/.pi/agent/extensions/$(basename "$f")" done echo "" # ─── Memory ───────────────────────────────────────────────── echo "── memory/ → ~/.pi/agent/memory/ ──────────────────────" mkdir -p "$HOME/.pi/agent/memory" for f in "$REPO_DIR"/memory/*; do [ -f "$f" ] || continue install_file "$f" "$HOME/.pi/agent/memory/$(basename "$f")" done echo "" # ─── AGENTS.md ────────────────────────────────────────────── echo "── agent/ → ~/.pi/agent/ ───────────────────────────────" install_file "$REPO_DIR/agent/AGENTS.md" "$HOME/.pi/agent/AGENTS.md" install_file "$REPO_DIR/agent/settings.json" "$HOME/.pi/agent/settings.json" echo "" # ─── PATH prüfen ──────────────────────────────────────────── echo "── PATH-Check ──────────────────────────────────────────" if echo "$PATH" | grep -q "$HOME/bin"; then green "~/bin ist im PATH" else yellow "~/bin ist NICHT im PATH" info "Folgendes in ~/.bashrc oder ~/.zshrc eintragen:" info ' export PATH="$HOME/bin:$PATH"' fi echo "" # ─── SubConfirm-Autostart Hinweis ─────────────────────────── echo "── SubConfirm ──────────────────────────────────────────" if pgrep -f SubConfirm &>/dev/null; then green "SubConfirm läuft bereits (PID: $(pgrep -f SubConfirm))" else yellow "SubConfirm läuft nicht" info "Starten mit: SubConfirm --skip \"\$(tmux display-message -p '#S')\" &" info "Für Autostart beim Pi-Session-Start: in AGENTS.md ist das bereits eingetragen." fi echo "" echo "═══════════════════════════════════════════════════════" $DRY_RUN && echo " DRY-RUN abgeschlossen — keine Änderungen vorgenommen" || echo " Installation abgeschlossen ✓" echo "═══════════════════════════════════════════════════════" echo ""