feat(ui): rework review into terminal footer and add Git tab

Move review feedback into a prompt-style footer on the Output tab with
Retry/Reset actions, relocate Approve and all merge/worktree controls to a
new Git tab, and reduce the Session tab to subtask outcomes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-06-05 08:34:29 +02:00
parent 6c65158be8
commit 8819a56496

View File

@@ -127,6 +127,11 @@
Content="Output"
Command="{Binding SelectTabCommand}"
CommandParameter="output" />
<Button Classes="tab-btn"
Classes.active="{Binding IsGitTab}"
Content="Git"
Command="{Binding SelectTabCommand}"
CommandParameter="git" />
<Button Classes="tab-btn"
Classes.active="{Binding IsSessionTab}"
Content="Session"
@@ -138,61 +143,78 @@
<!-- ── Tab body (bottom inset keeps content clear of the rounded corner) ── -->
<Grid Margin="0,0,0,8">
<!-- Output: log rendered directly on the console body (no nested card) -->
<ScrollViewer Name="LogScroll"
IsVisible="{Binding IsOutputTab}"
VerticalScrollBarVisibility="Visible"
AllowAutoHide="False"
Padding="12,8,12,4">
<ItemsControl ItemsSource="{Binding Log}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:LogLineViewModel">
<Grid ColumnDefinitions="60,*" Margin="0,1">
<TextBlock Grid.Column="0"
Classes="log-ts"
Text="{Binding TimestampFormatted}" />
<SelectableTextBlock Grid.Column="1"
Text="{Binding Text}" Tag="{Binding ClassName}"
Foreground="{DynamicResource TextDimBrush}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!-- Output: log + review footer, both gated on IsOutputTab -->
<DockPanel IsVisible="{Binding IsOutputTab}" LastChildFill="True">
<!-- Session: review (top) + merge/worktree + outcomes — each gated on state -->
<ScrollViewer IsVisible="{Binding IsSessionTab}" Padding="14,10">
<StackPanel Spacing="14">
<!-- Review controls -->
<StackPanel Spacing="8" IsVisible="{Binding IsWaitingForReview}">
<TextBlock Classes="section-label" Text="REVIEW" />
<TextBlock Classes="field-label" Text="Feedback" />
<TextBox Text="{Binding ReviewFeedback, Mode=TwoWay}"
<!-- Review footer (terminal prompt) — only while awaiting review -->
<Border DockPanel.Dock="Bottom"
IsVisible="{Binding IsWaitingForReview}"
Background="{DynamicResource Surface2Brush}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="0,1,0,0"
Padding="10,6">
<DockPanel LastChildFill="True">
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" Spacing="8"
VerticalAlignment="Bottom" Margin="8,0,0,0">
<Button Classes="btn accent" Content="Retry"
Command="{Binding RejectReviewCommand}" />
<Button Classes="btn" Content="Reset"
Command="{Binding ParkReviewCommand}" />
</StackPanel>
<TextBlock DockPanel.Dock="Left" Text="&#x276F;"
FontFamily="{StaticResource MonoFont}"
Foreground="{DynamicResource TextMuteBrush}"
VerticalAlignment="Top" Margin="0,4,8,0" />
<TextBox Name="ReviewInput"
KeyDown="OnReviewInputKeyDown"
Text="{Binding ReviewFeedback, Mode=TwoWay}"
AcceptsReturn="True"
TextWrapping="Wrap"
MinHeight="60"
MaxHeight="180"
PlaceholderText="Optional feedback for the next run…"
Padding="8"
Background="{DynamicResource Surface2Brush}"
BorderBrush="{DynamicResource LineBrush}"
BorderThickness="1"
CornerRadius="8" />
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Classes="btn accent" Content="Approve"
Command="{Binding ApproveReviewCommand}" />
<Button Classes="btn" Content="Reject"
Command="{Binding RejectReviewCommand}" />
<Button Classes="btn" Content="Park"
Command="{Binding ParkReviewCommand}" />
<Button Classes="btn" Content="Cancel"
Command="{Binding CancelReviewCommand}" />
</StackPanel>
MaxHeight="160"
PlaceholderText="Feedback for the next run…"
Background="Transparent"
BorderThickness="0"
Padding="0,2"
FontFamily="{StaticResource MonoFont}"
FontSize="{StaticResource FontSizeMono}" />
</DockPanel>
</Border>
<ScrollViewer Name="LogScroll"
VerticalScrollBarVisibility="Visible"
AllowAutoHide="False"
Padding="12,8,12,4">
<ItemsControl ItemsSource="{Binding Log}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:LogLineViewModel">
<Grid ColumnDefinitions="60,*" Margin="0,1">
<TextBlock Grid.Column="0"
Classes="log-ts"
Text="{Binding TimestampFormatted}" />
<SelectableTextBlock Grid.Column="1"
Text="{Binding Text}" Tag="{Binding ClassName}"
Foreground="{DynamicResource TextDimBrush}"
TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
<!-- Git: merge target, approve, diff, worktree -->
<ScrollViewer IsVisible="{Binding IsGitTab}" Padding="14,10">
<StackPanel Spacing="14">
<!-- Approve (review-gated) -->
<StackPanel Spacing="8" IsVisible="{Binding IsWaitingForReview}">
<TextBlock Classes="section-label" Text="REVIEW" />
<Button Classes="btn accent" Content="Approve"
Command="{Binding ApproveReviewCommand}" />
</StackPanel>
<!-- Merge & worktree management -->
<!-- Merge & worktree management (moved from Session tab) -->
<StackPanel Spacing="10" IsVisible="{Binding ShowMergeSection}">
<TextBlock Classes="section-label" Text="MERGE &amp; WORKTREE" />
<StackPanel Spacing="4">
@@ -201,7 +223,6 @@
SelectedItem="{Binding SelectedMergeTarget, Mode=TwoWay}"
HorizontalAlignment="Stretch" />
</StackPanel>
<!-- Mergeability at a glance: green when clean, red on conflict, muted otherwise -->
<StackPanel Spacing="0">
<TextBlock Classes="meta" Text="{Binding MergePreviewText}" TextWrapping="Wrap"
Foreground="{DynamicResource MossBrush}"
@@ -240,6 +261,13 @@
Converter={x:Static ObjectConverters.IsNotNull}}" />
</StackPanel>
</StackPanel>
</ScrollViewer>
<!-- Session: subtask outcomes (review lives in Output, merge in Git) -->
<ScrollViewer IsVisible="{Binding IsSessionTab}" Padding="14,10">
<StackPanel Spacing="14">
<!-- Child outcomes -->
<StackPanel Spacing="6" IsVisible="{Binding HasChildOutcomes}">
<TextBlock Classes="section-label" Text="OUTCOMES" />
@@ -267,7 +295,7 @@
Classes="meta"
Foreground="{DynamicResource TextMuteBrush}"
TextWrapping="Wrap"
Text="Nothing to manage yet — review and merge controls appear here once the run finishes." />
Text="Nothing to manage yet — subtask outcomes appear here once the run finishes. Review in the Output tab, merge in the Git tab." />
</StackPanel>
</ScrollViewer>