@qwertybit/pr-preview 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,84 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.5] — 2026-07-07
10
+
11
+ ### Changed
12
+
13
+ - **New demo animation** — refreshed the README/npm demo with a designed
14
+ walkthrough of the full flow: a Claude Code prompt kicks off the run, the app is
15
+ driven automatically in a real Chrome window (add to cart → checkout, recording a
16
+ before/after), and out come `before.mp4` + `after.mp4`. Also available as an MP4.
17
+
18
+ ## [0.1.4] — 2026-07-07
19
+
20
+ ### Fixed
21
+
22
+ - **The cursor is visible again** — the synthetic pointer is now anchored to the
23
+ viewport origin, so it no longer drifts off-frame (and out of the cropped clip)
24
+ when the app centers its layout with flexbox/grid. It's also larger, with an
25
+ always-on highlight halo, so it reads clearly once the clip is downscaled — and a
26
+ regression test now asserts it renders and moves across captured frames.
27
+ - **Motion smoothing actually applies now** — corrected the ffmpeg `minterpolate`
28
+ scene-change-detection argument. The previous value was an invalid token, so the
29
+ interpolation command failed on every clip and silently fell back to a
30
+ non-interpolated, choppy encode. MP4s now interpolate as intended, and the
31
+ fallback logs a warning instead of failing quietly.
32
+
33
+ ### Changed
34
+
35
+ - **Snappier motion** — cursor glides, scrolling, and settle pauses are quicker now
36
+ that the capture runs at ~60fps during motion; the slow pacing was only needed for
37
+ the old low, variable capture rate.
38
+
39
+ ### Added
40
+
41
+ - **Smoother recordings** — agent-driven clips now read as fluid video instead of
42
+ a slideshow. Three changes: (1) the CDP screencast is capped to ~the CSS window
43
+ size so Chrome stops JPEG-encoding full Retina-resolution frames, raising the
44
+ delivered frame rate; (2) the agent animates motion in-page — the synthetic
45
+ cursor glides (distance-scaled), scroll eases, and text types character-by-
46
+ character; (3) a new `gif.interpolate` option (`"blend"` default / `"mci"` /
47
+ `"off"`) synthesises intermediate MP4 frames from the real captured frames up to
48
+ `gif.smoothFps` (default 60), so a low, variable capture rate still plays smooth.
49
+ `"blend"` never warps text/geometry; `"mci"` is sharper with a slight warp risk
50
+ on fast-scrolling dense pages.
51
+
52
+ - **Claude Code integration via MCP** — a new `pr-preview mcp` command starts a
53
+ Model Context Protocol server (stdio) so an agent can record a journey from a
54
+ plain-English prompt. Claude reads the app's accessibility tree and drives it
55
+ with real clicks/typing, so the existing engine captures a real live clip — it
56
+ is agent-driven, not synthesized. Tools: `start_recording`, `snapshot`, `act`,
57
+ `next_pass`, `finish_recording`, `open_pr`, `cancel_recording`.
58
+ - **Agent before/after** — `start_recording({ mode: "before-after" })` records the
59
+ same journey on the PR base branch (in a git worktree) and on your branch,
60
+ producing `before.*` and `after.*`, all driven by the agent.
61
+ - **`open_pr` tool** — commits the clip into `pr-preview/`, pushes the branch, and
62
+ opens a pull request with the preview embedded (an inline GIF plus a link to the
63
+ full MP4). Requires the GitHub CLI (`gh`) authenticated.
64
+ - **`detect_localhost` tool + "never guess the URL"** — probes common dev-server
65
+ ports and reports which local apps are running (with page titles). When no URL
66
+ is given, the agent uses it to ask which running app to record, or to ask for a
67
+ local/staging/production URL — it never guesses.
68
+ - **`/record` slash command** — `init` installs a Claude Code skill at
69
+ `.claude/skills/record/SKILL.md`, so you can record any flow in one line:
70
+ `/record localhost:3000 add a book, then checkout`. It drives the recording
71
+ through the MCP tools (agent mode). Non-destructive: skipped if it already exists.
72
+ - **`init` now writes `.mcp.json`** (merging into an existing file) so Claude Code
73
+ discovers the server automatically, plus the `/record` skill above.
74
+ - **`init` prompts before overwriting** — when a `pr-preview` config, MCP server
75
+ entry, or `/record` skill already exists, it asks `Overwrite it? (y/N)` instead
76
+ of silently skipping. In a non-interactive shell (CI) it defaults to keeping the
77
+ existing file.
78
+
79
+ ### Notes
80
+
81
+ - Agent before/after needs a managed dev server (omit `url`); already-running
82
+ apps (`--url`) remain single-clip in agent mode. Manual `pr-preview run` is
83
+ unchanged and still supports the full `--url` before/after flow.
84
+
7
85
  ## [0.1.0] — 2026-06-08
