@midscene/computer 1.10.0 → 1.10.1-beta-20260624112700.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
@@ -372,6 +372,42 @@ function sendKeyViaAppleScript(key, modifiers = []) {
372
372
  script
373
373
  ]);
374
374
  }
375
+ const POWERSHELL_TIMEOUT_MS = 15000;
376
+ const POWERSHELL_MAX_BUFFER = 67108864;
377
+ function escapePowershellSingleQuoted(value) {
378
+ return value.replace(/'/g, "''");
379
+ }
380
+ function runPowershell(script) {
381
+ const encoded = Buffer.from(script, 'utf16le').toString('base64');
382
+ return execFileSync('powershell.exe', [
383
+ '-NoProfile',
384
+ '-NonInteractive',
385
+ '-ExecutionPolicy',
386
+ 'Bypass',
387
+ '-EncodedCommand',
388
+ encoded
389
+ ], {
390
+ encoding: 'utf8',
391
+ timeout: POWERSHELL_TIMEOUT_MS,
392
+ maxBuffer: POWERSHELL_MAX_BUFFER,
393
+ windowsHide: true
394
+ });
395
+ }
396
+ function listWindowsDisplays() {
397
+ const script = `
398
+ Add-Type -AssemblyName System.Windows.Forms
399
+ $s = [System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
400
+ [PSCustomObject]@{ id = $_.DeviceName; name = $_.DeviceName; primary = $_.Primary }
401
+ }
402
+ ConvertTo-Json @($s) -Compress
403
+ `.trim();
404
+ const parsed = JSON.parse(runPowershell(script).trim());
405
+ return parsed.map((d)=>({
406
+ id: String(d.id),
407
+ name: d.name || String(d.id),
408
+ primary: d.primary || false
409
+ }));
410
+ }
375
411
  let device_libnut = null;
376
412
  let libnutLoadError = null;
377
413
  async function getLibnut() {
@@ -638,6 +674,7 @@ class ComputerDevice {
638
674
  }
639
675
  static async listDisplays() {
640
676
  try {
677
+ if ('win32' === process.platform) return listWindowsDisplays();
641
678
  const displays = await screenshot_desktop.listDisplays();
642
679
  return displays.map((d)=>({
643
680
  id: String(d.id),
@@ -695,7 +732,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
695
732
  }
696
733
  async healthCheck() {
697
734
  console.log('[HealthCheck] Starting health check...');
698
- console.log("[HealthCheck] @midscene/computer v1.10.0");
735
+ console.log("[HealthCheck] @midscene/computer v1.10.1-beta-20260624112700.0");
699
736
  console.log('[HealthCheck] Taking screenshot...');
700
737
  const screenshotTimeout = 15000;
701
738
  let timeoutId;
@@ -764,6 +801,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
764
801
  debugDevice('Taking screenshot', {
765
802
  displayId: this.displayId
766
803
  });
804
+ if ('win32' === process.platform) return this.screenshotViaPowershell();
767
805
  const options = {
768
806
  format: 'png'
769
807
  };
@@ -797,6 +835,40 @@ Please follow these steps:
797
835
  Original error: ${lastRawMessage}`);
798
836
  throw new Error(`Failed to take screenshot: ${lastRawMessage}`);
799
837
  }
838
+ screenshotViaPowershell() {
839
+ const deviceName = this.displayId ? String(this.displayId) : '';
840
+ const target = deviceName ? `[System.Windows.Forms.Screen]::AllScreens | Where-Object { $_.DeviceName -eq '${escapePowershellSingleQuoted(deviceName)}' } | Select-Object -First 1` : '$null';
841
+ const script = `
842
+ $ErrorActionPreference = 'Stop'
843
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
844
+ Add-Type @"
845
+ using System;
846
+ using System.Runtime.InteropServices;
847
+ public class NutDpi { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); }
848
+ "@
849
+ [NutDpi]::SetProcessDPIAware() | Out-Null
850
+ $screen = ${target}
851
+ if (-not $screen) { $screen = [System.Windows.Forms.Screen]::PrimaryScreen }
852
+ $b = $screen.Bounds
853
+ $bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height)
854
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
855
+ $g.CopyFromScreen($b.X, $b.Y, 0, 0, $bmp.Size)
856
+ $ms = New-Object System.IO.MemoryStream
857
+ $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
858
+ [Console]::Out.Write([Convert]::ToBase64String($ms.ToArray()))
859
+ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
860
+ `.trim();
861
+ let stdout;
862
+ try {
863
+ stdout = runPowershell(script);
864
+ } catch (error) {
865
+ const message = error instanceof Error ? error.message : String(error);
866
+ throw new Error(`Failed to take screenshot on Windows: ${message}`);
867
+ }
868
+ const body = stdout.trim();
869
+ if (!body) throw new Error('Failed to take screenshot on Windows: PowerShell returned no image data');
870
+ return createImgBase64ByFormat('png', body);
871
+ }
800
872
  async size() {
801
873
  if (this.displayGeometry) return {
802
874
  width: Math.round(this.displayGeometry.bounds.width),
@@ -2058,7 +2130,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2058
2130
  const tools = new ComputerMidsceneTools();
2059
2131
  runToolsCLI(tools, 'midscene-computer', {
2060
2132
  stripPrefix: 'computer_',
2061
- version: "1.10.0",
2133
+ version: "1.10.1-beta-20260624112700.0",
2062
2134
  extraCommands: createReportCliCommands()
2063
2135
  }).catch((e)=>{
2064
2136
  process.exit(reportCLIError(e));
package/dist/es/index.mjs CHANGED
@@ -372,6 +372,42 @@ function sendKeyViaAppleScript(key, modifiers = []) {
372
372
  script
373
373
  ]);
374
374
  }
375
+ const POWERSHELL_TIMEOUT_MS = 15000;
376
+ const POWERSHELL_MAX_BUFFER = 67108864;
377
+ function escapePowershellSingleQuoted(value) {
378
+ return value.replace(/'/g, "''");
379
+ }
380
+ function runPowershell(script) {
381
+ const encoded = Buffer.from(script, 'utf16le').toString('base64');
382
+ return execFileSync('powershell.exe', [
383
+ '-NoProfile',
384
+ '-NonInteractive',
385
+ '-ExecutionPolicy',
386
+ 'Bypass',
387
+ '-EncodedCommand',
388
+ encoded
389
+ ], {
390
+ encoding: 'utf8',
391
+ timeout: POWERSHELL_TIMEOUT_MS,
392
+ maxBuffer: POWERSHELL_MAX_BUFFER,
393
+ windowsHide: true
394
+ });
395
+ }
396
+ function listWindowsDisplays() {
397
+ const script = `
398
+ Add-Type -AssemblyName System.Windows.Forms
399
+ $s = [System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
400
+ [PSCustomObject]@{ id = $_.DeviceName; name = $_.DeviceName; primary = $_.Primary }
401
+ }
402
+ ConvertTo-Json @($s) -Compress
403
+ `.trim();
404
+ const parsed = JSON.parse(runPowershell(script).trim());
405
+ return parsed.map((d)=>({
406
+ id: String(d.id),
407
+ name: d.name || String(d.id),
408
+ primary: d.primary || false
409
+ }));
410
+ }
375
411
  let device_libnut = null;
376
412
  let libnutLoadError = null;
377
413
  async function getLibnut() {
@@ -638,6 +674,7 @@ class ComputerDevice {
638
674
  }
639
675
  static async listDisplays() {
640
676
  try {
677
+ if ('win32' === process.platform) return listWindowsDisplays();
641
678
  const displays = await screenshot_desktop.listDisplays();
642
679
  return displays.map((d)=>({
643
680
  id: String(d.id),
@@ -695,7 +732,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
695
732
  }
696
733
  async healthCheck() {
697
734
  console.log('[HealthCheck] Starting health check...');
698
- console.log("[HealthCheck] @midscene/computer v1.10.0");
735
+ console.log("[HealthCheck] @midscene/computer v1.10.1-beta-20260624112700.0");
699
736
  console.log('[HealthCheck] Taking screenshot...');
700
737
  const screenshotTimeout = 15000;
701
738
  let timeoutId;
@@ -764,6 +801,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
764
801
  debugDevice('Taking screenshot', {
765
802
  displayId: this.displayId
766
803
  });
804
+ if ('win32' === process.platform) return this.screenshotViaPowershell();
767
805
  const options = {
768
806
  format: 'png'
769
807
  };
@@ -797,6 +835,40 @@ Please follow these steps:
797
835
  Original error: ${lastRawMessage}`);
798
836
  throw new Error(`Failed to take screenshot: ${lastRawMessage}`);
799
837
  }
838
+ screenshotViaPowershell() {
839
+ const deviceName = this.displayId ? String(this.displayId) : '';
840
+ const target = deviceName ? `[System.Windows.Forms.Screen]::AllScreens | Where-Object { $_.DeviceName -eq '${escapePowershellSingleQuoted(deviceName)}' } | Select-Object -First 1` : '$null';
841
+ const script = `
842
+ $ErrorActionPreference = 'Stop'
843
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
844
+ Add-Type @"
845
+ using System;
846
+ using System.Runtime.InteropServices;
847
+ public class NutDpi { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); }
848
+ "@
849
+ [NutDpi]::SetProcessDPIAware() | Out-Null
850
+ $screen = ${target}
851
+ if (-not $screen) { $screen = [System.Windows.Forms.Screen]::PrimaryScreen }
852
+ $b = $screen.Bounds
853
+ $bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height)
854
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
855
+ $g.CopyFromScreen($b.X, $b.Y, 0, 0, $bmp.Size)
856
+ $ms = New-Object System.IO.MemoryStream
857
+ $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
858
+ [Console]::Out.Write([Convert]::ToBase64String($ms.ToArray()))
859
+ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
860
+ `.trim();
861
+ let stdout;
862
+ try {
863
+ stdout = runPowershell(script);
864
+ } catch (error) {
865
+ const message = error instanceof Error ? error.message : String(error);
866
+ throw new Error(`Failed to take screenshot on Windows: ${message}`);
867
+ }
868
+ const body = stdout.trim();
869
+ if (!body) throw new Error('Failed to take screenshot on Windows: PowerShell returned no image data');
870
+ return createImgBase64ByFormat('png', body);
871
+ }
800
872
  async size() {
801
873
  if (this.displayGeometry) return {
802
874
  width: Math.round(this.displayGeometry.bounds.width),
@@ -2099,7 +2171,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
2099
2171
  }
2100
2172
  }
2101
2173
  function version() {
2102
- const currentVersion = "1.10.0";
2174
+ const currentVersion = "1.10.1-beta-20260624112700.0";
2103
2175
  console.log(`@midscene/computer v${currentVersion}`);
2104
2176
  return currentVersion;
2105
2177
  }
package/dist/lib/cli.js CHANGED
@@ -398,6 +398,42 @@ function sendKeyViaAppleScript(key, modifiers = []) {
398
398
  script
399
399
  ]);
400
400
  }
401
+ const POWERSHELL_TIMEOUT_MS = 15000;
402
+ const POWERSHELL_MAX_BUFFER = 67108864;
403
+ function escapePowershellSingleQuoted(value) {
404
+ return value.replace(/'/g, "''");
405
+ }
406
+ function runPowershell(script) {
407
+ const encoded = Buffer.from(script, 'utf16le').toString('base64');
408
+ return (0, external_node_child_process_namespaceObject.execFileSync)('powershell.exe', [
409
+ '-NoProfile',
410
+ '-NonInteractive',
411
+ '-ExecutionPolicy',
412
+ 'Bypass',
413
+ '-EncodedCommand',
414
+ encoded
415
+ ], {
416
+ encoding: 'utf8',
417
+ timeout: POWERSHELL_TIMEOUT_MS,
418
+ maxBuffer: POWERSHELL_MAX_BUFFER,
419
+ windowsHide: true
420
+ });
421
+ }
422
+ function listWindowsDisplays() {
423
+ const script = `
424
+ Add-Type -AssemblyName System.Windows.Forms
425
+ $s = [System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
426
+ [PSCustomObject]@{ id = $_.DeviceName; name = $_.DeviceName; primary = $_.Primary }
427
+ }
428
+ ConvertTo-Json @($s) -Compress
429
+ `.trim();
430
+ const parsed = JSON.parse(runPowershell(script).trim());
431
+ return parsed.map((d)=>({
432
+ id: String(d.id),
433
+ name: d.name || String(d.id),
434
+ primary: d.primary || false
435
+ }));
436
+ }
401
437
  let device_libnut = null;
402
438
  let libnutLoadError = null;
403
439
  async function getLibnut() {
@@ -664,6 +700,7 @@ class ComputerDevice {
664
700
  }
665
701
  static async listDisplays() {
666
702
  try {
703
+ if ('win32' === process.platform) return listWindowsDisplays();
667
704
  const displays = await external_screenshot_desktop_default().listDisplays();
668
705
  return displays.map((d)=>({
669
706
  id: String(d.id),
@@ -721,7 +758,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
721
758
  }
722
759
  async healthCheck() {
723
760
  console.log('[HealthCheck] Starting health check...');
724
- console.log("[HealthCheck] @midscene/computer v1.10.0");
761
+ console.log("[HealthCheck] @midscene/computer v1.10.1-beta-20260624112700.0");
725
762
  console.log('[HealthCheck] Taking screenshot...');
726
763
  const screenshotTimeout = 15000;
727
764
  let timeoutId;
@@ -790,6 +827,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
790
827
  debugDevice('Taking screenshot', {
791
828
  displayId: this.displayId
792
829
  });
830
+ if ('win32' === process.platform) return this.screenshotViaPowershell();
793
831
  const options = {
794
832
  format: 'png'
795
833
  };
@@ -823,6 +861,40 @@ Please follow these steps:
823
861
  Original error: ${lastRawMessage}`);
824
862
  throw new Error(`Failed to take screenshot: ${lastRawMessage}`);
825
863
  }
864
+ screenshotViaPowershell() {
865
+ const deviceName = this.displayId ? String(this.displayId) : '';
866
+ const target = deviceName ? `[System.Windows.Forms.Screen]::AllScreens | Where-Object { $_.DeviceName -eq '${escapePowershellSingleQuoted(deviceName)}' } | Select-Object -First 1` : '$null';
867
+ const script = `
868
+ $ErrorActionPreference = 'Stop'
869
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
870
+ Add-Type @"
871
+ using System;
872
+ using System.Runtime.InteropServices;
873
+ public class NutDpi { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); }
874
+ "@
875
+ [NutDpi]::SetProcessDPIAware() | Out-Null
876
+ $screen = ${target}
877
+ if (-not $screen) { $screen = [System.Windows.Forms.Screen]::PrimaryScreen }
878
+ $b = $screen.Bounds
879
+ $bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height)
880
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
881
+ $g.CopyFromScreen($b.X, $b.Y, 0, 0, $bmp.Size)
882
+ $ms = New-Object System.IO.MemoryStream
883
+ $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
884
+ [Console]::Out.Write([Convert]::ToBase64String($ms.ToArray()))
885
+ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
886
+ `.trim();
887
+ let stdout;
888
+ try {
889
+ stdout = runPowershell(script);
890
+ } catch (error) {
891
+ const message = error instanceof Error ? error.message : String(error);
892
+ throw new Error(`Failed to take screenshot on Windows: ${message}`);
893
+ }
894
+ const body = stdout.trim();
895
+ if (!body) throw new Error('Failed to take screenshot on Windows: PowerShell returned no image data');
896
+ return (0, img_namespaceObject.createImgBase64ByFormat)('png', body);
897
+ }
826
898
  async size() {
827
899
  if (this.displayGeometry) return {
828
900
  width: Math.round(this.displayGeometry.bounds.width),
@@ -2085,7 +2157,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
2085
2157
  const tools = new ComputerMidsceneTools();
2086
2158
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
2087
2159
  stripPrefix: 'computer_',
2088
- version: "1.10.0",
2160
+ version: "1.10.1-beta-20260624112700.0",
2089
2161
  extraCommands: (0, core_namespaceObject.createReportCliCommands)()
2090
2162
  }).catch((e)=>{
2091
2163
  process.exit((0, cli_namespaceObject.reportCLIError)(e));
package/dist/lib/index.js CHANGED
@@ -424,6 +424,42 @@ function sendKeyViaAppleScript(key, modifiers = []) {
424
424
  script
425
425
  ]);
426
426
  }
427
+ const POWERSHELL_TIMEOUT_MS = 15000;
428
+ const POWERSHELL_MAX_BUFFER = 67108864;
429
+ function escapePowershellSingleQuoted(value) {
430
+ return value.replace(/'/g, "''");
431
+ }
432
+ function runPowershell(script) {
433
+ const encoded = Buffer.from(script, 'utf16le').toString('base64');
434
+ return (0, external_node_child_process_namespaceObject.execFileSync)('powershell.exe', [
435
+ '-NoProfile',
436
+ '-NonInteractive',
437
+ '-ExecutionPolicy',
438
+ 'Bypass',
439
+ '-EncodedCommand',
440
+ encoded
441
+ ], {
442
+ encoding: 'utf8',
443
+ timeout: POWERSHELL_TIMEOUT_MS,
444
+ maxBuffer: POWERSHELL_MAX_BUFFER,
445
+ windowsHide: true
446
+ });
447
+ }
448
+ function listWindowsDisplays() {
449
+ const script = `
450
+ Add-Type -AssemblyName System.Windows.Forms
451
+ $s = [System.Windows.Forms.Screen]::AllScreens | ForEach-Object {
452
+ [PSCustomObject]@{ id = $_.DeviceName; name = $_.DeviceName; primary = $_.Primary }
453
+ }
454
+ ConvertTo-Json @($s) -Compress
455
+ `.trim();
456
+ const parsed = JSON.parse(runPowershell(script).trim());
457
+ return parsed.map((d)=>({
458
+ id: String(d.id),
459
+ name: d.name || String(d.id),
460
+ primary: d.primary || false
461
+ }));
462
+ }
427
463
  let device_libnut = null;
428
464
  let libnutLoadError = null;
429
465
  async function getLibnut() {
@@ -690,6 +726,7 @@ class ComputerDevice {
690
726
  }
691
727
  static async listDisplays() {
692
728
  try {
729
+ if ('win32' === process.platform) return listWindowsDisplays();
693
730
  const displays = await external_screenshot_desktop_default().listDisplays();
694
731
  return displays.map((d)=>({
695
732
  id: String(d.id),
@@ -747,7 +784,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
747
784
  }
748
785
  async healthCheck() {
749
786
  console.log('[HealthCheck] Starting health check...');
750
- console.log("[HealthCheck] @midscene/computer v1.10.0");
787
+ console.log("[HealthCheck] @midscene/computer v1.10.1-beta-20260624112700.0");
751
788
  console.log('[HealthCheck] Taking screenshot...');
752
789
  const screenshotTimeout = 15000;
753
790
  let timeoutId;
@@ -816,6 +853,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
816
853
  debugDevice('Taking screenshot', {
817
854
  displayId: this.displayId
818
855
  });
856
+ if ('win32' === process.platform) return this.screenshotViaPowershell();
819
857
  const options = {
820
858
  format: 'png'
821
859
  };
@@ -849,6 +887,40 @@ Please follow these steps:
849
887
  Original error: ${lastRawMessage}`);
850
888
  throw new Error(`Failed to take screenshot: ${lastRawMessage}`);
851
889
  }
890
+ screenshotViaPowershell() {
891
+ const deviceName = this.displayId ? String(this.displayId) : '';
892
+ const target = deviceName ? `[System.Windows.Forms.Screen]::AllScreens | Where-Object { $_.DeviceName -eq '${escapePowershellSingleQuoted(deviceName)}' } | Select-Object -First 1` : '$null';
893
+ const script = `
894
+ $ErrorActionPreference = 'Stop'
895
+ Add-Type -AssemblyName System.Windows.Forms, System.Drawing
896
+ Add-Type @"
897
+ using System;
898
+ using System.Runtime.InteropServices;
899
+ public class NutDpi { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); }
900
+ "@
901
+ [NutDpi]::SetProcessDPIAware() | Out-Null
902
+ $screen = ${target}
903
+ if (-not $screen) { $screen = [System.Windows.Forms.Screen]::PrimaryScreen }
904
+ $b = $screen.Bounds
905
+ $bmp = New-Object System.Drawing.Bitmap($b.Width, $b.Height)
906
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
907
+ $g.CopyFromScreen($b.X, $b.Y, 0, 0, $bmp.Size)
908
+ $ms = New-Object System.IO.MemoryStream
909
+ $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
910
+ [Console]::Out.Write([Convert]::ToBase64String($ms.ToArray()))
911
+ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
912
+ `.trim();
913
+ let stdout;
914
+ try {
915
+ stdout = runPowershell(script);
916
+ } catch (error) {
917
+ const message = error instanceof Error ? error.message : String(error);
918
+ throw new Error(`Failed to take screenshot on Windows: ${message}`);
919
+ }
920
+ const body = stdout.trim();
921
+ if (!body) throw new Error('Failed to take screenshot on Windows: PowerShell returned no image data');
922
+ return (0, img_namespaceObject.createImgBase64ByFormat)('png', body);
923
+ }
852
924
  async size() {
853
925
  if (this.displayGeometry) return {
854
926
  width: Math.round(this.displayGeometry.bounds.width),
@@ -2157,7 +2229,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
2157
2229
  }
2158
2230
  const env_namespaceObject = require("@midscene/shared/env");
2159
2231
  function version() {
2160
- const currentVersion = "1.10.0";
2232
+ const currentVersion = "1.10.1-beta-20260624112700.0";
2161
2233
  console.log(`@midscene/computer v${currentVersion}`);
2162
2234
  return currentVersion;
2163
2235
  }
@@ -101,6 +101,20 @@ export declare class ComputerDevice implements AbstractInterface {
101
101
  */
102
102
  private isRunningAsAdmin;
103
103
  screenshotBase64(): Promise<string>;
104
+ /**
105
+ * Windows screenshot path that bypasses screenshot-desktop's polyglot .bat
106
+ * (see screenshotBase64 for the rationale). Captures via PowerShell +
107
+ * System.Drawing, which honors `displayId` by matching the monitor's
108
+ * DeviceName and captures in virtual-desktop coordinates, so secondary
109
+ * displays — including those at negative offsets — are supported.
110
+ *
111
+ * Note: the script makes the process system-DPI-aware (SetProcessDPIAware)
112
+ * so captures return physical pixels. On mixed-DPI multi-monitor setups a
113
+ * non-primary monitor may still be off by its per-monitor scale factor;
114
+ * system DPI awareness covers the common single-scale and uniform-scale
115
+ * cases that #2150 reports.
116
+ */
117
+ private screenshotViaPowershell;
104
118
  size(): Promise<Size>;
105
119
  private toGlobalPoint;
106
120
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/computer",
3
- "version": "1.10.0",
3
+ "version": "1.10.1-beta-20260624112700.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/shared": "1.10.0",
37
- "@midscene/core": "1.10.0"
36
+ "@midscene/shared": "1.10.1-beta-20260624112700.0",
37
+ "@midscene/core": "1.10.1-beta-20260624112700.0"
38
38
  },
39
39
  "optionalDependencies": {
40
40
  "node-mac-permissions": "2.5.0"