This hang was caused by emitting the Git Graph Count Updated event for
every commit being added to the graph instead of every batch of commits.
This would cause gpui to have a massive amount of events to handle on
the foreground thread, even if most of them had very little work
involved.
For example, Zed graph has over 80k commits, that means we were emitting
80k plus events instead of 80.
- [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 ...
This PR changes `agent.play_sound_when_agent_done` from a boolean to an
enum with three options:
- `never` (default)
- `when_hidden`
- `always`
In Settings → Agent, this now appears as a _Play Sound When Agent Done_
dropdown.
Existing settings are migrated automatically:
- `false` → `never`
- `true` → `always`
### Why
A boolean only allowed the sound to be on or off. This change gives
users clearer control over when the agent notification sound should
play.
### Verification
- Added a migrator test for this setting change.
- Manually tested the settings UI, settings migration and the feature
Release Notes:
- Added new agent notification sound options
---------
Co-authored-by: Oleksiy Syvokon <oleksiy.syvokon@gmail.com>
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:
- N/A or Added/Fixed/Improved ...
## Summary
- break tooltip back-references from stored callbacks and tasks with
weak handles
- keep the tooltip controller as the sole strong owner of tooltip
lifecycle state
- add a regression test that exercises the visible-tooltip ownership
graph directly
## Testing
- cargo test -p gpui tooltip_is_released_when_its_owner_disappears --lib
Closes AI-120
Release Notes:
- Fixed a tooltip memory leak.
Closes#29757Closes#49387
This PR upgrades ESLint language server from `vscode-eslint 2.4.4` to
upstream `microsoft/vscode-eslint 3.0.24`, and make the workspace
configuration version-aware so ESLint 8, 9, and 10 take the correct
config-mode path.
The key part is that the 3.x bump alone is not enough. This PR keeps Zed
out of that path except where it is still actually needed. Rest
heavy-lifting is done by eslint server itself.
Zed now only overrides ESLint settings in the two known broken cases:
- ESLint 8.21-8.56 flat config: send `experimental.useFlatConfig = true`
- ESLint 9 legacy config: send `useFlatConfig = false`
All other cases defer to `vscode-eslint 3.x`'s own config and
working-directory discovery.
For testing, I created https://github.com/smitbarmase/eslint-repros,
which contains a versioned ESLint repros covering root flat config,
legacy config, and package-local monorepo cases across ESLint 8, 9, and
10. Here is compare between `zed/main`, a pure `vscode-eslint 3.x`
upgrade and this branch with the config-mode fixes:
## zed main
```text
eslint-v8_21-flat-root-single
eslint-v8_56-flat-package-local-monorepo -> breaks on main
eslint-v8_56-flat-root-single
eslint-v8_56-legacy-root-single
eslint-v8_57-flat-package-local-monorepo -> breaks on main
eslint-v8_57-flat-root-single
eslint-v8_57-legacy-root-single
eslint-v9_0-flat-package-local-monorepo
eslint-v9_0-flat-root-single
eslint-v9_0-legacy-root-single -> breaks on main
eslint-v10_0-flat-package-local-monorepo
eslint-v10_0-flat-root-single -> breaks on main
```
## vscode-eslint 3.x upgrade
```text
eslint-v8_21-flat-root-single
eslint-v8_56-flat-package-local-monorepo -> breaks on 3.x upgrade
eslint-v8_56-flat-root-single
eslint-v8_56-legacy-root-single
eslint-v8_57-flat-package-local-monorepo
eslint-v8_57-flat-root-single
eslint-v8_57-legacy-root-single
eslint-v9_0-flat-package-local-monorepo
eslint-v9_0-flat-root-single
eslint-v9_0-legacy-root-single -> breaks on 3.x upgrade
eslint-v10_0-flat-package-local-monorepo
eslint-v10_0-flat-root-single -> breaks on 3.x upgrade
```
## vscode-eslint 3.x upgrade + use flat config fixes
```text
eslint-v8_21-flat-root-single
eslint-v8_56-flat-package-local-monorepo
eslint-v8_56-flat-root-single
eslint-v8_56-legacy-root-single
eslint-v8_57-flat-package-local-monorepo
eslint-v8_57-flat-root-single
eslint-v8_57-legacy-root-single
eslint-v9_0-flat-package-local-monorepo
eslint-v9_0-flat-root-single
eslint-v9_0-legacy-root-single
eslint-v10_0-flat-package-local-monorepo
eslint-v10_0-flat-root-single
```
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 ESLint not reporting diagnostics in some cases for projects that
use flat-config, legacy-config, and monorepo projects across ESLint 8,
9, and 10.
A couple of things that this PR wants to accomplish:
* remove dependency on `settings` crate from `language_model`
* refactor provider-specific code into submodules - to be honest, I
would go one step further and put all provider-specific bits in
`language_models` instead but I realise we have cloud logic in
`language_model` which uses those too making it tricky
* move anthropic-specific telemetry into `language_models` crate - I
think it makes more sense for it to be there
Anyhow, I would very appreciate if you could have a look @mikayla-maki
and @maxdeviant and lemme know what you think, if you would tweak
something, etc.
Release Notes:
- N/A
## 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
Clicking on a sticky header causes
`selections.select_ranges([anchor..anchor])` to be called, but this does
not clear the editor's `selections.select_mode()`, resulting in possible
incorrect selections if this is followed up by a shift-click. This PR
fixes that with
```diff
- selections.select_ranges([anchor..anchor]);
+ selections.clear_disjoint();
+ selections.set_pending_anchor_range(anchor..anchor, SelectMode::Character);
```
which is essentially what `editor.select(SelectPhase::Begin { ... },
...)` (i.e. a regular single click in the editor) does as well.
Before:
https://github.com/user-attachments/assets/bcf2647e-a22a-4866-8975-d29e135df148
After:
https://github.com/user-attachments/assets/fb82db51-fef1-4b7c-9954-6e076ae0b176
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 bug that caused clicking on a sticky header to not always
properly clear the previous selection.
This PR improves adding selection as context particularly for terminals,
making them not depend on open buffers. It also now works adding
selection from a terminal that's no in the panel but as a tab.
Also, I'm removing a behavior introduced in
https://github.com/zed-industries/zed/pull/48045 that turned out to be
confusing, where the selection keybinding would add as context the
content of the current line I'm focused on. I think we shouldn't do this
given that a lot of times, particularly when adding a selection from a
terminal, I'd also end up adding content from a buffer just because my
cursor was previously in there, even without anything selected on it.
Saw myself multiple times deleting the unwanted buffer context crease in
this case. If the keybinding is about _selection_, we should only
trigger it when there's something selected.ing not do anything if there
isn't any selection.
Release Notes:
- Agent: Improved adding selection as context particularly for
terminals, making them not depend on open buffers.
Follow-up to https://github.com/zed-industries/zed/pull/52608
This PR adds a new iteration to the thinking block display design after
some internal round of feedback. It turns out, we had some people
appreciating the auto-collapse when thinking is done; thinking content
isn't too useful afterwards and it is just more content _to to he
model_, not the user. I also liked the one old but it definitely has the
issue of being a jarring layout shift when it wraps up. So that's why
I'm keeping what I introduced in the PR linked above as a setting, so
that anyone who feels strongly about the default (auto-expand, and
auto-collapse) can change that.
Release Notes:
- N/A
Since this was just removing unused keys, but behavior isn't broken if
they are there. So we can just leave them as-is
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: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: MrSubidubi <dev@bahn.sh>
Persist the last used agent globally as a fallback for new
workspaces, keep per-workspace selections independent. This should mean
"new thread" should grab whatever agent you are currently looking at,
and won't leak across projects.
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:
- agent: Prefer the currently used agent per-project when creating a new
thread.
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: MrSubidubi <dev@bahn.sh>
Changed the migration codepath, so that threads with no project are also
migrated to the archive.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Closes
https://github.com/zed-industries/zed/issues/19709#issuecomment-3494789304
Closes
https://github.com/zed-industries/zed/issues/24194#issuecomment-2835787560
This PR fixes case where if eslint cached install is partial or stale,
Zed can try to launch a missing `eslintServer.js` and the server crashes
with `MODULE_NOT_FOUND`.
```
Error: Cannot find module '/Users/.../languages/eslint/vscode-eslint-2.4.4/vscode-eslint/server/out/eslintServer.js'
```
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 ESLint server startup failures caused by reusing an incomplete
or stale cached server install.
## Context
Previously, markdown images failed to load workspace-absolute paths.
This updates the image resolver to identify the active workspace root
directory. Paths which are workspace absolute are correctly resolved and
rendered. The added test covers a successful resolution.
This PR re-implements the fix that was originally proposed in my
previous PR, #52178.
## Fix
https://github.com/user-attachments/assets/d69644ea-06cc-4638-b4ee-ec9f3abbb1ed
## How to Review
Small PR - focus on two changes in the file
`crates/markdown_preview/src/markdown_preview_view.rs`:
- `fn render_markdown_element()` (lines ~583-590): added the logic to
determine the workspace_directory
- `fn resolve_preview_image()` (lines ~714-726): added
workspace_directory variable, and a verification to create the full path
when a path is workspace-absolute
One test was added, covering a successful resolution
(`resolves_workspace_absolute_preview_images`). This test was
implemented in the file
`crates/markdown_preview/src/markdown_preview_view.rs`.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] 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#46924
Release Notes:
- Added workspace-absolute path detection in markdown files
data_table: Replace column width builder API with `ColumnWidthConfig`
enum
This PR consolidates the data table width configuration API from three
separate builder methods (`.column_widths()`, `.resizable_columns()`,
`.width()`) into a single `.width_config(ColumnWidthConfig)` call. This
makes invalid state combinations unrepresentable and clarifies the two
distinct width management modes.
**What changed:**
- Introduces `ColumnWidthConfig` enum with two variants:
- `Static`: Fixed column widths, no resize handles
- `Redistributable`: Drag-to-resize columns that redistribute space
within a fixed table width
- Introduces `TableResizeBehavior` enum (`None`, `Resizable`,
`MinSize(f32)`) for per-column resize policy
- Renames `TableColumnWidths` → `RedistributableColumnsState` to better
reflect its purpose
- Extracts all width management logic into a new `width_management.rs`
module
- Updates all callers: `csv_preview`, `git_graph`, `keymap_editor`,
`edit_prediction_context_view`
```rust
pub enum ColumnWidthConfig {
/// Static column widths (no resize handles).
Static {
widths: StaticColumnWidths,
/// Controls widths of the whole table.
table_width: Option<DefiniteLength>,
},
/// Redistributable columns — dragging redistributes the fixed available space
/// among columns without changing the overall table width.
Redistributable {
entity: Entity<RedistributableColumnsState>,
table_width: Option<DefiniteLength>,
},
}
```
**Why:**
The old API allowed callers to combine methods incorrectly. The new
enum-based design enforces correct usage at compile time and provides a
clearer path for adding independently resizable columns in PR #3.
**Context:**
This is part 2 of a 3-PR series improving data table column width
handling:
1. [#51059](https://github.com/zed-industries/zed/pull/51059) - Extract
modules into separate files (mechanical change)
2. **This PR**: Introduce width config enum for redistributable column
widths (API rework)
3. Implement independently resizable column widths (new feature)
The series builds on previously merged infrastructure:
- [#46341](https://github.com/zed-industries/zed/pull/46341) - Data
table dynamic column support
- [#46190](https://github.com/zed-industries/zed/pull/46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([#48207](https://github.com/zed-industries/zed/pull/48207))
### Anthony's note
This PR also fixes the table dividers being a couple pixels off, and the
csv preview from having double line rendering for a single column in
some cases.
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
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
When vim mode is enabled, previously if Cmd-F (or platform equivalent)
was pressed, enter will go to the editor's first match, and then hitting
enter again goes to the next line rather than next match. This PR
changes it to make enter go to the next match, which matches the
convention in most other programs. The behavior when search is initiated
with / is left unchanged.
This is a reopen of #35157, rebased and fixed.
Closes#7692
Release Notes:
- In vim mode, when search is triggered by the non-vim mode shortcut
(cmd-f by default) enter will now behave as it does outside of vim mode.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Relates to #5303 and
https://github.com/zed-industries/zed/issues/40826#issuecomment-3684556858
although I haven't found anywhere an actual request for `gpui` itself to
support a system alert sound.
### What
Basically, this PR adds a function that triggers an OS-dependent alert
sound, commonly used by terminal applications for `\a` / `BEL`, and GUI
applications to indicate an action failed in some small way (e.g. no
search results found, unable to move cursor, button disabled).
Also updated the `input` example, which now plays the bell if the user
presses <kbd>backspace</kbd> with nothing behind the cursor to delete,
or <kbd>delete</kbd> with nothing in front of the cursor.
Test with `cargo run --example input --features gpui_platform/font-kit`.
### Why
If this is merged, I plan to take a second step:
- Add a new Zed setting (probably something like
`terminal.audible_bell`)
- If enabled, `printf '\a'`, `tput bel` etc. would call this new API to
play an audible sound
This isn't the super-shiny dream of #5303 but it would allow users to
more easily configure tasks to notify when done. Plus, any TUI/CLI apps
that expect this functionality will work. Also, I think many terminal
users expect something like this (WezTerm, iTerm, etc. almost all
support this).
### Notes
~I was only able to test on macOS and Windows, so if there are any Linux
users who could verify this works for X11 / Wayland that would be a huge
help! If not I can try~
Confirmed Wayland + X11 both working when I ran the example on a NixOS
desktop
Release Notes:
- N/A
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:
- Removed the (broken) Claude ACP upsell dialogue
This PR bumps Tree-sitter for this crash fix
https://github.com/tree-sitter/tree-sitter/pull/5475
Release Notes:
- Fixed a crash that could occasionally occur when parsing files using
certain language extensions
This PR changes the API for the `ListItem`'s `end_hover` slot so that
whatever is in there is always part of the flex stack, as opposed to an
absolutely-positioned element. Additionally, I'm also improving the API
for swapping content between the default state and the hovered state
(e.g., list items where by default we render X, but when you hover, we
show something else). Lastly, I'm adding buttons to some Git picker
items that were only previously available through modal footer buttons.
Release Notes:
- N/A
This fixes a bug where search would match all commits if there was an empty query instead of setting the query to None
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:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Remco Smits <djsmits12@gmail.com>
This PR reverts part of
https://github.com/zed-industries/zed/pull/50839, as it was causing bad
clipping in the agent panel
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
Splits the tests out of `multi_workspace.rs` into a dedicated
`multi_workspace_tests.rs` file for better organization.
Release Notes:
- N/A
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
- Adds a new icon for thread import
- Iterate on the design to access the import modal: it's now through a
button in the sidebar's footer, which only appears when the archive view
is toggled
- Fixed an issue where clicking on checkboxes within the import modal's
list items wouldn't do anything
Release Notes:
- N/A
Closes#41887
This is a stable subset of other efforts to make symlink flows more
intuitive like #46344
Release Notes:
- Fixed expanded symlinks not being searchable
When a single-file worktree's root file no longer exists, the background
scanner would previously enter an infinite retry loop attempting to
canonicalize the path. This caused continuous error logging and resource
waste.
This fix detects when a single-file worktree root cannot be
canonicalized (after attempting the file handle fallback) and emits a
new Deleted event, allowing the worktree to be properly closed.
This is most commonly encountered with temporary files, logs, and
similar files that are opened in Zed and then deleted externally, but
persist in the workspace database across sessions.
Closes#34864
## Test
**Logs** from manual testing:
```
2026-02-17T16:16:11+01:00 INFO [worktree] inserting parent git repo for this worktree: "tmp.md"
2026-02-17T16:16:17+01:00 ERROR [worktree] root path could not be canonicalized: canonicalizing "/Users/***/tmp/tmp.md": No such file or directory (os error 2)
2026-02-17T16:16:17+01:00 INFO [worktree] single-file worktree root "/Users/***/tmp/tmp.md" no longer exists, marking as deleted
2026-02-17T16:16:17+01:00 INFO [worktree] worktree root /Users/***/tmp/tmp.md no longer exists, closing worktree
```
Release Notes:
- Fixed an issue where Zed would enter an infinite retry loop when the
backing file for a single-file worktree was deleted
Closes https://github.com/zed-industries/zed/issues/50223
## Summary
When clicking **Change Keybinding** from the command palette on an
action whose namespace contains underscores (e.g.
`terminal_panel::Toggle`, `project_panel::ToggleFocus`), the keymap
editor showed **"No matches found for the provided query"**. Actions
without underscores (e.g. `zed::OpenLog`) worked fine.
I opened this issue for this
https://github.com/zed-industries/zed/issues/50223, but took the liberty
of sending a PR.
**Root cause:** `normalize_action_query` preserved underscores in the
query, but the search candidates are built with `humanize_action_name`
which converts underscores to spaces. The fuzzy matcher looked for `_`
in a candidate like `"terminal panel: toggle"` where it doesn't exist,
so matching always failed.
**Fix:** `normalize_action_query` now converts underscores to spaces
before the deduplication checks, consistent with `humanize_action_name`.
This also correctly collapses consecutive underscores with adjacent
spaces.
All three call sites of `normalize_action_query` (command palette
search, keymap editor filter, action completion provider) match against
humanized candidates, so the fix improves consistency across all of
them.
## Before (Left) / After (Right)
<img width="2560" height="1053" alt="Screenshot 2026-02-28 at 17 56 05"
src="https://github.com/user-attachments/assets/195530b6-57af-4270-9370-03744cb55e81"
/>
<img width="2557" height="1062" alt="Screenshot 2026-02-28 at 17 55 38"
src="https://github.com/user-attachments/assets/1e8637cd-86c9-496e-bc2b-f9f2d0ac23dc"
/>
Release Notes:
- Fixed keymap editor showing no results when opening "Change
Keybinding" from the command palette for actions with underscores in
their namespace (e.g. `terminal_panel::Toggle`,
`project_panel::ToggleFocus`)
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>
When reopening an ACP agent thread (e.g. after restarting Zed) that has
no saved scroll position, the conversation now starts scrolled to the
bottom so the user sees the latest messages instead of starting at the
top.
Uses `set_follow_tail(true)` rather than a one-shot `scroll_to_end()` so
the scroll position is re-anchored on every layout pass — ensuring it
lands at the true bottom even when list items haven't been measured yet.
The follow-tail mode automatically disengages as soon as the user
scrolls up.
Release Notes:
- Fixed agent threads starting scrolled to the top when reopened after
restarting Zed.
Closes#52489
The special token check in `prompt_input_contains_special_tokens` used
`String::contains()` to look for `=======\n` in the buffer. This meant
any line containing `=======` (like `// =======` section separators)
would cause edit predictions to bail out entirely.
Fixed by only matching when the token appears at the start of a line,
since the git merge markers are always placed at line boundaries in the
prompt.
Added tests for both the helper function and a regression test for the
reported issue.
---------
Co-authored-by: Oleksiy Syvokon <oleksiy.syvokon@gmail.com>
```
thread 'main' (35618165) panicked at crates/gpui/src/app/entity_map.rs:164:32:
cannot read workspace::multi_workspace::MultiWorkspace while it is already being updated
stack backtrace:
0: __rustc::rust_begin_unwind
at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/std/src/panicking.rs:689:5
1: core::panicking::panic_fmt
at /rustc/e408947bfd200af42db322daf0fadfe7e26d3bd1/library/core/src/panicking.rs:80:14
2: gpui::app::entity_map::double_lease_panic::<workspace::multi_workspace::MultiWorkspace>
at ./crates/gpui/src/app/entity_map.rs:208:5
3: <gpui::app::entity_map::EntityMap>::read::<workspace::multi_workspace::MultiWorkspace>::{closure#1}
at ./crates/gpui/src/app/entity_map.rs:164:32
4: <core::option::Option<&workspace::multi_workspace::MultiWorkspace>>::unwrap_or_else::<<gpui::app::entity_map::EntityMap>::read<workspace::multi_workspace::MultiWorkspace>::{closure#1}>
at /Users/bebo/.rustup/toolchains/1.94.1-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:1067:21
5: <gpui::app::entity_map::EntityMap>::read::<workspace::multi_workspace::MultiWorkspace>
at ./crates/gpui/src/app/entity_map.rs:164:14
6: <gpui::app::entity_map::Entity<workspace::multi_workspace::MultiWorkspace>>::read
at ./crates/gpui/src/app/entity_map.rs:465:21
7: <sidebar::Sidebar>::show_archive::{closure#0}
at ./crates/sidebar/src/sidebar.rs:3462:15
8: <core::option::Option<gpui::app::entity_map::Entity<workspace::multi_workspace::MultiWorkspace>>>::and_then::<gpui::app::entity_map::Entity<workspace::Workspace>, <sidebar::Sidebar>::show_archive::{closure#0}>
at /Users/bebo/.rustup/toolchains/1.94.1-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:1546:24
9: <sidebar::Sidebar>::show_archive
at ./crates/sidebar/src/sidebar.rs:3461:69
10: <sidebar::Sidebar as workspace::multi_workspace::Sidebar>::restore_serialized_state
at ./crates/sidebar/src/sidebar.rs:3606:22
11: <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state::{closure#0}
at ./crates/workspace/src/multi_workspace.rs:216:18
12: <gpui::app::App as gpui::AppContext>::update_entity::<sidebar::Sidebar, (), <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state::{closure#0}>::{closure#0}
at ./crates/gpui/src/app.rs:2397:26
13: <gpui::app::App>::update::<(), <gpui::app::App as gpui::AppContext>::update_entity<sidebar::Sidebar, (), <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state::{closure#0}>::{closure#0}>
at ./crates/gpui/src/app.rs:886:22
14: <gpui::app::App as gpui::AppContext>::update_entity::<sidebar::Sidebar, (), <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state::{closure#0}>
at ./crates/gpui/src/app.rs:2395:14
15: <gpui::app::entity_map::Entity<sidebar::Sidebar>>::update::<(), gpui::app::App, <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state::{closure#0}>
at ./crates/gpui/src/app/entity_map.rs:481:12
16: <gpui::app::entity_map::Entity<sidebar::Sidebar> as workspace::multi_workspace::SidebarHandle>::restore_serialized_state
at ./crates/workspace/src/multi_workspace.rs:215:14
17: workspace::restore_multiworkspace::{closure#0}::{closure#7}
at ./crates/workspace/src/workspace.rs:8712:29
18: <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update::<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}::{closure#1}
at ./crates/gpui/src/window.rs:5318:43
19: <gpui::app::App as gpui::AppContext>::update_entity::<workspace::multi_workspace::MultiWorkspace, (), <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}::{closure#1}>::{closure#0}
at ./crates/gpui/src/app.rs:2397:26
20: <gpui::app::App>::update::<(), <gpui::app::App as gpui::AppContext>::update_entity<workspace::multi_workspace::MultiWorkspace, (), <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}::{closure#1}>::{closure#0}>
at ./crates/gpui/src/app.rs:886:22
21: <gpui::app::App as gpui::AppContext>::update_entity::<workspace::multi_workspace::MultiWorkspace, (), <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}::{closure#1}>
at ./crates/gpui/src/app.rs:2395:14
22: <gpui::app::entity_map::Entity<workspace::multi_workspace::MultiWorkspace>>::update::<(), gpui::app::App, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}::{closure#1}>
at ./crates/gpui/src/app/entity_map.rs:481:12
23: <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update::<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}
at ./crates/gpui/src/window.rs:5318:21
24: <gpui::app::App>::update_window_id::<core::result::Result<(), anyhow::Error>, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}>::{closure#0}
at ./crates/gpui/src/app.rs:1561:26
25: <gpui::app::App>::update::<core::option::Option<core::result::Result<(), anyhow::Error>>, <gpui::app::App>::update_window_id<core::result::Result<(), anyhow::Error>, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}>::{closure#0}>
at ./crates/gpui/src/app.rs:886:22
26: <gpui::app::App>::update_window_id::<core::result::Result<(), anyhow::Error>, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}>
at ./crates/gpui/src/app.rs:1555:14
27: <gpui::app::App as gpui::AppContext>::update_window::<core::result::Result<(), anyhow::Error>, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}>
at ./crates/gpui/src/app.rs:2425:14
28: <gpui::app::async_context::AsyncApp as gpui::AppContext>::update_window::<core::result::Result<(), anyhow::Error>, <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>::{closure#0}>
at ./crates/gpui/src/app/async_context.rs:94:14
29: <gpui:🪟:WindowHandle<workspace::multi_workspace::MultiWorkspace>>::update::<gpui::app::async_context::AsyncApp, (), workspace::restore_multiworkspace::{closure#0}::{closure#7}>
at ./crates/gpui/src/window.rs:5313:12
30: workspace::restore_multiworkspace::{closure#0}
at ./crates/workspace/src/workspace.rs:8710:14
31: zed::restore_or_create_workspace::{closure#0}
at ./crates/zed/src/main.rs:1358:82
32: zed::main::{closure#10}::{closure#16}::{closure#0}::<i32>
at ./crates/zed/src/main.rs:877:84
33: <gpui::app::App>::spawn::<zed::main::{closure#10}::{closure#16}, ()>::{closure#0}
at ./crates/gpui/src/app.rs:1633:44
34: <core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()>>> as core::future::future::Future>::poll
at /Users/bebo/.rustup/toolchains/1.94.1-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:133:9
35: <core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()>>> as core::future::future::Future>::poll
at /Users/bebo/.rustup/toolchains/1.94.1-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:133:9
36: <scheduler::executor::spawn_local_with_source_location::Checked<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()>>>> as core::future::future::Future>::poll
at ./crates/scheduler/src/executor.rs:361:64
37: <async_task::raw::RawTask<scheduler::executor::spawn_local_with_source_location::Checked<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()>>>>, (), <scheduler::executor::ForegroundExecutor>::spawn<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future<Output = ()>>>>::{closure#0}, scheduler::RunnableMeta>>::run
at /Users/bebo/.cargo/git/checkouts/async-task-e468f817236eac43/b4486cd/src/raw.rs:296:17
38: <async_task::runnable::Runnable<scheduler::RunnableMeta>>::run
at /Users/bebo/.cargo/git/checkouts/async-task-e468f817236eac43/b4486cd/src/runnable.rs:788:18
39: gpui_macos::dispatcher::trampoline
at ./crates/gpui_macos/src/dispatcher.rs:197:14
40: <unknown>
41: <unknown>
42: <unknown>
43: <unknown>
44: <unknown>
45: <unknown>
46: <unknown>
47: <unknown>
48: <unknown>
49: <unknown>
50: <unknown>
51: <unknown>
52: <unknown>
53: <() as objc::message::MessageArguments>::invoke::<()>
at /Users/bebo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/objc-0.2.7/src/message/mod.rs:128:17
54: objc::message::platform::send_unverified::<objc::runtime::Object, (), ()>
at /Users/bebo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/objc-0.2.7/src/message/apple/mod.rs:27:9
55: objc::message::send_message::<objc::runtime::Object, (), ()>
at /Users/bebo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/objc-0.2.7/src/message/mod.rs:178:5
56: <*mut objc::runtime::Object as cocoa::appkit::NSApplication>::run
at /Users/bebo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cocoa-0.26.0/src/appkit.rs:628:9
57: <gpui_macos::platform::MacPlatform as gpui::platform::Platform>::run
at ./crates/gpui_macos/src/platform.rs:488:17
58: <gpui::app::Application>::run::<zed::main::{closure#10}>
at ./crates/gpui/src/app.rs:187:18
59: zed::main
at ./crates/zed/src/main.rs:456:9
60: <fn() as core::ops::function::FnOnce<()>>::call_once
at /Users/bebo/.rustup/toolchains/1.94.1-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace
```
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
This should prevent the "wgpu-hal invariant was violated (usage error):
Requested feature is not available on this device" panic, although I'm
not 100% sure (there's a possibility that a device reports the feature
but fails to use it). At the very least, we get more logging
I've tested this fix by patching code to emulate a situation where
device features change after the creation, but that may be not
representative of the real world failure.
Addresses ZED-5G1
Release Notes:
- N/A
For submodules, `common_dir_abs_path` equals `repository_dir_abs_path`
(since submodules don't have a `commondir` file). The previous code
passed this path to `original_repo_path_from_common_dir`
unconditionally, which returned the `.git/modules/<name>` path as the
`original_repo_abs_path` — causing `linked_worktree_path()` to return a
false positive for submodules.
Now we detect linked worktrees by checking whether `common_dir` differs
from `repository_dir` (only true for actual linked worktrees that have a
`commondir` file). For normal repos and submodules,
`original_repo_abs_path` is simply `work_directory_abs_path`.
Also fixes the misleading doc comment on `common_dir_abs_path` in
`LocalRepositoryEntry` and adds test assertions for
`original_repo_abs_path` and `linked_worktree_path()` on both worktrees
and submodules.
Closes AI-102
Release Notes:
- Fixed git submodules being incorrectly classified as linked worktrees,
which could cause issues with worktree-related operations.
🫡
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>
- Adjust thread item and gradient fade colors for themes that define
transparent colors for the tokens we use on them
- Make the entire project header clickable area activate the workspace
instead of collapsing the group. The chevron is now an icon button that
does that, which makes it consistent with the collab panel and settings
UI.
Release Notes:
- N/A
All local agent server types were calling `local_directory_environment`
with `paths::home_dir()`, causing direnv and shell environment to be
loaded from `~` rather than the project's worktree directory. This meant
project-specific `.envrc` variables (e.g. Google Vertex credentials)
were never picked up by external agents like Claude.
Added `default_environment()` on `ProjectEnvironment` that resolves the
default visible worktree path and uses it for environment loading,
falling back to home_dir() only when no worktree is available.
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:
- Fixed default environment variable context for external agents
The `CONTEXT_1M_BETA_HEADER` (`context-1m-2025-08-07`) is deprecated for
Sonnet 4 and 4.5. This removes the constant from the anthropic crate and
the match arm in `beta_headers()` that sent it for
`ClaudeSonnet4_5_1mContext`.
Note: The bedrock crate still has its own copy of this constant, used
when the user-configurable `allow_extended_context` setting is enabled.
That may warrant a separate cleanup.
Closes AI-114
Release Notes:
- N/A
- update flake.lock with the 1.94.1
- Fixes nix build not working.
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
Extract `SyntaxTheme` into its own lightweight crate so that downstream
consumers can use syntax highlighting colors without pulling in the full
`theme` crate and its transitive dependencies.
## Changes
**Commit 1 — Extract SyntaxTheme into its own crate**
Move `SyntaxTheme`, `SyntaxThemeSettings`, `HighlightStyle`, and
supporting types from `theme/src/styles/syntax.rs` into a new
`syntax_theme` crate that depends only on `gpui`. The `theme` crate
re-exports everything for backward compatibility — no call-site changes
needed.
**Commit 2 — Add `bundled-themes` feature with One Dark**
Add an optional `bundled-themes` feature that bundles `one_dark()`, a
`SyntaxTheme` loaded from the existing One Dark JSON theme file. This
lets consumers get a usable syntax theme without depending on the full
theme machinery.
Release Notes:
- N/A
Propagate work directory changes through `ConversationView` instead
of only updating active and generating root threads.
This makes sure that all subagents are in sync, as well as any currently
"active" threads in the agent panel.
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: Bennet Bo Fenner <bennetbo@gmx.de>
## Summary
- Add `unconfigure_surface()` and `replace_surface()` methods to
`WgpuRenderer` for mobile platform window lifecycle management
- Prefer `PresentMode::Mailbox` (triple-buffering) over `Fifo` to avoid
blocking during lifecycle transitions
- Early return in `draw()` when surface is unconfigured to prevent
driver hangs
## Motivation
On Android, the native window (`ANativeWindow`) is destroyed when the
app goes to the background and recreated when it returns to the
foreground. The same happens during orientation changes. Without surface
lifecycle methods, the only option is to destroy the entire
`WgpuRenderer` and create a new one on resume.
The problem: GPUI's scene cache holds `AtlasTextureId` references from
the old renderer's atlas. A new renderer has an empty atlas, so those
cached IDs cause index-out-of-bounds panics.
The fix: Keep the renderer (device, queue, atlas, pipelines) alive
across surface destruction. Only the wgpu `Surface` needs to be
replaced.
### `unconfigure_surface()`
Marks the surface as unconfigured so `draw()` skips rendering via the
existing `surface_configured` guard. Drops intermediate textures that
reference the old surface dimensions. The renderer stays fully alive.
### `replace_surface()`
Creates a new `wgpu::Surface` from fresh window handles using the
**same** `wgpu::Instance` that created the original adapter/device.
Reconfigures the surface and marks it as configured so rendering
resumes. All cached atlas textures remain valid.
### PresentMode::Mailbox
`Fifo` (VSync) blocks in `get_current_texture()` and can deadlock if the
compositor is frozen during a lifecycle transition (e.g.
`TerminateWindow` → `InitWindow` on Android). Mailbox (triple-buffering)
avoids this. Falls back to `AutoNoVsync` → `Fifo` if unsupported.
### draw() early return
Some drivers (notably Adreno) block indefinitely when acquiring a
texture from an unconfigured surface. The early return prevents this.
## Context
This is needed by
[gpui-mobile](https://github.com/itsbalamurali/gpui-mobile), a project
bringing GPUI to Android and iOS. The Android implementation needs these
methods to handle:
1. **Background/foreground transitions** — `TerminateWindow` destroys
the native window, `InitWindow` recreates it
2. **Orientation changes** — Surface is destroyed and recreated with new
dimensions
3. **Split-screen transitions** — Similar surface recreation
Without this change, we maintain a local fork of `gpui_wgpu` with just
these additions. Upstreaming them would let mobile platform
implementations use the official crate directly.
## Test plan
- [x] Tested on Android (Motorola, Adreno 720 GPU) — 3 consecutive
background/foreground cycles, zero panics, atlas textures preserved
- [x] Tested orientation changes (portrait→landscape→portrait) — surface
replacement completed in <40ms per rotation
- [x] Verified `draw()` correctly skips rendering when surface is
unconfigured
- [x] Verified no regression on desktop — methods are additive, existing
code paths unchanged
- [x] PresentMode fallback chain works on devices that don't support
Mailbox
## Release Notes
- N/A