@midscene/computer 1.12.8 → 1.12.9-beta-20260917073745.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/cli.mjs CHANGED
@@ -386,6 +386,14 @@ function resolveShiftedKey(character, keyboardLayout) {
386
386
  if (/^[A-Z]$/.test(character)) return character.toLowerCase();
387
387
  return 'en-US' === keyboardLayout ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
388
388
  }
389
+ function clampPointerPointToSize(point, size) {
390
+ const maximumX = Math.max(0, Math.floor(size.width) - 1);
391
+ const maximumY = Math.max(0, Math.floor(size.height) - 1);
392
+ return {
393
+ x: Math.max(0, Math.min(point.x, maximumX)),
394
+ y: Math.max(0, Math.min(point.y, maximumY))
395
+ };
396
+ }
389
397
  const POWERSHELL_TIMEOUT_MS = 15000;
390
398
  const POWERSHELL_MAX_BUFFER = 67108864;
391
399
  const WINDOWS_PHYSICAL_PIXEL_POWERSHELL_PREAMBLE = `
@@ -1120,6 +1128,20 @@ class ComputerDevice {
1120
1128
  moveDisplayPointer(point, context, smooth) {
1121
1129
  return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
1122
1130
  }
1131
+ async performPointerDrag(from, to, duration) {
1132
+ const screenSize = await this.size();
1133
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
1134
+ const boundedTo = clampPointerPointToSize(to, screenSize);
1135
+ await this.moveDisplayPointer(boundedFrom, 'Mouse did not reach the drag start target');
1136
+ await this.inputDriver.withMouseButton('left', async ()=>{
1137
+ await this.inputDriver.delay(100);
1138
+ await this.moveDisplayPointer(boundedTo, 'Mouse did not reach the drag end target', {
1139
+ smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1140
+ smoothDelay: void 0 === duration ? SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / SMOOTH_MOVE_STEPS_DRAG))
1141
+ });
1142
+ await this.inputDriver.delay(100);
1143
+ });
1144
+ }
1123
1145
  async focusKeyboardTarget(element, delayMs) {
1124
1146
  const [x, y] = element.center;
1125
1147
  if ('darwin' === process.platform) await this.inputPrimitives.pointer.tap({
@@ -1212,7 +1234,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1212
1234
  }
1213
1235
  async healthCheck(displays) {
1214
1236
  console.log('[HealthCheck] Starting health check...');
1215
- console.log("[HealthCheck] @midscene/computer v1.12.8");
1237
+ console.log("[HealthCheck] @midscene/computer v1.12.9-beta-20260917073745.0");
1216
1238
  console.log('[HealthCheck] Taking screenshot...');
1217
1239
  const screenshotTimeout = 15000;
1218
1240
  let timeoutId;
@@ -1560,7 +1582,9 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1560
1582
  }
1561
1583
  actionSpace() {
1562
1584
  const defaultActions = [
1563
- ...defineActionsFromInputPrimitives(this.inputPrimitives)
1585
+ ...defineActionsFromInputPrimitives(this.inputPrimitives, {
1586
+ size: ()=>this.size()
1587
+ })
1564
1588
  ];
1565
1589
  const platformActions = Object.values(createPlatformActions());
1566
1590
  const customActions = this.options?.customActions || [];
@@ -1691,15 +1715,11 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1691
1715
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1692
1716
  },
1693
1717
  dragAndDrop: async (from, to)=>{
1694
- await this.moveDisplayPointer(from, 'Mouse did not reach the drag start target');
1695
- await this.inputDriver.withMouseButton('left', async ()=>{
1696
- await this.inputDriver.delay(100);
1697
- await this.moveDisplayPointer(to, 'Mouse did not reach the drag end target', {
1698
- smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1699
- smoothDelay: SMOOTH_MOVE_DELAY_DRAG
1700
- });
1701
- await this.inputDriver.delay(100);
1702
- });
1718
+ await this.performPointerDrag(from, to);
1719
+ },
1720
+ swipe: async (from, to, opts)=>{
1721
+ const repeatCount = opts?.repeat ?? 1;
1722
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
1703
1723
  }
1704
1724
  },
1705
1725
  keyboard: {
@@ -2200,7 +2220,9 @@ class RDPDevice {
2200
2220
  }
2201
2221
  actionSpace() {
2202
2222
  const defaultActions = [
2203
- ...defineActionsFromInputPrimitives(this.inputPrimitives),
2223
+ ...defineActionsFromInputPrimitives(this.inputPrimitives, {
2224
+ size: ()=>this.size()
2225
+ }),
2204
2226
  defineAction({
2205
2227
  name: 'ListDisplays',
2206
2228
  description: 'List all available displays/monitors',
@@ -2284,6 +2306,26 @@ class RDPDevice {
2284
2306
  }
2285
2307
  if (options?.settleDelayMs) await sleep(options.settleDelayMs);
2286
2308
  }
2309
+ async performPointerDrag(from, to, duration) {
2310
+ const screenSize = await this.size();
2311
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
2312
+ const boundedTo = clampPointerPointToSize(to, screenSize);
2313
+ await this.movePointer(Math.round(boundedFrom.x), Math.round(boundedFrom.y), {
2314
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2315
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2316
+ });
2317
+ await this.backend.mouseButton('left', 'down');
2318
+ try {
2319
+ await sleep(DRAG_HOLD_DURATION);
2320
+ await this.movePointer(Math.round(boundedTo.x), Math.round(boundedTo.y), {
2321
+ steps: device_SMOOTH_MOVE_STEPS_DRAG,
2322
+ stepDelayMs: void 0 === duration ? device_SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / device_SMOOTH_MOVE_STEPS_DRAG))
2323
+ });
2324
+ await sleep(DRAG_HOLD_DURATION);
2325
+ } finally{
2326
+ await this.backend.mouseButton('left', 'up');
2327
+ }
2328
+ }
2287
2329
  async performWheel(direction, amount, x, y) {
2288
2330
  let remaining = Math.abs(amount);
2289
2331
  if (0 === remaining) remaining = DEFAULT_SCROLL_STEP_AMOUNT;
@@ -2337,18 +2379,11 @@ class RDPDevice {
2337
2379
  });
2338
2380
  },
2339
2381
  dragAndDrop: async (from, to)=>{
2340
- await this.movePointer(Math.round(from.x), Math.round(from.y), {
2341
- steps: device_SMOOTH_MOVE_STEPS_TAP,
2342
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2343
- });
2344
- await this.backend.mouseButton('left', 'down');
2345
- await sleep(DRAG_HOLD_DURATION);
2346
- await this.movePointer(Math.round(to.x), Math.round(to.y), {
2347
- steps: device_SMOOTH_MOVE_STEPS_DRAG,
2348
- stepDelayMs: device_SMOOTH_MOVE_DELAY_DRAG
2349
- });
2350
- await sleep(DRAG_HOLD_DURATION);
2351
- await this.backend.mouseButton('left', 'up');
2382
+ await this.performPointerDrag(from, to);
2383
+ },
2384
+ swipe: async (from, to, opts)=>{
2385
+ const repeatCount = opts?.repeat ?? 1;
2386
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
2352
2387
  }
2353
2388
  },
2354
2389
  keyboard: {
@@ -2688,7 +2723,7 @@ const tools = new ComputerMidsceneTools({
2688
2723
  });
2689
2724
  runToolsCLI(tools, 'midscene-computer', {
2690
2725
  stripPrefix: 'computer_',
2691
- version: "1.12.8",
2726
+ version: "1.12.9-beta-20260917073745.0",
2692
2727
  extraCommands: createReportCliCommands()
2693
2728
  }).catch((e)=>{
2694
2729
  process.exit(reportCLIError(e));
package/dist/es/index.mjs CHANGED
@@ -386,6 +386,14 @@ function resolveShiftedKey(character, keyboardLayout) {
386
386
  if (/^[A-Z]$/.test(character)) return character.toLowerCase();
387
387
  return 'en-US' === keyboardLayout ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
388
388
  }
389
+ function clampPointerPointToSize(point, size) {
390
+ const maximumX = Math.max(0, Math.floor(size.width) - 1);
391
+ const maximumY = Math.max(0, Math.floor(size.height) - 1);
392
+ return {
393
+ x: Math.max(0, Math.min(point.x, maximumX)),
394
+ y: Math.max(0, Math.min(point.y, maximumY))
395
+ };
396
+ }
389
397
  const POWERSHELL_TIMEOUT_MS = 15000;
390
398
  const POWERSHELL_MAX_BUFFER = 67108864;
391
399
  const WINDOWS_PHYSICAL_PIXEL_POWERSHELL_PREAMBLE = `
