diff --git a/package.json b/package.json index 46ae8b7..6561dce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orkait-ai/hyperstack", - "version": "1.0.2", + "version": "1.0.3", "description": "Disciplined MCP server + skill system. 11 plugins, 79 tools, 21 skills with adversarial enforcement. Designer/DESIGN.md pipeline, shadcn/ui, React Flow, Motion, Lenis, React 19, Echo, Go, Rust, design tokens, UI/UX.", "bin": { "hyperstack": "bin/hyperstack.mjs" diff --git a/tests/skills-index-behaviour.test.ts b/tests/skills-index-behaviour.test.ts index 8f5f676..986633a 100644 --- a/tests/skills-index-behaviour.test.ts +++ b/tests/skills-index-behaviour.test.ts @@ -6,6 +6,10 @@ import { resolve, join } from "node:path"; const SKILLS_DIR = resolve("skills"); const INDEX_PATH = resolve("skills/INDEX.md"); +function normalize(str: string): string { + return str.replace(/\r\n/g, "\n"); +} + function getSkillDirs(): string[] { return readdirSync(SKILLS_DIR, { withFileTypes: true }) .filter((d) => d.isDirectory()) @@ -15,17 +19,17 @@ function getSkillDirs(): string[] { function getSkillCategory(skillName: string): string | null { const skillFile = join(SKILLS_DIR, skillName, "SKILL.md"); - const content = readFileSync(skillFile, "utf8"); + const content = normalize(readFileSync(skillFile, "utf8")); const match = content.match(/^category:\s*(.+)$/m); return match ? match[1].trim() : null; } test("skills/INDEX.md stays in sync with actual skill directories", () => { - const currentIndex = readFileSync(INDEX_PATH, "utf8"); + const currentIndex = normalize(readFileSync(INDEX_PATH, "utf8")); execSync("bash scripts/generate-skills-index.sh", { stdio: "pipe" }); - const regenerated = readFileSync(INDEX_PATH, "utf8"); + const regenerated = normalize(readFileSync(INDEX_PATH, "utf8")); expect(currentIndex).toBe(regenerated); }); @@ -35,7 +39,7 @@ test("every skill directory has a SKILL.md with required frontmatter fields", () for (const skillName of skillDirs) { const skillFile = join(SKILLS_DIR, skillName, "SKILL.md"); - const content = readFileSync(skillFile, "utf8"); + const content = normalize(readFileSync(skillFile, "utf8")); expect(content).toMatch(/^---\n/m); expect(content).toMatch(/^name:\s*.+$/m); @@ -56,7 +60,7 @@ test("every skill has a valid category (core | domain | meta)", () => { }); test("skills/INDEX.md references every skill directory that has a SKILL.md", () => { - const indexContent = readFileSync(INDEX_PATH, "utf8"); + const indexContent = normalize(readFileSync(INDEX_PATH, "utf8")); const skillDirs = getSkillDirs(); for (const skillName of skillDirs) {