Cherry-pick of #60300 to preview
----
# Objective
In the keymap editor, bindings whose `keymap.json` entries use a
deprecated action alias (e.g. `"editor::CopyRelativePath"` for
`workspace::CopyRelativePath`) could not be deleted or edited. Aliases
resolve to the canonical action on load, so the row displays normally,
but file updates searched for the canonical name and never matched the
alias entry. Deleting failed ("Failed to find keybinding to remove"),
and editing silently fell back to appending a new binding — leaving the
user with duplicate identical-looking rows they couldn't remove.
## Solution
- Thread gpui's deprecated-alias map
(`App::deprecated_actions_to_preferred_actions`) into
`KeymapFile::update_keybinding`, and resolve aliases in file entries
when matching bindings.
- As a side effect, editing an alias-based binding now rewrites the
entry with the canonical action name instead of duplicating it.
## Testing
- Unit tests in `settings` for removing and replacing alias-based
entries.
- End-to-end keymap editor tests (fake fs → keymap load → `KeymapEditor`
→ delete) covering both the alias case and plain duplicate bindings.
## 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:
- Fixed the keymap editor failing to delete or edit key bindings whose
keymap file entries use deprecated action names
Co-authored-by: Ben Kunkle <ben@zed.dev>
Cherry-pick of #60210 to preview
----
WSL downloads a linux zed binary for the sandbox helper. But the flag is
set on the `zed-editor` binary, not the `zed` cli binary. This fixes
that
---
Release Notes:
- N/A or Added/Fixed/Improved ...
Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
Removes git sandbox feature
The reason is essentially:
- write access to a `.git` dir can be trivially escalated to unsandboxed
access
- therefore, it is misleading to offer git access separate from
unsandboxed access
- instead, we encourage the model to use `--no-optional-locks` to avoid
needing write access to `git status`, etc.
Adds sandboxing to fetch tool
---
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] 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)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Remote `HEAD` refs such as `origin/HEAD` and `upstream/HEAD` are
symbolic refs that point to a remote's default branch. These refs can
appear in the branch picker, but selecting them shows this error prompt:

