@xiaou66/vite-plugin-vue-mcp-next 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -402,7 +402,7 @@ export function createMaskPlugin(options: { selectors: string[] }) {
402
402
 
403
403
  | 工具 | 输入 | 输出 | 说明 |
404
404
  | ---------------- | ------------------------- | ------------------------------- | ----------------------------------------------------------------- |
405
- | `list_pages` | | `entries`、`pages`、`cdpError?` | 返回 Vite HTML 入口、runtime 页面和 CDP target |
405
+ | `list_pages` | `includeDisconnected?` | `entries`、`pages`、`cdpError?` | 返回 Vite HTML 入口、runtime 页面和 CDP target |
406
406
  | `reload_page` | `pageId?`、`ignoreCache?` | `ok`、`source`、`ignoreCache?` | 刷新目标页面;CDP 可用时使用无缓存刷新,Runtime Hook 只能普通刷新 |
407
407
 
408
408
  `list_pages` 的 `pages` 中可能出现两类页面:
@@ -410,6 +410,8 @@ export function createMaskPlugin(options: { selectors: string[] }) {
410
410
  - `runtime-*`:由页面注入 runtime bridge 后连接
411
411
  - `cdp:*`:由 CDP `/json/list` 发现
412
412
 
413
+ runtime 页面会为同一个浏览器标签页维护稳定 client id。刷新或 HMR 重连后,新 `pageId` 会成为可操作目标,旧 `pageId` 会被标记为 `connected: false` 并在默认 `list_pages` 结果中隐藏;需要排查页面生命周期时可传 `includeDisconnected: true` 查看断开记录。断开的 runtime 记录保留 5 分钟后会被清理,同 URL 的不同标签页仍会保留为不同目标。
414
+
413
415
  `reload_page` 默认在 CDP 路径使用 `ignoreCache: true`,并等待 CDP `loadEventFired` 后返回,适合在测试前绕过浏览器 HTTP 缓存重新加载页面。未配置 CDP 时会退回 Runtime Hook,通过 `window.location.reload()` 触发普通刷新,并等待新的 runtime 页面重新接入;这条回退路径不能保证绕过 HTTP cache,也不会清理 `localStorage`、`sessionStorage`、`IndexedDB`、`CacheStorage` 或 Service Worker 缓存。
414
416
 
415
417
  ### DOM 工具
package/dist/index.cjs CHANGED
@@ -231,24 +231,64 @@ function createRingBuffer(capacity) {
231
231
  }
232
232
 
233
233
  // src/context.ts
234
+ var MINUTE_MS = 60 * 1e3;
235
+ var DISCONNECTED_RUNTIME_TARGET_RETENTION_MS = 5 * MINUTE_MS;
236
+ function shouldPruneDisconnectedRuntimeTarget(target, now) {
237
+ return target.source === "runtime" && !target.connected && typeof target.disconnectedAt === "number" && now - target.disconnectedAt > DISCONNECTED_RUNTIME_TARGET_RETENTION_MS;
238
+ }
239
+ function pruneDisconnectedRuntimeTargets(targets, now) {
240
+ for (const [pageId, target] of targets) {
241
+ if (shouldPruneDisconnectedRuntimeTarget(target, now)) {
242
+ targets.delete(pageId);
243
+ }
244
+ }
245
+ }
246
+ function markTargetDisconnected(target, now) {
247
+ return {
248
+ ...target,
249
+ connected: false,
250
+ disconnectedAt: target.disconnectedAt ?? now
251
+ };
252
+ }
253
+ function shouldListPageTarget(target, options) {
254
+ return options.includeDisconnected === true || target.source !== "runtime" || target.connected;
255
+ }
256
+ function disconnectPreviousRuntimeClientTarget(targets, target, now) {
257
+ if (target.source !== "runtime" || !target.runtimeClientId) {
258
+ return;
259
+ }
260
+ for (const [pageId, currentTarget] of targets) {
261
+ if (pageId === target.pageId || currentTarget.source !== "runtime" || currentTarget.runtimeClientId !== target.runtimeClientId || !currentTarget.connected) {
262
+ continue;
263
+ }
264
+ targets.set(pageId, markTargetDisconnected(currentTarget, now));
265
+ }
266
+ }
234
267
  function createPageTargetRegistry() {
235
268
  const targets = /* @__PURE__ */ new Map();
236
269
  return {
237
- upsert(target) {
270
+ upsert(target, now = Date.now()) {
271
+ pruneDisconnectedRuntimeTargets(targets, now);
272
+ disconnectPreviousRuntimeClientTarget(targets, target, now);
238
273
  targets.set(target.pageId, target);
239
274
  },
240
275
  get(pageId) {
241
276
  return targets.get(pageId);
242
277
  },
243
- list() {
244
- return [...targets.values()];
278
+ list(options = {}) {
279
+ const now = options.now ?? Date.now();
280
+ pruneDisconnectedRuntimeTargets(targets, now);
281
+ return [...targets.values()].filter(
282
+ (target) => shouldListPageTarget(target, options)
283
+ );
245
284
  },
246
- disconnect(pageId) {
285
+ disconnect(pageId, now = Date.now()) {
286
+ pruneDisconnectedRuntimeTargets(targets, now);
247
287
  const target = targets.get(pageId);
248
288
  if (!target) {
249
289
  return;
250
290
  }
251
- targets.set(pageId, { ...target, connected: false });
291
+ targets.set(pageId, markTargetDisconnected(target, now));
252
292
  }
253
293
  };
254
294
  }
@@ -701,9 +741,12 @@ function registerPageTools(server, ctx, vite) {
701
741
  server.registerTool(
702
742
  MCP_TOOL_NAMES.listPages,
703
743
  {
704
- description: "List Vite page entries and connected runtime/CDP targets."
744
+ description: "List Vite page entries and connected runtime/CDP targets.",
745
+ inputSchema: {
746
+ includeDisconnected: import_zod5.z.boolean().optional()
747
+ }
705
748
  },
706
- async () => {
749
+ async (input) => {
707
750
  const cdpResult = await listCdpPageTargets(ctx);
708
751
  for (const target of cdpResult.pages) {
709
752
  ctx.pages.upsert(target);
@@ -711,7 +754,9 @@ function registerPageTools(server, ctx, vite) {
711
754
  }
712
755
  return createToolResponse({
713
756
  entries: discoverHtmlEntries(vite),
714
- pages: ctx.pages.list(),
757
+ pages: ctx.pages.list({
758
+ includeDisconnected: input.includeDisconnected
759
+ }),
715
760
  cdpError: cdpResult.error
716
761
  });
717
762
  }
@@ -2335,7 +2380,7 @@ function isRuntimePageTarget(payload) {
2335
2380
  return false;
2336
2381
  }
2337
2382
  const target = payload;
2338
- return target.source === "runtime" && typeof target.pageId === "string" && typeof target.url === "string" && typeof target.pathname === "string" && typeof target.connected === "boolean";
2383
+ return target.source === "runtime" && typeof target.pageId === "string" && typeof target.url === "string" && typeof target.pathname === "string" && typeof target.connected === "boolean" && (target.runtimeClientId === void 0 || typeof target.runtimeClientId === "string");
2339
2384
  }
2340
2385
  function isConsoleRecord(payload) {
2341
2386
  if (!payload || typeof payload !== "object") {