ghost-bridge 0.4.0 → 0.5.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/LICENSE +21 -0
- package/README.md +113 -110
- package/dist/cli.js +68 -37
- package/extension/background.js +130 -39
- package/extension/icon-128.png +0 -0
- package/extension/icon-16.png +0 -0
- package/extension/icon-48.png +0 -0
- package/extension/manifest.json +1 -1
- package/extension/offscreen.js +1 -1
- package/extension/popup.html +416 -85
- package/extension/popup.js +128 -53
- package/package.json +24 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 <Author>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,156 +1,159 @@
|
|
|
1
|
-
# Ghost Bridge
|
|
1
|
+
# 👻 Ghost Bridge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/ghost-bridge)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
> **Zero-restart Chrome AI Copilot** — Subvert your workflow. Allow AI to seamlessly take over the browser you're already using, enabling real-time debugging, visual observation, and interactive manipulation without launching a new Chrome instance.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
- 🔍 **无 sourcemap 调试** — 片段截取、字符串搜索、覆盖率分析,在压缩代码中定位问题
|
|
9
|
-
- 🌐 **网络请求分析** — 完整记录请求/响应,支持多维度过滤和响应体查看
|
|
10
|
-
- 📸 **页面截图与内容提取** — 视觉分析 + 结构化数据提取
|
|
11
|
-
- 🎯 **DOM 交互操控** — AI 可直接点击按钮、填写表单、按键提交,使用 CDP 物理级模拟,兼容 React/Vue/Angular
|
|
12
|
-
- 📊 **性能诊断** — JS 堆内存、DOM 规模、Layout 开销、Web Vitals、资源加载分析
|
|
13
|
-
- 🔄 **多实例支持** — 自动单例管理,多个 MCP 客户端共享同一 Chrome 连接
|
|
8
|
+
---
|
|
14
9
|
|
|
15
|
-
##
|
|
10
|
+
## ✨ Why Ghost Bridge?
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
- 🔌 **Zero-Config Attach** — Bypasses the need for `--remote-debugging-port`. Captures Chrome's native DevTools Protocol directly via an extension.
|
|
13
|
+
- 🔍 **No-Sourcemap Debugging** — Slice code fragments, perform string searches, and analyze coverage to pinpoint bugs straight in minified production code.
|
|
14
|
+
- 🌐 **Deep Network Analysis** — Comprehensive capture of requests/responses with multi-dimensional filtering and response body inspection.
|
|
15
|
+
- 📸 **Visual & Structural Perception** — Full-page or clipped high-fidelity screenshots paired with structural data extraction (titles, links, forms, buttons).
|
|
16
|
+
- 🎯 **DOM Physical Manipulation** — Empowers AI to click, type, and form-submit with CDP-level physical simulation. Fully compatible with complex SPAs (React/Vue/Angular/Svelte).
|
|
17
|
+
- 📊 **Performance Diagnostics** — Get granular engine metrics: JS Heap, Layout recalculations, Web Vitals (TTFB/FCP/LCP), and resource loading speeds.
|
|
18
|
+
- 🔄 **Multi-Client Mastery** — Built-in singleton manager automatically coordinates multiple MCP clients sharing a single Chrome transport.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Quick Start
|
|
23
|
+
|
|
24
|
+
### 1. Install & Initialize
|
|
18
25
|
|
|
19
26
|
```bash
|
|
20
|
-
#
|
|
27
|
+
# Install globally
|
|
21
28
|
npm install -g ghost-bridge
|
|
22
29
|
|
|
23
|
-
#
|
|
30
|
+
# Auto-configure MCP (Claude Code, Antigravity, Codex) and prepare the extension directory
|
|
24
31
|
ghost-bridge init
|
|
25
32
|
```
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
> **Note on other MCP clients (Cursor, Windsurf, Roo):**
|
|
35
|
+
> `ghost-bridge init` attempts to auto-configure supported clients. If your client isn't auto-detected, simply add the following to your client's MCP configuration file (e.g., `mcp.json`):
|
|
36
|
+
> ```json
|
|
37
|
+
> {
|
|
38
|
+
> "mcpServers": {
|
|
39
|
+
> "ghost-bridge": {
|
|
40
|
+
> "command": "node",
|
|
41
|
+
> "args": ["/absolute/path/to/global/node_modules/ghost-bridge/dist/server.js"]
|
|
42
|
+
> }
|
|
43
|
+
> }
|
|
44
|
+
> }
|
|
45
|
+
> ```
|
|
28
46
|
|
|
29
|
-
|
|
30
|
-
2. 开启右上角的 **开发者模式**
|
|
31
|
-
3. 点击 **加载已解压的扩展程序**
|
|
32
|
-
4. 选择目录:`~/.ghost-bridge/extension`
|
|
47
|
+
### 2. Load the Chrome Extension
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
1. Open Chrome and navigate to `chrome://extensions`
|
|
50
|
+
2. Toggle **Developer mode** in the top right corner.
|
|
51
|
+
3. Click **Load unpacked**
|
|
52
|
+
4. Select the directory: `~/.ghost-bridge/extension`
|
|
35
53
|
|
|
36
|
-
|
|
54
|
+
> 💡 *Tip: Run `ghost-bridge extension --open` to reveal the directory directly.*
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
2. 点击 **连接**,等待状态变为 ✅ 已连接
|
|
40
|
-
3. 打开 Claude Desktop 或 Claude CLI,即可使用所有调试工具
|
|
56
|
+
### 3. Connect & Command
|
|
41
57
|
|
|
42
|
-
|
|
58
|
+
1. Click the **Ghost Bridge** ghost icon in your browser toolbar.
|
|
59
|
+
2. Click **Connect** and wait for the status to turn to ✅ **ON**.
|
|
60
|
+
3. Open Claude Desktop or your Claude CLI. All tools are now primed and ready!
|
|
43
61
|
|
|
44
|
-
|
|
45
|
-
|------|------|
|
|
46
|
-
| `ghost-bridge init` | 配置 MCP 并复制扩展文件 |
|
|
47
|
-
| `ghost-bridge status` | 检查配置状态 |
|
|
48
|
-
| `ghost-bridge extension` | 显示扩展安装路径(`--open` 打开目录) |
|
|
49
|
-
| `ghost-bridge start` | 手动启动 MCP 服务(通常不需要) |
|
|
62
|
+
---
|
|
50
63
|
|
|
51
|
-
##
|
|
64
|
+
## 🛠️ Tool Arsenal
|
|
52
65
|
|
|
53
|
-
### 🔍
|
|
66
|
+
### 🔍 Core Debugging
|
|
54
67
|
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
| `get_server_info` |
|
|
58
|
-
| `get_last_error` |
|
|
59
|
-
| `get_script_source` |
|
|
60
|
-
| `coverage_snapshot` |
|
|
61
|
-
| `find_by_string` |
|
|
62
|
-
| `symbolic_hints` |
|
|
63
|
-
| `eval_script` |
|
|
68
|
+
| Tool | Capability |
|
|
69
|
+
|------|------------|
|
|
70
|
+
| `get_server_info` | Retrieves server instance status, WebSocket ports, and client roles. |
|
|
71
|
+
| `get_last_error` | Aggregates recent exceptions, console errors, and failed network requests with mapped locators. |
|
|
72
|
+
| `get_script_source` | Pulls raw script definitions. Supports URL-fragment filtering, specific line targeting, and beautification. |
|
|
73
|
+
| `coverage_snapshot` | Triggers a quick coverage trace (1.5s default) to identify the most active scripts on the page. |
|
|
74
|
+
| `find_by_string` | Scans page script sources for keywords, returning a 200-character context window. |
|
|
75
|
+
| `symbolic_hints` | Gathers context clues: Resource lists, Global Variable keys, LocalStorage schema, and UA strings. |
|
|
76
|
+
| `eval_script` | Executes raw JavaScript expressions in the page context. *(Use with caution)* |
|
|
64
77
|
|
|
65
|
-
###
|
|
78
|
+
### 🌍 Network Intelligence
|
|
66
79
|
|
|
67
|
-
|
|
|
68
|
-
|
|
69
|
-
| `list_network_requests` |
|
|
70
|
-
| `get_network_detail` |
|
|
71
|
-
| `clear_network_requests` |
|
|
80
|
+
| Tool | Capability |
|
|
81
|
+
|------|------------|
|
|
82
|
+
| `list_network_requests` | Lists captured network traffic. Supports filtering by URL, Method, Status Code, or Resource Type. |
|
|
83
|
+
| `get_network_detail` | Dives deep into a specific request's Headers, Timing, and optional Response Body extraction. |
|
|
84
|
+
| `clear_network_requests` | Wipes the current network capture buffer. |
|
|
72
85
|
|
|
73
|
-
### 📸
|
|
86
|
+
### 📸 Page Perception
|
|
74
87
|
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
| `capture_screenshot` |
|
|
78
|
-
| `get_page_content` |
|
|
88
|
+
| Tool | Capability |
|
|
89
|
+
|------|------------|
|
|
90
|
+
| `capture_screenshot` | Captures the viewport or emulates full-page scrolling screenshots. |
|
|
91
|
+
| `get_page_content` | Extracts raw text, sanitized HTML, or structured actionable data representations. |
|
|
79
92
|
|
|
80
|
-
### 🎯
|
|
93
|
+
### 🎯 Interactive Automation (DOM)
|
|
81
94
|
|
|
82
|
-
|
|
|
83
|
-
|
|
84
|
-
| `get_interactive_snapshot` |
|
|
85
|
-
| `dispatch_action` |
|
|
95
|
+
| Tool | Capability |
|
|
96
|
+
|------|------------|
|
|
97
|
+
| `get_interactive_snapshot` | Scans for visible interactive elements, returning a concise map `[e1, e2...]`. Pierces open Shadow DOMs. |
|
|
98
|
+
| `dispatch_action` | Dispatches physical UI actions (click, fill, press, hover) against targeted element references (e.g., `e1`). |
|
|
86
99
|
|
|
87
|
-
|
|
100
|
+
**Example Agent Workflow:**
|
|
101
|
+
1. AI: `get_interactive_snapshot` ➝ `[{ref:"e1", tag:"input", placeholder:"Search..."}, {ref:"e2", tag:"button", text:"Login"}]`
|
|
102
|
+
2. AI: `dispatch_action({ref: "e1", action: "fill", value: "hello"})`
|
|
103
|
+
3. AI: `dispatch_action({ref: "e2", action: "click"})`
|
|
104
|
+
4. AI: `capture_screenshot` to verify state changes.
|
|
88
105
|
|
|
89
|
-
|
|
90
|
-
1. AI 调用 get_interactive_snapshot
|
|
91
|
-
→ 返回: [{ref:"e1", tag:"input", placeholder:"Search..."}, {ref:"e2", tag:"button", text:"Login"}]
|
|
106
|
+
### 📊 Performance Profiling
|
|
92
107
|
|
|
93
|
-
|
|
94
|
-
|
|
108
|
+
| Tool | Capability |
|
|
109
|
+
|------|------------|
|
|
110
|
+
| `perf_metrics` | Collects layered performance data (Engine Metrics, Web Vitals, and Resource Load Summaries). |
|
|
95
111
|
|
|
96
|
-
|
|
97
|
-
→ 点击 Login 按钮
|
|
112
|
+
---
|
|
98
113
|
|
|
99
|
-
|
|
100
|
-
```
|
|
114
|
+
## ⚙️ Configuration
|
|
101
115
|
|
|
102
|
-
|
|
116
|
+
| Setting | Default | Description |
|
|
117
|
+
|---------|---------|-------------|
|
|
118
|
+
| **Base Port** | `33333` | WS port. Auto-increments if occupied. |
|
|
119
|
+
| **Token** | *Monthly UUID* | Local WS auth token, auto-rotates on the 1st of every month. |
|
|
120
|
+
| **Auto Detach** | `false` | Keeps debugger attached to actively buffer invisible exceptions and network calls. |
|
|
103
121
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
**Environment Variables:**
|
|
123
|
+
- `GHOST_BRIDGE_PORT` — Override base port.
|
|
124
|
+
- `GHOST_BRIDGE_TOKEN` — Override connection token.
|
|
107
125
|
|
|
108
|
-
|
|
126
|
+
---
|
|
109
127
|
|
|
110
|
-
|
|
111
|
-
- **Web Vitals** — Navigation Timing 各阶段(DNS / TTFB / DOM Interactive / Load)、FP、FCP、Long Tasks 统计
|
|
112
|
-
- **资源加载摘要** — 按类型分组统计(count / size / avgDuration)、最慢资源识别
|
|
128
|
+
## 🏗️ Architecture
|
|
113
129
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
| 自动 Detach | `false` | 保持附加,便于持续捕获异常和网络请求 |
|
|
130
|
+
```mermaid
|
|
131
|
+
graph LR
|
|
132
|
+
A[Claude CLI/Desktop] <-->|stdio| B(MCP Server\nserver.js)
|
|
133
|
+
B <-->|WebSocket| C(Chrome Extension\nbackground.js)
|
|
134
|
+
C <-->|CDP| D[Browser Tab\nTarget Context]
|
|
135
|
+
```
|
|
121
136
|
|
|
122
|
-
|
|
137
|
+
- **MCP Server**: Spawned by Claude via standard I/O streams. Orchestrates WS connections.
|
|
138
|
+
- **Chrome Extension (MV3)**: Taps into `chrome.debugger` API. Utilizes an Offscreen Document to prevent WS hibernation.
|
|
139
|
+
- **Singleton Design**: If multiple agents spawn servers, the first becomes the master bridge while subsequent instances chain transparently as clients.
|
|
123
140
|
|
|
124
|
-
|
|
125
|
-
- `GHOST_BRIDGE_TOKEN` — 自定义 token
|
|
141
|
+
---
|
|
126
142
|
|
|
127
|
-
##
|
|
143
|
+
## ⚠️ Known Limitations
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
└──────────────┘ └──────────────┘ └──────┬───────┘
|
|
134
|
-
│ CDP
|
|
135
|
-
┌─────▼──────┐
|
|
136
|
-
│ 浏览器页面 │
|
|
137
|
-
└────────────┘
|
|
138
|
-
```
|
|
145
|
+
- **Service Workers Suspending**: MV3 background workers may suspend. We've built robust auto-reconnection logic, but prolonged inactivity might require re-toggling.
|
|
146
|
+
- **DevTools Conflict**: If you manually open Chrome DevTools (F12) on the target tab, `chrome.debugger.attach` may be rejected.
|
|
147
|
+
- **Beautify Overhead**: Beautifying massive single-line bundles is expensive; the server will auto-truncate overly large scripts.
|
|
148
|
+
- **Cross-Origin OOPIF**: Elements and errors deeply embedded in strict Cross-Origin Iframes might evade the primary debugger hook without further multi-target attach logic.
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
- **Chrome Extension (MV3)** — 使用 `chrome.debugger` API 附加页面,Offscreen Document 维持 WebSocket 长连接
|
|
142
|
-
- **单例模式** — 多个 MCP 客户端自动协调,首个实例为主服务,后续实例作为客户端连接
|
|
150
|
+
---
|
|
143
151
|
|
|
144
|
-
##
|
|
152
|
+
## 🤝 Contributing
|
|
145
153
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
- 大体积单行 bundle beautify 可能耗时,服务端对超长源码会截取片段
|
|
149
|
-
- 跨月时 token 会自动更新,扩展和服务端需在同月内启动
|
|
150
|
-
- DOM 交互:SPA 路由变化后 ref 标识会失效,需重新调用 `get_interactive_snapshot`
|
|
151
|
-
- DOM 交互:跨域 iframe 内的元素暂不支持细粒度操作
|
|
152
|
-
- DOM 交互:Shadow DOM 内的元素可以被扫描到,但部分封闭模式的 Shadow Root 可能无法穿透
|
|
154
|
+
Contributions, issues, and feature requests are welcome!
|
|
155
|
+
Check out our [Contributing Guide](CONTRIBUTING.md) to get started building tools or improving the bridge.
|
|
153
156
|
|
|
154
|
-
## License
|
|
157
|
+
## 📄 License
|
|
155
158
|
|
|
156
|
-
MIT
|
|
159
|
+
This project is [MIT](LICENSE) licensed.
|
package/dist/cli.js
CHANGED
|
@@ -5454,9 +5454,15 @@ var require_lib = __commonJS({
|
|
|
5454
5454
|
import path from "path";
|
|
5455
5455
|
import os2 from "os";
|
|
5456
5456
|
import { fileURLToPath } from "url";
|
|
5457
|
-
function
|
|
5457
|
+
function getClientConfigPaths() {
|
|
5458
5458
|
const homeDir = os2.homedir();
|
|
5459
|
-
return
|
|
5459
|
+
return [
|
|
5460
|
+
{ name: "Claude Code", path: path.join(homeDir, ".claude.json") },
|
|
5461
|
+
{ name: "Antigravity", path: path.join(homeDir, ".gemini", "antigravity", "mcp.json") },
|
|
5462
|
+
// Codex config placeholder - exact path depends on how Codex stores user config.
|
|
5463
|
+
// Assuming a common pattern here like ~/.codex/mcp.json or similar.
|
|
5464
|
+
{ name: "Codex", path: path.join(homeDir, ".codex", "mcp.json") }
|
|
5465
|
+
];
|
|
5460
5466
|
}
|
|
5461
5467
|
function getExtensionPath() {
|
|
5462
5468
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
@@ -5502,20 +5508,28 @@ function openFolder(folderPath) {
|
|
|
5502
5508
|
}
|
|
5503
5509
|
async function init(options) {
|
|
5504
5510
|
console.log(source_default.bold("\u{1F47B} Ghost Bridge Initialization"));
|
|
5505
|
-
const
|
|
5511
|
+
const clientConfigs = getClientConfigPaths();
|
|
5506
5512
|
const serverPath = getServerPath();
|
|
5507
5513
|
const isDryRun = options.dryRun;
|
|
5508
|
-
console.log(source_default.dim("Checking
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5514
|
+
console.log(source_default.dim("Checking MCP Client configurations..."));
|
|
5515
|
+
let configuredCount = 0;
|
|
5516
|
+
for (const client of clientConfigs) {
|
|
5517
|
+
const configPath = client.path;
|
|
5518
|
+
if (isDryRun) {
|
|
5519
|
+
console.log(source_default.yellow(`[Dry Run] Would check ${client.name} config at: ${configPath}`));
|
|
5520
|
+
if (import_fs_extra.default.existsSync(configPath) || client.name === "Claude Code") {
|
|
5521
|
+
console.log(source_default.yellow(`[Dry Run] Would add MCP server logic for ${client.name}`));
|
|
5522
|
+
}
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5525
|
+
const exists = import_fs_extra.default.existsSync(configPath);
|
|
5526
|
+
if (!exists && client.name !== "Claude Code") {
|
|
5527
|
+
continue;
|
|
5528
|
+
}
|
|
5529
|
+
if (!exists) {
|
|
5530
|
+
console.log(source_default.yellow(`Configuration file not found for ${client.name} at ${configPath}, creating...`));
|
|
5515
5531
|
await import_fs_extra.default.ensureDir(path2.dirname(configPath));
|
|
5516
|
-
|
|
5517
|
-
await import_fs_extra.default.writeJson(configPath, { mcpServers: {} }, { spaces: 2 });
|
|
5518
|
-
}
|
|
5532
|
+
await import_fs_extra.default.writeJson(configPath, { mcpServers: {} }, { spaces: 2 });
|
|
5519
5533
|
}
|
|
5520
5534
|
try {
|
|
5521
5535
|
const config = await import_fs_extra.default.readJson(configPath);
|
|
@@ -5525,11 +5539,15 @@ async function init(options) {
|
|
|
5525
5539
|
args: [serverPath]
|
|
5526
5540
|
};
|
|
5527
5541
|
await import_fs_extra.default.writeJson(configPath, config, { spaces: 2 });
|
|
5528
|
-
console.log(source_default.green(`\u2705 MCP Server
|
|
5542
|
+
console.log(source_default.green(`\u2705 MCP Server configured for ${source_default.bold(client.name)} in ${configPath}`));
|
|
5543
|
+
configuredCount++;
|
|
5529
5544
|
} catch (err) {
|
|
5530
|
-
console.error(source_default.red(`Failed to update config: ${err.message}`));
|
|
5545
|
+
console.error(source_default.red(`Failed to update config for ${client.name}: ${err.message}`));
|
|
5531
5546
|
}
|
|
5532
5547
|
}
|
|
5548
|
+
if (configuredCount === 0 && !isDryRun) {
|
|
5549
|
+
console.log(source_default.yellow("\u26A0\uFE0F No supported MCP clients found to configure automatically."));
|
|
5550
|
+
}
|
|
5533
5551
|
const sourceExt = getExtensionPath();
|
|
5534
5552
|
const targetExt = getUserExtensionDir();
|
|
5535
5553
|
console.log(source_default.dim(`Setting up extension in ${targetExt}...`));
|
|
@@ -5617,34 +5635,47 @@ __export(status_exports, {
|
|
|
5617
5635
|
});
|
|
5618
5636
|
async function status() {
|
|
5619
5637
|
console.log(source_default.bold("\u{1F47B} Ghost Bridge Status"));
|
|
5620
|
-
const
|
|
5638
|
+
const clientConfigs = getClientConfigPaths();
|
|
5621
5639
|
const extDir = getUserExtensionDir();
|
|
5622
5640
|
const serverPath = getServerPath();
|
|
5623
|
-
|
|
5624
|
-
let
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
const
|
|
5632
|
-
if (
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5641
|
+
console.log(source_default.bold.blue("\nMCP Client Configurations:"));
|
|
5642
|
+
let configuredCount = 0;
|
|
5643
|
+
for (const client of clientConfigs) {
|
|
5644
|
+
let mcpStatus = source_default.gray("Not Configured");
|
|
5645
|
+
let mcpDetails = "";
|
|
5646
|
+
const configPath = client.path;
|
|
5647
|
+
if (import_fs_extra3.default.existsSync(configPath)) {
|
|
5648
|
+
try {
|
|
5649
|
+
const config = await import_fs_extra3.default.readJson(configPath);
|
|
5650
|
+
if (config.mcpServers && config.mcpServers["ghost-bridge"]) {
|
|
5651
|
+
mcpStatus = source_default.green("Configured");
|
|
5652
|
+
const cfg = config.mcpServers["ghost-bridge"];
|
|
5653
|
+
const configuredPath = cfg.args[0];
|
|
5654
|
+
if (configuredPath === serverPath) {
|
|
5655
|
+
mcpDetails = source_default.dim("(Paths match)");
|
|
5656
|
+
} else {
|
|
5657
|
+
mcpDetails = source_default.yellow(`(Path mismatch)
|
|
5658
|
+
Configured: ${configuredPath}
|
|
5659
|
+
Current: ${serverPath}`);
|
|
5660
|
+
}
|
|
5661
|
+
configuredCount++;
|
|
5638
5662
|
}
|
|
5663
|
+
} catch (e) {
|
|
5664
|
+
mcpStatus = source_default.red("Error reading config");
|
|
5665
|
+
}
|
|
5666
|
+
} else {
|
|
5667
|
+
if (client.name === "Claude Code") {
|
|
5668
|
+
mcpStatus = source_default.yellow("Config file not found");
|
|
5669
|
+
} else {
|
|
5670
|
+
mcpStatus = source_default.gray("Not Installed");
|
|
5639
5671
|
}
|
|
5640
|
-
} catch (e) {
|
|
5641
|
-
mcpStatus = source_default.red("Error reading config");
|
|
5642
5672
|
}
|
|
5643
|
-
}
|
|
5644
|
-
|
|
5673
|
+
console.log(` ${source_default.bold(client.name)}: ${mcpStatus} ${mcpDetails}`);
|
|
5674
|
+
console.log(` Config File: ${source_default.dim(configPath)}`);
|
|
5675
|
+
}
|
|
5676
|
+
if (configuredCount === 0) {
|
|
5677
|
+
console.log(source_default.yellow("\n No MCP clients currently have ghost-bridge configured. Run `ghost-bridge init`."));
|
|
5645
5678
|
}
|
|
5646
|
-
console.log(`MCP Configuration: ${mcpStatus} ${mcpDetails}`);
|
|
5647
|
-
console.log(` Config File: ${configPath}`);
|
|
5648
5679
|
let extStatus = source_default.red("Not Installed (Run init)");
|
|
5649
5680
|
if (import_fs_extra3.default.existsSync(extDir)) {
|
|
5650
5681
|
extStatus = source_default.green("Installed");
|