@midscene/computer 1.12.2-beta-20260828074555.0 → 1.12.2
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 +83 -30
- package/dist/es/index.mjs +80 -29
- package/dist/lib/cli.js +83 -30
- package/dist/lib/index.js +80 -29
- package/dist/types/index.d.ts +16 -1
- package/package.json +3 -3
package/dist/es/cli.mjs
CHANGED
|
@@ -185,7 +185,50 @@ class ComputerInputDriver {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
const debugXvfb = getDebug('computer:xvfb');
|
|
188
|
-
|
|
188
|
+
const xvfbCleanupMonitorScript = String.raw`
|
|
189
|
+
const parentPid = Number(process.argv[1]);
|
|
190
|
+
const xvfbPid = Number(process.argv[2]);
|
|
191
|
+
const timer = setInterval(() => {
|
|
192
|
+
try {
|
|
193
|
+
process.kill(xvfbPid, 0);
|
|
194
|
+
} catch {
|
|
195
|
+
clearInterval(timer);
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
process.kill(parentPid, 0);
|
|
200
|
+
return;
|
|
201
|
+
} catch {
|
|
202
|
+
// The owner is gone, so its X11 clients can no longer receive XIO errors.
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
process.kill(xvfbPid, 'SIGTERM');
|
|
206
|
+
} catch {
|
|
207
|
+
// Xvfb may have already exited.
|
|
208
|
+
}
|
|
209
|
+
clearInterval(timer);
|
|
210
|
+
}, 100);
|
|
211
|
+
`;
|
|
212
|
+
function scheduleXvfbStopAfterProcessExit(instance, parentPid = process.pid) {
|
|
213
|
+
const xvfbPid = instance.process.pid;
|
|
214
|
+
if (!xvfbPid) throw new Error('Cannot schedule Xvfb cleanup before its process starts');
|
|
215
|
+
const monitor = spawn(process.execPath, [
|
|
216
|
+
'-e',
|
|
217
|
+
xvfbCleanupMonitorScript,
|
|
218
|
+
String(parentPid),
|
|
219
|
+
String(xvfbPid)
|
|
220
|
+
], {
|
|
221
|
+
detached: true,
|
|
222
|
+
stdio: 'ignore'
|
|
223
|
+
});
|
|
224
|
+
monitor.on('error', (error)=>{
|
|
225
|
+
debugXvfb(`Xvfb cleanup monitor failed: ${error.message}`);
|
|
226
|
+
});
|
|
227
|
+
instance.process.unref();
|
|
228
|
+
monitor.unref();
|
|
229
|
+
return monitor;
|
|
230
|
+
}
|
|
231
|
+
function createXvfbSignalCleanup(cleanup, source = process) {
|
|
189
232
|
return ()=>{
|
|
190
233
|
if (!hasActiveCliInterruptWaiter(source)) cleanup();
|
|
191
234
|
};
|
|
@@ -736,18 +779,21 @@ class ComputerDevice {
|
|
|
736
779
|
this.xvfbInstance = await startXvfb({
|
|
737
780
|
resolution: this.options?.xvfbResolution
|
|
738
781
|
});
|
|
782
|
+
if (this.options?.keepXvfbAliveUntilProcessExit) scheduleXvfbStopAfterProcessExit(this.xvfbInstance);
|
|
739
783
|
process.env.DISPLAY = this.xvfbInstance.display;
|
|
740
784
|
debugDevice(`Xvfb started on display ${this.xvfbInstance.display}`);
|
|
741
|
-
this.
|
|
742
|
-
|
|
743
|
-
this.xvfbInstance
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
785
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) {
|
|
786
|
+
this.xvfbCleanup = ()=>{
|
|
787
|
+
if (this.xvfbInstance) {
|
|
788
|
+
this.xvfbInstance.stop();
|
|
789
|
+
this.xvfbInstance = void 0;
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
this.xvfbSignalCleanup = createXvfbSignalCleanup(()=>this.xvfbCleanup?.());
|
|
793
|
+
process.on('exit', this.xvfbCleanup);
|
|
794
|
+
process.on('SIGINT', this.xvfbSignalCleanup);
|
|
795
|
+
process.on('SIGTERM', this.xvfbSignalCleanup);
|
|
796
|
+
}
|
|
751
797
|
}
|
|
752
798
|
device_libnut = await getLibnut();
|
|
753
799
|
this.displayGeometry = resolveDisplayGeometry(this.displayId);
|
|
@@ -765,17 +811,17 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
765
811
|
await this.healthCheck();
|
|
766
812
|
} catch (error) {
|
|
767
813
|
if (this.xvfbInstance) {
|
|
768
|
-
this.xvfbInstance.stop();
|
|
814
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
769
815
|
this.xvfbInstance = void 0;
|
|
770
816
|
}
|
|
771
817
|
if (this.xvfbCleanup) {
|
|
772
818
|
process.removeListener('exit', this.xvfbCleanup);
|
|
773
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
774
819
|
this.xvfbCleanup = void 0;
|
|
775
820
|
}
|
|
776
|
-
if (this.
|
|
777
|
-
process.removeListener('SIGINT', this.
|
|
778
|
-
this.
|
|
821
|
+
if (this.xvfbSignalCleanup) {
|
|
822
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
823
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
824
|
+
this.xvfbSignalCleanup = void 0;
|
|
779
825
|
}
|
|
780
826
|
debugDevice(`Failed to connect: ${error}`);
|
|
781
827
|
throw new Error(`Unable to connect to computer device: ${error}`);
|
|
@@ -783,7 +829,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
783
829
|
}
|
|
784
830
|
async healthCheck() {
|
|
785
831
|
console.log('[HealthCheck] Starting health check...');
|
|
786
|
-
console.log("[HealthCheck] @midscene/computer v1.12.2
|
|
832
|
+
console.log("[HealthCheck] @midscene/computer v1.12.2");
|
|
787
833
|
console.log('[HealthCheck] Taking screenshot...');
|
|
788
834
|
const screenshotTimeout = 15000;
|
|
789
835
|
let timeoutId;
|
|
@@ -1120,18 +1166,19 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1120
1166
|
if (this.destroyed) return;
|
|
1121
1167
|
this.destroyed = true;
|
|
1122
1168
|
this.inputDriver.destroy();
|
|
1169
|
+
const keepXvfbAliveUntilProcessExit = this.options?.keepXvfbAliveUntilProcessExit === true;
|
|
1123
1170
|
if (this.xvfbInstance) {
|
|
1124
|
-
this.xvfbInstance.stop();
|
|
1171
|
+
if (!keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
1125
1172
|
this.xvfbInstance = void 0;
|
|
1126
1173
|
}
|
|
1127
|
-
if (this.xvfbCleanup) {
|
|
1174
|
+
if (this.xvfbCleanup && !keepXvfbAliveUntilProcessExit) {
|
|
1128
1175
|
process.removeListener('exit', this.xvfbCleanup);
|
|
1129
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
1130
1176
|
this.xvfbCleanup = void 0;
|
|
1131
1177
|
}
|
|
1132
|
-
if (this.
|
|
1133
|
-
process.removeListener('SIGINT', this.
|
|
1134
|
-
this.
|
|
1178
|
+
if (this.xvfbSignalCleanup) {
|
|
1179
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
1180
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
1181
|
+
this.xvfbSignalCleanup = void 0;
|
|
1135
1182
|
}
|
|
1136
1183
|
debugDevice('Computer device destroyed');
|
|
1137
1184
|
}
|
|
@@ -1147,7 +1194,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1147
1194
|
device_define_property(this, "destroyed", false);
|
|
1148
1195
|
device_define_property(this, "xvfbInstance", void 0);
|
|
1149
1196
|
device_define_property(this, "xvfbCleanup", void 0);
|
|
1150
|
-
device_define_property(this, "
|
|
1197
|
+
device_define_property(this, "xvfbSignalCleanup", void 0);
|
|
1151
1198
|
device_define_property(this, "inputDriver", new ComputerInputDriver({
|
|
1152
1199
|
getLibnut: ()=>device_libnut,
|
|
1153
1200
|
useAppleScript: ()=>this.useAppleScript,
|
|
@@ -1963,7 +2010,8 @@ function createLocalComputerDevice(opts) {
|
|
|
1963
2010
|
keyboardTypeDelay: opts?.keyboardTypeDelay,
|
|
1964
2011
|
keyboardDriver: opts?.keyboardDriver,
|
|
1965
2012
|
headless: opts?.headless,
|
|
1966
|
-
xvfbResolution: opts?.xvfbResolution
|
|
2013
|
+
xvfbResolution: opts?.xvfbResolution,
|
|
2014
|
+
keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
|
|
1967
2015
|
});
|
|
1968
2016
|
}
|
|
1969
2017
|
function createRDPComputerDevice(opts) {
|
|
@@ -2106,6 +2154,9 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2106
2154
|
...void 0 !== keyboardTypeDelay ? {
|
|
2107
2155
|
keyboardTypeDelay
|
|
2108
2156
|
} : {},
|
|
2157
|
+
...this.options.keepXvfbAliveUntilProcessExit ? {
|
|
2158
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2159
|
+
} : {},
|
|
2109
2160
|
...extractAgentBehaviorInitArgs(opts) ?? {},
|
|
2110
2161
|
...reportOptions ?? {}
|
|
2111
2162
|
};
|
|
@@ -2171,21 +2222,23 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2171
2222
|
}
|
|
2172
2223
|
];
|
|
2173
2224
|
}
|
|
2174
|
-
constructor(
|
|
2175
|
-
super(
|
|
2225
|
+
constructor(options = {}){
|
|
2226
|
+
super(), agent_tools_define_property(this, "options", void 0), agent_tools_define_property(this, "lastInitArgsSignature", void 0), agent_tools_define_property(this, "initArgSpec", void 0), this.options = options, this.initArgSpec = {
|
|
2176
2227
|
namespace: 'computer',
|
|
2177
2228
|
shape: computerInitArgShape,
|
|
2178
2229
|
cli: {
|
|
2179
2230
|
preferBareKeys: true
|
|
2180
2231
|
},
|
|
2181
2232
|
adapt: (extracted)=>adaptComputerInitArgs(extracted)
|
|
2182
|
-
}
|
|
2233
|
+
};
|
|
2183
2234
|
}
|
|
2184
2235
|
}
|
|
2185
|
-
const tools = new ComputerMidsceneTools(
|
|
2236
|
+
const tools = new ComputerMidsceneTools({
|
|
2237
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2238
|
+
});
|
|
2186
2239
|
runToolsCLI(tools, 'midscene-computer', {
|
|
2187
2240
|
stripPrefix: 'computer_',
|
|
2188
|
-
version: "1.12.2
|
|
2241
|
+
version: "1.12.2",
|
|
2189
2242
|
extraCommands: createReportCliCommands()
|
|
2190
2243
|
}).catch((e)=>{
|
|
2191
2244
|
process.exit(reportCLIError(e));
|
package/dist/es/index.mjs
CHANGED
|
@@ -185,7 +185,50 @@ class ComputerInputDriver {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
const debugXvfb = getDebug('computer:xvfb');
|
|
188
|
-
|
|
188
|
+
const xvfbCleanupMonitorScript = String.raw`
|
|
189
|
+
const parentPid = Number(process.argv[1]);
|
|
190
|
+
const xvfbPid = Number(process.argv[2]);
|
|
191
|
+
const timer = setInterval(() => {
|
|
192
|
+
try {
|
|
193
|
+
process.kill(xvfbPid, 0);
|
|
194
|
+
} catch {
|
|
195
|
+
clearInterval(timer);
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
process.kill(parentPid, 0);
|
|
200
|
+
return;
|
|
201
|
+
} catch {
|
|
202
|
+
// The owner is gone, so its X11 clients can no longer receive XIO errors.
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
process.kill(xvfbPid, 'SIGTERM');
|
|
206
|
+
} catch {
|
|
207
|
+
// Xvfb may have already exited.
|
|
208
|
+
}
|
|
209
|
+
clearInterval(timer);
|
|
210
|
+
}, 100);
|
|
211
|
+
`;
|
|
212
|
+
function scheduleXvfbStopAfterProcessExit(instance, parentPid = process.pid) {
|
|
213
|
+
const xvfbPid = instance.process.pid;
|
|
214
|
+
if (!xvfbPid) throw new Error('Cannot schedule Xvfb cleanup before its process starts');
|
|
215
|
+
const monitor = spawn(process.execPath, [
|
|
216
|
+
'-e',
|
|
217
|
+
xvfbCleanupMonitorScript,
|
|
218
|
+
String(parentPid),
|
|
219
|
+
String(xvfbPid)
|
|
220
|
+
], {
|
|
221
|
+
detached: true,
|
|
222
|
+
stdio: 'ignore'
|
|
223
|
+
});
|
|
224
|
+
monitor.on('error', (error)=>{
|
|
225
|
+
debugXvfb(`Xvfb cleanup monitor failed: ${error.message}`);
|
|
226
|
+
});
|
|
227
|
+
instance.process.unref();
|
|
228
|
+
monitor.unref();
|
|
229
|
+
return monitor;
|
|
230
|
+
}
|
|
231
|
+
function createXvfbSignalCleanup(cleanup, source = process) {
|
|
189
232
|
return ()=>{
|
|
190
233
|
if (!hasActiveCliInterruptWaiter(source)) cleanup();
|
|
191
234
|
};
|
|
@@ -736,18 +779,21 @@ class ComputerDevice {
|
|
|
736
779
|
this.xvfbInstance = await startXvfb({
|
|
737
780
|
resolution: this.options?.xvfbResolution
|
|
738
781
|
});
|
|
782
|
+
if (this.options?.keepXvfbAliveUntilProcessExit) scheduleXvfbStopAfterProcessExit(this.xvfbInstance);
|
|
739
783
|
process.env.DISPLAY = this.xvfbInstance.display;
|
|
740
784
|
debugDevice(`Xvfb started on display ${this.xvfbInstance.display}`);
|
|
741
|
-
this.
|
|
742
|
-
|
|
743
|
-
this.xvfbInstance
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
785
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) {
|
|
786
|
+
this.xvfbCleanup = ()=>{
|
|
787
|
+
if (this.xvfbInstance) {
|
|
788
|
+
this.xvfbInstance.stop();
|
|
789
|
+
this.xvfbInstance = void 0;
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
this.xvfbSignalCleanup = createXvfbSignalCleanup(()=>this.xvfbCleanup?.());
|
|
793
|
+
process.on('exit', this.xvfbCleanup);
|
|
794
|
+
process.on('SIGINT', this.xvfbSignalCleanup);
|
|
795
|
+
process.on('SIGTERM', this.xvfbSignalCleanup);
|
|
796
|
+
}
|
|
751
797
|
}
|
|
752
798
|
device_libnut = await getLibnut();
|
|
753
799
|
this.displayGeometry = resolveDisplayGeometry(this.displayId);
|
|
@@ -765,17 +811,17 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
765
811
|
await this.healthCheck();
|
|
766
812
|
} catch (error) {
|
|
767
813
|
if (this.xvfbInstance) {
|
|
768
|
-
this.xvfbInstance.stop();
|
|
814
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
769
815
|
this.xvfbInstance = void 0;
|
|
770
816
|
}
|
|
771
817
|
if (this.xvfbCleanup) {
|
|
772
818
|
process.removeListener('exit', this.xvfbCleanup);
|
|
773
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
774
819
|
this.xvfbCleanup = void 0;
|
|
775
820
|
}
|
|
776
|
-
if (this.
|
|
777
|
-
process.removeListener('SIGINT', this.
|
|
778
|
-
this.
|
|
821
|
+
if (this.xvfbSignalCleanup) {
|
|
822
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
823
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
824
|
+
this.xvfbSignalCleanup = void 0;
|
|
779
825
|
}
|
|
780
826
|
debugDevice(`Failed to connect: ${error}`);
|
|
781
827
|
throw new Error(`Unable to connect to computer device: ${error}`);
|
|
@@ -783,7 +829,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
783
829
|
}
|
|
784
830
|
async healthCheck() {
|
|
785
831
|
console.log('[HealthCheck] Starting health check...');
|
|
786
|
-
console.log("[HealthCheck] @midscene/computer v1.12.2
|
|
832
|
+
console.log("[HealthCheck] @midscene/computer v1.12.2");
|
|
787
833
|
console.log('[HealthCheck] Taking screenshot...');
|
|
788
834
|
const screenshotTimeout = 15000;
|
|
789
835
|
let timeoutId;
|
|
@@ -1120,18 +1166,19 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1120
1166
|
if (this.destroyed) return;
|
|
1121
1167
|
this.destroyed = true;
|
|
1122
1168
|
this.inputDriver.destroy();
|
|
1169
|
+
const keepXvfbAliveUntilProcessExit = this.options?.keepXvfbAliveUntilProcessExit === true;
|
|
1123
1170
|
if (this.xvfbInstance) {
|
|
1124
|
-
this.xvfbInstance.stop();
|
|
1171
|
+
if (!keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
1125
1172
|
this.xvfbInstance = void 0;
|
|
1126
1173
|
}
|
|
1127
|
-
if (this.xvfbCleanup) {
|
|
1174
|
+
if (this.xvfbCleanup && !keepXvfbAliveUntilProcessExit) {
|
|
1128
1175
|
process.removeListener('exit', this.xvfbCleanup);
|
|
1129
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
1130
1176
|
this.xvfbCleanup = void 0;
|
|
1131
1177
|
}
|
|
1132
|
-
if (this.
|
|
1133
|
-
process.removeListener('SIGINT', this.
|
|
1134
|
-
this.
|
|
1178
|
+
if (this.xvfbSignalCleanup) {
|
|
1179
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
1180
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
1181
|
+
this.xvfbSignalCleanup = void 0;
|
|
1135
1182
|
}
|
|
1136
1183
|
debugDevice('Computer device destroyed');
|
|
1137
1184
|
}
|
|
@@ -1147,7 +1194,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1147
1194
|
device_define_property(this, "destroyed", false);
|
|
1148
1195
|
device_define_property(this, "xvfbInstance", void 0);
|
|
1149
1196
|
device_define_property(this, "xvfbCleanup", void 0);
|
|
1150
|
-
device_define_property(this, "
|
|
1197
|
+
device_define_property(this, "xvfbSignalCleanup", void 0);
|
|
1151
1198
|
device_define_property(this, "inputDriver", new ComputerInputDriver({
|
|
1152
1199
|
getLibnut: ()=>device_libnut,
|
|
1153
1200
|
useAppleScript: ()=>this.useAppleScript,
|
|
@@ -2006,7 +2053,8 @@ function createLocalComputerDevice(opts) {
|
|
|
2006
2053
|
keyboardTypeDelay: opts?.keyboardTypeDelay,
|
|
2007
2054
|
keyboardDriver: opts?.keyboardDriver,
|
|
2008
2055
|
headless: opts?.headless,
|
|
2009
|
-
xvfbResolution: opts?.xvfbResolution
|
|
2056
|
+
xvfbResolution: opts?.xvfbResolution,
|
|
2057
|
+
keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
|
|
2010
2058
|
});
|
|
2011
2059
|
}
|
|
2012
2060
|
function createRDPComputerDevice(opts) {
|
|
@@ -2149,6 +2197,9 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2149
2197
|
...void 0 !== keyboardTypeDelay ? {
|
|
2150
2198
|
keyboardTypeDelay
|
|
2151
2199
|
} : {},
|
|
2200
|
+
...this.options.keepXvfbAliveUntilProcessExit ? {
|
|
2201
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2202
|
+
} : {},
|
|
2152
2203
|
...extractAgentBehaviorInitArgs(opts) ?? {},
|
|
2153
2204
|
...reportOptions ?? {}
|
|
2154
2205
|
};
|
|
@@ -2214,19 +2265,19 @@ class ComputerMidsceneTools extends BaseMidsceneTools {
|
|
|
2214
2265
|
}
|
|
2215
2266
|
];
|
|
2216
2267
|
}
|
|
2217
|
-
constructor(
|
|
2218
|
-
super(
|
|
2268
|
+
constructor(options = {}){
|
|
2269
|
+
super(), agent_tools_define_property(this, "options", void 0), agent_tools_define_property(this, "lastInitArgsSignature", void 0), agent_tools_define_property(this, "initArgSpec", void 0), this.options = options, this.initArgSpec = {
|
|
2219
2270
|
namespace: 'computer',
|
|
2220
2271
|
shape: computerInitArgShape,
|
|
2221
2272
|
cli: {
|
|
2222
2273
|
preferBareKeys: true
|
|
2223
2274
|
},
|
|
2224
2275
|
adapt: (extracted)=>adaptComputerInitArgs(extracted)
|
|
2225
|
-
}
|
|
2276
|
+
};
|
|
2226
2277
|
}
|
|
2227
2278
|
}
|
|
2228
2279
|
function version() {
|
|
2229
|
-
const currentVersion = "1.12.2
|
|
2280
|
+
const currentVersion = "1.12.2";
|
|
2230
2281
|
console.log(`@midscene/computer v${currentVersion}`);
|
|
2231
2282
|
return currentVersion;
|
|
2232
2283
|
}
|
package/dist/lib/cli.js
CHANGED
|
@@ -211,7 +211,50 @@ class ComputerInputDriver {
|
|
|
211
211
|
}
|
|
212
212
|
const interrupt_namespaceObject = require("@midscene/shared/cli/interrupt");
|
|
213
213
|
const debugXvfb = (0, logger_namespaceObject.getDebug)('computer:xvfb');
|
|
214
|
-
|
|
214
|
+
const xvfbCleanupMonitorScript = String.raw`
|
|
215
|
+
const parentPid = Number(process.argv[1]);
|
|
216
|
+
const xvfbPid = Number(process.argv[2]);
|
|
217
|
+
const timer = setInterval(() => {
|
|
218
|
+
try {
|
|
219
|
+
process.kill(xvfbPid, 0);
|
|
220
|
+
} catch {
|
|
221
|
+
clearInterval(timer);
|
|
222
|
+
process.exit(0);
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
process.kill(parentPid, 0);
|
|
226
|
+
return;
|
|
227
|
+
} catch {
|
|
228
|
+
// The owner is gone, so its X11 clients can no longer receive XIO errors.
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
process.kill(xvfbPid, 'SIGTERM');
|
|
232
|
+
} catch {
|
|
233
|
+
// Xvfb may have already exited.
|
|
234
|
+
}
|
|
235
|
+
clearInterval(timer);
|
|
236
|
+
}, 100);
|
|
237
|
+
`;
|
|
238
|
+
function scheduleXvfbStopAfterProcessExit(instance, parentPid = process.pid) {
|
|
239
|
+
const xvfbPid = instance.process.pid;
|
|
240
|
+
if (!xvfbPid) throw new Error('Cannot schedule Xvfb cleanup before its process starts');
|
|
241
|
+
const monitor = (0, external_node_child_process_namespaceObject.spawn)(process.execPath, [
|
|
242
|
+
'-e',
|
|
243
|
+
xvfbCleanupMonitorScript,
|
|
244
|
+
String(parentPid),
|
|
245
|
+
String(xvfbPid)
|
|
246
|
+
], {
|
|
247
|
+
detached: true,
|
|
248
|
+
stdio: 'ignore'
|
|
249
|
+
});
|
|
250
|
+
monitor.on('error', (error)=>{
|
|
251
|
+
debugXvfb(`Xvfb cleanup monitor failed: ${error.message}`);
|
|
252
|
+
});
|
|
253
|
+
instance.process.unref();
|
|
254
|
+
monitor.unref();
|
|
255
|
+
return monitor;
|
|
256
|
+
}
|
|
257
|
+
function createXvfbSignalCleanup(cleanup, source = process) {
|
|
215
258
|
return ()=>{
|
|
216
259
|
if (!(0, interrupt_namespaceObject.hasActiveCliInterruptWaiter)(source)) cleanup();
|
|
217
260
|
};
|
|
@@ -762,18 +805,21 @@ class ComputerDevice {
|
|
|
762
805
|
this.xvfbInstance = await startXvfb({
|
|
763
806
|
resolution: this.options?.xvfbResolution
|
|
764
807
|
});
|
|
808
|
+
if (this.options?.keepXvfbAliveUntilProcessExit) scheduleXvfbStopAfterProcessExit(this.xvfbInstance);
|
|
765
809
|
process.env.DISPLAY = this.xvfbInstance.display;
|
|
766
810
|
debugDevice(`Xvfb started on display ${this.xvfbInstance.display}`);
|
|
767
|
-
this.
|
|
768
|
-
|
|
769
|
-
this.xvfbInstance
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
811
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) {
|
|
812
|
+
this.xvfbCleanup = ()=>{
|
|
813
|
+
if (this.xvfbInstance) {
|
|
814
|
+
this.xvfbInstance.stop();
|
|
815
|
+
this.xvfbInstance = void 0;
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
this.xvfbSignalCleanup = createXvfbSignalCleanup(()=>this.xvfbCleanup?.());
|
|
819
|
+
process.on('exit', this.xvfbCleanup);
|
|
820
|
+
process.on('SIGINT', this.xvfbSignalCleanup);
|
|
821
|
+
process.on('SIGTERM', this.xvfbSignalCleanup);
|
|
822
|
+
}
|
|
777
823
|
}
|
|
778
824
|
device_libnut = await getLibnut();
|
|
779
825
|
this.displayGeometry = resolveDisplayGeometry(this.displayId);
|
|
@@ -791,17 +837,17 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
791
837
|
await this.healthCheck();
|
|
792
838
|
} catch (error) {
|
|
793
839
|
if (this.xvfbInstance) {
|
|
794
|
-
this.xvfbInstance.stop();
|
|
840
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
795
841
|
this.xvfbInstance = void 0;
|
|
796
842
|
}
|
|
797
843
|
if (this.xvfbCleanup) {
|
|
798
844
|
process.removeListener('exit', this.xvfbCleanup);
|
|
799
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
800
845
|
this.xvfbCleanup = void 0;
|
|
801
846
|
}
|
|
802
|
-
if (this.
|
|
803
|
-
process.removeListener('SIGINT', this.
|
|
804
|
-
this.
|
|
847
|
+
if (this.xvfbSignalCleanup) {
|
|
848
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
849
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
850
|
+
this.xvfbSignalCleanup = void 0;
|
|
805
851
|
}
|
|
806
852
|
debugDevice(`Failed to connect: ${error}`);
|
|
807
853
|
throw new Error(`Unable to connect to computer device: ${error}`);
|
|
@@ -809,7 +855,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
809
855
|
}
|
|
810
856
|
async healthCheck() {
|
|
811
857
|
console.log('[HealthCheck] Starting health check...');
|
|
812
|
-
console.log("[HealthCheck] @midscene/computer v1.12.2
|
|
858
|
+
console.log("[HealthCheck] @midscene/computer v1.12.2");
|
|
813
859
|
console.log('[HealthCheck] Taking screenshot...');
|
|
814
860
|
const screenshotTimeout = 15000;
|
|
815
861
|
let timeoutId;
|
|
@@ -1146,18 +1192,19 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1146
1192
|
if (this.destroyed) return;
|
|
1147
1193
|
this.destroyed = true;
|
|
1148
1194
|
this.inputDriver.destroy();
|
|
1195
|
+
const keepXvfbAliveUntilProcessExit = this.options?.keepXvfbAliveUntilProcessExit === true;
|
|
1149
1196
|
if (this.xvfbInstance) {
|
|
1150
|
-
this.xvfbInstance.stop();
|
|
1197
|
+
if (!keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
1151
1198
|
this.xvfbInstance = void 0;
|
|
1152
1199
|
}
|
|
1153
|
-
if (this.xvfbCleanup) {
|
|
1200
|
+
if (this.xvfbCleanup && !keepXvfbAliveUntilProcessExit) {
|
|
1154
1201
|
process.removeListener('exit', this.xvfbCleanup);
|
|
1155
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
1156
1202
|
this.xvfbCleanup = void 0;
|
|
1157
1203
|
}
|
|
1158
|
-
if (this.
|
|
1159
|
-
process.removeListener('SIGINT', this.
|
|
1160
|
-
this.
|
|
1204
|
+
if (this.xvfbSignalCleanup) {
|
|
1205
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
1206
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
1207
|
+
this.xvfbSignalCleanup = void 0;
|
|
1161
1208
|
}
|
|
1162
1209
|
debugDevice('Computer device destroyed');
|
|
1163
1210
|
}
|
|
@@ -1173,7 +1220,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1173
1220
|
device_define_property(this, "destroyed", false);
|
|
1174
1221
|
device_define_property(this, "xvfbInstance", void 0);
|
|
1175
1222
|
device_define_property(this, "xvfbCleanup", void 0);
|
|
1176
|
-
device_define_property(this, "
|
|
1223
|
+
device_define_property(this, "xvfbSignalCleanup", void 0);
|
|
1177
1224
|
device_define_property(this, "inputDriver", new ComputerInputDriver({
|
|
1178
1225
|
getLibnut: ()=>device_libnut,
|
|
1179
1226
|
useAppleScript: ()=>this.useAppleScript,
|
|
@@ -1990,7 +2037,8 @@ function createLocalComputerDevice(opts) {
|
|
|
1990
2037
|
keyboardTypeDelay: opts?.keyboardTypeDelay,
|
|
1991
2038
|
keyboardDriver: opts?.keyboardDriver,
|
|
1992
2039
|
headless: opts?.headless,
|
|
1993
|
-
xvfbResolution: opts?.xvfbResolution
|
|
2040
|
+
xvfbResolution: opts?.xvfbResolution,
|
|
2041
|
+
keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
|
|
1994
2042
|
});
|
|
1995
2043
|
}
|
|
1996
2044
|
function createRDPComputerDevice(opts) {
|
|
@@ -2133,6 +2181,9 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2133
2181
|
...void 0 !== keyboardTypeDelay ? {
|
|
2134
2182
|
keyboardTypeDelay
|
|
2135
2183
|
} : {},
|
|
2184
|
+
...this.options.keepXvfbAliveUntilProcessExit ? {
|
|
2185
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2186
|
+
} : {},
|
|
2136
2187
|
...(0, agent_behavior_init_args_namespaceObject.extractAgentBehaviorInitArgs)(opts) ?? {},
|
|
2137
2188
|
...reportOptions ?? {}
|
|
2138
2189
|
};
|
|
@@ -2198,21 +2249,23 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2198
2249
|
}
|
|
2199
2250
|
];
|
|
2200
2251
|
}
|
|
2201
|
-
constructor(
|
|
2202
|
-
super(
|
|
2252
|
+
constructor(options = {}){
|
|
2253
|
+
super(), agent_tools_define_property(this, "options", void 0), agent_tools_define_property(this, "lastInitArgsSignature", void 0), agent_tools_define_property(this, "initArgSpec", void 0), this.options = options, this.initArgSpec = {
|
|
2203
2254
|
namespace: 'computer',
|
|
2204
2255
|
shape: computerInitArgShape,
|
|
2205
2256
|
cli: {
|
|
2206
2257
|
preferBareKeys: true
|
|
2207
2258
|
},
|
|
2208
2259
|
adapt: (extracted)=>adaptComputerInitArgs(extracted)
|
|
2209
|
-
}
|
|
2260
|
+
};
|
|
2210
2261
|
}
|
|
2211
2262
|
}
|
|
2212
|
-
const tools = new ComputerMidsceneTools(
|
|
2263
|
+
const tools = new ComputerMidsceneTools({
|
|
2264
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2265
|
+
});
|
|
2213
2266
|
(0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-computer', {
|
|
2214
2267
|
stripPrefix: 'computer_',
|
|
2215
|
-
version: "1.12.2
|
|
2268
|
+
version: "1.12.2",
|
|
2216
2269
|
extraCommands: (0, core_namespaceObject.createReportCliCommands)()
|
|
2217
2270
|
}).catch((e)=>{
|
|
2218
2271
|
process.exit((0, cli_namespaceObject.reportCLIError)(e));
|
package/dist/lib/index.js
CHANGED
|
@@ -237,7 +237,50 @@ class ComputerInputDriver {
|
|
|
237
237
|
}
|
|
238
238
|
const interrupt_namespaceObject = require("@midscene/shared/cli/interrupt");
|
|
239
239
|
const debugXvfb = (0, logger_namespaceObject.getDebug)('computer:xvfb');
|
|
240
|
-
|
|
240
|
+
const xvfbCleanupMonitorScript = String.raw`
|
|
241
|
+
const parentPid = Number(process.argv[1]);
|
|
242
|
+
const xvfbPid = Number(process.argv[2]);
|
|
243
|
+
const timer = setInterval(() => {
|
|
244
|
+
try {
|
|
245
|
+
process.kill(xvfbPid, 0);
|
|
246
|
+
} catch {
|
|
247
|
+
clearInterval(timer);
|
|
248
|
+
process.exit(0);
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
process.kill(parentPid, 0);
|
|
252
|
+
return;
|
|
253
|
+
} catch {
|
|
254
|
+
// The owner is gone, so its X11 clients can no longer receive XIO errors.
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
process.kill(xvfbPid, 'SIGTERM');
|
|
258
|
+
} catch {
|
|
259
|
+
// Xvfb may have already exited.
|
|
260
|
+
}
|
|
261
|
+
clearInterval(timer);
|
|
262
|
+
}, 100);
|
|
263
|
+
`;
|
|
264
|
+
function scheduleXvfbStopAfterProcessExit(instance, parentPid = process.pid) {
|
|
265
|
+
const xvfbPid = instance.process.pid;
|
|
266
|
+
if (!xvfbPid) throw new Error('Cannot schedule Xvfb cleanup before its process starts');
|
|
267
|
+
const monitor = (0, external_node_child_process_namespaceObject.spawn)(process.execPath, [
|
|
268
|
+
'-e',
|
|
269
|
+
xvfbCleanupMonitorScript,
|
|
270
|
+
String(parentPid),
|
|
271
|
+
String(xvfbPid)
|
|
272
|
+
], {
|
|
273
|
+
detached: true,
|
|
274
|
+
stdio: 'ignore'
|
|
275
|
+
});
|
|
276
|
+
monitor.on('error', (error)=>{
|
|
277
|
+
debugXvfb(`Xvfb cleanup monitor failed: ${error.message}`);
|
|
278
|
+
});
|
|
279
|
+
instance.process.unref();
|
|
280
|
+
monitor.unref();
|
|
281
|
+
return monitor;
|
|
282
|
+
}
|
|
283
|
+
function createXvfbSignalCleanup(cleanup, source = process) {
|
|
241
284
|
return ()=>{
|
|
242
285
|
if (!(0, interrupt_namespaceObject.hasActiveCliInterruptWaiter)(source)) cleanup();
|
|
243
286
|
};
|
|
@@ -788,18 +831,21 @@ class ComputerDevice {
|
|
|
788
831
|
this.xvfbInstance = await startXvfb({
|
|
789
832
|
resolution: this.options?.xvfbResolution
|
|
790
833
|
});
|
|
834
|
+
if (this.options?.keepXvfbAliveUntilProcessExit) scheduleXvfbStopAfterProcessExit(this.xvfbInstance);
|
|
791
835
|
process.env.DISPLAY = this.xvfbInstance.display;
|
|
792
836
|
debugDevice(`Xvfb started on display ${this.xvfbInstance.display}`);
|
|
793
|
-
this.
|
|
794
|
-
|
|
795
|
-
this.xvfbInstance
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
837
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) {
|
|
838
|
+
this.xvfbCleanup = ()=>{
|
|
839
|
+
if (this.xvfbInstance) {
|
|
840
|
+
this.xvfbInstance.stop();
|
|
841
|
+
this.xvfbInstance = void 0;
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
this.xvfbSignalCleanup = createXvfbSignalCleanup(()=>this.xvfbCleanup?.());
|
|
845
|
+
process.on('exit', this.xvfbCleanup);
|
|
846
|
+
process.on('SIGINT', this.xvfbSignalCleanup);
|
|
847
|
+
process.on('SIGTERM', this.xvfbSignalCleanup);
|
|
848
|
+
}
|
|
803
849
|
}
|
|
804
850
|
device_libnut = await getLibnut();
|
|
805
851
|
this.displayGeometry = resolveDisplayGeometry(this.displayId);
|
|
@@ -817,17 +863,17 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
817
863
|
await this.healthCheck();
|
|
818
864
|
} catch (error) {
|
|
819
865
|
if (this.xvfbInstance) {
|
|
820
|
-
this.xvfbInstance.stop();
|
|
866
|
+
if (!this.options?.keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
821
867
|
this.xvfbInstance = void 0;
|
|
822
868
|
}
|
|
823
869
|
if (this.xvfbCleanup) {
|
|
824
870
|
process.removeListener('exit', this.xvfbCleanup);
|
|
825
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
826
871
|
this.xvfbCleanup = void 0;
|
|
827
872
|
}
|
|
828
|
-
if (this.
|
|
829
|
-
process.removeListener('SIGINT', this.
|
|
830
|
-
this.
|
|
873
|
+
if (this.xvfbSignalCleanup) {
|
|
874
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
875
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
876
|
+
this.xvfbSignalCleanup = void 0;
|
|
831
877
|
}
|
|
832
878
|
debugDevice(`Failed to connect: ${error}`);
|
|
833
879
|
throw new Error(`Unable to connect to computer device: ${error}`);
|
|
@@ -835,7 +881,7 @@ Available Displays: ${displays.length > 0 ? displays.map((d)=>d.name).join(', ')
|
|
|
835
881
|
}
|
|
836
882
|
async healthCheck() {
|
|
837
883
|
console.log('[HealthCheck] Starting health check...');
|
|
838
|
-
console.log("[HealthCheck] @midscene/computer v1.12.2
|
|
884
|
+
console.log("[HealthCheck] @midscene/computer v1.12.2");
|
|
839
885
|
console.log('[HealthCheck] Taking screenshot...');
|
|
840
886
|
const screenshotTimeout = 15000;
|
|
841
887
|
let timeoutId;
|
|
@@ -1172,18 +1218,19 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1172
1218
|
if (this.destroyed) return;
|
|
1173
1219
|
this.destroyed = true;
|
|
1174
1220
|
this.inputDriver.destroy();
|
|
1221
|
+
const keepXvfbAliveUntilProcessExit = this.options?.keepXvfbAliveUntilProcessExit === true;
|
|
1175
1222
|
if (this.xvfbInstance) {
|
|
1176
|
-
this.xvfbInstance.stop();
|
|
1223
|
+
if (!keepXvfbAliveUntilProcessExit) this.xvfbInstance.stop();
|
|
1177
1224
|
this.xvfbInstance = void 0;
|
|
1178
1225
|
}
|
|
1179
|
-
if (this.xvfbCleanup) {
|
|
1226
|
+
if (this.xvfbCleanup && !keepXvfbAliveUntilProcessExit) {
|
|
1180
1227
|
process.removeListener('exit', this.xvfbCleanup);
|
|
1181
|
-
process.removeListener('SIGTERM', this.xvfbCleanup);
|
|
1182
1228
|
this.xvfbCleanup = void 0;
|
|
1183
1229
|
}
|
|
1184
|
-
if (this.
|
|
1185
|
-
process.removeListener('SIGINT', this.
|
|
1186
|
-
this.
|
|
1230
|
+
if (this.xvfbSignalCleanup) {
|
|
1231
|
+
process.removeListener('SIGINT', this.xvfbSignalCleanup);
|
|
1232
|
+
process.removeListener('SIGTERM', this.xvfbSignalCleanup);
|
|
1233
|
+
this.xvfbSignalCleanup = void 0;
|
|
1187
1234
|
}
|
|
1188
1235
|
debugDevice('Computer device destroyed');
|
|
1189
1236
|
}
|
|
@@ -1199,7 +1246,7 @@ $g.Dispose(); $bmp.Dispose(); $ms.Dispose()
|
|
|
1199
1246
|
device_define_property(this, "destroyed", false);
|
|
1200
1247
|
device_define_property(this, "xvfbInstance", void 0);
|
|
1201
1248
|
device_define_property(this, "xvfbCleanup", void 0);
|
|
1202
|
-
device_define_property(this, "
|
|
1249
|
+
device_define_property(this, "xvfbSignalCleanup", void 0);
|
|
1203
1250
|
device_define_property(this, "inputDriver", new ComputerInputDriver({
|
|
1204
1251
|
getLibnut: ()=>device_libnut,
|
|
1205
1252
|
useAppleScript: ()=>this.useAppleScript,
|
|
@@ -2060,7 +2107,8 @@ function createLocalComputerDevice(opts) {
|
|
|
2060
2107
|
keyboardTypeDelay: opts?.keyboardTypeDelay,
|
|
2061
2108
|
keyboardDriver: opts?.keyboardDriver,
|
|
2062
2109
|
headless: opts?.headless,
|
|
2063
|
-
xvfbResolution: opts?.xvfbResolution
|
|
2110
|
+
xvfbResolution: opts?.xvfbResolution,
|
|
2111
|
+
keepXvfbAliveUntilProcessExit: opts?.keepXvfbAliveUntilProcessExit
|
|
2064
2112
|
});
|
|
2065
2113
|
}
|
|
2066
2114
|
function createRDPComputerDevice(opts) {
|
|
@@ -2206,6 +2254,9 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2206
2254
|
...void 0 !== keyboardTypeDelay ? {
|
|
2207
2255
|
keyboardTypeDelay
|
|
2208
2256
|
} : {},
|
|
2257
|
+
...this.options.keepXvfbAliveUntilProcessExit ? {
|
|
2258
|
+
keepXvfbAliveUntilProcessExit: true
|
|
2259
|
+
} : {},
|
|
2209
2260
|
...(0, agent_behavior_init_args_namespaceObject.extractAgentBehaviorInitArgs)(opts) ?? {},
|
|
2210
2261
|
...reportOptions ?? {}
|
|
2211
2262
|
};
|
|
@@ -2271,20 +2322,20 @@ class ComputerMidsceneTools extends base_tools_namespaceObject.BaseMidsceneTools
|
|
|
2271
2322
|
}
|
|
2272
2323
|
];
|
|
2273
2324
|
}
|
|
2274
|
-
constructor(
|
|
2275
|
-
super(
|
|
2325
|
+
constructor(options = {}){
|
|
2326
|
+
super(), agent_tools_define_property(this, "options", void 0), agent_tools_define_property(this, "lastInitArgsSignature", void 0), agent_tools_define_property(this, "initArgSpec", void 0), this.options = options, this.initArgSpec = {
|
|
2276
2327
|
namespace: 'computer',
|
|
2277
2328
|
shape: computerInitArgShape,
|
|
2278
2329
|
cli: {
|
|
2279
2330
|
preferBareKeys: true
|
|
2280
2331
|
},
|
|
2281
2332
|
adapt: (extracted)=>adaptComputerInitArgs(extracted)
|
|
2282
|
-
}
|
|
2333
|
+
};
|
|
2283
2334
|
}
|
|
2284
2335
|
}
|
|
2285
2336
|
const env_namespaceObject = require("@midscene/shared/env");
|
|
2286
2337
|
function version() {
|
|
2287
|
-
const currentVersion = "1.12.2
|
|
2338
|
+
const currentVersion = "1.12.2";
|
|
2288
2339
|
console.log(`@midscene/computer v${currentVersion}`);
|
|
2289
2340
|
return currentVersion;
|
|
2290
2341
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -73,7 +73,7 @@ export declare class ComputerDevice implements AbstractInterface {
|
|
|
73
73
|
private destroyed;
|
|
74
74
|
private xvfbInstance?;
|
|
75
75
|
private xvfbCleanup?;
|
|
76
|
-
private
|
|
76
|
+
private xvfbSignalCleanup?;
|
|
77
77
|
private readonly inputDriver;
|
|
78
78
|
/**
|
|
79
79
|
* On macOS, use AppleScript for keyboard operations by default
|
|
@@ -181,6 +181,14 @@ export declare interface ComputerDeviceOpt extends ComputerDeviceInputOpt {
|
|
|
181
181
|
* Resolution for Xvfb virtual display (default '1920x1080x24')
|
|
182
182
|
*/
|
|
183
183
|
xvfbResolution?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Keep a managed Xvfb server alive until process exit.
|
|
186
|
+
*
|
|
187
|
+
* @internal The foreground CLI uses this because libnut keeps a process-wide
|
|
188
|
+
* X11 connection open. Stopping Xvfb during normal CLI teardown would make
|
|
189
|
+
* Xlib terminate an otherwise successful command with exit code 1.
|
|
190
|
+
*/
|
|
191
|
+
keepXvfbAliveUntilProcessExit?: boolean;
|
|
184
192
|
}
|
|
185
193
|
|
|
186
194
|
/**
|
|
@@ -202,7 +210,9 @@ declare type ComputerLocalInitArgs = {
|
|
|
202
210
|
* Extends BaseMidsceneTools to provide desktop automation tools
|
|
203
211
|
*/
|
|
204
212
|
export declare class ComputerMidsceneTools extends BaseMidsceneTools<ComputerAgent, ComputerInitArgs> {
|
|
213
|
+
private readonly options;
|
|
205
214
|
private lastInitArgsSignature?;
|
|
215
|
+
constructor(options?: ComputerMidsceneToolsOptions);
|
|
206
216
|
protected getCliReportSessionName(): string;
|
|
207
217
|
protected readonly initArgSpec: InitArgSpec<ComputerInitArgs>;
|
|
208
218
|
protected createTemporaryDevice(): ComputerDevice;
|
|
@@ -213,6 +223,11 @@ export declare class ComputerMidsceneTools extends BaseMidsceneTools<ComputerAge
|
|
|
213
223
|
protected preparePlatformTools(): ToolDefinition[];
|
|
214
224
|
}
|
|
215
225
|
|
|
226
|
+
declare interface ComputerMidsceneToolsOptions {
|
|
227
|
+
/** Keep CLI-owned Xvfb alive until process exit so Xlib clients stay valid. */
|
|
228
|
+
keepXvfbAliveUntilProcessExit?: boolean;
|
|
229
|
+
}
|
|
230
|
+
|
|
216
231
|
/** Init args for the RDP remote-desktop agent. */
|
|
217
232
|
declare type ComputerRDPInitArgs = {
|
|
218
233
|
mode: 'rdp';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midscene/computer",
|
|
3
|
-
"version": "1.12.2
|
|
3
|
+
"version": "1.12.2",
|
|
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.12.2
|
|
37
|
-
"@midscene/shared": "1.12.2
|
|
36
|
+
"@midscene/core": "1.12.2",
|
|
37
|
+
"@midscene/shared": "1.12.2"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
40
|
"node-mac-permissions": "2.5.0"
|