Stacked on top of #57430.
When the `sandboxing` feature flag is on (macOS only), agent-run
terminal commands are launched under `/usr/bin/sandbox-exec` with a
per-command Seatbelt policy:
- **Reads:** any path on the filesystem.
- **Writes:** each project worktree plus a per-command `$TMPDIR`.
- **Network:** blocked.
The model can request relaxations on individual calls via three new
input flags on the `terminal` tool:
- `allow_network: true`
- `allow_fs_write: true`
- `unsandboxed: true`
Each one triggers a separate always-prompt user approval (bypassing any
`always_allow` rules, since escalation is a stronger trust boundary than
the baseline command approval). The flags are silently ignored when
sandboxing is off, so the model can't surreptitiously change runtime
behavior by setting them in the no-op case.
The per-command tempdir is provisioned regardless of sandbox state so
the model can't infer whether the sandbox is in effect by looking at
`$TMPDIR`.
The Seatbelt config file's lifetime is tied to the `Terminal` entity via
an opaque RAII handle (`SandboxConfigHandle = Box<dyn Any + Send>`), so
cancellation paths drop it automatically.
### Notes for review
- The writable scope passed to the sandbox is the project's worktree
paths plus the per-command tempdir, **not** the resolved `cd` working
directory — `cd` is model-controlled, and using it as the writable scope
would let the model widen its own write permissions outside the project.
- The new tool flags are always present in the JSON schema (with
`#[serde(default)]`), even when the sandbox prompt section isn't
rendered. The system prompt only documents them when the section is
present, so the model shouldn't try to use them when it's not — but the
schema doesn't actively reject them, just ignores them.
- I opted not to add an end-to-end test for the escalation prompt path:
the existing `FakeThreadEnvironment` ignores the new params and toggling
the feature flag in tests is more wiring than felt worth it for a first
cut. The pure-function pieces (`sandbox_approval_title`, schema,
deserialization) are covered, and the sandbox crate itself has
end-to-end tests that actually invoke `sandbox-exec`.
Release Notes:
- N/A
---------
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Stacked on top of #57429.
Adds a new `sandboxing` feature flag (off for staff by default) and a
single source-of-truth helper `sandboxing_enabled(cx) = cfg!(target_os =
"macos") && cx.has_flag::<SandboxingFeatureFlag>()`. When the helper
returns true, the agent's system prompt gains a new `## Terminal
sandbox` section that:
- Lists each worktree's absolute path as a writable directory.
- Describes the per-command `$TMPDIR` scratch directory.
- States that outbound network access is blocked.
- Documents the three per-command flags (`allow_network`,
`allow_fs_write`, `unsandboxed`) the model can request to relax the
sandbox.
- Tells the model the section is stable for the duration of the
conversation.
When the flag is off, the section is omitted entirely — no mention of
sandboxing at all.
No behavior change to terminal execution yet; that's the next PR in the
stack.
Three new tests cover: section omitted when `sandboxing: false`, section
rendered with all worktrees + flag docs when `sandboxing: true`, and the
zero-worktrees case.
Release Notes:
- N/A
---------
Co-authored-by: MartinYe1234 <52641447+MartinYe1234@users.noreply.github.com>
Co-authored-by: Martin Ye <martin@zed.dev>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] ~Unsafe blocks (if any) have justifying comments~ (N/A)
- [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 (didn't add new test for
parsing SHA-256 - not sure if would be desired)
- [x] Performance impact has been considered and is acceptable
Closes#24070
Upgrades git2 from 0.20.1 to 0.21.0 with the `unstable-sha256` feature -
adds ability to open and work with git repositories using the SHA-256
object format. `Oid::from_str` now detects 64-char hex strings to parse
SHA-256 OIDs correctly.
Also adapts to breaking API changes in 0.21.0:
`Remote::url()` and `Commit::message()` both now return `Result`.
Release Notes:
- Added support for opening SHA-256 object format git repositories
Adds a new `sandbox` crate that wraps shell invocations under macOS's
`sandbox-exec(1)` with a Seatbelt policy built from per-command
permissions:
- Reads are unrestricted.
- Writes are restricted to a caller-provided list of directories (plus
the standard `/dev/*` write targets).
- Network access and unrestricted filesystem writes must be opted into
per command.
`wrap_invocation(program, args, writable_dirs, permissions)` returns the
new program/args plus a `SeatbeltConfigFile` RAII handle that deletes
the on-disk policy file when dropped — callers hold it for the lifetime
of the spawned command.
No callers yet — this is the first of three stacked PRs. The second
wires the sandbox state into the agent's system prompt behind a feature
flag; the third wires the actual wrapping into the agent terminal tool.
The macOS-only dependencies (`tempfile`, `anyhow`) are gated by
`target.'cfg(target_os = "macos")'` so the crate is empty on other
platforms.
Includes 14 tests covering both the generated Seatbelt policy text and
end-to-end behavior (actually invoking `sandbox-exec` and asserting
reads/writes succeed or fail per policy).
Release Notes:
- N/A
Removes a leftover test label added by #56065
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
Follow-up to #57772.
While comparing the `edit_file_tool_streaming/medium_insertions`
benchmark in Criterion and xctrace, I noticed the DP scoring loop was
spending most of its time on inlined `Matrix::get`/`Matrix::set` access
in `StreamingDiff::push_new`.
This changes the loop to split the previous and current score columns
once per DP column and then index those column slices directly. This
keeps the scoring algorithm the same, but hoists the column offset
calculation out of the inner loop and gives the compiler clearer
aliasing information between the immutable previous column and mutable
current column.
In xctrace, the hottest DP scoring line dropped from 10,407 samples
before to 9,409 samples after on
`edit_file_tool_streaming/medium_insertions`, and total
`StreamingDiff::push_new` leaf samples dropped from 10,800 to 9,822.
This is consistently faster in the end-to-end `edit_file_tool`
benchmark, and gives a small speed-up for the targeted workload without
changing the scoring algorithm.
### Results
Benchmarked with `release-fast` against a clean baseline using
Criterion’s `before_slice` baseline.
#### `streaming_diff_push_new`
| Fixture | Before median | After median | Change |
| --- | ---: | ---: | ---: |
| `tiny_function_rewrite` | `7.6317 ms` | `6.4951 ms` | 10.8% faster |
| `small_function_rewrite` | `45.961 ms` | `44.839 ms` | No significant
change |
| `medium_many_small_changes` | `99.694 ms` | `104.83 ms` | 5.2% slower
|
| `medium_insertions` | `95.909 ms` | `83.093 ms` | 13.5% faster |
#### `edit_file_tool_streaming`
| Fixture | Before median | After median | Change |
| --- | ---: | ---: | ---: |
| `tiny_function_rewrite` | `1.1110 ms` | `1.0617 ms` | 7.1% faster |
| `small_function_rewrite` | `2.4554 ms` | `2.2751 ms` | 7.1% faster |
| `medium_many_small_changes` | `87.272 ms` | `77.065 ms` | 11.5% faster
|
| `medium_insertions` | `92.469 ms` | `87.478 ms` | 5.9% faster |
The lower-level `streaming_diff_push_new` benchmark is mixed, but the
end-to-end `edit_file_tool_streaming` workload improves across all
fixtures.
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 or Added/Fixed/Improved ...
Two model updates:
- **Free**: Big Pickle now has a max output tokens of 32k as per
49991c8f8f
- **Go**: added Qwen3.7 Max as per
4f1d5c511a
and
1554a5a82e (diff-a7ee7cf35b40335095a44cfaac16041313c36322cd14544ddad0289ce69131ab).
Tested this successfully by running a simple "_rename this variable for
me. add a function. delete the function_" 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 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:
- OpenCode: updated models (added Qwen3.7 Max, updated Big Pickle token
counts)
GPUI AccessKit integration
This PR is replacing #51097 , and is much more limited in scope. This PR
*ONLY* adds AccessKit support to GPUI, and doesn't touch Zed. Once this
lands, we can start adding aria attributes to Zed's components.
This PR is the first step to addressing #41138 .
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: John Tur <john-tur@outlook.com>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
This PR is a follow-up to #54206 to make it so we only respect the
feature flag overrides for Zed staff (or when running a development
build).
Previously just the UI portion of the feature flags was disabled for
non-staff, but manipulating the settings file by hand would still allow
setting overrides that would be respected.
The only other setting on the "Developer" page of the settings UI was
the performance profiler. This was previously only available for staff,
as the entire "Developer" page was limited to staff, but it seems
reasonable to allow non-staff to see this.
Release Notes:
- N/A
This PR uses the status toast for the Skill Creator confirming action as
opposed the regular message notification. Aside from it looking a bit
better, it's also auto-dismissed, which is preferred in this case.
Release Notes:
- Improved skill creation toast confirmation by making it
auto-dismissed.
---------
Co-authored-by: Martin Ye <martin@zed.dev>
Don't panic when a diff transform boundary falls inside a multi-byte
UTF-8 character. Round split points up to the next char boundary and
advance past any transform boundaries skipped by that adjustment.
Closes FR-16
Release Notes:
- Fixed a crash when deleting words near inline diff boundaries
containing multi-byte characters
## Motivation
Miniprofs of Zed dropping frames showed foreground thread stalls of
711.56 ms, 641.01 ms, and 221.99 ms from the `edit_file_tool`. The new
benchmark isolated `StreamingDiff::push_new` as one of the expensive
phases so this PR aims to speed it up so we can avoid dropping more
frames in the future.
## Benchmark methodology
I had an agent create a Criterion suite with four deterministic Rust
edit fixtures: tiny localized rewrite, small localized rewrite, many
small changes, and helper block insertions.
Benchmarked with:
```sh
cargo bench -p streaming_diff --bench streaming_diff --profile release-fast -- --warm-up-time 1 --measurement-time 2
```
The benchmark binary was also recorded under `xctrace` CPU Counters to
inspect CPU samples before and after the change.
## Results
`StreamingDiff::push_new` improved across all fixtures:
| Benchmark | Before | After | Improvement |
|---|---:|---:|---:|
| `tiny_function_rewrite` | ~10.81 ms | ~6.91 ms | ~36% faster |
| `small_function_rewrite` | ~51.02 ms | ~35.39 ms | ~31% faster |
| `medium_many_small_changes` | ~130.71 ms | ~83.83 ms | ~36% faster |
| `medium_insertions` | ~120.52 ms | ~79.90 ms | ~34% faster |
The `xctrace` baseline showed samples in `Hash::hash`,
`RandomState::hash_one`, `HashMap::insert`, and
`RawTable::reserve_rehash`. After replacing the map with two `Vec<u32>`
row buffers, the hash table frames disappeared from the top samples.
The speedup comes from removing hash work from the DP inner loop and
replacing scattered hash table probes with contiguous row buffer access
(better cache hits 🏎️). The trace did not include direct cache miss
counts, but this layout is likely more cache friendly because it
replaces hash table access with a continuous line of memory (the
`Vec`s).
Release Notes:
- N/A
## Summary
- Track existing skill file contents and instruction bodies before
migrating Rules to Skills
- Skip writing migrated skills when an equivalent skill already exists
- Cover duplicate detection across differently named skills
## Tests
- cargo test -p prompt_store rules_to_skills_migration
Release Notes:
- Fixed duplicate Skills being created when migrating Rules.
Until now, the cloud-hosted model list was only refreshed in response to
events that exercise the LLM token (a `UserUpdated` push, an
organization change, or `PrivateUserInfoUpdated`). If a user wasn't
actively using AI features around the time we shipped new models, the
list could stay stale until they restarted Zed.
This is the second step toward fixing that, after #57078 made the cloud
websocket reconnect on its own. We now treat each successful (re)connect
as a hint that the server state may have changed, so possibly new model
definitions will be available, and trigger a model list refresh.
The trigger is a new `Client::cloud_connection_id()` watch that bumps a
counter each time the websocket handshake completes.
`CloudLanguageModelProvider::State` subscribes to it and, on every tick
after the initial `0`, schedules a debounced refresh (with jitter, so we
don't have all active clients trying to reconnect at the same time after
we deploy in cloud).
Closes CLO-713.
Release Notes:
- The list of Zed hosted models is now refreshed automatically, without
requiring a restart
<img width="620" height="172" alt="Screenshot 2026-05-27 at 12 08 26 PM"
src="https://github.com/user-attachments/assets/226b3d0c-003b-44ac-a16f-10af4f2952b3"
/>
Add command palette actions for opening global and project-specific
AGENTS.md files
Closes AI-324
Release Notes:
- Added commands to open global and project-specific AGENTS.md rules
Stop trying to add new watches for 5 seconds after receiving the "OS
file watch limit reached" error.
This was flooding the logs and many pointless syscalls.
Related to #57422, #57042, FR-18
Release Notes:
- Improved file watcher behavior when the OS file watch limit is
reached.
Closes#47251
Fix dot (`.`) repeat not correctly repeating the last change after
replaying a macro (`@register`)
([#47251](https://github.com/zed-industries/zed/issues/47251))
When replaying a macro that contains text insertions,
`replay_insert_event` calls `handle_input` directly and never emits
`InputHandled`, so the `observe_insertion` subscription never fires.
This left the dot register stale — `.` after `@register` would repeat an
earlier change instead of the last one made by the macro.
Fix by calling `observe_insertion` explicitly in the
`ReplayableAction::Insertion` branch of `Replayer::next`.
Release Notes:
- Fixed dot (`.`) repeat not repeating the last change made by a macro
(`@register`).
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Tiny UI tweak here to improve the label/traffic lights alignment in the
skills creator header.
Release Notes:
- N/A
Co-authored-by: Martin Ye <martin@zed.dev>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Needed for use in cloud
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
Release Notes:
- agent: Fixed an issue where commit message generation would not
respect instructions from global `AGENTS.md`
---------
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Also adds a menu item called "Rules Library" that takes to the
documentation, which will explain the removal of the feature as a whole.
Release Notes:
- N/A
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Extends the same `~/.agents/skills` special case that
`create_directory`, `edit_file`, and `write_file` already use to the
path tools, so the agent can copy or move skills into and out of the
global skills folder and delete individual skills or skill resources
beneath it.
- `copy_path` now allows source and/or destination to be a descendant of
`~/.agents/skills`, going through `fs::copy_recursive` directly when one
side is outside the project.
- `move_path` now allows source and/or destination to be a descendant of
`~/.agents/skills`, going through `fs.rename` directly when one side is
outside the project. Moving the `~/.agents/skills` root itself is
rejected.
- `delete_path` now allows deleting any file or directory beneath
`~/.agents/skills`, going through `fs.remove_dir` / `fs.remove_file`
directly. Deleting the `~/.agents/skills` root itself is rejected.
- All three tools still always prompt for approval on agent-skill paths,
even when default tool permissions are set to allow.
- Added shared helpers in `tool_permissions.rs` for resolving global
skill descendants and rejecting operations on the skills root where
needed.
- Added tests covering copying and moving skills in both directions,
deleting a global skill directory/file, and rejecting deletion of the
skills root.
Release Notes:
- Agent can now copy or move skills into and out of `~/.agents/skills`
and delete individual skills, with an explicit confirmation prompt for
each operation
Follow-up to #57466 simplifying `load_skill_frontmatter` rather than
fixing a separate bug.
#57466 fixed the chunked-read loop so it truncates accumulated bytes at
the frontmatter boundary, preventing `str::from_utf8` from failing on a
multi-byte grapheme split across chunks. That fix is correct, but the
chunked read it's working around isn't pulling its weight:
`MAX_SKILL_FILE_SIZE` is 100KB and there's already a metadata pre-check,
so "stop reading early once we've seen the closing `---`" saves at most
~25 pages per file while forcing the use of `open_sync`, a hand-rolled
loop, and a long comment about `smol::unblock` vs the GPUI test
scheduler.
This PR:
- replaces the chunked `open_sync` + read loop with a single
`fs.load(...)` call (the same primitive `read_skill_body` already uses);
- deletes `closing_delimiter_end`, `SKILL_READ_CHUNK_SIZE`, the
`std::io::{self, Read}` import, and the `Parking forbidden` paragraph;
- tightens the metadata pre-check so a metadata error (permissions, I/O,
etc.) bails out instead of silently falling through to a blind read;
- removes the now-obsolete
`test_load_skill_frontmatter_with_emoji_at_chunk_boundary` test — by
construction, a single full read can't split a UTF-8 sequence at any
boundary.
Closes AI-303
Release Notes:
- N/A
The Skill Creator window previously couldn't be resized — its minimum
size was set to the same dimensions as its initial size, so users
couldn't make it smaller or shorter. Its contents also didn't scroll, so
on smaller windows the Skill Content editor would be squeezed below its
usable size.
This change:
- Lowers the window's minimum size to 500×420 so it can be resized in
both directions.
- Wraps the form body in a scrollable container with a vertical
scrollbar.
- Replaces `flex_1 + min_h_0` on the form fields and Skill Content
wrapper with `flex_grow + flex_shrink_0`. Combined with the existing
`min_h(160)` on the body editor, this means:
- When there's extra vertical space, the Skill Content editor grows to
fill it.
- When the window is short, the form keeps its content at natural size
and the outer container scrolls instead of crushing the editor.
Closes AI-315
Release Notes:
- Made the Skill Creator window resizable and its contents scrollable
when the window is smaller than the form.
It look like this:
<img width="1698" height="688" alt="grafik"
src="https://github.com/user-attachments/assets/02a37271-63d3-42da-887f-e17b31e8d9ca"
/>
The idea is to avoid people turning on fast mode without understanding
the financial implications. It also clarifiers (in the BYOK case) why
they might not see a difference between fast mode enabled and disabled.
Release Notes:
- N/A
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
async_tasks can build a cycle with the scheduler where the runnable
itself keeps a reference to the scheduler and the scheduler keeping
references to the runnable. This effectively can cause scheduler / task
leaks, most notably in test environments, so we break this cycle by
using weak pointers instead.
Release Notes:
- N/A or Added/Fixed/Improved ...
Same mechanism as for BYOK: `service_tier == priority`. Most of the work
is already done. When validating this in manual testing, I noticed we
get back `service_tier == auto` in the response, unlike in the regular
OpenAI API scenario with BYOK, but apparently [it doesn't mean priority
tier wasn't
applied](https://github.com/openai/codex/issues/14204#issuecomment-4033184620).
It's not a hard confirmation, but the model does seem to respond faster
when I toggle fast mode on.
Release Notes:
- Added Fast Mode (priority service tier) support to OpenAI models used
through the ChatGPT subscription provider.
Maps the existing `Speed::Fast` plumbing to OpenAI's `service_tier:
"priority"`, which matches what "fast mode" in Codex does. Relevant docs
[here](https://platform.openai.com/docs/api-reference/chat/create#chat-create-service_tier).
Like for the existing Anthropic fast mode we have a
`Model::supports_priority` method for the variants on
https://openai.com/api-priority-processing. Pro, nano, and legacy gpt-4
are excluded; Custom defaults to false.
This is gated to staff only for now (not in this diff, but the existing
fast mode feature), until we have the mechanism to require confirmation
before you enable fast mode.
Release Notes:
- Added support for Fast Mode (priority service tier) on the OpenAI API
provider.
> [!NOTE]
> Authored by Claude, but fixes a real issue I encountered; I have
reviewed the diff
Some npm registries return `npm info --json` with non-string values in
the `time` map. JFrog Artifactory emits `"unpublished": null`, and npm
itself represents `unpublished` as an object for packages that have had
versions unpublished.
Because `NpmInfo.time` was typed `HashMap<String, String>`, serde
aborted the entire deserialization with `invalid type: null, expected a
string`. As a result `select_npm_package_version` never ran, and
language servers installed via npm (for example the tsgo extension,
`tailwindcss-language-server`, and `json-language-server`) failed to
start with an error like:
```
Failed to start language server "tsgo": invalid type: null, expected a string at line 100 column 23
```
Only version keys in `time` are ever read (to honor npm's `before`
cutoff), so this deserializes the map leniently: keep the string-valued
entries and drop the rest. The field type and all downstream logic are
unchanged. Added a regression test covering a `time` map containing
`"unpublished": null`.
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
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed language servers failing to install when the npm registry
returns non-string values (such as `"unpublished": null`) in package
`time` metadata
Summary
- Display the full path for global skill files in the agent edits
summary when they do not have a project-relative file name.
Closes AI-320
Validation
- cargo check -p agent_ui --lib
Release Notes:
- Fixed global skill edits appearing without a file path in the agent
changes summary.
Zed reloads a lot of data about a git repository any time any file
changes inside of the `.git` directory, with the exception of a few
known paths that we know do not warrant a reload, such as `index.lock`
and `COMMIT_MESSAGE`. Previously, we ignored FS events for those files,
but we used a specific path that only worked for the main worktree. This
caused a lot of unnecessary reloads when using linked worktrees. Now we
ignore those files in a general way, by their filename, so that the
optimization applies to linked worktrees as well.
@cole-miller Noticed this bug.
Release Notes:
- Fixed unnecessary reloading of Git state that could occur when editing
in linked worktrees.
Summary
- Allow write_file and edit_file to create or modify files under
~/.agents/skills.
- Keep the global skills exception constrained to that directory and
preserve existing project-path behavior.
- Document global skill file editing support in the built-in
create-skill instructions.
Tests
- cargo fmt -p agent
- cargo test -p agent global_skill_file
- cargo test -p agent
test_create_directory_allows_global_skill_directory
Release Notes:
- Fixed agent file editing for global skills
---------
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
This change caps remote log size at 1MB and maintains one rotated file.
Before this change, remote logs were growing indefinitely, leading to
issues like #57042 and #57422Closes#57422
Release Notes:
- Fixed remote server logs growing unbounded
On Linux, we create a filesystem watcher recursively for every subdir.
When we get "fs watcher lost sync" events, we used to log it for every
child dir, which could results in thousands messages. This becomes
problematic when we get into a state where we get those events
repeatedly (this larger issue is to be addressed separately).
Now we log one message per parent.
Partially addresses #57422, #57042, FR-18
Release Notes:
- N/A
The `agent_profile_switched` event fired from the profile picker was
using snake_case instead of the title case used by every other agent
telemetry event. This caused it to land in Amplitude as a separate event
from the `Agent Profile Switched` event fired by keyboard cycling,
making it impossible to track profile switches in a single chart.
Renames the event to `Agent Profile Switched` to match. The `source`
property (`"picker"` vs `"cycle"`) still distinguishes the two code
paths.
Release Notes:
- N/A
`register_server_capabilities` / `unregister_server_capabilities` had no
arm for `textDocument/documentLink`, so when a server saw our
`documentLink.dynamicRegistration` capability and chose to register the
provider dynamically, the registration silently fell into the `unhandled
capability registration` warning. `document_link_provider` stayed
`None`, `GetDocumentLinks::check_capabilities` returned false, and no
`textDocument/documentLink` request was ever sent.
Follow-up to https://github.com/zed-industries/zed/pull/56011
Release Notes:
- N/A
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary:
- Added a rename action for agent threads in the sidebar.
- Persisted renamed thread titles and kept open thread views in sync.
Release Notes:
- Improved agent threads by allowing them to be renamed directly from
the sidebar.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (I am not adding
new unsafe blocks)
- [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 (Should I add a test for
this?)
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- Added Recognizing HIP files as C++
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
Matches behavior from selectors between Zed + external agents.
Also means they will persist across worktree creation 🎉
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
rust-analyzer does not really attempt to be backwards compatible, so
when users opt-into the component a toolchain override, we should prefer
that over any other rust-analyzer (especially our own) for better
toolchain compatibility in case people have a more out of date install.
This mirrors the VSCode extension behavior
Release Notes:
- When a worktree contains a Rust toolchain file with a rust analyzer
component specified, Zed will now spawn the given toolchain's
rust-analyzer for toolchain compatability
The threads sidebar rebuilds its `Vec<ListEntry>` from scratch on events
that touch thread/sidebar state (status changes, title generation, new
live info, sending a message, etc.). It previously called
`ListState::reset` after every rebuild, which rewrote every list item to
`Unmeasured`. On the next render frame, the sticky project header had no
measured bounds for the next project header.
The sticky project header uses `ListState::bounds_for_item` for the next
project header to compute how far it should be pushed off screen. When
those measurements were missing, it temporarily fell back to `top_offset
= 0`, snapped fully into view for one frame, then popped back once the
list was remeasured.
Fix: preserve list measurements for entries whose identity and layout
shape did not change. `EntryShape` captures each entry's identity plus
height-affecting project-header flags. `update_entries` snapshots the
old shapes, rebuilds contents, then splices only the changed shape range
into `ListState`. Unchanged items keep their measured bounds, so the
sticky header remains in its pushed-off position across same-shape
updates.
This also adds a regression test that renders a two-project sidebar,
scrolls into the sticky-header push-off state, performs a same-shape
thread metadata update, and verifies the next header's measured bounds
are preserved.
Closes AI-196
Release Notes:
- Fixed the project section header flickering in the agent threads
sidebar when sending a message while the header was partially scrolled
off screen.
This PR adds support for inset shadows in the box shadow through the
`inset: true` field. It includes support for both the macOS as well WGSL
shaders. For now, there is no immediate application of it in Zed, so
nothing should change in the app.
<img width="600" alt="Screenshot 2026-05-25 at 8 46@2x"
src="https://github.com/user-attachments/assets/db564a6b-8af5-491a-a573-17c060a3647c"
/>
Run the example above with `cargo run --example shadow -p gpui`.
Release Notes:
- N/A
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
When creating a git worktree, we now always fetch latest `origin/main`
and create the worktree based on that. If running `git fetch` fails, we
show an error toast with the option to base the worktree of off local
`origin/main`:
<img width="530" height="45" alt="image"
src="https://github.com/user-attachments/assets/f9ae4c05-8c2c-44f3-9c14-3c291a9d82f6"
/>
Release Notes:
- git: Always create worktrees based on latest `origin/main`
Resolves https://github.com/zed-industries/zed/issues/57522
This diff fixes `r` in Helix select mode. The keybinding already pushed
the replace operator in `helix_select`, but when the replacement
character was typed, the operator dispatch only handled `HelixNormal`,
so selected text in `HelixSelect` fell through and cleared the operator
without editing the buffer.
With this change, Helix select mode uses the same `helix_replace` path
as Helix normal mode. Multi-character selections now replace each
selected grapheme with the typed character and return to Helix normal
mode, matching the existing behaviour for Helix normal selections.
Release Notes:
- Fixed `r` not replacing multi-character selections in Helix select
mode.
Ensures that we show the error message of the `edit_file`/`write_file`
tools in the UI
Release Notes:
- agent: Fixed an issue where errors would not show up in the UI if an
edit tool call failed
Resolves https://github.com/zed-industries/zed/issues/57486
This diff fixes `g w` after selecting lines with `x` in Helix mode. `x`
leaves Zed in Helix normal mode with a non-empty selection, but jump
target collection treated non-visual selections as ranges to skip. As a
result, words on the selected line did not receive jump labels.
With this change, Helix normal mode keeps existing selection ranges
eligible for jump targets, matching Helix's behavior where normal mode
can still carry selections. The regression covers `x` followed by `g w`
targeting a word inside the selected line.
Release Notes:
- Fixed `g w` not targeting words on lines selected with `x` in Helix
mode.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
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
Closes#55939.
Release Notes:
- Fixed commit modal buttons being hidden for `ui_font_size` values
I use the One Dark theme, so to actually test if my fix worked, I had to
also do:
```jsonc
"experimental.theme_overrides": {
"warning": "#ff0000",
"modified": "#00ff00",
},
```
| Before | After |
|--------|--------|
| <img width="676" height="254" alt="image"
src="https://github.com/user-attachments/assets/a2831667-1113-49ac-b6aa-1221c71bf997"
/> | <img width="299" height="137" alt="image"
src="https://github.com/user-attachments/assets/ad6e85aa-ba24-47ad-b69d-6d0c3aa3a407"
/> |
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
- [ ] Performance impact has been considered and is acceptable
Closes#57443.
Release Notes:
- Fixed Project Panel git status indicator showing modified files with a
warning color instead of the modified color
Instead of mixing row dimensions accidentally, this will now target the
rows in the current active excerpt, clamping to the nearest excerpt if
out of bounds.
Release Notes:
- Fixed go to line going to arbitrary lines in multibuffers
Fixed width mode wouldn't reliably take the sidebar width into account
when laying out the content of the agent panel. This fixes it
Release Notes:
- N/A or Added/Fixed/Improved ...
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
For long threads we will spend more and more time cloning the messages
just to save them to the database, as we need a copy of everything to do
so asynchronously. Messages are really expensive to clone though and we
accumulate a lot of them really fast, so even for smaller threads we
start seeing pauses in the millisecond range. The fix to this is fairly
simple though, we never mutate the messages once pushed to the vec, so
just Arc them.
This PR also slightly changes `UserMessage` to be a bit faster to clone
as well.
Release Notes:
- Fixed a cause of stutters when interacting with the agent
We were sending the `speed` field set to `"standard"` for BYOK Anthropic
but without the corresponding beta header. leading the requests to fail
with "invalid request format to Anthropic's API: speed: Extra inputs are
not permitted".
This makes sure to attach the beta header whenever the `speed` parameter
is used.
Release Notes:
- Fixed "speed: Extra inputs are not permitted" errors for Opus 4.6 and
4.7 in the Anthropic API provider.
## Context
This PR updates a misleading comment in the remote edit merge path in
the text CRDT.
At `crates/text/src/text.rs`, the code skips fragments when
`fragment.timestamp > timestamp`, but the comment described this as
"lower lamport timestamp." In this codebase, Lamport ordering is
ascending (`value`, then `replica_id`), so `>` means a higher Lamport
timestamp.
This change is comment-only and does not change runtime behavior.
## How to Review
1. Open `crates/text/src/text.rs` and inspect the updated two-line
comment above the `while let Some(fragment) = old_fragments.item()` loop
in `apply_remote_edit`.
2. Confirm the condition directly below is unchanged:
`fragment.timestamp > timestamp`.
3. (Optional) Cross-check Lamport ordering in
`crates/clock/src/clock.rs` (`impl Ord for Lamport`) to confirm the
wording.
## 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 (comment-only change; no
behavior changes)
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
Co-authored-by: Lukas Wirth <lukas@zed.dev>
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#53486
Note that this builds off of #55117 because both touched similar code
areas; I thought it best to in order to avoid conflicts.
Release Notes:
- Added support for local features in dev containers
Closes#53266
When a tool call awaiting permission is below the viewport, it’s easy to
miss why the agent has stopped working. This PR adds a floating row at
the bottom of the panel that mirrors the pending permission request.
It reuses the same permission prompt, so you can allow or deny it and
see the raw input without scrolling to the end of the thread. It offers
a "Scroll to" button to jump back to the inline prompt in the thread.
Once the inline prompt is in view, the floating row disappears. If
multiple tool calls need permission, including a subagent’s, they’re
shown one at a time so rows don’t stack on top of each other.
<img width="508" height="181" alt="image"
src="https://github.com/user-attachments/assets/7d5fedd6-bc4d-4674-8ea2-5c8f2ed3aff6"
/>
Release Notes:
- Improved visibility of pending tool call confirmations in the Agent
Panel when its scrolled out of view.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
When restarting Zed, I hit a bug where all Git operations were hung. I
realized that there was a hanging git process running `git cat-file
--batch-check=%(objectname)`. The process was waiting on stdin. This was
surprising, because [the
code](e2bbdb19b6/crates/git/src/repository.rs (L1665-L1709))
that spawns this process explicitly closes the pipe that is attached to
the process's stdin after writing a list of ref names.
Using Claude, I found that this could be caused by that pipe file
descriptor being cloned due to file descriptor inheritance when another
child process is `exec`'d while that stdin pipe is open. The fix is to
enhance our Darwin process spawning layer to set the close-on-exec flag
for the pipe file descriptors, so that they are not inherited by child
processes spawned using code paths that don't set
`POSIX_SPAWN_CLOEXEC_DEFAULT`.
Release Notes:
- Fixed a bug on macOS where Git operations could be blocked depending
on the timing of spawning child processes.
This PR changes the git store's `compute_snapshot`, which runs to update
state that depends on the contents of `.git`, to degrade gracefully when
fetching individual pieces of state fails. For example, when fetching
the list of branches fails, instead of returning early from the function
(leaving the previous git state snapshot in place with stale state), we
continue with an empty list of branches. This prevents failures of
individual git commands from making the entire git UI get stuck
indefinitely.
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:
- Fixed an issue where failing to fetch branches using the git CLI would
prevent other git-related state from being updated.
When viewing the diff for a commit where one of the files has a large
number (hundreds or thousands) of diff hunks, we can get a hang on the
main thread, since there's a large amount of work to recompute diff
transforms for thousands of excerpts. This PR makes it so that we batch
the addition of excerpts, with yield points in between batches so the UI
remains responsive.
We should have something similar for the project diff, but that's a bit
trickier; will address it in a separate PR.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Improved performance when opening the commit view with files that have
many diff hunks.
Following up on our recent extension outage, this PR adds an action to
quickly visit our status page (which with the help of @\gaauwe was
recently updated to a more up to date design 🎉 ).
While already invokable through the command palette, we can later use
this to also add buttons where appropriate for a quick lookup of our
current status.
Release Notes:
- Added the `zed::OpenStatusPage` action to be able to easily visit the
Zed status page.
cc @cole-miller
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- Fixed branch enumeration when a broken Git ref prevents commit
metadata from being read.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Summary:
- Added a rename action for agent threads in the sidebar.
- Persisted renamed thread titles and kept open thread views in sync.
Release Notes:
- Improved agent threads by allowing them to be renamed directly from
the sidebar.
When shift is held during a single click, extend the existing selection
from its anchor point to the clicked position instead of starting a new
selection.
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:
- Added markdown support shift+click to extend text selection
When generating a training or evaluation example with `ep split-commit`,
the cursor sampling logic becomes:
1. 80% chance of cursor being at the end of the source patch
2. 20% chance of cursor being at the beginning of the target patch
3. 20% chance of adding a jitter offset (same line, ±5 columns for now)
Release Notes:
- N/A
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
- [x] Performance impact has been considered and is acceptable
Resolves the issues described at
https://github.com/pop-os/cosmic-text/releases/tag/0.19.0
This fix addresses the characters '\u{001C}' | '\u{001D}' | '\u{001E}' |
'\u{0085}' | '\u{2029}', which can cause the Editor gpui-component to
crash, as these characters can cause the 'assert "left == right"'.
Release Notes:
- N/A
This is useful when running tests for a large number of iterations
noninteractively
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
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- Fixed an issue where edit prediction previews that appeared in the
diff popover could be occluded by open docks or the sidebar on the right
side of the editor
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#57463
Release Notes:
- Fixed utf-8 parsing issues when loading skill frontmatter with
multi-codepoint graphemes (such as an emoji) crossing file chunk load
boundaries.
Format `read_file` tool output in `cat -n` style: each line is prefixed
with its line number right-aligned in a 6-character field, followed by a
single tab, followed by the line's original content (newlines preserved,
including CRLF). Numbering reflects the actual file lines, so a ranged
read starting at line 42 emits `42` for its first line, not `1`.
For large files, content returned by `get_buffer_content_or_outline` is
**not** prefixed:
- The symbol outline path already conveys structure via its `[L100-150]`
annotations.
- The truncated first-1KB fallback (used when a file exceeds
`AUTO_OUTLINE_SIZE` and has no parseable outline) is wrapped in a
synthetic `# First 1KB of …` header, so its lines don't correspond to
real file line numbers.
Both cases are reported via `BufferContent::is_synthetic` (renamed from
`is_outline`).
Also updates the `edit_file` tool's input doc to describe the prefix
format and tell the model to strip it before constructing `old_text` /
`new_text`, preserving the original indentation that appears after the
tab.
Updates how we render `read_file` tool call outputs in the UI
(screenshots included in comments below).
Also fixes an existing bug where `read_file` tool call outputs would not
re-render their content code block when an older thread was restored
(the tool's `replay` hook was missing).
Closes AI-226
Release Notes:
- Improved how `read_file` tool output renders in the agent panel, with
a line-number gutter, and fixed it not re-rendering on restored threads
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
If the agent server supports it, we pass along the multiple directories.
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#54480
Release Notes:
- acp: External agents that support it now have access to all working
directories in a project.
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: Add Logout flow for agents that support it.
The circular progress in the agent panel's message editor would
previously display the number of default user rules auto-embedded into
the thread. However, given default rules are all migrated to a global
AGENTS.md file, that feature doesn't make a lot of sense anymore. So,
this PR fixes it by adding a button that opens up the global file when
it exists.
Release Notes:
- N/A
Tiny changes: improving keyboard nav by fixing the tab order, and
improving styles by making the dropdown take just the width of the label
instead of a fixed width.
Release Notes:
- N/A
Quick follow-up to https://github.com/zed-industries/zed/pull/57322. We
weren't removing the pending notification when re-visiting the project
that contains the pending thread (only while the project is still
collapsed, though).
Release Notes:
- N/A