@modelprofile.com/browser-runtime 4.1.1 → 4.2.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.
@@ -8,4 +8,4 @@ export { BrowserRuntimeError } from './errors.js';
8
8
  export { createBrowserRuntimeMcpHttpHandler } from './mcp.js';
9
9
  export type { TAcquireBrowserRuntimeLeaseOptions } from './classes.runtime.js';
10
10
  export type { TBrowserRuntimeErrorCode } from './errors.js';
11
- export type { IAttachTrustedFramedPeerOptions, IApplyBrowserAttachmentBindingRequest, IBrowserAttachmentBinding, IBrowserActionStateResult, IBrowserArtifactMetadata, IBrowserArtifactStoreOptions, IBrowserMcpAuthenticatedBinding, TBrowserCapabilityAuthorizationRequest, TBrowserCapabilityDescriptor, IBrowserClickAction, IBrowserEgressConnectionOptions, IBrowserEgressProxyOptions, IBrowserEgressProxyStats, IBrowserFlexCapabilityBinding, IBrowserFlexSessionId, IBrowserFillAction, IBrowserNavigateAction, IBrowserObservationResult, IBrowserOpenCodeSessionId, IBrowserPressAction, TBrowserRuntimeAuditEvent, TBrowserRuntimeLeaseAuthority, TBrowserRuntimeOperationClassification, TBrowserRuntimeOperationIdentity, IBrowserRuntimeFlexToolProviderOptions, IBrowserRuntimeFrameSubscription, IBrowserRuntimeFramedClientOptions, IBrowserRuntimeMcpOptions, IBrowserRuntimeOperationOptions, IBrowserRuntimeOptions, IBrowserResourceKey, IBrowserResourceRegistration, IBrowserRuntimeState, IBrowserRuntimeTabState, IBrowserScreenshotAction, IBrowserScreenshotResult, IBrowserSnapshotAction, ICreateBrowserResourceRequest, TIssueBrowserCapabilityRequest, TIssuedBrowserCapability, TQualifiedBrowserSessionId, IRegisterBrowserResourceRequest, IResolvedBrowserFlexCapability, TBrowserActorRole, TBrowserAgentAction, TBrowserAgentActionResult, TBrowserCapabilitySource, TBrowserDnsResolver, TBrowserEgressConnector, TBrowserHarnessId, TBrowserRuntimeEvent, } from './interfaces.js';
11
+ export type { IAttachTrustedFramedPeerOptions, IApplyBrowserAttachmentBindingRequest, IBrowserAttachmentBinding, IBrowserActionStateResult, IBrowserArtifactMetadata, IBrowserArtifactStoreOptions, IBrowserMcpAuthenticatedBinding, TBrowserCapabilityAuthorizationRequest, TBrowserCapabilityDescriptor, IBrowserClickAction, IBrowserEgressConnectionOptions, IBrowserEgressProxyOptions, IBrowserEgressProxyStats, IBrowserFlexCapabilityBinding, IBrowserFlexSessionId, IBrowserFillAction, IBrowserNavigateAction, IBrowserObservationResult, IBrowserOpenCodeSessionId, IBrowserPressAction, TBrowserRuntimeAuditEvent, TBrowserRuntimeLeaseAuthority, TBrowserRuntimeOperationClassification, TBrowserRuntimeOperationIdentity, IBrowserRuntimeFlexToolProviderOptions, IBrowserRuntimeFrameSubscription, IBrowserRuntimeFramedClientOptions, IBrowserRuntimeMcpOptions, IBrowserRuntimeOperationOptions, IBrowserRuntimeOptions, IBrowserRuntimeScreencastOptions, IBrowserResourceKey, IBrowserResourceRegistration, IBrowserRuntimeState, IBrowserRuntimeTabState, IBrowserScreenshotAction, IBrowserScreenshotResult, IBrowserSnapshotAction, ICreateBrowserResourceRequest, TIssueBrowserCapabilityRequest, TIssuedBrowserCapability, TQualifiedBrowserSessionId, IRegisterBrowserResourceRequest, IResolvedBrowserFlexCapability, TBrowserActorRole, TBrowserAgentAction, TBrowserAgentActionResult, TBrowserCapabilitySource, TBrowserDnsResolver, TBrowserEgressConnector, TBrowserHarnessId, TBrowserRuntimeEvent, } from './interfaces.js';
@@ -147,6 +147,13 @@ export interface IBrowserRuntimeEnvironment {
147
147
  platform: NodeJS.Platform;
148
148
  uid: number | undefined;
149
149
  }
