pw-repl 0.9.0 → 0.11.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/AGENTS.md +2 -1
- package/README.md +23 -16
- package/bin/pw-repl.js +12 -1
- package/lib/background.js +14 -4
- package/lib/cdp.js +6 -0
- package/lib/cli-names.js +1 -1
- package/lib/client.js +3 -2
- package/lib/commands.js +3 -0
- package/lib/cursor.js +36 -50
- package/lib/elements.js +133 -18
- package/lib/emulation.js +13 -1
- package/lib/help.js +108 -29
- package/lib/inspect.js +65 -6
- package/lib/modes.js +11 -2
- package/lib/output.js +1 -1
- package/lib/overlay.js +79 -0
- package/lib/record.js +15 -11
- package/lib/runner.js +16 -9
- package/lib/send.js +27 -4
- package/lib/server.js +12 -4
- package/lib/skill.js +1 -1
- package/lib/start.js +4 -1
- package/lib/syntax.js +30 -1
- package/lib/tabs.js +24 -8
- package/lib/toast.js +166 -0
- package/lib/watch.js +210 -29
- package/package.json +1 -1
- package/skill/SKILL.md +73 -56
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pw-repl
|
|
3
|
-
description: Inspect and drive a Chromium browser, possibly one
|
|
3
|
+
description: Inspect and drive a Chromium browser, possibly one the user is using, through the pw-repl (playwright-repl) REPL - tabs, page snapshots, clicks and typing, the mouse at a point (moves, buttons, wheel), requests and their bodies, console messages, waiting for pages and elements, choosing files, faking, patching or delaying responses, cutting or slowing the network, emulating a phone, dark mode, a locale or a timezone, recording what the user does, and recording a video of a tab, with a pointer and on-screen captions. Use when asked to look at, debug or test something in a web page, in an existing Chromium with remote debugging or in one it starts itself.
|
|
4
4
|
allowed-tools: Bash(pw-repl:*) Bash(npx pw-repl@latest:*)
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,22 +9,26 @@ allowed-tools: Bash(pw-repl:*) Bash(npx pw-repl@latest:*)
|
|
|
9
9
|
<!-- pw-repl skill stamp -->
|
|
10
10
|
|
|
11
11
|
pw-repl (playwright-repl) is a REPL that drives a running Chromium over CDP. The browser may be a
|
|
12
|
-
shared session:
|
|
12
|
+
shared session: the user can have their own tabs open in it and be using it while you work.
|
|
13
13
|
|
|
14
14
|
`pw-repl` below is the command the `pw-repl` npm package installs. Without a global install, use
|
|
15
15
|
`npx pw-repl@latest` in its place, in that same form for every command, so each one runs the same
|
|
16
16
|
version; from a clone, `<clone>/bin/pw-repl.js`.
|
|
17
17
|
|
|
18
|
-
`pw-repl where` also names the skill of the pw-repl you run: `skill: e5f6a7b8 (pw-repl 0.4.3)`.
|
|
19
|
-
|
|
18
|
+
`pw-repl where` also names the skill of the pw-repl you run: `skill: e5f6a7b8 (pw-repl 0.4.3)`. Compare
|
|
19
|
+
its hash (`e5f6a7b8`) with the one at the top of this file. The same hash is the same skill, whatever
|
|
20
|
+
the versions say, since a release that leaves the skill as it was keeps its hash: say nothing. When the
|
|
21
|
+
hashes differ, tell the user once, in these words and in passing, with whatever else you are telling
|
|
22
|
+
them, and carry on with the task:
|
|
20
23
|
|
|
21
|
-
- if this file's pw-repl version is newer than that one, pw-repl is behind:
|
|
22
|
-
|
|
24
|
+
- if this file's pw-repl version is newer than that one, pw-repl is behind: "🔄 pw-repl is older than
|
|
25
|
+
this skill (pw-repl <that version>, skill from <this file's>); `npx pw-repl@latest` or
|
|
23
26
|
`npm install -g pw-repl` updates it."
|
|
24
|
-
- otherwise, the skill is:
|
|
25
|
-
|
|
26
|
-
replaced."
|
|
27
|
-
|
|
27
|
+
- otherwise, the skill is: "🔄 This pw-repl skill is out of date (from pw-repl <this file's version>;
|
|
28
|
+
<that version> has a newer one). If you'd like me to update it, just ask: everything but its Custom
|
|
29
|
+
rules section would be replaced." Update it only when the user asks for that; a yes to something else
|
|
30
|
+
is not one. To update it, save what `pw-repl skill` prints over this file, with this file's Custom
|
|
31
|
+
rules section in place of the new one's.
|
|
28
32
|
|
|
29
33
|
## Arguments
|
|
30
34
|
|
|
@@ -34,11 +38,12 @@ the sections below are how to carry it out. With no args, get a REPL running and
|
|
|
34
38
|
|
|
35
39
|
## Start it
|
|
36
40
|
|
|
37
|
-
`pw-repl where`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
Run `pw-repl where` first, before anything else (with `-e <socket>` for a REPL you were told is on one),
|
|
42
|
+
and check the skill it names against the top of this file. It says whether a REPL is running and how
|
|
43
|
+
`send` reaches it, or that one is still starting (retry shortly; it exits 64 until the REPL serves, as
|
|
44
|
+
when none is running). Right after you start one, for a moment before its process is up, it can still
|
|
45
|
+
say none is there: retry for a few seconds before taking that as a failed start. There are three ways to
|
|
46
|
+
run one; each takes an optional start URL, which opens in a new tab.
|
|
42
47
|
|
|
43
48
|
- `pw-repl serve --background` runs it detached, with a command server on `/tmp/playwright-repl.sock`
|
|
44
49
|
(owner-only) and its output in `/tmp/playwright-repl.log`. `pw-repl attach` shows everything it does
|
|
@@ -47,12 +52,12 @@ opens in a new tab.
|
|
|
47
52
|
- `pw-repl serve` runs the same in a terminal, where the pane shows every command. Its prompt is
|
|
48
53
|
`pw[serve]>`. It stops at that prompt (`quit`, or Ctrl-C); `pw-repl stop` is for a background one.
|
|
49
54
|
- Add `--launch` to `run` or `serve` (with or without `--background`) to have it start a Chromium of its
|
|
50
|
-
own instead of connecting to one: headless unless `--headed`, in a temporary profile, on a free port
|
|
51
|
-
its own (never 9222). It stops with the REPL, Ctrl-C while it starts included, and `stop` returns
|
|
52
|
-
it has exited. It prints the command it ran; flags after `--` are passed to that Chromium, and a
|
|
53
|
-
`--user-data-dir=<dir>` among them is used instead of the temporary profile, and kept. Started again
|
|
54
|
-
a kept profile, Chromium picks up where it left off, as it would for
|
|
55
|
-
come back, and session cookies with them, so a login stays. They start loading before the REPL is
|
|
55
|
+
own instead of connecting to one: headless unless `--headed`, in a temporary profile, on a free port
|
|
56
|
+
of its own (never 9222). It stops with the REPL, Ctrl-C while it starts included, and `stop` returns
|
|
57
|
+
once it has exited. It prints the command it ran; flags after `--` are passed to that Chromium, and a
|
|
58
|
+
`--user-data-dir=<dir>` among them is used instead of the temporary profile, and kept. Started again
|
|
59
|
+
in a kept profile, Chromium picks up where it left off, as it would for the user, headless too: its
|
|
60
|
+
tabs come back, and session cookies with them, so a login stays. They start loading before the REPL is
|
|
56
61
|
attached, so `requests` and `console` have only what came after, often nothing: `reload` for a full
|
|
57
62
|
record.
|
|
58
63
|
- `pw-repl run` runs it in a terminal with no server; `send` then reaches it through tmux, if it runs in
|
|
@@ -71,14 +76,15 @@ pw-repl send -e /tmp/mine.sock tab new http://localhost:3000
|
|
|
71
76
|
pw-repl stop -e /tmp/mine.sock
|
|
72
77
|
```
|
|
73
78
|
|
|
74
|
-
A socket file left by a REPL that died is replaced when the next one starts there. The log of a
|
|
75
|
-
(`/tmp/mine.log`), appended to run after run, with a line where
|
|
76
|
-
start moves it to `/tmp/mine.log.1`); `tail -f` on it follows along
|
|
77
|
-
`serve <port>` listens on TCP 127.0.0.1 instead of a socket, with no
|
|
79
|
+
A socket file left by a REPL that died is replaced when the next one starts there. The log of a
|
|
80
|
+
background REPL is next to its socket (`/tmp/mine.log`), appended to run after run, with a line where
|
|
81
|
+
each starts and stops (past 5 MB, a start moves it to `/tmp/mine.log.1`); `tail -f` on it follows along
|
|
82
|
+
without a terminal to attach from. `serve <port>` listens on TCP 127.0.0.1 instead of a socket, with no
|
|
83
|
+
access control.
|
|
78
84
|
|
|
79
85
|
### One REPL, many clients
|
|
80
86
|
|
|
81
|
-
One REPL serves everyone using its browser: the
|
|
87
|
+
One REPL serves everyone using its browser: the user at its prompt and any number of agents. When
|
|
82
88
|
`pw-repl where` finds one running for the browser you need, use it rather than start another, as a
|
|
83
89
|
client of your own: `PW_CLIENT=<name>` (or `send -c <name>`), with a name that says who you are.
|
|
84
90
|
|
|
@@ -104,9 +110,10 @@ pw-repl send -t 90 'screenshot -d 60' # wait longer than the 20s default
|
|
|
104
110
|
Always send commands with `pw-repl send`; don't type into the pane yourself, except `quit` at the prompt
|
|
105
111
|
of a REPL of your own, which `send` refuses. The words after `send` are the command. For `fill`, `type`,
|
|
106
112
|
`select`, `press` and `upload`, a word quoted in your shell stays one word
|
|
107
|
-
(`pw-repl send fill "text=Your name" Ada`); other commands get the words as they are, joined by
|
|
108
|
-
(`pw-repl send eval "document.title + ' x'"`). A command that takes only a selector takes the
|
|
109
|
-
spaces and all: `pw-repl send click "text=Your name"`. It works however the REPL was
|
|
113
|
+
(`pw-repl send fill "text=Your name" Ada`); other commands get the words as they are, joined by
|
|
114
|
+
spaces (`pw-repl send eval "document.title + ' x'"`). A command that takes only a selector takes the
|
|
115
|
+
whole line, spaces and all: `pw-repl send click "text=Your name"`. It works however the REPL was
|
|
116
|
+
started:
|
|
110
117
|
|
|
111
118
|
- `run` (in tmux): `send` types the command into the tmux pane and reads the result back off the screen.
|
|
112
119
|
It types only when the pane's last line is a bare prompt, so nothing lands in a shell or in the middle
|
|
@@ -120,8 +127,14 @@ spaces and all: `pw-repl send click "text=Your name"`. It works however the REPL
|
|
|
120
127
|
REPL), or why neither is reachable, without running anything.
|
|
121
128
|
|
|
122
129
|
`send --file take.txt` runs a file of commands, one per line, as typed at the prompt (no shell quoting;
|
|
123
|
-
files relative to your folder, as on `send`'s command line; `#` comments), and stops at the first that
|
|
124
|
-
It is the way to record a video without gaps (`help record`), and to keep a
|
|
130
|
+
files relative to your folder, as on `send`'s command line; `#` comments), and stops at the first that
|
|
131
|
+
fails, saying which line. It is the way to record a video without gaps (`help record`), and to keep a
|
|
132
|
+
repro to run again. A `{{ PW_NAME }}` in a line is the variable PW_NAME from `send`'s environment, best
|
|
133
|
+
in double quotes (`fill '#password' "{{ PW_PASSWORD }}"`): the REPL fills it in as it runs the line, and
|
|
134
|
+
its pane and log show the line as written, so a secret stays out of both the file and the log. Only
|
|
135
|
+
`PW_` names are variables; any other `{{ ... }}` (a page's template text) is sent as written. One that
|
|
136
|
+
is not set stops the file; `--no-vars` sends it as written. A single `send` takes them too: to type a
|
|
137
|
+
password, `PW_PASSWORD=... pw-repl send fill '#password' "{{ PW_PASSWORD }}"` keeps it out of the log.
|
|
125
138
|
|
|
126
139
|
`send` takes one command; chain several in your shell. Use `&&` when a step only makes sense if the one
|
|
127
140
|
before it worked: it stops at any exit status but 0, a failure and an outcome not confirmed included.
|
|
@@ -143,11 +156,15 @@ Every command you run and its output show in the REPL's pane, or in `attach` and
|
|
|
143
156
|
background REPL (server commands as `[server]` lines), so whoever looks there sees what you do. The pane
|
|
144
157
|
shows REPL commands only, not what was clicked in the browser (unless `watch on --live` is on); for
|
|
145
158
|
that, look at the browser itself: `tab` and `info` for where things are, `requests` for the requests the
|
|
146
|
-
clicks made (`body <#>` for what one returned), `console` for console messages and page errors.
|
|
147
|
-
on` records each step someone takes in a tab, with the requests it caused (`watch on --changes`
|
|
148
|
-
what each step changed on the page); `watch` reads it back, and `watch new` only what it has not
|
|
149
|
-
yet. For a tab they have not opened yet, `watch on --next-tab [url-part]` waits for it and
|
|
150
|
-
from its first page.
|
|
159
|
+
clicks made (`body <#>` for what one returned), `console` for console messages and page errors.
|
|
160
|
+
`watch on` records each step someone takes in a tab, with the requests it caused (`watch on --changes`
|
|
161
|
+
adds what each step changed on the page); `watch` reads it back, and `watch new` only what it has not
|
|
162
|
+
shown yet. For a tab they have not opened yet, `watch on --next-tab [url-part]` waits for it and
|
|
163
|
+
watches it from its first page. `watch save <file>` writes the steps as commands that `send --file`
|
|
164
|
+
runs again, a repro to keep. What is typed is recorded, except in password fields; `watch on
|
|
165
|
+
--no-values` leaves it out. The file has a `{{ PW_PASSWORD }}` variable where a password was typed,
|
|
166
|
+
which `send --file` fills in from its environment (`PW_PASSWORD=... pw-repl send --file login.txt`), so
|
|
167
|
+
the file can be shared without it.
|
|
151
168
|
|
|
152
169
|
When watching someone:
|
|
153
170
|
|
|
@@ -182,7 +199,7 @@ task (`cart-bug`), since two agents with one name are one client:
|
|
|
182
199
|
pw-repl send -c <name> open http://localhost:3000 # a tab of your own in the shared browser
|
|
183
200
|
pw-repl send -c <name> snapshot # no snapshot after each command; ask for one
|
|
184
201
|
pw-repl send -c <name> click e5
|
|
185
|
-
pw-repl send -c <name> close # your modes off; tab close <url-part> closes
|
|
202
|
+
pw-repl send -c <name> close # your modes off; tab close <url-part> closes yours
|
|
186
203
|
```
|
|
187
204
|
|
|
188
205
|
- There is no browser of your own to open or close: `open` opens a tab in the one the REPL uses, and
|
|
@@ -196,27 +213,27 @@ pw-repl send -c <name> close # your modes off; tab close
|
|
|
196
213
|
## Sharing the browser
|
|
197
214
|
|
|
198
215
|
- The browser may have tabs that are not yours, and someone may be using it. Whether to read or act in
|
|
199
|
-
one of those tabs, or to open your own (`tab new <url>`), depends on the task; when that is not
|
|
200
|
-
|
|
216
|
+
one of those tabs, or to open your own (`tab new <url>`), depends on the task; when that is not clear,
|
|
217
|
+
ask. `tab` marks `(in front)` the tab the user sees: "this page" is usually that one. A tab you have
|
|
218
|
+
selected is never marked (help tab says why).
|
|
201
219
|
- No tab is selected when the REPL starts. A start URL's tab, marked `(the start URL)` in `tab`, is
|
|
202
220
|
selected at its prompt and for `send` without a client name; a named client (`-c`) selects it with
|
|
203
221
|
`tab <index>`. Closing a tab the REPL opened goes back to the tab before it, if the REPL opened that
|
|
204
|
-
one too; otherwise no tab is selected.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
the commands that read it wait. One answered in the browser is gone from `dialog` too.
|
|
222
|
+
one too; otherwise no tab is selected. Tab numbers change when tabs open or close; `tab <url-part>`
|
|
223
|
+
and `tab close <url-part>` pick a tab by its URL and refuse if it is ambiguous.
|
|
224
|
+
- You can answer any dialog yourself, one you opened included: `dialog` shows it, and `dialog accept` or
|
|
225
|
+
`dialog dismiss` answers it. Nothing answers one on its own, and while one is open its page and the
|
|
226
|
+
commands that read it wait. One answered in the browser is gone from `dialog` too.
|
|
210
227
|
- Modes and tabs stay on or open until they are turned off or closed, whoever started them. `modes`
|
|
211
228
|
lists what is on in every tab (the prompt shows the selected tab's, e.g. `(watch routes:1) pw>`);
|
|
212
229
|
`modes off` turns off every mode in every tab.
|
|
213
230
|
- Someone may be attached to the REPL's tmux session; killing the session ends it for them too.
|
|
214
|
-
- To point something out, to the
|
|
215
|
-
without changing the page (`--style=<css>` restyles it; `highlight off` hides them)
|
|
216
|
-
|
|
231
|
+
- To point something out, to the user or in a screenshot, `highlight <ref|selector>` draws a box over it
|
|
232
|
+
without changing the page (`--style=<css>` restyles it; `highlight off` hides them), without
|
|
233
|
+
Playwright's locator label unless `highlight --labels on`.
|
|
217
234
|
- For a video, `help video` says how: a take written as a file and sent with `send --file`, `record on`
|
|
218
|
-
around it, `cursor on` for a pointer,
|
|
219
|
-
the user's machine records what they see.
|
|
235
|
+
around it, `cursor on` for a pointer, `toast` to say what is happening, and the pacing recording adds
|
|
236
|
+
for the viewer; a screen recorder on the user's machine records what they see.
|
|
220
237
|
|
|
221
238
|
## Environment
|
|
222
239
|
|
|
@@ -225,13 +242,13 @@ pw-repl send -c <name> close # your modes off; tab close
|
|
|
225
242
|
- `PW_CHROME` — the Chromium `--launch` starts (default: Playwright's own, then one on the `PATH`).
|
|
226
243
|
- `PW_FFMPEG` — the ffmpeg `record` uses, and no other, read by the REPL, not by `send` (default:
|
|
227
244
|
Playwright's own, then one on the `PATH`).
|
|
228
|
-
- Playwright's own Chromium and ffmpeg are found where Playwright installs them:
|
|
229
|
-
or `~/.cache/ms-playwright`.
|
|
245
|
+
- Playwright's own Chromium and ffmpeg are found where Playwright installs them:
|
|
246
|
+
`PLAYWRIGHT_BROWSERS_PATH`, or `~/.cache/ms-playwright`.
|
|
230
247
|
- `PW_CDP_URL` — CDP endpoint (default `http://localhost:9222`).
|
|
231
|
-
- `PW_SCREENSHOT_DIR` — where the REPL saves screenshots, read when it starts, not by `send`. Without
|
|
232
|
-
a REPL on a socket of its own saves them next to its socket, and any other in `/tmp`. `screenshot`
|
|
233
|
-
prints each file's path; other REPLs may save theirs in the same place. Remove only your
|
|
234
|
-
|
|
248
|
+
- `PW_SCREENSHOT_DIR` — where the REPL saves screenshots, read when it starts, not by `send`. Without
|
|
249
|
+
it, a REPL on a socket of its own saves them next to its socket, and any other in `/tmp`. `screenshot`
|
|
250
|
+
prints each file's path; other REPLs may save theirs in the same place. Remove only your own, and keep
|
|
251
|
+
those too if they are needed, e.g. as evidence or as something to hand over.
|
|
235
252
|
- `PW_ENDPOINT` / `PW_TMUX_SESSION` — defaults for `send -e` / `-s`. `PW_SOCKET` — the socket `serve`
|
|
236
253
|
serves on and `send` looks for when neither is given (default `/tmp/playwright-repl.sock`).
|
|
237
254
|
|