@modelprofile.com/browser-runtime 5.2.1 → 5.3.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/changelog.md +6 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.runtime.d.ts +20 -0
- package/dist_ts/classes.runtime.js +179 -1
- package/dist_ts/interfaces.d.ts +4 -1
- package/package.json +2 -2
- package/readme.md +22 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.runtime.ts +169 -0
- package/ts/interfaces.ts +5 -0
package/dist_ts/interfaces.d.ts
CHANGED
|
@@ -101,7 +101,7 @@ export type TBrowserRuntimeOperationIdentity = TReadonlyBrowserCapabilityAuthori
|
|
|
101
101
|
readonly classification: TBrowserRuntimeOperationClassification;
|
|
102
102
|
readonly startedAt: number;
|
|
103
103
|
};
|
|
104
|
-
export type TBrowserRuntimeOperationClassification = 'raw-input' | 'frame-stream' | 'video-peer' | 'viewport' | 'navigation' | 'tab' | 'agent-action';
|
|
104
|
+
export type TBrowserRuntimeOperationClassification = 'raw-input' | 'frame-stream' | 'video-peer' | 'devtools' | 'viewport' | 'navigation' | 'tab' | 'agent-action';
|
|
105
105
|
/** The viewport accepted by the shared resource, which may be smaller than one viewer's request. */
|
|
106
106
|
export interface IBrowserRuntimeViewportResult {
|
|
107
107
|
viewport: plugins.smartpuppeteer.ILiveBrowserViewport;
|
|
@@ -120,6 +120,7 @@ export type TBrowserRuntimeAuditEvent = TBrowserRuntimeOperationIdentity & {
|
|
|
120
120
|
readonly errorCode?: string;
|
|
121
121
|
};
|
|
122
122
|
export interface ILiveBrowserSessionLike {
|
|
123
|
+
openDevTools?(options: plugins.smartpuppeteer.ILiveBrowserDevToolsOptions, operationOptions?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<plugins.smartpuppeteer.ILiveBrowserDevToolsConnection>;
|
|
123
124
|
start(options?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<void>;
|
|
124
125
|
stop(): Promise<void>;
|
|
125
126
|
terminate(options?: plugins.smartpuppeteer.ILiveBrowserTerminationOptions): Promise<plugins.smartpuppeteer.ILiveBrowserTerminationResult>;
|
|
@@ -200,6 +201,8 @@ export interface IBrowserRuntimeOptions {
|
|
|
200
201
|
screencast?: IBrowserRuntimeScreencastOptions;
|
|
201
202
|
/** Trusted host configuration; defaults to direct ICE and automatic GPU support. */
|
|
202
203
|
video?: plugins.smartpuppeteer.ILiveVideoOptions;
|
|
204
|
+
/** Enables selected-tab DevTools for human leases only. Disabled by default. */
|
|
205
|
+
devTools?: boolean;
|
|
203
206
|
egress?: Omit<IBrowserEgressProxyOptions, 'projectId' | 'browserResourceId'>;
|
|
204
207
|
artifacts?: Omit<IBrowserArtifactStoreOptions, 'rootDirectory'>;
|
|
205
208
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelprofile.com/browser-runtime",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Parent-owned, resource-centric Chromium runtime with revisioned attachment fencing, authenticated human and agent control, fail-closed egress, bounded artifacts, and Flex/MCP adapters.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@push.rocks/smartagent": "^6.0.0",
|
|
31
31
|
"@push.rocks/smartipc": "^2.6.0",
|
|
32
32
|
"@push.rocks/smartmcp": "^0.3.0",
|
|
33
|
-
"@push.rocks/smartpuppeteer": "^2.
|
|
33
|
+
"@push.rocks/smartpuppeteer": "^2.9.0",
|
|
34
34
|
"ipaddr.js": "^2.5.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
package/readme.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Parent-owned, resource-centric Chromium runtime with revisioned attachment fencing, authenticated human and agent control, fail-closed egress, bounded artifacts, and Flex/MCP adapters.
|
|
4
4
|
|
|
5
|
+
## Selected-tab DevTools
|
|
6
|
+
|
|
7
|
+
Set the trusted host option `devTools: true` to enable `humanLease.openDevTools({
|
|
8
|
+
tabId, onMessage, onClose }, operationOptions?)`. Agent leases cannot acquire an
|
|
9
|
+
inspector. The returned connection exposes `tabId`, `browserVersion`,
|
|
10
|
+
`send(message)`, and `close()` using SmartPuppeteer's bounded CDP contract.
|
|
11
|
+
|
|
12
|
+
DevTools commands run concurrently on a separate lane, so pausing JavaScript does
|
|
13
|
+
not queue `Debugger.resume` behind a pending evaluation. The lane reserves interrupt
|
|
14
|
+
capacity and applies the normal authorization hook and audit policy to every command;
|
|
15
|
+
audit records contain the method and outcome, never expressions or response bodies.
|
|
16
|
+
Lease, attachment, and browser incarnation authority are rechecked before execution
|
|
17
|
+
and around every delivered event. Revocation closes pending and late-opening
|
|
18
|
+
attachments. Failed cleanup terminates the exact owned browser incarnation.
|
|
19
|
+
|
|
20
|
+
Await each `onMessage` delivery to preserve transport backpressure. Closing an
|
|
21
|
+
inspector does not close the human lease or its video peer. The embedding application
|
|
22
|
+
must close the inspector when changing the inspected tab or replacing its transport.
|
|
23
|
+
No browser debugging port or browser-wide target discovery is exposed. Pair this
|
|
24
|
+
connection with `DevToolsFrontend` from `@push.rocks/smartbrowser/web` for the official
|
|
25
|
+
Chrome DevTools UI.
|
|
26
|
+
|
|
5
27
|
## Native video viewers
|
|
6
28
|
|
|
7
29
|
Human leases expose `openVideoPeer(options?)`, `answerVideoPeer(negotiationId, description, options?)`, `closeVideoPeer(options?)`, and `getVideoStatistics(options?)`. Each operation runs through the resource's bounded, authorized and audited operation queue. Peer IDs are private to the lease; offers expose the negotiation ID and exact tab/generation/viewport source identity. Agent leases cannot open media peers. Releasing or revoking a human lease closes only its peer, preserving other viewers and agent work. Failed peer cleanup remains owned for a subsequent release attempt.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@modelprofile.com/browser-runtime',
|
|
6
|
-
version: '5.
|
|
6
|
+
version: '5.3.0',
|
|
7
7
|
description: 'Parent-owned, resource-centric Chromium runtime with revisioned attachment fencing, authenticated human and agent control, fail-closed egress, bounded artifacts, and Flex/MCP adapters.'
|
|
8
8
|
}
|
package/ts/classes.runtime.ts
CHANGED
|
@@ -105,6 +105,7 @@ interface INormalizedRuntimeOptions {
|
|
|
105
105
|
frameAcknowledgementTimeoutMs: number;
|
|
106
106
|
screencast: INormalizedScreencastOptions;
|
|
107
107
|
video: Required<plugins.smartpuppeteer.ILiveVideoOptions>;
|
|
108
|
+
devTools: boolean;
|
|
108
109
|
egress: NonNullable<IBrowserRuntimeOptions['egress']>;
|
|
109
110
|
ownership?: IBrowserRuntimeTestingOptions['ownership'];
|
|
110
111
|
beforeLeasePublication?: IBrowserRuntimeTestingOptions['beforeLeasePublication'];
|
|
@@ -144,10 +145,25 @@ interface ILeaseRecord {
|
|
|
144
145
|
videoPeerId: string;
|
|
145
146
|
videoPeerMayExist: boolean;
|
|
146
147
|
frameCaptureUsed: boolean;
|
|
148
|
+
devTools?: IDevToolsRecord;
|
|
147
149
|
heldKeys: Map<string, plugins.smartpuppeteer.ILiveBrowserKeyInput>;
|
|
148
150
|
heldButtons: Map<string, plugins.smartpuppeteer.ILiveBrowserMouseInput>;
|
|
149
151
|
}
|
|
150
152
|
|
|
153
|
+
interface IDevToolsRecord {
|
|
154
|
+
authority: TBrowserRuntimeLeaseAuthority;
|
|
155
|
+
session: ILiveBrowserSessionLike;
|
|
156
|
+
controller: AbortController;
|
|
157
|
+
connection?: plugins.smartpuppeteer.ILiveBrowserDevToolsConnection;
|
|
158
|
+
opening?: Promise<plugins.smartpuppeteer.ILiveBrowserDevToolsConnection>;
|
|
159
|
+
closePromise?: Promise<void>;
|
|
160
|
+
pending: Set<Promise<void>>;
|
|
161
|
+
commands: number;
|
|
162
|
+
interrupts: number;
|
|
163
|
+
closed: boolean;
|
|
164
|
+
removeAbortListener(): void;
|
|
165
|
+
}
|
|
166
|
+
|
|
151
167
|
export interface IBrowserRuntimeLeaseRenewalOptions {
|
|
152
168
|
signal?: AbortSignal;
|
|
153
169
|
/** Lifetime from successful reauthorization; defaults to the runtime capability lifetime. */
|
|
@@ -318,6 +334,9 @@ export class BrowserRuntime {
|
|
|
318
334
|
if (options.beforeOperation !== undefined && typeof options.beforeOperation !== 'function') {
|
|
319
335
|
throw new BrowserRuntimeError('INVALID_INPUT', 'beforeOperation must be a function');
|
|
320
336
|
}
|
|
337
|
+
if (options.devTools !== undefined && typeof options.devTools !== 'boolean') {
|
|
338
|
+
throw new BrowserRuntimeError('INVALID_INPUT', 'devTools must be a boolean');
|
|
339
|
+
}
|
|
321
340
|
const testingOptions = browserRuntimeTesting in options
|
|
322
341
|
&& options[browserRuntimeTesting] === true
|
|
323
342
|
? options as IBrowserRuntimeTestingOptions
|
|
@@ -570,6 +589,7 @@ export class BrowserRuntime {
|
|
|
570
589
|
),
|
|
571
590
|
screencast,
|
|
572
591
|
video: plugins.smartpuppeteer.normalizeLiveVideoOptions(options.video ?? {}),
|
|
592
|
+
devTools: options.devTools ?? false,
|
|
573
593
|
egress: options.egress ?? {},
|
|
574
594
|
ownership: testingOptions?.ownership,
|
|
575
595
|
beforeLeasePublication: testingOptions?.beforeLeasePublication,
|
|
@@ -1374,6 +1394,148 @@ export class BrowserRuntime {
|
|
|
1374
1394
|
});
|
|
1375
1395
|
}
|
|
1376
1396
|
|
|
1397
|
+
/** @internal */
|
|
1398
|
+
public async leaseOpenDevTools(lease: ILeaseRecord, options: plugins.smartpuppeteer.ILiveBrowserDevToolsOptions,
|
|
1399
|
+
operationOptions: IBrowserRuntimeOperationOptions = {}): Promise<plugins.smartpuppeteer.ILiveBrowserDevToolsConnection> {
|
|
1400
|
+
this.requireHuman(lease);
|
|
1401
|
+
if (!this.options.devTools) throw new BrowserRuntimeError('CAPABILITY_INVALID', 'DevTools is not enabled.');
|
|
1402
|
+
if (!options || typeof options.onMessage !== 'function' || typeof options.onClose !== 'function') {
|
|
1403
|
+
throw new BrowserRuntimeError('INVALID_INPUT');
|
|
1404
|
+
}
|
|
1405
|
+
const tabId = validateBoundedString(options.tabId, 'tabId', 1, 128);
|
|
1406
|
+
let created: IDevToolsRecord | undefined;
|
|
1407
|
+
try {
|
|
1408
|
+
return await this.runOperation(lease, 'openDevTools', 'devtools', operationOptions, async (signal, session) => {
|
|
1409
|
+
if (!session.openDevTools) throw new BrowserRuntimeError('CAPABILITY_INVALID', 'The browser adapter does not support DevTools.');
|
|
1410
|
+
if (lease.devTools) await this.closeLeaseDevTools(lease, lease.devTools);
|
|
1411
|
+
const controller = new AbortController();
|
|
1412
|
+
const record: IDevToolsRecord = {
|
|
1413
|
+
authority: this.createLeaseAuthority(lease), session, controller,
|
|
1414
|
+
pending: new Set(), commands: 0, interrupts: 0, closed: false,
|
|
1415
|
+
removeAbortListener: () => lease.controller.signal.removeEventListener('abort', abort),
|
|
1416
|
+
};
|
|
1417
|
+
const abort = (): void => { this.trackCleanup(this.closeLeaseDevTools(lease, record)); };
|
|
1418
|
+
lease.controller.signal.addEventListener('abort', abort, { once: true });
|
|
1419
|
+
created = record;
|
|
1420
|
+
lease.devTools = record;
|
|
1421
|
+
record.opening = session.openDevTools({ tabId,
|
|
1422
|
+
onMessage: async message => {
|
|
1423
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1424
|
+
await options.onMessage(message);
|
|
1425
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1426
|
+
},
|
|
1427
|
+
onClose: reason => {
|
|
1428
|
+
record.closed = true;
|
|
1429
|
+
controller.abort(new BrowserRuntimeError('ABORTED'));
|
|
1430
|
+
record.removeAbortListener();
|
|
1431
|
+
options.onClose(reason);
|
|
1432
|
+
},
|
|
1433
|
+
}, { signal });
|
|
1434
|
+
const connection = await record.opening;
|
|
1435
|
+
record.connection = connection;
|
|
1436
|
+
try {
|
|
1437
|
+
signal.throwIfAborted();
|
|
1438
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1439
|
+
} catch (error) { await this.closeLeaseDevTools(lease, record); throw error; }
|
|
1440
|
+
return {
|
|
1441
|
+
tabId: connection.tabId,
|
|
1442
|
+
browserVersion: connection.browserVersion,
|
|
1443
|
+
send: message => this.sendLeaseDevTools(lease, record, message),
|
|
1444
|
+
close: () => this.closeLeaseDevTools(lease, record),
|
|
1445
|
+
};
|
|
1446
|
+
});
|
|
1447
|
+
} catch (error) {
|
|
1448
|
+
if (created) await this.closeLeaseDevTools(lease, created);
|
|
1449
|
+
throw error;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
private requireDevToolsAuthority(lease: ILeaseRecord, record: IDevToolsRecord): void {
|
|
1454
|
+
this.requireHuman(lease);
|
|
1455
|
+
if (record.closed || record.controller.signal.aborted || lease.devTools !== record
|
|
1456
|
+
|| lease.slot.session !== record.session || !this.isLeaseAuthorityCurrent(lease, record.authority)) {
|
|
1457
|
+
throw new BrowserRuntimeError('CAPABILITY_REVOKED');
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
private async sendLeaseDevTools(lease: ILeaseRecord, record: IDevToolsRecord, message: string): Promise<void> {
|
|
1462
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1463
|
+
const limits = plugins.smartpuppeteer.liveBrowserDevToolsLimits;
|
|
1464
|
+
if (typeof message !== 'string' || plugins.Buffer.byteLength(message) > limits.commandBytes) {
|
|
1465
|
+
throw new BrowserRuntimeError('INVALID_INPUT');
|
|
1466
|
+
}
|
|
1467
|
+
let command: { method?: unknown };
|
|
1468
|
+
try { command = JSON.parse(message); } catch { throw new BrowserRuntimeError('INVALID_INPUT'); }
|
|
1469
|
+
if (!command || typeof command.method !== 'string' || !/^[A-Za-z]+\.[A-Za-z]+$/.test(command.method)) {
|
|
1470
|
+
throw new BrowserRuntimeError('INVALID_INPUT');
|
|
1471
|
+
}
|
|
1472
|
+
const action = command.method;
|
|
1473
|
+
const interrupt = limits.interruptMethods.includes(action);
|
|
1474
|
+
if (interrupt ? record.interrupts >= limits.interruptCommands : record.commands >= limits.commands) {
|
|
1475
|
+
throw new BrowserRuntimeError('QUOTA_EXCEEDED');
|
|
1476
|
+
}
|
|
1477
|
+
if (interrupt) record.interrupts++; else record.commands++;
|
|
1478
|
+
const startedAt = Date.now();
|
|
1479
|
+
const operation: IOperationRecord = {
|
|
1480
|
+
operationId: randomId(), lease, controller: record.controller, action, startedAt,
|
|
1481
|
+
session: record.session, incarnationGeneration: record.authority.incarnationGeneration,
|
|
1482
|
+
promise: Promise.resolve(),
|
|
1483
|
+
};
|
|
1484
|
+
const identity = this.createOperationIdentity(lease, operation, action, 'devtools', startedAt);
|
|
1485
|
+
const task = (async () => {
|
|
1486
|
+
let failed = false;
|
|
1487
|
+
let failure: unknown;
|
|
1488
|
+
try {
|
|
1489
|
+
await this.runBeforeOperation(identity, record.controller.signal);
|
|
1490
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1491
|
+
await record.connection!.send(message);
|
|
1492
|
+
this.requireDevToolsAuthority(lease, record);
|
|
1493
|
+
} catch (error) { failed = true; failure = error; }
|
|
1494
|
+
finally {
|
|
1495
|
+
try {
|
|
1496
|
+
await this.emitAudit(Object.freeze({ ...identity, phase: failed ? 'failed' : 'completed',
|
|
1497
|
+
finishedAt: Date.now(), ...(failed ? { errorCode: this.operationErrorCode(failure) } : {}) }));
|
|
1498
|
+
} finally {
|
|
1499
|
+
if (interrupt) record.interrupts--; else record.commands--;
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
if (failed) throw failure;
|
|
1503
|
+
})();
|
|
1504
|
+
record.pending.add(task);
|
|
1505
|
+
void task.then(() => record.pending.delete(task), () => record.pending.delete(task));
|
|
1506
|
+
return task;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
private closeLeaseDevTools(lease: ILeaseRecord, record: IDevToolsRecord): Promise<void> {
|
|
1510
|
+
if (record.closePromise) return record.closePromise;
|
|
1511
|
+
record.closed = true;
|
|
1512
|
+
record.controller.abort(new BrowserRuntimeError('ABORTED'));
|
|
1513
|
+
record.removeAbortListener();
|
|
1514
|
+
const closing = (async () => {
|
|
1515
|
+
try {
|
|
1516
|
+
const detached = await waitBounded((async () => {
|
|
1517
|
+
// Opening may still be completing when lease revocation arrives.
|
|
1518
|
+
await Promise.resolve();
|
|
1519
|
+
const connection = record.connection ?? await record.opening?.catch(() => undefined);
|
|
1520
|
+
await connection?.close();
|
|
1521
|
+
})(), this.options.quiescenceTimeoutMs + 3500);
|
|
1522
|
+
if (!detached.settled) throw new BrowserRuntimeError('TIMEOUT');
|
|
1523
|
+
const pending = await waitBounded(Promise.allSettled([...record.pending]),
|
|
1524
|
+
this.options.quiescenceTimeoutMs + this.options.auditTimeoutMs + this.options.beforeOperationTimeoutMs);
|
|
1525
|
+
if (!pending.settled) throw new BrowserRuntimeError('TIMEOUT');
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
await this.terminateRegisteredResourceInternal(lease.slot, false, {
|
|
1528
|
+
session: record.session, incarnationGeneration: record.authority.incarnationGeneration,
|
|
1529
|
+
});
|
|
1530
|
+
throw error;
|
|
1531
|
+
} finally {
|
|
1532
|
+
if (lease.devTools === record) lease.devTools = undefined;
|
|
1533
|
+
}
|
|
1534
|
+
})();
|
|
1535
|
+
record.closePromise = closing;
|
|
1536
|
+
return closing;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1377
1539
|
/** @internal */
|
|
1378
1540
|
public async leaseAnswerVideoPeer(lease: ILeaseRecord, negotiationId: string,
|
|
1379
1541
|
description: plugins.smartpuppeteer.ILiveVideoDescription, options: IBrowserRuntimeOperationOptions = {}): Promise<void> {
|
|
@@ -2013,6 +2175,7 @@ export class BrowserRuntime {
|
|
|
2013
2175
|
usePipe: true,
|
|
2014
2176
|
allowEvaluation: true,
|
|
2015
2177
|
video: this.options.video,
|
|
2178
|
+
allowDevTools: this.options.devTools,
|
|
2016
2179
|
screencast: {
|
|
2017
2180
|
enabled: false, maxOutstandingFrames: this.options.maxOutstandingFrames,
|
|
2018
2181
|
quality: this.options.screencast.quality,
|
|
@@ -3477,6 +3640,7 @@ export class BrowserRuntime {
|
|
|
3477
3640
|
release();
|
|
3478
3641
|
}
|
|
3479
3642
|
await this.closeFrameSubscriptionIfLease(lease);
|
|
3643
|
+
if (lease.devTools) await this.closeLeaseDevTools(lease, lease.devTools);
|
|
3480
3644
|
if (operation) {
|
|
3481
3645
|
const settled = await waitBounded(operation.promise, this.options.quiescenceTimeoutMs);
|
|
3482
3646
|
if (!settled.settled) {
|
|
@@ -4381,6 +4545,11 @@ export class BrowserRuntimeLease {
|
|
|
4381
4545
|
return this.runtime.leaseOpenVideoPeer(this.record, options);
|
|
4382
4546
|
}
|
|
4383
4547
|
|
|
4548
|
+
public openDevTools(options: plugins.smartpuppeteer.ILiveBrowserDevToolsOptions,
|
|
4549
|
+
operationOptions?: IBrowserRuntimeOperationOptions): Promise<plugins.smartpuppeteer.ILiveBrowserDevToolsConnection> {
|
|
4550
|
+
return this.runtime.leaseOpenDevTools(this.record, options, operationOptions);
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4384
4553
|
public answerVideoPeer(negotiationId: string, description: plugins.smartpuppeteer.ILiveVideoDescription,
|
|
4385
4554
|
options?: IBrowserRuntimeOperationOptions): Promise<void> {
|
|
4386
4555
|
return this.runtime.leaseAnswerVideoPeer(this.record, negotiationId, description, options);
|
package/ts/interfaces.ts
CHANGED
|
@@ -134,6 +134,7 @@ export type TBrowserRuntimeOperationClassification =
|
|
|
134
134
|
| 'raw-input'
|
|
135
135
|
| 'frame-stream'
|
|
136
136
|
| 'video-peer'
|
|
137
|
+
| 'devtools'
|
|
137
138
|
| 'viewport'
|
|
138
139
|
| 'navigation'
|
|
139
140
|
| 'tab'
|
|
@@ -160,6 +161,8 @@ export type TBrowserRuntimeAuditEvent = TBrowserRuntimeOperationIdentity & {
|
|
|
160
161
|
};
|
|
161
162
|
|
|
162
163
|
export interface ILiveBrowserSessionLike {
|
|
164
|
+
openDevTools?(options: plugins.smartpuppeteer.ILiveBrowserDevToolsOptions,
|
|
165
|
+
operationOptions?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<plugins.smartpuppeteer.ILiveBrowserDevToolsConnection>;
|
|
163
166
|
start(options?: plugins.smartpuppeteer.ILiveBrowserOperationOptions): Promise<void>;
|
|
164
167
|
stop(): Promise<void>;
|
|
165
168
|
terminate(
|
|
@@ -300,6 +303,8 @@ export interface IBrowserRuntimeOptions {
|
|
|
300
303
|
screencast?: IBrowserRuntimeScreencastOptions;
|
|
301
304
|
/** Trusted host configuration; defaults to direct ICE and automatic GPU support. */
|
|
302
305
|
video?: plugins.smartpuppeteer.ILiveVideoOptions;
|
|
306
|
+
/** Enables selected-tab DevTools for human leases only. Disabled by default. */
|
|
307
|
+
devTools?: boolean;
|
|
303
308
|
egress?: Omit<IBrowserEgressProxyOptions, 'projectId' | 'browserResourceId'>;
|
|
304
309
|
artifacts?: Omit<IBrowserArtifactStoreOptions, 'rootDirectory'>;
|
|
305
310
|
}
|