## Context
Closes#53741
Right-clicking on a link in any Markdown view showed no way to copy the
URL. The right-click handler already detected links for left-click
navigation, but the context menu was never extended to surface a
link-specific action.
Video of the manual test below :
[Screencast from 2026-04-13
00-29-49.webm](https://github.com/user-attachments/assets/fbde09ab-78da-4366-b1e0-e15e0d43442b)
## How to Review
- **`crates/markdown/src/markdown.rs`** — Added a `context_menu_link:
Option<SharedString>` field to `Markdown`. Added
`capture_for_context_menu(link)` (replaces the old
`capture_selection_for_context_menu`) which saves both selected text and
the hovered link together. Added a `context_menu_link()` accessor.
Updated the capture-phase right-click handler to detect the link under
the cursor via `rendered_text.link_for_source_index`. Added a
`event.button != MouseButton::Right` guard to the bubble-phase
`MouseDownEvent` handler to prevent selection logic from running on
right-click.
- **`crates/agent_ui/src/conversation_view/thread_view.rs`** — In
`render_message_context_menu`, after computing `has_selection`, also
reads `context_menu_link` from the same markdown chunks. Adds a "Copy
Link" entry with a separator at the top of the menu when a link URL is
present.
- **`crates/markdown_preview/src/markdown_preview_view.rs`** — Wraps the
markdown element in a `right_click_menu` with a "Copy Link" entry (when
a link is present).
Edit: There was a mention of a "Copy" and "Copy as Markdown" buttons.
After discussion, it was decided that I would re-add them fully fleshed
out in a separate PR
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Added "Copy Link" to the right-click context menu when clicking on a
link in Markdown views (agent panel and Markdown preview)
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#54419
Release Notes:
- Fixed Agent menu shortcut context handling so Alt-Shift-L consistently
resolves to Rules (and displays correctly) when the Toggle Agent Menu is
open, while preserving existing global/context-specific shortcuts such
as Language Servers and onboarding bindings outside Agent menu context.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
The `ReviewBranchDiff`, `ResolveConflictsWithAgent`, and
`ResolveConflictedFilesWithAgent` actions are dispatched from the git UI
(`git_ui/src/project_diff.rs` and `git_ui/src/conflict_view.rs`), not
the agent panel. Their `source` field in the "Agent Thread Started"
telemetry event was set to `"agent_panel"` — this changes it to
`"git_panel"`.
Also threads the `source` parameter through `activate_draft` and
`ensure_draft` so that drafts created from the sidebar correctly report
`source = "sidebar"` instead of `"agent_panel"`.
Release Notes:
- N/A
The recent-projects picker, sidebar, welcome screen, and agent thread
store all called `recent_workspaces_on_disk`, which combined listing
with deleting stale rows. Its retention predicate rejected workspaces
with no on-disk directory, including empty workspaces holding unsaved
scratch buffers, and the resulting `delete_workspace_by_id` call
cascaded into `items`, `pane_groups`, and the per-editor tables. For
clarity, the method has been renamed to `recent_workspaces_for_ui`.
Meanwhile, `last_session_workspace_locations` used a slightly different
form of the same predicate. The two disagreeing on what counts as a
valid workspace caused #48799, `Workspace WorkspaceId(N) not found`
errors on repeated launches (#50409), the
`test_window_edit_state_restoring_enabled` flake (#50871), and the
foreign key constraint fail on `projects: open recent` with a dirty
scratch buffer (#51456).
Note that for the last issue mentioned (#51456) there is no save prompt
for scratch buffers. This seems out of scope for this PR so I'll fix
that after this is addressed.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#48799Closes#50409Closes#50871Closes#51456
Release Notes:
- Fixed unsaved scratch buffers being lost across restarts and an
occasional error when opening a recent project.
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
Release Notes:
- N/A
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
Release Notes:
- N/A
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
Release Notes:
- N/A
Use stored thread metadata during reset when no root thread view exists,
so retries keep the original session id and title instead of starting a
new session.
Add a regression test for reconnecting after an initial custom agent
load failure.
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
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
Release Notes:
- N/A
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
This PR improves the hover state in thread items within the history view
by making them more stable. There were other thread events calling a
refresh, which would clear the hover state even though I'd still be
hovering the item, making the buttons that only appear on hover feel
unstable and disappear.
Release Notes:
- Agent: Improve hover state stability on thread items within the
sidebar's history view.
Fixes two problems:
* We were not preserving scroll position in the thread history view when
the thread metadata store updated
* We were updating thread metadata on every single chunk streamed by the
agent, even though the content of the thread does not affect its
metadata.
Release Notes:
- N/A
Closes#54313
**Before:**
- Favoriting a model only stored `provider`, `model`, and hardcoded
`enable_thinking` to `false`.
- Selecting a favorited model would not restore your preferred
`enable_thinking`, `effort`, or `speed` settings.
This means that if you'd like to use, say, GPT 5.4 your favorite model
on `xhigh` effort every single time, switching to it would set effort to
`medium` (the default for the model) instead.
**After:**
- Favoriting a model captures your current `enable_thinking`, `effort`,
and `speed` when it matches the currently-selected model. Otherwise, it
falls back to the model's own defaults, i.e. thinking-capable models are
no longer favorited with `enable_thinking` forced to `false`.
- Selecting a favorited model applies its stored thinking / effort /
speed.
- Toggling thinking, changing effort, or toggling fast mode on a
favorited model updates the favorite entry in settings (along with the
existing `default_model` setting), so the preference doesn't drift.
Release Notes:
- Agent favorite models now remember and restore per-model thinking,
effort level, and fast mode preferences.
There were a few places where you could trigger generation without
causing the `interacted_at` field to be set.
Also renames `message_sent_or_queued` to `interacted`, to be consistent
with the field on `ThreadMetadata`
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR adds support for rendering **Netpbm** image formats (`.pbm`,
`.ppm`, `.pgm`) within Zed's built-in image viewer.
These formats are particularly useful for projects that want minimal
external dependencies, a common scenario in academic environments and
low-level graphics programming.
Since the underlying `image` crate and `GPUI` already provide support
for these codecs, this change explicitly exposes the `Pnm` variant
within `gpui::ImageFormat` by mapping it to `image::ImageFormat::Pnm`.
## Screenshots/Examples
Below is an example of `.pbm`, `.ppm`, and `.pgm` files being rendered
correctly in the image preview (images taken from
https://filesamples.com):
<img width="1917" height="1012" alt="pnm_example"
src="https://github.com/user-attachments/assets/0056133f-908c-4c91-ba9d-53aef0657b05"
/>
Release Notes:
- Added support for PNM image previews (`.pbm`, `.ppm`, `.pgm`).
Follow up to https://github.com/zed-industries/zed/pull/52730.
This PR adds a boolean setting `limit_content_width` in the Agent Panel
settings that allows turning off the content max-width entirely, which
was added for better readability. We had a handful of requests for it,
so it feels fair.
<img width="500" alt="Screenshot 2026-04-20 at 8 57@2x"
src="https://github.com/user-attachments/assets/d2540b35-3fa8-4424-895d-dc499ac4839c"
/>
Release Notes:
- Agent: Added a new `limit_content_width` setting in the agent panel
that allows turning off the content max-width limit.
This PR makes Zed only have one worktree picker, as opposed to a flavor
of it in the title bar and another in the agent panel. It then moves it
to the title bar, making it always present, so that its trigger is
separate from the branch picker (which now contains only two views:
branches and stashes). For the worktree picker, I'm mostly favoring the
behavior we've introduced in the agent-panel-flavored version.
It also updates the title bar settings migration to use the JSON
`migrate_settings` helper instead of a shallow Tree-sitter rewrite, so
old `show_branch_icon = true` values are promoted to
`show_branch_status_icon = true` across root, platform, release-channel,
and profile settings scopes.
- [x] Move worktree creation logic to the `git_ui` crate to make this
more generic and less agent-specific
- [x] Double-check the remote use case and ensure nothing broke there
- [x] Improve the UX for the detached HEAD state; better invite people
to create a branch
- [x] Migrate `show_branch_icon = true` to `show_branch_status_icon =
true` across nested settings scopes
Suggested .rules additions
When migrating renamed settings keys that can appear in platform
overrides, release-channel overrides, or profiles, prefer the JSON
`migrations::migrate_settings` helper over shallow Tree-sitter key
rewrites unless tests explicitly cover every nested scope that can
contain the key.
Release Notes:
- Improved migration of the title bar branch status icon setting.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This PR revamps our feature flag system, to enable richer iteration.
Feature flags can now:
- Support enum values, for richer configuration
- Be manually set via the settings file
- Be manually set via the settings UI
This PR also adds a feature flag to demonstrate this behavior, a
`agent-thread-worktree-label`, which controls which how the worktree tag
UI displays.
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
This is a follow up to: #54202
`thread_worktree_archive.rs` had its own
walk-up-and-remove-empty-parents pass that ran after archiving a Zed
managed git worktree. It duplicated logic that #54202 moved into
`Repository::remove_worktree` (which also adds remote support for this)
This PR deletes the dead code path and its associated tests.
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
We currently, unfortunately, don't support title summarization and/or
regeneration for external agents, so we should hide that menu for them
so it's not misleading.
Release Notes:
- N/A
- Ensures the activity bar properly reacts to the shrinking of the agent
panel's width
- Removes horizontal scroll from plan entries and instead add a tooltip
to display the full content when not fully visible
Release Notes:
- N/A
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them. This is an MVP and will later be
expanded with a picker, vim marks integration and syntax tree based
bookmark positions. In this MVP bookmarks shift under external edits.
# UI
## Adding/Removing bookmarks
To add a bookmark:
- run the toggle bookmark action
- hold secondary and click in the gutter
- open the context menu by right clicking in the gutter and select add
bookmark To remove a bookmark:
- run the toggle bookmark action
- click on the bookmarks icon in the gutter
- open the context menu by right clicking in the gutter and select
remove bookmark
remove all bookmarks with `workspace: clear bookmarks`
# Implementation
This mirrors the implementation of breakpoints. The rendering of the
gutter was refactored to make place for bookmark icons and buttons:
- Code was extracted to a `Gutter` struct
- Runnables, breakpoints and bookmarks are now collected ahead of
layouting. Just before layouting we remove the items that collide and do
not have priority.
- The `phantom_breakpoint` is replaced by a `gutter_hover_button`
## In depth phantom breakpoint discussion:
This was phantom_breakpoint. It worked as follows:
- A fake breakpoint was added to the list of breakpoints.
- While rendering the breakpoints it a breakpoint turned out to be fake
it would get a different description and look.
- The breakpoint list was edited run_indicators ("play buttons")
rendering to removes the fake breakpoint if it collided.
This would not scale to more functionality. Now we only render
breakpoints, bookmarks and run indicators. Then we render a button if
there is not breakpoint, bookmark or run indicator already present. We
can do so since the rendering of such "gutter indicators" has been
refactored into two phases:
- collect the items.
- render them if no higher priority item collides.
This is far easier and more readable which enabled me to easily take the
phantom_breakpoint system and use it for placing bookmarks as well :)
Note: this was previously merged but it needed a better squashed commit
message. For the actual PR see: 51404. This reverts commit
1c3846e76f.
Release Notes:
- Added Bookmarks
Co-authored-by: Austin Cummings <me@austincummings.com>
Closes#4526
Adds basic bookmark functionality to the editor, allowing users to mark
lines and later navigate between them.
### What's new
**Toggling bookmarks**
Users can toggle a bookmark on the current line(s) via the `editor:
toggle bookmark` action. A bookmark icon appears in the gutter for each
bookmarked line.
**Navigation**
Two new actions, `editor: go to next bookmark` and `editor: go to
previous bookmark`, navigate between bookmarks in the current buffer,
wrapping around at the ends of the buffer.
**Viewing all bookmarks**
`editor: view bookmarks` opens all bookmarks across the project in a
multibuffer, similar to how references and diagnostics are surfaced.
**Clearing bookmarks**
`workspace: clear bookmarks` removes all bookmarks in the current
project.
**Persistence**
Bookmarks are persisted to the workspace database and restored when the
workspace is reopened. They are stored as `(path, row)` pairs and
resolved back to text anchors. Out of range or unresolvable bookmarks
are skipped with a logged warning.
**Gutter rendering**
Bookmark icons are rendered in the gutter using the existing gutter
button layout system, consistent with breakpoints. They are suppressed
on lines that already show a breakpoint or phantom breakpoint indicator.
A new `gutter.bookmarks` setting (defaulting to `true`) controls their
visibility.
### What's left
- [x] Lazily load buffers that have bookmarks
- [x] Clean up test boilerplate
- [ ] Assign default keybindings
- [ ] Compare line of saved bookmarks with current buffer (gray out the
"stale" bookmarks)
### What's next (and nice to haves)
- [ ] Resilience against external edits
- [ ] Save column position with the bookmark
- [ ] Bookmarks attached to syntactic structures?
- [ ] Labeled bookmarks?
---
Release Notes:
- Added bookmarks: toggle bookmarks on lines with `editor: toggle
bookmark`, navigate with `editor: go to next bookmark` / `editor: go to
previous bookmark`, view all bookmarks with `editor: view bookmarks`,
and clear with `workspace: clear bookmarks`. Bookmarks are shown in the
gutter and persisted across sessions.
---------
Co-authored-by: Yara <git@yara.blue>
### Summary
Follow up to: https://github.com/zed-industries/zed/pull/54001
This PR makes
`agent_ui::thread_worktree_archive::find_or_create_repository` whether
or not the repository it's searching for is on a remote machine. In the
case where it's on a remote machine that has an active connection in
Zed's connection pool, we return the repository; otherwise, we error
out.
I implemented it this way so archiving a thread on a remote machine that
isn't connected deletes the metadata without showing a remote connection
modal to a user. In the future, we can work around this by having better
git worktree garbage collection, where remote machines remove git
worktree's that were created by Zed and have no thread metadata on
connection too.
Finally, this PR gets archive threads working on remotes!
#### Follow Ups
1. Replace instances of `std::fs` with Zed's Fs trait in the archive
thread codepaths
2. Make archive thread work properly for workspace's that are not open
(local and remote)
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Reimplements #36722 while fixing the race that required the revert in
#36932.
When no default model is configured, this picks an environment fallback
by authenticating all providers. It always prefers the Zed cloud
provider when it's authenticated, and waits for its models to load
before picking another provider as the fallback, so we don't flicker
from Zed models to Anthropic while sign-in is in flight.
The fallback is recomputed whenever provider state changes (via
`ProviderStateChanged`/`AddedProvider`/`RemovedProvider` events), so the
selection becomes correct as soon as cloud models arrive.
### What changed vs. the original PR
- `language_models::init` now owns `authenticate_all_providers`
(previously done in `LanguageModelPickerDelegate` and `agent`'s
`LanguageModels`).
- After all authentications settle, and on any subsequent provider state
change, `update_environment_fallback_model` recomputes the fallback.
- The fallback logic prefers Zed cloud: if the cloud provider is
authenticated, only use it (waiting for its models to load). Otherwise,
fall through to the first authenticated provider with a default or
recommended model.
- `LanguageModelRegistry::default_model()` falls back to
`environment_fallback_model` when no explicit default is set.
- Existing `Thread`s that are empty are updated to the new default when
`DefaultModelChanged` fires, so a blank thread started before sign-in
switches to Zed models once the user signs in.
Release Notes:
- agent: Automatically select a model when there's no selected model or configured default
This renames the Archive view to Thread History in all user-facing
surfaces. The concept of archiving a thread (the verb/state) remains
unchanged — only the view that lists all threads is renamed, since it
shows both active and archived entries.
## Changes
- Rename `ViewAllThreads` action → `ToggleThreadHistory`
- Context-sensitive tooltip: "Show Thread History" / "Hide Thread
History"
- Update action doc comment to reference "history" instead of "archive
view"
- Telemetry event: `Thread History Viewed`
- `SerializedSidebarView::Archive` → `History` (with `#[serde(alias =
"Archive")]` for backward compat)
- Add a Lucide-based clock icon adapted to 16×16 / 1.2px stroke
- Switch the history toggle button to use the new clock icon
- Update all three platform keymaps
cc @danilo-leal
Release Notes:
- Renamed the threads Archive view to Thread History and updated its
icon to a clock.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Make sure that we never write thread metadata to the DB for a thread
running on a collab project.
When joining a collab project and starting a native thread we would set
all your threads that had no paths associated with to the path of the
collab project (in `move_thread_paths`).
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Release Notes:
- Fixed a bug where the agent panel would sometimes close if you
scrolled up or down while it was zoomed.
Co-authored-by: Lukas <lukas@zed.dev>
Replace `std::fs::remove_dir_all` with the `Fs` trait's `remove_dir`
method in `remove_root_after_worktree_removal`. This makes the code
testable with `FakeFs` and consistent with the rest of the codebase.
- Add `Arc<dyn Fs>` parameter to `remove_root` and its internal helper
- Use `RemoveOptions { recursive, ignore_if_not_exists }` which handles
both the recursive deletion and NotFound cases cleanly
- Pass `fs` from workspace `AppState` through the sidebar call chain
- Add test verifying error propagation and rollback when `remove_dir`
fails
- Remove tests that were testing raw `std::fs::remove_dir_all` patterns
Release Notes:
- N/A
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
Release Notes:
- N/A
Replace call sites that treated the active thread as the root thread
with the dedicated `root_thread_view` and `root_thread` helpers, and
simplify `ConversationView` lookups to avoid passing `cx` when it is
not needed.
Also emit token limit telemetry when usage crosses warning or exceeded
thresholds, while avoiding duplicate events for the same session state.
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
When the Agent panel (or any dock panel without its own pane) is focused
and a file is open in the center editor, pressing `/` in vim mode would
steal focus to the buffer's search bar instead of staying on the panel.
## Root cause
`Vim::pane()` calls `workspace.focused_pane()`, which falls back to the
center pane when a dock panel without its own `pane()` method is
focused. Vim search commands then open the `BufferSearchBar` on the
center pane and focus it, stealing focus from the panel.
## Fix
Add a guard in `Vim::pane()` that returns `None` when the resolved pane
doesn't actually contain focus. This prevents all vim search/match
commands (`/`, `?`, `n`, `N`, `*`, `#`, etc.) from stealing focus from
non-pane panels.
All 497 vim tests and 253 agent_ui tests pass.
Release Notes:
- Fixed vim search (`/`) stealing focus from the Agent panel when a file
is open in the editor.
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
Closes #ISSUE
Release Notes:
- N/A
## Summary
Adds three tests that exercise session disassociation ("Session not
found" after reopening a thread). The third test **fails**, reproducing
the bug.
### Root cause
A retained `ConversationView` with a `thread_error` receives
`AgentServersUpdated`, which triggers `reset()` → `close_all_sessions` →
state transitions to `Loading`. When the user then reopens the same
session via `open_thread`, `load_agent_thread`'s `has_session` check
returns `false` (because the retained view is in `Loading` state, not
`Connected`), so a **second** `ConversationView` is created for the same
session. Both views' async load tasks complete and both transition to
`Connected` with the same session ID. When the retained view is later
cleaned up, its `on_release` → `close_all_sessions` removes the session
from the connection, leaving the active view stranded with a dead
session.
### Tests
| Test | Status | What it verifies |
|------|--------|-----------------|
| `test_open_thread_on_visible_session_does_not_disassociate_it` | ✅
Pass | `load_agent_thread` short-circuits when session is already active
|
| `test_retained_thread_cleanup_does_not_disassociate_reopened_session`
| ✅ Pass | Eviction + reopen cycle works (close-then-reload) |
| `test_retained_thread_reset_race_disassociates_session` | ❌ **Fail** |
Reproduces the race described above |
cc @bennetbo @ConradIrwin
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
## Problem
When creating a new agent thread from the sidebar's **+** button (or via
the `NewThread` / `NewThreadInGroup` actions), the panel always returned
the cached draft thread — even if the user had since switched to a
different agent. This meant the new thread would use the wrong agent
(typically the default Zed Agent instead of the last-used external
agent).
The root cause was in `ensure_draft()`: it cached the draft and returned
it unconditionally on subsequent calls without checking whether its
agent
matched the current `selected_agent`.
Meanwhile, **cmd-n from within the agent panel** dispatched
`NewExternalAgentThread`, which calls `create_thread()` — this always
creates a fresh thread with the correct `selected_agent`, so it worked
fine.
## Fix
`ensure_draft()` now compares the cached draft's agent against the
desired agent. When they differ and the draft's editor is empty, the
stale draft is discarded and a new one is created with the correct
agent.
If the draft has user-typed content, it is preserved to avoid losing
work.
## Test
Added `test_draft_replaced_when_selected_agent_changes` which verifies:
1. A draft created with `NativeAgent` gets replaced when
`selected_agent`
changes to a custom agent
2. The replacement draft uses the correct agent
3. Calling `activate_draft` again with the same agent reuses the cached
draft (no unnecessary replacement)
The test fails without the fix (returns the stale `NativeAgent` draft)
and passes with it.
Release Notes:
- N/A
- Don't ever swap to the ellipsis menu with the close icon button; we
now always have it
- Promote the "focus the last workspace" feature through the ellipsis
menu
- Add a unified tooltip for the thread item to show relevant thread
metadata
- Use a different icon for accessing the now "all threads" view
- Simplifies how we display archived threads
- Bonus: Don't display the "open in new window" button in currently
active worktrees (in dedicated picker)
- Bonus: Use the "main worktree" label for whenever we're mentioning the
original worktree
Release Notes:
- N/A
- Adds a status toast to the announcement banner for surfacing the
layout revert option
- Removes the agent panel banner
A good chunk of the diff here was because I touched up the status toast
component API a little bit.
Release Notes:
- N/A
The cross-channel import tests from #54002 hardcoded
`ReleaseChannel::Preview` and `ReleaseChannel::Nightly` as source
channels. When those tests run on a release branch (where the current
channel is Preview or Nightly), the import skips the current channel,
causing test failures.
This adds a `foreign_channels` helper that dynamically picks two
channels that are neither the current one nor Dev, making the tests work
on main, preview, nightly, or any other branch.
Discovered while cherry-picking #54002 to v0.233.x (#54021).
Release Notes:
- N/A
Users have been testing the threads sidebar on Nightly and Preview but
once we release the feature we expect many of these users to move back
to Stable. As it stands right now, they would lose the threads they'd
been working on. This PR adds a way to import these threads.
- [x] Add `agent: import threads from other channels` action to the
command palette.
- This can be always available for users that switch between channels
regularly.
- [x] Add tests for import behavior
- [x] Add a button that disappears after using it to make importing more
discoverable for when users first switch.
Release Notes:
- Added an action to the command palette that imports threads from other
Zed release channels into the current one.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
When archiving a thread, we now check whether the linked worktree lives
inside the Zed-managed worktrees directory (configured via
`git.worktree_directory`). If it doesn't — meaning the user created it
themselves outside of Zed — we skip both the directory deletion and the
`git worktree remove`, leaving it untouched.
Previously, archiving a thread would delete *any* linked worktree
associated with the thread's folder paths, even ones the user had
created manually via `git worktree add`.
Release Notes:
- Fixed archiving an agent thread deleting linked git worktrees the user
created outside of Zed's managed worktrees directory.
The `worktree_receivers` and `worktree_directory_setting` were pre
computed as `Option`s before the async block, then unwrapped with
`expect` inside the match arm that always had them set. Move the
fetching directly into the `WorktreeCreationArgs::New` arm so the values
are never optional, replacing the panicking expects with error
propagation via `?`.
The expects were guaranteed to never panic because the `Some` codepath
used the same branching logic of the unwrap codepath later on. This
change is just for future maintainability though.
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)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A or Added/Fixed/Improved ...