This PR builds out GPUI's benchmark harness so render benchmarks measure
realistic frame costs using GPUI-owned, runtime-gated instrumentation.
It adds measurements for frame draw time, dirty-to-draw latency,
invalidation coalescing, and frame-budget overruns, and runs benchmark
workloads with production-like concurrency.
## How it works
**Frame timings flow through the GPUI profiler.** `Window::draw` emits a
`FrameTiming { window_id, dirty_at, invalidations, draw_start, draw_end
}` event into a global ring buffer in `gpui::profiler`, mirroring the
existing task-timing channel. Collection is runtime-gated by
`profiler::set_frame_trace_enabled` (one relaxed atomic load when
disabled — no `Instant::now` calls in production). `BenchReport` is a
pure listener: it drains events through a cursor-based
`FrameTimingCollector` and builds histograms in the bench layer.
`Window` carries no bench-only cfg fields, and the same event channel
can later feed the miniprofiler UI or an in-app frame-time HUD.
**`BenchDispatcher`** is a multithreaded `PlatformDispatcher` for
benchmarks: background tasks run on a worker pool (same priority queue
as `LinuxDispatcher`, with task-profiler hooks), timers fire in real
time on a dedicated thread, and foreground tasks queue until the bench
thread drains them with a blocking `run_until_idle()`. Unlike
`TestDispatcher`, work executes in parallel in real time, so wall-clock
measurements reflect production concurrency. In-flight accounting is
panic-safe via drop guards.
**`gpui::bench_platform()`** returns a per-process `TestPlatform` backed
by the `BenchDispatcher`, cached in a thread-local so worker threads
persist across Criterion calibration passes. This replaces the earlier
approach of constructing a real platform per invocation, which had
process-global singleton issues, never ran foreground tasks (no run loop
pumped the main queue), and couldn't open windows on headless CI.
**Text shaping** uses `NoopTextSystem`: deterministic across
machines/font installations and CI-portable. Measured cost of this
trade: ~10% of editor draw time vs `MacTextSystem` (Noop still emits one
glyph per character at fixed advances, so downstream layout/paint
structure is preserved).
**GPU coverage (macOS only for now).** `PlatformHeadlessRenderer` gained
`render_scene`, which encodes and submits the scene to Metal against a
cached offscreen target without blocking on completion or reading pixels
back — matching production `present()` CPU cost (`render_scene_to_image`
would overstate it: it waits for the GPU and copies pixels back).
`TestWindow::draw` forwards scenes to the renderer, the real
`MetalAtlas` means glyph/SVG rasterization happens during paint, and
`bench_renderer` presents after each measured update. Platforms without
a headless renderer degrade to discarding the scene.
## Example
```rust
#[gpui::bench]
fn editor_render(cx: &mut BenchAppContext) {
init_context(cx);
let buffer = cx.update(|cx| { /* build a MultiBuffer */ });
let mut window = cx.add_empty_window();
let editor = window.update(|window, cx| {
let editor = window.replace_root(cx, |window, cx| {
let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx);
editor.set_style(editor::EditorStyle::default(), window, cx);
editor
});
window.focus(&editor.focus_handle(cx), cx);
editor
});
let mut move_down = true;
cx.bench_renderer(editor, move |editor, window, cx| {
if move_down {
editor.move_down(&MoveDown, window, cx);
} else {
editor.move_up(&MoveUp, window, cx);
}
move_down = !move_down;
});
}
```
## Example output (release, M-series)
```
editor_render time: [329.75 µs 330.17 µs 330.69 µs]
GPUI bench report (all observed iterations): editor_render
note: includes Criterion warmup/calibration
window dirty-to-draw:
samples: 31533
mean: 0.321ms
p50: 0.322ms
p90: 0.336ms
p95: 0.342ms
p99: 0.360ms
max: 0.504ms
frame budget overruns total: 0
frame budget overruns max: 0
window draw:
samples: 31533
mean: 0.295ms
p50: 0.295ms
p90: 0.307ms
p95: 0.313ms
p99: 0.330ms
max: 0.455ms
frame budget overruns total: 0
frame budget overruns max: 0
invalidations per frame: mean 5.00, max 5
```
(`invalidations per frame: mean 5.00` is real signal: each `move_down`
notifies the window five times before the draw.)
## Known limitations
- **Draw-per-flush**: the harness draws synchronously when effects flush
rather than coalescing invalidations to a vsync tick, so `dirty-to-draw`
excludes queueing delay, and `frame budget overruns` is a draw-time
budget proxy rather than actual missed presents. A frame-paced mode is
natural follow-up work.
- **GPU submission is measured on macOS only**; other platforms have no
headless renderer yet.
- The GPUI report includes Criterion warmup/calibration samples (noted
in the output); Criterion's `time` is the regression-gating number.
- `run_until_idle` waits for queued, running, and already-due work, but
not for timers that haven't reached their due time — the dispatcher runs
in real time and can't skip ahead like `TestDispatcher`'s virtual clock.
## Future work
- A vsync-like frame-pacing mode (suppress draw-on-flush; tick-driven
draw + present) so dirty-to-draw captures queueing delay
- Record present duration in `FrameTiming` so the report can split draw
vs present
- Benches that scroll through novel content (cold layout caches) and an
agent-panel render bench
- Headless renderers for Windows/Linux
- Move benches into a dedicated crate
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:
- 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 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 FR-67
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR changes how base texts are managed by the `buffer_diff` crate,
to enable keeping two diff entities alive that share the same base text
buffer entity. Previously, each diff owned its own base text buffer and
edited it when calling `BufferDiff::set_snapshot`, so the only way to
reuse the same base text between two diffs was to have two independent
buffers for it, which is pretty inefficient.
After this PR, each diff still has a base text buffer, but
`set_snapshot` doesn't edit it. Instead, that responsibility moves into
the caller. For updating the base text buffer, this PR also introduces a
new pair of APIs, `Buffer::snapshot_with_edits` and
`Buffer::fast_forward`, which allow us to move the parsing of the new
base text into the background and then install the new syntax tree
synchronously on the foreground.
The git store uses the low-level APIs `set_snapshot` and `fast_forward`
directly, and manages the head text and index text buffers itself
(garbage-collecting them when they're no longer needed); this enables
adding an `open_staged_diff` API which returns a diff between the
managed index buffer and the managed head buffer (the latter is also
used for the uncommitted diff's base text). Other downstreams don't need
to reuse a base text buffer, and those have been migrated to use the
high-level `set_base_text` API, which now calls `set_snapshot` and
`fast_forward` internally, with a guard to prevent concurrent updates.
Another change worthy of note is that we now always diff the old base
text with the new base text to create `snapshot_with_edits`.
There are also some incidental bug fixes:
- Fixed an issue where a dangling weak unstaged diff could stick around
in the git store forever
- Restored the `IndexMatchesHead` optimization that had become
inoperative in the remote case
- Fixed a crash in the multibuffer due to the handling of
`BufferDiffEvent::LanguageChanged`, which could cause the multibuffer to
have transforms that were inconsistent with the diff base text.
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 ZED-81P
Release Notes:
- Fixed a rare crash that could occur while using the uncommitted diff.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
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 #ISSUE
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)
- [ ] Tests cover the new/changed behavior (visual difference only)
- [x] Performance impact has been considered and is acceptable
I was unable to find a specific issue or PR that mentions this.
As Linux installations always use built-in prompts and ignore the `Use
System Prompts` setting (as far as I'm aware) all users using Zed (with
client-side decorations) are affected. The darkened prompt backdrop was
drawn across the full window boundary, including the transparent
decoration/shadow inset, causing it to overlap.
This PR fixes the backdrop to respect the client-side decoration inset
and only applies rounded corners on non-tiled edges. Tiled edges remain
flush, matching the rest of the client-side window decoration behavior.
I've verified it works on Wayland, X11 and causes no regressions on
macOS or Windows (with `Use System Prompts` off).
Notice the screenshots below on a white background showing the before
and after, where the faint overlap is shown broken and fixed (sorry if
you have to squint).
Before:

After:

Release Notes:
- Fixed prompt darkened backdrop/background rendering outside
client-decorated window boundaries on Linux.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes AI-344
Closes AI-342
Moves agent skills management out of the agent panel and into the
settings UI. The skill creator (previously its own crate) now lives in
`settings_ui` as a settings page, alongside the skills setup page. The
agent panel's ellipsis menu now links to the settings page instead of
hosting skill management directly.
Release Notes:
- Improved agent skills management by moving it into the settings UI
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Nucleo tracking issue:
https://github.com/zed-industries/zed/issues/55872
This PR switches the outline picker to use `fuzzy_nucleo`.
with that I refactored the outline fuzzy picking to take advantage of
nucleo and its multi-atom query support. The previous implementation had
a lot going on specifically to work around the lack of multiple atoms,
basically taking matters into its own hands to accomplish the same goals
within the constraints it had.
Instead of having two lists of candidates that we have to run the query
against, we just run a single query and take advantage of the fact that
nucleo chooses the matches that are the furtherest towards the end of
the haystack to implement the same ancestor/leaf filtering. It retains
the leaf only matching on single atom queries.
video:
https://github.com/user-attachments/assets/64baa8d7-fd77-452c-86d1-e08561422d85
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:
- outline: switch to fuzzy_nucleo
This will improve local dev installation times as well as CI times by a
lot (I measured it once and for some extensions, it might save us up to
60% of CI time. It will similarly help locally).
I also moved the debug adapter schema validation to the other
validations, as it felt it makes more sense to check there as opposed to
doing this during the compilation step.
Release Notes:
- Improved dev extension installation times for language extensions with
multiple grammars or language servers.
This PR bumps the version of the GLSL extension to v0.2.4.
Release Notes:
- N/A
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Stabilizes context windows + persistent session/delete for acp agents
that support them
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: Show context window usage and cost metrics for external agents
that support it.
- acp: Persist session deletion from history for external agents that
support it.
Closes https://github.com/zed-industries/zed/issues/54840
There are likely more places we can use this new workspace function in,
but these are the known ones to me right now
Release Notes:
- Fixed file hyperlinks in the agent panel not opening files when
clicked
Co-authored-by: saberoueslati <saberoueslati12@gmail.com>
TypeId is effectively already a hash, so re-hashing it with fxhash is
unnecessary.
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
The parser stores emitted byte offsets between partial tool-call parses.
Because partial JSON can be repaired differently as more bytes arrive, a
byte offset that was valid in an earlier string can land inside a
multibyte character in a later string. We now normalize those offsets
with `find_char_boundary` before slicing.
Added property tests covering boundary-sensitive write/edit streaming
sequences to prevent regressions.
Fixes Sentry ZED-8Y1 / 7523469866.
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 a crash that could occur while streaming agent edits containing
multibyte characters.
I was a silly goose didn't notice my `git push` failed, so merged #57967
without a critical commit, and some follow-ups.
This PR just cherry-picks those commits.
Release Notes:
- N/A or Added/Fixed/Improved ...
Closes AI-286
This PR adds a right-click menu to thread items in the sidebar. A big
motivation for this addition was surfacing the "regenerate thread title"
action. And because this action and the "open thread as markdown" action
previously only worked on the already-loaded agent panel, there was a
load of plumbing needed to make that work even for threads in workspaces
that haven't been loaded, mostly using the thread metadata store. At the
end of the day, the title regeneration feature is only possible for the
Zed agent, so this is gated from external agents. But I believe it's now
in a slightly nicer spot due to some refactors to better expose the
state in which the title regeneration can fall into.
Release Notes:
- Agent: Added a right-click menu to thread items in the sidebar,
allowing to regenerate a thread title, rename a thread title, open the
thread as markdown, and archive it.
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Following up on #57644 by @cameron1024, this PR updates `merman` to
v0.6.
With merman 0.6's new raster-safe SVG pipeline, Zed can move generic
`usvg`/`resvg` cleanup passes out of this crate and rely on merman for
them instead.
**What's moved to merman:**
- `foreignObject` fallback text generation
- Unsupported CSS cleanup
- Invalid SVG attribute cleanup
**What's kept in Zed:**
- Theme CSS injection and accent color assignment
- Zed-specific fallback overlay handling
**Integration note:**
In merman v0.6, fallback overlay groups are marked with
`data-merman-foreignobject="fallback"` and preserve source classes like
`node` or `section-*`, so host CSS can still style fallback text. This
PR updates Zed's accent tracker to check for this marker, ensuring
fallback overlays are not treated as real layout nodes.
I also added a render-stage test for the new contract: the SVG output
from `render_mermaid` is already raster-safe before Zed-specific
post-processing runs.
---
### 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:
- Improved rendering of Mermaid diagrams in Markdown previews.
### Tests:
- `cargo +1.95 fmt --check -p mermaid_render`
- `cargo +1.95 test -p mermaid_render`
- `cargo +1.95 clippy -p mermaid_render --all-targets -- -D warnings`
- `git diff --check HEAD~1..HEAD`
---------
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
This change adds metrics for evaluating editable context collectors and
the collectors themselves:
- `cursor excerpt`: small area around the cursor.
- `current-file`: the full file that contains the cursor.
- `edit-history`: excerpts around edit history edits.
- `edit-history-file`: full files referenced by the edit history.
- `git-log`: files related to the cursor file according to recent git
co-change history.
- `oracle-file`: full files referenced by the expected patches. This is
an oracle/evaluation-only source because it uses the target patch.
Individual collectors can be enabled by passing a comma-separated list
like this: `ep context --type=edit-history,current-file`. There's also a
preset, `--type=editable`, which will enable all collectors except
oracle.
This change also adds the
`.prompt_input.related_files[0].excerpts[0].context_source` field.
Editable context is only accessible via ep-cli for now.
Release Notes:
- N/A
---------
Co-authored-by: Eric Holk <eric@zed.dev>
This centralizes some repeated logic across `cloud_api_client`, to map
generic request failures (`ConnectionFailed`, 401s) to errors and read
response bodies, handling failures there too.
Closes CLO-759.
Release Notes:
- N/A
Closes AI-354
The "Panel Layout" submenu available in the user menu exposed two quick
menu items to switch between the classic and agentic workspace layout.
These will now also be available as actions, reachable through the
command palette.
<img width="600" alt="Screenshot 2026-06-01 at 8 28@2x"
src="https://github.com/user-attachments/assets/c468b958-9588-4646-a689-6e661a8f6e5a"
/>
Release Notes:
- Exposed actions to switch between the classic and agentic workspace
layout in the command palette.
cc @Anthony-Eid
## Why
This is the first step in moving the Git Graph work into the Git UI
crate before continuing with follow-up refactors and feature work. The
goal is for Git UI components and shared Git UI helpers to live in one
crate, so future changes to the Git Graph can reuse existing `git_ui`
code instead of duplicating it.
This PR is not only a filesystem move. While moving `git_graph` into
`git_ui`, a few small dependency and helper boundaries had to change:
- `git_graph` and `git_ui` both needed the same remote parsing and
commit tooltip construction behavior, so those pieces are now shared
from `git_ui`.
- `git_graph` previously depended on `project_panel` to resolve
file-history actions from the project panel selection. After moving
`git_graph` into `git_ui`, keeping that dependency would create an
undesirable `git_ui` -> `project_panel` relationship. The
project-panel-specific action forwarding now lives in `project_panel`,
and calls into exported `git_ui::git_graph` helpers instead.
- `git_graph` initialization now happens through `git_ui::init`, so
downstream crates only need to initialize `git_ui`.
This prepares the codebase for the next planned PRs: splitting the large
`git_graph.rs` implementation into smaller pieces, then adding Git Graph
features such as keeping the main branch lane at index `0`.
## License removal
The removed `crates/git_graph/LICENSE-GPL` file was a symlink to the
repository root `LICENSE-GPL`. The moved code is now inside `git_ui`,
which is also licensed as `GPL-3.0-or-later` and has its own
`LICENSE-GPL` symlink to the same root license file. The code did not
move to a differently licensed crate; it remains covered by the same GPL
license.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Why: denoise was used on the "new" removed audio pipeline. While we will
(hopefully) reintroduce that later it is currently dead code! Worse dead
code causing issues as the denoise crate breaks compilation on old arm
targets.
denoise (through candle-core) eventually depends on gemm which does not
compile on older arm targets. This is a known issue in gemm (see
sarah-quinones/gemm#31).
Hopefully this will be addressed in gemm before we re-land denoise/new
audio. If it is not we can always compile denoise only for supported
platforms.
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#57770
Release Notes:
- Fixed Zed not compiling on pre ARMv8.2-A machines
Brings stable logout and additional directories support as well as
removing dep on rmcp + tokio
This also removed the unstable model selector (replaced awhile ago by
session config options) so it removes all of that code.
Native agent still uses it because we have a special model selector that
would need more work to rip out
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
Add a `custom_headers` setting to each HTTP-based language model
provider
(Anthropic, Bedrock, DeepSeek, Google, LM Studio, Mistral, Ollama,
OpenAI,
OpenAI-compatible, OpenCode, OpenRouter, Vercel AI Gateway, and xAI) so
users
can attach extra headers to every outgoing request. Headers managed by
Zed
(authentication, content-type, etc.) cannot be overridden and are
skipped with
a warning.
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:
- Added support for configuring custom HTTP headers on language model
providers via `language_models.<provider>.custom_headers`.
Signed-off-by: Aurabindo Pillai <mail@aurabindo.in>
Closes FR-49
This PR fixes stack overflow in flowcharts with deeply nested subgraphs.
Rewrote recursive call to iterate with an explicit stack on heap. Added
test which reproduces the overflow.
We use our fork now, with patch on existing v0.4.0:
https://github.com/zed-industries/merman/commit/1c765dcca2ef5092fcde7bebe8374819563623ef
Release Notes:
- Fixed a crash in when rendering Mermaid diagram flowcharts with deeply
nested subgraphs.
We have a lot of long blocking tasks on both the foreground and
background, this is a start of getting some insight into those.
We will now log tasks running longer then 100ms on the foreground or
background. Hanging actions will also be logged including their name. We
simultaneously collect statistics on task and action performance and
send those to telemetry. This includes quantiles and averages for each
hanging task.
Finally this adds tree dev actions:
- hang action
- hang foreground
- hang background
These cause a hang to check if hang reporting is working and in the
future telemetry.
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:
- Added logging and telemetry of tasks and actions with performance
issues
## Summary
- Remove the `git2` crate and its C dependencies (`libgit2-sys`,
`libz-sys`), replacing all remaining usage with the git CLI and other
previously used rust crates
- Replace `git2::Patch` in `buffer_diff` with `imara-diff` (used
elsewhere in the codebase for word diffing)
- Replace `git2::Oid` with `[u8; 20]` and the `hex` crate
- Replace `git2::Repository` in `RealGitRepository` with stored paths
and git CLI calls via the existing `GitBinary`
- Fixes a bug where linked worktree git dir events could cause the
repository entry to be dropped
### Motivation
libgit2 does not support the
[reftable](https://github.blog/2024-04-29-highlights-from-git-2-45/#preliminary-reftable-support)
storage format that was introduced in git 2.45 (see
[libgit2#7117](https://github.com/libgit2/libgit2/pull/7117)), meaning
that git operations in the app using these (like git status, branch
names, diffs, e.g.) appeared broken for any repository using
`--ref-format=reftable`. [Git 3 will use reftables by
default](https://www.deployhq.com/blog/git-3-0-on-the-horizon-what-git-users-need-to-know-about-the-next-major-release),
so this needs to be supported eventually.
Most operations used the git binary already, but there were still a
handfull of stragglers using libgit2. By swapping out the remaining
uses, we can remove the dependancy of libgit2 and eliminate ~30k lines
of vendored C and the associated build complexity (cmake, libz,
pkg-config), as well as ensure that all git operations go through
similar codepaths.
Closes#46747
Closes https://github.com/zed-industries/zed/discussions/45702
fixes ZED-76X
fixes ZED-73N
### Notes
- `reload_index` is removed from the `GitRepository` trait since both
implementations were no-ops (the CLI always reads from disk)
- `change_branch` is simplified to `git checkout <name>`, which natively
handles local/remote branch resolution
- `load_index_text` and `load_committed_text` no longer explicitly
filter symlinks (the old code returned `None` for symlinked entries)
## Test plan
- [x] `cargo test -p git` (34 tests)
- [x] `cargo test -p buffer_diff` (14 tests)
- [x] `cargo test -p worktree --
test_linked_worktree_git_dir_events_do_not_panic`
- [x] `cargo test -p util` (108 tests)
- [x] `cargo test -p project -- test_file_status
test_repository_subfolder_git_status test_update_gitignore`
- [ ] Manual testing of diff gutter, staging, branch switching, remote
operations
- [ ] Manual testing with a reftable repository
Release Notes:
- Fixed git integration not working with repositories using the reftable
reference storage format
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
Extraction done from #53453
I removed the default Oid implementation we had and added support back
for SHA264 back as well. I also removed the hex dependency and just
added some of those functions we needed in house so we can avoid
building yet another dependency
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
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
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 ...
Refactor to isolate alacritty types into the terminal crate and offers
comparable apis where needed for similar functionality. However, these
are Zed-owned types instead of the dependency leaking across multiple
crates, making alacritty an implementation detail of the terminal crate.
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
Project-local skills now load through project buffers so remote
workspaces can resolve them consistently with other project files.
Validation:
- cargo check -p agent_skills -p agent
- cargo test -p agent_skills
- cargo test -p agent skills
Closes AI-329
Closes https://github.com/zed-industries/zed/issues/57877
Release Notes:
- Improved project skills support in remote workspaces.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
This updates our WebRTC configuration to enable gain normalization in
the
recording flow, which should help normalize the effective volume of
participants
in calls.
Release Notes:
- Added volume equalizations to participants in collab calls
Bumps the workspace `convert_case` dependency from 0.8 to 0.11 (already
in the tree) so the `zed` binary includes only one copy.
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
## Summary
While profiling agent sessions that make a lot of `edit_file`
operations, I noticed the LSP `textDocument/didChange` handler firing
excessively. Looking into this, I found out that the streaming edit
pipeline was applying each `CharOperation` from `StreamingDiff` as its
own `buffer.edit` transaction, and every transaction emits a
`BufferEvent::Edited` event. Each event can trigger several other
expensive events depending on whether the buffer is being rendered in an
editor or is registered with a language.
For example, there are `didChange` LSP events, the editor's on edit work
(matching brackets, bracket colorization, code actions, outline), and
more. A single `edit_file` could trigger hundreds of these at the higher
end in a single synchronous app update, which would block the foreground
thread for a bit and cause Zed to drop frames.
I fixed this by collecting all of a chunk's `CharOperation`s and
applying them in one `buffer.edit` call, so only a single
`BufferEvent::Edited` event gets emitted. This is safe because
operations are non overlapping by design of streaming diff (the edit
cursor only advances).
## Why this wasn't caught earlier
The cost only fully appears when a buffer is both registered with a
language server and rendered in an editor. Without that, most of the per
transaction observers never run, so the existing `edit_file_tool`
benchmark (which ran the tool against a bare buffer) didn't surface it.
I reworked the benchmark to open the edited buffer in an editor view,
register a fake language server with per edit diagnostics, and lay out a
frame, so it exercises the same cascade as the real editor. I also added
a larger fixture.
## Results
Measured with the `release-fast` profile on the reworked benchmark:
| Fixture | Initial file | Before | After | Improvement |
| --- | --- | --- | --- | --- |
| `tiny_function_rewrite` | 1.4 KB | 31.1 ms | 12.1 ms | −61% |
| `small_function_rewrite` | 3.0 KB | 42.4 ms | 19.3 ms | −55% |
| `medium_many_small_changes` | 4.6 KB | 309.2 ms | 151.5 ms | −51% |
| `medium_insertions` | 4.6 KB | 171.8 ms | 126.1 ms | −27% |
| `large_multi_edit` | 44 KB | 9,549 ms | 919 ms | −90% |
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:
- Improved agent's edit file tool performance
The `nc` crate and `zed --nc <socket>` flag were added in #34577 to let
the Claude Code integration spawn the running zed binary as a
netcat-style bridge between stdio and a Unix socket for its MCP server.
That integration was removed in #37120 in favor of the external
`@agentclientprotocol/claude-agent-acp` npm package, which dropped the
only caller of `--nc`. The flag, its dispatch in `main.rs`, and the `nc`
crate itself were left behind and have been unused since.
Nothing in the Zed codebase spawns `zed --nc` anymore, so remove the
flag and delete the crate. The unrelated `--askpass` netcat bridge (in
the `askpass` crate) is unaffected.
Release Notes:
- N/A
Added because I'd like to get this skill Danilo made without having to
upload a gist
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
This PR does two things
1. Move PTY child spawning to the background executor. Forking to spawn
the terminal child was taking between 10-70ms on profiles I was looking
at, which caused frames to be dropped because it was on the foreground
thread. This should fix issues such as #57574 where the miniprof from
this comment showed terminal creation blocking the foreground thread as
well.
https://github.com/zed-industries/zed/issues/57574#issuecomment-4546858817
2. Stopped overwriting alacrities exit status with `9` on
`AlacTermEvent::Exit` event handling. Before we get the exit event,
alacritty emits `ChildExit(status)` with the real status, which we used
to overwrite with exit status 9 when handling the AlacTermEvent::Exit.
This was an easy fix so I added it in this PR when I noticed the bug.
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 dropped frames caused by agents or users creating new terminals
This PR uses https://github.com/zed-industries/zed/pull/57758 as a base
and adds tests, cleans up the comments, and checks changes the database
query used in auth.db to include oauth key.
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 GitHub Copilot Chat showing an empty model dropdown for users on
newer Copilot SDK builds
---------
Co-authored-by: Alexander Shlemov <eodus@users.noreply.github.com>
Co-authored-by: cameron <cameron.studdstreet@gmail.com>
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>
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
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 ...
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 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>