8
86
 
9
87
  Initial release.
@@ -30,4 +108,7 @@ Initial release.
30
108
  CSP `frame-ancestors`) are stripped.
31
109
  - CLI: `pr-preview init`, `pr-preview record`, `pr-preview run`.
32
110
 
111
+ [Unreleased]: https://github.com/QwertyBit-Ventures/pr-preview/compare/v0.1.5...HEAD
112
+ [0.1.5]: https://github.com/QwertyBit-Ventures/pr-preview/compare/v0.1.4...v0.1.5
113
+ [0.1.4]: https://github.com/QwertyBit-Ventures/pr-preview/compare/v0.1.0...v0.1.4
33
114
  [0.1.0]: https://github.com/QwertyBit-Ventures/pr-preview/releases/tag/v0.1.0
package/README.md CHANGED
@@ -16,7 +16,11 @@
16
16
  </p>
17
17
 
18
18
  <p align="center">
19
- <img src="https://cdn.jsdelivr.net/npm/@qwertybit/pr-preview/assets/demo.gif" alt="PR Preview demo — recording a UI journey and producing a before/after video" width="720" />
19
+ <img src="https://cdn.jsdelivr.net/npm/@qwertybit/pr-preview/assets/demo.gif" alt="PR Preview demo — a Claude Code prompt drives the app in Chrome and produces before/after videos" width="720" />
20
+ </p>
21
+
22
+ <p align="center">
23
+ <a href="https://cdn.jsdelivr.net/npm/@qwertybit/pr-preview/assets/demo.mp4">▶ Watch in higher quality (MP4)</a>
20
24
  </p>
21
25
 
22
26
  **PR Preview** opens your app in a controlled Chrome window and records the journey you perform —
@@ -38,33 +42,35 @@ about a minute.
38
42
 
39
43
  ---
40
44
 
41
- ## Features
45
+ ## Features
42
46
 
43
- - 🎬 **Record by demonstration** — just use your app. Clicks, typing, scrolling and navigation are
47
+ - **Record by demonstration** — just use your app. Clicks, typing, scrolling and navigation are
44
48
  captured as an editable outline; no selectors or scripts to hand-write.
45
- - 🎥 **Live capture, zero drift** — the clip is your real recording, not a replay, so it never
49
+ - **Live capture, zero drift** — the clip is your real recording, not a replay, so it never
46
50
  desyncs on stateful apps. A synthetic cursor makes every move easy to follow.
47
- - 🌳 **True before/after** — the base branch runs in an isolated git **worktree**; your working
51
+ - **True before/after** — the base branch runs in an isolated git **worktree**; your working
48
52
  tree is never touched. Or point it at an app you already run with `--url`.
49
- - 🎞️ **Tiny, sharp MP4s** — H.264, near-Full-HD, a few hundred KB. GitHub renders them inline in a
53
+ - **Tiny, sharp MP4s** — H.264, near-Full-HD, a few hundred KB. GitHub renders them inline in a
50
54
  PR. High-quality GIF fallback when ffmpeg isn't installed.
51
- - 🔒 **Runs entirely on your machine** — nothing is uploaded. Your source and app data never leave
55
+ - **Runs entirely on your machine** — nothing is uploaded. Your source and app data never leave
52
56
  your computer.
53
- - 🏷️ **Self-describing clips** — each is captioned with its branch and a timestamp.
54
- - 🤖 **Agent-friendly**config-driven and flag-free, so you can kick it off from Claude Code or CI.
57
+ - **Self-describing clips** — each is captioned with its branch and a timestamp.
58
+ - **Drive it from Claude Code** — a built-in MCP server lets Claude record a journey for you from
59
+ a plain-English prompt: it opens Chrome, performs the flow step by step, and can even open the PR.
60
+ Agent-driven, but still a real capture of your real app — never synthesized. Manual mode still works.
55
61
 
56
- ## 🚀 Install
62
+ ## Install
57
63
 
58
64
  ```bash
59
65
  npm i -D @qwertybit/pr-preview
60
66
  npx playwright install chromium # one-time browser download
61
- npx pr-preview init # scaffolds pr-preview.config.js
67
+ npx pr-preview init # scaffolds pr-preview.config.js + .mcp.json (Claude Code)
62
68
  ```
63
69
 
64
70
  > **ffmpeg** (optional, recommended) gives you MP4 output. macOS: `brew install ffmpeg` ·
65
71
  > Debian/Ubuntu: `apt install ffmpeg`. Without it, PR Preview produces a high-quality GIF instead.
66
72
 
67
- ## Quick start
73
+ ## Quick start
68
74
 
69
75
  On your PR branch:
70
76
 
