import type { FileSelection } from "@/context/file" export type PromptComment = { path: string selection?: FileSelection comment: string preview?: string origin?: "review" | "file" } function selection(selection: unknown) { if (!selection || typeof selection !== "object") return undefined const startLine = Number((selection as FileSelection).startLine) const startChar = Number((selection as FileSelection).startChar) const endLine = Number((selection as FileSelection).endLine) const endChar = Number((selection as FileSelection).endChar) if (![startLine, startChar, endLine, endChar].every(Number.isFinite)) return undefined return { startLine, startChar, endLine, endChar, } satisfies FileSelection } export function createCommentMetadata(input: PromptComment) { return { opencodeComment: { path: input.path, selection: input.selection, comment: input.comment, preview: input.preview, origin: input.origin, }, } } export function readCommentMetadata(value: unknown) { if (!value || typeof value !== "object") return const meta = (value as { opencodeComment?: unknown }).opencodeComment if (!meta || typeof meta !== "object") return const path = (meta as { path?: unknown }).path const comment = (meta as { comment?: unknown }).comment if (typeof path !== "string" || typeof comment !== "string") return const preview = (meta as { preview?: unknown }).preview const origin = (meta as { origin?: unknown }).origin return { path, selection: selection((meta as { selection?: unknown }).selection), comment, preview: typeof preview === "string" ? preview : undefined, origin: origin === "review" || origin === "file" ? origin : undefined, } satisfies PromptComment } export function formatCommentNote(input: { path: string; selection?: FileSelection; comment: string }) { const start = input.selection ? Math.min(input.selection.startLine, input.selection.endLine) : undefined const end = input.selection ? Math.max(input.selection.startLine, input.selection.endLine) : undefined const range = start === undefined || end === undefined ? "this file" : start === end ? `line ${start}` : `lines ${start} through ${end}` return `The user made the following comment regarding ${range} of ${input.path}: ${input.comment}` } export function parseCommentNote(text: string) { const match = text.match( /^The user made the following comment regarding (this file|line (\d+)|lines (\d+) through (\d+)) of (.+?): ([\s\S]+)$/, ) if (!match) return const start = match[2] ? Number(match[2]) : match[3] ? Number(match[3]) : undefined const end = match[2] ? Number(match[2]) : match[4] ? Number(match[4]) : undefined return { path: match[5], selection: start !== undefined && end !== undefined ? { startLine: start, startChar: 0, endLine: end, endChar: 0, } : undefined, comment: match[6], } satisfies PromptComment }