@hangox/mg-cli 1.0.8 → 1.0.9

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as ServerInfo, N as NodeInfo, a as SpaceNodeInfo, M as MessageType } from './index-DmySkKst.js';
2
- export { W as AllPagesInfo, B as BaseMessage, C as CONFIG_DIR, T as CliOptions, X as ConnectedPageInfo, F as ConnectionInfo, a0 as ConnectionManager, q as ConnectionType, f as DEFAULT_PORT, D as DEV_DEFAULT_PORT, e as DEV_PORT_RANGE_END, d as DEV_PORT_RANGE_START, E as ErrorCode, x as ErrorInfo, s as ErrorMessages, r as ErrorNames, O as ExportImageParams, K as GetAllNodesParams, G as GetNodeParams, J as GetPageParams, H as HEARTBEAT_INTERVAL, m as HEARTBEAT_TIMEOUT, I as IS_DEV_MODE, L as LOG_DIR, a5 as LogLevel, a3 as Logger, a6 as LoggerOptions, i as MAX_PORT_ATTEMPTS, p as MAX_RETRY_COUNT, t as MGError, Z as MGServer, a1 as ManagedWebSocket, V as MgPageInfo, Q as OutputFormatter, h as PORT_RANGE_END, g as PORT_RANGE_START, j as PORT_SCAN_TIMEOUT, P as PROD_DEFAULT_PORT, c as PROD_PORT_RANGE_END, b as PROD_PORT_RANGE_START, z as PingMessage, A as PongMessage, R as REQUEST_TIMEOUT, o as RETRY_INTERVALS, U as RGBA, y as RegisterMessage, a2 as RequestHandler, v as RequestMessage, w as ResponseMessage, k as SERVER_INFO_FILE, l as SERVER_LOG_FILE, n as SERVER_START_TIMEOUT, $ as ServerOptions, Y as ServerStatusResponse, u as createError, a4 as createLogger, _ as createServer } from './index-DmySkKst.js';
1
+ import { S as ServerInfo, N as NodeInfo, a as SpaceNodeInfo, M as MessageType } from './index-cEKly9mt.js';
2
+ export { W as AllPagesInfo, B as BaseMessage, C as CONFIG_DIR, T as CliOptions, _ as ConnectedPageInfo, F as ConnectionInfo, a3 as ConnectionManager, q as ConnectionType, f as DEFAULT_PORT, D as DEV_DEFAULT_PORT, e as DEV_PORT_RANGE_END, d as DEV_PORT_RANGE_START, E as ErrorCode, x as ErrorInfo, s as ErrorMessages, r as ErrorNames, O as ExportImageParams, X as ExtensionInfo, K as GetAllNodesParams, G as GetNodeParams, J as GetPageParams, H as HEARTBEAT_INTERVAL, m as HEARTBEAT_TIMEOUT, I as IS_DEV_MODE, L as LOG_DIR, a8 as LogLevel, a6 as Logger, a9 as LoggerOptions, i as MAX_PORT_ATTEMPTS, p as MAX_RETRY_COUNT, t as MGError, a0 as MGServer, a4 as ManagedWebSocket, V as MgPageInfo, Z as NavigateToNodeParams, Y as OpenPageParams, Q as OutputFormatter, h as PORT_RANGE_END, g as PORT_RANGE_START, j as PORT_SCAN_TIMEOUT, P as PROD_DEFAULT_PORT, c as PROD_PORT_RANGE_END, b as PROD_PORT_RANGE_START, z as PingMessage, A as PongMessage, R as REQUEST_TIMEOUT, o as RETRY_INTERVALS, U as RGBA, y as RegisterMessage, a5 as RequestHandler, v as RequestMessage, w as ResponseMessage, k as SERVER_INFO_FILE, l as SERVER_LOG_FILE, n as SERVER_START_TIMEOUT, a2 as ServerOptions, $ as ServerStatusResponse, u as createError, a7 as createLogger, a1 as createServer } from './index-cEKly9mt.js';
3
3
  import 'ws';
4
4
 
