ghost-bridge 0.4.0 → 0.5.1
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 +160 -133
- package/dist/cli.js +649 -448
- package/dist/server.js +136 -42
- package/extension/background.js +257 -51
- 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 +2 -2
- package/extension/offscreen.js +1 -1
- package/extension/popup.html +388 -86
- package/extension/popup.js +128 -53
- package/package.json +25 -2
package/dist/server.js
CHANGED
|
@@ -3228,8 +3228,8 @@ var require_utils = __commonJS({
|
|
|
3228
3228
|
}
|
|
3229
3229
|
return ind;
|
|
3230
3230
|
}
|
|
3231
|
-
function removeDotSegments(
|
|
3232
|
-
let input =
|
|
3231
|
+
function removeDotSegments(path3) {
|
|
3232
|
+
let input = path3;
|
|
3233
3233
|
const output = [];
|
|
3234
3234
|
let nextSlash = -1;
|
|
3235
3235
|
let len = 0;
|
|
@@ -3428,8 +3428,8 @@ var require_schemes = __commonJS({
|
|
|
3428
3428
|
wsComponent.secure = void 0;
|
|
3429
3429
|
}
|
|
3430
3430
|
if (wsComponent.resourceName) {
|
|
3431
|
-
const [
|
|
3432
|
-
wsComponent.path =
|
|
3431
|
+
const [path3, query] = wsComponent.resourceName.split("?");
|
|
3432
|
+
wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
|
|
3433
3433
|
wsComponent.query = query;
|
|
3434
3434
|
wsComponent.resourceName = void 0;
|
|
3435
3435
|
}
|
|
@@ -6782,12 +6782,12 @@ var require_dist = __commonJS({
|
|
|
6782
6782
|
throw new Error(`Unknown format "${name}"`);
|
|
6783
6783
|
return f;
|
|
6784
6784
|
};
|
|
6785
|
-
function addFormats(ajv, list,
|
|
6785
|
+
function addFormats(ajv, list, fs3, exportName) {
|
|
6786
6786
|
var _a2;
|
|
6787
6787
|
var _b;
|
|
6788
6788
|
(_a2 = (_b = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
6789
6789
|
for (const f of list)
|
|
6790
|
-
ajv.addFormat(f,
|
|
6790
|
+
ajv.addFormat(f, fs3[f]);
|
|
6791
6791
|
}
|
|
6792
6792
|
module.exports = exports = formatsPlugin;
|
|
6793
6793
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -15012,8 +15012,8 @@ function getErrorMap() {
|
|
|
15012
15012
|
|
|
15013
15013
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
15014
15014
|
var makeIssue = (params) => {
|
|
15015
|
-
const { data, path:
|
|
15016
|
-
const fullPath = [...
|
|
15015
|
+
const { data, path: path3, errorMaps, issueData } = params;
|
|
15016
|
+
const fullPath = [...path3, ...issueData.path || []];
|
|
15017
15017
|
const fullIssue = {
|
|
15018
15018
|
...issueData,
|
|
15019
15019
|
path: fullPath
|
|
@@ -15128,11 +15128,11 @@ var errorUtil;
|
|
|
15128
15128
|
|
|
15129
15129
|
// node_modules/zod/v3/types.js
|
|
15130
15130
|
var ParseInputLazyPath = class {
|
|
15131
|
-
constructor(parent, value,
|
|
15131
|
+
constructor(parent, value, path3, key) {
|
|
15132
15132
|
this._cachedPath = [];
|
|
15133
15133
|
this.parent = parent;
|
|
15134
15134
|
this.data = value;
|
|
15135
|
-
this._path =
|
|
15135
|
+
this._path = path3;
|
|
15136
15136
|
this._key = key;
|
|
15137
15137
|
}
|
|
15138
15138
|
get path() {
|
|
@@ -18776,10 +18776,10 @@ function mergeDefs(...defs) {
|
|
|
18776
18776
|
function cloneDef(schema) {
|
|
18777
18777
|
return mergeDefs(schema._zod.def);
|
|
18778
18778
|
}
|
|
18779
|
-
function getElementAtPath(obj,
|
|
18780
|
-
if (!
|
|
18779
|
+
function getElementAtPath(obj, path3) {
|
|
18780
|
+
if (!path3)
|
|
18781
18781
|
return obj;
|
|
18782
|
-
return
|
|
18782
|
+
return path3.reduce((acc, key) => acc?.[key], obj);
|
|
18783
18783
|
}
|
|
18784
18784
|
function promiseAllObject(promisesObj) {
|
|
18785
18785
|
const keys = Object.keys(promisesObj);
|
|
@@ -19162,11 +19162,11 @@ function aborted(x, startIndex = 0) {
|
|
|
19162
19162
|
}
|
|
19163
19163
|
return false;
|
|
19164
19164
|
}
|
|
19165
|
-
function prefixIssues(
|
|
19165
|
+
function prefixIssues(path3, issues) {
|
|
19166
19166
|
return issues.map((iss) => {
|
|
19167
19167
|
var _a2;
|
|
19168
19168
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
19169
|
-
iss.path.unshift(
|
|
19169
|
+
iss.path.unshift(path3);
|
|
19170
19170
|
return iss;
|
|
19171
19171
|
});
|
|
19172
19172
|
}
|
|
@@ -28520,9 +28520,21 @@ var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
|
28520
28520
|
var import_js_beautify = __toESM(require_js(), 1);
|
|
28521
28521
|
import crypto from "crypto";
|
|
28522
28522
|
import net from "net";
|
|
28523
|
-
import
|
|
28523
|
+
import fs2 from "fs";
|
|
28524
28524
|
import os from "os";
|
|
28525
|
+
import path2 from "path";
|
|
28526
|
+
|
|
28527
|
+
// lib/version.js
|
|
28528
|
+
import fs from "fs";
|
|
28525
28529
|
import path from "path";
|
|
28530
|
+
import { fileURLToPath } from "url";
|
|
28531
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
28532
|
+
var __dirname = path.dirname(__filename);
|
|
28533
|
+
var packageJsonPath = path.resolve(__dirname, "../package.json");
|
|
28534
|
+
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
28535
|
+
var GHOST_BRIDGE_VERSION = packageJson.version;
|
|
28536
|
+
|
|
28537
|
+
// src/server.js
|
|
28526
28538
|
var BASE_PORT = Number(process.env.GHOST_BRIDGE_PORT || 33333);
|
|
28527
28539
|
var MAX_PORT_RETRIES = 10;
|
|
28528
28540
|
function getMonthlyToken() {
|
|
@@ -28532,7 +28544,7 @@ function getMonthlyToken() {
|
|
|
28532
28544
|
}
|
|
28533
28545
|
var WS_TOKEN = process.env.GHOST_BRIDGE_TOKEN || getMonthlyToken();
|
|
28534
28546
|
var RESPONSE_TIMEOUT = 8e3;
|
|
28535
|
-
var PORT_INFO_FILE =
|
|
28547
|
+
var PORT_INFO_FILE = path2.join(os.tmpdir(), "ghost-bridge-port.json");
|
|
28536
28548
|
var chromeConnection = null;
|
|
28537
28549
|
var activeConnection = null;
|
|
28538
28550
|
var actualPort = BASE_PORT;
|
|
@@ -28552,12 +28564,12 @@ function isProcessRunning(pid) {
|
|
|
28552
28564
|
}
|
|
28553
28565
|
function getExistingService() {
|
|
28554
28566
|
try {
|
|
28555
|
-
if (!
|
|
28556
|
-
const info = JSON.parse(
|
|
28567
|
+
if (!fs2.existsSync(PORT_INFO_FILE)) return null;
|
|
28568
|
+
const info = JSON.parse(fs2.readFileSync(PORT_INFO_FILE, "utf-8"));
|
|
28557
28569
|
if (!info.pid || !info.port) return null;
|
|
28558
28570
|
if (!isProcessRunning(info.pid)) {
|
|
28559
28571
|
log(`\u65E7\u670D\u52A1 PID ${info.pid} \u5DF2\u4E0D\u5B58\u5728\uFF0C\u6E05\u7406\u65E7\u4FE1\u606F`);
|
|
28560
|
-
|
|
28572
|
+
fs2.unlinkSync(PORT_INFO_FILE);
|
|
28561
28573
|
return null;
|
|
28562
28574
|
}
|
|
28563
28575
|
return info;
|
|
@@ -28636,14 +28648,14 @@ async function initWebSocketService() {
|
|
|
28636
28648
|
} else {
|
|
28637
28649
|
log(`\u274C \u73B0\u6709\u670D\u52A1\u9A8C\u8BC1\u5931\u8D25\uFF0C\u542F\u52A8\u65B0\u670D\u52A1...`);
|
|
28638
28650
|
try {
|
|
28639
|
-
|
|
28651
|
+
fs2.unlinkSync(PORT_INFO_FILE);
|
|
28640
28652
|
} catch {
|
|
28641
28653
|
}
|
|
28642
28654
|
}
|
|
28643
28655
|
}
|
|
28644
28656
|
const wss2 = await startWebSocketServer();
|
|
28645
28657
|
isMainInstance = true;
|
|
28646
|
-
|
|
28658
|
+
fs2.writeFileSync(
|
|
28647
28659
|
PORT_INFO_FILE,
|
|
28648
28660
|
JSON.stringify({
|
|
28649
28661
|
port: actualPort,
|
|
@@ -28858,7 +28870,7 @@ async function askChrome(command, params = {}, options = {}) {
|
|
|
28858
28870
|
});
|
|
28859
28871
|
}
|
|
28860
28872
|
function jsonText(data) {
|
|
28861
|
-
return typeof data === "string" ? data : JSON.stringify(data
|
|
28873
|
+
return typeof data === "string" ? data : JSON.stringify(data);
|
|
28862
28874
|
}
|
|
28863
28875
|
function buildSnippet(source, line, column, { beautifyEnabled = true, contextLines = 20 } = {}) {
|
|
28864
28876
|
const result = {};
|
|
@@ -28896,11 +28908,32 @@ function buildSnippet(source, line, column, { beautifyEnabled = true, contextLin
|
|
|
28896
28908
|
return result;
|
|
28897
28909
|
}
|
|
28898
28910
|
var server = new Server(
|
|
28899
|
-
{ name: "ghost-bridge", version:
|
|
28911
|
+
{ name: "ghost-bridge", version: GHOST_BRIDGE_VERSION },
|
|
28900
28912
|
{ capabilities: { tools: {} } }
|
|
28901
28913
|
);
|
|
28902
28914
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
28903
28915
|
tools: [
|
|
28916
|
+
{
|
|
28917
|
+
name: "inspect_page",
|
|
28918
|
+
description: "\u3010\u9875\u9762\u5206\u6790\u5165\u53E3\u3011\u5F53\u7528\u6237\u8981\u6C42\u5206\u6790\u5F53\u524D\u9875\u9762/\u7F51\u7AD9/\u7F51\u9875\u3001\u7406\u89E3\u9875\u9762\u7ED3\u6784\u3001\u5FEB\u901F\u67E5\u770B\u5F53\u524D\u6807\u7B7E\u5185\u5BB9\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u65E0\u9700\u7528\u6237\u663E\u5F0F\u63D0\u5230 ghost-bridge\u3002\u9ED8\u8BA4\u8FD4\u56DE\u9875\u9762\u5143\u6570\u636E\u3001\u7ED3\u6784\u5316\u5185\u5BB9\u6458\u8981\u548C\u53EF\u4EA4\u4E92\u5143\u7D20\u6982\u89C8\uFF0C\u9002\u5408\u4F5C\u4E3A\u540E\u7EED\u622A\u56FE\u3001\u4EA4\u4E92\u3001\u7F51\u7EDC\u6392\u67E5\u524D\u7684\u7B2C\u4E00\u6B65\u3002",
|
|
28919
|
+
inputSchema: {
|
|
28920
|
+
type: "object",
|
|
28921
|
+
properties: {
|
|
28922
|
+
selector: {
|
|
28923
|
+
type: "string",
|
|
28924
|
+
description: "CSS \u9009\u62E9\u5668\uFF0C\u9650\u5B9A\u5206\u6790\u8303\u56F4\u3002\u4E0D\u6307\u5B9A\u5219\u5206\u6790\u6574\u4E2A\u9875\u9762"
|
|
28925
|
+
},
|
|
28926
|
+
includeInteractive: {
|
|
28927
|
+
type: "boolean",
|
|
28928
|
+
description: "\u662F\u5426\u5305\u542B\u4EA4\u4E92\u5143\u7D20\u6982\u89C8\uFF0C\u9ED8\u8BA4 true"
|
|
28929
|
+
},
|
|
28930
|
+
maxElements: {
|
|
28931
|
+
type: "number",
|
|
28932
|
+
description: "\u4EA4\u4E92\u5143\u7D20\u6982\u89C8\u7684\u6700\u5927\u6570\u91CF\uFF0C\u9ED8\u8BA4 30"
|
|
28933
|
+
}
|
|
28934
|
+
}
|
|
28935
|
+
}
|
|
28936
|
+
},
|
|
28904
28937
|
{
|
|
28905
28938
|
name: "get_server_info",
|
|
28906
28939
|
description: "\u83B7\u53D6 ghost-bridge \u670D\u52A1\u5668\u72B6\u6001\uFF0C\u5305\u62EC\u5F53\u524D WebSocket \u7AEF\u53E3\u3001\u8FDE\u63A5\u72B6\u6001\u7B49",
|
|
@@ -28908,8 +28941,21 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
28908
28941
|
},
|
|
28909
28942
|
{
|
|
28910
28943
|
name: "get_last_error",
|
|
28911
|
-
description: "\u83B7\u53D6\u5F53\u524D\u6807\u7B7E\u6700\u8FD1\u7684\u5F02\u5E38/\u62A5\u9519\u5806\u6808\u4E0E\u5143\u6570\u636E\uFF08\u65E0 sourcemap \u53CB\u597D\uFF09",
|
|
28912
|
-
inputSchema: {
|
|
28944
|
+
description: "\u83B7\u53D6\u5F53\u524D\u6807\u7B7E\u6700\u8FD1\u7684\u5F02\u5E38/\u62A5\u9519\u5806\u6808\u4E0E\u5143\u6570\u636E\uFF08\u65E0 sourcemap \u53CB\u597D\uFF09\u3002\u9ED8\u8BA4\u53EA\u8FD4\u56DE error \u7EA7\u522B\u7684\u6700\u8FD1 20 \u6761\u3002",
|
|
28945
|
+
inputSchema: {
|
|
28946
|
+
type: "object",
|
|
28947
|
+
properties: {
|
|
28948
|
+
severity: {
|
|
28949
|
+
type: "string",
|
|
28950
|
+
enum: ["error", "warn", "info", "all"],
|
|
28951
|
+
description: "\u65E5\u5FD7\u7EA7\u522B\u8FC7\u6EE4\uFF0C\u9ED8\u8BA4 error"
|
|
28952
|
+
},
|
|
28953
|
+
limit: {
|
|
28954
|
+
type: "number",
|
|
28955
|
+
description: "\u8FD4\u56DE\u6761\u6570\u9650\u5236\uFF0C\u9ED8\u8BA4 20\uFF0C\u6700\u5927 100"
|
|
28956
|
+
}
|
|
28957
|
+
}
|
|
28958
|
+
}
|
|
28913
28959
|
},
|
|
28914
28960
|
{
|
|
28915
28961
|
name: "get_script_source",
|
|
@@ -28964,7 +29010,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
28964
29010
|
},
|
|
28965
29011
|
{
|
|
28966
29012
|
name: "list_network_requests",
|
|
28967
|
-
description: "\u5217\u51FA\u6355\u83B7\u7684\u7F51\u7EDC\u8BF7\u6C42\uFF0C\u652F\u6301\u6309 URL\u3001\u65B9\u6CD5\u3001\u72B6\u6001\u3001\u7C7B\u578B\u8FC7\u6EE4",
|
|
29013
|
+
description: "\u5217\u51FA\u6355\u83B7\u7684\u7F51\u7EDC\u8BF7\u6C42\uFF0C\u652F\u6301\u6309 URL\u3001\u65B9\u6CD5\u3001\u72B6\u6001\u3001\u7C7B\u578B\u8FC7\u6EE4\u3002\u9ED8\u8BA4\u6309\u6392\u969C\u4F18\u5148\u7EA7\u6392\u5E8F\uFF1A\u5931\u8D25\u8BF7\u6C42\u3001\u8FDB\u884C\u4E2D\u8BF7\u6C42\u3001XHR/Fetch \u4F1A\u4F18\u5148\u5C55\u793A\u3002",
|
|
28968
29014
|
inputSchema: {
|
|
28969
29015
|
type: "object",
|
|
28970
29016
|
properties: {
|
|
@@ -28972,7 +29018,12 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
28972
29018
|
method: { type: "string", description: "\u8BF7\u6C42\u65B9\u6CD5\uFF1AGET/POST/PUT/DELETE \u7B49" },
|
|
28973
29019
|
status: { type: "string", description: "\u72B6\u6001\uFF1Asuccess/error/failed/pending" },
|
|
28974
29020
|
resourceType: { type: "string", description: "\u8D44\u6E90\u7C7B\u578B\uFF1AXHR/Fetch/Script/Image \u7B49" },
|
|
28975
|
-
limit: { type: "number", description: "\u8FD4\u56DE\u6570\u91CF\u9650\u5236\uFF0C\u9ED8\u8BA4 50" }
|
|
29021
|
+
limit: { type: "number", description: "\u8FD4\u56DE\u6570\u91CF\u9650\u5236\uFF0C\u9ED8\u8BA4 50" },
|
|
29022
|
+
priorityMode: {
|
|
29023
|
+
type: "string",
|
|
29024
|
+
enum: ["debug", "api", "recent"],
|
|
29025
|
+
description: "\u6392\u5E8F\u6A21\u5F0F\uFF1Adebug=\u6392\u969C\u4F18\u5148\uFF08\u9ED8\u8BA4\uFF09\uFF0Capi=\u63A5\u53E3\u4F18\u5148\uFF0Crecent=\u6309\u65F6\u95F4\u5012\u5E8F"
|
|
29026
|
+
}
|
|
28976
29027
|
}
|
|
28977
29028
|
}
|
|
28978
29029
|
},
|
|
@@ -29012,7 +29063,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29012
29063
|
},
|
|
29013
29064
|
{
|
|
29014
29065
|
name: "capture_screenshot",
|
|
29015
|
-
description: "\u3010\u63A8\u8350\u7528\u4E8E\u89C6\u89C9\u5206\u6790\u3011\u622A\u53D6\u5F53\u524D\u9875\u9762\u7684\u622A\u56FE\uFF0C\u8FD4\u56DE base64 \u56FE\u7247\u3002\u9002\u7528\u4E8E\uFF1A1) \u67E5\u770B\u9875\u9762\u5B9E\u9645\u89C6\u89C9\u6548\u679C 2) \u6392\u67E5 UI/\u6837\u5F0F/\u5E03\u5C40/\u989C\u8272\u95EE\u9898 3) \u9A8C\u8BC1\u9875\u9762\u6E32\u67D3 4) \u5206\u6790\u5143\u7D20\u4F4D\u7F6E\u548C\u95F4\u8DDD 5) \u67E5\u770B\u56FE\u7247/\u56FE\u6807\u7B49\u89C6\u89C9\u5185\u5BB9\u3002\u5F53\u9700\u8981\u770B\u5230\u9875\u9762\u300C\u957F\u4EC0\u4E48\u6837\u300D\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u5982\u4EC5\u9700\u6587\u672C/\u94FE\u63A5\u7B49\u4FE1\u606F\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u66F4\u5FEB\u7684 get_page_content\u3002",
|
|
29066
|
+
description: "\u3010\u63A8\u8350\u7528\u4E8E\u89C6\u89C9\u5206\u6790\u3011\u622A\u53D6\u5F53\u524D\u9875\u9762\u7684\u622A\u56FE\uFF0C\u8FD4\u56DE base64 \u56FE\u7247\u3002\u9002\u7528\u4E8E\uFF1A1) \u67E5\u770B\u9875\u9762\u5B9E\u9645\u89C6\u89C9\u6548\u679C 2) \u6392\u67E5 UI/\u6837\u5F0F/\u5E03\u5C40/\u989C\u8272\u95EE\u9898 3) \u9A8C\u8BC1\u9875\u9762\u6E32\u67D3 4) \u5206\u6790\u5143\u7D20\u4F4D\u7F6E\u548C\u95F4\u8DDD 5) \u67E5\u770B\u56FE\u7247/\u56FE\u6807\u7B49\u89C6\u89C9\u5185\u5BB9\u3002\u5F53\u7528\u6237\u8BF4\u201C\u770B\u770B\u8FD9\u4E2A\u9875\u9762\u957F\u4EC0\u4E48\u6837\u201D\u201C\u5E2E\u6211\u5206\u6790\u754C\u9762/\u5E03\u5C40/\u6837\u5F0F\u201D\u65F6\uFF0C\u5E94\u4F18\u5148\u4F7F\u7528\u6B64\u5DE5\u5177\uFF0C\u65E0\u9700\u7528\u6237\u663E\u5F0F\u63D0\u5230 ghost-bridge\u3002\u5F53\u9700\u8981\u770B\u5230\u9875\u9762\u300C\u957F\u4EC0\u4E48\u6837\u300D\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u5982\u4EC5\u9700\u6587\u672C/\u94FE\u63A5\u7B49\u4FE1\u606F\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u66F4\u5FEB\u7684 get_page_content\u3002",
|
|
29016
29067
|
inputSchema: {
|
|
29017
29068
|
type: "object",
|
|
29018
29069
|
properties: {
|
|
@@ -29044,7 +29095,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29044
29095
|
},
|
|
29045
29096
|
{
|
|
29046
29097
|
name: "get_page_content",
|
|
29047
|
-
description: "\u3010\u63A8\u8350\u7528\u4E8E\u5FEB\u901F\u83B7\u53D6\u9875\u9762\u5185\u5BB9\u3011\u63D0\u53D6\u5F53\u524D\u9875\u9762\u7684\u6587\u672C\u3001HTML \u6216\u7ED3\u6784\u5316\u6570\u636E\u3002\u6BD4 capture_screenshot \u66F4\u5FEB\u66F4\u8F7B\u91CF\uFF0C\u9002\u7528\u4E8E\uFF1A1) \u83B7\u53D6\u9875\u9762\u6587\u5B57\u5185\u5BB9 2) \u63D0\u53D6\u94FE\u63A5/\u6309\u94AE/\u8868\u5355\u7B49\u5143\u7D20 3) \u5206\u6790 DOM \u7ED3\u6784 4) \u83B7\u53D6\u9875\u9762\u5143\u6570\u636E\uFF08title/description\uFF09\u3002\u5F53\u9700\u8981\u6587\u672C\u4FE1\u606F\u800C\u975E\u89C6\u89C9\u6548\u679C\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u6CE8\u610F\uFF1A\u4E0D\u652F\u6301 iframe \u5185\u5BB9\uFF0C\u4E0D\u53CD\u6620 CSS \u6837\u5F0F\u3002",
|
|
29098
|
+
description: "\u3010\u63A8\u8350\u7528\u4E8E\u5FEB\u901F\u83B7\u53D6\u9875\u9762\u5185\u5BB9\u3011\u63D0\u53D6\u5F53\u524D\u9875\u9762\u7684\u6587\u672C\u3001HTML \u6216\u7ED3\u6784\u5316\u6570\u636E\u3002\u6BD4 capture_screenshot \u66F4\u5FEB\u66F4\u8F7B\u91CF\uFF0C\u9002\u7528\u4E8E\uFF1A1) \u83B7\u53D6\u9875\u9762\u6587\u5B57\u5185\u5BB9 2) \u63D0\u53D6\u94FE\u63A5/\u6309\u94AE/\u8868\u5355\u7B49\u5143\u7D20 3) \u5206\u6790 DOM \u7ED3\u6784 4) \u83B7\u53D6\u9875\u9762\u5143\u6570\u636E\uFF08title/description\uFF09\u3002\u5F53\u7528\u6237\u8BF4\u201C\u5206\u6790\u8FD9\u4E2A\u9875\u9762/\u7F51\u7AD9\u201D\u201C\u770B\u770B\u9875\u9762\u91CC\u6709\u4EC0\u4E48\u5185\u5BB9\u201D\u4E14\u4E0D\u5F3A\u8C03\u89C6\u89C9\u6548\u679C\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u6B64\u5DE5\u5177\uFF0C\u65E0\u9700\u7528\u6237\u663E\u5F0F\u63D0\u5230 ghost-bridge\u3002\u5F53\u9700\u8981\u6587\u672C\u4FE1\u606F\u800C\u975E\u89C6\u89C9\u6548\u679C\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u6B64\u5DE5\u5177\u3002\u6CE8\u610F\uFF1A\u4E0D\u652F\u6301 iframe \u5185\u5BB9\uFF0C\u4E0D\u53CD\u6620 CSS \u6837\u5F0F\u3002",
|
|
29048
29099
|
inputSchema: {
|
|
29049
29100
|
type: "object",
|
|
29050
29101
|
properties: {
|
|
@@ -29070,7 +29121,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29070
29121
|
},
|
|
29071
29122
|
{
|
|
29072
29123
|
name: "get_interactive_snapshot",
|
|
29073
|
-
description: "\u3010\u64CD\u4F5C\u9875\u9762\u524D\u5FC5\u987B\u5148\u8C03\u7528\u3011\u626B\u63CF\u5F53\u524D\u9875\u9762\u6240\u6709\u53EF\u89C1\u7684\u53EF\u4EA4\u4E92\u5143\u7D20\uFF08\u6309\u94AE/\u94FE\u63A5/\u8F93\u5165\u6846/\u4E0B\u62C9\u6846\u7B49\uFF09\uFF0C\u8FD4\u56DE\u5E26\u6709 ref \u77ED\u6807\u8BC6\uFF08\u5982 e1, e2, e3\uFF09\u7684\u7CBE\u7B80\u5217\u8868\uFF0C\u5305\u542B\u5143\u7D20\u7C7B\u578B\u3001\u6587\u672C\u548C\u4F4D\u7F6E\u3002Token \u6781\u7701\uFF08\u901A\u5E38 < 1000 tokens\uFF09\uFF0C\u4E13\u4E3A AI \u64CD\u4F5C\u9875\u9762\u800C\u8BBE\u8BA1\u3002\u83B7\u53D6\u540E\u53EF\u901A\u8FC7 dispatch_action \u5DE5\u5177\u4F7F\u7528 ref \u6807\u8BC6\u6765\u70B9\u51FB\u3001\u586B\u5199\u3001\u6309\u952E\u7B49\u3002\u652F\u6301 Shadow DOM \u7A7F\u900F\u3002\n\u26A0\uFE0F \u4EC5\u7528\u4E8E\u4EA4\u4E92\u64CD\u4F5C\u524D\u7684\u5143\u7D20\u5B9A\u4F4D\u3002\u5982\u9700\u6392\u67E5 UI/CSS \u5E03\u5C40\u95EE\u9898\uFF0C\u8BF7\u4F7F\u7528 capture_screenshot \u6216 get_page_content\u3002",
|
|
29124
|
+
description: "\u3010\u64CD\u4F5C\u9875\u9762\u524D\u5FC5\u987B\u5148\u8C03\u7528\u3011\u626B\u63CF\u5F53\u524D\u9875\u9762\u6240\u6709\u53EF\u89C1\u7684\u53EF\u4EA4\u4E92\u5143\u7D20\uFF08\u6309\u94AE/\u94FE\u63A5/\u8F93\u5165\u6846/\u4E0B\u62C9\u6846\u7B49\uFF09\uFF0C\u8FD4\u56DE\u5E26\u6709 ref \u77ED\u6807\u8BC6\uFF08\u5982 e1, e2, e3\uFF09\u7684\u7CBE\u7B80\u5217\u8868\uFF0C\u5305\u542B\u5143\u7D20\u7C7B\u578B\u3001\u6587\u672C\u548C\u4F4D\u7F6E\u3002Token \u6781\u7701\uFF08\u901A\u5E38 < 1000 tokens\uFF09\uFF0C\u4E13\u4E3A AI \u64CD\u4F5C\u9875\u9762\u800C\u8BBE\u8BA1\u3002\u5F53\u7528\u6237\u8981\u6C42\u70B9\u51FB\u3001\u8F93\u5165\u3001\u767B\u5F55\u3001\u63D0\u4EA4\u8868\u5355\u3001\u6253\u5F00\u83DC\u5355\u7B49\u64CD\u4F5C\u65F6\uFF0C\u5E94\u4E3B\u52A8\u4F7F\u7528\u6B64\u5DE5\u5177\u5F00\u59CB\u5B9A\u4F4D\u5143\u7D20\uFF0C\u65E0\u9700\u7528\u6237\u663E\u5F0F\u63D0\u5230 ghost-bridge\u3002\u83B7\u53D6\u540E\u53EF\u901A\u8FC7 dispatch_action \u5DE5\u5177\u4F7F\u7528 ref \u6807\u8BC6\u6765\u70B9\u51FB\u3001\u586B\u5199\u3001\u6309\u952E\u7B49\u3002\u652F\u6301 Shadow DOM \u7A7F\u900F\u3002\n\u26A0\uFE0F \u4EC5\u7528\u4E8E\u4EA4\u4E92\u64CD\u4F5C\u524D\u7684\u5143\u7D20\u5B9A\u4F4D\u3002\u5982\u9700\u6392\u67E5 UI/CSS \u5E03\u5C40\u95EE\u9898\uFF0C\u8BF7\u4F7F\u7528 capture_screenshot \u6216 get_page_content\u3002",
|
|
29074
29125
|
inputSchema: {
|
|
29075
29126
|
type: "object",
|
|
29076
29127
|
properties: {
|
|
@@ -29091,7 +29142,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
29091
29142
|
},
|
|
29092
29143
|
{
|
|
29093
29144
|
name: "dispatch_action",
|
|
29094
|
-
description: "\u3010\u64CD\u4F5C\u9875\u9762\u5143\u7D20\u3011\u5BF9 get_interactive_snapshot \u8FD4\u56DE\u7684\u5143\u7D20\u6267\u884C\u52A8\u4F5C\u3002\u901A\u8FC7 ref \u6807\u8BC6\uFF08\u5982 e1, e5\uFF09\u7CBE\u51C6\u5B9A\u4F4D\u5143\u7D20\uFF0C\u4F7F\u7528 CDP \u7269\u7406\u7EA7\u6A21\u62DF\u6267\u884C\u64CD\u4F5C\uFF0C\u517C\u5BB9\u6240\u6709\u524D\u7AEF\u6846\u67B6\uFF08React/Vue/Angular\uFF09\uFF0C\u6210\u529F\u7387\u6781\u9AD8\u3002\n\u652F\u6301\u7684\u52A8\u4F5C\uFF1Aclick\uFF08\u70B9\u51FB\uFF09\u3001fill\uFF08\u586B\u5199\u8F93\u5165\u6846\uFF09\u3001press\uFF08\u6309\u952E\u5982 Enter\uFF09\u3001scroll\uFF08\u6EDA\u52A8\uFF09\u3001select\uFF08\u4E0B\u62C9\u9009\u62E9\uFF09\u3001hover\uFF08\u60AC\u505C\uFF09\u3001focus\uFF08\u805A\u7126\uFF09\u3002\n\u26A0\uFE0F \u4F7F\u7528\u524D\u5FC5\u987B\u5148\u8C03\u7528 get_interactive_snapshot \u83B7\u53D6\u5143\u7D20\u5217\u8868\u3002\u64CD\u4F5C\u540E\u5EFA\u8BAE\u7528 capture_screenshot \u6216\u518D\u6B21 get_interactive_snapshot \u9A8C\u8BC1\u7ED3\u679C\u3002",
|
|
29145
|
+
description: "\u3010\u64CD\u4F5C\u9875\u9762\u5143\u7D20\u3011\u5BF9 get_interactive_snapshot \u8FD4\u56DE\u7684\u5143\u7D20\u6267\u884C\u52A8\u4F5C\u3002\u901A\u8FC7 ref \u6807\u8BC6\uFF08\u5982 e1, e5\uFF09\u7CBE\u51C6\u5B9A\u4F4D\u5143\u7D20\uFF0C\u4F7F\u7528 CDP \u7269\u7406\u7EA7\u6A21\u62DF\u6267\u884C\u64CD\u4F5C\uFF0C\u517C\u5BB9\u6240\u6709\u524D\u7AEF\u6846\u67B6\uFF08React/Vue/Angular\uFF09\uFF0C\u6210\u529F\u7387\u6781\u9AD8\u3002\n\u5F53\u7528\u6237\u660E\u786E\u5E0C\u671B\u5728\u9875\u9762\u4E0A\u6267\u884C\u70B9\u51FB\u3001\u8F93\u5165\u3001\u56DE\u8F66\u3001\u6EDA\u52A8\u3001\u9009\u62E9\u7B49\u64CD\u4F5C\u65F6\uFF0C\u5E94\u7ED3\u5408 get_interactive_snapshot \u4E3B\u52A8\u4F7F\u7528\u6B64\u5DE5\u5177\uFF0C\u65E0\u9700\u7528\u6237\u663E\u5F0F\u63D0\u5230 ghost-bridge\u3002\n\u652F\u6301\u7684\u52A8\u4F5C\uFF1Aclick\uFF08\u70B9\u51FB\uFF09\u3001fill\uFF08\u586B\u5199\u8F93\u5165\u6846\uFF09\u3001press\uFF08\u6309\u952E\u5982 Enter\uFF09\u3001scroll\uFF08\u6EDA\u52A8\uFF09\u3001select\uFF08\u4E0B\u62C9\u9009\u62E9\uFF09\u3001hover\uFF08\u60AC\u505C\uFF09\u3001focus\uFF08\u805A\u7126\uFF09\u3002\n\u26A0\uFE0F \u4F7F\u7528\u524D\u5FC5\u987B\u5148\u8C03\u7528 get_interactive_snapshot \u83B7\u53D6\u5143\u7D20\u5217\u8868\u3002\u64CD\u4F5C\u540E\u5EFA\u8BAE\u7528 capture_screenshot \u6216\u518D\u6B21 get_interactive_snapshot \u9A8C\u8BC1\u7ED3\u679C\u3002",
|
|
29095
29146
|
inputSchema: {
|
|
29096
29147
|
type: "object",
|
|
29097
29148
|
properties: {
|
|
@@ -29134,6 +29185,48 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29134
29185
|
const name = request.params.name;
|
|
29135
29186
|
const args = request.params.arguments || {};
|
|
29136
29187
|
try {
|
|
29188
|
+
if (name === "inspect_page") {
|
|
29189
|
+
const { selector, includeInteractive = true, maxElements = 30 } = args;
|
|
29190
|
+
const page = await askChrome("getPageContent", {
|
|
29191
|
+
mode: "structured",
|
|
29192
|
+
selector,
|
|
29193
|
+
maxLength: 2e4,
|
|
29194
|
+
includeMetadata: true
|
|
29195
|
+
});
|
|
29196
|
+
let interactive = null;
|
|
29197
|
+
if (includeInteractive) {
|
|
29198
|
+
interactive = await askChrome("getInteractiveSnapshot", {
|
|
29199
|
+
selector,
|
|
29200
|
+
includeText: true,
|
|
29201
|
+
maxElements
|
|
29202
|
+
});
|
|
29203
|
+
}
|
|
29204
|
+
const links = page?.counts?.links;
|
|
29205
|
+
const buttons = page?.counts?.buttons;
|
|
29206
|
+
const forms = page?.counts?.forms;
|
|
29207
|
+
const interactiveCount = Array.isArray(interactive?.elements) ? interactive.elements.length : Array.isArray(interactive) ? interactive.length : void 0;
|
|
29208
|
+
return {
|
|
29209
|
+
content: [
|
|
29210
|
+
{
|
|
29211
|
+
type: "text",
|
|
29212
|
+
text: jsonText({
|
|
29213
|
+
summary: {
|
|
29214
|
+
title: page?.metadata?.title,
|
|
29215
|
+
url: page?.metadata?.url,
|
|
29216
|
+
description: page?.metadata?.description,
|
|
29217
|
+
links,
|
|
29218
|
+
buttons,
|
|
29219
|
+
forms,
|
|
29220
|
+
interactiveCount
|
|
29221
|
+
},
|
|
29222
|
+
page,
|
|
29223
|
+
interactive,
|
|
29224
|
+
nextStepHint: "\u5982\u679C\u9700\u8981\u770B\u89C6\u89C9\u6548\u679C\uFF0C\u7EE7\u7EED\u7528 capture_screenshot\uFF1B\u5982\u679C\u9700\u8981\u70B9\u51FB\u6216\u8F93\u5165\uFF0C\u7EE7\u7EED\u7528 dispatch_action\uFF1B\u5982\u679C\u9700\u8981\u6392\u67E5\u8BF7\u6C42\u6216\u6027\u80FD\uFF0C\u7EE7\u7EED\u7528 list_network_requests / perf_metrics\u3002"
|
|
29225
|
+
})
|
|
29226
|
+
}
|
|
29227
|
+
]
|
|
29228
|
+
};
|
|
29229
|
+
}
|
|
29137
29230
|
if (name === "get_server_info") {
|
|
29138
29231
|
let chromeOk, clientsCount;
|
|
29139
29232
|
if (isMainInstance) {
|
|
@@ -29155,7 +29248,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29155
29248
|
type: "text",
|
|
29156
29249
|
text: jsonText({
|
|
29157
29250
|
service: "ghost-bridge",
|
|
29158
|
-
version:
|
|
29251
|
+
version: GHOST_BRIDGE_VERSION,
|
|
29159
29252
|
role: isMainInstance ? "\u4E3B\u5B9E\u4F8B (WebSocket Server)" : "\u5BA2\u6237\u7AEF (\u8FDE\u63A5\u5230\u4E3B\u5B9E\u4F8B)",
|
|
29160
29253
|
wsPort: actualPort,
|
|
29161
29254
|
wsUrl: `ws://localhost:${actualPort}`,
|
|
@@ -29170,7 +29263,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29170
29263
|
};
|
|
29171
29264
|
}
|
|
29172
29265
|
if (name === "get_last_error") {
|
|
29173
|
-
const
|
|
29266
|
+
const { severity = "error", limit = 20 } = args;
|
|
29267
|
+
const data = await askChrome("getLastError", { severity, limit });
|
|
29174
29268
|
return { content: [{ type: "text", text: jsonText(data) }] };
|
|
29175
29269
|
}
|
|
29176
29270
|
if (name === "get_script_source") {
|
|
@@ -29227,8 +29321,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29227
29321
|
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29228
29322
|
}
|
|
29229
29323
|
if (name === "list_network_requests") {
|
|
29230
|
-
const { filter, method, status, resourceType, limit } = args;
|
|
29231
|
-
const res = await askChrome("listNetworkRequests", { filter, method, status, resourceType, limit });
|
|
29324
|
+
const { filter, method, status, resourceType, limit, priorityMode = "debug" } = args;
|
|
29325
|
+
const res = await askChrome("listNetworkRequests", { filter, method, status, resourceType, limit, priorityMode });
|
|
29232
29326
|
return { content: [{ type: "text", text: jsonText(res) }] };
|
|
29233
29327
|
}
|
|
29234
29328
|
if (name === "get_network_detail") {
|
|
@@ -29331,10 +29425,10 @@ function cleanup() {
|
|
|
29331
29425
|
log("\u{1F9F9} \u6B63\u5728\u6E05\u7406...");
|
|
29332
29426
|
if (isMainInstance) {
|
|
29333
29427
|
try {
|
|
29334
|
-
if (
|
|
29335
|
-
const info = JSON.parse(
|
|
29428
|
+
if (fs2.existsSync(PORT_INFO_FILE)) {
|
|
29429
|
+
const info = JSON.parse(fs2.readFileSync(PORT_INFO_FILE, "utf-8"));
|
|
29336
29430
|
if (info.pid === process.pid) {
|
|
29337
|
-
|
|
29431
|
+
fs2.unlinkSync(PORT_INFO_FILE);
|
|
29338
29432
|
log("\u{1F4DD} \u5DF2\u5220\u9664\u7AEF\u53E3\u4FE1\u606F\u6587\u4EF6");
|
|
29339
29433
|
}
|
|
29340
29434
|
}
|
|
@@ -29364,10 +29458,10 @@ process.on("SIGTERM", () => {
|
|
|
29364
29458
|
process.on("exit", () => {
|
|
29365
29459
|
if (isMainInstance) {
|
|
29366
29460
|
try {
|
|
29367
|
-
if (
|
|
29368
|
-
const info = JSON.parse(
|
|
29461
|
+
if (fs2.existsSync(PORT_INFO_FILE)) {
|
|
29462
|
+
const info = JSON.parse(fs2.readFileSync(PORT_INFO_FILE, "utf-8"));
|
|
29369
29463
|
if (info.pid === process.pid) {
|
|
29370
|
-
|
|
29464
|
+
fs2.unlinkSync(PORT_INFO_FILE);
|
|
29371
29465
|
}
|
|
29372
29466
|
}
|
|
29373
29467
|
} catch {
|