fbda4f862a2fb03b854636b17bd04be3db3d94de
346
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8b2baadb09 |
lsp: Show request durations in RPC messages (#61018)
Language server performance issues can be difficult to diagnose because request timings are not shown alongside the corresponding JSON-RPC traffic. Annotate responses in the "LSP Logs / RPC Messages" view with their end-to-end duration, making it easier to identify slow methods, latency outliers, and cancellation behavior in the language server process launched by Zed. Capture timestamps at the transport boundary, correlate decoded request IDs separately by direction, preserve timing across cancellation, bound stale request tracking, and forward host-measured durations to remote clients. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and relxability - [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 ## Showcase <details> <summary>Example trace</summary> ``` // Send: {"jsonrpc":"2.0","id":61,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":378,"character":3}}} // Receive (took 7.698042ms): {"jsonrpc":"2.0","id":61,"result":[]} // Send: {"jsonrpc":"2.0","id":62,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":378,"character":3},"end":{"line":378,"character":3}},"context":{"diagnostics":[]}}} // Receive (took 5.632167ms): {"jsonrpc":"2.0","id":62,"result":[{"title":"Show macro expansion for `@static`","command":{"title":"Show macro expansion for `@static`","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}},{"title":"Expand all macros in this top-level form","command":{"title":"Expand all macros in this top-level form","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609&mode=toplevel"]}},{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}}]} // Send: {"jsonrpc":"2.0","id":63,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":379,"character":3}}} // Receive (took 3.473792ms): {"jsonrpc":"2.0","id":63,"result":[]} // Send: {"jsonrpc":"2.0","id":64,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":379,"character":3},"end":{"line":379,"character":3}},"context":{"diagnostics":[]}}} // Receive (took 4.472375ms): {"jsonrpc":"2.0","id":64,"result":[{"title":"Show macro expansion for `@static`","command":{"title":"Show macro expansion for `@static`","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}},{"title":"Expand all macros in this top-level form","command":{"title":"Expand all macros in this top-level form","command":"jetls.openMacroExpansion","arguments":["jetls-macro-expansion:/macro-expanded.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609&mode=toplevel"]}},{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=14278&stop=15609"]}}]} // Send: {"jsonrpc":"2.0","id":65,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":380,"character":0}}} // Receive (took 1.186541ms): {"jsonrpc":"2.0","id":65,"result":[]} // Send: {"jsonrpc":"2.0","id":66,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":380,"character":0},"end":{"line":380,"character":0}},"context":{"diagnostics":[]}}} // Receive (took 2.552708ms): {"jsonrpc":"2.0","id":66,"result":[]} // Send: {"jsonrpc":"2.0","id":67,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":401,"character":0}}} // Receive (took 1.490084ms): {"jsonrpc":"2.0","id":67,"result":[]} // Send: {"jsonrpc":"2.0","id":68,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":401,"character":0},"end":{"line":401,"character":0}},"context":{"diagnostics":[]}}} // Receive (took 2.819125ms): {"jsonrpc":"2.0","id":68,"result":[]} // Send: {"jsonrpc":"2.0","id":69,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":400,"character":0}}} // Receive (took 3.501375ms): {"jsonrpc":"2.0","id":69,"result":[]} // Send: {"jsonrpc":"2.0","id":70,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":0}}} // Receive (took 2.903333ms): {"jsonrpc":"2.0","id":70,"result":[]} // Send: {"jsonrpc":"2.0","id":71,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}} // Receive (took 3.166ms): {"jsonrpc":"2.0","id":71,"result":[{"range":{"start":{"line":389,"character":19},"end":{"line":389,"character":22}},"kind":3},{"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}},"kind":2}]} // Send: {"jsonrpc":"2.0","id":72,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":399,"character":14},"end":{"line":399,"character":14}},"context":{"diagnostics":[]}}} // Receive (took 3.169625ms): {"jsonrpc":"2.0","id":72,"result":[{"title":"Show inferred type annotations","command":{"title":"Show inferred type annotations","command":"jetls.openTypeAnnotation","arguments":["jetls-type-annotation:/type-annotated.jl?source=file%253A%252F%252F%252FUsers%252Faviatesk%252Fjulia%252Fpackages%252Fworktrees%252FJETLS%252Fplacid-wren%252FJETLS%252Fsrc%252Fanalysis%252FAnalyzer.jl&start=15676&stop=16556"]}}]} // Send: {"jsonrpc":"2.0","id":73,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}} // Receive (took 1.234396208s): {"jsonrpc":"2.0","id":73,"result":{"contents":{"kind":"markdown","value":"```julia\n(local) ret :: Compiler.RTEffects # Core.PartialStruct(Compiler.RTEffects, Any[Any, Any, Compiler.Effects, Core.Const(nothing)])\n```\n"},"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}}}} // Send: {"jsonrpc":"2.0","id":74,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":399,"character":14}}} // Receive (took 11.429875ms): {"jsonrpc":"2.0","id":74,"result":{"contents":{"kind":"markdown","value":"```julia\n(local) ret :: Compiler.RTEffects # Core.PartialStruct(Compiler.RTEffects, Any[Any, Any, Compiler.Effects, Core.Const(nothing)])\n```\n"},"range":{"start":{"line":399,"character":11},"end":{"line":399,"character":14}}}} // Send: {"jsonrpc":"2.0","id":75,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"position":{"line":401,"character":0}}} // Receive (took 1.098667ms): {"jsonrpc":"2.0","id":75,"result":[]} // Send: {"jsonrpc":"2.0","id":76,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///Users/aviatesk/julia/packages/worktrees/JETLS/placid-wren/JETLS/src/analysis/Analyzer.jl"},"range":{"start":{"line":401,"character":0},"end":{"line":401,"character":0}},"context":{"diagnostics":[]}}} // Receive (took 4.117459ms): {"jsonrpc":"2.0","id":76,"result":[]} ``` </details> --- Release Notes: - Improved LSP Logs by showing request durations alongside RPC responses, making slow language server behavior easier to diagnose. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
fdedc0c2b7 |
branch_picker: Add remote icons and fix edge cases (#61215)
# Objective Make the branch picker easier to scan and ensure branch creation and remote icons behave consistently across All, Local, and Remote filters. ## Solution - Group local and remote branches under their own headers in the All filter. - Place the create-branch option above branch sections when there is no exact branch-name match. - Resolve each remote's hosting provider from its URL and show the provider icon for branches from that remote. - Include remote URLs in remote-workspace repository responses so arbitrary remote names work without hardcoding `origin` or `upstream`. ## Edge Cases Fixed - An exact branch can exist outside the active Local or Remote filter. The picker now checks all branches before offering to create a duplicate branch. - A non-exact search can return fuzzy branch matches and a create action. The create action now stays at the top, before the Local and Remote section headers. - When a filtered search has no branch matches, the create action is shown without incorrectly placing it under a Local Branches or Remote Branches header. - Repositories can use any remote name, not only `origin` and `upstream`. Provider icons are resolved independently for every configured remote. - Remotes hosted on an unknown or unsupported forge use the generic server icon instead of implying a desktop or a specific provider. - Remote-workspace repositories carry the same remote-name-to-URL data as local repositories, so their branch icons follow the same provider-resolution path. ## Testing - `cargo check -p git_ui --no-default-features` - Branch picker test suite (17 tests) - `git diff --check` Tested on macOS. ## 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 ## Showcase <img width="560" height="522" alt="Screenshot 2026-07-17 at 11 19 27 PM" src="https://github.com/user-attachments/assets/28d57315-b859-4a8d-86ca-53f9fb513bf5" /> The updated branch picker groups local and remote branches, keeps the create-branch action above those sections, and shows forge-specific icons for remote branches. --- Release Notes: - Improved branch picker filtering, grouping, branch creation suggestions, and remote-provider icons. |
||
|
|
0c2cf8b508 |
project: Add remote support for adding paths to .gitignore (#56368)
Release Notes: - Fixed remote support for adding paths to .gitignore The problem solved by this PR is: when opening a remote project, right-clicking a new file in the git panel and clicking "Add to .gitignore" does not work. --------- Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
2328aebf25 |
git_panel: Show staged and unstaged diff stats (#60815)
# Objective - Show accurate diff stats for each staged and unstaged projection of a partially staged file in the Git panel. - This was originally considered for https://github.com/zed-industries/zed/pull/59884, but was scoped out of that already-large PR and is being submitted separately as discussed there. ## Solution - Collect HEAD-to-index and index-to-worktree diff stats alongside the existing combined HEAD-to-worktree stats. - Carry the staged and unstaged stats through repository status snapshots and remote status serialization. - Use the stat matching the projected Git panel section while preserving the combined stat for the other grouping modes. - Update the fake Git repository and add regression coverage with deliberately different staged and unstaged counts. ## Testing - `cargo check -p git_ui` - `cargo check -p collab` - `cargo test -p git_ui test_group_by_staging_section_membership_and_order --lib` - `cargo test -p project --lib --no-run` - `cargo fmt --all -- --check` - `git diff --check` ## 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 diff stats for partially staged files in the Git panel |
||
|
|
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. |
||
|
|
23ee3ba37d |
project_panel: Add remote support for undo/redo system (#59709)
# Objective Add remote (SSH) and collaboration support for trashing and restoring files in the project panel, which in turn enables undo/redo of trash operations against remote and collab projects. Relates to #5039. ## Solution - Updated the project panel undo system to carry `TrashId` instead of `TrashedEntry`. - Using `TrashedEntry` could get hairy, as it includes paths, which wouldn't play too nicely when using, for exapmle, macOS as the client and Windows as the host. Using a simple identifier is much easier in this regard and simplifies implementation. - Enabled the Trash action and context-menu entry on remote projects, and removed the command palette filter in `ProjectPanel::new` that was still hiding the action on remote. - As far as I can tell, there isn't a reliable way to detect whether a given remote actually supports the OS trash, so we expose the action everywhere rather than guessing. On a remote without trash support the action will fail when invoked but this is a conscious tradeoff until we find a better way to handle this. - `fs` now tracks trashed files in a `SlotMap<TrashId, TrashedEntry>` on each `Fs` implementation. Trashed files are referenced by an opaque `TrashId` instead of passing a `TrashedEntry` around, which avoids serializing filesystem paths in remote messages. - Split the old `delete_entry(trash: bool)` API into distinct `trash_entry`/`trash_file` (returning a `TrashId`) and `delete_entry`/`delete_file` across `Project`, `Worktree`, `LocalWorktree` and `RemoteWorktree`. - This lets us drop the optional trash result (`Option<TrashedEntry>`) from the delete path and require a `TrashId` from the trash path. - Added new proto messages (`TrashProjectEntry`, `TrashProjectEntryResponse`, `RestoreProjectEntry`, `RestoreProjectEntryResponse`) to let clients request the host to trash or restore entries. - This deprecates `DeleteProjectEntry::use_trash`, but the host still honors it. An older collab peer may request trashing via that flag instead of the newer `TrashProjectEntry`. If the host ignored it, a newer host would permanently delete a file the user meant to send to the trash. The field will be removed in a later PR once all supported peers use `TrashProjectEntry`. ## Testing The following tests were introduced to ensure the new behavior is correctly tested: * `remote_server::remote_editing_tests::test_remote_trash_restore` – Tests trashing a project entry in remote * `remote_server::remote_editing_tests::test_remote_delete_project_entry_with_trash` – Test to ensure we continue respecting `DeleteProjectEntry::use_trash` until it is fully removed * `project_panel::tests::undo::trash_directory_undo_redo` – Not related to these changes but a nice to have as we were missing a test ensuring that trashing and then undoing and redoing it for a directory works as expected Besides these, the following scenarios were manually tested against a remote session on the same machine (macOS): - Trashing → Undo (Restore) → Redo (Trashing) - Batch Trashing → Undo (Batch Restore) → Redo (Batch Trashing) - Rename → Undo (Rename) → Redo (Rename) - Move → Undo (Move) → Redo (Move) - Batch Move → Undo (Batch Move) → Redo (Batch Move) ## 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 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 - [ ] Performance impact has been considered and is acceptable Release Notes: - N/A --------- Co-authored-by: Yara <git@yara.blue> |
||
|
|
d224ea86e8 |
Add a bespoke LSP request path for edit prediction context (#60947)
Closes EP-193
Edit prediction context collection previously reused the editor
goto-definition / goto-type-definition path, which resolves every LSP
result into a `LocationLink` — opening a buffer per target (worktree
creation, buffer registration, anchor conversion) before edit prediction
gets a chance to filter. On remote projects the host additionally
created a peer-visible buffer per link and the client waited on each
one.
This adds a bespoke request path that returns raw results first and only
does the expensive work for results that survive filtering:
- New `EditPredictionDefinition { path: ProjectPath, range:
Range<Unclipped<PointUtf16>> }` boundary type. LSP wire types never
leave `lsp_command.rs`; the workspace-only filter and URI→`ProjectPath`
resolution happen while normalizing the LSP response, before any buffer
exists, so the type encodes the workspace-only invariant.
- New `GetEditPredictionDefinitions` /
`GetEditPredictionTypeDefinitions` LSP commands and proto messages.
Responses carry only path + UTF-16 range — the host never calls
`create_buffer_for_peer` and the client never waits on remote buffers.
- One public API: `Project::edit_prediction_definitions(buffer,
position, include_type_definitions, cx)` fires both LSP requests
concurrently and returns a merged, deduped list ("not capable" = empty).
The definition/type-definition split was never used downstream, so
`CacheEntry` now holds a single list and the fetch pipeline runs one
task per identifier.
- `edit_prediction_context` dedupes raw results before opening buffers;
survivors open via `project.open_buffer(ProjectPath)` (skipping the
invisible-worktree/yarn machinery of `open_local_buffer_via_lsp`, and
working identically on remote projects), then clip → anchor →
`MAX_TARGET_LEN`.
- Removes the `workspace_only` flag from `GetDefinitions` /
`GetTypeDefinitions`: edit prediction was its only user. The editor path
always sent `false`, which proto3 doesn't encode, so normal
goto-definition requests are wire-identical; old peers still sending
`true` get unfiltered results (graceful degradation). The proto field
numbers are `reserved`.
Tested with a local test proving filtering precedes buffer opening (an
out-of-workspace target never spawns a worktree, an oversized target is
excluded from related files) and a collab test proving the remote
round-trip returns correct paths/ranges without opening buffers on the
client.
Release Notes:
- N/A
|
||
|
|
8e863013b4 |
Fix remote worktree picker hides "Create from origin/main" option (#59134)
This passes the `include_remote_name` flag through the remote `GetDefaultBranch` RPC instead of dropping it at the client/host boundary. That lets remote repositories resolve default branches as `origin/main` when needed, so worktree creation uses a valid remote branch name instead of falling back to `main`. 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 Closes #59121 Release Notes: - Fixed remote worktree creation from the default branch when the default branch requires its remote name. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
48192372a0 |
Git partially staged changes (#46541)
This PR explores the addition of a new feature and UI to improve visibility into partially staged commits. Currently, the Git panel shows tracked and untracked changes, but it does not clearly distinguish between staged and unstaged changes. As a result, it’s difficult to quickly see which changes are not staged in the current UI. Both staged and unstaged changes are combined into the `Uncommitted Changes` multibuffer. This developer experience differs from other editors, most notably VS Code; which presents separate Staged Changes and Changes lists. ### Staged and unstaged diffs in multibuffers This PR introduces an alternative UI for unstaged changes that aligns with the overall Zed experience. Instead of showing changes on a per-file basis, staged and unstaged diffs are each displayed in their own multibuffers, similar to how `Uncommitted Changes` currently works. For example the following screenshot shows the current `Uncommitted Changes` on the left, the `Staged Changes` in the middle and the `Unstaged Changes` buffer on the right for comparison <img width="1408" height="859" src="https://github.com/user-attachments/assets/aa709f7a-041d-4cb1-95d6-84c0f5fff688" /> ### Indicators/interactions The new multibuffers can be opened in two ways: 1. Via a new `U` chip, which appears when a file has unstaged changes 2. Via new menu options (See screenshots below for both interaction paths.) <table> <tr> <td style="text-align: center; vertical-align: top;"> <p>via the chip</p> <img height="400" src="https://github.com/user-attachments/assets/3ef69f02-b787-499c-959a-25f50b3728e8" alt="Via the chip" /> </td> <td style="text-align: center; vertical-align: top;"> <p>via the menu</p> <img height="400" src="https://github.com/user-attachments/assets/f5be8b6d-ccdc-4420-bd29-75570b558016" alt="Via the menu" /> </td> </tr> </table> ### Design goals - minimally intrusive UI changes (small new badge and menu items) - adhere by Zed'ism (use multibuffer where possible) - avoid disabling any current interactions (Uncommitted Changes ui is unchanged) - avoid introducing an app level view mode (no new settings needed) ### Experience goals - make it easy to see what changes are not staged - make it easy to see that a file has unstaged changes (avoid developers accidently leaving out changes in a commit; a personal issue that I have when using Zed) - elegantly handle large file's unstaged changes (follows the same collapse and expanding seen in `Uncommitted Changes`) ### How to try - Clone the repo and run `cargo run` - Make a change to a file and stage it - Make another change to the file (the `U` indicator will appear) - Click the `U` to see the unstaged view ### Open questions/rough edges - [ ] determine if this user experience is useful for others - [ ] ensure all interactions work as expected (response to all update cases) In general I'm really interested in hearing the community's feedback about this interface, more than happy to make any changes or explore a different solution! ### Related issue: - https://github.com/zed-industries/zed/pull/36646 - https://github.com/zed-industries/zed/issues/26560 Release Notes: - Support partially staged commit multibuffers via a staged and unstaged changes view. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
f023a7e4a3 |
Fix worktree grouping for bare checkouts (#59968)
Summary - Track whether a worktree root is itself a linked Git worktree. - Use that metadata when computing project group keys so bare checkout worktrees group under the repository identity path. - Propagate the metadata through remote worktree protocols and add local/remote regression coverage. Background Bare checkout layouts can place linked worktrees under the repository identity directory, e.g. `/monty/.bare` with worktrees like `/monty/feature-a`. We were treating those linked worktree paths as separate project identities, which caused the sidebar to move agent threads under the active worktree instead of the shared repository group. We also exclude adding this to collab intentionally, we can open a different PR for that if we need to. Closes #59910 Closes AI-431 Test Plan - `cargo fmt --package project --package worktree --package remote_server --package workspace --package collab --package proto` - `git --no-pager diff --check` - `cargo test -p project test_project_group_key -- --nocapture` - `cargo test -p remote_server test_remote_root_repo_common_dir -- --nocapture` - `cargo test -p worktree remote_worktree -- --nocapture` - `cargo test -p workspace test_remote_project_root_dir_changes_update_groups -- --nocapture` - `cargo check -p collab` 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 Release Notes: - Fixed agent thread/sidebar grouping for Git worktrees backed by bare checkouts. --------- Co-authored-by: Anthony Eid <anthony@zed.dev> |
||
|
|
5531777b7b |
collab: Add username to User (#60097)
This PR adds the `username` field to `User` and `proto::User`. Closes CLO-949. Release Notes: - N/A |
||
|
|
fe2c2f4000 |
Fix code lens not being resolved in remote workflows (#59999)
Follow-up to https://github.com/zed-industries/zed/pull/54100 Closes https://github.com/zed-industries/zed/issues/59122 Original PR overlooked that the resolve was not handled from the remote hosts at all... Also, fixes the re-fetch of code lens not taking new language servers into account: before, it exit early whilst now it actually re-fetches the lens for the new servers. Before: <img width="1728" height="1084" alt="before" src="https://github.com/user-attachments/assets/9ee8205b-084b-4409-9abc-18c4ddb9c4e9" /> After: <img width="1728" height="1084" alt="after" src="https://github.com/user-attachments/assets/16ad76dc-25e1-4257-80dc-b5aeabc9a4ef" /> Release Notes: - Fixed code lens not being resolved in remote workflows |
||
|
|
7c91706a11 |
Unship shared threads (#59981)
This PR unships shared threads. The feature is not used much and is getting in the way, at this point. These are only ever made available to staff. The corresponding database schema migration has been created in the Cloud repo and applied to the production database. Release Notes: - N/A |
||
|
|
f743291f1c |
collab: Revert livekit changes (#59733)
- **Revert "livekit: Preserve tokens on channel rejoin (#59388)"** - **Revert "call: Log LiveKit connection info refresh outcomes in retry loop (#59205)"** - **Revert "audio: Fix phantom presence in channels (#59195)"** - **proto: Reserve RejoinRoomResponse field 4 after revert** We've observed a spike of phantom collaborator issues after this fixes. This sucks and I'm quite unhappy about it. # Objective - Describe the objective or issue this PR addresses. - If you're fixing a specific issue, use "Fixes #X" for each issue as [described in the GitHub docs](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). ## Solution - Describe the solution used to achieve the objective above. ## Testing - Did you test these changes? If so, how? - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? ## Self-Review Checklist: - [ ] 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) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable ## Showcase > This section is optional. If this PR does not include a visual change or does not add a new user-facing feature, you can delete this section. - Help others understand the result of this PR by showcasing your awesome work! - If this PR includes a visual change, consider adding a screenshot, GIF, or video - A before/after comparison is very useful for changes to existing features! While a showcase should aim to be brief and digestible, you can use a toggleable section to save space on longer showcases: <details> <summary>Click to view showcase</summary> My super cool demos here </details> --- Release Notes: - N/A --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
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. |
||
|
|
130a9d31d7 |
audio: Fix phantom presence in channels (#59195)
# Objective You know that feeling? You join the channel, crack a banger joke to break the ice - yet, nobody laughs. Worse yet, you're swarmed with Slack messages like "Piotr, we can't hear you". After a while you realize that maybe it's for the best as the joke was not as good as you've initially thought, but still: it's possible to get into a state where other participants see you as muted. You don't hear anybody. Bummer. That's what happened when we were hoping to pair with @dinocosta today. I could not hear him. However, he had some logs to share which indicated that while collab thought he's in the room with me, live-kit was rejecting his token as it was revoked. What clanker helped us figure out is that there's a race-y code path where if you disconnect from a given room abruptly, collab can put you in a limbo. <details><summary>Clanker's idea of what's going on</summary> <p> Found the whole story. Here's what those logs mean and where the bug surface is. What's happening The error at room.rs:1809 is the detach_and_log_err on the task spawned by spawn_room_connection (crates/call/src/call_impl/room.rs:1754-1810). So this is the initial livekit::Room::connect call failing — the LiveKit SDK internally retried 3 times (that's the retrying... (1/3) lines), got 401 invalid token: revoked every time, gave up, and the error propagated out of the ? at line 1762 and was logged-and-dropped. The "revoked" comes from the collab server: leave_room_for_session (crates/collab/src/rpc.rs:4091-4095) calls live_kit.remove_participant(livekit_room, session.user_id().to_string()), and LiveKit Cloud treats a removed participant's token as revoked. Crucially, the LiveKit identity is just the user id, not the connection id, while the DB-side leave_room(connection_id) is per-connection. leave_room_for_session fires from three places: 1. Explicit leave (rpc.rs:1666) 2. connection_lost, after RECONNECT_TIMEOUT expires (rpc.rs:1342) 3. Stale-connection cleanup when re-joining a channel (rpc.rs:3401) So there's a race: an old connection's delayed cleanup (path 2) can fire after the same user has rejoined the room on a new connection and been issued a fresh token — and remove_participant(room, user_id) kicks/revokes the user's current LiveKit participant, because the identity is shared across connections. Quick restart of Zed, two instances, or a reconnect that straddles the server's RECONNECT_TIMEOUT all set this up. Client-side consequences (this connects to your first question) When that initial connect fails: - this.live_kit stays None and this.diagnostics is never created — lines 1780-1791 only run on success. So in this failure mode CallDiagnostics doesn't exist at all; the "stats never overridden" path I described earlier isn't even reached. - There is no retry and no token refresh. The failure is detach_and_log_err'd and that's the end of it. The user stays in the room at the collab level (status is still Online, they appear in the channel), but with no audio and no way to recover short of leaving and rejoining. - Even a collab-level reconnect doesn't help: RejoinRoomResponse (crates/proto/proto/call.proto:58) carries no live_kit_connection_info, and rejoin() never calls spawn_room_connection — the LiveKit connection is established exactly once, in Room::new, with the token from the original join response. So the user-visible symptom is: you're "in" the call, everyone sees you, but you can't hear or be heard, and there's no error surfaced in the UI — just this log line. If you want to fix it, the two angles are server-side (make leave_room_for_session skip the LiveKit removal when the user still has a live connection in that room, or scope LiveKit identities per-connection) and client-side (treat a failed spawn_room_connection as fatal-but-recoverable: surface it, and have rejoin request fresh connection info instead of silently carrying on). Happy to dig into either if you want. </p> </details> So tl;dr: our token was swapped out underneath us. One way to "fix" it was to just go into another channel, but that was a bummer. We have a good and reliable repro for it though: `kill -9 $ZED_PID` followed by an attempt to rejoin the same channel within 30s would consistently put us in that state. Put another way: you panic and thus do not send a clean "leave room" message to LK. if you rejoin the channel within 30s (after restarting), LK will invalidate the very token you're attempting to use (as it cleans up old tokens). It may also happen without crashing, but that's the most reliable way to repro the issue. Long story short your LK token gets tainted and you can't share the audio anyhow. ## Solution The fix is both client and server-side. On client's side, we now retry the reconnection with a back-off and we grab a fresh token off of reconnect attempts. On server's side, we share the current token on room reconnect attempts. We've also tweaked the call diagnostics to not use `unwrap_or_default` so much: it was hard for us to tell that we're in a totally bogus state and we've only reached that conclusion based on source code analysis. We now show some generic "ok you're in a borked state pls report a bug" message instead. ## Testing We added tests that present the flacky scenario. We've also tried to setup an infra to test the new behaviour, but sadly, local LK instance seems to revoke tokens more leniently than the prod.. OTOH, we are quite confident that once new collab is deployed, we'll be able to mince the new tokens and life is going to be good. Even when running against the current prod instance we could see that our code changed the behaviour for the better, as now we'll actually try to use a new token if one is provided by collab. For that to happen we need to redeploy though. ## 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 a race condition that caused collab users to not receive/send any audio to their peers. --------- Co-authored-by: dino <dinojoaocosta@gmail.com> Co-authored-by: Dino <dino@zed.dev> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
0b0436dda5 |
acp: Indicate when agent is downloading (#57710)
Release Notes: - agent: Indicate when ACP servers are downloading --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
cf5bdcb9a9 |
lsp: Register available LSP adapters locally when in remote development (#54915)
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 #49178 The context for this change is covered in #49178. Some language server adapters are lazily registered; in remote development or collab sessions, the local client fails to register these adapters, may causing certain LSP features to function incorrectly. This PR is intended to address that. Release Notes: - N/A |
||
|
|
760f479696 |
Remove stale SSH LSP log entries after server restarts (#55299)
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 #55287 This fixes the SSH remote case where restarting a language server left a stale entry in the LSP Logs panel. The root cause was that the remote client learned about the replacement language server, but never received an explicit removal update for the previous server id. As a result, the old status and log-store entry remained visible even though only the new server continued producing logs. Tested with: - `cargo test -p collab --test collab_tests remote_editing_collaboration_tests::test_ssh_restarting_language_server_replaces_remote_status -- --exact` Release Notes: - Fixed stale duplicate entries in the LSP Logs panel after restarting an SSH remote language server. Co-authored-by: Lukas Wirth <lukas@zed.dev> |
||
|
|
8d4499341e |
Support LSP document links (#56011)
Closes https://github.com/zed-industries/zed/issues/33587 https://github.com/user-attachments/assets/bbaea8a9-402e-485b-800e-2f4486142956 Release Notes: - Supported LSP document links (enabled by default, use `"lsp_document_links": false` to turn it off) |
||
|
|
f7088b3f8a |
git: Recover branch refs when metadata lookup fails (#57285)
cc @cole-miller 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: - Fixed branch enumeration when a broken Git ref prevents commit metadata from being read. --------- Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
ab007980ef |
ep: Don't open unnecessary files during context collection (#57318)
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 or Added/Fixed/Improved ... |
||
|
|
2ef5304e89 |
git_ui: Add force delete for unmerged branches (#55927)
Git's `-d` flag deletes a branch only if it's fully merged into its upstream or HEAD - this is what we were using before, which caused the "not fully merged" error. The `-D` flag force deletes a branch even with unmerged changes (equivalent to `--delete --force`). ### Before Deleting an unmerged branch failed with a "not fully merged" error toast. ### After - Deleting an unmerged branch prompts for confirmation to force delete - Delete button tooltip shows "Hold alt to force delete" hint - Holding **alt** turns the delete icon red and tooltip changes to "Force Delete Branch" - Force delete keybinding: `cmd-alt-shift-backspace` Release Notes: - Added confirmation prompt when deleting unmerged git branches, with option to force delete. - Added alt+click on delete button to force delete a branch immediately. |
||
|
|
26b9e07fa8 |
git_graph: Add remote support (#55788)
Follow up: https://github.com/zed-industries/zed/pull/55167, https://github.com/zed-industries/zed/pull/54468 This is the final PR for adding remote support on the git graph. It uses the client stream request support added in #55167 to add support for the initial graph data request. I also fixed a bug where `GitGraph::FullyLoaded` repository event was never emitted. 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 ##53040 Co-authored-by: Remco Smits \<djsmits12@gmail.com\> Release Notes: - git_graph: Add remote support --------- Co-authored-by: Ben Kunkle <ben@zed.dev> |
||
|
|
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> |
||
|
|
cb4281662f |
Fix creating branch with base in remote (#55387)
To support branch create with base branch, added extra optional field in GitCreateBranch proto. 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 #43985 Release Notes: - git: Fixed remote branch creation based on default branch |
||
|
|
17c284803f |
Improve bare repo support (#55153)
Fixes https://github.com/zed-industries/zed/issues/54830 This fixes a bugs where * when there's no main worktree, we treated the first linked worktree as main * the titlebar and sidebar showed two different things when opening a linked wortree directly When there's no main worktree, our "project group key" will be the bare repo path. For displaying this to the user, we try to present something meaningful: * If the bare repo is `foo.git`, we'll say "foo" * If the bare repo is "bar/.bare", we'll "bar" Release Notes: - Fixed bugs in Zed's sidebar and titlebar when editing in git worktrees created from bare repositories. |
||
|
|
05f474361d |
git: Replace file history view with git graph (#50288)
## Summary This PR replaces the git file history view with the git graph view that doesn't render the graph canvas. This has several advantages 1. Benefits from the graphs performance and lazy loading 2. Gets the graph's search for free 3. Resizable columns 4. The commit information panel 5. Is persistent 6. Cleans up a lot of code The one con of this change is the graph doesn't have support remote/collab support yet, but that is a WIP and should be merged within a week. Also, the git graph now propagates errors to the UI, which is the last thing on the graph's stable launch todo list! 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 - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: dino <dinojoaocosta@gmail.com> Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com> Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com> |
||
|
|
08029066e6 |
git: Fix remote branch picker not showing branches (#54575)
This sends `branch_list` in live `UpdateRepository` messages so downstream repository snapshots stay in sync and the remote branch picker can populate correctly. Collab DB replay for join/reconnect will follow in a separate change. This fixes a bug where the branch picker wouldn't show any branches in remote environments 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 #54530 Release Notes: - git: Fix remote branch picker not showing any branches |
||
|
|
e311f9df9a |
git_graph: Add remote support for commit data handler (#54468)
### Motivation To support remote Git graph usage, we need remote support for the Git APIs that the graph depends on. This PR adds remote support for `CommitDataHandler` (the `git cat-file --batch` process manager), allowing remote Git graph consumers to fetch visible commit data without polling. #### Summary The Git graph separates the UI and data layers so the UI can continue rendering while commit data is fetched in the background. This change extends that model to remote repositories by allowing `GitStore::fetch_commit_data(sha: Oid, await_result: bool, cx: &mut Context) -> &CommitDataState` to await remote commit loading. For simplicity, the `Starting` variant was removed from `CommitDataState`. `CommitDataState::Loading(Option<...>)` now stores `Some(...)` when `await_result == true` is passed to `fetch_commit_data`. This allows the data layer to await commit loading without polling, and only when explicitly requested. I also removed the `Graph` prefix from `CommitData`-related types because this API is general-purpose and not limited to the graph. Longer term, I hope to replace `Repository::show` with the commit data functionality, since it already provides built-in caching. #### Bug Fixes - Fix stale `Loading(...)` entries that survive enqueue failure or handler shutdown. - Fix commit data handler bookkeeping so `pending_requests`, `completion_senders`, and `CommitDataState` remain consistent. - Fix remote commit-data loading so the data layer can await results instead of polling. #### Testing - Add property tests for commit data fetching. - Add a collab integration test that verifies batched remote commit-data fetching. #### Follow Up In a follow-up, I want to replace the `Repository::show` backend with the commit data handler and remove `CommitDetails` from the codebase as a cleanup and maintenance pass. The commit data handler already provides caching and is a better long-term path for commit metadata access. I may also want to allow the `CommitData` type to propagate errors to callers. For the Git graph, the remaining work is remote search and initial data fetching. 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: Remco Smits <djsmits12@gmail.com> |
||
|
|
5c770a5560 |
agent: Support remote archive thread git operations (#54001)
### Summary This PR implements remote support for git store operations that the sidebar's archive thread checkpoint/restore featured relied on. This was the second to last blocker for remote usage of this feature. I also made a shared backend between `update_ref` and `delete_ref` called `edit_ref` because they run the same git command and this allowed for some code unification. #### Remote Git Operations - `Repository::update_ref` - `Repository::delete_ref` - `Repository::repair_worktrees` - `Repository::create_archive_checkpoint` - `Repository::restore_archive_checkpoint` #### Follow up `agent_ui::thread_worktree_archive::find_or_create_repository` needs to be made aware of the remote machine that the repository it's searching for is on. Once that is completed, we can get the correct repo when archiving a remote thread and the flow should work without any problems. 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 |
||
|
|
4a41cc4bf0 |
agent_ui: Improve the new thread worktree UX (#53941)
Closes https://github.com/zed-industries/zed/issues/53262 - Remove the ability to pick a branch from the agent panel; delegate this to the title bar picker - Make the worktree creation earger, just as you selected whether you want to create it from main or current branch - Remove flicker when creating a new worktree and switching to a previously existing one - Improve some UI stuff: how we display that a worktree is creating/loading, the branch and worktree icons, etc. - Fixed a bug where worktrees in a detached HEAD state wouldn't show up in the worktree pickers A big part of the diff of this PR is the removal of everything involved with the `StartThreadIn` enum/the set up involved in only creating the worktree by the time of the first prompt send. Release Notes: - Agent: Improved and simplified the UX of creating threads in Git worktrees. - Git: Fixed a bug where worktrees in a detached HEAD state wouldn't show up in the worktree picker. --------- Co-authored-by: Nathan Sobo <nathan@zed.dev> |
||
|
|
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> |
||
|
|
555a0a4985 |
agent_panel: Add new thread git worktree/branch pickers (#52979)
This PR allows users to create a new thread based off a git worktree that already exists or has a custom name. User's can also choose what branch they want the newly generated worktree to be based off of. The UI still needs some polish, but I'm merging this early to get the team using this before our preview launch. I'll be active today and tomorrow before launch to fix any nits we have with the UI. Functionality of this feature works! And I have a basic test to prevent regressions 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 ... --------- Co-authored-by: cameron <cameron.studdstreet@gmail.com> |
||
|
|
4b17369db2 |
Add allow_empty commits, detached worktree creation, and new git operations (#53213)
Extend the git API with several new capabilities needed for worktree archival and restoration: - Add `allow_empty` flag to `CommitOptions` for creating WIP marker commits - Change `create_worktree` to accept `Option<String>` branch, enabling detached worktree creation when `None` is passed - Add `head_sha()` to read the current HEAD commit hash - Add `update_ref()` and `delete_ref()` for managing git references - Add `stage_all_including_untracked()` to stage everything before a WIP commit - Implement all new operations in `FakeGitRepository` with functional commit history tracking, reset support, and ref management - Update existing call sites for the new `CommitOptions` field and `create_worktree` signature Part 1 of 3 in the persist-worktree stack. These are nonbreaking API additions with no behavioral changes to existing code. Release Notes: - N/A --------- Co-authored-by: Anthony Eid <anthony@zed.dev> |
||
|
|
83e95f3c7e |
Maintain root repo common dir path as a field on Worktree (#53023)
This enables us to always different git worktrees of the same repo together. Depends on https://github.com/zed-industries/cloud/pull/2220 Release Notes: - N/A --------- Co-authored-by: Eric Holk <eric@zed.dev> |
||
|
|
972bc8c5d6 |
devcontainer: Implement remote support for git checkpoint operations (#48896)
Closes #47907 Implements the four git checkpoint operations (`create`, `restore`, `compare`, `diff`) that had been stubbed out for remote repositories, and related test infrastructure. Testing steps: 1. Open a project with a `.devcontainer` configuration and connect to the Dev Container 2. Open an Agent thread and ask the agent to make a code change 3. After the agent completes, verify the "Restore from checkpoint" button appears (previously missing in Dev Container sessions) 4. Click "Restore from checkpoint" and confirm the file reverts to its prior state Release Notes: - Added support for git checkpoint operations in remote/Dev Container sessions, restoring the "Restore from checkpoint" button in Agent threads. --------- Co-authored-by: KyleBarton <kjb@initialcapacity.io> |
||
|
|
30b1051cd8 |
Require multibuffer excerpts to be ordered and nonoverlapping (#52364)
TODO:
- [x] merge main
- [x] nonshrinking `set_excerpts_for_path`
- [x] Test-drive potential problem areas in the app
- [x] prepare cloud side
- [x] test collaboration
- [ ] docstrings
- [ ] ???
## Context
### Background
Currently, a multibuffer consists of an arbitrary list of
anchor-delimited excerpts from individual buffers. Excerpt ranges for a
fixed buffer are permitted to overlap, and can appear in any order in
the multibuffer, possibly separated by excerpts from other buffers.
However, in practice all code that constructs multibuffers does so using
the APIs defined in the `path_key` submodule of the `multi_buffer` crate
(`set_excerpts_for_path` etc.) If you only use these APIs, the resulting
multibuffer will maintain the following invariants:
- All excerpts for the same buffer appear contiguously in the
multibuffer
- Excerpts for the same buffer cannot overlap
- Excerpts for the same buffer appear in order
- The placement of the excerpts for a specific buffer in the multibuffer
are determined by the `PathKey` passed to `set_excerpts_for_path`. There
is exactly one `PathKey` per buffer in the multibuffer
### Purpose of this PR
This PR changes the multibuffer so that the invariants maintained by the
`path_key` APIs *always* hold. It's no longer possible to construct a
multibuffer with overlapping excerpts, etc. The APIs that permitted
this, like `insert_excerpts_with_ids_after`, have been removed in favor
of the `path_key` suite.
The main upshot of this is that given a `text::Anchor` and a
multibuffer, it's possible to efficiently figure out the unique excerpt
that includes that anchor, if any:
```
impl MultiBufferSnapshot {
fn buffer_anchor_to_anchor(&self, anchor: text::Anchor) -> Option<multi_buffer::Anchor>;
}
```
And in the other direction, given a `multi_buffer::Anchor`, we can look
at its `text::Anchor` to locate the excerpt that contains it. That means
we don't need an `ExcerptId` to create or resolve
`multi_buffer::Anchor`, and in fact we can delete `ExcerptId` entirely,
so that excerpts no longer have any identity outside their
`Range<text::Anchor>`.
There are a large number of changes to `editor` and other downstream
crates as a result of removing `ExcerptId` and multibuffer APIs that
assumed it.
### Other changes
There are some other improvements that are not immediate consequences of
that big change, but helped make it smoother. Notably:
- The `buffer_id` field of `text::Anchor` is no longer optional.
`text::Anchor::{MIN, MAX}` have been removed in favor of
`min_for_buffer`, etc.
- `multi_buffer::Anchor` is now a three-variant enum (inlined slightly):
```
enum Anchor {
Min,
Excerpt {
text_anchor: text::Anchor,
path_key_index: PathKeyIndex,
diff_base_anchor: Option<text::Anchor>,
},
Max,
}
```
That means it's no longer possible to unconditionally access the
`text_anchor` field, which is good because most of the places that were
doing that were buggy for min/max! Instead, we have a new API that
correctly resolves min/max to the start of the first excerpt or the end
of the last excerpt:
```
impl MultiBufferSnapshot {
fn anchor_to_buffer_anchor(&self, anchor: multi_buffer::Anchor) -> Option<text::Anchor>;
}
```
- `MultiBufferExcerpt` has been removed in favor of a new
`map_excerpt_ranges` API directly on `MultiBufferSnapshot`.
## 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:
- N/A
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Conrad <conrad@zed.dev>
|
||
|
|
408fc61439 |
git: Forbid main git worktree deletion from worktree picker (#52841)
This operation would always fail in the UI because the git binary already disallowed it. This PR just makes the UI more inline with what's actually valid 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: - git: Forbid main git worktree deletion from git worktree picker --------- Co-authored-by: Eric Holk <eric@zed.dev> |
||
|
|
a0ef595454 |
Remove text thread and slash command crates (#52757)
🫡 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: - Removed legacy Text Threads feature to help streamline the new agentic workflows in Zed. Thanks to all of you who were enthusiastic Text Thread users over the years ❤️! --------- Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de> |
||
|
|
eed7604164 |
acp: Notify when we receive new versions from the registry (#52818)
Wires up the missing version notifications for registry + extension agents. The UI part of this is already setup, we were just never triggering it. 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: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
d0e956b435 |
git_ui: Fix branch picker deleting remote instead of remote branch (#48338)
Closes #48256 It appears that the current git remotes support was implemented in #42819, following the design described in https://github.com/zed-industries/zed/pull/42486#issuecomment-3524092306. That design does not include an interaction for deleting remotes, but the delete remote branch action was mistakenly implemented as deleting the remote itself. After this PR, there should be no code paths that use `remove_remote` anymore. I've kept it for now though, as it may be useful when we introduce the corresponding interaction in the future. Release Notes: - Fixed a bug where deleting a remote branch from the branch picker would incorrectly remove the entire remote configuration |
||
|
|
c7fadb72ef |
editor: Fix jumbled auto-imports when completing with multiple cursors (#50320)
When accepting an autocomplete suggestion with multiple active cursors using `CMD+D`, Zed applies the primary completion edit to all cursors. However, the overlap check for LSP `additionalTextEdits` only verifies the replace range of the newest cursor. If user has a cursor inside an existing import statement at the top of the file and another cursor further down, Zed fails to detect the overlap at the top of the file. When the user auto-completes the import statement ends up jumbled. This fix updates the completion logic to calculate the commit ranges for all active cursors and passes them to the LSP store. The overlap check now iterates over all commit ranges to ensure auto-imports are correctly discarded if they intersect with any of the user's multi-cursor edits. Closes https://github.com/zed-industries/zed/issues/50314 ### Before https://github.com/user-attachments/assets/8d0f71ec-37ab-4714-a318-897d9ee5e56b ### After https://github.com/user-attachments/assets/4c978167-3065-48c0-bc3c-547a2dd22ac3 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 - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - Fixed an issue where accepting an autocomplete suggestion with multiple cursors could result in duplicated or jumbled text in import statements. |
||
|
|
41835e38bd |
Implement sidebar rendering of the configured worktrees (#51342)
Implements worktree support for the agent panel sidebar 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 - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - N/A |
||
|
|
a2eb59914c |
agent: Re-use ACP connections per project (#51209)
Release Notes: - N/A --------- Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> |
||
|
|
1f80405d0b |
git: Add SSH support for removing and renaming git worktrees (#50759)
This should be the last step in implementing full git worktree support in the `GitStore`. We still need to add UI for that allows a user to rename a git worktree and, by extension git branches if we use the git picker to do so. Also, I added a helper function called `disallow_guest_request::<T>` to the `Collab::rpc` that is used to specify a proto request isn't allowed to be sent by a guest. This enabled me to add a regression test that checks that a guest isn't allowed to delete a git worktree, without the test hanging forever because it's waiting for the proto server to respond. Since SSH connections send the proto message directly from client to remote host, this won't affect those requests. Before you mark this PR as ready for review, make sure that you have: - [x] Added solid test coverage and/or screenshots from doing manual testing - [x] 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: - git: Add SSH support for removing git worktrees |
||
|
|
4d70e3b436 |
Remove unreferenced dev dependencies (#51093)
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 |
||
|
|
dee5cc0000 |
git: Move diff num stat calculation to repository snapshot layer (#50645)
Follow up on: https://github.com/zed-industries/zed/pull/49519 This PR reworks how Zed calculates diff num stats by moving the calculation to the `RepositorySnapshot` layer, instead of the `GitPanel`. This has a couple of benefits: 1. Snapshot recalculations are already set up to recompute on file system changes and only update the affected files. This means that diff stats don't need to manage their own subscription or states anymore like they did in the original PR. 2. We're able to further separate the data layer from the UI. Before, the git panel owned all the subscriptions and tasks that refreshed the diff stat, now the repository does, which is more inline with the code base. 3. Integration tests are cleaner because `FakeRepository` can handle all the data and calculations of diff stat and make it accessible to more tests in the codebase. Because a lot of tests wouldn't initialize the git panel when they used the git repository. 4. This made implementing remote/collab support for this feature streamline. Remote clients wouldn't get the same buffer events as local clients, so they wouldn't know that the diff stat state has been updated and invalidate their data. 5. File system changes that happened outside of Zed now trigger the diff stat refresh because we're using the `RepositorySnapshot`. I added some integration tests as well to make sure collab support is working this time. Finally, adding the initial diff calculation to `compute_snapshot` didn't affect performance for me when checking against chromium's diff with HEAD~1000. So this should be a safe change to make. I decided to add diff stats on the status entry struct because it made updating changed paths and the collab database much simpler than having two separate SumTrees. Also whenever the UI got a file's status it would check its diff stat as well, so this change makes that code more streamlined as well. 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 |
||
|
+30 |
3a7db9852c |
Add "Start Thread in New Worktree" (#49141)
Add the thread target selector in the agent panel behind the `agent-git-worktrees` flag: <img width="590" height="121" alt="Screenshot 2026-03-02 at 11 50 47 PM" src="https://github.com/user-attachments/assets/17ee3303-7e01-4e40-bb84-1e7e748a3196" /> - Add a "Start Thread In..." dropdown to the agent panel toolbar, gated behind `AgentV2FeatureFlag` - Options: "Local Project" (default) and "New Worktree" - The "New Worktree" option is disabled when there's no git repository or in collab mode Closes AI-34 Release Notes: - N/A --------- Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com> Co-authored-by: Oleksiy Syvokon <oleksiy@zed.dev> Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com> Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Co-authored-by: Remco Smits <djsmits12@gmail.com> Co-authored-by: morgankrey <morgan@zed.dev> Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Co-authored-by: Ben Kunkle <ben@zed.dev> Co-authored-by: Finn Evers <finn@zed.dev> Co-authored-by: Bennet Bo Fenner <bennet@zed.dev> Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com> Co-authored-by: MostlyK <135974627+MostlyKIGuess@users.noreply.github.com> Co-authored-by: cameron <cameron.studdstreet@gmail.com> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com> Co-authored-by: John Tur <john-tur@outlook.com> Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com> Co-authored-by: Wuji Chen <chenwuji2000@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Kasper Nyhus <kanyhus@gmail.com> Co-authored-by: dino <dinojoaocosta@gmail.com> Co-authored-by: Anthony Eid <hello@anthonyeid.me> Co-authored-by: Josh Robson Chase <josh@robsonchase.com> Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com> Co-authored-by: ozacod <ozacod@users.noreply.github.com> Co-authored-by: Xiaobo Liu <cppcoffee@gmail.com> Co-authored-by: Lena <241371603+zelenenka@users.noreply.github.com> Co-authored-by: 0x2CA <2478557459@qq.com> Co-authored-by: Joseph T. Lyons <JosephTLyons@gmail.com> Co-authored-by: Albab Hasan <155961300+Albab-Hasan@users.noreply.github.com> Co-authored-by: KyleBarton <kjb@initialcapacity.io> Co-authored-by: Kunall Banerjee <hey@kimchiii.space> Co-authored-by: Lukas Wirth <lukas@zed.dev> Co-authored-by: Tom Houlé <13155277+tomhoule@users.noreply.github.com> Co-authored-by: Nikhil Pandey <nikhil@nikhil.com.np> Co-authored-by: Mikayla Maki <mikayla@zed.dev> Co-authored-by: dancer <144584931+dancer@users.noreply.github.com> Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |