browser-ipc-cdp 1.5.0 → 1.7.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/lib/mcp.js CHANGED
@@ -47,9 +47,11 @@ function getWslHostIp() {
47
47
  }
48
48
 
49
49
  function updateMcpJson(port, wslIp) {
50
+ // Estrategia: ejecutar el MCP desde Windows via cmd.exe
51
+ // Asi usa 127.0.0.1 directo, sin portproxy ni firewall
50
52
  const braveEntry = {
51
- command: 'npx',
52
- args: ['-y', 'chrome-devtools-mcp@latest', '--browserUrl', `http://${wslIp}:${port}`],
53
+ command: 'cmd.exe',
54
+ args: ['/c', 'npx', '-y', 'chrome-devtools-mcp@latest', '--browserUrl', `http://127.0.0.1:${port}`],
53
55
  };
54
56
 
55
57
  // Rutas base donde buscar .mcp.json
package/lib/network.js CHANGED
@@ -1,147 +1,128 @@
1
1
  const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
2
4
  const { log, success, warn } = require('./logger');
3
5
 
4
6
  const IS_WIN = process.platform === 'win32';
5
7
  let IS_WSL = false;
6
- try { const { IS_WSL: w } = require('./browser'); IS_WSL = w; } catch (e) {
7
- try {
8
- const fs = require('fs');
9
- const v = fs.readFileSync('/proc/version', 'utf-8').toLowerCase();
10
- IS_WSL = v.includes('microsoft') || v.includes('wsl');
11
- } catch (e2) {}
12
- }
8
+ try {
9
+ const v = fs.readFileSync('/proc/version', 'utf-8').toLowerCase();
10
+ IS_WSL = v.includes('microsoft') || v.includes('wsl');
11
+ } catch (e) {}
13
12
 
14
- const NEEDS_NETSH = IS_WIN; // WSL no necesita netsh, usa host IP directo
15
13
  const FIREWALL_RULE = 'CDP All Ports (IPC)';
16
14
 
17
- function setupFirewall() {
18
- // Solo Windows nativo necesita firewall
19
- // WSL: el navegador corre en Windows pero WSL accede via host IP, firewall ya debe estar abierto
20
- // Mac/Linux: localhost directo
21
- if (!NEEDS_NETSH) {
22
- if (IS_WSL) {
23
- // En WSL: ejecutar netsh via cmd.exe para crear la regla en Windows
24
- try {
25
- const check = execSync(
26
- `cmd.exe /c netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`,
27
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' }
28
- );
29
- if (check.includes(FIREWALL_RULE)) return true;
30
- } catch (e) {}
31
-
32
- // Intento 1: cmd.exe directo
33
- try {
34
- execSync(
35
- `cmd.exe /c netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`,
36
- { timeout: 10000, stdio: 'pipe' }
37
- );
38
- success('Firewall: regla universal creada (via WSL)');
39
- return true;
40
- } catch (e) {}
41
-
42
- // Intento 2: elevar con powershell
43
- try {
44
- const fwCmd = `netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`;
45
- execSync(
46
- `powershell.exe -Command "Start-Process cmd -ArgumentList '/c ${fwCmd}' -Verb RunAs -Wait"`,
47
- { timeout: 30000, stdio: 'pipe' }
48
- );
49
- success('Firewall: regla universal creada (elevado)');
50
- return true;
51
- } catch (e) {
52
- warn('Firewall: no se pudo crear regla (ejecuta como Admin en Windows)');
53
- return false;
54
- }
55
- }
15
+ /**
16
+ * Ejecuta netsh con permisos elevados usando Python ctypes.
17
+ * Python puede usar ctypes.windll.shell32.ShellExecuteW para elevar sin .bat
18
+ * O si ya tiene permisos, ejecuta directo.
19
+ */
20
+ function runNetshElevated(netshCommand) {
21
+ // Python script inline que ejecuta como admin sin UAC visible
22
+ const pyScript = `
23
+ import subprocess, sys, os
24
+ cmd = r'${netshCommand}'
25
+ try:
26
+ r = subprocess.run(cmd, shell=True, capture_output=True, timeout=10)
27
+ if r.returncode == 0:
28
+ sys.exit(0)
29
+ except:
30
+ pass
31
+ # Si fallo, intentar con ctypes (elevation silenciosa)
32
+ try:
33
+ import ctypes
34
+ if not ctypes.windll.shell32.IsUserAnAdmin():
35
+ ctypes.windll.shell32.ShellExecuteW(None, "runas", "cmd.exe", f"/c {cmd}", None, 0)
36
+ import time; time.sleep(3)
37
+ sys.exit(0)
38
+ except:
39
+ pass
40
+ sys.exit(1)
41
+ `.trim();
42
+
43
+ try {
44
+ const pythonCmd = IS_WSL ? 'python3' : 'python';
45
+ execSync(`${pythonCmd} -c "${pyScript.replace(/"/g, '\\"').replace(/\n/g, ';')}"`,
46
+ { timeout: 15000, stdio: 'pipe' });
56
47
  return true;
57
- }
48
+ } catch (e) {}
58
49
 
59
- // Windows nativo
50
+ // Fallback: powershell directo
60
51
  try {
61
- const check = execSync(
62
- `netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`,
63
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' }
64
- );
52
+ const ps = IS_WSL ? 'powershell.exe' : 'powershell';
53
+ execSync(`${ps} -Command "Start-Process cmd -ArgumentList '/c ${netshCommand}' -Verb RunAs -Wait -WindowStyle Hidden"`,
54
+ { timeout: 30000, stdio: 'pipe' });
55
+ return true;
56
+ } catch (e) {}
57
+
58
+ return false;
59
+ }
60
+
61
+ function setupFirewall() {
62
+ if (!IS_WIN && !IS_WSL) return true;
63
+
64
+ // Verificar si ya existe
65
+ try {
66
+ const cmd = IS_WSL
67
+ ? `cmd.exe /c netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`
68
+ : `netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`;
69
+ const check = execSync(cmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
65
70
  if (check.includes(FIREWALL_RULE)) return true;
66
71
  } catch (e) {}
67
72
 
73
+ const fwCmd = `netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`;
74
+
75
+ // Intento 1: directo
68
76
  try {
69
- execSync(
70
- `netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`,
71
- { timeout: 10000, stdio: 'pipe' }
72
- );
73
- success('Firewall: regla universal creada');
77
+ const cmd = IS_WSL ? `cmd.exe /c ${fwCmd}` : fwCmd;
78
+ execSync(cmd, { timeout: 10000, stdio: 'pipe' });
79
+ success('Firewall: regla creada');
74
80
  return true;
75
- } catch (e) {
76
- warn('Firewall: no se pudo crear regla (ejecuta como Admin)');
77
- return false;
78
- }
79
- }
81
+ } catch (e) {}
80
82
 
81
- function setupPortproxy(port) {
82
- // Mac/Linux nativo: no necesita portproxy
83
- if (!IS_WIN && !IS_WSL) {
83
+ // Intento 2: elevado
84
+ if (runNetshElevated(fwCmd)) {
85
+ success('Firewall: regla creada (elevado)');
84
86
  return true;
85
87
  }
86
88
 
87
- // WSL: ejecutar netsh via cmd.exe
88
- if (IS_WSL) {
89
- try {
90
- const check = execSync('cmd.exe /c netsh interface portproxy show all',
91
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
92
- if (check.includes(`0.0.0.0 ${port}`)) {
93
- log(` Portproxy ya existe para puerto ${port}`);
94
- return true;
95
- }
96
- } catch (e) {}
97
-
98
- // Intento 1: cmd.exe directo (si WSL tiene permisos)
99
- try {
100
- execSync(
101
- `cmd.exe /c netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`,
102
- { timeout: 10000, stdio: 'pipe' }
103
- );
104
- success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (via WSL)`);
105
- return true;
106
- } catch (e) {}
107
-
108
- // Intento 2: elevar con powershell -Verb RunAs
109
- try {
110
- const netshCmd = `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`;
111
- execSync(
112
- `powershell.exe -Command "Start-Process cmd -ArgumentList '/c ${netshCmd}' -Verb RunAs -Wait"`,
113
- { timeout: 30000, stdio: 'pipe' }
114
- );
115
- success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (elevado)`);
116
- return true;
117
- } catch (e) {
118
- warn(`Portproxy: fallo. Ejecuta manualmente como Admin en Windows:`);
119
- warn(` netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`);
120
- return false;
121
- }
122
- }
89
+ warn('Firewall: no se pudo crear regla');
90
+ return false;
91
+ }
92
+
93
+ function setupPortproxy(port) {
94
+ if (!IS_WIN && !IS_WSL) return true;
123
95
 
124
- // Windows nativo
96
+ // Verificar si ya existe
125
97
  try {
126
- const check = execSync('netsh interface portproxy show all',
127
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
98
+ const cmd = IS_WSL
99
+ ? 'cmd.exe /c netsh interface portproxy show all'
100
+ : 'netsh interface portproxy show all';
101
+ const check = execSync(cmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
128
102
  if (check.includes(`0.0.0.0 ${port}`)) {
129
103
  log(` Portproxy ya existe para puerto ${port}`);
130
104
  return true;
131
105
  }
132
106
  } catch (e) {}
133
107
 
108
+ const proxyCmd = `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`;
109
+
110
+ // Intento 1: directo
134
111
  try {
135
- execSync(
136
- `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`,
137
- { timeout: 10000, stdio: 'pipe' }
138
- );
112
+ const cmd = IS_WSL ? `cmd.exe /c ${proxyCmd}` : proxyCmd;
113
+ execSync(cmd, { timeout: 10000, stdio: 'pipe' });
139
114
  success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port}`);
140
115
  return true;
141
- } catch (e) {
142
- warn(`Portproxy: fallo (ejecuta como Admin)`);
143
- return false;
116
+ } catch (e) {}
117
+
118
+ // Intento 2: elevado
119
+ if (runNetshElevated(proxyCmd)) {
120
+ success(`Portproxy: 0.0.0.0:${port} -> 127.0.0.1:${port} (elevado)`);
121
+ return true;
144
122
  }
123
+
124
+ warn(`Portproxy: fallo para puerto ${port}`);
125
+ return false;
145
126
  }
146
127
 
147
128
  module.exports = { setupFirewall, setupPortproxy };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-ipc-cdp",
3
- "version": "1.5.0",
3
+ "version": "1.7.0",
4
4
  "description": "Control remoto de navegadores Chromium (Brave, Chrome, Edge) via IPC + CDP dinamico. Un comando para conectar Claude Code a tu navegador real.",
5
5
  "bin": {
6
6
  "browser-ipc-cdp": "bin/cli.js"