vite-plugin-opencode-assistant 1.1.24 → 1.1.26
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/es/core/mcp-chrome.d.ts +43 -0
- package/es/core/mcp-chrome.mjs +147 -0
- package/es/core/mcp-proxy.d.ts +21 -0
- package/es/core/mcp-proxy.mjs +254 -0
- package/es/core/opencode-web.d.ts +1 -1
- package/es/core/opencode-web.mjs +4 -4
- package/es/core/service.d.ts +2 -1
- package/es/core/service.mjs +4 -3
- package/es/endpoints/context.mjs +7 -2
- package/es/endpoints/index.d.ts +4 -2
- package/es/endpoints/index.mjs +4 -1
- package/es/endpoints/mcp-tools.d.ts +17 -0
- package/es/endpoints/mcp-tools.mjs +519 -0
- package/es/endpoints/mcp.d.ts +6 -0
- package/es/endpoints/mcp.mjs +290 -0
- package/es/index.mjs +71 -66
- package/lib/client.js +564 -563
- package/lib/core/mcp-chrome.cjs +174 -0
- package/lib/core/mcp-chrome.d.ts +43 -0
- package/lib/core/mcp-proxy.cjs +286 -0
- package/lib/core/mcp-proxy.d.ts +21 -0
- package/lib/core/opencode-web.cjs +4 -4
- package/lib/core/opencode-web.d.ts +1 -1
- package/lib/core/service.cjs +4 -3
- package/lib/core/service.d.ts +2 -1
- package/lib/endpoints/context.cjs +7 -2
- package/lib/endpoints/index.cjs +5 -1
- package/lib/endpoints/index.d.ts +4 -2
- package/lib/endpoints/mcp-tools.cjs +541 -0
- package/lib/endpoints/mcp-tools.d.ts +17 -0
- package/lib/endpoints/mcp.cjs +307 -0
- package/lib/endpoints/mcp.d.ts +6 -0
- package/lib/index.cjs +71 -66
- package/package.json +6 -5
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
|
+
};
|
|
23
|
+
var __copyProps = (to, from, except, desc) => {
|
|
24
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
+
for (let key of __getOwnPropNames(from))
|
|
26
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
27
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
28
|
+
}
|
|
29
|
+
return to;
|
|
30
|
+
};
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
var __async = (__this, __arguments, generator) => {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
var fulfilled = (value) => {
|
|
35
|
+
try {
|
|
36
|
+
step(generator.next(value));
|
|
37
|
+
} catch (e) {
|
|
38
|
+
reject(e);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var rejected = (value) => {
|
|
42
|
+
try {
|
|
43
|
+
step(generator.throw(value));
|
|
44
|
+
} catch (e) {
|
|
45
|
+
reject(e);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
49
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
var mcp_exports = {};
|
|
53
|
+
__export(mcp_exports, {
|
|
54
|
+
MCP_API_PATH: () => import_shared.MCP_API_PATH,
|
|
55
|
+
setupMcpEndpoint: () => setupMcpEndpoint
|
|
56
|
+
});
|
|
57
|
+
module.exports = __toCommonJS(mcp_exports);
|
|
58
|
+
var import_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
59
|
+
var import_node = require("@vite-plugin-opencode-assistant/shared/node");
|
|
60
|
+
var import_mcp_chrome = require("../core/mcp-chrome.cjs");
|
|
61
|
+
var import_mcp_tools = require("./mcp-tools.cjs");
|
|
62
|
+
const log = (0, import_node.createLogger)("McpEndpoint");
|
|
63
|
+
function setupMcpEndpoint(server, mcp, getPageContext) {
|
|
64
|
+
server.middlewares.use((req, res, next) => __async(null, null, function* () {
|
|
65
|
+
var _a, _b, _c;
|
|
66
|
+
if (!((_a = req.url) == null ? void 0 : _a.startsWith(import_shared.MCP_API_PATH))) return next();
|
|
67
|
+
const url = new URL(req.url, `http://localhost`);
|
|
68
|
+
const token = (_c = url.searchParams.get("token")) != null ? _c : (_b = req.headers["authorization"]) == null ? void 0 : _b.replace(/^Bearer /i, "");
|
|
69
|
+
if (token !== mcp.accessToken) {
|
|
70
|
+
sendMcpJson(res, 401, { error: "Unauthorized" });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
74
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
75
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Authorization");
|
|
76
|
+
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
77
|
+
if (req.method === "OPTIONS") {
|
|
78
|
+
res.writeHead(204);
|
|
79
|
+
res.end();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (req.method === "GET") {
|
|
83
|
+
handleGetSse(req, res, mcp);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (req.method === "DELETE") {
|
|
87
|
+
res.writeHead(200);
|
|
88
|
+
res.end();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (req.method === "POST") {
|
|
92
|
+
yield handlePost(req, res, mcp, (0, import_mcp_chrome.getProjectOrigins)(server), getPageContext);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
next();
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
function handleGetSse(req, res, mcp) {
|
|
99
|
+
res.writeHead(200, {
|
|
100
|
+
"Content-Type": "text/event-stream",
|
|
101
|
+
"Cache-Control": "no-cache",
|
|
102
|
+
Connection: "keep-alive",
|
|
103
|
+
"Mcp-Session-Id": mcp.sessionId
|
|
104
|
+
});
|
|
105
|
+
res.write(":ok\n\n");
|
|
106
|
+
const keepAlive = setInterval(() => res.write(":ping\n\n"), 15e3);
|
|
107
|
+
req.on("close", () => clearInterval(keepAlive));
|
|
108
|
+
}
|
|
109
|
+
function handlePost(req, res, mcp, projectOrigins, getPageContext) {
|
|
110
|
+
return __async(this, null, function* () {
|
|
111
|
+
try {
|
|
112
|
+
const body = yield readBody(req);
|
|
113
|
+
if (!body) {
|
|
114
|
+
res.writeHead(400);
|
|
115
|
+
res.end("Empty body");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const { method, id } = tryParseRequest(body);
|
|
119
|
+
log.debug("MCP request", { method, body: body.substring(0, 150) });
|
|
120
|
+
switch (method) {
|
|
121
|
+
case "tools/list":
|
|
122
|
+
return handleToolsList(res, id, mcp.sessionId);
|
|
123
|
+
case "tools/call":
|
|
124
|
+
return handleToolsCall(res, id, body, mcp, projectOrigins, getPageContext);
|
|
125
|
+
default:
|
|
126
|
+
return handleForward(res, body, mcp);
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
log.debug("MCP POST error", { error: e.message });
|
|
130
|
+
sendMcpJson(res, 500, {
|
|
131
|
+
jsonrpc: "2.0",
|
|
132
|
+
error: { code: -32603, message: e.message }
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function handleToolsList(res, id, sessionId) {
|
|
138
|
+
sendMcpJson(res, 200, { jsonrpc: "2.0", id, result: { tools: import_mcp_tools.CUSTOM_TOOLS } }, sessionId);
|
|
139
|
+
}
|
|
140
|
+
function handleToolsCall(res, id, body, mcp, projectOrigins, getPageContext) {
|
|
141
|
+
const params = tryParseParams(body);
|
|
142
|
+
const toolName = params == null ? void 0 : params.name;
|
|
143
|
+
const mapped = toolName != null ? import_mcp_tools.TOOL_MAP[toolName] : void 0;
|
|
144
|
+
if (!mapped) {
|
|
145
|
+
sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, mcp.sessionId);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
switch (toolName) {
|
|
149
|
+
case "devtools_list_pages":
|
|
150
|
+
return handleListPages(res, id, mcp, projectOrigins, getPageContext);
|
|
151
|
+
default:
|
|
152
|
+
return handleDevTool(res, id, mcp, mapped, (params == null ? void 0 : params.arguments) || {}, projectOrigins);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function handleListPages(res, id, mcp, projectOrigins, getPageContext) {
|
|
156
|
+
return __async(this, null, function* () {
|
|
157
|
+
var _a, _b, _c, _d;
|
|
158
|
+
const listResult = yield mcp.callChromeDevTool("list_pages", {});
|
|
159
|
+
const text = (_c = (_b = (_a = listResult == null ? void 0 : listResult.result) == null ? void 0 : _a.content) == null ? void 0 : _b[0]) == null ? void 0 : _c.text;
|
|
160
|
+
const allPages = text ? (0, import_mcp_chrome.parseListPages)(text) : [];
|
|
161
|
+
log.debug("Chrome pages", { total: allPages.length, urls: allPages.map((p) => p.url) });
|
|
162
|
+
log.debug("project origins", { origins: projectOrigins });
|
|
163
|
+
const filtered = allPages.filter((p) => (0, import_mcp_chrome.isProjectPage)(p.url, projectOrigins));
|
|
164
|
+
log.debug("filtered pages", { count: filtered.length, pageIds: filtered.map((p) => p.pageId) });
|
|
165
|
+
if (filtered.length === 0) {
|
|
166
|
+
sendMcpResult(res, id, "\u6682\u65E0\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u672C\u5730\u5F00\u53D1\u9875\u9762", mcp.sessionId);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const pc = getPageContext();
|
|
170
|
+
const chromeSelectedPageId = (_d = allPages.find((p) => p.selected)) == null ? void 0 : _d.pageId;
|
|
171
|
+
const resolved = yield (0, import_mcp_chrome.resolveChromePageId)(
|
|
172
|
+
mcp,
|
|
173
|
+
pc.url,
|
|
174
|
+
pc.title,
|
|
175
|
+
projectOrigins,
|
|
176
|
+
pc.sessionId,
|
|
177
|
+
filtered,
|
|
178
|
+
chromeSelectedPageId
|
|
179
|
+
);
|
|
180
|
+
const activePageId = resolved.ok ? resolved.pageId : null;
|
|
181
|
+
const pageList = filtered.map((p) => ({
|
|
182
|
+
pageId: p.pageId,
|
|
183
|
+
url: p.url,
|
|
184
|
+
title: p.title,
|
|
185
|
+
active: activePageId != null ? p.pageId === activePageId : false,
|
|
186
|
+
selected: p.selected
|
|
187
|
+
}));
|
|
188
|
+
sendMcpResult(res, id, JSON.stringify(pageList, null, 2), mcp.sessionId);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function handleDevTool(res, id, mcp, mapped, args, projectOrigins) {
|
|
192
|
+
return __async(this, null, function* () {
|
|
193
|
+
var _a, _b, _c;
|
|
194
|
+
const pageId = args["pageId"];
|
|
195
|
+
if (typeof pageId !== "number") {
|
|
196
|
+
sendMcpError(
|
|
197
|
+
res,
|
|
198
|
+
id,
|
|
199
|
+
-32e3,
|
|
200
|
+
"\u7F3A\u5C11 pageId \u53C2\u6570\uFF0C\u8BF7\u5148\u8C03\u7528 devtools_list_pages \u83B7\u53D6\u53EF\u7528\u9875\u9762\u5217\u8868",
|
|
201
|
+
mcp.sessionId
|
|
202
|
+
);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const checkResult = yield mcp.callChromeDevTool("list_pages", {});
|
|
206
|
+
const checkText = (_c = (_b = (_a = checkResult == null ? void 0 : checkResult.result) == null ? void 0 : _a.content) == null ? void 0 : _b[0]) == null ? void 0 : _c.text;
|
|
207
|
+
const checkPages = checkText ? (0, import_mcp_chrome.parseListPages)(checkText) : [];
|
|
208
|
+
const projectPages = checkPages.filter((p) => (0, import_mcp_chrome.isProjectPage)(p.url, projectOrigins));
|
|
209
|
+
const isValid = projectPages.some((p) => p.pageId === pageId);
|
|
210
|
+
log.debug("handleDevTool validation", {
|
|
211
|
+
pageId,
|
|
212
|
+
totalChromePages: checkPages.length,
|
|
213
|
+
projectPages: projectPages.length,
|
|
214
|
+
projectPageIds: projectPages.map((p) => p.pageId),
|
|
215
|
+
origins: projectOrigins,
|
|
216
|
+
isValid
|
|
217
|
+
});
|
|
218
|
+
if (!isValid) {
|
|
219
|
+
sendMcpError(res, id, -32e3, "pageId \u65E0\u6548\u6216\u975E\u9879\u76EE\u9875\u9762", mcp.sessionId);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
yield mcp.callChromeDevTool("select_page", { pageId, bringToFront: false });
|
|
223
|
+
const forwardArgs = __spreadValues({}, args);
|
|
224
|
+
delete forwardArgs["pageId"];
|
|
225
|
+
const forwardBody = JSON.stringify({
|
|
226
|
+
jsonrpc: "2.0",
|
|
227
|
+
id,
|
|
228
|
+
method: "tools/call",
|
|
229
|
+
params: { name: mapped, arguments: forwardArgs }
|
|
230
|
+
});
|
|
231
|
+
const responseText = yield mcp.forward(forwardBody);
|
|
232
|
+
log.debug("MCP response", { mapped, response: responseText.substring(0, 100) });
|
|
233
|
+
sendMcpJson(res, 200, responseText, mcp.sessionId);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function handleForward(res, body, mcp) {
|
|
237
|
+
return __async(this, null, function* () {
|
|
238
|
+
const responseText = yield mcp.forward(body);
|
|
239
|
+
sendMcpJson(res, 200, responseText, mcp.sessionId);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function sendMcpResult(res, id, text, sessionId) {
|
|
243
|
+
sendMcpJson(
|
|
244
|
+
res,
|
|
245
|
+
200,
|
|
246
|
+
{
|
|
247
|
+
jsonrpc: "2.0",
|
|
248
|
+
id,
|
|
249
|
+
result: { content: [{ type: "text", text }] }
|
|
250
|
+
},
|
|
251
|
+
sessionId
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
function sendMcpError(res, id, code, message, sessionId) {
|
|
255
|
+
sendMcpJson(
|
|
256
|
+
res,
|
|
257
|
+
200,
|
|
258
|
+
{
|
|
259
|
+
jsonrpc: "2.0",
|
|
260
|
+
id,
|
|
261
|
+
error: { code, message }
|
|
262
|
+
},
|
|
263
|
+
sessionId
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
function sendMcpJson(res, statusCode, body, sessionId) {
|
|
267
|
+
const headers = { "Content-Type": "application/json" };
|
|
268
|
+
if (sessionId) headers["Mcp-Session-Id"] = sessionId;
|
|
269
|
+
res.writeHead(statusCode, headers);
|
|
270
|
+
res.end(typeof body === "string" ? body : JSON.stringify(body));
|
|
271
|
+
}
|
|
272
|
+
function readBody(req, maxSize = 1024 * 1024) {
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
let body = "";
|
|
275
|
+
req.on("data", (chunk) => {
|
|
276
|
+
body += chunk.toString();
|
|
277
|
+
if (body.length > maxSize) {
|
|
278
|
+
req.destroy();
|
|
279
|
+
reject(new Error("Request body too large"));
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
req.on("end", () => resolve(body));
|
|
283
|
+
req.on("error", reject);
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
function tryParseRequest(body) {
|
|
287
|
+
var _a;
|
|
288
|
+
try {
|
|
289
|
+
const data = JSON.parse(body);
|
|
290
|
+
return { method: data.method || "unknown", id: (_a = data.id) != null ? _a : null };
|
|
291
|
+
} catch (e) {
|
|
292
|
+
return { method: "unknown", id: null };
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function tryParseParams(body) {
|
|
296
|
+
var _a;
|
|
297
|
+
try {
|
|
298
|
+
return (_a = JSON.parse(body).params) != null ? _a : null;
|
|
299
|
+
} catch (e) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
304
|
+
0 && (module.exports = {
|
|
305
|
+
MCP_API_PATH,
|
|
306
|
+
setupMcpEndpoint
|
|
307
|
+
});
|
|
@@ -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;
|
package/lib/index.cjs
CHANGED
|
@@ -72,7 +72,9 @@ var import_endpoints = require("./endpoints/index.cjs");
|
|
|
72
72
|
var import_injector = require("./core/injector.cjs");
|
|
73
73
|
var import_api = require("./core/api.cjs");
|
|
74
74
|
var import_service = require("./core/service.cjs");
|
|
75
|
+
var import_mcp_proxy = require("./core/mcp-proxy.cjs");
|
|
75
76
|
var import_paths = require("./utils/paths.cjs");
|
|
77
|
+
var import_system = require("./utils/system.cjs");
|
|
76
78
|
function opencodePlugin(options = {}) {
|
|
77
79
|
const plugins = [];
|
|
78
80
|
plugins.push(
|
|
@@ -100,6 +102,7 @@ function createOpenCodePlugin(options = {}) {
|
|
|
100
102
|
let activeTabId = DEFAULT_TAB;
|
|
101
103
|
const serviceInstanceId = import_crypto.default.randomUUID();
|
|
102
104
|
const sseClients = /* @__PURE__ */ new Set();
|
|
105
|
+
const mcpProxy = new import_mcp_proxy.McpProxy();
|
|
103
106
|
const api = new import_api.OpenCodeAPI(
|
|
104
107
|
config.hostname,
|
|
105
108
|
() => actualWebPort,
|
|
@@ -118,6 +121,7 @@ function createOpenCodePlugin(options = {}) {
|
|
|
118
121
|
actualProxyPort = port;
|
|
119
122
|
}
|
|
120
123
|
);
|
|
124
|
+
service.workspaceRoot = (0, import_system.findGitRoot)(process.cwd());
|
|
121
125
|
return {
|
|
122
126
|
name: "vite-plugin-opencode",
|
|
123
127
|
apply(_viteConfig, env) {
|
|
@@ -131,56 +135,60 @@ function createOpenCodePlugin(options = {}) {
|
|
|
131
135
|
projectRoot = server.config.root;
|
|
132
136
|
let viteOrigin = "";
|
|
133
137
|
const getViteOrigin = () => viteOrigin;
|
|
134
|
-
(0, import_endpoints.setupMiddlewares)(
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
(0, import_endpoints.setupMiddlewares)(
|
|
139
|
+
server,
|
|
140
|
+
{
|
|
141
|
+
get webUrl() {
|
|
142
|
+
return actualWebPort ? `http://${config.hostname}:${actualWebPort}` : null;
|
|
143
|
+
},
|
|
144
|
+
get sseClients() {
|
|
145
|
+
return sseClients;
|
|
146
|
+
},
|
|
147
|
+
getPageContext() {
|
|
148
|
+
return pageContexts.get(activeTabId) || pageContexts.get(DEFAULT_TAB) || { url: "", title: "" };
|
|
149
|
+
},
|
|
150
|
+
setPageContext(tabId, ctx) {
|
|
151
|
+
pageContexts.set(tabId || DEFAULT_TAB, ctx);
|
|
152
|
+
},
|
|
153
|
+
setActiveTabId(tabId) {
|
|
154
|
+
activeTabId = tabId;
|
|
155
|
+
},
|
|
156
|
+
clearSelectedElements() {
|
|
157
|
+
const ctx = pageContexts.get(activeTabId);
|
|
158
|
+
if (ctx) {
|
|
159
|
+
ctx.selectedElements = [];
|
|
160
|
+
pageContexts.set(activeTabId, ctx);
|
|
161
|
+
}
|
|
162
|
+
const defaultCtx = pageContexts.get(DEFAULT_TAB);
|
|
163
|
+
if (defaultCtx) {
|
|
164
|
+
defaultCtx.selectedElements = [];
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
get isServiceStarted() {
|
|
168
|
+
return service.isStarted;
|
|
169
|
+
},
|
|
170
|
+
get currentTask() {
|
|
171
|
+
return service.currentTask;
|
|
172
|
+
},
|
|
173
|
+
get actualProxyPort() {
|
|
174
|
+
return actualProxyPort;
|
|
175
|
+
},
|
|
176
|
+
get actualWebPort() {
|
|
177
|
+
return actualWebPort;
|
|
178
|
+
},
|
|
179
|
+
get serviceInstanceId() {
|
|
180
|
+
return serviceInstanceId;
|
|
181
|
+
},
|
|
182
|
+
getSessions: () => api.getSessions(service.workspaceRoot),
|
|
183
|
+
createSession: () => api.createSession(service.workspaceRoot),
|
|
184
|
+
deleteSession: (id) => api.deleteSession(id),
|
|
185
|
+
resolveWidgetPath: import_paths.resolveWidgetPath,
|
|
186
|
+
resolveWidgetStylePath: import_paths.resolveWidgetStylePath,
|
|
187
|
+
getAvailableModels: () => service.getAvailableModels(),
|
|
188
|
+
retryWarmupChromeMcp: (selectedModel) => service.retryWarmupChromeMcp(getViteOrigin(), selectedModel)
|
|
137
189
|
},
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
},
|
|
141
|
-
getPageContext() {
|
|
142
|
-
return pageContexts.get(activeTabId) || pageContexts.get(DEFAULT_TAB) || { url: "", title: "" };
|
|
143
|
-
},
|
|
144
|
-
setPageContext(tabId, ctx) {
|
|
145
|
-
pageContexts.set(tabId || DEFAULT_TAB, ctx);
|
|
146
|
-
},
|
|
147
|
-
setActiveTabId(tabId) {
|
|
148
|
-
activeTabId = tabId;
|
|
149
|
-
},
|
|
150
|
-
clearSelectedElements() {
|
|
151
|
-
const ctx = pageContexts.get(activeTabId);
|
|
152
|
-
if (ctx) {
|
|
153
|
-
ctx.selectedElements = [];
|
|
154
|
-
pageContexts.set(activeTabId, ctx);
|
|
155
|
-
}
|
|
156
|
-
const defaultCtx = pageContexts.get(DEFAULT_TAB);
|
|
157
|
-
if (defaultCtx) {
|
|
158
|
-
defaultCtx.selectedElements = [];
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
get isServiceStarted() {
|
|
162
|
-
return service.isStarted;
|
|
163
|
-
},
|
|
164
|
-
get currentTask() {
|
|
165
|
-
return service.currentTask;
|
|
166
|
-
},
|
|
167
|
-
get actualProxyPort() {
|
|
168
|
-
return actualProxyPort;
|
|
169
|
-
},
|
|
170
|
-
get actualWebPort() {
|
|
171
|
-
return actualWebPort;
|
|
172
|
-
},
|
|
173
|
-
get serviceInstanceId() {
|
|
174
|
-
return serviceInstanceId;
|
|
175
|
-
},
|
|
176
|
-
getSessions: () => api.getSessions(service.workspaceRoot),
|
|
177
|
-
createSession: () => api.createSession(service.workspaceRoot),
|
|
178
|
-
deleteSession: (id) => api.deleteSession(id),
|
|
179
|
-
resolveWidgetPath: import_paths.resolveWidgetPath,
|
|
180
|
-
resolveWidgetStylePath: import_paths.resolveWidgetStylePath,
|
|
181
|
-
getAvailableModels: () => service.getAvailableModels(),
|
|
182
|
-
retryWarmupChromeMcp: (selectedModel) => service.retryWarmupChromeMcp(getViteOrigin(), selectedModel)
|
|
183
|
-
});
|
|
190
|
+
mcpProxy
|
|
191
|
+
);
|
|
184
192
|
(_a2 = server.httpServer) == null ? void 0 : _a2.on("listening", () => __async(null, null, function* () {
|
|
185
193
|
var _a3;
|
|
186
194
|
log.debug("Vite server listening event fired");
|
|
@@ -211,7 +219,16 @@ function createOpenCodePlugin(options = {}) {
|
|
|
211
219
|
logsApiUrl
|
|
212
220
|
});
|
|
213
221
|
try {
|
|
214
|
-
yield
|
|
222
|
+
yield mcpProxy.start();
|
|
223
|
+
yield service.start(
|
|
224
|
+
mcpProxy.accessToken,
|
|
225
|
+
vitePort,
|
|
226
|
+
[viteOrigin],
|
|
227
|
+
contextApiUrl,
|
|
228
|
+
logsApiUrl,
|
|
229
|
+
viteOrigin,
|
|
230
|
+
mcpProxy
|
|
231
|
+
);
|
|
215
232
|
} catch (e) {
|
|
216
233
|
log.error("Failed to start services", { error: e });
|
|
217
234
|
}
|
|
@@ -219,9 +236,11 @@ function createOpenCodePlugin(options = {}) {
|
|
|
219
236
|
(_b2 = server.httpServer) == null ? void 0 : _b2.on("close", () => {
|
|
220
237
|
log.debug("HTTP server closing");
|
|
221
238
|
service.stop();
|
|
239
|
+
mcpProxy.stop();
|
|
222
240
|
});
|
|
223
241
|
const cleanup = () => __async(null, null, function* () {
|
|
224
242
|
log.debug("Process cleanup triggered");
|
|
243
|
+
mcpProxy.stop();
|
|
225
244
|
yield service.stop();
|
|
226
245
|
process.exit(0);
|
|
227
246
|
});
|
|
@@ -248,23 +267,9 @@ function createOpenCodePlugin(options = {}) {
|
|
|
248
267
|
const titleInject = `<script>
|
|
249
268
|
(function () {
|
|
250
269
|
var KEY = "_opencode_pk";
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
prefix = "[" + Math.random().toString(36).slice(2, 5) + "]";
|
|
254
|
-
sessionStorage.setItem(KEY, prefix);
|
|
255
|
-
}
|
|
256
|
-
var applied = false;
|
|
257
|
-
function apply() {
|
|
258
|
-
if (applied) return;
|
|
259
|
-
var title = document.title;
|
|
260
|
-
if (title.indexOf(prefix) === 0) return;
|
|
261
|
-
applied = true;
|
|
262
|
-
document.title = prefix + title.replace(prefix, "");
|
|
263
|
-
applied = false;
|
|
270
|
+
if (!sessionStorage.getItem(KEY)) {
|
|
271
|
+
sessionStorage.setItem(KEY, "[" + Math.random().toString(36).slice(2, 5) + "]");
|
|
264
272
|
}
|
|
265
|
-
apply();
|
|
266
|
-
var target = document.querySelector("title") || document.head;
|
|
267
|
-
new MutationObserver(apply).observe(target, { childList: true });
|
|
268
273
|
})();
|
|
269
274
|
</script>`;
|
|
270
275
|
timer.end();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-opencode-assistant",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.26",
|
|
4
4
|
"description": "Embed OpenCode Web UI in your Vite dev server for real-time code modification and preview",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -35,17 +35,18 @@
|
|
|
35
35
|
"author": "",
|
|
36
36
|
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"chrome-devtools-mcp": "^1.6.0",
|
|
38
39
|
"unplugin-vue-inspector": "^3.0.0",
|
|
39
40
|
"execa": "^9.6.1",
|
|
40
|
-
"@vite-plugin-opencode-assistant/
|
|
41
|
-
"@vite-plugin-opencode-assistant/opencode": "1.1.
|
|
42
|
-
"@vite-plugin-opencode-assistant/
|
|
41
|
+
"@vite-plugin-opencode-assistant/shared": "1.1.26",
|
|
42
|
+
"@vite-plugin-opencode-assistant/opencode": "1.1.26",
|
|
43
|
+
"@vite-plugin-opencode-assistant/components": "1.1.26"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
46
|
"vite": ">=5.0.0"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@vite-plugin-opencode-assistant/client": "1.1.
|
|
49
|
+
"@vite-plugin-opencode-assistant/client": "1.1.26"
|
|
49
50
|
},
|
|
50
51
|
"scripts": {
|
|
51
52
|
"build": "pagoda-cli build && vite build -c vite.client.config.ts",
|