summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/utils
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-26 18:23:04 -0600
committerGitHub <[email protected]>2026-02-26 18:23:04 -0600
commitfc52e4b2d3a41efde772e6de8fb2e01f27821701 (patch)
treecf23af294a00a10e55f230232585344c111f0bb9 /packages/app/src/utils
parent9a6bfeb782766099d4ce3a98bb9e7b4e79f8bfe6 (diff)
downloadopencode-fc52e4b2d3a41efde772e6de8fb2e01f27821701.tar.gz
opencode-fc52e4b2d3a41efde772e6de8fb2e01f27821701.zip
feat(app): better diff/code comments (#14621)
Co-authored-by: adamelmore <[email protected]> Co-authored-by: David Hill <[email protected]>
Diffstat (limited to 'packages/app/src/utils')
-rw-r--r--packages/app/src/utils/comment-note.ts88
1 files changed, 88 insertions, 0 deletions
diff --git a/packages/app/src/utils/comment-note.ts b/packages/app/src/utils/comment-note.ts
new file mode 100644
index 000000000..99e87fc81
--- /dev/null
+++ b/packages/app/src/utils/comment-note.ts
@@ -0,0 +1,88 @@
+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
+}