From 43fb506e87e683c167f3f0f57a7f876740702f4a Mon Sep 17 00:00:00 2001 From: Mika Kuns Date: Thu, 18 Jun 2026 15:52:41 +0200 Subject: [PATCH] feat(review): unify review actions into the Git-tab cockpit Grow the detail-pane Git tab into the review+merge cockpit: target, pre-flight mergeability, inspect actions, then the four review verbs (Approve & Merge / Send back / Park / Cancel) plus a demoted Reset (discard branch). The decision block is gated independently of the merge controls so sandbox (no-worktree) review tasks still get the buttons. - Add ParkReviewCommand (-> RejectReviewToIdleAsync) - Send back (reject-to-queue) disabled until feedback is entered - Remove the mislabeled [Continue]/[Reset] line from the Output tab - Accent dot on the Git tab while awaiting review --- .../Islands/DetailsIslandViewModel.cs | 18 +- .../Views/Islands/Detail/WorkConsole.axaml | 168 ++++++++++-------- .../DetailsIslandReviewActionsTests.cs | 101 +++++++++++ 3 files changed, 210 insertions(+), 77 deletions(-) create mode 100644 tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandReviewActionsTests.cs diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs index a1ff6e3..f322813 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs @@ -337,7 +337,12 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable public Func? ShowErrorAsync { get; set; } // ── Review ────────────────────────────────────────────────────────────── - [ObservableProperty] private string _reviewFeedback = ""; + [ObservableProperty] + [NotifyPropertyChangedFor(nameof(HasReviewFeedback))] + [NotifyCanExecuteChangedFor(nameof(RejectReviewCommand))] + private string _reviewFeedback = ""; + + public bool HasReviewFeedback => !string.IsNullOrWhiteSpace(ReviewFeedback); // Kept for backwards-compat surface — delegates to Merge.RequestConflictResolution public Func? RequestConflictResolution @@ -1169,7 +1174,7 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable } } - [RelayCommand] + [RelayCommand(CanExecute = nameof(HasReviewFeedback))] private async System.Threading.Tasks.Task RejectReviewAsync() { if (Task is null || !_worker.IsConnected) return; @@ -1180,6 +1185,15 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase, IDisposable ReviewFeedback = ""; } + // Park: set the task aside (back to Idle), keeping its worktree intact. + [RelayCommand] + private async System.Threading.Tasks.Task ParkReviewAsync() + { + if (Task is null || !_worker.IsConnected) return; + try { await _worker.RejectReviewToIdleAsync(Task.Id); } + catch { /* stale review action; broadcast reconciles */ } + } + [RelayCommand] private async System.Threading.Tasks.Task ResetReviewAsync() { diff --git a/src/ClaudeDo.Ui/Views/Islands/Detail/WorkConsole.axaml b/src/ClaudeDo.Ui/Views/Islands/Detail/WorkConsole.axaml index b00bb97..1674575 100644 --- a/src/ClaudeDo.Ui/Views/Islands/Detail/WorkConsole.axaml +++ b/src/ClaudeDo.Ui/Views/Islands/Detail/WorkConsole.axaml @@ -167,9 +167,16 @@ CommandParameter="output" /> + -