@midscene/computer 1.8.1-beta-20260513084557.0 → 1.8.1

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
@@ -118,15 +118,6 @@ function _define_property(obj, key, value) {
118
118
  else obj[key] = value;
119
119
  return obj;
120
120
  }
121
- const computerInputParamSchema = core_namespaceObject.z.object({
122
- value: core_namespaceObject.z.string().describe('The text to input'),
123
- mode: core_namespaceObject.z["enum"]([
124
- 'replace',
125
- 'clear',
126
- 'append'
127
- ]).default('replace').optional().describe('Input mode: replace, clear, or append'),
128
- locate: (0, core_namespaceObject.getMidsceneLocationSchema)().describe('The input field to be filled').optional()
129
- });
130
121
  const SMOOTH_MOVE_STEPS_TAP = 8;
131
122
  const SMOOTH_MOVE_STEPS_MOUSE_MOVE = 10;
132
123
  const SMOOTH_MOVE_DELAY_TAP = 8;
@@ -437,7 +428,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
437
428
  }
438
429
  async healthCheck() {
439
430
  console.log('[HealthCheck] Starting health check...');
440
- console.log("[HealthCheck] @midscene/computer v1.8.1-beta-20260513084557.0");
431
+ console.log("[HealthCheck] @midscene/computer v1.8.1");
441
432
  console.log('[HealthCheck] Taking screenshot...');
442
433
  const screenshotTimeout = 15000;
443
434
  let timeoutId;
@@ -503,21 +494,38 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
503
494
  debugDevice('Taking screenshot', {
504
495
  displayId: this.displayId
505
496
  });
506
- try {
507
- const options = {
508
- format: 'png'
509
- };
510
- if (void 0 !== this.displayId) if ('darwin' === process.platform) {
511
- const screenIndex = Number(this.displayId);
512
- if (!Number.isNaN(screenIndex)) options.screen = screenIndex;
513
- } else options.screen = this.displayId;
514
- debugDevice('Screenshot options', options);
497
+ const options = {
498
+ format: 'png'
499
+ };
500
+ if (void 0 !== this.displayId) if ('darwin' === process.platform) {
501
+ const screenIndex = Number(this.displayId);
502
+ if (!Number.isNaN(screenIndex)) options.screen = screenIndex;
503
+ } else options.screen = this.displayId;
504
+ debugDevice('Screenshot options', options);
505
+ const MAX_ATTEMPTS = 3;
506
+ const RETRY_DELAY_MS = 300;
507
+ let lastRawMessage = '';
508
+ for(let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++)try {
515
509
  const buffer = await external_screenshot_desktop_default()(options);
510
+ if (attempt > 1) debugDevice(`Screenshot succeeded on attempt ${attempt}`);
516
511
  return (0, img_namespaceObject.createImgBase64ByFormat)('png', buffer.toString('base64'));
517
512
  } catch (error) {
518
- debugDevice(`Screenshot failed: ${error}`);
519
- throw new Error(`Failed to take screenshot: ${error}`);
513
+ lastRawMessage = error instanceof Error ? error.message : String(error);
514
+ const isMacTransient = 'darwin' === process.platform && /could not create image from display/i.test(lastRawMessage);
515
+ const willRetry = isMacTransient && attempt < MAX_ATTEMPTS;
516
+ debugDevice(`Screenshot attempt ${attempt} failed: ${lastRawMessage}${willRetry ? ' — retrying' : ''}`);
517
+ if (!willRetry) break;
518
+ await (0, utils_namespaceObject.sleep)(RETRY_DELAY_MS);
520
519
  }
520
+ if ('darwin' === process.platform && /could not create image from display/i.test(lastRawMessage)) throw new Error(`Failed to take screenshot on macOS: the host process is missing Screen Recording permission, or the target display is locked/sleeping.
521
+
522
+ Please follow these steps:
523
+ 1. Open System Settings > Privacy & Security > Screen Recording
524
+ 2. Enable the application running this script (e.g., Terminal, iTerm2, VS Code, WebStorm, or Midscene Studio)
525
+ 3. Fully quit and relaunch that application after granting permission — macOS only re-reads this permission on process launch.
526
+
527
+ Original error: ${lastRawMessage}`);
528
+ throw new Error(`Failed to take screenshot: ${lastRawMessage}`);
521
529
  }
522
530
  async size() {
523
531
  external_node_assert_default()(libnut, 'libnut not initialized');
@@ -563,228 +571,111 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
563
571
  external_node_assert_default()(libnut, 'libnut not initialized');
564
572
  await this.typeViaClipboard(text);
565
573
  }
574
+ async selectAllAndDelete() {
575
+ external_node_assert_default()(libnut, 'libnut not initialized');
576
+ if (this.useAppleScript) {
577
+ sendKeyViaAppleScript('a', [
578
+ 'command'
579
+ ]);
580
+ await (0, utils_namespaceObject.sleep)(50);
581
+ sendKeyViaAppleScript('backspace', []);
582
+ return;
583
+ }
584
+ const modifier = 'darwin' === process.platform ? 'command' : 'control';
585
+ libnut.keyTap('a', [
586
+ modifier
587
+ ]);
588
+ await (0, utils_namespaceObject.sleep)(50);
589
+ libnut.keyTap('backspace');
590
+ }
591
+ async pressKeyboardShortcut(keyName) {
592
+ external_node_assert_default()(libnut, 'libnut not initialized');
593
+ const keys = keyName.split('+');
594
+ const modifiers = keys.slice(0, -1).map(normalizeKeyName);
595
+ const key = normalizePrimaryKey(keys[keys.length - 1]);
596
+ debugDevice('KeyboardPress', {
597
+ original: keyName,
598
+ key,
599
+ modifiers,
600
+ driver: this.useAppleScript ? "applescript" : 'libnut'
601
+ });
602
+ if (this.useAppleScript) sendKeyViaAppleScript(key, modifiers);
603
+ else if (modifiers.length > 0) libnut.keyTap(key, modifiers);
604
+ else libnut.keyTap(key);
605
+ }
606
+ async performScroll(param) {
607
+ external_node_assert_default()(libnut, 'libnut not initialized');
608
+ if (param.locate) {
609
+ const element = param.locate;
610
+ const [x, y] = element.center;
611
+ libnut.moveMouse(Math.round(x), Math.round(y));
612
+ }
613
+ const scrollType = param?.scrollType;
614
+ const edgeSpec = scrollType && scrollType in EDGE_SCROLL_SPEC ? EDGE_SCROLL_SPEC[scrollType] : null;
615
+ if (edgeSpec) {
616
+ if (runPhasedScroll(edgeSpec.direction, EDGE_SCROLL_TOTAL_PX, EDGE_SCROLL_STEPS)) return void await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
617
+ if (this.useAppleScript) {
618
+ sendKeyViaAppleScript(edgeSpec.key);
619
+ await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
620
+ return;
621
+ }
622
+ const [dx, dy] = edgeSpec.libnut;
623
+ for(let i = 0; i < SCROLL_REPEAT_COUNT; i++){
624
+ libnut.scrollMouse(dx, dy);
625
+ await (0, utils_namespaceObject.sleep)(SCROLL_STEP_DELAY);
626
+ }
627
+ return;
628
+ }
629
+ if ('singleAction' === scrollType || !scrollType) {
630
+ const distance = param?.distance || 500;
631
+ const direction = param?.direction || 'down';
632
+ const isKnownDirection = 'up' === direction || 'down' === direction || 'left' === direction || 'right' === direction;
633
+ if (isKnownDirection) {
634
+ const steps = Math.max(PHASED_MIN_STEPS, Math.round(distance / PHASED_PIXELS_PER_STEP));
635
+ if (runPhasedScroll(direction, distance, steps)) return void await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
636
+ }
637
+ if (this.useAppleScript && ('up' === direction || 'down' === direction)) {
638
+ const pages = Math.max(1, Math.round(distance / APPROX_VIEWPORT_HEIGHT_PX));
639
+ const key = 'up' === direction ? 'pageup' : 'pagedown';
640
+ for(let i = 0; i < pages; i++){
641
+ sendKeyViaAppleScript(key);
642
+ await (0, utils_namespaceObject.sleep)(SCROLL_STEP_DELAY);
643
+ }
644
+ await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
645
+ return;
646
+ }
647
+ const ticks = Math.ceil(distance / 100);
648
+ const directionMap = {
649
+ up: [
650
+ 0,
651
+ ticks
652
+ ],
653
+ down: [
654
+ 0,
655
+ -ticks
656
+ ],
657
+ left: [
658
+ -ticks,
659
+ 0
660
+ ],
661
+ right: [
662
+ ticks,
663
+ 0
664
+ ]
665
+ };
666
+ const [dx, dy] = directionMap[direction] || [
667
+ 0,
668
+ -ticks
669
+ ];
670
+ libnut.scrollMouse(dx, dy);
671
+ await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
672
+ return;
673
+ }
674
+ throw new Error(`Unknown scroll type: ${scrollType}, param: ${JSON.stringify(param)}`);
675
+ }
566
676
  actionSpace() {
567
677
  const defaultActions = [
568
- (0, device_namespaceObject.defineActionTap)(async (param)=>{
569
- external_node_assert_default()(libnut, 'libnut not initialized');
570
- const element = param.locate;
571
- external_node_assert_default()(element, 'Element not found, cannot tap');
572
- const [x, y] = element.center;
573
- const targetX = Math.round(x);
574
- const targetY = Math.round(y);
575
- await smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_TAP, SMOOTH_MOVE_DELAY_TAP);
576
- libnut.mouseToggle('down', 'left');
577
- await (0, utils_namespaceObject.sleep)(CLICK_HOLD_DURATION);
578
- libnut.mouseToggle('up', 'left');
579
- }),
580
- (0, device_namespaceObject.defineActionDoubleClick)(async (param)=>{
581
- external_node_assert_default()(libnut, 'libnut not initialized');
582
- const element = param.locate;
583
- external_node_assert_default()(element, 'Element not found, cannot double click');
584
- const [x, y] = element.center;
585
- libnut.moveMouse(Math.round(x), Math.round(y));
586
- libnut.mouseClick('left', true);
587
- }),
588
- (0, device_namespaceObject.defineActionRightClick)(async (param)=>{
589
- external_node_assert_default()(libnut, 'libnut not initialized');
590
- const element = param.locate;
591
- external_node_assert_default()(element, 'Element not found, cannot right click');
592
- const [x, y] = element.center;
593
- libnut.moveMouse(Math.round(x), Math.round(y));
594
- libnut.mouseClick('right');
595
- }),
596
- (0, device_namespaceObject.defineAction)({
597
- name: 'MouseMove',
598
- description: 'Move the mouse to the element',
599
- interfaceAlias: 'aiHover',
600
- paramSchema: device_namespaceObject.actionHoverParamSchema,
601
- sample: {
602
- locate: {
603
- prompt: 'the navigation menu item "Products"'
604
- }
605
- },
606
- call: async (param)=>{
607
- external_node_assert_default()(libnut, 'libnut not initialized');
608
- const element = param.locate;
609
- external_node_assert_default()(element, 'Element not found, cannot move mouse');
610
- const [x, y] = element.center;
611
- const targetX = Math.round(x);
612
- const targetY = Math.round(y);
613
- await smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_MOUSE_MOVE, SMOOTH_MOVE_DELAY_MOUSE_MOVE);
614
- await (0, utils_namespaceObject.sleep)(MOUSE_MOVE_EFFECT_WAIT);
615
- }
616
- }),
617
- (0, device_namespaceObject.defineAction)({
618
- name: 'Input',
619
- description: 'Input text into the input field',
620
- interfaceAlias: 'aiInput',
621
- paramSchema: computerInputParamSchema,
622
- sample: {
623
- value: 'test@example.com',
624
- locate: {
625
- prompt: 'the email input field'
626
- }
627
- },
628
- call: async (param)=>{
629
- external_node_assert_default()(libnut, 'libnut not initialized');
630
- const element = param.locate;
631
- if (element) {
632
- const [x, y] = element.center;
633
- libnut.moveMouse(Math.round(x), Math.round(y));
634
- libnut.mouseClick('left');
635
- await (0, utils_namespaceObject.sleep)(INPUT_FOCUS_DELAY);
636
- if ('append' !== param.mode) {
637
- if (this.useAppleScript) {
638
- sendKeyViaAppleScript('a', [
639
- 'command'
640
- ]);
641
- await (0, utils_namespaceObject.sleep)(50);
642
- sendKeyViaAppleScript('backspace', []);
643
- } else {
644
- const modifier = 'darwin' === process.platform ? 'command' : 'control';
645
- libnut.keyTap('a', [
646
- modifier
647
- ]);
648
- await (0, utils_namespaceObject.sleep)(50);
649
- libnut.keyTap('backspace');
650
- }
651
- await (0, utils_namespaceObject.sleep)(INPUT_CLEAR_DELAY);
652
- }
653
- }
654
- if ('clear' === param.mode) return;
655
- if (!param.value) return;
656
- await this.smartTypeString(param.value);
657
- }
658
- }),
659
- (0, device_namespaceObject.defineActionScroll)(async (param)=>{
660
- external_node_assert_default()(libnut, 'libnut not initialized');
661
- if (param.locate) {
662
- const element = param.locate;
663
- const [x, y] = element.center;
664
- libnut.moveMouse(Math.round(x), Math.round(y));
665
- }
666
- const scrollType = param?.scrollType;
667
- const edgeSpec = scrollType && scrollType in EDGE_SCROLL_SPEC ? EDGE_SCROLL_SPEC[scrollType] : null;
668
- if (edgeSpec) {
669
- if (runPhasedScroll(edgeSpec.direction, EDGE_SCROLL_TOTAL_PX, EDGE_SCROLL_STEPS)) return void await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
670
- if (this.useAppleScript) {
671
- sendKeyViaAppleScript(edgeSpec.key);
672
- await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
673
- return;
674
- }
675
- const [dx, dy] = edgeSpec.libnut;
676
- for(let i = 0; i < SCROLL_REPEAT_COUNT; i++){
677
- libnut.scrollMouse(dx, dy);
678
- await (0, utils_namespaceObject.sleep)(SCROLL_STEP_DELAY);
679
- }
680
- return;
681
- }
682
- if ('singleAction' === scrollType || !scrollType) {
683
- const distance = param?.distance || 500;
684
- const direction = param?.direction || 'down';
685
- const isKnownDirection = 'up' === direction || 'down' === direction || 'left' === direction || 'right' === direction;
686
- if (isKnownDirection) {
687
- const steps = Math.max(PHASED_MIN_STEPS, Math.round(distance / PHASED_PIXELS_PER_STEP));
688
- if (runPhasedScroll(direction, distance, steps)) return void await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
689
- }
690
- if (this.useAppleScript && ('up' === direction || 'down' === direction)) {
691
- const pages = Math.max(1, Math.round(distance / APPROX_VIEWPORT_HEIGHT_PX));
692
- const key = 'up' === direction ? 'pageup' : 'pagedown';
693
- for(let i = 0; i < pages; i++){
694
- sendKeyViaAppleScript(key);
695
- await (0, utils_namespaceObject.sleep)(SCROLL_STEP_DELAY);
696
- }
697
- await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
698
- return;
699
- }
700
- const ticks = Math.ceil(distance / 100);
701
- const directionMap = {
702
- up: [
703
- 0,
704
- ticks
705
- ],
706
- down: [
707
- 0,
708
- -ticks
709
- ],
710
- left: [
711
- -ticks,
712
- 0
713
- ],
714
- right: [
715
- ticks,
716
- 0
717
- ]
718
- };
719
- const [dx, dy] = directionMap[direction] || [
720
- 0,
721
- -ticks
722
- ];
723
- libnut.scrollMouse(dx, dy);
724
- await (0, utils_namespaceObject.sleep)(SCROLL_COMPLETE_DELAY);
725
- return;
726
- }
727
- throw new Error(`Unknown scroll type: ${scrollType}, param: ${JSON.stringify(param)}`);
728
- }),
729
- (0, device_namespaceObject.defineActionKeyboardPress)(async (param)=>{
730
- external_node_assert_default()(libnut, 'libnut not initialized');
731
- if (param.locate) {
732
- const [x, y] = param.locate.center;
733
- libnut.moveMouse(Math.round(x), Math.round(y));
734
- libnut.mouseClick('left');
735
- await (0, utils_namespaceObject.sleep)(50);
736
- }
737
- const keys = param.keyName.split('+');
738
- const modifiers = keys.slice(0, -1).map(normalizeKeyName);
739
- const key = normalizePrimaryKey(keys[keys.length - 1]);
740
- debugDevice('KeyboardPress', {
741
- original: param.keyName,
742
- key,
743
- modifiers,
744
- driver: this.useAppleScript ? "applescript" : 'libnut'
745
- });
746
- if (this.useAppleScript) sendKeyViaAppleScript(key, modifiers);
747
- else if (modifiers.length > 0) libnut.keyTap(key, modifiers);
748
- else libnut.keyTap(key);
749
- }),
750
- (0, device_namespaceObject.defineActionDragAndDrop)(async (param)=>{
751
- external_node_assert_default()(libnut, 'libnut not initialized');
752
- const from = param.from;
753
- const to = param.to;
754
- external_node_assert_default()(from, 'missing "from" param for drag and drop');
755
- external_node_assert_default()(to, 'missing "to" param for drag and drop');
756
- const [fromX, fromY] = from.center;
757
- const [toX, toY] = to.center;
758
- libnut.moveMouse(Math.round(fromX), Math.round(fromY));
759
- libnut.mouseToggle('down', 'left');
760
- await (0, utils_namespaceObject.sleep)(100);
761
- libnut.moveMouse(Math.round(toX), Math.round(toY));
762
- await (0, utils_namespaceObject.sleep)(100);
763
- libnut.mouseToggle('up', 'left');
764
- }),
765
- (0, device_namespaceObject.defineActionClearInput)(async (param)=>{
766
- external_node_assert_default()(libnut, 'libnut not initialized');
767
- const element = param.locate;
768
- external_node_assert_default()(element, 'Element not found, cannot clear input');
769
- const [x, y] = element.center;
770
- libnut.moveMouse(Math.round(x), Math.round(y));
771
- libnut.mouseClick('left');
772
- await (0, utils_namespaceObject.sleep)(100);
773
- if (this.useAppleScript) {
774
- sendKeyViaAppleScript('a', [
775
- 'command'
776
- ]);
777
- await (0, utils_namespaceObject.sleep)(50);
778
- sendKeyViaAppleScript('backspace', []);
779
- } else {
780
- const modifier = 'darwin' === process.platform ? 'command' : 'control';
781
- libnut.keyTap('a', [
782
- modifier
783
- ]);
784
- libnut.keyTap('backspace');
785
- }
786
- await (0, utils_namespaceObject.sleep)(50);
787
- })
678
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives)
788
679
  ];
