@xiaou66/vite-plugin-vue-mcp-next 1.1.1 → 1.2.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.
@@ -28,105 +28,6 @@ __export(client_exports, {
28
28
  module.exports = __toCommonJS(client_exports);
29
29
  var import_vite_hot_client = require("vite-hot-client");
30
30
 
31
- // src/shared/limits.ts
32
- var DEFAULT_DOM_MAX_DEPTH = 8;
33
- var DEFAULT_DOM_MAX_NODES = 2e3;
34
- var DEFAULT_DOM_MAX_TEXT_LENGTH = 300;
35
- var DEFAULT_CONSOLE_MAX_RECORDS = 1e3;
36
- var DEFAULT_NETWORK_MAX_RECORDS = 500;
37
- var DEFAULT_NETWORK_MAX_BODY_SIZE = 1e5;
38
- var DEFAULT_MASK_HEADERS = [
39
- "authorization",
40
- "cookie",
41
- "set-cookie"
42
- ];
43
-
44
- // src/constants.ts
45
- var DEFAULT_MCP_PATH = "/__mcp";
46
- var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
47
- var DEFAULT_SCREENSHOT_SAVE_DIR = ".vite-mcp/screenshot";
48
- var DEFAULT_PERFORMANCE_SAVE_DIR = ".vite-mcp/performance";
49
- var DEFAULT_PERFORMANCE_MAX_DURATION_MS = 3e4;
50
- var DEFAULT_PERFORMANCE_SAMPLE_INTERVAL_MS = 250;
51
- var DEFAULT_PERFORMANCE_LONG_TASK_THRESHOLD_MS = 50;
52
- var VIRTUAL_RUNTIME_ID = "virtual:vite-plugin-vue-mcp-next/runtime";
53
- var RESOLVED_VIRTUAL_RUNTIME_ID = `\0${VIRTUAL_RUNTIME_ID}`;
54
- var VIRTUAL_SCREENSHOT_CONFIG_ID = "virtual:vite-plugin-vue-mcp-next/screenshot-config";
55
- var RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID = `\0${VIRTUAL_SCREENSHOT_CONFIG_ID}`;
56
- var VIRTUAL_SNAPDOM_LOADER_ID = "virtual:vite-plugin-vue-mcp-next/snapdom-loader";
57
- var RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID = `\0${VIRTUAL_SNAPDOM_LOADER_ID}`;
58
- var DEFAULT_MCP_CLIENT_SERVER_NAME = "vite-mcp-next";
59
- var RUNTIME_PAGE_CONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-connected";
60
- var RUNTIME_PAGE_DISCONNECTED_EVENT = "vite-plugin-vue-mcp-next:page-disconnected";
61
- var RUNTIME_PAGE_HEARTBEAT_EVENT = "vite-plugin-vue-mcp-next:heartbeat";
62
- var DEFAULT_RUNTIME_PAGE_HEARTBEAT_INTERVAL_MS = 15e3;
63
- var DEFAULT_OPTIONS = {
64
- mcpPath: DEFAULT_MCP_PATH,
65
- host: "localhost",
66
- printUrl: true,
67
- updateCursorMcpJson: {
68
- enabled: true,
69
- serverName: DEFAULT_MCP_CLIENT_SERVER_NAME
70
- },
71
- mcpClients: {
72
- cursor: true,
73
- codex: true,
74
- claudeCode: true,
75
- trae: true,
76
- serverName: DEFAULT_MCP_CLIENT_SERVER_NAME
77
- },
78
- skill: {
79
- autoConfig: true
80
- },
81
- runtime: {
82
- mode: "auto",
83
- evaluate: {
84
- enabled: false,
85
- timeoutMs: 3e3
86
- }
87
- },
88
- cdp: {},
89
- network: {
90
- mode: "auto",
91
- maxRecords: DEFAULT_NETWORK_MAX_RECORDS,
92
- captureRequestBody: true,
93
- captureResponseBody: true,
94
- maxBodySize: DEFAULT_NETWORK_MAX_BODY_SIZE,
95
- maskHeaders: [...DEFAULT_MASK_HEADERS]
96
- },
97
- dom: {
98
- maxDepth: DEFAULT_DOM_MAX_DEPTH,
99
- maxNodes: DEFAULT_DOM_MAX_NODES,
100
- maxTextLength: DEFAULT_DOM_MAX_TEXT_LENGTH
101
- },
102
- console: {
103
- maxRecords: DEFAULT_CONSOLE_MAX_RECORDS
104
- },
105
- screenshot: {
106
- type: "path",
107
- saveDir: DEFAULT_SCREENSHOT_SAVE_DIR,
108
- prefer: "auto",
109
- maxBytes: DEFAULT_SCREENSHOT_MAX_BYTES,
110
- snapdom: {
111
- options: {},
112
- plugins: []
113
- }
114
- },
115
- performance: {
116
- mode: "auto",
117
- maxDurationMs: DEFAULT_PERFORMANCE_MAX_DURATION_MS,
118
- sampleIntervalMs: DEFAULT_PERFORMANCE_SAMPLE_INTERVAL_MS,
119
- longTaskThresholdMs: DEFAULT_PERFORMANCE_LONG_TASK_THRESHOLD_MS,
120
- saveDir: DEFAULT_PERFORMANCE_SAVE_DIR,
121
- memory: {
122
- enabled: true
123
- },
124
- stacks: {
125
- enabled: true
126
- }
127
- }
128
- };
129
-
130
31
  // src/runtime/consoleHook.ts
131
32
  var import_nanoid = require("nanoid");
132
33
 
@@ -482,6 +383,101 @@ function getRuntimePageIdentity(input) {
482
383
  // src/runtime/performanceHook.ts
483
384
  var import_nanoid4 = require("nanoid");
484
385
 
386
+ // src/shared/limits.ts
387
+ var DEFAULT_DOM_MAX_DEPTH = 8;
388
+ var DEFAULT_DOM_MAX_NODES = 2e3;
389
+ var DEFAULT_DOM_MAX_TEXT_LENGTH = 300;
390
+ var DEFAULT_CONSOLE_MAX_RECORDS = 1e3;
391
+ var DEFAULT_NETWORK_MAX_RECORDS = 500;
392
+ var DEFAULT_NETWORK_MAX_BODY_SIZE = 1e5;
393
+ var DEFAULT_MASK_HEADERS = [
394
+ "authorization",
395
+ "cookie",
396
+ "set-cookie"
397
+ ];
398
+
399
+ // src/constants.ts
400
+ var DEFAULT_MCP_PATH = "/__mcp";
401
+ var DEFAULT_SCREENSHOT_MAX_BYTES = 5 * 1024 * 1024;
402
+ var DEFAULT_SCREENSHOT_SAVE_DIR = ".vite-mcp/screenshot";
403
+ var DEFAULT_PERFORMANCE_SAVE_DIR = ".vite-mcp/performance";
404
+ var DEFAULT_PERFORMANCE_MAX_DURATION_MS = 3e4;
405
+ var DEFAULT_PERFORMANCE_SAMPLE_INTERVAL_MS = 250;
406
+ var DEFAULT_PERFORMANCE_LONG_TASK_THRESHOLD_MS = 50;
407
+ var VIRTUAL_RUNTIME_ID = "virtual:vite-plugin-vue-mcp-next/runtime";
408
+ var RESOLVED_VIRTUAL_RUNTIME_ID = `\0${VIRTUAL_RUNTIME_ID}`;
409
+ var VIRTUAL_SCREENSHOT_CONFIG_ID = "virtual:vite-plugin-vue-mcp-next/screenshot-config";
410
+ var RESOLVED_VIRTUAL_SCREENSHOT_CONFIG_ID = `\0${VIRTUAL_SCREENSHOT_CONFIG_ID}`;
411
+ var VIRTUAL_SNAPDOM_LOADER_ID = "virtual:vite-plugin-vue-mcp-next/snapdom-loader";
412
+ var RESOLVED_VIRTUAL_SNAPDOM_LOADER_ID = `\0${VIRTUAL_SNAPDOM_LOADER_ID}`;
413
+ var DEFAULT_MCP_CLIENT_SERVER_NAME = "vite-mcp-next";
414
+ var DEFAULT_OPTIONS = {
415
+ mcpPath: DEFAULT_MCP_PATH,
416
+ host: "localhost",
417
+ printUrl: true,
418
+ updateCursorMcpJson: {
419
+ enabled: true,
420
+ serverName: DEFAULT_MCP_CLIENT_SERVER_NAME
421
+ },
422
+ mcpClients: {
423
+ cursor: true,
424
+ codex: true,
425
+ claudeCode: true,
426
+ trae: true,
427
+ serverName: DEFAULT_MCP_CLIENT_SERVER_NAME
428
+ },
429
+ skill: {
430
+ autoConfig: true
431
+ },
432
+ runtime: {
433
+ mode: "auto",
434
+ evaluate: {
435
+ enabled: false,
436
+ timeoutMs: 3e3
437
+ }
438
+ },
439
+ cdp: {},
440
+ network: {
441
+ mode: "auto",
442
+ maxRecords: DEFAULT_NETWORK_MAX_RECORDS,
443
+ captureRequestBody: true,
444
+ captureResponseBody: true,
445
+ maxBodySize: DEFAULT_NETWORK_MAX_BODY_SIZE,
446
+ maskHeaders: [...DEFAULT_MASK_HEADERS]
447
+ },
448
+ dom: {
449
+ maxDepth: DEFAULT_DOM_MAX_DEPTH,
450
+ maxNodes: DEFAULT_DOM_MAX_NODES,
451
+ maxTextLength: DEFAULT_DOM_MAX_TEXT_LENGTH
452
+ },
453
+ console: {
454
+ maxRecords: DEFAULT_CONSOLE_MAX_RECORDS
455
+ },
456
+ screenshot: {
457
+ type: "path",
458
+ saveDir: DEFAULT_SCREENSHOT_SAVE_DIR,
459
+ prefer: "auto",
460
+ maxBytes: DEFAULT_SCREENSHOT_MAX_BYTES,
461
+ snapdom: {
462
+ options: {},
463
+ plugins: []
464
+ }
465
+ },
466
+ performance: {
467
+ mode: "auto",
468
+ maxDurationMs: DEFAULT_PERFORMANCE_MAX_DURATION_MS,
469
+ sampleIntervalMs: DEFAULT_PERFORMANCE_SAMPLE_INTERVAL_MS,
470
+ longTaskThresholdMs: DEFAULT_PERFORMANCE_LONG_TASK_THRESHOLD_MS,
471
+ saveDir: DEFAULT_PERFORMANCE_SAVE_DIR,
472
+ memory: {
473
+ enabled: true
474
+ },
475
+ stacks: {
476
+ enabled: true
477
+ }
478
+ }
479
+ };
480
+
485
481
  // src/performance/summary.ts
486
482
  function buildPerformanceSummary(input) {
487
483
  const memory = buildMemorySummary(input.memorySamples);
@@ -1116,6 +1112,390 @@ function createTimeout(timeoutMs) {
1116
1112
  });
1117
1113
  }
1118
1114
 
1115
+ // src/runtime/storageBridge.ts
1116
+ function createRuntimeStorageBridge(env) {
1117
+ return {
1118
+ async manageStorage(request) {
1119
+ try {
1120
+ return await manageRuntimeStorage(env, request);
1121
+ } catch (error) {
1122
+ return createRuntimeStorageError(
1123
+ request,
1124
+ error instanceof Error ? error.message : String(error)
1125
+ );
1126
+ }
1127
+ }
1128
+ };
1129
+ }
1130
+ async function manageRuntimeStorage(env, request) {
1131
+ if (request.origin !== env.origin) {
1132
+ return createRuntimeStorageError(
1133
+ request,
1134
+ "Runtime storage access is limited to the current page origin"
1135
+ );
1136
+ }
1137
+ if (request.scope === "cookie") {
1138
+ return manageRuntimeCookie(env, request);
1139
+ }
1140
+ if (request.scope === "indexedDB") {
1141
+ return manageRuntimeIndexedDb(env, request);
1142
+ }
1143
+ return manageRuntimeWebStorage(getWebStorage(env, request.scope), request);
1144
+ }
1145
+ function manageRuntimeCookie(env, request) {
1146
+ if (!env.cookie) {
1147
+ return createRuntimeStorageError(
1148
+ request,
1149
+ "Runtime cookie access is unavailable",
1150
+ ["document.cookie is not available in this runtime environment"]
1151
+ );
1152
+ }
1153
+ if (request.action === "list") {
1154
+ return createRuntimeStorageSuccess(request, {
1155
+ origin: request.origin,
1156
+ cookies: readRuntimeCookies(env.cookie)
1157
+ });
1158
+ }
1159
+ if (request.action === "get") {
1160
+ assertCookieName(request);
1161
+ return createRuntimeStorageSuccess(request, {
1162
+ origin: request.origin,
1163
+ cookies: readRuntimeCookies(env.cookie).filter(
1164
+ (cookie) => cookie.name === request.cookie.name
1165
+ )
1166
+ });
1167
+ }
1168
+ if (request.action === "set") {
1169
+ assertCookieName(request);
1170
+ env.cookie.set(createRuntimeCookieWrite(request));
1171
+ return createRuntimeStorageSuccess(request, { ok: true });
1172
+ }
1173
+ if (request.action === "delete") {
1174
+ assertCookieName(request);
1175
+ env.cookie.set(createRuntimeCookieDelete(request));
1176
+ return createRuntimeStorageSuccess(request, {
1177
+ deletedCount: 1,
1178
+ skippedHttpOnlyCount: 0,
1179
+ limitations: ["HttpOnly cookies are invisible to runtime cookie access"]
1180
+ });
1181
+ }
1182
+ const cookies = readRuntimeCookies(env.cookie);
1183
+ for (const cookie of cookies) {
1184
+ env.cookie.set(
1185
+ createRuntimeCookieDelete({
1186
+ ...request,
1187
+ cookie: {
1188
+ name: cookie.name,
1189
+ path: request.cookie?.path
1190
+ }
1191
+ })
1192
+ );
1193
+ }
1194
+ return createRuntimeStorageSuccess(request, {
1195
+ deletedCount: cookies.length,
1196
+ skippedHttpOnlyCount: 0,
1197
+ limitations: ["HttpOnly cookies are invisible to runtime cookie access"]
1198
+ });
1199
+ }
1200
+ function getWebStorage(env, scope) {
1201
+ return scope === "sessionStorage" ? env.sessionStorage : env.localStorage;
1202
+ }
1203
+ function manageRuntimeWebStorage(storage, request) {
1204
+ if (request.action === "list") {
1205
+ return createRuntimeStorageSuccess(request, {
1206
+ origin: request.origin,
1207
+ scope: request.scope,
1208
+ entries: readStorageEntries(storage)
1209
+ });
1210
+ }
1211
+ if (request.action === "get") {
1212
+ assertStorageKey(request);
1213
+ return createRuntimeStorageSuccess(request, {
1214
+ origin: request.origin,
1215
+ scope: request.scope,
1216
+ key: request.key,
1217
+ value: storage.getItem(request.key)
1218
+ });
1219
+ }
1220
+ if (request.action === "set") {
1221
+ assertStorageKey(request);
1222
+ storage.setItem(request.key, request.value ?? "");
1223
+ return createRuntimeStorageSuccess(request, { ok: true });
1224
+ }
1225
+ if (request.action === "delete") {
1226
+ assertStorageKey(request);
1227
+ storage.removeItem(request.key);
1228
+ return createRuntimeStorageSuccess(request, { ok: true });
1229
+ }
1230
+ storage.clear();
1231
+ return createRuntimeStorageSuccess(request, { ok: true });
1232
+ }
1233
+ async function manageRuntimeIndexedDb(env, request) {
1234
+ if (!env.indexedDB?.databases) {
1235
+ return createRuntimeStorageError(request, "IndexedDB metadata API is unavailable");
1236
+ }
1237
+ if (request.action === "list") {
1238
+ const databases = await env.indexedDB.databases();
1239
+ return createRuntimeStorageSuccess(request, {
1240
+ origin: request.origin,
1241
+ scope: request.scope,
1242
+ databases: databases.map((database) => ({
1243
+ name: database.name,
1244
+ version: database.version
1245
+ }))
1246
+ });
1247
+ }
1248
+ assertIndexedDbTarget(request);
1249
+ if ("stores" in env.indexedDB) {
1250
+ return manageMemoryIndexedDb(env.indexedDB, request);
1251
+ }
1252
+ return manageBrowserIndexedDb(env.indexedDB, request);
1253
+ }
1254
+ function manageMemoryIndexedDb(indexedDB, request) {
1255
+ const storeId = `${request.databaseName}:${request.objectStoreName}`;
1256
+ const store = indexedDB.stores.get(storeId) ?? /* @__PURE__ */ new Map();
1257
+ indexedDB.stores.set(storeId, store);
1258
+ if (request.action === "get") {
1259
+ assertStorageKey(request);
1260
+ return createRuntimeStorageSuccess(request, {
1261
+ key: request.key,
1262
+ value: store.get(request.key) ?? null
1263
+ });
1264
+ }
1265
+ if (request.action === "set") {
1266
+ assertStorageKey(request);
1267
+ store.set(request.key, parseIndexedDbValue(request.value));
1268
+ return createRuntimeStorageSuccess(request, { ok: true });
1269
+ }
1270
+ if (request.action === "delete") {
1271
+ assertStorageKey(request);
1272
+ store.delete(request.key);
1273
+ return createRuntimeStorageSuccess(request, { ok: true });
1274
+ }
1275
+ store.clear();
1276
+ return createRuntimeStorageSuccess(request, { ok: true });
1277
+ }
1278
+ async function manageBrowserIndexedDb(indexedDB, request) {
1279
+ const database = await openIndexedDbForRequest(indexedDB, request);
1280
+ try {
1281
+ return await executeIndexedDbTransaction(database, request);
1282
+ } finally {
1283
+ database.close();
1284
+ }
1285
+ }
1286
+ function openIndexedDb(indexedDB, databaseName) {
1287
+ return new Promise((resolve, reject) => {
1288
+ const request = indexedDB.open(databaseName);
1289
+ request.onerror = () => {
1290
+ reject(request.error ?? new Error("IndexedDB open failed"));
1291
+ };
1292
+ request.onsuccess = () => {
1293
+ resolve(request.result);
1294
+ };
1295
+ });
1296
+ }
1297
+ async function openIndexedDbForRequest(indexedDB, request) {
1298
+ const database = await openIndexedDb(indexedDB, request.databaseName);
1299
+ if (request.action !== "set" || database.objectStoreNames.contains(request.objectStoreName)) {
1300
+ return database;
1301
+ }
1302
+ const version = database.version + 1;
1303
+ database.close();
1304
+ return openIndexedDbWithStore(indexedDB, {
1305
+ databaseName: request.databaseName,
1306
+ objectStoreName: request.objectStoreName,
1307
+ version
1308
+ });
1309
+ }
1310
+ function openIndexedDbWithStore(indexedDB, options) {
1311
+ return new Promise((resolve, reject) => {
1312
+ const request = indexedDB.open(options.databaseName, options.version);
1313
+ request.onupgradeneeded = () => {
1314
+ const database = request.result;
1315
+ if (!database.objectStoreNames.contains(options.objectStoreName)) {
1316
+ database.createObjectStore(options.objectStoreName);
1317
+ }
1318
+ };
1319
+ request.onerror = () => {
1320
+ reject(request.error ?? new Error("IndexedDB upgrade failed"));
1321
+ };
1322
+ request.onsuccess = () => {
1323
+ resolve(request.result);
1324
+ };
1325
+ });
1326
+ }
1327
+ function executeIndexedDbTransaction(database, request) {
1328
+ return new Promise((resolve, reject) => {
1329
+ const mode = request.action === "get" ? "readonly" : "readwrite";
1330
+ const transaction = database.transaction(request.objectStoreName, mode);
1331
+ const store = transaction.objectStore(request.objectStoreName);
1332
+ transaction.onerror = () => {
1333
+ reject(transaction.error ?? new Error("IndexedDB transaction failed"));
1334
+ };
1335
+ if (request.action === "get") {
1336
+ assertStorageKey(request);
1337
+ const getRequest = store.get(request.key);
1338
+ getRequest.onerror = () => {
1339
+ reject(getRequest.error ?? new Error("IndexedDB get failed"));
1340
+ };
1341
+ getRequest.onsuccess = () => {
1342
+ const value = getRequest.result ?? null;
1343
+ resolve(
1344
+ createRuntimeStorageSuccess(request, {
1345
+ key: request.key,
1346
+ value
1347
+ })
1348
+ );
1349
+ };
1350
+ return;
1351
+ }
1352
+ if (request.action === "set") {
1353
+ assertStorageKey(request);
1354
+ store.put(parseIndexedDbValue(request.value), request.key);
1355
+ transaction.oncomplete = () => {
1356
+ resolve(createRuntimeStorageSuccess(request, { ok: true }));
1357
+ };
1358
+ return;
1359
+ }
1360
+ if (request.action === "delete") {
1361
+ assertStorageKey(request);
1362
+ store.delete(request.key);
1363
+ transaction.oncomplete = () => {
1364
+ resolve(createRuntimeStorageSuccess(request, { ok: true }));
1365
+ };
1366
+ return;
1367
+ }
1368
+ store.clear();
1369
+ transaction.oncomplete = () => {
1370
+ resolve(createRuntimeStorageSuccess(request, { ok: true }));
1371
+ };
1372
+ });
1373
+ }
1374
+ function readStorageEntries(storage) {
1375
+ const entries = [];
1376
+ for (let index = 0; index < storage.length; index += 1) {
1377
+ const key = storage.key(index);
1378
+ if (!key) {
1379
+ continue;
1380
+ }
1381
+ const value = storage.getItem(key);
1382
+ if (value === null) {
1383
+ continue;
1384
+ }
1385
+ entries.push({ key, value });
1386
+ }
1387
+ return entries;
1388
+ }
1389
+ function readRuntimeCookies(cookieAccess) {
1390
+ return cookieAccess.get().split(";").map((item) => item.trim()).filter(Boolean).map((item) => {
1391
+ const separatorIndex = item.indexOf("=");
1392
+ if (separatorIndex === -1) {
1393
+ return { name: decodeCookiePart(item), value: "" };
1394
+ }
1395
+ return {
1396
+ name: decodeCookiePart(item.slice(0, separatorIndex)),
1397
+ value: decodeCookiePart(item.slice(separatorIndex + 1))
1398
+ };
1399
+ });
1400
+ }
1401
+ function createRuntimeCookieWrite(request) {
1402
+ const value = request.cookie.value ?? request.value ?? "";
1403
+ const parts = [
1404
+ `${encodeURIComponent(request.cookie.name)}=${encodeURIComponent(value)}`
1405
+ ];
1406
+ appendRuntimeCookieAttributes(parts, request.cookie);
1407
+ return parts.join("; ");
1408
+ }
1409
+ function createRuntimeCookieDelete(request) {
1410
+ const parts = [
1411
+ `${encodeURIComponent(request.cookie.name)}=`,
1412
+ "Expires=Thu, 01 Jan 1970 00:00:00 GMT",
1413
+ "Max-Age=0"
1414
+ ];
1415
+ appendRuntimeCookieAttributes(parts, {
1416
+ path: request.cookie.path,
1417
+ domain: request.cookie.domain
1418
+ });
1419
+ return parts.join("; ");
1420
+ }
1421
+ function appendRuntimeCookieAttributes(parts, cookie) {
1422
+ if (cookie.path) {
1423
+ parts.push(`Path=${cookie.path}`);
1424
+ }
1425
+ if (cookie.domain) {
1426
+ parts.push(`Domain=${cookie.domain}`);
1427
+ }
1428
+ if (cookie.expires !== void 0) {
1429
+ parts.push(`Expires=${new Date(cookie.expires * 1e3).toUTCString()}`);
1430
+ }
1431
+ if (cookie.sameSite) {
1432
+ parts.push(`SameSite=${normalizeRuntimeSameSite(cookie.sameSite)}`);
1433
+ }
1434
+ if (cookie.secure) {
1435
+ parts.push("Secure");
1436
+ }
1437
+ }
1438
+ function normalizeRuntimeSameSite(sameSite) {
1439
+ if (sameSite === "strict") {
1440
+ return "Strict";
1441
+ }
1442
+ if (sameSite === "lax") {
1443
+ return "Lax";
1444
+ }
1445
+ return "None";
1446
+ }
1447
+ function decodeCookiePart(value) {
1448
+ try {
1449
+ return decodeURIComponent(value);
1450
+ } catch {
1451
+ return value;
1452
+ }
1453
+ }
1454
+ function assertStorageKey(request) {
1455
+ if (!request.key) {
1456
+ throw new Error("Storage key is required for this operation");
1457
+ }
1458
+ }
1459
+ function assertCookieName(request) {
1460
+ if (!request.cookie?.name) {
1461
+ throw new Error("Cookie name is required for this operation");
1462
+ }
1463
+ }
1464
+ function assertIndexedDbTarget(request) {
1465
+ if (!request.databaseName || !request.objectStoreName) {
1466
+ throw new Error("IndexedDB databaseName and objectStoreName are required");
1467
+ }
1468
+ }
1469
+ function parseIndexedDbValue(value) {
1470
+ if (value === void 0) {
1471
+ return null;
1472
+ }
1473
+ try {
1474
+ return JSON.parse(value);
1475
+ } catch {
1476
+ return value;
1477
+ }
1478
+ }
1479
+ function createRuntimeStorageSuccess(request, data) {
1480
+ return {
1481
+ ok: true,
1482
+ source: "hook",
1483
+ action: request.action,
1484
+ scope: request.scope,
1485
+ data
1486
+ };
1487
+ }
1488
+ function createRuntimeStorageError(request, error, limitations) {
1489
+ return {
1490
+ ok: false,
1491
+ source: "hook",
1492
+ action: request.action,
1493
+ scope: request.scope,
1494
+ error,
1495
+ limitations
1496
+ };
1497
+ }
1498
+
1119
1499
  // src/runtime/devtoolsBridge.ts
1120
1500
  function createRuntimeDevtoolsRpc(getRpc) {
1121
1501
  return {
@@ -1171,7 +1551,26 @@ function createRuntimeDevtoolsRpc(getRpc) {
1171
1551
  });
1172
1552
  }
1173
1553
  },
1174
- onScreenshotTaken: () => void 0
1554
+ onScreenshotTaken: () => void 0,
1555
+ async manageStorage(options) {
1556
+ const bridge = createRuntimeStorageBridge({
1557
+ origin: window.location.origin,
1558
+ localStorage: window.localStorage,
1559
+ sessionStorage: window.sessionStorage,
1560
+ indexedDB: window.indexedDB,
1561
+ cookie: {
1562
+ get: () => window.document.cookie,
1563
+ set: (value) => {
1564
+ window.document.cookie = value;
1565
+ }
1566
+ }
1567
+ });
1568
+ getRpc().onStorageUpdated(
1569
+ options.event,
1570
+ await bridge.manageStorage(options)
1571
+ );
1572
+ },
1573
+ onStorageUpdated: () => void 0
1175
1574
  };
