Commit Graph
291 Commits
Author SHA1 Message Date
Conrad IrwinandBen Kunkle 72dc742101 Support building with corgi (#63396)
[corgi](https://github.com/ConradIrwin/corgi) is a cargo-compatible
build tool that runs `build.rs` scripts and proc-macros in a sandbox (no
network, no ambient env, reads limited to a package's own `.rs` sources
unless declared). This makes Zed buildable under it. Cargo builds (dev
and release) are unaffected.

### Changes

- **`scratch` patch**: patch `scratch` to a small local copy
(`corgi-patches/scratch`) that reads `OUT_DIR` at runtime instead of
baking it in at compile time. `cxx-build` writes its shared cxxbridge
headers into `scratch::path(...)`; upstream returns a single global dir
(outside any action's `OUT_DIR`) that the sandbox can't grant, while
this patch gives each build script a private, writable dir in its own
entry. webrtc-sys is self-contained, so per-crate scratch dirs are
sufficient. Kept local rather than a cxx git fork because a git checkout
of cxx needs symlink support that Windows cargo CI lacks.
- **Dev asset loading**: add `util::dev_fs_embed!` and switch dev-mode
`rust_embed` asset sources (`assets`, `settings`, `grammars`, `agent`,
`edit_prediction_cli`) to read from the checkout at runtime, locating
the repo root by walking from the executable up to the enclosing `.git`.
This avoids baking `CARGO_MANIFEST_DIR` into the binary (corgi rejects
artifacts that embed the build-time checkout path, and it's wrong in any
other worktree). Release builds still embed via `#[derive(RustEmbed)]`.
- **Stop baking checkout paths into artifacts**: drop
`gpui::GPUI_MANIFEST_DIR`; resolve `../gpui` from `gpui_apple`'s build
script; stage the metal shader into `OUT_DIR` before compiling so the
`.metallib` records the output dir, not the checkout; resolve the repo
root at runtime in `remote` and `inspector_ui` (removing
`inspector_ui`'s `build.rs` / `ZED_REPO_DIR`).
- **corgi.toml**: declare the pinned tools (`cmake`, prebuilt libwebrtc
via `LK_CUSTOM_WEBRTC`), a release-only `ZED_COMMIT_SHA` probe, and the
non-`.rs` / cross-package reads each package performs.

### Validation

- `corgi check` + `corgi build`, dev and release, for `zed` (plus `cli`,
`remote_server`, `ep`) with a warm C++ cache — clean; built binaries
embed no checkout path.
- `corgi fmt --check`, `corgi clippy`, and `corgi test` on the changed
crates (922 tests pass).
- `cargo check -p util` locally; relying on CI for the full cargo
build/test matrix.

### Notes for the reviewer

- Per the repo rule, the first two lines of `README.md` are the
review-confirmation marker; remove them before merging (this is what
Danger is failing on).
- `remote_server` cross-compilation (linux-musl via zigbuild) is not yet
covered by `corgi.toml` — host (macOS arm64) only for now.

### Suggested .rules additions

Only if the team wants corgi guidance in `.rules` (it recurred several
times here): dev builds must not bake the checkout path into artifacts —
no `env!("CARGO_MANIFEST_DIR")` or `file!()`-derived absolute paths in
library/binary output. Resolve the repo root at runtime via
`util::dev_repo_root()` (walks to `.git`), and use `util::dev_fs_embed!`
for dev-mode `rust_embed` sources.

Release Notes:

- N/A

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-08-31 17:37:00 +00:00
b421755e5d Fix settings schema missing extension-provided LSP settings on remote (#62355)
## Objective

Fixes an issue where language servers provided by extensions are not
included in the settings schemas served by remote servers. When
connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (dev servers,
multi-workspace reopen, git worktree picker), setup-N servers never
received any extension sync, so their schemas omitted extension-provided
language servers, breaking language support for remote development.

## Solution

Three changes ensure that language servers provided by extensions are
included in the settings schemas served by remote servers:

1. **Register connections opened via
`open_remote_project_with_existing_connection` with the extension
store**: dev servers, multi-workspace reopen, and the git worktree
picker now register their connections with the extension store so that
extensions are synced to those servers. Previously only the
`open_remote_project` flow did this, so setup-N servers never received
any extension sync and their schemas omitted extension language servers.

2. **Emit `ExtensionsInstalledChanged` from `HeadlessExtensionStore`
after sync and install complete**: this allows the remote process to
invalidate its cached settings schemas. The local `ExtensionStore`
already emitted this event; without it, the remote schema cache stayed
stale for the lifetime of the server process.

3. **Include available LSP adapters in the project settings schema**:
this matches the user settings schema (this was fixed for `settings` in
#46766 but never applied to `project_settings`).

## Testing

- Manually verified that after connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (including dev
servers and the git worktree picker), extension language servers appear
in the schema served by the remote server.
- Verified that `ExtensionsInstalledChanged` is emitted after sync and
install complete, and that the remote schema cache is correctly
invalidated and rebuilt.
- Verified that the `project_settings` schema includes the available LSP
adapters, matching the behavior of the user settings schema.
- Reviewers should focus on the multi-workspace reopen and git worktree
picker flows (the two previously unregistered flows) to confirm that
extension language servers are correctly synced and appear in the
schema.

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] 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
**Server / Project** — before the fix
<img width="1061" height="749" alt="image"
src="https://github.com/user-attachments/assets/d6c5459f-58fb-4769-a701-f6fb317adc37"
/>
**Local**
<img width="1119" height="449" alt="image"
src="https://github.com/user-attachments/assets/fb30a1e2-74f0-4439-a25f-1022ed164074"
/>

---

Release Notes:

- Fixed an issue where language servers provided by extensions were
missing from settings schemas served by remote servers.

---------

Co-authored-by: vancez <vancez@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-08-27 17:09:28 +00:00
tidely 12f3994269 git_ui: Dismiss askpass prompts when requests end (#61292)
# Objective

Fixes #47623

- When authenticating git commands using a security key through
`askpass`. The modal which asks for user presence does not get dismissed
even after the git command finishes successfully.

## Solution

Add a cancellation task to the `AskPassModal`, which gets dropped when
the requested operation completes. This cancellation task then dismisses
the modal.

## Testing

- I've tried authentication through `askpass` using my own security key.
Testing both successful and failed authentication.
- I've added tests which confirm that the modal gets dismissed when a
task is cancelled, and that the cancellation is triggered when
`ask_password` Task gets dropped.

Willing to pair on review, message me on Slack. Showcase video left out
because it would leak private information.

## 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 authentication prompts not dismissing automatically when using
security keys with ssh
2026-08-18 10:02:20 +00:00
TomandSmit Barmase 44612e574b remote: Fix missing path escaping in SFTP upload (#62239)
# Objective

- Fixes #62238
- Properly escapes paths in the sftp PUT line

## Solution

- 10-line wrapper function that escapes paths as sftp expects. Namely:
paths in quotes with `\\` and `"` escaped.

## Testing

- Did you test these changes? If so, how? `cargo check`
- Are there any parts that need more testing? Up to you, this is a
simple change and I dont think sftp with default install paths ever
worked on MacOS
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? Just connect to a remote on OSX and see if
the logs had an sftp upload failure in there
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

## 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:

- Fix remote uploads over sftp where the paths contain spaces

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-08-11 19:38:35 +00:00
Kirill Bulatov 3692029a80 Bump rustc to 1.97 (#62395)
Release Notes:

- N/A
2026-08-09 22:29:52 +00:00
Travis McHenryandLukas Wirth 3123c86b0e Remote: Stream remote server into WSL on /mnt copy failure (#57624)
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 #47375


The current `crates/remote/src/transport/wsl.rs` remote transport code
tries to copy the remote-server from /mnt/c/* from within WSL. This
fails if you have automount disabled, or otherwise have your drive
unmounted.

How to reproduce this error:

Prerequisites: Windows with WSL2 and a WSL distro installed.

1. Inside the WSL distro, disable Windows automount — edit
`/etc/wsl.conf`:
```ini
[automount]
enabled = false
```

2. From a Windows shell: `wsl --shutdown`
3. Open the distro shell again and confirm `mount | grep /mnt/c` returns
nothing.
4. From Zed (any version before this PR), open a remote WSL project on
that distro for the first time (no cached
`~/.zed_server/zed-remote-server-*` inside the distro — `rm` it if
present).

The solution was to pipe the server in over stdin if the copy fails.
This is a fallback path similar to how ssh.rs has a fallback path if the
download fails there.

With this PR the logs look like this:
```
2026-05-24T18:51:37-07:00 INFO  [remote::transport::wsl] uploading remote server to WSL ".zed_server/download-72808-remote_server" (441187kb)
2026-05-24T18:51:37-07:00 WARN  [remote::transport::wsl] failed to upload remote server via /mnt, falling back to wsl.exe stdin: Command 'Command("wsl.exe" "--distribution" "Ubuntu" "--cd" "~" "--exec" "wslpath" "-u" "C:/Users/<user>/Documents/GitHub/zed/target/remote_server/x86_64-unknown-linux-musl/debug/remote_server")' failed: wslpath: C:/Users/<user>/Documents/GitHub/zed/target/remote_server/x86_64-unknown-linux-musl/debug/remote_server: Command 'Command("wsl.exe" "--distribution" "Ubuntu" "--cd" "~" "wslpath" "-u" "C:/Users/<user>/Documents/GitHub/zed/target/remote_server/x86_64-unknown-linux-musl/debug/remote_server")' failed: wslpath: C:/Users/<user>/Documents/GitHub/zed/target/remote_server/x86_64-unknown-linux-musl/debug/remote_server
2026-05-24T18:51:38-07:00 INFO  [remote::transport::wsl] uploaded remote server in 945.899ms
```

I considered making wsl just use curl/wget to download as a fallback, as
docker/ssh do, but that would lose the 'cache' effect of downloading
once on windows and sending to multiple WSL distros. Which seems to have
been the intent of the copy method in the first place.

I also considered using the network-drive style UNC mount to copy from
Windows to the WSL distro, but that could run into similar issues where
the user may have that disabled. It also seems to copy as WSL's default
user, rather than the --user specified to Zed for the distro. Currently
--user is not passed by default to wsl.exe, so that ends up being the
default user. However, it is settable through the settings.json, so some
rare users may still have an issue with ownership of the copied files.

I chose to make the new stdin option the fallback instead of the default
because the current code is working for most people, and it seemed like
a much larger change to replace the default.

For the tests there don't seem to be any tests for wsl.rs currently that
I can find, so it seemed like a lot of extra code needed to satisfy that
PR checkbox. wsl.rs and docker.rs have zero inline tests, and the ones
that are in ssh.rs don't cover the ensure/upload/download portion. The
integration tests seem to use RemoteClient::fake_server and bypass the
real transports.

For manual testing I tested these scenarios:
1. WSL distro with automount **on** AND existing binary: **still works**
2. WSL distro with automount **on** AND **no** existing binary: **still
works**
3. WSL distro with automount **off** AND existing binary: **still
works**
4. WSL distro with automount **off** AND **no** existing binary: **now
works**

I'm not all that proficient with rust so I used a coding agent to help,
but I reviewed every line and it all makes sense to me. Please let me
know if something looks off, I'm trying to learn.


Release Notes:

- Fixed remote server installation failing in WSL when automount is
disabled.

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-08-04 08:54:56 +00:00
377382e196 remote: Fix incorrect arguments passed to SCP & SFTP (#56080)
All arguments passed to the initial remote connection command were
initially blindly passed to `scp` or `sftp` command line.
This is an issue with some arguments like "-X" or "-Y" that either does
not exist, or have a different semantic.
This PR introduces a denylist of arguments before crafting the command
to execute.

Reproduce steps:

1. Create a new remote connection, e.g `ssh -X user@192.168.1.1`
2. Expect the upload of the remote server to fail with a message saying
that '-X' is not a valid argument for `ssh` / `sftp` depending on your
setup.

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

Release Notes:

- Fixed wrong arguments that may be passed to scp or sftp command when
pushing remote files.

---------

Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-08-02 09:09:11 +00:00
Duncan Ogilvie b4ae33f7fd Fix Devcontainer bugs/spec mismatches (#59020)
When testing Zed on our team's Devcontainer I found some missing
features/bugs/spec mismatches. Commit messages were written by hand,
code reviewed and tested manually, but everything was written by
Claude/Codex based on:

- https://github.com/devcontainers/cli
- https://github.com/devcontainers/spec

The main use case of the metadata is that you can `devcontainer exec`
and `devcontainer up` into a container Zed started (and vice versa). The
same with VSCode, it will reuse Zed's created devcontainer correctly
now. This is useful when using LLMs so they can run commands in the same
devcontainer you have 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 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 Dev Container compatibility and lifecycle behavior.
2026-07-21 14:15:32 +00:00
Smit Barmase 5f624dbe96 git: Fix operations timing out and commit-msg hook being skipped (#61185)
Closes #44926
Closes #43157
Closes #29903

We have an askpass 17s timeout that races against Git operations and
results in "Connecting to host timed out". It came along in #25953 when
we extracted askpass out of remoting, where it was used for SSH.

I think, for SSH connection, no prompt and no connection after 17
seconds means the host is unreachable, so the timeout is a reliable
signal there. But for Git, silence is pretty normal. Cases like hook
running, pack transferring, an ssh-agent waiting on a fingerprint are
all senarios where we should not be dependent on timeout which kills
these healthy operations.

#43285 worked around this for commits by running the pre-commit hook
manually and passing `--no-verify` to `git commit`. But, there are more
problems to address, which I reproduced on my machine:

1. A slow `post-commit` hook fails, since `--no-verify` doesn't skip it.
2. A slow `pre-push` hook fails too, and a workaround like #43285 needs
a lot more handling. See
https://github.com/zed-industries/zed/pull/42946#issuecomment-3550570438.
3. This is the tough one: due to `--no-verify`, we are also skipping the
`commit-msg` hook. There is no direct way to call that hook since, Git
hands this hook its in-progress message file, commits whatever the hook
leaves in it, and aborts if the hook exits non-zero. Reproducing that
outside `git commit` means reimplementing that.
4. An ssh-agent waiting for user approval fails after the timeout, like
if you have 1Password set up.
5. It doesn't solve large fetches. Fetching
`git@github.com:torvalds/linux.git` just dies at the 17s timeout
mid-download.

This PR fix keep the timeout only on the SSH transport and drop it for
Git, which is less of a behavior change and more of a restoring its
original scope. If Git in a terminal doesn't time out, we shouldn't
either. This way, we let Git handle all types of hooks, which solves the
hooks issue along with the timeout issue. _This follows how VS Code does
it. It does not have any kind of timeout on git child process, and hooks
are handled by Git itself._

Edit: I also think working towards way to cancel long going operations
is better way forward. See
https://github.com/microsoft/vscode/issues/171353.

Hooks still don't run for untrusted repositories, the existing
`core.hooksPath=/dev/null` clamp covers that. The `RunGitHook` proto
handler is kept for compatibility with older remote clients.




Release Notes:

- Fixed git operations failing with a misleading "Connecting to host
timed out" error when they took longer than 17 seconds (large fetches,
slow hooks, or waiting on agent-based authentication like 1Password
Touch ID).
- Fixed `commit-msg` hooks being silently skipped on commit.
2026-07-17 13:38:09 +00:00
Lukas Wirth 6b6393fb0b Split out RelPath into a separate crate (#61029)
This is necessary to remove some `util` dependencies from crates, as
well as better sharing for our projects. This also includes the WIP
AbsPath abstraction as well as some bug fixes from internal tooling.


Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-15 08:33:25 +00:00
Tom Houlé f6385d12c7 Consistently use context() to preserve sources for anyhow errors (#59112)
When you use `anyhow::anyhow!("{error}")` to convert a preexisting error
to an `anyhow::Error`, the error source can be lost (depending on the
`Display` impl of the error). Anyhow errors can display the whole source
chain when printed. This commit makes us consistently use `context()`
instead to preserve the underlying error's source.

Release Notes:

- N/A
2026-07-08 12:20:52 +00:00
Kirill Bulatov 8eb85ac9e2 Restore remote binary dev build output (#59997)
Follow-up of https://github.com/zed-industries/zed/pull/46695

cargo outputs to stderr, so if we do not inherit it, we do not see it,
yet this can be useful to understand what broke and see the progress.
I am not sure if there was a reason to remove it, hence creating the PR
to discuss — want to add at least a comment there for the future if we
decide to keep things as is.

Before:

<img width="1731" height="1022" alt="before"
src="https://github.com/user-attachments/assets/92bb0969-e495-41b0-8cac-1f85a83440a0"
/>

After:
<img width="1728" height="1086" alt="after"
src="https://github.com/user-attachments/assets/c733fb8b-adbe-44dc-84a5-48e2c9e63a38"
/>

Release Notes:

- N/A
2026-06-27 09:21:37 +00:00
Lukas Wirth 42edf2fea1 Implement telemetry for the remote server (#59692)
# Objective

Telemetry events generated **on a remote server** were silently dropped,
and all remote telemetry that *was* reported got attributed to the local
client's OS.

## Solution

This PR makes server-originated events flow to the telemetry pipeline
and attributes them to the actual remote host (connection type, OS,
version, architecture), plus adds a transport-agnostic connection event.

## Additional Notes

This removes the "SSH Project Opened" event and replaces it with a
"Remote Connection Established" one that has more structured info and is
also more useful in where it gets invoked.

The server unconditionally sends back telemetry to the client, the
client is then responsible for filtering on whether telemetry is enabled
by the user or not as the server does not have knowledge of those
settings itself.

Release Notes:

- N/A
2026-06-23 05:53:33 +00:00
Richard Feldman fdebc23ccc Prevent archival of manually-created worktrees (#58275)
This fixes archive cleanup for agent threads so Zed only removes
worktrees it explicitly created, rather than treating every linked
worktree under the configured managed directory as safe to delete. When
Zed creates a worktree, it now records it in the local database along
with the creation time of the worktree's git metadata directory
(`.git/worktrees/<name>/`). Archive planning requires that record, and
right before deleting anything, Zed re-stats the directory and compares
creation times: if the worktree was removed and recreated outside Zed
(or the time can't be read at all), deletion is skipped and the stale
record is dropped. Every failure mode fails safe by leaving the
directory untouched.

For remote (SSH) projects, the stat runs on the remote host via a new
`GitWorktreeCreatedAt` request. Worktrees created by a different Zed
install (another release channel, or another machine connecting to the
same host) have no record in the local database and are therefore never
auto-archived, which is the intended conservative behavior.

Closes https://github.com/zed-industries/zed/issues/57155

Closes AI-352

Release Notes:

- Fixed archiving an agent thread incorrectly deleting manually-created
git worktrees.
2026-06-16 15:36:59 +00:00
Zaenalos dd00e1800e Fix SSH askpass on Windows by invoking cli.exe directly (#52491)
On Windows, Zed generated a .ps1 askpass script and set **SSH_ASKPASS**
to 'powershell.exe -ExecutionPolicy Bypass -File ...'. SSH calls exec()
on SSH_ASKPASS which cannot exec a command string, causing:

error: ssh_askpass: exec(powershell.exe ...): No such file or directory

Fix by pointing **SSH_ASKPASS** directly to cli.exe and passing the
socket path via **ZED_ASKPASS_SOCKET** env var, which cli.exe reads
before clap parses arguments.

---
> Compiling Zed almost blew up my computer.
---

Related #29048 

Release Notes:

- Fixed some ssh issues on windows that prevented from connecting to a
remote
2026-06-08 09:37:00 +00:00
Lukas Wirth 9d76bd1265 remote: Do not swallow ssh errors (#58780)
Release Notes:

- Fixed non-descriptive error messages when remote agent processed
disconnected
2026-06-08 08:48:09 +00:00
427b8589b5 scheduler: Add spawn_dedicated for single-threaded actors with !Send state (#57609)
Adds `scheduler::spawn_dedicated_thread` (and inherent `spawn_dedicated`
methods on `PlatformScheduler` and `TestScheduler`) so single-threaded
actors that own `!Send` state can run on their own OS thread and freely
do blocking I/O without disturbing any other executor.

### Why

A single-threaded actor that needs to do blocking syscalls is currently
stuck: it can't run on the shared foreground executor (blocking would
stall every other foreground session), and it can't move to the
background pool because its state isn't `Send`. `spawn_dedicated` gives
each such actor its own thread and its own `LocalExecutor`, while still
participating in the same testable scheduler infrastructure as
everything else.

### Shape

- `pub fn spawn_dedicated_thread(session_id, scheduler, f) -> Task<_>`
in `scheduler`. Owns the OS thread, the per-session runnable channel,
and the `LocalExecutor` setup.
- Inherent `spawn_dedicated` on `PlatformScheduler` (allocates its own
`SessionId`, delegates to the free function).
- Inherent `spawn_dedicated` on `TestScheduler` (no real thread — runs
as a fresh local session driven by the test scheduler's run loop, so
determinism under `many` is preserved).
- Renames `Scheduler::schedule_foreground` → `schedule_local` and
`scheduler::ForegroundExecutor` → `scheduler::LocalExecutor` to reflect
that these are session-pinned queues rather than "the main thread" (a
dedicated session runs on its own thread). GPUI's wrapper
`gpui::ForegroundExecutor` and the `foreground_executor` field/method
names are unchanged to keep blast radius small.
- `LocalExecutor::new` now takes an explicit dispatch closure, so the
routing decision (default session, dedicated thread, or something else)
lives at the construction site.

### Tests

- `TestScheduler` side: round-trip, `!Send` future, `Send` closure
capturing shared state, inner `executor.spawn`, determinism under `many`
seeds, drop-cancels-future, detached child runs after root completes.
- `PlatformScheduler` side: real separate thread (blocking syscalls
don't stall the test), `!Send` future output, drop-cancels-future,
thread tears down after work completes, detached child outlives root.

cc @as-cii

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2026-05-29 15:58:02 +00:00
Ben Kunkle 9ac5425e90 Remove CRLF line endings (#57680)
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 #ISSUE

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-26 12:59:21 +00:00
Conrad Irwin cb7a717a67 Merge gpui::Task and scheduler::Task (#53674)
Release Notes:

- N/A or Added/Fixed/Improved ...
2026-05-05 22:41:13 +00:00
Anthony Eidandcameron 7a60f55db2 git_graph: Add remote support for search operations (#55167)
### Motivation 

This is the second of three PRs to add remote/collab support for the git
graph and is a follow-up to #54468. I'm adding remote support for the
search because it's not user accessible without the initial graph fetch
having remote support, so it allows us to merge this without having to
add full remote support. Collab guest support will be added in a
follow-up PR.

#### Summary

For large repos, searching can take a while to fully stream in all
matched results. For example, running a basic search on the Linux repo
took over 10s for me. Because of that, we want to stream search results
in chunks to downstream users to keep the time-to-first-match low. After
this change, the first chunk gets sent back after ~50ms on the Linux
repo from receiving the request.

In order to accomplish that, I added a new proto client API that allows
for a request to map to n responses. e.g.

```/dev/null/example.rs#L1-1
client.add_entity_stream_request_handler(Self::handle_search_commits);
```

Note: The proto API isn't supported over collab yet, that will be
another PR

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 #ISSUE

Release Notes:

- N/A

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
2026-05-04 16:38:14 +00:00
Nico b30e222745 remote: Reuse existing SSH ControlMaster sessions (#51604)
Closes #45271

Zed hardcodes `ControlMaster=yes` with a `ControlPath` in a random temp
directory, so it can never find a ControlMaster session the user already
has open. This means you get prompted for credentials again even if
you're already authenticated.

This patch checks for an existing master before spawning a new one. It
runs `ssh -G` to resolve the user's configured `controlpath` (with `%h`,
`%p`, etc. already expanded), then `ssh -O check` to verify it's alive.
If it is, Zed skips askpass and uses the existing socket. If not, the
current behavior is unchanged. Both commands are local and don't hit the
network.

Also adds a `killed: AtomicBool` to `SshRemoteConnection` because
`has_been_killed()` was using `master_process.is_none()` as a proxy for
"connection is dead." When reusing an external master, `master_process`
starts as `None`, so the connection pool would discard it immediately.

Tested against a university SSH setup with `ControlMaster auto`
configured. The reuse path connects without prompting, and the fallback
path works normally when no master exists. Windows is unaffected.

Release Notes:

- Zed now reuses existing SSH ControlMaster sessions instead of
prompting for credentials again (#45271).
2026-04-21 07:44:24 +00:00
Toni AlataloandClaude Opus 4.6 27c38f4386 remote: Set current_dir for cargo zigbuild cross-compilation (#53951)
## Summary

- The cross-compile path for building `remote_server` via `cargo
zigbuild` was missing `.current_dir()`, causing it to inherit the
process cwd
- This fails with "cannot specify features for packages outside of
workspace" when Zed is launched from outside its source tree
- The native build path at the same location already sets
`.current_dir()` correctly — this aligns the cross-compile path

Closes #53950

## Test plan

- [x] Build Zed from source
- [x] Launch from `/tmp`: `cd /tmp && /path/to/zed some-project
--dev-container`
- [x] Verify dev container cross-compilation succeeds

Release Notes:

- Fixed dev container cross-compilation failing when Zed is launched
from outside its source directory

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 09:07:53 +00:00
05cad6cf57 sidebar: Filter thread groups by remote host identity (#53918)
### Summary 

Follow up on: https://github.com/zed-industries/zed/pull/53550

Threads in the sidebar are now filtered by remote connection in addition
to path list. Previously, two different machines with the same absolute
project paths (e.g. both at `/home/user/project`) would have their
threads merged into a single sidebar group. Now each remote host gets
its own group.

To support this, this PR introduces `RemoteConnectionIdentity`, a
normalized subset of `RemoteConnectionOptions` that includes only the
fields relevant for identity matching (e.g. SSH host + username + port,
but not nickname or connection timeout). All remote host comparisons in
the sidebar, thread metadata store, and workspace persistence now go
through `same_remote_connection_identity()` instead of raw `==` on
`RemoteConnectionOptions`.

#### Follow Up on remoting for sidebar

1. Make the neighbor in archive thread fallback to the main git worktree
instead of the next thread
2. Start implementing remote git operations that archive feature depends
on
3. Make remote connection pool equality use `RemoteConnectionIdentity`

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:

- N/A

---------

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
2026-04-14 18:40:36 +00:00
KyleBarton 3175865522 Use stored home_dir in Docker struct, not literal $HOME (#53642)
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 #ISSUE

Release Notes:

- N/A
2026-04-10 10:56:48 -07:00
9b2d9fe537 sidebar: Better handling for threads in remote workspaces (#53451)
This PR greatly improves our handling of remote threads in the sidebar.

One primary issue was that many parts of the sidebar were only looking
at a thread's path list and not its remote connection information. The
fix here is to use `ProjectGroupKey` more consistently throughout the
sidebar which also includes remote connection information.

The second major change is to extend the MultiWorkspace with the ability
to initiate the creation of remote workspaces when needed. This involved
refactoring a lot of our remote workspace creation paths to share a
single code path for better consistency.

Release Notes:

- (Preview only) Fixed remote project threads appearing as a separate
local project in the sidebar

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2026-04-09 06:56:28 +00:00
Nitin K. M.andClaude Opus 4.6 d7e1dd408a Removal of mold/wild scripts and mentions in docs (#53078)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] 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


Release Notes:

- N/A

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 21:20:02 +03:00
Conrad Irwin 810e60ee3e Fix shell escaping in getting current env (#53335)
Credit to Dario Weißer for bringing this to our attention.

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:

- Fixed a bug where a cleverly crafted directory name could lead to
remote code execution
2026-04-08 02:56:06 +00:00
Saketh c2478bff0d remote: Use SSH nicknames in display names (#53103)
Closes #52943

## Summary
- Prefer SSH nicknames over raw hosts in remote connection display names
- Add regression tests for nickname and host fallback behavior

## Why
The `nickname` field is documented as the user-facing label for SSH
connections, but `RemoteConnectionOptions::display_name()` always
returned the raw host. That meant recent-projects UI surfaces kept
ignoring nicknames even when they were configured.

## Validation
- `cargo test -p remote ssh_display_name`
- `cargo test -p remote`

Release Notes:

- Fixed SSH recent-project labels to show configured nicknames instead
of raw hosts when available.
2026-04-03 18:55:40 -04:00
b416e4dbde Track project groups in MultiWorkspace (#53032)
This PR adds tracking of project groups to the MultiWorkspace and
serialization/restoration of them. This will later be used by the
sidebar to provide reliable reloading of threads across Zed reloads.

Release Notes:

- N/A

---------

Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
2026-04-03 16:23:52 +00:00
51bad89a6c Clean up worktree setup in tests (#52934)
Release Notes:

- N/A

---------

Co-authored-by: Eric Holk <eric@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
2026-04-01 23:37:12 +00:00
KyleBarton 4b1bc30b49 Dev containers native implementation (#52338)
## Context

Closes #11473

In-house Zed implementation of devcontainers. Replaces the dependency on
the [reference implementation](https://github.com/devcontainers/cli) via
Node.

This enables additional features with this implementation:
1. Zed extensions can be specified in the `customizations` block, via
this syntax in `devcontainer.json:
```
...
  "customizations": {
    "zed": {
      "extensions": ["vue", "ruby"],
    },
  },

```
2.
[forwardPorts](https://containers.dev/implementors/json_reference/#general-properties)
are supported for multiple ports proxied to the host

## How to Review

<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour — numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
     - See the review process guidelines for comment conventions -->

## Self-Review Checklist

<!-- Check before requesting review: -->
- [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:

- Improved devcontainer implementation by moving initialization and
creation in-house
2026-04-01 08:16:27 -07:00
Conrad Irwin 5e57ae3396 Fix a few cases where we weren't escaping shell vars correctly (#50562)
Release Notes:

- N/A
2026-03-02 23:31:11 -07:00
Cole Miller ce5b4190ca remote_server: Don't panic when forwarding stderr (#50505)
Closes ZED-5B7

Release Notes:

- N/A
2026-03-02 12:59:14 -05:00
Wuji ChenandClaude 83398d2863 ssh: Fix IPv6 address formatting in port forward -L arguments (#49032)
## Summary

- Fix SSH `-L` port-forward arguments to wrap IPv6 addresses in brackets
(e.g. `-L[::1]:8080:[::1]:80`), so SSH can correctly parse them
- Rewrite `parse_port_forward_spec` to support bracket-wrapped IPv6
tokens like `[::1]:8080:[::1]:80`
- Add diagnostic logging for stdin read failures in the remote server to
aid debugging connection issues

Closes #49009

## Test plan

- [x] New unit tests: `test_parse_port_forward_spec_ipv6`,
`test_port_forward_ipv6_formatting`,
`test_build_command_with_ipv6_port_forward`
- [x] Existing tests pass: `cargo test -p remote --lib
transport::ssh::tests` (6/6)
- [ ] Manual verification: connect via SSH to an IPv6 host with port
forwarding configured

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-26 08:42:56 +00:00
Filipe Azevedo 8739c2cbcb recent_projects: Fix remote reconnect when server is not running (#49834)
Closes https://github.com/zed-industries/zed/issues/49363

When an existing remote workspace's connection is dead (e.g. the server
died and reconnect failed, leaving the client in `ServerNotRunning`
state), `remote_connection()` returns `None`. Previously this caused an
error dialog, blocking reconnection — the user had to manually switch to
another project and back to recover.

Now the code falls through to establish a fresh connection instead,
matching the previous behavior where clicking "Reconnect" would just
work.

Release Notes:

- Fixed remote reconnect failing with an error when the server is not
running, now establishes a fresh connection instead.
2026-02-23 12:39:56 +01:00
Lukas Wirth f21a93a930 remote: Fix wsl interop detection failing on some setups (#49708)
Closes https://github.com/zed-industries/zed/issues/49697

Release Notes:

- Fixed interop detection on WSL not working on newer setups
2026-02-20 12:51:49 +01:00
MostlyK c3d4b14977 repl: Add WSL and SSH remote kernel support (#47891)
Closes #15196, #46918 

- fix: notebook_ui, use buffer so that notebooks open in remote/WSL
settings.
- fix: add musl in nix for cross-compilation, without this remote server
doesn't build inside NixOS


Release Notes:

- Implement WSL and SSH remote kernels (crates/repl/src/kernels/*) and
wire up spawn/kill kernel proto messages and client requests.
2026-02-20 09:36:21 +00:00
Lukas Wirth 2fb5628281 Reduce amount of monomorphizations from FnMut closures (#49453)
Replaces a bunch of `impl FnMut` parameters with `&mut dyn FnMut` for
functions where this is the sole generic parameter.
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-18 12:00:02 +01:00
John Tur 4edfa67b24 Reuse existing remote workspaces when opening files from the CLI (#49307)
Re-lands https://github.com/zed-industries/zed/pull/48891, which was
reverted due to conflicts with multi-workspace.

Before you mark this PR as ready for review, make sure that you have:
- [X] Added a solid test coverage and/or screenshots from doing manual
testing
- [X] Done a self-review taking into account security and performance
aspects

Release Notes:

- N/A
2026-02-16 18:03:18 -05:00
Jakub KonkaandCole Miller f4aa279898 util: Always use posix_spawn on macOS even with pre_exec hooks (#49090)
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>
2026-02-13 20:16:11 +01:00
Mikayla Maki 4d00186953 Revert PRs for landing in main (#48969)
We're going to re-apply these after landing the multiworkspace branch.

Release Notes:

- N/A
2026-02-12 00:28:17 +00:00
John Tur ca431e7500 Reuse existing windows when opening files in remote workspaces (#48891)
Closes https://github.com/zed-industries/zed/issues/42366

- [ ] Tests or screenshots needed?
- [X] Code Reviewed
- [X] Manual QA

Release Notes:

- Opening files with the Zed CLI will reuse existing windows for remote
workspaces.
2026-02-10 17:48:54 -05:00
Andres Suarez f0010404b4 remote: Fix build_remote_server_from_source compression on unix (#48319)
When using gzip, the output path's extension becomes `.gz`.

Release Notes:

- N/A
2026-02-04 09:15:21 +00:00
KyleBarton 6b4b4a0e85 Use remote user from devcontainer CLI and respect shell in passwd (#48230)
Closes #46252

Uses the `remoteUser` property returned from the devcontainer CLI so
that settings are respected. Additionally, checks for a default shell in
`passwd` if `$SHELL` is not set.

Release Notes:

- Fixed remote_user and shell inconsistencies from within dev containers
2026-02-02 16:43:51 -08:00
localcc b0040c7743 Fix SSH reconnection message (#48190)
Closes #34531

Release Notes:

- N/A
2026-02-02 16:41:35 +00:00
andreasp 02f3860d25 Fix launching from WSL with fish as default shell (#48136)
Closes #46801

When connecting to WSL2 with fish as the default shell, Zed gets stuck
at "Starting proxy". The connection works fine when bash is the default
shell.

In `start_proxy()`, the WSL command was being invoked with:

```rust
let proxy_process = match wsl_command_impl(&self.connection_options, "env", &proxy_args, false)
```

Changing the last argument to true invokes the WSL command with `--exec`
flag which executes the command in the WSL environment without spawning
a new shell.

With above fix I can launch Zed from WSL (Arch) with fish.
2026-02-02 08:11:22 +00:00
Joseph T. Lyons d21b5f1dd6 Revert "Allow always_allow patterns for Nushell, Elvish, and Rc shells" (#48050)
Reverts zed-industries/zed#47908

This PR inadvertently caused a regression:

- https://github.com/zed-industries/zed/issues/48047
2026-01-30 21:26:13 +00:00
Richard FeldmanandZed Zippy a0374a5a80 Allow always_allow patterns for Nushell, Elvish, and Rc shells (#47908)
## Summary

This PR extends the `always_allow` tool permission patterns to work with
Nushell, Elvish, and Rc shells. Previously, these shells were
incorrectly excluded because they don't use `&&`/`||` operators for
command chaining. However, brush-parser can safely parse their command
syntax since they all use `;` for sequential execution.

## Changes

- Add `ShellKind::Nushell`, `ShellKind::Elvish`, and `ShellKind::Rc` to
`supports_posix_chaining()`
- Split `ShellKind::Unknown` into `ShellKind::UnknownWindows` and
`ShellKind::UnknownUnix` to preserve platform-specific fallback behavior
while still denying `always_allow` patterns for unrecognized shells
- Add comprehensive tests for the new shell support
- Clarify documentation about shell compatibility

## Shell Notes

- **Nushell**: Uses `;` for sequential execution. The `and`/`or`
keywords are boolean operators on values, not command chaining.
- **Elvish**: Uses `;` to separate pipelines. Does not have `&&` or `||`
operators. Its `and`/`or` are special commands operating on values.
- **Rc (Plan 9)**: Uses `;` for sequential execution and `|` for piping.
Does not have `&&`/`||` operators.

## Security

Unknown shells still return `false` from `supports_posix_chaining()`, so
`always_allow` patterns are denied for safety when we can't verify the
shell's syntax.

(No release notes because granular tool permissions are still
feature-flagged.)

Release Notes:

- N/A

---------

Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-01-29 06:08:05 +00:00
Lukas Wirth 19aa418dea remote_server: Cleanup old server binaries on wsl (#47839)
Closes https://github.com/zed-industries/zed/issues/44736

Release Notes:

- Fixed remote server binaries accumulating on wsl over time
2026-01-28 13:30:43 +01:00
Lukas Wirth 6cf6032f90 agent_servers: Inherit codex api key environment vars for remote (#47850)
Closes https://github.com/zed-industries/zed/issues/46786

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-01-28 12:29:44 +00:00