agent_ui: Show full branch name in thread branch picker aside (#53791)

XiaoYan Li , Claude Opus 4.6 (1M context) , and Danilo Leal created

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

## Summary

- Display the full branch name in the DocumentationAside panel for
thread branch picker entries, so users can see truncated branch names in
full
- Add a separator between the branch name and descriptive text, matching
the pattern used by the model selector's DocumentationAside

Release Notes:

- Agent: Improved branch picker by displaying the full branch name in
the documentation aside.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>

Change summary

crates/agent_ui/src/thread_branch_picker.rs | 49 +++++++++++++++++++++-
1 file changed, 46 insertions(+), 3 deletions(-)

Detailed changes

crates/agent_ui/src/thread_branch_picker.rs 🔗

@@ -292,6 +292,21 @@ impl ThreadBranchPickerDelegate {
         }
     }
 
+    fn entry_branch_name(&self, entry: &ThreadBranchEntry) -> Option<SharedString> {
+        match entry {
+            ThreadBranchEntry::CurrentBranch => {
+                Some(SharedString::from(self.current_branch_name.clone()))
+            }
+            ThreadBranchEntry::DefaultBranch => {
+                self.default_branch_name.clone().map(SharedString::from)
+            }
+            ThreadBranchEntry::ExistingBranch { branch, .. } => {
+                Some(SharedString::from(branch.name().to_string()))
+            }
+            _ => None,
+        }
+    }
+
     fn entry_aside_text(&self, entry: &ThreadBranchEntry) -> Option<SharedString> {
         match entry {
             ThreadBranchEntry::CurrentBranch => Some(SharedString::from(
@@ -742,17 +757,45 @@ impl PickerDelegate for ThreadBranchPickerDelegate {
         cx: &mut Context<Picker<Self>>,
     ) -> Option<DocumentationAside> {
         let entry = self.matches.get(self.selected_index)?;
-        let aside_text = self.entry_aside_text(entry)?;
+        let branch_name = self.entry_branch_name(entry);
+        let aside_text = self.entry_aside_text(entry);
+
+        if branch_name.is_none() && aside_text.is_none() {
+            return None;
+        }
+
         let side = crate::ui::documentation_aside_side(cx);
 
         Some(DocumentationAside::new(
             side,
-            Rc::new(move |_| Label::new(aside_text.clone()).into_any_element()),
+            Rc::new(move |cx| {
+                v_flex()
+                    .gap_1()
+                    .when_some(branch_name.clone(), |this, name| {
+                        this.child(Label::new(name))
+                    })
+                    .when_some(aside_text.clone(), |this, text| {
+                        this.child(
+                            div()
+                                .when(branch_name.is_some(), |this| {
+                                    this.pt_1()
+                                        .border_t_1()
+                                        .border_color(cx.theme().colors().border_variant)
+                                })
+                                .child(Label::new(text).color(Color::Muted)),
+                        )
+                    })
+                    .into_any_element()
+            }),
         ))
     }
 
     fn documentation_aside_index(&self) -> Option<usize> {
         let entry = self.matches.get(self.selected_index)?;
-        self.entry_aside_text(entry).map(|_| self.selected_index)
+        if self.entry_branch_name(entry).is_some() || self.entry_aside_text(entry).is_some() {
+            Some(self.selected_index)
+        } else {
+            None
+        }
     }
 }