@juangadm/pre-post 0.3.0 → 1.0.0
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/README.md +102 -240
- package/dist/bin/cli.js +200 -454
- package/dist/bin/cli.js.map +1 -1
- package/dist/browser.d.ts +42 -27
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +358 -105
- package/dist/browser.js.map +1 -1
- package/dist/capture.d.ts +1 -6
- package/dist/capture.d.ts.map +1 -1
- package/dist/capture.js +12 -36
- package/dist/capture.js.map +1 -1
- package/dist/commands/compare.d.ts +18 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +64 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/detect.d.ts +20 -0
- package/dist/commands/detect.d.ts.map +1 -0
- package/dist/commands/detect.js +19 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +38 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +34 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/pr.d.ts +28 -0
- package/dist/commands/pr.d.ts.map +1 -0
- package/dist/commands/pr.js +159 -0
- package/dist/commands/pr.js.map +1 -0
- package/dist/commands/prune.d.ts +10 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +13 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/config.d.ts +36 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -0
- package/dist/diff-pool.d.ts +17 -0
- package/dist/diff-pool.d.ts.map +1 -0
- package/dist/diff-pool.js +89 -0
- package/dist/diff-pool.js.map +1 -0
- package/dist/diff-worker.d.ts +29 -0
- package/dist/diff-worker.d.ts.map +1 -0
- package/dist/diff-worker.js +38 -0
- package/dist/diff-worker.js.map +1 -0
- package/dist/diff.d.ts +37 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +171 -0
- package/dist/diff.js.map +1 -0
- package/dist/doctor.d.ts +38 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +72 -0
- package/dist/doctor.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/git.d.ts +23 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +86 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +73 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +240 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +22 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -67
- package/dist/index.js.map +1 -1
- package/dist/pkg.d.ts +8 -0
- package/dist/pkg.d.ts.map +1 -0
- package/dist/pkg.js +35 -0
- package/dist/pkg.js.map +1 -0
- package/dist/report.d.ts +20 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +107 -0
- package/dist/report.js.map +1 -0
- package/dist/routes/imports.d.ts +46 -0
- package/dist/routes/imports.d.ts.map +1 -0
- package/dist/routes/imports.js +208 -0
- package/dist/routes/imports.js.map +1 -0
- package/dist/routes/vite.d.ts +15 -0
- package/dist/routes/vite.d.ts.map +1 -0
- package/dist/routes/vite.js +130 -0
- package/dist/routes/vite.js.map +1 -0
- package/dist/routes.d.ts +41 -14
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +271 -141
- package/dist/routes.js.map +1 -1
- package/dist/run.d.ts +36 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +128 -0
- package/dist/run.js.map +1 -0
- package/dist/sessions.d.ts +50 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +74 -0
- package/dist/sessions.js.map +1 -0
- package/dist/types.d.ts +118 -69
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/viewport.d.ts +6 -1
- package/dist/viewport.d.ts.map +1 -1
- package/dist/viewport.js +13 -7
- package/dist/viewport.js.map +1 -1
- package/package.json +21 -14
- package/skill/SKILL.md +31 -229
- package/dist/clipboard.d.ts +0 -9
- package/dist/clipboard.d.ts.map +0 -1
- package/dist/clipboard.js +0 -26
- package/dist/clipboard.js.map +0 -1
- package/dist/upload.d.ts +0 -39
- package/dist/upload.d.ts.map +0 -1
- package/dist/upload.js +0 -159
- package/dist/upload.js.map +0 -1
- package/dist/video.d.ts +0 -19
- package/dist/video.d.ts.map +0 -1
- package/dist/video.js +0 -263
- package/dist/video.js.map +0 -1
- package/skill/scripts/adapters/0x0st.sh +0 -36
- package/skill/scripts/adapters/blob.sh +0 -55
- package/skill/scripts/adapters/git-native.sh +0 -51
- package/skill/scripts/upload-and-copy.sh +0 -230
package/README.md
CHANGED
|
@@ -1,273 +1,135 @@
|
|
|
1
1
|
# pre-post
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
L --> M{Launch Chromium}
|
|
52
|
-
M -->|"PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH"| M1[Custom path — fail hard if invalid]
|
|
53
|
-
M -->|Auto-detect| M2[System Chrome → Bundled → Cached]
|
|
54
|
-
M1 --> P[Navigate + wait for network idle]
|
|
55
|
-
M2 --> P
|
|
56
|
-
|
|
57
|
-
P --> Q[Disable CSS animations]
|
|
58
|
-
Q --> R[Wait for document.fonts.ready]
|
|
59
|
-
R --> S[Take 2x retina screenshot]
|
|
60
|
-
|
|
61
|
-
S --> T[Save to ~/Downloads]
|
|
62
|
-
T --> T1{--markdown?}
|
|
63
|
-
T1 -->|No| U[Done]
|
|
64
|
-
T1 -->|Yes| V{Upload method}
|
|
65
|
-
V -->|Default| W["git-native: commit to .pre-post/"]
|
|
66
|
-
V -->|--upload-url| Y["HTTP: 0x0.st / Vercel Blob / PUT"]
|
|
67
|
-
W --> X[Build blob+SHA URL]
|
|
68
|
-
Y --> X
|
|
69
|
-
X --> Z[Markdown table]
|
|
70
|
-
|
|
71
|
-
Z --> Z1{Skill mode?}
|
|
72
|
-
Z1 -->|Yes| Z2[User approves screenshots]
|
|
73
|
-
Z2 --> Z3["gh pr edit — append to PR body"]
|
|
74
|
-
Z1 -->|No| Z4[Copy to clipboard]
|
|
75
|
-
|
|
76
|
-
style A fill:#4f46e5,color:#fff
|
|
77
|
-
style L fill:#2563eb,color:#fff
|
|
78
|
-
style S fill:#059669,color:#fff
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
## Prerequisites
|
|
82
|
-
|
|
83
|
-
- **Node.js** 18+
|
|
84
|
-
- **Chromium** — install once via Playwright:
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
npx playwright install chromium
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## CI / Sandboxed Environments
|
|
91
|
-
|
|
92
|
-
pre-post needs a Chromium binary. In restricted environments where `npx playwright install chromium` fails (CDN blocked):
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# Point to a pre-installed Chrome/Chromium binary
|
|
96
|
-
export PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/path/to/chrome
|
|
97
|
-
|
|
98
|
-
# This is treated as an explicit override — pre-post will fail with a
|
|
99
|
-
# clear error if the path is wrong, rather than silently falling back.
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
When no custom path is set, pre-post auto-detects in order: system Chrome, bundled Playwright Chromium, then any builds in `~/.cache/ms-playwright/`.
|
|
103
|
-
|
|
104
|
-
If no browser is available at all, use image-only mode:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
pre-post before.png after.png --markdown
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Proxy URLs**: If your git remote uses a proxy (e.g., `http://proxy@host/git/owner/repo`), set the repo explicitly:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
export GH_REPO=owner/repo
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Google Fonts**: Container egress proxies typically block `fonts.googleapis.com`.
|
|
117
|
-
Screenshots will render with system font fallbacks. This is cosmetic only —
|
|
118
|
-
`document.fonts.ready` still resolves and layout is preserved.
|
|
3
|
+
Before/after screenshots for pull requests. One command detects the routes your branch
|
|
4
|
+
changed, captures them on production ("Pre") and on your dev server ("Post"), pixel-diffs
|
|
5
|
+
them, uploads the images to GitHub, and posts a single comment on the PR that a reviewer
|
|
6
|
+
can judge at a glance.
|
|
7
|
+
|
|
8
|
+
> Originally forked from [before-and-after](https://github.com/vercel-labs/before-and-after) by James Clements / Vercel Labs.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
$ npx -y @juangadm/pre-post@latest pr
|
|
12
|
+
|
|
13
|
+
Routes (nextjs-app, 41ms): /, /pricing
|
|
14
|
+
/ medium src/app/page.tsx imports src/components/ui/button.tsx (2 hops)
|
|
15
|
+
/pricing medium src/app/pricing/page.tsx imports src/components/ui/button.tsx (2 hops)
|
|
16
|
+
Capturing 8 screenshots (2 route(s) × 2 viewport(s)) ...
|
|
17
|
+
changed /pricing @ mobile (1.42%, 1811ms)
|
|
18
|
+
changed /pricing @ desktop (0.64%, 2036ms)
|
|
19
|
+
same / @ mobile (0.00%, 1990ms)
|
|
20
|
+
same / @ desktop (0.00%, 2211ms)
|
|
21
|
+
Publishing 10 image(s) to acme/web@pre-post-assets ...
|
|
22
|
+
Updated PR comment: https://github.com/acme/web/pull/42#issuecomment-1
|
|
23
|
+
pre-post · PR #42 · 2 route(s) · 2 viewport(s) · 6.8s
|
|
24
|
+
/ desktop no change
|
|
25
|
+
/ mobile no change
|
|
26
|
+
/pricing desktop 0.64% changed
|
|
27
|
+
/pricing mobile 1.4% changed
|
|
28
|
+
Comment: https://github.com/acme/web/pull/42#issuecomment-1
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## How it works
|
|
32
|
+
|
|
33
|
+
1. **Routes.** Diffs the branch against the merge base with `main`, then follows the import
|
|
34
|
+
graph: a change to `components/ui/button.tsx` marks every page that imports it. Next.js
|
|
35
|
+
App Router and Pages Router, Vite apps (React Router, file-based `src/pages`), and a
|
|
36
|
+
generic fallback. Monorepos are handled by picking the app that owns the changed files.
|
|
37
|
+
2. **Capture.** Playwright + Chromium headless shell. Fixed clock, reduced motion,
|
|
38
|
+
animations finished, caret hidden, fonts and images settled, layout stable across frames,
|
|
39
|
+
lazy content primed. 2x device scale, full page (capped at 2400 CSS px), desktop + mobile.
|
|
40
|
+
All routes and viewports run concurrently.
|
|
41
|
+
3. **Diff.** Pure-JS pixel comparison in worker threads. Reports the percentage changed,
|
|
42
|
+
the bounding box, a red-highlight image, and a tight crop of the changed region.
|
|
43
|
+
4. **Publish.** Images go to a `pre-post-assets` branch in the same repository via the GitHub
|
|
44
|
+
API, as one commit per run. Nothing is committed to the PR branch, no CI is triggered,
|
|
45
|
+
and the blob URLs render on private repos. `pre-post prune` removes images for PRs
|
|
46
|
+
closed more than 90 days ago.
|
|
47
|
+
5. **Comment.** One sticky comment per PR, updated in place on every run. Changed routes show
|
|
48
|
+
a Pre/Post crop with the full page and diff collapsed underneath; unchanged routes fold
|
|
49
|
+
into a single line.
|
|
119
50
|
|
|
120
51
|
## Install
|
|
121
52
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
## Basic Use
|
|
53
|
+
Nothing to install. `npx -y @juangadm/pre-post@latest pr` downloads the CLI and, on first
|
|
54
|
+
use, the Chromium headless shell (~80 MB). You need Node 20+ and a GitHub token: either
|
|
55
|
+
`gh auth login` or `GH_TOKEN`.
|
|
127
56
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
After making visual UI changes, say `/pre-post` or "take pre and post screenshots". Claude will:
|
|
131
|
-
|
|
132
|
-
1. Detect affected routes from your git diff
|
|
133
|
-
2. Propose routes for your approval
|
|
134
|
-
3. Capture desktop + mobile screenshots (production vs localhost)
|
|
135
|
-
4. Show you the screenshots for approval
|
|
136
|
-
5. Upload and append markdown to your PR
|
|
137
|
-
|
|
138
|
-
### From the CLI
|
|
139
|
-
|
|
140
|
-
Capture any two URLs:
|
|
57
|
+
As a Claude Code skill:
|
|
141
58
|
|
|
142
59
|
```bash
|
|
143
|
-
pre-post
|
|
60
|
+
npx skills add juangadm/pre-post -y
|
|
144
61
|
```
|
|
145
62
|
|
|
146
|
-
|
|
63
|
+
Then say `/pre-post` after making UI changes.
|
|
147
64
|
|
|
148
|
-
|
|
149
|
-
pre-post before.png after.png
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## CLI Subcommands
|
|
153
|
-
|
|
154
|
-
### `detect` -- Route Detection
|
|
155
|
-
|
|
156
|
-
Detect affected routes from git changes:
|
|
157
|
-
|
|
158
|
-
```bash
|
|
159
|
-
pre-post detect # Auto-detect framework
|
|
160
|
-
pre-post detect --framework nextjs-app # Force framework
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
Outputs JSON with route paths, confidence levels, and source files.
|
|
164
|
-
|
|
165
|
-
### `compare` -- URL Comparison
|
|
166
|
-
|
|
167
|
-
Compare pre/post states across routes:
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
pre-post compare --before-base https://prod.com --after-base http://localhost:3000
|
|
171
|
-
pre-post compare --before-base URL --after-base URL --routes /dashboard,/settings
|
|
172
|
-
pre-post compare --before-base URL --after-base URL --responsive # Desktop + mobile
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### `run` -- Full Auto
|
|
176
|
-
|
|
177
|
-
Combines `detect` + `compare`:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
pre-post run --before-base https://prod.com --after-base http://localhost:3000
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
## Options
|
|
184
|
-
|
|
185
|
-
Capture a specific element using a CSS selector:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
pre-post url1 url2 ".hero"
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Use different selectors for pre and post:
|
|
65
|
+
## Usage
|
|
192
66
|
|
|
193
67
|
```bash
|
|
194
|
-
pre-post
|
|
195
|
-
|
|
68
|
+
pre-post pr # everything, on the current branch's PR
|
|
69
|
+
pre-post pr --before https://acme.com # first run in a repo (saved to .pre-post.json)
|
|
70
|
+
pre-post pr --routes /pricing,/docs # explicit routes
|
|
71
|
+
pre-post pr --viewports desktop,1440x900 # custom viewports
|
|
72
|
+
pre-post pr --dry-run # capture + diff locally, post nothing
|
|
73
|
+
pre-post pr --json # machine-readable output
|
|
196
74
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
pre-post
|
|
201
|
-
pre-post
|
|
75
|
+
pre-post https://acme.com http://localhost:3000 --routes /pricing # ad-hoc comparison
|
|
76
|
+
pre-post before.png after.png # diff two images
|
|
77
|
+
pre-post detect # which routes does this branch touch?
|
|
78
|
+
pre-post login https://staging.acme.com # sign in once; the session is reused
|
|
79
|
+
pre-post prune --days 90 # clean up the assets branch
|
|
80
|
+
pre-post doctor # browser, token, dev server, config
|
|
202
81
|
```
|
|
203
82
|
|
|
204
|
-
|
|
83
|
+
When something needs a human, the CLI exits with code 3 and one sentence saying what to do
|
|
84
|
+
(log in, start the dev server, pass `--before`). Re-running picks up where it left off.
|
|
205
85
|
|
|
206
|
-
|
|
207
|
-
pre-post url1 url2 --full
|
|
208
|
-
```
|
|
86
|
+
## Configuration
|
|
209
87
|
|
|
210
|
-
|
|
88
|
+
Optional `.pre-post.json` in the repo root:
|
|
211
89
|
|
|
212
|
-
```
|
|
213
|
-
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"before": "https://acme.com",
|
|
93
|
+
"routes": ["/"],
|
|
94
|
+
"samples": { "/blog/[slug]": "/blog/hello-world" },
|
|
95
|
+
"viewports": ["desktop", "mobile"],
|
|
96
|
+
"fullPage": true,
|
|
97
|
+
"maxHeight": 2400,
|
|
98
|
+
"scale": 2,
|
|
99
|
+
"threshold": 0.001,
|
|
100
|
+
"minChangedPixels": 40,
|
|
101
|
+
"maxRoutes": 6,
|
|
102
|
+
"ignore": ["apps/docs"],
|
|
103
|
+
"headers": {},
|
|
104
|
+
"assetsBranch": "pre-post-assets"
|
|
105
|
+
}
|
|
214
106
|
```
|
|
215
107
|
|
|
216
|
-
|
|
108
|
+
Environment:
|
|
217
109
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
110
|
+
| Variable | Purpose |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `GH_TOKEN` / `GITHUB_TOKEN` | GitHub token (default: `gh auth token`) |
|
|
113
|
+
| `VERCEL_AUTOMATION_BYPASS_SECRET` | Bypass Vercel Deployment Protection on the production URL |
|
|
114
|
+
| `PRE_POST_CONCURRENCY` | Parallel pages (default 6) |
|
|
115
|
+
| `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` | Use a specific Chromium binary |
|
|
116
|
+
| `GH_REPO` | `owner/repo` when the remote URL cannot be parsed |
|
|
221
117
|
|
|
222
|
-
|
|
118
|
+
## Library
|
|
223
119
|
|
|
224
|
-
```
|
|
225
|
-
|
|
120
|
+
```ts
|
|
121
|
+
import { runPr, captureScreenshot, diffImages, detectRoutesForRepo } from '@juangadm/pre-post';
|
|
226
122
|
```
|
|
227
123
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
## Route Detection
|
|
231
|
-
|
|
232
|
-
Pre-post automatically maps `git diff --name-only` to affected UI routes:
|
|
233
|
-
|
|
234
|
-
| Changed File | Detected Route | Confidence |
|
|
235
|
-
|---|---|---|
|
|
236
|
-
| `app/page.tsx` | `/` | high |
|
|
237
|
-
| `app/dashboard/page.tsx` | `/dashboard` | high |
|
|
238
|
-
| `app/(marketing)/about/page.tsx` | `/about` (strips route groups) | high |
|
|
239
|
-
| `app/blog/[slug]/page.tsx` | `/blog/[slug]` | high |
|
|
240
|
-
| `app/dashboard/layout.tsx` | `/dashboard` | medium |
|
|
241
|
-
| `app/dashboard/components/Chart.tsx` | `/dashboard` | medium |
|
|
242
|
-
| `globals.css`, `tailwind.config.ts` | `/` | low |
|
|
243
|
-
| `app/api/*`, `middleware.ts` | Skipped (no visual) | -- |
|
|
244
|
-
|
|
245
|
-
Supports:
|
|
246
|
-
- **Next.js App Router** (route groups, dynamic segments, parallel routes, catch-all)
|
|
247
|
-
- **Next.js Pages Router** (`pages/`, `_app.tsx`, `_document.tsx`)
|
|
248
|
-
- **Generic fallback** (defaults to `/`)
|
|
249
|
-
|
|
250
|
-
## Add Skill
|
|
251
|
-
|
|
252
|
-
Install as an agent skill using the [`skills` CLI](https://github.com/vercel-labs/skills):
|
|
124
|
+
## Development
|
|
253
125
|
|
|
254
126
|
```bash
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
127
|
+
pnpm install
|
|
128
|
+
pnpm build
|
|
129
|
+
pnpm test:unit
|
|
130
|
+
TEST_BROWSER=true pnpm test # needs a Chromium; npx playwright-core install chromium-headless-shell
|
|
258
131
|
```
|
|
259
132
|
|
|
260
|
-
This copies `skill/SKILL.md` into the appropriate directory for your agent (e.g., `.claude/skills/` for Claude Code, `.agents/skills/` for Amp/Codex/Gemini CLI, etc.).
|
|
261
|
-
|
|
262
|
-
The skill uses `gh` to detect the associated PR and Playwright for screenshots.
|
|
263
|
-
|
|
264
|
-
> **Note:** The npm package (`@juangadm/pre-post`) is published on [npmjs.com](https://www.npmjs.com/package/@juangadm/pre-post), not GitHub Packages — so the "Packages" section on the GitHub repo page will show none.
|
|
265
|
-
|
|
266
|
-
## Credits
|
|
267
|
-
|
|
268
|
-
- Original [before-and-after](https://github.com/vercel-labs/before-and-after) by [James Clements](https://github.com/jamesclement) at [Vercel Labs](https://github.com/vercel-labs)
|
|
269
|
-
- Browser automation powered by [Playwright](https://playwright.dev/)
|
|
270
|
-
|
|
271
133
|
## License
|
|
272
134
|
|
|
273
135
|
MIT
|