ghost-bridge 0.7.0 → 0.8.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/README.md +20 -18
- package/dist/cli.js +266 -140
- package/dist/server.js +137 -38
- package/extension/background.js +246 -628
- package/extension/bg-dom.js +441 -0
- package/extension/bg-network.js +194 -0
- package/extension/manifest.json +1 -3
- package/extension/offscreen.js +64 -21
- package/extension/popup.html +72 -54
- package/extension/popup.js +72 -42
- package/package.json +1 -1
- package/extension/icon-32.png +0 -0
package/dist/server.js
CHANGED
|
@@ -28523,6 +28523,7 @@ import net from "net";
|
|
|
28523
28523
|
import fs2 from "fs";
|
|
28524
28524
|
import os from "os";
|
|
28525
28525
|
import path2 from "path";
|
|
28526
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
28526
28527
|
|
|
28527
28528
|
// lib/version.js
|
|
28528
28529
|
import fs from "fs";
|
|
@@ -28541,6 +28542,7 @@ var WS_TOKEN = process.env.GHOST_BRIDGE_TOKEN || DEFAULT_WS_TOKEN;
|
|
|
28541
28542
|
var RESPONSE_TIMEOUT = 8e3;
|
|
28542
28543
|
var PORT_INFO_FILE = path2.join(os.tmpdir(), "ghost-bridge-port.json");
|
|
28543
28544
|
var SERVER_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
|
|
28545
|
+
var SERVER_ENTRY_PATH = fileURLToPath2(import.meta.url);
|
|
28544
28546
|
var chromeConnection = null;
|
|
28545
28547
|
var activeConnection = null;
|
|
28546
28548
|
var actualPort = BASE_PORT;
|
|
@@ -28550,6 +28552,30 @@ var mcpClients = /* @__PURE__ */ new Set();
|
|
|
28550
28552
|
function log(msg) {
|
|
28551
28553
|
console.error(`[ghost-bridge] ${msg}`);
|
|
28552
28554
|
}
|
|
28555
|
+
function buildIdentityPayload() {
|
|
28556
|
+
return {
|
|
28557
|
+
type: "identity",
|
|
28558
|
+
service: "ghost-bridge",
|
|
28559
|
+
token: WS_TOKEN,
|
|
28560
|
+
pid: process.pid,
|
|
28561
|
+
port: actualPort,
|
|
28562
|
+
version: GHOST_BRIDGE_VERSION,
|
|
28563
|
+
serverPath: SERVER_ENTRY_PATH,
|
|
28564
|
+
startedAt: SERVER_STARTED_AT
|
|
28565
|
+
};
|
|
28566
|
+
}
|
|
28567
|
+
function getServiceMismatch(probe) {
|
|
28568
|
+
if (!probe || probe.service !== "ghost-bridge") return null;
|
|
28569
|
+
if (!probe.version) return "\u65E7\u670D\u52A1\u7F3A\u5C11\u7248\u672C\u5143\u6570\u636E";
|
|
28570
|
+
if (probe.version !== GHOST_BRIDGE_VERSION) {
|
|
28571
|
+
return `\u7248\u672C\u4E0D\u4E00\u81F4\uFF08\u65E7: ${probe.version}, \u65B0: ${GHOST_BRIDGE_VERSION}\uFF09`;
|
|
28572
|
+
}
|
|
28573
|
+
if (!probe.serverPath) return "\u65E7\u670D\u52A1\u7F3A\u5C11\u8DEF\u5F84\u5143\u6570\u636E";
|
|
28574
|
+
if (path2.resolve(probe.serverPath) !== path2.resolve(SERVER_ENTRY_PATH)) {
|
|
28575
|
+
return `\u8DEF\u5F84\u4E0D\u4E00\u81F4\uFF08\u65E7: ${probe.serverPath}, \u65B0: ${SERVER_ENTRY_PATH}\uFF09`;
|
|
28576
|
+
}
|
|
28577
|
+
return null;
|
|
28578
|
+
}
|
|
28553
28579
|
function isProcessRunning(pid) {
|
|
28554
28580
|
try {
|
|
28555
28581
|
process.kill(pid, 0);
|
|
@@ -28628,11 +28654,11 @@ async function waitForPortAvailable(port, timeoutMs = 5e3) {
|
|
|
28628
28654
|
}
|
|
28629
28655
|
return isPortAvailable(port);
|
|
28630
28656
|
}
|
|
28631
|
-
async function stopExistingService(pid, port) {
|
|
28657
|
+
async function stopExistingService(pid, port, reason = "\u9700\u8981\u7531\u65B0\u5B9E\u4F8B\u63A5\u7BA1") {
|
|
28632
28658
|
if (!pid || pid === process.pid) {
|
|
28633
28659
|
return false;
|
|
28634
28660
|
}
|
|
28635
|
-
log(`\u68C0\u6D4B\u5230\u65E7\u5B9E\u4F8B
|
|
28661
|
+
log(`\u68C0\u6D4B\u5230\u65E7\u5B9E\u4F8B\u9700\u8981\u66FF\u6362\uFF1A${reason}\uFF0C\u51C6\u5907\u505C\u6B62\u65E7\u5B9E\u4F8B (PID: ${pid})`);
|
|
28636
28662
|
try {
|
|
28637
28663
|
process.kill(pid, "SIGTERM");
|
|
28638
28664
|
} catch (e) {
|
|
@@ -28686,13 +28712,18 @@ async function initWebSocketService() {
|
|
|
28686
28712
|
const probe = await probeExistingService(existing.port);
|
|
28687
28713
|
if (probe?.service === "ghost-bridge") {
|
|
28688
28714
|
if (probe.token === WS_TOKEN) {
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28715
|
+
const mismatch = getServiceMismatch(probe);
|
|
28716
|
+
if (!mismatch) {
|
|
28717
|
+
actualPort = existing.port;
|
|
28718
|
+
isMainInstance = false;
|
|
28719
|
+
log(`\u2705 \u590D\u7528\u73B0\u6709\u670D\u52A1\uFF0C\u7AEF\u53E3 ${actualPort}`);
|
|
28720
|
+
return null;
|
|
28721
|
+
}
|
|
28722
|
+
await stopExistingService(Number(probe.pid) || existing.pid, existing.port, mismatch);
|
|
28723
|
+
} else {
|
|
28724
|
+
const oldPid = Number(probe.pid) || existing.pid;
|
|
28725
|
+
await stopExistingService(oldPid, existing.port, "token \u4E0D\u4E00\u81F4");
|
|
28693
28726
|
}
|
|
28694
|
-
const oldPid = Number(probe.pid) || existing.pid;
|
|
28695
|
-
await stopExistingService(oldPid, existing.port);
|
|
28696
28727
|
} else {
|
|
28697
28728
|
log(`\u274C \u73B0\u6709\u670D\u52A1\u9A8C\u8BC1\u5931\u8D25\uFF0C\u542F\u52A8\u65B0\u670D\u52A1...`);
|
|
28698
28729
|
try {
|
|
@@ -28705,12 +28736,17 @@ async function initWebSocketService() {
|
|
|
28705
28736
|
const probe = await probeExistingService(BASE_PORT);
|
|
28706
28737
|
if (probe?.service === "ghost-bridge") {
|
|
28707
28738
|
if (probe.token === WS_TOKEN) {
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28739
|
+
const mismatch = getServiceMismatch(probe);
|
|
28740
|
+
if (!mismatch) {
|
|
28741
|
+
actualPort = BASE_PORT;
|
|
28742
|
+
isMainInstance = false;
|
|
28743
|
+
log(`\u2705 \u590D\u7528\u56FA\u5B9A\u7AEF\u53E3\u4E0A\u7684\u73B0\u6709\u670D\u52A1\uFF0C\u7AEF\u53E3 ${actualPort}`);
|
|
28744
|
+
return null;
|
|
28745
|
+
}
|
|
28746
|
+
await stopExistingService(Number(probe.pid), BASE_PORT, mismatch);
|
|
28747
|
+
} else {
|
|
28748
|
+
await stopExistingService(Number(probe.pid), BASE_PORT, "token \u4E0D\u4E00\u81F4");
|
|
28712
28749
|
}
|
|
28713
|
-
await stopExistingService(Number(probe.pid), BASE_PORT);
|
|
28714
28750
|
}
|
|
28715
28751
|
if (!await isPortAvailable(BASE_PORT)) {
|
|
28716
28752
|
throw new Error(`\u56FA\u5B9A\u7AEF\u53E3 ${BASE_PORT} \u5DF2\u88AB\u5176\u4ED6\u8FDB\u7A0B\u5360\u7528\uFF0C\u8BF7\u91CA\u653E\u8BE5\u7AEF\u53E3\u6216\u901A\u8FC7 GHOST_BRIDGE_PORT \u6307\u5B9A\u5176\u4ED6\u7AEF\u53E3`);
|
|
@@ -28724,6 +28760,8 @@ async function initWebSocketService() {
|
|
|
28724
28760
|
port: actualPort,
|
|
28725
28761
|
wsUrl: `ws://localhost:${actualPort}`,
|
|
28726
28762
|
pid: process.pid,
|
|
28763
|
+
version: GHOST_BRIDGE_VERSION,
|
|
28764
|
+
serverPath: SERVER_ENTRY_PATH,
|
|
28727
28765
|
startedAt: SERVER_STARTED_AT
|
|
28728
28766
|
}, null, 2)
|
|
28729
28767
|
);
|
|
@@ -28737,14 +28775,7 @@ if (wss) {
|
|
|
28737
28775
|
const token = url2.searchParams.get("token") || "";
|
|
28738
28776
|
const role = url2.searchParams.get("role") || "";
|
|
28739
28777
|
if (role === "probe") {
|
|
28740
|
-
ws.send(JSON.stringify(
|
|
28741
|
-
type: "identity",
|
|
28742
|
-
service: "ghost-bridge",
|
|
28743
|
-
token: WS_TOKEN,
|
|
28744
|
-
pid: process.pid,
|
|
28745
|
-
port: actualPort,
|
|
28746
|
-
startedAt: SERVER_STARTED_AT
|
|
28747
|
-
}));
|
|
28778
|
+
ws.send(JSON.stringify(buildIdentityPayload()));
|
|
28748
28779
|
ws.close(1e3, "Probe complete");
|
|
28749
28780
|
return;
|
|
28750
28781
|
}
|
|
@@ -28757,7 +28788,7 @@ if (wss) {
|
|
|
28757
28788
|
if (role === "mcp-client") {
|
|
28758
28789
|
log("\u{1F4E1} MCP \u5BA2\u6237\u7AEF\u5DF2\u8FDE\u63A5");
|
|
28759
28790
|
mcpClients.add(ws);
|
|
28760
|
-
ws.send(JSON.stringify(
|
|
28791
|
+
ws.send(JSON.stringify(buildIdentityPayload()));
|
|
28761
28792
|
ws.on("message", (data) => {
|
|
28762
28793
|
try {
|
|
28763
28794
|
const msg = JSON.parse(data.toString());
|
|
@@ -28767,7 +28798,11 @@ if (wss) {
|
|
|
28767
28798
|
result: {
|
|
28768
28799
|
chromeConnected: !!chromeConnection,
|
|
28769
28800
|
mcpClientsCount: mcpClients.size,
|
|
28770
|
-
port: actualPort
|
|
28801
|
+
port: actualPort,
|
|
28802
|
+
version: GHOST_BRIDGE_VERSION,
|
|
28803
|
+
serverPath: SERVER_ENTRY_PATH,
|
|
28804
|
+
pid: process.pid,
|
|
28805
|
+
startedAt: SERVER_STARTED_AT
|
|
28771
28806
|
}
|
|
28772
28807
|
}));
|
|
28773
28808
|
return;
|
|
@@ -28801,7 +28836,7 @@ if (wss) {
|
|
|
28801
28836
|
log("\u{1F310} Chrome \u6269\u5C55\u5DF2\u8FDE\u63A5");
|
|
28802
28837
|
chromeConnection = ws;
|
|
28803
28838
|
activeConnection = ws;
|
|
28804
|
-
ws.send(JSON.stringify(
|
|
28839
|
+
ws.send(JSON.stringify(buildIdentityPayload()));
|
|
28805
28840
|
ws.on("message", (data) => {
|
|
28806
28841
|
try {
|
|
28807
28842
|
const msg = JSON.parse(data.toString());
|
|
@@ -28999,7 +29034,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
28999
29034
|
tools: [
|
|
29000
29035
|
{
|
|
29001
29036
|
name: "inspect_page",
|
|
29002
|
-
description: "\
|
|
29037
|
+
description: "\u9875\u9762\u5206\u6790\u5165\u53E3\u3002\u8FD4\u56DE\u9875\u9762\u5143\u6570\u636E\u3001\u7ED3\u6784\u5316\u6458\u8981\u548C\u53EF\u4EA4\u4E92\u5143\u7D20\u6982\u89C8\uFF0C\u9002\u5408\u5148\u5FEB\u901F\u4E86\u89E3\u5F53\u524D\u9875\u9762\u3002",
|
|
29003
29038
|
inputSchema: {
|
|
29004
29039
|
type: "object",
|
|
29005
29040
|
properties: {
|
|
@@ -29023,9 +29058,41 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29023
29058
|
description: "\u83B7\u53D6 ghost-bridge \u670D\u52A1\u5668\u72B6\u6001\uFF0C\u5305\u62EC\u5F53\u524D WebSocket \u7AEF\u53E3\u3001\u8FDE\u63A5\u72B6\u6001\u7B49",
|
|
29024
29059
|
inputSchema: { type: "object", properties: {} }
|
|
29025
29060
|
},
|
|
29061
|
+
{
|
|
29062
|
+
name: "list_tabs",
|
|
29063
|
+
description: "\u5217\u51FA\u5F53\u524D Chrome \u6807\u7B7E\u9875\uFF0C\u5E76\u8FD4\u56DE Ghost Bridge \u5F53\u524D\u76EE\u6807\u6A21\u5F0F\u4E0E\u76EE\u6807\u6807\u7B7E\u9875\u3002",
|
|
29064
|
+
inputSchema: { type: "object", properties: {} }
|
|
29065
|
+
},
|
|
29066
|
+
{
|
|
29067
|
+
name: "get_target_tab",
|
|
29068
|
+
description: "\u67E5\u770B Ghost Bridge \u5F53\u524D\u64CD\u4F5C\u76EE\u6807\u3002\u76EE\u6807\u6A21\u5F0F\u4E3A focused \u65F6\u8DDF\u968F\u5F53\u524D\u805A\u7126\u6807\u7B7E\u9875\uFF1Bpinned \u65F6\u9501\u5B9A\u6307\u5B9A\u6807\u7B7E\u9875\u3002",
|
|
29069
|
+
inputSchema: { type: "object", properties: {} }
|
|
29070
|
+
},
|
|
29071
|
+
{
|
|
29072
|
+
name: "pin_current_tab",
|
|
29073
|
+
description: "\u9501\u5B9A\u5F53\u524D\u805A\u7126\u7684 Chrome \u6807\u7B7E\u9875\u3002\u9501\u5B9A\u540E\u7528\u6237\u5207\u6362\u5230\u5176\u4ED6\u9875\u9762\u4E5F\u4E0D\u4F1A\u6539\u53D8 Ghost Bridge \u7684\u64CD\u4F5C\u76EE\u6807\u3002",
|
|
29074
|
+
inputSchema: { type: "object", properties: {} }
|
|
29075
|
+
},
|
|
29076
|
+
{
|
|
29077
|
+
name: "pin_tab",
|
|
29078
|
+
description: "\u6309 tabId\u3001URL \u7247\u6BB5\u6216\u6807\u9898\u7247\u6BB5\u9501\u5B9A Chrome \u6807\u7B7E\u9875\u3002",
|
|
29079
|
+
inputSchema: {
|
|
29080
|
+
type: "object",
|
|
29081
|
+
properties: {
|
|
29082
|
+
tabId: { type: "number", description: "Chrome \u6807\u7B7E\u9875 ID\uFF0C\u4F18\u5148\u4F7F\u7528" },
|
|
29083
|
+
urlContains: { type: "string", description: "URL \u7247\u6BB5\u3002\u672A\u63D0\u4F9B tabId \u65F6\u6309\u5B83\u5339\u914D" },
|
|
29084
|
+
titleContains: { type: "string", description: "\u6807\u9898\u7247\u6BB5\u3002\u53EF\u4E0E urlContains \u540C\u65F6\u4F7F\u7528" }
|
|
29085
|
+
}
|
|
29086
|
+
}
|
|
29087
|
+
},
|
|
29088
|
+
{
|
|
29089
|
+
name: "unpin_tab",
|
|
29090
|
+
description: "\u89E3\u9664\u9501\u5B9A\uFF0C\u6062\u590D\u8DDF\u968F\u5F53\u524D\u805A\u7126\u6807\u7B7E\u9875\u3002",
|
|
29091
|
+
inputSchema: { type: "object", properties: {} }
|
|
29092
|
+
},
|
|
29026
29093
|
{
|
|
29027
29094
|
name: "get_last_error",
|
|
29028
|
-
description: "\u83B7\u53D6\
|
|
29095
|
+
description: "\u83B7\u53D6\u76EE\u6807\u6807\u7B7E\u9875\u6700\u8FD1\u7684\u63A7\u5236\u53F0\u3001\u5F02\u5E38\u548C\u7F51\u7EDC\u9519\u8BEF\u4E8B\u4EF6\u3002\u9ED8\u8BA4\u53EA\u8FD4\u56DE error\uFF1B\u5982\u9700\u67E5\u770B console.log / console.warn\uFF0C\u8BF7\u4F20 severity=info / warn / all\u3002",
|
|
29029
29096
|
inputSchema: {
|
|
29030
29097
|
type: "object",
|
|
29031
29098
|
properties: {
|
|
@@ -29043,7 +29110,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29043
29110
|
},
|
|
29044
29111
|
{
|
|
29045
29112
|
name: "get_script_source",
|
|
29046
|
-
description: "\u6293\u53D6\u76EE\u6807\u811A\u672C\u6E90\u7801\
|
|
29113
|
+
description: "\u6293\u53D6\u76EE\u6807\u6807\u7B7E\u9875\u7684\u811A\u672C\u6E90\u7801\u7247\u6BB5\uFF0C\u652F\u6301\u6309 URL \u7247\u6BB5\u7B5B\u9009\u548C\u53EF\u9009 beautify\u3002",
|
|
29047
29114
|
inputSchema: {
|
|
29048
29115
|
type: "object",
|
|
29049
29116
|
properties: {
|
|
@@ -29067,7 +29134,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29067
29134
|
},
|
|
29068
29135
|
{
|
|
29069
29136
|
name: "find_by_string",
|
|
29070
|
-
description: "\u5728\
|
|
29137
|
+
description: "\u5728\u76EE\u6807\u6807\u7B7E\u9875\u811A\u672C\u5185\u6309\u5B57\u7B26\u4E32\u641C\u7D22\uFF0C\u8FD4\u56DE\u5339\u914D\u4E0A\u4E0B\u6587\u3002",
|
|
29071
29138
|
inputSchema: {
|
|
29072
29139
|
type: "object",
|
|
29073
29140
|
properties: {
|
|
@@ -29085,7 +29152,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29085
29152
|
},
|
|
29086
29153
|
{
|
|
29087
29154
|
name: "eval_script",
|
|
29088
|
-
description: "\u5728\
|
|
29155
|
+
description: "\u5728\u76EE\u6807\u6807\u7B7E\u9875\u6267\u884C\u53EA\u8BFB JS \u8868\u8FBE\u5F0F\uFF08\u8C28\u614E\u4F7F\u7528\uFF09",
|
|
29089
29156
|
inputSchema: {
|
|
29090
29157
|
type: "object",
|
|
29091
29158
|
properties: { code: { type: "string" } },
|
|
@@ -29094,7 +29161,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29094
29161
|
},
|
|
29095
29162
|
{
|
|
29096
29163
|
name: "list_network_requests",
|
|
29097
|
-
description: "\u5217\u51FA\u6355\u83B7\u7684\u7F51\u7EDC\u8BF7\u6C42\uFF0C\u652F\u6301\u6309 URL\u3001\u65B9\u6CD5\u3001\u72B6\u6001\
|
|
29164
|
+
description: "\u5217\u51FA\u76EE\u6807\u6807\u7B7E\u9875\u6355\u83B7\u7684\u7F51\u7EDC\u8BF7\u6C42\uFF0C\u652F\u6301\u6309 URL\u3001\u65B9\u6CD5\u3001\u72B6\u6001\u548C\u7C7B\u578B\u8FC7\u6EE4\u3002\u9ED8\u8BA4\u6309\u6392\u969C\u4F18\u5148\u7EA7\u6392\u5E8F\uFF1Bdata URL \u548C\u8D85\u957F URL \u4F1A\u81EA\u52A8\u6458\u8981\u5316\u3002",
|
|
29098
29165
|
inputSchema: {
|
|
29099
29166
|
type: "object",
|
|
29100
29167
|
properties: {
|
|
@@ -29113,7 +29180,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29113
29180
|
},
|
|
29114
29181
|
{
|
|
29115
29182
|
name: "get_network_detail",
|
|
29116
|
-
description: "\u83B7\u53D6\u5355\u4E2A\u7F51\u7EDC\u8BF7\u6C42\
|
|
29183
|
+
description: "\u83B7\u53D6\u5355\u4E2A\u7F51\u7EDC\u8BF7\u6C42\u8BE6\u60C5\uFF0C\u5305\u62EC\u8BF7\u6C42\u5934\u3001\u54CD\u5E94\u5934\u548C\u53EF\u9009\u54CD\u5E94\u4F53\uFF1B\u8D85\u957F URL \u4F1A\u81EA\u52A8\u6458\u8981\u5316\u3002",
|
|
29117
29184
|
inputSchema: {
|
|
29118
29185
|
type: "object",
|
|
29119
29186
|
properties: {
|
|
@@ -29130,7 +29197,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29130
29197
|
},
|
|
29131
29198
|
{
|
|
29132
29199
|
name: "perf_metrics",
|
|
29133
|
-
description: "\u83B7\u53D6\u9875\u9762\u6027\u80FD\u6307\u6807\
|
|
29200
|
+
description: "\u83B7\u53D6\u9875\u9762\u6027\u80FD\u6307\u6807\uFF0C\u5305\u62EC\u5F15\u64CE\u7EA7\u6307\u6807\u3001Web Vitals \u548C\u8D44\u6E90\u52A0\u8F7D\u6458\u8981\u3002",
|
|
29134
29201
|
inputSchema: {
|
|
29135
29202
|
type: "object",
|
|
29136
29203
|
properties: {
|
|
@@ -29147,7 +29214,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29147
29214
|
},
|
|
29148
29215
|
{
|
|
29149
29216
|
name: "capture_screenshot",
|
|
29150
|
-
description: "\
|
|
29217
|
+
description: "\u622A\u53D6\u76EE\u6807\u6807\u7B7E\u9875\u622A\u56FE\uFF0C\u9002\u5408\u770B\u9875\u9762\u5B9E\u9645\u89C6\u89C9\u6548\u679C\u3001UI \u6837\u5F0F\u548C\u5E03\u5C40\u3002\u9ED8\u8BA4\u4F18\u5148\u4F7F\u7528 JPEG\uFF1B\u9700\u8981\u6587\u5B57\u3001\u7EC6\u7EBF\u6216\u900F\u660E\u80CC\u666F\u7EC6\u8282\u65F6\u6539\u7528 PNG\u3002",
|
|
29151
29218
|
inputSchema: {
|
|
29152
29219
|
type: "object",
|
|
29153
29220
|
properties: {
|
|
@@ -29179,7 +29246,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29179
29246
|
},
|
|
29180
29247
|
{
|
|
29181
29248
|
name: "get_page_content",
|
|
29182
|
-
description: "\
|
|
29249
|
+
description: "\u63D0\u53D6\u76EE\u6807\u6807\u7B7E\u9875\u7684\u6587\u672C\u3001HTML \u6216\u7ED3\u6784\u5316\u6570\u636E\u3002\u6BD4\u622A\u56FE\u66F4\u8F7B\u91CF\uFF0C\u9002\u5408\u5148\u770B\u6587\u5B57\u3001DOM \u7ED3\u6784\u548C\u9875\u9762\u5143\u6570\u636E\uFF1B\u4E0D\u53CD\u6620 CSS\uFF0C\u4E5F\u4E0D\u542B iframe \u5185\u5BB9\u3002",
|
|
29183
29250
|
inputSchema: {
|
|
29184
29251
|
type: "object",
|
|
29185
29252
|
properties: {
|
|
@@ -29205,7 +29272,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29205
29272
|
},
|
|
29206
29273
|
{
|
|
29207
29274
|
name: "get_interactive_snapshot",
|
|
29208
|
-
description: "\
|
|
29275
|
+
description: "\u626B\u63CF\u5F53\u524D\u9875\u9762\u53EF\u89C1\u7684\u53EF\u4EA4\u4E92\u5143\u7D20\uFF0C\u8FD4\u56DE\u5E26 ref \u7684\u7CBE\u7B80\u5217\u8868\uFF0C\u4F9B\u540E\u7EED dispatch_action \u4F7F\u7528\u3002\u652F\u6301 Shadow DOM\uFF1B\u4EC5\u7528\u4E8E\u4EA4\u4E92\u5B9A\u4F4D\u3002",
|
|
29209
29276
|
inputSchema: {
|
|
29210
29277
|
type: "object",
|
|
29211
29278
|
properties: {
|
|
@@ -29226,7 +29293,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29226
29293
|
},
|
|
29227
29294
|
{
|
|
29228
29295
|
name: "dispatch_action",
|
|
29229
|
-
description: "\
|
|
29296
|
+
description: "\u5BF9 get_interactive_snapshot \u8FD4\u56DE\u7684\u5143\u7D20\u6267\u884C\u70B9\u51FB\u3001\u8F93\u5165\u3001\u6309\u952E\u3001\u6EDA\u52A8\u3001\u9009\u62E9\u3001\u60AC\u505C\u6216\u805A\u7126\u3002\u26A0\uFE0F \u4F7F\u7528\u524D\u5FC5\u987B\u5148\u8C03\u7528 get_interactive_snapshot \u83B7\u53D6 ref\uFF1B\u64CD\u4F5C\u540E\u5EFA\u8BAE\u518D\u9A8C\u8BC1\u9875\u9762\u72B6\u6001\u3002",
|
|
29230
29297
|
inputSchema: {
|
|
29231
29298
|
type: "object",
|
|
29232
29299
|
properties: {
|
|
@@ -29305,13 +29372,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29305
29372
|
};
|
|
29306
29373
|
}
|
|
29307
29374
|
if (name === "get_server_info") {
|
|
29308
|
-
let chromeOk, clientsCount;
|
|
29375
|
+
let chromeOk, clientsCount, mainStatus;
|
|
29309
29376
|
if (isMainInstance) {
|
|
29310
29377
|
chromeOk = !!chromeConnection;
|
|
29311
29378
|
clientsCount = mcpClients.size;
|
|
29379
|
+
mainStatus = {
|
|
29380
|
+
pid: process.pid,
|
|
29381
|
+
version: GHOST_BRIDGE_VERSION,
|
|
29382
|
+
serverPath: SERVER_ENTRY_PATH,
|
|
29383
|
+
startedAt: SERVER_STARTED_AT
|
|
29384
|
+
};
|
|
29312
29385
|
} else {
|
|
29313
29386
|
try {
|
|
29314
|
-
|
|
29387
|
+
mainStatus = await askMainInstance("_getMainStatus");
|
|
29315
29388
|
chromeOk = mainStatus.chromeConnected;
|
|
29316
29389
|
clientsCount = mainStatus.mcpClientsCount;
|
|
29317
29390
|
} catch {
|
|
@@ -29330,6 +29403,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29330
29403
|
wsPort: actualPort,
|
|
29331
29404
|
wsUrl: `ws://localhost:${actualPort}`,
|
|
29332
29405
|
pid: process.pid,
|
|
29406
|
+
serverPath: SERVER_ENTRY_PATH,
|
|
29407
|
+
mainPid: mainStatus?.pid,
|
|
29408
|
+
mainVersion: mainStatus?.version,
|
|
29409
|
+
mainServerPath: mainStatus?.serverPath,
|
|
29410
|
+
mainStartedAt: mainStatus?.startedAt,
|
|
29333
29411
|
chromeConnected: chromeOk,
|
|
29334
29412
|
mcpClientsCount: clientsCount,
|
|
29335
29413
|
portInfoFile: PORT_INFO_FILE,
|
|
@@ -29339,6 +29417,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29339
29417
|
]
|
|
29340
29418
|
};
|
|
29341
29419
|
}
|
|
29420
|
+
if (name === "list_tabs") {
|
|
29421
|
+
const res = await askChrome("listTabs");
|
|
29422
|
+
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29423
|
+
}
|
|
29424
|
+
if (name === "get_target_tab") {
|
|
29425
|
+
const res = await askChrome("getTargetTab");
|
|
29426
|
+
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29427
|
+
}
|
|
29428
|
+
if (name === "pin_current_tab") {
|
|
29429
|
+
const res = await askChrome("pinCurrentTab", {}, { timeoutMs: 1e4 });
|
|
29430
|
+
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29431
|
+
}
|
|
29432
|
+
if (name === "pin_tab") {
|
|
29433
|
+
const { tabId, urlContains, titleContains } = args;
|
|
29434
|
+
const res = await askChrome("pinTab", { tabId, urlContains, titleContains }, { timeoutMs: 1e4 });
|
|
29435
|
+
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29436
|
+
}
|
|
29437
|
+
if (name === "unpin_tab") {
|
|
29438
|
+
const res = await askChrome("unpinTab", {}, { timeoutMs: 1e4 });
|
|
29439
|
+
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29440
|
+
}
|
|
29342
29441
|
if (name === "get_last_error") {
|
|
29343
29442
|
const { severity = "error", limit = 20 } = args;
|
|
29344
29443
|
const data = await askChrome("getLastError", { severity, limit });
|