browser-ipc-cdp 1.1.0 → 1.3.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/bin/cli.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * npx browser-ipc-cdp --status # Ver estado actual
13
13
  * npx browser-ipc-cdp --uninstall # Desinstalar
14
14
  */
15
- const { detectBrowsers, findBrowser, launchBrowser, detectExistingCDP } = require('../lib/browser');
15
+ const { detectBrowsers, findBrowser, launchBrowser, detectExistingCDP, IS_WSL, IS_WIN, IS_MAC } = require('../lib/browser');
16
16
  const { setupPortproxy, setupFirewall } = require('../lib/network');
17
17
  const { updateMcpJson, getWslHostIp } = require('../lib/mcp');
18
18
  const { saveCdpInfo, loadCdpInfo } = require('../lib/config');
@@ -30,6 +30,8 @@ for (let i = 0; i < args.length; i++) {
30
30
 
31
31
  async function main() {
32
32
  banner();
33
+ const platform = IS_WIN ? 'Windows' : IS_WSL ? 'WSL (Windows host)' : IS_MAC ? 'macOS' : 'Linux';
34
+ log(`Plataforma: ${platform}`);
33
35
 
34
36
  // --list: listar navegadores
35
37
  if (flags.list) {
package/lib/browser.js CHANGED
@@ -6,10 +6,47 @@ const { log, success, warn } = require('./logger');
6
6
 
7
7
  const IS_WIN = process.platform === 'win32';
8
8
  const IS_MAC = process.platform === 'darwin';
9
+
10
+ // Detectar WSL: Linux pero con acceso a Windows
11
+ function isWSL() {
12
+ if (IS_WIN || IS_MAC) return false;
13
+ try {
14
+ const version = fs.readFileSync('/proc/version', 'utf-8').toLowerCase();
15
+ if (version.includes('microsoft') || version.includes('wsl')) return true;
16
+ } catch (e) {}
17
+ try {
18
+ return fs.existsSync('/proc/sys/fs/binfmt_misc/WSLInterop');
19
+ } catch (e) {}
20
+ return false;
21
+ }
22
+
23
+ const IS_WSL = isWSL();
9
24
  const HOME = process.env.HOME || process.env.USERPROFILE || '';
10
- const LOCALAPPDATA = process.env.LOCALAPPDATA || '';
11
- const PROGRAMFILES = process.env.PROGRAMFILES || 'C:\\Program Files';
12
- const PROGRAMFILES86 = process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)';
25
+
26
+ // En WSL: obtener paths de Windows via /mnt/c/
27
+ function getWindowsEnv(varName) {
28
+ if (IS_WIN) return process.env[varName] || '';
29
+ if (IS_WSL) {
30
+ try {
31
+ const result = execSync(`cmd.exe /c echo %${varName}%`, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
32
+ const winPath = result.trim();
33
+ if (winPath && !winPath.includes('%')) {
34
+ // Convertir C:\Users\... a /mnt/c/Users/...
35
+ return winPath.replace(/\\/g, '/').replace(/^([A-Za-z]):/, (_, d) => `/mnt/${d.toLowerCase()}`);
36
+ }
37
+ } catch (e) {}
38
+ }
39
+ return '';
40
+ }
41
+
42
+ const LOCALAPPDATA = IS_WIN ? (process.env.LOCALAPPDATA || '') : getWindowsEnv('LOCALAPPDATA');
43
+ const USERPROFILE = IS_WIN ? (process.env.USERPROFILE || '') : getWindowsEnv('USERPROFILE');
44
+
45
+ // Program Files: en WSL usar /mnt/c/
46
+ const PROGRAMFILES = IS_WIN ? (process.env.PROGRAMFILES || 'C:\\Program Files')
47
+ : IS_WSL ? '/mnt/c/Program Files' : '';
48
+ const PROGRAMFILES86 = IS_WIN ? (process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)')
49
+ : IS_WSL ? '/mnt/c/Program Files (x86)' : '';
13
50
 
14
51
  // Rutas dinámicas por plataforma
15
52
  const BROWSER_REGISTRY = {
@@ -19,6 +56,11 @@ const BROWSER_REGISTRY = {
19
56
  path.join(PROGRAMFILES86, 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
20
57
  path.join(LOCALAPPDATA, 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
21
58
  ],
59
+ wsl: [
60
+ path.join(PROGRAMFILES, 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
61
+ path.join(PROGRAMFILES86, 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe'),
62
+ ...(LOCALAPPDATA ? [path.join(LOCALAPPDATA, 'BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe')] : []),
63
+ ],
22
64
  mac: [
23
65
  '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser',
24
66
  path.join(HOME, 'Applications', 'Brave Browser.app', 'Contents', 'MacOS', 'Brave Browser'),
@@ -31,10 +73,11 @@ const BROWSER_REGISTRY = {
31
73
  ],
32
74
  userData: {
33
75
  win: path.join(LOCALAPPDATA, 'BraveSoftware', 'Brave-Browser', 'User Data'),
76
+ wsl: LOCALAPPDATA ? path.join(LOCALAPPDATA, 'BraveSoftware', 'Brave-Browser', 'User Data') : '',
34
77
  mac: path.join(HOME, 'Library', 'Application Support', 'BraveSoftware', 'Brave-Browser'),
35
78
  linux: path.join(HOME, '.config', 'BraveSoftware', 'Brave-Browser'),
36
79
  },
37
- processName: { win: 'brave.exe', mac: 'Brave Browser', linux: 'brave' },
80
+ processName: { win: 'brave.exe', wsl: 'brave.exe', mac: 'Brave Browser', linux: 'brave' },
38
81
  },
39
82
  chrome: {
40
83
  win: [
@@ -42,6 +85,11 @@ const BROWSER_REGISTRY = {
42
85
  path.join(PROGRAMFILES86, 'Google', 'Chrome', 'Application', 'chrome.exe'),
43
86
  path.join(LOCALAPPDATA, 'Google', 'Chrome', 'Application', 'chrome.exe'),
44
87
  ],
88
+ wsl: [
89
+ path.join(PROGRAMFILES, 'Google', 'Chrome', 'Application', 'chrome.exe'),
90
+ path.join(PROGRAMFILES86, 'Google', 'Chrome', 'Application', 'chrome.exe'),
91
+ ...(LOCALAPPDATA ? [path.join(LOCALAPPDATA, 'Google', 'Chrome', 'Application', 'chrome.exe')] : []),
92
+ ],
45
93
  mac: [
46
94
  '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
47
95
  path.join(HOME, 'Applications', 'Google Chrome.app', 'Contents', 'MacOS', 'Google Chrome'),
@@ -55,16 +103,21 @@ const BROWSER_REGISTRY = {
55
103
  ],
56
104
  userData: {
57
105
  win: path.join(LOCALAPPDATA, 'Google', 'Chrome', 'User Data'),
106
+ wsl: LOCALAPPDATA ? path.join(LOCALAPPDATA, 'Google', 'Chrome', 'User Data') : '',
58
107
  mac: path.join(HOME, 'Library', 'Application Support', 'Google', 'Chrome'),
59
108
  linux: path.join(HOME, '.config', 'google-chrome'),
60
109
  },
61
- processName: { win: 'chrome.exe', mac: 'Google Chrome', linux: 'chrome' },
110
+ processName: { win: 'chrome.exe', wsl: 'chrome.exe', mac: 'Google Chrome', linux: 'chrome' },
62
111
  },
63
112
  edge: {
64
113
  win: [
65
114
  path.join(PROGRAMFILES86, 'Microsoft', 'Edge', 'Application', 'msedge.exe'),
66
115
  path.join(PROGRAMFILES, 'Microsoft', 'Edge', 'Application', 'msedge.exe'),
67
116
  ],
117
+ wsl: [
118
+ path.join(PROGRAMFILES86, 'Microsoft', 'Edge', 'Application', 'msedge.exe'),
119
+ path.join(PROGRAMFILES, 'Microsoft', 'Edge', 'Application', 'msedge.exe'),
120
+ ],
68
121
  mac: [
69
122
  '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
70
123
  ],
@@ -74,15 +127,19 @@ const BROWSER_REGISTRY = {
74
127
  ],
75
128
  userData: {
76
129
  win: path.join(LOCALAPPDATA, 'Microsoft', 'Edge', 'User Data'),
130
+ wsl: LOCALAPPDATA ? path.join(LOCALAPPDATA, 'Microsoft', 'Edge', 'User Data') : '',
77
131
  mac: path.join(HOME, 'Library', 'Application Support', 'Microsoft Edge'),
78
132
  linux: path.join(HOME, '.config', 'microsoft-edge'),
79
133
  },
80
- processName: { win: 'msedge.exe', mac: 'Microsoft Edge', linux: 'msedge' },
134
+ processName: { win: 'msedge.exe', wsl: 'msedge.exe', mac: 'Microsoft Edge', linux: 'msedge' },
81
135
  },
82
136
  chromium: {
83
137
  win: [
84
138
  path.join(LOCALAPPDATA, 'Chromium', 'Application', 'chrome.exe'),
85
139
  ],
140
+ wsl: [
141
+ ...(LOCALAPPDATA ? [path.join(LOCALAPPDATA, 'Chromium', 'Application', 'chrome.exe')] : []),
142
+ ],
86
143
  mac: [
87
144
  '/Applications/Chromium.app/Contents/MacOS/Chromium',
88
145
  ],
@@ -93,15 +150,17 @@ const BROWSER_REGISTRY = {
93
150
  ],
94
151
  userData: {
95
152
  win: path.join(LOCALAPPDATA, 'Chromium', 'User Data'),
153
+ wsl: LOCALAPPDATA ? path.join(LOCALAPPDATA, 'Chromium', 'User Data') : '',
96
154
  mac: path.join(HOME, 'Library', 'Application Support', 'Chromium'),
97
155
  linux: path.join(HOME, '.config', 'chromium'),
98
156
  },
99
- processName: { win: 'chrome.exe', mac: 'Chromium', linux: 'chromium' },
157
+ processName: { win: 'chrome.exe', wsl: 'chrome.exe', mac: 'Chromium', linux: 'chromium' },
100
158
  },
101
159
  };
102
160
 
103
161
  function getPlatform() {
104
162
  if (IS_WIN) return 'win';
163
+ if (IS_WSL) return 'wsl';
105
164
  if (IS_MAC) return 'mac';
106
165
  return 'linux';
107
166
  }
@@ -188,11 +247,12 @@ function testCdp(port, timeout = 3000) {
188
247
  function isBrowserRunning(exe) {
189
248
  const exeName = path.basename(exe);
190
249
  try {
191
- if (IS_WIN) {
192
- const result = execSync(
193
- `tasklist /FI "IMAGENAME eq ${exeName}" /FO CSV /NH`,
194
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' }
195
- );
250
+ if (IS_WIN || IS_WSL) {
251
+ // Windows y WSL: usar tasklist de Windows
252
+ const cmd = IS_WSL
253
+ ? `cmd.exe /c tasklist /FI "IMAGENAME eq ${exeName}" /FO CSV /NH`
254
+ : `tasklist /FI "IMAGENAME eq ${exeName}" /FO CSV /NH`;
255
+ const result = execSync(cmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
196
256
  return result.toLowerCase().includes(exeName.toLowerCase());
197
257
  } else {
198
258
  const result = execSync(`pgrep -f "${exeName}"`, { timeout: 5000, stdio: 'pipe' });
@@ -225,11 +285,11 @@ async function detectExistingCDP(browser) {
225
285
  try {
226
286
  const exeName = path.basename(browser.exe);
227
287
  let cmdOutput = '';
228
- if (IS_WIN) {
229
- cmdOutput = execSync(
230
- `wmic process where "name='${exeName}'" get commandline /format:list`,
231
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' }
232
- );
288
+ if (IS_WIN || IS_WSL) {
289
+ const wmicCmd = `wmic process where "name='${exeName}'" get commandline /format:list`;
290
+ cmdOutput = IS_WSL
291
+ ? execSync(`cmd.exe /c ${wmicCmd}`, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' })
292
+ : execSync(wmicCmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
233
293
  } else {
234
294
  cmdOutput = execSync(
235
295
  `ps aux | grep "${exeName}" | grep -v grep`,
@@ -251,11 +311,11 @@ async function detectExistingCDP(browser) {
251
311
  const exeName = path.basename(browser.exe);
252
312
  const pids = new Set();
253
313
 
254
- if (IS_WIN) {
255
- const taskResult = execSync(
256
- `tasklist /FI "IMAGENAME eq ${exeName}" /FO CSV /NH`,
257
- { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' }
258
- );
314
+ if (IS_WIN || IS_WSL) {
315
+ const taskCmd = `tasklist /FI "IMAGENAME eq ${exeName}" /FO CSV /NH`;
316
+ const taskResult = IS_WSL
317
+ ? execSync(`cmd.exe /c ${taskCmd}`, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' })
318
+ : execSync(taskCmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
259
319
  taskResult.split('\n').forEach(line => {
260
320
  const parts = line.trim().replace(/"/g, '').split(',');
261
321
  if (parts.length >= 2) {
@@ -273,8 +333,11 @@ async function detectExistingCDP(browser) {
273
333
  }
274
334
 
275
335
  if (pids.size > 0) {
276
- if (IS_WIN) {
277
- const netstat = execSync('netstat -ano -p tcp', { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
336
+ if (IS_WIN || IS_WSL) {
337
+ const netstatCmd = 'netstat -ano -p tcp';
338
+ const netstat = IS_WSL
339
+ ? execSync(`cmd.exe /c ${netstatCmd}`, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' })
340
+ : execSync(netstatCmd, { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
278
341
  for (const line of netstat.split('\n')) {
279
342
  const tokens = line.trim().split(/\s+/);
280
343
  if (tokens.length >= 5 && tokens[3] === 'LISTENING') {
@@ -319,6 +382,8 @@ function killBrowser(exe) {
319
382
  try {
320
383
  if (IS_WIN) {
321
384
  execSync(`taskkill /F /IM ${exeName}`, { timeout: 10000, stdio: 'pipe' });
385
+ } else if (IS_WSL) {
386
+ execSync(`cmd.exe /c taskkill /F /IM ${exeName}`, { timeout: 10000, stdio: 'pipe' });
322
387
  } else {
323
388
  execSync(`pkill -f "${exeName}"`, { timeout: 10000, stdio: 'pipe' });
324
389
  }
@@ -347,13 +412,21 @@ function launchBrowser(browser, { port = 0, clean = false } = {}) {
347
412
  if (clean) args.push(`--user-data-dir=${userData}`);
348
413
 
349
414
  const spawnOpts = { detached: true, stdio: 'ignore' };
350
- // En Mac, si el exe es un .app, necesita 'open' como wrapper
351
- let cmd = browser.exe;
352
- let spawnArgs = args;
353
- if (IS_MAC && browser.exe.includes('.app/')) {
354
- // Ejecutar directo el binario dentro del .app
415
+ let child;
416
+
417
+ if (IS_WSL) {
418
+ // WSL: convertir ruta /mnt/c/... a C:\... y lanzar via cmd.exe
419
+ const winExe = browser.exe.replace(/^\/mnt\/([a-z])\//, (_, d) => `${d.toUpperCase()}:\\`).replace(/\//g, '\\');
420
+ const winArgs = args.map(a => {
421
+ if (a.startsWith('--user-data-dir=/mnt/')) {
422
+ return a.replace(/^--user-data-dir=\/mnt\/([a-z])\//, (_, d) => `--user-data-dir=${d.toUpperCase()}:\\`).replace(/\//g, '\\');
423
+ }
424
+ return a;
425
+ });
426
+ child = spawn('cmd.exe', ['/c', 'start', '', winExe, ...winArgs], spawnOpts);
427
+ } else {
428
+ child = spawn(browser.exe, args, spawnOpts);
355
429
  }
356
- const child = spawn(cmd, spawnArgs, spawnOpts);
357
430
  child.unref();
358
431
 
359
432
  log(` PID: ${child.pid}`);
@@ -395,4 +468,4 @@ function launchBrowser(browser, { port = 0, clean = false } = {}) {
395
468
  });
396
469
  }
397
470
 
398
- module.exports = { detectBrowsers, findBrowser, detectExistingCDP, launchBrowser, testCdp };
471
+ module.exports = { detectBrowsers, findBrowser, detectExistingCDP, launchBrowser, testCdp, IS_WSL, IS_WIN, IS_MAC };
package/lib/network.js CHANGED
@@ -2,17 +2,61 @@ const { execSync } = require('child_process');
2
2
  const { log, success, warn } = require('./logger');
3
3
 
4
4
  const IS_WIN = process.platform === 'win32';
5
+ 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
+ }
13
+
14
+ const NEEDS_NETSH = IS_WIN; // WSL no necesita netsh, usa host IP directo
5
15
  const FIREWALL_RULE = 'CDP All Ports (IPC)';
6
16
 
7
17
  function setupFirewall() {
8
- // Solo necesario en Windows (WSL requiere reglas de firewall)
9
- // Mac/Linux no necesitan firewall para localhost
10
- if (!IS_WIN) {
11
- log(' Firewall: no necesario en esta plataforma');
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
+ }
12
56
  return true;
13
57
  }
14
58
 
15
- // Verificar si ya existe
59
+ // Windows nativo
16
60
  try {
17
61
  const check = execSync(
18
62
  `netsh advfirewall firewall show rule name="${FIREWALL_RULE}"`,
@@ -21,7 +65,6 @@ function setupFirewall() {
21
65
  if (check.includes(FIREWALL_RULE)) return true;
22
66
  } catch (e) {}
23
67
 
24
- // Crear regla universal
25
68
  try {
26
69
  execSync(
27
70
  `netsh advfirewall firewall add rule name="${FIREWALL_RULE}" dir=in action=allow protocol=TCP localport=1024-65535`,
@@ -36,14 +79,49 @@ function setupFirewall() {
36
79
  }
37
80
 
38
81
  function setupPortproxy(port) {
39
- // Solo necesario en Windows (WSL no alcanza 127.0.0.1 de Windows)
40
- // Mac/Linux: localhost funciona directo
41
- if (!IS_WIN) {
42
- log(' Portproxy: no necesario en esta plataforma');
82
+ // Mac/Linux nativo: no necesita portproxy
83
+ if (!IS_WIN && !IS_WSL) {
43
84
  return true;
44
85
  }
45
86
 
46
- // Verificar si ya existe
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
+ }
123
+
124
+ // Windows nativo
47
125
  try {
48
126
  const check = execSync('netsh interface portproxy show all',
49
127
  { timeout: 10000, encoding: 'utf-8', stdio: 'pipe' });
@@ -53,7 +131,6 @@ function setupPortproxy(port) {
53
131
  }
54
132
  } catch (e) {}
55
133
 
56
- // Crear portproxy
57
134
  try {
58
135
  execSync(
59
136
  `netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=${port} connectaddress=127.0.0.1 connectport=${port}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-ipc-cdp",
3
- "version": "1.1.0",
3
+ "version": "1.3.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"