@mcpc-tech/unplugin-dev-inspector-mcp 0.0.36 → 0.0.38
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/client/dist/inspector.iife.js +358 -416
- package/dist/config-updater.cjs +84 -48
- package/dist/config-updater.js +80 -44
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +21 -4
- package/dist/index.js +3 -1
- package/package.json +2 -2
package/dist/config-updater.cjs
CHANGED
|
@@ -21,6 +21,7 @@ let _modelcontextprotocol_sdk_inMemory_js = require("@modelcontextprotocol/sdk/i
|
|
|
21
21
|
let node_process = require("node:process");
|
|
22
22
|
node_process = require_chunk.__toESM(node_process);
|
|
23
23
|
let os = require("os");
|
|
24
|
+
let child_process = require("child_process");
|
|
24
25
|
let fs = require("fs");
|
|
25
26
|
fs = require_chunk.__toESM(fs);
|
|
26
27
|
let http = require("http");
|
|
@@ -58015,9 +58016,9 @@ var require_utils$5 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) =>
|
|
|
58015
58016
|
var require_execAsync$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
58016
58017
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58017
58018
|
exports.execAsync = void 0;
|
|
58018
|
-
const child_process$
|
|
58019
|
+
const child_process$2 = require("child_process");
|
|
58019
58020
|
const util$1 = require("util");
|
|
58020
|
-
exports.execAsync = util$1.promisify(child_process$
|
|
58021
|
+
exports.execAsync = util$1.promisify(child_process$2.exec);
|
|
58021
58022
|
}));
|
|
58022
58023
|
|
|
58023
58024
|
//#endregion
|
|
@@ -66167,9 +66168,9 @@ var require_utils$1 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) =>
|
|
|
66167
66168
|
var require_execAsync = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
66168
66169
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66169
66170
|
exports.execAsync = void 0;
|
|
66170
|
-
const child_process = require("child_process");
|
|
66171
|
+
const child_process$1 = require("child_process");
|
|
66171
66172
|
const util = require("util");
|
|
66172
|
-
exports.execAsync = util.promisify(child_process.exec);
|
|
66173
|
+
exports.execAsync = util.promisify(child_process$1.exec);
|
|
66173
66174
|
}));
|
|
66174
66175
|
|
|
66175
66176
|
//#endregion
|
|
@@ -83445,19 +83446,6 @@ async function getOrCreateMcpClient(defKey, def) {
|
|
|
83445
83446
|
mcpClientConnecting.delete(defKey);
|
|
83446
83447
|
}
|
|
83447
83448
|
}
|
|
83448
|
-
async function releaseMcpClient(defKey) {
|
|
83449
|
-
const entry = mcpClientPool.get(defKey);
|
|
83450
|
-
if (!entry) return;
|
|
83451
|
-
entry.refCount -= 1;
|
|
83452
|
-
if (entry.refCount <= 0) {
|
|
83453
|
-
mcpClientPool.delete(defKey);
|
|
83454
|
-
try {
|
|
83455
|
-
await entry.client.close();
|
|
83456
|
-
} catch (err) {
|
|
83457
|
-
console.error("Error closing MCP client:", err);
|
|
83458
|
-
}
|
|
83459
|
-
}
|
|
83460
|
-
}
|
|
83461
83449
|
var cleanupAllPooledClients = async () => {
|
|
83462
83450
|
const entries = Array.from(mcpClientPool.entries());
|
|
83463
83451
|
mcpClientPool.clear();
|
|
@@ -83515,12 +83503,7 @@ async function composeMcpDepTools(mcpConfig, filterIn) {
|
|
|
83515
83503
|
console.error(`Error creating MCP client for ${name}:`, error);
|
|
83516
83504
|
}
|
|
83517
83505
|
}
|
|
83518
|
-
const cleanupClients = async () => {
|
|
83519
|
-
await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
|
|
83520
|
-
acquiredKeys.length = 0;
|
|
83521
|
-
Object.keys(allTools).forEach((key) => delete allTools[key]);
|
|
83522
|
-
Object.keys(allClients).forEach((key) => delete allClients[key]);
|
|
83523
|
-
};
|
|
83506
|
+
const cleanupClients = async () => {};
|
|
83524
83507
|
return {
|
|
83525
83508
|
tools: allTools,
|
|
83526
83509
|
clients: allClients,
|
|
@@ -86322,17 +86305,6 @@ var ComposableMCPServer = class extends _modelcontextprotocol_sdk_server_index_j
|
|
|
86322
86305
|
server: this,
|
|
86323
86306
|
toolNames: Object.keys(allTools)
|
|
86324
86307
|
});
|
|
86325
|
-
this.onclose = async () => {
|
|
86326
|
-
await cleanupClients();
|
|
86327
|
-
await this.disposePlugins();
|
|
86328
|
-
await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
|
|
86329
|
-
};
|
|
86330
|
-
this.onerror = async (error) => {
|
|
86331
|
-
await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
|
|
86332
|
-
await cleanupClients();
|
|
86333
|
-
await this.disposePlugins();
|
|
86334
|
-
await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
|
|
86335
|
-
};
|
|
86336
86308
|
const toolNameToDetailList = Object.entries(allTools);
|
|
86337
86309
|
const publicToolNames = this.getPublicToolNames();
|
|
86338
86310
|
const hiddenToolNames = this.getHiddenToolNames();
|
|
@@ -86845,6 +86817,7 @@ var ConnectionManager = class {
|
|
|
86845
86817
|
transport.onclose = () => this.removeTransport(sessionId);
|
|
86846
86818
|
}
|
|
86847
86819
|
removeTransport(sessionId) {
|
|
86820
|
+
console.log(`[dev-inspector] [connection-manager] Removing transport: ${sessionId}`);
|
|
86848
86821
|
delete this.transports[sessionId];
|
|
86849
86822
|
for (const [_clientId, sessionIds] of this.watchersByClientId) if (sessionIds.has(sessionId)) {
|
|
86850
86823
|
sessionIds.delete(sessionId);
|
|
@@ -86875,6 +86848,7 @@ var ConnectionManager = class {
|
|
|
86875
86848
|
}
|
|
86876
86849
|
sessionsToRemove.push(existingSessionId);
|
|
86877
86850
|
}
|
|
86851
|
+
if (sessionsToRemove.length > 0) console.log(`[dev-inspector] [connection-manager] Cleaned up ${sessionsToRemove.length} previous sessions for clientId=${clientId} (new session=${newSessionId})`);
|
|
86878
86852
|
for (const sessionId of sessionsToRemove) sessionIds.delete(sessionId);
|
|
86879
86853
|
}
|
|
86880
86854
|
handleInspectorConnection(sessionId) {
|
|
@@ -86894,11 +86868,14 @@ var ConnectionManager = class {
|
|
|
86894
86868
|
}
|
|
86895
86869
|
}
|
|
86896
86870
|
/**
|
|
86897
|
-
*
|
|
86898
|
-
|
|
86899
|
-
|
|
86900
|
-
|
|
86901
|
-
|
|
86871
|
+
* Get the currently active Inspector (browser) transport
|
|
86872
|
+
*/
|
|
86873
|
+
getInspectorTransport() {
|
|
86874
|
+
if (!this.latestInspectorSessionId) return null;
|
|
86875
|
+
return this.transports[this.latestInspectorSessionId] || null;
|
|
86876
|
+
}
|
|
86877
|
+
/**
|
|
86878
|
+
* Bind watcher (e.g. VS Code/ACP) to Inspector (browser)
|
|
86902
86879
|
*/
|
|
86903
86880
|
handleWatcherConnection(sessionId, clientId, puppetId, transport) {
|
|
86904
86881
|
this.cleanupPreviousWatchers(clientId, sessionId);
|
|
@@ -87082,11 +87059,17 @@ async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
|
87082
87059
|
const url$1 = new URL(req.url ?? "", `http://${host}:${port}`);
|
|
87083
87060
|
const transport = new _modelcontextprotocol_sdk_server_sse_js.SSEServerTransport("/__mcp__/messages", res);
|
|
87084
87061
|
const sessionId = transport.sessionId;
|
|
87085
|
-
const clientId = url$1.searchParams.get("clientId") ||
|
|
87062
|
+
const clientId = url$1.searchParams.get("clientId") || `agent-${sessionId}`;
|
|
87086
87063
|
const puppetId = url$1.searchParams.get("puppetId") || "inspector";
|
|
87064
|
+
console.log(`[dev-inspector] [sse] New connection request: clientId=${clientId}, puppetId=${puppetId}, sessionId=${sessionId}`);
|
|
87087
87065
|
connectionManager.registerTransport(sessionId, transport);
|
|
87088
|
-
if (clientId === "inspector")
|
|
87089
|
-
|
|
87066
|
+
if (clientId === "inspector") {
|
|
87067
|
+
console.log(`[dev-inspector] [sse] Handling Inspector connection: ${sessionId}`);
|
|
87068
|
+
connectionManager.handleInspectorConnection(sessionId);
|
|
87069
|
+
} else {
|
|
87070
|
+
console.log(`[dev-inspector] [sse] Handling Watcher connection: ${sessionId} (binding to ${puppetId})`);
|
|
87071
|
+
connectionManager.handleWatcherConnection(sessionId, clientId, puppetId, transport);
|
|
87072
|
+
}
|
|
87090
87073
|
await mcpServer.connect(transport);
|
|
87091
87074
|
} catch (error) {
|
|
87092
87075
|
console.error("Error establishing SSE connection:", error);
|
|
@@ -88100,6 +88083,7 @@ var ACPLanguageModel = class {
|
|
|
88100
88083
|
try {
|
|
88101
88084
|
await this.ensureConnected();
|
|
88102
88085
|
const promptContent = convertAiSdkMessagesToAcp(options, this.isFreshSession);
|
|
88086
|
+
console.log(`###########`, promptContent);
|
|
88103
88087
|
this.isFreshSession = false;
|
|
88104
88088
|
let accumulatedText = "";
|
|
88105
88089
|
const toolCalls = [];
|
|
@@ -88309,6 +88293,19 @@ function createACPProvider(config) {
|
|
|
88309
88293
|
//#endregion
|
|
88310
88294
|
//#region src/middleware/acp-middleware.ts
|
|
88311
88295
|
/**
|
|
88296
|
+
* Check if a command exists in the system PATH
|
|
88297
|
+
* Skips check for npx since it always exists
|
|
88298
|
+
*/
|
|
88299
|
+
function checkCommandExists(command) {
|
|
88300
|
+
if (command === "npx" || command === "node") return true;
|
|
88301
|
+
try {
|
|
88302
|
+
(0, child_process.execSync)(`which ${command}`, { stdio: "ignore" });
|
|
88303
|
+
return true;
|
|
88304
|
+
} catch {
|
|
88305
|
+
return false;
|
|
88306
|
+
}
|
|
88307
|
+
}
|
|
88308
|
+
/**
|
|
88312
88309
|
* Provider manager - stores one provider per agent config
|
|
88313
88310
|
* Key: agentKey (command:args), Value: ProviderEntry
|
|
88314
88311
|
*/
|
|
@@ -88372,14 +88369,33 @@ async function loadMcpToolsV5(transport) {
|
|
|
88372
88369
|
return tools;
|
|
88373
88370
|
}
|
|
88374
88371
|
/**
|
|
88372
|
+
* Default system instructions for DevInspector - provides AI guidance
|
|
88373
|
+
*/
|
|
88374
|
+
const DEFAULT_SYSTEM_INSTRUCTIONS = `# DevInspector Context
|
|
88375
|
+
|
|
88376
|
+
You are connected to a web app with DevInspector. Available tools:
|
|
88377
|
+
|
|
88378
|
+
- **list_inspections**: Check pending element inspections from user
|
|
88379
|
+
- **capture_element_context**: Activate visual selector to capture UI elements
|
|
88380
|
+
- **update_inspection_status**: Update inspection status with progress/results
|
|
88381
|
+
- **execute_page_script**: Run JavaScript in browser context
|
|
88382
|
+
- **chrome_devtools**: Access Chrome DevTools for network, console, performance
|
|
88383
|
+
|
|
88384
|
+
Workflow: Check \`list_inspections\` first. If there are pending items, help resolve them. Otherwise, assist with the user's request.`;
|
|
88385
|
+
/**
|
|
88375
88386
|
* Get an active transport from the connection manager
|
|
88376
88387
|
*/
|
|
88377
88388
|
function getActiveTransport() {
|
|
88378
88389
|
const connectionManager = getConnectionManager();
|
|
88379
88390
|
if (!connectionManager) return null;
|
|
88380
|
-
|
|
88381
|
-
|
|
88382
|
-
|
|
88391
|
+
return connectionManager.getInspectorTransport() || connectionManager.transports[Object.keys(connectionManager.transports)[0]];
|
|
88392
|
+
}
|
|
88393
|
+
/**
|
|
88394
|
+
* Get specifically the inspector transport for context and tools
|
|
88395
|
+
*/
|
|
88396
|
+
function getInspectorTransport() {
|
|
88397
|
+
const connectionManager = getConnectionManager();
|
|
88398
|
+
return connectionManager ? connectionManager.getInspectorTransport() : null;
|
|
88383
88399
|
}
|
|
88384
88400
|
function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
88385
88401
|
/**
|
|
@@ -88426,6 +88442,14 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88426
88442
|
console.log(`[dev-inspector] [acp] Reusing existing provider for ${agent.name}`);
|
|
88427
88443
|
provider = providerEntry.provider;
|
|
88428
88444
|
} else {
|
|
88445
|
+
if (!checkCommandExists(agent.command)) {
|
|
88446
|
+
const hints = [`Agent "${agent.name}" command not found: "${agent.command}"`];
|
|
88447
|
+
if (agent.installCommand) hints.push(`Install with: ${agent.installCommand}`);
|
|
88448
|
+
if (agent.configHint) hints.push(agent.configHint);
|
|
88449
|
+
if (agent.configLink) hints.push(`Documentation: ${agent.configLink}`);
|
|
88450
|
+
console.error(`\n${hints.join("\n")}\n`);
|
|
88451
|
+
return;
|
|
88452
|
+
}
|
|
88429
88453
|
console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
|
|
88430
88454
|
provider = createACPProvider({
|
|
88431
88455
|
command: agent.command,
|
|
@@ -88452,7 +88476,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88452
88476
|
}
|
|
88453
88477
|
console.log(`[dev-inspector] [acp] Spawning new process/session for ${agent.name}`);
|
|
88454
88478
|
const initPromise = (async () => {
|
|
88455
|
-
const transport = getActiveTransport();
|
|
88479
|
+
const transport = getInspectorTransport() || getActiveTransport();
|
|
88456
88480
|
let initialTools = {};
|
|
88457
88481
|
if (transport) try {
|
|
88458
88482
|
const rawTools = await loadMcpToolsV5(transport);
|
|
@@ -88484,6 +88508,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88484
88508
|
res.setHeader("Content-Type", "application/json");
|
|
88485
88509
|
res.end(JSON.stringify({ sessionId }));
|
|
88486
88510
|
} catch (error) {
|
|
88511
|
+
if (error instanceof Error && error.message.includes("command not found")) throw error;
|
|
88487
88512
|
console.error("ACP Init Session Error:", error);
|
|
88488
88513
|
if (!res.headersSent) {
|
|
88489
88514
|
res.statusCode = 500;
|
|
@@ -88578,7 +88603,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88578
88603
|
});
|
|
88579
88604
|
await provider.initSession();
|
|
88580
88605
|
}
|
|
88581
|
-
const transport = getActiveTransport();
|
|
88606
|
+
const transport = getInspectorTransport() || getActiveTransport();
|
|
88582
88607
|
let mcpTools = {};
|
|
88583
88608
|
if (transport) mcpTools = await loadMcpToolsV5(transport);
|
|
88584
88609
|
else console.warn("[dev-inspector] [acp] No active MCP transport available, tools will not be loaded");
|
|
@@ -88595,10 +88620,21 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88595
88620
|
abortController.abort();
|
|
88596
88621
|
if (shouldCleanupProvider) provider.cleanup();
|
|
88597
88622
|
});
|
|
88623
|
+
const systemPrompt = agent.acpSystemPrompt ?? acpOptions?.acpSystemPrompt ?? DEFAULT_SYSTEM_INSTRUCTIONS;
|
|
88624
|
+
const enhancedMessages = (0, ai.convertToModelMessages)(messages).map((msg, index$1) => {
|
|
88625
|
+
if (index$1 === 0 && msg.role === "user" && Array.isArray(msg.content)) return {
|
|
88626
|
+
...msg,
|
|
88627
|
+
content: [{
|
|
88628
|
+
type: "text",
|
|
88629
|
+
text: `<system_instructions>\n${systemPrompt}\n</system_instructions>\n\n`
|
|
88630
|
+
}, ...msg.content]
|
|
88631
|
+
};
|
|
88632
|
+
return msg;
|
|
88633
|
+
});
|
|
88598
88634
|
const response = (0, ai.streamText)({
|
|
88599
88635
|
model: provider.languageModel(model, mode),
|
|
88600
88636
|
includeRawChunks: true,
|
|
88601
|
-
messages:
|
|
88637
|
+
messages: enhancedMessages,
|
|
88602
88638
|
abortSignal: abortController.signal,
|
|
88603
88639
|
tools: acpTools(mcpTools),
|
|
88604
88640
|
onError: (error) => {
|
package/dist/config-updater.js
CHANGED
|
@@ -17,6 +17,7 @@ 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 { execSync } from "child_process";
|
|
20
21
|
import fs, { existsSync } from "fs";
|
|
21
22
|
import * as http from "http";
|
|
22
23
|
import * as https from "https";
|
|
@@ -83480,19 +83481,6 @@ async function getOrCreateMcpClient(defKey, def) {
|
|
|
83480
83481
|
mcpClientConnecting.delete(defKey);
|
|
83481
83482
|
}
|
|
83482
83483
|
}
|
|
83483
|
-
async function releaseMcpClient(defKey) {
|
|
83484
|
-
const entry = mcpClientPool.get(defKey);
|
|
83485
|
-
if (!entry) return;
|
|
83486
|
-
entry.refCount -= 1;
|
|
83487
|
-
if (entry.refCount <= 0) {
|
|
83488
|
-
mcpClientPool.delete(defKey);
|
|
83489
|
-
try {
|
|
83490
|
-
await entry.client.close();
|
|
83491
|
-
} catch (err) {
|
|
83492
|
-
console.error("Error closing MCP client:", err);
|
|
83493
|
-
}
|
|
83494
|
-
}
|
|
83495
|
-
}
|
|
83496
83484
|
var cleanupAllPooledClients = async () => {
|
|
83497
83485
|
const entries = Array.from(mcpClientPool.entries());
|
|
83498
83486
|
mcpClientPool.clear();
|
|
@@ -83550,12 +83538,7 @@ async function composeMcpDepTools(mcpConfig, filterIn) {
|
|
|
83550
83538
|
console.error(`Error creating MCP client for ${name}:`, error);
|
|
83551
83539
|
}
|
|
83552
83540
|
}
|
|
83553
|
-
const cleanupClients = async () => {
|
|
83554
|
-
await Promise.all(acquiredKeys.map((k) => releaseMcpClient(k)));
|
|
83555
|
-
acquiredKeys.length = 0;
|
|
83556
|
-
Object.keys(allTools).forEach((key) => delete allTools[key]);
|
|
83557
|
-
Object.keys(allClients).forEach((key) => delete allClients[key]);
|
|
83558
|
-
};
|
|
83541
|
+
const cleanupClients = async () => {};
|
|
83559
83542
|
return {
|
|
83560
83543
|
tools: allTools,
|
|
83561
83544
|
clients: allClients,
|
|
@@ -86357,17 +86340,6 @@ var ComposableMCPServer = class extends Server {
|
|
|
86357
86340
|
server: this,
|
|
86358
86341
|
toolNames: Object.keys(allTools)
|
|
86359
86342
|
});
|
|
86360
|
-
this.onclose = async () => {
|
|
86361
|
-
await cleanupClients();
|
|
86362
|
-
await this.disposePlugins();
|
|
86363
|
-
await this.logger.info(`[${name}] Event: closed - cleaned up dependent clients and plugins`);
|
|
86364
|
-
};
|
|
86365
|
-
this.onerror = async (error) => {
|
|
86366
|
-
await this.logger.error(`[${name}] Event: error - ${error?.stack ?? String(error)}`);
|
|
86367
|
-
await cleanupClients();
|
|
86368
|
-
await this.disposePlugins();
|
|
86369
|
-
await this.logger.info(`[${name}] Action: cleaned up dependent clients and plugins`);
|
|
86370
|
-
};
|
|
86371
86343
|
const toolNameToDetailList = Object.entries(allTools);
|
|
86372
86344
|
const publicToolNames = this.getPublicToolNames();
|
|
86373
86345
|
const hiddenToolNames = this.getHiddenToolNames();
|
|
@@ -86880,6 +86852,7 @@ var ConnectionManager = class {
|
|
|
86880
86852
|
transport.onclose = () => this.removeTransport(sessionId);
|
|
86881
86853
|
}
|
|
86882
86854
|
removeTransport(sessionId) {
|
|
86855
|
+
console.log(`[dev-inspector] [connection-manager] Removing transport: ${sessionId}`);
|
|
86883
86856
|
delete this.transports[sessionId];
|
|
86884
86857
|
for (const [_clientId, sessionIds] of this.watchersByClientId) if (sessionIds.has(sessionId)) {
|
|
86885
86858
|
sessionIds.delete(sessionId);
|
|
@@ -86910,6 +86883,7 @@ var ConnectionManager = class {
|
|
|
86910
86883
|
}
|
|
86911
86884
|
sessionsToRemove.push(existingSessionId);
|
|
86912
86885
|
}
|
|
86886
|
+
if (sessionsToRemove.length > 0) console.log(`[dev-inspector] [connection-manager] Cleaned up ${sessionsToRemove.length} previous sessions for clientId=${clientId} (new session=${newSessionId})`);
|
|
86913
86887
|
for (const sessionId of sessionsToRemove) sessionIds.delete(sessionId);
|
|
86914
86888
|
}
|
|
86915
86889
|
handleInspectorConnection(sessionId) {
|
|
@@ -86929,11 +86903,14 @@ var ConnectionManager = class {
|
|
|
86929
86903
|
}
|
|
86930
86904
|
}
|
|
86931
86905
|
/**
|
|
86932
|
-
*
|
|
86933
|
-
|
|
86934
|
-
|
|
86935
|
-
|
|
86936
|
-
|
|
86906
|
+
* Get the currently active Inspector (browser) transport
|
|
86907
|
+
*/
|
|
86908
|
+
getInspectorTransport() {
|
|
86909
|
+
if (!this.latestInspectorSessionId) return null;
|
|
86910
|
+
return this.transports[this.latestInspectorSessionId] || null;
|
|
86911
|
+
}
|
|
86912
|
+
/**
|
|
86913
|
+
* Bind watcher (e.g. VS Code/ACP) to Inspector (browser)
|
|
86937
86914
|
*/
|
|
86938
86915
|
handleWatcherConnection(sessionId, clientId, puppetId, transport) {
|
|
86939
86916
|
this.cleanupPreviousWatchers(clientId, sessionId);
|
|
@@ -87117,11 +87094,17 @@ async function handleSseConnection(req, res, serverContext, connectionManager) {
|
|
|
87117
87094
|
const url = new URL(req.url ?? "", `http://${host}:${port}`);
|
|
87118
87095
|
const transport = new SSEServerTransport("/__mcp__/messages", res);
|
|
87119
87096
|
const sessionId = transport.sessionId;
|
|
87120
|
-
const clientId = url.searchParams.get("clientId") ||
|
|
87097
|
+
const clientId = url.searchParams.get("clientId") || `agent-${sessionId}`;
|
|
87121
87098
|
const puppetId = url.searchParams.get("puppetId") || "inspector";
|
|
87099
|
+
console.log(`[dev-inspector] [sse] New connection request: clientId=${clientId}, puppetId=${puppetId}, sessionId=${sessionId}`);
|
|
87122
87100
|
connectionManager.registerTransport(sessionId, transport);
|
|
87123
|
-
if (clientId === "inspector")
|
|
87124
|
-
|
|
87101
|
+
if (clientId === "inspector") {
|
|
87102
|
+
console.log(`[dev-inspector] [sse] Handling Inspector connection: ${sessionId}`);
|
|
87103
|
+
connectionManager.handleInspectorConnection(sessionId);
|
|
87104
|
+
} else {
|
|
87105
|
+
console.log(`[dev-inspector] [sse] Handling Watcher connection: ${sessionId} (binding to ${puppetId})`);
|
|
87106
|
+
connectionManager.handleWatcherConnection(sessionId, clientId, puppetId, transport);
|
|
87107
|
+
}
|
|
87125
87108
|
await mcpServer.connect(transport);
|
|
87126
87109
|
} catch (error) {
|
|
87127
87110
|
console.error("Error establishing SSE connection:", error);
|
|
@@ -88135,6 +88118,7 @@ var ACPLanguageModel = class {
|
|
|
88135
88118
|
try {
|
|
88136
88119
|
await this.ensureConnected();
|
|
88137
88120
|
const promptContent = convertAiSdkMessagesToAcp(options, this.isFreshSession);
|
|
88121
|
+
console.log(`###########`, promptContent);
|
|
88138
88122
|
this.isFreshSession = false;
|
|
88139
88123
|
let accumulatedText = "";
|
|
88140
88124
|
const toolCalls = [];
|
|
@@ -88344,6 +88328,19 @@ function createACPProvider(config) {
|
|
|
88344
88328
|
//#endregion
|
|
88345
88329
|
//#region src/middleware/acp-middleware.ts
|
|
88346
88330
|
/**
|
|
88331
|
+
* Check if a command exists in the system PATH
|
|
88332
|
+
* Skips check for npx since it always exists
|
|
88333
|
+
*/
|
|
88334
|
+
function checkCommandExists(command) {
|
|
88335
|
+
if (command === "npx" || command === "node") return true;
|
|
88336
|
+
try {
|
|
88337
|
+
execSync(`which ${command}`, { stdio: "ignore" });
|
|
88338
|
+
return true;
|
|
88339
|
+
} catch {
|
|
88340
|
+
return false;
|
|
88341
|
+
}
|
|
88342
|
+
}
|
|
88343
|
+
/**
|
|
88347
88344
|
* Provider manager - stores one provider per agent config
|
|
88348
88345
|
* Key: agentKey (command:args), Value: ProviderEntry
|
|
88349
88346
|
*/
|
|
@@ -88407,14 +88404,33 @@ async function loadMcpToolsV5(transport) {
|
|
|
88407
88404
|
return tools;
|
|
88408
88405
|
}
|
|
88409
88406
|
/**
|
|
88407
|
+
* Default system instructions for DevInspector - provides AI guidance
|
|
88408
|
+
*/
|
|
88409
|
+
const DEFAULT_SYSTEM_INSTRUCTIONS = `# DevInspector Context
|
|
88410
|
+
|
|
88411
|
+
You are connected to a web app with DevInspector. Available tools:
|
|
88412
|
+
|
|
88413
|
+
- **list_inspections**: Check pending element inspections from user
|
|
88414
|
+
- **capture_element_context**: Activate visual selector to capture UI elements
|
|
88415
|
+
- **update_inspection_status**: Update inspection status with progress/results
|
|
88416
|
+
- **execute_page_script**: Run JavaScript in browser context
|
|
88417
|
+
- **chrome_devtools**: Access Chrome DevTools for network, console, performance
|
|
88418
|
+
|
|
88419
|
+
Workflow: Check \`list_inspections\` first. If there are pending items, help resolve them. Otherwise, assist with the user's request.`;
|
|
88420
|
+
/**
|
|
88410
88421
|
* Get an active transport from the connection manager
|
|
88411
88422
|
*/
|
|
88412
88423
|
function getActiveTransport() {
|
|
88413
88424
|
const connectionManager = getConnectionManager();
|
|
88414
88425
|
if (!connectionManager) return null;
|
|
88415
|
-
|
|
88416
|
-
|
|
88417
|
-
|
|
88426
|
+
return connectionManager.getInspectorTransport() || connectionManager.transports[Object.keys(connectionManager.transports)[0]];
|
|
88427
|
+
}
|
|
88428
|
+
/**
|
|
88429
|
+
* Get specifically the inspector transport for context and tools
|
|
88430
|
+
*/
|
|
88431
|
+
function getInspectorTransport() {
|
|
88432
|
+
const connectionManager = getConnectionManager();
|
|
88433
|
+
return connectionManager ? connectionManager.getInspectorTransport() : null;
|
|
88418
88434
|
}
|
|
88419
88435
|
function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
88420
88436
|
/**
|
|
@@ -88461,6 +88477,14 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88461
88477
|
console.log(`[dev-inspector] [acp] Reusing existing provider for ${agent.name}`);
|
|
88462
88478
|
provider = providerEntry.provider;
|
|
88463
88479
|
} else {
|
|
88480
|
+
if (!checkCommandExists(agent.command)) {
|
|
88481
|
+
const hints = [`Agent "${agent.name}" command not found: "${agent.command}"`];
|
|
88482
|
+
if (agent.installCommand) hints.push(`Install with: ${agent.installCommand}`);
|
|
88483
|
+
if (agent.configHint) hints.push(agent.configHint);
|
|
88484
|
+
if (agent.configLink) hints.push(`Documentation: ${agent.configLink}`);
|
|
88485
|
+
console.error(`\n${hints.join("\n")}\n`);
|
|
88486
|
+
return;
|
|
88487
|
+
}
|
|
88464
88488
|
console.log(`[dev-inspector] [acp] Creating new global provider for ${agent.name}`);
|
|
88465
88489
|
provider = createACPProvider({
|
|
88466
88490
|
command: agent.command,
|
|
@@ -88487,7 +88511,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88487
88511
|
}
|
|
88488
88512
|
console.log(`[dev-inspector] [acp] Spawning new process/session for ${agent.name}`);
|
|
88489
88513
|
const initPromise = (async () => {
|
|
88490
|
-
const transport = getActiveTransport();
|
|
88514
|
+
const transport = getInspectorTransport() || getActiveTransport();
|
|
88491
88515
|
let initialTools = {};
|
|
88492
88516
|
if (transport) try {
|
|
88493
88517
|
const rawTools = await loadMcpToolsV5(transport);
|
|
@@ -88519,6 +88543,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88519
88543
|
res.setHeader("Content-Type", "application/json");
|
|
88520
88544
|
res.end(JSON.stringify({ sessionId }));
|
|
88521
88545
|
} catch (error) {
|
|
88546
|
+
if (error instanceof Error && error.message.includes("command not found")) throw error;
|
|
88522
88547
|
console.error("ACP Init Session Error:", error);
|
|
88523
88548
|
if (!res.headersSent) {
|
|
88524
88549
|
res.statusCode = 500;
|
|
@@ -88613,7 +88638,7 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88613
88638
|
});
|
|
88614
88639
|
await provider.initSession();
|
|
88615
88640
|
}
|
|
88616
|
-
const transport = getActiveTransport();
|
|
88641
|
+
const transport = getInspectorTransport() || getActiveTransport();
|
|
88617
88642
|
let mcpTools = {};
|
|
88618
88643
|
if (transport) mcpTools = await loadMcpToolsV5(transport);
|
|
88619
88644
|
else console.warn("[dev-inspector] [acp] No active MCP transport available, tools will not be loaded");
|
|
@@ -88630,10 +88655,21 @@ function setupAcpMiddleware(middlewares, serverContext, acpOptions) {
|
|
|
88630
88655
|
abortController.abort();
|
|
88631
88656
|
if (shouldCleanupProvider) provider.cleanup();
|
|
88632
88657
|
});
|
|
88658
|
+
const systemPrompt = agent.acpSystemPrompt ?? acpOptions?.acpSystemPrompt ?? DEFAULT_SYSTEM_INSTRUCTIONS;
|
|
88659
|
+
const enhancedMessages = convertToModelMessages(messages).map((msg, index$1) => {
|
|
88660
|
+
if (index$1 === 0 && msg.role === "user" && Array.isArray(msg.content)) return {
|
|
88661
|
+
...msg,
|
|
88662
|
+
content: [{
|
|
88663
|
+
type: "text",
|
|
88664
|
+
text: `<system_instructions>\n${systemPrompt}\n</system_instructions>\n\n`
|
|
88665
|
+
}, ...msg.content]
|
|
88666
|
+
};
|
|
88667
|
+
return msg;
|
|
88668
|
+
});
|
|
88633
88669
|
const response = streamText({
|
|
88634
88670
|
model: provider.languageModel(model, mode),
|
|
88635
88671
|
includeRawChunks: true,
|
|
88636
|
-
messages:
|
|
88672
|
+
messages: enhancedMessages,
|
|
88637
88673
|
abortSignal: abortController.signal,
|
|
88638
88674
|
tools: acpTools(mcpTools),
|
|
88639
88675
|
onError: (error) => {
|
package/dist/index.cjs
CHANGED
|
@@ -23,7 +23,7 @@ var browser_launcher_exports = /* @__PURE__ */ require_chunk.__export({ launchBr
|
|
|
23
23
|
*/
|
|
24
24
|
async function launchBrowserWithDevTools(options) {
|
|
25
25
|
const { url, serverContext } = options;
|
|
26
|
-
const sseUrl = `http://${serverContext.host === "0.0.0.0" ? "localhost" : serverContext.host || "localhost"}:${serverContext.port || 5173}/__mcp__/sse?clientId=
|
|
26
|
+
const sseUrl = `http://${serverContext.host === "0.0.0.0" ? "localhost" : serverContext.host || "localhost"}:${serverContext.port || 5173}/__mcp__/sse?clientId=temp-browser-launcher`;
|
|
27
27
|
let client = null;
|
|
28
28
|
try {
|
|
29
29
|
client = new _modelcontextprotocol_sdk_client_index_js.Client({
|
|
@@ -44,6 +44,8 @@ async function launchBrowserWithDevTools(options) {
|
|
|
44
44
|
} catch (error) {
|
|
45
45
|
console.error(`[dev-inspector] ⚠️ Failed to auto-open browser:`, error instanceof Error ? error.message : String(error));
|
|
46
46
|
return false;
|
|
47
|
+
} finally {
|
|
48
|
+
await client?.close().catch(() => {});
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
var init_browser_launcher = require_chunk.__esmMin((() => {}));
|
package/dist/index.d.cts
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,18 @@ 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;
|
|
68
85
|
}
|
|
69
86
|
//#endregion
|
|
70
87
|
//#region src/utils/create-plugin.d.ts
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as unplugin1 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,18 @@ 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;
|
|
68
85
|
}
|
|
69
86
|
//#endregion
|
|
70
87
|
//#region src/utils/create-plugin.d.ts
|
|
@@ -134,10 +151,10 @@ interface DevInspectorOptions extends McpConfigOptions, AcpOptions {
|
|
|
134
151
|
}
|
|
135
152
|
//#endregion
|
|
136
153
|
//#region src/core.d.ts
|
|
137
|
-
declare const unplugin:
|
|
154
|
+
declare const unplugin: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
|
|
138
155
|
//#endregion
|
|
139
156
|
//#region src/core-external.d.ts
|
|
140
|
-
declare const unpluginExternal:
|
|
157
|
+
declare const unpluginExternal: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
|
|
141
158
|
//#endregion
|
|
142
159
|
//#region src/turbopack.d.ts
|
|
143
160
|
interface TurbopackDevInspectorOptions extends DevInspectorOptions {
|
|
@@ -162,7 +179,7 @@ interface TurbopackDevInspectorOptions extends DevInspectorOptions {
|
|
|
162
179
|
declare function turbopackDevInspector(options?: TurbopackDevInspectorOptions): any;
|
|
163
180
|
//#endregion
|
|
164
181
|
//#region src/index.d.ts
|
|
165
|
-
declare const external:
|
|
182
|
+
declare const external: unplugin1.UnpluginInstance<DevInspectorOptions | undefined, boolean>;
|
|
166
183
|
declare module "virtual:dev-inspector-mcp" {}
|
|
167
184
|
//#endregion
|
|
168
185
|
export { type CustomEditorConfig, type DevInspectorOptions, type EditorId, type McpConfigOptions, type TurbopackDevInspectorOptions, unplugin as default, unplugin, external, turbopackDevInspector, unpluginExternal };
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var browser_launcher_exports = /* @__PURE__ */ __export({ launchBrowserWithDevTo
|
|
|
19
19
|
*/
|
|
20
20
|
async function launchBrowserWithDevTools(options) {
|
|
21
21
|
const { url, serverContext } = options;
|
|
22
|
-
const sseUrl = `http://${serverContext.host === "0.0.0.0" ? "localhost" : serverContext.host || "localhost"}:${serverContext.port || 5173}/__mcp__/sse?clientId=
|
|
22
|
+
const sseUrl = `http://${serverContext.host === "0.0.0.0" ? "localhost" : serverContext.host || "localhost"}:${serverContext.port || 5173}/__mcp__/sse?clientId=temp-browser-launcher`;
|
|
23
23
|
let client = null;
|
|
24
24
|
try {
|
|
25
25
|
client = new Client({
|
|
@@ -40,6 +40,8 @@ async function launchBrowserWithDevTools(options) {
|
|
|
40
40
|
} catch (error) {
|
|
41
41
|
console.error(`[dev-inspector] ⚠️ Failed to auto-open browser:`, error instanceof Error ? error.message : String(error));
|
|
42
42
|
return false;
|
|
43
|
+
} finally {
|
|
44
|
+
await client?.close().catch(() => {});
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
var init_browser_launcher = __esmMin((() => {}));
|
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.38",
|
|
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",
|
|
@@ -186,4 +186,4 @@
|
|
|
186
186
|
"publishConfig": {
|
|
187
187
|
"access": "public"
|
|
188
188
|
}
|
|
189
|
-
}
|
|
189
|
+
}
|