Merge pull request #1370 from misyuari/fix/refactor-skills
fix: update skill resolution to support disabled skills functionality
This commit is contained in:
@@ -33,10 +33,12 @@ describe("resolveSkillContent", () => {
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it("should return null for empty string", () => {
|
||||
// given: builtin skills
|
||||
// when: resolving content for empty string
|
||||
const result = resolveSkillContent("")
|
||||
it("should return null for disabled skill", () => {
|
||||
// given: frontend-ui-ux skill disabled
|
||||
const options = { disabledSkills: new Set(["frontend-ui-ux"]) }
|
||||
|
||||
// when: resolving content for disabled skill
|
||||
const result = resolveSkillContent("frontend-ui-ux", options)
|
||||
|
||||
// then: returns null
|
||||
expect(result).toBeNull()
|
||||
@@ -96,6 +98,20 @@ describe("resolveMultipleSkills", () => {
|
||||
expect(result.notFound).toEqual(["skill-one", "skill-two", "skill-three"])
|
||||
})
|
||||
|
||||
it("should treat disabled skills as not found", () => {
|
||||
// #given: frontend-ui-ux disabled, playwright not disabled
|
||||
const skillNames = ["frontend-ui-ux", "playwright"]
|
||||
const options = { disabledSkills: new Set(["frontend-ui-ux"]) }
|
||||
|
||||
// #when: resolving multiple skills with disabled one
|
||||
const result = resolveMultipleSkills(skillNames, options)
|
||||
|
||||
// #then: frontend-ui-ux in notFound, playwright resolved
|
||||
expect(result.resolved.size).toBe(1)
|
||||
expect(result.resolved.has("playwright")).toBe(true)
|
||||
expect(result.notFound).toEqual(["frontend-ui-ux"])
|
||||
})
|
||||
|
||||
it("should preserve skill order in resolved map", () => {
|
||||
// given: list of skill names in specific order
|
||||
const skillNames = ["playwright", "frontend-ui-ux"]
|
||||
@@ -111,21 +127,24 @@ describe("resolveMultipleSkills", () => {
|
||||
})
|
||||
|
||||
describe("resolveSkillContentAsync", () => {
|
||||
it("should return template for builtin skill", async () => {
|
||||
it("should return template for builtin skill async", async () => {
|
||||
// given: builtin skill 'frontend-ui-ux'
|
||||
// when: resolving content async
|
||||
const result = await resolveSkillContentAsync("frontend-ui-ux")
|
||||
const options = { disabledSkills: new Set(["frontend-ui-ux"]) }
|
||||
const result = await resolveSkillContentAsync("git-master", options)
|
||||
|
||||
// then: returns template string
|
||||
expect(result).not.toBeNull()
|
||||
expect(typeof result).toBe("string")
|
||||
expect(result).toContain("Role: Designer-Turned-Developer")
|
||||
expect(result).toContain("Git Master Agent")
|
||||
})
|
||||
|
||||
it("should return null for non-existent skill", async () => {
|
||||
// given: non-existent skill name
|
||||
// when: resolving content async
|
||||
const result = await resolveSkillContentAsync("definitely-not-a-skill-12345")
|
||||
it("should return null for disabled skill async", async () => {
|
||||
// given: frontend-ui-ux disabled
|
||||
const options = { disabledSkills: new Set(["frontend-ui-ux"]) }
|
||||
|
||||
// when: resolving content async for disabled skill
|
||||
const result = await resolveSkillContentAsync("frontend-ui-ux", options)
|
||||
|
||||
// then: returns null
|
||||
expect(result).toBeNull()
|
||||
@@ -133,9 +152,9 @@ describe("resolveSkillContentAsync", () => {
|
||||
})
|
||||
|
||||
describe("resolveMultipleSkillsAsync", () => {
|
||||
it("should resolve builtin skills", async () => {
|
||||
it("should resolve builtin skills async", async () => {
|
||||
// given: builtin skill names
|
||||
const skillNames = ["playwright", "frontend-ui-ux"]
|
||||
const skillNames = ["playwright", "git-master"]
|
||||
|
||||
// when: resolving multiple skills async
|
||||
const result = await resolveMultipleSkillsAsync(skillNames)
|
||||
@@ -144,10 +163,10 @@ describe("resolveMultipleSkillsAsync", () => {
|
||||
expect(result.resolved.size).toBe(2)
|
||||
expect(result.notFound).toEqual([])
|
||||
expect(result.resolved.get("playwright")).toContain("Playwright Browser Automation")
|
||||
expect(result.resolved.get("frontend-ui-ux")).toContain("Designer-Turned-Developer")
|
||||
expect(result.resolved.get("git-master")).toContain("Git Master Agent")
|
||||
})
|
||||
|
||||
it("should handle partial success with non-existent skills", async () => {
|
||||
it("should handle partial success with non-existent skills async", async () => {
|
||||
// given: mix of existing and non-existing skills
|
||||
const skillNames = ["playwright", "nonexistent-skill-12345"]
|
||||
|
||||
@@ -160,6 +179,20 @@ describe("resolveMultipleSkillsAsync", () => {
|
||||
expect(result.resolved.get("playwright")).toContain("Playwright Browser Automation")
|
||||
})
|
||||
|
||||
it("should treat disabled skills as not found async", async () => {
|
||||
// #given: frontend-ui-ux disabled
|
||||
const skillNames = ["frontend-ui-ux", "playwright"]
|
||||
const options = { disabledSkills: new Set(["frontend-ui-ux"]) }
|
||||
|
||||
// #when: resolving multiple skills async with disabled one
|
||||
const result = await resolveMultipleSkillsAsync(skillNames, options)
|
||||
|
||||
// #then: frontend-ui-ux in notFound, playwright resolved
|
||||
expect(result.resolved.size).toBe(1)
|
||||
expect(result.resolved.has("playwright")).toBe(true)
|
||||
expect(result.notFound).toEqual(["frontend-ui-ux"])
|
||||
})
|
||||
|
||||
it("should NOT inject watermark when both options are disabled", async () => {
|
||||
// given: git-master skill with watermark disabled
|
||||
const skillNames = ["git-master"]
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { GitMasterConfig, BrowserAutomationProvider } from "../../config/sc
|
||||
export interface SkillResolutionOptions {
|
||||
gitMasterConfig?: GitMasterConfig
|
||||
browserProvider?: BrowserAutomationProvider
|
||||
disabledSkills?: Set<string>
|
||||
}
|
||||
|
||||
const cachedSkillsByProvider = new Map<string, LoadedSkill[]>()
|
||||
@@ -23,7 +24,12 @@ async function getAllSkills(options?: SkillResolutionOptions): Promise<LoadedSki
|
||||
|
||||
const [discoveredSkills, builtinSkillDefs] = await Promise.all([
|
||||
discoverSkills({ includeClaudeCodePaths: true }),
|
||||
Promise.resolve(createBuiltinSkills({ browserProvider: options?.browserProvider })),
|
||||
Promise.resolve(
|
||||
createBuiltinSkills({
|
||||
browserProvider: options?.browserProvider,
|
||||
disabledSkills: options?.disabledSkills,
|
||||
})
|
||||
),
|
||||
])
|
||||
|
||||
const builtinSkillsAsLoaded: LoadedSkill[] = builtinSkillDefs.map((skill) => ({
|
||||
@@ -122,7 +128,10 @@ export function injectGitMasterConfig(template: string, config?: GitMasterConfig
|
||||
}
|
||||
|
||||
export function resolveSkillContent(skillName: string, options?: SkillResolutionOptions): string | null {
|
||||
const skills = createBuiltinSkills({ browserProvider: options?.browserProvider })
|
||||
const skills = createBuiltinSkills({
|
||||
browserProvider: options?.browserProvider,
|
||||
disabledSkills: options?.disabledSkills,
|
||||
})
|
||||
const skill = skills.find((s) => s.name === skillName)
|
||||
if (!skill) return null
|
||||
|
||||
@@ -137,7 +146,10 @@ export function resolveMultipleSkills(skillNames: string[], options?: SkillResol
|
||||
resolved: Map<string, string>
|
||||
notFound: string[]
|
||||
} {
|
||||
const skills = createBuiltinSkills({ browserProvider: options?.browserProvider })
|
||||
const skills = createBuiltinSkills({
|
||||
browserProvider: options?.browserProvider,
|
||||
disabledSkills: options?.disabledSkills,
|
||||
})
|
||||
const skillMap = new Map(skills.map((s) => [s.name, s.template]))
|
||||
|
||||
const resolved = new Map<string, string>()
|
||||
|
||||
Reference in New Issue
Block a user