vite-plugin-aipanel 1.2.8 → 1.2.10

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.
Files changed (58) hide show
  1. package/es/core/chrome-project.d.ts +15 -0
  2. package/es/core/chrome-project.mjs +13 -0
  3. package/es/core/mcp-chrome.d.ts +12 -8
  4. package/es/core/mcp-chrome.mjs +52 -10
  5. package/es/core/mcp-proxy.d.ts +21 -1
  6. package/es/core/mcp-proxy.mjs +83 -12
  7. package/es/core/mcp-tools.d.ts +51 -3
  8. package/es/core/mcp-tools.mjs +109 -659
  9. package/es/core/official-meta.d.ts +9 -0
  10. package/es/core/official-meta.mjs +62 -0
  11. package/es/core/official-tools.d.ts +7 -0
  12. package/es/core/official-tools.mjs +54 -0
  13. package/es/core/proxy-server.mjs +16 -13
  14. package/es/core/service.mjs +4 -5
  15. package/es/endpoints/context.mjs +2 -2
  16. package/es/endpoints/host-events.mjs +1 -2
  17. package/es/endpoints/index.d.ts +2 -2
  18. package/es/endpoints/index.mjs +2 -2
  19. package/es/endpoints/mcp.d.ts +2 -2
  20. package/es/endpoints/mcp.mjs +116 -87
  21. package/es/endpoints/sse.mjs +3 -3
  22. package/es/endpoints/vue-devtools.d.ts +5 -2
  23. package/es/endpoints/vue-devtools.mjs +3 -4
  24. package/es/index.mjs +29 -6
  25. package/lib/client.js +2380 -2369
  26. package/lib/core/chrome-project.cjs +36 -0
  27. package/lib/core/chrome-project.d.ts +15 -0
  28. package/lib/core/mcp-chrome.cjs +64 -10
  29. package/lib/core/mcp-chrome.d.ts +12 -8
  30. package/lib/core/mcp-proxy.cjs +87 -13
  31. package/lib/core/mcp-proxy.d.ts +21 -1
  32. package/lib/core/mcp-tools.cjs +124 -660
  33. package/lib/core/mcp-tools.d.ts +51 -3
  34. package/lib/core/official-meta.cjs +85 -0
  35. package/lib/core/official-meta.d.ts +9 -0
  36. package/lib/core/official-tools.cjs +70 -0
  37. package/lib/core/official-tools.d.ts +7 -0
  38. package/lib/core/proxy-server.cjs +16 -13
  39. package/lib/core/service.cjs +4 -5
  40. package/lib/endpoints/context.cjs +1 -1
  41. package/lib/endpoints/host-events.cjs +0 -1
  42. package/lib/endpoints/index.cjs +2 -2
  43. package/lib/endpoints/index.d.ts +2 -2
  44. package/lib/endpoints/mcp.cjs +114 -85
  45. package/lib/endpoints/mcp.d.ts +2 -2
  46. package/lib/endpoints/sse.cjs +2 -2
  47. package/lib/endpoints/vue-devtools.cjs +4 -5
  48. package/lib/endpoints/vue-devtools.d.ts +5 -2
  49. package/lib/index.cjs +29 -7
  50. package/package.json +10 -7
  51. package/es/utils/format-bridge.d.ts +0 -9
  52. package/es/utils/format-bridge.mjs +0 -80
  53. package/es/utils/system.d.ts +0 -3
  54. package/es/utils/system.mjs +0 -76
  55. package/lib/utils/format-bridge.cjs +0 -102
  56. package/lib/utils/format-bridge.d.ts +0 -9
  57. package/lib/utils/system.cjs +0 -110
  58. package/lib/utils/system.d.ts +0 -3
