# caspar-AV's hosted demo caspar-AV drives a CasparCG server over AMCP and listens to its OSC telemetry, so it can't be hosted in any useful sense — there is no server for a page on the public internet to drive. What is hosted is a **click-through demo**: the real, unmodified console, replaying responses recorded from `caspar-avd` itself running against `scripts/fake-caspar.py`. That fake speaks real AMCP framing, real `REQ`/`RES` correlation and pushes real OSC, and stands in for media-scanner. So the demo isn't a mockup of caspar-AV — it's caspar-AV's own output, captured. **Firing a cue works.** `record-demo.sh` fires all five cues in `demo-show.json` against the running bridge and records what it did, so clicking *Fire* in the demo puts the bridge's actual AMCP into the command log — `PLAY 1-10 WALK_IN/LOGO_LOOP LOOP MIX 25` and the rest, exactly as it compiled them. **Media thumbnails are real too**, recorded from the scanner and inlined by the shim (they're ``, which never goes through `fetch`). Nothing is live, and nothing is saved. Editing a cue, dragging a screen or sending a raw AMCP command reports that the click went nowhere rather than faking success. ## What's here | File | What it is | |---|---| | `record-demo.sh` | Rebuilds everything: fake server, bridge, recording, assembly | | `record-fixtures.mjs` | Records a running backend's reads, telemetry and writes (vendored) | | `demo-shim.js` | Replays the recording over `fetch` / `WebSocket` / `` (vendored) | | `build-demo.sh` | Assembles the built console + shim + fixtures into a site (vendored) | | `serve-demo.py` | Serves it with a static host's headers, for local checking (vendored) | | `demo-fixtures.json` | The recording. Regenerate it; don't hand-edit it | | `dist/` | **Committed build output** — what Cloudflare Pages serves | | `dist/` | **Committed build output** — what Cloudflare Pages serves | The vendored files come from `stoatworks-backend/pages-demo`. Fix them there and copy out, or the copies drift. ## Rebuilding and publishing ```bash demo/record-demo.sh # fake server + bridge + record + assemble demo/serve-demo.py --dir demo/dist # check it locally first git add demo/dist && git commit && git push ``` Cloudflare Pages publishes `demo/dist` from the repo with **no build command**. It has to be committed: assembling the demo means running the bridge against a fake CasparCG and capturing what it says, which a build container can't do. ## Rules the demo has to keep - **It always says it's a demo.** The banner isn't optional. - **Fixtures are recorded, never authored.** A hand-written fixture is a guess about what the software does, and guesses drift away from the code. - **An unrecorded control says so.** Don't turn one into a fake success message — that's a demo showing behaviour the software doesn't have.