#!/usr/bin/env bash # deploy.sh — Apply timmy-config as sidecar overlay onto ~/.hermes/ # This is the canonical way to deploy Timmy's configuration. # Hermes-agent is the engine. timmy-config is the driver's seat. # # Usage: ./deploy.sh [--restart-loops] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" HERMES_HOME="$HOME/.hermes" TIMMY_HOME="$HOME/.timmy" log() { echo "[deploy] $*"; } # === Sanity checks === if [ ! -f "$SCRIPT_DIR/SOUL.md" ]; then echo "ERROR: Run from timmy-config root" >&2 exit 1 fi # === Create directories === mkdir -p "$HERMES_HOME/bin" mkdir -p "$HERMES_HOME/skins" mkdir -p "$HERMES_HOME/playbooks" mkdir -p "$HERMES_HOME/memories" mkdir -p "$TIMMY_HOME" # === Deploy SOUL === cp "$SCRIPT_DIR/SOUL.md" "$TIMMY_HOME/SOUL.md" log "SOUL.md -> $TIMMY_HOME/" # === Deploy config === cp "$SCRIPT_DIR/config.yaml" "$HERMES_HOME/config.yaml" log "config.yaml -> $HERMES_HOME/" # === Deploy channel directory === if [ -f "$SCRIPT_DIR/channel_directory.json" ]; then cp "$SCRIPT_DIR/channel_directory.json" "$HERMES_HOME/channel_directory.json" log "channel_directory.json -> $HERMES_HOME/" fi # === Deploy memories === for f in "$SCRIPT_DIR"/memories/*; do [ -f "$f" ] && cp "$f" "$HERMES_HOME/memories/" done log "memories/ -> $HERMES_HOME/memories/" # === Deploy skins === for f in "$SCRIPT_DIR"/skins/*; do [ -f "$f" ] && cp "$f" "$HERMES_HOME/skins/" done log "skins/ -> $HERMES_HOME/skins/" # === Deploy playbooks === for f in "$SCRIPT_DIR"/playbooks/*; do [ -f "$f" ] && cp "$f" "$HERMES_HOME/playbooks/" done log "playbooks/ -> $HERMES_HOME/playbooks/" # === Deploy cron === if [ -d "$SCRIPT_DIR/cron" ]; then mkdir -p "$HERMES_HOME/cron" for f in "$SCRIPT_DIR"/cron/*; do [ -f "$f" ] && cp "$f" "$HERMES_HOME/cron/" done log "cron/ -> $HERMES_HOME/cron/" fi # === Deploy bin (operational scripts) === for f in "$SCRIPT_DIR"/bin/*; do [ -f "$f" ] && cp "$f" "$HERMES_HOME/bin/" done chmod +x "$HERMES_HOME/bin/"*.sh "$HERMES_HOME/bin/"*.py 2>/dev/null || true log "bin/ -> $HERMES_HOME/bin/" # === Restart loops if requested === if [ "${1:-}" = "--restart-loops" ]; then log "Killing existing loops..." pkill -f 'claude-loop.sh' 2>/dev/null || true pkill -f 'gemini-loop.sh' 2>/dev/null || true pkill -f 'timmy-orchestrator.sh' 2>/dev/null || true sleep 2 log "Clearing stale locks..." rm -rf "$HERMES_HOME/logs/claude-locks/"* 2>/dev/null || true rm -rf "$HERMES_HOME/logs/gemini-locks/"* 2>/dev/null || true log "Relaunching loops..." nohup bash "$HERMES_HOME/bin/timmy-orchestrator.sh" >> "$HERMES_HOME/logs/timmy-orchestrator.log" 2>&1 & nohup bash "$HERMES_HOME/bin/claude-loop.sh" 2 >> "$HERMES_HOME/logs/claude-loop.log" 2>&1 & nohup bash "$HERMES_HOME/bin/gemini-loop.sh" 1 >> "$HERMES_HOME/logs/gemini-loop.log" 2>&1 & sleep 1 log "Loops relaunched." fi log "Deploy complete. timmy-config applied to $HERMES_HOME/"