@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/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
- if (this.transports[sessionId]) delete this.transports[sessionId];
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
- const previousBound = this.boundPuppets.get(watcherSessionId);
86898
- if (previousBound && typeof previousBound.unbindPuppet === "function") previousBound.unbindPuppet();
86899
- const newBound = bindPuppet(watcherTransport, inspectorTransport);
86900
- this.boundPuppets.set(watcherSessionId, newBound);
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 url$1 = new URL(req.url ?? "", `http://${req.headers.host}`);
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 sessionId = new URL(req.url || "", `http://${req.headers.host}`).searchParams.get("sessionId");
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) await new Promise((resolve$4) => setTimeout(resolve$4, delay));
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
- script.src = '/__inspector__/inspector.iife.js';
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
- transformIndexHtml(html$2) {
88258
- if (!(options.autoInject ?? true)) return html$2;
88259
- return html$2.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script src="/__inspector__/inspector.iife.js"><\/script></body>`);
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
- if (this.transports[sessionId]) delete this.transports[sessionId];
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
- const previousBound = this.boundPuppets.get(watcherSessionId);
86890
- if (previousBound && typeof previousBound.unbindPuppet === "function") previousBound.unbindPuppet();
86891
- const newBound = bindPuppet(watcherTransport, inspectorTransport);
86892
- this.boundPuppets.set(watcherSessionId, newBound);
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 url = new URL(req.url ?? "", `http://${req.headers.host}`);
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 sessionId = new URL(req.url || "", `http://${req.headers.host}`).searchParams.get("sessionId");
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) await new Promise((resolve$4) => setTimeout(resolve$4, delay));
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
- script.src = '/__inspector__/inspector.iife.js';
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
- transformIndexHtml(html$2) {
88250
- if (!(options.autoInject ?? true)) return html$2;
88251
- return html$2.replace("</body>", `<dev-inspector-mcp></dev-inspector-mcp><script src="/__inspector__/inspector.iife.js"><\/script></body>`);
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.2",
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",