1#![allow(missing_docs)]
5
6use clap::{Parser, Subcommand, ValueEnum};
7
8#[derive(Debug, Parser)]
10#[command(
11 name = "browser-automation-cli",
12 version,
13 about = "One-shot browser automation CLI (Chrome CDP). BORN, EXECUTE, FINALIZE, DIE.",
14 long_about = None,
15 propagate_version = true
16)]
17pub struct Cli {
18 #[command(flatten)]
19 pub globals: GlobalOpts,
20
21 #[command(subcommand)]
22 pub command: Commands,
23}
24
25#[derive(Debug, Clone, Parser)]
26pub struct GlobalOpts {
27 #[arg(long, global = true)]
28 pub json: bool,
29
30 #[arg(short = 'q', long = "quiet", global = true)]
32 pub quiet: bool,
33
34 #[arg(long = "verbose", global = true)]
36 pub verbose: bool,
37
38 #[arg(long = "debug", global = true)]
40 pub debug: bool,
41
42 #[arg(long, global = true, default_value_t = 0)]
43 pub timeout: u64,
44
45 #[arg(long, global = true, default_value_t = 0)]
47 pub step_timeout: u64,
48
49 #[arg(long, global = true)]
51 pub headed: bool,
52
53 #[arg(long, global = true)]
54 pub artifacts_dir: Option<std::path::PathBuf>,
55
56 #[arg(long, global = true)]
57 pub lang: Option<String>,
58
59 #[arg(long, global = true)]
60 pub capture_console: bool,
61
62 #[arg(long, global = true)]
63 pub capture_network: bool,
64
65 #[arg(long, global = true)]
66 pub ignore_robots: bool,
67
68 #[arg(long, global = true)]
69 pub i_accept_robots_risk: bool,
70
71 #[arg(long, global = true)]
73 pub category_memory: bool,
74
75 #[arg(long, global = true)]
77 pub category_extensions: bool,
78
79 #[arg(long, global = true)]
81 pub category_third_party: bool,
82
83 #[arg(long, global = true)]
85 pub category_webmcp: bool,
86
87 #[arg(long, global = true)]
89 pub experimental_screencast: bool,
90
91 #[arg(long, global = true)]
93 pub experimental_vision: bool,
94}
95
96#[derive(Debug, Subcommand)]
97pub enum Commands {
98 Doctor {
100 #[arg(long)]
101 offline: bool,
102 #[arg(long)]
103 quick: bool,
104 #[arg(long)]
105 fix: bool,
106 #[arg(long)]
107 json: bool,
108 },
109 Commands {
111 #[arg(long)]
112 json: bool,
113 },
114 Schema {
116 #[arg(long = "cmd", value_name = "CMD")]
117 cmd: String,
118 },
119 Version,
121 Goto {
123 url: String,
124 #[arg(long)]
126 init_script: Option<String>,
127 #[arg(long)]
129 handle_before_unload: bool,
130 #[arg(long)]
132 navigation_timeout_ms: Option<u64>,
133 },
134 View {
136 #[arg(long)]
137 verbose: bool,
138 #[arg(long)]
139 path: Option<std::path::PathBuf>,
140 },
141 Press {
143 target: String,
144 #[arg(long)]
145 dblclick: bool,
146 #[arg(long)]
148 include_snapshot: bool,
149 },
150 ClickAt {
152 #[arg(long)]
153 x: f64,
154 #[arg(long)]
155 y: f64,
156 #[arg(long)]
157 dblclick: bool,
158 #[arg(long)]
160 include_snapshot: bool,
161 },
162 Write {
164 target: String,
165 value: String,
166 #[arg(long)]
168 include_snapshot: bool,
169 },
170 Keys {
172 key: String,
173 #[arg(long)]
175 include_snapshot: bool,
176 },
177 Type {
179 text: String,
181 #[arg(long)]
183 target: Option<String>,
184 #[arg(long)]
185 clear: bool,
186 #[arg(long)]
188 submit: Option<String>,
189 #[arg(long)]
191 focus_only: bool,
192 },
193 Wait {
195 #[arg(long, default_value_t = 0)]
196 ms: u64,
197 #[arg(long = "text", action = clap::ArgAction::Append)]
199 text: Vec<String>,
200 #[arg(long)]
201 selector: Option<String>,
202 #[arg(long)]
204 state: Option<String>,
205 #[arg(long)]
207 wait_timeout_ms: Option<u64>,
208 #[arg(long)]
210 include_snapshot: bool,
211 },
212 Hover {
214 target: String,
215 #[arg(long)]
217 include_snapshot: bool,
218 },
219 Drag {
221 #[arg(long)]
222 from: String,
223 #[arg(long)]
224 to: String,
225 #[arg(long)]
227 include_snapshot: bool,
228 },
229 FillForm {
231 #[arg(long)]
232 json: String,
233 #[arg(long)]
235 include_snapshot: bool,
236 },
237 Upload {
239 target: String,
240 path: std::path::PathBuf,
241 #[arg(long)]
243 include_snapshot: bool,
244 },
245 Back,
247 Forward,
249 Reload {
251 #[arg(long)]
252 ignore_cache: bool,
253 #[arg(long)]
255 init_script: Option<String>,
256 #[arg(long)]
258 handle_before_unload: bool,
259 },
260 Eval {
262 expression: String,
264 #[arg(long)]
266 args: Option<String>,
267 #[arg(long)]
269 dialog_action: Option<String>,
270 #[arg(long)]
272 file_path: Option<std::path::PathBuf>,
273 },
274 Grab {
276 #[arg(long)]
277 path: Option<std::path::PathBuf>,
278 #[arg(long, value_enum, default_value_t = GrabFormat::Png)]
279 format: GrabFormat,
280 #[arg(long)]
281 full_page: bool,
282 #[arg(long)]
283 quality: Option<i32>,
284 #[arg(long)]
286 element: Option<String>,
287 },
288 PrintPdf {
290 #[arg(long)]
292 path: Option<std::path::PathBuf>,
293 #[arg(long)]
295 url: Option<String>,
296 },
297 Monitor {
299 #[command(subcommand)]
300 action: MonitorAction,
301 },
302 Run {
304 #[arg(long)]
305 script: std::path::PathBuf,
306 },
307 Exec {
309 #[arg(trailing_var_arg = true)]
312 args: Vec<String>,
313 },
314 Extract {
316 target: String,
318 #[arg(long)]
319 attr: Option<String>,
320 #[arg(long)]
322 llm: bool,
323 #[arg(long)]
325 question: Option<String>,
326 #[arg(long)]
328 schema_json: Option<std::path::PathBuf>,
329 },
330 Text { target: String },
332 Scroll {
334 #[arg(long)]
336 target: Option<String>,
337 #[arg(long, default_value_t = 0.0)]
338 delta_x: f64,
339 #[arg(long, default_value_t = 0.0)]
340 delta_y: f64,
341 },
342 Cookie {
344 #[command(subcommand)]
345 action: CookieAction,
346 },
347 Attr { target: String, name: String },
349 Assert {
351 #[command(subcommand)]
352 kind: AssertKind,
353 },
354 Console {
356 #[command(subcommand)]
357 action: ConsoleAction,
358 },
359 Net {
361 #[command(subcommand)]
362 action: NetAction,
363 },
364 Page {
366 #[command(subcommand)]
367 action: Option<PageAction>,
368 },
369 Dialog {
371 #[command(subcommand)]
372 action: DialogAction,
373 },
374 Scrape {
376 url: String,
377 #[arg(long, default_value = "text")]
379 format: String,
380 #[arg(long, default_value = "browser")]
382 engine: String,
383 #[arg(long)]
385 only_main_content: bool,
386 #[arg(long)]
388 webhook_url: Option<String>,
389 },
390 BatchScrape {
392 #[arg(long)]
393 urls_file: std::path::PathBuf,
394 #[arg(long, default_value = "text")]
395 format: String,
396 #[arg(long, default_value_t = 2)]
397 concurrency: usize,
398 },
399 Crawl {
401 url: String,
402 #[arg(long, default_value_t = 20)]
403 limit: usize,
404 #[arg(long, default_value_t = 2)]
405 max_depth: usize,
406 #[arg(long, default_value = "text")]
407 format: String,
408 #[arg(long, default_value_t = true)]
410 same_host: bool,
411 },
412 Map {
414 url: String,
415 #[arg(long, default_value_t = 50)]
416 limit: usize,
417 #[arg(long, default_value_t = 2)]
418 max_depth: usize,
419 },
420 Search {
422 query: String,
423 #[arg(long, default_value_t = 10)]
424 limit: usize,
425 },
426 Parse {
428 path: std::path::PathBuf,
429 #[arg(long)]
431 redact_pii: bool,
432 },
433 Qr {
435 #[command(subcommand)]
436 action: QrAction,
437 },
438 FindPaths {
440 pattern: Option<String>,
442 #[arg(num_args = 0..)]
444 paths: Vec<String>,
445 #[arg(long)]
447 extension: Option<String>,
448 #[arg(long)]
450 hidden: bool,
451 #[arg(long)]
453 no_ignore: bool,
454 #[arg(long)]
456 max_depth: Option<usize>,
457 #[arg(long = "type")]
459 entry_type: Option<String>,
460 #[arg(long, default_value_t = 10000)]
462 limit: usize,
463 },
464 Mitm {
466 #[command(subcommand)]
467 action: MitmAction,
468 },
469 Workflow {
471 #[command(subcommand)]
472 action: WorkflowAction,
473 },
474 Config {
476 #[command(subcommand)]
477 action: ConfigAction,
478 },
479 Emulate {
481 #[arg(long)]
482 user_agent: Option<String>,
483 #[arg(long)]
484 locale: Option<String>,
485 #[arg(long)]
486 timezone: Option<String>,
487 #[arg(long)]
488 offline: bool,
489 #[arg(long)]
490 latitude: Option<f64>,
491 #[arg(long)]
492 longitude: Option<f64>,
493 #[arg(long)]
494 media: Option<String>,
495 #[arg(long)]
497 network_conditions: Option<String>,
498 #[arg(long)]
500 cpu_throttling_rate: Option<f64>,
501 #[arg(long)]
503 color_scheme: Option<String>,
504 #[arg(long)]
506 extra_headers: Option<String>,
507 #[arg(long)]
509 viewport: Option<String>,
510 },
511 Resize {
513 #[arg(long)]
514 width: i32,
515 #[arg(long)]
516 height: i32,
517 #[arg(long, default_value_t = 1.0)]
518 scale: f64,
519 #[arg(long)]
520 mobile: bool,
521 },
522 Perf {
524 #[command(subcommand)]
525 action: PerfAction,
526 },
527 Lighthouse {
529 url: String,
530 #[arg(long)]
531 out_dir: Option<std::path::PathBuf>,
532 #[arg(long, default_value = "desktop")]
533 device: String,
534 #[arg(long, default_value = "navigation")]
536 mode: String,
537 #[arg(long)]
538 lighthouse_path: Option<std::path::PathBuf>,
539 },
540 Screencast {
542 #[command(subcommand)]
543 action: ScreencastAction,
544 },
545 Heap {
547 #[command(subcommand)]
548 action: HeapAction,
549 },
550 Extension {
552 #[command(subcommand)]
553 action: ExtensionAction,
554 },
555 Devtools3p {
557 #[command(subcommand)]
558 action: Devtools3pAction,
559 },
560 Webmcp {
562 #[command(subcommand)]
563 action: WebmcpAction,
564 },
565 Completions {
567 #[arg(value_enum)]
568 shell: CompletionShell,
569 },
570}
571
572#[derive(Debug, Clone, Subcommand)]
573pub enum PerfAction {
574 Start {
575 #[arg(long)]
576 path: Option<std::path::PathBuf>,
577 #[arg(long)]
578 reload: bool,
579 #[arg(long)]
581 auto_stop: bool,
582 },
583 Stop {
584 #[arg(long)]
585 path: Option<std::path::PathBuf>,
586 },
587 Insight {
588 #[arg(long)]
590 name: Option<String>,
591 #[arg(long)]
593 insight_set_id: Option<String>,
594 #[arg(long)]
596 insight_name: Option<String>,
597 },
598}
599
600#[derive(Debug, Clone, Subcommand)]
601pub enum ScreencastAction {
602 Start {
603 #[arg(long)]
604 path: Option<std::path::PathBuf>,
605 },
606 Stop {
607 #[arg(long)]
609 path: Option<std::path::PathBuf>,
610 },
611}
612
613#[derive(Debug, Clone, Subcommand)]
614pub enum HeapAction {
615 Take {
616 #[arg(long)]
617 path: std::path::PathBuf,
618 },
619 Close {
620 #[arg(long)]
621 path: std::path::PathBuf,
622 },
623 Compare {
624 #[arg(long)]
625 base: std::path::PathBuf,
626 #[arg(long)]
627 current: std::path::PathBuf,
628 #[arg(long)]
630 class_index: Option<u64>,
631 },
632 Summary {
633 #[arg(long)]
634 path: std::path::PathBuf,
635 },
636 Details {
637 #[arg(long)]
638 path: std::path::PathBuf,
639 #[arg(long)]
640 filter_name: Option<String>,
641 #[arg(long)]
642 page_idx: Option<usize>,
643 #[arg(long)]
644 page_size: Option<usize>,
645 },
646 ClassNodes {
647 #[arg(long)]
648 path: std::path::PathBuf,
649 #[arg(long)]
650 id: u64,
651 #[arg(long)]
652 filter_name: Option<String>,
653 #[arg(long)]
654 page_idx: Option<usize>,
655 #[arg(long)]
656 page_size: Option<usize>,
657 },
658 Dominators {
659 #[arg(long)]
660 path: std::path::PathBuf,
661 #[arg(long)]
662 node: u64,
663 },
664 DupStrings {
665 #[arg(long)]
666 path: std::path::PathBuf,
667 #[arg(long)]
668 page_idx: Option<usize>,
669 #[arg(long)]
670 page_size: Option<usize>,
671 },
672 Edges {
673 #[arg(long)]
674 path: std::path::PathBuf,
675 #[arg(long)]
676 node: u64,
677 #[arg(long)]
678 page_idx: Option<usize>,
679 #[arg(long)]
680 page_size: Option<usize>,
681 },
682 Retainers {
683 #[arg(long)]
684 path: std::path::PathBuf,
685 #[arg(long)]
686 node: u64,
687 #[arg(long)]
688 page_idx: Option<usize>,
689 #[arg(long)]
690 page_size: Option<usize>,
691 },
692 Paths {
693 #[arg(long)]
694 path: std::path::PathBuf,
695 #[arg(long)]
696 node: u64,
697 #[arg(long, default_value_t = 8)]
698 max_depth: u64,
699 #[arg(long)]
700 max_nodes: Option<u64>,
701 #[arg(long)]
702 max_siblings: Option<u64>,
703 },
704 ObjectDetails {
706 #[arg(long)]
707 path: std::path::PathBuf,
708 #[arg(long)]
709 node: u64,
710 },
711}
712
713#[derive(Debug, Clone, Subcommand)]
714pub enum ExtensionAction {
715 List,
716 Install {
717 path: std::path::PathBuf,
718 },
719 Reload {
720 id: String,
721 #[arg(long)]
723 path: Option<std::path::PathBuf>,
724 },
725 Trigger {
726 id: String,
727 #[arg(long)]
729 path: Option<std::path::PathBuf>,
730 },
731 Uninstall {
732 id: String,
733 },
734}
735
736#[derive(Debug, Clone, Subcommand)]
737pub enum Devtools3pAction {
738 List {
739 #[arg(long)]
741 url: Option<String>,
742 },
743 Exec {
744 name: String,
745 #[arg(long)]
746 params: Option<String>,
747 #[arg(long)]
748 url: Option<String>,
749 },
750}
751
752#[derive(Debug, Clone, Subcommand)]
753pub enum WebmcpAction {
754 List {
755 #[arg(long)]
756 url: Option<String>,
757 },
758 Exec {
759 name: String,
760 #[arg(long)]
761 input: Option<String>,
762 #[arg(long)]
763 url: Option<String>,
764 },
765}
766
767#[derive(Debug, Clone, Copy, ValueEnum)]
768pub enum CompletionShell {
769 Bash,
770 Zsh,
771 Fish,
772 Elvish,
773 Powershell,
774}
775
776#[derive(Debug, Clone, Subcommand)]
777pub enum QrAction {
778 Encode {
780 #[arg(long)]
781 text: String,
782 #[arg(long, default_value = "png")]
784 format: String,
785 #[arg(long)]
786 path: Option<std::path::PathBuf>,
787 },
788 Decode {
790 #[arg(long)]
791 path: std::path::PathBuf,
792 },
793}
794
795#[derive(Debug, Clone, Subcommand)]
796pub enum MonitorAction {
797 Check {
799 #[arg(long)]
801 url: String,
802 #[arg(long)]
804 baseline: std::path::PathBuf,
805 #[arg(long)]
807 write_baseline: bool,
808 #[arg(long, default_value = "http")]
810 engine: String,
811 },
812}
813
814#[derive(Debug, Clone, Subcommand)]
815pub enum PageAction {
816 Info,
818 List,
820 New {
822 #[arg(long)]
823 url: Option<String>,
824 #[arg(long)]
826 background: bool,
827 #[arg(long)]
829 isolated_context: bool,
830 },
831 Select {
833 #[arg(value_name = "INDEX")]
834 index: Option<usize>,
835 #[arg(long = "page-id")]
837 page_id: Option<usize>,
838 #[arg(long, default_value_t = true)]
840 bring_to_front: bool,
841 },
842 Close {
844 #[arg(long)]
845 index: Option<usize>,
846 #[arg(long = "page-id")]
848 page_id: Option<usize>,
849 },
850}
851
852#[derive(Debug, Clone, Subcommand)]
853pub enum CookieAction {
854 List {
856 #[arg(long)]
857 url: Option<String>,
858 },
859 Set {
861 #[arg(long)]
863 json: String,
864 },
865 Clear,
867}
868
869#[derive(Debug, Clone, Copy, ValueEnum, Default)]
870pub enum GrabFormat {
871 #[default]
872 Png,
873 Jpeg,
874 Webp,
875}
876
877#[derive(Debug, Clone, Subcommand)]
878pub enum AssertKind {
879 Url {
880 value: String,
881 #[arg(long)]
882 contains: bool,
883 },
884 Text {
885 value: String,
886 #[arg(long)]
887 target: Option<String>,
888 },
889 Console {
890 #[arg(long, default_value = "error")]
891 level: String,
892 #[arg(long, default_value_t = 0)]
893 max: u64,
894 },
895}
896
897#[derive(Debug, Clone, Subcommand)]
898pub enum ConsoleAction {
899 List {
900 #[arg(long)]
902 page_idx: Option<usize>,
903 #[arg(long)]
905 page_size: Option<usize>,
906 #[arg(long)]
908 types: Option<String>,
909 #[arg(long)]
911 include_preserved: bool,
912 #[arg(long)]
914 service_worker_id: Option<String>,
915 },
916 Get {
917 id: usize,
918 },
919 Clear,
920 Dump {
921 #[arg(long)]
922 path: std::path::PathBuf,
923 },
924}
925
926#[derive(Debug, Clone, Subcommand)]
927pub enum NetAction {
928 List {
929 #[arg(long)]
931 page_idx: Option<usize>,
932 #[arg(long)]
934 page_size: Option<usize>,
935 #[arg(long)]
937 resource_types: Option<String>,
938 #[arg(long)]
940 include_preserved: bool,
941 },
942 Get {
943 id: String,
945 #[arg(long)]
946 request_path: Option<std::path::PathBuf>,
947 #[arg(long)]
948 response_path: Option<std::path::PathBuf>,
949 },
950}
951
952#[derive(Debug, Clone, Subcommand)]
953pub enum DialogAction {
954 Accept {
955 #[arg(long)]
956 text: Option<String>,
957 },
958 Dismiss,
959}
960
961#[derive(Debug, Clone, Subcommand)]
962pub enum MitmAction {
963 Status,
965 List {
967 #[arg(long)]
968 host: Option<String>,
969 #[arg(long, default_value_t = 100)]
970 limit: usize,
971 },
972 Get { id: u64 },
974 Har {
976 #[arg(long)]
977 out: std::path::PathBuf,
978 },
979 Export {
981 #[arg(long, default_value = "json")]
982 format: String,
983 #[arg(long)]
984 out: std::path::PathBuf,
985 },
986 Domains,
988 Apis {
990 #[arg(long)]
991 kind: Option<String>,
992 },
993 InitCa,
995 Start {
997 #[arg(long, default_value_t = 30)]
999 seconds: u64,
1000 },
1001}
1002
1003#[derive(Debug, Clone, Subcommand)]
1004pub enum WorkflowAction {
1005 Run {
1007 #[arg(long)]
1008 manifest: std::path::PathBuf,
1009 #[arg(long)]
1010 journal: Option<std::path::PathBuf>,
1011 },
1012 Resume {
1014 #[arg(long)]
1015 manifest: std::path::PathBuf,
1016 #[arg(long)]
1017 journal: Option<std::path::PathBuf>,
1018 },
1019 Status {
1021 #[arg(long)]
1022 journal: Option<std::path::PathBuf>,
1023 #[arg(long)]
1024 name: Option<String>,
1025 },
1026}
1027
1028#[derive(Debug, Clone, Subcommand)]
1029pub enum ConfigAction {
1030 Path,
1032 Init,
1034 Show,
1036 Set { key: String, value: String },
1038 Get { key: Option<String> },
1040}