summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/utils/diffs.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/utils/diffs.ts')
-rw-r--r--packages/app/src/utils/diffs.ts49
1 files changed, 49 insertions, 0 deletions
diff --git a/packages/app/src/utils/diffs.ts b/packages/app/src/utils/diffs.ts
new file mode 100644
index 000000000..0cb2504fb
--- /dev/null
+++ b/packages/app/src/utils/diffs.ts
@@ -0,0 +1,49 @@
+import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { Message } from "@opencode-ai/sdk/v2/client"
+
+type Diff = SnapshotFileDiff | VcsFileDiff
+
+function diff(value: unknown): value is Diff {
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false
+ if (!("file" in value) || typeof value.file !== "string") return false
+ if (!("patch" in value) || typeof value.patch !== "string") return false
+ if (!("additions" in value) || typeof value.additions !== "number") return false
+ if (!("deletions" in value) || typeof value.deletions !== "number") return false
+ if (!("status" in value) || value.status === undefined) return true
+ return value.status === "added" || value.status === "deleted" || value.status === "modified"
+}
+
+function object(value: unknown): value is Record<string, unknown> {
+ return !!value && typeof value === "object" && !Array.isArray(value)
+}
+
+export function diffs(value: unknown): Diff[] {
+ if (Array.isArray(value) && value.every(diff)) return value
+ if (Array.isArray(value)) return value.filter(diff)
+ if (diff(value)) return [value]
+ if (!object(value)) return []
+ return Object.values(value).filter(diff)
+}
+
+export function message(value: Message): Message {
+ if (value.role !== "user") return value
+
+ const raw = value.summary as unknown
+ if (raw === undefined) return value
+ if (!object(raw)) return { ...value, summary: undefined }
+
+ const title = typeof raw.title === "string" ? raw.title : undefined
+ const body = typeof raw.body === "string" ? raw.body : undefined
+ const next = diffs(raw.diffs)
+
+ if (title === raw.title && body === raw.body && next === raw.diffs) return value
+
+ return {
+ ...value,
+ summary: {
+ ...(title === undefined ? {} : { title }),
+ ...(body === undefined ? {} : { body }),
+ diffs: next,
+ },
+ }
+}