@@ -0,0 +1,36 @@
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 chrome_project_exports = {};
19
+ __export(chrome_project_exports, {
20
+ resolveProjectScope: () => resolveProjectScope
21
+ });
22
+ module.exports = __toCommonJS(chrome_project_exports);
23
+ var import_mcp_chrome = require("./mcp-chrome.cjs");
24
+ function resolveProjectScope(server, project) {
25
+ const auto = (0, import_mcp_chrome.getProjectOrigins)(server);
26
+ const operationsOrigins = [.../* @__PURE__ */ new Set([...auto, ...project?.allowOrigins ?? []])];
27
+ return {
28
+ origins: auto,
29
+ operationsOrigins,
30
+ includeExtensions: project?.includeExtensionPages === true
31
+ };
32
+ }
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ resolveProjectScope
36
+ });
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 项目边界策略解析:在请求时把 chromeMcp.project 与 vite 自动 origins 合并为一份体。
3
+ * 所有边界判定(页面归属 / 导航目标 / 扩展页)均只读此解析结果,单一来源。
4
+ */
5
+ import type { ViteDevServer } from "vite";
6
+ import type { ChromeProjectOptions } from "@aipanel/core";
7
+ export interface ProjectScope {
8
+ /** 项目页 origins(自动,“项目页全局一个”分类 + vue-devtools 桥可用范围) */
9
+ origins: string[];
10
+ /** 可操作范围 = 项目页 ∪ allowOrigins:chrome 页面级 list/current/pageId 校验、navigate/new 目标用 */
11
+ operationsOrigins: string[];
12
+ /** 是否允许 chrome-extension:// 页面纳入可操作范围 */
13
+ includeExtensions: boolean;
14
+ }
15
+ export declare function resolveProjectScope(server: ViteDevServer, project?: ChromeProjectOptions): ProjectScope;
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,17 +16,28 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
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
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
  var mcp_chrome_exports = {};
19
29
  __export(mcp_chrome_exports, {
20
30
  extractEvalValue: () => extractEvalValue,
21
31
  getProjectOrigins: () => getProjectOrigins,
32
+ isOriginEntryMatch: () => isOriginEntryMatch,
33
+ isPageAllowed: () => isPageAllowed,
22
34
  isProjectPage: () => isProjectPage,
23
35
  parseListPages: () => parseListPages,
24
36
  resolveChromePageId: () => resolveChromePageId,
25
37
  validatePageId: () => validatePageId
26
38
  });
27
39
  module.exports = __toCommonJS(mcp_chrome_exports);
40
+ var import_picomatch = __toESM(require("picomatch"));
28
41
  var import_node = require("@aipanel/core/node");
29
42
  const log = (0, import_node.createLogger)("McpChrome");
