@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/dist/es/index.mjs CHANGED
@@ -19,6 +19,207 @@ import { z } from "@midscene/core";
19
19
  import { agentBehaviorInitArgShape, extractAgentBehaviorInitArgs, getAgentInitArgsSignature, shouldRebuildAgentForInitArgs } from "@midscene/shared/agent-tools/agent-behavior-init-args";
20
20
  import { BaseMidsceneTools } from "@midscene/shared/agent-tools/base-tools";
21
21
  import { overrideAIConfig } from "@midscene/shared/env";
22
+ const US_SHIFTED_CHARACTER_KEYS = new Map([
23
+ [
24
+ '~',
25
+ '`'
26
+ ],
27
+ [
28
+ '!',
29
+ '1'
30
+ ],
31
+ [
32
+ '@',
33
+ '2'
34
+ ],
35
+ [
36
+ '#',
37
+ '3'
38
+ ],
39
+ [
40
+ '$',
41
+ '4'
42
+ ],
43
+ [
44
+ '%',
45
+ '5'
46
+ ],
47
+ [
48
+ '^',
49
+ '6'
50
+ ],
51
+ [
52
+ '&',
53
+ '7'
54
+ ],
55
+ [
56
+ '*',
57
+ '8'
58
+ ],
59
+ [
60
+ '(',
61
+ '9'
62
+ ],
63
+ [
64
+ ')',
65
+ '0'
66
+ ],
67
+ [
68
+ '_',
69
+ '-'
70
+ ],
71
+ [
72
+ '+',
73
+ '='
74
+ ],
75
+ [
76
+ '{',
77
+ '['
78
+ ],
79
+ [
80
+ '}',
81
+ ']'
82
+ ],
83
+ [
84
+ '|',
85
+ '\\'
86
+ ],
87
+ [
88
+ ':',
89
+ ';'
90
+ ],
91
+ [
92
+ '"',
93
+ "'"
94
+ ],
95
+ [
96
+ '<',
97
+ ','
98
+ ],
99
+ [
100
+ '>',
101
+ '.'
102
+ ],
103
+ [
104
+ '?',
105
+ '/'
106
+ ]
107
+ ]);
108
+ function resolveUSShiftedKey(character) {
109
+ if (/^[A-Z]$/.test(character)) return character.toLowerCase();
110
+ return US_SHIFTED_CHARACTER_KEYS.get(character);
111
+ }
112
+ const debugKeyboard = getDebug('computer:keyboard');
113
+ const APPLE_SCRIPT_KEY_CODES = {
114
+ return: 36,
115
+ enter: 36,
116
+ tab: 48,
117
+ space: 49,
118
+ backspace: 51,
119
+ delete: 51,
120
+ escape: 53,
121
+ forwarddelete: 117,
122
+ left: 123,
123
+ right: 124,
124
+ down: 125,
125
+ up: 126,
126
+ home: 115,
127
+ end: 119,
128
+ pageup: 116,
129
+ pagedown: 121,
130
+ f1: 122,
131
+ f2: 120,
132
+ f3: 99,
133
+ f4: 118,
134
+ f5: 96,
135
+ f6: 97,
136
+ f7: 98,
137
+ f8: 100,
138
+ f9: 101,
139
+ f10: 109,
140
+ f11: 103,
141
+ f12: 111
142
+ };
143
+ const APPLE_SCRIPT_MODIFIER_KEYS = {
144
+ command: 'command',
145
+ cmd: 'command',
146
+ control: 'control',
147
+ ctrl: 'control',
148
+ shift: 'shift',
149
+ alt: 'option',
150
+ option: 'option',
151
+ meta: 'command'
152
+ };
153
+ function buildKeyCommand(key) {
154
+ const keyCode = APPLE_SCRIPT_KEY_CODES[key.toLowerCase()];
155
+ if (void 0 !== keyCode) return `key code ${keyCode}`;
156
+ const escapedKey = key.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
157
+ return `keystroke "${escapedKey}"`;
158
+ }
159
+ function resolveModifierKeys(modifiers) {
160
+ return modifiers.map((modifier)=>APPLE_SCRIPT_MODIFIER_KEYS[modifier.toLowerCase()]).filter((modifier)=>void 0 !== modifier);
161
+ }
162
+ function buildLogicalKeyPress(key, modifiers) {
163
+ const modifierKeys = resolveModifierKeys(modifiers);
164
+ const modifierClause = modifierKeys.length ? ` using {${modifierKeys.map((modifier)=>`${modifier} down`).join(', ')}}` : '';
165
+ return `tell application "System Events" to ${buildKeyCommand(key)}${modifierClause}`;
166
+ }
167
+ function resolvePhysicalKey(key, modifiers) {
168
+ const resolvedModifiers = [
169
+ ...modifiers
170
+ ];
171
+ const shiftedBaseKey = resolveUSShiftedKey(key);
172
+ if (void 0 !== shiftedBaseKey) {
173
+ resolvedModifiers.push('shift');
174
+ return {
175
+ key: shiftedBaseKey,
176
+ modifiers: resolvedModifiers
177
+ };
178
+ }
179
+ return {
180
+ key,
181
+ modifiers: resolvedModifiers
182
+ };
183
+ }
184
+ function buildPhysicalKeyPress(key, modifiers) {
185
+ const resolved = resolvePhysicalKey(key, modifiers);
186
+ const modifierKeys = [
187
+ ...new Set(resolveModifierKeys(resolved.modifiers))
188
+ ];
189
+ const keyCommand = buildKeyCommand(resolved.key);
190
+ if (0 === modifierKeys.length) return `tell application "System Events" to ${keyCommand}`;
191
+ const releaseCommands = [
192
+ ...modifierKeys
193
+ ].reverse().map((modifier)=>`key up ${modifier}`);
194
+ return [
195
+ 'tell application "System Events"',
196
+ 'try',
197
+ ...modifierKeys.map((modifier)=>`key down ${modifier}`),
198
+ keyCommand,
199
+ 'on error errorMessage number errorNumber',
200
+ ...releaseCommands,
201
+ 'error errorMessage number errorNumber',
202
+ 'end try',
203
+ ...releaseCommands,
204
+ 'end tell'
205
+ ].join('\n');
206
+ }
207
+ function buildAppleScriptKeyPress(key, modifiers = [], eventMode = 'logical') {
208
+ return 'physical' === eventMode ? buildPhysicalKeyPress(key, modifiers) : buildLogicalKeyPress(key, modifiers);
209
+ }
210
+ function sendKeyViaAppleScript(key, modifiers = [], eventMode = 'logical') {
211
+ const script = buildAppleScriptKeyPress(key, modifiers, eventMode);
212
+ debugKeyboard('sendKeyViaAppleScript', {
213
+ key,
214
+ modifiers,
215
+ eventMode,
216
+ script
217
+ });
218
+ execFileSync("osascript", [
219
+ '-e',
220
+ script
221
+ ]);
222
+ }
22
223
  function _define_property(obj, key, value) {
23
224
  if (key in obj) Object.defineProperty(obj, key, {
24
225
  value: value,
@@ -91,6 +292,29 @@ class ComputerInputDriver {
91
292
  if (void 0 !== modifiers) lib.keyTap(key, modifiers);
92
293
  else lib.keyTap(key);
93
294
  }
295
+ keyToggle(key, state, modifiers) {
296
+ const lib = this.getLibnutOrThrow('keyToggle');
297
+ if (void 0 !== modifiers) lib.keyToggle(key, state, modifiers);
298
+ else lib.keyToggle(key, state);
299
+ }
300
+ async keyTapWithExplicitModifiers(key, modifiers, delayMs) {
301
+ const uniqueModifiers = [
302
+ ...new Set(modifiers)
303
+ ];
304
+ if (0 === uniqueModifiers.length) return void this.keyTap(key);
305
+ const pressedModifiers = [];
306
+ try {
307
+ for (const modifier of uniqueModifiers){
308
+ this.keyToggle(modifier, 'down');
309
+ pressedModifiers.push(modifier);
310
+ }
311
+ await this.delay(delayMs);
312
+ this.keyTap(key);
313
+ await this.delay(delayMs);
314
+ } finally{
315
+ for (const modifier of pressedModifiers.reverse())this.releaseKey(modifier);
316
+ }
317
+ }
94
318
  typeString(text) {
95
319
  this.getLibnutOrThrow('typeString').typeString(text);
96
320
  }
@@ -163,6 +387,15 @@ class ComputerInputDriver {
163
387
  this.options.debug(`Failed to release mouse button ${button}: ${error}`);
164
388
  }
165
389
  }
390
+ releaseKey(key) {
391
+ try {
392
+ const libnut = this.options.getLibnut();
393
+ node_assert(libnut, 'libnut not initialized');
394
+ libnut.keyToggle(key, 'up');
395
+ } catch (error) {
396
+ this.options.debug(`Failed to release key ${key}: ${error}`);
397
+ }
398
+ }
166
399
  rejectPendingInputDelays() {
167
400
  const error = this.createDestroyedError('in-flight input');
168
401
  for (const waitRef of this.pendingInputDelayWaits){
@@ -543,92 +776,6 @@ const LIBNUT_FALLBACK_PIXELS_PER_DETENT = 100;
543
776
  const LIBNUT_FALLBACK_TICK_DELAY_MS = 30;
544
777
  const LIBNUT_FALLBACK_MAX_DETENTS = 200;
545
778
  const LIBNUT_FALLBACK_DETENT_AMOUNT = 'win32' === process.platform ? 120 : 1;
546
- const LINUX_SHIFTED_CHARACTER_KEYS = new Map([
547
- [
548
- '~',
549
- '`'
550
- ],
551
- [
552
- '!',
553
- '1'
554
- ],
555
- [
556
- '@',
557
- '2'
558
- ],
559
- [
560
- '#',
561
- '3'
562
- ],
563
- [
564
- '$',
565
- '4'
566
- ],
567
- [
568
- '%',
569
- '5'
570
- ],
571
- [
572
- '^',
573
- '6'
574
- ],
575
- [
576
- '&',
577
- '7'
578
- ],
579
- [
580
- '*',
581
- '8'
582
- ],
583
- [
584
- '(',
585
- '9'
586
- ],
587
- [
588
- ')',
589
- '0'
590
- ],
591
- [
592
- '_',
593
- '-'
594
- ],
595
- [
596
- '+',
597
- '='
598
- ],
599
- [
600
- '{',
601
- '['
602
- ],
603
- [
604
- '}',
605
- ']'
606
- ],
607
- [
608
- '|',
609
- '\\'
610
- ],
611
- [
612
- ':',
613
- ';'
614
- ],
615
- [
616
- '"',
617
- "'"
618
- ],
619
- [
620
- '<',
621
- ','
622
- ],
623
- [
624
- '>',
625
- '.'
626
- ],
627
- [
628
- '?',
629
- '/'
630
- ]
631
- ]);
632
779
  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)));
633
780
  const DEFAULT_SCROLL_VIEWPORT_RATIO = 0.7;
634
781
  const EDGE_SCROLL_SPEC = {
@@ -665,67 +812,6 @@ const EDGE_SCROLL_SPEC = {
665
812
  ]
666
813
  }
667
814
  };
