Follow-up to #59195. While verifying that fix against prod we hit a log
that couldn't distinguish "retrying with a fresh token that is still
revoked" from "silently retrying with the same dead token because the
server returned no connection info" (e.g. a collab deploy predating
#59195). Make the retry loop self-diagnosing:
- Warn when `RejoinRoomResponse` carries no `live_kit_connection_info`,
since the loop then reuses the existing token.
- On refresh, log whether the token actually changed.
Release Notes:
- N/A
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Clip split buffer headers to the editor's content bounds so they no
longer paint into the horizontal scrollbar area.
Reuse the editor's computed right margin and horizontal scrollbar
visibility instead of reimplementing scrollbar detection in
split_editor_view. This keeps split headers aligned when minimap, inline
blame, or scrollbar visibility change the available content area.
Release Notes:
- Fixed horizontal scrollbars not being rendered behind buffer headers
in split editors
---------
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes AI-394
When the kernel isn't running — e.g. Python isn't installed, ipykernel
is missing, or the kernel failed to launch — clicking run on a notebook
cell would unconditionally enter the executing state and silently drop
the execute request. The cell then spun forever with no logs and no way
to cancel (the stop button only works on a running kernel).
This change makes `execute_cell` attempt to send the execute request
first, and only mark the cell as executing when the send succeeds. On
failure it:
- Renders the failure (including the original kernel launch error) as an
error output on the cell, reusing the same `ErrorView` used for Python
tracebacks
- Logs the reason at the moment run is clicked, instead of only once at
notebook open
- No longer swallows `try_send` errors when the kernel process has died
Also adds the first unit test for the notebook editor, which exercises
the production path end to end: a real `.ipynb` parsed via
`NotebookItem::try_open`, a kernelspec pointing at a nonexistent
interpreter selected through `ReplStore::set_active_kernelspec`, a real
failed process spawn, and assertions through the production save path
(`to_nbformat_cell`). Verified red/green: the test fails against the
previous behavior.
Note for future notebook tests: `NotebookEditor` renders a continuously
animating kernel status icon, so rendering it as a root view in a GPUI
test makes `run_until_parked` spin forever. The test creates the editor
inside an empty window instead.
Release Notes:
- N/A
# Objective
We were not caching builds for nightly/bundling jobs AT ALL.
## Solution
## Testing
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
This is a follow up to https://github.com/zed-industries/zed/pull/58169
and https://github.com/zed-industries/zed/pull/58518 after removing a
bunch of unsafe usage.
Before this, GPUI moved traffic lights by directly changing the native
button frames inside AppKit’s existing titlebar layout and the old
y-coordinate was based on the native titlebar height, so the buttons
moved visually while the titlebar tracking geometry could still be based
on the old layout.
Now the native titlebar container is resized and repositioned to contain
the traffic lights. We capture the original AppKit titlebar/button
frames, resize the titlebar container to fit the requested position,
move the native close/minimize/zoom buttons inside that container and
update AppKit tracking areas. This keeps the visible buttons and
hover/click geometry aligned.
### Before
https://github.com/user-attachments/assets/77dde6cb-3fc8-4166-bc86-22cf2c93e119
### After
https://github.com/user-attachments/assets/da84ade6-ef47-4e53-ae4a-3779315773f9
---------
Co-authored-by: Yara 🏳️⚧️ <git@yara.blue>
# Objective
You know that feeling? You join the channel, crack a banger joke to
break the ice - yet, nobody laughs. Worse yet, you're swarmed with Slack
messages like "Piotr, we can't hear you". After a while you realize that
maybe it's for the best as the joke was not as good as you've initially
thought, but still: it's possible to get into a state where other
participants see you as muted. You don't hear anybody. Bummer.
That's what happened when we were hoping to pair with @dinocosta today.
I could not hear him. However, he had some logs to share which indicated
that while collab thought he's in the room with me, live-kit was
rejecting his token as it was revoked.
What clanker helped us figure out is that there's a race-y code path
where if you disconnect from a given room abruptly, collab can put you
in a limbo.
<details><summary>Clanker's idea of what's going on</summary>
<p>
Found the whole story. Here's what those logs mean and where the bug
surface is.
What's happening
The error at room.rs:1809 is the detach_and_log_err on the task spawned
by spawn_room_connection (crates/call/src/call_impl/room.rs:1754-1810).
So this is the initial livekit::Room::connect call failing — the LiveKit
SDK internally retried 3 times (that's the retrying... (1/3) lines), got
401 invalid token: revoked every time, gave up, and the error propagated
out of the ? at line 1762 and was logged-and-dropped.
The "revoked" comes from the collab server: leave_room_for_session
(crates/collab/src/rpc.rs:4091-4095) calls
live_kit.remove_participant(livekit_room,
session.user_id().to_string()), and LiveKit Cloud treats a removed
participant's token as revoked. Crucially, the LiveKit identity is just
the user id, not the connection id, while the DB-side
leave_room(connection_id) is per-connection. leave_room_for_session
fires from three places:
1. Explicit leave (rpc.rs:1666)
2. connection_lost, after RECONNECT_TIMEOUT expires (rpc.rs:1342)
3. Stale-connection cleanup when re-joining a channel (rpc.rs:3401)
So there's a race: an old connection's delayed cleanup (path 2) can fire
after the same user has rejoined the room on a new connection and been
issued a fresh token — and remove_participant(room, user_id)
kicks/revokes the user's current LiveKit participant, because the
identity is shared across connections. Quick restart of Zed, two
instances, or a reconnect that straddles the server's RECONNECT_TIMEOUT
all set this up.
Client-side consequences (this connects to your first question)
When that initial connect fails:
- this.live_kit stays None and this.diagnostics is never created — lines
1780-1791 only run on success. So in this failure mode CallDiagnostics
doesn't exist at all; the "stats never overridden" path I described
earlier isn't even reached.
- There is no retry and no token refresh. The failure is
detach_and_log_err'd and that's the end of it. The user stays in the
room at the collab level (status is still Online, they appear in the
channel), but with no audio and no way to recover short of leaving and
rejoining.
- Even a collab-level reconnect doesn't help: RejoinRoomResponse
(crates/proto/proto/call.proto:58) carries no live_kit_connection_info,
and rejoin() never calls spawn_room_connection — the LiveKit connection
is established exactly once, in Room::new, with the token from the
original join response.
So the user-visible symptom is: you're "in" the call, everyone sees you,
but you can't hear or be heard, and there's no error surfaced in the UI
— just this log line.
If you want to fix it, the two angles are server-side (make
leave_room_for_session skip the LiveKit removal when the user still has
a live connection in that room, or scope LiveKit identities
per-connection) and client-side (treat a failed spawn_room_connection as
fatal-but-recoverable: surface it, and have rejoin request fresh
connection info instead of silently carrying on). Happy to dig into
either if you want.
</p>
</details>
So tl;dr: our token was swapped out underneath us. One way to "fix" it
was to just go into another channel, but that was a bummer.
We have a good and reliable repro for it though: `kill -9 $ZED_PID`
followed by an attempt to rejoin the same channel within 30s would
consistently put us in that state.
Put another way: you panic and thus do not send a clean "leave room"
message to LK. if you rejoin the channel within 30s (after restarting),
LK will invalidate the very token you're attempting to use (as it cleans
up old tokens).
It may also happen without crashing, but that's the most reliable way to
repro the issue. Long story short your LK token gets tainted and you
can't share the audio anyhow.
## Solution
The fix is both client and server-side.
On client's side, we now retry the reconnection with a back-off and we
grab a fresh token off of reconnect attempts.
On server's side, we share the current token on room reconnect attempts.
We've also tweaked the call diagnostics to not use `unwrap_or_default`
so much: it was hard for us to tell that we're in a totally bogus state
and we've only reached that conclusion based on source code analysis. We
now show some generic "ok you're in a borked state pls report a bug"
message instead.
## Testing
We added tests that present the flacky scenario. We've also tried to
setup an infra to test the new behaviour, but sadly, local LK instance
seems to revoke tokens more leniently than the prod..
OTOH, we are quite confident that once new collab is deployed, we'll be
able to mince the new tokens and life is going to be good. Even when
running against the current prod instance we could see that our code
changed the behaviour for the better, as now we'll actually try to use a
new token if one is provided by collab. For that to happen we need to
redeploy though.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed a race condition that caused collab users to not receive/send
any audio to their peers.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Dino <dino@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Both cloning and dropping of these has quite a bit of overhead (despite
them being snapshots), so avoid where possible, especially in display
map syncing
Release Notes:
- N/A or Added/Fixed/Improved ...
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#56748
## Summary
Block / column selection (Shift+Ctrl+drag on Linux, Shift+Cmd+drag on
macOS) anchored its rectangle on a single byte column applied to every
row in the dragged range. On a row whose text contained a multi-byte
character before that column (for example `ã`), the same byte offset
mapped to a different visual `x`, so the per-row cursor drifted off the
column.
`select_columns` now anchors the rectangle in `x` pixels via
`x_for_display_point` and resolves each row's byte column with
`display_column_for_x` — the same pair of helpers already used by
vertical cursor motion and Vim VisualBlock.
## Before / After
**Before** — cursor on the `ã` row drifts one column to the left:
<img width="1068" height="366" alt="image"
src="https://github.com/user-attachments/assets/0559ef89-852e-40f3-9d43-f5f44277f99e"
/>
**After** — rectangle stays visually aligned across rows:
<img width="866" height="408" alt="image"
src="https://github.com/user-attachments/assets/bce13c1a-1ddb-4fd6-8216-2c0e902f6668"
/>
## Test plan
- `cargo test -p editor test_columnar_selection_with_multibyte_chars`
(new regression test covers the buggy case past the `ã` byte boundary,
plus a control case where old and new logic agree).
- Manual: Shift+Ctrl+drag down a five-line buffer where row 3 contains
`ã` — selection rectangle stays aligned (see screenshots).
- Manual: Shift+Alt+drag (`FromSelection` branch) over the same buffer —
same result.
- Manual: drag past EOL on the `ã` row — each row extends to its own EOL
with no panic.
Release Notes:
- Fixed misalignment of column selection on rows that contain multi-byte
characters
---------
Co-authored-by: Tom Houlé <tom@tomhoule.com>
Release Notes:
- Fixed an issue where the close button could overflow within a
workspace error popup.
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
# Objective
Give a bit more structure to contributors so that each (potentially new)
contributor doesn't have to come up with their own structure on-the-fly.
## Solution
Update the PR template to include sections for describing
- what the PR is trying to achieve
- how it decided to achieve the goal
- how reviewers can test the work
- demos of the new functionality
## Testing
I used the PR template for this PR, so reviewers can evaluate if they
think the structure is useful.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
<details>
<summary>Click to view showcase</summary>
### Before
<img width="1082" height="572" alt="image"
src="https://github.com/user-attachments/assets/bc72b8ab-f5ec-4270-b1ec-546456525e92"
/>
### After
<img width="1241" height="945" alt="image"
src="https://github.com/user-attachments/assets/088d90e4-2cb1-42cd-9f8f-0b2783ab7fe4"
/>
</details>
---
Release Notes:
- N/A
Follow up to https://github.com/zed-industries/zed/pull/59126 where
seeing the typed-prompt in the agent panel's toolbar felt really busy.
With that change, I'd be seeing the prompt I'm writing in three
different stops, which felt overwhelming. Toning that down a little bit
in here.
Release Notes:
- N/A
Mermaid diagrams with long node labels rendered as an unreadable jumble:
each label was painted as one long line over a box sized for wrapped
text, overflowing into neighboring nodes. With this change, labels wrap
to the box width the layout computed.
**Root cause:** mermaid's default `htmlLabels: true` makes merman emit
labels as HTML inside `<foreignObject>`, which resvg cannot rasterize.
merman's resvg-safe pipeline replaces each one with a single-line
`<text>` fallback that only honors explicit `<br>` breaks, so
soft-wrapped labels collapse onto one long line — while the node boxes
were laid out for the wrapped text.
**Fix:** disable HTML labels in the site config (both the top-level key,
which merman reads for node labels, and `flowchart.htmlLabels`, which it
reads for edge labels). merman then emits native SVG `<text>`/`<tspan>`
labels wrapped to the same measured width the layout used, and the
foreignObject fallback never runs for these diagrams.
One behavior preserved deliberately: a literal `\n` in label text used
to become a line break as a side effect of the foreignObject fallback
(`fallback.rs` converts `\n` when flattening HTML labels).
`render_mermaid` now normalizes `\n` to `<br/>` before rendering so the
native path keeps that behavior; the existing
`backslash_n_converted_to_line_break` test covers it.
Side effect: class diagram member text also switches from the lossy
fallback to native SVG text; the accent-class test was updated
accordingly (accent classes now land directly on `text`/`tspan`
elements).
Verified with `cargo nextest run -p mermaid_render`, `-p markdown`,
`script/clippy -p mermaid_render`, and `cargo fmt --check`.
Release Notes:
- Fixed mermaid diagram labels overflowing and overlapping nodes when
long labels wrap
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Replaces the verbose struct-literal construction of `gpui::BoxShadow`
with a builder API:
- `BoxShadow::new(offset_x, offset_y, color)` takes the required fields,
with arguments ordered to match the CSS `box-shadow` property.
- `.blur_radius(_)`, `.spread_radius(_)`, and `.inset()` set the
optional fields.
All in-tree call sites are migrated, including the Tailwind-style
`shadow_xs`..`shadow_2xl` helpers in `gpui_macros`, the `ElevationIndex`
shadows in `ui`, and various widgets across `editor`, `workspace`,
`agent_ui`, and `ai_onboarding`. The fields on `BoxShadow` remain
public, so external code using struct-literal construction continues to
work.
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
Opening a new git worktree of a repository that has a dev container
configuration re-prompted you to reopen in a dev container, even after
you'd clicked "Don't Show Again" in another worktree of the same repo.
The dismissal was keyed on each worktree's own absolute path, so sibling
worktrees never saw the stored choice.
This keys the dismissal on the repository's common Git directory
instead, which is shared across all linked git worktrees of the same
repo, so dismissing in one worktree now suppresses the prompt in the
others. Projects that aren't Git repositories fall back to the worktree
path as before.
Closes AI-357
Release Notes:
- Fixed the "Reopen in Dev Container" suggestion re-appearing in new git
worktrees after choosing "Don't Show Again"
I asked Claude Fable 5 to review our macOS process spawning layer, and
it found two notable bugs:
- We didn't mark stdio descriptors as inherited when the `Inherit`
option was passed. This means they would be closed in the child due to
`POSIX_SPAWN_DEFAULT_CLOEXEC`. Now we correctly mark them as inherited.
- Child processes were inheriting Rust's default `SIG_IGN` disposition
for `SIGPIPE`. `std::process::Command` resets the disposition to
`SIG_DFL` for children, and this PR makes us do that too, with a
regression test.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
## Context
GPUI API change only:
- added `.alpha(a: f32)` method to `RGBA`
- added `.opacity(factor: f32)` method to `RGBA`
- added documentation for both new methods
- added test coverage for both methods
These implementations already exist for the `HSLA` struct and were
missing for `RGBA`.
> [!NOTE]
> In my opinion, a trait implementation could be beneficial here. Let me
know what you think about that idea before I end up making unwanted
changes.
## How to Review
Just added the new methods, including documentation and test coverage.
## 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:
- Added `gpui::Rgba::alpha` and `gpui::Rgba::opacity` methods for
setting and scaling a color's alpha channel, matching the existing
`gpui::Hsla` API
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This change is motivated by user feedback where we saw some confusion
where they didn't know that you could create either a worktree or branch
through simply typing in their respective picker's editor. Hopefully,
this new placeholder in each of them will help communicate that.
Release Notes:
- Improved placeholder copywriting in both the branch and worktree
pickers to communicate it's possible to type-to-create each.
Co-authored-by: María Craig <maria@zed.dev>
This PR fixes an issue where font properties like bolds and italics
would be lost when falling back to a fallback font.
The problem we identified was that when loading the fallback fonts, we
were just loading them by name. This meant that when the original font
had a different font weight (e.g., bold) or style applied to it this
would not cascade to the fallback font.
To reproduce the problem, we used the following text in a Markdown file:
```md
**한글 bold**
```
With the following font configuration in Zed:
```json
"buffer_font_family": "Victor Mono",
"buffer_font_fallbacks": [
"D2Coding"
]
```
The fonts can be obtained from their respective locations:
- [Victor Mono](https://rubjo.github.io/victor-mono/)
- [D2Coding](https://github.com/naver/d2codingfont)
#### Before
<img width="168" height="46" alt="Screenshot 2026-05-14 at 1 15 15 PM"
src="https://github.com/user-attachments/assets/f6883e4b-8f2b-4285-a110-0e18d562c51d"
/>
#### After
<img width="176" height="53" alt="Screenshot 2026-05-14 at 1 16 04 PM"
src="https://github.com/user-attachments/assets/88d67207-6711-473b-8027-e0acfa58c258"
/>
Closes#51460.
Release Notes:
- macOS: Fixed fallback fonts missing weight/style.
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
When the agent panel's thread is empty, the toolbar no longer shows the
labeled agent dropdown on the far left. Instead, it uses the same layout
as an active thread: a stable plus icon button on the far right, and the
left slot displays a muted "New {agent} Thread" placeholder title —
matching the sidebar's draft thread item. As soon as you type into the
message editor, the title shows your prompt text instead, reusing the
sidebar's draft label truncation logic.
Release Notes:
- Improved the agent panel's empty-state toolbar to show a "New {agent}
Thread" placeholder title (or your draft prompt as you type), with a
stable new-thread button on the right.
Wrap the fds returned by `create_pipe` and `open_dev_null` in
`std::fs::File` earlier, so that they are closed if we return early due
to an error. Includes a regression test.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed a file descriptor leak on macOS.
---------
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Audited the AI documentation against the implementation
## Changes
- **tool-permissions**: `skill` tool patterns match the absolute
`SKILL.md` path, not the skill name (fixed the table, example pattern,
and added a clarifying note).
- **external-agents**: Gemini CLI receives Zed's Google AI key when no
env key is set; extension-provided agents are deprecated in favor of the
ACP registry.
- **inline-assistant**: alternatives run alongside the inline assistant
model (not just the default model); fixed a broken anchor and
`gpt-4-mini` → `gpt-5-mini` model id typos.
- **mcp**: corrected the extensions menu item name ("Install New
Servers…"), the remote server `url` example, and removed the nonexistent
`thinking` tool from the profile example.
- **agent-panel**: "New From Summary" lives in the New Thread menu;
corrected the `@`-mention type list (no "instruction files"; added Fetch
and Branch Diff).
- **use-api-access**: DeepSeek default `api_url` includes `/v1`.
- **skills**: folder name is a convention not a requirement; long
descriptions warn rather than fail (measured in bytes); hidden skills
are also `@`-mentionable; dropped the unenforced consecutive-hyphen
rule; reconciled the no-remote-registry note with GitHub import.
- **edit-prediction**: `alt-tab` and `alt-l` are bound across platforms;
predictions are throttled rather than fired on every keystroke.
- **getting-started, windows-and-projects, parallel-agents**: Panel
Layout lives in the title-bar user menu, with
`workspace::UseAgenticLayout`/`UseClassicLayout` action references.
Release Notes:
- N/A
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
We recently changed this given some new models (e.g., Fable) don't allow
turning thinking off. In those cases, we are not rendering the split
button anymore, but we should still display the thinking icon, so they
look a bit more consistent.
Release Notes:
- N/A
Sometimes, landing in the archive view at first, particularly after
importing ACP threads, can be confusing as there's not an immediately
available "create new thread" button users can click on.
Release Notes:
- N/A
## Summary
Add keyboard shortcut for macOS, in the ACP Permission dialog, for
"Always Allow", following what is available in both Linux and Windows.
### 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
Release Notes:
- Added missing `AllowAlways` keybinding on macOS (`cmd-alt-y`).
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Allows contents to update without dropping the permission (caused by
claude subagents)
Closes
https://github.com/agentclientprotocol/claude-agent-acp/issues/708
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:
- acp: Fix failed permissions requests for external agents
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#58653
Release Notes:
- Fix "Loading Commit History..." message in History tab stuck on
projects with empty or no repositories
On transparent or blurred window backgrounds, several agent panel
surfaces and
the multibuffer header rendered drop shadows and fade gradients that
have no
opaque surface to blend into, so they showed up as dark halos or colored
patches:
- agent message boxes and the activity bar (drop shadows)
- diff-hunk Reject/Keep controls (drop shadow)
- the diff review pane (double-painted `editor_background`)
- agent thread-list rows, the conversation title edit affordance, and
sidebar
project headers (fade gradient)
- the multibuffer buffer header (`editor_subheader_background` + sticky
shadow)
These are skipped when `window_background_appearance` isn't `Opaque`.
Opaque
windows are unchanged; on transparent windows the elements stay
delineated by
their borders and truncate text with an ellipsis instead of fading.
## Screenshots
Before:
<img width="1920" height="1200" alt="Screenshot 2026-06-09 at 3 26 26
PM"
src="https://github.com/user-attachments/assets/7dc9c76c-7de9-4c50-8719-05957d091706"
/>
After:
<img width="1728" height="1117" alt="Screenshot 2026-06-09 at 3 26 29
PM"
src="https://github.com/user-attachments/assets/889a53ad-9f11-41b9-9f51-ffcbd5c37821"
/>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed dark shadow and gradient artifacts in the agent panel and
multibuffer headers when using a transparent or blurred window
background
This PR fixes some cases where scrolling is choppy due to a user
inputting a scroll event while a list state is going through a
remeasure. Currently, the list state would ignore the user's scroll and
fall back to the pending scroll position, this PR fixes this by rebasing
the pending scroll onto the user's new scroll position.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- agent_panel: Improve scroll smoothness while a response is streaming
## Summary
- add an editor action for selecting the contents of the innermost
enclosing bracket pair
- register the action without assigning a default key binding
- cover cursor, selection, nested bracket, no-op, and multi-cursor cases
## Tests
- cargo fmt --check
- cargo test -p editor test_select_inside_enclosing_bracket --lib
- cargo test -p editor test_move_to_enclosing_bracket --lib
Release Notes:
- Added action to select the contents enclosed by brackets
## Summary
Exposes the existing recursive pane-size reset as a command-palette
action, so it can be invoked outside of vim mode.
The center pane grid's sizes can already be evened out by
double-clicking a divider, or via `vim::ResetPaneSizes` (`ctrl-w =`)
when vim mode is on, but there is no general action for it — so users
not in vim mode have no discoverable way to undo a drifted split layout
in one step.
## How it works
`workspace::ResetPaneSizes` (palette: "workspace: reset pane sizes")
calls the existing `Workspace::reset_pane_sizes`, which resets every
`PaneAxis` in the center pane group to equal flexes, recursing into
nested splits. The split structure is preserved — no panes are added,
removed, or rearranged, only their sizes are equalized. This is the same
path the vim `ctrl-w =` binding and the divider double-click already
use.
## Out of scope
- Docks (left/right/bottom panels) — they keep their existing `Reset
Active Dock Size` / `Reset Open Docks Size` actions.
- The terminal panel's internal splits — it is a separate panel, not
part of the center pane group.
- No default keybinding (palette-only); vim users keep `ctrl-w =`.
## Testing
Added `test_reset_pane_sizes`: builds a nested split (a horizontal axis
of three panes whose last child is a vertical split), skews every axis's
flexes, dispatches the action, and asserts every axis returns to uniform
sizes.
Release Notes:
- Added a `workspace: reset pane sizes` command that equalizes the sizes
of all panes in the center group
## Context
This follow-up was inspired by Christopher’s suggestion in the review
comment on #58483: long filenames should truncate in the middle so both
the beginning and the suffix/extension remain visible.
Previously, very long filenames in picker rows could still be clipped or
end-truncated, making files with shared prefixes hard to distinguish.
This adds middle-truncation support to GPUI text overflow and applies it
to filename-focused picker surfaces: the tab switcher and the Ctrl-P
file finder. Normal editor tab bar behavior remains unchanged and
continues to use the existing title length cap.
## How to Review
- **`crates/gpui/src/style.rs`, `crates/gpui/src/styled.rs`,
`crates/gpui/src/elements/text.rs`,
`crates/gpui/src/text_system/line_wrapper.rs`**: Adds
`TextOverflow::TruncateMiddle`, wires it through text layout, and
implements middle truncation while preserving valid text runs. Very
narrow widths now show the truncation affix instead of falling back to
the abruptly clipped original text.
- **`crates/ui/src/components/label/label_like.rs`,
`crates/ui/src/components/label/label.rs`,
`crates/ui/src/components/label/highlighted_label.rs`**: Exposes middle
truncation through the shared label components.
- **`crates/workspace/src/item.rs`, `crates/editor/src/items.rs`,
`crates/workspace/src/pane.rs`,
`crates/tab_switcher/src/tab_switcher.rs`**: Adds an explicit
tab-content opt-in for middle truncation. The tab switcher enables it,
while the normal tab bar and dragged tabs keep their existing behavior.
- **`crates/file_finder/src/file_finder.rs`**: Applies middle truncation
to Ctrl-P file finder filenames and lets the path shrink from the start
so long paths do not hide important filename suffixes.
Manual test before change :
[Screencast from 2026-06-10
22-59-28.webm](https://github.com/user-attachments/assets/5e032646-a48c-45f2-8fe2-0424507fd576)
Manual test after change :
[Screencast from 2026-06-10
22-54-48.webm](https://github.com/user-attachments/assets/4b9253da-f169-4ed1-bdd5-ee71dcf49a83)
## 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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Improved long filename truncation in the tab switcher and file finder
so extensions remain visible.
Pasting text that merely starts with a scheme-like prefix (for example a
commit message like `editor: Fix crash in project panel`) over a
selection in a Markdown buffer would wrap the selection in a Markdown
link, because `url::Url::parse` accepts `editor:` as a valid URL scheme.
Paste now only treats clipboard text as a URL when the whole text is a
single standalone URL, using `linkify` (already a workspace dependency)
instead of `url::Url::parse`. Added a regression test covering the
scheme-like prefix case.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#59070
Release Notes:
- Fixed pasting text starting with a scheme-like prefix (such as
`editor: ...`) over a selection in a Markdown buffer incorrectly
creating a Markdown link.
This slightly reworks the extension CLI bump workflow - instead of
triggering on label push, it now triggers on workflow dispatch with a
message enforced to be added there.
This primarily allows us to add a message to these bumps to better
communicate what changes with that version of the CLI. Furthermore, we
can soon restrict the label to be only created by that workflow, which
has the advantage that it can only be based off of main. Also, it has
the nice side-effect that we actually only ever update the label if
everything worked properly.
Release Notes:
- N/A
After prompting an agent, no response was received and only a spinner
was shown. After updating and reopening Zed, the thread still appeared
in the sidebar but failed to restore with `Failed to Launch` / `no
thread found with ID: SessionId(...)`, and the original prompt was lost.
## Root cause
A native agent thread is tracked by two independent persistence layers:
- **Sidebar metadata** (`ThreadMetadataStore`) and the **serialized
agent panel** record the thread's `session_id` through fast, separate
write paths.
- **Thread content** (`ThreadsDatabase`) is written by a per-session
async task (`NativeAgent::save_thread`) that can still be in flight when
the process exits.
When a graceful quit or update restart raced that async content save,
the metadata/serialized session id was persisted but the content row was
not. On restore, the metadata gate passes, then `load_thread` finds no
content row and hard-fails with `no thread found with ID`.
## Fix
Register an `on_app_quit` handler on `NativeAgent` that synchronously
commits every newly created non-empty thread's content to
`ThreadsDatabase` during shutdown, keeping the two stores consistent
across a graceful quit/restart (the auto-updater's path).
Closes AI-374
Release Notes:
- Fixed agent threads failing to restore after quitting or updating Zed
while a response was still in progress
Fixes the agent panel silently reverting all pending subagent file
changes when an earlier message is edited and regenerated.
`ThreadView::regenerate` decides whether to auto-keep pending edits from
earlier prompts (behavior introduced in #43347) by scanning the parent
thread's entries for diffs. Subagent edits never appear there — they are
only forwarded to the parent's action log via the linked-log mechanism —
so the auto-keep step was skipped and `rewind`'s unscoped
`reject_all_edits` reverted all of them on disk, without confirmation.
The fix treats any earlier subagent tool call as potentially having
edits, so they get auto-kept just like direct edits from earlier
prompts. Keeping all edits is a no-op when the subagent made none. Edits
produced by the prompt being regenerated are still auto-rejected,
consistent with existing behavior.
Also adds a regression test
(`test_regenerate_keeps_pending_subagent_edits`) that reproduces the
full flow — subagent edit forwarded through a linked action log,
follow-up prompt, regenerate — and fails with the exact reported data
loss without the fix.
Closes AI-386
Closes https://github.com/zed-industries/zed/issues/58932
Release Notes:
- Fixed pending subagent file changes being discarded when editing an
earlier message in the agent panel.
When running `zed` [directly from a foreground
terminal](https://github.com/zed-industries/zed/issues/51351#issuecomment-4507962670)
(stable `zed-editor`, or zed dev builds via `cargo run` as in #51351),
Zed only enables the stdout log sink and never creates `Zed.log` on
disk. This causes `zed: open log` and `zed: reveal log in file manager`
to always failed with `Unable to access/open log file ...: Failed to
read file... No such file or directory (os error 2)`.
Per maintainer feedback, rather than always creating the log file, this
change only registers the `OpenLog` and `RevealLogInFileManager` action
handlers when stdout isn't a PTY. In the PTY case the two actions no
longer appear in the command palette at all, so they can't be invoked
only to error.
Repro (before this change):
1. `rm -rf ~/.local/share/zed/logs/`
2. `~/.local/zed.app/libexec/zed-editor` (the GUI binary directly,
bypassing the CLI wrapper which detaches and sets `ZED_FORCE_CLI_MODE`)
3. In Zed, run `zed: open log` → error toast
Release Notes:
- Fixed `zed: open log` and `zed: reveal log in file manager` appearing
and erroring when Zed was launched directly from a terminal. These
actions are now hidden in that scenario, since logs go to stdout rather
than Zed's log file.
---------
Co-authored-by: dino <dinojoaocosta@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
Release Notes:
- N/A
---------
Co-authored-by: Martin Ye <martin@zed.dev>
Claude Fable 5 always thinks and cannot honor a request with thinking
disabled, but the cloud models listing gives clients no way to tell it
apart from models where thinking is optional (e.g. Claude Opus 4.6):
both report `supports_thinking: true` plus the same adaptive effort
levels. As a result, the agent panel shows a thinking toggle for Fable
even though turning it off isn't actually supported.
zed-industries/cloud#2789 adds a `supports_disabling_thinking` field to
the models listing. This PR mirrors it through
`cloud_llm_client::LanguageModel` (serde-defaulted to `false`, so a
server without the field is treated as "don't claim thinking can be
turned off") and exposes it as
`LanguageModel::supports_disabling_thinking()`, forwarded from the
listing by `CloudLanguageModel`. The agent panel now hides the thinking
toggle for models that report `false`, showing only the effort selector.
The trait default is `true`: every non-cloud provider in the tree treats
thinking as toggleable today, and only the cloud listing knows about
always-thinking models.
Draft until zed-industries/cloud#2789 lands and deploys.
Release Notes:
- Fixed the agent panel offering a thinking toggle for models that
cannot run with thinking disabled.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed a bug that prevented scrolling the sidebar when the mouse was
positioned over a project header.
## Summary
Routine housekeeping to remove seven inactive GitHub Actions workflows,
surfaced by a workflow-activity review (run history via the Actions
API).
The removals fall into two groups:
- **Four hand-written workflows** that are manually disabled, never run,
or long dormant.
- **Three xtask-generated workflows** (manual eval/perf tools) dormant
for >90 days — removed at the source in `tooling/xtask` and regenerated,
with now-unused helper code dropped.
Reusable workflows `extension_tests` and `extension_bump` were
intentionally **kept** — their low standalone run counts are an artifact
of `workflow_call` (they run constantly via `run_tests` and
`extension_auto_bump`), so they are not dormant.
## What is being removed
| Workflow | Roughly what it does | Author | Last run | Reason |
|---|---|---|---|---|
| `assign-reviewers.yml` | Auto-assigns reviewers to PRs (via a GitHub
App token) | John D. Swanson | 2026-04-17 | Manually disabled in Actions
settings |
| `assign_contributor_issue.yml` | Assigns/labels contributor issues and
notifies Slack | Lena | 2026-05-12 | Manually disabled in Actions
settings |
| `background_agent_mvp.yml` | Experimental background-agent MVP (manual
dispatch; schedule commented out) | morgankrey | 2026-02-24 | Dormant
>90 days; experimental, never promoted |
| `randomized_tests.yml` | Runs randomized tests via
`script/randomized-test-ci` | Max Brunsfeld | never | Never run; only
triggers on pushes to a branch that is never pushed |
| `compare_perf.yml` \* | Manual perf comparison between two commits for
a crate | Conrad Irwin | 2025-11-06 | Dormant >90 days; on-demand tool |
| `run_unit_evals.yml` \* | Manual agent unit evals for a given
model/commit | Ben Kunkle | 2025-11-14 | Dormant >90 days; on-demand
tool |
| `run_cron_unit_evals.yml` \* | Agent unit evals across a model matrix
(manual dispatch) | Richard Feldman | 2026-01-27 | Dormant >90 days;
on-demand tool |
\* xtask-generated — removed via `tooling/xtask` and regenerated (commit
2).
## Notes
- **Commit 1** removes the four hand-written workflows.
- **Commit 2** removes the three xtask-generated workflows: it deletes
their generator modules and registry entries, regenerates with `cargo
xtask workflows`, and drops the helper code left unused by the removal
(`vars` secrets and `steps::git_checkout`). Regeneration is a no-op for
all other workflows, and `./script/clippy` (deny-warnings) is clean.
Release Notes:
- N/A