ghost-bridge 0.2.1 → 0.2.3
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/dist/cli.js +21 -7
- package/extension/background.js +16 -14
- package/extension/offscreen.js +9 -0
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5474,7 +5474,7 @@ function getServerPath() {
|
|
|
5474
5474
|
return path.resolve(currentDir, "../dist/server.js");
|
|
5475
5475
|
}
|
|
5476
5476
|
function getUserExtensionDir() {
|
|
5477
|
-
return path.join(os2.homedir(), "
|
|
5477
|
+
return path.join(os2.homedir(), "ghost-bridge", "extension");
|
|
5478
5478
|
}
|
|
5479
5479
|
var init_utils = __esm({
|
|
5480
5480
|
"lib/utils.js"() {
|
|
@@ -5487,6 +5487,18 @@ __export(init_exports, {
|
|
|
5487
5487
|
init: () => init
|
|
5488
5488
|
});
|
|
5489
5489
|
import path2 from "path";
|
|
5490
|
+
import { exec } from "child_process";
|
|
5491
|
+
import os3 from "os";
|
|
5492
|
+
function openFolder(folderPath) {
|
|
5493
|
+
const platform = os3.platform();
|
|
5494
|
+
let command = "";
|
|
5495
|
+
if (platform === "darwin") command = `open "${folderPath}"`;
|
|
5496
|
+
else if (platform === "win32") command = `start "" "${folderPath}"`;
|
|
5497
|
+
else command = `xdg-open "${folderPath}"`;
|
|
5498
|
+
exec(command, (err) => {
|
|
5499
|
+
if (err) console.error(source_default.dim("Failed to open folder:", err.message));
|
|
5500
|
+
});
|
|
5501
|
+
}
|
|
5490
5502
|
async function init(options) {
|
|
5491
5503
|
console.log(source_default.bold("\u{1F47B} Ghost Bridge Initialization"));
|
|
5492
5504
|
const configPath = getClaudeConfigPath();
|
|
@@ -5539,6 +5551,8 @@ async function init(options) {
|
|
|
5539
5551
|
console.log(`4. Select the folder: ${source_default.bold(targetExt)}`);
|
|
5540
5552
|
if (!isDryRun) {
|
|
5541
5553
|
await import_fs_extra.default.outputFile(path2.join(targetExt, ".ghost-bridge-managed"), "This folder is managed by ghost-bridge CLI. Do not edit manually.");
|
|
5554
|
+
console.log(source_default.dim("\n\u{1F4C2} Opening extension folder..."));
|
|
5555
|
+
openFolder(targetExt);
|
|
5542
5556
|
}
|
|
5543
5557
|
}
|
|
5544
5558
|
var import_fs_extra;
|
|
@@ -5555,15 +5569,15 @@ var extension_exports = {};
|
|
|
5555
5569
|
__export(extension_exports, {
|
|
5556
5570
|
showExtension: () => showExtension
|
|
5557
5571
|
});
|
|
5558
|
-
import { exec } from "child_process";
|
|
5559
|
-
import
|
|
5560
|
-
function
|
|
5561
|
-
const platform =
|
|
5572
|
+
import { exec as exec2 } from "child_process";
|
|
5573
|
+
import os4 from "os";
|
|
5574
|
+
function openFolder2(path4) {
|
|
5575
|
+
const platform = os4.platform();
|
|
5562
5576
|
let command = "";
|
|
5563
5577
|
if (platform === "darwin") command = `open "${path4}"`;
|
|
5564
5578
|
else if (platform === "win32") command = `start "" "${path4}"`;
|
|
5565
5579
|
else command = `xdg-open "${path4}"`;
|
|
5566
|
-
|
|
5580
|
+
exec2(command, (err) => {
|
|
5567
5581
|
if (err) console.error("Failed to open folder:", err);
|
|
5568
5582
|
});
|
|
5569
5583
|
}
|
|
@@ -5583,7 +5597,7 @@ async function showExtension(options) {
|
|
|
5583
5597
|
console.log('3. Click "Load unpacked" and select the directory above.');
|
|
5584
5598
|
if (options.open) {
|
|
5585
5599
|
console.log(source_default.dim("Opening folder..."));
|
|
5586
|
-
|
|
5600
|
+
openFolder2(extDir);
|
|
5587
5601
|
}
|
|
5588
5602
|
}
|
|
5589
5603
|
var import_fs_extra2;
|
package/extension/background.js
CHANGED
|
@@ -801,20 +801,9 @@ function sendToServer(data) {
|
|
|
801
801
|
chrome.runtime.sendMessage({ type: 'send', data }).catch(() => {})
|
|
802
802
|
}
|
|
803
803
|
|
|
804
|
-
// ==========
|
|
805
|
-
|
|
806
|
-
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
807
|
-
// 判断消息来源
|
|
808
|
-
const senderUrl = sender.url || ''
|
|
809
|
-
const isFromOffscreen = senderUrl.includes('offscreen.html')
|
|
810
|
-
const isFromBackground = !sender.url // background 发的消息没有 url
|
|
804
|
+
// ========== 状态广播 ==========
|
|
811
805
|
|
|
812
|
-
|
|
813
|
-
if (isFromBackground) {
|
|
814
|
-
return
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
// 主动推送状态给 popup
|
|
806
|
+
// 主动推送状态给 popup
|
|
818
807
|
function broadcastStatus() {
|
|
819
808
|
let status
|
|
820
809
|
if (!state.enabled) {
|
|
@@ -839,7 +828,20 @@ function broadcastStatus() {
|
|
|
839
828
|
}).catch(() => {}) // popup 可能未打开,忽略错误
|
|
840
829
|
}
|
|
841
830
|
|
|
842
|
-
//
|
|
831
|
+
// ========== 消息监听 ==========
|
|
832
|
+
|
|
833
|
+
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
834
|
+
// 判断消息来源
|
|
835
|
+
const senderUrl = sender.url || ''
|
|
836
|
+
const isFromOffscreen = senderUrl.includes('offscreen.html')
|
|
837
|
+
const isFromBackground = !sender.url // background 发的消息没有 url
|
|
838
|
+
|
|
839
|
+
// background 自己发出的消息不处理(避免循环)
|
|
840
|
+
if (isFromBackground) {
|
|
841
|
+
return
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// 来自 offscreen 的状态更新
|
|
843
845
|
if (message.type === 'status' && isFromOffscreen) {
|
|
844
846
|
if (message.status === 'connected') {
|
|
845
847
|
state.connected = true
|
package/extension/offscreen.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
let ws = null
|
|
5
5
|
let reconnectTimer = null
|
|
6
|
+
let manualDisconnect = false // 用户主动断开标志,防止 onclose 触发重连
|
|
6
7
|
let config = {
|
|
7
8
|
basePort: 33333,
|
|
8
9
|
token: '',
|
|
@@ -23,6 +24,9 @@ function getMonthlyToken() {
|
|
|
23
24
|
|
|
24
25
|
// 连接到服务器
|
|
25
26
|
function connect(portIndex = 0, isNewRound = false) {
|
|
27
|
+
// 如果已手动断开,不再尝试连接
|
|
28
|
+
if (manualDisconnect) return
|
|
29
|
+
|
|
26
30
|
if (portIndex >= config.maxPortRetries) {
|
|
27
31
|
log(`扫描完毕,未找到服务,2秒后重试...`)
|
|
28
32
|
reconnectTimer = setTimeout(() => connect(0, true), 2000)
|
|
@@ -99,6 +103,9 @@ function connect(portIndex = 0, isNewRound = false) {
|
|
|
99
103
|
ws.onclose = (event) => {
|
|
100
104
|
clearTimeout(connectionTimeout)
|
|
101
105
|
|
|
106
|
+
// 用户主动断开,不重连
|
|
107
|
+
if (manualDisconnect) return
|
|
108
|
+
|
|
102
109
|
if (!identityVerified) {
|
|
103
110
|
// 连接失败,尝试下一个端口
|
|
104
111
|
setTimeout(() => connect(portIndex + 1), 50)
|
|
@@ -127,6 +134,7 @@ function sendToServer(data) {
|
|
|
127
134
|
|
|
128
135
|
// 断开连接
|
|
129
136
|
function disconnect() {
|
|
137
|
+
manualDisconnect = true // 标记为手动断开,阻止 onclose 重连
|
|
130
138
|
if (reconnectTimer) {
|
|
131
139
|
clearTimeout(reconnectTimer)
|
|
132
140
|
reconnectTimer = null
|
|
@@ -145,6 +153,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
145
153
|
config.token = message.token || getMonthlyToken()
|
|
146
154
|
config.maxPortRetries = message.maxPortRetries || 10
|
|
147
155
|
disconnect()
|
|
156
|
+
manualDisconnect = false // 用户重新连接,清除断开标志
|
|
148
157
|
connect(0, true)
|
|
149
158
|
sendResponse({ ok: true })
|
|
150
159
|
return true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghost-bridge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Ghost Bridge: Zero-restart Chrome debugger bridge for Claude MCP. Includes CLI for easy setup.",
|
|
@@ -26,4 +26,4 @@
|
|
|
26
26
|
"js-beautify": "^1.14.11",
|
|
27
27
|
"ws": "^8.14.2"
|
|
28
28
|
}
|
|
29
|
-
}
|
|
29
|
+
}
|