Add hero diagram, project icon, and VHS demo pipeline (#46)#78
Merged
Conversation
Restructures the README header with a centered icon, tagline, and a Mermaid flow diagram showing the AI-agent → MCP → simulator → snapshot loop. Adds an SVG icon (assets/icon.svg) and a vhs-driven demo pipeline (scripts/demo.tape + scripts/record-demo.sh) so the demo GIF can be regenerated reproducibly. The GIF reference in the README is commented out until the first recording lands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Records assets/demo.gif via vhs against the bundled SPM ToDo example and embeds it in the README header alongside the captured light/dark variant PNGs. Simplifies the tape (drops chafa — it prints multi-image output vertically, which overflows the terminal viewport) so the demo ends on the variants progress output and the two captured file paths. record-demo.sh now prefers an existing release/debug binary, drops the chafa dependency, and copies the variant PNGs into assets/ as part of the recording pipeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…46) assets/demo.gif is now a side-by-side composite: `vhs` captures the terminal running `previewsmcp list` and `previewsmcp run --platform ios`, `xcrun simctl io recordVideo` captures the booted simulator, and ffmpeg hstacks them with `tpad` to hold both final frames. scripts/ record-demo-ios.sh orchestrates the whole pipeline — warmup, parallel recording, compositing, palette-gen gif. Also fixes a latent bug in BuildHelpers.launchIOSPreview where the FileWatcher for `run --platform ios` was a local `let`, released as soon as the function returned. The timer closure used [weak self], so deinit silently cancelled the polling timer and hot reload never fired. Retained via a module-level IOSRunHolder. The demo now shows the payoff clearly: editing ToDoView.swift renames the navigation title from "My Items" to "Focus Mode" live in the simulator, with the terminal logging "Literal-only change applied (state preserved)" at the moment of the swap. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adopts the AppIcon.png composition (IDE window on the left, iPhone on the right with content card, circular sync arrows over the overlap) but keeps the flat orange→pink gradient and white foreground from the previous icon. Same 256×256 viewBox, still pure SVG. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rasterized from assets/icon.svg at 1024×1024 via rsvg-convert so the iOS host app's icon matches the new README branding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tape now performs two dramatic hot-reload edits: grows the SummaryCard from height 120 to 220 (literal-only, state preserved) and recolors it from .blue to .pink (structural recompile — on-brand). The pink card at full height is a much clearer wow moment than the prior navigationTitle-only swap. - Removes the two variant preview PNGs under the hero GIF and drops the now-unused scripts/demo.tape + scripts/record-demo.sh pipeline that produced them. - Moves the "how to regenerate the demo" documentation out of the README and into scripts/record-demo-ios.sh's header comment so the instructions live next to the code they describe. - record-demo-ios.sh now trims sim.mp4 to the timestamp of its last real frame before compositing — simctl recordVideo pads several seconds of silence after SIGINT, which was stretching the gif to ~63s. Also tightened tape Sleeps where the previous runs showed slack. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three issues on top of the previous iOS demo recording: 1. IOSHostBuilder's cache key hashed only the Swift source, not the bundled resources — replacing AppIcon.png left a stale .app bundle in /tmp/previewsmcp-host serving the old icon indefinitely. The hash now covers the source, the info plist, and the icon PNG data. record-demo-ios.sh also wipes the host-app workdir before recording so any cache-busting edge cases can't bite. 2. The recording previously opened with the last-session's host app still showing. `simctl uninstall` doesn't return to home (iOS keeps a snapshot of the last foreground app), and osascript Cmd+Shift+H doesn't reach the Simulator when it's been launched headless. The script now kickstarts SpringBoard via launchctl, which forces a fresh home screen, and waits 10s for it to settle before starting the simulator recording. 3. simctl recordVideo is variable-framerate with sparse samples, which made the composite simulator half feel laggy against the vhs terminal half. The composite filtergraph now runs `fps=15` (before `trim` — order matters on VFR sources) on both inputs so the gif plays at a consistent 15fps. Also trims sim.mp4 to the terminal's duration + 1.5s to stop simctl's post-SIGINT ghost frames from stretching the composite. The ToDoView demo's final color-swap sleep is also bumped 8s → 14s so the structural recompile finishes before the tape cuts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses review findings on PR #78: - Move iOS `run` file-watcher retention from the module-level `IOSRunHolder` in BuildHelpers.swift to a proper hand-off through `PreviewHost.retainFileWatcher`. PreviewHost is already the MainActor app-lifetime singleton that stores the macOS path's watchers; storing iOS watchers there too removes the `nonisolated(unsafe) static var` footgun and matches the existing pattern. - Add a regression test in the new PreviewsMacOSTests target that creates a FileWatcher inside an inner scope, hands it to PreviewHost.retainFileWatcher, releases the local binding, and then asserts the callback still fires on a subsequent file modification. Without the retention hand-off the timer closure's weak self would cause deinit immediately and the test would go red — a direct guard against regressing the original hot-reload bug. - Drop `rm -rf /tmp/previewsmcp-host` from scripts/record-demo-ios.sh. It was a defensive workaround for the stale-cache bug fixed in the previous commit (IOSHostBuilder.sourceHash now covers resources), and it was costing ~30s per recording regen for no remaining benefit. - Pass `$term_dur` into awk via `-v` instead of string interpolation. Trusted source here (ffprobe on a file we just wrote) so no active vulnerability, but the previous pattern would have produced a parse error on any non-numeric output — wrong-by-default. Co-Authored-By: Claude Opus 4.6 (1M context) <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.
Summary
assets/icon.svg(orange/pink gradient, preview-window motif with a device frame and a green live-indicator dot)scripts/demo.tape(vhs script) +scripts/record-demo.sh(deps check + release build + vhs invocation)Addresses parts of #46 — hero diagram and icon land now; the demo GIF lands after running
scripts/record-demo.sh(the README reference is currently commented out so GitHub doesn't render a broken image).Notes
ToDoexample and pipes the resulting snapshots throughchafaso the GIF visually shows both the CLI and the rendered preview without needing a separate screen recording.vhs,chafa. Documented in the README's "Regenerating the demo GIF" section.Test plan
xmllintvalidatesassets/icon.svgrsvg-convert(verified visually)scripts/record-demo.shon a machine withvhs/chafainstalled and confirmassets/demo.gifis produced<img>block inREADME.mdand verify it renders in GitHub preview