adspower-browser 2.0.0-beta.2 → 2.0.0-beta.3

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.
Files changed (3) hide show
  1. package/README.MD +29 -29
  2. package/cli/index.js +1104 -465
  3. package/package.json +2 -2
package/cli/index.js CHANGED
@@ -572,106 +572,772 @@ var PORT = config.port;
572
572
  var API_KEY = config.apiKey;
573
573
  var CONFIG = config;
574
574
 
575
+ // ../core/src/constants/localApiContracts.ts
576
+ var LOCAL_API_CONTRACTS = {
577
+ "check-status": {
578
+ method: "GET",
579
+ path: "/status",
580
+ params: {}
581
+ },
582
+ "get-application-list": {
583
+ method: "GET",
584
+ path: "/api/v2/category/list",
585
+ params: {
586
+ category_id: { apiName: "category_id", location: "query" },
587
+ page: { apiName: "page", location: "query" },
588
+ limit: { apiName: "limit", location: "query" }
589
+ }
590
+ },
591
+ "open-browser": {
592
+ method: "POST",
593
+ path: "/api/v2/browser-profile/start",
594
+ params: {
595
+ profile_id: { apiName: "profile_id", location: "body" },
596
+ profile_no: { apiName: "profile_no", location: "body" },
597
+ ip_tab: { apiName: "ip_tab", location: "body" },
598
+ launch_args: { apiName: "launch_args", location: "body" },
599
+ headless: { apiName: "headless", location: "body" },
600
+ last_opened_tabs: { apiName: "last_opened_tabs", location: "body" },
601
+ proxy_detection: { apiName: "proxy_detection", location: "body" },
602
+ password_filling: { apiName: "password_filling", location: "body" },
603
+ password_saving: { apiName: "password_saving", location: "body" },
604
+ cdp_mask: { apiName: "cdp_mask", location: "body" },
605
+ delete_cache: { apiName: "delete_cache", location: "body" },
606
+ device_scale: { apiName: "device_scale", location: "body" }
607
+ }
608
+ },
609
+ "close-browser": {
610
+ method: "POST",
611
+ path: "/api/v2/browser-profile/stop",
612
+ params: {
613
+ profile_id: { apiName: "profile_id", location: "body" },
614
+ profile_no: { apiName: "profile_no", location: "body" }
615
+ }
616
+ },
617
+ "create-browser": {
618
+ method: "POST",
619
+ path: "/api/v2/browser-profile/create",
620
+ params: {
621
+ group_id: { apiName: "group_id", location: "body" },
622
+ username: { apiName: "username", location: "body" },
623
+ password: { apiName: "password", location: "body" },
624
+ cookie: { apiName: "cookie", location: "body" },
625
+ fakey: { apiName: "fakey", location: "body" },
626
+ name: { apiName: "name", location: "body" },
627
+ platform: { apiName: "platform", location: "body" },
628
+ remark: { apiName: "remark", location: "body" },
629
+ user_proxy_config: { apiName: "user_proxy_config", location: "body" },
630
+ proxyid: { apiName: "proxyid", location: "body" },
631
+ repeat_config: { apiName: "repeat_config", location: "body" },
632
+ ignore_cookie_error: { apiName: "ignore_cookie_error", location: "body" },
633
+ tabs: { apiName: "tabs", location: "body" },
634
+ ip: { apiName: "ip", location: "body" },
635
+ country: { apiName: "country", location: "body" },
636
+ region: { apiName: "region", location: "body" },
637
+ city: { apiName: "city", location: "body" },
638
+ ipchecker: { apiName: "ipchecker", location: "body" },
639
+ category_id: { apiName: "category_id", location: "body" },
640
+ profile_tag_ids: { apiName: "profile_tag_ids", location: "body" },
641
+ fingerprint_config: { apiName: "fingerprint_config", location: "body" },
642
+ platform_account: { apiName: "platform_account", location: "body" }
643
+ }
644
+ },
645
+ "update-browser": {
646
+ method: "POST",
647
+ path: "/api/v2/browser-profile/update",
648
+ params: {
649
+ profile_id: { apiName: "profile_id", location: "body" },
650
+ group_id: { apiName: "group_id", location: "body" },
651
+ username: { apiName: "username", location: "body" },
652
+ password: { apiName: "password", location: "body" },
653
+ cookie: { apiName: "cookie", location: "body" },
654
+ fakey: { apiName: "fakey", location: "body" },
655
+ name: { apiName: "name", location: "body" },
656
+ platform: { apiName: "platform", location: "body" },
657
+ remark: { apiName: "remark", location: "body" },
658
+ user_proxy_config: { apiName: "user_proxy_config", location: "body" },
659
+ proxyid: { apiName: "proxyid", location: "body" },
660
+ repeat_config: { apiName: "repeat_config", location: "body" },
661
+ ignore_cookie_error: { apiName: "ignore_cookie_error", location: "body" },
662
+ tabs: { apiName: "tabs", location: "body" },
663
+ ip: { apiName: "ip", location: "body" },
664
+ country: { apiName: "country", location: "body" },
665
+ region: { apiName: "region", location: "body" },
666
+ city: { apiName: "city", location: "body" },
667
+ ipchecker: { apiName: "ipchecker", location: "body" },
668
+ category_id: { apiName: "category_id", location: "body" },
669
+ profile_tag_ids: { apiName: "profile_tag_ids", location: "body" },
670
+ fingerprint_config: { apiName: "fingerprint_config", location: "body" },
671
+ platform_account: { apiName: "platform_account", location: "body" },
672
+ launch_args: { apiName: "launch_args", location: "body" },
673
+ tags_update_type: { apiName: "tags_update_type", location: "body" }
674
+ }
675
+ },
676
+ "delete-browser": {
677
+ method: "POST",
678
+ path: "/api/v2/browser-profile/delete",
679
+ params: {
680
+ profile_id: { apiName: "profile_id", location: "body" }
681
+ }
682
+ },
683
+ "get-browser-list": {
684
+ method: "POST",
685
+ path: "/api/v2/browser-profile/list",
686
+ params: {
687
+ group_id: { apiName: "group_id", location: "body" },
688
+ limit: { apiName: "limit", location: "body" },
689
+ page: { apiName: "page", location: "body" },
690
+ profile_id: { apiName: "profile_id", location: "body" },
691
+ profile_no: { apiName: "profile_no", location: "body" },
692
+ sort_type: { apiName: "sort_type", location: "body" },
693
+ sort_order: { apiName: "sort_order", location: "body" },
694
+ tag_ids: { apiName: "tag_ids", location: "body" },
695
+ tags_filter: { apiName: "tags_filter", location: "body" },
696
+ name: { apiName: "name", location: "body" },
697
+ name_filter: { apiName: "name_filter", location: "body" }
698
+ }
699
+ },
700
+ "get-opened-browser": {
701
+ method: "GET",
702
+ path: "/api/v1/browser/local-active",
703
+ params: {}
704
+ },
705
+ "move-browser": {
706
+ method: "POST",
707
+ path: "/api/v1/user/regroup",
708
+ params: {
709
+ user_ids: { apiName: "user_ids", location: "body" },
710
+ group_id: { apiName: "group_id", location: "body" }
711
+ }
712
+ },
713
+ "get-profile-cookies": {
714
+ method: "GET",
715
+ path: "/api/v2/browser-profile/cookies",
716
+ params: {
717
+ profile_id: { apiName: "profile_id", location: "query" },
718
+ profile_no: { apiName: "profile_no", location: "query" }
719
+ }
720
+ },
721
+ "get-profile-ua": {
722
+ method: "POST",
723
+ path: "/api/v2/browser-profile/ua",
724
+ params: {
725
+ profile_id: { apiName: "profile_id", location: "body" },
726
+ profile_no: { apiName: "profile_no", location: "body" }
727
+ }
728
+ },
729
+ "close-all-profiles": {
730
+ method: "POST",
731
+ path: "/api/v2/browser-profile/stop-all",
732
+ params: {}
733
+ },
734
+ "new-fingerprint": {
735
+ method: "POST",
736
+ path: "/api/v2/browser-profile/new-fingerprint",
737
+ params: {
738
+ profile_id: { apiName: "profile_id", location: "body" },
739
+ profile_no: { apiName: "profile_no", location: "body" }
740
+ }
741
+ },
742
+ "delete-cache-v2": {
743
+ method: "POST",
744
+ path: "/api/v2/browser-profile/delete-cache",
745
+ params: {
746
+ profile_id: { apiName: "profile_id", location: "body" },
747
+ type: { apiName: "type", location: "body" }
748
+ }
749
+ },
750
+ "share-profile": {
751
+ method: "POST",
752
+ path: "/api/v2/browser-profile/share",
753
+ params: {
754
+ profile_id: { apiName: "profile_id", location: "body" },
755
+ receiver: { apiName: "receiver", location: "body" },
756
+ share_type: { apiName: "share_type", location: "body" },
757
+ content: { apiName: "content", location: "body" }
758
+ }
759
+ },
760
+ "get-browser-active": {
761
+ method: "GET",
762
+ path: "/api/v2/browser-profile/active",
763
+ params: {
764
+ profile_id: { apiName: "profile_id", location: "query" },
765
+ profile_no: { apiName: "profile_no", location: "query" }
766
+ }
767
+ },
768
+ "get-cloud-active": {
769
+ method: "POST",
770
+ path: "/api/v1/browser/cloud-active",
771
+ params: {
772
+ user_ids: { apiName: "user_ids", location: "body" }
773
+ }
774
+ },
775
+ "create-group": {
776
+ method: "POST",
777
+ path: "/api/v1/group/create",
778
+ params: {
779
+ group_name: { apiName: "group_name", location: "body" },
780
+ remark: { apiName: "remark", location: "body" }
781
+ }
782
+ },
783
+ "update-group": {
784
+ method: "POST",
785
+ path: "/api/v1/group/update",
786
+ params: {
787
+ group_id: { apiName: "group_id", location: "body" },
788
+ group_name: { apiName: "group_name", location: "body" },
789
+ remark: { apiName: "remark", location: "body" }
790
+ }
791
+ },
792
+ "get-group-list": {
793
+ method: "GET",
794
+ path: "/api/v1/group/list",
795
+ params: {
796
+ group_name: { apiName: "group_name", location: "query" },
797
+ page: { apiName: "page", location: "query" },
798
+ page_size: { apiName: "page_size", location: "query" }
799
+ }
800
+ },
801
+ "create-proxy": {
802
+ method: "POST",
803
+ path: "/api/v2/proxy-list/create",
804
+ params: {},
805
+ bodyShape: "array"
806
+ },
807
+ "update-proxy": {
808
+ method: "POST",
809
+ path: "/api/v2/proxy-list/update",
810
+ params: {
811
+ proxy_id: { apiName: "proxy_id", location: "body" },
812
+ type: { apiName: "type", location: "body" },
813
+ host: { apiName: "host", location: "body" },
814
+ port: { apiName: "port", location: "body" },
815
+ user: { apiName: "user", location: "body" },
816
+ password: { apiName: "password", location: "body" },
817
+ proxy_url: { apiName: "proxy_url", location: "body" },
818
+ remark: { apiName: "remark", location: "body" },
819
+ ipchecker: { apiName: "ipchecker", location: "body" }
820
+ }
821
+ },
822
+ "get-proxy-list": {
823
+ method: "POST",
824
+ path: "/api/v2/proxy-list/list",
825
+ params: {
826
+ proxy_id: { apiName: "proxy_id", location: "body" },
827
+ limit: { apiName: "limit", location: "body" },
828
+ page: { apiName: "page", location: "body" }
829
+ }
830
+ },
831
+ "delete-proxy": {
832
+ method: "POST",
833
+ path: "/api/v2/proxy-list/delete",
834
+ params: {
835
+ proxy_id: { apiName: "proxy_id", location: "body" }
836
+ }
837
+ },
838
+ "get-tag-list": {
839
+ method: "POST",
840
+ path: "/api/v2/browser-tags/list",
841
+ params: {
842
+ ids: { apiName: "ids", location: "body" },
843
+ page: { apiName: "page", location: "body" },
844
+ limit: { apiName: "limit", location: "body" }
845
+ }
846
+ },
847
+ "create-tag": {
848
+ method: "POST",
849
+ path: "/api/v2/browser-tags/create",
850
+ params: {
851
+ tags: { apiName: "tags", location: "body" }
852
+ }
853
+ },
854
+ "update-tag": {
855
+ method: "POST",
856
+ path: "/api/v2/browser-tags/update",
857
+ params: {
858
+ tags: { apiName: "tags", location: "body" }
859
+ }
860
+ },
861
+ "delete-tag": {
862
+ method: "POST",
863
+ path: "/api/v2/browser-tags/delete",
864
+ params: {
865
+ ids: { apiName: "ids", location: "body" }
866
+ }
867
+ },
868
+ "download-kernel": {
869
+ method: "POST",
870
+ path: "/api/v2/browser-profile/download-kernel",
871
+ params: {
872
+ kernel_type: { apiName: "kernel_type", location: "body" },
873
+ kernel_version: { apiName: "kernel_version", location: "body" }
874
+ }
875
+ },
876
+ "get-kernel-list": {
877
+ method: "GET",
878
+ path: "/api/v2/browser-profile/kernels",
879
+ params: {
880
+ kernel_type: { apiName: "kernel_type", location: "query" }
881
+ }
882
+ },
883
+ "update-patch": {
884
+ method: "POST",
885
+ path: "/api/v2/browser-profile/update-patch",
886
+ params: {
887
+ version_type: { apiName: "version_type", location: "body" }
888
+ }
889
+ }
890
+ };
891
+
575
892
  // ../core/src/constants/api.ts
893
+ function readLocalApiMinIntervalMs() {
894
+ const raw = process.env.ADSP_LOCAL_API_MIN_INTERVAL_MS?.trim() ?? "";
895
+ if (!raw) {
896
+ return 0;
897
+ }
898
+ const n = Number(raw);
899
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
900
+ }
901
+ var localApiThrottleLock = Promise.resolve();
902
+ var localApiLastRequestStartMs = 0;
903
+ async function sleep(ms) {
904
+ await new Promise((resolve) => {
905
+ setTimeout(resolve, ms);
906
+ });
907
+ }
908
+ async function throttleLocalApiRequest() {
909
+ const gapMs = readLocalApiMinIntervalMs();
910
+ if (gapMs <= 0) {
911
+ return;
912
+ }
913
+ const prev = localApiThrottleLock;
914
+ let release;
915
+ localApiThrottleLock = new Promise((resolve) => {
916
+ release = resolve;
917
+ });
918
+ await prev;
919
+ try {
920
+ const now = Date.now();
921
+ const earliest = localApiLastRequestStartMs === 0 ? now : localApiLastRequestStartMs + gapMs;
922
+ const waitMs = Math.max(0, earliest - now);
923
+ if (waitMs > 0) {
924
+ await sleep(waitMs);
925
+ }
926
+ localApiLastRequestStartMs = Date.now();
927
+ } finally {
928
+ release();
929
+ }
930
+ }
931
+ function isLocalApiRequestUrl(url) {
932
+ if (!url) {
933
+ return false;
934
+ }
935
+ try {
936
+ const u = new URL(url, "http://127.0.0.1");
937
+ return u.hostname === "127.0.0.1" || u.hostname === "localhost";
938
+ } catch {
939
+ return url.includes("127.0.0.1") || url.includes("localhost");
940
+ }
941
+ }
576
942
  var LOCAL_API_BASE = `http://127.0.0.1:${PORT}`;
