@midscene/computer 1.12.2 → 1.12.3-beta-20260828085408.0

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/lib/cli.js CHANGED
@@ -54,6 +54,7 @@ function _define_property(obj, key, value) {
54
54
  else obj[key] = value;
55
55
  return obj;
56
56
  }
57
+ const MOUSE_COORDINATE_TOLERANCE_PX = 5;
57
58
  class ComputerInputDriver {
58
59
  destroy() {
59
60
  if (this.destroyed) return;
@@ -69,6 +70,15 @@ class ComputerInputDriver {
69
70
  moveMouse(x, y) {
70
71
  this.getLibnutOrThrow('moveMouse').moveMouse(x, y);
71
72
  }
73
+ assertMousePosition(targetX, targetY, context) {
74
+ const current = this.getMousePos();
75
+ const drift = {
76
+ x: current.x - targetX,
77
+ y: current.y - targetY
78
+ };
79
+ if (Math.abs(drift.x) > MOUSE_COORDINATE_TOLERANCE_PX || Math.abs(drift.y) > MOUSE_COORDINATE_TOLERANCE_PX) throw new Error(`${context}: expected (${targetX}, ${targetY}), got (${current.x}, ${current.y}), drift=(${drift.x}, ${drift.y})`);
80
+ return drift;
81
+ }
72
82
  focusActiveWindow() {
73
83
  const lib = this.getLibnutOrThrow('focusActiveWindow');
74
84
  if ('function' != typeof lib.getActiveWindow || 'function' != typeof lib.focusWindow) return false;
@@ -209,6 +219,83 @@ class ComputerInputDriver {
209
219
  this.pendingInputDelayWaits = new Set();
210
220
  }
211
221
  }
222
+ function windows_pointer_define_property(obj, key, value) {
223
+ if (key in obj) Object.defineProperty(obj, key, {
224
+ value: value,
225
+ enumerable: true,
226
+ configurable: true,
227
+ writable: true
228
+ });
229
+ else obj[key] = value;
230
+ return obj;
231
+ }
232
+ const WINDOWS_POINTER_TOLERANCE_PX = 5;
233
+ function assertFinitePoint(point, context) {
234
+ if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) throw new Error(`${context} must contain finite coordinates, got (${point.x}, ${point.y})`);
235
+ }
236
+ function parseWindowsPointerPosition(output, context) {
237
+ const match = output.trim().match(/^(-?\d+),(-?\d+)$/);
238
+ if (!match) throw new Error(`${context} returned an invalid cursor position: ${JSON.stringify(output.trim())}`);
239
+ return {
240
+ x: Number(match[1]),
241
+ y: Number(match[2])
242
+ };
243
+ }
244
+ function windowsPointerPositionScript() {
245
+ return `
246
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
247
+ $position = [System.Windows.Forms.Cursor]::Position
248
+ [Console]::Out.Write(('{0},{1}' -f $position.X, $position.Y))
249
+ `.trim();
250
+ }
251
+ function windowsPointerMoveScript(point, options) {
252
+ assertFinitePoint(point, 'Windows pointer target');
253
+ if (options?.smoothSteps !== void 0 && !Number.isFinite(options.smoothSteps) || options?.smoothDelayMs !== void 0 && !Number.isFinite(options.smoothDelayMs)) throw new Error('Windows pointer smoothing options must be finite numbers');
254
+ const targetX = Math.round(point.x);
255
+ const targetY = Math.round(point.y);
256
+ const smoothSteps = Math.max(1, Math.round(options?.smoothSteps ?? 1));
257
+ const smoothDelayMs = Math.max(0, Math.round(options?.smoothDelayMs ?? 0));
258
+ return `
259
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
260
+ $targetX = ${targetX}
261
+ $targetY = ${targetY}
262
+ $smoothSteps = ${smoothSteps}
263
+ $smoothDelayMs = ${smoothDelayMs}
264
+ $start = [System.Windows.Forms.Cursor]::Position
265
+ for ($step = 1; $step -le $smoothSteps; $step += 1) {
266
+ $x = [int][Math]::Round($start.X + (($targetX - $start.X) * $step / [double]$smoothSteps))
267
+ $y = [int][Math]::Round($start.Y + (($targetY - $start.Y) * $step / [double]$smoothSteps))
268
+ [System.Windows.Forms.Cursor]::Position = [System.Drawing.Point]::new($x, $y)
269
+ if ($smoothDelayMs -gt 0 -and $step -lt $smoothSteps) {
270
+ Start-Sleep -Milliseconds $smoothDelayMs
271
+ }
272
+ }
273
+ [System.Windows.Forms.Cursor]::Position = [System.Drawing.Point]::new($targetX, $targetY)
274
+ $position = [System.Windows.Forms.Cursor]::Position
275
+ [Console]::Out.Write(('{0},{1}' -f $position.X, $position.Y))
276
+ `.trim();
277
+ }
278
+ class WindowsPointerDriver {
279
+ getPosition() {
280
+ return parseWindowsPointerPosition(this.options.runPowershell(windowsPointerPositionScript()), 'Windows pointer query');
281
+ }
282
+ moveTo(point, options) {
283
+ return parseWindowsPointerPosition(this.options.runPowershell(windowsPointerMoveScript(point, options)), 'Windows pointer move');
284
+ }
285
+ constructor(options){
286
+ windows_pointer_define_property(this, "options", void 0);
287
+ this.options = options;
288
+ }
289
+ }
290
+ function windowsPointerDrift(expected, actual) {
291
+ return {
292
+ x: actual.x - expected.x,
293
+ y: actual.y - expected.y
294
+ };
295
+ }
296
+ function windowsPointerIsWithinTolerance(drift) {
297
+ return Math.abs(drift.x) <= WINDOWS_POINTER_TOLERANCE_PX && Math.abs(drift.y) <= WINDOWS_POINTER_TOLERANCE_PX;
298
+ }
212
299
  const interrupt_namespaceObject = require("@midscene/shared/cli/interrupt");
213
300
  const debugXvfb = (0, logger_namespaceObject.getDebug)('computer:xvfb');
214
301
  const xvfbCleanupMonitorScript = String.raw`
@@ -487,19 +574,33 @@ function runPowershell(script) {
487
574
  windowsHide: true
488
575
  });
489
576
  }
490
- function listWindowsDisplays() {
577
+ function readWindowsDisplayGeometries() {
491
578
  const script = `
492
579
  Add-Type -AssemblyName System.Windows.Forms
493
580
  $s = [System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
494
- [PSCustomObject]@{ id = $_.DeviceName; name = $_.DeviceName; primary = $_.Primary }
581
+ $b = $_.Bounds
582
+ [PSCustomObject]@{
583
+ id = $_.DeviceName
584
+ name = $_.DeviceName
585
+ primary = $_.Primary
586
+ bounds = [PSCustomObject]@{ x = $b.X; y = $b.Y; width = $b.Width; height = $b.Height }
587
+ }
495
588
  }
496
589
  ConvertTo-Json @($s) -Compress
497
590
  `.trim();
498
- const parsed = JSON.parse(runPowershell(script).trim());
499
- return parsed.map((d)=>({
500
- id: String(d.id),
501
- name: d.name || String(d.id),
502
- primary: d.primary || false
591
+ const output = runPowershell(script).trim();
592
+ if (!output) throw new Error('Windows display enumeration returned no data');
593
+ const parsed = JSON.parse(output);
594
+ if (!Array.isArray(parsed)) throw new Error('Windows display enumeration returned invalid data');
595
+ const displays = parsed.filter(isWindowsDisplayGeometry);
596
+ if (displays.length !== parsed.length || 0 === displays.length) throw new Error('Windows display enumeration returned invalid geometry');
597
+ return displays;
598
+ }
599
+ function listWindowsDisplays(geometries = readWindowsDisplayGeometries()) {
600
+ return geometries.map((display)=>({
601
+ id: display.id,
602
+ name: display.name,
603
+ primary: display.primary
503
604
  }));
504
605
  }
505
606
  let device_libnut = null;
@@ -601,6 +702,16 @@ function getDisplayInfoBinary() {
601
702
  function isFiniteNumber(value) {
602
703
  return 'number' == typeof value && Number.isFinite(value);
603
704
  }
705
+ function isDisplayBounds(value) {
706
+ if (!value || 'object' != typeof value) return false;
707
+ const bounds = value;
708
+ return isFiniteNumber(bounds.x) && isFiniteNumber(bounds.y) && isFiniteNumber(bounds.width) && isFiniteNumber(bounds.height) && bounds.width > 0 && bounds.height > 0;
709
+ }
710
+ function isWindowsDisplayGeometry(value) {
711
+ if (!value || 'object' != typeof value) return false;
712
+ const candidate = value;
713
+ return 'string' == typeof candidate.id && candidate.id.length > 0 && 'string' == typeof candidate.name && 'boolean' == typeof candidate.primary && isDisplayBounds(candidate.bounds);
714
+ }
604
715
  function isDarwinDisplayGeometry(value) {
605
716
  if (!value || 'object' != typeof value) return false;
606
717
  const candidate = value;
@@ -643,9 +754,11 @@ function readDarwinFrontmostApplication() {
643
754
  return;
644
755
  }
645
756
  }
646
- async function pressMouseAtGlobalPoint(inputDriver, targetX, targetY, holdDuration, reason) {
647
- await inputDriver.delay(CLICK_SETTLE_DELAY);
648
- const current = inputDriver.getMousePos();
757
+ async function pressMouseAtGlobalPoint(inputDriver, targetX, targetY, current, holdDuration, reason) {
758
+ const drift = {
759
+ x: current.x - targetX,
760
+ y: current.y - targetY
761
+ };
649
762
  debugComputerInput('tap mouse moved %o', {
650
763
  reason,
651
764
  target: {
@@ -653,10 +766,7 @@ async function pressMouseAtGlobalPoint(inputDriver, targetX, targetY, holdDurati
653
766
  y: targetY
654
767
  },
655
768
  current,
656
- drift: {
657
- x: current.x - targetX,
658
- y: current.y - targetY
659
- }
769
+ drift
660
770
  });
661
771
  await inputDriver.withMouseButton('left', async ()=>{
662
772
  debugComputerInput('tap mouse down %o', {
@@ -675,9 +785,18 @@ function resolveDarwinDisplayGeometryFromList(displayId, displays) {
675
785
  if (void 0 === displayId || '' === displayId) return displays.find((display)=>display.primary) || displays.find((display)=>0 === display.screenIndex) || displays[0];
676
786
  return displays.find((display)=>display.screenIndex === screenIndex) || displays.find((display)=>display.cgDisplayId === screenIndex);
677
787
  }
678
- function resolveDisplayGeometry(displayId) {
679
- if ('darwin' !== process.platform) return;
680
- return resolveDarwinDisplayGeometryFromList(displayId, readDarwinDisplayGeometries());
788
+ function resolveWindowsDisplayGeometryFromList(displayId, displays) {
789
+ if (!displays.length) return;
790
+ if (void 0 === displayId || '' === displayId) return displays.find((display)=>display.primary) || displays[0];
791
+ return displays.find((display)=>display.id === displayId);
792
+ }
793
+ function resolveDisplayGeometry(displayId, windowsDisplays) {
794
+ if ('darwin' === process.platform) return resolveDarwinDisplayGeometryFromList(displayId, readDarwinDisplayGeometries());
795
+ if ('win32' === process.platform) {
796
+ const geometry = resolveWindowsDisplayGeometryFromList(displayId, windowsDisplays ?? readWindowsDisplayGeometries());
797
+ if (!geometry) throw new Error(displayId ? `Requested Windows display not found: ${displayId}` : 'No Windows displays were detected');
798
+ return geometry;
799
+ }
681
800
  }
682
801
  function mapDisplayLocalPointToGlobal(point, geometry) {
683
802
  if (!geometry) return point;
@@ -763,6 +882,30 @@ function normalizePrimaryKey(key) {
763
882
  return KEY_NAME_MAP[lowerKey] || lowerKey;
764
883
  }
765
884
  class ComputerDevice {
885
+ async moveGlobalPointer(point, context, smooth) {
886
+ if (this.destroyed) throw new Error('ComputerDevice has been destroyed');
887
+ const target = {
888
+ x: Math.round(point.x),
889
+ y: Math.round(point.y)
890
+ };
891
+ if ('win32' === process.platform) {
892
+ const actual = this.windowsPointerDriver.moveTo(target, {
893
+ smoothSteps: smooth?.smoothSteps,
894
+ smoothDelayMs: smooth?.smoothDelay
895
+ });
896
+ const drift = windowsPointerDrift(target, actual);
897
+ if (!windowsPointerIsWithinTolerance(drift)) throw new Error(`${context}: expected (${target.x}, ${target.y}), got (${actual.x}, ${actual.y}), drift=(${drift.x}, ${drift.y})`);
898
+ await this.inputDriver.delay(CLICK_SETTLE_DELAY);
899
+ return actual;
900
+ }
901
+ if (smooth) await this.inputDriver.smoothMoveMouse(target.x, target.y, smooth.smoothSteps, smooth.smoothDelay);
902
+ else this.inputDriver.moveMouse(target.x, target.y);
903
+ await this.inputDriver.delay(CLICK_SETTLE_DELAY);
904
+ return target;
905
+ }
906
+ moveDisplayPointer(point, context, smooth) {
907
+ return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
908
+ }
766
909
  async focusKeyboardTarget(element, delayMs) {
767
910
  const [x, y] = element.center;
768
911
  if ('darwin' === process.platform) await this.inputPrimitives.pointer.tap({
@@ -770,11 +913,10 @@ class ComputerDevice {
770
913
  y
771
914
  });
772
915
  else {
773
- const point = this.toGlobalPoint({
916
+ await this.moveDisplayPointer({
774
917
  x,
775
918
  y
776
- });
777
- this.inputDriver.moveMouse(Math.round(point.x), Math.round(point.y));
919
+ }, 'Mouse did not reach the keyboard focus target');
778
920
  this.inputDriver.mouseClick('left');
779
921
  }
780
922
  await this.inputDriver.delay(delayMs);
@@ -793,7 +935,7 @@ class ComputerDevice {
793
935
  }));
794
936
  } catch (error) {
795
937
  debugDevice(`Failed to list displays: ${error}`);
796
- return [];
938
+ throw new Error(`Failed to list displays: ${error}`);
797
939
  }
798
940
  }
799
941
  async connect() {
@@ -822,9 +964,10 @@ class ComputerDevice {
822
964
  }
823
965
  }
824
966
  device_libnut = await getLibnut();
825
- this.displayGeometry = resolveDisplayGeometry(this.displayId);
967
+ const windowsDisplayGeometries = 'win32' === process.platform ? readWindowsDisplayGeometries() : void 0;
968
+ this.displayGeometry = resolveDisplayGeometry(this.displayId, windowsDisplayGeometries);
826
969
  const size = await this.size();
827
- const displays = await ComputerDevice.listDisplays();
970
+ const displays = windowsDisplayGeometries ? listWindowsDisplays(windowsDisplayGeometries) : await ComputerDevice.listDisplays();
828
971
  const headlessInfo = this.xvfbInstance ? `\nHeadless: true (Xvfb on ${this.xvfbInstance.display})` : '';
829
972
  this.description = `
830
973
  Type: Computer
@@ -834,7 +977,7 @@ Screen Size: ${size.width}x${size.height}
834
977
  Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ') : 'Unknown'}${headlessInfo}
835
978
  `;
836
979
  debugDevice('Computer device connected', this.description);
837
- await this.healthCheck();
980
+ await this.healthCheck(displays);
838
981
  } catch (error) {
839
982
  if (this.xvfbInstance) {
840
983
  if (!this.options?.keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
@@ -853,9 +996,9 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
853
996
  throw new Error(`Unable to connect to computer device: ${error}`);
854
997
  }
855
998
  }
856
- async healthCheck() {
999
+ async healthCheck(displays) {
857
1000
  console.log('[HealthCheck] Starting health check...');
858
- console.log("[HealthCheck] @midscene/computer v1.12.2");
1001
+ console.log("[HealthCheck] @midscene/computer v1.12.3-beta-20260828085408.0");
859
1002
  console.log('[HealthCheck] Taking screenshot...');
860
1003
  const screenshotTimeout = 15000;
861
1004
  let timeoutId;
@@ -867,23 +1010,38 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
867
1010
  timeoutPromise
868
1011
  ]);
869
1012
  console.log(`[HealthCheck] Screenshot succeeded (length=${base64.length})`);
870
- console.log('[HealthCheck] Moving mouse...');
871
- const startPos = this.inputDriver.getMousePos();
1013
+ console.log('[HealthCheck] Verifying mouse control...');
1014
+ const startPos = 'win32' === process.platform ? this.windowsPointerDriver.getPosition() : this.inputDriver.getMousePos();
872
1015
  console.log(`[HealthCheck] Current mouse position: (${startPos.x}, ${startPos.y})`);
873
- const offsetX = Math.floor(40 * Math.random()) + 10;
874
- const offsetY = Math.floor(40 * Math.random()) + 10;
875
- const targetX = startPos.x + offsetX;
876
- const targetY = startPos.y + offsetY;
877
- console.log(`[HealthCheck] Moving mouse to (${targetX}, ${targetY})...`);
878
- this.inputDriver.moveMouse(targetX, targetY);
879
- await (0, utils_namespaceObject.sleep)(50);
880
- const movedPos = this.inputDriver.getMousePos();
881
- console.log(`[HealthCheck] Mouse position after move: (${movedPos.x}, ${movedPos.y})`);
882
- const deltaX = Math.abs(movedPos.x - targetX);
883
- const deltaY = Math.abs(movedPos.y - targetY);
884
- if (deltaX > 5 || deltaY > 5) {
885
- const msg = `[HealthCheck] WARNING: Mouse control may not be working. Expected (${targetX}, ${targetY}), got (${movedPos.x}, ${movedPos.y}), delta=(${deltaX}, ${deltaY})`;
886
- warnDevice(msg);
1016
+ if ('win32' === process.platform) {
1017
+ if (!this.displayGeometry) throw new Error('Windows display geometry is unavailable');
1018
+ const bounds = this.displayGeometry.bounds;
1019
+ const target = {
1020
+ x: Math.round(bounds.x + bounds.width / 2),
1021
+ y: Math.round(bounds.y + bounds.height / 2)
1022
+ };
1023
+ try {
1024
+ const actual = this.windowsPointerDriver.moveTo(target);
1025
+ const drift = windowsPointerDrift(target, actual);
1026
+ if (!windowsPointerIsWithinTolerance(drift)) throw new Error(`Windows screenshot-space pointer verification: expected (${target.x}, ${target.y}), got (${actual.x}, ${actual.y}), drift=(${drift.x}, ${drift.y})`);
1027
+ } finally{
1028
+ this.windowsPointerDriver.moveTo(startPos);
1029
+ }
1030
+ console.log(`[HealthCheck] Mouse verified in screenshot-space display bounds (${bounds.x}, ${bounds.y}, ${bounds.width}, ${bounds.height})`);
1031
+ } else {
1032
+ const offsetX = Math.floor(40 * Math.random()) + 10;
1033
+ const offsetY = Math.floor(40 * Math.random()) + 10;
1034
+ const targetX = startPos.x + offsetX;
1035
+ const targetY = startPos.y + offsetY;
1036
+ console.log(`[HealthCheck] Moving mouse to (${targetX}, ${targetY})...`);
1037
+ try {
1038
+ this.inputDriver.moveMouse(targetX, targetY);
1039
+ await (0, utils_namespaceObject.sleep)(CLICK_SETTLE_DELAY);
1040
+ this.inputDriver.assertMousePosition(targetX, targetY, 'Mouse health check failed');
1041
+ } finally{
1042
+ this.inputDriver.moveMouse(startPos.x, startPos.y);
1043
+ console.log(`[HealthCheck] Mouse restored to (${startPos.x}, ${startPos.y})`);
1044
+ }
887
1045
  }
888
1046
  if ('win32' === process.platform && !this.isRunningAsAdmin()) {
889
1047
  const hint = [
@@ -893,10 +1051,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
893
1051
  ].join(' ');
894
1052
  warnDevice(`[HealthCheck] ${hint}`);
895
1053
  }
896
- this.inputDriver.moveMouse(startPos.x, startPos.y);
897
- console.log(`[HealthCheck] Mouse restored to (${startPos.x}, ${startPos.y})`);
898
1054
  console.log('[HealthCheck] Listing monitors...');
899
- const displays = await ComputerDevice.listDisplays();
900
1055
  if (displays.length > 0) {
901
1056
  console.log(`[HealthCheck] Found ${displays.length} monitor(s):`);
902
1057
  for (const display of displays){
@@ -1079,10 +1234,14 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1079
1234
  resolveUntargetedScrollPoint(screenSize) {
1080
1235
  if ('win32' === process.platform) {
1081
1236
  const activeWindowRect = this.inputDriver.getActiveWindowRect();
1082
- if (activeWindowRect) return {
1083
- x: activeWindowRect.x + activeWindowRect.width / 2,
1084
- y: activeWindowRect.y + activeWindowRect.height / 2
1085
- };
1237
+ if (activeWindowRect) {
1238
+ const activeWindowCenter = {
1239
+ x: activeWindowRect.x + activeWindowRect.width / 2,
1240
+ y: activeWindowRect.y + activeWindowRect.height / 2
1241
+ };
1242
+ const bounds = this.displayGeometry?.bounds;
1243
+ if (!bounds || activeWindowCenter.x >= bounds.x && activeWindowCenter.x < bounds.x + bounds.width && activeWindowCenter.y >= bounds.y && activeWindowCenter.y < bounds.y + bounds.height) return activeWindowCenter;
1244
+ }
1086
1245
  }
1087
1246
  return this.toGlobalPoint({
1088
1247
  x: screenSize.width / 2,
@@ -1093,17 +1252,16 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1093
1252
  if (param.locate) {
1094
1253
  const element = param.locate;
1095
1254
  const [x, y] = element.center;
1096
- const point = this.toGlobalPoint({
1255
+ await this.moveDisplayPointer({
1097
1256
  x,
1098
1257
  y
1099
- });
1100
- this.inputDriver.moveMouse(Math.round(point.x), Math.round(point.y));
1258
+ }, 'Mouse did not reach the scroll target');
1101
1259
  return;
1102
1260
  }
1103
1261
  const screenSize = await this.size();
1104
1262
  if ('win32' === process.platform && this.inputDriver.focusActiveWindow()) await this.inputDriver.delay(CLICK_FOCUS_SETTLE_DELAY);
1105
1263
  const point = this.resolveUntargetedScrollPoint(screenSize);
1106
- this.inputDriver.moveMouse(Math.round(point.x), Math.round(point.y));
1264
+ await this.moveGlobalPointer(point, 'Mouse did not reach the scroll viewport');
1107
1265
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1108
1266
  return screenSize;
1109
1267
  }
@@ -1228,6 +1386,9 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1228
1386
  runPhasedScroll,
1229
1387
  debug: (message)=>debugDevice(message)
1230
1388
  }));
1389
+ device_define_property(this, "windowsPointerDriver", new WindowsPointerDriver({
1390
+ runPowershell
1391
+ }));
1231
1392
  device_define_property(this, "useAppleScript", void 0);
1232
1393
  device_define_property(this, "adminCheckCache", void 0);
1233
1394
  device_define_property(this, "uri", void 0);
@@ -1252,15 +1413,17 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1252
1413
  },
1253
1414
  holdDuration,
1254
1415
  displayId: this.displayId,
1255
- displayGeometry: this.displayGeometry ? {
1256
- screenIndex: this.displayGeometry.screenIndex,
1257
- cgDisplayId: this.displayGeometry.cgDisplayId,
1258
- bounds: this.displayGeometry.bounds
1259
- } : void 0
1416
+ displayGeometry: this.displayGeometry
1260
1417
  });
1261
1418
  const frontmostBefore = 'darwin' === process.platform ? readDarwinFrontmostApplication() : void 0;
1262
- await this.inputDriver.smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_TAP, SMOOTH_MOVE_DELAY_TAP);
1263
- await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, holdDuration, 'primary');
1419
+ const current = await this.moveGlobalPointer({
1420
+ x: targetX,
1421
+ y: targetY
1422
+ }, 'Mouse did not reach the tap target', {
1423
+ smoothSteps: SMOOTH_MOVE_STEPS_TAP,
1424
+ smoothDelay: SMOOTH_MOVE_DELAY_TAP
1425
+ });
1426
+ await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, current, holdDuration, 'primary');
1264
1427
  if (frontmostBefore && 'darwin' === process.platform) {
1265
1428
  await (0, utils_namespaceObject.sleep)(CLICK_FOCUS_SETTLE_DELAY);
1266
1429
  const frontmostAfter = readDarwinFrontmostApplication();
@@ -1271,42 +1434,43 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1271
1434
  focusChanged
1272
1435
  });
1273
1436
  if (focusChanged) {
1274
- this.inputDriver.moveMouse(targetX, targetY);
1275
- await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, holdDuration, 'focus-follow-up');
1437
+ const followUpCurrent = await this.moveGlobalPointer({
1438
+ x: targetX,
1439
+ y: targetY
1440
+ }, 'Mouse did not reach the focus follow-up target');
1441
+ await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, followUpCurrent, holdDuration, 'focus-follow-up');
1276
1442
  }
1277
1443
  }
1278
1444
  },
1279
1445
  doubleClick: async ({ x, y })=>{
1280
- const target = this.toGlobalPoint({
1446
+ await this.moveDisplayPointer({
1281
1447
  x,
1282
1448
  y
1283
- });
1284
- this.inputDriver.moveMouse(Math.round(target.x), Math.round(target.y));
1449
+ }, 'Mouse did not reach the double-click target');
1285
1450
  this.inputDriver.mouseClick('left', true);
1286
1451
  },
1287
1452
  rightClick: async ({ x, y })=>{
1288
- const target = this.toGlobalPoint({
1453
+ await this.moveDisplayPointer({
1289
1454
  x,
1290
1455
  y
1291
- });
1292
- this.inputDriver.moveMouse(Math.round(target.x), Math.round(target.y));
1456
+ }, 'Mouse did not reach the right-click target');
1293
1457
  this.inputDriver.mouseClick('right');
1294
1458
  },
1295
1459
  hover: async ({ x, y })=>{
1296
- const target = this.toGlobalPoint({
1460
+ await this.moveDisplayPointer({
1297
1461
  x,
1298
1462
  y
1463
+ }, 'Mouse did not reach the hover target', {
1464
+ smoothSteps: SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1465
+ smoothDelay: SMOOTH_MOVE_DELAY_MOUSE_MOVE
1299
1466
  });
1300
- await this.inputDriver.smoothMoveMouse(Math.round(target.x), Math.round(target.y), SMOOTH_MOVE_STEPS_MOUSE_MOVE, SMOOTH_MOVE_DELAY_MOUSE_MOVE);
1301
1467
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1302
1468
  },
1303
1469
  dragAndDrop: async (from, to)=>{
1304
- const globalFrom = this.toGlobalPoint(from);
1305
- const globalTo = this.toGlobalPoint(to);
1306
- this.inputDriver.moveMouse(Math.round(globalFrom.x), Math.round(globalFrom.y));
1470
+ await this.moveDisplayPointer(from, 'Mouse did not reach the drag start target');
1307
1471
  await this.inputDriver.withMouseButton('left', async ()=>{
1308
1472
  await this.inputDriver.delay(100);
1309
- this.inputDriver.moveMouse(Math.round(globalTo.x), Math.round(globalTo.y));
1473
+ await this.moveDisplayPointer(to, 'Mouse did not reach the drag end target');
1310
1474
  await this.inputDriver.delay(100);
1311
1475
  });
1312
1476
  }
@@ -2265,7 +2429,7 @@ const tools = new ComputerMidsceneTools({
2265
2429
  });
2266
2430
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
2267
2431
  stripPrefix: 'computer_',
2268
- version: "1.12.2",
2432
+ version: "1.12.3-beta-20260828085408.0",
2269
2433
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
2270
2434
  }).catch((e)=>{
2271
2435
  process.exit((0, cli_namespaceObject.reportCLIError)(e));