@hangox/mg-cli 1.1.6 → 1.2.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 Command13 } from "commander";
4
+ import { Command as Command14 } from "commander";
5
5
 
6
6
  // src/cli/version-check.ts
7
7
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
@@ -221,6 +221,17 @@ function killProcess(pid) {
221
221
  return false;
222
222
  }
223
223
  }
224
+ function normalizePageUrl(url) {
225
+ try {
226
+ if (!url.includes("://") && !url.startsWith("//")) {
227
+ return url.split("?")[0].split("#")[0];
228
+ }
229
+ const urlObj = new URL(url);
230
+ return urlObj.host + urlObj.pathname;
231
+ } catch {
232
+ return url;
233
+ }
234
+ }
224
235
  function parseMgpLink(link) {
225
236
  if (!link.startsWith("mgp://")) {
226
237
  return null;
@@ -1117,7 +1128,7 @@ var MGServer = class {
1117
1128
  throw new MGError("E016" /* SERVER_ALREADY_RUNNING */, "Server \u5DF2\u5728\u8FD0\u884C\u4E2D");
1118
1129
  }
1119
1130
  const port = await this.findAvailablePort();
1120
- return new Promise((resolve9, reject) => {
1131
+ return new Promise((resolve10, reject) => {
1121
1132
  this.wss = new WebSocketServer({ port });
1122
1133
  this.wss.on("listening", () => {
1123
1134
  this.port = port;
@@ -1126,7 +1137,7 @@ var MGServer = class {
1126
1137
  this.logger.info(`Server \u542F\u52A8\u6210\u529F\uFF0C\u76D1\u542C\u7AEF\u53E3: ${port}`);
1127
1138
  this.connectionManager.startHeartbeatCheck(HEARTBEAT_INTERVAL);
1128
1139
  initServerAnalytics(this.logger);
1129
- resolve9(port);
1140
+ resolve10(port);
1130
1141
  });
1131
1142
  this.wss.on("error", (error) => {
1132
1143
  this.logger.error("Server \u9519\u8BEF:", error);
@@ -1157,14 +1168,14 @@ var MGServer = class {
1157
1168
  * 检查端口是否可用
1158
1169
  */
1159
1170
  isPortAvailable(port) {
1160
- return new Promise((resolve9) => {
1171
+ return new Promise((resolve10) => {
1161
1172
  const testServer = new WebSocketServer({ port });
1162
1173
  testServer.on("listening", () => {
1163
1174
  testServer.close();
1164
- resolve9(true);
1175
+ resolve10(true);
1165
1176
  });
1166
1177
  testServer.on("error", () => {
1167
- resolve9(false);
1178
+ resolve10(false);
1168
1179
  });
1169
1180
  });
1170
1181
  }
@@ -1499,12 +1510,12 @@ var MGServer = class {
1499
1510
  await shutdownServerAnalytics();
1500
1511
  this.requestHandler.cleanupAll();
1501
1512
  this.connectionManager.closeAll();
1502
- return new Promise((resolve9) => {
1513
+ return new Promise((resolve10) => {
1503
1514
  this.wss.close(() => {
1504
1515
  this.isRunning = false;
1505
1516
  this.wss = null;
1506
1517
  this.logger.info("Server \u5DF2\u505C\u6B62");
1507
- resolve9();
1518
+ resolve10();
1508
1519
  });
1509
1520
  });
1510
1521
  }
@@ -1621,7 +1632,7 @@ async function startServerDaemon(port) {
1621
1632
  child.unref();
1622
1633
  const startTime = Date.now();
1623
1634
  while (Date.now() - startTime < SERVER_START_TIMEOUT) {
1624
- await new Promise((resolve9) => setTimeout(resolve9, 200));
1635
+ await new Promise((resolve10) => setTimeout(resolve10, 200));
1625
1636
  const { running: running2, info: info2 } = isServerRunning();
1626
1637
  if (running2 && info2) {
1627
1638
  return info2;
@@ -1642,7 +1653,7 @@ function stopServer() {
1642
1653
  }
1643
1654
  async function restartServer(port) {
1644
1655
  const { info: oldInfo } = stopServer();
1645
- await new Promise((resolve9) => setTimeout(resolve9, 500));
1656
+ await new Promise((resolve10) => setTimeout(resolve10, 500));
1646
1657
  return startServerDaemon(port || oldInfo?.port);
1647
1658
  }
1648
1659
  function getServerStatus() {
@@ -1715,7 +1726,7 @@ var MGClient = class {
1715
1726
  * 尝试连接指定端口
1716
1727
  */
1717
1728
  tryConnect(port) {
1718
- return new Promise((resolve9, reject) => {
1729
+ return new Promise((resolve10, reject) => {
1719
1730
  const ws = new WebSocket2(`ws://localhost:${port}`);
1720
1731
  const timer = setTimeout(() => {
1721
1732
  ws.close();
@@ -1725,7 +1736,7 @@ var MGClient = class {
1725
1736
  clearTimeout(timer);
1726
1737
  this.ws = ws;
1727
1738
  this.register();
1728
- resolve9();
1739
+ resolve10();
1729
1740
  });
1730
1741
  ws.on("error", (error) => {
1731
1742
  clearTimeout(timer);
@@ -1778,7 +1789,7 @@ var MGClient = class {
1778
1789
  pageUrl,
1779
1790
  timestamp: Date.now()
1780
1791
  };
1781
- return new Promise((resolve9, reject) => {
1792
+ return new Promise((resolve10, reject) => {
1782
1793
  const timer = setTimeout(() => {
1783
1794
  reject(new MGError("E012" /* REQUEST_TIMEOUT */, ErrorMessages["E012" /* REQUEST_TIMEOUT */]));
1784
1795
  }, REQUEST_TIMEOUT);
@@ -1789,7 +1800,7 @@ var MGClient = class {
1789
1800
  clearTimeout(timer);
1790
1801
  this.ws?.off("message", messageHandler);
1791
1802
  if (response.success) {
1792
- resolve9(response.data);
1803
+ resolve10(response.data);
1793
1804
  } else {
1794
1805
  const error = response.error;
1795
1806
  reject(
@@ -2706,10 +2717,92 @@ async function handleGetNodeForSpace(options) {
2706
2717
  }
2707
2718
  }
2708
2719
 
2709
- // src/cli/commands/list-extensions.ts
2720
+ // src/cli/commands/get-comments.ts
2710
2721
  import { Command as Command9 } from "commander";
2722
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync9 } from "fs";
2723
+ import { dirname as dirname11, resolve as resolve8 } from "path";
2724
+ function createGetCommentsCommand() {
2725
+ 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) => {
2726
+ await handleGetComments(options);
2727
+ });
2728
+ }
2729
+ async function handleGetComments(options) {
2730
+ const tracker = createCommandTracker("get_comments");
2731
+ const client = new MGClient({
2732
+ noAutoStart: options.noAutoStart,
2733
+ noRetry: options.noRetry
2734
+ });
2735
+ try {
2736
+ let pageUrl;
2737
+ if (options.link) {
2738
+ if (options.link.startsWith("mgp://")) {
2739
+ const parsed = parseMgpLink(options.link);
2740
+ if (!parsed) {
2741
+ console.error(`\u9519\u8BEF [${"E010" /* INVALID_LINK */}]: \u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F`);
2742
+ console.error(`\u63D0\u4F9B\u7684\u94FE\u63A5: ${options.link}`);
2743
+ tracker.failure({ code: "E010" /* INVALID_LINK */, message: "\u65E0\u6548\u7684 mgp:// \u94FE\u63A5\u683C\u5F0F" });
2744
+ process.exit(1);
2745
+ }
2746
+ pageUrl = normalizePageUrl(parsed.pageUrl);
2747
+ } else {
2748
+ pageUrl = normalizePageUrl(options.link);
2749
+ }
2750
+ }
2751
+ await client.connect();
2752
+ const params = {
2753
+ includeDeleted: options.includeDeleted ?? false,
2754
+ includeNearby: options.includeNearby,
2755
+ nearbyLimit: parseNumberOption(options.nearbyLimit, 5),
2756
+ nearbyDepth: parseNumberOption(options.nearbyDepth, 3)
2757
+ };
2758
+ console.log("\u6B63\u5728\u83B7\u53D6\u8BC4\u8BBA\u533A\u5185\u5BB9...");
2759
+ const result = await client.requestWithRetry(
2760
+ "get_comments" /* GET_COMMENTS */,
2761
+ params,
2762
+ pageUrl
2763
+ );
2764
+ const outputPath = resolve8(options.output);
2765
+ mkdirSync10(dirname11(outputPath), { recursive: true });
2766
+ const outputData = {
2767
+ extractedAt: (/* @__PURE__ */ new Date()).toISOString(),
2768
+ ...result
2769
+ };
2770
+ const jsonContent = JSON.stringify(outputData, null, options.pretty ? 2 : 0);
2771
+ writeFileSync9(outputPath, jsonContent, "utf-8");
2772
+ console.log(`\u6587\u4EF6\u8DEF\u5F84: ${outputPath}`);
2773
+ const displayPageUrl = pageUrl || result.pageUrl;
2774
+ if (displayPageUrl) {
2775
+ console.log(`\u9875\u9762 URL: ${displayPageUrl}`);
2776
+ }
2777
+ console.log(`\u8BC4\u8BBA\u6570\u91CF: ${result.total}`);
2778
+ console.log(`\u8F93\u51FA\u683C\u5F0F: ${options.pretty ? "\u683C\u5F0F\u5316" : "\u538B\u7F29"}`);
2779
+ tracker.success();
2780
+ } catch (error) {
2781
+ if (error instanceof MGError) {
2782
+ console.error(`\u9519\u8BEF [${error.code}]: ${error.message}`);
2783
+ tracker.failure(error);
2784
+ } else {
2785
+ console.error(`\u9519\u8BEF: ${error instanceof Error ? error.message : error}`);
2786
+ tracker.failure(error instanceof Error ? error : void 0);
2787
+ }
2788
+ process.exit(1);
2789
+ } finally {
2790
+ client.close();
2791
+ }
2792
+ }
2793
+ function parseNumberOption(value, fallback) {
2794
+ if (typeof value === "number") return value;
2795
+ if (typeof value === "string") {
2796
+ const parsed = Number.parseInt(value, 10);
2797
+ return Number.isNaN(parsed) ? fallback : parsed;
2798
+ }
2799
+ return fallback;
2800
+ }
2801
+
2802
+ // src/cli/commands/list-extensions.ts
2803
+ import { Command as Command10 } from "commander";
2711
2804
  function createListExtensionsCommand() {
2712
- return new Command9("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) => {
2805
+ 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) => {
2713
2806
  await handleListExtensions(options);
2714
2807
  });
2715
2808
  }
@@ -2749,9 +2842,9 @@ async function handleListExtensions(options) {
2749
2842
  }
2750
2843
 
2751
2844
  // src/cli/commands/open-page.ts
2752
- import { Command as Command10 } from "commander";
2845
+ import { Command as Command11 } from "commander";
2753
2846
  function createOpenPageCommand() {
2754
- return new Command10("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) => {
2847
+ 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) => {
2755
2848
  await handleOpenPage(options);
2756
2849
  });
2757
2850
  }
@@ -2846,9 +2939,9 @@ async function handleOpenPage(options) {
2846
2939
  }
2847
2940
 
2848
2941
  // src/cli/commands/navigate-to-node.ts
2849
- import { Command as Command11 } from "commander";
2942
+ import { Command as Command12 } from "commander";
2850
2943
  function createNavigateToNodeCommand() {
2851
- return new Command11("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) => {
2944
+ 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) => {
2852
2945
  await handleNavigateToNode(options);
2853
2946
  });
2854
2947
  }
@@ -2943,10 +3036,10 @@ async function handleNavigateToNode(options) {
2943
3036
  }
2944
3037
 
2945
3038
  // src/cli/commands/visualize.ts
2946
- import { Command as Command12 } from "commander";
2947
- import { writeFileSync as writeFileSync9 } from "fs";
2948
- import { resolve as resolve8, dirname as dirname11 } from "path";
2949
- import { mkdirSync as mkdirSync10 } from "fs";
3039
+ import { Command as Command13 } from "commander";
3040
+ import { writeFileSync as writeFileSync10 } from "fs";
3041
+ import { resolve as resolve9, dirname as dirname12 } from "path";
3042
+ import { mkdirSync as mkdirSync11 } from "fs";
2950
3043
 
2951
3044
  // src/shared/ascii-renderer.ts
2952
3045
  var defaultRenderOptions = {
@@ -3236,7 +3329,7 @@ function renderAscii(node, options = {}) {
3236
3329
 
3237
3330
  // src/cli/commands/visualize.ts
3238
3331
  function createVisualizeCommand() {
3239
- return new Command12("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) => {
3332
+ 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) => {
3240
3333
  await handleVisualize(options);
3241
3334
  });
3242
3335
  }
@@ -3288,10 +3381,10 @@ async function handleVisualize(options) {
3288
3381
  };
3289
3382
  const asciiOutput = renderAscii(data, renderOptions);
3290
3383
  if (options.output) {
3291
- const outputPath = resolve8(options.output);
3292
- const outputDir = dirname11(outputPath);
3293
- mkdirSync10(outputDir, { recursive: true });
3294
- writeFileSync9(outputPath, asciiOutput, "utf-8");
3384
+ const outputPath = resolve9(options.output);
3385
+ const outputDir = dirname12(outputPath);
3386
+ mkdirSync11(outputDir, { recursive: true });
3387
+ writeFileSync10(outputPath, asciiOutput, "utf-8");
3295
3388
  console.log(`ASCII \u793A\u610F\u56FE\u5DF2\u4FDD\u5B58\u5230: ${outputPath}`);
3296
3389
  console.log(`Link: ${options.link}`);
3297
3390
  console.log(`\u6A21\u5F0F: ${options.compact ? "\u7D27\u51D1" : "\u6807\u51C6"}`);
@@ -3312,7 +3405,7 @@ async function handleVisualize(options) {
3312
3405
  }
3313
3406
 
3314
3407
  // src/cli/index.ts
3315
- var program = new Command13();
3408
+ var program = new Command14();
3316
3409
  program.name("mg-cli").description("MasterGo CLI \u5DE5\u5177 - \u7528\u4E8E Claude Code \u4E0E MasterGo \u901A\u4FE1").version(getVersion());
3317
3410
  program.addCommand(createServerCommand());
3318
3411
  program.addCommand(createGetNodeByIdCommand());
@@ -3322,6 +3415,7 @@ program.addCommand(createExportImageCommand());
3322
3415
  program.addCommand(createExecuteCodeCommand());
3323
3416
  program.addCommand(createGetAllPagesCommand());
3324
3417
  program.addCommand(createGetNodeForSpaceCommand());
3418
+ program.addCommand(createGetCommentsCommand());
3325
3419
  program.addCommand(createListExtensionsCommand());
3326
3420
  program.addCommand(createOpenPageCommand());
3327
3421
  program.addCommand(createNavigateToNodeCommand());