vite-plugin-aipanel 1.2.22 → 1.2.24

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.
@@ -18,27 +18,41 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
18
18
  var mcp_tools_exports = {};
19
19
  __export(mcp_tools_exports, {
20
20
  CUSTOM_TOOLS: () => CUSTOM_TOOLS,
21
+ LOGS_DEVTOOLS_PREFIX: () => LOGS_DEVTOOLS_PREFIX,
21
22
  MCP_PREFIX: () => MCP_PREFIX,
22
23
  OFFICIAL_GLOBAL_POLICY: () => OFFICIAL_GLOBAL_POLICY,
23
24
  OFFICIAL_NO_PAGE_TOOLS: () => OFFICIAL_NO_PAGE_TOOLS,
24
25
  PAGE_ID_PROP: () => PAGE_ID_PROP,
25
26
  PROJECT_DESCRIPTION_NOTES: () => PROJECT_DESCRIPTION_NOTES,
27
+ VITE_LOGS_TOOL_NAME: () => VITE_LOGS_TOOL_NAME,
28
+ VUE_DEVTOOLS_PREFIX: () => VUE_DEVTOOLS_PREFIX,
29
+ VUE_DEVTOOLS_TOOLS: () => VUE_DEVTOOLS_TOOLS,
26
30
  configureToolScope: () => configureToolScope,
27
31
  currentOfficialShorts: () => currentOfficialShorts,
28
32
  displayToolName: () => displayToolName,
29
33
  extraToolFlag: () => extraToolFlag,
34
+ findVueDevtoolsTool: () => findVueDevtoolsTool,
30
35
  isAllowedToolName: () => isAllowedToolName,
31
36
  isOfficialExtraTool: () => isOfficialExtraTool,
32
37
  officialDefaultShorts: () => officialDefaultShorts,
33
38
  officialExtraCandidates: () => officialExtraCandidates,
39
+ serviceLogToolName: () => serviceLogToolName,
40
+ vueDevtoolsToolList: () => vueDevtoolsToolList,
34
41
  withPageIdSchema: () => withPageIdSchema
35
42
  });
36
43
  module.exports = __toCommonJS(mcp_tools_exports);
44
+ var import_core = require("@aipanel/core");
37
45
  var import_official_meta = require("./official-meta.cjs");
38
46
  const MCP_PREFIX = "chrome-devtools_";
39
47
  function displayToolName(short) {
40
48
  return MCP_PREFIX + short;
41
49
  }
