@hypothesi/tauri-mcp-server 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/config.d.ts +14 -0
- package/dist/config.js +26 -0
- package/dist/driver/app-discovery.d.ts +4 -2
- package/dist/driver/app-discovery.js +23 -3
- package/dist/driver/element-picker.d.ts +1 -1
- package/dist/driver/plugin-client.d.ts +23 -1
- package/dist/driver/plugin-client.js +127 -2
- package/dist/driver/plugin-commands.d.ts +8 -4
- package/dist/driver/plugin-commands.js +71 -16
- package/dist/driver/protocol.d.ts +7 -0
- package/dist/driver/scripts/find-element.js +129 -16
- package/dist/driver/scripts/focus.js +31 -4
- package/dist/driver/scripts/html2canvas-loader.js +20 -2
- package/dist/driver/scripts/index.d.ts +2 -4
- package/dist/driver/scripts/index.js +40 -11
- package/dist/driver/scripts/interact.js +66 -5
- package/dist/driver/scripts/resolve-ref.js +101 -50
- package/dist/driver/session-manager.d.ts +39 -0
- package/dist/driver/session-manager.js +133 -13
- package/dist/driver/webview-executor.d.ts +20 -8
- package/dist/driver/webview-executor.js +159 -58
- package/dist/driver/webview-interactions.d.ts +57 -42
- package/dist/driver/webview-interactions.js +62 -40
- package/dist/manager/mobile.js +3 -2
- package/dist/monitor/logs.d.ts +14 -2
- package/dist/monitor/logs.js +37 -5
- package/dist/tools-registry.js +35 -33
- package/dist/version.d.ts +5 -0
- package/dist/version.js +16 -0
- package/package.json +1 -1
- package/dist/driver/scripts/get-styles.js +0 -47
- package/dist/driver/scripts/keyboard.js +0 -76
|
@@ -30,10 +30,18 @@ export declare const ManageDriverSessionSchema: z.ZodObject<{
|
|
|
30
30
|
export interface SessionInfo {
|
|
31
31
|
name: string;
|
|
32
32
|
identifier: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Working directory of the host Tauri process at session-start time.
|
|
35
|
+
* `null` when the plugin is too old to advertise it (pre-v0.11) or
|
|
36
|
+
* when the lookup failed; in that case CWD-based routing skips this
|
|
37
|
+
* session and falls back to default behavior.
|
|
38
|
+
*/
|
|
39
|
+
cwd: string | null;
|
|
33
40
|
host: string;
|
|
34
41
|
port: number;
|
|
35
42
|
client: PluginClient;
|
|
36
43
|
connected: boolean;
|
|
44
|
+
pluginVersion: string | null;
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Check if any session is currently active.
|
|
@@ -52,9 +60,40 @@ export declare function getDefaultSession(): SessionInfo | null;
|
|
|
52
60
|
* Get all active sessions.
|
|
53
61
|
*/
|
|
54
62
|
export declare function getAllSessions(): SessionInfo[];
|
|
63
|
+
/**
|
|
64
|
+
* Find the session whose `cwd` best matches `hintCwd`.
|
|
65
|
+
*
|
|
66
|
+
* Used to disambiguate multiple concurrent Tauri instances when the caller
|
|
67
|
+
* did not pass an explicit appIdentifier. The "best match" is the longest
|
|
68
|
+
* shared prefix between the hint and a session's CWD, in either direction:
|
|
69
|
+
*
|
|
70
|
+
* - `session.cwd === hintCwd` (exact)
|
|
71
|
+
* - `hintCwd.startsWith(session.cwd + '/')` (TS server runs inside a
|
|
72
|
+
* subdirectory of the host process's CWD; rare)
|
|
73
|
+
* - `session.cwd.startsWith(hintCwd + '/')` (host process runs inside
|
|
74
|
+
* the workspace the TS server was launched from; the common case
|
|
75
|
+
* when VSCode opens a parent dir and moss runs from a worktree)
|
|
76
|
+
*
|
|
77
|
+
* Sessions whose `cwd` is null (older plugin without CWD support) are
|
|
78
|
+
* skipped — they cannot be matched and stay eligible for the existing
|
|
79
|
+
* "use default app" fallback in `resolveTargetApp`.
|
|
80
|
+
*
|
|
81
|
+
* Pure function (takes `sessions` as a parameter) so it can be unit-tested
|
|
82
|
+
* without touching module state.
|
|
83
|
+
*
|
|
84
|
+
* @returns The best-matching session, or null if no session matches.
|
|
85
|
+
*/
|
|
86
|
+
export declare function findSessionByCwd(sessions: Iterable<SessionInfo>, hintCwd: string | null): SessionInfo | null;
|
|
55
87
|
/**
|
|
56
88
|
* Resolve target app from port or identifier.
|
|
57
89
|
* Returns the appropriate session based on the routing logic.
|
|
90
|
+
*
|
|
91
|
+
* Order of precedence:
|
|
92
|
+
* 1. Explicit `portOrIdentifier` (port number or bundle id)
|
|
93
|
+
* 2. CWD match via `findSessionByCwd` against `MCP_BRIDGE_CWD` or
|
|
94
|
+
* `process.cwd()` — lets each MCP client target the Tauri instance
|
|
95
|
+
* running in its own workspace/worktree without manual routing
|
|
96
|
+
* 3. The default app (most-recently-connected)
|
|
58
97
|
*/
|
|
59
98
|
export declare function resolveTargetApp(portOrIdentifier?: string | number): SessionInfo;
|
|
60
99
|
/**
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { getDefaultHost, getDefaultPort } from '../config.js';
|
|
2
|
+
import { getCwdHint, getDefaultHost, getDefaultPort } from '../config.js';
|
|
3
3
|
import { AppDiscovery } from './app-discovery.js';
|
|
4
4
|
import { PluginClient } from './plugin-client.js';
|
|
5
5
|
import { resetInitialization } from './webview-executor.js';
|
|
6
6
|
import { createMcpLogger } from '../logger.js';
|
|
7
|
+
import { PLUGIN_VERSION_FULL, describeVersionSkew } from '../version.js';
|
|
7
8
|
const sessionLogger = createMcpLogger('SESSION');
|
|
8
9
|
/**
|
|
9
10
|
* Session Manager - Native IPC-based session management
|
|
@@ -69,9 +70,65 @@ function getAppDiscovery(host) {
|
|
|
69
70
|
}
|
|
70
71
|
return appDiscovery;
|
|
71
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Find the session whose `cwd` best matches `hintCwd`.
|
|
75
|
+
*
|
|
76
|
+
* Used to disambiguate multiple concurrent Tauri instances when the caller
|
|
77
|
+
* did not pass an explicit appIdentifier. The "best match" is the longest
|
|
78
|
+
* shared prefix between the hint and a session's CWD, in either direction:
|
|
79
|
+
*
|
|
80
|
+
* - `session.cwd === hintCwd` (exact)
|
|
81
|
+
* - `hintCwd.startsWith(session.cwd + '/')` (TS server runs inside a
|
|
82
|
+
* subdirectory of the host process's CWD; rare)
|
|
83
|
+
* - `session.cwd.startsWith(hintCwd + '/')` (host process runs inside
|
|
84
|
+
* the workspace the TS server was launched from; the common case
|
|
85
|
+
* when VSCode opens a parent dir and moss runs from a worktree)
|
|
86
|
+
*
|
|
87
|
+
* Sessions whose `cwd` is null (older plugin without CWD support) are
|
|
88
|
+
* skipped — they cannot be matched and stay eligible for the existing
|
|
89
|
+
* "use default app" fallback in `resolveTargetApp`.
|
|
90
|
+
*
|
|
91
|
+
* Pure function (takes `sessions` as a parameter) so it can be unit-tested
|
|
92
|
+
* without touching module state.
|
|
93
|
+
*
|
|
94
|
+
* @returns The best-matching session, or null if no session matches.
|
|
95
|
+
*/
|
|
96
|
+
export function findSessionByCwd(sessions, hintCwd) {
|
|
97
|
+
if (!hintCwd) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
let best = null, bestScore = -1;
|
|
101
|
+
for (const session of sessions) {
|
|
102
|
+
if (!session.cwd) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
let score = -1;
|
|
106
|
+
if (session.cwd === hintCwd) {
|
|
107
|
+
score = session.cwd.length;
|
|
108
|
+
}
|
|
109
|
+
else if (hintCwd.startsWith(session.cwd + '/')) {
|
|
110
|
+
score = session.cwd.length;
|
|
111
|
+
}
|
|
112
|
+
else if (session.cwd.startsWith(hintCwd + '/')) {
|
|
113
|
+
score = hintCwd.length;
|
|
114
|
+
}
|
|
115
|
+
if (score > bestScore) {
|
|
116
|
+
best = session;
|
|
117
|
+
bestScore = score;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return best;
|
|
121
|
+
}
|
|
72
122
|
/**
|
|
73
123
|
* Resolve target app from port or identifier.
|
|
74
124
|
* Returns the appropriate session based on the routing logic.
|
|
125
|
+
*
|
|
126
|
+
* Order of precedence:
|
|
127
|
+
* 1. Explicit `portOrIdentifier` (port number or bundle id)
|
|
128
|
+
* 2. CWD match via `findSessionByCwd` against `MCP_BRIDGE_CWD` or
|
|
129
|
+
* `process.cwd()` — lets each MCP client target the Tauri instance
|
|
130
|
+
* running in its own workspace/worktree without manual routing
|
|
131
|
+
* 3. The default app (most-recently-connected)
|
|
75
132
|
*/
|
|
76
133
|
export function resolveTargetApp(portOrIdentifier) {
|
|
77
134
|
if (activeSessions.size === 0) {
|
|
@@ -105,6 +162,12 @@ export function resolveTargetApp(portOrIdentifier) {
|
|
|
105
162
|
}
|
|
106
163
|
throw new Error(formatAppNotFoundError(portOrIdentifier));
|
|
107
164
|
}
|
|
165
|
+
// No explicit identifier: try CWD-based routing before falling back to
|
|
166
|
+
// "default app". If no session matches, behave as before.
|
|
167
|
+
const cwdMatch = findSessionByCwd(activeSessions.values(), getCwdHint());
|
|
168
|
+
if (cwdMatch) {
|
|
169
|
+
return cwdMatch;
|
|
170
|
+
}
|
|
108
171
|
// Use default app
|
|
109
172
|
if (defaultPort !== null && activeSessions.has(defaultPort)) {
|
|
110
173
|
const session = activeSessions.get(defaultPort);
|
|
@@ -149,6 +212,30 @@ function promoteNextDefault() {
|
|
|
149
212
|
defaultPort = null;
|
|
150
213
|
}
|
|
151
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Return whether a cached session is responsive, removing it when stale.
|
|
217
|
+
*/
|
|
218
|
+
async function keepResponsiveSession(port) {
|
|
219
|
+
const session = activeSessions.get(port);
|
|
220
|
+
if (!session) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
if (await session.client.checkConnection()) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Treat probe errors like missed pongs and replace the stale client below.
|
|
230
|
+
}
|
|
231
|
+
session.client.disconnect();
|
|
232
|
+
activeSessions.delete(port);
|
|
233
|
+
if (port === defaultPort) {
|
|
234
|
+
promoteNextDefault();
|
|
235
|
+
}
|
|
236
|
+
sessionLogger.info(`Removed stale session: ${session.name} (${session.host}:${session.port})`);
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
152
239
|
async function handleStatusAction() {
|
|
153
240
|
if (activeSessions.size === 0) {
|
|
154
241
|
return JSON.stringify({
|
|
@@ -157,6 +244,9 @@ async function handleStatusAction() {
|
|
|
157
244
|
identifier: null,
|
|
158
245
|
host: null,
|
|
159
246
|
port: null,
|
|
247
|
+
pluginVersion: null,
|
|
248
|
+
serverVersion: PLUGIN_VERSION_FULL,
|
|
249
|
+
versionWarning: describeVersionSkew(null),
|
|
160
250
|
});
|
|
161
251
|
}
|
|
162
252
|
if (activeSessions.size === 1) {
|
|
@@ -168,22 +258,35 @@ async function handleStatusAction() {
|
|
|
168
258
|
identifier: null,
|
|
169
259
|
host: null,
|
|
170
260
|
port: null,
|
|
261
|
+
pluginVersion: null,
|
|
262
|
+
serverVersion: PLUGIN_VERSION_FULL,
|
|
263
|
+
versionWarning: describeVersionSkew(null),
|
|
171
264
|
});
|
|
172
265
|
}
|
|
266
|
+
const versionWarning = describeVersionSkew(session.pluginVersion);
|
|
173
267
|
return JSON.stringify({
|
|
174
268
|
connected: true,
|
|
175
269
|
app: session.name,
|
|
176
270
|
identifier: session.identifier,
|
|
271
|
+
cwd: session.cwd,
|
|
177
272
|
host: session.host,
|
|
178
273
|
port: session.port,
|
|
274
|
+
pluginVersion: session.pluginVersion,
|
|
275
|
+
serverVersion: PLUGIN_VERSION_FULL,
|
|
276
|
+
versionWarning,
|
|
179
277
|
});
|
|
180
278
|
}
|
|
181
279
|
const apps = Array.from(activeSessions.values()).map((session) => {
|
|
280
|
+
const versionWarning = describeVersionSkew(session.pluginVersion);
|
|
182
281
|
return {
|
|
183
282
|
name: session.name,
|
|
184
283
|
identifier: session.identifier,
|
|
284
|
+
cwd: session.cwd,
|
|
185
285
|
host: session.host,
|
|
186
286
|
port: session.port,
|
|
287
|
+
pluginVersion: session.pluginVersion,
|
|
288
|
+
serverVersion: PLUGIN_VERSION_FULL,
|
|
289
|
+
versionWarning,
|
|
187
290
|
isDefault: session.port === defaultPort,
|
|
188
291
|
};
|
|
189
292
|
});
|
|
@@ -192,12 +295,13 @@ async function handleStatusAction() {
|
|
|
192
295
|
apps,
|
|
193
296
|
totalCount: apps.length,
|
|
194
297
|
defaultPort,
|
|
298
|
+
serverVersion: PLUGIN_VERSION_FULL,
|
|
195
299
|
});
|
|
196
300
|
}
|
|
197
301
|
async function handleStartAction(host, port) {
|
|
198
302
|
const configuredHost = host ?? getDefaultHost();
|
|
199
303
|
const configuredPort = port ?? getDefaultPort();
|
|
200
|
-
if (
|
|
304
|
+
if (await keepResponsiveSession(configuredPort)) {
|
|
201
305
|
return `Already connected to app on port ${configuredPort}`;
|
|
202
306
|
}
|
|
203
307
|
let connectedSession = null;
|
|
@@ -232,21 +336,31 @@ async function handleStartAction(host, port) {
|
|
|
232
336
|
if (!connectedSession) {
|
|
233
337
|
return `Session start failed - no Tauri app found at localhost or ${configuredHost}:${configuredPort}`;
|
|
234
338
|
}
|
|
339
|
+
if (await keepResponsiveSession(connectedSession.port)) {
|
|
340
|
+
return `Already connected to app on port ${connectedSession.port}`;
|
|
341
|
+
}
|
|
235
342
|
const client = new PluginClient(connectedSession.host, connectedSession.port);
|
|
236
343
|
await client.connect();
|
|
237
|
-
const identifier = await
|
|
344
|
+
const { identifier, cwd, pluginVersion } = await fetchAppMetadata(client);
|
|
238
345
|
const sessionInfo = {
|
|
239
346
|
name: connectedSession.name,
|
|
240
347
|
identifier,
|
|
348
|
+
cwd,
|
|
241
349
|
host: connectedSession.host,
|
|
242
350
|
port: connectedSession.port,
|
|
243
351
|
client,
|
|
244
352
|
connected: true,
|
|
353
|
+
pluginVersion,
|
|
245
354
|
};
|
|
246
355
|
activeSessions.set(connectedSession.port, sessionInfo);
|
|
247
356
|
defaultPort = connectedSession.port;
|
|
248
357
|
sessionLogger.info(`Session started: ${sessionInfo.name} (${sessionInfo.host}:${sessionInfo.port}) [DEFAULT]`);
|
|
249
|
-
|
|
358
|
+
let result = `Session started with app: ${sessionInfo.name} (${sessionInfo.host}:${sessionInfo.port}) [DEFAULT]`;
|
|
359
|
+
const versionWarning = describeVersionSkew(sessionInfo.pluginVersion);
|
|
360
|
+
if (versionWarning) {
|
|
361
|
+
result = `${versionWarning}\n\n${result}`;
|
|
362
|
+
}
|
|
363
|
+
return result;
|
|
250
364
|
}
|
|
251
365
|
async function handleStopAction(appIdentifier) {
|
|
252
366
|
if (appIdentifier !== undefined) {
|
|
@@ -292,27 +406,33 @@ async function tryConnect(host, port) {
|
|
|
292
406
|
* Must be called after a PluginClient is connected.
|
|
293
407
|
*
|
|
294
408
|
* @param client - The PluginClient to query
|
|
295
|
-
* @returns
|
|
296
|
-
* - The plugin
|
|
409
|
+
* @returns `{ identifier, cwd }`. Each field is null when:
|
|
410
|
+
* - The plugin is too old to advertise it
|
|
297
411
|
* - The backend state request fails
|
|
298
|
-
* - The
|
|
412
|
+
* - The field is missing from the response
|
|
413
|
+
*
|
|
414
|
+
* Older plugins (pre-identifier) return `{ identifier: null, cwd: null }`.
|
|
415
|
+
* Newer plugins without the cwd field return a real identifier and a null cwd.
|
|
416
|
+
* Routing degrades gracefully in either case.
|
|
299
417
|
*/
|
|
300
|
-
async function
|
|
418
|
+
async function fetchAppMetadata(client) {
|
|
301
419
|
try {
|
|
302
420
|
const response = await client.sendCommand({
|
|
303
421
|
command: 'invoke_tauri',
|
|
304
422
|
args: { command: 'plugin:mcp-bridge|get_backend_state', args: {} },
|
|
305
423
|
});
|
|
306
424
|
if (!response.success || !response.data) {
|
|
307
|
-
return null;
|
|
425
|
+
return { identifier: null, cwd: null, pluginVersion: null };
|
|
308
426
|
}
|
|
309
427
|
const state = response.data;
|
|
310
|
-
|
|
311
|
-
|
|
428
|
+
return {
|
|
429
|
+
identifier: state.app?.identifier ?? null,
|
|
430
|
+
cwd: typeof state.cwd === 'string' && state.cwd.length > 0 ? state.cwd : null,
|
|
431
|
+
pluginVersion: state.bridge?.pluginVersion ?? null,
|
|
432
|
+
};
|
|
312
433
|
}
|
|
313
434
|
catch {
|
|
314
|
-
|
|
315
|
-
return null;
|
|
435
|
+
return { identifier: null, cwd: null, pluginVersion: null };
|
|
316
436
|
}
|
|
317
437
|
}
|
|
318
438
|
/**
|
|
@@ -28,18 +28,20 @@ export interface ExecuteInWebviewResult {
|
|
|
28
28
|
* @param script - JavaScript code to execute in the webview context
|
|
29
29
|
* @param windowId - Optional window label to target (defaults to "main")
|
|
30
30
|
* @param appIdentifier - Optional app identifier to target specific app
|
|
31
|
+
* @param timeoutMs - Optional timeout in milliseconds
|
|
31
32
|
* @returns Result of the script execution with window context
|
|
32
33
|
*/
|
|
33
|
-
export declare function executeInWebview(script: string, windowId?: string, appIdentifier?: string | number): Promise<string>;
|
|
34
|
+
export declare function executeInWebview(script: string, windowId?: string, appIdentifier?: string | number, timeoutMs?: number): Promise<string>;
|
|
34
35
|
/**
|
|
35
36
|
* Execute JavaScript in the Tauri webview and return window context.
|
|
36
37
|
*
|
|
37
38
|
* @param script - JavaScript code to execute in the webview context
|
|
38
39
|
* @param windowId - Optional window label to target (defaults to "main")
|
|
39
40
|
* @param appIdentifier - Optional app identifier to target specific app
|
|
41
|
+
* @param timeoutMs - Optional timeout in milliseconds
|
|
40
42
|
* @returns Result of the script execution with window context
|
|
41
43
|
*/
|
|
42
|
-
export declare function executeInWebviewWithContext(script: string, windowId?: string, appIdentifier?: string | number): Promise<ExecuteInWebviewResult>;
|
|
44
|
+
export declare function executeInWebviewWithContext(script: string, windowId?: string, appIdentifier?: string | number, timeoutMs?: number, isRetry?: boolean): Promise<ExecuteInWebviewResult>;
|
|
43
45
|
/**
|
|
44
46
|
* Execute async JavaScript in the webview with timeout support.
|
|
45
47
|
*
|
|
@@ -61,13 +63,19 @@ export declare function initializeConsoleCapture(): Promise<string>;
|
|
|
61
63
|
/**
|
|
62
64
|
* Retrieve captured console logs with optional filtering.
|
|
63
65
|
*
|
|
64
|
-
* @param
|
|
65
|
-
* @param since - Optional ISO timestamp to filter logs after this time
|
|
66
|
-
* @param windowId - Optional window label to target (defaults to "main")
|
|
67
|
-
* @param appIdentifier - Optional app identifier to target specific app
|
|
66
|
+
* @param options - Filtering and formatting options
|
|
68
67
|
* @returns Formatted console logs as string
|
|
69
68
|
*/
|
|
70
|
-
export declare function getConsoleLogs(
|
|
69
|
+
export declare function getConsoleLogs(options?: {
|
|
70
|
+
filter?: string;
|
|
71
|
+
since?: string;
|
|
72
|
+
lines?: number;
|
|
73
|
+
windowId?: string;
|
|
74
|
+
appIdentifier?: string | number;
|
|
75
|
+
level?: string;
|
|
76
|
+
maxChars?: number;
|
|
77
|
+
maxCharsPerEntry?: number;
|
|
78
|
+
}): Promise<string>;
|
|
71
79
|
/**
|
|
72
80
|
* Clear all captured console logs.
|
|
73
81
|
*/
|
|
@@ -85,9 +93,10 @@ export interface CaptureScreenshotOptions {
|
|
|
85
93
|
windowId?: string;
|
|
86
94
|
appIdentifier?: string | number;
|
|
87
95
|
maxWidth?: number;
|
|
96
|
+
allowScreenCapture?: boolean;
|
|
88
97
|
}
|
|
89
98
|
/**
|
|
90
|
-
* Capture a screenshot of the
|
|
99
|
+
* Capture a screenshot of the visible webview viewport.
|
|
91
100
|
*
|
|
92
101
|
* @param options - Screenshot options (format, quality, windowId, appIdentifier, etc.)
|
|
93
102
|
* @returns Screenshot result with image content
|
|
@@ -113,10 +122,13 @@ export declare const GetConsoleLogsSchema: z.ZodObject<{
|
|
|
113
122
|
export declare const CaptureScreenshotSchema: z.ZodObject<{
|
|
114
123
|
format: z.ZodDefault<z.ZodOptional<z.ZodEnum<["png", "jpeg"]>>>;
|
|
115
124
|
quality: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
allowScreenCapture: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
116
126
|
}, "strip", z.ZodTypeAny, {
|
|
117
127
|
format: "png" | "jpeg";
|
|
128
|
+
allowScreenCapture: boolean;
|
|
118
129
|
quality?: number | undefined;
|
|
119
130
|
}, {
|
|
120
131
|
format?: "png" | "jpeg" | undefined;
|
|
121
132
|
quality?: number | undefined;
|
|
133
|
+
allowScreenCapture?: boolean | undefined;
|
|
122
134
|
}>;
|