@hangox/mg-cli 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli/index.ts
4
- import { Command as Command15 } from "commander";
4
+ import { Command as Command23 } from "commander";
5
5
 
6
6
  // src/cli/version-check.ts
7
7
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
@@ -168,6 +168,7 @@ var SERVER_LOG_FILE = join3(LOG_DIR, "server.log");
168
168
  var HEARTBEAT_INTERVAL = 3e4;
169
169
  var HEARTBEAT_TIMEOUT = 9e4;
170
170
  var REQUEST_TIMEOUT = 3e4;
171
+ var MAX_REQUEST_TIMEOUT = 6e5;
171
172
  var SERVER_START_TIMEOUT = 5e3;
172
173
  var RETRY_INTERVALS = [1e3, 2e3, 4e3];
173
174
  var MAX_RETRY_COUNT = 3;
@@ -427,7 +428,6 @@ var NODE_DEFAULTS = {
427
428
  layoutPositioning: "AUTO",
428
429
  constrainProportions: false,
429
430
  // 容器专属属性 (FrameNode)
430
- flexMode: "NONE",
431
431
  flexWrap: "NO_WRAP",
432
432
  itemSpacing: 0,
433
433
  crossAxisSpacing: 0,
@@ -538,6 +538,8 @@ var ErrorNames = {
538
538
  ["E016" /* SERVER_ALREADY_RUNNING */]: "SERVER_ALREADY_RUNNING",
539
539
  ["E017" /* CONNECTION_LOST */]: "CONNECTION_LOST",
540
540
  ["E018" /* NO_EXTENSION_CONNECTED */]: "NO_EXTENSION_CONNECTED",
541
+ ["E019" /* EDIT_NOT_ALLOWED */]: "EDIT_NOT_ALLOWED",
542
+ ["E020" /* CREATE_NODE_FAILED */]: "CREATE_NODE_FAILED",
541
543
  ["E099" /* UNKNOWN_ERROR */]: "UNKNOWN_ERROR"
542
544
  };
543
545
  var ErrorMessages = {
@@ -559,6 +561,8 @@ var ErrorMessages = {
559
561
  ["E016" /* SERVER_ALREADY_RUNNING */]: "Server \u5DF2\u5728\u8FD0\u884C\u4E2D",
560
562
  ["E017" /* CONNECTION_LOST */]: "\u8FDE\u63A5\u65AD\u5F00",
561
563
  ["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",
564
+ ["E019" /* EDIT_NOT_ALLOWED */]: "\u9875\u9762\u53EA\u8BFB\u6216\u65E0\u7F16\u8F91\u6743\u9650\uFF0C\u65E0\u6CD5\u6267\u884C\u5199\u64CD\u4F5C",
565
+ ["E020" /* CREATE_NODE_FAILED */]: "\u521B\u5EFA\u8282\u70B9\u5931\u8D25\uFF08\u6839\u8282\u70B9\u65E0\u6CD5\u521B\u5EFA\uFF09",
562
566
  ["E099" /* UNKNOWN_ERROR */]: "\u672A\u77E5\u9519\u8BEF"
563
567
  };
564
568
  var MGError = class extends Error {
@@ -905,6 +909,12 @@ var ConnectionManager = class {
905
909
  };
906
910
 
907
911
  // src/server/request-handler.ts
912
+ function resolveRequestTimeout(timeoutMs) {
913
+ if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
914
+ return REQUEST_TIMEOUT;
915
+ }
916
+ return Math.min(timeoutMs, MAX_REQUEST_TIMEOUT);
917
+ }
908
918
  var RequestHandler = class {
909
919
  logger;
910
920
  connectionManager;
@@ -937,7 +947,7 @@ var RequestHandler = class {
937
947
  }
938
948
  const timer = setTimeout(() => {
939
949
  this.handleTimeout(requestId);
940
- }, REQUEST_TIMEOUT);
950
+ }, resolveRequestTimeout(message.timeoutMs));
941
951
  this.pendingRequests.set(requestId, {
942
952
  id: requestId,
943
953
  consumer,
@@ -1132,7 +1142,7 @@ var MGServer = class {
1132
1142
  throw new MGError("E016" /* SERVER_ALREADY_RUNNING */, "Server \u5DF2\u5728\u8FD0\u884C\u4E2D");
1133
1143
  }
1134
1144
  const port = await this.findAvailablePort();
1135
- return new Promise((resolve10, reject) => {
1145
+ return new Promise((resolve16, reject) => {
1136
1146
  this.wss = new WebSocketServer({ port });
1137
1147
  this.wss.on("listening", () => {
1138
1148
  this.port = port;
@@ -1141,7 +1151,7 @@ var MGServer = class {
1141
1151
  this.logger.info(`Server \u542F\u52A8\u6210\u529F\uFF0C\u76D1\u542C\u7AEF\u53E3: ${port}`);
1142
1152
  this.connectionManager.startHeartbeatCheck(HEARTBEAT_INTERVAL);
1143
1153
  initServerAnalytics(this.logger);
1144
- resolve10(port);
1154
+ resolve16(port);
1145
1155
  });
1146
1156
  this.wss.on("error", (error) => {
1147
1157
  this.logger.error("Server \u9519\u8BEF:", error);
@@ -1172,14 +1182,14 @@ var MGServer = class {
1172
1182
  * 检查端口是否可用
1173
1183
  */
1174
1184
  isPortAvailable(port) {
1175
- return new Promise((resolve10) => {
1185
+ return new Promise((resolve16) => {
1176
1186
  const testServer = new WebSocketServer({ port });
1177
1187
  testServer.on("listening", () => {
1178
1188
  testServer.close();
1179
- resolve10(true);
1189
+ resolve16(true);
1180
1190
  });
1181
1191
  testServer.on("error", () => {
1182
- resolve10(false);
1192
+ resolve16(false);
1183
1193
  });
1184
1194
  });
1185
1195
  }
@@ -1514,12 +1524,12 @@ var MGServer = class {
1514
1524
  await shutdownServerAnalytics();
1515
1525
  this.requestHandler.cleanupAll();
1516
1526
  this.connectionManager.closeAll();
1517
- return new Promise((resolve10) => {
1527
+ return new Promise((resolve16) => {
1518
1528
  this.wss.close(() => {
1519
1529
  this.isRunning = false;
1520
1530
  this.wss = null;
1521
1531
  this.logger.info("Server \u5DF2\u505C\u6B62");
1522
- resolve10();
1532
+ resolve16();
1523
1533
  });
1524
1534
  });
1525
1535
  }
@@ -1636,7 +1646,7 @@ async function startServerDaemon(port) {
1636
1646
  child.unref();
1637
1647
  const startTime = Date.now();
1638
1648
  while (Date.now() - startTime < SERVER_START_TIMEOUT) {
1639
- await new Promise((resolve10) => setTimeout(resolve10, 200));
1649
+ await new Promise((resolve16) => setTimeout(resolve16, 200));
1640
1650
  const { running: running2, info: info2 } = isServerRunning();
1641
1651
  if (running2 && info2) {
1642
1652
  return info2;
@@ -1657,7 +1667,7 @@ function stopServer() {
1657
1667
  }
1658
1668
  async function restartServer(port) {
1659
1669
  const { info: oldInfo } = stopServer();
1660
- await new Promise((resolve10) => setTimeout(resolve10, 500));
1670
+ await new Promise((resolve16) => setTimeout(resolve16, 500));
1661
1671
  return startServerDaemon(port || oldInfo?.port);
1662
1672
  }
1663
1673
  function getServerStatus() {
@@ -1730,7 +1740,7 @@ var MGClient = class {
1730
1740
  * 尝试连接指定端口
1731
1741
  */
1732
1742
  tryConnect(port) {
1733
- return new Promise((resolve10, reject) => {
1743
+ return new Promise((resolve16, reject) => {
1734
1744
  const ws = new WebSocket2(`ws://localhost:${port}`);
1735
1745
  const timer = setTimeout(() => {
1736
1746
  ws.close();
@@ -1740,7 +1750,7 @@ var MGClient = class {
1740
1750
  clearTimeout(timer);
1741
1751
  this.ws = ws;
1742
1752
  this.register();
1743
- resolve10();
1753
+ resolve16();
1744
1754
  });
1745
1755
  ws.on("error", (error) => {
1746
1756
  clearTimeout(timer);
@@ -1780,8 +1790,10 @@ var MGClient = class {
1780
1790
  }
1781
1791
  /**
1782
1792
  * 发送请求并等待响应
1793
+ * @param timeoutMs 请求超时(毫秒),缺省 REQUEST_TIMEOUT。
1794
+ * 会随消息透传给 Server,使 Server 侧转发超时同步放宽
1783
1795
  */
1784
- async request(type, params, pageUrl) {
1796
+ async request(type, params, pageUrl, timeoutMs) {
1785
1797
  if (!this.ws) {
1786
1798
  throw new MGError("E001" /* CONNECTION_FAILED */, "\u672A\u8FDE\u63A5\u5230 Server");
1787
1799
  }
@@ -1791,12 +1803,13 @@ var MGClient = class {
1791
1803
  type,
1792
1804
  params,
1793
1805
  pageUrl,
1806
+ timeoutMs,
1794
1807
  timestamp: Date.now()
1795
1808
  };
1796
- return new Promise((resolve10, reject) => {
1809
+ return new Promise((resolve16, reject) => {
1797
1810
  const timer = setTimeout(() => {
1798
1811
  reject(new MGError("E012" /* REQUEST_TIMEOUT */, ErrorMessages["E012" /* REQUEST_TIMEOUT */]));
1799
- }, REQUEST_TIMEOUT);
1812
+ }, timeoutMs ?? REQUEST_TIMEOUT);
1800
1813
  const messageHandler = (data) => {
1801
1814
  try {
1802
1815
  const response = JSON.parse(data.toString());
@@ -1804,7 +1817,7 @@ var MGClient = class {
1804
1817
  clearTimeout(timer);
1805
1818
  this.ws?.off("message", messageHandler);
1806
1819
  if (response.success) {
1807
- resolve10(response.data);
1820
+ resolve16(response.data);
1808
1821
  } else {
1809
1822
  const error = response.error;
1810
1823
  reject(
@@ -1824,15 +1837,16 @@ var MGClient = class {
1824
1837
  }
1825
1838
  /**
1826
1839
  * 带重试的请求
1840
+ * @param timeoutMs 请求超时(毫秒),透传给 request()
1827
1841
  */
1828
- async requestWithRetry(type, params, pageUrl) {
1842
+ async requestWithRetry(type, params, pageUrl, timeoutMs) {
1829
1843
  if (this.options.noRetry) {
1830
- return this.request(type, params, pageUrl);
1844
+ return this.request(type, params, pageUrl, timeoutMs);
1831
1845
  }
1832
1846
  let lastError = null;
1833
1847
  for (let attempt = 0; attempt <= MAX_RETRY_COUNT; attempt++) {
1834
1848
  try {
1835
- return await this.request(type, params, pageUrl);
1849
+ return await this.request(type, params, pageUrl, timeoutMs);
1836
1850
  } catch (error) {
1837
1851
  lastError = error instanceof Error ? error : new Error(String(error));
1838
1852
  if (error instanceof MGError) {
@@ -2249,13 +2263,172 @@ async function handleGetNodeByLink(options) {
2249
2263
  }
2250
2264
  }
2251
2265
 
2252
- // src/cli/commands/get-all-nodes.ts
2266
+ // src/cli/commands/get-node-context.ts
2253
2267
  import { Command as Command4 } from "commander";
2254
2268
  import { writeFileSync as writeFileSync5 } from "fs";
2255
2269
  import { resolve as resolve4, dirname as dirname7 } from "path";
2256
2270
  import { mkdirSync as mkdirSync6 } from "fs";
2271
+ function parseAncestorsOption(value) {
2272
+ if (value === "all") {
2273
+ return -1;
2274
+ }
2275
+ const n = Number.parseInt(value, 10);
2276
+ if (Number.isNaN(n) || n <= 0 || String(n) !== value.trim()) {
2277
+ throw new MGError("E011" /* INVALID_PARAMS */, `--ancestors \u53C2\u6570\u65E0\u6548: '${value}'\uFF0C\u671F\u671B\u6B63\u6574\u6570\u6216 'all'`);
2278
+ }
2279
+ return n;
2280
+ }
2281
+ function resolveContextTarget(options) {
2282
+ if (options.link && options.nodeId) {
2283
+ throw new MGError("E011" /* INVALID_PARAMS */, "--link \u4E0E --nodeId \u53EA\u80FD\u4E8C\u9009\u4E00");
2284
+ }
2285
+ if (!options.link && !options.nodeId) {
2286
+ throw new MGError("E011" /* INVALID_PARAMS */, "\u5FC5\u987B\u63D0\u4F9B --link \u6216 --nodeId \u4E4B\u4E00");
2287
+ }
2288
+ if (options.link) {
2289
+ const parsed = parseMgpLink(options.link);
2290
+ if (!parsed) {
2291
+ throw new MGError(
2292
+ "E010" /* INVALID_LINK */,
2293
+ `\u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F: ${options.link}
2294
+ \u671F\u671B\u683C\u5F0F: mgp://[mastergo_page_url]?nodeId=[\u8282\u70B9ID]`
2295
+ );
2296
+ }
2297
+ if (parsed.pageId) {
2298
+ throw new MGError(
2299
+ "E011" /* INVALID_PARAMS */,
2300
+ "get_node_context \u4E0D\u652F\u6301\u9875\u9762\u94FE\u63A5\uFF08\u76EE\u6807\u662F PAGE\uFF09\u3002\u8BF7\u6539\u7528 get_node_by_link \u7684 pageId \u6A21\u5F0F\u83B7\u53D6\u6574\u9875\u6570\u636E"
2301
+ );
2302
+ }
2303
+ if (parsed.childNodeIds && parsed.childNodeIds.length > 0) {
2304
+ throw new MGError(
2305
+ "E011" /* INVALID_PARAMS */,
2306
+ "get_node_context \u4E0D\u652F\u6301\u591A\u9009\u94FE\u63A5\u3002\u8BF7\u5BF9\u6BCF\u4E2A\u5B50\u8282\u70B9\u5206\u522B\u83B7\u53D6 context"
2307
+ );
2308
+ }
2309
+ return { pageUrl: parsed.pageUrl, nodeId: parsed.nodeId, nodePath: parsed.nodePath };
2310
+ }
2311
+ let pageUrl;
2312
+ if (options.fileId) {
2313
+ const domain = options.domain || "mastergo.netease.com";
2314
+ pageUrl = buildPageUrl(domain, options.fileId, options.pageType);
2315
+ }
2316
+ return { pageUrl, nodeId: options.nodeId };
2317
+ }
2318
+ function resolveContextParams(options) {
2319
+ const ancestorLevels = parseAncestorsOption(options.ancestors ?? "all");
2320
+ const maxSiblings = Number.parseInt(options.maxSiblings ?? "50", 10);
2321
+ if (Number.isNaN(maxSiblings) || maxSiblings <= 0 || String(maxSiblings) !== (options.maxSiblings ?? "50").trim()) {
2322
+ throw new MGError("E011" /* INVALID_PARAMS */, `--maxSiblings \u53C2\u6570\u65E0\u6548: '${options.maxSiblings}'\uFF0C\u671F\u671B\u6B63\u6574\u6570`);
2323
+ }
2324
+ const maxDepth = Number.parseInt(options.maxDepth ?? "1", 10);
2325
+ if (Number.isNaN(maxDepth) || maxDepth < 0) {
2326
+ throw new MGError("E011" /* INVALID_PARAMS */, `--maxDepth \u53C2\u6570\u65E0\u6548: '${options.maxDepth}'\uFF0C\u671F\u671B\u975E\u8D1F\u6574\u6570`);
2327
+ }
2328
+ return {
2329
+ ancestorLevels,
2330
+ includeSiblings: options.siblings !== false,
2331
+ maxSiblings,
2332
+ maxDepth,
2333
+ includeInvisible: options.includeInvisible || false
2334
+ };
2335
+ }
2336
+ function buildContextOutput(data, raw = false) {
2337
+ const node = raw ? data.node : trimNodeDefaults(data.node);
2338
+ return {
2339
+ contextSummary: data.contextSummary,
2340
+ indexInParent: data.indexInParent,
2341
+ siblingCount: data.siblingCount,
2342
+ ...data.siblingsTruncated ? { siblingsTruncated: true } : {},
2343
+ ...data.ancestorsIncomplete ? { ancestorsIncomplete: true } : {},
2344
+ ancestors: data.ancestors,
2345
+ ...data.siblings !== void 0 ? { siblings: data.siblings } : {},
2346
+ node
2347
+ };
2348
+ }
2349
+ function createGetNodeContextCommand() {
2350
+ return new Command4("get_node_context").description(
2351
+ "\u83B7\u53D6\u8282\u70B9\u4E0A\u4E0B\u6587\uFF08\u76EE\u6807\u8282\u70B9 + \u7956\u5148\u94FE + \u5144\u5F1F\u8282\u70B9\u6458\u8981\uFF09\u3002\u7236\u5BB9\u5668 AutoLayout \u5C5E\u6027\u4E0E\u5144\u5F1F\u4F4D\u7F6E\u5C3A\u5BF8\u7528\u4E8E AI \u5E03\u5C40\u51B3\u7B56\uFF1B\u9700\u8981\u67D0\u4E2A\u5144\u5F1F\u7684\u7EC6\u8282\u65F6\u7528\u6458\u8981\u91CC\u7684 id \u518D\u8C03 get_node_by_id"
2352
+ ).option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u4E0E --nodeId \u4E8C\u9009\u4E00").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u914D\u5408 --domain / --fileId / --pageType \u4F7F\u7528").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u652F\u6301\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9\u8DEF\u5F84").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --fileId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--ancestors <n|all>", "\u5411\u4E0A\u53D6\u51E0\u5C42\u7956\u5148\uFF0C'all' = \u76F4\u5230\u5E76\u5305\u542B PAGE", "all").option("--no-siblings", "\u4E0D\u8FD4\u56DE siblings \u6570\u7EC4\uFF08indexInParent / siblingCount \u4ECD\u8FD4\u56DE\uFF09").option("--maxSiblings <n>", "\u5144\u5F1F\u6570\u91CF\u4E0A\u9650\uFF0C\u8D85\u51FA\u65F6\u4EE5\u76EE\u6807\u4E3A\u4E2D\u5FC3\u5F00\u7A97\uFF0C\u8FD4\u56DE\u603B\u6570\uFF08\u542B\u76EE\u6807\uFF09= maxSiblings", "50").option("--maxDepth <number>", "\u76EE\u6807\u8282\u70B9\u81EA\u8EAB\u5B50\u6811\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 1", "1").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9\uFF08\u4EC5\u4F5C\u7528\u4E8E siblings \u8FC7\u6EE4\u4E0E node \u5B50\u6811\uFF0C\u4E0D\u5F71\u54CD\u7956\u5148\u94FE\uFF09", false).option("--raw", "\u4FDD\u7559\u539F\u59CB\u6570\u636E\uFF0C\u4E0D\u7CBE\u7B80 node \u7684\u9ED8\u8BA4\u503C\u5B57\u6BB5", false).option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2353
+ await handleGetNodeContext(options);
2354
+ });
2355
+ }
2356
+ async function handleGetNodeContext(options) {
2357
+ const tracker = createCommandTracker("get_node_context");
2358
+ let pageUrl;
2359
+ let nodeId;
2360
+ let nodePath;
2361
+ let protocolParams;
2362
+ try {
2363
+ const target = resolveContextTarget(options);
2364
+ pageUrl = target.pageUrl;
2365
+ nodeId = target.nodeId;
2366
+ nodePath = target.nodePath;
2367
+ protocolParams = resolveContextParams(options);
2368
+ } catch (error) {
2369
+ if (error instanceof MGError) {
2370
+ console.error(`\u9519\u8BEF [${error.code}]: ${error.message}`);
2371
+ tracker.failure(error);
2372
+ } else {
2373
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
2374
+ tracker.failure(error instanceof Error ? error : void 0);
2375
+ }
2376
+ process.exit(1);
2377
+ }
2378
+ const client = new MGClient({
2379
+ noAutoStart: options.noAutoStart,
2380
+ noRetry: options.noRetry
2381
+ });
2382
+ try {
2383
+ await client.connect();
2384
+ const params = {
2385
+ nodeId,
2386
+ ...protocolParams
2387
+ };
2388
+ const data = await client.requestWithRetry("get_node_context" /* GET_NODE_CONTEXT */, params, pageUrl);
2389
+ const outputData = buildContextOutput(data, options.raw);
2390
+ const outputPath = resolve4(options.output);
2391
+ const outputDir = dirname7(outputPath);
2392
+ mkdirSync6(outputDir, { recursive: true });
2393
+ const jsonContent = JSON.stringify(outputData, null, options.pretty ? 2 : 0);
2394
+ writeFileSync5(outputPath, jsonContent, "utf-8");
2395
+ const size = jsonContent.length;
2396
+ const sizeKB = (size / 1024).toFixed(2);
2397
+ console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
2398
+ console.log(`\u8282\u70B9 ID: ${nodeId}`);
2399
+ console.log(`\u6570\u636E\u5927\u5C0F: ${size.toLocaleString()} \u5B57\u7B26 (\u7EA6 ${sizeKB} KB)`);
2400
+ console.log(`\u7956\u5148\u5C42\u6570: ${params.ancestorLevels === -1 ? "all\uFF08\u76F4\u5230 PAGE\uFF09" : params.ancestorLevels}`);
2401
+ console.log(`\u8282\u70B9\u6DF1\u5EA6: ${params.maxDepth}`);
2402
+ if (!options.raw) {
2403
+ console.log(`\u6570\u636E\u6A21\u5F0F: \u7CBE\u7B80\u6A21\u5F0F (\u4F7F\u7528 --raw \u83B7\u53D6\u5B8C\u6574\u6570\u636E\uFF0C\u4EC5\u5F71\u54CD node \u5B57\u6BB5)`);
2404
+ }
2405
+ console.log(`
2406
+ contextSummary: ${data.contextSummary}`);
2407
+ tracker.success();
2408
+ } catch (error) {
2409
+ if (error instanceof MGError) {
2410
+ console.error(`\u9519\u8BEF [${error.code}]: ${error.message}`);
2411
+ if (error.code === "E005" /* NODE_NOT_FOUND */ && nodePath && nodePath.length > 0) {
2412
+ console.error(`\u63D0\u793A: \u94FE\u63A5\u643A\u5E26 nodePath\uFF0C\u53EF\u5C1D\u8BD5\u83B7\u53D6\u7236\u8282\u70B9 ${nodePath.join(" / ")}`);
2413
+ }
2414
+ tracker.failure(error);
2415
+ } else {
2416
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
2417
+ tracker.failure(error instanceof Error ? error : void 0);
2418
+ }
2419
+ process.exit(1);
2420
+ } finally {
2421
+ client.close();
2422
+ }
2423
+ }
2424
+
2425
+ // src/cli/commands/get-all-nodes.ts
2426
+ import { Command as Command5 } from "commander";
2427
+ import { writeFileSync as writeFileSync6 } from "fs";
2428
+ import { resolve as resolve5, dirname as dirname8 } from "path";
2429
+ import { mkdirSync as mkdirSync7 } from "fs";
2257
2430
  function createGetAllNodesCommand() {
2258
- return new Command4("get_all_nodes").description("\u83B7\u53D6\u5F53\u524D\u9875\u9762\u7684\u6240\u6709\u8282\u70B9\u6811\u3002\u8B66\u544A\uFF1A\u6DF1\u5EA6\u6BCF\u589E\u52A0 1\uFF0C\u6570\u636E\u91CF\u53EF\u80FD\u5448\u6307\u6570\u7EA7\u589E\u957F\u3002\u5EFA\u8BAE\u4ECE maxDepth=1 \u5F00\u59CB").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u652F\u6301\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9\u8DEF\u5F84").option("--maxDepth <number>", "\u6700\u5927\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 1\u3002\u6DF1\u5EA6 2 \u53EF\u80FD\u4EA7\u751F 100KB-500KB\uFF0C\u6DF1\u5EA6 3 \u53EF\u80FD\u8D85\u8FC7 1MB", "1").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9\uFF08visible: false\uFF09\uFF0C\u9ED8\u8BA4\u4E0D\u5305\u542B", false).option("--raw", "\u4FDD\u7559\u539F\u59CB\u6570\u636E\uFF0C\u4E0D\u7CBE\u7B80\u9ED8\u8BA4\u503C\u5B57\u6BB5", false).option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2431
+ return new Command5("get_all_nodes").description("\u83B7\u53D6\u5F53\u524D\u9875\u9762\u7684\u6240\u6709\u8282\u70B9\u6811\u3002\u8B66\u544A\uFF1A\u6DF1\u5EA6\u6BCF\u589E\u52A0 1\uFF0C\u6570\u636E\u91CF\u53EF\u80FD\u5448\u6307\u6570\u7EA7\u589E\u957F\u3002\u5EFA\u8BAE\u4ECE maxDepth=1 \u5F00\u59CB").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u652F\u6301\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9\u8DEF\u5F84").option("--maxDepth <number>", "\u6700\u5927\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 1\u3002\u6DF1\u5EA6 2 \u53EF\u80FD\u4EA7\u751F 100KB-500KB\uFF0C\u6DF1\u5EA6 3 \u53EF\u80FD\u8D85\u8FC7 1MB", "1").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9\uFF08visible: false\uFF09\uFF0C\u9ED8\u8BA4\u4E0D\u5305\u542B", false).option("--raw", "\u4FDD\u7559\u539F\u59CB\u6570\u636E\uFF0C\u4E0D\u7CBE\u7B80\u9ED8\u8BA4\u503C\u5B57\u6BB5", false).option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2259
2432
  await handleGetAllNodes(options);
2260
2433
  });
2261
2434
  }
@@ -2272,11 +2445,11 @@ async function handleGetAllNodes(options) {
2272
2445
  };
2273
2446
  const data = await client.requestWithRetry("get_all_nodes" /* GET_ALL_NODES */, params);
2274
2447
  const outputData = options.raw ? data : Array.isArray(data) ? data.map((node) => trimNodeDefaults(node)) : trimNodeDefaults(data);
2275
- const outputPath = resolve4(options.output);
2276
- const outputDir = dirname7(outputPath);
2277
- mkdirSync6(outputDir, { recursive: true });
2448
+ const outputPath = resolve5(options.output);
2449
+ const outputDir = dirname8(outputPath);
2450
+ mkdirSync7(outputDir, { recursive: true });
2278
2451
  const jsonContent = JSON.stringify(outputData, null, options.pretty ? 2 : 0);
2279
- writeFileSync5(outputPath, jsonContent, "utf-8");
2452
+ writeFileSync6(outputPath, jsonContent, "utf-8");
2280
2453
  const size = jsonContent.length;
2281
2454
  const sizeKB = (size / 1024).toFixed(2);
2282
2455
  const nodeCount = Array.isArray(data) ? data.length : 1;
@@ -2297,14 +2470,14 @@ async function handleGetAllNodes(options) {
2297
2470
  }
2298
2471
 
2299
2472
  // src/cli/commands/export-image.ts
2300
- import { Command as Command5 } from "commander";
2301
- import { writeFileSync as writeFileSync6, unlinkSync as unlinkSync2 } from "fs";
2302
- import { resolve as resolve5, dirname as dirname8, extname, basename } from "path";
2303
- import { mkdirSync as mkdirSync7 } from "fs";
2473
+ import { Command as Command6 } from "commander";
2474
+ import { writeFileSync as writeFileSync7, unlinkSync as unlinkSync2 } from "fs";
2475
+ import { resolve as resolve6, dirname as dirname9, extname, basename } from "path";
2476
+ import { mkdirSync as mkdirSync8 } from "fs";
2304
2477
  import { tmpdir } from "os";
2305
2478
  import { vdConvert } from "vd-tool";
2306
2479
  function createExportImageCommand() {
2307
- return new Command5("export_image").description("\u5BFC\u51FA MasterGo \u8282\u70B9\u4E3A\u56FE\u7247\u6587\u4EF6\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A --output\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u6E05\u7406").option("--link <mgp-link>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u3002\u4E0E --nodeId/--domain/--fileId \u4E8C\u9009\u4E00").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --domain/--fileId \u914D\u5408\u4F7F\u7528").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--format <type>", "\u5BFC\u51FA\u683C\u5F0F\uFF1APNG\uFF08\u65E0\u635F\u900F\u660E\uFF09\u3001JPG\uFF08\u6709\u635F\uFF09\u3001SVG\uFF08\u77E2\u91CF\uFF09\u3001PDF\u3001WEBP\u3001VECTOR\uFF08Android VectorDrawable\uFF09", "PNG").option("--scale <number>", "\u7F29\u653E\u500D\u7387\uFF08\u5982 1\u30012\u30013\uFF09\u3002\u4E0E width/height \u4E92\u65A5").option("--width <number>", "\u56FA\u5B9A\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/height \u4E92\u65A5").option("--height <number>", "\u56FA\u5B9A\u9AD8\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/width \u4E92\u65A5").option("--useAbsoluteBounds", "\u4F7F\u7528\u5B8C\u6574\u5C3A\u5BF8\u3002true: \u5305\u542B\u88AB\u88C1\u526A\u90E8\u5206\uFF0Cfalse: \u53EA\u5BFC\u51FA\u53EF\u89C1\u533A\u57DF", false).option("--no-use-render-bounds", "\u4E0D\u5305\u542B\u7279\u6548\u548C\u5916\u63CF\u8FB9\u3002\u9ED8\u8BA4\u5305\u542B\u9634\u5F71\u3001\u5916\u63CF\u8FB9\u7B49").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2480
+ return new Command6("export_image").description("\u5BFC\u51FA MasterGo \u8282\u70B9\u4E3A\u56FE\u7247\u6587\u4EF6\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A --output\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u7CFB\u7EDF\u6E05\u7406").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\u3002\u5F3A\u70C8\u5EFA\u8BAE\u6307\u5B9A\uFF0C\u5426\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55\u53EF\u80FD\u88AB\u6E05\u7406").option("--link <mgp-link>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u3002\u4E0E --nodeId/--domain/--fileId \u4E8C\u9009\u4E00").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --domain/--fileId \u914D\u5408\u4F7F\u7528").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--format <type>", "\u5BFC\u51FA\u683C\u5F0F\uFF1APNG\uFF08\u65E0\u635F\u900F\u660E\uFF09\u3001JPG\uFF08\u6709\u635F\uFF09\u3001SVG\uFF08\u77E2\u91CF\uFF09\u3001PDF\u3001WEBP\u3001VECTOR\uFF08Android VectorDrawable\uFF09", "PNG").option("--scale <number>", "\u7F29\u653E\u500D\u7387\uFF08\u5982 1\u30012\u30013\uFF09\u3002\u4E0E width/height \u4E92\u65A5").option("--width <number>", "\u56FA\u5B9A\u5BBD\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/height \u4E92\u65A5").option("--height <number>", "\u56FA\u5B9A\u9AD8\u5EA6\uFF08\u50CF\u7D20\uFF09\u3002\u4E0E scale/width \u4E92\u65A5").option("--useAbsoluteBounds", "\u4F7F\u7528\u5B8C\u6574\u5C3A\u5BF8\u3002true: \u5305\u542B\u88AB\u88C1\u526A\u90E8\u5206\uFF0Cfalse: \u53EA\u5BFC\u51FA\u53EF\u89C1\u533A\u57DF", false).option("--no-use-render-bounds", "\u4E0D\u5305\u542B\u7279\u6548\u548C\u5916\u63CF\u8FB9\u3002\u9ED8\u8BA4\u5305\u542B\u9634\u5F71\u3001\u5916\u63CF\u8FB9\u7B49").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2308
2481
  await handleExportImage(options);
2309
2482
  });
2310
2483
  }
@@ -2380,28 +2553,28 @@ async function handleExportImage(options) {
2380
2553
  const ext = getExtension(format);
2381
2554
  let outputPath;
2382
2555
  if (options.output) {
2383
- outputPath = resolve5(options.output);
2556
+ outputPath = resolve6(options.output);
2384
2557
  if (!extname(outputPath)) {
2385
2558
  outputPath = `${outputPath}${ext}`;
2386
2559
  }
2387
2560
  } else {
2388
2561
  const filename = response.filename || `export_${Date.now()}${ext}`;
2389
- outputPath = resolve5(tmpdir(), filename);
2562
+ outputPath = resolve6(tmpdir(), filename);
2390
2563
  console.log("\u8B66\u544A: \u672A\u6307\u5B9A --output\uFF0C\u6587\u4EF6\u5C06\u4FDD\u5B58\u5230\u4E34\u65F6\u76EE\u5F55\uFF0C\u53EF\u80FD\u4F1A\u88AB\u7CFB\u7EDF\u6E05\u7406");
2391
2564
  }
2392
- const outputDir = dirname8(outputPath);
2393
- mkdirSync7(outputDir, { recursive: true });
2565
+ const outputDir = dirname9(outputPath);
2566
+ mkdirSync8(outputDir, { recursive: true });
2394
2567
  const buffer = Buffer.from(response.data, "base64");
2395
2568
  let finalPath = outputPath;
2396
2569
  let finalSize = buffer.length;
2397
2570
  if (isVectorFormat) {
2398
- const tempSvgPath = resolve5(tmpdir(), `temp_${Date.now()}.svg`);
2399
- writeFileSync6(tempSvgPath, buffer);
2571
+ const tempSvgPath = resolve6(tmpdir(), `temp_${Date.now()}.svg`);
2572
+ writeFileSync7(tempSvgPath, buffer);
2400
2573
  try {
2401
- const vectorOutputDir = dirname8(outputPath);
2574
+ const vectorOutputDir = dirname9(outputPath);
2402
2575
  const convertedPath = await convertSvgToVector(tempSvgPath, vectorOutputDir);
2403
2576
  const expectedOutputName = basename(tempSvgPath, ".svg") + ".xml";
2404
- const expectedOutputPath = resolve5(vectorOutputDir, expectedOutputName);
2577
+ const expectedOutputPath = resolve6(vectorOutputDir, expectedOutputName);
2405
2578
  if (expectedOutputPath !== outputPath) {
2406
2579
  const { renameSync, existsSync: existsSync5 } = await import("fs");
2407
2580
  if (existsSync5(expectedOutputPath)) {
@@ -2420,7 +2593,7 @@ async function handleExportImage(options) {
2420
2593
  }
2421
2594
  }
2422
2595
  } else {
2423
- writeFileSync6(outputPath, buffer);
2596
+ writeFileSync7(outputPath, buffer);
2424
2597
  }
2425
2598
  const sizeKB = (finalSize / 1024).toFixed(2);
2426
2599
  console.log(`\u6587\u4EF6\u8DEF\u5F84: ${finalPath}`);
@@ -2482,9 +2655,9 @@ async function convertSvgToVector(svgPath, outputDir) {
2482
2655
  }
2483
2656
 
2484
2657
  // src/cli/commands/execute-code.ts
2485
- import { Command as Command6 } from "commander";
2658
+ import { Command as Command7 } from "commander";
2486
2659
  function createExecuteCodeCommand() {
2487
- return new Command6("execute_code").description("\u5728 MasterGo \u9875\u9762\u6267\u884C\u81EA\u5B9A\u4E49 JavaScript \u4EE3\u7801\u3002\u901A\u8FC7 mg \u53D8\u91CF\u8BBF\u95EE MasterGo API\uFF0C\u7ED3\u679C\u4F1A\u88AB JSON \u5E8F\u5217\u5316\u8FD4\u56DE").argument("<code>", "\u8981\u6267\u884C\u7684\u4EE3\u7801\u3002\u53EF\u4F7F\u7528 mg \u53D8\u91CF\uFF0C\u5982 mg.currentPage.name\u3001mg.currentPage.selection").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (code, options) => {
2660
+ return new Command7("execute_code").description("\u5728 MasterGo \u9875\u9762\u6267\u884C\u81EA\u5B9A\u4E49 JavaScript \u4EE3\u7801\u3002\u901A\u8FC7 mg \u53D8\u91CF\u8BBF\u95EE MasterGo API\uFF0C\u7ED3\u679C\u4F1A\u88AB JSON \u5E8F\u5217\u5316\u8FD4\u56DE").argument("<code>", "\u8981\u6267\u884C\u7684\u4EE3\u7801\u3002\u53EF\u4F7F\u7528 mg \u53D8\u91CF\uFF0C\u5982 mg.currentPage.name\u3001mg.currentPage.selection").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (code, options) => {
2488
2661
  await handleExecuteCode(code, options);
2489
2662
  });
2490
2663
  }
@@ -2530,13 +2703,13 @@ async function handleExecuteCode(code, options) {
2530
2703
  }
2531
2704
 
2532
2705
  // src/cli/commands/get-all-pages.ts
2533
- import { Command as Command7 } from "commander";
2534
- import { writeFileSync as writeFileSync7 } from "fs";
2535
- import { resolve as resolve6, dirname as dirname9 } from "path";
2536
- import { mkdirSync as mkdirSync8 } from "fs";
2706
+ import { Command as Command8 } from "commander";
2707
+ import { writeFileSync as writeFileSync8 } from "fs";
2708
+ import { resolve as resolve7, dirname as dirname10 } from "path";
2709
+ import { mkdirSync as mkdirSync9 } from "fs";
2537
2710
  import { tmpdir as tmpdir2 } from "os";
2538
2711
  function createGetAllPagesCommand() {
2539
- return new Command7("get_all_pages").description("\u83B7\u53D6 MasterGo \u6587\u6863\u7684\u6240\u6709\u9875\u9762\u4FE1\u606F\u3002\u4E0D\u6307\u5B9A --output \u65F6\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55").option("--link <url>", "\u9875\u9762\u94FE\u63A5\u3002\u652F\u6301\u5B8C\u6574 URL \u6216 mgp:// \u534F\u8BAE").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\u3002\u4ECE URL \u4E2D /file/ \u540E\u9762\u7684\u6570\u5B57").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --fileId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u4E0D\u6307\u5B9A\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2712
+ return new Command8("get_all_pages").description("\u83B7\u53D6 MasterGo \u6587\u6863\u7684\u6240\u6709\u9875\u9762\u4FE1\u606F\u3002\u4E0D\u6307\u5B9A --output \u65F6\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55").option("--link <url>", "\u9875\u9762\u94FE\u63A5\u3002\u652F\u6301\u5B8C\u6574 URL \u6216 mgp:// \u534F\u8BAE").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\u3002\u4ECE URL \u4E2D /file/ \u540E\u9762\u7684\u6570\u5B57").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --fileId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u4E0D\u6307\u5B9A\u5219\u4FDD\u5B58\u5230\u7CFB\u7EDF\u4E34\u65F6\u76EE\u5F55").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2540
2713
  await handleGetAllPages(options);
2541
2714
  });
2542
2715
  }
@@ -2575,15 +2748,15 @@ async function handleGetAllPages(options) {
2575
2748
  );
2576
2749
  let outputPath;
2577
2750
  if (options.output) {
2578
- outputPath = resolve6(options.output);
2751
+ outputPath = resolve7(options.output);
2579
2752
  } else {
2580
2753
  const filename = `pages_${fileId || "current"}_${Date.now()}.json`;
2581
- outputPath = resolve6(tmpdir2(), filename);
2754
+ outputPath = resolve7(tmpdir2(), filename);
2582
2755
  }
2583
- const outputDir = dirname9(outputPath);
2584
- mkdirSync8(outputDir, { recursive: true });
2756
+ const outputDir = dirname10(outputPath);
2757
+ mkdirSync9(outputDir, { recursive: true });
2585
2758
  const jsonContent = JSON.stringify(data, null, options.pretty ? 2 : 0);
2586
- writeFileSync7(outputPath, jsonContent, "utf-8");
2759
+ writeFileSync8(outputPath, jsonContent, "utf-8");
2587
2760
  const size = jsonContent.length;
2588
2761
  const sizeKB = (size / 1024).toFixed(2);
2589
2762
  console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
@@ -2600,12 +2773,12 @@ async function handleGetAllPages(options) {
2600
2773
  }
2601
2774
 
2602
2775
  // src/cli/commands/get-node-for-space.ts
2603
- import { Command as Command8 } from "commander";
2604
- import { writeFileSync as writeFileSync8 } from "fs";
2605
- import { resolve as resolve7, dirname as dirname10 } from "path";
2606
- import { mkdirSync as mkdirSync9 } from "fs";
2776
+ import { Command as Command9 } from "commander";
2777
+ import { writeFileSync as writeFileSync9 } from "fs";
2778
+ import { resolve as resolve8, dirname as dirname11 } from "path";
2779
+ import { mkdirSync as mkdirSync10 } from "fs";
2607
2780
  function createGetNodeForSpaceCommand() {
2608
- return new Command8("get_node_for_space").description("\u83B7\u53D6\u8282\u70B9\u6216\u9875\u9762\u7684\u7A7A\u95F4\u4F4D\u7F6E\u4FE1\u606F\uFF08id\u3001name\u3001x\u3001y\u3001width\u3001height\uFF09\uFF0C\u7528\u4E8E AI \u7406\u89E3\u5143\u7D20\u5E03\u5C40\u3002\u9ED8\u8BA4\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\u3002\u652F\u6301 nodeId \u548C pageId \u94FE\u63A5").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --link \u4E8C\u9009\u4E00").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF08\u652F\u6301 nodeId \u548C pageId\uFF09\u3002\u4E0E --nodeId \u4E8C\u9009\u4E00").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --nodeId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u548C --nodeId \u914D\u5408\u4F7F\u7528").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 99\uFF08\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\uFF09", "99").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2781
+ return new Command9("get_node_for_space").description("\u83B7\u53D6\u8282\u70B9\u6216\u9875\u9762\u7684\u7A7A\u95F4\u4F4D\u7F6E\u4FE1\u606F\uFF08id\u3001name\u3001x\u3001y\u3001width\u3001height\uFF09\uFF0C\u7528\u4E8E AI \u7406\u89E3\u5143\u7D20\u5E03\u5C40\u3002\u9ED8\u8BA4\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\u3002\u652F\u6301 nodeId \u548C pageId \u94FE\u63A5").option("--nodeId <id>", "\u8282\u70B9 ID\uFF0C\u683C\u5F0F\u5982 123:456\u3002\u4E0E --link \u4E8C\u9009\u4E00").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF08\u652F\u6301 nodeId \u548C pageId\uFF09\u3002\u4E0E --nodeId \u4E8C\u9009\u4E00").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com\u3002\u4E0E --nodeId \u914D\u5408\u4F7F\u7528", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u548C --nodeId \u914D\u5408\u4F7F\u7528").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6\uFF0C\u9ED8\u8BA4 99\uFF08\u83B7\u53D6\u6700\u6DF1\u5C42\u7EA7\uFF09", "99").option("--includeInvisible", "\u5305\u542B\u4E0D\u53EF\u89C1\u8282\u70B9", false).option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2609
2782
  await handleGetNodeForSpace(options);
2610
2783
  });
2611
2784
  }
@@ -2686,11 +2859,11 @@ async function handleGetNodeForSpace(options) {
2686
2859
  );
2687
2860
  }
2688
2861
  const spaceData = extractSpaceInfo(data);
2689
- const outputPath = resolve7(options.output);
2690
- const outputDir = dirname10(outputPath);
2691
- mkdirSync9(outputDir, { recursive: true });
2862
+ const outputPath = resolve8(options.output);
2863
+ const outputDir = dirname11(outputPath);
2864
+ mkdirSync10(outputDir, { recursive: true });
2692
2865
  const jsonContent = JSON.stringify(spaceData, null, options.pretty ? 2 : 0);
2693
- writeFileSync8(outputPath, jsonContent, "utf-8");
2866
+ writeFileSync9(outputPath, jsonContent, "utf-8");
2694
2867
  const size = jsonContent.length;
2695
2868
  const sizeKB = (size / 1024).toFixed(2);
2696
2869
  console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
@@ -2722,11 +2895,11 @@ async function handleGetNodeForSpace(options) {
2722
2895
  }
2723
2896
 
2724
2897
  // src/cli/commands/get-comments.ts
2725
- import { Command as Command9 } from "commander";
2726
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
2727
- import { dirname as dirname11, resolve as resolve8 } from "path";
2898
+ import { Command as Command10 } from "commander";
2899
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "fs";
2900
+ import { dirname as dirname12, resolve as resolve9 } from "path";
2728
2901
  function createGetCommentsCommand() {
2729
- return new Command9("get_comments").description("\u83B7\u53D6 MasterGo \u8BC4\u8BBA\u533A\u5185\u5BB9").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u6216\u9875\u9762 URL\uFF08\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u83B7\u53D6\u5F53\u524D\u9875\u9762\uFF09").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--include-deleted", "\u5305\u542B\u5DF2\u5220\u9664\u7684\u8BC4\u8BBA", false).option("--no-include-nearby", "\u4E0D\u8BA1\u7B97\u9644\u8FD1\u8282\u70B9").option("--nearby-limit <number>", "\u9644\u8FD1\u8282\u70B9\u6570\u91CF\uFF08\u9ED8\u8BA4 5\uFF09", "5").option("--nearby-depth <number>", "\u9644\u8FD1\u8282\u70B9\u641C\u7D22\u6DF1\u5EA6\uFF08\u9ED8\u8BA4 3\uFF09", "3").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2902
+ return new Command10("get_comments").description("\u83B7\u53D6 MasterGo \u8BC4\u8BBA\u533A\u5185\u5BB9").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\u6216\u9875\u9762 URL\uFF08\u53EF\u9009\uFF0C\u4E0D\u63D0\u4F9B\u5219\u83B7\u53D6\u5F53\u524D\u9875\u9762\uFF09").requiredOption("--output <path>", "\u8F93\u51FA JSON \u6587\u4EF6\u8DEF\u5F84").option("--include-deleted", "\u5305\u542B\u5DF2\u5220\u9664\u7684\u8BC4\u8BBA", false).option("--no-include-nearby", "\u4E0D\u8BA1\u7B97\u9644\u8FD1\u8282\u70B9").option("--nearby-limit <number>", "\u9644\u8FD1\u8282\u70B9\u6570\u91CF\uFF08\u9ED8\u8BA4 5\uFF09", "5").option("--nearby-depth <number>", "\u9644\u8FD1\u8282\u70B9\u641C\u7D22\u6DF1\u5EA6\uFF08\u9ED8\u8BA4 3\uFF09", "3").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2730
2903
  await handleGetComments(options);
2731
2904
  });
2732
2905
  }
@@ -2765,14 +2938,14 @@ async function handleGetComments(options) {
2765
2938
  params,
2766
2939
  pageUrl
2767
2940
  );
2768
- const outputPath = resolve8(options.output);
2769
- mkdirSync10(dirname11(outputPath), { recursive: true });
2941
+ const outputPath = resolve9(options.output);
2942
+ mkdirSync11(dirname12(outputPath), { recursive: true });
2770
2943
  const outputData = {
2771
2944
  extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
2772
2945
  ...result
2773
2946
  };
2774
2947
  const jsonContent = JSON.stringify(outputData, null, options.pretty ? 2 : 0);
2775
- writeFileSync9(outputPath, jsonContent, "utf-8");
2948
+ writeFileSync10(outputPath, jsonContent, "utf-8");
2776
2949
  console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
2777
2950
  const displayPageUrl = pageUrl || result.pageUrl;
2778
2951
  if (displayPageUrl) {
@@ -2803,10 +2976,605 @@ function parseNumberOption(value, fallback) {
2803
2976
  return fallback;
2804
2977
  }
2805
2978
 
2979
+ // src/cli/commands/list-fonts.ts
2980
+ import { Command as Command11 } from "commander";
2981
+ function resolveListFontsTargetPageUrl(options) {
2982
+ if (options.link && options.fileId) {
2983
+ throw new MGError("E011" /* INVALID_PARAMS */, "--link \u548C --fileId \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
2984
+ }
2985
+ if (options.link) {
2986
+ const parsed = parseMgpLink(options.link);
2987
+ if (!parsed) {
2988
+ throw new MGError("E010" /* INVALID_LINK */, `\u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F: ${options.link}`);
2989
+ }
2990
+ return parsed.pageUrl;
2991
+ }
2992
+ if (options.fileId) {
2993
+ return buildPageUrl(options.domain || "mastergo.netease.com", options.fileId, options.pageType);
2994
+ }
2995
+ return void 0;
2996
+ }
2997
+ function createListFontsCommand() {
2998
+ return new Command11("list_fonts").description("\u67E5\u8BE2\u5F53\u524D MasterGo \u9875\u9762\u53EF\u7528\u5B57\u4F53\u3002\u7528\u4E8E AI \u521B\u5EFA/\u590D\u523B UI \u524D\u9884\u67E5\u5B57\u4F53\uFF0C\u907F\u514D\u76F2\u76EE\u4F9D\u8D56 execute_code \u8C03\u8BD5\u63A2\u9488").option("--filter <keyword>", "\u6309\u5B57\u4F53 family/style/localized \u540D\u79F0\u8FC7\u6EE4\uFF08\u5927\u5C0F\u5199\u4E0D\u654F\u611F\uFF09\uFF0C\u5982 PingFang\u3001Source Han Sans\u3001\u601D\u6E90").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").addHelpText("after", `
2999
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3000
+
3001
+ # \u67E5\u8BE2\u5F53\u524D\u8FDE\u63A5\u9875\u9762\u5168\u90E8\u53EF\u7528\u5B57\u4F53
3002
+ mg-cli list_fonts --pretty
3003
+
3004
+ # AI \u521B\u5EFA UI \u524D\u9884\u67E5 PingFang / \u601D\u6E90\u9ED1\u4F53\u662F\u5426\u53EF\u7528
3005
+ mg-cli list_fonts --fileId <\u76EE\u6807\u6587\u4EF6> --filter "PingFang" --pretty
3006
+ mg-cli list_fonts --fileId <\u76EE\u6807\u6587\u4EF6> --filter "Source Han Sans" --pretty
3007
+
3008
+ \u8BF4\u660E\uFF1A
3009
+ - \u8FD9\u662F\u6B63\u5F0F\u5B57\u4F53\u9884\u67E5\u547D\u4EE4\uFF1Bexecute_code \u4EC5\u4FDD\u7559\u7ED9\u4E34\u65F6\u8C03\u8BD5\uFF0C\u4E0D\u5E94\u8FDB\u5165\u56FA\u5B9A\u5DE5\u4F5C\u6D41\u3002
3010
+ - \u8F93\u51FA\u5305\u542B { total, fonts }\uFF0Cfonts \u6761\u76EE\u4FDD\u7559 MasterGo \u8FD4\u56DE\u7684 fontName/localizedFontName/referrer \u7B49\u5B57\u6BB5\u3002
3011
+ `).action(async (options) => {
3012
+ await handleListFonts(options);
3013
+ });
3014
+ }
3015
+ async function handleListFonts(options) {
3016
+ const tracker = createCommandTracker("list_fonts");
3017
+ let pageUrl;
3018
+ try {
3019
+ pageUrl = resolveListFontsTargetPageUrl(options);
3020
+ } catch (error) {
3021
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3022
+ tracker.failure(error instanceof Error ? error : void 0);
3023
+ process.exit(2);
3024
+ }
3025
+ const client = new MGClient({
3026
+ noAutoStart: options.noAutoStart,
3027
+ noRetry: options.noRetry
3028
+ });
3029
+ try {
3030
+ await client.connect();
3031
+ const params = {};
3032
+ if (options.filter) params.filter = options.filter;
3033
+ const result = await client.requestWithRetry("list_fonts" /* LIST_FONTS */, params, pageUrl);
3034
+ console.log(JSON.stringify(result, null, options.pretty ? 2 : 0));
3035
+ tracker.success();
3036
+ } catch (error) {
3037
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3038
+ tracker.failure(error instanceof Error ? error : void 0);
3039
+ process.exit(1);
3040
+ } finally {
3041
+ client.close();
3042
+ }
3043
+ }
3044
+
3045
+ // src/cli/commands/list-library.ts
3046
+ import { Command as Command12 } from "commander";
3047
+ import { writeFileSync as writeFileSync11, mkdirSync as mkdirSync12 } from "fs";
3048
+ import { resolve as resolve10, dirname as dirname13 } from "path";
3049
+ function buildListLibraryParams(options) {
3050
+ const filter = typeof options.filter === "string" ? options.filter.trim() : "";
3051
+ return filter ? { filter } : {};
3052
+ }
3053
+ function createListLibraryCommand() {
3054
+ return new Command12("list_library").description("\u5217\u51FA\u5F53\u524D\u56E2\u961F\u53EF\u7528\u7684\u5DF2\u53D1\u5E03\u56E2\u961F\u5E93\u7EC4\u4EF6/\u7EC4\u4EF6\u96C6\uFF08\u53EA\u8BFB\uFF09\u3002\u8F93\u51FA\u5305\u542B\u7EC4\u4EF6 ukey\uFF0C\u4F9B import_component \u5BFC\u5165\uFF1B\u4E0D\u652F\u6301\u521B\u5EFA\u6216\u53D1\u5E03\u56E2\u961F\u5E93").option("--filter <keyword>", "\u6309\u5E93\u540D/\u7EC4\u4EF6\u540D/ukey \u8FC7\u6EE4\uFF08\u5927\u5C0F\u5199\u4E0D\u654F\u611F\uFF09\uFF0C\u5982 WeUI\u3001\u6309\u94AE\u3001ukey \u7247\u6BB5").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u7ED3\u679C JSON \u8F93\u51FA\u8DEF\u5F84\uFF08{libraries,totalLibraries,totalComponents}\uFF09\u3002\u4E0D\u63D0\u4F9B\u5219\u7ED3\u679C\u6253\u5230 stdout").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").addHelpText("after", `
3055
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3056
+
3057
+ # \u5217\u51FA\u5F53\u524D\u8FDE\u63A5\u9875\u9762\u53EF\u7528\u7684\u5DF2\u53D1\u5E03\u56E2\u961F\u5E93\u7EC4\u4EF6/\u7EC4\u4EF6\u96C6
3058
+ mg-cli list_library --pretty
3059
+
3060
+ # \u6309\u5E93\u540D\u6216\u7EC4\u4EF6\u540D\u8FC7\u6EE4\uFF0C\u5E76\u4FDD\u7559 ukey \u4F9B\u5BFC\u5165\u4F7F\u7528
3061
+ mg-cli list_library --fileId <\u76EE\u6807\u6587\u4EF6> --filter "WeUI" --pretty
3062
+
3063
+ \u8BF4\u660E\uFF1A
3064
+ - \u672C\u547D\u4EE4\u53EA\u8BFB\u53D6\u5DF2\u53D1\u5E03\u56E2\u961F\u5E93\u8D44\u6E90\uFF0C\u4E0D\u521B\u5EFA\u3001\u4E0D\u53D1\u5E03\u56E2\u961F\u5E93\u3002
3065
+ - \u8F93\u51FA\u4E2D components[].ukey \u53EF\u4F20\u7ED9 import_component --ukey \u6216 --ukeySet\u3002
3066
+ `).action(async (options) => {
3067
+ await handleListLibrary(options);
3068
+ });
3069
+ }
3070
+ async function handleListLibrary(options) {
3071
+ const tracker = createCommandTracker("list_library");
3072
+ let pageUrl;
3073
+ let params;
3074
+ try {
3075
+ pageUrl = resolveListFontsTargetPageUrl(options);
3076
+ params = buildListLibraryParams(options);
3077
+ } catch (error) {
3078
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3079
+ tracker.failure(error instanceof Error ? error : void 0);
3080
+ process.exit(2);
3081
+ }
3082
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: options.noRetry });
3083
+ try {
3084
+ await client.connect();
3085
+ const result = await client.requestWithRetry("list_library" /* LIST_LIBRARY */, params, pageUrl);
3086
+ const jsonText = JSON.stringify(result, null, options.pretty ? 2 : 0);
3087
+ if (options.output) {
3088
+ const outputPath = resolve10(options.output);
3089
+ mkdirSync12(dirname13(outputPath), { recursive: true });
3090
+ writeFileSync11(outputPath, jsonText, "utf-8");
3091
+ }
3092
+ console.log(`\u56E2\u961F\u5E93: ${result.totalLibraries} \u4E2A\uFF0C\u7EC4\u4EF6/\u7EC4\u4EF6\u96C6: ${result.totalComponents} \u4E2A`);
3093
+ if (options.output) {
3094
+ console.log(`\u7ED3\u679C\u6587\u4EF6: ${resolve10(options.output)}`);
3095
+ } else {
3096
+ console.log(jsonText);
3097
+ }
3098
+ tracker.success();
3099
+ } catch (error) {
3100
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3101
+ tracker.failure(error instanceof Error ? error : void 0);
3102
+ process.exit(1);
3103
+ } finally {
3104
+ client.close();
3105
+ }
3106
+ }
3107
+
3108
+ // src/cli/commands/import-component.ts
3109
+ import { Command as Command14 } from "commander";
3110
+ import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync14 } from "fs";
3111
+ import { resolve as resolve12, dirname as dirname15 } from "path";
3112
+
3113
+ // src/cli/commands/create-node.ts
3114
+ import { Command as Command13 } from "commander";
3115
+ import { readFileSync as readFileSync4, writeFileSync as writeFileSync12, mkdirSync as mkdirSync13 } from "fs";
3116
+ import { resolve as resolve11, dirname as dirname14 } from "path";
3117
+ var CREATE_NODE_DEFAULT_TIMEOUT_SECONDS = 120;
3118
+ function resolveTimeoutMs(timeoutSeconds, defaultSeconds = CREATE_NODE_DEFAULT_TIMEOUT_SECONDS) {
3119
+ const n = typeof timeoutSeconds === "string" ? Number(timeoutSeconds) : timeoutSeconds;
3120
+ if (typeof n !== "number" || !Number.isFinite(n) || n <= 0) {
3121
+ return defaultSeconds * 1e3;
3122
+ }
3123
+ return Math.round(n * 1e3);
3124
+ }
3125
+ function countNodes(node) {
3126
+ if (!node || typeof node !== "object") return 0;
3127
+ let count = 1;
3128
+ if (Array.isArray(node.children)) {
3129
+ for (const child of node.children) {
3130
+ count += countNodes(child);
3131
+ }
3132
+ }
3133
+ return count;
3134
+ }
3135
+ function summarizeWarnings(warnings) {
3136
+ const summary = {};
3137
+ for (const w of warnings ?? []) {
3138
+ summary[w.kind] = (summary[w.kind] ?? 0) + 1;
3139
+ }
3140
+ return summary;
3141
+ }
3142
+ function exitCodeForError(error) {
3143
+ if (error instanceof MGError && (error.code === "E019" /* EDIT_NOT_ALLOWED */ || error.code === "E020" /* CREATE_NODE_FAILED */)) {
3144
+ return 1;
3145
+ }
3146
+ return 2;
3147
+ }
3148
+ function resolveTargetPageUrl(options) {
3149
+ if (options.link && options.fileId) {
3150
+ throw new MGError("E011" /* INVALID_PARAMS */, "--link \u548C --fileId \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
3151
+ }
3152
+ if (options.link) {
3153
+ const parsed = parseMgpLink(options.link);
3154
+ if (!parsed) {
3155
+ throw new MGError("E010" /* INVALID_LINK */, `\u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F: ${options.link}`);
3156
+ }
3157
+ return parsed.pageUrl;
3158
+ }
3159
+ if (options.fileId) {
3160
+ const domain = options.domain || "mastergo.netease.com";
3161
+ return buildPageUrl(domain, options.fileId, options.pageType);
3162
+ }
3163
+ return void 0;
3164
+ }
3165
+ function parsePropsInput(propsArg) {
3166
+ if (!propsArg) return {};
3167
+ const trimmed = propsArg.trim();
3168
+ try {
3169
+ if (trimmed.startsWith("{")) {
3170
+ return JSON.parse(trimmed);
3171
+ }
3172
+ return JSON.parse(readFileSync4(resolve11(trimmed), "utf-8"));
3173
+ } catch (e) {
3174
+ throw new MGError(
3175
+ "E011" /* INVALID_PARAMS */,
3176
+ `--props \u89E3\u6790\u5931\u8D25\uFF08\u652F\u6301\u5185\u8054 JSON \u6216 JSON \u6587\u4EF6\u8DEF\u5F84\uFF09: ${e instanceof Error ? e.message : e}`
3177
+ );
3178
+ }
3179
+ }
3180
+ function buildCreateParams(options) {
3181
+ if (options.input && options.type) {
3182
+ throw new MGError("E011" /* INVALID_PARAMS */, "--input\uFF08\u6574\u6811\u6A21\u5F0F\uFF09\u4E0E --type\uFF08\u9010\u8282\u70B9\u6A21\u5F0F\uFF09\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
3183
+ }
3184
+ if (!options.input && !options.type) {
3185
+ throw new MGError("E011" /* INVALID_PARAMS */, "\u5FC5\u987B\u63D0\u4F9B --input\uFF08\u6574\u6811\u6A21\u5F0F\uFF09\u6216 --type\uFF08\u9010\u8282\u70B9\u6A21\u5F0F\uFF09\u4E4B\u4E00");
3186
+ }
3187
+ if (options.childIds && options.type !== "GROUP") {
3188
+ throw new MGError("E011" /* INVALID_PARAMS */, "--childIds \u4EC5\u9002\u7528\u4E8E --type GROUP");
3189
+ }
3190
+ let node;
3191
+ if (options.input) {
3192
+ node = JSON.parse(readFileSync4(resolve11(options.input), "utf-8"));
3193
+ if (!node || typeof node !== "object" || !node.type) {
3194
+ throw new MGError("E011" /* INVALID_PARAMS */, `--input \u4E0D\u662F\u6709\u6548\u7684 NodeInfo JSON: ${options.input}`);
3195
+ }
3196
+ } else {
3197
+ const props = parsePropsInput(options.props);
3198
+ if ("children" in props) {
3199
+ throw new MGError("E011" /* INVALID_PARAMS */, "\u9010\u8282\u70B9\u6A21\u5F0F\u7684 --props \u4E0D\u63A5\u53D7 children\uFF08\u5B50\u8282\u70B9\u8BF7\u5355\u72EC create_node\uFF0CGROUP \u7528 --childIds\uFF09");
3200
+ }
3201
+ node = { ...props, type: options.type };
3202
+ }
3203
+ const params = { node };
3204
+ if (options.parentId) params.parentId = options.parentId;
3205
+ if (options.x !== void 0) params.x = Number(options.x);
3206
+ if (options.y !== void 0) params.y = Number(options.y);
3207
+ if (options.childIds) {
3208
+ params.childIds = options.childIds.split(",").map((s) => s.trim()).filter(Boolean);
3209
+ }
3210
+ return params;
3211
+ }
3212
+ function createCreateNodeCommand() {
3213
+ return new Command13("create_node").description(
3214
+ "\u5728\u76EE\u6807\u9875\u9762\u521B\u5EFA\u8282\u70B9\uFF08\u5199\u64CD\u4F5C\uFF09\uFF0C\u4E24\u79CD\u6A21\u5F0F\uFF1A\u2460 \u6574\u6811\u6A21\u5F0F --input\uFF1A\u628A get_node_by_id --raw \u5BFC\u51FA\u7684\u5168\u6811 JSON \u4E00\u952E\u91CD\u5EFA\uFF08\u590D\u5236\u6574\u4E2A\u754C\u9762\uFF09\uFF1B\u2461 \u9010\u8282\u70B9\u6A21\u5F0F --type + --props\uFF1A\u521B\u5EFA\u5355\u4E2A\u8282\u70B9\u5E76\u8FD4\u56DE\u65B0\u8282\u70B9 ID\uFF0C\u7528\u4E8E\u9010\u6B65\u642D\u5EFA\u754C\u9762\u3002props \u5B57\u6BB5\u4E0E get_node_by_id \u8F93\u51FA\u540C\u540D\uFF08\u8BFB\u5199\u5BF9\u79F0\uFF09\u3002\u6CE8\u610F\uFF1A\u521B\u5EFA\u6210\u529F \u2260 \u5C5E\u6027\u5168\u90E8\u751F\u6548\uFF0C\u90E8\u5206\u5C5E\u6027\u4F1A\u88AB\u9875\u9762\u9759\u9ED8\u62D2\u7EDD\uFF08\u8BB0\u5F55\u5728\u8FD4\u56DE\u7684 warnings \u91CC\uFF09\uFF0C\u52A1\u5FC5\u56DE\u8BFB\u8282\u70B9\u6570\u636E\u81EA\u68C0"
3215
+ ).option("--input <path>", "\u6574\u6811\u6A21\u5F0F\uFF1A\u8282\u70B9 JSON \u6587\u4EF6\u8DEF\u5F84\uFF08get_node_by_id --raw \u5BFC\u51FA\uFF0C\u542B children \u5168\u6811\uFF09\u3002\u4E0E --type \u4E92\u65A5").option("--type <TYPE>", "\u9010\u8282\u70B9\u6A21\u5F0F\uFF1A\u8282\u70B9\u7C7B\u578B FRAME|RECTANGLE|TEXT|ELLIPSE|POLYGON|STAR|LINE|PEN|GROUP\uFF08\u5176\u4ED6\u7C7B\u578B\u4F1A\u964D\u7EA7\u4E3A FRAME \u5E76\u8BB0 warning\uFF09\u3002\u4E0E --input \u4E92\u65A5").option("--props <spec>", '\u9010\u8282\u70B9\u6A21\u5F0F\uFF1A\u8282\u70B9\u5C5E\u6027\uFF0C\u5185\u8054 JSON\uFF08\u4EE5 { \u5F00\u5934\uFF09\u6216 JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u5B57\u6BB5\u4E0E get_node_by_id \u8F93\u51FA\u540C\u540D\uFF0C\u5982 {"name":"\u6807\u9898","x":16,"y":8,"width":100,"height":40,"fills":[...]}\u3002\u4E0D\u63A5\u53D7 children').option("--childIds <ids>", "\u4EC5 --type GROUP\uFF1A\u9017\u53F7\u5206\u9694\u7684\u5DF2\u5EFA\u8282\u70B9 ID \u5217\u8868\uFF0C\u628A\u5B83\u4EEC\u6210\u7EC4\u3002\u6210\u7EC4\u524D\u5B50\u8282\u70B9\u987B\u5DF2\u6309\u7236\u5BB9\u5668\u5750\u6807\u7CFB\u653E\u597D\uFF08\u89C1\u4E0B\u65B9 GROUP \u6D41\u7A0B\u8BF4\u660E\uFF09").option("--parentId <id>", "\u76EE\u6807\u7236\u8282\u70B9 ID\uFF0C\u7F3A\u7701 = \u76EE\u6807\u9875\u5F53\u524D\u9875\u9762\u3002\u9010\u8282\u70B9\u6A21\u5F0F\u4E0B\u5E94\u4F20\u4E0A\u4E00\u6B65\u8FD4\u56DE\u7684\u65B0\u8282\u70B9 ID").option("--x <n>", "\u8986\u76D6\u8282\u70B9\u653E\u7F6E\u4F4D\u7F6E X\uFF08\u7F3A\u7701\u7528 props/JSON \u91CC\u7684 x\uFF09").option("--y <n>", "\u8986\u76D6\u8282\u70B9\u653E\u7F6E\u4F4D\u7F6E Y\uFF08\u7F3A\u7701\u7528 props/JSON \u91CC\u7684 y\uFF09").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option(
3216
+ "--timeout <seconds>",
3217
+ `\u8BF7\u6C42\u8D85\u65F6\uFF08\u79D2\uFF09\uFF0C\u9ED8\u8BA4 ${CREATE_NODE_DEFAULT_TIMEOUT_SECONDS}\u3002\u6574\u6811\u91CD\u5EFA\u5927\u6811\u65F6\u5FC5\u987B\u653E\u5BBD\uFF08\u5982 300\uFF09`,
3218
+ String(CREATE_NODE_DEFAULT_TIMEOUT_SECONDS)
3219
+ ).option("--output <path>", "\u7ED3\u679C JSON \u8F93\u51FA\u8DEF\u5F84\uFF08{nodeId, idMap, warnings}\uFF09\u3002\u4E0D\u63D0\u4F9B\u5219\u7ED3\u679C\u6253\u5230 stdout").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").addHelpText("after", `
3220
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3221
+
3222
+ \u3010\u6574\u6811\u6A21\u5F0F\uFF08\u590D\u5236\u754C\u9762\uFF09\u3011
3223
+ mg-cli create_node --input tree.json --fileId <\u76EE\u6807\u6587\u4EF6> --timeout 300 --output result.json
3224
+ # result.json \u91CC idMap \u662F\u300C\u6E90\u8282\u70B9 ID \u2192 \u65B0\u8282\u70B9 ID\u300D\u7684\u5168\u6811\u6620\u5C04
3225
+
3226
+ \u3010\u9010\u8282\u70B9\u6A21\u5F0F\uFF08\u9010\u6B65\u642D\u5EFA\u754C\u9762\uFF09\u3011
3227
+ # 1. \u5EFA\u7236\u5BB9\u5668\uFF0C\u62FF\u5230\u65B0\u8282\u70B9 ID
3228
+ mg-cli create_node --type FRAME --props '{"name":"\u5361\u7247","x":0,"y":0,"width":343,"height":88}' --fileId <\u76EE\u6807\u6587\u4EF6>
3229
+ # 2. \u5728\u91CC\u9762\u5EFA\u5B50\u8282\u70B9\uFF08--parentId \u7528\u4E0A\u4E00\u6B65\u8FD4\u56DE\u7684 nodeId\uFF09
3230
+ mg-cli create_node --type TEXT --parentId <\u65B0FrameID> --props '{"name":"\u6807\u9898","x":16,"y":12,"characters":"\u4F60\u597D","textStyles":[{"start":0,"end":2,"textStyle":{"fontName":{"family":"MiSans","style":"Medium"},"fontSize":16}}]}' --fileId <\u76EE\u6807\u6587\u4EF6>
3231
+
3232
+ \u3010GROUP \u6D41\u7A0B\uFF08\u5148\u5B50\u540E\u7EC4\uFF09\u3011
3233
+ GROUP \u7684\u5C3A\u5BF8/\u4F4D\u7F6E\u7531\u5B50\u8282\u70B9\u5305\u56F4\u76D2\u81EA\u52A8\u6D3E\u751F\uFF0C\u5FC5\u987B\u5148\u5EFA\u5B50\u8282\u70B9\u518D\u6210\u7EC4\uFF1A
3234
+ 1. \u628A\u6BCF\u4E2A\u5B50\u8282\u70B9\u76F4\u63A5\u5EFA\u5728 GROUP \u7684\u7236\u5BB9\u5668\u91CC\uFF0C\u5750\u6807\u6362\u7B97\u516C\u5F0F\uFF1A
3235
+ \u5B50\u8282\u70B9\u5728\u7236\u5BB9\u5668\u4E2D\u7684 x = \u6E90 GROUP \u7684 x + \u6E90\u5B50\u8282\u70B9\u7684 x\uFF08y \u540C\u7406\uFF09
3236
+ 2. mg-cli create_node --type GROUP --childIds <\u5B50ID1,\u5B50ID2> --props '{"name":"\u6309\u94AE"}' --fileId <\u76EE\u6807\u6587\u4EF6>
3237
+ \u6CE8\u610F\uFF1A\u6210\u7EC4\u4F1A\u91CD\u7F6E\u5B50\u8282\u70B9\u7684 constraints\uFF0C\u5982\u9700 constraints \u8BF7\u5728\u6210\u7EC4\u540E\u7528 update_node \u8865\u8BBE
3238
+
3239
+ \u3010\u91CD\u8981\u7EA6\u675F\u3011
3240
+ - TEXT \u6587\u672C\u6837\u5F0F\u5199\u5728 props.textStyles\uFF08\u5206\u6BB5\u6570\u7EC4\uFF09\uFF0C\u5B57\u4F53\u7F3A\u5931\u65F6\u4F1A\u7528\u56DE\u9000\u5B57\u4F53\u5E76\u8BB0 FONT_FALLBACK warning
3241
+ - \u81EA\u52A8\u5E03\u5C40\u5BB9\u5668\u7684 mainAxisSizingMode/crossAxisSizingMode \u82E5\u4E3A AUTO\uFF0C\u5FC5\u987B\u7B49\u5B50\u8282\u70B9\u5168\u90E8
3242
+ \u521B\u5EFA\u5B8C\u540E\u7528 update_node \u8BBE\u7F6E\uFF08\u5148\u8BBE\u4F1A\u88AB\u5B50\u8282\u70B9\u8FFD\u52A0\u8FC7\u7A0B\u91CD\u7F6E\uFF09
3243
+ - \u521B\u5EFA \u2260 \u6210\u529F\uFF1A\u90E8\u5206\u5C5E\u6027\u4F1A\u88AB\u9875\u9762\u9759\u9ED8\u62D2\u7EDD\uFF08warnings \u91CC\u6709\u8BB0\u5F55\uFF0C\u4F46 warnings \u4E5F\u4E0D\u5B8C\u5907\uFF09\uFF0C
3244
+ \u6BCF\u5EFA\u5B8C\u4E00\u90E8\u5206\u52A1\u5FC5\u7528 get_node_by_id --raw \u56DE\u8BFB\u5E76\u4E0E\u9884\u671F\u5BF9\u6BD4
3245
+ `).action(async (options) => {
3246
+ await handleCreateNode(options);
3247
+ });
3248
+ }
3249
+ async function handleCreateNode(options) {
3250
+ const tracker = createCommandTracker("create_node");
3251
+ let pageUrl;
3252
+ let params;
3253
+ try {
3254
+ pageUrl = resolveTargetPageUrl(options);
3255
+ params = buildCreateParams(options);
3256
+ } catch (error) {
3257
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3258
+ tracker.failure(error instanceof Error ? error : void 0);
3259
+ process.exit(2);
3260
+ }
3261
+ const timeoutMs = resolveTimeoutMs(options.timeout);
3262
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: true });
3263
+ try {
3264
+ await client.connect();
3265
+ const result = await client.request(
3266
+ "create_node" /* CREATE_NODE */,
3267
+ params,
3268
+ pageUrl,
3269
+ timeoutMs
3270
+ );
3271
+ const jsonText = JSON.stringify(result, null, options.pretty ? 2 : 0);
3272
+ if (options.output) {
3273
+ const outputPath = resolve11(options.output);
3274
+ mkdirSync13(dirname14(outputPath), { recursive: true });
3275
+ writeFileSync12(outputPath, jsonText, "utf-8");
3276
+ }
3277
+ const total = countNodes(params.node);
3278
+ const created = Object.keys(result.idMap ?? {}).length;
3279
+ const summary = summarizeWarnings(result.warnings);
3280
+ console.log(`\u65B0\u5EFA\u8282\u70B9: ${result.nodeId}`);
3281
+ if (options.input) {
3282
+ console.log(`\u6E90\u8282\u70B9\u603B\u6570: ${total}\uFF0C\u5DF2\u6620\u5C04\u8282\u70B9\u6570: ${created}`);
3283
+ }
3284
+ const summaryText = Object.entries(summary).map(([kind, count]) => `${kind}=${count}`).join(", ");
3285
+ console.log(`warnings: ${result.warnings?.length ?? 0} \u6761${summaryText ? ` (${summaryText})` : ""}`);
3286
+ if (options.output) {
3287
+ console.log(`\u7ED3\u679C\u6587\u4EF6: ${resolve11(options.output)}`);
3288
+ } else {
3289
+ console.log(jsonText);
3290
+ }
3291
+ tracker.success();
3292
+ } catch (error) {
3293
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3294
+ tracker.failure(error instanceof Error ? error : void 0);
3295
+ process.exit(exitCodeForError(error));
3296
+ } finally {
3297
+ client.close();
3298
+ }
3299
+ }
3300
+
3301
+ // src/cli/commands/import-component.ts
3302
+ function buildImportComponentParams(options) {
3303
+ const ukey = typeof options.ukey === "string" ? options.ukey.trim() : "";
3304
+ const ukeySet = typeof options.ukeySet === "string" ? options.ukeySet.trim() : "";
3305
+ if (ukey && ukeySet || !ukey && !ukeySet) {
3306
+ throw new MGError("E011" /* INVALID_PARAMS */, "\u5FC5\u987B\u4E14\u53EA\u80FD\u63D0\u4F9B --ukey \u6216 --ukeySet \u4E4B\u4E00");
3307
+ }
3308
+ if (options.placeInstance && ukeySet) {
3309
+ throw new MGError("E011" /* INVALID_PARAMS */, "--placeInstance \u4EC5\u652F\u6301 --ukey \u5BFC\u5165\u5177\u4F53\u7EC4\u4EF6\uFF1B\u7EC4\u4EF6\u96C6\u4E0D\u80FD\u76F4\u63A5\u6446\u653E INSTANCE");
3310
+ }
3311
+ const params = ukey ? { ukey } : { ukeySet };
3312
+ if (options.placeInstance) params.placeInstance = true;
3313
+ if (options.parentId) params.parentId = options.parentId;
3314
+ if (options.x !== void 0) {
3315
+ const x = Number(options.x);
3316
+ if (!Number.isFinite(x)) throw new MGError("E011" /* INVALID_PARAMS */, "--x \u5FC5\u987B\u662F\u6570\u5B57");
3317
+ params.x = x;
3318
+ }
3319
+ if (options.y !== void 0) {
3320
+ const y = Number(options.y);
3321
+ if (!Number.isFinite(y)) throw new MGError("E011" /* INVALID_PARAMS */, "--y \u5FC5\u987B\u662F\u6570\u5B57");
3322
+ params.y = y;
3323
+ }
3324
+ return params;
3325
+ }
3326
+ function createImportComponentCommand() {
3327
+ return new Command14("import_component").description("\u6309 ukey \u5BFC\u5165\u5DF2\u53D1\u5E03\u56E2\u961F\u5E93\u7EC4\u4EF6\u6216\u7EC4\u4EF6\u96C6\uFF08\u5199\u64CD\u4F5C\uFF09\u3002\u9ED8\u8BA4\u53EA\u5BFC\u5165\u7EC4\u4EF6\u5B9A\u4E49/\u8D44\u6E90\uFF0C\u4E0D\u4F1A\u6446\u5230\u753B\u5E03\uFF1B\u9700\u8981\u53EF\u89C1 INSTANCE \u65F6\u52A0 --placeInstance").option("--ukey <key>", "\u7EC4\u4EF6 ukey\uFF0C\u8C03\u7528 mg.importComponentByKeyAsync").option("--ukeySet <key>", "\u7EC4\u4EF6\u96C6 ukey\uFF0C\u8C03\u7528 mg.importComponentSetByKeyAsync\u3002\u4E0E --ukey \u4E8C\u9009\u4E00").option("--placeInstance", "\u5BFC\u5165\u5177\u4F53\u7EC4\u4EF6\u540E\u7ACB\u5373\u8C03\u7528 createInstance()\uFF0C\u628A\u53EF\u89C1 INSTANCE \u6446\u653E\u5230\u753B\u5E03\uFF1B\u4EC5\u652F\u6301 --ukey\uFF0C\u4E0D\u652F\u6301 --ukeySet").option("--parentId <id>", "\u914D\u5408 --placeInstance\uFF1A\u5B9E\u4F8B\u76EE\u6807\u7236\u8282\u70B9 ID\uFF0C\u7F3A\u7701 = \u5F53\u524D\u9875\u9762").option("--x <n>", "\u914D\u5408 --placeInstance\uFF1A\u5B9E\u4F8B\u653E\u7F6E\u4F4D\u7F6E X").option("--y <n>", "\u914D\u5408 --placeInstance\uFF1A\u5B9E\u4F8B\u653E\u7F6E\u4F4D\u7F6E Y").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u6587\u4EF6\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u6587\u4EF6").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u7ED3\u679C JSON \u8F93\u51FA\u8DEF\u5F84\uFF08{id,nodeId,name,type,ukey,instance?}\uFF09\u3002\u4E0D\u63D0\u4F9B\u5219\u7ED3\u679C\u6253\u5230 stdout").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").addHelpText("after", `
3328
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3329
+
3330
+ # \u5148\u67E5 ukey
3331
+ mg-cli list_library --fileId <\u76EE\u6807\u6587\u4EF6> --filter "\u6309\u94AE" --pretty
3332
+
3333
+ # \u53EA\u5BFC\u5165\u5355\u4E2A\u5DF2\u53D1\u5E03\u7EC4\u4EF6\u5B9A\u4E49/\u8D44\u6E90\uFF08\u4E0D\u4F1A\u5728\u753B\u5E03\u4E0A\u51FA\u73B0 INSTANCE\uFF09
3334
+ mg-cli import_component --fileId <\u76EE\u6807\u6587\u4EF6> --ukey <components.ukey> --pretty
3335
+
3336
+ # \u5BFC\u5165\u5E76\u628A\u4E00\u4E2A\u53EF\u89C1 INSTANCE \u6446\u5230\u5F53\u524D\u9875\u9762\u5750\u6807 (100,200)
3337
+ mg-cli import_component --fileId <\u76EE\u6807\u6587\u4EF6> --ukey <components.ukey> --placeInstance --x 100 --y 200 --pretty
3338
+
3339
+ # \u5BFC\u5165\u5DF2\u53D1\u5E03\u7EC4\u4EF6\u96C6\u5B9A\u4E49\uFF08\u7EC4\u4EF6\u96C6\u4E0D\u80FD\u76F4\u63A5\u6446\u653E INSTANCE\uFF1B\u8BF7\u9009\u62E9\u5177\u4F53\u7EC4\u4EF6 ukey \u518D --placeInstance\uFF09
3340
+ mg-cli import_component --fileId <\u76EE\u6807\u6587\u4EF6> --ukeySet <component-set-ukey> --output imported.json --pretty
3341
+
3342
+ \u8BF4\u660E\uFF1A
3343
+ - \u201C\u5BFC\u5165\u7EC4\u4EF6\u5B9A\u4E49/\u8D44\u6E90\u201D \u2260 \u201C\u5728\u753B\u5E03\u4E0A\u6446\u653E\u5B9E\u4F8B\u201D\uFF1A\u9ED8\u8BA4\u8FD4\u56DE COMPONENT/COMPONENT_SET \u5B9A\u4E49 ID\uFF0C\u4E0D\u8981\u628A\u5B83\u5F53 parentId \u5BB9\u5668\u8FFD\u52A0\u5B50\u8282\u70B9\u3002
3344
+ - \u9700\u8981\u771F\u6B63\u7528\u5230\u754C\u9762\u91CC\u65F6\uFF0C\u5BF9\u5177\u4F53 COMPONENT \u4F7F\u7528 --placeInstance\uFF1B\u8FD4\u56DE\u7684 instance.nodeId \u624D\u662F\u753B\u5E03\u4E0A\u7684 INSTANCE\u3002
3345
+ - \u672C\u547D\u4EE4\u53EA\u5BFC\u5165\u5DF2\u53D1\u5E03\u56E2\u961F\u5E93\u7EC4\u4EF6/\u7EC4\u4EF6\u96C6\u5230\u5F53\u524D\u6587\u4EF6\uFF0C\u4E0D\u521B\u5EFA\u3001\u4E0D\u53D1\u5E03\u56E2\u961F\u5E93\u3002
3346
+ - \u5BFC\u5165\u662F\u5199\u64CD\u4F5C\uFF0C\u4E0D\u505A\u81EA\u52A8\u91CD\u8BD5\uFF0C\u907F\u514D\u8D85\u65F6\u540E\u91CD\u590D\u5BFC\u5165\u3002
3347
+ `).action(async (options) => {
3348
+ await handleImportComponent(options);
3349
+ });
3350
+ }
3351
+ async function handleImportComponent(options) {
3352
+ const tracker = createCommandTracker("import_component");
3353
+ let pageUrl;
3354
+ let params;
3355
+ try {
3356
+ pageUrl = resolveTargetPageUrl(options);
3357
+ params = buildImportComponentParams(options);
3358
+ } catch (error) {
3359
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3360
+ tracker.failure(error instanceof Error ? error : void 0);
3361
+ process.exit(2);
3362
+ }
3363
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: true });
3364
+ try {
3365
+ await client.connect();
3366
+ const result = await client.request("import_component" /* IMPORT_COMPONENT */, params, pageUrl);
3367
+ const jsonText = JSON.stringify(result, null, options.pretty ? 2 : 0);
3368
+ if (options.output) {
3369
+ const outputPath = resolve12(options.output);
3370
+ mkdirSync14(dirname15(outputPath), { recursive: true });
3371
+ writeFileSync13(outputPath, jsonText, "utf-8");
3372
+ }
3373
+ console.log(`\u5DF2\u5BFC\u5165${result.type === "COMPONENT_SET" ? "\u7EC4\u4EF6\u96C6\u5B9A\u4E49" : "\u7EC4\u4EF6\u5B9A\u4E49"}: ${result.nodeId}`);
3374
+ console.log(`\u540D\u79F0: ${result.name}`);
3375
+ console.log(`ukey: ${result.ukey}`);
3376
+ if (result.instance) {
3377
+ console.log(`\u5DF2\u6446\u653E\u5B9E\u4F8B: ${result.instance.nodeId}`);
3378
+ console.log(`\u5B9E\u4F8B\u4F4D\u7F6E: (${result.instance.x ?? "\u672A\u77E5"}, ${result.instance.y ?? "\u672A\u77E5"})`);
3379
+ } else {
3380
+ console.log("\u672A\u6446\u653E\u5B9E\u4F8B: \u662F\uFF08\u5BFC\u5165\u5B9A\u4E49\u4E0D\u7B49\u4E8E\u753B\u5E03\u5B9E\u4F8B\uFF1B\u5982\u9700\u53EF\u89C1\u5B9E\u4F8B\u8BF7\u52A0 --placeInstance\uFF09");
3381
+ }
3382
+ if (options.output) {
3383
+ console.log(`\u7ED3\u679C\u6587\u4EF6: ${resolve12(options.output)}`);
3384
+ } else {
3385
+ console.log(jsonText);
3386
+ }
3387
+ tracker.success();
3388
+ } catch (error) {
3389
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3390
+ tracker.failure(error instanceof Error ? error : void 0);
3391
+ process.exit(exitCodeForError(error));
3392
+ } finally {
3393
+ client.close();
3394
+ }
3395
+ }
3396
+
3397
+ // src/cli/commands/create-page.ts
3398
+ import { Command as Command15 } from "commander";
3399
+ import { writeFileSync as writeFileSync14, mkdirSync as mkdirSync15 } from "fs";
3400
+ import { resolve as resolve13, dirname as dirname16 } from "path";
3401
+ function buildCreatePageParams(options) {
3402
+ const name = typeof options.name === "string" ? options.name.trim() : "";
3403
+ return name ? { name } : {};
3404
+ }
3405
+ function createCreatePageCommand() {
3406
+ return new Command15("create_page").description("\u5728\u76EE\u6807\u6587\u4EF6\u4E2D\u65B0\u5EFA\u9875\u9762\uFF08\u5199\u64CD\u4F5C\uFF09\u3002\u521B\u5EFA\u540E\u4F1A\u5207\u6362\u5230\u65B0\u9875\u9762\uFF0C\u4FBF\u4E8E\u540E\u7EED create_node \u9ED8\u8BA4\u5199\u5165\u8BE5\u9875").option("--name <name>", "\u65B0\u9875\u9762\u540D\u79F0\uFF1B\u4E0D\u63D0\u4F9B\u5219\u4F7F\u7528 MasterGo \u9ED8\u8BA4\u547D\u540D\uFF08\u9875\u9762 N\uFF09").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u6587\u4EF6\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u6587\u4EF6").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u7ED3\u679C JSON \u8F93\u51FA\u8DEF\u5F84\uFF08{pageId,id,name,type,childCount,previousPageId,current}\uFF09\u3002\u4E0D\u63D0\u4F9B\u5219\u7ED3\u679C\u6253\u5230 stdout").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").addHelpText("after", `
3407
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3408
+
3409
+ # \u5728\u6307\u5B9A\u6587\u4EF6\u4E2D\u65B0\u5EFA\u9875\u9762\u5E76\u547D\u540D
3410
+ mg-cli create_page --fileId 197827017565461 --name "AI \u751F\u6210\u9875" --output page.json --pretty
3411
+
3412
+ # \u4F7F\u7528 mgp:// \u94FE\u63A5\u6307\u5B9A\u6587\u4EF6
3413
+ mg-cli create_page --link "mgp://mastergo.netease.com/file/197827017565461?pageId=M" --name "\u7A7A\u767D\u9875"
3414
+
3415
+ \u884C\u4E3A\u8BF4\u660E\uFF1A
3416
+ - MasterGo \u7684 mg.createPage() \u8FD4\u56DE\u7A7A\u767D PAGE\uFF0C\u9ED8\u8BA4 childCount=0
3417
+ - createPage \u4E0D\u4F1A\u81EA\u52A8\u5207\u6362\u5F53\u524D\u9875\uFF1B\u672C\u547D\u4EE4\u4F1A\u5728\u521B\u5EFA\u540E\u663E\u5F0F\u5207\u6362\u5230\u65B0\u9875\u9762
3418
+ - \u540E\u7EED create_node \u4E0D\u4F20 parentId \u65F6\uFF0C\u4F1A\u9ED8\u8BA4\u521B\u5EFA\u5230\u5F53\u524D\u9875\uFF0C\u4E5F\u5C31\u662F\u8FD9\u4E2A\u65B0\u9875\u9762
3419
+ `).action(async (options) => {
3420
+ await handleCreatePage(options);
3421
+ });
3422
+ }
3423
+ async function handleCreatePage(options) {
3424
+ const tracker = createCommandTracker("create_page");
3425
+ let pageUrl;
3426
+ let params;
3427
+ try {
3428
+ pageUrl = resolveTargetPageUrl(options);
3429
+ params = buildCreatePageParams(options);
3430
+ } catch (error) {
3431
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3432
+ tracker.failure(error instanceof Error ? error : void 0);
3433
+ process.exit(2);
3434
+ }
3435
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: true });
3436
+ try {
3437
+ await client.connect();
3438
+ const result = await client.request("create_page" /* CREATE_PAGE */, params, pageUrl);
3439
+ const jsonText = JSON.stringify(result, null, options.pretty ? 2 : 0);
3440
+ if (options.output) {
3441
+ const outputPath = resolve13(options.output);
3442
+ mkdirSync15(dirname16(outputPath), { recursive: true });
3443
+ writeFileSync14(outputPath, jsonText, "utf-8");
3444
+ }
3445
+ console.log(`\u65B0\u5EFA\u9875\u9762: ${result.pageId}`);
3446
+ console.log(`\u9875\u9762\u540D\u79F0: ${result.name}`);
3447
+ console.log(`\u5B50\u8282\u70B9\u6570: ${result.childCount}`);
3448
+ console.log(`\u5DF2\u5207\u6362\u5230\u65B0\u9875\u9762: ${result.current ? "\u662F" : "\u5426"}`);
3449
+ if (options.output) {
3450
+ console.log(`\u7ED3\u679C\u6587\u4EF6: ${resolve13(options.output)}`);
3451
+ } else {
3452
+ console.log(jsonText);
3453
+ }
3454
+ tracker.success();
3455
+ } catch (error) {
3456
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3457
+ tracker.failure(error instanceof Error ? error : void 0);
3458
+ process.exit(exitCodeForCreatePageError(error));
3459
+ } finally {
3460
+ client.close();
3461
+ }
3462
+ }
3463
+ function exitCodeForCreatePageError(error) {
3464
+ if (error instanceof MGError && error.code === "E020" /* CREATE_NODE_FAILED */) return 1;
3465
+ return exitCodeForError(error);
3466
+ }
3467
+
3468
+ // src/cli/commands/delete-node.ts
3469
+ import { Command as Command16 } from "commander";
3470
+ function createDeleteNodeCommand() {
3471
+ return new Command16("delete_node").description("\u5220\u9664\u76EE\u6807\u9875\u9762\u4E2D\u7684\u6307\u5B9A\u8282\u70B9\uFF08\u5199\u64CD\u4F5C\uFF09").requiredOption("--nodeId <id>", "\u8981\u5220\u9664\u7684\u8282\u70B9 ID").option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").action(async (options) => {
3472
+ await handleDeleteNode(options);
3473
+ });
3474
+ }
3475
+ async function handleDeleteNode(options) {
3476
+ const tracker = createCommandTracker("delete_node");
3477
+ let pageUrl;
3478
+ try {
3479
+ pageUrl = resolveTargetPageUrl(options);
3480
+ } catch (error) {
3481
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3482
+ tracker.failure(error instanceof Error ? error : void 0);
3483
+ process.exit(2);
3484
+ }
3485
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: true });
3486
+ try {
3487
+ await client.connect();
3488
+ const params = { nodeId: options.nodeId };
3489
+ const result = await client.request("delete_node" /* DELETE_NODE */, params, pageUrl);
3490
+ if (result?.deleted) {
3491
+ console.log(`\u5DF2\u5220\u9664\u8282\u70B9: ${options.nodeId}`);
3492
+ } else {
3493
+ console.log(`\u5220\u9664\u7ED3\u679C: ${JSON.stringify(result)}`);
3494
+ }
3495
+ tracker.success();
3496
+ } catch (error) {
3497
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3498
+ tracker.failure(error instanceof Error ? error : void 0);
3499
+ process.exit(exitCodeForError(error));
3500
+ } finally {
3501
+ client.close();
3502
+ }
3503
+ }
3504
+
3505
+ // src/cli/commands/update-node.ts
3506
+ import { Command as Command17 } from "commander";
3507
+ import { writeFileSync as writeFileSync15, mkdirSync as mkdirSync16 } from "fs";
3508
+ import { resolve as resolve14, dirname as dirname17 } from "path";
3509
+ function createUpdateNodeCommand() {
3510
+ return new Command17("update_node").description(
3511
+ "\u66F4\u65B0\u5DF2\u6709\u8282\u70B9\u7684\u5C5E\u6027\uFF08\u5199\u64CD\u4F5C\uFF09\u3002\u8BED\u4E49\uFF1A\u4EC5\u8BBE\u7F6E --props \u91CC\u7ED9\u51FA\u7684\u5B57\u6BB5\uFF0C\u672A\u7ED9\u51FA\u7684\u5B57\u6BB5\u4E00\u5F8B\u4E0D\u52A8\u3002props \u5B57\u6BB5\u4E0E get_node_by_id \u8F93\u51FA\u540C\u540D\uFF08\u8BFB\u5199\u5BF9\u79F0\uFF09\u3002\u6CE8\u610F\uFF1A\u66F4\u65B0\u6210\u529F \u2260 \u5C5E\u6027\u5168\u90E8\u751F\u6548\uFF0C\u88AB\u9875\u9762\u62D2\u7EDD\u7684\u5199\u5165\u8BB0\u5F55\u5728 warnings \u91CC\uFF0C\u52A1\u5FC5\u56DE\u8BFB\u81EA\u68C0"
3512
+ ).requiredOption("--nodeId <id>", "\u8981\u66F4\u65B0\u7684\u8282\u70B9 ID").requiredOption("--props <spec>", `\u8981\u8BBE\u7F6E\u7684\u5C5E\u6027\uFF1A\u5185\u8054 JSON\uFF08\u4EE5 { \u5F00\u5934\uFF09\u6216 JSON \u6587\u4EF6\u8DEF\u5F84\u3002\u5982 '{"mainAxisSizingMode":"AUTO"}'`).option("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5\uFF0C\u7528\u4E8E\u6307\u5B9A\u76EE\u6807\u9875\u9762\u3002\u4E0E --domain/--fileId \u4E8C\u9009\u4E00").option("--domain <domain>", "MasterGo \u57DF\u540D\uFF0C\u9ED8\u8BA4 mastergo.netease.com", "mastergo.netease.com").option("--fileId <id>", "\u6587\u4EF6 ID\uFF08\u7EAF\u6570\u5B57\uFF09\uFF0C\u4E0E --domain \u914D\u5408\u6307\u5B9A\u76EE\u6807\u9875\u9762").option("--pageType <type>", "\u9875\u9762\u7C7B\u578B: file(\u9ED8\u8BA4) \u6216 prototyping", "file").option("--output <path>", "\u7ED3\u679C JSON \u8F93\u51FA\u8DEF\u5F84\uFF08{nodeId, warnings}\uFF09\u3002\u4E0D\u63D0\u4F9B\u5219\u7ED3\u679C\u6253\u5230 stdout").option("--pretty", "\u683C\u5F0F\u5316\u8F93\u51FA JSON\uFF08\u9ED8\u8BA4\u538B\u7F29\uFF09", false).option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").addHelpText("after", `
3513
+ \u7528\u6CD5\u793A\u4F8B\uFF1A
3514
+
3515
+ # \u5B50\u8282\u70B9\u5EFA\u5B8C\u540E\uFF0C\u628A\u81EA\u52A8\u5E03\u5C40\u5BB9\u5668\u7684\u5C3A\u5BF8\u6A21\u5F0F\u6539\u4E3A AUTO\uFF08\u9010\u8282\u70B9\u521B\u5EFA\u6D41\u7A0B\u7684\u6807\u51C6\u6536\u5C3E\u52A8\u4F5C\uFF09
3516
+ mg-cli update_node --nodeId "12:34" --props '{"mainAxisSizingMode":"AUTO","crossAxisSizingMode":"AUTO"}' --fileId <\u76EE\u6807\u6587\u4EF6>
3517
+
3518
+ # \u81EA\u68C0\u53D1\u73B0\u586B\u5145\u8272\u4E0D\u5BF9\uFF0C\u5355\u70B9\u4FEE\u6B63
3519
+ mg-cli update_node --nodeId "12:35" --props '{"fills":[{"type":"SOLID","color":{"r":1,"g":0,"b":0,"a":1},"visible":true}]}' --fileId <\u76EE\u6807\u6587\u4EF6>
3520
+
3521
+ # \u6210\u7EC4\u540E\u8865\u8BBE\u5B50\u8282\u70B9 constraints\uFF08mg.group \u4F1A\u91CD\u7F6E constraints\uFF09
3522
+ mg-cli update_node --nodeId "12:36" --props '{"constraints":{"horizontal":"CENTER","vertical":"CENTER"}}' --fileId <\u76EE\u6807\u6587\u4EF6>
3523
+
3524
+ \u8BED\u4E49\u8BF4\u660E\uFF1A\u4EC5\u8BBE\u7F6E\u7ED9\u51FA\u7684\u5B57\u6BB5\u3002\u672A\u51FA\u73B0\u5728 --props \u91CC\u7684\u5C5E\u6027\u4FDD\u6301\u539F\u6837\uFF0C\u4E0D\u4F1A\u88AB\u91CD\u7F6E\u3002
3525
+ `).action(async (options) => {
3526
+ await handleUpdateNode(options);
3527
+ });
3528
+ }
3529
+ async function handleUpdateNode(options) {
3530
+ const tracker = createCommandTracker("update_node");
3531
+ let pageUrl;
3532
+ let props;
3533
+ try {
3534
+ pageUrl = resolveTargetPageUrl(options);
3535
+ props = parsePropsInput(options.props);
3536
+ if (Object.keys(props).length === 0) {
3537
+ throw new MGError("E011" /* INVALID_PARAMS */, "--props \u4E0D\u80FD\u4E3A\u7A7A\u5BF9\u8C61");
3538
+ }
3539
+ } catch (error) {
3540
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3541
+ tracker.failure(error instanceof Error ? error : void 0);
3542
+ process.exit(2);
3543
+ }
3544
+ const client = new MGClient({ noAutoStart: options.noAutoStart, noRetry: true });
3545
+ try {
3546
+ await client.connect();
3547
+ const params = { nodeId: options.nodeId, props };
3548
+ const result = await client.request("update_node" /* UPDATE_NODE */, params, pageUrl);
3549
+ const jsonText = JSON.stringify(result, null, options.pretty ? 2 : 0);
3550
+ if (options.output) {
3551
+ const outputPath = resolve14(options.output);
3552
+ mkdirSync16(dirname17(outputPath), { recursive: true });
3553
+ writeFileSync15(outputPath, jsonText, "utf-8");
3554
+ }
3555
+ const summary = summarizeWarnings(result.warnings);
3556
+ const summaryText = Object.entries(summary).map(([kind, count]) => `${kind}=${count}`).join(", ");
3557
+ console.log(`\u5DF2\u66F4\u65B0\u8282\u70B9: ${result.nodeId}`);
3558
+ console.log(`warnings: ${result.warnings?.length ?? 0} \u6761${summaryText ? ` (${summaryText})` : ""}`);
3559
+ if (options.output) {
3560
+ console.log(`\u7ED3\u679C\u6587\u4EF6: ${resolve14(options.output)}`);
3561
+ } else {
3562
+ console.log(jsonText);
3563
+ }
3564
+ tracker.success();
3565
+ } catch (error) {
3566
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
3567
+ tracker.failure(error instanceof Error ? error : void 0);
3568
+ process.exit(exitCodeForError(error));
3569
+ } finally {
3570
+ client.close();
3571
+ }
3572
+ }
3573
+
2806
3574
  // src/cli/commands/list-extensions.ts
2807
- import { Command as Command10 } from "commander";
3575
+ import { Command as Command18 } from "commander";
2808
3576
  function createListExtensionsCommand() {
2809
- return new Command10("list_extensions").description("\u5217\u51FA\u6240\u6709\u5DF2\u8FDE\u63A5\u7684 Chrome \u6269\u5C55\u5B9E\u4F8B").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
3577
+ return new Command18("list_extensions").description("\u5217\u51FA\u6240\u6709\u5DF2\u8FDE\u63A5\u7684 Chrome \u6269\u5C55\u5B9E\u4F8B").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2810
3578
  await handleListExtensions(options);
2811
3579
  });
2812
3580
  }
@@ -2846,9 +3614,9 @@ async function handleListExtensions(options) {
2846
3614
  }
2847
3615
 
2848
3616
  // src/cli/commands/open-page.ts
2849
- import { Command as Command11 } from "commander";
3617
+ import { Command as Command19 } from "commander";
2850
3618
  function createOpenPageCommand() {
2851
- return new Command11("open_page").description("\u901A\u8FC7 Chrome \u6269\u5C55\u6253\u5F00\u6307\u5B9A\u7684\u9875\u9762").requiredOption("--link <link>", "\u9875\u9762\u94FE\u63A5\uFF08\u652F\u6301 https:// \u6216 mgp:// \u683C\u5F0F\uFF09").option("--ext <index>", "\u6269\u5C55\u5B9E\u4F8B\u5E8F\u53F7\uFF081, 2, 3...\uFF09\uFF0C\u9ED8\u8BA4\u81EA\u52A8\u9009\u62E9\u7B2C\u4E00\u4E2A\u53EF\u7528\u6269\u5C55").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
3619
+ return new Command19("open_page").description("\u901A\u8FC7 Chrome \u6269\u5C55\u6253\u5F00\u6307\u5B9A\u7684\u9875\u9762").requiredOption("--link <link>", "\u9875\u9762\u94FE\u63A5\uFF08\u652F\u6301 https:// \u6216 mgp:// \u683C\u5F0F\uFF09").option("--ext <index>", "\u6269\u5C55\u5B9E\u4F8B\u5E8F\u53F7\uFF081, 2, 3...\uFF09\uFF0C\u9ED8\u8BA4\u81EA\u52A8\u9009\u62E9\u7B2C\u4E00\u4E2A\u53EF\u7528\u6269\u5C55").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2852
3620
  await handleOpenPage(options);
2853
3621
  });
2854
3622
  }
@@ -2943,9 +3711,9 @@ async function handleOpenPage(options) {
2943
3711
  }
2944
3712
 
2945
3713
  // src/cli/commands/navigate-to-node.ts
2946
- import { Command as Command12 } from "commander";
3714
+ import { Command as Command20 } from "commander";
2947
3715
  function createNavigateToNodeCommand() {
2948
- return new Command12("navigate_to_node").description("\u5BFC\u822A\u5230 mgp:// \u94FE\u63A5\u6307\u5B9A\u7684\u8282\u70B9\uFF08\u81EA\u52A8\u5207\u6362\u6216\u6253\u5F00\u9875\u9762\uFF09").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5").option("--ext <index>", "\u6269\u5C55\u5B9E\u4F8B\u5E8F\u53F7\uFF081, 2, 3...\uFF09\uFF0C\u9ED8\u8BA4\u81EA\u52A8\u9009\u62E9\u7B2C\u4E00\u4E2A\u53EF\u7528\u6269\u5C55").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
3716
+ return new Command20("navigate_to_node").description("\u5BFC\u822A\u5230 mgp:// \u94FE\u63A5\u6307\u5B9A\u7684\u8282\u70B9\uFF08\u81EA\u52A8\u5207\u6362\u6216\u6253\u5F00\u9875\u9762\uFF09").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5").option("--ext <index>", "\u6269\u5C55\u5B9E\u4F8B\u5E8F\u53F7\uFF081, 2, 3...\uFF09\uFF0C\u9ED8\u8BA4\u81EA\u52A8\u9009\u62E9\u7B2C\u4E00\u4E2A\u53EF\u7528\u6269\u5C55").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
2949
3717
  await handleNavigateToNode(options);
2950
3718
  });
2951
3719
  }
@@ -3040,10 +3808,10 @@ async function handleNavigateToNode(options) {
3040
3808
  }
3041
3809
 
3042
3810
  // src/cli/commands/visualize.ts
3043
- import { Command as Command13 } from "commander";
3044
- import { writeFileSync as writeFileSync10 } from "fs";
3045
- import { resolve as resolve9, dirname as dirname12 } from "path";
3046
- import { mkdirSync as mkdirSync11 } from "fs";
3811
+ import { Command as Command21 } from "commander";
3812
+ import { writeFileSync as writeFileSync16 } from "fs";
3813
+ import { resolve as resolve15, dirname as dirname18 } from "path";
3814
+ import { mkdirSync as mkdirSync17 } from "fs";
3047
3815
 
3048
3816
  // src/shared/ascii-renderer.ts
3049
3817
  var defaultRenderOptions = {
@@ -3333,7 +4101,7 @@ function renderAscii(node, options = {}) {
3333
4101
 
3334
4102
  // src/cli/commands/visualize.ts
3335
4103
  function createVisualizeCommand() {
3336
- return new Command13("visualize").description("\u5C06 MasterGo \u8BBE\u8BA1\u7A3F\u8282\u70B9\u6E32\u67D3\u4E3A ASCII \u793A\u610F\u56FE").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0D\u6307\u5B9A\u5219\u8F93\u51FA\u5230\u7EC8\u7AEF\uFF09").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6", "3").option("--no-show-id", "\u9690\u85CF\u8282\u70B9 ID").option("--no-show-size", "\u9690\u85CF\u5C3A\u5BF8").option("--no-show-padding", "\u9690\u85CF padding").option("--no-show-radius", "\u9690\u85CF\u5706\u89D2").option("--no-show-layout", "\u9690\u85CF\u5E03\u5C40\u65B9\u5411").option("--no-show-gap", "\u9690\u85CF gap \u53EF\u89C6\u5316").option("--no-compact", "\u4F7F\u7528\u6846\u56FE\u6A21\u5F0F\uFF08\u4EBA\u7C7B\u9605\u8BFB\u4F18\u5316\uFF09").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
4104
+ return new Command21("visualize").description("\u5C06 MasterGo \u8BBE\u8BA1\u7A3F\u8282\u70B9\u6E32\u67D3\u4E3A ASCII \u793A\u610F\u56FE").requiredOption("--link <url>", "mgp:// \u534F\u8BAE\u94FE\u63A5").option("--output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0D\u6307\u5B9A\u5219\u8F93\u51FA\u5230\u7EC8\u7AEF\uFF09").option("--maxDepth <number>", "\u904D\u5386\u6DF1\u5EA6", "3").option("--no-show-id", "\u9690\u85CF\u8282\u70B9 ID").option("--no-show-size", "\u9690\u85CF\u5C3A\u5BF8").option("--no-show-padding", "\u9690\u85CF padding").option("--no-show-radius", "\u9690\u85CF\u5706\u89D2").option("--no-show-layout", "\u9690\u85CF\u5E03\u5C40\u65B9\u5411").option("--no-show-gap", "\u9690\u85CF gap \u53EF\u89C6\u5316").option("--no-compact", "\u4F7F\u7528\u6846\u56FE\u6A21\u5F0F\uFF08\u4EBA\u7C7B\u9605\u8BFB\u4F18\u5316\uFF09").option("--no-auto-start", "\u7981\u7528\u81EA\u52A8\u542F\u52A8 Server").option("--no-retry", "\u7981\u7528\u81EA\u52A8\u91CD\u8BD5").action(async (options) => {
3337
4105
  await handleVisualize(options);
3338
4106
  });
3339
4107
  }
@@ -3385,10 +4153,10 @@ async function handleVisualize(options) {
3385
4153
  };
3386
4154
  const asciiOutput = renderAscii(data, renderOptions);
3387
4155
  if (options.output) {
3388
- const outputPath = resolve9(options.output);
3389
- const outputDir = dirname12(outputPath);
3390
- mkdirSync11(outputDir, { recursive: true });
3391
- writeFileSync10(outputPath, asciiOutput, "utf-8");
4156
+ const outputPath = resolve15(options.output);
4157
+ const outputDir = dirname18(outputPath);
4158
+ mkdirSync17(outputDir, { recursive: true });
4159
+ writeFileSync16(outputPath, asciiOutput, "utf-8");
3392
4160
  console.log(`ASCII \u793A\u610F\u56FE\u5DF2\u4FDD\u5B58\u5230: ${outputPath}`);
3393
4161
  console.log(`Link: ${options.link}`);
3394
4162
  console.log(`\u6A21\u5F0F: ${options.compact ? "\u7D27\u51D1" : "\u6807\u51C6"}`);
@@ -3409,7 +4177,7 @@ async function handleVisualize(options) {
3409
4177
  }
3410
4178
 
3411
4179
  // src/cli/commands/register.ts
3412
- import { Command as Command14 } from "commander";
4180
+ import { Command as Command22 } from "commander";
3413
4181
 
3414
4182
  // src/scripts/register-utils.ts
3415
4183
  import fs from "fs";
@@ -3546,7 +4314,7 @@ function checkRegistration(browser = "chrome") {
3546
4314
 
3547
4315
  // src/cli/commands/register.ts
3548
4316
  function createRegisterCommand() {
3549
- const cmd = new Command14("register").description("\u6CE8\u518C Native Messaging Host\uFF08\u8BA9 Chrome \u63D2\u4EF6\u80FD\u81EA\u52A8\u542F\u52A8 Server\uFF09").option("--unregister", "\u5378\u8F7D Native Host").option("--check", "\u68C0\u67E5\u6CE8\u518C\u72B6\u6001").option("--browser <type>", "\u6307\u5B9A\u6D4F\u89C8\u5668 (chrome/chromium/edge)", "chrome").action(async (options) => {
4317
+ const cmd = new Command22("register").description("\u6CE8\u518C Native Messaging Host\uFF08\u8BA9 Chrome \u63D2\u4EF6\u80FD\u81EA\u52A8\u542F\u52A8 Server\uFF09").option("--unregister", "\u5378\u8F7D Native Host").option("--check", "\u68C0\u67E5\u6CE8\u518C\u72B6\u6001").option("--browser <type>", "\u6307\u5B9A\u6D4F\u89C8\u5668 (chrome/chromium/edge)", "chrome").action(async (options) => {
3550
4318
  const browser = options.browser;
3551
4319
  if (!["chrome", "chromium", "edge"].includes(browser)) {
3552
4320
  console.error(`\u4E0D\u652F\u6301\u7684\u6D4F\u89C8\u5668: ${browser}`);
@@ -3581,17 +4349,25 @@ function createRegisterCommand() {
3581
4349
  }
3582
4350
 
3583
4351
  // src/cli/index.ts
3584
- var program = new Command15();
4352
+ var program = new Command23();
3585
4353
  program.name("mg-cli").description("MasterGo CLI \u5DE5\u5177 - \u7528\u4E8E Claude Code \u4E0E MasterGo \u901A\u4FE1").version(getVersion());
3586
4354
  program.addCommand(createServerCommand());
3587
4355
  program.addCommand(createGetNodeByIdCommand());
3588
4356
  program.addCommand(createGetNodeByLinkCommand());
4357
+ program.addCommand(createGetNodeContextCommand());
3589
4358
  program.addCommand(createGetAllNodesCommand());
3590
4359
  program.addCommand(createExportImageCommand());
3591
4360
  program.addCommand(createExecuteCodeCommand());
3592
4361
  program.addCommand(createGetAllPagesCommand());
3593
4362
  program.addCommand(createGetNodeForSpaceCommand());
3594
4363
  program.addCommand(createGetCommentsCommand());
4364
+ program.addCommand(createListFontsCommand());
4365
+ program.addCommand(createListLibraryCommand());
4366
+ program.addCommand(createCreatePageCommand());
4367
+ program.addCommand(createImportComponentCommand());
4368
+ program.addCommand(createCreateNodeCommand());
4369
+ program.addCommand(createDeleteNodeCommand());
4370
+ program.addCommand(createUpdateNodeCommand());
3595
4371
  program.addCommand(createListExtensionsCommand());
3596
4372
  program.addCommand(createOpenPageCommand());
3597
4373
  program.addCommand(createNavigateToNodeCommand());