@mcpc-tech/unplugin-dev-inspector-mcp 0.0.37 → 0.0.39

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.
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
2
2
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
3
3
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
4
  import { randomUUID } from "crypto";
5
- import { CallToolRequestSchema, CompleteRequestSchema, ErrorCode, GetPromptRequestSchema, JSONRPCMessageSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, PingRequestSchema, ReadResourceRequestSchema, SetLevelRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
+ import { CallToolRequestSchema, CallToolResultSchema, CompleteRequestSchema, ErrorCode, GetPromptRequestSchema, JSONRPCMessageSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, PingRequestSchema, ReadResourceRequestSchema, SetLevelRequestSchema, SubscribeRequestSchema, UnsubscribeRequestSchema } from "@modelcontextprotocol/sdk/types.js";
6
6
  import z$1, { z } from "zod";
7
7
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
8
  import { Readable, Writable } from "node:stream";
@@ -17,7 +17,8 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
17
17
  import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
18
18
  import process$1, { cwd } from "node:process";
19
19
  import { homedir } from "os";
20
- import fs, { existsSync } from "fs";
20
+ import { execSync } from "child_process";
21
+ import fs, { existsSync, readFileSync } from "fs";
21
22
  import * as http from "http";
22
23
  import * as https from "https";
23
24
  import * as zlib from "zlib";
@@ -27,6 +28,7 @@ import { fileURLToPath as fileURLToPath$1 } from "url";
27
28
  import { asSchema, convertToModelMessages, jsonSchema, streamText, tool } from "ai";
28
29
  import { ClientSideConnection, PROTOCOL_VERSION, ndJsonStream, planEntrySchema } from "@agentclientprotocol/sdk";
29
30
  import { spawn } from "node:child_process";
31
+ import { createRequire as createRequire$1 } from "module";
30
32
  import { mkdir, readFile, writeFile } from "fs/promises";
31
33
 
32
34
  //#region rolldown:runtime
@@ -83480,6 +83482,19 @@ async function getOrCreateMcpClient(defKey, def) {
83480
83482
  mcpClientConnecting.delete(defKey);
83481
83483
  }
83482
83484
  }
83485
+ async function releaseMcpClient(defKey) {
83486
+ const entry = mcpClientPool.get(defKey);
83487
+ if (!entry) return;
83488
+ entry.refCount -= 1;
83489
+ if (entry.refCount <= 0) {
83490
+ mcpClientPool.delete(defKey);
83491
+ try {
83492
+ await entry.client.close();
83493
+ } catch (err) {
83494
+ console.error("Error closing MCP client:", err);
83495
+ }
83496
+ }
83497
+ }
83483
83498
  var cleanupAllPooledClients = async () => {
83484
83499
  const entries = Array.from(mcpClientPool.entries());
83485
83500
  mcpClientPool.clear();
@@ -83537,7 +83552,12 @@ async function composeMcpDepTools(mcpConfig, filterIn) {
83537
83552
  console.error(`Error creating MCP client for ${name}:`, error);
83538
83553
  }
83539
83554
  }
83540
- const cleanupClients = async () => {};
83555
+ const cleanupClients = async () => {
83556
+ await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
83557
+ acquiredKeys.length = 0;
83558
+ Object.keys(allTools).forEach((key) => delete allTools[key]);
83559
+ Object.keys(allClients).forEach((key) => delete allClients[key]);
83560
+ };
83541
83561
  return {
83542
83562
  tools: allTools,
83543
83563
  clients: allClients,
@@ -86339,6 +86359,17 @@ var ComposableMCPServer = class extends Server {
86339
86359
  server: this,
86340
86360
  toolNames: Object.keys(allTools)
86341
86361
  });
86362
+ this.onclose = async () => {
86363
+ await cleanupClients();
86364
+ await this.disposePlugins();
86365
+ await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
86366
+ };
86367
+ this.onerror = async (error) => {
86368
+ await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
86369
+ await cleanupClients();
86370
+ await this.disposePlugins();
86371
+ await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
86372
+ };
86342
86373
  const toolNameToDetailList = Object.entries(allTools);
86343
86374
  const publicToolNames = this.getPublicToolNames();
86344
86375
  const hiddenToolNames = this.getHiddenToolNames();
