fix(skill): exclude Git metadata from local discovery (#315)

Signed-off-by: avivsinai <avivsinai@gmail.com>
This commit is contained in:
avivsinai
2026-09-04 22:54:32 +03:00
committed by GitHub
parent 45360621f2
commit b7a2bb998c
3 changed files with 36 additions and 0 deletions
+11
View File
@@ -6,6 +6,17 @@ All notable changes to this project will be documented here. The format follows
## [Unreleased]
### Added
- Carried forward from the unpublished `v0.32.0` tag: `bkt skill` now supports
installing, listing, previewing, updating, and publishing Agent Skills hosted
in Bitbucket Cloud or Data Center, plus Cloud workspace skill search.
- `bkt pipeline run` can select branch and custom pipeline definitions with
`--selector-type` and `--selector-pattern`.
### Fixed
- Local skill discovery ignores Git metadata, so concurrent Git maintenance no
longer causes `bkt skill publish` to fail while walking `.git`.
## [0.32.0] - 2026-09-04
### Added
- `bkt skill` installs and manages [Agent Skills](https://agentskills.io/specification)
+5
View File
@@ -443,6 +443,11 @@ func DiscoverAllLocalSkills(dir string) ([]Skill, error) {
if walkErr != nil {
return walkErr
}
// Git metadata is not skill content; pruning it also avoids races with
// concurrent maintenance. Other hidden directories remain eligible.
if info.IsDir() && info.Name() == ".git" {
return filepath.SkipDir
}
// Skip symlinks to avoid following links outside the source tree.
if info.Mode()&os.ModeSymlink != 0 {
return nil
@@ -412,6 +412,26 @@ func TestDiscoverAllLocalSkills(t *testing.T) {
}
})
t.Run("git metadata is pruned without excluding other hidden directories", func(t *testing.T) {
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "skills", "real", "SKILL.md"), "---\nname: real\n---\n")
writeFile(t, filepath.Join(dir, ".claude", "skills", "hidden", "SKILL.md"), "---\nname: hidden\n---\n")
writeFile(t, filepath.Join(dir, ".git", "skills", "fake", "SKILL.md"), "---\nname: fake\n---\n")
skills, err := DiscoverAllLocalSkills(dir)
if err != nil {
t.Fatalf("DiscoverAllLocalSkills: %v", err)
}
var names []string
for _, skill := range skills {
names = append(names, skill.DisplayName())
}
sort.Strings(names)
if !reflect.DeepEqual(names, []string{"[hidden-dir] hidden", "real"}) {
t.Fatalf("skills = %v, want authored and supported hidden skills only", names)
}
})
t.Run("single skill directory uses frontmatter name", func(t *testing.T) {
dir := t.TempDir()
writeFile(t, filepath.Join(dir, "SKILL.md"), "---\nname: renamed\ndescription: One\n---\n")