chrome-bridge-mcp 1.30.1 → 1.30.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/extension/manifest.json +1 -1
- package/extension/service-worker.js +12 -2
- package/package.json +1 -1
- package/server/lighthouse.js +18 -1
- package/server/protocol.js +1 -1
package/extension/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Chrome Bridge for Claude Code",
|
|
4
|
-
"version": "1.30.
|
|
4
|
+
"version": "1.30.2",
|
|
5
5
|
"description": "Bridge your browser to Claude Code: 67 token-efficient web-dev automation tools over a local WebSocket. ChromeOS included.",
|
|
6
6
|
"homepage_url": "https://github.com/frsorrentino/chrome-bridge",
|
|
7
7
|
"minimum_chrome_version": "135",
|
|
@@ -1507,14 +1507,24 @@ function recordTabEnding(tabId, ending) {
|
|
|
1507
1507
|
if (tabEndings.size > TAB_ENDINGS_MAX) tabEndings.delete(tabEndings.keys().next().value);
|
|
1508
1508
|
}
|
|
1509
1509
|
|
|
1510
|
+
const CLOSE_WAIT_MS = 5000;
|
|
1511
|
+
|
|
1510
1512
|
async function cmdTabAction({ action, tab_id, bypass_cache = false }) {
|
|
1511
1513
|
if (!action) throw new Error('Missing required parameter: action');
|
|
1512
1514
|
const tabId = await resolveTabId(tab_id);
|
|
1513
1515
|
|
|
1514
1516
|
if (action === 'close') {
|
|
1517
|
+
// chrome.tabs.remove aspetta che la pagina lasci andare: con un dialogo
|
|
1518
|
+
// «Vuoi uscire?» aperto o la pagina bloccata in un ciclo resterebbe muta
|
|
1519
|
+
// fino al timeout del comando (30 s, visto il 15/10). Dopo 5 s si risponde
|
|
1520
|
+
// con un errore; la chiusura resta in corso e Chrome la completa quando
|
|
1521
|
+
// la pagina cede (get_tabs la riporta come closed_by_bridge).
|
|
1515
1522
|
bridgeClosing.add(tabId);
|
|
1516
|
-
|
|
1517
|
-
|
|
1523
|
+
const removing = chrome.tabs.remove(tabId).then(() => true, (e) => { bridgeClosing.delete(tabId); throw e; });
|
|
1524
|
+
const done = await Promise.race([removing, new Promise((r) => setTimeout(() => r(false), CLOSE_WAIT_MS))]);
|
|
1525
|
+
if (done) return { action, closed: tabId };
|
|
1526
|
+
removing.catch(() => {});
|
|
1527
|
+
throw new Error(`Tab ${tabId} did not close within ${CLOSE_WAIT_MS / 1000} s: the page is not answering, either a "Leave site?" dialog is open (beforeunload) or the page is stuck in a loop. The close is still pending and completes if the page lets go. Look at the tab: answer the dialog, or close it by hand.`);
|
|
1518
1528
|
}
|
|
1519
1529
|
if (action === 'discard') {
|
|
1520
1530
|
// La scheda resta nella barra e si ricarica al focus: il processo muore, la
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-bridge-mcp",
|
|
3
3
|
"mcpName": "io.github.frsorrentino/chrome-bridge",
|
|
4
|
-
"version": "1.30.
|
|
4
|
+
"version": "1.30.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Chrome Bridge by frsorrentino: MCP server that lets Claude Code borrow a tab from your own logged-in Chrome and hand it back — logins, 2FA and CAPTCHAs stay with you (handoff). 67 tools; 2.8-4.3× cheaper and up to 9.3× fewer turns than Claude in Chrome, measured; ChromeOS included.",
|
|
7
7
|
"main": "server/index.js",
|
package/server/lighthouse.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* chrome-bridge gira da Node 18: sotto si usa la 12.8.2 (Node >= 18.16).
|
|
10
10
|
*/
|
|
11
11
|
import { spawn } from 'node:child_process';
|
|
12
|
+
import { existsSync } from 'node:fs';
|
|
13
|
+
import { win32 } from 'node:path';
|
|
12
14
|
|
|
13
15
|
export function lighthouseVersion(node = process.versions.node) {
|
|
14
16
|
const [maj, min] = node.split('.').map(Number);
|
|
@@ -21,9 +23,24 @@ export function lighthouseArgs(url, port, outBase, { categories, formFactor = 'm
|
|
|
21
23
|
'--quiet', ...(categories?.length ? [`--only-categories=${categories.join(',')}`] : []), ...(formFactor === 'desktop' ? ['--preset=desktop'] : [])];
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Come lanciare npx. Su Windows npx è npx.cmd, che spawn senza shell non trova
|
|
28
|
+
* (ENOENT): si usa npx-cli.js accanto a node.exe con il node del server, senza
|
|
29
|
+
* shell. Se manca, npx.cmd con la shell e gli argomenti fra virgolette.
|
|
30
|
+
*/
|
|
31
|
+
export function npxCommand({ platform = process.platform, execPath = process.execPath, env = process.env, exists = existsSync } = {}) {
|
|
32
|
+
if (env.CHROME_BRIDGE_NPX) return { cmd: env.CHROME_BRIDGE_NPX, pre: [], shell: false };
|
|
33
|
+
if (platform !== 'win32') return { cmd: 'npx', pre: [], shell: false };
|
|
34
|
+
const cli = win32.join(win32.dirname(execPath), 'node_modules', 'npm', 'bin', 'npx-cli.js');
|
|
35
|
+
if (exists(cli)) return { cmd: execPath, pre: [cli], shell: false };
|
|
36
|
+
return { cmd: 'npx.cmd', pre: [], shell: true };
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
export function runLighthouse(args, { timeoutMs = 240000 } = {}) {
|
|
25
40
|
return new Promise((resolve, reject) => {
|
|
26
|
-
const
|
|
41
|
+
const { cmd, pre, shell } = npxCommand();
|
|
42
|
+
const argv = [...pre, ...args].map((a) => (shell ? `"${a}"` : a));
|
|
43
|
+
const p = spawn(cmd, argv, { stdio: ['ignore', 'ignore', 'pipe'], shell });
|
|
27
44
|
let err = '';
|
|
28
45
|
const timer = setTimeout(() => { p.kill('SIGKILL'); reject(new Error(`Lighthouse did not finish within ${timeoutMs / 1000} s`)); }, timeoutMs);
|
|
29
46
|
p.stderr.on('data', (d) => { err += d; });
|