Commit Graph
37363 Commits
Author SHA1 Message Date
Bing WangandBen Kunkle 930c6f08b6 terminal: Reduce flicker on resize (#47195)
Skip PTY resizes for pixel-only changes and coalesce pending resize
events.
Snap standalone terminal layout to whole device pixels to avoid subpixel
jitter.

before:


https://github.com/user-attachments/assets/0ad0db83-0099-44c8-b8d1-3dc8146b25ef


after:


https://github.com/user-attachments/assets/86278014-1c87-4263-a9e5-b58bcc1fa2ea




Release Notes:

- Fixed: Reduce terminal flicker on resize

---------

Signed-off-by: pigletfly <wangbing.adam@gmail.com>
Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-04-27 07:13:44 +00:00
Finn Eitreim 53e1473bea editor: Make editor: expand excerpts actually expand all excerpts (#54717)
Expand all excerpts had a doc comment describing it as expanding all
excerpts, but in practice it only expanded the excerpt that was the most
relevant.

I fixed that to make it expand all excerpts. 

video:


https://github.com/user-attachments/assets/9858ebda-199c-4f72-8a2f-3cd606b0eff4

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

Release Notes:

- editor: `expand excerpts` now has correct documentation explaining its
function.
2026-04-27 06:58:07 +00:00
Kirill Bulatov 04c4b2b6cd Fix code lens id clash (#54851)
Follow-up to https://github.com/zed-industries/zed/pull/54100

Instead of relying on "line number" that could have overlapped depending
on the range we query, use hierarchical IDset: `block id -> lens #` to
ensure no clashes happen anymore.

Release Notes:

- N/A
2026-04-25 11:23:45 +00:00
Kirill Bulatov 88ed80c13e Fix offline lookup of clangd on Windows (#54781)
Closes https://github.com/zed-industries/zed/issues/54042
Part of https://github.com/zed-industries/zed/issues/9789

This binary was not found when Zed first downloads the release, and then
rerun offline on the same project.

Using a `clangd-windows-21.1.0.zip ` archive from
https://github.com/clangd/clangd/releases/tag/21.1.0

```
~/Downloads ❯ unzip -l clangd-windows-21.1.0.zip|rg clangd.exe
 46908928  08-27-2025 01:40   clangd_21.1.0/bin/clangd.exe
```

Similarly, delve releases are in
https://github.com/go-delve/delve/releases and codelldb are in
https://github.com/vadimcn/codelldb/releases

```
~/Downloads ❯ unzip -l codelldb-win32-x64.vsix|rg exe
  1014272  04-21-2026 03:05   extension/bin/codelldb-launch.exe
  4400128  04-21-2026 03:05   extension/adapter/codelldb.exe
   242176  04-14-2026 04:14   extension/lldb/bin/lldb.exe
  6272000  04-14-2026 04:14   extension/lldb/bin/lldb-server.exe
    96768  04-14-2026 01:42   extension/lldb/bin/lldb-argdumper.exe
    96768  04-14-2026 04:13   extension/lldb/lib/lldb-python/lldb/lldb-argdumper.exe
    35284  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/pygments/lexer.py
   101888  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/w64.exe
   168448  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/w64-arm.exe
    91648  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/w32.exe
   108032  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/t64.exe
   182784  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/t64-arm.exe
    97792  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/distlib/t32.exe
    12161  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/pygments/lexers/__init__.py
    74926  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py
    53448  04-14-2026 01:36   extension/lldb/lib/site-packages/pip/_vendor/pygments/lexers/python.py
```


Release Notes:

- Fixed offline lookup of clangd on Windows
2026-04-25 06:14:41 +00:00
Kirill Bulatov cecd991263 Fix whitespace rendering in Zed (#54798)
Closes https://github.com/zed-industries/zed/issues/49186

<img width="403" height="136" alt="first"
src="https://github.com/user-attachments/assets/dafaa681-b921-4411-a453-8857681e50f8"
/>

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

<img width="405" height="104" alt="second"
src="https://github.com/user-attachments/assets/17e3b5df-0d61-47f3-88ff-8aeeafae1425"
/>

Release Notes:

- Fixed whitespace rendering in Zed
2026-04-25 06:11:27 +00:00
Bennet Bo Fenner 83830be2b1 Revert terminal changes from #54728 (#54836)
Reverts parts of #54728, which seems to have causes scrolling issues in
the terminal

Release Notes:

- N/A
2026-04-24 22:16:20 +00:00
Bennet Bo Fenner 50d90feab4 open_ai: Add support for gpt-5.5 (#54820)
Release Notes:

- Added support for GPT 5.5 and GPT 5.5 Pro via the OpenAI provider
2026-04-24 20:26:56 +00:00
Max MalkinandKyleBarton 655f2f90e1 Fall back to empty workspace when devcontainer restore is cancelled (#54734)
Closes #47872

Release Notes:

- Fixed Zed exiting on startup when cancelling a failed devcontainer
connection. It now falls back to an empty workspace.

Co-authored-by: KyleBarton <kjb@initialcapacity.io>
2026-04-24 19:05:42 +00:00
Cole Miller d19f3684d2 Update AI rules to reflect that AsyncApp updates are now infallible (#54818)
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:

- N/A
2026-04-24 19:04:32 +00:00
Tom Houlé 7dcc45bbf7 agent_ui: Recognize image file extensions case insensitively (#54786)
Straightforward.

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

Release Notes:

- Fixed the file extension recognition logic for images in the agent UI
being case sensitive. It is now case insensitive.
2026-04-24 18:30:54 +00:00
2ab4a856a3 git: Improve handling of unsafe repositories (#43693)
These changes update Zed's Git Panel to be able to detect unsafe git
repositories, where the user running Zed doesn't own the `.git`
directory, and show a dedicated empty view in the Git Panel that not
only explains the situation but also allows the user to choose whether
to trust this directory, which will end up running `git config --global
--add safe.directory <path>`.

While testing those changes, it was noted that attempting to add or
reset files after trusting the directory would fail, as expected, but
the UI wouldn't react to the fact that those operations failed. What
this means is, if the user tried to add a file, the UI would show a
checkmark for that file and, after the operation failed, the checkmark
would remain. We now revert that, for both `git add` and `git reset`.

Some more technical notes on this change:

- Introduce `project::git_store::GitAccess` enum to express whether we
actually have access to the repository, exposed via
`git::Repository::access`, which probes the backend with a `git status`
command and classifies the result.
- On unsafe repositories,
`project::git_store::LocalRepositoryState::new` fails to spawn the git
worker, which now cleanly signals `GitAccess::No` rather than leaving
the panel in a broken state.
- Updated `git_ui::git_panel::GitPanel::render_empty_state` with a third
alternative, when `GitAccess::No`, that basically renders a view
explaining why the repository is considered unsafe, together with
buttons for git's documentation on safe directories and a button to add
the repository's folder as a safe directory
- Updated `project::git_store::GitStore` to now watch `~/.gitconfig` and
`$XDG_CONFIG_HOME/git/config`. Watching this files allows the Git Panel
to react when the git configuration is updated, which will be the case
if the user decides to trust the repository. When either changes, a
`GitStoreEvent::GlobalConfigurationUpdated` event is emitted and the
panel refetches repository state.
- Added `project::git_store::Repository::refetch_repo_state` field,
which stores a closure to allow recreating the
`Repository::repository_state` and the job sender after the repository's
directory is trusted, without requiring a project reload.
- Added a `fs::Fs::git_config` trait method, wrapping a real `git
config` invocation. In order to be able to call this, both
`git_store::GitStore::git_config` and `project::Project::git_config`
wrappers have also been introduced. Worth mentioning that this isn't yet
supported for remote projects or collab guests.
- Updated `fs::Fs::git_clone` argument order to match
`fs::Fs::git_config` and `fs::Fs::git_init`.
- Added a new
`project::git_store::pending_op::PendingOps::last_op_errored` method
that allows determining whether the last pending operation failed. This
now allows us to filter out failed operations when determining whether
`git add` or `git reset` failed, so that we can fall through to the real
git status.
- Updated `git_ui::git_panel::GitPanel::change_file_stage` to now call
`update_counts` in its error branch so the cached staged counters stay
consistent with the reverted per-entry state, seeing as we now handle
reverting the UI state if an operation fails.
- Fixed `fs::RealFs::git_init` to fall back to the provided branch name
when `git config --global --get init.defaultBranch` fails, for example,
when the user hsan't configured one.

Co-authored-by: cameron <cameron.studdstreet@gmail.com>

Closes #42286

Release Notes:

- Added a dedicated empty state in the Git Panel for unsafe
repositories, with a "Trust Directory" button that adds the repository
to `safe.directory`
- Fixed stage and unstage checkboxes in the Git Panel not reverting when
a `git add` or `git reset` command failed

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-04-24 17:14:24 +00:00
Bennet Bo Fenner b9839bea5d acp: Improve ACP debug view (#54769)
Adds a dropdown to the ACP logs which lets you specify which agent
connection to look at. Also adds a button to restart the connection.

<img width="710" height="1023" alt="image"
src="https://github.com/user-attachments/assets/12430175-3c1d-452f-bc45-d1ec0616b51b"
/>

Release Notes:

- N/A
2026-04-24 15:53:14 +00:00
Bennet Bo Fenner b0dabe79b4 agent_ui: Remove unused APIs (#54774)
Release Notes:

- N/A
2026-04-24 15:52:27 +00:00
Kirill Bulatov eae9741e2a Fix default.json profile and os settings not applying on startup (#54635)
When started working on "disable the profiler for all but Nightly and
Dev" users, I've tried to do that using the default OS settings and
discovered that those are ignored.

Release Notes:

- Fixed default.json profile and os settings not applying on startup
2026-04-24 15:05:52 +00:00
morgankrey 5fb1e6d1a4 docs: Document configuration boundaries for external agents (#54759)
## Summary

- Add a new "Configuration Boundaries" section to the external agents
documentation explaining what settings are shared between Zed and ACP
agents
- Clarify bidirectional configuration story: what Zed forwards to agents
AND what agents inherit from native installations
- Add troubleshooting section for common user confusion points
- Update MCP docs with clearer cross-links

## Context

Users are confused about which Zed settings apply to external ACP agents
like Claude and Codex. Common questions:
- "I configured MCP in Zed but Claude can't see it"
- "My Codex config.toml isn't being used"
- "Do profiles apply to external agents?"

## Key Points

**What Zed forwards to ACP agents:**
- Model/mode selection, env vars, MCP servers (with limitations),
CLAUDE.md

**What's NOT forwarded:**
- Profiles, tool permissions settings, `.rules` files

**What agents DON'T inherit from native installations:**
- `~/.claude/` config, `~/.codex/config.toml`, native MCP servers,
authentication state

## Test plan

- [x] Review for technical accuracy against codebase
- [x] Check brand voice compliance

Release Notes:

- N/A
2026-04-24 15:04:03 +00:00
Danilo Leal 331047c2e8 Fix when agent-powered merge conflict button shows up (#54791)
This PR fixes the logic to dismiss the "resolve merge conflict with
agent" button. Previously, we were just observing
`merge_heads_by_conflicted_path`, which seems to be intentionally
sticky, preserving the conflicted paths until changes are either
committed or aborted. This would make the button to resolve conflicts
show up even _after_ the changes get resolved. Now, we're checking
whether paths are _currently_ conflicted (`is_conflicted()`), and if
they are not, we don't display the button, even though the resolution
might have not been committed or aborted yet.

As a bonus, in this PR, I'm also putting the resolve conflict button
_before_ the activity indicator, so as to avoid bounciness, and did a
quick polish of the activity indicator button itself, by using the
`Button` component.

Release Notes:

- Fixed a bug with the merge conflict "resolve with agent" button where
it would be displayed even though all conflicts have already been
resolved.
2026-04-24 14:41:44 +00:00
Vlad IonescuandBen Brandt 8c77e669da opencode: Add support for OpenCode Go (#53651)
**TL;DR**: add support for OpenCode Go (flat-rate monthly subscription)
along the already-implemented OpenCode Zed (pay-as-you-go billing).

> [!WARNING]
> This code was written by LLMs, under the supervision of a so-called
developer that never wrote Rust profesionally and that spends more time
in Pages&Keynote than in an IDE.

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

## Background

OpenCode offers a few different ways to access models:
- **free access to 3 models**, with feedback and data used to improve
the model. These models use the OpenCode Zen API endpoints, but have
different usage limits (200 requests per 5 hours) and have a different
privacy policy. Some people disable or block the free models, some
people are super-excited to have access to LLMs for free, and some
people like using the free models to test new LLMs (at launch MiMo-V2
had 2 free weeks of usage, for example).
- **pay-as-you-go access to 30 models** as part of the [OpenCode
Zen](https://opencode.ai/zen) subscription. These models use the same
OpenCode Zen API endpoints.
- **flat-rate monthly access to 7 models** as part of the [OpenCode
Go](https://opencode.ai/go) subscription. These models use the OpenCode
Zen API endpoints with an extra `/go` appended to the path. There are
5-hour, weekly, and monthly usage limits and, additionally, users can
toggle a switch in the OpenCode Console to use Zen models with their
pay-as-you-go billing after the Go limits are hit.

There's also a currently-paused [OpenCode
Black](https://opencode.ai/black) flat-rate subscription with way higher
usage limits and with access to more models, with $100 and $200 monthly
plans.

The whole thing is a bit messy, but it's great value and highly reliable
LLM access!

<br>

https://github.com/zed-industries/zed/pull/49589 added support for
OpenCode Zen by implementing a new `opencode` provider. OpenCode Go
[could be used by overriding the API
URL](https://github.com/zed-industries/zed/pull/49589#issuecomment-4130300454),
but that is a terrible user experience: some models have to be manually
added, the model list always shows the 30-something OpenCode Zen models,
and free models cannot be used at all.

I was annoyed by the experience of using OpenCode Go with Zed and this
past week I had to test a bunch of LLMs and providers and harnesses, so
I took this on as a test case 🙂

## Implementation

This PR makes the OpenCode provider more general (not just for Zen) and
adds an `OpenCodeModelSubscription` concept which is then used to
implement support for OpenCode Go. The free models are also broken out
into their own subscription for a prettier model list.

For a better user experience, the different subscriptions can be enabled
or disabled, both in the settings file and in the UX:
<img width="434" height="176" alt="Screenshot showing the OpenCode
provider configuration, with the newly added toggles"
src="https://github.com/user-attachments/assets/3520e114-00c8-4794-84bf-35cd72d9c57e"
/>


The code was written by LLMs, but I do understand it and I did a bunch
of "manual" iterations and "manual" tweaks. Still, my Rust experience is
non-existent so **I won't feel offended if y'all reject this PR**! I did
consider alternatives (adding a new `opencode-go` provider and renaming
this to `opencode-zen`, for example, or adding support for custom API
URLs in OpenCode custom models which would've been the smallest code
change but a terrible user experience, and so on) but all alternatives
would have been, in my opinion, a worse user experience.

**Tests I did**:
- confirmed OpenCode Go models work as expected
- confirmed OpenCode Zen Free models work as expected
- confirmed I get an error when trying to use OpenCode Zen models since
I don't have that subscription
- confirmed the subcription toggles work as expected (model are
shown/hidden, settings file is updated)

**Notes**:
- this PR is best reviewed commit-by-commit. I did not create a separate
PR for the model updates to minimize delays
- my exeprience with Rust is roughly zero, but I tried to strike a
balance between idiomatic Rust and easy-to-read code
- users of the OpenCode provider might have to do some re-configuration
after this PR is merged since the model identifiers now include the
subscription, eg `claude-haiku-4-5` is now `zen/claude-haiku-4-5`. Since
this is a relatively new provider and the impact is small, I preffered
that rather than adding complex migration/mapping logic.
- does changing the provider name from "OpenCode Zen" to "OpenCode"
break anything for y'all at Zed?
- does changing the telemetry id from `"opencode/<model-id>"` to
`"opencode/<subscription>/<model-id>"` break anything for y'all at Zed?

---

Release Notes:
- OpenCode provider: add support for OpenCode Go

---------

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
2026-04-24 14:17:30 +00:00
Kunall Banerjee 2b81eb16d2 agent_ui: Allow selection of commands from tool calls (#50545)
Closes #50427.

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)

The changes respect your current theme + mimic the existing UI when it
comes to font size+weight.

<img width="437" height="131" alt="image"
src="https://github.com/user-attachments/assets/89f6c5d0-d1a3-478a-88e9-7d203240416d"
/>


https://github.com/user-attachments/assets/a5fb6c82-fffd-494f-a374-9296d1690736

Release Notes:

- Allow selection of commands from tool calls
2026-04-24 13:54:28 +00:00
iam-liamandLukas Wirth 3230938609 markdown: Make table cell checkboxes clickable (#54747)
Closes #53587

Follow-up to #50595.

[#50595](https://github.com/zed-industries/zed/pull/50595) added
display-only checkboxes when `[x]` / `[X]` / `[ ]` appears as the sole
content of a markdown table cell. That PR called out interactivity as a
later step — this PR delivers it.


https://github.com/user-attachments/assets/c666ee4c-7e31-4450-ab33-c07c82949818

## What this does

When a consumer of `MarkdownElement` supplies an `on_checkbox_toggle`
callback, table-cell checkboxes now invoke it on click with the source
range of the `[x]` / `[ ]` marker and the new checked state. This
mirrors the existing list-item checkbox path.

For markdown preview (`markdown_preview_view.rs`) the callback is
already wired to edit the source buffer, so clicking a checkbox in a
previewed `.md` file now flips `[x]` to `[ ]` and back in the file, the
same as it already did for list checkboxes.

## How it works

`replace_pending_checkbox` previously took the cell's outer source range
and always built a visualization-only checkbox. It now takes the
optional toggle callback instead, and reconstructs the marker's exact
source range from `pending_line.source_mappings` — pulldown-cmark emits
`[x]` in a table cell as three separate `Text` events, so the per-chunk
mappings are needed to recover the 3-character range to rewrite. If a
callback was supplied, the checkbox attaches an `on_click` that invokes
it with that range and `!checked`; otherwise it falls back to the prior
visualization-only rendering.

Two free helpers (`source_range_for_rendered` /
`source_index_for_rendered`) were extracted so the mapping logic is
unit-testable.

## Scope

One file: `crates/markdown/src/markdown.rs`. No changes to
`markdown_preview` — since #52008 it renders through the shared
`MarkdownElement`, so its existing `on_checkbox_toggle` wiring picks up
table checkboxes for free.

## Relation to #53587

[#53587](https://github.com/zed-industries/zed/issues/53587) reports
that markdown checkboxes in the **agent panel** can't be clicked. This
PR is a necessary piece of that fix — without it, even if the agent
panel wired `on_checkbox_toggle`, its table checkboxes would stay inert.
It does not fully close #53587 on its own: the agent panel's
`MarkdownElement` instances in `conversation_view.rs` / `thread_view.rs`
don't currently wire `on_checkbox_toggle`, and wiring it there requires
deciding how clicks should mutate the in-memory agent response (no
source file to edit into). That's a follow-up.

## Test plan

**Unit tests** (2 new, both in `crates/markdown/src/markdown.rs`):
- `test_table_checkbox_marker_source_range` — walks parser events for a
table with checkboxes, replays what the builder accumulates, and asserts
the reconstructed source range slices to exactly `[x]` / `[ ]` in the
original markdown (including a padded-whitespace case).
- `test_source_range_for_rendered_handles_split_chunks` — pins the
mapping helper against the three-chunk layout pulldown-cmark produces.

**Automated**:
- [x] `cargo test -p markdown` — 46 tests pass (44 existing + 2 new)
- [x] `cargo test -p markdown_preview` — 3 tests pass
- [x] `./script/clippy -p markdown` — clean

**Manual** (against a preview of a markdown file with checkbox tables):
- [x] Click a checked `[x]` table cell — it becomes `[ ]` in the source
and rerenders as unchecked
- [x] Click an unchecked `[ ]` — becomes `[x]`
- [x] Uppercase `[X]` toggles on click (replacement writes `[x]` / `[
]`, matching the list-item behaviour)
- [x] Padded-whitespace cells still target just the three marker
characters
- [x] Multiple checkbox columns in one table all independently clickable
- [x] Alignment variants (left/center/right) behave the same
- [x] Non-checkbox table text unaffected
- [x] List-item checkboxes continue to work (regression)

Release Notes:

- Made table-cell markdown checkboxes clickable in markdown preview,
matching list-item checkbox behavior

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-04-24 13:02:06 +00:00
Tim Vermeulen d018263a72 markdown: Make highlighting of rendered markdown more accurate (#54744)
Paints selections and search highlights of rendered markdown more
accurately, to properly match what's actually being selected.

Particularly noticeable when the selection spans multiple rows in a
table cell or when it starts right after a soft wrap.

|Before|After|
| --- | --- |
|<img width="831" height="677" alt="before"
src="https://github.com/user-attachments/assets/3b2c33be-e4cb-400f-9ba6-4163eb438f99"
/> | <img width="831" height="677" alt="after"
src="https://github.com/user-attachments/assets/04161dd8-7f4a-46c5-8c63-3497d3533f6d"
/> |


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 selection and search highlights in rendered markdown not always
being displayed accurately.
2026-04-24 12:51:52 +00:00
Danilo Leal d41ea8ed16 ui: Improve submenu rendering when there's not enough space (#54773)
This PR makes the submenu render on the left of the trigger if there's
not enough space (200px of available width) on the right. This improves
the rendering overall, I believe, as it's better than the submenu
rendering _on top_ of the parent menu.

Release Notes:

- N/A
2026-04-24 12:47:36 +00:00
Danilo Leal 1bf8de0a4b agent_ui: Fix markdown heading sizes (#54766)
Follow up to https://github.com/zed-industries/zed/pull/54374 as that
removed the custom heading styles that were mostly tailored to the agent
panel. It makes sense for those values not to be the ones used for
general markdown rendering, but I think it's just too big for the agent
panel. So I'm sort of hijacking the `MarkdownFont::Agent` enum here so
that we can set it conditionally to just the agent context.

Release Notes:

- N/A
2026-04-24 12:47:29 +00:00
Danilo Leal 71f14685a5 title_bar: Add "panel layout" menu to the user menu (#54771)
Closes https://github.com/zed-industries/zed/issues/54545

With the release of the parallel agents feature, we changed the default
panel positions optimizing for an agentic-first layout. Even though we
introduced a settings backfill _and_ the ability to revert after
interacting with the announcement toast, this change seems to be causing
a bit of frustration still. In response, this PR adds a "Panel Layout"
menu in the user menu that allows to quickly toggle between the
"Classic" layout and the "Agentic" layout. If you have a different set
up, you'll see a "custom" item there just confirming that.

| Panel Layout | Custom set up |
|--------|--------|
| <img width="1110" height="866" alt="Screenshot 2026-04-24 at 12 
52@2x"
src="https://github.com/user-attachments/assets/197fc4ec-b4b3-4b13-bcb3-9d3495cf0d0a"
/> | <img width="1156" height="866" alt="Screenshot 2026-04-24 at 12 
55@2x"
src="https://github.com/user-attachments/assets/ca791b1b-eb6a-47a9-8aa5-c2015f33e5bd"
/> |

Release Notes:

- Added a menu item in the user menu called "Panel Layout" which offers
the ability to quickly swap between the two standard panel layouts:
classic (project panel, git panel, etc., on the left) and agentic (agent
panel on the left, everything else on the right).
2026-04-24 12:47:15 +00:00
Kirill Bulatov a21366ea30 Reveal all go to definitions in the center by default (#54778)
Allows to reconfigure behavior, including the previous one, `top`

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

Release Notes:

- Reworked go to definition to open its target in the center of the
editor. Can be reconfigured with `go_to_definition_scroll_strategy`.
2026-04-24 12:43:30 +00:00
Riccardo Strina 5b7d0e8685 Fix gzip tar extraction by buffering decompressed bytes (#54696)
When extracting gzip tar files, the `GzipDecoder` was being pinned
directly over the response body stream. This caused issues because the
decoder needs to read the entire stream into memory before the `Archive`
can be created and used.

Buffer the decompressed bytes into a `Vec` first, then create the
decoder over that in-memory buffer to ensure all data is available when
needed.

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 [Java extension issue
222](https://github.com/zed-extensions/java/issues/222)

Testing:
**Automated:**
- `cargo test -p extension_host
test_extension_store_with_test_extension` — integration test that
exercises the full `download_file` → `GzipTar` → `extract_tar_file` path
through a WASM extension with a `FakeHttpClient` serving a real gzipped
tar archive. Passed.

**Manual:**
- Built and ran Zed with `cargo +nightly run`, deleted and reinstalled
the Java extension. The extension's language server download completed
successfully and all expected files were extracted.

Release Notes:

- Fixed extension `download_file` with `GzipTar` silently dropping
archive entries by buffering the full HTTP response before extraction,
matching the approach already used for extension installation. See
https://github.com/zed-industries/zed/blob/0a256eda7a7004985f1dddfee7bf822f66bc6ce0/crates/extension_host/src/extension_host.rs#L761
2026-04-24 12:42:45 +00:00
Richard Feldman e3466a5074 Don't block thread creation when PromptStore fails to initialize (#52333)
NativeAgentServer::connect used `prompt_store.await?` which turned any
PromptStore initialization failure (permission denied, disk issues,
etc.) into a hard connection error, putting the ConversationView into
LoadError state and preventing all new native agent threads from being
created.

Changed to `.log_err()` so the error is logged at ERROR level but thread
creation proceeds with `prompt_store: None`. `NativeAgent::new` already
accepts `Option<Entity<PromptStore>>` and handles `None` gracefully —
user custom prompts won't load but threads still work.

Added a regression test that serializes a stale thread ID, loads the
panel (triggering the "last active thread not found in database"
warning), then dispatches NewThread through the real NativeAgentServer
path and verifies it produces a connected thread.

Release Notes:

- Agent panel now handles filesystem errors more gracefully
2026-04-24 12:32:28 +00:00
XiaoYan LiandNeel cd9a88b750 agent_ui: Switch to All filter when last archived thread is removed (#54763)
When the archive view's filter is set to "Archived Only" and the user
deletes (or unarchives) the last archived thread, the toggle button
becomes disabled because there are no archived threads left. With the
filter still pinned to "Archived Only", the list goes empty and there's
no way for the user to switch back to the All view.

This fixes it by automatically falling back to `ThreadFilter::All`
inside `update_items` whenever the current filter is `ArchivedOnly` but
the store has no archived entries. Since `update_items` is invoked from
the `ThreadMetadataStore` observer, this covers all paths that mutate
the store, not only deletions triggered from this view.

Release Notes:

- Fixed the agent thread archive view getting stuck on an empty
"Archived Only" list after the last archived thread was removed.

---------

Co-authored-by: Neel <neel@zed.dev>
2026-04-24 12:02:08 +00:00
Joseph T. Lyons 5b66fd294a Fix broken rustfmt in git graph code (#54730)
rustfmt is broken in this code. I believe it's too deep / complex in the
builder pattern. After factoring some bits out, it now auto formats.

Self-Review Checklist:

- [X] I've reviewed my own diff for quality, security, and reliability
- [X] Unsafe blocks (if any) have justifying comments
- [X] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [X] Performance impact has been considered and is acceptable

Closes #ISSUE

Release Notes:

- N/A
2026-04-24 11:44:36 +00:00
Oleksiy Syvokon 611dc0bcfd project_search: Fix project search status text and refactor search state (#54753)
This change fixes a small bug where we were showing "Loading project..."
even when in fact we had already started the search.

It also refactors three booleans in the `SearchState` enum, so that it's
harder to make similar mistakes in the future.


Release Notes:

- N/A
2026-04-24 10:45:16 +00:00
Xiaobo Liu a2598f7fd8 editor: Make parse_blocks synchronous since it has no await points (#54756)
Release Notes:

- N/A

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
2026-04-24 10:40:20 +00:00
Matt Van HornandMatt Van Horn b9a60d802d language_models: Honor images capability for custom OpenAI models (#54223)
## Summary

Users who add custom OpenAI models under
`language_models.openai.available_models` can set `capabilities.images:
true` to declare that the endpoint accepts image inputs. Today, that
setting is silently ignored: the Agent panel's image-attach button stays
disabled regardless, and the only workaround is to switch to a built-in
OpenAI model, attach the image, and switch back.

Root cause: `Model::Custom` does not carry a `supports_images` field,
and the OpenAI provider's `supports_images()` for the `Custom` arm
hardcodes `false`.

## Changes

1. `crates/settings_content/src/language_model.rs`: add `images: bool`
to `OpenAiModelCapabilities` with `#[serde(default)]` so existing
settings.json files keep working unchanged.
2. `crates/open_ai/src/open_ai.rs`: add `supports_images: bool` to
`Model::Custom` with a matching serde default.
3. `crates/language_models/src/provider/open_ai.rs`: pass
`model.capabilities.images` into the `Model::Custom` variant in
`provided_models`, and return the stored value from `supports_images()`
for `Custom`.

Existing `Model::Custom { .. }` match sites (`completion.rs:829`,
various in `open_ai.rs`) all use `..` so they continue to compile
without change.

## Testing

- `cargo check -p settings_content -p open_ai -p language_models`:
clean.
- I was not able to complete `./script/clippy` locally: the build
stalled on the first-time `webrtc-sys` download for livekit-rust-sdks
(TLS close_notify failure on docs.rs mirror). Happy to rerun once CI has
cached artifacts.
- Manually verified the capability plumbing by tracing: settings.json ->
`OpenAiModelCapabilities.images` -> `Model::Custom { supports_images }`
-> `supports_images()` -> `Thread::prompt_capabilities` ->
`SessionCapabilities.supports_images()` -> `build_add_context_menu` gate
in `thread_view.rs`.

## Related Issues

Closes #50752

Release Notes:

- Fixed custom OpenAI models ignoring the `capabilities.images` setting
in `language_models.openai.available_models`.

This contribution was developed with AI assistance (Codex).

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-04-24 10:36:46 +00:00
Lukas Wirth e1a69bdc8f Remove smol as a dependency from a bunch of crates (#53603)
We aren't making use of it in these crates and it unblocks some
web-related work

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-04-24 10:29:51 +00:00
Kirill Bulatov c3ac472fce Exit early on mutating actions in readonly editor (#54758)
Hides and disables all mutating editor actions for readonly editors.

Certain actions (as cmd-backspace mentioned in the issue) could be
somewhat beneficial to have for navigation purposes, but we'd better
shape that story properly, let's build a "harness" and disable the
mutating ones first.

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

Release Notes:

- Fixed readonly editor having certain mutation actions enabled
2026-04-24 10:17:53 +00:00
MoulberryandBen Kunkle ae7a265a20 Fix showing unsupported window controls on Linux Wayland (#50609)
Release Notes:

- Fixed showing unsupported window controls on Linux Wayland

Before:
<img width="207" height="84" alt="image"
src="https://github.com/user-attachments/assets/174d3488-7c40-4b36-a1b5-76b85e19b796"
/>

After:
<img width="185" height="90" alt="image"
src="https://github.com/user-attachments/assets/82f10cbb-a834-4db9-a8e7-9e5156b3397e"
/>

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-04-24 10:10:12 +00:00
Tom HouléandBennet Bo Fenner b9a9f3bf9f agent_ui: Fix permissions getting granted to wrong tool call (#54683)
Release Notes:

- Fixed an issue where the first tool call would always be accepted when
parallel tool calls were made, rather than the one that was actually
clicked

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-04-24 09:52:28 +00:00
Smit Barmase 22a389260a gpui: Fix out-of-bounds panic rendering GIFs (#54701)
Clamp the cached `frame_index` of an `img` element when the underlying
image changes so a stale index from a previous, longer animation cannot
index out of bounds on the new image.

Release Notes:

- Fixed a panic when a GIF was replaced with one that had fewer frames
in Markdown Preview.
2026-04-24 09:46:50 +00:00
Om ChillureandDanilo Leal ba113e0a1d Fix agent thread sidebar covering window buttons (#54755)
## Summary

Fixes an oversight in the agent threads archive sidebar's header: on
Linux and Windows it only accounted for macOS traffic lights, so the
custom window controls (minimize/maximize/close) rendered on top of the
sidebar. The main sidebar
(`crates/sidebar/src/sidebar.rs::render_sidebar_header`) already handles
this correctly — this PR mirrors that pattern in
`ThreadsArchiveView::render_header`.

### What changed
- `crates/agent_ui/src/threads_archive_view.rs`
- `render_header` now computes `traffic_lights`, `left_window_controls`,
and `right_window_controls` (matching `sidebar.rs`) and reserves space /
renders controls accordingly when not fullscreen.
- Added `render_left_window_controls` / `render_right_window_controls`
helpers that delegate to `platform_title_bar`.
  - Imported `workspace::CloseWindow`.
- `crates/agent_ui/Cargo.toml`
  - Added `platform_title_bar` dependency.

### Behavior
- macOS (sidebar on left): unchanged — traffic-light padding + divider.
- Linux/Windows, sidebar on left: renders left-side window controls
inside the header.
- Linux/Windows, sidebar on right: renders right-side window controls
inside the header.
- Fullscreen: no controls rendered, same as before.

#### Closes #54596

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

### Video 

[Screencast from 2026-04-24
14-27-51.webm](https://github.com/user-attachments/assets/47009458-2acb-4b65-bff6-d25302a0342e)

Release Notes:

- Agent: Fixed the threads sidebar overlapping the window control
buttons on Linux and Windows.

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
2026-04-24 09:42:05 +00:00
Dino 6a1ef6b77e keymaps: Update no action bindings to null (#54506)
Update uses of `zed::NoAction` in default keymaps with `null` seeing as
`zed::NoAction` is being deprecated.

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
2026-04-24 09:33:26 +00:00
Albab Hasan db577853d0 gpui: Fix Core Foundation object leaks on macOS (#49022)
release `TISInputSource` returned by
`TISCopyCurrentKeyboardLayoutInputSource` in `MacKeyboardLayout::new()`,
and `CFUUIDRef` returned by `CGDisplayCreateUUIDFromDisplayID` in
`MacDisplay::uuid()`. both follow the core foundation create rule and
must be released by the caller.

Release Notes:

- N/A
2026-04-24 09:09:29 +00:00
Lukas Wirth d7c2ab4ef8 gpui_shared_string: Implement SharedString via smol_str (#54649)
This reduces the size of Sharedstring from 32 bytes to 24 while also
allowing for small-string optimization, meaning strings with length < 23
bytes will not actually allocate.

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-04-24 08:58:26 +00:00
Finn Evers 7d8e34ae14 ci: Reduce compliance notifications on success (#54669)
...What a beatiful syntax to have in a context where anything else would
not be evaluated regardless.

Release Notes:

- N/A
2026-04-24 08:56:22 +00:00
Sakethanddino bb47d90c76 Highlight nested JSX member expression tags (#53750)
The highlight queries only matched JSX member-expression tags when the
object was a plain identifier (`<A.B>`), so tags with more than one dot
like `<A.B.C>` lost their component-tag highlighting.

The fix explicitly captures every leaf `identifier` and
`property_identifier` at each nesting depth (up to 3 levels) in the
JavaScript and TSX highlight queries so each token gets its own
`@tag.component.jsx` capture that beats the generic `@property` rule.

A more concise approach, capturing the whole nested
`(member_expression)` node as a single `@tag.component.jsx` blob, does
not work because the generic `(property_identifier) @property` rule
targets a smaller, more specific node inside the blob, winning the
resolution for inner segments like `B` in `<A.B.C>`. 

Closes #53305 

Release Notes:

- Fixed highlighting for nested JSX member expression tags in JavaScript
and TSX files.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-04-24 08:45:47 +00:00
275af6d6a7 agent: Propagate tool permission decisions to pending permission prompts (#54679)
When the agent issued several parallel tool calls that all required
confirmation, clicking "Always for en.wikipedia.org" (or similar) on the
first prompt would persist the new rule to settings but leave the
sibling prompts stuck waiting on their own oneshot channels. The same
happened across subagents, and whenever the user edited settings.json by
hand while prompts were on screen.

`ToolCallEventStream::authorize()` now takes full ownership of the
permission decision. It evaluates the tool-permission settings up front,
and on Confirm it spawns a task that races the user's response against a
`SettingsStore` observer. When settings change, it re-runs the decision;
a new Allow or Deny drops the response receiver, flips the tool call
status to dismiss the prompt UI, and resolves the task without user
input. Subagents fall out of this for free since each thread observes
`SettingsStore` independently.

A few tools (`copy_path`, `move_path`, `delete_path`,
`create_directory`, `save_file`, `restore_file_from_disk`, and the
`edit-file` helper) sometimes need to prompt even when settings say
Allow — for example, edits that target `.zed/settings.json`. For those,
a new `authorize_always_prompt()` method skips the settings check and
always waits for user input; tools pick between the two at the call site
based on whether the path is sensitive.

Closes #54101.

Release Notes:

- In the agent panel, when you click "Always allow" for a tool, this
decision now gets propagated to other pending calls to the same tool.

Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
2026-04-24 08:42:44 +00:00
John Tur 3b39487e90 Pixel snapping (#54728)
Painting primitives at non-integer pixel coordinates produces blurry
output. Pixel snapping converts layout coordinates into integer
device-pixel coordinates so painted edges land exactly on physical pixel
boundaries.

Non-integer coordinates can arise for several reasons, including:

- flex distribution, percentages, centering, and text measurement can
produce fractional element sizes and positions;
- at fractional scale factors (for example 125% or 150%), integer
logical-pixel values can map to non-integer device-pixel values.

We pixel-snap by rounding in device-pixel space, after multiplying by
`scale_factor`, so that snapping targets physical pixels. Bounds are
divided by `scale_factor` before being returned to GPUI.

Midpoints are rounded toward zero. This is a stylistic choice: a
1-logical-pixel line at 150% scale should render as 1 dp rather than 2
dp.

Pixel snapping is done in two phases:

1. Pre-layout metric snapping. Before Taffy computes layout, all
authored absolute lengths are rounded in `to_taffy`. This includes
borders, padding, gaps, and explicit sizes. Custom-measured leaf nodes
have their measured sizes rounded up to integer device-pixel lengths.
2. Post-layout edge snapping. After Taffy resolves the tree, layout
relationships such as flex shares, grid tracks, percentages, and
centering can produce new fractional edge positions. Boxes now have
edges in absolute coordinates, and snapping must decide where those
edges land on the device-pixel grid.

Ideally, post-layout snapping would satisfy:

- Edge closure. Two raw layout edges at the same absolute position
should snap to the same pixel column.
- Translation stability. A component's internal geometry should not
change when it moves to a new absolute position.

These goals are in tension because rounding is not associative. The
simple local schemes make different tradeoffs:

- Absolute edge rounding gives each window coordinate one answer, so
coincident edges always close globally. But a span's snapped length is
`round(far) - round(near)`, which may change by 1 dp as its absolute
origin moves.
- Parent-relative edge rounding rounds each child inside its parent's
coordinate space. This guarantees translation stability, but a shared
edge reached through different parents can accumulate different
rounding, causing non-closure between cousins.
- Length rounding rounds each width, height, and thickness independently
and then places boxes from those rounded lengths. Sizes stay stable
under translation, but neighboring boxes derive their shared boundary
from different sources, so closure is not guaranteed.

We apply absolute edge rounding for each element's outer box in
post-layout rounding to preserve closure. Border and padding widths are
not touched by post-layout rounding; they keep their pre-layout rounded
value so that they remain stable under translation.

This gives both closure and translation stability in the case that all
local metrics are integer device-pixel lengths. Pre-layout rounding
covers that in most cases. The exception is metrics resolved by layout
relationships, such as percentages. Outer box edges will still close
globally, and painted border widths are still snapped independently, but
the raw content-box origin can carry a 1 dp residual into descendants.

---

Fixes https://github.com/zed-industries/zed/issues/46360
Fixes https://github.com/zed-industries/zed/issues/44528
Fixes https://github.com/zed-industries/zed/issues/40282
Fixes https://github.com/zed-industries/zed/issues/42257

---


Release Notes:

- Fixed potentially blurry appearance of UI elements when using
fractional display scaling.
2026-04-24 08:31:43 +00:00
Finn Evers 3fe9753d89 ci: Improve messaging around compliance failures (#54636)
Release Notes:

- N/A
2026-04-24 08:27:25 +00:00
John Tur a602db1c5b Pass shift-home and shift-end keystrokes to the terminal (#54706)
It's not clear what this logic was supposed to do, and it was preventing
shift+{special key} combinations from being sent to the terminal.

Fixes #52985

Release Notes:

- N/A
2026-04-24 06:41:37 +00:00
prayansh_chhablaniandJakub Konka e2d3597035 Helix jump list (#46467)
Closes #41580

This implements Helix's jump list, Zed already supports jumplists, so
all that is done is re-binding ctrl-s to to that instead. In another PR
we can extend this by adding space+j functionility to see all selections
in jumplist.

after this change:
Pressing Ctrl+S saves the current cursor position to the jumplist,
allowing the user to navigate back to this position using Ctrl+O
(backward) and Ctrl+I (forward), consistent with regular Helix's
behavior.

Release Notes:

- N/A *or* Added/Fixed/Improved ...

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2026-04-24 06:37:31 +00:00
Daniel GräfeandChristopher Biscardi ffbee47392 gpui: Add support for NSWindow's representedFilename (#48029)
This sets the accessibility document property (AXDocument) of the
window, which other apps can use to understand what file the current
window represents. Document-based apps on macOS are generally expected
to set this property.

The document path is set via `Window::set_document_path()` which calls
`setRepresentedFilename:` on the underlying NSWindow. The workspace
updates this path in `update_window_title()` whenever the active item or
project structure changes. For tests, instead of trying to somehow
assemble a proper NSWindow, we store the document path on the window
mock used for testing and check its value.

Motivation: I am the developer of Timing, an automatic time tracking app
for Mac. Timing uses the `AXDocument` property (a standard property of
most document-based app windows on macOS) to understand what document
the user is working on. With this change, Timing is able to understand
which directory the user is working in. Without this, Timing would only
record the window title, i.e. the filename without information about the
containing directory. I've had several users ask for better support for
Zed.

Here's a screenshot of the macOS Accessibility Inspector showing the
`AXDocument` property with this change. The UI of Zed itself does not
change. However, in my dev build of Zed, the traffic lights are a bit
too large and misaligned. However, this happens even when building
`main`, so I assume it’s unrelated to my changes.

<img width="1370" height="1162" alt="Screenshot 2026-01-30 at 16 18 25"
src="https://github.com/user-attachments/assets/dc260252-91fb-41e1-97a9-e6fb843c6a70"
/>

Release Notes:

- Set the represented filename property of windows on macOS

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-04-24 03:48:27 +00:00
Eric Holk 90fe7ab1ea Fix agent threads missing from sidebar after upgrade (#54723)
Fixes #54618.

## Summary

After upgrading from `v0.232.x` to `v0.233.5+`, many users reported that
most
of their agent threads "disappeared" from the sidebar. The threads are
still
on disk in the legacy `threads.db` — but they never make it into
`sidebar_threads`, which is the only table the new sidebar UI reads
from, so
they're unreachable from the UI.

The root cause is a race between `ThreadStore::reload` and
`migrate_thread_metadata`:

- `ThreadStore::new` constructs with an empty in-memory `Vec` and kicks
off
  `reload()` as a fire-and-forget task.
- `migrate_thread_metadata` runs during `agent_ui::init` and reads
  `ThreadStore::global(cx).read(cx).entries()` synchronously, without
  awaiting that reload.
- On cold boot the migration observes an empty iterator, early-returns
on
  `to_migrate.is_empty()`, and never populates `sidebar_threads`. The
  migration runs every launch, so it keeps losing the race forever.

Empirically, the only rows that *did* end up in `sidebar_threads` for
affected users came from `handle_conversation_event` writing rows when
the
user actively interacted with a thread. That's why users would typically
see
a handful of recently-touched threads rather than their full history.

## Fix

1. `ThreadStore` now tracks its current reload as a `Shared<Task<()>>`
and
   exposes it via `reload_task()`. `migrate_thread_metadata` awaits this
   before reading `entries()`.
2. Move the top-5-per-project unarchive pass out from under the
   `is_first_migration` guard. Previously the rescue only ran when
   `sidebar_threads` was empty, which meant any user who had even one
pre-existing row (e.g. from interacting with a thread on a prior launch)
got every subsequent batch of migrated threads archived with no rescue.
   Running the rescue per-batch is stateless and idempotent — a user who
bounces between older releases and newer ones still gets their top 5 per
   project surfaced each time a new batch is migrated.

No new KVP flag or one-shot backfill is needed: because the migration
already dedupes by session_id and runs on every launch, the next cold
boot
on a fixed build picks up any legacy threads that earlier launches
missed.

## Structure

The PR is split into two commits to make the diff easy to verify:

1. **Regression test** — fails on `main`, reproduces the cold-boot race
by
seeding the legacy DB, reinitializing `ThreadStore` to get a fresh empty
   cache, and running the migration without parking first.
2. **The fix** — gates entries reads on `reload_task().await`, and
adjusts
the per-batch rescue policy. Updates one existing test's assertions to
   match the new per-batch rescue policy.

## Validation

- The regression test fails on `main`, passes after the fix.
- All `agent_ui`, `agent::thread_store`, and `sidebar` lib tests pass.
- `./script/clippy -p agent -p agent_ui` is clean.
- End-to-end repro with a real on-disk data dir: launched `v0.230.2 →
v0.231.2 → v0.232.3 → v0.233.8` as a non-staff user, creating 15 threads
  and interacting with one, reproduced the reported state (1 thread in
sidebar, 14 missing). Launched a debug build of this branch against the
same data dir: `Migrating 14 thread store entries` in the log, 15 rows
in
`sidebar_threads` with 6 unarchived (the interacted-with thread plus the
  5 most recent), 9 archived and reachable from the archive view.

Release Notes:

- Fixed agent threads appearing to be missing after upgrading to the
parallel-agents sidebar. The thread-metadata migration was racing
against the on-disk thread store's async reload and skipping itself on
every launch. Upgrading to this build runs the migration successfully;
previously-missing threads are surfaced either in the sidebar (5 most
recent per project) or in the archive view.
2026-04-24 03:09:30 +00:00
shiwyangandConrad Irwin fd4e7b90fe Support GFM callouts in Markdown (formerly GitHub admonitions) (#54661)
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 #10022 

Release Notes:

- Added support for GFM alert callouts (`> [!NOTE]`, `> [!TIP]`, `>
[!IMPORTANT]`, `> [!WARNING]`, `> [!CAUTION]`) in markdown preview,
rendering each type with a colored left border, icon, and bold label.

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2026-04-24 02:52:54 +00:00