150
+ export interface IBrowserRuntimeScreencastOptions {
151
+ quality?: number;
152
+ maxWidth?: number;
153
+ maxHeight?: number;
154
+ everyNthFrame?: number;
155
+ firstFrameTimeoutMs?: number;
156
+ }
150
157
  export interface IBrowserRuntimeOptions {
151
158
  runtimeDirectory: string;
152
159
  authorizeCapability(request: TBrowserCapabilityAuthorizationRequest, signal: AbortSignal): Promise<boolean> | boolean;
@@ -176,6 +183,7 @@ export interface IBrowserRuntimeOptions {
176
183
  maxFrameBytes?: number;
177
184
  maxOutstandingFrames?: number;
178
185
  frameAcknowledgementTimeoutMs?: number;
186
+ screencast?: IBrowserRuntimeScreencastOptions;
179
187
  egress?: Omit<IBrowserEgressProxyOptions, 'projectId' | 'browserResourceId'>;
180
188
  artifacts?: Omit<IBrowserArtifactStoreOptions, 'rootDirectory'>;
181
189
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelprofile.com/browser-runtime",
3
- "version": "4.1.1",
3
+ "version": "4.2.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",
@@ -26,18 +26,18 @@
26
26
  "node": ">=24 <27"
27
27
  },
28
28
  "dependencies": {
29
- "@modelprofile.com/flexharness": "^4.0.0",
30
- "@push.rocks/smartagent": "^4.8.0",
29
+ "@modelprofile.com/flexharness": "^5.4.0",
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.6.0",
33
+ "@push.rocks/smartpuppeteer": "^2.7.0",
34
34
  "ipaddr.js": "^2.5.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@git.zone/tsbuild": "4.4.2",
38
38
  "@git.zone/tsrun": "2.0.6",
39
39
  "@git.zone/tstest": "4.0.0",
40
- "@types/node": "26.2.0"
40
+ "@types/node": "26.4.1"
41
41
  },
42
42
  "files": [
43
43
  "ts/**/*",
package/readme.hints.md CHANGED
@@ -47,7 +47,10 @@ Durable implementation findings for `@modelprofile.com/browser-runtime`.
47
47
  - Framed messages contain no identity selectors. The parent binds project, resource, attachment authority/revision, actor, peer, role, source, qualified session, Flex scope, channel, and exact run out of band.
48
48
  - One qualified session can own multiple resource-specific framed channels. Capability revocation owns server-peer disconnect; peer-initiated release/close revokes only that channel's capability without recursively disconnecting itself.
49
49
  - Framed request counts and queued write bytes are bounded. Runtime shutdown has a bounded caller-visible cleanup deadline while retaining in-flight cleanup ownership for retry.
50
- - Frame delivery owns a bounded map of exact identities and configures SmartPuppeteer's separate private CDP-to-ack map to the same limit. Equal limits prevent private eviction while the application map has spare capacity, but private-first retirement at full capacity can make an exact acknowledgement fulfill `{ accepted: false }`. Both fulfilled booleans settle the application entry without proving successful upstream retirement; rejection or timeout fails closed. Application acknowledgement timeout and failed delivery deliberately fail the lease regardless of a fulfilled boolean. There is no cumulative frame protocol.
50
+ - Frame delivery owns a bounded map of exact identities and configures SmartPuppeteer's separate private CDP-to-ack map to the same limit. Equal limits prevent private eviction while the application map has spare capacity, but private-first retirement at full capacity can make an exact acknowledgement fulfill `{ accepted: false }`. Both fulfilled booleans settle the application entry without proving successful upstream retirement; a rejected or timed-out acknowledgement operation toward SmartPuppeteer fails closed. Failed delivery (a throwing listener) deliberately fails the lease regardless of a fulfilled boolean. There is no cumulative frame protocol.
51
+ - A late application acknowledgement (`frameAcknowledgementTimeoutMs`, default 10 s) is retired through `retireOutstandingFrame(subscription, key, false)`, the same path as oldest-first eviction: the entry is acknowledged toward SmartPuppeteer and the lease is untouched. It must never route through `handleFrameFailure`; one slow viewer acknowledgement previously fenced the slot and terminated the whole Chromium incarnation. A later explicit acknowledgement of the retired identity returns `false`.
52
+ - A frame above `maxFrameBytes` is dropped, acknowledged in the background with `failLease=false`, and reported as `FRAME_TOO_LARGE` with `fatal: false`. `highestSequence` is advanced before the size check so the following frames stay valid. During an active refresh the oversized frame still fails the refresh with `FRAME_TOO_LARGE`, but the pushed error event is non-fatal.
53
+ - `screencast` (`quality` 0..100 default 70, `maxWidth`/`maxHeight` 1..4096 each with `maxWidth * maxHeight <= 8_294_400` and defaults 2560/1600, `everyNthFrame` 1..60 default 1, `firstFrameTimeoutMs` 1000..60000 default left to SmartPuppeteer) is validated in the constructor with `validateExactKeys` plus the integer validators and forwarded to `LiveBrowserSession` next to `maxOutstandingFrames`. The ceilings deliberately match `@push.rocks/smartpuppeteer` 2.6's `LiveBrowserSession` validation (`maxViewportPixelArea = 8294400`, `maxTimeoutMs = 60000`); a looser runtime bound would let `new BrowserRuntime()` succeed and every incarnation launch fail instead. Without `quality`/`maxWidth`/`maxHeight`, SmartPuppeteer's defaults (quality 80, unbounded size) produced multi-megabyte frames on device-pixel-ratio 2 viewers.
51
54
  - During refresh, application entries plus refresh-owned acknowledgement promises share the same hard frame-window bound. ACK ownership is fixed at admission, refresh failures defer until the operation reservation is gone, and the exact failure fence completes before terminal audit, caller settlement, or FIFO advancement. Lifecycle teardown explicitly abandons an exact refresh record so stale state cannot retain `BUSY` admission.
52
55
  - Runtime state and error events preserve diagnostic messages only after truncating them to 2,048 characters. The first fatal session error invalidates exact capability admission synchronously, delivers once to the captured exact subscriber, and schedules revocation in `finally` so a throwing listener cannot retain authority.
53
56
  - Flex resolves only a capability token, and the provider's run must exactly match its trusted framed client. SmartAgent exposes exactly navigate, snapshot, screenshot, click, fill, and press.
package/readme.md CHANGED
@@ -122,11 +122,17 @@ Operations from one valid lease enter a strict bounded FIFO. `maxQueuedOperation
122
122
 
123
123
  `lease.getAuthority()` returns an immutable process-local lease authority containing the runtime authority ID, exported `authorityGeneration`, incarnation generation, and complete capability binding. Every snapshot also binds the exact `capabilityId` and `leaseId`. `lease.isAuthorityCurrent(authority)` performs an exact synchronous revalidation suitable for a host-owned virtual stream. These values are not durable Controller state and do not replace attachment checks against the Controller database.
124
124
 
125
- Human frame delivery keeps a bounded exact-identity application window. `maxOutstandingFrames` defaults to 4 and accepts values from 1 through 32. Runtime passes the same bound to SmartPuppeteer's private CDP-to-ack window; the windows remain separately owned, but equal limits prevent private eviction while the application window still has spare capacity. At full capacity SmartPuppeteer retires its oldest private entry before publishing the next frame, so a later exact acknowledgement can fulfill with `{ accepted: false }`. A fulfilled `true` or `false` settles the Runtime entry locally without fencing; `false` does not prove that upstream retirement succeeded. Rejected or timed-out acknowledgement operations fail closed, as do application acknowledgement timeout and failed-delivery retirement regardless of a fulfilled boolean. Frame acknowledgement stays outside the operation FIFO.
125
+ Human frame delivery keeps a bounded exact-identity application window. `maxOutstandingFrames` defaults to 4 and accepts values from 1 through 32. Runtime passes the same bound to SmartPuppeteer's private CDP-to-ack window; the windows remain separately owned, but equal limits prevent private eviction while the application window still has spare capacity. At full capacity SmartPuppeteer retires its oldest private entry before publishing the next frame, so a later exact acknowledgement can fulfill with `{ accepted: false }`. A fulfilled `true` or `false` settles the Runtime entry locally without fencing; `false` does not prove that upstream retirement succeeded. Rejected or timed-out acknowledgement operations toward SmartPuppeteer fail closed, as does failed-delivery retirement regardless of a fulfilled boolean. Frame acknowledgement stays outside the operation FIFO.
126
+
127
+ A late application acknowledgement is not a lease failure. `frameAcknowledgementTimeoutMs` defaults to 10,000 milliseconds and accepts values from 100 through 60,000; when a delivered frame is still unacknowledged after that time, Runtime retires the entry through the same path as oldest-first window eviction: it acknowledges the frame toward SmartPuppeteer and leaves the lease, subscription, and incarnation untouched. A later explicit acknowledgement of that retired identity returns `false`. The same timeout still bounds each acknowledgement operation toward SmartPuppeteer, and that bound remains fail closed.
128
+
129
+ An oversized frame is dropped, not fatal. `maxFrameBytes` defaults to 4 MiB and accepts values from 64 KiB through 16 MiB. A frame above the bound is acknowledged toward SmartPuppeteer in the background, never enters the application window, and is reported once on the subscription as `{ type: 'error', error: { code: 'FRAME_TOO_LARGE', fatal: false, tabId } }`. The sequence watermark advances past the dropped frame so later frames remain valid and continue to be delivered.
130
+
131
+ `screencast` tunes the Chromium screencast that SmartPuppeteer starts for every incarnation. `quality` is the JPEG quality from 0 through 100 and defaults to 70. `maxWidth` and `maxHeight` accept values from 1 through 4,096 each, their product must not exceed 8,294,400 pixels (SmartPuppeteer's ceiling, so 3,840×2,160 is accepted and 4,096×4,096 is rejected with `INVALID_INPUT`), they default to 2,560 and 1,600, and they make Chromium scale captured frames to fit. `everyNthFrame` accepts values from 1 through 60 and defaults to 1. `firstFrameTimeoutMs` accepts values from 1,000 through 60,000 and is left to SmartPuppeteer's default when omitted. Runtime forwards these values together with `maxOutstandingFrames`; the defaults keep frames from device-pixel-ratio 2 viewers well below `maxFrameBytes`.
126
132
 
127
133
  Human state and error events retain an optional diagnostic `message` bounded to 2,048 characters. A fatal session error synchronously invalidates the exact capability before its captured subscriber is notified once, then revokes and cleans up the lease even when that subscriber throws.
128
134
 
129
- `humanLease.refreshFrameStream(options?: IBrowserRuntimeOperationOptions): Promise<void>` requires the lease's exact active frame subscription and enters the same audited FIFO as other browser mutations. Runtime retires the old application window, asks SmartPuppeteer for a new screencast generation, and succeeds only after the exact first new-generation frame was delivered through that subscription and validated against the current tab, viewport, lease, session, and incarnation. Existing and refresh-owned acknowledgement work share `maxOutstandingFrames`; synchronous listener acknowledgements cannot create an unbounded promise set. A missing or pre-execution-replaced subscription fails with `BUSY`. Refresh protocol, delivery, retirement, or acknowledgement failure returns `FRAME_STREAM_FAILED` or `FRAME_TOO_LARGE` only after the exact incarnation is fenced; stale authority returns `ABORTED` without touching its replacement. Pass `options.signal` for caller cancellation; active cancellation preserves a successfully restored stream.
135
+ `humanLease.refreshFrameStream(options?: IBrowserRuntimeOperationOptions): Promise<void>` requires the lease's exact active frame subscription and enters the same audited FIFO as other browser mutations. Runtime retires the old application window, asks SmartPuppeteer for a new screencast generation, and succeeds only after the exact first new-generation frame was delivered through that subscription and validated against the current tab, viewport, lease, session, and incarnation. Existing and refresh-owned acknowledgement work share `maxOutstandingFrames`; synchronous listener acknowledgements cannot create an unbounded promise set. A missing or pre-execution-replaced subscription fails with `BUSY`. Refresh protocol, delivery, retirement, or acknowledgement failure returns `FRAME_STREAM_FAILED` or `FRAME_TOO_LARGE` only after the exact incarnation is fenced; an oversized frame during an active refresh still fails that refresh with `FRAME_TOO_LARGE` while the subscription's error event itself stays `fatal: false`. Stale authority returns `ABORTED` without touching its replacement. Pass `options.signal` for caller cancellation; active cancellation preserves a successfully restored stream.
130
136
 
131
137
  ## Trusted Pipe And Flex
132
138
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@modelprofile.com/browser-runtime',
6
- version: '4.1.1',
6
+ version: '4.2.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
  }
@@ -55,6 +55,17 @@ import {
55
55
  } from './utils.js';
56
56
  import { BrowserRuntimeFramedServerPeer } from './classes.framed.js';
57
57
 
58
+ // @push.rocks/smartpuppeteer LiveBrowserSession rejects screencast bounds above this area.
59
+ const maxScreencastPixelArea = 8_294_400;
60
+
61
+ interface INormalizedScreencastOptions {
62
+ quality: number;
63
+ maxWidth: number;
64
+ maxHeight: number;
65
+ everyNthFrame: number;
66
+ firstFrameTimeoutMs?: number;
67
+ }
68
+
58
69
  interface INormalizedRuntimeOptions {
59
70
  runtimeDirectory: string;
60
71
  authorizeCapability: IBrowserRuntimeOptions['authorizeCapability'];
@@ -89,6 +100,7 @@ interface INormalizedRuntimeOptions {
89
100
  maxFrameBytes: number;
90
101
  maxOutstandingFrames: number;
91
102
  frameAcknowledgementTimeoutMs: number;
103
+ screencast: INormalizedScreencastOptions;
92
104
  egress: NonNullable<IBrowserRuntimeOptions['egress']>;
93
105
  ownership?: IBrowserRuntimeTestingOptions['ownership'];
94
106
  beforeLeasePublication?: IBrowserRuntimeTestingOptions['beforeLeasePublication'];
@@ -295,6 +307,61 @@ export class BrowserRuntime {
295
307
  capabilityMaximumTtlMs,
296
308
  5 * 60_000,
297
309
  );
310
+ const screencastOptions = options.screencast === undefined
311
+ ? {}
312
+ : validateExactKeys(
313
+ options.screencast,
314
+ ['quality', 'maxWidth', 'maxHeight', 'everyNthFrame', 'firstFrameTimeoutMs'],
315
+ 'screencast',
316
+ );
317
+ // Bounds mirror what @push.rocks/smartpuppeteer's LiveBrowserSession accepts, so a runtime
318
+ // that constructs successfully can never launch incarnations that fail on these values.
319
+ const screencast: INormalizedScreencastOptions = {
320
+ quality: validateOptionalInteger(
321
+ screencastOptions.quality,
322
+ 'screencast.quality',
323
+ 0,
324
+ 100,
325
+ 70,
326
+ ),
327
+ maxWidth: validateOptionalInteger(
328
+ screencastOptions.maxWidth,
329
+ 'screencast.maxWidth',
330
+ 1,
331
+ 4096,
332
+ 2560,
333
+ ),
334
+ maxHeight: validateOptionalInteger(
335
+ screencastOptions.maxHeight,
336
+ 'screencast.maxHeight',
337
+ 1,
338
+ 4096,
339
+ 1600,
340
+ ),
341
+ everyNthFrame: validateOptionalInteger(
342
+ screencastOptions.everyNthFrame,
343
+ 'screencast.everyNthFrame',
344
+ 1,
345
+ 60,
346
+ 1,
347
+ ),
348
+ ...(screencastOptions.firstFrameTimeoutMs === undefined
349
+ ? {}
350
+ : {
351
+ firstFrameTimeoutMs: validateInteger(
352
+ screencastOptions.firstFrameTimeoutMs,
353
+ 'screencast.firstFrameTimeoutMs',
354
+ 1000,
355
+ 60_000,
356
+ ),
357
+ }),
358
+ };
359
+ if (screencast.maxWidth * screencast.maxHeight > maxScreencastPixelArea) {
360
+ throw new BrowserRuntimeError(
361
+ 'INVALID_INPUT',
362
+ `screencast.maxWidth * screencast.maxHeight must not exceed ${maxScreencastPixelArea} pixels`,
363
+ );
364
+ }
298
365
  const environment = testingOptions?.environment ?? {
299
366
  platform: process.platform,
300
367
  uid: process.getuid?.(),
@@ -472,6 +539,7 @@ export class BrowserRuntime {
472
539
  60_000,
473
540
  10_000,
474
541
  ),
542
+ screencast,
475
543
  egress: options.egress ?? {},
476
544
  ownership: testingOptions?.ownership,
477
545
  beforeLeasePublication: testingOptions?.beforeLeasePublication,
@@ -1677,6 +1745,13 @@ export class BrowserRuntime {
1677
1745
  allowEvaluation: true,
1678
1746
  screencast: {
1679
1747
  maxOutstandingFrames: this.options.maxOutstandingFrames,
1748
+ quality: this.options.screencast.quality,
1749
+ maxWidth: this.options.screencast.maxWidth,
1750
+ maxHeight: this.options.screencast.maxHeight,
1751
+ everyNthFrame: this.options.screencast.everyNthFrame,
1752
+ ...(this.options.screencast.firstFrameTimeoutMs === undefined
1753
+ ? {}
1754
+ : { firstFrameTimeoutMs: this.options.screencast.firstFrameTimeoutMs }),
1680
1755
  },
1681
1756
  launchOptions: {
1682
1757
  headless: true,
@@ -2613,7 +2688,9 @@ export class BrowserRuntime {
2613
2688
  ): void {
2614
2689
  if (frame.timer || subscription.closed || !subscription.outstanding.has(key)) return;
2615
2690
  const timer = setTimeout(() => {
2616
- this.trackCleanup(this.retireOutstandingFrame(subscription, key, true).then(() => undefined));
2691
+ // A late application acknowledgement retires the entry exactly like oldest-first
2692
+ // eviction: the frame is acknowledged toward the session and the lease is untouched.
2693
+ this.trackCleanup(this.retireOutstandingFrame(subscription, key, false).then(() => undefined));
2617
2694
  }, this.options.frameAcknowledgementTimeoutMs);
2618
2695
  timer.unref();
2619
2696
  frame.timer = timer;
@@ -2725,23 +2802,20 @@ export class BrowserRuntime {
2725
2802
  }
2726
2803
  subscription.highestSequence = acknowledgement.sequence;
2727
2804
  if (event.frame.data.byteLength > this.options.maxFrameBytes) {
2805
+ // An oversized frame is dropped, not fatal: the sequence watermark already advanced so
2806
+ // later frames stay valid, and the subscriber is told without losing its lease.
2728
2807
  if (refresh) {
2729
2808
  this.failFrameRefresh(refresh, 'FRAME_TOO_LARGE');
2730
2809
  this.pushToSubscription(subscription, {
2731
2810
  type: 'error',
2732
- error: { code: 'FRAME_TOO_LARGE', fatal: true, tabId: event.frame.tabId },
2811
+ error: { code: 'FRAME_TOO_LARGE', fatal: false, tabId: event.frame.tabId },
2733
2812
  });
2734
2813
  return;
2735
2814
  }
2736
- this.trackCleanup(this.acknowledgeFrameInBackground(
2737
- slot,
2738
- session,
2739
- acknowledgement,
2740
- true,
2741
- ));
2815
+ this.trackCleanup(this.acknowledgeFrameInBackground(slot, session, acknowledgement));
2742
2816
  this.pushToSubscription(subscription, {
2743
2817
  type: 'error',
2744
- error: { code: 'FRAME_TOO_LARGE', fatal: true, tabId: event.frame.tabId },
2818
+ error: { code: 'FRAME_TOO_LARGE', fatal: false, tabId: event.frame.tabId },
2745
2819
  });
2746
2820
  return;
2747
2821
  }
package/ts/index.ts CHANGED
@@ -43,6 +43,7 @@ export type {
43
43
  IBrowserRuntimeMcpOptions,
44
44
  IBrowserRuntimeOperationOptions,
45
45
  IBrowserRuntimeOptions,
46
+ IBrowserRuntimeScreencastOptions,
46
47
  IBrowserResourceKey,
47
48
  IBrowserResourceRegistration,
48
49
  IBrowserRuntimeState,
package/ts/interfaces.ts CHANGED
@@ -236,6 +236,14 @@ export interface IBrowserRuntimeEnvironment {
236
236
  uid: number | undefined;
237
237
  }
238
238
 
239
+ export interface IBrowserRuntimeScreencastOptions {
240
+ quality?: number;
241
+ maxWidth?: number;
242
+ maxHeight?: number;
243
+ everyNthFrame?: number;
244
+ firstFrameTimeoutMs?: number;
245
+ }
246
+
239
247
  export interface IBrowserRuntimeOptions {
240
248
  runtimeDirectory: string;
241
249
  authorizeCapability(
@@ -271,6 +279,7 @@ export interface IBrowserRuntimeOptions {
271
279
  maxFrameBytes?: number;
272
280
  maxOutstandingFrames?: number;
273
281
  frameAcknowledgementTimeoutMs?: number;
282
+ screencast?: IBrowserRuntimeScreencastOptions;
274
283
  egress?: Omit<IBrowserEgressProxyOptions, 'projectId' | 'browserResourceId'>;
275
284
  artifacts?: Omit<IBrowserArtifactStoreOptions, 'rootDirectory'>;
276
285
  }