@browserbridge/bbx 1.7.8 → 1.9.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/PRIVACY.md +57 -12
- package/README.md +19 -8
- package/SECURITY.md +12 -0
- package/package.json +15 -6
- package/packages/agent-client/src/cli-args.js +59 -0
- package/packages/agent-client/src/cli-batch.js +121 -58
- package/packages/agent-client/src/cli-output.js +8 -1
- package/packages/agent-client/src/cli.js +272 -70
- package/packages/agent-client/src/client.js +296 -8
- package/packages/agent-client/src/command-registry.js +64 -55
- package/packages/agent-client/src/config.js +195 -0
- package/packages/agent-client/src/content-extract.js +198 -0
- package/packages/agent-client/src/npm-self-update.js +305 -0
- package/packages/agent-client/src/remotes.js +4 -2
- package/packages/agent-client/src/runtime.js +864 -39
- package/packages/agent-client/src/types.ts +169 -6
- package/packages/mcp-server/src/guidance.js +1 -1
- package/packages/mcp-server/src/handlers-capture.js +69 -6
- package/packages/mcp-server/src/handlers-dom.js +61 -4
- package/packages/mcp-server/src/handlers-navigation.js +2 -1
- package/packages/mcp-server/src/handlers-page.js +211 -54
- package/packages/mcp-server/src/handlers-utils.js +101 -10
- package/packages/mcp-server/src/handlers.js +14 -7
- package/packages/mcp-server/src/server.js +176 -11
- package/packages/native-host/src/artifact-store.js +353 -0
- package/packages/native-host/src/config.js +9 -1
- package/packages/native-host/src/daemon-logger.js +3 -1
- package/packages/native-host/src/daemon.js +701 -33
- package/packages/native-host/src/native-host.js +28 -3
- package/packages/protocol/src/capability-values.js +2 -0
- package/packages/protocol/src/defaults.js +31 -0
- package/packages/protocol/src/errors.js +102 -6
- package/packages/protocol/src/incidental-sanitizer.js +197 -0
- package/packages/protocol/src/index.js +2 -0
- package/packages/protocol/src/protocol.js +612 -6
- package/packages/protocol/src/recovery-telemetry.js +302 -0
- package/packages/protocol/src/registry.js +206 -38
- package/packages/protocol/src/summary.js +203 -30
- package/packages/protocol/src/types.ts +721 -2
- package/skills/browser-bridge/SKILL.md +54 -19
- package/skills/browser-bridge/references/interaction.md +55 -11
- package/skills/browser-bridge/references/patch-workflow.md +2 -0
- package/skills/browser-bridge/references/protocol.md +265 -86
- package/skills/browser-bridge/references/token-efficiency.md +29 -13
|
@@ -40,7 +40,12 @@ const METHOD_POLICIES = Object.freeze({
|
|
|
40
40
|
capability: CAPABILITIES.NETWORK_INTERCEPT,
|
|
41
41
|
debuggerBacked: true,
|
|
42
42
|
}),
|
|
43
|
+
sensitiveRead: Object.freeze({ capability: CAPABILITIES.SENSITIVE_READ }),
|
|
43
44
|
navigationControl: Object.freeze({ capability: CAPABILITIES.NAVIGATION_CONTROL }),
|
|
45
|
+
navigationControlDebugger: Object.freeze({
|
|
46
|
+
capability: CAPABILITIES.NAVIGATION_CONTROL,
|
|
47
|
+
debuggerBacked: true,
|
|
48
|
+
}),
|
|
44
49
|
domRead: Object.freeze({ capability: CAPABILITIES.DOM_READ }),
|
|
45
50
|
domReadDebugger: Object.freeze({
|
|
46
51
|
capability: CAPABILITIES.DOM_READ,
|
|
@@ -102,10 +107,19 @@ const BRIDGE_METHOD_DESCRIPTIONS = Object.freeze({
|
|
|
102
107
|
'page.get_state': 'Get URL, title, origin, and ready-state for the active page.',
|
|
103
108
|
'page.evaluate': 'Evaluate JavaScript in the page context.',
|
|
104
109
|
'page.get_console': 'Read buffered console output from the page.',
|
|
105
|
-
'page.
|
|
106
|
-
|
|
110
|
+
'page.handle_dialog':
|
|
111
|
+
'Inspect or explicitly act on the current JavaScript dialog. expectedDialogId is only a stale-decision check immediately before dispatch; Chrome cannot bind the CDP command atomically to that identifier.',
|
|
112
|
+
'page.wait_for_load_state':
|
|
113
|
+
'Wait for truthful tab-complete state and/or an event-aware URL condition.',
|
|
114
|
+
'page.get_storage': 'Read local or session storage key metadata without values.',
|
|
115
|
+
'sensitive.read': 'Deliberately read one exact local or session storage value.',
|
|
107
116
|
'page.get_text': 'Read bounded visible text from the page.',
|
|
108
|
-
'page.
|
|
117
|
+
'page.extract_content':
|
|
118
|
+
'Extract bounded semantic page content as text or Markdown without returning source HTML.',
|
|
119
|
+
'page.get_network':
|
|
120
|
+
'Read buffered fetch/XHR activity or explicitly manage bounded all-resource CDP capture.',
|
|
121
|
+
'network.export_har':
|
|
122
|
+
'Export bounded captured network evidence as a HAR 1.2 document, inline or as a daemon-owned artifact.',
|
|
109
123
|
'network.intercept.add': 'Add a request interception rule (CDP Fetch domain).',
|
|
110
124
|
'network.intercept.remove': 'Remove a request interception rule by ID.',
|
|
111
125
|
'network.intercept.list': 'List active interception rules.',
|
|
@@ -115,6 +129,10 @@ const BRIDGE_METHOD_DESCRIPTIONS = Object.freeze({
|
|
|
115
129
|
'navigation.go_back': 'Navigate backward in tab history.',
|
|
116
130
|
'navigation.go_forward': 'Navigate forward in tab history.',
|
|
117
131
|
'dom.query': 'Query a DOM subtree and return compact node summaries.',
|
|
132
|
+
'dom.baseline.create': 'Create a short-lived compact semantic DOM baseline for later comparison.',
|
|
133
|
+
'dom.baseline.compare': 'Compare the current DOM with a retained semantic baseline.',
|
|
134
|
+
'dom.baseline.describe': 'Describe a retained semantic DOM baseline and its scope.',
|
|
135
|
+
'dom.baseline.release': 'Release a retained semantic DOM baseline.',
|
|
118
136
|
'dom.describe': 'Describe one element by elementRef.',
|
|
119
137
|
'dom.get_text': 'Read bounded text for one element.',
|
|
120
138
|
'dom.get_attributes': 'Read selected attributes for one element.',
|
|
@@ -122,37 +140,45 @@ const BRIDGE_METHOD_DESCRIPTIONS = Object.freeze({
|
|
|
122
140
|
'dom.find_by_text': 'Find elements by visible text.',
|
|
123
141
|
'dom.find_by_role': 'Find elements by ARIA role and optional name.',
|
|
124
142
|
'dom.get_html': 'Read inner or outer HTML for one element.',
|
|
125
|
-
'dom.get_accessibility_tree':
|
|
143
|
+
'dom.get_accessibility_tree':
|
|
144
|
+
'Read a depth-limited accessibility tree with optional compact or interactive filtering.',
|
|
126
145
|
'layout.get_box_model': 'Read the box model for one element.',
|
|
127
146
|
'layout.hit_test': 'Resolve the topmost element at a viewport point.',
|
|
128
|
-
'styles.get_computed':
|
|
129
|
-
|
|
147
|
+
'styles.get_computed':
|
|
148
|
+
'Read requested computed styles; omission returns display, position, width, height, and color.',
|
|
149
|
+
'styles.get_matched_rules':
|
|
150
|
+
'Read element classes and inline style context (not stylesheet cascade data).',
|
|
130
151
|
'viewport.scroll': 'Scroll the viewport or a scrollable element.',
|
|
131
152
|
'viewport.resize': 'Resize or reset the tab viewport.',
|
|
132
|
-
'input.click': '
|
|
133
|
-
'input.focus': '
|
|
134
|
-
'input.type': '
|
|
135
|
-
'input.fill':
|
|
153
|
+
'input.click': 'Actionability-check and click an element through DOM or optional CDP input.',
|
|
154
|
+
'input.focus': 'Actionability-check and focus an element through DOM input.',
|
|
155
|
+
'input.type': 'Actionability-check and type through DOM or optional CDP text input.',
|
|
156
|
+
'input.fill':
|
|
157
|
+
'Fill an editable target using a DOM strategy or optional CDP text input; verify afterward.',
|
|
136
158
|
'input.press_key': 'Send a key press to the page or an element.',
|
|
137
159
|
'input.set_checked': 'Set checkbox or radio checked state.',
|
|
138
160
|
'input.select_option': 'Select options in a select element.',
|
|
139
|
-
'input.hover': '
|
|
140
|
-
'input.drag': '
|
|
161
|
+
'input.hover': 'Actionability-check and hover through DOM or optional CDP pointer input.',
|
|
162
|
+
'input.drag': 'Actionability-check and drag through DOM or optional CDP pointer input.',
|
|
141
163
|
'input.scroll_into_view': 'Scroll an element into the visible viewport.',
|
|
142
164
|
'screenshot.capture_region': 'Capture a screenshot of a viewport region.',
|
|
143
165
|
'screenshot.capture_element': 'Capture a screenshot of one element.',
|
|
144
166
|
'screenshot.capture_full_page': 'Capture a full-page screenshot beyond the viewport.',
|
|
167
|
+
'artifact.read': 'Read one bounded chunk from a daemon-owned artifact.',
|
|
168
|
+
'artifact.delete': 'Delete one daemon-owned artifact.',
|
|
145
169
|
'patch.apply_styles': 'Apply a reversible inline style patch.',
|
|
146
170
|
'patch.apply_dom': 'Apply a reversible DOM patch.',
|
|
147
171
|
'patch.list': 'List active reversible patches.',
|
|
148
172
|
'patch.rollback': 'Rollback one reversible patch.',
|
|
149
|
-
'patch.commit_session_baseline':
|
|
173
|
+
'patch.commit_session_baseline':
|
|
174
|
+
'Keep current document mutations and discard their rollback history.',
|
|
150
175
|
'cdp.get_document': 'Read the CDP DOM document tree.',
|
|
151
176
|
'cdp.get_dom_snapshot': 'Read a CDP DOM snapshot.',
|
|
152
177
|
'cdp.get_box_model': 'Read a CDP box model for a node.',
|
|
153
178
|
'cdp.get_computed_styles_for_node': 'Read CDP computed styles for a node.',
|
|
154
179
|
'cdp.dispatch_key_event': 'Dispatch a key press through Chrome DevTools Protocol input.',
|
|
155
|
-
'performance.get_metrics':
|
|
180
|
+
'performance.get_metrics':
|
|
181
|
+
'Read a raw Chrome/CDP counter point sample; names and units vary, and BBX measures no navigation window, LCP, CLS, or INP.',
|
|
156
182
|
'log.tail': 'Tail recent bridge log entries.',
|
|
157
183
|
'health.ping': 'Check daemon, extension, and access-routing health.',
|
|
158
184
|
'daemon.metrics': 'Daemon health and performance metrics.',
|
|
@@ -195,7 +221,7 @@ function createRegistryEntry(
|
|
|
195
221
|
/** @type {Readonly<Record<import('./types.js').BridgeMethod, BridgeMethodRegistryEntry>>} */
|
|
196
222
|
export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
197
223
|
// system - trivial
|
|
198
|
-
'access.request': createRegistryEntry('access.request', 'system', false, [], 'trivial'),
|
|
224
|
+
'access.request': createRegistryEntry('access.request', 'system', false, ['intent'], 'trivial'),
|
|
199
225
|
'skill.get_runtime_context': createRegistryEntry(
|
|
200
226
|
'skill.get_runtime_context',
|
|
201
227
|
'system',
|
|
@@ -265,11 +291,19 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
265
291
|
'low',
|
|
266
292
|
METHOD_POLICIES.pageRead
|
|
267
293
|
),
|
|
294
|
+
'page.handle_dialog': createRegistryEntry(
|
|
295
|
+
'page.handle_dialog',
|
|
296
|
+
'page',
|
|
297
|
+
true,
|
|
298
|
+
['action', 'promptText', 'expectedDialogId'],
|
|
299
|
+
'low',
|
|
300
|
+
METHOD_POLICIES.navigationControlDebugger
|
|
301
|
+
),
|
|
268
302
|
'page.wait_for_load_state': createRegistryEntry(
|
|
269
303
|
'page.wait_for_load_state',
|
|
270
304
|
'wait',
|
|
271
305
|
true,
|
|
272
|
-
['timeoutMs'],
|
|
306
|
+
['waitForLoad', 'timeoutMs', 'url', 'urlMatch'],
|
|
273
307
|
'low',
|
|
274
308
|
METHOD_POLICIES.pageRead
|
|
275
309
|
),
|
|
@@ -281,6 +315,14 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
281
315
|
'low',
|
|
282
316
|
METHOD_POLICIES.pageRead
|
|
283
317
|
),
|
|
318
|
+
'sensitive.read': createRegistryEntry(
|
|
319
|
+
'sensitive.read',
|
|
320
|
+
'sensitive',
|
|
321
|
+
true,
|
|
322
|
+
['source', 'key'],
|
|
323
|
+
'low',
|
|
324
|
+
METHOD_POLICIES.sensitiveRead
|
|
325
|
+
),
|
|
284
326
|
'page.get_text': createRegistryEntry(
|
|
285
327
|
'page.get_text',
|
|
286
328
|
'page',
|
|
@@ -289,14 +331,30 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
289
331
|
'low',
|
|
290
332
|
METHOD_POLICIES.pageRead
|
|
291
333
|
),
|
|
334
|
+
'page.extract_content': createRegistryEntry(
|
|
335
|
+
'page.extract_content',
|
|
336
|
+
'page',
|
|
337
|
+
true,
|
|
338
|
+
['format', 'selector', 'includeMetadata', 'consistency', 'textBudget', 'settleTimeoutMs'],
|
|
339
|
+
'moderate',
|
|
340
|
+
METHOD_POLICIES.pageRead
|
|
341
|
+
),
|
|
292
342
|
'page.get_network': createRegistryEntry(
|
|
293
343
|
'page.get_network',
|
|
294
344
|
'page',
|
|
295
345
|
true,
|
|
296
|
-
['clear', 'limit', 'urlPattern'],
|
|
346
|
+
['clear', 'limit', 'urlPattern', 'source', 'capture'],
|
|
297
347
|
'low',
|
|
298
348
|
METHOD_POLICIES.networkRead
|
|
299
349
|
),
|
|
350
|
+
'network.export_har': createRegistryEntry(
|
|
351
|
+
'network.export_har',
|
|
352
|
+
'page',
|
|
353
|
+
true,
|
|
354
|
+
['limit', 'urlPattern', 'delivery'],
|
|
355
|
+
'moderate',
|
|
356
|
+
METHOD_POLICIES.networkRead
|
|
357
|
+
),
|
|
300
358
|
// network intercept - moderate (holds debugger session)
|
|
301
359
|
'network.intercept.add': createRegistryEntry(
|
|
302
360
|
'network.intercept.add',
|
|
@@ -380,11 +438,43 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
380
438
|
'low',
|
|
381
439
|
METHOD_POLICIES.domRead
|
|
382
440
|
),
|
|
441
|
+
'dom.baseline.create': createRegistryEntry(
|
|
442
|
+
'dom.baseline.create',
|
|
443
|
+
'inspect',
|
|
444
|
+
true,
|
|
445
|
+
['selector', 'maxNodes', 'maxDepth', 'textBudget', 'attributeAllowlist'],
|
|
446
|
+
'low',
|
|
447
|
+
METHOD_POLICIES.domRead
|
|
448
|
+
),
|
|
449
|
+
'dom.baseline.compare': createRegistryEntry(
|
|
450
|
+
'dom.baseline.compare',
|
|
451
|
+
'inspect',
|
|
452
|
+
true,
|
|
453
|
+
['baselineId', 'maxChanges'],
|
|
454
|
+
'low',
|
|
455
|
+
METHOD_POLICIES.domRead
|
|
456
|
+
),
|
|
457
|
+
'dom.baseline.describe': createRegistryEntry(
|
|
458
|
+
'dom.baseline.describe',
|
|
459
|
+
'inspect',
|
|
460
|
+
true,
|
|
461
|
+
['baselineId'],
|
|
462
|
+
'low',
|
|
463
|
+
METHOD_POLICIES.domRead
|
|
464
|
+
),
|
|
465
|
+
'dom.baseline.release': createRegistryEntry(
|
|
466
|
+
'dom.baseline.release',
|
|
467
|
+
'inspect',
|
|
468
|
+
true,
|
|
469
|
+
['baselineId'],
|
|
470
|
+
'low',
|
|
471
|
+
METHOD_POLICIES.domRead
|
|
472
|
+
),
|
|
383
473
|
'dom.describe': createRegistryEntry(
|
|
384
474
|
'dom.describe',
|
|
385
475
|
'inspect',
|
|
386
476
|
true,
|
|
387
|
-
['elementRef'],
|
|
477
|
+
['elementRef', 'target'],
|
|
388
478
|
'low',
|
|
389
479
|
METHOD_POLICIES.domRead
|
|
390
480
|
),
|
|
@@ -392,7 +482,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
392
482
|
'dom.get_text',
|
|
393
483
|
'inspect',
|
|
394
484
|
true,
|
|
395
|
-
['elementRef', 'textBudget'],
|
|
485
|
+
['elementRef', 'target', 'textBudget'],
|
|
396
486
|
'low',
|
|
397
487
|
METHOD_POLICIES.domRead
|
|
398
488
|
),
|
|
@@ -400,7 +490,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
400
490
|
'dom.get_attributes',
|
|
401
491
|
'inspect',
|
|
402
492
|
true,
|
|
403
|
-
['elementRef', 'attributes'],
|
|
493
|
+
['elementRef', 'target', 'attributes'],
|
|
404
494
|
'low',
|
|
405
495
|
METHOD_POLICIES.domRead
|
|
406
496
|
),
|
|
@@ -432,7 +522,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
432
522
|
'dom.get_html',
|
|
433
523
|
'inspect',
|
|
434
524
|
true,
|
|
435
|
-
['elementRef', 'outer', 'maxLength'],
|
|
525
|
+
['elementRef', 'target', 'outer', 'maxLength'],
|
|
436
526
|
'low',
|
|
437
527
|
METHOD_POLICIES.domRead
|
|
438
528
|
),
|
|
@@ -440,7 +530,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
440
530
|
'dom.get_accessibility_tree',
|
|
441
531
|
'inspect',
|
|
442
532
|
true,
|
|
443
|
-
['maxNodes', 'maxDepth'],
|
|
533
|
+
['selector', 'maxNodes', 'maxDepth', 'compact', 'interactiveOnly'],
|
|
444
534
|
'moderate',
|
|
445
535
|
METHOD_POLICIES.domReadDebugger
|
|
446
536
|
),
|
|
@@ -449,7 +539,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
449
539
|
'layout.get_box_model',
|
|
450
540
|
'inspect',
|
|
451
541
|
true,
|
|
452
|
-
['elementRef'],
|
|
542
|
+
['elementRef', 'target'],
|
|
453
543
|
'low',
|
|
454
544
|
METHOD_POLICIES.layoutRead
|
|
455
545
|
),
|
|
@@ -466,7 +556,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
466
556
|
'styles.get_computed',
|
|
467
557
|
'inspect',
|
|
468
558
|
true,
|
|
469
|
-
['elementRef', 'properties'],
|
|
559
|
+
['elementRef', 'target', 'properties'],
|
|
470
560
|
'low',
|
|
471
561
|
METHOD_POLICIES.stylesRead
|
|
472
562
|
),
|
|
@@ -474,7 +564,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
474
564
|
'styles.get_matched_rules',
|
|
475
565
|
'inspect',
|
|
476
566
|
true,
|
|
477
|
-
['elementRef'],
|
|
567
|
+
['elementRef', 'target'],
|
|
478
568
|
'moderate',
|
|
479
569
|
METHOD_POLICIES.stylesRead
|
|
480
570
|
),
|
|
@@ -500,7 +590,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
500
590
|
'input.click',
|
|
501
591
|
'interact',
|
|
502
592
|
true,
|
|
503
|
-
['target', 'button', 'clickCount', 'modifiers'],
|
|
593
|
+
['target', 'button', 'clickCount', 'modifiers', 'executionMode', 'recoverStale'],
|
|
504
594
|
'low',
|
|
505
595
|
METHOD_POLICIES.automationInput
|
|
506
596
|
),
|
|
@@ -508,7 +598,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
508
598
|
'input.focus',
|
|
509
599
|
'interact',
|
|
510
600
|
true,
|
|
511
|
-
['target'],
|
|
601
|
+
['target', 'executionMode', 'recoverStale'],
|
|
512
602
|
'low',
|
|
513
603
|
METHOD_POLICIES.automationInput
|
|
514
604
|
),
|
|
@@ -516,7 +606,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
516
606
|
'input.type',
|
|
517
607
|
'interact',
|
|
518
608
|
true,
|
|
519
|
-
['target', 'text', 'clear', 'submit', 'modifiers'],
|
|
609
|
+
['target', 'text', 'clear', 'submit', 'modifiers', 'executionMode', 'recoverStale'],
|
|
520
610
|
'low',
|
|
521
611
|
METHOD_POLICIES.automationInput
|
|
522
612
|
),
|
|
@@ -524,7 +614,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
524
614
|
'input.fill',
|
|
525
615
|
'interact',
|
|
526
616
|
true,
|
|
527
|
-
['target', 'value', 'mode'],
|
|
617
|
+
['target', 'value', 'mode', 'executionMode', 'recoverStale'],
|
|
528
618
|
'low',
|
|
529
619
|
METHOD_POLICIES.automationInput
|
|
530
620
|
),
|
|
@@ -532,7 +622,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
532
622
|
'input.press_key',
|
|
533
623
|
'interact',
|
|
534
624
|
true,
|
|
535
|
-
['target', 'key', 'modifiers'],
|
|
625
|
+
['target', 'key', 'modifiers', 'executionMode', 'recoverStale'],
|
|
536
626
|
'low',
|
|
537
627
|
METHOD_POLICIES.automationInput
|
|
538
628
|
),
|
|
@@ -540,7 +630,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
540
630
|
'input.set_checked',
|
|
541
631
|
'interact',
|
|
542
632
|
true,
|
|
543
|
-
['target', 'checked'],
|
|
633
|
+
['target', 'checked', 'executionMode', 'recoverStale'],
|
|
544
634
|
'low',
|
|
545
635
|
METHOD_POLICIES.automationInput
|
|
546
636
|
),
|
|
@@ -548,7 +638,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
548
638
|
'input.select_option',
|
|
549
639
|
'interact',
|
|
550
640
|
true,
|
|
551
|
-
['target', 'values', 'labels', 'indexes'],
|
|
641
|
+
['target', 'values', 'labels', 'indexes', 'executionMode', 'recoverStale'],
|
|
552
642
|
'low',
|
|
553
643
|
METHOD_POLICIES.automationInput
|
|
554
644
|
),
|
|
@@ -556,7 +646,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
556
646
|
'input.hover',
|
|
557
647
|
'interact',
|
|
558
648
|
true,
|
|
559
|
-
['target', 'duration', 'modifiers'],
|
|
649
|
+
['target', 'duration', 'modifiers', 'executionMode', 'recoverStale'],
|
|
560
650
|
'low',
|
|
561
651
|
METHOD_POLICIES.automationInput
|
|
562
652
|
),
|
|
@@ -564,7 +654,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
564
654
|
'input.drag',
|
|
565
655
|
'interact',
|
|
566
656
|
true,
|
|
567
|
-
['source', 'destination', 'offsetX', 'offsetY'],
|
|
657
|
+
['source', 'destination', 'offsetX', 'offsetY', 'executionMode', 'recoverStale'],
|
|
568
658
|
'moderate',
|
|
569
659
|
METHOD_POLICIES.automationInput
|
|
570
660
|
),
|
|
@@ -581,7 +671,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
581
671
|
'screenshot.capture_region',
|
|
582
672
|
'capture',
|
|
583
673
|
true,
|
|
584
|
-
['x', 'y', 'width', 'height'],
|
|
674
|
+
['x', 'y', 'width', 'height', 'format', 'quality', 'delivery', 'scale'],
|
|
585
675
|
'high',
|
|
586
676
|
METHOD_POLICIES.screenshotPartialDebugger
|
|
587
677
|
),
|
|
@@ -589,7 +679,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
589
679
|
'screenshot.capture_element',
|
|
590
680
|
'capture',
|
|
591
681
|
true,
|
|
592
|
-
['elementRef'],
|
|
682
|
+
['elementRef', 'format', 'quality', 'delivery', 'scale'],
|
|
593
683
|
'high',
|
|
594
684
|
METHOD_POLICIES.screenshotPartialDebugger
|
|
595
685
|
),
|
|
@@ -597,10 +687,24 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
597
687
|
'screenshot.capture_full_page',
|
|
598
688
|
'capture',
|
|
599
689
|
true,
|
|
600
|
-
[],
|
|
690
|
+
['format', 'quality', 'delivery', 'scale'],
|
|
601
691
|
'high',
|
|
602
692
|
METHOD_POLICIES.screenshotPartialDebugger
|
|
603
693
|
),
|
|
694
|
+
'artifact.read': createRegistryEntry(
|
|
695
|
+
'artifact.read',
|
|
696
|
+
'artifact',
|
|
697
|
+
false,
|
|
698
|
+
['artifactId', 'offset', 'maxBytes'],
|
|
699
|
+
'low'
|
|
700
|
+
),
|
|
701
|
+
'artifact.delete': createRegistryEntry(
|
|
702
|
+
'artifact.delete',
|
|
703
|
+
'artifact',
|
|
704
|
+
false,
|
|
705
|
+
['artifactId'],
|
|
706
|
+
'low'
|
|
707
|
+
),
|
|
604
708
|
// patch - moderate (side effects)
|
|
605
709
|
'patch.apply_styles': createRegistryEntry(
|
|
606
710
|
'patch.apply_styles',
|
|
@@ -655,7 +759,7 @@ export const BRIDGE_METHOD_REGISTRY = Object.freeze({
|
|
|
655
759
|
'cdp.get_dom_snapshot',
|
|
656
760
|
'cdp',
|
|
657
761
|
true,
|
|
658
|
-
[],
|
|
762
|
+
['computedStyles'],
|
|
659
763
|
'high',
|
|
660
764
|
METHOD_POLICIES.cdpDomSnapshotDebugger
|
|
661
765
|
),
|
|
@@ -702,6 +806,70 @@ export const BRIDGE_METHODS = Object.freeze(
|
|
|
702
806
|
/** @type {ReadonlySet<import('./types.js').BridgeMethod>} */
|
|
703
807
|
export const METHOD_SET = new Set(BRIDGE_METHODS);
|
|
704
808
|
|
|
809
|
+
/** Methods whose read-only forms may run concurrently without side effects. */
|
|
810
|
+
const BATCH_SAFE_METHODS = new Set([
|
|
811
|
+
'health.ping',
|
|
812
|
+
'daemon.metrics',
|
|
813
|
+
'tabs.list',
|
|
814
|
+
'skill.get_runtime_context',
|
|
815
|
+
'setup.get_status',
|
|
816
|
+
'log.tail',
|
|
817
|
+
'page.get_state',
|
|
818
|
+
'page.get_console',
|
|
819
|
+
'page.wait_for_load_state',
|
|
820
|
+
'page.get_storage',
|
|
821
|
+
'page.get_text',
|
|
822
|
+
'page.extract_content',
|
|
823
|
+
'page.get_network',
|
|
824
|
+
'dom.query',
|
|
825
|
+
'dom.baseline.compare',
|
|
826
|
+
'dom.baseline.describe',
|
|
827
|
+
'dom.describe',
|
|
828
|
+
'dom.get_text',
|
|
829
|
+
'dom.get_attributes',
|
|
830
|
+
'dom.wait_for',
|
|
831
|
+
'dom.find_by_text',
|
|
832
|
+
'dom.find_by_role',
|
|
833
|
+
'dom.get_html',
|
|
834
|
+
'dom.get_accessibility_tree',
|
|
835
|
+
'layout.get_box_model',
|
|
836
|
+
'layout.hit_test',
|
|
837
|
+
'styles.get_computed',
|
|
838
|
+
'styles.get_matched_rules',
|
|
839
|
+
'network.intercept.list',
|
|
840
|
+
'patch.list',
|
|
841
|
+
'performance.get_metrics',
|
|
842
|
+
]);
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Classify a normalized or raw bridge call for parallel read-only execution.
|
|
846
|
+
* Parameter checks deliberately reject malformed truthy mutation flags before
|
|
847
|
+
* protocol normalization can coerce them.
|
|
848
|
+
*
|
|
849
|
+
* @param {import('./types.js').BridgeMethod} method
|
|
850
|
+
* @param {Record<string, unknown>} [params]
|
|
851
|
+
* @returns {boolean}
|
|
852
|
+
*/
|
|
853
|
+
export function isBatchSafeBridgeCall(method, params = {}) {
|
|
854
|
+
if (!BATCH_SAFE_METHODS.has(method)) return false;
|
|
855
|
+
if (
|
|
856
|
+
(method === 'page.get_console' || method === 'page.get_network') &&
|
|
857
|
+
params.clear !== undefined &&
|
|
858
|
+
params.clear !== false
|
|
859
|
+
) {
|
|
860
|
+
return false;
|
|
861
|
+
}
|
|
862
|
+
if (
|
|
863
|
+
method === 'page.get_network' &&
|
|
864
|
+
params.source === 'cdp' &&
|
|
865
|
+
params.capture !== undefined &&
|
|
866
|
+
params.capture !== 'read'
|
|
867
|
+
) {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
|
|
705
873
|
/**
|
|
706
874
|
* @returns {Record<string, import('./types.js').BridgeMethod[]>}
|
|
707
875
|
*/
|