#!/usr/bin/env bash set -euo pipefail BINARY_NAME="email-mcp" DEFAULT_PROFILE="default" PROFILE_ENV="EMAIL_MCP_PROFILE" RELEASE_BASE_URL="https://gitea.lclr.dev" RELEASE_REPOSITORY="AI/email-mcp" prompt() { local label="$1" local default_value="$2" local answer="" if [ -n "$default_value" ]; then printf "%s [%s]: " "$label" "$default_value" else printf "%s: " "$label" fi if [ -r /dev/tty ]; then IFS= read -r answer < /dev/tty || answer="" else IFS= read -r answer || answer="" fi if [ -z "$answer" ]; then printf "%s" "$default_value" return fi printf "%s" "$answer" } detect_os() { case "$(uname -s | tr '[:upper:]' '[:lower:]')" in linux) printf "linux" ;; darwin) printf "darwin" ;; *) printf "OS non supporté: %s\n" "$(uname -s)" >&2 exit 1 ;; esac } detect_arch() { case "$(uname -m)" in x86_64|amd64) printf "amd64" ;; aarch64|arm64) printf "arm64" ;; *) printf "Architecture non supportée: %s\n" "$(uname -m)" >&2 exit 1 ;; esac } release_api_url() { printf "%s/api/v1/repos/%s/releases/latest\n" "${RELEASE_BASE_URL%/}" "$RELEASE_REPOSITORY" } extract_asset_url() { local json="$1" local asset_name="$2" printf "%s\n" "$json" \ | grep -o '"browser_download_url":"[^"]*"' \ | sed 's/"browser_download_url":"//;s/"$//' \ | sed 's#\\/#/#g' \ | grep "/${asset_name}$" \ | head -n 1 } go_bin_dir() { local gobin gobin="$(go env GOBIN 2>/dev/null || true)" if [ -n "$gobin" ]; then printf "%s\n" "$gobin" return fi go env GOPATH 2>/dev/null | awk '{print $1 "/bin"}' } resolve_binary_path() { if command -v "$BINARY_NAME" >/dev/null 2>&1; then command -v "$BINARY_NAME" return fi if command -v go >/dev/null 2>&1; then local bin_dir bin_dir="$(go_bin_dir)" if [ -n "$bin_dir" ] && [ -x "$bin_dir/$BINARY_NAME" ]; then printf "%s\n" "$bin_dir/$BINARY_NAME" return fi fi printf "%s\n" "$HOME/.local/bin/$BINARY_NAME" } verify_checksum() { local binary_path="$1" local checksum_path="$2" if command -v sha256sum >/dev/null 2>&1; then ( cd "$(dirname "$binary_path")" && sha256sum -c "$(basename "$checksum_path")" ) return fi if command -v shasum >/dev/null 2>&1; then local expected local actual expected="$(awk '{print $1}' "$checksum_path")" actual="$(shasum -a 256 "$binary_path" | awk '{print $1}')" if [ "$expected" != "$actual" ]; then printf "Checksum invalide pour %s\n" "$binary_path" >&2 exit 1 fi return fi printf "Aucun utilitaire de checksum trouvé (sha256sum/shasum), vérification ignorée.\n" >&2 } download_latest_release_binary() { if ! command -v curl >/dev/null 2>&1; then printf "curl est requis pour télécharger la release.\n" >&2 exit 1 fi local os_name local arch_name local ext="" os_name="$(detect_os)" arch_name="$(detect_arch)" if [ "$os_name" = "windows" ]; then ext=".exe" fi local asset_name local checksum_name asset_name="${BINARY_NAME}-${os_name}-${arch_name}${ext}" checksum_name="${asset_name}.sha256" printf "Récupération de la dernière release...\n" local release_json release_json="$(curl -fsSL "$(release_api_url)")" local asset_url asset_url="$(extract_asset_url "$release_json" "$asset_name")" if [ -z "$asset_url" ]; then printf "Asset introuvable dans la dernière release: %s\n" "$asset_name" >&2 exit 1 fi local checksum_url checksum_url="$(extract_asset_url "$release_json" "$checksum_name" || true)" local tmp_dir tmp_dir="$(mktemp -d)" trap 'rm -rf "$tmp_dir"' EXIT INT TERM curl -fsSL "$asset_url" -o "$tmp_dir/$asset_name" chmod +x "$tmp_dir/$asset_name" if [ -n "$checksum_url" ]; then curl -fsSL "$checksum_url" -o "$tmp_dir/$checksum_name" verify_checksum "$tmp_dir/$asset_name" "$tmp_dir/$checksum_name" fi local target_dir target_dir="$(prompt "Répertoire d'installation" "$HOME/.local/bin")" mkdir -p "$target_dir" install -m 0755 "$tmp_dir/$asset_name" "$target_dir/$BINARY_NAME" printf "Binaire installé: %s/%s\n" "$target_dir" "$BINARY_NAME" printf "Ajoute ce dossier au PATH si nécessaire.\n" } install_binary() { if command -v "$BINARY_NAME" >/dev/null 2>&1; then printf "Binaire détecté: %s\n" "$(command -v "$BINARY_NAME")" local reinstall reinstall="$(prompt "Forcer une réinstallation depuis la dernière release ? (y/N)" "N")" case "$reinstall" in y|Y|yes|YES) download_latest_release_binary ;; *) return ;; esac return fi download_latest_release_binary } run_setup_wizard() { install_binary local profile profile="$(prompt "Profil à configurer (${PROFILE_ENV})" "$DEFAULT_PROFILE")" local binary_path binary_path="$(resolve_binary_path)" printf "Lancement de %s setup...\n\n" "$BINARY_NAME" if [ -r /dev/tty ] && [ -w /dev/tty ]; then env "${PROFILE_ENV}=${profile}" "$binary_path" setup < /dev/tty > /dev/tty else env "${PROFILE_ENV}=${profile}" "$binary_path" setup fi } print_mcp_json() { local profile profile="$(prompt "Profil à exposer dans la config MCP (${PROFILE_ENV})" "$DEFAULT_PROFILE")" local default_command default_command="$(resolve_binary_path)" local command_path command_path="$(prompt "Commande du serveur MCP" "$default_command")" cat <&2 ;; esac done } main "$@"