patchright-cli 0.9.0__tar.gz → 0.9.1__tar.gz
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.
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.claude-plugin/marketplace.json +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.github/workflows/ci.yml +15 -5
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.github/workflows/publish-docker.yml +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.github/workflows/publish.yml +8 -8
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/Dockerfile +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/PKG-INFO +33 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/README.md +32 -0
- patchright_cli-0.9.1/docs/daemon-protocol.md +102 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/pyproject.toml +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/SKILL.md +34 -2
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/__init__.py +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/cli.py +45 -2
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/daemon.py +109 -3
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/mcp_server.py +78 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/ref_registry.py +35 -12
- patchright_cli-0.9.1/tests/test_daemon_info.py +53 -0
- patchright_cli-0.9.1/tests/test_daemon_read.py +118 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_daemon_token.py +22 -0
- patchright_cli-0.9.1/tests/test_docker.py +112 -0
- patchright_cli-0.9.1/tests/test_emulation.py +203 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_mcp.py +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_ref_registry.py +87 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/uv.lock +1 -1
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.claude-plugin/skills/browser-automation.json +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.github/dependabot.yml +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.gitignore +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/.pre-commit-config.yaml +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/CLAUDE.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/CONTRIBUTING.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/GLOSSARY.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/LICENSE +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/Makefile +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/compose.yml +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/docs/installation.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/docs/mcp-architecture.svg +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/patchright-cli +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/patchright-cli.cmd +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/request-mocking.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/running-code.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/session-management.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/snapshot-refs.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/storage-state.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/tracing.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/skills/patchright-cli/references/video-recording.md +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/__main__.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/dashboard.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/src/patchright_cli/snapshot.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/__init__.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/fixture.html +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_annotate.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_attach.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_cli_config.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_daemon_handlers.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_e2e.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_navigation_policy.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_network_guard.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_packaging.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_profiles.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_supply_chain.py +0 -0
- {patchright_cli-0.9.0 → patchright_cli-0.9.1}/tests/test_tabs.py +0 -0
|
@@ -10,8 +10,8 @@ jobs:
|
|
|
10
10
|
lint:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
14
|
-
- uses: astral-sh/setup-uv@
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
|
+
- uses: astral-sh/setup-uv@v7
|
|
15
15
|
with:
|
|
16
16
|
version: ">=0.7,<0.8"
|
|
17
17
|
python-version: "3.12"
|
|
@@ -28,8 +28,8 @@ jobs:
|
|
|
28
28
|
python-version: "3.12"
|
|
29
29
|
runs-on: ${{ matrix.os }}
|
|
30
30
|
steps:
|
|
31
|
-
- uses: actions/checkout@
|
|
32
|
-
- uses: astral-sh/setup-uv@
|
|
31
|
+
- uses: actions/checkout@v7
|
|
32
|
+
- uses: astral-sh/setup-uv@v7
|
|
33
33
|
with:
|
|
34
34
|
version: ">=0.7,<0.8"
|
|
35
35
|
python-version: ${{ matrix.python-version }}
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
docker:
|
|
40
40
|
runs-on: ubuntu-latest
|
|
41
41
|
steps:
|
|
42
|
-
- uses: actions/checkout@
|
|
42
|
+
- uses: actions/checkout@v7
|
|
43
43
|
- run: docker build -t patchright-cli:ci .
|
|
44
44
|
- run: docker run --rm patchright-cli:ci --help
|
|
45
45
|
- name: Browser session inside the container
|
|
@@ -78,6 +78,16 @@ jobs:
|
|
|
78
78
|
grep -q "refusing to start \`mcp --http\`" unprotected.log
|
|
79
79
|
- name: compose.yml works without a token
|
|
80
80
|
run: docker compose config -q
|
|
81
|
+
- uses: astral-sh/setup-uv@v7
|
|
82
|
+
with:
|
|
83
|
+
version: ">=0.7,<0.8"
|
|
84
|
+
python-version: "3.12"
|
|
85
|
+
- name: Image test suite
|
|
86
|
+
run: |
|
|
87
|
+
uv venv && uv pip install -e ".[dev]"
|
|
88
|
+
uv run pytest tests/test_docker.py -v
|
|
89
|
+
env:
|
|
90
|
+
PATCHRIGHT_CLI_DOCKER_IMAGE: patchright-cli:ci
|
|
81
91
|
- if: failure()
|
|
82
92
|
run: |
|
|
83
93
|
docker logs cli || true
|
|
@@ -15,10 +15,10 @@ jobs:
|
|
|
15
15
|
build:
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
19
|
|
|
20
20
|
- name: Install uv
|
|
21
|
-
uses: astral-sh/setup-uv@
|
|
21
|
+
uses: astral-sh/setup-uv@v7
|
|
22
22
|
|
|
23
23
|
- name: Set up Python
|
|
24
24
|
run: uv python install 3.12
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
run: uv build
|
|
28
28
|
|
|
29
29
|
- name: Upload artifacts
|
|
30
|
-
uses: actions/upload-artifact@
|
|
30
|
+
uses: actions/upload-artifact@v7
|
|
31
31
|
with:
|
|
32
32
|
name: dist
|
|
33
33
|
path: dist/
|
|
@@ -40,13 +40,13 @@ jobs:
|
|
|
40
40
|
id-token: write
|
|
41
41
|
steps:
|
|
42
42
|
- name: Download artifacts
|
|
43
|
-
uses: actions/download-artifact@
|
|
43
|
+
uses: actions/download-artifact@v8
|
|
44
44
|
with:
|
|
45
45
|
name: dist
|
|
46
46
|
path: dist/
|
|
47
47
|
|
|
48
48
|
- name: Install uv
|
|
49
|
-
uses: astral-sh/setup-uv@
|
|
49
|
+
uses: astral-sh/setup-uv@v7
|
|
50
50
|
|
|
51
51
|
- name: Publish to PyPI
|
|
52
52
|
run: uv publish
|
|
@@ -59,16 +59,16 @@ jobs:
|
|
|
59
59
|
permissions:
|
|
60
60
|
contents: write
|
|
61
61
|
steps:
|
|
62
|
-
- uses: actions/checkout@
|
|
62
|
+
- uses: actions/checkout@v7
|
|
63
63
|
|
|
64
64
|
- name: Download artifacts
|
|
65
|
-
uses: actions/download-artifact@
|
|
65
|
+
uses: actions/download-artifact@v8
|
|
66
66
|
with:
|
|
67
67
|
name: dist
|
|
68
68
|
path: dist/
|
|
69
69
|
|
|
70
70
|
- name: Create GitHub Release
|
|
71
|
-
uses: softprops/action-gh-release@
|
|
71
|
+
uses: softprops/action-gh-release@v3
|
|
72
72
|
with:
|
|
73
73
|
files: dist/*
|
|
74
74
|
generate_release_notes: true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Base images are pinned by multi-arch index digest; Dependabot (.github/dependabot.yml) bumps them.
|
|
2
2
|
# uv is a named stage because Dependabot only reads image references on FROM lines.
|
|
3
|
-
FROM ghcr.io/astral-sh/uv:latest@sha256:
|
|
3
|
+
FROM ghcr.io/astral-sh/uv:latest@sha256:af22a52f5eafef3d78e551599d405c02df61919d18028f0cea8eda93bc9986d0 AS uv
|
|
4
4
|
|
|
5
5
|
FROM python:3.12-slim@sha256:5b8b1421ccb6a525860a77863c049eab5847076cda34e030c75a80c58faf3f3c
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: patchright-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Anti-detect browser automation CLI using Patchright (undetected Playwright fork)
|
|
5
5
|
Project-URL: Homepage, https://github.com/AhaiMk01/patchright-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/AhaiMk01/patchright-cli
|
|
@@ -211,6 +211,16 @@ patchright-cli screenshot
|
|
|
211
211
|
patchright-cli close
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
+
Quote URLs that contain `&`; unquoted, bash, PowerShell and cmd.exe all split the command there. On Windows two cases need more than quotes: in cmd.exe without quotes, escape it as `^&` (inside quotes the `^` stays in the URL, so use one or the other), and when PowerShell runs a `.cmd`/`.bat` wrapper such as the repo's `patchright-cli.cmd`, PowerShell drops the quotes and cmd.exe splits at `&`, so pass the rest verbatim with `--%`:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
patchright-cli goto "https://example.com/?a=1&b=2" # any shell, patchright-cli.exe
|
|
218
|
+
patchright-cli goto https://example.com/?a=1^&b=2 # cmd.exe, unquoted
|
|
219
|
+
.\patchright-cli.cmd --% goto "https://example.com/?a=1&b=2" # PowerShell, .cmd wrapper
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Don't use `--%` with the installed `patchright-cli.exe`: in PowerShell 7 the quotes after it reach the CLI and end up in the URL.
|
|
223
|
+
|
|
214
224
|
---
|
|
215
225
|
|
|
216
226
|
## Architecture
|
|
@@ -236,6 +246,12 @@ The daemon only listens on `127.0.0.1`, but any local process can reach that por
|
|
|
236
246
|
- Run the CLI as the same user, with the same home directory, as the daemon. In Docker the MCP server and daemon share a user and `HOME`, so this holds.
|
|
237
247
|
- An older CLI talking to a newer daemon gets an error saying the daemon requires an auth token: upgrade, or stop the daemon (`patchright-cli kill-all` from the newer install, or end the process). A newer CLI talking to an older daemon finds no token file and sends none, which the older daemon accepts.
|
|
238
248
|
|
|
249
|
+
### Daemon client protocol
|
|
250
|
+
|
|
251
|
+
Third-party clients can use the daemon TCP interface directly. The
|
|
252
|
+
[client protocol reference](docs/daemon-protocol.md) defines discovery,
|
|
253
|
+
authentication, message framing, replies, and compatibility rules.
|
|
254
|
+
|
|
239
255
|
---
|
|
240
256
|
|
|
241
257
|
<details>
|
|
@@ -322,6 +338,22 @@ patchright-cli upload ./file.pdf e5 # Upload to specific input
|
|
|
322
338
|
patchright-cli resize 1920 1080 # Resize viewport
|
|
323
339
|
```
|
|
324
340
|
|
|
341
|
+
### Emulation
|
|
342
|
+
```bash
|
|
343
|
+
patchright-cli set-color-scheme dark # dark | light | no-preference
|
|
344
|
+
patchright-cli clear-color-scheme
|
|
345
|
+
patchright-cli set-reduced-motion reduce # reduce | no-preference
|
|
346
|
+
patchright-cli clear-reduced-motion
|
|
347
|
+
patchright-cli set-forced-colors active # active | none
|
|
348
|
+
patchright-cli clear-forced-colors
|
|
349
|
+
patchright-cli set-contrast more # more | no-preference
|
|
350
|
+
patchright-cli clear-contrast
|
|
351
|
+
patchright-cli set-media print # screen | print
|
|
352
|
+
patchright-cli clear-media
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Each setting holds for the whole session, including tabs and popups opened later; `clear-*` drops just that one, back to the browser default. A popup gets the setting just after it opens, so a script that reads media queries the instant the popup is created may still see the default.
|
|
356
|
+
|
|
325
357
|
### Tabs
|
|
326
358
|
```bash
|
|
327
359
|
patchright-cli tab-list
|
|
@@ -174,6 +174,16 @@ patchright-cli screenshot
|
|
|
174
174
|
patchright-cli close
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
+
Quote URLs that contain `&`; unquoted, bash, PowerShell and cmd.exe all split the command there. On Windows two cases need more than quotes: in cmd.exe without quotes, escape it as `^&` (inside quotes the `^` stays in the URL, so use one or the other), and when PowerShell runs a `.cmd`/`.bat` wrapper such as the repo's `patchright-cli.cmd`, PowerShell drops the quotes and cmd.exe splits at `&`, so pass the rest verbatim with `--%`:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
patchright-cli goto "https://example.com/?a=1&b=2" # any shell, patchright-cli.exe
|
|
181
|
+
patchright-cli goto https://example.com/?a=1^&b=2 # cmd.exe, unquoted
|
|
182
|
+
.\patchright-cli.cmd --% goto "https://example.com/?a=1&b=2" # PowerShell, .cmd wrapper
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Don't use `--%` with the installed `patchright-cli.exe`: in PowerShell 7 the quotes after it reach the CLI and end up in the URL.
|
|
186
|
+
|
|
177
187
|
---
|
|
178
188
|
|
|
179
189
|
## Architecture
|
|
@@ -199,6 +209,12 @@ The daemon only listens on `127.0.0.1`, but any local process can reach that por
|
|
|
199
209
|
- Run the CLI as the same user, with the same home directory, as the daemon. In Docker the MCP server and daemon share a user and `HOME`, so this holds.
|
|
200
210
|
- An older CLI talking to a newer daemon gets an error saying the daemon requires an auth token: upgrade, or stop the daemon (`patchright-cli kill-all` from the newer install, or end the process). A newer CLI talking to an older daemon finds no token file and sends none, which the older daemon accepts.
|
|
201
211
|
|
|
212
|
+
### Daemon client protocol
|
|
213
|
+
|
|
214
|
+
Third-party clients can use the daemon TCP interface directly. The
|
|
215
|
+
[client protocol reference](docs/daemon-protocol.md) defines discovery,
|
|
216
|
+
authentication, message framing, replies, and compatibility rules.
|
|
217
|
+
|
|
202
218
|
---
|
|
203
219
|
|
|
204
220
|
<details>
|
|
@@ -285,6 +301,22 @@ patchright-cli upload ./file.pdf e5 # Upload to specific input
|
|
|
285
301
|
patchright-cli resize 1920 1080 # Resize viewport
|
|
286
302
|
```
|
|
287
303
|
|
|
304
|
+
### Emulation
|
|
305
|
+
```bash
|
|
306
|
+
patchright-cli set-color-scheme dark # dark | light | no-preference
|
|
307
|
+
patchright-cli clear-color-scheme
|
|
308
|
+
patchright-cli set-reduced-motion reduce # reduce | no-preference
|
|
309
|
+
patchright-cli clear-reduced-motion
|
|
310
|
+
patchright-cli set-forced-colors active # active | none
|
|
311
|
+
patchright-cli clear-forced-colors
|
|
312
|
+
patchright-cli set-contrast more # more | no-preference
|
|
313
|
+
patchright-cli clear-contrast
|
|
314
|
+
patchright-cli set-media print # screen | print
|
|
315
|
+
patchright-cli clear-media
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Each setting holds for the whole session, including tabs and popups opened later; `clear-*` drops just that one, back to the browser default. A popup gets the setting just after it opens, so a script that reads media queries the instant the popup is created may still see the default.
|
|
319
|
+
|
|
288
320
|
### Tabs
|
|
289
321
|
```bash
|
|
290
322
|
patchright-cli tab-list
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Daemon client protocol
|
|
2
|
+
|
|
3
|
+
The TCP interface is a public interface for third-party clients. The current
|
|
4
|
+
protocol version is **1**, defined by `PROTOCOL_VERSION` in `daemon.py`.
|
|
5
|
+
|
|
6
|
+
## Discovery
|
|
7
|
+
|
|
8
|
+
`patchright-cli daemon-info --json` prints one JSON object and exits without
|
|
9
|
+
starting a daemon or browser, connecting to the daemon, or reading the token.
|
|
10
|
+
For example, on a Unix installation with home directory `/home/alice`:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{"version": "0.9.0", "protocol": 1, "port": 9321, "token_path": "/home/alice/.patchright-cli/daemon-9321.token"}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`version` is the installed package version. `protocol` describes that installed
|
|
17
|
+
version's wire contract, not a handshake with a running daemon. After upgrading,
|
|
18
|
+
restart any older daemon before using the new contract.
|
|
19
|
+
|
|
20
|
+
`--port=N` and `--port N`, before or after the command, select the port and its
|
|
21
|
+
token path. The default port is 9321. There is currently no port or token-path
|
|
22
|
+
environment override. `token_path` is absolute and follows the current user's
|
|
23
|
+
home directory. The file need not exist for discovery to succeed. Discovery
|
|
24
|
+
reports configuration, not daemon readiness, and never prints the token value.
|
|
25
|
+
Older installations without this command do not advertise a protocol version.
|
|
26
|
+
|
|
27
|
+
## Transport and authentication
|
|
28
|
+
|
|
29
|
+
Connect to `127.0.0.1` on the discovered port. Each connection carries one
|
|
30
|
+
request and one reply, after which the daemon closes the connection. Both
|
|
31
|
+
messages use the same framing:
|
|
32
|
+
|
|
33
|
+
1. Four bytes containing the unsigned payload byte length in big-endian order
|
|
34
|
+
(`struct.pack("!I", length)`).
|
|
35
|
+
2. That many bytes of UTF-8 encoded JSON, with an object as the top-level value.
|
|
36
|
+
|
|
37
|
+
Reads must loop until the entire header and payload arrive. There is no newline
|
|
38
|
+
or other delimiter. An incomplete request can close without a reply.
|
|
39
|
+
|
|
40
|
+
The daemon reads a request before checking its token, so it bounds that read:
|
|
41
|
+
|
|
42
|
+
- The whole request must arrive within 30 seconds of connecting, or the daemon
|
|
43
|
+
closes the connection without a reply. Commands themselves and replies have
|
|
44
|
+
no time limit.
|
|
45
|
+
- A request whose header announces more than 64 MiB (67,108,864 bytes) gets a
|
|
46
|
+
`success: false` reply whose `output` starts with `Daemon error: request of`,
|
|
47
|
+
sent without reading the body, and the connection closes.
|
|
48
|
+
|
|
49
|
+
The daemon writes a new secret to `~/.patchright-cli/daemon-<port>.token` when
|
|
50
|
+
it starts and removes its token on clean shutdown. Read the discovered
|
|
51
|
+
`token_path` as UTF-8 text and strip surrounding whitespace before each request.
|
|
52
|
+
The token may change when the daemon restarts. Send it in the request's `token`
|
|
53
|
+
field. Keep the value private. The client must run as a user who can read this
|
|
54
|
+
file. A missing file can indicate that the daemon has not started or has stopped.
|
|
55
|
+
|
|
56
|
+
## Request fields
|
|
57
|
+
|
|
58
|
+
| Field | JSON type | Meaning |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `command` | string | Command name, such as `list`, `open`, or `snapshot`. |
|
|
61
|
+
| `args` | array of strings | Positional command arguments. Defaults to `[]` if omitted. |
|
|
62
|
+
| `options` | object | Command options using CLI option names without leading `--`. Defaults to `{}`. Values are the JSON the CLI sends: a string for `--name=value`, `true` for a bare flag, and an object for a few structured options (for example `viewport` is `{"width": 1280, "height": 720}`). |
|
|
63
|
+
| `cwd` | string or null | Absolute caller working directory for relative paths and output files. Omitted or null uses the daemon's working directory. |
|
|
64
|
+
| `token` | string | Current authentication token read from `token_path`. Required. |
|
|
65
|
+
|
|
66
|
+
`options.session` and `options.tab` select a session and named tab; both default
|
|
67
|
+
to `default`. Command-specific arguments and options follow CLI help.
|
|
68
|
+
|
|
69
|
+
## Reply fields
|
|
70
|
+
|
|
71
|
+
Every reply carries an explicit boolean `success` and a string `output`, on
|
|
72
|
+
both success and failure. `success: false` indicates authentication, command,
|
|
73
|
+
or daemon errors. `output` contains the result or a human-readable error.
|
|
74
|
+
Additional fields, such as `snapshot_path`, are command-specific. Clients must
|
|
75
|
+
ignore unknown fields. No structured error codes are currently provided.
|
|
76
|
+
|
|
77
|
+
Clients can detect these states in failed replies by matching these output
|
|
78
|
+
fragments. Surrounding context and recovery advice can vary. The fragments in
|
|
79
|
+
this table are part of the protocol:
|
|
80
|
+
|
|
81
|
+
| Output fragment | State |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| `Session '<name>' is not open` | The requested session is absent. |
|
|
84
|
+
| `Tab '<name>' is not open` | The requested named tab is absent from the session. |
|
|
85
|
+
| `requires an auth token` | The request omitted `token`. |
|
|
86
|
+
| `rejected the auth token` | The supplied token is invalid or stale. Read the token file fresh before retrying. |
|
|
87
|
+
| `Daemon error: request of` | The request exceeded the 64 MiB limit. |
|
|
88
|
+
|
|
89
|
+
Best effort, not covered by the compatibility rules below: a command on a page,
|
|
90
|
+
context or browser that has closed usually fails with Playwright's own message
|
|
91
|
+
containing `has been closed`. That text comes from Playwright and can change
|
|
92
|
+
with its version without a protocol increment.
|
|
93
|
+
|
|
94
|
+
## Compatibility
|
|
95
|
+
|
|
96
|
+
`protocol` is independent of the package version. Any incompatible change to
|
|
97
|
+
framing, request limits, request fields (`command`, `args`, `options`, `cwd`,
|
|
98
|
+
`token`), reply fields (`success`, `output`), authentication, or the
|
|
99
|
+
state-detection fragments in the table above requires a protocol increment.
|
|
100
|
+
Raising a request limit is not incompatible. Optional additive fields and new
|
|
101
|
+
commands do not require an increment. Clients can reject unsupported protocol
|
|
102
|
+
versions before sending requests.
|
|
@@ -59,8 +59,21 @@ patchright-cli goto "https://example.com/search?q=cats&page=2"
|
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
The same applies to `#` (a bash comment), spaces, and `%` (expanded by
|
|
62
|
-
cmd.exe), and to any argument holding shell metacharacters. Quoting
|
|
63
|
-
|
|
62
|
+
cmd.exe), and to any argument holding shell metacharacters. Quoting works for
|
|
63
|
+
the installed `patchright-cli.exe` in bash, PowerShell and cmd.exe; leave it on.
|
|
64
|
+
|
|
65
|
+
On Windows, two cases need more than quotes:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
# cmd.exe without quotes: escape the & as ^&. Inside quotes ^ is kept
|
|
69
|
+
# literally, so use one or the other, never both.
|
|
70
|
+
patchright-cli goto https://example.com/search?q=cats^&page=2
|
|
71
|
+
|
|
72
|
+
# PowerShell calling a .cmd/.bat wrapper (such as the repo's patchright-cli.cmd):
|
|
73
|
+
# PowerShell drops the quotes and cmd.exe splits at &. Pass the rest verbatim
|
|
74
|
+
# with --%. Don't use --% with patchright-cli.exe: in PowerShell 7 the quotes end up in the URL.
|
|
75
|
+
.\patchright-cli.cmd --% goto "https://example.com/search?q=cats&page=2"
|
|
76
|
+
```
|
|
64
77
|
|
|
65
78
|
## Global options
|
|
66
79
|
|
|
@@ -320,6 +333,25 @@ show # Live dashboard
|
|
|
320
333
|
show --annotate # Ask a human to mark up the page and wait for it
|
|
321
334
|
```
|
|
322
335
|
|
|
336
|
+
### Emulation
|
|
337
|
+
|
|
338
|
+
Each setting holds for the whole session: every open tab, and tabs and popups
|
|
339
|
+
opened later (a popup gets it just after it opens). `clear-*` drops just that
|
|
340
|
+
one, back to the browser default.
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
set-color-scheme dark # dark | light | no-preference
|
|
344
|
+
clear-color-scheme
|
|
345
|
+
set-reduced-motion reduce # reduce | no-preference
|
|
346
|
+
clear-reduced-motion
|
|
347
|
+
set-forced-colors active # active | none
|
|
348
|
+
clear-forced-colors
|
|
349
|
+
set-contrast more # more | no-preference
|
|
350
|
+
clear-contrast
|
|
351
|
+
set-media print # screen | print
|
|
352
|
+
clear-media
|
|
353
|
+
```
|
|
354
|
+
|
|
323
355
|
### Storage
|
|
324
356
|
|
|
325
357
|
```bash
|
|
@@ -17,7 +17,7 @@ from pathlib import Path
|
|
|
17
17
|
import click
|
|
18
18
|
|
|
19
19
|
from patchright_cli import __version__
|
|
20
|
-
from patchright_cli.daemon import DEFAULT_PORT, ensure_daemon_running, read_daemon_token
|
|
20
|
+
from patchright_cli.daemon import DEFAULT_PORT, PROTOCOL_VERSION, ensure_daemon_running, read_daemon_token, token_path
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
def _soften_output_encoding(*streams) -> None:
|
|
@@ -497,6 +497,17 @@ COMMANDS_HELP = {
|
|
|
497
497
|
# Upload / Resize
|
|
498
498
|
"upload": "upload <file> [ref] Upload file to input",
|
|
499
499
|
"resize": "resize <w> <h> Resize viewport",
|
|
500
|
+
# Emulation
|
|
501
|
+
"set-color-scheme": "set-color-scheme <dark|light|no-preference> Emulate prefers-color-scheme",
|
|
502
|
+
"clear-color-scheme": "clear-color-scheme Stop emulating prefers-color-scheme",
|
|
503
|
+
"set-reduced-motion": "set-reduced-motion <reduce|no-preference> Emulate prefers-reduced-motion",
|
|
504
|
+
"clear-reduced-motion": "clear-reduced-motion Stop emulating prefers-reduced-motion",
|
|
505
|
+
"set-forced-colors": "set-forced-colors <active|none> Emulate forced-colors",
|
|
506
|
+
"clear-forced-colors": "clear-forced-colors Stop emulating forced-colors",
|
|
507
|
+
"set-contrast": "set-contrast <more|no-preference> Emulate prefers-contrast",
|
|
508
|
+
"clear-contrast": "clear-contrast Stop emulating prefers-contrast",
|
|
509
|
+
"set-media": "set-media <screen|print> Emulate CSS media type",
|
|
510
|
+
"clear-media": "clear-media Stop emulating the CSS media type",
|
|
500
511
|
# State
|
|
501
512
|
"state-save": "state-save [file] Save cookies+storage to JSON",
|
|
502
513
|
"state-load": "state-load <file> Load saved state",
|
|
@@ -547,6 +558,7 @@ COMMANDS_HELP = {
|
|
|
547
558
|
# Setup
|
|
548
559
|
"install": "install --skills Install skill files for AI agents",
|
|
549
560
|
"mcp": "mcp [--http] [--host=HOST] [--port=N] Start MCP server (stdio by default)",
|
|
561
|
+
"daemon-info": "daemon-info --json Show daemon client protocol and token path without starting it",
|
|
550
562
|
}
|
|
551
563
|
|
|
552
564
|
ALL_COMMANDS = list(COMMANDS_HELP.keys())
|
|
@@ -619,6 +631,21 @@ def _print_help():
|
|
|
619
631
|
("Tabs", ["tab-list", "tab-new", "tab-close", "tab-select"]),
|
|
620
632
|
("Dialog", ["dialog-accept", "dialog-dismiss"]),
|
|
621
633
|
("Upload/Resize", ["upload", "resize"]),
|
|
634
|
+
(
|
|
635
|
+
"Emulation",
|
|
636
|
+
[
|
|
637
|
+
"set-color-scheme",
|
|
638
|
+
"clear-color-scheme",
|
|
639
|
+
"set-reduced-motion",
|
|
640
|
+
"clear-reduced-motion",
|
|
641
|
+
"set-forced-colors",
|
|
642
|
+
"clear-forced-colors",
|
|
643
|
+
"set-contrast",
|
|
644
|
+
"clear-contrast",
|
|
645
|
+
"set-media",
|
|
646
|
+
"clear-media",
|
|
647
|
+
],
|
|
648
|
+
),
|
|
622
649
|
("State", ["state-save", "state-load"]),
|
|
623
650
|
(
|
|
624
651
|
"Storage",
|
|
@@ -653,7 +680,7 @@ def _print_help():
|
|
|
653
680
|
("Profiles", ["profile-list", "profile-delete"]),
|
|
654
681
|
("Dashboard", ["show"]),
|
|
655
682
|
("Codegen", ["codegen", "codegen-stop"]),
|
|
656
|
-
("Setup", ["install", "mcp"]),
|
|
683
|
+
("Setup", ["install", "mcp", "daemon-info"]),
|
|
657
684
|
]
|
|
658
685
|
for cat_name, cmds in categories:
|
|
659
686
|
click.echo(f"\n {cat_name}:")
|
|
@@ -823,6 +850,22 @@ def main():
|
|
|
823
850
|
_print_help()
|
|
824
851
|
sys.exit(1)
|
|
825
852
|
|
|
853
|
+
if command == "daemon-info":
|
|
854
|
+
if not as_json or args or extra_opts:
|
|
855
|
+
click.echo("Usage: patchright-cli daemon-info --json [--port=N]", err=True)
|
|
856
|
+
sys.exit(1)
|
|
857
|
+
click.echo(
|
|
858
|
+
json.dumps(
|
|
859
|
+
{
|
|
860
|
+
"version": __version__,
|
|
861
|
+
"protocol": PROTOCOL_VERSION,
|
|
862
|
+
"port": port,
|
|
863
|
+
"token_path": str(token_path(port).resolve()),
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
)
|
|
867
|
+
return
|
|
868
|
+
|
|
826
869
|
if command == "install":
|
|
827
870
|
_handle_install(args + [k if v is True else f"{k}={v}" for k, v in extra_opts.items()])
|
|
828
871
|
sys.exit(0)
|