@mcpc-tech/unplugin-dev-inspector-mcp 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +289 -0
- package/client/dist/inspector.iife.js +326 -326
- package/dist/index.cjs +127 -21
- package/dist/index.js +127 -21
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -86862,28 +86862,52 @@ You MUST ask the user for confirmation before navigating to any URL.`,
|
|
|
86862
86862
|
|
|
86863
86863
|
//#endregion
|
|
86864
86864
|
//#region src/middleware/connection-manager.ts
|
|
86865
|
+
/**
|
|
86866
|
+
* Manages MCP transport connections between Watcher (VS Code) and Inspector (Browser).
|
|
86867
|
+
* Ensures only one chrome puppet binding is active at a time.
|
|
86868
|
+
*/
|
|
86865
86869
|
var ConnectionManager = class {
|
|
86866
86870
|
transports = {};
|
|
86867
86871
|
latestInspectorSessionId = null;
|
|
86868
86872
|
chromeWatcherSessionIds = /* @__PURE__ */ new Set();
|
|
86869
86873
|
boundPuppets = /* @__PURE__ */ new Map();
|
|
86870
|
-
constructor() {}
|
|
86871
86874
|
getTransport(sessionId) {
|
|
86872
86875
|
return this.transports[sessionId];
|
|
86873
86876
|
}
|
|
86874
86877
|
registerTransport(sessionId, transport) {
|
|
86875
86878
|
this.transports[sessionId] = transport;
|
|
86876
|
-
transport.onclose = () =>
|
|
86877
|
-
this.removeTransport(sessionId);
|
|
86878
|
-
};
|
|
86879
|
+
transport.onclose = () => this.removeTransport(sessionId);
|
|
86879
86880
|
}
|
|
86880
86881
|
removeTransport(sessionId) {
|
|
86881
|
-
|
|
86882
|
+
delete this.transports[sessionId];
|
|
86882
86883
|
if (this.chromeWatcherSessionIds.has(sessionId)) {
|
|
86883
86884
|
this.chromeWatcherSessionIds.delete(sessionId);
|
|
86885
|
+
const boundPuppet = this.boundPuppets.get(sessionId);
|
|
86886
|
+
if (boundPuppet) boundPuppet.unbindPuppet();
|
|
86884
86887
|
this.boundPuppets.delete(sessionId);
|
|
86885
86888
|
}
|
|
86886
86889
|
}
|
|
86890
|
+
/**
|
|
86891
|
+
* Clean up previous chrome watcher connections when a new one connects.
|
|
86892
|
+
*/
|
|
86893
|
+
cleanupPreviousChromeWatchers(newSessionId) {
|
|
86894
|
+
const sessionsToRemove = [];
|
|
86895
|
+
for (const existingSessionId of this.chromeWatcherSessionIds) {
|
|
86896
|
+
if (existingSessionId === newSessionId) continue;
|
|
86897
|
+
const boundPuppet = this.boundPuppets.get(existingSessionId);
|
|
86898
|
+
if (boundPuppet) boundPuppet.unbindPuppet();
|
|
86899
|
+
this.boundPuppets.delete(existingSessionId);
|
|
86900
|
+
const transport = this.transports[existingSessionId];
|
|
86901
|
+
if (transport) {
|
|
86902
|
+
try {
|
|
86903
|
+
transport.close?.();
|
|
86904
|
+
} catch {}
|
|
86905
|
+
delete this.transports[existingSessionId];
|
|
86906
|
+
}
|
|
86907
|
+
sessionsToRemove.push(existingSessionId);
|
|
86908
|
+
}
|
|
86909
|
+
for (const sessionId of sessionsToRemove) this.chromeWatcherSessionIds.delete(sessionId);
|
|
86910
|
+
}
|
|
86887
86911
|
handleInspectorConnection(sessionId) {
|
|
86888
86912
|
this.latestInspectorSessionId = sessionId;
|
|
86889
86913
|
this.rebindWatchersToInspector(sessionId);
|
|
@@ -86893,16 +86917,16 @@ var ConnectionManager = class {
|
|
|
86893
86917
|
if (!inspectorTransport) return;
|
|
86894
86918
|
for (const watcherSessionId of this.chromeWatcherSessionIds) {
|
|
86895
86919
|
const watcherTransport = this.transports[watcherSessionId];
|
|
86896
|
-
if (watcherTransport)
|
|
86897
|
-
|
|
86898
|
-
|
|
86899
|
-
|
|
86900
|
-
|
|
86901
|
-
}
|
|
86920
|
+
if (!watcherTransport) continue;
|
|
86921
|
+
const previousBound = this.boundPuppets.get(watcherSessionId);
|
|
86922
|
+
if (previousBound) previousBound.unbindPuppet();
|
|
86923
|
+
const newBound = bindPuppet(watcherTransport, inspectorTransport);
|
|
86924
|
+
this.boundPuppets.set(watcherSessionId, newBound);
|
|
86902
86925
|
}
|
|
86903
86926
|
}
|
|
86904
86927
|
handleWatcherConnection(sessionId, puppetId, transport) {
|
|
86905
86928
|
if (puppetId === "chrome") {
|
|
86929
|
+
this.cleanupPreviousChromeWatchers(sessionId);
|
|
86906
86930
|
this.chromeWatcherSessionIds.add(sessionId);
|
|
86907
86931
|
if (this.latestInspectorSessionId) {
|
|
86908
86932
|
const inspectorTransport = this.transports[this.latestInspectorSessionId];
|
|
@@ -86920,6 +86944,24 @@ var ConnectionManager = class {
|
|
|
86920
86944
|
}
|
|
86921
86945
|
};
|
|
86922
86946
|
|
|
86947
|
+
//#endregion
|
|
86948
|
+
//#region src/utils/cors.ts
|
|
86949
|
+
/**
|
|
86950
|
+
* Set CORS headers and handle preflight requests
|
|
86951
|
+
* Returns true if request was handled (preflight), false otherwise
|
|
86952
|
+
*/
|
|
86953
|
+
function handleCors(res, method) {
|
|
86954
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
86955
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
86956
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, mcp-session-id, mcp-protocol-version");
|
|
86957
|
+
if (method === "OPTIONS") {
|
|
86958
|
+
res.statusCode = 204;
|
|
86959
|
+
res.end();
|
|
86960
|
+
return true;
|
|
86961
|
+
}
|
|
86962
|
+
return false;
|
|
86963
|
+
}
|
|
86964
|
+
|
|
86923
86965
|
//#endregion
|
|
86924
86966
|
//#region src/middleware/mcproute-middleware.ts
|
|
86925
86967
|
/**
|
|
@@ -86929,6 +86971,9 @@ async function setupMcpMiddleware(middlewares, serverContext) {
|
|
|
86929
86971
|
const connectionManager = new ConnectionManager();
|
|
86930
86972
|
middlewares.use(async (req, res, next$1) => {
|
|
86931
86973
|
const url$1 = req.url || "";
|
|
86974
|
+
if (url$1.startsWith("/__mcp__")) {
|
|
86975
|
+
if (handleCors(res, req.method)) return;
|
|
86976
|
+
}
|
|
86932
86977
|
if (url$1.startsWith("/__mcp__") && !url$1.startsWith("/__mcp__/sse") && !url$1.startsWith("/__mcp__/messages")) {
|
|
86933
86978
|
if (req.method === "POST") await handleStreamableHttpPost(req, res, serverContext, connectionManager);
|
|
86934
86979
|
else if (req.method === "GET") await handleStreamableHttpGet(req, res, connectionManager);
|
|
@@ -86941,7 +86986,7 @@ async function setupMcpMiddleware(middlewares, serverContext) {
|
|
|
86941
86986
|
return;
|
|
86942
86987
|
}
|
|
86943
86988
|
if (url$1.startsWith("/__mcp__/messages") && req.method === "POST") {
|
|
86944
|
-
await handleSseMessage(req, res, connectionManager);
|
|
86989
|
+
await handleSseMessage(req, res, serverContext, connectionManager);
|
|
86945
86990
|
return;
|
|
86946
86991
|
}
|
|
86947
86992
|
next$1();
|
|
@@ -87052,7 +87097,9 @@ async function handleStreamableHttpDelete(req, res, connectionManager) {
|
|
|
87052
87097
|
async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
87053
87098
|
try {
|
|
87054
87099
|
const mcpServer = await createInspectorMcpServer(serverContext);
|
|
87055
|
-
const
|
|
87100
|
+
const host = serverContext?.host || "localhost";
|
|
87101
|
+
const port = serverContext?.port || 5173;
|
|
87102
|
+
const url$1 = new URL(req.url ?? "", `http://${host}:${port}`);
|
|
87056
87103
|
const transport = new __modelcontextprotocol_sdk_server_sse_js.SSEServerTransport("/__mcp__/messages", res);
|
|
87057
87104
|
const sessionId = transport.sessionId;
|
|
87058
87105
|
const aliasSessionId = url$1.searchParams.get("sessionId") || sessionId;
|
|
@@ -87074,9 +87121,11 @@ async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
|
87074
87121
|
/**
|
|
87075
87122
|
* Handle SSE message (deprecated)
|
|
87076
87123
|
*/
|
|
87077
|
-
async function handleSseMessage(req, res, connectionManager) {
|
|
87124
|
+
async function handleSseMessage(req, res, serverContext, connectionManager) {
|
|
87078
87125
|
try {
|
|
87079
|
-
const
|
|
87126
|
+
const host = serverContext?.host || "localhost";
|
|
87127
|
+
const port = serverContext?.port || 5173;
|
|
87128
|
+
const sessionId = new URL(req.url || "", `http://${host}:${port}`).searchParams.get("sessionId");
|
|
87080
87129
|
if (!sessionId) {
|
|
87081
87130
|
res.writeHead(400).end("Missing sessionId parameter");
|
|
87082
87131
|
return;
|
|
@@ -87158,6 +87207,9 @@ function setupInspectorMiddleware(middlewares, config) {
|
|
|
87158
87207
|
let cachedCSS = null;
|
|
87159
87208
|
let filesChecked = false;
|
|
87160
87209
|
middlewares.use((req, res, next$1) => {
|
|
87210
|
+
if (req.url?.startsWith("/__inspector__")) {
|
|
87211
|
+
if (handleCors(res, req.method)) return;
|
|
87212
|
+
}
|
|
87161
87213
|
if (!filesChecked) {
|
|
87162
87214
|
cachedScript = getInspectorScript();
|
|
87163
87215
|
cachedCSS = getInspectorCSS();
|
|
@@ -87839,6 +87891,7 @@ function resolveMcpRemote(cwd$1 = process.cwd()) {
|
|
|
87839
87891
|
//#region src/middleware/acp-middleware.ts
|
|
87840
87892
|
function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
87841
87893
|
middlewares.use("/api/acp/chat", async (req, res) => {
|
|
87894
|
+
if (handleCors(res, req.method)) return;
|
|
87842
87895
|
if (req.method !== "POST") {
|
|
87843
87896
|
res.statusCode = 405;
|
|
87844
87897
|
res.end("Method Not Allowed");
|
|
@@ -87881,7 +87934,10 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
87881
87934
|
const delay = agent.acpDelay ?? acpOptions?.acpDelay;
|
|
87882
87935
|
if (mode !== void 0) await provider.setMode(mode);
|
|
87883
87936
|
if (model !== void 0) await provider.setModel(model);
|
|
87884
|
-
if (delay !== void 0 && delay > 0)
|
|
87937
|
+
if (delay !== void 0 && delay > 0) {
|
|
87938
|
+
console.log(`[dev-inspector] [acp] Delaying response by ${delay}ms, agent: ${agent.name}`);
|
|
87939
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, delay));
|
|
87940
|
+
}
|
|
87885
87941
|
const response = (0, ai.streamText)({
|
|
87886
87942
|
model: provider.languageModel(),
|
|
87887
87943
|
includeRawChunks: true,
|
|
@@ -88205,6 +88261,8 @@ const unplugin$1 = (0, unplugin.createUnplugin)((options = {}) => {
|
|
|
88205
88261
|
const enabled = options.enabled ?? process.env.NODE_ENV !== "production";
|
|
88206
88262
|
const enableMcp = options.enableMcp ?? true;
|
|
88207
88263
|
const virtualModuleName = options.virtualModuleName ?? "virtual:dev-inspector-mcp";
|
|
88264
|
+
let resolvedHost = options.host || "localhost";
|
|
88265
|
+
let resolvedPort = options.port || 5173;
|
|
88208
88266
|
if (!enabled) return { name: "unplugin-dev-inspector" };
|
|
88209
88267
|
return {
|
|
88210
88268
|
name: "unplugin-dev-inspector",
|
|
@@ -88220,10 +88278,22 @@ if (import.meta.env.DEV) {
|
|
|
88220
88278
|
// Create inspector element
|
|
88221
88279
|
const inspector = document.createElement('dev-inspector-mcp');
|
|
88222
88280
|
document.body.appendChild(inspector);
|
|
88223
|
-
|
|
88281
|
+
|
|
88282
|
+
// Store dev server config globally (injected at build time)
|
|
88283
|
+
window.__DEV_INSPECTOR_CONFIG__ = {
|
|
88284
|
+
host: '${resolvedHost}',
|
|
88285
|
+
port: '${resolvedPort}',
|
|
88286
|
+
base: import.meta.env.BASE_URL || '/'
|
|
88287
|
+
};
|
|
88288
|
+
|
|
88224
88289
|
// Dynamically load inspector script (only in dev)
|
|
88225
88290
|
const script = document.createElement('script');
|
|
88226
|
-
|
|
88291
|
+
const config = window.__DEV_INSPECTOR_CONFIG__;
|
|
88292
|
+
let baseUrl = 'http://' + config.host + ':' + config.port + config.base;
|
|
88293
|
+
if (baseUrl.endsWith('/')) {
|
|
88294
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
88295
|
+
}
|
|
88296
|
+
script.src = baseUrl + '/__inspector__/inspector.iife.js';
|
|
88227
88297
|
script.type = 'module';
|
|
88228
88298
|
document.head.appendChild(script);
|
|
88229
88299
|
}
|
|
@@ -88254,9 +88324,45 @@ if (import.meta.env.DEV) {
|
|
|
88254
88324
|
},
|
|
88255
88325
|
vite: {
|
|
88256
88326
|
apply: "serve",
|
|
88257
|
-
|
|
88258
|
-
|
|
88259
|
-
|
|
88327
|
+
configResolved(config) {
|
|
88328
|
+
const viteHost = config.server.host;
|
|
88329
|
+
resolvedHost = options.host ?? (typeof viteHost === "string" ? viteHost : viteHost === true ? "0.0.0.0" : "localhost");
|
|
88330
|
+
resolvedPort = options.port ?? config.server.port ?? 5173;
|
|
88331
|
+
if (resolvedHost === "0.0.0.0") resolvedHost = "localhost";
|
|
88332
|
+
},
|
|
88333
|
+
transformIndexHtml: {
|
|
88334
|
+
order: "pre",
|
|
88335
|
+
handler(html$2, ctx) {
|
|
88336
|
+
if (!(options.autoInject ?? true)) return html$2;
|
|
88337
|
+
const server = ctx.server;
|
|
88338
|
+
const viteHost = server?.config.server.host;
|
|
88339
|
+
const host = options.host ?? (typeof viteHost === "string" ? viteHost : viteHost === true ? "0.0.0.0" : "localhost");
|
|
88340
|
+
const port = options.port ?? server?.config.server.port ?? 5173;
|
|
88341
|
+
const base = server?.config.base ?? "/";
|
|
88342
|
+
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
88343
|
+
return html$2.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script>
|
|
88344
|
+
(function() {
|
|
88345
|
+
if (!window.__DEV_INSPECTOR_LOADED__) {
|
|
88346
|
+
window.__DEV_INSPECTOR_LOADED__ = true;
|
|
88347
|
+
// Store dev server config for client-side use (e.g., config-loader.ts)
|
|
88348
|
+
window.__DEV_INSPECTOR_CONFIG__ = {
|
|
88349
|
+
host: '${displayHost}',
|
|
88350
|
+
port: '${port}',
|
|
88351
|
+
base: '${base}'
|
|
88352
|
+
};
|
|
88353
|
+
var script = document.createElement('script');
|
|
88354
|
+
var config = window.__DEV_INSPECTOR_CONFIG__;
|
|
88355
|
+
var baseUrl = 'http://' + config.host + ':' + config.port + config.base;
|
|
88356
|
+
if (baseUrl.endsWith('/')) {
|
|
88357
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
88358
|
+
}
|
|
88359
|
+
script.src = baseUrl + '/__inspector__/inspector.iife.js';
|
|
88360
|
+
script.type = 'module';
|
|
88361
|
+
document.head.appendChild(script);
|
|
88362
|
+
}
|
|
88363
|
+
})();
|
|
88364
|
+
<\/script></body>`);
|
|
88365
|
+
}
|
|
88260
88366
|
},
|
|
88261
88367
|
async configureServer(server) {
|
|
88262
88368
|
if (enableMcp) {
|
package/dist/index.js
CHANGED
|
@@ -86854,28 +86854,52 @@ You MUST ask the user for confirmation before navigating to any URL.`,
|
|
|
86854
86854
|
|
|
86855
86855
|
//#endregion
|
|
86856
86856
|
//#region src/middleware/connection-manager.ts
|
|
86857
|
+
/**
|
|
86858
|
+
* Manages MCP transport connections between Watcher (VS Code) and Inspector (Browser).
|
|
86859
|
+
* Ensures only one chrome puppet binding is active at a time.
|
|
86860
|
+
*/
|
|
86857
86861
|
var ConnectionManager = class {
|
|
86858
86862
|
transports = {};
|
|
86859
86863
|
latestInspectorSessionId = null;
|
|
86860
86864
|
chromeWatcherSessionIds = /* @__PURE__ */ new Set();
|
|
86861
86865
|
boundPuppets = /* @__PURE__ */ new Map();
|
|
86862
|
-
constructor() {}
|
|
86863
86866
|
getTransport(sessionId) {
|
|
86864
86867
|
return this.transports[sessionId];
|
|
86865
86868
|
}
|
|
86866
86869
|
registerTransport(sessionId, transport) {
|
|
86867
86870
|
this.transports[sessionId] = transport;
|
|
86868
|
-
transport.onclose = () =>
|
|
86869
|
-
this.removeTransport(sessionId);
|
|
86870
|
-
};
|
|
86871
|
+
transport.onclose = () => this.removeTransport(sessionId);
|
|
86871
86872
|
}
|
|
86872
86873
|
removeTransport(sessionId) {
|
|
86873
|
-
|
|
86874
|
+
delete this.transports[sessionId];
|
|
86874
86875
|
if (this.chromeWatcherSessionIds.has(sessionId)) {
|
|
86875
86876
|
this.chromeWatcherSessionIds.delete(sessionId);
|
|
86877
|
+
const boundPuppet = this.boundPuppets.get(sessionId);
|
|
86878
|
+
if (boundPuppet) boundPuppet.unbindPuppet();
|
|
86876
86879
|
this.boundPuppets.delete(sessionId);
|
|
86877
86880
|
}
|
|
86878
86881
|
}
|
|
86882
|
+
/**
|
|
86883
|
+
* Clean up previous chrome watcher connections when a new one connects.
|
|
86884
|
+
*/
|
|
86885
|
+
cleanupPreviousChromeWatchers(newSessionId) {
|
|
86886
|
+
const sessionsToRemove = [];
|
|
86887
|
+
for (const existingSessionId of this.chromeWatcherSessionIds) {
|
|
86888
|
+
if (existingSessionId === newSessionId) continue;
|
|
86889
|
+
const boundPuppet = this.boundPuppets.get(existingSessionId);
|
|
86890
|
+
if (boundPuppet) boundPuppet.unbindPuppet();
|
|
86891
|
+
this.boundPuppets.delete(existingSessionId);
|
|
86892
|
+
const transport = this.transports[existingSessionId];
|
|
86893
|
+
if (transport) {
|
|
86894
|
+
try {
|
|
86895
|
+
transport.close?.();
|
|
86896
|
+
} catch {}
|
|
86897
|
+
delete this.transports[existingSessionId];
|
|
86898
|
+
}
|
|
86899
|
+
sessionsToRemove.push(existingSessionId);
|
|
86900
|
+
}
|
|
86901
|
+
for (const sessionId of sessionsToRemove) this.chromeWatcherSessionIds.delete(sessionId);
|
|
86902
|
+
}
|
|
86879
86903
|
handleInspectorConnection(sessionId) {
|
|
86880
86904
|
this.latestInspectorSessionId = sessionId;
|
|
86881
86905
|
this.rebindWatchersToInspector(sessionId);
|
|
@@ -86885,16 +86909,16 @@ var ConnectionManager = class {
|
|
|
86885
86909
|
if (!inspectorTransport) return;
|
|
86886
86910
|
for (const watcherSessionId of this.chromeWatcherSessionIds) {
|
|
86887
86911
|
const watcherTransport = this.transports[watcherSessionId];
|
|
86888
|
-
if (watcherTransport)
|
|
86889
|
-
|
|
86890
|
-
|
|
86891
|
-
|
|
86892
|
-
|
|
86893
|
-
}
|
|
86912
|
+
if (!watcherTransport) continue;
|
|
86913
|
+
const previousBound = this.boundPuppets.get(watcherSessionId);
|
|
86914
|
+
if (previousBound) previousBound.unbindPuppet();
|
|
86915
|
+
const newBound = bindPuppet(watcherTransport, inspectorTransport);
|
|
86916
|
+
this.boundPuppets.set(watcherSessionId, newBound);
|
|
86894
86917
|
}
|
|
86895
86918
|
}
|
|
86896
86919
|
handleWatcherConnection(sessionId, puppetId, transport) {
|
|
86897
86920
|
if (puppetId === "chrome") {
|
|
86921
|
+
this.cleanupPreviousChromeWatchers(sessionId);
|
|
86898
86922
|
this.chromeWatcherSessionIds.add(sessionId);
|
|
86899
86923
|
if (this.latestInspectorSessionId) {
|
|
86900
86924
|
const inspectorTransport = this.transports[this.latestInspectorSessionId];
|
|
@@ -86912,6 +86936,24 @@ var ConnectionManager = class {
|
|
|
86912
86936
|
}
|
|
86913
86937
|
};
|
|
86914
86938
|
|
|
86939
|
+
//#endregion
|
|
86940
|
+
//#region src/utils/cors.ts
|
|
86941
|
+
/**
|
|
86942
|
+
* Set CORS headers and handle preflight requests
|
|
86943
|
+
* Returns true if request was handled (preflight), false otherwise
|
|
86944
|
+
*/
|
|
86945
|
+
function handleCors(res, method) {
|
|
86946
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
86947
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
86948
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, mcp-session-id, mcp-protocol-version");
|
|
86949
|
+
if (method === "OPTIONS") {
|
|
86950
|
+
res.statusCode = 204;
|
|
86951
|
+
res.end();
|
|
86952
|
+
return true;
|
|
86953
|
+
}
|
|
86954
|
+
return false;
|
|
86955
|
+
}
|
|
86956
|
+
|
|
86915
86957
|
//#endregion
|
|
86916
86958
|
//#region src/middleware/mcproute-middleware.ts
|
|
86917
86959
|
/**
|
|
@@ -86921,6 +86963,9 @@ async function setupMcpMiddleware(middlewares, serverContext) {
|
|
|
86921
86963
|
const connectionManager = new ConnectionManager();
|
|
86922
86964
|
middlewares.use(async (req, res, next$1) => {
|
|
86923
86965
|
const url = req.url || "";
|
|
86966
|
+
if (url.startsWith("/__mcp__")) {
|
|
86967
|
+
if (handleCors(res, req.method)) return;
|
|
86968
|
+
}
|
|
86924
86969
|
if (url.startsWith("/__mcp__") && !url.startsWith("/__mcp__/sse") && !url.startsWith("/__mcp__/messages")) {
|
|
86925
86970
|
if (req.method === "POST") await handleStreamableHttpPost(req, res, serverContext, connectionManager);
|
|
86926
86971
|
else if (req.method === "GET") await handleStreamableHttpGet(req, res, connectionManager);
|
|
@@ -86933,7 +86978,7 @@ async function setupMcpMiddleware(middlewares, serverContext) {
|
|
|
86933
86978
|
return;
|
|
86934
86979
|
}
|
|
86935
86980
|
if (url.startsWith("/__mcp__/messages") && req.method === "POST") {
|
|
86936
|
-
await handleSseMessage(req, res, connectionManager);
|
|
86981
|
+
await handleSseMessage(req, res, serverContext, connectionManager);
|
|
86937
86982
|
return;
|
|
86938
86983
|
}
|
|
86939
86984
|
next$1();
|
|
@@ -87044,7 +87089,9 @@ async function handleStreamableHttpDelete(req, res, connectionManager) {
|
|
|
87044
87089
|
async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
87045
87090
|
try {
|
|
87046
87091
|
const mcpServer = await createInspectorMcpServer(serverContext);
|
|
87047
|
-
const
|
|
87092
|
+
const host = serverContext?.host || "localhost";
|
|
87093
|
+
const port = serverContext?.port || 5173;
|
|
87094
|
+
const url = new URL(req.url ?? "", `http://${host}:${port}`);
|
|
87048
87095
|
const transport = new SSEServerTransport("/__mcp__/messages", res);
|
|
87049
87096
|
const sessionId = transport.sessionId;
|
|
87050
87097
|
const aliasSessionId = url.searchParams.get("sessionId") || sessionId;
|
|
@@ -87066,9 +87113,11 @@ async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
|
87066
87113
|
/**
|
|
87067
87114
|
* Handle SSE message (deprecated)
|
|
87068
87115
|
*/
|
|
87069
|
-
async function handleSseMessage(req, res, connectionManager) {
|
|
87116
|
+
async function handleSseMessage(req, res, serverContext, connectionManager) {
|
|
87070
87117
|
try {
|
|
87071
|
-
const
|
|
87118
|
+
const host = serverContext?.host || "localhost";
|
|
87119
|
+
const port = serverContext?.port || 5173;
|
|
87120
|
+
const sessionId = new URL(req.url || "", `http://${host}:${port}`).searchParams.get("sessionId");
|
|
87072
87121
|
if (!sessionId) {
|
|
87073
87122
|
res.writeHead(400).end("Missing sessionId parameter");
|
|
87074
87123
|
return;
|
|
@@ -87150,6 +87199,9 @@ function setupInspectorMiddleware(middlewares, config) {
|
|
|
87150
87199
|
let cachedCSS = null;
|
|
87151
87200
|
let filesChecked = false;
|
|
87152
87201
|
middlewares.use((req, res, next$1) => {
|
|
87202
|
+
if (req.url?.startsWith("/__inspector__")) {
|
|
87203
|
+
if (handleCors(res, req.method)) return;
|
|
87204
|
+
}
|
|
87153
87205
|
if (!filesChecked) {
|
|
87154
87206
|
cachedScript = getInspectorScript();
|
|
87155
87207
|
cachedCSS = getInspectorCSS();
|
|
@@ -87831,6 +87883,7 @@ function resolveMcpRemote(cwd$1 = process.cwd()) {
|
|
|
87831
87883
|
//#region src/middleware/acp-middleware.ts
|
|
87832
87884
|
function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
87833
87885
|
middlewares.use("/api/acp/chat", async (req, res) => {
|
|
87886
|
+
if (handleCors(res, req.method)) return;
|
|
87834
87887
|
if (req.method !== "POST") {
|
|
87835
87888
|
res.statusCode = 405;
|
|
87836
87889
|
res.end("Method Not Allowed");
|
|
@@ -87873,7 +87926,10 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
87873
87926
|
const delay = agent.acpDelay ?? acpOptions?.acpDelay;
|
|
87874
87927
|
if (mode !== void 0) await provider.setMode(mode);
|
|
87875
87928
|
if (model !== void 0) await provider.setModel(model);
|
|
87876
|
-
if (delay !== void 0 && delay > 0)
|
|
87929
|
+
if (delay !== void 0 && delay > 0) {
|
|
87930
|
+
console.log(`[dev-inspector] [acp] Delaying response by ${delay}ms, agent: ${agent.name}`);
|
|
87931
|
+
await new Promise((resolve$4) => setTimeout(resolve$4, delay));
|
|
87932
|
+
}
|
|
87877
87933
|
const response = streamText({
|
|
87878
87934
|
model: provider.languageModel(),
|
|
87879
87935
|
includeRawChunks: true,
|
|
@@ -88197,6 +88253,8 @@ const unplugin = createUnplugin((options = {}) => {
|
|
|
88197
88253
|
const enabled = options.enabled ?? process.env.NODE_ENV !== "production";
|
|
88198
88254
|
const enableMcp = options.enableMcp ?? true;
|
|
88199
88255
|
const virtualModuleName = options.virtualModuleName ?? "virtual:dev-inspector-mcp";
|
|
88256
|
+
let resolvedHost = options.host || "localhost";
|
|
88257
|
+
let resolvedPort = options.port || 5173;
|
|
88200
88258
|
if (!enabled) return { name: "unplugin-dev-inspector" };
|
|
88201
88259
|
return {
|
|
88202
88260
|
name: "unplugin-dev-inspector",
|
|
@@ -88212,10 +88270,22 @@ if (import.meta.env.DEV) {
|
|
|
88212
88270
|
// Create inspector element
|
|
88213
88271
|
const inspector = document.createElement('dev-inspector-mcp');
|
|
88214
88272
|
document.body.appendChild(inspector);
|
|
88215
|
-
|
|
88273
|
+
|
|
88274
|
+
// Store dev server config globally (injected at build time)
|
|
88275
|
+
window.__DEV_INSPECTOR_CONFIG__ = {
|
|
88276
|
+
host: '${resolvedHost}',
|
|
88277
|
+
port: '${resolvedPort}',
|
|
88278
|
+
base: import.meta.env.BASE_URL || '/'
|
|
88279
|
+
};
|
|
88280
|
+
|
|
88216
88281
|
// Dynamically load inspector script (only in dev)
|
|
88217
88282
|
const script = document.createElement('script');
|
|
88218
|
-
|
|
88283
|
+
const config = window.__DEV_INSPECTOR_CONFIG__;
|
|
88284
|
+
let baseUrl = 'http://' + config.host + ':' + config.port + config.base;
|
|
88285
|
+
if (baseUrl.endsWith('/')) {
|
|
88286
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
88287
|
+
}
|
|
88288
|
+
script.src = baseUrl + '/__inspector__/inspector.iife.js';
|
|
88219
88289
|
script.type = 'module';
|
|
88220
88290
|
document.head.appendChild(script);
|
|
88221
88291
|
}
|
|
@@ -88246,9 +88316,45 @@ if (import.meta.env.DEV) {
|
|
|
88246
88316
|
},
|
|
88247
88317
|
vite: {
|
|
88248
88318
|
apply: "serve",
|
|
88249
|
-
|
|
88250
|
-
|
|
88251
|
-
|
|
88319
|
+
configResolved(config) {
|
|
88320
|
+
const viteHost = config.server.host;
|
|
88321
|
+
resolvedHost = options.host ?? (typeof viteHost === "string" ? viteHost : viteHost === true ? "0.0.0.0" : "localhost");
|
|
88322
|
+
resolvedPort = options.port ?? config.server.port ?? 5173;
|
|
88323
|
+
if (resolvedHost === "0.0.0.0") resolvedHost = "localhost";
|
|
88324
|
+
},
|
|
88325
|
+
transformIndexHtml: {
|
|
88326
|
+
order: "pre",
|
|
88327
|
+
handler(html$2, ctx) {
|
|
88328
|
+
if (!(options.autoInject ?? true)) return html$2;
|
|
88329
|
+
const server = ctx.server;
|
|
88330
|
+
const viteHost = server?.config.server.host;
|
|
88331
|
+
const host = options.host ?? (typeof viteHost === "string" ? viteHost : viteHost === true ? "0.0.0.0" : "localhost");
|
|
88332
|
+
const port = options.port ?? server?.config.server.port ?? 5173;
|
|
88333
|
+
const base = server?.config.base ?? "/";
|
|
88334
|
+
const displayHost = host === "0.0.0.0" ? "localhost" : host;
|
|
88335
|
+
return html$2.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script>
|
|
88336
|
+
(function() {
|
|
88337
|
+
if (!window.__DEV_INSPECTOR_LOADED__) {
|
|
88338
|
+
window.__DEV_INSPECTOR_LOADED__ = true;
|
|
88339
|
+
// Store dev server config for client-side use (e.g., config-loader.ts)
|
|
88340
|
+
window.__DEV_INSPECTOR_CONFIG__ = {
|
|
88341
|
+
host: '${displayHost}',
|
|
88342
|
+
port: '${port}',
|
|
88343
|
+
base: '${base}'
|
|
88344
|
+
};
|
|
88345
|
+
var script = document.createElement('script');
|
|
88346
|
+
var config = window.__DEV_INSPECTOR_CONFIG__;
|
|
88347
|
+
var baseUrl = 'http://' + config.host + ':' + config.port + config.base;
|
|
88348
|
+
if (baseUrl.endsWith('/')) {
|
|
88349
|
+
baseUrl = baseUrl.slice(0, -1);
|
|
88350
|
+
}
|
|
88351
|
+
script.src = baseUrl + '/__inspector__/inspector.iife.js';
|
|
88352
|
+
script.type = 'module';
|
|
88353
|
+
document.head.appendChild(script);
|
|
88354
|
+
}
|
|
88355
|
+
})();
|
|
88356
|
+
<\/script></body>`);
|
|
88357
|
+
}
|
|
88252
88358
|
},
|
|
88253
88359
|
async configureServer(server) {
|
|
88254
88360
|
if (enableMcp) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcpc-tech/unplugin-dev-inspector-mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Universal dev inspector plugin for React/Vue - inspect component sources and API calls in any bundler",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"build:client": "tsdown --config tsdown.client.config.ts",
|
|
35
35
|
"dev:plugin": "tsdown --watch",
|
|
36
36
|
"dev:client": "tsdown --config tsdown.client.config.ts --watch",
|
|
37
|
-
"prepublishOnly": "pnpm build"
|
|
37
|
+
"prepublishOnly": "cp ../../README.md . && pnpm build"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"esbuild": ">=0.17.0",
|