5
5
  /**
@@ -155,7 +155,7 @@ declare const NODE_DEFAULTS: Record<string, unknown>;
155
155
  declare function trimNodeDefaults<T extends Record<string, unknown>>(node: T): T;
156
156
  /**
157
157
  * 提取节点的空间信息
158
- * 只保留 id、name、x、y、width、height 和 children 字段
158
+ * 只保留 id、name、x、y、width、height、absoluteX、absoluteY 和 children 字段
159
159
  * 用于让 AI 以最少的字段理解节点的空间布局关系
160
160
  *
161
161
  * @param node 原始节点数据
package/dist/index.js CHANGED
@@ -26,6 +26,7 @@ var MAX_RETRY_COUNT = 3;
26
26
  var ConnectionType = /* @__PURE__ */ ((ConnectionType2) => {
27
27
  ConnectionType2["CONSUMER"] = "consumer";
28
28
  ConnectionType2["PROVIDER"] = "provider";
29
+ ConnectionType2["CHROME_EXTENSION"] = "chrome_extension";
29
30
  return ConnectionType2;
30
31
  })(ConnectionType || {});
31
32
  var MessageType = /* @__PURE__ */ ((MessageType2) => {
@@ -40,6 +41,9 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
40
41
  MessageType2["EXPORT_IMAGE"] = "export_image";
41
42
  MessageType2["EXECUTE_CODE"] = "execute_code";
42
43
  MessageType2["GET_ALL_PAGES"] = "get_all_pages";
44
+ MessageType2["LIST_EXTENSIONS"] = "list_extensions";
45
+ MessageType2["OPEN_PAGE"] = "open_page";
46
+ MessageType2["NAVIGATE_TO_NODE"] = "navigate_to_node";
43
47
  MessageType2["GET_SERVER_STATUS"] = "get_server_status";
44
48
  MessageType2["RESPONSE"] = "response";
45
49
  MessageType2["ERROR"] = "error";
@@ -65,6 +69,7 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
65
69
  ErrorCode2["SERVER_START_FAILED"] = "E015";
66
70
  ErrorCode2["SERVER_ALREADY_RUNNING"] = "E016";
67
71
  ErrorCode2["CONNECTION_LOST"] = "E017";
72
+ ErrorCode2["NO_EXTENSION_CONNECTED"] = "E018";
68
73
  ErrorCode2["UNKNOWN_ERROR"] = "E099";
69
74
  return ErrorCode2;
70
75
  })(ErrorCode || {});
@@ -86,6 +91,7 @@ var ErrorNames = {
86
91
  ["E015" /* SERVER_START_FAILED */]: "SERVER_START_FAILED",
87
92
  ["E016" /* SERVER_ALREADY_RUNNING */]: "SERVER_ALREADY_RUNNING",
88
93
  ["E017" /* CONNECTION_LOST */]: "CONNECTION_LOST",
94
+ ["E018" /* NO_EXTENSION_CONNECTED */]: "NO_EXTENSION_CONNECTED",
89
95
  ["E099" /* UNKNOWN_ERROR */]: "UNKNOWN_ERROR"
90
96
  };