789
680
  const platformActions = Object.values(createPlatformActions());
790
681
  const customActions = this.options?.customActions || [];
@@ -822,6 +713,88 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
822
713
  _define_property(this, "xvfbCleanup", void 0);
823
714
  _define_property(this, "useAppleScript", void 0);
824
715
  _define_property(this, "uri", void 0);
716
+ _define_property(this, "inputPrimitives", {
717
+ pointer: {
718
+ tap: async ({ x, y })=>{
719
+ external_node_assert_default()(libnut, 'libnut not initialized');
720
+ const targetX = Math.round(x);
721
+ const targetY = Math.round(y);
722
+ await smoothMoveMouse(targetX, targetY, SMOOTH_MOVE_STEPS_TAP, SMOOTH_MOVE_DELAY_TAP);
723
+ libnut.mouseToggle('down', 'left');
724
+ await (0, utils_namespaceObject.sleep)(CLICK_HOLD_DURATION);
725
+ libnut.mouseToggle('up', 'left');
726
+ },
727
+ doubleClick: async ({ x, y })=>{
728
+ external_node_assert_default()(libnut, 'libnut not initialized');
729
+ libnut.moveMouse(Math.round(x), Math.round(y));
730
+ libnut.mouseClick('left', true);
731
+ },
732
+ rightClick: async ({ x, y })=>{
733
+ external_node_assert_default()(libnut, 'libnut not initialized');
734
+ libnut.moveMouse(Math.round(x), Math.round(y));
735
+ libnut.mouseClick('right');
736
+ },
737
+ hover: async ({ x, y })=>{
738
+ external_node_assert_default()(libnut, 'libnut not initialized');
739
+ await smoothMoveMouse(Math.round(x), Math.round(y), SMOOTH_MOVE_STEPS_MOUSE_MOVE, SMOOTH_MOVE_DELAY_MOUSE_MOVE);
740
+ await (0, utils_namespaceObject.sleep)(MOUSE_MOVE_EFFECT_WAIT);
741
+ },
742
+ dragAndDrop: async (from, to)=>{
743
+ external_node_assert_default()(libnut, 'libnut not initialized');
744
+ libnut.moveMouse(Math.round(from.x), Math.round(from.y));
745
+ libnut.mouseToggle('down', 'left');
746
+ await (0, utils_namespaceObject.sleep)(100);
747
+ libnut.moveMouse(Math.round(to.x), Math.round(to.y));
748
+ await (0, utils_namespaceObject.sleep)(100);
749
+ libnut.mouseToggle('up', 'left');
750
+ }
751
+ },
752
+ keyboard: {
753
+ typeText: async (value, opts)=>{
754
+ external_node_assert_default()(libnut, 'libnut not initialized');
755
+ const element = opts?.target;
756
+ if (element) {
757
+ const [x, y] = element.center;
758
+ libnut.moveMouse(Math.round(x), Math.round(y));
759
+ libnut.mouseClick('left');
760
+ await (0, utils_namespaceObject.sleep)(INPUT_FOCUS_DELAY);
761
+ if (opts?.replace !== false) {
762
+ await this.selectAllAndDelete();
763
+ await (0, utils_namespaceObject.sleep)(INPUT_CLEAR_DELAY);
764
+ }
765
+ }
766
+ await this.smartTypeString(value);
767
+ },
768
+ keyboardPress: async (keyName, opts)=>{
769
+ external_node_assert_default()(libnut, 'libnut not initialized');
770
+ const target = opts?.target;
771
+ if (target) {
772
+ const [x, y] = target.center;
773
+ libnut.moveMouse(Math.round(x), Math.round(y));
774
+ libnut.mouseClick('left');
775
+ await (0, utils_namespaceObject.sleep)(50);
776
+ }
777
+ await this.pressKeyboardShortcut(keyName);
778
+ },
779
+ clearInput: async (target)=>{
780
+ external_node_assert_default()(libnut, 'libnut not initialized');
781
+ if (target) {
782
+ const element = target;
783
+ const [x, y] = element.center;
784
+ libnut.moveMouse(Math.round(x), Math.round(y));
785
+ libnut.mouseClick('left');
786
+ await (0, utils_namespaceObject.sleep)(100);
787
+ }
788
+ await this.selectAllAndDelete();
789
+ await (0, utils_namespaceObject.sleep)(50);
790
+ }
791
+ },
792
+ scroll: {
793
+ scroll: async (param)=>{
794
+ await this.performScroll(param);
795
+ }
796
+ }
797
+ });
825
798
  this.options = options;
