@mcpc-tech/unplugin-dev-inspector-mcp 0.0.10 → 0.0.12
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 +19 -1
- package/dist/cli.cjs +180 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +177 -0
- package/dist/config-updater.cjs +88171 -0
- package/dist/config-updater.js +88183 -0
- package/dist/index.cjs +21 -88259
- package/dist/index.js +13 -88286
- package/dist/loader.cjs +45 -0
- package/dist/loader.d.cts +15 -0
- package/dist/loader.d.ts +15 -0
- package/dist/loader.js +42 -0
- package/dist/standalone-server.cjs +2 -102
- package/dist/standalone-server.js +1 -100
- package/dist/vue-transform.cjs +140 -0
- package/dist/vue-transform.js +126 -0
- package/package.json +15 -1
package/README.md
CHANGED
|
@@ -289,7 +289,25 @@ export default {
|
|
|
289
289
|
- "This API call is failing" → AI analyzes network requests, timing, responses
|
|
290
290
|
- "Where is this component?" → Jump to source file and line number
|
|
291
291
|
|
|
292
|
-
##
|
|
292
|
+
## Two Workflow Modes
|
|
293
|
+
|
|
294
|
+
DevInspector offers two ways to interact with your AI, depending on your preference:
|
|
295
|
+
|
|
296
|
+
### 1. Editor Mode
|
|
297
|
+
**Best for:** Code-heavy tasks, refactoring, and maintaining flow.
|
|
298
|
+
|
|
299
|
+
- **How it works:** You use your IDE's AI assistant (Cursor, Windsurf, Copilot).
|
|
300
|
+
- **The Flow:** Click an element in the browser -> The context (source, props, styles) is sent to your Editor via MCP -> You ask your Editor to fix it.
|
|
301
|
+
- **Why:** Keeps you in your coding environment.
|
|
302
|
+
|
|
303
|
+
### 2. Inspector Bar Mode (Recommended)
|
|
304
|
+
**Best for:** Quick fixes, visual tweaks, or if you don't use an AI editor.
|
|
305
|
+
|
|
306
|
+
- **How it works:** You use the floating "Inspector Bar" directly in the browser.
|
|
307
|
+
- **The Flow:** Click "Ask AI" in the browser -> Select an agent (e.g., Claude Code, Custom Script) -> The agent runs in your terminal but interacts with the browser overlay.
|
|
308
|
+
- **Why:** No context switching. Great for "what is this?" questions or network debugging.
|
|
309
|
+
|
|
310
|
+
## MCP Tools
|
|
293
311
|
|
|
294
312
|
### `capture_element_context`
|
|
295
313
|
Activates visual selector. Returns source location, DOM hierarchy, styles, dimensions, and user notes.
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const require_chunk = require('./chunk.cjs');
|
|
3
|
+
const require_config_updater = require('./config-updater.cjs');
|
|
4
|
+
let node_http = require("node:http");
|
|
5
|
+
node_http = require_chunk.__toESM(node_http);
|
|
6
|
+
|
|
7
|
+
//#region src/utils/standalone-server.ts
|
|
8
|
+
var StandaloneServer = class {
|
|
9
|
+
server;
|
|
10
|
+
middlewares = [];
|
|
11
|
+
port = 0;
|
|
12
|
+
host = "localhost";
|
|
13
|
+
stack = [];
|
|
14
|
+
constructor() {
|
|
15
|
+
this.server = node_http.default.createServer(async (req, res) => {
|
|
16
|
+
let index = 0;
|
|
17
|
+
const next = async () => {
|
|
18
|
+
if (index >= this.middlewares.length) {
|
|
19
|
+
if (!res.writableEnded) {
|
|
20
|
+
res.statusCode = 404;
|
|
21
|
+
res.end("Not Found");
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const layer = this.middlewares[index++];
|
|
26
|
+
if ((req.url || "/").startsWith(layer.route)) try {
|
|
27
|
+
const originalUrl = req.url;
|
|
28
|
+
if (layer.route !== "/" && req.url) {}
|
|
29
|
+
await layer.handle(req, res, next);
|
|
30
|
+
if (layer.route !== "/") req.url = originalUrl;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("Middleware error:", error);
|
|
33
|
+
if (!res.writableEnded) {
|
|
34
|
+
res.statusCode = 500;
|
|
35
|
+
res.end("Internal Server Error");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else next();
|
|
39
|
+
};
|
|
40
|
+
await next();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
use(routeOrHandle, handle) {
|
|
44
|
+
let route = "/";
|
|
45
|
+
let handler;
|
|
46
|
+
if (typeof routeOrHandle === "string") {
|
|
47
|
+
route = routeOrHandle;
|
|
48
|
+
if (!handle) throw new Error("Handler is required when route is provided");
|
|
49
|
+
handler = handle;
|
|
50
|
+
} else handler = routeOrHandle;
|
|
51
|
+
this.middlewares.push({
|
|
52
|
+
route,
|
|
53
|
+
handle: handler
|
|
54
|
+
});
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
listen(...args) {
|
|
58
|
+
return this.server.listen(...args);
|
|
59
|
+
}
|
|
60
|
+
async start(options = {}) {
|
|
61
|
+
const startPort = options.port || 8888;
|
|
62
|
+
this.host = options.host || "localhost";
|
|
63
|
+
for (let port = startPort; port < startPort + 100; port++) try {
|
|
64
|
+
await new Promise((resolve, reject) => {
|
|
65
|
+
this.server.listen(port, this.host, () => {
|
|
66
|
+
this.port = port;
|
|
67
|
+
resolve();
|
|
68
|
+
});
|
|
69
|
+
this.server.on("error", (err) => {
|
|
70
|
+
if (err.code === "EADDRINUSE") {
|
|
71
|
+
this.server.close();
|
|
72
|
+
reject(err);
|
|
73
|
+
} else reject(err);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
host: this.host,
|
|
78
|
+
port: this.port
|
|
79
|
+
};
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error.code !== "EADDRINUSE") throw error;
|
|
82
|
+
}
|
|
83
|
+
throw new Error(`Could not find a free port starting from ${startPort}`);
|
|
84
|
+
}
|
|
85
|
+
close() {
|
|
86
|
+
this.server.close();
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
let globalServer = null;
|
|
90
|
+
async function startStandaloneServer(options = {}) {
|
|
91
|
+
if (globalServer) return {
|
|
92
|
+
server: globalServer,
|
|
93
|
+
host: globalServer.host,
|
|
94
|
+
port: globalServer.port
|
|
95
|
+
};
|
|
96
|
+
globalServer = new StandaloneServer();
|
|
97
|
+
const { host, port } = await globalServer.start(options);
|
|
98
|
+
return {
|
|
99
|
+
server: globalServer,
|
|
100
|
+
host,
|
|
101
|
+
port
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/cli.ts
|
|
107
|
+
/**
|
|
108
|
+
* Standalone dev-inspector server for Turbopack/other non-webpack builds
|
|
109
|
+
*
|
|
110
|
+
* Usage:
|
|
111
|
+
* npx dev-inspector-server
|
|
112
|
+
* npx dev-inspector-server --port 8888 --host localhost
|
|
113
|
+
*/
|
|
114
|
+
async function main() {
|
|
115
|
+
const args = process.argv.slice(2);
|
|
116
|
+
let port = 8888;
|
|
117
|
+
let host = "localhost";
|
|
118
|
+
for (let i = 0; i < args.length; i++) if (args[i] === "--port" && args[i + 1]) {
|
|
119
|
+
port = parseInt(args[i + 1], 10);
|
|
120
|
+
i++;
|
|
121
|
+
} else if (args[i] === "--host" && args[i + 1]) {
|
|
122
|
+
host = args[i + 1];
|
|
123
|
+
i++;
|
|
124
|
+
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
125
|
+
console.log(`
|
|
126
|
+
dev-inspector-server - Standalone MCP server for dev-inspector
|
|
127
|
+
|
|
128
|
+
Usage:
|
|
129
|
+
npx dev-inspector-server [options]
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
--port <number> Port to run the server on (default: 8888)
|
|
133
|
+
--host <string> Host to bind to (default: localhost)
|
|
134
|
+
--help, -h Show this help message
|
|
135
|
+
|
|
136
|
+
Example:
|
|
137
|
+
npx dev-inspector-server --port 3001
|
|
138
|
+
`);
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const { server, host: actualHost, port: actualPort } = await startStandaloneServer({
|
|
143
|
+
port,
|
|
144
|
+
host
|
|
145
|
+
});
|
|
146
|
+
const serverContext = {
|
|
147
|
+
host: actualHost,
|
|
148
|
+
port: actualPort
|
|
149
|
+
};
|
|
150
|
+
const baseUrl = `http://${actualHost === "0.0.0.0" ? "localhost" : actualHost}:${actualPort}/__mcp__/sse`;
|
|
151
|
+
console.log(`
|
|
152
|
+
╔══════════════════════════════════════════════════════════╗
|
|
153
|
+
║ 🔍 Dev Inspector MCP Server ║
|
|
154
|
+
╠══════════════════════════════════════════════════════════╣
|
|
155
|
+
║ ║
|
|
156
|
+
║ MCP Endpoint: ${baseUrl.padEnd(40)}║
|
|
157
|
+
║ ║
|
|
158
|
+
║ Use this in your editor's MCP config or with ║
|
|
159
|
+
║ the DevInspector React component. ║
|
|
160
|
+
║ ║
|
|
161
|
+
╚══════════════════════════════════════════════════════════╝
|
|
162
|
+
`);
|
|
163
|
+
require_config_updater.setupMcpMiddleware(server, serverContext);
|
|
164
|
+
require_config_updater.setupAcpMiddleware(server, serverContext, {});
|
|
165
|
+
require_config_updater.setupInspectorMiddleware(server, {});
|
|
166
|
+
await require_config_updater.updateMcpConfigs(process.cwd(), baseUrl, {});
|
|
167
|
+
process.on("SIGINT", () => {
|
|
168
|
+
console.log("\n👋 Shutting down dev-inspector server...");
|
|
169
|
+
process.exit(0);
|
|
170
|
+
});
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error("Failed to start dev-inspector server:", error);
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
main();
|
|
177
|
+
|
|
178
|
+
//#endregion
|
|
179
|
+
exports.StandaloneServer = StandaloneServer;
|
|
180
|
+
exports.startStandaloneServer = startStandaloneServer;
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { i as setupMcpMiddleware, n as setupAcpMiddleware, r as setupInspectorMiddleware, t as updateMcpConfigs } from "./config-updater.js";
|
|
3
|
+
import http from "node:http";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/standalone-server.ts
|
|
6
|
+
var StandaloneServer = class {
|
|
7
|
+
server;
|
|
8
|
+
middlewares = [];
|
|
9
|
+
port = 0;
|
|
10
|
+
host = "localhost";
|
|
11
|
+
stack = [];
|
|
12
|
+
constructor() {
|
|
13
|
+
this.server = http.createServer(async (req, res) => {
|
|
14
|
+
let index = 0;
|
|
15
|
+
const next = async () => {
|
|
16
|
+
if (index >= this.middlewares.length) {
|
|
17
|
+
if (!res.writableEnded) {
|
|
18
|
+
res.statusCode = 404;
|
|
19
|
+
res.end("Not Found");
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const layer = this.middlewares[index++];
|
|
24
|
+
if ((req.url || "/").startsWith(layer.route)) try {
|
|
25
|
+
const originalUrl = req.url;
|
|
26
|
+
if (layer.route !== "/" && req.url) {}
|
|
27
|
+
await layer.handle(req, res, next);
|
|
28
|
+
if (layer.route !== "/") req.url = originalUrl;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("Middleware error:", error);
|
|
31
|
+
if (!res.writableEnded) {
|
|
32
|
+
res.statusCode = 500;
|
|
33
|
+
res.end("Internal Server Error");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else next();
|
|
37
|
+
};
|
|
38
|
+
await next();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
use(routeOrHandle, handle) {
|
|
42
|
+
let route = "/";
|
|
43
|
+
let handler;
|
|
44
|
+
if (typeof routeOrHandle === "string") {
|
|
45
|
+
route = routeOrHandle;
|
|
46
|
+
if (!handle) throw new Error("Handler is required when route is provided");
|
|
47
|
+
handler = handle;
|
|
48
|
+
} else handler = routeOrHandle;
|
|
49
|
+
this.middlewares.push({
|
|
50
|
+
route,
|
|
51
|
+
handle: handler
|
|
52
|
+
});
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
listen(...args) {
|
|
56
|
+
return this.server.listen(...args);
|
|
57
|
+
}
|
|
58
|
+
async start(options = {}) {
|
|
59
|
+
const startPort = options.port || 8888;
|
|
60
|
+
this.host = options.host || "localhost";
|
|
61
|
+
for (let port = startPort; port < startPort + 100; port++) try {
|
|
62
|
+
await new Promise((resolve, reject) => {
|
|
63
|
+
this.server.listen(port, this.host, () => {
|
|
64
|
+
this.port = port;
|
|
65
|
+
resolve();
|
|
66
|
+
});
|
|
67
|
+
this.server.on("error", (err) => {
|
|
68
|
+
if (err.code === "EADDRINUSE") {
|
|
69
|
+
this.server.close();
|
|
70
|
+
reject(err);
|
|
71
|
+
} else reject(err);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
host: this.host,
|
|
76
|
+
port: this.port
|
|
77
|
+
};
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (error.code !== "EADDRINUSE") throw error;
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`Could not find a free port starting from ${startPort}`);
|
|
82
|
+
}
|
|
83
|
+
close() {
|
|
84
|
+
this.server.close();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
let globalServer = null;
|
|
88
|
+
async function startStandaloneServer(options = {}) {
|
|
89
|
+
if (globalServer) return {
|
|
90
|
+
server: globalServer,
|
|
91
|
+
host: globalServer.host,
|
|
92
|
+
port: globalServer.port
|
|
93
|
+
};
|
|
94
|
+
globalServer = new StandaloneServer();
|
|
95
|
+
const { host, port } = await globalServer.start(options);
|
|
96
|
+
return {
|
|
97
|
+
server: globalServer,
|
|
98
|
+
host,
|
|
99
|
+
port
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/cli.ts
|
|
105
|
+
/**
|
|
106
|
+
* Standalone dev-inspector server for Turbopack/other non-webpack builds
|
|
107
|
+
*
|
|
108
|
+
* Usage:
|
|
109
|
+
* npx dev-inspector-server
|
|
110
|
+
* npx dev-inspector-server --port 8888 --host localhost
|
|
111
|
+
*/
|
|
112
|
+
async function main() {
|
|
113
|
+
const args = process.argv.slice(2);
|
|
114
|
+
let port = 8888;
|
|
115
|
+
let host = "localhost";
|
|
116
|
+
for (let i = 0; i < args.length; i++) if (args[i] === "--port" && args[i + 1]) {
|
|
117
|
+
port = parseInt(args[i + 1], 10);
|
|
118
|
+
i++;
|
|
119
|
+
} else if (args[i] === "--host" && args[i + 1]) {
|
|
120
|
+
host = args[i + 1];
|
|
121
|
+
i++;
|
|
122
|
+
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
123
|
+
console.log(`
|
|
124
|
+
dev-inspector-server - Standalone MCP server for dev-inspector
|
|
125
|
+
|
|
126
|
+
Usage:
|
|
127
|
+
npx dev-inspector-server [options]
|
|
128
|
+
|
|
129
|
+
Options:
|
|
130
|
+
--port <number> Port to run the server on (default: 8888)
|
|
131
|
+
--host <string> Host to bind to (default: localhost)
|
|
132
|
+
--help, -h Show this help message
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
npx dev-inspector-server --port 3001
|
|
136
|
+
`);
|
|
137
|
+
process.exit(0);
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const { server, host: actualHost, port: actualPort } = await startStandaloneServer({
|
|
141
|
+
port,
|
|
142
|
+
host
|
|
143
|
+
});
|
|
144
|
+
const serverContext = {
|
|
145
|
+
host: actualHost,
|
|
146
|
+
port: actualPort
|
|
147
|
+
};
|
|
148
|
+
const baseUrl = `http://${actualHost === "0.0.0.0" ? "localhost" : actualHost}:${actualPort}/__mcp__/sse`;
|
|
149
|
+
console.log(`
|
|
150
|
+
╔══════════════════════════════════════════════════════════╗
|
|
151
|
+
║ 🔍 Dev Inspector MCP Server ║
|
|
152
|
+
╠══════════════════════════════════════════════════════════╣
|
|
153
|
+
║ ║
|
|
154
|
+
║ MCP Endpoint: ${baseUrl.padEnd(40)}║
|
|
155
|
+
║ ║
|
|
156
|
+
║ Use this in your editor's MCP config or with ║
|
|
157
|
+
║ the DevInspector React component. ║
|
|
158
|
+
║ ║
|
|
159
|
+
╚══════════════════════════════════════════════════════════╝
|
|
160
|
+
`);
|
|
161
|
+
setupMcpMiddleware(server, serverContext);
|
|
162
|
+
setupAcpMiddleware(server, serverContext, {});
|
|
163
|
+
setupInspectorMiddleware(server, {});
|
|
164
|
+
await updateMcpConfigs(process.cwd(), baseUrl, {});
|
|
165
|
+
process.on("SIGINT", () => {
|
|
166
|
+
console.log("\n👋 Shutting down dev-inspector server...");
|
|
167
|
+
process.exit(0);
|
|
168
|
+
});
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("Failed to start dev-inspector server:", error);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
main();
|
|
175
|
+
|
|
176
|
+
//#endregion
|
|
177
|
+
export { startStandaloneServer as n, StandaloneServer as t };
|