cdp-tunnel 1.3.1 → 1.5.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/cli/index.js CHANGED
@@ -595,6 +595,109 @@ program
595
595
  }
596
596
  });
597
597
 
598
+ program
599
+ .command('diagnose')
600
+ .description('诊断 CDP Tunnel 连接问题')
601
+ .option('-p, --port <port>', '指定端口', parseInt)
602
+ .action(async (options) => {
603
+ const config = getConfig();
604
+ const port = options.port || config.port || 9221;
605
+ const http = require('http');
606
+
607
+ console.log('');
608
+ log('bold', '🔍 CDP Tunnel 诊断');
609
+ console.log('');
610
+
611
+ const running = isServerRunning();
612
+ log(running ? 'green' : 'red', ` 1. Proxy Server: ${running ? '运行中' : '❌ 未运行'}`);
613
+ if (!running) {
614
+ log('yellow', ' → 运行 cdp-tunnel start 启动服务器');
615
+ }
616
+
617
+ let httpOk = false;
618
+ try {
619
+ const result = await new Promise((resolve, reject) => {
620
+ http.get(`http://localhost:${port}/json/version`, res => {
621
+ let data = '';
622
+ res.on('data', chunk => data += chunk);
623
+ res.on('end', () => resolve(JSON.parse(data)));
624
+ }).on('error', reject);
625
+ });
626
+ httpOk = true;
627
+ log('green', ` 2. HTTP 端点: 正常 (Browser: ${result.Browser || 'unknown'})`);
628
+ } catch (err) {
629
+ log('red', ` 2. HTTP 端点: ❌ ${err.message}`);
630
+ }
631
+
632
+ const extStatus = checkChromeExtension();
633
+ log(extStatus.connected ? 'green' : 'red', ` 3. Chrome 扩展: ${extStatus.connected ? '已连接' : '❌ 未连接'}`);
634
+ if (!extStatus.connected) {
635
+ log('yellow', ' → 点击浏览器工具栏上的 CDP Bridge 图标');
636
+ log('yellow', ' → 或运行 cdp-tunnel extension 安装扩展');
637
+ }
638
+
639
+ if (httpOk) {
640
+ try {
641
+ const targets = await new Promise((resolve, reject) => {
642
+ http.get(`http://localhost:${port}/json/list`, res => {
643
+ let data = '';
644
+ res.on('data', chunk => data += chunk);
645
+ res.on('end', () => resolve(JSON.parse(data)));
646
+ }).on('error', reject);
647
+ });
648
+ log('green', ` 4. 可用 Targets: ${targets.length} 个`);
649
+ targets.forEach((t, i) => {
650
+ log('gray', ` ${i + 1}. ${t.title || t.url || 'unknown'} (${t.type})`);
651
+ });
652
+ } catch (err) {
653
+ log('red', ` 4. Targets: ❌ ${err.message}`);
654
+ }
655
+ }
656
+
657
+ const { isChromeRunning, findChromePath } = require('./chrome-manager');
658
+ const chromeRunning = isChromeRunning();
659
+ log(chromeRunning ? 'green' : 'yellow', ` 5. Chrome 进程: ${chromeRunning ? '运行中' : '未运行'}`);
660
+
661
+ if (chromeRunning) {
662
+ const chromePath = findChromePath();
663
+ if (chromePath) {
664
+ log('gray', ` 路径: ${chromePath}`);
665
+ }
666
+ }
667
+
668
+ if (httpOk && extStatus.connected) {
669
+ log('cyan', ' 6. Playwright 连接测试...');
670
+ try {
671
+ const { chromium } = require('playwright');
672
+ const browser = await chromium.connectOverCDP(`http://localhost:${port}`, {
673
+ timeout: 10000
674
+ });
675
+ const contexts = browser.contexts();
676
+ log('green', ` ✅ 连接成功! ${contexts.length} 个上下文, 共 ${contexts.reduce((sum, ctx) => sum + ctx.pages().length, 0)} 个页面`);
677
+ await browser.close();
678
+ } catch (err) {
679
+ if (err.code === 'MODULE_NOT_FOUND') {
680
+ log('gray', ' ⏭ 跳过 (playwright 未安装)');
681
+ } else {
682
+ log('red', ` ❌ ${err.message}`);
683
+ log('yellow', ' → 检查 Chrome 是否有多个实例在运行');
684
+ log('yellow', ' → 尝试关闭所有 Chrome 后重新运行 cdp-tunnel start');
685
+ }
686
+ }
687
+ }
688
+
689
+ console.log('');
690
+ if (running && httpOk && extStatus.connected) {
691
+ log('green', '✅ 一切正常! 连接 ws://localhost:' + port + '/devtools/browser/...');
692
+ log('cyan', ' Playwright: chromium.connectOverCDP("http://localhost:' + port + '")');
693
+ } else {
694
+ log('yellow', '⚠️ 有问题需要修复,请根据上面的提示操作');
695
+ }
696
+ console.log('');
697
+
698
+ process.exit(0);
699
+ });
700
+
598
701
  program.addHelpText('after', `
599
702
 
600
703
  常用命令:
@@ -603,6 +706,7 @@ program.addHelpText('after', `
603
706
  $ cdp-tunnel start --watchdog 服务崩溃时自动重启
604
707
  $ cdp-tunnel status 查看状态
605
708
  $ cdp-tunnel update 检查并更新
709
+ $ cdp-tunnel diagnose 诊断连接问题
606
710
  $ cdp-tunnel extension 安装 Chrome 扩展
607
711
 
608
712
  快速开始:
@@ -21,7 +21,7 @@ var SpecialHandler = (function() {
21
21
  });
22
22
 
23
23
  if (params && params.autoAttach) {
24
- return emitAutoAttachForExistingTargets().then(function() {
24
+ return emitAutoAttachForExistingTargets(context).then(function() {
25
25
  return {};
26
26
  });
27
27
  }
@@ -354,9 +354,11 @@ function checkTabVisibility(tabId) {
354
354
  });
355
355
  }
356
356
 
357
- function emitAutoAttachForExistingTargets() {
357
+ function emitAutoAttachForExistingTargets(context) {
358
+ var clientId = context ? context.clientId : null;
359
+ var config = State.getAutoAttachConfig();
360
+
358
361
  return chrome.debugger.getTargets().then(function(targets) {
359
- var config = State.getAutoAttachConfig();
360
362
  var promises = [];
361
363
 
362
364
  Logger.info('[CDP] emitAutoAttachForExistingTargets: checking', targets.length, 'targets');
@@ -389,13 +391,14 @@ function checkTabVisibility(tabId) {
389
391
  EventBuilder.send('Target.targetCreated', { targetInfo: targetInfo });
390
392
 
391
393
  if (target.attached && isAttachedByUs) {
392
- var promise = Promise.resolve();
393
-
394
- promises.push(promise.then(function() {
394
+ promises.push(Promise.resolve().then(function() {
395
395
  var sessionId = CDPUtils.generateSessionId();
396
396
  State.mapSession(sessionId, target.tabId, targetId);
397
397
 
398
- addTabToAutomationGroup(target.tabId);
398
+ if (clientId) {
399
+ State.setTabIdToClientId(target.tabId, clientId);
400
+ }
401
+ addTabToAutomationGroup(target.tabId, clientId);
399
402
 
400
403
  if (config.waitForDebuggerOnStart) {
401
404
  State.addPendingDebuggerTab(target.tabId);
@@ -404,9 +407,32 @@ function checkTabVisibility(tabId) {
404
407
  EventBuilder.send('Target.attachedToTarget', {
405
408
  sessionId: sessionId,
406
409
  targetInfo: Object.assign({}, targetInfo, { attached: true }),
407
- waitingForDebugger: config.waitForDebuggerOnStart
410
+ waitingForDebugger: config.waitForDebuggerOnStart || false
408
411
  });
409
412
  }));
413
+ } else if (!target.attached) {
414
+ promises.push(
415
+ DebuggerManager.attach(target.tabId).then(function(attached) {
416
+ if (!attached) return;
417
+ var sessionId = CDPUtils.generateSessionId();
418
+ State.mapSession(sessionId, target.tabId, targetId);
419
+
420
+ if (clientId) {
421
+ State.setTabIdToClientId(target.tabId, clientId);
422
+ }
423
+ addTabToAutomationGroup(target.tabId, clientId);
424
+
425
+ if (config.waitForDebuggerOnStart) {
426
+ State.addPendingDebuggerTab(target.tabId);
427
+ }
428
+
429
+ EventBuilder.send('Target.attachedToTarget', {
430
+ sessionId: sessionId,
431
+ targetInfo: Object.assign({}, targetInfo, { attached: true }),
432
+ waitingForDebugger: config.waitForDebuggerOnStart || false
433
+ });
434
+ })
435
+ );
410
436
  }
411
437
  });
412
438
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-tunnel",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "Chrome Extension CDP Proxy - 通过 Chrome 扩展将 chrome.debugger API 暴露为 WebSocket 端点",
5
5
  "main": "server/proxy-server.js",
6
6
  "bin": "./cli/index.js",