chrome-bridge-mcp 1.31.1 → 1.31.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.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "chrome-bridge-mcp",
3
- "version": "1.31.1",
3
+ "version": "1.31.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "chrome-bridge-mcp",
9
- "version": "1.31.1",
9
+ "version": "1.31.2",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@jridgewell/trace-mapping": "^0.3.31",
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.31.1",
4
+ "version": "1.31.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). 69 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/index.js CHANGED
@@ -44,6 +44,9 @@ function parseSecurity() {
44
44
  };
45
45
  }
46
46
 
47
+ const SHUTDOWN_DEADLINE_MS = 10000;
48
+ const PARENT_CHECK_MS = 1000;
49
+
47
50
  function parseCaps() {
48
51
  const i = process.argv.indexOf('--caps');
49
52
  if (i !== -1 && process.argv[i + 1]) return process.argv[i + 1];
@@ -78,6 +81,9 @@ async function main() {
78
81
  // segnale arrivano insieme.
79
82
  let closing = null;
80
83
  const shutdown = () => (closing ??= (async () => {
84
+ // Uno shutdown bloccato non deve tenere vivo il processo: dopo la
85
+ // scadenza, o al secondo segnale, si esce comunque.
86
+ setTimeout(forceExit, SHUTDOWN_DEADLINE_MS);
81
87
  console.error('[chrome-bridge] Shutting down...');
82
88
  // Il browser di --launch per primo: su Windows Claude Code chiude stdin e
83
89
  // dopo 300 ms uccide l'albero dei processi (2.1.296). Le sue schede
@@ -91,14 +97,38 @@ async function main() {
91
97
  try { await mcpServer.close(); } catch {}
92
98
  process.exit(0);
93
99
  })());
94
- process.on('SIGINT', shutdown);
95
- process.on('SIGTERM', shutdown);
100
+ const forceExit = () => {
101
+ if (browser) { try { process.kill(browser.pid, 'SIGKILL'); } catch {} }
102
+ process.exit(1);
103
+ };
104
+ const onSignal = () => (closing ? forceExit() : shutdown());
105
+ process.on('SIGINT', onSignal);
106
+ process.on('SIGTERM', onSignal);
107
+ // Client sparito: stdout e stderr restano pipe senza lettore e ogni
108
+ // scrittura dà EPIPE. Senza questi ascoltatori l'errore arrivava a
109
+ // uncaughtException, che riscriveva su stderr: un ciclo di errori che non
110
+ // lasciava girare l'event loop, neanche per SIGTERM (28/10/2026: un server
111
+ // --launch orfano da 2 h al 46% di CPU, chiuso solo con SIGKILL).
112
+ process.stdout.on('error', shutdown);
113
+ process.stderr.on('error', shutdown);
96
114
  // Su Windows SIGINT e SIGTERM non arrivano, e un client terminato di colpo
97
115
  // non manda segnali: in entrambi i casi resta solo la fine di stdin. L'SDK
98
116
  // non la ascolta, e il WebSocket teneva vivo il processo.
99
117
  process.stdin.once('end', shutdown);
100
118
  process.stdin.once('close', shutdown);
101
119
  mcpServer.server.onclose = shutdown;
120
+ // Prima di mcpServer.connect() nessuno legge stdin e la sua fine non
121
+ // arriva; un client che muore durante l'avvio a freddo di Chrome lascia un
122
+ // orfano adottato da init (o da systemd, su Crostini). Il cambio di padre
123
+ // lo rivela anche quando stdin resta aperto in un altro processo.
124
+ if (LAUNCH) {
125
+ const parent = process.ppid;
126
+ const parentGone = () => {
127
+ if (process.ppid !== parent) return true;
128
+ try { process.kill(parent, 0); return false; } catch (e) { return e.code !== 'EPERM'; }
129
+ };
130
+ setInterval(() => { if (parentGone()) shutdown(); }, PARENT_CHECK_MS).unref();
131
+ }
102
132
  process.on('uncaughtException', (err) => {
103
133
  console.error('[chrome-bridge] Uncaught exception:', err);
104
134
  shutdown().catch(() => process.exit(1));
@@ -105,7 +105,7 @@ export const MessageType = Object.freeze({
105
105
  });
106
106
 
107
107
  // Versione
108
- export const VERSION = '1.31.1';
108
+ export const VERSION = '1.31.2';
109
109
 
110
110
  // Configurazione
111
111
  export const DEFAULT_PORT = 8765;