skill.test.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { test, expect } from "bun:test"
  2. import { Skill } from "../../src/skill"
  3. import { SystemPrompt } from "../../src/session/system"
  4. import { Instance } from "../../src/project/instance"
  5. import { tmpdir } from "../fixture/fixture"
  6. import path from "path"
  7. test("discovers skills from .opencode/skill/ directory", async () => {
  8. await using tmp = await tmpdir({
  9. git: true,
  10. init: async (dir) => {
  11. const skillDir = path.join(dir, ".opencode", "skill", "test-skill")
  12. await Bun.write(
  13. path.join(skillDir, "SKILL.md"),
  14. `---
  15. name: test-skill
  16. description: A test skill for verification.
  17. ---
  18. # Test Skill
  19. Instructions here.
  20. `,
  21. )
  22. },
  23. })
  24. await Instance.provide({
  25. directory: tmp.path,
  26. fn: async () => {
  27. const skills = await Skill.all()
  28. expect(skills.length).toBe(1)
  29. expect(skills[0].name).toBe("test-skill")
  30. expect(skills[0].description).toBe("A test skill for verification.")
  31. expect(skills[0].location).toContain("skill/test-skill/SKILL.md")
  32. },
  33. })
  34. })
  35. test("discovers multiple skills from .opencode/skill/ directory", async () => {
  36. await using tmp = await tmpdir({
  37. git: true,
  38. init: async (dir) => {
  39. const skillDir = path.join(dir, ".opencode", "skill", "my-skill")
  40. await Bun.write(
  41. path.join(skillDir, "SKILL.md"),
  42. `---
  43. name: my-skill
  44. description: Another test skill.
  45. ---
  46. # My Skill
  47. `,
  48. )
  49. },
  50. })
  51. await Instance.provide({
  52. directory: tmp.path,
  53. fn: async () => {
  54. const skills = await Skill.all()
  55. expect(skills.length).toBe(1)
  56. expect(skills[0].name).toBe("my-skill")
  57. },
  58. })
  59. })
  60. test("skips skills with missing frontmatter", async () => {
  61. await using tmp = await tmpdir({
  62. git: true,
  63. init: async (dir) => {
  64. const skillDir = path.join(dir, ".opencode", "skill", "no-frontmatter")
  65. await Bun.write(
  66. path.join(skillDir, "SKILL.md"),
  67. `# No Frontmatter
  68. Just some content without YAML frontmatter.
  69. `,
  70. )
  71. },
  72. })
  73. await Instance.provide({
  74. directory: tmp.path,
  75. fn: async () => {
  76. const skills = await Skill.all()
  77. expect(skills).toEqual([])
  78. },
  79. })
  80. })
  81. test("returns empty array when no skills exist", async () => {
  82. await using tmp = await tmpdir({ git: true })
  83. await Instance.provide({
  84. directory: tmp.path,
  85. fn: async () => {
  86. const skills = await Skill.all()
  87. expect(skills).toEqual([])
  88. },
  89. })
  90. })
  91. test("discovers skills from .claude/skills/ directory", async () => {
  92. await using tmp = await tmpdir({
  93. git: true,
  94. init: async (dir) => {
  95. const skillDir = path.join(dir, ".claude", "skills", "claude-skill")
  96. await Bun.write(
  97. path.join(skillDir, "SKILL.md"),
  98. `---
  99. name: claude-skill
  100. description: A skill in the .claude/skills directory.
  101. ---
  102. # Claude Skill
  103. `,
  104. )
  105. },
  106. })
  107. await Instance.provide({
  108. directory: tmp.path,
  109. fn: async () => {
  110. const skills = await Skill.all()
  111. expect(skills.length).toBe(1)
  112. expect(skills[0].name).toBe("claude-skill")
  113. expect(skills[0].location).toContain(".claude/skills/claude-skill/SKILL.md")
  114. },
  115. })
  116. })