@midscene/android 1.10.6-beta-20260717061640.0 → 1.10.6

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.
package/dist/es/cli.mjs CHANGED
@@ -14,7 +14,7 @@ import { createDefaultMobileActions, defineAction } from "@midscene/core/device"
14
14
  import { getTmpFile, sleep } from "@midscene/core/utils";
15
15
  import { MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, globalConfigManager } from "@midscene/shared/env";
16
16
  import { createImgBase64ByFormat, validateScreenshotBuffer } from "@midscene/shared/img";
17
- import { ADB as external_appium_adb_ADB } from "appium-adb";
17
+ import { ADB, getSdkRootFromEnv } from "appium-adb";
18
18
  var __webpack_modules__ = {
19
19
  "./src/scrcpy-manager.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
20
20
  __webpack_require__.d(__webpack_exports__, {
@@ -678,6 +678,35 @@ const defaultAppNameMapping = {
678
678
  var external_node_fs_ = __webpack_require__("node:fs");
679
679
  var external_node_module_ = __webpack_require__("node:module");
680
680
  var external_node_path_ = __webpack_require__("node:path");
681
+ const warnAdb = (0, logger_.getDebug)('android:adb', {
682
+ console: true
683
+ });
684
+ async function adb_createAndroidAdb({ adbExecTimeout, deviceId, deviceOptions }) {
685
+ const androidAdbPath = deviceOptions?.androidAdbPath || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_PATH);
686
+ const remoteAdbHost = deviceOptions?.remoteAdbHost || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_HOST);
687
+ const remoteAdbPort = deviceOptions?.remoteAdbPort || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_PORT);
688
+ const adbOptions = {
689
+ udid: deviceId,
690
+ adbExecTimeout,
691
+ remoteAdbHost: remoteAdbHost || void 0,
692
+ remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
693
+ };
694
+ if (androidAdbPath) return new ADB({
695
+ ...adbOptions,
696
+ executable: {
697
+ path: androidAdbPath,
698
+ defaultArgs: []
699
+ }
700
+ });
701
+ const sdkRoot = getSdkRootFromEnv();
702
+ if (sdkRoot) try {
703
+ return await ADB.createADB(adbOptions);
704
+ } catch (error) {
705
+ const message = error instanceof Error ? error.message : String(error);
706
+ warnAdb(`Unable to initialize adb from Android SDK at "${sdkRoot}", falling back to adb from PATH: ${message}`);
707
+ }
708
+ return new ADB(adbOptions);
709
+ }
681
710
  var scrcpy_manager = __webpack_require__("./src/scrcpy-manager.ts");
682
711
  function _define_property(obj, key, value) {
683
712
  if (key in obj) Object.defineProperty(obj, key, {
@@ -691,6 +720,10 @@ function _define_property(obj, key, value) {
691
720
  }
692
721
  const debugAdapter = (0, logger_.getDebug)('android:scrcpy-adapter');
693
722
  const SCRCPY_RETRY_COOLDOWN_MS = 5000;
723
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
724
+ host: '127.0.0.1',
725
+ port: 5037
726
+ };
694
727
  class ScrcpyDeviceAdapter {
695
728
  isEnabled() {
696
729
  if (!this.isConfigured()) return false;
@@ -749,10 +782,8 @@ class ScrcpyDeviceAdapter {
749
782
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
750
783
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
751
784
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
752
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
753
- host: '127.0.0.1',
754
- port: 5037
755
- }));
785
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
786
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
756
787
  const adb = new Adb(await adbClient.createTransport({
757
788
  serial: this.deviceId
758
789
  }));
@@ -832,15 +863,17 @@ class ScrcpyDeviceAdapter {
832
863
  this.resolvedConfig = null;
833
864
  this.clearFailure();
834
865
  }
835
- constructor(deviceId, scrcpyConfig){
866
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
836
867
  _define_property(this, "deviceId", void 0);
837
868
  _define_property(this, "scrcpyConfig", void 0);
869
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
838
870
  _define_property(this, "manager", void 0);
839
871
  _define_property(this, "resolvedConfig", void 0);
840
872
  _define_property(this, "lastError", void 0);
841
873
  _define_property(this, "retryAfter", void 0);
842
874
  this.deviceId = deviceId;
843
875
  this.scrcpyConfig = scrcpyConfig;
876
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
844
877
  this.manager = null;
845
878
  this.resolvedConfig = null;
846
879
  this.lastError = null;
@@ -983,18 +1016,10 @@ class AndroidDevice {
983
1016
  let error = null;
984
1017
  debugDevice(`Initializing ADB with device ID: ${this.deviceId}`);
985
1018
  try {
986
- const androidAdbPath = this.options?.androidAdbPath || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_PATH);
987
- const remoteAdbHost = this.options?.remoteAdbHost || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_HOST);
988
- const remoteAdbPort = this.options?.remoteAdbPort || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_PORT);
989
- this.adb = new external_appium_adb_ADB({
990
- udid: this.deviceId,
1019
+ this.adb = await adb_createAndroidAdb({
991
1020
  adbExecTimeout: 60000,
992
- executable: androidAdbPath ? {
993
- path: androidAdbPath,
994
- defaultArgs: []
995
- } : void 0,
996
- remoteAdbHost: remoteAdbHost || void 0,
997
- remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
1021
+ deviceId: this.deviceId,
1022
+ deviceOptions: this.options
998
1023
  });
999
1024
  const size = await this.getScreenSize();
1000
1025
  this.description = `
@@ -1029,8 +1054,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1029
1054
  } catch (error) {
1030
1055
  const methodName = String(prop);
1031
1056
  const deviceId = this.deviceId;
1032
- debugDevice(`ADB error with device ${deviceId} when calling ${methodName}: ${error}`);
1033
- throw new Error(`ADB error with device ${deviceId} when calling ${methodName}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
1057
+ const adbExecutable = target.executable.path;
1058
+ debugDevice(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}): ${error}`);
1059
+ throw new Error(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}), please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
1034
1060
  cause: error
1035
1061
  });
1036
1062
  }
@@ -1049,7 +1075,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1049
1075
  return adapter.getStatus();
1050
1076
  }
1051
1077
  getScrcpyAdapter() {
1052
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig);
1078
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1079
+ const adb = await this.getAdb();
1080
+ return {
1081
+ host: adb.adbHost ?? '127.0.0.1',
1082
+ port: adb.adbPort ?? 5037
1083
+ };
1084
+ });
1053
1085
  return this.scrcpyAdapter;
1054
1086
  }
1055
1087
  async openScrcpyFrameSource() {
@@ -2081,17 +2113,21 @@ const createPlatformActions = (device)=>({
2081
2113
  })
2082
2114
  });
2083
2115
  const debugUtils = (0, logger_.getDebug)('android:utils');
2084
- async function getConnectedDevices() {
2116
+ async function getConnectedDevices(deviceOptions) {
2117
+ let adbExecutable;
2085
2118
  try {
2086
- const adb = await external_appium_adb_ADB.createADB({
2087
- adbExecTimeout: 60000
2119
+ const adb = await adb_createAndroidAdb({
2120
+ adbExecTimeout: 60000,
2121
+ deviceOptions
2088
2122
  });
2123
+ adbExecutable = adb.executable.path;
2089
2124
  const devices = await adb.getConnectedDevices();
2090
2125
  debugUtils(`Found ${devices.length} connected devices: `, devices);
2091
2126
  return devices;
2092
2127
  } catch (error) {
2093
2128
  console.error('Failed to get device list:', error);
2094
- throw new Error(`Unable to get connected Android device list, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2129
+ const adbExecutableContext = adbExecutable ? ` (ADB executable: ${adbExecutable})` : '';
2130
+ throw new Error(`Unable to get connected Android device list${adbExecutableContext}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2095
2131
  cause: error
2096
2132
  });
2097
2133
  }
@@ -2147,7 +2183,7 @@ class AndroidAgent extends Agent {
2147
2183
  }
2148
2184
  async function agentFromAdbDevice(deviceId, opts) {
2149
2185
  if (!deviceId) {
2150
- const devices = await getConnectedDevices();
2186
+ const devices = await getConnectedDevices(opts);
2151
2187
  if (0 === devices.length) throw new Error('No Android devices found. Please connect an Android device and ensure ADB is properly configured. Run `adb devices` to verify device connection.');
2152
2188
  deviceId = devices[0].udid;
2153
2189
  debugAgent('deviceId not specified, will use the first device (id = %s)', deviceId);
@@ -2276,7 +2312,7 @@ class AndroidMidsceneTools extends BaseMidsceneTools {
2276
2312
  const tools = new AndroidMidsceneTools();
2277
2313
  runToolsCLI(tools, 'midscene-android', {
2278
2314
  stripPrefix: 'android_',
2279
- version: "1.10.6-beta-20260717061640.0",
2315
+ version: "1.10.6",
2280
2316
  extraCommands: createReportCliCommands()
2281
2317
  }).catch((e)=>{
2282
2318
  process.exit(reportCLIError(e));
package/dist/es/index.mjs CHANGED
@@ -10,7 +10,7 @@ import { getTmpFile, sleep } from "@midscene/core/utils";
10
10
  import { MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, globalConfigManager, overrideAIConfig } from "@midscene/shared/env";
11
11
  import { createImgBase64ByFormat, validateScreenshotBuffer } from "@midscene/shared/img";
12
12
  import { mergeAndNormalizeAppNameMapping, normalizeForComparison, repeat } from "@midscene/shared/utils";
13
- import { ADB } from "appium-adb";
13
+ import { ADB, getSdkRootFromEnv } from "appium-adb";
14
14
  import { Agent } from "@midscene/core/agent";
15
15
  import { agentBehaviorInitArgShape, extractAgentBehaviorInitArgs, getAgentInitArgsSignature, shouldRebuildAgentForInitArgs } from "@midscene/shared/agent-tools/agent-behavior-init-args";
16
16
  import { BaseMidsceneTools } from "@midscene/shared/agent-tools/base-tools";
@@ -542,6 +542,35 @@ var external_node_fs_ = __webpack_require__("node:fs");
542
542
  var external_node_module_ = __webpack_require__("node:module");
543
543
  var external_node_path_ = __webpack_require__("node:path");
544
544
  var logger_ = __webpack_require__("@midscene/shared/logger");
545
+ const warnAdb = (0, logger_.getDebug)('android:adb', {
546
+ console: true
547
+ });
548
+ async function createAndroidAdb({ adbExecTimeout, deviceId, deviceOptions }) {
549
+ const androidAdbPath = deviceOptions?.androidAdbPath || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_PATH);
550
+ const remoteAdbHost = deviceOptions?.remoteAdbHost || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_HOST);
551
+ const remoteAdbPort = deviceOptions?.remoteAdbPort || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_PORT);
552
+ const adbOptions = {
553
+ udid: deviceId,
554
+ adbExecTimeout,
555
+ remoteAdbHost: remoteAdbHost || void 0,
556
+ remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
557
+ };
558
+ if (androidAdbPath) return new ADB({
559
+ ...adbOptions,
560
+ executable: {
561
+ path: androidAdbPath,
562
+ defaultArgs: []
563
+ }
564
+ });
565
+ const sdkRoot = getSdkRootFromEnv();
566
+ if (sdkRoot) try {
567
+ return await ADB.createADB(adbOptions);
568
+ } catch (error) {
569
+ const message = error instanceof Error ? error.message : String(error);
570
+ warnAdb(`Unable to initialize adb from Android SDK at "${sdkRoot}", falling back to adb from PATH: ${message}`);
571
+ }
572
+ return new ADB(adbOptions);
573
+ }
545
574
  const EMPTY_ADB_SHELL_STDOUT = '<empty>';
546
575
  const MAX_RUN_ADB_SHELL_STDOUT = 200;
547
576
  function normalizeShellStream(value) {
@@ -594,6 +623,10 @@ function _define_property(obj, key, value) {
594
623
  }
595
624
  const debugAdapter = (0, logger_.getDebug)('android:scrcpy-adapter');
596
625
  const SCRCPY_RETRY_COOLDOWN_MS = 5000;
626
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
627
+ host: '127.0.0.1',
628
+ port: 5037
629
+ };
597
630
  class ScrcpyDeviceAdapter {
598
631
  isEnabled() {
599
632
  if (!this.isConfigured()) return false;
@@ -652,10 +685,8 @@ class ScrcpyDeviceAdapter {
652
685
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
653
686
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
654
687
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
655
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
656
- host: '127.0.0.1',
657
- port: 5037
658
- }));
688
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
689
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
659
690
  const adb = new Adb(await adbClient.createTransport({
660
691
  serial: this.deviceId
661
692
  }));
@@ -735,15 +766,17 @@ class ScrcpyDeviceAdapter {
735
766
  this.resolvedConfig = null;
736
767
  this.clearFailure();
737
768
  }
738
- constructor(deviceId, scrcpyConfig){
769
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
739
770
  _define_property(this, "deviceId", void 0);
740
771
  _define_property(this, "scrcpyConfig", void 0);
772
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
741
773
  _define_property(this, "manager", void 0);
742
774
  _define_property(this, "resolvedConfig", void 0);
743
775
  _define_property(this, "lastError", void 0);
744
776
  _define_property(this, "retryAfter", void 0);
745
777
  this.deviceId = deviceId;
746
778
  this.scrcpyConfig = scrcpyConfig;
779
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
747
780
  this.manager = null;
748
781
  this.resolvedConfig = null;
749
782
  this.lastError = null;
@@ -886,18 +919,10 @@ class AndroidDevice {
886
919
  let error = null;
887
920
  debugDevice(`Initializing ADB with device ID: ${this.deviceId}`);
888
921
  try {
889
- const androidAdbPath = this.options?.androidAdbPath || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_PATH);
890
- const remoteAdbHost = this.options?.remoteAdbHost || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_HOST);
891
- const remoteAdbPort = this.options?.remoteAdbPort || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_PORT);
892
- this.adb = new ADB({
893
- udid: this.deviceId,
922
+ this.adb = await createAndroidAdb({
894
923
  adbExecTimeout: 60000,
895
- executable: androidAdbPath ? {
896
- path: androidAdbPath,
897
- defaultArgs: []
898
- } : void 0,
899
- remoteAdbHost: remoteAdbHost || void 0,
900
- remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
924
+ deviceId: this.deviceId,
925
+ deviceOptions: this.options
901
926
  });
902
927
  const size = await this.getScreenSize();
903
928
  this.description = `
@@ -932,8 +957,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
932
957
  } catch (error) {
933
958
  const methodName = String(prop);
934
959
  const deviceId = this.deviceId;
935
- debugDevice(`ADB error with device ${deviceId} when calling ${methodName}: ${error}`);
936
- throw new Error(`ADB error with device ${deviceId} when calling ${methodName}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
960
+ const adbExecutable = target.executable.path;
961
+ debugDevice(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}): ${error}`);
962
+ throw new Error(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}), please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
937
963
  cause: error
938
964
  });
939
965
  }
@@ -952,7 +978,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
952
978
  return adapter.getStatus();
953
979
  }
