cdp-tunnel 2.1.2 → 2.2.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
@@ -20,6 +20,21 @@ program
20
20
  .description('Chrome DevTools Protocol Tunnel')
21
21
  .version(require(path.join(__dirname, '..', 'package.json')).version);
22
22
 
23
+ function syncExtensionVersion() {
24
+ try {
25
+ const pkgVersion = require(path.join(__dirname, '..', 'package.json')).version;
26
+ const manifestPath = path.join(__dirname, '..', 'extension-new', 'manifest.json');
27
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
28
+ if (manifest.version !== pkgVersion) {
29
+ manifest.version = pkgVersion;
30
+ manifest.description = `CDP Tunnel v${pkgVersion} — ${manifest.description.split('—')[1] || manifest.description}`.trim();
31
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
32
+ }
33
+ } catch {}
34
+ }
35
+
36
+ syncExtensionVersion();
37
+
23
38
  function log(color, ...args) {
24
39
  const colors = {
25
40
  green: '\x1b[32m',
@@ -657,7 +657,7 @@
657
657
  <nav class="navbar">
658
658
  <div class="navbar-brand">
659
659
  <div class="logo">🔌</div>
660
- <h1>CDP Bridge</h1>
660
+ <h1>CDP Bridge <small id="versionBadge" style="font-size:12px;color:#888;font-weight:normal"></small></h1>
661
661
  </div>
662
662
  <div class="status-badge disconnected" id="statusBadge">
663
663
  <div class="dot"></div>
@@ -267,6 +267,12 @@
267
267
  chrome.storage.local.set({ autoMute: e.target.checked });
268
268
  addLog(e.target.checked ? '🔇 自动静音已开启' : '🔊 自动静音已关闭', 'action');
269
269
  });
270
+
271
+ var versionBadge = document.getElementById('versionBadge');
272
+ if (versionBadge) {
273
+ var manifest = chrome.runtime.getManifest();
274
+ versionBadge.textContent = 'v' + manifest.version;
275
+ }
270
276
 
271
277
  fetchState();
272
278
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-tunnel",
3
- "version": "2.1.2",
3
+ "version": "2.2.0",
4
4
  "description": "Bridge Chrome's debugger API to WebSocket — control your existing browser with Playwright/Puppeteer via CDP",
5
5
  "main": "server/proxy-server.js",
6
6
  "bin": "./cli/index.js",
@@ -1,13 +1,17 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const os = require('os');
3
4
 
4
5
  const logDir = path.join(__dirname, '../../logs');
5
6
  if (!fs.existsSync(logDir)) {
6
7
  fs.mkdirSync(logDir, { recursive: true });
7
8
  }
8
9
 
10
+ const cdpDir = path.join(os.homedir(), '.cdp-tunnel');
11
+
9
12
  const logFile = path.join(logDir, 'cdp-debug.log');
10
13
  const statusLogFile = path.join(logDir, 'server-status.log');
14
+ const disconnectLogFile = path.join(cdpDir, 'disconnect.log');
11
15
 
12
16
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
13
17
  const MAX_LOG_FILES = 5;
@@ -117,6 +121,26 @@ function clearLog() {
117
121
  }
118
122
  }
119
123
 
124
+ function logDisconnect(event, details) {
125
+ const timestamp = new Date().toISOString();
126
+ const separator = '='.repeat(70);
127
+ const lines = [
128
+ separator,
129
+ `[${timestamp}] ${event}`,
130
+ JSON.stringify(details, null, 2),
131
+ ''
132
+ ].join('\n');
133
+ try {
134
+ const dir = path.dirname(disconnectLogFile);
135
+ if (!fs.existsSync(dir)) {
136
+ fs.mkdirSync(dir, { recursive: true });
137
+ }
138
+ fs.appendFileSync(disconnectLogFile, lines);
139
+ } catch (e) {
140
+ console.error('[LOGGER] Error writing disconnect log:', e.message);
141
+ }
142
+ }
143
+
120
144
  const NOISY_METHODS = [
121
145
  'Runtime.consoleAPICalled',
122
146
  'Network.requestWillBeSent',
@@ -249,5 +273,6 @@ module.exports = {
249
273
  logFile,
250
274
  logStatus,
251
275
  logConnectionEvent,
252
- flushAllLogs
276
+ flushAllLogs,
277
+ logDisconnect
253
278
  };
@@ -16,7 +16,7 @@ const path = require('path');
16
16
  const os = require('os');
17
17
  const { execSync, spawn: spawnProcess } = require('child_process');
18
18
  const { CONFIG, BROWSER_ID, shouldLog } = require('./modules/config');
19
- const { logCDP, logEvent, clearLog, logStatus, logConnectionEvent, flushAllLogs } = require('./modules/logger');
19
+ const { logCDP, logEvent, clearLog, logStatus, logConnectionEvent, flushAllLogs, logDisconnect } = require('./modules/logger');
20
20
 
21
21
  const PORT = CONFIG.PORT;
22
22
  const CONFIG_DIR = path.join(os.homedir(), '.cdp-tunnel');
@@ -154,11 +154,13 @@ const browserContextToClientId = new Map();
154
154
  const clientIdToBrowserContext = new Map();
155
155
  let globalRequestIdCounter = 0;
156
156
 
157
+ const { version: PKG_VERSION } = require('../package.json');
158
+
157
159
  let cachedTargets = [];
158
160
  let lastTargetsUpdate = 0;
159
161
 
160
162
  console.log('='.repeat(60));
161
- console.log(' WebSocket CDP Proxy Server');
163
+ console.log(` WebSocket CDP Proxy Server v${PKG_VERSION}`);
162
164
  console.log('='.repeat(60));
163
165
  console.log(` Server started on port ${PORT}`);
164
166
  console.log(` - Plugin path: ws://localhost:${PORT}/plugin`);
@@ -670,6 +672,16 @@ function handlePluginConnection(ws, clientInfo) {
670
672
  totalClients: clientConnections.size
671
673
  });
