@midscene/computer 1.12.5 → 1.12.6-beta-20260909033030.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/README.md +1 -49
- package/dist/es/cli.mjs +269 -155
- package/dist/es/index.mjs +269 -155
- package/dist/lib/cli.js +269 -155
- package/dist/lib/index.js +269 -155
- package/dist/types/index.d.ts +39 -1
- package/package.json +3 -3
package/dist/lib/cli.js
CHANGED
|
@@ -42,6 +42,207 @@ const utils_namespaceObject = require("@midscene/core/utils");
|
|
|
42
42
|
const img_namespaceObject = require("@midscene/shared/img");
|
|
43
43
|
const external_screenshot_desktop_namespaceObject = require("screenshot-desktop");
|
|
44
44
|
var external_screenshot_desktop_default = /*#__PURE__*/ __webpack_require__.n(external_screenshot_desktop_namespaceObject);
|
|
45
|
+
const US_SHIFTED_CHARACTER_KEYS = new Map([
|
|
46
|
+
[
|
|
47
|
+
'~',
|
|
48
|
+
'`'
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
'!',
|
|
52
|
+
'1'
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
'@',
|
|
56
|
+
'2'
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
'#',
|
|
60
|
+
'3'
|
|
61
|
+
],
|
|
62
|
+
[
|
|
63
|
+
'$',
|
|
64
|
+
'4'
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
'%',
|
|
68
|
+
'5'
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
'^',
|
|
72
|
+
'6'
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
'&',
|
|
76
|
+
'7'
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
'*',
|
|
80
|
+
'8'
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
'(',
|
|
84
|
+
'9'
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
')',
|
|
88
|
+
'0'
|
|
89
|
+
],
|
|
90
|
+
[
|
|
91
|
+
'_',
|
|
92
|
+
'-'
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
'+',
|
|
96
|
+
'='
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
'{',
|
|
100
|
+
'['
|
|
101
|
+
],
|
|
102
|
+
[
|
|
103
|
+
'}',
|
|
104
|
+
']'
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
'|',
|
|
108
|
+
'\\'
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
':',
|
|
112
|
+
';'
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
'"',
|
|
116
|
+
"'"
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
'<',
|
|
120
|
+
','
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
'>',
|
|
124
|
+
'.'
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
'?',
|
|
128
|
+
'/'
|
|
129
|
+
]
|
|
130
|
+
]);
|
|
131
|
+
function resolveUSShiftedKey(character) {
|
|
132
|
+
if (/^[A-Z]$/.test(character)) return character.toLowerCase();
|
|
133
|
+
return US_SHIFTED_CHARACTER_KEYS.get(character);
|
|
134
|
+
}
|
|
135
|
+
const debugKeyboard = (0, logger_namespaceObject.getDebug)('computer:keyboard');
|
|
136
|
+
const APPLE_SCRIPT_KEY_CODES = {
|
|
137
|
+
return: 36,
|
|
138
|
+
enter: 36,
|
|
139
|
+
tab: 48,
|
|
140
|
+
space: 49,
|
|
141
|
+
backspace: 51,
|
|
142
|
+
delete: 51,
|
|
143
|
+
escape: 53,
|
|
144
|
+
forwarddelete: 117,
|
|
145
|
+
left: 123,
|
|
146
|
+
right: 124,
|
|
147
|
+
down: 125,
|
|
148
|
+
up: 126,
|
|
149
|
+
home: 115,
|
|
150
|
+
end: 119,
|
|
151
|
+
pageup: 116,
|
|
152
|
+
pagedown: 121,
|
|
153
|
+
f1: 122,
|
|
154
|
+
f2: 120,
|
|
155
|
+
f3: 99,
|
|
156
|
+
f4: 118,
|
|
157
|
+
f5: 96,
|
|
158
|
+
f6: 97,
|
|
159
|
+
f7: 98,
|
|
160
|
+
f8: 100,
|
|
161
|
+
f9: 101,
|
|
162
|
+
f10: 109,
|
|
163
|
+
f11: 103,
|
|
164
|
+
f12: 111
|
|
165
|
+
};
|
|
166
|
+
const APPLE_SCRIPT_MODIFIER_KEYS = {
|
|
167
|
+
command: 'command',
|
|
168
|
+
cmd: 'command',
|
|
169
|
+
control: 'control',
|
|
170
|
+
ctrl: 'control',
|
|
171
|
+
shift: 'shift',
|
|
172
|
+
alt: 'option',
|
|
173
|
+
option: 'option',
|
|
174
|
+
meta: 'command'
|
|
175
|
+
};
|
|
176
|
+
function buildKeyCommand(key) {
|
|
177
|
+
const keyCode = APPLE_SCRIPT_KEY_CODES[key.toLowerCase()];
|
|
178
|
+
if (void 0 !== keyCode) return `key code ${keyCode}`;
|
|
179
|
+
const escapedKey = key.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
180
|
+
return `keystroke "${escapedKey}"`;
|
|
181
|
+
}
|
|
182
|
+
function resolveModifierKeys(modifiers) {
|
|
183
|
+
return modifiers.map((modifier)=>APPLE_SCRIPT_MODIFIER_KEYS[modifier.toLowerCase()]).filter((modifier)=>void 0 !== modifier);
|
|
184
|
+
}
|
|
185
|
+
function buildLogicalKeyPress(key, modifiers) {
|
|
186
|
+
const modifierKeys = resolveModifierKeys(modifiers);
|
|
187
|
+
const modifierClause = modifierKeys.length ? ` using {${modifierKeys.map((modifier)=>`${modifier} down`).join(', ')}}` : '';
|
|
188
|
+
return `tell application "System Events" to ${buildKeyCommand(key)}${modifierClause}`;
|
|
189
|
+
}
|
|
190
|
+
function resolvePhysicalKey(key, modifiers) {
|
|
191
|
+
const resolvedModifiers = [
|
|
192
|
+
...modifiers
|
|
193
|
+
];
|
|
194
|
+
const shiftedBaseKey = resolveUSShiftedKey(key);
|
|
195
|
+
if (void 0 !== shiftedBaseKey) {
|
|
196
|
+
resolvedModifiers.push('shift');
|
|
197
|
+
return {
|
|
198
|
+
key: shiftedBaseKey,
|
|
199
|
+
modifiers: resolvedModifiers
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
key,
|
|
204
|
+
modifiers: resolvedModifiers
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function buildPhysicalKeyPress(key, modifiers) {
|
|
208
|
+
const resolved = resolvePhysicalKey(key, modifiers);
|
|
209
|
+
const modifierKeys = [
|
|
210
|
+
...new Set(resolveModifierKeys(resolved.modifiers))
|
|
211
|
+
];
|
|
212
|
+
const keyCommand = buildKeyCommand(resolved.key);
|
|
213
|
+
if (0 === modifierKeys.length) return `tell application "System Events" to ${keyCommand}`;
|
|
214
|
+
const releaseCommands = [
|
|
215
|
+
...modifierKeys
|
|
216
|
+
].reverse().map((modifier)=>`key up ${modifier}`);
|
|
217
|
+
return [
|
|
218
|
+
'tell application "System Events"',
|
|
219
|
+
'try',
|
|
220
|
+
...modifierKeys.map((modifier)=>`key down ${modifier}`),
|
|
221
|
+
keyCommand,
|
|
222
|
+
'on error errorMessage number errorNumber',
|
|
223
|
+
...releaseCommands,
|
|
224
|
+
'error errorMessage number errorNumber',
|
|
225
|
+
'end try',
|
|
226
|
+
...releaseCommands,
|
|
227
|
+
'end tell'
|
|
228
|
+
].join('\n');
|
|
229
|
+
}
|
|
230
|
+
function buildAppleScriptKeyPress(key, modifiers = [], eventMode = 'logical') {
|
|
231
|
+
return 'physical' === eventMode ? buildPhysicalKeyPress(key, modifiers) : buildLogicalKeyPress(key, modifiers);
|
|
232
|
+
}
|
|
233
|
+
function sendKeyViaAppleScript(key, modifiers = [], eventMode = 'logical') {
|
|
234
|
+
const script = buildAppleScriptKeyPress(key, modifiers, eventMode);
|
|
235
|
+
debugKeyboard('sendKeyViaAppleScript', {
|
|
236
|
+
key,
|
|
237
|
+
modifiers,
|
|
238
|
+
eventMode,
|
|
239
|
+
script
|
|
240
|
+
});
|
|
241
|
+
(0, external_node_child_process_namespaceObject.execFileSync)("osascript", [
|
|
242
|
+
'-e',
|
|
243
|
+
script
|
|
244
|
+
]);
|
|
245
|
+
}
|
|
45
246
|
const external_node_assert_namespaceObject = require("node:assert");
|
|
46
247
|
var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
|
|
47
248
|
function _define_property(obj, key, value) {
|
|
@@ -116,6 +317,29 @@ class ComputerInputDriver {
|
|
|
116
317
|
if (void 0 !== modifiers) lib.keyTap(key, modifiers);
|
|
117
318
|
else lib.keyTap(key);
|
|
118
319
|
}
|
|
320
|
+
keyToggle(key, state, modifiers) {
|
|
321
|
+
const lib = this.getLibnutOrThrow('keyToggle');
|
|
322
|
+
if (void 0 !== modifiers) lib.keyToggle(key, state, modifiers);
|
|
323
|
+
else lib.keyToggle(key, state);
|
|
324
|
+
}
|
|
325
|
+
async keyTapWithExplicitModifiers(key, modifiers, delayMs) {
|
|
326
|
+
const uniqueModifiers = [
|
|
327
|
+
...new Set(modifiers)
|
|
328
|
+
];
|
|
329
|
+
if (0 === uniqueModifiers.length) return void this.keyTap(key);
|
|
330
|
+
const pressedModifiers = [];
|
|
331
|
+
try {
|
|
332
|
+
for (const modifier of uniqueModifiers){
|
|
333
|
+
this.keyToggle(modifier, 'down');
|
|
334
|
+
pressedModifiers.push(modifier);
|
|
335
|
+
}
|
|
336
|
+
await this.delay(delayMs);
|
|
337
|
+
this.keyTap(key);
|
|
338
|
+
await this.delay(delayMs);
|
|
339
|
+
} finally{
|
|
340
|
+
for (const modifier of pressedModifiers.reverse())this.releaseKey(modifier);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
119
343
|
typeString(text) {
|
|
120
344
|
this.getLibnutOrThrow('typeString').typeString(text);
|
|
121
345
|
}
|
|
@@ -188,6 +412,15 @@ class ComputerInputDriver {
|
|
|
188
412
|
this.options.debug(`Failed to release mouse button ${button}: ${error}`);
|
|
189
413
|
}
|
|
190
414
|
}
|
|
415
|
+
releaseKey(key) {
|
|
416
|
+
try {
|
|
417
|
+
const libnut = this.options.getLibnut();
|
|
418
|
+
external_node_assert_default()(libnut, 'libnut not initialized');
|
|
419
|
+
libnut.keyToggle(key, 'up');
|
|
420
|
+
} catch (error) {
|
|
421
|
+
this.options.debug(`Failed to release key ${key}: ${error}`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
191
424
|
rejectPendingInputDelays() {
|
|
192
425
|
const error = this.createDestroyedError('in-flight input');
|
|
193
426
|
for (const waitRef of this.pendingInputDelayWaits){
|
|
@@ -569,92 +802,6 @@ const LIBNUT_FALLBACK_PIXELS_PER_DETENT = 100;
|
|
|
569
802
|
const LIBNUT_FALLBACK_TICK_DELAY_MS = 30;
|
|
570
803
|
const LIBNUT_FALLBACK_MAX_DETENTS = 200;
|
|
571
804
|
const LIBNUT_FALLBACK_DETENT_AMOUNT = 'win32' === process.platform ? 120 : 1;
|
|
572
|
-
const LINUX_SHIFTED_CHARACTER_KEYS = new Map([
|
|
573
|
-
[
|
|
574
|
-
'~',
|
|
575
|
-
'`'
|
|
576
|
-
],
|
|
577
|
-
[
|
|
578
|
-
'!',
|
|
579
|
-
'1'
|
|
580
|
-
],
|
|
581
|
-
[
|
|
582
|
-
'@',
|
|
583
|
-
'2'
|
|
584
|
-
],
|
|
585
|
-
[
|
|
586
|
-
'#',
|
|
587
|
-
'3'
|
|
588
|
-
],
|
|
589
|
-
[
|
|
590
|
-
'$',
|
|
591
|
-
'4'
|
|
592
|
-
],
|
|
593
|
-
[
|
|
594
|
-
'%',
|
|
595
|
-
'5'
|
|
596
|
-
],
|
|
597
|
-
[
|
|
598
|
-
'^',
|
|
599
|
-
'6'
|
|
600
|
-
],
|
|
601
|
-
[
|
|
602
|
-
'&',
|
|
603
|
-
'7'
|
|
604
|
-
],
|
|
605
|
-
[
|
|
606
|
-
'*',
|
|
607
|
-
'8'
|
|
608
|
-
],
|
|
609
|
-
[
|
|
610
|
-
'(',
|
|
611
|
-
'9'
|
|
612
|
-
],
|
|
613
|
-
[
|
|
614
|
-
')',
|
|
615
|
-
'0'
|
|
616
|
-
],
|
|
617
|
-
[
|
|
618
|
-
'_',
|
|
619
|
-
'-'
|
|
620
|
-
],
|
|
621
|
-
[
|
|
622
|
-
'+',
|
|
623
|
-
'='
|
|
624
|
-
],
|
|
625
|
-
[
|
|
626
|
-
'{',
|
|
627
|
-
'['
|
|
628
|
-
],
|
|
629
|
-
[
|
|
630
|
-
'}',
|
|
631
|
-
']'
|
|
632
|
-
],
|
|
633
|
-
[
|
|
634
|
-
'|',
|
|
635
|
-
'\\'
|
|
636
|
-
],
|
|
637
|
-
[
|
|
638
|
-
':',
|
|
639
|
-
';'
|
|
640
|
-
],
|
|
641
|
-
[
|
|
642
|
-
'"',
|
|
643
|
-
"'"
|
|
644
|
-
],
|
|
645
|
-
[
|
|
646
|
-
'<',
|
|
647
|
-
','
|
|
648
|
-
],
|
|
649
|
-
[
|
|
650
|
-
'>',
|
|
651
|
-
'.'
|
|
652
|
-
],
|
|
653
|
-
[
|
|
654
|
-
'?',
|
|
655
|
-
'/'
|
|
656
|
-
]
|
|
657
|
-
]);
|
|
658
805
|
const LIBNUT_FALLBACK_EDGE_DETENTS = Math.min(LIBNUT_FALLBACK_MAX_DETENTS, Math.max(1, Math.ceil(EDGE_SCROLL_TOTAL_PX / LIBNUT_FALLBACK_PIXELS_PER_DETENT)));
|
|
659
806
|
const DEFAULT_SCROLL_VIEWPORT_RATIO = 0.7;
|
|
660
807
|
const EDGE_SCROLL_SPEC = {
|
|
@@ -691,67 +838,6 @@ const EDGE_SCROLL_SPEC = {
|
|
|
691
838
|
]
|
|
692
839
|
}
|
|
693
840
|
};
|
|
694
|
-
const APPLESCRIPT_KEY_CODE_MAP = {
|
|
695
|
-
return: 36,
|
|
696
|
-
enter: 36,
|
|
697
|
-
tab: 48,
|
|
698
|
-
space: 49,
|
|
699
|
-
backspace: 51,
|
|
700
|
-
delete: 51,
|
|
701
|
-
escape: 53,
|
|
702
|
-
forwarddelete: 117,
|
|
703
|
-
left: 123,
|
|
704
|
-
right: 124,
|
|
705
|
-
down: 125,
|
|
706
|
-
up: 126,
|
|
707
|
-
home: 115,
|
|
708
|
-
end: 119,
|
|
709
|
-
pageup: 116,
|
|
710
|
-
pagedown: 121,
|
|
711
|
-
f1: 122,
|
|
712
|
-
f2: 120,
|
|
713
|
-
f3: 99,
|
|
714
|
-
f4: 118,
|
|
715
|
-
f5: 96,
|
|
716
|
-
f6: 97,
|
|
717
|
-
f7: 98,
|
|
718
|
-
f8: 100,
|
|
719
|
-
f9: 101,
|
|
720
|
-
f10: 109,
|
|
721
|
-
f11: 103,
|
|
722
|
-
f12: 111
|
|
723
|
-
};
|
|
724
|
-
const APPLESCRIPT_MODIFIER_MAP = {
|
|
725
|
-
command: 'command down',
|
|
726
|
-
cmd: 'command down',
|
|
727
|
-
control: 'control down',
|
|
728
|
-
ctrl: 'control down',
|
|
729
|
-
shift: 'shift down',
|
|
730
|
-
alt: 'option down',
|
|
731
|
-
option: 'option down',
|
|
732
|
-
meta: 'command down'
|
|
733
|
-
};
|
|
734
|
-
function sendKeyViaAppleScript(key, modifiers = []) {
|
|
735
|
-
const lowerKey = key.toLowerCase();
|
|
736
|
-
const keyCode = APPLESCRIPT_KEY_CODE_MAP[lowerKey];
|
|
737
|
-
const modifierParts = modifiers.map((m)=>APPLESCRIPT_MODIFIER_MAP[m.toLowerCase()]).filter(Boolean);
|
|
738
|
-
const modifierStr = modifierParts.length > 0 ? ` using {${modifierParts.join(', ')}}` : '';
|
|
739
|
-
let script;
|
|
740
|
-
if (void 0 !== keyCode) script = `tell application "System Events" to key code ${keyCode}${modifierStr}`;
|
|
741
|
-
else {
|
|
742
|
-
const escapedKey = key.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
743
|
-
script = `tell application "System Events" to keystroke "${escapedKey}"${modifierStr}`;
|
|
744
|
-
}
|
|
745
|
-
debugDevice('sendKeyViaAppleScript', {
|
|
746
|
-
key,
|
|
747
|
-
modifiers,
|
|
748
|
-
script
|
|
749
|
-
});
|
|
750
|
-
(0, external_node_child_process_namespaceObject.execFileSync)("osascript", [
|
|
751
|
-
'-e',
|
|
752
|
-
script
|
|
753
|
-
]);
|
|
754
|
-
}
|
|
755
841
|
function escapePowershellSingleQuoted(value) {
|
|
756
842
|
return value.replace(/'/g, "''");
|
|
757
843
|
}
|
|
@@ -1179,7 +1265,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
1179
1265
|
}
|
|
1180
1266
|
async healthCheck(displays) {
|
|
1181
1267
|
console.log('[HealthCheck] Starting health check...');
|
|
1182
|
-
console.log("[HealthCheck] @midscene/computer v1.12.
|
|
1268
|
+
console.log("[HealthCheck] @midscene/computer v1.12.6-beta-20260909033030.0");
|
|
1183
1269
|
console.log('[HealthCheck] Taking screenshot...');
|
|
1184
1270
|
const screenshotTimeout = 15000;
|
|
1185
1271
|
let timeoutId;
|
|
@@ -1356,7 +1442,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1356
1442
|
]);
|
|
1357
1443
|
else {
|
|
1358
1444
|
const modifier = 'darwin' === process.platform ? 'command' : 'control';
|
|
1359
|
-
this.
|
|
1445
|
+
await this.sendLocalModifiedKey('v', [
|
|
1360
1446
|
modifier
|
|
1361
1447
|
]);
|
|
1362
1448
|
}
|
|
@@ -1373,12 +1459,16 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1373
1459
|
}
|
|
1374
1460
|
async typeStringWithDelay(text, keyboardTypeDelay) {
|
|
1375
1461
|
await (0, device_namespaceObject.sendTextSequentially)(text.replace(/\r\n?/g, '\n'), {
|
|
1376
|
-
sendCharacter: (character)=>{
|
|
1377
|
-
const linuxShiftedKey = 'linux' === process.platform ?
|
|
1462
|
+
sendCharacter: async (character)=>{
|
|
1463
|
+
const linuxShiftedKey = 'linux' === process.platform ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
|
|
1464
|
+
const pacedShiftedKey = !this.useAppleScript && (this.options?.keyboardShortcutDelay ?? 0) > 0 ? resolveUSShiftedKey(character) : void 0;
|
|
1378
1465
|
if ('\n' === character) this.inputDriver.sendKey('return');
|
|
1379
1466
|
else if ('\t' === character) this.inputDriver.sendKey('tab');
|
|
1380
1467
|
else if (' ' === character) this.inputDriver.sendKey('space');
|
|
1381
1468
|
else if (this.useAppleScript) this.inputDriver.sendKeyViaAppleScript(character);
|
|
1469
|
+
else if (void 0 !== pacedShiftedKey) await this.sendLocalModifiedKey(pacedShiftedKey, [
|
|
1470
|
+
'shift'
|
|
1471
|
+
]);
|
|
1382
1472
|
else if (void 0 !== linuxShiftedKey) this.inputDriver.keyTap(linuxShiftedKey, [
|
|
1383
1473
|
'shift'
|
|
1384
1474
|
]);
|
|
@@ -1399,12 +1489,17 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1399
1489
|
return;
|
|
1400
1490
|
}
|
|
1401
1491
|
const modifier = 'darwin' === process.platform ? 'command' : 'control';
|
|
1402
|
-
this.
|
|
1492
|
+
await this.sendLocalModifiedKey('a', [
|
|
1403
1493
|
modifier
|
|
1404
1494
|
]);
|
|
1405
1495
|
await this.inputDriver.delay(50);
|
|
1406
1496
|
this.inputDriver.keyTap('backspace');
|
|
1407
1497
|
}
|
|
1498
|
+
async sendLocalModifiedKey(key, modifiers) {
|
|
1499
|
+
const shortcutDelay = this.options?.keyboardShortcutDelay ?? 0;
|
|
1500
|
+
if (modifiers.length > 0 && shortcutDelay > 0) return void await this.inputDriver.keyTapWithExplicitModifiers(key, modifiers, shortcutDelay);
|
|
1501
|
+
this.inputDriver.keyTap(key, modifiers);
|
|
1502
|
+
}
|
|
1408
1503
|
async pressKeyboardShortcut(keyName) {
|
|
1409
1504
|
const keys = keyName.split('+');
|
|
1410
1505
|
const modifiers = keys.slice(0, -1).map(normalizeKeyName);
|
|
@@ -1415,6 +1510,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1415
1510
|
modifiers,
|
|
1416
1511
|
driver: this.useAppleScript ? "applescript" : 'libnut'
|
|
1417
1512
|
});
|
|
1513
|
+
if (!this.useAppleScript && modifiers.length > 0 && (this.options?.keyboardShortcutDelay ?? 0) > 0) return void await this.sendLocalModifiedKey(key, modifiers);
|
|
1418
1514
|
this.inputDriver.sendKey(key, modifiers);
|
|
1419
1515
|
}
|
|
1420
1516
|
resolveUntargetedScrollPoint(screenSize) {
|
|
@@ -1568,7 +1664,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1568
1664
|
device_define_property(this, "inputDriver", new ComputerInputDriver({
|
|
1569
1665
|
getLibnut: ()=>device_libnut,
|
|
1570
1666
|
useAppleScript: ()=>this.useAppleScript,
|
|
1571
|
-
sendKeyViaAppleScript,
|
|
1667
|
+
sendKeyViaAppleScript: (key, modifiers)=>sendKeyViaAppleScript(key, modifiers, this.options?.keyboardEventMode ?? 'logical'),
|
|
1572
1668
|
runPhasedScroll,
|
|
1573
1669
|
debug: (message)=>debugDevice(message)
|
|
1574
1670
|
}));
|
|
@@ -1694,6 +1790,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1694
1790
|
}
|
|
1695
1791
|
}
|
|
1696
1792
|
});
|
|
1793
|
+
if (options?.keyboardShortcutDelay !== void 0 && (!Number.isFinite(options.keyboardShortcutDelay) || options.keyboardShortcutDelay < 0)) throw new Error('keyboardShortcutDelay must be a finite non-negative number');
|
|
1697
1794
|
this.options = options;
|
|
1698
1795
|
this.displayId = options?.displayId;
|
|
1699
1796
|
this.useAppleScript = 'darwin' === process.platform && options?.keyboardDriver !== 'libnut';
|
|
@@ -2397,6 +2494,8 @@ function createLocalComputerDevice(opts) {
|
|
|
2397
2494
|
keyboardTypeDelay: opts?.keyboardTypeDelay,
|
|
2398
2495
|
inputStrategy: opts?.inputStrategy,
|
|
2399
2496
|
keyboardDriver: opts?.keyboardDriver,
|
|
2497
|
+
keyboardEventMode: opts?.keyboardEventMode,
|
|
2498
|
+
keyboardShortcutDelay: opts?.keyboardShortcutDelay,
|
|
2400
2499
|
headless: opts?.headless,
|
|
2401
2500
|
xvfbResolution: opts?.xvfbResolution,
|
|
2402
2501
|
keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
|
|
@@ -2454,6 +2553,11 @@ const computerInitArgShape = {
|
|
|
2454
2553
|
headless: core_namespaceObject.z.boolean().optional().describe('Start virtual display via Xvfb (Linux local mode only). Ignored when host is set.'),
|
|
2455
2554
|
keyboardTypeDelay: core_namespaceObject.z.number().finite().nonnegative().optional().describe('Finite non-negative delay in milliseconds between keystrokes. In "legacy" mode, positive values enable key-by-key input; zero or omitted uses clipboard input.'),
|
|
2456
2555
|
inputStrategy: core_namespaceObject.z["enum"](device_namespaceObject.inputStrategies).optional().describe('Text input strategy. "legacy" (default) preserves current Computer behavior, "sequential" sends one Unicode code point at a time, and "bulk" uses one backend input operation. "bulk" requires keyboardTypeDelay to be omitted or set to 0.'),
|
|
2556
|
+
keyboardEventMode: core_namespaceObject.z["enum"]([
|
|
2557
|
+
'logical',
|
|
2558
|
+
'physical'
|
|
2559
|
+
]).optional().describe('macOS AppleScript keyboard event mode for local control. "logical" (default) uses a compact keystroke command; "physical" sends explicit modifier transitions for foreground apps that require separate key state changes. Both modes use AppleScript, and "physical" is not hardware input. It assumes an en-US layout for shifted punctuation and requires sequential text input or a positive keyboardTypeDelay. Ignored in RDP mode and outside the macOS AppleScript driver.'),
|
|
2560
|
+
keyboardShortcutDelay: core_namespaceObject.z.number().finite().nonnegative().optional().describe('Finite non-negative delay in milliseconds around modifier transitions for local libnut keyboard events. Positive values pace shortcuts and the implicit Shift used by uppercase or en-US punctuation during sequential input. Ignored in RDP mode and by the macOS AppleScript driver.'),
|
|
2457
2561
|
host: core_namespaceObject.z.string().optional().describe('RDP host (FQDN or IP). Set this to switch into RDP mode.'),
|
|
2458
2562
|
port: core_namespaceObject.z.number().optional().describe('RDP port (default 3389). Requires host.'),
|
|
2459
2563
|
username: core_namespaceObject.z.string().optional().describe('RDP username. Requires host.'),
|
|
@@ -2470,7 +2574,7 @@ const computerInitArgShape = {
|
|
|
2470
2574
|
function adaptComputerInitArgs(extracted) {
|
|
2471
2575
|
if (!extracted || 0 === Object.keys(extracted).length) return;
|
|
2472
2576
|
if (extracted.host) {
|
|
2473
|
-
const { displayId: _d, headless: _h, ...rdpFields } = extracted;
|
|
2577
|
+
const { displayId: _d, headless: _h, keyboardEventMode: _k, keyboardShortcutDelay: _s, ...rdpFields } = extracted;
|
|
2474
2578
|
const host = normalizeRdpHost(extracted.host);
|
|
2475
2579
|
return {
|
|
2476
2580
|
mode: 'rdp',
|
|
@@ -2484,6 +2588,8 @@ function adaptComputerInitArgs(extracted) {
|
|
|
2484
2588
|
headless: extracted.headless,
|
|
2485
2589
|
keyboardTypeDelay: extracted.keyboardTypeDelay,
|
|
2486
2590
|
inputStrategy: extracted.inputStrategy,
|
|
2591
|
+
keyboardEventMode: extracted.keyboardEventMode,
|
|
2592
|
+
keyboardShortcutDelay: extracted.keyboardShortcutDelay,
|
|
2487
2593
|
...(0, agent_behavior_init_args_namespaceObject.extractAgentBehaviorInitArgs)(extracted) ?? {}
|
|
2488
2594
|
};
|
|
2489
2595
|
}
|
|
@@ -2535,6 +2641,8 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2535
2641
|
const headless = opts?.mode === 'local' ? opts.headless : void 0;
|
|
2536
2642
|
const keyboardTypeDelay = opts?.keyboardTypeDelay;
|
|
2537
2643
|
const inputStrategy = opts?.inputStrategy;
|
|
2644
|
+
const keyboardEventMode = opts?.mode === 'local' ? opts.keyboardEventMode : void 0;
|
|
2645
|
+
const keyboardShortcutDelay = opts?.mode === 'local' ? opts.keyboardShortcutDelay : void 0;
|
|
2538
2646
|
agent_tools_debug('Creating Computer agent with displayId:', displayId || 'primary');
|
|
2539
2647
|
const agentOpts = {
|
|
2540
2648
|
...displayId ? {
|
|
@@ -2549,6 +2657,12 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2549
2657
|
...void 0 !== inputStrategy ? {
|
|
2550
2658
|
inputStrategy
|
|
2551
2659
|
} : {},
|
|
2660
|
+
...void 0 !== keyboardEventMode ? {
|
|
2661
|
+
keyboardEventMode
|
|
2662
|
+
} : {},
|
|
2663
|
+
...void 0 !== keyboardShortcutDelay ? {
|
|
2664
|
+
keyboardShortcutDelay
|
|
2665
|
+
} : {},
|
|
2552
2666
|
...this.options.keepXvfbAliveUntilProcessExit ? {
|
|
2553
2667
|
keepXvfbAliveUntilProcessExit: true
|
|
2554
2668
|
} : {},
|
|
@@ -2633,7 +2747,7 @@ const tools = new ComputerMidsceneTools({
|
|
|
2633
2747
|
});
|
|
2634
2748
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
|
|
2635
2749
|
stripPrefix: 'computer_',
|
|
2636
|
-
version: "1.12.
|
|
2750
|
+
version: "1.12.6-beta-20260909033030.0",
|
|
2637
2751
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
2638
2752
|
}).catch((e)=>{
|
|
2639
2753
|
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|