@@ -1120,6 +1128,20 @@ class ComputerDevice {
1120
1128
  moveDisplayPointer(point, context, smooth) {
1121
1129
  return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
1122
1130
  }
1131
+ async performPointerDrag(from, to, duration) {
1132
+ const screenSize = await this.size();
1133
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
1134
+ const boundedTo = clampPointerPointToSize(to, screenSize);
1135
+ await this.moveDisplayPointer(boundedFrom, 'Mouse did not reach the drag start target');
1136
+ await this.inputDriver.withMouseButton('left', async ()=>{
1137
+ await this.inputDriver.delay(100);
1138
+ await this.moveDisplayPointer(boundedTo, 'Mouse did not reach the drag end target', {
1139
+ smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1140
+ smoothDelay: void 0 === duration ? SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / SMOOTH_MOVE_STEPS_DRAG))
1141
+ });
1142
+ await this.inputDriver.delay(100);
1143
+ });
1144
+ }
1123
1145
  async focusKeyboardTarget(element, delayMs) {
1124
1146
  const [x, y] = element.center;
1125
1147
  if ('darwin' === process.platform) await this.inputPrimitives.pointer.tap({
@@ -1212,7 +1234,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1212
1234
  }
1213
1235
  async healthCheck(displays) {
1214
1236
  console.log('[HealthCheck] Starting health check...');
1215
- console.log("[HealthCheck] @midscene/computer v1.12.8");
1237
+ console.log("[HealthCheck] @midscene/computer v1.12.9-beta-20260917073745.0");
1216
1238
  console.log('[HealthCheck] Taking screenshot...');
1217
1239
  const screenshotTimeout = 15000;
1218
1240
  let timeoutId;
@@ -1560,7 +1582,9 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1560
1582
  }
1561
1583
  actionSpace() {
1562
1584
  const defaultActions = [
1563
- ...defineActionsFromInputPrimitives(this.inputPrimitives)
1585
+ ...defineActionsFromInputPrimitives(this.inputPrimitives, {
1586
+ size: ()=>this.size()
1587
+ })
1564
1588
  ];
1565
1589
  const platformActions = Object.values(createPlatformActions());
1566
1590
  const customActions = this.options?.customActions || [];
@@ -1691,15 +1715,11 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1691
1715
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1692
1716
  },
1693
1717
  dragAndDrop: async (from, to)=>{
1694
- await this.moveDisplayPointer(from, 'Mouse did not reach the drag start target');
1695
- await this.inputDriver.withMouseButton('left', async ()=>{
1696
- await this.inputDriver.delay(100);
1697
- await this.moveDisplayPointer(to, 'Mouse did not reach the drag end target', {
1698
- smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1699
- smoothDelay: SMOOTH_MOVE_DELAY_DRAG
1700
- });
1701
- await this.inputDriver.delay(100);
1702
- });
1718
+ await this.performPointerDrag(from, to);
1719
+ },
1720
+ swipe: async (from, to, opts)=>{
1721
+ const repeatCount = opts?.repeat ?? 1;
1722
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
1703
1723
  }
1704
1724
  },
1705
1725
  keyboard: {
@@ -2243,7 +2263,9 @@ class RDPDevice {
2243
2263
  }
2244
2264
  actionSpace() {
2245
2265
  const defaultActions = [
2246
- ...defineActionsFromInputPrimitives(this.inputPrimitives),
2266
+ ...defineActionsFromInputPrimitives(this.inputPrimitives, {
2267
+ size: ()=>this.size()
2268
+ }),
2247
2269
  defineAction({
2248
2270
  name: 'ListDisplays',
2249
2271
  description: 'List all available displays/monitors',
@@ -2327,6 +2349,26 @@ class RDPDevice {
2327
2349
  }
2328
2350
  if (options?.settleDelayMs) await sleep(options.settleDelayMs);
2329
2351
  }
2352
+ async performPointerDrag(from, to, duration) {
2353
+ const screenSize = await this.size();
2354
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
2355
+ const boundedTo = clampPointerPointToSize(to, screenSize);
2356
+ await this.movePointer(Math.round(boundedFrom.x), Math.round(boundedFrom.y), {
2357
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2358
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2359
+ });
2360
+ await this.backend.mouseButton('left', 'down');
2361
+ try {
2362
+ await sleep(DRAG_HOLD_DURATION);
2363
+ await this.movePointer(Math.round(boundedTo.x), Math.round(boundedTo.y), {
2364
+ steps: device_SMOOTH_MOVE_STEPS_DRAG,
2365
+ stepDelayMs: void 0 === duration ? device_SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / device_SMOOTH_MOVE_STEPS_DRAG))
2366
+ });
2367
+ await sleep(DRAG_HOLD_DURATION);
2368
+ } finally{
2369
+ await this.backend.mouseButton('left', 'up');
2370
+ }
2371
+ }
2330
2372
  async performWheel(direction, amount, x, y) {
2331
2373
  let remaining = Math.abs(amount);
2332
2374
  if (0 === remaining) remaining = DEFAULT_SCROLL_STEP_AMOUNT;
@@ -2380,18 +2422,11 @@ class RDPDevice {
2380
2422
  });
2381
2423
  },
2382
2424
  dragAndDrop: async (from, to)=>{
2383
- await this.movePointer(Math.round(from.x), Math.round(from.y), {
2384
- steps: device_SMOOTH_MOVE_STEPS_TAP,
2385
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2386
- });
2387
- await this.backend.mouseButton('left', 'down');
2388
- await sleep(DRAG_HOLD_DURATION);
2389
- await this.movePointer(Math.round(to.x), Math.round(to.y), {
2390
- steps: device_SMOOTH_MOVE_STEPS_DRAG,
2391
- stepDelayMs: device_SMOOTH_MOVE_DELAY_DRAG
2392
- });
2393
- await sleep(DRAG_HOLD_DURATION);
2394
- await this.backend.mouseButton('left', 'up');
2425
+ await this.performPointerDrag(from, to);
2426
+ },
2427
+ swipe: async (from, to, opts)=>{
2428
+ const repeatCount = opts?.repeat ?? 1;
2429
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
2395
2430
  }
2396
2431
  },
2397
2432
  keyboard: {
@@ -2727,7 +2762,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2727
2762
  }
2728
2763
  }
