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 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(), ".ghost-bridge", "extension");
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 os3 from "os";
5560
- function openFolder(path4) {
5561
- const platform = os3.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
- exec(command, (err) => {
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
- openFolder(extDir);
5600
+ openFolder2(extDir);
5587
5601
  }
5588
5602
  }
5589
5603
  var import_fs_extra2;
@@ -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
- // background 自己发出的消息不处理(避免循环)
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
- // 来自 offscreen 的状态更新
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
@@ -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.1",
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
+ }