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
We'll now add panels to the workspace as soon as they're ready rather
than waiting for all the rest to complete. We should strive to make all
panels fast, but given that their load tasks are fallible and do IO,
this approach seems more resilient.
Additionally, we'll now start loading the agent panel at the same time
as the rest.
Release Notes:
- workspace: Add panels as soon as they are ready
Previously, this was controllable via the undocumented
ZED_WINDOW_DECORATIONS environment variable (added in #13866). Using an
environment variable for this is inconvenient because it requires users
to set that environment variable somehow before starting Zed, such as in
the .desktop file or persistently in their shell. Controlling this via a
Zed setting is more convenient.
This does not modify the design of the titlebar in any way. It only
moves the existing option from an environment variable to a Zed setting.
Fixes#14165
Client-side decorations (default):
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/525feb92-2f60-47d3-b0ca-47c98770fa8c"
/>
Server-side decorations in KDE Plasma:
<img width="3840" height="2160" alt="image"
src="https://github.com/user-attachments/assets/7379c7c8-e5e3-47ba-a3ea-4191fec9434d"
/>
Release Notes:
- Changed option for Wayland server-side decorations from an environment
variable to settings.json field
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Also tidies up error notifications so that in the case of syntax errors
we don't see noise about the migration failing as well.
Release Notes:
- Invalid values in settings files will no longer prevent the rest of
the file from being parsed.
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 ...
### 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>
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 PR makes the `OpenProjectSettings` action open the settings UI in
project settings mode for the first visible worktree, instead of opening
the file. It also adds a `OpenProjectSettingsFile` action that maintains
the old behavior.
Finally, this PR partially fixes a bug where the settings UI won't load
project settings when the settings window is loaded before opening a
project/workspace. This happens because the global `app_state` isn't
correct in the `Subscription` that refreshes the available setting files
to open. The bug is still present in some cases, but it's out of scope
for this PR.
Release Notes:
- settings ui: Project Settings action now opens settings UI instead of
a file
Fix bundled file persistence by introducing SerializationMode enum
Closes: #38094
What's the issue?
Opening bundled files like Default Key Bindings
(zed://settings/keymap-default.json) was causing SQLite foreign key
constraint errors. The editor was trying to save state for these
read-only assets just like regular files, but since bundled files don't
have database entries, the foreign key constraint would fail.
The fix
Replaced the boolean serialize_dirty_buffers flag with a type-safe
SerializationMode enum:
```rust
pub enum SerializationMode {
Enabled, // Regular files persist across sessions
Disabled, // Bundled files don't persist
}
```
This prevents serialization at the source: workspace_id() returns None
for disabled editors, serialize() bails early, and should_serialize()
returns false. When opening bundled files, we set the mode to Disabled
from the start, so they're treated as transient views that never
interact with the persistence layer.
Changes
- editor.rs: Added SerializationMode enum and updated serialization
methods to respect it
- items.rs: Guarded should_serialize() to prevent disabled editors from
being serialized
- zed.rs: Set SerializationMode::Disabled in open_bundled_file()
Result
Bundled files open cleanly without SQLite errors and don't persist
across workspace reloads (expected behavior). Regular file persistence
remains unaffected.
Release Notes: Fixed SQLite foreign key constraint errors when opening
bundled files like Default Key Bindings.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
When doing a project wide search in zed on windows for `hang`, zed
starts to freeze for a couple seconds ultimately starting to error with
`Not enough quota is available to process this command.` when
dispatching windows messages. The cause for this is that we simply
overload the windows message pump due to the sheer amount of foreground
tasks we spawn when we populate the project search.
This PR is an attempt at reducing this.
Release Notes:
- Reduced hangs and stutters in large project file searches
Introduce a new `prefer_focused_window` field to the
`workspace::OpenOptions` struct that, when provided, will make it so
that Zed opens the provided path in the currently focused window.
This will now automatically be set to true when the `--wait` flag is
used with the CLI.
Closes#40551
Release Notes:
- Improved the `--wait` flag in Zed's CLI so as to always open the
provided file in the currently focused window
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes https://github.com/zed-industries/zed/issues/41267
The only downside would be the fact that a Zed window will appear behing
the version modal, but this is a limitation for all "window-less"
actions currently.
Release Notes:
- Made "About Zed" menu entry to work when all Zed windows are closed
Split out from https://github.com/zed-industries/zed/pull/40774 to
reduce the size of the reland of that PR (once I figure out the cause of
the issue)
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Very often, when I'm testing or playing around with the zoom feature,
including the agent panel, I find myself missing one quick action that
would bring everything back to normal. That's what `ResetAllZoom` does.
If you have customized your zoom level in all areas of Zed, that action
returns everything to its default state. Similarly, if you're playing
around with zoom just in the agent panel, `ResetAgentZoom` does the same
in that context.
Release Notes:
- Added the `ResetAllZoom` and `ResetAgentZoom ` actions, allowing to
return the zoom level across the whole app and/or just in the agent
panel to its default/original value.
We document the location of the log file in many places, we should just
make it easy to open directly within your file browser. The one thing
here is naming. We use dynamic naming for "reveal" actions in the
project panel, to reflect the right file manager name per OS, but for a
command palette action, I dont think we want to have dynamic code for
the action name, just going with finder at the moment.
Release Notes:
- Added a `zed: reveal log in file manager` action to the command
palette.
We were spawning the process on the foreground thread before which can
block an arbitrary amount of time. Likewise we no longer block
deserialization on the terminal loading.
Release Notes:
- Improved startup time on systems with slow process spawning
capabilities
Closes#5294
This PR adds a line ending indicator to the status bar, hidden by
default as discussed in
https://github.com/zed-industries/zed/issues/5294.
### Changes
- 8b063a22d8700bed9c93989b9e0f6a064b2e86cf add the indicator and
`status_bar.line_endings_button` setting.
- ~~9926237b709dd4e25ce58d558fd385d63b405f3b changes
`status_bar.line_endings_button` from a boolean to an enum:~~
<details> <summary> show details </summary>
- `always` Always show line endings indicator.
- `non_native` Indicate when line endings do not match the current
platform.
- `lf_only` Indicate when using unix-style (LF) line endings only.
- `crlf_only` Indicate when using windows-style (CRLF) line endings
only.
- `never` Do not show line endings indicator.
I know this many options might be overdoing it, but I was torn between
the pleasant default of `non_native` and the simplicity of `lf_only` /
`crlf_only`.
My thinking was if one is developing on a project which exclusively uses
one line-ending style or the other, it would be nice to be able to
configure no-indicator-in-the-happy-case behavior regardless of the
platform zed is running on. But I'm not really familiar with any
projects that use exclusively CRLF line endings in practice. Is this a
scenario worth supporting or just something I dreamed up?
</details>
- 01174191e4cf337069e7a31b0f0432ae94c52515 rename the action context for
`line ending: Toggle` -> `line ending selector: Toggle`.
When running the action in the command palette with the old name I felt
surprised to be greeted with an additional menu, with the new name it
feels more predictable (plus now it matches
`language_selector::Toggle`!)
### Future work
Hidden status bar items still get padding, creating inconsistent spacing
(and it kind of stands out where I placed the line-endings button):
<img alt="the gap after the indicator is larger than for other buttons"
src="https://github.com/user-attachments/assets/24a346d4-3ff6-4f7f-bd87-64d453c2441a"
/>
I started a new follow-up PR to address that:
https://github.com/zed-industries/zed/pull/39992
Release Notes:
- Added line ending indicator to the status bar (disabled by default;
enabled by setting `status_bar.line_endings_button` to `true`)
Continues the work from #35927 to add a git diff view for stash entries.
[Screencast From 2025-09-17
19-46-01.webm](https://github.com/user-attachments/assets/ded33782-adef-4696-8e34-3665911c09c7)
Stash entries are [represented as
commits](https://git-scm.com/docs/git-stash#_discussion) except they
have up to 3 parents:
```
.----W (this is the stash entry)
/ /|
-----H----I |
\|
U
```
Where `H` is the `HEAD` commit, `I` is a commit that records the state
of the index, and `U` is another commit that records untracked files
(when using `git stash -u`).
Given this, I modified the existing commit view struct to allow loading
stash and commits entries with git sha identifier so that we can get a
similar git diff view for both of them.
The stash diff is generated by comparing the stash commit with its
parent (`<commit>^` or `H` in the diagram) which generates the same diff
as doing `git stash show -p <stash entry>`. This *can* be
counter-intuitive since a user may expect the comparison to be made
between the stash commit and the current commit (`HEAD`), but given that
the default behavior in git cli is to compare with the stash parent, I
went for that approach.
Hoping to get some feedback from a Zed team member to see if they agree
with this approach.
Release Notes:
- Add git diff view for stash entries
- Add toolbar on git diff view for stash entries
- Prompt before executing a destructive stash action on diff view
- Fix commit view for merge commits (see #38289)
Add new `workspace::NewFileSplit` action which expects a
`SplitDirection` argument, allowing users to programmatically control
the direction of the split in keymaps, for example:
```json
{
"context": "Editor",
"bindings": {
"ctrl-s ctrl-h": ["workspace::NewFileSplit", "left"],
"ctrl-s ctrl-j": ["workspace::NewFileSplit", "down"],
"ctrl-s ctrl-k": ["workspace::NewFileSplit", "up"],
"ctrl-s ctrl-l": ["workspace::NewFileSplit", "right"]
}
}
```
Release Notes:
- Added `workspace::NewFileSplit` action, which can be used to
programmatically split the editor in the provided direction.
Co-authored-by: Rian Drake <rian.drake@rocketwerkz.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Added a "Copy All Messages" button to the ACP logs toolbar that copies
all messages in the watched stream to the clipboard as structured JSON.
## Motivation
When troubleshooting ACP protocol implementations, it's helpful to
provide the entire message thread to an LLM for analysis. Previously, I
had to copy individual messages one at a time, which was tedious and
time-consuming. This feature allows copying the entire conversation
history in a single click.
Release Notes:
- Added: Copy All Messages button to ACP logs view
---------
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
This PR primarily does two things:
- replace `serde_json::from_reader` with `serde_json::from_slice`, as
the latter is much much faster, even with loading the file into memory
first.
- runs the initial loading of themes and icon themes coming from
extensions in parallel instead of sequential.
Measuring the `eager_load_active_theme_and_icon_theme` method, this
drastically improves the speed at which this happens (tested this method
primarily with debug builds on my MacBook Pro, but the `Before`
measurement was also confirmed against a `release-fast` build):
- Before: ~260ms on average (in one run, it even took 600ms)
- After: ~20ms on average
Which reduces the time this method takes to load these by around ~92%.
Given that we block on this during the initial app startup, this should
drastically improve Zeds initial startup loading time. Yet, it also
improves responsiveness when installing theme extensions and trying
these.
I also replaced all other `serde_json::from_reader` implementations with
`serde_json::from_slice` and added the former to `disallowed_methods`,
given
https://github.com/serde-rs/json/issues/160#issuecomment-253446892.
Release Notes:
- Improved Zed startup speed when using themes provided by extensions
This PR renames the following actions to make it easier and prioritize
the UI version of interacting with them:
| Before | After |
|--------|--------|
| `OpenSettingsEditor` | `OpenSettings` |
| `OpenSettings` | `OpenSettingsFile` |
| `OpenKeymapEditor` | `OpenKeymap` |
| `OpenKeymap` | `OpenKeymapFile` |
Release Notes:
- Rename actions to open settings (UI/window and JSON file) as well as
to open the keymap (editor tab and JSON file).
Follow-up to #39649, possible fix for #39669
This implements an alternate strategy for showing/hiding the agent panel
in response to `disable_ai`. We don't load the panel at all if AI is
disabled at startup, and when the value of `disable_ai` changes, we load
the panel or destroy it as needed.
Release Notes:
- N/A
Prior we only logged the crate in `log_err`, which is not too helpful.
We now assemble the module path from the file system path.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Before this change the active theme and icon theme were retrofitted onto
the ThemeSettings.
Now they're in their own new global (GlobalTheme::theme(cx) and
GlobalTheme::icon_theme(cx))
This lets us remove cx from the settings traits, and tidy up a few other
things along the way.
Release Notes:
- N/A
# Why
I have find out that this tool exists by browsing Keymap Editor. I think
it would be nice for its discoverability to show it in the app menus in
Dev builds.
# How
Add "GPUI Inspector" app menu item conditionally for Dev builds only.
Release Notes:
- N/A
# Preview
<img width="1014" height="948" alt="Screenshot 2025-10-01 at 14 36 48"
src="https://github.com/user-attachments/assets/c0409e67-1f4d-44f3-90b3-293ad4fe5c73"
/>
Closes#5355
Release Notes:
- Fixed rendering glitches with files with more than 16 million lines
(that occured due to floating number rounding errors).
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes #ISSUE
Adds the ability to create settings and keymap migrations by mutating
`serde_json::Value`s instead of using tree-sitter queries. This
(hopefully) will make complicated migrations far simpler to implement.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
---------
Co-authored-by: Smit <heysmitbarmase@gmail.com>
Co-authored-by: Smit <smit@zed.dev>
Closes #ISSUE
Release Notes:
- project panel: Revamped how project panel entries are refreshed, which
should lead to a significantly smoother experience when working in large
projects.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Thanks to @Zertsov for #37932 which caused me to consider this
implementation approach.
One known issue with this is that it will not wait for actions that do
async work to complete. Supporting this would require quite a lot of
code change. It also doesn't affect the main usecase of sequencing
editor actions, since few are async.
Another caveat is that this is implemented as an action handler on
workspace and so won't work in other types of windows. This seems fine
for now, since action sequences don't seem useful in other window types.
The command palette isn't accessible in non-workspace windows.
Alternatives considered:
* Add `cx: &App` to `Action::build`. This would allow removal of the
special case in keymap parsing. Decided not to do this, since ideally
`build` is a pure function of the input json.
* Build it more directly into GPUI. The main advantage of this would be
the potential to handle non-workspace windows. Since it's possible to do
outside of GPUI, seems better to do so. While some aspects of the GPUI
action system are pretty directly informed by the specifics of Zed's
keymap files, it seems to avoid this as much as possible.
* Bake it more directly into keymap syntax like in #37932. While I think
it would be good for this to be a primitive in the JSON syntax, it seems
like it would better fit in a more comprehensive change to provide
better JSON structure. So in the meantime it seems better to keep the
structure the same and just add a new action.
- Another reason to not bake it in yet is that this provides a place to
document the caveat about async actions.
Closes#17710
Release Notes:
- Added support for action sequences in keymaps. Example:
`["action::Sequence", [ ["editor::SelectLargerSyntaxNode",
"editor::Copy", "editor::UndoSelection"]`
---------
Co-authored-by: Mitchel Vostrez <mitch@voz.dev>
Closes https://github.com/zed-industries/zed/issues/38690Closes#37353
### Background
On Windows, paths are normally separated by `\`, unlike mac and linux
where they are separated by `/`. When editing code in a project that
uses a different path style than your local system (e.g. remoting from
Windows to Linux, using WSL, and collaboration between windows and unix
users), the correct separator for a path may differ from the "native"
separator.
Previously, to work around this, Zed converted paths' separators in
numerous places. This was applied to both absolute and relative paths,
leading to incorrect conversions in some cases.
### Solution
Many code paths in Zed use paths that are *relative* to either a
worktree root or a git repository. This PR introduces a dedicated type
for these paths called `RelPath`, which stores the path in the same way
regardless of host platform, and offers `Path`-like manipulation APIs.
RelPath supports *displaying* the path using either separator, so that
we can display paths in a style that is determined at runtime based on
the current project.
The representation of absolute paths is left untouched, for now.
Absolute paths are different from relative paths because (except in
contexts where we know that the path refers to the local filesystem)
they should generally be treated as opaque strings. Currently we use a
mix of types for these paths (std::path::Path, String, SanitizedPath).
Release Notes:
- N/A
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Peter Tripp <petertripp@gmail.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>