2729
2764
  function version() {
2730
- const currentVersion = "1.12.8";
2765
+ const currentVersion = "1.12.9-beta-20260917073745.0";
2731
2766
  console.log(`@midscene/computer v${currentVersion}`);
2732
2767
  return currentVersion;
2733
2768
  }
package/dist/lib/cli.js CHANGED
@@ -411,6 +411,14 @@ function resolveShiftedKey(character, keyboardLayout) {
411
411
  if (/^[A-Z]$/.test(character)) return character.toLowerCase();
412
412
  return 'en-US' === keyboardLayout ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
413
413
  }
414
+ function clampPointerPointToSize(point, size) {
415
+ const maximumX = Math.max(0, Math.floor(size.width) - 1);
416
+ const maximumY = Math.max(0, Math.floor(size.height) - 1);
417
+ return {
418
+ x: Math.max(0, Math.min(point.x, maximumX)),
419
+ y: Math.max(0, Math.min(point.y, maximumY))
420
+ };
421
+ }
414
422
  const POWERSHELL_TIMEOUT_MS = 15000;
415
423
  const POWERSHELL_MAX_BUFFER = 67108864;
416
424
  const WINDOWS_PHYSICAL_PIXEL_POWERSHELL_PREAMBLE = `
@@ -1146,6 +1154,20 @@ class ComputerDevice {
1146
1154
  moveDisplayPointer(point, context, smooth) {
1147
1155
  return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
1148
1156
  }
1157
+ async performPointerDrag(from, to, duration) {
1158
+ const screenSize = await this.size();
1159
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
1160
+ const boundedTo = clampPointerPointToSize(to, screenSize);
1161
+ await this.moveDisplayPointer(boundedFrom, 'Mouse did not reach the drag start target');
1162
+ await this.inputDriver.withMouseButton('left', async ()=>{
1163
+ await this.inputDriver.delay(100);
1164
+ await this.moveDisplayPointer(boundedTo, 'Mouse did not reach the drag end target', {
1165
+ smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1166
+ smoothDelay: void 0 === duration ? SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / SMOOTH_MOVE_STEPS_DRAG))
1167
+ });
1168
+ await this.inputDriver.delay(100);
1169
+ });
1170
+ }
1149
1171
  async focusKeyboardTarget(element, delayMs) {
1150
1172
  const [x, y] = element.center;
1151
1173
  if ('darwin' === process.platform) await this.inputPrimitives.pointer.tap({
@@ -1238,7 +1260,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1238
1260
  }
1239
1261
  async healthCheck(displays) {
1240
1262
  console.log('[HealthCheck] Starting health check...');
1241
- console.log("[HealthCheck] @midscene/computer v1.12.8");
1263
+ console.log("[HealthCheck] @midscene/computer v1.12.9-beta-20260917073745.0");
1242
1264
  console.log('[HealthCheck] Taking screenshot...');
1243
1265
  const screenshotTimeout = 15000;
1244
1266
  let timeoutId;
@@ -1586,7 +1608,9 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1586
1608
  }
1587
1609
  actionSpace() {
1588
1610
  const defaultActions = [
1589
- ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives)
1611
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives, {
1612
+ size: ()=>this.size()
1613
+ })
1590
1614
  ];
1591
1615
  const platformActions = Object.values(createPlatformActions());
1592
1616
  const customActions = this.options?.customActions || [];
@@ -1717,15 +1741,11 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1717
1741
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1718
1742
  },
1719
1743
  dragAndDrop: async (from, to)=>{
1720
- await this.moveDisplayPointer(from, 'Mouse did not reach the drag start target');
1721
- await this.inputDriver.withMouseButton('left', async ()=>{
1722
- await this.inputDriver.delay(100);
1723
- await this.moveDisplayPointer(to, 'Mouse did not reach the drag end target', {
1724
- smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1725
- smoothDelay: SMOOTH_MOVE_DELAY_DRAG
1726
- });
1727
- await this.inputDriver.delay(100);
1728
- });
1744
+ await this.performPointerDrag(from, to);
1745
+ },
1746
+ swipe: async (from, to, opts)=>{
1747
+ const repeatCount = opts?.repeat ?? 1;
1748
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
1729
1749
  }
1730
1750
  },
1731
1751
  keyboard: {
@@ -2227,7 +2247,9 @@ class RDPDevice {
2227
2247
  }
2228
2248
  actionSpace() {
2229
2249
  const defaultActions = [
2230
- ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives),
2250
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives, {
2251
+ size: ()=>this.size()
2252
+ }),
2231
2253
  (0, device_namespaceObject.defineAction)({
2232
2254
  name: 'ListDisplays',
2233
2255
  description: 'List all available displays/monitors',
@@ -2311,6 +2333,26 @@ class RDPDevice {
2311
2333
  }
2312
2334
  if (options?.settleDelayMs) await (0, utils_namespaceObject.sleep)(options.settleDelayMs);
2313
2335
  }
2336
+ async performPointerDrag(from, to, duration) {
2337
+ const screenSize = await this.size();
2338
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
2339
+ const boundedTo = clampPointerPointToSize(to, screenSize);
2340
+ await this.movePointer(Math.round(boundedFrom.x), Math.round(boundedFrom.y), {
2341
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2342
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2343
+ });
2344
+ await this.backend.mouseButton('left', 'down');
2345
+ try {
2346
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2347
+ await this.movePointer(Math.round(boundedTo.x), Math.round(boundedTo.y), {
2348
+ steps: device_SMOOTH_MOVE_STEPS_DRAG,
2349
+ stepDelayMs: void 0 === duration ? device_SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / device_SMOOTH_MOVE_STEPS_DRAG))
2350
+ });
2351
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2352
+ } finally{
2353
+ await this.backend.mouseButton('left', 'up');
2354
+ }
2355
+ }
2314
2356
  async performWheel(direction, amount, x, y) {
2315
2357
  let remaining = Math.abs(amount);
2316
2358
  if (0 === remaining) remaining = DEFAULT_SCROLL_STEP_AMOUNT;
@@ -2364,18 +2406,11 @@ class RDPDevice {
2364
2406
  });
2365
2407
  },
2366
2408
  dragAndDrop: async (from, to)=>{
2367
- await this.movePointer(Math.round(from.x), Math.round(from.y), {
2368
- steps: device_SMOOTH_MOVE_STEPS_TAP,
2369
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2370
- });
2371
- await this.backend.mouseButton('left', 'down');
2372
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2373
- await this.movePointer(Math.round(to.x), Math.round(to.y), {
2374
- steps: device_SMOOTH_MOVE_STEPS_DRAG,
2375
- stepDelayMs: device_SMOOTH_MOVE_DELAY_DRAG
2376
- });
2377
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2378
- await this.backend.mouseButton('left', 'up');
2409
+ await this.performPointerDrag(from, to);
2410
+ },
2411
+ swipe: async (from, to, opts)=>{
2412
+ const repeatCount = opts?.repeat ?? 1;
2413
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
2379
2414
  }
2380
2415
  },
2381
2416
  keyboard: {
@@ -2715,7 +2750,7 @@ const tools = new ComputerMidsceneTools({
2715
2750
  });
2716
2751
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
2717
2752
  stripPrefix: 'computer_',
2718
- version: "1.12.8",
2753
+ version: "1.12.9-beta-20260917073745.0",
2719
2754
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
2720
2755
  }).catch((e)=>{
2721
2756
  process.exit((0, cli_namespaceObject.reportCLIError)(e));
package/dist/lib/index.js CHANGED
@@ -437,6 +437,14 @@ function resolveShiftedKey(character, keyboardLayout) {
437
437
  if (/^[A-Z]$/.test(character)) return character.toLowerCase();
438
438
  return 'en-US' === keyboardLayout ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
439
439
  }
440
+ function clampPointerPointToSize(point, size) {
441
+ const maximumX = Math.max(0, Math.floor(size.width) - 1);
442
+ const maximumY = Math.max(0, Math.floor(size.height) - 1);
443
+ return {
444
+ x: Math.max(0, Math.min(point.x, maximumX)),
445
+ y: Math.max(0, Math.min(point.y, maximumY))
446
+ };
447
+ }
440
448
  const POWERSHELL_TIMEOUT_MS = 15000;
441
449
  const POWERSHELL_MAX_BUFFER = 67108864;
442
450
  const WINDOWS_PHYSICAL_PIXEL_POWERSHELL_PREAMBLE = `
