Verify
Verify an engine change end-to-end by rendering the bundled fixture (examples/local-demo) and inspecting the output MP4 and intermediates. Use when the user says "verify", "run the smoke test", "e2e this change", "does the fixture still render", or before committing a nontrivial engine change. Knows the gotchas: OPENAI_API_KEY (or a local OPENAI_BASE_URL server) is needed for voice/captions but not probe/record/compose, stage-by-stage re-runs beat full re-renders, AIDEMO_KEEP_TMP=1 keeps .compose-tmp for compose debugging, logs/fail-*.png from failed takes. Do NOT use for: recording real product demos (use record-demo) or doc-only changes with no runtime surface.From its SKILL.md
npx -y skills add tandryukha/aidemo --skill verifyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 22 stars22 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.8 KB, as published. Nobody here has run it
verify — e2e smoke test for engine changes
Your job: prove a change to the engine still renders the self-contained fixture end-to-end. Be terse; surface only failures + a final status.
Phases
-
Typecheck (always):
npm run typecheck -
Fixture server (background; it's a plain static server on :8787):
node examples/local-demo/serve.mjs & curl -sf http://localhost:8787 >/dev/null && echo up -
Full e2e (needs
OPENAI_API_KEYin.env, orOPENAI_BASE_URLpointing at a local OpenAI-compatible server — check withnode bin/aidemo.mjs doctorfirst; it reports the resolved endpoint):node bin/aidemo.mjs render examples/local-demo --headlessIf neither is available, prefer the offline full e2e — the bundled mock serves both endpoints locally, so every stage still runs, with zero API spend (say which path you used in the report):
node test/mock-openai.mjs & # mock TTS+STT on :8790 OPENAI_API_KEY= OPENAI_BASE_URL=http://127.0.0.1:8790/v1 \ node bin/aidemo.mjs render examples/local-demo --headless(Narration is sine tones and captions are placeholder words — fine for verifying the pipeline, useless for judging output quality.) Last resort:
probe(selectors) +record+composeagainst previously generatedaudio//generated/artifacts if present (captions --offlinecan regenerate caption cues from an existingvoice.jsonwithout network). -
Inspect the output — existence is not enough:
ffprobe -v error -show_entries format=duration -show_entries stream=codec_type \ -of default=nw=1 examples/local-demo/output/final-demo.mp4Expect one video + one audio stream and a plausible duration (the fixture is ~30–60 s). A suspiciously tiny file or missing audio stream is a failure.
-
Stage-scoped iteration — if the change touches one stage, re-run just it (
voice,record,captions,compose, orprobefor selector work) instead of a full re-render; each stage is independently re-runnable. -
Cleanup: kill the serve process from phase 2.
Gotchas
- Logs:
examples/local-demo/logs/<command>.log; failed takes leavelogs/fail-*.png/json— read those before re-running blind. - Compose hangs → look for an unbounded
apador-stream_loop -1in the filtergraph (they never EOF; see AGENTS.md ffmpeg gotchas). - Captions missing from the output with no error → negative-pts stream-copy concat; the card assembly concat must re-encode.
AIDEMO_KEEP_TMP=1 node bin/aidemo.mjs compose examples/local-demokeeps.compose-tmp/so you can ffprobe intermediate segments.- Don't leave the fixture server running or the port collides on the next run.
Report
verify: PASS|FAIL
typecheck: ok|errors
e2e: full render | offline full render (mock) | keyless fallback (probe+record+compose) | skipped (why)
output: <duration>s, video+audio | anomaly: <what>
failures: <stage → cause → log excerpt> (omit if none)