vite-plugin-aipanel 1.2.0-beta.0
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 +72 -0
- package/es/client/vue-devtools-bridge.d.ts +58 -0
- package/es/client/vue-devtools-bridge.mjs +150 -0
- package/es/core/injector.d.ts +2 -0
- package/es/core/injector.mjs +15 -0
- package/es/core/mcp-chrome.d.ts +56 -0
- package/es/core/mcp-chrome.mjs +133 -0
- package/es/core/mcp-proxy.d.ts +23 -0
- package/es/core/mcp-proxy.mjs +212 -0
- package/es/core/mcp-tools.d.ts +15 -0
- package/es/core/mcp-tools.mjs +671 -0
- package/es/core/provider-loader.d.ts +19 -0
- package/es/core/provider-loader.mjs +30 -0
- package/es/core/proxy-server.d.ts +12 -0
- package/es/core/proxy-server.mjs +148 -0
- package/es/core/service.d.ts +39 -0
- package/es/core/service.mjs +267 -0
- package/es/endpoints/context.d.ts +3 -0
- package/es/endpoints/context.mjs +106 -0
- package/es/endpoints/index.d.ts +9 -0
- package/es/endpoints/index.mjs +30 -0
- package/es/endpoints/logs.d.ts +9 -0
- package/es/endpoints/logs.mjs +86 -0
- package/es/endpoints/mcp.d.ts +6 -0
- package/es/endpoints/mcp.mjs +610 -0
- package/es/endpoints/sessions.d.ts +3 -0
- package/es/endpoints/sessions.mjs +62 -0
- package/es/endpoints/sse.d.ts +3 -0
- package/es/endpoints/sse.mjs +44 -0
- package/es/endpoints/start.d.ts +3 -0
- package/es/endpoints/start.mjs +21 -0
- package/es/endpoints/types.d.ts +34 -0
- package/es/endpoints/types.mjs +0 -0
- package/es/endpoints/vue-devtools.d.ts +9 -0
- package/es/endpoints/vue-devtools.mjs +107 -0
- package/es/endpoints/warmup.d.ts +3 -0
- package/es/endpoints/warmup.mjs +42 -0
- package/es/endpoints/widget.d.ts +3 -0
- package/es/endpoints/widget.mjs +36 -0
- package/es/env.d.ts +1 -0
- package/es/index.d.ts +22 -0
- package/es/index.mjs +342 -0
- package/es/utils/format-bridge.d.ts +9 -0
- package/es/utils/format-bridge.mjs +80 -0
- package/es/utils/paths.d.ts +3 -0
- package/es/utils/paths.mjs +45 -0
- package/es/utils/system.d.ts +3 -0
- package/es/utils/system.mjs +76 -0
- package/lib/client/vue-devtools-bridge.cjs +150 -0
- package/lib/client/vue-devtools-bridge.d.ts +58 -0
- package/lib/client.css +2 -0
- package/lib/client.js +6950 -0
- package/lib/core/injector.cjs +34 -0
- package/lib/core/injector.d.ts +2 -0
- package/lib/core/mcp-chrome.cjs +161 -0
- package/lib/core/mcp-chrome.d.ts +56 -0
- package/lib/core/mcp-proxy.cjs +244 -0
- package/lib/core/mcp-proxy.d.ts +23 -0
- package/lib/core/mcp-tools.cjs +694 -0
- package/lib/core/mcp-tools.d.ts +15 -0
- package/lib/core/provider-loader.cjs +53 -0
- package/lib/core/provider-loader.d.ts +19 -0
- package/lib/core/proxy-server.cjs +181 -0
- package/lib/core/proxy-server.d.ts +12 -0
- package/lib/core/service.cjs +289 -0
- package/lib/core/service.d.ts +39 -0
- package/lib/endpoints/context.cjs +129 -0
- package/lib/endpoints/context.d.ts +3 -0
- package/lib/endpoints/index.cjs +58 -0
- package/lib/endpoints/index.d.ts +9 -0
- package/lib/endpoints/logs.cjs +107 -0
- package/lib/endpoints/logs.d.ts +9 -0
- package/lib/endpoints/mcp.cjs +624 -0
- package/lib/endpoints/mcp.d.ts +6 -0
- package/lib/endpoints/sessions.cjs +85 -0
- package/lib/endpoints/sessions.d.ts +3 -0
- package/lib/endpoints/sse.cjs +67 -0
- package/lib/endpoints/sse.d.ts +3 -0
- package/lib/endpoints/start.cjs +44 -0
- package/lib/endpoints/start.d.ts +3 -0
- package/lib/endpoints/types.cjs +15 -0
- package/lib/endpoints/types.d.ts +34 -0
- package/lib/endpoints/vue-devtools.cjs +132 -0
- package/lib/endpoints/vue-devtools.d.ts +9 -0
- package/lib/endpoints/warmup.cjs +65 -0
- package/lib/endpoints/warmup.d.ts +3 -0
- package/lib/endpoints/widget.cjs +69 -0
- package/lib/endpoints/widget.d.ts +3 -0
- package/lib/env.d.ts +1 -0
- package/lib/index.cjs +361 -0
- package/lib/index.d.ts +22 -0
- package/lib/utils/format-bridge.cjs +102 -0
- package/lib/utils/format-bridge.d.ts +9 -0
- package/lib/utils/paths.cjs +80 -0
- package/lib/utils/paths.d.ts +3 -0
- package/lib/utils/system.cjs +110 -0
- package/lib/utils/system.d.ts +3 -0
- package/package.json +68 -0
|
@@ -0,0 +1,85 @@
|
|
|
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 sessions_exports = {};
|
|
19
|
+
__export(sessions_exports, {
|
|
20
|
+
setupSessionsEndpoint: () => setupSessionsEndpoint
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(sessions_exports);
|
|
23
|
+
var import_core = require("@aipanel/core");
|
|
24
|
+
var import_node = require("@aipanel/core/node");
|
|
25
|
+
const log = (0, import_node.createLogger)("Endpoints:Sessions");
|
|
26
|
+
function setupSessionsEndpoint(server, ctx) {
|
|
27
|
+
server.middlewares.use(import_core.SESSIONS_API_PATH, async (req, res) => {
|
|
28
|
+
const reqCtx = new import_node.RequestContext(req.method || "GET", import_core.SESSIONS_API_PATH);
|
|
29
|
+
res.setHeader("Content-Type", "application/json");
|
|
30
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
31
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
32
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
33
|
+
if (req.method === "OPTIONS") {
|
|
34
|
+
res.writeHead(200);
|
|
35
|
+
res.end();
|
|
36
|
+
reqCtx.end(200);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
if (req.method === "GET") {
|
|
41
|
+
reqCtx.checkpoint("Fetching sessions");
|
|
42
|
+
const [sessions, capabilities] = await Promise.all([
|
|
43
|
+
ctx.getSessions(),
|
|
44
|
+
ctx.getCapabilities()
|
|
45
|
+
]);
|
|
46
|
+
res.writeHead(200);
|
|
47
|
+
res.end(JSON.stringify({ sessions, capabilities }));
|
|
48
|
+
reqCtx.end(200);
|
|
49
|
+
} else if (req.method === "POST") {
|
|
50
|
+
reqCtx.checkpoint("Creating session");
|
|
51
|
+
const newSession = await ctx.createSession();
|
|
52
|
+
res.writeHead(200);
|
|
53
|
+
res.end(JSON.stringify(newSession));
|
|
54
|
+
reqCtx.end(200);
|
|
55
|
+
} else if (req.method === "DELETE") {
|
|
56
|
+
const url = new URL(req.url || "", `http://${req.headers.host}`);
|
|
57
|
+
const sessionId = url.searchParams.get("id");
|
|
58
|
+
if (!sessionId) {
|
|
59
|
+
res.writeHead(400);
|
|
60
|
+
res.end(JSON.stringify({ error: "Session ID is required" }));
|
|
61
|
+
reqCtx.end(400);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
reqCtx.checkpoint(`Deleting session: ${sessionId}`);
|
|
65
|
+
await ctx.deleteSession(sessionId);
|
|
66
|
+
res.writeHead(200);
|
|
67
|
+
res.end(JSON.stringify({ success: true }));
|
|
68
|
+
reqCtx.end(200);
|
|
69
|
+
} else {
|
|
70
|
+
res.writeHead(405);
|
|
71
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
72
|
+
reqCtx.end(405);
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
log.error("Session API error", { error: e, method: req.method });
|
|
76
|
+
res.writeHead(500);
|
|
77
|
+
res.end(JSON.stringify({ error: String(e) }));
|
|
78
|
+
reqCtx.error(e);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
setupSessionsEndpoint
|
|
85
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
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 sse_exports = {};
|
|
19
|
+
__export(sse_exports, {
|
|
20
|
+
setupSseEndpoint: () => setupSseEndpoint
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(sse_exports);
|
|
23
|
+
var import_core = require("@aipanel/core");
|
|
24
|
+
var import_node = require("@aipanel/core/node");
|
|
25
|
+
const log = (0, import_node.createLogger)("Endpoints:SSE");
|
|
26
|
+
function setupSseEndpoint(server, ctx) {
|
|
27
|
+
server.middlewares.use(import_core.SSE_EVENTS_PATH, async (req, res) => {
|
|
28
|
+
const reqCtx = new import_node.RequestContext("GET", import_core.SSE_EVENTS_PATH);
|
|
29
|
+
res.writeHead(200, {
|
|
30
|
+
"Content-Type": "text/event-stream",
|
|
31
|
+
"Cache-Control": "no-cache",
|
|
32
|
+
Connection: "keep-alive",
|
|
33
|
+
"Access-Control-Allow-Origin": "*"
|
|
34
|
+
});
|
|
35
|
+
ctx.sseClients.add(res);
|
|
36
|
+
log.debug("SSE client connected", { totalClients: ctx.sseClients.size });
|
|
37
|
+
res.write(`data: ${JSON.stringify({ type: "CONNECTED" })}
|
|
38
|
+
|
|
39
|
+
`);
|
|
40
|
+
const statusPayload = { type: "STATUS_SYNC" };
|
|
41
|
+
if (ctx.isServiceStarted !== void 0) {
|
|
42
|
+
statusPayload.isStarted = ctx.isServiceStarted;
|
|
43
|
+
}
|
|
44
|
+
if (ctx.currentTask) {
|
|
45
|
+
statusPayload.task = ctx.currentTask.task;
|
|
46
|
+
Object.keys(ctx.currentTask).forEach((key) => {
|
|
47
|
+
if (key !== "task") {
|
|
48
|
+
statusPayload[key] = ctx.currentTask[key];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
res.write(`data: ${JSON.stringify(statusPayload)}
|
|
53
|
+
|
|
54
|
+
`);
|
|
55
|
+
req.on("close", () => {
|
|
56
|
+
ctx.sseClients.delete(res);
|
|
57
|
+
log.debug("SSE client disconnected", {
|
|
58
|
+
totalClients: ctx.sseClients.size
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
reqCtx.end(200);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
65
|
+
0 && (module.exports = {
|
|
66
|
+
setupSseEndpoint
|
|
67
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
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 start_exports = {};
|
|
19
|
+
__export(start_exports, {
|
|
20
|
+
setupStartEndpoint: () => setupStartEndpoint
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(start_exports);
|
|
23
|
+
var import_core = require("@aipanel/core");
|
|
24
|
+
var import_node = require("@aipanel/core/node");
|
|
25
|
+
function setupStartEndpoint(server, ctx) {
|
|
26
|
+
server.middlewares.use(import_core.START_API_PATH, async (_req, res) => {
|
|
27
|
+
const reqCtx = new import_node.RequestContext("GET", import_core.START_API_PATH);
|
|
28
|
+
res.setHeader("Content-Type", "application/json");
|
|
29
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
30
|
+
res.writeHead(200);
|
|
31
|
+
res.end(JSON.stringify({
|
|
32
|
+
success: true,
|
|
33
|
+
proxyPort: ctx.actualProxyPort,
|
|
34
|
+
webPort: ctx.actualWebPort,
|
|
35
|
+
projectRoot: server.config.root,
|
|
36
|
+
serviceInstanceId: ctx.serviceInstanceId
|
|
37
|
+
}));
|
|
38
|
+
reqCtx.end(200);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
42
|
+
0 && (module.exports = {
|
|
43
|
+
setupStartEndpoint
|
|
44
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
14
|
+
var types_exports = {};
|
|
15
|
+
module.exports = __toCommonJS(types_exports);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ChatSession, PageContext, ProviderCapabilities, ServiceStartupTask } from "@aipanel/core";
|
|
2
|
+
import type http from "http";
|
|
3
|
+
export interface EndpointContext {
|
|
4
|
+
get webUrl(): string | null;
|
|
5
|
+
get sseClients(): Set<http.ServerResponse>;
|
|
6
|
+
/** 获取当前活跃 Tab 的上下文(扩展模式)或默认上下文(非扩展模式) */
|
|
7
|
+
getPageContext(): PageContext;
|
|
8
|
+
/** 写入某个 Tab 的上下文 */
|
|
9
|
+
setPageContext(tabId: string, ctx: PageContext): void;
|
|
10
|
+
/** 设置当前活跃 Tab ID */
|
|
11
|
+
setActiveTabId(tabId: string): void;
|
|
12
|
+
/** 清除选中元素(活跃 Tab) */
|
|
13
|
+
clearSelectedElements(): void;
|
|
14
|
+
get isServiceStarted(): boolean;
|
|
15
|
+
get currentTask(): {
|
|
16
|
+
task: ServiceStartupTask;
|
|
17
|
+
data?: Record<string, unknown>;
|
|
18
|
+
} | null;
|
|
19
|
+
get actualProxyPort(): number;
|
|
20
|
+
get actualWebPort(): number;
|
|
21
|
+
get serviceInstanceId(): string;
|
|
22
|
+
getSessions: () => Promise<ChatSession[]>;
|
|
23
|
+
createSession: () => Promise<ChatSession>;
|
|
24
|
+
deleteSession: (id: string) => Promise<void>;
|
|
25
|
+
/** 获取当前 Provider 能力描述(客户端自适应行为依据) */
|
|
26
|
+
getCapabilities: () => ProviderCapabilities;
|
|
27
|
+
resolveWidgetPath: () => string;
|
|
28
|
+
resolveWidgetStylePath: () => string;
|
|
29
|
+
retryWarmupChromeMcp: () => Promise<{
|
|
30
|
+
success: boolean;
|
|
31
|
+
errorType?: string;
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
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 vue_devtools_exports = {};
|
|
19
|
+
__export(vue_devtools_exports, {
|
|
20
|
+
VUE_DEVTOOLS_API_PATH: () => VUE_DEVTOOLS_API_PATH,
|
|
21
|
+
executeAction: () => executeAction,
|
|
22
|
+
setupVueDevtoolsEndpoint: () => setupVueDevtoolsEndpoint
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(vue_devtools_exports);
|
|
25
|
+
var import_node = require("@aipanel/core/node");
|
|
26
|
+
var import_core = require("@aipanel/core");
|
|
27
|
+
var import_mcp_chrome = require("../core/mcp-chrome.cjs");
|
|
28
|
+
const log = (0, import_node.createLogger)("Endpoints:VueDevtools");
|
|
29
|
+
const VUE_DEVTOOLS_API_PATH = "/__aipanel_vue_devtools__";
|
|
30
|
+
function setupVueDevtoolsEndpoint(server, mcp) {
|
|
31
|
+
server.middlewares.use(VUE_DEVTOOLS_API_PATH, async (req, res) => {
|
|
32
|
+
res.setHeader("Content-Type", "application/json");
|
|
33
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
34
|
+
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
35
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
36
|
+
if (req.method === "OPTIONS") {
|
|
37
|
+
res.writeHead(200);
|
|
38
|
+
res.end();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (req.method !== "POST") {
|
|
42
|
+
res.writeHead(405);
|
|
43
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const body = await readBody(req);
|
|
48
|
+
const { action, args } = JSON.parse(body);
|
|
49
|
+
const result = await executeAction(action, args, mcp, (0, import_mcp_chrome.getProjectOrigins)(server));
|
|
50
|
+
res.writeHead(200);
|
|
51
|
+
res.end(JSON.stringify({ success: true, data: result }));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
log.error("Vue DevTools API error", { error: e.message });
|
|
54
|
+
res.writeHead(500);
|
|
55
|
+
res.end(JSON.stringify({ success: false, error: e.message }));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async function executeAction(action, args, mcp, projectOrigins) {
|
|
60
|
+
const pageId = args?.pageId;
|
|
61
|
+
if (typeof pageId !== "number") {
|
|
62
|
+
throw new Error("\u7F3A\u5C11 pageId \u53C2\u6570\uFF0C\u8BF7\u5148\u83B7\u53D6\u9875\u9762 ID");
|
|
63
|
+
}
|
|
64
|
+
const validation = await (0, import_mcp_chrome.validatePageId)(mcp, pageId, projectOrigins);
|
|
65
|
+
if (!validation.valid) {
|
|
66
|
+
log.error("pageId \u65E0\u6548\u6216\u975E\u9879\u76EE\u9875\u9762", {
|
|
67
|
+
pageId,
|
|
68
|
+
projectPageIds: validation.projectPages.map((p) => p.pageId)
|
|
69
|
+
});
|
|
70
|
+
throw new Error(validation.error);
|
|
71
|
+
}
|
|
72
|
+
await mcp.callChromeDevTool("select_page", { pageId, bringToFront: false });
|
|
73
|
+
const callExpr = buildCallExpr(action, args);
|
|
74
|
+
const result = await mcp.callChromeDevTool("evaluate_script", {
|
|
75
|
+
function: callExpr
|
|
76
|
+
});
|
|
77
|
+
const parsed = parseEvalResult(result);
|
|
78
|
+
return parsed;
|
|
79
|
+
}
|
|
80
|
+
function buildCallExpr(action, args) {
|
|
81
|
+
switch (action) {
|
|
82
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_TREE:
|
|
83
|
+
return `async () => { return await window.__aipanel_vue.api.getInspectorTree({ inspectorId: "components", filter: ${JSON.stringify(args?.filter ?? "")} }) }`;
|
|
84
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_STATE:
|
|
85
|
+
return `async () => { return await window.__aipanel_vue.api.getInspectorState({ inspectorId: "components", nodeId: ${JSON.stringify(args?.nodeId)} }) }`;
|
|
86
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_RENDER_CODE:
|
|
87
|
+
return `async () => { return await window.__aipanel_vue.api.getComponentRenderCode(${JSON.stringify(args?.nodeId)}) }`;
|
|
88
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.GET_APPS:
|
|
89
|
+
return `async () => { return window.__aipanel_vue.ctx.state.appRecords.map(r => ({ id: r.id, name: r.name })) }`;
|
|
90
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.TOGGLE_APP:
|
|
91
|
+
return `async () => { await window.__aipanel_vue.api.toggleApp(${JSON.stringify(args?.appId)}); return "ok" }`;
|
|
92
|
+
case import_core.VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO:
|
|
93
|
+
return `async () => { const r = window.__aipanel_vue.router.value; return window.__aipanel_vue.safeStringify({ currentRoute: r?.currentRoute?.value ?? null, routes: r?.getRoutes?.() ?? [] }) }`;
|
|
94
|
+
default:
|
|
95
|
+
throw new Error(`Unknown action: ${action}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function parseEvalResult(result) {
|
|
99
|
+
const r = result;
|
|
100
|
+
const text = r?.result?.content?.[0]?.text;
|
|
101
|
+
if (!text) return null;
|
|
102
|
+
let jsonText = text;
|
|
103
|
+
const mdMatch = text.match(/```(?:json)?\s*\n([\s\S]*?)\n\s*```/);
|
|
104
|
+
if (mdMatch) {
|
|
105
|
+
jsonText = mdMatch[1];
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
return JSON.parse(jsonText);
|
|
109
|
+
} catch {
|
|
110
|
+
return text;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function readBody(req) {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
let body = "";
|
|
116
|
+
req.on("data", (chunk) => {
|
|
117
|
+
body += chunk.toString();
|
|
118
|
+
if (body.length > 1024 * 1024) {
|
|
119
|
+
req.destroy();
|
|
120
|
+
reject(new Error("Request body too large"));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
req.on("end", () => resolve(body));
|
|
124
|
+
req.on("error", reject);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
128
|
+
0 && (module.exports = {
|
|
129
|
+
VUE_DEVTOOLS_API_PATH,
|
|
130
|
+
executeAction,
|
|
131
|
+
setupVueDevtoolsEndpoint
|
|
132
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vue DevTools API 端点
|
|
3
|
+
* 接收 aipanel 插件的请求,通过 MCP 代理在浏览器中执行 window.__aipanel_vue
|
|
4
|
+
*/
|
|
5
|
+
import type { ViteDevServer } from "vite";
|
|
6
|
+
import type { McpProxy } from "../core/mcp-proxy";
|
|
7
|
+
export declare const VUE_DEVTOOLS_API_PATH = "/__aipanel_vue_devtools__";
|
|
8
|
+
export declare function setupVueDevtoolsEndpoint(server: ViteDevServer, mcp: McpProxy): void;
|
|
9
|
+
export declare function executeAction(action: string, args: Record<string, unknown> | undefined, mcp: McpProxy, projectOrigins: string[]): Promise<unknown>;
|
|
@@ -0,0 +1,65 @@
|
|
|
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 warmup_exports = {};
|
|
19
|
+
__export(warmup_exports, {
|
|
20
|
+
setupWarmupEndpoint: () => setupWarmupEndpoint
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(warmup_exports);
|
|
23
|
+
var import_node = require("@aipanel/core/node");
|
|
24
|
+
var import_core = require("@aipanel/core");
|
|
25
|
+
const log = (0, import_node.createLogger)("Endpoints:Warmup");
|
|
26
|
+
function setupWarmupEndpoint(server, ctx) {
|
|
27
|
+
server.middlewares.use(import_core.WARMUP_API_PATH, async (req, res) => {
|
|
28
|
+
if (req.method !== "POST") {
|
|
29
|
+
res.writeHead(405);
|
|
30
|
+
res.end("Method not allowed");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const result = await ctx.retryWarmupChromeMcp();
|
|
35
|
+
res.setHeader("Content-Type", "application/json");
|
|
36
|
+
res.writeHead(200);
|
|
37
|
+
if (result.success) {
|
|
38
|
+
res.end(JSON.stringify({ success: true }));
|
|
39
|
+
} else {
|
|
40
|
+
res.end(
|
|
41
|
+
JSON.stringify({
|
|
42
|
+
success: false,
|
|
43
|
+
errorType: result.errorType,
|
|
44
|
+
error: result.errorMessage
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
} catch (e) {
|
|
49
|
+
log.error("Failed to retry warmup", { error: e });
|
|
50
|
+
res.setHeader("Content-Type", "application/json");
|
|
51
|
+
res.writeHead(500);
|
|
52
|
+
res.end(
|
|
53
|
+
JSON.stringify({
|
|
54
|
+
success: false,
|
|
55
|
+
errorType: "UNKNOWN",
|
|
56
|
+
error: String(e)
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
63
|
+
0 && (module.exports = {
|
|
64
|
+
setupWarmupEndpoint
|
|
65
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var widget_exports = {};
|
|
29
|
+
__export(widget_exports, {
|
|
30
|
+
setupWidgetEndpoints: () => setupWidgetEndpoints
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(widget_exports);
|
|
33
|
+
var import_fs = __toESM(require("fs"));
|
|
34
|
+
var import_core = require("@aipanel/core");
|
|
35
|
+
var import_node = require("@aipanel/core/node");
|
|
36
|
+
function setupWidgetEndpoints(server, ctx) {
|
|
37
|
+
server.middlewares.use(import_core.WIDGET_SCRIPT_PATH, async (_req, res) => {
|
|
38
|
+
const reqCtx = new import_node.RequestContext("GET", import_core.WIDGET_SCRIPT_PATH);
|
|
39
|
+
const widgetPath = ctx.resolveWidgetPath();
|
|
40
|
+
if (import_fs.default.existsSync(widgetPath)) {
|
|
41
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
42
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
43
|
+
import_fs.default.createReadStream(widgetPath).pipe(res);
|
|
44
|
+
reqCtx.end(200);
|
|
45
|
+
} else {
|
|
46
|
+
res.writeHead(404);
|
|
47
|
+
res.end("Widget script not found");
|
|
48
|
+
reqCtx.end(404);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
server.middlewares.use(import_core.WIDGET_STYLE_PATH, async (_req, res) => {
|
|
52
|
+
const reqCtx = new import_node.RequestContext("GET", import_core.WIDGET_STYLE_PATH);
|
|
53
|
+
const stylePath = ctx.resolveWidgetStylePath();
|
|
54
|
+
if (import_fs.default.existsSync(stylePath)) {
|
|
55
|
+
res.setHeader("Content-Type", "text/css");
|
|
56
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
57
|
+
import_fs.default.createReadStream(stylePath).pipe(res);
|
|
58
|
+
reqCtx.end(200);
|
|
59
|
+
} else {
|
|
60
|
+
res.writeHead(404);
|
|
61
|
+
res.end("Widget style not found");
|
|
62
|
+
reqCtx.end(404);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 && (module.exports = {
|
|
68
|
+
setupWidgetEndpoints
|
|
69
|
+
});
|
package/lib/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="chrome" />
|