patchright-cli 0.8.0__py3-none-any.whl → 0.9.1__py3-none-any.whl
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/__init__.py +1 -1
- patchright_cli/_skills/patchright-cli/SKILL.md +34 -2
- patchright_cli/cli.py +62 -5
- patchright_cli/daemon.py +628 -32
- patchright_cli/mcp_server.py +205 -32
- patchright_cli/ref_registry.py +35 -12
- {patchright_cli-0.8.0.dist-info → patchright_cli-0.9.1.dist-info}/METADATA +135 -6
- {patchright_cli-0.8.0.dist-info → patchright_cli-0.9.1.dist-info}/RECORD +11 -11
- {patchright_cli-0.8.0.dist-info → patchright_cli-0.9.1.dist-info}/WHEEL +0 -0
- {patchright_cli-0.8.0.dist-info → patchright_cli-0.9.1.dist-info}/entry_points.txt +0 -0
- {patchright_cli-0.8.0.dist-info → patchright_cli-0.9.1.dist-info}/licenses/LICENSE +0 -0
patchright_cli/__init__.py
CHANGED
|
@@ -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
|
patchright_cli/cli.py
CHANGED
|
@@ -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
|
|
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:
|
|
@@ -392,6 +392,11 @@ def _send_command(command: str, args: list, options: dict, port: int = DEFAULT_P
|
|
|
392
392
|
"options": options,
|
|
393
393
|
"cwd": os.getcwd(),
|
|
394
394
|
}
|
|
395
|
+
# A daemon that predates tokens writes no token file and accepts the
|
|
396
|
+
# message without one, so a missing file is not an error here.
|
|
397
|
+
token = read_daemon_token(port)
|
|
398
|
+
if token:
|
|
399
|
+
msg["token"] = token
|
|
395
400
|
data = json.dumps(msg).encode("utf-8")
|
|
396
401
|
|
|
397
402
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
@@ -426,7 +431,7 @@ def _recv_exact(sock: socket.socket, n: int) -> bytes:
|
|
|
426
431
|
|
|
427
432
|
COMMANDS_HELP = {
|
|
428
433
|
# Core
|
|
429
|
-
"open": "open [url] Open browser (starts daemon if needed)",
|
|
434
|
+
"open": "open [url] Open browser (starts daemon if needed) [--block-networks=link-local|private] [--web-only]",
|
|
430
435
|
"attach": "attach --cdp=<url> [--context=new|host] Attach to running Chrome via CDP",
|
|
431
436
|
"goto": "goto <url> Navigate to URL",
|
|
432
437
|
"click": "click <ref> [button] Click element [--modifiers=Alt,Shift]",
|
|
@@ -492,6 +497,17 @@ COMMANDS_HELP = {
|
|
|
492
497
|
# Upload / Resize
|
|
493
498
|
"upload": "upload <file> [ref] Upload file to input",
|
|
494
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",
|
|
495
511
|
# State
|
|
496
512
|
"state-save": "state-save [file] Save cookies+storage to JSON",
|
|
497
513
|
"state-load": "state-load <file> Load saved state",
|
|
@@ -542,6 +558,7 @@ COMMANDS_HELP = {
|
|
|
542
558
|
# Setup
|
|
543
559
|
"install": "install --skills Install skill files for AI agents",
|
|
544
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",
|
|
545
562
|
}
|
|
546
563
|
|
|
547
564
|
ALL_COMMANDS = list(COMMANDS_HELP.keys())
|
|
@@ -614,6 +631,21 @@ def _print_help():
|
|
|
614
631
|
("Tabs", ["tab-list", "tab-new", "tab-close", "tab-select"]),
|
|
615
632
|
("Dialog", ["dialog-accept", "dialog-dismiss"]),
|
|
616
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
|
+
),
|
|
617
649
|
("State", ["state-save", "state-load"]),
|
|
618
650
|
(
|
|
619
651
|
"Storage",
|
|
@@ -648,7 +680,7 @@ def _print_help():
|
|
|
648
680
|
("Profiles", ["profile-list", "profile-delete"]),
|
|
649
681
|
("Dashboard", ["show"]),
|
|
650
682
|
("Codegen", ["codegen", "codegen-stop"]),
|
|
651
|
-
("Setup", ["install", "mcp"]),
|
|
683
|
+
("Setup", ["install", "mcp", "daemon-info"]),
|
|
652
684
|
]
|
|
653
685
|
for cat_name, cmds in categories:
|
|
654
686
|
click.echo(f"\n {cat_name}:")
|
|
@@ -688,6 +720,10 @@ def main():
|
|
|
688
720
|
i = 0
|
|
689
721
|
while i < len(argv):
|
|
690
722
|
arg = argv[i]
|
|
723
|
+
if arg == "--":
|
|
724
|
+
# End of options: the rest is positional, even text that looks like a flag.
|
|
725
|
+
remaining.extend(argv[i:])
|
|
726
|
+
break
|
|
691
727
|
if arg == "--headless":
|
|
692
728
|
headless = True
|
|
693
729
|
elif arg == "--persistent":
|
|
@@ -814,6 +850,22 @@ def main():
|
|
|
814
850
|
_print_help()
|
|
815
851
|
sys.exit(1)
|
|
816
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
|
+
|
|
817
869
|
if command == "install":
|
|
818
870
|
_handle_install(args + [k if v is True else f"{k}={v}" for k, v in extra_opts.items()])
|
|
819
871
|
sys.exit(0)
|
|
@@ -832,8 +884,13 @@ def main():
|
|
|
832
884
|
# Separate --key=value and --flag from positional args
|
|
833
885
|
positional_args = []
|
|
834
886
|
cmd_opts: dict = {}
|
|
887
|
+
end_of_options = False
|
|
835
888
|
for a in args:
|
|
836
|
-
if
|
|
889
|
+
if end_of_options:
|
|
890
|
+
positional_args.append(a)
|
|
891
|
+
elif a == "--":
|
|
892
|
+
end_of_options = True
|
|
893
|
+
elif a.startswith("--") and "=" in a:
|
|
837
894
|
k, v = a[2:].split("=", 1)
|
|
838
895
|
cmd_opts[k] = v
|
|
839
896
|
elif a.startswith("--"):
|
|
@@ -855,7 +912,7 @@ def main():
|
|
|
855
912
|
except FileNotFoundError:
|
|
856
913
|
click.echo(f"File not found: {file_opt}", err=True)
|
|
857
914
|
sys.exit(1)
|
|
858
|
-
elif args and args[0] == "-":
|
|
915
|
+
elif args and args[0] == "-" and not end_of_options:
|
|
859
916
|
# Read JS from stdin
|
|
860
917
|
args = [sys.stdin.read()]
|
|
861
918
|
elif not args and not sys.stdin.isatty():
|