@@ -1172,6 +1180,20 @@ class ComputerDevice {
1172
1180
  moveDisplayPointer(point, context, smooth) {
1173
1181
  return this.moveGlobalPointer(this.toGlobalPoint(point), context, smooth);
1174
1182
  }
1183
+ async performPointerDrag(from, to, duration) {
1184
+ const screenSize = await this.size();
1185
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
1186
+ const boundedTo = clampPointerPointToSize(to, screenSize);
1187
+ await this.moveDisplayPointer(boundedFrom, 'Mouse did not reach the drag start target');
1188
+ await this.inputDriver.withMouseButton('left', async ()=>{
1189
+ await this.inputDriver.delay(100);
1190
+ await this.moveDisplayPointer(boundedTo, 'Mouse did not reach the drag end target', {
1191
+ smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1192
+ smoothDelay: void 0 === duration ? SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / SMOOTH_MOVE_STEPS_DRAG))
1193
+ });
1194
+ await this.inputDriver.delay(100);
1195
+ });
1196
+ }
1175
1197
  async focusKeyboardTarget(element, delayMs) {
1176
1198
  const [x, y] = element.center;
1177
1199
  if ('darwin' === process.platform) await this.inputPrimitives.pointer.tap({
@@ -1264,7 +1286,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1264
1286
  }
1265
1287
  async healthCheck(displays) {
1266
1288
  console.log('[HealthCheck] Starting health check...');
1267
- console.log("[HealthCheck] @midscene/computer v1.12.8");
1289
+ console.log("[HealthCheck] @midscene/computer v1.12.9-beta-20260917073745.0");
1268
1290
  console.log('[HealthCheck] Taking screenshot...');
1269
1291
  const screenshotTimeout = 15000;
1270
1292
  let timeoutId;
@@ -1612,7 +1634,9 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1612
1634
  }
1613
1635
  actionSpace() {
1614
1636
  const defaultActions = [
1615
- ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives)
1637
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives, {
1638
+ size: ()=>this.size()
1639
+ })
1616
1640
  ];
1617
1641
  const platformActions = Object.values(createPlatformActions());
1618
1642
  const customActions = this.options?.customActions || [];
@@ -1743,15 +1767,11 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1743
1767
  await this.inputDriver.delay(MOUSE_MOVE_EFFECT_WAIT);
1744
1768
  },
