@xiaou66/vite-plugin-vue-mcp-next 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -54,8 +54,10 @@ var DEFAULT_MASK_HEADERS = [
54
54
  // src/constants.ts
55
55
  var DEFAULT_MCP_PATH = "/__mcp";
56
56
  var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
57
+ var DEFAULT_SCREENSHOT_SAVE_DIR = ".vite-mcp/screenshot";
57
58
  var MCP_TOOL_NAMES = {
58
59
  listPages: "list_pages",
60
+ reloadPage: "reload_page",
59
61
  getPageState: "get_page_state",
60
62
  getDomTree: "get_dom_tree",
61
63
  queryDom: "query_dom",
@@ -78,7 +80,10 @@ var VIRTUAL_RUNTIME_ID = "virtual:vite-plugin-vue-mcp-next/runtime";
78
80
  var RESOLVED_VIRTUAL_RUNTIME_ID = `\0${VIRTUAL_RUNTIME_ID}`;
79
81
  var VIRTUAL_SCREENSHOT_CONFIG_ID = "virtual:vite-plugin-vue-mcp-next/screenshot-config";
80
82
  var RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID = `\0${VIRTUAL_SCREENSHOT_CONFIG_ID}`;
83
+ var VIRTUAL_SNAPDOM_LOADER_ID = "virtual:vite-plugin-vue-mcp-next/snapdom-loader";
84
+ var RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID = `\0${VIRTUAL_SNAPDOM_LOADER_ID}`;
81
85
  var DEFAULT_MCP_CLIENT_SERVER_NAME = "vue-mcp-next";
86
+ var RUNTIME_PAGE_RECONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-reconnected";
82
87
  var DEFAULT_OPTIONS = {
83
88
  mcpPath: DEFAULT_MCP_PATH,
84
89
  host: "localhost",
@@ -119,6 +124,8 @@ var DEFAULT_OPTIONS = {
119
124
  maxRecords: DEFAULT_CONSOLE_MAX_RECORDS
120
125
  },
121
126
  screenshot: {
127
+ type: "path",
128
+ saveDir: DEFAULT_SCREENSHOT_SAVE_DIR,
122
129
  prefer: "auto",
123
130
  maxBytes: DEFAULT_SCREENSHOT_MAX_BYTES,
124
131
  snapdom: {
@@ -648,6 +655,9 @@ function registerNetworkTools(server, ctx) {
648
655
  );
649
656
  }
650
657
 
658
+ // src/mcp/tools/pages.ts
659
+ var import_zod5 = require("zod");
660
+
651
661
  // src/plugin/entryDiscovery.ts
652
662
  var import_node_fs = __toESM(require("fs"), 1);
653
663
  var import_node_path = __toESM(require("path"), 1);
@@ -699,6 +709,118 @@ function registerPageTools(server, ctx, vite) {
699
709
  });
700
710
  }
701
711
  );
712
+ server.registerTool(
713
+ MCP_TOOL_NAMES.reloadPage,
714
+ {
715
+ description: "Reload the selected page. CDP uses ignoreCache; Runtime Hook falls back to normal reload.",
716
+ inputSchema: {
717
+ pageId: import_zod5.z.string().optional(),
718
+ ignoreCache: import_zod5.z.boolean().optional()
719
+ }
720
+ },
721
+ async (input) => {
722
+ if (hasCdpConfig(ctx)) {
723
+ return reloadPageWithCdp(ctx, input.pageId, input.ignoreCache ?? true);
724
+ }
725
+ const target = resolveRuntimeReloadTarget(ctx, input.pageId);
726
+ if (!target.ok) {
727
+ return createToolError(target.error);
728
+ }
729
+ const reconnect = waitForRuntimePageReconnect(ctx);
730
+ ctx.pages.disconnect(target.page.pageId);
731
+ const result = await requestRuntimeData(ctx, (event) => {
732
+ void ctx.rpcServer?.reloadPage({ event });
733
+ });
734
+ if (!isRecord(result) || result.ok === false) {
735
+ reconnect.cancel();
736
+ return createToolResponse(
737
+ isRecord(result) ? result : { ok: false, error: "Invalid runtime reload response" }
738
+ );
739
+ }
740
+ const page = await reconnect.promise;
741
+ return createToolResponse(
742
+ page ? { ...result, reconnected: true, pageId: page.pageId, page } : {
743
+ ...result,
744
+ reconnected: false,
745
+ error: "runtime page reconnect timed out"
746
+ }
747
+ );
748
+ }
749
+ );
750
+ }
751
+ function hasCdpConfig(ctx) {
752
+ return Boolean(ctx.options.cdp.browserUrl || ctx.options.cdp.wsEndpoint);
753
+ }
754
+ function isRecord(value) {
755
+ return typeof value === "object" && value !== null && !Array.isArray(value);
756
+ }
757
+ function resolveRuntimeReloadTarget(ctx, pageId) {
758
+ try {
759
+ const page = resolvePageTarget(ctx, pageId);
760
+ if (page.source !== "runtime") {
761
+ return {
762
+ ok: false,
763
+ error: "Runtime reload requires a runtime page target"
764
+ };
765
+ }
766
+ return { ok: true, page };
767
+ } catch (error) {
768
+ return {
769
+ ok: false,
770
+ error: error instanceof Error ? error.message : String(error)
771
+ };
772
+ }
773
+ }
774
+ function waitForRuntimePageReconnect(ctx) {
775
+ let timeout;
776
+ let cleanup;
777
+ const promise = new Promise((resolve) => {
778
+ timeout = setTimeout(() => {
779
+ cleanup?.();
780
+ resolve(null);
781
+ }, 5e3);
782
+ cleanup = ctx.hooks.hookOnce(RUNTIME_PAGE_RECONNECTED_EVENT, (payload) => {
783
+ if (timeout) {
784
+ clearTimeout(timeout);
785
+ }
786
+ resolve(isPageTarget(payload) ? payload : null);
787
+ });
788
+ });
789
+ return {
790
+ promise,
791
+ cancel() {
792
+ if (timeout) {
793
+ clearTimeout(timeout);
794
+ }
795
+ cleanup?.();
796
+ }
797
+ };
798
+ }
799
+ function isPageTarget(value) {
800
+ if (!isRecord(value)) {
801
+ return false;
802
+ }
803
+ return typeof value.pageId === "string" && (value.source === "runtime" || value.source === "cdp") && typeof value.url === "string" && typeof value.pathname === "string" && typeof value.connected === "boolean";
804
+ }
805
+ async function reloadPageWithCdp(ctx, pageId, ignoreCache) {
806
+ const cdp = await connectCdpForPage(ctx, pageId);
807
+ if (!cdp) {
808
+ return createToolError("CDP target is unavailable for page reload");
809
+ }
810
+ try {
811
+ await cdp.client.Page.enable();
812
+ const loaded = cdp.client.Page.loadEventFired();
813
+ await cdp.client.Page.reload({ ignoreCache });
814
+ await loaded;
815
+ return createToolResponse({
816
+ ok: true,
817
+ source: "cdp",
818
+ ignoreCache,
819
+ pageId
820
+ });
821
+ } finally {
822
+ await closeCdpClient(cdp.client);
823
+ }
702
824
  }
