feat(media): hero streaming-demo assets generated from source (pnpm gen:media)#440
Merged
Conversation
…en:media)
docs/media/streaming-demo.{mp4,gif} + streaming-demo-square.mp4 are rendered
from a deterministic HTML scene (every frame is a pure function of time via
__seek(t)) by frame-stepping headless Chromium and assembling with ffmpeg —
no hand recording, fully reproducible. GIF is auto-stepped down until it fits
the < 2.5 MB budget (currently 285 KB at 1280px/15fps). The on-screen snippet
mirrors the real useStitchStream JSDoc example.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ponents Replace the hand-built HTML scene with apps/docs/app/demo/streaming — a real (noindexed) page reusing CodePanel, Logo, BrandBackdrop, and the Signal tokens, so the capture always matches the live brand (fonts, palette, amber ✓ chip instead of an off-system green). The generator now boots the docs dev server on a dedicated port and frame-steps the page; determinism is unchanged (render is a pure function of t, CSS animations frozen and the Next dev indicator hidden in capture mode). Visitors get the same scene self-running via rAF at /demo/streaming. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…token
The demo loop now cycles four chapters — streaming-first, validation +
drift, resilience, agent-native — each with real verified API usage
(retry/throttle/timeout/cache shapes, drift(User), stitch run/mcp front
doors) and a chapter-dot indicator. The '✓' badge and success rows use a
new --ok status token (light #15803d / dark #4ade80 + soft/line tints)
added to tokens.css/global.css instead of the amber accent. gen:media now
renders a theme × layout matrix: streaming-demo[-dark].{mp4,gif} +
streaming-demo-square[-dark].mp4, via Playwright colorScheme emulation.
Chapter out-fades land a beat before the boundary so the loop seam stays
clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
streaming-demo[-dark].webp (libwebp_anim, 15 fps, q70): 24-bit color with no palette banding at ~770 KB vs the ~2.45 MB GIFs. GitHub renders animated WebP, so the README <picture> snippet now uses it; the GIFs stay for channels that only accept .gif uploads. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ements example Also drops cache from the resilience snippet so each chapter owns one feature (resilience = retry/throttle/timeout). GIF ladder stepped down to 12fps/128c as designed and both GIFs stay under the 2.5 MB budget. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… managed renewal Agent chapter's third row becomes discovery/flat-context (code-mode) so the capability message lives in one place. GIF ladder stepped to 1120px (light) / 960px (dark). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Trace scene: per-stitch trace: 'console', STITCH_TRACE_FILE + stitch trace summary rows, secrets-scrubbed-at-sink. The scene now accepts ?chapters=<keys> (refs re-keyed from index to chapter key), and the generator captures GIFs from the 4-chapter marquee cut at full 1280px/15fps — GIF size is now constant as the tour grows, while mp4/webp carry all 7 chapters (35.2 s). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ure has a scene Full tour is now 9 chapters (45 s): streaming, drift, shaping (unwrap), resilience, caching, auth, observability, request styles (llm/graphql/ sse — one engine), agent-native. Snippets mirror the llm() JSDoc and the README hero's unwrap example. GIFs stay the fixed 4-chapter marquee cut. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rejifald
commented
Jul 3, 2026
rejifald
left a comment
Owner
Author
There was a problem hiding this comment.
review-sweep (re-review at 47c5b8b — supersedes the unposted payloads for 643664c and e70a8fa): 8 findings — 4 medium, 4 low; all in-diff, none security. Headlines: the hero snippet still wouldn't stream, the new caching chapter animates a cache HIT that the snippet (run verbatim) refuses to serve, and the branch now carries four generations of regenerable binaries (21 MB of blobs). A related pre-existing README issue (deprecated maxEntries in the Caching example) is filed separately. See inline comments.
seam() declares the cross-cutting config once (SeamConfig: base, auth, throttle…); members inherit it via api.stitch() and share one runtime. Full tour: 10 chapters, 50 s. GIF stays the fixed 4-chapter marquee cut. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…an tracked set, retina
Scene: chapter 1 now uses sse({ url }) (the surface that actually emits
delta chunks — mirrors integrations/react.mdx); caching chapter adds
cache.version so the snippet is honestly cacheable without a registered
fingerprinter (README announcements example gets the same fix).
Quality (the ghosting report): crossfades shortened to 0.22 s; GIF
re-encoded at 256 colors, dither=none, full-frame updates (measured both
cleaner AND smaller — 1729 KB vs 2434 KB); webp is now lossless (beats
q95 on this content); mp4 crf 14; new @2x retina exports (2560×1440).
Repo size: only the README-embedded @2x webp pair stays tracked —
mp4/gif/square variants are gitignored and regenerate via pnpm gen:media
(squash-merge recommended for this PR).
Pipeline: ffmpeg+libwebp preflight before the server boots; dev server
killed on the startup-timeout path; chromium launched inside try with
SIGINT/SIGTERM handlers; all encodes stage in a temp dir and publish to
docs/media only after every variant succeeds.
Drift gate: scripts/check-media-freshness.mjs (pnpm check:media-fresh,
lefthook pre-push) fails a branch that edits the scene/generator without
regenerating the committed pair; STITCH_MEDIA_STALE_OK=1 defers.
Reproducibility claim softened to visually-reproducible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The loop covers ten features now, so 'streaming-demo' undersells it: assets are demo*, the live page is /demo, the component is <DemoMedia /> (theme via the site's .dark class, 1x/@2x via srcset density). README gets the theme+density <picture> after the badge block, linked to the live tour; the homepage gets a 'See it run' Demo section after Problem. copy-demo-media skips missing files (gen:media boots the dev server before the assets exist on a fresh clone). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Proof before pitch: most visitors never reach viewport 4, and the demo's closing chapter is the agent story, so it sets up 'Built for agents' rather than upstaging it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The page was a fixed full-viewport overlay with no way out. It now lives in the route group with the navbar, a heading, and a playground link; the stage renders in-flow at its 1280×720 design size, scaled to the page column (ScaledStage — no reflow, just zoom). ?capture=1 keeps the exact-viewport opaque overlay, so the generator's pixel contract and the committed assets are unchanged (verified against a 1280×720 capture screenshot). Page is now indexable with a proper title/description; export renamed StreamingScene→DemoScene. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Marketing campaign topic A0 — the hero demo for the README, Show HN, Product Hunt, and X. Ships the assets and the pipeline that regenerates them from source (
pnpm gen:media):docs/media/streaming-demo[-dark].mp4— 1280×720, 30 fps, ~20 s loopdocs/media/streaming-demo[-dark].webp— README embed via<picture>docs/media/streaming-demo[-dark].gif— for gif-only channels (PH gallery etc.)docs/media/streaming-demo-square[-dark].mp4— 1:1 for socialNine feature chapters — one per core feature
One loop cycles every core feature, with a chapter-dot indicator: streaming-first, validation + drift (
drift(User)), data shaping (unwrap: 'data'), resilience (retry/throttle/timeout), caching (cache: { ttl, scope }— MISS→HIT, derived keys), auth (bearer(env())— capability, not credential), observability (trace: 'console',stitch trace), any request style (llm()/graphql/sse — one engine), and agent-native (stitch run/stitch mcp→run_stitch). Every snippet is verified against README/core shapes and package JSDoc examples. The full ~45 s tour ships as mp4 + WebP; the GIF is a fixed 4-chapter marquee cut (via the scene's?chapters=param) so it stays at full 1280 px quality under its 2.5 MB budget no matter how many chapters the tour gains.The scene is a docs-site page, not a mockup
apps/docs/app/demo/streaming(noindexed) reusesCodePanel,Logo,BrandBackdrop, the Signal tokens and type stacks. Visit/demo/streamingon a dev server to watch it live (rAF-driven; static end-state under prefers-reduced-motion). Light/dark both work — the capture matrix records each viacolorSchemeemulation.New design-system token
Success states needed a color the palette didn't have; rather than hard-coding a hex (forbidden by tokens.css), this adds a semantic
--okstatus token (light#15803d/ dark#4ade80+--ok-soft/--ok-linetints, exposed asbg-ok-soft/text-ok/border-ok-line). The "✓ …" badges and success rows use it.Generated from source, not hand-recorded
Every frame is a pure function of time (
window.__seek(t);?capturefreezes CSS animations and hides the Next dev indicator). The generator boots the docs dev server on a dedicated port (refusing to reuse an unknown server), frame-steps headless Chromium at 30 fps / 2× DPR, and assembles with ffmpeg; GIF encoding walks a quality ladder until it fits the budget.Verified
retry: { attempts, on },throttle: { rate: '10/s' },timeout,cache,drift(User),stitch run/stitch mcpall match README/coreFollow-up (separate PR): wire the GIF into the README hero via the
<picture>snippet in docs/media/README.md.🤖 Generated with Claude Code