@midscene/android 1.9.5-beta-20260611045217.0 → 1.9.5

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
@@ -2,30 +2,28 @@ import * as __rspack_external__midscene_shared_logger_b1dc2426 from "@midscene/s
2
2
  import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
3
3
  import * as __rspack_external_node_module_ab9f2194 from "node:module";
4
4
  import * as __rspack_external_node_path_c5b9b54f from "node:path";
5
- import * as __rspack_external_node_assert_3e74d44e from "node:assert";
6
- import * as __rspack_external_node_child_process_27f17141 from "node:child_process";
7
- import * as __rspack_external__midscene_core_c3cd7634 from "@midscene/core";
8
- import * as __rspack_external__midscene_core_device_1cfad35b from "@midscene/core/device";
9
- import * as __rspack_external__midscene_core_utils_9c4af4f4 from "@midscene/core/utils";
10
- import * as __rspack_external__midscene_shared_env_0c37bb76 from "@midscene/shared/env";
11
- import * as __rspack_external__midscene_shared_img_758d2833 from "@midscene/shared/img";
12
- import * as __rspack_external__midscene_shared_utils_b0457388 from "@midscene/shared/utils";
13
- import * as __rspack_external_appium_adb_724653d6 from "appium-adb";
14
- import * as __rspack_external__midscene_shared_constants_ab069bca from "@midscene/shared/constants";
15
- import * as __rspack_external__midscene_shared_timeout_982edd16 from "@midscene/shared/timeout";
16
- import * as __rspack_external__midscene_core_agent_2b7f9158 from "@midscene/core/agent";
17
- import * as __rspack_external__midscene_shared_mcp_base_tools_a0c805f3 from "@midscene/shared/mcp/base-tools";
18
- import * as __rspack_external__midscene_shared_cli_24fbb5ae from "@midscene/shared/cli";
5
+ import { createReportCliCommands, getMidsceneLocationSchema, z } from "@midscene/core";
6
+ import { reportCLIError, runToolsCLI } from "@midscene/shared/cli";
7
+ import { BaseMidsceneTools } from "@midscene/shared/mcp/base-tools";
8
+ import { Agent } from "@midscene/core/agent";
9
+ import { mergeAndNormalizeAppNameMapping, normalizeForComparison, repeat } from "@midscene/shared/utils";
10
+ import node_assert from "node:assert";
11
+ import { execFile } from "node:child_process";
12
+ import { createDefaultMobileActions, defineAction } from "@midscene/core/device";
13
+ import { getTmpFile, sleep } from "@midscene/core/utils";
14
+ import { MIDSCENE_ADB_PATH, MIDSCENE_ADB_REMOTE_HOST, MIDSCENE_ADB_REMOTE_PORT, MIDSCENE_ANDROID_IME_STRATEGY, globalConfigManager } from "@midscene/shared/env";
15
+ import { createImgBase64ByFormat, validateScreenshotBuffer } from "@midscene/shared/img";
16
+ import { ADB as external_appium_adb_ADB } from "appium-adb";
19
17
  var __webpack_modules__ = {
20
18
  "./src/scrcpy-manager.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
21
19
  __webpack_require__.d(__webpack_exports__, {
22
20
  ScrcpyScreenshotManager: ()=>ScrcpyScreenshotManager,
23
21
  o: ()=>DEFAULT_SCRCPY_CONFIG
24
22
  });
25
- var external_node_fs_ = __webpack_require__("node:fs");
26
- var external_node_module_ = __webpack_require__("node:module");
27
- var external_node_path_ = __webpack_require__("node:path");
28
- var logger_ = __webpack_require__("@midscene/shared/logger");
23
+ var node_fs__rspack_import_0 = __webpack_require__("node:fs");
24
+ var node_module__rspack_import_1 = __webpack_require__("node:module");
25
+ var node_path__rspack_import_2 = __webpack_require__("node:path");
26
+ var _midscene_shared_logger__rspack_import_3 = __webpack_require__("@midscene/shared/logger");
29
27
  function _define_property(obj, key, value) {
30
28
  if (key in obj) Object.defineProperty(obj, key, {
31
29
  value: value,
@@ -36,8 +34,8 @@ var __webpack_modules__ = {
36
34
  else obj[key] = value;
37
35
  return obj;
38
36
  }
39
- const debugScrcpy = (0, logger_.getDebug)('android:scrcpy');
40
- const warnScrcpy = (0, logger_.getDebug)('android:scrcpy', {
37
+ const debugScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy');
38
+ const warnScrcpy = (0, _midscene_shared_logger__rspack_import_3.getDebug)('android:scrcpy', {
41
39
  console: true
42
40
  });
43
41
  const NAL_TYPE_IDR = 5;
@@ -78,11 +76,6 @@ var __webpack_modules__ = {
78
76
  return false;
79
77
  }
80
78
  class ScrcpyScreenshotManager {
81
- shouldRetryWithForwardTunnel(error) {
82
- const cause = error instanceof Error ? error.cause : void 0;
83
- const message = error instanceof Error ? `${error.message}${cause instanceof Error ? ` ${cause.message}` : ''}` : String(error);
84
- return /more than one device\/emulator/i.test(message);
85
- }
86
79
  async validateEnvironment() {
87
80
  await this.ensureFfmpegAvailable();
88
81
  }
@@ -101,7 +94,12 @@ var __webpack_modules__ = {
101
94
  try {
102
95
  this.isConnecting = true;
103
96
  debugScrcpy('Starting scrcpy connection...');
104
- this.scrcpyClient = await this.startScrcpy(this.adb, {
97
+ const { AdbScrcpyClient, AdbScrcpyOptions3_3_3 } = await import("@yume-chan/adb-scrcpy");
98
+ const { ReadableStream } = await import("@yume-chan/stream-extra");
99
+ const { DefaultServerPath } = await import("@yume-chan/scrcpy");
100
+ const serverBinPath = this.resolveServerBinPath();
101
+ await AdbScrcpyClient.pushServer(this.adb, ReadableStream.from((0, node_fs__rspack_import_0.createReadStream)(serverBinPath)));
102
+ const scrcpyOptions = new AdbScrcpyOptions3_3_3({
105
103
  audio: false,
106
104
  control: false,
107
105
  maxSize: this.options.maxSize,
@@ -110,6 +108,7 @@ var __webpack_modules__ = {
110
108
  sendFrameMeta: true,
111
109
  videoCodecOptions: 'i-frame-interval=0,bitrate-mode=2'
112
110
  });
111
+ this.scrcpyClient = await AdbScrcpyClient.start(this.adb, DefaultServerPath, scrcpyOptions);
113
112
  const videoStreamPromise = this.scrcpyClient.videoStream;
114
113
  if (!videoStreamPromise) throw new Error('Scrcpy client did not provide video stream');
115
114
  this.videoStream = await videoStreamPromise;
@@ -131,50 +130,13 @@ var __webpack_modules__ = {
131
130
  this.isConnecting = false;
132
131
  }
133
132
  }
134
- async startScrcpyOnce(adb, options = {}, onProgress, tunnelForward = false) {
135
- const { AdbScrcpyClient, AdbScrcpyOptions3_3_3 } = await import("@yume-chan/adb-scrcpy");
136
- const { ReadableStream } = await import("@yume-chan/stream-extra");
137
- const { DefaultServerPath } = await import("@yume-chan/scrcpy");
138
- const serverBinPath = this.resolveServerBinPath();
139
- onProgress?.('pushing-server');
140
- await (0, __rspack_external__midscene_shared_timeout_982edd16.withTimeout)(AdbScrcpyClient.pushServer(adb, ReadableStream.from((0, external_node_fs_.createReadStream)(serverBinPath))), __rspack_external__midscene_shared_constants_ab069bca.SCRCPY_PUSH_TIMEOUT_MS, `Timed out pushing scrcpy server to device after ${Math.round(__rspack_external__midscene_shared_constants_ab069bca.SCRCPY_PUSH_TIMEOUT_MS / 1000)}s`);
141
- const scrcpyOptions = new AdbScrcpyOptions3_3_3({
142
- audio: false,
143
- control: true,
144
- maxSize: 1024,
145
- sendFrameMeta: true,
146
- videoBitRate: 2000000,
147
- ...options,
148
- tunnelForward
149
- });
150
- onProgress?.('starting-service');
151
- const startPromise = AdbScrcpyClient.start(adb, DefaultServerPath, scrcpyOptions);
152
- return await (0, __rspack_external__midscene_shared_timeout_982edd16.withTimeout)(startPromise, __rspack_external__midscene_shared_constants_ab069bca.SCRCPY_START_TIMEOUT_MS, `Timed out starting scrcpy service after ${Math.round(__rspack_external__midscene_shared_constants_ab069bca.SCRCPY_START_TIMEOUT_MS / 1000)}s`, {
153
- onSettledAfterTimeout: async (lateClient)=>{
154
- try {
155
- await lateClient.close();
156
- } catch (closeError) {
157
- console.error('failed to close late scrcpy client after timeout:', closeError);
158
- }
159
- }
160
- });
161
- }
162
- async startScrcpy(adb, options = {}, onProgress) {
163
- try {
164
- return await this.startScrcpyOnce(adb, options, onProgress, false);
165
- } catch (error) {
166
- if (!this.shouldRetryWithForwardTunnel(error)) throw error;
167
- warnScrcpy(`Reverse tunnel failed for device ${adb.serial}; retrying scrcpy with forward tunnel: ${error}`);
168
- return await this.startScrcpyOnce(adb, options, onProgress, true);
169
- }
170
- }
171
133
  resolveServerBinPath() {
172
- const androidPkgJson = (0, external_node_module_.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
173
- return external_node_path_["default"].join(external_node_path_["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server');
134
+ const androidPkgJson = (0, node_module__rspack_import_1.createRequire)(import.meta.url).resolve('@midscene/android/package.json');
135
+ return node_path__rspack_import_2["default"].join(node_path__rspack_import_2["default"].dirname(androidPkgJson), 'bin', 'scrcpy-server');
174
136
  }
175
137
  getFfmpegPath() {
176
138
  try {
177
- const dynamicRequire = (0, external_node_module_.createRequire)(import.meta.url);
139
+ const dynamicRequire = (0, node_module__rspack_import_1.createRequire)(import.meta.url);
178
140
  const ffmpegInstaller = dynamicRequire('@ffmpeg-installer/ffmpeg');
179
141
  debugScrcpy(`Using ffmpeg from npm package: ${ffmpegInstaller.path}`);
180
142
  return ffmpegInstaller.path;
@@ -485,6 +447,45 @@ function __webpack_require__(moduleId) {
485
447
  __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
486
448
  })();
487
449
  var logger_ = __webpack_require__("@midscene/shared/logger");
450
+ const EMPTY_ADB_SHELL_STDOUT = '<empty>';
451
+ const MAX_RUN_ADB_SHELL_STDOUT = 200;
452
+ function normalizeShellStream(value) {
453
+ if (null == value) return '';
454
+ return String(value);
455
+ }
456
+ function truncateAdbShellStream(output, streamName) {
457
+ if (output.length <= MAX_RUN_ADB_SHELL_STDOUT) return output;
458
+ return `${output.slice(0, MAX_RUN_ADB_SHELL_STDOUT)}
459
+ ...[${streamName} truncated, ${output.length - MAX_RUN_ADB_SHELL_STDOUT} more characters]`;
460
+ }
461
+ function buildRunAdbShellPlanningFeedback({ command, stdout }) {
462
+ if ('' === stdout) return;
463
+ const commandText = 'string' == typeof command && command.length > 0 ? `Command: ${command}\n` : '';
464
+ return `${commandText}Stdout:
465
+ ${stdout}`;
466
+ }
467
+ function buildAdbShellStderrErrorMessage(command, stdout, stderr) {
468
+ return `RunAdbShell command returned stderr.
469
+ Command: ${command}
470
+ Stderr:
471
+ ${truncateAdbShellStream(stderr, 'stderr')}
472
+ Stdout:
473
+ ${stdout ? truncateAdbShellStream(stdout, 'stdout') : EMPTY_ADB_SHELL_STDOUT}`;
474
+ }
475
+ function getAdbShellStdoutOrThrow(command, output) {
476
+ if ('string' == typeof output) return output;
477
+ const stdout = normalizeShellStream(output.stdout);
478
+ const stderr = normalizeShellStream(output.stderr);
479
+ if (stderr) throw new Error(buildAdbShellStderrErrorMessage(command, stdout, stderr));
480
+ return stdout;
481
+ }
482
+ async function runAdbShellStdoutOrThrow(adb, command, options = {}) {
483
+ const output = await adb.shell(command, {
484
+ ...options,
485
+ outputFormat: adb.EXEC_OUTPUT_FORMAT.FULL
486
+ });
487
+ return getAdbShellStdoutOrThrow(command, output);
488
+ }
488
489
  const defaultAppNameMapping = {
489
490
  微信: 'com.tencent.mm',
490
491
  QQ: 'com.tencent.mobileqq',
@@ -655,7 +656,7 @@ class ScrcpyDeviceAdapter {
655
656
  async screenshotBase64(deviceInfo) {
656
657
  const manager = await this.ensureManager(deviceInfo);
657
658
  const screenshotBuffer = await manager.getScreenshotJpeg();
658
- return (0, __rspack_external__midscene_shared_img_758d2833.createImgBase64ByFormat)('jpeg', screenshotBuffer.toString('base64'));
659
+ return createImgBase64ByFormat('jpeg', screenshotBuffer.toString('base64'));
659
660
  }
660
661
  getResolution() {
661
662
  return this.manager?.getResolution() ?? null;
@@ -726,7 +727,7 @@ class AndroidDevice {
726
727
  input: this.inputPrimitives,
727
728
  size: ()=>this.size(),
728
729
  sleep: async (timeMs)=>{
729
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(timeMs);
730
+ await sleep(timeMs);
730
731
  },
731
732
  getDefaultAutoDismissKeyboard: ()=>this.options?.autoDismissKeyboard,
732
733
  systemActions: {
@@ -745,18 +746,18 @@ class AndroidDevice {
745
746
  }
746
747
  };
747
748
  const defaultActions = [
748
- ...(0, __rspack_external__midscene_core_device_1cfad35b.createDefaultMobileActions)(mobileActionContext),
749
- (0, __rspack_external__midscene_core_device_1cfad35b.defineAction)({
749
+ ...createDefaultMobileActions(mobileActionContext),
750
+ defineAction({
750
751
  name: 'PullGesture',
751
752
  description: 'Trigger pull down to refresh or pull up actions',
752
- paramSchema: __rspack_external__midscene_core_c3cd7634.z.object({
753
- direction: __rspack_external__midscene_core_c3cd7634.z["enum"]([
753
+ paramSchema: z.object({
754
+ direction: z["enum"]([
754
755
  'up',
755
756
  'down'
756
757
  ]).describe('The direction to pull'),
757
- distance: __rspack_external__midscene_core_c3cd7634.z.number().optional().describe('The distance to pull (in pixels)'),
758
- duration: __rspack_external__midscene_core_c3cd7634.z.number().optional().describe('The duration of the pull (in milliseconds)'),
759
- locate: (0, __rspack_external__midscene_core_c3cd7634.getMidsceneLocationSchema)().optional().describe('The element to start the pull from (optional)')
758
+ distance: z.number().optional().describe('The distance to pull (in pixels)'),
759
+ duration: z.number().optional().describe('The duration of the pull (in milliseconds)'),
760
+ locate: getMidsceneLocationSchema().optional().describe('The element to start the pull from (optional)')
760
761
  }),
761
762
  sample: {
762
763
  direction: 'down',
@@ -803,7 +804,7 @@ class AndroidDevice {
803
804
  else if ('right' === param.direction) await this.scrollRight(param.distance || void 0, startingPoint);
804
805
  else throw new Error(`Unknown scroll direction: ${param.direction}`);
805
806
  else await this.scrollDown(param?.distance || void 0, startingPoint);
806
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(500);
807
+ await sleep(500);
807
808
  }
808
809
  }
809
810
  describe() {
@@ -830,10 +831,10 @@ class AndroidDevice {
830
831
  let error = null;
831
832
  debugDevice(`Initializing ADB with device ID: ${this.deviceId}`);
832
833
  try {
833
- const androidAdbPath = this.options?.androidAdbPath || __rspack_external__midscene_shared_env_0c37bb76.globalConfigManager.getEnvConfigValue(__rspack_external__midscene_shared_env_0c37bb76.MIDSCENE_ADB_PATH);
834
- const remoteAdbHost = this.options?.remoteAdbHost || __rspack_external__midscene_shared_env_0c37bb76.globalConfigManager.getEnvConfigValue(__rspack_external__midscene_shared_env_0c37bb76.MIDSCENE_ADB_REMOTE_HOST);
835
- const remoteAdbPort = this.options?.remoteAdbPort || __rspack_external__midscene_shared_env_0c37bb76.globalConfigManager.getEnvConfigValue(__rspack_external__midscene_shared_env_0c37bb76.MIDSCENE_ADB_REMOTE_PORT);
836
- this.adb = new __rspack_external_appium_adb_724653d6.ADB({
834
+ const androidAdbPath = this.options?.androidAdbPath || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_PATH);
835
+ const remoteAdbHost = this.options?.remoteAdbHost || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_HOST);
836
+ const remoteAdbPort = this.options?.remoteAdbPort || globalConfigManager.getEnvConfigValue(MIDSCENE_ADB_REMOTE_PORT);
837
+ this.adb = new external_appium_adb_ADB({
837
838
  udid: this.deviceId,
838
839
  adbExecTimeout: 60000,
839
840
  executable: androidAdbPath ? {
@@ -907,7 +908,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
907
908
  this.appNameMapping = mapping;
908
909
  }
909
910
  resolvePackageName(appName) {
910
- const normalizedAppName = (0, __rspack_external__midscene_shared_utils_b0457388.normalizeForComparison)(appName);
911
+ const normalizedAppName = normalizeForComparison(appName);
911
912
  return this.appNameMapping[normalizedAppName];
912
913
  }
913
914
  async launch(uri) {
@@ -1226,7 +1227,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1226
1227
  screenshotBuffer = await adb.takeScreenshot.call(adb);
1227
1228
  debugDevice('adb.takeScreenshot completed');
1228
1229
  try {
1229
- (0, __rspack_external__midscene_shared_img_758d2833.validateScreenshotBuffer)(screenshotBuffer, {
1230
+ validateScreenshotBuffer(screenshotBuffer, {
1230
1231
  label: 'Screenshot',
1231
1232
  minBufferSize: this.options?.minScreenshotBufferSize ?? AndroidDevice.DEFAULT_MIN_SCREENSHOT_BUFFER_SIZE
1232
1233
  });
@@ -1242,7 +1243,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1242
1243
  }
1243
1244
  } catch (error) {
1244
1245
  debugDevice(`Taking screenshot via adb.takeScreenshot failed or was skipped: ${error}`);
1245
- const screenshotPath = (0, __rspack_external__midscene_core_utils_9c4af4f4.getTmpFile)('png');
1246
+ const screenshotPath = getTmpFile('png');
1246
1247
  localScreenshotPath = screenshotPath;
1247
1248
  try {
1248
1249
  debugDevice('Fallback: taking screenshot via shell screencap');
@@ -1260,14 +1261,14 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1260
1261
  await adb.pull(androidScreenshotPath, screenshotPath);
1261
1262
  debugDevice(`adb.pull completed, local path: ${screenshotPath}`);
1262
1263
  screenshotBuffer = await external_node_fs_["default"].promises.readFile(screenshotPath);
1263
- (0, __rspack_external__midscene_shared_img_758d2833.validateScreenshotBuffer)(screenshotBuffer, {
1264
+ validateScreenshotBuffer(screenshotBuffer, {
1264
1265
  label: 'Fallback screenshot',
1265
1266
  minBufferSize: this.options?.minScreenshotBufferSize ?? AndroidDevice.DEFAULT_MIN_SCREENSHOT_BUFFER_SIZE
1266
1267
  });
1267
1268
  debugDevice(`Fallback screenshot validated successfully: ${screenshotBuffer.length} bytes`);
1268
1269
  } finally{
1269
1270
  const adbPath = adb.executable?.path ?? 'adb';
1270
- const child = (0, __rspack_external_node_child_process_27f17141.execFile)(adbPath, [
1271
+ const child = execFile(adbPath, [
1271
1272
  '-s',
1272
1273
  this.deviceId,
1273
1274
  'shell',
@@ -1282,7 +1283,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1282
1283
  }
1283
1284
  if (!screenshotBuffer) throw new Error('Failed to capture screenshot: all methods failed');
1284
1285
  debugDevice('Converting to base64');
1285
- const result = (0, __rspack_external__midscene_shared_img_758d2833.createImgBase64ByFormat)('png', screenshotBuffer.toString('base64'));
1286
+ const result = createImgBase64ByFormat('png', screenshotBuffer.toString('base64'));
1286
1287
  if (localScreenshotPath) {
1287
1288
  debugDevice(`Deleting local screenshot: ${localScreenshotPath}`);
1288
1289
  (0, external_node_fs_.unlink)(localScreenshotPath, (unlinkError)=>{
@@ -1299,7 +1300,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1299
1300
  });
1300
1301
  await this.ensureYadb();
1301
1302
  const adb = await this.getAdb();
1302
- const IME_STRATEGY = (this.options?.imeStrategy || __rspack_external__midscene_shared_env_0c37bb76.globalConfigManager.getEnvConfigValue(__rspack_external__midscene_shared_env_0c37bb76.MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
1303
+ const IME_STRATEGY = (this.options?.imeStrategy || globalConfigManager.getEnvConfigValue(MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
1303
1304
  if (IME_STRATEGY === IME_STRATEGY_YADB_FOR_NON_ASCII) await adb.clearTextField(100);
1304
1305
  else await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboardClear`);
1305
1306
  if (await adb.isSoftKeyboardPresent()) return;
@@ -1327,12 +1328,12 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1327
1328
  x: start.x,
1328
1329
  y: Math.round(height)
1329
1330
  };
1330
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1331
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1331
+ await repeat(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1332
+ await sleep(1000);
1332
1333
  return;
1333
1334
  }
1334
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.scroll(0, -9999999, defaultFastScrollDuration));
1335
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1335
+ await repeat(defaultScrollUntilTimes, ()=>this.scroll(0, -9999999, defaultFastScrollDuration));
1336
+ await sleep(1000);
1336
1337
  }
1337
1338
  async scrollUntilBottom(startPoint) {
1338
1339
  if (startPoint) {
@@ -1344,12 +1345,12 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1344
1345
  x: start.x,
1345
1346
  y: 0
1346
1347
  };
1347
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1348
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1348
+ await repeat(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1349
+ await sleep(1000);
1349
1350
  return;
1350
1351
  }
1351
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.scroll(0, 9999999, defaultFastScrollDuration));
1352
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1352
+ await repeat(defaultScrollUntilTimes, ()=>this.scroll(0, 9999999, defaultFastScrollDuration));
1353
+ await sleep(1000);
1353
1354
  }
1354
1355
  async scrollUntilLeft(startPoint) {
1355
1356
  if (startPoint) {
@@ -1362,12 +1363,12 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1362
1363
  x: Math.round(width),
1363
1364
  y: start.y
1364
1365
  };
1365
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1366
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1366
+ await repeat(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1367
+ await sleep(1000);
1367
1368
  return;
1368
1369
  }
1369
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.scroll(-9999999, 0, defaultFastScrollDuration));
1370
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1370
+ await repeat(defaultScrollUntilTimes, ()=>this.scroll(-9999999, 0, defaultFastScrollDuration));
1371
+ await sleep(1000);
1371
1372
  }
1372
1373
  async scrollUntilRight(startPoint) {
1373
1374
  if (startPoint) {
@@ -1379,12 +1380,12 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1379
1380
  x: 0,
1380
1381
  y: start.y
1381
1382
  };
1382
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1383
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1383
+ await repeat(defaultScrollUntilTimes, ()=>this.dragPoint(start, end, defaultFastScrollDuration));
1384
+ await sleep(1000);
1384
1385
  return;
1385
1386
  }
1386
- await (0, __rspack_external__midscene_shared_utils_b0457388.repeat)(defaultScrollUntilTimes, ()=>this.scroll(9999999, 0, defaultFastScrollDuration));
1387
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(1000);
1387
+ await repeat(defaultScrollUntilTimes, ()=>this.scroll(9999999, 0, defaultFastScrollDuration));
1388
+ await sleep(1000);
1388
1389
  }
1389
1390
  async scrollUp(distance, startPoint) {
1390
1391
  const { height } = await this.size();
@@ -1469,7 +1470,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1469
1470
  async typeText(text, options) {
1470
1471
  if (!text) return;
1471
1472
  const adb = await this.getAdb();
1472
- const IME_STRATEGY = (this.options?.imeStrategy || __rspack_external__midscene_shared_env_0c37bb76.globalConfigManager.getEnvConfigValue(__rspack_external__midscene_shared_env_0c37bb76.MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
1473
+ const IME_STRATEGY = (this.options?.imeStrategy || globalConfigManager.getEnvConfigValue(MIDSCENE_ANDROID_IME_STRATEGY)) ?? IME_STRATEGY_YADB_FOR_NON_ASCII;
1473
1474
  const shouldAutoDismissKeyboard = options?.autoDismissKeyboard ?? this.options?.autoDismissKeyboard ?? true;
1474
1475
  const useYadb = IME_STRATEGY === IME_STRATEGY_ALWAYS_YADB || IME_STRATEGY === IME_STRATEGY_YADB_FOR_NON_ASCII && this.shouldUseYadbForText(text);
1475
1476
  if (useYadb) await this.execYadb(escapeForShell(text));
@@ -1535,7 +1536,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1535
1536
  const { x: adjustedX, y: adjustedY } = await this.adjustCoordinates(point.x, point.y);
1536
1537
  const tapCommand = `input${this.getDisplayArg()} tap ${adjustedX} ${adjustedY}`;
1537
1538
  await adb.shell(tapCommand);
1538
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(50);
1539
+ await sleep(50);
1539
1540
  await adb.shell(tapCommand);
1540
1541
  }
1541
1542
  async mouseMove() {
@@ -1646,7 +1647,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1646
1647
  y: start.y + pullDistance
1647
1648
  };
1648
1649
  await this.pullDrag(start, end, duration);
1649
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(200);
1650
+ await sleep(200);
1650
1651
  }
1651
1652
  async pullDrag(from, to, duration) {
1652
1653
  await this.swipePoint(from, to, duration);
@@ -1666,7 +1667,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1666
1667
  y: start.y - pullDistance
1667
1668
  };
1668
1669
  await this.pullDrag(start, end, duration);
1669
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(100);
1670
+ await sleep(100);
1670
1671
  }
1671
1672
  getDisplayArg() {
1672
1673
  return 'number' == typeof this.options?.displayId ? ` -d ${this.options.displayId}` : '';
@@ -1717,7 +1718,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1717
1718
  const startTime = Date.now();
1718
1719
  const intervalMs = 100;
1719
1720
  while(Date.now() - startTime < timeoutMs){
1720
- await (0, __rspack_external__midscene_core_utils_9c4af4f4.sleep)(intervalMs);
1721
+ await sleep(intervalMs);
1721
1722
  const currentStatus = await adb.isSoftKeyboardPresent();
1722
1723
  const isStillShown = 'boolean' == typeof currentStatus ? currentStatus : currentStatus?.isKeyboardShown;
1723
1724
  if (!isStillShown) {
@@ -1800,7 +1801,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1800
1801
  recentAppsButton: ()=>this.recentApps()
1801
1802
  }
1802
1803
  });
1803
- (0, __rspack_external_node_assert_3e74d44e["default"])(deviceId, 'deviceId is required for AndroidDevice');
1804
+ node_assert(deviceId, 'deviceId is required for AndroidDevice');
1804
1805
  this.deviceId = deviceId;
1805
1806
  this.options = options;
1806
1807
  this.customActions = options?.customActions;
@@ -1808,31 +1809,37 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1808
1809
  }
1809
1810
  device_define_property(AndroidDevice, "TAKE_SCREENSHOT_FAIL_THRESHOLD", 3);
1810
1811
  device_define_property(AndroidDevice, "DEFAULT_MIN_SCREENSHOT_BUFFER_SIZE", 1024);
1811
- const runAdbShellParamSchema = __rspack_external__midscene_core_c3cd7634.z.object({
1812
- command: __rspack_external__midscene_core_c3cd7634.z.string().describe('ADB shell command to execute')
1812
+ const runAdbShellParamSchema = z.object({
1813
+ command: z.string().describe('ADB shell command to execute')
1813
1814
  });
1814
- const launchParamSchema = __rspack_external__midscene_core_c3cd7634.z.object({
1815
- uri: __rspack_external__midscene_core_c3cd7634.z.string().describe('App name, package name, or URL to launch. Prioritize using the exact package name or URL the user has provided. If none provided, use the accurate app name.')
1815
+ const launchParamSchema = z.object({
1816
+ uri: z.string().describe('App name, package name, or URL to launch. Prioritize using the exact package name or URL the user has provided. If none provided, use the accurate app name.')
1816
1817
  });
1817
- const terminateParamSchema = __rspack_external__midscene_core_c3cd7634.z.object({
1818
- uri: __rspack_external__midscene_core_c3cd7634.z.string().describe('Package name or app name to terminate. Use the exact package name, e.g. com.android.settings.')
1818
+ const terminateParamSchema = z.object({
1819
+ uri: z.string().describe('Package name or app name to terminate. Use the exact package name, e.g. com.android.settings.')
1819
1820
  });
1820
1821
  const createPlatformActions = (device)=>({
1821
- RunAdbShell: (0, __rspack_external__midscene_core_device_1cfad35b.defineAction)({
1822
+ RunAdbShell: defineAction({
1822
1823
  name: 'RunAdbShell',
1823
- description: 'Execute ADB shell command on Android device',
1824
+ description: 'Execute an ADB shell command on the Android device and return the command stdout. Read the returned stdout to decide the next step; the stdout may indicate either success or failure.',
1824
1825
  interfaceAlias: 'runAdbShell',
1825
1826
  paramSchema: runAdbShellParamSchema,
1826
1827
  sample: {
1827
1828
  command: 'dumpsys window displays | grep -E "mCurrentFocus"'
1828
1829
  },
1829
- call: async (param)=>{
1830
+ call: async (param, context)=>{
1830
1831
  if (!param.command || '' === param.command.trim()) throw new Error('RunAdbShell requires a non-empty command parameter');
1831
1832
  const adb = await device.getAdb();
1832
- return await adb.shell(param.command);
1833
+ const stdout = await runAdbShellStdoutOrThrow(adb, param.command);
1834
+ const planningFeedback = buildRunAdbShellPlanningFeedback({
1835
+ command: param.command,
1836
+ stdout
1837
+ });
1838
+ if (planningFeedback && context?.task) context.task.planningFeedback = planningFeedback;
1839
+ return stdout;
1833
1840
  }
1834
1841
  }),
1835
- Launch: (0, __rspack_external__midscene_core_device_1cfad35b.defineAction)({
1842
+ Launch: defineAction({
1836
1843
  name: 'Launch',
1837
1844
  description: 'Launch an Android app or URL',
1838
1845
  interfaceAlias: 'launch',
@@ -1845,7 +1852,7 @@ const createPlatformActions = (device)=>({
1845
1852
  await device.launch(param.uri);
1846
1853
  }
1847
1854
  }),
1848
- Terminate: (0, __rspack_external__midscene_core_device_1cfad35b.defineAction)({
1855
+ Terminate: defineAction({
1849
1856
  name: 'Terminate',
1850
1857
  description: 'Terminate (force-stop) an Android app by package name',
1851
1858
  interfaceAlias: 'terminate',
@@ -1859,7 +1866,7 @@ const createPlatformActions = (device)=>({
1859
1866
  const debugUtils = (0, logger_.getDebug)('android:utils');
1860
1867
  async function getConnectedDevices() {
1861
1868
  try {
1862
- const adb = await __rspack_external_appium_adb_724653d6.ADB.createADB({
1869
+ const adb = await external_appium_adb_ADB.createADB({
1863
1870
  adbExecTimeout: 60000
1864
1871
  });
1865
1872
  const devices = await adb.getConnectedDevices();
@@ -1883,7 +1890,7 @@ function agent_define_property(obj, key, value) {
1883
1890
  return obj;
1884
1891
  }
1885
1892
  const debugAgent = (0, logger_.getDebug)('android:agent');
1886
- class AndroidAgent extends __rspack_external__midscene_core_agent_2b7f9158.Agent {
1893
+ class AndroidAgent extends Agent {
1887
1894
  async launch(uri) {
1888
1895
  const action = this.wrapActionInActionSpace('Launch');
1889
1896
  return action({
@@ -1899,7 +1906,7 @@ class AndroidAgent extends __rspack_external__midscene_core_agent_2b7f9158.Agent
1899
1906
  async runAdbShell(command, opt) {
1900
1907
  if (opt?.timeout !== void 0) {
1901
1908
  const adb = await this.interface.getAdb();
1902
- return await adb.shell(command, {
1909
+ return await runAdbShellStdoutOrThrow(adb, command, {
1903
1910
  timeout: opt.timeout
1904
1911
  });
1905
1912
  }
@@ -1914,7 +1921,7 @@ class AndroidAgent extends __rspack_external__midscene_core_agent_2b7f9158.Agent
1914
1921
  }
1915
1922
  constructor(device, opts){
1916
1923
  super(device, opts), agent_define_property(this, "back", void 0), agent_define_property(this, "home", void 0), agent_define_property(this, "recentApps", void 0), agent_define_property(this, "appNameMapping", void 0);
1917
- this.appNameMapping = (0, __rspack_external__midscene_shared_utils_b0457388.mergeAndNormalizeAppNameMapping)(defaultAppNameMapping, opts?.appNameMapping);
1924
+ this.appNameMapping = mergeAndNormalizeAppNameMapping(defaultAppNameMapping, opts?.appNameMapping);
1918
1925
  device.setAppNameMapping(this.appNameMapping);
1919
1926
  this.back = this.createActionWrapper('AndroidBackButton');
1920
1927
  this.home = this.createActionWrapper('AndroidHomeButton');
@@ -1943,7 +1950,7 @@ function mcp_tools_define_property(obj, key, value) {
1943
1950
  return obj;
1944
1951
  }
1945
1952
  const debug = (0, logger_.getDebug)('mcp:android-tools');
1946
- class AndroidMidsceneTools extends __rspack_external__midscene_shared_mcp_base_tools_a0c805f3.BaseMidsceneTools {
1953
+ class AndroidMidsceneTools extends BaseMidsceneTools {
1947
1954
  getCliReportSessionName() {
1948
1955
  return 'midscene-android';
1949
1956
  }
@@ -2021,8 +2028,8 @@ class AndroidMidsceneTools extends __rspack_external__midscene_shared_mcp_base_t
2021
2028
  super(...args), mcp_tools_define_property(this, "initArgSpec", {
2022
2029
  namespace: 'android',
2023
2030
  shape: {
2024
- deviceId: __rspack_external__midscene_core_c3cd7634.z.string().optional().describe('Android device ID (from adb devices)'),
2025
- useScrcpy: __rspack_external__midscene_core_c3cd7634.z.boolean().optional().describe('Enable scrcpy accelerated screenshots')
2031
+ deviceId: z.string().optional().describe('Android device ID (from adb devices)'),
2032
+ useScrcpy: z.boolean().optional().describe('Enable scrcpy accelerated screenshots')
2026
2033
  },
2027
2034
  cli: {
2028
2035
  preferBareKeys: true
@@ -2035,10 +2042,10 @@ class AndroidMidsceneTools extends __rspack_external__midscene_shared_mcp_base_t
2035
2042
  }
2036
2043
  }
2037
2044
  const tools = new AndroidMidsceneTools();
2038
- (0, __rspack_external__midscene_shared_cli_24fbb5ae.runToolsCLI)(tools, 'midscene-android', {
2045
+ runToolsCLI(tools, 'midscene-android', {
2039
2046
  stripPrefix: 'android_',
2040
- version: "1.9.5-beta-20260611045217.0",
2041
- extraCommands: (0, __rspack_external__midscene_core_c3cd7634.createReportCliCommands)()
2047
+ version: "1.9.5",
2048
+ extraCommands: createReportCliCommands()
2042
2049
  }).catch((e)=>{
2043
- process.exit((0, __rspack_external__midscene_shared_cli_24fbb5ae.reportCLIError)(e));
2050
+ process.exit(reportCLIError(e));
2044
2051
  });