From 747edcb6e6d39c5df6ae6a022714eb363efbd69d Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 7 Feb 2026 20:01:15 +0900 Subject: [PATCH] fix(skill-loader): filter discovered skills by browserProvider (#1563) --- .../skill-content.test.ts | 30 +++++++++++++++++++ .../opencode-skill-loader/skill-content.ts | 17 +++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/features/opencode-skill-loader/skill-content.test.ts b/src/features/opencode-skill-loader/skill-content.test.ts index 4ea846712..16f80105e 100644 --- a/src/features/opencode-skill-loader/skill-content.test.ts +++ b/src/features/opencode-skill-loader/skill-content.test.ts @@ -389,3 +389,33 @@ describe("resolveMultipleSkills with browserProvider", () => { expect(result.notFound).toContain("agent-browser") }) }) + +describe("resolveMultipleSkillsAsync with browserProvider filtering", () => { + it("should exclude discovered agent-browser when browserProvider is playwright", async () => { + // given: playwright is the selected browserProvider (default) + const skillNames = ["playwright", "git-master"] + const options = { browserProvider: "playwright" as const } + + // when: resolving multiple skills + const result = await resolveMultipleSkillsAsync(skillNames, options) + + // then: playwright resolved, agent-browser would be excluded if discovered + expect(result.resolved.has("playwright")).toBe(true) + expect(result.resolved.has("git-master")).toBe(true) + expect(result.notFound).not.toContain("playwright") + }) + + it("should exclude discovered playwright when browserProvider is agent-browser", async () => { + // given: agent-browser is the selected browserProvider + const skillNames = ["agent-browser", "git-master"] + const options = { browserProvider: "agent-browser" as const } + + // when: resolving multiple skills + const result = await resolveMultipleSkillsAsync(skillNames, options) + + // then: agent-browser resolved, playwright would be excluded if discovered + expect(result.resolved.has("agent-browser")).toBe(true) + expect(result.resolved.has("git-master")).toBe(true) + expect(result.notFound).not.toContain("agent-browser") + }) +}) diff --git a/src/features/opencode-skill-loader/skill-content.ts b/src/features/opencode-skill-loader/skill-content.ts index 3b3596290..1810aa628 100644 --- a/src/features/opencode-skill-loader/skill-content.ts +++ b/src/features/opencode-skill-loader/skill-content.ts @@ -55,10 +55,23 @@ async function getAllSkills(options?: SkillResolutionOptions): Promise s.name)) + // Provider-gated skill names that should be filtered based on browserProvider + const providerGatedSkillNames = new Set(["agent-browser", "playwright"]) + const browserProvider = options?.browserProvider ?? "playwright" + + // Filter discovered skills to exclude provider-gated names that don't match the selected provider + const filteredDiscoveredSkills = discoveredSkills.filter((skill) => { + if (!providerGatedSkillNames.has(skill.name)) { + return true + } + // For provider-gated skills, only include if it matches the selected provider + return skill.name === browserProvider + }) + + const discoveredNames = new Set(filteredDiscoveredSkills.map((s) => s.name)) const uniqueBuiltins = builtinSkillsAsLoaded.filter((s) => !discoveredNames.has(s.name)) - let allSkills = [...discoveredSkills, ...uniqueBuiltins] + let allSkills = [...filteredDiscoveredSkills, ...uniqueBuiltins] // Filter discovered skills by disabledSkills (builtin skills are already filtered by createBuiltinSkills) if (hasDisabledSkills) {