Zed-managed npm installers were resolving a concrete latest version with
`npm info` and then installing `package@version`. That is brittle when
users
configure npm release-age filtering via `before` or `min-release-age`:
npm's
installer applies those rules during resolution, but our pinned install
target
could disagree with it, and therefore fail to install.
This changes managed npm installs to install `package@latest` and let
npm apply
its own resolver and user config. The local latest-version lookup
remains as a
best-effort cache freshness check, not as the exact install target.
Exact extension API installs remain unchanged because extensions
explicitly
request a package and version. If we want to revisit that we can.
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#53611
Release Notes:
- Fixed npm-backed tool installs to better respect npm release-age
filters.
We currently run node on the JS wrapper around the native binaries
shipped with https://github.com/github/copilot-language-server-release.
According to their README, this is not required, and it seems like it is
just an option provided so that you can run the server with `npx`.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#55891
Release Notes:
- Stopped relying on node for running the Copilot language server that
provides edit predictions. The system node version should no longer
affect whether Copilot edit predictions work in Zed
As part of the work that is being developed for the Project Panel's Undo
& Redo system, in
https://github.com/zed-industries/zed/tree/5039-create-redo , we're
implementing an asynchronous task queue which simply receives a message
with the operation/change that is meant to be carried out, in order to
ensure these run in a sequential fashion.
While trying to use `futures_channel::mpsc::Receiver`, it was noted that
`recv` method was not available so this Pull Request updates the
`futures` crate to `0.3.32`, where it is available.
This version also deprecates `try_next` in favor of `try_recv` so this
Pull Request updates existing callers of `try_next` to use `try_recv`,
which was mostly updating the expected return type from
`Result<Option<T>>` to `Result<T>`.
Co-authored-by: Yara <git@yara.blue>
Self-Review Checklist:
- [ ] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A
Closes#37836
This behavior was already fixed for Supermaven in #37047, but is still
present in Copilot. What's actually happening:
- Receive a multi-line edit prediction
- Dismiss it with escape
- Clicking anywhere in the editor below the cursor calls
`Editor::select` which starts out by calling `Editor::hide_context_menu`
-> `Editor::update_visible_edit_prediction`, bringing back the
prediction that was just dismissed and updating the editor's display map
- The subsequent selection logic in `Editor::select` now operates using
a display map that is inconsistent with what the user saw when clicking
- If the click was anywhere where the prediction inlay used to be,
`Editor::select` thinks the user clicked on the inlay and does nothing,
and the inlay reappears
- If the click was below where the prediction inlay used to be, the
inlay is immediately removed again but the cursor is moved to the wrong
position because the inlay temporarily added a vertical offset to all
lines after it in the buffer
Ultimately, `Editor::select` should be handling the user input using the
same display map that the user saw when making the input. This can
obviously be solved in multiple ways, I chose to clear the current
completions in `CopilotCompletionProvider::discard` such that any
subsequent calls to `Editor::update_visible_edit_prediction` doesn't
immediately nullify the dismissal of the edit prediction by the user.
Note that this also changes the behavior that occurs after dismissing an
edit prediction, moving to a different position in the buffer, and then
returning: currently, this resurfaces the dismissed edit prediction
(which the `test_copilot` test exercises), and after this change it
doesn’t. This current behavior didn't seem desirable to me because it
doesn't happen when using Zeta or Supermaven, but if we want to keep it,
then we could fix the incorrect selection behavior some other way.
Release Notes:
- Fixed bug that resurfaced dismissed Copilot edit predictions when
moving the cursor around
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
## Summary
This fix addresses the cross-platform root cause identified in issue
#38109 where open buffers go stale or empty when external tools write
files.
## The Problem
The buffer's `file_updated()` method was only comparing `mtime` to
determine if a buffer needed to be reloaded. This caused a race
condition when external tools write files using `std::fs::write()`,
which uses `O_TRUNC` and creates a brief window where the file is 0
bytes:
1. Scanner re-stats → sees 0 bytes, mtime T
2. `file_updated()` sees mtime changed → emits `ReloadNeeded`
3. Buffer reloads to empty, stamps `saved_mtime = T`
4. Tool finishes writing → file has content, but mtime is still T (or
same-second granularity)
5. Scanner re-stats → mtime T matches `saved_mtime` → **no reload
triggered**
6. Buffer permanently stuck empty
## The Fix
Release Notes:
- Add the file `size` to `DiskState::Present`, so that even when mtime
stays the same, size changes (0 → N bytes) will trigger a reload. This
is the same fix that was identified in the issue by @lex00.
## Changes
- `crates/language/src/buffer.rs`: Add `size: u64` to
`DiskState::Present`, add `size()` method
- `crates/worktree/src/worktree.rs`: Pass size when constructing File
and DiskState::Present
- `crates/project/src/buffer_store.rs`: Pass size when constructing File
- `crates/project/src/image_store.rs`: Pass size when constructing File
- `crates/copilot/src/copilot.rs`: Update test mock
## Test plan
- [ ] Open a file in Zed
- [ ] Write to that file from an external tool (e.g., `echo "content" >
file`)
- [ ] Verify the buffer updates correctly without needing to reload
Fixes#38109
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Ben Kunkle <ben.kunkle@gmail.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
BufferEvent::Edited had no way to distinguish local edits from remote
(collaboration) edits. This caused edit prediction behavior to fire on
the guest's editor when the host made document changes.
Release Notes:
- Fixed edit predictions triggering on collaboration guests when the
host edits the document.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
Paving the way to remove `ExcerptId`. Done in this PR:
- Unshipped the stack trace view
- Get rid of `push_excerpts`
- Get rid of some callers of `remove_excerpts`
We still need to remove some calls to `remove_excerpts` and other APIs,
especially in `randomly_edit_excerpts` and collaboration.
Release Notes:
- The stack trace multibuffer view has been removed.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Here's some backstory:
* on macOS, @cole-miller and I noticed that since roughly Oct 2025, due
to some changes to latest macOS Tahoe, for any spawned child process we
needed to reset Mach exception ports
(https://github.com/zed-industries/zed/issues/36754 +
6e8f2d2ebe)
* the changes in that PR achieve that via `pre_exec` hook on
`std::process::Command` which then abandons `posix_spawn` syscall for
`fork` + `execve` dance on macOS (we tracked it down in Rust's std
implementation)
* as it turns out, `fork` + `execve` is pretty expensive on macOS
(apparently way more so than on other OSes like Linux) and `fork` takes
a process-wide lock on the allocator which is bad
* however, since we wanna reset exception ports on the child, the only
official way supported by Rust's std is to use `pre_exec` hook
* posix_spawn on macOS exposes this tho via a macOS specific extension
to that syscall `posix_spawnattr_setexceptionports_np` but there is no
way to use that via any standard interfaces in `std::process::Command`
* thus, it seemed like a good idea to instead create our own custom
Command wrapper that on non-macOS hosts is a zero-cost wrapper of
`smol::process::Command`, while on macOS we reimplement the minimum to
achieve `smol::process::Command` with `posix_spawn` under-the-hood
Notably, this changeset improves git-blame in very large repos
significantly.
Release Notes:
- Fixed performance spawning child processes on macOS by always forcing
`posix_spawn` no matter what.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Closes#48274
Previously, the Copilot language server would continue running even when
`disable_ai: true` was set in settings. This change ensures Copilot
properly responds to the `disable_ai` setting:
- Add `disable_ai` check in `start_copilot()` to prevent starting when
AI is disabled
- Modify the `SettingsStore` observer to shut down the running language
server when `disable_ai` changes from false to true
- Add tests for all scenarios:
- Copilot doesn't start when `disable_ai` is true
- Copilot stops when `disable_ai` becomes true
- Copilot can start again when `disable_ai` becomes false
Release Notes:
- Fixed Copilot starting when disabled_ai: true
Fixes#36818
Release Notes:
- Added new `global_lsp_settings.request_timeout` setting to configure
the maximum timeout duration for LSP-related operations.
Code inspired by [prior
implementation](https://github.com/zed-industries/zed/pull/38443),
though with a few tweaks here & there (like using `serde:default` and
keeping the pre-defined constant in the LSP file).
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
### Summary
Adds accept/reject tracking for Mercury edit predictions.
### Changes
Sends events to https://api-feedback.inceptionlabs.ai/feedback when:
Accept — user presses Tab
Reject — user presses Escape
Ignore — prediction dismissed implicitly (typing, cursor move, etc.)
Added `discard_explicit` method to the delegate trait to distinguish
explicit vs implicit dismissal. Updated `reject_prediction` and
`reject_current_prediction` methods with an `explicit` bool parameter to
thread this through to the Mercury feedback logic. Other providers are
unaffected—they use the default implementation.
Feedback is fire-and-forget in a background thread, only sent for
predictions that were shown.
### Data Collected
- Request ID (returned from Inception API)
- User action (either accept/reject/ignore)
- Client Zed version (to track updates made to Zed client which could
potentially affect nextedit implementation)
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Part of #7450
Big thanks to @macmv for pushing this forwards so much!
Rebased version of https://github.com/zed-industries/zed/pull/39539 as
working on an in-org branch simplifies a lot of things for us)
Release Notes:
- Added LSP semantic tokens highlighting support
---------
Co-authored-by: Neil Macneale V <neil.macneale.v@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Closes#48097
Release Notes:
- Fixed Copilot instances not being cleared up after their window is
closed.
- Copilot edit prediction provider now respects `disable_ai` setting.
* [x] capture and store teacher model's predicted cursor position
* [x] provide cursor position to student during distillation
* [x] eval cursor positions
* [x] parse and apply cursor position predictions at runtime
Release Notes:
- N/A
Closes: #46593#32635#47924
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Cole Miller <cole@zed.dev>
Release Notes:
- Fixed issues with signing into Copilot via the Settings UI
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Users had trouble signing in due to us relying on the Copilot::global
being set, which was never the case. We've decided to use a dedicated
LSP instance just for handling auth of Copilot Chat and other goodies.
That instance is subscribed to by local Copilot instances for projects.
When the Auth instance changes it's state, local instances are prompted
to re-check their own sign in status.
Closes#47352
Co-authored-by: dino <dinojoaocosta@gmail.com>
Release Notes:
- Fixed authentication issues with Copilot.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Adds a new setting to GitHub Copilot to toggle the Next Edit Suggestions
feature, it is enabled by default.
## Motivations
Due to some current usability issues with this feature, see #46880, and
some personal anecdotes of using it, it is currently rough to utilize,
so this gives the option to disable it.
## Related
- #47071
- #30124
- #44486
## Release Notes
- Adds the ability to disable GitHub Copilot's Next Edit Suggestions
feature.
## User Interface

