cdp-tunnel 2.10.6 → 2.10.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.
package/cli/index.js
CHANGED
|
@@ -906,16 +906,106 @@ program.addHelpText('after', `
|
|
|
906
906
|
$ cdp-tunnel start 启动服务(自动启动 Chrome)
|
|
907
907
|
$ cdp-tunnel start --auto-restart Chrome 断连时自动重启
|
|
908
908
|
$ cdp-tunnel start --watchdog 服务崩溃时自动重启
|
|
909
|
+
$ cdp-tunnel setup 一键安装:启动服务 + 加载扩展
|
|
909
910
|
$ cdp-tunnel status 查看状态
|
|
910
911
|
$ cdp-tunnel update 检查并更新
|
|
911
912
|
$ cdp-tunnel diagnose 诊断连接问题
|
|
912
913
|
$ cdp-tunnel extension 安装 Chrome 扩展
|
|
913
914
|
|
|
914
915
|
快速开始:
|
|
915
|
-
$
|
|
916
|
-
$ cdp-tunnel start # 一行命令搞定!
|
|
916
|
+
$ npx cdp-tunnel setup # 无需全局安装,一键搞定!
|
|
917
917
|
`);
|
|
918
918
|
|
|
919
|
+
program
|
|
920
|
+
.command('setup')
|
|
921
|
+
.description('一键安装:启动服务器 + 自动加载 Chrome 扩展')
|
|
922
|
+
.option('-p, --port <port>', '指定端口', parseInt)
|
|
923
|
+
.action(async (options) => {
|
|
924
|
+
const globalConfig = getConfig();
|
|
925
|
+
const port = options.port || globalConfig.port || 9221;
|
|
926
|
+
const instanceConfig = getConfig(port);
|
|
927
|
+
instanceConfig.port = port;
|
|
928
|
+
saveConfig(instanceConfig, port);
|
|
929
|
+
|
|
930
|
+
console.log('');
|
|
931
|
+
log('bold', 'CDP Tunnel 一键安装');
|
|
932
|
+
console.log('');
|
|
933
|
+
|
|
934
|
+
if (isServerRunning(port)) {
|
|
935
|
+
log('green', ` Proxy: 已运行 (端口 ${port})`);
|
|
936
|
+
} else {
|
|
937
|
+
ensureInstanceDir(port);
|
|
938
|
+
startServer(port, false, false);
|
|
939
|
+
log('green', ` Proxy: 已启动 (端口 ${port})`);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
943
|
+
|
|
944
|
+
const extStatus = checkChromeExtension(port);
|
|
945
|
+
if (extStatus.connected) {
|
|
946
|
+
log('green', ' 扩展: 已连接');
|
|
947
|
+
console.log('');
|
|
948
|
+
log('green', ' Ready!');
|
|
949
|
+
log('cyan', ` CDP: http://localhost:${port}`);
|
|
950
|
+
process.exit(0);
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
const { isChromeRunning, launchChromeWithExtension } = require('./chrome-manager');
|
|
955
|
+
const chromeRunning = isChromeRunning();
|
|
956
|
+
|
|
957
|
+
if (!chromeRunning) {
|
|
958
|
+
log('cyan', ' Chrome: 启动中 (带扩展)...');
|
|
959
|
+
const launched = launchChromeWithExtension();
|
|
960
|
+
if (launched) {
|
|
961
|
+
const connected = await waitForPluginConnection(port, 15000);
|
|
962
|
+
if (connected) {
|
|
963
|
+
log('green', ' 扩展: 已连接');
|
|
964
|
+
} else {
|
|
965
|
+
log('yellow', ' 扩展: 请点击 Chrome 工具栏上的 CDP Bridge 图标');
|
|
966
|
+
}
|
|
967
|
+
} else {
|
|
968
|
+
log('yellow', ' Chrome: 无法自动启动');
|
|
969
|
+
log('cyan', ' 请手动安装扩展:');
|
|
970
|
+
console.log('');
|
|
971
|
+
log('gray', ' 1. 打开 chrome://extensions/');
|
|
972
|
+
log('gray', ' 2. 开启开发者模式');
|
|
973
|
+
log('gray', ` 3. 加载: ${getExtensionPath()}`);
|
|
974
|
+
const connected = await waitForPluginConnection(port, 120000);
|
|
975
|
+
if (connected) {
|
|
976
|
+
log('green', ' 扩展: 已连接');
|
|
977
|
+
} else {
|
|
978
|
+
log('yellow', ' 超时,请稍后运行: cdp-tunnel start');
|
|
979
|
+
process.exit(1);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
} else {
|
|
983
|
+
log('yellow', ' Chrome: 已运行,需要加载扩展');
|
|
984
|
+
log('cyan', ' 正在打开引导...');
|
|
985
|
+
|
|
986
|
+
const guidePath = generateGuideHtml();
|
|
987
|
+
const platform = os.platform();
|
|
988
|
+
try {
|
|
989
|
+
if (platform === 'darwin') execSync('open "' + guidePath + '"');
|
|
990
|
+
else if (platform === 'win32') execSync('start "" "' + guidePath + '"');
|
|
991
|
+
else execSync('xdg-open "' + guidePath + '"');
|
|
992
|
+
} catch {}
|
|
993
|
+
|
|
994
|
+
const connected = await waitForPluginConnection(port, 120000);
|
|
995
|
+
if (connected) {
|
|
996
|
+
log('green', ' 扩展: 已连接');
|
|
997
|
+
} else {
|
|
998
|
+
log('yellow', ' 超时,请稍后运行: cdp-tunnel start');
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
console.log('');
|
|
1004
|
+
log('green', ' Ready!');
|
|
1005
|
+
log('cyan', ` CDP: http://localhost:${port}`);
|
|
1006
|
+
process.exit(0);
|
|
1007
|
+
});
|
|
1008
|
+
|
|
919
1009
|
ensureConfigDir();
|
|
920
1010
|
migrateFromLegacy();
|
|
921
1011
|
|
|
@@ -178,6 +178,7 @@ importScripts('features/automation-badge.js');
|
|
|
178
178
|
if (state.getGroupIdForClient(clientId) === removedGroupId) {
|
|
179
179
|
Logger.info('[TabGroups] Clearing cached groupId for client:', clientId);
|
|
180
180
|
state.setGroupIdForClient(clientId, null);
|
|
181
|
+
state.setGroupCreationPromise(clientId, null);
|
|
181
182
|
|
|
182
183
|
var attached = state.getAttachedTabIds();
|
|
183
184
|
attached.forEach(function(tid) {
|
|
@@ -209,19 +210,20 @@ importScripts('features/automation-badge.js');
|
|
|
209
210
|
var clientId = state.getClientIdByTabId(tabId);
|
|
210
211
|
if (clientId) {
|
|
211
212
|
var cachedGroupId = state.getGroupIdForClient(clientId);
|
|
213
|
+
var groupPromise = state.getGroupCreationPromise(clientId);
|
|
212
214
|
if (cachedGroupId) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
Logger.info('[Tabs] Tab', tabId, 'left group, re-adding to cached group:', cachedGroupId);
|
|
216
|
+
chrome.tabs.group({ tabIds: tabId, groupId: cachedGroupId }, function() {
|
|
217
|
+
if (chrome.runtime.lastError) {
|
|
218
|
+
Logger.warn('[Tabs] Failed to re-add tab to group:', chrome.runtime.lastError.message);
|
|
219
|
+
var ctx = { _state: state, _wsManager: wsManager, clientId: clientId, mode: state.mode };
|
|
220
|
+
SpecialHandler.addTabToAutomationGroup(tabId, clientId, null, ctx);
|
|
219
221
|
}
|
|
220
222
|
});
|
|
223
|
+
} else if (!groupPromise) {
|
|
224
|
+
Logger.info('[Tabs] Tab', tabId, 'left group, no cache and no pending creation — skipping (onRemoved handles re-group)');
|
|
221
225
|
} else {
|
|
222
|
-
Logger.info('[Tabs] Tab', tabId, 'left group,
|
|
223
|
-
var ctx = { _state: state, _wsManager: wsManager, clientId: clientId, mode: state.mode };
|
|
224
|
-
SpecialHandler.addTabToAutomationGroup(tabId, clientId, null, ctx);
|
|
226
|
+
Logger.info('[Tabs] Tab', tabId, 'left group, group creation pending — skipping');
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
229
|
}
|
|
@@ -314,6 +314,7 @@ var WebSocketConnection = (function() {
|
|
|
314
314
|
if (self.state.getCDPClients().length === 0) {
|
|
315
315
|
self.state.setHasConnectedClient(false);
|
|
316
316
|
}
|
|
317
|
+
self._cleanupStaleState(discClientId);
|
|
317
318
|
self._broadcastStateUpdate();
|
|
318
319
|
});
|
|
319
320
|
break;
|
|
@@ -374,7 +375,6 @@ var WebSocketConnection = (function() {
|
|
|
374
375
|
return new Promise(function(resolve) {
|
|
375
376
|
var timeoutId = setTimeout(function() {
|
|
376
377
|
Logger.warn('[WS:' + self.connectionId + '] closeTabGroupByClientId timeout for client:', clientId, '— forcing cleanup');
|
|
377
|
-
self._cleanupStaleState(clientId);
|
|
378
378
|
resolve();
|
|
379
379
|
}, 5000);
|
|
380
380
|
|
|
@@ -596,9 +596,9 @@ var WebSocketConnection = (function() {
|
|
|
596
596
|
return;
|
|
597
597
|
}
|
|
598
598
|
self._groupCreationPending.delete(clientId);
|
|
599
|
-
self.state.
|
|
600
|
-
|
|
601
|
-
|
|
599
|
+
if (!self.state.getGroupIdForClient(clientId)) {
|
|
600
|
+
self.state.setGroupIdForClient(clientId, groupId);
|
|
601
|
+
}
|
|
602
602
|
chrome.tabGroups.update(groupId, {
|
|
603
603
|
title: baseName,
|
|
604
604
|
color: CDPUtils.getGroupColorForClient(clientId),
|
|
@@ -607,8 +607,10 @@ var WebSocketConnection = (function() {
|
|
|
607
607
|
if (chrome.runtime.lastError) {
|
|
608
608
|
Logger.warn('[WS:' + self.connectionId + '] Failed to set group title:', chrome.runtime.lastError.message);
|
|
609
609
|
}
|
|
610
|
+
self.state.setGroupCreationPromise(clientId, null);
|
|
611
|
+
resolveGroupReady(groupId);
|
|
612
|
+
Logger.info('[WS:' + self.connectionId + '] Created group for client:', clientId, 'groupId:', groupId, 'title:', baseName);
|
|
610
613
|
});
|
|
611
|
-
Logger.info('[WS:' + self.connectionId + '] Created group for client:', clientId, 'groupId:', groupId, 'title:', baseName);
|
|
612
614
|
});
|
|
613
615
|
});
|
|
614
616
|
};
|
package/package.json
CHANGED