1. Extension loaded events are now condensed into a single event with a
Vec of (extension_id, extension_version) called id_and_versions.
2. Editor Saved & AutoSaved are merged into a singular event with a type
field that is either "manual" or "autosave”.
3. Editor Edited event will only fire once every 10 minutes now.
4. Editor Closed event is fired when an editor item (tab) is removed
from a pane
cc: @katie-z-geer
Release Notes:
- N/A
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This PR changes the signature of `language_names` from
```rust
pub fn language_names(&self) -> Vec<String>
// Into
pub fn language_names(&self) -> Vec<LanguageName>
```
The function previously eagerly converted `LanguageName`'s to
`String`'s, which requires the reallocation of all of the elements. The
functions get called in many places in the code base, but only one of
which actually requires the conversion to a `String`. In one case it
would do a `SharedString` -> `String` -> `SharedString` conversion,
which is now totally bypassed.
Release Notes:
- N/A
Follow-up of https://github.com/zed-industries/zed/pull/34208
Closes https://github.com/zed-industries/zed/issues/35185
Previous code assumed that extensions' language server wrappers may leak
only in static data (e.g. fields that were not cleared on deinit), but
we seem to have a race that breaks this assumption.
1. We do clean `all_lsp_adapters` field after
https://github.com/zed-industries/zed/pull/34334 and it's called for
every extension that is unregistered.
2. `LspStore::maintain_workspace_config` ->
`LspStore::refresh_workspace_configurations` chain is triggered
independently, apparently on `ToolchainStoreEvent::ToolchainActivated`
event which means somewhere behind there's potentially a Python code
that gets executed to activate the toolchian, making
`refresh_workspace_configurations` start timings unpredictable.
3. Seems that toolchain activation overlaps with plugin reload, as
`2025-07-28T12:16:19+03:00 INFO [extension_host] extensions updated.
loading 0, reloading 1, unloading 0` suggests in the issue logs.
The plugin reload seem to happen faster than workspace configuration
refresh in
c65da547c9/crates/project/src/lsp_store.rs (L7426-L7456)
as the language servers are just starting and take extra time to respond
to the notification.
At least one of the `.clone()`d `adapter`s there is the adapter that got
removed during plugin reload and has its channel closed, which causes a
panic later.
----------------------------
A good fix would be to re-architect the workspace refresh approach, same
as other accesses to the language server collections.
One way could be to use `Weak`-based structures instead, as definitely
the extension server data belongs to extension, not the `LspStore`.
This is quite a large undertaking near the extension core though, so is
not done yet.
Currently, to stop the excessive panics, no more `.expect` is done on
the channel result, as indeed, it now can be closed very dynamically.
This will result in more errors (and backtraces, presumably) printed in
the logs and no panics.
More logging and comments are added, and workspace querying is replaced
to the concurrent one: no need to wait until a previous server had
processed the notification to send the same to the next one.
Release Notes:
- Fixed warm-related panic happening during startup
Fixes an issue that caused Windows to fail when removing extension's
directories, as Zed had never stop any related processes.
Now:
* Zed shuts down and waits until the end when the language servers are
shut down
* Adds `impl Drop for WasmExtension` where does
`self.tx.close_channel();` to stop a receiver loop that holds the "lock"
on the extension's work dir.
The extension was dropped, but the channel was not closed for some
reason.
* Does more unregistration to ensure `Arc<WasmExtension>` with the `tx`
does not leak further
* Tidies up the related errors which had never reported a problematic
path before
Release Notes:
- N/A
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Smit <smit@zed.dev>
There were a couple of things preventing this from working:
- our hack to stop the node REPL from appearing broke in recent versions
of the JS DAP that started passing `--experimental-network-inspection`
by default
- we had lost the ability to create a debug terminal without specifying
a program
This PR fixes those issues. We also fixed environment variables from the
**runInTerminal** request not getting passed to the spawned program.
Release Notes:
- Debugger: Fix RunInTerminal not working for JavaScript debugger.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Closes #ISSUE
Adds a new `documentation` method to actions, that is extracted from doc
comments when using the `actions!` or derive macros.
Additionally, this PR adds doc comments to as many action definitions in
Zed as possible.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
- [x] Show disabled MCP servers in the list so you can enable them again
- [x] If MCP is not present in the settings, add it
Closes #ISSUE
Release Notes:
- agent: Allow to enable/disable context servers permanently in the
agent configuration view
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Still a work in progress! Todos before merging:
- [x] Allow to delete (not just turn off) an MCP server from the panel's
settings view
- [x] Also uninstall the extension upon deleting the server (check if
the extension just provides MCPs)
- [x] Resolve repository URL again
- [x] Add a button to open the configuration modal from the panel's
settings view
- [x] Improve modal UX to install and configure a non-extension MCP
Release Notes:
- N/A
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Closes#32068Closes#15653
Not entirely sure that it fixes the latter issue, but I am fairly
certain given the comments in #32068 and the available logs in the
issue.
This PR fixes an issue where the Supermaven provider would not leave the
"Initializing" stage. This happened due to the downloaded binary missing
executable permissions. The change here ensures that freshly downloaded
binaries as well as existing binaries downloaded by Zed have executable
permissions set. I decided on also adding this for the latter since
existing downloads would continue to be broken and Supermaven does not
seem to change versions often given the logs provided by users.
While I was at it, I also added a `make_file_executable` to the util
crate mirroring the method of the `zed_extensions_api` and refactored
existing usages where possible to use that method instead. This makes
the code slightly more readable in my opinion, yet adds a method to
non-unix systems that practically does nothing. I can revert this should
that be preferred.
Release Notes:
- Fixed an issue where the Supermaven completion provider would not
leave the "Initializing" stage.
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Prevent extensions from blocking async threads by enabling epoch
interruption with 100ms intervals. Extensions will yield control back to
the executor regularly during Future::poll operations.
Addresses the
[discussion](https://github.com/zed-industries/zed/discussions/24515)
that goes into depth on why this is important when enabling async
support with Wasmtime.
Release Notes:
- N/A
We'll now clean up DAP locators for unloaded extensions and load schemas
proper
I can now load a custom Ruby extensions with all bells and whistles and
use it as my debugger.
Release Notes:
- N/A
This changes the way context servers are organised. We now store a
`source` which indicates if the MCP server is configured manually or
managed by an extension.
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
- DAP schemas will be stored in `debug_adapters_schemas` subdirectory in
extension work dir.
- Added Debug Config integration and such.
Release Notes:
- N/A
Closes#29032
This PR fixes an issue where reconnecting to SSH Remote would result in
a broken language server.
This was caused by SSH clients not registering because the `ssh_clients`
map would still contain an entry from a previously killed SSH server.
For fix, now we also check if its value has been dropped.
Release Notes:
- Fixed issue where reconnecting to SSH Remote would result in broken
code completions and diagnostics.
Before this I'd get log lines like
> ERROR [project] missing `database_url` setting
Now it's:
> ERROR [project] from extension "Postgres Context Server" version
0.0.3: missing `database_url` setting
Release Notes:
- N/A
Also adds reuse of the markdown documentation cache even when
completions are re-queried, so that markdown documentation doesn't
flicker when `is_incomplete: true` (completions provided by rust
analyzer always set this)
Release Notes:
- Added support for filtering language server completions instead of
re-querying.
We now actually call dap_schema provided by extensions instead of
defaulting to a null `serde_json::Value`. We still need to update the
Json LSP whenever a new dap is installed.
Release Notes:
- N/A
This PR allows DAPs to define their own schema so users can see
completion items when editing their debug.json files.
Users facing this aren’t the biggest chance, but behind the scenes, this
affected a lot of code because we manually translated common fields from
Zed's config format to be adapter-specific. Now we store the raw JSON
from a user's configuration file and just send that.
I'm ignoring the Protobuf CICD error because the DebugTaskDefinition
message is not yet user facing and we need to deprecate some fields in
it.
Release Notes:
- debugger beta: Show completion items when editing debug.json
- debugger beta: Breaking change, debug.json schema now relays on what
DAP you have selected instead of always having the same based values.
---------
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Co-authored-by: Cole Miller <m@cole-miller.net>
Co-authored-by: Cole Miller <cole@zed.dev>
Builds on top of https://github.com/zed-industries/zed/pull/30942
This turns on incremental compilation and decreases extension
compilation times by up to another 41%
Putting us at roughly 92% improved extension load times from what is in
the app today.
Because we only have a static engine, I can't reset the cache between
every run. So technically the benchmarks are always running with a
warmed cache. So the first extension we load will take the 8.8ms, and
then any subsequent extensions will be closer to the measured time in
this benchmark.
This is also measuring the entire load process, not just the
compilation. However, since this is the loading we likely think of when
thinking about extensions, I felt it was likely more helpful to see the
impact on the overall time.
This works because our extensions are largely the same Wasm bytecode
(SDK code + std lib functions etc) with minor changes in the trait impl.
The more different that extensions implementation is, there will be less
benefit, however, there will always be a large part of every extension
that is always the same across extensions, so this should be a speedup
regardless.
I used `moka` to provide a bound to the cache. We could use a bare
`DashMap`, however if there was some issue this could lead to a memory
leak. `moka` has some slight overhead, but makes sure that we don't go
over 32mb while using an LRU-style mechanism for deciding which
compilation artifacts to keep.
I measured our current extensions to take roughly 512kb in the cache.
Which means with a cap of 32mb, we can keep roughly 64 *completely
novel* extensions with no overlap. Since our extensions will have more
overlap than this though, we can actually keep much more in the cache
without having to worry about it.
#### Before:
```
load/1 time: [8.8301 ms 8.8616 ms 8.8931 ms]
change: [-0.1880% +0.3221% +0.8679%] (p = 0.23 > 0.05)
No change in performance detected.
```
#### After:
```
load/1 time: [5.1575 ms 5.1726 ms 5.1876 ms]
change: [-41.894% -41.628% -41.350%] (p = 0.00 < 0.05)
Performance has improved.
```
Release Notes:
- N/A
https://github.com/zed-industries/zed/issues/30972 brought up another
case where our context is not enough to track the actual source of the
issue: we get a general top-level error without inner error.
The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD
SHA"))?; ` on the top level.
The PR finally reworks the way we use anyhow to reduce such issues (or
at least make it simpler to bubble them up later in a fix).
On top of that, uses a few more anyhow methods for better readability.
* `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error
conversion/option reporting cases are replaced with `context` and
`with_context` calls
* in addition to that, various `anyhow!("failed to do ...")` are
stripped with `.context("Doing ...")` messages instead to remove the
parasitic `failed to` text
* `anyhow::ensure!` is used instead of `if ... { return Err(...); }`
calls
* `anyhow::bail!` is used instead of `return Err(anyhow!(...));`
Release Notes:
- N/A
Extensions cannot look up available port themselves, hence the new API.
With this I'm able to port our Ruby implementation into an extension.
Release Notes:
- N/A
Precursor to other optimizations, but this already gets us a big
improvement.
Wasm compilation can easily be parallelized, and with all of the cores
on my M4 Max this already gets us an 86% improvement, bringing loading
an extension down to <9ms.
Not all setups will see this much improvement, but it will use the cores
available (it just uses rayon under the hood like we do elsewhere).
Since we load extensions in sequence, this should have a nice impact for
users with a lot of extensions.
#### Before
```
Benchmarking load: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 6.5s, or reduce sample count to 70.
load time: [64.859 ms 64.935 ms 65.027 ms]
Found 8 outliers among 100 measurements (8.00%)
2 (2.00%) low mild
3 (3.00%) high mild
3 (3.00%) high severe
```
#### After
```
load time: [8.8685 ms 8.9012 ms 8.9344 ms]
change: [-86.347% -86.292% -86.237%] (p = 0.00 < 0.05)
Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
2 (2.00%) high mild
```
Release Notes:
- N/A
- Languages now define their preferred debuggers in `config.toml`.
- `LanguageRegistry` now exposes language config even for languages that
are not yet loaded. This necessitated extension registry changes (we now
deserialize config.toml of all language entries when loading new
extension index), but it should be backwards compatible with the old
format. /cc @maxdeviant
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Remco Smits <djsmits12@gmail.com>
Co-authored-by: Anthony <anthony@zed.dev>
Because we instantiated `ContextServerManager` both in `agent` and
`assistant-context-editor`, and these two entities track the running MCP
servers separately, we were effectively running every MCP server twice.
This PR moves the `ContextServerManager` into the project crate (now
called `ContextServerStore`). The store can be accessed via a project
instance. This ensures that we only instantiate one `ContextServerStore`
per project.
Also, this PR adds a bunch of tests to ensure that the
`ContextServerStore` behaves correctly (Previously there were none).
Closes#28714Closes#29530
Release Notes:
- N/A