@browserbridge/bbx 1.0.0 → 1.1.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.
Files changed (72) hide show
  1. package/README.md +6 -4
  2. package/package.json +53 -53
  3. package/packages/agent-client/src/cli-helpers.js +43 -5
  4. package/packages/agent-client/src/cli.js +176 -171
  5. package/packages/agent-client/src/client.js +66 -21
  6. package/packages/agent-client/src/command-registry.js +104 -69
  7. package/packages/agent-client/src/detect.js +162 -54
  8. package/packages/agent-client/src/install.js +34 -28
  9. package/packages/agent-client/src/mcp-config.js +40 -40
  10. package/packages/agent-client/src/runtime.js +41 -20
  11. package/packages/agent-client/src/setup-status.js +23 -30
  12. package/packages/mcp-server/src/bin.js +57 -5
  13. package/packages/mcp-server/src/handlers.js +573 -256
  14. package/packages/mcp-server/src/server.js +568 -257
  15. package/packages/native-host/bin/bridge-daemon.js +39 -6
  16. package/packages/native-host/bin/install-manifest.js +26 -4
  17. package/packages/native-host/bin/postinstall.js +4 -2
  18. package/packages/native-host/src/config.js +142 -13
  19. package/packages/native-host/src/daemon-process.js +396 -0
  20. package/packages/native-host/src/daemon.js +350 -150
  21. package/packages/native-host/src/framing.js +131 -11
  22. package/packages/native-host/src/install-manifest.js +194 -29
  23. package/packages/native-host/src/native-host.js +154 -102
  24. package/packages/protocol/src/budget.js +3 -7
  25. package/packages/protocol/src/capabilities.js +6 -3
  26. package/packages/protocol/src/defaults.js +1 -0
  27. package/packages/protocol/src/errors.js +15 -11
  28. package/packages/protocol/src/payload-cost.js +19 -6
  29. package/packages/protocol/src/protocol.js +242 -73
  30. package/packages/protocol/src/registry.js +311 -45
  31. package/packages/protocol/src/summary.js +260 -109
  32. package/packages/protocol/src/types.js +29 -4
  33. package/skills/browser-bridge/SKILL.md +3 -2
  34. package/skills/browser-bridge/agents/openai.yaml +3 -3
  35. package/skills/browser-bridge/references/interaction.md +34 -11
  36. package/skills/browser-bridge/references/patch-workflow.md +3 -0
  37. package/skills/browser-bridge/references/protocol.md +127 -71
  38. package/skills/browser-bridge/references/tailwind.md +12 -11
  39. package/skills/browser-bridge/references/token-efficiency.md +23 -22
  40. package/skills/browser-bridge/references/ui-workflows.md +8 -0
  41. package/CHANGELOG.md +0 -55
  42. package/assets/banner.jpg +0 -0
  43. package/assets/logo.png +0 -0
  44. package/assets/logo.svg +0 -65
  45. package/docs/api-reference.md +0 -157
  46. package/docs/cli-guide.md +0 -128
  47. package/docs/index.md +0 -25
  48. package/docs/manual-setup.md +0 -140
  49. package/docs/mcp-vs-cli.md +0 -258
  50. package/docs/publishing.md +0 -114
  51. package/docs/quickstart.md +0 -104
  52. package/docs/troubleshooting.md +0 -59
  53. package/docs/usage-scenarios.md +0 -136
  54. package/manifest.json +0 -52
  55. package/packages/extension/assets/icon-128.png +0 -0
  56. package/packages/extension/assets/icon-16.png +0 -0
  57. package/packages/extension/assets/icon-32.png +0 -0
  58. package/packages/extension/assets/icon-48.png +0 -0
  59. package/packages/extension/src/background-helpers.js +0 -459
  60. package/packages/extension/src/background-routing.js +0 -91
  61. package/packages/extension/src/background.js +0 -3227
  62. package/packages/extension/src/content-script-helpers.js +0 -281
  63. package/packages/extension/src/content-script.js +0 -1977
  64. package/packages/extension/src/debugger-coordinator.js +0 -188
  65. package/packages/extension/src/sidepanel-helpers.js +0 -102
  66. package/packages/extension/ui/offscreen.html +0 -6
  67. package/packages/extension/ui/offscreen.js +0 -61
  68. package/packages/extension/ui/popup.html +0 -35
  69. package/packages/extension/ui/popup.js +0 -279
  70. package/packages/extension/ui/sidepanel.html +0 -102
  71. package/packages/extension/ui/sidepanel.js +0 -1854
  72. package/packages/extension/ui/ui.css +0 -1159
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Browser Bridge
1
+ # Browser Bridge (BBX)
2
2
 
