Repository navigation
Expand file tree
/
Copy pathClaudeSkillDispatch.test.ts
More file actions
82 lines (72 loc) · 3 KB
/
Copy pathClaudeSkillDispatch.test.ts
File metadata and controls
82 lines (72 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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("dispatches currency-prefixed mentions and preserves their source boundaries", () => {
for (const symbol of ["€", "£", "¥", "₹", "₩", "₿", "𑿝"]) {
expect(
planClaudeSkillDispatch(
`${symbol}review the diff, then ${symbol}implement the fixes`,
SKILLS,
),
).toEqual({
leadingText: "/review the diff, then",
commandText: "/implement the fixes",
skillName: "implement",
});
expect(planClaudeSkillDispatch(`${symbol}2spec for this`, SKILLS)).toEqual({
leadingText: undefined,
commandText: "/2spec for this",
skillName: "2spec",
});
expect(planClaudeSkillDispatch(`5${symbol}review ${symbol}unknown`, SKILLS)).toBeUndefined();
}
});
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", "1e6"]);
for (const symbol of ["$", "€", "£", "¥", "₹", "₩", "₿", "𑿝"]) {
expect(
planClaudeSkillDispatch(
`pay ${symbol}20 ${symbol}20k ${symbol}100M ${symbol}1e6 tomorrow`,
skillsWithCurrency,
),
).toBeUndefined();
}
});
});