claude-browser-bridge 4.0.1 → 4.0.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/bin/cli.js +17 -6
- package/gen-token.js +48 -10
- package/index.js +24 -10
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -44,14 +44,25 @@ Docs: https://github.com/HimanshuKanwar2001/claude-browser-bridge
|
|
|
44
44
|
`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function init() {
|
|
47
|
+
async function init() {
|
|
48
48
|
const extPath = args[args.indexOf("init") + 1] || null;
|
|
49
|
-
const tokenPath = join(SERVER_DIR, ".bridge-token");
|
|
50
49
|
const token = randomBytes(24).toString("hex");
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const os = await import("node:os");
|
|
51
|
+
const home = os.homedir();
|
|
52
|
+
|
|
53
|
+
// Write to canonical path: ~/.claude/browser-bridge-token
|
|
54
|
+
const claudeDir = join(home, ".claude");
|
|
55
|
+
if (!existsSync(claudeDir)) mkdirSync(claudeDir, { recursive: true });
|
|
56
|
+
const canonicalPath = join(home, ".claude", "browser-bridge-token");
|
|
57
|
+
writeFileSync(canonicalPath, token + "\n");
|
|
58
|
+
console.log(`✓ Token written to ${canonicalPath}`);
|
|
59
|
+
|
|
60
|
+
// Also write to server/.bridge-token (legacy fallback)
|
|
61
|
+
try {
|
|
62
|
+
const legacyPath = join(SERVER_DIR, ".bridge-token");
|
|
63
|
+
writeFileSync(legacyPath, token + "\n");
|
|
64
|
+
console.log(`✓ Token written to ${legacyPath}`);
|
|
65
|
+
} catch {}
|
|
55
66
|
|
|
56
67
|
// Write extension config if we can find the extension directory
|
|
57
68
|
const searchPaths = [
|
package/gen-token.js
CHANGED
|
@@ -1,13 +1,51 @@
|
|
|
1
|
-
// Generates the shared secret used to authenticate the extension to the
|
|
2
|
-
//
|
|
1
|
+
// Generates the shared secret used to authenticate the extension to the bridge.
|
|
2
|
+
// Writes to THREE locations so the token works regardless of install method:
|
|
3
|
+
// 1. ~/.claude/browser-bridge-token (canonical — works with global npm install)
|
|
4
|
+
// 2. server/.bridge-token (legacy — works with cloned repo)
|
|
5
|
+
// 3. extension/config.js (embedded in the Chrome extension)
|
|
6
|
+
|
|
3
7
|
import { randomBytes } from "node:crypto";
|
|
4
|
-
import { writeFileSync } from "node:fs";
|
|
8
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
5
12
|
|
|
6
13
|
const token = randomBytes(24).toString("hex");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
console.log(
|
|
14
|
+
|
|
15
|
+
// 1. Write to ~/.claude/browser-bridge-token (canonical path)
|
|
16
|
+
const claudeDir = join(homedir(), ".claude");
|
|
17
|
+
if (!existsSync(claudeDir)) mkdirSync(claudeDir, { recursive: true });
|
|
18
|
+
const canonicalPath = join(claudeDir, "browser-bridge-token");
|
|
19
|
+
writeFileSync(canonicalPath, token + "\n");
|
|
20
|
+
console.log(`✓ Token written to ${canonicalPath}`);
|
|
21
|
+
|
|
22
|
+
// 2. Write to server/.bridge-token (legacy, for local repo use)
|
|
23
|
+
try {
|
|
24
|
+
writeFileSync(new URL("./.bridge-token", import.meta.url), token + "\n");
|
|
25
|
+
console.log("✓ Token written to server/.bridge-token");
|
|
26
|
+
} catch {
|
|
27
|
+
// May fail if running from global install (read-only node_modules)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 3. Write extension/config.js (search multiple locations)
|
|
31
|
+
const searchPaths = [
|
|
32
|
+
new URL("../extension/config.js", import.meta.url).pathname,
|
|
33
|
+
join(process.cwd(), "extension", "config.js"),
|
|
34
|
+
];
|
|
35
|
+
let extensionWritten = false;
|
|
36
|
+
for (const p of searchPaths) {
|
|
37
|
+
try {
|
|
38
|
+
if (existsSync(join(p, "..", "manifest.json"))) {
|
|
39
|
+
writeFileSync(p, `// Generated by gen-token.js — keep out of version control.\nconst BRIDGE_TOKEN = ${JSON.stringify(token)};\n`);
|
|
40
|
+
console.log(`✓ Extension config written to ${p}`);
|
|
41
|
+
extensionWritten = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
if (!extensionWritten) {
|
|
47
|
+
console.log(`⚠ Extension directory not found — create extension/config.js manually:`);
|
|
48
|
+
console.log(` const BRIDGE_TOKEN = "${token}";`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log("\n✓ Token generated. Reload the extension in chrome://extensions to apply.");
|
package/index.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
// "owns" the bridge; later sessions detect EADDRINUSE and relay their tool
|
|
7
7
|
// calls through the owner. If the owner exits, a relay takes over the port.
|
|
8
8
|
|
|
9
|
-
import { readFileSync } from "node:fs";
|
|
9
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { homedir } from "node:os";
|
|
10
12
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
11
13
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
14
|
import {
|
|
@@ -17,20 +19,32 @@ import WebSocket, { WebSocketServer } from "ws";
|
|
|
17
19
|
|
|
18
20
|
const PORT = Number(process.env.BRIDGE_PORT) || 8787;
|
|
19
21
|
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
const
|
|
22
|
+
// Token resolution: check multiple locations so it works whether the server
|
|
23
|
+
// runs from a global npm install, npx, or the cloned repo.
|
|
24
|
+
const TOKEN_LOCATIONS = [
|
|
25
|
+
process.env.BRIDGE_TOKEN_PATH, // explicit override
|
|
26
|
+
join(homedir(), ".claude", "browser-bridge-token"), // canonical home path
|
|
27
|
+
new URL("./.bridge-token", import.meta.url).pathname, // relative to server file (repo install)
|
|
28
|
+
join(process.cwd(), "server", ".bridge-token"), // cwd/server/ (cloned repo)
|
|
29
|
+
join(process.cwd(), ".bridge-token"), // cwd root
|
|
30
|
+
].filter(Boolean);
|
|
31
|
+
|
|
23
32
|
function readToken() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
// Also check env var directly
|
|
34
|
+
if (process.env.BRIDGE_TOKEN) return process.env.BRIDGE_TOKEN;
|
|
35
|
+
for (const p of TOKEN_LOCATIONS) {
|
|
36
|
+
try {
|
|
37
|
+
const t = readFileSync(p, "utf8").trim();
|
|
38
|
+
if (t) return t;
|
|
39
|
+
} catch {}
|
|
28
40
|
}
|
|
41
|
+
return null;
|
|
29
42
|
}
|
|
30
43
|
if (!readToken()) {
|
|
31
44
|
console.error(
|
|
32
|
-
"[bridge] WARNING:
|
|
33
|
-
"or `node gen-token.js`.
|
|
45
|
+
"[bridge] WARNING: auth token not found. Run `claude-browser-bridge init` " +
|
|
46
|
+
"or `node gen-token.js`. Searched:\n" +
|
|
47
|
+
TOKEN_LOCATIONS.map(p => " - " + p).join("\n")
|
|
34
48
|
);
|
|
35
49
|
}
|
|
36
50
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-browser-bridge",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Connect your live Chrome tabs to Claude Code — 65 tools for debugging, performance, accessibility, visual inspection, and browser automation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|