Files
2026-01-27 12:19:22 +01:00

183 lines
5.4 KiB
TypeScript

import { test, expect, describe } from "bun:test"
import { KilocodePaths } from "../../src/kilocode/paths"
import { tmpdir } from "../fixture/fixture"
import path from "path"
import fs from "fs/promises"
describe("KilocodePaths", () => {
describe("skillDirectories", () => {
test("discovers skills from .kilocode/skills/", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
const skillDir = path.join(dir, ".kilocode", "skills", "test-skill")
await fs.mkdir(skillDir, { recursive: true })
await Bun.write(
path.join(skillDir, "SKILL.md"),
`---
name: test-skill
description: A test skill
---
# Test instructions`,
)
},
})
const result = await KilocodePaths.skillDirectories({
projectDir: tmp.path,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
expect(result).toHaveLength(1)
expect(result[0]).toEndWith(".kilocode")
})
test("returns empty array when no .kilocode/skills/ exists", async () => {
await using tmp = await tmpdir()
const result = await KilocodePaths.skillDirectories({
projectDir: tmp.path,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
expect(result).toHaveLength(0)
})
test("discovers skills from nested .kilocode directories", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
// Root level skill
const rootSkillDir = path.join(dir, ".kilocode", "skills", "root-skill")
await fs.mkdir(rootSkillDir, { recursive: true })
await Bun.write(
path.join(rootSkillDir, "SKILL.md"),
`---
name: root-skill
description: Root level skill
---
# Root instructions`,
)
// Nested project skill
const nestedDir = path.join(dir, "packages", "nested")
const nestedSkillDir = path.join(nestedDir, ".kilocode", "skills", "nested-skill")
await fs.mkdir(nestedSkillDir, { recursive: true })
await Bun.write(
path.join(nestedSkillDir, "SKILL.md"),
`---
name: nested-skill
description: Nested skill
---
# Nested instructions`,
)
},
})
// Run from nested directory, should find both
const nestedPath = path.join(tmp.path, "packages", "nested")
const result = await KilocodePaths.skillDirectories({
projectDir: nestedPath,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
expect(result).toHaveLength(2)
expect(result.some((d) => d.includes("packages/nested"))).toBe(true)
expect(result.some((d) => !d.includes("packages/nested"))).toBe(true)
})
test("handles .kilocode directory without skills subdirectory", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
// Create .kilocode but not skills/
await fs.mkdir(path.join(dir, ".kilocode"), { recursive: true })
await Bun.write(path.join(dir, ".kilocode", "config.json"), "{}")
},
})
const result = await KilocodePaths.skillDirectories({
projectDir: tmp.path,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
expect(result).toHaveLength(0)
})
test("handles symlinked skill directories", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
// Create actual skill in a different location
const actualDir = path.join(dir, "shared-skills", "my-skill")
await fs.mkdir(actualDir, { recursive: true })
await Bun.write(
path.join(actualDir, "SKILL.md"),
`---
name: my-skill
description: Symlinked skill
---
# Instructions`,
)
// Create .kilocode/skills/ and symlink the skill
const skillsDir = path.join(dir, ".kilocode", "skills")
await fs.mkdir(skillsDir, { recursive: true })
await fs.symlink(actualDir, path.join(skillsDir, "my-skill"))
},
})
const result = await KilocodePaths.skillDirectories({
projectDir: tmp.path,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
expect(result).toHaveLength(1)
expect(result[0]).toEndWith(".kilocode")
})
test("discovers multiple skills in same directory", async () => {
await using tmp = await tmpdir({
init: async (dir) => {
const skillsDir = path.join(dir, ".kilocode", "skills")
// First skill
const skill1 = path.join(skillsDir, "skill-one")
await fs.mkdir(skill1, { recursive: true })
await Bun.write(
path.join(skill1, "SKILL.md"),
`---
name: skill-one
description: First skill
---
# First`,
)
// Second skill
const skill2 = path.join(skillsDir, "skill-two")
await fs.mkdir(skill2, { recursive: true })
await Bun.write(
path.join(skill2, "SKILL.md"),
`---
name: skill-two
description: Second skill
---
# Second`,
)
},
})
const result = await KilocodePaths.skillDirectories({
projectDir: tmp.path,
worktreeRoot: tmp.path,
skipGlobalPaths: true,
})
// Should return the .kilocode directory (not skills/ subdirectory)
expect(result).toHaveLength(1)
expect(result[0]).toEndWith(".kilocode")
})
})
})