cdp-tunnel 2.7.6 → 2.7.8

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.
@@ -13,9 +13,7 @@ var LocalHandler = (function() {
13
13
  }
14
14
 
15
15
  function browserClose() {
16
- return State.cleanupAllTabs().then(function() {
17
- return {};
18
- });
16
+ return Promise.resolve({});
19
17
  }
20
18
 
21
19
  function getWindowForTarget() {
@@ -1,4 +1,6 @@
1
1
  var SpecialHandler = (function() {
2
+ var _groupQueue = new Map();
3
+
2
4
  function muteTabIfNeeded(tabId) {
3
5
  Config.getAutoMute(function(enabled) {
4
6
  if (!enabled) return;
@@ -159,6 +161,33 @@ var SpecialHandler = (function() {
159
161
  }
160
162
 
161
163
  function addTabToAutomationGroup(tabId, clientId, callback) {
164
+ var key = clientId || '__no_client__';
165
+ var prev = _groupQueue.get(key) || Promise.resolve();
166
+
167
+ var next = prev.then(function() {
168
+ return new Promise(function(resolve) {
169
+ _addTabToAutomationGroupInner(tabId, clientId, function(success) {
170
+ resolve(success);
171
+ });
172
+ });
173
+ }).catch(function(err) {
174
+ Logger.error('[addTabToAutomationGroup] queue error:', err.message || err);
175
+ });
176
+
177
+ _groupQueue.set(key, next);
178
+
179
+ next.finally(function() {
180
+ if (_groupQueue.get(key) === next) {
181
+ _groupQueue.delete(key);
182
+ }
183
+ });
184
+
185
+ if (callback) {
186
+ next.then(function(success) { callback(success); });
187
+ }
188
+ }
189
+
190
+ function _addTabToAutomationGroupInner(tabId, clientId, callback) {
162
191
  Logger.info('[TabGroup] Starting addTabToAutomationGroup for tabId:', tabId, 'clientId:', clientId);
163
192
 
164
193
  WebSocketManager.send({ type: 'tabgroup-debug', tabId: tabId, clientId: clientId, phase: 'start' });
@@ -198,6 +227,25 @@ var SpecialHandler = (function() {
198
227
  if (callback) callback(false);
199
228
  return;
200
229
  }
230
+ var cachedGroupId = State.getGroupIdForClient(clientId);
231
+ if (cachedGroupId) {
232
+ Logger.info('[TabGroup] Using cached groupId:', cachedGroupId, 'for client:', clientId);
233
+ chrome.tabs.group({ tabIds: tabId, groupId: cachedGroupId }, function(result) {
234
+ if (!chrome.runtime.lastError) {
235
+ updateTabGroupName(clientId);
236
+ Logger.info('[TabGroup] Tab', tabId, 'added to cached group:', cachedGroupId);
237
+ if (callback) callback(true);
238
+ return;
239
+ }
240
+ Logger.warn('[TabGroup] Cached groupId', cachedGroupId, 'failed:', chrome.runtime.lastError.message, '— falling back to query');
241
+ doGroupQuery(tabId, clientId, baseName, retries, callback);
242
+ });
243
+ return;
244
+ }
245
+ doGroupQuery(tabId, clientId, baseName, retries, callback);
246
+ }
247
+
248
+ function doGroupQuery(tabId, clientId, baseName, retries, callback) {
201
249
  chrome.tabGroups.query({}, function(allGroups) {
202
250
  if (chrome.runtime.lastError) {
203
251
  Logger.error('[TabGroup] tabGroups.query failed:', chrome.runtime.lastError.message);
@@ -238,7 +286,7 @@ var SpecialHandler = (function() {
238
286
  }
239
287
  Logger.info('[TabGroup] chrome.tabs.group returned groupId:', groupId);
240
288
  EventBuilder.send('CDPTunnel.debug', { source: 'doGroup', phase: 'groupCreated', tabId: tabId, groupId: groupId });
241
- if (groupId) {
289
+ if (groupId) {
242
290
  if (chrome.tabGroups) {
243
291
  chrome.tabGroups.update(groupId, {
244
292
  title: baseName,
@@ -203,8 +203,8 @@ var DebuggerManager = (function() {
203
203
  return;
204
204
  }
205
205
 
206
- var sessionId = State.findSessionByTabId(source.tabId);
207
- Logger.info('[Event] method=' + method + ' tabId=' + source.tabId + ' sessionId=' + (sessionId || 'null'));
206
+ var sessionIds = State.findSessionsByTabId(source.tabId);
207
+ Logger.info('[Event] method=' + method + ' tabId=' + source.tabId + ' sessions=' + sessionIds.length);
208
208
 
209
209
  if (method === 'Runtime.executionContextCreated' && params && params.context) {
210
210
  var context = params.context;
@@ -285,7 +285,9 @@ var DebuggerManager = (function() {
285
285
  }
286
286
  }
287
287
 
288
- EventBuilder.send(method, params, sessionId);
288
+ for (var i = 0; i < sessionIds.length; i++) {
289
+ EventBuilder.send(method, params, sessionIds[i]);
290
+ }
289
291
  }
290
292
 
291
293
  function handleDetach(source, reason) {
@@ -54,15 +54,23 @@ var State = (function() {
54
54
  }
55
55
 
56
56
  function findSessionByTabId(tabId) {
57
- var entries = _state.sessionIdToTabId.entries();
58
- var entry = entries.next();
59
- while (!entry.done) {
60
- if (entry.value[1] === tabId) {
61
- return entry.value[0];
57
+ var lastMatch = null;
58
+ _state.sessionIdToTabId.forEach(function(mappedTabId, sessionId) {
59
+ if (mappedTabId === tabId) {
60
+ lastMatch = sessionId;
62
61
  }
63
- entry = entries.next();
64
- }
65
- return null;
62
+ });
63
+ return lastMatch;
64
+ }
65
+
66
+ function findSessionsByTabId(tabId) {
67
+ var sessions = [];
68
+ _state.sessionIdToTabId.forEach(function(mappedTabId, sessionId) {
69
+ if (mappedTabId === tabId) {
70
+ sessions.push(sessionId);
71
+ }
72
+ });
73
+ return sessions;
66
74
  }
67
75
 
68
76
  function findSessionByTargetId(targetId) {
@@ -453,6 +461,7 @@ var State = (function() {
453
461
  getTabIdBySession: getTabIdBySession,
454
462
  getTargetIdBySession: getTargetIdBySession,
455
463
  findSessionByTabId: findSessionByTabId,
464
+ findSessionsByTabId: findSessionsByTabId,
456
465
  findSessionByTargetId: findSessionByTargetId,
457
466
  getTabIdByTargetId: getTabIdByTargetId,
458
467
  hasOtherSessionForTab: hasOtherSessionForTab,
@@ -488,24 +488,17 @@ var WebSocketManager = (function() {
488
488
  Logger.info('[Monitor] Tab', tabId, 'escaped! Forcing regroup for client:', clientId);
489
489
  if (groupId) {
490
490
  chrome.tabs.group({ tabIds: tabId, groupId: groupId }, function() {
491
- Logger.info('[Monitor] Re-added tab', tabId, 'to existing group:', groupId);
492
- });
493
- } else {
494
- var baseName = CDPUtils.getGroupBaseName(clientId);
495
- chrome.tabs.group({ tabIds: tabId }, function(newGroupId) {
496
- if (chrome.runtime.lastError || !newGroupId) {
497
- Logger.error('[Monitor] Failed to create group for tab', tabId, ':', chrome.runtime.lastError?.message);
498
- return;
491
+ if (chrome.runtime.lastError) {
492
+ Logger.error('[Monitor] Failed to re-add tab', tabId, 'to group', groupId, ':', chrome.runtime.lastError?.message);
493
+ State.removeGroupForClient(clientId);
494
+ SpecialHandler.addTabToAutomationGroup(tabId, clientId);
495
+ } else {
496
+ Logger.info('[Monitor] Re-added tab', tabId, 'to existing group:', groupId);
499
497
  }
500
- chrome.tabGroups.update(newGroupId, {
501
- title: baseName,
502
- color: CDPUtils.getGroupColorForClient(clientId),
503
- collapsed: true
504
- }, function() {
505
- State.setGroupIdForClient(clientId, newGroupId);
506
- Logger.info('[Monitor] Created new group', newGroupId, 'for escaped tab', tabId);
507
- });
508
498
  });
499
+ } else {
500
+ Logger.info('[Monitor] No cached groupId for client', clientId, '— delegating to addTabToAutomationGroup for tab', tabId);
501
+ SpecialHandler.addTabToAutomationGroup(tabId, clientId);
509
502
  }
510
503
  });
511
504
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "CDP Bridge",
4
- "version": "2.7.6",
4
+ "version": "2.7.8",
5
5
  "description": "Chrome DevTools Protocol Bridge for Playwright/Puppeteer automation",
6
6
  "permissions": [
7
7
  "debugger",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-tunnel",
3
- "version": "2.7.6",
3
+ "version": "2.7.8",
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",
@@ -1329,9 +1329,15 @@ function handleClientConnection(ws, clientInfo, customClientId = null, targetPlu
1329
1329
  }
1330
1330
 
1331
1331
  if (parsed && parsed.method === 'Browser.close') {
1332
- if (shouldLog('info')) {
1333
- console.log(`\n[BROWSER CLOSE] Client ${id} requested Browser.close, forwarding to plugin`);
1332
+ console.log(`[BROWSER CLOSE] Client ${id} requested Browser.close — closing client group only`);
1333
+ if (ws.pairedPlugin) {
1334
+ safeSend(ws.pairedPlugin, JSON.stringify({
1335
+ type: 'browser-close',
1336
+ clientId: id
1337
+ }), 'plugin');
1334
1338
  }
1339
+ safeSend(ws, JSON.stringify({ id: originalId, result: {} }), 'client');
1340
+ return;
1335
1341
  }
1336
1342
 
1337
1343
  if (parsed && parsed.method) {