52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import type { PromptTemplate } from "./types.js";
|
|
|
|
export function parseCommandArgs(argsString: string): string[] {
|
|
const args: string[] = [];
|
|
let current = "";
|
|
let inQuote: string | null = null;
|
|
|
|
for (let i = 0; i < argsString.length; i++) {
|
|
const char = argsString[i]!;
|
|
if (inQuote) {
|
|
if (char === inQuote) inQuote = null;
|
|
else current += char;
|
|
} else if (char === '"' || char === "'") {
|
|
inQuote = char;
|
|
} else if (char === " " || char === "\t") {
|
|
if (current) {
|
|
args.push(current);
|
|
current = "";
|
|
}
|
|
} else {
|
|
current += char;
|
|
}
|
|
}
|
|
if (current) args.push(current);
|
|
return args;
|
|
}
|
|
|
|
export function substituteArgs(content: string, args: string[]): string {
|
|
let result = content;
|
|
result = result.replace(/\$(\d+)/g, (_, num: string) => args[parseInt(num, 10) - 1] ?? "");
|
|
result = result.replace(/\$\{@:(\d+)(?::(\d+))?\}/g, (_, startStr: string, lengthStr?: string) => {
|
|
let start = parseInt(startStr, 10) - 1;
|
|
if (start < 0) start = 0;
|
|
if (lengthStr) return args.slice(start, start + parseInt(lengthStr, 10)).join(" ");
|
|
return args.slice(start).join(" ");
|
|
});
|
|
const allArgs = args.join(" ");
|
|
result = result.replace(/\$ARGUMENTS/g, allArgs);
|
|
result = result.replace(/\$@/g, allArgs);
|
|
return result;
|
|
}
|
|
|
|
export function expandPromptTemplate(text: string, templates: PromptTemplate[]): string {
|
|
if (!text.startsWith("/")) return text;
|
|
const spaceIndex = text.indexOf(" ");
|
|
const commandName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
const argsString = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1);
|
|
const template = templates.find((candidate) => candidate.name === commandName);
|
|
if (!template) return text;
|
|
return substituteArgs(template.content, parseCommandArgs(argsString));
|
|
}
|