Diff review comments: store locally and batch submit to agent (#46669)

Doesn't support editing or deleting comments yet, but inputs work:

<img width="797" height="881" alt="Screenshot 2026-01-14 at 11 51 36 AM"
src="https://github.com/user-attachments/assets/746e085b-a919-475a-b804-ee0377e40a0b"
/>


<img width="698" height="178" alt="Screenshot 2026-01-14 at 11 47 51 AM"
src="https://github.com/user-attachments/assets/3edac0e8-62e5-4af5-a324-df2bd293f3ca"
/>

<img width="695" height="695" alt="Screenshot 2026-01-14 at 11 47 58 AM"
src="https://github.com/user-attachments/assets/64795ffd-62b4-48ea-a46c-7724221095d7"
/>


### Features implemented:
- **Local comment storage**: Comments are stored per-hunk in the Editor,
with chronological ordering
- **Expandable comments section**: Shows "N Comments" header that can
expand/collapse
- **Inline editing**: Click edit to transform a comment row into an
editable text field with confirm/cancel buttons
- **Delete functionality**: Remove individual comments
- **Send Review to Agent**: Toolbar button with badge showing comment
count, batch-submits all comments across all files/hunks to the Agent
panel
- **User avatars**: Shows the current user's avatar (from their Zed
account) next to comments, falls back to Person icon when not logged in
- **Visual tests**: Added tests for one comment, multiple comments
expanded, and comments collapsed

Note that this is behind a feature flag, so no release notes yet.

Release Notes:

- N/A

---------

Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: David Baldwin <baldwindavid@gmail.com>
This commit is contained in:
authored and GitHub committed 2026-01-14 17:43:38 +00:00
1 parent 0350e0ca87
commit 415f384ff3
10 files changed
+2491 -42

No files matched your search

+47 -4
View File
@@ -9,7 +9,7 @@ use buffer_diff::{BufferDiff, DiffHunkSecondaryStatus};
use collections::{HashMap, HashSet};
use editor::{
Addon, Editor, EditorEvent, SelectionEffects, SplittableEditor,
actions::{GoToHunk, GoToPreviousHunk},
actions::{GoToHunk, GoToPreviousHunk, SendReviewToAgent},
multibuffer_context_lines,
scroll::Autoscroll,
};
@@ -70,6 +70,7 @@ pub struct ProjectDiff {
workspace: WeakEntity<Workspace>,
focus_handle: FocusHandle,
pending_scroll: Option<PathKey>,
review_comment_count: usize,
_task: Task<Result<()>>,
_subscription: Subscription,
}
@@ -311,8 +312,16 @@ impl ProjectDiff {
});
diff_display_editor
});
cx.subscribe_in(&editor, window, Self::handle_editor_event)
.detach();
let editor_subscription = cx.subscribe_in(&editor, window, Self::handle_editor_event);
let primary_editor = editor.read(cx).primary_editor().clone();
let review_comment_subscription =
cx.subscribe(&primary_editor, |this, _editor, event: &EditorEvent, cx| {
if let EditorEvent::ReviewCommentsChanged { total_count } = event {
this.review_comment_count = *total_count;
cx.notify();
}
});
let branch_diff_subscription = cx.subscribe_in(
&branch_diff,
@@ -363,8 +372,12 @@ impl ProjectDiff {
multibuffer,
buffer_diff_subscriptions: Default::default(),
pending_scroll: None,
review_comment_count: 0,
_task: task,
_subscription: branch_diff_subscription,
_subscription: Subscription::join(
branch_diff_subscription,
Subscription::join(editor_subscription, review_comment_subscription),
),
}
}
@@ -453,6 +466,16 @@ impl ProjectDiff {
}
}
/// Returns the total count of review comments across all hunks/files.
pub fn total_review_comment_count(&self) -> usize {
self.review_comment_count
}
/// Returns a reference to the splittable editor.
pub fn editor(&self) -> &Entity<SplittableEditor> {
&self.editor
}
fn button_states(&self, cx: &App) -> ButtonStates {
let editor = self.editor.read(cx).primary_editor().read(cx);
let snapshot = self.multibuffer.read(cx).snapshot(cx);
@@ -1278,6 +1301,7 @@ impl Render for ProjectDiffToolbar {
};
let focus_handle = project_diff.focus_handle(cx);
let button_states = project_diff.read(cx).button_states(cx);
let review_count = project_diff.read(cx).total_review_comment_count();
h_group_xl()
.my_neg_1()
@@ -1419,6 +1443,25 @@ impl Render for ProjectDiffToolbar {
})),
),
)
// "Send Review to Agent" button (only shown when there are review comments)
.when(review_count > 0, |el| {
el.child(vertical_divider()).child(
Button::new(
"send-review",
format!("Send Review to Agent ({})", review_count),
)
.icon(IconName::ZedAssistant)
.icon_position(IconPosition::Start)
.tooltip(Tooltip::for_action_title_in(
"Send all review comments to the Agent panel",
&SendReviewToAgent,
&focus_handle,
))
.on_click(cx.listener(|this, _, window, cx| {
this.dispatch_action(&SendReviewToAgent, window, cx)
})),
)
})
}
}