Skip to content

Skip hidden directories in recursive skill loading#1875

Merged
dgageot merged 2 commits intodocker:mainfrom
dgageot:skills2
Mar 3, 2026
Merged

Skip hidden directories in recursive skill loading#1875
dgageot merged 2 commits intodocker:mainfrom
dgageot:skills2

Conversation

@dgageot
Copy link
Member

@dgageot dgageot commented Feb 27, 2026

Return fs.SkipDir for hidden directories and symlinks instead of descending into them. This avoids walking large trees like .git, .node_modules, or .cache that can never contain skills.

Assisted-By: cagent

@dgageot dgageot requested a review from a team as a code owner February 27, 2026 19:51
docker-agent[bot]
docker-agent bot previously approved these changes Feb 27, 2026
Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

✅ This PR effectively optimizes directory traversal by skipping hidden directories like .git, .node_modules, and .cache early using fs.SkipDir. The logic correctly handles the root directory edge case.

Note

One minor behavioral change: the refactored code no longer filters out hidden or symlinked skill files (e.g., .SKILL.md or symlinked SKILL.md), only hidden directories. The original code checked isHiddenOrSymlink(d) for both directories and files, but the new code only applies this check to directories (line 222). This may be intentional since hidden skill files are rare, but it's worth noting the behavior change.

@rumpl
Copy link
Member

rumpl commented Feb 27, 2026

I'm not sure about symlinks though, seems like something someone would do

dgageot added 2 commits March 3, 2026 10:18
Return fs.SkipDir for hidden directories and symlinks instead of
descending into them. This avoids walking large trees like .git,
.node_modules, or .cache that can never contain skills.

Assisted-By: cagent
Signed-off-by: David Gageot <david.gageot@docker.com>
var skills []Skill
for _, entry := range entries {
if !entry.IsDir() || isHiddenOrSymlink(entry) {
if !entry.IsDir() || (isHidden(entry) || isSymlink(entry)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not following symlinks? The real change with symlink are security issues to ensure that they don't allow to go outside of the project folder....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want to work on loadSkillsFlat in that PR. Happy to work on it in another PR

Copy link
Contributor

@aheritier aheritier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dgageot dgageot merged commit 96d4e9e into docker:main Mar 3, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants