Skip to content

Commit 975f958

Browse files
committed
refactor(demo): migrate to asciinema+agg recording pipeline
Replace VHS with asciinema+agg+gifsicle for deterministic, higher-quality demo GIF output. Simulation script now matches Codex CLI v0.117.0 format.
1 parent 853f3b7 commit 975f958

4 files changed

Lines changed: 161 additions & 35 deletions

File tree

.github/demo.gif

-7.01 KB
Loading

.github/demo/demo-agent.sh

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,63 @@
11
#!/bin/bash
2-
# Simulates Claude Code terminal output for the demo GIF.
2+
# Simulates Codex CLI terminal output for the demo GIF.
3+
# Format matches real Codex CLI v0.117.0 interactive mode output.
34
# Runs in the LEFT tmux pane. Makes real file changes so diffpane picks them up.
45

56
DEMO_DIR="/tmp/diffpane-demo"
67

7-
# ANSI colors
8+
# ANSI colors matching Codex CLI palette
89
BOLD='\033[1m'
910
DIM='\033[2m'
10-
GREEN='\033[32m'
11-
PURPLE='\033[35m'
1211
RESET='\033[0m'
1312

13+
# Codex uses a dimmed bullet for tool/action markers
14+
BULLET="${DIM}\xe2\x80\xa2${RESET}" #
15+
PROMPT="${BOLD}\xe2\x80\xba${RESET}" #
16+
CORNER="${DIM}\xe2\x94\x94${RESET}" #
17+
1418
# Simulate typing (character by character)
1519
type_out() {
1620
local text="$1"
1721
for ((i = 0; i < ${#text}; i++)); do
1822
printf '%s' "${text:$i:1}"
1923
sleep 0.03
2024
done
21-
echo
2225
}
2326

24-
# Wait for VHS hidden setup + Show (~4s setup, then ~1.5s empty visible)
25-
sleep 5
27+
# Horizontal separator matching Codex style
28+
separator() {
29+
local cols
30+
cols=$(tput cols 2>/dev/null || echo 60)
31+
printf '%s' "${DIM}"
32+
printf '%*s' "$cols" '' | tr ' ' ''
33+
printf '%s\n' "${RESET}"
34+
}
35+
36+
# Wait for tmux setup (~2s already elapsed before recording starts)
37+
sleep 3
2638

27-
# Claude Code banner
28-
echo -e "${BOLD}${PURPLE} ╭────────────────────────────────────────╮${RESET}"
29-
echo -e "${BOLD}${PURPLE}${RESET} ${PURPLE}${RESET}${BOLD} Welcome to Claude Code! ${PURPLE}${RESET}"
30-
echo -e "${BOLD}${PURPLE}${RESET} /help for help ${PURPLE}${RESET}"
31-
echo -e "${BOLD}${PURPLE} ╰────────────────────────────────────────╯${RESET}"
39+
# --- Codex prompt with user task ---
40+
printf '%s ' "${PROMPT}"
41+
type_out "Add a detail parameter to health endpoint, and a version to config"
42+
echo
3243
echo
33-
sleep 0.8
3444

35-
# --- Change 1: add detail param to health handler ---
45+
sleep 0.8
3646

37-
printf '%b> %b' "$BOLD" "$RESET"
38-
type_out "Add a detail parameter to the health endpoint"
47+
# --- Phase 1: reading files ---
48+
echo -e "${BULLET} Reading project files to understand current structure."
3949
echo
40-
sleep 0.3
50+
sleep 0.4
4151

42-
echo -e " ${PURPLE}${RESET} Adding a ${BOLD}detail${RESET} query parameter with JSON response."
52+
echo -e " ${CORNER} Read ${DIM}internal/handler/health.go${RESET}"
53+
sleep 0.6
54+
echo -e " ${CORNER} Read ${DIM}internal/config/config.go${RESET}"
4355
echo
44-
sleep 0.5
56+
sleep 0.8
4557

46-
echo -e " ${GREEN}Edit${RESET} ${DIM}internal/handler/health.go${RESET}"
58+
# --- Phase 2: first edit (health.go) ---
59+
echo -e "${BULLET} Edited ${BOLD}internal/handler/health.go${RESET}"
60+
echo -e " ${CORNER} ${DIM}+8 -1${RESET}"
4761

4862
# Make actual file change (triggers diffpane)
4963
cat >"$DEMO_DIR/internal/handler/health.go" <<'GOEOF'
@@ -71,23 +85,12 @@ func Health(w http.ResponseWriter, r *http.Request) {
7185
}
7286
GOEOF
7387

74-
sleep 1
75-
echo -e " ${GREEN}${RESET} Changes applied"
7688
echo
7789
sleep 1.5
7890

79-
# --- Change 2: add version to config ---
80-
81-
printf '%b> %b' "$BOLD" "$RESET"
82-
type_out "Add version to the config"
83-
echo
84-
sleep 0.3
85-
86-
echo -e " ${PURPLE}${RESET} Adding a version field to the config map."
87-
echo
88-
sleep 0.5
89-
90-
echo -e " ${GREEN}Edit${RESET} ${DIM}internal/config/config.go${RESET}"
91+
# --- Phase 3: second edit (config.go) ---
92+
echo -e "${BULLET} Edited ${BOLD}internal/config/config.go${RESET}"
93+
echo -e " ${CORNER} ${DIM}+1 -0${RESET}"
9194

9295
# Make actual file change (triggers diffpane)
9396
cat >"$DEMO_DIR/internal/config/config.go" <<'GOEOF'
@@ -101,8 +104,22 @@ var Config = map[string]string{
101104
}
102105
GOEOF
103106

107+
echo
104108
sleep 1
105-
echo -e " ${GREEN}${RESET} Changes applied"
109+
110+
# --- Phase 4: verification ---
111+
echo -e "${BULLET} Ran ${DIM}git diff --stat${RESET}"
112+
echo -e " ${CORNER} ${DIM}2 files changed, 9 insertions(+), 1 deletion(-)${RESET}"
113+
echo
114+
115+
sleep 0.5
116+
separator
117+
echo
118+
119+
# --- Completion summary ---
120+
echo -e "${BULLET} Added ${BOLD}detail${RESET} query parameter to health handler and"
121+
echo -e " ${BOLD}version${RESET} field to config map."
122+
echo
106123

107124
# Keep alive so tmux pane doesn't close
108125
sleep 60

.github/demo/demo-simulate.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ git init -q
1414
git config user.email "demo@example.com"
1515
git config user.name "Demo"
1616

17+
# Go module so Codex can run tests without errors
18+
cat >go.mod <<'EOF'
19+
module demo
20+
go 1.21
21+
EOF
22+
1723
cat >internal/handler/health.go <<'EOF'
1824
package handler
1925

.github/demo/record-agg.sh

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/bash
2+
# Automated demo GIF recording with asciinema + agg.
3+
# Uses a simulated Codex CLI session (demo-agent.sh) for deterministic output.
4+
#
5+
# Prerequisites: brew install asciinema agg gifsicle tmux
6+
# Usage: bash .github/demo/record-agg.sh
7+
# Output: .github/demo.gif
8+
9+
set -e
10+
11+
PROJ_DIR="/Users/yuhan/workspace/dev/diffpane"
12+
SCRIPT_DIR="$PROJ_DIR/.github/demo"
13+
DEMO_DIR="/tmp/diffpane-demo"
14+
CAST_FILE="/tmp/diffpane-demo.cast"
15+
GIF_RAW="/tmp/diffpane-demo-raw.gif"
16+
GIF_FINAL="$PROJ_DIR/.github/demo.gif"
17+
18+
# --- 1. Build diffpane ---
19+
echo "==> Building diffpane..."
20+
go build -o /tmp/diffpane-bin "$PROJ_DIR"
21+
22+
# --- 2. Setup demo repo ---
23+
echo "==> Setting up demo repo..."
24+
bash "$SCRIPT_DIR/demo-simulate.sh"
25+
26+
# --- 3. Clean stale tmux session ---
27+
tmux kill-session -t demo 2>/dev/null || true
28+
29+
# --- 4. Start tmux session with split panes ---
30+
# Left pane: simulated Codex CLI output
31+
tmux -f "$SCRIPT_DIR/tmux-demo.conf" new-session -d -s demo \
32+
"bash $SCRIPT_DIR/demo-agent.sh"
33+
34+
sleep 0.5
35+
36+
# Right pane: diffpane watching the demo repo
37+
tmux split-window -h -t demo \
38+
"cd $DEMO_DIR && DIFFPANE_THEME=dark /tmp/diffpane-bin"
39+
40+
tmux select-layout -t demo even-horizontal
41+
sleep 1.5
42+
43+
# --- 5. Background controller ---
44+
(
45+
# demo-agent.sh takes ~12s for all changes, then sleeps
46+
sleep 16
47+
48+
# Show file list overlay
49+
tmux send-keys -t demo:0.1 Tab
50+
sleep 2
51+
52+
# Close overlay
53+
tmux send-keys -t demo:0.1 Escape
54+
sleep 1
55+
56+
# End recording
57+
tmux kill-session -t demo
58+
) &
59+
CONTROLLER_PID=$!
60+
61+
# --- 6. Record with asciinema ---
62+
echo "==> Recording..."
63+
asciinema rec \
64+
--headless \
65+
--window-size 120x40 \
66+
--idle-time-limit 3 \
67+
-c "tmux attach -t demo" \
68+
--overwrite \
69+
"$CAST_FILE" || true
70+
71+
wait $CONTROLLER_PID 2>/dev/null || true
72+
tmux kill-session -t demo 2>/dev/null || true
73+
74+
# --- 7. Check recording ---
75+
EVENT_COUNT=$(grep -c '^\[' "$CAST_FILE" || echo 0)
76+
echo "==> Recorded $EVENT_COUNT events"
77+
if [ "$EVENT_COUNT" -lt 20 ]; then
78+
echo "WARNING: Very few events captured."
79+
echo "Cast file: $CAST_FILE"
80+
exit 1
81+
fi
82+
83+
# --- 8. Convert to GIF ---
84+
echo "==> Converting to GIF..."
85+
agg \
86+
--font-size 28 \
87+
--theme github-dark \
88+
--fps-cap 20 \
89+
--idle-time-limit 2 \
90+
--speed 1 \
91+
--last-frame-duration 0.5 \
92+
"$CAST_FILE" "$GIF_RAW"
93+
94+
# --- 9. Trim + compress ---
95+
echo "==> Trimming + compressing..."
96+
FRAME_COUNT=$(gifsicle --info "$GIF_RAW" 2>&1 | head -1 | grep -o '[0-9]* images' | grep -o '[0-9]*')
97+
LAST=$((FRAME_COUNT - 2))
98+
gifsicle "$GIF_RAW" "#0-${LAST}" -O3 --lossy=30 -k 256 -o "$GIF_FINAL"
99+
100+
# --- 10. Report ---
101+
echo "==> Done!"
102+
ls -lh "$GIF_FINAL"
103+
file "$GIF_FINAL"

0 commit comments

Comments
 (0)