@midscene/computer 1.13.4-beta-20260928083351.0 → 1.14.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/es/index.mjs CHANGED
@@ -86,24 +86,6 @@ function sendKeyViaAppleScript(key, modifiers = []) {
86
86
  script
87
87
  ]);
88
88
  }
89
- const desktopPointerPolicy = {
90
- uiSettleMs: 100,
91
- moveSettleMs: 50,
92
- defaultTapHoldMs: 100,
93
- tapMoveSteps: 8,
94
- tapMoveStepDelayMs: 8,
95
- hoverMoveSteps: 10,
96
- hoverMoveStepDelayMs: 10
97
- };
98
- const desktopKeyboardPolicy = {
99
- focusBeforeTypeMs: 300,
100
- focusBeforeClearMs: 300,
101
- focusBeforeShortcutMs: 50,
102
- afterClearMs: 150
103
- };
104
- function resolveTapHoldDuration(duration) {
105
- return Math.max(0, Math.round(duration ?? desktopPointerPolicy.defaultTapHoldMs));
106
- }
107
89
  function _define_property(obj, key, value) {
108
90
  if (key in obj) Object.defineProperty(obj, key, {
109
91
  value: value,
@@ -793,9 +775,18 @@ async function captureScreenshot(options) {
793
775
  });
794
776
  }
795
777
  }
778
+ const SMOOTH_MOVE_STEPS_TAP = 8;
779
+ const SMOOTH_MOVE_STEPS_MOUSE_MOVE = 10;
796
780
  const SMOOTH_MOVE_STEPS_DRAG = 20;
781
+ const SMOOTH_MOVE_DELAY_TAP = 8;
782
+ const SMOOTH_MOVE_DELAY_MOUSE_MOVE = 10;
797
783
  const SMOOTH_MOVE_DELAY_DRAG = 10;
784
+ const MOUSE_MOVE_EFFECT_WAIT = 300;
785
+ const CLICK_SETTLE_DELAY = 50;
786
+ const CLICK_HOLD_DURATION = 100;
798
787
  const CLICK_FOCUS_SETTLE_DELAY = 120;
788
+ const INPUT_FOCUS_DELAY = 300;
789
+ const INPUT_CLEAR_DELAY = 150;
799
790
  const SCROLL_STEP_DELAY = 100;
800
791
  const SCROLL_COMPLETE_DELAY = 500;
801
792
  const EDGE_SCROLL_TOTAL_PX = 50000;
@@ -1116,7 +1107,7 @@ function normalizePrimaryKey(key) {
1116
1107
  return KEY_NAME_MAP[lowerKey] || lowerKey;
1117
1108
  }
