Review Hub
Stage, commit, push, review diffs, and resolve conflicts for any worktree without leaving Daintree.
Overview
Review Hub is Daintree's in-app Git workspace for a worktree. You stage files, read diffs, write a commit message, push to your remote, and resolve conflicts without switching to a terminal or another app. It exists mainly to review and ship the work an agent produced, but it handles any changes in the worktree.
The composer is the focal point. The file list starts collapsed, so you land on the commit message and expand the files when you want to look at them. Conflicts, divergence, and CI status all show up in the same place, so you rarely have to drop to the command line.
Opening Review Hub
There are four ways in.
From a worktree card
Open the three-dot menu on a worktree card and select Review & Commit. The right-click context menu has the same item. It's always available, even when the worktree has no changes.
Opening from the card auto-stages every unstaged file when nothing is staged yet, so you land on a ready-to-commit view. If you already have a partial staging set, it leaves that alone.
From the agent completion banner
When an agent finishes a run that touched files, a banner appears at the bottom of its pane: "N files changed, review when ready." Click Review to open Review Hub on that worktree. The banner also carries Send to assistant, which relays the completion to Daintree's built-in Help Agent when that session is running and idle, a Send to agent button, and a dismiss action.
When an agent finishes and changed nothing, you get a quiet "Finished, no changes" pill in the pane header instead. No banner, no toast. See Agents for how Daintree tracks agent runtime states.
From the notification center
When an agent finishes with changes, an Open review hub action appears on the inbox entry. Click it to open Review Hub for that worktree directly. See Notifications & Sound.
As a Review panel
You can also add Review as a persistent, non-modal panel. It lives in the panel grid alongside your terminals and agents and shows the same content as the modal, so you can keep a review surface open while an agent works. See Terminals & Panels for how panels are arranged. When no worktree is selected, the panel reads "Open a worktree to review and commit changes."
Header and chrome
The header runs left to right and tells you everything you need to know about the worktree:
- Branch pill: a monospace pill with the current branch name, truncated with a tooltip for long names.
- Protected chip: an amber "Protected" chip appears when the branch matches a protected-branch pattern. It's a heads-up that you probably want a pull request rather than a direct push.
- PR pill: when the worktree has a remote with a linked pull request, a read-only pill shows the PR number, its state, and its CI status when that's available. A "No PR" pill shows when there's a remote but no PR yet. With no remote, the pill is hidden.
- Open-in-browser button: a separate icon button next to the PR pill opens the pull request in your system browser.
- Diff mode toggle: switch between Working tree and vs {mainBranch} to change what the file list shows.
- Refresh button: visible in working-tree mode. It spins during background refreshes.
The PR pill is a status display, not a link. Clicking it does nothing. Use the open-in-browser button beside it to jump to the PR. The same CI status also shows on the worktree card itself: a check, an X, a colored dot, plus a short label. You can read build state without opening anything.
Working tree vs base branch
Working tree mode
This is the default. You get a Staged section, a Changes (unstaged) section, and the commit composer. The refresh button is visible. When the working tree is clean, you see "Working tree clean — No changes to commit."
Comparing against {mainBranch}
Toggle to vs {mainBranch} to see every file that differs from the main branch, listed flat under "Changed vs {mainBranch} (N files)." This view is read-only. No staging, no commit composer. Click any file to open its diff against the main branch. The toggle is disabled when you're already on the main branch, and it reverts to working-tree mode on its own if the branch becomes the main branch.
When a pull request has unresolved review comments, the matching rows show an amber count badge. Click it to open that file's conversation in the PR in your browser.
The file list
The file list is collapsed when Review Hub opens. A Show files (N) toggle expands it; once open it reads Hide files (N). The expanded state is remembered per worktree for the session, but it isn't saved to disk, so every fresh open starts collapsed.
Files split into two sections, Staged and Changes. Each section's count chip also shows churn: a green +N for inserted lines and a red −N for deleted lines across that section.
File rows
Each row carries a colored status badge, the file path with the directory prefix muted and the filename in normal weight, the churn for that file, a Viewed checkbox, and a +/− stage toggle. Plain-click a row to open its diff.
| Badge | Meaning | Color |
|---|---|---|
| M | Modified | Amber |
| A | Added | Green |
| D | Deleted | Red |
| R | Renamed | Blue |
| C | Copied | Blue |
| ? | Untracked | Green |
| ! | Conflict | Red |
| I | Ignored | Dimmed |
Staged rows get a subtle green tint. Generated files are dimmed so they don't compete with hand-written changes for your attention: lockfiles, dist/ and build/ output, .min.js, snapshots, and anything else matching the generated patterns.
Viewed marks
Tick the Viewed checkbox on a row to mark that you've read it. The row dims to about 60% so it recedes while the rest stay prominent. Viewed marks are tracked per section, so a path is independent in Staged versus Changes, and they're session-scoped only. They reset when you close Review Hub.
Empty states are explicit: "Working tree clean — No changes to commit," "Nothing staged," and "All changes staged." A filtered list that matches nothing offers a Clear filter action.
Staging files
Click + on an unstaged file to stage it, or − on a staged file to unstage it. Each section also has a bulk button that adapts to context. It reads Stage all (N) normally, Stage shown (N) when a filter or the hide-generated toggle is narrowing the list, and Stage selection (N) when you've multi-selected rows. The unstage variants mirror this in the Staged section.
Multi-select
To act on a subset, build a selection first. Cmd/Ctrl+click toggles individual rows, and Shift+click selects a contiguous range from the last anchor. Selection is scoped to one section at a time. Selected rows pick up a subtle overlay, and the bulk button switches to Stage selection (N). Press Escape to clear the selection.
Filtering and view options
Each section header has a filter input. It's glob-aware (*, **, ?, and [] all work) and falls back to a substring match otherwise, with a short debounce as you type.
Next to the filter is a view-options dropdown:
- Sort by: Path or Status. Click again to flip the direction.
- View: Comfortable or Compact density.
- Show generated files: toggle generated files in or out of the list entirely.
These settings are per session. They reset to their defaults when you close Review Hub: empty filter, sort by Path ascending, Comfortable, generated files shown.
Reviewing diffs
Click a file to open its diff in the File Viewer. You get a View/Diff toggle, a Split/Unified toggle, a copy-diff button, and Open in Editor. Generated diffs collapse by default, so a large lockfile change doesn't bury the real edits.
Inside the diff, n and p jump to the next and previous hunk and scroll it into view. They need no modifier, as long as you're not typing in a field. Cmd/Ctrl+F finds within the panel and Cmd/Ctrl+L jumps to a line. See File Viewer for the full panel reference.
To compare two separate worktrees side by side instead, use the cross-worktree diff described in Comparing Worktrees.
Committing
The composer sits at the bottom of working-tree mode. It's a monospace textarea that grows from two to six lines as you type. A vertical ruler marks column 72 and an N/72 counter tracks your subject line. The counter turns amber when any line runs past 72 characters, a nudge toward the standard Git convention.
With a remote configured, you get two buttons: a ghost Commit and a primary Commit & Push (N). With no remote, you get a single Commit (N).
Recalling recent messages
With the cursor at the very start of an empty composer, ↑ walks back through your last eight commit messages, bodies included, and ↓ walks forward again, restoring your in-progress draft at the end. Once you edit the text, the recall index resets.
What blocks a commit
The commit buttons are disabled when there's nothing staged, the message is empty, there are unresolved conflicts, or the worktree is in detached HEAD. Hover a disabled button to see the reasons listed. Click it to jump focus to the blocker, expanding the file list if that's what's needed.
When Review Hub is opened from a worktree card that has an agent note, the composer can be pre-seeded with the note's first line. Anything you type over it is kept.
Pushing
Clicking Commit & Push opens a confirmation first: "Push to '<branch>'?" with the branch pill, a full preview of the commit message, and a Don't ask again for this worktree checkbox. Tick it and future pushes from that worktree skip straight through. On a protected branch the dialog adds a line noting that most teams use pull requests instead.
The confirmation, and its per-worktree opt-out, applies to every remote push path, including the global Cmd/Ctrl+K, Cmd/Ctrl+P chord.
During the push you see "Pushing to <target>" with per-stage progress bars. The first push to a new branch sets the upstream for you.
If the push fails, an amber banner explains why and what to do about it. Authentication, network, and transient errors keep the detail short. Policy, hook, and unknown failures tuck the raw output behind a Show details toggle. An auth failure may surface a forge error code and an Open forge settings shortcut.
git push --set-upstream by hand.Recovering from divergence
When a push is rejected because the remote moved on, the banner reads "Remote has N new commits. Pull and rebase, or force push to overwrite." You have two recovery paths.
Pull and rebase
The primary option, Pull and rebase, opens a confirmation: "Pull and rebase '<branch>'? Replays N local commit(s) on top of M incoming commit(s) from the remote. Rebasing rewrites local commit history and cannot be undone." The counts come from the worktree's ahead/behind state. Confirm and the rebase runs. If it hits conflicts mid-replay, the working tree drops into the conflict view described below.
Force push
The secondary option, Force push, only appears when Daintree captured a lease for the remote branch. It opens a dialog titled "Force push <branch>?" that lists up to twenty Remote commits to discard with hash, message, and author, and an "…and N more" line past twenty, so you can see exactly what you'd overwrite. Confirm and it runs a force-push-with-lease.
--force-with-lease: it only overwrites the remote if it still matches the version Daintree saw when the push was rejected, so it won't blindly clobber a teammate's work. It will still discard every remote commit listed in the dialog. Pull and rebase is the safer default.Resolving conflicts
Review Hub resolves conflicts in place, so you don't have to drop to the terminal. When a worktree is mid-conflict, from a merge, rebase, cherry-pick, or revert, the file list is replaced by a three-region conflict panel.
Operation chrome
An amber banner names the operation: "Resolve Merge Conflicts," "Resolve Rebase Conflicts," and so on. For a rebase it also shows a Step N of M badge and a running conflict count. An Abort button backs the whole operation out. Its confirmation spells out exactly what gets discarded and restored for that operation type.
Rebase sequence rail
During a rebase, a vertical rail lists the full commit sequence so you can see where you are. Done commits get a check and dim out, the current commit is bold with an accent chevron, pending commits show a dashed circle, and dropped commits are struck through with a slash. Fixup and squash commits sit indented under their parent.
The worklist
Each conflicted file shows a warning icon, its path, a label like "both modified," and a badge with the number of conflict regions. Per file you can:
- Take ours / Take theirs: resolve the whole file one way, each behind a confirmation. During a rebase the tooltips spell out the inversion, since "ours" and "theirs" swap meaning.
- Open: jump to the file in your external editor at the first conflict marker.
- Mark resolved: stage the file once you've handled it by hand.
Resolved files collapse into a Resolved (N) disclosure. The Continue button at the bottom is enabled only once no conflicts remain.
Detached HEAD
When a worktree is in a detached HEAD state, the composer shows an amber warning and disables the textarea and commit buttons. Check out a named branch before you can commit.
git checkout -b <branch-name>.Errors and auto-refresh
If git status fails to load, a red banner with a Retry button replaces the file lists. A push that's rate-limited reports "Too many push attempts" instead of a raw error.
Review Hub watches the worktree for changes and refreshes in the background with an 800ms debounce, so the lists stay current while an agent writes files. Your scroll position is kept, and the surface dims briefly while a refresh is in flight.
Keyboard shortcuts
Inside Review Hub:
| Shortcut | Where | Action |
|---|---|---|
| n / p | Diff viewer | Next / previous hunk |
| Cmd/Ctrl+Enter | Composer | Commit & Push (or Commit with no remote) |
| Cmd/Ctrl+Shift+Enter | Composer | Commit only |
| ↑ / ↓ | Composer (at start) | Recall previous / next commit message |
| Cmd/Ctrl+click | File row | Toggle multi-select |
| Shift+click | File row | Range-select from anchor |
| Cmd/Ctrl+F | File viewer | Find in panel |
| Cmd/Ctrl+L | File viewer | Go to line |
Escape works in priority order: it closes an open diff first, then clears a multi-selection, then closes Review Hub.
Daintree also has global Git chords that act on the active worktree whether or not Review Hub is open:
| Chord | Action |
|---|---|
| Cmd/Ctrl+K, Cmd/Ctrl+A | Stage all changes |
| Cmd/Ctrl+K, Cmd/Ctrl+C | Commit staged changes |
| Cmd/Ctrl+K, Cmd/Ctrl+P | Push to remote |
Chords are two key combos pressed in sequence, within about a second. For the full reference, see Keyboard Shortcuts.
What persists, what resets
Most of Review Hub's view state is per session and resets when you close it. Two things survive a restart: the diff Split/Unified preference and the per-worktree push-confirm opt-out.
| Setting | Scope |
|---|---|
| Diff view (Split / Unified) | Persisted across restarts |
| "Don't ask again" push confirmation | Persisted, per worktree |
| File list expanded / collapsed | Session only, per worktree |
| Filter, sort, density, show-generated | Session only (reset to defaults) |
| Viewed marks | Session only |