← back to Debate Ring Viewer

scripts/weekly-highlight-reel.sh

118 lines

#!/bin/bash
# Weekly highlight reel — records the most recent claude-codex debate run
# as a 60-second narrated MP4 via the app-demo-video skill, then emails
# Steve a link via George.
set -euo pipefail

# George basic-auth pulled from env. Hardcoded plaintext was committed in
# baseline ce2f175 — ROTATE that credential; setting GEORGE_AUTH here only
# stops new copies from being committed.
: "${GEORGE_AUTH:?GEORGE_AUTH must be set (user:pass for http://localhost:9850)}"

OUTROOT="$HOME/.claude/skills/app-demo-video/output/debate-ring-weekly"
mkdir -p "$OUTROOT"
LOG_DIR="$HOME/Projects/debate-ring-viewer/logs"
mkdir -p "$LOG_DIR"
TS=$(date +%Y%m%d-%H%M%S)
LOG="$LOG_DIR/weekly-reel-$TS.log"

trap 'echo "[reel] FAILED at line $LINENO (rc=$?)" | tee -a "$LOG"' ERR

echo "[reel] start $(date -Iseconds)" | tee -a "$LOG"

# Confirm the viewer is up, otherwise pm2 restart it.
if ! curl -sf --max-time 5 -o /dev/null http://localhost:9730/api/runs; then
  echo "[reel] viewer DOWN, attempting pm2 restart" | tee -a "$LOG"
  /opt/homebrew/bin/pm2 restart debate-ring >> "$LOG" 2>&1 || true
  sleep 4
  if ! curl -sf --max-time 5 -o /dev/null http://localhost:9730/api/runs; then
    echo "[reel] viewer still DOWN — aborting" | tee -a "$LOG"
    exit 2
  fi
fi

# PRE-BUILD: snap a storyboard frame, run the four-horsemen design panel
# against it. Cheap insurance — catches a broken viewer or busted overlay
# before we spend 35 seconds rendering an MP4 of nothing useful.
REVIEW_DIR="$HOME/Projects/debate-ring-viewer/logs/reviews"
mkdir -p "$REVIEW_DIR" "$HOME/Projects/debate-ring-viewer/storyboards"
echo "[reel] pre-build storyboard snap" | tee -a "$LOG"
URL=http://localhost:9730 OUT="$HOME/Projects/debate-ring-viewer/storyboards" \
  /opt/homebrew/bin/node "$HOME/Projects/debate-ring-viewer/scripts/storyboard-snap.cjs" >> "$LOG" 2>&1 || true
echo "[reel] pre-build four-horsemen review" | tee -a "$LOG"
PRE_REVIEW="$REVIEW_DIR/pre-build-$TS.md"
bash "$HOME/Projects/debate-ring-viewer/scripts/four-horsemen-review.sh" \
  "$HOME/Projects/debate-ring-viewer/storyboards/frame-02-fighting.png" "$PRE_REVIEW" >> "$LOG" 2>&1 || true

cd "$HOME/.claude/skills/app-demo-video"
RC=0
/opt/homebrew/bin/node scripts/run.js \
  --url "http://localhost:9730" \
  --appName "Debate Ring" \
  --flowFile "$HOME/Projects/debate-ring-viewer/demo-flow.json" \
  >> "$LOG" 2>&1 || RC=$?

SRC="$HOME/.claude/skills/app-demo-video/output/debate-ring/debate-ring-demo.mp4"
DST="$OUTROOT/debate-ring-$TS.mp4"

# Build the JSON body via node from env vars so paths/values containing
# quotes or newlines can't corrupt the JSON literal.
send_email() {
  local subject="$1" body="$2" payload
  payload=$(SUBJECT="$subject" BODY="$body" /opt/homebrew/bin/node -e \
    'process.stdout.write(JSON.stringify({to:"steveabramsdesigns@gmail.com",subject:process.env.SUBJECT,body:process.env.BODY}))')
  curl -sS --max-time 10 -X POST http://localhost:9850/api/send \
    -u "$GEORGE_AUTH" \
    -H 'content-type: application/json' \
    -d "$payload" >> "$LOG" 2>&1 || true
}

if [ "$RC" -ne 0 ] || [ ! -s "$SRC" ]; then
  echo "[reel] FAILED rc=$RC, no MP4" | tee -a "$LOG"
  send_email "Debate-Ring weekly reel FAILED" \
    "Reel build failed at $(date -Iseconds). Log: $LOG"
  exit "$RC"
fi

cp "$SRC" "$DST"
SIZE=$(/usr/bin/stat -f%z "$DST" 2>/dev/null || echo 0)
DUR=$(/opt/homebrew/bin/ffprobe -v error -show_entries format=duration -of csv=p=0 "$DST" 2>/dev/null | head -1 || echo "")

echo "[reel] wrote $DST ($SIZE bytes, ${DUR}s)" | tee -a "$LOG"

# POST-BUILD: extract 4 keyframes from the final MP4, run the four-horsemen
# review against the most informative middle frame.
echo "[reel] post-build keyframe extraction" | tee -a "$LOG"
KF_DIR="$HOME/Projects/debate-ring-viewer/storyboards/post-build-$TS"
bash "$HOME/Projects/debate-ring-viewer/scripts/keyframes-extract.sh" \
  "$DST" "$KF_DIR" 4 >> "$LOG" 2>&1 || true
POST_REVIEW="$REVIEW_DIR/post-build-$TS.md"
MID_FRAME=$(ls "$KF_DIR"/frame-*.png 2>/dev/null | sed -n '2p' || true)
if [ -n "${MID_FRAME:-}" ]; then
  bash "$HOME/Projects/debate-ring-viewer/scripts/four-horsemen-review.sh" \
    "$MID_FRAME" "$POST_REVIEW" >> "$LOG" 2>&1 || true
fi

DATE_TAG=$(date -Iseconds | cut -c1-10)
SUCCESS_BODY=$(cat <<EOF
New highlight reel of the latest 8-LLM debate, with Steve avatar narrating from the bottom-right corner.

File: $DST
Duration: ${DUR}s
Size: $SIZE bytes

Four-horsemen design panel reviews:
  PRE-build:  $PRE_REVIEW
  POST-build: $POST_REVIEW

Live viewer: http://localhost:9730

Open with:  open $DST
EOF
)
send_email "Debate-Ring weekly reel $DATE_TAG" "$SUCCESS_BODY"

# Trim reels older than 8 weeks
find "$OUTROOT" -name 'debate-ring-*.mp4' -mtime +56 -delete 2>/dev/null || true
echo "[reel] end $(date -Iseconds)" | tee -a "$LOG"