1745
1769
  dragAndDrop: async (from, to)=>{
1746
- await this.moveDisplayPointer(from, 'Mouse did not reach the drag start target');
1747
- await this.inputDriver.withMouseButton('left', async ()=>{
1748
- await this.inputDriver.delay(100);
1749
- await this.moveDisplayPointer(to, 'Mouse did not reach the drag end target', {
1750
- smoothSteps: SMOOTH_MOVE_STEPS_DRAG,
1751
- smoothDelay: SMOOTH_MOVE_DELAY_DRAG
1752
- });
1753
- await this.inputDriver.delay(100);
1754
- });
1770
+ await this.performPointerDrag(from, to);
1771
+ },
1772
+ swipe: async (from, to, opts)=>{
1773
+ const repeatCount = opts?.repeat ?? 1;
1774
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
1755
1775
  }
1756
1776
  },
1757
1777
  keyboard: {
@@ -2297,7 +2317,9 @@ class RDPDevice {
2297
2317
  }
2298
2318
  actionSpace() {
2299
2319
  const defaultActions = [
2300
- ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives),
2320
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives, {
2321
+ size: ()=>this.size()
2322
+ }),
2301
2323
  (0, device_namespaceObject.defineAction)({
2302
2324
  name: 'ListDisplays',
2303
2325
  description: 'List all available displays/monitors',
@@ -2381,6 +2403,26 @@ class RDPDevice {
2381
2403
  }
2382
2404
  if (options?.settleDelayMs) await (0, utils_namespaceObject.sleep)(options.settleDelayMs);
2383
2405
  }
2406
+ async performPointerDrag(from, to, duration) {
2407
+ const screenSize = await this.size();
2408
+ const boundedFrom = clampPointerPointToSize(from, screenSize);
2409
+ const boundedTo = clampPointerPointToSize(to, screenSize);
2410
+ await this.movePointer(Math.round(boundedFrom.x), Math.round(boundedFrom.y), {
2411
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
2412
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2413
+ });
2414
+ await this.backend.mouseButton('left', 'down');
2415
+ try {
2416
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2417
+ await this.movePointer(Math.round(boundedTo.x), Math.round(boundedTo.y), {
2418
+ steps: device_SMOOTH_MOVE_STEPS_DRAG,
2419
+ stepDelayMs: void 0 === duration ? device_SMOOTH_MOVE_DELAY_DRAG : Math.max(0, Math.round(duration / device_SMOOTH_MOVE_STEPS_DRAG))
2420
+ });
2421
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2422
+ } finally{
2423
+ await this.backend.mouseButton('left', 'up');
2424
+ }
2425
+ }
2384
2426
  async performWheel(direction, amount, x, y) {
2385
2427
  let remaining = Math.abs(amount);
2386
2428
  if (0 === remaining) remaining = DEFAULT_SCROLL_STEP_AMOUNT;
@@ -2434,18 +2476,11 @@ class RDPDevice {
2434
2476
  });
2435
2477
  },
2436
2478
  dragAndDrop: async (from, to)=>{
2437
- await this.movePointer(Math.round(from.x), Math.round(from.y), {
2438
- steps: device_SMOOTH_MOVE_STEPS_TAP,
2439
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
2440
- });
2441
- await this.backend.mouseButton('left', 'down');
2442
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2443
- await this.movePointer(Math.round(to.x), Math.round(to.y), {
2444
- steps: device_SMOOTH_MOVE_STEPS_DRAG,
2445
- stepDelayMs: device_SMOOTH_MOVE_DELAY_DRAG
2446
- });
2447
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
2448
- await this.backend.mouseButton('left', 'up');
2479
+ await this.performPointerDrag(from, to);
2480
+ },
2481
+ swipe: async (from, to, opts)=>{
2482
+ const repeatCount = opts?.repeat ?? 1;
2483
+ for(let index = 0; index < repeatCount; index++)await this.performPointerDrag(from, to, opts?.duration);
2449
2484
  }
2450
2485
  },
