#!/usr/bin/env bash set -Eeuo pipefail umask 077 ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" INSTALL_PACKAGES=0 INSTALL_HERMES=0 INSTALL_LLAMA=0 LLAMA_REF="" ENABLE_TIMERS=0 SKIP_BROWSER=1 usage() { sed -n '/^## Installationsoptionen/,/^## /p' "$ROOT_DIR/README.md" | sed '$d' } while (($# > 0)); do case "$1" in --install-packages) INSTALL_PACKAGES=1 ;; --install-hermes) INSTALL_HERMES=1 ;; --install-llama) INSTALL_LLAMA=1 ;; --llama-ref) [[ $# -ge 2 ]] || exit 2; LLAMA_REF="$2"; shift ;; --enable-timers) ENABLE_TIMERS=1 ;; --skip-browser) SKIP_BROWSER=1 ;; --with-browser) SKIP_BROWSER=0 ;; -h|--help) usage; exit 0 ;; *) printf 'Unbekannte Option: %s\n' "$1" >&2; usage >&2; exit 2 ;; esac shift done if ((INSTALL_LLAMA)) && [[ -z "$LLAMA_REF" ]]; then printf -- '--install-llama benötigt --llama-ref TAG_ODER_COMMIT (oder bewusst master).\n' >&2 exit 2 fi if [[ ! -e /etc/arch-release ]]; then printf 'Warnung: Dieses Deployment ist für Arch Linux ausgelegt.\n' >&2 fi export PATH="$HOME/.local/bin:$PATH" if ((INSTALL_PACKAGES)); then # Vollständige Aktualisierung statt partieller Arch-Aktualisierung. packages=( bash git curl xz jq zstd tar ripgrep ffmpeg coreutils util-linux \ jre-openjdk-headless ) if ((INSTALL_LLAMA)); then packages+=(base-devel cmake ninja cuda openssl) fi sudo pacman -Syu --needed "${packages[@]}" fi if ((INSTALL_LLAMA)); then "$ROOT_DIR/scripts/install-llama-cpp.sh" --ref "$LLAMA_REF" fi if ((INSTALL_HERMES)) && ! command -v hermes >/dev/null 2>&1; then installer_args=() ((SKIP_BROWSER)) && installer_args+=(--skip-browser) curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- "${installer_args[@]}" export PATH="$HOME/.local/bin:$PATH" fi config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/hermes-stack-maintenance" unit_dir="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user" libexec_dir="$HOME/.local/libexec" mkdir -p "$config_dir" "$unit_dir" "$libexec_dir" "${XDG_STATE_HOME:-$HOME/.local/state}" # Bestehende Deployment-Dateien vor Ersetzen sichern. Keine Secrets ausgeben. deploy_backup="$(mktemp -d "${XDG_STATE_HOME:-$HOME/.local/state}/hermes-stack-deployment.XXXXXXXX")" mkdir -p "$deploy_backup/libexec" "$deploy_backup/units" for file in "$ROOT_DIR"/libexec/*; do target="$libexec_dir/$(basename "$file")" [[ ! -e "$target" ]] || cp -a -- "$target" "$deploy_backup/libexec/" done for file in "$ROOT_DIR"/systemd/user/*; do target="$unit_dir/$(basename "$file")" [[ ! -e "$target" ]] || cp -a -- "$target" "$deploy_backup/units/" done printf 'Vorherige Deployment-Dateien: %s\n' "$deploy_backup" for file in "$ROOT_DIR"/libexec/*; do install -m 0755 "$file" "$libexec_dir/$(basename "$file")" done for file in "$ROOT_DIR"/systemd/user/*; do install -m 0644 "$file" "$unit_dir/$(basename "$file")" done install_config_if_missing() { local example="$1" target="$2" if [[ ! -e "$target" ]]; then install -m 0600 "$example" "$target" printf 'Konfiguration angelegt: %s\n' "$target" else printf 'Konfiguration beibehalten: %s\n' "$target" fi } install_config_if_missing \ "$ROOT_DIR/config/config.env.example" "$config_dir/config.env" install_config_if_missing \ "$ROOT_DIR/config/llama.env.example" "$config_dir/llama.env" install_config_if_missing \ "$ROOT_DIR/config/signal-cli.env.example" "$config_dir/signal-cli.env" if [[ ! -e "$HOME/.hermes/.env" ]]; then mkdir -p "$HOME/.hermes" install -m 0600 "$ROOT_DIR/config/hermes.env.example" "$HOME/.hermes/.env" printf 'Hermes-Umgebung angelegt: %s\n' "$HOME/.hermes/.env" fi systemctl --user daemon-reload if command -v hermes >/dev/null 2>&1 && [[ ! -e "$unit_dir/hermes-gateway.service" ]]; then if [[ -d "$HOME/.hermes/hermes-agent/.git" ]]; then hermes gateway install || printf 'Gateway-Unit konnte noch nicht erzeugt werden; nach `hermes setup` erneut ausführen.\n' >&2 fi fi if ((ENABLE_TIMERS)); then systemctl --user enable --now \ hermes-stack-hermes-update.timer \ hermes-stack-health.timer \ hermes-stack-signal-health.timer \ hermes-stack-signal-update-check.timer fi printf '\nDeployment installiert. Nächster Schritt:\n %s\n' \ "$libexec_dir/hermes-stack-doctor"