Adding a series of UI tweaks to refine how we display whether a thread
is covered by sandbox. Most notably, separating all the tooltip UI stuff
into a dedicated component so we can get a preview and iterate more
easily on all of its states.
Release Notes:
- N/A
# Objective
Fix unreliable working/status indicators for ACP agent threads.
ACP threads update their internal running state when a turn starts,
completes, or is canceled, but those status-only changes were not being
emitted as thread events. The agent UI could miss transitions unless
another entry-related event happened nearby, making it particularly hard
to monitor the status of multiple agent threads running at once.
Hope this helps, and thanks for making Zed.
## Solution
- Add an `AcpThreadEvent::StatusChanged` event.
- Emit it when `running_turn` is set, cleared, or canceled.
- Have `ConversationView` handle the event by syncing the active thread
view's generating indicator.
- Treat status changes as UI state only, not root thread metadata
changes.
## Testing
- `cargo check -p sidebar -p project -p git_ui -p workspace`
- Manually verified in a local dev build on macOS that ACP agent
status/working indicators update reliably.
No automated test was added; this changes UI synchronization for ACP
thread status events.
## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Fixed unreliable working indicators for ACP agent threads.
This separates the two user-message identities we currently need in
agent threads:
- `protocol_id`: the ACP `messageId` used to group or split streamed
message chunks from ACP agents.
- `client_id`: the Zed-generated user message ID used by the native
agent for truncate, rewind, edit/regenerate, checkpoints, token usage,
and persistence.
The main behavior change is that ACP protocol message IDs now affect
message merging/rendering without leaking Zed-native client IDs into ACP
agents by default. Agents that can accept Zed-generated user message IDs
opt into that path through `AgentSessionClientUserMessageIds`, which
owns both ID generation and prompt submission. The native Zed agent
implements that capability; normal ACP agents continue through the
protocol-only `prompt` path.
In ACP v2 we'll have a mechanism for getting user message replays that
will allow the agent to adequately generate it's own opaque id that we
can then use for these other capabilities. But for now, this split at
least makes sure we keep the two concepts distinct.
Release Notes:
- N/A
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This PR unships shared threads.
The feature is not used much and is getting in the way, at this point.
These are only ever made available to staff.
The corresponding database schema migration has been created in the
Cloud repo and applied to the production database.
Release Notes:
- N/A
Closes AI-367
This PR significantly refactors the queue feature so that we don't rely
on indexes being counted and synced across various state points of the
thread view. Instead, I'm introducing a dedicated message queue module
where we control through a stable queue entry ID all the states of a
given queued message.
Additionally, it's relevant to note that I changed the default behavior
of queued messages on this PR so that they get sent only at the end of
the generation. This makes the out-of-the-box, default behavior of the
feature consistent across the native and external agents, given we never
could pull off the feature with the latter. I personally never liked
that behavior anyway, but I do appreciate how some people do. Because of
that, though, for the Zed agent, a "Steer" toggle button is available
for whenever you'd like to signal that a queued message should be sent
at the turn boundary. This is not a setting, though; decided to go
simpler at this moment. It's something you can choose on a per-message
basis.
Ultimately, I think this implementation makes the overall shape of the
feature much more stable and easier to maintain overtime.
Release Notes:
- Agent: Changed the default behavior of queued messages for the Zed
agent so that they get send at the end of the generation. The ability to
steer them (i.e., send the message at the end of a turn boundary) is
still possible to be toggled.
This pull request updates how long configuration option names are
displayed in the UI to better handle Unicode characters, ensuring that
names are truncated by grapheme clusters (user-perceived characters)
rather than bytes or code points. This prevents visual glitches with
multi-codepoint characters like emojis or accented letters. The main
changes are:
**Unicode handling improvements:**
* Added the `unicode-segmentation` crate as a workspace dependency in
`Cargo.toml` to support grapheme-aware string operations.
* Updated import statements in `config_options.rs` to include
`unicode_segmentation::UnicodeSegmentation`.
**UI display logic:**
* Changed the truncation logic for configuration option display names in
`ConfigOptionSelector` to use `.graphemes(true).take(32)` instead of
slicing bytes, ensuring proper handling of Unicode graphemes.
---
Release Notes:
- Agent: Made label truncation of configuration options in the agent
panel more robust against non-single-byte characters like emojis and
others.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
# Objective
- Fixes#59654
When the same file was added as a mention more than once in the Agent
Panel,
the label would expand to the full absolute path instead of staying at
the
base filename.
Before
<img width="734" height="438" alt="Screenshot 2026-06-24 at 11 19 30 AM"
src="https://github.com/user-attachments/assets/94450eef-088a-49aa-97d3-80d6dd06925b"
/>
## Solution
The algorithm in `compute_disambiguation_details` treats two
entries with the same URI as a "collision" and tries to resolve it by
adding
more parent path components. Since the paths are identical it can never
succeed and keeps escalating to the full path.
Fix by deduplicating URIs via a `HashSet` before passing them to
`compute_disambiguation_details`, so identical mentions share a single
entry
and are never flagged as collisions.
## Testing
Reproduced by opening the Agent Panel, adding the same file as a mention
twice, and observing the label. Before: label showed the full absolute
path.
After: label stays at the base filename.
Tested on macOS.
After
<img width="638" height="215" alt="Screenshot 2026-06-24 at 11 20 09 AM"
src="https://github.com/user-attachments/assets/5acac2bd-d5a3-41c4-827c-84ccdc3a064d"
/>
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
---
Release Notes:
- Fixed duplicate file mentions in the Agent Panel showing the full
absolute
path instead of the base filename.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
We weren't handling these really before, just rendering the URI. This
should provide best-effort support for what we can render.
<img width="800" height="359" alt="image"
src="https://github.com/user-attachments/assets/51f101c7-c3be-4801-9000-62000a71faa6"
/>
(I will remove the extra labels that was just for testing)
Release Notes:
- acp: Support embedded resources in tool calls.
Agent terminal commands that request Git metadata access now verify
linked-worktree and submodule metadata before moving Git paths from
protected to writable sandbox paths. This prevents a mutated `.git`
gitfile from redirecting a grant to unrelated repository metadata while
preserving standard submodule layouts.
Release Notes:
- Improved agent terminal sandboxing for Git metadata access.
---------
Co-authored-by: Martin Ye <martin@zed.dev>
# Objective
Fix OpenAI-compatible reasoning/thinking support. Previously,
`OpenAiCompatibleLanguageModel` never reported thinking support, so
configured `reasoning_effort` values did not reliably reach the wire and
Responses API reasoning state could miss `include:
["reasoning.encrypted_content"]`.
Fixes#58289
Addresses #59207 for OpenAI-compatible Responses models configured with
`reasoning_effort`.
## Solution
- Treat a non-`none` configured `reasoning_effort` as OpenAI-compatible
thinking support.
- Expose common OpenAI-style effort levels in the agent UI, using the
configured effort as the default.
- Honor selected reasoning effort for OpenAI-compatible chat-completions
requests.
- Send `reasoning_effort: "none"` when thinking is disabled for a
configured reasoning model.
- Preserve native OpenAI behavior by continuing to use native
model-specific supported efforts and `max_completion_tokens`.
- Add an OpenAI-compatible `max_tokens_parameter` capability for
endpoints that expect output limits as `max_tokens`.
- Parse common streamed thinking fields (`reasoning` and
`reasoning_content`).
- Add provider setup UI and docs for configuring OpenAI-compatible
reasoning models.
## Testing
- `cargo fmt -p language_model_core -p agent_ui -p language_models`
- `cargo test -p language_models provider::open_ai_compatible::tests
--lib`
- `cargo test -p language_models provider::open_ai::tests --lib`
- `cargo test -p open_ai completion::tests --lib`
- `cargo test -p agent_ui
agent_configuration::add_llm_provider_modal::tests --lib`
- `git --no-pager diff --check`
## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Improved OpenAI-compatible provider setup for reasoning models.
---------
Co-authored-by: Anant Goel <anant@zed.dev>
Summary:
- Add a shell-level startup handshake owned by the terminal.
- Send a split startup marker through the shell and run the configured
init command after the marker is observed, preventing local echo from
satisfying the handshake.
- Keep display-only/restored terminal behavior unchanged while
preserving startup output when shells fail or users type first.
Tests:
- `cargo test -p terminal test_init_command_startup_marker --
--nocapture`
- `cargo test -p terminal write_init_command_after_startup --
--nocapture`
- `cargo test -p agent_ui init_command -- --nocapture`
- `./script/clippy -p terminal -p agent_ui`
Closes AI-426
Release Notes:
- Fixed terminal init commands sometimes appearing or running
incorrectly when using custom shells
---------
Co-authored-by: Anant Goel <anant@zed.dev>
Agent terminal sandboxing now protects `.git` metadata by default and
exposes an explicit `allow_git_access` approval. Without it, file
contents of the `.git` directories for opened worktrees and discovered
repositories (including a linked worktree's common `.git`) cannot be
read or written, though their metadata stays visible; when approved,
those Git directories become writable so commands like fetch/commit
work. SSH commit signing keeps working because the inherited
`SSH_AUTH_SOCK` is allowed as local Unix-socket IPC, which does not let
sandboxed commands send network packets to other machines. The Seatbelt
profile also allows PTY terminal-control ioctls so signing/passphrase
prompts can manage terminal state.
This intentionally restricts only `.git` itself (whose location we know
exactly, including the worktree case) rather than
`.gitignore`/`.gitattributes`/`.gitmodules`, since those can be nested
arbitrarily and the goal is to keep the policy expressible as a plain
deny-by-default allowlist that will port to Linux and Windows sandboxes
later.
Closes AI-334
Release Notes:
- Improved agent terminal sandboxing for Git metadata, Git worktrees,
and SSH commit signing.
The recent "pickers with previews" overhaul left the picker
sizing/presentation API spread across several overlapping knobs that
every call site had to set correctly — and many didn't, causing pickers
across the app to render at the wrong width, lose their container, or
stop dismissing. This PR consolidates that surface into a small,
hard-to-misuse API and makes correct sizing the default.
Net effect: a plain `Picker::uniform_list(delegate, …)` now renders
correctly out of the box (standard width, standard max-height, shrinks
to fit, dismisses properly), and the ~35 call sites only specify what
genuinely differs.
## API changes
**Presentation** — three overlapping booleans (`is_modal`, `is_popover`,
`is_resizable`) collapsed into one enum, with resizability living inside
the only variant where it's meaningful:
```rust
enum Presentation {
Modal { resizable: bool }, // own chrome, dismisses on blur, optionally resizable
Popover, // own chrome, dismisses on blur, never resizable
Embedded, // host container owns chrome + dismissal
}
```
- `modal(bool)` is **removed** in favor of explicit, self-documenting
builders:
- *(default)* → `Modal` (resizable iff it has a preview)
- `.popover()` → `Popover` (menu-attached surfaces)
- `.embedded()` → `Embedded` (pickers nested in a larger modal/view)
- Dynamic callers use `.when(cond, Picker::embedded)` (added `impl
FluentBuilder for Picker`).
**Sizing** — preview-vs-not now drives everything; the manual padding
knob is gone:
| Before | After |
|---|---|
| `vertical_padding` field + `no_vertical_padding()` | removed — derived
from whether a preview is visible |
| `height(...)` (ambiguous: fixed vs max) | `max_height(...)` (plain
pickers shrink-to-fit, capped here) |
| `minimum_results_width(...)` | removed — a plain picker's min width
tracks its opening width; preview pickers use standard internal pane
mins |
| default size = 60% viewport | default = `DEFAULT_MODAL_WIDTH` (34rem)
× `DEFAULT_MODAL_MAX_HEIGHT` (24rem, max) |
| resize handles gated on `is_modal` | gated on `is_resizable` (new
`resizable(bool)` builder; auto-`true` for preview pickers) |
Call sites now only override the exceptions: narrow popover selectors
(`initial_width`), the taller outline view (`max_height`), and preview
pickers (constructed via `*_with_preview`).
## Behavior fixes
- **Wrong widths everywhere**: pickers were falling back to
60%-of-viewport because the original migration set
`minimum_results_width` but never `initial_width`. Fixed at the source
via the new defaults.
- **Popovers had no container and wouldn't dismiss**: `is_modal=false`
was suppressing both the elevated background *and* blur-dismiss. Split
out so popovers keep their chrome and dismiss on click-away/escape. This
fixed the agent-panel model/profile selectors, sidebar recent projects,
and the settings theme/font/icon/ollama pickers (which were incorrectly
using `modal(false)`).
- **Sidebar recent projects stretched to full height**: was missing the
shrink-to-fit behavior; now capped and content-sized like other
popovers.
- **Preview crash**: removed an over-strict `debug_assert!` that
panicked when previewing an empty file (`message == None && editor
empty` is valid).
- **Preview-aware default size**: pickers open at standard width with
the preview hidden, and expand to the larger "telescope" size when a
preview is shown. Fixes the text finder rendering super-wide by default,
and makes the file finder expand (rather than cram its results) when you
toggle the preview.
---
Release Notes:
- N/A
## Summary
Fixes#37815.
`State::fetch_models()` calls `/api/tags` to list models, then calls
`/api/show` for **every** model in that list to get its capabilities,
collecting the results with `collect::<Result<Vec<_>>>()?`. If
`/api/show` errors for even one model, the whole batch fails and
`fetched_models` is never populated. Since `is_authenticated()` is
defined as `!self.fetched_models.is_empty()`, this means a single bad
model permanently breaks both authentication state and the model picker
for the entire Ollama provider - with no error surfaced anywhere (not
the UI, not the logs), which matches the reports in #37815 of "Connect
does nothing" / "no logs, no nothing".
I hit this myself: I had a stale local reference to an Ollama Cloud
model that had been retired server-side. `/api/show` for that one model
returned `410 Gone`, which silently broke Connect and the model picker
for every other model too. Removing the retired model with `ollama rm`
fixed it immediately, which confirmed the root cause.
## Fix
Instead of aborting the whole fetch on the first error, skip individual
models that fail `/api/show` and log a warning, keeping the rest.
Extracted this into a small `skip_failed_models` helper so it's
unit-testable without mocking HTTP.
## Disclosure
I used Claude (Anthropic's Claude Code) to help track down this root
cause (tracing through `fetch_models`/`is_authenticated` in this file)
and draft the fix + tests below. I reviewed and understand the change -
it's a small, targeted fix to a single function plus two unit tests for
the new helper.
## Test plan
- [x] `cargo check -p language_models` passes
- [x] `cargo test -p language_models --lib ollama::` - all 3 tests pass
(the 2 new ones plus the existing
`test_merge_settings_preserves_display_names_for_similar_models`,
unaffected by this change)
- [x] `cargo fmt -p language_models -- --check` - no diff
## Release Notes
Release Notes:
- Fixed Ollama models silently failing to show up in the model picker
(and "Connect" appearing to do nothing) when a single model's details
couldn't be fetched, e.g. a retired Ollama Cloud model
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
# Objective
The reasoning for this is that it is currently rather hard to find the
option to add a remote MCP in the app - there is no hint that this is
supported and (without using the command palette) requires up to 5
clicks before the proper modal is shown.
The idea for this here is to make adding a remote server the default and
also make it more visibile throughout the app - the `AddContextServer`
action will now default to remote and this also adds two context menu
entries to directly open the modal with the remote option preselected.
Open for feedback - I admit this might not be the most optiomal
solution, but at least it surfaces the availablilty better and
(hopefully) makes adding these easier.
Release Notes:
- Added an entry to the agent panel options menu to quickly add a remote
MCP server
# Objective
Fixes#59498
Original issue mentioned problem with the alignment of text entered into
the agent editor compared with the thread title when in full expanded
mode. I was able to reproduce issue both in expanded mode and also when
resizing while not in expanded mode by dragging panel wide enough. After
more investigation, it seemed that all of the contents within the editor
(text entered, bottom row of elements) were not properly aligned on both
the left and right sides with other content in the agent panel.
## Solution
Moved horizontal padding to inner div that uses `max_content_width` in
`render_message_editor` so that it is calculated as expected as part of
the max width of the content.
- Dropped horizontal padding, keep vertical padding on outer `h_flex`
div. Changed `.p_2()` to `.py_2()` here .
- Added horizontal padding back to first child `v_flex` div that uses
`max_content_width`. Added `.px_2()` here.
After changes, elements within the editor are aligned on both the left
and right sides with the messages within the message history and the
contents of the title bar.
## Testing
I tested the fix on Linux visually, no tests were added due to the small
amount of changes and the strictly visual nature of the issue.
<details>
<summary>Self-Review Checklist</summary>
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (**no unsafe
blocks added**)
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior (**no tests added**)
- [x] Performance impact has been considered and is acceptable
</details>
## Showcase
<details>
<summary>Before/After empty convo</summary>
### Before
<img width="946" height="551" alt="before-maximized"
src="https://github.com/user-attachments/assets/27805f8c-9a04-40b3-a808-5dc3a548a0b8"
/>
### After
<img width="948" height="554" alt="after-maximized"
src="https://github.com/user-attachments/assets/4f557aa8-d8ce-44c4-8278-35df203ca434"
/>
</details>
<details>
<summary>Before/After existing convo</summary>
### Before
<img width="950" height="555" alt="before-with-convo"
src="https://github.com/user-attachments/assets/82ea6b04-bca7-48fd-ab11-3414855afec8"
/>
### After
<img width="950" height="555" alt="after-with-convo"
src="https://github.com/user-attachments/assets/2f2f394a-6d78-4650-9ddf-e760841a2635"
/>
</details>
## Note
- A similar issue also seems to apply to the activity bar within
`render_activity_bar`, but it's less jarring, and this is also my first
PR, so I'm leaving it alone.
---
Release Notes:
- N/A
Follow-ups to the recently-landed agent terminal sandboxing work.
- Make the persistent "Allow Unsandboxed Terminal Commands" setting
(`allow_unsandboxed`) the single off-switch for the agent terminal
sandbox: when enabled, the sandboxed terminal tool isn't exposed and the
system prompt omits the sandbox section, so the model uses the plain
`terminal` tool (and on Windows, WSL sandbox setup is skipped). This
removes the dead, unwired `disabled` setting that was meant to do the
same thing but had no UI, writer, or docs. Per-command and per-thread
`unsandboxed: true` grants are unchanged.
- Expand the blocklist of Windows-specific environment variables that
aren't forwarded into the WSL sandbox (system locations, `HOME`/profile
paths, host/session identity, CPU descriptors, etc.) so they can't
shadow or break Linux commands. It stays a blocklist, so portable
variables like `LANG` still reach the command.
Release Notes:
- N/A
This PR makes the search-closing behavior consistent with regular
buffers, where hitting escape when focused in the message editor will
close it (before it cancels the message). Also, made the whole search
bar height match the toolbar for perfect grid alignment.
Release Notes:
- Agent: Fixed the closing behavior of the in-thread search by enabling
`escape` to close it when focused in the message editor.
# Objective
- Fixes#59643.
## Problems
- Initial and minimum width was not migrated for all pickers.
- Some pickers had their width still determined by their wrapper.
- Some pickers where not modals but did not have modal false set.
## Solution
- Migrate the pickers we missed.
- Remove the width being set on the div's wrapping the pickers.
- Set modal false on the missed pickers.
## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
We finally have a cancellation mechanism to use! Made the non
side-effectful handlers stop their work if we get a cancel request
notification.
Release Notes:
- N/A
Overhauls Zed's pickers to make them resizable and give them a preview.
Closes#8279
### Background
The most requested Zed feature has the last year has been a [Telescope
like search box](https://github.com/zed-industries/zed/issues/8279)
[discussion](https://github.com/zed-industries/zed/discussions/22581).
To understand why this is so popular we need to understand search can
serve thee goals:
- Navigation: fuzzy search is faster & easier then clicking in a file
tree
- Exploration: example, find a function by a word in its doc comment
- Collecting: example, getting a list of functions to change
The project search which shows results in a multibuffer is the perfect
way to operate on a list of items. Navigation and Exploration need a lot
of context around each result and offer fast navigation between them.
For both of these live searching is also critical.
The `telescope UI` is a picker with a preview to the right or below.
It's offered in various editors and IDE's most famously Neovim (through
the Telescope plugin), IntelliJ (natively), Helix (natively) and of
course VScode (plugins) and it's _many_ forks.
While having a UI like that for text search (our project search) is most
requested the UX pattern is applied widely, from `find_all_references`
to `bookmarks`. It enhances most pickers. Note that we have over 50
different picker modals!
The community has tried to build something like this for Zed:
- https://github.com/zed-industries/zed/pull/44530
- https://github.com/zed-industries/zed/pull/45307
- https://github.com/zed-industries/zed/pull/46478
- https://github.com/zed-industries/zed/pull/43790
These all became huge PR's that we could not merge for various reasons.
This is a really hard feature to integrate in Zed!
This PR got started as https://github.com/zed-industries/zed/pull/46478
and supercedes that.
### Design
- Extend pickers to support an optional preview with minimal changes to
the pickers themselves.
- Make pickers resizable.
- Complement the existing search do not replace it by having both UI's
share the underlying search and allow freely switching between them.
- Allow extending the preview to things other then files.
- Maintain a clean design on all the pickers.
### Heigh level Implementation overview
- Adds an `Option<Preview>` to `Picker`
- Gives `PickerDelegate` a method to communicate a preview to the Picker
- Overhaul the way pickers are drawn to allow for resizing them.
Implemented on the `Shape` and `SizeBouds` structs.
- Adds a high level way to draw the `footer` and `editor` so we do not
need to change much to the pickers.
- Adds a new text finder Picker
- Adds a way to take a running search from project search and hand it to
the text finder Picker and the other way round
- Give the file finder a preview
### Next steps
A more detailed list and how to help out will be added to the tracking
issue for [Pickes with
previews](https://github.com/zed-industries/zed/issues/56037)
- Add more previews to more pickers!
- Enable selectioning multiple items in pickers and performing actions
on those
- Open selected items in a multibuffer
- Add a way to restore the last picker
- Make popovers (picker attached to some menu) resizable as well
## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
TODO (will be done post merge)
---
Release Notes:
- Added resizing via dragging to all picker modals.
- Added a preview to the File finder, the preview can be to the right or
below.
- Added a Text finder picker with a preview as alternative project
search UI. The search is shared and allowes switch between UIs while
running.
---------
Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com>
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
The agent-waiting notification heading was hardcoded to the agent id,
showing "claude acp" for external agents. Use the thread's own title,
which external agents now provide via session info updates, and fall
back to the agent id only for threads that aren't titled yet.
# Objective
- External agent notifications were just headed generically I.e. "claude
acp". There was a TODO in the code to use the thread name, so that it's
clear which thread actually produced the notification.
## Solution
- Use the thread name, seems it was inscope in the code already from a
previous change.
## Testing
Tested manually by triggering a notification and seeing the thread name
instead of acp-claude.
## 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 adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior - this code path wasn't
tested and doesn't seem like it needs it, but willing to be corrected.
- [x] Performance impact has been considered and is acceptable
Release Notes:
- agent: Include thread title in notification when Zed is not focused
The agent panel's `grep` tool output previously rendered file paths and
line numbers as plain markdown text, so search results weren't clickable
(unlike `find_path`, which emits `ResourceLink` content blocks).
This PR makes `grep` results clickable in the same way `find_path` does:
- `grep` now streams a `ResourceLink` content block per match
(`crates/foo/bar.rs#L12-15` → `file:///abs/path#L12-15`) followed by the
code snippet, via `event_stream.update_fields`, and sets `locations` on
the tool call.
- `render_resource_link` in `agent_ui` now splits an optional `#L...`
fragment off `file://` URIs before resolving the project-relative path,
so labels render as `path#L12-15` instead of falling back to the raw
absolute URI. Clicking opens the file at the matched line (handled by
the existing `MentionUri` selection parsing).
- The model-facing text output of the tool is unchanged.
Closes AI-401
Release Notes:
- Improved the agent panel so that file search results from the agent's
`grep` tool are clickable and open the file at the matched line.
This is a narrower alternative to #54816, scoped to search only the
currently-loaded thread, excluding tool output or thinking blocks (happy
to follow up on those, see next). It uses a custom bar confined to
`agent_ui` rather than `BufferSearchBar` + `SearchableItem`, avoiding
the cross-crate plumbing that #54816 reached. Open as draft pending
direction from @benbrandt on what scope/approach would be acceptable for
in-thread search.
<img width="959" height="609" alt="image"
src="https://github.com/user-attachments/assets/8971e432-61d3-46db-a6a4-2bbd355089e7"
/>
## What this PR does
Adds a search bar to the agent panel, triggered by Ctrl+F (Cmd+F on
macOS), that lets users grep the currently-loaded thread without leaving
the agent panel; not cross-thread or cross-agent.
- Searches visible content only: user messages, assistant message
chunks, and tool-call labels. Thought blocks and rendered tool-call
content (collapsed by default) are intentionally skipped so that:
1. The visible match count matches what the user sees.
2. The search experience is consistent between tool output blocks in the
current Zed session, ans tool output blocks from past sessions, which
are not rendered - see issue #57230
- Highlights matches inline via `Markdown::set_search_highlights` for
markdown-rendered content and
`Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)`
for past user messages (rendered through `MessageEditor`'s inner
`Editor`, not through markdown).
- Next/prev navigation, case/whole-word/regex toggles (same UI as
`BufferSearchBar`).
- Returns focus to the message editor on dismiss so the user can keep
typing immediately.
<details><summary>Commits (authored by Claude 4.7 Opus, max)</summary>
### Seven logical commits
1. **`agent_ui: Add in-thread search bar`** — initial implementation:
bar UI, keymap bindings under `AcpThreadSearchBar` context, markdown
highlight plumbing, focus-restore on dismiss.
2. **`agent_ui: Add unit tests for in-thread search`** — coverage of the
matcher across entry kinds and the dismiss-clears-highlights path.
3. **`agent_ui: Limit search to visible tool-call text`** — UX fixes
from manual testing: `track_focus` so `AcpThreadSearchBar` context lands
in the editor's dispatch chain; red border on zero-match query; skip
tool-call content (only search labels).
4. **`agent_ui: Fix Esc dispatch, smart toggle, error message, skip
Thought blocks`** — round 2 of UX fixes: contribute `AcpThreadSearchBar`
context from `ThreadView` when bar is visible, smart Ctrl/Cmd+F
outside-the-bar focuses instead of closing, regex error message row,
skip `AssistantMessageChunk::Thought`.
5. **`agent_ui: Polish thread search bar — Esc routing, user-message
highlights, action forwarding`** — `search::*` action forwarders on
`ThreadView`; `cx.defer` around the activate callback (fixes a
double-borrow panic); `editor::actions::Cancel` interception so Esc
dismisses our bar instead of escaping to the workspace's
`BufferSearchBar`; user-message highlights via the inner `Editor`; muted
zero-match counter; three new gpui regression tests.
6. **agent_ui: Fix Shift+Enter shadowing in thread search bar`** —
capture-phase intercept of `editor::Newline*` on the bar's `bar_row`
element so a base keymap binding `shift-enter` at the `Editor` context
(e.g. JetBrains → `editor::NewlineBelow`) can't shadow the bar's
`agent::SelectPreviousThreadMatch`. Adds a regression test that loads
`default-linux.json` + `linux/jetbrains.json` and asserts `shift-enter`
navigates instead of inserting a newline.
7. `agent_ui: Debounce thread search, refresh on thread changes,
highlight user messages`** — last round before maintainer review: 150 ms
debounce on the match rescan; subscribe to `AcpThread` updates so
results/highlights/counter follow a streaming conversation live;
navigate the list to the entry owning the active match; `.ok()` instead
of `let _ =`; assorted cleanups; two new regression tests
(`test_thread_search_refreshes_on_new_thread_entry`,
`test_thread_search_scrolls_to_later_user_message_match`).
</details>
8 gpui tests cover the load-bearing logic (`cargo test -p agent_ui --lib
-- thread_search`). All pass.
## Manual testing
Verified on Linux against `upstream/main` `bde5c0bdc9` (full `release`
profile, with LTO and `codegen-units=1` built and tested at that
commit). Branch since merged with `upstream/main` `2106e8c`. Of the 100
intervening upstream commits, several touch files in this diff; one
produced a real conflict in `crates/agent_ui/src/conversation_view.rs`
(`gpui::{...}` import block — both sides added new, non-overlapping
symbols; resolved by union).
- Bar opens / dismisses via Ctrl+F and Esc
- Next/prev navigation via Enter / Shift+Enter / F3 / Shift+F3 / chevron
buttons
- Case / whole-word / regex toggles via buttons and via Alt+C / Alt+W /
Alt+R (Linux)
- Highlights inside past user messages render correctly on the
`MessageEditor`'s inner `Editor`
- query text turns red on no-match; bad regex shows error message;
zero-match counter stays muted (not red)
- `search::*` actions fire from outside the bar (focus in message
editor) via the `ThreadView`-level forwarders
- Workspace pane `BufferSearchBar` is unaffected; the two bars hold
independent state
- Feature looks great in light mode and dark mode, and with various
themes
- Navigating to a match in a past user message scrolls that message into
view (its top to the viewport top)
- Results update live as the agent streams new messages while the bar is
open (debounced ~150 ms, same for typing)
[Zed agent thread search subscribe to thread
updates.webm](https://github.com/user-attachments/assets/75585fee-ba25-42ac-9dde-16c8e152fb06)
<details><summary>Full manual test plan</summary>
### Setup (preconditions for every test below unless otherwise noted)
1. Launch the dev binary: `./target/release-fast/zed --user-data-dir
~/.local/share/zed-dev-feat`
2. Open the agent panel, start a thread, send 2–3 prompts so the thread
contains:
- At least one user prompt with a distinctive substring (e.g.
`watermelon`)
- At least one assistant message with a distinctive substring
- At least one tool call with a known label substring
- At least one collapsed Thinking block
3. In parallel: have at least one code editor open in a workspace pane
(some tests cross-check that path).
### Core matching
#### T-001 — Ctrl+F opens the bar with focus in query
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** With focus in the agent panel's message editor, press Ctrl+F
(Linux) / Cmd+F (macOS). The search bar appears at the top of the thread
view and the query input is focused.
#### T-002a — Active match visually distinct from inactive matches
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Type a query that produces ≥3 matches. The current ("active")
match must be visually different from the others — different highlight
color, not just position. If they look identical, this may be a theme
issue (`search_active_match_background` vs `search_match_background` too
close on the entry's background); note the theme.
#### T-002b — User-prompt text gets inline highlight, not just match
count
**Status:** ✅ PASS 2026-05-15 17:15 (fix shipped 2026-05-15 16:15;
regression-guarded by
`test_thread_search_highlights_user_message_editor`)
**Repro:** Send a user prompt containing a distinctive substring. Then
search that substring. The user prompt text **must** show yellow
highlight, not just be counted. The bar's matcher reads from
`message.content.markdown()` but the on-screen render goes through a
`MessageEditor`; the current code only highlights via
`Markdown::set_search_highlights`, which misses the editor.
**Notes:** Fix routes user-message matches through
`Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)`
— the same path `Editor`'s own `SearchableItem` impl uses.
`collect_markdowns` no longer pulls the user message's markdown
(avoiding double-counting). The bar now maintains separate
`highlighted_markdowns` and `highlighted_editors` lists for clean-up.
Match-target enum (`MatchTarget::Markdown` vs `MatchTarget::Editor`)
tags each match so active-vs-inactive re-paint can dispatch correctly.
Pending runtime verification on next `release-fast` build.
#### T-003 — Enter / Shift+Enter in bar navigates matches
**Status:** ✅ PASS 2026-05-25 14:00 (verified on `release` build)
**Repro:** With focus in the query, type a query with ≥3 matches. Press
Enter → counter `1/N → 2/N → 3/N`. Press Shift+Enter → reverses (and no
`\n`s are output in the search box). F3 / Shift+F3 same.
### Option toggles
#### T-004 — Alt+C toggles case sensitivity from inside bar
**Status:** ✅ PASS 2026-05-15 07:50
**Repro:** With focus in query, press Alt+C. `Aa` button toggles state;
results re-filter.
#### T-005 — Alt+W toggles whole-word from inside bar
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Same as T-004, with Alt+W toggling `wd` button.
#### T-006 — Alt+R toggles regex from inside bar (Linux)
**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:35)
**Repro:** Press Alt+R. `.*` button toggles.
**Notes:** macOS keymap (`alt-cmd-x`) left unchanged in this session —
it matches the wider macOS Zed convention.
#### T-006a — Tooltips on toggle buttons show their hotkey
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Hover each toggle button (`Aa`, `wd`, `.*`). Tooltip shows
action name AND keybinding (e.g. "Toggle Case Sensitive · Alt+C").
### Error / empty states
#### T-007 — Empty matches: no red border on bar input
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Type `zzzzzzz`. Query text turns red. Counter shows `0/0`.
Bar input border stays **neutral**, no red box.
#### T-008 — Bad-regex error message
**Status:** ✅ PASS 2026-05-15 15:30 (error renders aligned with the
input)
**Repro:** Switch to regex mode, type `[`. Error message appears below
bar, aligned with the input.
#### T-019 — Zero-match counter not colored red
**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30)
**Repro:** Type a query with no matches. The counter (`0/0`) stays
muted, **not** red. MPS-parity.
### Dismissal & re-entry
#### T-009 — Esc doesn't interrupt agent generation
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Start a long prompt; while the agent is generating, open the
search bar and press Esc. Bar closes, generation continues.
#### T-010 — Close-X button position
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Look at the bar. Close (X) button is on the right side, after
the nav arrows (`<` `>` `1/N` `X`). NOT free-floating left of the input.
#### T-011 — Ctrl+F in bar selects all query text
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** With bar open and query containing text, press Ctrl+F. All
query text becomes selected (next keystroke replaces).
#### T-012 — Ctrl+F outside the bar (bar already open) does not crash
**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30;
regression-guarded by
`test_thread_search_select_next_from_thread_view_update_does_not_panic`)
**Repro:** Bar visible, focus in the message editor (not the bar). Press
Ctrl+F. Bar gets re-focused, query text is selected. **Must not crash.**
**Notes:** Original crash also reproducible from Enter / Shift+Enter
inside the bar after a search had matches. Fix wraps the
`on_activate_match` callback's `view.update` in `cx.defer`.
#### T-021 — Esc dismisses agent bar (not the unrelated workspace pane's
BufferSearchBar)
**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 14:40;
regression-guarded by `test_thread_search_editor_cancel_dismisses_bar`)
**Repro:** Open a file in a workspace pane editor (e.g.
`settings.json`). Open BufferSearchBar there. Switch focus to the agent
panel, open agent search bar, type a query. Press Esc. **The agent bar
must dismiss; the workspace pane's BufferSearchBar must remain.**
**Notes:** Root cause: `Editor::cancel` in single-line mode calls
`cx.propagate()`. The propagated `editor::actions::Cancel` walked past
our bar all the way to `Workspace`, where `BufferSearchBar::register`
had registered a workspace-wide handler that dismissed the active pane's
bar. Fix: `ThreadView` now catches `editor::actions::Cancel` when the
bar is visible.
### Action routing while bar is open, focus is in the message editor
#### T-013 — F3 / Shift+F3 from outside the bar
**Status:** ✅ PASS 2026-05-15 15:30 (Enter from outside is *expected*
not to work — message editor's `enter` binding outranks. F3 is the
canonical out-of-bar nav key.)
**Repro:** Bar open with matches, focus in message editor. Press F3 →
next match. Shift+F3 → previous.
#### T-014 — Alt+C / Alt+W / Alt+R from outside the bar
**Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 02:30;
`ThreadView` forwarders for `search::ToggleCaseSensitive`,
`ToggleWholeWord`, `ToggleRegex`, `FocusSearch`)
**Repro:** Bar visible, focus in message editor. Alt+C/W/R toggles the
bar's options and re-runs search.
### Nav buttons
#### T-022 — `<` / `>` chevron buttons in the bar advance match
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** With ≥2 matches, click `<` → previous. Click `>` → next.
Wraps at ends.
### Coexistence with workspace-pane buffer search
#### T-015 — Ctrl+F in a workspace-pane editor still opens
`BufferSearchBar` (no agent-panel takeover)
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Focus a code editor in a workspace pane, press Ctrl+F. The
pane's `BufferSearchBar` opens as before; agent panel's bar does NOT
open.
#### T-016 — Independent bars: agent vs workspace pane
**Status:** ✅ PASS 2026-05-15 15:30
**Repro:** Have both bars open simultaneously. They hold independent
state (different queries, different toggles, independent dismissal).
### Tool-call content (auto-expand on match)
#### T-017 — Auto-expand collapsed tool calls on match
**Status:** ⏸️ BLOCKED (not implemented; out of scope for current
session)
**Repro:** Have a tool call whose collapsed content contains a unique
substring. Search that substring. The tool call auto-expands so the
match is visible. After dismissal, the tool call collapses again unless
the user manually expanded it before.
#### T-018 — Auto-expand collapsed Thinking blocks on match
**Status:** ⏸️ BLOCKED (not implemented; out of scope for current
session)
**Repro:** Same shape as T-017 for a collapsed Thinking block.
#### T-019 — Streaming results automatically highlighted / live thread
search
**Status:** ✅ PASS 2026-06-08
**Repro:** Send prompt "Write a 5-paragraph story about a researcher who
hated noise. The last paragraph should be a one-sentence: "So she moved
to <name of the quietest continent on Earth>" (replace that <name> with
the actual name)", then search for `Antarctica`.
</details>
## Known limitations
1. (pre-existing, not from this PR): search highlights inside markdown
table cells can be visually offset by a few characters in columns
starting with the second. The bug lives in `crates/markdown`'s render
layer - see issue #57229
2. (excluded vs. #54816 to keep the scope tight): raw tool-call
input/output JSON and terminal scrollback are not indexed.
3. Navigating to a search hit located **below the fold of a very long
user message** highlights the match but only scrolls the message's top
into view, so the hit can stay off-screen until you scroll manually.
Past user messages render through an `AutoHeight` `Editor` inside a
virtualized `List`, which can't reliably drive intra-entry autoscroll
the way markdown content does. User messages are usually shorter than a
viewport, so this is left unaddressed.
4. Plain-text search across triple-backtick fences does not match (the
fence characters live in the markdown source; regex search with explicit
fence handling does).
5. The literal text "Thinking" rendered as the thought-disclosure header
is not searchable (rendered chrome, not markdown source).
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- No new `unsafe` introduced; no network, file-system, or process APIs
touched; only added dep is `search` (promoted from dev-dep to runtime),
already used by this crate's tests; `MessageEditor::editor()` accessor
widening is `pub(crate)` (in-crate only). Assessment: no new attack
surface.
- [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)
— partially; see "What I did NOT verify" above
- [ ] I did not verify **macOS and Windows**. Keymap entries exist for
all three platforms (`AcpThreadSearchBar` context bindings) but I only
verified Linux at runtime.
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable:
regexp-searching for "t.e" in a thread almost at the context limit (919k
tokens) felt instant, and navigation among the 2100+ results occurred at
the keyboard autorepeat rate.
- [ ] Haven't measured against the 8ms / 120fps frame budget.
Partially closes#39338
Release Notes:
- Added in-thread search to the agent panel (Ctrl/Cmd+F)
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Adds a dedicated Sandbox settings page under the AI settings, letting
users review and manage the elevated terminal sandbox permissions that
are always allowed without prompting.
The page exposes:
- Network: an "Allow All Domains" toggle and an editable list of allowed
domains (exact domains or leading-`*.` subdomain wildcards), with
validation.
- Filesystem: an "Allow All Filesystem Writes" toggle and an editable
list of writable paths.
- Sandbox: an "Allow Unsandboxed Terminal Commands" toggle.
This replaces the single "Allow Unsandboxed Terminal Commands" setting
item with the new page, and updates the agent panel's settings shortcut
to open it. "Allow always" sandbox grants now persist to settings only
and are no longer also cached as an in-memory thread grant.
Closes AI-413
Release Notes:
- Added a settings page for managing the agent terminal sandbox
permissions (allowed domains, writable paths, and unsandboxed command
execution).
## Summary
- Adds an `agent.terminal_init_command` setting for Terminal Threads.
- Runs the configured command automatically when creating a new Terminal
Thread, while skipping restored terminal threads.
- Documents the setting and exposes it in the AI settings page.
Closes https://github.com/zed-industries/zed/issues/58697
Closes AI-337
Release Notes:
- Added a setting to automatically run a command when opening a new
terminal thread in the agent panel.
---------
Co-authored-by: Anant Goel <anant@zed.dev>
# Objective
Fixes#58736
Pause the debugger on a breakpoint, switch your theme, and the active
debug line keeps its old highlight color until you step again or restart
Zed.
## Solution
The highlight stores a concrete color grabbed from the theme back when
`go_to_active_debug_line` ran. A theme switch goes through
`theme_changed`, which refreshes brackets, semantic tokens, and outline
symbols but never re-applies that highlight, so it stays stale.
Re-running `go_to_active_debug_line` from `theme_changed` re-resolves
the color against the current theme.
## Testing
Added a regression test in `debugger_ui` that stops at a debug line,
swaps the theme's `editor.debugger_active_line.background`, and checks
the highlight follows. It fails on `main` and passes with the fix.
Also tested by hand on Windows: started a debugpy session, paused at a
breakpoint, switched themes from the theme selector, and watched the
active line recolor live without stepping or restarting.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
Paused at a breakpoint, switching themes from the theme selector.
| Before | After |
| --- | --- |
|
https://github.com/user-attachments/assets/653a7e1b-3a99-4316-b1c9-b16ed7a7a8ba
|
https://github.com/user-attachments/assets/22a4c876-30f2-44c5-aad9-0f860639074c
|
---
Release Notes:
- Fixed the active debug line color not updating when switching themes
while the debugger is paused
([#58736](https://github.com/zed-industries/zed/issues/58736)).
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Adds UI for the various scenarios where sandboxing can fail on linux:
- no `bwrap` on the path
- `bwrap` is setuid
- `bwrap` exists but cannot create unprivileged userns
---
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Martin Ye <martin@zed.dev>
This fixes archive cleanup for agent threads so Zed only removes
worktrees it explicitly created, rather than treating every linked
worktree under the configured managed directory as safe to delete. When
Zed creates a worktree, it now records it in the local database along
with the creation time of the worktree's git metadata directory
(`.git/worktrees/<name>/`). Archive planning requires that record, and
right before deleting anything, Zed re-stats the directory and compares
creation times: if the worktree was removed and recreated outside Zed
(or the time can't be read at all), deletion is skipped and the stale
record is dropped. Every failure mode fails safe by leaving the
directory untouched.
For remote (SSH) projects, the stat runs on the remote host via a new
`GitWorktreeCreatedAt` request. Worktrees created by a different Zed
install (another release channel, or another machine connecting to the
same host) have no record in the local database and are therefore never
auto-archived, which is the intended conservative behavior.
Closes https://github.com/zed-industries/zed/issues/57155
Closes AI-352
Release Notes:
- Fixed archiving an agent thread incorrectly deleting manually-created
git worktrees.
Manage various LLM settings (previously in agent panel) in settings UI.
Behind a feature flag, not staff shipped
Release Notes:
- N/A or Added/Fixed/Improved ...
Adds provider-side context compaction support to the Anthropic and
OpenAI API clients. Client plumbing only; not wired into the UI.
Release Notes:
- N/A
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
## Summary
- Show the command being approved in sandbox permission prompts even
when no specific write paths are requested
- Keep the existing network and write-path details alongside the command
## Validation
- rustfmt crates/agent_ui/src/conversation_view/thread_view.rs
- cargo check -p agent_ui
Release Notes:
- Improved sandbox permission prompts to show the command being
approved.
Third of a four-PR stack adding hostname-allowlisted network access to
agent terminal sandboxing. Stacked on #59218 — review/merge #59217 and
#59218 first.
Replaces the boolean `allow_network` terminal-sandbox escalation with a
hostname allowlist. The `terminal` tool now takes `allow_hosts` (exact
hostnames or leading-`*.` subdomain wildcards, validated up front) and
`allow_all_hosts` as a broad escape hatch. Approval prompts name the
requested hosts, thread grants and persistent "allow always" settings
cover requests via host-pattern subsumption the same way write paths use
subtree containment, and the authorization card in the agent panel lists
the requested hosts.
Host allowlists aren't enforced yet in this PR: `SandboxWrap` carries
the allowlist, but any network request still maps to unrestricted egress
at the Seatbelt layer, matching previous behavior. Enforcement via the
in-process proxy lands in the final PR of the stack. All of this is
behind the existing sandboxing feature flag. For non-local projects
(where the loopback proxy won't apply), host requests are widened to
"arbitrary network access" before prompting so approvals match
enforcement. Old persisted `network: bool` authorization details still
deserialize via a serde alias.
Release Notes:
- N/A
---------
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martin@zed.dev>
Summary:
- Include terminal command text in sandbox authorization metadata.
- Render the command in sandbox permission prompts, including prompts to
run outside the sandbox.
- Keep write-path details visible alongside the command when both are
present.
Tests:
- cargo test -p agent sandbox
- cargo check -p agent_ui
Release Notes:
- Improved agent sandbox permission prompts to show the command being
requested.
When a Zed Business organization hits its token spend limit, the agent
panel told the user to "check that your API key has access to this
model", and did not display the error message returned by the server.
The message about checking your API key was the generic 401 and 403
error for all language model providers. This is also incorrect in
general since there are no API keys involved in the Zed and ChatGPT
Subscription providers.
So this commit changes the message for authentication errors (401s) to
be provider-specific, with the current message about invalid API key as
the default, and overrides for the providers that don't use API keys.
And the authorization error messages (403s) now include the server error
message. So the spend-limit case now reads "Permission Denied —
Token-based spending limit reached." instead of talking about API keys.
<img width="1888" height="426" alt="grafik"
src="https://github.com/user-attachments/assets/cf9e07cd-66f0-4f8d-828c-79b875edcf2d"
/>
Telemetry event names (`invalid_api_key`, `no_api_key`) are kept
unchanged to avoid breaking existing dashboards.
Release Notes:
- Fixed agent panel errors telling users to check their API key when the
provider doesn't use one (Zed account, ChatGPT subscription). Permission
errors also now show the provider's actual message.
## Context
Dragging a file from the Project Panel into the agent composer was
appending the generated file mention to the end of the prompt instead of
inserting it at the active caret position. This change routes dragged
file insertion through the same caret-based mention insertion path
already used for pasted external paths, so dropped file and directory
mentions are inserted inline where the user is typing.
Closes#55002
Video of the manual test below :
[Screencast from 2026-04-29
01-13-59.webm](https://github.com/user-attachments/assets/9d2196fb-accd-4f4a-a9c0-0ce45b212121)
## How to Review
-
[crates/agent_ui/src/message_editor.rs](/home/saber/coding/zed/crates/agent_ui/src/message_editor.rs)
removes the separate end-of-buffer insertion mode from
`insert_mention_for_project_path`, updates `insert_dragged_files` to use
the shared caret-based insertion flow, and adds regression tests
covering single-file and multi-file drag insertion order at the cursor.
The existing paste-at-cursor behavior remains covered by the
pre-existing test in the same module.
## 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:
- Fixed dragged file mentions in the agent composer being appended to
the end of the prompt instead of inserted at the cursor
Co-authored-by: Richard Feldman <richard@zed.dev>
Summary:
When you have a lot of projects open, finding a thread from a specific
project in the archive ("Search all threads") view is slower than it
should be — the filter only matches the thread title, so you have to
remember or scan titles to find what belongs to which project. Folder
names are a quicker mental handle than thread titles, especially across
many projects.
This PR makes the archive filter also try matching the basename of each
of the thread's worktree paths. Title matches still take precedence and
get the highlight positions; project-name matches just include the row.
Same `fuzzy_match_positions` contiguous substring matcher already used
for titles, so the matching feel is consistent.
Example: typing `my-laravel-project` now surfaces every thread that
lives
under a project named `my-laravel-project`, regardless of title.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — N/A
- [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 — small extension to an
existing filter branch; manually verified.
- [x] Performance impact has been considered and is acceptable — per-row
path-basename check only runs when the title didn't match.
Release Notes:
- Improved the archive "Search all threads" view so you can filter by
project name, not just by thread title — handy when many projects are
open.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Both cloning and dropping of these has quite a bit of overhead (despite
them being snapshots), so avoid where possible, especially in display
map syncing
Release Notes:
- N/A or Added/Fixed/Improved ...
Follow up to https://github.com/zed-industries/zed/pull/59126 where
seeing the typed-prompt in the agent panel's toolbar felt really busy.
With that change, I'd be seeing the prompt I'm writing in three
different stops, which felt overwhelming. Toning that down a little bit
in here.
Release Notes:
- N/A
Replaces the verbose struct-literal construction of `gpui::BoxShadow`
with a builder API:
- `BoxShadow::new(offset_x, offset_y, color)` takes the required fields,
with arguments ordered to match the CSS `box-shadow` property.
- `.blur_radius(_)`, `.spread_radius(_)`, and `.inset()` set the
optional fields.
All in-tree call sites are migrated, including the Tailwind-style
`shadow_xs`..`shadow_2xl` helpers in `gpui_macros`, the `ElevationIndex`
shadows in `ui`, and various widgets across `editor`, `workspace`,
`agent_ui`, and `ai_onboarding`. The fields on `BoxShadow` remain
public, so external code using struct-literal construction continues to
work.
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