From 666220564681d637bcdf99cf6a77825a7d80891b Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 27 Mar 2026 17:58:38 +0900 Subject: [PATCH] fix(#2748): pass browserProvider into skill() discovery skill-context already filtered browser-related skills using the configured browser provider, but the skill tool rebuilt discovery without forwarding browserProvider. That caused skills like agent-browser to be prompt-visible while skill() could still fail to resolve them unless browser_automation_engine.provider was explicitly threaded through both paths. Fix: - pass skillContext.browserProvider from tool-registry into createSkillTool - extend SkillLoadOptions with browserProvider - forward browserProvider to getAllSkills() - add regression tests for execution and description visibility --- src/plugin/tool-registry.ts | 1 + src/tools/skill/tools.test.ts | 32 ++++++++++++++++++++++++++++++++ src/tools/skill/tools.ts | 2 +- src/tools/skill/types.ts | 4 +++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/plugin/tool-registry.ts b/src/plugin/tool-registry.ts index 6775802b0..f13546977 100644 --- a/src/plugin/tool-registry.ts +++ b/src/plugin/tool-registry.ts @@ -113,6 +113,7 @@ export function createToolRegistry(args: { mcpManager: managers.skillMcpManager, getSessionID: getSessionIDForMcp, gitMasterConfig: pluginConfig.git_master, + browserProvider: skillContext.browserProvider, nativeSkills: "skills" in ctx ? (ctx as { skills: SkillLoadOptions["nativeSkills"] }).skills : undefined, }) diff --git a/src/tools/skill/tools.test.ts b/src/tools/skill/tools.test.ts index 1c91610fe..281e073d0 100644 --- a/src/tools/skill/tools.test.ts +++ b/src/tools/skill/tools.test.ts @@ -583,6 +583,38 @@ describe("skill tool - dynamic description cache invalidation", () => { +describe("skill tool - browserProvider forwarding", () => { + it("passes browserProvider to getAllSkills during execution", async () => { + // given: a skill tool configured with agent-browser as browserProvider + // and a pre-provided agent-browser skill (simulating what skill-context provides) + const agentBrowserSkill = createMockSkill("agent-browser") + const tool = createSkillTool({ + skills: [agentBrowserSkill], + browserProvider: "agent-browser", + }) + + // when: executing skill("agent-browser") + const result = await tool.execute({ name: "agent-browser" }, mockContext) + + // then: skill should resolve successfully (not filtered out) + expect(result).toContain("Skill: agent-browser") + }) + + it("description includes agent-browser when browserProvider is agent-browser", () => { + // given + const agentBrowserSkill = createMockSkill("agent-browser") + + // when + const tool = createSkillTool({ + skills: [agentBrowserSkill], + browserProvider: "agent-browser", + }) + + // then + expect(tool.description).toContain("agent-browser") + }) +}) + describe("skill tool - nativeSkills integration", () => { it("merges native skills exposed by PluginInput.skills.all()", async () => { //#given diff --git a/src/tools/skill/tools.ts b/src/tools/skill/tools.ts index 1d8bebe53..19d146c8d 100644 --- a/src/tools/skill/tools.ts +++ b/src/tools/skill/tools.ts @@ -189,7 +189,7 @@ export function createSkillTool(options: SkillLoadOptions = {}): ToolDefinition const getSkills = async (): Promise => { clearSkillCache() - const discovered = await getAllSkills({disabledSkills: options?.disabledSkills}) + const discovered = await getAllSkills({disabledSkills: options?.disabledSkills, browserProvider: options?.browserProvider}) const allSkills = !options.skills ? discovered : [...discovered, ...options.skills.filter(s => !new Set(discovered.map(d => d.name)).has(s.name))] diff --git a/src/tools/skill/types.ts b/src/tools/skill/types.ts index ce54d8238..d5922e95d 100644 --- a/src/tools/skill/types.ts +++ b/src/tools/skill/types.ts @@ -1,6 +1,6 @@ import type { SkillScope, LoadedSkill } from "../../features/opencode-skill-loader/types" import type { SkillMcpManager } from "../../features/skill-mcp-manager" -import type { GitMasterConfig } from "../../config/schema" +import type { BrowserAutomationProvider, GitMasterConfig } from "../../config/schema" import type { CommandInfo } from "../slashcommand/types" export interface SkillArgs { @@ -33,6 +33,8 @@ export interface SkillLoadOptions { /** Git master configuration for watermark/co-author settings */ gitMasterConfig?: GitMasterConfig disabledSkills?: Set + /** Browser automation provider for provider-gated skill filtering */ + browserProvider?: BrowserAutomationProvider /** Include Claude marketplace plugin commands in discovery (default: true) */ pluginsEnabled?: boolean /** Override plugin enablement from Claude settings by plugin key */