@@ -85,7 +91,7 @@ Both clips land in `.pr-preview/output/`. Drag them into your PR description —
85
91
  Just need one clip (a demo, a bug repro)? `npx pr-preview run --single` records a single standalone
86
92
  video, no comparison.
87
93
 
88
- ## 🧠 How it works
94
+ ## How it works
89
95
 
90
96
  A run is a short wizard shown in the harness sidebar:
91
97
 
@@ -103,7 +109,7 @@ Record Capture Record Capture Generate
103
109
  keep a session you set up by hand (e.g. a manual login) — only shown when there's state to reset.
104
110
  - **Refresh button** in the frame corner reloads the app whenever you need a clean slate.
105
111
 
106
- ## 📦 Output
112
+ ## Output
107
113
 
108
114
  | `format` | Result | Needs ffmpeg |
109
115
  | --- | --- | --- |
@@ -113,7 +119,7 @@ Record Capture Record Capture Generate
113
119
 
114
120
  MP4 is recommended: full color, far smaller than GIF, and GitHub embeds it inline.
115
121
 
116
- ## ⚙️ Configuration
122
+ ## Configuration
117
123
 
118
124
  Everything lives in `pr-preview.config.js` (or `.ts` / `.json`), so a project is set up once and
119
125
  runs with **no flags**:
