vite-plugin-opencode-assistant 1.1.25 → 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/endpoints/context.d.ts +0 -35
- package/es/endpoints/context.mjs +0 -119
- package/es/endpoints/mcp-tools.d.ts +2 -1
- package/es/endpoints/mcp-tools.mjs +370 -176
- package/es/endpoints/mcp.mjs +200 -169
- package/lib/core/mcp-chrome.cjs +174 -0
- package/lib/core/mcp-chrome.d.ts +43 -0
- package/lib/endpoints/context.cjs +0 -123
- package/lib/endpoints/context.d.ts +0 -35
- package/lib/endpoints/mcp-tools.cjs +368 -176
- package/lib/endpoints/mcp-tools.d.ts +2 -1
- package/lib/endpoints/mcp.cjs +193 -169
- package/package.json +5 -5
|
@@ -37,131 +37,12 @@ var __async = (__this, __arguments, generator) => {
|
|
|
37
37
|
};
|
|
38
38
|
var context_exports = {};
|
|
39
39
|
__export(context_exports, {
|
|
40
|
-
extractEvalValue: () => extractEvalValue,
|
|
41
|
-
getProjectOrigin: () => getProjectOrigin,
|
|
42
|
-
parseListPages: () => parseListPages,
|
|
43
|
-
resolveChromePageId: () => resolveChromePageId,
|
|
44
40
|
setupContextEndpoint: () => setupContextEndpoint
|
|
45
41
|
});
|
|
46
42
|
module.exports = __toCommonJS(context_exports);
|
|
47
43
|
var import_shared = require("@vite-plugin-opencode-assistant/shared");
|
|
48
44
|
var import_node = require("@vite-plugin-opencode-assistant/shared/node");
|
|
49
45
|
const log = (0, import_node.createLogger)("Endpoints:Context");
|
|
50
|
-
function getProjectOrigin(pageUrl) {
|
|
51
|
-
try {
|
|
52
|
-
return new URL(pageUrl).origin;
|
|
53
|
-
} catch (e) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function parseListPages(text) {
|
|
58
|
-
const pages = [];
|
|
59
|
-
for (const line of text.split("\n")) {
|
|
60
|
-
const match = line.match(/^(\d+):\s*(.+?)\s*\((\S+)\)/);
|
|
61
|
-
if (match) {
|
|
62
|
-
pages.push({
|
|
63
|
-
pageId: parseInt(match[1], 10),
|
|
64
|
-
title: match[2].replace(/\s*\.{3}$/, "").trim(),
|
|
65
|
-
url: match[3],
|
|
66
|
-
selected: /\[selected\]/i.test(line)
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return pages;
|
|
71
|
-
}
|
|
72
|
-
function extractEvalValue(text) {
|
|
73
|
-
if (!text) return void 0;
|
|
74
|
-
const marker = "```json\n";
|
|
75
|
-
const startIdx = text.indexOf(marker);
|
|
76
|
-
if (startIdx < 0) return text.trim();
|
|
77
|
-
const contentStart = startIdx + marker.length;
|
|
78
|
-
const endIdx = text.indexOf("\n```", contentStart);
|
|
79
|
-
const jsonStr = endIdx < 0 ? text.substring(contentStart) : text.substring(contentStart, endIdx);
|
|
80
|
-
try {
|
|
81
|
-
return JSON.parse(jsonStr.trim());
|
|
82
|
-
} catch (e) {
|
|
83
|
-
return jsonStr.trim();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function resolveChromePageId(mcp, url, title, sessionId, pages, chromeSelectedPageId) {
|
|
87
|
-
return __async(this, null, function* () {
|
|
88
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
89
|
-
if (!mcp || !mcp.isRunning) {
|
|
90
|
-
const reason = !mcp ? "MCP \u6A21\u5757\u672A\u521D\u59CB\u5316" : "Chrome DevTools MCP \u8FDB\u7A0B\u672A\u542F\u52A8";
|
|
91
|
-
log.debug(`resolveChromePageId: ${reason}`);
|
|
92
|
-
return { ok: false, error: reason };
|
|
93
|
-
}
|
|
94
|
-
if (!url) {
|
|
95
|
-
return { ok: false, error: "\u9875\u9762 URL \u4E3A\u7A7A\uFF0C\u5C1A\u672A\u6536\u5230\u4E0A\u4E0B\u6587\u4FE1\u606F" };
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
if (!pages) {
|
|
99
|
-
const listResult = yield mcp.callChromeDevTool("list_pages", {});
|
|
100
|
-
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;
|
|
101
|
-
if (!text) {
|
|
102
|
-
return { ok: false, error: "\u65E0\u6CD5\u83B7\u53D6 Chrome \u9875\u9762\u5217\u8868\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u6253\u5F00\u76EE\u6807\u9875\u9762" };
|
|
103
|
-
}
|
|
104
|
-
const allPages = parseListPages(text);
|
|
105
|
-
chromeSelectedPageId = (_d = allPages.find((p) => p.selected)) == null ? void 0 : _d.pageId;
|
|
106
|
-
const projectOrigin = getProjectOrigin(url);
|
|
107
|
-
pages = projectOrigin ? allPages.filter((p) => p.url.startsWith(projectOrigin)) : allPages;
|
|
108
|
-
}
|
|
109
|
-
log.debug("resolveChromePageId: list_pages result", {
|
|
110
|
-
pages: pages.map((p) => ({ id: p.pageId, url: p.url, title: p.title.substring(0, 40) })),
|
|
111
|
-
target: { url, title }
|
|
112
|
-
});
|
|
113
|
-
const normalizeUrl = (u) => u.replace(/\/$/, "");
|
|
114
|
-
const targetUrl = normalizeUrl(url);
|
|
115
|
-
if (sessionId) {
|
|
116
|
-
let matchedPageId = null;
|
|
117
|
-
for (const page of pages) {
|
|
118
|
-
yield mcp.callChromeDevTool("select_page", { pageId: page.pageId, bringToFront: false });
|
|
119
|
-
const evalResult = yield mcp.callChromeDevTool("evaluate_script", {
|
|
120
|
-
function: "() => sessionStorage.getItem('_opencode_pk')"
|
|
121
|
-
});
|
|
122
|
-
const rawText = (_g = (_f = (_e = evalResult == null ? void 0 : evalResult.result) == null ? void 0 : _e.content) == null ? void 0 : _f[0]) == null ? void 0 : _g.text;
|
|
123
|
-
const extracted = extractEvalValue(rawText);
|
|
124
|
-
if (extracted === sessionId) {
|
|
125
|
-
matchedPageId = page.pageId;
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
if (chromeSelectedPageId != null && chromeSelectedPageId !== matchedPageId) {
|
|
130
|
-
yield mcp.callChromeDevTool("select_page", {
|
|
131
|
-
pageId: chromeSelectedPageId,
|
|
132
|
-
bringToFront: false
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
if (matchedPageId != null) {
|
|
136
|
-
return { ok: true, pageId: matchedPageId };
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
ok: false,
|
|
140
|
-
error: `\u672A\u80FD\u901A\u8FC7\u4F1A\u8BDD\u6807\u8BC6\u627E\u5230\u76EE\u6807\u9875\u9762\uFF0C\u8BF7\u786E\u8BA4\u76EE\u6807\u9875\u9762\u5DF2\u6253\u5F00`
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
const matches = pages.filter((p) => normalizeUrl(p.url) === targetUrl);
|
|
144
|
-
if (matches.length === 0) {
|
|
145
|
-
return {
|
|
146
|
-
ok: false,
|
|
147
|
-
error: `Chrome \u4E2D\u672A\u627E\u5230\u5339\u914D\u7684\u9875\u9762 (${targetUrl})\uFF0C\u8BF7\u786E\u8BA4\u672C\u5730\u5F00\u53D1\u9875\u9762\u5DF2\u5728 Chrome DevTools \u4E2D\u6253\u5F00`
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
if (matches.length === 1) {
|
|
151
|
-
log.debug("resolveChromePageId: URL matched", { pageId: matches[0].pageId });
|
|
152
|
-
return { ok: true, pageId: matches[0].pageId };
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
ok: false,
|
|
156
|
-
error: `\u5B58\u5728 ${matches.length} \u4E2A\u540C URL \u7684\u9875\u9762\uFF0C\u7F3A\u5C11\u9875\u9762\u6807\u8BC6\u65E0\u6CD5\u533A\u5206\uFF0C\u8BF7\u5237\u65B0\u9875\u9762\u540E\u91CD\u8BD5`
|
|
157
|
-
};
|
|
158
|
-
} catch (err) {
|
|
159
|
-
const msg = `MCP \u8C03\u7528\u5931\u8D25: ${err.message}`;
|
|
160
|
-
log.debug("Failed to resolve pageId via MCP", { error: err.message });
|
|
161
|
-
return { ok: false, error: msg };
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
46
|
function setupContextEndpoint(server, ctx) {
|
|
166
47
|
server.middlewares.use(import_shared.CONTEXT_API_PATH, (req, res) => __async(null, null, function* () {
|
|
167
48
|
const reqCtx = new import_node.RequestContext(req.method || "GET", import_shared.CONTEXT_API_PATH);
|
|
@@ -268,9 +149,5 @@ function setupContextEndpoint(server, ctx) {
|
|
|
268
149
|
}
|
|
269
150
|
// Annotate the CommonJS export names for ESM import in node:
|
|
270
151
|
0 && (module.exports = {
|
|
271
|
-
extractEvalValue,
|
|
272
|
-
getProjectOrigin,
|
|
273
|
-
parseListPages,
|
|
274
|
-
resolveChromePageId,
|
|
275
152
|
setupContextEndpoint
|
|
276
153
|
});
|
|
@@ -1,38 +1,3 @@
|
|
|
1
1
|
import type { ViteDevServer } from "vite";
|
|
2
|
-
import type { McpProxy } from "../core/mcp-proxy";
|
|
3
2
|
import type { EndpointContext } from "./types";
|
|
4
|
-
/** 从页面 URL 提取项目 origin(protocol + host + port) */
|
|
5
|
-
export declare function getProjectOrigin(pageUrl: string): string | null;
|
|
6
|
-
export interface PageInfo {
|
|
7
|
-
pageId: number;
|
|
8
|
-
url: string;
|
|
9
|
-
title: string;
|
|
10
|
-
/** Chrome DevTools 当前选中的页面 */
|
|
11
|
-
selected: boolean;
|
|
12
|
-
}
|
|
13
|
-
/** 解析 list_pages 返回的文本。格式:"56: Title (URL) [selected]" */
|
|
14
|
-
export declare function parseListPages(text: string): PageInfo[];
|
|
15
|
-
/** 从 evaluate_script 返回的格式化文本中提取 JSON 值 */
|
|
16
|
-
export declare function extractEvalValue(text: string | undefined): string | undefined;
|
|
17
|
-
type PageIdResult = {
|
|
18
|
-
ok: true;
|
|
19
|
-
pageId: number;
|
|
20
|
-
} | {
|
|
21
|
-
ok: false;
|
|
22
|
-
error: string;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* 通过 MCP 解析当前页面对应的 Chrome DevTools pageId
|
|
26
|
-
*
|
|
27
|
-
* 策略:
|
|
28
|
-
* 1. list_pages → 解析每行的 "pageId: title (URL)" 格式
|
|
29
|
-
* 2. 优先用 sessionId 匹配(跨导航可靠,遍历所有页面 evaluate_script)
|
|
30
|
-
* 3. 无 sessionId 时降级为 URL 精确匹配
|
|
31
|
-
*
|
|
32
|
-
* 失败时返回具体原因,由调用方透传给 Agent。
|
|
33
|
-
*/
|
|
34
|
-
export declare function resolveChromePageId(mcp: McpProxy | undefined, url: string, title: string, sessionId?: string, pages?: PageInfo[],
|
|
35
|
-
/** Chrome 当前选中的 pageId(调用方传入,避免过滤后丢失非项目页面信息) */
|
|
36
|
-
chromeSelectedPageId?: number): Promise<PageIdResult>;
|
|
37
3
|
export declare function setupContextEndpoint(server: ViteDevServer, ctx: EndpointContext): void;
|
|
38
|
-
export {};
|