feat(review): gate Approve & Merge behind opening the diff
Approve & Merge is disabled until the pending changes have been inspected: DetailsIslandViewModel tracks ReviewDiffViewed (reset on task switch and on every state change), MergeSectionViewModel raises DiffViewed when a diff or combined diff is opened and exposes HasReviewableDiff, and a hint sits next to the button. A review with nothing to inspect (sandbox run, no worktree) approves straight through. ClaudeDo-Task: f9809a93
This commit is contained in:
@@ -48,6 +48,15 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
public Func<DiffViewerViewModel, System.Threading.Tasks.Task>? ShowDiffViewer { get; set; }
|
||||
public Func<MergeModalViewModel, System.Threading.Tasks.Task>? ShowMergeModal { get; set; }
|
||||
|
||||
// Raised when the user opens a diff/combined-diff for the current task, so the
|
||||
// review gate can record that the changes were inspected before merging.
|
||||
public Action? DiffViewed { get; set; }
|
||||
|
||||
// True when there is something to inspect before merging (a live worktree diff,
|
||||
// a merged commit range, or a planning/children combined diff). When false there
|
||||
// is nothing to read, so the review gate must not block approve.
|
||||
public bool HasReviewableDiff => CanOpenDiff() || CanReviewDiff();
|
||||
|
||||
public MergeSectionViewModel(IWorkerClient worker, IServiceProvider services)
|
||||
{
|
||||
_worker = worker;
|
||||
@@ -69,6 +78,7 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
_worktreeStateLabel = worktreeState;
|
||||
_listWorkingDir = listWorkDir;
|
||||
OnPropertyChanged(nameof(ShowMergeSection));
|
||||
OnPropertyChanged(nameof(HasReviewableDiff));
|
||||
OpenDiffCommand.NotifyCanExecuteChanged();
|
||||
OpenWorktreeCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
@@ -79,6 +89,7 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
TaskTitle = taskTitle;
|
||||
_isPlanningParent = isPlanningParent;
|
||||
OnPropertyChanged(nameof(ShowMergeSection));
|
||||
OnPropertyChanged(nameof(HasReviewableDiff));
|
||||
}
|
||||
|
||||
internal void SyncChildOutcomes(bool hasChildOutcomes, int subtaskCount)
|
||||
@@ -86,6 +97,7 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
_hasChildOutcomes = hasChildOutcomes;
|
||||
_subtaskCount = subtaskCount;
|
||||
OnPropertyChanged(nameof(ShowMergeSection));
|
||||
OnPropertyChanged(nameof(HasReviewableDiff));
|
||||
ReviewCombinedDiffCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
@@ -128,6 +140,7 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
var vm = _services.GetRequiredService<DiffViewerViewModel>();
|
||||
vm.ConfigurePlanning(TaskId, SelectedMergeTarget ?? "main");
|
||||
await vm.LoadAsync();
|
||||
DiffViewed?.Invoke();
|
||||
await ShowDiffViewer(vm);
|
||||
}
|
||||
|
||||
@@ -157,6 +170,7 @@ public sealed partial class MergeSectionViewModel : ViewModelBase
|
||||
else return;
|
||||
|
||||
await vm.LoadAsync();
|
||||
DiffViewed?.Invoke();
|
||||
await ShowDiffViewer(vm);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user