@xiaou66/vite-plugin-vue-mcp-next 1.2.0 → 1.3.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/README.md +41 -0
- package/dist/index.cjs +440 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -926
- package/dist/index.d.ts +5 -926
- package/dist/index.js +412 -94
- package/dist/index.js.map +1 -1
- package/dist/runtime/client.cjs +655 -176
- package/dist/runtime/client.cjs.map +1 -1
- package/dist/runtime/client.d.cts +5 -1
- package/dist/runtime/client.d.ts +5 -1
- package/dist/runtime/client.js +655 -176
- package/dist/runtime/client.js.map +1 -1
- package/dist/types-BKXdHkwk.d.cts +1019 -0
- package/dist/types-BKXdHkwk.d.ts +1019 -0
- package/package.json +3 -1
- package/skills/vite-mcp-next/SKILL.md +9 -6
package/dist/index.cjs
CHANGED
|
@@ -88,7 +88,8 @@ var MCP_TOOL_NAMES = {
|
|
|
88
88
|
highlightComponent: "highlight_component",
|
|
89
89
|
getRouterInfo: "get_router_info",
|
|
90
90
|
getPiniaTree: "get_pinia_tree",
|
|
91
|
-
getPiniaState: "get_pinia_state"
|
|
91
|
+
getPiniaState: "get_pinia_state",
|
|
92
|
+
getElementContext: "get_element_context"
|
|
92
93
|
};
|
|
93
94
|
var VIRTUAL_RUNTIME_ID = "virtual:vite-plugin-vue-mcp-next/runtime";
|
|
94
95
|
var RESOLVED_VIRTUAL_RUNTIME_ID = `\0${VIRTUAL_RUNTIME_ID}`;
|
|
@@ -99,6 +100,12 @@ var RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID = `\0${VIRTUAL_SNAPDOM_LOADER_ID}`;
|
|
|
99
100
|
var DEFAULT_MCP_CLIENT_SERVER_NAME = "vite-mcp-next";
|
|
100
101
|
var LEGACY_MCP_CLIENT_SERVER_NAMES = ["vue-mcp-next"];
|
|
101
102
|
var RUNTIME_PAGE_RECONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-reconnected";
|
|
103
|
+
var RUNTIME_PAGE_CONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-connected";
|
|
104
|
+
var RUNTIME_PAGE_DISCONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-disconnected";
|
|
105
|
+
var RUNTIME_PAGE_HEARTBEAT_EVENT = "vite-plugin-vue-mcp-next:heartbeat";
|
|
106
|
+
var DEFAULT_RUNTIME_PAGE_HEARTBEAT_TIMEOUT_MS = 45e3;
|
|
107
|
+
var DEFAULT_RUNTIME_PAGE_HEARTBEAT_SCAN_INTERVAL_MS = 45e3;
|
|
108
|
+
var DEFAULT_ELEMENT_PICKER_TOAST_DURATION_MS = 2200;
|
|
102
109
|
var DEFAULT_OPTIONS = {
|
|
103
110
|
mcpPath: DEFAULT_MCP_PATH,
|
|
104
111
|
host: "localhost",
|
|
@@ -117,6 +124,16 @@ var DEFAULT_OPTIONS = {
|
|
|
117
124
|
skill: {
|
|
118
125
|
autoConfig: true
|
|
119
126
|
},
|
|
127
|
+
elementPicker: {
|
|
128
|
+
enabled: true,
|
|
129
|
+
shortcut: {
|
|
130
|
+
altKey: true,
|
|
131
|
+
shiftKey: true,
|
|
132
|
+
metaKey: false,
|
|
133
|
+
ctrlKey: false
|
|
134
|
+
},
|
|
135
|
+
toastDurationMs: DEFAULT_ELEMENT_PICKER_TOAST_DURATION_MS
|
|
136
|
+
},
|
|
120
137
|
runtime: {
|
|
121
138
|
mode: "auto",
|
|
122
139
|
evaluate: {
|
|
@@ -191,6 +208,14 @@ function mergeOptions(options = {}) {
|
|
|
191
208
|
...DEFAULT_OPTIONS.skill,
|
|
192
209
|
...options.skill
|
|
193
210
|
},
|
|
211
|
+
elementPicker: {
|
|
212
|
+
...DEFAULT_OPTIONS.elementPicker,
|
|
213
|
+
...options.elementPicker,
|
|
214
|
+
shortcut: {
|
|
215
|
+
...DEFAULT_OPTIONS.elementPicker.shortcut,
|
|
216
|
+
...options.elementPicker?.shortcut
|
|
217
|
+
}
|
|
218
|
+
},
|
|
194
219
|
runtime: {
|
|
195
220
|
...DEFAULT_OPTIONS.runtime,
|
|
196
221
|
...options.runtime,
|
|
@@ -611,9 +636,164 @@ function registerDomTools(server, ctx) {
|
|
|
611
636
|
);
|
|
612
637
|
}
|
|
613
638
|
|
|
614
|
-
// src/mcp/tools/
|
|
639
|
+
// src/mcp/tools/elementContext.ts
|
|
615
640
|
var import_zod3 = require("zod");
|
|
616
641
|
|
|
642
|
+
// src/shared/elementId.ts
|
|
643
|
+
var PROJECT_SOURCE_ID_PATTERN = /^(.+\.(?:vue|tsx|jsx|ts|js)):(\d+):(\d+)$/;
|
|
644
|
+
var RUNTIME_ID_PATTERN = /^runtime:([A-Za-z0-9_-]+)$/;
|
|
645
|
+
var PACKAGE_ID_PREFIX = "pkg:";
|
|
646
|
+
function parseElementId(elementId) {
|
|
647
|
+
const sourceMatch = PROJECT_SOURCE_ID_PATTERN.exec(elementId);
|
|
648
|
+
if (sourceMatch) {
|
|
649
|
+
return {
|
|
650
|
+
kind: "project-source",
|
|
651
|
+
elementId,
|
|
652
|
+
file: sourceMatch[1],
|
|
653
|
+
line: Number(sourceMatch[2]),
|
|
654
|
+
column: Number(sourceMatch[3])
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
if (elementId.startsWith(PACKAGE_ID_PREFIX)) {
|
|
658
|
+
return parsePackageElementId(elementId);
|
|
659
|
+
}
|
|
660
|
+
const runtimeMatch = RUNTIME_ID_PATTERN.exec(elementId);
|
|
661
|
+
if (runtimeMatch) {
|
|
662
|
+
return {
|
|
663
|
+
kind: "runtime",
|
|
664
|
+
elementId,
|
|
665
|
+
runtimeId: runtimeMatch[1]
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
kind: "invalid",
|
|
670
|
+
elementId,
|
|
671
|
+
reason: "unsupported elementId format"
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function parsePackageElementId(elementId) {
|
|
675
|
+
const value = elementId.slice(PACKAGE_ID_PREFIX.length);
|
|
676
|
+
const parts = value.split("/").filter(Boolean);
|
|
677
|
+
if (parts.length < 2) {
|
|
678
|
+
return {
|
|
679
|
+
kind: "invalid",
|
|
680
|
+
elementId,
|
|
681
|
+
reason: "package elementId must include packageName and entryFile"
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
const scoped = parts[0]?.startsWith("@");
|
|
685
|
+
const packageName = scoped ? parts.slice(0, 2).join("/") : parts[0];
|
|
686
|
+
const entryFile = parts.slice(scoped ? 2 : 1).join("/");
|
|
687
|
+
if (!entryFile) {
|
|
688
|
+
return {
|
|
689
|
+
kind: "invalid",
|
|
690
|
+
elementId,
|
|
691
|
+
reason: "package elementId must include entryFile"
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
return {
|
|
695
|
+
kind: "package",
|
|
696
|
+
elementId,
|
|
697
|
+
packageName,
|
|
698
|
+
entryFile
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// src/mcp/tools/elementContext.ts
|
|
703
|
+
function registerElementContextTools(server, ctx) {
|
|
704
|
+
server.registerTool(
|
|
705
|
+
MCP_TOOL_NAMES.getElementContext,
|
|
706
|
+
{
|
|
707
|
+
description: "Get editable source, Vue component, and DOM context for a copied elementId.",
|
|
708
|
+
inputSchema: {
|
|
709
|
+
elementId: import_zod3.z.string(),
|
|
710
|
+
pageId: import_zod3.z.string().optional()
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
async (input) => {
|
|
714
|
+
const runtimeResult = await tryRuntimeElementContext(
|
|
715
|
+
ctx,
|
|
716
|
+
input.elementId,
|
|
717
|
+
input.pageId
|
|
718
|
+
);
|
|
719
|
+
if (runtimeResult) {
|
|
720
|
+
return createToolResponse(runtimeResult);
|
|
721
|
+
}
|
|
722
|
+
return createToolResponse(createStaticElementContext(input.elementId));
|
|
723
|
+
}
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
async function tryRuntimeElementContext(ctx, elementId, pageId) {
|
|
727
|
+
if (!ctx.rpcServer) {
|
|
728
|
+
return parseElementId(elementId).kind === "runtime" ? createRuntimeUnavailableContext(elementId) : void 0;
|
|
729
|
+
}
|
|
730
|
+
try {
|
|
731
|
+
resolvePageTarget(ctx, pageId);
|
|
732
|
+
} catch (error) {
|
|
733
|
+
const parsed = parseElementId(elementId);
|
|
734
|
+
if (parsed.kind === "project-source" || parsed.kind === "package") {
|
|
735
|
+
return void 0;
|
|
736
|
+
}
|
|
737
|
+
return {
|
|
738
|
+
ok: false,
|
|
739
|
+
elementId,
|
|
740
|
+
error: error instanceof Error ? error.message : String(error),
|
|
741
|
+
limitations: ["call list_pages and pass pageId when multiple pages exist"]
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
return await requestRuntimeData(ctx, (event) => {
|
|
745
|
+
void ctx.rpcServer?.getElementContext({ event, elementId });
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
function createStaticElementContext(elementId) {
|
|
749
|
+
const parsed = parseElementId(elementId);
|
|
750
|
+
if (parsed.kind === "project-source") {
|
|
751
|
+
return {
|
|
752
|
+
ok: true,
|
|
753
|
+
elementId,
|
|
754
|
+
editable: true,
|
|
755
|
+
codeLocation: {
|
|
756
|
+
file: parsed.file,
|
|
757
|
+
line: parsed.line,
|
|
758
|
+
column: parsed.column
|
|
759
|
+
},
|
|
760
|
+
limitations: ["runtime unavailable, DOM and component context omitted"]
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
if (parsed.kind === "package") {
|
|
764
|
+
return {
|
|
765
|
+
ok: true,
|
|
766
|
+
elementId,
|
|
767
|
+
editable: false,
|
|
768
|
+
packageLocation: {
|
|
769
|
+
packageName: parsed.packageName,
|
|
770
|
+
entryFile: parsed.entryFile
|
|
771
|
+
},
|
|
772
|
+
limitations: ["third-party package source is not editable from this project"]
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
if (parsed.kind === "runtime") {
|
|
776
|
+
return createRuntimeUnavailableContext(elementId);
|
|
777
|
+
}
|
|
778
|
+
return {
|
|
779
|
+
ok: false,
|
|
780
|
+
elementId,
|
|
781
|
+
error: parsed.reason,
|
|
782
|
+
limitations: ["please provide a copied elementId from the element picker"]
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
function createRuntimeUnavailableContext(elementId) {
|
|
786
|
+
return {
|
|
787
|
+
ok: false,
|
|
788
|
+
elementId,
|
|
789
|
+
error: "runtime bridge is not connected",
|
|
790
|
+
limitations: ["runtime ids are only valid while the page is connected"]
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/mcp/tools/evaluate.ts
|
|
795
|
+
var import_zod4 = require("zod");
|
|
796
|
+
|
|
617
797
|
// src/cdp/cdpEvaluate.ts
|
|
618
798
|
async function cdpEvaluate(options) {
|
|
619
799
|
const result = await options.client.Runtime.evaluate({
|
|
@@ -634,9 +814,9 @@ function registerEvaluateTools(server, ctx) {
|
|
|
634
814
|
{
|
|
635
815
|
description: "Evaluate a script in the selected page when explicitly enabled.",
|
|
636
816
|
inputSchema: {
|
|
637
|
-
pageId:
|
|
638
|
-
expression:
|
|
639
|
-
awaitPromise:
|
|
817
|
+
pageId: import_zod4.z.string().optional(),
|
|
818
|
+
expression: import_zod4.z.string(),
|
|
819
|
+
awaitPromise: import_zod4.z.boolean().optional()
|
|
640
820
|
}
|
|
641
821
|
},
|
|
642
822
|
async (input) => {
|
|
@@ -685,18 +865,18 @@ function assertEvaluateEnabled(options) {
|
|
|
685
865
|
}
|
|
686
866
|
|
|
687
867
|
// src/mcp/tools/network.ts
|
|
688
|
-
var
|
|
868
|
+
var import_zod5 = require("zod");
|
|
689
869
|
function registerNetworkTools(server, ctx) {
|
|
690
870
|
server.registerTool(
|
|
691
871
|
MCP_TOOL_NAMES.getNetworkRequests,
|
|
692
872
|
{
|
|
693
873
|
description: "Get captured network request summaries.",
|
|
694
874
|
inputSchema: {
|
|
695
|
-
pageId:
|
|
696
|
-
urlContains:
|
|
697
|
-
method:
|
|
698
|
-
status:
|
|
699
|
-
limit:
|
|
875
|
+
pageId: import_zod5.z.string().optional(),
|
|
876
|
+
urlContains: import_zod5.z.string().optional(),
|
|
877
|
+
method: import_zod5.z.string().optional(),
|
|
878
|
+
status: import_zod5.z.number().optional(),
|
|
879
|
+
limit: import_zod5.z.number().optional()
|
|
700
880
|
}
|
|
701
881
|
},
|
|
702
882
|
(input) => {
|
|
@@ -719,7 +899,7 @@ function registerNetworkTools(server, ctx) {
|
|
|
719
899
|
MCP_TOOL_NAMES.getNetworkRequestDetail,
|
|
720
900
|
{
|
|
721
901
|
description: "Get captured network request detail by id.",
|
|
722
|
-
inputSchema: { id:
|
|
902
|
+
inputSchema: { id: import_zod5.z.string() }
|
|
723
903
|
},
|
|
724
904
|
(input) => {
|
|
725
905
|
if (ctx.options.network.mode === "off") {
|
|
@@ -736,7 +916,7 @@ function registerNetworkTools(server, ctx) {
|
|
|
736
916
|
{
|
|
737
917
|
description: "Clear cached network requests.",
|
|
738
918
|
inputSchema: {
|
|
739
|
-
pageId:
|
|
919
|
+
pageId: import_zod5.z.string().optional()
|
|
740
920
|
}
|
|
741
921
|
},
|
|
742
922
|
() => {
|
|
@@ -747,7 +927,7 @@ function registerNetworkTools(server, ctx) {
|
|
|
747
927
|
}
|
|
748
928
|
|
|
749
929
|
// src/mcp/tools/performance.ts
|
|
750
|
-
var
|
|
930
|
+
var import_zod6 = require("zod");
|
|
751
931
|
|
|
752
932
|
// src/performance/summary.ts
|
|
753
933
|
function buildPerformanceSummary(input) {
|
|
@@ -1029,10 +1209,10 @@ function registerPerformanceTools(server, ctx) {
|
|
|
1029
1209
|
{
|
|
1030
1210
|
description: "Record a performance sample for the selected page.",
|
|
1031
1211
|
inputSchema: {
|
|
1032
|
-
pageId:
|
|
1033
|
-
durationMs:
|
|
1034
|
-
includeMemory:
|
|
1035
|
-
includeStacks:
|
|
1212
|
+
pageId: import_zod6.z.string().optional(),
|
|
1213
|
+
durationMs: import_zod6.z.number().optional(),
|
|
1214
|
+
includeMemory: import_zod6.z.boolean().optional(),
|
|
1215
|
+
includeStacks: import_zod6.z.boolean().optional()
|
|
1036
1216
|
}
|
|
1037
1217
|
},
|
|
1038
1218
|
async (input) => handleRecordPerformance(ctx, input)
|
|
@@ -1042,9 +1222,9 @@ function registerPerformanceTools(server, ctx) {
|
|
|
1042
1222
|
{
|
|
1043
1223
|
description: "Start a performance recording session.",
|
|
1044
1224
|
inputSchema: {
|
|
1045
|
-
pageId:
|
|
1046
|
-
includeMemory:
|
|
1047
|
-
includeStacks:
|
|
1225
|
+
pageId: import_zod6.z.string().optional(),
|
|
1226
|
+
includeMemory: import_zod6.z.boolean().optional(),
|
|
1227
|
+
includeStacks: import_zod6.z.boolean().optional()
|
|
1048
1228
|
}
|
|
1049
1229
|
},
|
|
1050
1230
|
async (input) => handleStartPerformanceRecording(ctx, input)
|
|
@@ -1054,7 +1234,7 @@ function registerPerformanceTools(server, ctx) {
|
|
|
1054
1234
|
{
|
|
1055
1235
|
description: "Stop a performance recording session.",
|
|
1056
1236
|
inputSchema: {
|
|
1057
|
-
recordingId:
|
|
1237
|
+
recordingId: import_zod6.z.string()
|
|
1058
1238
|
}
|
|
1059
1239
|
},
|
|
1060
1240
|
async (input) => handleStopPerformanceRecording(ctx, input)
|
|
@@ -1064,9 +1244,9 @@ function registerPerformanceTools(server, ctx) {
|
|
|
1064
1244
|
{
|
|
1065
1245
|
description: "Get cached performance reports and active sessions.",
|
|
1066
1246
|
inputSchema: {
|
|
1067
|
-
pageId:
|
|
1068
|
-
recordingId:
|
|
1069
|
-
limit:
|
|
1247
|
+
pageId: import_zod6.z.string().optional(),
|
|
1248
|
+
recordingId: import_zod6.z.string().optional(),
|
|
1249
|
+
limit: import_zod6.z.number().optional()
|
|
1070
1250
|
}
|
|
1071
1251
|
},
|
|
1072
1252
|
(input) => handleGetPerformanceReport(ctx, input)
|
|
@@ -1076,7 +1256,7 @@ function registerPerformanceTools(server, ctx) {
|
|
|
1076
1256
|
{
|
|
1077
1257
|
description: "Take a heap snapshot with CDP.",
|
|
1078
1258
|
inputSchema: {
|
|
1079
|
-
pageId:
|
|
1259
|
+
pageId: import_zod6.z.string().optional()
|
|
1080
1260
|
}
|
|
1081
1261
|
},
|
|
1082
1262
|
async (input) => handleTakeHeapSnapshot(ctx, input)
|
|
@@ -1333,7 +1513,7 @@ function toStructuredRecord(value) {
|
|
|
1333
1513
|
}
|
|
1334
1514
|
|
|
1335
1515
|
// src/mcp/tools/pages.ts
|
|
1336
|
-
var
|
|
1516
|
+
var import_zod7 = require("zod");
|
|
1337
1517
|
|
|
1338
1518
|
// src/plugin/entryDiscovery.ts
|
|
1339
1519
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
@@ -1358,10 +1538,10 @@ function walkHtmlEntries(root, dir, entries) {
|
|
|
1358
1538
|
if (!item.isFile() || !item.name.endsWith(".html")) {
|
|
1359
1539
|
continue;
|
|
1360
1540
|
}
|
|
1361
|
-
const
|
|
1541
|
+
const relative3 = (0, import_vite.normalizePath)(import_node_path2.default.relative(root, fullPath));
|
|
1362
1542
|
entries.push({
|
|
1363
|
-
file:
|
|
1364
|
-
pathname:
|
|
1543
|
+
file: relative3,
|
|
1544
|
+
pathname: relative3 === "index.html" ? "/" : `/${relative3}`
|
|
1365
1545
|
});
|
|
1366
1546
|
}
|
|
1367
1547
|
}
|
|
@@ -1373,7 +1553,7 @@ function registerPageTools(server, ctx, vite) {
|
|
|
1373
1553
|
{
|
|
1374
1554
|
description: "List Vite page entries and connected runtime/CDP targets.",
|
|
1375
1555
|
inputSchema: {
|
|
1376
|
-
includeDisconnected:
|
|
1556
|
+
includeDisconnected: import_zod7.z.boolean().optional()
|
|
1377
1557
|
}
|
|
1378
1558
|
},
|
|
1379
1559
|
async (input) => {
|
|
@@ -1396,8 +1576,8 @@ function registerPageTools(server, ctx, vite) {
|
|
|
1396
1576
|
{
|
|
1397
1577
|
description: "Reload the selected page. CDP uses ignoreCache; Runtime Hook falls back to normal reload.",
|
|
1398
1578
|
inputSchema: {
|
|
1399
|
-
pageId:
|
|
1400
|
-
ignoreCache:
|
|
1579
|
+
pageId: import_zod7.z.string().optional(),
|
|
1580
|
+
ignoreCache: import_zod7.z.boolean().optional()
|
|
1401
1581
|
}
|
|
1402
1582
|
},
|
|
1403
1583
|
async (input) => {
|
|
@@ -1549,7 +1729,7 @@ function getPathname(url) {
|
|
|
1549
1729
|
}
|
|
1550
1730
|
|
|
1551
1731
|
// src/mcp/tools/storage.ts
|
|
1552
|
-
var
|
|
1732
|
+
var import_zod8 = require("zod");
|
|
1553
1733
|
|
|
1554
1734
|
// src/cdp/cdpStorage.ts
|
|
1555
1735
|
function createCdpStorageAdapter(client) {
|
|
@@ -1793,7 +1973,7 @@ function registerStorageTools(server, ctx) {
|
|
|
1793
1973
|
registerStorageTool(server, MCP_TOOL_NAMES.listStorage, {
|
|
1794
1974
|
description: "List same-origin storage and CDP cookies when available.",
|
|
1795
1975
|
inputSchema: {
|
|
1796
|
-
pageId:
|
|
1976
|
+
pageId: import_zod8.z.string().optional()
|
|
1797
1977
|
},
|
|
1798
1978
|
action: "list",
|
|
1799
1979
|
handler: (input) => handleListStorage(ctx, input.pageId)
|
|
@@ -1837,23 +2017,23 @@ function registerStorageTool(server, name, options) {
|
|
|
1837
2017
|
}
|
|
1838
2018
|
function createStorageInputSchema() {
|
|
1839
2019
|
return {
|
|
1840
|
-
pageId:
|
|
1841
|
-
scope:
|
|
1842
|
-
key:
|
|
1843
|
-
value:
|
|
1844
|
-
databaseName:
|
|
1845
|
-
objectStoreName:
|
|
1846
|
-
indexName:
|
|
1847
|
-
cookie:
|
|
1848
|
-
name:
|
|
1849
|
-
value:
|
|
1850
|
-
domain:
|
|
1851
|
-
path:
|
|
1852
|
-
url:
|
|
1853
|
-
httpOnly:
|
|
1854
|
-
secure:
|
|
1855
|
-
sameSite:
|
|
1856
|
-
expires:
|
|
2020
|
+
pageId: import_zod8.z.string().optional(),
|
|
2021
|
+
scope: import_zod8.z.enum(["localStorage", "sessionStorage", "indexedDB", "cookie"]).optional(),
|
|
2022
|
+
key: import_zod8.z.string().optional(),
|
|
2023
|
+
value: import_zod8.z.string().optional(),
|
|
2024
|
+
databaseName: import_zod8.z.string().optional(),
|
|
2025
|
+
objectStoreName: import_zod8.z.string().optional(),
|
|
2026
|
+
indexName: import_zod8.z.string().optional(),
|
|
2027
|
+
cookie: import_zod8.z.object({
|
|
2028
|
+
name: import_zod8.z.string(),
|
|
2029
|
+
value: import_zod8.z.string().optional(),
|
|
2030
|
+
domain: import_zod8.z.string().optional(),
|
|
2031
|
+
path: import_zod8.z.string().optional(),
|
|
2032
|
+
url: import_zod8.z.string().optional(),
|
|
2033
|
+
httpOnly: import_zod8.z.boolean().optional(),
|
|
2034
|
+
secure: import_zod8.z.boolean().optional(),
|
|
2035
|
+
sameSite: import_zod8.z.enum(["strict", "lax", "none"]).optional(),
|
|
2036
|
+
expires: import_zod8.z.number().optional()
|
|
1857
2037
|
}).optional()
|
|
1858
2038
|
};
|
|
1859
2039
|
}
|
|
@@ -1971,7 +2151,7 @@ function hasCdpConfig2(ctx) {
|
|
|
1971
2151
|
}
|
|
1972
2152
|
|
|
1973
2153
|
// src/mcp/tools/screenshot.ts
|
|
1974
|
-
var
|
|
2154
|
+
var import_zod9 = require("zod");
|
|
1975
2155
|
|
|
1976
2156
|
// src/cdp/cdpScreenshot.ts
|
|
1977
2157
|
async function cdpCaptureScreenshot(options) {
|
|
@@ -2131,14 +2311,14 @@ function createProjectRelativePath(ctx, filePath) {
|
|
|
2131
2311
|
var DEFAULT_SCREENSHOT_TARGET = "viewport";
|
|
2132
2312
|
var DEFAULT_SCREENSHOT_FORMAT = "png";
|
|
2133
2313
|
var screenshotInputSchema = {
|
|
2134
|
-
pageId:
|
|
2135
|
-
target:
|
|
2136
|
-
selector:
|
|
2137
|
-
format:
|
|
2138
|
-
prefer:
|
|
2139
|
-
quality:
|
|
2140
|
-
scale:
|
|
2141
|
-
snapdom:
|
|
2314
|
+
pageId: import_zod9.z.string().optional(),
|
|
2315
|
+
target: import_zod9.z.enum(["viewport", "fullPage", "element"]).optional(),
|
|
2316
|
+
selector: import_zod9.z.string().optional(),
|
|
2317
|
+
format: import_zod9.z.enum(["png", "jpeg", "webp"]).optional(),
|
|
2318
|
+
prefer: import_zod9.z.enum(["auto", "cdp", "runtime"]).optional(),
|
|
2319
|
+
quality: import_zod9.z.number().optional(),
|
|
2320
|
+
scale: import_zod9.z.number().optional(),
|
|
2321
|
+
snapdom: import_zod9.z.record(import_zod9.z.string(), import_zod9.z.unknown()).optional()
|
|
2142
2322
|
};
|
|
2143
2323
|
function registerScreenshotTools(server, ctx) {
|
|
2144
2324
|
server.registerTool(
|
|
@@ -2258,7 +2438,7 @@ function isScreenshotImagePayload(result) {
|
|
|
2258
2438
|
|
|
2259
2439
|
// src/mcp/tools/vue.ts
|
|
2260
2440
|
var import_nanoid3 = require("nanoid");
|
|
2261
|
-
var
|
|
2441
|
+
var import_zod10 = require("zod");
|
|
2262
2442
|
function registerVueTools(server, ctx) {
|
|
2263
2443
|
server.registerTool(
|
|
2264
2444
|
MCP_TOOL_NAMES.getComponentTree,
|
|
@@ -2271,7 +2451,7 @@ function registerVueTools(server, ctx) {
|
|
|
2271
2451
|
MCP_TOOL_NAMES.getComponentState,
|
|
2272
2452
|
{
|
|
2273
2453
|
description: "Get Vue component state.",
|
|
2274
|
-
inputSchema: { componentName:
|
|
2454
|
+
inputSchema: { componentName: import_zod10.z.string() }
|
|
2275
2455
|
},
|
|
2276
2456
|
async ({ componentName }) => requestVueData(ctx, (event) => {
|
|
2277
2457
|
void ctx.rpcServer?.getInspectorState({ event, componentName });
|
|
@@ -2282,10 +2462,10 @@ function registerVueTools(server, ctx) {
|
|
|
2282
2462
|
{
|
|
2283
2463
|
description: "Edit Vue component state.",
|
|
2284
2464
|
inputSchema: {
|
|
2285
|
-
componentName:
|
|
2286
|
-
path:
|
|
2287
|
-
value:
|
|
2288
|
-
valueType:
|
|
2465
|
+
componentName: import_zod10.z.string(),
|
|
2466
|
+
path: import_zod10.z.array(import_zod10.z.string()),
|
|
2467
|
+
value: import_zod10.z.string(),
|
|
2468
|
+
valueType: import_zod10.z.enum(["string", "number", "boolean", "object", "array"])
|
|
2289
2469
|
}
|
|
2290
2470
|
},
|
|
2291
2471
|
({ componentName, path: path8, value, valueType }) => {
|
|
@@ -2305,7 +2485,7 @@ function registerVueTools(server, ctx) {
|
|
|
2305
2485
|
MCP_TOOL_NAMES.highlightComponent,
|
|
2306
2486
|
{
|
|
2307
2487
|
description: "Highlight a Vue component.",
|
|
2308
|
-
inputSchema: { componentName:
|
|
2488
|
+
inputSchema: { componentName: import_zod10.z.string() }
|
|
2309
2489
|
},
|
|
2310
2490
|
({ componentName }) => {
|
|
2311
2491
|
if (!ctx.rpcServer) {
|
|
@@ -2333,7 +2513,7 @@ function registerVueTools(server, ctx) {
|
|
|
2333
2513
|
MCP_TOOL_NAMES.getPiniaState,
|
|
2334
2514
|
{
|
|
2335
2515
|
description: "Get Pinia store state.",
|
|
2336
|
-
inputSchema: { storeName:
|
|
2516
|
+
inputSchema: { storeName: import_zod10.z.string() }
|
|
2337
2517
|
},
|
|
2338
2518
|
async ({ storeName }) => requestVueData(ctx, (event) => {
|
|
2339
2519
|
void ctx.rpcServer?.getPiniaState({ event, storeName });
|
|
@@ -2376,6 +2556,7 @@ function createMcpServer(ctx, vite) {
|
|
|
2376
2556
|
});
|
|
2377
2557
|
registerPageTools(server, ctx, vite);
|
|
2378
2558
|
registerDomTools(server, ctx);
|
|
2559
|
+
registerElementContextTools(server, ctx);
|
|
2379
2560
|
registerScreenshotTools(server, ctx);
|
|
2380
2561
|
registerConsoleTools(server, ctx);
|
|
2381
2562
|
registerEvaluateTools(server, ctx);
|
|
@@ -2457,6 +2638,10 @@ function createServerVueRuntimeRpc(ctx) {
|
|
|
2457
2638
|
onDomQueryUpdated: (event, data) => {
|
|
2458
2639
|
void ctx.hooks.callHook(event, data);
|
|
2459
2640
|
},
|
|
2641
|
+
getElementContext: () => void 0,
|
|
2642
|
+
onElementContextUpdated: (event, data) => {
|
|
2643
|
+
void ctx.hooks.callHook(event, data);
|
|
2644
|
+
},
|
|
2460
2645
|
reloadPage: () => void 0,
|
|
2461
2646
|
onPageReloaded: (event, data) => {
|
|
2462
2647
|
void ctx.hooks.callHook(event, data);
|
|
@@ -2769,9 +2954,85 @@ async function startCdpObservers(ctx, target, client) {
|
|
|
2769
2954
|
}
|
|
2770
2955
|
}
|
|
2771
2956
|
|
|
2957
|
+
// src/plugin/elementInstrumentation.ts
|
|
2958
|
+
var import_compiler_sfc = require("@vue/compiler-sfc");
|
|
2959
|
+
var import_magic_string = __toESM(require("magic-string"), 1);
|
|
2960
|
+
var import_node_path4 = require("path");
|
|
2961
|
+
var VUE_FILE_SUFFIX = ".vue";
|
|
2962
|
+
var ELEMENT_NODE_TYPE = 1;
|
|
2963
|
+
var SKIPPED_TAGS = /* @__PURE__ */ new Set(["template", "slot", "script", "style"]);
|
|
2964
|
+
var MCP_ID_ATTR = "data-v-mcp-id";
|
|
2965
|
+
function createElementInstrumentationController(options) {
|
|
2966
|
+
return {
|
|
2967
|
+
transform(code, id, ssr) {
|
|
2968
|
+
if (ssr || shouldSkipInstrumentation(id)) {
|
|
2969
|
+
return void 0;
|
|
2970
|
+
}
|
|
2971
|
+
const filename = id.split("?", 1)[0];
|
|
2972
|
+
if (!filename.endsWith(VUE_FILE_SUFFIX)) {
|
|
2973
|
+
return void 0;
|
|
2974
|
+
}
|
|
2975
|
+
const parsed = (0, import_compiler_sfc.parse)(code, { filename });
|
|
2976
|
+
const template = parsed.descriptor.template;
|
|
2977
|
+
if (!template?.ast) {
|
|
2978
|
+
return void 0;
|
|
2979
|
+
}
|
|
2980
|
+
const s = new import_magic_string.default(code);
|
|
2981
|
+
const relativeFile = normalizePath2((0, import_node_path4.relative)(options.root, filename));
|
|
2982
|
+
for (const node of template.ast.children) {
|
|
2983
|
+
injectNodeId(s, node, relativeFile);
|
|
2984
|
+
}
|
|
2985
|
+
if (!s.hasChanged()) {
|
|
2986
|
+
return void 0;
|
|
2987
|
+
}
|
|
2988
|
+
return {
|
|
2989
|
+
code: s.toString(),
|
|
2990
|
+
map: s.generateMap({ hires: true })
|
|
2991
|
+
};
|
|
2992
|
+
}
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
function shouldSkipInstrumentation(id) {
|
|
2996
|
+
if (id.startsWith("\0")) {
|
|
2997
|
+
return true;
|
|
2998
|
+
}
|
|
2999
|
+
const normalized = normalizePath2(id);
|
|
3000
|
+
if (normalized.includes("/node_modules/")) {
|
|
3001
|
+
return true;
|
|
3002
|
+
}
|
|
3003
|
+
return !normalized.startsWith("/") && !/^[A-Za-z]:\//.test(normalized);
|
|
3004
|
+
}
|
|
3005
|
+
function normalizePath2(path8) {
|
|
3006
|
+
return path8.replace(/\\/g, "/");
|
|
3007
|
+
}
|
|
3008
|
+
function injectNodeId(s, node, relativeFile) {
|
|
3009
|
+
if (node.type !== ELEMENT_NODE_TYPE || !node.tag || !node.loc) {
|
|
3010
|
+
return;
|
|
3011
|
+
}
|
|
3012
|
+
if (!SKIPPED_TAGS.has(node.tag) && !hasMcpIdAttr(node)) {
|
|
3013
|
+
const id = `${relativeFile}:${String(node.loc.start.line)}:${String(node.loc.start.column)}`;
|
|
3014
|
+
const insertAt = node.loc.start.offset + node.tag.length + 1;
|
|
3015
|
+
s.appendLeft(insertAt, ` ${MCP_ID_ATTR}="${id}"`);
|
|
3016
|
+
}
|
|
3017
|
+
for (const child of node.children ?? []) {
|
|
3018
|
+
injectNodeId(s, child, relativeFile);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
function hasMcpIdAttr(node) {
|
|
3022
|
+
return (node.props ?? []).some((prop) => {
|
|
3023
|
+
if (!isTemplateProp(prop)) {
|
|
3024
|
+
return false;
|
|
3025
|
+
}
|
|
3026
|
+
return prop.name === MCP_ID_ATTR;
|
|
3027
|
+
});
|
|
3028
|
+
}
|
|
3029
|
+
function isTemplateProp(value) {
|
|
3030
|
+
return Boolean(value && typeof value === "object" && "name" in value);
|
|
3031
|
+
}
|
|
3032
|
+
|
|
2772
3033
|
// src/plugin/injectRuntime.ts
|
|
2773
3034
|
var import_node_module = require("module");
|
|
2774
|
-
var
|
|
3035
|
+
var import_node_path5 = require("path");
|
|
2775
3036
|
function createRuntimeInjectionController(options, getConfig) {
|
|
2776
3037
|
return {
|
|
2777
3038
|
resolveId(importee) {
|
|
@@ -2788,7 +3049,7 @@ function createRuntimeInjectionController(options, getConfig) {
|
|
|
2788
3049
|
},
|
|
2789
3050
|
load(id) {
|
|
2790
3051
|
if (id === RESOLVED_VIRTUAL_RUNTIME_ID) {
|
|
2791
|
-
return createRuntimeModule();
|
|
3052
|
+
return createRuntimeModule(options, getConfig()?.root);
|
|
2792
3053
|
}
|
|
2793
3054
|
if (id === RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID) {
|
|
2794
3055
|
return createScreenshotConfigModule(options);
|
|
@@ -2831,14 +3092,17 @@ ${code}`;
|
|
|
2831
3092
|
}
|
|
2832
3093
|
};
|
|
2833
3094
|
}
|
|
2834
|
-
function createRuntimeModule() {
|
|
3095
|
+
function createRuntimeModule(options, root) {
|
|
2835
3096
|
return [
|
|
2836
3097
|
"import { setScreenshotModuleRegistry, setSnapdomLoader, startRuntimeClient } from '@xiaou66/vite-plugin-vue-mcp-next/runtime/client';",
|
|
2837
3098
|
`import { screenshotModuleRegistry } from '${VIRTUAL_SCREENSHOT_CONFIG_ID}';`,
|
|
2838
3099
|
`import { loadSnapdom } from '${VIRTUAL_SNAPDOM_LOADER_ID}';`,
|
|
2839
3100
|
"setScreenshotModuleRegistry(screenshotModuleRegistry);",
|
|
2840
3101
|
"setSnapdomLoader(loadSnapdom);",
|
|
2841
|
-
|
|
3102
|
+
`void startRuntimeClient(${JSON.stringify({
|
|
3103
|
+
elementPicker: options.elementPicker,
|
|
3104
|
+
projectRoot: root
|
|
3105
|
+
})});`
|
|
2842
3106
|
].join("\n");
|
|
2843
3107
|
}
|
|
2844
3108
|
function createSnapdomLoaderModule(root) {
|
|
@@ -2855,7 +3119,7 @@ function createSnapdomLoaderModule(root) {
|
|
|
2855
3119
|
}
|
|
2856
3120
|
function canResolveSnapdomFromProject(root) {
|
|
2857
3121
|
try {
|
|
2858
|
-
(0, import_node_module.createRequire)((0,
|
|
3122
|
+
(0, import_node_module.createRequire)((0, import_node_path5.join)(root ?? process.cwd(), "package.json")).resolve(
|
|
2859
3123
|
"@zumer/snapdom"
|
|
2860
3124
|
);
|
|
2861
3125
|
return true;
|
|
@@ -2895,16 +3159,16 @@ function getPluginPath(plugin) {
|
|
|
2895
3159
|
|
|
2896
3160
|
// src/plugin/mcpClientConfig/index.ts
|
|
2897
3161
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
2898
|
-
var
|
|
3162
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
2899
3163
|
|
|
2900
3164
|
// src/plugin/mcpClientConfig/codexConfig.ts
|
|
2901
3165
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
2902
|
-
var
|
|
3166
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
2903
3167
|
async function updateCodexMcpClientConfig(options) {
|
|
2904
3168
|
try {
|
|
2905
3169
|
const current = await readOptionalTextFile(options.configPath);
|
|
2906
3170
|
const next = replaceOrAppendOwnedBlock(current, options);
|
|
2907
|
-
await import_promises3.default.mkdir(
|
|
3171
|
+
await import_promises3.default.mkdir(import_node_path6.default.dirname(options.configPath), { recursive: true });
|
|
2908
3172
|
await import_promises3.default.writeFile(options.configPath, next);
|
|
2909
3173
|
} catch (error) {
|
|
2910
3174
|
console.warn(
|
|
@@ -3004,7 +3268,7 @@ function isNodeError(error) {
|
|
|
3004
3268
|
|
|
3005
3269
|
// src/plugin/mcpClientConfig/jsonConfig.ts
|
|
3006
3270
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
3007
|
-
var
|
|
3271
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
3008
3272
|
async function updateJsonMcpClientConfig(options) {
|
|
3009
3273
|
try {
|
|
3010
3274
|
const config = await readJsonConfig(options.configPath);
|
|
@@ -3044,7 +3308,7 @@ function renameLegacyServer(mcpServers, options) {
|
|
|
3044
3308
|
);
|
|
3045
3309
|
}
|
|
3046
3310
|
async function writeJsonConfig(configPath, config) {
|
|
3047
|
-
await import_promises4.default.mkdir(
|
|
3311
|
+
await import_promises4.default.mkdir(import_node_path7.default.dirname(configPath), { recursive: true });
|
|
3048
3312
|
await import_promises4.default.writeFile(configPath, `${JSON.stringify(config, null, 2)}
|
|
3049
3313
|
`);
|
|
3050
3314
|
}
|
|
@@ -3089,12 +3353,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
3089
3353
|
root,
|
|
3090
3354
|
clientName: "cursor",
|
|
3091
3355
|
enabled: options.cursor,
|
|
3092
|
-
entryPath:
|
|
3356
|
+
entryPath: import_node_path8.default.join(root, ".cursor"),
|
|
3093
3357
|
entryKind: "directory",
|
|
3094
3358
|
userOptions,
|
|
3095
3359
|
createJob: () => updateJsonMcpClientConfig({
|
|
3096
3360
|
clientName: "Cursor",
|
|
3097
|
-
configPath:
|
|
3361
|
+
configPath: import_node_path8.default.join(root, ".cursor", "mcp.json"),
|
|
3098
3362
|
mcpUrl: sseUrl,
|
|
3099
3363
|
serverName,
|
|
3100
3364
|
legacyServerNames
|
|
@@ -3104,11 +3368,11 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
3104
3368
|
root,
|
|
3105
3369
|
clientName: "codex",
|
|
3106
3370
|
enabled: options.codex,
|
|
3107
|
-
entryPath:
|
|
3371
|
+
entryPath: import_node_path8.default.join(root, ".codex"),
|
|
3108
3372
|
entryKind: "directory",
|
|
3109
3373
|
userOptions,
|
|
3110
3374
|
createJob: () => updateCodexMcpClientConfig({
|
|
3111
|
-
configPath:
|
|
3375
|
+
configPath: import_node_path8.default.join(root, ".codex", "config.toml"),
|
|
3112
3376
|
mcpUrl: streamableHttpUrl,
|
|
3113
3377
|
serverName,
|
|
3114
3378
|
legacyServerNames
|
|
@@ -3118,12 +3382,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
3118
3382
|
root,
|
|
3119
3383
|
clientName: "claudeCode",
|
|
3120
3384
|
enabled: options.claudeCode,
|
|
3121
|
-
entryPath:
|
|
3385
|
+
entryPath: import_node_path8.default.join(root, ".mcp.json"),
|
|
3122
3386
|
entryKind: "file",
|
|
3123
3387
|
userOptions,
|
|
3124
3388
|
createJob: () => updateJsonMcpClientConfig({
|
|
3125
3389
|
clientName: "Claude Code",
|
|
3126
|
-
configPath:
|
|
3390
|
+
configPath: import_node_path8.default.join(root, ".mcp.json"),
|
|
3127
3391
|
mcpUrl: sseUrl,
|
|
3128
3392
|
serverName,
|
|
3129
3393
|
legacyServerNames
|
|
@@ -3133,12 +3397,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
3133
3397
|
root,
|
|
3134
3398
|
clientName: "trae",
|
|
3135
3399
|
enabled: options.trae,
|
|
3136
|
-
entryPath:
|
|
3400
|
+
entryPath: import_node_path8.default.join(root, ".trae"),
|
|
3137
3401
|
entryKind: "directory",
|
|
3138
3402
|
userOptions,
|
|
3139
3403
|
createJob: () => updateJsonMcpClientConfig({
|
|
3140
3404
|
clientName: "Trae",
|
|
3141
|
-
configPath:
|
|
3405
|
+
configPath: import_node_path8.default.join(root, ".trae", "mcp.json"),
|
|
3142
3406
|
mcpUrl: sseUrl,
|
|
3143
3407
|
serverName,
|
|
3144
3408
|
legacyServerNames
|
|
@@ -3198,11 +3462,11 @@ function isNodeError3(error) {
|
|
|
3198
3462
|
|
|
3199
3463
|
// src/plugin/skillConfig/index.ts
|
|
3200
3464
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
3201
|
-
var
|
|
3465
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
3202
3466
|
|
|
3203
3467
|
// src/plugin/skillConfig/writers.ts
|
|
3204
3468
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
3205
|
-
var
|
|
3469
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
3206
3470
|
var GENERATED_SKILL_CONFIG_MARKER = "<!-- Generated by vite-plugin-vue-mcp-next. Safe to edit, but automatic updates only apply while this marker remains. -->";
|
|
3207
3471
|
async function writeGeneratedTextFile(options) {
|
|
3208
3472
|
try {
|
|
@@ -3213,7 +3477,7 @@ async function writeGeneratedTextFile(options) {
|
|
|
3213
3477
|
);
|
|
3214
3478
|
return;
|
|
3215
3479
|
}
|
|
3216
|
-
await import_promises6.default.mkdir(
|
|
3480
|
+
await import_promises6.default.mkdir(import_node_path9.default.dirname(options.filePath), { recursive: true });
|
|
3217
3481
|
await import_promises6.default.writeFile(options.filePath, options.content);
|
|
3218
3482
|
} catch (error) {
|
|
3219
3483
|
console.warn(
|
|
@@ -3240,7 +3504,7 @@ function isNodeError4(error) {
|
|
|
3240
3504
|
|
|
3241
3505
|
// src/plugin/skillConfig/index.ts
|
|
3242
3506
|
var PACKAGE_NAME = "@xiaou66/vite-plugin-vue-mcp-next";
|
|
3243
|
-
var PACKAGED_SKILL_PATH =
|
|
3507
|
+
var PACKAGED_SKILL_PATH = import_node_path10.default.join("skills", "vite-mcp-next", "SKILL.md");
|
|
3244
3508
|
async function updateSkillConfigs(root, options) {
|
|
3245
3509
|
if (!options.autoConfig) {
|
|
3246
3510
|
return;
|
|
@@ -3256,13 +3520,13 @@ async function updateSkillConfigs(root, options) {
|
|
|
3256
3520
|
function createSkillConfigDescriptors(root) {
|
|
3257
3521
|
return [
|
|
3258
3522
|
{
|
|
3259
|
-
entryPath:
|
|
3260
|
-
filePath:
|
|
3523
|
+
entryPath: import_node_path10.default.join(root, ".codex"),
|
|
3524
|
+
filePath: import_node_path10.default.join(root, ".codex", "skills", "vite-mcp-next", "SKILL.md"),
|
|
3261
3525
|
targetName: "Codex skill"
|
|
3262
3526
|
},
|
|
3263
3527
|
{
|
|
3264
|
-
entryPath:
|
|
3265
|
-
filePath:
|
|
3528
|
+
entryPath: import_node_path10.default.join(root, ".claude"),
|
|
3529
|
+
filePath: import_node_path10.default.join(
|
|
3266
3530
|
root,
|
|
3267
3531
|
".claude",
|
|
3268
3532
|
"skills",
|
|
@@ -3272,8 +3536,8 @@ function createSkillConfigDescriptors(root) {
|
|
|
3272
3536
|
targetName: "Claude Code skill"
|
|
3273
3537
|
},
|
|
3274
3538
|
{
|
|
3275
|
-
entryPath:
|
|
3276
|
-
filePath:
|
|
3539
|
+
entryPath: import_node_path10.default.join(root, ".cursor"),
|
|
3540
|
+
filePath: import_node_path10.default.join(root, ".cursor", "rules", "vite-mcp-next.mdc"),
|
|
3277
3541
|
targetName: "Cursor rule"
|
|
3278
3542
|
}
|
|
3279
3543
|
];
|
|
@@ -3321,9 +3585,9 @@ async function safelyReadPackagedSkillContent(root) {
|
|
|
3321
3585
|
}
|
|
3322
3586
|
function getPackagedSkillCandidates(root) {
|
|
3323
3587
|
return [
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3588
|
+
import_node_path10.default.resolve(root, "node_modules", PACKAGE_NAME, PACKAGED_SKILL_PATH),
|
|
3589
|
+
import_node_path10.default.resolve(process.cwd(), "node_modules", PACKAGE_NAME, PACKAGED_SKILL_PATH),
|
|
3590
|
+
import_node_path10.default.resolve(process.cwd(), PACKAGED_SKILL_PATH)
|
|
3327
3591
|
];
|
|
3328
3592
|
}
|
|
3329
3593
|
async function hasDirectoryEntry(entryPath) {
|
|
@@ -3357,6 +3621,7 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3357
3621
|
options,
|
|
3358
3622
|
() => config
|
|
3359
3623
|
);
|
|
3624
|
+
let elementInstrumentation;
|
|
3360
3625
|
const cdpLifecycle = createCdpLifecycleController(ctx);
|
|
3361
3626
|
ctx.cdpLifecycle = cdpLifecycle;
|
|
3362
3627
|
return {
|
|
@@ -3365,6 +3630,9 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3365
3630
|
apply: "serve",
|
|
3366
3631
|
configResolved(resolvedConfig) {
|
|
3367
3632
|
config = resolvedConfig;
|
|
3633
|
+
elementInstrumentation = createElementInstrumentationController({
|
|
3634
|
+
root: resolvedConfig.root
|
|
3635
|
+
});
|
|
3368
3636
|
},
|
|
3369
3637
|
async configureServer(server) {
|
|
3370
3638
|
ctx.server = server;
|
|
@@ -3381,32 +3649,53 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3381
3649
|
() => createMcpServer(ctx, server),
|
|
3382
3650
|
server
|
|
3383
3651
|
);
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
(
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3652
|
+
const lastSeenAt = /* @__PURE__ */ new Map();
|
|
3653
|
+
const heartbeatTimer = setInterval(() => {
|
|
3654
|
+
const now = Date.now();
|
|
3655
|
+
for (const [pageId, seenAt] of lastSeenAt) {
|
|
3656
|
+
const target = ctx.pages.get(pageId);
|
|
3657
|
+
if (!target || target.source !== "runtime" || !target.connected) {
|
|
3658
|
+
lastSeenAt.delete(pageId);
|
|
3659
|
+
continue;
|
|
3391
3660
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
"vite-plugin-vue-mcp-next:console-record",
|
|
3396
|
-
(payload) => {
|
|
3397
|
-
if (isConsoleRecord(payload)) {
|
|
3398
|
-
ctx.consoleRecords.push(payload);
|
|
3661
|
+
if (now - seenAt >= DEFAULT_RUNTIME_PAGE_HEARTBEAT_TIMEOUT_MS) {
|
|
3662
|
+
ctx.pages.disconnect(pageId, now);
|
|
3663
|
+
lastSeenAt.delete(pageId);
|
|
3399
3664
|
}
|
|
3400
3665
|
}
|
|
3401
|
-
);
|
|
3402
|
-
server.ws.on(
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3666
|
+
}, DEFAULT_RUNTIME_PAGE_HEARTBEAT_SCAN_INTERVAL_MS);
|
|
3667
|
+
server.ws.on(RUNTIME_PAGE_CONNECTED_EVENT, (payload) => {
|
|
3668
|
+
if (isRuntimePageTarget(payload)) {
|
|
3669
|
+
ctx.pages.upsert(payload);
|
|
3670
|
+
lastSeenAt.set(payload.pageId, Date.now());
|
|
3671
|
+
void ctx.hooks.callHook(RUNTIME_PAGE_RECONNECTED_EVENT, payload);
|
|
3672
|
+
void cdpLifecycle.connectPage(payload);
|
|
3673
|
+
}
|
|
3674
|
+
});
|
|
3675
|
+
server.ws.on(RUNTIME_PAGE_HEARTBEAT_EVENT, (payload) => {
|
|
3676
|
+
if (isRuntimeHeartbeatTarget(payload)) {
|
|
3677
|
+
const target = ctx.pages.get(payload.pageId);
|
|
3678
|
+
if (target?.source === "runtime" && target.connected) {
|
|
3679
|
+
lastSeenAt.set(payload.pageId, payload.timestamp);
|
|
3407
3680
|
}
|
|
3408
3681
|
}
|
|
3409
|
-
);
|
|
3682
|
+
});
|
|
3683
|
+
server.ws.on(RUNTIME_PAGE_DISCONNECTED_EVENT, (payload) => {
|
|
3684
|
+
if (isRuntimeDisconnectTarget(payload)) {
|
|
3685
|
+
ctx.pages.disconnect(payload.pageId);
|
|
3686
|
+
lastSeenAt.delete(payload.pageId);
|
|
3687
|
+
}
|
|
3688
|
+
});
|
|
3689
|
+
server.ws.on("vite-plugin-vue-mcp-next:console-record", (payload) => {
|
|
3690
|
+
if (isConsoleRecord(payload)) {
|
|
3691
|
+
ctx.consoleRecords.push(payload);
|
|
3692
|
+
}
|
|
3693
|
+
});
|
|
3694
|
+
server.ws.on("vite-plugin-vue-mcp-next:network-record", (payload) => {
|
|
3695
|
+
if (isNetworkRecord(payload)) {
|
|
3696
|
+
ctx.networkRecords.push(payload);
|
|
3697
|
+
}
|
|
3698
|
+
});
|
|
3410
3699
|
server.ws.on(
|
|
3411
3700
|
"vite-plugin-vue-mcp-next:performance-record",
|
|
3412
3701
|
(payload) => {
|
|
@@ -3436,6 +3725,7 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3436
3725
|
}, 300);
|
|
3437
3726
|
}
|
|
3438
3727
|
server.httpServer?.once("close", () => {
|
|
3728
|
+
clearInterval(heartbeatTimer);
|
|
3439
3729
|
void cdpLifecycle.closeAll();
|
|
3440
3730
|
});
|
|
3441
3731
|
},
|
|
@@ -3446,7 +3736,21 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3446
3736
|
return runtimeInjection.load(id);
|
|
3447
3737
|
},
|
|
3448
3738
|
transform(code, id, transformOptions) {
|
|
3449
|
-
|
|
3739
|
+
const instrumented = elementInstrumentation?.transform(
|
|
3740
|
+
code,
|
|
3741
|
+
id,
|
|
3742
|
+
transformOptions?.ssr
|
|
3743
|
+
);
|
|
3744
|
+
const nextCode = instrumented && typeof instrumented === "object" && "code" in instrumented && typeof instrumented.code === "string" ? instrumented.code : code;
|
|
3745
|
+
const runtimeInjected = runtimeInjection.transform(
|
|
3746
|
+
nextCode,
|
|
3747
|
+
id,
|
|
3748
|
+
transformOptions?.ssr
|
|
3749
|
+
);
|
|
3750
|
+
if (runtimeInjected) {
|
|
3751
|
+
return runtimeInjected;
|
|
3752
|
+
}
|
|
3753
|
+
return instrumented;
|
|
3450
3754
|
},
|
|
3451
3755
|
transformIndexHtml(html) {
|
|
3452
3756
|
return runtimeInjection.transformIndexHtml(html);
|
|
@@ -3460,6 +3764,20 @@ function isRuntimePageTarget(payload) {
|
|
|
3460
3764
|
const target = payload;
|
|
3461
3765
|
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");
|
|
3462
3766
|
}
|
|
3767
|
+
function isRuntimeHeartbeatTarget(payload) {
|
|
3768
|
+
if (!payload || typeof payload !== "object") {
|
|
3769
|
+
return false;
|
|
3770
|
+
}
|
|
3771
|
+
const target = payload;
|
|
3772
|
+
return typeof target.pageId === "string" && typeof target.timestamp === "number";
|
|
3773
|
+
}
|
|
3774
|
+
function isRuntimeDisconnectTarget(payload) {
|
|
3775
|
+
if (!payload || typeof payload !== "object") {
|
|
3776
|
+
return false;
|
|
3777
|
+
}
|
|
3778
|
+
const target = payload;
|
|
3779
|
+
return typeof target.pageId === "string";
|
|
3780
|
+
}
|
|
3463
3781
|
function isConsoleRecord(payload) {
|
|
3464
3782
|
if (!payload || typeof payload !== "object") {
|
|
3465
3783
|
return false;
|