1118
1109
  class ComputerDevice {
1119
- async moveGlobalPointer(point, context, options) {
1110
+ async moveGlobalPointer(point, context, smooth) {
1120
1111
  if (this.destroyed) throw new Error('ComputerDevice has been destroyed');
1121
1112
  const target = {
1122
1113
  x: Math.round(point.x),
@@ -1124,21 +1115,21 @@ class ComputerDevice {
1124
1115
  };
1125
1116
  if ('win32' === process.platform) {
1126
1117
  const actual = this.windowsPointerDriver.moveTo(target, {
1127
- smoothSteps: options?.smoothSteps,
1128
- smoothDelayMs: options?.smoothDelay
1118
+ smoothSteps: smooth?.smoothSteps,
1119
+ smoothDelayMs: smooth?.smoothDelay
1129
1120
  });
1130
1121
  const drift = windowsPointerDrift(target, actual);
1131
1122
  if (!windowsPointerIsWithinTolerance(drift)) throw new Error(`${context}: expected (${target.x}, ${target.y}), got (${actual.x}, ${actual.y}), drift=(${drift.x}, ${drift.y})`);
1132
- await this.inputDriver.delay(options?.settleDelayMs ?? desktopPointerPolicy.moveSettleMs);
1123
+ await this.inputDriver.delay(CLICK_SETTLE_DELAY);
1133
1124
  return actual;
1134
1125
  }
1135
- if (options?.smoothSteps !== void 0 && void 0 !== options.smoothDelay) await this.inputDriver.smoothMoveMouse(target.x, target.y, options.smoothSteps, options.smoothDelay);
1126
+ if (smooth) await this.inputDriver.smoothMoveMouse(target.x, target.y, smooth.smoothSteps, smooth.smoothDelay);
1136
1127
  else this.inputDriver.moveMouse(target.x, target.y);
1137
- await this.inputDriver.delay(options?.settleDelayMs ?? desktopPointerPolicy.moveSettleMs);
1128
+ await this.inputDriver.delay(CLICK_SETTLE_DELAY);
1138
1129
  return this.inputDriver.getMousePos();
1139
1130
  }
1140
- moveDisplayPointer(point, context, options) {
1141
- return this.moveGlobalPointer(this.toGlobalPoint(point), context, options);
1131
+ moveDisplayPointer(point, context, smooth) {
1132
+ return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
1142
1133
  }
1143
1134
  async performPointerDrag(from, to, duration) {
1144
1135
  const screenSize = await this.size();
@@ -1164,9 +1155,7 @@ class ComputerDevice {
1164
1155
  await this.moveDisplayPointer({
1165
1156
  x,
1166
1157
  y
1167
- }, 'Mouse did not reach the keyboard focus target', {
1168
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1169
- });
1158
+ }, 'Mouse did not reach the keyboard focus target');
1170
1159
  this.inputDriver.mouseClick('left');
1171
1160
  }
1172
1161
  await this.inputDriver.delay(delayMs);
@@ -1248,7 +1237,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1248
1237
  }
1249
1238
  async healthCheck(displays) {
1250
1239
  console.log('[HealthCheck] Starting health check...');
1251
- console.log("[HealthCheck] @midscene/computer v1.13.4-beta-20260928083351.0");
1240
+ console.log("[HealthCheck] @midscene/computer v1.14.0");
1252
1241
  console.log('[HealthCheck] Taking screenshot...');
1253
1242
  const screenshotTimeout = 15000;
1254
1243
  let timeoutId;
@@ -1286,7 +1275,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1286
1275
  console.log(`[HealthCheck] Moving mouse to (${targetX}, ${targetY})...`);
1287
1276
  try {
1288
1277
  this.inputDriver.moveMouse(targetX, targetY);
1289
- await sleep(desktopPointerPolicy.moveSettleMs);
1278
+ await sleep(CLICK_SETTLE_DELAY);
1290
1279
  this.inputDriver.assertMousePosition(targetX, targetY, 'Mouse health check failed');
1291
1280
  } finally{
1292
1281
  this.inputDriver.moveMouse(startPos.x, startPos.y);
@@ -1521,9 +1510,8 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1521
1510
  const screenSize = await this.size();
1522
1511
  if ('win32' === process.platform && this.inputDriver.focusActiveWindow()) await this.inputDriver.delay(CLICK_FOCUS_SETTLE_DELAY);
1523
1512
  const point = this.resolveUntargetedScrollPoint(screenSize);
1524
- await this.moveGlobalPointer(point, 'Mouse did not reach the scroll viewport', {
1525
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1526
- });
1513
+ await this.moveGlobalPointer(point, 'Mouse did not reach the scroll viewport');
1514
+ await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1527
1515
  return screenSize;
1528
1516
  }
1529
1517
  async performScroll(param) {
@@ -1664,7 +1652,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1664
1652
  });
1665
1653
  const targetX = Math.round(target.x);
1666
1654
  const targetY = Math.round(target.y);
1667
- const holdDuration = resolveTapHoldDuration(opts?.duration);
1655
+ const holdDuration = Math.max(0, Math.round(opts?.duration ?? CLICK_HOLD_DURATION));
1668
1656
  debugComputerInput('tap start %o', {
1669
1657
  local: {
1670
1658
  x,
@@ -1683,9 +1671,8 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1683
1671
  x: targetX,
1684
1672
  y: targetY
1685
1673
  }, 'Mouse did not reach the tap target', {
1686
- smoothSteps: desktopPointerPolicy.tapMoveSteps,
1687
- smoothDelay: desktopPointerPolicy.tapMoveStepDelayMs,
1688
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1674
+ smoothSteps: SMOOTH_MOVE_STEPS_TAP,
1675
+ smoothDelay: SMOOTH_MOVE_DELAY_TAP
1689
1676
  });
1690
1677
  await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, current, holdDuration, 'primary');
1691
1678
  if (frontmostBefore && 'darwin' === process.platform) {
@@ -1701,9 +1688,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1701
1688
  const followUpCurrent = await this.moveGlobalPointer({
1702
1689
  x: targetX,
1703
1690
  y: targetY
1704
- }, 'Mouse did not reach the focus follow-up target', {
1705
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1706
- });
1691
+ }, 'Mouse did not reach the focus follow-up target');
1707
1692
  await pressMouseAtGlobalPoint(this.inputDriver, targetX, targetY, followUpCurrent, holdDuration, 'focus-follow-up');
1708
1693
  }
