@@ -28,6 +28,7 @@ import { Dialog } from "@opencode-ai/ui/dialog"
2828import { InlineInput } from "@opencode-ai/ui/inline-input"
2929import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
3030import { Tabs } from "@opencode-ai/ui/tabs"
31+ import { Select } from "@opencode-ai/ui/select"
3132import { useCodeComponent } from "@opencode-ai/ui/context/code"
3233import { LineComment as LineCommentView , LineCommentEditor } from "@opencode-ai/ui/line-comment"
3334import { SessionTurn } from "@opencode-ai/ui/session-turn"
@@ -54,7 +55,7 @@ import { useCommand } from "@/context/command"
5455import { useLanguage } from "@/context/language"
5556import { useNavigate , useParams } from "@solidjs/router"
5657import { UserMessage } from "@opencode-ai/sdk/v2"
57- import type { FileDiff } from "@opencode-ai/sdk/v2/client "
58+ import type { FileDiff } from "@opencode-ai/sdk/v2"
5859import { useSDK } from "@/context/sdk"
5960import { usePrompt } from "@/context/prompt"
6061import { useComments , type LineComment } from "@/context/comments"
@@ -104,6 +105,8 @@ const setSessionHandoff = (key: string, patch: Partial<HandoffSession>) => {
104105}
105106
106107interface SessionReviewTabProps {
108+ title ?: JSX . Element
109+ empty ?: JSX . Element
107110 diffs : ( ) => FileDiff [ ]
108111 view : ( ) => ReturnType < ReturnType < typeof useLayout > [ "view" ] >
109112 diffStyle : DiffStyle
@@ -220,6 +223,8 @@ function SessionReviewTab(props: SessionReviewTabProps) {
220223
221224 return (
222225 < SessionReview
226+ title = { props . title }
227+ empty = { props . empty }
223228 scrollRef = { ( el ) => {
224229 scroll = el
225230 props . onScrollRef ?.( el )
@@ -709,10 +714,14 @@ export default function Page() {
709714 messageId : undefined as string | undefined ,
710715 turnStart : 0 ,
711716 mobileTab : "session" as "session" | "changes" ,
717+ changes : "session" as "session" | "turn" ,
712718 newSessionWorktree : "main" ,
713719 promptHeight : 0 ,
714720 } )
715721
722+ const turnDiffs = createMemo ( ( ) => lastUserMessage ( ) ?. summary ?. diffs ?? [ ] )
723+ const reviewDiffs = createMemo ( ( ) => ( store . changes === "session" ? diffs ( ) : turnDiffs ( ) ) )
724+
716725 const renderedUserMessages = createMemo (
717726 ( ) => {
718727 const msgs = visibleUserMessages ( )
@@ -894,6 +903,7 @@ export default function Page() {
894903 ( ) => {
895904 setStore ( "messageId" , undefined )
896905 setStore ( "expanded" , { } )
906+ setStore ( "changes" , "session" )
897907 setUi ( "autoCreated" , false )
898908 } ,
899909 { defer : true } ,
@@ -1428,17 +1438,64 @@ export default function Page() {
14281438 setFileTreeTab ( "all" )
14291439 }
14301440
1441+ const changesOptions = [ "session" , "turn" ] as const
1442+ const changesOptionsList = [ ...changesOptions ]
1443+
1444+ const changesTitle = ( ) => (
1445+ < Select
1446+ options = { changesOptionsList }
1447+ current = { store . changes }
1448+ label = { ( option ) =>
1449+ option === "session" ? language . t ( "ui.sessionReview.title" ) : language . t ( "ui.sessionReview.title.lastTurn" )
1450+ }
1451+ onSelect = { ( option ) => option && setStore ( "changes" , option ) }
1452+ variant = "ghost"
1453+ size = "large"
1454+ triggerStyle = { { "font-size" : "var(--font-size-large)" } }
1455+ />
1456+ )
1457+
1458+ const emptyTurn = ( ) => (
1459+ < div class = "h-full pb-30 flex flex-col items-center justify-center text-center gap-6" >
1460+ < Mark class = "w-14 opacity-10" />
1461+ < div class = "text-14-regular text-text-weak max-w-56" > { language . t ( "session.review.noChanges" ) } </ div >
1462+ </ div >
1463+ )
1464+
14311465 const reviewPanel = ( ) => (
14321466 < div class = "flex flex-col h-full overflow-hidden bg-background-stronger contain-strict" >
14331467 < div class = "relative pt-2 flex-1 min-h-0 overflow-hidden" >
14341468 < Switch >
1469+ < Match when = { store . changes === "turn" && ! ! params . id } >
1470+ < SessionReviewTab
1471+ title = { changesTitle ( ) }
1472+ empty = { emptyTurn ( ) }
1473+ diffs = { reviewDiffs }
1474+ view = { view }
1475+ diffStyle = { layout . review . diffStyle ( ) }
1476+ onDiffStyleChange = { layout . review . setDiffStyle }
1477+ onScrollRef = { ( el ) => setTree ( "reviewScroll" , el ) }
1478+ focusedFile = { tree . activeDiff }
1479+ onLineComment = { ( comment ) => addCommentToContext ( { ...comment , origin : "review" } ) }
1480+ comments = { comments . all ( ) }
1481+ focusedComment = { comments . focus ( ) }
1482+ onFocusedCommentChange = { comments . setFocus }
1483+ onViewFile = { ( path ) => {
1484+ showAllFiles ( )
1485+ const value = file . tab ( path )
1486+ tabs ( ) . open ( value )
1487+ file . load ( path )
1488+ } }
1489+ />
1490+ </ Match >
14351491 < Match when = { hasReview ( ) } >
14361492 < Show
14371493 when = { diffsReady ( ) }
14381494 fallback = { < div class = "px-6 py-4 text-text-weak" > { language . t ( "session.review.loadingChanges" ) } </ div > }
14391495 >
14401496 < SessionReviewTab
1441- diffs = { diffs }
1497+ title = { changesTitle ( ) }
1498+ diffs = { reviewDiffs }
14421499 view = { view }
14431500 diffStyle = { layout . review . diffStyle ( ) }
14441501 onDiffStyleChange = { layout . review . setDiffStyle }
@@ -2138,6 +2195,31 @@ export default function Page() {
21382195 fallback = {
21392196 < div class = "relative h-full overflow-hidden" >
21402197 < Switch >
2198+ < Match when = { store . changes === "turn" && ! ! params . id } >
2199+ < SessionReviewTab
2200+ title = { changesTitle ( ) }
2201+ empty = { emptyTurn ( ) }
2202+ diffs = { reviewDiffs }
2203+ view = { view }
2204+ diffStyle = "unified"
2205+ focusedFile = { tree . activeDiff }
2206+ onLineComment = { ( comment ) => addCommentToContext ( { ...comment , origin : "review" } ) }
2207+ comments = { comments . all ( ) }
2208+ focusedComment = { comments . focus ( ) }
2209+ onFocusedCommentChange = { comments . setFocus }
2210+ onViewFile = { ( path ) => {
2211+ showAllFiles ( )
2212+ const value = file . tab ( path )
2213+ tabs ( ) . open ( value )
2214+ file . load ( path )
2215+ } }
2216+ classes = { {
2217+ root : "pb-[calc(var(--prompt-height,8rem)+32px)]" ,
2218+ header : "px-4" ,
2219+ container : "px-4" ,
2220+ } }
2221+ />
2222+ </ Match >
21412223 < Match when = { hasReview ( ) } >
21422224 < Show
21432225 when = { diffsReady ( ) }
@@ -2148,7 +2230,8 @@ export default function Page() {
21482230 }
21492231 >
21502232 < SessionReviewTab
2151- diffs = { diffs }
2233+ title = { changesTitle ( ) }
2234+ diffs = { reviewDiffs }
21522235 view = { view }
21532236 diffStyle = "unified"
21542237 focusedFile = { tree . activeDiff }
0 commit comments