50
+ const VUE_DEVTOOLS_PREFIX = "vue-devtools_";
51
+ const LOGS_DEVTOOLS_PREFIX = "logs-devtools_";
52
+ const VITE_LOGS_TOOL_NAME = `${LOGS_DEVTOOLS_PREFIX}vite_logs`;
53
+ function serviceLogToolName(name) {
54
+ return `${LOGS_DEVTOOLS_PREFIX}${name}_logs`;
55
+ }
42
56
  const OFFICIAL_GLOBAL_POLICY = [
43
57
  "evaluate_script",
44
58
  "list_console_messages",
@@ -69,8 +83,153 @@ const CUSTOM_TOOLS = [
69
83
  name: displayToolName("current_page"),
70
84
  description: "Get the page the user is currently browsing (URL, title, and page ID). Resolves the project page with injected context; for allowOrigins pages use list_pages and pass its pageId to page tools instead.",
71
85
  inputSchema: { type: "object", properties: {} }
86
+ },
87
+ {
88
+ name: VITE_LOGS_TOOL_NAME,
89
+ description: `\u83B7\u53D6 Vite \u5F00\u53D1\u670D\u52A1\u5668\u7684\u8FD0\u884C\u65E5\u5FD7\u3002
90
+
91
+ **\u4F55\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177**\uFF1A
92
+ - \u7528\u6237\u62A5\u544A"\u9875\u9762\u6CA1\u66F4\u65B0"\u3001"\u70ED\u66F4\u65B0\u4E0D\u5DE5\u4F5C"\u3001"HMR \u5931\u6548"\u65F6
93
+ - \u6784\u5EFA\u62A5\u9519\u6216\u7F16\u8BD1\u5931\u8D25\uFF0C\u9700\u8981\u67E5\u770B\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F
94
+ - \u9875\u9762\u767D\u5C4F\u3001\u6837\u5F0F\u4E22\u5931\u3001\u6A21\u5757\u52A0\u8F7D\u5931\u8D25\u7B49\u5F00\u53D1\u95EE\u9898
95
+ - \u7528\u6237\u63D0\u5230"\u5F00\u53D1\u670D\u52A1\u5668\u6709\u95EE\u9898"\u3001"vite \u62A5\u9519"
96
+ - \u9700\u8981\u786E\u8BA4\u6700\u8FD1\u7684\u6587\u4EF6\u53D8\u66F4\u662F\u5426\u88AB Vite \u6B63\u786E\u5904\u7406
97
+
98
+ **\u65E5\u5FD7\u5185\u5BB9**\uFF1A
99
+ - Vite HMR \u70ED\u66F4\u65B0\u65E5\u5FD7\uFF08\u54EA\u4E9B\u6587\u4EF6\u88AB\u66F4\u65B0\u3001\u66F4\u65B0\u72B6\u6001\uFF09
100
+ - \u6784\u5EFA\u7F16\u8BD1\u65E5\u5FD7\uFF08\u9519\u8BEF\u3001\u8B66\u544A\u3001\u6210\u529F\u4FE1\u606F\uFF09
101
+ - OpenCode Web \u8FDB\u7A0B\u8F93\u51FA
102
+ - \u63D2\u4EF6\u8FD0\u884C\u65E5\u5FD7
103
+
104
+ \u65E5\u5FD7\u4FDD\u5B58\u5728\u5185\u5B58\u7F13\u51B2\u533A\uFF08\u6700\u8FD1 500 \u6761\uFF09\u3002`,
105
+ inputSchema: {
106
+ type: "object",
107
+ properties: {
108
+ level: {
109
+ type: "string",
110
+ description: "\u65E5\u5FD7\u7EA7\u522B\u8FC7\u6EE4\uFF1Aerror(\u9519\u8BEF)\u3001warn(\u8B66\u544A)\u3001info(\u4FE1\u606F)\u3001debug(\u8C03\u8BD5)\u3001log(\u666E\u901A)\u3002\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF0C\u5982 'error,warn'"
111
+ },
112
+ limit: {
113
+ type: "integer",
114
+ minimum: 1,
115
+ maximum: 200,
116
+ default: 50,
117
+ description: "\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4 50\uFF0C\u6700\u5927 200"
118
+ },
119
+ source: {
120
+ type: "string",
121
+ description: "\u6765\u6E90\u8FC7\u6EE4\uFF1Aconsole(\u63A7\u5236\u53F0)\u3001provider-stdout(\u670D\u52A1\u8F93\u51FA)\u3001provider-stderr(\u670D\u52A1\u9519\u8BEF)"
122
+ }
123
+ }
124
+ }
125
+ }
126
+ ];
127
+ const VUE_DEVTOOLS_TOOLS = [
128
+ {
129
+ name: `${VUE_DEVTOOLS_PREFIX}get_apps`,
130
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_APPS,
131
+ description: `\u83B7\u53D6\u6307\u5B9A\u9875\u9762\u6240\u6709 Vue \u5E94\u7528\u5B9E\u4F8B\u5217\u8868\u3002
132
+
133
+ **\u4F55\u65F6\u4F7F\u7528**\uFF1A
134
+ - \u6392\u67E5\u5FAE\u524D\u7AEF/\u591A\u5B9E\u4F8B\u573A\u666F\u4E0B\u64CD\u4F5C\u7684\u662F\u54EA\u4E2A\u5E94\u7528
135
+ - \u5207\u6362\u6D3B\u8DC3\u5E94\u7528\u524D\u67E5\u770B\u6709\u54EA\u4E9B\u53EF\u7528`,
136
+ inputSchema: withPageIdSchema({ type: "object", properties: {} })
137
+ },
138
+ {
139
+ name: `${VUE_DEVTOOLS_PREFIX}set_active_app`,
140
+ action: import_core.VUE_DEVTOOLS_ACTIONS.TOGGLE_APP,
141
+ description: `\u5207\u6362\u6307\u5B9A\u9875\u9762\u7684\u6D3B\u8DC3 Vue \u5E94\u7528\u5B9E\u4F8B\u3002\u540E\u7EED\u6240\u6709 vue-devtools_* \u5DE5\u5177\u90FD\u64CD\u4F5C\u8FD9\u4E2A\u5E94\u7528\u3002`,
142
+ inputSchema: withPageIdSchema({
143
+ type: "object",
144
+ properties: {
145
+ appId: { type: "string", description: "\u5E94\u7528 ID\uFF08\u4ECE vue-devtools_get_apps \u83B7\u53D6\uFF09" }
146
+ },
147
+ required: ["appId"]
148
+ })
149
+ },
150
+ {
151
+ name: `${VUE_DEVTOOLS_PREFIX}get_component_tree`,
152
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_TREE,
153
+ description: `\u83B7\u53D6\u6307\u5B9A\u9875\u9762\u5F53\u524D\u6D3B\u8DC3 Vue \u5E94\u7528\u7684\u7EC4\u4EF6\u6811\u3002
154
+
155
+ **\u4F55\u65F6\u4F7F\u7528**\uFF1A
156
+ - \u4E86\u89E3\u9875\u9762\u7EC4\u4EF6\u5C42\u7EA7\u7ED3\u6784
157
+ - \u627E\u5230\u76EE\u6807\u7EC4\u4EF6\u7684 nodeId\uFF08\u540E\u7EED\u67E5\u72B6\u6001\u7528\uFF09
158
+ - \u6392\u67E5\u7EC4\u4EF6\u672A\u6E32\u67D3\u95EE\u9898
159
+ - \u53EA\u5173\u5FC3\u67D0\u7C7B\u7EC4\u4EF6\u65F6\u7528 filter \u7F29\u5C0F\u8303\u56F4
160
+
161
+ **\u8FD4\u56DE**\uFF1A\u7EC4\u4EF6\u6811 [{ id, name, children, file, ... }]`,
162
+ inputSchema: withPageIdSchema({
163
+ type: "object",
164
+ properties: {
165
+ filter: { type: "string", description: "\u6309\u7EC4\u4EF6\u540D\u8FC7\u6EE4\uFF08\u5927\u5C0F\u5199\u4E0D\u654F\u611F\u7684\u5B50\u4E32\u5339\u914D\uFF09\uFF0C\u53EF\u9009" }
166
+ }
167
+ })
168
+ },
169
+ {
170
+ name: `${VUE_DEVTOOLS_PREFIX}get_component_state`,
171
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_STATE,
172
+ description: `\u83B7\u53D6\u6307\u5B9A\u7EC4\u4EF6\u7684\u5B8C\u6574\u8FD0\u884C\u65F6\u72B6\u6001\u3002
173
+
174
+ **\u4F55\u65F6\u4F7F\u7528**\uFF1A
175
+ - \u6392\u67E5 props \u4F20\u503C\u662F\u5426\u6B63\u786E
176
+ - \u67E5\u770B ref/reactive \u54CD\u5E94\u5F0F\u6570\u636E\u7684\u5F53\u524D\u503C
177
+ - \u68C0\u67E5 computed \u8BA1\u7B97\u7ED3\u679C
178
+ - \u67E5\u770B attrs / events / inject / provide / template refs`,
179
+ inputSchema: withPageIdSchema({
180
+ type: "object",
181
+ properties: {
182
+ nodeId: {
183
+ type: "string",
184
+ description: "\u7EC4\u4EF6\u8282\u70B9 ID\uFF08\u4ECE vue-devtools_get_component_tree \u83B7\u53D6\uFF09"
185
+ }
186
+ },
187
+ required: ["nodeId"]
188
+ })
189
+ },
190
+ {
191
+ name: `${VUE_DEVTOOLS_PREFIX}get_component_render_code`,
192
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_RENDER_CODE,
193
+ description: `\u83B7\u53D6\u7EC4\u4EF6\u7684\u6E32\u67D3\u51FD\u6570\u6E90\u7801\u3002`,
194
+ inputSchema: withPageIdSchema({
195
+ type: "object",
196
+ properties: { nodeId: { type: "string", description: "\u7EC4\u4EF6\u8282\u70B9 ID" } },
197
+ required: ["nodeId"]
198
+ })
199
+ },
200
+ {
201
+ name: `${VUE_DEVTOOLS_PREFIX}get_current_route`,
202
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO,
203
+ description: `\u83B7\u53D6 Vue Router \u7684\u5F53\u524D\u8DEF\u7531\u4FE1\u606F\u3002
204
+
205
+ **\u4F55\u65F6\u4F7F\u7528**\uFF1A
206
+ - \u6392\u67E5\u8DEF\u7531\u8DF3\u8F6C\u95EE\u9898
207
+ - \u67E5\u770B\u5F53\u524D\u8DEF\u7531 path/params/query/hash
208
+ - \u786E\u8BA4\u8DEF\u7531\u5B88\u536B\u548C matched \u8BB0\u5F55`,
209
+ inputSchema: withPageIdSchema({ type: "object", properties: {} })
210
+ },
211
+ {
212
+ name: `${VUE_DEVTOOLS_PREFIX}get_routes`,
213
+ action: import_core.VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO,
214
+ description: `\u83B7\u53D6 Vue Router \u7684\u5B8C\u6574\u8DEF\u7531\u8868\u3002
215
+
216
+ **\u4F55\u65F6\u4F7F\u7528**\uFF1A
217
+ - \u67E5\u770B\u6240\u6709\u5DF2\u6CE8\u518C\u8DEF\u7531
218
+ - \u786E\u8BA4\u8DEF\u7531\u914D\u7F6E\u662F\u5426\u6B63\u786E
219
+ - \u67E5\u770B\u8DEF\u7531\u5D4C\u5957\u5173\u7CFB`,
220
+ inputSchema: withPageIdSchema({ type: "object", properties: {} })
72
221
  }
73
222
  ];
