diff --git a/packages/ui/src/components/instance/instance-shell2.tsx b/packages/ui/src/components/instance/instance-shell2.tsx index ab8cbfb3..c0ad2ad6 100644 --- a/packages/ui/src/components/instance/instance-shell2.tsx +++ b/packages/ui/src/components/instance/instance-shell2.tsx @@ -136,7 +136,6 @@ const InstanceShell2: Component = (props) => { activeSessions, activeSessionIdForInstance, activeSessionForInstance, - activeSessionDiffs, latestTodoState, tokenStats, backgroundProcessList, @@ -759,7 +758,6 @@ const InstanceShell2: Component = (props) => { instance={props.instance} activeSessionId={activeSessionIdForInstance} activeSession={activeSessionForInstance} - activeSessionDiffs={activeSessionDiffs} latestTodoState={latestTodoState} backgroundProcessList={backgroundProcessList} onOpenBackgroundOutput={openBackgroundOutput} @@ -828,7 +826,6 @@ const InstanceShell2: Component = (props) => { instance={props.instance} activeSessionId={activeSessionIdForInstance} activeSession={activeSessionForInstance} - activeSessionDiffs={activeSessionDiffs} latestTodoState={latestTodoState} backgroundProcessList={backgroundProcessList} onOpenBackgroundOutput={openBackgroundOutput} diff --git a/packages/ui/src/components/instance/shell/right-panel/RightPanel.tsx b/packages/ui/src/components/instance/shell/right-panel/RightPanel.tsx index 874bc6da..231c1834 100644 --- a/packages/ui/src/components/instance/shell/right-panel/RightPanel.tsx +++ b/packages/ui/src/components/instance/shell/right-panel/RightPanel.tsx @@ -41,10 +41,7 @@ import { RIGHT_PANEL_CHANGES_DIFF_CONTEXT_MODE_KEY, RIGHT_PANEL_CHANGES_DIFF_VIEW_MODE_KEY, RIGHT_PANEL_CHANGES_DIFF_WORD_WRAP_KEY, - RIGHT_PANEL_CHANGES_LIST_OPEN_NONPHONE_KEY, - RIGHT_PANEL_CHANGES_LIST_OPEN_PHONE_KEY, RIGHT_PANEL_FILES_WORD_WRAP_KEY, - RIGHT_PANEL_CHANGES_SPLIT_WIDTH_KEY, RIGHT_PANEL_FILES_LIST_OPEN_NONPHONE_KEY, RIGHT_PANEL_FILES_LIST_OPEN_PHONE_KEY, RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY, @@ -62,7 +59,6 @@ import { readStoredRightPanelTab, } from "../storage" -const LazyChangesTab = lazy(() => import("./tabs/ChangesTab")) const LazyGitChangesTab = lazy(() => import("./tabs/GitChangesTab")) const LazyFilesTab = lazy(() => import("./tabs/FilesTab")) const LazyStatusTab = lazy(() => import("./tabs/StatusTab")) @@ -79,7 +75,6 @@ interface RightPanelProps { activeSessionId: Accessor activeSession: Accessor - activeSessionDiffs: Accessor latestTodoState: Accessor backgroundProcessList: Accessor @@ -101,10 +96,9 @@ interface RightPanelProps { } const RightPanel: Component = (props) => { - const [rightPanelTab, setRightPanelTab] = createSignal(readStoredRightPanelTab("changes")) - const defaultStatusSectionIds = ["yolo-mode", "session-changes", "plan", "background-processes", "mcp", "lsp", "plugins"] + const [rightPanelTab, setRightPanelTab] = createSignal(readStoredRightPanelTab("git-changes")) + const defaultStatusSectionIds = ["yolo-mode", "plan", "background-processes", "mcp", "lsp", "plugins"] const [rightPanelExpandedItems, setRightPanelExpandedItems] = createSignal(defaultStatusSectionIds) - const [selectedFile, setSelectedFile] = createSignal(null) const [browserPath, setBrowserPath] = createSignal(".") const [browserEntries, setBrowserEntries] = createSignal(null) @@ -131,17 +125,14 @@ const RightPanel: Component = (props) => { readStoredEnum(RIGHT_PANEL_FILES_WORD_WRAP_KEY, ["on", "off"] as const) ?? "off", ) - const [changesSplitWidth, setChangesSplitWidth] = createSignal(320) const [filesSplitWidth, setFilesSplitWidth] = createSignal(320) const [gitChangesSplitWidth, setGitChangesSplitWidth] = createSignal(320) - const [activeSplitResize, setActiveSplitResize] = createSignal<"changes" | "git-changes" | "files" | null>(null) + const [activeSplitResize, setActiveSplitResize] = createSignal<"git-changes" | "files" | null>(null) const [splitResizeStartX, setSplitResizeStartX] = createSignal(0) const [splitResizeStartWidth, setSplitResizeStartWidth] = createSignal(0) const [filesListOpen, setFilesListOpen] = createSignal(true) const [filesListTouched, setFilesListTouched] = createSignal(false) - const [changesListOpen, setChangesListOpen] = createSignal(true) - const [changesListTouched, setChangesListTouched] = createSignal(false) const [gitChangesListOpen, setGitChangesListOpen] = createSignal(true) const [gitChangesListTouched, setGitChangesListTouched] = createSignal(false) const [gitStagedOpen, setGitStagedOpen] = createSignal(true) @@ -149,11 +140,8 @@ const RightPanel: Component = (props) => { const listLayoutKey = createMemo(() => (props.isPhoneLayout() ? "phone" : "nonphone")) - const listOpenStorageKey = (tab: "changes" | "git-changes" | "files") => { + const listOpenStorageKey = (tab: "git-changes" | "files") => { const layout = listLayoutKey() - if (tab === "changes") { - return layout === "phone" ? RIGHT_PANEL_CHANGES_LIST_OPEN_PHONE_KEY : RIGHT_PANEL_CHANGES_LIST_OPEN_NONPHONE_KEY - } if (tab === "git-changes") { return layout === "phone" ? RIGHT_PANEL_GIT_CHANGES_LIST_OPEN_PHONE_KEY @@ -174,7 +162,7 @@ const RightPanel: Component = (props) => { : RIGHT_PANEL_GIT_CHANGES_UNSTAGED_OPEN_NONPHONE_KEY } - const persistListOpen = (tab: "changes" | "git-changes" | "files", value: boolean) => { + const persistListOpen = (tab: "git-changes" | "files", value: boolean) => { if (typeof window === "undefined") return window.localStorage.setItem(listOpenStorageKey(tab), value ? "true" : "false") } @@ -198,15 +186,6 @@ const RightPanel: Component = (props) => { setFilesListTouched(false) } - const changesPersisted = readStoredBool(listOpenStorageKey("changes")) - if (changesPersisted !== null) { - setChangesListOpen(changesPersisted) - setChangesListTouched(true) - } else { - setChangesListOpen(true) - setChangesListTouched(false) - } - const gitPersisted = readStoredBool(listOpenStorageKey("git-changes")) if (gitPersisted !== null) { setGitChangesListOpen(gitPersisted) @@ -271,19 +250,13 @@ const RightPanel: Component = (props) => { if (splitWidthsInitialized()) return if (!props.rightDrawerWidthInitialized()) return setSplitWidthsInitialized(true) - setChangesSplitWidth(clampSplitWidth(readStoredPanelWidth(RIGHT_PANEL_CHANGES_SPLIT_WIDTH_KEY, 320))) setFilesSplitWidth(clampSplitWidth(readStoredPanelWidth(RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY, 320))) setGitChangesSplitWidth(clampSplitWidth(readStoredPanelWidth(RIGHT_PANEL_GIT_CHANGES_SPLIT_WIDTH_KEY, 320))) }) - const persistSplitWidth = (mode: "changes" | "git-changes" | "files", width: number) => { + const persistSplitWidth = (mode: "git-changes" | "files", width: number) => { if (typeof window === "undefined") return - const key = - mode === "changes" - ? RIGHT_PANEL_CHANGES_SPLIT_WIDTH_KEY - : mode === "git-changes" - ? RIGHT_PANEL_GIT_CHANGES_SPLIT_WIDTH_KEY - : RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY + const key = mode === "git-changes" ? RIGHT_PANEL_GIT_CHANGES_SPLIT_WIDTH_KEY : RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY window.localStorage.setItem(key, String(width)) } @@ -300,16 +273,14 @@ const RightPanel: Component = (props) => { const isRtl = typeof document !== "undefined" && document.documentElement.dir === "rtl" const delta = (event.clientX - splitResizeStartX()) * (isRtl ? -1 : 1) const next = clampSplitWidth(splitResizeStartWidth() + delta) - if (mode === "changes") setChangesSplitWidth(next) - else if (mode === "git-changes") setGitChangesSplitWidth(next) + if (mode === "git-changes") setGitChangesSplitWidth(next) else setFilesSplitWidth(next) } function splitMouseUp() { const mode = activeSplitResize() if (mode) { - const width = - mode === "changes" ? changesSplitWidth() : mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth() + const width = mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth() persistSplitWidth(mode, width) } stopSplitResize() @@ -324,16 +295,14 @@ const RightPanel: Component = (props) => { const isRtl = typeof document !== "undefined" && document.documentElement.dir === "rtl" const delta = (touch.clientX - splitResizeStartX()) * (isRtl ? -1 : 1) const next = clampSplitWidth(splitResizeStartWidth() + delta) - if (mode === "changes") setChangesSplitWidth(next) - else if (mode === "git-changes") setGitChangesSplitWidth(next) + if (mode === "git-changes") setGitChangesSplitWidth(next) else setFilesSplitWidth(next) } function splitTouchEnd() { const mode = activeSplitResize() if (mode) { - const width = - mode === "changes" ? changesSplitWidth() : mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth() + const width = mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth() persistSplitWidth(mode, width) } stopSplitResize() @@ -346,22 +315,20 @@ const RightPanel: Component = (props) => { onTouchEnd: splitTouchEnd, }) - const startSplitResize = (mode: "changes" | "git-changes" | "files", clientX: number) => { + const startSplitResize = (mode: "git-changes" | "files", clientX: number) => { if (typeof document === "undefined") return setActiveSplitResize(mode) setSplitResizeStartX(clientX) - setSplitResizeStartWidth( - mode === "changes" ? changesSplitWidth() : mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth(), - ) + setSplitResizeStartWidth(mode === "git-changes" ? gitChangesSplitWidth() : filesSplitWidth()) splitPointerDrag.start() } - const handleSplitResizeMouseDown = (mode: "changes" | "git-changes" | "files") => (event: MouseEvent) => { + const handleSplitResizeMouseDown = (mode: "git-changes" | "files") => (event: MouseEvent) => { event.preventDefault() startSplitResize(mode, event.clientX) } - const handleSplitResizeTouchStart = (mode: "changes" | "git-changes" | "files") => (event: TouchEvent) => { + const handleSplitResizeTouchStart = (mode: "git-changes" | "files") => (event: TouchEvent) => { const touch = event.touches[0] if (!touch) return event.preventDefault() @@ -444,36 +411,6 @@ const RightPanel: Component = (props) => { setBrowserSelectedLoading(false) }) - const bestDiffFile = createMemo(() => { - const diffs = props.activeSessionDiffs() - if (!Array.isArray(diffs) || diffs.length === 0) return null - const best = diffs.reduce((currentBest, item) => { - const bestAdd = typeof (currentBest as any)?.additions === "number" ? (currentBest as any).additions : 0 - const bestDel = typeof (currentBest as any)?.deletions === "number" ? (currentBest as any).deletions : 0 - const bestScore = bestAdd + bestDel - - const add = typeof (item as any)?.additions === "number" ? (item as any).additions : 0 - const del = typeof (item as any)?.deletions === "number" ? (item as any).deletions : 0 - const score = add + del - - if (score > bestScore) return item - if (score < bestScore) return currentBest - return String(item.file || "").localeCompare(String((currentBest as any)?.file || "")) < 0 ? item : currentBest - }, diffs[0]) - return typeof (best as any)?.file === "string" ? (best as any).file : null - }) - - createEffect(() => { - const next = bestDiffFile() - if (!next) return - const diffs = props.activeSessionDiffs() - if (!Array.isArray(diffs) || diffs.length === 0) return - - const current = selectedFile() - if (current && diffs.some((d) => d.file === current)) return - setSelectedFile(next) - }) - const normalizeBrowserPath = (input: string) => { const raw = String(input || ".").trim() if (!raw || raw === "./") return "." @@ -644,22 +581,6 @@ const RightPanel: Component = (props) => { setBrowserSelectedDirty(false) }) - const handleSelectChangesFile = (file: string, closeList: boolean) => { - setSelectedFile(file) - if (closeList) { - setChangesListOpen(false) - } - } - - const toggleChangesList = () => { - setChangesListTouched(true) - setChangesListOpen((current) => { - const next = !current - persistListOpen("changes", next) - return next - }) - } - const toggleFilesList = () => { setFilesListTouched(true) setFilesListOpen((current) => { @@ -730,13 +651,6 @@ const RightPanel: Component = (props) => { const browserScopeKey = createMemo(() => `${props.instanceId}:${worktreeSlugForViewer()}`) const gitScopeKey = createMemo(() => `${props.instanceId}:git:${worktreeSlugForViewer()}`) - const openChangesTabFromStatus = (file?: string) => { - if (file) { - setSelectedFile(file) - } - setRightPanelTab("changes") - } - const handleAccordionChange = (values: string[]) => { setRightPanelExpandedItems(values) } @@ -774,15 +688,6 @@ const RightPanel: Component = (props) => {
-
- - }> - - - - }> = (props) => { instance={props.instance} activeSessionId={props.activeSessionId} activeSession={props.activeSession} - activeSessionDiffs={props.activeSessionDiffs} latestTodoState={props.latestTodoState} backgroundProcessList={props.backgroundProcessList} onOpenBackgroundOutput={props.onOpenBackgroundOutput} @@ -947,7 +826,6 @@ const RightPanel: Component = (props) => { onTerminateBackgroundProcess={props.onTerminateBackgroundProcess} expandedItems={rightPanelExpandedItems} onExpandedItemsChange={handleAccordionChange} - onOpenChangesTab={openChangesTabFromStatus} /> diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx deleted file mode 100644 index 6f6a5609..00000000 --- a/packages/ui/src/components/instance/shell/right-panel/tabs/ChangesTab.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import { For, Show, Suspense, createMemo, lazy, type Accessor, type Component, type JSX } from "solid-js" - -import DiffToolbar from "../components/DiffToolbar" -import SplitFilePanel from "../components/SplitFilePanel" -import type { DiffContextMode, DiffViewMode, DiffWordWrapMode } from "../types" - -const LazyMonacoDiffViewer = lazy(() => - import("../../../../file-viewer/monaco-diff-viewer").then((module) => ({ default: module.MonacoDiffViewer })), -) - -interface ChangesTabProps { - t: (key: string, vars?: Record) => string - - instanceId: string - activeSessionId: Accessor - activeSessionDiffs: Accessor - - selectedFile: Accessor - onSelectFile: (file: string, closeList: boolean) => void - - diffViewMode: Accessor - diffContextMode: Accessor - diffWordWrapMode: Accessor - onViewModeChange: (mode: DiffViewMode) => void - onContextModeChange: (mode: DiffContextMode) => void - onWordWrapModeChange: (mode: DiffWordWrapMode) => void - - listOpen: Accessor - onToggleList: () => void - splitWidth: Accessor - onResizeMouseDown: (event: MouseEvent) => void - onResizeTouchStart: (event: TouchEvent) => void - isPhoneLayout: Accessor -} - -const ChangesTab: Component = (props) => { - const sessionId = createMemo(() => props.activeSessionId()) - const hasSession = createMemo(() => Boolean(sessionId() && sessionId() !== "info")) - const diffs = createMemo(() => (hasSession() ? props.activeSessionDiffs() : null)) - - const sorted = createMemo(() => { - const list = diffs() - if (!Array.isArray(list)) return [] - return [...list].sort((a, b) => String(a.file || "").localeCompare(String(b.file || ""))) - }) - - const totals = createMemo(() => { - return sorted().reduce( - (acc, item) => { - acc.additions += typeof item.additions === "number" ? item.additions : 0 - acc.deletions += typeof item.deletions === "number" ? item.deletions : 0 - return acc - }, - { additions: 0, deletions: 0 }, - ) - }) - - const mostChanged = createMemo(() => { - const items = sorted() - if (items.length === 0) return null - return items.reduce((best, item) => { - const bestAdd = typeof (best as any)?.additions === "number" ? (best as any).additions : 0 - const bestDel = typeof (best as any)?.deletions === "number" ? (best as any).deletions : 0 - const bestScore = bestAdd + bestDel - - const add = typeof (item as any)?.additions === "number" ? (item as any).additions : 0 - const del = typeof (item as any)?.deletions === "number" ? (item as any).deletions : 0 - const score = add + del - - if (score > bestScore) return item - if (score < bestScore) return best - return String(item.file || "").localeCompare(String((best as any)?.file || "")) < 0 ? item : best - }, items[0]) - }) - - const selectedFileData = createMemo(() => { - const currentSelected = props.selectedFile() - const items = sorted() - if (currentSelected) { - const match = items.find((f) => f.file === currentSelected) - if (match) return match - } - return mostChanged() - }) - - const scopeKey = createMemo(() => `${props.instanceId}:${hasSession() ? sessionId() : "no-session"}`) - - const emptyViewerMessage = createMemo(() => { - if (!hasSession()) return props.t("instanceShell.sessionChanges.noSessionSelected") - const currentDiffs = diffs() - if (currentDiffs === undefined) return props.t("instanceShell.sessionChanges.loading") - if (!Array.isArray(currentDiffs) || currentDiffs.length === 0) return props.t("instanceShell.sessionChanges.empty") - return props.t("instanceShell.filesShell.viewerEmpty") - }) - - const headerPath = createMemo(() => { - const file = selectedFileData() - return file?.file ? String(file.file) : props.t("instanceShell.rightPanel.tabs.changes") - }) - - const renderContent = (): JSX.Element => { - const sortedList = sorted() - const totalsValue = totals() - const selected = selectedFileData() - - const renderViewer = () => ( -
-
- 0 ? selected : null} - fallback={ -
- {emptyViewerMessage()} -
- } - > - {(file) => ( - - {props.t("instanceInfo.loading")} -
- } - > - - - )} - -
-
- ) - - const renderEmptyList = () => ( -
{emptyViewerMessage()}
- ) - - const renderListPanel = () => ( - 0} fallback={renderEmptyList()}> - - {(item) => ( -
{ - props.onSelectFile(item.file, props.isPhoneLayout()) - }} - > -
-
- {item.file} -
-
- +{item.additions} - -{item.deletions} -
-
-
- )} -
-
- ) - - const renderListOverlay = () => ( - 0} fallback={renderEmptyList()}> - - {(item) => ( -
{ - props.onSelectFile(item.file, true) - }} - title={item.file} - > -
-
- {item.file} -
-
- +{item.additions} - -{item.deletions} -
-
-
- )} -
-
- ) - - return ( - - - {headerPath()} - - -
- - +{totalsValue.additions} - - - -{totalsValue.deletions} - -
- -
- -
- - } - list={{ panel: renderListPanel, overlay: renderListOverlay }} - viewer={renderViewer()} - listOpen={props.listOpen()} - onToggleList={props.onToggleList} - splitWidth={props.splitWidth()} - onResizeMouseDown={props.onResizeMouseDown} - onResizeTouchStart={props.onResizeTouchStart} - isPhoneLayout={props.isPhoneLayout()} - overlayAriaLabel={props.t("instanceShell.rightPanel.tabs.changes")} - /> - ) - } - - return <>{renderContent()} -} - -export default ChangesTab diff --git a/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx b/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx index 7be3284c..8dca954c 100644 --- a/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx +++ b/packages/ui/src/components/instance/shell/right-panel/tabs/StatusTab.tsx @@ -24,7 +24,6 @@ interface StatusTabProps { activeSessionId: Accessor activeSession: Accessor - activeSessionDiffs: Accessor latestTodoState: Accessor @@ -36,7 +35,6 @@ interface StatusTabProps { expandedItems: Accessor onExpandedItemsChange: (values: string[]) => void - onOpenChangesTab: (file?: string) => void } const StatusTab: Component = (props) => { @@ -71,85 +69,6 @@ const StatusTab: Component = (props) => { ) } - const renderStatusSessionChanges = () => { - const sessionId = props.activeSessionId() - if (!sessionId || sessionId === "info") { - return ( -
- {props.t("instanceShell.sessionChanges.noSessionSelected")} -
- ) - } - - const diffs = props.activeSessionDiffs() - if (diffs === undefined) { - return ( -
- {props.t("instanceShell.sessionChanges.loading")} -
- ) - } - - if (!Array.isArray(diffs) || diffs.length === 0) { - return ( -
- {props.t("instanceShell.sessionChanges.empty")} -
- ) - } - - const sorted = [...diffs].sort((a, b) => String(a.file || "").localeCompare(String(b.file || ""))) - const totals = sorted.reduce( - (acc, item) => { - acc.additions += typeof item.additions === "number" ? item.additions : 0 - acc.deletions += typeof item.deletions === "number" ? item.deletions : 0 - return acc - }, - { additions: 0, deletions: 0 }, - ) - - return ( -
-
- {props.t("instanceShell.sessionChanges.filesChanged", { count: sorted.length })} - - {`+${totals.additions}`} - {`-${totals.deletions}`} - -
- -
-
- - {(item) => ( - - )} - -
-
-
- ) - } - const renderPlanSectionContent = () => { const sessionId = props.activeSessionId() if (!sessionId || sessionId === "info") { @@ -260,12 +179,6 @@ const StatusTab: Component = (props) => { tooltipKey: "instanceShell.rightPanel.sections.yoloMode.tooltip", render: renderYoloModeSection, }, - { - id: "session-changes", - labelKey: "instanceShell.rightPanel.sections.sessionChanges", - tooltipKey: "instanceShell.rightPanel.sections.sessionChanges.tooltip", - render: renderStatusSessionChanges, - }, { id: "plan", labelKey: "instanceShell.rightPanel.sections.plan", diff --git a/packages/ui/src/components/instance/shell/right-panel/types.ts b/packages/ui/src/components/instance/shell/right-panel/types.ts index a651383a..aa407b6e 100644 --- a/packages/ui/src/components/instance/shell/right-panel/types.ts +++ b/packages/ui/src/components/instance/shell/right-panel/types.ts @@ -1,4 +1,4 @@ -export type RightPanelTab = "changes" | "git-changes" | "files" | "status" +export type RightPanelTab = "git-changes" | "files" | "status" export type DiffViewMode = "split" | "unified" diff --git a/packages/ui/src/components/instance/shell/right-panel/useGitChanges.ts b/packages/ui/src/components/instance/shell/right-panel/useGitChanges.ts index dabdd1c9..de189989 100644 --- a/packages/ui/src/components/instance/shell/right-panel/useGitChanges.ts +++ b/packages/ui/src/components/instance/shell/right-panel/useGitChanges.ts @@ -431,7 +431,7 @@ export function useGitChanges(options: UseGitChangesOptions) { if (event.type !== "instance.event") return if (event.instanceId !== options.instanceId) return const eventType = (event.event as { type?: unknown } | undefined)?.type - if (eventType !== "session.updated" && eventType !== "session.diff") return + if (eventType !== "session.updated") return void passiveRefreshGitStatus({ forceReloadSelectedDiff: true }) }) diff --git a/packages/ui/src/components/instance/shell/storage.ts b/packages/ui/src/components/instance/shell/storage.ts index 963f4838..f50b5f4c 100644 --- a/packages/ui/src/components/instance/shell/storage.ts +++ b/packages/ui/src/components/instance/shell/storage.ts @@ -12,11 +12,8 @@ export const LEFT_PIN_STORAGE_KEY = "opencode-session-left-drawer-pinned-v1" export const RIGHT_PIN_STORAGE_KEY = "opencode-session-right-drawer-pinned-v1" export const RIGHT_PANEL_TAB_STORAGE_KEY = "opencode-session-right-panel-tab-v2" export const LEGACY_RIGHT_PANEL_TAB_STORAGE_KEY = "opencode-session-right-panel-tab-v1" -export const RIGHT_PANEL_CHANGES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-changes-split-width-v1" export const RIGHT_PANEL_FILES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-files-split-width-v1" export const RIGHT_PANEL_GIT_CHANGES_SPLIT_WIDTH_KEY = "opencode-session-right-panel-git-changes-split-width-v1" -export const RIGHT_PANEL_CHANGES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-changes-list-open-nonphone-v1" -export const RIGHT_PANEL_CHANGES_LIST_OPEN_PHONE_KEY = "opencode-session-right-panel-changes-list-open-phone-v1" export const RIGHT_PANEL_FILES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-files-list-open-nonphone-v1" export const RIGHT_PANEL_FILES_LIST_OPEN_PHONE_KEY = "opencode-session-right-panel-files-list-open-phone-v1" export const RIGHT_PANEL_GIT_CHANGES_LIST_OPEN_NONPHONE_KEY = "opencode-session-right-panel-git-changes-list-open-nonphone-v1" @@ -55,13 +52,13 @@ export function persistPinState(side: "left" | "right", value: boolean) { } export function readStoredRightPanelTab( - defaultValue: "changes" | "git-changes" | "files" | "status", -): "changes" | "git-changes" | "files" | "status" { + defaultValue: "git-changes" | "files" | "status", +): "git-changes" | "files" | "status" { if (typeof window === "undefined") return defaultValue const stored = window.localStorage.getItem(RIGHT_PANEL_TAB_STORAGE_KEY) if (stored === "status") return "status" - if (stored === "changes") return "changes" + if (stored === "changes") return "git-changes" if (stored === "git-changes") return "git-changes" if (stored === "files") return "files" @@ -69,7 +66,7 @@ export function readStoredRightPanelTab( const legacy = window.localStorage.getItem(LEGACY_RIGHT_PANEL_TAB_STORAGE_KEY) if (legacy === "status") return "status" if (legacy === "browser") return "files" - if (legacy === "files") return "changes" + if (legacy === "files") return "git-changes" return defaultValue } diff --git a/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts b/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts index 5eb98bf2..9b84ba86 100644 --- a/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts +++ b/packages/ui/src/components/instance/shell/useInstanceSessionContext.ts @@ -27,7 +27,6 @@ type InstanceSessionContextState = { activeSessionIdForInstance: Accessor parentSessionIdForInstance: Accessor activeSessionForInstance: Accessor - activeSessionDiffs: Accessor // Usage / info summaries activeSessionUsage: Accessor @@ -77,11 +76,6 @@ export function useInstanceSessionContext(options: InstanceSessionContextOptions return activeSessions().get(sessionId) ?? null }) - const activeSessionDiffs = createMemo(() => { - const session = activeSessionForInstance() - return session?.diff - }) - const activeSessionUsage = createMemo(() => { const sessionId = activeSessionIdForInstance() if (!sessionId) return null @@ -161,7 +155,6 @@ export function useInstanceSessionContext(options: InstanceSessionContextOptions activeSessionIdForInstance, parentSessionIdForInstance, activeSessionForInstance, - activeSessionDiffs, activeSessionUsage, activeSessionInfoDetails, tokenStats, diff --git a/packages/ui/src/lib/i18n/messages/de/instance.ts b/packages/ui/src/lib/i18n/messages/de/instance.ts index b32ab4f6..02cd77ea 100644 --- a/packages/ui/src/lib/i18n/messages/de/instance.ts +++ b/packages/ui/src/lib/i18n/messages/de/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "Senden Sie eine Nachricht, um eine neue Sitzung zu erstellen, oder wählen Sie eine bestehende Sitzung aus.", "instanceShell.rightPanel.title": "Status-Panel", - "instanceShell.rightPanel.tabs.changes": "Sitzungsänderungen", "instanceShell.rightPanel.tabs.gitChanges": "Git-Änderungen", "instanceShell.rightPanel.tabs.files": "Dateien", "instanceShell.rightPanel.tabs.status": "Status", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "Datei konnte nicht gespeichert werden", "instanceShell.rightPanel.sections.yoloMode": "Yolo-Modus", "instanceShell.rightPanel.sections.yoloMode.tooltip": "Genehmigt Berechtigungsanfragen für die aktuelle Sitzung automatisch. Nur verwenden, wenn Sie den ausgeführten Tools vertrauen.", - "instanceShell.rightPanel.sections.sessionChanges": "Sitzungsänderungen", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "In der aktuellen Sitzung geänderte Dateien. Zeigt Hinzufügungen und Löschungen für jede Datei.", "instanceShell.rightPanel.sections.plan": "Plan", "instanceShell.rightPanel.sections.plan.tooltip": "Die Roadmap des Agenten für diese Sitzung. Verfolgt Aufgaben, Unteraufgaben und deren Abschlussstatus.", "instanceShell.rightPanel.sections.backgroundProcesses": "Hintergrund-Shells", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "Plugins", "instanceShell.rightPanel.sections.plugins.tooltip": "Plugins, die die Benutzeroberfläche und das Serververhalten anpassen.", - "instanceShell.sessionChanges.noSessionSelected": "Wählen Sie eine Sitzung aus, um Änderungen zu sehen.", - "instanceShell.sessionChanges.loading": "Sitzungsänderungen werden abgerufen...", - "instanceShell.sessionChanges.empty": "Noch keine Sitzungsänderungen.", - "instanceShell.sessionChanges.filesChanged": "{count} Dateien geändert", - "instanceShell.sessionChanges.actions.show": "Änderungen anzeigen", - "instanceShell.gitChanges.noSessionSelected": "Wählen Sie eine Sitzung aus, um Git-Änderungen zu sehen.", "instanceShell.gitChanges.loading": "Git-Änderungen werden geladen...", "instanceShell.gitChanges.empty": "Noch keine Git-Änderungen.", diff --git a/packages/ui/src/lib/i18n/messages/en/instance.ts b/packages/ui/src/lib/i18n/messages/en/instance.ts index 153adaa4..efcff08e 100644 --- a/packages/ui/src/lib/i18n/messages/en/instance.ts +++ b/packages/ui/src/lib/i18n/messages/en/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "Send a message below to create a new session, or select an existing session to continue.", "instanceShell.rightPanel.title": "Status Panel", - "instanceShell.rightPanel.tabs.changes": "Session Changes", "instanceShell.rightPanel.tabs.gitChanges": "Git Changes", "instanceShell.rightPanel.tabs.files": "Files", "instanceShell.rightPanel.tabs.status": "Status", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "Failed to save file", "instanceShell.rightPanel.sections.yoloMode": "Yolo Mode", "instanceShell.rightPanel.sections.yoloMode.tooltip": "Automatically approves permission requests for the current session. Use it only when you trust the tools being run.", - "instanceShell.rightPanel.sections.sessionChanges": "Session Changes", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "Files modified in the current session. Shows additions and deletions for each file.", "instanceShell.rightPanel.sections.plan": "Plan", "instanceShell.rightPanel.sections.plan.tooltip": "The agent's roadmap for this session. Tracks tasks, subtasks, and their completion status.", "instanceShell.rightPanel.sections.backgroundProcesses": "Background Shells", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "Plugins", "instanceShell.rightPanel.sections.plugins.tooltip": "Plugins that customize the UI and server behavior, adding features beyond MCP and LSP.", - "instanceShell.sessionChanges.noSessionSelected": "Select a session to view changes.", - "instanceShell.sessionChanges.loading": "Fetching session changes...", - "instanceShell.sessionChanges.empty": "No session changes yet.", - "instanceShell.sessionChanges.filesChanged": "{count} files changed", - "instanceShell.sessionChanges.actions.show": "Show changes", - "instanceShell.gitChanges.noSessionSelected": "Select a session to view git changes.", "instanceShell.gitChanges.loading": "Loading git changes...", "instanceShell.gitChanges.empty": "No git changes yet.", diff --git a/packages/ui/src/lib/i18n/messages/es/instance.ts b/packages/ui/src/lib/i18n/messages/es/instance.ts index f01aa8de..f98dc974 100644 --- a/packages/ui/src/lib/i18n/messages/es/instance.ts +++ b/packages/ui/src/lib/i18n/messages/es/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "Envía un mensaje abajo para crear una nueva sesión, o selecciona una sesión existente para continuar.", "instanceShell.rightPanel.title": "Panel de estado", - "instanceShell.rightPanel.tabs.changes": "Cambios", "instanceShell.rightPanel.tabs.gitChanges": "Cambios de Git", "instanceShell.rightPanel.tabs.files": "Archivos", "instanceShell.rightPanel.tabs.status": "Estado", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "Error al guardar el archivo", "instanceShell.rightPanel.sections.yoloMode": "Modo yolo", "instanceShell.rightPanel.sections.yoloMode.tooltip": "Aprueba automaticamente las solicitudes de permiso de la sesion actual. Usalo solo si confias en las herramientas que se estan ejecutando.", - "instanceShell.rightPanel.sections.sessionChanges": "Cambios de sesión", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "Archivos modificados en la sesión actual. Muestra las adiciones y eliminaciones de cada archivo.", "instanceShell.rightPanel.sections.plan": "Plan", "instanceShell.rightPanel.sections.plan.tooltip": "Hoja de ruta del agente para esta sesión. Realiza el seguimiento de tareas, subtareas y su estado de finalización.", "instanceShell.rightPanel.sections.backgroundProcesses": "Shells en segundo plano", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "Plugins", "instanceShell.rightPanel.sections.plugins.tooltip": "Plugins que personalizan el comportamiento de la UI y del servidor, y añaden funciones más allá de MCP y LSP.", - "instanceShell.sessionChanges.noSessionSelected": "Selecciona una sesión para ver los cambios.", - "instanceShell.sessionChanges.loading": "Obteniendo cambios de la sesión...", - "instanceShell.sessionChanges.empty": "Aún no hay cambios.", - "instanceShell.sessionChanges.filesChanged": "{count} archivos cambiados", - "instanceShell.sessionChanges.actions.show": "Mostrar cambios", - "instanceShell.gitChanges.loading": "Cargando cambios de Git...", "instanceShell.gitChanges.empty": "Aún no hay cambios de Git.", "instanceShell.gitChanges.deleted": "Eliminado", diff --git a/packages/ui/src/lib/i18n/messages/fr/instance.ts b/packages/ui/src/lib/i18n/messages/fr/instance.ts index 1f6efba1..f726e1fa 100644 --- a/packages/ui/src/lib/i18n/messages/fr/instance.ts +++ b/packages/ui/src/lib/i18n/messages/fr/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "Envoyez un message ci-dessous pour créer une nouvelle session, ou sélectionnez une session existante pour continuer.", "instanceShell.rightPanel.title": "Panneau d'état", - "instanceShell.rightPanel.tabs.changes": "Modifications", "instanceShell.rightPanel.tabs.gitChanges": "Changements Git", "instanceShell.rightPanel.tabs.files": "Fichiers", "instanceShell.rightPanel.tabs.status": "Statut", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "Échec de l'enregistrement du fichier", "instanceShell.rightPanel.sections.yoloMode": "Mode yolo", "instanceShell.rightPanel.sections.yoloMode.tooltip": "Approuve automatiquement les demandes d'autorisation pour la session actuelle. A utiliser seulement si vous faites confiance aux outils executes.", - "instanceShell.rightPanel.sections.sessionChanges": "Changements de session", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "Fichiers modifiés dans la session actuelle. Affiche les ajouts et suppressions pour chaque fichier.", "instanceShell.rightPanel.sections.plan": "Plan", "instanceShell.rightPanel.sections.plan.tooltip": "Feuille de route de l'agent pour cette session. Suit les tâches et leur statut d'achèvement.", "instanceShell.rightPanel.sections.backgroundProcesses": "Shells en arrière-plan", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "Plugins", "instanceShell.rightPanel.sections.plugins.tooltip": "Plugins qui personnalisent le comportement de l'UI et du serveur, ajoutant des fonctionnalités au-delà de MCP et LSP.", - "instanceShell.sessionChanges.noSessionSelected": "Sélectionnez une session pour voir les changements.", - "instanceShell.sessionChanges.loading": "Récupération des changements...", - "instanceShell.sessionChanges.empty": "Aucun changement pour l'instant.", - "instanceShell.sessionChanges.filesChanged": "{count} fichiers modifiés", - "instanceShell.sessionChanges.actions.show": "Afficher les changements", - "instanceShell.gitChanges.loading": "Chargement des changements Git...", "instanceShell.gitChanges.empty": "Aucun changement Git pour l'instant.", "instanceShell.gitChanges.deleted": "Supprimé", diff --git a/packages/ui/src/lib/i18n/messages/he/instance.ts b/packages/ui/src/lib/i18n/messages/he/instance.ts index c0e2141e..0808ca99 100644 --- a/packages/ui/src/lib/i18n/messages/he/instance.ts +++ b/packages/ui/src/lib/i18n/messages/he/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "שלח הודעה למטה כדי ליצור סשן חדש, או בחר סשן קיים כדי להמשיך.", "instanceShell.rightPanel.title": "לוח סטטוס", - "instanceShell.rightPanel.tabs.changes": "שינויי סשן", "instanceShell.rightPanel.tabs.gitChanges": "שינויי Git", "instanceShell.rightPanel.tabs.files": "קבצים", "instanceShell.rightPanel.tabs.status": "סטטוס", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "כשלון בשמירת הקובץ", "instanceShell.rightPanel.sections.yoloMode": "מצב Yolo", "instanceShell.rightPanel.sections.yoloMode.tooltip": "מאשר אוטומטית בקשות הרשאה עבור הסשן הנוכחי. השתמשו בזה רק אם אתם סומכים על הכלים שרצים.", - "instanceShell.rightPanel.sections.sessionChanges": "שינויי סשן", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "קבצים שהשתנו בסשן הנוכחי. מציג הוספות ומחיקות לכל קובץ.", "instanceShell.rightPanel.sections.plan": "תוכנית", "instanceShell.rightPanel.sections.plan.tooltip": "מפת הדרכים של הסוכן לסשן זה. עוקב אחר משימות, תת-משימות וסטטוס השלמתן.", "instanceShell.rightPanel.sections.backgroundProcesses": "מעטפות רקע", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "תוספים", "instanceShell.rightPanel.sections.plugins.tooltip": "תוספים המתאימים אישית את הממשק ואת התנהגות השרת, ומוסיפים תכונות מעבר ל-MCP ו-LSP.", - "instanceShell.sessionChanges.noSessionSelected": "בחר סשן לצפייה בשינויים.", - "instanceShell.sessionChanges.loading": "מאחזר שינויי סשן...", - "instanceShell.sessionChanges.empty": "אין שינויי סשן עדיין.", - "instanceShell.sessionChanges.filesChanged": "{count} קבצים שונו", - "instanceShell.sessionChanges.actions.show": "הצג שינויים", - "instanceShell.filesShell.fileListTitle": "רשימת קבצים", "instanceShell.filesShell.mobileSelectorLabel": "בחר קובץ", "instanceShell.filesShell.mobileSelectorEmpty": "בחר קובץ", diff --git a/packages/ui/src/lib/i18n/messages/ja/instance.ts b/packages/ui/src/lib/i18n/messages/ja/instance.ts index ca6cd551..6ff5833f 100644 --- a/packages/ui/src/lib/i18n/messages/ja/instance.ts +++ b/packages/ui/src/lib/i18n/messages/ja/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "下にメッセージを送信して新しいセッションを作成するか、既存のセッションを選択して続行してください。", "instanceShell.rightPanel.title": "ステータスパネル", - "instanceShell.rightPanel.tabs.changes": "変更", "instanceShell.rightPanel.tabs.gitChanges": "Git 変更", "instanceShell.rightPanel.tabs.files": "ファイル", "instanceShell.rightPanel.tabs.status": "ステータス", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "ファイルの保存に失敗しました", "instanceShell.rightPanel.sections.yoloMode": "Yoloモード", "instanceShell.rightPanel.sections.yoloMode.tooltip": "現在のセッションの権限リクエストを自動承認します。実行中のツールを信頼できる場合にのみ使用してください。", - "instanceShell.rightPanel.sections.sessionChanges": "セッション変更", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "現在のセッションで変更されたファイル。各ファイルの追加と削除を表示します。", "instanceShell.rightPanel.sections.plan": "計画", "instanceShell.rightPanel.sections.plan.tooltip": "このセッションにおけるエージェントのロードマップ。タスクやサブタスク、および完了状況を追跡します。", "instanceShell.rightPanel.sections.backgroundProcesses": "バックグラウンドシェル", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "プラグイン", "instanceShell.rightPanel.sections.plugins.tooltip": "UI とサーバーの動作をカスタマイズし、MCP や LSP 以外の機能も追加できるプラグイン。", - "instanceShell.sessionChanges.noSessionSelected": "変更を表示するにはセッションを選択してください。", - "instanceShell.sessionChanges.loading": "変更を取得中...", - "instanceShell.sessionChanges.empty": "まだ変更はありません。", - "instanceShell.sessionChanges.filesChanged": "{count} 個のファイルが変更されました", - "instanceShell.sessionChanges.actions.show": "変更を表示", - "instanceShell.gitChanges.loading": "Git の変更を読み込み中...", "instanceShell.gitChanges.empty": "Git の変更はまだありません。", "instanceShell.gitChanges.deleted": "削除済み", diff --git a/packages/ui/src/lib/i18n/messages/ne/instance.ts b/packages/ui/src/lib/i18n/messages/ne/instance.ts index 4fa38473..6d5f30cc 100644 --- a/packages/ui/src/lib/i18n/messages/ne/instance.ts +++ b/packages/ui/src/lib/i18n/messages/ne/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "नयाँ सत्र सिर्जना गर्न तल सन्देश पठाउनुहोस्, वा जारी राख्न अवस्थित सत्र चयन गर्नुहोस्।", "instanceShell.rightPanel.title": "स्थिति प्यानल (Status Panel)", - "instanceShell.rightPanel.tabs.changes": "सत्र परिवर्तनहरू", "instanceShell.rightPanel.tabs.gitChanges": "Git परिवर्तनहरू", "instanceShell.rightPanel.tabs.files": "फाइलहरू", "instanceShell.rightPanel.tabs.status": "स्थिति", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "फाइल बचत गर्न असफल भयो", "instanceShell.rightPanel.sections.yoloMode": "Yolo मोड", "instanceShell.rightPanel.sections.yoloMode.tooltip": "हालको सत्रको लागि अनुमति अनुरोधहरू स्वतः स्वीकृत गर्दछ। तपाईंले चलिरहेका उपकरणहरूलाई विश्वास गर्दा मात्र यसलाई प्रयोग गर्नुहोस्।", - "instanceShell.rightPanel.sections.sessionChanges": "सत्र परिवर्तनहरू", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "हालको सत्रमा परिमार्जन गरिएका फाइलहरू।", "instanceShell.rightPanel.sections.plan": "योजना", "instanceShell.rightPanel.sections.plan.tooltip": "यस सत्रको लागि एजेन्टको मार्गचित्र।", "instanceShell.rightPanel.sections.backgroundProcesses": "पृष्ठभूमि शेलहरू", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "प्लगइनहरू", "instanceShell.rightPanel.sections.plugins.tooltip": "UI र सर्भर व्यवहार अनुकूलित गर्ने प्लगइनहरू।", - "instanceShell.sessionChanges.noSessionSelected": "परिवर्तनहरू हेर्न सत्र चयन गर्नुहोस्।", - "instanceShell.sessionChanges.loading": "सत्र परिवर्तनहरू प्राप्त गर्दै...", - "instanceShell.sessionChanges.empty": "अझै कुनै सत्र परिवर्तनहरू छैनन्।", - "instanceShell.sessionChanges.filesChanged": "{count} फाइलहरू परिवर्तन भए", - "instanceShell.sessionChanges.actions.show": "परिवर्तनहरू देखाउनुहोस्", - "instanceShell.gitChanges.noSessionSelected": "Git परिवर्तनहरू हेर्न सत्र चयन गर्नुहोस्।", "instanceShell.gitChanges.loading": "Git परिवर्तनहरू लोड गर्दै...", "instanceShell.gitChanges.empty": "अझै कुनै Git परिवर्तनहरू छैनन्।", diff --git a/packages/ui/src/lib/i18n/messages/ru/instance.ts b/packages/ui/src/lib/i18n/messages/ru/instance.ts index bce93442..f76da0df 100644 --- a/packages/ui/src/lib/i18n/messages/ru/instance.ts +++ b/packages/ui/src/lib/i18n/messages/ru/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "Отправьте сообщение ниже, чтобы создать новую сессию, или выберите существующую сессию, чтобы продолжить.", "instanceShell.rightPanel.title": "Панель состояния", - "instanceShell.rightPanel.tabs.changes": "Изменения", "instanceShell.rightPanel.tabs.gitChanges": "Изменения Git", "instanceShell.rightPanel.tabs.files": "Файлы", "instanceShell.rightPanel.tabs.status": "Статус", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "Не удалось сохранить файл", "instanceShell.rightPanel.sections.yoloMode": "Режим Yolo", "instanceShell.rightPanel.sections.yoloMode.tooltip": "Автоматически одобряет запросы разрешений для текущей сессии. Включайте только если доверяете запускаемым инструментам.", - "instanceShell.rightPanel.sections.sessionChanges": "Изменения сессии", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "Файлы, измененные в текущей сессии. Показывает добавления и удаления для каждого файла.", "instanceShell.rightPanel.sections.plan": "План", "instanceShell.rightPanel.sections.plan.tooltip": "Дорожная карта агента для этой сессии. Отслеживает задачи и их статус выполнения.", "instanceShell.rightPanel.sections.backgroundProcesses": "Фоновые оболочки", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "Плагины", "instanceShell.rightPanel.sections.plugins.tooltip": "Плагины, настраивающие поведение интерфейса и сервера, добавляющие функции поверх MCP и LSP.", - "instanceShell.sessionChanges.noSessionSelected": "Выберите сессию, чтобы просмотреть изменения.", - "instanceShell.sessionChanges.loading": "Загрузка изменений...", - "instanceShell.sessionChanges.empty": "Пока нет изменений.", - "instanceShell.sessionChanges.filesChanged": "Изменено файлов: {count}", - "instanceShell.sessionChanges.actions.show": "Показать изменения", - "instanceShell.gitChanges.loading": "Загрузка изменений Git...", "instanceShell.gitChanges.empty": "Изменений Git пока нет.", "instanceShell.gitChanges.deleted": "Удалено", diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts index 70a378c9..dc6dbd64 100644 --- a/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/instance.ts @@ -89,7 +89,6 @@ export const instanceMessages = { "instanceShell.empty.description": "在下方发送消息以创建新会话,或选择现有会话继续。", "instanceShell.rightPanel.title": "状态面板", - "instanceShell.rightPanel.tabs.changes": "更改", "instanceShell.rightPanel.tabs.gitChanges": "Git 更改", "instanceShell.rightPanel.tabs.files": "文件", "instanceShell.rightPanel.tabs.status": "状态", @@ -109,8 +108,6 @@ export const instanceMessages = { "instanceShell.rightPanel.toast.saveError": "保存文件失败", "instanceShell.rightPanel.sections.yoloMode": "Yolo 模式", "instanceShell.rightPanel.sections.yoloMode.tooltip": "自动批准当前会话的权限请求。仅在你信任正在运行的工具时启用。", - "instanceShell.rightPanel.sections.sessionChanges": "会话更改", - "instanceShell.rightPanel.sections.sessionChanges.tooltip": "当前会话中修改的文件。显示每个文件的添加和删除。", "instanceShell.rightPanel.sections.plan": "计划", "instanceShell.rightPanel.sections.plan.tooltip": "代理的路线图。跟踪任务、子任务及其完成状态。", "instanceShell.rightPanel.sections.backgroundProcesses": "后台 Shell", @@ -122,12 +119,6 @@ export const instanceMessages = { "instanceShell.rightPanel.sections.plugins": "插件", "instanceShell.rightPanel.sections.plugins.tooltip": "自定义 UI 和服务器行为的插件,添加超出 MCP 和 LSP 的功能。", - "instanceShell.sessionChanges.noSessionSelected": "选择会话以查看更改。", - "instanceShell.sessionChanges.loading": "正在获取会话更改...", - "instanceShell.sessionChanges.empty": "暂无会话更改。", - "instanceShell.sessionChanges.filesChanged": "已更改 {count} 个文件", - "instanceShell.sessionChanges.actions.show": "显示更改", - "instanceShell.gitChanges.loading": "正在加载 Git 更改...", "instanceShell.gitChanges.empty": "暂无 Git 更改。", "instanceShell.gitChanges.deleted": "已删除", diff --git a/packages/ui/src/lib/sse-manager.ts b/packages/ui/src/lib/sse-manager.ts index 8fa3dfdc..47b9ea80 100644 --- a/packages/ui/src/lib/sse-manager.ts +++ b/packages/ui/src/lib/sse-manager.ts @@ -10,7 +10,6 @@ import type { EventLspUpdated, EventSessionCompacted, - EventSessionDiff, EventSessionError, EventSessionIdle, EventSessionUpdated, @@ -77,7 +76,6 @@ type SSEEvent = | MessagePartDeltaEvent | EventSessionUpdated | EventSessionCompacted - | EventSessionDiff | EventSessionError | EventSessionIdle | EventSessionStatus @@ -168,9 +166,6 @@ class SSEManager { case "session.status": this.onSessionStatus?.(instanceId, event as EventSessionStatus) break - case "session.diff": - this.onSessionDiff?.(instanceId, event as EventSessionDiff) - break case "permission.asked": case "permission.updated": this.onPermissionUpdated?.(instanceId, event as any) @@ -234,7 +229,6 @@ class SSEManager { onTuiToast?: (instanceId: string, event: TuiToastEvent) => void onSessionIdle?: (instanceId: string, event: EventSessionIdle) => void onSessionStatus?: (instanceId: string, event: EventSessionStatus) => void - onSessionDiff?: (instanceId: string, event: EventSessionDiff) => void onPermissionUpdated?: (instanceId: string, event: EventPermissionV2Asked | LegacyPermissionAskedEvent) => void onPermissionReplied?: (instanceId: string, event: EventPermissionV2Replied | LegacyPermissionRepliedEvent) => void onQuestionAsked?: (instanceId: string, event: EventQuestionV2Asked | { type: "question.asked"; properties?: any }) => void diff --git a/packages/ui/src/stores/session-api.ts b/packages/ui/src/stores/session-api.ts index 0eb6e9b5..ac89ed65 100644 --- a/packages/ui/src/stores/session-api.ts +++ b/packages/ui/src/stores/session-api.ts @@ -7,7 +7,7 @@ import { type SessionStatus, } from "../types/session" import type { Message } from "../types/message" -import type { SnapshotFileDiff, SessionV2Info, V2SessionsResponse } from "@opencode-ai/sdk/v2/client" +import type { SessionV2Info, V2SessionsResponse } from "@opencode-ai/sdk/v2/client" import { instances } from "./instances" import { preferences, setAgentModelPreference } from "./preferences" @@ -61,8 +61,6 @@ import { hydrateSessionMetadataWithClient } from "./session-metadata" const log = getLogger("api") -const pendingSessionDiffFetches = new Map>() - function getErrorMessage(error: unknown): string { if (!error) return "Failed to load messages" @@ -89,46 +87,6 @@ async function getSessionWorkspacePayload(instanceId: string, sessionId: string) return workspace ? { workspace } : {} } -async function loadSessionDiff(instanceId: string, sessionId: string, force = false): Promise { - if (!instanceId || !sessionId) return - - const key = `${instanceId}:${sessionId}` - if (!force) { - const existing = sessions().get(instanceId)?.get(sessionId) - if (existing?.diff !== undefined) return - const pending = pendingSessionDiffFetches.get(key) - if (pending) return pending - } - - const promise = (async () => { - const instance = instances().get(instanceId) - if (!instance?.client) return - - const client = getRootClient(instanceId) - - try { - const diffs = await requestData( - client.session.diff({ sessionID: sessionId, ...(await getSessionWorkspacePayload(instanceId, sessionId)) }), - "session.diff", - ) - - if (!Array.isArray(diffs)) { - return - } - - withSession(instanceId, sessionId, (session) => { - session.diff = diffs - }) - } catch (error) { - log.warn("Failed to fetch session diff", { instanceId, sessionId, error }) - } - })() - - pendingSessionDiffFetches.set(key, promise) - void promise.finally(() => pendingSessionDiffFetches.delete(key)) - return promise -} - interface SessionForkResponse { id: string title?: string @@ -474,7 +432,6 @@ function toClientSessionV2(instanceId: string, apiSession: SessionV2Info, existi }, metadata: existingSession?.metadata, revert: existingSession?.revert, - diff: existingSession?.diff, pendingPermission: existingSession?.pendingPermission, pendingQuestion: existingSession?.pendingQuestion, } @@ -851,10 +808,9 @@ async function fetchProviders(instanceId: string): Promise { async function loadMessages( instanceId: string, sessionId: string, - options?: { force?: boolean; skipDiff?: boolean; skipChildren?: boolean }, + options?: { force?: boolean; skipChildren?: boolean }, ): Promise { const force = options?.force ?? false - const skipDiff = options?.skipDiff ?? false const skipChildren = options?.skipChildren ?? false if (force) { @@ -896,12 +852,6 @@ async function loadMessages( throw new Error("Session not found") } - if (!skipDiff) { - void loadSessionDiff(instanceId, sessionId).catch((error) => { - log.warn("Failed to load session diff", { instanceId, sessionId, error }) - }) - } - setLoading((prev) => { const next = { ...prev } const loadingSet = next.loadingMessages.get(instanceId) || new Set() @@ -1048,7 +998,7 @@ async function loadMessages( if (!skipChildren && session.parentId === null) { for (const child of getDescendantSessions(instanceId, sessionId)) { - void loadMessages(instanceId, child.id, { skipDiff: true, skipChildren: true }).catch((error) => + void loadMessages(instanceId, child.id, { skipChildren: true }).catch((error) => log.error("Failed to load child session messages", { instanceId, sessionId: child.id, diff --git a/packages/ui/src/stores/session-events.ts b/packages/ui/src/stores/session-events.ts index 8f87e936..90430b1f 100644 --- a/packages/ui/src/stores/session-events.ts +++ b/packages/ui/src/stores/session-events.ts @@ -8,7 +8,6 @@ import type { } from "../types/message" import type { EventSessionCompacted, - EventSessionDiff, EventSessionError, EventSessionIdle, EventSessionUpdated, @@ -563,31 +562,6 @@ function handleSessionUpdate(instanceId: string, event: EventSessionUpdated): vo } } -function handleSessionDiff(instanceId: string, event: EventSessionDiff): void { - const sessionId = event.properties?.sessionID - if (!sessionId) return - - const diffs = event.properties?.diff - if (!Array.isArray(diffs)) return - - const existing = sessions().get(instanceId)?.get(sessionId) - if (existing) { - withSession(instanceId, sessionId, (session) => { - session.diff = diffs - }) - return - } - - // A diff event can arrive before we have hydrated the session list. - // Best-effort: fetch the session record so the diff has somewhere to live. - void (async () => { - await fetchSessionInfo(instanceId, sessionId, (event as any)?.directory) - withSession(instanceId, sessionId, (session) => { - session.diff = diffs - }) - })().catch((error) => log.warn("Failed to hydrate session for diff event", { instanceId, sessionId, error })) -} - function handleSessionIdle(instanceId: string, event: EventSessionIdle): void { const sessionId = event.properties?.sessionID if (!sessionId) return @@ -799,7 +773,6 @@ export { handleQuestionAsked, handleQuestionAnswered, handleSessionCompacted, - handleSessionDiff, handleSessionError, handleSessionIdle, handleSessionStatus, diff --git a/packages/ui/src/stores/sessions.ts b/packages/ui/src/stores/sessions.ts index 9dc353d2..365fa8c3 100644 --- a/packages/ui/src/stores/sessions.ts +++ b/packages/ui/src/stores/sessions.ts @@ -80,7 +80,6 @@ import { handleQuestionAnswered, handleQuestionAsked, handleSessionCompacted, - handleSessionDiff, handleSessionError, handleSessionIdle, handleSessionStatus, @@ -95,7 +94,6 @@ sseManager.onMessageRemoved = handleMessageRemoved sseManager.onMessagePartRemoved = handleMessagePartRemoved sseManager.onSessionUpdate = handleSessionUpdate sseManager.onSessionCompacted = handleSessionCompacted -sseManager.onSessionDiff = handleSessionDiff sseManager.onSessionError = handleSessionError sseManager.onSessionIdle = handleSessionIdle sseManager.onSessionStatus = handleSessionStatus diff --git a/packages/ui/src/types/session.ts b/packages/ui/src/types/session.ts index 067ec63e..fa2ded5e 100644 --- a/packages/ui/src/types/session.ts +++ b/packages/ui/src/types/session.ts @@ -4,7 +4,7 @@ import type { Provider as SDKProvider, Model as SDKModel, } from "@opencode-ai/sdk" -import type { SessionStatus as SDKSessionStatus, SnapshotFileDiff } from "@opencode-ai/sdk/v2/client" +import type { SessionStatus as SDKSessionStatus } from "@opencode-ai/sdk/v2/client" // Export SDK types for external use export type { @@ -77,7 +77,6 @@ export interface Session retry?: SessionRetryState | null // Retry metadata for transient backoff states idleSince?: number | null // Timestamp set when work finished but the session has not been viewed yet metadata?: Record // Session metadata persisted by OpenCode - diff?: SnapshotFileDiff[] // Session-level file diffs (hydrated via session.diff) } // Adapter function to convert SDK Session to client Session