100 lines · 2.5 KB · TypeScript
RawDownload
import {  INLINE_TERMINAL_CONTEXT_PLACEHOLDER,  type TerminalContextDraft,} from "./lib/terminalContext"; export type ComposerPromptSegment =  | {      type: "text";      text: string;    }  | {      type: "mention";      path: string;    }  | {      type: "terminal-context";      context: TerminalContextDraft | null;    }; const MENTION_TOKEN_REGEX = /(^|\s)@([^\s@]+)(?=\s)/g; function pushTextSegment(segments: ComposerPromptSegment[], text: string): void {  if (!text) return;  const last = segments[segments.length - 1];  if (last && last.type === "text") {    last.text += text;    return;  }  segments.push({ type: "text", text });} function splitPromptTextIntoComposerSegments(text: string): ComposerPromptSegment[] {  const segments: ComposerPromptSegment[] = [];  if (!text) {    return segments;  }   let cursor = 0;  for (const match of text.matchAll(MENTION_TOKEN_REGEX)) {    const fullMatch = match[0];    const prefix = match[1] ?? "";    const path = match[2] ?? "";    const matchIndex = match.index ?? 0;    const mentionStart = matchIndex + prefix.length;    const mentionEnd = mentionStart + fullMatch.length - prefix.length;     if (mentionStart > cursor) {      pushTextSegment(segments, text.slice(cursor, mentionStart));    }     if (path.length > 0) {      segments.push({ type: "mention", path });    } else {      pushTextSegment(segments, text.slice(mentionStart, mentionEnd));    }     cursor = mentionEnd;  }   if (cursor < text.length) {    pushTextSegment(segments, text.slice(cursor));  }   return segments;} export function splitPromptIntoComposerSegments(  prompt: string,  terminalContexts: ReadonlyArray<TerminalContextDraft> = [],): ComposerPromptSegment[] {  if (!prompt) {    return [];  }   const segments: ComposerPromptSegment[] = [];  let textCursor = 0;  let terminalContextIndex = 0;   for (let index = 0; index < prompt.length; index += 1) {    if (prompt[index] !== INLINE_TERMINAL_CONTEXT_PLACEHOLDER) {      continue;    }     if (index > textCursor) {      segments.push(...splitPromptTextIntoComposerSegments(prompt.slice(textCursor, index)));    }    segments.push({      type: "terminal-context",      context: terminalContexts[terminalContextIndex] ?? null,    });    terminalContextIndex += 1;    textCursor = index + 1;  }   if (textCursor < prompt.length) {    segments.push(...splitPromptTextIntoComposerSegments(prompt.slice(textCursor)));  }   return segments;}