@@ -219,3 +219,110 @@ test("returns empty array when no skills exist", async () => {
219219 } ,
220220 } )
221221} )
222+
223+ test ( "discovers skills from .agents/skills/ directory" , async ( ) => {
224+ await using tmp = await tmpdir ( {
225+ git : true ,
226+ init : async ( dir ) => {
227+ const skillDir = path . join ( dir , ".agents" , "skills" , "agent-skill" )
228+ await Bun . write (
229+ path . join ( skillDir , "SKILL.md" ) ,
230+ `---
231+ name: agent-skill
232+ description: A skill in the .agents/skills directory.
233+ ---
234+
235+ # Agent Skill
236+ ` ,
237+ )
238+ } ,
239+ } )
240+
241+ await Instance . provide ( {
242+ directory : tmp . path ,
243+ fn : async ( ) => {
244+ const skills = await Skill . all ( )
245+ expect ( skills . length ) . toBe ( 1 )
246+ const agentSkill = skills . find ( ( s ) => s . name === "agent-skill" )
247+ expect ( agentSkill ) . toBeDefined ( )
248+ expect ( agentSkill ! . location ) . toContain ( ".agents/skills/agent-skill/SKILL.md" )
249+ } ,
250+ } )
251+ } )
252+
253+ test ( "discovers global skills from ~/.agents/skills/ directory" , async ( ) => {
254+ await using tmp = await tmpdir ( { git : true } )
255+
256+ const originalHome = process . env . OPENCODE_TEST_HOME
257+ process . env . OPENCODE_TEST_HOME = tmp . path
258+
259+ try {
260+ const skillDir = path . join ( tmp . path , ".agents" , "skills" , "global-agent-skill" )
261+ await fs . mkdir ( skillDir , { recursive : true } )
262+ await Bun . write (
263+ path . join ( skillDir , "SKILL.md" ) ,
264+ `---
265+ name: global-agent-skill
266+ description: A global skill from ~/.agents/skills for testing.
267+ ---
268+
269+ # Global Agent Skill
270+
271+ This skill is loaded from the global home directory.
272+ ` ,
273+ )
274+
275+ await Instance . provide ( {
276+ directory : tmp . path ,
277+ fn : async ( ) => {
278+ const skills = await Skill . all ( )
279+ expect ( skills . length ) . toBe ( 1 )
280+ expect ( skills [ 0 ] . name ) . toBe ( "global-agent-skill" )
281+ expect ( skills [ 0 ] . description ) . toBe ( "A global skill from ~/.agents/skills for testing." )
282+ expect ( skills [ 0 ] . location ) . toContain ( ".agents/skills/global-agent-skill/SKILL.md" )
283+ } ,
284+ } )
285+ } finally {
286+ process . env . OPENCODE_TEST_HOME = originalHome
287+ }
288+ } )
289+
290+ test ( "discovers skills from both .claude/skills/ and .agents/skills/" , async ( ) => {
291+ await using tmp = await tmpdir ( {
292+ git : true ,
293+ init : async ( dir ) => {
294+ const claudeDir = path . join ( dir , ".claude" , "skills" , "claude-skill" )
295+ const agentDir = path . join ( dir , ".agents" , "skills" , "agent-skill" )
296+ await Bun . write (
297+ path . join ( claudeDir , "SKILL.md" ) ,
298+ `---
299+ name: claude-skill
300+ description: A skill in the .claude/skills directory.
301+ ---
302+
303+ # Claude Skill
304+ ` ,
305+ )
306+ await Bun . write (
307+ path . join ( agentDir , "SKILL.md" ) ,
308+ `---
309+ name: agent-skill
310+ description: A skill in the .agents/skills directory.
311+ ---
312+
313+ # Agent Skill
314+ ` ,
315+ )
316+ } ,
317+ } )
318+
319+ await Instance . provide ( {
320+ directory : tmp . path ,
321+ fn : async ( ) => {
322+ const skills = await Skill . all ( )
323+ expect ( skills . length ) . toBe ( 2 )
324+ expect ( skills . find ( ( s ) => s . name === "claude-skill" ) ) . toBeDefined ( )
325+ expect ( skills . find ( ( s ) => s . name === "agent-skill" ) ) . toBeDefined ( )
326+ } ,
327+ } )
328+ } )
0 commit comments