577
943
  var getLocalApiBase = () => {
578
944
  return `http://127.0.0.1:${CONFIG.port}`;
579
945
  };
580
946
  var API_ENDPOINTS = {
581
947
  STATUS: "/status",
582
- START_BROWSER: "/api/v2/browser-profile/start",
583
- CLOSE_BROWSER: "/api/v2/browser-profile/stop",
584
- CREATE_BROWSER: "/api/v2/browser-profile/create",
585
- GET_BROWSER_LIST: "/api/v2/browser-profile/list",
586
- UPDATE_BROWSER: "/api/v2/browser-profile/update",
587
- DELETE_BROWSER: "/api/v2/browser-profile/delete",
588
- GET_PROFILE_COOKIES: "/api/v2/browser-profile/cookies",
589
- GET_PROFILE_UA: "/api/v2/browser-profile/ua",
590
- CLOSE_ALL_PROFILES: "/api/v2/browser-profile/stop-all",
591
- NEW_FINGERPRINT: "/api/v2/browser-profile/new-fingerprint",
592
- DELETE_CACHE_V2: "/api/v2/browser-profile/delete-cache",
593
- SHARE_PROFILE: "/api/v2/browser-profile/share",
594
- GET_BROWSER_ACTIVE: "/api/v2/browser-profile/active",
595
- CREATE_PROXY: "/api/v2/proxy-list/create",
596
- UPDATE_PROXY: "/api/v2/proxy-list/update",
597
- GET_PROXY_LIST: "/api/v2/proxy-list/list",
598
- DELETE_PROXY: "/api/v2/proxy-list/delete",
599
- GET_OPENED_BROWSER: "/api/v1/browser/local-active",
600
- GET_CLOUD_ACTIVE: "/api/v1/browser/cloud-active",
601
- MOVE_BROWSER: "/api/v1/user/regroup",
602
- GET_GROUP_LIST: "/api/v1/group/list",
603
- CREATE_GROUP: "/api/v1/group/create",
604
- UPDATE_GROUP: "/api/v1/group/update",
605
- GET_APPLICATION_LIST: "/api/v2/category/list",
606
- GET_TAG_LIST: "/api/v2/browser-tags/list",
607
- CREATE_TAG: "/api/v2/browser-tags/create",
608
- UPDATE_TAG: "/api/v2/browser-tags/update",
609
- DELETE_TAG: "/api/v2/browser-tags/delete",
610
- DOWNLOAD_KERNEL: "/api/v2/browser-profile/download-kernel",
611
- GET_KERNEL_LIST: "/api/v2/browser-profile/kernels",
612
- UPDATE_PATCH: "/api/v2/browser-profile/update-patch"
948
+ START_BROWSER: LOCAL_API_CONTRACTS["open-browser"].path,
949
+ CLOSE_BROWSER: LOCAL_API_CONTRACTS["close-browser"].path,
950
+ CREATE_BROWSER: LOCAL_API_CONTRACTS["create-browser"].path,
951
+ GET_BROWSER_LIST: LOCAL_API_CONTRACTS["get-browser-list"].path,
952
+ UPDATE_BROWSER: LOCAL_API_CONTRACTS["update-browser"].path,
953
+ DELETE_BROWSER: LOCAL_API_CONTRACTS["delete-browser"].path,
954
+ GET_PROFILE_COOKIES: LOCAL_API_CONTRACTS["get-profile-cookies"].path,
955
+ GET_PROFILE_UA: LOCAL_API_CONTRACTS["get-profile-ua"].path,
956
+ CLOSE_ALL_PROFILES: LOCAL_API_CONTRACTS["close-all-profiles"].path,
957
+ NEW_FINGERPRINT: LOCAL_API_CONTRACTS["new-fingerprint"].path,
958
+ DELETE_CACHE_V2: LOCAL_API_CONTRACTS["delete-cache-v2"].path,
959
+ SHARE_PROFILE: LOCAL_API_CONTRACTS["share-profile"].path,
960
+ GET_BROWSER_ACTIVE: LOCAL_API_CONTRACTS["get-browser-active"].path,
961
+ CREATE_PROXY: LOCAL_API_CONTRACTS["create-proxy"].path,
962
+ UPDATE_PROXY: LOCAL_API_CONTRACTS["update-proxy"].path,
963
+ GET_PROXY_LIST: LOCAL_API_CONTRACTS["get-proxy-list"].path,
964
+ DELETE_PROXY: LOCAL_API_CONTRACTS["delete-proxy"].path,
965
+ GET_OPENED_BROWSER: LOCAL_API_CONTRACTS["get-opened-browser"].path,
966
+ GET_CLOUD_ACTIVE: LOCAL_API_CONTRACTS["get-cloud-active"].path,
967
+ MOVE_BROWSER: LOCAL_API_CONTRACTS["move-browser"].path,
968
+ GET_GROUP_LIST: LOCAL_API_CONTRACTS["get-group-list"].path,
969
+ CREATE_GROUP: LOCAL_API_CONTRACTS["create-group"].path,
970
+ UPDATE_GROUP: LOCAL_API_CONTRACTS["update-group"].path,
971
+ GET_APPLICATION_LIST: LOCAL_API_CONTRACTS["get-application-list"].path,
972
+ GET_TAG_LIST: LOCAL_API_CONTRACTS["get-tag-list"].path,
973
+ CREATE_TAG: LOCAL_API_CONTRACTS["create-tag"].path,
974
+ UPDATE_TAG: LOCAL_API_CONTRACTS["update-tag"].path,
975
+ DELETE_TAG: LOCAL_API_CONTRACTS["delete-tag"].path,
976
+ DOWNLOAD_KERNEL: LOCAL_API_CONTRACTS["download-kernel"].path,
977
+ GET_KERNEL_LIST: LOCAL_API_CONTRACTS["get-kernel-list"].path,
978
+ UPDATE_PATCH: LOCAL_API_CONTRACTS["update-patch"].path
613
979
  };
614
980
  var apiClient = import_axios.default.create({
615
981
  headers: API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {}
616
982
  });
