@qwertybit/pr-preview 0.1.3 → 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 +71 -0
- package/README.md +84 -27
- package/dist/cli/index.js +1029 -131
- package/dist/cli/index.js.map +1 -1
- package/dist/inpage/recorder.global.js +79 -14
- package/package.json +2 -1
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
|
-
##
|
|
41
|
+
## Features
|
|
42
42
|
|
|
43
|
-
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
51
|
+
- **Runs entirely on your machine** — nothing is uploaded. Your source and app data never leave
|
|
52
52
|
your computer.
|
|
53
|
-
-
|
|
54
|
-
-
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
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
|
-
##
|
|
166
|
+
## CLI
|
|
165
167
|
|
|
166
168
|
| Command | What it does |
|
|
167
169
|
| --- | --- |
|
|
168
|
-
| `pr-preview init` | Scaffold `pr-preview.config.js
|
|
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
|
-
##
|
|
191
|
+
## Use it from Claude Code
|
|
189
192
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
-
|
|
283
|
+
- **This CLI** — recording and before/after clip generation. MIT, free forever. Clips carry a
|
|
227
284
|
small `pr-preview.com` watermark.
|
|
228
|
-
-
|
|
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
|
-
-
|
|
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
|
|
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 Preview for Teams</a> —<br/>
|
|
239
296
|
hosted clips, team reviews & sharing, coming soon.</sub>
|
|
240
297
|
</p>
|