#!/usr/bin/env bash # ============================================================================== # update.sh — Multi-Agent Mux (MAM) Orchestration Updater # ============================================================================== # Safely updates MAM skills, virtual environment, and docs to the latest version. # Preserves user configuration (.env) and local metadata/jobs database (.mam). # ============================================================================== set -euo pipefail TARGET_DIR="" FORCE=0 # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in -y|--yes|--force) FORCE=1 shift ;; *) TARGET_DIR="$1" shift ;; esac done if [ -z "$TARGET_DIR" ]; then TARGET_DIR="$(pwd)" fi echo "====================================================================" echo "⚡ Starting Multi-Agent Mux (MAM) Update" echo "📂 Target Workspace: $TARGET_DIR" echo "====================================================================" if [ ! -d "$TARGET_DIR" ]; then echo "❌ Error: Target directory '$TARGET_DIR' does not exist." >&2 exit 1 fi cd "$TARGET_DIR" # 1. Verification of existing install if [ ! -f "remove.sh" ]; then echo "❌ Error: No MAM installation (remove.sh) found in '$TARGET_DIR'." >&2 echo " Please run install.sh first to set up the workspace." >&2 exit 1 fi # Request confirmation if not forced if [ $FORCE -eq 0 ]; then echo "⚠️ WARNING: This will update MAM orchestration skills, virtual environment, " echo " and docs to the latest version." echo " (Your configuration, job history, and custom skills will be preserved)." if [ ! -t 0 ]; then echo "❌ Error: Non-interactive terminal detected. Please run with -y/--yes/--force." >&2 exit 1 fi if ! read -p "❓ Proceed with update? [y/N]: " -r response; then response="n" fi if [[ ! "$response" =~ ^[yY](es)?$ ]]; then echo "❌ Update cancelled by user." exit 0 fi fi # 2. Stage backups of user configurations and metadata to prevent deletion echo "💾 Backing up configuration and database..." HAS_ENV=0 if [ -f ".env" ]; then HAS_ENV=1 mv ".env" ".env.update-tmp" fi HAS_MAM=0 if [ -d ".mam" ]; then HAS_MAM=1 # Copy database and jobs to temporary backup outside of .mam. # We do NOT move the .mam folder away so that remove.sh can still read .mam/install_manifest.txt! mkdir -p .mam.update-tmp # Copy SQLite databases and session files for db in .mam/agent-sessions.*; do if [ -f "$db" ]; then cp -f "$db" .mam.update-tmp/ fi done # Copy jobs history if [ -d ".mam/jobs" ] && [ "$(ls -A .mam/jobs 2>/dev/null)" ]; then mkdir -p .mam.update-tmp/jobs cp -rf .mam/jobs/* .mam.update-tmp/jobs/ fi # Copy delegate logs if [ -d ".mam/delegate_job_logs" ] && [ "$(ls -A .mam/delegate_job_logs 2>/dev/null)" ]; then mkdir -p .mam.update-tmp/delegate_job_logs cp -rf .mam/delegate_job_logs/* .mam.update-tmp/delegate_job_logs/ fi # Copy manifest so we have a backup if [ -f ".mam/install_manifest.txt" ]; then cp -f .mam/install_manifest.txt .mam.update-tmp/ fi fi # Define trap to restore backup files on failure restore_on_failure() { echo "❌ Update failed. Reverting configuration and database to previous state..." if [ $HAS_ENV -eq 1 ] && [ -f ".env.update-tmp" ]; then mv -f ".env.update-tmp" ".env" 2>/dev/null || true fi if [ $HAS_MAM -eq 1 ] && [ -d ".mam.update-tmp" ]; then # Revert to old database/jobs backup by restoring .mam directory rm -rf .mam 2>/dev/null || true mkdir -p .mam cp -f .mam.update-tmp/agent-sessions.* .mam/ 2>/dev/null || true if [ -d ".mam.update-tmp/jobs" ]; then cp -rf .mam.update-tmp/jobs .mam/ 2>/dev/null || true fi if [ -d ".mam.update-tmp/delegate_job_logs" ]; then cp -rf .mam.update-tmp/delegate_job_logs .mam/ 2>/dev/null || true fi if [ -f ".mam.update-tmp/install_manifest.txt" ]; then cp -f .mam.update-tmp/install_manifest.txt .mam/ 2>/dev/null || true fi rm -rf .mam.update-tmp 2>/dev/null || true fi } trap restore_on_failure EXIT # 3. Perform uninstallation of existing files echo "🗑️ Removing existing installation..." # remove.sh will run in manifest mode because .mam/install_manifest.txt is still present. # It will delete .agents/, documents, scripts, .venv, and .mam folder. bash remove.sh --force # 4. Fetch and run the latest installer from Gitea echo "📥 Fetching and running the latest installer..." INSTALLER_URL="https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh" if command -v curl &>/dev/null; then curl -fsSL "$INSTALLER_URL" | bash -s -- "$TARGET_DIR" elif command -v wget &>/dev/null; then wget -qO- "$INSTALLER_URL" | bash -s -- "$TARGET_DIR" else echo "❌ Error: Neither 'curl' nor 'wget' is available to fetch the installer." >&2 exit 1 fi # Disable failure trap since installation succeeded trap - EXIT # 5. Restore backups of configuration and database echo "🔄 Restoring configuration and database..." if [ $HAS_ENV -eq 1 ]; then # Overwrite the default .env created by installer (if any) with the user's backup mv -f ".env.update-tmp" ".env" fi if [ $HAS_MAM -eq 1 ]; then if [ -d ".mam.update-tmp" ]; then # The installer created a new .mam directory with a new manifest. # We want to merge the old .mam database/jobs back while keeping the new manifest. for db in .mam.update-tmp/agent-sessions.*; do if [ -f "$db" ]; then cp -f "$db" .mam/ fi done if [ -d ".mam.update-tmp/jobs" ] && [ "$(ls -A .mam.update-tmp/jobs 2>/dev/null)" ]; then mkdir -p .mam/jobs cp -rf .mam.update-tmp/jobs/* .mam/jobs/ fi if [ -d ".mam.update-tmp/delegate_job_logs" ] && [ "$(ls -A .mam.update-tmp/delegate_job_logs 2>/dev/null)" ]; then mkdir -p .mam/delegate_job_logs cp -rf .mam.update-tmp/delegate_job_logs/* .mam/delegate_job_logs/ fi rm -rf ".mam.update-tmp" fi fi echo "====================================================================" echo "🎉 Update complete!" echo "===================================================================="