@browserbridge/bbx 1.2.0 → 1.4.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 +8 -5
- package/package.json +2 -2
- package/packages/agent-client/src/cli.js +56 -31
- package/packages/agent-client/src/client.js +81 -65
- package/packages/agent-client/src/command-registry.js +4 -15
- package/packages/agent-client/src/detect.js +3 -3
- package/packages/agent-client/src/install.js +3 -7
- package/packages/agent-client/src/mcp-config.js +20 -5
- package/packages/agent-client/src/runtime.js +7 -41
- package/packages/agent-client/src/setup-status.js +3 -13
- package/packages/agent-client/src/types.ts +139 -0
- package/packages/mcp-server/src/guidance.js +241 -0
- package/packages/mcp-server/src/handlers-capture.js +91 -16
- package/packages/mcp-server/src/handlers-dom.js +59 -4
- package/packages/mcp-server/src/handlers-navigation.js +22 -2
- package/packages/mcp-server/src/handlers-page.js +6 -11
- package/packages/mcp-server/src/handlers-utils.js +69 -1
- package/packages/mcp-server/src/server.js +111 -28
- package/packages/native-host/bin/postinstall.js +42 -21
- package/packages/native-host/src/auth-token.js +92 -0
- package/packages/native-host/src/daemon-process.js +1 -2
- package/packages/native-host/src/daemon.js +199 -30
- package/packages/native-host/src/framing.js +13 -0
- package/packages/native-host/src/native-host.js +25 -7
- package/packages/protocol/src/defaults.js +3 -0
- package/packages/protocol/src/json-lines.js +29 -1
- package/packages/protocol/src/protocol.js +43 -0
- package/packages/protocol/src/registry.js +3 -9
- package/packages/protocol/src/types.ts +574 -0
- package/skills/browser-bridge/SKILL.md +21 -5
- package/skills/browser-bridge/agents/openai.yaml +1 -1
- package/skills/browser-bridge/references/interaction.md +6 -6
- package/skills/browser-bridge/references/protocol.md +57 -54
- package/skills/browser-bridge/references/ui-workflows.md +1 -1
- package/packages/protocol/src/types.js +0 -626
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
export type BridgeRequestSource = 'cli' | 'mcp';
|
|
2
|
+
|
|
3
|
+
export type Capability =
|
|
4
|
+
| 'page.read'
|
|
5
|
+
| 'page.evaluate'
|
|
6
|
+
| 'dom.read'
|
|
7
|
+
| 'styles.read'
|
|
8
|
+
| 'layout.read'
|
|
9
|
+
| 'viewport.control'
|
|
10
|
+
| 'navigation.control'
|
|
11
|
+
| 'screenshot.partial'
|
|
12
|
+
| 'patch.dom'
|
|
13
|
+
| 'patch.styles'
|
|
14
|
+
| 'cdp.dom_snapshot'
|
|
15
|
+
| 'cdp.box_model'
|
|
16
|
+
| 'cdp.styles'
|
|
17
|
+
| 'cdp.input'
|
|
18
|
+
| 'automation.input'
|
|
19
|
+
| 'tabs.manage'
|
|
20
|
+
| 'performance.read'
|
|
21
|
+
| 'network.read';
|
|
22
|
+
|
|
23
|
+
export type ErrorCode =
|
|
24
|
+
| 'ACCESS_DENIED'
|
|
25
|
+
| 'TAB_MISMATCH'
|
|
26
|
+
| 'ELEMENT_STALE'
|
|
27
|
+
| 'RESULT_TRUNCATED'
|
|
28
|
+
| 'RATE_LIMITED'
|
|
29
|
+
| 'INTERNAL_ERROR'
|
|
30
|
+
| 'INVALID_REQUEST'
|
|
31
|
+
| 'NATIVE_HOST_UNAVAILABLE'
|
|
32
|
+
| 'EXTENSION_DISCONNECTED'
|
|
33
|
+
| 'TIMEOUT';
|
|
34
|
+
|
|
35
|
+
export type BridgeMethod =
|
|
36
|
+
| 'access.request'
|
|
37
|
+
| 'tabs.list'
|
|
38
|
+
| 'tabs.create'
|
|
39
|
+
| 'tabs.close'
|
|
40
|
+
| 'skill.get_runtime_context'
|
|
41
|
+
| 'setup.get_status'
|
|
42
|
+
| 'setup.install'
|
|
43
|
+
| 'page.get_state'
|
|
44
|
+
| 'page.evaluate'
|
|
45
|
+
| 'page.get_console'
|
|
46
|
+
| 'page.wait_for_load_state'
|
|
47
|
+
| 'page.get_storage'
|
|
48
|
+
| 'page.get_text'
|
|
49
|
+
| 'page.get_network'
|
|
50
|
+
| 'navigation.navigate'
|
|
51
|
+
| 'navigation.reload'
|
|
52
|
+
| 'navigation.go_back'
|
|
53
|
+
| 'navigation.go_forward'
|
|
54
|
+
| 'dom.query'
|
|
55
|
+
| 'dom.describe'
|
|
56
|
+
| 'dom.get_text'
|
|
57
|
+
| 'dom.get_attributes'
|
|
58
|
+
| 'dom.wait_for'
|
|
59
|
+
| 'dom.find_by_text'
|
|
60
|
+
| 'dom.find_by_role'
|
|
61
|
+
| 'dom.get_html'
|
|
62
|
+
| 'dom.get_accessibility_tree'
|
|
63
|
+
| 'layout.get_box_model'
|
|
64
|
+
| 'layout.hit_test'
|
|
65
|
+
| 'styles.get_computed'
|
|
66
|
+
| 'styles.get_matched_rules'
|
|
67
|
+
| 'viewport.scroll'
|
|
68
|
+
| 'viewport.resize'
|
|
69
|
+
| 'input.click'
|
|
70
|
+
| 'input.focus'
|
|
71
|
+
| 'input.type'
|
|
72
|
+
| 'input.press_key'
|
|
73
|
+
| 'input.set_checked'
|
|
74
|
+
| 'input.select_option'
|
|
75
|
+
| 'input.hover'
|
|
76
|
+
| 'input.drag'
|
|
77
|
+
| 'input.scroll_into_view'
|
|
78
|
+
| 'screenshot.capture_region'
|
|
79
|
+
| 'screenshot.capture_element'
|
|
80
|
+
| 'screenshot.capture_full_page'
|
|
81
|
+
| 'patch.apply_styles'
|
|
82
|
+
| 'patch.apply_dom'
|
|
83
|
+
| 'patch.list'
|
|
84
|
+
| 'patch.rollback'
|
|
85
|
+
| 'patch.commit_session_baseline'
|
|
86
|
+
| 'cdp.get_document'
|
|
87
|
+
| 'cdp.get_dom_snapshot'
|
|
88
|
+
| 'cdp.get_box_model'
|
|
89
|
+
| 'cdp.get_computed_styles_for_node'
|
|
90
|
+
| 'cdp.dispatch_key_event'
|
|
91
|
+
| 'performance.get_metrics'
|
|
92
|
+
| 'log.tail'
|
|
93
|
+
| 'health.ping'
|
|
94
|
+
| 'daemon.metrics';
|
|
95
|
+
|
|
96
|
+
export type CostClass = 'cheap' | 'moderate' | 'heavy' | 'extreme';
|
|
97
|
+
|
|
98
|
+
export interface BridgeMeta {
|
|
99
|
+
protocol_version?: string;
|
|
100
|
+
token_budget?: number | null;
|
|
101
|
+
transport_bytes?: number;
|
|
102
|
+
transport_approx_tokens?: number;
|
|
103
|
+
transport_cost_class?: CostClass;
|
|
104
|
+
text_bytes?: number;
|
|
105
|
+
text_approx_tokens?: number;
|
|
106
|
+
text_cost_class?: CostClass;
|
|
107
|
+
image_approx_tokens?: number;
|
|
108
|
+
image_bytes?: number;
|
|
109
|
+
source?: BridgeRequestSource;
|
|
110
|
+
response_bytes?: number;
|
|
111
|
+
approx_tokens?: number;
|
|
112
|
+
cost_class?: CostClass;
|
|
113
|
+
debugger_backed?: boolean;
|
|
114
|
+
budget_applied?: boolean;
|
|
115
|
+
budget_truncated?: boolean;
|
|
116
|
+
continuation_hint?: string | null;
|
|
117
|
+
[key: string]: unknown;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface BridgeParams {
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface BridgeRequest {
|
|
125
|
+
id: string;
|
|
126
|
+
method: BridgeMethod;
|
|
127
|
+
tab_id: number | null;
|
|
128
|
+
params: BridgeParams;
|
|
129
|
+
meta: Required<Pick<BridgeMeta, 'protocol_version' | 'token_budget'>> & Record<string, unknown>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface BridgeRecovery {
|
|
133
|
+
hint: string;
|
|
134
|
+
retry?: boolean;
|
|
135
|
+
retryAfterMs?: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface BridgeFailure {
|
|
139
|
+
code: ErrorCode;
|
|
140
|
+
message: string;
|
|
141
|
+
details: unknown;
|
|
142
|
+
recovery?: BridgeRecovery;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface BridgeSuccessResponse {
|
|
146
|
+
id: string;
|
|
147
|
+
ok: true;
|
|
148
|
+
result: unknown;
|
|
149
|
+
error: null;
|
|
150
|
+
meta: { protocol_version: string } & Record<string, unknown>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface BridgeFailureResponse {
|
|
154
|
+
id: string;
|
|
155
|
+
ok: false;
|
|
156
|
+
result: null;
|
|
157
|
+
error: BridgeFailure;
|
|
158
|
+
meta: { protocol_version: string } & Record<string, unknown>;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export type BridgeResponse = BridgeSuccessResponse | BridgeFailureResponse;
|
|
162
|
+
|
|
163
|
+
export interface BudgetOptions {
|
|
164
|
+
maxNodes?: number;
|
|
165
|
+
maxDepth?: number;
|
|
166
|
+
textBudget?: number;
|
|
167
|
+
includeBbox?: boolean;
|
|
168
|
+
attributeAllowlist?: string[];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface Budget {
|
|
172
|
+
maxNodes: number;
|
|
173
|
+
maxDepth: number;
|
|
174
|
+
textBudget: number;
|
|
175
|
+
includeBbox: boolean;
|
|
176
|
+
attributeAllowlist: string[];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface TruncateResult {
|
|
180
|
+
value: string;
|
|
181
|
+
truncated: boolean;
|
|
182
|
+
omitted: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface DomQueryParams extends BudgetOptions {
|
|
186
|
+
selector?: string;
|
|
187
|
+
withinRef?: string | null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface NormalizedDomQuery extends BridgeParams {
|
|
191
|
+
selector: string;
|
|
192
|
+
withinRef: string | null;
|
|
193
|
+
budget: Budget;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface StyleQueryParams {
|
|
197
|
+
elementRef?: string;
|
|
198
|
+
target?: InputTarget;
|
|
199
|
+
properties?: string[];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export interface NormalizedStyleQuery extends BridgeParams {
|
|
203
|
+
elementRef: string;
|
|
204
|
+
target: InputTarget;
|
|
205
|
+
properties: string[];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface InputTarget {
|
|
209
|
+
elementRef?: string;
|
|
210
|
+
selector?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface InputActionParams {
|
|
214
|
+
target?: InputTarget;
|
|
215
|
+
button?: 'left' | 'middle' | 'right';
|
|
216
|
+
clickCount?: number;
|
|
217
|
+
text?: string;
|
|
218
|
+
clear?: boolean;
|
|
219
|
+
submit?: boolean;
|
|
220
|
+
key?: string;
|
|
221
|
+
modifiers?: string[];
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface NormalizedInputAction extends BridgeParams {
|
|
225
|
+
target: InputTarget;
|
|
226
|
+
button: 'left' | 'middle' | 'right';
|
|
227
|
+
clickCount: number;
|
|
228
|
+
text: string;
|
|
229
|
+
clear: boolean;
|
|
230
|
+
submit: boolean;
|
|
231
|
+
key: string;
|
|
232
|
+
modifiers: string[];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export interface CdpDispatchKeyEventParams {
|
|
236
|
+
key?: string;
|
|
237
|
+
code?: string;
|
|
238
|
+
modifiers?: string[] | number;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface CdpNodeIdParams {
|
|
242
|
+
nodeId?: number;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export interface NormalizedCdpDispatchKeyEventParams extends BridgeParams {
|
|
246
|
+
key: string;
|
|
247
|
+
code: string;
|
|
248
|
+
modifiers: string[] | number;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export interface NormalizedCdpNodeIdParams extends BridgeParams {
|
|
252
|
+
nodeId: number;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface CheckedActionParams {
|
|
256
|
+
target?: InputTarget;
|
|
257
|
+
checked?: boolean;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export interface NormalizedCheckedAction extends BridgeParams {
|
|
261
|
+
target: InputTarget;
|
|
262
|
+
checked: boolean;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface SelectActionParams {
|
|
266
|
+
target?: InputTarget;
|
|
267
|
+
values?: string[];
|
|
268
|
+
labels?: string[];
|
|
269
|
+
indexes?: number[];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export interface NormalizedSelectAction extends BridgeParams {
|
|
273
|
+
target: InputTarget;
|
|
274
|
+
values: string[];
|
|
275
|
+
labels: string[];
|
|
276
|
+
indexes: number[];
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface ViewportActionParams {
|
|
280
|
+
target?: InputTarget;
|
|
281
|
+
top?: number;
|
|
282
|
+
left?: number;
|
|
283
|
+
behavior?: 'auto' | 'smooth';
|
|
284
|
+
relative?: boolean;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export interface NormalizedViewportAction extends BridgeParams {
|
|
288
|
+
target: InputTarget;
|
|
289
|
+
top: number;
|
|
290
|
+
left: number;
|
|
291
|
+
behavior: 'auto' | 'smooth';
|
|
292
|
+
relative: boolean;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export interface NavigationActionParams {
|
|
296
|
+
url?: string;
|
|
297
|
+
waitForLoad?: boolean;
|
|
298
|
+
timeoutMs?: number;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface NormalizedNavigationAction extends BridgeParams {
|
|
302
|
+
url: string;
|
|
303
|
+
waitForLoad: boolean;
|
|
304
|
+
timeoutMs: number;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface PatchOperationParams {
|
|
308
|
+
patchId?: string | null;
|
|
309
|
+
target?: Record<string, unknown>;
|
|
310
|
+
operation?: string | null;
|
|
311
|
+
name?: string | null;
|
|
312
|
+
declarations?: Record<string, string>;
|
|
313
|
+
value?: unknown;
|
|
314
|
+
important?: boolean;
|
|
315
|
+
verify?: boolean;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export interface NormalizedPatchOperation extends BridgeParams {
|
|
319
|
+
patchId: string | null;
|
|
320
|
+
target: Record<string, unknown>;
|
|
321
|
+
operation: string | null;
|
|
322
|
+
name: string | null;
|
|
323
|
+
declarations: Record<string, string>;
|
|
324
|
+
value: unknown;
|
|
325
|
+
important: boolean;
|
|
326
|
+
verify: boolean;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export interface McpClientStatus {
|
|
330
|
+
key: string;
|
|
331
|
+
label: string;
|
|
332
|
+
detected: boolean;
|
|
333
|
+
configPath: string;
|
|
334
|
+
configExists: boolean;
|
|
335
|
+
configured: boolean;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export interface SkillInstallationStatus {
|
|
339
|
+
name: string;
|
|
340
|
+
path: string;
|
|
341
|
+
exists: boolean;
|
|
342
|
+
managed: boolean;
|
|
343
|
+
version: string | null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export interface SkillTargetStatus {
|
|
347
|
+
key: string;
|
|
348
|
+
label: string;
|
|
349
|
+
detected: boolean;
|
|
350
|
+
basePath: string;
|
|
351
|
+
installed: boolean;
|
|
352
|
+
managed: boolean;
|
|
353
|
+
installedVersion: string | null;
|
|
354
|
+
currentVersion: string | null;
|
|
355
|
+
updateAvailable: boolean;
|
|
356
|
+
skills: SkillInstallationStatus[];
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export interface SetupStatus {
|
|
360
|
+
scope: 'global' | 'local';
|
|
361
|
+
mcpClients: McpClientStatus[];
|
|
362
|
+
skillTargets: SkillTargetStatus[];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export interface SetupInstallParams {
|
|
366
|
+
action?: 'install' | 'uninstall';
|
|
367
|
+
kind?: 'mcp' | 'skill';
|
|
368
|
+
target?: string;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export interface SetupInstallResult {
|
|
372
|
+
action: 'install' | 'uninstall';
|
|
373
|
+
kind: 'mcp' | 'skill';
|
|
374
|
+
target: string;
|
|
375
|
+
paths: string[];
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export interface EvaluateParams {
|
|
379
|
+
expression?: string;
|
|
380
|
+
awaitPromise?: boolean;
|
|
381
|
+
timeoutMs?: number;
|
|
382
|
+
returnByValue?: boolean;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface NormalizedEvaluateParams extends BridgeParams {
|
|
386
|
+
expression: string;
|
|
387
|
+
awaitPromise: boolean;
|
|
388
|
+
timeoutMs: number;
|
|
389
|
+
returnByValue: boolean;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
export interface ConsoleParams {
|
|
393
|
+
level?: string;
|
|
394
|
+
clear?: boolean;
|
|
395
|
+
limit?: number;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export interface NormalizedConsoleParams extends BridgeParams {
|
|
399
|
+
level: string;
|
|
400
|
+
clear: boolean;
|
|
401
|
+
limit: number;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export interface WaitForParams {
|
|
405
|
+
selector?: string;
|
|
406
|
+
text?: string;
|
|
407
|
+
state?: 'attached' | 'detached' | 'visible' | 'hidden';
|
|
408
|
+
timeoutMs?: number;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export interface NormalizedWaitForParams extends BridgeParams {
|
|
412
|
+
selector: string;
|
|
413
|
+
text: string | null;
|
|
414
|
+
state: 'attached' | 'detached' | 'visible' | 'hidden';
|
|
415
|
+
timeoutMs: number;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export interface FindByTextParams {
|
|
419
|
+
text?: string;
|
|
420
|
+
exact?: boolean;
|
|
421
|
+
selector?: string;
|
|
422
|
+
maxResults?: number;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface NormalizedFindByTextParams extends BridgeParams {
|
|
426
|
+
text: string;
|
|
427
|
+
exact: boolean;
|
|
428
|
+
selector: string;
|
|
429
|
+
maxResults: number;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export interface FindByRoleParams {
|
|
433
|
+
role?: string;
|
|
434
|
+
name?: string;
|
|
435
|
+
selector?: string;
|
|
436
|
+
maxResults?: number;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export interface NormalizedFindByRoleParams extends BridgeParams {
|
|
440
|
+
role: string;
|
|
441
|
+
name: string;
|
|
442
|
+
selector: string;
|
|
443
|
+
maxResults: number;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export interface GetHtmlParams {
|
|
447
|
+
elementRef?: string;
|
|
448
|
+
target?: InputTarget;
|
|
449
|
+
outer?: boolean;
|
|
450
|
+
maxLength?: number;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
export interface NormalizedGetHtmlParams extends BridgeParams {
|
|
454
|
+
elementRef: string;
|
|
455
|
+
target: InputTarget;
|
|
456
|
+
outer: boolean;
|
|
457
|
+
maxLength: number;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export interface HoverParams {
|
|
461
|
+
target?: InputTarget;
|
|
462
|
+
duration?: number;
|
|
463
|
+
modifiers?: string[];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export interface NormalizedHoverParams extends BridgeParams {
|
|
467
|
+
target: InputTarget;
|
|
468
|
+
duration: number;
|
|
469
|
+
modifiers: string[];
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export interface DragParams {
|
|
473
|
+
source?: InputTarget;
|
|
474
|
+
destination?: InputTarget;
|
|
475
|
+
offsetX?: number;
|
|
476
|
+
offsetY?: number;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export interface NormalizedDragParams extends BridgeParams {
|
|
480
|
+
source: InputTarget;
|
|
481
|
+
destination: InputTarget;
|
|
482
|
+
offsetX: number;
|
|
483
|
+
offsetY: number;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export interface StorageParams {
|
|
487
|
+
type?: 'local' | 'session';
|
|
488
|
+
keys?: string[];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export interface NormalizedStorageParams extends BridgeParams {
|
|
492
|
+
type: 'local' | 'session';
|
|
493
|
+
keys: string[] | null;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
export interface WaitForLoadStateParams {
|
|
497
|
+
waitForLoad?: boolean;
|
|
498
|
+
timeoutMs?: number;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
export interface NormalizedWaitForLoadStateParams extends BridgeParams {
|
|
502
|
+
waitForLoad: boolean;
|
|
503
|
+
timeoutMs: number;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export interface TabCreateParams {
|
|
507
|
+
url?: string;
|
|
508
|
+
active?: boolean;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export interface NormalizedTabCreateParams extends BridgeParams {
|
|
512
|
+
url: string;
|
|
513
|
+
active: boolean;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export interface TabCloseParams {
|
|
517
|
+
tabId?: number;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export interface NormalizedTabCloseParams extends BridgeParams {
|
|
521
|
+
tabId: number;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export interface AccessibilityTreeParams {
|
|
525
|
+
maxDepth?: number;
|
|
526
|
+
maxNodes?: number;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export interface NormalizedAccessibilityTreeParams extends BridgeParams {
|
|
530
|
+
maxDepth: number;
|
|
531
|
+
maxNodes: number;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export interface NetworkParams {
|
|
535
|
+
clear?: boolean;
|
|
536
|
+
limit?: number;
|
|
537
|
+
urlPattern?: string;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
export interface NormalizedNetworkParams extends BridgeParams {
|
|
541
|
+
clear: boolean;
|
|
542
|
+
limit: number;
|
|
543
|
+
urlPattern: string | null;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export interface PageTextParams {
|
|
547
|
+
textBudget?: number;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export interface NormalizedPageTextParams extends BridgeParams {
|
|
551
|
+
textBudget: number;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
export interface LogTailParams {
|
|
555
|
+
limit?: number;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export interface NormalizedLogTailParams extends BridgeParams {
|
|
559
|
+
limit: number;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
export interface ViewportResizeParams {
|
|
563
|
+
width?: number;
|
|
564
|
+
height?: number;
|
|
565
|
+
deviceScaleFactor?: number;
|
|
566
|
+
reset?: boolean;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export interface NormalizedViewportResizeParams extends BridgeParams {
|
|
570
|
+
width: number;
|
|
571
|
+
height: number;
|
|
572
|
+
deviceScaleFactor: number;
|
|
573
|
+
reset: boolean;
|
|
574
|
+
}
|
|
@@ -10,14 +10,16 @@ Token-efficient Chrome tab inspection, interaction, and CSS/DOM patching through
|
|
|
10
10
|
This CLI skill is for agents that can run shell commands and where direct `bbx` control fits better than MCP tools: manual debugging, terminal reproduction, install/doctor flows, raw protocol access, or environments without MCP.
|
|
11
11
|
|
|
12
12
|
Skill name: `browser-bridge` (also known as `bbx`). In GitHub Copilot, invoke as `/browser-bridge`. `bbx` is the CLI command used throughout this skill.
|
|
13
|
-
|
|
14
|
-
For open-ended investigation,
|
|
13
|
+
When the runtime supports subagents, delegate bridge inspection to a smaller, lower-cost worker and return only concise findings to the parent.
|
|
14
|
+
For open-ended investigation, start with structured reads (`page.get_state`, `dom.query`, `page.get_text`, `styles.get_computed`, `bbx batch`) and escalate to screenshots or debugger-backed methods only when structured evidence is insufficient.
|
|
15
15
|
|
|
16
16
|
## CLI
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
bbx status # daemon + extension health
|
|
20
20
|
bbx doctor # install/access readiness
|
|
21
|
+
bbx access-request # ask user to enable access for the focused window
|
|
22
|
+
bbx restart # start/restart the local daemon non-interactively
|
|
21
23
|
bbx call <method> '{...}' # any RPC method (raw output)
|
|
22
24
|
bbx <method> '{...}' # direct alias for an exact bridge method such as page.get_state
|
|
23
25
|
bbx call --tab 123 <method> '{...}' # explicit tab override
|
|
@@ -59,6 +61,7 @@ bbx navigate <url> # navigate to URL
|
|
|
59
61
|
bbx reload # reload current page
|
|
60
62
|
bbx back # navigate back
|
|
61
63
|
bbx forward # navigate forward
|
|
64
|
+
bbx scroll <top> [left] # scroll viewport
|
|
62
65
|
bbx resize <width> <height> # resize viewport
|
|
63
66
|
```
|
|
64
67
|
|
|
@@ -77,7 +80,7 @@ bbx patch-text <ref> <text...> # apply text patch
|
|
|
77
80
|
bbx patches # list active patches
|
|
78
81
|
bbx rollback <patchId> # rollback a patch
|
|
79
82
|
bbx screenshot <ref> [outPath] # capture partial element screenshot
|
|
80
|
-
bbx call screenshot.capture_full_page '{}' #
|
|
83
|
+
bbx call screenshot.capture_full_page '{}' # raw base64; avoid unless document context matters
|
|
81
84
|
```
|
|
82
85
|
|
|
83
86
|
## Access Flow
|
|
@@ -114,8 +117,8 @@ After access is enabled:
|
|
|
114
117
|
| `EXTENSION_DISCONNECTED` | After 3s | Check Chrome is running; `bbx status` to verify, then retry |
|
|
115
118
|
| `NATIVE_HOST_UNAVAILABLE` | No | Run `bbx doctor` to diagnose the installation |
|
|
116
119
|
| `INTERNAL_ERROR` | Once | Retry once; if persistent, check `page.get_console` for details |
|
|
117
|
-
| `DAEMON_OFFLINE` | No | Daemon not running - start with `bbx
|
|
118
|
-
| `CONNECTION_LOST` | Yes | Socket dropped mid-request - retry; if persistent, restart
|
|
120
|
+
| `DAEMON_OFFLINE` | No | Daemon not running - start with `bbx restart` |
|
|
121
|
+
| `CONNECTION_LOST` | Yes | Socket dropped mid-request - retry; if persistent, run `bbx restart` |
|
|
119
122
|
| `BRIDGE_TIMEOUT` | Once | Extension took too long - retry once with simpler call |
|
|
120
123
|
|
|
121
124
|
Error responses now include a machine-readable `error.recovery` field with `retry`, `retryAfterMs`, `alternativeMethod`, and `hint`.
|
|
@@ -160,6 +163,12 @@ For a natural-language inspection task:
|
|
|
160
163
|
4. Escalate to `screenshot.capture_element`, `screenshot.capture_region`, or other debugger-backed methods only when structured reads are ambiguous or visual confirmation is required.
|
|
161
164
|
5. Return concise findings and evidence, not raw dumps.
|
|
162
165
|
|
|
166
|
+
CLI-first starter:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
bbx batch '[{"method":"page.get_state"},{"method":"dom.query","params":{"selector":"main","maxNodes":10,"maxDepth":3,"textBudget":400,"attributeAllowlist":["id","class","data-testid"]}},{"method":"page.get_text","params":{"textBudget":2000}}]'
|
|
170
|
+
```
|
|
171
|
+
|
|
163
172
|
## Common Workflows
|
|
164
173
|
|
|
165
174
|
### Debug a CSS layout issue
|
|
@@ -269,6 +278,13 @@ Return: verdict, tab id + origin, minimal evidence set. No raw HTML or base64 im
|
|
|
269
278
|
|
|
270
279
|
Every CLI shortcut command produces consistent `{ok, summary, evidence}` JSON. Use `bbx call <method>` for raw protocol output when needed.
|
|
271
280
|
|
|
281
|
+
## CLI Raw Params Gotchas
|
|
282
|
+
|
|
283
|
+
- Use `selector`, not `scope`, to narrow `dom.find_by_text` and `dom.find_by_role`.
|
|
284
|
+
- Wrap interaction targets as `target: { elementRef }` or `target: { selector }`; `viewport.scroll` also uses the `target` wrapper for element scrolling.
|
|
285
|
+
- `input.drag` uses `source`, `destination`, and optional destination offsets `offsetX` / `offsetY`.
|
|
286
|
+
- Raw `screenshot.capture_region` and `screenshot.capture_full_page` return base64 JSON; prefer `bbx screenshot <ref> [outPath]` when one element is enough.
|
|
287
|
+
|
|
272
288
|
## Response Shapes
|
|
273
289
|
|
|
274
290
|
The summarizer auto-detects response types and produces concise summaries:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: 'Browser Bridge'
|
|
3
3
|
short_description: 'Token-efficient Chrome tab inspection, interaction, and patching via local bridge'
|
|
4
|
-
default_prompt: 'Use the browser-bridge skill for Chrome tab inspection, interaction, and patching. Start with `bbx status` to confirm connectivity
|
|
4
|
+
default_prompt: 'Use the browser-bridge skill for Chrome tab inspection, interaction, and patching. Start with `bbx status` to confirm connectivity; if the daemon is offline, run `bbx restart`. If ACCESS_DENIED, ask the user to click Enable in the extension popup/side panel, then retry. Default routing follows the active tab; use `--tab` only for a different tab. Prefer structured reads (`dom.query`, `styles.get_computed`) over screenshots. Batch independent reads with `bbx batch`. Use `bbx skill` for runtime presets.'
|
|
@@ -32,7 +32,7 @@ bbx call navigation.go_forward
|
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
34
|
bbx call viewport.scroll '{"top":640,"behavior":"smooth"}'
|
|
35
|
-
bbx call viewport.scroll '{"elementRef":"el_123","top":200}'
|
|
35
|
+
bbx call viewport.scroll '{"target":{"elementRef":"el_123"},"top":200}'
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Scrolls the window or a specific scrollable element.
|
|
@@ -125,10 +125,10 @@ bbx scroll 640 # scroll down 640px
|
|
|
125
125
|
bbx scroll 0 200 # scroll right 200px
|
|
126
126
|
bbx scroll 0 # scroll to top (top=0)
|
|
127
127
|
bbx call viewport.scroll '{"top":640,"behavior":"smooth"}'
|
|
128
|
-
bbx call viewport.scroll '{"elementRef":"el_123","top":200}'
|
|
128
|
+
bbx call viewport.scroll '{"target":{"elementRef":"el_123"},"top":200}'
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
Scrolls the window by default. Pass
|
|
131
|
+
Scrolls the window by default. Pass `target: { elementRef }` to scroll an inner scrollable container.
|
|
132
132
|
|
|
133
133
|
### Scroll target into view
|
|
134
134
|
|
|
@@ -205,7 +205,7 @@ bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRe
|
|
|
205
205
|
With pixel offsets for precise positioning:
|
|
206
206
|
|
|
207
207
|
```bash
|
|
208
|
-
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"},"
|
|
208
|
+
bbx call input.drag '{"source":{"elementRef":"el_src"},"destination":{"elementRef":"el_dst"},"offsetX":5,"offsetY":5}'
|
|
209
209
|
```
|
|
210
210
|
|
|
211
211
|
Event sequence: `mousedown → dragstart → drag → dragenter → dragover → drop → dragend → mouseup`.
|
|
@@ -225,10 +225,10 @@ Find elements matching visible text. Faster than `dom.query` when you know the l
|
|
|
225
225
|
|
|
226
226
|
```bash
|
|
227
227
|
bbx find 'Submit Order'
|
|
228
|
-
bbx call dom.find_by_text '{"text":"Add to Cart","
|
|
228
|
+
bbx call dom.find_by_text '{"text":"Add to Cart","selector":"button","exact":false}'
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
- `
|
|
231
|
+
- `selector`: optional CSS selector to narrow search (e.g. `"button"`, `".sidebar"`)
|
|
232
232
|
- `exact`: `true` for exact match, `false` (default) for substring/case-insensitive
|
|
233
233
|
|
|
234
234
|
### By ARIA role
|