@midscene/computer 1.10.7 → 1.10.8-beta-20260723091821.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/bin/darwin/rdp-helper +0 -0
- package/bin/linux/rdp-helper +0 -0
- package/dist/es/cli.mjs +2 -2
- package/dist/es/index.mjs +2 -2
- package/dist/lib/cli.js +2 -2
- package/dist/lib/index.js +2 -2
- package/native/rdp/CMakeLists.txt +16 -0
- package/native/rdp/include/rdp_helper_session.hpp +9 -1
- package/native/rdp/include/rdp_helper_session_policy.hpp +41 -0
- package/native/rdp/src/session.cpp +34 -25
- package/native/rdp/tests/session_policy_test.cpp +77 -0
- package/package.json +3 -3
package/bin/darwin/rdp-helper
CHANGED
|
Binary file
|
package/bin/linux/rdp-helper
CHANGED
|
Binary file
|
package/dist/es/cli.mjs
CHANGED
|
@@ -750,7 +750,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
750
750
|
}
|
|
751
751
|
async healthCheck() {
|
|
752
752
|
console.log('[HealthCheck] Starting health check...');
|
|
753
|
-
console.log("[HealthCheck] @midscene/computer v1.10.
|
|
753
|
+
console.log("[HealthCheck] @midscene/computer v1.10.8-beta-20260723091821.0");
|
|
754
754
|
console.log('[HealthCheck] Taking screenshot...');
|
|
755
755
|
const screenshotTimeout = 15000;
|
|
756
756
|
let timeoutId;
|
|
@@ -2148,7 +2148,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2148
2148
|
const tools = new ComputerMidsceneTools();
|
|
2149
2149
|
runToolsCLI(tools, 'midscene-computer', {
|
|
2150
2150
|
stripPrefix: 'computer_',
|
|
2151
|
-
version: "1.10.
|
|
2151
|
+
version: "1.10.8-beta-20260723091821.0",
|
|
2152
2152
|
extraCommands: createReportCliCommands()
|
|
2153
2153
|
}).catch((e)=>{
|
|
2154
2154
|
process.exit(reportCLIError(e));
|
package/dist/es/index.mjs
CHANGED
|
@@ -750,7 +750,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
750
750
|
}
|
|
751
751
|
async healthCheck() {
|
|
752
752
|
console.log('[HealthCheck] Starting health check...');
|
|
753
|
-
console.log("[HealthCheck] @midscene/computer v1.10.
|
|
753
|
+
console.log("[HealthCheck] @midscene/computer v1.10.8-beta-20260723091821.0");
|
|
754
754
|
console.log('[HealthCheck] Taking screenshot...');
|
|
755
755
|
const screenshotTimeout = 15000;
|
|
756
756
|
let timeoutId;
|
|
@@ -2189,7 +2189,7 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2189
2189
|
}
|
|
2190
2190
|
}
|
|
2191
2191
|
function version() {
|
|
2192
|
-
const currentVersion = "1.10.
|
|
2192
|
+
const currentVersion = "1.10.8-beta-20260723091821.0";
|
|
2193
2193
|
console.log(`@midscene/computer v${currentVersion}`);
|
|
2194
2194
|
return currentVersion;
|
|
2195
2195
|
}
|
package/dist/lib/cli.js
CHANGED
|
@@ -776,7 +776,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
776
776
|
}
|
|
777
777
|
async healthCheck() {
|
|
778
778
|
console.log('[HealthCheck] Starting health check...');
|
|
779
|
-
console.log("[HealthCheck] @midscene/computer v1.10.
|
|
779
|
+
console.log("[HealthCheck] @midscene/computer v1.10.8-beta-20260723091821.0");
|
|
780
780
|
console.log('[HealthCheck] Taking screenshot...');
|
|
781
781
|
const screenshotTimeout = 15000;
|
|
782
782
|
let timeoutId;
|
|
@@ -2175,7 +2175,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2175
2175
|
const tools = new ComputerMidsceneTools();
|
|
2176
2176
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
|
|
2177
2177
|
stripPrefix: 'computer_',
|
|
2178
|
-
version: "1.10.
|
|
2178
|
+
version: "1.10.8-beta-20260723091821.0",
|
|
2179
2179
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
2180
2180
|
}).catch((e)=>{
|
|
2181
2181
|
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|
package/dist/lib/index.js
CHANGED
|
@@ -802,7 +802,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
802
802
|
}
|
|
803
803
|
async healthCheck() {
|
|
804
804
|
console.log('[HealthCheck] Starting health check...');
|
|
805
|
-
console.log("[HealthCheck] @midscene/computer v1.10.
|
|
805
|
+
console.log("[HealthCheck] @midscene/computer v1.10.8-beta-20260723091821.0");
|
|
806
806
|
console.log('[HealthCheck] Taking screenshot...');
|
|
807
807
|
const screenshotTimeout = 15000;
|
|
808
808
|
let timeoutId;
|
|
@@ -2247,7 +2247,7 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2247
2247
|
}
|
|
2248
2248
|
const env_namespaceObject = require("@midscene/shared/env");
|
|
2249
2249
|
function version() {
|
|
2250
|
-
const currentVersion = "1.10.
|
|
2250
|
+
const currentVersion = "1.10.8-beta-20260723091821.0";
|
|
2251
2251
|
console.log(`@midscene/computer v${currentVersion}`);
|
|
2252
2252
|
return currentVersion;
|
|
2253
2253
|
}
|
|
@@ -66,16 +66,32 @@ if(BUILD_TESTING)
|
|
|
66
66
|
tests/connection_policy_test.cpp
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
+
add_executable(
|
|
70
|
+
rdp-session-policy-test
|
|
71
|
+
tests/session_policy_test.cpp
|
|
72
|
+
)
|
|
73
|
+
|
|
69
74
|
target_include_directories(
|
|
70
75
|
rdp-connection-policy-test
|
|
71
76
|
PRIVATE
|
|
72
77
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
|
73
78
|
)
|
|
74
79
|
|
|
80
|
+
target_include_directories(
|
|
81
|
+
rdp-session-policy-test
|
|
82
|
+
PRIVATE
|
|
83
|
+
${CMAKE_CURRENT_SOURCE_DIR}/include
|
|
84
|
+
)
|
|
85
|
+
|
|
75
86
|
add_test(
|
|
76
87
|
NAME rdp-connection-policy-test
|
|
77
88
|
COMMAND rdp-connection-policy-test
|
|
78
89
|
)
|
|
90
|
+
|
|
91
|
+
add_test(
|
|
92
|
+
NAME rdp-session-policy-test
|
|
93
|
+
COMMAND rdp-session-policy-test
|
|
94
|
+
)
|
|
79
95
|
endif()
|
|
80
96
|
|
|
81
97
|
if(APPLE)
|
|
@@ -77,6 +77,9 @@ class FreeRdpSessionTransport final : public SessionTransport {
|
|
|
77
77
|
// Records that at least one paint has reached the local framebuffer and
|
|
78
78
|
// wakes Connect().
|
|
79
79
|
void MarkFramePainted(std::optional<RawFrame> first_frame = std::nullopt);
|
|
80
|
+
// Records a framebuffer update even when it is too blank or uniform to count
|
|
81
|
+
// as the first informative frame.
|
|
82
|
+
void MarkFramebufferUpdated();
|
|
80
83
|
bool HasFramePainted() const;
|
|
81
84
|
BOOL CallOriginalEndPaint(rdpContext* context);
|
|
82
85
|
// Mark the session as no longer active and wake any first-frame waiter.
|
|
@@ -98,6 +101,9 @@ class FreeRdpSessionTransport final : public SessionTransport {
|
|
|
98
101
|
// RDP session exposes a zero-filled (all black) buffer until the first paint
|
|
99
102
|
// is processed, so screenshots taken before this is > 0 would be blank.
|
|
100
103
|
std::atomic<uint64_t> frames_painted_{0};
|
|
104
|
+
// Number of valid framebuffer updates observed before the first informative
|
|
105
|
+
// frame. This distinguishes a silent desktop from a blank or locked one.
|
|
106
|
+
std::atomic<uint64_t> framebuffer_updates_{0};
|
|
101
107
|
// Tracks whether the session is still alive while Connect() waits for the
|
|
102
108
|
// first frame, so a drop during that window wakes the wait immediately
|
|
103
109
|
// instead of stalling until the timeout.
|
|
@@ -114,7 +120,9 @@ class FreeRdpSessionTransport final : public SessionTransport {
|
|
|
114
120
|
|
|
115
121
|
void ResetStateLocked();
|
|
116
122
|
void ClearSessionErrorLocked();
|
|
117
|
-
|
|
123
|
+
bool RecordEventLoopFailureIfActive(bool operation_failed,
|
|
124
|
+
bool disconnect_requested,
|
|
125
|
+
std::string message);
|
|
118
126
|
std::string LastFreeRdpErrorLocked() const;
|
|
119
127
|
void StopInstance(bool preserve_session_error);
|
|
120
128
|
void EventLoop();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <cstdint>
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <string_view>
|
|
6
|
+
|
|
7
|
+
namespace midscene::rdp {
|
|
8
|
+
|
|
9
|
+
constexpr bool ShouldReportEventLoopFailure(bool operation_failed,
|
|
10
|
+
bool disconnect_requested,
|
|
11
|
+
bool session_running,
|
|
12
|
+
bool session_connected) noexcept {
|
|
13
|
+
return (operation_failed || disconnect_requested) && session_running &&
|
|
14
|
+
session_connected;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
inline std::string BuildFirstFrameTimeoutMessage(
|
|
18
|
+
uint64_t framebuffer_updates,
|
|
19
|
+
std::string_view failure_reason) {
|
|
20
|
+
std::string message;
|
|
21
|
+
if (framebuffer_updates == 0) {
|
|
22
|
+
message =
|
|
23
|
+
"Connected to the RDP server but received no desktop frame within "
|
|
24
|
+
"timeout; the remote desktop may be blank or locked";
|
|
25
|
+
} else {
|
|
26
|
+
message = "Connected to the RDP server and received " +
|
|
27
|
+
std::to_string(framebuffer_updates) + " framebuffer update";
|
|
28
|
+
if (framebuffer_updates != 1) {
|
|
29
|
+
message += "s";
|
|
30
|
+
}
|
|
31
|
+
message +=
|
|
32
|
+
", but none passed the informative-frame check within timeout; the "
|
|
33
|
+
"remote desktop may be blank, locked, or still loading";
|
|
34
|
+
}
|
|
35
|
+
if (!failure_reason.empty()) {
|
|
36
|
+
message += " (" + std::string(failure_reason) + ")";
|
|
37
|
+
}
|
|
38
|
+
return message;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
} // namespace midscene::rdp
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
#include <winpr/synch.h>
|
|
38
38
|
|
|
39
39
|
#include "rdp_helper_connection_policy.hpp"
|
|
40
|
+
#include "rdp_helper_session_policy.hpp"
|
|
40
41
|
|
|
41
42
|
namespace midscene::rdp {
|
|
42
43
|
|
|
@@ -512,6 +513,7 @@ BOOL MidsceneEndPaint(rdpContext* context) {
|
|
|
512
513
|
ok = typed_context->owner->CallOriginalEndPaint(context);
|
|
513
514
|
const bool already_painted = typed_context->owner->HasFramePainted();
|
|
514
515
|
if (ok && framebuffer_invalidated) {
|
|
516
|
+
typed_context->owner->MarkFramebufferUpdated();
|
|
515
517
|
if (already_painted) {
|
|
516
518
|
typed_context->owner->MarkFramePainted();
|
|
517
519
|
} else if (auto first_frame = CaptureInformativeFramebuffer(context);
|
|
@@ -978,6 +980,7 @@ ConnectionInfo FreeRdpSessionTransport::Connect(const ConnectionConfig& config)
|
|
|
978
980
|
mouse_x_ = 0;
|
|
979
981
|
mouse_y_ = 0;
|
|
980
982
|
frames_painted_.store(0, std::memory_order_relaxed);
|
|
983
|
+
framebuffer_updates_.store(0, std::memory_order_relaxed);
|
|
981
984
|
{
|
|
982
985
|
std::lock_guard<std::mutex> frame_lock(frame_mutex_);
|
|
983
986
|
first_frame_.reset();
|
|
@@ -1061,18 +1064,15 @@ ConnectionInfo FreeRdpSessionTransport::Connect(const ConnectionConfig& config)
|
|
|
1061
1064
|
|
|
1062
1065
|
if (!painted) {
|
|
1063
1066
|
std::string reason;
|
|
1067
|
+
const uint64_t framebuffer_updates =
|
|
1068
|
+
framebuffer_updates_.load(std::memory_order_relaxed);
|
|
1064
1069
|
{
|
|
1065
1070
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
1066
1071
|
reason = connected_ ? std::string() : LastFreeRdpErrorLocked();
|
|
1067
1072
|
}
|
|
1068
1073
|
StopInstance(false);
|
|
1069
|
-
std::
|
|
1070
|
-
|
|
1071
|
-
"timeout; the remote desktop may be blank or locked";
|
|
1072
|
-
if (!reason.empty()) {
|
|
1073
|
-
message += " (" + reason + ")";
|
|
1074
|
-
}
|
|
1075
|
-
throw std::runtime_error(message);
|
|
1074
|
+
throw std::runtime_error(
|
|
1075
|
+
BuildFirstFrameTimeoutMessage(framebuffer_updates, reason));
|
|
1076
1076
|
}
|
|
1077
1077
|
|
|
1078
1078
|
return info;
|
|
@@ -1357,6 +1357,7 @@ void FreeRdpSessionTransport::ResetStateLocked() {
|
|
|
1357
1357
|
connected_ = false;
|
|
1358
1358
|
gdi_initialized_ = false;
|
|
1359
1359
|
frames_painted_.store(0, std::memory_order_relaxed);
|
|
1360
|
+
framebuffer_updates_.store(0, std::memory_order_relaxed);
|
|
1360
1361
|
{
|
|
1361
1362
|
std::lock_guard<std::mutex> frame_lock(frame_mutex_);
|
|
1362
1363
|
first_frame_.reset();
|
|
@@ -1402,6 +1403,10 @@ void FreeRdpSessionTransport::MarkFramePainted(
|
|
|
1402
1403
|
frame_cv_.notify_all();
|
|
1403
1404
|
}
|
|
1404
1405
|
|
|
1406
|
+
void FreeRdpSessionTransport::MarkFramebufferUpdated() {
|
|
1407
|
+
framebuffer_updates_.fetch_add(1, std::memory_order_relaxed);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1405
1410
|
bool FreeRdpSessionTransport::HasFramePainted() const {
|
|
1406
1411
|
return frames_painted_.load(std::memory_order_relaxed) > 0;
|
|
1407
1412
|
}
|
|
@@ -1418,12 +1423,22 @@ void FreeRdpSessionTransport::ClearSessionErrorLocked() {
|
|
|
1418
1423
|
last_error_.reset();
|
|
1419
1424
|
}
|
|
1420
1425
|
|
|
1421
|
-
|
|
1426
|
+
bool FreeRdpSessionTransport::RecordEventLoopFailureIfActive(
|
|
1427
|
+
bool operation_failed,
|
|
1428
|
+
bool disconnect_requested,
|
|
1429
|
+
std::string message) {
|
|
1422
1430
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
1431
|
+
if (!ShouldReportEventLoopFailure(operation_failed, disconnect_requested,
|
|
1432
|
+
running_, connected_)) {
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1423
1435
|
last_error_ = ErrorPayload{
|
|
1424
|
-
|
|
1436
|
+
"session_lost",
|
|
1425
1437
|
message.empty() ? "RDP session was lost" : std::move(message),
|
|
1426
1438
|
};
|
|
1439
|
+
connected_ = false;
|
|
1440
|
+
running_ = false;
|
|
1441
|
+
return true;
|
|
1427
1442
|
}
|
|
1428
1443
|
|
|
1429
1444
|
std::string FreeRdpSessionTransport::LastFreeRdpErrorLocked() const {
|
|
@@ -1522,11 +1537,9 @@ void FreeRdpSessionTransport::EventLoop() {
|
|
|
1522
1537
|
const DWORD count = freerdp_get_event_handles(
|
|
1523
1538
|
instance->context, handles, static_cast<DWORD>(std::size(handles)));
|
|
1524
1539
|
if (count == 0) {
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
connected_ = false;
|
|
1529
|
-
running_ = false;
|
|
1540
|
+
if (!RecordEventLoopFailureIfActive(
|
|
1541
|
+
true, false, "freerdp_get_event_handles returned no handles")) {
|
|
1542
|
+
return;
|
|
1530
1543
|
}
|
|
1531
1544
|
std::fprintf(stderr,
|
|
1532
1545
|
"RDP session event loop failed: freerdp_get_event_handles returned no handles\n");
|
|
@@ -1537,12 +1550,10 @@ void FreeRdpSessionTransport::EventLoop() {
|
|
|
1537
1550
|
|
|
1538
1551
|
const DWORD status = WaitForMultipleObjects(count, handles, FALSE, 100);
|
|
1539
1552
|
if (status == WAIT_FAILED) {
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
connected_ = false;
|
|
1545
|
-
running_ = false;
|
|
1553
|
+
if (!RecordEventLoopFailureIfActive(
|
|
1554
|
+
true, false,
|
|
1555
|
+
"WaitForMultipleObjects failed in the RDP event loop")) {
|
|
1556
|
+
return;
|
|
1546
1557
|
}
|
|
1547
1558
|
std::fprintf(stderr,
|
|
1548
1559
|
"RDP session event loop failed: WaitForMultipleObjects failed\n");
|
|
@@ -1568,11 +1579,9 @@ void FreeRdpSessionTransport::EventLoop() {
|
|
|
1568
1579
|
}
|
|
1569
1580
|
|
|
1570
1581
|
if (!ok || should_disconnect) {
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
connected_ = false;
|
|
1575
|
-
running_ = false;
|
|
1582
|
+
if (!RecordEventLoopFailureIfActive(!ok, should_disconnect,
|
|
1583
|
+
failure_reason)) {
|
|
1584
|
+
return;
|
|
1576
1585
|
}
|
|
1577
1586
|
std::fprintf(stderr, "RDP session event loop failed: %s\n",
|
|
1578
1587
|
failure_reason.c_str());
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#include <iostream>
|
|
2
|
+
#include <string>
|
|
3
|
+
#include <string_view>
|
|
4
|
+
|
|
5
|
+
#include "rdp_helper_session_policy.hpp"
|
|
6
|
+
|
|
7
|
+
namespace {
|
|
8
|
+
|
|
9
|
+
bool ExpectBool(std::string_view name, bool actual, bool expected) {
|
|
10
|
+
if (actual == expected) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
std::cerr << name << ": expected " << expected << ", actual=" << actual
|
|
15
|
+
<< '\n';
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
bool ExpectMessage(std::string_view name,
|
|
20
|
+
const std::string& actual,
|
|
21
|
+
std::string_view expected) {
|
|
22
|
+
if (actual == expected) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
std::cerr << name << ": expected \"" << expected << "\", actual=\""
|
|
27
|
+
<< actual << "\"\n";
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace
|
|
32
|
+
|
|
33
|
+
int main() {
|
|
34
|
+
bool passed = true;
|
|
35
|
+
passed &= ExpectBool(
|
|
36
|
+
"active transport failure",
|
|
37
|
+
midscene::rdp::ShouldReportEventLoopFailure(true, false, true, true),
|
|
38
|
+
true);
|
|
39
|
+
passed &= ExpectBool(
|
|
40
|
+
"intentional shutdown transport failure",
|
|
41
|
+
midscene::rdp::ShouldReportEventLoopFailure(true, false, false, false),
|
|
42
|
+
false);
|
|
43
|
+
passed &= ExpectBool(
|
|
44
|
+
"active server disconnect",
|
|
45
|
+
midscene::rdp::ShouldReportEventLoopFailure(false, true, true, true),
|
|
46
|
+
true);
|
|
47
|
+
passed &= ExpectBool(
|
|
48
|
+
"healthy active session",
|
|
49
|
+
midscene::rdp::ShouldReportEventLoopFailure(false, false, true, true),
|
|
50
|
+
false);
|
|
51
|
+
|
|
52
|
+
passed &= ExpectMessage(
|
|
53
|
+
"no framebuffer updates",
|
|
54
|
+
midscene::rdp::BuildFirstFrameTimeoutMessage(0, ""),
|
|
55
|
+
"Connected to the RDP server but received no desktop frame within "
|
|
56
|
+
"timeout; the remote desktop may be blank or locked");
|
|
57
|
+
passed &= ExpectMessage(
|
|
58
|
+
"non-informative framebuffer updates",
|
|
59
|
+
midscene::rdp::BuildFirstFrameTimeoutMessage(3, ""),
|
|
60
|
+
"Connected to the RDP server and received 3 framebuffer updates, but "
|
|
61
|
+
"none passed the informative-frame check within timeout; the remote "
|
|
62
|
+
"desktop may be blank, locked, or still loading");
|
|
63
|
+
passed &= ExpectMessage(
|
|
64
|
+
"single non-informative framebuffer update",
|
|
65
|
+
midscene::rdp::BuildFirstFrameTimeoutMessage(1, ""),
|
|
66
|
+
"Connected to the RDP server and received 1 framebuffer update, but "
|
|
67
|
+
"none passed the informative-frame check within timeout; the remote "
|
|
68
|
+
"desktop may be blank, locked, or still loading");
|
|
69
|
+
passed &= ExpectMessage(
|
|
70
|
+
"session loss reason",
|
|
71
|
+
midscene::rdp::BuildFirstFrameTimeoutMessage(
|
|
72
|
+
0, "ERRCONNECT_CONNECT_TRANSPORT_FAILED"),
|
|
73
|
+
"Connected to the RDP server but received no desktop frame within "
|
|
74
|
+
"timeout; the remote desktop may be blank or locked "
|
|
75
|
+
"(ERRCONNECT_CONNECT_TRANSPORT_FAILED)");
|
|
76
|
+
return passed ? 0 : 1;
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/computer",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.8-beta-20260723091821.0",
|
|
4
4
|
"description": "Midscene.js Computer Desktop Automation",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"@computer-use/libnut": "^4.2.0",
|
|
34
34
|
"clipboardy": "^4.0.0",
|
|
35
35
|
"screenshot-desktop": "^1.15.3",
|
|
36
|
-
"@midscene/core": "1.10.
|
|
37
|
-
"@midscene/shared": "1.10.
|
|
36
|
+
"@midscene/core": "1.10.8-beta-20260723091821.0",
|
|
37
|
+
"@midscene/shared": "1.10.8-beta-20260723091821.0"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
40
|
"node-mac-permissions": "2.5.0"
|