@@ -86851,6 +86882,7 @@ var ConnectionManager = class {
86851
86882
  transport.onclose = () => this.removeTransport(sessionId);
86852
86883
  }
86853
86884
  removeTransport(sessionId) {
86885
+ console.log(`[dev-inspector] [connection-manager] Removing transport: ${sessionId}`);
86854
86886
  delete this.transports[sessionId];
86855
86887
  for (const [_clientId, sessionIds] of this.watchersByClientId) if (sessionIds.has(sessionId)) {
86856
86888
  sessionIds.delete(sessionId);
@@ -86881,6 +86913,7 @@ var ConnectionManager = class {
86881
86913
  }
86882
86914
  sessionsToRemove.push(existingSessionId);
86883
86915
  }
86916
+ if (sessionsToRemove.length > 0) console.log(`[dev-inspector] [connection-manager] Cleaned up ${sessionsToRemove.length} previous sessions for clientId=${clientId} (new session=${newSessionId})`);
86884
86917
  for (const sessionId of sessionsToRemove) sessionIds.delete(sessionId);
86885
86918
  }
86886
86919
  handleInspectorConnection(sessionId) {
@@ -87091,11 +87124,17 @@ async function handleSseConnection(req, res, serverContext, connectionManager) {
87091
87124
  const url = new URL(req.url ?? "", `http://${host}:${port}`);
87092
87125
  const transport = new SSEServerTransport("/__mcp__/messages", res);
87093
87126
  const sessionId = transport.sessionId;
87094
- const clientId = url.searchParams.get("clientId") || "agent";
87127
+ const clientId = url.searchParams.get("clientId") || `agent-${sessionId}`;
87095
87128
  const puppetId = url.searchParams.get("puppetId") || "inspector";
87129
+ console.log(`[dev-inspector] [sse] New connection request: clientId=${clientId}, puppetId=${puppetId}, sessionId=${sessionId}`);
87096
87130
  connectionManager.registerTransport(sessionId, transport);
87097
- if (clientId === "inspector") connectionManager.handleInspectorConnection(sessionId);
87098
- else connectionManager.handleWatcherConnection(sessionId, clientId, puppetId, transport);
87131
+ if (clientId === "inspector") {
87132
+ console.log(`[dev-inspector] [sse] Handling Inspector connection: ${sessionId}`);
87133
+ connectionManager.handleInspectorConnection(sessionId);
87134
+ } else {
87135
+ console.log(`[dev-inspector] [sse] Handling Watcher connection: ${sessionId} (binding to ${puppetId})`);
87136
+ connectionManager.handleWatcherConnection(sessionId, clientId, puppetId, transport);
87137
+ }
87099
87138
  await mcpServer.connect(transport);
87100
87139
  } catch (error) {
87101
87140
  console.error("Error establishing SSE connection:", error);
@@ -87235,7 +87274,7 @@ function setupInspectorMiddleware(middlewares, config) {
87235
87274
  }
87236
87275
 
87237
87276
  //#endregion
87238
- //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.41/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87277
+ //#region ../../node_modules/.pnpm/@mcpc-tech+acp-ai-provider@0.1.43/node_modules/@mcpc-tech/acp-ai-provider/index.mjs
87239
87278
  createRequire(import.meta.url);
87240
87279
  function formatToolError(toolResult) {
87241
87280
  if (!toolResult || toolResult.length === 0) return "Unknown tool error";
@@ -87678,7 +87717,6 @@ var ACPLanguageModel = class {
87678
87717
  */
87679
87718
  parseToolCall(update$1) {
87680
87719
  if (update$1.sessionUpdate !== "tool_call") throw new Error("Invalid update type for parseToolCall");
87681
- console.log("Parsing tool call update:", JSON.stringify(update$1, null, 2));
87682
87720
  return {
87683
87721
  toolCallId: update$1.toolCallId,
87684
87722
  toolName: update$1.title || update$1.toolCallId,
@@ -87980,11 +88018,6 @@ var ACPLanguageModel = class {
87980
88018
  this.currentThinkingId = null;
87981
88019
  }
87982
88020
  const { toolCallId, toolName, toolInput } = this.parseToolCall(update$1);
87983
- console.log(`Parsing tool call: ${JSON.stringify({
87984
- toolCallId,
87985
- toolName,
87986
- toolInput
87987
- }, null, 2)}`);
87988
88021
  const existingToolCall = this.toolCallsMap.get(toolCallId);
87989
88022
  const hasInput = toolInput && typeof toolInput === "object" && Object.keys(toolInput).length > 0;
87990
88023
  if (!existingToolCall) {
@@ -88011,13 +88044,14 @@ var ACPLanguageModel = class {
88011
88044
  });
88012
88045
  } else if (!existingToolCall.inputAvailable && hasInput) {
88013
88046
  existingToolCall.inputAvailable = true;
88047
+ if (update$1.title && existingToolCall.name !== update$1.title && update$1.title !== toolCallId) existingToolCall.name = update$1.title;
88014
88048
  controller.enqueue({
88015
88049
  type: "tool-call",
88016
88050
  toolCallId,
88017
88051
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88018
88052
  input: JSON.stringify({
88019
88053
  toolCallId,
88020
- toolName,
88054
+ toolName: existingToolCall.name,
88021
88055
  args: toolInput
88022
88056
  })
88023
88057
  });
@@ -88044,13 +88078,14 @@ var ACPLanguageModel = class {
88044
88078
  }
88045
88079
  if (!toolInfo.inputAvailable) {
88046
88080
  toolInfo.inputAvailable = true;
88081
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88047
88082
  controller.enqueue({
88048
88083
  type: "tool-call",
88049
88084
  toolCallId,
88050
88085
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88051
88086
  input: JSON.stringify({
88052
88087
  toolCallId,
88053
- toolName,
88088
+ toolName: toolInfo.name,
88054
88089
  args: {}
88055
88090
  })
88056
88091
  });
@@ -88076,13 +88111,14 @@ var ACPLanguageModel = class {
88076
88111
  });
88077
88112
  } else if (!toolInfo.inputAvailable) {
88078
88113
  toolInfo.inputAvailable = true;
88114
+ if (update$1.title && toolInfo.name !== update$1.title && update$1.title !== toolCallId) toolInfo.name = update$1.title;
88079
88115
  controller.enqueue({
88080
88116
  type: "tool-call",
88081
88117
  toolCallId,
88082
88118
  toolName: ACP_PROVIDER_AGENT_DYNAMIC_TOOL_NAME2,
88083
88119
  input: JSON.stringify({
88084
88120
  toolCallId,
88085
- toolName,
88121
+ toolName: toolInfo.name,
88086
88122
  args: {}
88087
88123
  })
88088
88124
  });
@@ -88315,9 +88351,52 @@ function createACPProvider(config) {
88315
88351
  return new ACPProvider(config);
88316
88352
  }
88317
88353
 
88354
+ //#endregion
88355
+ //#region src/utils/npm-package.ts
88356
+ /**
88357
+ * Resolve npm package bin entry point
88358
+ * Returns the absolute path to the bin file, or null if resolution fails
88359
+ */
88360
+ function resolveNpmPackageBin(packageName) {
88361
+ try {
88362
+ const packageJsonPath = createRequire$1(import.meta.url).resolve(`${packageName}/package.json`);
88363
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
88364
+ let binPath;
88365
+ if (typeof packageJson.bin === "string") binPath = packageJson.bin;
88366
+ else if (typeof packageJson.bin === "object") {
88367
+ const binEntries = Object.entries(packageJson.bin);
88368
+ const matchingEntry = binEntries.find(([name]) => name === packageJson.name.split("/").pop());
88369
+ binPath = matchingEntry ? matchingEntry[1] : binEntries[0]?.[1];
88370
+ }
88371
+ if (!binPath) {
88372
+ console.warn(`[dev-inspector] [acp] No bin entry found in ${packageName}/package.json`);
88373
+ return null;
88374
+ }
88375
+ const binFullPath = join(dirname(packageJsonPath), binPath);
88376
+ console.log(`[dev-inspector] [acp] Resolved ${packageName} bin to: ${binFullPath}`);
88377
+ return binFullPath;
88378
+ } catch (error) {
88379
+ console.warn(`[dev-inspector] [acp] Failed to resolve npm package ${packageName}:`, error);
88380
+ return null;
88381
+ }
88382
+ }
88383
+
88318
88384
  //#endregion
88319
88385
  //#region src/middleware/acp-middleware.ts
88320
88386
  /**
88387
+ * Check if a command exists in the system PATH
88388
+ * Skips check for npx since it always exists
88389
+ */
88390
+ function checkCommandExists(command) {
88391
+ if (command === "npx" || command === "node") return true;
88392
+ try {
88393
+ execSync(`which ${command}`, { stdio: "ignore" });
88394
+ return true;
88395
+ } catch {
88396
+ return false;
88397
+ }
88398
+ }
88399
+ /**
88321
88400
  * Provider manager - stores one provider per agent config
88322
88401
  * Key: agentKey (command:args), Value: ProviderEntry
88323
88402
  */
@@ -88370,10 +88449,13 @@ async function loadMcpToolsV5(transport) {
88370
88449
  inputSchema: jsonSchema(toolInfo.inputSchema),
88371
88450
  execute: async (args) => {
88372
88451
  console.log(`[dev-inspector] [acp] Executing MCP tool: ${toolName}`);
88373
- return await callMcpMethodViaTransport(transport, "tools/call", {
88452
+ const result = await callMcpMethodViaTransport(transport, "tools/call", {
88374
88453
  name: toolName,
88375
88454
  arguments: args
88376
88455
  });
88456
+ const parsedResult = CallToolResultSchema.safeParse(result);
88457
+ if (!parsedResult.success) return result;
88458
+ return parsedResult.data?.content?.map((item) => item?.text).join("\n");
88377
88459
  }
88378
88460
  });
88379
88461
  }
@@ -88381,12 +88463,33 @@ async function loadMcpToolsV5(transport) {
88381
88463
  return tools;
88382
88464
  }
88383
88465
  /**
88384
- * Get the Inspector transport from the connection manager
88466
+ * Default system instructions for DevInspector - provides AI guidance
88467
+ */
88468
+ const DEFAULT_SYSTEM_INSTRUCTIONS = `# DevInspector Context
88469
+
88470
+ You are connected to a web app with DevInspector. Available tools:
88471
+
88472
+ - **list_inspections**: Check pending element inspections from user
88473
+ - **capture_element_context**: Activate visual selector to capture UI elements
88474
+ - **update_inspection_status**: Update inspection status with progress/results
88475
+ - **execute_page_script**: Run JavaScript in browser context
88476
+ - **chrome_devtools**: Access Chrome DevTools for network, console, performance
88477
+
88478
+ Workflow: Check \`list_inspections\` first. If there are pending items, help resolve them. Otherwise, assist with the user's request.`;
88479
+ /**
88480
+ * Get an active transport from the connection manager
88385
88481
  */
88386
88482
  function getActiveTransport() {
88387
88483
  const connectionManager = getConnectionManager();
88388
88484
  if (!connectionManager) return null;
88389
- return connectionManager.getInspectorTransport();
88485
+ return connectionManager.getInspectorTransport() || connectionManager.transports[Object.keys(connectionManager.transports)[0]];
88486
+ }
88487
+ /**
88488
+ * Get specifically the inspector transport for context and tools
88489
+ */
88490
+ function getInspectorTransport() {
88491
+ const connectionManager = getConnectionManager();
88492
+ return connectionManager ? connectionManager.getInspectorTransport() : null;
88390
88493
  }
88391
88494
  function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88392
88495
  /**
@@ -88433,10 +88536,28 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88433
88536
  console.log(`[dev-inspector] [acp] Reusing existing provider for ${agent.name}`);
88434
88537
  provider = providerEntry.provider;
88435
88538
  } else {
88539
+ if (!checkCommandExists(agent.command)) {
88540
+ const hints = [`Agent "${agent.name}" command not found: "${agent.command}"`];
88541
+ if (agent.installCommand) hints.push(`Install with: ${agent.installCommand}`);
88542
+ if (agent.configHint) hints.push(agent.configHint);
88543
+ if (agent.configLink) hints.push(`Documentation: ${agent.configLink}`);
88544
+ console.error(`\n${hints.join("\n")}\n`);
88545
+ return;
88546
+ }
88436
88547
  console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
88548
+ let command = agent.command;
88549
+ let args = agent.args;
88550
+ if (agent.npmPackage) {
88551
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88552
+ if (binPath) {
88553
+ command = binPath;
88554
+ args = agent.npmArgs || [];
88555
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88556
+ } else console.log(`[dev-inspector] [acp] Failed to resolve npm package, falling back to: ${agent.command}`);
88557
+ }
88437
88558
  provider = createACPProvider({
88438
- command: agent.command,
88439
- args: agent.args,
88559
+ command,
88560
+ args,
88440
88561
  env: {
88441
88562
  ...process.env,
88442
88563
  ...envVars
@@ -88459,7 +88580,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88459
88580
  }
88460
88581
  console.log(`[dev-inspector] [acp] Spawning new process/session for ${agent.name}`);
88461
88582
  const initPromise = (async () => {
88462
- const transport = getActiveTransport();
88583
+ const transport = getInspectorTransport() || getActiveTransport();
88463
88584
  let initialTools = {};
88464
88585
  if (transport) try {
88465
88586
  const rawTools = await loadMcpToolsV5(transport);
@@ -88491,6 +88612,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88491
88612
  res.setHeader("Content-Type", "application/json");
88492
88613
  res.end(JSON.stringify({ sessionId }));
88493
88614
  } catch (error) {
88615
+ if (error instanceof Error && error.message.includes("command not found")) throw error;
88494
88616
  console.error("ACP Init Session Error:", error);
88495
88617
  if (!res.headersSent) {
88496
88618
  res.statusCode = 500;
@@ -88570,9 +88692,19 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88570
88692
  shouldCleanupProvider = false;
88571
88693
  } else {
88572
88694
  console.log(`[dev-inspector] [acp] Creating new provider (no session found or provided)`);
88695
+ let command = agent.command;
88696
+ let args = agent.args;
88697
+ if (agent.npmPackage) {
88698
+ const binPath = resolveNpmPackageBin(agent.npmPackage);
88699
+ if (binPath) {
88700
+ command = binPath;
88701
+ args = agent.npmArgs || [];
88702
+ console.log(`[dev-inspector] [acp] Using resolved npm package: ${agent.npmPackage}`);
88703
+ }
88704
+ }
88573
88705
  provider = createACPProvider({
88574
- command: agent.command,
88575
- args: agent.args,
88706
+ command,
88707
+ args,
88576
88708
  env: {
88577
88709
  ...process.env,
88578
88710
  ...envVars
@@ -88585,7 +88717,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88585
88717
  });
88586
88718
  await provider.initSession();
88587
88719
  }
88588
- const transport = getActiveTransport();
88720
+ const transport = getInspectorTransport() || getActiveTransport();
88589
88721
  let mcpTools = {};
88590
88722
  if (transport) mcpTools = await loadMcpToolsV5(transport);
88591
88723
  else console.warn("[dev-inspector] [acp] No active MCP transport available, tools will not be loaded");
@@ -88602,10 +88734,21 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
88602
88734
  abortController.abort();
88603
88735
  if (shouldCleanupProvider) provider.cleanup();
88604
88736
  });
88737
+ const systemPrompt = agent.acpSystemPrompt ?? acpOptions?.acpSystemPrompt ?? DEFAULT_SYSTEM_INSTRUCTIONS;
88738
+ const enhancedMessages = convertToModelMessages(messages).map((msg, index$1) => {
88739
+ if (index$1 === 0 && msg.role === "user" && Array.isArray(msg.content)) return {
88740
+ ...msg,
88741
+ content: [{
88742
+ type: "text",
88743
+ text: `<system_instructions>\n${systemPrompt}\n</system_instructions>\n\n`
88744
+ }, ...msg.content]
88745
+ };
88746
+ return msg;
88747
+ });
88605
88748
  const response = streamText({
88606
88749
  model: provider.languageModel(model, mode),
88607
88750
  includeRawChunks: true,
88608
- messages: convertToModelMessages(messages),
88751
+ messages: enhancedMessages,
88609
88752
  abortSignal: abortController.signal,
88610
88753
  tools: acpTools(mcpTools),
88611
88754
  onError: (error) => {
package/dist/index.cjs CHANGED
@@ -40,6 +40,7 @@ async function launchBrowserWithDevTools(options) {
40
40
  chrome_navigate_page: { url }
41
41
  }
42
42
  });
43
+ await new Promise((r) => setTimeout(r, 1e3));
43
44
  return true;
44
45
  } catch (error) {
45
46
  console.error(`[dev-inspector] ⚠️ Failed to auto-open browser:`, error instanceof Error ? error.message : String(error));
@@ -204,6 +205,7 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
204
205
  }
205
206
  require_config_updater.setupInspectorMiddleware(server.middlewares, {
206
207
  agents: options.agents,
208
+ visibleAgents: options.visibleAgents,
207
209
  defaultAgent: options.defaultAgent,
208
210
  showInspectorBar: options.showInspectorBar
209
211
  });
@@ -266,6 +268,7 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
266
268
  }
267
269
  require_config_updater.setupInspectorMiddleware(server, {
268
270
  agents: options.agents,
271
+ visibleAgents: options.visibleAgents,
269
272
  defaultAgent: options.defaultAgent
270
273
  });
271
274
  callback();
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import * as unplugin1 from "unplugin";
1
+ import * as unplugin0 from "unplugin";
2
2
 
3
3
  //#region src/utils/config-updater.d.ts
4
4
  type EditorId = "cursor" | "vscode" | "windsurf" | "claude-code" | "antigravity";
@@ -52,6 +52,11 @@ interface AcpOptions {
52
52
  * @default undefined (skipped if not specified)
53
53
  */
54
54
  acpDelay?: number;
55
+ /**
56
+ * Custom system instructions to prepend to user messages
57
+ * @default undefined (uses built-in DevInspector context)
58
+ */
59
+ acpSystemPrompt?: string;
55
60
  }
56
61
  interface Agent extends AcpOptions {
57
62
  name: string;
@@ -65,6 +70,26 @@ interface Agent extends AcpOptions {
65
70
  meta?: {
66
71
  icon?: string;
67
72
  };
73
+ /**
74
+ * Configuration hint text to help users set up the agent
75
+ */
76
+ configHint?: string;
77
+ /**
78
+ * Link to configuration documentation or setup guide
79
+ */
80
+ configLink?: string;
81
+ /**
82
+ * Installation command for the agent (shown in error messages)
83
+ */
84
+ installCommand?: string;
85
+ /**
86
+ * NPM package name for agents that use npm packages (for faster loading via require.resolve)
87
+ */
88
+ npmPackage?: string;
89
+ /**
90
+ * Arguments to pass when using npm package resolution (separate from npx args)
91
+ */
92
+ npmArgs?: string[];
68
93
  }
69
94
  //#endregion
70
95
  //#region src/utils/create-plugin.d.ts
@@ -94,6 +119,13 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
94
119
  * @see AVAILABLE_AGENTS https://github.com/mcpc-tech/dev-inspector-mcp/blob/main/packages/unplugin-dev-inspector/client/constants/agents.ts
95
120
  */
96
121
  agents?: Agent[];
122
+ /**
123
+ * Filter which agents are visible in the UI
124
+ * Only agents with names in this list will be shown (applies after merging custom agents)
125
+ * If not specified or empty array, all agents are visible
126
+ * @example ['Claude Code', 'Gemini CLI', 'My Custom Agent']
127
+ */
128
+ visibleAgents?: string[];
97
129
  /**
98
130
  * Default agent name to use
99
131
  * @default "Claude Code"
@@ -134,10 +166,10 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
134
166
  }
135
167
  //#endregion
136
168
  //#region src/core.d.ts
137
- declare const unplugin: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
169
+ declare const unplugin: unplugin0.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
138
170
  //#endregion
139
171
  //#region src/core-external.d.ts
140
- declare const unpluginExternal: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
172
+ declare const unpluginExternal: unplugin0.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
141
173
  //#endregion
142
174
  //#region src/turbopack.d.ts
143
175
  interface TurbopackDevInspectorOptions extends DevInspectorOptions {
@@ -162,7 +194,7 @@ interface TurbopackDevInspectorOptions extends DevInspectorOptions {
162
194
  declare function turbopackDevInspector(options?: TurbopackDevInspectorOptions): any;
163
195
  //#endregion
164
196
  //#region src/index.d.ts
165
- declare const external: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
197
+ declare const external: unplugin0.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
166
198
  declare module "virtual:dev-inspector-mcp" {}
167
199
  //#endregion
168
200
  export { type CustomEditorConfig, type DevInspectorOptions, type EditorId, type McpConfigOptions, type TurbopackDevInspectorOptions, unplugin as default, unplugin, external, turbopackDevInspector, unpluginExternal };
package/dist/index.d.ts CHANGED
@@ -52,6 +52,11 @@ interface AcpOptions {
52
52
  * @default undefined (skipped if not specified)
53
53
  */
54
54
  acpDelay?: number;
55
+ /**
56
+ * Custom system instructions to prepend to user messages
57
+ * @default undefined (uses built-in DevInspector context)
58
+ */
59
+ acpSystemPrompt?: string;
55
60
  }
56
61
  interface Agent extends AcpOptions {
57
62
  name: string;
@@ -65,6 +70,26 @@ interface Agent extends AcpOptions {
65
70
  meta?: {
66
71
  icon?: string;
67
72
  };
73
+ /**
74
+ * Configuration hint text to help users set up the agent
75
+ */
76
+ configHint?: string;
77
+ /**
78
+ * Link to configuration documentation or setup guide
79
+ */
80
+ configLink?: string;
81
+ /**
82
+ * Installation command for the agent (shown in error messages)
83
+ */
84
+ installCommand?: string;
85
+ /**
86
+ * NPM package name for agents that use npm packages (for faster loading via require.resolve)
87
+ */
88
+ npmPackage?: string;
89
+ /**
90
+ * Arguments to pass when using npm package resolution (separate from npx args)
91
+ */
92
+ npmArgs?: string[];
68
93
  }
69
94
  //#endregion
70
95
  //#region src/utils/create-plugin.d.ts
@@ -94,6 +119,13 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
94
119
  * @see AVAILABLE_AGENTS https://github.com/mcpc-tech/dev-inspector-mcp/blob/main/packages/unplugin-dev-inspector/client/constants/agents.ts
95
120
  */
96
121
  agents?: Agent[];
122
+ /**
123
+ * Filter which agents are visible in the UI
124
+ * Only agents with names in this list will be shown (applies after merging custom agents)
125
+ * If not specified or empty array, all agents are visible
126
+ * @example ['Claude Code', 'Gemini CLI', 'My Custom Agent']
127
+ */
128
+ visibleAgents?: string[];
97
129
  /**
98
130
  * Default agent name to use
99
131
  * @default "Claude Code"
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ async function launchBrowserWithDevTools(options) {
36
36
  chrome_navigate_page: { url }
37
37
  }
38
38
  });
39
+ await new Promise((r) => setTimeout(r, 1e3));
39
40
  return true;
40
41
  } catch (error) {
41
42
  console.error(`[dev-inspector] ⚠️ Failed to auto-open browser:`, error instanceof Error ? error.message : String(error));
@@ -200,6 +201,7 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
200
201
  }
201
202
  setupInspectorMiddleware(server.middlewares, {
202
203
  agents: options.agents,
204
+ visibleAgents: options.visibleAgents,
203
205
  defaultAgent: options.defaultAgent,
204
206
  showInspectorBar: options.showInspectorBar
205
207
  });
@@ -262,6 +264,7 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
262
264
  }
263
265
  setupInspectorMiddleware(server, {
264
266
  agents: options.agents,
267
+ visibleAgents: options.visibleAgents,
265
268
  defaultAgent: options.defaultAgent
266
269
  });
267
270
  callback();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpc-tech/unplugin-dev-inspector-mcp",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
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",
@@ -113,7 +113,7 @@
113
113
  "@babel/parser": "^7.28.5",
114
114
  "@babel/traverse": "^7.28.5",
115
115
  "@code-inspector/core": "^1.3.0",
116
- "@mcpc-tech/acp-ai-provider": "^0.1.41",
116
+ "@mcpc-tech/acp-ai-provider": "^0.1.43",
117
117
  "@mcpc-tech/cmcp": "^0.0.15",
118
118
  "@mcpc-tech/core": "^0.3.8",
119
119
  "@modelcontextprotocol/sdk": "^1.20.1",
@@ -168,6 +168,12 @@
168
168
  "use-stick-to-bottom": "^1.1.1",
169
169
  "zod": "^3.24.1"
170
170
  },
171
+ "optionalDependencies": {
172
+ "@blowmage/cursor-agent-acp": "^0.1.0",
173
+ "@yaonyan/droid-acp": "^0.0.8",
174
+ "@zed-industries/claude-code-acp": "^0.12.4",
175
+ "@zed-industries/codex-acp": "^0.7.1"
176
+ },
171
177
  "devDependencies": {
172
178
  "@babel/types": "^7.28.5",
173
179
  "@tailwindcss/postcss": "^4.1.14",