Reproduces the real reviewer UI for any recorded session, with no VPN/Pi/
Python/DWH. The server (node:http, zero deps) serves the built SPA and a
tiny SSE/REST shim that re-emits the reviewer gates captured in a Pi
transcript, in their original order, with the reviewer's real 3-Jul
choices shown as comparison badges.
- tools/replay/extract.mjs: extracts gates from one or many transcripts
(session-id, file, or directory). Handles sessions split across resume
re-entries by sorting on message timestamp and dropping unanswered
gates. Reads the question from session_manifest.yaml, resolving the
sessions dir from any workspace yaml (no hardcoded paths).
- tools/replay/server.mjs: same-origin :5333. SSE streams gates; POST
/response advances the cursor and pushes info badges (scelta reale).
POST /resume and the final "Ripeti/Esci" widget close the SSE so the
browser EventSource reconnects (cursor resets, gate 1 re-emitted) — the
replay is re-runnable any number of times. GET /sessions/:id/documents
reads the real session files so GateArtifactBody resolves file-reference
artifacts. Exit emits system_event {event:"session_exit"} to return to
the landing.
- scripts/replay.sh: launcher (extract / build / run / all).
- tools/replay/README.md: data flow, commands, fidelity notes.
- .gitignore: ignore tools/replay/web/ (built artifact, like dist/).
71 lines
2.4 KiB
Bash
71 lines
2.4 KiB
Bash
#!/usr/bin/env bash
|
|
# Replay a recorded ThothII reviewer session on http://localhost:5333, with no
|
|
# VPN/Pi/Python/DWH. The real frontend UI is served against a tiny SSE/REST shim
|
|
# that re-emits the reviewer gates captured in Pi transcripts.
|
|
#
|
|
# Usage:
|
|
# scripts/replay.sh # extract(default) + build(if missing) + run
|
|
# scripts/replay.sh extract [<session>] # (re)build replay.json for a session
|
|
# scripts/replay.sh build # (re)build the SPA bundle only
|
|
# scripts/replay.sh run # run only (assumes build + fixture present)
|
|
#
|
|
# <session> a session id (e.g. 2026-07-03-170732-fammi-…)
|
|
# a transcript file path
|
|
# a directory of transcripts (picks the dominant session)
|
|
# default: the 3-Jul 17:07 full session
|
|
#
|
|
# Examples:
|
|
# scripts/replay.sh extract 2026-07-03-132933-fammi-la-lista-dei-pazienti-che-negli-ul
|
|
# scripts/replay.sh run
|
|
#
|
|
# Env:
|
|
# PORT default 5333
|
|
#
|
|
# See tools/replay/README.md for the data flow.
|
|
|
|
set -euo pipefail
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd)"
|
|
PORT="${PORT:-5333}"
|
|
WEB_DIR="$HERE/tools/replay/web"
|
|
FIXTURE="$HERE/tools/replay/replay.json"
|
|
|
|
action="${1:-all}"
|
|
# Positional target for extract: shifts past the action word.
|
|
target="${2:-}"
|
|
|
|
do_extract() {
|
|
echo "→ extracting replay.json for ${target:-default session (3-Jul 17:07)}…"
|
|
node "$HERE/tools/replay/extract.mjs" "$target"
|
|
}
|
|
|
|
do_build() {
|
|
if [[ -d "$WEB_DIR" ]]; then
|
|
echo "→ $WEB_DIR exists, skipping build (use 'rm -rf $WEB_DIR' to force)"
|
|
return
|
|
fi
|
|
echo "→ building SPA bundle into $WEB_DIR (VITE_BACKEND_URL=http://localhost:$PORT)…"
|
|
(
|
|
cd "$HERE/frontend"
|
|
VITE_BACKEND_URL="http://localhost:$PORT" npx vite build --outDir ../tools/replay/web
|
|
)
|
|
}
|
|
|
|
do_run() {
|
|
[[ -f "$FIXTURE" ]] || { echo "✗ missing $FIXTURE — run: scripts/replay.sh extract"; exit 1; }
|
|
[[ -d "$WEB_DIR" ]] || { echo "✗ missing $WEB_DIR — run: scripts/replay.sh build"; exit 1; }
|
|
echo "→ starting replay server on :$PORT (Ctrl-C to stop)…"
|
|
PORT="$PORT" node "$HERE/tools/replay/server.mjs"
|
|
}
|
|
|
|
case "$action" in
|
|
extract) do_extract ;;
|
|
build) do_build ;;
|
|
run) do_run ;;
|
|
all)
|
|
[[ -f "$FIXTURE" ]] || do_extract
|
|
do_build
|
|
do_run
|
|
;;
|
|
*) echo "unknown action: $action"; echo "usage: $0 [extract|build|run|all]"; exit 2 ;;
|
|
esac
|