668
- const APPLESCRIPT_KEY_CODE_MAP = {
669
- return: 36,
670
- enter: 36,
671
- tab: 48,
672
- space: 49,
673
- backspace: 51,
674
- delete: 51,
675
- escape: 53,
676
- forwarddelete: 117,
677
- left: 123,
678
- right: 124,
679
- down: 125,
680
- up: 126,
681
- home: 115,
682
- end: 119,
683
- pageup: 116,
684
- pagedown: 121,
685
- f1: 122,
686
- f2: 120,
687
- f3: 99,
688
- f4: 118,
689
- f5: 96,
690
- f6: 97,
691
- f7: 98,
692
- f8: 100,
693
- f9: 101,
694
- f10: 109,
695
- f11: 103,
696
- f12: 111
697
- };
698
- const APPLESCRIPT_MODIFIER_MAP = {
699
- command: 'command down',
700
- cmd: 'command down',
701
- control: 'control down',
702
- ctrl: 'control down',
703
- shift: 'shift down',
704
- alt: 'option down',
705
- option: 'option down',
706
- meta: 'command down'
707
- };
708
- function sendKeyViaAppleScript(key, modifiers = []) {
709
- const lowerKey = key.toLowerCase();
710
- const keyCode = APPLESCRIPT_KEY_CODE_MAP[lowerKey];
711
- const modifierParts = modifiers.map((m)=>APPLESCRIPT_MODIFIER_MAP[m.toLowerCase()]).filter(Boolean);
712
- const modifierStr = modifierParts.length > 0 ? ` using {${modifierParts.join(', ')}}` : '';
713
- let script;
714
- if (void 0 !== keyCode) script = `tell application "System Events" to key code ${keyCode}${modifierStr}`;
715
- else {
716
- const escapedKey = key.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
717
- script = `tell application "System Events" to keystroke "${escapedKey}"${modifierStr}`;
718
- }
719
- debugDevice('sendKeyViaAppleScript', {
720
- key,
721
- modifiers,
722
- script
723
- });
724
- execFileSync("osascript", [
725
- '-e',
726
- script
727
- ]);
728
- }
729
815
  function escapePowershellSingleQuoted(value) {
730
816
  return value.replace(/'/g, "''");
731
817
  }
@@ -1153,7 +1239,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
1153
1239
  }
