@@ -183,3 +183,110 @@ test("returns empty array when no skills exist", async () => {
183183 } ,
184184 } )
185185} )
186+
187+ test ( "discovers skills from .agents/skills/ directory" , async ( ) => {
188+ await using tmp = await tmpdir ( {
189+ git : true ,
190+ init : async ( dir ) => {
191+ const skillDir = path . join ( dir , ".agents" , "skills" , "agent-skill" )
192+ await Bun . write (
193+ path . join ( skillDir , "SKILL.md" ) ,
194+ `---
195+ name: agent-skill
196+ description: A skill in the .agents/skills directory.
197+ ---
198+
199+ # Agent Skill
200+ ` ,
201+ )
202+ } ,
203+ } )
204+
205+ await Instance . provide ( {
206+ directory : tmp . path ,
207+ fn : async ( ) => {
208+ const skills = await Skill . all ( )
209+ expect ( skills . length ) . toBe ( 1 )
210+ const agentSkill = skills . find ( ( s ) => s . name === "agent-skill" )
211+ expect ( agentSkill ) . toBeDefined ( )
212+ expect ( agentSkill ! . location ) . toContain ( ".agents/skills/agent-skill/SKILL.md" )
213+ } ,
214+ } )
215+ } )
216+
217+ test ( "discovers global skills from ~/.agents/skills/ directory" , async ( ) => {
218+ await using tmp = await tmpdir ( { git : true } )
219+
220+ const originalHome = process . env . OPENCODE_TEST_HOME
221+ process . env . OPENCODE_TEST_HOME = tmp . path
222+
223+ try {
224+ const skillDir = path . join ( tmp . path , ".agents" , "skills" , "global-agent-skill" )
225+ await fs . mkdir ( skillDir , { recursive : true } )
226+ await Bun . write (
227+ path . join ( skillDir , "SKILL.md" ) ,
228+ `---
229+ name: global-agent-skill
230+ description: A global skill from ~/.agents/skills for testing.
231+ ---
232+
233+ # Global Agent Skill
234+
235+ This skill is loaded from the global home directory.
236+ ` ,
237+ )
238+
239+ await Instance . provide ( {
240+ directory : tmp . path ,
241+ fn : async ( ) => {
242+ const skills = await Skill . all ( )
243+ expect ( skills . length ) . toBe ( 1 )
244+ expect ( skills [ 0 ] . name ) . toBe ( "global-agent-skill" )
245+ expect ( skills [ 0 ] . description ) . toBe ( "A global skill from ~/.agents/skills for testing." )
246+ expect ( skills [ 0 ] . location ) . toContain ( ".agents/skills/global-agent-skill/SKILL.md" )
247+ } ,
248+ } )
249+ } finally {
250+ process . env . OPENCODE_TEST_HOME = originalHome
251+ }
252+ } )
253+
254+ test ( "discovers skills from both .claude/skills/ and .agents/skills/" , async ( ) => {
255+ await using tmp = await tmpdir ( {
256+ git : true ,
257+ init : async ( dir ) => {
258+ const claudeDir = path . join ( dir , ".claude" , "skills" , "claude-skill" )
259+ const agentDir = path . join ( dir , ".agents" , "skills" , "agent-skill" )
260+ await Bun . write (
261+ path . join ( claudeDir , "SKILL.md" ) ,
262+ `---
263+ name: claude-skill
264+ description: A skill in the .claude/skills directory.
265+ ---
266+
267+ # Claude Skill
268+ ` ,
269+ )
270+ await Bun . write (
271+ path . join ( agentDir , "SKILL.md" ) ,
272+ `---
273+ name: agent-skill
274+ description: A skill in the .agents/skills directory.
275+ ---
276+
277+ # Agent Skill
278+ ` ,
279+ )
280+ } ,
281+ } )
282+
283+ await Instance . provide ( {
284+ directory : tmp . path ,
285+ fn : async ( ) => {
286+ const skills = await Skill . all ( )
287+ expect ( skills . length ) . toBe ( 2 )
288+ expect ( skills . find ( ( s ) => s . name === "claude-skill" ) ) . toBeDefined ( )
289+ expect ( skills . find ( ( s ) => s . name === "agent-skill" ) ) . toBeDefined ( )
290+ } ,
291+ } )
292+ } )
0 commit comments