vite-plugin-opencode-assistant 1.1.23 → 1.1.25

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.
@@ -0,0 +1,349 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var mcp_tools_exports = {};
19
+ __export(mcp_tools_exports, {
20
+ CUSTOM_TOOLS: () => CUSTOM_TOOLS,
21
+ TOOL_MAP: () => TOOL_MAP
22
+ });
23
+ module.exports = __toCommonJS(mcp_tools_exports);
24
+ const CUSTOM_TOOLS = [
25
+ {
26
+ name: "devtools_select_page",
27
+ description: "\u9009\u62E9\u5F53\u524D\u9879\u76EE\u4E2D\u7684\u67D0\u4E2A\u9875\u9762\u4F5C\u4E3A\u540E\u7EED\u5DE5\u5177\u64CD\u4F5C\u7684\u76EE\u6807",
28
+ inputSchema: {
29
+ type: "object",
30
+ properties: {
31
+ pageId: { type: "number", description: "\u9875\u9762 ID\uFF08\u4ECE devtools_list_pages \u83B7\u53D6\uFF09" }
32
+ },
33
+ required: ["pageId"]
34
+ }
35
+ },
36
+ {
37
+ name: "devtools_list_pages",
38
+ description: "\u83B7\u53D6\u5F53\u524D\u9879\u76EE\u6240\u6709\u6253\u5F00\u7684\u9875\u9762\u5217\u8868\uFF0C\u542B active\uFF08\u7528\u6237\u6B63\u5728\u6D4F\u89C8\uFF09\u548C selected\uFF08Chrome DevTools \u5F53\u524D\u64CD\u4F5C\u76EE\u6807\uFF09\u6807\u8BB0",
39
+ inputSchema: {
40
+ type: "object",
41
+ properties: {}
42
+ }
43
+ },
44
+ {
45
+ name: "devtools_snapshot",
46
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u53EF\u8BBF\u95EE\u6027\u6811\u5FEB\u7167\uFF0C\u8FD4\u56DE\u5143\u7D20 uid\u3001\u89D2\u8272\u3001\u6587\u672C\u7B49",
47
+ inputSchema: {
48
+ type: "object",
49
+ properties: {
50
+ verbose: { type: "boolean", description: "\u662F\u5426\u83B7\u53D6\u5B8C\u6574\u8282\u70B9\u4FE1\u606F" }
51
+ }
52
+ }
53
+ },
54
+ {
55
+ name: "devtools_screenshot",
56
+ description: "\u622A\u53D6\u5F53\u524D\u9875\u9762\u5C4F\u5E55\u622A\u56FE\uFF0C\u8FD4\u56DE base64 \u56FE\u7247\u6570\u636E",
57
+ inputSchema: {
58
+ type: "object",
59
+ properties: {
60
+ format: { type: "string", description: "\u56FE\u7247\u683C\u5F0F: png \u6216 jpeg" },
61
+ quality: { type: "number", description: "jpeg \u8D28\u91CF 0-100" },
62
+ fullPage: { type: "boolean", description: "\u662F\u5426\u622A\u53D6\u5B8C\u6574\u9875\u9762" }
63
+ }
64
+ }
65
+ },
66
+ {
67
+ name: "devtools_evaluate",
68
+ description: "\u5728\u5F53\u524D\u9875\u9762\u6267\u884C JavaScript \u4EE3\u7801\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF08\u8FD4\u56DE\u503C\u9700\u53EF JSON \u5E8F\u5217\u5316\uFF09",
69
+ inputSchema: {
70
+ type: "object",
71
+ properties: {
72
+ function: { type: "string", description: "JS \u51FD\u6570\u58F0\u660E\uFF0C\u5982 () => document.title" }
73
+ },
74
+ required: ["function"]
75
+ }
76
+ },
77
+ {
78
+ name: "devtools_click",
79
+ description: "\u70B9\u51FB\u9875\u9762\u5143\u7D20",
80
+ inputSchema: {
81
+ type: "object",
82
+ properties: {
83
+ uid: { type: "string", description: "\u5143\u7D20 uid\uFF08\u4ECE devtools_snapshot \u83B7\u53D6\uFF09" },
84
+ dblClick: { type: "boolean", description: "\u662F\u5426\u53CC\u51FB" }
85
+ },
86
+ required: ["uid"]
87
+ }
88
+ },
89
+ {
90
+ name: "devtools_hover",
91
+ description: "\u9F20\u6807\u60AC\u505C\u5728\u9875\u9762\u5143\u7D20\u4E0A",
92
+ inputSchema: {
93
+ type: "object",
94
+ properties: {
95
+ uid: { type: "string", description: "\u5143\u7D20 uid" }
96
+ },
97
+ required: ["uid"]
98
+ }
99
+ },
100
+ {
101
+ name: "devtools_drag",
102
+ description: "\u62D6\u62FD\u9875\u9762\u5143\u7D20",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: {
106
+ uid: { type: "string", description: "\u6E90\u5143\u7D20 uid" },
107
+ targetUid: { type: "string", description: "\u76EE\u6807\u5143\u7D20 uid" }
108
+ },
109
+ required: ["uid", "targetUid"]
110
+ }
111
+ },
112
+ {
113
+ name: "devtools_type",
114
+ description: "\u5728\u805A\u7126\u5143\u7D20\u4E2D\u8F93\u5165\u6587\u672C",
115
+ inputSchema: {
116
+ type: "object",
117
+ properties: {
118
+ text: { type: "string", description: "\u8981\u8F93\u5165\u7684\u6587\u672C" }
119
+ },
120
+ required: ["text"]
121
+ }
122
+ },
123
+ {
124
+ name: "devtools_press_key",
125
+ description: "\u6309\u4E0B\u952E\u76D8\u6309\u952E",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ key: { type: "string", description: "\u6309\u952E\u540D\u79F0\uFF0C\u5982 Enter\u3001Control+A" }
130
+ },
131
+ required: ["key"]
132
+ }
133
+ },
134
+ {
135
+ name: "devtools_fill",
136
+ description: "\u586B\u5199\u8F93\u5165\u6846\u503C\u5E76\u89E6\u53D1 input/change \u4E8B\u4EF6",
137
+ inputSchema: {
138
+ type: "object",
139
+ properties: {
140
+ uid: { type: "string", description: "\u8F93\u5165\u6846\u5143\u7D20 uid" },
141
+ value: { type: "string", description: "\u8981\u586B\u5165\u7684\u503C" }
142
+ },
143
+ required: ["uid", "value"]
144
+ }
145
+ },
146
+ {
147
+ name: "devtools_fill_form",
148
+ description: "\u6279\u91CF\u586B\u5199\u8868\u5355\u5B57\u6BB5",
149
+ inputSchema: {
150
+ type: "object",
151
+ properties: {
152
+ fields: {
153
+ type: "array",
154
+ items: {
155
+ type: "object",
156
+ properties: { uid: { type: "string" }, value: { type: "string" } }
157
+ },
158
+ description: "\u5B57\u6BB5\u6570\u7EC4 [{ uid, value }]"
159
+ }
160
+ },
161
+ required: ["fields"]
162
+ }
163
+ },
164
+ {
165
+ name: "devtools_navigate",
166
+ description: "\u5BFC\u822A\u9875\u9762\uFF08url/reload/back/forward\uFF09",
167
+ inputSchema: {
168
+ type: "object",
169
+ properties: {
170
+ type: { type: "string", description: "url | reload | back | forward" },
171
+ url: { type: "string", description: "\u76EE\u6807 URL\uFF08type=url \u65F6\uFF09" }
172
+ },
173
+ required: ["type"]
174
+ }
175
+ },
176
+ {
177
+ name: "devtools_resize_page",
178
+ description: "\u8C03\u6574\u9875\u9762\u89C6\u53E3\u5927\u5C0F",
179
+ inputSchema: {
180
+ type: "object",
181
+ properties: {
182
+ width: { type: "number", description: "\u89C6\u53E3\u5BBD\u5EA6" },
183
+ height: { type: "number", description: "\u89C6\u53E3\u9AD8\u5EA6" }
184
+ },
185
+ required: ["width", "height"]
186
+ }
187
+ },
188
+ {
189
+ name: "devtools_emulate",
190
+ description: "\u6A21\u62DF\u79FB\u52A8\u8BBE\u5907",
191
+ inputSchema: {
192
+ type: "object",
193
+ properties: {
194
+ device: { type: "string", description: "\u8BBE\u5907\u540D\u79F0\uFF0C\u5982 iPhone 15" }
195
+ },
196
+ required: ["device"]
197
+ }
198
+ },
199
+ {
200
+ name: "devtools_network",
201
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u7F51\u7EDC\u8BF7\u6C42\u5217\u8868",
202
+ inputSchema: { type: "object", properties: {} }
203
+ },
204
+ {
205
+ name: "devtools_network_request",
206
+ description: "\u83B7\u53D6\u67D0\u6761\u7F51\u7EDC\u8BF7\u6C42\u7684\u8BE6\u7EC6\u4FE1\u606F",
207
+ inputSchema: {
208
+ type: "object",
209
+ properties: {
210
+ reqid: { type: "number", description: "\u8BF7\u6C42 ID\uFF08\u4ECE devtools_network \u83B7\u53D6\uFF09" }
211
+ },
212
+ required: ["reqid"]
213
+ }
214
+ },
215
+ {
216
+ name: "devtools_console",
217
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u63A7\u5236\u53F0\u6D88\u606F",
218
+ inputSchema: { type: "object", properties: {} }
219
+ },
220
+ {
221
+ name: "devtools_console_message",
222
+ description: "\u83B7\u53D6\u67D0\u6761\u63A7\u5236\u53F0\u6D88\u606F\u7684\u8BE6\u7EC6\u4FE1\u606F",
223
+ inputSchema: {
224
+ type: "object",
225
+ properties: {
226
+ msgid: { type: "number", description: "\u6D88\u606F ID\uFF08\u4ECE devtools_console \u83B7\u53D6\uFF09" }
227
+ },
228
+ required: ["msgid"]
229
+ }
230
+ },
231
+ {
232
+ name: "devtools_wait_for",
233
+ description: "\u7B49\u5F85\u9875\u9762\u51FA\u73B0\u6307\u5B9A\u6587\u672C",
234
+ inputSchema: {
235
+ type: "object",
236
+ properties: {
237
+ text: { type: "string", description: "\u7B49\u5F85\u51FA\u73B0\u7684\u6587\u672C" }
238
+ },
239
+ required: ["text"]
240
+ }
241
+ },
242
+ {
243
+ name: "devtools_handle_dialog",
244
+ description: "\u5904\u7406 JavaScript \u5BF9\u8BDD\u6846\uFF08accept/dismiss/\u8F93\u5165\u6587\u672C\uFF09",
245
+ inputSchema: {
246
+ type: "object",
247
+ properties: {
248
+ action: { type: "string", description: "accept | dismiss | prompt \u8F93\u5165\u6587\u672C" }
249
+ },
250
+ required: ["action"]
251
+ }
252
+ },
253
+ {
254
+ name: "devtools_upload_file",
255
+ description: "\u4E0A\u4F20\u6587\u4EF6\u5230\u6587\u4EF6\u8F93\u5165\u6846",
256
+ inputSchema: {
257
+ type: "object",
258
+ properties: {
259
+ uid: { type: "string", description: "\u6587\u4EF6\u8F93\u5165\u6846\u5143\u7D20 uid" },
260
+ filePath: { type: "string", description: "\u6587\u4EF6\u7EDD\u5BF9\u8DEF\u5F84" }
261
+ },
262
+ required: ["uid", "filePath"]
263
+ }
264
+ },
265
+ {
266
+ name: "devtools_performance_start",
267
+ description: "\u5F00\u59CB\u8BB0\u5F55\u6027\u80FD trace",
268
+ inputSchema: {
269
+ type: "object",
270
+ properties: {
271
+ reload: { type: "boolean", description: "\u662F\u5426\u81EA\u52A8\u5237\u65B0" },
272
+ autoStop: { type: "boolean", description: "\u662F\u5426\u81EA\u52A8\u505C\u6B62" }
273
+ }
274
+ }
275
+ },
276
+ {
277
+ name: "devtools_performance_stop",
278
+ description: "\u505C\u6B62\u6027\u80FD trace \u8BB0\u5F55\u5E76\u8FD4\u56DE\u7ED3\u679C",
279
+ inputSchema: { type: "object", properties: {} }
280
+ },
281
+ {
282
+ name: "devtools_performance_insight",
283
+ description: "\u83B7\u53D6\u6027\u80FD\u6307\u6807\u8BE6\u7EC6\u5206\u6790",
284
+ inputSchema: {
285
+ type: "object",
286
+ properties: {
287
+ insightSetId: { type: "string", description: "\u6307\u6807\u96C6 ID" },
288
+ insightName: { type: "string", description: "\u6307\u6807\u540D\u79F0" }
289
+ },
290
+ required: ["insightSetId", "insightName"]
291
+ }
292
+ },
293
+ {
294
+ name: "devtools_lighthouse",
295
+ description: "\u8FD0\u884C Lighthouse \u5BA1\u8BA1\uFF08\u53EF\u8BBF\u95EE\u6027/SEO/\u6700\u4F73\u5B9E\u8DF5\uFF0C\u4E0D\u542B\u6027\u80FD\uFF09",
296
+ inputSchema: {
297
+ type: "object",
298
+ properties: {
299
+ mode: { type: "string", description: "navigation \u6216 snapshot" },
300
+ device: { type: "string", description: "desktop \u6216 mobile" }
301
+ }
302
+ }
303
+ },
304
+ {
305
+ name: "devtools_heapsnapshot",
306
+ description: "\u6355\u83B7\u5806\u5185\u5B58\u5FEB\u7167",
307
+ inputSchema: {
308
+ type: "object",
309
+ properties: {
310
+ filePath: { type: "string", description: "\u4FDD\u5B58\u8DEF\u5F84" }
311
+ },
312
+ required: ["filePath"]
313
+ }
314
+ }
315
+ ];
316
+ const TOOL_MAP = {
317
+ devtools_select_page: "select_page",
318
+ devtools_list_pages: "list_pages",
319
+ devtools_snapshot: "take_snapshot",
320
+ devtools_screenshot: "take_screenshot",
321
+ devtools_evaluate: "evaluate_script",
322
+ devtools_click: "click",
323
+ devtools_hover: "hover",
324
+ devtools_drag: "drag",
325
+ devtools_type: "type_text",
326
+ devtools_press_key: "press_key",
327
+ devtools_fill: "fill",
328
+ devtools_fill_form: "fill_form",
329
+ devtools_navigate: "navigate_page",
330
+ devtools_resize_page: "resize_page",
331
+ devtools_emulate: "emulate",
332
+ devtools_network: "list_network_requests",
333
+ devtools_network_request: "get_network_request",
334
+ devtools_console: "list_console_messages",
335
+ devtools_console_message: "get_console_message",
336
+ devtools_wait_for: "wait_for",
337
+ devtools_handle_dialog: "handle_dialog",
338
+ devtools_upload_file: "upload_file",
339
+ devtools_performance_start: "performance_start_trace",
340
+ devtools_performance_stop: "performance_stop_trace",
341
+ devtools_performance_insight: "performance_analyze_insight",
342
+ devtools_lighthouse: "lighthouse_audit",
343
+ devtools_heapsnapshot: "take_heapsnapshot"
344
+ };
345
+ // Annotate the CommonJS export names for ESM import in node:
346
+ 0 && (module.exports = {
347
+ CUSTOM_TOOLS,
348
+ TOOL_MAP
349
+ });
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 自定义 DevTools 工具定义
3
+ * 所有工具自动映射到 chrome-devtools-mcp 底层工具
4
+ */
5
+ export interface CustomTool {
6
+ name: string;
7
+ description: string;
8
+ inputSchema: {
9
+ type: "object";
10
+ properties: Record<string, unknown>;
11
+ required?: string[];
12
+ };
13
+ }
14
+ export declare const CUSTOM_TOOLS: CustomTool[];
15
+ /** 工具名映射(自定义 → chrome-devtools-mcp) */
16
+ export declare const TOOL_MAP: Record<string, string>;
@@ -0,0 +1,283 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var __async = (__this, __arguments, generator) => {
19
+ return new Promise((resolve, reject) => {
20
+ var fulfilled = (value) => {
21
+ try {
22
+ step(generator.next(value));
23
+ } catch (e) {
24
+ reject(e);
25
+ }
26
+ };
27
+ var rejected = (value) => {
28
+ try {
29
+ step(generator.throw(value));
30
+ } catch (e) {
31
+ reject(e);
32
+ }
33
+ };
34
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
35
+ step((generator = generator.apply(__this, __arguments)).next());
36
+ });
37
+ };
38
+ var mcp_exports = {};
39
+ __export(mcp_exports, {
40
+ MCP_API_PATH: () => import_shared.MCP_API_PATH,
41
+ setupMcpEndpoint: () => setupMcpEndpoint
42
+ });
43
+ module.exports = __toCommonJS(mcp_exports);
44
+ var import_shared = require("@vite-plugin-opencode-assistant/shared");
45
+ var import_node = require("@vite-plugin-opencode-assistant/shared/node");
46
+ var import_context = require("../endpoints/context.cjs");
47
+ var import_mcp_tools = require("./mcp-tools.cjs");
48
+ const log = (0, import_node.createLogger)("McpEndpoint");
49
+ function setupMcpEndpoint(server, mcp, getPageContext) {
50
+ server.middlewares.use((req, res, next) => __async(null, null, function* () {
51
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
52
+ if (!((_a = req.url) == null ? void 0 : _a.startsWith(import_shared.MCP_API_PATH))) return next();
53
+ const url = new URL(req.url, `http://localhost`);
54
+ const token = (_c = url.searchParams.get("token")) != null ? _c : (_b = req.headers["authorization"]) == null ? void 0 : _b.replace(/^Bearer /i, "");
55
+ if (token !== mcp.accessToken) {
56
+ res.writeHead(401, { "Content-Type": "application/json" });
57
+ res.end(JSON.stringify({ error: "Unauthorized" }));
58
+ return;
59
+ }
60
+ res.setHeader("Access-Control-Allow-Origin", "*");
61
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
62
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Authorization");
63
+ res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
64
+ if (req.method === "OPTIONS") {
65
+ res.writeHead(204);
66
+ res.end();
67
+ return;
68
+ }
69
+ if (req.method === "GET") {
70
+ res.writeHead(200, {
71
+ "Content-Type": "text/event-stream",
72
+ "Cache-Control": "no-cache",
73
+ Connection: "keep-alive",
74
+ "Mcp-Session-Id": mcp.sessionId
75
+ });
76
+ res.write(":ok\n\n");
77
+ const keepAlive = setInterval(() => res.write(":ping\n\n"), 15e3);
78
+ req.on("close", () => clearInterval(keepAlive));
79
+ return;
80
+ }
81
+ if (req.method === "DELETE") {
82
+ res.writeHead(200);
83
+ res.end();
84
+ return;
85
+ }
86
+ if (req.method === "POST") {
87
+ try {
88
+ const body = yield readBody(req);
89
+ if (!body) {
90
+ res.writeHead(400);
91
+ res.end("Empty body");
92
+ return;
93
+ }
94
+ const { method, id } = tryParseRequest(body);
95
+ log.debug("MCP request", { method, body: body.substring(0, 150) });
96
+ if (method === "tools/list") {
97
+ res.writeHead(200, {
98
+ "Content-Type": "application/json",
99
+ "Mcp-Session-Id": mcp.sessionId
100
+ });
101
+ res.end(JSON.stringify({ jsonrpc: "2.0", id, result: { tools: import_mcp_tools.CUSTOM_TOOLS } }));
102
+ return;
103
+ }
104
+ if (method === "tools/call") {
105
+ const params = tryParseParams(body);
106
+ const toolName = params == null ? void 0 : params.name;
107
+ const mapped = toolName != null ? import_mcp_tools.TOOL_MAP[toolName] : void 0;
108
+ if (!mapped) {
109
+ res.writeHead(200, {
110
+ "Content-Type": "application/json",
111
+ "Mcp-Session-Id": mcp.sessionId
112
+ });
113
+ res.end(
114
+ JSON.stringify({
115
+ jsonrpc: "2.0",
116
+ id,
117
+ error: { code: -32601, message: `Tool not found: ${toolName}` }
118
+ })
119
+ );
120
+ return;
121
+ }
122
+ if (toolName === "devtools_list_pages") {
123
+ const listResult = yield mcp.callChromeDevTool("list_pages", {});
124
+ const text = (_f = (_e = (_d = listResult == null ? void 0 : listResult.result) == null ? void 0 : _d.content) == null ? void 0 : _e[0]) == null ? void 0 : _f.text;
125
+ const allPages = text ? (0, import_context.parseListPages)(text) : [];
126
+ const pc = getPageContext();
127
+ const projectOrigin = (0, import_context.getProjectOrigin)(pc.url);
128
+ if (!projectOrigin) {
129
+ res.writeHead(200, {
130
+ "Content-Type": "application/json",
131
+ "Mcp-Session-Id": mcp.sessionId
132
+ });
133
+ res.end(
134
+ JSON.stringify({
135
+ jsonrpc: "2.0",
136
+ id,
137
+ result: {
138
+ content: [
139
+ { type: "text", text: "\u6682\u65E0\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u672C\u5730\u5F00\u53D1\u9875\u9762" }
140
+ ]
141
+ }
142
+ })
143
+ );
144
+ return;
145
+ }
146
+ const filtered = allPages.filter((p) => p.url.startsWith(projectOrigin));
147
+ const chromeSelectedPageId = (_g = allPages.find((p) => p.selected)) == null ? void 0 : _g.pageId;
148
+ const resolved = yield (0, import_context.resolveChromePageId)(
149
+ mcp,
150
+ pc.url,
151
+ pc.title,
152
+ pc.sessionId,
153
+ filtered,
154
+ chromeSelectedPageId
155
+ );
156
+ const activePageId = resolved.ok ? resolved.pageId : null;
157
+ res.writeHead(200, {
158
+ "Content-Type": "application/json",
159
+ "Mcp-Session-Id": mcp.sessionId
160
+ });
161
+ res.end(
162
+ JSON.stringify({
163
+ jsonrpc: "2.0",
164
+ id,
165
+ result: {
166
+ content: [
167
+ {
168
+ type: "text",
169
+ text: JSON.stringify(
170
+ filtered.map((p) => ({
171
+ pageId: p.pageId,
172
+ url: p.url,
173
+ title: p.title,
174
+ active: activePageId != null ? p.pageId === activePageId : false,
175
+ selected: p.selected
176
+ })),
177
+ null,
178
+ 2
179
+ )
180
+ }
181
+ ]
182
+ }
183
+ })
184
+ );
185
+ return;
186
+ }
187
+ if (toolName !== "devtools_select_page") {
188
+ const checkResult = yield mcp.callChromeDevTool("list_pages", {});
189
+ const checkText = (_j = (_i = (_h = checkResult == null ? void 0 : checkResult.result) == null ? void 0 : _h.content) == null ? void 0 : _i[0]) == null ? void 0 : _j.text;
190
+ const checkPages = checkText ? (0, import_context.parseListPages)(checkText) : [];
191
+ const pc = getPageContext();
192
+ const origin = (0, import_context.getProjectOrigin)(pc.url);
193
+ const hasProjectSelected = origin ? checkPages.some((p) => p.selected && p.url.startsWith(origin)) : true;
194
+ if (!hasProjectSelected) {
195
+ res.writeHead(200, {
196
+ "Content-Type": "application/json",
197
+ "Mcp-Session-Id": mcp.sessionId
198
+ });
199
+ res.end(
200
+ JSON.stringify({
201
+ jsonrpc: "2.0",
202
+ id,
203
+ error: {
204
+ code: -32e3,
205
+ message: "Chrome DevTools \u5F53\u524D\u672A\u9009\u4E2D\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u5148\u8C03\u7528 devtools_list_pages \u67E5\u770B\u53EF\u7528\u9875\u9762\uFF0C\u518D\u8C03\u7528 devtools_select_page \u9009\u62E9\u76EE\u6807\u9875\u9762"
206
+ }
207
+ })
208
+ );
209
+ return;
210
+ }
211
+ }
212
+ const forwardBody = JSON.stringify({
213
+ jsonrpc: "2.0",
214
+ id,
215
+ method: "tools/call",
216
+ params: {
217
+ name: mapped,
218
+ arguments: (params == null ? void 0 : params.arguments) || {}
219
+ }
220
+ });
221
+ const responseText2 = yield mcp.forward(forwardBody);
222
+ log.debug("MCP response", { method: toolName, response: responseText2.substring(0, 100) });
223
+ res.writeHead(200, {
224
+ "Content-Type": "application/json",
225
+ "Mcp-Session-Id": mcp.sessionId
226
+ });
227
+ res.end(responseText2);
228
+ return;
229
+ }
230
+ const responseText = yield mcp.forward(body);
231
+ res.writeHead(200, { "Content-Type": "application/json", "Mcp-Session-Id": mcp.sessionId });
232
+ res.end(responseText);
233
+ } catch (e) {
234
+ log.debug("MCP POST error", { error: e.message });
235
+ res.writeHead(500, { "Content-Type": "application/json" });
236
+ res.end(
237
+ JSON.stringify({
238
+ jsonrpc: "2.0",
239
+ error: { code: -32603, message: e.message }
240
+ })
241
+ );
242
+ }
243
+ return;
244
+ }
245
+ next();
246
+ }));
247
+ }
248
+ function readBody(req, maxSize = 1024 * 1024) {
249
+ return new Promise((resolve, reject) => {
250
+ let body = "";
251
+ req.on("data", (chunk) => {
252
+ body += chunk.toString();
253
+ if (body.length > maxSize) {
254
+ req.destroy();
255
+ reject(new Error("Request body too large"));
256
+ }
257
+ });
258
+ req.on("end", () => resolve(body));
259
+ req.on("error", reject);
260
+ });
261
+ }
262
+ function tryParseRequest(body) {
263
+ var _a;
264
+ try {
265
+ const data = JSON.parse(body);
266
+ return { method: data.method || "unknown", id: (_a = data.id) != null ? _a : null };
267
+ } catch (e) {
268
+ return { method: "unknown", id: null };
269
+ }
270
+ }
271
+ function tryParseParams(body) {
272
+ var _a;
273
+ try {
274
+ return (_a = JSON.parse(body).params) != null ? _a : null;
275
+ } catch (e) {
276
+ return null;
277
+ }
278
+ }
279
+ // Annotate the CommonJS export names for ESM import in node:
280
+ 0 && (module.exports = {
281
+ MCP_API_PATH,
282
+ setupMcpEndpoint
283
+ });
@@ -0,0 +1,6 @@
1
+ import type { ViteDevServer } from "vite";
2
+ import type { PageContext } from "@vite-plugin-opencode-assistant/shared";
3
+ import { MCP_API_PATH } from "@vite-plugin-opencode-assistant/shared";
4
+ import { McpProxy } from "../core/mcp-proxy";
5
+ export { MCP_API_PATH };
6
+ export declare function setupMcpEndpoint(server: ViteDevServer, mcp: McpProxy, getPageContext: () => PageContext): void;