# Terminal-style review controls **Date:** 2026-06-05 **Status:** Approved (design) ## Problem Review feedback today is a multi-line `TextBox` plus four buttons (Approve / Reject / Park / Cancel) tucked into the WorkConsole **Session** tab (`WorkConsole.axaml:169-193`). It feels disconnected from the live terminal. Entering feedback should feel like typing into the terminal, with action buttons docked at the bottom — and merge/approve actions should live in an obvious, dedicated place. ## Goal - Type review feedback directly in the **Output (terminal)** tab, prompt-style. - Bottom-docked action strip on the terminal: `[Retry]` `[Reset]`. - Move all git/merge/worktree actions (including **Approve**) into a new **Git** tab so it is obvious where each action lives. ## Tab structure Three tabs in WorkConsole: **Output** · **Git** · **Session**. | Tab | Contents | | --- | --- | | **Output** | Live `Log` (unchanged) + new review footer (below), footer gated on `IsWaitingForReview`. | | **Git** | The current "Merge & worktree" block — merge-target dropdown, mergeability indicator, **Approve**, Open Diff, Merge, Worktree, Review Combined Diff, Merge All Subtasks. Visibility gated on `ShowMergeSection` / `IsWaitingForReview` as today. | | **Session** | Child outcomes + empty-state only. | ### ViewModel changes (`DetailsIslandViewModel`) - Add `public bool IsGitTab => SelectedTab == "git";` - Add `[NotifyPropertyChangedFor(nameof(IsGitTab))]` alongside the existing `IsOutputTab` / `IsSessionTab` notifications on `SelectedTab` (`:139-144`). - `SelectTab` already accepts a string parameter — no change beyond the new `"git"` value wired from XAML. - No command renames (avoids breaking hand-rolled test fakes). ## Terminal footer (Output tab) A `Border` docked `Bottom` inside the Output tab body, visible only when `IsWaitingForReview`: - Background `Surface2Brush`, top border `LineBrush` (`BorderThickness="0,1,0,0"`). - A `❯` prompt-prefix `TextBlock` (mono, `TextMuteBrush`) + a borderless mono `TextBox`: - Bound `Text="{Binding ReviewFeedback, Mode=TwoWay}"`. - `AcceptsReturn="True"`, `TextWrapping="Wrap"`, transparent background, no border. - Starts ~1 line tall; grows with content up to `MaxHeight≈160`, then scrolls. - `PlaceholderText` e.g. "Feedback for the next run…". - Right-aligned button strip: - `[Retry]` — `Classes="btn accent"` → `RejectReviewCommand`. - `[Reset]` — `Classes="btn"` → `ParkReviewCommand`. `[Accept]` is **not** in the footer; approval happens on the Git tab via `ApproveReviewCommand`. The old `Cancel` review button is dropped from this UI; cancel remains reachable through the task's existing cancel control (`CancelReviewCommand` stays on the ViewModel, just not surfaced here). ### Enter handling (`WorkConsole.axaml.cs`) - Handle `KeyDown` on the input `TextBox`: - **Enter** without Shift → execute `RejectReviewCommand` (if it can execute) and set `e.Handled = true`. - **Shift+Enter** → fall through to default behavior (inserts newline). - `RejectReviewAsync` already returns early on whitespace-only feedback (`DetailsIslandViewModel.cs:1464`), so pressing Enter with an empty prompt is a no-op with no extra guard needed. ## Command mapping | Button | Location | Command | Effect | | --- | --- | --- | --- | | `[Retry]` | Output footer | `RejectReviewCommand` | Reject-to-queue with feedback; resumes the session (Queued). | | `[Reset]` | Output footer | `ParkReviewCommand` | Park back to Idle. | | `[Approve]` | Git tab | `ApproveReviewCommand` | Merge `SelectedMergeTarget` → Done (conflict keeps it in review). | ## Copy / empty state - Update the Session empty-state text (`WorkConsole.axaml:270`) — it currently says "review and merge controls appear here once the run finishes", which is no longer accurate. Reword to reflect that only outcomes live on Session. - Button labels remain literal strings (`Retry`, `Reset`, `Approve`), matching the existing review buttons (no new localization keys). ## Out of scope - No changes to worker-side review/merge logic or `IWorkerClient` signatures. - No merge-target selector duplicated into the terminal footer (Approve uses the Git tab dropdown / default target). - No command renames on the ViewModel. ## Testing / verification - Build `ClaudeDo.App` and `ClaudeDo.Worker` in `-c Release`. - Manual visual verification (must be flagged — cannot be auto-verified): - Footer appears only in `WaitingForReview`, on the Output tab. - Enter sends Retry; Shift+Enter inserts a newline; empty Enter does nothing. - Git tab shows Approve + merge/worktree controls; Session shows only outcomes.