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 12:59:13 +09:00
parent 961cc788f6
commit 86a62aef45

View File

@@ -0,0 +1,86 @@
import { execFileSync } from "node:child_process"
import { afterEach, beforeEach, describe, expect, it } from "bun:test"
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"
import { tmpdir } from "node:os"
import { join } from "node:path"
import {
discoverOpencodeProjectSkills,
discoverProjectAgentsSkills,
discoverProjectClaudeSkills,
} from "./loader"
function writeSkill(directory: string, name: string, description: string): void {
mkdirSync(directory, { recursive: true })
writeFileSync(
join(directory, "SKILL.md"),
`---\nname: ${name}\ndescription: ${description}\n---\nBody\n`,
)
}
describe("project skill discovery", () => {
let tempDir = ""
beforeEach(() => {
tempDir = mkdtempSync(join(tmpdir(), "omo-project-skill-discovery-"))
})
afterEach(() => {
rmSync(tempDir, { recursive: true, force: true })
})
it("discovers ancestor project skill directories up to the worktree root", async () => {
// given
const repositoryDir = join(tempDir, "repo")
const nestedDirectory = join(repositoryDir, "packages", "app", "src")
mkdirSync(nestedDirectory, { recursive: true })
execFileSync("git", ["init"], {
cwd: repositoryDir,
stdio: ["ignore", "ignore", "ignore"],
})
writeSkill(
join(repositoryDir, ".claude", "skills", "repo-claude"),
"repo-claude",
"Discovered from the repository root",
)
writeSkill(
join(repositoryDir, ".agents", "skills", "repo-agents"),
"repo-agents",
"Discovered from the repository root",
)
writeSkill(
join(repositoryDir, ".opencode", "skill", "repo-opencode"),
"repo-opencode",
"Discovered from the repository root",
)
writeSkill(
join(tempDir, ".claude", "skills", "outside-claude"),
"outside-claude",
"Should stay outside the worktree",
)
writeSkill(
join(tempDir, ".agents", "skills", "outside-agents"),
"outside-agents",
"Should stay outside the worktree",
)
writeSkill(
join(tempDir, ".opencode", "skills", "outside-opencode"),
"outside-opencode",
"Should stay outside the worktree",
)
// when
const [claudeSkills, agentSkills, opencodeSkills] = await Promise.all([
discoverProjectClaudeSkills(nestedDirectory),
discoverProjectAgentsSkills(nestedDirectory),
discoverOpencodeProjectSkills(nestedDirectory),
])
// then
expect(claudeSkills.map(skill => skill.name)).toEqual(["repo-claude"])
expect(agentSkills.map(skill => skill.name)).toEqual(["repo-agents"])
expect(opencodeSkills.map(skill => skill.name)).toEqual(["repo-opencode"])
})
})