Spaces:
Running
Running
File size: 2,254 Bytes
3f76ff4 | 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 83 84 85 86 87 | import type { CommandMode, ParsedCommand, WorkPackage } from "./work-package-types";
const commandModes: CommandMode[] = ["ask", "plan", "change", "execute"];
export function parseWorkPackageCommand(
input: string,
workPackages: WorkPackage[],
): ParsedCommand | null {
const trimmedInput = input.trim();
if (!trimmedInput.startsWith("@")) {
return null;
}
const mentionBody = trimmedInput.slice(1);
const candidates = workPackages
.flatMap((workPackage) => [
{ name: workPackage.title, workPackage },
{ name: workPackage.shortName, workPackage },
])
.sort((left, right) => right.name.length - left.name.length);
for (const candidate of candidates) {
const packageName = candidate.name.toLowerCase();
const inputName = mentionBody.toLowerCase();
if (!inputName.startsWith(packageName)) {
continue;
}
const boundaryCharacter = mentionBody[candidate.name.length];
const isBoundary =
boundaryCharacter === undefined ||
boundaryCharacter === " " ||
boundaryCharacter === "#" ||
boundaryCharacter === ":";
if (!isBoundary) {
continue;
}
const remainingText = mentionBody.slice(candidate.name.length).trim();
const [maybeMode, ...instructionParts] = remainingText.split(/\s+/);
const mode = commandModes.includes(maybeMode as CommandMode)
? (maybeMode as CommandMode)
: "ask";
return {
referencedPackageName: candidate.name,
workPackageId: candidate.workPackage.id,
mode,
instruction:
mode === maybeMode
? instructionParts.join(" ").trim()
: remainingText.replace(/^#\S+\s*/, "").trim(),
};
}
return {
mode: "ask",
instruction: trimmedInput,
};
}
export function getPackageSuggestions(input: string, workPackages: WorkPackage[]) {
const match = input.match(/@([A-Za-z\s-]*)$/);
if (!match) {
return [];
}
const query = match[1].toLowerCase().trim();
return workPackages
.filter((workPackage) => {
if (!query) {
return true;
}
return (
workPackage.title.toLowerCase().includes(query) ||
workPackage.shortName.toLowerCase().includes(query)
);
})
.slice(0, 6);
}
|