





























@@ -68,6 +68,7 @@ function createContext() {
6868function createResolveToolsParams(params?: {
6969context?: ReturnType<typeof createContext> & Record<string, unknown>;
7070toolAllowlist?: readonly string[];
71+toolDenylist?: readonly string[];
7172existingToolNames?: Set<string>;
7273env?: NodeJS.ProcessEnv;
7374suppressNameConflicts?: boolean;
@@ -76,6 +77,7 @@ function createResolveToolsParams(params?: {
7677return {
7778context: (params?.context ?? createContext()) as never,
7879 ...(params?.toolAllowlist ? { toolAllowlist: [...params.toolAllowlist] } : {}),
80+ ...(params?.toolDenylist ? { toolDenylist: [...params.toolDenylist] } : {}),
7981 ...(params?.existingToolNames ? { existingToolNames: params.existingToolNames } : {}),
8082 ...(params?.env ? { env: params.env } : {}),
8183 ...(params?.suppressNameConflicts ? { suppressNameConflicts: true } : {}),
@@ -2177,6 +2179,30 @@ describe("resolvePluginTools optional tools", () => {
21772179expectResolvedToolNames(tools, ["browser"]);
21782180});
217921812182+it("does not materialize plugin tools blocked by explicit deny policy", () => {
2183+const browserFactory = vi.fn(() => makeTool("browser"));
2184+const browserEntry: MockRegistryToolEntry = {
2185+pluginId: "browser",
2186+optional: false,
2187+source: "/tmp/browser.js",
2188+names: ["browser"],
2189+declaredNames: ["browser"],
2190+factory: browserFactory,
2191+};
2192+setRegistry([browserEntry]);
2193+2194+const tools = resolvePluginTools(
2195+createResolveToolsParams({
2196+toolAllowlist: ["*"],
2197+toolDenylist: ["browser"],
2198+}),
2199+);
2200+2201+expectResolvedToolNames(tools, []);
2202+expect(browserFactory).not.toHaveBeenCalled();
2203+expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
2204+});
2205+21802206it("includes optional tools when wildcard allowlist is active (#76507)", () => {
21812207setOptionalDemoRegistry();
21822208此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。