@browserbridge/bbx 1.5.1 → 1.5.2

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 CHANGED
@@ -112,6 +112,8 @@ Browser Bridge is optimized for the opposite starting point: **inspect the state
112
112
  5. Enable Browser Bridge for the browser window you want to inspect/control with the AI agent
113
113
  6. Ask your agent to use Browser Bridge via MCP (`BB MCP` or `Browser Bridge MCP`), or invoke the installed Browser Bridge skill in CLI mode (`/browser-bridge`, `browser-bridge`, or the client-specific skill trigger)
114
114
 
115
+ On Ubuntu, Chromium is commonly installed as a strict snap, and Flatpak Chromium is similarly sandboxed. If native messaging stays disconnected there, use a non-sandboxed Chromium-based browser such as Google Chrome, Brave, or Edge.
116
+
115
117
  MCP mode is self-contained: the server exposes tools, startup instructions, and prompt templates, so a separate CLI skill is not required for MCP guidance.
116
118
 
117
119
  ## How it works
@@ -129,6 +131,7 @@ MCP mode is self-contained: the server exposes tools, startup instructions, and
129
131
  - [Quickstart](https://github.com/koltyakov/browser-bridge/blob/main/docs/quickstart.md)
130
132
  - [Usage scenarios](https://github.com/koltyakov/browser-bridge/blob/main/docs/usage-scenarios.md)
131
133
  - [Manual setup](https://github.com/koltyakov/browser-bridge/blob/main/docs/manual-setup.md)
134
+ - [Agent permissions](https://github.com/koltyakov/browser-bridge/blob/main/docs/agent-permissions.md)
132
135
  - [CLI guide](https://github.com/koltyakov/browser-bridge/blob/main/docs/cli-guide.md)
133
136
  - [MCP vs CLI](https://github.com/koltyakov/browser-bridge/blob/main/docs/mcp-vs-cli.md)
134
137
  - [Troubleshooting](https://github.com/koltyakov/browser-bridge/blob/main/docs/troubleshooting.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@browserbridge/bbx",
3
- "version": "1.5.1",
3
+ "version": "1.5.2",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "agent-tools",
@@ -21,6 +21,9 @@ import { BridgeClient } from './client.js';
21
21
  /** @typedef {import('./types.js').DoctorReport} DoctorReport */
22
22
  /** @typedef {import('./types.js').DoctorReportOptions} DoctorReportOptions */
23
23
 
24
+ const CHROMIUM_SANDBOXED_MANIFEST_RE =
25
+ /(?:^|[/\\])(?:snap[/\\]chromium|\.var[/\\]app[/\\]org\.chromium\.Chromium)[/\\]/;
26
+
24
27
  /**
25
28
  * @param {BridgeClient} client
26
29
  * @returns {Promise<void>}
@@ -164,6 +167,12 @@ export async function getDoctorReport(options = {}) {
164
167
 
165
168
  const browserManifests = await (options.checkBrowserManifests || checkBrowserManifests)();
166
169
  const manifestInstalled = Boolean(manifest) || browserManifests.some((b) => b.installed);
170
+ const chromiumSandboxedManifestInstalled = browserManifests.some(
171
+ (entry) =>
172
+ entry.installed &&
173
+ entry.browser === 'chromium' &&
174
+ CHROMIUM_SANDBOXED_MANIFEST_RE.test(entry.manifestPath)
175
+ );
167
176
 
168
177
  /** @type {DoctorReport} */
169
178
  const report = {
@@ -228,6 +237,12 @@ export async function getDoctorReport(options = {}) {
228
237
  }
229
238
  if (report.daemonReachable && !report.extensionConnected) {
230
239
  report.issues.push('extension_disconnected');
240
+ if (chromiumSandboxedManifestInstalled) {
241
+ report.issues.push('chromium_sandboxed_native_host_limited');
242
+ report.nextSteps.push(
243
+ "Detected a sandboxed Chromium native host manifest for snap or Flatpak. Sandboxed Chromium may not be able to launch Browser Bridge's Node-based native host; use Google Chrome, Brave, or Edge from a non-sandboxed package and run `bbx install --browser <browser>`."
244
+ );
245
+ }
231
246
  report.nextSteps.push(
232
247
  'Open Chrome and make sure the Browser Bridge extension is installed and active.'
233
248
  );
@@ -7,12 +7,14 @@ import * as z from 'zod/v4';
7
7
 
8
8
  export const MCP_SERVER_INSTRUCTIONS = [
9
9
  "Browser Bridge MCP inspects and interacts with the user's real Chrome tab through typed MCP tools.",
10
+ 'In permission-ask hosts, use browser_call as the default Browser Bridge MCP tool so the user can approve one BBX tool instead of separate browser_status, browser_page, browser_dom, browser_input, and other tools.',
10
11
  'Prefer Browser Bridge MCP tools over shelling out to bbx. Use bbx only for explicit CLI setup, doctor, logs, or raw debugging requests.',
11
- 'Call browser_status first. If window access is disabled, call browser_access once, ask the user to click Enable in the Browser Bridge popup or side panel, then retry once.',
12
- 'Use structured reads first: browser_page, browser_dom, browser_styles_layout, and browser_batch. Keep budgetPreset quick or normal before widening.',
12
+ 'Start with browser_call method health.ping. If window access is disabled, call browser_call method access.request once, ask the user to click Enable in the Browser Bridge popup or side panel, then retry once.',
13
+ 'Use structured reads first through browser_call: page.get_state, dom.query, page.get_text, styles.get_computed, layout.get_box_model, or batch. Keep budgets quick or normal before widening.',
13
14
  'Reuse elementRef values returned by DOM tools. Use attribute allowlists for focused DOM reads.',
14
- 'Escalate to browser_capture, accessibility_tree, page evaluate, viewport resize, or CDP only when structured reads cannot answer the question.',
15
- 'Use browser_patch for temporary style or DOM experiments, and rollback patches before finishing unless the user asks to keep them.',
15
+ 'Escalate to screenshot.capture_element, screenshot.capture_region, accessibility_tree, page.evaluate, viewport.resize, or CDP only when structured reads cannot answer the question.',
16
+ 'Use patch.apply_styles or patch.apply_dom for temporary experiments, and rollback patches before finishing unless the user asks to keep them.',
17
+ 'Only use the specialized Browser Bridge MCP tools directly when the host has already allowed them or the user explicitly wants typed tool calls.',
16
18
  ].join('\n');
17
19
 
18
20
  export const MCP_GUIDANCE_PROMPT_NAMES = Object.freeze([
@@ -97,13 +99,15 @@ function createGuidePrompt() {
97
99
  'Use Browser Bridge MCP for this browser task.',
98
100
  '',
99
101
  'Rules:',
100
- '1. Prefer MCP tools over `bbx`; do not shell out unless setup, doctor, logs, or raw CLI debugging is explicitly needed.',
101
- '2. Call `browser_status` first. If access is disabled, call `browser_access` once, ask the user to click Enable, then retry once.',
102
- '3. Start with structured reads: `browser_page` action `state`, `browser_dom` action `query`/`find_text`/`find_role`, `browser_styles_layout`, and `browser_batch`.',
103
- '4. Keep budgets tight with `budgetPreset: "quick"` or `"normal"`; widen only when results are truncated.',
104
- '5. Reuse `elementRef` values returned by DOM tools instead of rescanning.',
105
- '6. Escalate to `browser_capture`, accessibility tree, `browser_page` evaluate, viewport resize, or CDP only when structured reads cannot answer.',
106
- '7. Use `browser_patch` for temporary style/DOM experiments and rollback before finishing unless the user asks to keep patches.',
102
+ '1. Prefer MCP over `bbx`; do not shell out unless setup, doctor, logs, or raw CLI debugging is explicitly needed.',
103
+ '2. In permission-ask hosts, use `browser_call` as the default tool so the user can approve one BBX MCP tool instead of separate tools for status, page, DOM, input, and patches.',
104
+ '3. Start with `browser_call` method `health.ping`. If access is disabled, call `browser_call` method `access.request` once, ask the user to click Enable, then retry once.',
105
+ '4. Start with structured reads via `browser_call`: `page.get_state`, `dom.query`, `dom.find_by_text`, `dom.find_by_role`, `styles.get_computed`, and `batch`.',
106
+ '5. Keep budgets tight with `budgetPreset: "quick"` or `"normal"`; widen only when results are truncated.',
107
+ '6. Reuse `elementRef` values returned by DOM tools instead of rescanning.',
108
+ '7. Escalate to screenshots, accessibility tree, `page.evaluate`, viewport resize, or CDP only when structured reads cannot answer.',
109
+ '8. Use `patch.apply_styles` or `patch.apply_dom` for temporary experiments and rollback before finishing unless the user asks to keep patches.',
110
+ '9. Only use specialized Browser Bridge MCP tools directly when the host has already allowed them or the user explicitly wants typed tool calls.',
107
111
  '',
108
112
  'Return concise findings with evidence. Edit source code only after the live page behavior is understood.',
109
113
  ].join('\n')
@@ -656,7 +656,7 @@ export function createBridgeMcpServer() {
656
656
  {
657
657
  title: 'Raw Browser Bridge Call',
658
658
  description:
659
- 'Call any bridge method directly by name. Escape hatch when grouped tools lack a needed parameter or method.',
659
+ 'Primary Browser Bridge tool for permission-ask hosts: call any bridge method directly by name so the user can approve one BBX MCP tool instead of each specialized tool separately.',
660
660
  inputSchema: {
661
661
  method: z.string().describe('Bridge method name (e.g., "dom.query", "input.click")'),
662
662
  params: z
@@ -19,6 +19,10 @@ export const DEFAULT_EXTENSION_ID_ENV = 'BROWSER_BRIDGE_EXTENSION_ID';
19
19
  export const BUILT_IN_EXTENSION_ID_SOURCE = 'built_in';
20
20
  export const INSTALL_NATIVE_MANIFEST_ERROR = 'INSTALL_NATIVE_MANIFEST_FAILED';
21
21
 
22
+ const CHROMIUM_SNAP_NATIVE_MESSAGING_RE = /(?:^|[/\\])snap[/\\]chromium[/\\]/;
23
+ const CHROMIUM_FLATPAK_NATIVE_MESSAGING_RE =
24
+ /(?:^|[/\\])\.var[/\\]app[/\\]org\.chromium\.Chromium[/\\]/;
25
+
22
26
  /** @typedef {import('./config.js').SupportedBrowser} SupportedBrowser */
23
27
  /** @typedef {'env' | 'built_in' | 'none' | 'invalid_env'} ExtensionIdSource */
24
28
  /** @typedef {NodeJS.ErrnoException & { cause?: unknown }} MaybeErrnoError */
@@ -360,6 +364,18 @@ exec '${escapeSingleQuotes(nodePath)}' '${escapeSingleQuotes(hostPath)}' "$@"
360
364
  );
361
365
  }
362
366
 
367
+ if (isChromiumSnapManifestInstall(browser, installDir)) {
368
+ stderr.write(
369
+ 'Compatibility warning: detected a Linux Chromium snap native messaging path. Strict snap Chromium commonly blocks launching Browser Bridge\'s Node-based native host with AppArmor, which leaves `bbx status` at "Extension: disconnected". Use a non-snap Chromium-based browser such as Google Chrome, Brave, or Edge and run `bbx install --browser <browser>`.\n'
370
+ );
371
+ }
372
+
373
+ if (isChromiumFlatpakManifestInstall(browser, installDir)) {
374
+ stderr.write(
375
+ 'Compatibility warning: detected a Linux Chromium Flatpak native messaging path. Sandboxed Flatpak Chromium commonly blocks launching Browser Bridge\'s Node-based native host, which leaves `bbx status` at "Extension: disconnected". Use a non-sandboxed Chromium-based browser such as Google Chrome, Brave, or Edge and run `bbx install --browser <browser>`.\n'
376
+ );
377
+ }
378
+
363
379
  const hasPlaceholder = allowedOrigins.some((origin) =>
364
380
  origin.includes('__REPLACE_WITH_EXTENSION_ID__')
365
381
  );
@@ -378,6 +394,24 @@ exec '${escapeSingleQuotes(nodePath)}' '${escapeSingleQuotes(hostPath)}' "$@"
378
394
  };
379
395
  }
380
396
 
397
+ /**
398
+ * @param {SupportedBrowser | undefined} browser
399
+ * @param {string} installDir
400
+ * @returns {boolean}
401
+ */
402
+ function isChromiumSnapManifestInstall(browser, installDir) {
403
+ return browser === 'chromium' && CHROMIUM_SNAP_NATIVE_MESSAGING_RE.test(installDir);
404
+ }
405
+
406
+ /**
407
+ * @param {SupportedBrowser | undefined} browser
408
+ * @param {string} installDir
409
+ * @returns {boolean}
410
+ */
411
+ function isChromiumFlatpakManifestInstall(browser, installDir) {
412
+ return browser === 'chromium' && CHROMIUM_FLATPAK_NATIVE_MESSAGING_RE.test(installDir);
413
+ }
414
+
381
415
  /**
382
416
  * @param {UninstallManifestOptions} [options={}]
383
417
  * @returns {Promise<{ manifestPath: string, bridgeDir: string, removedManifest: boolean, removedBridgeDir: boolean }>}
@@ -9,6 +9,8 @@ Token-efficient Chrome tab inspection, interaction, and CSS/DOM patching through
9
9
 
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
+ Permission prompts are controlled by the host agent, not by Browser Bridge. In permission-ask MCP hosts, use the generic `browser_call` MCP tool by default so the user can approve one BBX tool instead of separate status, page, DOM, input, and patch tools. In Claude Code CLI mode, allow `bbx` with `Bash(bbx *)` when direct shell access is desired. Exact permission syntax varies by client.
13
+
12
14
  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
15
  When the runtime supports subagents, delegate bridge inspection to a smaller, lower-cost worker and return only concise findings to the parent.
14
16
  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.