[READ-ONLY] Mirror of https://github.com/bombshell-dev/tools. Internal CLI to standardize tooling across all Bombshell projects
Something went wrong. Try again.
TypeScript
at fix/sync-ii
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091import { lstat, readlink } from "node:fs/promises";import { fileURLToPath } from "node:url";import { describe, it, expect } from "vitest";import { createFixture } from "../test-utils/index.ts";import { copySkills, findProjectRoot } from "./sync.ts";
describe("copySkills", () => { it("symlinks each skill into the destination", async () => { const fixture = await createFixture({ "source-skills": { build: { "SKILL.md": "---\nname: build\ndescription: Build the project.\n---\nbody", }, }, });
const source = new URL("source-skills/", fixture.root); const dest = new URL("project/skills/", fixture.root);
const skills = await copySkills({ source, dest });
expect(skills).toEqual([{ name: "build", description: "Build the project." }]);
// The destination entry must be a symlink, not a copy. const linkPath = fileURLToPath(new URL("build", dest)); expect((await lstat(linkPath)).isSymbolicLink()).toBe(true);
// And it must resolve back to the source skill. expect(await readlink(linkPath)).toBe("../../source-skills/build");
// Reading through the link reaches the real file. expect(await fixture.text("project/skills/build/SKILL.md")).toContain("name: build"); });
it("is idempotent and never touches the source on re-sync", async () => { const fixture = await createFixture({ "source-skills": { build: { "SKILL.md": "---\nname: build\ndescription: Build the project.\n---\nbody", }, }, });
const source = new URL("source-skills/", fixture.root); const dest = new URL("project/skills/", fixture.root);
const first = await copySkills({ source, dest }); // Re-running must not throw and must yield the same result. const second = await copySkills({ source, dest });
expect(second).toEqual(first); // The source skill files must survive a re-sync. expect(await fixture.text("source-skills/build/SKILL.md")).toContain("name: build"); expect(await fixture.text("project/skills/build/SKILL.md")).toContain("name: build"); });});
describe("findProjectRoot", () => { it("finds the nearest package.json walking up from the start directory", async () => { const fixture = await createFixture({ "package.json": { name: "my-app", version: "1.0.0" }, src: { nested: { "index.ts": "export const x = 1" } }, });
const result = await findProjectRoot(fileURLToPath(new URL("src/nested", fixture.root)));
expect(result).toEqual({ kind: "found", root: fixture.root }); });
it("reports self when the nearest package is @bomb.sh/tools", async () => { const fixture = await createFixture({ "package.json": { name: "@bomb.sh/tools", version: "1.0.0" }, });
const result = await findProjectRoot(fileURLToPath(fixture.root));
expect(result).toEqual({ kind: "self" }); });
it("reports not-found when no package.json exists in any parent", async () => { const fixture = await createFixture({ src: { "index.ts": "export const x = 1" }, });
// A nested directory in a fixture that has no package.json anywhere up to /tmp. const result = await findProjectRoot(fileURLToPath(new URL("src", fixture.root)));
expect(result).toEqual({ kind: "not-found" }); });});