#!/usr/bin/env bash # start-loops.sh — Start all Hermes agent loops (orchestrator + workers) # Validates model health, cleans stale state, launches loops with nohup. # Part of Gitea issue #126. # # Usage: start-loops.sh set -euo pipefail HERMES_BIN="$HOME/.hermes/bin" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" LOG_DIR="$HOME/.hermes/logs" CLAUDE_LOCKS="$LOG_DIR/claude-locks" GEMINI_LOCKS="$LOG_DIR/gemini-locks" mkdir -p "$LOG_DIR" "$CLAUDE_LOCKS" "$GEMINI_LOCKS" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] START-LOOPS: $*" } # ── 1. Model health check ──────────────────────────────────────────── log "Running model health check..." if ! bash "$SCRIPT_DIR/model-health-check.sh"; then log "FATAL: Model health check failed. Aborting loop startup." exit 1 fi log "Model health check passed." # ── 2. Kill stale loop processes ────────────────────────────────────── log "Killing stale loop processes..." for proc_name in claude-loop gemini-loop timmy-orchestrator; do pids=$(pgrep -f "${proc_name}\\.sh" 2>/dev/null || true) if [ -n "$pids" ]; then log " Killing stale $proc_name PIDs: $pids" echo "$pids" | xargs kill 2>/dev/null || true sleep 1 # Force-kill any survivors pids=$(pgrep -f "${proc_name}\\.sh" 2>/dev/null || true) if [ -n "$pids" ]; then echo "$pids" | xargs kill -9 2>/dev/null || true fi else log " No stale $proc_name found." fi done # ── 3. Clear lock directories ──────────────────────────────────────── log "Clearing lock dirs..." rm -rf "${CLAUDE_LOCKS:?}"/* rm -rf "${GEMINI_LOCKS:?}"/* log " Cleared $CLAUDE_LOCKS and $GEMINI_LOCKS" # ── 4. Launch loops with nohup ─────────────────────────────────────── log "Launching timmy-orchestrator..." nohup bash "$HERMES_BIN/timmy-orchestrator.sh" \ >> "$LOG_DIR/timmy-orchestrator-nohup.log" 2>&1 & ORCH_PID=$! log " timmy-orchestrator PID: $ORCH_PID" log "Launching claude-loop (5 workers)..." nohup bash "$HERMES_BIN/claude-loop.sh" 5 \ >> "$LOG_DIR/claude-loop-nohup.log" 2>&1 & CLAUDE_PID=$! log " claude-loop PID: $CLAUDE_PID" log "Launching gemini-loop (3 workers)..." nohup bash "$HERMES_BIN/gemini-loop.sh" 3 \ >> "$LOG_DIR/gemini-loop-nohup.log" 2>&1 & GEMINI_PID=$! log " gemini-loop PID: $GEMINI_PID" # ── 5. PID summary ─────────────────────────────────────────────────── log "Waiting 3s for processes to settle..." sleep 3 echo "" echo "═══════════════════════════════════════════════════" echo " HERMES LOOP STATUS" echo "═══════════════════════════════════════════════════" printf " %-25s %s\n" "PROCESS" "PID / STATUS" echo "───────────────────────────────────────────────────" for entry in "timmy-orchestrator:$ORCH_PID" "claude-loop:$CLAUDE_PID" "gemini-loop:$GEMINI_PID"; do name="${entry%%:*}" pid="${entry##*:}" if kill -0 "$pid" 2>/dev/null; then printf " %-25s %s\n" "$name" "$pid ✓ running" else printf " %-25s %s\n" "$name" "$pid ✗ DEAD" fi done echo "───────────────────────────────────────────────────" echo " Logs: $LOG_DIR/*-nohup.log" echo "═══════════════════════════════════════════════════" echo "" log "All loops launched."