617
983
  var getApiClient = () => {
618
- return import_axios.default.create({
984
+ const client = import_axios.default.create({
619
985
  headers: CONFIG.apiKey ? { "Authorization": `Bearer ${CONFIG.apiKey}` } : {}
620
986
  });
987
+ client.interceptors.request.use(async (config2) => {
988
+ if (isLocalApiRequestUrl(config2.url)) {
989
+ await throttleLocalApiRequest();
990
+ }
991
+ return config2;
992
+ });
993
+ return client;
994
+ };
995
+
996
+ // ../core/src/constants/toolIntentMetadata.ts
997
+ var TOOL_INTENT_BY_NAME = {
998
+ "open-browser": {
999
+ intentEn: "Start an existing AdsPower browser profile (launch the profile browser).",
1000
+ intentZh: "\u542F\u52A8\u5DF2\u5B58\u5728\u7684 AdsPower \u6D4F\u89C8\u5668\u73AF\u5883\uFF08\u7528\u6237\u5E38\u79F0\u73AF\u5883\u3001\u914D\u7F6E\u6587\u4EF6\u3001profile\uFF09\u3002",
1001
+ triggersEn: "open browser, launch profile, start environment, open AdsPower, open config profile",
1002
+ triggersZh: "\u6253\u5F00\u6D4F\u89C8\u5668,\u542F\u52A8\u73AF\u5883,\u6253\u5F00\u914D\u7F6E,\u6253\u5F00\u914D\u7F6E\u6587\u4EF6,\u6253\u5F00profile,\u62C9\u8D77AdsPower,\u542F\u52A8\u6307\u7EB9\u6D4F\u89C8\u5668"
1003
+ },
1004
+ "close-browser": {
1005
+ intentEn: "Stop a running AdsPower browser profile.",
1006
+ intentZh: "\u5173\u95ED\u6B63\u5728\u8FD0\u884C\u7684\u6D4F\u89C8\u5668\u73AF\u5883 / profile\u3002",
1007
+ triggersEn: "close browser, stop profile, shutdown environment, kill browser",
1008
+ triggersZh: "\u5173\u95ED\u6D4F\u89C8\u5668,\u505C\u6B62\u73AF\u5883,\u5173\u6389profile,\u7ED3\u675F\u6D4F\u89C8\u5668,\u9000\u51FA\u6307\u7EB9\u73AF\u5883"
1009
+ },
1010
+ "create-browser": {
1011
+ intentEn: "Create a new AdsPower browser profile (account).",
1012
+ intentZh: "\u65B0\u5EFA\u6D4F\u89C8\u5668\u73AF\u5883 / \u8D26\u53F7 profile\u3002",
1013
+ triggersEn: "create profile, new browser, add account, spin up profile",
1014
+ triggersZh: "\u65B0\u5EFA\u73AF\u5883,\u521B\u5EFAprofile,\u6DFB\u52A0\u6D4F\u89C8\u5668,\u65B0\u5F00\u6307\u7EB9,\u521B\u5EFA\u8D26\u53F7"
1015
+ },
1016
+ "update-browser": {
1017
+ intentEn: "Update fields of an existing browser profile.",
1018
+ intentZh: "\u66F4\u65B0\u5DF2\u6709 profile \u7684\u914D\u7F6E\uFF08\u5907\u6CE8\u3001\u4EE3\u7406\u3001\u6307\u7EB9\u7B49\uFF09\u3002",
1019
+ triggersEn: "edit profile, change settings, modify browser, update fingerprint",
1020
+ triggersZh: "\u4FEE\u6539\u914D\u7F6E,\u66F4\u65B0profile,\u6539\u4EE3\u7406,\u6539\u6307\u7EB9,\u7F16\u8F91\u73AF\u5883"
1021
+ },
1022
+ "delete-browser": {
1023
+ intentEn: "Delete one or more browser profiles permanently.",
1024
+ intentZh: "\u6C38\u4E45\u5220\u9664\u4E00\u4E2A\u6216\u591A\u4E2A\u6D4F\u89C8\u5668 profile\u3002",
1025
+ triggersEn: "remove profile, delete account, trash browser",
1026
+ triggersZh: "\u5220\u9664\u73AF\u5883,\u79FB\u9664profile,\u5220\u6389\u6D4F\u89C8\u5668\u8D26\u53F7"
1027
+ },
1028
+ "get-browser-list": {
1029
+ intentEn: "List or search browser profiles (pagination, filters).",
1030
+ intentZh: "\u5206\u9875/\u6761\u4EF6\u67E5\u8BE2\u6D4F\u89C8\u5668 profile \u5217\u8868\u3002",
1031
+ triggersEn: "list profiles, search browsers, query accounts, show all profiles",
1032
+ triggersZh: "\u5217\u8868,\u67E5\u8BE2\u73AF\u5883,\u641C\u7D22profile,\u5217\u51FA\u6240\u6709\u6D4F\u89C8\u5668"
1033
+ },
1034
+ "get-opened-browser": {
1035
+ intentEn: "List browser profiles currently open on this device.",
1036
+ intentZh: "\u67E5\u770B\u672C\u673A\u5F53\u524D\u5DF2\u6253\u5F00\u7684\u6D4F\u89C8\u5668 profile\u3002",
1037
+ triggersEn: "opened browsers, running profiles, active local sessions",
1038
+ triggersZh: "\u5DF2\u6253\u5F00,\u6B63\u5728\u8FD0\u884C,\u5F53\u524D\u4F1A\u8BDD,\u672C\u5730\u6D3B\u8DC3"
1039
+ },
1040
+ "move-browser": {
1041
+ intentEn: "Move profiles to another group (regroup).",
1042
+ intentZh: "\u5C06 profile \u79FB\u52A8\u5230\u6307\u5B9A\u5206\u7EC4\u3002",
1043
+ triggersEn: "move to group, regroup profiles, change group",
1044
+ triggersZh: "\u79FB\u52A8\u5206\u7EC4,\u6362\u7EC4,\u5F52\u7C7B\u5230\u7EC4"
1045
+ },
1046
+ "get-profile-cookies": {
1047
+ intentEn: "Read cookies for one profile.",
1048
+ intentZh: "\u8BFB\u53D6\u5355\u4E2A profile \u7684 Cookie\u3002",
1049
+ triggersEn: "get cookies, export cookies, read cookie jar",
1050
+ triggersZh: "\u5BFC\u51FACookie,\u67E5\u770BCookie,\u8BFB\u53D6\u7AD9\u70B9Cookie"
1051
+ },
1052
+ "get-profile-ua": {
1053
+ intentEn: "Get User-Agent strings for up to 10 profiles.",
1054
+ intentZh: "\u6279\u91CF\u67E5\u8BE2\u6700\u591A 10 \u4E2A profile \u7684 UA\u3002",
1055
+ triggersEn: "user agent, UA string, browser UA",
1056
+ triggersZh: "UA,\u7528\u6237\u4EE3\u7406,\u6D4F\u89C8\u5668\u6807\u8BC6"
1057
+ },
1058
+ "close-all-profiles": {
1059
+ intentEn: "Close all opened profiles on this device.",
1060
+ intentZh: "\u5173\u95ED\u672C\u673A\u6240\u6709\u5DF2\u6253\u5F00\u7684\u73AF\u5883\u3002",
1061
+ triggersEn: "close everything, stop all browsers, shutdown all profiles",
1062
+ triggersZh: "\u5168\u90E8\u5173\u95ED,\u4E00\u952E\u5173\u73AF\u5883,\u5173\u6240\u6709\u6D4F\u89C8\u5668"
1063
+ },
1064
+ "new-fingerprint": {
1065
+ intentEn: "Generate a new fingerprint for up to 10 profiles.",
1066
+ intentZh: "\u4E3A\u6700\u591A 10 \u4E2A profile \u91CD\u65B0\u751F\u6210\u6307\u7EB9\u3002",
1067
+ triggersEn: "refresh fingerprint, regenerate fp, new device identity",
1068
+ triggersZh: "\u5237\u65B0\u6307\u7EB9,\u91CD\u65B0\u6307\u7EB9,\u6362\u8BBE\u5907\u6307\u7EB9"
1069
+ },
1070
+ "delete-cache-v2": {
1071
+ intentEn: "Clear selected local cache types for profiles.",
1072
+ intentZh: "\u6309\u7C7B\u578B\u6E05\u7406 profile \u672C\u5730\u7F13\u5B58\u3002",
1073
+ triggersEn: "clear cache, wipe storage, delete history cache",
1074
+ triggersZh: "\u6E05\u7F13\u5B58,\u5220\u5386\u53F2,\u6E05\u7406\u672C\u5730\u6570\u636E"
1075
+ },
1076
+ "share-profile": {
1077
+ intentEn: "Share profiles to another AdsPower account.",
1078
+ intentZh: "\u5C06 profile \u5206\u4EAB\u7ED9\u5176\u4ED6 AdsPower \u8D26\u53F7\u3002",
1079
+ triggersEn: "share account, transfer profile, send browser to user",
1080
+ triggersZh: "\u5206\u4EAB\u73AF\u5883,\u8F6C\u8BA9profile,\u53D1\u7ED9\u540C\u4E8B"
1081
+ },
1082
+ "get-browser-active": {
1083
+ intentEn: "Get active status/details for one profile.",
1084
+ intentZh: "\u67E5\u8BE2\u5355\u4E2A profile \u7684\u6D3B\u8DC3/\u8FD0\u884C\u4FE1\u606F\u3002",
1085
+ triggersEn: "is profile running, active status, browser state",
1086
+ triggersZh: "\u662F\u5426\u5728\u7EBF,\u6D3B\u8DC3\u72B6\u6001,\u8FD0\u884C\u4FE1\u606F"
1087
+ },
1088
+ "get-cloud-active": {
1089
+ intentEn: "Query cloud-side active status for many profile IDs.",
1090
+ intentZh: "\u6309 user_ids \u6279\u91CF\u67E5\u8BE2\u4E91\u7AEF\u6D3B\u8DC3\u72B6\u6001\u3002",
1091
+ triggersEn: "cloud status, remote active, team multi device caveat",
1092
+ triggersZh: "\u4E91\u7AEF\u72B6\u6001,\u8FDC\u7A0B\u662F\u5426\u6253\u5F00,\u591A\u8BBE\u5907\u6A21\u5F0F\u9650\u5236"
1093
+ },
1094
+ "create-group": {
1095
+ intentEn: "Create a browser profile group.",
1096
+ intentZh: "\u65B0\u5EFA\u6D4F\u89C8\u5668\u5206\u7EC4\u3002",
1097
+ triggersEn: "new group, add folder for profiles",
1098
+ triggersZh: "\u65B0\u5EFA\u5206\u7EC4,\u521B\u5EFA\u7EC4,\u73AF\u5883\u5206\u7EC4"
1099
+ },
1100
+ "update-group": {
1101
+ intentEn: "Rename or update a group.",
1102
+ intentZh: "\u91CD\u547D\u540D\u6216\u66F4\u65B0\u5206\u7EC4\u4FE1\u606F\u3002",
1103
+ triggersEn: "rename group, edit group",
1104
+ triggersZh: "\u6539\u7EC4\u540D,\u66F4\u65B0\u5206\u7EC4"
1105
+ },
1106
+ "get-group-list": {
1107
+ intentEn: "List groups with optional name search.",
1108
+ intentZh: "\u5206\u9875\u67E5\u8BE2\u5206\u7EC4\u5217\u8868\uFF0C\u53EF\u6309\u540D\u79F0\u641C\u7D22\u3002",
1109
+ triggersEn: "list groups, search group name",
1110
+ triggersZh: "\u5206\u7EC4\u5217\u8868,\u67E5\u7EC4\u540D"
1111
+ },
1112
+ "check-status": {
1113
+ intentEn: "Check Local API availability on this machine.",
1114
+ intentZh: "\u68C0\u6D4B\u672C\u673A Local API \u662F\u5426\u53EF\u7528\u3002",
1115
+ triggersEn: "API health, connection status, ping AdsPower API",
1116
+ triggersZh: "\u63A5\u53E3\u901A\u4E0D\u901A,\u68C0\u6D4BAPI,\u8FDE\u63A5\u72B6\u6001"
1117
+ },
1118
+ "get-application-list": {
1119
+ intentEn: "List application/extension categories with pagination.",
1120
+ intentZh: "\u5206\u9875\u83B7\u53D6\u5E94\u7528/\u6269\u5C55\u5206\u7C7B\u5217\u8868\u3002",
1121
+ triggersEn: "categories, extension list, application catalog",
1122
+ triggersZh: "\u5E94\u7528\u5206\u7C7B,\u6269\u5C55\u76EE\u5F55,\u7C7B\u522B\u5217\u8868"
1123
+ },
1124
+ "create-proxy": {
1125
+ intentEn: "Create one or more proxy entries.",
1126
+ intentZh: "\u65B0\u5EFA\u4E00\u6761\u6216\u591A\u6761\u4EE3\u7406\u914D\u7F6E\u3002",
1127
+ triggersEn: "add proxy, new proxy row",
1128
+ triggersZh: "\u6DFB\u52A0\u4EE3\u7406,\u65B0\u5EFA\u4EE3\u7406"
1129
+ },
1130
+ "update-proxy": {
1131
+ intentEn: "Update an existing proxy entry.",
1132
+ intentZh: "\u66F4\u65B0\u5DF2\u6709\u4EE3\u7406\u9879\u3002",
1133
+ triggersEn: "edit proxy, change proxy host",
1134
+ triggersZh: "\u4FEE\u6539\u4EE3\u7406,\u66F4\u65B0\u4EE3\u7406"
1135
+ },
1136
+ "get-proxy-list": {
1137
+ intentEn: "List proxies with filters/pagination.",
1138
+ intentZh: "\u5206\u9875/\u6761\u4EF6\u67E5\u8BE2\u4EE3\u7406\u5217\u8868\u3002",
1139
+ triggersEn: "list proxies, search proxy",
1140
+ triggersZh: "\u4EE3\u7406\u5217\u8868,\u67E5\u4EE3\u7406"
1141
+ },
1142
+ "delete-proxy": {
1143
+ intentEn: "Delete proxies by id list.",
1144
+ intentZh: "\u6309 ID \u5217\u8868\u5220\u9664\u4EE3\u7406\u3002",
1145
+ triggersEn: "remove proxy, delete proxy entries",
1146
+ triggersZh: "\u5220\u9664\u4EE3\u7406,\u79FB\u9664\u4EE3\u7406"
1147
+ },
1148
+ "get-tag-list": {
1149
+ intentEn: "List browser tags.",
1150
+ intentZh: "\u67E5\u8BE2\u6D4F\u89C8\u5668\u6807\u7B7E\u5217\u8868\u3002",
1151
+ triggersEn: "list tags, label list",
1152
+ triggersZh: "\u6807\u7B7E\u5217\u8868,\u67E5\u770B\u6807\u7B7E"
1153
+ },
1154
+ "create-tag": {
1155
+ intentEn: "Create tags (batch).",
1156
+ intentZh: "\u6279\u91CF\u521B\u5EFA\u6807\u7B7E\u3002",
1157
+ triggersEn: "new tag, add label",
1158
+ triggersZh: "\u65B0\u5EFA\u6807\u7B7E,\u6DFB\u52A0\u6807\u7B7E"
1159
+ },
1160
+ "update-tag": {
1161
+ intentEn: "Update existing tags (batch).",
1162
+ intentZh: "\u6279\u91CF\u66F4\u65B0\u6807\u7B7E\u3002",
1163
+ triggersEn: "rename tag, change tag color",
1164
+ triggersZh: "\u6539\u6807\u7B7E\u540D,\u6539\u989C\u8272"
1165
+ },
1166
+ "delete-tag": {
1167
+ intentEn: "Delete tags by id list.",
1168
+ intentZh: "\u6309 ID \u5220\u9664\u6807\u7B7E\u3002",
1169
+ triggersEn: "remove tags",
1170
+ triggersZh: "\u5220\u9664\u6807\u7B7E"
1171
+ },
1172
+ "download-kernel": {
1173
+ intentEn: "Download or update a browser kernel version.",
1174
+ intentZh: "\u4E0B\u8F7D\u6216\u66F4\u65B0\u6307\u5B9A\u5185\u6838\u7248\u672C\u3002",
1175
+ triggersEn: "download chrome kernel, fetch firefox kernel",
1176
+ triggersZh: "\u4E0B\u8F7D\u5185\u6838,\u66F4\u65B0Chrome\u5185\u6838"
1177
+ },
1178
+ "get-kernel-list": {
1179
+ intentEn: "List supported kernel versions (optional type filter).",
1180
+ intentZh: "\u67E5\u8BE2\u652F\u6301\u7684\u5185\u6838\u7248\u672C\u5217\u8868\u3002",
1181
+ triggersEn: "kernel versions, supported browsers list",
1182
+ triggersZh: "\u5185\u6838\u5217\u8868,\u53EF\u7528\u7248\u672C"
1183
+ },
1184
+ "update-patch": {
1185
+ intentEn: "Update AdsPower client patch channel.",
1186
+ intentZh: "\u5C06 AdsPower \u5BA2\u6237\u7AEF\u66F4\u65B0\u5230\u8865\u4E01\u901A\u9053\u7248\u672C\u3002",
1187
+ triggersEn: "upgrade client, patch update, stable beta channel",
1188
+ triggersZh: "\u5347\u7EA7\u5BA2\u6237\u7AEF,\u8865\u4E01\u66F4\u65B0,\u7A33\u5B9A\u7248\u6D4B\u8BD5\u7248"
1189
+ },
1190
+ "connect-browser-with-ws": {
1191
+ intentEn: "Attach Playwright automation using ws from open-browser.",
1192
+ intentZh: "\u7528 open-browser \u8FD4\u56DE\u7684 ws \u8FDE\u63A5\u81EA\u52A8\u5316\uFF08Playwright\uFF09\u3002",
1193
+ triggersEn: "connect puppeteer, attach playwright, ws automation",
1194
+ triggersZh: "\u8FDE\u63A5\u81EA\u52A8\u5316,\u6302\u4E0APlaywright,\u7528ws\u63A7\u5236"
1195
+ },
1196
+ "open-new-page": {
1197
+ intentEn: "Open a new page in the connected automation session.",
1198
+ intentZh: "\u5728\u5DF2\u8FDE\u63A5\u4F1A\u8BDD\u4E2D\u6253\u5F00\u65B0\u6807\u7B7E\u9875/\u9875\u9762\u3002",
1199
+ triggersEn: "new tab, new page",
1200
+ triggersZh: "\u65B0\u6807\u7B7E\u9875,\u65B0\u9875\u9762"
1201
+ },
1202
+ "navigate": {
1203
+ intentEn: "Navigate current automation page to a URL.",
1204
+ intentZh: "\u81EA\u52A8\u5316\u5F53\u524D\u9875\u8DF3\u8F6C\u5230 URL\u3002",
1205
+ triggersEn: "goto url, open url in automation",
1206
+ triggersZh: "\u8DF3\u8F6C\u7F51\u5740,\u6253\u5F00\u94FE\u63A5"
1207
+ },
1208
+ "screenshot": {
1209
+ intentEn: "Capture screenshot of the automation page.",
1210
+ intentZh: "\u622A\u53D6\u81EA\u52A8\u5316\u5F53\u524D\u9875\u9762\u622A\u56FE\u3002",
1211
+ triggersEn: "screenshot, capture page image",
1212
+ triggersZh: "\u622A\u56FE,\u622A\u5C4F"
1213
+ },
1214
+ "get-page-visible-text": {
1215
+ intentEn: "Read visible text of the current page.",
1216
+ intentZh: "\u8BFB\u53D6\u5F53\u524D\u9875\u53EF\u89C1\u6587\u672C\u3002",
1217
+ triggersEn: "visible text, page text content",
1218
+ triggersZh: "\u53EF\u89C1\u6587\u5B57,\u9875\u9762\u6587\u672C"
1219
+ },
1220
+ "get-page-html": {
1221
+ intentEn: "Read HTML of the current page.",
1222
+ intentZh: "\u8BFB\u53D6\u5F53\u524D\u9875 HTML\u3002",
1223
+ triggersEn: "page source, dom html",
1224
+ triggersZh: "\u7F51\u9875\u6E90\u7801,HTML"
1225
+ },
1226
+ "click-element": {
1227
+ intentEn: "Click an element by selector in automation session.",
1228
+ intentZh: "\u5728\u81EA\u52A8\u5316\u4F1A\u8BDD\u4E2D\u6309\u9009\u62E9\u5668\u70B9\u51FB\u5143\u7D20\u3002",
1229
+ triggersEn: "click button, tap element",
1230
+ triggersZh: "\u70B9\u51FB\u6309\u94AE,\u70B9\u5143\u7D20"
1231
+ },
1232
+ "fill-input": {
1233
+ intentEn: "Fill an input field by selector.",
1234
+ intentZh: "\u6309\u9009\u62E9\u5668\u586B\u5199\u8F93\u5165\u6846\u3002",
1235
+ triggersEn: "type text, enter value, input field",
1236
+ triggersZh: "\u8F93\u5165\u6587\u5B57,\u586B\u8868\u5355"
1237
+ },
1238
+ "select-option": {
1239
+ intentEn: "Select a dropdown option by selector and value.",
1240
+ intentZh: "\u4E0B\u62C9\u6846\u6309 selector \u4E0E value \u9009\u62E9\u3002",
1241
+ triggersEn: "dropdown select, pick option",
1242
+ triggersZh: "\u4E0B\u62C9\u9009\u62E9,\u9009\u9009\u9879"
1243
+ },
1244
+ "hover-element": {
1245
+ intentEn: "Hover an element by selector.",
1246
+ intentZh: "\u60AC\u505C\u5230\u6307\u5B9A\u5143\u7D20\u3002",
1247
+ triggersEn: "mouse over, hover menu",
1248
+ triggersZh: "\u9F20\u6807\u60AC\u505C,\u5212\u8FC7\u83DC\u5355"
1249
+ },
1250
+ "scroll-element": {
1251
+ intentEn: "Scroll an element into view or by selector.",
1252
+ intentZh: "\u6EDA\u52A8\u6307\u5B9A\u5143\u7D20\u6216\u533A\u57DF\u3002",
1253
+ triggersEn: "scroll into view, page scroll",
1254
+ triggersZh: "\u6EDA\u52A8\u5230\u53EF\u89C1,\u9875\u9762\u6EDA\u52A8"
1255
+ },
1256
+ "press-key": {
1257
+ intentEn: "Press a keyboard key (optional focused selector).",
1258
+ intentZh: "\u6A21\u62DF\u6309\u952E\uFF08\u53EF\u9009\u9650\u5B9A\u5728\u5143\u7D20\u4E0A\uFF09\u3002",
1259
+ triggersEn: "hit Enter, keyboard shortcut",
1260
+ triggersZh: "\u6309\u56DE\u8F66,\u5FEB\u6377\u952E"
1261
+ },
1262
+ "evaluate-script": {
1263
+ intentEn: "Run JavaScript in the page context.",
1264
+ intentZh: "\u5728\u9875\u9762\u4E0A\u4E0B\u6587\u6267\u884C JS\u3002",
1265
+ triggersEn: "execute js, run script in page",
1266
+ triggersZh: "\u6267\u884C\u811A\u672C,\u9875\u9762JS"
1267
+ },
1268
+ "drag-element": {
1269
+ intentEn: "Drag an element to a target element.",
1270
+ intentZh: "\u62D6\u62FD\u5143\u7D20\u5230\u53E6\u4E00\u5143\u7D20\u3002",
1271
+ triggersEn: "drag and drop, dnd",
1272
+ triggersZh: "\u62D6\u62FD,\u62D6\u653E"
1273
+ },
1274
+ "iframe-click-element": {
1275
+ intentEn: "Click inside an iframe by iframe and inner selectors.",
1276
+ intentZh: "\u5728 iframe \u5185\u70B9\u51FB\u5B50\u5143\u7D20\u3002",
1277
+ triggersEn: "iframe click, nested frame",
1278
+ triggersZh: "\u6846\u67B6\u5185\u70B9\u51FB,iframe\u91CC\u70B9"
1279
+ }
621
1280
  };
1281
+ function formatDescription(rec) {
1282
+ return `${rec.intentEn} / ${rec.intentZh} | Triggers: ${rec.triggersEn}; ${rec.triggersZh}`;
1283
+ }
1284
+ function buildMcpToolDescription(toolName, legacyFallback) {
1285
+ const rec = TOOL_INTENT_BY_NAME[toolName];
1286
+ return rec ? formatDescription(rec) : legacyFallback;
1287
+ }
1288
+ function buildCliCommandDescription(commandName, legacyFallback) {
1289
+ return buildMcpToolDescription(commandName, legacyFallback);
1290
+ }
1291
+
1292
+ // ../core/src/handlers/browser.ts
1293
+ var import_node_os = __toESM(require("os"));
622
1294
 
623
1295
  // ../core/src/utils/requestBuilder.ts
624
- function buildRequestBody(params) {
1296
+ function toContractValue(value) {
1297
+ if (Array.isArray(value)) {
1298
+ return value;
1299
+ }
1300
+ if (value && typeof value === "object") {
1301
+ return buildNestedConfig(value);
1302
+ }
1303
+ return value;
1304
+ }
1305
+ function buildRequestBodyFor(command, params) {
625
1306
  const requestBody = {};
626
- const basicFields = {
627
- groupId: "group_id",
628
- username: "username",
629
- password: "password",
630
- cookie: "cookie",
631
- fakey: "fakey",
632
- name: "name",
633
- platform: "platform",
634
- remark: "remark",
635
- proxyid: "proxyid",
636
- repeatConfig: "repeat_config",
637
- ignoreCookieError: "ignore_cookie_error",
638
- tabs: "tabs",
639
- ip: "ip",
640
- country: "country",
641
- region: "region",
642
- city: "city",
643
- ipchecker: "ipchecker",
644
- categoryId: "category_id",
645
- launchArgs: "launch_args",
646
- profileId: "profile_id",
647
- profileTagIds: "profile_tag_ids",
648
- tagsUpdateType: "tags_update_type"
649
- };
650
- Object.entries(basicFields).forEach(([paramKey, key]) => {
651
- const value = params[paramKey];
1307
+ const contract = LOCAL_API_CONTRACTS[command];
1308
+ Object.entries(contract.params).forEach(([inputName, config2]) => {
1309
+ if (config2.location !== "body") {
1310
+ return;
1311
+ }
1312
+ const value = params[inputName];
652
1313
  if (value !== void 0) {
653
- requestBody[key] = value;
1314
+ requestBody[config2.apiName] = toContractValue(value);
654
1315
  }
655
1316
  });
656
- if (params.userProxyConfig) {
657
- const proxyConfig = buildNestedConfig(params.userProxyConfig);
658
- if (Object.keys(proxyConfig).length > 0) {
659
- requestBody.user_proxy_config = proxyConfig;
1317
+ return requestBody;
1318
+ }
1319
+ function buildQueryParamsFor(command, params) {
1320
+ const query = new URLSearchParams();
1321
+ const contract = LOCAL_API_CONTRACTS[command];
1322
+ Object.entries(contract.params).forEach(([inputName, config2]) => {
1323
+ if (config2.location !== "query") {
1324
+ return;
660
1325
  }
661
- }
662
- if (params.fingerprintConfig) {
663
- const fpConfig = buildNestedConfig(params.fingerprintConfig);
664
- if (Object.keys(fpConfig).length > 0) {
665
- requestBody.fingerprint_config = fpConfig;
1326
+ const value = params[inputName];
1327
+ if (value === void 0) {
1328
+ return;
666
1329
  }
667
- }
668
- return requestBody;
1330
+ query.set(config2.apiName, Array.isArray(value) ? value.join(",") : String(value));
1331
+ });
1332
+ return query;
669
1333
  }
670
1334
  function buildNestedConfig(config2) {
671
1335
  const result = {};
672
1336
  Object.entries(config2).forEach(([key, value]) => {
673
1337
  if (value !== void 0) {
674
- if (typeof value === "object" && value !== null) {
1338
+ if (Array.isArray(value)) {
1339
+ result[key] = value;
1340
+ } else if (typeof value === "object" && value !== null) {
675
1341
  const nestedConfig = buildNestedConfig(value);
676
1342
  if (Object.keys(nestedConfig).length > 0) {
677
1343
  result[key] = nestedConfig;
@@ -684,47 +1350,58 @@ function buildNestedConfig(config2) {
684
1350
  return result;
685
1351
  }
686
1352
 
1353
+ // ../core/src/utils/openBrowserHeadless.ts
1354
+ function isTruthyCi(env) {
1355
+ const v = env.CI;
1356
+ return v === "true" || v === "1" || v === "True";
1357
+ }
1358
+ function linuxLooksHeadless(env) {
1359
+ const d = (env.DISPLAY ?? "").trim();
1360
+ const w = (env.WAYLAND_DISPLAY ?? "").trim();
1361
+ return d === "" && w === "";
1362
+ }
1363
+ function resolveOpenBrowserHeadless(params, env, platform) {
1364
+ if (params.headless !== void 0) {
1365
+ return { params: { ...params }, didAutoSetHeadless: false };
1366
+ }
1367
+ let needHeadless = false;
1368
+ if (isTruthyCi(env)) {
1369
+ needHeadless = true;
1370
+ } else if (platform === "linux" && linuxLooksHeadless(env)) {
1371
+ needHeadless = true;
1372
+ }
1373
+ if (!needHeadless) {
1374
+ return { params: { ...params }, didAutoSetHeadless: false };
1375
+ }
1376
+ return {
1377
+ params: { ...params, headless: "1" },
1378
+ didAutoSetHeadless: true
1379
+ };
1380
+ }
1381
+
687
1382
  // ../core/src/handlers/browser.ts
688
1383
  var browserHandlers = {
689
- async openBrowser({ profileNo, profileId, ipTab, launchArgs, clearCacheAfterClosing, cdpMask }) {
690
- const requestBody = {};
691
- if (profileId) {
692
- requestBody.profile_id = profileId;
693
- }
694
- if (profileNo) {
695
- requestBody.profile_no = profileNo;
696
- }
697
- if (ipTab) {
698
- requestBody.ip_tab = ipTab;
699
- }
700
- if (launchArgs) {
701
- requestBody.launch_args = launchArgs;
702
- }
703
- if (clearCacheAfterClosing) {
704
- requestBody.delete_cache = clearCacheAfterClosing;
705
- }
706
- if (cdpMask) {
707
- requestBody.cdp_mask = cdpMask;
708
- }
1384
+ async openBrowser(params) {
1385
+ const { params: resolvedParams, didAutoSetHeadless } = resolveOpenBrowserHeadless(
1386
+ params,
1387
+ process.env,
1388
+ import_node_os.default.platform()
1389
+ );
1390
+ const requestBody = buildRequestBodyFor("open-browser", resolvedParams);
709
1391
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.START_BROWSER}`, requestBody);
710
1392
  if (response.data.code === 0) {
1393
+ const autoNote = didAutoSetHeadless ? "\n\u5DF2\u6839\u636E\u8FD0\u884C\u73AF\u5883\u81EA\u52A8\u4F7F\u7528 headless=1\uFF08\u65E0\u53EF\u7528\u56FE\u5F62\u4F1A\u8BDD\uFF09\u3002\nAuto-set headless=1 (no graphical session detected)." : "";
711
1394
  return `Browser opened successfully with: ${Object.entries(response.data.data).map(([key, value]) => {
712
1395
  if (value && typeof value === "object") {
713
1396
  return Object.entries(value).map(([key2, value2]) => `ws.${key2}: ${value2}`).join("\n");
714
1397
  }
715
1398
  return `${key}: ${value}`;
716
- }).join("\n")}`;
1399
+ }).join("\n")}${autoNote}`;
717
1400
  }
718
1401
  throw new Error(`Failed to open browser: ${response.data.msg}`);
719
1402
  },
720
- async closeBrowser({ profileId, profileNo }) {
721
- const requestBody = {};
722
- if (profileId) {
723
- requestBody.profile_id = profileId;
724
- }
725
- if (profileNo) {
726
- requestBody.profile_no = profileNo;
727
- }
1403
+ async closeBrowser(params) {
1404
+ const requestBody = buildRequestBodyFor("close-browser", params);
728
1405
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_BROWSER}`, requestBody);
729
1406
  if (response.data.code === 0) {
730
1407
  return "Browser closed successfully";
@@ -732,7 +1409,7 @@ var browserHandlers = {
732
1409
  throw new Error(`Failed to close browser: ${response.data.msg}`);
733
1410
  },
734
1411
  async createBrowser(params) {
735
- const requestBody = buildRequestBody(params);
1412
+ const requestBody = buildRequestBodyFor("create-browser", params);
736
1413
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_BROWSER}`, requestBody);
737
1414
  if (response.data.code === 0) {
738
1415
  return `Browser created successfully with: ${Object.entries(response.data.data).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
@@ -740,58 +1417,25 @@ var browserHandlers = {
740
1417
  throw new Error(`Failed to create browser: ${response.data.msg}`);
741
1418
  },
742
1419
  async updateBrowser(params) {
743
- const requestBody = buildRequestBody(params);
1420
+ const requestBody = buildRequestBodyFor("update-browser", params);
744
1421
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_BROWSER}`, requestBody);
745
1422
  if (response.data.code === 0) {
746
1423
  return `Browser updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
747
1424
  }
748
1425
  throw new Error(`Failed to update browser: ${response.data.msg}`);
749
1426
  },
750
- async deleteBrowser({ profileIds }) {
751
- const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_BROWSER}`, {
752
- profile_id: profileIds
753
- });
1427
+ async deleteBrowser(params) {
1428
+ const response = await getApiClient().post(
1429
+ `${getLocalApiBase()}${API_ENDPOINTS.DELETE_BROWSER}`,
1430
+ buildRequestBodyFor("delete-browser", params)
1431
+ );
754
1432
  if (response.data.code === 0) {
755
- return `Browsers deleted successfully: ${profileIds.join(", ")}`;
1433
+ return `Browsers deleted successfully: ${params.profile_id.join(", ")}`;
756
1434
  }
757
1435
  throw new Error(`Failed to delete browsers: ${response.data.msg}`);
758
1436
  },
759
1437
  async getBrowserList(params) {
760
- const { groupId, limit, page, profileId, profileNo, sortType, sortOrder, tag_ids, tags_filter, name, name_filter } = params;
761
- const requestBody = {};
762
- if (limit !== void 0) {
763
- requestBody.limit = limit;
764
- }
765
- if (page !== void 0) {
766
- requestBody.page = page;
767
- }
768
- if (profileId && profileId.length > 0) {
769
- requestBody.profile_id = profileId;
770
- }
771
- if (profileNo && profileNo.length > 0) {
772
- requestBody.profile_no = profileNo;
773
- }
774
- if (groupId !== void 0) {
775
- requestBody.group_id = groupId;
776
- }
777
- if (sortType) {
778
- requestBody.sort_type = sortType;
779
- }
780
- if (sortOrder) {
781
- requestBody.sort_order = sortOrder;
782
- }
783
- if (tag_ids && tag_ids.length > 0) {
784
- requestBody.tag_ids = tag_ids;
785
- }
786
- if (tags_filter) {
787
- requestBody.tags_filter = tags_filter;
788
- }
789
- if (name) {
790
- requestBody.name = name;
791
- }
792
- if (name_filter) {
793
- requestBody.name_filter = name_filter;
794
- }
1438
+ const requestBody = buildRequestBodyFor("get-browser-list", params);
795
1439
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_LIST}`, requestBody);
796
1440
  if (response.data.code === 0) {
797
1441
  return `Browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
@@ -805,38 +1449,25 @@ var browserHandlers = {
805
1449
  }
806
1450
  throw new Error(`Failed to get opened browsers: ${response.data.msg}`);
807
1451
  },
808
- async moveBrowser({ groupId, userIds }) {
809
- const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.MOVE_BROWSER}`, {
810
- group_id: groupId,
811
- user_ids: userIds
812
- });
1452
+ async moveBrowser(params) {
1453
+ const requestBody = buildRequestBodyFor("move-browser", params);
1454
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.MOVE_BROWSER}`, requestBody);
1455
+ const { group_id, user_ids } = params;
813
1456
  if (response.data.code === 0) {
814
- return `Browsers moved successfully to group ${groupId}: ${userIds.join(", ")}`;
1457
+ return `Browsers moved successfully to group ${group_id}: ${user_ids.join(", ")}`;
815
1458
  }
816
1459
  throw new Error(`Failed to move browsers: ${response.data.msg}`);
817
1460
  },
818
- async getProfileCookies({ profileId, profileNo }) {
819
- const params = new URLSearchParams();
820
- if (profileId) {
821
- params.set("profile_id", profileId);
822
- }
823
- if (profileNo) {
824
- params.set("profile_no", profileNo);
825
- }
826
- const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params });
1461
+ async getProfileCookies(params) {
1462
+ const query = buildQueryParamsFor("get-profile-cookies", params);
1463
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params: query });
827
1464
  if (response.data.code === 0) {
828
1465
  return `Profile cookies: ${JSON.stringify(response.data.data, null, 2)}`;
829
1466
  }
830
1467
  throw new Error(`Failed to get profile cookies: ${response.data.msg}`);
831
1468
  },
832
- async getProfileUa({ profileId, profileNo }) {
833
- const requestBody = {};
834
- if (profileId && profileId.length > 0) {
835
- requestBody.profile_id = profileId;
836
- }
837
- if (profileNo && profileNo.length > 0) {
838
- requestBody.profile_no = profileNo;
839
- }
1469
+ async getProfileUa(params) {
1470
+ const requestBody = buildRequestBodyFor("get-profile-ua", params);
840
1471
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_UA}`, requestBody);
841
1472
  if (response.data.code === 0) {
842
1473
  return `Profile User-Agent: ${JSON.stringify(response.data.data, null, 2)}`;
@@ -850,65 +1481,43 @@ var browserHandlers = {
850
1481
  }
851
1482
  throw new Error(`Failed to close all profiles: ${response.data.msg}`);
852
1483
  },
853
- async newFingerprint({ profileId, profileNo }) {
854
- const requestBody = {};
855
- if (profileId && profileId.length > 0) {
856
- requestBody.profile_id = profileId;
857
- }
858
- if (profileNo && profileNo.length > 0) {
859
- requestBody.profile_no = profileNo;
860
- }
1484
+ async newFingerprint(params) {
1485
+ const requestBody = buildRequestBodyFor("new-fingerprint", params);
861
1486
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.NEW_FINGERPRINT}`, requestBody);
862
1487
  if (response.data.code === 0) {
863
1488
  return `New fingerprint created: ${JSON.stringify(response.data.data, null, 2)}`;
864
1489
  }
865
1490
  throw new Error(`Failed to create new fingerprint: ${response.data.msg}`);
866
1491
  },
867
- async deleteCacheV2({ profileIds, type }) {
868
- const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_CACHE_V2}`, {
869
- profile_id: profileIds,
870
- type
871
- });
1492
+ async deleteCacheV2(params) {
1493
+ const response = await getApiClient().post(
1494
+ `${getLocalApiBase()}${API_ENDPOINTS.DELETE_CACHE_V2}`,
1495
+ buildRequestBodyFor("delete-cache-v2", params)
1496
+ );
872
1497
  if (response.data.code === 0) {
873
- return `Cache deleted successfully for profiles: ${profileIds.join(", ")}`;
1498
+ return `Cache deleted successfully for profiles: ${params.profile_id.join(", ")}`;
874
1499
  }
875
1500
  throw new Error(`Failed to delete cache: ${response.data.msg}`);
876
1501
  },
877
- async shareProfile({ profileIds, receiver, shareType, content }) {
878
- const requestBody = {
879
- profile_id: profileIds,
880
- receiver
881
- };
882
- if (shareType !== void 0) {
883
- requestBody.share_type = shareType;
884
- }
885
- if (content !== void 0) {
886
- requestBody.content = content;
887
- }
1502
+ async shareProfile(params) {
1503
+ const requestBody = buildRequestBodyFor("share-profile", params);
888
1504
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.SHARE_PROFILE}`, requestBody);
889
1505
  if (response.data.code === 0) {
890
- return `Profiles shared successfully: ${profileIds.join(", ")}`;
1506
+ return `Profiles shared successfully: ${params.profile_id.join(", ")}`;
891
1507
  }
892
1508
  throw new Error(`Failed to share profiles: ${response.data.msg}`);
893
1509
  },
894
- async getBrowserActive({ profileId, profileNo }) {
895
- const params = new URLSearchParams();
896
- if (profileId) {
897
- params.set("profile_id", profileId);
898
- }
899
- if (profileNo) {
900
- params.set("profile_no", profileNo);
901
- }
902
- const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params });
1510
+ async getBrowserActive(params) {
1511
+ const query = buildQueryParamsFor("get-browser-active", params);
1512
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params: query });
903
1513
  if (response.data.code === 0) {
904
1514
  return `Browser active info: ${JSON.stringify(response.data.data, null, 2)}`;
905
1515
  }
906
1516
  throw new Error(`Failed to get browser active: ${response.data.msg}`);
907
1517
  },
908
- async getCloudActive({ userIds }) {
909
- const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, {
910
- user_ids: userIds
911
- });
1518
+ async getCloudActive(params) {
1519
+ const requestBody = buildRequestBodyFor("get-cloud-active", params);
1520
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, requestBody);
912
1521
  if (response.data.code === 0) {
913
1522
  return `Cloud active browsers: ${JSON.stringify(response.data.data, null, 2)}`;
914
1523
  }
@@ -918,46 +1527,31 @@ var browserHandlers = {
918
1527
 
919
1528
  // ../core/src/handlers/group.ts
920
1529
  var groupHandlers = {
921
- async createGroup({ groupName, remark }) {
922
- const requestBody = {
923
- group_name: groupName
924
- };
925
- if (remark !== void 0) {
926
- requestBody.remark = remark;
927
- }
1530
+ async createGroup(params) {
1531
+ const requestBody = buildRequestBodyFor("create-group", params);
928
1532
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_GROUP}`, requestBody);
1533
+ const { group_name, remark } = params;
929
1534
  if (response.data.code === 0) {
930
- return `Group created successfully with name: ${groupName}${remark ? `, remark: ${remark}` : ""}`;
1535
+ return `Group created successfully with name: ${group_name}${remark ? `, remark: ${remark}` : ""}`;
931
1536
  }
932
1537
  throw new Error(`Failed to create group: ${response.data.msg}`);
933
1538
  },
934
- async updateGroup({ groupId, groupName, remark }) {
935
- const requestBody = {
936
- group_id: groupId,
937
- group_name: groupName
938
- };
939
- if (remark !== void 0) {
940
- requestBody.remark = remark;
941
- }
1539
+ async updateGroup(params) {
1540
+ const requestBody = buildRequestBodyFor("update-group", params);
942
1541
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_GROUP}`, requestBody);
1542
+ const { group_id, group_name, remark } = params;
943
1543
  if (response.data.code === 0) {
944
- return `Group updated successfully with id: ${groupId}, name: ${groupName}${remark !== void 0 ? `, remark: ${remark === null ? "(cleared)" : remark}` : ""}`;
1544
+ return `Group updated successfully with id: ${group_id}, name: ${group_name}${remark !== void 0 ? `, remark: ${remark === null ? "(cleared)" : remark}` : ""}`;
945
1545
  }
946
1546
  throw new Error(`Failed to update group: ${response.data.msg}`);
947
1547
  },
948
- async getGroupList({ groupName, size, page }) {
949
- const params = new URLSearchParams();
950
- if (groupName) {
951
- params.set("group_name", groupName);
952
- }
953
- if (size) {
954
- params.set("page_size", size.toString());
955
- }
956
- if (page) {
957
- params.set("page", page.toString());
1548
+ async getGroupList(params) {
1549
+ const query = buildQueryParamsFor("get-group-list", params);
1550
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_GROUP_LIST}`, { params: query });
1551
+ if (response.data.code === 0) {
1552
+ return `Group list: ${JSON.stringify(response.data.data.list, null, 2)}`;
958
1553
  }
959
- const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_GROUP_LIST}`, { params });
960
- return `Group list: ${JSON.stringify(response.data.data.list, null, 2)}`;
1554
+ throw new Error(`Failed to get group list: ${response.data.msg}`);
961
1555
  }
962
1556
  };
963
1557
 
@@ -967,54 +1561,14 @@ var applicationHandlers = {
967
1561
  const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.STATUS}`);
968
1562
  return `Connection status: ${JSON.stringify(response.data, null, 2)}`;
969
1563
  },
970
- async getApplicationList({ category_id, page, limit }) {
971
- const params = new URLSearchParams();
972
- if (category_id) {
973
- params.set("category_id", category_id);
974
- }
975
- if (page !== void 0) {
976
- params.set("page", page.toString());
977
- }
978
- if (limit !== void 0) {
979
- params.set("limit", limit.toString());
980
- }
981
- const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params });
1564
+ async getApplicationList(params) {
1565
+ const query = buildQueryParamsFor("get-application-list", params);
1566
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params: query });
982
1567
  return `Application list: ${JSON.stringify(response.data.data.list, null, 2)}`;
983
1568
  }
984
1569
  };
985
1570
 
986
1571
  // ../core/src/handlers/proxy.ts
987
- function buildProxyRequestBody(params) {
988
- const requestBody = {};
989
- if (params.proxyId) {
990
- requestBody.proxy_id = params.proxyId;
991
- }
992
- if (params.type !== void 0) {
993
- requestBody.type = params.type;
994
- }
995
- if (params.host !== void 0) {
996
- requestBody.host = params.host;
997
- }
998
- if (params.port !== void 0) {
999
- requestBody.port = params.port;
1000
- }
1001
- if (params.user !== void 0) {
1002
- requestBody.user = params.user;
1003
- }
1004
- if (params.password !== void 0) {
1005
- requestBody.password = params.password;
1006
- }
1007
- if (params.proxyUrl !== void 0) {
1008
- requestBody.proxy_url = params.proxyUrl;
1009
- }
1010
- if (params.remark !== void 0) {
1011
- requestBody.remark = params.remark;
1012
- }
1013
- if (params.ipchecker !== void 0) {
1014
- requestBody.ipchecker = params.ipchecker;
1015
- }
1016
- return requestBody;
1017
- }
1018
1572
  function buildCreateProxyRequestBody(proxy) {
1019
1573
  const requestBody = {};
1020
1574
  requestBody.type = proxy.type;
@@ -1039,7 +1593,7 @@ function buildCreateProxyRequestBody(proxy) {
1039
1593
  }
1040
1594
  var proxyHandlers = {
1041
1595
  async createProxy(params) {
1042
- const requestBody = params.proxies.map((proxy) => buildCreateProxyRequestBody(proxy));
1596
+ const requestBody = params.map((proxy) => buildCreateProxyRequestBody(proxy));
1043
1597
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_PROXY}`, requestBody);
1044
1598
  if (response.data.code === 0) {
1045
1599
  return `Proxy created successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
@@ -1047,7 +1601,7 @@ var proxyHandlers = {
1047
1601
  throw new Error(`Failed to create proxy: ${response.data.msg}`);
1048
1602
  },
1049
1603
  async updateProxy(params) {
1050
- const requestBody = buildProxyRequestBody(params);
1604
+ const requestBody = buildRequestBodyFor("update-proxy", params);
1051
1605
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PROXY}`, requestBody);
1052
1606
  if (response.data.code === 0) {
1053
1607
  return `Proxy updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
@@ -1055,29 +1609,21 @@ var proxyHandlers = {
1055
1609
  throw new Error(`Failed to update proxy: ${response.data.msg}`);
1056
1610
  },
1057
1611
  async getProxyList(params) {
1058
- const { limit, page, proxyId } = params;
1059
- const requestBody = {};
1060
- if (limit !== void 0) {
1061
- requestBody.limit = limit;
1062
- }
1063
- if (page !== void 0) {
1064
- requestBody.page = page;
1065
- }
1066
- if (proxyId && proxyId.length > 0) {
1067
- requestBody.proxy_id = proxyId;
1068
- }
1612
+ const requestBody = buildRequestBodyFor("get-proxy-list", params);
1069
1613
  const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROXY_LIST}`, requestBody);
1070
1614
  if (response.data.code === 0) {
1071
1615
  return `Proxy list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
1072
1616
  }
1073
1617
  throw new Error(`Failed to get proxy list: ${response.data.msg}`);
1074
1618
  },
1075
- async deleteProxy({ proxyIds }) {
1076
- const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_PROXY}`, {
1077
- proxy_id: proxyIds
1078
- });
1619
+ async deleteProxy(params) {
1620
+ const response = await getApiClient().post(
1621
+ `${getLocalApiBase()}${API_ENDPOINTS.DELETE_PROXY}`,
1622
+ buildRequestBodyFor("delete-proxy", params)
1623
+ );
1624
+ const { proxy_id } = params;
1079
1625
  if (response.data.code === 0) {
1080
- return `Proxies deleted successfully: ${proxyIds.join(", ")}`;
1626
+ return `Proxies deleted successfully: ${proxy_id.join(", ")}`;
1081
1627
  }
1082
1628
  throw new Error(`Failed to delete proxies: ${response.data.msg}`);
1083
1629
  }
@@ -1131,7 +1677,7 @@ var import_path = __toESM(require("path"));
1131
1677
  var import_os = __toESM(require("os"));
1132
1678
 
1133
1679
  // ../core/src/utils/browserBase.ts
1134
- var import_playwright = require("playwright");
1680
+ var import_playwright_core = require("playwright-core");
1135
1681
  var BrowserBase = class {
1136
1682
  browser;
1137
1683
  page;
@@ -1166,7 +1712,7 @@ var BrowserBase = class {
1166
1712
  }
1167
1713
  }
1168
1714
  async connectBrowserWithWs(wsUrl) {
1169
- this.browser = await import_playwright.chromium.connectOverCDP(wsUrl);
1715
+ this.browser = await import_playwright_core.chromium.connectOverCDP(wsUrl);
1170
1716
  const defaultContext = this.browser.contexts()[0];
1171
1717
  this.page = defaultContext.pages()[0];
1172
1718
  await this.page.bringToFront().catch((error) => {
@@ -1242,9 +1788,9 @@ var userProxyConfigSchema = import_zod.z.object({
1242
1788
  proxy_type: import_zod.z.enum(["http", "https", "socks5", "no_proxy"]).optional(),
1243
1789
  proxy_host: import_zod.z.string().optional().describe("The proxy host of the browser, eg: 127.0.0.1"),
1244
1790
  proxy_port: import_zod.z.string().optional().describe("The proxy port of the browser, eg: 8080"),
1245
- proxy_user: import_zod.z.string().optional().describe("The proxy user of the browser, eg: user"),
1246
- proxy_password: import_zod.z.string().optional().describe("The proxy password of the browser, eg: password"),
1247
- proxy_url: import_zod.z.string().optional().describe("The proxy url of the browser, eg: http://127.0.0.1:8080"),
1791
+ proxy_user: import_zod.z.string().optional().describe("The proxy user for proxy authentication, eg: user"),
1792
+ proxy_password: import_zod.z.string().optional().describe("The proxy password for proxy authentication, eg: password"),
1793
+ proxy_url: import_zod.z.string().optional().describe("This URL is used for dynamic proxy, only supports http/https/socks5 proxies. 1. By clicking this link, you can manually change the proxy IP address. 2. When multiple environments use the same proxy account, refreshing the IP will change the IP address of the same proxy account."),
1248
1794
  global_config: import_zod.z.enum(["0", "1"]).optional().describe("The global config of the browser, default is 0")
1249
1795
  }).describe("The user proxy config of the browser");
1250
1796
  var CHROME_VERSIONS = [
@@ -1285,9 +1831,10 @@ var CHROME_VERSIONS = [
1285
1831
  "142",
1286
1832
  "143",
1287
1833
  "144",
1288
- "ua_auto"
1834
+ "ua_auto",
1835
+ "latest"
1289
1836
  ];
1290
- var FIREFOX_VERSIONS = ["100", "107", "114", "120", "123", "126", "129", "132", "135", "138", "141", "144", "ua_auto"];
1837
+ var FIREFOX_VERSIONS = ["100", "107", "114", "120", "123", "126", "129", "132", "135", "138", "141", "144", "ua_auto", "latest"];
1291
1838
  var ALL_KERNEL_VERSIONS = [.../* @__PURE__ */ new Set([...CHROME_VERSIONS, ...FIREFOX_VERSIONS])];
1292
1839
  var browserKernelConfigSchema = import_zod.z.object({
1293
1840
  version: import_zod.z.union(
@@ -1642,14 +2189,21 @@ var mediaDevicesNumSchema = import_zod.z.object({
1642
2189
  videoinput_num: import_zod.z.enum(DEVICE_COUNT_VALUES).describe("Number of cameras, 1-9"),
1643
2190
  audiooutput_num: import_zod.z.enum(DEVICE_COUNT_VALUES).describe("Number of speakers, 1-9")
1644
2191
  }).describe("Device counts when media_devices=2: audioinput_num, videoinput_num, audiooutput_num each 1-9.");
2192
+ var platformAccountSchema = import_zod.z.object({
2193
+ domain_name: import_zod.z.string().min(1).describe("Platform domain name, eg: facebook.com"),
2194
+ login_user: import_zod.z.string().min(1).describe("Platform login user, e.g. shop username or login email"),
2195
+ password: import_zod.z.string().min(1).optional().describe("Optional platform account password"),
2196
+ fakey: import_zod.z.string().min(1).optional().describe("2FA key for online 2FA code generators")
2197
+ }).strict().optional().describe("Structured platform account metadata keyed by Postman field name platform_account.");
2198
+ var nonEmptyStringArraySchema = import_zod.z.array(import_zod.z.string()).nonempty();
1645
2199
  var fingerprintConfigSchema = import_zod.z.object({
1646
2200
  automatic_timezone: import_zod.z.enum(["0", "1"]).optional().describe("Auto timezone by IP: 0 custom, 1 (default) by IP"),
1647
2201
  timezone: import_zod.z.string().optional().describe("Timezone when automatic_timezone=0, e.g. Asia/Shanghai"),
1648
- location_switch: import_zod.z.enum(["0", "1"]).optional().describe("Location by IP: 0 custom, 1 (default) by IP"),
2202
+ location_switch: import_zod.z.enum(["0", "1"]).optional().describe("1: Generate location based on IP (default); 0: Specify location"),
1649
2203
  longitude: import_zod.z.number().min(-180).max(180).optional().describe("Custom longitude when location_switch=0, -180 to 180, up to 6 decimals"),
1650
2204
  latitude: import_zod.z.number().min(-90).max(90).optional().describe("Custom latitude when location_switch=0, -90 to 90, up to 6 decimals"),
1651
2205
  accuracy: import_zod.z.number().int().min(10).max(5e3).optional().describe("Location accuracy in meters when location_switch=0, 10-5000, default 1000"),
1652
- location: import_zod.z.enum(["ask", "allow", "block"]).optional().describe("Site location permission: ask (default), allow, block"),
2206
+ location: import_zod.z.enum(["ask", "allow", "block"]).optional().describe("When the website requests to obtain your current location, the support: ask (default), allow, block; ask: ask (default), the same as the prompt of ordinary browsers; allow: always allow the website to get the location; block: always block the website from getting the location."),
1653
2207
  language_switch: import_zod.z.enum(["0", "1"]).optional().describe("Language by IP country: 0 custom, 1 (default) by IP"),
1654
2208
  language: import_zod.z.array(import_zod.z.string()).optional().describe('Custom languages when language_switch=0, e.g. ["en-US", "zh-CN"]'),
1655
2209
  page_language_switch: import_zod.z.enum(["0", "1"]).optional().describe("Match UI language to language: 0 off, 1 (default) on; Chrome 109+ Win / 119+ macOS, v2.6.72+"),
@@ -1665,7 +2219,7 @@ var fingerprintConfigSchema = import_zod.z.object({
1665
2219
  webgl_image: import_zod.z.enum(["0", "1"]).optional().describe("WebGL image fingerprint: 0 default, 1 (default) add noise"),
1666
2220
  webgl_config: webglConfigSchema.optional().describe("Custom WebGL metadata when webgl=2. Must include unmasked_vendor and unmasked_renderer (non-empty). webgpu.webgpu_switch: 0 Disabled, 1 WebGL based, 2 Real. V2.6.8.1+"),
1667
2221
  flash: import_zod.z.enum(["block", "allow"]).optional().describe("Flash: block (default) or allow"),
1668
- webrtc: import_zod.z.enum(["disabled", "forward", "proxy", "local"]).optional().describe("WebRTC: disabled (default), forward, proxy, local"),
2222
+ webrtc: import_zod.z.enum(["disabled", "forward", "proxy", "local", "disableUDP"]).optional().describe("WebRTC: forward: forward, use proxy IP to cover real IP, used in proxy scene, more secure (need to upgrade to V2.6.8.6 or later version); proxy: replace, use proxy IP to cover real IP, used in proxy scene; local: real, the website will get the real IP; disabled: disabled (default), the website will not get the IP; disableUDP: disable UDP, disable non-proxy UDP traffic (only supported by Chrome kernel)."),
1669
2223
  audio: import_zod.z.enum(["0", "1"]).optional().describe("Audio fingerprint: 0 close, 1 (default) add noise"),
1670
2224
  do_not_track: import_zod.z.enum(["default", "true", "false"]).optional().describe("Do Not Track: default, true (open), false (close)"),
1671
2225
  hardware_concurrency: import_zod.z.enum(["2", "4", "6", "8", "16"]).optional().describe("CPU cores: 2, 4 (default if omitted), 6, 8, 16; omit to follow current computer"),
@@ -1680,7 +2234,7 @@ var fingerprintConfigSchema = import_zod.z.object({
1680
2234
  speech_switch: import_zod.z.enum(["0", "1"]).optional().describe("SpeechVoices: 0 use computer default, 1 replace with value. V3.11.10+"),
1681
2235
  mac_address_config: macAddressConfigSchema.optional().describe("MAC address: model 0/1/2, address when model=2. V4.3.9+"),
1682
2236
  gpu: import_zod.z.enum(["0", "1", "2"]).optional().describe("GPU: 0 follow Local settings - Hardware acceleration, 1 turn on, 2 turn off"),
1683
- browser_kernel_config: browserKernelConfigSchema.optional(),
2237
+ browser_kernel_config: browserKernelConfigSchema.optional().default({ "version": "latest", "type": "chrome" }),
1684
2238
  random_ua: randomUaConfigSchema.optional().describe("Random UA config; ignored when ua (custom UA) is provided."),
1685
2239
  tls_switch: import_zod.z.enum(["0", "1"]).optional().describe("TLS custom list: 0 (default) off, 1 on"),
1686
2240
  tls: import_zod.z.string().optional().refine(
@@ -1702,127 +2256,156 @@ var fingerprintConfigSchema = import_zod.z.object({
1702
2256
  }
1703
2257
  }
1704
2258
  }).describe("Fingerprint config (fingerprint_config). All fields optional. See AdsPower Local API fingerprint_config.");
2259
+ var createProxyItemSchema = import_zod.z.object({
2260
+ type: import_zod.z.enum(["http", "https", "ssh", "socks5"]).describe("Proxy type, support: http/https/ssh/socks5"),
2261
+ host: import_zod.z.string().describe("Proxy host, support: ipV4, ipV6, eg: 192.168.0.1"),
2262
+ port: import_zod.z.string().describe("Port, range: 0-65536, eg: 8000"),
2263
+ user: import_zod.z.string().optional().describe("Proxy username, eg: user12345678"),
2264
+ password: import_zod.z.string().optional().describe("Proxy password, eg: password"),
2265
+ proxy_url: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
2266
+ remark: import_zod.z.string().optional().describe("Remark/description for the proxy"),
2267
+ ipchecker: import_zod.z.enum(["ip2location", "ipapi", "ipfoxy"]).optional().describe("IP checker.")
2268
+ }).strict();
1705
2269
  var schemas = {
1706
2270
  createBrowserSchema: import_zod.z.object({
1707
- groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group, use 0 for Ungrouped'),
2271
+ group_id: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group, use 0 for Ungrouped'),
1708
2272
  username: import_zod.z.string().optional().describe("Platform account username"),
1709
2273
  password: import_zod.z.string().optional().describe("Platform account password"),
1710
- cookie: import_zod.z.string().optional().describe("Cookie data in JSON or Netscape format"),
2274
+ cookie: import_zod.z.string().optional().describe(`Cookie data in JSON array string or Netscape format, eg: '[{"domain":".baidu.com","expirationDate":1724188800,"name":"BAIDUID","value":"xxxxxxxxxx"}]'`),
1711
2275
  fakey: import_zod.z.string().optional().describe("2FA key for online 2FA code generators"),
1712
- name: import_zod.z.string().max(100).optional().describe("Account name, max 100 characters"),
1713
- platform: import_zod.z.string().optional().describe("Platform domain, eg: facebook.com"),
1714
- remark: import_zod.z.string().optional().describe("Remarks to describe the account. Maximum 1500 characters."),
1715
- userProxyConfig: userProxyConfigSchema.default({ proxy_soft: "no_proxy" }).describe("Proxy configuration. If proxyid is provided, proxyid takes priority and this field is ignored. Defaults to no_proxy when neither proxyid nor a custom proxy is needed."),
1716
- proxyid: import_zod.z.string().optional().describe("Proxy profile ID. Takes priority over userProxyConfig when provided."),
1717
- repeatConfig: import_zod.z.array(import_zod.z.union([import_zod.z.literal(0), import_zod.z.literal(2), import_zod.z.literal(3), import_zod.z.literal(4)])).optional().describe("Account deduplication settings (0, 2, 3, or 4)"),
1718
- ignoreCookieError: import_zod.z.enum(["0", "1"]).optional().describe("Handle cookie verification failures: 0 (default) return data as-is, 1 filter out incorrectly formatted cookies"),
2276
+ name: import_zod.z.string().max(100).optional().describe("Profile name, max 100 characters"),
2277
+ platform: import_zod.z.string().optional().describe("Platform domain, eg: facebook.com, The platform account is only applicable to single account platform settings. If you need to configure multiple account platforms, please use platform_account instead."),
2278
+ remark: import_zod.z.string().optional().describe("Remarks to describe the profile. Maximum 1500 characters."),
2279
+ user_proxy_config: userProxyConfigSchema.default({ proxy_soft: "no_proxy" }).describe("Proxy configuration. If proxyid is provided, proxyid takes priority and this field is ignored. Defaults to no_proxy when neither proxyid nor a custom proxy is needed."),
2280
+ proxyid: import_zod.z.string().optional().describe(" Already added proxy (proxy ID). user_proxy_config and proxyid cannot be empty at the same time. Takes priority over user_proxy_config when provided."),
2281
+ repeat_config: import_zod.z.array(import_zod.z.union([import_zod.z.literal(0), import_zod.z.literal(2), import_zod.z.literal(3), import_zod.z.literal(4)])).optional().describe("Account deduplication settings (0, 2, 3, or 4), 0: allow duplicate (default), 2: deduplicate by account and password, 3: deduplicate by cookie, 4: deduplicate by c_user (c_user is Facebook's unique identifier)"),
2282
+ ignore_cookie_error: import_zod.z.enum(["0", "1"]).optional().describe("Handle cookie verification failures: 0 (default) return data as-is, 1 filter out incorrectly formatted cookies"),
1719
2283
  tabs: import_zod.z.array(import_zod.z.string()).optional().describe('URLs to open on startup, eg: ["https://www.google.com"]'),
1720
2284
  ip: import_zod.z.string().optional().describe("IP address"),
1721
2285
  country: countryCodeSchema.optional().describe('Country/Region, ISO 3166-1 alpha-2 (lowercase). eg: "cn", "us"'),
1722
2286
  region: import_zod.z.string().optional().describe("Region"),
1723
2287
  city: import_zod.z.string().optional().describe("City"),
1724
- ipchecker: import_zod.z.enum(["ip2location", "ipapi"]).optional().describe("IP query channel"),
1725
- categoryId: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
1726
- profileTagIds: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to assign to the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
1727
- fingerprintConfig: fingerprintConfigSchema.optional().default({ random_ua: { ua_system_version: ["Windows"] } })
1728
- }),
2288
+ ipchecker: import_zod.z.enum(["ip2location", "ipapi", "ipfoxy"]).optional().describe("IP query channel"),
2289
+ category_id: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
2290
+ profile_tag_ids: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to assign to the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
2291
+ fingerprint_config: fingerprintConfigSchema.optional().default({ random_ua: { ua_system_version: ["Windows"] }, browser_kernel_config: { version: "latest", type: "chrome" } }),
2292
+ platform_account: platformAccountSchema
2293
+ }).strict(),
1729
2294
  updateBrowserSchema: import_zod.z.object({
1730
2295
  platform: import_zod.z.string().optional().describe("The platform of the browser, eg: facebook.com"),
1731
2296
  tabs: import_zod.z.array(import_zod.z.string()).optional().describe('The tabs of the browser, eg: ["https://www.google.com"]'),
1732
- cookie: import_zod.z.string().optional().describe("The cookie of the browser"),
2297
+ cookie: import_zod.z.string().optional().describe(`Cookie data in JSON array string or Netscape format, eg: '[{"domain":".baidu.com","expirationDate":1724188800,"name":"BAIDUID","value":"xxxxxxxxxx"}]'`),
1733
2298
  username: import_zod.z.string().optional().describe('The username of the browser, eg: "user"'),
1734
2299
  password: import_zod.z.string().optional().describe('The password of the browser, eg: "password"'),
1735
2300
  fakey: import_zod.z.string().optional().describe("Enter the 2FA-key"),
1736
- ignoreCookieError: import_zod.z.enum(["0", "1"]).optional().describe("Specifies how to handle the case when cookie validation fails."),
1737
- groupId: import_zod.z.string().optional().describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group'),
2301
+ ignore_cookie_error: import_zod.z.enum(["0", "1"]).optional().describe("Specifies how to handle the case when cookie validation fails."),
2302
+ group_id: import_zod.z.string().optional().describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group'),
1738
2303
  name: import_zod.z.string().max(100).optional().describe('The Profile name of the browser, eg: "My Browser"'),
1739
2304
  remark: import_zod.z.string().max(1500).optional().describe("Profile remarks, maximum 1500 characters"),
1740
2305
  country: countryCodeSchema.optional().describe('The country of the browser, ISO 3166-1 alpha-2 (lowercase). eg: "cn", "us"'),
1741
2306
  region: import_zod.z.string().optional().describe("The region of the browser"),
1742
2307
  city: import_zod.z.string().optional().describe("The city of the browser"),
2308
+ ipchecker: import_zod.z.enum(["ip2location", "ipapi", "ipfoxy"]).optional().describe("IP query channel"),
1743
2309
  ip: import_zod.z.string().optional().describe("The IP of the browser"),
1744
- categoryId: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
1745
- userProxyConfig: userProxyConfigSchema.optional(),
2310
+ category_id: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
2311
+ user_proxy_config: userProxyConfigSchema.optional(),
1746
2312
  proxyid: import_zod.z.string().optional().describe("Proxy ID"),
1747
- fingerprintConfig: fingerprintConfigSchema.optional(),
1748
- launchArgs: import_zod.z.string().optional().describe("Browser startup parameters"),
1749
- profileTagIds: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to set on the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
1750
- tagsUpdateType: import_zod.z.enum(["1", "2"]).optional().describe('How to apply profile_tag_ids: "1" (default) replace all existing tags; "2" append tags (truncated to 30 total if exceeded)'),
1751
- profileId: import_zod.z.string().describe("The profile id of the browser to update, it is required when you want to update the browser")
1752
- }),
1753
- openBrowserSchema: import_zod.z.object({
1754
- profileNo: import_zod.z.string().optional().describe("Priority will be given to user id when profile_id is filled."),
1755
- profileId: import_zod.z.string().describe("Unique profile ID, generated after creating profile. The profile id of the browser to open"),
1756
- ipTab: import_zod.z.enum(["0", "1"]).optional().describe("The ip tab of the browser, 0 is not use ip tab, 1 is use ip tab, default is 0"),
1757
- launchArgs: import_zod.z.string().optional().describe("The launch args of the browser, use chrome launch args, or vista url"),
1758
- clearCacheAfterClosing: import_zod.z.enum(["0", "1"]).optional().describe("The clear cache after closing of the browser, 0 is not clear cache after closing, 1 is clear cache after closing, default is 0"),
1759
- cdpMask: import_zod.z.enum(["0", "1"]).optional().describe("The cdp mask of the browser, 0 is not use cdp mask, 1 is use cdp mask, default is 0")
2313
+ fingerprint_config: fingerprintConfigSchema.optional(),
2314
+ launch_args: import_zod.z.string().optional().describe("Browser startup parameters"),
2315
+ profile_tag_ids: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to set on the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
2316
+ tags_update_type: import_zod.z.enum(["1", "2"]).optional().describe('How to apply profile_tag_ids: "1" (default) replace all existing tags; "2" append tags (truncated to 30 total if exceeded)'),
2317
+ profile_id: import_zod.z.string().describe("The profile id of the browser to update, it is required when you want to update the browser"),
2318
+ platform_account: platformAccountSchema
1760
2319
  }).strict(),
2320
+ openBrowserSchema: import_zod.z.object({
2321
+ profile_no: import_zod.z.string().optional().describe(
2322
+ "Profile serial number (environment number). At least one of profile_id or profile_no is required; if both are provided, profile_id takes priority (AdsPower API). "
2323
+ ),
2324
+ profile_id: import_zod.z.string().optional().describe(
2325
+ "Unique profile ID generated after creating a profile; identifies which browser to open. At least one of profile_id or profile_no is required; if both are provided, profile_id takes priority (AdsPower API). "
2326
+ ),
2327
+ ip_tab: import_zod.z.enum(["0", "1"]).optional().describe("The ip tab of the browser, 0 is not use ip tab, 1 is use ip tab, default is 0"),
2328
+ launch_args: import_zod.z.union([import_zod.z.string(), import_zod.z.array(import_zod.z.string())]).optional().describe('The launch args of the browser, use chrome launch args, eg: ["--window-position=400,0","--blink-settings=imagesEnabled=false", "--disable-notifications"]'),
2329
+ headless: import_zod.z.enum(["0", "1"]).optional().describe(
2330
+ 'Headless: "0" visible window, "1" headless. If omitted, the runtime may auto-set "1" when no graphical session is detected (Linux without DISPLAY/WAYLAND, or CI). Explicit "0"/"1" is always sent as-is.'
2331
+ ),
2332
+ last_opened_tabs: import_zod.z.enum(["0", "1"]).optional().describe("Whether to restore the last opened tabs."),
2333
+ proxy_detection: import_zod.z.enum(["0", "1"]).optional().describe("Whether to enable proxy detection."),
2334
+ password_filling: import_zod.z.enum(["0", "1"]).optional().describe("Whether to enable password auto-filling."),
2335
+ password_saving: import_zod.z.enum(["0", "1"]).optional().describe("Whether to enable password saving."),
2336
+ delete_cache: import_zod.z.enum(["0", "1"]).optional().describe("The clear cache after closing of the browser, 0 is not clear cache after closing, 1 is clear cache after closing, default is 0"),
2337
+ cdp_mask: import_zod.z.enum(["0", "1"]).optional().describe("The cdp mask of the browser, 0 is not use cdp mask, 1 is use cdp mask, default is 0"),
2338
+ device_scale: import_zod.z.string().optional().describe("Device scale factor passed to browser-profile/start.")
2339
+ }).strict().refine((data) => data.profile_id || data.profile_no, {
2340
+ message: "Either profile_id or profile_no must be provided"
2341
+ }),
1761
2342
  closeBrowserSchema: import_zod.z.object({
1762
- profileId: import_zod.z.string().optional().describe("The profile id of the browser to stop, either profileId or profileNo must be provided"),
1763
- profileNo: import_zod.z.string().optional().describe("The profile number of the browser to stop, priority will be given to profileId when profileId is filled")
1764
- }).refine((data) => data.profileId || data.profileNo, {
1765
- message: "Either profileId or profileNo must be provided"
2343
+ profile_id: import_zod.z.string().optional().describe("The profile id of the browser to stop, either profile_id or profile_no must be provided"),
2344
+ profile_no: import_zod.z.string().optional().describe("The profile number of the browser to stop, priority will be given to profile_id when profile_id is filled")
2345
+ }).strict().refine((data) => data.profile_id || data.profile_no, {
2346
+ message: "Either profile_id or profile_no must be provided"
1766
2347
  }),
1767
2348
  deleteBrowserSchema: import_zod.z.object({
1768
- profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids of the browsers to delete, it is required when you want to delete the browser")
2349
+ profile_id: import_zod.z.array(import_zod.z.string()).describe("The profile ids of the browsers to delete, it is required when you want to delete the browser")
1769
2350
  }).strict(),
1770
2351
  getBrowserListSchema: import_zod.z.object({
1771
- groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").optional().describe("Query by group ID; searches all groups if empty"),
1772
- limit: import_zod.z.number().optional().describe("Profiles per page. Number of profiles returned per page, range 1 ~ 200, default is 50"),
1773
- page: import_zod.z.number().optional().describe("Page number for results, default is 1"),
1774
- profileId: import_zod.z.array(import_zod.z.string()).optional().describe('Query by profile ID. Example: ["h1yynkm","h1yynks"]'),
1775
- profileNo: import_zod.z.array(import_zod.z.string()).optional().describe('Query by profile number. Example: ["123","124"]'),
1776
- sortType: import_zod.z.enum(["profile_no", "last_open_time", "created_time"]).optional().describe("Sort results by: profile_no, last_open_time, or created_time"),
1777
- sortOrder: import_zod.z.enum(["asc", "desc"]).optional().describe('Sort order: "asc" (ascending) or "desc" (descending)'),
1778
- tag_ids: import_zod.z.array(import_zod.z.string()).optional().describe('Tag IDs to filter profiles by tags. Example: ["tag1","tag2"]'),
2352
+ group_id: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").optional().describe("Query by group ID; searches all groups if empty"),
2353
+ limit: import_zod.z.number().min(1).max(200).optional().describe("Profiles per page. Number of profiles returned per page, range 1 ~ 200, default is 50"),
2354
+ page: import_zod.z.number().min(1).optional().describe("Page number for results, default is 1"),
2355
+ profile_id: nonEmptyStringArraySchema.optional().describe('Query by profile ID. Example: ["h1yynkm","h1yynks"]'),
2356
+ profile_no: nonEmptyStringArraySchema.optional().describe('Query by profile number. Example: ["123","124"]'),
2357
+ sort_type: import_zod.z.enum(["profile_no", "last_open_time", "created_time"]).optional().describe("Sort results by: profile_no, last_open_time, or created_time"),
2358
+ sort_order: import_zod.z.enum(["asc", "desc"]).optional().describe('Sort order: "asc" (ascending) or "desc" (descending)'),
2359
+ tag_ids: nonEmptyStringArraySchema.optional().describe('Tag IDs to filter profiles by tags. Example: ["tag1","tag2"]'),
1779
2360
  tags_filter: import_zod.z.enum(["include", "exclude"]).optional().describe('Tag matching mode: "include" (default) matches profiles with any of the tags, "exclude" matches profiles without the tags'),
1780
2361
  name: import_zod.z.string().optional().describe("Profile name keyword to search for"),
1781
2362
  name_filter: import_zod.z.enum(["include", "exclude"]).optional().describe('Name matching mode: "include" (default) matches profiles containing the name keyword, "exclude" matches profiles not containing the name keyword')
1782
2363
  }).strict(),
1783
2364
  moveBrowserSchema: import_zod.z.object({
1784
- groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The target group id, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
1785
- userIds: import_zod.z.array(import_zod.z.string()).describe("The browser Profile ids to move")
2365
+ group_id: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The target group id, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
2366
+ user_ids: import_zod.z.array(import_zod.z.string()).describe("The browser Profile ids to move")
1786
2367
  }).strict(),
1787
2368
  getProfileCookiesSchema: import_zod.z.object({
1788
- profileId: import_zod.z.string().optional().describe("The profile id, either profileId or profileNo must be provided"),
1789
- profileNo: import_zod.z.string().optional().describe("The profile number, priority will be given to profileId when profileId is filled")
1790
- }).refine((data) => data.profileId || data.profileNo, {
1791
- message: "Either profileId or profileNo must be provided"
2369
+ profile_id: import_zod.z.string().optional().describe("The profile id, either profile_id or profile_no must be provided"),
2370
+ profile_no: import_zod.z.string().optional().describe("The profile number, priority will be given to profile_id when profile_id is filled")
2371
+ }).strict().refine((data) => data.profile_id || data.profile_no, {
2372
+ message: "Either profile_id or profile_no must be provided"
1792
2373
  }),
1793
2374
  getProfileUaSchema: import_zod.z.object({
1794
- profileId: import_zod.z.array(import_zod.z.string()).optional().describe("The profile id array, either profileId or profileNo must be provided"),
1795
- profileNo: import_zod.z.array(import_zod.z.string()).optional().describe("The profile number array, priority will be given to profileId when profileId is filled")
1796
- }).refine((data) => data.profileId && data.profileId.length > 0 || data.profileNo && data.profileNo.length > 0, {
1797
- message: "Either profileId or profileNo must be provided with at least one element"
2375
+ profile_id: nonEmptyStringArraySchema.optional().describe("The profile id array, either profile_id or profile_no must be provided"),
2376
+ profile_no: nonEmptyStringArraySchema.optional().describe("The profile number array, priority will be given to profile_id when profile_id is filled")
2377
+ }).strict().refine((data) => data.profile_id && data.profile_id.length > 0 || data.profile_no && data.profile_no.length > 0, {
2378
+ message: "Either profile_id or profile_no must be provided with at least one element"
1798
2379
  }),
1799
2380
  closeAllProfilesSchema: import_zod.z.object({}).strict(),
1800
2381
  newFingerprintSchema: import_zod.z.object({
1801
- profileId: import_zod.z.array(import_zod.z.string()).optional().describe("The profile id array, either profileId or profileNo must be provided"),
1802
- profileNo: import_zod.z.array(import_zod.z.string()).optional().describe("The profile number array, priority will be given to profileId when profileId is filled")
1803
- }).strict(),
2382
+ profile_id: nonEmptyStringArraySchema.optional().describe("The profile id array, either profile_id or profile_no must be provided"),
2383
+ profile_no: nonEmptyStringArraySchema.optional().describe("The profile number array, priority will be given to profile_id when profile_id is filled")
2384
+ }).strict().refine((data) => data.profile_id && data.profile_id.length > 0 || data.profile_no && data.profile_no.length > 0, {
2385
+ message: "Either profile_id or profile_no must be provided with at least one element"
2386
+ }),
1804
2387
  deleteCacheV2Schema: import_zod.z.object({
1805
- profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
2388
+ profile_id: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
1806
2389
  type: import_zod.z.array(import_zod.z.enum(["local_storage", "indexeddb", "extension_cache", "cookie", "history", "image_file"])).describe("Types of cache to clear, it is required")
1807
2390
  }).strict(),
1808
2391
  shareProfileSchema: import_zod.z.object({
1809
- profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
2392
+ profile_id: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
1810
2393
  receiver: import_zod.z.string().describe("Receiver's account email or phone number (no area code), it is required"),
1811
- shareType: import_zod.z.number().int().optional().describe("Share type: 1 for email (default), 2 for phone number"),
2394
+ share_type: import_zod.z.number().int().optional().describe("Share type: 1 for email (default), 2 for phone number"),
1812
2395
  content: import_zod.z.array(import_zod.z.enum(["name", "proxy", "remark", "tabs"])).optional().describe("Shared content")
1813
2396
  }).strict(),
1814
2397
  createGroupSchema: import_zod.z.object({
1815
- groupName: import_zod.z.string().describe("The name of the group to create"),
2398
+ group_name: import_zod.z.string().describe("The name of the group to create"),
1816
2399
  remark: import_zod.z.string().optional().describe("The remark of the group")
1817
2400
  }).strict(),
1818
2401
  updateGroupSchema: import_zod.z.object({
1819
- groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The id of the group to update, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
1820
- groupName: import_zod.z.string().describe("The new name of the group"),
2402
+ group_id: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The id of the group to update, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
2403
+ group_name: import_zod.z.string().describe("The new name of the group"),
1821
2404
  remark: import_zod.z.string().nullable().optional().describe("The new remark of the group")
1822
2405
  }).strict(),
1823
2406
  getGroupListSchema: import_zod.z.object({
1824
- groupName: import_zod.z.string().optional().describe("The name of the group to search, use like to search"),
1825
- size: import_zod.z.number().optional().describe("The size of the page, max is 100, default is 10"),
2407
+ group_name: import_zod.z.string().optional().describe("The name of the group to search, use like to search"),
2408
+ page_size: import_zod.z.number().optional().describe("The size of the page, max is 100, default is 10"),
1826
2409
  page: import_zod.z.number().optional().describe("The page of the group, default is 1")
1827
2410
  }).strict(),
1828
2411
  getApplicationListSchema: import_zod.z.object({
@@ -1831,46 +2414,38 @@ var schemas = {
1831
2414
  limit: import_zod.z.number().min(1).max(100).optional().describe("Default 1, how many values are returned per page, range 1 to 100")
1832
2415
  }).strict(),
1833
2416
  getBrowserActiveSchema: import_zod.z.object({
1834
- profileId: import_zod.z.string().optional().describe("The profile id, either profileId or profileNo must be provided"),
1835
- profileNo: import_zod.z.string().optional().describe("The profile number, priority will be given to profileId when profileId is filled")
1836
- }).refine((data) => data.profileId || data.profileNo, {
1837
- message: "Either profileId or profileNo must be provided"
2417
+ profile_id: import_zod.z.string().optional().describe("The profile id, either profile_id or profile_no must be provided"),
2418
+ profile_no: import_zod.z.string().optional().describe("The profile number, priority will be given to profile_id when profile_id is filled")
2419
+ }).strict().refine((data) => data.profile_id || data.profile_no, {
2420
+ message: "Either profile_id or profile_no must be provided"
1838
2421
  }),
1839
2422
  getCloudActiveSchema: import_zod.z.object({
1840
- userIds: import_zod.z.string().describe("Profile IDs string to check (split by comma, max 100 per request). Unique profile ID, generated after creating the profile.")
1841
- }).refine((data) => data.userIds.split(",").length <= 100, {
2423
+ user_ids: import_zod.z.string().describe("Profile IDs string to check (split by comma, max 100 per request). Unique profile ID, generated after creating the profile.")
2424
+ }).refine((data) => data.user_ids.split(",").length <= 100, {
1842
2425
  message: "The number of profile ids is too many, the maximum is 100"
1843
2426
  }),
1844
- createProxySchema: import_zod.z.object({
1845
- proxies: import_zod.z.array(import_zod.z.object({
1846
- type: import_zod.z.enum(["http", "https", "ssh", "socks5"]).describe("Proxy type, support: http/https/ssh/socks5"),
1847
- host: import_zod.z.string().describe("Proxy host, support: ipV4, ipV6, eg: 192.168.0.1"),
1848
- port: import_zod.z.string().describe("Port, range: 0-65536, eg: 8000"),
1849
- user: import_zod.z.string().optional().describe("Proxy username, eg: user12345678"),
1850
- password: import_zod.z.string().optional().describe("Proxy password, eg: password"),
1851
- proxy_url: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
1852
- remark: import_zod.z.string().optional().describe("Remark/description for the proxy"),
1853
- ipchecker: import_zod.z.enum(["ipinfo", "ip2location", "ipapi", "ipfoxy"]).optional().describe("IP checker.")
1854
- }).strict()).describe("Array of proxy configurations to create")
2427
+ createProxySchema: import_zod.z.array(createProxyItemSchema).describe("Top-level array of proxy configurations to create"),
2428
+ createProxyMcpSchema: import_zod.z.object({
2429
+ proxies: import_zod.z.array(createProxyItemSchema).describe("Compatibility wrapper for MCP create-proxy input. Core and CLI accept a top-level array.")
1855
2430
  }).strict(),
1856
2431
  updateProxySchema: import_zod.z.object({
1857
- proxyId: import_zod.z.string().describe("The unique id after the proxy is added"),
2432
+ proxy_id: import_zod.z.string().describe("The unique id after the proxy is added"),
1858
2433
  type: import_zod.z.enum(["http", "https", "ssh", "socks5"]).optional().describe("Proxy type, support: http/https/ssh/socks5"),
1859
2434
  host: import_zod.z.string().optional().describe("Proxy host, support: ipV4, ipV6, eg: 192.168.0.1"),
1860
2435
  port: import_zod.z.string().optional().describe("Port, range: 0-65536, eg: 8000"),
1861
2436
  user: import_zod.z.string().optional().describe("Proxy username, eg: user12345678"),
1862
2437
  password: import_zod.z.string().optional().describe("Proxy password, eg: password"),
1863
- proxyUrl: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
2438
+ proxy_url: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
1864
2439
  remark: import_zod.z.string().optional().describe("Remark/description for the proxy"),
1865
2440
  ipchecker: import_zod.z.enum(["ip2location", "ipapi", "ipfoxy"]).optional().describe("IP checker.")
1866
2441
  }).strict(),
1867
2442
  getProxyListSchema: import_zod.z.object({
1868
2443
  limit: import_zod.z.number().optional().describe("Profiles per page. Number of proxies returned per page, range 1 ~ 200, default is 50"),
1869
2444
  page: import_zod.z.number().optional().describe("Page number for results, default is 1"),
1870
- proxyId: import_zod.z.array(import_zod.z.string()).optional().describe('Query by proxy ID. Example: ["proxy1","proxy2"]')
2445
+ proxy_id: nonEmptyStringArraySchema.optional().describe('Query by proxy ID. Single request can pass up to 100 proxy IDs. Example: ["proxy1","proxy2"]')
1871
2446
  }).strict(),
1872
2447
  deleteProxySchema: import_zod.z.object({
1873
- proxyIds: import_zod.z.array(import_zod.z.string()).describe("The proxy ids of the proxies to delete, it is required when you want to delete the proxy. The maximum is 100. ")
2448
+ proxy_id: import_zod.z.array(import_zod.z.string()).describe("The proxy ids of the proxies to delete, it is required when you want to delete the proxy. The maximum is 100. ")
1874
2449
  }).strict(),
1875
2450
  getTagListSchema: import_zod.z.object({
1876
2451
  ids: import_zod.z.array(import_zod.z.string()).optional().describe('Tag IDs to query, max 100 per request. Example: ["tag1","tag2"]'),
@@ -1954,155 +2529,241 @@ var schemas = {
1954
2529
  var STATELESS_HANDLERS = {
1955
2530
  "open-browser": {
1956
2531
  fn: browserHandlers.openBrowser,
1957
- description: "Open the browser, both environment and profile mean browser"
2532
+ description: buildCliCommandDescription(
2533
+ "open-browser",
2534
+ "Open the browser, both environment and profile mean browser"
2535
+ )
1958
2536
  },
1959
2537
  "close-browser": {
1960
2538
  fn: browserHandlers.closeBrowser,
1961
- description: "Close the browser"
2539
+ description: buildCliCommandDescription("close-browser", "Close the browser")
1962
2540
  },
1963
2541
  "create-browser": {
1964
2542
  fn: browserHandlers.createBrowser,
1965
- description: "Create a browser"
2543
+ description: buildCliCommandDescription("create-browser", "Create a browser")
1966
2544
  },
1967
2545
  "update-browser": {
1968
2546
  fn: browserHandlers.updateBrowser,
1969
- description: "Update the browser"
2547
+ description: buildCliCommandDescription("update-browser", "Update the browser")
1970
2548
  },
1971
2549
  "delete-browser": {
1972
2550
  fn: browserHandlers.deleteBrowser,
1973
- description: "Delete the browser"
2551
+ description: buildCliCommandDescription("delete-browser", "Delete the browser")
1974
2552
  },
1975
2553
  "get-browser-list": {
1976
2554
  fn: browserHandlers.getBrowserList,
1977
- description: "Get the list of browsers"
2555
+ description: buildCliCommandDescription("get-browser-list", "Get the list of browsers")
1978
2556
  },
1979
2557
  "get-opened-browser": {
1980
2558
  fn: browserHandlers.getOpenedBrowser,
1981
- description: "Get the list of opened browsers"
2559
+ description: buildCliCommandDescription("get-opened-browser", "Get the list of opened browsers")
1982
2560
  },
1983
2561
  "move-browser": {
1984
2562
  fn: browserHandlers.moveBrowser,
1985
- description: "Move browsers to a group"
2563
+ description: buildCliCommandDescription("move-browser", "Move browsers to a group")
1986
2564
  },
1987
2565
  "get-profile-cookies": {
1988
2566
  fn: browserHandlers.getProfileCookies,
1989
- description: "Query and return cookies of the specified profile. Only one profile can be queried per request."
2567
+ description: buildCliCommandDescription(
2568
+ "get-profile-cookies",
2569
+ "Query and return cookies of the specified profile. Only one profile can be queried per request."
2570
+ )
1990
2571
  },
1991
2572
  "get-profile-ua": {
1992
2573
  fn: browserHandlers.getProfileUa,
1993
- description: "Query and return the User-Agent of specified profiles. Up to 10 profiles can be queried per request."
2574
+ description: buildCliCommandDescription(
2575
+ "get-profile-ua",
2576
+ "Query and return the User-Agent of specified profiles. Up to 10 profiles can be queried per request."
2577
+ )
1994
2578
  },
1995
2579
  "close-all-profiles": {
1996
2580
  fn: browserHandlers.closeAllProfiles,
1997
- description: "Close all opened profiles on the current device"
2581
+ description: buildCliCommandDescription(
2582
+ "close-all-profiles",
2583
+ "Close all opened profiles on the current device"
2584
+ )
1998
2585
  },
1999
2586
  "new-fingerprint": {
2000
2587
  fn: browserHandlers.newFingerprint,
2001
- description: "Generate a new fingerprint for specified profiles. Up to 10 profiles are supported per request."
2588
+ description: buildCliCommandDescription(
2589
+ "new-fingerprint",
2590
+ "Generate a new fingerprint for specified profiles. Up to 10 profiles are supported per request."
2591
+ )
2002
2592
  },
2003
2593
  "delete-cache-v2": {
2004
2594
  fn: browserHandlers.deleteCacheV2,
2005
- description: "Clear local cache of specific profiles.For account security, please ensure that there are no open browsers on the device when using this interface."
2595
+ description: buildCliCommandDescription(
2596
+ "delete-cache-v2",
2597
+ "Clear local cache of specific profiles.For account security, please ensure that there are no open browsers on the device when using this interface."
2598
+ )
2006
2599
  },
2007
2600
  "share-profile": {
2008
2601
  fn: browserHandlers.shareProfile,
2009
- description: "Share profiles via account email or phone number. The maximum number of profiles that can be shared at one time is 200."
2602
+ description: buildCliCommandDescription(
2603
+ "share-profile",
2604
+ "Share profiles via account email or phone number. The maximum number of profiles that can be shared at one time is 200."
2605
+ )
2010
2606
  },
2011
2607
  "get-browser-active": {
2012
2608
  fn: browserHandlers.getBrowserActive,
2013
- description: "Get active browser profile information"
2609
+ description: buildCliCommandDescription("get-browser-active", "Get active browser profile information")
2014
2610
  },
2015
2611
  "get-cloud-active": {
2016
2612
  fn: browserHandlers.getCloudActive,
2017
- description: 'Query the status of browser profiles by user_id, up to 100 profiles per request. If the team has enabled "Multi device mode," specific statuses cannot be retrieved and the response will indicate "Profile not opened."'
2613
+ description: buildCliCommandDescription(
2614
+ "get-cloud-active",
2615
+ 'Query the status of browser profiles by user_ids, up to 100 profiles per request. If the team has enabled "Multi device mode," specific statuses cannot be retrieved and the response will indicate "Profile not opened."'
2616
+ )
2018
2617
  },
2019
2618
  "create-group": {
2020
2619
  fn: groupHandlers.createGroup,
2021
- description: "Create a browser group"
2620
+ description: buildCliCommandDescription("create-group", "Create a browser group")
2022
2621
  },
2023
2622
  "update-group": {
2024
2623
  fn: groupHandlers.updateGroup,
2025
- description: "Update the browser group"
2624
+ description: buildCliCommandDescription("update-group", "Update the browser group")
2026
2625
  },
2027
2626
  "get-group-list": {
2028
2627
  fn: groupHandlers.getGroupList,
2029
- description: "Get the list of groups"
2628
+ description: buildCliCommandDescription("get-group-list", "Get the list of groups")
2030
2629
  },
2031
2630
  "check-status": {
2032
2631
  fn: applicationHandlers.checkStatus,
2033
- description: "Check the availability of the current device API interface (Connection Status)"
2632
+ description: buildCliCommandDescription(
2633
+ "check-status",
2634
+ "Check the availability of the current device API interface (Connection Status)"
2635
+ )
2034
2636
  },
2035
2637
  "get-application-list": {
2036
2638
  fn: applicationHandlers.getApplicationList,
2037
- description: "Get the list of applications (categories)"
2639
+ description: buildCliCommandDescription(
2640
+ "get-application-list",
2641
+ "Get the list of applications (categories)"
2642
+ )
2038
2643
  },
2039
2644
  "create-proxy": {
2040
2645
  fn: proxyHandlers.createProxy,
2041
- description: "Create the proxy"
2646
+ description: buildCliCommandDescription("create-proxy", "Create the proxy")
2042
2647
  },
2043
2648
  "update-proxy": {
2044
2649
  fn: proxyHandlers.updateProxy,
2045
- description: "Update the proxy"
2650
+ description: buildCliCommandDescription("update-proxy", "Update the proxy")
2046
2651
  },
2047
2652
  "get-proxy-list": {
2048
2653
  fn: proxyHandlers.getProxyList,
2049
- description: "Get the list of proxies"
2654
+ description: buildCliCommandDescription("get-proxy-list", "Get the list of proxies")
2050
2655
  },
2051
2656
  "delete-proxy": {
2052
2657
  fn: proxyHandlers.deleteProxy,
2053
- description: "Delete the proxy"
2658
+ description: buildCliCommandDescription("delete-proxy", "Delete the proxy")
2054
2659
  },
2055
2660
  "get-tag-list": {
2056
2661
  fn: tagHandlers.getTagList,
2057
- description: "Get the list of browser tags"
2662
+ description: buildCliCommandDescription("get-tag-list", "Get the list of browser tags")
2058
2663
  },
2059
2664
  "create-tag": {
2060
2665
  fn: tagHandlers.createTag,
2061
- description: "Create browser tags (batch supported)"
2666
+ description: buildCliCommandDescription("create-tag", "Create browser tags (batch supported)")
2062
2667
  },
2063
2668
  "update-tag": {
2064
2669
  fn: tagHandlers.updateTag,
2065
- description: "Update browser tags (batch supported)"
2670
+ description: buildCliCommandDescription("update-tag", "Update browser tags (batch supported)")
2066
2671
  },
2067
2672
  "delete-tag": {
2068
2673
  fn: tagHandlers.deleteTag,
2069
- description: "Delete browser tags"
2674
+ description: buildCliCommandDescription("delete-tag", "Delete browser tags")
2070
2675
  },
2071
2676
  "download-kernel": {
2072
2677
  fn: kernelHandlers.downloadKernel,
2073
- description: "Download or update a browser kernel version"
2678
+ description: buildCliCommandDescription(
2679
+ "download-kernel",
2680
+ "Download or update a browser kernel version"
2681
+ )
2074
2682
  },
2075
2683
  "get-kernel-list": {
2076
2684
  fn: kernelHandlers.getKernelList,
2077
- description: "Get browser kernel list by type or all"
2685
+ description: buildCliCommandDescription("get-kernel-list", "Get browser kernel list by type or all")
2078
2686
  },
2079
2687
  "update-patch": {
2080
2688
  fn: patchHandlers.updatePatch,
2081
- description: "Update AdsPower to latest patch version"
2689
+ description: buildCliCommandDescription("update-patch", "Update AdsPower to latest patch version")
2082
2690
  }
2083
2691
  };
2084
2692
  var SINGLE_PROFILE_ID_COMMANDS = {
2085
- "open-browser": "profileId",
2086
- "close-browser": "profileId",
2087
- "get-profile-cookies": "profileId",
2088
- "get-browser-active": "profileId"
2693
+ "open-browser": "profile_id",
2694
+ "close-browser": "profile_id",
2695
+ "get-profile-cookies": "profile_id",
2696
+ "get-browser-active": "profile_id"
2089
2697
  };
2090
2698
  var SINGLE_PROFILE_ID_ARRAY_COMMANDS = ["get-profile-ua", "new-fingerprint"];
2699
+ function resolveStatelessCommandArgs(commandName, params) {
2700
+ let args = {};
2701
+ if (!params) {
2702
+ return { ok: true, args };
2703
+ }
2704
+ const trimmed = params.trim();
2705
+ if (trimmed.startsWith("{")) {
2706
+ try {
2707
+ args = JSON.parse(params);
2708
+ return { ok: true, args };
2709
+ } catch {
2710
+ return { ok: false, error: "Invalid JSON for command args" };
2711
+ }
2712
+ }
2713
+ if (SINGLE_PROFILE_ID_COMMANDS[commandName]) {
2714
+ if (!isNaN(Number(trimmed))) {
2715
+ return { ok: true, args: { profile_no: trimmed } };
2716
+ }
2717
+ return { ok: true, args: { profile_id: trimmed } };
2718
+ }
2719
+ if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(commandName)) {
2720
+ if (!isNaN(Number(trimmed))) {
2721
+ return { ok: true, args: { profile_no: [trimmed] } };
2722
+ }
2723
+ return { ok: true, args: { profile_id: [trimmed] } };
2724
+ }
2725
+ try {
2726
+ args = JSON.parse(params);
2727
+ return { ok: true, args };
2728
+ } catch {
2729
+ return {
2730
+ ok: false,
2731
+ error: `Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`
2732
+ };
2733
+ }
2734
+ }
2735
+
2736
+ // src/startConfig.ts
2737
+ var MISSING_API_KEY_ERROR = "error: required option '-k, --api-key <apiKey>' not specified";
2738
+ function resolveStartApiKey(optionApiKey, env = process.env) {
2739
+ if (optionApiKey) {
2740
+ return {
2741
+ ok: true,
2742
+ apiKey: optionApiKey
2743
+ };
2744
+ }
2745
+ if (env.ADS_API_KEY) {
2746
+ return {
2747
+ ok: true,
2748
+ apiKey: env.ADS_API_KEY
2749
+ };
2750
+ }
2751
+ return {
2752
+ ok: false,
2753
+ error: MISSING_API_KEY_ERROR
2754
+ };
2755
+ }
2091
2756
 
2092
2757
  // src/index.ts
2093
2758
  var program = new import_commander.Command();
2094
2759
  program.name("adspower-browser").description("CLI and runtime for adspower-browser").version(VERSION);
2095
2760
  program.command("start").description("Start the adspower runtime").option("-k, --api-key <apiKey>", "Set the API key for the adspower runtime").addOption(new import_commander.Option("--base-url <baseUrl>", "Set the base URL for the adspower runtime").hideHelp()).addOption(new import_commander.Option("--node-env <nodeEnv>", "Set the node environment for the adspower runtime").hideHelp()).action(async (options) => {
2096
- if (options.apiKey) {
2097
- store.setStoreValue("apiKey", options.apiKey);
2098
- } else {
2099
- const apiKey = process.env.ADS_API_KEY;
2100
- if (!apiKey) {
2101
- logError("error: required option '-k, --api-key <apiKey>' not specified");
2102
- process.exit(1);
2103
- }
2104
- store.setStoreValue("apiKey", "");
2761
+ const resolvedApiKey = resolveStartApiKey(options.apiKey, process.env);
2762
+ if (!resolvedApiKey.ok) {
2763
+ logError(resolvedApiKey.error);
2764
+ process.exit(1);
2105
2765
  }
2766
+ store.setStoreValue("apiKey", resolvedApiKey.apiKey);
2106
2767
  if (options.baseUrl) {
2107
2768
  store.setStoreValue("baseUrl", options.baseUrl);
2108
2769
  }
@@ -2132,34 +2793,12 @@ for (const cmd of Object.keys(STATELESS_HANDLERS)) {
2132
2793
  }
2133
2794
  const { apiKey, port } = getApiKeyAndPort(options);
2134
2795
  updateConfig(apiKey, port);
2135
- let args = {};
2136
- if (params) {
2137
- const trimmed = params.trim();
2138
- if (trimmed.startsWith("{")) {
2139
- try {
2140
- args = JSON.parse(params);
2141
- } catch {
2142
- logError("Invalid JSON for command args");
2143
- return;
2144
- }
2145
- } else if (SINGLE_PROFILE_ID_COMMANDS[command.name()]) {
2146
- const key = SINGLE_PROFILE_ID_COMMANDS[command.name()];
2147
- if (!isNaN(Number(trimmed))) {
2148
- args = { profileNo: Number(trimmed) };
2149
- } else {
2150
- args = { profileId: trimmed };
2151
- }
2152
- } else if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(command.name())) {
2153
- args = { profileId: [trimmed] };
2154
- } else {
2155
- try {
2156
- args = JSON.parse(params);
2157
- } catch {
2158
- logError(`Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`);
2159
- return;
2160
- }
2161
- }
2796
+ const resolved = resolveStatelessCommandArgs(command.name(), params);
2797
+ if (!resolved.ok) {
2798
+ logError(resolved.error);
2799
+ return;
2162
2800
  }
2801
+ const args = resolved.args;
2163
2802
  logSuccess(`Executing command: ${command.name()}, params: ${JSON.stringify(args)}`);
2164
2803
  const loading = createLoading(`Executing ${command.name()}...`);
2165
2804
  try {