826
799
  this.displayId = options?.displayId;
827
800
  this.useAppleScript = 'darwin' === process.platform && options?.keyboardDriver !== 'libnut';
@@ -1198,132 +1171,7 @@ class RDPDevice {
1198
1171
  }
1199
1172
  actionSpace() {
1200
1173
  const defaultActions = [
1201
- (0, device_namespaceObject.defineActionTap)(async ({ locate })=>{
1202
- const element = this.requireLocate(locate, 'tap');
1203
- await this.moveToElement(element, {
1204
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1205
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1206
- });
1207
- await this.backend.mouseButton('left', 'down');
1208
- await (0, utils_namespaceObject.sleep)(device_CLICK_HOLD_DURATION);
1209
- await this.backend.mouseButton('left', 'up');
1210
- }),
1211
- (0, device_namespaceObject.defineActionDoubleClick)(async ({ locate })=>{
1212
- const element = this.requireLocate(locate, 'double click');
1213
- await this.moveToElement(element, {
1214
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1215
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1216
- });
1217
- await this.backend.mouseButton('left', 'doubleClick');
1218
- }),
1219
- (0, device_namespaceObject.defineActionRightClick)(async ({ locate })=>{
1220
- const element = this.requireLocate(locate, 'right click');
1221
- await this.moveToElement(element, {
1222
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1223
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1224
- });
1225
- await this.backend.mouseButton('right', 'click');
1226
- }),
1227
- (0, device_namespaceObject.defineActionHover)(async ({ locate })=>{
1228
- const element = this.requireLocate(locate, 'hover');
1229
- await this.moveToElement(element, {
1230
- steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1231
- stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE,
1232
- settleDelayMs: device_MOUSE_MOVE_EFFECT_WAIT
1233
- });
1234
- }),
1235
- (0, device_namespaceObject.defineActionInput)(async (param)=>{
1236
- this.assertConnected();
1237
- if (param.locate) {
1238
- await this.moveToElement(param.locate, {
1239
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1240
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1241
- });
1242
- await this.backend.mouseButton('left', 'click');
1243
- await (0, utils_namespaceObject.sleep)(device_INPUT_FOCUS_DELAY);
1244
- }
1245
- if ('typeOnly' !== param.mode) {
1246
- await this.clearInput();
1247
- await (0, utils_namespaceObject.sleep)(device_INPUT_CLEAR_DELAY);
1248
- }
1249
- if ('clear' === param.mode) return;
1250
- if (param.value) await this.backend.typeText(param.value);
1251
- }),
1252
- (0, device_namespaceObject.defineActionClearInput)(async ({ locate })=>{
1253
- this.assertConnected();
1254
- if (locate) {
1255
- await this.moveToElement(locate, {
1256
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1257
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1258
- });
1259
- await this.backend.mouseButton('left', 'click');
1260
- await (0, utils_namespaceObject.sleep)(device_INPUT_FOCUS_DELAY);
1261
- }
1262
- await this.clearInput();
1263
- await (0, utils_namespaceObject.sleep)(device_INPUT_CLEAR_DELAY);
1264
- }),
1265
- (0, device_namespaceObject.defineActionKeyboardPress)(async ({ locate, keyName })=>{
1266
- this.assertConnected();
1267
- if (locate) {
1268
- await this.moveToElement(locate, {
1269
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1270
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1271
- });
1272
- await this.backend.mouseButton('left', 'click');
1273
- }
1274
- await this.backend.keyPress(keyName);
1275
- }),
1276
- (0, device_namespaceObject.defineActionScroll)(async (param)=>{
1277
- this.assertConnected();
1278
- const target = param.locate;
1279
- if (target) await this.moveToElement(target, {
1280
- steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1281
- stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE
1282
- });
1283
- if (param.scrollType && 'singleAction' !== param.scrollType) {
1284
- const direction = this.edgeScrollDirection(param.scrollType);
1285
- for(let i = 0; i < device_EDGE_SCROLL_STEPS; i++)await this.performWheel(direction, DEFAULT_SCROLL_DISTANCE, target?.center[0], target?.center[1]);
1286
- await (0, utils_namespaceObject.sleep)(device_SCROLL_COMPLETE_DELAY);
1287
- return;
1288
- }
1289
- await this.performWheel(param.direction || 'down', param.distance || DEFAULT_SCROLL_DISTANCE, target?.center[0], target?.center[1]);
1290
- await (0, utils_namespaceObject.sleep)(device_SCROLL_COMPLETE_DELAY);
1291
- }),
1292
- (0, device_namespaceObject.defineActionDragAndDrop)(async ({ from, to })=>{
1293
- this.assertConnected();
1294
- const source = this.requireLocate(from, 'drag source');
1295
- const target = this.requireLocate(to, 'drag target');
1296
- await this.moveToElement(source, {
1297
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1298
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1299
- });
1300
- await this.backend.mouseButton('left', 'down');
1301
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
1302
- await this.moveToElement(target, {
1303
- steps: SMOOTH_MOVE_STEPS_DRAG,
1304
- stepDelayMs: SMOOTH_MOVE_DELAY_DRAG
1305
- });
1306
- await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
1307
- await this.backend.mouseButton('left', 'up');
1308
- }),
1309
- (0, device_namespaceObject.defineAction)({
1310
- name: 'MiddleClick',
1311
- description: 'Middle click the element',
1312
- sample: {
1313
- locate: {
1314
- prompt: 'the browser tab close target'
1315
- }
1316
- },
1317
- paramSchema: device_namespaceObject.actionTapParamSchema,
1318
- call: async ({ locate })=>{
1319
- const element = this.requireLocate(locate, 'middle click');
1320
- await this.moveToElement(element, {
1321
- steps: device_SMOOTH_MOVE_STEPS_TAP,
1322
- stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1323
- });
1324
- await this.backend.mouseButton('middle', 'click');
1325
- }
1326
- }),
1174
+ ...(0, device_namespaceObject.defineActionsFromInputPrimitives)(this.inputPrimitives),
1327
1175
  (0, device_namespaceObject.defineAction)({
1328
1176
  name: 'ListDisplays',
1329
1177
  description: 'List all available displays/monitors',
@@ -1352,10 +1200,6 @@ class RDPDevice {
1352
1200
  throwIfDestroyed() {
1353
1201
  if (this.destroyed) throw new Error('RDPDevice has been destroyed');
1354
1202
  }
1355
- requireLocate(locate, actionName) {
1356
- if (!locate) throw new Error(`Missing target element for ${actionName}`);
1357
- return locate;
1358
- }
1359
1203
  async moveToElement(element, options) {
1360
1204
  this.assertConnected();
1361
1205
  const targetX = Math.round(element.center[0]);
@@ -1421,6 +1265,113 @@ class RDPDevice {
1421
1265
  device_define_property(this, "destroyed", false);
1422
1266
  device_define_property(this, "cursorPosition", void 0);
1423
1267
  device_define_property(this, "uri", void 0);
1268
+ device_define_property(this, "inputPrimitives", {
1269
+ pointer: {
1270
+ tap: async ({ x, y })=>{
1271
+ await this.movePointer(Math.round(x), Math.round(y), {
1272
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
1273
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1274
+ });
1275
+ await this.backend.mouseButton('left', 'down');
1276
+ await (0, utils_namespaceObject.sleep)(device_CLICK_HOLD_DURATION);
1277
+ await this.backend.mouseButton('left', 'up');
1278
+ },
1279
+ doubleClick: async ({ x, y })=>{
1280
+ await this.movePointer(Math.round(x), Math.round(y), {
1281
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
1282
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1283
+ });
1284
+ await this.backend.mouseButton('left', 'doubleClick');
1285
+ },
1286
+ rightClick: async ({ x, y })=>{
1287
+ await this.movePointer(Math.round(x), Math.round(y), {
1288
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
1289
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1290
+ });
1291
+ await this.backend.mouseButton('right', 'click');
1292
+ },
1293
+ hover: async ({ x, y })=>{
1294
+ await this.movePointer(Math.round(x), Math.round(y), {
1295
+ steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1296
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE,
1297
+ settleDelayMs: device_MOUSE_MOVE_EFFECT_WAIT
1298
+ });
1299
+ },
1300
+ dragAndDrop: async (from, to)=>{
1301
+ await this.movePointer(Math.round(from.x), Math.round(from.y), {
1302
+ steps: device_SMOOTH_MOVE_STEPS_TAP,
1303
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_TAP
1304
+ });
1305
+ await this.backend.mouseButton('left', 'down');
1306
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
1307
+ await this.movePointer(Math.round(to.x), Math.round(to.y), {
1308
+ steps: SMOOTH_MOVE_STEPS_DRAG,
1309
+ stepDelayMs: SMOOTH_MOVE_DELAY_DRAG
1310
+ });
1311
+ await (0, utils_namespaceObject.sleep)(DRAG_HOLD_DURATION);
1312
+ await this.backend.mouseButton('left', 'up');
1313
+ }
1314
+ },
1315
+ keyboard: {
1316
+ typeText: async (value, opts)=>{
1317
+ this.assertConnected();
1318
+ const target = opts?.target;
1319
+ if (target) {
1320
+ await this.inputPrimitives.pointer.tap({
1321
+ x: target.center[0],
1322
+ y: target.center[1]
1323
+ });
1324
+ await (0, utils_namespaceObject.sleep)(device_INPUT_FOCUS_DELAY);
1325
+ }
1326
+ if (opts?.replace !== false) {
1327
+ await this.clearInput();
1328
+ await (0, utils_namespaceObject.sleep)(device_INPUT_CLEAR_DELAY);
1329
+ }
1330
+ if (opts?.focusOnly || !value) return;
1331
+ await this.backend.typeText(value);
1332
+ },
1333
+ clearInput: async (target)=>{
1334
+ this.assertConnected();
1335
+ const element = target;
1336
+ if (element) {
1337
+ await this.inputPrimitives.pointer.tap({
1338
+ x: element.center[0],
1339
+ y: element.center[1]
1340
+ });
1341
+ await (0, utils_namespaceObject.sleep)(device_INPUT_FOCUS_DELAY);
1342
+ }
1343
+ await this.clearInput();
1344
+ await (0, utils_namespaceObject.sleep)(device_INPUT_CLEAR_DELAY);
1345
+ },
1346
+ keyboardPress: async (keyName, opts)=>{
1347
+ this.assertConnected();
1348
+ const target = opts?.target;
1349
+ if (target) await this.inputPrimitives.pointer.tap({
1350
+ x: target.center[0],
1351
+ y: target.center[1]
1352
+ });
1353
+ await this.backend.keyPress(keyName);
1354
+ }
1355
+ },
1356
+ scroll: {
1357
+ scroll: async (param)=>{
1358
+ this.assertConnected();
1359
+ const target = param.locate;
1360
+ if (target) await this.moveToElement(target, {
1361
+ steps: device_SMOOTH_MOVE_STEPS_MOUSE_MOVE,
1362
+ stepDelayMs: device_SMOOTH_MOVE_DELAY_MOUSE_MOVE
1363
+ });
1364
+ if (param.scrollType && 'singleAction' !== param.scrollType) {
1365
+ const direction = this.edgeScrollDirection(param.scrollType);
1366
+ for(let i = 0; i < device_EDGE_SCROLL_STEPS; i++)await this.performWheel(direction, DEFAULT_SCROLL_DISTANCE, target?.center[0], target?.center[1]);
1367
+ await (0, utils_namespaceObject.sleep)(device_SCROLL_COMPLETE_DELAY);
1368
+ return;
1369
+ }
1370
+ await this.performWheel(param.direction || 'down', param.distance || DEFAULT_SCROLL_DISTANCE, target?.center[0], target?.center[1]);
1371
+ await (0, utils_namespaceObject.sleep)(device_SCROLL_COMPLETE_DELAY);
1372
+ }
1373
+ }
1374
+ });
1424
1375
  this.options = {
1425
1376
  port: 3389,
1426
1377
  securityProtocol: 'auto',
@@ -1648,7 +1599,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
1648
1599
  const tools = new ComputerMidsceneTools();
1649
1600
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
1650
1601
  stripPrefix: 'computer_',
1651
- version: "1.8.1-beta-20260513084557.0",
1602
+ version: "1.8.1",
1652
1603
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
1653
1604
  }).catch((e)=>{
1654
1605
  process.exit((0, cli_namespaceObject.reportCLIError)(e));