@@ -1046,15 +1046,37 @@ func GlobalSkillsDirs() []string {
1046 return paths
1046 return paths
1049+// projectSkillSubdirs lists the conventional subdirectories where
1050+// project-level skills are discovered. Shared across working-dir and
1051+// git-root lookups to prevent drift when a new convention is added.
1052+var projectSkillSubdirs = []string{
1049// ProjectSkillsDir returns the default project directories for which Crush
1059// ProjectSkillsDir returns the default project directories for which Crush
1050−// will look for skills.
1060+// will look for skills. In addition to the working directory, it also
1061+// checks the git working tree root so that monorepo-level skills are
1062+// discovered when the user is inside a subdirectory.
1063+// Working-directory paths come first so local skills take precedence
1064+// over monorepo-level ones.
1051func ProjectSkillsDir(workingDir string) []string {
1065func ProjectSkillsDir(workingDir string) []string {
1052− return []string{
1066+ dirs := make([]string, 0, len(projectSkillSubdirs)*2)
1067+ for _, sub := range projectSkillSubdirs {
1053− filepath.Join(workingDir, ".agents/skills"),
1068+ dirs = append(dirs, filepath.Join(workingDir, sub))
1054− filepath.Join(workingDir, ".crush/skills"),
1069+ }
1055− filepath.Join(workingDir, ".claude/skills"),
1070+
1056− filepath.Join(workingDir, ".cursor/skills"),
1071+ // When the working directory is inside a git repository, also look at
1072+ // the repository root so monorepo-level .agents/skills are found.
1073+ if root := worktreeRoot(workingDir); root != "" && root != workingDir {
1074+ for _, sub := range projectSkillSubdirs {
1075+ dirs = append(dirs, filepath.Join(root, sub))
1060func isAppleTerminal() bool { return os.Getenv("TERM_PROGRAM") == "Apple_Terminal" }
1082func isAppleTerminal() bool { return os.Getenv("TERM_PROGRAM") == "Apple_Terminal" }