2026-01-25 15:02:41 +09:00
|
|
|
import { describe, test, expect } from "bun:test"
|
|
|
|
|
import { createBuiltinSkills } from "./skills"
|
|
|
|
|
|
|
|
|
|
describe("createBuiltinSkills", () => {
|
|
|
|
|
test("returns playwright skill by default", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given - no options (default)
|
2026-01-25 15:02:41 +09:00
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const skills = createBuiltinSkills()
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then
|
2026-01-25 15:02:41 +09:00
|
|
|
const browserSkill = skills.find((s) => s.name === "playwright")
|
|
|
|
|
expect(browserSkill).toBeDefined()
|
|
|
|
|
expect(browserSkill!.description).toContain("browser")
|
|
|
|
|
expect(browserSkill!.mcpConfig).toHaveProperty("playwright")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("returns playwright skill when browserProvider is 'playwright'", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given
|
2026-01-25 15:02:41 +09:00
|
|
|
const options = { browserProvider: "playwright" as const }
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then
|
2026-01-25 15:02:41 +09:00
|
|
|
const playwrightSkill = skills.find((s) => s.name === "playwright")
|
|
|
|
|
const agentBrowserSkill = skills.find((s) => s.name === "agent-browser")
|
|
|
|
|
expect(playwrightSkill).toBeDefined()
|
|
|
|
|
expect(agentBrowserSkill).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("returns agent-browser skill when browserProvider is 'agent-browser'", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given
|
2026-01-25 15:02:41 +09:00
|
|
|
const options = { browserProvider: "agent-browser" as const }
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then
|
2026-01-25 15:02:41 +09:00
|
|
|
const agentBrowserSkill = skills.find((s) => s.name === "agent-browser")
|
|
|
|
|
const playwrightSkill = skills.find((s) => s.name === "playwright")
|
|
|
|
|
expect(agentBrowserSkill).toBeDefined()
|
|
|
|
|
expect(agentBrowserSkill!.description).toContain("browser")
|
|
|
|
|
expect(agentBrowserSkill!.allowedTools).toContain("Bash(agent-browser:*)")
|
|
|
|
|
expect(agentBrowserSkill!.template).toContain("agent-browser")
|
|
|
|
|
expect(playwrightSkill).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("agent-browser skill template is inlined (not loaded from file)", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given
|
2026-01-25 15:02:41 +09:00
|
|
|
const options = { browserProvider: "agent-browser" as const }
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
const agentBrowserSkill = skills.find((s) => s.name === "agent-browser")
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then - template should contain substantial content (inlined, not fallback)
|
2026-01-25 15:02:41 +09:00
|
|
|
expect(agentBrowserSkill!.template).toContain("## Quick start")
|
|
|
|
|
expect(agentBrowserSkill!.template).toContain("## Commands")
|
|
|
|
|
expect(agentBrowserSkill!.template).toContain("agent-browser open")
|
|
|
|
|
expect(agentBrowserSkill!.template).toContain("agent-browser snapshot")
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-31 17:22:34 -07:00
|
|
|
test("always includes frontend-ui-ux, git-master, review-work, and ai-slop-remover skills", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given - both provider options
|
2026-01-25 15:02:41 +09:00
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const defaultSkills = createBuiltinSkills()
|
|
|
|
|
const agentBrowserSkills = createBuiltinSkills({ browserProvider: "agent-browser" })
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then
|
2026-01-25 15:02:41 +09:00
|
|
|
for (const skills of [defaultSkills, agentBrowserSkills]) {
|
|
|
|
|
expect(skills.find((s) => s.name === "frontend-ui-ux")).toBeDefined()
|
|
|
|
|
expect(skills.find((s) => s.name === "git-master")).toBeDefined()
|
2026-03-31 17:22:34 -07:00
|
|
|
expect(skills.find((s) => s.name === "review-work")).toBeDefined()
|
|
|
|
|
expect(skills.find((s) => s.name === "ai-slop-remover")).toBeDefined()
|
2026-01-25 15:02:41 +09:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-31 17:22:34 -07:00
|
|
|
test("returns exactly 6 skills regardless of provider", () => {
|
2026-02-01 16:47:50 +09:00
|
|
|
// given
|
2026-01-25 15:02:41 +09:00
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// when
|
2026-01-25 15:02:41 +09:00
|
|
|
const defaultSkills = createBuiltinSkills()
|
|
|
|
|
const agentBrowserSkills = createBuiltinSkills({ browserProvider: "agent-browser" })
|
|
|
|
|
|
2026-02-01 16:47:50 +09:00
|
|
|
// then
|
2026-03-31 17:22:34 -07:00
|
|
|
expect(defaultSkills).toHaveLength(6)
|
|
|
|
|
expect(agentBrowserSkills).toHaveLength(6)
|
2026-01-25 15:02:41 +09:00
|
|
|
})
|
2026-01-26 14:21:28 +07:00
|
|
|
|
|
|
|
|
test("should exclude playwright when it is in disabledSkills", () => {
|
|
|
|
|
// #given
|
|
|
|
|
const options = { disabledSkills: new Set(["playwright"]) }
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
|
|
|
|
// #then
|
|
|
|
|
expect(skills.map((s) => s.name)).not.toContain("playwright")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("frontend-ui-ux")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("git-master")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("dev-browser")
|
2026-03-31 17:22:34 -07:00
|
|
|
expect(skills.map((s) => s.name)).toContain("review-work")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("ai-slop-remover")
|
|
|
|
|
expect(skills.length).toBe(5)
|
2026-01-26 14:21:28 +07:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("should exclude multiple skills when they are in disabledSkills", () => {
|
|
|
|
|
// #given
|
|
|
|
|
const options = { disabledSkills: new Set(["playwright", "git-master"]) }
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
|
|
|
|
// #then
|
|
|
|
|
expect(skills.map((s) => s.name)).not.toContain("playwright")
|
|
|
|
|
expect(skills.map((s) => s.name)).not.toContain("git-master")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("frontend-ui-ux")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("dev-browser")
|
2026-03-31 17:22:34 -07:00
|
|
|
expect(skills.map((s) => s.name)).toContain("review-work")
|
|
|
|
|
expect(skills.map((s) => s.name)).toContain("ai-slop-remover")
|
|
|
|
|
expect(skills.length).toBe(4)
|
2026-01-26 14:21:28 +07:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("should return an empty array when all skills are disabled", () => {
|
|
|
|
|
// #given
|
|
|
|
|
const options = {
|
2026-03-31 17:22:34 -07:00
|
|
|
disabledSkills: new Set(["playwright", "frontend-ui-ux", "git-master", "dev-browser", "review-work", "ai-slop-remover"]),
|
2026-01-26 14:21:28 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
|
|
|
|
// #then
|
|
|
|
|
expect(skills.length).toBe(0)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("should return all skills when disabledSkills set is empty", () => {
|
|
|
|
|
// #given
|
|
|
|
|
const options = { disabledSkills: new Set<string>() }
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
|
|
|
|
// #then
|
2026-03-31 17:22:34 -07:00
|
|
|
expect(skills.length).toBe(6)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("review-work skill has correct structure", () => {
|
|
|
|
|
// #given - default options
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills()
|
|
|
|
|
const reviewWork = skills.find((s) => s.name === "review-work")
|
|
|
|
|
|
|
|
|
|
// #then
|
|
|
|
|
expect(reviewWork).toBeDefined()
|
|
|
|
|
expect(reviewWork!.description).toContain("review")
|
|
|
|
|
expect(reviewWork!.template).toContain("5-Agent Parallel Review Orchestrator")
|
|
|
|
|
expect(reviewWork!.template).toContain("Goal & Constraint Verification")
|
|
|
|
|
expect(reviewWork!.template).toContain("QA")
|
|
|
|
|
expect(reviewWork!.template).toContain("Code Quality")
|
|
|
|
|
expect(reviewWork!.template).toContain("Security")
|
|
|
|
|
expect(reviewWork!.template).toContain("Context Mining")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("ai-slop-remover skill has correct structure", () => {
|
|
|
|
|
// #given - default options
|
|
|
|
|
|
|
|
|
|
// #when
|
|
|
|
|
const skills = createBuiltinSkills()
|
|
|
|
|
const aiSlopRemover = skills.find((s) => s.name === "ai-slop-remover")
|
|
|
|
|
|
|
|
|
|
// #then
|
|
|
|
|
expect(aiSlopRemover).toBeDefined()
|
|
|
|
|
expect(aiSlopRemover!.description).toContain("AI-generated code smells")
|
|
|
|
|
expect(aiSlopRemover!.template).toContain("DETECTION CRITERIA")
|
|
|
|
|
expect(aiSlopRemover!.template).toContain("SAFETY RULES")
|
2026-01-26 14:21:28 +07:00
|
|
|
})
|
2026-02-13 11:15:38 +01:00
|
|
|
|
|
|
|
|
test("returns playwright-cli skill when browserProvider is 'playwright-cli'", () => {
|
|
|
|
|
// given
|
|
|
|
|
const options = { browserProvider: "playwright-cli" as const }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
const playwrightSkill = skills.find((s) => s.name === "playwright")
|
|
|
|
|
const agentBrowserSkill = skills.find((s) => s.name === "agent-browser")
|
|
|
|
|
expect(playwrightSkill).toBeDefined()
|
|
|
|
|
expect(playwrightSkill!.description).toContain("browser")
|
|
|
|
|
expect(playwrightSkill!.allowedTools).toContain("Bash(playwright-cli:*)")
|
|
|
|
|
expect(playwrightSkill!.mcpConfig).toBeUndefined()
|
|
|
|
|
expect(agentBrowserSkill).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("playwright-cli skill template contains CLI commands", () => {
|
|
|
|
|
// given
|
|
|
|
|
const options = { browserProvider: "playwright-cli" as const }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const skills = createBuiltinSkills(options)
|
|
|
|
|
const skill = skills.find((s) => s.name === "playwright")
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(skill!.template).toContain("playwright-cli open")
|
|
|
|
|
expect(skill!.template).toContain("playwright-cli snapshot")
|
|
|
|
|
expect(skill!.template).toContain("playwright-cli click")
|
|
|
|
|
})
|
2026-01-25 15:02:41 +09:00
|
|
|
})
|