@qwertybit/pr-preview 0.1.2 → 0.1.4

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