@@ -426,3 +426,101 @@ func TestFindEval_WithCustomEvalsDir(t *testing.T) {
426426 t .Errorf ("expected %q, got %q" , expected , evalPath )
427427 }
428428}
429+
430+ func TestDetectContext_GitHubSkillsDir (t * testing.T ) {
431+ // Skills in .github/skills/ are auto-discovered
432+ root := t .TempDir ()
433+ writeFile (t , filepath .Join (root , ".github" , "skills" , "github-skill" , "SKILL.md" ), skillMD ("github-skill" ))
434+
435+ ctx , err := DetectContext (root )
436+ if err != nil {
437+ t .Fatalf ("unexpected error: %v" , err )
438+ }
439+ if ctx .Type != ContextMultiSkill {
440+ t .Fatalf ("expected ContextMultiSkill, got %d" , ctx .Type )
441+ }
442+ if len (ctx .Skills ) != 1 {
443+ t .Fatalf ("expected 1 skill, got %d" , len (ctx .Skills ))
444+ }
445+ if ctx .Skills [0 ].Name != "github-skill" {
446+ t .Errorf ("expected 'github-skill', got %q" , ctx .Skills [0 ].Name )
447+ }
448+ }
449+
450+ func TestDetectContext_BothSkillsDirs (t * testing.T ) {
451+ // Skills in both skills/ and .github/skills/ are merged
452+ root := t .TempDir ()
453+ writeFile (t , filepath .Join (root , "skills" , "regular-skill" , "SKILL.md" ), skillMD ("regular-skill" ))
454+ writeFile (t , filepath .Join (root , ".github" , "skills" , "github-skill" , "SKILL.md" ), skillMD ("github-skill" ))
455+
456+ ctx , err := DetectContext (root )
457+ if err != nil {
458+ t .Fatalf ("unexpected error: %v" , err )
459+ }
460+ if ctx .Type != ContextMultiSkill {
461+ t .Fatalf ("expected ContextMultiSkill, got %d" , ctx .Type )
462+ }
463+ if len (ctx .Skills ) != 2 {
464+ t .Fatalf ("expected 2 skills, got %d" , len (ctx .Skills ))
465+ }
466+
467+ names := map [string ]bool {}
468+ for _ , s := range ctx .Skills {
469+ names [s .Name ] = true
470+ }
471+ if ! names ["regular-skill" ] || ! names ["github-skill" ] {
472+ t .Errorf ("expected skills regular-skill and github-skill, got %v" , names )
473+ }
474+ }
475+
476+ func TestDetectContext_GitHubSkillsDirDedup (t * testing.T ) {
477+ // Same skill name in both dirs: configured skills/ wins
478+ root := t .TempDir ()
479+ writeFile (t , filepath .Join (root , "skills" , "shared-name" , "SKILL.md" ), skillMD ("shared-name" ))
480+ writeFile (t , filepath .Join (root , ".github" , "skills" , "shared-name" , "SKILL.md" ), skillMD ("shared-name" ))
481+
482+ ctx , err := DetectContext (root )
483+ if err != nil {
484+ t .Fatalf ("unexpected error: %v" , err )
485+ }
486+ if ctx .Type != ContextMultiSkill {
487+ t .Fatalf ("expected ContextMultiSkill, got %d" , ctx .Type )
488+ }
489+ if len (ctx .Skills ) != 1 {
490+ t .Fatalf ("expected 1 skill (deduped), got %d" , len (ctx .Skills ))
491+ }
492+ if ctx .Skills [0 ].Name != "shared-name" {
493+ t .Errorf ("expected 'shared-name', got %q" , ctx .Skills [0 ].Name )
494+ }
495+ // Verify that skills/ directory won (not .github/skills/)
496+ expectedDir := filepath .Join (root , "skills" , "shared-name" )
497+ if ctx .Skills [0 ].Dir != expectedDir {
498+ t .Errorf ("expected dir %q (configured should win), got %q" , expectedDir , ctx .Skills [0 ].Dir )
499+ }
500+ }
501+
502+ func TestDetectContext_GitHubSkillsDirWithCustomOverride (t * testing.T ) {
503+ // Custom paths.skills + .github/skills/ both work
504+ root := t .TempDir ()
505+ writeFile (t , filepath .Join (root , "my-skills" , "custom-skill" , "SKILL.md" ), skillMD ("custom-skill" ))
506+ writeFile (t , filepath .Join (root , ".github" , "skills" , "github-skill" , "SKILL.md" ), skillMD ("github-skill" ))
507+
508+ ctx , err := DetectContext (root , WithSkillsDir ("my-skills" ))
509+ if err != nil {
510+ t .Fatalf ("unexpected error: %v" , err )
511+ }
512+ if ctx .Type != ContextMultiSkill {
513+ t .Fatalf ("expected ContextMultiSkill, got %d" , ctx .Type )
514+ }
515+ if len (ctx .Skills ) != 2 {
516+ t .Fatalf ("expected 2 skills, got %d" , len (ctx .Skills ))
517+ }
518+
519+ names := map [string ]bool {}
520+ for _ , s := range ctx .Skills {
521+ names [s .Name ] = true
522+ }
523+ if ! names ["custom-skill" ] || ! names ["github-skill" ] {
524+ t .Errorf ("expected skills custom-skill and github-skill, got %v" , names )
525+ }
526+ }
0 commit comments