fix(skills): discover ancestor project skill directories

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-03-26 11:22:00 +09:00
parent 8242500856
commit b5cb50b561
2 changed files with 125 additions and 12 deletions
+38 -12
View File
@@ -3,6 +3,11 @@ import { homedir } from "os"
import { getClaudeConfigDir } from "../../shared/claude-config-dir"
import { getOpenCodeConfigDir } from "../../shared/opencode-config-dir"
import { getOpenCodeSkillDirs } from "../../shared/opencode-command-dirs"
import {
findProjectAgentsSkillDirs,
findProjectClaudeSkillDirs,
findProjectOpencodeSkillDirs,
} from "../../shared/project-discovery-dirs"
import type { CommandDefinition } from "../claude-code-command-loader/types"
import type { LoadedSkill } from "./types"
import { skillsToCommandDefinitionRecord } from "./skill-definition-record"
@@ -16,9 +21,11 @@ export async function loadUserSkills(): Promise<Record<string, CommandDefinition
}
export async function loadProjectSkills(directory?: string): Promise<Record<string, CommandDefinition>> {
const projectSkillsDir = join(directory ?? process.cwd(), ".claude", "skills")
const skills = await loadSkillsFromDir({ skillsDir: projectSkillsDir, scope: "project" })
return skillsToCommandDefinitionRecord(skills)
const projectSkillDirs = findProjectClaudeSkillDirs(directory ?? process.cwd())
const allSkills = await Promise.all(
projectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })),
)
return skillsToCommandDefinitionRecord(deduplicateSkillsByName(allSkills.flat()))
}
export async function loadOpencodeGlobalSkills(): Promise<Record<string, CommandDefinition>> {
@@ -30,9 +37,15 @@ export async function loadOpencodeGlobalSkills(): Promise<Record<string, Command
}
export async function loadOpencodeProjectSkills(directory?: string): Promise<Record<string, CommandDefinition>> {
const opencodeProjectDir = join(directory ?? process.cwd(), ".opencode", "skills")
const skills = await loadSkillsFromDir({ skillsDir: opencodeProjectDir, scope: "opencode-project" })
return skillsToCommandDefinitionRecord(skills)
const opencodeProjectSkillDirs = findProjectOpencodeSkillDirs(
directory ?? process.cwd(),
)
const allSkills = await Promise.all(
opencodeProjectSkillDirs.map((skillsDir) =>
loadSkillsFromDir({ skillsDir, scope: "opencode-project" }),
),
)
return skillsToCommandDefinitionRecord(deduplicateSkillsByName(allSkills.flat()))
}
export interface DiscoverSkillsOptions {
@@ -104,8 +117,11 @@ export async function discoverUserClaudeSkills(): Promise<LoadedSkill[]> {
}
export async function discoverProjectClaudeSkills(directory?: string): Promise<LoadedSkill[]> {
const projectSkillsDir = join(directory ?? process.cwd(), ".claude", "skills")
return loadSkillsFromDir({ skillsDir: projectSkillsDir, scope: "project" })
const projectSkillDirs = findProjectClaudeSkillDirs(directory ?? process.cwd())
const allSkills = await Promise.all(
projectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })),
)
return deduplicateSkillsByName(allSkills.flat())
}
export async function discoverOpencodeGlobalSkills(): Promise<LoadedSkill[]> {
@@ -117,13 +133,23 @@ export async function discoverOpencodeGlobalSkills(): Promise<LoadedSkill[]> {
}
export async function discoverOpencodeProjectSkills(directory?: string): Promise<LoadedSkill[]> {
const opencodeProjectDir = join(directory ?? process.cwd(), ".opencode", "skills")
return loadSkillsFromDir({ skillsDir: opencodeProjectDir, scope: "opencode-project" })
const opencodeProjectSkillDirs = findProjectOpencodeSkillDirs(
directory ?? process.cwd(),
)
const allSkills = await Promise.all(
opencodeProjectSkillDirs.map((skillsDir) =>
loadSkillsFromDir({ skillsDir, scope: "opencode-project" }),
),
)
return deduplicateSkillsByName(allSkills.flat())
}
export async function discoverProjectAgentsSkills(directory?: string): Promise<LoadedSkill[]> {
const agentsProjectDir = join(directory ?? process.cwd(), ".agents", "skills")
return loadSkillsFromDir({ skillsDir: agentsProjectDir, scope: "project" })
const agentsProjectSkillDirs = findProjectAgentsSkillDirs(directory ?? process.cwd())
const allSkills = await Promise.all(
agentsProjectSkillDirs.map((skillsDir) => loadSkillsFromDir({ skillsDir, scope: "project" })),
)
return deduplicateSkillsByName(allSkills.flat())
}
export async function discoverGlobalAgentsSkills(): Promise<LoadedSkill[]> {