@@ -161,13 +167,14 @@ export default {
161
167
  | `permissions` | allow-all | Browser permissions to grant (Playwright names). Unlisted ones stay denied — no native prompt blocks the run. |
162
168
  | `geolocation` | — | Fixed `{ latitude, longitude }` so location apps render identical results in both clips. |
163
169
 
164
- ## 🖥️ CLI
170
+ ## CLI
165
171
 
166
172
  | Command | What it does |
167
173
  | --- | --- |
168
- | `pr-preview init` | Scaffold `pr-preview.config.js` and a `.gitignore` entry. |
174
+ | `pr-preview init` | Scaffold `pr-preview.config.js`, a `.gitignore` entry, `.mcp.json`, and the `/record` Claude Code skill. |
169
175
  | `pr-preview record` | Record a journey on the current branch only (`-o <file>`). |
170
176
  | `pr-preview run` | The full before/after flow. |
177
+ | `pr-preview mcp` | Run the MCP server (stdio) so Claude Code can drive a recording. |
171
178
 
172
179
  `run` flags: `-b, --base <ref>` (override base) · `--keep-worktree` (reuse the base worktree) ·
173
180
  `-u, --url <url>` (use your own running app) · `-s, --single` (one standalone clip, no comparison).
@@ -185,14 +192,68 @@ npx pr-preview run --url http://localhost:3000
185
192
  It records BEFORE on your running app, then **pauses** — you switch branches, restart on the same
186
193
  URL, and click **Continue** — then it records AFTER. No worktree, no managed dev server.
187
194
 
188
- ## 🤖 Use it from Claude Code
195
+ ## Use it from Claude Code
196
+
197
+ PR Preview ships an **MCP server** so Claude Code can record a journey for you — you describe the
198
+ flow in plain English and Claude drives your real app in Chrome, records it, and (optionally) opens
199
+ the PR. It's agent-driven, but still a real capture of your real app; nothing is synthesized.
200
+
201
+ **Setup** — `npx pr-preview init` writes a `.mcp.json` that registers the server:
202
+
203
+ ```json
204
+ { "mcpServers": { "pr-preview": { "command": "npx", "args": ["pr-preview", "mcp"] } } }
205
+ ```
206
+
207
+ Open the project in Claude Code (it auto-discovers `.mcp.json`) and just ask:
208
+
209
+ > **You:** Record my add-to-cart flow — add 3 books to the cart, then go to checkout. Then open the PR.
210
+ >
211
+ > **Claude:** *opens Chrome, performs each step live, renders `before.mp4` + `after.mp4`, and opens
212
+ > the pull request with the clip embedded.*
213
+
214
+ **The tools Claude uses:**
215
+
216
+ | Tool | What it does |
217
+ | --- | --- |
218
+ | `start_recording` | Open the app + start recording. `mode: "single"` (one clip) or `"before-after"`. Omit `url` to start your dev server; pass one to record an app you already run. |
219
+ | `snapshot` | Read the page as an accessibility tree with `[ref=eN]` handles. |
220
+ | `act` | Perform one action: `click` / `fill` / `press` / `hover` / `navigate` / `scroll` / `wait`. |
221
+ | `next_pass` | *(before-after)* finish the BEFORE clip, switch to your branch, start AFTER. |
222
+ | `finish_recording` | Stop, encode, and return the clip path(s). |
223
+ | `open_pr` | Commit the clip, push the branch, and open a PR with the preview embedded. |
224
+ | `detect_localhost` | Probe common dev-server ports and report which local apps are running (with their page titles). |
225
+ | `cancel_recording` | Abort and close the browser without producing a clip. |
226
+
227
+ Claude targets elements by their accessible name (no selectors or scripts), so it works on any app.
228
+
229
+ **No URL? Claude asks — it never guesses.** If you don't name a URL, Claude runs `detect_localhost`
230
+ first: if apps are running it asks which one to record; if none are, it asks for a local, staging, or
231
+ production URL. That way it always records the app you meant.
232
+
233
+ **The `/record` slash command.** `init` also installs a Claude Code skill at
234
+ `.claude/skills/record/SKILL.md`, so you can record any flow in one line:
235
+
236
+ ```
237
+ /record localhost:3000 add a book to the cart, then checkout
238
+ ```
239
+
240
+ The skill drives the recording through the MCP tools above (agent mode), resolving the URL the same
241
+ way. It's non-destructive — `init` skips it if the file already exists.
242
+
243
+ **Before/after in agent mode** needs a managed dev server (omit `url`) and for you to be on a PR
244
+ branch: Claude records the journey on the base branch (in a git worktree), then redoes the *same*
245
+ journey on your branch. `--url` / already-running apps stay single-clip in agent mode, since an
246
+ external app can't be branch-swapped without you.
247
+
248
+ **About `open_pr`:** GitHub only plays inline video from its own attachment CDN (no public API), so
249
+ the open-source path embeds an animated **GIF** (rendered inline) and links the full MP4. It creates
250
+ a commit on your branch and pushes it, and needs the [GitHub CLI](https://cli.github.com) (`gh`)
251
+ authenticated. One-click *hosted video in the PR body* is part of PR Preview for Teams.
189
252
 
190
- Because every setting lives in the config, a run takes no flags so an AI agent can kick it off.
191
- Ask Claude Code for a preview and it runs `npx pr-preview run`; a Chrome window opens, **you click
192
- through the ~30-second journey**, and the agent picks up the finished `before.mp4` / `after.mp4` to
193
- drop into your PR. The agent triggers and finalizes; you demonstrate the journey.
253
+ **Prefer to record by hand?** Manual mode is unchanged: `npx pr-preview run` opens Chrome for you to
254
+ click through yourself. Both modes produce the same clips the only difference is whose hands drive.
194
255
 
195
- ## 🔐 Privacy
256
+ ## Privacy
196
257
 
197
258
  PR Preview runs locally — it opens your app in a Chrome window, records, and writes video files to
198
259
  your project. Nothing is uploaded. The clip is a real screen recording, so avoid typing real
@@ -216,25 +277,25 @@ PR Preview drives a real app inside a controlled browser, so a few things are ou
216
277
 
217
278
  ## Contributing
218
279
 
219
- See [CONTRIBUTING.md](./CONTRIBUTING.md). Issues and PRs welcome — and a helps a lot.
280
+ See [CONTRIBUTING.md](./CONTRIBUTING.md). Issues and PRs welcome — and a star helps a lot.
220
281
 
221
282
  ## License & what's free
222
283
 
223
284
  The **CLI is open source under the [MIT license](./LICENSE)** — free to use, including commercially.
224
285
  This is an open-core project:
225
286
 
226
- - **This CLI** — recording and before/after clip generation. MIT, free forever. Clips carry a
287
+ - **This CLI** — recording and before/after clip generation. MIT, free forever. Clips carry a
227
288
  small `pr-preview.com` watermark.
228
- - 🔒 **PR Preview for Teams** ([pr-preview.com](https://pr-preview.com)) — the hosted service:
289
+ - **PR Preview for Teams** ([pr-preview.com](https://pr-preview.com)) — the hosted service:
229
290
  clip hosting, a synced review player, team reviewers & comments, sharing, and watermark-free
230
291
  clips. A separate, proprietary commercial offering — *coming soon*.
231
- - ™️ The **"PR Preview" name and logo** are trademarks of SC QWERTYBIT SRL; the MIT license covers
292
+ - The **"PR Preview" name and logo** are trademarks of SC QWERTYBIT SRL; the MIT license covers
232
293
  the code, not the brand.
233
294
 
234
295
  ---
235
296
 
236
297
  <p align="center">
237
- <a href="https://pr-preview.com"><strong>🎬 pr-preview.com</strong></a><br/>
298
+ <a href="https://pr-preview.com"><strong>pr-preview.com</strong></a><br/>
238
299
  <sub>See it in action, and <a href="https://pr-preview.com/#teams">join the early-access list for PR&nbsp;Preview for Teams</a> —<br/>
239
300
  hosted clips, team reviews &amp; sharing, coming soon.</sub>
240
301
  </p>
package/assets/demo.gif CHANGED
Binary file
Binary file