import { describe, expect, it } from "vite-plus/test"; import { planClaudeSkillDispatch } from "./ClaudeSkillDispatch.ts"; const SKILLS = new Set(["2spec", "implement", "review", "re-release-version"]); describe("planClaudeSkillDispatch", () => { it("leaves a prompt without a known skill untouched", () => { expect(planClaudeSkillDispatch("fix the build", SKILLS)).toBeUndefined(); // Not a discovered skill, so it stays prose rather than becoming a command. expect(planClaudeSkillDispatch("echo $HOME then $unknown", SKILLS)).toBeUndefined(); }); it("moves a mid-prompt mention into a trailing slash command", () => { expect(planClaudeSkillDispatch("ok, now $implement all the tickets", SKILLS)).toEqual({ leadingText: "ok, now", commandText: "/implement all the tickets", skillName: "implement", }); }); it("keeps a mention that opens the prompt as a single command block", () => { expect(planClaudeSkillDispatch("$review\nfocus on auth", SKILLS)).toEqual({ leadingText: undefined, commandText: "/review\nfocus on auth", skillName: "review", }); }); it("dispatches a known skill whose name begins with a digit", () => { expect(planClaudeSkillDispatch("use $2spec for this", SKILLS)).toEqual({ leadingText: "use", commandText: "/2spec for this", skillName: "2spec", }); }); it("dispatches the last mention and rewrites earlier ones inline", () => { expect(planClaudeSkillDispatch("$review the diff, then $implement the fixes", SKILLS)).toEqual({ leadingText: "/review the diff, then", commandText: "/implement the fixes", skillName: "implement", }); }); it("ignores a dollar token glued to other text", () => { expect(planClaudeSkillDispatch("cost is 5$implement", SKILLS)).toBeUndefined(); }); it("ignores currency amounts and compact monetary expressions", () => { const skillsWithCurrency = new Set([...SKILLS, "20", "20k", "100M"]); expect(planClaudeSkillDispatch("pay $20 tomorrow", skillsWithCurrency)).toBeUndefined(); expect(planClaudeSkillDispatch("budget is $20k tomorrow", skillsWithCurrency)).toBeUndefined(); }); });