67 lines · 1.9 KB · TypeScript
RawDownload
export function proposedPlanTitle(planMarkdown: string): string | null {  const heading = planMarkdown.match(/^\s{0,3}#{1,6}\s+(.+)$/m)?.[1]?.trim();  return heading && heading.length > 0 ? heading : null;} function sanitizePlanFileSegment(input: string): string {  const sanitized = input    .toLowerCase()    .replace(/[`'".,!?()[\]{}]+/g, "")    .replace(/[^a-z0-9]+/g, "-")    .replace(/^-+|-+$/g, "");  return sanitized.length > 0 ? sanitized : "plan";} export function buildPlanImplementationPrompt(planMarkdown: string): string {  return `PLEASE IMPLEMENT THIS PLAN:\n${planMarkdown.trim()}`;} export function resolvePlanFollowUpSubmission(input: {  draftText: string;  planMarkdown: string;}): {  text: string;  interactionMode: "default" | "plan";} {  const trimmedDraftText = input.draftText.trim();  if (trimmedDraftText.length > 0) {    return {      text: trimmedDraftText,      interactionMode: "plan",    };  }   return {    text: buildPlanImplementationPrompt(input.planMarkdown),    interactionMode: "default",  };} export function buildPlanImplementationThreadTitle(planMarkdown: string): string {  const title = proposedPlanTitle(planMarkdown);  if (!title) {    return "Implement plan";  }  return `Implement ${title}`;} export function buildProposedPlanMarkdownFilename(planMarkdown: string): string {  const title = proposedPlanTitle(planMarkdown);  return `${sanitizePlanFileSegment(title ?? "plan")}.md`;} export function normalizePlanMarkdownForExport(planMarkdown: string): string {  return `${planMarkdown.trimEnd()}\n`;} export function downloadPlanAsTextFile(filename: string, contents: string): void {  const blob = new Blob([contents], { type: "text/markdown;charset=utf-8" });  const url = URL.createObjectURL(blob);  const anchor = document.createElement("a");  anchor.href = url;  anchor.download = filename;  anchor.click();  window.setTimeout(() => {    URL.revokeObjectURL(url);  }, 0);}