@xiaou66/vite-plugin-vue-mcp-next 1.1.1 → 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 +61 -0
- package/dist/index.cjs +791 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -849
- package/dist/index.d.ts +5 -849
- package/dist/index.js +763 -54
- package/dist/index.js.map +1 -1
- package/dist/runtime/client.cjs +934 -81
- 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 +934 -81
- 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 +14 -6
package/dist/index.cjs
CHANGED
|
@@ -72,6 +72,11 @@ var MCP_TOOL_NAMES = {
|
|
|
72
72
|
getNetworkRequests: "get_network_requests",
|
|
73
73
|
getNetworkRequestDetail: "get_network_request_detail",
|
|
74
74
|
clearNetworkRequests: "clear_network_requests",
|
|
75
|
+
listStorage: "list_storage",
|
|
76
|
+
getStorageItem: "get_storage_item",
|
|
77
|
+
setStorageItem: "set_storage_item",
|
|
78
|
+
deleteStorageItem: "delete_storage_item",
|
|
79
|
+
clearStorage: "clear_storage",
|
|
75
80
|
recordPerformance: "record_performance",
|
|
76
81
|
startPerformanceRecording: "start_performance_recording",
|
|
77
82
|
stopPerformanceRecording: "stop_performance_recording",
|
|
@@ -83,7 +88,8 @@ var MCP_TOOL_NAMES = {
|
|
|
83
88
|
highlightComponent: "highlight_component",
|
|
84
89
|
getRouterInfo: "get_router_info",
|
|
85
90
|
getPiniaTree: "get_pinia_tree",
|
|
86
|
-
getPiniaState: "get_pinia_state"
|
|
91
|
+
getPiniaState: "get_pinia_state",
|
|
92
|
+
getElementContext: "get_element_context"
|
|
87
93
|
};
|
|
88
94
|
var VIRTUAL_RUNTIME_ID = "virtual:vite-plugin-vue-mcp-next/runtime";
|
|
89
95
|
var RESOLVED_VIRTUAL_RUNTIME_ID = `\0${VIRTUAL_RUNTIME_ID}`;
|
|
@@ -99,6 +105,7 @@ var RUNTIME_PAGE_DISCONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-disconnecte
|
|
|
99
105
|
var RUNTIME_PAGE_HEARTBEAT_EVENT = "vite-plugin-vue-mcp-next:heartbeat";
|
|
100
106
|
var DEFAULT_RUNTIME_PAGE_HEARTBEAT_TIMEOUT_MS = 45e3;
|
|
101
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) => {
|
|
@@ -1548,8 +1728,430 @@ function getPathname(url) {
|
|
|
1548
1728
|
}
|
|
1549
1729
|
}
|
|
1550
1730
|
|
|
1731
|
+
// src/mcp/tools/storage.ts
|
|
1732
|
+
var import_zod8 = require("zod");
|
|
1733
|
+
|
|
1734
|
+
// src/cdp/cdpStorage.ts
|
|
1735
|
+
function createCdpStorageAdapter(client) {
|
|
1736
|
+
return {
|
|
1737
|
+
async manageStorage(request) {
|
|
1738
|
+
try {
|
|
1739
|
+
return await manageCdpStorage(client, request);
|
|
1740
|
+
} catch (error) {
|
|
1741
|
+
return createCdpStorageError(
|
|
1742
|
+
request,
|
|
1743
|
+
error instanceof Error ? error.message : String(error)
|
|
1744
|
+
);
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1749
|
+
async function manageCdpStorage(client, request) {
|
|
1750
|
+
if (request.scope === "cookie") {
|
|
1751
|
+
return manageCdpCookies(client, request);
|
|
1752
|
+
}
|
|
1753
|
+
if (request.scope === "indexedDB") {
|
|
1754
|
+
return manageCdpIndexedDb(client, request);
|
|
1755
|
+
}
|
|
1756
|
+
return manageCdpDomStorage(client, request);
|
|
1757
|
+
}
|
|
1758
|
+
async function manageCdpCookies(client, request) {
|
|
1759
|
+
if (request.action === "list" || request.action === "get") {
|
|
1760
|
+
const result2 = await client.Storage.getCookies();
|
|
1761
|
+
const cookies2 = result2.cookies.filter(
|
|
1762
|
+
(cookie) => isCookieInOrigin(cookie, request.origin)
|
|
1763
|
+
);
|
|
1764
|
+
return createCdpStorageSuccess(request, {
|
|
1765
|
+
origin: request.origin,
|
|
1766
|
+
cookies: request.action === "get" && request.cookie?.name ? cookies2.filter((cookie) => cookie.name === request.cookie?.name) : cookies2
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
if (request.action === "set") {
|
|
1770
|
+
if (!request.cookie?.name) {
|
|
1771
|
+
throw new Error("Cookie name is required for set operation");
|
|
1772
|
+
}
|
|
1773
|
+
await client.Storage.setCookies({
|
|
1774
|
+
cookies: [
|
|
1775
|
+
{
|
|
1776
|
+
name: request.cookie.name,
|
|
1777
|
+
value: request.cookie.value ?? request.value ?? "",
|
|
1778
|
+
url: request.cookie.url ?? request.origin,
|
|
1779
|
+
domain: request.cookie.domain,
|
|
1780
|
+
path: request.cookie.path,
|
|
1781
|
+
httpOnly: request.cookie.httpOnly,
|
|
1782
|
+
secure: request.cookie.secure,
|
|
1783
|
+
sameSite: normalizeCookieSameSite(request.cookie.sameSite),
|
|
1784
|
+
expires: request.cookie.expires
|
|
1785
|
+
}
|
|
1786
|
+
]
|
|
1787
|
+
});
|
|
1788
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1789
|
+
}
|
|
1790
|
+
const result = await client.Storage.getCookies();
|
|
1791
|
+
const cookies = result.cookies.filter(
|
|
1792
|
+
(cookie) => isCookieInOrigin(cookie, request.origin)
|
|
1793
|
+
);
|
|
1794
|
+
const candidates = request.action === "delete" && request.cookie?.name ? cookies.filter((cookie) => cookie.name === request.cookie?.name) : cookies;
|
|
1795
|
+
const deletable = candidates.filter((cookie) => !cookie.httpOnly);
|
|
1796
|
+
const skippedHttpOnlyCount = candidates.length - deletable.length;
|
|
1797
|
+
for (const cookie of deletable) {
|
|
1798
|
+
await client.Network.deleteCookies({
|
|
1799
|
+
name: cookie.name,
|
|
1800
|
+
domain: cookie.domain,
|
|
1801
|
+
path: cookie.path
|
|
1802
|
+
});
|
|
1803
|
+
}
|
|
1804
|
+
return createCdpStorageSuccess(request, {
|
|
1805
|
+
deletedCount: deletable.length,
|
|
1806
|
+
skippedHttpOnlyCount
|
|
1807
|
+
});
|
|
1808
|
+
}
|
|
1809
|
+
async function manageCdpDomStorage(client, request) {
|
|
1810
|
+
const storageId = {
|
|
1811
|
+
securityOrigin: request.origin,
|
|
1812
|
+
isLocalStorage: request.scope === "localStorage"
|
|
1813
|
+
};
|
|
1814
|
+
if (request.action === "list") {
|
|
1815
|
+
const result2 = await client.DOMStorage.getDOMStorageItems({ storageId });
|
|
1816
|
+
return createCdpStorageSuccess(request, {
|
|
1817
|
+
origin: request.origin,
|
|
1818
|
+
scope: request.scope,
|
|
1819
|
+
entries: result2.entries.map(([key, value]) => ({ key, value }))
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
if (request.action === "get") {
|
|
1823
|
+
assertStorageKey(request);
|
|
1824
|
+
const result2 = await client.DOMStorage.getDOMStorageItems({ storageId });
|
|
1825
|
+
const entry = result2.entries.find(([key]) => key === request.key);
|
|
1826
|
+
return createCdpStorageSuccess(request, {
|
|
1827
|
+
key: request.key,
|
|
1828
|
+
value: entry?.[1] ?? null
|
|
1829
|
+
});
|
|
1830
|
+
}
|
|
1831
|
+
if (request.action === "set") {
|
|
1832
|
+
assertStorageKey(request);
|
|
1833
|
+
await client.DOMStorage.setDOMStorageItem({
|
|
1834
|
+
storageId,
|
|
1835
|
+
key: request.key,
|
|
1836
|
+
value: request.value ?? ""
|
|
1837
|
+
});
|
|
1838
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1839
|
+
}
|
|
1840
|
+
if (request.action === "delete") {
|
|
1841
|
+
assertStorageKey(request);
|
|
1842
|
+
await client.DOMStorage.removeDOMStorageItem({
|
|
1843
|
+
storageId,
|
|
1844
|
+
key: request.key
|
|
1845
|
+
});
|
|
1846
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1847
|
+
}
|
|
1848
|
+
const result = await client.DOMStorage.getDOMStorageItems({ storageId });
|
|
1849
|
+
for (const [key] of result.entries) {
|
|
1850
|
+
await client.DOMStorage.removeDOMStorageItem({ storageId, key });
|
|
1851
|
+
}
|
|
1852
|
+
return createCdpStorageSuccess(request, { deletedCount: result.entries.length });
|
|
1853
|
+
}
|
|
1854
|
+
async function manageCdpIndexedDb(client, request) {
|
|
1855
|
+
if (request.action === "list") {
|
|
1856
|
+
const result = await client.IndexedDB.requestDatabaseNames({
|
|
1857
|
+
securityOrigin: request.origin
|
|
1858
|
+
});
|
|
1859
|
+
return createCdpStorageSuccess(request, {
|
|
1860
|
+
origin: request.origin,
|
|
1861
|
+
databases: result.databaseNames
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
assertIndexedDbTarget(request);
|
|
1865
|
+
if (request.action === "get") {
|
|
1866
|
+
const result = await client.IndexedDB.requestData({
|
|
1867
|
+
securityOrigin: request.origin,
|
|
1868
|
+
databaseName: request.databaseName,
|
|
1869
|
+
objectStoreName: request.objectStoreName,
|
|
1870
|
+
indexName: request.indexName ?? "",
|
|
1871
|
+
skipCount: 0,
|
|
1872
|
+
pageSize: 100
|
|
1873
|
+
});
|
|
1874
|
+
return createCdpStorageSuccess(request, {
|
|
1875
|
+
entries: result.objectStoreDataEntries,
|
|
1876
|
+
hasMore: result.hasMore
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
if (request.action === "delete") {
|
|
1880
|
+
assertStorageKey(request);
|
|
1881
|
+
await client.IndexedDB.deleteObjectStoreEntries({
|
|
1882
|
+
securityOrigin: request.origin,
|
|
1883
|
+
databaseName: request.databaseName,
|
|
1884
|
+
objectStoreName: request.objectStoreName,
|
|
1885
|
+
keyRange: createExactCdpKeyRange(request.key)
|
|
1886
|
+
});
|
|
1887
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1888
|
+
}
|
|
1889
|
+
if (request.action === "clear") {
|
|
1890
|
+
if (request.objectStoreName) {
|
|
1891
|
+
await client.IndexedDB.clearObjectStore({
|
|
1892
|
+
securityOrigin: request.origin,
|
|
1893
|
+
databaseName: request.databaseName,
|
|
1894
|
+
objectStoreName: request.objectStoreName
|
|
1895
|
+
});
|
|
1896
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1897
|
+
}
|
|
1898
|
+
await client.IndexedDB.deleteDatabase({
|
|
1899
|
+
securityOrigin: request.origin,
|
|
1900
|
+
databaseName: request.databaseName
|
|
1901
|
+
});
|
|
1902
|
+
return createCdpStorageSuccess(request, { ok: true });
|
|
1903
|
+
}
|
|
1904
|
+
return createCdpStorageError(
|
|
1905
|
+
request,
|
|
1906
|
+
"IndexedDB set operation requires runtime bridge"
|
|
1907
|
+
);
|
|
1908
|
+
}
|
|
1909
|
+
function isCookieInOrigin(cookie, origin) {
|
|
1910
|
+
const hostname = new URL(origin).hostname;
|
|
1911
|
+
const domain = cookie.domain?.replace(/^\./, "");
|
|
1912
|
+
return Boolean(domain && (hostname === domain || hostname.endsWith(`.${domain}`)));
|
|
1913
|
+
}
|
|
1914
|
+
function normalizeCookieSameSite(sameSite) {
|
|
1915
|
+
if (!sameSite) {
|
|
1916
|
+
return void 0;
|
|
1917
|
+
}
|
|
1918
|
+
if (sameSite === "strict") {
|
|
1919
|
+
return "Strict";
|
|
1920
|
+
}
|
|
1921
|
+
if (sameSite === "lax") {
|
|
1922
|
+
return "Lax";
|
|
1923
|
+
}
|
|
1924
|
+
return "None";
|
|
1925
|
+
}
|
|
1926
|
+
function createExactCdpKeyRange(key) {
|
|
1927
|
+
const parsedKey = parseJsonValue(key);
|
|
1928
|
+
return {
|
|
1929
|
+
lower: parsedKey,
|
|
1930
|
+
upper: parsedKey,
|
|
1931
|
+
lowerOpen: false,
|
|
1932
|
+
upperOpen: false
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1935
|
+
function parseJsonValue(value) {
|
|
1936
|
+
try {
|
|
1937
|
+
return JSON.parse(value);
|
|
1938
|
+
} catch {
|
|
1939
|
+
return value;
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
function assertStorageKey(request) {
|
|
1943
|
+
if (!request.key) {
|
|
1944
|
+
throw new Error("Storage key is required for this operation");
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
function assertIndexedDbTarget(request) {
|
|
1948
|
+
if (!request.databaseName || !request.objectStoreName) {
|
|
1949
|
+
throw new Error("IndexedDB databaseName and objectStoreName are required");
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
function createCdpStorageSuccess(request, data) {
|
|
1953
|
+
return {
|
|
1954
|
+
ok: true,
|
|
1955
|
+
source: "cdp",
|
|
1956
|
+
action: request.action,
|
|
1957
|
+
scope: request.scope,
|
|
1958
|
+
data
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
function createCdpStorageError(request, error) {
|
|
1962
|
+
return {
|
|
1963
|
+
ok: false,
|
|
1964
|
+
source: "cdp",
|
|
1965
|
+
action: request.action,
|
|
1966
|
+
scope: request.scope,
|
|
1967
|
+
error
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// src/mcp/tools/storage.ts
|
|
1972
|
+
function registerStorageTools(server, ctx) {
|
|
1973
|
+
registerStorageTool(server, MCP_TOOL_NAMES.listStorage, {
|
|
1974
|
+
description: "List same-origin storage and CDP cookies when available.",
|
|
1975
|
+
inputSchema: {
|
|
1976
|
+
pageId: import_zod8.z.string().optional()
|
|
1977
|
+
},
|
|
1978
|
+
action: "list",
|
|
1979
|
+
handler: (input) => handleListStorage(ctx, input.pageId)
|
|
1980
|
+
});
|
|
1981
|
+
registerStorageTool(server, MCP_TOOL_NAMES.getStorageItem, {
|
|
1982
|
+
description: "Read one storage entry.",
|
|
1983
|
+
inputSchema: createStorageInputSchema(),
|
|
1984
|
+
action: "get",
|
|
1985
|
+
handler: (input) => handleStorageAction(ctx, { ...input, action: "get" })
|
|
1986
|
+
});
|
|
1987
|
+
registerStorageTool(server, MCP_TOOL_NAMES.setStorageItem, {
|
|
1988
|
+
description: "Write one storage entry.",
|
|
1989
|
+
inputSchema: createStorageInputSchema(),
|
|
1990
|
+
action: "set",
|
|
1991
|
+
handler: (input) => handleStorageAction(ctx, { ...input, action: "set" })
|
|
1992
|
+
});
|
|
1993
|
+
registerStorageTool(server, MCP_TOOL_NAMES.deleteStorageItem, {
|
|
1994
|
+
description: "Delete one storage entry.",
|
|
1995
|
+
inputSchema: createStorageInputSchema(),
|
|
1996
|
+
action: "delete",
|
|
1997
|
+
handler: (input) => handleStorageAction(ctx, { ...input, action: "delete" })
|
|
1998
|
+
});
|
|
1999
|
+
registerStorageTool(server, MCP_TOOL_NAMES.clearStorage, {
|
|
2000
|
+
description: "Clear one storage scope.",
|
|
2001
|
+
inputSchema: createStorageInputSchema(),
|
|
2002
|
+
action: "clear",
|
|
2003
|
+
handler: (input) => handleStorageAction(ctx, { ...input, action: "clear" })
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2006
|
+
function registerStorageTool(server, name, options) {
|
|
2007
|
+
server.registerTool(
|
|
2008
|
+
name,
|
|
2009
|
+
{
|
|
2010
|
+
description: options.description,
|
|
2011
|
+
inputSchema: options.inputSchema
|
|
2012
|
+
},
|
|
2013
|
+
(async (input) => options.handler(
|
|
2014
|
+
input
|
|
2015
|
+
))
|
|
2016
|
+
);
|
|
2017
|
+
}
|
|
2018
|
+
function createStorageInputSchema() {
|
|
2019
|
+
return {
|
|
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()
|
|
2037
|
+
}).optional()
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
async function handleListStorage(ctx, pageId) {
|
|
2041
|
+
let baseRequest;
|
|
2042
|
+
try {
|
|
2043
|
+
baseRequest = createStorageRequest(ctx, {
|
|
2044
|
+
pageId,
|
|
2045
|
+
action: "list",
|
|
2046
|
+
scope: "localStorage"
|
|
2047
|
+
});
|
|
2048
|
+
} catch (error) {
|
|
2049
|
+
return createToolError(error instanceof Error ? error.message : String(error));
|
|
2050
|
+
}
|
|
2051
|
+
const [localStorage, sessionStorage, indexedDB] = await Promise.all([
|
|
2052
|
+
requestRuntimeStorage(ctx, { ...baseRequest, scope: "localStorage" }),
|
|
2053
|
+
requestRuntimeStorage(ctx, { ...baseRequest, scope: "sessionStorage" }),
|
|
2054
|
+
requestRuntimeStorage(ctx, { ...baseRequest, scope: "indexedDB" })
|
|
2055
|
+
]);
|
|
2056
|
+
const cookie = await listCookiesIfCdpAvailable(ctx, baseRequest, pageId);
|
|
2057
|
+
return createToolResponse({
|
|
2058
|
+
ok: true,
|
|
2059
|
+
origin: baseRequest.origin,
|
|
2060
|
+
localStorage: extractStorageData(localStorage),
|
|
2061
|
+
sessionStorage: extractStorageData(sessionStorage),
|
|
2062
|
+
indexedDB: extractStorageData(indexedDB),
|
|
2063
|
+
cookie
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
async function handleStorageAction(ctx, input) {
|
|
2067
|
+
let request;
|
|
2068
|
+
try {
|
|
2069
|
+
request = createStorageRequest(ctx, input);
|
|
2070
|
+
} catch (error) {
|
|
2071
|
+
return createToolError(error instanceof Error ? error.message : String(error));
|
|
2072
|
+
}
|
|
2073
|
+
const cdp = await connectCdpForPage(ctx, input.pageId);
|
|
2074
|
+
if (cdp && shouldUseCdpStorage(request)) {
|
|
2075
|
+
try {
|
|
2076
|
+
const result2 = await createCdpStorageAdapter(cdp.client).manageStorage(
|
|
2077
|
+
request
|
|
2078
|
+
);
|
|
2079
|
+
return createToolResponse(result2);
|
|
2080
|
+
} finally {
|
|
2081
|
+
await closeCdpClient(cdp.client);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
const result = await requestRuntimeStorage(ctx, request);
|
|
2085
|
+
return createToolResponse(result);
|
|
2086
|
+
}
|
|
2087
|
+
async function requestRuntimeStorage(ctx, request) {
|
|
2088
|
+
return requestRuntimeData(ctx, (event) => {
|
|
2089
|
+
void ctx.rpcServer?.manageStorage({
|
|
2090
|
+
...request,
|
|
2091
|
+
event
|
|
2092
|
+
});
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
async function listCookiesIfCdpAvailable(ctx, request, pageId) {
|
|
2096
|
+
if (!hasCdpConfig2(ctx)) {
|
|
2097
|
+
return extractStorageData(
|
|
2098
|
+
await requestRuntimeStorage(ctx, { ...request, scope: "cookie" })
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
2101
|
+
const cdp = await connectCdpForPage(ctx, pageId);
|
|
2102
|
+
if (!cdp) {
|
|
2103
|
+
return extractStorageData(
|
|
2104
|
+
await requestRuntimeStorage(ctx, { ...request, scope: "cookie" })
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
try {
|
|
2108
|
+
const result = await createCdpStorageAdapter(cdp.client).manageStorage({
|
|
2109
|
+
...request,
|
|
2110
|
+
scope: "cookie"
|
|
2111
|
+
});
|
|
2112
|
+
return extractStorageData(result);
|
|
2113
|
+
} finally {
|
|
2114
|
+
await closeCdpClient(cdp.client);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
function extractStorageData(result) {
|
|
2118
|
+
if (!isStorageResultRecord(result)) {
|
|
2119
|
+
return result;
|
|
2120
|
+
}
|
|
2121
|
+
return result.data ?? result;
|
|
2122
|
+
}
|
|
2123
|
+
function isStorageResultRecord(value) {
|
|
2124
|
+
return typeof value === "object" && value !== null && "ok" in value;
|
|
2125
|
+
}
|
|
2126
|
+
function shouldUseCdpStorage(request) {
|
|
2127
|
+
return request.scope === "cookie";
|
|
2128
|
+
}
|
|
2129
|
+
function createStorageRequest(ctx, input) {
|
|
2130
|
+
const page = resolvePageTarget(ctx, input.pageId);
|
|
2131
|
+
const origin = new URL(page.url).origin;
|
|
2132
|
+
return {
|
|
2133
|
+
event: "",
|
|
2134
|
+
pageId: page.pageId,
|
|
2135
|
+
origin,
|
|
2136
|
+
action: input.action,
|
|
2137
|
+
scope: normalizeScope(input.scope),
|
|
2138
|
+
key: input.key,
|
|
2139
|
+
value: input.value,
|
|
2140
|
+
databaseName: input.databaseName,
|
|
2141
|
+
objectStoreName: input.objectStoreName,
|
|
2142
|
+
indexName: input.indexName,
|
|
2143
|
+
cookie: input.cookie
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
function normalizeScope(scope) {
|
|
2147
|
+
return scope ?? "localStorage";
|
|
2148
|
+
}
|
|
2149
|
+
function hasCdpConfig2(ctx) {
|
|
2150
|
+
return Boolean(ctx.options.cdp.browserUrl || ctx.options.cdp.wsEndpoint);
|
|
2151
|
+
}
|
|
2152
|
+
|
|
1551
2153
|
// src/mcp/tools/screenshot.ts
|
|
1552
|
-
var
|
|
2154
|
+
var import_zod9 = require("zod");
|
|
1553
2155
|
|
|
1554
2156
|
// src/cdp/cdpScreenshot.ts
|
|
1555
2157
|
async function cdpCaptureScreenshot(options) {
|
|
@@ -1709,14 +2311,14 @@ function createProjectRelativePath(ctx, filePath) {
|
|
|
1709
2311
|
var DEFAULT_SCREENSHOT_TARGET = "viewport";
|
|
1710
2312
|
var DEFAULT_SCREENSHOT_FORMAT = "png";
|
|
1711
2313
|
var screenshotInputSchema = {
|
|
1712
|
-
pageId:
|
|
1713
|
-
target:
|
|
1714
|
-
selector:
|
|
1715
|
-
format:
|
|
1716
|
-
prefer:
|
|
1717
|
-
quality:
|
|
1718
|
-
scale:
|
|
1719
|
-
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()
|
|
1720
2322
|
};
|
|
1721
2323
|
function registerScreenshotTools(server, ctx) {
|
|
1722
2324
|
server.registerTool(
|
|
@@ -1836,7 +2438,7 @@ function isScreenshotImagePayload(result) {
|
|
|
1836
2438
|
|
|
1837
2439
|
// src/mcp/tools/vue.ts
|
|
1838
2440
|
var import_nanoid3 = require("nanoid");
|
|
1839
|
-
var
|
|
2441
|
+
var import_zod10 = require("zod");
|
|
1840
2442
|
function registerVueTools(server, ctx) {
|
|
1841
2443
|
server.registerTool(
|
|
1842
2444
|
MCP_TOOL_NAMES.getComponentTree,
|
|
@@ -1849,7 +2451,7 @@ function registerVueTools(server, ctx) {
|
|
|
1849
2451
|
MCP_TOOL_NAMES.getComponentState,
|
|
1850
2452
|
{
|
|
1851
2453
|
description: "Get Vue component state.",
|
|
1852
|
-
inputSchema: { componentName:
|
|
2454
|
+
inputSchema: { componentName: import_zod10.z.string() }
|
|
1853
2455
|
},
|
|
1854
2456
|
async ({ componentName }) => requestVueData(ctx, (event) => {
|
|
1855
2457
|
void ctx.rpcServer?.getInspectorState({ event, componentName });
|
|
@@ -1860,10 +2462,10 @@ function registerVueTools(server, ctx) {
|
|
|
1860
2462
|
{
|
|
1861
2463
|
description: "Edit Vue component state.",
|
|
1862
2464
|
inputSchema: {
|
|
1863
|
-
componentName:
|
|
1864
|
-
path:
|
|
1865
|
-
value:
|
|
1866
|
-
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"])
|
|
1867
2469
|
}
|
|
1868
2470
|
},
|
|
1869
2471
|
({ componentName, path: path8, value, valueType }) => {
|
|
@@ -1883,7 +2485,7 @@ function registerVueTools(server, ctx) {
|
|
|
1883
2485
|
MCP_TOOL_NAMES.highlightComponent,
|
|
1884
2486
|
{
|
|
1885
2487
|
description: "Highlight a Vue component.",
|
|
1886
|
-
inputSchema: { componentName:
|
|
2488
|
+
inputSchema: { componentName: import_zod10.z.string() }
|
|
1887
2489
|
},
|
|
1888
2490
|
({ componentName }) => {
|
|
1889
2491
|
if (!ctx.rpcServer) {
|
|
@@ -1911,7 +2513,7 @@ function registerVueTools(server, ctx) {
|
|
|
1911
2513
|
MCP_TOOL_NAMES.getPiniaState,
|
|
1912
2514
|
{
|
|
1913
2515
|
description: "Get Pinia store state.",
|
|
1914
|
-
inputSchema: { storeName:
|
|
2516
|
+
inputSchema: { storeName: import_zod10.z.string() }
|
|
1915
2517
|
},
|
|
1916
2518
|
async ({ storeName }) => requestVueData(ctx, (event) => {
|
|
1917
2519
|
void ctx.rpcServer?.getPiniaState({ event, storeName });
|
|
@@ -1954,10 +2556,12 @@ function createMcpServer(ctx, vite) {
|
|
|
1954
2556
|
});
|
|
1955
2557
|
registerPageTools(server, ctx, vite);
|
|
1956
2558
|
registerDomTools(server, ctx);
|
|
2559
|
+
registerElementContextTools(server, ctx);
|
|
1957
2560
|
registerScreenshotTools(server, ctx);
|
|
1958
2561
|
registerConsoleTools(server, ctx);
|
|
1959
2562
|
registerEvaluateTools(server, ctx);
|
|
1960
2563
|
registerNetworkTools(server, ctx);
|
|
2564
|
+
registerStorageTools(server, ctx);
|
|
1961
2565
|
registerPerformanceTools(server, ctx);
|
|
1962
2566
|
registerVueTools(server, ctx);
|
|
1963
2567
|
return server;
|
|
@@ -2034,6 +2638,10 @@ function createServerVueRuntimeRpc(ctx) {
|
|
|
2034
2638
|
onDomQueryUpdated: (event, data) => {
|
|
2035
2639
|
void ctx.hooks.callHook(event, data);
|
|
2036
2640
|
},
|
|
2641
|
+
getElementContext: () => void 0,
|
|
2642
|
+
onElementContextUpdated: (event, data) => {
|
|
2643
|
+
void ctx.hooks.callHook(event, data);
|
|
2644
|
+
},
|
|
2037
2645
|
reloadPage: () => void 0,
|
|
2038
2646
|
onPageReloaded: (event, data) => {
|
|
2039
2647
|
void ctx.hooks.callHook(event, data);
|
|
@@ -2046,6 +2654,10 @@ function createServerVueRuntimeRpc(ctx) {
|
|
|
2046
2654
|
onScreenshotTaken: (event, data) => {
|
|
2047
2655
|
void ctx.hooks.callHook(event, data);
|
|
2048
2656
|
},
|
|
2657
|
+
manageStorage: () => void 0,
|
|
2658
|
+
onStorageUpdated: (event, data) => {
|
|
2659
|
+
void ctx.hooks.callHook(event, data);
|
|
2660
|
+
},
|
|
2049
2661
|
recordPerformance: () => void 0,
|
|
2050
2662
|
onPerformanceRecorded: (event, data) => {
|
|
2051
2663
|
void ctx.hooks.callHook(event, data);
|
|
@@ -2342,9 +2954,85 @@ async function startCdpObservers(ctx, target, client) {
|
|
|
2342
2954
|
}
|
|
2343
2955
|
}
|
|
2344
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
|
+
|
|
2345
3033
|
// src/plugin/injectRuntime.ts
|
|
2346
3034
|
var import_node_module = require("module");
|
|
2347
|
-
var
|
|
3035
|
+
var import_node_path5 = require("path");
|
|
2348
3036
|
function createRuntimeInjectionController(options, getConfig) {
|
|
2349
3037
|
return {
|
|
2350
3038
|
resolveId(importee) {
|
|
@@ -2361,7 +3049,7 @@ function createRuntimeInjectionController(options, getConfig) {
|
|
|
2361
3049
|
},
|
|
2362
3050
|
load(id) {
|
|
2363
3051
|
if (id === RESOLVED_VIRTUAL_RUNTIME_ID) {
|
|
2364
|
-
return createRuntimeModule();
|
|
3052
|
+
return createRuntimeModule(options, getConfig()?.root);
|
|
2365
3053
|
}
|
|
2366
3054
|
if (id === RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID) {
|
|
2367
3055
|
return createScreenshotConfigModule(options);
|
|
@@ -2404,14 +3092,17 @@ ${code}`;
|
|
|
2404
3092
|
}
|
|
2405
3093
|
};
|
|
2406
3094
|
}
|
|
2407
|
-
function createRuntimeModule() {
|
|
3095
|
+
function createRuntimeModule(options, root) {
|
|
2408
3096
|
return [
|
|
2409
3097
|
"import { setScreenshotModuleRegistry, setSnapdomLoader, startRuntimeClient } from '@xiaou66/vite-plugin-vue-mcp-next/runtime/client';",
|
|
2410
3098
|
`import { screenshotModuleRegistry } from '${VIRTUAL_SCREENSHOT_CONFIG_ID}';`,
|
|
2411
3099
|
`import { loadSnapdom } from '${VIRTUAL_SNAPDOM_LOADER_ID}';`,
|
|
2412
3100
|
"setScreenshotModuleRegistry(screenshotModuleRegistry);",
|
|
2413
3101
|
"setSnapdomLoader(loadSnapdom);",
|
|
2414
|
-
|
|
3102
|
+
`void startRuntimeClient(${JSON.stringify({
|
|
3103
|
+
elementPicker: options.elementPicker,
|
|
3104
|
+
projectRoot: root
|
|
3105
|
+
})});`
|
|
2415
3106
|
].join("\n");
|
|
2416
3107
|
}
|
|
2417
3108
|
function createSnapdomLoaderModule(root) {
|
|
@@ -2428,7 +3119,7 @@ function createSnapdomLoaderModule(root) {
|
|
|
2428
3119
|
}
|
|
2429
3120
|
function canResolveSnapdomFromProject(root) {
|
|
2430
3121
|
try {
|
|
2431
|
-
(0, import_node_module.createRequire)((0,
|
|
3122
|
+
(0, import_node_module.createRequire)((0, import_node_path5.join)(root ?? process.cwd(), "package.json")).resolve(
|
|
2432
3123
|
"@zumer/snapdom"
|
|
2433
3124
|
);
|
|
2434
3125
|
return true;
|
|
@@ -2468,16 +3159,16 @@ function getPluginPath(plugin) {
|
|
|
2468
3159
|
|
|
2469
3160
|
// src/plugin/mcpClientConfig/index.ts
|
|
2470
3161
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
2471
|
-
var
|
|
3162
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
2472
3163
|
|
|
2473
3164
|
// src/plugin/mcpClientConfig/codexConfig.ts
|
|
2474
3165
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
2475
|
-
var
|
|
3166
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
2476
3167
|
async function updateCodexMcpClientConfig(options) {
|
|
2477
3168
|
try {
|
|
2478
3169
|
const current = await readOptionalTextFile(options.configPath);
|
|
2479
3170
|
const next = replaceOrAppendOwnedBlock(current, options);
|
|
2480
|
-
await import_promises3.default.mkdir(
|
|
3171
|
+
await import_promises3.default.mkdir(import_node_path6.default.dirname(options.configPath), { recursive: true });
|
|
2481
3172
|
await import_promises3.default.writeFile(options.configPath, next);
|
|
2482
3173
|
} catch (error) {
|
|
2483
3174
|
console.warn(
|
|
@@ -2577,7 +3268,7 @@ function isNodeError(error) {
|
|
|
2577
3268
|
|
|
2578
3269
|
// src/plugin/mcpClientConfig/jsonConfig.ts
|
|
2579
3270
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
2580
|
-
var
|
|
3271
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
2581
3272
|
async function updateJsonMcpClientConfig(options) {
|
|
2582
3273
|
try {
|
|
2583
3274
|
const config = await readJsonConfig(options.configPath);
|
|
@@ -2617,7 +3308,7 @@ function renameLegacyServer(mcpServers, options) {
|
|
|
2617
3308
|
);
|
|
2618
3309
|
}
|
|
2619
3310
|
async function writeJsonConfig(configPath, config) {
|
|
2620
|
-
await import_promises4.default.mkdir(
|
|
3311
|
+
await import_promises4.default.mkdir(import_node_path7.default.dirname(configPath), { recursive: true });
|
|
2621
3312
|
await import_promises4.default.writeFile(configPath, `${JSON.stringify(config, null, 2)}
|
|
2622
3313
|
`);
|
|
2623
3314
|
}
|
|
@@ -2662,12 +3353,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
2662
3353
|
root,
|
|
2663
3354
|
clientName: "cursor",
|
|
2664
3355
|
enabled: options.cursor,
|
|
2665
|
-
entryPath:
|
|
3356
|
+
entryPath: import_node_path8.default.join(root, ".cursor"),
|
|
2666
3357
|
entryKind: "directory",
|
|
2667
3358
|
userOptions,
|
|
2668
3359
|
createJob: () => updateJsonMcpClientConfig({
|
|
2669
3360
|
clientName: "Cursor",
|
|
2670
|
-
configPath:
|
|
3361
|
+
configPath: import_node_path8.default.join(root, ".cursor", "mcp.json"),
|
|
2671
3362
|
mcpUrl: sseUrl,
|
|
2672
3363
|
serverName,
|
|
2673
3364
|
legacyServerNames
|
|
@@ -2677,11 +3368,11 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
2677
3368
|
root,
|
|
2678
3369
|
clientName: "codex",
|
|
2679
3370
|
enabled: options.codex,
|
|
2680
|
-
entryPath:
|
|
3371
|
+
entryPath: import_node_path8.default.join(root, ".codex"),
|
|
2681
3372
|
entryKind: "directory",
|
|
2682
3373
|
userOptions,
|
|
2683
3374
|
createJob: () => updateCodexMcpClientConfig({
|
|
2684
|
-
configPath:
|
|
3375
|
+
configPath: import_node_path8.default.join(root, ".codex", "config.toml"),
|
|
2685
3376
|
mcpUrl: streamableHttpUrl,
|
|
2686
3377
|
serverName,
|
|
2687
3378
|
legacyServerNames
|
|
@@ -2691,12 +3382,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
2691
3382
|
root,
|
|
2692
3383
|
clientName: "claudeCode",
|
|
2693
3384
|
enabled: options.claudeCode,
|
|
2694
|
-
entryPath:
|
|
3385
|
+
entryPath: import_node_path8.default.join(root, ".mcp.json"),
|
|
2695
3386
|
entryKind: "file",
|
|
2696
3387
|
userOptions,
|
|
2697
3388
|
createJob: () => updateJsonMcpClientConfig({
|
|
2698
3389
|
clientName: "Claude Code",
|
|
2699
|
-
configPath:
|
|
3390
|
+
configPath: import_node_path8.default.join(root, ".mcp.json"),
|
|
2700
3391
|
mcpUrl: sseUrl,
|
|
2701
3392
|
serverName,
|
|
2702
3393
|
legacyServerNames
|
|
@@ -2706,12 +3397,12 @@ async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options,
|
|
|
2706
3397
|
root,
|
|
2707
3398
|
clientName: "trae",
|
|
2708
3399
|
enabled: options.trae,
|
|
2709
|
-
entryPath:
|
|
3400
|
+
entryPath: import_node_path8.default.join(root, ".trae"),
|
|
2710
3401
|
entryKind: "directory",
|
|
2711
3402
|
userOptions,
|
|
2712
3403
|
createJob: () => updateJsonMcpClientConfig({
|
|
2713
3404
|
clientName: "Trae",
|
|
2714
|
-
configPath:
|
|
3405
|
+
configPath: import_node_path8.default.join(root, ".trae", "mcp.json"),
|
|
2715
3406
|
mcpUrl: sseUrl,
|
|
2716
3407
|
serverName,
|
|
2717
3408
|
legacyServerNames
|
|
@@ -2771,11 +3462,11 @@ function isNodeError3(error) {
|
|
|
2771
3462
|
|
|
2772
3463
|
// src/plugin/skillConfig/index.ts
|
|
2773
3464
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
2774
|
-
var
|
|
3465
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
2775
3466
|
|
|
2776
3467
|
// src/plugin/skillConfig/writers.ts
|
|
2777
3468
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
2778
|
-
var
|
|
3469
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
2779
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. -->";
|
|
2780
3471
|
async function writeGeneratedTextFile(options) {
|
|
2781
3472
|
try {
|
|
@@ -2786,7 +3477,7 @@ async function writeGeneratedTextFile(options) {
|
|
|
2786
3477
|
);
|
|
2787
3478
|
return;
|
|
2788
3479
|
}
|
|
2789
|
-
await import_promises6.default.mkdir(
|
|
3480
|
+
await import_promises6.default.mkdir(import_node_path9.default.dirname(options.filePath), { recursive: true });
|
|
2790
3481
|
await import_promises6.default.writeFile(options.filePath, options.content);
|
|
2791
3482
|
} catch (error) {
|
|
2792
3483
|
console.warn(
|
|
@@ -2813,7 +3504,7 @@ function isNodeError4(error) {
|
|
|
2813
3504
|
|
|
2814
3505
|
// src/plugin/skillConfig/index.ts
|
|
2815
3506
|
var PACKAGE_NAME = "@xiaou66/vite-plugin-vue-mcp-next";
|
|
2816
|
-
var PACKAGED_SKILL_PATH =
|
|
3507
|
+
var PACKAGED_SKILL_PATH = import_node_path10.default.join("skills", "vite-mcp-next", "SKILL.md");
|
|
2817
3508
|
async function updateSkillConfigs(root, options) {
|
|
2818
3509
|
if (!options.autoConfig) {
|
|
2819
3510
|
return;
|
|
@@ -2829,13 +3520,13 @@ async function updateSkillConfigs(root, options) {
|
|
|
2829
3520
|
function createSkillConfigDescriptors(root) {
|
|
2830
3521
|
return [
|
|
2831
3522
|
{
|
|
2832
|
-
entryPath:
|
|
2833
|
-
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"),
|
|
2834
3525
|
targetName: "Codex skill"
|
|
2835
3526
|
},
|
|
2836
3527
|
{
|
|
2837
|
-
entryPath:
|
|
2838
|
-
filePath:
|
|
3528
|
+
entryPath: import_node_path10.default.join(root, ".claude"),
|
|
3529
|
+
filePath: import_node_path10.default.join(
|
|
2839
3530
|
root,
|
|
2840
3531
|
".claude",
|
|
2841
3532
|
"skills",
|
|
@@ -2845,8 +3536,8 @@ function createSkillConfigDescriptors(root) {
|
|
|
2845
3536
|
targetName: "Claude Code skill"
|
|
2846
3537
|
},
|
|
2847
3538
|
{
|
|
2848
|
-
entryPath:
|
|
2849
|
-
filePath:
|
|
3539
|
+
entryPath: import_node_path10.default.join(root, ".cursor"),
|
|
3540
|
+
filePath: import_node_path10.default.join(root, ".cursor", "rules", "vite-mcp-next.mdc"),
|
|
2850
3541
|
targetName: "Cursor rule"
|
|
2851
3542
|
}
|
|
2852
3543
|
];
|
|
@@ -2894,9 +3585,9 @@ async function safelyReadPackagedSkillContent(root) {
|
|
|
2894
3585
|
}
|
|
2895
3586
|
function getPackagedSkillCandidates(root) {
|
|
2896
3587
|
return [
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
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)
|
|
2900
3591
|
];
|
|
2901
3592
|
}
|
|
2902
3593
|
async function hasDirectoryEntry(entryPath) {
|
|
@@ -2930,6 +3621,7 @@ function vueMcpNext(userOptions = {}) {
|
|
|
2930
3621
|
options,
|
|
2931
3622
|
() => config
|
|
2932
3623
|
);
|
|
3624
|
+
let elementInstrumentation;
|
|
2933
3625
|
const cdpLifecycle = createCdpLifecycleController(ctx);
|
|
2934
3626
|
ctx.cdpLifecycle = cdpLifecycle;
|
|
2935
3627
|
return {
|
|
@@ -2938,6 +3630,9 @@ function vueMcpNext(userOptions = {}) {
|
|
|
2938
3630
|
apply: "serve",
|
|
2939
3631
|
configResolved(resolvedConfig) {
|
|
2940
3632
|
config = resolvedConfig;
|
|
3633
|
+
elementInstrumentation = createElementInstrumentationController({
|
|
3634
|
+
root: resolvedConfig.root
|
|
3635
|
+
});
|
|
2941
3636
|
},
|
|
2942
3637
|
async configureServer(server) {
|
|
2943
3638
|
ctx.server = server;
|
|
@@ -3041,7 +3736,21 @@ function vueMcpNext(userOptions = {}) {
|
|
|
3041
3736
|
return runtimeInjection.load(id);
|
|
3042
3737
|
},
|
|
3043
3738
|
transform(code, id, transformOptions) {
|
|
3044
|
-
|
|
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;
|
|
3045
3754
|
},
|
|
3046
3755
|
transformIndexHtml(html) {
|
|
3047
3756
|
return runtimeInjection.transformIndexHtml(html);
|