-
Notifications
You must be signed in to change notification settings - Fork 1
Add skills directory support for all agents #192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2377,6 +2377,272 @@ description: A Cursor IDE skill | |
| } | ||
| }, | ||
| }, | ||
| { | ||
| name: "discover skills from .opencode/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .opencode/skills directory | ||
| skillDir := filepath.Join(dir, ".opencode", "skills", "opencode-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: opencode-skill | ||
| description: A skill for OpenCode | ||
| --- | ||
|
|
||
| # OpenCode Skill | ||
|
|
||
| This is a skill for OpenCode. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "opencode-skill" { | ||
| t.Errorf("expected skill name 'opencode-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2408
to
+2416
|
||
| }, | ||
| { | ||
| name: "discover skills from .github/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .github/skills directory | ||
| skillDir := filepath.Join(dir, ".github", "skills", "copilot-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: copilot-skill | ||
| description: A skill for GitHub Copilot | ||
| --- | ||
|
|
||
| # Copilot Skill | ||
|
|
||
| This is a skill for GitHub Copilot. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "copilot-skill" { | ||
| t.Errorf("expected skill name 'copilot-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2446
to
+2454
|
||
| }, | ||
| { | ||
| name: "discover skills from .augment/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .augment/skills directory | ||
| skillDir := filepath.Join(dir, ".augment", "skills", "augment-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: augment-skill | ||
| description: A skill for Augment | ||
| --- | ||
|
|
||
| # Augment Skill | ||
|
|
||
| This is a skill for Augment. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "augment-skill" { | ||
| t.Errorf("expected skill name 'augment-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2484
to
+2492
|
||
| }, | ||
| { | ||
| name: "discover skills from .windsurf/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .windsurf/skills directory | ||
| skillDir := filepath.Join(dir, ".windsurf", "skills", "windsurf-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: windsurf-skill | ||
| description: A skill for Windsurf | ||
| --- | ||
|
|
||
| # Windsurf Skill | ||
|
|
||
| This is a skill for Windsurf. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "windsurf-skill" { | ||
| t.Errorf("expected skill name 'windsurf-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2522
to
+2530
|
||
| }, | ||
| { | ||
| name: "discover skills from .claude/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .claude/skills directory | ||
| skillDir := filepath.Join(dir, ".claude", "skills", "claude-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: claude-skill | ||
| description: A skill for Claude | ||
| --- | ||
|
|
||
| # Claude Skill | ||
|
|
||
| This is a skill for Claude. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "claude-skill" { | ||
| t.Errorf("expected skill name 'claude-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2560
to
+2568
|
||
| }, | ||
| { | ||
| name: "discover skills from .gemini/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .gemini/skills directory | ||
| skillDir := filepath.Join(dir, ".gemini", "skills", "gemini-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: gemini-skill | ||
| description: A skill for Gemini | ||
| --- | ||
|
|
||
| # Gemini Skill | ||
|
|
||
| This is a skill for Gemini. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "gemini-skill" { | ||
| t.Errorf("expected skill name 'gemini-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2598
to
+2606
|
||
| }, | ||
| { | ||
| name: "discover skills from .codex/skills directory", | ||
| setup: func(t *testing.T, dir string) { | ||
| // Create task | ||
| createTask(t, dir, "test-task", "", "Test task content") | ||
|
|
||
| // Create skill in .codex/skills directory | ||
| skillDir := filepath.Join(dir, ".codex", "skills", "codex-skill") | ||
| if err := os.MkdirAll(skillDir, 0o755); err != nil { | ||
| t.Fatalf("failed to create skill directory: %v", err) | ||
| } | ||
|
|
||
| skillContent := `--- | ||
| name: codex-skill | ||
| description: A skill for Codex | ||
| --- | ||
|
|
||
| # Codex Skill | ||
|
|
||
| This is a skill for Codex. | ||
| ` | ||
| skillPath := filepath.Join(skillDir, "SKILL.md") | ||
| if err := os.WriteFile(skillPath, []byte(skillContent), 0o644); err != nil { | ||
| t.Fatalf("failed to create skill file: %v", err) | ||
| } | ||
| }, | ||
| taskName: "test-task", | ||
| wantErr: false, | ||
| checkFunc: func(t *testing.T, result *Result) { | ||
| if len(result.Skills.Skills) != 1 { | ||
| t.Fatalf("expected 1 skill, got %d", len(result.Skills.Skills)) | ||
| } | ||
| skill := result.Skills.Skills[0] | ||
| if skill.Name != "codex-skill" { | ||
| t.Errorf("expected skill name 'codex-skill', got %q", skill.Name) | ||
| } | ||
| }, | ||
|
Comment on lines
+2636
to
+2644
|
||
| }, | ||
|
Comment on lines
+2380
to
+2645
|
||
| } | ||
|
|
||
| for _, tt := range tests { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation example is missing directory structures for Augment and Windsurf skills, which were added to the search paths list above. For consistency and completeness, examples should be provided for all newly supported agent skill directories.