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/dist/server.js CHANGED
@@ -3228,8 +3228,8 @@ var require_utils = __commonJS({
3228
3228
  }
3229
3229
  return ind;
3230
3230
  }
3231
- function removeDotSegments(path2) {
3232
- let input = path2;
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 [path2, query] = wsComponent.resourceName.split("?");
3432
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
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, fs2, exportName) {
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, fs2[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: path2, errorMaps, issueData } = params;
15016
- const fullPath = [...path2, ...issueData.path || []];
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, path2, key) {
15131
+ constructor(parent, value, path3, key) {
15132
15132
  this._cachedPath = [];
15133
15133
  this.parent = parent;
15134
15134
  this.data = value;
15135
- this._path = path2;
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, path2) {
18780
- if (!path2)
18779
+ function getElementAtPath(obj, path3) {
18780
+ if (!path3)
18781
18781
  return obj;
18782
- return path2.reduce((acc, key) => acc?.[key], obj);
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(path2, issues) {
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(path2);
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 fs from "fs";
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 = path.join(os.tmpdir(), "ghost-bridge-port.json");
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 (!fs.existsSync(PORT_INFO_FILE)) return null;
28556
- const info = JSON.parse(fs.readFileSync(PORT_INFO_FILE, "utf-8"));
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
- fs.unlinkSync(PORT_INFO_FILE);
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
- fs.unlinkSync(PORT_INFO_FILE);
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
- fs.writeFileSync(
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, null, 2);
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: "0.4.0" },
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: { type: "object", properties: {} }
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: "0.3.0",
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 data = await askChrome("getLastError");
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 (fs.existsSync(PORT_INFO_FILE)) {
29335
- const info = JSON.parse(fs.readFileSync(PORT_INFO_FILE, "utf-8"));
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
- fs.unlinkSync(PORT_INFO_FILE);
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 (fs.existsSync(PORT_INFO_FILE)) {
29368
- const info = JSON.parse(fs.readFileSync(PORT_INFO_FILE, "utf-8"));
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
- fs.unlinkSync(PORT_INFO_FILE);
29464
+ fs2.unlinkSync(PORT_INFO_FILE);
29371
29465
  }
29372
29466
  }
29373
29467
  } catch {