954
980
  getScrcpyAdapter() {
955
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig);
981
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
982
+ const adb = await this.getAdb();
983
+ return {
984
+ host: adb.adbHost ?? '127.0.0.1',
985
+ port: adb.adbPort ?? 5037
986
+ };
987
+ });
956
988
  return this.scrcpyAdapter;
957
989
  }
958
990
  async openScrcpyFrameSource() {
@@ -2107,35 +2139,40 @@ async function withTimeout(promise, timeoutMs, label) {
2107
2139
  if (timer) clearTimeout(timer);
2108
2140
  }
2109
2141
  }
2110
- async function createAdbForDetailLookup() {
2111
- return await ADB.createADB({
2112
- adbExecTimeout: DETAIL_LOOKUP_ADB_TIMEOUT_MS
2142
+ async function createAdbForDetailLookup(deviceOptions) {
2143
+ return await createAndroidAdb({
2144
+ adbExecTimeout: DETAIL_LOOKUP_ADB_TIMEOUT_MS,
2145
+ deviceOptions
2113
2146
  });
2114
2147
  }
2115
- async function getConnectedDevices() {
2148
+ async function getConnectedDevices(deviceOptions) {
2149
+ let adbExecutable;
2116
2150
  try {
2117
- const adb = await ADB.createADB({
2118
- adbExecTimeout: 60000
2151
+ const adb = await createAndroidAdb({
2152
+ adbExecTimeout: 60000,
2153
+ deviceOptions
2119
2154
  });
2155
+ adbExecutable = adb.executable.path;
2120
2156
  const devices = await adb.getConnectedDevices();
2121
2157
  debugUtils(`Found ${devices.length} connected devices: `, devices);
2122
2158
  return devices;
2123
2159
  } catch (error) {
2124
2160
  console.error('Failed to get device list:', error);
2125
- throw new Error(`Unable to get connected Android device list, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2161
+ const adbExecutableContext = adbExecutable ? ` (ADB executable: ${adbExecutable})` : '';
2162
+ throw new Error(`Unable to get connected Android device list${adbExecutableContext}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2126
2163
  cause: error
2127
2164
  });
2128
2165
  }
2129
2166
  }
2130
- async function getConnectedDevicesWithDetails() {
2131
- const devices = await getConnectedDevices();
2167
+ async function getConnectedDevicesWithDetails(deviceOptions) {
2168
+ const devices = await getConnectedDevices(deviceOptions);
2132
2169
  if (0 === devices.length) return [];
2133
2170
  return await Promise.all(devices.map(async (device)=>{
2134
2171
  const detailedDevice = {
2135
2172
  ...device
2136
2173
  };
2137
2174
  try {
2138
- const adb = await createAdbForDetailLookup();
2175
+ const adb = await createAdbForDetailLookup(deviceOptions);
2139
2176
  adb.setDeviceId(device.udid);
2140
2177
  const [modelResult, brandResult, sizeResult, densityResult] = await Promise.allSettled([
2141
2178
  withTimeout(adb.shell([
@@ -2213,7 +2250,7 @@ class AndroidAgent extends Agent {
2213
2250
  }
2214
2251
  async function agentFromAdbDevice(deviceId, opts) {
2215
2252
  if (!deviceId) {
2216
- const devices = await getConnectedDevices();
2253
+ const devices = await getConnectedDevices(opts);
2217
2254
  if (0 === devices.length) throw new Error('No Android devices found. Please connect an Android device and ensure ADB is properly configured. Run `adb devices` to verify device connection.');
2218
2255
  deviceId = devices[0].udid;
2219
2256
  debugAgent('deviceId not specified, will use the first device (id = %s)', deviceId);
package/dist/lib/cli.js CHANGED
@@ -693,6 +693,35 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
693
693
  const env_namespaceObject = require("@midscene/shared/env");
694
694
  const img_namespaceObject = require("@midscene/shared/img");
695
695
  const external_appium_adb_namespaceObject = require("appium-adb");
696
+ const warnAdb = (0, logger_.getDebug)('android:adb', {
697
+ console: true
698
+ });
699
+ async function adb_createAndroidAdb({ adbExecTimeout, deviceId, deviceOptions }) {
700
+ const androidAdbPath = deviceOptions?.androidAdbPath || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_PATH);
701
+ const remoteAdbHost = deviceOptions?.remoteAdbHost || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_HOST);
702
+ const remoteAdbPort = deviceOptions?.remoteAdbPort || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_PORT);
703
+ const adbOptions = {
704
+ udid: deviceId,
705
+ adbExecTimeout,
706
+ remoteAdbHost: remoteAdbHost || void 0,
707
+ remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
708
+ };
709
+ if (androidAdbPath) return new external_appium_adb_namespaceObject.ADB({
710
+ ...adbOptions,
711
+ executable: {
712
+ path: androidAdbPath,
713
+ defaultArgs: []
714
+ }
715
+ });
716
+ const sdkRoot = (0, external_appium_adb_namespaceObject.getSdkRootFromEnv)();
717
+ if (sdkRoot) try {
718
+ return await external_appium_adb_namespaceObject.ADB.createADB(adbOptions);
719
+ } catch (error) {
720
+ const message = error instanceof Error ? error.message : String(error);
721
+ warnAdb(`Unable to initialize adb from Android SDK at "${sdkRoot}", falling back to adb from PATH: ${message}`);
722
+ }
723
+ return new external_appium_adb_namespaceObject.ADB(adbOptions);
724
+ }
696
725
  var scrcpy_manager = __webpack_require__("./src/scrcpy-manager.ts");
697
726
  function _define_property(obj, key, value) {
698
727
  if (key in obj) Object.defineProperty(obj, key, {
@@ -706,6 +735,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
706
735
  }
707
736
  const debugAdapter = (0, logger_.getDebug)('android:scrcpy-adapter');
708
737
  const SCRCPY_RETRY_COOLDOWN_MS = 5000;
738
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
739
+ host: '127.0.0.1',
740
+ port: 5037
741
+ };
709
742
  class ScrcpyDeviceAdapter {
710
743
  isEnabled() {
711
744
  if (!this.isConfigured()) return false;
@@ -764,10 +797,8 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
764
797
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
765
798
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
766
799
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
767
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
768
- host: '127.0.0.1',
769
- port: 5037
770
- }));
800
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
801
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
771
802
  const adb = new Adb(await adbClient.createTransport({
772
803
  serial: this.deviceId
773
804
  }));
@@ -847,15 +878,17 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
847
878
  this.resolvedConfig = null;
848
879
  this.clearFailure();
849
880
  }
850
- constructor(deviceId, scrcpyConfig){
881
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
851
882
  _define_property(this, "deviceId", void 0);
852
883
  _define_property(this, "scrcpyConfig", void 0);
884
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
853
885
  _define_property(this, "manager", void 0);
854
886
  _define_property(this, "resolvedConfig", void 0);
855
887
  _define_property(this, "lastError", void 0);
856
888
  _define_property(this, "retryAfter", void 0);
857
889
  this.deviceId = deviceId;
858
890
  this.scrcpyConfig = scrcpyConfig;
891
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
859
892
  this.manager = null;
860
893
  this.resolvedConfig = null;
861
894
  this.lastError = null;
@@ -998,18 +1031,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
998
1031
  let error = null;
999
1032
  debugDevice(`Initializing ADB with device ID: ${this.deviceId}`);
1000
1033
  try {
1001
- const androidAdbPath = this.options?.androidAdbPath || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_PATH);
1002
- const remoteAdbHost = this.options?.remoteAdbHost || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_HOST);
1003
- const remoteAdbPort = this.options?.remoteAdbPort || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_PORT);
1004
- this.adb = new external_appium_adb_namespaceObject.ADB({
1005
- udid: this.deviceId,
1034
+ this.adb = await adb_createAndroidAdb({
1006
1035
  adbExecTimeout: 60000,
1007
- executable: androidAdbPath ? {
1008
- path: androidAdbPath,
1009
- defaultArgs: []
1010
- } : void 0,
1011
- remoteAdbHost: remoteAdbHost || void 0,
1012
- remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
1036
+ deviceId: this.deviceId,
1037
+ deviceOptions: this.options
1013
1038
  });
1014
1039
  const size = await this.getScreenSize();
1015
1040
  this.description = `
@@ -1044,8 +1069,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1044
1069
  } catch (error) {
1045
1070
  const methodName = String(prop);
1046
1071
  const deviceId = this.deviceId;
1047
- debugDevice(`ADB error with device ${deviceId} when calling ${methodName}: ${error}`);
1048
- throw new Error(`ADB error with device ${deviceId} when calling ${methodName}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
1072
+ const adbExecutable = target.executable.path;
1073
+ debugDevice(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}): ${error}`);
1074
+ throw new Error(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}), please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
1049
1075
  cause: error
1050
1076
  });
1051
1077
  }
@@ -1064,7 +1090,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1064
1090
  return adapter.getStatus();
1065
1091
  }
1066
1092
  getScrcpyAdapter() {
1067
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig);
1093
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1094
+ const adb = await this.getAdb();
1095
+ return {
1096
+ host: adb.adbHost ?? '127.0.0.1',
1097
+ port: adb.adbPort ?? 5037
1098
+ };
1099
+ });
1068
1100
  return this.scrcpyAdapter;
1069
1101
  }
1070
1102
  async openScrcpyFrameSource() {
@@ -2096,17 +2128,21 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
2096
2128
  })
2097
2129
  });
2098
2130
  const debugUtils = (0, logger_.getDebug)('android:utils');
2099
- async function getConnectedDevices() {
2131
+ async function getConnectedDevices(deviceOptions) {
2132
+ let adbExecutable;
2100
2133
  try {
2101
- const adb = await external_appium_adb_namespaceObject.ADB.createADB({
2102
- adbExecTimeout: 60000
2134
+ const adb = await adb_createAndroidAdb({
2135
+ adbExecTimeout: 60000,
2136
+ deviceOptions
2103
2137
  });
2138
+ adbExecutable = adb.executable.path;
2104
2139
  const devices = await adb.getConnectedDevices();
2105
2140
  debugUtils(`Found ${devices.length} connected devices: `, devices);
2106
2141
  return devices;
2107
2142
  } catch (error) {
2108
2143
  console.error('Failed to get device list:', error);
2109
- throw new Error(`Unable to get connected Android device list, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2144
+ const adbExecutableContext = adbExecutable ? ` (ADB executable: ${adbExecutable})` : '';
2145
+ throw new Error(`Unable to get connected Android device list${adbExecutableContext}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2110
2146
  cause: error
2111
2147
  });
2112
2148
  }
@@ -2162,7 +2198,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
2162
2198
  }
2163
2199
  async function agentFromAdbDevice(deviceId, opts) {
2164
2200
  if (!deviceId) {
2165
- const devices = await getConnectedDevices();
2201
+ const devices = await getConnectedDevices(opts);
2166
2202
  if (0 === devices.length) throw new Error('No Android devices found. Please connect an Android device and ensure ADB is properly configured. Run `adb devices` to verify device connection.');
2167
2203
  deviceId = devices[0].udid;
2168
2204
  debugAgent('deviceId not specified, will use the first device (id = %s)', deviceId);
@@ -2291,7 +2327,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
2291
2327
  const tools = new AndroidMidsceneTools();
2292
2328
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-android', {
2293
2329
  stripPrefix: 'android_',
2294
- version: "1.10.6-beta-20260717061640.0",
2330
+ version: "1.10.6",
2295
2331
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
2296
2332
  }).catch((e)=>{
2297
2333
  process.exit((0, cli_namespaceObject.reportCLIError)(e));
package/dist/lib/index.js CHANGED
@@ -575,6 +575,35 @@ var __webpack_exports__ = {};
575
575
  var logger_ = __webpack_require__("@midscene/shared/logger");
576
576
  const shared_utils_namespaceObject = require("@midscene/shared/utils");
577
577
  const external_appium_adb_namespaceObject = require("appium-adb");
578
+ const warnAdb = (0, logger_.getDebug)('android:adb', {
579
+ console: true
580
+ });
581
+ async function createAndroidAdb({ adbExecTimeout, deviceId, deviceOptions }) {
582
+ const androidAdbPath = deviceOptions?.androidAdbPath || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_PATH);
583
+ const remoteAdbHost = deviceOptions?.remoteAdbHost || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_HOST);
584
+ const remoteAdbPort = deviceOptions?.remoteAdbPort || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_PORT);
585
+ const adbOptions = {
586
+ udid: deviceId,
587
+ adbExecTimeout,
588
+ remoteAdbHost: remoteAdbHost || void 0,
589
+ remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
590
+ };
591
+ if (androidAdbPath) return new external_appium_adb_namespaceObject.ADB({
592
+ ...adbOptions,
593
+ executable: {
594
+ path: androidAdbPath,
595
+ defaultArgs: []
596
+ }
597
+ });
598
+ const sdkRoot = (0, external_appium_adb_namespaceObject.getSdkRootFromEnv)();
599
+ if (sdkRoot) try {
600
+ return await external_appium_adb_namespaceObject.ADB.createADB(adbOptions);
601
+ } catch (error) {
602
+ const message = error instanceof Error ? error.message : String(error);
603
+ warnAdb(`Unable to initialize adb from Android SDK at "${sdkRoot}", falling back to adb from PATH: ${message}`);
604
+ }
605
+ return new external_appium_adb_namespaceObject.ADB(adbOptions);
606
+ }
578
607
  const EMPTY_ADB_SHELL_STDOUT = '<empty>';
579
608
  const MAX_RUN_ADB_SHELL_STDOUT = 200;
580
609
  function normalizeShellStream(value) {
@@ -627,6 +656,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
627
656
  }
628
657
  const debugAdapter = (0, logger_.getDebug)('android:scrcpy-adapter');
629
658
  const SCRCPY_RETRY_COOLDOWN_MS = 5000;
659
+ const DEFAULT_ADB_SERVER_ENDPOINT = {
660
+ host: '127.0.0.1',
661
+ port: 5037
662
+ };
630
663
  class ScrcpyDeviceAdapter {
631
664
  isEnabled() {
632
665
  if (!this.isConfigured()) return false;
@@ -685,10 +718,8 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
685
718
  const { Adb, AdbServerClient } = await import("@yume-chan/adb");
686
719
  const { AdbServerNodeTcpConnector } = await import("@yume-chan/adb-server-node-tcp");
687
720
  const { ScrcpyScreenshotManager: ScrcpyManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./src/scrcpy-manager.ts"));
688
- const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector({
689
- host: '127.0.0.1',
690
- port: 5037
691
- }));
721
+ const adbServerEndpoint = await this.resolveAdbServerEndpoint();
722
+ const adbClient = new AdbServerClient(new AdbServerNodeTcpConnector(adbServerEndpoint));
692
723
  const adb = new Adb(await adbClient.createTransport({
693
724
  serial: this.deviceId
694
725
  }));
@@ -768,15 +799,17 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
768
799
  this.resolvedConfig = null;
769
800
  this.clearFailure();
770
801
  }
771
- constructor(deviceId, scrcpyConfig){
802
+ constructor(deviceId, scrcpyConfig, resolveAdbServerEndpoint = ()=>DEFAULT_ADB_SERVER_ENDPOINT){
772
803
  _define_property(this, "deviceId", void 0);
773
804
  _define_property(this, "scrcpyConfig", void 0);
805
+ _define_property(this, "resolveAdbServerEndpoint", void 0);
774
806
  _define_property(this, "manager", void 0);
775
807
  _define_property(this, "resolvedConfig", void 0);
776
808
  _define_property(this, "lastError", void 0);
777
809
  _define_property(this, "retryAfter", void 0);
778
810
  this.deviceId = deviceId;
779
811
  this.scrcpyConfig = scrcpyConfig;
812
+ this.resolveAdbServerEndpoint = resolveAdbServerEndpoint;
780
813
  this.manager = null;
781
814
  this.resolvedConfig = null;
782
815
  this.lastError = null;
@@ -919,18 +952,10 @@ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
919
952
  let error = null;
920
953
  debugDevice(`Initializing ADB with device ID: ${this.deviceId}`);
921
954
  try {
922
- const androidAdbPath = this.options?.androidAdbPath || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_PATH);
923
- const remoteAdbHost = this.options?.remoteAdbHost || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_HOST);
924
- const remoteAdbPort = this.options?.remoteAdbPort || env_namespaceObject.globalConfigManager.getEnvConfigValue(env_namespaceObject.MIDSCENE_ADB_REMOTE_PORT);
925
- this.adb = new external_appium_adb_namespaceObject.ADB({
926
- udid: this.deviceId,
955
+ this.adb = await createAndroidAdb({
927
956
  adbExecTimeout: 60000,
928
- executable: androidAdbPath ? {
929
- path: androidAdbPath,
930
- defaultArgs: []
931
- } : void 0,
932
- remoteAdbHost: remoteAdbHost || void 0,
933
- remoteAdbPort: remoteAdbPort ? Number(remoteAdbPort) : void 0
957
+ deviceId: this.deviceId,
958
+ deviceOptions: this.options
934
959
  });
935
960
  const size = await this.getScreenSize();
936
961
  this.description = `
@@ -965,8 +990,9 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
965
990
  } catch (error) {
966
991
  const methodName = String(prop);
967
992
  const deviceId = this.deviceId;
968
- debugDevice(`ADB error with device ${deviceId} when calling ${methodName}: ${error}`);
969
- throw new Error(`ADB error with device ${deviceId} when calling ${methodName}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
993
+ const adbExecutable = target.executable.path;
994
+ debugDevice(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}): ${error}`);
995
+ throw new Error(`ADB error with device ${deviceId} when calling ${methodName} (ADB executable: ${adbExecutable}), please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
970
996
  cause: error
971
997
  });
972
998
  }
@@ -985,7 +1011,13 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
985
1011
  return adapter.getStatus();
986
1012
  }
987
1013
  getScrcpyAdapter() {
988
- if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig);
1014
+ if (!this.scrcpyAdapter) this.scrcpyAdapter = new ScrcpyDeviceAdapter(this.deviceId, this.options?.scrcpyConfig, async ()=>{
1015
+ const adb = await this.getAdb();
1016
+ return {
1017
+ host: adb.adbHost ?? '127.0.0.1',
1018
+ port: adb.adbPort ?? 5037
1019
+ };
1020
+ });
989
1021
  return this.scrcpyAdapter;
990
1022
  }
991
1023
  async openScrcpyFrameSource() {
@@ -2141,35 +2173,40 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
2141
2173
  if (timer) clearTimeout(timer);
2142
2174
  }
2143
2175
  }
2144
- async function createAdbForDetailLookup() {
2145
- return await external_appium_adb_namespaceObject.ADB.createADB({
2146
- adbExecTimeout: DETAIL_LOOKUP_ADB_TIMEOUT_MS
2176
+ async function createAdbForDetailLookup(deviceOptions) {
2177
+ return await createAndroidAdb({
2178
+ adbExecTimeout: DETAIL_LOOKUP_ADB_TIMEOUT_MS,
2179
+ deviceOptions
2147
2180
  });
2148
2181
  }
2149
- async function getConnectedDevices() {
2182
+ async function getConnectedDevices(deviceOptions) {
2183
+ let adbExecutable;
2150
2184
  try {
2151
- const adb = await external_appium_adb_namespaceObject.ADB.createADB({
2152
- adbExecTimeout: 60000
2185
+ const adb = await createAndroidAdb({
2186
+ adbExecTimeout: 60000,
2187
+ deviceOptions
2153
2188
  });
2189
+ adbExecutable = adb.executable.path;
2154
2190
  const devices = await adb.getConnectedDevices();
2155
2191
  debugUtils(`Found ${devices.length} connected devices: `, devices);
2156
2192
  return devices;
2157
2193
  } catch (error) {
2158
2194
  console.error('Failed to get device list:', error);
2159
- throw new Error(`Unable to get connected Android device list, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2195
+ const adbExecutableContext = adbExecutable ? ` (ADB executable: ${adbExecutable})` : '';
2196
+ throw new Error(`Unable to get connected Android device list${adbExecutableContext}, please check https://midscenejs.com/integrate-with-android.html#faq : ${error.message}`, {
2160
2197
  cause: error
2161
2198
  });
2162
2199
  }
2163
2200
  }
2164
- async function getConnectedDevicesWithDetails() {
2165
- const devices = await getConnectedDevices();
2201
+ async function getConnectedDevicesWithDetails(deviceOptions) {
2202
+ const devices = await getConnectedDevices(deviceOptions);
2166
2203
  if (0 === devices.length) return [];
2167
2204
  return await Promise.all(devices.map(async (device)=>{
2168
2205
  const detailedDevice = {
2169
2206
  ...device
2170
2207
  };
2171
2208
  try {
2172
- const adb = await createAdbForDetailLookup();
2209
+ const adb = await createAdbForDetailLookup(deviceOptions);
2173
2210
  adb.setDeviceId(device.udid);
2174
2211
  const [modelResult, brandResult, sizeResult, densityResult] = await Promise.allSettled([
2175
2212
  withTimeout(adb.shell([
@@ -2247,7 +2284,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
2247
2284
  }
2248
2285
  async function agentFromAdbDevice(deviceId, opts) {
2249
2286
  if (!deviceId) {
2250
- const devices = await getConnectedDevices();
2287
+ const devices = await getConnectedDevices(opts);
2251
2288
  if (0 === devices.length) throw new Error('No Android devices found. Please connect an Android device and ensure ADB is properly configured. Run `adb devices` to verify device connection.');
2252
2289
  deviceId = devices[0].udid;
2253
2290
  debugAgent('deviceId not specified, will use the first device (id = %s)', deviceId);
@@ -1,7 +1,7 @@
1
1
  import { AbstractInterface } from '@midscene/core/device';
2
2
  import type { ActionParam } from '@midscene/core';
3
3
  import type { ActionReturn } from '@midscene/core';
4
- import { ADB } from 'appium-adb';
4
+ import type { ADB } from 'appium-adb';
5
5
  import type { Adb } from '@yume-chan/adb';
6
6
  import { Agent } from '@midscene/core/agent';
7
7
  import { AgentBehaviorInitArgs } from '@midscene/shared/agent-tools/agent-behavior-init-args';
@@ -9,7 +9,7 @@ import { AgentOpt } from '@midscene/core/agent';
9
9
  import { AndroidDeviceInputOpt } from '@midscene/core/device';
10
10
  import { AndroidDeviceOpt } from '@midscene/core/device';
11
11
  import { BaseMidsceneTools } from '@midscene/shared/agent-tools/base-tools';
12
- import { Device } from 'appium-adb';
12
+ import type { Device } from 'appium-adb';
13
13
  import { DeviceAction } from '@midscene/core';
14
14
  import type { ElementInfo } from '@midscene/shared/extractor';
15
15
  import { InitArgSpec } from '@midscene/shared/agent-tools/base-tools';
@@ -22,6 +22,11 @@ import type { ToolDefinition } from '@midscene/shared/agent-tools/types';
22
22
 
23
23
  declare type ActionArgs<T extends DeviceAction> = [ActionParam<T>] extends [undefined] ? [] : [ActionParam<T>];
24
24
 
25
+ declare interface AdbServerEndpoint {
26
+ host: string;
27
+ port: number;
28
+ }
29
+
25
30
  export declare function agentFromAdbDevice(deviceId?: string, opts?: AndroidAgentOpt & AndroidDeviceOpt): Promise<AndroidAgent>;
26
31
 
27
32
  export declare class AndroidAgent extends Agent<AndroidDevice> {
@@ -321,9 +326,9 @@ declare interface DevicePhysicalInfo {
321
326
  isCurrentOrientation?: boolean;
322
327
  }
323
328
 
324
- export declare function getConnectedDevices(): Promise<Device[]>;
329
+ export declare function getConnectedDevices(deviceOptions?: AndroidDeviceOpt): Promise<Device[]>;
325
330
 
326
- export declare function getConnectedDevicesWithDetails(): Promise<AndroidConnectedDevice[]>;
331
+ export declare function getConnectedDevicesWithDetails(deviceOptions?: AndroidDeviceOpt): Promise<AndroidConnectedDevice[]>;
327
332
 
328
333
  export { overrideAIConfig }
329
334
 
@@ -341,6 +346,8 @@ declare interface RawKeyframe {
341
346
  capturedAt: number;
342
347
  }
343
348
 
349
+ declare type ResolveAdbServerEndpoint = () => AdbServerEndpoint | Promise<AdbServerEndpoint>;
350
+
344
351
  declare interface ResolvedScrcpyConfig {
345
352
  enabled: boolean;
346
353
  maxSize: number;
@@ -369,11 +376,12 @@ declare interface ScrcpyConfig {
369
376
  export declare class ScrcpyDeviceAdapter {
370
377
  private deviceId;
371
378
  private scrcpyConfig;
379
+ private resolveAdbServerEndpoint;
372
380
  private manager;
373
381
  private resolvedConfig;
374
382
  private lastError;
375
383
  private retryAfter;
376
- constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined);
384
+ constructor(deviceId: string, scrcpyConfig: ScrcpyConfig | undefined, resolveAdbServerEndpoint?: ResolveAdbServerEndpoint);
377
385
  isEnabled(): boolean;
378
386
  getStatus(): ScrcpyStatus;
379
387
  private isConfigured;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/android",
3
- "version": "1.10.6-beta-20260717061640.0",
3
+ "version": "1.10.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -41,8 +41,8 @@
41
41
  "@yume-chan/stream-extra": "2.1.0",
42
42
  "appium-adb": "12.12.1",
43
43
  "sharp": "^0.34.3",
44
- "@midscene/shared": "1.10.6-beta-20260717061640.0",
45
- "@midscene/core": "1.10.6-beta-20260717061640.0"
44
+ "@midscene/shared": "1.10.6",
45
+ "@midscene/core": "1.10.6"
46
46
  },
47
47
  "optionalDependencies": {
48
48
  "@ffmpeg-installer/ffmpeg": "^1.1.0"
@@ -56,7 +56,7 @@
56
56
  "undici": "^6.0.0",
57
57
  "vitest": "3.0.5",
58
58
  "zod": "^3.25.1",
59
- "@midscene/playground": "1.10.6-beta-20260717061640.0"
59
+ "@midscene/playground": "1.10.6"
60
60
  },
61
61
  "license": "MIT",
62
62
  "scripts": {