1709
1694
  }
@@ -1712,18 +1697,14 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1712
1697
  await this.moveDisplayPointer({
1713
1698
  x,
1714
1699
  y
1715
- }, 'Mouse did not reach the double-click target', {
1716
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1717
- });
1700
+ }, 'Mouse did not reach the double-click target');
1718
1701
  this.inputDriver.mouseClick('left', true);
1719
1702
  },
1720
1703
  rightClick: async ({ x, y })=>{
1721
1704
  await this.moveDisplayPointer({
1722
1705
  x,
1723
1706
  y
1724
- }, 'Mouse did not reach the right-click target', {
1725
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1726
- });
1707
+ }, 'Mouse did not reach the right-click target');
1727
1708
  this.inputDriver.mouseClick('right');
1728
1709
  },
1729
1710
  hover: async ({ x, y })=>{
@@ -1731,10 +1712,10 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1731
1712
  x,
1732
1713
  y
1733
1714
  }, 'Mouse did not reach the hover target', {
1734
- smoothSteps: desktopPointerPolicy.hoverMoveSteps,
1735
- smoothDelay: desktopPointerPolicy.hoverMoveStepDelayMs,
1736
- settleDelayMs: desktopPointerPolicy.uiSettleMs
1715
+ smoothSteps: SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1716
+ smoothDelay: SMOOTH_MOVE_DELAY_MOUSE_MOVE
1737
1717
  });
1718
+ await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1738
1719
  },
1739
1720
  dragAndDrop: async (from, to)=>{
1740
1721
  await this.performPointerDrag(from, to);
@@ -1749,25 +1730,23 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1749
1730
  const resolvedInputOptions = resolveTextInputOptions(opts, this.options);
1750
1731
  const element = opts?.target;
1751
1732
  if (element) {
1752
- await this.focusKeyboardTarget(element, desktopKeyboardPolicy.focusBeforeTypeMs);
1753
- if (opts?.focusOnly) return;
1733
+ await this.focusKeyboardTarget(element, INPUT_FOCUS_DELAY);
1754
1734
  if (opts?.replace !== false) {
1755
1735
  await this.selectAllAndDelete();
1756
- await this.inputDriver.delay(desktopKeyboardPolicy.afterClearMs);
1736
+ await this.inputDriver.delay(INPUT_CLEAR_DELAY);
1757
1737
  }
1758
1738
  }
1759
- if (opts?.focusOnly || !value) return;
1760
1739
  await this.smartTypeString(value, resolvedInputOptions);
1761
1740
  },
1762
1741
  keyboardPress: async (keyName, opts)=>{
1763
1742
  const target = opts?.target;
1764
- if (target) await this.focusKeyboardTarget(target, desktopKeyboardPolicy.focusBeforeShortcutMs);
1743
+ if (target) await this.focusKeyboardTarget(target, 50);
1765
1744
  await this.pressKeyboardShortcut(keyName);
1766
1745
  },
1767
1746
  clearInput: async (target)=>{
1768
- if (target) await this.focusKeyboardTarget(target, desktopKeyboardPolicy.focusBeforeClearMs);
1747
+ if (target) await this.focusKeyboardTarget(target, 100);
1769
1748
  await this.selectAllAndDelete();
1770
- await this.inputDriver.delay(desktopKeyboardPolicy.afterClearMs);
1749
+ await this.inputDriver.delay(50);
1771
1750
  }
1772
1751
  },