This happens because the local branch name is directly derived from the
selected ref, resulting in an attempted checkout of a local branch named
`HEAD`.
This change follows up on feedback from #57588, which just filtered
remote `HEAD` refs out of the branch picker to prevent the error prompt.
As mentioned in [this
comment](https://github.com/zed-industries/zed/pull/57588#issuecomment-4533477336),
I agree that the preferred behaviour should be to instead allow checking
them out - useful for repos with multiple remotes such as an upstream.
For example, if `refs/remotes/origin/HEAD` points to
`refs/remotes/origin/main`, selecting `origin/HEAD` now behaves like
selecting `origin/main`, switching to the corresponding local `main`
branch instead of trying to create or check out a branch named `HEAD`.
This does not fetch or pull from the remote; it uses the locally known
remote refs.
Release Notes:
- Fixed selecting remote HEAD refs from the branch picker
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Behind a feature flag as we iterate on the RFD
Release Notes:
- N/A
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
This makes it so that we show open the settings UI instead of the modal
when adding an MCP server when clicking on `Add server`:
<img width="240" height="320" alt="image"
src="https://github.com/user-attachments/assets/bc5e9059-1053-45d5-8fd5-acfb7da48a35"
/>
We still show the modal when installing an extension. Since we're
hopefully replacing MCP extensions with MCP registry support soon, we
can leave it as is for now.
Release Notes:
- N/A
## Summary
It is incremental step to solve issue #59825.
This PR addresses the need for facilitating quick edits for matches
obtained by ‘text_finder’. This makes the text finder remember the last
query, so you can jump to a match, make a quick edit, and reopen the
finder to the same results instead of typing the same query again.
## Problem
A common flow is, open the text editor, then jump to first match, edit
that file, then reopen the finder to continue for next matches. But on
the reopen, the query was seeded from under the cursor. And after
editing, the cursor is usually sitting on an unrelated word, and
previous search was lost. The root cause is priority, the word under the
cursor was seeding the query.
## Solution
Reorder query seeding so last query outranks the cursor word, then
cursor word can be dropped entirely, since last query is prioritized
over the word under cursor, the last query always wins, so checking the
cursor word afterwards is dead code. And JetBrains makes the same
choice, entirely ignores word on the cursor for seeding query. Explicit
selection still outranks the last query, since selecting text is usually
a deliberate choice.
### Before
1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text or word under the cursor
4- Empty
### After
1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text
4- Last query (of this project)
5- Empty
With updated order, this friction disappears (the same order is also
observed in JetBrains). To make the last query persistent, it is stored
per project in the database along with the active filters (case
sensitive, whole word, regex), so they also survive reopening the
project.
## Testing
- Manually verified the seed priority order between the options.
- Verified the last query is seeded when project is reopened.
- Verified filters are restored regardless of this query order.
Release Notes:
- Improved the text finder to seed the last query and filters to make
quick edits easier.
---------
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Yara 🏳️⚧️ <git@yara.blue>
Zed don't surface the fact that bookmarks can have labels/names now
anywhere except opening the bookmark name editor every time you place
one. This keeps the label/name mechanism but makes the default add
bookmark action add an unnamed one.
Next step is probably to enable holding shift (or some other modifier)
to place a named bookmark, or even a setting to switch between default
named vs unnamed.
Release Notes:
- N/A
# Objective
Zed supports trusting all projects under a given directory. However,
when a local Windows client connects to a remote Linux server, the trust
scope input rejects valid directories with the error "Enter an absolute
folder path", even though the path is correct.
<img width="681" height="374" alt="image"
src="https://github.com/user-attachments/assets/87f084fb-1213-4594-96cb-3de81f4789aa"
/>
The root cause is in the `validate_trust_scope` function:
53e4d34a71/crates/workspace/src/security_modal.rs (L497-L519)
which uses `Path::is_absolute()` to check whether the entered path is
absolute. On Windows, this method only considers paths with a drive
letter as absolute, so Unix-style paths like `/home/user` are never
recognized. When doing cross-platform remote development, valid trust
scopes are incorrectly rejected.
## Solution
The `util::paths` crate already provides a helper for this situation:
53e4d34a71/crates/util/src/paths.rs (L575-L586)
The fix
- Adds a `path_style: PathStyle` parameter to `validate_trust_scope` and
uses `util::paths::is_absolute()` in place of `Path::is_absolute()`.
- The call site in `edited_trust_scope` retrieves the path style from
the worktree store, which already tracks whether a connection is local
or remote and the remote host's path convention.
The associated unit tests were updated for the new function signature.
## Testing
Built and tested locally; `cargo test -p workspace` passed.
## 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 the "Folder to trust" input rejecting valid folder paths when
connecting to a remote host that uses a different path style than the
local machine.
Closes AI-159
Closes AI-434
Closes AI-435
Release Notes:
- Key agent-related settings now live in the settings editor, close to
all other settings available in Zed. This specifically includes the move
of LLM providers, external agents, and MCP servers to the settings
editor.
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
This makes sure that the behaviour of the CLI matches that of the UI.
In Zed itself we always open a new window (e.g. when clicking on Open
Project in new window in the recent projects picker), but in the CLI we
where re-using existing windows even when specifying
"cli_default_open_behavior": "new_window".
This caused confusion, so this PR ensures that we always open a new
window, even if that folder is already open. We still focus the active
window in the case where the path is a subpath of a project that is
already open.
Can be tested with
```
cd crates/cli
cargo run -- --zed ../../target/debug/zed somefolder
```
Release Notes:
- cli: Ensure `zed somefolder` always opens a new window, even when
`cli_default_open_behavior` is set to `new_window` and the project is
already open
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#54160
Summary:
In Helix mode, rename could fail when the cursor was visually positioned
on the last character of a symbol. The editor renders some Vim/Helix
selections with the visible cursor offset from the selection head, but
rename was still using the raw selection head as the LSP prepare-rename
position.
This updates rename to use the visible cursor position for point lookup
when cursor offset rendering is active. It also adds regression coverage
for Helix rename and Vim visual rename.
Verification:
- `cargo check -p editor`
- `cargo fmt --check --package editor --package vim`
- `git diff --check -- crates\editor\src\editor.rs
crates\vim\src\test.rs`
- `test::test_rename`
- `test::test_helix_rename_uses_visible_cursor_position`
- `test::test_visual_rename_uses_visible_cursor_position`
Release Notes:
- Fixed Helix mode rename when the cursor is visually on the last
character of a symbol.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Helix's keymap to `Vertically center the line` (`align_view_center`
command) is `zc`
([documentation](https://docs.helix-editor.com/keymap.html#view-mode)).
Release Notes:
- Added Helix's `z c` keymap to editor, project panel and outline panel
to scroll cursor to center
Right now subpages are not searchable. Since we don't have the bandwidth
to implement this today, this PR adds support for having aliases users
can search for. E.g. if I search for `claude` I will see the LLM
provider subpage, whereas previously I would not see anything.
https://github.com/user-attachments/assets/25af5c5a-86d2-473b-b0dd-11141b12a089
Release Notes:
- N/A
Large change to sandboxing:
- fixes a nasty TOCTOU relating to a symlink swap attack, documented in
the `sandboxing/README.md`
- Adds UI and restrictions when in an untrusted workspace
- Adds tests for (soon to be removed) git support
---
Release Notes:
- N/A or Added/Fixed/Improved ...
This follows up on discussion #56551.
Right now, when Zed generates a commit message, it includes project
rules files like `AGENTS.md`, `CLAUDE.md`, and `.rules` in the prompt
alongside the git diff. That can add a lot of extra context for a task
that is really just summarizing the changes in a commit.
This PR adds an `include_project_rules` option to
`agent.commit_message_model`. When it is set to `false`, Zed skips
loading project rules when generating commit messages. If the option is
omitted, the current behavior stays the same.
Example:
```json
{
"agent": {
"commit_message_model": {
"provider": "anthropic",
"model": "claude-3-5-haiku",
"include_project_rules": false
}
}
}
```
I also updated the settings plumbing so this option is only used for commit message generation and defaults to true when not specified.
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:
- agent: Added setting to exclude project rules files from commit message generation prompts (`agent.commit_message_include_project_rules`)
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Now that we have `/compact` we want to make the "new from summary"
option less prominent. You can still manually handoff to a new thread by
@mentioning the thread in a new one (`@thread threadname`)
Release Notes:
- agent: Remove "New from summary" menu item from agent panel dropdown.
You can still @mention the thread in a new one, or run /compact
Co-authored-by: gaauwe <gaauwe@users.noreply.github.com>
# Objective
The objective is to improve Helix's default keymap within Zed as a few
are still missing.
These are all [default
keymaps](https://docs.helix-editor.com/keymap.html) i was using within
Helix but dissapointed they weren't working in Zed
There's more info in [Are we Helix
yet?](https://github.com/zed-industries/zed/discussions/33580#top)
## Solution
- Add `] g` and `[ g` for hunk navigation in helix mode, in helix this
is go to next/previous change which maps nicely to Zed's go to
next/previous hunk. (it was set to `c` here but this is incorrect and
doesn't match Helix's keymap.
- Add `alt-b` and `alt-e` for larger syntax node navigation in helix
mode, i use this a few times to go to the top of a function within the
body and Zed doesn't have it mapped.
- Add `] space` and `[ space` for inserting empty lines in helix mode.
This one was incorrectly implemented previously, after the `space` Zed
is waiting for input. It needs to be a direct chord added rather than on
`helix_next` mode.
- This means the space binding from the helix_next operator context is
redundant, so ive removed it
- Add `*` to use selection for find in helix mode. Helix mode is
slightly different and doesn't "go to next" on `*`, instead that becomes
the `/` register. This is pretty fundamental to helix navigation so
should be ported to Zed also.
- Move `] d` and `[ d` diagnostics navigation into helix_normal context.
Vim was already using this one but it wasn't shared with Helix. I've
moved it to the shared Vim and Helix block.
## Testing
I've tested these changes with a local build and each one works as
expected
## 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:
- Added `alt-b`/`alt-e` in Helix mode to move to the start/end of the
larger syntax node.
- Added `*` in Helix mode to set the current selection for search.
- Fixed Helix `[`/`]` navigation so `c` goes to the previous/next
comment and `g` to the previous/next hunk, and single-key follow-ups
like `g` no longer hang.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Summary:
- Use the compaction-aware request history when generating thread
summaries.
- Reuse the same compaction boundary logic for thread title generation,
including saved-thread title regeneration.
- Add regression tests for summary and title request construction with
compacted history.
Tests:
- `cargo test -p agent uses_compacted_history`
Release Notes:
- Improved agent thread summary and title generation to respect
compaction boundaries.
Co-authored-by: gaauwe <gaauwe@users.noreply.github.com>
# Objective
Closes EP-202
Prevent V4 edit predictions from leaking `<|user_cursor|>` markers into
users' buffers.
## Solution
- Strip cursor marker text from emitted prediction edits, including when
`text_diff` splits the marker across edit fragments.
- Preserve literal marker-like text that already exists in the buffer.
## Testing
- `cargo test -p edit_prediction prediction_edits_for_single_file_diff
-- --nocapture`
- `cargo test -p edit_prediction --lib`
- `cargo fmt --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:
- N/A
After a filesystem watcher loses sync (e.g. a `git pull` that changes
many files overflows the backend's event queue), the backend can enqueue
many `Rescan` markers in quick succession. The dispatch thread processed
each one separately, and each rescan invokes every registration for that
watcher mode, so a single burst could kick off several full worktree
scans at once — leading to sustained CPU and an unresponsive project
panel.
This adds `dispatch_batch`, which handles the first event and drains the
events already waiting in the channel, forwarding at most one `Rescan`
per `WatcherMode` per drained batch while letting ordinary filesystem
events and errors pass through untouched. A later watcher overflow can
still trigger another recovery scan.
Reported with a reproduction and patch in #59610.
Release Notes:
- Batch file watcher rescan events to improve Zed's responsiveness under
heavy FS usage
# Objective
Fix the agent `terminal` tool in headless eval environments. In the eval
sandbox, terminal commands failed before the shell ran with `IOError:
Not a tty (os error 25)` because PTY setup attempted to acquire a
controlling terminal.
## Solution
- Add a `terminal::HeadlessTerminal` global that is set by `eval_cli`
only.
- When headless mode is enabled, run terminal task commands as plain
subprocesses with piped stdout/stderr instead of opening a PTY.
- Pump subprocess output through the existing terminal emulator/event
channel so output capture, completion, and task killing keep working.
- Build ACP terminal commands non-interactively in headless mode.
- Keep the normal editor terminal path unchanged when the global is
unset.
- Handle non-PTY output edge cases by preserving split CRLF sequences
and avoiding an indefinite wait if subprocess exit-status polling
errors.
## Testing
- `cargo fmt --all`
- `cargo test -p util non_interactive_omits_interactive_flag`
- `cargo test -p terminal test_no_pty_task_terminal_captures_output`
- `cargo test -p terminal test_convert_lf_to_crlf_preserves_split_crlf`
- `cargo test -p terminal test_write_output`
- `cargo check -p eval_cli`
- `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:
- Fixed the agent terminal tool failing with "Not a tty" in
headless/eval environments
When opening Zed from GNOME on Wayland, the cursor can stay stuck in the
launch spinner state for several seconds because GPUI never tells the
compositor that the launched app's first window has loaded. Desktop
launchers pass this information through `XDG_ACTIVATION_TOKEN`, which
Wayland clients are expected to consume once their first toplevel
surface is ready.
This PR fixes that by reading and removing `XDG_ACTIVATION_TOKEN` during
Wayland client startup, storing it on the client state, and consuming it
on the first XDG toplevel surface via the existing
`xdg_activation_v1.activate(token, surface)` plumbing. Anthony manually
verified this on GNOME Wayland.
docs ref: https://wayland.app/protocols/xdg-activation-v1
Release Notes:
- Fixed Linux Wayland cursor being stuck as a spinner for a couple of
seconds.
## Summary
Tune the shared `ReqwestClient` builder so HTTP connections that have
silently gone bad on a flaky network path are detected and dropped
rather than reused.
A stale, reused HTTP/2 connection (after a NAT/conntrack timeout, a
silent reset, or a degraded path) is a common source of intermittent
TLS `BadRecordMac` errors against long-lived endpoints such as
`cloud.zed.dev`. The client already retries these (`HttpSend` is
retryable with exponential backoff), but users still see periodic
multi-second stalls and "connection error" warnings.
These settings make the client probe and recycle connections instead of
sending a request's first records into a connection that is already
dead:
- `tcp_keepalive(30s)` — surface dead TCP connections instead of reusing
them.
- `pool_idle_timeout(30s)` — bound how long an idle connection lingers
in the pool.
- `http2_keep_alive_interval(15s)` / `http2_keep_alive_timeout(10s)` /
`http2_keep_alive_while_idle(true)` — ping idle HTTP/2 connections so
broken ones are torn down.
All three constructors (`new`, `user_agent`, `proxy_and_user_agent`) go
through `builder()`, so every Zed HTTP client picks this up.
## Notes
- Values are conservative; they can be tightened if stale-connection
errors persist.
- `tcp_keepalive_interval` is not yet available in the pinned
`zed-reqwest`
fork rev, so only the initial keepalive idle time is set here.
## Verification
Behavior is network-dependent, so there is no deterministic test.
Verified
that the crate builds (`cargo check -p reqwest_client`). The change is
being validated empirically against a setup that reproduces the
`BadRecordMac` errors.
Release Notes:
- Improved resilience to intermittent network errors by detecting and
dropping stale HTTP connections instead of reusing them.
This PR adds a conditional `allow(dead_code)` to the `wake_sender` field
to fix this error when building Collab:
```
error: field `wake_sender` is never read
--> crates/gpui_linux/src/linux/platform.rs:126:5
|
116 | pub(crate) struct LinuxCommon {
| ----------- field in this struct
...
126 | wake_sender: Sender<()>,
| ^^^^^^^^^^^
|
= note: `-D dead-code` implied by `-D warnings`
= help: to override `-D warnings` add `#[expect(dead_code)]` or `#[allow(dead_code)]`
error: could not compile `gpui_linux` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
```
https://github.com/zed-industries/zed/actions/runs/28374439219/job/84060893437
Release Notes:
- N/A
Hi there, I'm Celina from Hugging Face! Opening this PR to add
[llama.cpp](https://llama.app) as a model provider
# Objective
Today Zed users running llama.cpp have to fall back to the generic
OpenAI-compatible provider, which means no auto-discovery (the router
mode (`llama serve`) discovers models from the cache and loads them on
demand) and manual configuration of every model and its capabilities.
This PR makes `llama.cpp` a first-class provider with the same
auto-discovery experience.
## Solution
- Add a `llama_cpp` client crate with the OpenAI-compatible chat types
(`/v1/chat/completions`, including `reasoning_content`) and the
discovery types (`/v1/models`, `/props`), mirroring the existing
`ollama` crate.
- Add the provider in
`crates/language_models/src/provider/llama_cpp.rs`, modeled on the
Ollama provider (settings, configuration view, event mapping).
- Auto discover served models and their context length and tool/vision
support from `/props`. Set `auto_discover: false` to list models
manually instead.
- An unloaded model can't be inspected without loading it, so it is
listed with optimistic defaults (large context, tools enabled) and is
usable from the first message; its real context length and tool support
are filled in once it loads. These live behind a shared map, so a model
already selected in an open conversation picks them up without being
re-selected.
- Show load progress. The provider subscribes to `/models/sse` and
surfaces each model's load progress (e.g. "Loading weights 42%") in its
display name, reconciling stale labels against `/v1/models`. Builds
without `/models/sse` degrade gracefully - no progress, and no
capability refresh after the initial discovery.
- Add settings (`api_url`, `auto_discover`, `available_models` with
per-model `max_tokens` / `supports_tools` / `supports_images`,
`context_window`, `custom_headers`), the provider icon, a `default.json`
entry, and documentation under "Use a Local Model".
No new dependencies: the crate reuses existing workspace dependencies,
and shared state uses `std::sync::RwLock`.
## Testing
- Unit tests in both new crates cover wire/response parsing, model
discovery for single-model and router shapes, the cold-start optimistic
defaults, the in-place capability refresh once a model loads, and the
`/models/sse` event handling (state changes, load failure, load
progress).
- Built Zed locally and ran it against a local `llama serve` router:
confirmed models are discovered without manual configuration, that the
first message works before a model has finished loading, that load
progress is shown in the model's display name while it loads, and that
the reported context length and tool support refine to the model's real
values once it finishes loading.
- Platforms: tested on macOS (Apple Silicon).
## 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
The generation speed (tokens/sec) depends on the machine you're running
the model, here it's a Apple M3 Max 64GB running a 4-bit quant of
https://huggingface.co/Qwen/Qwen3.5-35B-A3B. For the load progress
status, make sure to upgrade your llama.cpp version to the latest build.
https://github.com/user-attachments/assets/0254f6ef-abe9-42ed-810b-ef1a5b8fa3bd
---
Release Notes:
- Added llama.cpp as a language model provider
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
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
Closes#39159
## Summary
• resolve remote terminal path candidates outside known worktrees
through `Project::resolve_abs_path`
• keep the local filesystem backed resolution path unchanged
• preserve the existing preference for direct in-worktree matches when
the terminal cwd is already inside a worktree
• add regression coverage for both absolute and cwd-relative remote
external paths
### Why
The hyperlink parser wasn't the bug. `terminal_path_like_target` already
knew how to parse these paths. The actual problem was that remote
projects had no equivalent of the local background existence check.
After worktree lookup failed, remote projects only fell back to worktree
traversal, so cmd-click on `/tmp/a.txt` in an SSH remote terminal
no-op'd.
The project layer already has remote absolute-path resolution via
`Project::resolve_abs_path`, so the right fix is to use that existing
path for remote candidates instead of pretending remote projects cannot
resolve paths outside their worktrees.
## Verification
• `cargo test -p terminal_view terminal_path_like_target --quiet`
• `cargo test -p terminal_view --quiet`
## Manual
• Verified locally on my MBP w/ a stateless Zed build using SSH to self
(`localhost`)
• Opened `/tmp/zed-39159-project` as a remote project
• Confirmed cmd-click opens `/tmp/zed-39159-external/a.txt`
• Confirmed cmd-click opens `zed-39159-external/b.txt` from `cwd=/tmp`
• Confirmed in-worktree paths still open correctly
• Confirmed nonexistent external paths do not open bogus targets
Release Notes:
- Fixed remote terminal path opening so cmd-click can open files outside
the project worktree.
# 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.
# Objective
- Currently, the file preview pane in pickers forces line numbers and
the editor gutter to always be visible, ignoring user-configured
preferences. This PR ensures the preview component respects the user's
global editor layout settings.
## Solution
- Modified `EditorPreview::new` within `crates/picker/src/preview.rs`.
- Imported `EditorSettings` from the `editor` crate.
- Replaced the hardcoded `true` values for `set_show_gutter` and
`set_show_line_numbers` with the user's active global configuration
retrieved via `EditorSettings::get_global(cx).gutter.line_numbers`.
## Testing
- Did you test these changes? If so, how?
- Yes, manually verified that toggling line numbers off or using
relative line numbers in `settings.json` is accurately reflected inside
the picker's file preview pane.
- Are there any parts that need more testing?
- No, using the global context lookup seamlessly integrates with Zed's
existing configuration lifecycle.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Open your `settings.json` and change your line number preferences
(e.g., set `"line_numbers": false`).
- Bring up a picker that renders a file preview (like the project search
or file finder).
- Confirm that the preview pane's gutter and line number layout
perfectly matches your active configuration.
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
- Tested on Linux.
## 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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
<details>
<summary>Click to view showcase</summary>
### Line numbers ON
<img width="1940" height="2072" alt="preview-line-numbers-on"
src="https://github.com/user-attachments/assets/db824b5e-bc29-459d-bc0c-86762d44f707"
/>
### Line numbers OFF
<img width="1940" height="2072" alt="preview-line-numbers-off"
src="https://github.com/user-attachments/assets/48a6357e-d4b5-462b-920f-d1c20d3d27af"
/>
</details>
---
Release Notes:
- Preview line numbers now respect user configuration settings