1154
1240
  async healthCheck(displays) {
1155
1241
  console.log('[HealthCheck] Starting health check...');
1156
- console.log("[HealthCheck] @midscene/computer v1.12.5");
1242
+ console.log("[HealthCheck] @midscene/computer v1.12.6-beta-20260909033030.0");
1157
1243
  console.log('[HealthCheck] Taking screenshot...');
1158
1244
  const screenshotTimeout = 15000;
1159
1245
  let timeoutId;
@@ -1330,7 +1416,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1330
1416
  ]);
1331
1417
  else {
1332
1418
  const modifier = 'darwin' === process.platform ? 'command' : 'control';
1333
- this.inputDriver.keyTap('v', [
1419
+ await this.sendLocalModifiedKey('v', [
1334
1420
  modifier
1335
1421
  ]);
1336
1422
  }
@@ -1347,12 +1433,16 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1347
1433
  }
1348
1434
  async typeStringWithDelay(text, keyboardTypeDelay) {
1349
1435
  await sendTextSequentially(text.replace(/\r\n?/g, '\n'), {
1350
- sendCharacter: (character)=>{
1351
- const linuxShiftedKey = 'linux' === process.platform ? LINUX_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
1436
+ sendCharacter: async (character)=>{
1437
+ const linuxShiftedKey = 'linux' === process.platform ? US_SHIFTED_CHARACTER_KEYS.get(character) : void 0;
1438
+ const pacedShiftedKey = !this.useAppleScript && (this.options?.keyboardShortcutDelay ?? 0) > 0 ? resolveUSShiftedKey(character) : void 0;
1352
1439
  if ('\n' === character) this.inputDriver.sendKey('return');
1353
1440
  else if ('\t' === character) this.inputDriver.sendKey('tab');
1354
1441
  else if (' ' === character) this.inputDriver.sendKey('space');
1355
1442
  else if (this.useAppleScript) this.inputDriver.sendKeyViaAppleScript(character);
1443
+ else if (void 0 !== pacedShiftedKey) await this.sendLocalModifiedKey(pacedShiftedKey, [
1444
+ 'shift'
1445
+ ]);
1356
1446
  else if (void 0 !== linuxShiftedKey) this.inputDriver.keyTap(linuxShiftedKey, [
1357
1447
  'shift'
1358
1448
  ]);
@@ -1373,12 +1463,17 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1373
1463
  return;
1374
1464
  }
1375
1465
  const modifier = 'darwin' === process.platform ? 'command' : 'control';
1376
- this.inputDriver.keyTap('a', [
1466
+ await this.sendLocalModifiedKey('a', [
1377
1467
  modifier
1378
1468
  ]);
1379
1469
  await this.inputDriver.delay(50);
1380
1470
  this.inputDriver.keyTap('backspace');
1381
1471
  }
1472
+ async sendLocalModifiedKey(key, modifiers) {
1473
+ const shortcutDelay = this.options?.keyboardShortcutDelay ?? 0;
1474
+ if (modifiers.length > 0 && shortcutDelay > 0) return void await this.inputDriver.keyTapWithExplicitModifiers(key, modifiers, shortcutDelay);
1475
+ this.inputDriver.keyTap(key, modifiers);
1476
+ }
1382
1477
  async pressKeyboardShortcut(keyName) {
1383
1478
  const keys = keyName.split('+');
1384
1479
  const modifiers = keys.slice(0, -1).map(normalizeKeyName);
@@ -1389,6 +1484,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1389
1484
  modifiers,
1390
1485
  driver: this.useAppleScript ? "applescript" : 'libnut'
1391
1486
  });
1487
+ if (!this.useAppleScript && modifiers.length > 0 && (this.options?.keyboardShortcutDelay ?? 0) > 0) return void await this.sendLocalModifiedKey(key, modifiers);
1392
1488
  this.inputDriver.sendKey(key, modifiers);
1393
1489
  }
1394
1490
  resolveUntargetedScrollPoint(screenSize) {
@@ -1542,7 +1638,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1542
1638
  device_define_property(this, "inputDriver", new ComputerInputDriver({
1543
1639
  getLibnut: ()=>device_libnut,
1544
1640
  useAppleScript: ()=>this.useAppleScript,
1545
- sendKeyViaAppleScript,
1641
+ sendKeyViaAppleScript: (key, modifiers)=>sendKeyViaAppleScript(key, modifiers, this.options?.keyboardEventMode ?? 'logical'),
1546
1642
  runPhasedScroll,
1547
1643
  debug: (message)=>debugDevice(message)
1548
1644
  }));
@@ -1668,6 +1764,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
1668
1764
  }
1669
1765
  }
1670
1766
  });
1767
+ if (options?.keyboardShortcutDelay !== void 0 && (!Number.isFinite(options.keyboardShortcutDelay) || options.keyboardShortcutDelay < 0)) throw new Error('keyboardShortcutDelay must be a finite non-negative number');
1671
1768
  this.options = options;
1672
1769
  this.displayId = options?.displayId;
1673
1770
  this.useAppleScript = 'darwin' === process.platform && options?.keyboardDriver !== 'libnut';
@@ -2413,6 +2510,8 @@ function createLocalComputerDevice(opts) {
2413
2510
  keyboardTypeDelay: opts?.keyboardTypeDelay,
2414
2511
  inputStrategy: opts?.inputStrategy,
2415
2512
  keyboardDriver: opts?.keyboardDriver,
2513
+ keyboardEventMode: opts?.keyboardEventMode,
2514
+ keyboardShortcutDelay: opts?.keyboardShortcutDelay,
2416
2515
  headless: opts?.headless,
2417
2516
  xvfbResolution: opts?.xvfbResolution,
2418
2517
  keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
@@ -2470,6 +2569,11 @@ const computerInitArgShape = {
2470
2569
  headless: z.boolean().optional().describe('Start virtual display via Xvfb (Linux local mode only). Ignored when host is set.'),
2471
2570
  keyboardTypeDelay: 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.'),
2472
2571
  inputStrategy: z["enum"](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.'),
2572
+ keyboardEventMode: z["enum"]([
2573
+ 'logical',
2574
+ 'physical'
2575
+ ]).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.'),
2576
+ keyboardShortcutDelay: 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.'),
2473
2577
  host: z.string().optional().describe('RDP host (FQDN or IP). Set this to switch into RDP mode.'),
2474
2578
  port: z.number().optional().describe('RDP port (default 3389). Requires host.'),
2475
2579
  username: z.string().optional().describe('RDP username. Requires host.'),
@@ -2486,7 +2590,7 @@ const computerInitArgShape = {
2486
2590
  function adaptComputerInitArgs(extracted) {
2487
2591
  if (!extracted || 0 === Object.keys(extracted).length) return;
2488
2592
  if (extracted.host) {
2489
- const { displayId: _d, headless: _h, ...rdpFields } = extracted;
2593
+ const { displayId: _d, headless: _h, keyboardEventMode: _k, keyboardShortcutDelay: _s, ...rdpFields } = extracted;
2490
2594
  const host = normalizeRdpHost(extracted.host);
2491
2595
  return {
2492
2596
  mode: 'rdp',
@@ -2500,6 +2604,8 @@ function adaptComputerInitArgs(extracted) {
2500
2604
  headless: extracted.headless,
2501
2605
  keyboardTypeDelay: extracted.keyboardTypeDelay,
2502
2606
  inputStrategy: extracted.inputStrategy,
2607
+ keyboardEventMode: extracted.keyboardEventMode,
2608
+ keyboardShortcutDelay: extracted.keyboardShortcutDelay,
2503
2609
  ...extractAgentBehaviorInitArgs(extracted) ?? {}
2504
2610
  };
2505
2611
  }
@@ -2551,6 +2657,8 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2551
2657
  const headless = opts?.mode === 'local' ? opts.headless : void 0;
2552
2658
  const keyboardTypeDelay = opts?.keyboardTypeDelay;
2553
2659
  const inputStrategy = opts?.inputStrategy;
2660
+ const keyboardEventMode = opts?.mode === 'local' ? opts.keyboardEventMode : void 0;
2661
+ const keyboardShortcutDelay = opts?.mode === 'local' ? opts.keyboardShortcutDelay : void 0;
2554
2662
  agent_tools_debug('Creating Computer agent with displayId:', displayId || 'primary');
2555
2663
  const agentOpts = {
2556
2664
  ...displayId ? {
@@ -2565,6 +2673,12 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2565
2673
  ...void 0 !== inputStrategy ? {
2566
2674
  inputStrategy
2567
2675
  } : {},
2676
+ ...void 0 !== keyboardEventMode ? {
2677
+ keyboardEventMode
2678
+ } : {},
2679
+ ...void 0 !== keyboardShortcutDelay ? {
2680
+ keyboardShortcutDelay
2681
+ } : {},
2568
2682
  ...this.options.keepXvfbAliveUntilProcessExit ? {
2569
2683
  keepXvfbAliveUntilProcessExit: true
2570
2684
  } : {},
@@ -2645,7 +2759,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2645
2759
  }
2646
2760
  }
2647
2761
  function version() {
2648
- const currentVersion = "1.12.5";
2762
+ const currentVersion = "1.12.6-beta-20260909033030.0";
2649
2763
  console.log(`@midscene/computer v${currentVersion}`);
2650
2764
  return currentVersion;
2651
2765
  }