2451
2486
  keyboard: {
@@ -2785,7 +2820,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
2785
2820
  }
2786
2821
  const env_namespaceObject = require("@midscene/shared/env");
2787
2822
  function version() {
2788
- const currentVersion = "1.12.8";
2823
+ const currentVersion = "1.12.9-beta-20260917073745.0";
2789
2824
  console.log(`@midscene/computer v${currentVersion}`);
2790
2825
  return currentVersion;
2791
2826
  }
@@ -89,6 +89,7 @@ export declare class ComputerDevice implements AbstractInterface {
89
89
  constructor(options?: ComputerDeviceOpt);
90
90
  private moveGlobalPointer;
91
91
  private moveDisplayPointer;
92
+ private performPointerDrag;
92
93
  private focusKeyboardTarget;
93
94
  describe(): string;
94
95
  /**
@@ -388,6 +389,7 @@ export declare class RDPDevice implements AbstractInterface {
388
389
  private edgeScrollDirection;
389
390
  private defaultScrollDistance;
390
391
  private movePointer;
392
+ private performPointerDrag;
391
393
  private performWheel;
392
394
  }
393
395
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/computer",
3
- "version": "1.12.8",
3
+ "version": "1.12.9-beta-20260917073745.0",
4
4
  "description": "Midscene.js Computer Desktop Automation",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -33,8 +33,8 @@
33
33
  "@computer-use/libnut": "^4.2.0",
34
34
  "clipboardy": "^4.0.0",
35
35
  "screenshot-desktop": "^1.15.3",
36
- "@midscene/core": "1.12.8",
37
- "@midscene/shared": "1.12.8"
36
+ "@midscene/core": "1.12.9-beta-20260917073745.0",
37
+ "@midscene/shared": "1.12.9-beta-20260917073745.0"
38
38
  },
39
39
  "optionalDependencies": {
40
40
  "node-mac-permissions": "2.5.0"