1176
1575
  }
1177
1576
 
@@ -1469,11 +1868,7 @@ async function startRuntimeClient() {
1469
1868
  innerHeight: window.innerHeight,
1470
1869
  readyState: document.readyState
1471
1870
  });
1472
- hot.send(RUNTIME_PAGE_CONNECTED_EVENT, identity);
1473
- installRuntimePageLifecycle({
1474
- pageId: identity.pageId,
1475
- send: hot.send.bind(hot)
1476
- });
1871
+ hot.send("vite-plugin-vue-mcp-next:page-connected", identity);
1477
1872
  installPerformanceHook({
1478
1873
  pageId: identity.pageId,
1479
1874
  send(report) {
@@ -1495,27 +1890,6 @@ async function startRuntimeClient() {
1495
1890
  }
1496
1891
  });
1497
1892
  }
1498
- function installRuntimePageLifecycle(options) {
1499
- let disconnected = false;
1500
- const heartbeatTimer = setInterval(() => {
1501
- options.send(RUNTIME_PAGE_HEARTBEAT_EVENT, {
1502
- pageId: options.pageId,
1503
- timestamp: Date.now()
1504
- });
1505
- }, DEFAULT_RUNTIME_PAGE_HEARTBEAT_INTERVAL_MS);
1506
- const disconnect = () => {
1507
- if (disconnected) {
1508
- return;
1509
- }
1510
- disconnected = true;
1511
- clearInterval(heartbeatTimer);
1512
- options.send(RUNTIME_PAGE_DISCONNECTED_EVENT, {
1513
- pageId: options.pageId
1514
- });
1515
- };
1516
- window.addEventListener("pagehide", disconnect, { once: true });
1517
- window.addEventListener("beforeunload", disconnect, { once: true });
1518
- }
1519
1893
  // Annotate the CommonJS export names for ESM import in node:
1520
1894
  0 && (module.exports = {
1521
1895
  evaluateExpression,