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
This adds checks to the extension CLI to ensure that tasks and semantic
token rules are actually valid for the compiled extensions.
Release Notes:
- N/A
(This should be merged after #48332)
This PR exposes the LSP settings schema functionality to extensions,
allowing them to provide JSON schema for `initialization_options` and
`settings` fields to enable autocomplete in settings files.
New extension API methods (v0.8.0+):
- `language_server_initialization_options_schema`
- `language_server_settings_schema`
Both methods return an optional JSON string conforming to JSON schema.
Older extension versions gracefully return `None`.
Release Notes:
- Added support for settings schemas for the next version of the
extension API so that settings autocompletion can be provided for
language server settings.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
## Summary
- Route `zed:extension/github` in `since_v0_0_4` to the `since_v0_6_0`
bindings
- Call `latest_github_release` through `since_v0_6_0` for compatibility
with the v0.0.4 extension API
Release Notes:
- Fixed backward compatibility for v0.0.4 extension API GitHub bindings.
We see a number of crashes in Sentry that appear to be crashes in
wasmtime.
This shouldn't happen, as wasmtime is designed to run untrusted code
"safely".
Looking into this, it seems likely that the problem is that we race with
wasmtime
when installing signal handlers. If wasmtime's handlers are installed
before ours,
then any signals that it intends to handle (like out of bounds memory
access) will
reach our handlers before its; which causes us to assume the app has
crashed.
This changes fixes our crash handler initialization to ensure we always
create
our signal handler first, and reverts a previous attempt to fix this
from #40883
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:
- Linux: Fixed crashes that could happen due to our crash handler
erroneously catching signals intended for wasmtime.
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 +
https://github.com/RemiKalbe/zed/commit/6e8f2d2ebe5a93753625a3026aeb996de8cb436b)
* 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>
## Summary
When the v0.8.0 extension API was forked in #44025, the five DAP
dispatcher methods in `wit.rs` were not updated to handle
`Extension::V0_8_0`. Because `V0_8_0` is listed before `V0_6_0` in the
enum, the wildcard `_ =>` catch-all fires first, causing all DAP calls
to bail with `"not available prior to v0.6.0"` for any extension
targeting the v0.8.0 API.
The DAP WIT interface is identical between v0.6.0 and v0.8.0, so the
handler code is the same — this just adds the missing match arms for:
- `call_get_dap_binary`
- `call_dap_request_kind`
- `call_dap_config_to_scenario`
- `call_dap_locator_create_scenario`
- `call_run_dap_locator`
This follows the same pattern used by every other method in the
`Extension` impl block, which already handles both `V0_8_0` and
`V0_6_0`.
## Test plan
- Verified that an extension targeting `zed_extension_api` v0.8.0 with
DAP support can successfully start a debug session (previously failed
with `"dap_request_kind not available prior to v0.6.0"`)
Release Notes:
- Fixed DAP (Debug Adapter Protocol) methods failing for extensions
targeting the v0.8.0 extension API.
Round 2 of #46269 with conflicts properly resolved.
This came up a few times across various extensions. With us about to
ship a new API version soon, it might be worth to add.
Release Notes:
- N/A
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Some language servers include local symbols (e.g., local variables,
parameters) in workspace symbol results. Without the `containerName`
information, these symbols lack context information, making it difficult
to distinguish them from top-level definitions and hindering efficient
symbol lookup.
This change exposes the `container_name` field from LSP
[`SymbolInformation`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolInformation)
to the extension API, allowing language server extensions to access
`symbol.container_name` in `label_for_symbol` and provide meaningful
context when rendering symbol labels.
Note: The `container_name `field is added to all extension API versions
because they seem to share the same underlying Rust types via wasmtime
bindgen. The field is optional, so existing extensions would remain
compatible as far as I understand.
Closes #ISSUE
Release Notes:
- Added `container_name` field to `lsp::Symbol`, accessible via the
extension API's `label_for_symbol` function
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
This allows extensions to add more than one snippet file whilst keeping
it backwards compatible.
Release Notes:
- Added support for specifying multiple snippets paths in extensions.
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
While at it, annotate more functions that are potentially related to
language parsing in buffers.
Also, on macOS, in order to actually have callstack frames properly
recorded by Tracy, you need to manually run `dsymutil` on the binary.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/34402
Release Notes:
- MCP servers can now be run on the remote server when using remote
development. This can be enabled by setting the `"remote": true`
property in the settings entry for the MCP server.
---------
Co-authored-by: localcc <kate@zed.dev>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
## Motivation
This PR unifies the async execution infrastructure between GPUI and
other components that depend on the `scheduler` crate (such as our cloud
codebase). By having a scheduler that lives independently of GPUI, we
can enable deterministic testing across the entire stack - testing GPUI
applications alongside cloud services with a single, unified scheduler.
## Summary
This PR completes the integration of the `scheduler` crate into GPUI,
unifying async execution and enabling deterministic testing of GPUI
combined with other components that depend on the scheduler crate.
## Key Changes
### Scheduler Integration (Phases 1-5, previously completed)
- `TestDispatcher` now delegates to `TestScheduler` for timing, clock,
RNG, and task scheduling
- `PlatformScheduler` implements the `Scheduler` trait for production
use
- GPUI executors wrap scheduler executors, selecting `TestScheduler` or
`PlatformScheduler` based on environment
- Unified blocking logic via `Scheduler::block()`
### Dead Code Cleanup
- Deleted orphaned `crates/gpui/src/platform/platform_scheduler.rs`
(older incompatible version)
## Intentional Removals
### `spawn_labeled` and `deprioritize` removed
The `TaskLabel` system (`spawn_labeled`, `deprioritize`) was removed
during this integration. It was only used in a few places for test
ordering control.
cc @maxbrunsfeld @as-cii - The new priority-weighted scheduling in
`TestScheduler` provides similar functionality through
`Priority::High/Medium/Low`. If `deprioritize` is important for specific
test scenarios, we could add it back to the scheduler crate. Let me know
if this is blocking anything.
### `start_waiting` / `finish_waiting` debug methods removed
Replaced by `TracingWaker` in `TestScheduler` - run tests with
`PENDING_TRACES=1` to see backtraces of pending futures when parking is
forbidden.
### Realtime Priority removed
The realtime priority feature was unused in the codebase. I'd prefer to
reintroduce it when we have an actual use case, as the implementation
(bounded channel with capacity 1) could potentially block the main
thread. Having a real use case will help us validate the design.
## Testing
- All GPUI tests pass
- All scheduler tests pass
- Clippy clean
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ GPUI │
│ ┌──────────────────────┐ ┌────────────────────────────┐ │
│ │ gpui::Background- │ │ gpui::ForegroundExecutor │ │
│ │ Executor │ │ - wraps scheduler:: │ │
│ │ - scheduler: Arc< │ │ ForegroundExecutor │ │
│ │ dyn Scheduler> │ └────────────┬───────────────┘ │
│ └──────────┬───────────┘ │ │
│ │ │ │
│ └──────────┬──────────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ Arc<dyn Scheduler> │ │
│ └───────────┬───────────┘ │
│ ┌──────────────┴──────────────┐ │
│ ▼ ▼ │
│ ┌──────────────────┐ ┌────────────────────┐ │
│ │ PlatformScheduler│ │ TestScheduler │ │
│ │ (production) │ │ (deterministic) │ │
│ └──────────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Yara <git@yara.blue>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Missing required extension files or directories currently result in
opaque "Directory not found" errors being logged during the update index
phase. This can be frustrating to those developing extensions. Add some
context so folks know where to start looking.
Release Notes:
- N/A
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
While profiling Zed, I noticed around 12 `tokio-runtime-worker` threads.
Since `gpui_tokio` runs a Tokio runtime with only two worker threads,
this meant something else was spinning up a default Tokio runtime (My
machine has 10 cores).
After digging into it a bit, it looks like `wasmtime-wasi` needs a Tokio
runtime for some of its calls. That’s also why we run extension tasks on
`gpui-tokio` in the first place.
Reproduction case:
1. Run a clean Zed build.
2. Sample the process → only 2–3 Tokio threads.
3. Install a WASM extension (for example
https://github.com/zed-extensions/nix), which shouldn’t pull in anything
that creates its own runtime.
4. Sample the process again → 10+ Tokio worker threads show up.
```
marcocondrache@xawed ~/P/zed (main)> sample 34260 1 | grep -E "Thread_"
Sampling process 34260 for 1 second with 1 millisecond of run time between samples
Sampling completed, processing symbols...
Sample analysis of process 34260 written to file /tmp/zed_2026-01-03_112527_5pq7.sample.txt
744 Thread_3086626 DispatchQueue_1: com.apple.main-thread (serial)
744 Thread_3086629: RayonWorker0
....
744 Thread_3086651: MacWatcher
744 Thread_3086653: MacWatcher
744 Thread_3086661: com.apple.NSEventThread
744 Thread_3086680: tokio-runtime-worker
744 Thread_3086681: tokio-runtime-worker
...
744 Thread_3087087: tokio-runtime-worker
744 Thread_3087089: tokio-runtime-worker
744 Thread_3087090: tokio-runtime-worker
744 Thread_3087091: tokio-runtime-worker
744 Thread_3087092: tokio-runtime-worker
744 Thread_3087093: tokio-runtime-worker
744 Thread_3087094: tokio-runtime-worker
744 Thread_3087095: tokio-runtime-worker
744 Thread_3087096: tokio-runtime-worker
744 Thread_3087097: tokio-runtime-worker
...
```
Release Notes:
- Reduced number of threads when using extensions
---------
Signed-off-by: Marco Mihai Condrache <52580954+marcocondrache@users.noreply.github.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 ...
This fixes an issue where the snippet file location would not be the
proper one for compiled extensions because it would be populated with an
absolute path instead of a relative one in relation to the extension
output directory. This caused the copy operation downstream to not do
anything, because it copied the file to the location it already was
(which was not the output directory for that extension).
Also adds some tests and pulls in the `Fs` so we do not have such issues
with snippets a third time hopefully.
Release Notes:
- N/A
Implements a specialized constructor `LanguageName::new_static` for
`&'static str` which reduces allocations.
`LanguageName::new` always backs the underlying `SharedString` with an
owned `Arc<str>` even when a `&'static str` is passed. This makes us
allocate each time we create a new `LanguageName` no matter what.
Creating a specialized constructor for `&'static str` allows us to
essentially construct them for free.
Additional change:
Encourages using explicit constructors to avoid needless allocations.
Currently there were no instances of this trait being called where the
lifetime was not `'static` saving another 48 locations of allocation.
```rust
impl<'a> From<&'a str> for LanguageName {
fn from(str: &'a str) -> Self {
Self(SharedString::new(str))
}
}
// to
impl From<&'static str> for LanguageName {
fn from(str: &'static str) -> Self {
Self(SharedString::new_static(str))
}
}
```
Release Notes:
- N/A
To do
* [x] Default to no context retrieval. Allow opting in to LSP-based
retrieval via a setting (for users in `zeta2` feature flag)
* [x] Feed this context to models when enabled
* [x] Make the zeta2 context view work well with LSP retrieval
* [x] Add a UI for the setting (for feature-flagged users)
* [x] Ensure Zeta CLI `context` command is usable
---
* [ ] Filter out LSP definitions that are too large / entire files (e.g.
modules)
* [ ] Introduce timeouts
* [ ] Test with other LSPs
* [ ] Figure out hangs
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
This PR forks a new version of the `zed_extension_api` in preparation
for new changes.
We're jumping from v0.6.0 to v0.8.0 for the WIT because we released
v0.7.0 of the `zed_extension_api` without any WIT changes (it probably
should have been v0.6.1, instead).
Release Notes:
- N/A
Follow up to #39021.
<img width="576" height="141" alt="image"
src="https://github.com/user-attachments/assets/c89885a4-e664-4614-9bb0-86442dff34ee"
/>
- Add migration to remove `source` tag because `ContextServerSettings`
is now untagged
- Fix typos in context server modal
- PR seems to have removed the `test_action_namespaces` test, which I
brought back in this PR
Release Notes:
- Fixed an issue where the `source` property of MCP settings would show
up as unrecognised
https://github.com/zed-industries/zed/pull/40883 implemented this
incorrectly. It was marking a random background thread as a wasm thread
(whatever thread picked up the wasm epoch timer background task),
instead of marking the threads that actually run the wasm extension.
This has two implications:
1. it didn't prevent extension panics from tearing down as planned
2. Worse, it actually made us hide legit panics in sentry for one of our
background workers.
Now 2 still technically applies for all tokio threads after this, but we
basically only use these for wasm extensions in the main zed binary.
Release Notes:
- Fixed extension panics crashing Zed on Linux
### What this solves
This PR adds support for HTTP and SSE (Server-Sent Events) transports to
Zed's context server implementation, enabling communication with remote
MCP servers. Currently, Zed only supports local MCP servers via stdio
transport. This limitation prevents users from:
- Connecting to cloud-hosted MCP servers
- Using MCP servers running in containers or on remote machines
- Leveraging MCP servers that are designed to work over HTTP/SSE
### Why it's important
The MCP (Model Context Protocol) specification includes HTTP/SSE as
standard transport options, and many MCP server implementations are
being built with these transports in mind. Without this support, Zed
users are limited to a subset of the MCP ecosystem. This is particularly
important for:
- Enterprise users who need to connect to centralized MCP services
- Developers working with MCP servers that require network isolation
- Users wanting to leverage cloud-based context providers (e.g.,
knowledge bases, API integrations)
### Implementation approach
The implementation follows Zed's existing architectural patterns:
- **Transports**: Added `HttpTransport` and `SseTransport` to the
`context_server` crate, built on top of the existing `http_client` crate
- **Async handling**: Uses `gpui::spawn` for network operations instead
of introducing a new Tokio runtime
- **Settings**: Extended `ContextServerSettings` enum with a `Remote`
variant to support URL-based configuration
- **UI**: Updated the agent configuration UI with an "Add Remote Server"
option and dedicated modal for remote server management
### Changes included
- [x] HTTP transport implementation with request/response handling
- [x] SSE transport for server-sent events streaming
- [x] `build_transport` function to construct appropriate transport
based on URL scheme
- [x] Settings system updates to support remote server configuration
- [x] UI updates for adding/editing remote servers
- [x] Unit tests using `FakeHttpClient` for both transports
- [x] Integration tests (WIP)
- [x] Documentation updates (WIP)
### Testing
- Unit tests for both `HttpTransport` and `SseTransport` using mocked
HTTP client
- Manual testing with example MCP servers over HTTP/SSE
- Settings validation and UI interaction testing
### Screenshots/Recordings
[TODO: Add screenshots of the new "Add Remote Server" UI and
configuration modal]
### Example configuration
Users can now configure remote MCP servers in their `settings.json`:
```json
{
"context_servers": {
"my-remote-server": {
"enabled": true,
"url": "http://localhost:3000/mcp"
}
}
}
```
### AI assistance disclosure
I used AI to help with:
- Understanding the MCP protocol specification and how HTTP/SSE
transports should work
- Reviewing Zed's existing patterns for async operations and suggesting
consistent approaches
- Generating boilerplate for test cases
- Debugging SSE streaming issues
All code has been manually reviewed, tested, and adapted to fit Zed's
architecture. The core logic, architectural decisions, and integration
with Zed's systems were done with human understanding of the codebase.
AI was primarily used as a reference tool and for getting unstuck on
specific technical issues.
Release notes:
* You can now configure MCP Servers that connect over HTTP in your
settings file. These are not yet available in the extensions API.
```
{
"context_servers": {
"my-remote-server": {
"enabled": true,
"url": "http://localhost:3000/mcp"
}
}
}
```
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#40906Closes#39729
SFTP uploads weren't quoting the install directory which was causing
extension syncing to fail. We were also only running `install_extension`
once per remote-connection instead of once per project (thx @feeiyu for
pointing this out) so extension weren't being loaded in subsequently
opened remote projects.
Release Notes:
- N/A
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This fixes various issues where rustfmt failed to format code due to too
long strings, most of which I stumbled across over the last week and
some additonal ones I searched for whilst fixing the others.
Release Notes:
- N/A
This hopefully resolves the lingering test failures on linux,
but also adds some logging just in case this isn't the problem...
Release Notes:
- N/A
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
When trying to split and clone a non clone-able workspace item we now
attempt split and move instead of doing nothing. Additionally we disable
the split menu buttons if we can't split the active item at all.
Release Notes:
- Improved handling of unsplittable panes