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 #[arg(long)]
275 service_worker_id: Option<String>,
276 },
277 Grab {
279 #[arg(long)]
280 path: Option<std::path::PathBuf>,
281 #[arg(long, value_enum, default_value_t = GrabFormat::Png)]
282 format: GrabFormat,
283 #[arg(long)]
284 full_page: bool,
285 #[arg(long)]
286 quality: Option<i32>,
287 #[arg(long)]
289 element: Option<String>,
290 },
291 PrintPdf {
293 #[arg(long)]
295 path: Option<std::path::PathBuf>,
296 #[arg(long)]
298 url: Option<String>,
299 },
300 Monitor {
302 #[command(subcommand)]
303 action: MonitorAction,
304 },
305 Run {
307 #[arg(long)]
308 script: std::path::PathBuf,
309 },
310 Exec {
312 #[arg(trailing_var_arg = true)]
315 args: Vec<String>,
316 },
317 Extract {
319 target: String,
321 #[arg(long)]
322 attr: Option<String>,
323 #[arg(long)]
325 llm: bool,
326 #[arg(long)]
328 question: Option<String>,
329 #[arg(long)]
331 schema_json: Option<std::path::PathBuf>,
332 },
333 Text { target: String },
335 Scroll {
337 #[arg(long)]
339 target: Option<String>,
340 #[arg(long, default_value_t = 0.0)]
341 delta_x: f64,
342 #[arg(long, default_value_t = 0.0)]
343 delta_y: f64,
344 },
345 Cookie {
347 #[command(subcommand)]
348 action: CookieAction,
349 },
350 Attr { target: String, name: String },
352 Assert {
354 #[command(subcommand)]
355 kind: AssertKind,
356 },
357 Console {
359 #[command(subcommand)]
360 action: ConsoleAction,
361 },
362 Net {
364 #[command(subcommand)]
365 action: NetAction,
366 },
367 Page {
369 #[command(subcommand)]
370 action: Option<PageAction>,
371 },
372 Dialog {
374 #[command(subcommand)]
375 action: DialogAction,
376 },
377 Scrape {
379 url: String,
380 #[arg(long, default_value = "text")]
382 format: String,
383 #[arg(long, default_value = "browser")]
385 engine: String,
386 #[arg(long)]
388 only_main_content: bool,
389 #[arg(long)]
391 webhook_url: Option<String>,
392 },
393 BatchScrape {
395 #[arg(long)]
396 urls_file: std::path::PathBuf,
397 #[arg(long, default_value = "text")]
398 format: String,
399 #[arg(long, default_value_t = 2)]
400 concurrency: usize,
401 },
402 Crawl {
404 url: String,
405 #[arg(long, default_value_t = 20)]
406 limit: usize,
407 #[arg(long, default_value_t = 2)]
408 max_depth: usize,
409 #[arg(long, default_value = "text")]
410 format: String,
411 #[arg(long, default_value_t = true)]
413 same_host: bool,
414 },
415 Map {
417 url: String,
418 #[arg(long, default_value_t = 50)]
419 limit: usize,
420 #[arg(long, default_value_t = 2)]
421 max_depth: usize,
422 },
423 Search {
425 query: String,
426 #[arg(long, default_value_t = 10)]
427 limit: usize,
428 },
429 Parse {
431 path: std::path::PathBuf,
432 #[arg(long)]
434 redact_pii: bool,
435 },
436 Qr {
438 #[command(subcommand)]
439 action: QrAction,
440 },
441 FindPaths {
443 pattern: Option<String>,
445 #[arg(num_args = 0..)]
447 paths: Vec<String>,
448 #[arg(long)]
450 extension: Option<String>,
451 #[arg(long)]
453 hidden: bool,
454 #[arg(long)]
456 no_ignore: bool,
457 #[arg(long)]
459 max_depth: Option<usize>,
460 #[arg(long = "type")]
462 entry_type: Option<String>,
463 #[arg(long, default_value_t = 10000)]
465 limit: usize,
466 #[arg(long)]
468 glob: Option<String>,
469 },
470 SgScan {
472 #[arg(num_args = 0..)]
474 paths: Vec<String>,
475 #[arg(long, default_value_t = 500)]
477 limit: usize,
478 },
479 SgRewrite {
481 #[arg(num_args = 0..)]
483 paths: Vec<String>,
484 #[arg(long)]
486 apply: bool,
487 },
488 SheetWrite {
490 input: std::path::PathBuf,
492 #[arg(long, short = 'o')]
494 out: std::path::PathBuf,
495 #[arg(long, default_value = "Sheet1")]
497 sheet: String,
498 },
499 Mitm {
501 #[command(subcommand)]
502 action: MitmAction,
503 },
504 Workflow {
506 #[command(subcommand)]
507 action: WorkflowAction,
508 },
509 Config {
511 #[command(subcommand)]
512 action: ConfigAction,
513 },
514 Emulate {
516 #[arg(long)]
517 user_agent: Option<String>,
518 #[arg(long)]
519 locale: Option<String>,
520 #[arg(long)]
521 timezone: Option<String>,
522 #[arg(long)]
523 offline: bool,
524 #[arg(long)]
525 latitude: Option<f64>,
526 #[arg(long)]
527 longitude: Option<f64>,
528 #[arg(long)]
529 media: Option<String>,
530 #[arg(long)]
532 network_conditions: Option<String>,
533 #[arg(long)]
535 cpu_throttling_rate: Option<f64>,
536 #[arg(long)]
538 color_scheme: Option<String>,
539 #[arg(long)]
541 extra_headers: Option<String>,
542 #[arg(long)]
544 viewport: Option<String>,
545 },
546 Resize {
548 #[arg(long)]
549 width: i32,
550 #[arg(long)]
551 height: i32,
552 #[arg(long, default_value_t = 1.0)]
553 scale: f64,
554 #[arg(long)]
555 mobile: bool,
556 },
557 Perf {
559 #[command(subcommand)]
560 action: PerfAction,
561 },
562 Lighthouse {
564 url: String,
565 #[arg(long)]
566 out_dir: Option<std::path::PathBuf>,
567 #[arg(long, default_value = "desktop")]
568 device: String,
569 #[arg(long, default_value = "navigation")]
571 mode: String,
572 #[arg(long)]
573 lighthouse_path: Option<std::path::PathBuf>,
574 },
575 Screencast {
577 #[command(subcommand)]
578 action: ScreencastAction,
579 },
580 Heap {
582 #[command(subcommand)]
583 action: HeapAction,
584 },
585 Extension {
587 #[command(subcommand)]
588 action: ExtensionAction,
589 },
590 Devtools3p {
592 #[command(subcommand)]
593 action: Devtools3pAction,
594 },
595 Webmcp {
597 #[command(subcommand)]
598 action: WebmcpAction,
599 },
600 Completions {
602 #[arg(value_enum)]
603 shell: CompletionShell,
604 },
605}
606
607#[derive(Debug, Clone, Subcommand)]
608pub enum PerfAction {
609 Start {
610 #[arg(long)]
611 path: Option<std::path::PathBuf>,
612 #[arg(long)]
613 reload: bool,
614 #[arg(long)]
616 auto_stop: bool,
617 },
618 Stop {
619 #[arg(long)]
620 path: Option<std::path::PathBuf>,
621 },
622 Insight {
623 #[arg(long)]
625 name: Option<String>,
626 #[arg(long)]
628 insight_set_id: Option<String>,
629 #[arg(long)]
631 insight_name: Option<String>,
632 },
633}
634
635#[derive(Debug, Clone, Subcommand)]
636pub enum ScreencastAction {
637 Start {
638 #[arg(long)]
639 path: Option<std::path::PathBuf>,
640 },
641 Stop {
642 #[arg(long)]
644 path: Option<std::path::PathBuf>,
645 },
646}
647
648#[derive(Debug, Clone, Subcommand)]
649pub enum HeapAction {
650 Take {
651 #[arg(long)]
652 path: std::path::PathBuf,
653 },
654 Close {
655 #[arg(long)]
656 path: std::path::PathBuf,
657 },
658 Compare {
659 #[arg(long)]
660 base: std::path::PathBuf,
661 #[arg(long)]
662 current: std::path::PathBuf,
663 #[arg(long)]
665 class_index: Option<u64>,
666 },
667 Summary {
668 #[arg(long)]
669 path: std::path::PathBuf,
670 },
671 Details {
672 #[arg(long)]
673 path: std::path::PathBuf,
674 #[arg(long)]
675 filter_name: Option<String>,
676 #[arg(long)]
677 page_idx: Option<usize>,
678 #[arg(long)]
679 page_size: Option<usize>,
680 },
681 ClassNodes {
682 #[arg(long)]
683 path: std::path::PathBuf,
684 #[arg(long)]
685 id: u64,
686 #[arg(long)]
687 filter_name: Option<String>,
688 #[arg(long)]
689 page_idx: Option<usize>,
690 #[arg(long)]
691 page_size: Option<usize>,
692 },
693 Dominators {
694 #[arg(long)]
695 path: std::path::PathBuf,
696 #[arg(long)]
697 node: u64,
698 },
699 DupStrings {
700 #[arg(long)]
701 path: std::path::PathBuf,
702 #[arg(long)]
703 page_idx: Option<usize>,
704 #[arg(long)]
705 page_size: Option<usize>,
706 },
707 Edges {
708 #[arg(long)]
709 path: std::path::PathBuf,
710 #[arg(long)]
711 node: u64,
712 #[arg(long)]
713 page_idx: Option<usize>,
714 #[arg(long)]
715 page_size: Option<usize>,
716 },
717 Retainers {
718 #[arg(long)]
719 path: std::path::PathBuf,
720 #[arg(long)]
721 node: u64,
722 #[arg(long)]
723 page_idx: Option<usize>,
724 #[arg(long)]
725 page_size: Option<usize>,
726 },
727 Paths {
728 #[arg(long)]
729 path: std::path::PathBuf,
730 #[arg(long)]
731 node: u64,
732 #[arg(long, default_value_t = 8)]
733 max_depth: u64,
734 #[arg(long)]
735 max_nodes: Option<u64>,
736 #[arg(long)]
737 max_siblings: Option<u64>,
738 },
739 ObjectDetails {
741 #[arg(long)]
742 path: std::path::PathBuf,
743 #[arg(long)]
744 node: u64,
745 },
746}
747
748#[derive(Debug, Clone, Subcommand)]
749pub enum ExtensionAction {
750 List,
751 Install {
752 path: std::path::PathBuf,
753 },
754 Reload {
755 id: String,
756 #[arg(long)]
758 path: Option<std::path::PathBuf>,
759 },
760 Trigger {
761 id: String,
762 #[arg(long)]
764 path: Option<std::path::PathBuf>,
765 },
766 Uninstall {
767 id: String,
768 },
769}
770
771#[derive(Debug, Clone, Subcommand)]
772pub enum Devtools3pAction {
773 List {
774 #[arg(long)]
776 url: Option<String>,
777 },
778 Exec {
779 name: String,
780 #[arg(long)]
781 params: Option<String>,
782 #[arg(long)]
783 url: Option<String>,
784 },
785}
786
787#[derive(Debug, Clone, Subcommand)]
788pub enum WebmcpAction {
789 List {
790 #[arg(long)]
791 url: Option<String>,
792 },
793 Exec {
794 name: String,
795 #[arg(long)]
796 input: Option<String>,
797 #[arg(long)]
798 url: Option<String>,
799 },
800}
801
802#[derive(Debug, Clone, Copy, ValueEnum)]
803pub enum CompletionShell {
804 Bash,
805 Zsh,
806 Fish,
807 Elvish,
808 Powershell,
809}
810
811#[derive(Debug, Clone, Subcommand)]
812pub enum QrAction {
813 Encode {
815 #[arg(long)]
816 text: String,
817 #[arg(long, default_value = "png")]
819 format: String,
820 #[arg(long)]
821 path: Option<std::path::PathBuf>,
822 },
823 Decode {
825 #[arg(long)]
826 path: std::path::PathBuf,
827 },
828}
829
830#[derive(Debug, Clone, Subcommand)]
831pub enum MonitorAction {
832 Check {
834 #[arg(long)]
836 url: String,
837 #[arg(long)]
839 baseline: std::path::PathBuf,
840 #[arg(long)]
842 write_baseline: bool,
843 #[arg(long, default_value = "http")]
845 engine: String,
846 },
847}
848
849#[derive(Debug, Clone, Subcommand)]
850pub enum PageAction {
851 Info,
853 List,
855 New {
857 #[arg(long)]
858 url: Option<String>,
859 #[arg(long)]
861 background: bool,
862 #[arg(long)]
864 isolated_context: bool,
865 },
866 Select {
868 #[arg(value_name = "INDEX")]
869 index: Option<usize>,
870 #[arg(long = "page-id")]
872 page_id: Option<usize>,
873 #[arg(long, default_value_t = true)]
875 bring_to_front: bool,
876 },
877 Close {
879 #[arg(long)]
880 index: Option<usize>,
881 #[arg(long = "page-id")]
883 page_id: Option<usize>,
884 },
885 TabId,
887}
888
889#[derive(Debug, Clone, Subcommand)]
890pub enum CookieAction {
891 List {
893 #[arg(long)]
894 url: Option<String>,
895 },
896 Set {
898 #[arg(long)]
900 json: String,
901 },
902 Clear,
904}
905
906#[derive(Debug, Clone, Copy, ValueEnum, Default)]
907pub enum GrabFormat {
908 #[default]
909 Png,
910 Jpeg,
911 Webp,
912}
913
914#[derive(Debug, Clone, Subcommand)]
915pub enum AssertKind {
916 Url {
917 value: String,
918 #[arg(long)]
919 contains: bool,
920 },
921 Text {
922 value: String,
923 #[arg(long)]
924 target: Option<String>,
925 },
926 Console {
927 #[arg(long, default_value = "error")]
928 level: String,
929 #[arg(long, default_value_t = 0)]
930 max: u64,
931 },
932}
933
934#[derive(Debug, Clone, Subcommand)]
935pub enum ConsoleAction {
936 List {
937 #[arg(long)]
939 page_idx: Option<usize>,
940 #[arg(long)]
942 page_size: Option<usize>,
943 #[arg(long)]
945 types: Option<String>,
946 #[arg(long)]
948 include_preserved: bool,
949 #[arg(long)]
951 service_worker_id: Option<String>,
952 },
953 Get {
954 id: usize,
955 },
956 Clear,
957 Dump {
958 #[arg(long)]
959 path: std::path::PathBuf,
960 },
961}
962
963#[derive(Debug, Clone, Subcommand)]
964pub enum NetAction {
965 List {
966 #[arg(long)]
968 page_idx: Option<usize>,
969 #[arg(long)]
971 page_size: Option<usize>,
972 #[arg(long)]
974 resource_types: Option<String>,
975 #[arg(long)]
977 include_preserved: bool,
978 },
979 Get {
980 id: String,
982 #[arg(long)]
983 request_path: Option<std::path::PathBuf>,
984 #[arg(long)]
985 response_path: Option<std::path::PathBuf>,
986 },
987}
988
989#[derive(Debug, Clone, Subcommand)]
990pub enum DialogAction {
991 Accept {
992 #[arg(long)]
993 text: Option<String>,
994 },
995 Dismiss,
996}
997
998#[derive(Debug, Clone, Subcommand)]
999pub enum MitmAction {
1000 Status,
1002 List {
1004 #[arg(long)]
1005 host: Option<String>,
1006 #[arg(long, default_value_t = 100)]
1007 limit: usize,
1008 },
1009 Get { id: u64 },
1011 Har {
1013 #[arg(long)]
1014 out: std::path::PathBuf,
1015 },
1016 Export {
1018 #[arg(long, default_value = "json")]
1019 format: String,
1020 #[arg(long)]
1021 out: std::path::PathBuf,
1022 },
1023 Domains,
1025 Apis {
1027 #[arg(long)]
1028 kind: Option<String>,
1029 },
1030 InitCa,
1032 Start {
1034 #[arg(long, default_value_t = 30)]
1036 seconds: u64,
1037 },
1038}
1039
1040#[derive(Debug, Clone, Subcommand)]
1041pub enum WorkflowAction {
1042 Run {
1044 #[arg(long)]
1045 manifest: std::path::PathBuf,
1046 #[arg(long)]
1047 journal: Option<std::path::PathBuf>,
1048 },
1049 Resume {
1051 #[arg(long)]
1052 manifest: std::path::PathBuf,
1053 #[arg(long)]
1054 journal: Option<std::path::PathBuf>,
1055 },
1056 Status {
1058 #[arg(long)]
1059 journal: Option<std::path::PathBuf>,
1060 #[arg(long)]
1061 name: Option<String>,
1062 },
1063}
1064
1065#[derive(Debug, Clone, Subcommand)]
1066pub enum ConfigAction {
1067 Path,
1069 Init,
1071 Show,
1073 Set { key: String, value: String },
1075 Get { key: Option<String> },
1077 ListKeys,
1079}