test(builtin-skills): batch 29 (3 files)

This commit is contained in:
YeonGyu-Kim
2026-05-30 19:12:05 +09:00
parent 4279826b6c
commit 08ea320b54
3 changed files with 188 additions and 0 deletions
@@ -0,0 +1,69 @@
/// <reference path="../../../bun-test.d.ts" />
import { describe, expect, test } from "bun:test"
import type { BuiltinSkill } from "./types"
declare const Bun: {
file(path: string): { text(): Promise<string> }
}
const TARGET_SKILLS = ["remove-ai-slops", "review-work", "frontend-ui-ux", "init-deep"] as const
type TargetSkill = (typeof TARGET_SKILLS)[number]
type SkillSource = {
readonly name: TargetSkill
readonly description: string
readonly template: string
}
function getRequiredMatch(source: string, pattern: RegExp, label: string): RegExpMatchArray {
const match = source.match(pattern)
if (!match) {
throw new Error(`missing ${label}`)
}
return match
}
async function readSkillSource(name: TargetSkill): Promise<SkillSource> {
let skill: BuiltinSkill
switch (name) {
case "remove-ai-slops":
skill = (await import("./skills/remove-ai-slops")).removeAiSlopsSkill
break
case "review-work":
skill = (await import("./skills/review-work")).reviewWorkSkill
break
case "frontend-ui-ux":
skill = (await import("./skills/frontend-ui-ux")).frontendUiUxSkill
break
case "init-deep":
skill = (await import("./skills/init-deep")).initDeepSkill
break
}
return { name, description: skill.description, template: skill.template }
}
async function readSharedSkill(name: TargetSkill): Promise<{ readonly frontmatter: string; readonly body: string }> {
const content = await Bun.file(`packages/shared-skills/skills/${name}/SKILL.md`).text()
const match = getRequiredMatch(content, /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/, `${name} frontmatter`)
return { frontmatter: match[1], body: match[2] }
}
describe("shared builtin skill extraction", () => {
test("#given extracted builtin skill markdown #when compared to TS sources #then bodies and metadata stay byte-equivalent", async () => {
// given
const sources = await Promise.all(TARGET_SKILLS.map(readSkillSource))
// when
const sharedSkills = await Promise.all(TARGET_SKILLS.map(readSharedSkill))
// then
for (const [index, source] of sources.entries()) {
const sharedSkill = sharedSkills[index]
expect(sharedSkill.frontmatter).toContain(`name: ${source.name}`)
expect(sharedSkill.frontmatter).toContain(`description: ${JSON.stringify(source.description)}`)
expect(sharedSkill.body).toBe(source.template)
}
})
})
@@ -0,0 +1,81 @@
/// <reference path="../../../bun-test.d.ts" />
import { describe, expect, test } from "bun:test"
import { parseFrontmatter } from "../../shared/frontmatter"
import { createBuiltinSkills } from "./skills"
import { createSharedSkillTemplateLoader, loadSharedSkillTemplate } from "./skill-file-loader"
declare const Bun: {
file(path: string): { text(): Promise<string> }
}
const SHARED_BUILTIN_SKILLS = ["remove-ai-slops", "review-work", "frontend-ui-ux", "init-deep"] as const
describe("shared builtin skill file loader", () => {
test("#given extracted shared skill files #when builtin skills are created #then templates load from SKILL.md bodies", async () => {
// given
const skills = createBuiltinSkills()
// when
const skillTemplates = new Map(skills.map((skill) => [skill.name, skill.template]))
// then
for (const skillName of SHARED_BUILTIN_SKILLS) {
const content = await Bun.file(`packages/shared-skills/skills/${skillName}/SKILL.md`).text()
const { body } = parseFrontmatter(content)
expect(skillTemplates.get(skillName)).toBe(body)
expect(loadSharedSkillTemplate(skillName)).toBe(body)
}
})
test("#given repeated loads #when using the same loader #then it reads each shared skill file once", () => {
// given
const reads: string[] = []
const loader = createSharedSkillTemplateLoader((path) => {
reads.push(path)
return "---\nname: cached\n---\nCached body"
})
// when
const first = loader("cached-skill")
const second = loader("cached-skill")
// then
expect(first).toBe("Cached body")
expect(second).toBe("Cached body")
expect(reads).toHaveLength(1)
})
test("#given source and bundled layouts #when loading shared skill templates #then both package-relative paths resolve", () => {
// given
const expectedContent = "---\nname: layout\n---\nLayout body"
const createMissingFileError = (): Error => {
const error = new Error("ENOENT missing SKILL.md")
Object.defineProperty(error, "code", { value: "ENOENT" })
return error
}
const readFile = (path: string): string => {
if (path.endsWith("/packages/shared-skills/skills/layout/SKILL.md")) {
return expectedContent
}
throw createMissingFileError()
}
// when
const bundledLoader = createSharedSkillTemplateLoader(readFile, "/workspace/dist")
const sourceLoader = createSharedSkillTemplateLoader(readFile, "/workspace/src/features/builtin-skills")
// then
expect(bundledLoader("layout")).toBe("Layout body")
expect(sourceLoader("layout")).toBe("Layout body")
})
test("#given a missing shared skill file #when loading the template #then the loader fails fast", () => {
// given
const loader = createSharedSkillTemplateLoader(() => {
throw new Error("ENOENT missing SKILL.md")
})
expect(() => loader("__missing__")).toThrow("ENOENT missing SKILL.md")
})
})
@@ -0,0 +1,38 @@
import { readFileSync } from "node:fs"
import { dirname, join } from "node:path"
import { fileURLToPath } from "node:url"
import { parseFrontmatter } from "../../shared/frontmatter"
type SkillFileReader = (path: string, encoding: "utf8") => string
const SHARED_SKILL_PATHS = [
["..", "packages", "shared-skills", "skills"],
["..", "..", "..", "packages", "shared-skills", "skills"],
] as const
const moduleDir = typeof import.meta.dir === "string" ? import.meta.dir : dirname(fileURLToPath(import.meta.url))
export function createSharedSkillTemplateLoader(
readFile: SkillFileReader = readFileSync,
baseDir: string = moduleDir,
): (skillName: string) => string {
const cache = new Map<string, string>()
return (skillName) => {
const cached = cache.get(skillName)
if (cached !== undefined) return cached
let missingFileError: unknown
for (const segments of SHARED_SKILL_PATHS) {
try {
const { body } = parseFrontmatter(readFile(join(baseDir, ...segments, skillName, "SKILL.md"), "utf8"))
cache.set(skillName, body)
return body
} catch (error) {
if (!(error instanceof Error && Reflect.get(error, "code") === "ENOENT")) {
throw error
}
missingFileError ??= error
}
}
throw missingFileError ?? new Error(`missing shared skill template: ${skillName}`)
}
}
const loadSharedSkillTemplateFromDisk = createSharedSkillTemplateLoader()
export function loadSharedSkillTemplate(skillName: string): string {
return loadSharedSkillTemplateFromDisk(skillName)
}