91
97
  var ErrorMessages = {
@@ -106,6 +112,7 @@ var ErrorMessages = {
106
112
  ["E015" /* SERVER_START_FAILED */]: "\u81EA\u52A8\u542F\u52A8 Server \u5931\u8D25",
107
113
  ["E016" /* SERVER_ALREADY_RUNNING */]: "Server \u5DF2\u5728\u8FD0\u884C\u4E2D",
108
114
  ["E017" /* CONNECTION_LOST */]: "\u8FDE\u63A5\u65AD\u5F00",
115
+ ["E018" /* NO_EXTENSION_CONNECTED */]: "\u6CA1\u6709 Chrome \u6269\u5C55\u8FDE\u63A5\u5230 Server\u3002\u8BF7\u786E\u4FDD\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u5E76\u5B89\u88C5\u4E86 MG Plugin",
109
116
  ["E099" /* UNKNOWN_ERROR */]: "\u672A\u77E5\u9519\u8BEF"
110
117
  };
111
118
  var MGError = class extends Error {
@@ -489,6 +496,12 @@ function extractSpaceInfo(node) {
489
496
  width: roundToOneDecimal(typeof node.width === "number" ? node.width : 0),
490
497
  height: roundToOneDecimal(typeof node.height === "number" ? node.height : 0)
491
498
  };
499
+ if (typeof node.absoluteX === "number") {
500
+ result.absoluteX = roundToOneDecimal(node.absoluteX);
501
+ }
502
+ if (typeof node.absoluteY === "number") {
503
+ result.absoluteY = roundToOneDecimal(node.absoluteY);
504
+ }
492
505
  if (node.children && Array.isArray(node.children) && node.children.length > 0) {
493
506
  result.children = node.children.map((child) => extractSpaceInfo(child));
494
507
  }
@@ -584,6 +597,12 @@ var ConnectionManager = class {
584
597
  providers = /* @__PURE__ */ new Map();
585
598
  /** Consumer 连接 */
586
599
  consumers = /* @__PURE__ */ new Map();
600
+ /** Chrome 扩展连接(按扩展 ID 索引) */
601
+ chromeExtensions = /* @__PURE__ */ new Map();
602
+ /** 扩展序号映射(扩展 ID → 序号) */
603
+ extensionIndexMap = /* @__PURE__ */ new Map();
604
+ /** 下一个可用的扩展序号 */
605
+ nextExtensionIndex = 1;
587
606
  /** 所有连接(按 ID 索引) */
588
607
  allConnections = /* @__PURE__ */ new Map();
589
608
  /** 心跳检查定时器 */
@@ -678,6 +697,16 @@ var ConnectionManager = class {
678
697
  } else if (connectionInfo.type === "consumer" /* CONSUMER */) {
679
698
  this.consumers.delete(connectionId);
680
699
  this.logger.info(`Consumer \u65AD\u5F00: ${connectionId}`);
700
+ } else if (connectionInfo.type === "chrome_extension" /* CHROME_EXTENSION */) {
701
+ for (const [extensionId, extWs] of this.chromeExtensions) {
702
+ if (extWs.connectionId === connectionId) {
703
+ const index = this.extensionIndexMap.get(extensionId);
704
+ this.chromeExtensions.delete(extensionId);
705
+ this.extensionIndexMap.delete(extensionId);
706
+ this.logger.info(`Chrome \u6269\u5C55\u65AD\u5F00: ${extensionId} (\u5E8F\u53F7: #${index})`);
707
+ break;
708
+ }
709
+ }
681
710
  }
682
711
  }
683
712
  /**
@@ -731,6 +760,7 @@ var ConnectionManager = class {
731
760
  return {
732
761
  providers: providerCount,
733
762
  consumers: this.consumers.size,
763
+ extensions: this.chromeExtensions.size,
734
764
  total: this.allConnections.size
735
765
  };
736
766
  }
@@ -740,6 +770,48 @@ var ConnectionManager = class {
740
770
  getConnectedPageUrls() {
741
771
  return Array.from(this.providers.keys());
742
772
  }
773
+ /**
774
+ * 添加 Chrome 扩展连接
775
+ */
776
+ addChromeExtension(ws, extensionId) {
777
+ const managedWs = this.addConnection(ws, "chrome_extension" /* CHROME_EXTENSION */);
778
+ const index = this.nextExtensionIndex++;
779
+ this.extensionIndexMap.set(extensionId, index);
780
+ this.chromeExtensions.set(extensionId, managedWs);
781
+ this.logger.info(`Chrome \u6269\u5C55\u8FDE\u63A5: ${extensionId} (\u5206\u914D\u5E8F\u53F7: #${index})`);
782
+ return managedWs;
783
+ }
784
+ /**
785
+ * 根据序号查找扩展
786
+ */
787
+ findExtensionByIndex(index) {
788
+ for (const [extensionId, extIndex] of this.extensionIndexMap) {
789
+ if (extIndex === index) {
790
+ return this.chromeExtensions.get(extensionId);
791
+ }
792
+ }
793
+ return void 0;
794
+ }
795
+ /**
796
+ * 获取第一个扩展
797
+ */
798
+ getFirstExtension() {
799
+ return this.chromeExtensions.values().next().value;
800
+ }
801
+ /**
802
+ * 获取所有扩展信息
803
+ */
804
+ getAllExtensions() {
805
+ const result = [];
806
+ for (const [extensionId, ws] of this.chromeExtensions) {
807
+ const index = this.extensionIndexMap.get(extensionId);
808
+ if (index !== void 0) {
809
+ result.push({ index, extensionId, ws });
810
+ }
811
+ }
812
+ result.sort((a, b) => a.index - b.index);
813
+ return result;
814
+ }
743
815
  /**
744
816
  * 关闭所有连接
745
817
  */
@@ -751,6 +823,8 @@ var ConnectionManager = class {
751
823
  }
752
824
  this.providers.clear();
753
825
  this.consumers.clear();
826
+ this.chromeExtensions.clear();
827
+ this.extensionIndexMap.clear();
754
828
  this.allConnections.clear();
755
829
  }
756
830
  };
