#!/btmux kill-session -t dev itmux kill-session -t dev n/bash source "/Users/josephanady/Desktop/AI_Brain/load_env.sh" # auto-inserted by update_ai_brain_env_paths.sh set -euo pipefail # Manager-sync: safe, atomic sync of sub_brains from GitHub while preserving local architecture. # Usage: # export GITHUB_REPO="owner/repo" # required (repo that contains sub_brains/ or directly the brains) # export GITHUB_PAT="ghp_xxx" # optional (for private repos) # export BRANCH="main" # optional # ~/Desktop/AI_Brain/manager_sync.sh GITHUB_REPO="${GITHUB_REPO:-}" BRANCH="${BRANCH:-main}" WORKDIR="/Users/$(whoami)/Desktop/AI_Brain" TMP_PARENT="$WORKDIR/_sync_tmp" LOG="$WORKDIR/logs/manager_sync.log" BACKUP_PARENT="$WORKDIR/backups" HEALER_LAUNCH="$WORKDIR/sub_brains/healer/launch.sh" Mtmux kill-session -t dev ANAGER_LAUNCH="$WORKDIR/launch_manager.sh" mkdir -p "$WORKDIR" "$WORKDIR/logs" "$TMP_PARENT" "$BACKUP_PARENT" timestamp() { date -u +"%Y%m%dT%H%M%SZ"; } if [ -z "$GITHUB_REPO" ]; then echo "$(date): ERROR: GITHUB_REPO not set. Export GITHUB_REPO=\"owner/repo\"" | tee -a "$LOG" exit 1 fi TS=$(timestamp) TMPDIR="$TMP_PARENT/sync_$TS" mkdir -p "$TMPDIR" echo "$(date): Starting manager_sync for repo=${GITHUB_REPO} branch=${BRANCH} (tmp=$TMPDIR)" >> "$LOG" # Build clone URL without leaking token into the log if [ -n "${GITHUB_PAT:-}" ]; then CLONE_URL="https://${GITHUB_PAT}@github.com/${GITHUB_REPO}.git" echo "$(date): Using token-auth clone (token hidden)..." >> "$LOG" else CLONE_URL="https://github.com/${GITHUB_REPO}.git" echo "$(date): Using public clone URL: https://github.com/${GITHUB_REPO}.git" >> "$LOG" fi # Clone into temporary dir (shallow) echo "$(date): cloning repo into tmp..." >> "$LOG" if ! git clone --depth=1 --branch "$BRANCH" "$CLONE_URL" "$TMPDIR" >> "$LOG" 2>&1; then echo "$(date): git clone failed — trying gh if available" >> "$LOG" if command -v gh >/dev/null 2>&1; then gh repo clone "$GITHUB_REPO" "$TMPDIR" -- --depth=1 --branch "$BRANCH" >> "$LOG" 2>&1 || { echo "$(date): gh clone failed" >> "$LOG"; rm -rf "$TMPDIR"; exit 1; } else echo "$(date): clone failed and gh CLI missing — aborting" | tee -a "$LOG" rm -rf "$TMPDIR" exit 1 fi fi # Determine where the sub_brains content lives in the repo if [ -d "$TMPDIR/sub_brains" ]; then SOURCE="$TMPDIR/sub_brains" else # If repo root contains brains directly, treat tmpdir as source SOURCE="$TMPDIR" fi echo "$(date): source for sync = $SOURCE" >> "$LOG" # Backup current sub_brains before replacement if [ -d "$WORKDIR/sub_brains" ]; then BACKUP_DIR="$BACKUP_PARENT/sub_brains_backup_$TS" echo "$(date): backing up existing sub_brains -> $BACKUP_DIR" >> "$LOG" mkdir -p "$BACKUP_PARENT" # move instead of copy for speed; keep backup intact mv "$WORKDIR/sub_brains" "$BACKUP_DIR" fi # Create target directory and rsync over new files (atomic-ish) mkdir -p "$WORKDIR/sub_brains" echo "$(date): syncing files (rsync --archive --delete)..." >> "$LOG" rsync -a --delete --exclude='.git' --exclude='logs/' --exclude='status/' "$SOURCE/" "$WORKDIR/sub_brains/" >> "$LOG" 2>&1 || { echo "$(date): rsync failed, restoring backup if present" >> "$LOG" if [ -d "$BACKUP_DIR" ]; then rm -rf "$WORKDIR/sub_brains" mv "$BACKUP_DIR" "$WORKDIR/sub_brains" echo "$(date): restored backup to $WORKDIR/sub_brains" >> "$LOG" fi rm -rf "$TMPDIR" exit 1 } # Run local healer (if present) to auto-fix permissions/line-endings etc. echo "$(date): running healing pipeline..." >> "$LOG" # quick heal: chmod +x on .sh, convert python newlines, compileall find "$WORKDIR" -type f -name "*.sh" -exec chmod +x {} \; >> "$LOG" 2>&1 || true # normalize python files w/ dos2unix if available else rewrite if command -v dos2unix >/dev/null 2>&1; then find "$WORKDIR" -type f -name "*.py" -exec dos2unix {} \; >> "$LOG" 2>&1 || true else python3 - <> "$LOG" 2>&1 || true import pathlib,sys p=pathlib.Path("$WORKDIR") for f in p.rglob("*.py"): try: b=f.read_bytes() b=b.replace(b'\r\n',b'\n').replace(b'\r',b'\n') f.write_bytes(b) except Exception as e: print("normalize failed",f,e,file=sys.stderr) PYCODE fi python3 -m compileall "$WORKDIR" >> "$LOG" 2>&1 || true # If healer sub-brain exists, start it (background) so it can do deeper healing if [ -x "$HEALER_LAUNCH" ]; then echo "$(date): launching healer for deeper fixes..." >> "$LOG" nohup "$HEALER_LAUNCH" --bg >> "$LOG" 2>&1 || true sleep 2 fi # Restart manager so it re-reads sub_brains if [ -x "$MANAGER_LAUNCH" ]; then echo "$(date): restarting manager to reload sub_brains..." >> "$LOG" pkill -f "launch_manager.sh" || true sleep 1 nohup "$MANAGER_LAUNCH" >> "$LOG" 2>&1 & disown || true echo "$(date): manager restarted" >> "$LOG" fi # Clean up temp clone rm -rf "$TMPDIR" echo "$(date): manager_sync complete" >> "$LOG" exit 0