## Text Example
The text example will be adding a `z` variable to a `Point3D` class in
TypeScript.
### With Next Edit Suggestions
In this example I am able to just press auto-complete (press TAB) 3x.
```ts
class Point3D {
x: number;
y: number;
z: number; // <-- Cursor before z: suggested
constructor(x: number,
y: number
, z: number // <-- Next Suggestion
) {
this.x = x;
this.y = y;
this.z = z; // <-- Last Suggestion
}
}
```
### Without Next Edit Suggestions
```ts
class Point3D {
x: number;
y: number;
z: number; // <-- Cursor before z: the only suggestion
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
```
This PR fixes an issue when copilot takes 3s to complete. Right now, in
copilot edit prediction, we issue requests to both the Next Edit
Suggestion (NES) and the regular copilot inline completion endpoints.
Whichever come back first will be shown. However, there is a bug where
even if inline completion (which is usually much faster) comes back, we
still wait for NES (which takes about 3s).
This should address https://github.com/zed-industries/zed/issues/46389
and https://github.com/zed-industries/zed/issues/46880
Release notes:
- Improved responsiveness of Copilot inline completions.
- **copilot: Fix double lease panic when signing out**
- **Extract copilot_chat into a separate crate**
- **Do not use re-exports from copilot**
- **Use new SignIn API**
- **Extract copilot_ui out of copilot**
Closes#7501
Release Notes:
- Fixed Copilot providing suggestions from different Zed windows.
- Copilot edit predictions now support jumping to unresolved
diagnostics.
When `trim_completion()` creates new anchors from the current buffer
state, `completion.snapshot` was not being updated, leaving it with the
older snapshot from when the prediction was initially fetched. This
caused a panic in `interpolate_edits()` when trying to resolve anchors
with Lamport timestamps newer than what the old snapshot had observed.
The fix ensures that `completion.snapshot` is updated whenever new
anchors are created in `trim_completion()`, keeping the snapshot and
anchors consistent.
Closes#45956
Release Notes:
- Fixed a panic in Copilot edit predictions caused by anchor/snapshot
version mismatch
This PR introduces support for Next Edit Suggestions while doing away
with calling legacy endpoints. In the process we've also removed support
for cycling completions, as NES will give us a single prediction, for
the most part.
Closes#30124
Release Notes:
- Zed now supports Copilot's [Next Edit
Suggestions](https://code.visualstudio.com/blogs/2025/02/12/next-edit-suggestions).
Closes #ISSUE
Problem:
- The status bar’s pending keystroke indicator (shown next to --NORMAL--
in Vim mode) didn’t clear when focus moved to another context, e.g.
hitting g in the editor then clicking the Git panel. The keymap state
correctly canceled the prefix, but observers that render the indicator
never received a “pending input changed” notification, so the UI kept
showing stale prefixes until a new keystroke occurred.
Fix:
- The change introduces a `pending_input_changed_queued` flag and a new
helper `notify_pending_input_if_needed` which will flushes the queued
notification as soon as we have an App context. The
`pending_input_changed` now resets the flag after notifying subscribers.
Before:
https://github.com/user-attachments/assets/7bec4c34-acbf-42bd-b0d1-88df5ff099aa
After:
https://github.com/user-attachments/assets/2264dc93-3405-4d63-ad8f-50ada6733ae7
Release Notes:
- Fixed: pending keybinding prefixes on the status bar now clear
immediately when focus moves to another panel or UI context.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes #ISSUE
This PR is rather a nice to have change than anything critical, so
review priority should remain low.
Switch to using `semver::Version` for representing node binary and npm
package versions. This is in an effort to root out implicit behavior and
improve type safety when interacting with the `node_runtime` crate by
catching invalid versions where they appear. Currently Zed may
implicitly assume the current version is correct, or always install the
newest version when a invalid version is passed. `semver::Version` also
doesn't require the heap, which is probably more of a fun fact than
anything useful.
`npm_install_packages` still takes versions as a `&str`, because
`latest` can be used to fetch the latest version on npm. This could
likely be made into an enum as well, but would make the PR even larger.
I tested changes with some node based language servers and external
agents, which all worked fine. It would be nice to have some e2e tests
for node. To be safe I'd put it on nightly after a Wednesday release.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Use the url crate to extract the domain from the verification URI and
construct the appropriate Copilot sign-up URL for GitHub or GitHub
Enterprise.
Release Notes:
- Improved github enterprise (ghe) copilot sign in
- Edit prediction providers can now be configured through the settings
UI
- Cleaned up the status bar menu to only show _configured_ providers
- Added to the status bar icon button tooltip the name of the active
provider
- Only display the data collection functionality under "Privacy" for the
Zed models
- Moved the Codestral edit prediction provider out of the Mistral
section in the agent panel into the settings UI
- Refined and improved UI and states for configuring GitHub Copilot as
both an agent and edit prediction provider
#### Todos before merge:
- [x] UI: Unify with settings UI style and tidy it all up
- [x] Unify Copilot modal `impl`s to use separate window
- [x] Remove stop light icons from GitHub modal
- [x] Make dismiss events work on GitHub modal
- [ ] Investigate workarounds to tell if Copilot authenticated even when
LSP not running
Release Notes:
- settings_ui: Added a section for configuring edit prediction providers
under AI > Edit Predictions, including Codestral and GitHub Copilot.
Once you've updated you can use the following link to open it:
zed://settings/edit_predictions.providers
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Closes https://github.com/zed-industries/zed/issues/39056
Leverages a new `await_on_background` API that spawns the future on the
background but blocks the current task, allowing to borrow from the
surrounding scope.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Fixes a bug that led to us unnecessarily restarting a language server
when we were looking at a single file of a given language.
Release Notes:
- Fixed a bug that led to Zed sometimes starting an excessive amount of
language servers
When no predictions are available for the current buffer, we will now
attempt to predict at the closest diagnostic from the cursor location
that wasn't included in the last prediction request. This enables a
commonly desired kind of far-away jump without requiring explicit model
support.
Release Notes:
- N/A
This PR introduces a new `MultiBufferOffset` new type wrapping size. The
goal of this is to make it clear at the type level when we are
interacting with offsets of a multi buffer versus offsets of a language
/ text buffer. This improves readability of things quite a bit by making
it clear what kind of offsets one is working with while also reducing
accidental bugs by using the wrong kin of offset for the wrong API.
This PR also uncovered two minor bugs due to that.
Does not yet introduce the MultiBufferPoint equivalent, that is for a
follow up PR.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Closes#41457#41806#41801
Copilot started using `node:sqlite` module which is an experimental
feature between node v22-v23 (stable in v24). The fix was passing in the
experimental flag when Zed starts the copilot LSP.
I tested this with v20.19.5 and v24.11.0. The fix got v20.19 working and
didn't affect v24.11 which was already working.
Release Notes:
- AI: Fix Github Copilot edit predictions failing to start
Add support for GithubCopilot /responses endpoint. This gives the
copilot chat provider the ability to use the new GPT-5 codex model and
any other model that lacks support for /chat/copmletions endpoint.
Closes#38858
Release Notes:
- Add support for GithubCopilot /responses endpoint.
# Added
1. copilot_response.rs that has the /response endpoint types
2. uses response endpoint if model does not support /chat/completions.
3. new into_copilot_response() to map LanguageCompletionEvents to
Request.
4. new map_stream() to map response stream event to
LanguageCompletionEvents and tests.
5. Fixed a bug where trying to parse response for non streaming for
/chat/completion was failing
# Notes
There is a pr open - https://github.com/zed-industries/zed/pull/39989
for adding /response support for OpenAi and OpenAi compatible API.
Altough they share some similarities (copilot api seems to mirror openAi
directly) ive simplified some stuff and tried to keep it the same with
the vscode-chat implementation where possible. There might be a case for
code reuse but i think keeping them separate for now should be ok.
# Tool Calls
<img width="716" height="670" alt="Screenshot from 2025-10-15 17-12-30"
src="https://github.com/user-attachments/assets/14e88a52-ba8b-4209-8f78-73d15034b1e0"
/>
# Image
<img width="923" height="494" alt="Screenshot from 2025-10-21 02-02-26"
src="https://github.com/user-attachments/assets/b96ce97c-331e-45cb-b5b1-7aa10ed387b4"
/>
We've been considering removing workspace-hack for a couple reasons:
- Lukas ran into a situation where its build script seemed to be causing
spurious rebuilds. This seems more likely to be a cargo bug than an
issue with workspace-hack itself (given that it has an empty build
script), but we don't necessarily want to take the time to hunt that
down right now.
- Marshall mentioned hakari interacts poorly with automated crate
updates (in our case provided by rennovate) because you'd need to have
`cargo hakari generate && cargo hakari manage-deps` after their changes
and we prefer to not have actions that make commits.
Currently removing workspace-hack causes our workspace to grow from
~1700 to ~2000 crates being built (depending on platform), which is
mainly a problem when you're building the whole workspace or running
tests across the the normal and remote binaries (which is where
feature-unification nets us the most sharing). It doesn't impact
incremental times noticeably when you're just iterating on `-p zed`, and
we'll hopefully get these savings back in the future when
rust-lang/cargo#14774 (which re-implements the functionality of hakari)
is finished.
Release Notes:
- N/A