@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.
- package/README.md +6 -4
- package/package.json +53 -53
- package/packages/agent-client/src/cli-helpers.js +43 -5
- package/packages/agent-client/src/cli.js +176 -171
- package/packages/agent-client/src/client.js +66 -21
- package/packages/agent-client/src/command-registry.js +104 -69
- package/packages/agent-client/src/detect.js +162 -54
- package/packages/agent-client/src/install.js +34 -28
- package/packages/agent-client/src/mcp-config.js +40 -40
- package/packages/agent-client/src/runtime.js +41 -20
- package/packages/agent-client/src/setup-status.js +23 -30
- package/packages/mcp-server/src/bin.js +57 -5
- package/packages/mcp-server/src/handlers.js +573 -256
- package/packages/mcp-server/src/server.js +568 -257
- package/packages/native-host/bin/bridge-daemon.js +39 -6
- package/packages/native-host/bin/install-manifest.js +26 -4
- package/packages/native-host/bin/postinstall.js +4 -2
- package/packages/native-host/src/config.js +142 -13
- package/packages/native-host/src/daemon-process.js +396 -0
- package/packages/native-host/src/daemon.js +350 -150
- package/packages/native-host/src/framing.js +131 -11
- package/packages/native-host/src/install-manifest.js +194 -29
- package/packages/native-host/src/native-host.js +154 -102
- package/packages/protocol/src/budget.js +3 -7
- package/packages/protocol/src/capabilities.js +6 -3
- package/packages/protocol/src/defaults.js +1 -0
- package/packages/protocol/src/errors.js +15 -11
- package/packages/protocol/src/payload-cost.js +19 -6
- package/packages/protocol/src/protocol.js +242 -73
- package/packages/protocol/src/registry.js +311 -45
- package/packages/protocol/src/summary.js +260 -109
- package/packages/protocol/src/types.js +29 -4
- package/skills/browser-bridge/SKILL.md +3 -2
- package/skills/browser-bridge/agents/openai.yaml +3 -3
- package/skills/browser-bridge/references/interaction.md +34 -11
- package/skills/browser-bridge/references/patch-workflow.md +3 -0
- package/skills/browser-bridge/references/protocol.md +127 -71
- package/skills/browser-bridge/references/tailwind.md +12 -11
- package/skills/browser-bridge/references/token-efficiency.md +23 -22
- package/skills/browser-bridge/references/ui-workflows.md +8 -0
- package/CHANGELOG.md +0 -55
- package/assets/banner.jpg +0 -0
- package/assets/logo.png +0 -0
- package/assets/logo.svg +0 -65
- package/docs/api-reference.md +0 -157
- package/docs/cli-guide.md +0 -128
- package/docs/index.md +0 -25
- package/docs/manual-setup.md +0 -140
- package/docs/mcp-vs-cli.md +0 -258
- package/docs/publishing.md +0 -114
- package/docs/quickstart.md +0 -104
- package/docs/troubleshooting.md +0 -59
- package/docs/usage-scenarios.md +0 -136
- package/manifest.json +0 -52
- package/packages/extension/assets/icon-128.png +0 -0
- package/packages/extension/assets/icon-16.png +0 -0
- package/packages/extension/assets/icon-32.png +0 -0
- package/packages/extension/assets/icon-48.png +0 -0
- package/packages/extension/src/background-helpers.js +0 -459
- package/packages/extension/src/background-routing.js +0 -91
- package/packages/extension/src/background.js +0 -3227
- package/packages/extension/src/content-script-helpers.js +0 -281
- package/packages/extension/src/content-script.js +0 -1977
- package/packages/extension/src/debugger-coordinator.js +0 -188
- package/packages/extension/src/sidepanel-helpers.js +0 -102
- package/packages/extension/ui/offscreen.html +0 -6
- package/packages/extension/ui/offscreen.js +0 -61
- package/packages/extension/ui/popup.html +0 -35
- package/packages/extension/ui/popup.js +0 -279
- package/packages/extension/ui/sidepanel.html +0 -102
- package/packages/extension/ui/sidepanel.js +0 -1854
- 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
|
-

|
|
3
|
+

|
|
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://
|
|
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
|
|
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.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"
|
|
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
|
-
"
|
|
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": "
|
|
57
|
-
"
|
|
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:
|
|
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
|
-
"
|
|
71
|
-
"
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
72
|
+
"zod": "^4.3.6"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
|
-
"@
|
|
75
|
-
"@types/
|
|
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
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
78
|
+
"linkedom": "^0.18.12",
|
|
79
|
+
"oxfmt": "^0.47.0",
|
|
80
|
+
"oxlint": "^1.62.0",
|
|
81
|
+
"typescript": "^6.0.3"
|
|
81
82
|
},
|
|
82
|
-
"
|
|
83
|
-
"
|
|
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
|
|
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(
|
|
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 {
|