223
+ function findVueDevtoolsTool(name) {
224
+ return VUE_DEVTOOLS_TOOLS.find((t) => t.name === name);
225
+ }
226
+ function vueDevtoolsToolList() {
227
+ return VUE_DEVTOOLS_TOOLS.map(({ name, description, inputSchema }) => ({
228
+ name,
229
+ description,
230
+ inputSchema
231
+ }));
232
+ }
74
233
  const UNSAFE_CATEGORIES = /* @__PURE__ */ new Set(["EXTENSIONS", "PWA", "THIRD_PARTY", "WEBMCP"]);
75
234
  function metaByName(short) {
76
235
  return import_official_meta.OFFICIAL_TOOL_META.find((m) => m.name === short);
@@ -143,18 +302,25 @@ function isAllowedToolName(name) {
143
302
  // Annotate the CommonJS export names for ESM import in node:
144
303
  0 && (module.exports = {
145
304
  CUSTOM_TOOLS,
305
+ LOGS_DEVTOOLS_PREFIX,
146
306
  MCP_PREFIX,
147
307
  OFFICIAL_GLOBAL_POLICY,
148
308
  OFFICIAL_NO_PAGE_TOOLS,
149
309
  PAGE_ID_PROP,
150
310
  PROJECT_DESCRIPTION_NOTES,
311
+ VITE_LOGS_TOOL_NAME,
312
+ VUE_DEVTOOLS_PREFIX,
313
+ VUE_DEVTOOLS_TOOLS,
151
314
  configureToolScope,
152
315
  currentOfficialShorts,
153
316
  displayToolName,
154
317
  extraToolFlag,
318
+ findVueDevtoolsTool,
155
319
  isAllowedToolName,
156
320
  isOfficialExtraTool,
157
321
  officialDefaultShorts,
158
322
  officialExtraCandidates,
323
+ serviceLogToolName,
324
+ vueDevtoolsToolList,
159
325
  withPageIdSchema
160
326
  });
@@ -5,9 +5,17 @@
5
5
  * (schema/描述运行时同步自官方 tools/list,见 official-tools.ts)+ 本项目自定义工具。
6
6
  * 工具层限制(白名单、必填 pageId、仅项目页)由本文件 + endpoints/mcp.ts 的 tools/call 共同执行。
7
7
  */
8
+ import { type VueDevtoolsAction } from "@aipanel/core";
8
9
  /** 模型可见名前缀:官方短名 → chrome-devtools_<name> */
9
10
  export declare const MCP_PREFIX = "chrome-devtools_";
10
11
  export declare function displayToolName(short: string): string;
12
+ /** 本地桥接工具族前缀(tools/list 暴露面与 tools/call 路由共用) */
13
+ export declare const VUE_DEVTOOLS_PREFIX = "vue-devtools_";
14
+ export declare const LOGS_DEVTOOLS_PREFIX = "logs-devtools_";
15
+ /** Vite 进程日志工具名(工具定义与调用路由共用) */
16
+ export declare const VITE_LOGS_TOOL_NAME = "logs-devtools_vite_logs";
17
+ /** 服务日志文件工具名(按 LogFileConfig.name 生成,暴露与路由共用) */
18
+ export declare function serviceLogToolName(name: string): string;
11
19
  export interface CustomTool {
12
20
  name: string;
13
21
  description: string;
@@ -44,6 +52,20 @@ export declare function withPageIdSchema(schema: CustomTool["inputSchema"]): Cus
44
52
  export declare const PROJECT_DESCRIPTION_NOTES: Record<string, string>;
45
53
  /** 自定义工具(官方无对应,工具层本地实现) */
46
54
  export declare const CUSTOM_TOOLS: CustomTool[];
55
+ /**
56
+ * 页面桥接工具:描述与输入 schema(模型可见)+ 后端 action(调用分发)单一来源。
57
+ * tools/list 与 tools/call 都取自本定义,避免"清单"与"路由"两份来源各自漂移。
58
+ * 只在注入 Vue DevTools 桥的项目(Vue 项目)暴露。
59
+ */
60
+ export interface VueDevtoolsTool extends CustomTool {
61
+ /** 页面桥后端 action(endpoints/vue-devtools.ts executeAction) */
62
+ action: VueDevtoolsAction;
63
+ }
64
+ export declare const VUE_DEVTOOLS_TOOLS: readonly VueDevtoolsTool[];
65
+ /** vue-devtools_* 工具名 → 定义(未知名称返回 undefined) */
66
+ export declare function findVueDevtoolsTool(name: string): VueDevtoolsTool | undefined;
67
+ /** vue-devtools_* 的 tools/list 暴露面(剥掉仅用于路由分发的 action 字段) */
68
+ export declare function vueDevtoolsToolList(): CustomTool[];
47
69
  /** 官方声明了条件、且属于可开启范围的工具(由官方元数据派生,无手写) */
48
70
  export declare function isOfficialExtraTool(short: string): boolean;
49
71
  /** 由官方 conditions 推导所需 flag(experimentalX → --experimental-x,与官方 CLI 一致) */
@@ -36,7 +36,7 @@ var import_mcp = require("./mcp.cjs");
36
36
  var import_vue_devtools = require("./vue-devtools.cjs");
37
37
  var import_core = require("@aipanel/core");
38
38
  __reExport(endpoints_exports, require("./types.cjs"), module.exports);
39
- function setupMiddlewares(server, ctx, mcp, logFiles, chromeProject) {
39
+ function setupMiddlewares(server, ctx, mcp, logFiles, chromeProject, exposeVueDevtools = true) {
40
40
  (0, import_widget.setupWidgetEndpoints)(server, ctx);
41
41
  (0, import_context.setupContextEndpoint)(server, ctx);
42
42
  (0, import_start.setupStartEndpoint)(server, ctx);
@@ -46,7 +46,14 @@ function setupMiddlewares(server, ctx, mcp, logFiles, chromeProject) {
46
46
  (0, import_warmup.setupWarmupEndpoint)(server, ctx);
47
47
  (0, import_logs.setupLogsEndpoint)(server);
48
48
  if (mcp) {
49
- (0, import_mcp.setupMcpEndpoint)(server, mcp, () => ctx.getPageContext(), logFiles ?? [], chromeProject);
49
+ (0, import_mcp.setupMcpEndpoint)(
50
+ server,
51
+ mcp,
52
+ () => ctx.getPageContext(),
53
+ logFiles ?? [],
54
+ chromeProject,
55
+ exposeVueDevtools
56
+ );
50
57
  (0, import_vue_devtools.setupVueDevtoolsEndpoint)(server, mcp);
51
58
  }
52
59
  }
@@ -6,4 +6,6 @@ import type { McpProxy } from "../core/mcp-proxy";
6
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[], chromeProject?: ChromeProjectOptions): void;
9
+ export declare function setupMiddlewares(server: ViteDevServer, ctx: EndpointContext, mcp?: McpProxy, logFiles?: LogFileConfig[], chromeProject?: ChromeProjectOptions,
10
+ /** 是否暴露 vue-devtools_* 工具(Vue 项目才有页面桥;未识别框架按保守策略视为 Vue) */
11
+ exposeVueDevtools?: boolean): void;
@@ -30,7 +30,7 @@ var import_official_tools = require("../core/official-tools.cjs");
30
30
  var import_vue_devtools = require("./vue-devtools.cjs");
31
31
  var import_node2 = require("@aipanel/core/node");
32
32
  const log = (0, import_node.createLogger)("McpEndpoint");
33
- function setupMcpEndpoint(server, mcp, getPageContext, logFiles = [], chromeProject) {
33
+ function setupMcpEndpoint(server, mcp, getPageContext, logFiles = [], chromeProject, exposeVueDevtools = true) {
34
34
  const projectRoot = (0, import_node2.findGitRoot)(process.cwd());
35
35
  server.middlewares.use(async (req, res, next) => {
36
36
  if (!req.url?.startsWith(import_core.MCP_API_PATH)) return next();
@@ -63,7 +63,8 @@ function setupMcpEndpoint(server, mcp, getPageContext, logFiles = [], chromeProj
63
63
  scope.includeExtensions,
64
64
  getPageContext,
65
65
  logFiles,
66
- projectRoot
66
+ projectRoot,
67
+ exposeVueDevtools
67
68
  );
68
69
  return;
69
70
  }
@@ -81,7 +82,7 @@ function handleGetSse(req, res, mcp) {
81
82
  const keepAlive = setInterval(() => res.write(":ping\n\n"), 15e3);
82
83
  req.on("close", () => clearInterval(keepAlive));
83
84
  }
84
- async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot) {
85
+ async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot, exposeVueDevtools) {
85
86
  try {
86
87
  const body = await readBody(req);
87
88
  if (!body) {
@@ -93,7 +94,7 @@ async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, incl
93
94
  log.debug("MCP request", { method, body: body.substring(0, 150) });
94
95
  switch (method) {
95
96
  case "tools/list":
96
- return await handleToolsList(res, id, mcp, logFiles);
97
+ return await handleToolsList(res, id, mcp, logFiles, exposeVueDevtools);
97
98
  case "tools/call":
98
99
  return await handleToolsCall(
99
100
  res,
@@ -105,7 +106,8 @@ async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, incl
105
106
  includeExtensions,
106
107
  getPageContext,
107
108
  logFiles,
108
- projectRoot
109
+ projectRoot,
110
+ exposeVueDevtools
109
111
  );
110
112
  default:
111
113
  return await handleForward(res, body, mcp);
@@ -118,7 +120,7 @@ async function handlePost(req, res, mcp, projectOrigins, operationsOrigins, incl
118
120
  });
119
121
  }
120
122
  }
121
- async function handleToolsList(res, id, mcp, logFiles) {
123
+ async function handleToolsList(res, id, mcp, logFiles, exposeVueDevtools) {
122
124
  let official = [];
123
125
  try {
124
126
  official = await (0, import_official_tools.getOfficialProjectTools)(mcp);
@@ -127,20 +129,28 @@ async function handleToolsList(res, id, mcp, logFiles) {
127
129
  error: e instanceof Error ? e.message : String(e)
128
130
  });
129
131
  }
130
- const tools = [...official, ...import_mcp_tools.CUSTOM_TOOLS, ...buildServiceLogTools(logFiles)];
132
+ const tools = [
133
+ ...official,
134
+ ...import_mcp_tools.CUSTOM_TOOLS,
135
+ ...exposeVueDevtools ? (0, import_mcp_tools.vueDevtoolsToolList)() : [],
136
+ ...buildServiceLogTools(logFiles)
137
+ ];
131
138
  sendMcpJson(res, 200, { jsonrpc: "2.0", id, result: { tools } }, mcp.sessionId);
132
139
  }
133
- function handleToolsCall(res, id, body, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot) {
140
+ function handleToolsCall(res, id, body, mcp, projectOrigins, operationsOrigins, includeExtensions, getPageContext, logFiles, projectRoot, exposeVueDevtools) {
134
141
  const params = tryParseParams(body);
135
142
  const toolName = params?.name;
136
143
  const args = params?.arguments ?? {};
137
144
  if (toolName === "chrome-devtools_current_page") {
138
145
  return handleGetPageContext(res, id, mcp, operationsOrigins, includeExtensions, getPageContext);
139
146
  }
140
- if (toolName?.startsWith("vue-devtools_")) {
147
+ if (toolName?.startsWith(import_mcp_tools.VUE_DEVTOOLS_PREFIX)) {
148
+ if (!exposeVueDevtools) {
149
+ return sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, mcp.sessionId);
150
+ }
141
151
  return handleVueDevtoolsTool(res, id, mcp, projectOrigins, toolName, args);
142
152
  }
143
- if (toolName === "logs-devtools_vite_logs") {
153
+ if (toolName === import_mcp_tools.VITE_LOGS_TOOL_NAME) {
144
154
  return handleViteLogsTool(res, id, args, mcp.sessionId);
145
155
  }
146
156
  if (toolName && isServiceLogTool(toolName, logFiles)) {
@@ -401,23 +411,14 @@ async function handleDevTool(res, id, mcp, mapped, args, operationsOrigins, incl
401
411
  sendMcpError(res, id, -32603, `MCP \u8C03\u7528\u5931\u8D25: ${e.message}`, mcp.sessionId);
402
412
  }
403
413
  }
404
- const VUE_DEVTOOLS_TOOL_ACTIONS = {
405
- "vue-devtools_get_apps": import_core.VUE_DEVTOOLS_ACTIONS.GET_APPS,
406
- "vue-devtools_set_active_app": import_core.VUE_DEVTOOLS_ACTIONS.TOGGLE_APP,
407
- "vue-devtools_get_component_tree": import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_TREE,
408
- "vue-devtools_get_component_state": import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_STATE,
409
- "vue-devtools_get_component_render_code": import_core.VUE_DEVTOOLS_ACTIONS.GET_COMPONENT_RENDER_CODE,
410
- "vue-devtools_get_current_route": import_core.VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO,
411
- "vue-devtools_get_routes": import_core.VUE_DEVTOOLS_ACTIONS.GET_ROUTER_INFO
412
- };
413
414
  async function handleVueDevtoolsTool(res, id, mcp, projectOrigins, toolName, args) {
414
415
  try {
415
- const action = VUE_DEVTOOLS_TOOL_ACTIONS[toolName];
416
- if (!action) {
416
+ const tool = (0, import_mcp_tools.findVueDevtoolsTool)(toolName);
417
+ if (!tool) {
417
418
  sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, mcp.sessionId);
418
419
  return;
419
420
  }
420
- const result = await (0, import_vue_devtools.executeAction)(action, args, mcp, projectOrigins);
421
+ const result = await (0, import_vue_devtools.executeAction)(tool.action, args, mcp, projectOrigins);
421
422
  switch (toolName) {
422
423
  case "vue-devtools_set_active_app":
423
424
  sendMcpResult(res, id, `\u5DF2\u5207\u6362\u5230\u5E94\u7528 ${args["appId"]}`, mcp.sessionId);
@@ -496,7 +497,7 @@ function parseProcessLevelFilter(level) {
496
497
  }
497
498
  function buildServiceLogTools(logFiles) {
498
499
  return logFiles.map((cfg) => ({
499
- name: `logs-devtools_${cfg.name}_logs`,
500
+ name: (0, import_mcp_tools.serviceLogToolName)(cfg.name),
500
501
  description: `\u83B7\u53D6 ${cfg.name} \u7684\u65E5\u5FD7\u3002
501
502
 
502
503
  **\u4F55\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177**\uFF1A
@@ -524,11 +525,11 @@ ${cfg.description}
524
525
  }));
525
526
  }
526
527
  function isServiceLogTool(toolName, logFiles) {
527
- return logFiles.some((cfg) => `logs-devtools_${cfg.name}_logs` === toolName);
528
+ return logFiles.some((cfg) => (0, import_mcp_tools.serviceLogToolName)(cfg.name) === toolName);
528
529
  }
529
530
  async function handleServiceLogsTool(res, id, toolName, args, logFiles, projectRoot, sessionId) {
530
531
  try {
531
- const cfg = logFiles.find((c) => `logs-devtools_${c.name}_logs` === toolName);
532
+ const cfg = logFiles.find((c) => (0, import_mcp_tools.serviceLogToolName)(c.name) === toolName);
532
533
  if (!cfg) {
533
534
  sendMcpError(res, id, -32601, `Tool not found: ${toolName}`, sessionId);
534
535
  return;
@@ -3,4 +3,6 @@ import type { ChromeProjectOptions, LogFileConfig, PageContext } from "@aipanel/
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[], chromeProject?: ChromeProjectOptions): void;
6
+ export declare function setupMcpEndpoint(server: ViteDevServer, mcp: McpProxy, getPageContext: () => PageContext, logFiles?: LogFileConfig[], chromeProject?: ChromeProjectOptions,
7
+ /** Vue 项目才注入 vue-devtools 桥;非 Vue 项目既不上架也不路由这些工具,避免模型调用必失败的工具 */
8
+ exposeVueDevtools?: boolean): void;
package/lib/index.cjs CHANGED
@@ -230,7 +230,8 @@ function createAIPanelPlugin(options = {}) {
230
230
  },
231
231
  mcpProxy,
232
232
  config.logFiles,
233
- chromeProjectOptions
233
+ chromeProjectOptions,
234
+ isVueProject
234
235
  );
235
236
  if (!config.mcpOnly) {
236
237
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-aipanel",
3
- "version": "1.2.22",
3
+ "version": "1.2.24",
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,6 +35,8 @@
35
35
  "author": "",
36
36
  "license": "MIT",
37
37
  "dependencies": {
38
+ "@aipanel/core": "1.2.24",
39
+ "@aipanel/provider-opencode": "1.2.24",
38
40
  "@code-inspector/core": "^2.0.9",
39
41
  "@vue/devtools-kit": "^8.0.0",
40
42
  "@vue/language-server": "^3.3.7",
@@ -42,13 +44,11 @@
42
44
  "execa": "^9.6.1",
43
45
  "picomatch": "^4.0.2",
44
46
  "typescript-language-server": "^5.3.0",
45
- "unplugin-vue-inspector": "^3.0.0",
46
- "@aipanel/core": "1.2.22",
47
- "@aipanel/provider-opencode": "1.2.22"
47
+ "unplugin-vue-inspector": "^3.0.0"
48
48
  },
49
49
  "peerDependencies": {
50
- "vite": ">=5.0.0",
51
- "@aipanel/provider-deepseek": "1.2.22"
50
+ "@aipanel/provider-deepseek": "1.2.24",
51
+ "vite": ">=5.0.0"
52
52
  },
53
53
  "peerDependenciesMeta": {
54
54
  "@aipanel/provider-deepseek": {
@@ -56,9 +56,9 @@
56
56
  }
57
57
  },
58
58
  "devDependencies": {
59
+ "@aipanel/client": "1.2.24",
59
60
  "@types/picomatch": "^4.0.0",
60
- "sharp": "^0.34.5",
61
- "@aipanel/client": "1.2.22"
61
+ "sharp": "^0.34.5"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "node scripts/sync-official-meta.mjs && pagoda-cli build && vite build -c vite.client.config.ts",