703
825
  async function listCdpPageTargets(ctx) {
704
826
  if (ctx.options.cdp.wsEndpoint) {
@@ -745,7 +867,7 @@ function getPathname(url) {
745
867
  }
746
868
 
747
869
  // src/mcp/tools/screenshot.ts
748
- var import_zod5 = require("zod");
870
+ var import_zod6 = require("zod");
749
871
 
750
872
  // src/cdp/cdpScreenshot.ts
751
873
  async function cdpCaptureScreenshot(options) {
@@ -849,18 +971,70 @@ function isElementRect(value) {
849
971
  return typeof rect.x === "number" && typeof rect.y === "number" && typeof rect.width === "number" && rect.width > 0 && typeof rect.height === "number" && rect.height > 0;
850
972
  }
851
973
 
974
+ // src/mcp/tools/screenshotOutput.ts
975
+ var import_node_crypto = require("crypto");
976
+ var import_promises = require("fs/promises");
977
+ var import_node_path2 = __toESM(require("path"), 1);
978
+ async function createScreenshotOutput(ctx, payload) {
979
+ if (ctx.options.screenshot.type === "base64") {
980
+ return payload;
981
+ }
982
+ const saveDir = resolveScreenshotSaveDir(ctx);
983
+ await (0, import_promises.mkdir)(saveDir, { recursive: true });
984
+ const filePath = import_node_path2.default.join(saveDir, createScreenshotFileName(payload));
985
+ await (0, import_promises.writeFile)(filePath, Buffer.from(payload.data, "base64"));
986
+ return {
987
+ source: payload.source,
988
+ target: payload.target,
989
+ format: payload.format,
990
+ width: payload.width,
991
+ height: payload.height,
992
+ mimeType: payload.mimeType,
993
+ byteLength: payload.byteLength,
994
+ limitations: payload.limitations,
995
+ path: filePath,
996
+ relativePath: createProjectRelativePath(ctx, filePath)
997
+ };
998
+ }
999
+ function resolveScreenshotSaveDir(ctx) {
1000
+ const saveDir = ctx.options.screenshot.saveDir.trim();
1001
+ if (!saveDir) {
1002
+ throw new Error("screenshot.saveDir must be a non-empty string");
1003
+ }
1004
+ const root = ctx.server?.config.root;
1005
+ if (!root) {
1006
+ throw new Error("Vite server root is required for screenshot path output");
1007
+ }
1008
+ if (import_node_path2.default.isAbsolute(saveDir)) {
1009
+ return saveDir;
1010
+ }
1011
+ return import_node_path2.default.resolve(root, saveDir);
1012
+ }
1013
+ function createScreenshotFileName(payload) {
1014
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
1015
+ const suffix = (0, import_node_crypto.randomUUID)().slice(0, 8);
1016
+ return `${timestamp}-${payload.source}-${payload.target}-${suffix}.${payload.format}`;
1017
+ }
1018
+ function createProjectRelativePath(ctx, filePath) {
1019
+ const root = ctx.server?.config.root;
1020
+ if (!root) {
1021
+ throw new Error("Vite server root is required for screenshot path output");
1022
+ }
1023
+ return import_node_path2.default.relative(root, filePath).split(import_node_path2.default.sep).join("/");
1024
+ }
1025
+
852
1026
  // src/mcp/tools/screenshot.ts
853
1027
  var DEFAULT_SCREENSHOT_TARGET = "viewport";
854
1028
  var DEFAULT_SCREENSHOT_FORMAT = "png";
855
1029
  var screenshotInputSchema = {
856
- pageId: import_zod5.z.string().optional(),
857
- target: import_zod5.z.enum(["viewport", "fullPage", "element"]).optional(),
858
- selector: import_zod5.z.string().optional(),
859
- format: import_zod5.z.enum(["png", "jpeg", "webp"]).optional(),
860
- prefer: import_zod5.z.enum(["auto", "cdp", "runtime"]).optional(),
861
- quality: import_zod5.z.number().optional(),
862
- scale: import_zod5.z.number().optional(),
863
- snapdom: import_zod5.z.record(import_zod5.z.string(), import_zod5.z.unknown()).optional()
1030
+ pageId: import_zod6.z.string().optional(),
1031
+ target: import_zod6.z.enum(["viewport", "fullPage", "element"]).optional(),
1032
+ selector: import_zod6.z.string().optional(),
1033
+ format: import_zod6.z.enum(["png", "jpeg", "webp"]).optional(),
1034
+ prefer: import_zod6.z.enum(["auto", "cdp", "runtime"]).optional(),
1035
+ quality: import_zod6.z.number().optional(),
1036
+ scale: import_zod6.z.number().optional(),
1037
+ snapdom: import_zod6.z.record(import_zod6.z.string(), import_zod6.z.unknown()).optional()
864
1038
  };
865
1039
  function registerScreenshotTools(server, ctx) {
866
1040
  server.registerTool(
@@ -890,7 +1064,7 @@ async function handleTakeScreenshot(ctx, input) {
890
1064
  format,
891
1065
  quality: input.quality
892
1066
  });
893
- return createScreenshotResponse(ctx, {
1067
+ return await createScreenshotResponse(ctx, {
894
1068
  source: "cdp",
895
1069
  target,
896
1070
  format,
@@ -936,15 +1110,30 @@ async function createRuntimeScreenshot(ctx, input, normalized) {
936
1110
  if (!isPlainRecord(result)) {
937
1111
  return createToolError("runtime screenshot returned an invalid response");
938
1112
  }
939
- return createToolResponse(result);
1113
+ if (result.ok === false) {
1114
+ return createToolResponse(result);
1115
+ }
1116
+ if (!isScreenshotImagePayload(result)) {
1117
+ return createToolError("runtime screenshot returned an invalid response");
1118
+ }
1119
+ return createScreenshotResponse(ctx, {
1120
+ ...result,
1121
+ target: normalized.target,
1122
+ format: normalized.format
1123
+ });
940
1124
  }
941
- function createScreenshotResponse(ctx, result) {
1125
+ async function createScreenshotResponse(ctx, result) {
942
1126
  if (result.byteLength > ctx.options.screenshot.maxBytes) {
943
1127
  return createToolError(
944
1128
  `screenshot is too large: ${String(result.byteLength)} bytes`
945
1129
  );
946
1130
  }
947
- return createToolResponse(result);
1131
+ try {
1132
+ return createToolResponse(await createScreenshotOutput(ctx, result));
1133
+ } catch (error) {
1134
+ const message = error instanceof Error ? error.message : String(error);
1135
+ return createToolError(`failed to create screenshot output: ${message}`);
1136
+ }
948
1137
  }
949
1138
  function isScreenshotTooLarge(ctx, result) {
950
1139
  return isPlainRecord(result) && "byteLength" in result && typeof result.byteLength === "number" && result.byteLength > ctx.options.screenshot.maxBytes;
@@ -959,10 +1148,13 @@ function getBase64ByteLength(data) {
959
1148
  const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
960
1149
  return Math.ceil(data.length * 3 / 4) - padding;
961
1150
  }
1151
+ function isScreenshotImagePayload(result) {
1152
+ return (result.source === "cdp" || result.source === "snapdom") && typeof result.data === "string" && typeof result.width === "number" && typeof result.height === "number" && typeof result.mimeType === "string" && typeof result.byteLength === "number";
1153
+ }
962
1154
 
963
1155
  // src/mcp/tools/vue.ts
964
1156
  var import_nanoid2 = require("nanoid");
965
- var import_zod6 = require("zod");
1157
+ var import_zod7 = require("zod");
966
1158
  function registerVueTools(server, ctx) {
967
1159
  server.registerTool(
968
1160
  MCP_TOOL_NAMES.getComponentTree,
@@ -975,7 +1167,7 @@ function registerVueTools(server, ctx) {
975
1167
  MCP_TOOL_NAMES.getComponentState,
976
1168
  {
977
1169
  description: "Get Vue component state.",
978
- inputSchema: { componentName: import_zod6.z.string() }
1170
+ inputSchema: { componentName: import_zod7.z.string() }
979
1171
  },
980
1172
  async ({ componentName }) => requestVueData(ctx, (event) => {
981
1173
  void ctx.rpcServer?.getInspectorState({ event, componentName });
@@ -986,19 +1178,19 @@ function registerVueTools(server, ctx) {
986
1178
  {
987
1179
  description: "Edit Vue component state.",
988
1180
  inputSchema: {
989
- componentName: import_zod6.z.string(),
990
- path: import_zod6.z.array(import_zod6.z.string()),
991
- value: import_zod6.z.string(),
992
- valueType: import_zod6.z.enum(["string", "number", "boolean", "object", "array"])
1181
+ componentName: import_zod7.z.string(),
1182
+ path: import_zod7.z.array(import_zod7.z.string()),
1183
+ value: import_zod7.z.string(),
1184
+ valueType: import_zod7.z.enum(["string", "number", "boolean", "object", "array"])
993
1185
  }
994
1186
  },
995
- ({ componentName, path: path5, value, valueType }) => {
1187
+ ({ componentName, path: path6, value, valueType }) => {
996
1188
  if (!ctx.rpcServer) {
997
1189
  return vueBridgeUnavailable();
998
1190
  }
999
1191
  void ctx.rpcServer.editComponentState({
1000
1192
  componentName,
1001
- path: path5,
1193
+ path: path6,
1002
1194
  value,
1003
1195
  valueType
1004
1196
  });
@@ -1009,7 +1201,7 @@ function registerVueTools(server, ctx) {
1009
1201
  MCP_TOOL_NAMES.highlightComponent,
1010
1202
  {
1011
1203
  description: "Highlight a Vue component.",
1012
- inputSchema: { componentName: import_zod6.z.string() }
1204
+ inputSchema: { componentName: import_zod7.z.string() }
1013
1205
  },
1014
1206
  ({ componentName }) => {
1015
1207
  if (!ctx.rpcServer) {
@@ -1037,7 +1229,7 @@ function registerVueTools(server, ctx) {
1037
1229
  MCP_TOOL_NAMES.getPiniaState,
1038
1230
  {
1039
1231
  description: "Get Pinia store state.",
1040
- inputSchema: { storeName: import_zod6.z.string() }
1232
+ inputSchema: { storeName: import_zod7.z.string() }
1041
1233
  },
1042
1234
  async ({ storeName }) => requestVueData(ctx, (event) => {
1043
1235
  void ctx.rpcServer?.getPiniaState({ event, storeName });
@@ -1159,6 +1351,10 @@ function createServerVueRuntimeRpc(ctx) {
1159
1351
  onDomQueryUpdated: (event, data) => {
1160
1352
  void ctx.hooks.callHook(event, data);
1161
1353
  },
1354
+ reloadPage: () => void 0,
1355
+ onPageReloaded: (event, data) => {
1356
+ void ctx.hooks.callHook(event, data);
1357
+ },
1162
1358
  evaluateScript: () => void 0,
1163
1359
  onEvaluateScriptUpdated: (event, data) => {
1164
1360
  void ctx.hooks.callHook(event, data);
@@ -1452,6 +1648,8 @@ async function startCdpObservers(ctx, target, client) {
1452
1648
  }
1453
1649
 
1454
1650
  // src/plugin/injectRuntime.ts
1651
+ var import_node_module = require("module");
1652
+ var import_node_path3 = require("path");
1455
1653
  function createRuntimeInjectionController(options, getConfig) {
1456
1654
  return {
1457
1655
  resolveId(importee) {
@@ -1461,6 +1659,9 @@ function createRuntimeInjectionController(options, getConfig) {
1461
1659
  if (importee === VIRTUAL_SCREENSHOT_CONFIG_ID) {
1462
1660
  return RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID;
1463
1661
  }
1662
+ if (importee === VIRTUAL_SNAPDOM_LOADER_ID) {
1663
+ return RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID;
1664
+ }
1464
1665
  return void 0;
1465
1666
  },
1466
1667
  load(id) {
@@ -1470,6 +1671,9 @@ function createRuntimeInjectionController(options, getConfig) {
1470
1671
  if (id === RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID) {
1471
1672
  return createScreenshotConfigModule(options);
1472
1673
  }
1674
+ if (id === RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID) {
1675
+ return createSnapdomLoaderModule(getConfig()?.root);
1676
+ }
1473
1677
  return void 0;
1474
1678
  },
1475
1679
  transformIndexHtml(html) {
@@ -1507,12 +1711,39 @@ ${code}`;
1507
1711
  }
1508
1712
  function createRuntimeModule() {
1509
1713
  return [
1510
- "import { setScreenshotModuleRegistry, startRuntimeClient } from '@xiaou66/vite-plugin-vue-mcp-next/runtime/client';",
1714
+ "import { setScreenshotModuleRegistry, setSnapdomLoader, startRuntimeClient } from '@xiaou66/vite-plugin-vue-mcp-next/runtime/client';",
1511
1715
  `import { screenshotModuleRegistry } from '${VIRTUAL_SCREENSHOT_CONFIG_ID}';`,
1716
+ `import { loadSnapdom } from '${VIRTUAL_SNAPDOM_LOADER_ID}';`,
1512
1717
  "setScreenshotModuleRegistry(screenshotModuleRegistry);",
1718
+ "setSnapdomLoader(loadSnapdom);",
1513
1719
  "void startRuntimeClient();"
1514
1720
  ].join("\n");
1515
1721
  }
1722
+ function createSnapdomLoaderModule(root) {
1723
+ if (!canResolveSnapdomFromProject(root)) {
1724
+ return [
1725
+ "export const loadSnapdom = () =>",
1726
+ ` Promise.reject(new Error(${JSON.stringify(createMissingSnapdomMessage())}));`
1727
+ ].join("\n");
1728
+ }
1729
+ return [
1730
+ "import { snapdom } from '@zumer/snapdom';",
1731
+ "export const loadSnapdom = () => Promise.resolve({ snapdom });"
1732
+ ].join("\n");
1733
+ }
1734
+ function canResolveSnapdomFromProject(root) {
1735
+ try {
1736
+ (0, import_node_module.createRequire)((0, import_node_path3.join)(root ?? process.cwd(), "package.json")).resolve(
1737
+ "@zumer/snapdom"
1738
+ );
1739
+ return true;
1740
+ } catch {
1741
+ return false;
1742
+ }
1743
+ }
1744
+ function createMissingSnapdomMessage() {
1745
+ return "\u7F3A\u5C11\u53EF\u9009\u4F9D\u8D56 @zumer/snapdom\u3002DOM \u622A\u56FE\u964D\u7EA7\u9700\u8981\u8BE5\u4F9D\u8D56\uFF0C\u8BF7\u6267\u884C\uFF1Apnpm add -D @zumer/snapdom";
1746
+ }
1516
1747
  function createScreenshotConfigModule(options) {
1517
1748
  const paths = collectScreenshotImportPaths(options);
1518
1749
  const imports = paths.map((item, index) => `import * as m${String(index)} from ${JSON.stringify(item)};`).join("\n");
@@ -1541,17 +1772,17 @@ function getPluginPath(plugin) {
1541
1772
  }
1542
1773
 
1543
1774
  // src/plugin/mcpClientConfig/index.ts
1544
- var import_node_path4 = __toESM(require("path"), 1);
1775
+ var import_node_path6 = __toESM(require("path"), 1);
1545
1776
 
1546
1777
  // src/plugin/mcpClientConfig/codexConfig.ts
1547
- var import_promises = __toESM(require("fs/promises"), 1);
1548
- var import_node_path2 = __toESM(require("path"), 1);
1778
+ var import_promises2 = __toESM(require("fs/promises"), 1);
1779
+ var import_node_path4 = __toESM(require("path"), 1);
1549
1780
  async function updateCodexMcpClientConfig(options) {
1550
1781
  try {
1551
1782
  const current = await readOptionalTextFile(options.configPath);
1552
1783
  const next = replaceOrAppendOwnedBlock(current, options);
1553
- await import_promises.default.mkdir(import_node_path2.default.dirname(options.configPath), { recursive: true });
1554
- await import_promises.default.writeFile(options.configPath, next);
1784
+ await import_promises2.default.mkdir(import_node_path4.default.dirname(options.configPath), { recursive: true });
1785
+ await import_promises2.default.writeFile(options.configPath, next);
1555
1786
  } catch (error) {
1556
1787
  console.warn(
1557
1788
  `[vite-plugin-vue-mcp-next] Failed to update Codex MCP config at ${options.configPath}: ${formatError(error)}`
@@ -1593,7 +1824,7 @@ function quoteTomlString(value) {
1593
1824
  }
1594
1825
  async function readOptionalTextFile(filePath) {
1595
1826
  try {
1596
- return await import_promises.default.readFile(filePath, "utf-8");
1827
+ return await import_promises2.default.readFile(filePath, "utf-8");
1597
1828
  } catch (error) {
1598
1829
  if (isNodeError(error) && error.code === "ENOENT") {
1599
1830
  return "";
@@ -1619,8 +1850,8 @@ function isNodeError(error) {
1619
1850
  }
1620
1851
 
1621
1852
  // src/plugin/mcpClientConfig/jsonConfig.ts
1622
- var import_promises2 = __toESM(require("fs/promises"), 1);
1623
- var import_node_path3 = __toESM(require("path"), 1);
1853
+ var import_promises3 = __toESM(require("fs/promises"), 1);
1854
+ var import_node_path5 = __toESM(require("path"), 1);
1624
1855
  async function updateJsonMcpClientConfig(options) {
1625
1856
  try {
1626
1857
  const config = await readJsonConfig(options.configPath);
@@ -1634,8 +1865,8 @@ async function updateJsonMcpClientConfig(options) {
1634
1865
  }
1635
1866
  mcpServers[options.serverName] = { type: "sse", url: options.mcpUrl };
1636
1867
  config.mcpServers = mcpServers;
1637
- await import_promises2.default.mkdir(import_node_path3.default.dirname(options.configPath), { recursive: true });
1638
- await import_promises2.default.writeFile(
1868
+ await import_promises3.default.mkdir(import_node_path5.default.dirname(options.configPath), { recursive: true });
1869
+ await import_promises3.default.writeFile(
1639
1870
  options.configPath,
1640
1871
  `${JSON.stringify(config, null, 2)}
1641
1872
  `
@@ -1653,7 +1884,7 @@ async function readJsonConfig(configPath) {
1653
1884
  }
1654
1885
  async function readOptionalTextFile2(filePath) {
1655
1886
  try {
1656
- return await import_promises2.default.readFile(filePath, "utf-8");
1887
+ return await import_promises3.default.readFile(filePath, "utf-8");
1657
1888
  } catch (error) {
1658
1889
  if (isNodeError2(error) && error.code === "ENOENT") {
1659
1890
  return "{}";
@@ -1684,7 +1915,7 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options)
1684
1915
  jobs.push(
1685
1916
  updateJsonMcpClientConfig({
1686
1917
  clientName: "Cursor",
1687
- configPath: import_node_path4.default.join(root, ".cursor", "mcp.json"),
1918
+ configPath: import_node_path6.default.join(root, ".cursor", "mcp.json"),
1688
1919
  mcpUrl: sseUrl,
1689
1920
  serverName
1690
1921
  })
@@ -1693,7 +1924,7 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options)
1693
1924
  if (options.codex) {
1694
1925
  jobs.push(
1695
1926
  updateCodexMcpClientConfig({
1696
- configPath: import_node_path4.default.join(root, ".codex", "config.toml"),
1927
+ configPath: import_node_path6.default.join(root, ".codex", "config.toml"),
1697
1928
  mcpUrl: streamableHttpUrl,
1698
1929
  serverName
1699
1930
  })
@@ -1703,7 +1934,7 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options)
1703
1934
  jobs.push(
1704
1935
  updateJsonMcpClientConfig({
1705
1936
  clientName: "Claude Code",
1706
- configPath: import_node_path4.default.join(root, ".mcp.json"),
1937
+ configPath: import_node_path6.default.join(root, ".mcp.json"),
1707
1938
  mcpUrl: sseUrl,
1708
1939
  serverName
1709
1940
  })
@@ -1713,7 +1944,7 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options)
1713
1944
  jobs.push(
1714
1945
  updateJsonMcpClientConfig({
1715
1946
  clientName: "Trae",
1716
- configPath: import_node_path4.default.join(root, ".trae", "mcp.json"),
1947
+ configPath: import_node_path6.default.join(root, ".trae", "mcp.json"),
1717
1948
  mcpUrl: sseUrl,
1718
1949
  serverName
1719
1950
  })
@@ -1742,6 +1973,7 @@ function vueMcpNext(userOptions = {}) {
1742
1973
  config = resolvedConfig;
1743
1974
  },
1744
1975
  async configureServer(server) {
1976
+ ctx.server = server;
1745
1977
  ctx.rpcServer = (0, import_vite_dev_rpc.createRPCServer)(
1746
1978
  "vite-plugin-vue-mcp-next",
1747
1979
  server.ws,
@@ -1760,6 +1992,7 @@ function vueMcpNext(userOptions = {}) {
1760
1992
  (payload) => {
1761
1993
  if (isRuntimePageTarget(payload)) {
1762
1994
  ctx.pages.upsert(payload);
1995
+ void ctx.hooks.callHook(RUNTIME_PAGE_RECONNECTED_EVENT, payload);
1763
1996
  void cdpLifecycle.connectPage(payload);
1764
1997
  }
1765
1998
  }