소스 검색

fix(app): update remote sdk contracts

Dax Raad 2 주 전
부모
커밋
5592f5225b

+ 2 - 2
packages/app/src/context/global-sync/event-reducer.ts

@@ -8,8 +8,8 @@ import type {
   QuestionRequest,
   Session,
   SessionStatus,
-  FileDiffInfo,
 } from "@opencode-ai/sdk/v2/client"
+import type { SessionDiff } from "@/utils/diffs"
 import type { State, VcsCache } from "./types"
 import { trimSessions } from "./session-trim"
 import { dropSessionCaches } from "./session-cache"
@@ -171,7 +171,7 @@ export function applyDirectoryEvent(input: {
       break
     }
     case "session.diff": {
-      const props = event.properties as { sessionID: string; diff: FileDiffInfo[] }
+      const props = event.properties as { sessionID: string; diff: SessionDiff[] }
       input.setStore("session_diff", props.sessionID, reconcile(list(props.diff), { key: "file" }))
       break
     }

+ 3 - 3
packages/app/src/context/global-sync/session-cache.test.ts

@@ -5,8 +5,8 @@ import type {
   PermissionRequest,
   QuestionRequest,
   SessionStatus,
-  FileDiffInfo,
 } from "@opencode-ai/sdk/v2/client"
+import type { SessionDiff } from "@/utils/diffs"
 import { dropSessionCaches, pickSessionCacheEvictions } from "./session-cache"
 
 const msg = (id: string, sessionID: string) =>
@@ -32,7 +32,7 @@ describe("app session cache", () => {
   test("dropSessionCaches clears orphaned parts without message rows", () => {
     const store: {
       session_status: Record<string, SessionStatus | undefined>
-      session_diff: Record<string, FileDiffInfo[] | undefined>
+      session_diff: Record<string, SessionDiff[] | undefined>
       message: Record<string, Message[] | undefined>
       part: Record<string, Part[] | undefined>
       permission: Record<string, PermissionRequest[] | undefined>
@@ -63,7 +63,7 @@ describe("app session cache", () => {
     const m = msg("msg_1", "ses_1")
     const store: {
       session_status: Record<string, SessionStatus | undefined>
-      session_diff: Record<string, FileDiffInfo[] | undefined>
+      session_diff: Record<string, SessionDiff[] | undefined>
       message: Record<string, Message[] | undefined>
       part: Record<string, Part[] | undefined>
       permission: Record<string, PermissionRequest[] | undefined>

+ 2 - 2
packages/app/src/context/global-sync/session-cache.ts

@@ -4,14 +4,14 @@ import type {
   PermissionRequest,
   QuestionRequest,
   SessionStatus,
-  FileDiffInfo,
 } from "@opencode-ai/sdk/v2/client"
+import type { SessionDiff } from "@/utils/diffs"
 
 export const SESSION_CACHE_LIMIT = 40
 
 type SessionCache = {
   session_status: Record<string, SessionStatus | undefined>
-  session_diff: Record<string, FileDiffInfo[] | undefined>
+  session_diff: Record<string, SessionDiff[] | undefined>
   message: Record<string, Message[] | undefined>
   part: Record<string, Part[] | undefined>
   permission: Record<string, PermissionRequest[] | undefined>

+ 2 - 2
packages/app/src/context/global-sync/types.ts

@@ -13,9 +13,9 @@ import type {
   ReferenceInfo,
   Session,
   SessionStatus,
-  FileDiffInfo,
   VcsInfo,
 } from "@opencode-ai/sdk/v2/client"
+import type { SessionDiff } from "@/utils/diffs"
 import { NormalizedProviderListResponse } from "@opencode-ai/session-ui/context"
 import type { Accessor } from "solid-js"
 import type { SetStoreFunction, Store } from "solid-js/store"
@@ -50,7 +50,7 @@ export type State = {
   }
   session_working(id: string): boolean
   session_diff: {
-    [sessionID: string]: FileDiffInfo[]
+    [sessionID: string]: SessionDiff[]
   }
   permission: {
     [sessionID: string]: PermissionRequest[]

+ 11 - 3
packages/app/src/context/server-sdk.tsx

@@ -1,5 +1,5 @@
 import type { OpenCodeEvent } from "@opencode-ai/client/promise"
-import type { Event } from "@opencode-ai/sdk/v2/client"
+import type { Event, PermissionRequest } from "@opencode-ai/sdk/v2/client"
 import { createSimpleContext } from "@opencode-ai/ui/context"
 import { createGlobalEmitter } from "@solid-primitives/event-bus"
 import { makeEventListener } from "@solid-primitives/event-listener"
@@ -18,7 +18,15 @@ const isAbortError = (error: unknown) =>
   error !== null && typeof error === "object" && "name" in error && error.name === "AbortError"
 
 const isStreamClosed = (error: unknown, signal?: AbortSignal) => isAbortError(error) || signal?.aborted === true
-export type ServerEvent = Event & { current?: OpenCodeEvent }
+type PermissionEvent = {
+  id: string
+  type: "permission.v2.asked"
+  properties: PermissionRequest
+  current?: OpenCodeEvent
+}
+export type ServerEvent = (Event | PermissionEvent) & {
+  current?: OpenCodeEvent
+}
 type QueuedServerEvent = { directory: string; payload: ServerEvent }
 type CurrentDelta = Extract<
   OpenCodeEvent,
@@ -43,7 +51,7 @@ export function adaptServerEvent(event: OpenCodeEvent): ServerEvent {
             : undefined,
       },
       current: event,
-    } as ServerEvent
+    }
   }
   if (event.type === "permission.v2.replied")
     return { id: event.id, type: "permission.v2.replied", properties: event.data, current: event } as ServerEvent

+ 3 - 3
packages/app/src/context/server-session.ts

@@ -8,8 +8,8 @@ import type {
   QuestionRequest,
   Session,
   SessionStatus,
-  FileDiffInfo,
 } from "@opencode-ai/sdk/v2/client"
+import type { SessionDiff } from "@/utils/diffs"
 import { batch } from "solid-js"
 import { createStore, produce, reconcile } from "solid-js/store"
 import { diffs as cleanDiffs, message as cleanMessage } from "@/utils/diffs"
@@ -140,7 +140,7 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
   const [data, setData] = createStore({
     info: {} as Record<string, Session | undefined>,
     session_status: {} as Record<string, SessionStatus>,
-    session_diff: {} as Record<string, FileDiffInfo[]>,
+    session_diff: {} as Record<string, SessionDiff[]>,
     permission: {} as Record<string, PermissionRequest[]>,
     question: {} as Record<string, QuestionRequest[]>,
     message: {} as Record<string, Message[]>,
@@ -773,7 +773,7 @@ export function createServerSession(client: OpencodeClient, options?: { retry?:
         return
       }
       case "session.diff": {
-        const props = event.properties as { sessionID: string; diff: FileDiffInfo[] }
+        const props = event.properties as { sessionID: string; diff: SessionDiff[] }
         setData("session_diff", props.sessionID, reconcile(cleanDiffs(props.diff), { key: "file" }))
         return
       }

+ 2 - 7
packages/app/src/pages/session.tsx

@@ -909,13 +909,8 @@ export default function Page() {
   )
 
   const stopVcs = sdk().event.listen((evt) => {
-    if (evt.details.type !== "filesystem.changed") return
-    const props =
-      typeof evt.details.properties === "object" && evt.details.properties
-        ? (evt.details.properties as Record<string, unknown>)
-        : undefined
-    const file = typeof props?.file === "string" ? props.file : undefined
-    if (!file || file.startsWith(".git/")) return
+    if (evt.details.type !== "file.watcher.updated") return
+    if (evt.details.properties.file.startsWith(".git/")) return
     refreshVcs()
   })
   onCleanup(stopVcs)

+ 3 - 2
packages/app/src/pages/session/review-tab.tsx

@@ -1,6 +1,7 @@
 import { createEffect, onCleanup, type JSX } from "solid-js"
 import { makeEventListener } from "@solid-primitives/event-listener"
-import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { SessionDiff } from "@/utils/diffs"
 import { SessionReview } from "@opencode-ai/session-ui/session-review"
 import type {
   SessionReviewCommentActions,
@@ -14,7 +15,7 @@ import type { LineComment } from "@/context/comments"
 
 export type DiffStyle = "unified" | "split"
 
-type ReviewDiff = FileDiffInfo | VcsFileDiff
+type ReviewDiff = SessionDiff | VcsFileDiff
 
 export interface SessionReviewTabProps {
   title?: JSX.Element

+ 3 - 2
packages/app/src/pages/session/session-side-panel.tsx

@@ -23,7 +23,8 @@ import { Mark } from "@opencode-ai/ui/logo"
 import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2"
 import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2"
 import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
-import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { SessionDiff } from "@/utils/diffs"
 import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd"
 import { useDialog } from "@opencode-ai/ui/context/dialog"
 
@@ -59,7 +60,7 @@ import type { RenderDiff } from "@/pages/session/v2/review-diff-kinds"
 
 export function SessionSidePanel(props: {
   canReview: () => boolean
-  diffs: () => (FileDiffInfo | VcsFileDiff)[]
+  diffs: () => (SessionDiff | VcsFileDiff)[]
   diffsReady: () => boolean
   empty: () => string
   hasReview: () => boolean

+ 3 - 2
packages/app/src/pages/session/v2/review-diff-kinds.ts

@@ -1,8 +1,9 @@
-import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { SessionDiff } from "@/utils/diffs"
 import type { Kind } from "@/components/file-tree-v2"
 import { normalizeFileTreeV2Path } from "@/components/file-tree-v2-model"
 
-export type RenderDiff = FileDiffInfo | VcsFileDiff
+export type RenderDiff = SessionDiff | VcsFileDiff
 
 export function normalizePath(p: string) {
   return normalizeFileTreeV2Path(p)

+ 3 - 2
packages/app/src/pages/session/v2/review-panel-v2.tsx

@@ -1,5 +1,6 @@
 import { createMemo, createResource, createSignal, Show, type JSX } from "solid-js"
-import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { SessionDiff } from "@/utils/diffs"
 import {
   SESSION_REVIEW_V2_SIDEBAR_WIDTH_MAX,
   SESSION_REVIEW_V2_SIDEBAR_WIDTH_MIN,
@@ -29,7 +30,7 @@ import {
 import type { ReviewPanelV2State } from "@/pages/session/v2/review-panel-v2-state"
 import { applyFileListKeyDown, SessionFileListV2 } from "@/pages/session/v2/session-file-list-v2"
 
-type ReviewDiff = FileDiffInfo | VcsFileDiff
+type ReviewDiff = SessionDiff | VcsFileDiff
 
 export type ReviewPanelV2Props = {
   title?: JSX.Element

+ 2 - 2
packages/app/src/utils/diffs.test.ts

@@ -1,5 +1,5 @@
 import { describe, expect, test } from "bun:test"
-import type { FileDiffInfo } from "@opencode-ai/sdk/v2"
+import type { SnapshotFileDiff } from "@opencode-ai/sdk/v2"
 import type { Message } from "@opencode-ai/sdk/v2/client"
 import { diffs, message } from "./diffs"
 
@@ -9,7 +9,7 @@ const item = {
   additions: 1,
   deletions: 1,
   status: "modified",
-} satisfies FileDiffInfo
+} satisfies SnapshotFileDiff
 
 describe("diffs", () => {
   test("keeps valid arrays", () => {

+ 4 - 4
packages/app/src/utils/diffs.ts

@@ -1,9 +1,9 @@
-import type { FileDiffInfo } from "@opencode-ai/sdk/v2"
+import type { SnapshotFileDiff } from "@opencode-ai/sdk/v2"
 import type { Message } from "@opencode-ai/sdk/v2/client"
 
-type Diff = FileDiffInfo
+export type SessionDiff = SnapshotFileDiff & { file: string; patch: string }
 
-function diff(value: unknown): value is Diff {
+function diff(value: unknown): value is SessionDiff {
   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
@@ -17,7 +17,7 @@ function object(value: unknown): value is Record<string, unknown> {
   return !!value && typeof value === "object" && !Array.isArray(value)
 }
 
-export function diffs(value: unknown): Diff[] {
+export function diffs(value: unknown): SessionDiff[] {
   if (Array.isArray(value) && value.every(diff)) return value
   if (Array.isArray(value)) return value.filter(diff)
   if (diff(value)) return [value]

+ 4 - 2
packages/enterprise/src/core/share.ts

@@ -1,4 +1,4 @@
-import { FileDiffInfo, Message, Model, Part, Session } from "@opencode-ai/sdk/v2"
+import { Message, Model, Part, Session, SnapshotFileDiff } from "@opencode-ai/sdk/v2"
 import { iife } from "@opencode-ai/core/util/iife"
 import z from "zod"
 import { Storage } from "./storage"
@@ -8,6 +8,8 @@ function fn<T extends z.ZodType, Result>(schema: T, cb: (input: z.infer<T>) => R
 }
 
 export namespace Share {
+  export type SessionDiff = SnapshotFileDiff & { file: string; patch: string }
+
   export const Info = z.object({
     id: z.string(),
     secret: z.string(),
@@ -30,7 +32,7 @@ export namespace Share {
     }),
     z.object({
       type: z.literal("session_diff"),
-      data: z.custom<FileDiffInfo[]>(),
+      data: z.custom<SessionDiff[]>(),
     }),
     z.object({
       type: z.literal("model"),

+ 2 - 2
packages/enterprise/src/routes/share/[shareID].tsx

@@ -1,4 +1,4 @@
-import { FileDiffInfo, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2"
+import { Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2"
 import { SessionTurn } from "@opencode-ai/session-ui/session-turn"
 import { SessionReview } from "@opencode-ai/session-ui/session-review"
 import { DataProvider } from "@opencode-ai/session-ui/context"
@@ -65,7 +65,7 @@ const getData = query(async (shareID) => {
     shareID: string
     session: Session[]
     session_diff: {
-      [sessionID: string]: FileDiffInfo[]
+      [sessionID: string]: Share.SessionDiff[]
     }
     session_status: {
       [sessionID: string]: SessionStatus

+ 2 - 2
packages/session-ui/src/components/session-diff.ts

@@ -1,6 +1,6 @@
 import { parseDiffFromFile, parsePatchFiles, type FileDiffMetadata } from "@pierre/diffs"
 import { parsePatch } from "diff"
-import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2"
 
 type LegacyDiff = {
   file: string
@@ -12,7 +12,7 @@ type LegacyDiff = {
   status?: "added" | "deleted" | "modified"
 }
 
-type ReviewDiff = FileDiffInfo | VcsFileDiff | LegacyDiff
+type ReviewDiff = (SnapshotFileDiff | VcsFileDiff | LegacyDiff) & { file: string }
 export type DiffSource = Pick<LegacyDiff, "file" | "patch" | "before" | "after">
 
 export type ViewDiff = {

+ 5 - 3
packages/session-ui/src/components/session-review.tsx

@@ -15,7 +15,7 @@ import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
 import { checksum } from "@opencode-ai/core/util/encode"
 import { createEffect, createMemo, For, Match, onCleanup, Show, Switch, untrack, type JSX } from "solid-js"
 import { createStore } from "solid-js/store"
-import { type FileContent, type FileDiffInfo, type VcsFileDiff } from "@opencode-ai/sdk/v2"
+import { type FileContent, type SnapshotFileDiff, type VcsFileDiff } from "@opencode-ai/sdk/v2"
 import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
 import { type SelectedLineRange } from "@pierre/diffs"
 import { Dynamic } from "solid-js/web"
@@ -62,10 +62,12 @@ export type SessionReviewCommentActions = {
 
 export type SessionReviewFocus = { file: string; id: string }
 
-type RawReviewDiff = (FileDiffInfo | VcsFileDiff) & {
+type RawReviewDiff = (SnapshotFileDiff | VcsFileDiff) & {
+  file: string
   preloaded?: PreloadMultiFileDiffResult<any>
 }
-type ReviewDiff = (FileDiffInfo | VcsFileDiff) & {
+type ReviewDiff = (SnapshotFileDiff | VcsFileDiff) & {
+  file: string
   preloaded?: PreloadMultiFileDiffResult<any>
 }
 function diff(value: unknown): value is ReviewDiff {

+ 2 - 2
packages/session-ui/src/components/session-turn.tsx

@@ -1,6 +1,6 @@
 import {
   AssistantMessage,
-  type FileDiffInfo,
+  type SnapshotFileDiff,
   Message as MessageType,
   Part as PartType,
   type UserMessage,
@@ -92,7 +92,7 @@ function list<T>(value: T[] | undefined | null, fallback: T[]) {
 }
 
 type SummaryDiffInput = NonNullable<NonNullable<UserMessage["summary"]>["diffs"]>[number]
-type SummaryDiff = FileDiffInfo
+type SummaryDiff = SnapshotFileDiff & { file: string; patch: string }
 
 function summaryDiff(value: SummaryDiffInput): value is SummaryDiff {
   return (

+ 2 - 2
packages/session-ui/src/context/data.tsx

@@ -1,4 +1,4 @@
-import type { FileDiffInfo, Message, Part, Provider, Session, SessionStatus } from "@opencode-ai/sdk/v2"
+import type { Message, Part, Provider, Session, SessionStatus, SnapshotFileDiff } from "@opencode-ai/sdk/v2"
 import { createSimpleContext } from "@opencode-ai/ui/context"
 import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
 
@@ -21,7 +21,7 @@ type Data = {
     [sessionID: string]: SessionStatus
   }
   session_diff: {
-    [sessionID: string]: FileDiffInfo[]
+    [sessionID: string]: SnapshotFileDiff[]
   }
   session_diff_preload?: {
     [sessionID: string]: PreloadMultiFileDiffResult<any>[]

+ 2 - 2
packages/session-ui/src/v2/components/session-review-file-preview-v2.tsx

@@ -6,7 +6,7 @@ import { useFileComponent } from "@opencode-ai/ui/context/file"
 import { useI18n } from "@opencode-ai/ui/context/i18n"
 import { mediaKindFromPath } from "../../pierre/media"
 import { cloneSelectedLineRange, previewSelectedLines } from "../../pierre/selection-bridge"
-import type { FileContent, FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
+import type { FileContent, SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2"
 import { createEffect, createMemo, onCleanup, Show, untrack } from "solid-js"
 import { createStore } from "solid-js/store"
 import { Dynamic } from "solid-js/web"
@@ -27,7 +27,7 @@ import { LineCommentV2OverflowIcon } from "@opencode-ai/ui/v2/line-comment-v2"
 import { MenuV2 } from "@opencode-ai/ui/v2/menu-v2"
 import "./session-review-v2.css"
 
-type ReviewDiff = FileDiffInfo | VcsFileDiff
+type ReviewDiff = (SnapshotFileDiff | VcsFileDiff) & { file: string }
 
 export type SessionReviewFilePreviewV2Props = {
   file: string