3
- ![Browser Bridge: Connect AI Agent and Browsers](https://raw.githubusercontent.com/koltyakov/browser-bridge/main/assets/banner.jpg)
3
+ ![Browser Bridge (BBX): Connect AI Agent and Browsers](https://raw.githubusercontent.com/koltyakov/browser-bridge/main/assets/banner.jpg)
4
+
5
+ > **Chrome Web Store:** Install `Browser Bridge (BBX)` from the [Chrome Web Store](https://chromewebstore.google.com/detail/browser-bridge/jjjkmmcdkpcgamlopogicbnnhdgebhie). For local or custom builds, use the unpacked install flow in [docs/unpacked-extension.md](https://github.com/koltyakov/browser-bridge/blob/main/docs/unpacked-extension.md).
4
6
 
5
7
  A local bridge between your coding agent and a real Chrome tab. Browser Bridge gives the agent structured access to DOM, styles, layout, console, network, and reversible patches - starting from the actual tab you already have open, with all its real state intact.
6
8
 
@@ -103,9 +105,9 @@ Browser Bridge is optimized for the opposite starting point: **inspect the state
103
105
 
104
106
  ## Setup
105
107
 
106
- 1. Install [Browser Bridge from the Chrome Web Store](https://chrome.google.com/webstore/detail/jjjkmmcdkpcgamlopogicbnnhdgebhie) <!-- TODO: replace with final store link after publishing -->
108
+ 1. Install [Browser Bridge from the Chrome Web Store](https://chromewebstore.google.com/detail/browser-bridge/jjjkmmcdkpcgamlopogicbnnhdgebhie)
107
109
  2. `npm install -g @browserbridge/bbx` - installs the CLI and native host
108
- 3. In the extension side panel, install MCP or CLI (skill) for your agent of choice, or run the `bbx install-mcp` / `bbx install-skill` commands if you prefer terminal setup
110
+ 3. In the extension side panel, install MCP or CLI (skill) for your agent of choice
109
111
  4. Enable Browser Bridge for the Chrome window you want to inspect/control with the AI agent
110
112
  5. Ask your agent to use Browser Bridge via MCP (`BB MCP` or `Browser Bridge MCP`), or invoke the `browser-bridge` / `$bbx` skill in CLI mode
111
113
 
package/package.json CHANGED
@@ -1,86 +1,86 @@
1
1
  {
2
2
  "name": "@browserbridge/bbx",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "private": false,
5
- "type": "module",
5
+ "keywords": [
6
+ "agent-tools",
7
+ "ai-agent",
8
+ "browser",
9
+ "browser-automation",
10
+ "browser-bridge",
11
+ "chrome",
12
+ "chrome-extension",
13
+ "developer-tools",
14
+ "mcp",
15
+ "model-context-protocol",
16
+ "native-messaging",
17
+ "ui-debugging"
18
+ ],
19
+ "homepage": "https://github.com/koltyakov/browser-bridge#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/koltyakov/browser-bridge/issues"
22
+ },
6
23
  "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/koltyakov/browser-bridge.git"
27
+ },
28
+ "bin": {
29
+ "bbx": "packages/agent-client/src/cli.js",
30
+ "bbx-daemon": "packages/native-host/bin/bridge-daemon.js",
31
+ "bbx-install": "packages/native-host/bin/install-manifest.js",
32
+ "bbx-mcp": "packages/mcp-server/src/bin.js"
33
+ },
7
34
  "files": [
8
- "assets",
9
- "CHANGELOG.md",
10
35
  "LICENSE",
11
36
  "README.md",
12
- "docs",
13
- "manifest.json",
14
37
  "packages/agent-client/src",
15
- "packages/extension/assets",
16
- "packages/extension/src",
17
- "packages/extension/ui",
18
38
  "packages/mcp-server/src",
19
39
  "packages/native-host/bin",
20
40
  "packages/native-host/src",
21
41
  "packages/protocol/src",
22
- "skills/browser-bridge"
42
+ "skills/browser-bridge",
43
+ "!**/test/**",
44
+ "!**/*.test.*",
45
+ "!**/*.spec.*"
23
46
  ],
24
- "bin": {
25
- "bbx": "packages/agent-client/src/cli.js",
26
- "bbx-mcp": "packages/mcp-server/src/bin.js",
27
- "bbx-daemon": "packages/native-host/bin/bridge-daemon.js",
28
- "bbx-install": "packages/native-host/bin/install-manifest.js"
29
- },
47
+ "type": "module",
30
48
  "publishConfig": {
31
49
  "access": "public"
32
50
  },
33
- "repository": {
34
- "type": "git",
35
- "url": "git+https://github.com/koltyakov/browser-bridge.git"
36
- },
37
- "homepage": "https://github.com/koltyakov/browser-bridge#readme",
38
- "bugs": {
39
- "url": "https://github.com/koltyakov/browser-bridge/issues"
40
- },
41
- "keywords": [
42
- "browser-bridge",
43
- "browser",
44
- "chrome",
45
- "chrome-extension",
46
- "native-messaging",
47
- "mcp",
48
- "model-context-protocol",
49
- "ai-agent",
50
- "agent-tools",
51
- "developer-tools",
52
- "ui-debugging",
53
- "browser-automation"
54
- ],
55
51
  "scripts": {
56
- "lint": "eslint .",
57
- "test": "c8 node --test packages/protocol/test/*.test.js packages/native-host/test/*.test.js packages/agent-client/test/*.test.js packages/mcp-server/test/*.test.js packages/extension/test/*.test.js",
52
+ "lint": "oxlint . && oxfmt --check .",
53
+ "format": "oxfmt .",
54
+ "format:check": "oxfmt --check .",
55
+ "test:runtime": "node --test",
56
+ "test": "c8 node --test",
58
57
  "coverage": "c8 report --reporter=text --reporter=text-summary",
59
- "coverage:check": "c8 check-coverage --lines 70",
58
+ "coverage:review": "c8 report --reporter=json-summary && node scripts/review-coverage.mjs",
59
+ "coverage:check": "c8 check-coverage --lines 80 --branches 75",
60
60
  "typecheck": "tsc --noEmit",
61
61
  "postinstall": "node packages/native-host/bin/postinstall.js",
62
62
  "package:extension": "node scripts/package-extension.mjs",
63
63
  "check:extension-zip": "node scripts/check-extension-zip.mjs",
64
64
  "release:check": "npm run lint && npm run typecheck && npm test && npm run coverage:check && npm run package:extension && npm pack --dry-run",
65
- "prepublishOnly": "npm run lint && npm run typecheck && npm test",
65
+ "prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run coverage:check",
66
66
  "status": "node packages/agent-client/src/cli.js status",
67
67
  "daemon": "node packages/native-host/bin/bridge-daemon.js",
68
68
  "install-manifest": "node packages/native-host/bin/install-manifest.js"
69
69
  },
70
- "engines": {
71
- "node": ">=18"
70
+ "dependencies": {
71
+ "@modelcontextprotocol/sdk": "^1.29.0",
72
+ "zod": "^4.3.6"
72
73
  },
73
74
  "devDependencies": {
74
- "@eslint/js": "^10.0.1",
75
- "@types/chrome": "^0.1.38",
76
- "@types/node": "^25.4.0",
75
+ "@types/chrome": "^0.1.40",
76
+ "@types/node": "^25.5.2",
77
77
  "c8": "^11.0.0",
78
- "eslint": "^10.1.0",
79
- "globals": "^17.4.0",
80
- "typescript": "^6.0.2"
78
+ "linkedom": "^0.18.12",
79
+ "oxfmt": "^0.47.0",
80
+ "oxlint": "^1.62.0",
81
+ "typescript": "^6.0.3"
81
82
  },
82
- "dependencies": {
83
- "@modelcontextprotocol/sdk": "^1.28.0",
84
- "zod": "^4.3.6"
83
+ "engines": {
84
+ "node": ">=18"
85
85
  }
86
86
  }
@@ -3,6 +3,39 @@
3
3
  import readline from 'node:readline';
4
4
  import { bridgeMethodNeedsTab } from '../../protocol/src/index.js';
5
5
 
6
+ /**
7
+ * Strip ANSI escape sequences from a string to prevent terminal injection
8
+ * from malicious page content (e.g. DOM text, console output, eval results).
9
+ *
10
+ * @param {string} str
11
+ * @returns {string}
12
+ */
13
+ export function stripAnsi(str) {
14
+ // oxlint-disable-next-line no-control-regex
15
+ return str.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '').replace(/\x1b[^[]/g, '');
16
+ }
17
+
18
+ /**
19
+ * Recursively sanitize all string values in a value tree by stripping ANSI
20
+ * escape sequences. Only strings are touched; structure is preserved.
21
+ *
22
+ * @param {unknown} value
23
+ * @returns {unknown}
24
+ */
25
+ export function sanitizeOutput(value) {
26
+ if (typeof value === 'string') return stripAnsi(value);
27
+ if (Array.isArray(value)) return value.map(sanitizeOutput);
28
+ if (value !== null && typeof value === 'object') {
29
+ return Object.fromEntries(
30
+ Object.entries(/** @type {Record<string, unknown>} */ (value)).map(([k, v]) => [
31
+ k,
32
+ sanitizeOutput(v),
33
+ ])
34
+ );
35
+ }
36
+ return value;
37
+ }
38
+
6
39
  /**
7
40
  * @param {string[]} values
8
41
  * @returns {Record<string, string>}
@@ -30,7 +63,10 @@ export function parseCommaList(value) {
30
63
  if (!value) {
31
64
  return [];
32
65
  }
33
- return value.split(',').map((item) => item.trim()).filter(Boolean);
66
+ return value
67
+ .split(',')
68
+ .map((item) => item.trim())
69
+ .filter(Boolean);
34
70
  }
35
71
 
36
72
  /**
@@ -50,7 +86,9 @@ export function parseJsonObject(value) {
50
86
  }
51
87
 
52
88
  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
53
- throw new Error(`Expected a JSON object but got ${Array.isArray(parsed) ? 'array' : typeof parsed}. Wrap your input in {}.`);
89
+ throw new Error(
90
+ `Expected a JSON object but got ${Array.isArray(parsed) ? 'array' : typeof parsed}. Wrap your input in {}.`
91
+ );
54
92
  }
55
93
 
56
94
  return /** @type {Record<string, unknown>} */ (parsed);
@@ -131,7 +169,7 @@ export async function interactiveCheckbox(title, items) {
131
169
  }
132
170
 
133
171
  process.stdout.write('\x1b[?25l'); // hide cursor
134
- if (typeof /** @type {any} */ (process.stdin).setRawMode === 'function') {
172
+ if (typeof (/** @type {any} */ (process.stdin).setRawMode) === 'function') {
135
173
  /** @type {any} */ (process.stdin).setRawMode(true);
136
174
  }
137
175
  process.stdin.resume();
@@ -143,7 +181,7 @@ export async function interactiveCheckbox(title, items) {
143
181
  */
144
182
  function cleanup(result) {
145
183
  process.stdin.removeListener('keypress', onKeypress);
146
- if (typeof /** @type {any} */ (process.stdin).setRawMode === 'function') {
184
+ if (typeof (/** @type {any} */ (process.stdin).setRawMode) === 'function') {
147
185
  /** @type {any} */ (process.stdin).setRawMode(false);
148
186
  }
149
187
  process.stdin.pause();
@@ -204,7 +242,7 @@ export async function interactiveConfirm(prompt, options = {}) {
204
242
  const suffix = defaultValue ? ' [Y/n] ' : ' [y/N] ';
205
243
  const rl = readline.createInterface({
206
244
  input: process.stdin,
207
- output: process.stdout
245
+ output: process.stdout,
208
246
  });
209
247
 
210
248
  try {