@xiaou66/vite-plugin-vue-mcp-next 1.0.2 → 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 +3 -1
- package/dist/index.cjs +54 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +54 -9
- package/dist/index.js.map +1 -1
- package/dist/runtime/client.cjs +58 -1
- package/dist/runtime/client.cjs.map +1 -1
- package/dist/runtime/client.d.cts +1 -2
- package/dist/runtime/client.d.ts +1 -2
- package/dist/runtime/client.js +58 -1
- package/dist/runtime/client.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -370,10 +370,25 @@ interface PageTarget {
|
|
|
370
370
|
readonly pathname: string;
|
|
371
371
|
/** 页面标题,用于 AI 和用户在多个相似 URL 中识别目标页面。 */
|
|
372
372
|
readonly title?: string;
|
|
373
|
+
/** 同标签页稳定身份,仅 runtime 目标提供,用于刷新或 HMR 重连时断开旧 pageId。 */
|
|
374
|
+
readonly runtimeClientId?: string;
|
|
373
375
|
/** 对应的 Vite HTML 入口或 appendTo 入口,用于说明页面来自哪个开发入口。 */
|
|
374
376
|
readonly entry?: string;
|
|
375
377
|
/** 页面是否仍可调试,用于避免 MCP 对已断开的页面继续执行操作。 */
|
|
376
378
|
readonly connected: boolean;
|
|
379
|
+
/** runtime 目标断开时间,仅用于保留短期历史并清理过期断开记录。 */
|
|
380
|
+
readonly disconnectedAt?: number;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* 页面目标列表选项。
|
|
384
|
+
*
|
|
385
|
+
* 默认列表面向日常调试,只展示可操作页面;排查生命周期问题时可显式包含断开 runtime 记录。
|
|
386
|
+
*/
|
|
387
|
+
interface PageTargetListOptions {
|
|
388
|
+
/** 是否包含已断开的 runtime 页面,默认隐藏以避免刷新历史干扰目标选择。 */
|
|
389
|
+
readonly includeDisconnected?: boolean;
|
|
390
|
+
/** 测试或批处理场景可传入固定时间,避免依赖真实时钟造成用例不稳定。 */
|
|
391
|
+
readonly now?: number;
|
|
377
392
|
}
|
|
378
393
|
/**
|
|
379
394
|
* 页面 Console 和运行时异常的统一记录。
|
|
@@ -444,13 +459,13 @@ interface NetworkRecord {
|
|
|
444
459
|
*/
|
|
445
460
|
interface PageTargetRegistry {
|
|
446
461
|
/** 新增或更新页面目标,适合 runtime 重连和 CDP target 刷新场景。 */
|
|
447
|
-
upsert(target: PageTarget): void;
|
|
462
|
+
upsert(target: PageTarget, now?: number): void;
|
|
448
463
|
/** 获取单个页面目标,工具调用解析 pageId 时使用。 */
|
|
449
464
|
get(pageId: string): PageTarget | undefined;
|
|
450
|
-
/**
|
|
451
|
-
list(): PageTarget[];
|
|
452
|
-
/**
|
|
453
|
-
disconnect(pageId: string): void;
|
|
465
|
+
/** 返回页面目标快照,默认隐藏已断开的 runtime 历史记录。 */
|
|
466
|
+
list(options?: PageTargetListOptions): PageTarget[];
|
|
467
|
+
/** 标记页面断开,保留短期记录可以帮助用户理解刚才的页面为什么不可操作。 */
|
|
468
|
+
disconnect(pageId: string, now?: number): void;
|
|
454
469
|
}
|
|
455
470
|
/**
|
|
456
471
|
* 插件内部共享上下文。
|
package/dist/index.d.ts
CHANGED
|
@@ -370,10 +370,25 @@ interface PageTarget {
|
|
|
370
370
|
readonly pathname: string;
|
|
371
371
|
/** 页面标题,用于 AI 和用户在多个相似 URL 中识别目标页面。 */
|
|
372
372
|
readonly title?: string;
|
|
373
|
+
/** 同标签页稳定身份,仅 runtime 目标提供,用于刷新或 HMR 重连时断开旧 pageId。 */
|
|
374
|
+
readonly runtimeClientId?: string;
|
|
373
375
|
/** 对应的 Vite HTML 入口或 appendTo 入口,用于说明页面来自哪个开发入口。 */
|
|
374
376
|
readonly entry?: string;
|
|
375
377
|
/** 页面是否仍可调试,用于避免 MCP 对已断开的页面继续执行操作。 */
|
|
376
378
|
readonly connected: boolean;
|
|
379
|
+
/** runtime 目标断开时间,仅用于保留短期历史并清理过期断开记录。 */
|
|
380
|
+
readonly disconnectedAt?: number;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* 页面目标列表选项。
|
|
384
|
+
*
|
|
385
|
+
* 默认列表面向日常调试,只展示可操作页面;排查生命周期问题时可显式包含断开 runtime 记录。
|
|
386
|
+
*/
|
|
387
|
+
interface PageTargetListOptions {
|
|
388
|
+
/** 是否包含已断开的 runtime 页面,默认隐藏以避免刷新历史干扰目标选择。 */
|
|
389
|
+
readonly includeDisconnected?: boolean;
|
|
390
|
+
/** 测试或批处理场景可传入固定时间,避免依赖真实时钟造成用例不稳定。 */
|
|
391
|
+
readonly now?: number;
|
|
377
392
|
}
|
|
378
393
|
/**
|
|
379
394
|
* 页面 Console 和运行时异常的统一记录。
|
|
@@ -444,13 +459,13 @@ interface NetworkRecord {
|
|
|
444
459
|
*/
|
|
445
460
|
interface PageTargetRegistry {
|
|
446
461
|
/** 新增或更新页面目标,适合 runtime 重连和 CDP target 刷新场景。 */
|
|
447
|
-
upsert(target: PageTarget): void;
|
|
462
|
+
upsert(target: PageTarget, now?: number): void;
|
|
448
463
|
/** 获取单个页面目标,工具调用解析 pageId 时使用。 */
|
|
449
464
|
get(pageId: string): PageTarget | undefined;
|
|
450
|
-
/**
|
|
451
|
-
list(): PageTarget[];
|
|
452
|
-
/**
|
|
453
|
-
disconnect(pageId: string): void;
|
|
465
|
+
/** 返回页面目标快照,默认隐藏已断开的 runtime 历史记录。 */
|
|
466
|
+
list(options?: PageTargetListOptions): PageTarget[];
|
|
467
|
+
/** 标记页面断开,保留短期记录可以帮助用户理解刚才的页面为什么不可操作。 */
|
|
468
|
+
disconnect(pageId: string, now?: number): void;
|
|
454
469
|
}
|
|
455
470
|
/**
|
|
456
471
|
* 插件内部共享上下文。
|
package/dist/index.js
CHANGED
|
@@ -194,24 +194,64 @@ function createRingBuffer(capacity) {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// src/context.ts
|
|
197
|
+
var MINUTE_MS = 60 * 1e3;
|
|
198
|
+
var DISCONNECTED_RUNTIME_TARGET_RETENTION_MS = 5 * MINUTE_MS;
|
|
199
|
+
function shouldPruneDisconnectedRuntimeTarget(target, now) {
|
|
200
|
+
return target.source === "runtime" && !target.connected && typeof target.disconnectedAt === "number" && now - target.disconnectedAt > DISCONNECTED_RUNTIME_TARGET_RETENTION_MS;
|
|
201
|
+
}
|
|
202
|
+
function pruneDisconnectedRuntimeTargets(targets, now) {
|
|
203
|
+
for (const [pageId, target] of targets) {
|
|
204
|
+
if (shouldPruneDisconnectedRuntimeTarget(target, now)) {
|
|
205
|
+
targets.delete(pageId);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function markTargetDisconnected(target, now) {
|
|
210
|
+
return {
|
|
211
|
+
...target,
|
|
212
|
+
connected: false,
|
|
213
|
+
disconnectedAt: target.disconnectedAt ?? now
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function shouldListPageTarget(target, options) {
|
|
217
|
+
return options.includeDisconnected === true || target.source !== "runtime" || target.connected;
|
|
218
|
+
}
|
|
219
|
+
function disconnectPreviousRuntimeClientTarget(targets, target, now) {
|
|
220
|
+
if (target.source !== "runtime" || !target.runtimeClientId) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
for (const [pageId, currentTarget] of targets) {
|
|
224
|
+
if (pageId === target.pageId || currentTarget.source !== "runtime" || currentTarget.runtimeClientId !== target.runtimeClientId || !currentTarget.connected) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
targets.set(pageId, markTargetDisconnected(currentTarget, now));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
197
230
|
function createPageTargetRegistry() {
|
|
198
231
|
const targets = /* @__PURE__ */ new Map();
|
|
199
232
|
return {
|
|
200
|
-
upsert(target) {
|
|
233
|
+
upsert(target, now = Date.now()) {
|
|
234
|
+
pruneDisconnectedRuntimeTargets(targets, now);
|
|
235
|
+
disconnectPreviousRuntimeClientTarget(targets, target, now);
|
|
201
236
|
targets.set(target.pageId, target);
|
|
202
237
|
},
|
|
203
238
|
get(pageId) {
|
|
204
239
|
return targets.get(pageId);
|
|
205
240
|
},
|
|
206
|
-
list() {
|
|
207
|
-
|
|
241
|
+
list(options = {}) {
|
|
242
|
+
const now = options.now ?? Date.now();
|
|
243
|
+
pruneDisconnectedRuntimeTargets(targets, now);
|
|
244
|
+
return [...targets.values()].filter(
|
|
245
|
+
(target) => shouldListPageTarget(target, options)
|
|
246
|
+
);
|
|
208
247
|
},
|
|
209
|
-
disconnect(pageId) {
|
|
248
|
+
disconnect(pageId, now = Date.now()) {
|
|
249
|
+
pruneDisconnectedRuntimeTargets(targets, now);
|
|
210
250
|
const target = targets.get(pageId);
|
|
211
251
|
if (!target) {
|
|
212
252
|
return;
|
|
213
253
|
}
|
|
214
|
-
targets.set(pageId,
|
|
254
|
+
targets.set(pageId, markTargetDisconnected(target, now));
|
|
215
255
|
}
|
|
216
256
|
};
|
|
217
257
|
}
|
|
@@ -664,9 +704,12 @@ function registerPageTools(server, ctx, vite) {
|
|
|
664
704
|
server.registerTool(
|
|
665
705
|
MCP_TOOL_NAMES.listPages,
|
|
666
706
|
{
|
|
667
|
-
description: "List Vite page entries and connected runtime/CDP targets."
|
|
707
|
+
description: "List Vite page entries and connected runtime/CDP targets.",
|
|
708
|
+
inputSchema: {
|
|
709
|
+
includeDisconnected: z5.boolean().optional()
|
|
710
|
+
}
|
|
668
711
|
},
|
|
669
|
-
async () => {
|
|
712
|
+
async (input) => {
|
|
670
713
|
const cdpResult = await listCdpPageTargets(ctx);
|
|
671
714
|
for (const target of cdpResult.pages) {
|
|
672
715
|
ctx.pages.upsert(target);
|
|
@@ -674,7 +717,9 @@ function registerPageTools(server, ctx, vite) {
|
|
|
674
717
|
}
|
|
675
718
|
return createToolResponse({
|
|
676
719
|
entries: discoverHtmlEntries(vite),
|
|
677
|
-
pages: ctx.pages.list(
|
|
720
|
+
pages: ctx.pages.list({
|
|
721
|
+
includeDisconnected: input.includeDisconnected
|
|
722
|
+
}),
|
|
678
723
|
cdpError: cdpResult.error
|
|
679
724
|
});
|
|
680
725
|
}
|
|
@@ -2298,7 +2343,7 @@ function isRuntimePageTarget(payload) {
|
|
|
2298
2343
|
return false;
|
|
2299
2344
|
}
|
|
2300
2345
|
const target = payload;
|
|
2301
|
-
return target.source === "runtime" && typeof target.pageId === "string" && typeof target.url === "string" && typeof target.pathname === "string" && typeof target.connected === "boolean";
|
|
2346
|
+
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");
|
|
2302
2347
|
}
|
|
2303
2348
|
function isConsoleRecord(payload) {
|
|
2304
2349
|
if (!payload || typeof payload !== "object") {
|