Portfolio (every app, both stores, rollout %, crash sparklines), the Growth and Health charts with a real hover sweep (one captured frame per hovered day, the pointer follows the recorded positions), the Prices matrix (both stores per country, gaps marked), then v5's release timeline and 0 blockers. All frames are real fixture-mode captures (desktop.ts). Tests: scenes 4-5 s, 50-60 s total, captions >= 3 s, every desktop frame captured by desktop.ts and present. |
||
|---|---|---|
| .. | ||
| icons | ||
| desktop.ts | ||
| index.html | ||
| music.js | ||
| poster.jpg | ||
| README.md | ||
| render.ts | ||
| script.js | ||
| site-shots.ts | ||
| teaser.js | ||
storebound teaser (55.5 s, 16:9)
A calm, scripted motion piece: from an empty folder to everything ready on both stores. Every frame is a pure function
of time, rendered from an HTML/CSS/JS timeline in headless Chrome and encoded with ffmpeg. The music and the sound
design are original and synthesized from scratch in the same browser (Web Audio OfflineAudioContext): no samples,
no downloaded audio, nothing to license.
One idea per scene, 4-5 s each, one camera move per scene (a quick ease-out that settles before the cut), short dissolves on the cuts, no whips or rapid montages. Long terminal output streams faster rather than being cut. Each scene has one plain-English caption at the top, fully on screen for at least 3 s; below it, the real product.
| s | shows | caption |
|---|---|---|
| 0-4.5 | the demo game's icon, "Done"; the stores' to-do list line by line; one rejection mail (Guideline 2.1) | Your app is done. The stores are not. |
| 4.5-9 | an empty folder; bunx storebound init is typed; the files it creates list in |
storebound takes it from an empty folder. |
| 9-14 | the prompt "Get my app ready for both stores."; storebound release plan 1.0.0: 25 steps in fix order |
You ask once. It plans every step. |
| 14-19 | the demo game's store text in 4 languages; its renders in 7 store sizes x 4 languages | Store text and screenshots. Every language, every size. |
| 19-23.5 | play products --dry (174 regions), then catalog diff (175 / 174 region prices, 0 mismatches) |
In-app products on both stores, priced in 175 countries. |
| 23.5-28.5 | the scan's declarations proposal: detected answers with file:line, one "ask owner" line highlighted; 764 Data safety answers | The forms, answered from your code. It asks what it can't know. |
| 28.5-33.5 | storebound scan: three findings, each with a plain reason; fixed, the re-scan is clean |
It catches rejections before Apple does. |
| 33.5-38 | the desktop app's Portfolio: every app of three studios, App Store and Google Play per app, rollout %, crash-rate sparklines | Stop switching between two consoles. Every app, both stores, one window. |
| 38-42.5 | the Growth chart (visx) with the pointer sweeping across it, the crosshair and tooltip moving day by day; then the Health tab's crash rate, swept the same way | Installs, conversion and crashes, charted. |
| 42.5-47 | the Prices tab: products x key territories, both stores' prices per country, the gaps between them marked | Products and prices on both stores, side by side. |
| 47-51.5 | the release timeline with both stores on one track, then Store readiness: "No blockers" | Both stores, one view. Ready for review. |
| 51.5-55.5 | "Submit for Review" with the cursor resting on it (it never clicks), then the end card: storebound.dev, Open source · CLI · Desktop app | You press Submit. That's it. |
| file | what |
|---|---|
script.js |
the timeline: scenes in seconds, camera moves, captions, every line shown, the sound cues |
desktop.ts |
the desktop frames: apps/desktop's Vite dev server in fixture mode (VITE_FIXTURES=1, example.com-style data), captured headlessly in dark at 1280x800 @2x with the dev markers hidden, plus boxes.json (callout targets, the hover sweeps) -> out/desktop/. The chart hovers are real: the mouse moves across the chart in small steps and a frame is taken for every day the tooltip shows; the video moves its pointer the same way and shows the day it has reached |
index.html + teaser.js |
the picture; window.teaser.seek(t) sets every element for time t |
music.js |
music (D major, one chord per scene: pads, a slow soft pluck, a quiet sub) and soft sound design: a bell and an airy swell on each scene change, key clicks, quiet ticks, chimes for the fixes |
render.ts |
frames at 60 fps blended to 30 fps -> ffmpeg (H.264 high, yuv420p), sound -> loudnorm (-16 LUFS, -1.5 dBTP), mux, poster, the 1280x720 web version |
icons/ |
the mouse cursor and the UI icons: Phosphor files copied unchanged by bun tools/site-icons.ts (no hand-written SVG; CI checks it) |
Every CLI line in the video is real output, and tests/teaser.test.ts runs each command and checks every line (the
clock prefix and the "(0s)" timer left out):
storebound initin an empty temp folder.storebound release plan 1.0.0,play products --dryandcatalog diffin that folder, with the stores answered bytests/helpers/teaser-store-mock.ts(preloaded through abunfig.tomlin the folder, so the childrenrelease planstarts use it too; nothing reaches the network): a brand-new app record with nothing on it for the plan and the dry run, then the two products on both stores for the diff. Regions: the App Store's 175 storefronts, Google Play 174 (the count Play answered in a recorded read-only run).storebound scanoftests/fixtures/scan/teaser(findings, declarations proposal) and ofteaser-fixedafter the fixes, and the Data safety answer count ofstorebound check.
The plain reasons under the findings and the callouts on the desktop frames are annotations, set apart from the CLI
text. The store text is examples/demo-game/store/shots/copy.json, the screenshots its real renders, the app icon its
store/icon/icon.png. The mail row is fictional: no real names or addresses, no mail-app branding. The test also checks
the timing (scenes 4-5 s, captions on screen at least 3 s, 50-60 s in total, 16:9 only) and that every desktop frame a
scene names is one desktop.ts captures, and, where they were captured, that each file is there (2560x1600 JPEG, one
sweep frame per hovered day).
Render
Needs Bun, ffmpeg, Playwright (repo devDependency; Playwright's Chromium or an installed Google Chrome) and the demo game's store renders:
cd examples/demo-game && bun serve.ts & bun ../../cli/index.ts shots capture && bun ../../cli/index.ts shots fonts && bun ../../cli/index.ts shots render
# from the repo root
bun media/teaser/render.ts > media/teaser/out/render.log 2>&1 & # master, sound, poster, web version: about 15 min
bun media/teaser/render.ts --desktop # capture the desktop app frames again (after a UI change)
bun media/teaser/render.ts --stills 2,12.5,30 # PNG stills in out/stills for a quick layout check
bun media/teaser/render.ts --serve --port 8750 # live preview: /index.html?play=1 (or ?t=12.5)
Outputs (gitignored) in media/teaser/out/: teaser-1920x1080.mp4 (master), teaser-web.mp4 (1280x720, about
6 MB) with poster-web.jpg, teaser-1920x1080-silent.mp4, poster-1920x1080.jpg, music.wav.