@@ -868,6 +942,24 @@ var RequestHandler = class {
868
942
  this.logger.error(`\u53D1\u9001\u9519\u8BEF\u54CD\u5E94\u5931\u8D25: ${requestId}`, err);
869
943
  }
870
944
  }
945
+ /**
946
+ * 注册待处理请求(供外部使用,如 OPEN_PAGE)
947
+ * @param requestId 请求 ID
948
+ * @param consumer 发起请求的 Consumer
949
+ * @param sendCallback 发送请求的回调函数
950
+ */
951
+ registerPendingRequest(requestId, consumer, sendCallback) {
952
+ const timer = setTimeout(() => {
953
+ this.handleTimeout(requestId);
954
+ }, REQUEST_TIMEOUT);
955
+ this.pendingRequests.set(requestId, {
956
+ id: requestId,
957
+ consumer,
958
+ timer,
959
+ timestamp: Date.now()
960
+ });
961
+ sendCallback();
962
+ }
871
963
  /**
872
964
  * 清理特定连接的所有待处理请求
873
965
  */
@@ -1047,12 +1139,22 @@ var MGServer = class {
1047
1139
  */
1048
1140
  handleRegister(ws, message) {
1049
1141
  const { connectionType, pageUrl, pageId } = message.data;
1050
- const managedWs = this.connectionManager.addConnection(
1051
- ws,
1052
- connectionType,
1053
- pageUrl,
1054
- pageId
1055
- );
1142
+ const extensionId = message.data.extensionId;
1143
+ let managedWs;
1144
+ let extensionIndex;
1145
+ if (connectionType === "chrome_extension" /* CHROME_EXTENSION */ && extensionId) {
1146
+ managedWs = this.connectionManager.addChromeExtension(ws, extensionId);
1147
+ const exts = this.connectionManager.getAllExtensions();
1148
+ const ext = exts.find((e) => e.extensionId === extensionId);
1149
+ extensionIndex = ext?.index;
1150
+ } else {
1151
+ managedWs = this.connectionManager.addConnection(
1152
+ ws,
1153
+ connectionType,
1154
+ pageUrl,
1155
+ pageId
1156
+ );
1157
+ }
1056
1158
  const ack = {
1057
1159
  id: message.id || "",
1058
1160
  type: "register_ack" /* REGISTER_ACK */,
@@ -1060,7 +1162,8 @@ var MGServer = class {
1060
1162
  data: {
1061
1163
  connectionId: managedWs.connectionId,
1062
1164
  pageUrl,
1063
- serverVersion: getVersion()
1165
+ serverVersion: getVersion(),
1166
+ ...extensionIndex !== void 0 && { extensionIndex }
1064
1167
  }
1065
1168
  };
1066
1169
  ws.send(JSON.stringify(ack));
@@ -1077,6 +1180,15 @@ var MGServer = class {
1077
1180
  case "get_server_status" /* GET_SERVER_STATUS */:
1078
1181
  this.handleGetServerStatus(ws, message);
1079
1182
  break;
1183
+ case "list_extensions" /* LIST_EXTENSIONS */:
1184
+ this.handleListExtensions(ws, message);
1185
+ break;
1186
+ case "open_page" /* OPEN_PAGE */:
1187
+ this.handleOpenPage(ws, message);
1188
+ break;
1189
+ case "navigate_to_node" /* NAVIGATE_TO_NODE */:
1190
+ this.handleNavigateToNode(ws, message);
1191
+ break;
1080
1192
  case "response" /* RESPONSE */:
1081
1193
  case "error" /* ERROR */:
1082
1194
  this.requestHandler.handleResponse(message);
@@ -1109,6 +1221,13 @@ var MGServer = class {
1109
1221
  connectedAt: info.connectedAt.toISOString(),
1110
1222
  lastActiveAt: info.lastActiveAt.toISOString()
1111
1223
  }));
1224
+ const extensions = this.connectionManager.getAllExtensions();
1225
+ const connectedExtensions = extensions.map((ext) => ({
1226
+ index: ext.index,
1227
+ extensionId: ext.extensionId,
1228
+ connectedAt: ext.ws.connectionInfo.connectedAt.toISOString(),
1229
+ lastActiveAt: ext.ws.connectionInfo.lastActiveAt.toISOString()
1230
+ }));
1112
1231
  const uptimeMs = this.startedAt ? Date.now() - this.startedAt.getTime() : 0;
1113
1232
  const statusData = {
1114
1233
  running: this.isRunning,
@@ -1118,7 +1237,8 @@ var MGServer = class {
1118
1237
  uptime: formatDuration(uptimeMs),
1119
1238
  version: getVersion(),
1120
1239
  stats,
1121
- connectedPages
1240
+ connectedPages,
1241
+ connectedExtensions
1122
1242
  };
1123
1243
  const response = {
1124
1244
  id: message.id || "",
@@ -1129,6 +1249,156 @@ var MGServer = class {
1129
1249
  ws.send(JSON.stringify(response));
1130
1250
  this.logger.info("\u8FD4\u56DE Server \u72B6\u6001\u4FE1\u606F");
1131
1251
  }
1252
+ /**
1253
+ * 处理扩展列表查询
1254
+ */
1255
+ handleListExtensions(ws, message) {
1256
+ const extensions = this.connectionManager.getAllExtensions();
1257
+ const extensionList = extensions.map((ext) => ({
1258
+ index: ext.index,
1259
+ extensionId: ext.extensionId,
1260
+ connectedAt: ext.ws.connectionInfo.connectedAt.toISOString(),
1261
+ lastActiveAt: ext.ws.connectionInfo.lastActiveAt.toISOString()
1262
+ }));
1263
+ const response = {
1264
+ id: message.id || "",
1265
+ type: "response" /* RESPONSE */,
1266
+ success: true,
1267
+ data: {
1268
+ extensions: extensionList,
1269
+ totalCount: extensionList.length
1270
+ }
1271
+ };
1272
+ ws.send(JSON.stringify(response));
1273
+ this.logger.info(`\u8FD4\u56DE\u6269\u5C55\u5217\u8868\uFF0C\u5171 ${extensionList.length} \u4E2A\u6269\u5C55`);
1274
+ }
1275
+ /**
1276
+ * 处理打开页面请求
1277
+ */
1278
+ handleOpenPage(ws, message) {
1279
+ const params = message.params;
1280
+ const requestId = message.id || "";
1281
+ if (!params?.url) {
1282
+ const errorResponse = {
1283
+ id: requestId,
1284
+ type: "error" /* ERROR */,
1285
+ success: false,
1286
+ error: {
1287
+ code: "E011" /* INVALID_PARAMS */,
1288
+ name: "INVALID_PARAMS",
1289
+ message: "\u7F3A\u5C11 url \u53C2\u6570"
1290
+ }
1291
+ };
1292
+ ws.send(JSON.stringify(errorResponse));
1293
+ return;
1294
+ }
1295
+ const targetIndex = params.extensionIndex || 1;
1296
+ const targetExtension = this.connectionManager.findExtensionByIndex(targetIndex);
1297
+ if (!targetExtension) {
1298
+ const errorResponse = {
1299
+ id: requestId,
1300
+ type: "error" /* ERROR */,
1301
+ success: false,
1302
+ error: {
1303
+ code: "E018" /* NO_EXTENSION_CONNECTED */,
1304
+ name: "NO_EXTENSION_CONNECTED",
1305
+ message: targetIndex === 1 ? "\u6CA1\u6709 Chrome \u6269\u5C55\u8FDE\u63A5\u5230 Server\u3002\u8BF7\u786E\u4FDD\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u5E76\u5B89\u88C5\u4E86 MG Plugin" : `\u672A\u627E\u5230\u5E8F\u53F7\u4E3A #${targetIndex} \u7684\u6269\u5C55\u5B9E\u4F8B`
1306
+ }
1307
+ };
1308
+ ws.send(JSON.stringify(errorResponse));
1309
+ this.logger.warn(`\u672A\u627E\u5230\u6269\u5C55\u5B9E\u4F8B #${targetIndex}`);
1310
+ return;
1311
+ }
1312
+ const forwardMessage = {
1313
+ id: requestId,
1314
+ type: "open_page" /* OPEN_PAGE */,
1315
+ params: { url: params.url }
1316
+ };
1317
+ this.requestHandler.registerPendingRequest(requestId, ws, () => {
1318
+ try {
1319
+ targetExtension.send(JSON.stringify(forwardMessage));
1320
+ this.logger.info(`\u8F6C\u53D1 OPEN_PAGE \u8BF7\u6C42\u5230\u6269\u5C55 #${targetIndex}: ${params.url}`);
1321
+ } catch (error) {
1322
+ this.logger.error(`\u8F6C\u53D1\u8BF7\u6C42\u5931\u8D25: ${error}`);
1323
+ const errorResponse = {
1324
+ id: requestId,
1325
+ type: "error" /* ERROR */,
1326
+ success: false,
1327
+ error: {
1328
+ code: "E001" /* CONNECTION_FAILED */,
1329
+ name: "CONNECTION_FAILED",
1330
+ message: "\u8F6C\u53D1\u8BF7\u6C42\u5931\u8D25"
1331
+ }
1332
+ };
1333
+ ws.send(JSON.stringify(errorResponse));
1334
+ }
1335
+ });
1336
+ }
1337
+ /**
1338
+ * 处理节点导航请求
1339
+ */
1340
+ handleNavigateToNode(ws, message) {
1341
+ const params = message.params;
1342
+ const requestId = message.id || "";
1343
+ if (!params?.pageUrl || !params?.nodeId) {
1344
+ const errorResponse = {
1345
+ id: requestId,
1346
+ type: "error" /* ERROR */,
1347
+ success: false,
1348
+ error: {
1349
+ code: "E011" /* INVALID_PARAMS */,
1350
+ name: "INVALID_PARAMS",
1351
+ message: "\u7F3A\u5C11 pageUrl \u6216 nodeId \u53C2\u6570"
1352
+ }
1353
+ };
1354
+ ws.send(JSON.stringify(errorResponse));
1355
+ return;
1356
+ }
1357
+ const targetIndex = params.extensionIndex || 1;
1358
+ const targetExtension = this.connectionManager.findExtensionByIndex(targetIndex);
1359
+ if (!targetExtension) {
1360
+ const errorResponse = {
1361
+ id: requestId,
1362
+ type: "error" /* ERROR */,
1363
+ success: false,
1364
+ error: {
1365
+ code: "E018" /* NO_EXTENSION_CONNECTED */,
1366
+ name: "NO_EXTENSION_CONNECTED",
1367
+ message: targetIndex === 1 ? "\u6CA1\u6709 Chrome \u6269\u5C55\u8FDE\u63A5\u5230 Server\u3002\u8BF7\u786E\u4FDD\u6D4F\u89C8\u5668\u5DF2\u6253\u5F00\u5E76\u5B89\u88C5\u4E86 MG Plugin" : `\u672A\u627E\u5230\u5E8F\u53F7\u4E3A #${targetIndex} \u7684\u6269\u5C55\u5B9E\u4F8B`
1368
+ }
1369
+ };
1370
+ ws.send(JSON.stringify(errorResponse));
1371
+ this.logger.warn(`\u672A\u627E\u5230\u6269\u5C55\u5B9E\u4F8B #${targetIndex}`);
1372
+ return;
1373
+ }
1374
+ const forwardMessage = {
1375
+ id: requestId,
1376
+ type: "navigate_to_node" /* NAVIGATE_TO_NODE */,
1377
+ params: {
1378
+ pageUrl: params.pageUrl,
1379
+ nodeId: params.nodeId
1380
+ }
1381
+ };
1382
+ this.requestHandler.registerPendingRequest(requestId, ws, () => {
1383
+ try {
1384
+ targetExtension.send(JSON.stringify(forwardMessage));
1385
+ this.logger.info(`\u8F6C\u53D1 NAVIGATE_TO_NODE \u8BF7\u6C42\u5230\u6269\u5C55 #${targetIndex}: ${params.pageUrl} -> ${params.nodeId}`);
1386
+ } catch (error) {
1387
+ this.logger.error(`\u8F6C\u53D1\u8BF7\u6C42\u5931\u8D25: ${error}`);
1388
+ const errorResponse = {
1389
+ id: requestId,
1390
+ type: "error" /* ERROR */,
1391
+ success: false,
1392
+ error: {
1393
+ code: "E001" /* CONNECTION_FAILED */,
1394
+ name: "CONNECTION_FAILED",
1395
+ message: "\u8F6C\u53D1\u8BF7\u6C42\u5931\u8D25"
1396
+ }
1397
+ };
1398
+ ws.send(JSON.stringify(errorResponse));
1399
+ }
1400
+ });
1401
+ }
1132
1402
  /**
1133
1403
  * 停止服务器
1134
1404
  */