672
674
 
675
+ logDisconnect('PLUGIN_DISCONNECTED', {
676
+ pluginId: id,
677
+ code, reason: reason?.toString() || 'none',
678
+ remainingPlugins: pluginConnections.size,
679
+ affectedClients: affectedClients.map(c => c),
680
+ uptime: ws.connectedAt ? `${((Date.now() - ws.connectedAt) / 1000).toFixed(0)}s` : 'unknown',
681
+ activeSessions: sessionToClientId.size,
682
+ pendingRequests: pendingAttachRequests.size
683
+ });
684
+
673
685
  if (pluginConnections.size === 0) {
674
686
  updateExtensionState(false);
675
687
  }
@@ -963,6 +975,20 @@ function handleClientConnection(ws, clientInfo, customClientId = null) {
963
975
  totalPlugins: pluginConnections.size,
964
976
  totalClients: clientConnections.size
965
977
  });
978
+
979
+ const isUnexpected = code !== 1000 && code !== 1001;
980
+ if (isUnexpected) {
981
+ logDisconnect('CLIENT_DISCONNECTED_UNEXPECTED', {
982
+ clientId: id,
983
+ code, reason: reason?.toString() || 'none',
984
+ sessionsLost: sessionsToClean.length,
985
+ cdpMethodsUsed: ws.cdpTrace ? [...new Set(ws.cdpTrace)] : [],
986
+ uptime: ws.connectedAt ? `${((Date.now() - ws.connectedAt) / 1000).toFixed(0)}s` : 'unknown',
987
+ remainingClients: clientConnections.size,
988
+ pluginAlive: pluginConnections.size > 0,
989
+ pairedPluginId: ws.pairedPlugin?.id || null
990
+ });
991
+ }
966
992
 
967
993
  if (ws.cdpTrace && ws.cdpTrace.length && shouldLog('debug')) {
968
994
  const unique = [...new Set(ws.cdpTrace)];
@@ -1343,6 +1369,14 @@ const heartbeatInterval = setInterval(() => {
1343
1369
  console.log(`[${now}] Plugin ${ws.id} not responding, terminating...`);
1344
1370
  }
1345
1371
  logConnectionEvent('HEARTBEAT_TIMEOUT', { type: 'plugin', id: ws.id });
1372
+ logDisconnect('HEARTBEAT_TIMEOUT_PLUGIN', {
1373
+ pluginId: ws.id,
1374
+ pairedClientId: ws.pairedClientId || null,
1375
+ uptime: ws.connectedAt ? `${((Date.now() - ws.connectedAt) / 1000).toFixed(0)}s` : 'unknown',
1376
+ remainingPlugins: pluginConnections.size,
1377
+ activeClients: clientConnections.size,
1378
+ activeSessions: sessionToClientId.size
1379
+ });
1346
1380
  pluginConnections.delete(ws);
1347
1381
  if (ws.pairedClientId) {
1348
1382
  connectionPairs.delete(ws.pairedClientId);
@@ -1365,6 +1399,12 @@ const heartbeatInterval = setInterval(() => {
1365
1399
  console.log(`[${now}] Client ${ws.id} not responding, terminating...`);
1366
1400
  }
1367
1401
  logConnectionEvent('HEARTBEAT_TIMEOUT', { type: 'client', id: ws.id });
1402
+ logDisconnect('HEARTBEAT_TIMEOUT_CLIENT', {
1403
+ clientId: ws.id,
1404
+ uptime: ws.connectedAt ? `${((Date.now() - ws.connectedAt) / 1000).toFixed(0)}s` : 'unknown',
1405
+ remainingClients: clientConnections.size,
1406
+ pluginAlive: pluginConnections.size > 0
1407
+ });
1368
1408
  clientConnections.delete(ws);
1369
1409
  clientById.delete(ws.id);
1370
1410
  if (ws.pairedPlugin) {