30
43
  function getProjectOrigins(server) {
@@ -34,8 +47,45 @@ function getProjectOrigins(server) {
34
47
  log.debug("project origins", { origins });
35
48
  return origins;
36
49
  }
50
+ const entryMatcherCache = /* @__PURE__ */ new Map();
51
+ function parseRegexEntry(entry) {
52
+ if (!entry.startsWith("/")) return void 0;
53
+ const lastSlash = entry.lastIndexOf("/");
54
+ if (lastSlash <= 0) return void 0;
55
+ const source = entry.slice(1, lastSlash);
56
+ const flags = entry.slice(lastSlash + 1);
57
+ if (!/^[a-z]*$/.test(flags)) return void 0;
58
+ try {
59
+ return { kind: "regex", re: new RegExp(source, flags) };
60
+ } catch {
61
+ return void 0;
62
+ }
63
+ }
64
+ function compileEntryMatcher(entry) {
65
+ const cached = entryMatcherCache.get(entry);
66
+ if (cached) return cached;
67
+ let compiled = { kind: "prefix" };
68
+ const regexMatcher = parseRegexEntry(entry);
69
+ if (regexMatcher) {
70
+ compiled = regexMatcher;
71
+ } else if (import_picomatch.default.scan(entry).isGlob) {
72
+ compiled = { kind: "glob", match: (0, import_picomatch.default)(entry) };
73
+ }
74
+ entryMatcherCache.set(entry, compiled);
75
+ return compiled;
76
+ }
77
+ function isOriginEntryMatch(url, entry) {
78
+ const matcher = compileEntryMatcher(entry);
79
+ if (matcher.kind === "regex") return matcher.re.test(url);
80
+ if (matcher.kind === "glob") return matcher.match(url);
81
+ return url.startsWith(entry);
82
+ }
37
83
  function isProjectPage(url, origins) {
38
- return origins.some((origin) => url.startsWith(origin));
84
+ return origins.some((entry) => isOriginEntryMatch(url, entry));
85
+ }
86
+ function isPageAllowed(url, origins, includeExtensions) {
87
+ if (origins.some((entry) => isOriginEntryMatch(url, entry))) return true;
88
+ return includeExtensions && url.startsWith("chrome-extension://");
39
89
  }
40
90
  function parseListPages(text) {
41
91
  const pages = [];
@@ -66,29 +116,31 @@ function extractEvalValue(text) {
66
116
  return jsonStr.trim();
67
117
  }
68
118
  }
69
- async function validatePageId(mcp, pageId, projectOrigins) {
119
+ async function validatePageId(mcp, pageId, operationsOrigins, includeExtensions = false) {
70
120
  const listResult = await mcp.callChromeDevTool("list_pages", {});
71
121
  if (listResult?.error || !listResult?.result) {
72
122
  return {
73
123
  valid: false,
74
124
  error: listResult?.error?.message ?? "\u65E0\u6CD5\u83B7\u53D6 Chrome \u9875\u9762\u5217\u8868\uFF0C\u8BF7\u786E\u8BA4 Chrome DevTools \u5DF2\u8FDE\u63A5",
75
- projectPages: []
125
+ allowedPages: []
76
126
  };
77
127
  }
78
128
  const text = listResult?.result?.content?.[0]?.text;
79
129
  const allPages = text ? parseListPages(text) : [];
80
- const projectPages = allPages.filter((p) => isProjectPage(p.url, projectOrigins));
81
- const isValid = projectPages.some((p) => p.pageId === pageId);
130
+ const allowedPages = allPages.filter(
131
+ (p) => isPageAllowed(p.url, operationsOrigins, includeExtensions)
132
+ );
133
+ const isValid = allowedPages.some((p) => p.pageId === pageId);
82
134
  if (!isValid) {
83
135
  return {
84
136
  valid: false,
85
- error: `pageId ${pageId} \u65E0\u6548\u6216\u975E\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u83B7\u53D6\u6709\u6548\u9875\u9762 ID`,
86
- projectPages
137
+ error: `pageId ${pageId} \u4E0D\u5728\u53EF\u64CD\u4F5C\u8303\u56F4\uFF08\u9879\u76EE\u9875\u6216 allowOrigins \u767D\u540D\u5355\u9875\uFF09\uFF0C\u8BF7\u5148\u7528 list_pages \u83B7\u53D6\u6709\u6548\u9875\u9762 ID`,
138
+ allowedPages
87
139
  };
88
140
  }
89
- return { valid: true, projectPages };
141
+ return { valid: true, allowedPages };
90
142
  }
91
- async function resolveChromePageId(mcp, url, title, projectOrigins, sessionId, pages, chromeSelectedPageId) {
143
+ async function resolveChromePageId(mcp, url, title, operationsOrigins, sessionId, pages, chromeSelectedPageId) {
92
144
  if (!mcp || !mcp.isRunning) {
93
145
  const reason = !mcp ? "MCP \u6A21\u5757\u672A\u521D\u59CB\u5316" : "Chrome DevTools MCP \u8FDB\u7A0B\u672A\u542F\u52A8";
94
146
  log.debug(`resolveChromePageId: ${reason}`);
@@ -106,7 +158,7 @@ async function resolveChromePageId(mcp, url, title, projectOrigins, sessionId, p
106
158
  }
107
159
  const allPages = parseListPages(text);
108
160
  chromeSelectedPageId = allPages.find((p) => p.selected)?.pageId;
109
- pages = allPages.filter((p) => isProjectPage(p.url, projectOrigins));
161
+ pages = allPages.filter((p) => isProjectPage(p.url, operationsOrigins));
110
162
  }
111
163
  log.debug("resolveChromePageId: list_pages result", {
112
164
  pages: pages.map((p) => ({ id: p.pageId, url: p.url, title: p.title.substring(0, 40) })),
@@ -154,6 +206,8 @@ async function resolveChromePageId(mcp, url, title, projectOrigins, sessionId, p
154
206
  0 && (module.exports = {
155
207
  extractEvalValue,
156
208
  getProjectOrigins,
209
+ isOriginEntryMatch,
210
+ isPageAllowed,
157
211
  isProjectPage,
158
212
  parseListPages,
159
213
  resolveChromePageId,
@@ -7,8 +7,12 @@ import type { ViteDevServer } from "vite";
7
7
  import type { McpProxy } from "./mcp-proxy";
8
8
  /** 从 Vite 服务器解析的所有 URL 中提取项目 origin 列表 */
9
9
  export declare function getProjectOrigins(server: ViteDevServer): string[];
10
- /** 判断页面 URL 是否属于项目的某个 origin */
10
+ /** 判断页面 URL 是否命中某个范围条目(allowOrigins 三种写法,见模块注释) */
11
+ export declare function isOriginEntryMatch(url: string, entry: string): boolean;
12
+ /** 判断页面 URL 是否命中某组范围条目(可为精确 origin / 通配符 / 正则) */
11
13
  export declare function isProjectPage(url: string, origins: string[]): boolean;
14
+ /** 判断页面 URL 是否属于可操作范围(范围条目,或启用时的扩展页) */
15
+ export declare function isPageAllowed(url: string, origins: string[], includeExtensions: boolean): boolean;
12
16
  export interface PageInfo {
13
17
  pageId: number;
14
18
  url: string;
@@ -28,18 +32,18 @@ type PageIdResult = {
28
32
  error: string;
29
33
  };
30
34
  /**
31
- * 校验 pageId 是否属于项目页面
35
+ * 校验 pageId 是否属于可操作范围(项目页 ∪ allowOrigins)
32
36
  *
33
- * 调用 list_pages → 过滤项目页面 → 检查 pageId 是否在范围内。
37
+ * 调用 list_pages → 过滤允许页面 → 检查 pageId 是否在范围内。
34
38
  * 供 MCP 代理层和 Vue DevTools 端点共用。
35
39
  */
36
- export declare function validatePageId(mcp: McpProxy, pageId: number, projectOrigins: string[]): Promise<{
40
+ export declare function validatePageId(mcp: McpProxy, pageId: number, operationsOrigins: string[], includeExtensions?: boolean): Promise<{
37
41
  valid: true;
38
- projectPages: PageInfo[];
42
+ allowedPages: PageInfo[];
39
43
  } | {
40
44
  valid: false;
41
45
  error: string;
42
- projectPages: PageInfo[];
46
+ allowedPages: PageInfo[];
43
47
  }>;
44
48
  /**
45
49
  * 通过 MCP 解析当前页面对应的 Chrome DevTools pageId
@@ -50,7 +54,7 @@ export declare function validatePageId(mcp: McpProxy, pageId: number, projectOri
50
54
  *
51
55
  * 失败时返回具体原因,由调用方透传给 Agent。
52
56
  */
53
- export declare function resolveChromePageId(mcp: McpProxy | undefined, url: string, title: string, projectOrigins: string[], sessionId?: string, pages?: PageInfo[],
54
- /** Chrome 当前选中的 pageId(调用方传入,避免过滤后丢失非项目页面信息) */
57
+ export declare function resolveChromePageId(mcp: McpProxy | undefined, url: string, title: string, operationsOrigins: string[], sessionId?: string, pages?: PageInfo[],
58
+ /** Chrome 当前选中的 pageId(调用方传入,避免过滤后丢失范围外页面信息) */
55
59
  chromeSelectedPageId?: number): Promise<PageIdResult>;
56
60
  export {};
@@ -45,7 +45,10 @@ var __privateWrapper = (obj, member, setter, getter) => ({
45
45
  });
46
46
  var mcp_proxy_exports = {};
47
47
  __export(mcp_proxy_exports, {
48
- McpProxy: () => McpProxy
48
+ CORE_MCP_ARGS: () => CORE_MCP_ARGS,
49
+ McpProxy: () => McpProxy,
50
+ classifyUserMcpArgs: () => classifyUserMcpArgs,
51
+ filterUserMcpArgs: () => filterUserMcpArgs
49
52
  });
50
53
  module.exports = __toCommonJS(mcp_proxy_exports);
51
54
  var import_node_child_process = require("node:child_process");
@@ -53,8 +56,71 @@ var import_node_readline = require("node:readline");
53
56
  var import_node_crypto = __toESM(require("node:crypto"));
54
57
  var import_node_path = __toESM(require("node:path"));
55
58
  var import_node = require("@aipanel/core/node");
56
- var _proc, _rl, _messageId, _internalIdBase, _pending, _args, _startPromise, _lastExit, _stderrTail, _idleTimer, _idleTimeout, _McpProxy_instances, doStart_fn, formatNotAvailable_fn, resetIdleTimer_fn;
59
+ var _proc, _rl, _messageId, _internalIdBase, _pending, _args, _env, _startPromise, _lastExit, _stderrTail, _idleTimer, _idleTimeout, _McpProxy_instances, doStart_fn, formatNotAvailable_fn, resetIdleTimer_fn;
57
60
  const log = (0, import_node.createLogger)("McpProxy");
61
+ const CORE_MCP_ARGS = [
62
+ "--auto-connect",
63
+ "--no-usage-statistics",
64
+ "--no-performance-crux",
65
+ // chrome-devtools-mcp >=1.8.0 默认开启 pageIdRouting(要求每个页面级工具都传 pageId)。
66
+ // 代理层已自行校验 pageId 并用 select_page 选中目标页面后再转发,故显式关闭,
67
+ // 避免底层工具 schema 强制必填 pageId 导致转发时的参数校验失败。
68
+ "--no-page-id-routing",
69
+ // 客户端未协商 roots,官方默认把文件工具限制在 OS 临时目录;
70
+ // 为保持 upload_file “不限制项目目录”的设计,显式允许任意路径
71
+ // (工具层仍受白名单 + pageId 归属约束)。
72
+ "--allow-unrestricted-paths"
73
+ ];
74
+ const PROTECTED_FLAGS = /* @__PURE__ */ new Set([
75
+ "auto-connect",
76
+ "usage-statistics",
77
+ "performance-crux",
78
+ "page-id-routing"
79
+ ]);
80
+ const MANAGED_FLAGS = /* @__PURE__ */ new Set([
81
+ "slim",
82
+ "category-extensions",
83
+ "category-pwa",
84
+ "category-experimental-third-party",
85
+ "category-experimental-webmcp",
86
+ "category-performance",
87
+ "category-network",
88
+ "category-emulation",
89
+ "experimental-vision",
90
+ "experimental-interop-tools",
91
+ "experimental-memory",
92
+ "experimental-screencast",
93
+ "experimental-structured-content",
94
+ "experimental-include-all-pages",
95
+ "allow-unrestricted-paths"
96
+ ]);
97
+ function canonicalFlagName(arg) {
98
+ let flag = arg.trim();
99
+ if (!flag.startsWith("-")) return null;
100
+ flag = flag.replace(/^--?/, "").split("=")[0] ?? "";
101
+ if (flag.startsWith("no-")) flag = flag.slice(3);
102
+ return flag || null;
103
+ }
104
+ function classifyUserMcpArgs(userArgs) {
105
+ const kept = [];
106
+ const dropped = [];
107
+ for (const arg of userArgs) {
108
+ const name = canonicalFlagName(arg);
109
+ if (name === null) {
110
+ kept.push(arg);
111
+ } else if (PROTECTED_FLAGS.has(name)) {
112
+ dropped.push({ arg, kind: "protected" });
113
+ } else if (MANAGED_FLAGS.has(name)) {
114
+ dropped.push({ arg, kind: "managed" });
115
+ } else {
116
+ kept.push(arg);
117
+ }
118
+ }
119
+ return { kept, dropped };
120
+ }
121
+ function filterUserMcpArgs(userArgs) {
122
+ return classifyUserMcpArgs(userArgs).kept;
123
+ }
58
124
  function resolveChromeDevToolsMcpBin() {
59
125
  const pluginDir = (0, import_node.resolvePackageDir)("vite-plugin-aipanel");
60
126
  const require2 = (0, import_node.createPackageRequire)(pluginDir);
@@ -74,6 +140,7 @@ class McpProxy {
74
140
  __privateAdd(this, _internalIdBase, 1e6);
75
141
  __privateAdd(this, _pending, /* @__PURE__ */ new Map());
76
142
  __privateAdd(this, _args);
143
+ __privateAdd(this, _env);
77
144
  __privateAdd(this, _startPromise, null);
78
145
  /** 最近一次进程退出信息,用于生成精确错误(无退出记录时为 null) */
79
146
  __privateAdd(this, _lastExit, null);
@@ -82,15 +149,17 @@ class McpProxy {
82
149
  __privateAdd(this, _idleTimer, null);
83
150
  __privateAdd(this, _idleTimeout);
84
151
  __publicField(this, "sessionId");
85
- __privateSet(this, _args, options.args ?? [
86
- "--auto-connect",
87
- "--no-usage-statistics",
88
- "--no-performance-crux",
89
- // chrome-devtools-mcp >=1.8.0 默认开启 pageIdRouting(要求每个页面级工具都传 pageId)。
90
- // 代理层已自行校验 pageId 并用 select_page 选中目标页面后再转发,故显式关闭,
91
- // 避免底层工具 schema 强制必填 pageId 导致转发时的参数校验失败。
92
- "--no-page-id-routing"
93
- ]);
152
+ const userArgs = options.userArgs ?? [];
153
+ const { kept, dropped } = classifyUserMcpArgs(userArgs);
154
+ if (dropped.length > 0) {
155
+ log.warn(
156
+ "chrome MCP \u7528\u6237\u53C2\u6570\u4E0E\u53D7\u4FDD\u62A4/\u7B56\u7565\u63A5\u7BA1 flag \u51B2\u7A81\uFF0C\u5DF2\u5FFD\u7565\uFF1B\u8BF7\u7528 chromeMcp.project \u914D\u7F6E\u5BF9\u5E94\u884C\u4E3A",
157
+ { dropped }
158
+ );
159
+ }
160
+ const managedArgs = options.managedArgs ?? [];
161
+ __privateSet(this, _args, [...kept, ...managedArgs, ...CORE_MCP_ARGS]);
162
+ __privateSet(this, _env, options.env);
94
163
  __privateSet(this, _idleTimeout, options.idleTimeout ?? 0);
95
164
  this.sessionId = import_node_crypto.default.randomUUID();
96
165
  }
@@ -184,6 +253,7 @@ _messageId = new WeakMap();
184
253
  _internalIdBase = new WeakMap();
185
254
  _pending = new WeakMap();
186
255
  _args = new WeakMap();
256
+ _env = new WeakMap();
187
257
  _startPromise = new WeakMap();
188
258
  _lastExit = new WeakMap();
189
259
  _stderrTail = new WeakMap();
@@ -197,7 +267,8 @@ doStart_fn = async function() {
197
267
  __privateSet(this, _lastExit, null);
198
268
  __privateSet(this, _stderrTail, []);
199
269
  __privateSet(this, _proc, (0, import_node_child_process.spawn)(process.execPath, [binPath, ...__privateGet(this, _args)], {
200
- stdio: ["pipe", "pipe", "pipe"]
270
+ stdio: ["pipe", "pipe", "pipe"],
271
+ env: { ...process.env, ...__privateGet(this, _env) }
201
272
  }));
202
273
  log.debug("Using local chrome-devtools-mcp");
203
274
  } catch {
@@ -287,5 +358,8 @@ resetIdleTimer_fn = function() {
287
358
  };
288
359
  // Annotate the CommonJS export names for ESM import in node:
289
360
  0 && (module.exports = {
290
- McpProxy
361
+ CORE_MCP_ARGS,
362
+ McpProxy,
363
+ classifyUserMcpArgs,
364
+ filterUserMcpArgs
291
365
  });
@@ -1,5 +1,25 @@
1
+ /** chrome-devtools-mcp 的核心受保护参数(用户不可覆盖;始终最后注入确保生效) */
2
+ export declare const CORE_MCP_ARGS: readonly ["--auto-connect", "--no-usage-statistics", "--no-performance-crux", "--no-page-id-routing", "--allow-unrestricted-paths"];
3
+ /** 过滤用户透传参数:剔除与核心受保护 flag 冲突的项,其余原样保留 */
4
+ export type McpArgDropKind = "protected" | "managed";
5
+ export interface McpArgDrop {
6
+ arg: string;
7
+ kind: McpArgDropKind;
8
+ }
9
+ /** 分类用户透传参数:保留可透传项,列出被剔除项及原因 */
10
+ export declare function classifyUserMcpArgs(userArgs: readonly string[]): {
11
+ kept: string[];
12
+ dropped: McpArgDrop[];
13
+ };
14
+ /** 过滤用户透传参数:剔除与核心受保护/策略接管 flag 冲突的项 */
15
+ export declare function filterUserMcpArgs(userArgs: readonly string[]): string[];
1
16
  export interface McpProxyOptions {
2
- args?: string[];
17
+ /** 用户透传的额外 CLI 参数(追加;与核心受保护项冲突的会被剔除) */
18
+ userArgs?: string[];
19
+ /** 策略控制的内部注入参数(不经用户过滤,在用户参数之后、核心参数之前注入) */
20
+ managedArgs?: string[];
21
+ /** 用户透传的额外环境变量(合并到 process.env 之上) */
22
+ env?: Record<string, string>;
3
23
  idleTimeout?: number;
4
24
  }
5
25
  export declare class McpProxy {