magicciv/scripts/claude-demo-25turn.sh
Natalie 91ef4bc21f feat(@projects/@magic-civilization): rename claude-player to player-api refactor
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-17 03:43:32 -07:00

68 lines
2.4 KiB
Bash
Executable file

#!/usr/bin/env bash
# p2-67 Phase 5 — Real-apricot Claude-vs-AI demo driver, 25 EndTurns.
#
# Spawns player-api-server.sh, sends CP_TURNS act:end_turn requests
# (default 25) followed by shutdown. Streams the FULL JSON-Lines
# response stream verbatim to stdout — caller redirects to transcript.jsonl.
#
# On unexpected termination (game over, panic, protocol_error), the
# server's stdout is preserved up to the abort point. A synthetic
# {"type":"protocol_error", ...} line is appended if the harness exits
# non-zero before consuming the full request stream.
#
# Env:
# CP_TURNS (default 25) — number of EndTurns to issue
# CP_SEED (default 42)
# CP_PLAYERS (default 3)
# CP_CLAUDE_SLOT (default 0)
# CP_MAP_SIZE (default duel)
# CP_TIMEOUT_SEC (default 600) — harness wallclock budget
#
# Exit 0 always — termination details land in the transcript itself.
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
: "${CP_TURNS:=25}"
: "${CP_SEED:=42}"
: "${CP_PLAYERS:=3}"
: "${CP_CLAUDE_SLOT:=0}"
: "${CP_MAP_SIZE:=duel}"
: "${CP_TIMEOUT_SEC:=600}"
export CP_SEED CP_PLAYERS CP_CLAUDE_SLOT CP_MAP_SIZE CP_TIMEOUT_SEC
TMP=$(mktemp -d -t mc-demo25-XXXXXX)
trap "rm -rf '$TMP'" EXIT
# Build the request stream.
{
for i in $(seq 1 "$CP_TURNS"); do
printf '{"type":"act","id":%d,"action":{"type":"end_turn"}}\n' "$i"
done
printf '{"type":"shutdown","id":999}\n'
} > "$TMP/in.jsonl"
# Drive the harness. timeout is a hard ceiling; CP_TIMEOUT_SEC drives the
# in-process Godot watchdog inside the harness.
HARNESS_RC=0
timeout "$((CP_TIMEOUT_SEC + 60))" "$SCRIPT_DIR/player-api-server.sh" \
< "$TMP/in.jsonl" > "$TMP/out.jsonl" 2>"$TMP/err.log" \
|| HARNESS_RC=$?
# Emit transcript verbatim.
cat "$TMP/out.jsonl"
# If the harness aborted before issuing a shutdown_ok, append a protocol_error
# synthetic line so downstream tooling can detect the abort. Mirror the mock
# transcript's pattern.
if [[ $HARNESS_RC -ne 0 ]]; then
LAST_TURN=$(grep -c '"type":"act_response"' "$TMP/out.jsonl" 2>/dev/null || echo 0)
STDERR_TAIL=$(tail -20 "$TMP/err.log" 2>/dev/null | tr '\n' '|' | sed 's/"/\\"/g')
printf '{"type":"protocol_error","harness_rc":%d,"last_act_response_count":%d,"stderr_tail":"%s"}\n' \
"$HARNESS_RC" "$LAST_TURN" "$STDERR_TAIL"
fi
# Always exit clean — termination data is in the transcript.
exit 0