Spaces:
Running
Running
| 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); | |
| } | |