1773
1752
  scroll: {
@@ -2223,9 +2202,17 @@ function rdp_device_define_property(obj, key, value) {
2223
2202
  return obj;
2224
2203
  }
2225
2204
  const device_debug = getDebug('rdp:device');
2205
+ const device_SMOOTH_MOVE_STEPS_TAP = 8;
2206
+ const device_SMOOTH_MOVE_STEPS_MOUSE_MOVE = 10;
2226
2207
  const device_SMOOTH_MOVE_STEPS_DRAG = 12;
2208
+ const device_SMOOTH_MOVE_DELAY_TAP = 8;
2209
+ const device_SMOOTH_MOVE_DELAY_MOUSE_MOVE = 10;
2227
2210
  const device_SMOOTH_MOVE_DELAY_DRAG = 10;
2211
+ const device_MOUSE_MOVE_EFFECT_WAIT = 300;
2212
+ const device_CLICK_HOLD_DURATION = 50;
2228
2213
  const DRAG_HOLD_DURATION = 100;
2214
+ const device_INPUT_FOCUS_DELAY = 300;
2215
+ const device_INPUT_CLEAR_DELAY = 150;
2229
2216
  const device_SCROLL_STEP_DELAY = 100;
2230
2217
  const device_SCROLL_COMPLETE_DELAY = 500;
2231
2218
  const DEFAULT_SCROLL_DISTANCE = 480;
@@ -2311,6 +2298,12 @@ class RDPDevice {
2311
2298
  throwIfDestroyed() {
2312
2299
  if (this.destroyed) throw new Error('RDPDevice has been destroyed');
2313
2300
  }
2301
+ async moveToElement(element, options) {
2302
+ this.assertConnected();
2303
+ const targetX = Math.round(element.center[0]);
2304
+ const targetY = Math.round(element.center[1]);
2305
+ await this.movePointer(targetX, targetY, options);
2306
+ }
2314
2307
  async clearInput() {
2315
2308
  if (this.backend.clearInput) return void await this.backend.clearInput();
2316
2309
  await this.backend.keyPress('Control+A');
@@ -2364,8 +2357,8 @@ class RDPDevice {
2364
2357
  const boundedFrom = clampPointerPointToSize(from, screenSize);
2365
2358
  const boundedTo = clampPointerPointToSize(to, screenSize);
2366
2359
  await this.movePointer(Math.round(boundedFrom.x), Math.round(boundedFrom.y), {
2367
- steps: desktopPointerPolicy.tapMoveSteps,
2368
- stepDelayMs: desktopPointerPolicy.tapMoveStepDelayMs
2360
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2361
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2369
2362
  });
2370
2363
  await this.backend.mouseButton('left', 'down');
2371
2364
  try {
@@ -2401,40 +2394,34 @@ class RDPDevice {
2401
2394
  rdp_device_define_property(this, "uri", void 0);
2402
2395
  rdp_device_define_property(this, "inputPrimitives", {
2403
2396
  pointer: {
2404
- tap: async ({ x, y }, opts)=>{
2397
+ tap: async ({ x, y })=>{
2405
2398
  await this.movePointer(Math.round(x), Math.round(y), {
2406
- steps: desktopPointerPolicy.tapMoveSteps,
2407
- stepDelayMs: desktopPointerPolicy.tapMoveStepDelayMs,
2408
- settleDelayMs: desktopPointerPolicy.uiSettleMs
2399
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2400
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2409
2401
  });
2410
2402
  await this.backend.mouseButton('left', 'down');
2411
- try {
2412
- await sleep(resolveTapHoldDuration(opts?.duration));
2413
- } finally{
2414
- await this.backend.mouseButton('left', 'up');
2415
- }
2403
+ await sleep(device_CLICK_HOLD_DURATION);
2404
+ await this.backend.mouseButton('left', 'up');
2416
2405
  },
2417
2406
  doubleClick: async ({ x, y })=>{
2418
2407
  await this.movePointer(Math.round(x), Math.round(y), {
2419
- steps: desktopPointerPolicy.tapMoveSteps,
2420
- stepDelayMs: desktopPointerPolicy.tapMoveStepDelayMs,
2421
- settleDelayMs: desktopPointerPolicy.uiSettleMs
2408
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2409
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2422
2410
  });
2423
2411
  await this.backend.mouseButton('left', 'doubleClick');
2424
2412
  },
2425
2413
  rightClick: async ({ x, y })=>{
2426
2414
  await this.movePointer(Math.round(x), Math.round(y), {
2427
- steps: desktopPointerPolicy.tapMoveSteps,
2428
- stepDelayMs: desktopPointerPolicy.tapMoveStepDelayMs,
2429
- settleDelayMs: desktopPointerPolicy.uiSettleMs
2415
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2416
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2430
2417
  });
2431
2418
  await this.backend.mouseButton('right', 'click');
2432
2419
  },
2433
2420
  hover: async ({ x, y })=>{
2434
2421
  await this.movePointer(Math.round(x), Math.round(y), {
2435
- steps: desktopPointerPolicy.hoverMoveSteps,
2436
- stepDelayMs: desktopPointerPolicy.hoverMoveStepDelayMs,
2437
- settleDelayMs: desktopPointerPolicy.uiSettleMs
2422
+ steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
2423
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE,
2424
+ settleDelayMs: device_MOUSE_MOVE_EFFECT_WAIT
2438
2425
  });
2439
2426
  },
2440
2427
  dragAndDrop: async (from, to)=>{
@@ -2455,12 +2442,11 @@ class RDPDevice {
2455
2442
  x: target.center[0],
2456
2443
  y: target.center[1]
2457
2444
  });
2458
- await sleep(desktopKeyboardPolicy.focusBeforeTypeMs);
2459
- if (opts?.focusOnly) return;
2460
- if (opts?.replace !== false) {
2461
- await this.clearInput();
2462
- await sleep(desktopKeyboardPolicy.afterClearMs);
2463
- }
2445
+ await sleep(device_INPUT_FOCUS_DELAY);
2446
+ }
2447
+ if (opts?.replace !== false) {
2448
+ await this.clearInput();
2449
+ await sleep(device_INPUT_CLEAR_DELAY);
2464
2450
  }
2465
2451
  if (opts?.focusOnly || !value) return;
2466
2452
  await this.typeText(value, resolvedInputOptions);
@@ -2473,21 +2459,18 @@ class RDPDevice {
2473
2459
  x: element.center[0],
2474
2460
  y: element.center[1]
2475
2461
  });
2476
- await sleep(desktopKeyboardPolicy.focusBeforeClearMs);
2462
+ await sleep(device_INPUT_FOCUS_DELAY);
2477
2463
  }
2478
2464
  await this.clearInput();
2479
- await sleep(desktopKeyboardPolicy.afterClearMs);
2465
+ await sleep(device_INPUT_CLEAR_DELAY);
2480
2466
  },
2481
2467
  keyboardPress: async (keyName, opts)=>{
2482
2468
  this.assertConnected();
2483
2469
  const target = opts?.target;
2484
- if (target) {
2485
- await this.inputPrimitives.pointer.tap({
2486
- x: target.center[0],
2487
- y: target.center[1]
2488
- });
2489
- await sleep(desktopKeyboardPolicy.focusBeforeShortcutMs);
2490
- }
2470
+ if (target) await this.inputPrimitives.pointer.tap({
2471
+ x: target.center[0],
2472
+ y: target.center[1]
2473
+ });
2491
2474
  await this.backend.keyPress(keyName);
2492
2475
  }
2493
2476
  },
@@ -2495,27 +2478,17 @@ class RDPDevice {
2495
2478
  scroll: async (param)=>{
2496
2479
  this.assertConnected();
2497
2480
  const target = param.locate;
2498
- let scrollPoint;
2499
- if (target) scrollPoint = target.center;
2500
- else {
2501
- const size = await this.size();
2502
- scrollPoint = [
2503
- Math.round(size.width / 2),
2504
- Math.round(size.height / 2)
2505
- ];
2506
- }
2507
- await this.movePointer(Math.round(scrollPoint[0]), Math.round(scrollPoint[1]), {
2508
- steps: desktopPointerPolicy.hoverMoveSteps,
2509
- stepDelayMs: desktopPointerPolicy.hoverMoveStepDelayMs,
2510
- settleDelayMs: target ? desktopPointerPolicy.moveSettleMs : desktopPointerPolicy.uiSettleMs
2481
+ if (target) await this.moveToElement(target, {
2482
+ steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
2483
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE
2511
2484
  });
2512
2485
  if (param.scrollType && 'singleAction' !== param.scrollType) {
2513
2486
  const direction = this.edgeScrollDirection(param.scrollType);
2514
- for(let i = 0; i < device_EDGE_SCROLL_STEPS; i++)await this.performWheel(direction, DEFAULT_SCROLL_DISTANCE, scrollPoint[0], scrollPoint[1]);
2487
+ for(let i = 0; i < device_EDGE_SCROLL_STEPS; i++)await this.performWheel(direction, DEFAULT_SCROLL_DISTANCE, target?.center[0], target?.center[1]);
2515
2488
  await sleep(device_SCROLL_COMPLETE_DELAY);
2516
2489
  return;
2517
2490
  }
2518
- await this.performWheel(param.direction || 'down', param.distance || this.defaultScrollDistance(param.direction || 'down'), scrollPoint[0], scrollPoint[1]);
2491
+ await this.performWheel(param.direction || 'down', param.distance || this.defaultScrollDistance(param.direction || 'down'), target?.center[0], target?.center[1]);
2519
2492
  await sleep(device_SCROLL_COMPLETE_DELAY);
2520
2493
  }
2521
2494
  }
@@ -2792,7 +2765,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2792
2765
  }
2793
2766
  }
2794
2767
  function version() {
2795
- const currentVersion = "1.13.4-beta-20260928083351.0";
2768
+ const currentVersion = "1.14.0";
2796
2769
  console.log(`@midscene/computer v${currentVersion}`);
2797
2770
  return currentVersion;
2798
2771
  }