feat(agent): add initial harness foundation

This commit is contained in:
Mario Zechner
2026-05-03 00:35:36 +02:00
parent 7268e9a9fd
commit a5b27367d3
12 changed files with 3678 additions and 0 deletions
@@ -0,0 +1,51 @@
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));
}