pw-repl 0.11.0 → 0.11.1
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 +1 -1
- package/README.md +14 -5
- package/bin/pw-repl.js +4 -3
- package/lib/help.js +2 -2
- package/lib/runner.js +1 -1
- package/lib/syntax.js +1 -1
- package/lib/watch.js +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +11 -8
package/AGENTS.md
CHANGED
|
@@ -25,7 +25,7 @@ If you hit a limitation or write a workaround, consider adding the capability to
|
|
|
25
25
|
runs commands one at a time (`quit` and `dialog` skip its queue); `lib/server.js` is the command
|
|
26
26
|
server; `lib/send.js` and `lib/client.js` are `send` and `where`; `lib/background.js` is
|
|
27
27
|
`serve --background`, `attach` and `stop`; `lib/launch.js` is `--launch`; `lib/syntax.js` is how a
|
|
28
|
-
command line's words are read, shared with `send
|
|
28
|
+
command line's words are read, shared with `send`, and its `{{ PW_NAME }}` variables; `lib/cli-names.js` maps playwright-cli's command
|
|
29
29
|
names to these; `lib/state.js` holds the session state, with each client's selected tab;
|
|
30
30
|
`lib/output.js` routes all output so the server can return it; `lib/skill.js` stamps the skill
|
|
31
31
|
`pw-repl skill` prints, and gives `where` its hash.
|
package/README.md
CHANGED
|
@@ -179,6 +179,14 @@ Several agents can share one REPL: `pw-repl send -c <name>` (or `PW_CLIENT=<name
|
|
|
179
179
|
selected tab of its own, shown in the pane as `[server:<name>]`. `modes` says which client turned each mode on,
|
|
180
180
|
and `modes off --mine` turns off only the sender's own.
|
|
181
181
|
|
|
182
|
+
A password can be typed as a variable: `PW_PASSWORD=... pw-repl send fill '#password' "{{ PW_PASSWORD }}"`,
|
|
183
|
+
or the same line in a file run with `send --file`, as `watch save` writes it. `send` takes the value of
|
|
184
|
+
`{{ PW_NAME }}` from its own environment and passes it along with the command; the REPL puts it in only as
|
|
185
|
+
it runs the command, so the file, and the command as the pane, the log and the prompt's history show it,
|
|
186
|
+
never hold it. Output that reads it back can: `snapshot`, `html` and `attrs` hide a password field's value,
|
|
187
|
+
but `eval` reading the field, a field a Show password button made plain text (`help snapshot`), or page
|
|
188
|
+
text that repeats it do not. Only `PW_` names are variables (`pw-repl --help` has the rest).
|
|
189
|
+
|
|
182
190
|
### The HTTP protocol
|
|
183
191
|
|
|
184
192
|
With `pw-repl serve`, the server speaks HTTP with JSON, for clients of your own:
|
|
@@ -188,11 +196,12 @@ curl --unix-socket /tmp/playwright-repl.sock -H 'Content-Type: application/json'
|
|
|
188
196
|
-d '{"command": "info"}' http://localhost/run
|
|
189
197
|
```
|
|
190
198
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
199
|
+
The body may also have `"client": "<name>"`, and `"vars": {"PW_NAME": "<value>"}` with the values of the
|
|
200
|
+
`{{ PW_NAME }}` variables in the command, one line each (else 400). It returns `{"status": "ok" | "error", "output": "..."}`, plus
|
|
201
|
+
`"unconfirmed": true` when the command may or may not have done what it was sent to do (it timed out, or
|
|
202
|
+
the REPL quit while it ran and it was not read-only). While the REPL starts, `/run` answers 503 with
|
|
203
|
+
`"starting": true`: retry. `GET /health` says `"status": "starting"` until it serves, then `"ok"`.
|
|
204
|
+
`pw-repl serve <port>` serves TCP on 127.0.0.1 instead; other addresses are refused.
|
|
196
205
|
|
|
197
206
|
## Tests
|
|
198
207
|
|
package/bin/pw-repl.js
CHANGED
|
@@ -45,13 +45,14 @@ folder, as on send's command line, and # comments and blank lines skipped. It st
|
|
|
45
45
|
command that fails, saying its line, with its exit status. -t is each command's own limit. Other
|
|
46
46
|
clients' commands can run between its lines, on their own tabs.
|
|
47
47
|
|
|
48
|
-
A {{ PW_NAME }} in a command, or in a line of the file, is
|
|
49
|
-
|
|
48
|
+
A {{ PW_NAME }} in a command, or in a line of the file, is a variable: send takes its value from its own
|
|
49
|
+
environment (PW_NAME) and passes it along with the command, not in it, e.g. a password kept out of the
|
|
50
|
+
file and out of the command as the REPL logs it. In a file: fill '#password' "{{ PW_PASSWORD }}",
|
|
50
51
|
run with PW_PASSWORD=... pw-repl send --file login.txt; or one command: PW_PASSWORD=... pw-repl send
|
|
51
52
|
fill '#password' "{{ PW_PASSWORD }}". Only names starting PW_ are variables: any other {{ ... }}, as in a
|
|
52
53
|
page's template text, is sent as written. In a file, put it in double quotes: there its value is
|
|
53
54
|
escaped as they read it (in single quotes, which escape nothing, a value with a ' is refused). The REPL
|
|
54
|
-
|
|
55
|
+
puts it in only as it runs the command, and its pane and log show the command as written. A variable that
|
|
55
56
|
is not set stops the command, or the file at that line, before it is sent. --no-vars sends
|
|
56
57
|
{{ PW_NAME }} as it is. Variables need the command server (pw-repl serve), not the tmux pane.
|
|
57
58
|
|
package/lib/help.js
CHANGED
|
@@ -353,8 +353,8 @@ describing it: click, fill, select, check, press, and wait load after a step tha
|
|
|
353
353
|
element is found by its id, data-testid or name, its text, or else its place in the page, which a change
|
|
354
354
|
to the page can break. A select step chooses the option by its value. What was typed into a password
|
|
355
355
|
field (or any field, with --no-values) is a variable named after the field, e.g. fill '#password'
|
|
356
|
-
"{{ PW_PASSWORD }}"
|
|
357
|
-
|
|
356
|
+
"{{ PW_PASSWORD }}": run it with PW_PASSWORD=... pw-repl send --file login.txt, and send passes the
|
|
357
|
+
value along for the REPL to put in, which shows the line as written. A step that cannot be a command (a value with a line break, an element in a frame, or
|
|
358
358
|
one no selector finds alone) stays a comment saying why, and the save says how many there are.
|
|
359
359
|
|
|
360
360
|
Shared: every client sees the same steps, and watch new's place is shared.`,
|
package/lib/runner.js
CHANGED
|
@@ -188,7 +188,7 @@ function enqueue(line) {
|
|
|
188
188
|
// someone watching sees everything an agent does.
|
|
189
189
|
// client names the sender: its commands show as [server:<client>] and use its own selected tab.
|
|
190
190
|
// vars: values for the {{ PW_NAME }} variables in text (from send), filled in to run it; text is shown
|
|
191
|
-
// as written, so a password in one
|
|
191
|
+
// as written, so a password in one is not in the command as the pane, the log and the prompt's history show it.
|
|
192
192
|
function submit(text, client = null, vars = null) {
|
|
193
193
|
let run = text;
|
|
194
194
|
if (vars) {
|
package/lib/syntax.js
CHANGED
|
@@ -70,7 +70,7 @@ function variablesIn(line) {
|
|
|
70
70
|
// values: { NAME: value }. Throws on a variable it has no value for.
|
|
71
71
|
function expandVariables(line, values) {
|
|
72
72
|
const value = name => {
|
|
73
|
-
if (typeof values[name] !== 'string') throw new Error(`{{ ${name} }} has no value: send
|
|
73
|
+
if (typeof values[name] !== 'string') throw new Error(`{{ ${name} }} has no value: send passes it along from ${name} in its environment`);
|
|
74
74
|
return values[name];
|
|
75
75
|
};
|
|
76
76
|
return line.replace(new RegExp(`"(?:[^"\\\\]|\\\\.)*"|'[^']*'|${VARIABLE.source}`, 'g'), (whole, name) => {
|
package/lib/watch.js
CHANGED
|
@@ -553,7 +553,7 @@ function showWatch(watch, all) {
|
|
|
553
553
|
|
|
554
554
|
// watch save: the steps as commands for send --file to run again, a step that cannot be one (a value
|
|
555
555
|
// with a line break, an element in a frame) as a comment saying so. What was typed into a password field,
|
|
556
|
-
// or with --no-values, is a {{ PW_NAME }} variable, named after the field,
|
|
556
|
+
// or with --no-values, is a {{ PW_NAME }} variable, named after the field, set when send --file runs it. A
|
|
557
557
|
// selector is quoted as lib/syntax.js reads one: single quotes, which escape nothing, unless it holds
|
|
558
558
|
// one. A value is always double-quoted, so an empty one, or one that starts with -, stays the value.
|
|
559
559
|
function savedCommands(watch, p) {
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -129,12 +129,15 @@ REPL), or why neither is reachable, without running anything.
|
|
|
129
129
|
`send --file take.txt` runs a file of commands, one per line, as typed at the prompt (no shell quoting;
|
|
130
130
|
files relative to your folder, as on `send`'s command line; `#` comments), and stops at the first that
|
|
131
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
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
repro to run again. A `{{ PW_NAME }}` in a line is a variable, best in double quotes (`fill '#password'
|
|
133
|
+
"{{ PW_PASSWORD }}"`): `send` takes its value from its own environment and passes it along with the
|
|
134
|
+
line, not in it; the REPL puts it in only as it runs the line, and its pane and log show the line as
|
|
135
|
+
written, so neither the file nor the line as logged holds the secret. Only `PW_` names are variables;
|
|
136
|
+
any other `{{ ... }}` (a page's template text) is sent as written. One that is not set stops the file;
|
|
137
|
+
`--no-vars` sends it as written. A single `send` takes them too: `PW_PASSWORD=... pw-repl send fill
|
|
138
|
+
'#password' "{{ PW_PASSWORD }}"` types a password without it in the command. What reads it back can
|
|
139
|
+
still show it: `snapshot`, `html` and `attrs` hide a password field's value, `eval` on the field does
|
|
140
|
+
not.
|
|
138
141
|
|
|
139
142
|
`send` takes one command; chain several in your shell. Use `&&` when a step only makes sense if the one
|
|
140
143
|
before it worked: it stops at any exit status but 0, a failure and an outcome not confirmed included.
|
|
@@ -163,8 +166,8 @@ shown yet. For a tab they have not opened yet, `watch on --next-tab [url-part]`
|
|
|
163
166
|
watches it from its first page. `watch save <file>` writes the steps as commands that `send --file`
|
|
164
167
|
runs again, a repro to keep. What is typed is recorded, except in password fields; `watch on
|
|
165
168
|
--no-values` leaves it out. The file has a `{{ PW_PASSWORD }}` variable where a password was typed,
|
|
166
|
-
|
|
167
|
-
|
|
169
|
+
set when it runs (`PW_PASSWORD=... pw-repl send --file login.txt`), so the file can be shared without
|
|
170
|
+
it.
|
|
168
171
|
|
|
169
172
|
When watching someone:
|
|
170
173
|
|