vite-plugin-aipanel 1.2.9 → 1.2.11
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 +53 -35
- package/es/core/chrome-project.d.ts +15 -0
- package/es/core/chrome-project.mjs +13 -0
- package/es/core/mcp-chrome.d.ts +12 -8
- package/es/core/mcp-chrome.mjs +52 -10
- package/es/core/mcp-proxy.d.ts +14 -1
- package/es/core/mcp-proxy.mjs +49 -10
- package/es/core/mcp-tools.d.ts +54 -3
- package/es/core/mcp-tools.mjs +111 -659
- package/es/core/official-meta.d.ts +9 -0
- package/es/core/official-meta.mjs +62 -0
- package/es/core/official-tools.d.ts +7 -0
- package/es/core/official-tools.mjs +54 -0
- package/es/core/service.mjs +4 -5
- package/es/endpoints/context.mjs +2 -2
- package/es/endpoints/host-events.mjs +2 -3
- package/es/endpoints/index.d.ts +2 -2
- package/es/endpoints/index.mjs +2 -2
- package/es/endpoints/mcp.d.ts +2 -2
- package/es/endpoints/mcp.mjs +116 -87
- package/es/endpoints/sse.mjs +3 -3
- package/es/endpoints/vue-devtools.d.ts +5 -2
- package/es/endpoints/vue-devtools.mjs +3 -4
- package/es/index.mjs +21 -4
- package/lib/client.css +1 -1
- package/lib/client.js +2590 -2435
- package/lib/core/chrome-project.cjs +36 -0
- package/lib/core/chrome-project.d.ts +15 -0
- package/lib/core/mcp-chrome.cjs +64 -10
- package/lib/core/mcp-chrome.d.ts +12 -8
- package/lib/core/mcp-proxy.cjs +50 -10
- package/lib/core/mcp-proxy.d.ts +14 -1
- package/lib/core/mcp-tools.cjs +126 -660
- package/lib/core/mcp-tools.d.ts +54 -3
- package/lib/core/official-meta.cjs +85 -0
- package/lib/core/official-meta.d.ts +9 -0
- package/lib/core/official-tools.cjs +70 -0
- package/lib/core/official-tools.d.ts +7 -0
- package/lib/core/service.cjs +4 -5
- package/lib/endpoints/context.cjs +1 -1
- package/lib/endpoints/host-events.cjs +1 -2
- package/lib/endpoints/index.cjs +2 -2
- package/lib/endpoints/index.d.ts +2 -2
- package/lib/endpoints/mcp.cjs +114 -85
- package/lib/endpoints/mcp.d.ts +2 -2
- package/lib/endpoints/sse.cjs +2 -2
- package/lib/endpoints/vue-devtools.cjs +4 -5
- package/lib/endpoints/vue-devtools.d.ts +5 -2
- package/lib/index.cjs +22 -5
- package/package.json +10 -7
- package/es/utils/format-bridge.d.ts +0 -9
- package/es/utils/format-bridge.mjs +0 -87
- package/es/utils/system.d.ts +0 -3
- package/es/utils/system.mjs +0 -76
- package/lib/utils/format-bridge.cjs +0 -103
- package/lib/utils/format-bridge.d.ts +0 -9
- package/lib/utils/system.cjs +0 -110
- package/lib/utils/system.d.ts +0 -3
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** AUTO-GENERATED by packages/vite/scripts/sync-official-meta.mjs (build) — 不手改;升级 chrome-devtools-mcp 后重跑构建即可。 */
|
|
2
|
+
export interface OfficialToolMeta {
|
|
3
|
+
name: string;
|
|
4
|
+
category: "INPUT" | "NAVIGATION" | "EMULATION" | "PERFORMANCE" | "NETWORK" | "DEBUGGING" | "EXTENSIONS" | "THIRD_PARTY" | "MEMORY" | "WEBMCP" | "PWA" | "";
|
|
5
|
+
readOnlyHint: boolean;
|
|
6
|
+
pageScoped: boolean;
|
|
7
|
+
conditions: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare const OFFICIAL_TOOL_META: OfficialToolMeta[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const OFFICIAL_TOOL_META = [
|
|
2
|
+
{ name: "click", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
3
|
+
{ name: "click_at", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: ["experimentalVision"] },
|
|
4
|
+
{ name: "close_heapsnapshot", category: "MEMORY", readOnlyHint: false, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
5
|
+
{ name: "close_page", category: "NAVIGATION", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
6
|
+
{ name: "compare_heapsnapshots", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
7
|
+
{ name: "drag", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
8
|
+
{ name: "emulate", category: "EMULATION", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
9
|
+
{ name: "evaluate_script", category: "DEBUGGING", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
10
|
+
{ name: "execute_3p_developer_tool", category: "THIRD_PARTY", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
11
|
+
{ name: "execute_webmcp_tool", category: "WEBMCP", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
12
|
+
{ name: "fill", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
13
|
+
{ name: "fill_form", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
14
|
+
{ name: "get_console_message", category: "DEBUGGING", readOnlyHint: true, pageScoped: true, conditions: [] },
|
|
15
|
+
{ name: "get_heapsnapshot_class_nodes", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
16
|
+
{ name: "get_heapsnapshot_details", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
17
|
+
{ name: "get_heapsnapshot_dominators", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
18
|
+
{ name: "get_heapsnapshot_duplicate_strings", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
19
|
+
{ name: "get_heapsnapshot_edges", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
20
|
+
{ name: "get_heapsnapshot_object_details", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
21
|
+
{ name: "get_heapsnapshot_retainers", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
22
|
+
{ name: "get_heapsnapshot_retaining_paths", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
23
|
+
{ name: "get_heapsnapshot_summary", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
24
|
+
{ name: "get_network_request", category: "NETWORK", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
25
|
+
{ name: "get_os_app_state", category: "PWA", readOnlyHint: true, pageScoped: false, conditions: [] },
|
|
26
|
+
{ name: "get_tab_id", category: "NAVIGATION", readOnlyHint: true, pageScoped: true, conditions: ["experimentalInteropTools"] },
|
|
27
|
+
{ name: "handle_dialog", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
28
|
+
{ name: "hover", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
29
|
+
{ name: "install_extension", category: "EXTENSIONS", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
30
|
+
{ name: "install_pwa", category: "PWA", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
31
|
+
{ name: "launch_pwa", category: "PWA", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
32
|
+
{ name: "lighthouse_audit", category: "DEBUGGING", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
33
|
+
{ name: "list_3p_developer_tools", category: "THIRD_PARTY", readOnlyHint: true, pageScoped: true, conditions: [] },
|
|
34
|
+
{ name: "list_extensions", category: "EXTENSIONS", readOnlyHint: true, pageScoped: false, conditions: [] },
|
|
35
|
+
{ name: "list_network_requests", category: "NETWORK", readOnlyHint: true, pageScoped: true, conditions: [] },
|
|
36
|
+
{ name: "list_pages", category: "NAVIGATION", readOnlyHint: true, pageScoped: false, conditions: [] },
|
|
37
|
+
{ name: "list_webmcp_tools", category: "WEBMCP", readOnlyHint: true, pageScoped: true, conditions: [] },
|
|
38
|
+
{ name: "navigate_page", category: "NAVIGATION", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
39
|
+
{ name: "new_page", category: "NAVIGATION", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
40
|
+
{ name: "performance_analyze_insight", category: "PERFORMANCE", readOnlyHint: true, pageScoped: true, conditions: [] },
|
|
41
|
+
{ name: "performance_start_trace", category: "PERFORMANCE", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
42
|
+
{ name: "performance_stop_trace", category: "PERFORMANCE", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
43
|
+
{ name: "press_key", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
44
|
+
{ name: "query_heapsnapshot_objects", category: "MEMORY", readOnlyHint: true, pageScoped: false, conditions: ["memoryDebugging"] },
|
|
45
|
+
{ name: "reload_extension", category: "EXTENSIONS", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
46
|
+
{ name: "resize_page", category: "EMULATION", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
47
|
+
{ name: "screencast_start", category: "DEBUGGING", readOnlyHint: false, pageScoped: true, conditions: ["experimentalScreencast"] },
|
|
48
|
+
{ name: "screencast_stop", category: "DEBUGGING", readOnlyHint: false, pageScoped: true, conditions: ["experimentalScreencast"] },
|
|
49
|
+
{ name: "select_page", category: "NAVIGATION", readOnlyHint: true, pageScoped: false, conditions: [] },
|
|
50
|
+
{ name: "take_heapsnapshot", category: "MEMORY", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
51
|
+
{ name: "take_screenshot", category: "DEBUGGING", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
52
|
+
{ name: "take_snapshot", category: "DEBUGGING", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
53
|
+
{ name: "trigger_extension_action", category: "EXTENSIONS", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
54
|
+
{ name: "type_text", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
55
|
+
{ name: "uninstall_extension", category: "EXTENSIONS", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
56
|
+
{ name: "uninstall_pwa", category: "PWA", readOnlyHint: false, pageScoped: false, conditions: [] },
|
|
57
|
+
{ name: "upload_file", category: "INPUT", readOnlyHint: false, pageScoped: true, conditions: [] },
|
|
58
|
+
{ name: "wait_for", category: "NAVIGATION", readOnlyHint: true, pageScoped: true, conditions: [] }
|
|
59
|
+
];
|
|
60
|
+
export {
|
|
61
|
+
OFFICIAL_TOOL_META
|
|
62
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type CustomTool } from "./mcp-tools";
|
|
2
|
+
import type { McpProxy } from "./mcp-proxy";
|
|
3
|
+
/**
|
|
4
|
+
* 项目白名单的官方工具集(英文 schema/描述,已追加 pageId)。
|
|
5
|
+
* 官方当前版本缺失某名时跳过(名称跟随官方,不本地复制)。
|
|
6
|
+
*/
|
|
7
|
+
export declare function getOfficialProjectTools(mcp: McpProxy): Promise<CustomTool[]>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createLogger } from "@aipanel/core/node";
|
|
2
|
+
import {
|
|
3
|
+
MCP_PREFIX,
|
|
4
|
+
OFFICIAL_NO_PAGE_TOOLS,
|
|
5
|
+
PROJECT_DESCRIPTION_NOTES,
|
|
6
|
+
currentOfficialShorts,
|
|
7
|
+
displayToolName,
|
|
8
|
+
withPageIdSchema
|
|
9
|
+
} from "./mcp-tools.mjs";
|
|
10
|
+
const log = createLogger("OfficialChromeTools");
|
|
11
|
+
let cached = null;
|
|
12
|
+
async function fetchOfficialEntries(mcp) {
|
|
13
|
+
const res = await mcp.call("tools/list", {});
|
|
14
|
+
const map = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const t of res?.result?.tools ?? []) {
|
|
16
|
+
const raw = String(t?.name ?? "");
|
|
17
|
+
const short = raw.startsWith(MCP_PREFIX) ? raw.slice(MCP_PREFIX.length) : raw;
|
|
18
|
+
if (!short) continue;
|
|
19
|
+
const schema = t?.inputSchema ?? { type: "object", properties: {} };
|
|
20
|
+
map.set(short, { short, description: String(t?.description ?? ""), schema });
|
|
21
|
+
}
|
|
22
|
+
return map;
|
|
23
|
+
}
|
|
24
|
+
function ensureOfficialEntries(mcp) {
|
|
25
|
+
if (!cached) {
|
|
26
|
+
cached = fetchOfficialEntries(mcp).catch((e) => {
|
|
27
|
+
cached = null;
|
|
28
|
+
log.warn("Failed to fetch official chrome-devtools-mcp tools", {
|
|
29
|
+
error: e instanceof Error ? e.message : String(e)
|
|
30
|
+
});
|
|
31
|
+
throw e;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return cached;
|
|
35
|
+
}
|
|
36
|
+
async function getOfficialProjectTools(mcp) {
|
|
37
|
+
const map = await ensureOfficialEntries(mcp);
|
|
38
|
+
const tools = [];
|
|
39
|
+
for (const short of currentOfficialShorts()) {
|
|
40
|
+
const entry = map.get(short);
|
|
41
|
+
if (!entry) {
|
|
42
|
+
log.warn("Requested official tool missing from server tools/list (skip)", { short });
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const schema = OFFICIAL_NO_PAGE_TOOLS.has(short) ? entry.schema : withPageIdSchema(entry.schema);
|
|
46
|
+
const note = PROJECT_DESCRIPTION_NOTES[short];
|
|
47
|
+
const description = note ? entry.description ? `${entry.description} ${note}` : note : entry.description;
|
|
48
|
+
tools.push({ name: displayToolName(short), description, inputSchema: schema });
|
|
49
|
+
}
|
|
50
|
+
return tools;
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
getOfficialProjectTools
|
|
54
|
+
};
|
package/es/core/service.mjs
CHANGED
|
@@ -2,9 +2,8 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
|
-
import { DEFAULT_PROXY_PORT, SERVER_START_TIMEOUT, ChromeMcpWarmupErrorType } from "@aipanel/core";
|
|
6
|
-
import { createLogger, findAvailablePort } from "@aipanel/core/node";
|
|
7
|
-
import { findGitRoot, waitForServer } from "../utils/system.mjs";
|
|
5
|
+
import { DEFAULT_PROXY_PORT, SERVER_START_TIMEOUT, SSE_EVENT_TYPES, ChromeMcpWarmupErrorType } from "@aipanel/core";
|
|
6
|
+
import { createLogger, findAvailablePort, findGitRoot, waitForServer } from "@aipanel/core/node";
|
|
8
7
|
import { startProxyServer } from "./proxy-server.mjs";
|
|
9
8
|
const log = createLogger("Service");
|
|
10
9
|
class AIPanelService {
|
|
@@ -43,7 +42,7 @@ class AIPanelService {
|
|
|
43
42
|
this.currentTask = { task, ...data };
|
|
44
43
|
this.sseClients.forEach((client) => {
|
|
45
44
|
try {
|
|
46
|
-
client.write(`data: ${JSON.stringify({ type:
|
|
45
|
+
client.write(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.TASK_UPDATE, task, ...data })}
|
|
47
46
|
|
|
48
47
|
`);
|
|
49
48
|
} catch (e) {
|
|
@@ -230,7 +229,7 @@ class AIPanelService {
|
|
|
230
229
|
pushProviderEvent(event) {
|
|
231
230
|
this.sseClients.forEach((client) => {
|
|
232
231
|
try {
|
|
233
|
-
client.write(`data: ${JSON.stringify({ type:
|
|
232
|
+
client.write(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.SESSION_EVENT, event })}
|
|
234
233
|
|
|
235
234
|
`);
|
|
236
235
|
} catch (e) {
|
package/es/endpoints/context.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONTEXT_API_PATH } from "@aipanel/core";
|
|
1
|
+
import { CONTEXT_API_PATH, SSE_EVENT_TYPES } from "@aipanel/core";
|
|
2
2
|
import { RequestContext, createLogger } from "@aipanel/core/node";
|
|
3
3
|
import { ensureNodeId } from "@aipanel/core";
|
|
4
4
|
const log = createLogger("Endpoints:Context");
|
|
@@ -28,7 +28,7 @@ function setupContextEndpoint(server, ctx) {
|
|
|
28
28
|
let sentCount = 0;
|
|
29
29
|
ctx.sseClients.forEach((client) => {
|
|
30
30
|
try {
|
|
31
|
-
client.write(`data: ${JSON.stringify({ type:
|
|
31
|
+
client.write(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.CLEAR_ELEMENTS })}
|
|
32
32
|
|
|
33
33
|
`);
|
|
34
34
|
sentCount++;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { HOST_EVENTS_API_PATH } from "@aipanel/core";
|
|
2
|
-
import { RequestContext
|
|
3
|
-
const log = createLogger("Endpoints:HostEvents");
|
|
2
|
+
import { RequestContext } from "@aipanel/core/node";
|
|
4
3
|
function setupHostEventsEndpoint(server, ctx) {
|
|
5
4
|
server.middlewares.use(HOST_EVENTS_API_PATH, async (req, res) => {
|
|
6
5
|
const reqCtx = new RequestContext(req.method || "GET", HOST_EVENTS_API_PATH);
|
|
@@ -62,7 +61,7 @@ function setupHostEventsEndpoint(server, ctx) {
|
|
|
62
61
|
function isProviderEvent(value) {
|
|
63
62
|
if (typeof value !== "object" || value === null) return false;
|
|
64
63
|
const v = value;
|
|
65
|
-
if (v.type === "session.status" || v.type === "thinking") {
|
|
64
|
+
if (v.type === "session.status" || v.type === "thinking" || v.type === "session.pending" || v.type === "session.subagents") {
|
|
66
65
|
return typeof v.sessionId === "string" && v.sessionId.length > 0;
|
|
67
66
|
}
|
|
68
67
|
if (v.type === "session.updated") {
|
package/es/endpoints/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { EndpointContext } from "./types";
|
|
|
3
3
|
import { MCP_API_PATH } from "./mcp";
|
|
4
4
|
import { VUE_DEVTOOLS_API_PATH } from "./vue-devtools";
|
|
5
5
|
import type { McpProxy } from "../core/mcp-proxy";
|
|
6
|
-
import { LOGS_API_PATH, type LogFileConfig } from "@aipanel/core";
|
|
6
|
+
import { LOGS_API_PATH, type ChromeProjectOptions, type LogFileConfig } from "@aipanel/core";
|
|
7
7
|
export * from "./types";
|
|
8
8
|
export { LOGS_API_PATH, MCP_API_PATH, VUE_DEVTOOLS_API_PATH };
|
|
9
|
-
export declare function setupMiddlewares(server: ViteDevServer, ctx: EndpointContext, mcp?: McpProxy, logFiles?: LogFileConfig[]): void;
|
|
9
|
+
export declare function setupMiddlewares(server: ViteDevServer, ctx: EndpointContext, mcp?: McpProxy, logFiles?: LogFileConfig[], chromeProject?: ChromeProjectOptions): void;
|
package/es/endpoints/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { setupMcpEndpoint, MCP_API_PATH } from "./mcp.mjs";
|
|
|
10
10
|
import { setupVueDevtoolsEndpoint, VUE_DEVTOOLS_API_PATH } from "./vue-devtools.mjs";
|
|
11
11
|
import { LOGS_API_PATH } from "@aipanel/core";
|
|
12
12
|
export * from "./types.mjs";
|
|
13
|
-
function setupMiddlewares(server, ctx, mcp, logFiles) {
|
|
13
|
+
function setupMiddlewares(server, ctx, mcp, logFiles, chromeProject) {
|
|
14
14
|
setupWidgetEndpoints(server, ctx);
|
|
15
15
|
setupContextEndpoint(server, ctx);
|
|
16
16
|
setupStartEndpoint(server, ctx);
|
|
@@ -20,7 +20,7 @@ function setupMiddlewares(server, ctx, mcp, logFiles) {
|
|
|
20
20
|
setupWarmupEndpoint(server, ctx);
|
|
21
21
|
setupLogsEndpoint(server);
|
|
22
22
|
if (mcp) {
|
|
23
|
-
setupMcpEndpoint(server, mcp, () => ctx.getPageContext(), logFiles ?? []);
|
|
23
|
+
setupMcpEndpoint(server, mcp, () => ctx.getPageContext(), logFiles ?? [], chromeProject);
|
|
24
24
|
setupVueDevtoolsEndpoint(server, mcp);
|
|
25
25
|
}
|
|
26
26
|
}
|
package/es/endpoints/mcp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ViteDevServer } from "vite";
|
|
2
|
-
import type { LogFileConfig, PageContext } from "@aipanel/core";
|
|
2
|
+
import type { ChromeProjectOptions, LogFileConfig, PageContext } from "@aipanel/core";
|
|
3
3
|
import { MCP_API_PATH } from "@aipanel/core";
|
|
4
4
|
import { McpProxy } from "../core/mcp-proxy";
|
|
5
5
|
export { MCP_API_PATH };
|
|
6
|
-
export declare function setupMcpEndpoint(server: ViteDevServer, mcp: McpProxy, getPageContext: () => PageContext, logFiles?: LogFileConfig[]): void;
|
|
6
|
+
export declare function setupMcpEndpoint(server: ViteDevServer, mcp: McpProxy, getPageContext: () => PageContext, logFiles?: LogFileConfig[], chromeProject?: ChromeProjectOptions): void;
|
package/es/endpoints/mcp.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MCP_API_PATH, VUE_DEVTOOLS_ACTIONS
|
|
1
|
+
import { MCP_API_PATH, VUE_DEVTOOLS_ACTIONS } from "@aipanel/core";
|
|
2
2
|
import {
|
|
3
3
|
createLogger,
|
|
4
4
|
getProcessLogBuffer,
|
|
@@ -7,15 +7,17 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
parseListPages,
|
|
9
9
|
resolveChromePageId,
|
|
10
|
-
|
|
10
|
+
isPageAllowed,
|
|
11
11
|
isProjectPage,
|
|
12
12
|
validatePageId
|
|
13
13
|
} from "../core/mcp-chrome.mjs";
|
|
14
|
-
import {
|
|
14
|
+
import { resolveProjectScope } from "../core/chrome-project.mjs";
|
|
15
|
+
import { CUSTOM_TOOLS, isAllowedToolName } from "../core/mcp-tools.mjs";
|
|
16
|
+
import { getOfficialProjectTools } from "../core/official-tools.mjs";
|
|
15
17
|
import { executeAction } from "./vue-devtools.mjs";
|
|
16
|
-
import { findGitRoot } from "
|
|
18
|
+
import { findGitRoot } from "@aipanel/core/node";
|
|
17
19
|
const log = createLogger("McpEndpoint");
|
|
18
|
-
function setupMcpEndpoint(server, mcp, getPageContext, logFiles = []) {
|
|
20
|
+
function setupMcpEndpoint(server, mcp, getPageContext, logFiles = [], chromeProject) {
|
|
19
21
|
const projectRoot = findGitRoot(process.cwd());
|
|
20
22
|
server.middlewares.use(async (req, res, next) => {
|
|
21
23
|
if (!req.url?.startsWith(MCP_API_PATH)) return next();
|
|
@@ -38,11 +40,14 @@ function setupMcpEndpoint(server, mcp, getPageContext, logFiles = []) {
|
|
|
38
40
|
return;
|
|
39
41
|
}
|
|
40
42
|
if (req.method === "POST") {
|
|
43
|
+
const scope = resolveProjectScope(server, chromeProject);
|
|
41
44
|
await handlePost(
|
|
42
45
|
req,
|
|
43
46
|
res,
|
|
44
47
|
mcp,
|
|
45
|
-
|
|
48
|
+
scope.origins,
|
|
49
|
+
scope.operationsOrigins,
|
|
50
|
+
scope.includeExtensions,
|
|
46
51
|
getPageContext,
|
|
47
52
|
logFiles,
|
|
48
53
|
projectRoot
|
|
@@ -63,7 +68,7 @@ function handleGetSse(req, res, mcp) {
|
|
|
63
68
|
const keepAlive = setInterval(() => res.write(":ping\n\n"), 15e3);
|
|
64
69
|
req.on("close", () => clearInterval(keepAlive));
|
|
65
70
|
}
|
|
66
|
-
async function handlePost(req, res, mcp, projectOrigins, getPageContext, logFiles, projectRoot) {
|
|
71
|
+
async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot) {
|
|
67
72
|
try {
|
|
68
73
|
const body = await readBody(req);
|
|
69
74
|
if (!body) {
|
|
@@ -75,7 +80,7 @@ async function handlePost(req, res, mcp, projectOrigins, getPageContext, logFile
|
|
|
75
80
|
log.debug("MCP request", { method, body: body.substring(0, 150) });
|
|
76
81
|
switch (method) {
|
|
77
82
|
case "tools/list":
|
|
78
|
-
return handleToolsList(res, id, mcp
|
|
83
|
+
return await handleToolsList(res, id, mcp, logFiles);
|
|
79
84
|
case "tools/call":
|
|
80
85
|
return await handleToolsCall(
|
|
81
86
|
res,
|
|
@@ -83,6 +88,8 @@ async function handlePost(req, res, mcp, projectOrigins, getPageContext, logFile
|
|
|
83
88
|
body,
|
|
84
89
|
mcp,
|
|
85
90
|
projectOrigins,
|
|
91
|
+
operationsOrigins,
|
|
92
|
+
includeExtensions,
|
|
86
93
|
getPageContext,
|
|
87
94
|
logFiles,
|
|
88
95
|
projectRoot
|
|
@@ -98,16 +105,24 @@ async function handlePost(req, res, mcp, projectOrigins, getPageContext, logFile
|
|
|
98
105
|
});
|
|
99
106
|
}
|
|
100
107
|
}
|
|
101
|
-
function handleToolsList(res, id,
|
|
102
|
-
|
|
103
|
-
|
|
108
|
+
async function handleToolsList(res, id, mcp, logFiles) {
|
|
109
|
+
let official = [];
|
|
110
|
+
try {
|
|
111
|
+
official = await getOfficialProjectTools(mcp);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
log.warn("official chrome tools unavailable for tools/list", {
|
|
114
|
+
error: e instanceof Error ? e.message : String(e)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const tools = [...official, ...CUSTOM_TOOLS, ...buildServiceLogTools(logFiles)];
|
|
118
|
+
sendMcpJson(res, 200, { jsonrpc: "2.0", id, result: { tools } }, mcp.sessionId);
|
|
104
119
|
}
|
|
105
|
-
function handleToolsCall(res, id, body, mcp, projectOrigins, getPageContext, logFiles, projectRoot) {
|
|
120
|
+
function handleToolsCall(res, id, body, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot) {
|
|
106
121
|
const params = tryParseParams(body);
|
|
107
122
|
const toolName = params?.name;
|
|
108
123
|
const args = params?.arguments ?? {};
|
|
109
124
|
if (toolName === "chrome-devtools_current_page") {
|
|
110
|
-
return handleGetPageContext(res, id, mcp,
|
|
125
|
+
return handleGetPageContext(res, id, mcp, operationsOrigins, includeExtensions, getPageContext);
|
|
111
126
|
}
|
|
112
127
|
if (toolName?.startsWith("vue-devtools_")) {
|
|
113
128
|
return handleVueDevtoolsTool(res, id, mcp, projectOrigins, toolName, args);
|
|
@@ -121,25 +136,40 @@ function handleToolsCall(res, id, body, mcp, projectOrigins, getPageContext, log
|
|
|
121
136
|
if (toolName?.startsWith("chrome-devtools_")) {
|
|
122
137
|
const mapped = toolName.slice("chrome-devtools_".length);
|
|
123
138
|
if (toolName === "chrome-devtools_list_pages") {
|
|
124
|
-
return handleListPages(res, id, mcp,
|
|
139
|
+
return handleListPages(res, id, mcp, operationsOrigins, includeExtensions, getPageContext);
|
|
125
140
|
}
|
|
126
141
|
if (toolName === "chrome-devtools_new_page") {
|
|
127
|
-
return handleNewPage(res, id, mcp, args, projectOrigins,
|
|
142
|
+
return handleNewPage(res, id, mcp, args, projectOrigins, operationsOrigins);
|
|
128
143
|
}
|
|
129
|
-
|
|
144
|
+
if (!isAllowedToolName(toolName)) {
|
|
145
|
+
return sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, mcp.sessionId);
|
|
146
|
+
}
|
|
147
|
+
return handleDevTool(
|
|
148
|
+
res,
|
|
149
|
+
id,
|
|
150
|
+
mcp,
|
|
151
|
+
mapped,
|
|
152
|
+
args,
|
|
153
|
+
operationsOrigins,
|
|
154
|
+
includeExtensions,
|
|
155
|
+
projectRoot,
|
|
156
|
+
toolName
|
|
157
|
+
);
|
|
130
158
|
}
|
|
131
159
|
sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, mcp.sessionId);
|
|
132
160
|
}
|
|
133
|
-
async function resolveProjectPages(mcp,
|
|
161
|
+
async function resolveProjectPages(mcp, operationsOrigins, includeExtensions, getPageContext) {
|
|
134
162
|
const listResult = await mcp.callChromeDevTool("list_pages", {});
|
|
135
163
|
if (listResult?.error || !listResult?.result) {
|
|
136
164
|
throw new Error(listResult?.error?.message ?? "\u65E0\u6CD5\u83B7\u53D6 Chrome \u9875\u9762\u5217\u8868");
|
|
137
165
|
}
|
|
138
166
|
const text = listResult?.result?.content?.[0]?.text;
|
|
139
167
|
const allPages = text ? parseListPages(text) : [];
|
|
140
|
-
const filtered = allPages.filter(
|
|
168
|
+
const filtered = allPages.filter(
|
|
169
|
+
(p) => isPageAllowed(p.url, operationsOrigins, includeExtensions)
|
|
170
|
+
);
|
|
141
171
|
log.debug("Chrome pages", { total: allPages.length, urls: allPages.map((p) => p.url) });
|
|
142
|
-
log.debug("
|
|
172
|
+
log.debug("operations origins", { origins: operationsOrigins });
|
|
143
173
|
log.debug("filtered pages", { count: filtered.length, pageIds: filtered.map((p) => p.pageId) });
|
|
144
174
|
let activePageId = null;
|
|
145
175
|
let activePageError;
|
|
@@ -150,7 +180,7 @@ async function resolveProjectPages(mcp, projectOrigins, getPageContext) {
|
|
|
150
180
|
mcp,
|
|
151
181
|
pc.url,
|
|
152
182
|
pc.title,
|
|
153
|
-
|
|
183
|
+
operationsOrigins,
|
|
154
184
|
pc.sessionId,
|
|
155
185
|
filtered,
|
|
156
186
|
chromeSelectedPageId
|
|
@@ -160,37 +190,21 @@ async function resolveProjectPages(mcp, projectOrigins, getPageContext) {
|
|
|
160
190
|
}
|
|
161
191
|
return { filtered, activePageId, activePageError };
|
|
162
192
|
}
|
|
163
|
-
async function
|
|
164
|
-
let pages = [];
|
|
165
|
-
let ok = false;
|
|
166
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
167
|
-
try {
|
|
168
|
-
({ filtered: pages } = await resolveProjectPages(mcp, projectOrigins, getPageContext));
|
|
169
|
-
ok = true;
|
|
170
|
-
break;
|
|
171
|
-
} catch {
|
|
172
|
-
if (attempt < 2) await sleep(500);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (!ok) return null;
|
|
176
|
-
if (pages.length === 0) {
|
|
177
|
-
await sleep(500);
|
|
178
|
-
try {
|
|
179
|
-
({ filtered: pages } = await resolveProjectPages(mcp, projectOrigins, getPageContext));
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return pages;
|
|
184
|
-
}
|
|
185
|
-
async function handleListPages(res, id, mcp, projectOrigins, getPageContext) {
|
|
193
|
+
async function handleListPages(res, id, mcp, operationsOrigins, includeExtensions, getPageContext) {
|
|
186
194
|
try {
|
|
187
195
|
const { filtered, activePageId } = await resolveProjectPages(
|
|
188
196
|
mcp,
|
|
189
|
-
|
|
197
|
+
operationsOrigins,
|
|
198
|
+
includeExtensions,
|
|
190
199
|
getPageContext
|
|
191
200
|
);
|
|
192
201
|
if (filtered.length === 0) {
|
|
193
|
-
sendMcpResult(
|
|
202
|
+
sendMcpResult(
|
|
203
|
+
res,
|
|
204
|
+
id,
|
|
205
|
+
"\u6682\u65E0\u53EF\u7528\u9875\u9762\uFF08\u9879\u76EE\u9875\u6216 allowOrigins \u767D\u540D\u5355\u9875\uFF09\uFF0C\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u76F8\u5E94\u9875\u9762",
|
|
206
|
+
mcp.sessionId
|
|
207
|
+
);
|
|
194
208
|
return;
|
|
195
209
|
}
|
|
196
210
|
const pageList = filtered.map((p) => ({
|
|
@@ -206,15 +220,21 @@ async function handleListPages(res, id, mcp, projectOrigins, getPageContext) {
|
|
|
206
220
|
sendMcpError(res, id, -32603, `MCP \u8C03\u7528\u5931\u8D25: ${e.message}`, mcp.sessionId);
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
|
-
async function handleGetPageContext(res, id, mcp,
|
|
223
|
+
async function handleGetPageContext(res, id, mcp, operationsOrigins, includeExtensions, getPageContext) {
|
|
210
224
|
try {
|
|
211
225
|
const { filtered, activePageId, activePageError } = await resolveProjectPages(
|
|
212
226
|
mcp,
|
|
213
|
-
|
|
227
|
+
operationsOrigins,
|
|
228
|
+
includeExtensions,
|
|
214
229
|
getPageContext
|
|
215
230
|
);
|
|
216
231
|
if (filtered.length === 0) {
|
|
217
|
-
sendMcpResult(
|
|
232
|
+
sendMcpResult(
|
|
233
|
+
res,
|
|
234
|
+
id,
|
|
235
|
+
"\u6682\u65E0\u53EF\u7528\u9875\u9762\uFF08\u9879\u76EE\u9875\u6216 allowOrigins \u767D\u540D\u5355\u9875\uFF09\uFF0C\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u76F8\u5E94\u9875\u9762",
|
|
236
|
+
mcp.sessionId
|
|
237
|
+
);
|
|
218
238
|
return;
|
|
219
239
|
}
|
|
220
240
|
const pc = getPageContext();
|
|
@@ -251,48 +271,54 @@ async function handleGetPageContext(res, id, mcp, projectOrigins, getPageContext
|
|
|
251
271
|
sendMcpError(res, id, -32603, `MCP \u8C03\u7528\u5931\u8D25: ${e.message}`, mcp.sessionId);
|
|
252
272
|
}
|
|
253
273
|
}
|
|
254
|
-
async function handleNewPage(res, id, mcp, args, projectOrigins,
|
|
274
|
+
async function handleNewPage(res, id, mcp, args, projectOrigins, operationsOrigins) {
|
|
255
275
|
try {
|
|
256
276
|
const url = args["url"];
|
|
257
277
|
if (typeof url !== "string" || url.trim().length === 0) {
|
|
258
278
|
sendMcpError(res, id, -32e3, "\u7F3A\u5C11 url \u53C2\u6570\uFF0C\u8BF7\u63D0\u4F9B\u8981\u6253\u5F00\u7684\u9875\u9762 URL", mcp.sessionId);
|
|
259
279
|
return;
|
|
260
280
|
}
|
|
261
|
-
if (!isProjectPage(url,
|
|
281
|
+
if (!isProjectPage(url, operationsOrigins)) {
|
|
262
282
|
sendMcpError(
|
|
263
283
|
res,
|
|
264
284
|
id,
|
|
265
285
|
-32e3,
|
|
266
|
-
`\u4E0D\u5141\u8BB8\u6253\u5F00\
|
|
286
|
+
`\u4E0D\u5141\u8BB8\u6253\u5F00\u8BE5\u9875\u9762: ${url}\u3002\u4EC5\u5141\u8BB8\u9879\u76EE\u9875\u6216 allowOrigins \u767D\u540D\u5355\u9875 (${operationsOrigins.join(", ")})`,
|
|
267
287
|
mcp.sessionId
|
|
268
288
|
);
|
|
269
289
|
return;
|
|
270
290
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
291
|
+
if (isProjectPage(url, projectOrigins)) {
|
|
292
|
+
const listResult = await mcp.callChromeDevTool("list_pages", {});
|
|
293
|
+
if (listResult?.error || !listResult?.result) {
|
|
294
|
+
sendMcpError(
|
|
295
|
+
res,
|
|
296
|
+
id,
|
|
297
|
+
-32e3,
|
|
298
|
+
`\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D\u9879\u76EE\u9875\u9762\u72B6\u6001\uFF0C\u4E3A\u907F\u514D\u91CD\u590D\u6253\u5F00\uFF0C\u8BF7\u786E\u8BA4 Chrome DevTools \u5DF2\u8FDE\u63A5\u540E\u91CD\u8BD5`,
|
|
299
|
+
mcp.sessionId
|
|
300
|
+
);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const text = listResult?.result?.content?.[0]?.text;
|
|
304
|
+
const projectOpen = (text ? parseListPages(text) : []).filter(
|
|
305
|
+
(p) => isProjectPage(p.url, projectOrigins)
|
|
279
306
|
);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
id,
|
|
287
|
-
`\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u6253\u5F00\u7684\u9875\u9762\uFF0C\u65E0\u9700\u91CD\u590D\u6253\u5F00\u3002
|
|
307
|
+
if (projectOpen.length > 0) {
|
|
308
|
+
const existing = projectOpen.map((p) => `- ${p.title} (${p.url}) [pageId: ${p.pageId}]`).join("\n");
|
|
309
|
+
sendMcpResult(
|
|
310
|
+
res,
|
|
311
|
+
id,
|
|
312
|
+
`\u5F53\u524D\u9879\u76EE\u5DF2\u6709\u6253\u5F00\u7684\u9875\u9762\uFF0C\u65E0\u9700\u91CD\u590D\u6253\u5F00\u3002
|
|
288
313
|
|
|
289
314
|
\u5DF2\u6253\u5F00\u7684\u9875\u9762\uFF1A
|
|
290
315
|
${existing}
|
|
291
316
|
|
|
292
317
|
\u5982\u9700\u64CD\u4F5C\u73B0\u6709\u9875\u9762\uFF0C\u8BF7\u4F7F\u7528 chrome-devtools_list_pages \u83B7\u53D6\u9875\u9762 ID\uFF0C\u518D\u914D\u5408\u5176\u4ED6 chrome-devtools_* \u5DE5\u5177\u4F7F\u7528\u3002`,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
318
|
+
mcp.sessionId
|
|
319
|
+
);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
296
322
|
}
|
|
297
323
|
const forwardBody = JSON.stringify({
|
|
298
324
|
jsonrpc: "2.0",
|
|
@@ -308,37 +334,40 @@ ${existing}
|
|
|
308
334
|
sendMcpError(res, id, -32603, `MCP \u8C03\u7528\u5931\u8D25: ${e.message}`, mcp.sessionId);
|
|
309
335
|
}
|
|
310
336
|
}
|
|
311
|
-
async function handleDevTool(res, id, mcp, mapped, args,
|
|
337
|
+
async function handleDevTool(res, id, mcp, mapped, args, operationsOrigins, includeExtensions, projectRoot, toolName) {
|
|
312
338
|
try {
|
|
313
339
|
const pageId = args["pageId"];
|
|
314
340
|
if (typeof pageId !== "number") {
|
|
315
341
|
sendMcpError(res, id, -32e3, "\u7F3A\u5C11 pageId \u53C2\u6570\uFF0C\u8BF7\u5148\u83B7\u53D6\u9875\u9762 ID", mcp.sessionId);
|
|
316
342
|
return;
|
|
317
343
|
}
|
|
318
|
-
const validation = await validatePageId(mcp, pageId,
|
|
344
|
+
const validation = await validatePageId(mcp, pageId, operationsOrigins, includeExtensions);
|
|
319
345
|
log.debug("handleDevTool validation", {
|
|
320
346
|
pageId,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
origins:
|
|
347
|
+
allowedPages: validation.allowedPages.length,
|
|
348
|
+
allowedPageIds: validation.allowedPages.map((p) => p.pageId),
|
|
349
|
+
origins: operationsOrigins,
|
|
324
350
|
isValid: validation.valid
|
|
325
351
|
});
|
|
326
352
|
if (!validation.valid) {
|
|
327
353
|
sendMcpError(res, id, -32e3, validation.error, mcp.sessionId);
|
|
328
354
|
return;
|
|
329
355
|
}
|
|
330
|
-
if (toolName === "chrome-devtools_navigate_page"
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
356
|
+
if (toolName === "chrome-devtools_navigate_page") {
|
|
357
|
+
const navType = typeof args["type"] === "string" ? args["type"] : "url";
|
|
358
|
+
if (navType === "url") {
|
|
359
|
+
const targetUrl = args["url"];
|
|
360
|
+
if (typeof targetUrl === "string" && targetUrl.length > 0) {
|
|
361
|
+
if (!isProjectPage(targetUrl, operationsOrigins)) {
|
|
362
|
+
sendMcpError(
|
|
363
|
+
res,
|
|
364
|
+
id,
|
|
365
|
+
-32e3,
|
|
366
|
+
`\u4E0D\u5141\u8BB8\u8DF3\u8F6C\u5230\u8BE5\u9875\u9762: ${targetUrl}\u3002\u4EC5\u5141\u8BB8\u5BFC\u822A\u5230\u9879\u76EE\u9875\u6216 allowOrigins \u767D\u540D\u5355\u9875 (${operationsOrigins.join(", ")})`,
|
|
367
|
+
mcp.sessionId
|
|
368
|
+
);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
342
371
|
}
|
|
343
372
|
}
|
|
344
373
|
}
|
package/es/endpoints/sse.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SSE_EVENTS_PATH } from "@aipanel/core";
|
|
1
|
+
import { SSE_EVENT_TYPES, SSE_EVENTS_PATH } from "@aipanel/core";
|
|
2
2
|
import { RequestContext, createLogger } from "@aipanel/core/node";
|
|
3
3
|
const log = createLogger("Endpoints:SSE");
|
|
4
4
|
function setupSseEndpoint(server, ctx) {
|
|
@@ -12,10 +12,10 @@ function setupSseEndpoint(server, ctx) {
|
|
|
12
12
|
});
|
|
13
13
|
ctx.sseClients.add(res);
|
|
14
14
|
log.debug("SSE client connected", { totalClients: ctx.sseClients.size });
|
|
15
|
-
res.write(`data: ${JSON.stringify({ type:
|
|
15
|
+
res.write(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.CONNECTED })}
|
|
16
16
|
|
|
17
17
|
`);
|
|
18
|
-
const statusPayload = { type:
|
|
18
|
+
const statusPayload = { type: SSE_EVENT_TYPES.STATUS_SYNC };
|
|
19
19
|
if (ctx.isServiceStarted !== void 0) {
|
|
20
20
|
statusPayload.isStarted = ctx.isServiceStarted;
|
|
21
21
|
}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { ViteDevServer } from "vite";
|
|
6
6
|
import type { McpProxy } from "../core/mcp-proxy";
|
|
7
|
-
|
|
7
|
+
import { VUE_DEVTOOLS_API_PATH } from "@aipanel/core";
|
|
8
|
+
export { VUE_DEVTOOLS_API_PATH };
|
|
8
9
|
export declare function setupVueDevtoolsEndpoint(server: ViteDevServer, mcp: McpProxy): void;
|
|
9
|
-
export declare function executeAction(action: string, args: Record<string, unknown> | undefined, mcp: McpProxy,
|
|
10
|
+
export declare function executeAction(action: string, args: Record<string, unknown> | undefined, mcp: McpProxy,
|
|
11
|
+
/** vue-devtools 桥只注入在项目页面,范围为自动项目页 origins */
|
|
12
|
+
projectOrigins: string[]): Promise<unknown>;
|