builtin.test.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import { describe, expect, test } from "bun:test"
  2. import {
  3. getBuiltinSkills,
  4. getSkillByName,
  5. getSkillsForAgent,
  6. canAgentUseSkill,
  7. DEFAULT_AGENT_SKILLS,
  8. } from "./builtin"
  9. import type { PluginConfig } from "../../config/schema"
  10. describe("getBuiltinSkills", () => {
  11. test("returns all builtin skills", () => {
  12. const skills = getBuiltinSkills()
  13. expect(skills.length).toBeGreaterThan(0)
  14. const names = skills.map(s => s.name)
  15. expect(names).toContain("yagni-enforcement")
  16. expect(names).toContain("playwright")
  17. })
  18. })
  19. describe("getSkillByName", () => {
  20. test("returns skill by exact name", () => {
  21. const skill = getSkillByName("yagni-enforcement")
  22. expect(skill).toBeDefined()
  23. expect(skill?.name).toBe("yagni-enforcement")
  24. })
  25. test("returns undefined for unknown skill", () => {
  26. const skill = getSkillByName("nonexistent-skill")
  27. expect(skill).toBeUndefined()
  28. })
  29. test("returns playwright skill with mcpConfig", () => {
  30. const skill = getSkillByName("playwright")
  31. expect(skill).toBeDefined()
  32. expect(skill?.mcpConfig).toBeDefined()
  33. expect(skill?.mcpConfig?.playwright).toBeDefined()
  34. })
  35. })
  36. describe("DEFAULT_AGENT_SKILLS", () => {
  37. test("orchestrator has wildcard access", () => {
  38. expect(DEFAULT_AGENT_SKILLS.orchestrator).toContain("*")
  39. })
  40. test("designer has playwright skill", () => {
  41. expect(DEFAULT_AGENT_SKILLS.designer).toContain("playwright")
  42. })
  43. test("oracle has no skills by default", () => {
  44. expect(DEFAULT_AGENT_SKILLS.oracle).toEqual([])
  45. })
  46. test("librarian has no skills by default", () => {
  47. expect(DEFAULT_AGENT_SKILLS.librarian).toEqual([])
  48. })
  49. test("explorer has no skills by default", () => {
  50. expect(DEFAULT_AGENT_SKILLS.explorer).toEqual([])
  51. })
  52. test("fixer has no skills by default", () => {
  53. expect(DEFAULT_AGENT_SKILLS.fixer).toEqual([])
  54. })
  55. })
  56. describe("getSkillsForAgent", () => {
  57. test("returns all skills for orchestrator (wildcard)", () => {
  58. const skills = getSkillsForAgent("orchestrator")
  59. const allSkills = getBuiltinSkills()
  60. expect(skills.length).toBe(allSkills.length)
  61. })
  62. test("returns playwright for designer", () => {
  63. const skills = getSkillsForAgent("designer")
  64. const names = skills.map(s => s.name)
  65. expect(names).toContain("playwright")
  66. })
  67. test("returns empty for oracle", () => {
  68. const skills = getSkillsForAgent("oracle")
  69. expect(skills).toEqual([])
  70. })
  71. test("respects config override for agent skills", () => {
  72. const config: PluginConfig = {
  73. agents: {
  74. oracle: { skills: ["yagni-enforcement"] },
  75. },
  76. }
  77. const skills = getSkillsForAgent("oracle", config)
  78. expect(skills.length).toBe(1)
  79. expect(skills[0].name).toBe("yagni-enforcement")
  80. })
  81. test("config wildcard overrides default", () => {
  82. const config: PluginConfig = {
  83. agents: {
  84. explorer: { skills: ["*"] },
  85. },
  86. }
  87. const skills = getSkillsForAgent("explorer", config)
  88. const allSkills = getBuiltinSkills()
  89. expect(skills.length).toBe(allSkills.length)
  90. })
  91. test("config empty array removes default skills", () => {
  92. const config: PluginConfig = {
  93. agents: {
  94. designer: { skills: [] },
  95. },
  96. }
  97. const skills = getSkillsForAgent("designer", config)
  98. expect(skills).toEqual([])
  99. })
  100. test("backward compat: 'explore' alias config applies to explorer", () => {
  101. const config: PluginConfig = {
  102. agents: {
  103. explore: { skills: ["playwright"] },
  104. },
  105. }
  106. const skills = getSkillsForAgent("explorer", config)
  107. expect(skills.length).toBe(1)
  108. expect(skills[0].name).toBe("playwright")
  109. })
  110. test("backward compat: 'frontend-ui-ux-engineer' alias applies to designer", () => {
  111. const config: PluginConfig = {
  112. agents: {
  113. "frontend-ui-ux-engineer": { skills: ["yagni-enforcement"] },
  114. },
  115. }
  116. const skills = getSkillsForAgent("designer", config)
  117. expect(skills.length).toBe(1)
  118. expect(skills[0].name).toBe("yagni-enforcement")
  119. })
  120. test("returns empty for unknown agent without config", () => {
  121. const skills = getSkillsForAgent("unknown-agent")
  122. expect(skills).toEqual([])
  123. })
  124. })
  125. describe("canAgentUseSkill", () => {
  126. test("orchestrator can use any skill (wildcard)", () => {
  127. expect(canAgentUseSkill("orchestrator", "yagni-enforcement")).toBe(true)
  128. expect(canAgentUseSkill("orchestrator", "playwright")).toBe(true)
  129. expect(canAgentUseSkill("orchestrator", "any-skill")).toBe(true)
  130. })
  131. test("designer can use playwright", () => {
  132. expect(canAgentUseSkill("designer", "playwright")).toBe(true)
  133. })
  134. test("designer cannot use yagni-enforcement by default", () => {
  135. expect(canAgentUseSkill("designer", "yagni-enforcement")).toBe(false)
  136. })
  137. test("oracle cannot use any skill by default", () => {
  138. expect(canAgentUseSkill("oracle", "yagni-enforcement")).toBe(false)
  139. expect(canAgentUseSkill("oracle", "playwright")).toBe(false)
  140. })
  141. test("respects config override", () => {
  142. const config: PluginConfig = {
  143. agents: {
  144. oracle: { skills: ["yagni-enforcement"] },
  145. },
  146. }
  147. expect(canAgentUseSkill("oracle", "yagni-enforcement", config)).toBe(true)
  148. expect(canAgentUseSkill("oracle", "playwright", config)).toBe(false)
  149. })
  150. test("config wildcard grants all permissions", () => {
  151. const config: PluginConfig = {
  152. agents: {
  153. librarian: { skills: ["*"] },
  154. },
  155. }
  156. expect(canAgentUseSkill("librarian", "yagni-enforcement", config)).toBe(true)
  157. expect(canAgentUseSkill("librarian", "playwright", config)).toBe(true)
  158. expect(canAgentUseSkill("librarian", "any-other-skill", config)).toBe(true)
  159. })
  160. test("config empty array denies all", () => {
  161. const config: PluginConfig = {
  162. agents: {
  163. designer: { skills: [] },
  164. },
  165. }
  166. expect(canAgentUseSkill("designer", "playwright", config)).toBe(false)
  167. })
  168. test("backward compat: alias config affects agent permissions", () => {
  169. const config: PluginConfig = {
  170. agents: {
  171. explore: { skills: ["playwright"] },
  172. },
  173. }
  174. expect(canAgentUseSkill("explorer", "playwright", config)).toBe(true)
  175. expect(canAgentUseSkill("explorer", "yagni-enforcement", config)).toBe(false)
  176. })
  177. test("unknown agent returns false without config", () => {
  178. expect(canAgentUseSkill("unknown-agent", "playwright")).toBe(false)
  179. })
  180. })